leidenbase/0000755000176200001440000000000014532326115012347 5ustar liggesusersleidenbase/NAMESPACE0000644000176200001440000000021214445351407013566 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(leiden_find_partition) import(igraph) useDynLib(leidenbase,"_leiden_find_partition") leidenbase/cleanup.win0000644000176200001440000000043214444635421014521 0ustar liggesusers#! /bin/sh rm -f src/config.h src/Makevars touch src/config.h # Object files cause problems on Github Actions where they get included # in the source package that is re-generated from the original source, so # we remove them here in the cleanup step find src -name *.o | xargs rm leidenbase/man/0000755000176200001440000000000014444624070013125 5ustar liggesusersleidenbase/man/leiden_find_partition.Rd0000644000176200001440000001072214451315457017753 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/leidenbase.R \name{leiden_find_partition} \alias{leiden_find_partition} \title{Leiden find partition community detection function} \usage{ leiden_find_partition( igraph, partition_type = c("CPMVertexPartition", "ModularityVertexPartition", "RBConfigurationVertexPartition", "RBERVertexPartition", "SignificanceVertexPartition", "SurpriseVertexPartition"), initial_membership = NULL, edge_weights = NULL, node_sizes = NULL, seed = NULL, resolution_parameter = 0.1, num_iter = 2, verbose = FALSE ) } \arguments{ \item{igraph}{R igraph graph.} \item{partition_type}{String partition type name. Default is CPMVertexParition.} \item{initial_membership}{Numeric vector of initial membership assignments of nodes. These are 1-based indices. Default is one community per node.} \item{edge_weights}{Numeric vector of edge weights. Default is 1.0 for all edges.} \item{node_sizes}{Numeric vector of node sizes. Default is 1 for all nodes.} \item{seed}{Numeric random number generator seed. The seed value must be either NULL for random seed values or greater than 0 for a fixed seed value. Default is NULL.} \item{resolution_parameter}{Numeric resolution parameter. The value must be greater than 0.0. Default is 0.1. The resolution_parameter is ignored for the partition_types ModularityVertexPartition, SignificanceVertexPartition, and SurpriseVertexPartition.} \item{num_iter}{Numeric number of iterations. Default is 2.} \item{verbose}{A logic flag to determine whether or not we should print run diagnostics.} } \value{ A named list consisting of a numeric vector of the node community memberships (1-based indices), a numeric quality value, a numeric modularity, a numeric significance, a numeric vector of edge weights within each community, a numeric vector of edge weights from each community, a numeric vector of edge weights to each community, and total edge weight in the graph. } \description{ R to C wrapper that runs the basic Leiden community detection algorithm, which is similar to the find_partition() function in the python Leidenalg distribution. } \details{ The Leiden algorithm is described in From Louvain to Leiden: guaranteeing well-connected communities. V. A. Traag and L. Waltman and N. J. van Eck Scientific Reports, 9(1) (2019) DOI: 10.1038/s41598-019-41695-z. Significance is described in Significant Scales in Community Structure V. A. Traag, G. Krings, and P. Van Dooren Scientific Reports, 3(1) (2013) DOI: 10.1038/srep02930 Notes excerpted from leidenalg/src/VertexPartition.py \itemize{ \item \emph{ CPMVertexPartition } Implements Constant Potts Model. This quality function uses a linear resolution parameter and is well-defined for both positive and negative edge weights. \item \emph{ ModularityVertexPartition } Implements modularity. This quality function is well-defined only for positive edge weights. \item\emph{ RBConfigurationVertexPartition } Implements Reichardt and Bornholdt’s Potts model with a configuration null model. This quality function uses a linear resolution parameter and is well-defined only for positive edge weights. \item \emph{ RBERVertexPartition } Implements Reichardt and Bornholdt’s Potts model with an Erdos-Renyi null model. This quality function uses a linear resolution parameter and is well-defined only for positive edge weights. \item \emph{ SignificanceVertexPartition } Implements Significance. This quality function is well-defined only for unweighted graphs. \item \emph{ SurpriseVertexPartition } Implements (asymptotic) Surprise. This quality function is well-defined only for positive edge weights. } } \examples{ library(igraph) fpath <- system.file( 'testdata', 'igraph_n1500_edgelist.txt.gz', package = 'leidenbase' ) zfp <- gzfile(fpath) igraph <- read_graph( file = zfp, format='edgelist', n=1500 ) res <- leiden_find_partition(igraph=igraph, partition_type='CPMVertexPartition', resolution_parameter=1e-5) } \references{ V. A. Traag, L. Waltman, N. J. van Eck (2019). From Louvain to Leiden: guaranteeing well-connected communities. Scientific Reports, 9(1). DOI: 10.1038/s41598-019-41695-z Significant Scales in Community Structure V. A. Traag, G. Krings, and P. Van Dooren Scientific Reports, 3(1) (2013) DOI: 10.1038/srep02930 } leidenbase/DESCRIPTION0000644000176200001440000000364414532326115014064 0ustar liggesusersPackage: leidenbase Type: Package Title: R and C/C++ Wrappers to Run the Leiden find_partition() Function Authors@R: c( person('Brent', 'Ewing', email = 'bge@uw.edu', role = c('aut', 'cre')), person('Vincent', 'Traag', role = 'ctb'), person('Gábor', 'Csárdi', role = 'ctb'), person('Tamás', 'Nepusz', role = 'ctb'), person('Szabolcs', 'Horvat', role = 'ctb'), person('Fabio', 'Zanini', role = 'ctb')) Version: 0.1.27 Description: An R to C/C++ interface that runs the Leiden community detection algorithm to find a basic partition (). It runs the equivalent of the 'leidenalg' find_partition() function, which is given in the 'leidenalg' distribution file 'leiden/src/functions.py'. This package includes the required source code files from the official 'leidenalg' distribution and functions from the R 'igraph' package. The 'leidenalg' distribution is available from and the R 'igraph' package is available from . The Leiden algorithm is described in the article by Traag et al. (2019) . Leidenbase includes code from the packages: igraph version 0.9.8 with license GPL (>= 2), leidenalg version 0.8.10 with license GPL 3. Imports: igraph (>= 0.9.0) License: GPL-3 Encoding: UTF-8 RoxygenNote: 7.2.3 Depends: R (>= 3.5.0) Suggests: rmarkdown, knitr, testthat (>= 3.1.0) URL: https://github.com/cole-trapnell-lab/leidenbase BugReports: https://github.com/cole-trapnell-lab/leidenbase/issues NeedsCompilation: yes Maintainer: Brent Ewing VignetteBuilder: knitr Packaged: 2023-11-30 20:52:53 UTC; brent Author: Brent Ewing [aut, cre], Vincent Traag [ctb], Gábor Csárdi [ctb], Tamás Nepusz [ctb], Szabolcs Horvat [ctb], Fabio Zanini [ctb] Repository: CRAN Date/Publication: 2023-12-01 09:50:05 UTC leidenbase/build/0000755000176200001440000000000014532173045013450 5ustar liggesusersleidenbase/build/vignette.rds0000644000176200001440000000030714532173045016007 0ustar liggesusersb```b`afb`b2 1# 'ILIKJ,N MABȢ#(AA6 aD 0!eKM-F3% 5/$~hZ8S+`zP԰Aհe ,s\ܠL t7`~΢r=xAa$Gs=ʕXVr7 leidenbase/tests/0000755000176200001440000000000014451337463013521 5ustar liggesusersleidenbase/tests/cpp_tests/0000755000176200001440000000000014451640322015514 5ustar liggesusersleidenbase/tests/cpp_tests/NOTES0000644000176200001440000000663314446667730016357 0ustar liggesusers== file: leiden.cpp description: program to test leidenFindPartition function for memory problems using an instrumentation program such as valgrind and comparing to the leidenalg python module output. file: Makefile description: used to build leiden executable file: igraph_edgelist.txt description: list of graph edges for use when running the leiden executable. notes: o set up test directory o make a test directory o copy edgelist.edg, leiden.cpp, and Makefile from this directory to the test directory. Alternatively, use igraph_edgelist.txt.gz after gunzipping it. o copy leidenFindPartition.cpp and set #define R_INTERFACE 0 to the test directory o copy the leidenalg *.cpp and *.h files to the test directory o build leiden executable o use the make utility to build the executable o run leiden executable o type 'leiden' o test leiden using valgrind o type 'valgrind --leak-check=full leiden' o specifying a directed graph vs an undirected graph gives about 1/2 the communities. The python py igraph module appears to default to reading the edgelist as an undirected graph. == file: leidenalg.py description: run the leidenalg package. notes: o install leidenalg as a python package from the leidenalg github repository by * cloning the repository * ensuring that the correct igraph library is installed in the expected place * it may be necessary to set the igraph include file directory path by setting using environment variable as export IGRAPH_EXTRA_INCLUDE_PATH="/usr/include/igraph" * run the command python3 setup.py install --user o in order to use consistent version of igraph, python-igraph, and leidenalg igraph, I used pipx to create a python virtual environment in which I installed python-igraph. The python-igraph installed from source and I edited the setup.py to point to igraph libraries that I installed in a non-conventional place. In order to install the desired python-igraph version in the virtual environment called python-igraph, I used the command $HOME/.local/pipx/venvs/python-igraph/bin/python3 -m pip install "leidenalg==0.8.10" == test in R description: test membership using the leidenbase R interface notes: o install leidenbase in R using the command R CMD install o get membership values in R library(igraph) library(leidenbase) igraph<-read_graph('edgelist.edg',format='edgelist', directed=FALSE) res<-leiden_find_partition( igraph, partition_type = 'CPMVertexPartition', seed = 2016, resolution_parameter = 0.5, num_iter=2 ) which(res$membership==1)-1 which(res$membership==2)-1 which(res$membership==3)-1 ... o res$membership is a vector whose values are the communities to which each node belongs. For example, the first value is the community to which node 1 belongs, etc. o the R nodes and communities are 1-based whereas the python and C++ values are 0-based. o the res$total_weight is the weight of all edges in the graph, which is not the same as the total weight in all communities reported in leidenalg. leidenbase/tests/cpp_tests/initial_memberships.txt0000644000176200001440000001436214444624071022317 0ustar liggesusers574 651 1081 346 1170 1259 904 165 852 452 487 597 687 211 269 712 481 1040 1265 33 441 925 748 17 1138 1101 1179 1320 649 638 545 1107 564 584 434 1266 302 1058 603 726 828 1284 1188 1399 428 759 981 701 1091 870 1265 1358 319 189 377 245 1493 668 24 554 769 583 1156 128 694 982 752 891 894 1116 1412 424 75 663 1274 901 1118 44 899 979 687 658 727 651 982 524 1336 630 1344 141 1230 272 158 512 885 526 1063 146 900 1417 1447 88 1128 60 1105 1395 1274 1453 583 152 563 766 1474 906 763 1182 868 348 214 1035 566 1436 1428 664 1349 34 452 862 2 741 538 1277 460 1118 578 348 473 1340 773 384 1462 49 655 797 203 306 854 566 74 255 277 1003 48 1192 1236 761 62 164 883 1079 526 1495 754 441 1409 47 1258 939 270 95 1444 459 1125 932 1309 941 1270 1037 42 258 1201 1410 1384 568 1144 893 366 202 121 1395 1188 906 1207 704 1108 1374 471 929 1385 1335 400 1410 1481 1498 551 765 656 1278 448 45 828 997 198 1412 1086 1291 696 1361 340 54 676 1337 1048 333 919 1433 1313 1131 257 119 902 1418 181 107 681 1481 320 467 664 928 277 1060 1058 765 912 1435 6 129 660 134 518 1359 1416 1165 1007 508 1205 1149 1404 408 807 577 632 445 1496 631 338 1076 334 614 528 974 1438 431 928 244 873 301 1352 975 906 414 653 33 78 99 238 1372 1183 1112 1488 1446 790 1122 815 340 26 817 374 309 16 409 881 44 262 1056 968 1325 159 842 1408 299 1209 1470 16 27 138 918 1037 213 635 109 971 255 739 1218 539 1339 1355 702 56 1472 101 1035 1326 1173 1418 215 655 91 1446 1 291 290 650 497 657 1409 735 16 256 1297 1078 929 1287 54 287 1496 637 1447 353 1396 1188 1429 1195 523 228 600 160 20 1390 1473 988 210 4 1221 621 1346 1209 1257 681 572 376 108 217 58 1286 30 1322 217 722 422 121 452 861 438 900 1399 83 835 1322 1300 137 292 1255 81 645 708 785 901 862 649 1478 1208 993 337 295 1476 1402 1044 142 1436 1146 41 205 1284 821 16 849 654 38 765 528 137 265 703 524 1033 1313 534 915 1425 59 911 196 887 773 540 549 263 546 1440 329 328 1193 1242 226 1156 1131 402 520 263 715 278 747 952 845 433 135 1186 826 1220 464 746 542 896 725 55 736 422 340 1165 311 182 1467 1420 116 244 1023 55 1453 382 1465 736 1246 278 1084 292 1283 1426 485 1043 1261 429 1363 632 351 1168 1226 938 989 14 775 419 691 1406 54 1076 1372 1263 288 688 483 836 314 1074 995 592 1278 200 609 291 661 899 881 1250 681 144 270 995 905 759 752 970 1303 269 720 767 441 1197 24 14 691 879 986 413 1006 300 749 1307 976 384 1138 401 497 619 1024 786 981 1239 1379 551 1469 938 720 738 648 416 937 605 368 578 1090 1087 1213 614 1423 182 1071 850 640 1480 1276 820 163 170 827 337 1479 1331 1179 82 1479 1170 1128 306 701 281 1099 1211 1144 473 333 1241 1269 950 74 730 197 458 236 652 1225 265 353 654 947 1457 235 990 1373 178 1381 603 874 1351 1228 786 503 56 134 1009 1040 1082 1226 1119 393 1282 771 1027 535 1045 71 1248 913 708 1113 190 63 636 1385 1019 1390 463 427 850 160 1229 365 70 24 1481 684 329 1125 917 1019 887 1089 1489 455 1105 119 1140 1106 425 218 155 222 463 106 168 228 1122 1419 712 108 1195 1051 1110 261 198 613 396 67 684 1007 560 624 40 976 772 1177 1302 154 596 31 711 41 231 1065 395 544 453 1326 64 1122 232 1268 607 1 817 983 817 130 125 365 46 125 316 414 1408 759 213 311 1084 1337 501 1323 1390 888 140 464 951 412 122 908 431 547 718 1202 655 540 1420 163 519 872 812 692 1028 1123 759 1293 997 460 796 1213 783 449 31 1117 1234 48 1467 1180 635 196 1283 897 340 156 860 1363 365 364 965 1451 1204 16 1292 771 862 39 13 1494 1208 1341 893 295 991 1484 447 217 1290 249 343 343 96 1194 597 1492 185 929 184 535 1103 899 283 351 1282 1161 570 1384 1248 50 748 1396 585 252 1282 1169 1372 245 387 1449 1173 329 1089 322 377 478 1139 1132 399 1498 1277 1151 405 213 1353 105 1078 559 1490 239 1423 1497 276 100 1123 1422 973 1202 1145 295 854 683 569 277 926 278 598 227 137 192 1229 1173 50 277 1179 567 833 441 972 1218 1376 333 1118 104 55 1305 745 713 273 963 330 1060 873 1103 535 1445 193 124 1085 560 414 1397 880 1327 727 166 1031 772 220 1183 1291 423 1448 577 1256 449 1024 138 56 927 68 145 436 493 1296 1326 58 772 1131 745 1380 19 798 1329 147 216 712 695 563 582 1115 1222 1478 687 297 1095 247 375 715 789 1282 1392 15 398 626 641 1250 1148 214 551 1010 1115 913 1484 923 843 589 249 783 1379 486 1146 1482 1064 27 903 1385 1113 1184 527 172 638 1427 1410 1404 1275 923 73 1365 153 1262 606 891 975 1265 1096 673 105 1163 622 73 639 370 572 500 1081 286 177 1440 1076 543 94 256 657 1096 588 50 482 362 1359 1072 224 1198 710 443 296 653 949 572 362 1139 547 1283 948 1021 547 301 295 860 302 256 960 254 991 1323 1393 871 724 654 1318 125 1239 592 840 558 934 876 527 1243 21 835 739 211 952 262 534 446 1145 482 106 1373 1164 225 345 1206 474 27 1354 1343 570 765 771 834 258 1473 491 167 1371 414 1202 285 576 431 836 303 236 124 237 972 766 1352 259 15 920 389 308 1494 1097 581 1027 898 780 599 262 1104 677 363 1497 968 1327 344 1329 123 1027 1184 206 318 1142 434 381 735 18 1026 1320 72 11 418 618 873 923 171 1458 677 314 506 1374 537 637 242 1030 1381 480 656 31 860 939 677 1211 1445 1179 232 581 834 1054 826 861 971 473 1143 26 972 370 1435 1354 457 1275 219 296 1477 951 651 268 1228 1170 107 1202 922 495 586 1361 759 630 879 1089 1178 1391 875 919 319 215 662 16 332 388 215 414 1175 744 408 834 171 698 669 841 192 896 262 353 603 754 944 664 1248 985 1238 633 1405 242 181 1094 1410 1072 726 170 809 540 381 36 1102 335 1412 328 847 1102 979 1154 203 432 44 158 565 164 1313 689 790 633 1041 1285 640 1487 895 297 1103 512 59 826 30 339 594 451 104 891 300 654 218 965 1017 338 864 1273 1223 402 976 655 12 688 1365 620 14 426 1409 1351 739 1351 1328 10 385 228 1323 428 186 617 793 1262 10 1077 819 803 118 651 853 1358 14 1434 965 609 1138 1112 503 826 1427 402 1350 969 702 1357 1020 369 940 1158 276 1381 4 707 47 638 1235 1185 1381 102 878 1289 233 1256 885 263 346 675 1284 236 299 1333 451 1459 250 778 1401 1372 1344 1258 1062 1271 1256 377 890 1184 156 329 42 1134 788 899 801 1183 73 945 1334 1194 834 944 1183 470 920 1372 1145 1410 1277 165 600 763 795 905 145 691 1157 624 38 1068 302 776 199 1 514 794 904 656 1457 155 918 1046 1008 231 85 57 483 554 668 234 1245 1025 752 61 469 710 275 947 1173 171 733 1282 412 759 121 77 531 1089 273 329 373 1471 870 951 1464 1166 1146 1017 991 1193 1424 78 779 1272 1422 227 824 1069 1128 1176 363 1395 442 114 1413 545 1213 1095 1247 105 70 238 318 621 1386 969 1361 1155 1397 376 1425 423 479 462 719 1494 1282 leidenbase/tests/cpp_tests/tests_out/0000755000176200001440000000000014451640311017543 5ustar liggesusersleidenbase/tests/cpp_tests/tests_out/initial_memberships.txt0000644000176200001440000001436214451640311024341 0ustar liggesusers574 651 1081 346 1170 1259 904 165 852 452 487 597 687 211 269 712 481 1040 1265 33 441 925 748 17 1138 1101 1179 1320 649 638 545 1107 564 584 434 1266 302 1058 603 726 828 1284 1188 1399 428 759 981 701 1091 870 1265 1358 319 189 377 245 1493 668 24 554 769 583 1156 128 694 982 752 891 894 1116 1412 424 75 663 1274 901 1118 44 899 979 687 658 727 651 982 524 1336 630 1344 141 1230 272 158 512 885 526 1063 146 900 1417 1447 88 1128 60 1105 1395 1274 1453 583 152 563 766 1474 906 763 1182 868 348 214 1035 566 1436 1428 664 1349 34 452 862 2 741 538 1277 460 1118 578 348 473 1340 773 384 1462 49 655 797 203 306 854 566 74 255 277 1003 48 1192 1236 761 62 164 883 1079 526 1495 754 441 1409 47 1258 939 270 95 1444 459 1125 932 1309 941 1270 1037 42 258 1201 1410 1384 568 1144 893 366 202 121 1395 1188 906 1207 704 1108 1374 471 929 1385 1335 400 1410 1481 1498 551 765 656 1278 448 45 828 997 198 1412 1086 1291 696 1361 340 54 676 1337 1048 333 919 1433 1313 1131 257 119 902 1418 181 107 681 1481 320 467 664 928 277 1060 1058 765 912 1435 6 129 660 134 518 1359 1416 1165 1007 508 1205 1149 1404 408 807 577 632 445 1496 631 338 1076 334 614 528 974 1438 431 928 244 873 301 1352 975 906 414 653 33 78 99 238 1372 1183 1112 1488 1446 790 1122 815 340 26 817 374 309 16 409 881 44 262 1056 968 1325 159 842 1408 299 1209 1470 16 27 138 918 1037 213 635 109 971 255 739 1218 539 1339 1355 702 56 1472 101 1035 1326 1173 1418 215 655 91 1446 1 291 290 650 497 657 1409 735 16 256 1297 1078 929 1287 54 287 1496 637 1447 353 1396 1188 1429 1195 523 228 600 160 20 1390 1473 988 210 4 1221 621 1346 1209 1257 681 572 376 108 217 58 1286 30 1322 217 722 422 121 452 861 438 900 1399 83 835 1322 1300 137 292 1255 81 645 708 785 901 862 649 1478 1208 993 337 295 1476 1402 1044 142 1436 1146 41 205 1284 821 16 849 654 38 765 528 137 265 703 524 1033 1313 534 915 1425 59 911 196 887 773 540 549 263 546 1440 329 328 1193 1242 226 1156 1131 402 520 263 715 278 747 952 845 433 135 1186 826 1220 464 746 542 896 725 55 736 422 340 1165 311 182 1467 1420 116 244 1023 55 1453 382 1465 736 1246 278 1084 292 1283 1426 485 1043 1261 429 1363 632 351 1168 1226 938 989 14 775 419 691 1406 54 1076 1372 1263 288 688 483 836 314 1074 995 592 1278 200 609 291 661 899 881 1250 681 144 270 995 905 759 752 970 1303 269 720 767 441 1197 24 14 691 879 986 413 1006 300 749 1307 976 384 1138 401 497 619 1024 786 981 1239 1379 551 1469 938 720 738 648 416 937 605 368 578 1090 1087 1213 614 1423 182 1071 850 640 1480 1276 820 163 170 827 337 1479 1331 1179 82 1479 1170 1128 306 701 281 1099 1211 1144 473 333 1241 1269 950 74 730 197 458 236 652 1225 265 353 654 947 1457 235 990 1373 178 1381 603 874 1351 1228 786 503 56 134 1009 1040 1082 1226 1119 393 1282 771 1027 535 1045 71 1248 913 708 1113 190 63 636 1385 1019 1390 463 427 850 160 1229 365 70 24 1481 684 329 1125 917 1019 887 1089 1489 455 1105 119 1140 1106 425 218 155 222 463 106 168 228 1122 1419 712 108 1195 1051 1110 261 198 613 396 67 684 1007 560 624 40 976 772 1177 1302 154 596 31 711 41 231 1065 395 544 453 1326 64 1122 232 1268 607 1 817 983 817 130 125 365 46 125 316 414 1408 759 213 311 1084 1337 501 1323 1390 888 140 464 951 412 122 908 431 547 718 1202 655 540 1420 163 519 872 812 692 1028 1123 759 1293 997 460 796 1213 783 449 31 1117 1234 48 1467 1180 635 196 1283 897 340 156 860 1363 365 364 965 1451 1204 16 1292 771 862 39 13 1494 1208 1341 893 295 991 1484 447 217 1290 249 343 343 96 1194 597 1492 185 929 184 535 1103 899 283 351 1282 1161 570 1384 1248 50 748 1396 585 252 1282 1169 1372 245 387 1449 1173 329 1089 322 377 478 1139 1132 399 1498 1277 1151 405 213 1353 105 1078 559 1490 239 1423 1497 276 100 1123 1422 973 1202 1145 295 854 683 569 277 926 278 598 227 137 192 1229 1173 50 277 1179 567 833 441 972 1218 1376 333 1118 104 55 1305 745 713 273 963 330 1060 873 1103 535 1445 193 124 1085 560 414 1397 880 1327 727 166 1031 772 220 1183 1291 423 1448 577 1256 449 1024 138 56 927 68 145 436 493 1296 1326 58 772 1131 745 1380 19 798 1329 147 216 712 695 563 582 1115 1222 1478 687 297 1095 247 375 715 789 1282 1392 15 398 626 641 1250 1148 214 551 1010 1115 913 1484 923 843 589 249 783 1379 486 1146 1482 1064 27 903 1385 1113 1184 527 172 638 1427 1410 1404 1275 923 73 1365 153 1262 606 891 975 1265 1096 673 105 1163 622 73 639 370 572 500 1081 286 177 1440 1076 543 94 256 657 1096 588 50 482 362 1359 1072 224 1198 710 443 296 653 949 572 362 1139 547 1283 948 1021 547 301 295 860 302 256 960 254 991 1323 1393 871 724 654 1318 125 1239 592 840 558 934 876 527 1243 21 835 739 211 952 262 534 446 1145 482 106 1373 1164 225 345 1206 474 27 1354 1343 570 765 771 834 258 1473 491 167 1371 414 1202 285 576 431 836 303 236 124 237 972 766 1352 259 15 920 389 308 1494 1097 581 1027 898 780 599 262 1104 677 363 1497 968 1327 344 1329 123 1027 1184 206 318 1142 434 381 735 18 1026 1320 72 11 418 618 873 923 171 1458 677 314 506 1374 537 637 242 1030 1381 480 656 31 860 939 677 1211 1445 1179 232 581 834 1054 826 861 971 473 1143 26 972 370 1435 1354 457 1275 219 296 1477 951 651 268 1228 1170 107 1202 922 495 586 1361 759 630 879 1089 1178 1391 875 919 319 215 662 16 332 388 215 414 1175 744 408 834 171 698 669 841 192 896 262 353 603 754 944 664 1248 985 1238 633 1405 242 181 1094 1410 1072 726 170 809 540 381 36 1102 335 1412 328 847 1102 979 1154 203 432 44 158 565 164 1313 689 790 633 1041 1285 640 1487 895 297 1103 512 59 826 30 339 594 451 104 891 300 654 218 965 1017 338 864 1273 1223 402 976 655 12 688 1365 620 14 426 1409 1351 739 1351 1328 10 385 228 1323 428 186 617 793 1262 10 1077 819 803 118 651 853 1358 14 1434 965 609 1138 1112 503 826 1427 402 1350 969 702 1357 1020 369 940 1158 276 1381 4 707 47 638 1235 1185 1381 102 878 1289 233 1256 885 263 346 675 1284 236 299 1333 451 1459 250 778 1401 1372 1344 1258 1062 1271 1256 377 890 1184 156 329 42 1134 788 899 801 1183 73 945 1334 1194 834 944 1183 470 920 1372 1145 1410 1277 165 600 763 795 905 145 691 1157 624 38 1068 302 776 199 1 514 794 904 656 1457 155 918 1046 1008 231 85 57 483 554 668 234 1245 1025 752 61 469 710 275 947 1173 171 733 1282 412 759 121 77 531 1089 273 329 373 1471 870 951 1464 1166 1146 1017 991 1193 1424 78 779 1272 1422 227 824 1069 1128 1176 363 1395 442 114 1413 545 1213 1095 1247 105 70 238 318 621 1386 969 1361 1155 1397 376 1425 423 479 462 719 1494 1282 leidenbase/tests/cpp_tests/tests_out/edge_weights.txt0000644000176200001440000416416614451640311022764 0ustar liggesusers0.79490859863814 0.931301039159298 0.972387232058681 0.760992606214713 0.788359774376731 0.459851952770259 0.953903821744025 0.0902801301074214 0.440764791832771 0.805843545151874 0.265288385846652 0.0294845965248533 0.654374293198343 0.120589254919905 0.689030879028142 0.611943721694406 0.39933788098162 0.219940175919328 0.349626077869907 0.070124077508226 0.302261099498719 0.609767822504509 0.80906865801895 0.441521257630084 0.251783711225726 0.190329059206415 0.270689954105765 0.220709832212888 0.642924462780356 0.544415256101638 0.944740430677775 0.676276938763913 0.613690819921903 0.161340886815451 0.0621931792120449 0.363723371003289 0.58405420434894 0.279845784464851 0.498390989734326 0.214139961244073 0.0199226809781976 0.0804447295307182 0.357149578959215 0.0328935184096917 0.165607609087601 0.427531060953625 0.178110514327418 0.776757337811869 0.440928035893012 0.0583284663851373 0.723140240784269 0.506729069256689 0.971951574804261 0.303470852060709 0.369749043472111 0.759283016941044 0.476183621231467 0.310984140974469 0.819048855784349 0.35759318854427 0.0560099692293443 0.600755621378776 0.765346399131231 0.550013569169678 0.507245026610326 0.178926267861389 0.876003149515018 0.954743837262504 0.517888952859212 0.723174489282537 0.0961568687926047 0.426369771508034 0.137805656353012 0.594132546090987 0.278866262477823 0.421052794840653 0.0472701326617971 0.97801856481703 0.600084328961093 0.578720494594891 0.448755539369304 0.849029090411495 0.545180141688325 0.925187562818173 0.680860116772819 0.624971891741734 0.604818270020187 0.537580021391623 0.582724344625603 0.609657275888603 0.62674765155185 0.569702672900166 0.874553525848314 0.61319177567726 0.0226687147910707 0.661499663274735 0.710370488290209 0.76399133997038 0.443822950473987 0.38066981040407 0.333691205352079 0.147327897376381 0.511556042442098 0.345780209300574 0.340735497153364 0.098114639010746 0.0758998416480608 0.323397570508532 0.050871422807686 0.216192572109867 0.908421270214021 0.523689337184187 0.962970110704191 0.181862862335984 0.524640998814721 0.0399739928543568 0.88250089653302 0.588968982789665 0.984582581717987 0.280488253256772 0.625339040474501 0.617036058621015 0.159355436032638 0.86615209414158 0.888539697031956 0.79722136458382 0.582457743086852 0.387659523861948 0.0675976575631648 0.28984922170639 0.774079898959026 0.164803178980947 0.839262626399286 0.419891425410751 0.082494852815289 0.921590181530919 0.737774491186719 0.457308835696895 0.153753038924187 0.980996720707044 0.259226069038268 0.37751696186373 0.0402149786683731 0.803308585325722 0.274920837183017 0.578503571611363 0.747691088747233 0.873313928304706 0.1100604784186 0.504936974206939 0.603467006541323 0.604944812115282 0.0768286051764153 0.237820303300396 0.206184888323769 0.292276143934578 0.0616812752420083 0.18998146652244 0.0887953269435093 0.264762605866417 0.560839155693538 0.408940549571998 0.855565023829695 0.942689588225912 0.941524936903734 0.543292712946422 0.956641293547582 0.201370248396415 0.470059499139898 0.451204710374586 0.884056551274844 0.510226409763563 0.623952425543684 0.320829611506779 0.773782222478185 0.217870980640873 0.645605159322731 0.81164103390649 0.494852600449231 0.864056601081975 0.689409598286729 0.376444228880573 0.772017023593653 0.872871890515089 0.734688924895599 0.674167877875734 0.185148180108517 0.407573622076306 0.122955192453228 0.778909690496512 0.0302396793081425 0.0985345333628356 0.74828716410324 0.521661338205449 0.0772830004268326 0.442064171771053 0.372860975312069 0.840193314161152 0.491081883017905 0.733975380477495 0.886755856962409 0.0497791351587512 0.483817792485934 0.678807214552071 0.0591772073390894 0.0625757718319073 0.941707439664751 0.0277989665861242 0.78265712534776 0.260580019021872 0.126433720050845 0.280239638276398 0.106376232095063 0.828495356736239 0.469097249845508 0.0222999728261493 0.443358958489262 0.509768019216135 0.121207163918298 0.0542175026098266 0.851398011336569 0.429179915627465 0.975612228522077 0.134200009712949 0.287591861146502 0.059582445891574 0.133314414662309 0.871899260086939 0.100882633933797 0.991362312156707 0.63550333999563 0.159498805028852 0.356640751273371 0.653573583399411 0.38701112908544 0.222308959695511 0.0161210084659979 0.20471806434216 0.220224694404751 0.574863557303324 0.374992219975684 0.253992737750523 0.355873112336267 0.716744317251723 0.975698742272798 0.687607491828967 0.363684262824245 0.236450999095105 0.386013874092605 0.386160163783934 0.954083832774777 0.716702561522834 0.0456960467225872 0.883116559977643 0.983382222126238 0.535272189117968 0.686101609226316 0.649400397823192 0.751814732686616 0.646071513495408 0.382386765149422 0.015923986362759 0.411761497796979 0.312382669649087 0.750154036877211 0.10252746311482 0.725331998534966 0.0557572342501953 0.711954168197699 0.0518684270139784 0.0621630032290705 0.143257909540553 0.564831366739236 0.48853624609299 0.811666583938058 0.0925170942069963 0.46569784401916 0.226251019656193 0.47603936733678 0.0642104609846137 0.0413447432313114 0.170494605312124 0.0782287794072181 0.286142012279015 0.486325675894041 0.605286435941234 0.79501757461112 0.635748150304426 0.0464023072668351 0.274958372644614 0.827982701098081 0.626585831074044 0.978468891240191 0.256100948776584 0.270159493084066 0.0155597193702124 0.0293853890104219 0.165480786471162 0.386343166965526 0.369741227368359 0.848046363058966 0.615763549953699 0.933491120466497 0.138165014798287 0.152761151869781 0.4694453570107 0.264474903221708 0.586722802976146 0.0610579634993337 0.292865812939126 0.928558178441599 0.738380757973064 0.133006581787486 0.52154782963451 0.182882763722446 0.87195764771197 0.217077888022177 0.97864534469787 0.934804093588609 0.0241699322569184 0.814229310536757 0.0361952698463574 0.557681137216277 0.0508323199301958 0.081390114352107 0.983319347312208 0.500351752564311 0.0102482302719727 0.910740180660505 0.385231701752637 0.467475084345788 0.895201711310074 0.852317363223992 0.574044643582311 0.518705267896876 0.392142121484503 0.535323607043829 0.859085901621729 0.913951824815012 0.0625504760444164 0.236032757675275 0.875567996830214 0.586316308185924 0.968146607491653 0.0973583467816934 0.135131750178989 0.62687921698438 0.272868978446349 0.370109673598781 0.218399459342472 0.569734750757925 0.45884448398836 0.559932799527887 0.393787221044768 0.226840310175903 0.756837713303976 0.940298464163207 0.339469562412705 0.0456153734400868 0.15458570349263 0.610352798942477 0.839242577997502 0.970399698456749 0.852296127735171 0.410717527586967 0.865780976850074 0.752265465254895 0.920955538523849 0.297697016994935 0.242959428743925 0.762315026936121 0.118127659608144 0.320124629558995 0.917150834214408 0.388752879197709 0.0884747111005709 0.987803084768821 0.201107573464978 0.888115806460846 0.206243064347655 0.897852374780923 0.889050178802572 0.546037008310668 0.184723420543596 0.0274268987029791 0.764833232699893 0.765481903618202 0.0948827839503065 0.19976872023195 0.921325535804499 0.888870312988292 0.214097496489994 0.0984192215721123 0.940941555311438 0.99743921515299 0.916316853708122 0.947782035332639 0.415092850113288 0.37913608081406 0.280507964203134 0.320303816082887 0.878315156186 0.931651065486949 0.425552123244852 0.80038149838103 0.707888951529749 0.759813974234276 0.902885284055956 0.67433423302602 0.470819760849699 0.294480958490167 0.0960167026263662 0.471522656290326 0.872408906286582 0.400065562799573 0.652390814363025 0.821999235451221 0.674084810365457 0.615383926434442 0.820346810296178 0.732110421103425 0.0884602198796347 0.687858607990202 0.182171282530762 0.525160037984606 0.852955095192883 0.323558260141872 0.385529878423549 0.82202684963122 0.674520073460881 0.835482954643667 0.120723363715224 0.576340667451732 0.365779473287985 0.731069516113494 0.425249088737182 0.554132459689863 0.439295310389716 0.0148376274644397 0.392881604100112 0.996716869233642 0.0477696328400634 0.591127095497213 0.0400449121999554 0.237953432460781 0.946240481340792 0.823403124688193 0.316483599657658 0.155651009920985 0.583060980380978 0.0458380439993925 0.0346752277156338 0.976494286053348 0.755826346727554 0.502155295973644 0.118639065001626 0.191617293434683 0.266809950906318 0.278556875556242 0.173746329213027 0.386504913682584 0.396297259419225 0.900571503438987 0.574022860189434 0.467218830517959 0.0250140894413926 0.625850567573216 0.237369298508856 0.989275761204772 0.444868226479739 0.593725017958786 0.325253291348927 0.650262048521545 0.217125637042336 0.950892565718386 0.601646362624597 0.561836380029563 0.966796865328215 0.375765111600049 0.262945538193453 0.696921407375485 0.870942035512999 0.0369348455849104 0.911159153694753 0.616792519071605 0.126394431388471 0.676263873199932 0.604350613278802 0.869709644855466 0.659397195214406 0.386961797205731 0.523562938692048 0.849347588859964 0.565377748557366 0.160831259286497 0.391813286158722 0.263716621757485 0.616158509023953 0.376494985034224 0.808983004733454 0.655326465852559 0.576212970539927 0.395898949305993 0.644938557627611 0.0470785531797446 0.37630534430733 0.504273983330932 0.642898338567466 0.469387320901733 0.989147923917044 0.969086619303562 0.304461058522575 0.749720958252437 0.835444120992906 0.0353228574548848 0.793391628412064 0.557704538966063 0.263517702620011 0.903914176416583 0.98865717775654 0.0295304895401932 0.136053409164306 0.529053530180827 0.848930398991797 0.0956764396862127 0.222601578263566 0.575545259437058 0.214849575136323 0.383630842736457 0.469543042748701 0.516874968467746 0.810394162170123 0.733428158708848 0.198383807791397 0.400072848056443 0.217438819415402 0.668239175204653 0.291440387868788 0.443885971657 0.918575180533808 0.108725661973003 0.083890644966159 0.434882093509659 0.637586363570299 0.764007973019034 0.0380529547971673 0.327484638337046 0.504103295889217 0.0267804827890359 0.979520118355285 0.677421336537227 0.583884627928492 0.311815805623773 0.357038449863903 0.499449400685262 0.910311290032696 0.582850503395312 0.996643848398235 0.863138336013071 0.315329314256087 0.360866167526692 0.991424900225829 0.83875496920431 0.506345107452944 0.365811857252847 0.647503691362217 0.938832073525991 0.952231166551355 0.913143906746991 0.110026737486478 0.854161754183006 0.801200094008818 0.0814547183946706 0.869503767082933 0.899590889562387 0.452611410818063 0.409173078716267 0.558935601469129 0.32336332754232 0.581059276186861 0.718726693824865 0.700416429028846 0.485503192844335 0.466586696989834 0.0879031863179989 0.69653569905553 0.892863287457731 0.56048873221036 0.779904832243919 0.247274861691985 0.387959606556687 0.0608457001205534 0.801272978847846 0.450598914735019 0.90229536288185 0.12388802388683 0.77814103896264 0.318372469500173 0.0308039921335876 0.74461259334581 0.46446190224262 0.744674382954836 0.660611756746657 0.302745381912682 0.77021894585574 0.242391820196062 0.406658581965603 0.541536490975413 0.263525009774603 0.636446202660445 0.554246115321294 0.0954490468255244 0.0374242002028041 0.811988800389226 0.743318694983609 0.182305676457472 0.596208648141474 0.203516034760978 0.333433661402669 0.480567202887032 0.407406837730668 0.973380589256994 0.904302125449758 0.678897808655165 0.654207363636233 0.893948532107752 0.489239490283653 0.472817686419003 0.710587549805641 0.832770295725204 0.294106834526174 0.0497472813492641 0.425061012429651 0.905786821430083 0.299329524904024 0.0510125782899559 0.676231615089346 0.324353387174197 0.287820279742591 0.537605791552924 0.0723188449279405 0.942794003479648 0.578780253478326 0.166775916176848 0.0558159782318398 0.829885208611377 0.554026638141368 0.917091839676723 0.286085713696666 0.0646836126712151 0.482152056281921 0.814398923607077 0.214538512923755 0.474495273209177 0.0148419694369659 0.927617617803626 0.36068395819515 0.750929703058209 0.920509991566651 0.490081398687325 0.82481440129457 0.162747442964464 0.102519595839549 0.86304971362697 0.175321461632848 0.947475642866921 0.0284277670504525 0.661150773784611 0.713673077141866 0.0141955943219364 0.062206913693808 0.697969501963817 0.19522625423735 0.859756183517165 0.556694314067718 0.269952176285442 0.362708461605944 0.891093465848826 0.475912516368553 0.163986993255094 0.506693943466526 0.226742351753637 0.487322849058546 0.243065897081979 0.0203326826309785 0.743170815748163 0.756044609160162 0.0757860159059055 0.348397375710774 0.314923023460433 0.878161316390615 0.655250417599455 0.452308142581023 0.715192723269574 0.958773657991551 0.0401725162193179 0.294842913083266 0.579997347309254 0.646862050073687 0.0391985979746096 0.879383204209153 0.437287135303486 0.80552932044724 0.227773029585369 0.998616535805631 0.253541749094147 0.0459294630703516 0.404788645354565 0.0528770556836389 0.154403738032561 0.418247439407278 0.55336887137033 0.951694975702558 0.740708276990335 0.615590512540657 0.52919445032021 0.364959680661559 0.311376758832485 0.662705505134072 0.207935578008182 0.175105119054206 0.838274617546704 0.419442435209639 0.736298401241656 0.0514675048482604 0.364698439224158 0.948990315215197 0.087229922413826 0.385477939562406 0.96296169022331 0.314227270134725 0.476196216340177 0.742350929998793 0.935494345284533 0.150573964749929 0.663550564735197 0.170200120827649 0.100582383663859 0.688196716194507 0.894054725687019 0.296848956944887 0.798558854395524 0.178715635978151 0.0676427518879063 0.0128411930147558 0.605926036823075 0.647664213420358 0.334820771222003 0.823097681661602 0.889411348996218 0.809249622407369 0.285762001054827 0.379592512322124 0.127681752596982 0.357390210030135 0.462750601028092 0.973464072593488 0.785040951706469 0.234225705328863 0.930736044046935 0.32633776105009 0.804825946483761 0.551869666189887 0.186130676036701 0.417424839953892 0.610782121301163 0.091239189018961 0.747016234146431 0.937956770865712 0.94980511931004 0.896988501579035 0.632335915178992 0.726558967316523 0.283261834403966 0.469986240426078 0.927524547413923 0.882865504208021 0.724037006439175 0.568233523610979 0.476743019286077 0.985218336207326 0.831586954582017 0.379558269816916 0.189732882890385 0.171215703983326 0.094135204940103 0.822304726191796 0.0590257085254416 0.249073291867971 0.36956988368649 0.951037131021731 0.0704064228176139 0.0912586784525774 0.597453028378077 0.055211841056589 0.950155283939093 0.178685479587875 0.591925108188298 0.443053890028968 0.539457058857661 0.319808442357462 0.439831779685337 0.0205153896170668 0.369828357021324 0.832771923302207 0.425744873217773 0.139751552934758 0.369366263453849 0.751553927129134 0.900086215343326 0.858784292771015 0.832903530916665 0.98309678001795 0.54623681580415 0.866868901781272 0.497611601862591 0.597089441136923 0.635869607056957 0.410156047865748 0.178052879753523 0.732833474203944 0.357742942455225 0.0225145340827294 0.131219892017543 0.0938554564700462 0.247987188596744 0.818526546016801 0.603561433667783 0.834069370247889 0.205389333479106 0.92127872469835 0.462881779216696 0.334271122955251 0.282710496094078 0.0874338125647046 0.176431297655217 0.472876509693451 0.507216179473326 0.311022119922563 0.994878495999146 0.0219027055054903 0.900712810822297 0.13854588349117 0.0631125135812908 0.25775681210449 0.817390051016118 0.76542589270277 0.288916557847988 0.144822778613307 0.485089497852605 0.858096315672155 0.734706002352759 0.108064386725891 0.255917246942408 0.545826204472687 0.343409916656092 0.833757255792152 0.237559382491745 0.237988744035829 0.953586545418948 0.542130453085993 0.545786813467275 0.229142127260566 0.269854792275 0.32386631245492 0.806781140146777 0.760639285317156 0.199973247721791 0.746775799694005 0.380296514634974 0.544835331628565 0.85959150596289 0.135942517025396 0.686733829192817 0.869993852393236 0.992592914116103 0.018531971864868 0.950678281756118 0.788895106834825 0.98349303958239 0.66484060033923 0.931534600032028 0.0713666134956293 0.145657375482842 0.259378881715238 0.691189901528414 0.564155660201795 0.335484327289741 0.244346213785466 0.867070020372048 0.501598219769075 0.627620885453653 0.677591531856451 0.780619848419447 0.590261358914431 0.231652119534556 0.837894639975857 0.928466767207719 0.251836989074945 0.882969224958215 0.360761403292418 0.290900040832348 0.872943360069767 0.183202547682449 0.280942187733017 0.337129880709108 0.787539226855151 0.468215399766341 0.973314920293633 0.936731581792701 0.0146603820007294 0.273827050116379 0.757812213106081 0.780230820635334 0.901821196293458 0.0502738312073052 0.654108663226943 0.51351414204808 0.649117393738124 0.0450167789240368 0.0916847147699445 0.369217047996353 0.781537489057519 0.0639141179597937 0.478155597308651 0.101747289921623 0.448695387479383 0.40873213166371 0.22504994366318 0.82287961215945 0.261270342865027 0.917152752685361 0.227261120544281 0.0805503307189792 0.133940092280973 0.312822017937433 0.379419659310952 0.926026921635494 0.505049566992093 0.398143730200827 0.703830148589332 0.888876015846618 0.201198979858309 0.429661172928754 0.715169440689497 0.0397305528819561 0.913007782669738 0.550168931663502 0.134640524343122 0.0787985869473778 0.201988600189798 0.664787204472814 0.202901797434315 0.815079291593283 0.0643276792601682 0.962301868293434 0.119475651797839 0.836545316174161 0.635970398583449 0.12260046111187 0.676160275768489 0.617547641040292 0.282753286086954 0.519952187577728 0.506257664777804 0.428006023466587 0.725421308048535 0.167511704300996 0.346517020394094 0.58648165143095 0.375253498062957 0.0633126615267247 0.0494692275323905 0.352999916146509 0.918095287575852 0.899544090211857 0.369583915746771 0.950752889830619 0.835222040519584 0.325051301689818 0.3479743368458 0.584176173508167 0.293996029286645 0.409548342514317 0.105082514677197 0.244891380395275 0.429280681568198 0.791005051468965 0.597765922623221 0.023588054231368 0.758571750808042 0.0773283252539113 0.308471764384303 0.889271785132587 0.0531780292699114 0.964990584473126 0.220770042419899 0.868419864417519 0.0428467208938673 0.664110847918782 0.213894179367926 0.0642995625850745 0.400376750405412 0.898783406221773 0.793291598004289 0.663901697935071 0.605139887856785 0.838633777529467 0.0931456897547469 0.137096844839398 0.429474089164287 0.410798727106303 0.960894542958122 0.706567418011837 0.509231968051754 0.29212241431931 0.367436534767039 0.595225782487541 0.194020207000431 0.163457329771481 0.658223269169685 0.0572916585742496 0.749985086962115 0.595985431061126 0.576262231424917 0.653607735086698 0.486955826180056 0.0724516843468882 0.538912608879618 0.312250474253669 0.995064366168808 0.942042942040134 0.19735738595482 0.617759882751852 0.588059696939308 0.24849574820837 0.445881325972732 0.699812144101597 0.786669937078841 0.474063910904806 0.131563504617661 0.36225055972347 0.304077621803153 0.312231390504166 0.546586003103294 0.86363160548266 0.0118289286317304 0.883674529148266 0.934260928430594 0.952944551692344 0.773700455231592 0.755176015731413 0.424146967858542 0.135975540864747 0.305633538856637 0.890776829167735 0.959724011521321 0.137428105049767 0.349490969846956 0.136865792062599 0.976569341071881 0.460628002507146 0.481160109527409 0.786430251528509 0.691984207741916 0.387984488822985 0.499149857826997 0.303888372008223 0.753405743259937 0.586870608450845 0.545028840645682 0.515420814277604 0.227460105835926 0.739281108169816 0.606559878143016 0.824165277208667 0.847411539799068 0.546953895206097 0.403361794396769 0.71696412981255 0.920522679567803 0.22080520831747 0.442364741747733 0.0334396286960691 0.365273394342512 0.0285496790450998 0.955362869037781 0.29012669327436 0.260268789234106 0.167532649817877 0.690292966223788 0.969233502077404 0.485670949218329 0.0988231833721511 0.666413328850176 0.200960095995106 0.315945192528889 0.98622372839367 0.708881623214111 0.277642029528506 0.433134390674531 0.295722944268491 0.163221054964233 0.415464810812846 0.427167782124598 0.861663174531423 0.132965441730339 0.788759930583183 0.612463272348978 0.618167260366026 0.0868930656067096 0.0818549741781317 0.404720841939561 0.12089622594649 0.497831542582717 0.476054585331585 0.601099112734664 0.0891777623607777 0.749294100885745 0.650995774802286 0.737660863676574 0.643343708729371 0.333911256482825 0.63929676375119 0.434999557270203 0.337537858090363 0.872706699862611 0.847575908941217 0.420508606482763 0.163152466227766 0.27404965613503 0.727856311919168 0.864169804006815 0.34556223730091 0.497580098186154 0.298178543061949 0.216401583561674 0.832808037486393 0.319101556460373 0.129426171234809 0.0358225740748458 0.808271661151666 0.0354071332584135 0.965932062049396 0.0897640381404199 0.534452356153633 0.78693900591461 0.512168495450169 0.731055925004184 0.45088960976107 0.959563876476604 0.653544179138262 0.158156181008089 0.22464604294626 0.466572635655757 0.339847539223265 0.433280502187554 0.395285305983853 0.64995316225104 0.164644083501771 0.842441518707201 0.549098217880819 0.784067623778246 0.317704718289897 0.452704270989634 0.399527908030432 0.26966741830809 0.208883071464952 0.648628266165033 0.557782629469875 0.810715978699736 0.6364769092598 0.711449551789556 0.0149895344977267 0.393339342786931 0.139692099236418 0.348984700967558 0.738175937975757 0.439177298955619 0.670011918891687 0.235123949886765 0.667404640801251 0.609844410133082 0.12581991053652 0.890572014241479 0.954995846620295 0.162681668892037 0.462083539019804 0.797146124241408 0.542917108465917 0.441117437819485 0.288604004515801 0.184180962566752 0.753015722241253 0.58746515304083 0.36026296619093 0.0290430978802033 0.241808305373415 0.300911161408294 0.669882606850006 0.232124505031388 0.937050989342388 0.931603419501334 0.474588366879616 0.0318320837290958 0.999337802052032 0.39071141076507 0.187902600518428 0.202665495658293 0.432349895793013 0.750550071932375 0.136594690196216 0.598509381865151 0.327460096753202 0.0234630680270493 0.0864506502542645 0.806779511878267 0.919203182307538 0.661048900280148 0.374117896719836 0.764333911852445 0.0959763342910446 0.865629873808939 0.791741414235439 0.929872334501706 0.28425702617038 0.996435864064842 0.050697156356182 0.583248428339139 0.645866288966499 0.460828341539018 0.0595824078586884 0.661362165864557 0.113769061409403 0.0881244123191573 0.333462083262857 0.4098982635024 0.297992824562825 0.204600301620085 0.869375231142621 0.799881347494666 0.694247892824933 0.360176386516541 0.995807128832676 0.440779421816114 0.588901036463212 0.633227029377595 0.520808370991144 0.525628213125747 0.956897943378426 0.257353222335223 0.325808426032308 0.862447660192847 0.395613324870355 0.0674877466727048 0.67424016778823 0.52767579420004 0.171464253270533 0.640601085198578 0.932810117907356 0.291033650129102 0.168242610616144 0.748885970220435 0.679178949359339 0.204014513352886 0.512821606073994 0.912725351613481 0.840358509423677 0.0362310772319324 0.369321041661315 0.124560067511629 0.0471032489696518 0.956851241760887 0.790696439035237 0.83100769137498 0.660278234155849 0.0327841030992568 0.811062595436815 0.293110332353972 0.0956108670728281 0.406763792682905 0.882286949565169 0.972935394046363 0.653419189476408 0.820293082967401 0.809349547245074 0.216761960135773 0.845006799963303 0.926284053446725 0.410148310363293 0.84999513423536 0.863127071363851 0.304094341059681 0.141302288065199 0.338346044002101 0.0931372708873823 0.537663875606377 0.853904782570899 0.210192335804459 0.531723597338423 0.476040636943653 0.6520671918476 0.4634686824237 0.644402958478313 0.702585355753545 0.370192905918229 0.509039550232701 0.584869199760724 0.261822290853597 0.0545701264683157 0.316895288587548 0.622128033428453 0.671189556024037 0.329548301098403 0.108420705306344 0.646653469430748 0.109241112452 0.0532934922701679 0.758658239895012 0.770813078538049 0.845487719348166 0.189136209380813 0.0233031422784552 0.440962326112203 0.655775349561591 0.718351201829501 0.807961532243062 0.883589749466628 0.473016422998626 0.527032801476307 0.156020301172975 0.401992138675414 0.793338364623487 0.180112469077576 0.0222616619546898 0.880070130447857 0.310550381215289 0.414124178101774 0.462772119804285 0.351231337867212 0.204324318405706 0.746399438474327 0.54950094418833 0.326616222395096 0.13981323950924 0.162883591013961 0.556810721205547 0.531872008112259 0.773778552650474 0.666900520434137 0.869172269455157 0.995765813824255 0.228651415444911 0.141302287834696 0.227965066384058 0.441046621508431 0.994930717917159 0.371627203945536 0.997739719897509 0.374878904796205 0.494076339111198 0.317036615102552 0.771675706335809 0.403951737468597 0.349864730769768 0.991982758063823 0.258814959591255 0.603905227903742 0.17719919383293 0.0599863726552576 0.635910984992515 0.760481647765264 0.988679886616301 0.358443672556896 0.702132358038798 0.872403551486786 0.406480329898186 0.96315678924555 0.855152607664932 0.487882745689712 0.872073987082113 0.151379423588514 0.752446660837159 0.218003444571514 0.330082808127627 0.685955930827186 0.417175006999169 0.233998374473304 0.751920404869597 0.873074542637914 0.995399671003688 0.829016819407698 0.664523421516642 0.0624403528613038 0.21700979440473 0.721052028832492 0.788955409703776 0.97847844371805 0.363931297711097 0.516320234166924 0.0778377739130519 0.657746818303131 0.529974373879377 0.62603717765538 0.490869029553141 0.113265997665003 0.275884078559466 0.778430341985077 0.564011325170286 0.656564276772551 0.502013985363301 0.873467850850429 0.86162898573326 0.789853999784682 0.346053352495655 0.279162253525574 0.679136610920541 0.743865699388553 0.181752725092229 0.229910655475687 0.309596435767598 0.237757398751564 0.527190249555279 0.0583939239778556 0.714291320368648 0.0146310109319165 0.435434909800533 0.628136566895992 0.701859085301403 0.0796265909890644 0.467733472394757 0.290078851361759 0.213762061882298 0.618546320307069 0.154119126885198 0.175933904498816 0.983125686624553 0.136460012290627 0.838367004496977 0.670719900366385 0.947156407041475 0.677584693774115 0.739000468116719 0.0803277975390665 0.086515805888921 0.436561855319887 0.860215482474305 0.1276923859003 0.116309107039124 0.977061843429692 0.0144307652534917 0.320097367125563 0.309736291447189 0.754325422691181 0.217256668170448 0.552592825551983 0.393682414628565 0.295707984205801 0.175941960094497 0.645330622510519 0.99462003234541 0.724730618628673 0.137583488288801 0.0617680868017487 0.387703434557188 0.971263028364629 0.809460723593365 0.349403490521945 0.353011069232598 0.16927278595278 0.106687653430272 0.227090073288418 0.576689107231796 0.719175961089786 0.499889138522558 0.148638418645132 0.591329169059172 0.813558988994919 0.540138063030317 0.544693148566876 0.699223797488958 0.822011478813365 0.83884941108292 0.403231962572318 0.425438225124963 0.826462340874132 0.576043499459047 0.629886775522027 0.808647871853318 0.681905031581409 0.849107966006268 0.577451506850775 0.59411838425789 0.0674025917332619 0.862531690972391 0.148049730889034 0.811784257455729 0.929309241264127 0.951077947453596 0.107347137443721 0.822211804937106 0.76091798315756 0.672993230128195 0.738823122614995 0.315390300333966 0.888048869504128 0.977378529668786 0.181124492355157 0.698805625219829 0.240959867760539 0.019850439010188 0.728074556833599 0.169528952881228 0.0106689599645324 0.924703295617364 0.614511811621487 0.528855990138836 0.999411342900712 0.262668351065367 0.722396452154499 0.394494882582221 0.636170284678228 0.625777165256441 0.304469397866633 0.2384038040624 0.477477244373877 0.492802130489144 0.327366965971887 0.202760157666635 0.270151110175066 0.995914703351445 0.511287639066577 0.225496104448102 0.208176385643892 0.323372342258226 0.303182530978229 0.975960519397631 0.545422379130032 0.646982785584405 0.931841784964781 0.489069511636626 0.4242815736169 0.0765700470167212 0.293387540227268 0.160042167496867 0.236860122994985 0.595349972306285 0.742588262350764 0.738699329721276 0.629223519337829 0.329857758784201 0.788786290599965 0.779029300925322 0.134712318906095 0.726417752825655 0.0657810126314871 0.952814703041222 0.878074791575782 0.27752422623802 0.557129977545701 0.866350373865571 0.887358972781803 0.142099785814062 0.956157152892556 0.0969737061485648 0.362068332643248 0.639280076073483 0.213950169999152 0.789349605580792 0.142757550049573 0.456676300172694 0.528783994808327 0.408489475399256 0.548791997830849 0.13263987792423 0.767801268845797 0.40131685096072 0.0648873668257147 0.0248290854995139 0.656557301310822 0.212132640860509 0.884733996030409 0.644539341179188 0.430206324786413 0.813616201288533 0.554797681828495 0.708264447904658 0.593054194152355 0.123393453462049 0.113316599382088 0.566124369369354 0.577282665963285 0.498893185637426 0.661752600404434 0.454886916982941 0.142955642144661 0.112162187204231 0.97570762444986 0.274172830821481 0.510375219075941 0.903343747442123 0.667611088375561 0.96160891026957 0.0763702646479942 0.871253830031492 0.0959154249704443 0.673472038803156 0.113359400900081 0.724321713706013 0.193117248208728 0.764933499833569 0.71004960114602 0.0380513392062858 0.181065738692414 0.450026816693135 0.545109408588614 0.931988664972596 0.980625642600935 0.804332206097897 0.63372626908822 0.267565414248966 0.37978886942612 0.182662909210194 0.678421596128028 0.643963440309744 0.54500049139373 0.0243344851094298 0.466290894723497 0.759797857049853 0.235838315815199 0.762354391433764 0.344382065334357 0.392121385494247 0.372179455505684 0.0929760893620551 0.084254637430422 0.617820322769694 0.942305994534399 0.664559976882301 0.0508508066786453 0.273628434089478 0.169076418706682 0.234067958749365 0.792056134520099 0.213036386356689 0.729810149536934 0.375070230725687 0.137480853204615 0.272103444226086 0.594374486415181 0.595435070772655 0.938562188481446 0.156502950247377 0.674108669201378 0.0642020257515833 0.0549569960590452 0.852851609094068 0.115990739746485 0.112001460460015 0.5099184348993 0.809330165686551 0.867835971110035 0.838995013646781 0.943908645245247 0.841103626207914 0.755324007913005 0.289688449783716 0.734171847761609 0.111937838818412 0.370209947417025 0.201677181851119 0.252026421658229 0.585444031560328 0.743575486342888 0.788544125074986 0.347122548881453 0.445007201409899 0.258387072109617 0.900942948274314 0.0711790816346183 0.415769657529891 0.552812980639283 0.585043424721807 0.577408265764825 0.375947573101148 0.727440129807219 0.777245907569304 0.351548205742147 0.47096887327265 0.376713482118212 0.0798800753313117 0.989541101204231 0.765863950869534 0.927860831192229 0.891854100280907 0.0639846456819214 0.946778855277225 0.48480761239538 0.355037323308643 0.838855017360766 0.248437833804637 0.288338657140266 0.202600917662494 0.822923707487062 0.897600408066064 0.109181407506112 0.19632827046793 0.733579316840041 0.449266479378566 0.0336849486455321 0.253496994760353 0.14870399056701 0.342074846427422 0.262543158330955 0.0347035891842097 0.884043115754612 0.426956367916428 0.0694879177957773 0.647579046033788 0.821464438680559 0.293576208695304 0.796182496082038 0.322300334896427 0.771887043095194 0.498558142422698 0.343219348848797 0.92884785464732 0.646050035287626 0.826136577683501 0.0397218103893101 0.583025784748606 0.919388559893705 0.059538350563962 0.742598048557993 0.429740488091484 0.638237128371838 0.0697340415068902 0.132751042055897 0.0596149075357243 0.621271281826775 0.334016887866892 0.288333942214958 0.564300870450679 0.0272024140902795 0.560092154552694 0.613618597085588 0.0918893863237463 0.247585387756117 0.520386371230707 0.287182091840077 0.665731995981187 0.434782847962342 0.738157953952905 0.838491548828315 0.858634866403881 0.93250817252323 0.434651766815223 0.54261101588374 0.414959449651651 0.527637691472191 0.805439018851612 0.727330493906047 0.620546577638015 0.550474926282186 0.696406096580904 0.881094357441179 0.132760363800917 0.396075594311114 0.609770977620501 0.131164228469133 0.115411006545182 0.925758715569973 0.398976801375393 0.275530489587691 0.699936271454208 0.50074930985691 0.232038263042923 0.36266993429279 0.397348941776436 0.0880907412292436 0.313220817407127 0.808687359208707 0.73679700960638 0.166165402615443 0.534254940813407 0.306786186539102 0.781868482115678 0.450127617209218 0.16963313993765 0.578561474489979 0.146536872594152 0.688325753016397 0.0700725376466289 0.441254760739394 0.129543501765002 0.531196904338431 0.322903393320739 0.489271553389262 0.334237772955094 0.941514797797427 0.835382710790727 0.0631287015299313 0.513375913023483 0.731730521211866 0.862725593918003 0.38442674978869 0.226659145480953 0.523456887793727 0.0739217448118143 0.0947834962210618 0.931617723784875 0.101953543182462 0.0256359849777073 0.864840368959121 0.761878130040131 0.804321633877698 0.483880410059355 0.3351681195735 0.0543794060684741 0.146303113489412 0.964948412687518 0.106738106242847 0.0910812935349531 0.149062665342353 0.476515568569303 0.670823803904932 0.360566235580482 0.932447930276394 0.738849444137886 0.116260397054721 0.730709612530191 0.972357088576537 0.299871343236882 0.344165439007338 0.611998131771106 0.288630872329231 0.0838516209204681 0.9455945241265 0.453800846904051 0.400667199715972 0.597480765646324 0.399549386007711 0.569392754440196 0.208057818929665 0.574581652483903 0.444027803894132 0.91279053905746 0.870328190962318 0.172006383934058 0.936873986828141 0.277232596755493 0.71786052205367 0.102524384756107 0.631342428438365 0.726829123201314 0.853775942136999 0.454500933443196 0.430578618100844 0.554223535081837 0.27317285820609 0.385396589525044 0.810875018166844 0.460329879082274 0.0922123862523585 0.35846864817664 0.465377953336574 0.329017304389272 0.81742115569301 0.709916235951241 0.874711922674905 0.166399465752766 0.0396488082245924 0.178150917929597 0.833037103102542 0.0277900993917137 0.285384723588359 0.988898974477779 0.158827379150316 0.857354171676561 0.996446203708183 0.0580324552836828 0.120977135032881 0.519871423938312 0.0777222037292086 0.378490065743681 0.602368069130462 0.940410211235285 0.643634574788157 0.888079690202139 0.0597352972929366 0.333369293163996 0.615281541906297 0.738722016913816 0.278589000205975 0.890639714160934 0.388769192539621 0.948963346441742 0.495761841351632 0.494051593532786 0.356486975557636 0.925959769620094 0.192093151910231 0.270186016296502 0.840438060390297 0.553364043268375 0.177290536838118 0.0803941570874303 0.426547531452961 0.636372998806182 0.588402074277401 0.654998247120529 0.999318046849221 0.707888380114455 0.0895572713203728 0.45856779151829 0.136709177019075 0.703534420083743 0.42503884202335 0.682466569619719 0.973178266291507 0.901933155427687 0.123508930983953 0.0734093381161801 0.0679272314184345 0.199697033544071 0.425217724053655 0.571296755378135 0.195334974122234 0.106921628285199 0.968797403411008 0.514929376379587 0.717720755347982 0.359739695459139 0.967593413407449 0.120400815571193 0.974570260455366 0.19124307473423 0.29629843046423 0.393861525547691 0.142814110021573 0.635537242970895 0.610241856554057 0.769900841105264 0.405994418293703 0.696768404534087 0.134644989173394 0.39318415224785 0.549520936578047 0.164215755069163 0.905943546653725 0.316600976518821 0.371604266888462 0.581326321673114 0.0334332069009542 0.351690860872623 0.684870961166453 0.611061896048486 0.30870650450699 0.0692006413498893 0.665497481981292 0.791711059382651 0.316514483743813 0.690914903020021 0.463616329773795 0.436451547043398 0.864062559797894 0.825187061568722 0.105566028365865 0.878372639319859 0.916396856920328 0.432887197432574 0.820853605642915 0.372018418505322 0.387613983976189 0.713813137968537 0.796545809025411 0.074384377063252 0.914792105411179 0.879296889381949 0.57329644751735 0.0165558313019574 0.100988135314547 0.940146096355747 0.628717528905254 0.462232504843269 0.984132432551123 0.282123802644201 0.659177916957997 0.0849116398557089 0.333978190673515 0.891531875762157 0.522960867970251 0.322426992473193 0.733852345475461 0.0254007624136284 0.762201343874913 0.47747621310642 0.417192933396436 0.214677392656449 0.124610120402649 0.433580941699911 0.25213213925017 0.3560725106881 0.696801050810609 0.358804367685225 0.7494810650195 0.16022600509692 0.0415957646560855 0.789247067999095 0.595559889171273 0.302995167614426 0.70833969908068 0.331976212642621 0.494858895237558 0.500316085785162 0.0343454708415084 0.885364888303448 0.958227213476785 0.284163900921121 0.154947499500122 0.340798993632197 0.72910039319424 0.112912758134771 0.995582524819765 0.556993519931566 0.78802910263883 0.582706702437717 0.228757680710405 0.0788094111066312 0.919591475480702 0.224382085038815 0.111831706322264 0.725549331351649 0.448400772761088 0.378543844243977 0.371597736757249 0.576782060526311 0.683477598971222 0.931082126940601 0.0969015563814901 0.942480925985146 0.317542264391668 0.0619594463845715 0.430379528161138 0.0256040173000656 0.337074834215455 0.946292014517821 0.344605269045569 0.87024760665372 0.505519865520764 0.381983110839501 0.180300152378622 0.479473419047426 0.768036748419981 0.739071056691464 0.926813661148772 0.963150863721967 0.83827688154066 0.600747300474904 0.304470449648797 0.928939397498034 0.874850821539294 0.908941944106482 0.0166758875222877 0.874684909645002 0.646132639718708 0.626443900642917 0.742815207345411 0.270222040815279 0.277896134613548 0.207083050592337 0.114558249088004 0.659457947793417 0.34264922989998 0.574431966340635 0.735648798632901 0.109841664163396 0.0656164819072001 0.641998955789022 0.0381530746398494 0.366266036292072 0.0812910739518702 0.604672308103181 0.549182603172958 0.749948455530684 0.234603994931094 0.79934395757271 0.846595579965506 0.485152167750057 0.943915046295151 0.177838062639348 0.985697585372254 0.760215323751327 0.797866222762968 0.244117598109879 0.753467418770306 0.398656463518273 0.661685717385262 0.219919435319025 0.72878672423074 0.863356840934139 0.956355974527542 0.179527850840241 0.663056952739134 0.0364794326666743 0.429872380145825 0.257726928167976 0.0168334547709674 0.11662958458066 0.923642353750765 0.605977656668983 0.894101708747912 0.328392596954945 0.50018153580837 0.190964021920227 0.370129009056836 0.495429456289858 0.626013046365697 0.94145420242101 0.687077792156488 0.546470699841157 0.569315873843152 0.0572782938182354 0.673015050631948 0.707363915380556 0.0204418005933985 0.961807505320758 0.559731396266725 0.255882779927924 0.721747105864342 0.496480618864298 0.777807113453746 0.382372758213896 0.79922107885126 0.786750001374167 0.605415750748943 0.32185528513277 0.833102999341208 0.419248637142591 0.988070649807341 0.94503799905302 0.310801508901641 0.436951745182741 0.738106464110315 0.764649996941444 0.919102814905345 0.505360538156237 0.677570574814454 0.606966608276125 0.787465321812779 0.113648753250018 0.451600267367903 0.596091905622743 0.766755724996328 0.199597449619323 0.379105107292999 0.352155388314277 0.179259959871415 0.053960927692242 0.831120846816339 0.252317706078757 0.3885733063519 0.441055119207595 0.104788848476019 0.595379191243555 0.651727887566667 0.940815652629826 0.570948194123339 0.445131892340723 0.0304999590897933 0.261678415443748 0.979366133804433 0.278035922525451 0.0135858538653702 0.29776938873576 0.90741459620418 0.27217577931704 0.92317071946105 0.114097766501363 0.476301246343646 0.50720130561851 0.436951969692018 0.74888883467298 0.955359827328939 0.347164357164875 0.128252527094446 0.569404486087151 0.747695753423031 0.280419946655165 0.994655603696592 0.419596990714781 0.198243260604795 0.394149573945906 0.724880694090389 0.269848191149067 0.0191351980948821 0.685886892380659 0.278934176303446 0.187621864576358 0.96473374125082 0.927374615555163 0.469930516255554 0.0633541484898888 0.930717714040075 0.292488022604957 0.224276208630763 0.270123398953583 0.967924598704558 0.405989132875111 0.198519764293451 0.928626680048183 0.98997403438203 0.0146588574582711 0.894769137946423 0.498606243419927 0.248180510676466 0.596315211676993 0.0852499290043488 0.909696346907876 0.529778275629506 0.754211637517437 0.0319712958461605 0.254844677846413 0.626453963683452 0.456647511583287 0.0213739458215423 0.88486461870838 0.28708691050997 0.443747378438711 0.13829356756527 0.286809803135693 0.713634803842288 0.883756335810758 0.981765824717004 0.694251754661091 0.599349875445478 0.698533247292507 0.577374367399607 0.399901748937555 0.715623224647716 0.304889158296864 0.409628608960193 0.205826792339794 0.933249400733039 0.885635001545306 0.649554002967197 0.408042905242182 0.441399555392563 0.874156090952456 0.612893755747937 0.621445750659332 0.211250885978807 0.612825657289941 0.906894444169011 0.31144910890609 0.575840931700077 0.889086316959001 0.518189021262806 0.455415132911876 0.0548289384110831 0.407733760578558 0.681234717415646 0.0567322731972672 0.955121989024337 0.505766900638118 0.0771821192349307 0.271995169210713 0.667497596170288 0.847358672013506 0.0653044356801547 0.236362078899983 0.862049315965269 0.594830145048909 0.922192010686267 0.639540709676221 0.114619367935229 0.815343607009854 0.25745728953043 0.200475462065078 0.126553708733991 0.487760707610287 0.579560591711197 0.379403092877474 0.446794726520311 0.787661814913154 0.524582113074139 0.727673952069599 0.0357156869140454 0.598467520335689 0.857426429779734 0.532003415420186 0.832854068342131 0.367989519324619 0.942291277651675 0.534770740503445 0.336410489138216 0.58442344028037 0.466743856710382 0.775455101719126 0.930390425615478 0.642344042912591 0.528123982714023 0.499577716956846 0.276074683708139 0.355269463134464 0.161709296396002 0.489566376942676 0.448916147174314 0.755201580745634 0.75950672499137 0.504904241953045 0.370458187139593 0.364402223897632 0.859157548202202 0.822507883806247 0.273017969855573 0.4892647916032 0.882564749137964 0.406377523089759 0.461387091882061 0.633534447809216 0.945582171736751 0.150099295896944 0.853412045561708 0.134500958635472 0.289117510246579 0.428822766547091 0.544948804932646 0.0649000921682455 0.307332492982969 0.872063765225466 0.766515690234955 0.173513420431409 0.0490530758467503 0.183183970346581 0.391385505860671 0.110435190163553 0.923260065393988 0.251020971846301 0.303502477211878 0.827058365519624 0.371849106240552 0.274443450476974 0.0531338991364464 0.618047047634609 0.169209491163492 0.448093296703883 0.686496884315275 0.532582499065902 0.826031034812331 0.214257729037199 0.994033648690674 0.994691696905065 0.387090825499035 0.553122460453305 0.53717758390354 0.291127751325257 0.328534434954636 0.788724168606568 0.146231563258916 0.713424091283232 0.858451714087278 0.639692314520944 0.808300059039611 0.223154104121495 0.573422440094873 0.352574764958117 0.25394698649412 0.14610736237606 0.524725144845434 0.823100610424299 0.737926581699867 0.458591662570834 0.900465481814463 0.806648252091836 0.774731402290054 0.954765302562155 0.43740143426694 0.107148615231272 0.283828599313274 0.188604344369378 0.048911872189492 0.441260225719307 0.125419263590593 0.50113673173124 0.953602150888182 0.134881055145524 0.949492461099289 0.69087914634496 0.387675096599851 0.593515520608053 0.347367308018729 0.441046662307344 0.290887991553172 0.578918580235913 0.940347382060718 0.115692359081004 0.572935476247221 0.526810215511359 0.12697427661391 0.520200581736863 0.132433822203893 0.231631062454544 0.383920527701266 0.267405823881272 0.415826831099112 0.904231123584323 0.946940385091584 0.0471615709015168 0.34835584633518 0.223290361429099 0.0296703286236152 0.846896080560982 0.795854689257685 0.796863301331177 0.714770258816425 0.803001812070142 0.0380113106314093 0.757457497669384 0.793002403548453 0.728945438920055 0.828823559563607 0.244209626629017 0.628131568452809 0.517045189603232 0.194306497587822 0.968427044241689 0.389369253511541 0.919862460712902 0.310210001871455 0.375683639396448 0.678627800061367 0.740077311878558 0.508290568385273 0.430604199711233 0.0357028486253694 0.142295487138908 0.931154863566626 0.333437963728793 0.183768977902364 0.195218416466378 0.671333327477332 0.645047777702566 0.802045861713123 0.521777149033733 0.186443722874392 0.543304765913636 0.211664506057277 0.744531606580131 0.448769890214317 0.953495718508493 0.704351219406817 0.678774336390197 0.681338361178059 0.667822566663381 0.527068296300713 0.625989527981728 0.0660315714380704 0.114805121931713 0.148478864235804 0.486778033734299 0.982695898651145 0.732760545569472 0.387443853428122 0.149349526192527 0.163984755538404 0.681226313069928 0.387941654343158 0.978733448453713 0.435782557574566 0.178187931303401 0.332872992588673 0.774188308126759 0.270901506615337 0.862586383414455 0.207647421965376 0.885310959054623 0.122914101723582 0.482433209663723 0.328990977564827 0.461952652186155 0.20146680029342 0.951992466398515 0.899127767032478 0.129496106104925 0.922989730869886 0.565508535814006 0.813172397390008 0.621074094914366 0.188223259234801 0.953461024679709 0.57696350320708 0.819406987265684 0.572934157312848 0.493336066103075 0.393018273315392 0.829072721065022 0.784185860182624 0.336444058115594 0.070852854673285 0.094008063999936 0.598369457726367 0.263822656520642 0.0569875335600227 0.504813593681902 0.263320479518734 0.792368424849119 0.394077352492604 0.59827597865602 0.852728578241076 0.96582076883642 0.68748648225097 0.118127624802291 0.305939453030005 0.957010937468149 0.282123257045168 0.416891946441028 0.887281897410285 0.504187876186334 0.70055895277299 0.756168664135039 0.235351312321145 0.371449174773879 0.616940229118336 0.0448489623889327 0.0215262995683588 0.857395958984271 0.215844950152095 0.743308859679382 0.422147796654608 0.796867688943166 0.763064653037582 0.623932705838233 0.0991393067245372 0.370057295861188 0.686311030050274 0.18227529855445 0.615917494397145 0.512362067624927 0.232917494385038 0.401710965700913 0.399142242583912 0.210811338305939 0.218286062565166 0.3316390299052 0.761654348229058 0.591087464538869 0.629123959385324 0.583527672700584 0.127026644439902 0.665074499589391 0.906168985546101 0.139207098577172 0.651050385646522 0.21246115763206 0.66571292767534 0.696557735539973 0.580455132557545 0.125463902442716 0.901462471268605 0.717833527924959 0.060326589725446 0.131667217761278 0.88054745998932 0.687644897056743 0.92123076453805 0.134010888538323 0.956119144670665 0.357178511382081 0.389252101390157 0.0807420415873639 0.133149280482903 0.243562338724732 0.896387014489155 0.417147088325582 0.42312203967711 0.460315039111301 0.578880865443498 0.580844981621485 0.899114371619653 0.303482928308658 0.0558073804946616 0.60211774220923 0.344202533287462 0.892898625079542 0.204832866031211 0.521735644782893 0.694258392206393 0.185236559775658 0.111917312585283 0.540429573573638 0.535117873104755 0.402619278600905 0.626532435899135 0.899564222746994 0.336919095311314 0.901801410664339 0.734981487682089 0.119258105996996 0.705557065415196 0.987786071621813 0.993750536961015 0.316081998201553 0.348653053513262 0.308729056394659 0.105865168075543 0.788440200560726 0.381431957161985 0.404992668505292 0.925107388573233 0.197693924668711 0.355530921705067 0.668732286549639 0.0370659580803476 0.643264716269914 0.443044659793377 0.66900118296966 0.248018098960165 0.18595217802329 0.246621902738698 0.887989436320495 0.173804984220769 0.880108572244644 0.308381885068957 0.14030626349384 0.257711900568102 0.371515046579298 0.346399640997406 0.887068199384958 0.799685808212962 0.944099998374004 0.264268995483872 0.323760230208281 0.751643454006407 0.154610476731323 0.780368813164532 0.410525866737589 0.174420539329294 0.282006993279792 0.868503856703173 0.106309193486813 0.135725884705316 0.498713097157888 0.954322070770431 0.123629376522731 0.612314419010654 0.82440061848145 0.935274637371767 0.406669041931164 0.0358693330874667 0.0605619187816046 0.242994023456704 0.944318276711274 0.415966092774179 0.36271072168136 0.160329260693397 0.750427137890365 0.486026137645822 0.82490185180679 0.748481166395359 0.426046688829083 0.1569475429249 0.486735228528269 0.970985511157196 0.163376729788724 0.846108228643425 0.768356740523595 0.633039002858568 0.0202422337443568 0.938167230794206 0.951204511446413 0.156814103508368 0.747934114045929 0.268825850817375 0.414914439690765 0.956703494142275 0.208611733333673 0.980862443414517 0.103123638508841 0.112583908287343 0.122422970624175 0.946587374911178 0.97148599834647 0.265714457661379 0.384138367623091 0.508432548835408 0.318380591941532 0.873758071502671 0.367044746256433 0.827853248680476 0.0446114348014817 0.716810307074338 0.571225433575455 0.662171484464779 0.854640399201307 0.851454373076558 0.876025632943492 0.349993609467056 0.493765091805253 0.605313498298638 0.951595005686395 0.964614161939826 0.719420459067915 0.123703430469614 0.371136941378936 0.726067010788247 0.683844399414957 0.949649307106156 0.496353640658781 0.349657166411635 0.810941924927756 0.0350315603567287 0.568469153933693 0.154252514669206 0.203145821730141 0.51688549481798 0.456666405859869 0.159320928449742 0.0113613647827879 0.577221624564845 0.229725717226975 0.959053737232462 0.954818506189622 0.516481897442136 0.641142742871307 0.731563187348656 0.137732546543702 0.26993004022399 0.234662980248686 0.578665106727276 0.715226055521052 0.640447270297445 0.732133362079039 0.823143656735774 0.819145639797207 0.402365861795843 0.378028148510493 0.643536757894326 0.519584362781607 0.469058671360835 0.263343813039828 0.586196973207407 0.0152901134639978 0.227345319821034 0.225831906015519 0.145871923831291 0.559003096241504 0.770306798594538 0.409298562575132 0.582799377976917 0.914701333129779 0.88110629077768 0.101605383693241 0.976834440196399 0.809163387103472 0.345029099916574 0.390537270167843 0.653738253577612 0.222419154103845 0.835537114855833 0.520480825556442 0.938421952934004 0.387439412800595 0.728456447343342 0.149818299487233 0.969243269152939 0.72976715070894 0.760043078113813 0.0704632215900347 0.328632304172497 0.485157970415894 0.444989221075084 0.440050899356138 0.611005310490727 0.535197277702391 0.377673792887945 0.0538288274942897 0.655555297739338 0.986439739048947 0.135822347397916 0.833011097598355 0.257442436651327 0.17597022959264 0.842655165100004 0.443052594605833 0.840196550413966 0.688048545143101 0.582278953718487 0.446392023263034 0.376512239056174 0.261167560259346 0.021615823910106 0.143654418969527 0.526753407288343 0.606635689439718 0.882504941618536 0.884559408489149 0.448248745405581 0.802552630321588 0.679957863548771 0.433540010016877 0.158787311390042 0.799894760886673 0.439847221958917 0.625482626603916 0.555094609407242 0.904047306498978 0.559757246873341 0.210958809782751 0.694759982810356 0.739927556815091 0.205161411385052 0.764571940090973 0.260113831041381 0.883153726404998 0.916332001630217 0.149425791117828 0.213917048887815 0.404114131436218 0.917550936022308 0.811777235432528 0.193562232509721 0.635138793634251 0.711880275832955 0.0961928135575727 0.781479543996975 0.321454692585394 0.0184646801650524 0.357993539986201 0.239115574995521 0.635561533076689 0.82629141993355 0.130001961463131 0.462041047757957 0.386974909331184 0.462396691427566 0.226567775967997 0.723471048749052 0.164236831972376 0.0453938846662641 0.791308417438995 0.462070967652835 0.369773355475627 0.670892887529917 0.153596075591631 0.0696011725836433 0.933516097699758 0.840013650958426 0.62817814606009 0.231457540295087 0.432943965317681 0.0311955171800219 0.264075518506579 0.708731252248399 0.805407272225712 0.463641963477712 0.447253794283606 0.612221857109107 0.414583672063891 0.267601900002919 0.510493030895013 0.036763097140938 0.26611307434272 0.0821279110736214 0.612224212842993 0.939243648357224 0.243695751863997 0.878288679765537 0.929497983031906 0.526354420420248 0.239119211630896 0.0737847674149088 0.171253088465892 0.162639153196942 0.177781225834042 0.638976725316606 0.871247575811576 0.941570364304353 0.884519301312976 0.171558148628101 0.596805089535192 0.137092931601219 0.519454067877959 0.631674514077604 0.912880309806205 0.581784931889269 0.64032299450133 0.494185663603712 0.126480167654809 0.382252261964604 0.0728955228207633 0.900902673983946 0.188258715334814 0.968280202497263 0.657646157701965 0.402852617499884 0.729939273027703 0.19115154317813 0.686675582174212 0.361409803600982 0.486182456493843 0.552726720902137 0.902905570566654 0.603739210669883 0.550454746724572 0.152201960575767 0.906961579818744 0.0515580291091464 0.994654486682266 0.235085067139007 0.596269200413953 0.527817735234275 0.243372997881379 0.325500498421025 0.263736989635509 0.255251635024324 0.573252799825277 0.981472593243234 0.270108142464887 0.0305011809826829 0.559920160162728 0.93341561343288 0.82562990519451 0.995463106860407 0.3245117063215 0.767761900429614 0.62582892916631 0.0700429134862497 0.366252630967647 0.589975052883383 0.283582093429286 0.229100310679059 0.0535794709878974 0.0934300941415131 0.37243644279195 0.994489542667288 0.658499654380139 0.290883737171534 0.672893810782116 0.283441266182344 0.814482793265488 0.25147525184555 0.969421202205122 0.759538121714722 0.293398030849639 0.33902131742565 0.139837167495862 0.56780166342156 0.0751443402725272 0.596982522627804 0.49586172608193 0.543070128825493 0.0963519094977528 0.880905377794988 0.552365462426096 0.969155542268418 0.21002294286387 0.81001559619559 0.0101299030496739 0.505555904330686 0.988400350669399 0.0981340936385095 0.0493660376290791 0.169090594369918 0.432147289079148 0.253081966543104 0.866472506450955 0.261713556677569 0.980986259588972 0.740014709057286 0.951044176325668 0.121751608825289 0.741774246804416 0.647678143598605 0.342050655668136 0.392768051503226 0.466455766130239 0.424350660007913 0.832564346266445 0.831819599899463 0.988633298866916 0.693259153971449 0.686158318333328 0.755129562825896 0.605045407023281 0.246925808084197 0.71166909489315 0.687054506810382 0.220016323057935 0.59790002657799 0.697779157974292 0.153549519651569 0.312016332054045 0.870220744141843 0.77478824601043 0.995050986430142 0.0513018679432571 0.813742134857457 0.828650556034409 0.425731237160508 0.956213853009976 0.604389299177565 0.939070290545933 0.989066545988899 0.548411888412666 0.0272153796162456 0.617125783269294 0.21780320788268 0.893909771065228 0.297198810165282 0.475142506484408 0.462286287031602 0.491342425341718 0.729901378212962 0.850014842876699 0.191843621144071 0.488412767834961 0.882650904688053 0.564212511528749 0.494530540970154 0.144541242828127 0.966442805440165 0.745092436054256 0.0341004639142193 0.535993692320772 0.847171899196692 0.136626409161836 0.450669094168115 0.712965792475734 0.980215031269472 0.815332564334385 0.728888296238147 0.470092977299355 0.606604255374987 0.950793135999702 0.892392405988649 0.361073734650854 0.930028510899283 0.498577270198148 0.496315088681877 0.466211985014379 0.7376699000597 0.409508569105528 0.179217190393247 0.45130524558248 0.135639171339571 0.209201594346669 0.692413912273478 0.536403455864638 0.495557810133323 0.504235364738852 0.718636438329704 0.815372835628223 0.854602923670318 0.815079458015971 0.655333603357431 0.538671653952915 0.425943605187349 0.0241811074712314 0.847874070168473 0.182583729582839 0.355608849704731 0.628477752537001 0.513625726385508 0.904864650038071 0.330441623278894 0.729829804010224 0.42094239251921 0.511930965327192 0.431225437163375 0.200484384810552 0.0592884904099628 0.646737009009812 0.991643972413149 0.844752361110877 0.382934754721355 0.470424662556034 0.346545173949562 0.70162357530091 0.35604919537669 0.290156861420255 0.139366365319584 0.258570663072169 0.0550267813331448 0.414251252657268 0.105415510800667 0.0778539369674399 0.267235550191253 0.534210449713282 0.0508607337228023 0.367814348381944 0.528245091638528 0.0724941477179527 0.856893217943143 0.971914853246417 0.281995767354965 0.0198844530875795 0.181567425876856 0.971544855965767 0.368892520528752 0.871685413848609 0.518297739073168 0.665418139619287 0.0530027852579951 0.0559077933058143 0.62521858871216 0.764622171390802 0.223771529756486 0.438464819458313 0.0780187569721602 0.566886205640622 0.32950356958434 0.922260516441893 0.782706218196545 0.929435210330412 0.958258800134063 0.980616639410146 0.433749496303499 0.0949860909488052 0.427162786447443 0.369345204299316 0.392337678053882 0.71757067527622 0.915579523984343 0.0758251860900782 0.974245426419657 0.783150826778728 0.0343913327390328 0.0717774680070579 0.294626504580956 0.0536832108697854 0.693336802141275 0.257248226676602 0.634677893377375 0.294747278585564 0.749688551928848 0.256714512114413 0.112663033516146 0.194942307397723 0.229305962789804 0.275364881034475 0.477111089797691 0.0527160366624594 0.210306079487782 0.587632226666901 0.217055973012466 0.455813224508893 0.441599606066011 0.741510483671445 0.122529109113384 0.430450823686551 0.745741833746433 0.472618155528326 0.608030152283609 0.862175047383644 0.394754778807983 0.513796562040225 0.85912624921184 0.313025444317609 0.307341134054586 0.978948981047142 0.539760492825881 0.875051342437509 0.615536465044133 0.498933717168402 0.666238392328378 0.378884244794026 0.628736531056929 0.566425726050511 0.596357038170099 0.636302168664988 0.611671125942375 0.561721260938793 0.149131745509803 0.603111825720407 0.652264851520304 0.700606454925146 0.946349587547593 0.917445556807797 0.261308381513227 0.627611161251552 0.386290724226274 0.960625439085998 0.383185090171173 0.724930508180987 0.399550942820497 0.649298966883216 0.0558431544573978 0.124676782139577 0.837305882147048 0.193616427297238 0.107452096682973 0.464848611403722 0.679509743263479 0.345432885382324 0.650085649692919 0.622478890486527 0.405644405335188 0.5070495048468 0.192594616890419 0.60018653715495 0.497200596141629 0.709709905011114 0.994868171799462 0.425611277751159 0.204284238198306 0.843202573806047 0.835026738194283 0.720151399497408 0.55396478030365 0.528610276260879 0.821103189885616 0.957151247698348 0.188933108700439 0.524233659463935 0.634151222736109 0.943587065441534 0.482995532331988 0.69084276546957 0.191142444559373 0.476548999936786 0.496439467743039 0.394291290240362 0.387353274538182 0.975855297616217 0.875802030463237 0.195857907398604 0.986699795704335 0.925097285886295 0.67546340404544 0.744983217592817 0.826729036918841 0.146427824243438 0.709243774656206 0.263083743476309 0.590791066654492 0.88356768785743 0.305429282898549 0.553273522695526 0.153441227118019 0.75805842717411 0.0230145399831235 0.0418622338864952 0.765603192104027 0.682256063590758 0.504954995801672 0.486770112060476 0.603366206255741 0.964558919288684 0.0641383188241161 0.909431911399588 0.0742984799062833 0.719618793190457 0.436679618272465 0.468677771319635 0.631071895451751 0.872104890069459 0.397910620882176 0.53330359243555 0.613788643961307 0.618415019952226 0.118313140228856 0.620043953922577 0.220423902361654 0.749561247101519 0.691680819182657 0.544287108327262 0.610389495606068 0.426569292256609 0.535732194795273 0.32573986472562 0.289470294765197 0.633797454203013 0.231375971280504 0.528858065120876 0.982259075976908 0.76050305636134 0.909843938476406 0.0747396560781635 0.533089022419881 0.631838487908244 0.335652962338645 0.558995713712648 0.0993686060700566 0.64747056633234 0.504646853823215 0.742637521161232 0.443057373610791 0.816750275644008 0.50057608527597 0.480062293971423 0.81034731810214 0.23337987170089 0.874326441169251 0.0760527087235823 0.181016580611467 0.548492084324826 0.59016716736136 0.638662268957123 0.241266045859084 0.142617825064808 0.997181502014864 0.795220497804694 0.594374624255579 0.906872818439733 0.829243140893523 0.755466258511879 0.992104409590829 0.284807490415405 0.839264754627366 0.502772340357769 0.763617816464976 0.547797884123866 0.0898934654332697 0.834819496539421 0.281291119635571 0.610808505059686 0.285293083235156 0.125642026811838 0.156005776990205 0.736711443450768 0.719994244847912 0.736225272761658 0.199507854513358 0.820049039770383 0.278249513136689 0.46795145315351 0.430612335982732 0.0220598483993672 0.865071568335406 0.274330636179075 0.389807023319881 0.669201309247874 0.763471919549629 0.193519655731507 0.452336214308161 0.780554583065677 0.892664547881577 0.862573363720439 0.0861727965134196 0.135693287295289 0.0864981224411167 0.117349325823598 0.175493258712813 0.840833316578064 0.130616193949245 0.377709366774652 0.0706588906445541 0.0985555434203707 0.274608607476111 0.734337787316181 0.599403694283683 0.617017436798196 0.244419764084741 0.435615648988169 0.502795105921105 0.749376283958554 0.371998446860816 0.0992215840728022 0.179694007528014 0.339420679090545 0.0140362494392321 0.818992930154782 0.141032513431273 0.533680116159376 0.737143249933142 0.699499773327261 0.902763830991462 0.898304874149617 0.560498067555018 0.0822697352431715 0.885612260645721 0.718158895112574 0.157175775966607 0.834658814973664 0.114751128372736 0.556418178260792 0.510936598989647 0.0777144959615543 0.890176285984926 0.326713059884496 0.0909874878427945 0.585328620192595 0.919836413026787 0.684698821329512 0.485655122697353 0.153739187116735 0.293029730527196 0.696689204622526 0.60516363858711 0.983214430715889 0.143010533279739 0.501678821134847 0.824541639811359 0.903479835561011 0.518164203076158 0.0381441608839668 0.568468171993736 0.492988847754896 0.246505528101698 0.873643743034918 0.881451636985876 0.340045818025246 0.583623862708919 0.512676785604563 0.0173521113069728 0.58349698984297 0.580444703940302 0.175518226264976 0.660244306977838 0.859944405732676 0.116094949392136 0.427748680515215 0.856705325115472 0.758850256178994 0.565850660060532 0.0588884909451008 0.0923501120903529 0.479124296980444 0.739220003613737 0.28870524344733 0.0979812592943199 0.0986626168270595 0.613269637061749 0.389457486348692 0.253107247808948 0.059086127106566 0.536607225693297 0.390972905755043 0.263479987136088 0.135865464934614 0.61873854957521 0.635907158653717 0.784120269359555 0.565568903915118 0.12998124967562 0.577004364356399 0.448924517405685 0.632057324522175 0.125048107344192 0.038363852892071 0.660424864529632 0.203358243233524 0.102979884804226 0.0375946642877534 0.386086886399426 0.711689458852634 0.443500553078484 0.969509010917973 0.250867889481597 0.17506604522001 0.933026221224572 0.380283938196953 0.204978501095902 0.0872750333347358 0.65188411974581 0.640957627827302 0.545033476047683 0.789174856457394 0.245184568304103 0.819524480991531 0.360255623308476 0.281073753857054 0.155846294267103 0.140682671966497 0.243060391764157 0.93501725246897 0.207647796301171 0.713333651386201 0.996174635074567 0.351470672823489 0.0946202182769775 0.329658662851434 0.579295850095805 0.0919371719937772 0.0922501805680804 0.157449312629178 0.411733155229595 0.173764855377376 0.780514437626116 0.281375317298807 0.646118209350389 0.682415191109758 0.19288595294347 0.477343726125546 0.118281244467944 0.165687211225741 0.071935314394068 0.570672035496682 0.0350866497238167 0.215596195717808 0.547864881933201 0.755647458704188 0.918741486587096 0.859523655755911 0.403463248847984 0.0496007417934015 0.261512159178965 0.486788806030527 0.689545465584379 0.447112119249068 0.440367194432765 0.710353259393014 0.371724554763641 0.96301835184684 0.779977484045085 0.594723970831837 0.438774258473422 0.138787675371859 0.919046839026269 0.630405585803092 0.978905969311018 0.581544335393701 0.442051911121234 0.802808357221074 0.885192281238269 0.494281501173973 0.644020503237844 0.501463732258417 0.337303243130445 0.708216997385025 0.399387842593715 0.298433958091773 0.15602588463109 0.775058546881191 0.303277637164574 0.656248617651872 0.992646100225393 0.786413893008139 0.547650145264342 0.675431136484258 0.249174551314209 0.209860274598468 0.912353492795955 0.0553340614633635 0.0247807839652523 0.220973839217331 0.759688115117606 0.447846460279543 0.632206483276095 0.0304458346054889 0.315384185798466 0.671704933203291 0.21095547925448 0.899919471335597 0.341438989364542 0.345947403248865 0.209161218174268 0.345285009834915 0.27869765024865 0.24424947333755 0.385880113355815 0.889434376410209 0.743078588766512 0.772382182630245 0.787814019985963 0.560597099887673 0.910834087773692 0.673699228591286 0.111493643296417 0.718891273415647 0.662376516063232 0.522613098260481 0.533524933457375 0.752913643820211 0.999765833828133 0.900565574688371 0.913221387341619 0.166038433860522 0.555976383881643 0.734711330183782 0.885549825399648 0.378676803293638 0.122910708498675 0.111596492517274 0.850745281502605 0.382173603733536 0.387369424684439 0.735132009396329 0.215077840217855 0.988923855591565 0.769690532616805 0.791119573789183 0.362482299166732 0.459091468625702 0.638369617888238 0.432543087408412 0.876866828403436 0.882514959941618 0.22865859905025 0.437975431417581 0.517778526104521 0.546740084926132 0.145784438513219 0.811655914445873 0.769211921482347 0.259078253421467 0.858929789995309 0.189175225589424 0.769732348967809 0.379294711370021 0.539644613307901 0.215787941622548 0.819712927716319 0.0683227886422537 0.41880366390571 0.500350726367906 0.407806116875727 0.397632342556026 0.225018177444581 0.0214421302569099 0.389139431847725 0.479139807713218 0.703833681729157 0.984938566531055 0.66348552942276 0.483147422308102 0.94678874359699 0.679905926531646 0.360482818398159 0.560634830815252 0.795774042943958 0.738884479571134 0.292588602760807 0.347817850192077 0.0134931972273625 0.678937189287972 0.842188149846625 0.363549485341646 0.163229436490219 0.808944698933046 0.691986061441712 0.865860669806134 0.704202387735713 0.802398917071987 0.909239922775887 0.858984823119827 0.494645466899965 0.732754697955679 0.506393588779029 0.86576675508637 0.855532449239399 0.484432407375425 0.710144797458779 0.342705461406149 0.355564634515904 0.21719440695364 0.990039225053042 0.710953861123417 0.432598503627814 0.692002600445412 0.634968035197817 0.0798826122400351 0.756725896159187 0.394849434592761 0.444665702977218 0.769745943073649 0.7558128498937 0.994527058766689 0.251933912541717 0.898881848468445 0.743108842428774 0.335991689672228 0.238339764750563 0.316218087242451 0.436936819925904 0.182210291593801 0.683999470092822 0.552843975597061 0.991232026012149 0.993154369404074 0.322500510732643 0.920240249203052 0.49450238280464 0.921152420712169 0.966001674677245 0.870053645852022 0.727780543495901 0.478771788603626 0.817584908471908 0.646961422397289 0.706544731280301 0.534045039622579 0.9232371762814 0.218781556843314 0.799353469482157 0.792626693958882 0.615655297527555 0.651113107868005 0.517152960048988 0.399810404549353 0.753005227469839 0.586395159577951 0.579025557062123 0.551162329430226 0.253417421665508 0.24109935763292 0.523748427380342 0.0958067615586333 0.295854767402634 0.462050267390441 0.323147038670722 0.956350962023716 0.907934536407702 0.605953024958726 0.782765989988111 0.989802319591399 0.79262630717596 0.0514113537874073 0.644368360769004 0.0860914089041762 0.971091574272141 0.566996542038396 0.580167467484716 0.401815788482781 0.832458478156477 0.72501859810669 0.935077110698912 0.201998806372285 0.0806253152037971 0.718435438447632 0.290745529814158 0.817540102044586 0.204578685110901 0.72986277806107 0.761072929133661 0.827263355627656 0.880985598140396 0.0998064256669022 0.064576899309177 0.826297577342484 0.953756969396491 0.270937274124008 0.142943276385777 0.985914218614344 0.543976584337652 0.0695605666004121 0.586654235676397 0.826744809963275 0.505765463225543 0.667122213433031 0.441385511346161 0.157287621463183 0.117141684247181 0.407660853611305 0.740281412247568 0.386372449060436 0.501694606626406 0.358072617270518 0.296141207816545 0.541416149162687 0.450396579091903 0.222453872826882 0.442416383030359 0.419845776727889 0.737066174561623 0.253945547007024 0.713082817129325 0.201127338348888 0.190986705655232 0.453178012070712 0.800761887168046 0.538076181591023 0.0242867238726467 0.684123740817886 0.477853706323076 0.0831357350596227 0.756198750913609 0.0513844935805537 0.911780665444676 0.718294993373565 0.105619205485564 0.407170384745114 0.264541666379664 0.0490886435098946 0.325414329271298 0.149662213907577 0.476911396402866 0.854071304835379 0.438517215175089 0.0300005727796815 0.196795693479944 0.748589789238758 0.0817242740513757 0.83702854888048 0.345196881415322 0.154043540558778 0.126916426981334 0.717564415524248 0.0856675872532651 0.118732783563901 0.486737718645018 0.935602653722744 0.76225319445366 0.388084292646963 0.378832688797265 0.0933442629082128 0.313021770340856 0.19014613162959 0.906011915490963 0.308924964710604 0.449603444060776 0.77219784184359 0.413137907467317 0.542243754665833 0.335069521046244 0.676285847909749 0.308037179657258 0.519320782897994 0.109370240322314 0.797959575518034 0.389836155588273 0.418900192982983 0.268136713830754 0.195001913688611 0.345864592979196 0.907215442645829 0.990727470456623 0.845422710543498 0.816798236495815 0.100762403223198 0.731035457318649 0.0840200093318708 0.556193390768021 0.568632870293222 0.332401989875361 0.769823756513651 0.513249559018295 0.365787466878537 0.816453156287316 0.509963785081636 0.939073057956994 0.778709438825026 0.61609914775705 0.769818258571904 0.497901274841279 0.668326307162643 0.130567126455717 0.233898597157095 0.834260399059858 0.308370111701079 0.480058599018957 0.0283858165470883 0.511008377647959 0.443530801669694 0.336139991187956 0.42065333774779 0.0214564439910464 0.621963551801164 0.38660702713998 0.921043325569481 0.852970324251801 0.805358402503189 0.73744422997348 0.482905449483078 0.928449749681167 0.543012254068162 0.769723933788482 0.964358800156042 0.963475145013072 0.0346384317055345 0.699095193550456 0.0713207492930815 0.17127234831918 0.37247354560066 0.935070998237934 0.462088854173198 0.682008607345633 0.157681087569799 0.518632007108536 0.279268901885953 0.695013698346447 0.5812070954917 0.404088983631227 0.579847806151956 0.199061779244803 0.341932068669703 0.171252571679652 0.248515998530202 0.671007697747555 0.191899184654467 0.461464305093978 0.533827447490767 0.128460542545654 0.636622282243334 0.45847985280212 0.819127593077719 0.349473344485741 0.713567162700929 0.761287801568396 0.533943555897567 0.840410215246957 0.556240895916708 0.550662767938338 0.74752490947023 0.806000345058274 0.841885104735848 0.952767626857385 0.333874971265905 0.911592683182098 0.920882936972193 0.647657470535487 0.541816203717608 0.723460265619215 0.365501377289183 0.434684130265377 0.300799277878832 0.668890280919149 0.318310756648425 0.390039248662069 0.69724677848164 0.0184443646110594 0.560424374113791 0.350389622163493 0.0545293453033082 0.0554472823673859 0.915773038303014 0.169474274499808 0.329014208973385 0.0915071502909996 0.397003337866627 0.458776835701428 0.315414700389374 0.439619558257982 0.527136321689468 0.29323921012925 0.779663750771433 0.955266543955076 0.998387233924586 0.408326211976819 0.962207340206951 0.376823841796722 0.926022042823024 0.780902152929921 0.980024318245705 0.320777404110413 0.759211506356951 0.657799586511683 0.365563184416387 0.831286841460969 0.209426543191075 0.155159324002452 0.603335585864261 0.255605862948578 0.137043537255377 0.218889853064902 0.717389137858991 0.297698148530908 0.267240822932217 0.0848553332057781 0.26489126028493 0.782799251475371 0.607734864267986 0.370371382725425 0.994337332062423 0.429205261433963 0.261180606922135 0.295707300996874 0.844384999854956 0.314334923485294 0.724926385416184 0.182415569138248 0.74050343740033 0.655253512093332 0.517731473662425 0.605696872090921 0.476001878206152 0.390268303905614 0.328317537095863 0.202627907642163 0.351924087977968 0.913863749410957 0.936405825286638 0.370875210124068 0.58271826028591 0.535258202466648 0.137451882518362 0.232964175026864 0.586829959133174 0.2316931113787 0.222099448284134 0.449786812588573 0.186648143411148 0.152226236159913 0.322446774644777 0.0252556660328992 0.431522214224096 0.554752030840609 0.147890234566294 0.0289671284588985 0.231101372693665 0.733466357095167 0.970144415504765 0.282671678347979 0.780891266765539 0.827613809076138 0.395562790690456 0.160035689459182 0.848255374510772 0.0684426187397912 0.334296802298632 0.536781671475619 0.877400296789128 0.521148552102968 0.140761489935685 0.644034119010903 0.683361706775613 0.823826745341066 0.0330806780094281 0.763631998121273 0.741780058690347 0.34380364530487 0.186476466883905 0.573296361309476 0.142987067680806 0.115854090123903 0.479947759895585 0.957831669622101 0.933096226397902 0.0179578223521821 0.43585768266581 0.685375593940262 0.613754805526696 0.433232613482978 0.701946031013504 0.67045419594273 0.191144032720476 0.684367472375743 0.64054987864336 0.0954535130388103 0.548770237718709 0.380933648219798 0.387707042149268 0.955262891876046 0.954674996817484 0.631554544987157 0.649055676506832 0.506693412389141 0.23982221033657 0.148712591992226 0.700176255044062 0.40579371714266 0.492304063113406 0.68372771544382 0.839774397138972 0.999109696478117 0.313383785325568 0.43326725683175 0.143353331054095 0.198234529867768 0.620492811584845 0.847849985440262 0.451306327329949 0.0967995330505073 0.695782676041126 0.789321648643818 0.626725694590714 0.799901226938237 0.984337568336632 0.0557559166988358 0.956695949339774 0.345012329949532 0.263952078050934 0.091330640129745 0.593517652985174 0.516913150027394 0.458639939671848 0.520358477451373 0.989901856954675 0.651234291936271 0.611214773957618 0.156394030516967 0.509887780854479 0.931968183226418 0.777579686939716 0.593787554625887 0.425952821362298 0.150278453838546 0.0414353082911111 0.0737814136059023 0.669936308593024 0.278954252596013 0.258021765782032 0.486603642120026 0.339540242957883 0.758199992028531 0.361265575522557 0.58128331293352 0.0233658575848676 0.890818460655864 0.123415028941818 0.818244961365126 0.68710295494413 0.103486984414048 0.685047956535127 0.79733147370629 0.57321002850309 0.536680937574711 0.853365348323714 0.700684589224402 0.0896644122642465 0.519169630990364 0.26522823971929 0.290005205865018 0.492694266459439 0.777144735944457 0.389448156536091 0.786403425205499 0.43238897562027 0.693181430888362 0.810541330766864 0.0164647425408475 0.79231814814033 0.568062565098517 0.954119798284955 0.486560644214042 0.63872392349178 0.957880613796879 0.794390208562836 0.381236386531964 0.974261899499688 0.0324279200541787 0.761273519643582 0.719521260967013 0.507180201285519 0.128500742844772 0.356780124972574 0.838763362485915 0.418874798540492 0.0318570796330459 0.117711214262526 0.467893957803026 0.257143329211976 0.922104801509995 0.310399817319121 0.0748393089231104 0.626697251063306 0.353522373435553 0.123491865282413 0.367794036976993 0.156659589032643 0.920347381157335 0.11117722697556 0.410640476418193 0.767383190852124 0.212165339922067 0.553421742613427 0.536342986342497 0.881181825702079 0.2082343074237 0.890113563763443 0.520023782986682 0.248174071363173 0.270484609946143 0.175077654009219 0.983972720247693 0.187955645099282 0.593626927919686 0.140981612291653 0.595344047013205 0.0563184173149057 0.349986101083923 0.207767091402784 0.228695225641131 0.413541699617635 0.19392006064998 0.944156017126516 0.563234303866047 0.708946093565319 0.68361021756893 0.760684286288451 0.400687931326684 0.609816874323878 0.845056801452301 0.925751843603793 0.952343502556905 0.963581677200273 0.596584479666781 0.480466245859861 0.152579909956548 0.355814697742462 0.709174004825763 0.590081003052182 0.52355256770039 0.333962509599514 0.667884006139357 0.155798771369737 0.78592574991053 0.355758750676177 0.158922814724501 0.478927814944182 0.127962208709214 0.0826019750884734 0.382485245659482 0.537428604406305 0.242054545949213 0.708548553790897 0.490835845514666 0.0760071119037457 0.92370580989169 0.365370925413445 0.046540516007226 0.868482789481059 0.191155600710772 0.913114068449941 0.927944947949145 0.987419063034467 0.410427867977414 0.572213175506331 0.460265613186639 0.321110565043055 0.853572273037862 0.0561648755590431 0.191465096429456 0.145561643713154 0.910088208948728 0.988739853412844 0.595286233338993 0.475119440346025 0.18647672181949 0.643438061403576 0.514256845011842 0.134597285562195 0.572110339424107 0.810310210222378 0.990646589491516 0.599711215519346 0.497212327558082 0.572131694313139 0.798251556747127 0.450231966769788 0.159283345965669 0.559507288294844 0.207250508004799 0.841247944182251 0.594484780631028 0.667037977506407 0.906043676177505 0.239829526711255 0.367584783036727 0.996227858755737 0.85269301634049 0.335805584851187 0.0428717308584601 0.392091074436903 0.493291403278708 0.167258491029497 0.768115003041457 0.698811573563144 0.92143274751259 0.439058705272619 0.104176075069699 0.311012428682297 0.987830176400021 0.982027403379325 0.636995185927954 0.507525277575478 0.769733122994658 0.290259697963484 0.0580812793667428 0.590955823732074 0.435569366423879 0.992260446073487 0.773045647419058 0.215887114331126 0.253521002039779 0.0979106308426708 0.203126558880322 0.339955981813837 0.869025153412949 0.138988245597575 0.593615445445757 0.377808633067179 0.27100926092593 0.601979234968312 0.217236831139307 0.741782613117248 0.210912466596346 0.927966369683854 0.568615991990082 0.759859020845033 0.256204953505658 0.0642982136853971 0.292813456177246 0.98664822841296 0.520496360952966 0.309234272339381 0.716056372884195 0.0606120071699843 0.807921090607997 0.590325681513641 0.703713721858803 0.105056082513183 0.703609722431284 0.270001728294883 0.18540311477147 0.406258696138393 0.0133730801544152 0.182642964764964 0.155847597296815 0.334870913086925 0.629398953053169 0.595908552077599 0.472867991018575 0.689994494970888 0.933174437915441 0.214985090917908 0.537287684497423 0.843767130502965 0.220410086512566 0.68639623362571 0.62606522195274 0.61288945319131 0.228608365906402 0.65714659644058 0.368075183443725 0.126230494207703 0.987218377788086 0.114428960096557 0.895546463513747 0.0774074760684743 0.406415036423132 0.312435902780853 0.877226139826234 0.214467280094977 0.747930225240998 0.195173618798144 0.257184356322978 0.238214114238508 0.786248884913512 0.80414301577257 0.381889256741852 0.948613025993109 0.578745644474402 0.427662206871901 0.115413653634023 0.485834086325485 0.106822065336164 0.375828825673088 0.707377330616582 0.194462629037444 0.895225745327771 0.99448488582857 0.0156247664382681 0.189716951490846 0.982285859656986 0.147527710171416 0.360560683240183 0.817105155198369 0.286120487970766 0.958722332497127 0.0725682420027442 0.142286042766646 0.0711560353194363 0.174197288134601 0.369057681446429 0.899224046936724 0.957117144647054 0.123882612383459 0.0208366036135703 0.894866436440498 0.48743430085713 0.415657410959248 0.879126943466254 0.668602377506904 0.85708550990792 0.301479861154221 0.343078548340127 0.327236251092982 0.113386554305907 0.984898937877733 0.720066822196823 0.607710620032158 0.958318839077838 0.118026728627738 0.918182798479684 0.770944882079493 0.881329216042068 0.358403381209355 0.667965393287595 0.32857400667388 0.42013217081083 0.357594424497802 0.981578734267969 0.248137805277947 0.138082852009684 0.0707919515762478 0.361218696648721 0.440211500707082 0.624648902646732 0.606253744531423 0.243705977178179 0.0233875319501385 0.268779260301962 0.119082022956572 0.770048542162403 0.724408946393523 0.802608483573422 0.273196982811205 0.147403431839775 0.264479902356397 0.713024904339109 0.338882604115643 0.442880625340622 0.818341876072809 0.154307229239494 0.327447562958114 0.684846658613533 0.649862551551778 0.223070341185667 0.249692525563296 0.514261992590036 0.570845491040964 0.0996478750952519 0.383200086653233 0.14922834396828 0.648197635244578 0.848231441453099 0.908572769949678 0.109536391017027 0.490159626801033 0.914240656690672 0.516914759394713 0.0676622254168615 0.128677387619391 0.824552469733171 0.785901348933112 0.488316941328812 0.629807449986692 0.0120128962351009 0.209756110131275 0.98776370574953 0.340529148464557 0.911959216012619 0.279139927530196 0.494392398614436 0.238946428922936 0.656408590653446 0.489086929545738 0.0985933416546322 0.321800075904466 0.362621278015431 0.42376590692671 0.765828918663319 0.119320240898523 0.273746001115069 0.925595905776136 0.621659002201632 0.996948019051924 0.823935875981115 0.604967577217612 0.198478136262856 0.407662887563929 0.76818693659734 0.582404191400856 0.528365460189525 0.680889931328129 0.190726805510931 0.18204726443626 0.0500485870894045 0.785755055784248 0.712888249645475 0.248233820335008 0.714219659727532 0.54996490413323 0.906753618766088 0.568923993131611 0.69861339410767 0.212542563450988 0.820113855644595 0.995978983077221 0.233352034394629 0.346796034944709 0.3010304164025 0.0704260293464176 0.600606887901667 0.359149249892216 0.632853553816676 0.545226765857078 0.973352952026762 0.232804534179159 0.175517088966444 0.957245129917283 0.0808428598521277 0.489875272894278 0.642976549854502 0.624258371295873 0.100575361640658 0.873298365708906 0.675298382120673 0.812158663093578 0.556226861551404 0.600123594112229 0.697870527026244 0.433280032654293 0.720918890682515 0.91945876191603 0.973816237291321 0.607448449439835 0.926471259838436 0.110698134782724 0.108201728085987 0.254155394029804 0.256141355375294 0.855710074570961 0.172025197995827 0.359689218443818 0.403938523922116 0.173588691891637 0.196713174795732 0.540444993257988 0.587808169561904 0.386690899564419 0.0366409585624933 0.659888165423181 0.864607864248101 0.586718911174685 0.336439364165999 0.797693878239952 0.63406831680797 0.367497306938749 0.0984724724525586 0.726154774553142 0.24482795675518 0.0397167282737792 0.946298800045624 0.305083127396647 0.786398659339175 0.690877631944604 0.372212558868341 0.959564683695789 0.401518939044327 0.876950184733141 0.893851680557709 0.4804730841727 0.79076100850245 0.281143028107472 0.0684038885845803 0.98194614485139 0.441342760999687 0.963436365760863 0.900981645006686 0.231620961381122 0.782472431431524 0.696724082392175 0.957456945430022 0.0234626466687769 0.448569235855248 0.267933900586795 0.259651728484314 0.107848586288746 0.676511149422731 0.928827928872779 0.882714446806349 0.0189502582326531 0.275991501407698 0.304758986481465 0.50786378293531 0.214522014027461 0.988430477324873 0.551009998042136 0.847332433701959 0.97567776056705 0.736434975720476 0.181138742240146 0.986051176879555 0.252457743624691 0.0399551391461864 0.462742219502106 0.837349982315209 0.292932722005062 0.86964455537498 0.846377737508155 0.134700423371978 0.824729600176215 0.964795647494029 0.369493296057917 0.836832020513248 0.77496251499746 0.881856705658138 0.403988747384865 0.392628212189302 0.20390198741341 0.729518001885153 0.533520660866052 0.825653503101785 0.467778320773505 0.71343758465955 0.967391487136483 0.311258125733584 0.498653741192538 0.425677750015166 0.384336603551637 0.859940518310759 0.54018497209996 0.84371901106555 0.951334053990431 0.659169151415117 0.330282017467543 0.538847247175872 0.324351986641996 0.404758287966251 0.754236589856446 0.504773646013346 0.769221130742226 0.0503319334704429 0.836343081260566 0.952905437059235 0.402780053981114 0.342430752408691 0.868195160597097 0.543369452476036 0.423687090340536 0.406488443119451 0.293298712924588 0.576678146154154 0.842500992228743 0.7748522293102 0.945340667292476 0.749881542315707 0.416817061302718 0.972943087292369 0.246586130389478 0.433576678559184 0.64216004465241 0.909204322381411 0.254961179720703 0.35000522471033 0.928194089396857 0.851671039049979 0.540705042076297 0.329992463658564 0.8539321307512 0.0823426336818375 0.496128370494116 0.587235729915556 0.359658295863774 0.739949146355502 0.128132458196487 0.176556801567785 0.381815148396418 0.94341160176089 0.804316401474643 0.620473120000679 0.593085632827133 0.485105443082284 0.521192151620053 0.304302876293659 0.997177223430481 0.320728987785988 0.569529942977242 0.701778087471612 0.794252981531899 0.0306025377009064 0.862043150027748 0.839907797139604 0.178972173784859 0.512908868035302 0.373023754218593 0.48754756786162 0.0104918417381123 0.476774748624302 0.691635744681116 0.985464899486396 0.668309473576955 0.861708562977146 0.384722772876266 0.571707922450732 0.223252641565632 0.417062647021376 0.676784970064182 0.58911299880594 0.0570884165959433 0.784892253496218 0.641106827380136 0.651513473370578 0.656989255545195 0.523633584431373 0.702118502082303 0.228936799005605 0.986367426086217 0.842984813638031 0.0646606942848302 0.773589556177612 0.698857081178576 0.569550599674694 0.368942397546489 0.946127928432543 0.656825201499742 0.742762277324218 0.634341301647946 0.228910342869349 0.894647850382607 0.185046896920539 0.112877302034758 0.191615338083357 0.140101792938076 0.46637389377458 0.798389898026362 0.884234652824234 0.92123285242822 0.173564233288635 0.607924738263246 0.644106546533294 0.925976018651854 0.182114766123705 0.795284489172045 0.36909476258792 0.805068641011603 0.439754149955697 0.739977233756799 0.237676601919811 0.586018965933472 0.099651856792625 0.931211187965237 0.449411781828385 0.848118574600667 0.53145317107439 0.303108026860282 0.218573138704523 0.442748172935098 0.775042456665542 0.037664928776212 0.0602354659279808 0.593059462513775 0.385782304990571 0.888382067547645 0.370100300451741 0.158325002072379 0.857161531422753 0.502642493781168 0.82002027515322 0.345242534477729 0.752846187541727 0.794502435771283 0.914038251896855 0.200684931986034 0.0871060555288568 0.61255587320542 0.860402856902219 0.695789766293019 0.772889882468153 0.450571454991587 0.639123931254726 0.0303384954296052 0.968500369340181 0.449656908155885 0.146952803689055 0.255848830160685 0.546842421048786 0.123571871260647 0.0292479909467511 0.634985095136799 0.158490062491037 0.597196391916368 0.830696953018196 0.68579195054248 0.38017900938401 0.666747522894293 0.640713741602376 0.436762494926807 0.0113657185109332 0.797821753560565 0.106397944032215 0.737284081790131 0.644493386850227 0.743183162144851 0.20678644756088 0.666627901631873 0.802312735936139 0.0866630173590966 0.555177168198861 0.927344733232167 0.475986415187363 0.37000291551929 0.468360456500668 0.183671573607717 0.129573289121035 0.536695173860062 0.129965889691375 0.421901556309313 0.778523179797921 0.913300974497106 0.0169620570959523 0.0478552070632577 0.850837883511558 0.745318812169135 0.497833682796918 0.622324573551305 0.743303073840216 0.848523519262671 0.199798670553137 0.945916168701369 0.742231459023897 0.741338539530989 0.828017856623046 0.0276920891064219 0.388567773373798 0.721458896344993 0.0994359346502461 0.557908307411708 0.0573921965481713 0.476031265410129 0.626974941377994 0.321380498954095 0.135798509076703 0.642446619218681 0.0522251125541516 0.411461958396249 0.0252103778556921 0.338203138315585 0.546695309155621 0.11110198686365 0.0454552722792141 0.889479744341224 0.684665460495744 0.67689152461011 0.246264305792283 0.469023085027002 0.0450373696978204 0.815494408092927 0.753594824327156 0.102230378794484 0.4550734081259 0.694428595823701 0.326856285969261 0.878725355840288 0.479407089003362 0.129974489272572 0.286504095722921 0.300723491015378 0.219503059354611 0.627042839990463 0.307557495995425 0.0872915142518468 0.850938569698483 0.542062530731782 0.785207130983472 0.203411046247929 0.0514278400060721 0.632261367726605 0.293233093980234 0.169946774786804 0.434389158498961 0.264387070536613 0.222510216126684 0.667142323609441 0.688128884197213 0.12713608764112 0.267177146200556 0.180468147092033 0.920766727605369 0.608001560312696 0.542892017134 0.674845535615459 0.216887927819043 0.120464429606218 0.476446849368513 0.8623009150289 0.90593651333591 0.287079191447701 0.996036524528172 0.665916867845226 0.172333327988163 0.935345641311724 0.65293370337924 0.711571850567125 0.174724286089186 0.361116678849794 0.324444217311684 0.938326539027039 0.15153820051346 0.575895468783565 0.505580641380511 0.0204885665210895 0.283461044435389 0.807626577541232 0.991207547585946 0.724849048885517 0.934485771474428 0.77702885665698 0.357324386630207 0.763177280628588 0.152437332274858 0.791408459832892 0.361200932064094 0.233056100280955 0.577616635728627 0.626154102501459 0.23023356965743 0.570945220643189 0.214208277987782 0.864947745245881 0.411697149381507 0.973158151505049 0.814396220275667 0.0661518927360885 0.227016273124609 0.555302762698848 0.31706808443414 0.231288954804186 0.242413295637816 0.603878142035101 0.73232148563955 0.612050801094156 0.309521364844404 0.36802379271714 0.118485387710389 0.19071192819858 0.676735239645932 0.211716422790196 0.306915466079954 0.761090440626722 0.627424462656491 0.227995117434766 0.983300038592424 0.354902934913989 0.241143269711174 0.888988822768442 0.2768159467238 0.0151601643138565 0.150366386792157 0.368357142431196 0.20630351358559 0.0161643071775325 0.353268137655687 0.604971814311575 0.419767953145783 0.738720519340131 0.259336396676954 0.239607441858389 0.862156890714541 0.245564009265509 0.514812739200424 0.642157620689832 0.703603704245761 0.252945375237614 0.117929059255403 0.0510403570486233 0.705211753090844 0.10951852385886 0.329025683379732 0.725660684495233 0.373551070035901 0.186546025113203 0.723803571881726 0.0795861076330766 0.347879173264373 0.775066494601779 0.843513833789621 0.631117503796704 0.52294319673907 0.736113900025375 0.28469861448044 0.181203573788516 0.488453283230774 0.19186756457435 0.321464235612657 0.867867008249741 0.946304421306122 0.750363453552127 0.286431682491675 0.65588742025895 0.817542278447654 0.0850727054383606 0.85155854630284 0.808641374222934 0.602523136350792 0.83610839945497 0.557316413137596 0.575495762287173 0.717343013649806 0.31703474111855 0.222512263217941 0.966255794514436 0.793443923399318 0.77748423154233 0.871920730227139 0.684309630580246 0.788205957170576 0.0879636420099996 0.643146812480409 0.0571003875043243 0.688831462236121 0.674570363077801 0.682103147648741 0.684537831351627 0.468146777376533 0.97292175729759 0.139831404476427 0.617097682729363 0.131403221820947 0.980820001249667 0.623389543446247 0.620992899774574 0.240095801858697 0.922268432353158 0.468074916198384 0.375360432707239 0.52972824486671 0.842909017323982 0.664100277542602 0.275469646882266 0.946738039075863 0.600003794441 0.0585806389385834 0.631575875903945 0.337319460813887 0.65912423803471 0.0237388140545227 0.303139857619535 0.941047472748905 0.278998603320215 0.63434673804557 0.87895332103828 0.0951175897661597 0.921366470253561 0.0100686938455328 0.265471752299927 0.995880313555244 0.7974134004605 0.977513704998419 0.260503049450927 0.492283385440242 0.38990176392952 0.487363458038308 0.304538615643978 0.317900437824428 0.682534045721404 0.479744696556591 0.363806653802749 0.266898402951192 0.25384240020765 0.933034265295137 0.307358215660788 0.830119509857614 0.0698510620114394 0.843932964487467 0.147636327943765 0.572715817200951 0.993440054692328 0.705207320300397 0.648546006334946 0.920470827606041 0.550995919650886 0.610538098157849 0.972418933045119 0.867514700179454 0.954780493127182 0.748978637231048 0.0168219149019569 0.947186586251482 0.104145089793019 0.0752320436458103 0.454377942467108 0.0709750937507488 0.472472776321229 0.871134995934553 0.834374307091348 0.116939535310958 0.613006037354935 0.37063374878373 0.418408508677967 0.971269030184485 0.718168569987174 0.686488852922339 0.609695239162538 0.114987213476561 0.327458913815208 0.204427275962662 0.284118432491086 0.0442133139306679 0.0770621077320538 0.627170416580047 0.983414313583635 0.559627905557863 0.652912526438013 0.491722007601056 0.777915937295183 0.865692972901743 0.606462465550285 0.0507513557537459 0.837667175889947 0.961194211440161 0.764426011827309 0.318080070600845 0.979542881383095 0.17378248650115 0.853031964956317 0.190187288974412 0.367209046478383 0.561792305216659 0.171393214294221 0.335982702847105 0.950269966688938 0.206451062050182 0.294185649729334 0.413438003070187 0.950773248258047 0.441264960006811 0.346385904671624 0.0926342248916626 0.858930181388278 0.0803714943281375 0.996786075255368 0.918534007514827 0.758281237648334 0.0563909923587926 0.827454450132791 0.815561685271096 0.897609977601096 0.37400063003879 0.187592193854507 0.36552092988044 0.363901921571232 0.189629257107154 0.0432730469526723 0.783424537470564 0.795990256902296 0.0434552698838525 0.679797538109124 0.0504353515710682 0.390467525462154 0.26009192294674 0.216530613468494 0.349680483797565 0.744154075330589 0.590240963376127 0.715538140011486 0.21751209380338 0.784645013231784 0.537305338210426 0.107262896215543 0.845793427452445 0.837570247352123 0.679484273907728 0.289082808350213 0.330453511667438 0.989171429162379 0.166683365800418 0.501769530258607 0.21340184020577 0.760823732826393 0.824948011974338 0.23538338095881 0.123249052506872 0.327467877590097 0.560409996300004 0.853400148644578 0.333789534883108 0.787641533473507 0.953355249231681 0.534707512559835 0.870336671604309 0.547663450089749 0.339896619394422 0.674895100994036 0.636913899278734 0.61567051344784 0.458430457073264 0.29401498602936 0.92484052057378 0.124181964155287 0.317377196366433 0.603216817921493 0.38062358016381 0.392070215358399 0.0838621440436691 0.688686222713441 0.873511191052385 0.821340754122939 0.0852691174019128 0.909673133017495 0.0263436151668429 0.913410788807087 0.228341011547018 0.618173957611434 0.899455627794377 0.613812981089577 0.767234916535672 0.755721348763909 0.0955738110560924 0.0181283143279143 0.140843957217876 0.601226383678149 0.0818626722646877 0.793928346880712 0.158449498689733 0.802268721284345 0.965768944995943 0.0681192670646124 0.392598635051399 0.33452594075352 0.513534388681874 0.141313545107841 0.896625072923489 0.0989515701774508 0.478355913751293 0.781719564467203 0.780865218618419 0.9187115747598 0.391365426802076 0.0126064999145456 0.931629144945182 0.750867956092116 0.348748903069645 0.331645596916787 0.106779692091513 0.382325331666507 0.682715260204859 0.768266757712699 0.975306668861303 0.53494894600939 0.924424210302532 0.0932197261834517 0.011523347995244 0.339809772567824 0.50897425606614 0.0632965600164607 0.0786092380364425 0.838602004395798 0.445251452059019 0.0586163840885274 0.0826498135435395 0.0464140780991875 0.177949617241975 0.097887890865095 0.857024538121186 0.519806479674298 0.483414103831165 0.512637085034512 0.0765575849078596 0.766436080490239 0.211995325086173 0.50699747655075 0.392781738501508 0.303556705422234 0.704480053156149 0.614186337019783 0.872994753792882 0.774510308136232 0.0468367361743003 0.410678230165504 0.0297302832035348 0.0164592957706191 0.0502712866920047 0.302766531424131 0.587287524712738 0.21345584390685 0.519020840348676 0.163368919908535 0.892560853639152 0.203461588034406 0.468409669210669 0.498869780891109 0.351870687732007 0.716954445948359 0.571995203276165 0.538980965039227 0.605480962165166 0.333813277084846 0.432557535525411 0.274238152187318 0.21867888741428 0.676974069110584 0.274821716567967 0.114338619315531 0.308102119772229 0.394055687347427 0.517545287243556 0.223129542253446 0.81411402110476 0.854976877984591 0.364724498204887 0.851264451597817 0.0826225981325842 0.991037393757142 0.801980691787321 0.590732709686272 0.438965855012648 0.180345475361682 0.21416283352999 0.100505868874025 0.673073662074748 0.422689831890166 0.679028483426664 0.588154226178303 0.527481472662184 0.905753429709002 0.571659385573585 0.340298729338683 0.911668993977364 0.48408018136397 0.470674179953057 0.415204575057141 0.718041941914707 0.526905850470066 0.520006466268096 0.393294998286292 0.314099751862232 0.717837965786457 0.335410914369859 0.415768162952736 0.748595597897656 0.0340792065276764 0.999555044742301 0.719336992097087 0.78396407936234 0.87495333537925 0.971037744369823 0.610234837988392 0.986914404444396 0.287016462311149 0.213071073270403 0.909235359521117 0.371725647575222 0.0981406097090803 0.300599655017722 0.698181163961999 0.346770813839976 0.423197061733808 0.461151682611089 0.792505884456914 0.237897229997907 0.653488689849619 0.113659774027765 0.668731288244017 0.589672226980329 0.125764799732715 0.996041564461775 0.236378865693696 0.607774094843771 0.406895267528016 0.694378457416315 0.243184029990807 0.621571106358897 0.0222784552024677 0.0306919615436345 0.607297018163372 0.827522011750843 0.0605226061469875 0.658255718366709 0.926315605989657 0.436757826332469 0.726353684701025 0.997676818114705 0.473809859526809 0.380409067312721 0.778013506629504 0.0539084287104197 0.346032668137923 0.310625607497059 0.9634070686833 0.701216438100673 0.791879794700071 0.323099952805787 0.0811299415235408 0.286318484176882 0.629610343750101 0.118103923629969 0.0452935274061747 0.343545658790972 0.055006935542915 0.681307720963378 0.0495016232528724 0.84093585992232 0.126969198647421 0.09165322907269 0.725781601872295 0.914755956882145 0.379931793552823 0.823513826432172 0.225231513120234 0.904223008288536 0.279889917825349 0.85285275422968 0.589865040341392 0.0604061810299754 0.473251295429654 0.494749618920032 0.733414212395437 0.645320197811816 0.508837548817974 0.279529673329089 0.140146050078329 0.69419894519262 0.420197114613839 0.901146713492926 0.411674179362599 0.754124759342521 0.203097148856614 0.108466046038084 0.684793795438018 0.97813619292574 0.208935663108714 0.924481640651356 0.376722495912109 0.0760513291670941 0.796779662866611 0.607317462337669 0.736856537295971 0.413531814294402 0.689492683545686 0.656513024577871 0.651501372689381 0.487005165435839 0.950546387627255 0.23765406755032 0.355582805245649 0.0627500016335398 0.768525400927756 0.0277212529536337 0.94874170092633 0.976449643282685 0.141886372920126 0.0586958638299257 0.112913800927345 0.309169055160601 0.960432984617073 0.734074139895383 0.95118077270221 0.103408658797853 0.246765015877318 0.634007505911868 0.309132775475737 0.168636873108335 0.448257847942878 0.7792336841207 0.103765629238915 0.986285806130618 0.832698918601964 0.290305856517516 0.663302787400316 0.656013539382257 0.726877074141521 0.882199443962891 0.946558972643688 0.688366396341007 0.823577317609452 0.3848163197143 0.134710484798998 0.174617748369928 0.208181402066257 0.82265950639965 0.678472123853862 0.573311492174398 0.577841598172672 0.813862026729621 0.42896502751857 0.277680115660187 0.491755146922078 0.940713589882944 0.915997545735445 0.851616077150684 0.252542651004624 0.30318672151072 0.448180988552049 0.857545862491243 0.424082009303384 0.282214047766756 0.172850499167107 0.38931633755099 0.86784480626462 0.629916133452207 0.916171991287265 0.692961894238833 0.977881570593454 0.742518706887495 0.391546026074793 0.336799639088567 0.747343421841506 0.613026163666509 0.0577779283793643 0.763752000865061 0.558125838460401 0.379341400309932 0.0137848642817698 0.144266806975938 0.740486956483219 0.164785877706017 0.250006709699519 0.245680789817125 0.686645532276016 0.204253698943649 0.564646538440138 0.427945578608196 0.214127837973647 0.38603544334881 0.231534609904047 0.68628365997225 0.18618633751059 0.922702656574547 0.508482145562302 0.680837383940816 0.616462449405808 0.952121107447892 0.0730374493333511 0.0233160538668744 0.345813130335882 0.187238940724637 0.976826793511864 0.875371381102595 0.549291629856452 0.511523484678473 0.203974364686292 0.598853116170503 0.782611806513742 0.0460699819051661 0.334318909316789 0.786890515829436 0.691261525980663 0.30951687419787 0.172359656195622 0.427608653341886 0.238216062674765 0.945144181798678 0.552600452874321 0.893834533949848 0.397041981583461 0.963235279901419 0.188767658041324 0.783712554750964 0.972290763142519 0.0128815793292597 0.646946787803899 0.760255704994779 0.709833849575371 0.677689381020609 0.950772707730066 0.938516370379366 0.735435168605764 0.507955053101759 0.272254918375984 0.488484917141031 0.428003015641589 0.494950841006357 0.517790501853451 0.284253944815136 0.838367660045624 0.347910477095284 0.902004995630123 0.165197865597438 0.903772610640153 0.474864498076495 0.362087427226361 0.653586612774525 0.764788659771439 0.215758276893757 0.697895986470394 0.365473154583015 0.462850988944992 0.370790339855012 0.811068734866567 0.295787288073916 0.822906690191012 0.0614979924610816 0.798867704016156 0.496467471241485 0.537530503266025 0.761712584875058 0.941713995612226 0.28132659210125 0.119621096698102 0.75345393553609 0.118249456121121 0.533104519783519 0.810206133115571 0.229250961013604 0.226066008568741 0.420460072371643 0.438957082324196 0.89237093400443 0.170549740088172 0.953631979965139 0.336105168508366 0.468898613534402 0.986271837688983 0.720360864577815 0.394598280398641 0.552478398890235 0.259806137389969 0.413440105943009 0.918218705442268 0.487396581685171 0.735697398206685 0.464648198841605 0.98294024634175 0.336175538797397 0.15071678215405 0.558613044796512 0.497663482867647 0.664787587798201 0.797697650641203 0.0765102906688116 0.658116398835555 0.0104607020248659 0.463348494586535 0.492502371189184 0.0170039762509987 0.138520667226985 0.116231564439367 0.463095874628052 0.755243456796743 0.871209601473529 0.806527121961117 0.370228070432786 0.655742313275114 0.0122278680163436 0.720286720274016 0.343819946430158 0.98632862332277 0.824879786509555 0.613139636970591 0.577487381773535 0.069710070877336 0.0548361512902193 0.263475605056155 0.291078488135245 0.270954933830071 0.452214358786587 0.643889258203562 0.0869547401950695 0.338428591729607 0.583499116457533 0.261937473332509 0.557994663037825 0.978809486334212 0.138119958045427 0.035232938262634 0.830688595694955 0.32905906887725 0.0483870105305687 0.577391549043823 0.813178870126139 0.0203415147890337 0.1629794066865 0.0820094462414272 0.429871709614526 0.13243306546472 0.722716257320717 0.240360000180081 0.235183223101776 0.415687810990494 0.286024702033028 0.062338049930986 0.406231392906047 0.401762878745794 0.800161471683532 0.574595507287886 0.742469184382353 0.0386114686448127 0.577448903096374 0.805648865182884 0.857229646476917 0.936390116091352 0.832952312817797 0.819076293169055 0.194632626585662 0.776206259047613 0.129068345399573 0.356122597232461 0.866355867658276 0.190377546295058 0.228387818504125 0.368013151807245 0.0893338744482025 0.707776403462049 0.240124400514178 0.827618243480101 0.180531379184686 0.658365847773384 0.528292065709829 0.296183631080203 0.169293568274006 0.100361463078298 0.888994072459173 0.470921897818334 0.109255012664944 0.710374638945796 0.338745963713154 0.119869570611045 0.333394053494558 0.118069684812799 0.0878377893473953 0.506459797117859 0.0910758820315823 0.646101585982833 0.0851924089901149 0.173545349384658 0.864743708265014 0.565055812627543 0.590424640546553 0.697154972627759 0.252826257161796 0.73390684314305 0.856942288433202 0.353710840444546 0.873334580622613 0.0589304794813506 0.457618444361724 0.11814594581956 0.296112386265304 0.619939738283865 0.0939296655450016 0.803257951107808 0.596651541094761 0.251205496343318 0.605235170838423 0.919248400181532 0.335973164199386 0.874638600111939 0.889987621896435 0.587589659339283 0.405706578730606 0.988158292097505 0.956938405297697 0.0371490438003093 0.28807288356591 0.995585698836949 0.986131066223606 0.392097445291001 0.795769440042786 0.141508033759892 0.778680094724987 0.263766265045851 0.38242182432441 0.510643376044463 0.344813701706007 0.0841725470195524 0.68324441957986 0.506104262245353 0.378648670252878 0.398857956675347 0.837864720541984 0.208040809931699 0.394093038176652 0.0693990010581911 0.211193781790789 0.253490738465916 0.822667101682164 0.0892293017613701 0.636973548673559 0.0143158340221271 0.247165831089951 0.546512522415724 0.425053298899438 0.891735349625815 0.547730739484541 0.421236577581149 0.608707183748484 0.0991823984449729 0.743528713269625 0.893060576482676 0.287076153196394 0.501763668353669 0.36737168754451 0.23962689533364 0.437786420653574 0.985756328431889 0.167819590652362 0.959273490554187 0.300634783573914 0.752172534088604 0.25239520303905 0.610712891307194 0.608198409308679 0.91972165513318 0.223269673383329 0.795362890393008 0.765123333029915 0.653072839200031 0.194021616522223 0.450722205133643 0.745316297619138 0.49873439188581 0.975196567114908 0.692366090875585 0.0942725089588203 0.271962142605335 0.849503513087984 0.015167213305831 0.258987760969903 0.127698446959257 0.244920620769262 0.163285391854588 0.882895671201404 0.0292269735131413 0.909920881539583 0.69646444916958 0.859440942297224 0.657513112444431 0.35455338710919 0.537694681091234 0.239337296807207 0.207938033088576 0.335445306471083 0.423302230499685 0.26373700162163 0.130875624790788 0.8155535197258 0.523931837859564 0.612423749726731 0.720096552849282 0.176648743187543 0.644983632129151 0.955363322666381 0.614712337129749 0.954946773825213 0.506015355188865 0.087052498771809 0.161132888651919 0.062680597610306 0.984016162101179 0.754513993887231 0.982508650769014 0.111851954569574 0.019500571268145 0.393828139589168 0.99300822423771 0.133818113440648 0.698924318940844 0.456730325079989 0.227423603946809 0.512367482816335 0.973619494556915 0.708188300074544 0.535824507754296 0.859755048293155 0.483750034018885 0.625393431189004 0.558750747123268 0.292526785260998 0.110634279411752 0.855140346093103 0.690373071318027 0.0966515853558667 0.994103303269949 0.813768936286215 0.846318104248494 0.542071803149302 0.372309102467261 0.954385848231614 0.780671203879174 0.973465301862452 0.324397220420651 0.732149934275076 0.492712795620318 0.758605541528668 0.221639593816362 0.089699178931769 0.242816656057257 0.615303813272622 0.112757523108739 0.506431267843582 0.225000167835969 0.237516433452256 0.218560476289131 0.997023097812198 0.561275123434607 0.656216996419243 0.334252139013261 0.981965289223008 0.790525256474502 0.397448832269292 0.321234275186434 0.545568758717272 0.80081090694759 0.268207946659531 0.951271595463622 0.626941595526878 0.228051948477514 0.844220331290271 0.666101167371962 0.699327279899735 0.48680226437049 0.945749184510205 0.305752276603598 0.45847374702571 0.364187934172805 0.234996726426762 0.43470326034585 0.740288209069986 0.134474014525767 0.181134747634642 0.931026817213278 0.665546879323665 0.388204928119667 0.610926769815851 0.952677816001233 0.209743646408897 0.657864358359948 0.660970373204909 0.740895220148377 0.514674982705619 0.86056535044685 0.738373169144615 0.580734742034692 0.540879722971004 0.926881620613858 0.0826812711195089 0.50228060741676 0.91673162745079 0.31802063718671 0.909708348242566 0.855770802947227 0.472389899666887 0.0906353528797626 0.231155557108577 0.477173921738286 0.961581877185963 0.122149093509652 0.92862346961163 0.243073633662425 0.463924385544378 0.350542375601362 0.474924958839547 0.459070522878319 0.308015551392455 0.120656058185268 0.88240522284992 0.367507689225022 0.904897506532725 0.408637545260135 0.646660430140328 0.110443678873125 0.657761661040131 0.59150240332121 0.147429743220564 0.491774153222796 0.460836867359467 0.324842337721493 0.353785082250833 0.716529932098929 0.127891188173089 0.201018966522533 0.917896369821392 0.433009526866954 0.0908856632048264 0.658875784866978 0.0769902735226788 0.852010738181416 0.76962090062676 0.652146264521871 0.331054299182724 0.0138236006605439 0.15502743194811 0.0569355928548612 0.286965733817779 0.826593616334721 0.313530092996079 0.111204036241397 0.778262236630544 0.609645218772348 0.98298547758488 0.154357779554557 0.107458374414127 0.612444601890165 0.723707064702176 0.560916389650665 0.221055291367229 0.525567765040323 0.759726690836251 0.384603531712201 0.0969759376416914 0.133738934274297 0.51077843635343 0.0415474783349782 0.344623058754951 0.956909673411865 0.587077783951536 0.960355066068005 0.870201118020341 0.322896694461815 0.758244135300629 0.467574020097964 0.555634747378063 0.658023536819965 0.16450546446722 0.306867003424559 0.454932730244473 0.454577407434117 0.493234596208204 0.592472299991641 0.155982751189731 0.170939386310056 0.520067798790988 0.784784625961911 0.816973255306948 0.420629643260036 0.523023387119174 0.36575613769237 0.425469000183512 0.227878696005791 0.0810187282948755 0.826812104198616 0.295314280451275 0.398430186749902 0.0778506297199056 0.178215786127839 0.0603102939017117 0.961059460695833 0.116567821479402 0.109130594187882 0.641208622974809 0.88938104347093 0.844086557184346 0.730223459359258 0.737680499709677 0.587587094539776 0.532096549889538 0.21337842232082 0.411393804617692 0.839091122057289 0.557715631430037 0.549127042198088 0.876008517914452 0.743605090449564 0.793268982267473 0.968341496987268 0.177456730406266 0.758184710876085 0.46815227831481 0.0933087385795079 0.0690434025670402 0.93888265588088 0.108018026021309 0.769930756390095 0.0797091403300874 0.11999069544021 0.395307842888869 0.0864470942947082 0.448716277906205 0.306597007277887 0.101379722596612 0.373595005164389 0.786942194914445 0.803653920239303 0.458366190486122 0.257491844827309 0.401296495760325 0.356665226703044 0.800459074634127 0.0206562378397211 0.0726785853155889 0.670008307842072 0.195091345598921 0.452673451674636 0.765797216985375 0.102371938577853 0.659189046532847 0.171672380976379 0.769523116925266 0.0124110069638118 0.300172664190177 0.41670395034831 0.77244941808749 0.0257292231731117 0.853044441586826 0.284164979211055 0.173394101588055 0.564399611658882 0.375841409487184 0.4068641801388 0.0510466739651747 0.242040453266818 0.749289001713041 0.517582837687805 0.343408907055855 0.882697704269085 0.55100777738262 0.372639011472929 0.788330242647789 0.422327554132789 0.399239358750638 0.871754393056035 0.871311250699218 0.272644381579012 0.910738834526855 0.173795418143272 0.293663798200432 0.961242696915288 0.0602441473375075 0.36522413714556 0.394767405956518 0.051672226882074 0.0929390658461489 0.354074242361821 0.571267759797629 0.539980812030844 0.0876991553301923 0.64736836274853 0.887723000512924 0.379767403434962 0.250531636821106 0.430029463109095 0.748469444199 0.144975428325124 0.125543349452782 0.755831372370012 0.648505363701843 0.607688508403953 0.17593524025986 0.477073248459492 0.542990039635915 0.342641809338238 0.263933152656537 0.031823807542678 0.206047907008324 0.266398634698708 0.935278674620204 0.814876118996181 0.504662567167543 0.486813753989991 0.818727992381901 0.700114816720597 0.215565494189505 0.37106709824875 0.944734623171389 0.692268272137735 0.290701732987072 0.960061566520017 0.798947854749858 0.969381794142537 0.298300514987204 0.1102687199926 0.319651114139706 0.690350210096221 0.0314270346495323 0.267580175157636 0.733706457780208 0.0613304940192029 0.878492409947794 0.677441502034199 0.172762544085272 0.0798918968741782 0.357735087627079 0.225157233050559 0.106320682875812 0.448444697055966 0.0110041382536292 0.902476483781356 0.113148938436061 0.400961580243893 0.208393119154498 0.016182656546589 0.277244439274073 0.674970579445362 0.975119102885947 0.577529631699435 0.94317520248238 0.917095848112367 0.382361454379279 0.0281931516295299 0.264581048625987 0.80587940878002 0.285811158213764 0.854981782613322 0.318060630494729 0.310278807741124 0.686344714739826 0.298271355750039 0.196688576738816 0.768142816605978 0.798953876162414 0.564171331594698 0.405102469907142 0.9646171969641 0.798690404384397 0.787167183174752 0.3076736117783 0.533668174063787 0.989724302156828 0.380559859867208 0.216024191766046 0.480867147971876 0.305666320899036 0.860034786851611 0.265426630314905 0.992591567060444 0.230277325224597 0.222873851542827 0.386592567958869 0.0126982520613819 0.546512157530524 0.211131955301389 0.723588034217246 0.594153815694153 0.74739442785969 0.0703024028753862 0.893412401420064 0.384492561894003 0.882937583671883 0.991743468055502 0.920199062584434 0.692819941909984 0.887564843408763 0.0309199564764276 0.706188129412476 0.469632317917421 0.0400676906714216 0.236445385902189 0.648580676882993 0.498237996804528 0.144125449573621 0.9201012355485 0.31770112475846 0.23697242396418 0.251102056805976 0.398169377043378 0.212946233435068 0.397113648909144 0.665835099907126 0.862228967412375 0.386894231208134 0.900817879550159 0.19835870078532 0.447801936217584 0.50762207979802 0.885459706361871 0.887605436483864 0.504722007496748 0.781091189279687 0.880253747457173 0.878190965675749 0.755822914547753 0.556531084298622 0.795168512151577 0.349988704838324 0.597751147192903 0.302197609473951 0.355418375711888 0.711319594110828 0.312042580738198 0.412275379246566 0.529289857081603 0.591006211081985 0.280580216543749 0.888943211887963 0.479597174830269 0.927021396078635 0.236899329137523 0.353388930791989 0.160336195586715 0.383863736535422 0.948693217295222 0.381035202939529 0.070222035930492 0.803985939493869 0.819345483479556 0.8516742660827 0.957640724251978 0.275737536007073 0.0734870741073973 0.879232924522366 0.0482062994642183 0.590850644824095 0.921812361350749 0.447235726818908 0.436845649336465 0.334463924791198 0.355707779233344 0.311815714114346 0.153372491551563 0.41180266989395 0.367764520000201 0.982799926891457 0.851932607109193 0.196103297881782 0.117221239132341 0.485840223680716 0.967697784404736 0.426398656216916 0.279482627341058 0.555121869535651 0.376595050247852 0.141914682295173 0.512741280389018 0.294099519534502 0.519603997201193 0.299091858784668 0.599948540264741 0.90762702024309 0.287297230293043 0.372715799869038 0.667715912309941 0.553964935892727 0.826086928402074 0.399316125018522 0.271725394576788 0.951645323885605 0.741314358452801 0.504782029613852 0.0353770610014908 0.815358898304403 0.861327707422897 0.355889406546485 0.268716225980315 0.572388898271602 0.201661871194374 0.717402445450425 0.880876624472439 0.632462003184482 0.752663636836223 0.925122851131018 0.0912715619197115 0.901812884609681 0.90109769647941 0.720869598218706 0.651066128264647 0.228158507863991 0.638247293755412 0.916007691987324 0.642616775352508 0.721013945236336 0.941885139448568 0.595381338372827 0.145428800375666 0.928551626182161 0.521325390038546 0.579961015530862 0.301009078801144 0.380635525025427 0.266157083231956 0.742772554731928 0.404257770350669 0.0804823548882268 0.299794727717526 0.744574928572401 0.331760529992171 0.56228535202099 0.0452862389222719 0.901178278943989 0.789288378166966 0.806919084039982 0.916252959382255 0.56219217836624 0.884108033510856 0.370757201686502 0.521944509404711 0.794736090688966 0.434051242072601 0.544976005130447 0.140519027293194 0.830179494402837 0.973939049397595 0.585572957741097 0.0260225975583307 0.246344935970847 0.040662250474561 0.724264488273766 0.767680223309435 0.608245533667505 0.32145865584258 0.0356536582740955 0.0949848960246891 0.109471054899041 0.319408746003173 0.96223299580859 0.30259844197426 0.753920243838802 0.47286711971974 0.388872834688518 0.507392454522196 0.400067981921602 0.469099577227607 0.428688771850429 0.97718788879225 0.94313550099032 0.772323560123332 0.431019930269104 0.902523763037752 0.0687571942689829 0.678682710558642 0.572064933460206 0.0633484230423346 0.53385005700402 0.72227788036922 0.368662283730228 0.754519293135963 0.229792585032992 0.399575985977426 0.595860909549519 0.77864362741122 0.82595491095446 0.26082603670191 0.952726358410437 0.320854860271793 0.278075961472932 0.316283407455776 0.15152220687829 0.399827604172751 0.145503898498137 0.970790496498812 0.603786526806653 0.205437450150494 0.408896529388148 0.71583840664709 0.244190010649618 0.504233084609732 0.246286879347172 0.611573016771581 0.0138117293291725 0.268562236588914 0.866298551638611 0.982697939288337 0.502243269495666 0.487256226737518 0.20562476165127 0.0526339139812626 0.318181434234139 0.920404766788706 0.232913241616916 0.173123080627993 0.0585339714353904 0.0427096508350223 0.310219772404525 0.540953518063761 0.246421191445552 0.958805998160969 0.121394326514564 0.837202708609402 0.505480759416241 0.091664368098136 0.812207195821684 0.789378582029603 0.406868905897718 0.301400929316878 0.800374311087653 0.135157727792393 0.486852476308122 0.558721195340622 0.872587815516163 0.054131969185546 0.478540085810237 0.577920169504359 0.638209217304829 0.856931219019461 0.915698504680768 0.125020977449603 0.132740475367755 0.89459676023107 0.231511749604251 0.66557354936609 0.925248206830584 0.301814843285829 0.109788758575451 0.536522219427861 0.295097885779105 0.20125970777357 0.406874615671113 0.793964249002747 0.44700396109838 0.942090328941122 0.923667937205173 0.562670900833327 0.484550057151355 0.437522036777809 0.665264199555386 0.721159273271915 0.229704317850992 0.586924170278944 0.520269430018961 0.819004667333793 0.40606638780795 0.975837882703636 0.822301795354579 0.666766606182791 0.569378950577229 0.316995687107556 0.275464786970988 0.858199428357184 0.51570204695221 0.268945183721371 0.0910424336069263 0.487725841826759 0.748398362579755 0.322032867590897 0.644181697901804 0.942235681870952 0.648399978033267 0.885055149174295 0.563524106156547 0.42404989156872 0.610885627684183 0.185236604493111 0.835605547081213 0.353960766983218 0.959948264018167 0.758540900144726 0.946252825662959 0.91909409707645 0.432623393039685 0.629769334350713 0.81029528289102 0.446138906341512 0.270547872465104 0.0483590268553235 0.781522723999806 0.610740746592637 0.126111321041826 0.296037097286899 0.229169716085307 0.233956949515268 0.227171014875639 0.500187013235409 0.758536801582668 0.700765048600733 0.240041574339848 0.26618132009171 0.193353405690286 0.694618107469287 0.240029880495276 0.272669488815591 0.384545851037838 0.489178955529351 0.870378664520103 0.828602188576478 0.725221616497729 0.182814673562534 0.193820437770337 0.270740885671694 0.513180821607821 0.557911595297046 0.106865498430561 0.0789247309649363 0.244795614280738 0.826290121283382 0.47105792254908 0.687519796753768 0.118933643761557 0.155878362213261 0.585245578959584 0.277844439623877 0.119189892518334 0.462112736981362 0.340730180386454 0.197596954640467 0.555705226003192 0.816971976249479 0.804211179462727 0.882478824090213 0.964024429316632 0.0747338736965321 0.243675732275005 0.380597363058478 0.554326138356701 0.663569790474139 0.536725910424721 0.422986500153784 0.166823956551962 0.262881513633765 0.157177808766719 0.51908250940498 0.503784790756181 0.988432551154401 0.551710108553525 0.237761342185549 0.536934209163301 0.264839341477491 0.907849580391776 0.624073128092568 0.540022433837876 0.507481352358591 0.945637513503898 0.625573583748192 0.632560132639483 0.647342883250676 0.0858122028061189 0.54181682722643 0.174839757618029 0.282094420741778 0.468593451259658 0.581666702169459 0.314850088371895 0.44370308003854 0.654086845489219 0.838409352155868 0.922264451116789 0.866828033025376 0.817415043001529 0.39972039937973 0.828033081993926 0.297219958985224 0.30216739038704 0.346774169031996 0.439862271226011 0.921115670802537 0.565517330861185 0.117309796747286 0.47743367228657 0.219077085964382 0.316787280263379 0.870457616872154 0.625200922091026 0.762308903411031 0.921799916760065 0.564663755812217 0.399144673922565 0.673563654723112 0.298880151608028 0.682808409656864 0.127830966210458 0.820243535798509 0.251465602556709 0.22079416264547 0.0387251980369911 0.23298400076339 0.977400925506372 0.167183509310707 0.401230079738889 0.434058873082977 0.767372803264298 0.311161319131497 0.577467710704077 0.879167186869308 0.0877128261933103 0.284156090118922 0.285944377961569 0.257537817596458 0.552599379885942 0.988080798825249 0.145363892992027 0.236542697534896 0.660593430427834 0.554516090953257 0.598490320474375 0.488714214181527 0.16734318934381 0.97733339846367 0.0235616886825301 0.631167379431427 0.674751090048812 0.0939176838030107 0.983667441799771 0.364986026848201 0.0568006643932313 0.255942997511011 0.810789124928415 0.971109606239479 0.739228474113625 0.0305729469633661 0.335395716659259 0.0348865418857895 0.945134906384628 0.610468474235386 0.392139618459623 0.0537224619602785 0.17161481901072 0.108941265100148 0.558313031482976 0.745777088617906 0.0834759000362828 0.959995394600555 0.435447218625341 0.580326578407548 0.565291489742231 0.136518060155213 0.110868554611225 0.497395132507663 0.464386137046386 0.631414307595696 0.255525160392281 0.697608052862342 0.55430721065728 0.978578271975275 0.998080664202571 0.361470565861091 0.201724104520399 0.990186518121045 0.970818710906897 0.21920560576953 0.744328367828857 0.540527768721804 0.0418397248722613 0.113044937164523 0.872899218180683 0.217468365896493 0.536757533270866 0.532617253977805 0.139826990817674 0.869243170591071 0.89314728685189 0.998843329360243 0.297599186731968 0.135225034705363 0.898070855499245 0.49940160994418 0.572228276175447 0.811580112138763 0.147576831832994 0.483691596374847 0.248613110317383 0.21382858693134 0.916027793404646 0.275876278821379 0.301143614486791 0.531776344801765 0.950160172663163 0.49079081872711 0.566219877090771 0.437414636518806 0.328565257957671 0.933961576889269 0.264609859343618 0.624557428946719 0.956454697295558 0.845299073238857 0.611050003971905 0.889278273081873 0.806617809417658 0.930160783973988 0.718715973161161 0.104688599552028 0.758689719829708 0.24764008411672 0.370166139295325 0.723819955987856 0.746078484023456 0.482814934672788 0.0714768542349339 0.775416437487584 0.270042012035847 0.119632649014238 0.488820009683259 0.591358801056631 0.607294437689707 0.774113049574662 0.506446922640316 0.171360435478855 0.725702925892547 0.159038127667736 0.0752403899049386 0.684401128022 0.935634345489088 0.911831207231153 0.624428914673626 0.585419789629523 0.292101646519732 0.176073767554481 0.474331629918888 0.762689045791049 0.340478666608687 0.760444904309697 0.0185148192639463 0.0188131863297895 0.943284416333772 0.917893436218146 0.333430921882391 0.603763380914461 0.540052510704845 0.307945212682243 0.245227542929351 0.568873739242554 0.779270612208638 0.276831600137521 0.587918522786349 0.74047598088393 0.450348678401206 0.0463983105868101 0.571762638173532 0.0488261460652575 0.247267729258165 0.244227790674195 0.65349788458785 0.811455391703639 0.847978227490094 0.508915670439601 0.308264740784653 0.898676451523788 0.257195576024242 0.221018207459711 0.88204414785374 0.804684619968757 0.0851768304896541 0.751477773766965 0.324936266040895 0.214203421303537 0.830859524703119 0.381713444080669 0.018745048455894 0.256037879879586 0.337256527913269 0.922213369032834 0.719378066000063 0.390512413256802 0.562702950108796 0.201087412347551 0.526161377939861 0.419945966182277 0.242864210072439 0.363191327813547 0.980969974137843 0.902443144384306 0.111324511053972 0.84243770781206 0.588287233402953 0.0137075533368625 0.255296572376974 0.710327752926387 0.98560313611757 0.210204065376893 0.488931526944507 0.066913916405756 0.575844329304527 0.0836551665444858 0.168509359676391 0.886816640428733 0.543656900876667 0.509169684706721 0.199648121178616 0.505679194959812 0.975542885812465 0.622648580544628 0.925460929831024 0.0333634937740862 0.192076978944242 0.765592583694961 0.581905864018481 0.0768366305762902 0.720233925788198 0.295539945005439 0.196411649617367 0.572563011900056 0.0701021765591577 0.0335434303525835 0.179535637670197 0.56162696266314 0.428488098820671 0.35942659168737 0.422166794887744 0.124034586492926 0.134592779472005 0.208982417511288 0.357027793049347 0.148390745266806 0.439858239279129 0.88914533062838 0.64572488799924 0.857493960740976 0.660453169294633 0.172097624596208 0.186948321303353 0.983647731083911 0.712468468009029 0.210167018119246 0.316549344917294 0.0716350620496087 0.427533066093456 0.650138288820162 0.227493842388503 0.742708243427333 0.221675008886959 0.746559099836741 0.357831481860485 0.0422735823644325 0.338134902478196 0.696041366509162 0.22910561269382 0.274713247930631 0.518369037595112 0.657538347379304 0.42237506066449 0.927532373890281 0.525516532438342 0.164898448593449 0.41743335978128 0.307137145940214 0.605651136508677 0.732083816754166 0.0419373091892339 0.704567723337095 0.497836336339824 0.901878489493392 0.83470682307845 0.56396250546677 0.161146362435538 0.335135870222002 0.443068949668668 0.86909416857874 0.681956739248708 0.533220831723884 0.675538440623786 0.893561032323632 0.898508486545179 0.575067722904496 0.614029628161807 0.884020246695727 0.500408585220575 0.785285152336583 0.790725608875509 0.18406443787273 0.454683809387498 0.496318551057484 0.0490971322194673 0.907680278038606 0.840651223650202 0.789924131734297 0.93781354800798 0.167044246483129 0.570036304749083 0.833321204378735 0.657926670978777 0.329818735660519 0.94432539485395 0.24387311396189 0.600504062883556 0.997388417969924 0.337738101233263 0.539092473771889 0.87757961055031 0.129050817310344 0.729162483378313 0.471436740693171 0.447627452402376 0.745038317793515 0.770916693257168 0.88210392102832 0.117614956717007 0.495450789972674 0.946287420836743 0.509538336314727 0.0131663545942865 0.637496981217992 0.368967679273337 0.719059125678614 0.141034988334868 0.830573310181498 0.357201813554857 0.823335466720164 0.373903530698735 0.250526381367818 0.36782675770577 0.820779697143007 0.317045799468178 0.148200101854745 0.774554782179184 0.28424879216589 0.422836860110983 0.84792438122211 0.791043877513148 0.139860916151665 0.0275981806102209 0.430824409197085 0.0657188809569925 0.969971402755473 0.430058351967018 0.871766003689263 0.363188098936807 0.960895412873942 0.254117249581031 0.271927091497928 0.544478174711112 0.577013080110773 0.226616974386852 0.617846287935972 0.242212168287952 0.402843585496303 0.787691841991618 0.55676704055164 0.738537446316332 0.604030103697441 0.0331470382492989 0.151993430182338 0.411992690949701 0.516928825338837 0.0715647786599584 0.809084647274576 0.102699074870907 0.494358139282558 0.841528805978596 0.111328815915622 0.585191841027699 0.263672492315527 0.886764817510266 0.125917634076905 0.711554956589825 0.0389565652189776 0.574972734504845 0.161376774415839 0.796839152292814 0.552670832844451 0.275443875568453 0.634583009395283 0.134415050183889 0.600483579293359 0.132773412077222 0.0798379830690101 0.280036590611562 0.677564061970916 0.443507924543228 0.673145770812407 0.0808834109758027 0.043381870102603 0.433709355012979 0.263474251315929 0.421961573124863 0.899287487633992 0.429553173133172 0.0675419241725467 0.891558318990283 0.0840239758160897 0.0931528436252847 0.817975906128995 0.0270226821978576 0.54431059605442 0.851173014778178 0.247501997542568 0.816092896577902 0.75104696628172 0.394265929681715 0.157242445771117 0.917494860796723 0.397990715142805 0.770956406043842 0.734654104521032 0.179294376866892 0.182108653662726 0.886064102391247 0.357562463274226 0.0578348838933744 0.283409289054107 0.873621347888838 0.295447488673963 0.145192786036059 0.778043112810701 0.252842669619713 0.597138450543862 0.252925816192292 0.246363144733477 0.634969523551408 0.854860953288153 0.0524075830448419 0.967755013294518 0.821944613081869 0.285493367637973 0.249740863977931 0.759355076120701 0.513195103532635 0.483908991427161 0.837232439953368 0.239786851739045 0.261238210378215 0.85658812090056 0.836232441521715 0.390262177614495 0.713934033447877 0.812570607420057 0.289176256994251 0.25413187610684 0.582841237201355 0.996536314447876 0.514595016604289 0.158959329982754 0.946249907042366 0.308671072609723 0.0314935115235858 0.528513269121759 0.80983515643049 0.781386149059981 0.192579111920204 0.971278218238149 0.0584052377240732 0.91737153490074 0.833988884133287 0.015484247833956 0.609795091392007 0.189318175762892 0.0446372736524791 0.113578271628357 0.902239930527285 0.668460788910743 0.727675217066426 0.39149787528906 0.302502090383787 0.722362236618064 0.122427848284133 0.496627271596808 0.170936267152429 0.124246165510267 0.951138403606601 0.728251021124888 0.810997942297254 0.920050347086508 0.537270839617122 0.827033083562274 0.500269352127798 0.178365818255115 0.236112992772833 0.4472628472629 0.0171416527614929 0.39678944068728 0.676647386907134 0.442113536843099 0.452525196028873 0.452961204107851 0.674171943936963 0.42111602347577 0.73287991512334 0.209574794687796 0.418964527568314 0.755022969786078 0.971950975728687 0.972006267707329 0.226111380418297 0.760683698737994 0.383212962974794 0.514704368296079 0.390539974651765 0.764055884082336 0.636287412827369 0.0458942448487505 0.221399333162699 0.939019516874105 0.636351214260794 0.451436764914542 0.412505343591329 0.164794099263381 0.0453752308036201 0.074140539013315 0.014426828965079 0.466451511057094 0.569422491316218 0.810935343625024 0.0474439431796782 0.47842238509329 0.155656352504157 0.181541161518544 0.815740268109366 0.99949807632016 0.727786646736786 0.744444638048299 0.948048212977592 0.423797578178346 0.966097678670194 0.93335504733026 0.982415157407522 0.990414749779739 0.373542569109704 0.38096439308254 0.834201853079721 0.497892828313634 0.0118010906339623 0.228119076751173 0.180829185438342 0.992000964751933 0.417840409851633 0.748395546071697 0.828099227866624 0.750001156893559 0.564817581085954 0.838167724623345 0.82857086123433 0.259463910108898 0.952995625478215 0.902087885192595 0.522360060631763 0.0622826735884883 0.80362050754251 0.998001917458605 0.951724904587027 0.985698445145972 0.651175781222992 0.502853491702117 0.890876360307448 0.411933568713721 0.302492926532868 0.139742474139202 0.457778566959314 0.895513208019547 0.398809589678422 0.438661305413116 0.75393244617153 0.856638464916032 0.938158169516828 0.132332207553554 0.0850326217734255 0.749519163828809 0.805513513979968 0.96378555444302 0.480222530898172 0.849098883292172 0.656310130197089 0.0910919775487855 0.308562135361135 0.835066130582709 0.48003149286611 0.742029684423469 0.353590359869413 0.392159516573884 0.581847499443684 0.397425820990466 0.347725481912494 0.937611497265752 0.716921218805946 0.731602162527852 0.955424287999049 0.46298401968088 0.359212566118222 0.108963812377769 0.525339699573815 0.896128061248455 0.370899245524779 0.36738626105478 0.950664045701269 0.28440993450582 0.435437398534268 0.32086473015137 0.574831970876548 0.0242303690477274 0.212842531125061 0.642535040606745 0.626403032348026 0.992293580092955 0.240911697151605 0.815491790738888 0.460549181310926 0.192940330058336 0.453903792705387 0.294096372947097 0.741689927205443 0.330852035456337 0.161740067766514 0.0339967175782658 0.920222100832034 0.301712768552825 0.284266203620937 0.035928029816132 0.0484765625325963 0.874736419541296 0.644834253706504 0.92090479043778 0.794955541130621 0.789855433509219 0.673466588805895 0.658659302834421 0.122871918643359 0.441864063702524 0.119468907299452 0.537993527140934 0.338544167445507 0.328170892430935 0.72597388968803 0.969963820842095 0.418268711776473 0.114068902998697 0.50055789725855 0.161130271067377 0.0165086412499659 0.332133334791288 0.392283753645606 0.748104818775319 0.0829749269480817 0.234250927125104 0.117276296229102 0.35598938670475 0.853424745548982 0.862313448132481 0.882051953815389 0.59648260846734 0.0548321940260939 0.667111878860742 0.0290444666030817 0.872656528954394 0.772878419586923 0.712765554864891 0.788591830530204 0.345295734647661 0.023299528923817 0.979607497181278 0.322477238294669 0.979349222078454 0.422736855058465 0.41894775345223 0.230709424214438 0.0327679040865041 0.601654749221634 0.48151004711166 0.635230582200456 0.356778343650512 0.183509278064594 0.819949929988943 0.072862033827696 0.570812858133577 0.593387168608606 0.948098102903459 0.8371501918789 0.410017713271081 0.965248571909033 0.585754935187288 0.0575302679091692 0.501613023551181 0.887285301238298 0.415444236174226 0.035212720441632 0.153851033765823 0.315988742948975 0.626738350552041 0.865993573765736 0.741827184432186 0.131466645000037 0.704413614775986 0.397285020251293 0.472744257133454 0.311572732841596 0.749487196381669 0.288001988423057 0.196690804774407 0.81932828408666 0.358660380712245 0.525588212441653 0.727903156217653 0.566247839098796 0.258837731608655 0.0993126931181177 0.686535079013556 0.739176242975518 0.535743495172355 0.539215981534217 0.719308433779515 0.489756893808953 0.372475661612116 0.819536685859784 0.758955133589916 0.501580465326551 0.482626972694416 0.452621605244931 0.0666327213030308 0.979167163725942 0.534104634849355 0.723845160957426 0.924794890792109 0.572833410273306 0.491135197516996 0.203203166793101 0.777233439467382 0.123965774399694 0.0864769021654501 0.384079633783549 0.0474345080275089 0.205226460527629 0.151922361932229 0.518968552276492 0.10214276900515 0.557350839583669 0.191459527031984 0.501488272920251 0.559662262853235 0.353780176930595 0.0548489536205307 0.32189756364096 0.0876799074630253 0.332421401168685 0.0456944456533529 0.956685648420826 0.876400994474534 0.603285690406337 0.867136288871989 0.724357579408679 0.289523513375316 0.978713933895342 0.850785255678929 0.390604597826023 0.29407333308598 0.79152657499304 0.830458111106418 0.53123565108981 0.213252930163872 0.914876577141695 0.0487057906528935 0.941153994102497 0.935706240781583 0.392416801899672 0.946954947537743 0.0399548111413605 0.330641681558918 0.584388340767473 0.588691790360026 0.231991938988212 0.190608654853422 0.978915533774998 0.472855262910016 0.554958528664429 0.543510756171309 0.39925544527825 0.755777597327251 0.354775271886028 0.29677751804702 0.420968000176363 0.261595796721522 0.728812642144039 0.166904160301201 0.129920197213069 0.295486798312049 0.770713579668663 0.850667477974203 0.693345597879961 0.148667612457648 0.0303908736282028 0.357013523802161 0.701295278889593 0.580079635952134 0.902094880247023 0.0114785201312043 0.433066417840309 0.865326168308966 0.376173942300957 0.0373813818581402 0.287097971395124 0.335605954152998 0.588482184673194 0.0715938602178358 0.268492995530833 0.942652138511185 0.0462583345849998 0.357836089602206 0.76451618849067 0.625512487029191 0.848983689057641 0.187124346026685 0.046141349808313 0.925811092846561 0.377455575864296 0.456723726489581 0.995606227836106 0.9251503256266 0.0972423550090752 0.639992902937811 0.0702564331027679 0.755915659698658 0.638072297072504 0.85543841857696 0.308535731318407 0.0124609201704152 0.248906257888302 0.597336922045797 0.755266754820477 0.875291462945752 0.872080820554402 0.655719998343848 0.423938014723826 0.383183558713645 0.270664750519209 0.738742739765439 0.0380722950957715 0.0662704559927806 0.809614707222208 0.622351065415423 0.758250168468803 0.196525936133694 0.400227076478768 0.113858913755976 0.2797822172218 0.900466558260377 0.35927158070961 0.270520873956848 0.520277657338884 0.983103895164095 0.478091046973132 0.662175286600832 0.590203925569076 0.469234980063047 0.427122954260558 0.518432482671924 0.254151793813799 0.90755982673727 0.400152008552104 0.490896176735405 0.346521870393772 0.0376269440655597 0.56807236559689 0.802418044847436 0.677870206877124 0.794863556406926 0.139565451571252 0.569275433821604 0.260021170254331 0.161377435035538 0.541676085265353 0.104872958548367 0.612312893776689 0.0273265827028081 0.991605228888802 0.74277725329157 0.50938355053775 0.966982835996896 0.726110208539758 0.679675785622094 0.503784539047629 0.48253319397103 0.713684247285128 0.581353324330412 0.523805099145975 0.273839992822614 0.87637582661584 0.659695579337422 0.545640878058039 0.796834803405218 0.133720588593278 0.425461734749842 0.250300627839752 0.792351142475382 0.564387561457697 0.024113783731591 0.254238896728493 0.0984285553032532 0.3561681055394 0.53308855980169 0.492480927556753 0.104807908483781 0.0857409994816408 0.169062772968318 0.338175706693437 0.321788478640374 0.0570028149429709 0.836786099376623 0.0138698336668313 0.776810006904416 0.893853750929702 0.142999235438183 0.290253389114514 0.948390753741842 0.43781041318085 0.0249535970995203 0.0916675356612541 0.362102954555303 0.0328227758593857 0.531724654652644 0.0999698502104729 0.700003362386487 0.362755510360003 0.444067736349534 0.275463258740492 0.377426125272177 0.800727960912045 0.712962257261388 0.992237860993482 0.725071813950781 0.748853836581111 0.14944358474575 0.856018741172738 0.155312491883524 0.780190828249324 0.788307274703402 0.912057838512119 0.261794740522746 0.120165195851587 0.0982294466928579 0.945712171597406 0.97675809759181 0.890031561865471 0.816190359650645 0.182853997030761 0.567938932634424 0.77392476212699 0.260383414588869 0.757296541575342 0.359418276315555 0.564105843806174 0.6026217991882 0.109615602684207 0.0604167873645201 0.349843271002173 0.809850627747364 0.8136566037382 0.482318065217696 0.731650996753015 0.71266831192188 0.73706484479364 0.876854574899189 0.763389773587696 0.325740280321334 0.0852199798356742 0.595251235477626 0.373521074766759 0.644307684486266 0.280844414404128 0.843389011933468 0.755623855034355 0.805906360496301 0.504312588784378 0.255742910418194 0.550990743259899 0.346410055093002 0.340402270758059 0.896328533971682 0.7624864900182 0.554638683390804 0.276754448930733 0.0412327880156226 0.506627145272214 0.814137937105261 0.733713426787872 0.74044249857543 0.194668531934731 0.026371193388477 0.0708488985616714 0.964179497458972 0.709448455430102 0.901217504909728 0.509865652399603 0.647672531558201 0.67988433745224 0.542622462168802 0.322189267575741 0.562471768250689 0.717226955492515 0.107868545486126 0.851839675020892 0.932625175279099 0.866036005096976 0.344172649811953 0.102252614202443 0.384941841145046 0.146697464033496 0.132370494683273 0.588498666512314 0.169249223312363 0.431288169296458 0.764843202386983 0.320588694382459 0.824242581008002 0.109072879168671 0.749447123550344 0.866845878977329 0.73634883423103 0.179628482628614 0.592703916346654 0.104989970293827 0.9045437154104 0.313029606959317 0.240445942976512 0.411658251651097 0.719313525806647 0.224279180497397 0.0426912519079633 0.586175321661867 0.479653143563773 0.198939859182574 0.778240193461534 0.171661813135725 0.393349994069431 0.689896302127745 0.635234565972351 0.17808135578176 0.931493375380523 0.827599183011334 0.584299028718378 0.453811222275253 0.393893182277679 0.602818406387232 0.330777117817197 0.0836509220744483 0.734800954102539 0.671463158379775 0.872184973496478 0.610634462425951 0.89431645025732 0.419203451308422 0.448082993249409 0.0324919616710395 0.266312203467824 0.76848298181314 0.633186011025682 0.310556031058077 0.97721256014891 0.320210886991117 0.648074943230022 0.729243946361821 0.481790419551544 0.146453909731936 0.673716278388165 0.0301885174703784 0.662088214803953 0.383313506019767 0.940230847224593 0.583440863445867 0.577418978130445 0.445689945414197 0.224139704685658 0.867181031680666 0.353741083503701 0.76260201848112 0.556599345260765 0.131971896211617 0.69295182059519 0.239868220677599 0.065365934856236 0.0867803508858196 0.639105435516685 0.228874387962278 0.428837363338098 0.102573828890454 0.19291415306041 0.0559347136737779 0.703113207258284 0.428011164821219 0.326780396301765 0.393681536645163 0.541668179726694 0.504593428221997 0.712296723022591 0.321693953089416 0.896409060654696 0.668743864221033 0.031748616527766 0.898996651771013 0.358779298251029 0.366548415715806 0.328620354009327 0.913198805488646 0.939609519185033 0.756120028141886 0.110186948366463 0.704803804983385 0.409601530006621 0.840569456864614 0.123091833086219 0.087369782011956 0.499349590176716 0.0990957871917635 0.420676969538908 0.393866589453537 0.325354367084801 0.112618669883814 0.129766684961505 0.739683751726989 0.139511566117872 0.676046509956941 0.0732780255447142 0.878766651486512 0.120567161270883 0.607931357598864 0.981676621004008 0.394733624225482 0.565540165575221 0.999172647588421 0.213964173707645 0.184889239775948 0.434757104769815 0.689470125895459 0.19632559687132 0.583929360595066 0.443298249014188 0.350314644363243 0.867795361899771 0.744819806187879 0.902967279730365 0.448844976581167 0.620854827261064 0.853729338252451 0.164070714469999 0.674950933731161 0.697833416149952 0.198269365224987 0.374977480734233 0.0911295533482917 0.104477442123462 0.732915323739871 0.0586077660671435 0.41100135179935 0.332415129891597 0.945556225932669 0.752179031027481 0.828510225520004 0.305204494483769 0.559300175029784 0.0736347777000628 0.194780995408073 0.864148515732959 0.46955511208158 0.918846989581361 0.393324841654394 0.358957116974052 0.510993682201952 0.389324072978925 0.386387569091748 0.255235568089411 0.542150369409937 0.29742247995222 0.247517744540237 0.360246025191154 0.792528135769535 0.919771525235847 0.222345631925855 0.269966398971155 0.17992266838206 0.192036919021048 0.80358211484272 0.583824648223817 0.060291104351636 0.325254428647459 0.420915757052135 0.0937550037819892 0.0132834933465347 0.217091081745457 0.128755068981554 0.243224426677916 0.793489974078257 0.819041775213554 0.357694241921417 0.152224811655469 0.267493413616903 0.386063454684336 0.0212242827285081 0.357102453678381 0.528822334262077 0.286222938653082 0.168964407478925 0.119550203629769 0.757474719190504 0.348732956917956 0.134685659466777 0.275922253434546 0.622266851386521 0.636248339454178 0.40153025140753 0.925393040899653 0.325434837294742 0.765747149111703 0.708676743977703 0.379862919454463 0.517387628485449 0.346848462009802 0.128963852236047 0.330029801349156 0.534528940094169 0.969058057528455 0.262163248297293 0.743695965535007 0.213136869932059 0.262080278059002 0.654896171465516 0.563707514100242 0.794718200250063 0.83734944201773 0.715307683774736 0.175359565974213 0.249249400724657 0.585668313561473 0.044844904395286 0.743893050565384 0.722520366061944 0.31947109388886 0.882810250031762 0.240152027141303 0.0867383220116608 0.588135246385355 0.683902146934997 0.02233918127371 0.44248077086173 0.486602183270734 0.80653671131935 0.310855989051051 0.121786114564165 0.767738978585694 0.99239087858703 0.735288668926805 0.590443900630344 0.467546194547322 0.440779676982202 0.817486641868018 0.147296886283439 0.673402502241079 0.387916599200107 0.885229112976231 0.95785630939994 0.162590571141336 0.957648558334913 0.947790965915192 0.182372340960428 0.79267591127893 0.861629804708064 0.443334775797557 0.343987145449501 0.463777021712158 0.915149813920725 0.0185256535653025 0.0223387548443861 0.684952748697251 0.74449461717857 0.849951490692329 0.362375904128421 0.457563033443876 0.422675279125106 0.779486079800408 0.534254891024902 0.525471079451963 0.0993115963879973 0.599554394637234 0.583898943506647 0.751712940318976 0.717763274039607 0.924330891661812 0.163924407721497 0.882952436089981 0.975680096708238 0.896911140154116 0.0816862003668211 0.932567843585275 0.577234638726804 0.260504117829259 0.77355039682705 0.236173223725054 0.763702298568096 0.85471641080454 0.996259726395365 0.929043556433171 0.829175035289954 0.568349035708234 0.194883755424526 0.750479506407864 0.392855424797162 0.870503953143489 0.117028090620879 0.595283471229486 0.351421853119973 0.795285752324853 0.881091536784079 0.389594353104476 0.558990562446415 0.401180570833385 0.536843416828196 0.456051795810927 0.141986229068134 0.162709261174314 0.978378655568231 0.204916868458968 0.500713916914537 0.898111468628049 0.0941935519967228 0.261168742275331 0.894527785403188 0.221814659880474 0.843427912660409 0.674253432736732 0.368405903356615 0.196002346847672 0.298622752414085 0.249527535447851 0.748493826966733 0.535385253280401 0.166205954661127 0.421149856378324 0.419853523450438 0.549883599043824 0.925681053800508 0.851361018707976 0.694020389784128 0.688012093503494 0.16460884753149 0.300909911163617 0.246620793100446 0.103861302000005 0.113133187980857 0.67108274515951 0.866085336976685 0.0545732656796463 0.237015118990093 0.529471788657829 0.751667430629022 0.353243912551552 0.321634002889041 0.0274934083083644 0.542973171935882 0.872771817464381 0.706929665803909 0.836923372738529 0.813053367827088 0.44046898126835 0.29823083966272 0.190644253864884 0.979666843004525 0.6741824903409 0.736384552642703 0.744949970396701 0.985902698107529 0.250587589880452 0.856187305687927 0.58641516602831 0.934291305181105 0.810097781112418 0.532747089490294 0.249604778394569 0.842479047023226 0.224347223634832 0.648556678132154 0.635444307425059 0.311500842159148 0.0140855582687072 0.980513104444835 0.767453024531715 0.45873189258622 0.241160579975694 0.103866438975092 0.361998187324498 0.60734914488392 0.260320758752059 0.300328515579458 0.461838228290435 0.724342180469539 0.515987817526329 0.0958699828176759 0.595837335614487 0.817336424416862 0.0968886881275102 0.753691288172267 0.156658664257266 0.540834127764683 0.82212509940844 0.176597942546941 0.615944492444396 0.648916345911566 0.275947815913241 0.840272077962291 0.422585930656642 0.16170118547976 0.710245939348824 0.683503049425781 0.395033162934706 0.458659759184811 0.598653524657711 0.169219723392744 0.39425673171645 0.0794145311438478 0.991035751197487 0.854621240538545 0.420329971089959 0.0890757507854141 0.0474593183770776 0.335176232564263 0.374516705640126 0.568388331746683 0.526923471221235 0.734450301500037 0.389151920003351 0.567927127457224 0.884916753727011 0.874331923206337 0.3848550586286 0.192304687593132 0.127793008238077 0.869690081200097 0.880829208297655 0.697349476031959 0.545614129414316 0.2394080478861 0.100469644279219 0.546448694474529 0.248357886373997 0.356946395759005 0.600318468394689 0.433370345083531 0.16138891589595 0.528771425515879 0.85100585955428 0.907359354475047 0.742264108296949 0.274614154053852 0.427961614655796 0.994865040886216 0.307374580635224 0.256188702860381 0.0446857273182832 0.988651676818263 0.668203076233622 0.395479674544185 0.733281830293126 0.638998156501912 0.947738844265696 0.987440591030754 0.823939365094993 0.171497005117126 0.0862947523035109 0.801625279081054 0.258668303631712 0.0785532504017465 0.816865545252804 0.900405414057896 0.346885753138922 0.0188634810177609 0.0502841883688234 0.622604506423231 0.866862764426041 0.813916933999863 0.933071564952843 0.229705530523788 0.748839589923155 0.325538274066057 0.475681195056532 0.576668034708127 0.411540750779677 0.688859977910761 0.609202147179749 0.547994322825689 0.840734370453283 0.286614519250579 0.997218729064334 0.51785950987367 0.558522621265147 0.677415125651751 0.899949945819098 0.906835088664666 0.371303018543404 0.666250491396058 0.101174633372575 0.862962846055161 0.395933621928561 0.971427520595025 0.911595561464783 0.838205187015701 0.412225220324472 0.13044117490761 0.695479917444754 0.223107933350839 0.969186570418533 0.983354205028154 0.546255214270204 0.971173449163325 0.727898476559203 0.364349252847023 0.712638789874036 0.341097035920247 0.874299936627503 0.113050427499693 0.60564386139391 0.877377108715009 0.418398003072944 0.830231696267147 0.960633327336982 0.267625937939156 0.965590819935314 0.405509321053978 0.130612596038263 0.218844413908664 0.233902924607974 0.396149686521385 0.094860720958095 0.151213888796046 0.991152757180389 0.010496573029086 0.537618869794533 0.586061179670505 0.221349326372147 0.399945578495972 0.242026941911317 0.0716163501003757 0.109792432552204 0.222413417131174 0.177751608819235 0.864653119463474 0.735739035918377 0.889139984818175 0.0325675173406489 0.607980614334811 0.531585178149398 0.891299232288729 0.304615823323838 0.678747943181079 0.798284258344211 0.0281566803972237 0.0138438387657516 0.517148121574428 0.603622094506864 0.277669014667627 0.581263022965286 0.809150279588066 0.523835205286741 0.785283836168237 0.446151092078071 0.0505195003678091 0.776093870257027 0.85611839447869 0.386468075721059 0.59455887399381 0.287115661988501 0.164416344426572 0.114434571445454 0.772139404430054 0.560524688039441 0.700687651678454 0.458164499558043 0.755491611463949 0.127603537160903 0.936296836175024 0.158039881053846 0.218470321292989 0.82274204951711 0.980744709735736 0.914884440498427 0.102201753170229 0.609846733596642 0.0959172759042121 0.0436798337893561 0.345659322580323 0.552018872888293 0.759719437158201 0.448591911292169 0.319744043461978 0.791607631600928 0.571314539094456 0.708747444807086 0.161889825596008 0.397544548134319 0.204260683855973 0.42723375396803 0.284874466327019 0.0983923270204104 0.229882763079368 0.0387498488789424 0.781117819214705 0.901721544831526 0.21337037663674 0.861689534548204 0.389353625222575 0.165500771715306 0.136823101646733 0.660812650367152 0.244779636319727 0.172853082637303 0.721891916652676 0.864375545782968 0.870248560241889 0.10354410773376 0.37895816182252 0.54656437184196 0.05066271815449 0.822322582055349 0.0903811864810996 0.397223610740621 0.0986701021599583 0.765919716991484 0.527754712668247 0.120037394291721 0.581354113800917 0.716149256106 0.627401933588553 0.407864817753434 0.845753221390769 0.246570024038665 0.244587263679132 0.0830261731497012 0.819552937196568 0.315529699157923 0.426123431124724 0.632806825921871 0.338277753535658 0.798209257032722 0.722613508137874 0.45716646177927 0.544979540575296 0.966597771700472 0.64202176699182 0.102338011399843 0.385850413360167 0.291073950696737 0.630409648176283 0.408935238798149 0.285391420603264 0.656403128439561 0.229226936216 0.329418203274254 0.976457047017757 0.76925208974164 0.21233314746758 0.163079512929544 0.634999561924487 0.430055172417779 0.133735297869425 0.164781506229192 0.463920048873406 0.183998923806939 0.911974750026129 0.0692693879804574 0.933392252482008 0.268195202415809 0.0567776026343927 0.421540935402736 0.829214096216019 0.490114585952833 0.922097683828324 0.337121383240446 0.502907771083992 0.0481503865122795 0.76478747936897 0.104965567702893 0.969460458366666 0.0576928103202954 0.153907527583651 0.55835565067362 0.987406743837055 0.946529722819105 0.127092231805436 0.245084554261994 0.161063125275541 0.140121814601589 0.711941279429011 0.23722247451311 0.634324234563392 0.121483070375398 0.940544725714717 0.965507961029653 0.532426427085884 0.0681617163750343 0.182981885490008 0.408426713070367 0.0224318420607597 0.772403435406741 0.651318064092193 0.61507670807885 0.411121408019681 0.954894974878989 0.587094594947994 0.733053702129982 0.707489428513218 0.187303799472284 0.0286263786978088 0.325670186635107 0.907924528457224 0.554158348098863 0.484392524247523 0.838652564622462 0.932169316108339 0.170349329831079 0.989602608908899 0.2647097424604 0.891117532597855 0.411036305634771 0.366360474943649 0.98241972734686 0.260769111614209 0.421497783060186 0.476368090407923 0.0372347173700109 0.150221827481873 0.400873973912094 0.998517596826423 0.908539721907582 0.835411119512282 0.728131929556839 0.891934337222483 0.055173028842546 0.887968407131266 0.179680272815749 0.480450173623394 0.399759788771626 0.758581443661824 0.0546649048803374 0.550938724644948 0.234114316687919 0.388474353773054 0.605113577628508 0.541454130876809 0.497613980646711 0.736717347307131 0.798419917037245 0.728297641375102 0.5698631449393 0.914489089113194 0.188369740704075 0.850085034526419 0.176729421310592 0.0717961983964778 0.432975862461608 0.316664113183506 0.169385321803857 0.108905044423882 0.330647195866331 0.233865760485642 0.299773069487419 0.70262521560071 0.352847725364845 0.452219355385751 0.375676083990838 0.855714186502155 0.0808585939416662 0.764852105309255 0.853356529304292 0.0832664229697548 0.0281030842242762 0.555096536176279 0.849783576193731 0.163318805473391 0.368289167522453 0.766121078992728 0.943381766229868 0.709431195876095 0.0938902012398466 0.440618448203895 0.745984913213179 0.57721842081286 0.174784933328629 0.627191916455049 0.511610014333855 0.495265931938775 0.373296485275496 0.425877252323553 0.0266104296897538 0.901567451022565 0.417329139532521 0.486046282397583 0.966606766823679 0.238129682615399 0.812355541363359 0.912168661269825 0.242678310859483 0.593014966112096 0.135350486524403 0.143490215558559 0.930499828248285 0.335693405817728 0.877916173927952 0.122098922601435 0.970933683859184 0.890985265055206 0.770599153928924 0.261024058724288 0.352853481008206 0.472619398857933 0.215978711810894 0.310574266789481 0.202321697734296 0.955842363457195 0.242266683012713 0.188978432144504 0.240266226297244 0.0398869507922791 0.139074942367151 0.535253244822379 0.201312926383689 0.39980642584851 0.995916492510587 0.478860543067567 0.0113047630898654 0.399118830231018 0.0309971752204001 0.177987790734042 0.799111279754434 0.2053033833066 0.717086612069979 0.0275441912002862 0.0595617354870774 0.95300216160249 0.188480023164302 0.755509987340774 0.20671949562151 0.307265791599639 0.79097557967063 0.173493034574203 0.716142533505335 0.351972935572267 0.579349609925412 0.893116271840408 0.874463700470515 0.872253035765607 0.1419407705497 0.691281330280472 0.600219514202327 0.874715790273622 0.657485907175578 0.83365630452754 0.0768696311349049 0.959049182967283 0.81996437695343 0.402418056284077 0.498071642576251 0.451441649028566 0.177147863036953 0.281371860916261 0.948364176361356 0.253915172331035 0.317653656951152 0.42587042138679 0.43029093274381 0.0994295292207971 0.554277673396282 0.720706350009423 0.556658172914758 0.516414788300172 0.653809518907219 0.0484807475330308 0.472902656956576 0.363916830462404 0.383830022341572 0.969055762416683 0.260703791400883 0.281687049351167 0.262499167190399 0.0710304235317744 0.191287658957299 0.0410429723374546 0.737679289111402 0.285148157887161 0.810042820596136 0.209972320632078 0.177068845452741 0.330573292206973 0.180749234550167 0.980770082280505 0.153804037335794 0.295538811625447 0.996872839562129 0.69005186193157 0.198288870332763 0.471583865494467 0.222471671756357 0.914295542293694 0.72602356686024 0.92548856245121 0.159537908597849 0.913074067996349 0.09053683756385 0.939655993757769 0.765188806527294 0.669552989199292 0.878673092892859 0.877976084251422 0.659543649945408 0.301182532270905 0.686808081602212 0.714722052479629 0.469110840263311 0.548407606831752 0.487359754557256 0.360803377537522 0.410735087946523 0.214518995829858 0.374971311800182 0.309651358711999 0.790458816019818 0.0402805847045965 0.762082591836806 0.305915936259553 0.412564675584435 0.61002863382455 0.96704774776008 0.978749051387422 0.320607705523726 0.949414737785701 0.540357285274658 0.720148253371008 0.309146538309287 0.293824022219051 0.822543628725689 0.532565751688089 0.96057385773398 0.24121486535063 0.328992235185578 0.227578562139533 0.0986043308535591 0.736869978578761 0.574708123584278 0.795055673881434 0.88095821699826 0.356870156188961 0.855756232663989 0.550350216911174 0.146822835176717 0.0544201240758412 0.90131914952537 0.872847282777075 0.376964306002483 0.587917302506976 0.30118570651859 0.239511506785639 0.446176584253553 0.369442352505866 0.129298047202174 0.432492561526597 0.333651506626047 0.339500614765566 0.521487445167731 0.0878458059881814 0.315250055796932 0.724281122935936 0.409213297225069 0.200064397796523 0.846926656926516 0.365039371082094 0.0269923165114596 0.0667477763141505 0.811440597141627 0.563978296029381 0.0462965343543328 0.64629554171348 0.57833527678391 0.0723326361132786 0.587941196379252 0.324381941342726 0.189493545859586 0.748149833576754 0.794867594807874 0.433157189891208 0.92592576314928 0.0397234962834045 0.0443297210684978 0.448794905019458 0.785130464062095 0.700708677410148 0.318760085918475 0.387168406131677 0.104674121469725 0.367092245873064 0.997697471585125 0.916811961203348 0.917483511783648 0.0625588451232761 0.422382918719668 0.308663655736018 0.292803641848732 0.951274316313211 0.701636380627751 0.0472682526847348 0.746346948712599 0.896560505069792 0.618199469610117 0.410618366173003 0.0314398925309069 0.166605370033067 0.485161504247226 0.0243240161542781 0.604696100093424 0.903988404162228 0.955530581616331 0.258731434994843 0.921568070363719 0.0221328475675546 0.233189360827673 0.677838723715395 0.88741444662679 0.356343196958769 0.264568281101529 0.0228776628547348 0.700799349884037 0.0437940790457651 0.656804875342641 0.887706337498967 0.367653762013651 0.555868623808492 0.376302889918443 0.56931169598829 0.124918201067485 0.17807362473337 0.656136420639232 0.248469808627851 0.569330437672324 0.329764322126284 0.381371091636829 0.154020578607451 0.671412407527678 0.351619932076428 0.590737454576883 0.615738431422506 0.249582051325124 0.889798422812019 0.39979766122764 0.274454011402559 0.622051752137486 0.290439360935707 0.150780854427721 0.786977386167273 0.408731752717867 0.920166840662714 0.980609764447436 0.561557001285255 0.385836237696931 0.758588597993366 0.124677421783563 0.950669328814838 0.641717758842278 0.852171579024289 0.207918914302718 0.106935144942254 0.313121978004929 0.431486972030252 0.667568016247824 0.577422009005677 0.0237112054065801 0.980758161852136 0.561406614414882 0.112824444852304 0.44012658549007 0.394532676667441 0.140585645695683 0.401070843192283 0.0605447749397717 0.722627035628539 0.3425325712841 0.56254682995379 0.517696049832739 0.317552862658631 0.252943948197644 0.705255519952625 0.228711220889818 0.705107573410496 0.449375634451862 0.752504335287958 0.487615499205422 0.464538989139255 0.822563498257659 0.660018710652366 0.361306964983232 0.681017913140822 0.420892181964591 0.171055630482733 0.88266135543352 0.728575839255936 0.926714279374573 0.737353669523727 0.0924498285539448 0.286299049833324 0.837970729027875 0.591286180603784 0.589950168081559 0.622942044595256 0.810719752714504 0.869207105964888 0.561776154378895 0.359929876253009 0.387946062700357 0.871257445691153 0.857858803758863 0.753185159899294 0.890916559454054 0.922653719775844 0.404599598632194 0.283805880080909 0.630363946477883 0.749905223664828 0.0882278898893855 0.622366114221513 0.661452898499556 0.177590751149692 0.576074489115272 0.19845066729933 0.811237112905364 0.398421355283353 0.706298702075146 0.0223219991684891 0.23003218437545 0.259281881260686 0.376572260020766 0.360971837865654 0.188919108910486 0.156219519502483 0.638278784523718 0.154208659525029 0.0249265225254931 0.453556011701003 0.277921610192861 0.841239267152268 0.379449362764135 0.0408900835947134 0.565334981845226 0.553040623364504 0.40958205094561 0.489109740979038 0.0879724727850407 0.402654190945905 0.438640938918106 0.435075798914768 0.809936987522524 0.427895087993238 0.250579480808228 0.68895385667216 0.509852343886159 0.27094917910872 0.944860473298468 0.947806392745115 0.664320108313113 0.814626732754987 0.691609820083249 0.571363466442563 0.720720017645508 0.416234970984515 0.177348531917669 0.133178798151203 0.350169850171078 0.311742720478214 0.622658462179825 0.849743947079405 0.047628027186729 0.230845764041878 0.479591388991103 0.131221408031415 0.601098298369907 0.254966919689905 0.132464559229556 0.195763882498723 0.786575247179717 0.579866622288246 0.64389049761463 0.460464181269053 0.669310188870877 0.839335128373932 0.885108395214193 0.03750542138936 0.0907152569759637 0.119108313822653 0.702324735058937 0.74145810178481 0.904660183170345 0.658009244522546 0.442156162718311 0.155903261075728 0.114455251423642 0.590476689357311 0.970337708541192 0.998671775921248 0.205934718605131 0.582392939198762 0.540000632926822 0.258498318761121 0.795244853834156 0.719616788281128 0.0684931545332074 0.0305241099721752 0.0827725922269747 0.409228025402408 0.0529391115228646 0.430999633616302 0.06564068880165 0.795191527118441 0.702577640379313 0.847424130528234 0.939567357080523 0.265435493360274 0.619457638035528 0.374465996969957 0.762964798964094 0.116521094737109 0.637306381370872 0.629168444261886 0.210313266089652 0.330060578482226 0.169587948571425 0.0428450107970275 0.733726182095707 0.727985665912274 0.704723401388619 0.62926484517986 0.517463382156566 0.0909280150127597 0.536014833764639 0.110626907716505 0.833509829742834 0.646296631759033 0.312037896700203 0.63154253304936 0.636180836844724 0.401378032043576 0.966846732434351 0.0827890056069009 0.762171801773366 0.475419403410051 0.596570044457912 0.173381417274941 0.247119989015628 0.985736761088483 0.255480580779258 0.568731891792268 0.76129770164378 0.922010180992074 0.686241962560453 0.952349348326679 0.510857904108707 0.760844130439218 0.989750754374545 0.254423841200769 0.232966894262936 0.877774912875611 0.382900605800096 0.565477772741579 0.803704308741726 0.299939812112134 0.283639598460868 0.412289924866054 0.0971709933294915 0.169030159884132 0.804100315445103 0.376885197830852 0.802561887525953 0.110243917249609 0.433291954465676 0.322186904235277 0.504425935081672 0.188562469240278 0.17219099072041 0.789028924044687 0.624437825893983 0.248388141880278 0.544501351490617 0.145942681825254 0.120314621296711 0.802483832519501 0.896052364511415 0.977998899049126 0.721733792740852 0.922433399648871 0.378134270864539 0.976936268291902 0.971825155797414 0.78198659358779 0.362873075311072 0.18395428633783 0.486606477990281 0.126129193962552 0.787011603086721 0.790487837186083 0.495098699035589 0.282762313710991 0.162693593699951 0.932175194609445 0.987629401949234 0.0875570444157347 0.911277468469925 0.288339201586787 0.72278919494478 0.348345114837866 0.554506983114406 0.208925627728458 0.412807826737408 0.43858821865404 0.310123081053607 0.951119053165894 0.889329476871062 0.638226473862305 0.743925969295669 0.5600412264443 0.162924921466038 0.78718188668834 0.573094160740729 0.904967835561838 0.772635266820434 0.711461615129374 0.345486106066965 0.953732180483639 0.25094453335274 0.138548936264124 0.0650983283272944 0.17335509874858 0.216333343575243 0.944522381229326 0.588436500031967 0.995082733978052 0.815148914363235 0.112967716346029 0.801098183162976 0.828171886813361 0.919346689605154 0.380377510851249 0.968565596430562 0.512412494390737 0.987711014989764 0.694116308260709 0.960991030314472 0.059024387516547 0.779764992699493 0.625463792949449 0.056639877257403 0.559298049798235 0.637938114746939 0.963350684815086 0.231265493584797 0.904612829000689 0.0860688164480962 0.476345214203466 0.886658808332868 0.529352265819907 0.217391245116014 0.770689169010148 0.0253935631341301 0.260895474378485 0.367072298200801 0.0995371553720906 0.760051401322708 0.37506734137889 0.802697226512246 0.351261081888806 0.252029028870165 0.171690452820621 0.226368641080335 0.354203888401389 0.888653966952115 0.977626898703165 0.19661013471894 0.819346763228532 0.305090538968798 0.7591053143912 0.0624567800713703 0.329916413100436 0.213976782876998 0.945303159721661 0.173148323399946 0.0368544415291399 0.58919156345306 0.159737188701984 0.892881514891051 0.469114928683266 0.81013795029372 0.827118400314357 0.233976486201864 0.311806508312002 0.803582394672558 0.37313819747651 0.356932859739754 0.0520516913547181 0.869187032668851 0.140791964188684 0.82381195331458 0.852411772140767 0.788557132321876 0.477320473741274 0.543320690628607 0.78195553339785 0.423417618586682 0.78585206799442 0.421762643153779 0.360999572137371 0.936186115990859 0.347445076741278 0.89292993651703 0.591163622280583 0.146980951712467 0.781857887767255 0.371868396750651 0.527989475149661 0.0987919189571403 0.760234596973751 0.349059254643507 0.579910878967494 0.725140494427178 0.695680712640751 0.721426500163507 0.734698524165433 0.413498514774255 0.222458302159794 0.0108389552077278 0.13558365853969 0.727895409725606 0.446298307466786 0.932615158569533 0.0231220504222438 0.0640264389826916 0.951630413841922 0.20793995663058 0.0429696971178055 0.200413497735281 0.347953922636807 0.762176144898403 0.23629531113198 0.541633880056906 0.603755628198851 0.619561007730663 0.531850933744572 0.967628049380146 0.828140310067683 0.974592309156433 0.460362990051508 0.901178043140098 0.838681674993131 0.875586608280428 0.980877872318961 0.968233702569269 0.215569450762123 0.761960587410722 0.646383305247873 0.36679495963268 0.612708139130846 0.246054946281947 0.171005412782542 0.0401837824820541 0.966826243312098 0.357704201235902 0.928667711077724 0.232170850983821 0.585149429519661 0.928783838616218 0.559618281854782 0.210837607735302 0.792122355306055 0.0134941959939897 0.229185065696947 0.105866989505012 0.337975221753586 0.589841210779268 0.592388940204401 0.479046346161049 0.789935261309147 0.966814678779338 0.785203932072036 0.689295075044502 0.959863756790292 0.799845945793204 0.489543455329258 0.515159603497014 0.187516517862678 0.0956235647550784 0.0920678633614443 0.734944627131335 0.628174467703793 0.913763339365833 0.814558773981407 0.51335446432 0.298503370643593 0.101184725456405 0.791554709877819 0.750834899060428 0.566611195146106 0.383077340009622 0.109228876926936 0.647630274947733 0.121102568872739 0.611548762163147 0.280743601210415 0.415971946381032 0.602779252799228 0.971956708782818 0.0759097772208042 0.368745125117712 0.887335160276853 0.791950102753472 0.220295088435523 0.691002074854914 0.561106989728287 0.484398525836878 0.177436562143266 0.366336907693185 0.963001490600873 0.0946692269924097 0.905876652109437 0.848958649588749 0.442821397073567 0.877274186424911 0.0786808281438425 0.597410752635915 0.8801787871751 0.890640153498389 0.680692438078113 0.513197808016557 0.915174858230166 0.303802025371697 0.161003103619441 0.784553045795765 0.513188949581236 0.243627774419729 0.157168806728441 0.618658900645096 0.520370442136191 0.37532204991905 0.304364792448469 0.182200161246583 0.0127728403126821 0.399634401954245 0.636651808670722 0.531191162064206 0.469414099049754 0.9762275565858 0.592036287763622 0.580132559519261 0.786304652187973 0.383647706748452 0.25195838497486 0.633450820408762 0.461156363652553 0.662991099834908 0.0966840824973769 0.219329631701112 0.792544994940981 0.360937657365575 0.804506875697989 0.264903735762928 0.470123724236619 0.720824267629068 0.318572917098645 0.681989713530056 0.987216978408396 0.841971636004746 0.491621317956597 0.144201090068091 0.873600288042799 0.998608256161679 0.542550621735863 0.739765813325066 0.574158821071032 0.657646236764267 0.504109003127087 0.507491479248274 0.458608119515702 0.307953227018006 0.777342648478225 0.292179243979044 0.955838310765103 0.65624771892326 0.965900386187714 0.385236067927908 0.586719070221297 0.483484367397614 0.170723666318227 0.342029856750742 0.427566385206301 0.90197443516925 0.96219551820308 0.494678135535214 0.867865487164818 0.526198668377474 0.444744359825272 0.105704688890837 0.720412270517554 0.909210356932599 0.603281634948216 0.790474022950511 0.234472604910843 0.255895750063937 0.919350313793402 0.186618849330116 0.713597289356403 0.537048980656546 0.25268917119829 0.27675601473311 0.43374117862666 0.143428163176868 0.0847327191010118 0.373636687824037 0.52615797134582 0.41079586080974 0.572520291057881 0.754975320573431 0.795623603749555 0.954667073760647 0.872655502988491 0.314843489781488 0.0150081904348917 0.749071179309394 0.624961560165975 0.0285487471241504 0.576957941185683 0.323127441362012 0.722226197135169 0.786081973100081 0.67593462458346 0.845224609919824 0.3177395126177 0.952023284561001 0.0282464285567403 0.0780173923983239 0.581485765210819 0.0602308927616104 0.724977294392884 0.455769255957566 0.83106696159346 0.901317261941731 0.0739237215998582 0.621538143141661 0.44830140089849 0.632579083389137 0.269650690061972 0.612267307790462 0.372483069957234 0.307451150284614 0.440395058938302 0.0492659316165373 0.833303621890955 0.380442841898184 0.497844401386101 0.0406131650018506 0.151435882139485 0.804864757775795 0.350694964691065 0.533242026413791 0.0308719052677043 0.735428776084445 0.30023276905762 0.848772205929272 0.155701449133921 0.125118960766122 0.33043987238314 0.845949951217044 0.0578601782978512 0.335629909569398 0.869700786881149 0.0235042677843012 0.476299509508535 0.910035839970224 0.18456683892291 0.190209366718773 0.794459698102437 0.236051384569146 0.820334810805507 0.177088992048521 0.445807603257708 0.351014469743241 0.757898652865551 0.713914220849983 0.917273655079771 0.365641773957759 0.0372177770617418 0.8267693497031 0.828633921141736 0.0466804484440945 0.894270283866208 0.133873626010027 0.377725914306939 0.802477057594806 0.036009352884721 0.0410198167641647 0.449136742060073 0.894723962484859 0.283967070826329 0.831797092268243 0.674397311373614 0.874827595893294 0.318753184217494 0.809648361485451 0.85545978130307 0.791843687200453 0.916124568427913 0.985948598959949 0.988934235342313 0.369989272546954 0.44261919350829 0.186854065670632 0.293224130205344 0.953441777043045 0.888614375870675 0.0894827856426127 0.912695825877599 0.0913177559711039 0.616028383539524 0.16882450500736 0.134035425051115 0.592855862334836 0.250308717319276 0.193930001063272 0.371992670702748 0.393683840285521 0.079019510759972 0.813599665511865 0.759868786998559 0.660574189936742 0.682431224160828 0.455841912829783 0.288031101790257 0.430519006969407 0.527114240487572 0.29755926257465 0.512118244788144 0.618108976467047 0.780178335483652 0.976499718071427 0.797272139869165 0.152417619023472 0.0441190861887299 0.358261865912937 0.30724748740904 0.225572383434046 0.428282764111646 0.197894511951599 0.231702471387107 0.101311992942356 0.499063586795237 0.606798299618531 0.856992678549141 0.415813898765482 0.76926085136598 0.489007448651828 0.114831008957699 0.365191935047042 0.0854252479295246 0.819197987569496 0.358157923880499 0.299510487448424 0.133068362637423 0.449003609903157 0.748340680061374 0.549890353453811 0.835169274385553 0.160678080110811 0.757062628034037 0.439707121716347 0.576762205285486 0.123008458777331 0.651420970938634 0.383193298589904 0.29529391925782 0.364233576632105 0.6014978571143 0.288985525991302 0.384841219268274 0.901278003244661 0.949508120275568 0.882634074098896 0.856652066167444 0.227909455390181 0.933308182978071 0.135271800402552 0.514741924502887 0.719712729807943 0.874953154204413 0.619718379282858 0.887158865865786 0.536193817215972 0.0432248800317757 0.811056687200908 0.765124314278364 0.0628689519036561 0.216051017858554 0.106986812271643 0.247677006672602 0.535171265513636 0.661348829921335 0.803244849815965 0.612966296446975 0.334734632268082 0.37129947272595 0.604190145388711 0.740743081460241 0.0134808529051952 0.135664502624422 0.0785070900036953 0.167012279035989 0.194355780370533 0.0229414741997607 0.617896709169727 0.673245557118207 0.046908171614632 0.635825967662968 0.652374605899677 0.724411862017587 0.436581081750337 0.178545128789265 0.699126243137289 0.145201794528402 0.796389123448171 0.678977700765245 0.772000959424768 0.714149474531878 0.758606429423671 0.161872760355473 0.73494474791456 0.441558061016258 0.785063362065703 0.852771182449069 0.0467561156768352 0.360010731401853 0.547569456307683 0.697337223680224 0.516399416099303 0.0357049782364629 0.723099399458151 0.460053879041225 0.796159561790992 0.123193428835366 0.279989341781475 0.350460401594173 0.756773421822581 0.648456308885943 0.745838989790063 0.580108298917767 0.972294084220193 0.772777666784823 0.159974021094386 0.767587634439114 0.187883324760478 0.894453307101503 0.75575640033232 0.580873168599792 0.825447463977616 0.565101243716199 0.341526999997441 0.727156106440816 0.801136832181364 0.549705346054398 0.287648561724927 0.485530064806808 0.436236912487075 0.739447174270172 0.473284944852348 0.394212567238137 0.717847387338988 0.790731137474068 0.550882315651979 0.297388856115285 0.291914909661282 0.335184231225867 0.472774123321287 0.122267392149661 0.22264756440185 0.597883972090203 0.671676203852985 0.263402470583096 0.139693092009984 0.833979943869635 0.829172722199 0.472776839330327 0.374007618639152 0.156610783620272 0.727094266121276 0.0693040073569864 0.0943206606665626 0.504829848706722 0.580695758787915 0.379365171324462 0.775071303341538 0.982650374209043 0.0276947101484984 0.322347610003781 0.0529276862135157 0.500953784561716 0.289854967207648 0.987151230382733 0.343588228423614 0.0923509635659866 0.840996661828831 0.631837316495366 0.363072805816773 0.153739150236361 0.998725515005644 0.846450910244603 0.500294921982568 0.168284449556377 0.0247516360227019 0.689033490619622 0.150749754591379 0.749350794318598 0.140837758318521 0.6124727817229 0.399904671707191 0.724944872395135 0.0428684190008789 0.829608872267418 0.0130353462859057 0.0426281643402763 0.744549693407025 0.398514046496712 0.510384028183762 0.522148294216022 0.682759616000112 0.69062804147834 0.617465686856303 0.947542843518313 0.135204841778614 0.0141069979825988 0.578413152920548 0.765421815116424 0.720412012124434 0.0226926589128561 0.373541165119968 0.0330701147788204 0.109026843011379 0.175313310378697 0.653738086463418 0.685480122601148 0.138803404620849 0.921402625697665 0.465902597862296 0.54277620861074 0.33814661337994 0.223361064333003 0.159922796329483 0.0224722664081492 0.545210384977981 0.941759405264165 0.845368380220607 0.955149936280213 0.0841212763846852 0.922703042665962 0.132468728094827 0.05744535200065 0.167608906445093 0.652147880112752 0.512902306786273 0.707049046882894 0.0509577392484061 0.373076993573923 0.482358216189314 0.321366811494809 0.297867688301485 0.800327695216984 0.331800923452247 0.803114955986384 0.372943453888875 0.908833404704928 0.305546550040599 0.613549908541609 0.588108932930045 0.839588094316423 0.101451336676255 0.692903897084761 0.178322369025555 0.864174708866049 0.81630940143019 0.627811093677301 0.426843317353632 0.675113486514892 0.445506223987322 0.457420244622044 0.861865930841304 0.485836068876088 0.826518293472473 0.0249682125612162 0.843671436305158 0.189245618698187 0.764302395037375 0.207476180396043 0.86118943391135 0.542251997198909 0.577875654892996 0.252554327331018 0.0180887013487518 0.587337761544622 0.977860317586456 0.271599474607501 0.543117015075404 0.611921950518154 0.285411508190446 0.0175714660901576 0.320321844362188 0.0136550278472714 0.026994986650534 0.06926752229454 0.398271550892387 0.323255876572803 0.622947787330486 0.665741888219491 0.460109201446176 0.497428039021324 0.558560689417645 0.358329709896352 0.822570508294739 0.520501663428731 0.763515570699237 0.515874033505097 0.802977124808822 0.169071174087003 0.650128642527852 0.678055784308817 0.825479126700666 0.195734273320995 0.782261557290331 0.839131217708346 0.658387440310325 0.444536462391261 0.887351464859676 0.466197534131352 0.611009283890016 0.954259894378483 0.496619053496979 0.834557199631818 0.785665070668329 0.330477167891804 0.575670010528993 0.935326207659673 0.925046784898732 0.68588255409617 0.800941330241039 0.904176189806312 0.306421268838458 0.663326031025499 0.879848376826849 0.0258046608255245 0.751870560813695 0.338484018091112 0.506766879707575 0.43436610734323 0.733652351505589 0.479417202754412 0.418669095719233 0.802706781064626 0.27504438781878 0.408910701132845 0.472157676168717 0.900320583204739 0.446680298936553 0.995918859078083 0.622499129283242 0.264277167483233 0.968708303654566 0.628129614253994 0.620824015322141 0.66786019801395 0.45294032566715 0.857642024839297 0.937127708818298 0.0292907788651064 0.659016538353171 0.722395653924905 0.419712158902548 0.42849770154804 0.59767443532357 0.83107072500512 0.603950974780601 0.674369041644968 0.79552325778408 0.385005367819685 0.348560546701774 0.345011459111702 0.284888212794904 0.738344447400887 0.504242900782265 0.670151177339722 0.674315241707955 0.103642051173374 0.943184569175355 0.913573531755246 0.752690885670017 0.319348856655415 0.513129118089564 0.259031455223449 0.459417897737585 0.240118258087896 0.791806201988365 0.0259306808328256 0.651064204953145 0.318957215666305 0.279402918019332 0.236771118205506 0.829294435270131 0.699832384281326 0.966980304389726 0.280499644912779 0.861942644554656 0.0292039295029826 0.265730661975686 0.712882842060644 0.427730604291428 0.490039193017874 0.271188580910675 0.526412683804519 0.558641048986465 0.981051804542076 0.961240318131167 0.101188157175202 0.30453568181023 0.715144557270687 0.227487845178694 0.75597925275797 0.901718938311096 0.452720732775051 0.625783411639277 0.972144288357813 0.1640646886779 0.0634380981326103 0.647861097913701 0.811405666817445 0.40082145902561 0.694129599025473 0.950090283663012 0.294885630006902 0.866320624081418 0.577442705580033 0.035798336523585 0.650847323921043 0.515469333867077 0.283548658143263 0.396121065276675 0.144717236203142 0.0213910477119498 0.992215920859016 0.287826000580098 0.538570724355523 0.861939275762998 0.622325467900373 0.979301380626857 0.542802969932091 0.0885065831197426 0.417729462622665 0.153794743942563 0.523481903751381 0.329764842139557 0.397548253689893 0.892008305422496 0.875079564221669 0.464070107047446 0.798834480331279 0.808029565468896 0.299521548103075 0.791363706651609 0.294253972235601 0.978361076076981 0.627859064671211 0.110072923239786 0.206088957630564 0.107929639439099 0.792947988170199 0.414274676996283 0.436685492855031 0.585147222920787 0.582965678959154 0.767323358899448 0.124181246832013 0.517175098876469 0.884235620012041 0.193179993710946 0.234178693916183 0.657480143464636 0.0574803547025658 0.879729298858438 0.845474483903963 0.703593867789023 0.590410395963118 0.601137069324031 0.227428871616721 0.898033696217462 0.249267339799553 0.170339284539223 0.126471440605819 0.0487582004303113 0.0957781230262481 0.925573971634731 0.662860241122544 0.919068725684192 0.659247686327435 0.829723504306748 0.911571108624339 0.401755944313481 0.0359110676101409 0.538228387816343 0.0916369164222851 0.362657226468436 0.696222875805106 0.414694293362554 0.983264658097178 0.348271227774676 0.202190870831255 0.226278461881448 0.718680616177153 0.560560120628215 0.841278823888861 0.577677802750841 0.316662374043372 0.900801847651601 0.580456373121124 0.362677799954545 0.521127021801658 0.741613024249673 0.649222701266408 0.833324625955429 0.404675822297577 0.627355163972825 0.327776142195798 0.07703212905908 0.096350202166941 0.359114887756296 0.990713052996434 0.0305279141827486 0.0975549853290431 0.832880515258294 0.287465448132716 0.109128160774708 0.680959460053127 0.17635398671031 0.648406788916327 0.245702362300362 0.0578634410584346 0.743249857304618 0.854157239564229 0.39975213609403 0.874284470612183 0.765572130531073 0.765872153525706 0.938325998038053 0.4394389032037 0.804469781417865 0.50760341348825 0.140309834897053 0.344441160140559 0.1029284505127 0.746204482594039 0.218991133947857 0.277449799107853 0.143687748454977 0.19044554771157 0.418905136336107 0.150001590335742 0.529385264073499 0.36145522800507 0.882725305771455 0.69344039081363 0.976191783084068 0.701605764846317 0.667667247965001 0.139965768668335 0.758656249968335 0.405624777830672 0.660891194038559 0.691905161805917 0.322796304009389 0.384438892882317 0.582623514835723 0.034255972316023 0.849392558252439 0.0592289841570891 0.532439547509421 0.819188016729895 0.958622300014831 0.84917978315847 0.93572510993341 0.39274930866668 0.945130461147055 0.537379181708675 0.822111420708243 0.956579362410121 0.0608767990348861 0.551355792577378 0.153709116934333 0.847794353009667 0.933764806494582 0.413635638309643 0.941665851741563 0.376982641541399 0.298363313965965 0.949904513531365 0.619557528528385 0.156498894558754 0.430579277798533 0.385630516665988 0.575561745655723 0.610923690304626 0.408669760497287 0.538298700940795 0.0840051744319499 0.535267115070019 0.922700580439996 0.778959227984306 0.173763866522349 0.08329405259341 0.275766003506724 0.594671131859068 0.840951610608026 0.595338051416911 0.311621462879702 0.0115605554520153 0.407011004134547 0.102671846782323 0.083649934141431 0.35410543555161 0.127793151380029 0.0562721953727305 0.549669511239044 0.352517898648512 0.807079375365283 0.985575797387864 0.43448221459752 0.557768393184524 0.991246372938622 0.733892029218841 0.630036941110157 0.772092789020389 0.0728915581805631 0.847742621139623 0.379585541470442 0.206697910460643 0.177322443202138 0.487811127922032 0.517442026345525 0.125051209675148 0.688378314694855 0.912072045984678 0.162714379478712 0.589602637402713 0.351640026117675 0.111903417443391 0.295659069765825 0.688362930507865 0.614387328603771 0.547829113733023 0.610172357333358 0.365126824129838 0.771110023865476 0.0424495079717599 0.937902909154072 0.619785047704354 0.50402500461787 0.774898420134559 0.562615582346916 0.746158298223745 0.0979089239728637 0.603391059709247 0.283472323145252 0.232798186375294 0.985560357649811 0.0429158607614227 0.93728384533897 0.507368228496052 0.0114206767221913 0.216835218158085 0.218964459525887 0.592318598497659 0.56558998565888 0.899859106922522 0.478478414218407 0.853698891890235 0.262832318441942 0.940943628679961 0.324280319316313 0.786770512394141 0.208563931758981 0.821098076882772 0.474198160998058 0.541512135867961 0.749503533695824 0.230711700886022 0.546820981334895 0.406803801204078 0.751529128765687 0.548883256472182 0.445667250845581 0.184799362074118 0.93530429841252 0.808044428720605 0.454619250984397 0.165119489040226 0.384025722052902 0.28235006442992 0.495699438836891 0.29094199502375 0.0820459299208596 0.389587515252642 0.307829213072546 0.165584026162978 0.960910766634624 0.306807970162481 0.600901345647871 0.246815664155874 0.717249649830628 0.781816994808614 0.200099349787924 0.810340079867747 0.456847315619234 0.110002509155311 0.78531858024653 0.762436291680206 0.0613141461019404 0.850800308403559 0.760277471791487 0.51413162576966 0.115842879873235 0.842214376633056 0.442930336396676 0.503836235881317 0.175994292423129 0.391662349770777 0.392320324685425 0.647089987611398 0.0608160814922303 0.85391250785673 0.708578448100016 0.4710544924438 0.89574014079757 0.0452384587842971 0.984765385976061 0.977977045814041 0.218340750627685 0.399298984403722 0.759483814211562 0.481286261612549 0.368447546369862 0.326588823273778 0.889005469647236 0.755639773756266 0.26035930842394 0.340289376245346 0.565928574691061 0.24982074018335 0.335701348697767 0.149034841174725 0.708526637628675 0.142212115826551 0.392495863048825 0.638285492602736 0.0596186502021737 0.863856454750057 0.149764806579333 0.0926736601535231 0.370904726870358 0.0160368836415 0.35385906658601 0.148068107687868 0.490647068249527 0.813519942590501 0.934327601462137 0.915820984863676 0.584342074799351 0.317069088502321 0.022670773176942 0.394694245436694 0.573074817445595 0.814692643745802 0.821799661456607 0.270691725746729 0.378524946740363 0.103954597590491 0.934306464397814 0.0364823293895461 0.103371007854585 0.56931492486503 0.188775646791328 0.641683814607095 0.265132321934216 0.646426578373648 0.720674513026606 0.0698397600208409 0.148522908622399 0.0725755447777919 0.84329820438521 0.583580041218083 0.275506613233592 0.661001917219255 0.674591591190547 0.795466438266449 0.964099983142223 0.98054878551513 0.98121640994912 0.855302064919379 0.401938269357197 0.938719852310605 0.93754231729079 0.0513549669226632 0.260820675217547 0.615877395058051 0.924804013383109 0.257965896164533 0.840707856691442 0.169193761914503 0.959438446785789 0.244203924923204 0.339431810278911 0.226137052385602 0.650558488818351 0.865124588713515 0.620622420052532 0.687482066978701 0.682028294780757 0.715984979856294 0.294504860660527 0.481919774005655 0.772456674301065 0.2865127921151 0.271904030891601 0.677898777641822 0.701571250578854 0.160114715571981 0.334846672769636 0.948929498095531 0.431286763462704 0.535491645091679 0.566296451580711 0.41463829604676 0.697421469287947 0.095833905513864 0.153599576922134 0.262046804970596 0.42689115304267 0.582915372285061 0.97173147480702 0.896216868727934 0.557299888425041 0.416460335655138 0.890687330642249 0.100502136119176 0.269150603255257 0.453830836641137 0.685552274442743 0.103365789051168 0.0891612175945193 0.224259193870239 0.383089377994183 0.583413973043207 0.701412844071165 0.399246679504868 0.778173354698811 0.810626071954612 0.354486094717868 0.949032244051341 0.109421833199449 0.933439182757866 0.635757257221267 0.142293423912488 0.739055085184518 0.675057594538666 0.08882917920826 0.212400928984862 0.508662942836527 0.117819453780539 0.07414932184387 0.166595354937017 0.66196336229099 0.2553367537749 0.851901703199837 0.144837422887795 0.402323610025924 0.781482905412558 0.554757756057661 0.480436180979013 0.760461401361972 0.48217695744941 0.937518749118317 0.333619081862271 0.319110820579808 0.97736642714357 0.528247156708967 0.761000339107122 0.810512328732293 0.198486714407336 0.497644715136848 0.407658855156042 0.193052808975335 0.634131836106535 0.193478719438426 0.15556614080444 0.066258096457459 0.95824964965228 0.914357458679006 0.147277366654016 0.777819629730657 0.184767988862004 0.337020988177974 0.444060765728354 0.0514955175668001 0.45315583958989 0.684686731251422 0.432361070315819 0.399705690103583 0.831568450545892 0.488560190214775 0.0687292573857121 0.542319831270725 0.908997330821585 0.496964833971579 0.574465317493305 0.653992438646965 0.368360880487598 0.80036577996565 0.162166793977376 0.665604714665096 0.0700485690915957 0.626573296356946 0.958242878185119 0.613256691358984 0.730122110247612 0.630972134040203 0.60865324182203 0.0400956759601831 0.869880957880523 0.130686504307669 0.286934182427358 0.680665583403315 0.0985883007990196 0.143432093933225 0.424979054096621 0.33551476304885 0.426854450386018 0.119832987815607 0.723283006094862 0.796944501772523 0.339389439339284 0.377349265420344 0.0930712374998257 0.940781994909048 0.910380941845942 0.708217850704677 0.193026389719453 0.16783314718632 0.571932238105219 0.0843980894074775 0.832938973186538 0.963927454447839 0.572491966008674 0.685960719052237 0.444470097771846 0.756942439735867 0.259827081293333 0.0621585365547799 0.691520465391222 0.913476851929445 0.730925803438295 0.648165659960359 0.0362412626692094 0.284884512771387 0.308901767416392 0.645912388742436 0.790592936801259 0.532590899262577 0.825621994815301 0.128292829506099 0.0176881816401146 0.337670426438563 0.0300497633614577 0.389368359623477 0.991952926220838 0.433609305243008 0.573200462656096 0.566184254337568 0.387126892891247 0.896401113625616 0.788042102048639 0.88151635259157 0.439587199878879 0.746698263778817 0.942513375873677 0.467264009437058 0.919934663956519 0.295069145595189 0.778141526705585 0.0182753165019676 0.722739649619907 0.323458801149391 0.212596013946459 0.582214624895714 0.780168358189985 0.583861500015482 0.0638536180113442 0.108106207917444 0.338503956312779 0.81401743601542 0.591543508572504 0.0106269041216001 0.303434321819805 0.406758994085249 0.852905080795754 0.317772125471383 0.112403487192933 0.507414112752303 0.397732582259923 0.709498958031181 0.347737568533048 0.880715330231469 0.466398188720923 0.45390919360565 0.281922132922336 0.85434153471142 0.851787861322518 0.866201155642047 0.825307144988328 0.943848825509194 0.51892667299835 0.0965516010485589 0.858494661282748 0.893603152246214 0.229338226432446 0.892827506810427 0.740724103511311 0.355375967430882 0.364740781581495 0.961909229229204 0.319593959471677 0.762740585652646 0.879952224814333 0.161818387389649 0.650866790304426 0.910238422250841 0.39174334483454 0.504666832152288 0.0753412443585694 0.980366070922464 0.701939793850761 0.725865891966969 0.107040941135492 0.500053289378993 0.0218979887361638 0.271983684431762 0.0682630228437483 0.119930433370173 0.75681222573854 0.539090207933914 0.134578223479912 0.341281148279086 0.727114914520644 0.0796674235560931 0.980990529414266 0.996911626420915 0.979490017746575 0.124113334389403 0.431675088214688 0.267364838721696 0.144935123608448 0.872434728541411 0.636233922454994 0.105379763806704 0.127987640032079 0.65517892176751 0.34951894845115 0.199112194715999 0.2639362457674 0.568542392363306 0.957416301183402 0.488470791957807 0.360418542590924 0.808338277249131 0.563864520075731 0.377890684984159 0.935935116002802 0.176396230873652 0.684681525586639 0.172363328558858 0.693952026248444 0.732570744412951 0.683528946132865 0.114571685299743 0.692349613416009 0.113072165253106 0.675569273999427 0.456588425766677 0.745954342840705 0.293176482375711 0.297810445812065 0.377821452224161 0.0295280858618207 0.122486237753183 0.102382614985108 0.527355690302793 0.260264076152816 0.611753229722381 0.415991806923412 0.633626900913659 0.491404408342205 0.537640591873787 0.851892239926383 0.610210326600354 0.852488016551361 0.69110818545334 0.0472642958816141 0.803522203366738 0.713554645041004 0.106247077947482 0.469086207400542 0.192378516800236 0.364714962784201 0.156514879665338 0.709543912210502 0.541545615640935 0.697714568222873 0.780512187001295 0.61626240956597 0.371193486829288 0.726882982146926 0.574891047012061 0.680377824055031 0.495120578086935 0.554723530379124 0.597223668640945 0.783231993566733 0.70853389384225 0.77494099161122 0.27711364187533 0.742178403609432 0.640621907857712 0.90387734352611 0.182268584021367 0.388070077106822 0.640184290411416 0.783758692790288 0.906504811316263 0.562641248090658 0.186197504657321 0.569809649265371 0.462179760837462 0.214619311830029 0.898865069972817 0.924780983664095 0.825769867135677 0.117498521918897 0.581323711234145 0.671343467736151 0.250397370823193 0.425838883826509 0.296081637714524 0.53501892559696 0.321910043037497 0.207060009348206 0.171201556671876 0.0748294814559631 0.902772225195076 0.991638939625118 0.252321184589528 0.326996535577346 0.0915059041953646 0.507509534265846 0.837081618125085 0.794256114058662 0.708683143183589 0.684691930462141 0.71391648392193 0.540358786305878 0.39976212560432 0.160066141122952 0.334257909869775 0.951163895090576 0.495486572463997 0.0545052531990223 0.413013906890992 0.598460747485515 0.552748957693111 0.899805648128968 0.182447608963121 0.926630065576173 0.527398385559209 0.934981698405463 0.0880694716260768 0.584072681646794 0.53060846690787 0.826446396796964 0.970755899020005 0.833404437850695 0.350276840596925 0.641878338756505 0.836120706205256 0.453862404627725 0.207288322374225 0.612995808583219 0.426141490521841 0.854917838959955 0.41139090097975 0.928435827109497 0.963062523931731 0.878748420134652 0.759980326388031 0.638669430895243 0.784523481796496 0.584869817276485 0.765236453434918 0.923311281399801 0.777331375761423 0.209573517013341 0.847527146863285 0.347176110709552 0.112420972869731 0.976931114720646 0.0238565670954995 0.653715643833857 0.57223678563023 0.80924739160575 0.508590113087557 0.441272680452094 0.0323883308167569 0.399492503562942 0.992054524275009 0.490027190761175 0.0448299535526894 0.751830646337476 0.631118397454265 0.953562306484673 0.630727467795368 0.312459018246736 0.318560079040471 0.708724084317219 0.909559104433283 0.977284451983869 0.578953273834195 0.798304017235059 0.629409977979958 0.941584798130207 0.753590742130764 0.886782207298093 0.693106009832118 0.5972585766064 0.896426467269193 0.934163839924149 0.936836850596592 0.136980429633986 0.660033305599354 0.609559768098407 0.462431107270531 0.884243037577253 0.848920523119159 0.0958674567425623 0.810459110122174 0.142130467749666 0.675915942830034 0.047297266474925 0.228815907214303 0.57016233028844 0.341593104840722 0.882530180241447 0.121074299144093 0.324388834284619 0.761844433364458 0.66392516215099 0.343876361416187 0.856584681344684 0.975420251653995 0.632304455759004 0.201954031523783 0.256810297360644 0.156151170949452 0.545576803940348 0.796392363850027 0.56431936618872 0.0321128116035834 0.160696258677635 0.105007304069586 0.808002431886271 0.273718714939896 0.352109201869462 0.821809078399092 0.337573952451348 0.287233173002023 0.71356411937857 0.866472378061153 0.844468758872244 0.362508359299973 0.823133406988345 0.39319958968088 0.601190787202213 0.193558492148295 0.287353036983404 0.941275473905262 0.808056832742877 0.345853169974871 0.169881610854063 0.0505224673938938 0.435389061041642 0.904075808343478 0.0395243708463386 0.665939160648268 0.551215021803509 0.29655088538304 0.487791023738682 0.436660353117622 0.985616353582591 0.752871199811343 0.323359666934703 0.323557771015912 0.36562394506298 0.661768052359112 0.187536156661809 0.0494188291183673 0.369939328222536 0.498468914506957 0.473527867577504 0.778693559519015 0.228249218140263 0.8809808449517 0.571574141890742 0.540828365667257 0.212591712311842 0.32568161240546 0.0410214920551516 0.571254169379827 0.853272648120765 0.946769924233668 0.780144490364473 0.138372297482565 0.0681501700519584 0.129638269573916 0.161318230049219 0.359411185602658 0.810629505517427 0.173746710924897 0.241062236153521 0.805184768550098 0.925267690732144 0.643727171265055 0.347026171935722 0.58865645919228 0.323452163604088 0.105817570034415 0.321123354695737 0.0105241418001242 0.0706466463604011 0.503462648526765 0.608103245035745 0.118234358679038 0.540299203756731 0.999121893278789 0.703360007724259 0.721400803762954 0.611052465967368 0.837241603804287 0.31329438614659 0.0798911369079724 0.0400875641219318 0.14001591675682 0.570430393442512 0.07230552097084 0.833534141515847 0.192457518940791 0.539245169584174 0.980971230375581 0.947971484742593 0.0522013825690374 0.90224853287451 0.39073011649074 0.524416734101251 0.186162871450651 0.196645297389478 0.940449525252916 0.634826076184399 0.984269915670156 0.554986318717711 0.755845411345363 0.348136600810103 0.640913558085449 0.531168414249551 0.729243349360768 0.816487209319603 0.40792877500644 0.196143500946928 0.225189536339603 0.358573518211488 0.442360810069367 0.0549860596377403 0.768418497170787 0.0399336839886382 0.553433385516983 0.530083985116798 0.149370354614221 0.63816933440743 0.856978688670788 0.927592491665855 0.709485820550472 0.662144472587388 0.860601500819903 0.7523002499016 0.544549391404726 0.983184431067202 0.37719501740532 0.645832053606864 0.45759619765915 0.838909781258553 0.585667328163981 0.945072350355331 0.0451668264949694 0.0337176569271833 0.273825784197543 0.839320108150132 0.468490105536766 0.0434767349530011 0.335129332945216 0.55501122772228 0.992377883556765 0.657422827905975 0.574308432762045 0.943264210959896 0.106133032767102 0.58055017558625 0.246473291888833 0.681797694941051 0.578546551077161 0.0101184286433272 0.964633380533196 0.633537129934411 0.194117299655918 0.22712230719626 0.750318643206265 0.424362835141364 0.386594686044846 0.236983269099146 0.0424083941918798 0.999041568976827 0.337637564872857 0.584327581734396 0.733641479862854 0.702053467461374 0.196470953028183 0.803990059953649 0.359349492804613 0.520159012484364 0.998892413680442 0.916736991701182 0.629237913978286 0.337506075045094 0.223283217009157 0.27059146621963 0.663294360234868 0.0125119538488798 0.692633363867644 0.425544067188166 0.79793346767081 0.512098889506888 0.685943672712892 0.428194336269517 0.790173509907909 0.385559067626018 0.872800848542247 0.750990347531624 0.15769438294461 0.194963554642163 0.466806557725649 0.895251176189631 0.0362907180981711 0.230824756519869 0.4378627669462 0.965335182240233 0.931756966789253 0.212152367942035 0.32373289286159 0.732701184072066 0.0365851675462909 0.348352894752752 0.440828811321408 0.257184082947206 0.346426026369445 0.320968586206436 0.125934012650978 0.699592609987594 0.0452495853626169 0.785856990371831 0.78278810899239 0.265652426485904 0.54523709674133 0.623103574640118 0.870922547231894 0.314839261677116 0.694692741821054 0.280217405864969 0.489263286883943 0.222960418078583 0.445826901374385 0.165845150505193 0.39541446773801 0.138851797434036 0.389098776536994 0.475138061938342 0.214674758936744 0.559166058858391 0.3279122217861 0.564739387317095 0.0466139660379849 0.764555389562156 0.297379242554307 0.983796742546838 0.229300773260184 0.61220195046626 0.686156647421885 0.802697329777293 0.77935427879449 0.406409117584117 0.506021222856361 0.0913027689396404 0.765831644353457 0.760796146537177 0.431188093018718 0.714523983204272 0.847694608655293 0.628084345438983 0.0850481781456619 0.150846099266782 0.463780511056539 0.230890103010461 0.407832351499237 0.296230730775278 0.966385227800347 0.588068477003835 0.648441830573138 0.794697331951465 0.13500392165035 0.336596679245122 0.774912111051381 0.146344460768159 0.958600202908274 0.775144762822892 0.262160243238322 0.462611955024768 0.0253402645397 0.353488932386972 0.795498733948916 0.0378491895785555 0.492805051645264 0.336244280587416 0.690697097904049 0.574250943635125 0.901096762022935 0.691720488865394 0.44151668215869 0.180250246087089 0.245472647359129 0.445783070893958 0.281258982999716 0.664750530167948 0.0656867129728198 0.571470741077792 0.249258100804873 0.881242433986627 0.169060283312574 0.234965836808551 0.252985994589981 0.23039526128443 0.514957467699423 0.326770500375424 0.347152411611751 0.822417511215899 0.865518867571373 0.114928949861787 0.794463820636738 0.286013299082406 0.347930506365374 0.698503744145855 0.594029954571743 0.124332881872542 0.159365623544436 0.951484590917826 0.525645918701775 0.259485624351073 0.697321369498968 0.741406095386483 0.427590894980822 0.722261047244538 0.388179075438529 0.652412685116287 0.991020352949854 0.959328782302327 0.191411089501344 0.0561279221158475 0.683633997573052 0.925538827634882 0.505545570910908 0.403399169889744 0.256121781116817 0.449249180639163 0.608104028743692 0.282495487432461 0.0431980189029127 0.732900505897123 0.345783854925539 0.939756632000208 0.960554880015552 0.152167250150815 0.704683219990693 0.862668719310313 0.621362581728026 0.577107257603202 0.1315654316172 0.462393781105056 0.343796119634062 0.589938230826519 0.496237535018008 0.787770110673737 0.943032752729487 0.169201887352392 0.749044467776548 0.890645068499725 0.21788783197524 0.0913843536283821 0.640525977856014 0.791601603964809 0.320876864485908 0.679821819455829 0.159599156295881 0.488669379863422 0.069195892540738 0.845314390349667 0.395570258044172 0.448982965191826 0.881524283254985 0.0529693340673111 0.301705887597054 0.552420485869516 0.87001364332391 0.329101195945404 0.165509811786469 0.432661153010558 0.370846533558797 0.652847640030086 0.438063601097092 0.298489208579995 0.0762864565337077 0.718319424316287 0.709082269505598 0.682688138838857 0.0800303476420231 0.837061719780322 0.923500193047803 0.439187398415525 0.658713232313748 0.0626420371048152 0.757471554623917 0.818299840975087 0.263689795434475 0.965130730355158 0.151492140153423 0.0261022522510029 0.361530569538008 0.306634473588783 0.737905092888977 0.754137740312144 0.824923282992095 0.712634336338378 0.988642538092099 0.725289992250036 0.092578999067191 0.796209130627103 0.264297628253698 0.26435090633342 0.24720416754717 0.219881101627834 0.174581242331769 0.709334343634546 0.132524483152665 0.820499066771008 0.920257078639697 0.182402669305447 0.766069893643726 0.783792833182961 0.854689006842673 0.384935901099816 0.61501998929074 0.0747527831862681 0.690877735670656 0.808341030369047 0.78366027451586 0.37864384676097 0.129001365799922 0.803492296610493 0.55812157001812 0.159020849212538 0.667385797235183 0.838035540522542 0.967405737712979 0.978875279307831 0.413839824886527 0.807296929003205 0.254976103594527 0.85514651756268 0.0109876817697659 0.562000464731827 0.915707370722666 0.852589015299454 0.540271779510658 0.932501595139038 0.474433422056027 0.313018410769291 0.559962252655532 0.948588113300502 0.04538800339913 0.33908014577115 0.88239231310552 0.677366907328833 0.0797419002442621 0.630440550241619 0.376921280205715 0.414708182741888 0.73909168019658 0.0477325309533626 0.0458840038604103 0.12101223569829 0.584375433097594 0.881949171670713 0.292023423477076 0.941982340901159 0.712154072502162 0.616929874492343 0.430368388674688 0.177455924570095 0.822453632084653 0.332032280261628 0.640593636976555 0.91508225990925 0.489583679139614 0.294053142233752 0.704834754301701 0.262435019081458 0.42378378123045 0.531740152016282 0.192071405397728 0.699788483036682 0.16982322899159 0.926652632907499 0.924557158979587 0.137348268721253 0.417949801420327 0.699326248862781 0.52324198562419 0.660630644108169 0.929249988794327 0.548202511384152 0.606818674642127 0.563130426143762 0.794520945569966 0.479132123917807 0.529569346697535 0.611207212558947 0.471683260637801 0.553040884984657 0.060861403553281 0.816364135593176 0.256780675044283 0.558043883584905 0.100307108322158 0.944745801612735 0.680983585810754 0.472420056287665 0.678571327219252 0.400735119304154 0.108494404049125 0.563036079462618 0.0912076270254329 0.467282066759653 0.0315228106756695 0.495970007781871 0.494607774927281 0.284969499905128 0.492353434178513 0.619189189481549 0.287922112678643 0.354859392100479 0.906894620733801 0.112924247293267 0.440644389628433 0.798238220342901 0.567336468906142 0.758178127959836 0.42863960662391 0.621005347131286 0.540566767181735 0.120349779818207 0.38327556326054 0.829339867972303 0.0586459204275161 0.690783726444934 0.841147581159603 0.946679312151391 0.894187515778467 0.697000423115678 0.629965185271576 0.246996087555308 0.262279162390623 0.979031882365234 0.253912558895536 0.938376971555408 0.0603708480182104 0.20861625878606 0.140483257940505 0.469904423160478 0.503388628694229 0.921371821134817 0.730088473272044 0.739533179763239 0.104976858398877 0.588671763855964 0.943990350717213 0.503688866978045 0.196643383298069 0.374674471351318 0.265971276450437 0.0195600496302359 0.137485992715228 0.343640653183684 0.614358302135952 0.398775135572068 0.669329966201913 0.445970070755575 0.34984139286913 0.539766635252163 0.012479620364029 0.528403838367667 0.57768925572047 0.845485553087201 0.705848783871625 0.35352697287919 0.334206594286952 0.781612161903177 0.758216666798107 0.46588541621808 0.578503113833722 0.946768277755473 0.683866121263709 0.729603185637388 0.800525769793894 0.183412010918837 0.461004338371567 0.882782789135817 0.844770310097374 0.582710056707729 0.422935030825902 0.179715454848483 0.777272399894428 0.283154248590581 0.0123430843790993 0.600376342460513 0.389380003449041 0.0861202571936883 0.127159423928242 0.431559036050458 0.185499682803638 0.121450994131155 0.444210083298385 0.584332927083597 0.70079540529754 0.485361989648081 0.995577365255449 0.35096369584091 0.262652230192907 0.620236849572975 0.733862433871254 0.306659519511741 0.187399097436573 0.316780883132014 0.0759908861527219 0.381807175320573 0.14009072398534 0.274764127633534 0.377901780675165 0.585911707894411 0.439325539388228 0.803306478303857 0.314801607045811 0.80222045985749 0.324411198773887 0.0885325014940463 0.0768297675997019 0.302827497217804 0.344263475569896 0.87611080609262 0.835697873178869 0.538651389339939 0.901476599217858 0.567660359495785 0.276129852368031 0.163051046351902 0.769437862869818 0.622313230070285 0.131099510097411 0.658302897815593 0.466386639401317 0.5334118750575 0.550633701593615 0.543628630687017 0.680383366022725 0.155230723023415 0.639947356597986 0.285857866976876 0.457326856139116 0.328405668050982 0.846960308654234 0.874642396946438 0.0623637431045063 0.465194039901253 0.315713415283244 0.23656080695102 0.920767454148736 0.564111972632818 0.104625020092353 0.496591592831537 0.661072032572702 0.818023106323089 0.13444857513532 0.0505670188856311 0.0447502389294095 0.571125063637737 0.546563854825217 0.153921465598978 0.0140009371726774 0.347329305559397 0.560072585365269 0.811208481057547 0.960946591768879 0.638197414432652 0.257364621367306 0.296639393439982 0.684037963522133 0.359643718665466 0.28464487309102 0.812868316401728 0.623421799021307 0.579723013339099 0.957708533429541 0.126122308396734 0.376439520639833 0.510240812010597 0.107625623682979 0.429249452881049 0.317929460373707 0.727778314307798 0.27994473035913 0.408055076918099 0.905547750398982 0.444483028722461 0.57819618153153 0.994627742187586 0.561023054607213 0.233789752570447 0.810661705310922 0.329848968808074 0.701910570303444 0.13691452256171 0.54751365146134 0.588381700406317 0.290351702279877 0.841546119931154 0.0905944304168224 0.591760442620143 0.416536093475297 0.748912900038995 0.960550435238984 0.848254633215256 0.881271248161793 0.766330975112505 0.84468201387208 0.662828964721412 0.695636545626912 0.14022157439962 0.102051162996795 0.817236431580968 0.386774912364781 0.432672924303915 0.752198844547384 0.909093629857525 0.608408416991588 0.989158328562044 0.553905606665648 0.8888860341697 0.963320238683373 0.124879512402695 0.8748561871727 0.543705347166397 0.150124929600861 0.663487329646014 0.188596792882308 0.112977426026482 0.841634655187372 0.765206084521487 0.612406832929701 0.982413447771687 0.350809459581506 0.208513057127129 0.740326701807789 0.0607388572162017 0.193745305072516 0.502259513225872 0.965178481680341 0.0129722167667933 0.442575683656614 0.587283771443181 0.838583273314871 0.982717459148262 0.904158396869898 0.0827761232922785 0.150577939301729 0.98755535768345 0.555647086168174 0.989546425577719 0.573597225176636 0.946976281912066 0.313972251799423 0.858563090972602 0.508953911007848 0.0852513749455102 0.0583489213930443 0.74303583380999 0.305812135294545 0.0327880511432886 0.331242266693152 0.987079614689574 0.376902000759728 0.553266523953062 0.0490537685062736 0.0160259921755642 0.022172163890209 0.649344235467724 0.738273667048197 0.614431089933496 0.815851641076151 0.346450506870169 0.60260854230728 0.237735327691771 0.880644951183349 0.271070586303249 0.581366048981436 0.738847778527997 0.440845416248776 0.6692544891336 0.947443936578929 0.257894221693277 0.399004609177355 0.817130407420918 0.407273754901253 0.714200718889479 0.707404661048204 0.259916250661481 0.739492548655253 0.106371480750386 0.354542205210309 0.241301027585287 0.016282554876525 0.826095944500994 0.629014052182902 0.313921117391437 0.64575154859107 0.974754177809227 0.959473755594809 0.822574218690861 0.980663829923142 0.294939544964582 0.553135155369528 0.328687138834503 0.829296902567148 0.153371578762308 0.883604652595241 0.762045736126602 0.0949488802650012 0.220285703763366 0.812818102620076 0.601540041808039 0.557129832098726 0.131567717047874 0.0124613655009307 0.259545353038702 0.809854250783101 0.521513523510657 0.451537658092566 0.336828895367216 0.154846573129762 0.499431581932586 0.576047836591024 0.420145093463361 0.683131360949483 0.630386197329499 0.0487581819901243 0.0251413313415833 0.176130733671598 0.542911977944896 0.744288742172066 0.224316391411703 0.459674347261898 0.469836328621022 0.0111827575112693 0.565388674137648 0.758595519748051 0.0296126235160045 0.521993641208392 0.206253427271731 0.61762157028541 0.346192079635803 0.810907187534031 0.266930024875328 0.911778872827999 0.0521681021805853 0.584414323221427 0.332929946258664 0.326392189566977 0.204972328473814 0.691487551962491 0.835587114270311 0.981781804522034 0.211769269600045 0.648982201120816 0.101972229776438 0.701410795827396 0.62111326325452 0.726570999308024 0.66965158887906 0.333124886695296 0.569213376829866 0.233522480730899 0.299756729868241 0.582463076219428 0.820710950512439 0.230532751549035 0.579116633606609 0.231402709782124 0.215445640811231 0.735397466260474 0.814001614104491 0.519597784932703 0.778898877862375 0.340609045415185 0.653158696249593 0.575500438488089 0.684892828001175 0.928880249445792 0.0484862060588785 0.804802547961008 0.568332165242173 0.547130720464047 0.902477429071441 0.429813038471621 0.619455645573325 0.0411613110848702 0.512943676423747 0.477040609328542 0.0565304296766408 0.188258308498189 0.764608133798465 0.282498631714843 0.766179472149815 0.122767679493409 0.934790659451392 0.543322112828027 0.324219150450081 0.856289586259518 0.636673783150036 0.696582444699015 0.218158185170032 0.100299526178278 0.912750676674768 0.127730212255847 0.653747000680305 0.299242129020859 0.0328573205531575 0.958124380391091 0.285513502708636 0.851984696027357 0.718092471945565 0.622723745051771 0.946278418337461 0.103640058250166 0.0524955072393641 0.697776246038265 0.837444330148865 0.771285374369472 0.895837804868352 0.950058558704332 0.0933630311000161 0.512081451774575 0.878060191557743 0.719023093322758 0.439295290336013 0.383070913373958 0.110785836311989 0.669164479353931 0.0336420369474217 0.907116414923221 0.557016992445569 0.511546393844765 0.428184225514997 0.905179528216831 0.0885382769606076 0.239518822007813 0.571327030938119 0.555929945267271 0.411418309090659 0.146145783888642 0.970659972475842 0.670473518492654 0.934160769172013 0.404909807064105 0.110108101814985 0.0892721134214662 0.460065734698437 0.576750467414968 0.41829307126347 0.207116759484634 0.717117779213004 0.0679840191267431 0.345533228120767 0.280359446476214 0.351623584616464 0.242411355038639 0.984015674819238 0.760364396297373 0.87310360229807 0.450892119009513 0.346061128722504 0.665693189068697 0.547484918884002 0.798593037431128 0.576062232614495 0.657139996697661 0.539400948134717 0.712573283645324 0.400084980546962 0.0479744821111672 0.156385995435994 0.265041506087873 0.796153419134207 0.37210712133674 0.291140209976584 0.431509440706577 0.267020069691353 0.0845087123196572 0.80327171117533 0.812920764673036 0.373279174319468 0.0369875974277966 0.610059243151918 0.257287267087959 0.920543801649474 0.310419297763146 0.457826492774766 0.296109087546356 0.603549818424508 0.769405581708998 0.422311563033145 0.546893002020661 0.0331366799352691 0.647026692361105 0.393033888465725 0.190597634075675 0.139832869088277 0.521818847598042 0.994735270144883 0.298221051150467 0.0919199022976682 0.845810587198939 0.103142379731871 0.594192290452775 0.162466791155748 0.819994431000669 0.182316830926575 0.642956880629063 0.445138846596237 0.519387245711405 0.988005700241774 0.53789516557008 0.257983521986753 0.710746663033497 0.299712645835243 0.0604745507892221 0.297080495159607 0.726939785068389 0.99984096422093 0.668939959243871 0.0990272708330303 0.915727794612758 0.186741563242394 0.993863882797305 0.960530050995294 0.912977800769731 0.390790270916186 0.752045497335494 0.36974014262436 0.446490661667194 0.341862831760664 0.561683524018154 0.82568764579948 0.122047041596379 0.909984462612774 0.468713187773246 0.775754257563967 0.957211497090757 0.699747667757329 0.661763254683465 0.30051938880235 0.101204143434297 0.640034459512681 0.30565154569922 0.117326260607224 0.219052642113529 0.551839715638198 0.0538729613157921 0.87717454602709 0.713208385582548 0.251309027159587 0.162762932260521 0.690165125248022 0.924688766363543 0.612078770017251 0.517638512761332 0.227679267458152 0.132038015346043 0.10673342497088 0.473308990395162 0.97216784408316 0.878842279303353 0.601991304070689 0.450143367894925 0.604748930537607 0.199717125510797 0.933769127491396 0.336478693396784 0.0327878547552973 0.967727164924145 0.435784218804911 0.469451182726771 0.333064076951705 0.0363334048260003 0.067434283499606 0.664924114563037 0.287356576807797 0.392227737198118 0.371898754138965 0.895077291449998 0.150915156153496 0.122466146938968 0.617528258329257 0.77124412620673 0.87729524719296 0.55668235237943 0.103659824978095 0.776591598333325 0.589996048188768 0.0953867985168472 0.425035021447111 0.886658699535765 0.934526038619224 0.578549997317605 0.471215911617037 0.945667770393193 0.620824507675134 0.306894419142045 0.154237025834154 0.111614210770931 0.877134120066185 0.889897109160665 0.871434288006276 0.69662333696615 0.365066008854192 0.175990332392976 0.637307794350199 0.36855252796784 0.149952139055822 0.583755976506509 0.0348879781458527 0.647399933731649 0.246801556260325 0.252804217450321 0.950692505824845 0.472074576618616 0.485218262220733 0.483760462636128 0.9092453384283 0.481487674324308 0.47615346968174 0.0236464861128479 0.856255376716144 0.0909424380050041 0.413018035418354 0.890001825450454 0.868370557662565 0.814157430457417 0.07336151602678 0.994436827013269 0.172468480498064 0.236014375344384 0.171739503948484 0.828978139271494 0.888558214667719 0.930013722099829 0.156775827442762 0.386110480388161 0.829816416110843 0.601525801143143 0.572789689511992 0.207791319964454 0.889990751887672 0.0317757577169687 0.810382860179525 0.764505040706135 0.680688125609886 0.583654445759021 0.91351190488087 0.208906862072181 0.334304084328469 0.497253277911805 0.805433671658393 0.468656670905184 0.81548114360543 0.652492549796589 0.506002255510539 0.958836668340955 0.0150405066320673 0.932345684510656 0.712975253444165 0.709191411901265 0.890483852399047 0.460684020107146 0.813026623332407 0.488748023572844 0.357674894707743 0.880531759783626 0.409190115835518 0.74566254486097 0.200773591022007 0.274615754662082 0.72678749217419 0.649890524393413 0.296552481381223 0.10654475903837 0.0600757121341303 0.871725416607223 0.84726500162622 0.0746225756430067 0.538123826193623 0.633160568638705 0.64391672232654 0.390720044921618 0.884465668490157 0.85018015315989 0.836665966168512 0.501407775511034 0.792527365661226 0.784523574458435 0.215938204482663 0.15686275517568 0.639786143263336 0.541209278616589 0.979194498767611 0.844495378895663 0.36950504430104 0.82248254791135 0.749112363161985 0.390939765512012 0.916162300969008 0.261936555472203 0.909495322823059 0.894736946451012 0.396551169038285 0.255247997236438 0.613887543063611 0.670668355433736 0.447060131290928 0.269651783104055 0.286062318631448 0.277437120326795 0.379238691464998 0.687042363947257 0.229429755683523 0.90464011494536 0.183763070357963 0.239264238630421 0.200466021611355 0.118303717293311 0.148835122885648 0.732782919278834 0.21595489999745 0.949638666657265 0.903850466953591 0.0556626040511765 0.233244417693932 0.775424717131536 0.193013372791465 0.734806059498806 0.744333735997789 0.344701473114546 0.697019985388033 0.803436935020145 0.506742097940296 0.947190224500373 0.193608019724488 0.133328845491633 0.970241787759587 0.139513531380799 0.392999314037152 0.904575578209478 0.115097792593297 0.444337430307642 0.956158754653297 0.826171128831338 0.613971866811626 0.92535759563325 0.420355345478747 0.72765044843778 0.60445879010018 0.211689470843412 0.437121478575282 0.639909302275628 0.838909052410163 0.547497832085937 0.630868188780732 0.59680931533454 0.13007673596032 0.171786803258583 0.561901955408975 0.0925030964915641 0.914831440404523 0.980122458534315 0.876780610156711 0.407795777001884 0.8700353886839 0.15691822049208 0.0225856933812611 0.282623945001978 0.689512033064384 0.75231390716508 0.292437047013082 0.750128686230164 0.441672565357294 0.117616678108461 0.96957525636768 0.44102103090845 0.503024169923738 0.750235595288686 0.496942764755804 0.135624444775749 0.94984866120154 0.94667263726471 0.113347825303208 0.0802884908975102 0.780777625886258 0.0680218618479557 0.917900999691337 0.434105934745166 0.356136445812881 0.867284717394505 0.759865285668056 0.754466896497179 0.853639469540212 0.0732398158637807 0.308826382549014 0.933450803302694 0.445619960986078 0.189336133969482 0.692083582831547 0.630933880794328 0.52926189922262 0.815980655539315 0.354697540043853 0.790599222599994 0.813737413017079 0.936817726048175 0.307826721111778 0.956021350366063 0.791324960130733 0.0380726309376769 0.435607682135887 0.0797431179881096 0.459719462562352 0.538219069067854 0.869677390202414 0.424539056944195 0.794991415592376 0.0710765530425124 0.191547564172652 0.0453004046739079 0.385230452890974 0.395063001692761 0.419668782050721 0.100029521964025 0.83224459273275 0.813362541073002 0.188052870524116 0.117787158789579 0.211416712587234 0.0948214906128123 0.94733648929745 0.860022088016849 0.113786077322438 0.912780883775558 0.650218475512229 0.536654391773045 0.629741811680142 0.724889410536271 0.713506493794266 0.474351763145532 0.100902183298022 0.36667838676367 0.984664088496938 0.400278651837725 0.269618048164994 0.146960411188193 0.0423430712125264 0.127866688540671 0.894888347301167 0.713240089104511 0.162343345629051 0.284637047306169 0.779414944243617 0.312946766032837 0.461588115736376 0.98518666195916 0.238804010057356 0.486924587581307 0.750572978563141 0.987102417363785 0.60715552914422 0.254241341897286 0.352360145153943 0.0772238913294859 0.649910649091471 0.423095320768189 0.95076317922445 0.532255309526809 0.168958017723635 0.44452900448814 0.757942763406318 0.0251735147694126 0.266112074423581 0.272268738143612 0.315486278741155 0.329516163540538 0.895230498285964 0.93341610647738 0.644873108563479 0.931004648650996 0.0672127769771032 0.176028256712016 0.297746366392821 0.61184944093693 0.829263266052585 0.0613625280815177 0.0271380262589082 0.918409168832004 0.735548957467545 0.491062711447012 0.619335629690904 0.155077911037952 0.0740286448807456 0.963643257974181 0.0900279298936948 0.58329541624058 0.43174865487963 0.789155484579969 0.328518847464584 0.933190595668275 0.424254795007873 0.454798503201455 0.672994644260034 0.979906650951598 0.191426739918534 0.135949745578691 0.901803874964826 0.462756790246349 0.585242536789738 0.636062788530253 0.206885532909073 0.681699424188118 0.405929985283874 0.198733163126744 0.826933572937269 0.621941178322304 0.913751630077604 0.0403242178750224 0.707859128906857 0.687265415065922 0.741657488150522 0.41568547323579 0.920455438117497 0.197239384201821 0.777933767342474 0.898679124198388 0.911534851298202 0.95588770856848 0.249122773343697 0.906838011434302 0.550643798978999 0.466118186237291 0.313294534129091 0.652279413044453 0.621932223076001 0.970436242297292 0.31665335586993 0.990779316194821 0.5405229357793 0.658985233830754 0.337523029414006 0.485250816526823 0.413259510127828 0.870949040709529 0.11827504464658 0.277988458867185 0.5400295469095 0.495610298512038 0.765733602489345 0.45365171373589 0.224546695977915 0.399797513014637 0.387502296834718 0.706507263586391 0.99707148324931 0.516064983715769 0.909263993443456 0.839982700026594 0.582730977560859 0.600028666565195 0.963277202052996 0.251875183312222 0.0742528185457922 0.881813616242725 0.388738482482731 0.189294165717438 0.84090758189559 0.836728198111523 0.993351726427209 0.518539435986895 0.593337703498546 0.581903666178696 0.473410389064811 0.409723027558066 0.0704538945434615 0.60828571299091 0.339722095241304 0.817892505773343 0.0215888754208572 0.333166640349664 0.325078722478356 0.732225180841051 0.964426459507085 0.525378936603665 0.323956165031996 0.920464420563076 0.995515127549879 0.721799151217565 0.0732095875567757 0.349050489561632 0.613802383744623 0.503590527074412 0.45715145238908 0.151875970801339 0.467710016246419 0.806954340755474 0.608660364113748 0.710548665905371 0.595646085289773 0.714639969675336 0.397271065639798 0.802154168537818 0.484339624652639 0.320676927219611 0.0652414299407974 0.660607300675474 0.320953701057006 0.352820760740433 0.698798576458357 0.731806754097343 0.0264808417367749 0.375084414687008 0.362933181792032 0.44099079222884 0.33618742511142 0.464743024737108 0.802908316173125 0.696090908837505 0.464966803090647 0.915106166920159 0.0310035684332252 0.0638056871248409 0.174270418689121 0.930564193029422 0.568177781000268 0.851259168714751 0.149005097844638 0.507244575978257 0.953830736137461 0.146232161181979 0.395260534358677 0.354277501166798 0.667655171256047 0.291551249350887 0.653251583850943 0.810448144434486 0.814850472614635 0.926728246894199 0.0493654765863903 0.614856400399003 0.725459567517973 0.516488216202706 0.557986372099258 0.892159522562288 0.494185898024589 0.64912703565089 0.653607956368942 0.397612181438599 0.731297451576684 0.15431296275463 0.746147802991327 0.44015808455646 0.577643160093576 0.303799151468556 0.976524162383284 0.115866211089306 0.141364858155139 0.666775753898546 0.592496907499153 0.388747243185062 0.554238215545192 0.210742503162473 0.540391276301816 0.427439432356041 0.195397567723412 0.79975286341738 0.131139176783618 0.69036859611515 0.222218561058398 0.582546680800151 0.322390503722709 0.45263490937883 0.738197753408458 0.862609942136332 0.308376956467982 0.891270159720443 0.449857653793879 0.867219121039379 0.0800221618125215 0.3146482084319 0.803160632329527 0.917513617693912 0.259197345450521 0.154648383762687 0.0450454040872864 0.417337467581965 0.0977038036310114 0.931140427435748 0.0675617821794003 0.50541617634939 0.818246324555948 0.790281042014249 0.438364325279836 0.676285174612422 0.757411179607734 0.167659379772376 0.0807388320728205 0.851267747781239 0.656832634278107 0.892728320732713 0.332466753886547 0.934048692942597 0.755169838499278 0.0394316342240199 0.647515155165456 0.0232321772933938 0.25493680087151 0.754005272001959 0.480273637184873 0.166805581597146 0.212688393520657 0.347984249598812 0.875313473844435 0.990808276047464 0.650383363284636 0.18797592953546 0.806212705478538 0.767931468551978 0.999416070042644 0.0299315389432013 0.626809126986191 0.0107155502494425 0.0473795590363443 0.535814506257884 0.471453612772748 0.529722604935523 0.12158355418127 0.197283881986514 0.12433222586289 0.50401294012554 0.550200426119845 0.855351918195374 0.436643876580056 0.762282763754483 0.84569686264731 0.158445515378844 0.646878851389047 0.466654269902501 0.385847156592645 0.521749308269937 0.281084217510652 0.643230935230386 0.439038073238917 0.342951322344597 0.359622749637347 0.609496309652459 0.579836352260318 0.446882453865837 0.7551664480404 0.935845388818998 0.56992094270885 0.598047779037151 0.49650817910675 0.875707836835645 0.178665380706079 0.918300841723103 0.32728373180842 0.630964069224428 0.0636898739915341 0.629676164384 0.771977573349141 0.0539293822948821 0.724299816905987 0.912377906912006 0.714419015666936 0.60889951605117 0.496986028661486 0.0669061964214779 0.77268100355519 0.405148830611724 0.986051351369824 0.13111589812208 0.469852267857641 0.578547755221371 0.43323634854285 0.248320361746009 0.641976383156143 0.913439178396948 0.933147637869697 0.209387354797218 0.299675149328541 0.546349451923743 0.173532737910282 0.452053978487384 0.789429034381174 0.0901338607002981 0.815784231589641 0.337476051885169 0.22110742822988 0.280547610144131 0.514851755870041 0.36386355514871 0.665070824460126 0.865532546732575 0.506828504737932 0.801453826832585 0.323251133295707 0.908621476707049 0.341691405789461 0.274640378074255 0.743506051432341 0.963526564552449 0.527815056797117 0.625456223944202 0.744859582823701 0.0480670666019432 0.279582777149044 0.0629196324525401 0.132469590865076 0.586431213140022 0.253775173970498 0.169616684145294 0.104720817324705 0.625801035847981 0.521616861857474 0.997168492693454 0.046392764239572 0.0874789866432547 0.0664262525225058 0.463556480994448 0.403337609169539 0.668688849997707 0.18663620431209 0.614086284714285 0.931689056882169 0.392889069379307 0.625347329569049 0.100503075185698 0.153956204375718 0.110324588918593 0.432592706724536 0.0142241441109218 0.325459959744476 0.817863772043493 0.319966121169273 0.318986846511252 0.155515019535087 0.287829133567866 0.871202921285294 0.12769518281566 0.0572420420241542 0.330213780938648 0.442513743068557 0.882251585205086 0.281596039191354 0.0386958223581314 0.61235230737133 0.719468027374242 0.674939064704813 0.357655442846008 0.0453212863416411 0.936264828159474 0.309117611648981 0.274604059664998 0.281869900862221 0.193125964885112 0.962061962152366 0.452602098523639 0.482253718415741 0.815058602164499 0.947280942613725 0.394441431625746 0.0656764240399934 0.720982945668511 0.633944899863564 0.239410724940244 0.0729843743261881 0.717019824017771 0.650348624277394 0.534661828840617 0.713724490918685 0.774646117347293 0.0467647648160346 0.631407670511398 0.226728400138672 0.091882127574645 0.182570147463121 0.83860064950306 0.352648702731822 0.479462669340428 0.15262162742205 0.253958611418493 0.12357746347785 0.255323159208056 0.488788886796683 0.891301517719403 0.533406045883894 0.362083498314023 0.422073837905191 0.0483293771091849 0.125031869607046 0.0487588880187832 0.95497949247947 0.973035675701685 0.59074788549915 0.470240945739206 0.858552567618899 0.869554702797905 0.765742155970074 0.248123239835259 0.533323315137532 0.58694714698242 0.776251270391513 0.194689484136179 0.202147877996322 0.902361585281324 0.178284460611176 0.927361370429862 0.916663732987363 0.987673561817501 0.674761072644033 0.71889474316733 0.190811139631551 0.296392226475291 0.0405849759490229 0.651237169988453 0.763152630708646 0.316065766687971 0.952752099989448 0.589631375512108 0.243486869493499 0.408723631890025 0.822462283759378 0.73627697581891 0.216931932559237 0.265075651782099 0.0658765699109062 0.0857884555333294 0.0421475240937434 0.739511407664977 0.585781802309211 0.075892317360267 0.625174196497537 0.711310955574736 0.460233400946017 0.971857135922182 0.111575544003863 0.473125830241479 0.634029345316812 0.66821332989959 0.905248546379153 0.122521095008124 0.445191934511531 0.538441894985735 0.311510767820291 0.53742388187442 0.0985154597554356 0.346999989175238 0.178307633933146 0.507355306996033 0.898629199466668 0.362979066278785 0.0945068646036088 0.0965996573283337 0.923131977089215 0.292487301824149 0.148899040492252 0.564088621824049 0.361521675144322 0.0882699443493038 0.626475981727708 0.877111790843774 0.400876476475969 0.487530594822019 0.406572072133422 0.421144823129289 0.450937246757094 0.13012333615683 0.299666922008619 0.772976880504284 0.599295304247644 0.149149373176042 0.17357019361807 0.478651151056401 0.0296615363424644 0.859131256875116 0.891675345487893 0.942133744286839 0.211389834401198 0.0876900546369143 0.254124690887984 0.596903342539445 0.867376292746048 0.164554980287794 0.567617864084896 0.494918272870127 0.984556701146066 0.642640349748544 0.626080289429519 0.76425052002538 0.916792366430163 0.151901061902754 0.148092846812215 0.645433975839987 0.445735091601964 0.399250235694926 0.0974405144108459 0.377155970309395 0.624213013737463 0.664365719654597 0.685405297162943 0.957691572606564 0.455632682400756 0.815614320940804 0.607602600182872 0.217457178696059 0.669857996115461 0.689464958955068 0.818145943554118 0.327306543933228 0.577022972349078 0.483163938031066 0.863856110379566 0.990650404305197 0.0241053999005817 0.399870634349063 0.664580028511118 0.428561465409584 0.283734869225882 0.790166780853178 0.94971241703257 0.73684316792991 0.854804951823317 0.443048198234756 0.87476743086474 0.405115255410783 0.854421318715904 0.289649960503448 0.0830022898805328 0.584818202732131 0.981246749127749 0.779256790596992 0.939622044682037 0.377438091801014 0.935325530674309 0.959096855921671 0.772085701995529 0.872300612139516 0.94449682059465 0.223528067194857 0.160957544140983 0.838314465177245 0.971070159913506 0.278630520130973 0.694671360885259 0.541061304644681 0.51963089912897 0.2239965680358 0.849302556540351 0.218958965502679 0.575665048274677 0.817676702339668 0.225708846580237 0.749329253644683 0.899150465980638 0.734240095585119 0.978035499593243 0.752554037354421 0.295990880415775 0.667367750285193 0.893141324908938 0.41199970490532 0.990299868797883 0.352222510825377 0.479350831911434 0.99922386221122 0.733289124078583 0.432041273447685 0.852442308398895 0.741269994820468 0.629580879327841 0.152652039439417 0.0222455078898929 0.746391690138262 0.099848907017149 0.452199331186712 0.106804421995766 0.106457580749411 0.273368704516906 0.23670201567933 0.115724078046624 0.619885139425751 0.666301060612313 0.490260017714463 0.597662773288321 0.797212727661245 0.272650598918553 0.406052440342028 0.728078471224289 0.0742696569720283 0.81799227594398 0.913519538196269 0.831905223450158 0.936364496448077 0.219498693870846 0.0775514487503096 0.0332206957321614 0.0954313546186313 0.944138221193571 0.177186703833286 0.569258480374701 0.206628458262421 0.859056281840894 0.233024765562732 0.813979216422886 0.258698901203461 0.118050374940503 0.854929381133989 0.711834324039519 0.263154651757795 0.68330491076922 0.176320229873527 0.0749705067044124 0.947154962944333 0.375431287742686 0.0231936354585923 0.658403186616488 0.5271328533208 0.246313096222002 0.160830362862907 0.441881557216402 0.18623628298752 0.665061900101136 0.558336512525566 0.44425805774983 0.941610337328166 0.837362416533288 0.379465529045556 0.316841994372662 0.351873660981655 0.719073299036827 0.340242898676079 0.33999349514721 0.754226701997686 0.701997469915077 0.33190661753295 0.493496458388399 0.272370311764535 0.8063723124424 0.645953014318366 0.10532961871475 0.386991073999088 0.228719477483537 0.372791062339675 0.714500493633095 0.388910892468411 0.761052475278266 0.101357200213242 0.108656523949467 0.319871475065593 0.356452919298317 0.939559838094283 0.687847248374019 0.589674011990428 0.920718067178968 0.622373223144095 0.358050404451787 0.733649145679083 0.639681606765371 0.605386530889664 0.663864025785588 0.30439306471264 0.194547682094853 0.104727943995968 0.382674456730019 0.525524895063136 0.443255186567549 0.283597380113788 0.505594339442905 0.513179015161004 0.716983935495373 0.159986175252125 0.81728989014402 0.496943933633156 0.364831869651098 0.74108053019736 0.339412364640739 0.786841422519647 0.839490165628959 0.742744605862536 0.975771674595308 0.504775417423807 0.181284725132864 0.194072484239005 0.419212404480204 0.699029605493415 0.26297915234929 0.62792594745988 0.860187766181771 0.928939986431506 0.516010404680856 0.346773187783547 0.477264880265575 0.898061384388711 0.73581245967187 0.682855732478201 0.607029448514804 0.127276008322369 0.853185807978734 0.371497174580582 0.359688767120242 0.0831147247715853 0.113315831809305 0.200423798884731 0.814885184653103 0.349399916583207 0.707025181362405 0.0285134989372455 0.264310049563646 0.724063766377512 0.313967618471943 0.0155472736270167 0.326380189615302 0.913467625842895 0.914343720509205 0.771359322976787 0.0668176033091731 0.358904258408584 0.374140488945413 0.799631966555025 0.976640372672118 0.182136796845589 0.711771393904928 0.270095821653958 0.424791635181755 0.260957073131576 0.948124006986618 0.287251348111313 0.979118723659776 0.53426167309517 0.682758432140108 0.757123005585745 0.782528462861665 0.698755737137981 0.693422760842368 0.983808174771257 0.545138063486665 0.0668580048368312 0.347953731780872 0.30691331964219 0.0375313065713272 0.316839900258929 0.883695963791106 0.178515801976901 0.229632190442644 0.827812981535681 0.946006786315702 0.439025547280908 0.570808293956798 0.496431782795116 0.36317199512152 0.489163573186379 0.394971870519221 0.346060509132221 0.496117151945364 0.546187113276683 0.418611502866261 0.709853034284897 0.0974694159463979 0.991522842743434 0.659808323562611 0.645659847846255 0.129755696684588 0.53940368627198 0.591981733392458 0.952022889249492 0.342830871043261 0.625543020060286 0.467072043402586 0.0370817442634143 0.448378647302743 0.705101092606783 0.818863430484198 0.251862292008009 0.679667184196878 0.882104229901452 0.407045565193985 0.670504454672337 0.988685039496049 0.348840073889587 0.995538384544198 0.405469220562372 0.423717371432576 0.749626500699669 0.578662996939384 0.810300295164343 0.843923375129234 0.518047433819156 0.251508470689878 0.201280606728978 0.564962838587817 0.461352420873009 0.106918934634887 0.877858665669337 0.997187677863985 0.261968826260418 0.881722670162562 0.252578873294406 0.281941196848638 0.740028481571935 0.340676596891135 0.300126705942675 0.618095440678298 0.630770425593946 0.907023670463823 0.42858202483505 0.0396222972287796 0.615954978917725 0.0634251936897635 0.589404033592436 0.570203399120364 0.724459601817653 0.163234236931894 0.746697518103756 0.256808546925895 0.197760765505955 0.994700006744824 0.121321248975582 0.825448851371184 0.366869891332462 0.980543447542004 0.920341707342304 0.908383074363228 0.578555003136862 0.279224111593794 0.554510107112583 0.920358023450244 0.0775531848939136 0.3378950528102 0.808080786776263 0.125721912467852 0.717337967031635 0.91035470606992 0.95890385746723 0.199255062139127 0.88018400920555 0.773464029214811 0.816046845668461 0.554264366726857 0.200905433287844 0.0986010786960833 0.146271191681735 0.12391548040323 0.624540565165225 0.0888166550942697 0.387805207332131 0.112536678127944 0.167231179038063 0.755361795544159 0.464964223769493 0.782157125209924 0.924896211551968 0.568239453744609 0.866901250940282 0.941534797332715 0.566562455657404 0.805550623242743 0.523009110034909 0.927912495064083 0.178964913652744 0.679623333893251 0.810551196958404 0.152846329859458 0.582197878670413 0.748304792460985 0.235853232312948 0.231198535882868 0.117721578800119 0.357607704889961 0.563001873837784 0.941407278599218 0.542198349393439 0.566708876735065 0.296276545880828 0.219616925434675 0.813994696037844 0.117942290550563 0.921856804045383 0.0590226310887374 0.550302173078526 0.667890970306471 0.710108088348061 0.0326276477938518 0.0587745580193587 0.648685437429231 0.540195673862472 0.495977251778822 0.747906719304156 0.327274696347304 0.548190219155513 0.231572130613495 0.352014836287126 0.987684297463857 0.577303059888072 0.512386440711562 0.402886987472884 0.904600971268956 0.373406458171085 0.786218327910174 0.19135714158183 0.515028339792043 0.814574928046204 0.798489796125796 0.218520321398973 0.740989329642616 0.588232231165748 0.839989929501899 0.75422901508864 0.284669343219139 0.310034925895743 0.817056524045765 0.956355132502504 0.300223764253315 0.972873438014649 0.485502794305794 0.884526916188188 0.0458952535269782 0.0192127443826757 0.450048799701035 0.588388520048466 0.938621388857719 0.127387091547716 0.131974088058341 0.332366093746386 0.17962871497497 0.537086389341857 0.0871257883729413 0.236335428680759 0.758527355366386 0.474798668222502 0.0853535524825565 0.516758342583198 0.11065856997855 0.615822997197975 0.217419559792615 0.782929410613142 0.197835278382991 0.873404604466632 0.0655111225158908 0.0962718777032569 0.873352226498537 0.448200913174078 0.773902309585828 0.171879427395761 0.968540686503984 0.562904076075647 0.660802301503718 0.014997286060825 0.918174312997144 0.10814225202892 0.251518870033324 0.924349633345846 0.865348610938527 0.256393509488553 0.411704075054731 0.944223959764931 0.964303324928041 0.0121032771235332 0.873266062650364 0.79413308020914 0.303731810441241 0.886168193097692 0.034665863327682 0.97687752062222 0.71501439260086 0.915300329411402 0.96611095975386 0.17074806683464 0.739512333592866 0.353000093633309 0.0443683749274351 0.262931929565966 0.311527232602239 0.162647678556386 0.452349450213369 0.524711780089419 0.634445466806646 0.0466117640491575 0.811159302922897 0.850217693001032 0.590839783553965 0.652701084569562 0.162754000986461 0.739337049934547 0.878065202678554 0.685896666832268 0.73181525018299 0.77898062159773 0.588489915952086 0.12145391090773 0.511938547932077 0.09709921766771 0.226378894054797 0.535183628736995 0.239909973870963 0.944544634385966 0.664596554145683 0.161364152338356 0.528778900015168 0.0253325952659361 0.479839031251613 0.574350403780118 0.532312673029955 0.991420605506282 0.340995198604651 0.860136331890244 0.527693488942459 0.789062244771048 0.40273303035181 0.406988371801563 0.321970513942651 0.477106090432499 0.235924286041409 0.747292109485716 0.572197530390695 0.74877454884816 0.293012385687325 0.172107932199724 0.381367500179913 0.470654166818131 0.578366489105392 0.467646559413988 0.521986858677119 0.40367529186653 0.100155520073604 0.424467879435979 0.988577465438284 0.457334728715941 0.79240739173023 0.979920534798875 0.171672517433763 0.377452400925104 0.0765024635009467 0.891801154816057 0.544214458370116 0.305931460361462 0.142813933917787 0.711924330822658 0.274038441274315 0.642142298277467 0.844884514554869 0.3047250835062 0.214709681193344 0.979639720947016 0.271973123275675 0.385443869472947 0.561792932874523 0.81443231740268 0.805845848792233 0.278909232954029 0.353615446821786 0.422222611028701 0.034607741010841 0.0797438950114883 0.0624186884076335 0.23057371688541 0.0339931111386977 0.0237720930599608 0.639088634431828 0.202340972109232 0.340007577918004 0.277237527891994 0.623228729111142 0.0286835746257566 0.0906205758359283 0.181937388582155 0.296791392674204 0.728625503750518 0.502270080836024 0.640441328177694 0.259883124018088 0.0794343123934232 0.637421204496641 0.905211526781786 0.238541497399565 0.600100102005526 0.801574123005848 0.0317420345335267 0.172189381122589 0.645494336795527 0.501019653601106 0.922361383112147 0.222937583134044 0.652044182643294 0.560097698594909 0.965158092596103 0.0815187079180032 0.383251505501103 0.498558729051147 0.0648530710744672 0.52894568274729 0.65247769345995 0.297908641190734 0.940675176898949 0.17262718250975 0.698981439033523 0.647275366119575 0.128000845741481 0.88608477798989 0.734621833271813 0.256446912270039 0.530048679304309 0.432186455805786 0.705414795684628 0.462586591700092 0.765341081903316 0.503976373695768 0.520860025181901 0.289529548157006 0.45855068547884 0.126250657399651 0.965741865120363 0.15541379858274 0.529780850340612 0.750138663984835 0.796337080169469 0.988843064291868 0.123671461178455 0.745230293278582 0.702229264217895 0.285355588323437 0.225745681084227 0.472019051371608 0.50654418655904 0.478216096335091 0.518786871947814 0.179379198038951 0.853415398218203 0.458962061156053 0.333270706853364 0.0189405561587773 0.107206028061919 0.232180672227405 0.114497138999868 0.491297954064794 0.272668014983647 0.992282767458819 0.550738496484701 0.730556638962589 0.414426921023987 0.974287659518886 0.719830806935206 0.725651503817644 0.20651209538104 0.206784747375641 0.979595293926541 0.139232031092979 0.585850235226098 0.421413566265255 0.672016825454775 0.320217138445005 0.305079955453984 0.770247167178895 0.342866374165751 0.62961171155097 0.398785058236681 0.493549740156159 0.237387120258063 0.945759916929528 0.0596279491274618 0.0349918660102412 0.243185911120381 0.614130985571537 0.663581944170874 0.932905794817489 0.503978315216955 0.614475765665993 0.163646528855898 0.28535208261339 0.888573277534451 0.925514720778447 0.924870346884709 0.48648999478668 0.943549374390859 0.579269199646078 0.331324550034478 0.479177252817899 0.988740090369247 0.11978949847864 0.870954108303413 0.935216416860931 0.222002619323321 0.0624258314445615 0.304267414892092 0.206032441684511 0.146487030151766 0.859662752391305 0.885720998048782 0.651667572020087 0.288579965657555 0.773562033276539 0.263274652888067 0.478229860782158 0.761485927086323 0.499624816421419 0.757630084911361 0.428781531753484 0.944990837122314 0.563621531426907 0.612417861083522 0.836997950386722 0.192880268064328 0.873047458382789 0.108893625799101 0.0803431377001107 0.948406538541894 0.0489418416423723 0.58167831211118 0.0231462448695675 0.138578375331126 0.884626582632773 0.912800180509221 0.693194488384761 0.46149280624697 0.877441158399451 0.332022231051233 0.441985697711352 0.459931962206028 0.95143069901038 0.549225716560613 0.90418079524301 0.503675387201365 0.638482253777329 0.238829144032206 0.146803354041185 0.656868591720704 0.747521886893082 0.544595199595206 0.651255934722722 0.61406327550998 0.121127556709107 0.0652612512977794 0.286597889889963 0.824229000732303 0.746722159956116 0.96124463313492 0.988312561088242 0.309130663152318 0.604975070157088 0.36046659011161 0.619066095240414 0.614789868434891 0.676281965789385 0.708408176254015 0.279650832503103 0.522522785831243 0.81235624670051 0.450628405204043 0.734009489291348 0.644959274716675 0.240183850293979 0.708937266247813 0.0743119585304521 0.751983681910206 0.44952911258908 0.599223042686935 0.679110091396142 0.615221526243258 0.231773246438243 0.969686065525748 0.90354079605313 0.0505986477248371 0.2162162645231 0.499431215664372 0.408034189026803 0.0268436892959289 0.188287835847586 0.740530113205314 0.738504440686665 0.978816404631361 0.183630150032695 0.538738075275905 0.817463811303023 0.511931085188407 0.84780140384566 0.291712573787663 0.0346187786152586 0.363508543286007 0.726579944642726 0.701460000239313 0.95006095108809 0.321018019968178 0.170882875665557 0.487122311103158 0.0454611353366636 0.138479117106181 0.31142954017967 0.352541539429221 0.142113802200183 0.130684900241904 0.909463952146471 0.705182588321623 0.30416678218171 0.216487832465209 0.856711308725644 0.157608264505398 0.881445655680727 0.967370113576762 0.827295397988055 0.637547264150344 0.817428012215532 0.0838424517679959 0.457326072431169 0.295120578964707 0.383356143650599 0.981085621539969 0.486486617466435 0.312126808597241 0.270137623713817 0.916311979966704 0.297159399567172 0.119277307994198 0.446116838278249 0.459203425224405 0.939314776076935 0.772603684773203 0.846818558014929 0.927218046151102 0.371931094769388 0.421329420234542 0.173181112357415 0.411884344017599 0.765009999179747 0.843382007428445 0.32155695886584 0.482214670167305 0.173220557761379 0.559883926578332 0.319898610492237 0.777595365247689 0.204798873851541 0.864537826112937 0.180114670374896 0.319038180764765 0.907460005164612 0.145919425983448 0.643532962442841 0.941301421783864 0.592896569278091 0.856994818763342 0.595098037861753 0.411583044962026 0.544934991158079 0.410764346530195 0.627926597937476 0.612374707127456 0.350832709199749 0.649034153351095 0.666046948842704 0.811164361757692 0.824857317141723 0.373072726975661 0.726297704442404 0.487646619325969 0.440094324843958 0.0240044580865651 0.523328918889165 0.2744414706924 0.865299016516656 0.667103391995188 0.11511223817477 0.479716714955866 0.57802717998391 0.783485210295767 0.723909922663588 0.466432836218737 0.0170545546873473 0.128886361499317 0.733797833516728 0.563014767677523 0.134145767441951 0.932215971394908 0.708866064767353 0.680081460515503 0.0430464458675124 0.345849015631247 0.497056522730272 0.0248149741464294 0.959230988919735 0.873833041004837 0.465552415484562 0.0247654982027598 0.564446585960686 0.200810737626161 0.466708906562999 0.133528243382461 0.0165081876213662 0.876605425383896 0.79579086316051 0.0899106401624158 0.937621145863086 0.298051640230697 0.380522806847002 0.092125825479161 0.985417677164078 0.639133811737411 0.331285545581486 0.543831151884515 0.878576563354582 0.821797592698131 0.873672560206614 0.209742344070692 0.0791059479839168 0.428525501051918 0.597045086955186 0.611907686572522 0.0223828003834933 0.0545515867043287 0.739100254883524 0.960569696014281 0.666558344555087 0.443751158446539 0.0255641500768252 0.187372106304392 0.065154878157191 0.76157978187548 0.53921703124186 0.264310957051348 0.506900841672905 0.474495922303759 0.230989411254413 0.0407699715928175 0.616975264782086 0.476459234489594 0.554441040544771 0.255484427402262 0.753523007405456 0.512310302101541 0.702733967064414 0.0702518668514676 0.480052496700082 0.871564758783206 0.128136260102037 0.133650779577438 0.156768088096287 0.519489661587868 0.925050199790858 0.614232210442424 0.920693981989752 0.834241330754012 0.270968694358598 0.125349896447733 0.342824290201534 0.890811914158985 0.182712121689692 0.46463840018725 0.79122530083172 0.630940403779969 0.627262757199351 0.181566389307845 0.503002685492393 0.792135159019381 0.734691539253108 0.126125404965132 0.177805868838914 0.564632384674624 0.747933987730648 0.30074567732634 0.0732042562682182 0.893417847037781 0.676486216676422 0.82691215719562 0.213195164895151 0.916693868401926 0.292011320260353 0.0351127047860064 0.183581591488328 0.758687973774504 0.623331734151579 0.583228254544083 0.395359543410596 0.207563305899967 0.084056777220685 0.669187548719346 0.0132878689724021 0.378307614845689 0.911303738821298 0.197176998283248 0.422697233781219 0.781940979019273 0.692517095261719 0.325614887971897 0.0354990257811733 0.159427081460599 0.771848693038337 0.997640008043963 0.155470622249413 0.883358385742176 0.473795754397288 0.430313497078605 0.554887861027382 0.513775003617629 0.26485397399636 0.816482123285532 0.564433306260034 0.478922782847658 0.837204595962539 0.286173797168303 0.513895350731909 0.8360225318023 0.468403577955905 0.084832931375131 0.788966706623323 0.0297223532316275 0.900034938254394 0.673735072626732 0.888102143895812 0.267321422684472 0.548500752595719 0.724236475094222 0.202564298908692 0.352719778358005 0.592818391874898 0.597162372537423 0.704943757012952 0.366035693462472 0.0142840346111916 0.663211533599533 0.65019007531926 0.585428896546364 0.0558221607655287 0.298210995025001 0.543173894754145 0.694801917639561 0.375909758731723 0.853312515344005 0.232115881477948 0.399003928042948 0.584087432643864 0.346359135513194 0.469316413542256 0.77691934522707 0.689121640014928 0.987981676135678 0.249839623165317 0.469194133896381 0.269540513863321 0.517757547395304 0.118506093965843 0.945703189612832 0.539983308140654 0.440972369099036 0.724863450902049 0.774815268260427 0.583089807233773 0.458283733807039 0.173441760251299 0.716546714052092 0.729922535100486 0.804960446211044 0.930067099526059 0.401849099528044 0.282640766601544 0.370738923542667 0.898047451674938 0.447897620734293 0.0591852624737658 0.26485486650141 0.26141727196984 0.283857428701594 0.812298041172326 0.175087801644113 0.463316042853985 0.832249409309588 0.83691309832735 0.030631017878186 0.0377933810441755 0.710917809405364 0.725819799336605 0.924962470831815 0.528140386873856 0.953834725902416 0.664444759828039 0.0758831475162879 0.309220318649896 0.725838077710941 0.67653802000219 0.84993219926022 0.966250908556394 0.313275040776934 0.777529287373181 0.829101914186031 0.520996946797241 0.316704759504646 0.867455338682048 0.0244543479382992 0.201133377740625 0.239274986954406 0.138500968036242 0.532009432683699 0.951652023205534 0.770041251373477 0.982058207942173 0.424895285167731 0.012865694030188 0.943964842176065 0.926718069524504 0.586330140861683 0.756401811025571 0.902515380128752 0.785243997296784 0.031666382283438 0.767503448762 0.128474541183095 0.478197756647132 0.175853083003312 0.419691504049115 0.883106715222821 0.325984510455746 0.523767347242683 0.298432152797468 0.174135397104546 0.371700797579251 0.190822067977861 0.187843109017704 0.848329945935402 0.496792530016974 0.193448049027938 0.36050104490947 0.503179088931065 0.30419467365602 0.827312644403428 0.655382769044954 0.0457116563408636 0.831979124573991 0.786033285704907 0.338599587122444 0.0272601982601918 0.830236706926953 0.860562669935171 0.349190216159914 0.259741784364451 0.449685956521425 0.0790361299784854 0.115415253089741 0.0541918594553135 0.340910197871272 0.752264345474541 0.265793341093231 0.148081161496229 0.393040732771624 0.22415103364503 0.352192765190266 0.101201782398857 0.824354739757255 0.475778546796646 0.983890268639661 0.503580370449927 0.987688774049748 0.835275622170884 0.420822127924766 0.463677839322481 0.332627252433449 0.552774783405475 0.996911972635426 0.90395022260258 0.992607391737402 0.896348374229856 0.700919594194274 0.286228678852785 0.410472455427516 0.343707064364571 0.795385353076272 0.303627222771756 0.738169685138855 0.336987898645457 0.376913864023518 0.833907298753038 0.825686516338028 0.935773435209412 0.482481622761115 0.997317532277666 0.87351183853345 0.0254472116311081 0.16674691045424 0.0748029174446128 0.160436468021944 0.445353066478856 0.985271216440015 0.574532859288156 0.653204441282432 0.445885951693635 0.791251566112042 0.270888290763833 0.30350453767227 0.976658036296722 0.59035607094178 0.161881991513073 0.896121219478082 0.653302539389115 0.820708677067887 0.0970762527198531 0.724384927127976 0.877517481872346 0.383031780761667 0.343369201875757 0.456814319670666 0.700206580853555 0.775093916312326 0.0832181394146755 0.993947652878705 0.944335145563818 0.813931099059992 0.737612831369042 0.0210228257603012 0.756253658414353 0.95604334282456 0.25565625237301 0.149157837913372 0.0425232216971926 0.169975647048559 0.620483719420154 0.064831579728052 0.170567842589226 0.695154923440423 0.28567605180433 0.0848977041454054 0.37431661370676 0.717955382294022 0.0660431230627 0.589343496533111 0.510214431940112 0.168553912781645 0.585778938778676 0.112337283694651 0.970362896453589 0.811082274573855 0.886910952304024 0.51349981125677 0.904161223981064 0.440227960417978 0.183893675287254 0.187704834814649 0.237382623157464 0.465355296570342 0.744240799760446 0.677634098723065 0.388662565385457 0.513441735040396 0.967150544195902 0.812577779730782 0.319782236085739 0.110901160088833 0.0211595339304768 0.224291592587251 0.812948846311774 0.139973694721702 0.820575049330946 0.648825658685528 0.142634185198694 0.231106129800901 0.092170952304732 0.253896704944782 0.70124868537765 0.490943750343286 0.627420891022775 0.615944972350262 0.627443867265247 0.848016194221564 0.0613804950471967 0.936148077112157 0.67126590784872 0.0936077568144537 0.679212142387405 0.196908932132646 0.174007960199378 0.388317204655614 0.915032827761024 0.530795656933915 0.419391171950847 0.150079185720533 0.0547217928571627 0.613675637193955 0.891448268184904 0.654511732982937 0.669263348029926 0.788589870568831 0.421637854720466 0.0377332699531689 0.680321806916036 0.440710351560265 0.273728609483223 0.318748207211029 0.572553863953799 0.774341462869197 0.808664424917661 0.973901827419177 0.411063175983727 0.517485120831989 0.639476645470131 0.854302725493908 0.0829239066387527 0.615920045597013 0.105042781606317 0.386793005184736 0.948403409242164 0.651657707903069 0.339299552878365 0.616029539739247 0.803508441685699 0.444259148256388 0.6487631884031 0.699881490038242 0.171941456035711 0.208088535671122 0.759796336425934 0.479415104261134 0.628975243195891 0.223066696252208 0.746453570795711 0.576159414013382 0.650006390542258 0.296922715618275 0.75243169501191 0.44890748973703 0.354760463724379 0.0695469750300981 0.730568173069041 0.961952390561346 0.142731463178061 0.600893754283898 0.923768332037143 0.651937717532273 0.224505255806725 0.484216028377414 0.710769335934892 0.0104701166623272 0.0612851555924863 0.405143083496951 0.383706005860586 0.591188885336742 0.248980319902767 0.874015384027734 0.433329763303045 0.299271836392581 0.796514557749033 0.188806310978252 0.808818300440908 0.840732874493115 0.476677438835613 0.913972977553494 0.679097768049687 0.465001529881265 0.420687107031699 0.034582438999787 0.669507380162831 0.863885902806651 0.563395790806971 0.88266403202666 0.943412469371688 0.267621279717423 0.475586897702888 0.173121527964249 0.216642415630631 0.21442942008609 0.323457657166291 0.348022222553846 0.425814620228484 0.458132090237923 0.787168415209744 0.418143734792247 0.691032975767739 0.777781310791615 0.456299985053483 0.626617419575341 0.797689781982917 0.129897593462374 0.622111339066178 0.901593101783656 0.571032811300829 0.984177031526342 0.107690914392006 0.833619125653058 0.884475291732233 0.771796440463513 0.31978933210019 0.0219179716752842 0.209290972549934 0.267982835541479 0.394948469460942 0.187051048818976 0.756519292534795 0.824972200428601 0.78566536271479 0.685952493345831 0.59857087389566 0.83541379887145 0.679070632392541 0.292752578435466 0.920317198950797 0.664189330276567 0.329863398484886 0.0693358415737748 0.0318901332071982 0.0575618043169379 0.132187535066623 0.302151378311682 0.617738963973243 0.676082641659305 0.154312690070365 0.516784959840588 0.308379391494673 0.23365049688844 0.393702976128552 0.442709334213287 0.747534391644876 0.922936893741135 0.397478521200828 0.459670261838473 0.308816032302566 0.560824061478488 0.341078085401095 0.366552857265342 0.670897246329114 0.675617782985792 0.45749104041839 0.986657928873319 0.304423862360418 0.924311095429584 0.646732544410042 0.753319208994508 0.903337513506413 0.413889206554741 0.796490709746722 0.269700835384429 0.99105948994169 0.880024538007565 0.345294054285623 0.275005208875518 0.0332020151312463 0.48879917780403 0.442301348303445 0.307064248884562 0.567754463227466 0.383954802246299 0.519113168981858 0.721576373013668 0.272596821340267 0.330339015393984 0.38711574095767 0.945381866358221 0.104736074735411 0.598159418234136 0.663596995742992 0.800426632813178 0.101892614730168 0.299989561431576 0.489338843706064 0.610728996505495 0.36478070251178 0.913346074814908 0.18824361881474 0.488659859655891 0.427887604043353 0.307574273338541 0.739876314762514 0.63876663396135 0.420145876479801 0.784267843409907 0.764117649719119 0.804977548331954 0.824587246773299 0.736475335988216 0.783700617956929 0.320445254161023 0.281421022454742 0.896685538066085 0.238523661359213 0.385741038387641 0.841083274234552 0.745069978442043 0.294835014920682 0.558315505925566 0.394390276933555 0.970248670789879 0.62549563039327 0.565939950442407 0.569274169977289 0.428083436293527 0.967511582081206 0.303872554937843 0.342578129610047 0.157309225755744 0.728073538474273 0.688987222346477 0.237759284721687 0.752300380826928 0.0359046612586826 0.336815348053351 0.757429902851582 0.510478863529861 0.0757692699111067 0.739900828916579 0.38285065087257 0.914073756863363 0.476549920793623 0.944042949045543 0.193339159262832 0.589178382868413 0.37530322387116 0.951347983477172 0.546109405406751 0.305330110881478 0.939514343156479 0.038867921626661 0.158511759215035 0.388952495835256 0.0591424918430857 0.71402541148942 0.0795777957187965 0.283837123289704 0.0478704162989743 0.808536479754839 0.804285064912401 0.631964346563909 0.882189849764109 0.807441326500848 0.758892606603913 0.859352343422361 0.797325892322697 0.120432833498344 0.179439263490494 0.908156618033536 0.424023223831318 0.933222941139247 0.930742520240601 0.504575989567675 0.220748427524231 0.340426794593222 0.957381037783343 0.300972473185975 0.492340770149603 0.268725533895195 0.326894610670861 0.934639009658713 0.661154834774788 0.749946285581682 0.237186726597138 0.945383366697934 0.809008134098258 0.0493300347775221 0.125168163334019 0.308125010037329 0.0456182503397577 0.570094032906927 0.578400337682106 0.501604074067436 0.29864237876609 0.222095432241913 0.506272139863577 0.176206800825894 0.935329885324463 0.646845819021109 0.152230999951717 0.556564029767178 0.464388828161173 0.716830249445047 0.827998399459757 0.934426870520692 0.924864956818055 0.882803472110536 0.727411145521328 0.941715317773633 0.0637476938893087 0.144562249197625 0.665893230752554 0.829026435043197 0.384856239953078 0.089054773459211 0.896351531881373 0.558836406632327 0.499304260739591 0.265948384802323 0.877034156504087 0.921981278995518 0.316691189601552 0.585816629829351 0.131408872355241 0.0201178152672946 0.291599667058326 0.258606128392275 0.28763477353612 0.0311800251179375 0.433216817157809 0.569175702836365 0.217549079747405 0.052071529077366 0.341750297523104 0.83414692713879 0.0477119254274294 0.937846850294154 0.0545617218920961 0.752516492442228 0.697442560712807 0.35447442692006 0.274275422110222 0.84994031985756 0.678864471102133 0.0704553720634431 0.326309598966036 0.741452495276462 0.308374873418361 0.723385473603848 0.496776929618791 0.97012516095303 0.913409567836206 0.0392905349843204 0.782072756283451 0.801913519948721 0.204433204021771 0.870998238897882 0.897239113170654 0.610880390901584 0.0601184823038056 0.155620017037727 0.967257172272075 0.314580507129431 0.46806577147916 0.547717799774837 0.530237005476374 0.445136668579653 0.232845926405862 0.909018743566703 0.398335031005554 0.713612113653217 0.83269661542261 0.479717056790832 0.206809453538153 0.673230996285565 0.720120299430564 0.0589358050073497 0.372274915513117 0.45163640529383 0.502086790909525 0.71755421026377 0.168227089510765 0.709707180473488 0.742571768986527 0.715791383248288 0.823268968870398 0.144258625986986 0.292475876053795 0.346822908520699 0.92898427630309 0.0840946706524119 0.37609533846844 0.864436815839726 0.326056351810694 0.124738486462738 0.995012338564266 0.0474163421383128 0.125669457511976 0.32081223831512 0.888573298510164 0.24734883795958 0.658572667839471 0.548735132443253 0.945878963780124 0.782751844751183 0.84341581774177 0.66468283186201 0.136874111583456 0.725052406575996 0.453692089908291 0.148706416143104 0.924956236665603 0.532100340500474 0.685516897635534 0.0134023631713353 0.49569882132113 0.792559845054057 0.720157217837404 0.336084887990728 0.854681628693361 0.282154731217306 0.217086421218701 0.265364695719909 0.20258167302236 0.265907040059101 0.877768506985158 0.10361385658849 0.591251831836998 0.698093753557187 0.579365706825629 0.132980082547292 0.0370768871181645 0.0699172634351999 0.69160268972395 0.0492448242870159 0.118948992451187 0.878833668658044 0.522078662686981 0.81199896669481 0.895292306104675 0.242407995467074 0.414659007603768 0.63591467003338 0.473037692832295 0.699354309064802 0.715304456511512 0.22050275859423 0.358318208060227 0.094298883266747 0.811439368333667 0.339531706303824 0.259250188802835 0.233582489478868 0.644856185773388 0.559545087451115 0.753044888854493 0.138988630997483 0.664330609769095 0.236357983564958 0.86349142433377 0.524324494672474 0.515744428725447 0.348140764604323 0.464676574140321 0.0810593287460506 0.246213571997359 0.174622077664826 0.738649860462174 0.791350003979169 0.705351414226461 0.778396513001062 0.580942041084636 0.503963868943974 0.687444096789695 0.645465668528341 0.323234033940826 0.600260932245292 0.444359051887877 0.523813253857661 0.852851455810014 0.659905142611824 0.785483717191964 0.161508036507294 0.892509671747684 0.257085371473804 0.0742404318111949 0.092855510362424 0.4815884165233 0.200632500310894 0.221995274596848 0.20876829236513 0.975560798610095 0.249049636565614 0.753167668920942 0.916132213729434 0.3682409950695 0.273966960425023 0.988224800089374 0.743117798597086 0.972928925689776 0.183219907043967 0.734730348931625 0.309976768081542 0.248106056808028 0.74476192566799 0.50417588338023 0.523209443765227 0.796107389891986 0.129054079609923 0.587844487740658 0.188047187027987 0.142551188452635 0.110970890503377 0.379038556197193 0.859986300223973 0.109455912970006 0.719445561463945 0.895036180205643 0.44396439431468 0.322319293944165 0.522320748919155 0.706678808035795 0.747940149749629 0.40712996592978 0.493042566555087 0.885982742211781 0.0454387832945213 0.715603959953878 0.193263866365887 0.41239100959152 0.0854148944560438 0.4576364011853 0.0757319557317533 0.998971879822202 0.917709493048023 0.47686540911207 0.0745235241786577 0.996208620569669 0.216767764415126 0.331818309091032 0.986078840156551 0.703664591207635 0.303817129037343 0.806229115170427 0.233560427639168 0.0945810344931669 0.306420386475511 0.393123118455987 0.409414584313054 0.226385656762868 0.426466752830893 0.512744304579683 0.164776389768813 0.510004690487403 0.137892647013068 0.886074397778139 0.0208590492396615 0.315963160647079 0.624830043830443 0.681146809125785 0.550728600097354 0.69564716210356 0.301909111365676 0.265943015941884 0.0399203406693414 0.479245128610637 0.0712180443666875 0.0282733818865381 0.526270881302189 0.97314688985236 0.983393637984991 0.354643801881466 0.76567419673549 0.507412737805862 0.337895745239221 0.0723912616167217 0.0919850701489486 0.0409645934752189 0.965158557749819 0.15834465078311 0.92975808463525 0.636682351613417 0.795179789478425 0.312836438394152 0.71214540630579 0.326575006733183 0.329199965274893 0.425004833247513 0.093090527318418 0.59566188046243 0.997387961114291 0.951204735725187 0.206229043120984 0.0956528254132718 0.809487392252777 0.365993807499763 0.433324890253134 0.0994246769160964 0.0507035205257125 0.0527475474844687 0.19164168542251 0.367195135201328 0.122099824326579 0.355000640705694 0.602545974983368 0.118050235717092 0.929101399150677 0.583091582793277 0.32592015858274 0.728349097333848 0.861083851854783 0.0413944423012435 0.998895339907613 0.931334468913265 0.717011395469308 0.536907533127815 0.0975836370000616 0.0176081320969388 0.626747638643719 0.470208417018876 0.923946022370364 0.125433064226527 0.821183895438444 0.610123425375205 0.903643360373098 0.548962002063636 0.949382202380803 0.0795384819316678 0.670898721774574 0.39653006631881 0.775297240810469 0.834334731684066 0.781342882157769 0.699400638190564 0.545021432070062 0.963513295915909 0.269224792507011 0.769744625522289 0.861129094853532 0.599242216562852 0.423893625966739 0.0963773274514824 0.303414004191291 0.224878167328425 0.682468186363112 0.09327819932485 0.918816864539403 0.97408535245806 0.833099495014176 0.136450122587848 0.777073195625562 0.044578599052038 0.598782260904554 0.531249927252065 0.0231890376284719 0.870018106540665 0.417878251189832 0.230237462611403 0.764161544048693 0.784601463733707 0.925889039516915 0.256259021977894 0.375136841752101 0.164101613308303 0.36924712947337 0.495050161236431 0.142529498643707 0.713461033431813 0.636320039741695 0.473081097344402 0.718788514782209 0.185059701786377 0.496579562223051 0.764074415778741 0.0238937955279835 0.727414795295335 0.815423940070905 0.268333111503161 0.611786081145983 0.0406215679645538 0.141900970172137 0.507975115103181 0.585096406836528 0.913204590636306 0.831602480758447 0.0325575043191202 0.317992479251698 0.312643471288029 0.819136306296568 0.488256007805467 0.280852334233932 0.699883134441916 0.312010436726268 0.409596616618801 0.792684497260489 0.0939798078709282 0.740182785368524 0.408366346352268 0.284708614363335 0.839048067908734 0.282330008652061 0.229247826642822 0.492184480344877 0.0494498263811693 0.264501162969973 0.620762559019495 0.526397681098897 0.074000202966854 0.388770340902265 0.864945748865139 0.987041095905006 0.711258889476303 0.489619765433017 0.979200110577513 0.251187561186962 0.07365027990425 0.431128843314946 0.0911851170891896 0.94504951909883 0.0418373942631297 0.850013741306029 0.394968418055214 0.781949250134639 0.573475919633638 0.152826414918527 0.944954539919272 0.38143147633411 0.449932178196032 0.204508954696357 0.166710545022506 0.0878542534378357 0.171325370080303 0.948859488081653 0.746273225075565 0.534454902051948 0.26429511646973 0.652469598678872 0.152774996301159 0.24539360050112 0.0320735918614082 0.713027949274983 0.345552537532058 0.267646331633441 0.601436944336165 0.15109897715738 0.941536961749662 0.248441314620432 0.762064205356874 0.722870095733087 0.718997694500722 0.225919482612517 0.874092166430783 0.795625739123207 0.819771413765848 0.243044056755025 0.992616152900737 0.116861869161949 0.27649475669954 0.587694234100636 0.152923455249984 0.402271616996732 0.586929322697688 0.557869810524862 0.887776092116255 0.879290610037278 0.704291930056643 0.332565389294177 0.997024002533872 0.0263068253803067 0.330971334245987 0.893853578744456 0.96185008094646 0.0249530314467847 0.939399182344787 0.518362779917661 0.981053734307643 0.735576422512531 0.144537479877472 0.208443522639573 0.29892492645653 0.849828598140739 0.0845045321597718 0.243458630882669 0.913507126797922 0.522845654604025 0.619259285703301 0.739665244002827 0.526519836965017 0.900614420899656 0.544943750938401 0.273869512795936 0.159429238962475 0.455374619360082 0.0639161408483051 0.913580568069592 0.276603698327672 0.958281168541871 0.222064414003398 0.598211801273283 0.559906285305042 0.265202916963026 0.206404581253883 0.111945040172432 0.958989099536557 0.648623176212423 0.108757553815376 0.1966501123528 0.406623512418009 0.337668623449281 0.97408996411832 0.756254535245243 0.0455236563296057 0.20455582043156 0.678059057442006 0.911015073598828 0.143652687666472 0.404280147056561 0.0427347751287743 0.573373654505704 0.126385873528197 0.869952799696475 0.217096701622941 0.302499195504934 0.955746334800497 0.28670169869205 0.32836040799506 0.237280561793596 0.0987270131870173 0.983885074499995 0.964674559545238 0.367246888047084 0.338473574952222 0.696894927036483 0.326993235475384 0.251857708238531 0.187341419528238 0.433872858618852 0.713309193244204 0.14889560831245 0.929060294360388 0.340244980342686 0.76540670084767 0.878953893145081 0.496346201656852 0.359738136110827 0.997887647999451 0.393168864410836 0.0102613336383365 0.896369204034563 0.565222106003203 0.978796067871153 0.349858308283146 0.282571375716943 0.968939261694904 0.306487403877545 0.411693817931227 0.233228492748458 0.791249527088366 0.270008765070234 0.0643840688909404 0.277998134894297 0.654966358735692 0.257351485961117 0.342618514080532 0.0300561349070631 0.779849920363631 0.244262165948749 0.23869746058248 0.807287586743478 0.428600142088253 0.735629558141809 0.410825013362337 0.695098764772993 0.912108173768502 0.704797320491634 0.644126152831595 0.806237522512674 0.0466177126229741 0.602130211233161 0.376956355976872 0.0223036207561381 0.266422501832712 0.92461033656029 0.630077032151166 0.85035518741468 0.48646866871044 0.799886624615174 0.93731599718798 0.0897368960292079 0.415617483113892 0.430178114296868 0.333003851301037 0.903311435393989 0.999590609408915 0.488924271191936 0.144409465794452 0.590407451756764 0.126245056423359 0.851897868562955 0.587336340497714 0.508302264073864 0.690287838929799 0.914051845311187 0.620678613295313 0.452570468992926 0.158624486152548 0.45878985700896 0.949408754636534 0.477215548155364 0.947001828716602 0.801032545778435 0.299255021708086 0.0289605478476733 0.602485456364229 0.0862446461664513 0.4143038413045 0.93733502446441 0.572893827932421 0.468061613678001 0.605962854961399 0.350094691195991 0.919008407602087 0.148916728780605 0.0357839282834902 0.0487619875837117 0.733152578182053 0.845236897307914 0.347296880565118 0.881741746996995 0.582206161080394 0.978663435443304 0.1885876004491 0.611088508004323 0.608903199939523 0.263690817942843 0.0711896854336374 0.444913070017938 0.412508118839469 0.612950794242788 0.694155692120548 0.165944778225385 0.405214837722015 0.591024868863169 0.636350761784706 0.507797316894867 0.655769953501877 0.649474798676092 0.219322827272117 0.242684625240508 0.893491602945142 0.0168273639772087 0.237301239697263 0.377882102229632 0.406458159722388 0.113753671690356 0.923497490407899 0.416034241020679 0.64588150258176 0.337208128415514 0.326895891572349 0.0871677660755813 0.763376792618074 0.282212517692242 0.131435998561792 0.567711802776903 0.249877678640187 0.461673684888519 0.470989903153386 0.0918840259918943 0.366292978327256 0.966277597500011 0.530037583843805 0.51037356706569 0.144108479761053 0.514180601984263 0.44730755872326 0.686206441228278 0.753028685692698 0.491734054344706 0.456982476196718 0.799695714050904 0.149234737872612 0.72742764326511 0.225090607963502 0.623728642810602 0.52449613800738 0.175931520874146 0.521345254729968 0.340734609258361 0.139246255853213 0.806074179797433 0.563238356788643 0.73397465209011 0.905211642032955 0.734794911022764 0.21473326434847 0.514607861577533 0.967366686468013 0.96492322869366 0.217703703020234 0.857552240951918 0.213195988710504 0.349646520430688 0.148589799709152 0.527960509995464 0.819432359349448 0.855937945262995 0.702428969368339 0.555864784331061 0.765391102985013 0.203277739139739 0.92401618889533 0.552223723081406 0.348738498424645 0.239989699558355 0.846853926754557 0.382731251814403 0.180569240576588 0.981101982826367 0.481503535651136 0.54168838510057 0.0924901583953761 0.439783744381275 0.244998725794721 0.945831597624347 0.77032952935202 0.984057359553408 0.2917606065562 0.974355953442864 0.388183916218113 0.307457938578445 0.66964426812483 0.674279482497368 0.404172128359787 0.294385263831355 0.847583205723204 0.187418316029944 0.283228413178585 0.94792391090421 0.590644529634155 0.228639116531704 0.614647393096238 0.517133645105641 0.376789726759307 0.706763941769022 0.513906747458968 0.0629452387266792 0.495496877531987 0.921467051792424 0.291918189479038 0.42172133713495 0.0354103035875596 0.373721397663467 0.579570816103369 0.897947847465985 0.348896301938221 0.59542582832044 0.120629485184327 0.716353334346786 0.865245177163742 0.502347954898141 0.203031605286524 0.901372424147557 0.600133215279784 0.231398065160029 0.386146900679451 0.239984446871094 0.050187352723442 0.616607554776128 0.129088225073647 0.652332474451978 0.0267433804413304 0.723882606523111 0.846733391089365 0.848073344510049 0.133099002852105 0.0442488426389173 0.631991580184549 0.979498355477117 0.201240537355188 0.161574544729665 0.474760172488168 0.200468392558396 0.303975883142557 0.125102787108626 0.974448127869982 0.645494820619933 0.841862431142945 0.446971256504767 0.0617560435156338 0.237989532584324 0.532246463538613 0.314953116923571 0.692610595999286 0.407179092431907 0.55334868328413 0.584726415087935 0.303672118403483 0.255491914809681 0.0839596248650923 0.180384394298308 0.927536299114581 0.102167482774239 0.73306664806325 0.186072385683656 0.412071558246389 0.879284190316685 0.633806820204482 0.553065676894039 0.715995889070909 0.39052091833204 0.170648076534271 0.882747940639965 0.254760241152253 0.691569482865743 0.733381351060234 0.577813806736376 0.702222667241003 0.374695337344892 0.741110693502706 0.919746249963064 0.283708604406565 0.23834595304681 0.0195323739061132 0.368356176856905 0.885210499681998 0.926337406670209 0.569222444100305 0.88341023493791 0.690503305138554 0.898017767122947 0.862747515842784 0.98762364791939 0.164638949292712 0.77072547520278 0.184387629579287 0.896335086922627 0.0178494355431758 0.143458482071292 0.0534495504200459 0.285151278427802 0.715700311544351 0.548903523851186 0.553748523702379 0.299355024686083 0.751849608151242 0.8804221086693 0.373943357814569 0.866929564694874 0.0620646923687309 0.866139214592986 0.931829677138012 0.812524819974788 0.650203891398851 0.918112531916704 0.252503579705954 0.636583683243953 0.446162231564522 0.426991993205156 0.315673497579992 0.0372351011564024 0.577435617172159 0.172396911596879 0.0389712519058958 0.263209920225199 0.259863981259987 0.243943128355313 0.591180485140067 0.912593990406022 0.0318558245478198 0.102046017493121 0.807279750816524 0.847855680922512 0.362094555050135 0.189639899630565 0.52355556584429 0.487352602300234 0.83666816032026 0.873697039785329 0.820981800900772 0.119430396812968 0.706545367236249 0.154057843228802 0.12264638478402 0.587129520201124 0.224535941891372 0.853679777022917 0.71020817730343 0.195530335456133 0.465312829050235 0.324393215903547 0.415556223890744 0.257025412053335 0.27510187394917 0.0235858711437322 0.833957564397715 0.858510562716983 0.785985070609022 0.867961675329134 0.0662346361600794 0.588236453507561 0.547079763773363 0.809134611883201 0.705607956182212 0.927568370518275 0.499419363234192 0.103066568896174 0.47591825495474 0.885217479984276 0.537228775245603 0.493698156231549 0.193551781072747 0.411932352352887 0.362117556417361 0.678279462854844 0.183485760833137 0.556425235550851 0.36666359934723 0.0285076384153217 0.45267846994102 0.322366814767011 0.235814956016839 0.122941082022153 0.11430397112621 0.731927493065596 0.615891144752968 0.958961771870963 0.18448358470574 0.639110555895604 0.712343825944699 0.580051820313092 0.875489928915631 0.0360470211156644 0.393542888336815 0.700155368074775 0.656973098022863 0.702020799978636 0.785993087710813 0.146470355382189 0.36451780237956 0.4361590031581 0.144429374511819 0.209113979947288 0.371019097520038 0.20242241342552 0.69377172708977 0.927013086238876 0.737870787226129 0.59894102008082 0.0766680787387304 0.171618011698592 0.0262009823950939 0.804366910068784 0.685503055739682 0.805910663744435 0.797953240161296 0.664761072883848 0.988585077547468 0.0507458995329216 0.443019787438679 0.11339718415169 0.909735385475215 0.643837482999079 0.154961459413171 0.473095485761296 0.733464878422674 0.693393295037094 0.531655136530753 0.3066858970467 0.920350275575183 0.877168948738836 0.164563383019995 0.390902939767111 0.947886982124765 0.477391636958346 0.46936839596834 0.200903290077113 0.167522600376979 0.613447136769537 0.687199780677911 0.729782191908453 0.977119843580294 0.766256707489956 0.50027424500091 0.887765376062598 0.333698419614229 0.715458013941534 0.122946245505009 0.516841162764467 0.839178333999589 0.641477545672096 0.35677606720943 0.581152958099265 0.916704689334147 0.523354097811971 0.922572496284265 0.0154996559931897 0.971650646396447 0.388730057622306 0.841294857170433 0.162906880048104 0.749554693920072 0.71330284451833 0.0472588196070865 0.841840817630291 0.387843417704571 0.36041964877164 0.756159556526691 0.30639755130047 0.437653803669382 0.29184921695618 0.300476513523608 0.245122659064364 0.47558743938338 0.983718768677209 0.134164281620178 0.174962451015599 0.383471595817246 0.921037164703012 0.16396733348025 0.74838627088815 0.0455442408798262 0.0435700722644106 0.595699510429986 0.425769849529024 0.779022954504471 0.838770411247387 0.476576306396164 0.958300255979411 0.152023583806586 0.105781925613992 0.796692560412921 0.175547072479967 0.967764014641289 0.681516534413677 0.528557785807643 0.222000252755824 0.222237669241149 0.421112475583795 0.647218891894445 0.888396541711409 0.702921342414338 0.0157023763447069 0.273171583989169 0.900099220746197 0.784046518523246 0.657010058150627 0.878593491676729 0.420795300218742 0.645568502305541 0.0270284599694423 0.461918302727863 0.914158802083693 0.723683539403137 0.329017495936714 0.349406472300179 0.426231831302866 0.606717150809709 0.619687696194742 0.720614581957925 0.0579789195023477 0.992545086725149 0.471495663083624 0.74952417886816 0.108259690664709 0.792960597570054 0.296121616731398 0.226285146679729 0.18170160912443 0.264409280589316 0.896493160815444 0.600884466653224 0.913260087762028 0.909015936970245 0.391793822310865 0.532426022554282 0.436504328851588 0.997069040846545 0.415685906119179 0.60125123367412 0.16813003258314 0.997532301216852 0.133993972202297 0.524244621463586 0.653620905759744 0.854194983860944 0.0982382258353755 0.223335463129915 0.703178558819927 0.10147550761234 0.991708672805689 0.442236525975168 0.945618212851696 0.746629532591905 0.765541853357572 0.496723728065845 0.34175513161812 0.449134492818266 0.502359510441311 0.936627702226397 0.793391571708489 0.326308472270612 0.367369008646347 0.415652475904208 0.757921181011479 0.750416977577843 0.118624536669813 0.801429917055648 0.918941802107729 0.84165226303041 0.482436047377996 0.187017820985056 0.303605718286708 0.806540862666443 0.304728948799893 0.125757054162677 0.543484957888722 0.516796548806597 0.982930322294123 0.540426448883954 0.502437338172458 0.24553124404978 0.699760574044194 0.647138555606361 0.824215442584828 0.40623369009234 0.871943808582146 0.583950016601011 0.187839961969294 0.35866443063831 0.128833788526244 0.883332981618587 0.873015595583711 0.982169096623547 0.0479583990410902 0.946699375074822 0.537931462081615 0.650453693927266 0.628091519824229 0.242215892053209 0.419519205165561 0.0340191277069971 0.884281818212476 0.0876661471650004 0.203173935178202 0.0587959786015563 0.645813142503612 0.695484929718077 0.382742658453062 0.790978687764145 0.358558359225281 0.852837945837527 0.102456235126592 0.375008349837735 0.784350602969062 0.473676898172125 0.58943088988075 0.656660315801855 0.602296297617722 0.996678978798445 0.495347643634304 0.17514233665308 0.0271382652898319 0.726561205033213 0.306055312955286 0.729851530469023 0.290968618965708 0.0458879555924796 0.146990905725397 0.98646784973098 0.396655306767207 0.562164128306322 0.121929315293673 0.436902776805218 0.286320979825687 0.72686262187548 0.425492133167572 0.228970646660309 0.283651222693734 0.511585324767511 0.607206434893887 0.45639912111219 0.0480668842745945 0.493782626809552 0.829111198359169 0.180179946562275 0.950316571725998 0.907008778629825 0.96389217422111 0.256193391508423 0.38836728082737 0.746961643586401 0.966149598399643 0.555041633746587 0.910764642951544 0.471923462052364 0.618991513904184 0.8545815208368 0.730841077924706 0.51343029613141 0.0622196408803575 0.502153609849047 0.790552590133157 0.252769077599514 0.650594845721498 0.287917336209212 0.938058686091099 0.309930683057755 0.849713783774059 0.0353567643486895 0.312104118177667 0.435729464357719 0.915718012554571 0.855338194316719 0.16366715305252 0.206160739054903 0.329193300530314 0.950121867554262 0.348866027530748 0.842808663982432 0.117645324938931 0.31576776473783 0.217459993360098 0.597442214130424 0.750581740878988 0.388776673031971 0.0247500453260727 0.362989818060305 0.25379522606032 0.627395519400015 0.368741191595327 0.728903403361328 0.725329637038521 0.543742334723938 0.756232016780414 0.738152036727406 0.913425017716363 0.438836761487182 0.369407770931721 0.0689864087896422 0.449625399408396 0.930451134399045 0.632708946561906 0.703807105501182 0.59879427860491 0.485397171450313 0.516699720998295 0.334604483272415 0.97948887422448 0.234834380403627 0.0101932987989858 0.676669697458856 0.357588614225388 0.355930680064484 0.26435432353057 0.900781642969232 0.989691420998424 0.894920792349149 0.592294420185499 0.439690326163545 0.650636513859499 0.881517940061167 0.0166624206537381 0.187910152236 0.524065352419857 0.821306122299284 0.904553931273986 0.988051209931727 0.917402362513822 0.91599407275673 0.822971718357876 0.153490451353136 0.597634697181638 0.72358290530974 0.881678380751982 0.0983770785992965 0.778492220337503 0.795373414207716 0.653668229964096 0.460365483856294 0.187828835160471 0.335149972354993 0.707238848269917 0.21416300410172 0.500993209450971 0.63750985131599 0.58701968583744 0.812158150686882 0.915078676519915 0.292959253515583 0.565082534532994 0.0928774108504876 0.655174124783371 0.724708439002279 0.233377252502833 0.29131429917179 0.296764168965165 0.259237780170515 0.774266806619707 0.172325970123056 0.0690028629684821 0.582731863842346 0.972901345624123 0.440765687795356 0.33896849620156 0.965372099955566 0.309529538457282 0.540899218858685 0.765288548807148 0.524121471671388 0.342725847493857 0.195593669430818 0.185089836048428 0.329542228514329 0.449763783100061 0.33982940007234 0.447338201012462 0.844293659846298 0.67884678673232 0.924538184949197 0.692895209451672 0.92423639630666 0.838978048674762 0.284191997542512 0.497935357147362 0.90241491706809 0.79834207570646 0.579603611975908 0.844692042567767 0.305013291412033 0.0392180473008193 0.979570898481179 0.107363076219335 0.222592481258325 0.540897556936834 0.0718894481169991 0.0753151759272441 0.201759970223065 0.631422856927384 0.108730679778382 0.444387421654537 0.581986922700889 0.116775974310003 0.144235319204163 0.335556172332726 0.495877792555839 0.368554097688757 0.471966468256433 0.319141277084127 0.905900610061362 0.287292577142362 0.182774698233698 0.587999835943337 0.855276600634679 0.851337548729498 0.328741179185454 0.467536395431962 0.64568932863418 0.556842211051844 0.0314607746596448 0.471250069758389 0.272437518869992 0.556818087138236 0.0462991710705683 0.0400503366114572 0.379200347401202 0.899100632527843 0.0305075642839074 0.950492518770043 0.611841536550783 0.176353258553427 0.364082808510866 0.876095700813457 0.785600484143943 0.220520965973847 0.385024125177879 0.149299973030575 0.539299101599026 0.145798806184903 0.264392952956259 0.78852653705515 0.398308629498351 0.163569066931959 0.31602868254995 0.13568423869554 0.266287870719098 0.762274564325344 0.630035040387884 0.708055976980831 0.282129696588963 0.615562515726779 0.804953497948591 0.238808359175455 0.787796458243392 0.267395940402057 0.79047286398476 0.609030644912273 0.0664080324652605 0.784516303031705 0.715988692787942 0.36263465706259 0.825520846932195 0.117222355224658 0.183362701397855 0.844390187310055 0.585558075127192 0.47413819581503 0.401451479769312 0.195928372885101 0.619940469437279 0.246605268537533 0.829930471894331 0.215514235540759 0.738651351351291 0.760916679436341 0.147389695513994 0.384704863536172 0.980337145875674 0.929786959432531 0.68102496051928 0.604930239527021 0.191083822282963 0.29593416116666 0.618994205479976 0.957439192140009 0.0880741999205202 0.220014513614587 0.371075991720427 0.440320173799992 0.632948518474586 0.62134006556822 0.960465662011411 0.935226302414667 0.983732427323703 0.675978873656131 0.31082090198528 0.241737943151966 0.845695808329619 0.310440721111372 0.672959350203164 0.0278831847640686 0.428504613391124 0.918763002827764 0.478441880058963 0.206578737294767 0.890841269553639 0.663887559152208 0.757646768440027 0.688233299681451 0.112127075935714 0.154938358468935 0.521629997263663 0.500162172459532 0.390737738742027 0.371505333902314 0.968780573282856 0.419420536335092 0.104988638912328 0.474135080806445 0.148996987158898 0.354963098790031 0.905581435088534 0.942153974324465 0.0215400441922247 0.672508982750587 0.678002172922716 0.6381870243093 0.106446816290263 0.551167068327777 0.198592683016323 0.912850312001538 0.158559153031092 0.0110096931294538 0.856835267811548 0.0242523301579058 0.878455582589377 0.216773970229551 0.836780574696604 0.640830063684844 0.296486214725301 0.689851071576122 0.634643404695671 0.122733429381624 0.297980602406897 0.163388103004545 0.907222769162618 0.278802630233113 0.984075932509731 0.590063283415511 0.590536295187194 0.495197997828946 0.264753637250979 0.146564413704909 0.770679762440268 0.091605768641457 0.334694116411265 0.370541911581531 0.529221537341364 0.905147266418207 0.349658884576056 0.66371405266691 0.308665858646855 0.760454167046119 0.499424702359829 0.0417201660759747 0.201020228292327 0.389763330910355 0.94537922226591 0.103994090938941 0.322844540080987 0.14334385786904 0.81040105949156 0.115124969510362 0.0769128835154697 0.998697086691391 0.964064645059407 0.0975284540490247 0.339214945151471 0.756740329524036 0.589719358484726 0.754449235869106 0.262894867095165 0.66466396732023 0.905298905838281 0.505089732024353 0.754932457972318 0.798077664170414 0.26810808129143 0.298719445609022 0.42150687845191 0.306240541406441 0.995911543625407 0.0858446941850707 0.672552429905627 0.363003843205515 0.906320140219759 0.250557155734859 0.913423858750611 0.835984854351263 0.28894220192451 0.647383686313406 0.669609618782997 0.488392786509357 0.610161670784 0.629254556708038 0.503290045841131 0.353668752331287 0.0668701232667081 0.253751239990816 0.22134604355786 0.408457890124992 0.0270999094704166 0.167184251528233 0.0235991434683092 0.506475602663122 0.658080446003005 0.02542058077408 0.563648397857323 0.142761475043371 0.807314206766896 0.0325171710201539 0.337683285472449 0.342866883806419 0.337398598259315 0.987597137384582 0.491872982252389 0.755475622208323 0.372459684573114 0.82163221049821 0.349264300763607 0.5315291803726 0.109933101444039 0.224050423754379 0.388857221612707 0.175467228314374 0.233716704996768 0.345461899172515 0.688945962197613 0.872347360318527 0.249621627423912 0.536616647706833 0.107688282516319 0.572809646404348 0.069137893312145 0.666936737422366 0.438977281935513 0.119575904179364 0.10584137216676 0.344247509595007 0.874216703155544 0.6289607268502 0.77362705913838 0.662108538425528 0.678383781758603 0.0199841444264166 0.343253215865698 0.425862368787639 0.88036516306689 0.265075054320041 0.307680853931233 0.128394199823961 0.415499887736514 0.341531279042829 0.231506056657527 0.840392789731268 0.210823612094391 0.826453753279056 0.196809209214989 0.0904270546021871 0.329480285160244 0.488643761372659 0.814542382268701 0.646844743727706 0.60592079058988 0.378135099059436 0.867257475475781 0.849749464383349 0.815425694424193 0.561021705938037 0.748294935259037 0.632407115967944 0.899159729869571 0.768059142413549 0.221014778737444 0.283861168371513 0.568664273931645 0.0468489629402757 0.149190716766752 0.36487740492681 0.217731877320912 0.592553229823243 0.379156022954267 0.438656358141452 0.813474501590244 0.926075468885247 0.466756121970247 0.481261559599079 0.18555853396887 0.298908284418285 0.0481028903531842 0.106085983782541 0.813593104262836 0.783227178142406 0.386737680705264 0.0511023416626267 0.909566917771008 0.520281588556245 0.443490085045341 0.555034381682053 0.9885206505307 0.42306637221016 0.874864306617528 0.493969874461181 0.415923721604049 0.223823145914357 0.0934386709029786 0.809712819159031 0.154719579019584 0.11106116789626 0.0792772628529929 0.51636823927518 0.615744832933415 0.427952531711198 0.843956428933889 0.470519460099749 0.253055401840247 0.151647824889515 0.24217557719443 0.949241270946804 0.291492868179921 0.264257500332315 0.20593603315996 0.62596354506677 0.331161710505839 0.450665682503022 0.352352907611057 0.983873707738239 0.676778532594908 0.733163189587649 0.48118792516645 0.81019746807171 0.712690556088928 0.989742425864097 0.837625187584199 0.264325211085379 0.749246881790459 0.273770728022791 0.214355687459465 0.96505082556745 0.20849750536494 0.976388841376174 0.710043627216946 0.637885210542008 0.240804056478664 0.672773391520604 0.891926842669491 0.122245354512706 0.548976619830355 0.0960297942371108 0.829253154606558 0.966527299990412 0.429509614415001 0.610860094018281 0.40965517366305 0.829936300145928 0.816829028381035 0.892693008005153 0.142478564772755 0.177070887011942 0.865482254580129 0.475058133869898 0.938183041180018 0.473040593934711 0.289635886030737 0.503983971283305 0.396019117550459 0.106042707199231 0.69414939226117 0.148849339117296 0.925282130551059 0.534915097663179 0.254947147660423 0.307255055953283 0.209738641050644 0.24438112659147 0.846391653395258 0.59996243517613 0.934495653801132 0.757637433786877 0.916327306989115 0.305466435726266 0.623312072993722 0.0241988985636272 0.38794092272874 0.44876825641375 0.820130155156367 0.315007206602022 0.777510595016647 0.854513459028676 0.964895413054619 0.0941754718543962 0.631480995148886 0.379624014615547 0.777213394984137 0.641247929846868 0.718791695022956 0.0545629891939461 0.0545385176828131 0.332723823462147 0.286484694802202 0.862030407397542 0.707458721913863 0.66856733054854 0.113111845308449 0.617680758214556 0.507169477625284 0.565268962057307 0.639324944736436 0.511422966066748 0.409156376977917 0.387319236949552 0.0504640504950657 0.536955560825299 0.498354728720151 0.217881421705242 0.652519128329586 0.764568424469326 0.0123729692376219 0.275824835540261 0.410682102143764 0.335269440102857 0.159268975527957 0.749247571914457 0.470894494778477 0.597069359773304 0.463537722483743 0.511548316925764 0.595063341727946 0.859786310633644 0.687646877532825 0.953838146787602 0.0497491083107889 0.433931648700964 0.975208044517785 0.41565610055346 0.527999701846857 0.452605437580496 0.494496753937565 0.925919123759959 0.449876924019773 0.739442870330531 0.0697565864794888 0.0230912066739984 0.952871837655548 0.458207137419377 0.408013553535566 0.50545909196604 0.174105998836458 0.194057810229715 0.426532534970902 0.657468486500438 0.821348359086551 0.785901851889212 0.487021824761759 0.652683696625754 0.702153006899171 0.599765909805428 0.843353264939506 0.622300468999892 0.686143590155989 0.0255158148892224 0.156035512944218 0.145949547798373 0.223543966554571 0.299875274454244 0.429530014102347 0.84652125056833 0.536823327166494 0.505754476101138 0.676362373533193 0.576495853611268 0.763395434725098 0.0263907303055748 0.633907953796443 0.0999053782457486 0.176371575421654 0.19716413510032 0.382982559753582 0.762337656042073 0.734400837081485 0.15843880268978 0.55771374108037 0.863297420889139 0.11795756686246 0.910951119572856 0.810085884195287 0.903504155401606 0.140878532107454 0.286836596727371 0.704543663733639 0.90317619828973 0.605805597507861 0.471694042154122 0.845384665671736 0.348119150861166 0.799337199474685 0.173563939859159 0.456382152913138 0.371635248246603 0.870929072292056 0.572710719180759 0.533351151752286 0.234723236556165 0.424855480641127 0.0422593523026444 0.0589975042594597 0.141092494749464 0.236619744554628 0.487545729605481 0.609139934598934 0.511603563725948 0.782221267786808 0.0461786533845589 0.142502166137565 0.31594038286712 0.266741177306976 0.506045685838908 0.0927888527745381 0.976066697072238 0.37378013565205 0.689419920872897 0.844347083372995 0.491333782887086 0.843158507060725 0.0789141045766883 0.20394481520867 0.379926383201964 0.882446679386776 0.146265902575105 0.537874844714534 0.0188933986076154 0.581959728726651 0.649644795532804 0.186255617754068 0.0553543991455808 0.186997630824335 0.481734591193963 0.302216318196151 0.781534840124659 0.531153952993918 0.890716876431834 0.0737672692909837 0.886843935132492 0.930152392075397 0.698962686976884 0.784156387692783 0.454254778614268 0.0971555263921618 0.309446732336655 0.938892121459357 0.574255597246811 0.107104687939864 0.86270409588702 0.0781872442690656 0.411984958518296 0.981920715142041 0.817288302674424 0.476185136784334 0.514874794348143 0.130167371553835 0.358957585124299 0.602370495628566 0.834813885882031 0.0975201880047098 0.462112402752973 0.686301591901574 0.728821259934921 0.349666643976234 0.70237339571584 0.544284598387312 0.26805763585493 0.593342066446785 0.953503386629745 0.732467795615084 0.0119305843114853 0.0291024307953194 0.557175516048446 0.918468492988031 0.933526083522011 0.59645124055678 0.505461174093653 0.850042330510914 0.939143992054742 0.994493581529241 0.408245662704576 0.508283488044981 0.288246114139911 0.272015894597862 0.128603420341387 0.869295112218242 0.671496625244618 0.690748694930226 0.991806510675233 0.944426176007837 0.23677930818405 0.166779970251955 0.582241067432333 0.0888322144630365 0.200373752447776 0.76278344640974 0.775301748283673 0.028110449926462 0.709288630411029 0.537279220221099 0.0662326031294651 0.44146105802618 0.78557431336958 0.381090098915156 0.828098645387217 0.619561043228023 0.609196652695537 0.212298935388681 0.946558666536584 0.648003163188696 0.714029037752189 0.0704278560774401 0.658140781603288 0.219878343897872 0.871889029471204 0.98681419839384 0.48810351206921 0.802157145936508 0.198634817691054 0.0708639033418149 0.0733162870886736 0.964974218807183 0.743336595564615 0.219232332746033 0.578352158775087 0.426349477621261 0.44438837063266 0.0498644028138369 0.977154916124418 0.598795358277857 0.946193149529863 0.548469133898616 0.56252378686564 0.67223179838853 0.971653519147076 0.699533115029335 0.358095680642873 0.137689498388208 0.522846348877065 0.731542695460375 0.934684631603304 0.498503668266349 0.187916382714175 0.322344385737088 0.547472369875759 0.355709354947321 0.326526107045356 0.450987676519435 0.452166858708952 0.128717910160776 0.997759012251627 0.897258680975065 0.71587010002695 0.782452112189494 0.308315164092928 0.846927750660107 0.413000602757093 0.646309960095678 0.0932263863179833 0.100380053322297 0.957369277093094 0.96804382073693 0.928410226828419 0.356879362682812 0.55996830979595 0.313873262109701 0.401072408303153 0.193996052660514 0.804034565805923 0.960875078418758 0.738418044261634 0.761576853112783 0.702864559085574 0.465037605802063 0.548842851947993 0.44245594161097 0.454003138521221 0.363500613083597 0.530872393928003 0.69404536425136 0.82066414240282 0.473474617388565 0.84031264429912 0.169743011873215 0.977577605778351 0.23309031581739 0.684903629801702 0.542446199336555 0.136395592419431 0.792993907693308 0.873104018815793 0.376001716256142 0.165124540268444 0.533950571236201 0.191504409525078 0.176493240317795 0.0246454820898361 0.568890328265261 0.995584075869992 0.865616867945064 0.306797016691417 0.780466372587252 0.594496471940074 0.922911020314787 0.0850966553227045 0.640706980277319 0.0787080062134191 0.18261466461001 0.599624158935621 0.73348710852908 0.104404028512072 0.401041309849825 0.875299986922182 0.204421574026346 0.781785637731664 0.731875561580528 0.203155587883666 0.740524913533591 0.375952684720978 0.52857566080289 0.060063427281566 0.0310296829650179 0.864384928611107 0.353292638210114 0.493806009427644 0.993021120843478 0.817630110671744 0.162359422475565 0.514905580009799 0.0751508538075723 0.134646072764881 0.954131410992704 0.345670843778644 0.939788382544648 0.528456798584666 0.422493908591568 0.199094815300778 0.341304816259071 0.879396471462678 0.0582646209257655 0.570876040668227 0.379817185255233 0.524581404509954 0.847758540322539 0.0384491790947504 0.729823612717446 0.257631811609026 0.504387334468774 0.565441204698291 0.543121798459906 0.0444947487558238 0.0244280932610854 0.163998837617692 0.767612353509758 0.791320650198031 0.482859425311908 0.502209510123357 0.747024213215336 0.992028117696755 0.152756942205597 0.635225482336245 0.566417057779618 0.0270938518689945 0.667372346501797 0.0512648400478065 0.0212525586807169 0.0604385774419643 0.606063296815846 0.578554426881019 0.313324067471549 0.34825739532942 0.873612438281998 0.49881234316621 0.452765561791603 0.225186199818272 0.591381449063774 0.67443644536892 0.314019041468855 0.0981655993894674 0.746874683813658 0.216995246019214 0.136671926458366 0.50557338954648 0.110719183103647 0.564583081838209 0.0307190070743673 0.841398637851234 0.420601413869299 0.27426388892578 0.453627639841288 0.258343320230488 0.0188816736452281 0.521884100735188 0.969785668812692 0.491657297988422 0.874055198235437 0.501460728121456 0.116490740575828 0.735731868448202 0.482208493165672 0.435318276309408 0.913764231179375 0.80429211436538 0.837597165645566 0.577928913149517 0.72202173095895 0.085738262035884 0.282958841617219 0.876331978156231 0.318250043485314 0.255746176636312 0.675368797588162 0.312660822581965 0.231322502575349 0.862643453488126 0.353243338831235 0.79606208511861 0.596014836935792 0.513166963346303 0.310061898357235 0.595092076379806 0.256615102449432 0.103261628272012 0.996500188047066 0.894800359026995 0.37494234318845 0.849495406781789 0.549838750895578 0.818907666648738 0.116787975875195 0.891252490794286 0.246365114836954 0.599963946349453 0.566991456004325 0.500969776352867 0.705442292538937 0.715752172034699 0.639417947588954 0.218978575258516 0.466277602114715 0.601119734395761 0.196076979355421 0.304954947582446 0.972834390918724 0.555497548237909 0.745871559770312 0.724518686942756 0.017589962289203 0.995066999658011 0.755495028200094 0.498513017441146 0.625811891586054 0.453141348599456 0.0125029670237564 0.49509642789606 0.0488564160931855 0.0819657941698097 0.42314050775487 0.68456208688207 0.843161692603026 0.473515602778643 0.383511739643291 0.577065553045832 0.826978235761635 0.649837987609208 0.591432165571023 0.387160652494058 0.21175919480389 0.869893484299537 0.414555221160408 0.902666413558181 0.0874809147953056 0.674176289597526 0.451725944157224 0.900577541908715 0.092076113501098 0.756548290189821 0.779272814197466 0.162598472300451 0.19411887974944 0.470550120137632 0.152859189815354 0.704408951252699 0.449988488764502 0.719091888819821 0.795323780600447 0.632461070572026 0.866942143898923 0.223750586083625 0.149708649525419 0.356174828370567 0.125982260478195 0.15964011517819 0.833427393578459 0.688360275581945 0.14989457685966 0.776139885208104 0.543608996036928 0.439606226463802 0.299518336514011 0.919717722302303 0.486680963668041 0.514631750378758 0.885517483155709 0.149280402229633 0.605412023065146 0.284645394487306 0.0675200093933381 0.467698203462642 0.16492473945953 0.785425166140776 0.224950461850967 0.0117105838912539 0.674207371454686 0.427923025568016 0.119657216183841 0.904673268788029 0.547388341862243 0.382197724650614 0.446616902265232 0.441469404285308 0.921647330897395 0.55450324367499 0.409151775920764 0.525851439195685 0.0811830773833208 0.643513922027778 0.383141143287066 0.596798395747319 0.15778911087662 0.731719103278592 0.899957786125597 0.686716870674863 0.58883995634038 0.620897199122701 0.387049478220288 0.530549117627088 0.501800500091631 0.562933196127415 0.78166894223541 0.26004513143329 0.708301919978112 0.413969304042403 0.922645895374008 0.936707191187888 0.855169991229195 0.780503051502164 0.36119406954851 0.126003522474784 0.367041499400511 0.343547702424694 0.682208114264067 0.657381310516503 0.183035172098316 0.793829732909799 0.365560074478854 0.248088473398238 0.268683584544342 0.643003731842618 0.256959980276879 0.257265927181579 0.382260120250285 0.652701957020909 0.015324324159883 0.412380825076252 0.0790075954026543 0.774026767017785 0.734062382893171 0.510031361682341 0.291827008977998 0.145293963653967 0.165651168727782 0.121906506165396 0.283783506602049 0.0436110053304583 0.0854314631945454 0.715377039161976 0.773697551824152 0.299567234588321 0.23232224238338 0.936675222588237 0.138167250901461 0.0595146039826795 0.534868347870652 0.985637122534681 0.859676337738056 0.442077433031518 0.0435690375394188 0.229346045763232 0.181640654625371 0.441510441538412 0.949292388758622 0.504072430473752 0.89370290950872 0.968121613892727 0.0586289778142236 0.324418620257638 0.661710839834996 0.791330917233136 0.0330510695232078 0.90081427795114 0.446585839309264 0.580679025931749 0.503162191035226 0.467115440999623 0.541579117542133 0.56989295557607 0.598425036910921 0.562000147791114 0.636711452302989 0.494023099755868 0.180682755601592 0.0832375848223455 0.0700516651989892 0.927492481081281 0.855725137437694 0.51878572358517 0.633586856203619 0.054274932728149 0.499409641337115 0.0376296437089331 0.757789242395665 0.146756978353951 0.272454594022129 0.783302499391139 0.626171573195606 0.714328110155184 0.614639557630289 0.654623065611813 0.3030324147176 0.0580026259762235 0.469498792062514 0.294808822018094 0.714830828837585 0.71385908653494 0.691521211296786 0.0490456324652769 0.128272955825087 0.10327611672692 0.209418779180851 0.470856173764914 0.729136945793871 0.192823130453471 0.543437335414346 0.27435279321624 0.428757776874118 0.971693768082187 0.0195562454196624 0.372131005066913 0.460310471937992 0.640869969401974 0.5121497108927 0.109064439556096 0.586623236339074 0.4264328964171 0.349205129430629 0.708947801357135 0.189091948783025 0.506080718506128 0.235746287757065 0.332355506543536 0.617822744427249 0.0292189935222268 0.355817712252028 0.66722550567938 0.617587248948403 0.29878282614518 0.702212931052782 0.246409650193527 0.116390549046919 0.573518353500403 0.73199130325811 0.61366494303802 0.616360213090666 0.78983309160918 0.417269440579694 0.0652991675492376 0.609366571181454 0.0923397122859023 0.134243843650911 0.319180157757364 0.0567206690181047 0.393150624069385 0.715811864533462 0.431455011728685 0.918070217911154 0.190318277920596 0.880368769275956 0.874853153070435 0.979584255861118 0.757387028725352 0.933562534239609 0.794570792622399 0.174880139322486 0.827175325171556 0.330453428917099 0.644393812837079 0.876421059011482 0.493044338426553 0.872093278053217 0.705406443893444 0.979114003202412 0.269965430400334 0.523649451751262 0.285547244332265 0.357966765295714 0.10443285766989 0.417945439163595 0.34690171404276 0.995146691000555 0.156512414442841 0.145450362025294 0.632808359684423 0.941335536590777 0.316464460357092 0.880012380392291 0.558712197451387 0.11076139776269 0.900451955937315 0.0192150530940853 0.144196872566827 0.258548763967119 0.909425012234133 0.053710483906325 0.716060654926114 0.28310181484092 0.557983337996993 0.875361044455785 0.852690115468577 0.862806819714606 0.714699551071972 0.131992567430716 0.319882554851938 0.989065136236604 0.305373874516226 0.231852603321895 0.44386536244303 0.428621583185159 0.229368716129102 0.32566111567663 0.544096004141029 0.186323718056083 0.664493651909288 0.238374458809849 0.993928194332402 0.196961656315252 0.686537403168622 0.252918107502628 0.900610786569305 0.446163249462843 0.920198240382597 0.270399229344912 0.481852160294075 0.772042306934018 0.778667486016639 0.120168976781424 0.240550859111827 0.418456934452988 0.80872104505077 0.223888436623383 0.0853813480678946 0.354442109800875 0.504873376768082 0.374523737113923 0.718484035255387 0.98344973441679 0.644427264488768 0.440550053780898 0.0891936992923729 0.643685116344132 0.67207973230863 0.572306905593723 0.230703507910948 0.688449408991728 0.819648439385928 0.63850022881059 0.335059063385706 0.891937973396853 0.515875932383351 0.749404935629573 0.292268745270558 0.490912028150633 0.301383608218748 0.494400493626017 0.485615083980374 0.833962069104891 0.833565524870064 0.0523987686354667 0.308331141592935 0.828361745364964 0.733484175156336 0.28541338932002 0.954910729252733 0.608904618681408 0.170589959979989 0.588839196374174 0.807779928902164 0.712454193921294 0.583233323981985 0.227604036566336 0.443613835757133 0.900168819774408 0.533969475654885 0.255798038740177 0.209330780303571 0.762608934012242 0.287518245845567 0.67396559179062 0.0235745267407037 0.793658495489508 0.881642384584993 0.722079810863361 0.570553997785319 0.41625241194386 0.168067078706808 0.0230016574379988 0.0172100455709733 0.409084539541509 0.298771222888026 0.713056812316645 0.857600337108597 0.601760905690025 0.553232669152785 0.509478245507926 0.0311665430362336 0.278729243590497 0.890673417290673 0.711788084579166 0.159548797528259 0.392102605546825 0.512634595378768 0.684793057830539 0.0484167912020348 0.286019157760311 0.855910529545508 0.393710911863018 0.58524768713396 0.0995104468357749 0.52912427342264 0.482727326727472 0.899706274191849 0.130627023410052 0.0681286220019683 0.142939127343707 0.517835190724582 0.756427510653157 0.254352651245426 0.0891183114284649 0.373838281710632 0.980539022127632 0.310432374621742 0.355306357799564 0.945527853169479 0.656937162938993 0.0298453990672715 0.239482708745636 0.688371726707555 0.640484646251425 0.310452994669322 0.853319902021904 0.931216421290301 0.214268569562119 0.137413518400863 0.500009564929642 0.303162683574483 0.872077572315466 0.819419568774756 0.722240382249001 0.994864108504262 0.551415616923478 0.224696378202643 0.466483562637586 0.188466791408136 0.0233907359326258 0.134580541641917 0.133470024485141 0.580717458277941 0.0663464240310714 0.540218798087444 0.660330941511784 0.192932296821382 0.46026331738336 0.579524299809709 0.512773695241194 0.230123641248792 0.520025357317645 0.747793423025869 0.331651197662577 0.158982569228392 0.831627520688344 0.678692420008592 0.601341768538114 0.647612069412135 0.312728687310591 0.138141806439962 0.972843841053545 0.544856167887337 0.408383891729172 0.380126915855799 0.83284570018528 0.899972475117538 0.597784629501402 0.545726792502683 0.206268435739912 0.397480229453649 0.409063669859897 0.901204288597219 0.243041410357691 0.699147730334662 0.121614737920463 0.499609981982503 0.464390924118925 0.430243326404598 0.277378735698294 0.614413401875645 0.149629022262525 0.0108579112589359 0.4717649200093 0.904362891628407 0.201714858380146 0.413843050536234 0.394138143335003 0.48992959146155 0.822965256455354 0.524984062588774 0.83801512838807 0.894462963074911 0.600793083310127 0.109594477145001 0.888712049392052 0.775821246614214 0.736686723458115 0.906190377546009 0.313789547809865 0.878785031973384 0.907644268963486 0.820364398085512 0.549186097127385 0.0924061294598505 0.676604787539691 0.744744480559602 0.736509181798901 0.796558676818386 0.355457526764367 0.551226424062625 0.0141973804845475 0.503281139691826 0.803339899298735 0.890365992404986 0.322913321286906 0.452795199321117 0.0511791620985605 0.322784900136758 0.627530329383444 0.253797968577128 0.0565864246874116 0.14246686170809 0.0220178948994726 0.0262084730295464 0.413396995782387 0.484564561971929 0.992447828568984 0.68957882872317 0.103140410319902 0.122764859527815 0.173493146137334 0.635816435699817 0.673561929413117 0.702649816193152 0.523957532185595 0.114857517187484 0.55600590131944 0.14924285731744 0.336756719553377 0.426599176193122 0.0855684611061588 0.772004771241918 0.376673311553895 0.0346862729266286 0.694786740213167 0.591910209669732 0.48728342209477 0.606503521935083 0.115562897443306 0.329756638100371 0.781547614333685 0.0812179392483085 0.204873300059699 0.467435258612968 0.653816832746379 0.464422533826437 0.346307433608454 0.243036901962478 0.608879818704445 0.747989365225658 0.617595383836888 0.860558162000962 0.859411677028984 0.527848402878735 0.299003627561033 0.597191841339227 0.663846115523484 0.801539220341947 0.196671244346071 0.876476710804272 0.960908968946896 0.266476888398174 0.784536338986363 0.217167325234041 0.79876593677327 0.767646243576892 0.921574712288566 0.964349855051842 0.803028708465863 0.708762419621926 0.206636240712833 0.636267772645224 0.748413802778814 0.0906408236222342 0.357138873508666 0.95211709324969 0.725154522338416 0.0116472983220592 0.0548236453859136 0.917050002119504 0.180174305478577 0.338030106665101 0.626860766424797 0.359506704849191 0.417542699717451 0.621430583605543 0.266538751767948 0.84116017396329 0.434131372752599 0.592252794920933 0.395991888078861 0.912987189590931 0.849585210953373 0.525268722602632 0.606373582696542 0.984159437743947 0.598586526617873 0.350309906618204 0.553378525960725 0.717048823977821 0.922120470828377 0.190023716448341 0.438012357430998 0.718688582107425 0.94505265439162 0.394264789847657 0.633985611647367 0.651828050974291 0.191493885018863 0.218634446794167 0.0102197337290272 0.39094952106243 0.21740560909966 0.90017923848005 0.166390996635891 0.380600111568347 0.629062421254348 0.0786528882640414 0.0457032363209873 0.118102579109836 0.939760440820828 0.464123643981293 0.584297742515337 0.902793020193931 0.53744316754397 0.704030194883235 0.366360117665026 0.101068595151883 0.745947224006522 0.446085004752968 0.451229351304937 0.834429141753353 0.498688460607082 0.683402798888273 0.137228492561262 0.444168870171998 0.970788228816818 0.582510414023418 0.419526995683555 0.510045701924246 0.621833699692506 0.248960700926837 0.287133983927779 0.66115678275004 0.296558972557541 0.87985322521301 0.739219968116377 0.0401806799205951 0.567085510639008 0.636166767673567 0.681586928905454 0.626354213566519 0.422015175290871 0.477611341183074 0.949915433349088 0.827897802016232 0.68148637203034 0.926797323373612 0.911255428527947 0.109811289256904 0.668958401966374 0.466462482968345 0.39988364528399 0.793624418484978 0.850262663315516 0.959799956970382 0.443206692333333 0.922229818140622 0.741067696288228 0.373634623675607 0.901923862725962 0.167285792878829 0.578360154209658 0.243257110295817 0.177289033501875 0.521691069088411 0.848463596261572 0.308970086004119 0.98083693994442 0.368926742980257 0.074781069511082 0.585552629509475 0.795448223280255 0.619891114276834 0.479966904267203 0.455548014973756 0.488933454174548 0.941115466097835 0.478321594258305 0.625844482081011 0.996732595255598 0.538468580471817 0.521684773608576 0.942188540685456 0.988608187250793 0.811630851235241 0.256965263851453 0.734905308964662 0.299497308246791 0.599903483742382 0.142792535924818 0.82608554631006 0.648933727401309 0.532179971220903 0.44460978818126 0.577069352876861 0.853788025761023 0.227281997601967 0.404222228964791 0.51612879459979 0.309189666679595 0.421688552557025 0.174340474111959 0.964647239947226 0.568735663271509 0.876843499492388 0.725752438947093 0.523169972545002 0.389799687582999 0.81686847885605 0.410817446201108 0.151901864972897 0.594761390120257 0.807241046708077 0.470374769403134 0.547393376033288 0.68953636880964 0.658271945500746 0.113646645075642 0.289739692988805 0.692660606016871 0.141711541046388 0.828397901270073 0.739157958838623 0.73598914294038 0.0383784072706476 0.33489357215818 0.872628971247468 0.793053615635727 0.795477329501882 0.413023770086002 0.858915307994466 0.397725330656394 0.116504902869929 0.500119576088618 0.227565205912106 0.189650632510893 0.384573436635546 0.524240019484423 0.794350103691686 0.344897445740644 0.430958693404682 0.601205387450755 0.610626791999675 0.717882411708124 0.791177234870847 0.386155029574875 0.82635220893193 0.854557288817596 0.158817265168764 0.668035246790387 0.124007259979844 0.267147575055715 0.982386436124798 0.528018747102469 0.835426393058151 0.883339083245955 0.228602039769758 0.29189229438547 0.193335808680858 0.5199048656784 0.0526051728753373 0.499757261220366 0.524629072854295 0.255319148467388 0.730664199190214 0.636808662975673 0.408679048358463 0.114169257953763 0.778342124361079 0.233942786760163 0.0266849792166613 0.676777081352193 0.810722384129185 0.72436161020305 0.774387223115191 0.153987844048534 0.773907624969725 0.772624894445762 0.0218330795085058 0.71975281762192 0.949581525588874 0.955633110438939 0.78011832051212 0.187912128332537 0.829223625643644 0.490924980076961 0.128478597102221 0.0377087251422927 0.845449713661801 0.436502887289971 0.0624464962095954 0.792427876011934 0.99193224923918 0.512986647360958 0.727931783455424 0.629626930698287 0.624287507482804 0.738222939015832 0.413071572813205 0.23773128998233 0.192996923453175 0.666789879542775 0.773380780990701 0.469682951674331 0.507965797968209 0.8114845603914 0.27889979780186 0.213721663812175 0.723633126467466 0.301925193052739 0.0268442962085828 0.44315331260208 0.380172359161079 0.752111617622431 0.14278455155436 0.548008492495865 0.0183661927399226 0.193579813614488 0.43517211592989 0.100946202559862 0.178346145572141 0.0456079973652959 0.705642529227771 0.628713408675976 0.323272843849845 0.722814168259502 0.825421992777847 0.482618258323055 0.535232170454692 0.990371837390121 0.363277455011848 0.896094185472466 0.762172450637445 0.343246420656797 0.51220490306383 0.422883402220905 0.192182531035505 0.947517814652529 0.0467986399005167 0.683903367675375 0.830339763599914 0.705114063664805 0.681128917303868 0.912809182086494 0.5558483280777 0.584970122904051 0.0582547538122162 0.88668360323878 0.732919165983331 0.431325033074245 0.574293698361144 0.160666175587103 0.120526982408483 0.0975991207640618 0.774088668420445 0.845323314247653 0.847542729512788 0.676871868753806 0.335064540582243 0.948428236648906 0.666599609313998 0.281454195198603 0.322946998830885 0.926998250647448 0.140189869264141 0.443749112046789 0.912265066797845 0.563056215224788 0.639587735841051 0.0405582595756277 0.287691821712069 0.595736555382609 0.888525437696371 0.8175154576567 0.800073554173578 0.0443831054097973 0.95969160312321 0.131822192319669 0.845571063230745 0.381199981684331 0.286241166777909 0.971783943823539 0.900445298107807 0.598988213590346 0.996851734537631 0.10655243384419 0.961383453167509 0.814762178002857 0.899564382715616 0.304302400536835 0.344748723327648 0.53950343408389 0.888603457666468 0.313145251364913 0.851427029736806 0.524017370361835 0.75695637636818 0.774399219609331 0.893759081084281 0.871690579866991 0.624044153718278 0.744041336406954 0.279089002418332 0.872056121998467 0.824662807744462 0.430778378571849 0.797435927453917 0.145079411156476 0.0846997063257731 0.401913340068422 0.582137517714873 0.98261879308382 0.596195462485775 0.52153514877893 0.49711797419237 0.161012525402475 0.564883876093663 0.442846245456021 0.0460324388369918 0.274423030044418 0.428869790176395 0.101418371153995 0.915995139060542 0.195920382521581 0.105246146442369 0.0948695107037201 0.058272012444213 0.335199778839014 0.278636811000761 0.598702623960562 0.432792346642818 0.748706152811646 0.560181627031416 0.649714998246636 0.40458888488356 0.118198852560017 0.174222063678317 0.579638995467685 0.92492326584179 0.351062669625971 0.971414762060158 0.854085129674058 0.504507049084641 0.109926559326705 0.409246828861069 0.511070498258341 0.230803933630232 0.56481965768151 0.566755519344006 0.401432306123897 0.856508747651242 0.430016979102511 0.11084679011954 0.595374355304521 0.946221935583744 0.25617817674065 0.922828410351649 0.990667006927542 0.285029172580689 0.611313523233402 0.502521944055334 0.941563701173291 0.417246416392736 0.40265954966424 0.470713405688293 0.865420165318064 0.931949189142324 0.494792281445116 0.903255486253183 0.601787912726868 0.166270416022744 0.589508078428917 0.464603414312005 0.158543689320795 0.372825873033144 0.895156957898289 0.432558901251759 0.232253953299951 0.966365762338974 0.948968262134586 0.109727255941834 0.70617868273519 0.722907011143398 0.990250718784519 0.112059475362767 0.190150685433764 0.345060247927904 0.843291788122151 0.648908107066527 0.928951927374583 0.294900913925376 0.599825702803209 0.770490156288724 0.309969912481029 0.577239763485268 0.205187796065584 0.141542223480064 0.419638815594371 0.0514255665615201 0.215788998245262 0.458765679618809 0.369456020602956 0.293004512649495 0.998601652039215 0.295410368347075 0.436634782110341 0.112780625896994 0.674029660606757 0.43174324936932 0.717430325399619 0.309121602796949 0.653303599008359 0.556220968298148 0.591065711572301 0.734834231263958 0.919839148859028 0.707129483900499 0.261708206948824 0.0884042101167142 0.681584862682503 0.964472177571151 0.585753595277201 0.200787055355031 0.0582408118783496 0.980908710304648 0.538340951558202 0.441760903764516 0.258102419010829 0.653972271305975 0.554261775419582 0.907044707490131 0.390578944298904 0.477680187390652 0.460153944254853 0.942598245451227 0.710140082533471 0.558720297764521 0.0746861428860575 0.18676770266844 0.801127486925106 0.982980489975307 0.293552798186429 0.648183955852874 0.78533168914495 0.0408884597057477 0.215348891604226 0.198447833273094 0.330254062144086 0.0419586274283938 0.891116565179545 0.19908646028256 0.882709727731999 0.800279373859521 0.35640687668696 0.616530841984786 0.260068019623868 0.212211171393283 0.484290236299858 0.567359235852491 0.188763793208636 0.700250231311657 0.782662042884622 0.986017307327129 0.0166810035216622 0.372803374622017 0.522824675894808 0.843535324905533 0.0847463076747954 0.159267220713664 0.560026275371201 0.413930271698628 0.0779072035220452 0.773973837457597 0.0314929977338761 0.780820286106318 0.806656565619633 0.423298327634111 0.302310869563371 0.57605557409348 0.331194372917525 0.915687532769516 0.0828705951361917 0.740602884637192 0.0980505973938852 0.671085518563632 0.318442269756924 0.967396753653884 0.710950584993698 0.872011020067148 0.0490952172060497 0.37768832444679 0.830522653143853 0.269162048157305 0.591691690457519 0.0794903203123249 0.824281057149638 0.452682921632659 0.943871947890148 0.913536330061033 0.258013198701665 0.543462486215867 0.435219346089289 0.930483191511594 0.297599460568745 0.652492915373296 0.230686265644617 0.0951439550844952 0.647273594017606 0.683080009638797 0.814329474405386 0.965513005112298 0.591354198616464 0.216880247250665 0.123111375996377 0.0231725638569333 0.478823481288273 0.643252468528226 0.0557530729915015 0.029108697923366 0.151843713382259 0.966711009431165 0.0154714994411916 0.32711114825448 0.329362843988929 0.210885681533255 0.103865466485731 0.403865754334256 0.873071274345275 0.562450087661855 0.949304458783008 0.754986710846424 0.439713039863855 0.0782053308654577 0.967077255286276 0.547124027137179 0.455802719595376 0.0798417925811373 0.314862119210884 0.658491276311688 0.289702550533693 0.145569202345796 0.687056810220238 0.531245979208034 0.604179189843126 0.083985482386779 0.0961352732591331 0.204759297752753 0.848787468641531 0.45317418734543 0.908322321553715 0.930386327283923 0.104961814663839 0.93815163892461 0.140002499907278 0.999372190465219 0.557128077745438 0.478136909101158 0.49161974431714 0.955154238606337 0.594082087285351 0.633065431565046 0.0254643155960366 0.0210408259183168 0.626426564562134 0.202005704846233 0.961113324942999 0.175097264917567 0.465587351110298 0.317338704089634 0.117327688338701 0.306554337376729 0.406593776925001 0.0413240376673639 0.48698127225507 0.540242487273645 0.601961160358041 0.945279703803826 0.126719778061379 0.867757080071606 0.483931614309549 0.205456739969086 0.346121656792238 0.760338746919297 0.785488223512657 0.644435299108736 0.603446248883847 0.502829974701162 0.927876244422514 0.991607275749557 0.767918912859168 0.803532111279201 0.583465054435655 0.395909472890198 0.575455318347085 0.62851989481831 0.174697784313466 0.916817368096672 0.758409593796823 0.288146128910594 0.793852376998402 0.698947250004858 0.643348305637483 0.777976110621821 0.372457066988573 0.0655847885273397 0.19377772960579 0.336427483153529 0.11654858098831 0.109675521997269 0.908796868240461 0.378081344761886 0.398198626867961 0.686474202885292 0.8587793404283 0.632812461243011 0.874812613471877 0.402012276512105 0.286403868235648 0.102075852563139 0.108364429082721 0.073463670744095 0.260939055916388 0.204866765087936 0.0906970708025619 0.417317222331185 0.378826479525305 0.0674534011329524 0.753838020428084 0.88978301811032 0.0324179369979538 0.994128381232731 0.477240585549735 0.561874570117798 0.0578589008538984 0.823380019364413 0.718122997600585 0.884915761183947 0.766867677445989 0.474993370550219 0.841587137822062 0.682211342679802 0.24394505512435 0.852474637504201 0.351888101492077 0.357485301694833 0.426479289161507 0.110235639680177 0.633243057818618 0.587385740606114 0.871588063030504 0.0617896638950333 0.0767612772877328 0.509895377981011 0.606093933111988 0.411570909244474 0.836359814808238 0.450766937800217 0.630883217302617 0.527796057872474 0.0382478530518711 0.22863525607856 0.872806041068397 0.644393872767687 0.822921034120955 0.272719925031997 0.77145012314897 0.197231352347881 0.302605933069717 0.338357891822234 0.0877280160668306 0.911257293291856 0.557407802934758 0.979257468548603 0.780930825576652 0.856363755918574 0.423615399503615 0.550981136613991 0.0957098127366044 0.967110789688304 0.772747808895074 0.359187383507378 0.940711983281653 0.665831128351856 0.416203782404773 0.99674752788851 0.973153732544743 0.482686045602895 0.883712166722398 0.631346452087164 0.197954393001273 0.519407517469954 0.284830484406557 0.775506168359425 0.97047652649926 0.651334701750893 0.393604836761951 0.44043454421917 0.469919316607993 0.0989755329699255 0.955972958474886 0.399855247857049 0.685256780127529 0.723651301346254 0.941780187815893 0.375529049546458 0.249982038803864 0.231534260923509 0.980124525448773 0.657849368331954 0.528824391264934 0.900850326903164 0.344284827923402 0.987898570823017 0.158251538441982 0.906591845541261 0.704410177986138 0.0416013414296322 0.907393929134123 0.132234057122841 0.541412897466216 0.468996705648024 0.440626518090721 0.936247840367723 0.553677403358743 0.153123149566818 0.205841627009213 0.112955055774655 0.639659562904853 0.190860884340946 0.541830357944127 0.578335347087123 0.732119789640419 0.399529471758287 0.387464892759454 0.901767762163654 0.880275915327948 0.564712640056387 0.939371651606634 0.524737371611409 0.128203792676795 0.0380537760769948 0.74177865262609 0.891647177410778 0.92176700102631 0.338810751696583 0.313228760517668 0.158551740767434 0.389816667307168 0.412701403577812 0.910317984742578 0.101696143297013 0.629065172760747 0.724572317460552 0.300961953520309 0.832495203402359 0.859287590475287 0.247419959455729 0.230375226712786 0.344198142909445 0.189004318478983 0.838019167711027 0.802388104668353 0.946594555750489 0.753796317945234 0.862824080651626 0.721070994564798 0.929707892520819 0.0912319848989136 0.313515402390622 0.933964750214946 0.0434341544867493 0.882268145415001 0.309536197208799 0.630830270454753 0.230631184806116 0.633250979722943 0.632828507663216 0.112001954657026 0.656393516492099 0.996597495991737 0.94034549954813 0.867469029829372 0.229935305856634 0.965008478830569 0.466301731560379 0.0403521220269613 0.56811174553819 0.268414390315302 0.122957337968983 0.422099167115521 0.194895151460078 0.836591911991127 0.599534191798884 0.488283806156833 0.523817033404484 0.63577058740193 0.822635538997129 0.325687185029965 0.62366211384302 0.239473698870279 0.214407217639964 0.664145177092869 0.535160179503728 0.902813554955646 0.228277906461153 0.779808032095898 0.31450646424666 0.876481552044861 0.842660033309367 0.139181054809596 0.742933064573444 0.345498894106131 0.847514565815218 0.487993343477137 0.579617602084763 0.644414278678596 0.803668760210276 0.132284654921386 0.578923712831456 0.315959527008235 0.303538155285642 0.577832273661625 0.846993907366414 0.551755863728467 0.79152962730499 0.972801796505228 0.0524137600464746 0.448152544102632 0.526383623222355 0.734207489185501 0.96719370322302 0.442382101109251 0.85611765387468 0.278315931924153 0.196878983194474 0.0598318047029898 0.517459799689241 0.517760949148797 0.849285511814523 0.54724569295533 0.780381209349725 0.300576040053274 0.766417952172924 0.697745226877742 0.423616347329225 0.835141479952726 0.290936452825554 0.723596976785921 0.900655419197865 0.244344466116745 0.614545690624509 0.735279714833014 0.398748253697995 0.152954011792317 0.277693020794541 0.0476954355207272 0.488099452231545 0.417784708961844 0.961442833566107 0.677937261851039 0.559557360317558 0.147648298621643 0.615724320069421 0.536751186619513 0.548385137924924 0.293563676974736 0.609875418459997 0.742114639747888 0.236423183686566 0.232247026704717 0.111921011917293 0.113609512071125 0.305044692053925 0.813737146556377 0.475868477975018 0.0305682016117498 0.341226999131031 0.553879590097349 0.587695511544589 0.0651994787459262 0.695378060766961 0.861905505326577 0.980497832051478 0.631540263523348 0.480946970931254 0.166387870793696 0.862642972890753 0.994276953127701 0.852646453715861 0.991767056281678 0.124485564776696 0.701448429252487 0.672722126878798 0.913395929473918 0.097730845012702 0.548786002234556 0.788519032821059 0.609519068992231 0.666547643714584 0.406421647460666 0.572261990369298 0.0357448231009766 0.923073297878727 0.928797847626265 0.780244201065507 0.379403061759658 0.807405288151931 0.534204854269046 0.991994506998453 0.909855001897085 0.439806154279504 0.718918489979114 0.405830560175236 0.111494279943872 0.599657058995217 0.921685734200291 0.729969597684685 0.109218569553923 0.553800073706079 0.732203930600081 0.346253608546685 0.600306759797968 0.22599726262968 0.63441421460826 0.429432972618379 0.186524518092629 0.0814140351931564 0.169098274707794 0.830505063741002 0.884736388183665 0.0174814892723225 0.765884571147617 0.757526487940922 0.232507341983728 0.694450161161367 0.667294647160452 0.98478319412563 0.81950071781408 0.897345703444444 0.546983735116664 0.245766382711008 0.125877390443347 0.325790876736864 0.809889160823077 0.918227732144296 0.835686790856998 0.666982634125743 0.510691506084986 0.278286128432956 0.921839583215769 0.456005217742641 0.17643297548173 0.745539788536262 0.788233541846275 0.237798766775522 0.33616050704848 0.629883297933266 0.105769525279757 0.201049740198068 0.137602856247686 0.890732806909364 0.211099985318724 0.395853131664917 0.431549603894819 0.777075261618011 0.477242382315453 0.104474785353523 0.960190031696111 0.30087520811474 0.386329150579404 0.539120609809179 0.432555142450146 0.289055131243076 0.398608058718964 0.947241257487331 0.197631857765373 0.708139218520373 0.307815542670432 0.203189744181 0.0646483981376514 0.0605657856888138 0.0790328160463832 0.412393919683527 0.669604811656754 0.251719492352568 0.626305813838262 0.0348423958476633 0.978143198583275 0.515553765029181 0.0968543158494867 0.795690470172558 0.884798646403942 0.53594101193361 0.116528708920814 0.560308053414337 0.0428592943353578 0.688021606795955 0.596545556811616 0.836613821238279 0.960420557314064 0.391965207713656 0.149297971578781 0.177487572310492 0.524483726839535 0.488571271614637 0.244960913269315 0.545848015756346 0.986260814145207 0.688935477798805 0.545718543285038 0.494583098269068 0.754232194176875 0.646287520462647 0.27078473482281 0.0409767750627361 0.355255079327617 0.644776515176054 0.247676508557051 0.0267014315514825 0.498004856368061 0.876381716642063 0.481823846769985 0.628981166644953 0.122186449409928 0.759683339339681 0.435428724500816 0.748971361424774 0.0812513563246466 0.392465839427896 0.367449648045003 0.96998071343638 0.524638032019138 0.2422316411254 0.47685079918243 0.480261997277848 0.53636060847668 0.910700862493832 0.622972360032145 0.19825547745917 0.205745541879442 0.29796678863233 0.806590591010172 0.399015074213967 0.246811151611619 0.82180788785452 0.092944850763306 0.682025528983213 0.184010460448917 0.226172623506282 0.772384740514681 0.345428175067063 0.568693709080108 0.625108836407308 0.393326763582882 0.319439184989315 0.296495825750753 0.144263893887401 0.883843830809928 0.75390485757729 0.770340100880712 0.262625600027386 0.755109318266623 0.93274716357002 0.767955393081065 0.590194995447528 0.678401636469644 0.0992590593732893 0.388614479370881 0.903050328108948 0.980987916209269 0.911397120619658 0.684331685735378 0.795874469354749 0.759521054399665 0.325632827507798 0.157572718739975 0.823321065395139 0.341944125324953 0.591852446475532 0.0357991534238681 0.294250680201221 0.2621907647443 0.668214145647362 0.0855275902757421 0.708852807886433 0.593455661686603 0.422097580106929 0.0347623368538916 0.302623080599587 0.562643592068926 0.0566973311174661 0.600789075796492 0.164360455907881 0.168164603093173 0.917543152188882 0.0549815302668139 0.162211419229861 0.0462091693584807 0.508647016738541 0.69178999661468 0.652138899050187 0.525689785601571 0.218755197057035 0.39170965830097 0.729048199628014 0.266645545114297 0.0294770570239052 0.0300479947170243 0.325368108251132 0.658642253498547 0.676900555922184 0.218160151124466 0.512090405176859 0.590167303127237 0.997654450398404 0.0188078880030662 0.624927960070781 0.230040869242512 0.556037300117314 0.985042760502547 0.0942835818300955 0.732514916977379 0.91454345931299 0.401873053330928 0.945022189589217 0.737443159520626 0.878468841314316 0.778925430118106 0.0654720265534706 0.947182571361773 0.142141774811316 0.728832074874081 0.313115338154603 0.481525597490836 0.390353819350712 0.384717251423281 0.338485419084318 0.187015538320411 0.831437339663971 0.845883999427315 0.638329519701656 0.568435597633943 0.781539582018741 0.788014681260102 0.469839740977623 0.300682491564658 0.17752779427683 0.0460407943162136 0.7717740715947 0.0174560256791301 0.876836976045743 0.0590259565459564 0.317663355106488 0.210016765401233 0.990145120362286 0.195303318314254 0.328606543692295 0.14317251395667 0.582856036142912 0.828363601139281 0.875875976074021 0.231764884504955 0.644198885308579 0.157658046095166 0.761362327123061 0.614952095288318 0.910442006294616 0.538963475213386 0.295359883725178 0.251173211724963 0.865227227024734 0.750471494607627 0.6894436695287 0.271790815980639 0.622107922560535 0.792884532720782 0.803324779728428 0.11408530715853 0.454218781064264 0.054175231247209 0.403294724440202 0.464812748236582 0.824189770156518 0.292954812427051 0.282717620921321 0.508009104977827 0.335746746363584 0.192847490401473 0.432074723485857 0.994592561537866 0.254925537835807 0.301801177724265 0.825749978933018 0.756290383890737 0.36680590572767 0.647925233806018 0.567261156416498 0.515518516611774 0.676669264575467 0.359646085463464 0.736929882217664 0.137697535774205 0.093270051528234 0.483847305774689 0.407091617716942 0.312086628812831 0.442028493927792 0.644967181868851 0.754510902389884 0.729635636447929 0.638956004539505 0.056984347095713 0.381070983586833 0.413738470934331 0.0475153933721595 0.0553164379461668 0.617327243695036 0.0181842685397714 0.216731812735088 0.12433096247958 0.197564984427299 0.443678351517301 0.866519737071358 0.603480312519241 0.758740313479211 0.6561541202222 0.711311221574433 0.0274386370345019 0.147095715829637 0.237467518551275 0.622509643647354 0.436082278841641 0.758453392006923 0.194115522943903 0.980595717404503 0.385036851442419 0.802822228621226 0.665285507882945 0.339363443746697 0.263539352321532 0.725873834616505 0.340730146733113 0.43797640575096 0.149978977134451 0.341724378226791 0.366444781173486 0.177391864282545 0.471753020326141 0.186709196334705 0.242853687410243 0.503494884509128 0.847368292950559 0.647368477999698 0.938745461581275 0.635920567435678 0.92927281820681 0.59583872646559 0.527047402416356 0.243225602700841 0.889313227378298 0.0402761899470352 0.89434405475622 0.104435752779245 0.527666667921003 0.67975746643031 0.969303459767252 0.249577938702423 0.453717813277617 0.347672954578884 0.847456009462476 0.518385713747703 0.37423959042877 0.01816812092904 0.615780884190463 0.647580317945685 0.843859068665188 0.73312831573654 0.142461617088411 0.489725353482645 0.954676144719124 0.169262639931403 0.573952371652704 0.178106138932053 0.752084199138917 0.958758867578581 0.518580517957453 0.65962882355554 0.720387976262718 0.294969915261027 0.503019574398641 0.119334082794376 0.359996364652179 0.400781075477134 0.828137767165899 0.366436055507511 0.504451222340576 0.263357868150342 0.219456807677634 0.0295636385423131 0.582253346983343 0.798244354240596 0.032376307353843 0.333757170510944 0.369390698776115 0.585943066354375 0.705368196640629 0.279506307307165 0.59988936662674 0.318168570820708 0.40920834349934 0.443867044649087 0.638641261665616 0.0980262185446918 0.5329089394724 0.316874236348085 0.265024776228238 0.70782617145218 0.34664061666932 0.0735155925480649 0.0968712135148235 0.870015537822619 0.380478793808725 0.0645937720802613 0.715264772998635 0.393060347137507 0.0467119790893048 0.132971618501469 0.218975070931483 0.829626238774508 0.593588049551472 0.189228525797371 0.453513243605848 0.22802294021938 0.997801275085658 0.0569660618063062 0.572412696946412 0.465090545734856 0.546454287844244 0.651304513551295 0.145726819152478 0.321988122246694 0.741887165980879 0.790531533283647 0.188564771497622 0.741153490871657 0.811324398838915 0.676355815972202 0.122795791097451 0.607500640931539 0.759820536635816 0.580378317884169 0.696114702671766 0.0593766239006072 0.714214178381953 0.797313056800049 0.334333964807447 0.684453518667724 0.213040840353351 0.803527288478799 0.397806441662833 0.202433218683582 0.891196080418304 0.966650745747611 0.291279663199093 0.338533710937481 0.827647389809135 0.878791767943185 0.0734838074282743 0.420160133971367 0.47953676961828 0.525157517672051 0.613500199560076 0.721859389084857 0.695444627306424 0.855541348704137 0.505200852130074 0.776646085167304 0.794375617303886 0.868782564224675 0.271752258471679 0.490893568601459 0.0322528166486882 0.285019624482375 0.0496654384979047 0.634266020276118 0.381620497701224 0.450283988842275 0.47109725615941 0.293959410532843 0.695836889960337 0.55079305339139 0.67641960288398 0.558884997216519 0.253118139735889 0.68734678838402 0.739626358028036 0.64623268856667 0.702229360337369 0.358555542947724 0.75743057130836 0.247000287768897 0.110436141216196 0.544054518791381 0.878547594742849 0.670310966630932 0.186024869240355 0.180074359895661 0.890616843258031 0.074651810254436 0.490326006845571 0.753432334701065 0.143025166720618 0.824470319391694 0.0448822402418591 0.710248041760642 0.726498264295515 0.479166015137453 0.517795133797918 0.784499516468495 0.394140390041284 0.612009661267512 0.750424302250613 0.730078220297582 0.16350039613666 0.0712229187996127 0.816809171757195 0.85281460217433 0.476728921993636 0.581350510357879 0.534304881910794 0.0912440793565474 0.123063381260727 0.54375409172615 0.607592524003703 0.572241009585559 0.234635378746316 0.623961047944613 0.693243000598159 0.639895700102206 0.172893246747553 0.927171105041634 0.855041971614119 0.68827019227203 0.771515882930253 0.0245597170107067 0.129242314733565 0.110386177990586 0.435306405669544 0.749789905189536 0.535892190616578 0.843086821064353 0.204071473476943 0.419916501990519 0.677800017532427 0.78232688879827 0.351585847926326 0.888613042414654 0.0510938972095028 0.940310821163002 0.951684449352324 0.90168693167856 0.484659963201266 0.104174374192953 0.341771981799975 0.193148762027267 0.0867970835114829 0.627382331900299 0.593561151081231 0.608382355014328 0.710223724916577 0.78998469322687 0.685915325304959 0.758079884636682 0.333298588185571 0.592154996236786 0.76468773455359 0.970336097099353 0.42136376531329 0.574391750597861 0.950986618739553 0.11138500293484 0.122668575244024 0.565097265476361 0.130820055287331 0.0462438097107224 0.597014783504419 0.58647255949676 0.414723370771389 0.25322729527019 0.449739710588474 0.0330925693945028 0.21331928026164 0.428085048196372 0.536294822187629 0.270886270641349 0.0662954493612051 0.366782251808327 0.264110063661356 0.976229057847522 0.897932481027674 0.612936682198197 0.644342620112002 0.550747433060314 0.525078510229941 0.404374781635124 0.292660024370998 0.3271946046222 0.406791419771034 0.870438465815969 0.0691628401190974 0.608836263674311 0.420806379313581 0.224249201824423 0.877201332012191 0.113392313406803 0.241886805940885 0.384263579028193 0.248452126563061 0.549197913368698 0.323820414599031 0.156894056701567 0.0223171980353072 0.913173726834357 0.193492366559803 0.2799522917578 0.0767272964026779 0.0495573969813995 0.118662065677345 0.0427641222253442 0.350586726095062 0.818412372907624 0.7990062137926 0.137344567314722 0.297965335545596 0.636567248657811 0.560317966628354 0.904016173700802 0.511819525284227 0.0485242666047998 0.87761970550986 0.205352787333541 0.340663697980344 0.664641358959489 0.264209248356055 0.725508649072144 0.503264755585696 0.478346701494884 0.572710460787639 0.484379724452738 0.998234461816028 0.943787967821118 0.428197829762939 0.448800052367151 0.878081105726305 0.669829674523789 0.35319853609195 0.416068492284976 0.38340493431082 0.954876093510538 0.681488605136983 0.349336131284945 0.0752335179387592 0.956196646471508 0.720719865283463 0.981445059508551 0.786396567991469 0.441005906728096 0.669674555209931 0.401224725169595 0.624108753842302 0.347336916746572 0.253252097782679 0.650168727575801 0.294465186598245 0.0595519273821265 0.723951245970093 0.606292404844426 0.796424604442436 0.198156833061948 0.0623514688550495 0.853032952658832 0.895546767315827 0.71861101599643 0.452209189541172 0.89922525960952 0.570655627187807 0.409017824328039 0.309268054992426 0.499590741721913 0.921165540213697 0.767072162292898 0.738515810675453 0.580233351276256 0.567803140019532 0.784037749292329 0.560146427250002 0.29694128373405 0.351236996469088 0.125510312013794 0.820143532820512 0.907001618535724 0.87485977609409 0.8425890086242 0.215830961426254 0.9354742032988 0.634420782541856 0.229891207071487 0.0519843060709536 0.782864501385484 0.377343542047311 0.956312304015737 0.863441886845976 0.632027029369492 0.367563634908292 0.634158210875466 0.993697534792591 0.482219760350417 0.218098679147661 0.290083465557545 0.168936009360477 0.0401679677166976 0.453767897977959 0.904361927898135 0.398977397454437 0.651666394153144 0.952972080355976 0.651001025184523 0.126867642314173 0.0888832882489078 0.625479225541931 0.310244903152343 0.72864571465645 0.170019448255189 0.956825184163172 0.465399710682686 0.662480955289211 0.793001102823764 0.300708042057231 0.928722007977776 0.971954571104143 0.0992965510394424 0.97368206810439 0.659343270345125 0.716643174670171 0.127383377002552 0.953498496983666 0.972848140844144 0.844745489605703 0.0593951809522696 0.632641616137698 0.391326577707659 0.301378704973031 0.346233138556127 0.422682592042256 0.697308498709463 0.76651386719197 0.296932793180458 0.40222035581246 0.611282596734818 0.112395076854154 0.0992179243871942 0.524406038331799 0.152014015654568 0.17179036820773 0.322951068580151 0.178164359903894 0.571041530743241 0.704117571634706 0.739074209041428 0.673078502162825 0.672604532192927 0.899312531482428 0.972222450547852 0.680332719357684 0.970059295371175 0.18342517928686 0.0974482701229863 0.513954596056137 0.360737972038332 0.986869769049808 0.977547823954374 0.684004631731659 0.156328885946423 0.448513135274407 0.0361703039077111 0.435081607573666 0.148016719266307 0.472758060074411 0.434639361179434 0.61876283046091 0.0866525843623094 0.423385597663 0.393686657485086 0.519674532068893 0.195472337841056 0.412258106323425 0.858825469478034 0.0793556758295745 0.95504764856305 0.907735455457587 0.750666984561831 0.799816830120981 0.632576856506057 0.982337503705639 0.63074345267145 0.96233100194484 0.467381088258699 0.48178686774103 0.732453347728588 0.0423234858899377 0.146232579313219 0.64169366351096 0.099275061537046 0.0182701013865881 0.644366487246007 0.622464055125602 0.167835772146937 0.597225280543789 0.677968021004926 0.272790925283916 0.657868443091866 0.396649325692561 0.169868055703118 0.592795721048024 0.820106925822329 0.0872188638336956 0.538241016347893 0.186132876412012 0.293161574406549 0.736776397856884 0.998568845102563 0.396959445150569 0.189638615271542 0.388945249763783 0.325528529349249 0.246520744943991 0.0451599685894325 0.882368990418036 0.107402295731008 0.459221865872387 0.906096474120859 0.617867681549396 0.210593098232057 0.933877814183943 0.691154421225656 0.178739132003393 0.87637520425953 0.781314833711367 0.221872414546087 0.469860155186616 0.862341237724759 0.941901930852328 0.137772933319211 0.12058402251685 0.761005290988833 0.876417030983139 0.912447292264551 0.607620937335305 0.382616060345899 0.0303469228255562 0.386490601792466 0.828536445621867 0.359594642182346 0.338491571191698 0.854070940411184 0.649893951041158 0.999196552294306 0.536954955987167 0.677067228013184 0.974031636423897 0.0586759631801397 0.538610684240703 0.742575088220183 0.529025550193619 0.260822810130194 0.758852920786012 0.394382284034509 0.507470802958123 0.788104817124549 0.379922921978869 0.340087212095968 0.114466586376075 0.328421847010031 0.127910336924251 0.879907165756449 0.748575192908756 0.476961336117238 0.175726331842598 0.0565137715032324 0.847523515529465 0.75314629628323 0.37573961089598 0.996959370370023 0.394254359386396 0.927653755729552 0.876871361692902 0.88812929937616 0.996333622678649 0.25188297820976 0.570997227733023 0.103659192940686 0.793828347129747 0.182959154271521 0.0498614037479274 0.495185475328472 0.460558681464754 0.717766405183356 0.0190842047543265 0.514686250351369 0.960122823207639 0.302245367253199 0.585991757668089 0.0746180854574777 0.73527661181055 0.327266924961004 0.401849648354109 0.995435572434217 0.858487420051824 0.843281657313928 0.572034961702302 0.881796711662319 0.754964896566235 0.890446898264345 0.986188218586613 0.384481394977774 0.536205490776338 0.952476650157478 0.62115085034864 0.730800830603112 0.263479251372628 0.884171429951675 0.0216021299967542 0.602203173751477 0.300595032062847 0.638253348821308 0.971413378124125 0.469495800833683 0.220532251368277 0.991928360895254 0.604160980388988 0.155908798202872 0.0390771840955131 0.916787279243581 0.303017744857352 0.0773798256996088 0.481668826572131 0.436638131078798 0.460372204612941 0.0622640381660312 0.707392271086574 0.0245370261301287 0.912158169725444 0.804713993803598 0.792590806358494 0.593769083090592 0.459557856682222 0.373023484761361 0.858158518110868 0.0185911989794113 0.287847929650452 0.23097618664382 0.0204384523164481 0.550321185602807 0.676598571813665 0.896343619197141 0.816848352313973 0.786089782058261 0.61922037206823 0.285182114108466 0.131958609826397 0.135051117925905 0.849572133633774 0.112652618729044 0.233488212870434 0.167516484688967 0.447014090062585 0.79670272141695 0.26738221537089 0.972915280181915 0.226208474226296 0.89230535793351 0.595391361075453 0.680909332709853 0.964623914724216 0.912258403666783 0.260068669179454 0.0889417305029929 0.0602351367706433 0.531665837832261 0.814934209734201 0.187420979714952 0.795709171749186 0.523448674073443 0.494421875944827 0.688761273813434 0.053124340204522 0.99518596790731 0.910424450775608 0.814170361408032 0.88649095491739 0.0920662039751187 0.37447760022711 0.492708125642967 0.799631474663038 0.88646068765549 0.782179657735396 0.165260469801724 0.89215116454754 0.0825683164456859 0.377298376036342 0.637338345590979 0.0745571231213398 0.81729692484485 0.338466349856462 0.634965198405553 0.553638004285749 0.293349936536979 0.327803793486673 0.940387684241869 0.066074953591451 0.340117733371444 0.885267104140949 0.898109184119385 0.0823878395697102 0.234522151849233 0.531348863004241 0.58792894725455 0.677907104538754 0.521776502244174 0.76887740588747 0.361545848154929 0.32789173681289 0.449904359790962 0.687004141588695 0.867246139140334 0.681331015068572 0.23300684170099 0.254569844838697 0.653095438340679 0.906112946970388 0.94415369504597 0.428588741903659 0.602030062116683 0.437301730019972 0.887153116445988 0.929226981664542 0.491084558228031 0.614463490033522 0.905257840924896 0.716848679950926 0.198440012789797 0.28705947865732 0.593351288614795 0.377634464579169 0.244245372009464 0.98963173126569 0.845337457179558 0.249939121573698 0.226308020809665 0.635296133146621 0.853647053297609 0.056307578634005 0.459286719779484 0.768145828349516 0.386136981241871 0.659312054566108 0.293342258504126 0.29372344690375 0.987447214745916 0.419241493644658 0.326579971523024 0.0496349149174057 0.274335294861812 0.0379207663168199 0.383261123672128 0.312442067796364 0.12565769912675 0.507308109798469 0.893092736399267 0.476523344796151 0.591433386080898 0.210427101512905 0.78270740413107 0.718653240567073 0.977128966171294 0.0502555758832023 0.792387928804383 0.744789985639509 0.144325687414967 0.612792493535671 0.916828114346135 0.881774302225094 0.698336289729923 0.135832194688264 0.240130113745108 0.848275702742394 0.7039551495458 0.569498109451961 0.422294135442935 0.75280741935363 0.717700199380051 0.842937294889707 0.316336217385251 0.23715476422105 0.827278843771201 0.0869426943734288 0.241679808387998 0.125631794121582 0.0133673985023051 0.790602005454712 0.696683278637938 0.849886493873782 0.0441623929678462 0.933040626237635 0.0407340858364478 0.280728934807703 0.987337769009173 0.354868548575323 0.793910760474391 0.620483810699079 0.455623774407432 0.87342797187157 0.913545214773621 0.810104663451202 0.0520465133502148 0.350652194982395 0.275857746663969 0.915440735991579 0.635791293657385 0.2963111892296 0.649913950345945 0.173373745465651 0.851050045238808 0.329298247091938 0.90016195587581 0.902069514156319 0.723416185274255 0.121266760528088 0.566075502873864 0.0922258538124151 0.867006941332947 0.0470862272940576 0.402674518255517 0.418774737014901 0.846120648339856 0.532733684396371 0.564375839030836 0.2256007329165 0.710746975133661 0.667691432270221 0.129057335685939 0.538260061834008 0.302892665530089 0.186413545047399 0.817149478723295 0.442637341648806 0.909251198489219 0.691590579361655 0.47824414846953 0.493806354489643 0.768502111432608 0.0321947141550481 0.31908736835001 0.309960636375472 0.221066750790924 0.953768755441997 0.344351604219992 0.611238716465887 0.134760886209551 0.476885764542967 0.250046058523003 0.226537418810185 0.636418307498097 0.430232245465741 0.722325757548679 0.957448091374245 0.346724844989367 0.440495823265519 0.87520194113953 0.119346954275388 0.837448941809125 0.639493257543072 0.427102172169834 0.310392818576656 0.462401396902278 0.75369484574534 0.786836221003905 0.232501620454714 0.0878628841368481 0.771733596075792 0.0180194625956938 0.227611779600848 0.890507393372245 0.584056281174999 0.245678275728133 0.0302267840853892 0.460235795634799 0.298074928803835 0.536570608553011 0.939680627081543 0.738401610828005 0.941331245559268 0.346131952640135 0.137071097267326 0.426574585973285 0.807679406832904 0.605598916895688 0.61641938511515 0.12991644578753 0.123276541063096 0.480257249621209 0.380071450539399 0.495776627154555 0.838319944448303 0.553275889493525 0.615296968505718 0.746797754811123 0.329144999226555 0.0860631161252968 0.287704864686821 0.734594122972339 0.564625355736353 0.559750162614509 0.342128125429153 0.0139224898512475 0.451706006396562 0.54426154123852 0.234180702513549 0.552328689927235 0.264593301438727 0.829499163988512 0.940144976114389 0.20918121609604 0.993233022794593 0.0914415433327667 0.852890132719185 0.532997888249811 0.232010668916628 0.142260401456151 0.0908672200213186 0.94613494515419 0.947441213885322 0.632968118318822 0.262674437479582 0.16543055978138 0.987223227557261 0.727393737523817 0.149235318277497 0.808252047707792 0.904429659626912 0.243384197989944 0.82322621322237 0.256951634478755 0.919288079314865 0.394031580721494 0.150111353013199 0.458637307104655 0.493818622054532 0.904550192987081 0.136857572118752 0.672993126632646 0.892459764995147 0.789874407770112 0.886080462525133 0.556440072986297 0.829965110633057 0.549479491105303 0.382422656437848 0.793288739775307 0.698304474875331 0.756743652906735 0.975819128802977 0.364727597539313 0.890940523168538 0.159061385123059 0.882216649348848 0.0698794248630293 0.89685385963181 0.740978718006518 0.220931973308325 0.971009997650981 0.710145243019797 0.717056047460064 0.394135911841877 0.0352005270984955 0.277495091664605 0.1760321409069 0.910750967247877 0.889612442462239 0.420894649261609 0.377060270810034 0.73141814052593 0.648144427929074 0.172741173752584 0.359680162467994 0.147772449024487 0.441632778579369 0.0528612699615769 0.988149604464415 0.563518317551352 0.137972232094035 0.0176139209326357 0.915543245912995 0.140622002137825 0.346191727889236 0.455725753712468 0.550488845857326 0.741128819053993 0.590662497291341 0.33799747537123 0.341682155039161 0.449150406238623 0.915085191668477 0.60764232610818 0.977417197818868 0.96839367833687 0.904271868329961 0.0673263291129842 0.814725512687583 0.262530517121777 0.373891772083007 0.158536077442113 0.861756884334609 0.418508406085894 0.634397337227128 0.344525331526529 0.804453400999773 0.105820739672054 0.568498677134048 0.27088143723784 0.762506411182694 0.134386404966936 0.790137868945021 0.234631847911514 0.710385255883448 0.211959373867139 0.776432052222081 0.169258316629566 0.112508802327793 0.0938465512427501 0.691306372976396 0.40456611978123 0.817472856906243 0.537222681224812 0.104590978354681 0.985017170363572 0.371708150603808 0.718322211089544 0.0941825842345133 0.966714071424212 0.450451780022122 0.91431642718846 0.602221534184646 0.17577262454899 0.890060789100826 0.0939711838564835 0.441376918910537 0.416554790211376 0.0959724731463939 0.374453326486982 0.146348258294165 0.495382524400484 0.821958554324228 0.336013083746657 0.267889147866517 0.984980680691078 0.888950791957323 0.165941994909663 0.972118395338766 0.991373401624151 0.373472179688979 0.691302612791769 0.327739948949311 0.0114180245622993 0.367323601990938 0.329198585026897 0.478583042686805 0.232561763816047 0.846105760193895 0.0537277547549456 0.1000656647305 0.521887394152582 0.668338929931633 0.610748536419123 0.903225157908164 0.248963197958656 0.275657360840123 0.408610982401297 0.826581594946329 0.216832994271535 0.82341322530061 0.889175071883947 0.135867423282471 0.367200885082129 0.279302637055516 0.371073650277685 0.0798267055116594 0.940323644238524 0.520993045314681 0.483479303030763 0.906764442694839 0.4412355004251 0.219827900996897 0.246222921402659 0.712054431412835 0.357576462372672 0.173605366661213 0.585339393641334 0.19562513415236 0.201816543333698 0.529894480616786 0.244590532432776 0.255083702777047 0.147988030023407 0.296091928030364 0.59687902961392 0.801980834007263 0.273339430489577 0.429602025798522 0.557684655142948 0.400408055619337 0.186759415648412 0.833290227400139 0.849838689763565 0.5077957324218 0.278428246492986 0.538976211389527 0.964130018749274 0.678191299168393 0.283767325568479 0.36945813938044 0.321947163364384 0.93297791369725 0.0466380775044672 0.391419517402537 0.27042216478847 0.212256570903119 0.906536764933262 0.124468905450776 0.765532501647249 0.130036136892159 0.980448378005531 0.443566922077443 0.991637919652276 0.87058689088095 0.351127990300301 0.420075694280677 0.474761481510941 0.30675097707659 0.277960409959778 0.117206163126975 0.966681205478963 0.533609817095567 0.986271272727754 0.934784451792948 0.131398303592578 0.432658057594672 0.112507256118115 0.465445171736646 0.136750925832894 0.624833420689683 0.749671577275731 0.539309195757378 0.499292118798476 0.316052208309993 0.441971857429016 0.662858407937456 0.369329292492475 0.157597472616471 0.810231935547199 0.373453292788472 0.270047983429395 0.0537982105603442 0.330479223050643 0.715652521033771 0.931233696287963 0.406747143499088 0.79502508668229 0.249422626919113 0.167547497625928 0.142507560583763 0.619719327569474 0.358171479261946 0.639890488674864 0.842804314403329 0.607009634994902 0.178922465033829 0.942609132076614 0.961734720289242 0.993636714906897 0.238606853340752 0.540768865407445 0.835003900253214 0.782847906139214 0.281799222852569 0.0630419660359621 0.771254634116776 0.987390064226929 0.51741960307816 0.90476794462651 0.838783885031007 0.821375543840695 0.307659978026059 0.943341837923508 0.592911248819437 0.714522593966685 0.11936981019564 0.316503767920658 0.742456035376526 0.121286283615045 0.801929186731577 0.135167545117438 0.353845575284213 0.0263852980569936 0.635996518186294 0.940829790029675 0.149411596783903 0.571573661062866 0.299253347339109 0.940091590390075 0.908762804835569 0.27974690241972 0.943382129732054 0.308708501348738 0.083693872957956 0.297086716187187 0.330684037515894 0.0203206596290693 0.523867240040563 0.67562326917192 0.32646106089931 0.495874614850618 0.131072342630941 0.969422866201494 0.161799363109749 0.12639715523459 0.3807690375112 0.308860527090728 0.267728158580139 0.174044221213553 0.902492104233243 0.0718745597405359 0.687865279188845 0.740289735917468 0.81614465541672 0.675637618633918 0.0616116978810169 0.956761635129806 0.567634741235524 0.667778539794963 0.315945762330666 0.660149521189742 0.644116776457522 0.522016572963912 0.805063125321176 0.77016857925104 0.41616274031112 0.375765573526733 0.36741782120429 0.591886202620808 0.239787513050251 0.510170455782209 0.640804724332411 0.431951134125702 0.281748913412448 0.199876729247626 0.177420451873913 0.823723153672181 0.262630563434213 0.405034263113048 0.187851035301574 0.652091642613523 0.21142571255099 0.454842172099743 0.871852170303464 0.547512849313207 0.53346716380911 0.930378084059339 0.588697784112301 0.593713020081632 0.316829347861931 0.0491340939607471 0.174950743110385 0.118674881146289 0.904756170336623 0.804640599323902 0.517554751669522 0.755798986561131 0.298740233692806 0.665706355823204 0.98676163648488 0.144207751585636 0.909412994072773 0.6114158340008 0.71423640065128 0.0803739664657041 0.15437527445145 0.900599732368719 0.994788721562363 0.308902896647342 0.865830169045366 0.247576640192419 0.581188504556194 0.432806041247677 0.826070681675337 0.39699409034336 0.731170125082135 0.881883939970285 0.0848666561720893 0.0621184542728588 0.816512526543811 0.0774325618683361 0.0253539298707619 0.673924870095216 0.272594586620107 0.740602671883535 0.247981605830137 0.262464411125984 0.881929162223823 0.869921650532633 0.336967041410971 0.87138886383269 0.330466774080414 0.0545935780066066 0.572959675535094 0.0812012979015708 0.81330009798985 0.482316819352563 0.995835082773119 0.776862370120361 0.602028830542695 0.880756554882973 0.67684571941616 0.406909065397922 0.725081149295438 0.505356407323852 0.114673945126124 0.826433793851174 0.999895996423438 0.493262410233729 0.53496298291022 0.698063240810297 0.179029492109548 0.984026970816776 0.382213760928717 0.10071162563283 0.470787168049719 0.492446149825118 0.308164741955698 0.691948789213784 0.106145933060907 0.988930326253176 0.826264220196754 0.354444621354342 0.834430389923509 0.676105319631752 0.519402008464094 0.978127796417102 0.445585687824059 0.517884921603836 0.651948619370814 0.0731067060655914 0.195549615132622 0.760618705376983 0.0835631933459081 0.670313255519141 0.207353109435644 0.0190274631464854 0.0499151730281301 0.474406943330541 0.501922409550753 0.402724097694736 0.75660231947666 0.478076291596517 0.817775393067859 0.466599308925215 0.561941209726501 0.623011933595408 0.0695638860645704 0.958928231936879 0.549514639023691 0.49041357768001 0.274864233876578 0.297218334865756 0.695281267764512 0.291509877638891 0.501375292430166 0.0648916504811495 0.169965265223291 0.0954863849771209 0.546955013372935 0.30252333601471 0.642491162412334 0.536416662726551 0.689278894471936 0.406446692692116 0.0983446642081253 0.632692333797459 0.420859614289366 0.153044253457338 0.0818044266290963 0.202555386535823 0.842580687028822 0.909832668064628 0.852000918320846 0.85996092837071 0.08518487571273 0.133568154170644 0.762507249750197 0.958313327075448 0.146486629077699 0.300294215448666 0.489989957718644 0.917709855167195 0.200757780866697 0.526375526366755 0.196533702909946 0.707774402471259 0.997565077496693 0.170094200624153 0.674890670508612 0.886107720809523 0.259721494165715 0.653279150777962 0.854236879504751 0.104160725919064 0.91303304803092 0.11582667671144 0.352644956607837 0.42614424594678 0.0789591528009623 0.658252456758637 0.030934795064386 0.556755265109241 0.715604936361779 0.838061185060069 0.613479688540101 0.980046205134131 0.179490302931517 0.248920042619575 0.848941060646903 0.332436878017616 0.0827162708248943 0.983996522610541 0.323624248811975 0.42440227386076 0.668092399383895 0.579626764552668 0.380922968816012 0.141375836750958 0.591030334304087 0.780030418676324 0.0783669561077841 0.675991639567073 0.875420273183845 0.103703344510868 0.296332759407815 0.963517981336918 0.637655125414021 0.178958113372792 0.883600505166687 0.373025258015841 0.961147959993687 0.995236948339734 0.925323885357939 0.116518981261179 0.837878886754625 0.296506973996293 0.133792464754079 0.0245748220593669 0.740966995579656 0.0295423878403381 0.29916182085406 0.42914358753711 0.763287003198639 0.669334179554135 0.0761186353885569 0.391780757438391 0.27428987598978 0.731207998921163 0.115533049234655 0.812237490743864 0.207796637883876 0.37819934213534 0.600694242524914 0.506780616263859 0.712830955523532 0.317769455793314 0.838760346593335 0.848708394123241 0.69191878288053 0.750567913043778 0.0506537801958621 0.714175649916288 0.660769938053563 0.262475811771583 0.631354558393359 0.322184258990455 0.383920728468802 0.49671120256884 0.213890130594373 0.133551401952282 0.706853097998537 0.411288064436521 0.918993031021673 0.753312550012488 0.474335580267943 0.887350973659195 0.140971382597927 0.195266944123432 0.0665515162516385 0.414606745808851 0.919409577327315 0.67897888278123 0.578482887714636 0.718834764384665 0.483820070540532 0.165845276589971 0.444646823222283 0.706107883250807 0.323947101910599 0.265849667105358 0.779783118711785 0.423230552801397 0.189593227747828 0.823371595887002 0.0773230734886601 0.275646491732914 0.862252911303658 0.149919075800572 0.459417573651299 0.342837355996016 0.181914980297443 0.0232792315795086 0.255292893559672 0.341776366415434 0.0675013702828437 0.759601150965318 0.392089529840741 0.864833130033221 0.649903881081846 0.663084955085069 0.731710947414394 0.461910700760782 0.392548434869386 0.2833501838753 0.998905034374911 0.944697084482759 0.0174819364468567 0.932569172661752 0.692337789337616 0.0575515070860274 0.581464445819147 0.105708286801819 0.994138713038992 0.730019024531357 0.925046201036312 0.428756267775316 0.0848832159209996 0.338872988480143 0.62832900592126 0.551588371049147 0.190470998857636 0.304855397311039 0.943035733124707 0.288300530670676 0.316778593782801 0.170398021605797 0.193376742438413 0.0569151539821178 0.0863692301441915 0.434632828743197 0.40669631266268 0.360421081343666 0.0818910540174693 0.435237223389559 0.511014927832875 0.313798004479613 0.637484290911816 0.684687723333482 0.30901354307076 0.930943787735887 0.752283907516394 0.505138366173487 0.0957536074891686 0.192349107237533 0.801685767504387 0.808384794234298 0.236834758978803 0.36648339815205 0.0127552649704739 0.65100427250145 0.747361659416929 0.559226722002495 0.153162004193291 0.0901917578163557 0.375258758356795 0.859373156169895 0.42897218646016 0.0258673272654414 0.509853841920849 0.303469613341149 0.399595297693741 0.916472274519037 0.764541288812179 0.904129529909696 0.894164281834383 0.608324693241157 0.961507486014161 0.219942529809196 0.391562997500878 0.363046495127492 0.471584308289457 0.770208906556945 0.865852367572952 0.413767509618774 0.276534954463132 0.0155525025725365 0.184917350918986 0.849557545140851 0.70282974493457 0.301777153157163 0.436662120609544 0.189010749263689 0.43733894116478 0.949098088196479 0.725745619765949 0.503796744146384 0.0897887636651285 0.867685728303622 0.276593985650688 0.732155906821135 0.941115337016527 0.511390651252586 0.414810056937858 0.206827174327336 0.716987327106763 0.317163351280615 0.41327657997841 0.571544285153504 0.698748476083856 0.600115100101102 0.840952323321253 0.758826390197501 0.425588755137287 0.348071014827583 0.776396678872406 0.55158377944259 0.812309954455122 0.890170393192675 0.275884738948662 0.909139808465261 0.506044491145294 0.877164568272419 0.124922986065503 0.129728978928179 0.763484938091133 0.307386954922695 0.902862179423682 0.82660364318639 0.332160151663702 0.946546536812093 0.954117542128079 0.41260695547564 0.992461141000967 0.0974990924308076 0.325642271649558 0.136355830535758 0.131302741011605 0.824124214600306 0.467598244280089 0.161451399778016 0.447476719778497 0.12888366346946 0.626374223474413 0.178199856802821 0.118338828561828 0.38844990485115 0.45449685677886 0.786851508149412 0.803339327652939 0.0823738496913575 0.381888790435623 0.137700791389216 0.742597963502631 0.632274761295412 0.857919191222172 0.189085850843694 0.585111068629194 0.606611105443444 0.963724421074148 0.0558943937439471 0.290914178462699 0.0419155285623856 0.125047268546186 0.178400455610827 0.380060113051441 0.863100206316449 0.55496783773182 0.31974586419994 0.286920532770455 0.531844749366865 0.862760831040796 0.71907853720244 0.0888392906542867 0.380731291600969 0.0258358113723807 0.848122418918647 0.723722834980581 0.792597459808458 0.884826082866639 0.700765080640558 0.355813381113112 0.514703919047024 0.892334997537546 0.158059095959179 0.62085582395317 0.622973186383024 0.81968559958972 0.665434067561291 0.0470596132637002 0.340480484811123 0.878085285425186 0.98835165889468 0.587770885347854 0.316681226829533 0.450591767549049 0.811967673467006 0.766871971935034 0.273792985328473 0.753303104487713 0.260663423757069 0.502143389836419 0.329111155259889 0.583576483184006 0.911826965988148 0.543267954229377 0.13496231966652 0.176585908711422 0.19808284457773 0.593514671667945 0.122940957320388 0.820158433183096 0.356714128234889 0.583083745713811 0.888091960533056 0.36012568844948 0.320253053014167 0.702370951008052 0.0957077776314691 0.170970528097823 0.153060418355744 0.767615761947818 0.288782450435683 0.788694998305291 0.0379787182924338 0.0754657386709005 0.828736136942171 0.658465667271521 0.153375614166725 0.798002217067406 0.89680376916891 0.957523832598235 0.976646829964593 0.886384805594571 0.0989856826793402 0.971896951743402 0.833771146785002 0.902194392946549 0.0336709288018756 0.306825386688579 0.894629259447101 0.738189709568396 0.652420533490367 0.139601931101643 0.6694985208055 0.909459795728326 0.485911647826433 0.671238434966654 0.65284089069115 0.819416820956394 0.384278342011385 0.741867852420546 0.13198389293626 0.0413960032630712 0.370148614202626 0.125891528304201 0.966661311744247 0.563454311201349 0.21740908253938 0.20173746996792 0.0849975312501192 0.856662194901146 0.738841391769238 0.716842918084003 0.0242973615555093 0.185257347167935 0.141951268087141 0.638432640454266 0.786353681187611 0.182334798814263 0.226146896218415 0.495028970234562 0.0790092156035826 0.320786508261226 0.404762567472644 0.88458046349464 0.0441941951448098 0.365751200332306 0.208422760833055 0.47105529920198 0.280651551254559 0.523677651637699 0.871097523169592 0.170259831766598 0.305822900675703 0.794320705193095 0.140882683685049 0.80296209651744 0.253018695956562 0.502373318914324 0.632564982408658 0.982354162570555 0.980551897757687 0.723402270539664 0.242013053223491 0.241909370506182 0.0613796640862711 0.591262821035925 0.9490215196996 0.521902842419222 0.916855106400326 0.567525803525932 0.610082656657323 0.848244327455759 0.428554506083019 0.91454684101278 0.119755439683795 0.31777647343697 0.685627849935554 0.63743688441813 0.701522235639859 0.556951384565327 0.503308834778145 0.210972769234795 0.901356128554326 0.561839987852145 0.433411114723422 0.0538561385637149 0.862223533319775 0.924885889426805 0.41434110385133 0.118785831141286 0.434048904548399 0.0842475642357021 0.689265072168782 0.366559424968436 0.359672880207654 0.879663889210206 0.190249422723427 0.180206338849384 0.941303085319232 0.835257312678732 0.799437422351912 0.0821900067897513 0.450383557553869 0.826331351005938 0.543094500529114 0.025630449464079 0.552526985325385 0.344207449902315 0.158502828401979 0.916471097574104 0.747690595933236 0.857338134015445 0.170829771845601 0.968641539113596 0.412209853655659 0.899878251524642 0.437732817796059 0.0222020724904723 0.612447786049452 0.817103611524217 0.0710681394767016 0.222869238038547 0.784692741506733 0.360659567129333 0.305409713480622 0.0921806382434443 0.164194627685938 0.36829744163435 0.46475394340232 0.243992781785782 0.972772197239101 0.319615768450312 0.060364551616367 0.620423796188552 0.293837622087449 0.0287696223007515 0.559168632416986 0.779882887729909 0.310250535937957 0.859919970640913 0.759050756793003 0.924746663710102 0.929059302047826 0.196974581733812 0.4788808231242 0.729996610945091 0.359130018160213 0.895741730802692 0.167677537593991 0.133252081067767 0.784866309766658 0.783195207698736 0.172672055552248 0.0883667018543929 0.060280242851004 0.988823147967923 0.940763400285505 0.925426407495979 0.143734139124863 0.712619184267241 0.226904049834702 0.0129637123830616 0.393785957430955 0.760750727434643 0.166334895824548 0.403403752967715 0.160132979885675 0.876053389343433 0.518349717811216 0.457957358171698 0.503889219379053 0.440875282436609 0.927838657328393 0.33963655259693 0.154585779097397 0.452995855524205 0.571429430448916 0.247155204010196 0.270084355545696 0.457045187354088 0.260105140872765 0.75584475717973 0.563906270964071 0.326444836070295 0.694422388165258 0.511014253844041 0.132182197324 0.645557464470621 0.3888447452127 0.640846395466942 0.156392644275911 0.708873601502273 0.870814879359677 0.235178040487226 0.212604372652713 0.44449813653715 0.366470089638606 0.834020570367575 0.156424828164745 0.118324367075693 0.777905701377895 0.271399623318575 0.638230406232178 0.961782498352695 0.372115662831347 0.535336590318475 0.386694080957677 0.559479043229949 0.662603752412833 0.829457828234881 0.129533417979255 0.992653597774915 0.414377384919208 0.294994985847734 0.89905000338098 0.988989538154565 0.0381009990908205 0.582059380649589 0.647759010964073 0.0446002505975775 0.208610156697687 0.614185610245913 0.912961772098206 0.608947594228666 0.346700730295852 0.105312559697777 0.237244342269842 0.950533713456243 0.964929326171987 0.386059744288214 0.307827400863171 0.408542715446092 0.193577971209306 0.317122772266157 0.593942070023622 0.0319236982660368 0.456714528524317 0.764429263754282 0.263491384785157 0.423082305914722 0.738069642975461 0.167543320462573 0.614529764987528 0.910853460573126 0.314041349946056 0.362954940521158 0.86726374882739 0.950151085108519 0.94315848599188 0.552057029323187 0.0476944323745556 0.817504201305564 0.898549401862547 0.212467429831158 0.461040221361909 0.486629782698583 0.616851252911147 0.870599293289706 0.142690411633812 0.629506895914674 0.514938473845832 0.841594972596504 0.282183271094691 0.585204823149834 0.766464700351935 0.144662547218613 0.739621114791371 0.354771877969615 0.721756576744374 0.970386073463596 0.983659039989579 0.182639222559519 0.856006956049241 0.535407226607204 0.186149394670501 0.327981674445327 0.618098891067784 0.995191993238404 0.628778910294641 0.328176170703955 0.414152690088376 0.229315047117416 0.313514950145036 0.653139076351654 0.633078412304167 0.81320171313826 0.0192681389348581 0.886112417064141 0.606202061988879 0.125096247526817 0.816769161161501 0.214157116841525 0.836063173513394 0.284241012942512 0.327836791970767 0.571671536965296 0.3940290269861 0.745616605745163 0.0976000397768803 0.212540450897068 0.344604946111795 0.750328528068494 0.257806298190262 0.837809093182441 0.260787644693628 0.605449623758905 0.778916531344876 0.763148449626751 0.867864510756917 0.167084845781792 0.904140575351194 0.788452689407859 0.244758055768907 0.832997922776267 0.264821809469722 0.14664747568313 0.187545849515591 0.910285385949537 0.273313892905135 0.143692110020202 0.683132167477161 0.966211359426379 0.786131750540808 0.54071054255357 0.265418513866607 0.889324116308708 0.48969870418543 0.0996818124153651 0.15109118202934 0.0714090222376399 0.165169112505391 0.511822136645205 0.716031205256004 0.740431303537916 0.227836218574084 0.109014464344364 0.498811694532633 0.812254159059375 0.474426318204496 0.602218412721995 0.169515569685027 0.868207830619067 0.210712412234861 0.169291638277937 0.671014170714188 0.658318890759256 0.122563036060892 0.939174296427518 0.469919703621417 0.288739664822351 0.505659214325715 0.675704355975613 0.124167891296092 0.93194298932096 0.919003582266159 0.867803312155884 0.422579473594669 0.74750357048586 0.305051165020559 0.0764485987927765 0.0517751420265995 0.0469453763053752 0.348593194822315 0.230382252654526 0.296693935825024 0.537219825761858 0.625813464534003 0.243886282790918 0.0736204681149684 0.285516498547513 0.083008217709139 0.510694257130381 0.437936721777078 0.584512902847491 0.238704659861978 0.297660766583867 0.162888612276874 0.308181036165915 0.607688343594782 0.196605526977219 0.488631166494451 0.194804765270092 0.65374118741136 0.408944141720422 0.505057174952235 0.312474302626215 0.195846713974606 0.200253831532318 0.452967996550724 0.0322159021603875 0.28110653659096 0.387372812607791 0.797531407515053 0.201953596796375 0.0755088861729018 0.913160249823704 0.401567325403448 0.676765313516371 0.369980600357521 0.840028204184491 0.411356822822709 0.491684161422309 0.451744444505312 0.205950571403373 0.698482982108835 0.530285338589456 0.486561991730705 0.122097681115847 0.0718278518994339 0.165661347480491 0.96314798820531 0.866520111868158 0.700659222211689 0.36102822680492 0.49146706671454 0.208935753004625 0.235719800272491 0.755909568904899 0.445008190956432 0.428211809960194 0.925879481276497 0.418766256603412 0.604289790627081 0.0821879089879803 0.332292889431119 0.442477530459873 0.156572069830727 0.507459820674267 0.600058548657689 0.312701534826774 0.858604052851442 0.483227516338229 0.558268539921846 0.309658348464873 0.0711489598196931 0.247146703775506 0.0379281310969964 0.187786240172572 0.490756941568106 0.32446237328928 0.845810573829804 0.39186131616123 0.79194367634831 0.898384826651309 0.0128908116393723 0.447979819711763 0.322779541418422 0.64096860043006 0.278539749002084 0.629260443507228 0.100017977023963 0.766003813925199 0.836218740693293 0.586438162554987 0.583145760523621 0.436425885218196 0.496052169878967 0.456953983111307 0.274293569098227 0.996250400501303 0.154665174705442 0.472694761136081 0.549694991658907 0.983459562805947 0.938226343118586 0.290908144603018 0.134914931843523 0.583804854527116 0.944095424285624 0.85457700091647 0.106654995167628 0.567184126684442 0.461806533758063 0.614850284710992 0.470837837534491 0.33765277572209 0.467356430962682 0.231688121464103 0.0271787147619762 0.863908542285208 0.1239202015521 0.475354738053866 0.0845756582659669 0.0976432928489521 0.917165554324165 0.651462797892746 0.897662607738748 0.810773136133794 0.290637851799838 0.856207125661895 0.412560381556395 0.446714160882402 0.0865973797440529 0.548146299701184 0.857768634702079 0.323457683213055 0.280624933305662 0.0643455180665478 0.263609515619464 0.317009032270871 0.167576857630629 0.380448580484372 0.670037436422426 0.481059968709014 0.668370116667356 0.919551611945499 0.267436068553943 0.52578029234428 0.879150334612932 0.116000868480187 0.76752645842731 0.0548440305516124 0.0550285151717253 0.15096732390346 0.378877586734016 0.987725610858761 0.801934123630635 0.579353006377351 0.411922398339957 0.69599479581695 0.785786216934212 0.941450250458438 0.641853979269508 0.538401586120017 0.537750904299319 0.439320585893001 0.161500009493902 0.251406629225239 0.151341798000503 0.223706326177344 0.724537754787598 0.373241007742472 0.540634681698866 0.154713614771608 0.839331466383301 0.662327243883628 0.424098182499874 0.599945168707054 0.0534884333983064 0.026869627032429 0.699318375363946 0.803605301533826 0.343051196932793 0.333590299496427 0.189332574782893 0.0214174065762199 0.26956649285974 0.991559552084655 0.243894232125022 0.703012299558613 0.414826934549492 0.0281054346566088 0.959603832443245 0.836724923825823 0.131607697678264 0.131716754557565 0.781630092910491 0.0326069814153016 0.796464112773538 0.976816096128896 0.340257184519432 0.969376498120837 0.93915362036787 0.871647019765805 0.521745636598207 0.259869554575998 0.897171024163254 0.664601552358363 0.602135736604687 0.835158419569489 0.813079195844475 0.089919632289093 0.334553896768484 0.736657261571381 0.583869607243687 0.132888982952572 0.439610858408269 0.299646139687393 0.806310988909099 0.664503009843174 0.487037375140935 0.0468095968291163 0.0956612226134166 0.162292827584315 0.932908656504005 0.607010115822777 0.494151067738421 0.231397412838414 0.0599009381164797 0.42359015465714 0.148616985385306 0.422618509165477 0.781707208158914 0.591401494469028 0.606882990787271 0.0720304198889062 0.888575389396865 0.638192680606153 0.319422235921957 0.314542345623486 0.687792385360226 0.934414892005734 0.373109468817711 0.106286930649076 0.969633218024392 0.871392846913077 0.689609710504301 0.104102928149514 0.749317198372446 0.249134623238351 0.572999914789107 0.0160711775487289 0.1603122682916 0.2481585606304 0.374796213004738 0.202365108700469 0.469123438599054 0.505887050903402 0.247950627929531 0.158443926987238 0.927818347536959 0.831302709241863 0.495992765969131 0.828852896748576 0.795711017842404 0.632857941428665 0.990057999929413 0.984148225188255 0.985404013907537 0.187059289047029 0.12849408271024 0.872629001904279 0.324316403996199 0.822983876203652 0.759555380346719 0.188006560299546 0.473006548509002 0.792937260360923 0.312645775850397 0.118991932270583 0.207324785308447 0.951236897024792 0.389099799275864 0.732924303649925 0.0995576956658624 0.0339981485367753 0.415141961863264 0.784252167406958 0.0692044958099723 0.684313760721125 0.213286444742698 0.968746439574752 0.17701259596739 0.412356952179689 0.376137096732855 0.781754060524981 0.0389653948415071 0.29220805907622 0.0250037196022458 0.510869852888864 0.818950271548238 0.763005160153843 0.113749135634862 0.0810362397879362 0.26853529847227 0.404987032262143 0.436523002998438 0.786203017944936 0.380711523029022 0.896628132842015 0.274254608440679 0.881341236047447 0.575474163757172 0.956803873069584 0.606638490965124 0.593219564596657 0.582959716324694 0.77359928014921 0.03802520070225 0.364074369589798 0.0452770153712481 0.966149057410657 0.235265773364808 0.579722339119762 0.597894390565343 0.200666304400656 0.904528976168949 0.551035967357457 0.130306254283059 0.189635633493308 0.276408431038726 0.9180811202107 0.921158243662212 0.658449019240215 0.492396688864101 0.0548236138070934 0.279935992246028 0.202799684207421 0.316190848781262 0.059628436639905 0.331925422374625 0.539842350659892 0.824926111486275 0.0107212876831181 0.709161045062356 0.793727966819424 0.548783278388437 0.960739259065595 0.275036056081299 0.367104869794566 0.418526494987309 0.662135796479415 0.215878144332673 0.0103232977376319 0.627263905561995 0.725212392255198 0.993790219321381 0.854977751588449 0.778565667832736 0.264670544154942 0.312625275664032 0.60653381754877 0.409324400965124 0.220103081371635 0.119342954598833 0.0749245256371796 0.409391135771293 0.278751222218853 0.0240352930757217 0.465339084649459 0.91797404772602 0.412204416336026 0.574066720635165 0.928912030647043 0.183369167218916 0.385392126077786 0.786102408745792 0.315776551486924 0.734723710233811 0.484923446504399 0.749012350733392 0.953168838303536 0.550442504284438 0.930154085115064 0.625501078546513 0.856940840878524 0.391641055964865 0.544559869118966 0.0743364298110828 0.896158979218453 0.109028747882694 0.320079074690584 0.597662548548542 0.856833542962559 0.947197781288996 0.961799948532134 0.572779526894446 0.160571888145059 0.949979615572374 0.558590297212359 0.390465689050034 0.0772476697200909 0.376823135307059 0.449921344816685 0.672001036736183 0.244442067029886 0.0266478008031845 0.461992568967398 0.39395219802158 0.726489039361477 0.934931097610388 0.83802898388356 0.600991067760624 0.71440573066473 0.652094971297774 0.468650463707745 0.704174780240282 0.962108160583302 0.203852198217064 0.47390042666113 0.564749500146136 0.76956075864844 0.950027958136052 0.622496776545886 0.495980155877769 0.175209207916632 0.512483807895333 0.176979827985633 0.309934122613631 0.854661575912032 0.707704054540955 0.652482696282677 0.537786355097778 0.525150119008031 0.915867675878108 0.940422693628352 0.260824061066378 0.616584636159241 0.918125925255008 0.46516044579912 0.584292439578567 0.114157210979611 0.725387520785443 0.127411387877073 0.98338984875707 0.405336360859219 0.676350932088681 0.519263361999765 0.800434647148941 0.210728215705603 0.41833123230841 0.606640472593717 0.719927441582549 0.778746036372613 0.655926371926908 0.516347696445882 0.432154901188333 0.550141224130057 0.854585033922922 0.262443929149304 0.415429748410825 0.326095339437015 0.532230567636434 0.106417361549102 0.759208089159802 0.857736409092322 0.305619323546998 0.186108284578659 0.433017408663873 0.452997842915356 0.639867964447476 0.927254936897662 0.337881161125842 0.565787065618206 0.0582938682148233 0.989581529470161 0.127610530601814 0.0619749094033614 0.461921420963481 0.176197356223129 0.133430884496775 0.0816153589310124 0.595128088681959 0.0673823400284164 0.806224206392653 0.207257258957252 0.0278218785184436 0.925974587693345 0.0664905820367858 0.377839808969293 0.0706978068151511 0.562601047791541 0.644682100957725 0.852619217098691 0.846449565263465 0.669383123037405 0.266703322138637 0.201578139606863 0.355795034971088 0.906224938605446 0.475779968535062 0.570328179947101 0.799451696670148 0.552126371571794 0.951866279277019 0.552696275461931 0.729325451296754 0.446124674205203 0.358095094014425 0.729135747181717 0.103161526639014 0.914578206618316 0.987435755783226 0.766917361994274 0.766685570457485 0.899809493829962 0.963660365166143 0.474064098533709 0.220846429050434 0.478789456607774 0.0564815060165711 0.841812821046915 0.476711143578868 0.267147661263589 0.796763611836359 0.0967125546070747 0.695954580765683 0.0779126330045983 0.604261695158202 0.50937130256556 0.0453744927351363 0.895679993748199 0.779396774896886 0.127931372106541 0.0959804821806028 0.682272940971889 0.426803312520497 0.56231978307711 0.0107825731835328 0.972001074950676 0.174915676559322 0.385385596407577 0.588330155934673 0.696203503927682 0.77504690236412 0.224026305372827 0.103935922752134 0.130805047280155 0.382192496627104 0.490286535625346 0.481004940425046 0.529053356382065 0.490921068913303 0.764444643792231 0.552587127995212 0.0645730141922831 0.459323089821264 0.385419693696313 0.198049145597033 0.803396112825722 0.781018798407167 0.643196925993543 0.16637197420001 0.824326746861916 0.253428367068991 0.0858474122686312 0.0456748448871076 0.489624130455777 0.576393564972095 0.742795460440684 0.225313991697039 0.210649850443006 0.813830573302694 0.697675835071132 0.779191617905162 0.458320885943249 0.9986463266192 0.0841682977089658 0.968148341791239 0.956858843266964 0.70652867149096 0.582150051048957 0.795702706619631 0.148118123468012 0.0188222725014202 0.177291602911428 0.78036801908398 0.896780527618248 0.917773496631999 0.247622497479897 0.959653756483458 0.338297551150899 0.665588736473583 0.404582405462861 0.252966599892825 0.67327911272645 0.906828349006828 0.648955601612106 0.76260138229467 0.259002140397206 0.216905460287817 0.108192958624568 0.925954498262145 0.431278452009428 0.0821165805007331 0.541482268297113 0.164846601011232 0.35573023223551 0.902262261824217 0.210503787796479 0.436586348728742 0.729479238998611 0.824544701573905 0.963511993116699 0.466653087886516 0.890114904365037 0.744862742780242 0.141969129943755 0.307195516508073 0.735856942473911 0.824121122641955 0.396281933779828 0.694416267175693 0.714260383497458 0.186606503855437 0.518201240191702 0.663783269983251 0.0531849913625047 0.0550064498744905 0.0421774278534576 0.392717234957963 0.79734476700658 0.488270068909042 0.546254040091299 0.619436801085249 0.891632869669702 0.151239844281226 0.586696813837625 0.565966136660427 0.215602761115879 0.464570153746754 0.280586292124353 0.474015556355007 0.795687393427361 0.945805548324715 0.430837748136837 0.332862966198009 0.224604220371693 0.10908913903404 0.315278916533571 0.024028582230676 0.826764501547441 0.30833564030705 0.339410703179892 0.831516299392097 0.507727494509891 0.480746302050538 0.863533077719621 0.252338902843185 0.0694998566643335 0.88662795352051 0.177642750402447 0.282810781898443 0.739690016780514 0.583348732122686 0.408089322880842 0.235964414423797 0.69085247192299 0.111766464940738 0.652638098192401 0.0774802094674669 0.930112124239095 0.327247060730588 0.938960363750812 0.0941342992964201 0.869969210771378 0.0523339315550402 0.543274848554283 0.614691140134819 0.116206460429821 0.187613248859998 0.254131890167482 0.393605683397036 0.815394210570958 0.0488743685372174 0.588938269505743 0.127733243131079 0.567956785270944 0.565403814222664 0.962531197373755 0.985116199008189 0.826200744002126 0.291732410127297 0.0312218580651097 0.461580587991048 0.325342987184413 0.642099743396975 0.0746142376819625 0.230822884149384 0.869957138211466 0.0149139186670072 0.398099899950903 0.644353452569339 0.059067670092918 0.144893682284746 0.15466566659743 0.669380411638413 0.74896561730653 0.968955440653954 0.0575171993486583 0.713709556672256 0.279885265827179 0.810162725145929 0.643253784696572 0.952894562650472 0.120771204475313 0.372086189419497 0.755908402102068 0.903695877103601 0.0266222115862183 0.0467431950988248 0.662070364472456 0.603394856774248 0.307832644791342 0.0350083964853548 0.722677562662866 0.263073415127583 0.193715595626272 0.587226700908504 0.48256474328693 0.592469313142356 0.852686952746008 0.16941523731919 0.282647723623086 0.493348434397485 0.650424481674563 0.37977674776921 0.225323234379757 0.557763417561073 0.674250572202727 0.157333573948126 0.233371654292569 0.668989620050415 0.162253771498799 0.951155963044148 0.109145016258117 0.460212073256262 0.483557259843219 0.381972306042444 0.116669214616995 0.113253121573944 0.463941000152845 0.990800508810207 0.33795735966647 0.80772191768745 0.666241055782884 0.315469829863869 0.297124904892407 0.661459510689601 0.436407959512435 0.878069806271233 0.85749311594991 0.33921074378537 0.940384646451566 0.260752427394036 0.885224751180503 0.166672283939552 0.241426278636791 0.956965054825414 0.501391592402943 0.133619569560979 0.506861208179034 0.325399806932546 0.161137642532121 0.96356576124439 0.922727265234571 0.616640941426158 0.703133831915911 0.354741856653709 0.790017035240307 0.743818250251934 0.641545999334194 0.87967555769952 0.62034988722764 0.250890110598411 0.111575991178397 0.973419907884672 0.501745558246039 0.882572044997942 0.451030262748245 0.923629014811013 0.397543480447493 0.585191416442394 0.742925496951211 0.25311361704953 0.49806756637292 0.102203113595024 0.390579639724456 0.279663561533671 0.341069436261896 0.562617576653138 0.112820919088554 0.706686443425715 0.160568395112641 0.265200308137573 0.873316900401842 0.754066386008635 0.341688342874404 0.649377683661878 0.728258123593405 0.200592770006042 0.342210828284733 0.423862163780723 0.714495996532496 0.107234019343741 0.974492706099991 0.529682539710775 0.978763447641395 0.563734591209795 0.162343446589075 0.708268561218865 0.198430514249485 0.327164575469214 0.8555406546616 0.109723455649801 0.0896074369270354 0.798342635596637 0.178183058944996 0.32534959268989 0.804331111211795 0.880743439991493 0.974095491564367 0.229029737317469 0.531620154113043 0.899385836988222 0.174203180926852 0.407827219364699 0.626542611194309 0.548489118451253 0.322259851540439 0.119066170849837 0.33590923944721 0.487622997676954 0.699845723451581 0.808509639832191 0.761034494251944 0.407901192174759 0.140696512709837 0.916130285807885 0.134419349052478 0.0314777308725752 0.120571070590522 0.748772346167825 0.245342204472981 0.460150475655682 0.593374008538667 0.252946401434019 0.678331105981488 0.935042969153728 0.211599917919375 0.832508557094261 0.204746335223317 0.301034295756835 0.598397810435854 0.785926765273325 0.0359918499202468 0.586309725039173 0.686185402127448 0.13803078291472 0.753450579191558 0.980010648765601 0.31294947051676 0.0816925382590853 0.880322408340871 0.194713264601305 0.303289867618587 0.961114191401284 0.430132868762594 0.724112767486367 0.908525111516938 0.0395505234110169 0.789016937231645 0.767205485766754 0.239686582991853 0.640789020669181 0.208442133401986 0.145756447000895 0.61952541955281 0.658809759777505 0.854317837918643 0.91801896433346 0.136527613094077 0.405658959713764 0.208985166251659 0.983086063042283 0.125936375991441 0.314633777141571 0.450167531224433 0.662677320230287 0.801608154370915 0.364281546012498 0.81735211401945 0.0236657902225852 0.645272552287206 0.947185159211513 0.715846781258006 0.86189181095222 0.887956543406472 0.87234630438732 0.802699682514649 0.599186974603217 0.816231868742034 0.316439596300479 0.813598441544455 0.558052140639629 0.296198486955836 0.510660282468889 0.221449562618509 0.575972954910248 0.414173556542955 0.746384083100129 0.399857043700758 0.751754026669078 0.934977642255835 0.0220935323974118 0.363857142804191 0.128754169561435 0.931835926517379 0.0556497860467061 0.674957638583146 0.432108559384942 0.37585931790527 0.523595558921807 0.874863649224862 0.327381705674343 0.725700795359444 0.319867032133043 0.962151661906391 0.862738904275466 0.82754578138236 0.124984896918759 0.770438435713295 0.689709810984787 0.715538644811604 0.600370950780343 0.72440871819621 0.0831125504430383 0.827521618974861 0.967263545892201 0.919215752983 0.218430608506314 0.806545955385081 0.54650205323007 0.234237869628705 0.3063541998039 0.652585391758475 0.888618809122127 0.31670602818951 0.505773132038303 0.298638521539979 0.0334670937410556 0.952655773062725 0.0850572880590335 0.281170948394574 0.374121209268924 0.687813440135215 0.9686895193276 0.21658098353073 0.650974835508969 0.0891050423309207 0.488870084241498 0.395073992044199 0.163922130358405 0.598369742396753 0.0567737797531299 0.415808940660208 0.638134050031658 0.936327377504203 0.483847306005191 0.590243654260412 0.617535790915135 0.897906714093406 0.977165761720389 0.330366994459182 0.551362329162657 0.076805104771629 0.0191564736911096 0.27103760303231 0.973789367864374 0.785325849598739 0.220612810782623 0.915248224588577 0.09700161191402 0.323593828727026 0.354034312441945 0.334926097651478 0.272917584474199 0.259278723148163 0.887484124256298 0.0674121988401748 0.932741715186276 0.282399825504981 0.0878482813527807 0.537205688131507 0.985643031001091 0.160160417731386 0.808971407008357 0.665338660108391 0.944873519500252 0.0893335429858416 0.24933354583336 0.295799632857088 0.317096997264307 0.85551325046923 0.155528272036463 0.824178875694051 0.309641622523777 0.0974890282377601 0.665424583081622 0.196879924796522 0.967648607422598 0.218239086880349 0.0506514811655506 0.305232110046782 0.124454677002504 0.977133682018612 0.647682338049635 0.705728627843782 0.0464736869256012 0.103807659957092 0.130271407170221 0.0945804338040762 0.788162146974355 0.513703875206411 0.778190851439722 0.937682372815907 0.499919644584879 0.997137010453735 0.933385896149557 0.997764642271213 0.379918947427068 0.636855967126321 0.66410222413484 0.788305997028947 0.928279708798509 0.22120510405628 0.919034952942748 0.298536507890094 0.213991719658952 0.922875102979597 0.391719509279355 0.603865607548505 0.566888350003865 0.252908818488941 0.203470582927112 0.907534416159615 0.978279148631264 0.562814356037416 0.252785146378446 0.549183468709234 0.842962751106825 0.657305604789872 0.26696514651645 0.850491133083124 0.685924167835619 0.844479701048695 0.185277670098003 0.797979033142328 0.469599463497289 0.91119134680368 0.991093801136594 0.215068386625499 0.0980495405406691 0.831591208963655 0.123601649166085 0.79799633764429 0.126966549023055 0.543556312883738 0.409173474258278 0.435980467111804 0.741701307797339 0.914831557730213 0.154024692843668 0.239531810123008 0.942509454798419 0.891907947701402 0.191378566774074 0.963622939193156 0.823935058619827 0.114719168532174 0.493326816274785 0.65122307454003 0.435721642952412 0.283625981765799 0.570040138233453 0.723067960552871 0.540336212059483 0.719346802968066 0.271721335661132 0.218531138182152 0.394036691188812 0.099942576251924 0.276975790874567 0.467386331264861 0.982635968043469 0.511672481850255 0.989235471701249 0.576585022979416 0.454040893421043 0.258795260170009 0.850504628303461 0.0966773937805556 0.393850300314371 0.567580076453742 0.153079293961637 0.112055251868442 0.491418692111038 0.364544208957814 0.335144559007604 0.197453190332744 0.865845206326339 0.699519431258086 0.380314824818633 0.475381877168547 0.65001733594574 0.580981452604756 0.15299521754263 0.403545962767676 0.271212609626818 0.0864291833410971 0.885652454951778 0.898352042534389 0.281313371409196 0.71942975084763 0.941192746616434 0.499901737549808 0.830293286030646 0.114287293590605 0.210779602974653 0.119146352931857 0.439470116908196 0.0818463065987453 0.639892622435 0.665911600405816 0.978033442129381 0.299611563414801 0.777675279255491 0.0408729183161631 0.282844451605342 0.546454165678006 0.88775951507967 0.3786332083866 0.588517267589923 0.423114825645462 0.705961772198789 0.882649819944054 0.852782336687669 0.35047305455897 0.468939167424105 0.550700724758208 0.580992729701102 0.267798914499581 0.517887325973716 0.161309423937928 0.0553854699386284 0.347075507733971 0.68509902455844 0.350137609117664 0.955975079557393 0.417752428723034 0.61691911833128 0.798886379315518 0.224497406280134 0.627440242615994 0.102613431497011 0.882136849670205 0.689968672946561 0.775438490568195 0.042884385206271 0.98648483844474 0.312141439733095 0.662199593994301 0.123732953669969 0.895100788166747 0.549169219976757 0.703752729308326 0.721238719590474 0.703518439817708 0.242374540818855 0.412197066307999 0.097231815289706 0.852807702086866 0.519886214351282 0.232013424572069 0.292396135844756 0.746593570539262 0.26191050110152 0.634327428864781 0.44706076862989 0.52361695645377 0.0626463163807057 0.198819234082475 0.309390161300544 0.461763846108224 0.721866846526973 0.760178210339509 0.195345604890026 0.423039081194438 0.146291400052141 0.473297410649247 0.624690286575351 0.238267523704562 0.384931408609264 0.461851838300936 0.134806456521619 0.679168566842563 0.586588897483889 0.689309040028602 0.255512398860883 0.477362668116111 0.368948862676043 0.309219894525595 0.536877206396312 0.123504508566111 0.235857350467704 0.706468937501777 0.673431957212742 0.2977540962887 0.036215797001496 0.0246406987053342 0.884732244904153 0.607349137277342 0.680641018308233 0.885719446076546 0.397791783788707 0.402231168677099 0.731547232898884 0.820941499411128 0.986203390019946 0.318257552098949 0.0126020493754186 0.488113743376452 0.906139811326284 0.738227423899807 0.249881161530502 0.871095694594551 0.781860290293116 0.851344992341474 0.701778094617184 0.152058285702951 0.720858825691976 0.189686425835826 0.233486682104412 0.157066435799934 0.555795243850444 0.699048195276409 0.983063977691345 0.931725211404264 0.626815866183024 0.951274015738163 0.604323328025639 0.692295257046353 0.903323956280947 0.861200866827276 0.289176933057606 0.412827320550568 0.791019121792633 0.819095740190241 0.876945133274421 0.380756959880237 0.362646331314463 0.0817902813921682 0.776936430751812 0.766933528506197 0.396969968043268 0.872888045501895 0.593641852024011 0.507474134638905 0.819623566570226 0.562283530822024 0.993660229602829 0.360994722368196 0.810029154343065 0.201503127231263 0.509528884335887 0.414813174251467 0.0851506839180365 0.771775936128106 0.427049302770756 0.0890970692550763 0.173382167790551 0.933889155359939 0.663301222750451 0.548640998054761 0.747075577664655 0.103500808330718 0.641036798004061 0.901122821695171 0.567300546038896 0.487233030595817 0.524682794190012 0.856448958341498 0.136194825344719 0.573265006768052 0.130455111770425 0.814769533332437 0.497542599374428 0.237681079888716 0.365067364899442 0.531906019654125 0.230404859171249 0.210033368945587 0.488083661899436 0.165563394359779 0.746711656656116 0.158709722228814 0.697772422234993 0.159868130164687 0.555885982478503 0.953043528704438 0.0251034485129639 0.913229367332533 0.274201745956671 0.684664183512796 0.667937782565132 0.256310552619398 0.406111306950916 0.707975263360422 0.637927793082781 0.084438950556796 0.896825621712487 0.309102757617366 0.347849061130546 0.051149600634817 0.377628403289709 0.942807433467824 0.453787471314427 0.1965298816422 0.626940358420834 0.212882911907509 0.980314901017118 0.109720903066918 0.32360417666845 0.539407078113873 0.732811874060426 0.774813237304334 0.955891322845127 0.597402480829041 0.962100695765112 0.38980419666972 0.183880562470295 0.577444543836173 0.809848992102779 0.172412173617631 0.029607588192448 0.672159073979128 0.722824495455716 0.546898721936159 0.0782658342714421 0.138650202625431 0.149347499154974 0.144504651734605 0.328468444901519 0.344457198954187 0.145504451012239 0.0288240236183628 0.44810089429142 0.361428171179723 0.285586162116379 0.266551522058435 0.247192981268745 0.294362884589937 0.636699854577892 0.321740821129642 0.118979027597234 0.22886531193275 0.23171550468076 0.381407421801705 0.768672321503982 0.0404148318013176 0.720808177413419 0.904807834899984 0.908735692228656 0.893349099485204 0.669930027173832 0.299962748938706 0.29533763471758 0.940927807230037 0.814287535888143 0.760976757796016 0.148225213470869 0.465368604622781 0.473564724670723 0.167567600887269 0.581774834273383 0.452431487839203 0.537540121898055 0.726974942437373 0.0497152855503373 0.591929756267928 0.562478600339964 0.364069407335483 0.0965555645362474 0.310655334000476 0.618196298819967 0.288963687047362 0.850951578328386 0.149148323007394 0.930336409467272 0.299550134772435 0.649321213124786 0.944577860836871 0.294045280490536 0.737322313829791 0.331646258688997 0.0642869193013757 0.863401923964266 0.306478601684794 0.0973280822858214 0.803182942650747 0.509894433151931 0.430239618313499 0.11860719159944 0.0113338119164109 0.211317064121831 0.207538786213845 0.763066289143171 0.912594486216549 0.0455383660667576 0.361516002020799 0.0109113610628992 0.0204780092835426 0.749633077622857 0.861290060859174 0.531883430425078 0.99356049377704 0.109279931120109 0.166679064396303 0.0709203280089423 0.289701143547427 0.270411585422698 0.885621108477935 0.775366977679078 0.494819971460383 0.277122423322871 0.878921852398198 0.351993238679133 0.100964336178731 0.460963635577355 0.444612166273873 0.527196631012484 0.660351922756527 0.317025185183156 0.140479939398356 0.24967675321037 0.90370630641235 0.214037775408942 0.441474613407627 0.0661199635523371 0.161957224018406 0.348460377070587 0.651958512531128 0.23138683116762 0.554713158465456 0.403733838307671 0.0222798905405216 0.170968105518259 0.706859046802856 0.21840593668865 0.197321904269047 0.177418854492716 0.0701443280605599 0.97549283038592 0.315338576301001 0.829106649856549 0.0387425659270957 0.444807320616674 0.826879855750594 0.813234485499561 0.797410508117173 0.909884866471402 0.0738799653411843 0.719182063639164 0.181866521099582 0.320061505802441 0.569690503759775 0.37550132495584 0.285303416654933 0.702256644899026 0.709779565813951 0.0986394707043655 0.581345851905644 0.979190833780449 0.168247366340365 0.966710136057809 0.302337999457959 0.170488652819768 0.709439375943039 0.233389418877196 0.29505680104252 0.266395250002388 0.0671182394400239 0.791095958594233 0.539923057134729 0.0279859083611518 0.546792370693292 0.235493925500195 0.566335857799277 0.0832756163249724 0.992030714305583 0.319049219060689 0.706543304701336 0.169780106383842 0.769527353097219 0.321737261712551 0.0594354098336771 0.550608539266978 0.200979638674762 0.576943556687329 0.608442948777229 0.100132984321099 0.872360082203522 0.54699139079079 0.53541102712974 0.92886120419018 0.998854667770211 0.218610431216657 0.329094921902288 0.989835721454583 0.252627883392852 0.706651611756533 0.718770092113409 0.695023522125557 0.415694549956825 0.824117743938696 0.635454550026916 0.288085117938463 0.014747202550061 0.0622705682972446 0.726907615240198 0.421879847829696 0.181257801537868 0.686419295154046 0.656904155695811 0.351084766502026 0.0595550096593797 0.43131234184606 0.302822277031373 0.0424877711292356 0.309300975797232 0.862768752023112 0.713327146379743 0.990471511210781 0.808433939868119 0.380225825330708 0.362052166131325 0.752420468856581 0.53282096618088 0.261189434009139 0.939583810798358 0.20202714709565 0.915370885946322 0.132853447559755 0.169635448418558 0.516660869829357 0.160469284639694 0.737332701417618 0.524309040412772 0.100589235115331 0.375125413676724 0.974138911289629 0.872636358847376 0.961555969184265 0.694960278046783 0.762423532914836 0.241148169729859 0.891179780215025 0.77791116266977 0.536374678339343 0.218165689865127 0.0509202535753138 0.734576893153135 0.889881253826898 0.756229694469366 0.853042291230522 0.103030149757396 0.827166139192414 0.570169388500508 0.364768035947345 0.734180255795363 0.313851941104513 0.482062537933234 0.78067062554881 0.160322239131201 0.096433463068679 0.389912470532581 0.696262872801162 0.746806257350836 0.551461634640582 0.398531124184374 0.145072132584173 0.522073491597548 0.051752185607329 0.414052856299095 0.326876169561874 0.925981455971487 0.868635589941405 0.0346811539307237 0.986440254452173 0.896913991007023 0.282082143495791 0.606263638613746 0.390417661352549 0.912939172727056 0.542981095453724 0.619128589495085 0.332471222635359 0.548507661672775 0.661561330026016 0.491611688951962 0.998762373942882 0.244858461434487 0.634956885338761 0.689506348876748 0.772792117206845 0.238253230946139 0.60695067526307 0.837636863219086 0.149094967017882 0.483953453022987 0.738348985300399 0.29415431109257 0.131326993545517 0.331804340649396 0.0311089660879225 0.747593566665892 0.212394080760423 0.496014046175405 0.994745701528154 0.593192984911147 0.87485922772903 0.167021151992958 0.408514708490111 0.426014312470797 0.690233069499955 0.777769616947044 0.44112066531321 0.719410932406317 0.143319487317931 0.661356220978778 0.505794175749179 0.456296786833555 0.353086115492042 0.59161266826326 0.129439955735579 0.612701135086827 0.144504588576965 0.760616649757139 0.280318554900587 0.643774679410271 0.393826071291696 0.195846365916077 0.388166573913768 0.04933978341287 0.310897004406434 0.0495753904548474 0.295256232125685 0.208558036892209 0.402455526744016 0.18614197019022 0.147973769996315 0.448961876763497 0.511847148914821 0.0760074313799851 0.583927246658131 0.579054568777792 0.102814746245276 0.800520827593282 0.68492952696979 0.808636728217825 0.793587465272285 0.262978710476309 0.931272368356586 0.423578967917711 0.189629848576151 0.554391805706546 0.126680489860009 0.461286445802543 0.384608734841459 0.785658298509661 0.460852903868072 0.69322933457559 0.452050828442443 0.989791002848651 0.110807582824491 0.603578151080292 0.899473301330581 0.787851124408189 0.0348855087743141 0.729897766932845 0.989176657877397 0.811992185777053 0.285534015111625 0.50034677002579 0.860910778944381 0.617618053972255 0.535039210724644 0.635741348410957 0.0358855922613293 0.529183691162616 0.153588107356336 0.469374820990488 0.362659501296002 0.537413482300471 0.577162186771166 0.144352472247556 0.751669782444369 0.588417886507232 0.80706388537772 0.0126693599764258 0.828587559284642 0.108944189944305 0.618978816221934 0.802065198093187 0.627965615068097 0.120485448653344 0.0714502812339924 0.248830987811089 0.213845742528792 0.821461279646028 0.157593072326854 0.507357612480409 0.256630946027581 0.404778459686786 0.983442328607198 0.234903709052596 0.900300733265467 0.753115253611468 0.83225206146948 0.0116993736405857 0.0353447683155537 0.566216966076754 0.987725008786656 0.945416393994819 0.343612741194665 0.32385242837714 0.760465066810138 0.260323127163574 0.611804449877236 0.119761435510591 0.49388567334041 0.0188171505089849 0.228468151334673 0.658302492361981 0.710435281805694 0.736516845540609 0.307642336990684 0.686766228831839 0.832854599189013 0.150513756386936 0.662457733561751 0.230802401020192 0.954830306065269 0.701918657247443 0.697190408674069 0.398202088782564 0.576794454867486 0.780640554213896 0.100572835796047 0.658615575619042 0.957890232889913 0.823642974817194 0.794365616498981 0.0700603191787377 0.623192033830564 0.518406537789851 0.416163574960083 0.982830524693709 0.0373830728232861 0.51486440814333 0.812336479972582 0.916217306433246 0.257422165814787 0.799058960333932 0.333734362996183 0.570608606324531 0.110531335915439 0.167912356548477 0.28803529554978 0.366741659885738 0.948817688096315 0.680323088739533 0.794153555501252 0.624524885935243 0.522496502802242 0.739412015287671 0.806537226953078 0.257254683738574 0.704223065178376 0.936937545542605 0.328860357883386 0.517239541106392 0.882707362317015 0.903837102658581 0.528184225652367 0.684898619141895 0.102063640779816 0.586583276453894 0.454781190170907 0.486986811687239 0.276181671367958 0.854933358221315 0.377367059739772 0.932054167052265 0.0352388914464973 0.493549724020995 0.943013697331771 0.837188600713853 0.771486321927514 0.643788931600284 0.199499748668168 0.89546248667175 0.472014856229071 0.10274957286194 0.384500481723808 0.575188603170682 0.0856609794427641 0.45513523853384 0.60954842392588 0.0765012648887932 0.246842972459272 0.472444255345035 0.870814154660329 0.489903622607235 0.0281433156412095 0.123221097413916 0.394526190101169 0.553626864799298 0.027621410866268 0.332374892020598 0.718803087139968 0.275609948353376 0.444334343881346 0.179576901276596 0.686462714418303 0.209194113854319 0.525786763236392 0.668654614868574 0.368034553257748 0.93475703884149 0.182314128747676 0.370682606059127 0.836823180979118 0.213761293387506 0.797973484951071 0.0783405649731867 0.63006307246862 0.0657434972235933 0.729010664627422 0.506100587346591 0.744866932390723 0.83540005378658 0.496001126749907 0.145657316243742 0.594771684585139 0.688278939605225 0.607308457533363 0.0269067309936509 0.127588871449698 0.764815147717018 0.287136491793208 0.331315614380874 0.759486882428173 0.172299104614649 0.498103098999709 0.472972413648386 0.939050080331508 0.531954790721647 0.331783568931278 0.0612717963685282 0.48009152535582 0.31254365939647 0.517074897896964 0.222642210524064 0.689844853314571 0.467876757718623 0.677521322227549 0.492463587787934 0.71819797885837 0.860245401447173 0.496200174507685 0.690727598434314 0.537011205242015 0.0722557214018889 0.906049394479487 0.322479840666056 0.0563413274032064 0.420240740177687 0.0638457309128717 0.681640842480119 0.502789180858526 0.953230736479163 0.780723657682538 0.872258722949773 0.175116461152211 0.274184794123285 0.764685138405766 0.0730179926310666 0.185389080175664 0.892324085556902 0.185349755554926 0.811715587121435 0.319391170891468 0.860879154023714 0.121650859250221 0.456070267576724 0.442000211521517 0.545614539477974 0.579402774367481 0.175027668424882 0.881183264036663 0.620773253405932 0.161474125694949 0.89160732332617 0.132394291514065 0.216847107699141 0.625670010482427 0.508342075285036 0.0842577141756192 0.621787796304561 0.737325530720409 0.792760607518721 0.949325937451795 0.74554809537949 0.211124694708269 0.416183186329436 0.253836630964652 0.956569293837529 0.6233691831748 0.261751806235407 0.419680404670071 0.611909009425435 0.831605198381003 0.201265065339394 0.954038402377628 0.263664991077967 0.133085897872224 0.209660889385268 0.307015077203978 0.0658427577535622 0.74895911206957 0.613044837813359 0.343674705524463 0.133352031721734 0.216731255841441 0.805203172548208 0.123788980029058 0.139317503664643 0.571838138983585 0.617481499547139 0.712111971941777 0.614227732243016 0.969160745858681 0.934025329456199 0.584779173845891 0.479933531447314 0.589204852143303 0.670349057142157 0.790706404803786 0.587613157208543 0.737739160018973 0.797074115772266 0.711289751664735 0.56366513670655 0.308151092759799 0.838059135202784 0.806412859647535 0.236934412515257 0.253166208693292 0.327188104456291 0.4103392345272 0.632095501010772 0.832490456898231 0.970572709362023 0.569867421449162 0.421085853946861 0.542784251759294 0.976788410032168 0.597099929223768 0.0941464363969862 0.794780926620588 0.652844273082446 0.846068744976074 0.988779488981236 0.44098637880059 0.257241950328462 0.688321552341804 0.803823951440863 0.812987163637299 0.756877106153406 0.115195019401144 0.0444061955204234 0.410564267965965 0.743507697219029 0.116135640661232 0.398767997836694 0.790479404949583 0.63311471757479 0.759397596656345 0.371394122287165 0.306686527009588 0.123481942387298 0.0231789729744196 0.486313690925017 0.391802057006862 0.878023282140493 0.988611695726868 0.309421585223172 0.578597460284363 0.29477845079964 0.405368922771886 0.054784225106705 0.969877613198478 0.787295492070261 0.476342275529169 0.753484703218564 0.63627676661592 0.507513612313196 0.831823009259533 0.254231617925689 0.394388378746808 0.234320014899131 0.202163797640242 0.366710763813462 0.562762344798539 0.334657871532254 0.955505997159053 0.503870086763054 0.281416741104331 0.6927746166219 0.879457018664107 0.794338000244461 0.748564124647528 0.667266403248068 0.69462122224737 0.15472999611171 0.908079233558383 0.596703269276768 0.317395364560653 0.104662471881602 0.12080213212641 0.499831696648616 0.797143329400569 0.841301878963131 0.580328221428208 0.311742622745223 0.296905338969082 0.228281008331105 0.117634904850274 0.863343094466254 0.207157383908052 0.928527237882372 0.0466179781616665 0.571386464582756 0.239183827890083 0.0481236339500174 0.163375058185775 0.0365219995332882 0.954684475765098 0.722655524795409 0.919684864194132 0.871131847503129 0.334920553609263 0.354008451693226 0.334301585683133 0.0187371030403301 0.693615003940649 0.54477699194802 0.708111386976671 0.709410378749017 0.135656463855412 0.130486326396931 0.610747143262997 0.480047560262028 0.111924752509221 0.700832067385782 0.247309069621842 0.144353607702069 0.269799952080939 0.624066542410292 0.481334581125993 0.899792121560313 0.349063024509232 0.575844691884704 0.491826797882095 0.945706321217585 0.0990989674325101 0.799292352939956 0.175261771208607 0.0143109399965033 0.484777602374088 0.442648248097394 0.847165559460409 0.390994592797942 0.469837491505314 0.247946617649868 0.785320444088429 0.552059364772867 0.031214241576381 0.639020714382641 0.642466429742053 0.773737913705409 0.978515341610182 0.556361775030382 0.125624731990974 0.724450109500904 0.174086884199642 0.0959282591100782 0.843172478959896 0.397020104145631 0.744727563762572 0.703537805932574 0.821169245401397 0.891355608319864 0.883773110618349 0.0676810385566205 0.478733378616162 0.768395207906142 0.498559953479562 0.83225893343566 0.773345697382465 0.251670610874426 0.789126051045023 0.789818967578467 0.970559436806943 0.776670370893553 0.341924637504853 0.0657262996747158 0.279208066787105 0.550729787875898 0.341185567257926 0.403315786360763 0.0464633839321323 0.595382055465598 0.202003254375886 0.793945154880639 0.248684660547879 0.957192792287096 0.42710423101671 0.394288979915436 0.564097773919348 0.771912806802429 0.97467149685137 0.791994282675441 0.542534416960552 0.308485753110144 0.592763865394518 0.29137687318027 0.699321063021198 0.969416232574731 0.300803196879569 0.0357003059540875 0.306477924238425 0.993304935144261 0.760874319560826 0.542358251400292 0.0489075940661132 0.173250974158291 0.660892499373294 0.267816859567538 0.467620144076645 0.372266691420227 0.947885161847807 0.168824416955467 0.056361838884186 0.920442426721565 0.150978200386744 0.0825504744122736 0.0983731522224843 0.381818553376943 0.757111926260404 0.0329552967241034 0.571609307788312 0.0198017156566493 0.106528170937672 0.461350693718996 0.226645925249904 0.116375835852232 0.392338486195076 0.515636067271698 0.110575765932444 0.521728439279832 0.628014066428877 0.951510038375854 0.993773231760133 0.592350950883701 0.986589539060369 0.257631845953874 0.560414530050475 0.608549557260703 0.969879643232562 0.225800529806875 0.535391078996472 0.600752307216171 0.497980908097234 0.619839140379336 0.538824435973074 0.875455230937805 0.0123510067444295 0.154203121014871 0.560851012733765 0.437758626912255 0.284916096893139 0.300905819977634 0.412780432226136 0.418336767361034 0.472312326640822 0.106916588582098 0.894763084955048 0.0342468979000114 0.365831121716183 0.113036641615909 0.342882684741635 0.687638292012271 0.863553609715309 0.793489533127286 0.550394255074207 0.821271724204998 0.897815518148709 0.803970761836972 0.0302367747481912 0.869666891512461 0.477041756308172 0.150679016420618 0.313235863447189 0.725359206569847 0.22411947741406 0.50103150049923 0.827335430250969 0.207144681846257 0.567883601239882 0.314857601134572 0.604430177153554 0.530749448360875 0.72942498474149 0.65939491254976 0.874701846034732 0.310245882095769 0.797439350183122 0.395436032845173 0.420507190506905 0.776307305740193 0.137137897766661 0.671438343420159 0.477737238332629 0.458332348132972 0.136590452871751 0.833430618536659 0.413826610648539 0.343856146130711 0.277195161792915 0.164112517221365 0.0972412880137563 0.348083098912612 0.0333440854772925 0.820964963396545 0.381691520081367 0.192148764748126 0.749016187444795 0.840249109326396 0.336022302226629 0.411622097129002 0.379402426956221 0.0513095199293457 0.499672191566788 0.0977565879747272 0.830155374638271 0.384623616072349 0.688301717615686 0.334854161099065 0.458006874914281 0.0719310692325234 0.0763416298036464 0.103616517968476 0.486797689360101 0.491357961660251 0.118079720193055 0.506746682401281 0.103765748639125 0.463254668149166 0.55016222312348 0.788457487544511 0.263755178344436 0.102837752914056 0.897447150289081 0.976489352611825 0.357863220188301 0.0754680291726254 0.237415970391594 0.677313291332684 0.412201127528679 0.557705007346813 0.497951705756132 0.166801715381444 0.488352462660987 0.730413370465394 0.946491236535367 0.153615916771814 0.522163012251258 0.213540194393136 0.996469174879603 0.478604336031713 0.287179828076623 0.24181012541987 0.696498703660909 0.553521373791155 0.0514522564271465 0.304377743913792 0.869970744072925 0.0569069427973591 0.54400576754706 0.838335375196766 0.249456236695405 0.0375623992620967 0.49729034084361 0.840646166659426 0.873067675051279 0.369347254156601 0.0435166722489521 0.847205155382398 0.0538017188059166 0.859223593345378 0.366658154190518 0.0116718350653537 0.942397194397636 0.21355231651105 0.101413525764365 0.353119036757853 0.233583850825671 0.821341013207566 0.931831923383288 0.637142113880254 0.823688617276493 0.79991557985777 0.461175392081495 0.731918378542177 0.0537550614448264 0.23886532506207 0.287815308729187 0.590843987225089 0.924604777765926 0.20772739544278 0.334499051272869 0.083436801538337 0.982452752799727 0.603051054009702 0.982963492502458 0.770626383400522 0.987939126326237 0.248844183839392 0.751171152642928 0.753485649430659 0.114444709399249 0.711494812997989 0.392122260250617 0.172854204261675 0.55995093153324 0.670137871131301 0.926916105377022 0.311024808271322 0.753912742140237 0.50817861570511 0.418895226118621 0.143986137418542 0.595133542367257 0.851606192979962 0.734337453779299 0.287216752246022 0.573007245224435 0.947998016483616 0.26163416567957 0.452447652046103 0.629545253117103 0.891473174192943 0.622585787328426 0.0809891573805362 0.576428806474432 0.345063088177703 0.519328451249748 0.590091565360781 0.313461039566901 0.0412492638616823 0.108961636896711 0.586686448839027 0.62425774571253 0.214433557603043 0.938819104081485 0.151442042314447 0.0512989659188315 0.921084017069079 0.19039126095362 0.704133411294315 0.683599167978391 0.396779370040167 0.597664802400395 0.579590756860562 0.659993956314865 0.0219232875201851 0.659109873820562 0.301266109421849 0.313609699052759 0.774050713675097 0.252419928563759 0.195114968861453 0.887346836833749 0.658554151586723 0.991410529788118 0.0552242598310113 0.950586306252517 0.812502960746642 0.249726062500849 0.0140197247266769 0.402631790498272 0.369243586191442 0.667587582208216 0.766657835955266 0.179397611257155 0.203517750850879 0.868433224102482 0.832003656246234 0.021721740195062 0.409511811351404 0.175623214086518 0.616864612826612 0.33037649461301 0.939722577123903 0.706638639776502 0.725923800838646 0.507580625796691 0.704183005485684 0.776581806133036 0.232904382490087 0.03883876377251 0.89350873549236 0.780243282052688 0.0498588297283277 0.481164502671454 0.346839315907564 0.877738654857967 0.325815631074365 0.994131793128327 0.97099747054046 0.751397785537411 0.835460942592472 0.788339980219025 0.712407705518417 0.33273294536164 0.504862619224004 0.573478754120879 0.526178848173004 0.543329675609712 0.609600056218915 0.271256566653028 0.739943448798731 0.41207908714423 0.314150134832598 0.119188113501295 0.190809444286861 0.815318793663755 0.483268041184638 0.236090523635503 0.227902071939316 0.63685305173276 0.624057580940425 0.551140405891929 0.832389809666201 0.603734893361107 0.700420777455438 0.528661613971926 0.0445319490670227 0.625124805839732 0.509601267832331 0.574452777935658 0.666680165731814 0.775203385329805 0.0641559310466982 0.631165850970428 0.474134278658312 0.654538383202162 0.318867088791449 0.315006485129707 0.704396711117588 0.316463513914496 0.115781010740902 0.260604184425902 0.496447947924025 0.606116969976574 0.951555754134897 0.858437726974953 0.507209725177381 0.514338278260548 0.822652021988761 0.29397809228627 0.160588894838002 0.70827495835023 0.976224855789915 0.459075804839376 0.290746729348321 0.0514922522706911 0.0779991430672817 0.51283811903093 0.321561955926009 0.716773034615908 0.823053123946302 0.326715316963382 0.560624554329552 0.540113636697643 0.621478824978694 0.433165031350218 0.48130865491461 0.536168072179426 0.082425334462896 0.423754075702745 0.974608989688568 0.29263590045739 0.532409124427941 0.858456863048486 0.253572284199763 0.278529397833627 0.946332886961754 0.760857853856869 0.834814598595258 0.844487942890264 0.36196524070343 0.517114800387062 0.844334985457826 0.53753616071539 0.061678823849652 0.274364501582459 0.374772117903922 0.180165076625999 0.494958582427353 0.861938231126405 0.607352277871687 0.989977739707101 0.858648939954583 0.211758214707952 0.446869907854125 0.910634019121062 0.811652909617405 0.710995311206207 0.131698069346603 0.182141027024481 0.424742649516556 0.692015022677369 0.70925196163822 0.654807529025711 0.274376202803105 0.422838245199528 0.163931910572574 0.922850580757949 0.555696019278839 0.987320564545225 0.518475247309543 0.165128303680103 0.266793672370259 0.563788714541588 0.960469603140373 0.95157502228627 0.489701627646573 0.261472651769873 0.504929554567207 0.617951377409045 0.169404650577344 0.169566519691143 0.614738080552779 0.279683156998362 0.85285898724338 0.623636232579593 0.136145091007929 0.0423293332732283 0.788737706469838 0.482816845767666 0.247767285217997 0.371408604288008 0.823875911259092 0.607131789478008 0.360686877737753 0.0809175956249237 0.0558563885185868 0.479172322833911 0.885394831248559 0.361726230755448 0.233190137851052 0.0264066642406397 0.0347799310972914 0.836849304961506 0.70657274883939 0.939658741115127 0.409093574311119 0.602928898143582 0.969656570446678 0.928686466130894 0.269384921097662 0.95975660224678 0.489243230414577 0.330489901301917 0.60959720951505 0.306099773629103 0.958361381050199 0.527932893049438 0.917867199981119 0.424182009976357 0.299381667990237 0.398295066510327 0.605953575398307 0.225177953597158 0.12853004545439 0.977877499691676 0.418707581541967 0.825975594851188 0.850355065017939 0.907981549203396 0.283043247654568 0.929178679669276 0.541820009541698 0.430182527955622 0.0846857321215793 0.91947189248167 0.956102165407501 0.259934280784801 0.544460228951648 0.704085852438584 0.648557077362202 0.823903540652245 0.30480511368718 0.0535032685287297 0.352349607509095 0.884839369251858 0.148764845719561 0.600852437200956 0.124343247562647 0.142811407842673 0.207995906462893 0.144331410557497 0.291514165443368 0.593847017313819 0.808198859754484 0.36641340773087 0.729338986624498 0.128563210822176 0.0830440391553566 0.820323750150856 0.877447912117932 0.72560453735292 0.992222024330404 0.885519829669502 0.493345488116611 0.786484371863771 0.660878124556039 0.138232412529178 0.401384965323377 0.319680047254078 0.262427290568594 0.234557348634116 0.574797141742893 0.320783200322185 0.219623887988273 0.173006899151951 0.74520631596446 0.621505539738573 0.857838780481834 0.664782671644352 0.140880035904702 0.285894035790116 0.0612574257003143 0.721638489014003 0.865973255445715 0.825821768655442 0.547838346043136 0.193529296030756 0.817142255471554 0.815275574936531 0.889871968270745 0.107398662553169 0.874339165128768 0.802919405871071 0.667177011445165 0.829285184750333 0.905122648077086 0.576903330110945 0.0926074933051132 0.500396657877136 0.966004297793843 0.760962174835149 0.101350666393992 0.560969003653154 0.398490090619307 0.513496892175172 0.82863964658929 0.367834395631216 0.81088759714039 0.465780489940662 0.580245448960923 0.670965714743361 0.842713320839684 0.671680836258456 0.569981683301739 0.543913566612173 0.39931375683751 0.70275075915968 0.605358153746929 0.832855384049471 0.165052329648752 0.446169974368531 0.186808802157175 0.466649966423865 0.070318122212775 0.445340713167097 0.812144487199839 0.806312702693976 0.258188904870767 0.0983652526768856 0.404370064404793 0.599029984993394 0.760171898724511 0.951840934162028 0.304592686882243 0.156723032495938 0.963295353651047 0.0186898631998338 0.242670991027262 0.251394974335562 0.0957937646843493 0.488844930904452 0.407780603724532 0.414445969737135 0.748092531848233 0.372832488680724 0.125139983270783 0.390890133057255 0.760524402952287 0.110147960048635 0.159046398783103 0.551214630871546 0.22863394636428 0.594319630777463 0.328320018453524 0.84434371780837 0.348781762099825 0.846083331163973 0.952650440621655 0.449600348183885 0.288395850763191 0.393784995775204 0.0427897586952895 0.392832527155988 0.406414957591333 0.829719213505741 0.723212449098937 0.59917326040566 0.26145230763359 0.393743762825616 0.998648973016534 0.846698445091024 0.164171477644704 0.790525443872903 0.243292770159896 0.986901304996572 0.326607002301607 0.328899248007219 0.763990048926789 0.979469847178552 0.753346773386002 0.134055534305517 0.427442050632089 0.467830444728024 0.762445565711241 0.456412999657914 0.0402415717230178 0.0477409452106804 0.321484572603367 0.0579706907994114 0.339725854734425 0.279782156830188 0.0690083816554397 0.252892011641525 0.881448532580398 0.238625810544472 0.977843026223127 0.0821531877294183 0.898152299351059 0.2411152634467 0.984810318488162 0.467989579392597 0.871723367210943 0.923444542177022 0.377636477095075 0.947725339133758 0.490110392884817 0.817839310213458 0.995783387091942 0.506039418710861 0.181304047221784 0.853740034021903 0.914003628832288 0.956448351796717 0.476345953424461 0.061126859264914 0.651423586679157 0.306206068398897 0.306442459148821 0.887583375335671 0.663773055963684 0.549041359638795 0.38140814327402 0.202627906028647 0.646257231994532 0.431734743372072 0.529944826015271 0.655987406410277 0.452615967388265 0.861396821013186 0.882614936872851 0.614772931814659 0.507639258676209 0.294603999485262 0.951962389070541 0.363485320636537 0.362623458337039 0.534328809897415 0.735544785836246 0.883389047393575 0.153187076163013 0.554906772591639 0.80044049337972 0.762986910592299 0.905171089526266 0.164615706359036 0.579998150840402 0.419958614537027 0.241629996371921 0.313891073947307 0.788028043941595 0.506504136086442 0.533032904551365 0.481052209539339 0.122214339962229 0.0970199444564059 0.0188950826576911 0.412982836097945 0.501977339410223 0.612551013755146 0.80613606713945 0.898557026879862 0.111327686454169 0.298273407912347 0.494793785933871 0.182995465765707 0.564193547179457 0.963462966652587 0.814646230486687 0.13182847373886 0.255466619252693 0.87875284508802 0.163782516245265 0.100115644091275 0.894578174366616 0.327170070414431 0.978560600052588 0.0117528169904836 0.927699551703408 0.115017947275192 0.10441794993123 0.844643249833025 0.730860596632119 0.376906131361611 0.0444722750084475 0.0761333511187695 0.0625528891733848 0.143826205215883 0.471505097774789 0.450197564295959 0.964963454578537 0.880865629971959 0.212698923558928 0.325293206977658 0.104629639128689 0.986389958381187 0.405823879064992 0.128038558689877 0.325657947191503 0.118423031065613 0.352477829735726 0.851361262579449 0.444129782277159 0.0355778151680715 0.415373427700251 0.830851935413666 0.769692393001169 0.396885129353031 0.980767005074304 0.979332861944567 0.448100167748053 0.13354364416562 0.794028965069447 0.629084689854644 0.779305502194911 0.83678125974955 0.949472080082633 0.973009053834248 0.644792077771854 0.098720153667964 0.443035279270262 0.214025612953119 0.67026197474217 0.622601429678034 0.453358152182773 0.875787720186636 0.838364488794468 0.487897926343139 0.700062990575097 0.923807196344715 0.767737253506202 0.0112517438642681 0.784230694039725 0.768867833125405 0.201887700557709 0.119622765304521 0.731714266878553 0.736793370665982 0.121513756921049 0.415631283980329 0.559054917315952 0.210934227399994 0.810202443464659 0.303312121697236 0.283280226415955 0.972821566229686 0.522967610394117 0.0992039946699515 0.962631797583308 0.869032853804529 0.160464547586162 0.951892984816805 0.314059711531736 0.5783724367572 0.180445972075686 0.886493924940005 0.108589896787889 0.738623047047295 0.393701103297062 0.659059863572475 0.746181516724173 0.0539891994954087 0.985794215179049 0.435788058051839 0.399339990769513 0.512620715911035 0.823122326740995 0.756698645942379 0.0214223303366452 0.80378251680173 0.456976563350763 0.782517643773463 0.857991356432904 0.453350215295795 0.190794740312267 0.0290109190624207 0.588932152895723 0.524916272773407 0.594576557441615 0.632540542476345 0.318928089390975 0.556967130640987 0.188092761258595 0.220247127353214 0.539561924051959 0.0218602896179073 0.118058011713438 0.0720661913161166 0.629675792353228 0.231234232627321 0.746837590686046 0.513426197799854 0.419373006522655 0.101599385330919 0.539972064236645 0.93383808180457 0.583804332439322 0.991809875087347 0.402063453102019 0.719063576448243 0.386224064102862 0.111744734332897 0.290996214936022 0.0211245445976965 0.856819231302943 0.265304337069392 0.799016672605649 0.849298193822615 0.573320364670362 0.684022737690248 0.875671208631247 0.696575283452403 0.969787575758528 0.795957131872419 0.842255832478404 0.895253572952934 0.490435167450923 0.688133662510663 0.867486461568624 0.408269391767681 0.781545109003782 0.51838773917174 0.670407335739583 0.477013795452658 0.17169322991278 0.637085773807485 0.539195169247687 0.921145515092649 0.310474066040479 0.394485329182353 0.645848850773182 0.917780541474931 0.335508571295068 0.504888566872105 0.322039752695709 0.643956513023004 0.157429859614931 0.846954189047683 0.106184202211443 0.488738076474983 0.118747584579978 0.877814538993407 0.627249220719095 0.507637309778947 0.386513281147927 0.285606480205897 0.571591639784165 0.494546518009156 0.515866676562 0.676829214526806 0.726624825061299 0.719122618930414 0.380660848242696 0.310057345936075 0.305200070452411 0.23455410131719 0.404410529090092 0.0417233352526091 0.314937088021543 0.511782784364186 0.105332334723789 0.775012405845337 0.584306329649407 0.120440513375215 0.385021512664389 0.772693295783829 0.67544386390131 0.50122973781079 0.219850125571247 0.890558895200957 0.273882151700091 0.902896615089849 0.863490058607422 0.70345146344509 0.426361136429477 0.15492935182061 0.546339279164095 0.742030444159173 0.918808926730417 0.370218956370372 0.52885838505812 0.521844563360792 0.157814058605582 0.435111827352084 0.498565604013857 0.447908435212448 0.566668273748364 0.75384601932019 0.344441312272102 0.912921203686856 0.339884316562675 0.813712862904649 0.405064513087273 0.0119441214832477 0.372573683653027 0.751017021031585 0.739940564753488 0.0695267253997736 0.615105208079331 0.182255505088251 0.291852189744823 0.806238833840471 0.734363864737097 0.570343434591778 0.48779272668995 0.504598529469222 0.78949471463915 0.231110571580939 0.780820240466855 0.301250850858632 0.738543104457203 0.201567644374445 0.996462818086147 0.87061104360735 0.954691947498359 0.931206975074019 0.109659152182285 0.680459607436787 0.472959919730201 0.545769342773128 0.477601033118553 0.491773123338353 0.940879598818719 0.354267927021719 0.474469696900342 0.125499444981106 0.356266646671575 0.546558730297256 0.493195804739371 0.872183718641754 0.905811507538892 0.751577483776491 0.66443018355174 0.0317215799866244 0.05648708302062 0.617840707474388 0.366102146825288 0.282648025350645 0.731741762349848 0.569793396315072 0.343993724216707 0.205075372469146 0.448686547484249 0.295516845213715 0.18026777832536 0.198945569877978 0.992421601091046 0.652003529176582 0.740591252797749 0.562630042450037 0.934107676185667 0.830237813568674 0.770020473662298 0.109526426631492 0.427063469674904 0.578387929049786 0.847255756868981 0.360024338415824 0.558259694625158 0.536916197941173 0.327929022640456 0.477731641966384 0.478062628109474 0.723752769166604 0.2324237270304 0.874982923811767 0.15057260686066 0.876195872519165 0.572967690101359 0.15763972138986 0.699447631854564 0.265246027584653 0.784525583286304 0.551061638402753 0.610376999382861 0.528930726603139 0.544706264610868 0.926612286008894 0.20721330861561 0.10076086784713 0.773197262175381 0.68824944014661 0.385683938579168 0.997385582330171 0.0517917273612693 0.89973277712008 0.50745409199968 0.0761652726959437 0.648605442284606 0.305833635630552 0.795583196228836 0.29728514112765 0.572447548669297 0.990226102287415 0.602925748329144 0.470342087629251 0.983471958069131 0.66165381470928 0.726708292954136 0.274088212952483 0.814422802727204 0.429648330260534 0.509739851600025 0.894345207037404 0.216641893542837 0.794532562887762 0.660876785798464 0.54593423792161 0.0434607590665109 0.373528326370288 0.222873269063421 0.788519943535794 0.601612324574962 0.920882969934028 0.380020391505677 0.5066182481125 0.277190925620962 0.490712068064604 0.796996524075512 0.330375939102378 0.803608540091664 0.954101488792803 0.144007494612597 0.504292098048609 0.708276233489159 0.334211769064423 0.904062013470102 0.788126739510335 0.735945251837838 0.211099555431865 0.688939075018279 0.712113659218885 0.402982640410773 0.383994959441479 0.1609129585349 0.144845012177248 0.287820353042334 0.949859044870827 0.650686487688217 0.671120813542511 0.444102618037723 0.649330242131837 0.426200931081548 0.189502224733587 0.663221501673106 0.926499752693344 0.731971718627028 0.513287445534952 0.34949246534612 0.0886419428512454 0.309707171395421 0.130716889125761 0.696928658287507 0.585638156018686 0.895598112172447 0.70312003450701 0.521196776649449 0.718228929329198 0.955357525993604 0.0958770843641832 0.942034085679334 0.496118911139201 0.650340236297343 0.319548681897577 0.939534121640027 0.991486224681139 0.201570377210155 0.103619330788497 0.877074498562142 0.885299389220308 0.22813140032813 0.291212231814861 0.360030273620505 0.702665078213904 0.631038923014421 0.578565301981289 0.576200995713007 0.610971352194902 0.204398317723535 0.515257556848228 0.866631431588903 0.668717288684566 0.787747285871301 0.290230601192452 0.790271538633388 0.860709594429936 0.438667097245343 0.365729014712852 0.228730282972101 0.428032284367364 0.803552119343076 0.729984582641628 0.587593538002111 0.990125764620025 0.759752966028173 0.783096350086853 0.867045655814 0.328183994414285 0.677040100193117 0.987741872798651 0.578994152040686 0.529124097549357 0.2616163277952 0.193518901758362 0.42125853408128 0.812307188657578 0.4637474489538 0.0320448957034387 0.440299093208741 0.61749977446394 0.123258089351002 0.933168254920747 0.179100002313498 0.739904957904946 0.259339704154991 0.495808999824803 0.0946591683314182 0.80419897713 0.635723197734915 0.837999117234722 0.621640298780985 0.911173374997452 0.4099068633141 0.73983619467821 0.756967687117867 0.535616181124933 0.860600418841932 0.817453892095946 0.94804369490128 0.892679185010493 0.761383894996252 0.157498898752965 0.619877095585689 0.906743558030575 0.673242890206166 0.517904047535267 0.512905416262802 0.383506915229373 0.959972103722393 0.862104336412158 0.0449151721107773 0.175002182472963 0.78643931603292 0.43715679614339 0.244312590640038 0.487774535675999 0.668264379713219 0.155955732627772 0.819587527760305 0.354012250141241 0.740058788941242 0.540154296387918 0.467685806124937 0.85233780255774 0.919676129308064 0.257335774460807 0.899811059862841 0.156095717388671 0.1952327288175 0.869835028445814 0.457395702577196 0.196630829449277 0.309217731491663 0.272073238738813 0.093729511606507 0.947114165183157 0.924038192417938 0.185093097195495 0.325082385852002 0.388917516414076 0.498708438014146 0.744516752548516 0.591894670124166 0.116775259522256 0.151091850486118 0.938065060863737 0.71264183273539 0.0328717951779254 0.0768713529873639 0.980025591079611 0.37805851604091 0.426263778926805 0.880009798996616 0.156343814660795 0.460060018009972 0.333777740309015 0.405013991815504 0.574848733698018 0.0609162352187559 0.58285833194619 0.114157530225348 0.692575481964741 0.29517423391575 0.261176013471559 0.014831451845821 0.119769901630934 0.517044932362623 0.543362326957285 0.144477798903827 0.744830709178932 0.78698574810056 0.691741165847052 0.766707490538247 0.35243527646875 0.945396432031412 0.894002075956669 0.776628872866277 0.441886436028872 0.364784016904887 0.851567688025534 0.708260436702985 0.644753938855138 0.165169799632858 0.537117089026142 0.359418389492203 0.472853814433329 0.687259281629231 0.644712183817755 0.165073700211942 0.911119923118968 0.906696280618198 0.0144628684665076 0.910325124091469 0.638994950214401 0.0853863264573738 0.723086058213375 0.305678314627148 0.220382693614811 0.627172720220406 0.858871713087428 0.5783458284894 0.238500223651063 0.667934195948765 0.504082767581567 0.469199932413176 0.285150347889867 0.92120819674572 0.37599788161926 0.328694034772925 0.630437260512263 0.666906592096202 0.796128224767745 0.420567354152445 0.869471297601704 0.0214996548811905 0.875696080063935 0.329298609902617 0.648839588172268 0.320250858170912 0.137360444776714 0.9172261317214 0.676253167979885 0.873704625386745 0.185359565503895 0.413758535701782 0.436937393876724 0.375083504202776 0.247064580863807 0.39822644319851 0.564916772465222 0.33952954211738 0.984704431938007 0.653227100353688 0.0546430518757552 0.76628086943645 0.458226673644967 0.41431789111346 0.443408026674297 0.478290027885232 0.67341046517482 0.986243075607344 0.623548699778039 0.663824691714253 0.462766026705503 0.406079427555669 0.493036659932695 0.809939630001318 0.109257812115829 0.787976304925978 0.156019010129385 0.86171196680516 0.514562423804309 0.193612186976243 0.982363420927431 0.992151578206103 0.362454959284514 0.103850782795344 0.947801584235858 0.515711751100607 0.173547705118544 0.461090114284307 0.48527769978391 0.308473399337381 0.740561862136237 0.456277422101703 0.418405845453963 0.505200572300237 0.55141141486587 0.870320089957677 0.597424781469163 0.920375790570397 0.328445381990168 0.40530623074621 0.74707798157353 0.347691730146762 0.129161858584266 0.830235434554052 0.502755289177876 0.936208937105257 0.854590270014014 0.745849813949317 0.250833328422159 0.10948277617339 0.0921947002690285 0.898242592418101 0.555784891298972 0.891951627663802 0.453207076801918 0.850728600739967 0.756383987432346 0.654674386957195 0.390049312855117 0.861240531669464 0.727465066472068 0.07693252323661 0.312010698807426 0.865401919214055 0.788570530270226 0.713626206335612 0.120913151272107 0.313666989486665 0.230291678835638 0.856992321731523 0.92796480803052 0.57953090854222 0.886653760562185 0.541267132628709 0.0208169387676753 0.520307115998585 0.970617752284743 0.564271420089062 0.117414871007204 0.888071759769227 0.50614261529874 0.0563682019012049 0.38864451082889 0.680864662739914 0.926181435880717 0.49529467995977 0.758538117751014 0.0828462550113909 0.815957180489786 0.18839153977111 0.090932166359853 0.6942853759625 0.637996900219005 0.14364657681901 0.816193996055517 0.290160937854089 0.474912233266514 0.996264855763875 0.535423669952434 0.0734645616356283 0.568254590372089 0.246711746326182 0.446178266690113 0.341515679336153 0.461557830495294 0.574777461683843 0.663929497899953 0.370158192266244 0.612308616575319 0.296723753376864 0.148606859878637 0.621572270165198 0.353754221214913 0.0415531906438991 0.0211516267783009 0.492782657882199 0.96425069778692 0.132793311343994 0.596584997144528 0.383184425632935 0.967187884652521 0.909004965981003 0.225369615599047 0.582911324894521 0.291720072259195 0.518623675140552 0.0886566127114929 0.355056473212317 0.798010717532597 0.856593350998592 0.592301248356234 0.775890181104187 0.754683251292445 0.493151004305109 0.360966921942309 0.347620750640053 0.498241026527248 0.282318147001788 0.533201711555012 0.625503988177516 0.690534969936125 0.770242427359335 0.6028584932792 0.305744065188337 0.127222769428045 0.592519509636331 0.459611036567949 0.862308279348072 0.658420796073042 0.396266831266694 0.0928714207862504 0.387424892536364 0.493798087292816 0.351550102315377 0.927994128849823 0.485550473483745 0.454618271810468 0.563321472473908 0.98842285253806 0.936901921406388 0.0197828787751496 0.117567253566813 0.167207848282997 0.649211004886311 0.282635187292472 0.531768866844941 0.219375006086193 0.172139435876161 0.978255758637097 0.215164555197116 0.33897246867884 0.886451185196638 0.249731206621509 0.781904280050658 0.43423484363826 0.525705625952687 0.917342716115527 0.016028274379205 0.852681877776049 0.0548761754855514 0.997976475993637 0.0722043601796031 0.446432455217 0.73724586450262 0.0395913884788752 0.183205561039504 0.596766263721511 0.646095660228748 0.408286053398624 0.34109692965867 0.613433898559306 0.221706790549215 0.527732637689915 0.518566095887218 0.536384536002297 0.394991448696237 0.677621248909272 0.891150403153151 0.252832376998849 0.121742400717922 0.811115159650799 0.995574945441913 0.972065093517303 0.884925643971656 0.494343691857066 0.296500378402416 0.250418814686127 0.904542680224404 0.159521712581627 0.403787344354205 0.814523291373625 0.493178983831313 0.304517370704561 0.700366858118214 0.0483444176171906 0.776479844576679 0.1182414853503 0.753498548571952 0.164335406296887 0.0523973162402399 0.118213434829377 0.683937966306694 0.479078460899182 0.300080434903502 0.337143259525765 0.997733279201202 0.627187383165583 0.485962418040726 0.990716208342928 0.0906993387150578 0.345632533137687 0.53147207895061 0.762460344599094 0.310857613862026 0.49938934629783 0.94673949354561 0.991029250570573 0.733968792259693 0.250472224843688 0.652128483110573 0.867510109725408 0.289738411165308 0.065305916427169 0.528231710977852 0.538459370289929 0.83203696268145 0.0411719582183287 0.933050881747622 0.762218597435858 0.43799702280201 0.113993641680572 0.885462643422652 0.505587110198103 0.82859024555888 0.721478332071565 0.785051829803269 0.788832898633555 0.51076519330265 0.808537345982622 0.424709248114377 0.733616587684955 0.109862859083805 0.210415899329819 0.46802513806615 0.575966135037597 0.172441123789176 0.681914141955785 0.507875503287651 0.643060333535541 0.768648988443892 0.0825461312872358 0.301717174374498 0.627622858553659 0.0714227099274285 0.0830390667589381 0.530049252794124 0.281142700794153 0.238734859586693 0.477659069688525 0.854680909295566 0.224153901094105 0.488746505023446 0.687468737950549 0.634329185062088 0.171299223047681 0.30984281579731 0.928893108710181 0.0517057094210759 0.8552518089558 0.40594287382206 0.921666862973943 0.364589669781271 0.379960514144041 0.759878924030345 0.734817584385164 0.448822657961864 0.89877581393579 0.73956822741311 0.183644765263889 0.375637366974261 0.487568111151923 0.907719196053222 0.843260313258506 0.607331567006186 0.622428083161358 0.321268801440019 0.153800678686239 0.261951641619671 0.642072863136418 0.669391591001768 0.754852943655569 0.668888658413198 0.401214039081242 0.476590826890897 0.706577844554558 0.160064263450913 0.275609813279007 0.659558988262434 0.661615116132889 0.126305905582849 0.237860675093252 0.364307019747794 0.964943772444967 0.953346762366127 0.598227603822015 0.215715105650015 0.64807222399395 0.665274381304625 0.733365041636862 0.735440475922078 0.318975533917546 0.484939107755199 0.51349366606446 0.860389784192666 0.37738695854554 0.850418739905581 0.0591117707220837 0.651295743167866 0.099443075612653 0.509258650771808 0.357703149914742 0.237288781045936 0.0810421231295913 0.760755691071972 0.774574825970922 0.267923808963969 0.856596567197703 0.313174086285289 0.226614061989822 0.984826621918473 0.216291511319578 0.119826850229874 0.753792766595725 0.406084708594717 0.300646275267936 0.413613979388028 0.0249221941526048 0.0880992168001831 0.782655056589283 0.29891136392951 0.321070597090293 0.28454556415556 0.353216616003774 0.0148864782857709 0.109171414768789 0.151921200430952 0.915790887943003 0.667652637804858 0.614039250481874 0.71798886944307 0.237567617418244 0.609597795912996 0.811388312987983 0.469741747980006 0.807322375539225 0.489472756343894 0.0507204723590985 0.0447224428830668 0.362338621527888 0.953957644961774 0.0419832351664081 0.790494620408863 0.924498350457288 0.772793420697562 0.869027380065527 0.662761523886584 0.282088533481583 0.864149029061664 0.584446373418905 0.50263540790882 0.500790689405985 0.833827161388472 0.435478306706063 0.711421632424463 0.302277635505889 0.0316598904156126 0.632074638013728 0.21533445754787 0.308907602583058 0.60216684934916 0.809972156877629 0.0176473382394761 0.753907932478469 0.0208751535159536 0.407862585107796 0.614014204789419 0.014271024367772 0.447345043935347 0.999593254653737 0.341873851155397 0.740029695166741 0.136427023026627 0.360140740713105 0.555313006683718 0.437327217354905 0.216240677486639 0.531779985586181 0.747641949106474 0.906984074080829 0.41232977779815 0.433962778963614 0.780828636514489 0.476624666708522 0.695971331370529 0.186194470324554 0.0887208620109595 0.732517166910693 0.272760151147377 0.434751771867741 0.653163774677087 0.470408333078958 0.498981145329308 0.103671331885271 0.37966159802163 0.813428469120991 0.913960245526396 0.103578423769213 0.975476687385235 0.377910384635907 0.116231245424133 0.813836096138693 0.87121271809563 0.878469258062542 0.776644971841015 0.845976190220099 0.925817962277215 0.582451874497347 0.901069384568837 0.905686663324013 0.866654352280311 0.556786349271424 0.12543844438158 0.717629939040635 0.794582151316572 0.0491146787488833 0.95447868719697 0.310087977852672 0.929772867211141 0.535109470833559 0.678119851280935 0.175870446052868 0.220927369024139 0.2360269414098 0.584249188120011 0.322755189538002 0.414977971897461 0.671054142815992 0.619472625758499 0.0369505992671475 0.948719550112728 0.300265177455731 0.142468518328387 0.406217033071443 0.44400835525943 0.659990514914971 0.811358505578246 0.692816534854937 0.875712885989342 0.810761289927177 0.551063650688156 0.221168397020083 0.285583433660213 0.310933844211977 0.848081830453593 0.770351048589218 0.447532016597688 0.807068505105562 0.270364881039131 0.907183728751261 0.931171222317498 0.312022597568575 0.395739452061243 0.995636443004478 0.576384813028853 0.956406215277966 0.719966769660823 0.634344434635714 0.117430598873179 0.161062630617525 0.462501852586865 0.860624000844546 0.793119243800174 0.682063893100712 0.861977449946571 0.400547858052887 0.647490102557931 0.0693894324451685 0.642878678101115 0.402138286607806 0.998678228834178 0.552193437840324 0.461768303331919 0.806510928941425 0.149689476802014 0.754287710664794 0.280385366925038 0.636917659924366 0.968597063918132 0.331830408389214 0.279914129329845 0.305589667346794 0.897059000488371 0.823390140030533 0.526125566174742 0.746858488488942 0.316480577541515 0.652585355108604 0.380278041947167 0.130811695428565 0.113464546385221 0.124921802205499 0.527355735942256 0.928158512513619 0.677323215149809 0.613598077767529 0.944870746557135 0.769110922042746 0.856731930386741 0.228507691475097 0.602152164045256 0.263385418481194 0.297967931462918 0.423977127282415 0.890591325266287 0.610597936334088 0.932066697620321 0.963519559586421 0.566466761690099 0.645046113936696 0.899285970698111 0.0749537395033985 0.468505866825581 0.168045874566305 0.277146315351129 0.841724227243103 0.472962688063271 0.288834611962084 0.143047921219841 0.566466364765074 0.0830384497041814 0.363714623439591 0.820479926548433 0.188477442921139 0.905561857372522 0.446240487799514 0.121438823838253 0.768455136900302 0.108617520187981 0.823543824467342 0.441142530303914 0.922481135299895 0.339160356896464 0.641387912533246 0.740342119417619 0.371538416058756 0.756051516623702 0.188793097431771 0.980359561766963 0.84225508449832 0.0746075849235058 0.987134419616778 0.27341643325286 0.992694363265764 0.737326035059523 0.795796043700539 0.240369882276282 0.872346128283534 0.66329826194793 0.553189676778857 0.91852325988235 0.871580345812254 0.67574778907001 0.552325112991966 0.328121844299603 0.90748471086612 0.683615850354545 0.680952963575255 0.720411415584385 0.515023647455964 0.626457441272214 0.872630310235545 0.361117763824295 0.995206194026396 0.855629730676301 0.506519370677415 0.103626309016254 0.887211561235599 0.158177399439737 0.387259386326186 0.966340473466553 0.85429251032183 0.571656646514311 0.348228707700036 0.0759104712633416 0.411744317996781 0.968664231838193 0.66940004121745 0.606539725093171 0.962609924064018 0.712414138838649 0.184429226261564 0.356096623768099 0.408970465548336 0.87541877169162 0.931105844248086 0.124076028047129 0.0455445137945935 0.798879461709876 0.304558461434208 0.295297957658768 0.320563389374875 0.993919098940678 0.418594119993504 0.333089178195223 0.103659452025313 0.41229151026113 0.369083750338759 0.107748877892736 0.684271554821171 0.518951669593807 0.647191936490126 0.471330212655012 0.472065339698456 0.597740682847798 0.495732728214934 0.813910886079539 0.583451341851614 0.71184583832277 0.400359816781711 0.955531930516008 0.355106054726057 0.756631546481513 0.704455177343916 0.675555750657804 0.982535107135773 0.684484546817839 0.350416882291902 0.255554154820275 0.101045179571956 0.54129874325823 0.0920450676023029 0.13713967586169 0.401169653551187 0.856605362936389 0.415050629922189 0.875954980289098 0.283368698514532 0.0687968044821173 0.96554394129198 0.371602855522651 0.785547868527938 0.0993549096211791 0.225357052069157 0.663664810683113 0.0458953134575859 0.0173374550463632 0.709912774497643 0.778495386748109 0.529884531674907 0.76513033085037 0.882136756316759 0.247317921142094 0.268701355583034 0.287765118228272 0.343616548401769 0.0148479869309813 0.355824933890253 0.0527812711289153 0.0973428793833591 0.638698064356577 0.310149781752843 0.931431411972735 0.893816521575209 0.0150972122815438 0.71113132879138 0.483501641242765 0.727613896529656 0.581459290634375 0.18356416113209 0.908084806182887 0.648745411371347 0.846448228810914 0.883131742244586 0.091824604102876 0.176661061462946 0.167757327822037 0.157115536716301 0.426314560666215 0.143838157914579 0.160744020375423 0.0505064629251137 0.822668879316188 0.521424497284461 0.960050913162995 0.458170621469617 0.529717363081872 0.625863866866566 0.350648324848153 0.263210283727385 0.572800003800075 0.164173393810634 0.723683559917845 0.142606423266698 0.299535778395366 0.629204832743853 0.368745181360282 0.634287782693282 0.472562268623151 0.98275734688621 0.823505385667086 0.729348710826598 0.368633799864911 0.268026827373542 0.500513889521826 0.32119979042327 0.693939585115295 0.416710465727374 0.127884985355195 0.116441194559447 0.492461378423031 0.891601891999599 0.296445209051017 0.0414373270305805 0.891076945515815 0.21503294873517 0.378994246963412 0.0528822931577452 0.0244751433981583 0.355669270129874 0.873093154318631 0.698802143712528 0.636858156898525 0.649879798197653 0.539672233711462 0.631373017251026 0.0823707805527374 0.701867948346771 0.978303674079943 0.661107777261641 0.811087640668266 0.659369126483798 0.548275000450667 0.426487660084385 0.493576852993574 0.0209738732874393 0.757486489561852 0.869147873548791 0.572439387734048 0.663536358645652 0.235690176573116 0.547920671105385 0.766132576218806 0.508781946352683 0.337731288736686 0.103414184169378 0.515913337380625 0.591599015609827 0.672171910193283 0.0691953688394278 0.162268328873906 0.196669164523482 0.696829756880179 0.82270162908826 0.537028766754083 0.43733720041113 0.997913959380239 0.913163232062943 0.478100773249753 0.436583814816549 0.460208571925759 0.6926394051034 0.65577636238886 0.627438682115171 0.0911647178628482 0.102420886210166 0.914700098789763 0.152110022874549 0.499048604604322 0.850973227107897 0.255489279245958 0.158056865388062 0.364892138866708 0.146869742171839 0.300395471437369 0.9318657422252 0.0723771387385204 0.462191245616414 0.355161494917702 0.229334568821359 0.0476567807397805 0.538691371583846 0.78185226973379 0.0440096745663323 0.372747179535218 0.742172942778561 0.201804426978342 0.552836735288147 0.57176259760512 0.0566526055964641 0.946036148394924 0.303284954922274 0.266668054589536 0.804864603108726 0.873062630968634 0.904060740175191 0.794149542455561 0.204348848003428 0.835120447766967 0.530541352233849 0.787211237472948 0.47035445085261 0.230766216763295 0.333800673447549 0.712378209978342 0.329256386714987 0.960565557575319 0.341691978818271 0.251905289452989 0.955130642773584 0.250571316184942 0.168089766821358 0.542194193897303 0.313522997903638 0.0653151466627605 0.596840613863897 0.0767156615667045 0.148031958928332 0.811547899206635 0.0484343776083551 0.493742232427467 0.338921965847258 0.995463188227732 0.0923905834602192 0.315214347757865 0.512103595212102 0.504526829412207 0.213156566126272 0.152563783782534 0.595180269340053 0.950753560131416 0.238436391791329 0.940121787809767 0.305383481853642 0.0590195128531195 0.667102758805267 0.508537973689381 0.342592069930397 0.384711302388459 0.0543755285581574 0.657203969855327 0.696132761377376 0.91631745117018 0.0460407316195779 0.268419456295669 0.915485131433234 0.704822148589883 0.162612865096889 0.45005452722311 0.84897890774766 0.96782370414352 0.438180360211991 0.688901929336134 0.863242773625534 0.421581475462299 0.37730088874232 0.8478003426129 0.338842954717111 0.0737469996069558 0.941144149117172 0.235445347593632 0.0108874554350041 0.437898603144567 0.838016481667291 0.126593982793856 0.581154593513347 0.0210104602319188 0.341119508745614 0.981591942512896 0.227434986613225 0.702443175688386 0.380294629356358 0.904644751960877 0.78332985148998 0.488839314254001 0.571402971316129 0.411010438201483 0.729377353047021 0.439730459616985 0.55901318786433 0.286000653032679 0.743713687937707 0.207488662558608 0.653449075717945 0.902929377309047 0.426019432849716 0.618272250492591 0.256524730320089 0.774606778896414 0.814078176838811 0.412635595160536 0.0329122128407471 0.582260522060096 0.813474671009462 0.163174892722163 0.0903063896251842 0.680561045522336 0.708273776334245 0.0489762920606881 0.496481644599699 0.767474488448352 0.872339013828896 0.329007501585875 0.763844647591468 0.794480987528805 0.915541434164625 0.487363381281029 0.437666718484834 0.979934784453362 0.336078978602309 0.747910558320582 0.376242697460111 0.432687300273683 0.375638211534824 0.565367153056432 0.145807534616906 0.650709292667452 0.339650619924068 0.661550467833877 0.241231861209963 0.979076427402906 0.534287529233843 0.238378422989044 0.175263239969499 0.642558793642092 0.738321759055834 0.85848459017463 0.0378886649478227 0.473869250298012 0.623517354456708 0.0838154189148918 0.467552705316339 0.596627564011142 0.177083620883059 0.472516405803617 0.121250279380474 0.793037252044305 0.568650972102769 0.431071643007454 0.86215502364561 0.78310605031671 0.5319260671339 0.220698677974287 0.248412218540907 0.0499710537097417 0.314170976162422 0.62764229220571 0.313963538580574 0.23882242327556 0.129860780856106 0.305750909724738 0.809549826115835 0.589975022918079 0.900553541774861 0.836524875687901 0.728447196593042 0.750329501249362 0.231240881006233 0.574238719635177 0.325883577631321 0.615660416292958 0.959492012071423 0.363610021939967 0.840736032836139 0.735225313976407 0.465076119746082 0.903851357153617 0.461645596334711 0.543190779280849 0.818069234450813 0.544678752312902 0.765570921085309 0.198404357766267 0.29473881638376 0.254317328836769 0.473869096091948 0.212067087378819 0.755867224242538 0.0869099339982495 0.958717195061035 0.365096131130122 0.840043101320043 0.796129372438882 0.207832518569194 0.164119161451235 0.555359913448337 0.751349000178743 0.433783703772351 0.205800708003808 0.294468411556445 0.156549594700336 0.819096830927301 0.494684239698108 0.913317428906448 0.399958840217441 0.297218489763327 0.0764293400919996 0.863356251078658 0.392733368508052 0.644984911417123 0.0968709025671706 0.883738396044355 0.0901848851586692 0.243513385329861 0.989925003999379 0.677641711293254 0.760805998668075 0.505546656115912 0.376900450401008 0.265694346793462 0.794316400331445 0.376018958061468 0.498660061336122 0.509021640431602 0.106490032712463 0.551730611736421 0.212672701843549 0.293116297523957 0.226649461847264 0.406259918492287 0.517862286043819 0.161984431592282 0.667696513694245 0.719860983609688 0.697458357729483 0.28219775171252 0.192336406097747 0.289801759200636 0.947034753900953 0.0100577369169332 0.589598143068142 0.577872238848358 0.291234972022939 0.0140299924532883 0.0738790974998847 0.810028830256779 0.700678713719826 0.671524734543636 0.98106565750204 0.483068691007793 0.178727821484208 0.703043255100492 0.640408342371229 0.266258947746828 0.736878272744361 0.506775620586704 0.0626766753825359 0.118509412738495 0.567651106901467 0.94630561346421 0.816010762602091 0.910376312898006 0.635431740898639 0.245348851929884 0.942899619650561 0.79821090673795 0.907315138364211 0.33021598338848 0.963634781481232 0.910997889880091 0.570980425726157 0.901460742962081 0.658295363155194 0.975281231084373 0.708769105111714 0.242047100032214 0.0383639997220598 0.229399670287967 0.56463563982863 0.403247964966577 0.726502556249034 0.368473481109831 0.353576045213267 0.649027641199064 0.819345879482571 0.65619494702667 0.771945796757937 0.162959324631374 0.92601022842573 0.353092419500463 0.221078016823158 0.584756633944344 0.629006668271031 0.472429431509227 0.546103734588251 0.694678084407933 0.0970396602433175 0.747854256280698 0.63460434215609 0.107461706786416 0.896528649877291 0.866001311959699 0.215401114213746 0.293819405257236 0.384002007280942 0.806467681401409 0.999566825025249 0.141681386039127 0.915251148280222 0.147969788298942 0.203835285799578 0.419885104806162 0.433199322260916 0.380145235029049 0.414360943187494 0.662348149523605 0.283094991280232 0.923984735929407 0.0783218537154607 0.187028006883338 0.318627661864739 0.255353715289384 0.623634702505078 0.550640297187492 0.526366484912578 0.290589424872305 0.588066016391385 0.811367508538533 0.25716926141642 0.158876719328109 0.0525705910706893 0.583078392988536 0.418764681119937 0.80595409176778 0.47756189935375 0.100757758831605 0.438016747809015 0.985371173778549 0.279093889759388 0.922819134476595 0.906758029197808 0.879715137947351 0.0511570530058816 0.526285519583616 0.296690016593784 0.641284194088075 0.512639047761913 0.294556126454845 0.436468496110756 0.832764018224552 0.571980565686245 0.517044449690729 0.32090952943312 0.830734283102211 0.0938217164599337 0.115175797119737 0.776584699398372 0.715767650036141 0.844401132713538 0.787360800297465 0.584542523319833 0.816326401438564 0.156979060892481 0.646224415376782 0.64275478102034 0.12674340316793 0.763320885198191 0.322626276956871 0.536612546148244 0.905335522517562 0.992354667822365 0.403051687616389 0.53265382363461 0.207093550434802 0.945414006682113 0.243325665839948 0.104755545959342 0.904573851055466 0.545283820717596 0.973995959502645 0.165090594419744 0.653258560465183 0.221816335401963 0.749874825708102 0.834905097270384 0.612055625738576 0.316359955668449 0.224251738272142 0.960099409932736 0.990428275195882 0.432238224556204 0.182090494919103 0.3936360161216 0.936435383062344 0.0388732849550433 0.216359567826148 0.368208251059987 0.0425941481883638 0.822165847842116 0.455016628485173 0.389228777089156 0.117993226957042 0.159344106381759 0.581806446746923 0.53578112214338 0.363785846817773 0.434173259176314 0.270056739060674 0.925206650255714 0.976987807000987 0.479877145965584 0.877003124665935 0.278927217207383 0.322381488315295 0.689013705682009 0.725539478990249 0.62742956044618 0.83172665075399 0.953325616542716 0.0586650101700798 0.698855623481795 0.860265103403945 0.469718161136843 0.171591012959834 0.895817998724524 0.0953406943613663 0.504496950546745 0.659037668732926 0.154969391920604 0.978779616458341 0.0574179468862712 0.938256517718546 0.377120718434453 0.405816891156137 0.229050426054746 0.80032688915031 0.0158552475692704 0.717030394624453 0.715702949874103 0.923464056274388 0.0890197343379259 0.89815242474433 0.784001957580913 0.240216495878994 0.311904630390927 0.401616049678996 0.646170319013763 0.465947315776721 0.242415682259016 0.721104247984476 0.612028681628872 0.0239235616778024 0.294127602786757 0.0230019985814579 0.399106855865102 0.624582675867714 0.621091264341958 0.869963432077784 0.795974704218097 0.386276615408715 0.111743183513172 0.4936900939513 0.784998742809985 0.721390211950056 0.195174083029851 0.823252724218182 0.190489080382977 0.139157021022402 0.944064067669678 0.167582275588065 0.38808329825988 0.988472872697748 0.721853474394884 0.698970421482809 0.995393147557043 0.14680237025721 0.103189382385463 0.689522120307665 0.837771505857818 0.26025664037792 0.961302043891046 0.988810385514516 0.701220376463607 0.43681076511275 0.0143058039434254 0.356275388933718 0.439727843184955 0.581257233899087 0.581774209381547 0.811194758100901 0.259679265676532 0.0154516919143498 0.910517098193523 0.556901799824554 0.32914575020317 0.813601736805867 0.569896021718159 0.291780081698671 0.131425018352456 0.055782360387966 0.0232437492022291 0.557144232040737 0.273537588047329 0.429682584982365 0.274703384274617 0.088953308404889 0.413352837988641 0.82228419534862 0.598483085697517 0.734054920380004 0.648866864896845 0.188353614299558 0.834526003214996 0.966747962182853 0.747139848170336 0.426022200260777 0.549899004898034 0.60479685543105 0.825647954680026 0.907201753573026 0.295647204888519 0.541701064803638 0.751149039862212 0.946337036234327 0.420309269444551 0.70604448312195 0.729329407408368 0.342845138907433 0.983561101160012 0.263386216710787 0.0784563704999164 0.817847216213122 0.13640609963797 0.776032820791006 0.541608565829229 0.887689351551235 0.401989632884506 0.96951321689412 0.73389210897265 0.577661601663567 0.330888208649121 0.40228015849134 0.0857012313744053 0.930112682746258 0.526185916296672 0.106001048281323 0.36314709879458 0.293438037757296 0.344843209693208 0.135044356139842 0.200458629401401 0.39965305397287 0.580837535934988 0.290954248989001 0.447145774664823 0.449565384897869 0.200763944729697 0.458516198410653 0.101358840698376 0.706140471901745 0.35686260746792 0.108747538488824 0.985456186267547 0.152341646144632 0.971501896323171 0.836229864275083 0.75066261354601 0.832734969628509 0.389154694329482 0.556320184571669 0.669134968600702 0.765595692018978 0.185480209274683 0.332065846472979 0.81786784294527 0.639743180854712 0.954185975736473 0.672465274436399 0.466576503254473 0.637621845025569 0.039006913844496 0.598179512044881 0.0731172792077996 0.0413708683662117 0.620026851801667 0.261108443785924 0.858164744901005 0.167466880355496 0.0341034044325352 0.693012534449808 0.0557730245823041 0.567270399790723 0.0407898224540986 0.824537915124092 0.528430974946823 0.909949833324645 0.357415160525125 0.789161977139302 0.327712288899347 0.0172718386375345 0.212765975305811 0.849474421849009 0.35963277003495 0.426802862810437 0.229387165536173 0.940376762349624 0.87999294674024 0.413942658433225 0.0289003233495168 0.778272423220333 0.549686039639637 0.065571397494059 0.340714413565584 0.639087188951671 0.217287976150401 0.177101554425899 0.404247693018988 0.106029320775997 0.510066537491512 0.434609412471764 0.640929714455269 0.808040547983255 0.90706714896718 0.780947115176823 0.574922038281802 0.0737030912167393 0.871773786600679 0.437428861970548 0.408913999390788 0.285423121128697 0.771634458403569 0.611065087122843 0.836393848478328 0.30674102306366 0.11488439537352 0.0638040929706767 0.0198392478912137 0.371259082723409 0.727199451944325 0.424797153177205 0.316501795973163 0.539033147310838 0.0874121133051813 0.398512726409826 0.989732734393328 0.0311596724530682 0.540032173714135 0.508978469187859 0.178085989339743 0.411399993605446 0.0295178628526628 0.312450858694501 0.984184291427955 0.776556624905206 0.524268710571341 0.506009480606299 0.913796244265977 0.886070421382319 0.871948535724077 0.180273945415393 0.353589386227541 0.136697967920918 0.980582419033162 0.654421793045476 0.833296681465581 0.0731919089495204 0.417912391352002 0.340962341187987 0.500811487170868 0.243536905788351 0.697543111364357 0.0960709151625633 0.427381400857121 0.386072662330698 0.0588741142838262 0.688926617288962 0.608562280759215 0.479851994242053 0.345332161854021 0.50517168505583 0.783905299883336 0.128665231848136 0.549050902205054 0.867226466457359 0.0491987143689767 0.515681049802806 0.178312365685124 0.584733132156543 0.738434978807345 0.943866604384966 0.837743641352281 0.330707728085108 0.81122570972424 0.423018853692338 0.267331339586526 0.70150133368792 0.423613766625058 0.173150843943004 0.267291157497093 0.314646318543237 0.0117960278806277 0.971514906797092 0.689420884142164 0.363333567809314 0.536702948703896 0.43481266920222 0.876126204570755 0.197998613261152 0.508857199833728 0.443036354563665 0.532492552213371 0.142612163927406 0.351385016771965 0.621475072861649 0.867490765969269 0.215075334196445 0.848997836599592 0.517493823217228 0.944855986800976 0.43677955993684 0.275277336016297 0.138553260718472 0.634217087395955 0.368868332765996 0.734334466008004 0.722654615002684 0.118537589113694 0.444032305143774 0.932317974672187 0.634320084829815 0.797098234384321 0.976721818598453 0.596133512447123 0.409890949893743 0.833679554606788 0.12463058463065 0.199813908601645 0.756203170795925 0.0755569542082958 0.773960262022447 0.244597724797204 0.619708096804097 0.0325839549233206 0.541020857016556 0.368568124908488 0.165499008372426 0.16915627716342 0.835810007264372 0.836870306720957 0.653165864180773 0.6690199449379 0.346254310887307 0.766993499912787 0.120794486824889 0.755435040427837 0.861281208647415 0.210214847584721 0.712359710782766 0.330590080614202 0.0412199594080448 0.774726203309838 0.951312713392545 0.173195182220079 0.612166729939636 0.539713584447745 0.439061069765594 0.264733769102022 0.769066916380543 0.750450715743937 0.375278067537583 0.617157530817203 0.217503744086716 0.540698392083868 0.47411661318969 0.946642539883032 0.700547870681621 0.978988640357275 0.58643850807799 0.415435814310331 0.642609695242718 0.253065155085642 0.0923825373151339 0.317235293134581 0.244136929188389 0.177381435204297 0.749783179131337 0.211625962378457 0.117645993626211 0.394723940361291 0.94959241221426 0.111258422806859 0.913893655706197 0.480631492524408 0.630207127670292 0.346773089359049 0.307747546324972 0.464414612152614 0.825481313245837 0.530562072319444 0.536056813311297 0.958632569585461 0.349429946197197 0.959450986343436 0.924014686942101 0.783337039013859 0.0964747437322512 0.203661810201593 0.516528505706228 0.464595855679363 0.0122440877743065 0.522742555288132 0.730125703548547 0.590512032511178 0.74768129816046 0.815665532106068 0.0513574950722978 0.427871510139667 0.485382745692041 0.193345364846755 0.462273615396116 0.521804940009024 0.516885371960234 0.807619702809025 0.681190877254121 0.703269769977778 0.68704221919179 0.367590919930954 0.304617556931917 0.26103397539584 0.874577639158815 0.488101232631598 0.111460225067567 0.259820784430485 0.801510242279619 0.189486607278232 0.661015035337769 0.772895791165065 0.979367324118502 0.243492268549744 0.128040391183458 0.127852896663826 0.704129262021743 0.35295566131128 0.0776134418928996 0.0990331467986107 0.0787594981305301 0.0596418440388516 0.641099005283322 0.138362095679622 0.461606584736146 0.626712924991734 0.66864871193422 0.367111439802684 0.858266156478785 0.346305380293634 0.902510472042486 0.161357543375343 0.808478026436642 0.13262288529193 0.813765224276576 0.861293900106102 0.385433502399828 0.170785760190338 0.716177441470791 0.16936446249485 0.839755994754378 0.936921984099317 0.918177151172422 0.463915123499464 0.961526457739528 0.139848747933283 0.109288731699344 0.56871474057436 0.738397076616529 0.792794669310097 0.523231589507777 0.951229366974439 0.509295500949956 0.464508837589528 0.95069643151015 0.277051257570274 0.325040232737083 0.593022525436245 0.346286296774633 0.947035363810137 0.294219503146596 0.294531118334271 0.611115777352825 0.86552342368057 0.513613725742325 0.180930727249943 0.410094174584374 0.116111479636747 0.864790115761571 0.793471114377026 0.556718777741771 0.34031921684742 0.698703590594232 0.254319662903435 0.28047427628655 0.975492593890522 0.963563215576578 0.441054240763187 0.614273311775178 0.721518449620344 0.642592958698515 0.255433099833317 0.785796314319596 0.695798577244859 0.653277154166717 0.909778797593899 0.904837352107279 0.143752276892774 0.637666314458475 0.554025375219062 0.293346269936301 0.545868120170198 0.0949899032269605 0.187692998289131 0.937335677016526 0.25986273700837 0.864731659216341 0.0526730138622224 0.607666671304032 0.862005633928347 0.317282922985032 0.199300636600237 0.097701626305934 0.94081228406867 0.534894200782292 0.313007426180411 0.299609591697808 0.553942715467419 0.789866886709351 0.274569118968211 0.271311511956155 0.0786951865954325 0.752003494969103 0.0999234563135542 0.629525255886838 0.873537905351259 0.326042712065391 0.338107271471526 0.449963300621603 0.652514883168042 0.294999250140972 0.958998183864169 0.161275563144591 0.856919373043347 0.871982147113886 0.560929685947485 0.919897333180998 0.558788245934993 0.941980720469728 0.162471233627293 0.630386835359968 0.983943725819699 0.205640790092293 0.649858892557677 0.28387940825196 0.0678289159480482 0.602119863522239 0.613604021731298 0.4075422200514 0.894461024780758 0.556352091166191 0.531068983839359 0.49238816972822 0.546347255927976 0.701987644522451 0.669357753950171 0.591809649337083 0.216840996621177 0.367576599281747 0.723391893324442 0.961591802616604 0.541997658384498 0.874556465444621 0.502805355899036 0.451483965339139 0.808133508653846 0.178852808380034 0.439771390608512 0.666788529721089 0.651533672059886 0.56140110909706 0.793026410597377 0.683511424497701 0.836810433969367 0.666394521011971 0.361195747375023 0.470164243089966 0.681404755071271 0.486475469912402 0.638879145609681 0.910233414357062 0.206387906023301 0.978048730427399 0.181776174094994 0.45312059578253 0.873893200501334 0.0818266802467406 0.895538387172855 0.481673486637883 0.0802071168879047 0.702777550215833 0.172645774136763 0.973732280503027 0.91670022404287 0.166701229962055 0.526461001704447 0.33573559765704 0.182480607908219 0.675041833249852 0.691019969673362 0.820607738711406 0.439745581722818 0.83342756438069 0.812259634642396 0.291302262800746 0.0857037892588414 0.216063359645195 0.912557497045491 0.14838861542521 0.830119651616551 0.921489642173983 0.0982791805686429 0.388173223675694 0.764232396779116 0.27925653635757 0.228272857768461 0.927198364248034 0.0423927306360565 0.737132051438093 0.952503743171692 0.323723222827539 0.0329140324261971 0.0422550446749665 0.860247899631504 0.945402011801489 0.0377490270929411 0.282917937824968 0.118533266042359 0.513447190569714 0.628989566841628 0.42330472914502 0.910409186910838 0.18354419501964 0.827100507109426 0.543744958993048 0.447975543893408 0.368908396377228 0.239486665087752 0.343652427704074 0.420668431501836 0.952702751052566 0.30307008064352 0.682000432810746 0.650401297518983 0.842000763202086 0.85456828170456 0.658252921451349 0.654789282691199 0.921162965963595 0.879498853916302 0.203622473133728 0.553195696577895 0.831104757061694 0.423738050488755 0.281049337896984 0.189857470786665 0.424363357690163 0.897190391430631 0.793742804485373 0.705938304755837 0.84795885077212 0.60504634678131 0.730847648393828 0.459351362085436 0.174723703609779 0.285862350016832 0.990096430201083 0.31984587432351 0.703112323281821 0.890927744579967 0.462330986044835 0.512726086827461 0.37346164688468 0.453206569696777 0.690439040856436 0.26634062717203 0.705706032621674 0.190293003800325 0.410060301113408 0.747242961085867 0.0947692313534208 0.0534811068815179 0.442277184743434 0.457377018518746 0.387585356738418 0.985318438070826 0.81777076872997 0.769036579045933 0.675202330874745 0.165109842747916 0.126754770390689 0.564694015467539 0.663064380676951 0.902413728828542 0.469853460937738 0.0787610563263297 0.935571990918834 0.92952023065649 0.16870548627805 0.888381197862327 0.621917369505391 0.213920245955233 0.986878704011906 0.307487683522049 0.637020170306787 0.959459712931421 0.749870683581103 0.0860042488249019 0.899051911018323 0.588777750674635 0.454610557819251 0.0816339208232239 0.318217879189178 0.626482548969798 0.909916175142862 0.248381504565477 0.842198076660279 0.687039740600157 0.262780065867119 0.12432146117324 0.545034767321777 0.138109700691421 0.118504497737158 0.922298728197347 0.891365455840714 0.618467935912777 0.496146657397039 0.395752436257899 0.199973579645157 0.829443312350195 0.787566021138337 0.19519799787784 0.950890578557737 0.423481235387735 0.826828994487878 0.917334309234284 0.971214716688264 0.192678861806635 0.31295956951566 0.159979891297407 0.199629514338449 0.635049650543369 0.782732072952203 0.0356573154241778 0.149348262809217 0.415275377768557 0.732902390945237 0.12148306369083 0.132310506680515 0.663173387767747 0.784772399426438 0.371832328897435 0.0958689764444716 0.881110204015858 0.305228419704363 0.154474868748803 0.195021372004412 0.618631298681721 0.753081143184099 0.47719366149744 0.749640413820744 0.0820689287525602 0.672550248431507 0.166110796381254 0.765093899033964 0.582960997917689 0.166419221877586 0.183537480947562 0.55960876256926 0.709507121962961 0.931456140263472 0.722125504263677 0.34496288835071 0.939958135529887 0.57800560727017 0.33061979443999 0.635789005460683 0.210409347300883 0.434340722351335 0.0911277298443019 0.332082530693151 0.930790648206603 0.190768130661454 0.777270863365848 0.119044112006668 0.770826292545535 0.313064204899129 0.461929749473929 0.409608921986073 0.0107171328784898 0.499813021118753 0.036252695354633 0.346968262142036 0.684366607300471 0.965080102360807 0.804671683486085 0.940261029661633 0.761982547598891 0.130938282702118 0.547989202677272 0.630001207715832 0.0219658479327336 0.967992262204643 0.82355549618369 0.490836234833114 0.536130471024662 0.32133556505898 0.160256238474976 0.505850028309505 0.78481265435461 0.816894693886861 0.221005792373326 0.714393561293837 0.641315983126406 0.29653463335475 0.0942299921112135 0.574371065779123 0.549780967186671 0.954212481661234 0.460238227895461 0.0848267564480193 0.0860030078003183 0.255119371861219 0.57653526236536 0.819533052681945 0.111468301177956 0.396570695121773 0.920700231830124 0.765811824148987 0.420086890931707 0.192622837522067 0.251453680745326 0.624703296588268 0.188439904693514 0.278883861331269 0.430821621271316 0.680728926367592 0.903784146129619 0.447622615541331 0.841620627506636 0.535560479313135 0.719768685402814 0.939009442769457 0.73450602843659 0.638284625452943 0.0460409001167864 0.988126046434045 0.378393050306477 0.709744858385529 0.3440637948527 0.635981060930062 0.398744681372773 0.866341628145892 0.744791769727599 0.77767469331855 0.919800221393816 0.119365228731185 0.085192769265268 0.88013910735026 0.0839177543460391 0.442277335491963 0.0585981455910951 0.405185773451813 0.981844398123212 0.106138684453908 0.539265651560854 0.0569998914818279 0.510313231465407 0.650381730867084 0.59364904738497 0.599642990515567 0.0831187613285147 0.286626112135127 0.0874792837607674 0.327296994912904 0.579089793683961 0.867032489751 0.329018676800188 0.739641356354114 0.637783444221132 0.740015071867965 0.844552447355818 0.858315940373577 0.217820006893016 0.770138842144515 0.823702441193163 0.274624571145978 0.592646867018193 0.122282008763868 0.105840927988756 0.846700317922514 0.696195699118543 0.219101337345783 0.517193341753446 0.0470843931869604 0.609093121879268 0.470897184740752 0.527249795224052 0.0719870458031073 0.283507912014611 0.389698561136611 0.336259625589009 0.44675588687649 0.990983846220188 0.320727260401472 0.26203792832559 0.225331750519108 0.130709311822429 0.078718163529411 0.959530531778 0.0333549066400155 0.390449611742515 0.490467413805891 0.106119279153645 0.621604886015411 0.410187125343364 0.796060844324529 0.302050011681858 0.342930611248594 0.737740016104653 0.208117655261885 0.392125287437811 0.0759027538145892 0.0614583603502251 0.773145121394191 0.390320674267132 0.86996971787652 0.0724114017584361 0.0338348832703196 0.0840169441117905 0.206610438511707 0.072711845189333 0.254658263691235 0.111838593962602 0.387176684162114 0.410707826204598 0.716117519852705 0.790082816919312 0.0563736258517019 0.891173732755706 0.152342118443921 0.443135546403937 0.30164214540273 0.160753457832616 0.41903330255067 0.998052419137675 0.321082228929736 0.798727393785957 0.120527403075248 0.900067899627611 0.556663230136037 0.561830909517594 0.266324067192618 0.346593698379584 0.940389762911946 0.588690903848037 0.6024887868925 0.126594576337375 0.892473364172038 0.462528481830377 0.0820295167714357 0.219547822908498 0.611999496344943 0.92527736422373 0.864187223990448 0.47368191159796 0.858081572973169 0.849399735634215 0.49315313852625 0.622168649092782 0.686425977877807 0.121338047755416 0.338778391703963 0.54850447566947 0.761402522120625 0.511671641438734 0.570425498955883 0.0159785100771114 0.0637985403998755 0.199160742657259 0.735305285609793 0.188431539533194 0.421340268135536 0.798484131991863 0.659070414125454 0.287627586703747 0.412173913500737 0.884282029352617 0.813896015682258 0.220643885033205 0.84271722877631 0.924702657817397 0.90514864735771 0.982056350323837 0.738170269231778 0.745109501525294 0.0357294838619418 0.714369333654176 0.815570095609873 0.608407252032775 0.984393279599026 0.570822505117394 0.849297539426479 0.517414667792618 0.264608734953217 0.893179867896251 0.913988764428068 0.0258374707587063 0.694588818920311 0.607022056765854 0.976398991777096 0.593890938381665 0.859096178568434 0.280032304881606 0.176821598273236 0.116929376842454 0.261549616730772 0.990125260280911 0.269686413544696 0.483877082297113 0.475829918622039 0.888280688701197 0.87729271950433 0.971279121576808 0.643624881934375 0.676731359139085 0.989088828188833 0.881957860686816 0.647539304434322 0.263709091015626 0.22162882105913 0.807269844978582 0.310466710480396 0.142035629868042 0.666221684135962 0.805424866238609 0.521610154008958 0.502301711980253 0.988622882005293 0.0323211868689395 0.235118563738652 0.526660696712788 0.517909951622132 0.333624443807639 0.449670615438372 0.539576935286168 0.51934075362049 0.467954332588706 0.71955546889687 0.450128552818205 0.728907682867721 0.86454624382779 0.582488393443637 0.412978540456388 0.978277512295172 0.940035918082576 0.0976016811840236 0.801530964439735 0.578045391512569 0.931726331876125 0.497357257055119 0.383572762832046 0.23043744321214 0.326306969625875 0.516918892993126 0.199048866964877 0.143039455329999 0.264593902819324 0.607836162438616 0.161078342348337 0.4960215902864 0.354710279447027 0.293961240490899 0.0949404802988283 0.915907996729948 0.415827618495096 0.949307553507388 0.306432698066346 0.254607139655855 0.982123750129249 0.214687118241563 0.24660788082052 0.734776293809991 0.792368539408781 0.258547882987186 0.971137966555543 0.376992512112483 0.140548752644099 0.070598291810602 0.800718092876486 0.504478678165469 0.438600975805894 0.95824882514542 0.151571462231223 0.864376495913602 0.412967660976574 0.764448023417499 0.938363639761228 0.66788521950366 0.84768879561685 0.309305222802795 0.409218442037236 0.177401258866303 0.677073203555774 0.0236636059824377 0.776593544925563 0.655040838881396 0.214662264557555 0.474323510243557 0.343979437681846 0.762820549679454 0.994337107092142 0.264234401693102 0.128925215664785 0.69748316692654 0.282836102810688 0.832778637374286 0.348713581582997 0.296829446074553 0.384819665455725 0.864900245859753 0.146931148685981 0.997682724506594 0.984127401837613 0.127750641677994 0.471587063483894 0.441277608131059 0.206099073225632 0.52721268042922 0.224142976896837 0.955126707637683 0.353348870868795 0.790222334912978 0.286683237298857 0.995958718233742 0.440936284419149 0.20474917086307 0.88778538182145 0.842659131814726 0.903100004359148 0.481834316877648 0.351992638912052 0.444199041775428 0.0453761016414501 0.795479560072999 0.108609779688995 0.498310365318321 0.269683703298215 0.432983439534437 0.904839383985382 0.664526158270892 0.980312859227415 0.78248902621679 0.622270635543391 0.0735150001570582 0.756237830971368 0.779157400524709 0.0839165525068529 0.0422364442888647 0.423474870526697 0.682099477360025 0.0352026387304068 0.0124696744186804 0.787355859018862 0.355844905534759 0.796086341571063 0.138604347412474 0.6588424131996 0.842847523910459 0.987505385468248 0.66673009991413 0.360692765919957 0.334092275269795 0.940863707757089 0.64329171178164 0.342590091528837 0.154749672252219 0.703577368431725 0.161362883192487 0.593254885852803 0.453784540246706 0.6184263786464 0.667473302837461 0.316888285235036 0.618470134905074 0.608154741562903 0.0830643991963007 0.728959827336948 0.501556627235841 0.0293507426651195 0.183762425181922 0.27653814968653 0.825601734812371 0.362573866911698 0.886806264135521 0.881353307685349 0.30254281092668 0.903944235765375 0.712430074156728 0.970659706245642 0.150379219548777 0.975538764430676 0.904855089262128 0.556832374364603 0.0696602607052773 0.806336356382817 0.842515732392203 0.353582357750274 0.493525887543801 0.600258590341546 0.585214672745205 0.814251847672276 0.596772334692068 0.130206056530587 0.972369466782548 0.818871174671222 0.368039505139459 0.339779277569614 0.883450898546726 0.592293935900088 0.614755543179344 0.577920598238707 0.314563900127541 0.326395599388052 0.823201008022297 0.463891074268613 0.709560716752894 0.172463572411798 0.610289524667896 0.0912278068135493 0.941749009839259 0.657426146678627 0.478206600560807 0.851034954942297 0.380127629260533 0.522428931272589 0.227367589112837 0.607036379489582 0.31153436319204 0.0245167188742198 0.423347617562395 0.404690536183771 0.152669032993726 0.792616191350389 0.219080190369859 0.132816777864937 0.959254187596962 0.781301288472023 0.503626527851447 0.760165276622865 0.774805448860861 0.806886510371696 0.382053391232621 0.340967984115705 0.521139689979609 0.620844559534453 0.0740846813819371 0.826170162796043 0.50577040289063 0.94160548548447 0.773633358306251 0.898848819788545 0.755014606239274 0.0926894557871856 0.0733197863446549 0.161331338947639 0.587710043333937 0.329965857234783 0.967469569342211 0.0691037169611081 0.611206379523501 0.657340203190688 0.951944295098074 0.507627527951263 0.555687611245085 0.0280927565670572 0.453845704733394 0.0851421705447137 0.529685324870516 0.0676210920442827 0.881297707525082 0.627588686812669 0.169160899196286 0.600719145997427 0.559609429873526 0.508882948788814 0.855257704053074 0.679569969836157 0.83778965953039 0.507469865044113 0.210880522660445 0.0892527712788433 0.933351708273403 0.710648303076159 0.47610565450741 0.766901404547971 0.222571600743104 0.350164896214847 0.654597979350947 0.173944641437847 0.721865842689294 0.395906702943612 0.731572186390404 0.0882089672610164 0.173234608492348 0.200244286430534 0.450238587027416 0.269975981414318 0.338563995487057 0.988966510510072 0.900780917347874 0.140223798977677 0.598400906312745 0.241806618787814 0.791611141229514 0.609787810284179 0.276145123378374 0.0772272292338312 0.4322627516184 0.628520455630496 0.291513123342302 0.0873220991459675 0.737610923962202 0.303528767386451 0.23030034503201 0.676951874271035 0.850993157261983 0.847191576950718 0.229797606756911 0.807011190238409 0.187707074144855 0.979873054313939 0.418476932605263 0.0506566594005562 0.506122250878252 0.661025930261239 0.899097629312891 0.459210438949522 0.877745952331461 0.670680513510015 0.977431949276943 0.0409014639561065 0.040106054788921 0.73968516217079 0.237870283352677 0.11281107525574 0.394455311323982 0.811869353847578 0.18827183668036 0.192841059616767 0.0108045548084192 0.882230673341546 0.987324237830471 0.225306127879303 0.457455381245818 0.279344171041157 0.670115062233526 0.426615407937206 0.633429346580524 0.511540114961099 0.385614866248798 0.654887312338687 0.0274323311820626 0.489532581150997 0.296170421452262 0.575758032456506 0.282034922556486 0.347778949926142 0.964268351730425 0.892744327506516 0.669905555662699 0.608453436633572 0.733895544379484 0.568614421116654 0.704687151669059 0.288693364048377 0.24678494672291 0.941507825101726 0.225883370733354 0.337617311323993 0.887109959954396 0.0997684054588899 0.365419506777544 0.013440506006591 0.456978052626364 0.358914450760931 0.125531216270756 0.655166446059011 0.0378656098735519 0.0798693263158202 0.667222692398354 0.0899192646378651 0.905395107371733 0.617596104617696 0.0393958860775456 0.158829503459856 0.014214187792968 0.399789380431175 0.577787277991883 0.464181823462714 0.885883452408016 0.923281509256922 0.957661015833728 0.265045766923577 0.0125587808596902 0.14552373575978 0.0545837777387351 0.759154043046292 0.12498826110037 0.233904836624861 0.179275268684141 0.400356951868162 0.641083332046401 0.574806544855237 0.0390798738272861 0.856324418159202 0.0804281872999854 0.644648794983514 0.236565163675696 0.586351335090585 0.558915321412496 0.994887203916442 0.823498421269469 0.825376167991199 0.832247957375366 0.916887840728741 0.0627561419853009 0.424741186057217 0.603026299211197 0.475078211314976 0.439184367770795 0.805430074208416 0.239258269080892 0.917619866593741 0.244753827664535 0.940727580913808 0.0219449925422668 0.932168384417892 0.210357910704333 0.085527208794374 0.711285690905061 0.848707289556041 0.517442747587338 0.824322295861784 0.591078484859318 0.0322628568694927 0.3681468795822 0.501761364943814 0.564047833052464 0.615204927078448 0.624106350163929 0.915078533838969 0.511041925880127 0.382627554114442 0.271238630113658 0.0189100205921568 0.169270657724701 0.789800135768019 0.539080897253007 0.694774976295885 0.598460867577232 0.418573688727338 0.24441873535281 0.972194631220773 0.743501250990666 0.310769073765259 0.307186268754303 0.0705850902502425 0.871038983643521 0.04016134446254 0.822889010200743 0.163748398672324 0.401734791113995 0.0474348701466806 0.203752174493857 0.87967906179605 0.794912653174251 0.0791563537740149 0.894901851972099 0.536197297570761 0.336455430639908 0.482362022935413 0.320192316800822 0.19962829843862 0.403814482546877 0.638400555681437 0.401699888680596 0.585128282313235 0.95533580990741 0.0165318138804287 0.741871211531106 0.973536514176521 0.543612745157443 0.160614970414899 0.490255561182275 0.215323232545052 0.124285029817838 0.449729546587914 0.488319556838833 0.670501148577314 0.742634260244667 0.0392993888095953 0.628421682382468 0.175826892866753 0.655438306278084 0.113841490314808 0.391297224618029 0.633751469447743 0.0406949659017846 0.58183686060831 0.886895522247069 0.313668970884755 0.726795364520513 0.630210417399649 0.67815253328532 0.52620234166272 0.0445342462533154 0.950968570637051 0.856997357055079 0.0224262477690354 0.361516198639292 0.31901614013128 0.8544410132966 0.608460230228957 0.550296339294873 0.206733928755857 0.271651815695222 0.206369048396591 0.967715267776512 0.242823329560924 0.389502442372032 0.607204039744101 0.709222517269664 0.525872064083815 0.703866553897969 0.464199984050356 0.889813288138248 0.440872371883597 0.457960882321931 0.202158676569816 0.636096597691067 0.842115377262235 0.677047033472918 0.7469762791018 0.761432991994079 0.99936786785489 0.191571600725874 0.104799056733027 0.734238996319473 0.836565015595406 0.990771402358077 0.128778030471876 0.883402915336192 0.386420734229032 0.941487048312556 0.841612910979893 0.698066620666068 0.306238439225126 0.732710642274469 0.526334176091477 0.69833837531507 0.257288214222062 0.272346756730694 0.521863000781741 0.568666036122013 0.0916370173823088 0.491181729715317 0.690473110484891 0.774863983546384 0.773773200847208 0.54788169200765 0.0203254287224263 0.0790483237826265 0.623212226526812 0.649729016476776 0.590699785654433 0.740810348496307 0.082590854964219 0.645288195558824 0.521199107489083 0.471267804838717 0.712047436819412 0.655256476122886 0.931567257603165 0.492374998824671 0.875867678681388 0.281062689283863 0.575476041659713 0.0890790900727734 0.582708808537573 0.31813498017611 0.201859372050967 0.643870831846725 0.423688982073218 0.670413894683588 0.218334335747641 0.264055012327153 0.433052234570496 0.172276949652005 0.0670798891526647 0.557712532556616 0.273591772462241 0.853821650058962 0.665916147986427 0.183970696029719 0.765740152213257 0.600899741582107 0.439287594323978 0.928713511892129 0.0266358570940793 0.593928717714734 0.501895290259272 0.964843102162704 0.25628331623273 0.847143326587975 0.581140945008956 0.0619342033821158 0.0298967377003282 0.688841930960771 0.965708165678661 0.120854100491852 0.923989405215252 0.89436588978162 0.347622933958191 0.886212462224066 0.699086516289972 0.361767968274653 0.204924773767125 0.446732957886998 0.491748089401517 0.936568673343863 0.468340006563812 0.757030309531838 0.209191978711169 0.914124857618008 0.22229416720802 0.394196321663912 0.638706218376756 0.205875843467657 0.994595038054977 0.307272691917606 0.400857453118078 0.914483997316565 0.152221221120562 0.322915658350103 0.251053448934108 0.898139345811214 0.829599283600692 0.630200347905047 0.743225472231861 0.446131607946008 0.881167277547065 0.34759630079614 0.568753314218484 0.371216435411479 0.529343063475099 0.115460317449179 0.924216220898088 0.345378549527377 0.622048536860384 0.260426030321978 0.230938219681848 0.0492289488995448 0.310909995979164 0.0443996849819087 0.43356288576033 0.430845967158675 0.371976921400055 0.170066116910893 0.515891635816079 0.162908287495375 0.552685578309465 0.489519852811936 0.0873230990651064 0.892118896064348 0.305420599183999 0.205714719106909 0.572597998927813 0.643675221570302 0.761417499701493 0.268972294023261 0.264664853282738 0.729989974782802 0.496223450403195 0.714029650888406 0.961979978464078 0.161583328251727 0.72502457272727 0.789207892974373 0.598628672126215 0.517803709867876 0.0887003307067789 0.0248989235586487 0.893061533758882 0.334004297368228 0.96128997386666 0.47836979160551 0.91455182839185 0.895340917895082 0.408387483647093 0.634553007902578 0.190595515067689 0.694345858853776 0.974071438645478 0.584244732970837 0.054951306108851 0.253633848377503 0.794325772325974 0.148933527099434 0.622008997180965 0.470906408291776 0.759786344149616 0.0449793195282109 0.271128398594446 0.406319600848947 0.144947068239562 0.91668581234524 0.642442049509846 0.130068860847969 0.311537669517566 0.26252286329167 0.0339179673767649 0.0452798413299024 0.717172762088012 0.567965187772643 0.336942936168052 0.369705647258088 0.991777611905709 0.706936542149633 0.0722069503343664 0.0169795024348423 0.625525790932588 0.697716905977577 0.691136932782829 0.31880377026042 0.522331970925443 0.482278664761689 0.0962728734733537 0.69180798340356 0.921825704670046 0.0424263809807599 0.916776819739025 0.80054931353312 0.40955006966833 0.285699196313508 0.97401696564164 0.831670849365182 0.271720655679237 0.375490787541494 0.0172778072650544 0.644302851313259 0.368360494165681 0.198081602631137 0.691363164372742 0.238895998469088 0.998331481863279 0.190553405978717 0.37394256696105 0.335062289035413 0.63949059846811 0.540887002004311 0.339454196204897 0.612330851983279 0.776094402256422 0.0399023084715009 0.443818023025524 0.644005939408671 0.240825067458209 0.769275629331823 0.628928376999684 0.690012924324255 0.730667124034371 0.541683148548473 0.367155622029677 0.944542862053495 0.853850999691058 0.99276461069705 0.549421176319011 0.270056899490301 0.46556751338765 0.808377957765479 0.156625623591244 0.0317214031913318 0.463454805491492 0.704124658659566 0.997498719331343 0.379581102456432 0.225337403819431 0.715263470429927 0.0397430599387735 0.411841559095774 0.420877859701868 0.0202068221312948 0.39343095916789 0.0120844012871385 0.095587598553393 0.387105933774728 0.588617890619207 0.101870249549393 0.0912785161752254 0.329865364208818 0.30022500643041 0.687149145998992 0.300996676853392 0.311317933714017 0.99714389578905 0.384003213730175 0.378260164326057 0.0341623888281174 0.280471654322464 0.579697679518722 0.554620097065344 0.459161076874007 0.229370984733105 0.530553238778375 0.997235014745966 0.747143316078 0.971208171804901 0.995235795367043 0.831354900042061 0.41924358061282 0.525112983237486 0.952080067198258 0.0579041125043295 0.52824532859493 0.183410685299896 0.170555690506008 0.54504574338207 0.0469380186707713 0.240182634624653 0.0738062539207749 0.355216547634918 0.508203758669551 0.824688864189666 0.37555058791535 0.558373206192628 0.67166889047483 0.333701389867347 0.756551605043933 0.86755072262371 0.248895344985649 0.871991083920002 0.741915158876218 0.303733910317533 0.0128649949165992 0.0906241709808819 0.712075722222216 0.607649354585446 0.357226478457451 0.94427174220793 0.919414200973697 0.611595302659553 0.0835575052397326 0.733459661693778 0.352567867867183 0.0469316192343831 0.247551362845115 0.728040366652422 0.652411182471551 0.511811393392272 0.958268705280498 0.288790083751082 0.881433883695863 0.161146928549279 0.525363158949185 0.577129453825764 0.639144420837984 0.864507235456258 0.438250516594853 0.129375256956555 0.100577712995 0.916980630827602 0.0436006368743256 0.123028447018005 0.738924735421315 0.237565427415539 0.0538493184605613 0.254020301911514 0.784753891702276 0.820978881127667 0.359103048925754 0.457458456838504 0.088318995477166 0.406546274311841 0.080238508079201 0.118169943878893 0.774473091920372 0.873809700568672 0.755370441456325 0.147136445592623 0.211555940839462 0.140192728876136 0.748655077873263 0.0943544813524932 0.30946974638151 0.810370703025255 0.57863373236265 0.486360521623865 0.893398687453009 0.0287904461123981 0.828114443095401 0.508023729890119 0.493375329871196 0.654302957796026 0.643063190151006 0.370906949373893 0.0543562244484201 0.919387851099018 0.603785943866242 0.604640151413623 0.26739381240448 0.99037820340367 0.0229946086765267 0.0271996752615087 0.145958041809499 0.256871601531748 0.473920817589387 0.751201816368848 0.79264490640955 0.278430060315877 0.74235971305985 0.54774951413041 0.946367316865362 0.479577650821302 0.184936804163735 0.494390519328881 0.206901198539417 0.923810565366875 0.602519359339494 0.251931360650342 0.805287762756925 0.367231541662477 0.292306619570591 0.812770893436391 0.231018262309954 0.717240511334967 0.902762997034006 0.197609598154668 0.923100962077733 0.0894408220006153 0.435494680900592 0.241570755427238 0.629466399420053 0.933688135885168 0.0289352684258483 0.938754217212554 0.990689766728319 0.570440188869834 0.474530721702613 0.237761933424044 0.139259110046551 0.612239076325204 0.940716663170606 0.465753850324545 0.135502598474268 0.510578578379936 0.818299081008881 0.0388254038570449 0.680454614986666 0.617485097688623 0.36948603177676 0.552083981039468 0.79149237559177 0.0743522482644766 0.919636856089346 0.735310739295091 0.565804407461546 0.984539240133017 0.997224051132798 0.279346572645009 0.890321757853963 0.87204493456753 0.142180708039086 0.937591128004715 0.984361002587248 0.590476122321561 0.353609050151426 0.287558835463133 0.924123230262194 0.762778549618088 0.279778144245502 0.668498184918426 0.694360679693054 0.296203564000316 0.521011363796424 0.0792322639562189 0.57538911254378 0.512979238785338 0.687003698332701 0.861338856590446 0.741404180603567 0.230810280742589 0.874159485560376 0.949165529953316 0.713030017341953 0.570555857247673 0.833336035129614 0.144869331556838 0.518093913693447 0.37353385243332 0.923618256575428 0.103592884333339 0.730058820759878 0.663747120532207 0.470813367636874 0.916065826981794 0.187282684766687 0.0248788691638038 0.687635598131455 0.555916370293125 0.885504762423225 0.963503279206343 0.245662631304003 0.147059430843219 0.96518675994128 0.736230045543052 0.440639738782775 0.110980624156073 0.351868877136149 0.259976835434791 0.321761111558881 0.540770625523292 0.880077274867799 0.968911747091915 0.671325219327118 0.0928919089864939 0.363437090558 0.321654019251 0.875363003495149 0.748614600049332 0.694657332743518 0.246722387005575 0.45541960488772 0.518647674352396 0.881934445798397 0.508973727063276 0.0177894786582328 0.26504388256697 0.129655563011765 0.873610253580846 0.111000785734504 0.227768929179292 0.335942676116247 0.706529324043076 0.138026940440759 0.291455721114762 0.536486580308992 0.791423303491902 0.206931929341517 0.749234157830942 0.198604174710345 0.0162744264421053 0.59127011067234 0.602931575658731 0.234993234546855 0.146386288874783 0.426116863882635 0.549643555984367 0.103896608734503 0.417198338906746 0.617190006291494 0.622702986472286 0.615130803289358 0.559453970799223 0.137302742665634 0.793262515524402 0.0265915208915249 0.792758314481471 0.492447982549202 0.524731192304753 0.812555287773721 0.84494009235641 0.701387562113814 0.355212791599333 0.755731501930859 0.0779526592744514 0.773050475060008 0.793119366888423 0.152041186348069 0.497697286726907 0.890349425280001 0.734731314736418 0.919488659452181 0.833640963674989 0.755167480460368 0.362798625130672 0.43130993056111 0.506899167073425 0.270644476916641 0.930110652712174 0.682353316214867 0.227723016110249 0.180819240645506 0.926418266659602 0.609479263313115 0.795149912687484 0.793927922756411 0.448877459431533 0.730646925575566 0.576525568359066 0.689548170068301 0.153897899270523 0.183976145335473 0.562020383591298 0.40619528148789 0.971934544830583 0.933478708837647 0.0296671569114551 0.657371073907707 0.816289497322869 0.997781755225733 0.482894948949106 0.136098326002248 0.41169555200031 0.114022412982304 0.0834576301905327 0.550958297981415 0.119459110489115 0.267099379552528 0.523710742322728 0.78769428900443 0.252122465528082 0.192746928224806 0.584603645163588 0.58897860487923 0.403451030610595 0.450815284282435 0.821133329449221 0.674865827197209 0.241482332886662 0.324992304386105 0.690327736579347 0.205067975649145 0.786728085442446 0.158860941673629 0.0181384843215346 0.240278504695743 0.603217976887245 0.879586560286116 0.454889409404714 0.456950338177849 0.193791976033244 0.184665700914338 0.899138280013576 0.420306038262788 0.0399479276500642 0.357039164421149 0.276129194283858 0.403731001284905 0.584774598374497 0.181381541416049 0.93433807940688 0.242265906219836 0.706611114339903 0.218421689909883 0.488690310167149 0.288466732767411 0.61361683489522 0.773881069717463 0.937006122292951 0.404446853031404 0.582676023037639 0.899627141125966 0.781456329876091 0.926292926634196 0.646415905884933 0.199237921293825 0.760030270020943 0.985124927440193 0.0750007638242096 0.68901088318089 0.771337112693582 0.0355714007490315 0.891445465276483 0.803156050404068 0.619339488991536 0.375984832651447 0.222129101487808 0.243212666218169 0.64811524518067 0.714442740811501 0.671302471742965 0.75447042433545 0.856939275537152 0.446519017373212 0.742736962405033 0.206406934221741 0.6971742080478 0.7129002150218 0.68654970507836 0.983290560336318 0.966447536500637 0.786692958730273 0.373039499602746 0.817095499685966 0.279095634892583 0.31467292727204 0.488707592771389 0.251093746044207 0.183166011909489 0.214178476340603 0.062647383606527 0.0420465663750656 0.561054408226628 0.128157869696151 0.491388725193683 0.742200148508418 0.7982210698165 0.961344070460182 0.895366727241781 0.185803405130282 0.827669176890049 0.186204417883419 0.320365176266059 0.147347617081832 0.397106686586048 0.727708279399667 0.25576814166503 0.470613005785272 0.649732355994638 0.801472762599587 0.146402155733667 0.170121088260785 0.7826544171758 0.347910875864327 0.633387401609216 0.741425613171887 0.78784305613488 0.720893795201555 0.321875976405572 0.68568623410305 0.551693634320982 0.398813661502209 0.0564792376430705 0.545410623049829 0.571096991910599 0.0731156336516142 0.186181293888949 0.762728914166801 0.92134497936815 0.769350025344174 0.0732172081945464 0.202875903262757 0.504490903548431 0.0953016541805118 0.551254509619903 0.971596146423835 0.455713794790208 0.66336036457913 0.890278823336121 0.58911407870939 0.958986133893486 0.600854973648675 0.69051258216612 0.231758038355038 0.431571107918862 0.097368769175373 0.75055311986478 0.157348206928 0.419607493092772 0.194930332570802 0.189200981690083 0.945333147845231 0.243443197829183 0.914962986013852 0.926672883459833 0.428304516386706 0.8081023394363 0.854467970544938 0.533532322209794 0.181779776616022 0.272242165834177 0.0211609411472455 0.639807146405801 0.402458346479107 0.595749133895151 0.122521760468371 0.245016178509686 0.790573052056134 0.935928234125022 0.0601840150402859 0.524873895840719 0.42204843654763 0.27174416461261 0.912305819611065 0.979387189501431 0.290854299718048 0.0962464355467819 0.755672083038371 0.472443199413829 0.273297875297721 0.358655604703818 0.11194216419477 0.581993699469604 0.0436712632514536 0.389473383403383 0.548389210670721 0.911457501628902 0.567247140952386 0.301336361924186 0.675796487759799 0.791927155554295 0.824383134418167 0.164874485339969 0.0891569191869348 0.812613650735002 0.271784455960151 0.806673980762716 0.677698291549459 0.167810427953955 0.707953157725278 0.293996917412151 0.461022791697178 0.89755029063439 0.359110863876995 0.059858898408711 0.0479794973810203 0.666662779632024 0.235228102367837 0.619919561722782 0.101013588765636 0.301586437828373 0.165258437693119 0.629733351783361 0.315085893184878 0.930155862518586 0.880421044440009 0.606159104190301 0.252901874836534 0.0396100252843462 0.96830388937844 0.461282196030952 0.721811362770386 0.0266070002759807 0.796693449229933 0.022933658096008 0.109721043673344 0.976457190851215 0.477109782849439 0.825465457681566 0.857212203212548 0.653786603747867 0.379434858174063 0.177574614603072 0.0299543243297376 0.399168999986723 0.777556938433554 0.787070070696063 0.170189333318267 0.544692316453438 0.681868857236113 0.157763706292026 0.153551281611435 0.0160188251663931 0.869143129810691 0.957511369797867 0.774813151326962 0.353683982542716 0.58166669341037 0.923004183135927 0.732266262811609 0.0165881041646935 0.330252872291021 0.894486758061685 0.683165924083441 0.156151379784569 0.728544001581613 0.921161156059243 0.607223156455439 0.213950724126771 0.127490958666895 0.59495145289693 0.384290224406868 0.234407700293232 0.706433549399953 0.335450752549805 0.503277281774208 0.557243115699384 0.143507308459375 0.134679995793849 0.328517888113856 0.191121139919851 0.414657162202057 0.380051032181364 0.42642662306549 0.551232140520588 0.224816205995157 0.39059649474686 0.520027654273435 0.864075566583779 0.574931857450865 0.88350326268468 0.80873231661506 0.704727261150256 0.721945966915227 0.451357639224734 0.466773783059325 0.588913743826561 0.619837728783023 0.771430246471427 0.839206717596389 0.47639615314547 0.190161979126278 0.686293397543486 0.0653842431958765 0.982715056161396 0.673894751737826 0.594301956088748 0.103384033080656 0.12167153530987 0.555187480873428 0.536486412733793 0.615936135121156 0.244129645545036 0.847097424813546 0.0965297139296308 0.467217500519473 0.832491872413084 0.73775735956151 0.587337158781011 0.138042369114701 0.952523525112774 0.118530708618928 0.541940122235101 0.54709945143899 0.773752933237702 0.974475184464827 0.711042877899017 0.645667385964189 0.84513201782247 0.135686650210992 0.874703388556372 0.228122484497726 0.149534898938146 0.65045207695337 0.147204153118655 0.0698702052305453 0.76255270227557 0.515198660735041 0.194929206566885 0.906336966198869 0.127433963506483 0.33783579250332 0.717364960699342 0.949823874593712 0.795211618163157 0.873949237233028 0.0348883833689615 0.119443553886376 0.598378704788629 0.274120889655314 0.302421951175202 0.3470778775285 0.249497161924373 0.39852055150317 0.938822572450154 0.464505065649282 0.0143425079830922 0.830070366759319 0.706474924108479 0.987671202165075 0.455626464600209 0.267760613078717 0.860995605417993 0.869993857925292 0.0150475194351748 0.843528971108608 0.941893874334637 0.582295075512957 0.725559817133471 0.652570099080913 0.219215125746559 0.54831402080832 0.524581113616005 0.594424836654216 0.378210663718637 0.969982694603968 0.949938459841069 0.156175208655186 0.674432832475286 0.191772712632082 0.102249396389816 0.695085941466969 0.540672091997694 0.823591378482524 0.782517869435251 0.623525333064608 0.743447710368782 0.305692328477744 0.358362136965152 0.0240049511310644 0.712164532006718 0.794657022855245 0.783863659405615 0.595299287608359 0.353448868545238 0.579956147552002 0.57112888951553 0.331162978499196 0.56124985069735 0.602349464134313 0.146418788090814 0.538211039518937 0.992348549368326 0.878668910658453 0.927746082057711 0.345718671861105 0.936352872906718 0.48527894634055 0.0591040682559833 0.203085939758457 0.215053387838416 0.828320263011847 0.876580039008986 0.960113965924829 0.857598871805239 0.191115314664785 0.086795467690099 0.984767834832892 0.169659380784724 0.35492082120385 0.360215477177408 0.772852981348988 0.219130277605727 0.0282993770181201 0.444758857269771 0.401489492370747 0.0425822473526932 0.028920788730029 0.320107652370352 0.192751119448803 0.258324191763531 0.222987960802857 0.244453486346174 0.159024999176618 0.631119771017693 0.950919883011375 0.471141419024207 0.71866771611385 0.257197825496551 0.0549759820755571 0.191872272123583 0.290968793686479 0.343413821596187 0.187956121547613 0.4016166319279 0.221252566331532 0.139515417120419 0.53883684322238 0.175064673500601 0.563114189559128 0.304758176726755 0.190916607128456 0.336098805491347 0.224214182526339 0.209725688202307 0.808741455802228 0.717537466573995 0.22451922609238 0.299267563570756 0.0595002655847929 0.488300099675544 0.461086789749097 0.66744063397171 0.683347980361432 0.184537676458713 0.637378898558672 0.69772484931862 0.474527763435617 0.494057620938402 0.735083147280384 0.75140675323084 0.254299754647072 0.849848379851319 0.989940144775901 0.645307888756506 0.320003605689853 0.26297775389161 0.191200006986037 0.845902670808136 0.284341232362203 0.49571185230976 0.88885264152661 0.815695624416694 0.197144070563372 0.787212301471736 0.398203082247637 0.551258699230384 0.567200540525373 0.948311475689989 0.381409373925999 0.603215616082307 0.991141070250887 0.324802202193532 0.619071437593084 0.79398044017842 0.969654382748995 0.560652298512869 0.86860907871509 0.385330465089064 0.192958355802111 0.216875019227155 0.618391692424193 0.131424086892512 0.162599025045056 0.408150896970183 0.956732131291646 0.173404953177087 0.644881273878273 0.285610224946868 0.258316679692361 0.773314991474617 0.895120058853645 0.525978299153503 0.738277766993269 0.36267644736683 0.940048230595421 0.108847281690687 0.472051350281108 0.77230032548774 0.64162296199007 0.402386273699813 0.52697926938301 0.994429464538116 0.213976769968867 0.311838953359984 0.770881314375438 0.217053167799022 0.953114402871579 0.261432601066772 0.574795740749687 0.355256878628861 0.171539280859288 0.835623551849276 0.510416191327386 0.44167597333435 0.662694423964713 0.875814651618712 0.721046149178874 0.533713902269956 0.278518340175506 0.565315760024823 0.338816697504371 0.932867827394512 0.12616951066535 0.958168697692454 0.0819709827774204 0.41258293597959 0.201126422793604 0.108253618080635 0.556259367913008 0.847155795381405 0.69567450129427 0.578308142048772 0.357065902922768 0.745457309267949 0.284306528391317 0.0384179409570061 0.453839905064087 0.385194719266146 0.508140513207763 0.200557109680958 0.372521630693227 0.392981120257173 0.259411331142765 0.555871049384587 0.739275083760731 0.494027641804423 0.903035934621003 0.0837889245152473 0.633652165583335 0.174239230339881 0.433003175375052 0.98071511346614 0.798999039176852 0.163491328866221 0.97872095960658 0.683156744327862 0.330327654855791 0.338381561185233 0.975144827868789 0.176071047857404 0.291918628355488 0.766809475836344 0.942752764767501 0.78170345419785 0.2285987302172 0.682600346952677 0.508990041788202 0.743027574219741 0.923239486145321 0.803423614290077 0.856423441271763 0.983324277296197 0.944251404064707 0.422015380207449 0.621093250350095 0.649785088244826 0.400611606240273 0.216196825338993 0.586984877448995 0.328187928397674 0.543330522705801 0.475460481001064 0.842498945598491 0.688931010433007 0.825916503272019 0.886197271198034 0.823349587293342 0.359431661586277 0.221766152738128 0.137174352402799 0.0512924496177584 0.169707009252161 0.72763068147935 0.703363283623476 0.400833810723852 0.688796227648854 0.0284041583095677 0.168162221773528 0.8880453361338 0.791900026812218 0.334440973903984 0.581128905871883 0.0308898196788505 0.0677918142918497 0.802265035782475 0.631709496956319 0.403258190741763 0.676880849585868 0.933785424928647 0.573749772545416 0.607611441100016 0.251940010711551 0.0546817384660244 0.758827148780692 0.913791603562422 0.871538464229088 0.428530873369891 0.436354719926603 0.607003306553233 0.512033250278328 0.232118439362384 0.681809749752283 0.583446783206891 0.877225956807379 0.508187659925316 0.39000791140832 0.314838160106447 0.0141711705247872 0.576848825067282 0.810782131487504 0.847089668640401 0.0721803217823617 0.857613980080932 0.773341494633351 0.173649299254175 0.324513443848118 0.456192049798556 0.958165054142009 0.916247074657585 0.441827955511399 0.384014387330972 0.668645531001966 0.890607288936153 0.708715652541723 0.525375066930428 0.735533293911722 0.956314171776176 0.334314840028528 0.349407566264272 0.163267905025277 0.248160715366248 0.267976497649215 0.273370105049107 0.620994148175232 0.870890522850677 0.905872775751632 0.217126298353542 0.772502077959944 0.848579105592798 0.428417324461043 0.53503168044379 0.968923381236382 0.574565074064303 0.152271757835988 0.926654253799934 0.777311713681556 0.219955584770069 0.0990500785782933 0.628338010495063 0.0534977316320874 0.254506440560799 0.0624321866245009 0.356809899881482 0.194750667063054 0.502863359046169 0.834255210913252 0.557856030634139 0.873863857092801 0.206901039953809 0.0149223091825843 0.396919388223905 0.468596736839972 0.492032022872008 0.856945130066015 0.970803677544463 0.201276387383696 0.743502379299607 0.307598699901719 0.895147799118422 0.534548965906724 0.175248311255127 0.661174813564867 0.166748253821861 0.793334080046043 0.933466327865608 0.337172988564707 0.381278631847817 0.867832289757207 0.215042834980413 0.36814766167663 0.460732855023816 0.871066297478974 0.269163652684074 0.29643856620416 0.291053343096282 0.284211935533676 0.599555058483966 0.547621579570696 0.478389756565448 0.641700487993658 0.839578675990924 0.127635773834772 0.286776594433468 0.710678400457837 0.99346257039113 0.170153240801301 0.893750733672641 0.995731531211641 0.399490696655121 0.368362758620642 0.703842172974255 0.636428356708493 0.984323716529179 0.883645756002516 0.155299077108502 0.434740672258195 0.98542937700171 0.888733050690498 0.865091984388419 0.0580508161778562 0.697911736695096 0.87011455793865 0.13108121558791 0.0811237417021766 0.421242512324825 0.380690875551663 0.913473221748136 0.912408435102552 0.412693712406326 0.208498284232337 0.798945194522385 0.687358863940463 0.0847435861336999 0.304764366636518 0.689800192103721 0.0724904721276835 0.747800506593194 0.0682826383621432 0.780105962359812 0.526535161451902 0.125890183784068 0.715265157015529 0.851588247681502 0.772346376397181 0.556842040941119 0.44431791667128 0.042908756909892 0.402142493044958 0.0538222892954946 0.858062875545584 0.190194348799996 0.466379443118349 0.480393486414105 0.0997146089794114 0.573978953873739 0.94263730822131 0.826009198173415 0.188710830686614 0.123989378530532 0.525414236653596 0.972155481551308 0.342151500440668 0.91849639713997 0.342437129716855 0.936239351658151 0.918011194791179 0.727778517149854 0.935801331293769 0.258434733769391 0.664019038146362 0.0409701674827374 0.859606122577097 0.354527837308124 0.861243159165606 0.353003521203063 0.139112808830105 0.456076738468837 0.402151861812454 0.104071131274104 0.148892300142907 0.582617396151181 0.112632213509642 0.972787091839127 0.832738952708896 0.639778812136501 0.444392311992124 0.155995911720674 0.227511483193375 0.947288927906193 0.814710188892204 0.524403636727948 0.280492136529647 0.809723401982337 0.985214379404206 0.848003035534639 0.214368908151519 0.245315271196887 0.546276251296513 0.0252954961452633 0.152562987166457 0.445334033439867 0.688311036364175 0.82528091751039 0.164475839845836 0.607790124206804 0.380735393159557 0.565221937275492 0.412331195387524 0.138419574203435 0.132196174985729 0.93058039250318 0.522874797245022 0.263844247905072 0.461629028979223 0.317385975739453 0.625486362355296 0.610168026885949 0.457339779944159 0.172357370303944 0.877503150620032 0.781303454732988 0.754204706081655 0.137247065287083 0.512261358618271 0.503635856281035 0.971973296883516 0.266687068957835 0.0109819888230413 0.0172295557498001 0.989723360554781 0.648673171016853 0.421448635351844 0.368949650533032 0.532783294261899 0.0468007782706991 0.905219948876184 0.668262445107102 0.778158752145246 0.789695381214842 0.842695264439099 0.0638266893452965 0.177698992050719 0.647113249215763 0.104420933322981 0.291756262739655 0.76740399484057 0.913805526364595 0.0540772458561696 0.715748913884163 0.370266162096523 0.413799663311802 0.820122685728129 0.0602284750225954 0.875640409139451 0.708469556951895 0.854743522258941 0.0222288672346622 0.939246744234115 0.0725732789398171 0.595114459770266 0.267732520145364 0.629631034792401 0.771213719490916 0.049233668204397 0.811358616219368 0.223940923849586 0.700494485418312 0.32022269239882 0.808764837959316 0.135917982817627 0.286856747011188 0.472056255370844 0.416547776486259 0.800414497326128 0.469974982230924 0.055047309640795 0.868366704124492 0.0328795587271452 0.96745077971369 0.608256601928733 0.999409638105426 0.957076014732011 0.286363691447768 0.916693504208233 0.472050090124831 0.904797618805896 0.483997988610063 0.502786202307325 0.793355465822387 0.160130089155864 0.115488059788477 0.448254356754478 0.490840440578759 0.273829663321376 0.499416591443587 0.154709310370963 0.0464418033813126 0.970225304537453 0.0646269153198227 0.189428062681109 0.774472075405065 0.236553164646029 0.11048322201008 0.272052218539175 0.551081773703918 0.799752123043872 0.150349931230303 0.940385502767749 0.12349856344983 0.2741424964834 0.77427445607027 0.187303426058497 0.414954985973891 0.125688125665765 0.127925888686441 0.870432897571009 0.502662864886224 0.186859692002181 0.389739629968535 0.494350230516866 0.0999478605180047 0.925894890127238 0.880059787807986 0.327030889876187 0.681333793313243 0.727023412238341 0.151840511474293 0.287695553775411 0.976622910506558 0.516119924178347 0.0370396201917902 0.433027482077014 0.643336532039102 0.625694730014075 0.199950945929158 0.537219761221204 0.795275486903265 0.761806661637966 0.539358518647496 0.238105639377609 0.679849430408794 0.280993829246145 0.122149098580703 0.040054225185886 0.50347345701186 0.402027441491373 0.759564398289658 0.176895189371426 0.429515888919123 0.593125160750933 0.374628668923397 0.494279540060088 0.804220759831369 0.984742157794535 0.803561295641121 0.624977478887886 0.554395266007632 0.179196738612372 0.589865192933939 0.438906879145652 0.972294932699297 0.371355012494605 0.44864196925424 0.639724326916039 0.248320628667716 0.528025187798776 0.688764474568889 0.956946287094615 0.742845708336681 0.193544897811953 0.649885309969541 0.662103842862416 0.451412904004101 0.534154302109964 0.223045976166613 0.557259949976578 0.54174502113834 0.961927703069523 0.928713873780798 0.65708123934688 0.0973339181439951 0.901986327245831 0.0958276434568688 0.267306651403196 0.0673418287816457 0.188975159702823 0.375553071117029 0.828735272327904 0.451228566905484 0.436764866565354 0.166426887463313 0.522522623096593 0.530144372580107 0.436781104994006 0.654181014683563 0.855344424103387 0.710882503592875 0.403697024779394 0.154639403622132 0.344678477048874 0.109261263427325 0.501076124138199 0.509055835222825 0.0354731233115308 0.931602808670141 0.0428543265489861 0.581593542341143 0.0107191868848167 0.638239344190806 0.704457913867664 0.811311741725076 0.242784624991473 0.158477311332244 0.935283244098537 0.878265484084841 0.230416709065903 0.977538592796773 0.503870170665905 0.580045546269976 0.195232283717487 0.666735616987571 0.902519726480823 0.0252731503266841 0.638929827080574 0.994215075927787 0.23146981223952 0.333066816010978 0.938528124846052 0.941513118357398 0.850584426138084 0.0924011024343781 0.900685946696904 0.530758475984912 0.717436667671427 0.567550680490676 0.825958139139693 0.751722947808448 0.866128830232192 0.670191115327179 0.861128777221311 0.519418484540656 0.0869717270648107 0.585730164484121 0.0434949865890667 0.548768781404942 0.364621232235804 0.238508193499874 0.133180697490461 0.575080550359562 0.549621693759691 0.0669460516585968 0.0530384294479154 0.157058904366568 0.499637466850691 0.27126497929683 0.192041059534531 0.583914261769969 0.977806992484257 0.147463521955069 0.899678936845157 0.253320984328166 0.580586237215903 0.360809452887625 0.547038051148411 0.534703031824902 0.357519928447437 0.415771918296814 0.252391265367623 0.574149376007263 0.0475202037254348 0.684619263217319 0.13104652706068 0.199246588873211 0.089474713220261 0.355563235597219 0.640170287163928 0.223483553966507 0.0879817375959829 0.423789244135842 0.346112084491178 0.447000546436757 0.651271987135988 0.912178289121948 0.966113870998379 0.554283245790284 0.219837174566928 0.317316978322342 0.707951240176335 0.444459031124134 0.0816061798669398 0.251430734929163 0.213874755166471 0.299083746946417 0.252580404060427 0.861537962204311 0.835318296912592 0.477273270781152 0.950807438900229 0.598142662558239 0.446635230658576 0.701404867768288 0.343233567385469 0.129490260104649 0.986406561003532 0.0741783310240135 0.103151500709355 0.204292617188767 0.0108534459676594 0.881275747567415 0.452549789936747 0.144926839123946 0.172148759926204 0.932877481984906 0.472278919476084 0.797634403104894 0.0876884028571658 0.849133043508045 0.115626013132278 0.556747812968679 0.507669866390061 0.096123201160226 0.705980056796689 0.141320974428672 0.385275669151451 0.33712823884096 0.439235252083745 0.877717964968178 0.368057913517114 0.551485798200592 0.769631943532731 0.155590076628141 0.159039009569678 0.195410428831819 0.825234701100271 0.920014334784355 0.676207608501427 0.948416369005572 0.127251891554333 0.50138179697562 0.0166455921391025 0.639939766617026 0.289846384453122 0.353994347485714 0.832059119718615 0.033020772987511 0.974323064447381 0.4443618944427 0.12737371180905 0.71822072713403 0.0631517146527767 0.886973566650413 0.779864175550174 0.0280112523236312 0.470926103563979 0.611179879822303 0.358321724834386 0.435967791096773 0.0214606672548689 0.0802711621928029 0.873917520802934 0.947981900221203 0.896938143041916 0.197607213607989 0.471763919629157 0.430754753004294 0.485345466779545 0.136738324961625 0.100999879869632 0.922538211366627 0.425876170806587 0.689222938185558 0.108239006537478 0.886629903109279 0.40273307368625 0.967347256965004 0.349173061253969 0.502312800064683 0.484555284483358 0.918904136412311 0.747539484363515 0.115614813484717 0.576188797759823 0.841516094696708 0.883327488056384 0.01620643355418 0.597236498170532 0.295507877750788 0.194572369356174 0.752039304890204 0.97039210755378 0.42587431503227 0.842535102886613 0.959833844271488 0.485645531264599 0.495451607794967 0.214219092696439 0.909653076778632 0.500164531189948 0.048193321491126 0.285175653358456 0.829896376910619 0.415059658007231 0.0931665220949799 0.242911159479991 0.917907358098309 0.0458252635668032 0.0348291776911356 0.505544776599854 0.185496017355472 0.124406983302906 0.619983206414618 0.518351722720545 0.404793514024932 0.35369099004427 0.271645275421906 0.264690246111713 0.0471291816351004 0.909158703663852 0.162306053808425 0.483109985040501 0.459478865836281 0.148666596633848 0.660042130381335 0.653975455926266 0.529779197638854 0.025355316803325 0.410998103560414 0.841687818707433 0.357958599519916 0.789500317689963 0.661743043086026 0.739821520899422 0.0986291822325438 0.908991211445537 0.708404272005428 0.453322260433342 0.74010610000696 0.116372984077316 0.91370227699168 0.903938997599762 0.821906437976286 0.425658971450757 0.533695359278936 0.380108301639557 0.739842064881232 0.586342026945204 0.0534214641712606 0.804281179334503 0.0868396443850361 0.174886095733382 0.206544558638707 0.0393276352575049 0.575135094819125 0.410912018774543 0.0552419209200889 0.282686685663648 0.989626050766092 0.802585449013859 0.831749329878949 0.079133156479802 0.846092255522963 0.620547063536942 0.187792638686951 0.392471471291501 0.678382249148563 0.614173799536657 0.88925893393578 0.958357031932101 0.200838058376685 0.534074997089338 0.822110055903904 0.555115929490421 0.408519229793455 0.541134235353675 0.158444160716608 0.572527547732461 0.390745558994822 0.560055855275132 0.903934887973592 0.260536773325875 0.779925361934584 0.365749032688327 0.84814798024483 0.250671141906641 0.0162006223597564 0.661719826890621 0.49332731485134 0.306054869238287 0.349321320818271 0.827247223460581 0.637065062711481 0.424409588621929 0.0541992502822541 0.682809006657917 0.582523661453743 0.949519323380664 0.732406863705255 0.0374670800915919 0.187616646003444 0.918746105392929 0.485884759728797 0.583327489488292 0.720283203960862 0.631356201644521 0.387251714516897 0.238892210393678 0.629886787508149 0.297559260500129 0.268080630537588 0.884678364060819 0.807932838390116 0.617356971811969 0.185002445927821 0.0157454793597572 0.873964207207318 0.291888983910903 0.600434736078605 0.916129390997812 0.469413775193971 0.638488959551323 0.729324673351366 0.382688226017635 0.0720026639499702 0.147554586052429 0.813881023579743 0.365299841950182 0.279776875330135 0.89211882022908 0.464023481956683 0.931830568721052 0.228622677105013 0.216348558343016 0.806451096066739 0.0731435640808195 0.263941531877499 0.914566429562401 0.115660534775816 0.563466275425162 0.677579762868117 0.832694193765055 0.307483668862842 0.503200214470271 0.474021606810857 0.478038293516729 0.609771689872723 0.626947178062983 0.914466979098506 0.0691763385664672 0.488178297630511 0.08899239952676 0.199308061311021 0.0539770840620622 0.845989758279175 0.333579397888388 0.440220362599939 0.619325264231302 0.595230197298806 0.454693732282612 0.366363734707702 0.136690632645041 0.294945772676729 0.537835901575163 0.24018066982273 0.299612394606229 0.994927420581225 0.912061159359291 0.815347032044083 0.413471303051338 0.239728002417833 0.225570370457135 0.592862827193458 0.659194744320121 0.74669668114977 0.114456281308085 0.0229988895659335 0.650006030728109 0.0367955355043523 0.410961181465536 0.142756224430632 0.172796385516413 0.776617585397326 0.992581228108611 0.499537074093241 0.989685070889536 0.263831589869224 0.342041549903806 0.688970380693208 0.666640461243223 0.417349889352918 0.930188915631734 0.102841976177879 0.227605559034273 0.740992561515886 0.38410922659561 0.0446423135860823 0.297290684017353 0.0728636178397574 0.808884476509411 0.0863020679866895 0.414074444225989 0.242063456708565 0.292465023312252 0.430917599678505 0.709311988134868 0.175957796066068 0.64623758812435 0.317833498101681 0.500848090481013 0.800184341203421 0.0150378334964626 0.920326772634871 0.989178663939238 0.938590575535782 0.163039576094598 0.240220005968586 0.431037915905472 0.0365885923500173 0.511506278831512 0.293351442178246 0.677809930054937 0.691462029130198 0.0535332439746708 0.990745763122104 0.619272108087316 0.363612459271681 0.592101590689272 0.527506428228226 0.686790405760985 0.438490297803655 0.358086026743986 0.420957492035814 0.225500071393326 0.537904141100589 0.0633409930299968 0.0760477626044303 0.604462217900436 0.792048909424338 0.932551804771647 0.380157182887197 0.782610110708047 0.0491032926249318 0.619167248194572 0.145964129606728 0.64783830906963 0.377497124371585 0.939005257999525 0.608036765856668 0.563942648381926 0.512145579829812 0.940097761398647 0.884887094299775 0.529521140591241 0.88781502188649 0.791987548319157 0.427325305116829 0.955976957229432 0.388253760500811 0.963272876676638 0.928351792411413 0.289585304367356 0.350652697016485 0.965257793385536 0.64393443205161 0.811608130158856 0.885802871556953 0.0800006135320291 0.661280050559435 0.440878165329341 0.132167296039406 0.776153463870287 0.896777136467863 0.390595473391004 0.755106377748307 0.739314486060757 0.909362495851237 0.615012365886942 0.268388916119002 0.0944445404596627 0.879637636607513 0.10999086279422 0.574416205051821 0.250122498169076 0.826006294074468 0.558769854153506 0.0999216457176954 0.811017217594199 0.139506968057249 0.341970881575253 0.81481922064675 0.400868327296339 0.274091085011605 0.477032020811457 0.318465463824105 0.270816264546011 0.541971097830683 0.779559373089578 0.966908809018787 0.319706702083349 0.138091909829527 0.524041592930444 0.893428010116331 0.590961935732048 0.52818190633785 0.462916349957231 0.820244041059632 0.407912959780078 0.966376031218097 0.309384620024357 0.302984673073515 0.55340207753703 0.905141334901564 0.175021021889988 0.341691413857043 0.914241671592463 0.397572028161958 0.598363100241404 0.973100118392613 0.243507493229117 0.0192290939134546 0.804394617371727 0.370953186529223 0.717514795055613 0.860100704757497 0.725754120692145 0.968188396643382 0.474554755028803 0.433906503200997 0.122671960401349 0.41260099376319 0.939471368300729 0.863024382111616 0.96488301133737 0.781141144207213 0.370483837670181 0.198783625620417 0.788539184257388 0.035970819578506 0.187526573527139 0.0733615515241399 0.993557469355874 0.0410364548838697 0.278486255402677 0.566905919814017 0.919035649290308 0.747523796143942 0.765971120856702 0.258063866111916 0.786516006465536 0.122360452858265 0.881065822404344 0.244792586171534 0.508868648884818 0.669647816016804 0.0161102963308804 0.234929090586957 0.0471726504573599 0.225105279898271 0.963615989778191 0.0510794647666626 0.350772988349199 0.659148859833367 0.905988976128865 0.25109471576754 0.650051551251672 0.157669538711198 0.325910303224809 0.921880938331597 0.672816377901472 0.520602021380328 0.707596633536741 0.462846677398775 0.290770504050888 0.825755055746995 0.906256651347503 0.207986799315549 0.441151770451106 0.102897968192119 0.446179552201647 0.181671234909445 0.0538690409320407 0.778282768395729 0.739120632442646 0.774105219640769 0.446468027259689 0.16219428345561 0.0306195508479141 0.337009218037128 0.101562466002069 0.647631837292574 0.48475086110644 0.874806937121321 0.901182725795079 0.88828564081341 0.392371425440069 0.225069857682101 0.583005395433866 0.807846488757059 0.930113095345441 0.133994354836177 0.642948864218779 0.298685935179237 0.242523513326887 0.605951468837447 0.910497230736073 0.705744744567201 0.85576619658852 0.831464797332883 0.750166708512697 0.784370869426057 0.564853636031039 0.648067025935743 0.858589080802631 0.748129881294444 0.48180849761935 0.686592078784015 0.855814236963633 0.0231577865825966 0.0165900991624221 0.717897538193502 0.842433726345189 0.887984372875653 0.214907176748384 0.841412291196175 0.424352695113048 0.0694035931257531 0.666905592407566 0.0899194709374569 0.134994177164044 0.768743565166369 0.518039609647822 0.810835245910566 0.65492989188293 0.622355079613626 0.177428108470049 0.540862716969568 0.110936170397326 0.226962901230436 0.553730204529129 0.241216394272633 0.408428807645105 0.21105954668019 0.0328667061473243 0.299595116612036 0.758835251859855 0.460627871812321 0.132201443577651 0.290185769640375 0.389762422270142 0.223186085168272 0.0353985691745766 0.579452242935076 0.728554835421965 0.984457924671005 0.553408152887132 0.0630123310419731 0.554547035431024 0.590220586969517 0.714928400476929 0.279438374119345 0.999512155863922 0.985147841677535 0.131559838016983 0.719443541341461 0.922796872560866 0.816413530169521 0.924662634313572 0.0438321524998173 0.119106449289247 0.840788148723077 0.453025243419688 0.333438738216646 0.142630897774361 0.762542006967124 0.0684851335128769 0.0166837022430263 0.200667169245426 0.407644407961052 0.532936910470016 0.512112894828897 0.566982162150089 0.178609502790496 0.614688596311025 0.271987692406401 0.524228843578603 0.644941530185752 0.161133592145052 0.374710706549231 0.979144356672186 0.279458266932052 0.597202886319719 0.54535186869558 0.674412013273686 0.422156268768013 0.379741258707363 0.19525894661434 0.630513264278416 0.224434482830111 0.747436458347365 0.146270708548836 0.416461062198505 0.142227206584066 0.629483665428124 0.66326624909183 0.744267680021003 0.552159461104311 0.46570935922442 0.590882275276817 0.191195886756759 0.661459354178514 0.10954940748401 0.490202646374237 0.270685909711756 0.767398446879815 0.330908504379913 0.537408017781563 0.797257500435226 0.0153675265214406 0.240978861153126 0.577474640756846 0.634357921557967 0.827171561759897 0.281325801708736 0.156566184414551 0.529196652770042 0.126433687550016 0.983450479861349 0.770337289443705 0.80317280262243 0.371772126988508 0.807274082072545 0.217915839161724 0.52597601971589 0.610106554217637 0.712586867148057 0.414546530530788 0.526080606002361 0.918235774370842 0.31622489213245 0.476808581757359 0.29478828241583 0.809451304806862 0.320468113538809 0.96240577851655 0.0501769423158839 0.931330878839362 0.864353094163816 0.110834570960142 0.208817433849908 0.580127636680845 0.12103273242712 0.970299226406496 0.460013835253194 0.669162984776776 0.13965164745925 0.659596609240398 0.47216722403653 0.804189960800577 0.10497356567299 0.739897463582456 0.40622462074738 0.303667722032405 0.743359860857017 0.217917055292055 0.980063107640017 0.961026322988328 0.78332815222675 0.433247269743588 0.379036885977257 0.0247945843706839 0.556688198379707 0.261161182490177 0.0166406344948336 0.52191515723709 0.287325301559176 0.535864452656824 0.0447392711672001 0.712023627771996 0.0135561278229579 0.208306861261372 0.772734282787424 0.747423150294926 0.66146301755216 0.504556712426711 0.591595557613764 0.865096445991658 0.903935103954282 0.716003941209056 0.703874792051502 0.159418224177789 0.840612170330714 0.442725072451867 0.678271048367023 0.0128068502410315 0.967495065897238 0.610634680020157 0.516776915770024 0.275336943920702 0.578341383251827 0.421954083873425 0.607513127934653 0.786195105491206 0.686565601211041 0.477124879830517 0.575473194033839 0.554609188772738 0.294678980743047 0.574506468153559 0.687941900701262 0.0769631196558475 0.331932997603435 0.617836597617716 0.47126144597074 0.931172759768087 0.739681810897309 0.640350680137053 0.360264585700352 0.173489060252905 0.11772151080193 0.330605035836343 0.980108952249866 0.912271965271793 0.501815569412429 0.143316239770502 0.917343215844594 0.409422545863781 0.208770548983011 0.612692827782594 0.0189020270016044 0.720245149638504 0.807495206652675 0.131072427916806 0.342090079635382 0.135603538444266 0.964008700989652 0.262379620149732 0.251655147625133 0.273619144845288 0.934617643936071 0.105227361884899 0.368342481330037 0.293683339958079 0.44384258858161 0.63352958513191 0.371333913232666 0.632680025664158 0.719408877247479 0.0727623560884967 0.502431854060851 0.924859473628458 0.497860855795443 0.507890072879381 0.207821957413107 0.537740755281411 0.889233151096851 0.404698379717302 0.265543123430107 0.0848862225934863 0.937462131520733 0.0317243709089234 0.174978345995769 0.188286379994825 0.443020667727105 0.32287642500829 0.131695493482985 0.237215560826007 0.286216930840164 0.595782796456479 0.508282675754745 0.324085952138994 0.0494450003537349 0.366496307665948 0.847996145128272 0.873227213325445 0.809039536584169 0.501460749327671 0.412935724186245 0.0871469551720656 0.370010414912831 0.372608935066964 0.603258924244437 0.324544000851456 0.2307846498047 0.942122315750457 0.499723217869177 0.499237586094532 0.998872323788237 0.796366463685408 0.585695290633012 0.0123496852745302 0.0172695204755291 0.622869986568112 0.930295674633235 0.792725609887857 0.958943939979654 0.969443699233234 0.803131128721871 0.29422429068014 0.588615106842481 0.445319965882227 0.465869390312582 0.222778959954157 0.0791387918009423 0.60929307528073 0.914709678005893 0.202778284600936 0.194666898595169 0.43246073238086 0.508531994228251 0.164597938316874 0.716442227112129 0.790419379835948 0.443738610590808 0.114823557047639 0.656271090016235 0.338096884344704 0.234080795655027 0.583270964322146 0.5801436091098 0.710532240769826 0.349775235240813 0.962399321224075 0.0606401697150432 0.340495469537564 0.843277707195375 0.568275152563583 0.64249299836345 0.271963891887572 0.442864675500896 0.380280204520095 0.912842331088614 0.482079809703864 0.794769602501765 0.851837555090897 0.785321595447604 0.684147582135629 0.290695487065241 0.293798714214936 0.102316507375799 0.44515566888731 0.734705479573458 0.631017836199608 0.699710757879075 0.688750324721914 0.797623120245989 0.70746354033472 0.571259490526281 0.0162327449349687 0.340566517733969 0.124222104523797 0.592616224267986 0.233101556494366 0.268374528393615 0.284182212718297 0.14466639614664 0.316332340335939 0.342416474632919 0.0451302105071954 0.42172664306825 0.941456468028482 0.0755337647511624 0.975842470391654 0.868340867348015 0.0251046326034702 0.754448722079396 0.819584085207898 0.616375140191522 0.388346451253165 0.961343524861149 0.894124851643573 0.183068986560684 0.609859786482994 0.326121381821577 0.553579193227924 0.694229955363553 0.51031003647251 0.220953462349717 0.0912626101309433 0.226795605400112 0.639989949511364 0.577850395985879 0.72855913590407 0.224965931323823 0.761979422448203 0.517007861132734 0.238096230502706 0.0396359203779139 0.0102145854593255 0.342447503013536 0.859340816922486 0.247325582117774 0.0171651999582537 0.189738433386665 0.642897020324599 0.895858913350385 0.891522704074159 0.483109517581761 0.150586280720308 0.803740936485119 0.526512692545075 0.408146932329983 0.398759497832507 0.678395661157556 0.813588931018021 0.4549412440788 0.5780437869858 0.117746915156022 0.997272862999234 0.210037405041512 0.754042322025634 0.449601740879007 0.785189042543061 0.816340104111005 0.634989373260178 0.420986028916668 0.46757540149847 0.961041356350761 0.73264082749607 0.613595766520593 0.545048036880326 0.023458996664267 0.923195304379333 0.166949114480522 0.339023379038554 0.807346943630837 0.854982372007798 0.331270826163236 0.202164147081785 0.388536563357338 0.470696534069721 0.908988864240237 0.6502327927039 0.525766860281583 0.395970777522307 0.429793017960619 0.0483557788468897 0.711381167969666 0.241560980745126 0.563237565704621 0.598942809239961 0.518195467030164 0.047650224561803 0.420922338354867 0.792639475774486 0.23298399684485 0.0117398572270758 0.285145815983415 0.810446450703312 0.817573709515855 0.21290293633705 0.155828282583971 0.545803041753825 0.123258344056085 0.107372202959377 0.865155877792276 0.974294881157111 0.538568816257175 0.915533151524141 0.863965099952184 0.278447509803809 0.288324312749319 0.408950923099183 0.673289932967164 0.256454947351012 0.692348069511354 0.292129588935059 0.697034438806586 0.265287192536052 0.527634489794727 0.282443663822487 0.0659443060192279 0.752213871225249 0.557657652946655 0.761770132780075 0.336528174642008 0.115192376461346 0.939331627411302 0.739274102512281 0.454828999121673 0.402523466616403 0.226905344105326 0.800329242809676 0.800221356190741 0.514848110936582 0.405264868023805 0.94308661974268 0.863609007264022 0.0985192021913826 0.129214346040972 0.591756837563589 0.79049898220459 0.875638667002786 0.0524449589988217 0.706228909655474 0.610859569625463 0.888865374245215 0.414378433013335 0.149905054573901 0.874232683421578 0.0236781186400913 0.559427515815478 0.891092453943566 0.897503388018813 0.406545986414421 0.0702786791138351 0.565683487779461 0.765060345039237 0.121914399487432 0.447969547144603 0.0620596293848939 0.0701132060959935 0.876180398897268 0.730456615700386 0.624446628086735 0.21799525159644 0.468127402041573 0.0986454478604719 0.246454157428816 0.440998582746834 0.612337893829681 0.95543634073576 0.82534910909133 0.158580114452634 0.698226246300619 0.280835960269906 0.415642539639957 0.947045289240777 0.376801830437034 0.242170028311666 0.43934628782561 0.103447424680926 0.518068394088186 0.71050684586633 0.181109382235445 0.708495969753712 0.855823296166491 0.727567011662759 0.91117007189896 0.278987788611557 0.0699609014461748 0.291524641774595 0.919153636982665 0.613450674288906 0.966690170636866 0.703334114935715 0.497447446396109 0.397821211561095 0.343723388309591 0.474659974274691 0.719493522315752 0.513175538263749 0.998730055440683 0.655995922549628 0.526788600615691 0.841848406689242 0.610460339807905 0.471609159207437 0.437823585006408 0.550029250474181 0.852291592371184 0.269468547576107 0.0896220498532057 0.426465912419371 0.0833092018985189 0.837558980628382 0.342099686050788 0.469106921262573 0.920359674307983 0.231191067837644 0.646308897018898 0.0956647020461969 0.83653680694988 0.288965752809308 0.694632901800796 0.27472101240186 0.562069236948155 0.545450925691985 0.338447882470209 0.146780683444813 0.763047405008692 0.281703783129342 0.0491277037444524 0.832381791642401 0.155365255712532 0.93205934713129 0.270137021641713 0.138031426246744 0.808041396462359 0.384239546163008 0.549265579404309 0.878578199229669 0.808192197545432 0.0322843076474965 0.974259252180345 0.914797804811969 0.889721288892906 0.584500850341283 0.48211485182168 0.139232389063109 0.861721737107728 0.475784543084446 0.764775788059924 0.453794882886577 0.589782671944704 0.927498440488707 0.645245004261378 0.54111305172788 0.939917469155043 0.424556851033121 0.716270528917667 0.0964345017122105 0.903199621015228 0.630123824586626 0.955000399732962 0.607863345348742 0.798999212745111 0.216588717575651 0.922792660591658 0.996246230253018 0.547084210163448 0.914161577331834 0.293834988137241 0.139514167336747 0.335725444720592 0.440230936664157 0.954170021978207 0.913843759326264 0.176028607306071 0.34662860542303 0.545345051358454 0.138107001739554 0.036776746797841 0.385843073474243 0.626786963033956 0.418490324330051 0.507921177786775 0.35195666026324 0.101905546602793 0.410807294878177 0.613595220230054 0.709835260941181 0.0111889027035795 0.36760867760051 0.0862733722897246 0.378908579617273 0.562453194602858 0.194390302475076 0.205096332738176 0.13961958527565 0.349099385791924 0.773782358013559 0.207892052021343 0.347349733368028 0.626000503120013 0.0468400729261339 0.34246845083544 0.295227920215111 0.555964863144327 0.697968423212878 0.615305199513677 0.834623658987694 0.501080916051287 0.23473209429998 0.851508475432638 0.0854376095393673 0.906125977267511 0.0926504017761908 0.0486766867362894 0.840235663894564 0.6101157717756 0.880923306266777 0.955279805446044 0.899443754618987 0.308175920858048 0.431179888518527 0.353877504698467 0.688286223248579 0.773604926764965 0.423113902944606 0.990305865316186 0.725598348365165 0.74226882253075 0.784220983437262 0.314156853053719 0.803243648207281 0.48784112872323 0.12844738685526 0.427191134546883 0.0820091417478397 0.329240679594222 0.361699447766878 0.142674601017497 0.524918879293837 0.052748832073994 0.14804914771812 0.200607452082913 0.0245719191129319 0.179739318755455 0.48488018582575 0.905509615631308 0.795355605597142 0.71181702184258 0.623982880895492 0.0605390236759558 0.0532767329062335 0.218998103647027 0.439954043426551 0.774118207986467 0.457954124454409 0.455974615560845 0.606183423800394 0.637904127638321 0.722912506780122 0.652045845487155 0.404024100450333 0.449901554577518 0.108911155040842 0.6075520588574 0.103069166427013 0.123070198136847 0.916348388502374 0.0844431014428847 0.968223900918383 0.357356217389461 0.989316836260259 0.627218683308456 0.818959980537184 0.807325955240522 0.683433229576331 0.354850629784632 0.187078551896848 0.712827983656898 0.296293638551142 0.108726896774024 0.89765102960635 0.168338522177655 0.0697670127917081 0.188508479369339 0.356549788136035 0.254824425911065 0.0774375773686916 0.413417451020796 0.220081362749916 0.82282066648826 0.49019659130834 0.255034716881346 0.731440407282207 0.680310875573195 0.276564252693206 0.73889659592649 0.225505218971521 0.637193732343148 0.244086838955991 0.414078852352686 0.287054060699884 0.297768799571786 0.809771809778176 0.343430917263031 0.539975043479353 0.0719791271258146 0.545063484224957 0.472853387543 0.937040704328101 0.159833195921965 0.75560540816281 0.273371825518552 0.599709716101643 0.0198959314124659 0.594436427003238 0.068268719248008 0.267487316599581 0.197487562149763 0.354411575617269 0.0901648171641864 0.93543912522262 0.0328795704827644 0.249668974447995 0.746489960891195 0.859584750400391 0.449894917954225 0.8208314732695 0.526844411455095 0.247212637586053 0.345290765478276 0.526369741449598 0.202316849117633 0.49933058203198 0.238133430122398 0.96585932334885 0.158527711820789 0.252996209992562 0.0909824527497403 0.434403097897302 0.494426040430553 0.177845889346208 0.859592735001352 0.927060904640239 0.381011410949286 0.980252860621549 0.517443660607096 0.540815899178851 0.142265148190781 0.55973946799757 0.435833573734853 0.322815796439536 0.563265418224037 0.583062860127538 0.0915769652999006 0.260091695901938 0.560215624051634 0.132218748079613 0.0696104509942234 0.519338650747668 0.339210175597109 0.726619394887239 0.699399098434951 0.987967770621181 0.78046175585594 0.73548400813248 0.598588232565671 0.458121181023307 0.693238120402675 0.392471047167201 0.105583535940386 0.381195396992844 0.108674767748453 0.641947048276197 0.0370196335646324 0.599134557910729 0.399998466565739 0.476208298350684 0.293585384762846 0.725046778861433 0.856896571982652 0.863108029565774 0.936573620846029 0.4948187797633 0.756469332766719 0.533425791405607 0.825821581718046 0.0408186154230498 0.959392692071851 0.482555879550055 0.993636054287199 0.42532268951647 0.24067599767819 0.938694075234234 0.403515918171033 0.442568613919429 0.921251384124625 0.877972222184762 0.731991409519687 0.370335842492059 0.73560658604838 0.603703538819682 0.899799721222371 0.17523020345252 0.393677167934366 0.931821521734819 0.997593117875513 0.848000679800753 0.227680498801637 0.112649306410458 0.879357235124335 0.813500302408356 0.795589162781835 0.668556947340258 0.478769186923746 0.782191923917271 0.147036577458493 0.637242995994166 0.632637217692099 0.32771964837797 0.897943692430854 0.196515717043076 0.485854022933636 0.0283790227212012 0.490768373792525 0.938328859263565 0.790434383694082 0.81826867452357 0.309658335787244 0.480433570770547 0.225962120704353 0.30561988090165 0.0993940207967535 0.528813010442536 0.315357250217348 0.930181312512141 0.640141597921029 0.0998514994769357 0.437091749536339 0.537006390739698 0.210454418805894 0.0996113354037516 0.625635448961984 0.146510328636505 0.859164974296 0.597729280127678 0.327880660945084 0.712242942678276 0.496660445954185 0.507196457001846 0.171868305427488 0.837960457382724 0.793114336635917 0.144739689205308 0.975845471532084 0.454236234931741 0.411950795305893 0.863124104107264 0.529349216273986 0.572246983514633 0.0104595880070701 0.303295377776958 0.998709443460684 0.99337239879882 0.870437742499635 0.868628094235901 0.0291048835706897 0.825138892342802 0.322643334821332 0.470576581114437 0.291120290195104 0.0207599823316559 0.882125579488929 0.0644502447289415 0.813382797157392 0.261865051342174 0.225247751779389 0.429712759351823 0.543078850572929 0.454046314605512 0.0375198383885436 0.0626220852835104 0.649266214345116 0.324215427837335 0.809283336370718 0.840544578977861 0.464631007746793 0.482955966375303 0.878342899908312 0.344808546521235 0.112668093503453 0.215562621208373 0.748221052575391 0.520315840051044 0.58182788991835 0.311112211069558 0.109677494405769 0.12899453394115 0.282987355217338 0.972074650144204 0.56174348712666 0.469291923129931 0.524763898281381 0.840663979188539 0.736473445408046 0.672064635788556 0.35902586060809 0.635335606441367 0.150846425888594 0.0753985004476272 0.920045845375862 0.317293633737136 0.75156583441887 0.213247611783445 0.740249708725605 0.662590238752309 0.652767667935696 0.349683123510331 0.75282336757984 0.960019022473134 0.534799325098284 0.970029061532114 0.917240662588738 0.69767995829694 0.997966720443219 0.164618790480308 0.935372967133299 0.450568824959919 0.785737236801069 0.489416865289677 0.367805082879495 0.93676832547877 0.993923747711815 0.668288378003053 0.675588582258206 0.712082915969659 0.414625764787197 0.942508651958779 0.888162175463513 0.373845581258647 0.205899414175656 0.67963892507134 0.425432953997515 0.199459540070966 0.536124076889828 0.323392332803924 0.332233522862662 0.864044385841116 0.890096119577065 0.126983204430435 0.582149024852551 0.278300610433798 0.231398604996502 0.256566204144619 0.316363139597233 0.841699130148627 0.993074349826202 0.944338635138702 0.467846786421724 0.349845960964449 0.16734223068459 0.99058555731317 0.0870666995598003 0.502673125236761 0.16782550787786 0.569038271349855 0.190324688421097 0.232413365258835 0.474666707247961 0.37564480505418 0.732939803549088 0.54570009018993 0.864135431498289 0.56378098072717 0.623692057940643 0.303383098437916 0.619895840496756 0.325530513282865 0.401780609216075 0.193427849186119 0.746087272155564 0.663098045312799 0.114531335174106 0.553848333288915 0.296894997942727 0.209165334485006 0.80280265344074 0.217928138305433 0.784251746048685 0.344725732794032 0.485916270320304 0.564037366632838 0.492510994512122 0.302551778389607 0.979818698174786 0.774811258672271 0.101547595835291 0.292910846411251 0.744946378248278 0.831609973928426 0.642382422473747 0.465361225090455 0.0490174565510824 0.558630600085016 0.930591269447468 0.0562680707639083 0.181322933200281 0.179315443628002 0.431935346329119 0.444048947873525 0.679755813959055 0.573942367851269 0.682596304402687 0.422159508708864 0.805508968012873 0.716372725355905 0.498040955569595 0.33147410732694 0.350523378059734 0.55334734798409 0.0107356217014603 0.2784914156585 0.161373551762663 0.998781924920622 0.274961904401425 0.290217420377303 0.372541601185221 0.194942800442223 0.169242873433977 0.836174356085248 0.883791849075351 0.255598739043344 0.808398079928011 0.954000427348074 0.342757463885937 0.251711429380812 0.477641225119587 0.0754501315881498 0.353531815963797 0.470927302176133 0.864013146089856 0.886780714334454 0.110515465138014 0.517982506381813 0.441161709942389 0.203284273650497 0.640300905923359 0.177870032391511 0.981974773241673 0.622662586788647 0.567675248333253 0.318948988115881 0.499282925443258 0.929953194952104 0.340136991380714 0.388680596200284 0.427456034286879 0.578897120468318 0.369567772515584 0.443053799672052 0.522994834333658 0.781113260108978 0.0854633661010303 0.373457667261828 0.237922203773633 0.288562008603476 0.617239481082652 0.311493602080736 0.617070834739134 0.702944228760898 0.245458984563593 0.104288533010986 0.497850375315174 0.949717510212213 0.591208534969483 0.067519349695649 0.929135015611537 0.328027685477864 0.903693579917308 0.99211183199659 0.887802704302594 0.901821658450644 0.463554239359219 0.957452395313885 0.883829106551129 0.617807109453715 0.51923010397004 0.341023083624896 0.345772980747279 0.182193034114316 0.654830028358847 0.061663060716819 0.38778724221047 0.50400762243662 0.952805176379625 0.687944985283539 0.671228897010442 0.462913251314312 0.80135323031107 0.437758541395888 0.50566444672877 0.695483520887792 0.35378418836277 0.213885748283938 0.596654811000917 0.810631510657258 0.644905936245341 0.579991001118906 0.942578954941127 0.741549307641108 0.927920614508912 0.181559313116595 0.625861704524141 0.567951499391347 0.871830279496498 0.723170492602512 0.423184397474397 0.544243153836578 0.441452384684235 0.045919573137071 0.896032971658278 0.919733876136597 0.388058811305091 0.772605771510862 0.426060073177796 0.533892115382478 0.189656616351567 0.627670835310128 0.246222998159938 0.794760081602726 0.123751694431994 0.203379815025255 0.0379677164158784 0.70340289683314 0.984535556936171 0.103070741910487 0.420796586882789 0.419124704333954 0.391142260662746 0.785642250475939 0.304595616105944 0.421058624936268 0.925505541022867 0.976230142822023 0.260752844142262 0.31424057980068 0.954941282337531 0.39667741332436 0.726887764378916 0.817332970339339 0.780312183119822 0.0221233349665999 0.219440502172802 0.179401074324269 0.359572478691116 0.0953211774979718 0.0119420499587432 0.584969630551059 0.813828516530339 0.738224585955031 0.521237802146934 0.843323380311485 0.899209674654994 0.29485500846291 0.166584966427181 0.0479753003944643 0.885364643279463 0.562683721603826 0.200350303214509 0.736707718071993 0.389104925878346 0.0708246849826537 0.360276722800918 0.916492562182248 0.73812568616122 0.377179607402068 0.0294166647200473 0.197396413458046 0.58812615099363 0.975805899351835 0.727293202315923 0.780701706714462 0.493094397771638 0.722762375075836 0.0109378854278475 0.106430542133749 0.946481523858383 0.989664484495297 0.0692115113791078 0.752275269441307 0.256462378515862 0.813492037286051 0.936186838385183 0.202782004217152 0.858053195138928 0.8810855130665 0.0873865524400026 0.482181535917334 0.933818415575661 0.614449977064505 0.881339759679977 0.368129849839024 0.873488750727847 0.6766389316204 0.869158429633826 0.102531258335803 0.40132043388905 0.263116566317622 0.597361135394312 0.199715889557265 0.352922655681614 0.187194265683647 0.0762490575294942 0.272444550343789 0.616804800927639 0.329579058869276 0.919044950290117 0.20339351216564 0.930897739131469 0.0989395250473171 0.942009256889578 0.533329026985448 0.613212301218882 0.750814429991879 0.165912977661937 0.715147157798056 0.55775540622184 0.969629968402442 0.343532545052003 0.179036022010259 0.334373814973515 0.885393074820749 0.130955999803264 0.68336464544991 0.465754723006394 0.953291061015334 0.0883830087422393 0.883741990036797 0.438374738683924 0.855507937851362 0.836854532754514 0.68482392785605 0.702260215610731 0.128684046140406 0.283250611936674 0.133895794111304 0.655037291680928 0.511364583051763 0.571327654216438 0.59260336039355 0.430313426775392 0.961364821894094 0.389175464895088 0.767108764220029 0.561011151927523 0.566115910625085 0.257381961136125 0.436368554215878 0.786408431485761 0.409210888475645 0.590441497182474 0.884578844446223 0.527522529277485 0.624230535142124 0.506515034006443 0.692681982803624 0.247434766925871 0.0963008285663091 0.390952652897686 0.432212452550884 0.853106339762453 0.377897661367897 0.575243525423575 0.913770577830728 0.783039885081816 0.342052083860617 0.564479076417629 0.0490049197594635 0.0200277775968425 0.0360575937968679 0.395034799731802 0.830592303113081 0.945048517335672 0.364050819857512 0.939502409589477 0.487293344298378 0.113444063256029 0.743710008198395 0.353755113258958 0.338524082393851 0.923003893624991 0.745078078294173 0.125675174891949 0.705197096369229 0.494323208727874 0.782327202742454 0.387330631371588 0.222003789583687 0.264937419299968 0.985262212096713 0.671423252201639 0.148316792740952 0.432055260790512 0.73413844935596 0.734133148954716 0.988918579393066 0.850260928785428 0.294479838248808 0.785975360698067 0.134115386772901 0.293468329913449 0.339598001772538 0.484117046063766 0.711314665509854 0.610469026518986 0.971479275515303 0.456262422853615 0.299783328454942 0.374892987336498 0.223681218710262 0.942896829189267 0.300507124925498 0.781976446413901 0.749772334226873 0.85555161458673 0.716321649034508 0.191104413748253 0.252807141372468 0.260278137947898 0.359914626909886 0.390893464277033 0.477199614220299 0.14176703217905 0.245055144238286 0.409220420208294 0.602632686044089 0.62587431922555 0.627763359178789 0.954246227664407 0.97810465836199 0.838735326256137 0.201972871862818 0.773969816344324 0.774047018492129 0.527933230735362 0.707840853759553 0.579619759817142 0.632172936887946 0.324741845617536 0.985586179443635 0.202783363258932 0.276279255454428 0.926465737232938 0.522094675453845 0.225107619266491 0.644463450820185 0.303825006454717 0.51360725070117 0.7562628349429 0.73404357344145 0.836762013034895 0.429273602149915 0.122408161771018 0.127455107485875 0.102054531096946 0.883102720617317 0.844259034015704 0.593068512496538 0.402072883413639 0.83024467931129 0.366656659843866 0.970617096966598 0.543570053589065 0.0558508092095144 0.941664711907506 0.533896124279127 0.104772031947505 0.560175883374177 0.545508932757657 0.136726269458886 0.401688391915523 0.849753480886575 0.357315177139826 0.218051234160084 0.999409799457062 0.450056137281936 0.093436280132737 0.537895103103947 0.2098223475134 0.810485556116328 0.258464503146242 0.172184048220515 0.894742545813788 0.692097324919887 0.987887501178775 0.0470941074774601 0.348525767817628 0.923331231146585 0.442739573814906 0.0899791021225974 0.660277906151023 0.370202004767489 0.791232138683554 0.511214341858868 0.3375822023605 0.662624976146035 0.50335504196817 0.32153112669941 0.560282067963853 0.640161088737659 0.811485582208261 0.945322247389704 0.178020212270785 0.327514915049542 0.757359940551687 0.487709154610056 0.233929231378715 0.0269296973245218 0.487975360837299 0.968381619607098 0.36501722211251 0.111238305715378 0.490318485323805 0.228236761102453 0.864010964154731 0.312645943425596 0.77064577832818 0.573132328009233 0.0961102582234889 0.866335329669528 0.638168834678363 0.884035376177635 0.121429383154027 0.333801119469572 0.606991463343147 0.558625659728423 0.82078349443851 0.724946913032327 0.312367583040614 0.866791998133995 0.740528940639924 0.0626942362030968 0.56417866341304 0.998271414798219 0.5981720580603 0.681708327571396 0.238647517641075 0.236594415805303 0.534593675523065 0.856773432563059 0.399654515357688 0.28222882181406 0.493538203744683 0.114827078201342 0.259713674604427 0.689622122363653 0.203054332816973 0.853781118758488 0.199600914069451 0.513425268875435 0.854570964751765 0.335701600175817 0.0125738626276143 0.631625253653619 0.304776627055835 0.415689891504589 0.427894218538422 0.499940948993899 0.828245105419774 0.851196466316469 0.323842498566955 0.852928033065982 0.15489902831614 0.622198724576738 0.179249282772653 0.125673712124117 0.994308894758578 0.143955435659736 0.142742890792433 0.50468014435377 0.962045816155151 0.521488598601427 0.026872775463853 0.414018197045662 0.0672647557151504 0.823078244091012 0.154552463903092 0.0966242348705418 0.0793804808775894 0.222075044771191 0.70222046271665 0.978999715072569 0.104271048256196 0.323474315800704 0.483930147162173 0.730496224991512 0.382420796053484 0.957956727282144 0.290540722955484 0.996862230000552 0.81796952766832 0.359675777161028 0.959158242151607 0.60788160413038 0.0194353748345748 0.667785349756014 0.0691948022646829 0.979035448236391 0.306012076479383 0.755198741417844 0.804114387151785 0.0257856312440708 0.187502717687748 0.910913949918468 0.063833704914432 0.630774120546412 0.137294147463981 0.711069103302434 0.247481088675559 0.962803318290971 0.759060275156517 0.39611278839875 0.52600400385214 0.810528568774462 0.312494676266797 0.884378392468207 0.951043183782604 0.441340640839189 0.383069936505053 0.733097844710574 0.70783648343524 0.598464532333892 0.115162713115569 0.915890543784481 0.0386896167742088 0.118638263775501 0.226788351030555 0.0756377289118245 0.679942846782505 0.940833059013821 0.623314962340519 0.431589908611495 0.666569405670743 0.769360694375355 0.397715376873966 0.841550369011238 0.737618512329645 0.906584560745396 0.611112341484986 0.24558339566458 0.947036772179417 0.126336500158068 0.425199747867882 0.165586602257099 0.666532144506928 0.0611494369688444 0.225926415661816 0.693445967817679 0.335158093874343 0.883829713002779 0.479046357225161 0.52074488626793 0.361116873163264 0.280296211617533 0.596866398777347 0.69891299067298 0.963057556145359 0.550109987375326 0.9752569430531 0.231872114653233 0.76460810175864 0.872715759756975 0.212024088550825 0.411521289467346 0.0658768075588159 0.367457028038334 0.67251246241387 0.211999511239119 0.640672991555184 0.543231934320647 0.287635578911286 0.112472061638255 0.596417748106178 0.697915577555541 0.726608445334714 0.178918147725053 0.679342820846941 0.0340215196297504 0.834350747908466 0.659525504109915 0.0233658566628583 0.374231379474513 0.289227212762926 0.255637285027187 0.165044561028481 0.262421904881485 0.989614444512408 0.468172798554879 0.951489333042409 0.60285174647579 0.482704934577923 0.200097006270662 0.198305843602866 0.248327208817936 0.741912845093757 0.397233160682954 0.37516311763553 0.428544411924668 0.465959263404366 0.16239636600716 0.560711540379562 0.935555352799129 0.48316701546777 0.486708835780155 0.67106793492334 0.290141532092821 0.626307580638677 0.315624267351814 0.614522206585389 0.277357074010652 0.876091264795978 0.380618655020371 0.545563542910386 0.522969637892675 0.682921201826539 0.177150160223246 0.783935372370761 0.482065496891737 0.555469153346494 0.222673807092942 0.436420456427149 0.0989238554984331 0.891502135889605 0.989698887660634 0.185408386820927 0.0722580586955883 0.474086088917684 0.539131234122906 0.86770349980332 0.357081195830833 0.946373307160102 0.751924424138852 0.834854316452984 0.285855233487673 0.278875513458624 0.624528948769439 0.627138734955806 0.0989362682797946 0.309213776532561 0.222274908968247 0.968990555380005 0.712512778625824 0.404417786456179 0.389409204868134 0.777698734251317 0.0752087997901253 0.913937709082384 0.444749554886948 0.521228361693211 0.14726518714102 0.927618546728045 0.456148329498246 0.697517661601305 0.882290614091326 0.247640164562035 0.315799367299769 0.050960222450085 0.312716119401157 0.143818480160553 0.576958148637786 0.439769500028342 0.798547954401001 0.132109309027437 0.427534429284278 0.292550953431055 0.36875339047052 0.241474945517257 0.556358063020743 0.0496736376965418 0.184710527395364 0.299134249086492 0.317041456112638 0.797516967696138 0.213115040208213 0.683308801648673 0.666174993813038 0.60727443146985 0.800259241785388 0.031769841182977 0.301230419822969 0.621195416823029 0.0489940430456772 0.126647414388135 0.938986142440699 0.42027315963991 0.161702203839086 0.600452332166024 0.198082942541223 0.295664108546916 0.381955374493264 0.242380810482427 0.0921402427088469 0.470204823487438 0.577134659029543 0.410565778217278 0.212328645065427 0.253070048880763 0.545808322101366 0.868196487138048 0.0512898845877498 0.0638319332734682 0.118723022250924 0.856972512591165 0.926421429843176 0.516912572849542 0.920355761761311 0.175286098655779 0.164953705996741 0.16224145068787 0.949594475210179 0.230045204760972 0.933224078437779 0.627791232443415 0.473975794471335 0.766282848990522 0.432464599288069 0.545694367047399 0.63395596005721 0.958447221042588 0.372914182166569 0.340186971894 0.841954814635683 0.822516792260576 0.126067860748153 0.328129925250541 0.333252501087263 0.891982893461827 0.408394106440246 0.60166450454155 0.895197949972935 0.315450151187833 0.492002768898383 0.607394004787784 0.77368358960608 0.282961878024507 0.277268763494212 0.439284000562038 0.728787247701548 0.714033898354974 0.905752299325541 0.0319198952079751 0.351892865514383 0.95711685721064 0.307196446585003 0.0264315854618326 0.750694776459131 0.330787885503378 0.927704405160621 0.391693579610437 0.956082685885485 0.362361324164085 0.680893201003782 0.941581048318185 0.512669000849128 0.298654411679599 0.290553048145957 0.0108121904288419 0.149559548627585 0.659887505494989 0.902010716928635 0.485997493811883 0.369466339962091 0.311420839407947 0.0730809172336012 0.709468312284444 0.202572064071428 0.339266294618137 0.264494269106071 0.268415102567524 0.999539976574015 0.624757380734663 0.394992710005026 0.330004331762902 0.362154004829936 0.796619966698345 0.757595500110183 0.302247984376736 0.765709944881964 0.936474952937569 0.832266771437135 0.603544510186184 0.175911039819475 0.0528189755487256 0.181278984472156 0.987391988229938 0.18653310730122 0.15992729319958 0.351755169641692 0.125716235195287 0.456594986785203 0.212376102039125 0.199911590651609 0.209083737118635 0.497890411957633 0.249240924001206 0.942648036491591 0.931963878825773 0.986861043383833 0.506315740763675 0.436806641425937 0.723023331151344 0.213107669434976 0.627910846099258 0.409676092211157 0.169285330120474 0.865612168463413 0.642966243634 0.611372406668961 0.271807110651862 0.363851359039545 0.636499134295154 0.385178115260787 0.376232501880731 0.436160124551971 0.723872586817015 0.454950138011482 0.910371628860012 0.284501765023451 0.784847374921665 0.496522749850992 0.166164447413757 0.301871590425726 0.480147365930025 0.468668366593774 0.0308436074177735 0.541437094218563 0.942462738889735 0.487463579264004 0.817311860013287 0.706369266216643 0.95175153106451 0.859250578484498 0.904994022701867 0.771075448975898 0.394857368252706 0.994105198229663 0.679469198132865 0.639998299689032 0.905274221573491 0.904933892940171 0.635041665942408 0.462081214173231 0.801032120962627 0.811887077172287 0.716360732088797 0.692138745037373 0.897008231887594 0.767463234402239 0.732505047328304 0.0420115039730445 0.55273421545513 0.408441938902251 0.366414732888807 0.333130057554226 0.960879198648036 0.828426846831571 0.804688321836293 0.244879680557642 0.449940565945581 0.920009571914561 0.280516787371598 0.429591788498219 0.663741872915998 0.886556168408133 0.943675491900649 0.668600827609189 0.672018911731429 0.42100639264565 0.615862401342019 0.588556492172647 0.576783341197297 0.131955524783116 0.467480604415759 0.626379853263497 0.730504216968548 0.67307725007413 0.17849890292855 0.52739786301041 0.461820915951394 0.421624574097805 0.793285118122585 0.201943109401036 0.989410986553412 0.34053762242198 0.982924767648801 0.731735051965807 0.642061809396837 0.824891729296651 0.235352533292025 0.972087077216711 0.482881550078746 0.999739728055429 0.0628533826232888 0.524947598963045 0.36068932521157 0.656067318804562 0.126011957477313 0.692037991313264 0.793870075198356 0.291751384618692 0.436349727706984 0.0869555116863921 0.595404262060765 0.914482248034328 0.285959285700228 0.235049647919368 0.212202397782821 0.0260806177626364 0.88316232345067 0.963195562274195 0.847387760716956 0.552612353709992 0.752237878504675 0.026144232028164 0.353323574389797 0.559091350284871 0.167118232201319 0.556119129138533 0.744073256140109 0.629024697933346 0.0754930144734681 0.0207061277655885 0.336980071708094 0.733171152982395 0.612471158064436 0.0949618709157221 0.513467837355565 0.666508527467959 0.0143686084542424 0.911289184212219 0.470154245742597 0.55318812480662 0.810808803373948 0.657476011479739 0.288826787790749 0.854097899042536 0.536726552143227 0.230416062506847 0.337598053545225 0.764085128605366 0.815496389030013 0.2649233588879 0.215283760402817 0.215474102778826 0.555966322685126 0.739314323556609 0.135748811389785 0.900578265225049 0.144157405495644 0.075887310388498 0.351914985210169 0.893789283344522 0.96265501746675 0.94727032152703 0.176386589421891 0.559745972543023 0.986963657031301 0.964643093671184 0.656189463376068 0.444347992155235 0.869175983769819 0.639931344292127 0.630221860457677 0.340396467631217 0.132366647829767 0.45532704459969 0.323868531961925 0.524766218978912 0.451205756855197 0.999504154666793 0.698567482652143 0.0619995779939927 0.350731319980696 0.62409323250642 0.224958109457511 0.121908923443407 0.270809562921058 0.795352623127401 0.604927692245692 0.35620096756611 0.138882141914219 0.482641945434734 0.74846501509659 0.778118490302004 0.792355740997009 0.659592073645908 0.775438933824189 0.0244594100001268 0.982995627524797 0.240913056423888 0.989122710188385 0.484403326278552 0.710110473125242 0.363981313721742 0.0501010989793576 0.704285074686632 0.571234380754177 0.654133947489318 0.418812795947306 0.618623161949217 0.788498817305081 0.360297621295322 0.0907025648257695 0.895123923225328 0.826504868785851 0.013441060364712 0.415323997165542 0.280740900184028 0.119700914125424 0.318048305534758 0.33713608721504 0.304584579654038 0.438814769489691 0.415267406075727 0.222421213642228 0.674693636880256 0.615770256649703 0.906969167264178 0.178720833805855 0.108046443732455 0.500414318044204 0.397074328898452 0.292880548262037 0.872071563580539 0.124694778148551 0.039879885665141 0.589878227610607 0.284915670694318 0.764258280117065 0.646875202998053 0.654238459093031 0.342138250013813 0.698700625412166 0.926315840180032 0.281758506458718 0.249418418868445 0.867666506713722 0.771816703232471 0.990440608453937 0.989574673639145 0.561136036249809 0.617451650185976 0.990767057389021 0.314250543725211 0.272456997700501 0.628628278169781 0.55040478534298 0.781397330497857 0.723231688207015 0.206246215775609 0.362234120066278 0.404965796312317 0.640718705470208 0.386557568022981 0.908527651652694 0.806508246816229 0.25658961718902 0.472813902262133 0.354410122530535 0.521043542153202 0.273226782153361 0.263499648985453 0.547533718533814 0.0869752823328599 0.212592979844194 0.553890065506566 0.780826746625826 0.784859181942884 0.258834239037242 0.561866704917047 0.656745395367034 0.765444235617761 0.836160230902024 0.438996088851709 0.842581773847342 0.329400847139768 0.246335973117966 0.784289038330316 0.677930755922571 0.283202562802471 0.135956325728912 0.802099481166806 0.807331584568601 0.309092765110545 0.226008224629331 0.611829711550381 0.0804719631513581 0.725130305532366 0.275875029037707 0.0806271672900766 0.189491535187699 0.526326004553121 0.114615944284014 0.127815779333469 0.45803817367414 0.286710819669534 0.724067474007607 0.587654256927781 0.573891611006111 0.250088971373625 0.459090691371821 0.389091819515452 0.113133883406408 0.824518692842685 0.929127433928661 0.153648686828092 0.875580295973923 0.935602082537953 0.903261726181954 0.762189722408075 0.407107770168222 0.23787464768393 0.760315457885154 0.161417826651596 0.604626372444909 0.435844640382566 0.929211174966767 0.0436942473310046 0.992755580767989 0.0746801901631989 0.376771554416046 0.384602920881007 0.839708695444278 0.811957213270944 0.792041327049956 0.756730353382882 0.468022502732929 0.0681421123817563 0.569118712055497 0.122245038955007 0.892434659833089 0.87313979577506 0.827656112017576 0.363368250112981 0.511747326189652 0.793662515911274 0.220622787615284 0.155067145426292 0.814278727010824 0.0138237813743763 0.944564946251921 0.386354312675539 0.373377576919738 0.0746932280668989 0.258947044115048 0.693999353910331 0.683409332707524 0.444285654642154 0.896222270089202 0.280440519910771 0.854022435804363 0.895608009481803 0.900538991775829 0.518945893666241 0.116362941320986 0.91638093451038 0.141753326510079 0.150661208962556 0.0308457953459583 0.407894087631721 0.312125346751418 0.881524353558198 0.600639245589264 0.0202581893466413 0.0541146856592968 0.239795188086573 0.209988591331057 0.664437809260562 0.126448066055309 0.67967635427136 0.921154026852455 0.966185316580813 0.575573615373578 0.118027317330707 0.572579814367928 0.788199928842951 0.714442991367541 0.31585582976928 0.668914461075328 0.284590106196702 0.48181746439077 0.519713110553566 0.135703673039097 0.716426790140104 0.358542827747297 0.151924638373312 0.963350354966242 0.0570447762799449 0.766078815006185 0.524936976032332 0.512620448758826 0.0855661862785928 0.219667562188115 0.0258052197936922 0.861389706097543 0.448806149384472 0.334211613475345 0.261143008072395 0.536125151491724 0.0758737206622027 0.528921542468015 0.229138511139899 0.435645428737625 0.7785633960017 0.756677176493686 0.812871725761797 0.0770366402203217 0.357731010271236 0.0847392964852042 0.270459129295778 0.775162160908803 0.154800903471187 0.923793954907451 0.743762495655101 0.852317510053981 0.915985318508465 0.923299578335136 0.99099314353196 0.152532887479756 0.305618027893361 0.698926997608505 0.168589469841681 0.500738206098322 0.38275536673842 0.967767547089607 0.294577192293946 0.55907124702353 0.816302521165926 0.0669171678717248 0.942348974000197 0.242218894807156 0.677490578978322 0.618585387456696 0.761913882335648 0.325145106229465 0.295307946247049 0.872033882210962 0.534517609521281 0.634257032298483 0.0574555344413966 0.402004887529183 0.351142833498307 0.855944106820971 0.49511265226407 0.987737855373416 0.946833547258284 0.363639766192064 0.919001129260287 0.697324794302694 0.316089861788787 0.0172246942250058 0.193729887693189 0.0948089973861352 0.868843647113536 0.60476194700459 0.61376292451052 0.804394748758059 0.823475739608984 0.18807881356217 0.675815115806181 0.715934657969046 0.0760011737025343 0.999245298467576 0.573373824616428 0.265595897401217 0.642334214753937 0.310195815605111 0.200922411859501 0.826511064458173 0.819512280963827 0.774840729318094 0.640916817849502 0.762034946081694 0.902807674149517 0.0434762225463055 0.139366992285941 0.912385496892966 0.904842831839342 0.19712262877496 0.569073739666492 0.819260934530757 0.226627632123418 0.764087698936928 0.69359341647476 0.731800408137497 0.983024118305184 0.167456980971619 0.176723236702383 0.910695992901456 0.601227457127534 0.932733436464332 0.296305508499499 0.918006456124131 0.185458897720091 0.97858428647276 0.762148361760192 0.11056240209844 0.676534978293348 0.514242393437307 0.713463856854942 0.362350992818829 0.190397709256504 0.891844960632734 0.299575670051854 0.535534835236613 0.0868321705772541 0.0198282294184901 0.793952103834599 0.11787869841326 0.916072029569186 0.126372452529613 0.540753638192546 0.654207228100859 0.876363175725564 0.807406083154492 0.919199750127736 0.0955837053689174 0.456591453645378 0.702613768624142 0.29224789863918 0.837339141098782 0.963239832092077 0.588568280292675 0.664636408460792 0.386783574642614 0.9264577844413 0.839479840276763 0.0525429231836461 0.419697974480223 0.0157737751351669 0.580168613081332 0.351379657592624 0.700301896566525 0.895029637396801 0.0978306894050911 0.446293561423663 0.416611103545874 0.989288445748389 0.763358955655713 0.937887576599605 0.889082230383065 0.245491410710383 0.498519331361167 0.461898449561559 0.176260880592745 0.896141946939751 0.335026358100586 0.585540337050334 0.669852350652218 0.402023197021335 0.0447411075793207 0.185385799205396 0.507242988969665 0.14263959716307 0.350199048132636 0.0927933023916557 0.934264876013622 0.0242337940819561 0.745610070081893 0.347550649808254 0.710808036355302 0.236089062020183 0.674766555603128 0.577006529925857 0.131752287645359 0.881003505636472 0.476219167227391 0.240643535573035 0.986977414332796 0.652723844139837 0.94121547668241 0.0455376243102364 0.184596064775251 0.174774938747287 0.811690430787858 0.476397943226621 0.605493596689776 0.649214296690188 0.559080017867964 0.209199374378659 0.898464027715381 0.857051232827362 0.352845623875037 0.823087923575658 0.406552092190832 0.433750744934659 0.134369633155875 0.236220819230657 0.792660433738492 0.113865339700133 0.538668691075873 0.461101400370244 0.377514746044762 0.324639301351272 0.103646330910269 0.661348372143693 0.258359504030086 0.853021190355066 0.924868467138149 0.13634025618434 0.061345815048553 0.85590272565838 0.675001789231319 0.360930490125902 0.03427437400911 0.237333748594392 0.359343955216464 0.951142381385434 0.12659354921896 0.228413882786408 0.488386246697046 0.332222706540488 0.100762677059975 0.795799297702033 0.847458471918944 0.188062141328119 0.131076795014087 0.953723189970478 0.27304538856959 0.536612326249015 0.675469892686233 0.661751372287981 0.698895769151859 0.60756081748521 0.227383290932048 0.851179760198575 0.0152380031091161 0.311839797459543 0.861049745806958 0.339474462200888 0.0409089273912832 0.516569034932181 0.828902574612293 0.261379001205787 0.713831281268503 0.153325831654947 0.683028078384232 0.234893789154012 0.543849412740674 0.903470129338093 0.321891861704644 0.853150347729679 0.341559017924592 0.586713139396161 0.931979450872168 0.966838336847723 0.721200521434657 0.151725455310661 0.490950713127386 0.973875271475408 0.843493990534916 0.411624134078156 0.595204103051219 0.301000950136222 0.157525090503041 0.960024016536772 0.616513838288374 0.518107872914988 0.978989352839999 0.175845292024314 0.462493052238133 0.059368382981047 0.817409252321813 0.221880481205881 0.014247695687227 0.424114707442932 0.878107707540039 0.606813510237262 0.209644365133718 0.0537641231832095 0.985820420759264 0.250563246067613 0.750641414246056 0.678232522667386 0.246470312646125 0.0585273410356604 0.573041432870086 0.652449064608663 0.373387492208276 0.718056197562255 0.305458843901288 0.413081273965072 0.958790633566678 0.603398665133864 0.936839189273305 0.163862894023769 0.371038825984579 0.216866417340934 0.369658061894588 0.778059510055464 0.676695784791373 0.31378035468515 0.537228873900603 0.195697432132438 0.0152239855704829 0.0536884469608776 0.0269749772036448 0.75698946520919 0.395041360980831 0.942994415580761 0.21706523805391 0.197645652869251 0.286733262990601 0.226791436765343 0.641571631885599 0.175553369342815 0.073122465510387 0.899696739923675 0.480730410066899 0.254251242203172 0.492474986128509 0.24297949005384 0.234339401528705 0.291311238331255 0.96788506801473 0.598552060755901 0.320767863157671 0.320092409942299 0.0394570245174691 0.450660956513602 0.406905519810971 0.941334022420924 0.0662025737459771 0.297219023837242 0.570629794790875 0.601741556171328 0.288543904488906 0.984511002905201 0.672039558056276 0.911356082675047 0.965599516557995 0.0208365701907314 0.647547499714419 0.89833630452631 0.698255726858042 0.09103110026801 0.110376501271967 0.26844131506281 0.830043719306123 0.964610815967899 0.916367028995883 0.276474018634763 0.112954260772094 0.395371523078065 0.842704705123324 0.339451823413838 0.366809151200578 0.277992921622936 0.168518527906854 0.213979184250347 0.336567362805363 0.806515351589769 0.894167262229603 0.159384051053785 0.292263144063763 0.0191438264888711 0.356105536140967 0.241102163768373 0.834634595632087 0.302543913649861 0.0688228775234893 0.532877227191348 0.299526989110745 0.174892810496967 0.0520530589250848 0.264205947793089 0.692847306686454 0.928064967289101 0.918232074808329 0.897903152832296 0.16319567803992 0.101562102960888 0.957847343781032 0.806821041945368 0.121850843308493 0.375849841723684 0.571401457376778 0.782272824014071 0.772897446863353 0.720033894015942 0.882007081003394 0.815907728748862 0.587534988794941 0.419873678805307 0.0198509002453648 0.796039230811875 0.990517615596764 0.50280256728176 0.960024428905454 0.367468543013092 0.930153516926803 0.186571919745766 0.0762879476533271 0.253255931497551 0.620476110538002 0.677003522468731 0.681406930782832 0.622921719129663 0.140914569534361 0.379382369564846 0.55387072497746 0.952007835833356 0.0701978871226311 0.260531632893253 0.556554700415581 0.433939801799133 0.985816327959765 0.944110836824402 0.743884210339747 0.683952332364861 0.396432041742373 0.330837154916953 0.483209457402118 0.133061320330016 0.241244226968847 0.100090879842173 0.388309863386676 0.861636137990281 0.79375191393774 0.812432135215495 0.630797540505882 0.0126690363511443 0.104155975957401 0.409066612683237 0.842683009551838 0.135755675288383 0.262595147441607 0.540254703897517 0.795339401974343 0.390682466125581 0.949609296510462 0.797887727939524 0.313719509905204 0.423021345883608 0.751294919028878 0.282361949591432 0.239652466340922 0.448568582381122 0.633916507277172 0.576992119380739 0.862554041401017 0.768987778243609 0.902654372807592 0.893217577848118 0.627939625468571 0.291863488969393 0.780534877881873 0.20876759209903 0.938077841065824 0.331802569008432 0.73757058513118 0.381173176337034 0.223419004552998 0.394865099992603 0.69626456791535 0.779722147155553 0.552182379951701 0.0565273165120743 0.899560300749727 0.844647896990646 0.341985536683351 0.404709873716347 0.169699203060009 0.108625973400194 0.365309940257575 0.69526328074513 0.709197436310351 0.166200998630375 0.214776672779117 0.991806394732557 0.203259016817901 0.816661921562627 0.949157725605182 0.9504807981872 0.233124660896137 0.188908475607168 0.543470641849563 0.569843635682482 0.334868268072605 0.934966841377318 0.926985256769694 0.0524312524078414 0.500333956861868 0.231335289462004 0.395723784356378 0.441920345919207 0.390871210659388 0.447055785169359 0.552653757000808 0.683992710611783 0.434634294738062 0.771336127065588 0.453534997494426 0.682051565835718 0.856411818421911 0.855709195204545 0.722000558397267 0.661881003114395 0.926852201600559 0.787319218828343 0.809370828834362 0.872237597641069 0.63914221032057 0.741765958862379 0.812123652093578 0.3994898661552 0.239933118380141 0.203526553274132 0.536821326175705 0.429462266468909 0.869843779467046 0.608069225195795 0.19662148419302 0.467923331637867 0.485872154477984 0.285287939114496 0.443699734988622 0.787565744535532 0.921718575251289 0.416746860893909 0.108732833361719 0.550179968576413 0.543863225132227 0.443879623853136 0.261857411111705 0.713825517096557 0.135845862093847 0.115672960234806 0.445904519348405 0.165826043705456 0.661712513742968 0.891176328212023 0.896932933689095 0.70809517044574 0.747544899093919 0.428910318480339 0.0750890927808359 0.540177714733873 0.982865727010649 0.694104013727047 0.877251530811191 0.950056677574758 0.537465766684618 0.991144938080106 0.54683456714265 0.672902782163583 0.0109612136473879 0.342226067255251 0.849396243062802 0.628989478328731 0.581333247115836 0.521805375658441 0.274344035279937 0.779026009812951 0.586561572353821 0.566877459229436 0.335334648753051 0.866828602596652 0.894664927839767 0.734359157187864 0.690791624607518 0.203807529399637 0.239376530610025 0.493794569827151 0.932508790038992 0.492172698678914 0.292580881624017 0.401138302467298 0.601990471957251 0.664101766818203 0.979634666722268 0.295771743918303 0.0362657519290224 0.177639299321454 0.695587970947381 0.586774226664565 0.0389492829586379 0.613719573935959 0.0612731750030071 0.813871472023893 0.0309543462726288 0.0638672289438546 0.600863380299415 0.50617930182023 0.55144929285394 0.195004858125467 0.347748629648704 0.878466475668829 0.940228780310135 0.262544853445143 0.117690053456463 0.304317501436453 0.845447537719738 0.402799845603295 0.401872005928308 0.985450235158205 0.0310886267921887 0.0146760633052327 0.455257715720218 0.121123595065437 0.352511435823981 0.613540063095279 0.250552934315056 0.703103947057389 0.689867831401061 0.536991254112218 0.965456332655158 0.689938430117909 0.866957969497889 0.480948357402813 0.776920966811013 0.173385319218505 0.218242659205571 0.879149983557872 0.490977000074927 0.831893103637267 0.568613603294361 0.832509003116284 0.873282680716366 0.442002786693629 0.361817565923557 0.310983405441511 0.980915251038969 0.701133099289145 0.110387603878044 0.560254697424825 0.0989088654704392 0.775705810582731 0.710917755237315 0.489198229904287 0.920474971346557 0.089983036336489 0.61866164869396 0.930080350644421 0.995063650459051 0.825820637580473 0.860687254604418 0.410732690261211 0.045026404010132 0.571549138380215 0.622140248669311 0.443506692508236 0.693839820476715 0.949970360212028 0.738691075202078 0.859488746637944 0.7478582506557 0.118568293638527 0.401539309227373 0.72233568597585 0.461085635393392 0.843457072128076 0.32955734946765 0.638987023239024 0.669057172448374 0.229774549377616 0.267725935846101 0.86165532592684 0.96590969087556 0.45615319494158 0.822471614724491 0.25213467085734 0.667021974190138 0.35568994595902 0.338900624096859 0.459697007024661 0.76459205579944 0.157984171174467 0.715436041536741 0.821761597222649 0.770606262851506 0.814903891761787 0.590550316183362 0.38895598448813 0.407971932189539 0.31567762772087 0.100231595064979 0.384264334384352 0.279308316633105 0.218670295439661 0.566132359271869 0.84385720689781 0.0664802831923589 0.651735997791402 0.120767849744298 0.553695177393965 0.363568560101558 0.828813446504064 0.510695823393762 0.146669218738098 0.635334295344073 0.740072211783845 0.45039533322677 0.321673753017094 0.094168160550762 0.868030973782297 0.828425813259091 0.568229940913152 0.614582661124878 0.79604192469269 0.475656199383084 0.525794618756045 0.229390691760927 0.377758796387352 0.14051533441525 0.855981426071376 0.200558478864841 0.467921094612684 0.308174916789867 0.960316838407889 0.231866305302829 0.795516365994699 0.515010961990338 0.551977388230152 0.262869608879555 0.932643871784676 0.721196432323195 0.650534452034626 0.0886875629518181 0.45614864344243 0.556596836242825 0.741916025565006 0.784757543781307 0.982587717680726 0.196204806270543 0.275423138425685 0.887304281031247 0.519497557906434 0.133348069847561 0.807861845053267 0.31831529178191 0.117850105981342 0.252639466826804 0.89035543424543 0.670547798562329 0.107390118292533 0.697411765600555 0.55222928579431 0.44381972782081 0.341712956144474 0.188002113909461 0.738732638231013 0.564879853136372 0.152486371647101 0.773539626144338 0.657238067835569 0.111021253650542 0.181580012917984 0.889740929536056 0.67259560022736 0.0815507811657153 0.684496816687752 0.666710910133552 0.490234026731923 0.0617809774144553 0.357636234164238 0.756691441591829 0.256028603543527 0.566511232506018 0.411840315996669 0.85032234221464 0.661106552141719 0.894792813532986 0.960874453526922 0.600662006773055 0.479704846621025 0.882409725252073 0.811923297157045 0.890252791785169 0.591277713330928 0.0249519296456128 0.470751882521436 0.45149751910707 0.663956401671749 0.49532315322198 0.840552856086288 0.802842640064191 0.613233120420482 0.72302575787995 0.320762997714337 0.148534123713616 0.753955096253194 0.626518409140408 0.856165554334875 0.286679191291332 0.782384059831966 0.65281171716284 0.592815431994386 0.967842492158525 0.134699919954874 0.415541432555765 0.567576038052794 0.463494201567955 0.240470357092563 0.472881527268328 0.286412878802512 0.338790004411712 0.727001338643022 0.200592557943892 0.113949099639431 0.0137743061222136 0.0116021807165816 0.532207851861604 0.67060357759241 0.0539184659346938 0.3356759763835 0.142397412506398 0.691771639639046 0.403054651876446 0.133440196791198 0.0355087105673738 0.356026989703532 0.939333606965374 0.373743337106425 0.298348353903275 0.925553179171402 0.116335094564129 0.198127992379013 0.186397773616482 0.932433636134956 0.641702092059422 0.574520537094213 0.503932509562001 0.476653835857287 0.666752259486821 0.779691385005135 0.218237658687867 0.638079617596231 0.104273402607068 0.379367314996198 0.909252148619853 0.0120547342533246 0.36838709551841 0.631002757658716 0.686929261751939 0.409569248615298 0.465039109599311 0.988490336246323 0.302610884490423 0.169870743821375 0.535644051393028 0.37332829736406 0.920362969338894 0.622455219971016 0.789172190697864 0.357990444339812 0.605281638957094 0.883999000603799 0.57324275937397 0.954499654150568 0.47903152232524 0.954772389817517 0.321928809385281 0.238321273853071 0.986573808197863 0.172549792272039 0.237337016656529 0.0752493502222933 0.138773963018321 0.118410243487451 0.178345050916541 0.600745773166418 0.842412841450423 0.267445849920623 0.554071125553455 0.280903127267957 0.638894890532829 0.381491216546856 0.722936983592808 0.0165740121738054 0.909760335739702 0.312488552280702 0.563790639466606 0.814796783549245 0.909526558425278 0.176170323831029 0.0762102425494231 0.129133025738411 0.5537335942965 0.0432177121005952 0.7019441074715 0.394235305832699 0.159165348361712 0.623836429622024 0.656948652327992 0.5062868369231 0.136701235291548 0.124540184841026 0.497098100511357 0.117771856200416 0.131268271692097 0.407743905447423 0.343248502553906 0.444423041180708 0.490606995648704 0.148886965627316 0.851136167135555 0.297204302113969 0.724189870518167 0.515503737032413 0.703370946673676 0.399653181440663 0.773329124494921 0.525328097238671 0.30854527042713 0.315074035222642 0.864070448279381 0.830681263876613 0.752390649691224 0.100752398730256 0.244531361330301 0.718677203129046 0.571483672028407 0.19265093137743 0.636258751014248 0.179725307670888 0.976430843742564 0.708778657820076 0.977211427460425 0.980869263056666 0.296851311065257 0.148903453920502 0.938109664449003 0.583554539131001 0.302877659597434 0.578700770740397 0.57540199163137 0.972298354045488 0.056032345474232 0.931938610007055 0.434928609803319 0.928495221107733 0.588488107661251 0.975462628356181 0.325112170903012 0.261138120500837 0.430374819228891 0.228227996712085 0.456578644169495 0.514221174544655 0.939393724279944 0.750609388712328 0.472311068559065 0.606420985732693 0.680155782536603 0.640309505274054 0.318333671346772 0.79817286901176 0.500639914830681 0.794125322191976 0.423591278125532 0.720467963570263 0.628415014871862 0.78340135585051 0.419188675647601 0.0439495752309449 0.907987612797879 0.767694349875674 0.434820319574792 0.561205081611406 0.0471881316858344 0.73978223039303 0.300202146591619 0.673590838094242 0.0608335445798002 0.895765580879524 0.799815070235636 0.617138627320528 0.950179383419454 0.882035463447683 0.152206781993154 0.364599050073884 0.950675686991308 0.220889062071219 0.578847705377266 0.987407251864206 0.179455365692265 0.338066228455864 0.796408555025701 0.92015848103445 0.339312327087391 0.18450611400418 0.664733718710486 0.0580992318107747 0.50417912009405 0.664142587629613 0.611908604893833 0.220958937010728 0.675389558933675 0.13326904350426 0.311200745864771 0.223028767553624 0.845300834737718 0.331401922293007 0.451204449445941 0.294836841421202 0.273230580370873 0.701692055931781 0.813963015335612 0.974195786588825 0.314441726973746 0.11955746721942 0.0625200822367333 0.22815819806885 0.886435581801925 0.998921612333506 0.558261452896986 0.964768284792081 0.111952838988509 0.803702902446967 0.577574884609785 0.986524746697396 0.690490695047192 0.314253744711168 0.593234526733868 0.628248040131293 0.266014507163782 0.893260445289779 0.719032759899274 0.649009238814469 0.661206869755406 0.142092643468641 0.480663824626245 0.891565140015446 0.437663090378046 0.989064305967186 0.643077254251111 0.769761469250079 0.417199820114765 0.507937064468861 0.777085790273268 0.218765574272256 0.226445601200685 0.278501605014317 0.52473024724517 0.946349525311962 0.723292373248842 0.361179236262105 0.359007156265434 0.608358666519634 0.837043127000798 0.0342166541493498 0.833876865298953 0.151480695020873 0.684058118877001 0.0275692149950191 0.091945174112916 0.422882284054067 0.160733328985516 0.664197510113008 0.125074502397329 0.499851728454232 0.21814216272207 0.360914402676281 0.24492675190093 0.808379946539644 0.132687478961889 0.45982500912156 0.391113606917206 0.489464778658003 0.033279959957581 0.559731273869984 0.713553360681981 0.0926864154613577 0.897117899137083 0.404109790155198 0.690426007101778 0.122589770643972 0.355957573463675 0.661465176206548 0.120228055452462 0.162534239366651 0.13084677096922 0.148831230853684 0.275401573318522 0.673754048270639 0.92034003527835 0.372685713320971 0.0301375531731173 0.0391717239376158 0.676716229426675 0.483335232154932 0.0162589124822989 0.564522020386066 0.334994262494147 0.721532203003298 0.320256425493862 0.975901812065858 0.838923843053635 0.458404733473435 0.329139744464774 0.602294578300789 0.983292186760809 0.873928107083775 0.16831360072596 0.60009256757563 0.941347334161401 0.481274592892733 0.0203260165033862 0.0941572651662864 0.339265574298333 0.580533649260178 0.485976810145658 0.799570477060042 0.839648716661613 0.319417175704148 0.389162756148726 0.0202918749582022 0.859416416848544 0.750920050772838 0.126075025452301 0.236637166382279 0.691637354048435 0.619611461234745 0.114124495782889 0.451517371120863 0.694493272705004 0.517904129594099 0.0658368626562879 0.0862054335698485 0.204966248744167 0.0744731301441789 0.826253660423681 0.457171744662337 0.713214732003398 0.744682570628356 0.175688191542868 0.446876472330187 0.0423694056435488 0.598942465791479 0.686565972550306 0.270580535107292 0.463559290356934 0.0247210479015484 0.549193671434186 0.542379494726192 0.881361966736149 0.237721548953559 0.265566890295595 0.569870446100831 0.356982810518239 0.50879893575795 0.999402158535086 0.355174287797417 0.894057200590614 0.216640939493664 0.816238686079159 0.962465401634108 0.387092516233679 0.56089190315688 0.533485952515621 0.378128558325116 0.832008198755793 0.874223220839631 0.54343817997491 0.624344103643671 0.101838998503517 0.502697331900708 0.356634717183188 0.847562260436825 0.285274637746625 0.826306925825775 0.61287743111141 0.0340336272260174 0.200311784890946 0.773036327979062 0.471406546961516 0.205334665239789 0.142121593640186 0.681882595636416 0.500431916897651 0.924417871257756 0.628868685653433 0.511105099655688 0.255423288962338 0.28015064339852 0.13297330001602 0.307595768372994 0.470242626101244 0.670319403938483 0.555407887899782 0.365976975066587 0.786305814380758 0.546664297140669 0.337958342297934 0.488785866524559 0.79230904329801 0.316642236898188 0.466307742369827 0.864331422564574 0.675405166707933 0.871166591581423 0.852119502553251 0.138452997503337 0.241943768139463 0.0426967355585657 0.631247108115349 0.677983320136554 0.136873716271948 0.547200747996103 0.572790928462055 0.161710817250423 0.678833796312101 0.462817207213957 0.326810807166621 0.0653989773662761 0.884682809759397 0.287675566687249 0.110710574071854 0.380018919056747 0.279616524304729 0.857912085987627 0.765121409948915 0.825387229337357 0.320820911887568 0.880010049322154 0.0554568853252567 0.846929351729341 0.446217223198619 0.86801205230644 0.639712397267576 0.710553653514944 0.15282808098942 0.246148275986779 0.105175997666083 0.937519546886906 0.825403619206045 0.718328489051201 0.385887228962965 0.260306580553297 0.0736517198523507 0.333766583765391 0.28797440005932 0.0715562802692875 0.270885567839723 0.533553874869831 0.196967597512994 0.249328124879394 0.0374197618803009 0.697227599765174 0.940962899597362 0.720295959268697 0.85731382708298 0.741583816146012 0.427087373228278 0.696064619815443 0.216430449599866 0.777589867536444 0.0365930348215625 0.640782878012396 0.519137635652442 0.379961626778822 0.88895572286332 0.508678794021252 0.242140752901323 0.355391791416332 0.887033382237423 0.624550359209534 0.914489985997789 0.100927947696764 0.527666528928094 0.429258579851594 0.0321240047970787 0.416493096491322 0.512825774708763 0.90533276686212 0.956051749244798 0.256352643268183 0.911689337652642 0.631929491152987 0.512995630959049 0.99659469746286 0.998917845233809 0.79423892688239 0.836941699287854 0.729666918150615 0.143823375338688 0.939625786656979 0.452020206898451 0.579100654954091 0.871996327387169 0.910516954590566 0.309719894432928 0.817618701267056 0.376886522297282 0.248188655476552 0.932581662430894 0.835888006719761 0.580394198803697 0.618400186204817 0.0907000233069993 0.349379434376024 0.803362622219138 0.285832700501196 0.104478299822658 0.525310629310552 0.640117228291929 0.907673426356632 0.957098553020041 0.221308224578388 0.147682912005112 0.817796834164765 0.394316285683308 0.541265753763728 0.736801157726441 0.475673128166236 0.636917946669273 0.315234604994766 0.902884571573231 0.146222652269062 0.901692880252376 0.423640716727823 0.145440016158391 0.432367995067034 0.0472416531760246 0.606066451701336 0.326645598073956 0.580629355213605 0.480329412526917 0.143208407319617 0.0239009364903904 0.724186861310154 0.758658204858657 0.0265910469787195 0.211730864683632 0.861675744054373 0.17047927506268 0.390526570940856 0.759792707397137 0.0210276942001656 0.50801633030409 0.833948416912463 0.95002622314496 0.38461662378395 0.139923512749374 0.614428406194784 0.38235491087893 0.599610628909431 0.146312626320869 0.0928358171647415 0.921273735936265 0.888505579459015 0.0197461154963821 0.367822075742297 0.675502842073329 0.111817801729776 0.557454837628175 0.298392925679218 0.493851097528823 0.0937759460718371 0.157220310862176 0.866290726775769 0.0989446693984792 0.787467109358404 0.633739951245952 0.194259271577466 0.846550794974901 0.417387087820098 0.334811301724985 0.319229363552295 0.743638067035936 0.0372826302773319 0.401200054965448 0.56374852507608 0.0586667216499336 0.604873405948747 0.566562954233959 0.11740803799592 0.344982343439478 0.155508068045601 0.93414612743305 0.506500554080121 0.335409078879748 0.50974489568267 0.839066620580852 0.968700669417158 0.111337979305536 0.591820244607516 0.875878135650419 0.468675667755306 0.835965348782484 0.389447254810948 0.201565689714625 0.404141679231543 0.330939450471196 0.322486257851124 0.53867009322159 0.238972654326353 0.333897992456332 0.878750432650559 0.0501811137166806 0.171832267309073 0.633964981457684 0.138636077903211 0.632644912321121 0.550893373079598 0.719154358641244 0.926610545255244 0.796563126896508 0.771868310170248 0.826495973700658 0.256177970902063 0.635293059397955 0.218173148459755 0.4742825663439 0.709916143750306 0.969991788151674 0.480597063081805 0.573855701738503 0.499724339724053 0.23412948789075 0.94631552598672 0.225841580659617 0.81988447885029 0.157208042836282 0.379379256169777 0.583043924130034 0.715927634101827 0.888041061467957 0.0987775250081904 0.868782445976976 0.358048541531898 0.252243492393754 0.887928358733188 0.940641002622433 0.964514642094728 0.490807805827353 0.260447822243441 0.97842350509949 0.83813100398751 0.125670291699935 0.762364064003341 0.214749676575884 0.108161652488634 0.333136391297448 0.26145046730293 0.114962597901467 0.697832708046772 0.281488652992994 0.840866897080559 0.59188653223915 0.754873349105474 0.5934144075308 0.895348411756568 0.292730558777694 0.42707990472205 0.542909573114011 0.688876484644134 0.149792186568957 0.67912175827194 0.648997421190143 0.114816290000454 0.768312741315458 0.51318263819674 0.345526927339379 0.363955121741164 0.299215115990955 0.792336885905825 0.567948465519585 0.304253575531766 0.263123120190576 0.225513215328101 0.681854258370586 0.226373998415656 0.236022741196211 0.918381715773139 0.541390792522579 0.285712370444089 0.372378691122867 0.0242439025314525 0.714965770437848 0.17416951790452 0.484704989988822 0.524322021612898 0.271482585719787 0.757530512742232 0.283171986206435 0.224943501602393 0.0145032453304157 0.904644549579825 0.739431371029932 0.267881365185604 0.955137453887146 0.931067368797958 0.176387888533063 0.841003618158866 0.89057894452475 0.327621539207175 0.882434730145615 0.960944815287367 0.764514737939462 0.771387333390303 0.934925148345064 0.766912463128101 0.81679475660203 0.72895503842039 0.356448089813348 0.969918808806688 0.104336458134931 0.360832467854489 0.244839460435323 0.628741974830627 0.104350706867408 0.813470866337884 0.291113311967347 0.704204135404434 0.534715940416791 0.0792471048492007 0.062639056018088 0.926587555643637 0.159037650066894 0.636505016023293 0.0248770583374426 0.881118769713212 0.193810259709135 0.285321348814759 0.509114291537553 0.384029629989527 0.613290015312377 0.627458597286604 0.545688295846339 0.953803016156889 0.512938398842234 0.608127316625323 0.149088490824215 0.159899949629325 0.710063589871861 0.82729705529986 0.869565402024891 0.870012195538729 0.960950534280855 0.305655404077843 0.18231434910791 0.94912192928372 0.190402671741322 0.163964665415697 0.640412462600507 0.935751325886231 0.95574743475765 0.0153956514946185 0.625944339612033 0.126249856173526 0.88575506698573 0.0302869435818866 0.638234974327497 0.952172033481765 0.0154737267852761 0.533644641158171 0.969431876768358 0.0511280899262056 0.713034279330168 0.0220680874749087 0.518276270315982 0.536004001537804 0.32350570099894 0.336191689635161 0.686000871867873 0.653952747066505 0.946206547478214 0.83000577401137 0.341023122118786 0.231730729129631 0.748742037646007 0.950243514471222 0.180852949768305 0.0199175760429353 0.28449456643546 0.240855380590074 0.140341848675162 0.989714987787884 0.0743655378767289 0.770346526594367 0.334383946242742 0.903941795667633 0.475198881593533 0.12673842869699 0.475331604839303 0.520546216303483 0.0250168748316355 0.116451578459237 0.0277257521287538 0.525294731794857 0.665848420406692 0.663105505981948 0.144976710840128 0.195868974968325 0.793255655774847 0.596077247748617 0.481486248667352 0.961075538694859 0.322178956284188 0.500678556933999 0.190927470012102 0.657367411686573 0.926196607544553 0.0184067641478032 0.926929897023365 0.756798807505984 0.109870417255443 0.758628031411208 0.752889929970261 0.208389525392558 0.320489992129151 0.498906266184058 0.964007756621577 0.5434958435921 0.314406823387835 0.100104396960232 0.553808604367077 0.394660554754082 0.796996028495487 0.445480588669889 0.674494277252816 0.247855447521433 0.229207074521109 0.357407228709199 0.67448131080484 0.0430972886900418 0.0684269708581269 0.830818982108031 0.959751357627101 0.190577763391193 0.967158696833067 0.932580606730189 0.231785689876415 0.195916112926789 0.778593296534382 0.817111336579546 0.435715382969938 0.634767999276519 0.281553251503501 0.479200957217254 0.617252119295299 0.846414594601374 0.17176797098713 0.125721140285023 0.013316629671026 0.178194135734811 0.849173892671242 0.387752558523789 0.290959016007837 0.214486180595122 0.311475141148549 0.588070142383222 0.906052745291963 0.862819418511353 0.330900976634584 0.142511601520237 0.710016122295056 0.692705060697626 0.366624197047204 0.561727566791233 0.48001886525657 0.534989867550321 0.444817848119419 0.535179685764015 0.588996257900726 0.0156450236751698 0.445901344870217 0.277939234632067 0.770685009825975 0.607439671219327 0.0442246449645609 0.458083537917119 0.932045174464583 0.0834415676351637 0.404439384986181 0.400402978344355 0.119770995364524 0.908515169490129 0.584628060432151 0.292246035027783 0.20454078937415 0.909521801548544 0.661803510303143 0.116971882856451 0.352425730905961 0.202568340997677 0.678935413036961 0.0368443925492465 0.0717183494591154 0.75454052424524 0.652080184803344 0.518059087786824 0.534074812687468 0.154929956428241 0.265273386598565 0.430113054551184 0.111471586066764 0.517431816936005 0.0292753649433143 0.328852691836655 0.352481131451204 0.700962930708192 0.212238092452753 0.286646848355886 0.839947821104433 0.230574756681453 0.064374255023431 0.477139128332492 0.342371712692548 0.730905048316345 0.751899581518956 0.554386398813222 0.652782266340219 0.64176128413761 0.0908917618356645 0.0341928577795625 0.805666219242848 0.674150567841716 0.232783191506751 0.500615559723228 0.354550265185535 0.513044269487727 0.863931382300798 0.169325017090887 0.38900511629181 0.290345499461982 0.165284095138777 0.848879050216638 0.387398905702867 0.562108020118903 0.478977511939593 0.48633536252426 0.0684956070780754 0.462304050924722 0.22855763718253 0.637249477719888 0.798768071455415 0.708330352902412 0.415991158981342 0.683129445014056 0.646942719437648 0.557362388903275 0.270874747599009 0.218782039054204 0.765111669842154 0.160256287802476 0.836499745170586 0.678241474917158 0.593064529185649 0.434981472056825 0.454343683365732 0.166745079113171 0.776363101827446 0.547809609316755 0.365993194594048 0.637439619789366 0.289283413842786 0.0287192971864715 0.977859280786943 0.637060325427447 0.257759832376614 0.782441749956925 0.682966502450872 0.990379849651363 0.0687518486892804 0.456054582123179 0.141439571569208 0.797226113392971 0.770057526452001 0.988582938946784 0.493595984687563 0.788458096070681 0.275944775126409 0.117859217047226 0.771481116954237 0.31391213310184 0.774563905000687 0.441659051235765 0.120163741842844 0.888243752545677 0.556410770607181 0.411476089803036 0.998846574372146 0.682312579075806 0.0659388382732868 0.662114305133 0.63727875105571 0.239649602579884 0.224530877524521 0.620092474434059 0.179609217473771 0.30361488352064 0.617655466345605 0.972649374529719 0.792580955610611 0.760409390123095 0.382668680341449 0.920999936270528 0.257555438808631 0.457477262141183 0.500406737974845 0.880261073973961 0.264589096615091 0.994398643148597 0.412665283400565 0.949620816095266 0.09183150511235 0.488504366697744 0.873715232643299 0.0450706076738425 0.472271964759566 0.702874939527828 0.301281262184493 0.0101527082594112 0.358023890228942 0.431460547472816 0.242155745695345 0.805158916560467 0.293427446405403 0.27825251635164 0.573894762203563 0.398964322439861 0.487440124268178 0.988987101283856 0.0272378616617061 0.631287710410543 0.181551659977995 0.436963285051752 0.0377050248882733 0.417039950839244 0.403451552698389 0.462000879959669 0.323468716207426 0.912760295076296 0.388145106770098 0.803487197668292 0.867476887654048 0.796853206250817 0.71835427189013 0.268676366363652 0.559698563052807 0.690718935234472 0.614579650533851 0.786016592725646 0.0144205565354787 0.42700653352309 0.298342513204552 0.504140569730662 0.780344053064473 0.733308016511146 0.307059398884885 0.807372231120244 0.918685085892212 0.224698903816752 0.371716516455635 0.707107211612165 0.338622953605372 0.754219008060172 0.882514388987329 0.0896260811085813 0.781030948646367 0.426854706704617 0.635574534791522 0.45525616951054 0.966413206174038 0.957587867991533 0.238588248344604 0.606418069878127 0.241163758602925 0.875257462006994 0.518127950590569 0.0209612592775375 0.777839254238643 0.34411065736087 0.179406739841215 0.805638429881073 0.0504065198777243 0.661868592407554 0.753603334242944 0.095126927185338 0.6946867895592 0.394785085485783 0.208632872472517 0.0106444301363081 0.265251660831273 0.372931722011417 0.826053909403272 0.475365631594323 0.972612107603345 0.831380150651094 0.89734727316536 0.554472698657773 0.992268671779893 0.335928350626491 0.215778281500097 0.513398179318756 0.393112515578978 0.960790209763218 0.818730107010342 0.993834950374439 0.745563728739507 0.53143408755539 0.0213526425650343 0.152175591799896 0.549842662059236 0.296876493215095 0.201567953017075 0.681943011451513 0.707715067942627 0.204833527803421 0.152165625109337 0.316528779498767 0.115142209702171 0.716647293977439 0.78091736931121 0.766062655870337 0.730356704692822 0.0632108557899483 0.719521999265999 0.350756755452603 0.595048720042687 0.738017550369259 0.816392507664859 0.548548798963893 0.161820795217063 0.318156105945818 0.153221504683606 0.236010594414547 0.133167426548898 0.67252235326916 0.299048693303484 0.892145099339541 0.881780765971635 0.435103609943762 0.400857399641536 0.949710368788801 0.562192871947773 0.543330430043861 0.101571069962811 0.996352558676153 0.410339262187481 0.729497938500717 0.528330049037468 0.544767689565197 0.906519641145133 0.680447443367448 0.937150063626468 0.937627712183166 0.694254100483377 0.349927853604313 0.126183641150128 0.100088026453741 0.186975559303537 0.121562753419857 0.858155946165789 0.555975645352155 0.0998746910085902 0.229134525062982 0.0891995450621471 0.552273153385613 0.596111749568954 0.565637267681304 0.821231762014795 0.510739042812493 0.871867980228271 0.570701579442248 0.710031631644815 0.124971555443481 0.934214603223372 0.688817988452502 0.940037605590187 0.139743459767196 0.497255180017091 0.730427510400768 0.773067446486093 0.746926252257544 0.0973534739622846 0.373356963787228 0.448638584327418 0.924642400357407 0.953222830710001 0.552976907447446 0.153909738101065 0.405643721665256 0.894656720573548 0.199371294095181 0.163357140086591 0.0599738395516761 0.4005194066884 0.611981586774345 0.896265537682921 0.101285681792069 0.289035445190966 0.609706377496477 0.19305878106039 0.522954749746714 0.903736837599426 0.809516110999975 0.734104197861161 0.14937788927462 0.666285373545252 0.7952670975402 0.593648611966055 0.158639089628123 0.319649661513977 0.270070320488885 0.994570993434172 0.815679092558567 0.965396656983066 0.838114646619652 0.363773156281095 0.829100948150735 0.0612082099937834 0.747168687239755 0.5959908132907 0.286563216345385 0.460280957496725 0.0612141546490602 0.913207439184189 0.308918917942792 0.275954672435764 0.7412663784693 0.341716151367873 0.0343464818247594 0.8687289751973 0.739041225770488 0.244721245006658 0.226874734547455 0.403201476794202 0.265449704059865 0.872965424675494 0.728092846963555 0.208101809609216 0.434000845041592 0.14044176106574 0.710503226057626 0.718108112681657 0.542352899136022 0.653914680988528 0.105978481872007 0.505355540404562 0.420608106735162 0.776833717066329 0.231300215995871 0.332409887346439 0.541836675091181 0.232997391566169 0.583033325632568 0.581905780576635 0.0687996680126525 0.883003980331123 0.926686069576535 0.604834715900943 0.699754623856861 0.164158069784753 0.310434003351256 0.269372870896477 0.280475116698071 0.806560652905609 0.413240552924108 0.0842883460922167 0.843530605139676 0.960916547633242 0.226198797507677 0.339771390471142 0.117319577652961 0.270149066310842 0.564810770202894 0.163758774965536 0.545163350976072 0.481712565773632 0.0105735787888989 0.2084308523871 0.613649146251846 0.552549389230553 0.0242648473568261 0.957501112443861 0.585122450604104 0.945273153157905 0.245624762075022 0.265001577781513 0.593860736121424 0.87059479250107 0.271755040865391 0.75177129175514 0.0856007238267921 0.770624939072877 0.404650617789011 0.384364046237897 0.752606057813391 0.185988098585512 0.873941522319801 0.583678871861193 0.550625610961579 0.617729238618631 0.363484759363346 0.505287538066041 0.430239820925053 0.710773908179253 0.151371659808792 0.799283996769227 0.615278775878251 0.0415918659395538 0.338626760351472 0.571521243217867 0.548008080588188 0.465747367446311 0.360936696862336 0.751329955384135 0.164106947132386 0.199934096669313 0.584034625249915 0.57209576522233 0.47067164857639 0.55037461673608 0.59018889197614 0.574454522146843 0.762694267590996 0.231525060653221 0.287435145373456 0.430015470695216 0.589868416739628 0.760871656336822 0.955051803137176 0.187588861482218 0.368827721250709 0.519852806495037 0.908241122956388 0.698406061404385 0.487449929376598 0.416060986667872 0.345531472845469 0.490231523015536 0.790081961294636 0.632520741634071 0.651911294588354 0.0571569578489289 0.219164165137336 0.718789445089642 0.146479156652931 0.0326301169348881 0.249312746685464 0.387414342213888 0.520477564178873 0.569443493536673 0.791810626941733 0.282385375774465 0.226296953470446 0.250340592334978 0.635601327230688 0.920971002695151 0.932387499709148 0.749042582958937 0.300755862302613 0.7421455985168 0.212940072338097 0.750332974228077 0.841085669153836 0.907744404019322 0.0408167151617818 0.183287612495478 0.559643206994515 0.487559142536484 0.777996255834587 0.551587006705813 0.27267112584319 0.721595612352248 0.158625627139118 0.519316362324171 0.0723411983530968 0.845146751531865 0.461765964655206 0.764501230502501 0.552996992499102 0.185955359186046 0.428426586044952 0.943222565411124 0.87625522203045 0.471849340107292 0.70175837260671 0.644000275966246 0.706301554311067 0.199473762065172 0.670295400347095 0.29743443795247 0.385205696939956 0.0353955613495782 0.234100303759333 0.842391193823423 0.034636859910097 0.559781252539251 0.877810024605133 0.83220464275917 0.797590036015026 0.815964199746959 0.768005756919738 0.034290139907971 0.638669543380383 0.213462975649163 0.30415060806321 0.874049271098338 0.434938095896505 0.0276677840179764 0.543735938745085 0.814838050843682 0.674977139311377 0.871797735563014 0.775714709816966 0.452008818930481 0.58901192744961 0.198919282008428 0.292055824960116 0.264798585667741 0.50704361505108 0.439837486923207 0.788578133620322 0.636744730155915 0.372526630288921 0.748506534330081 0.808550168597139 0.211499004918151 0.748897583389189 0.52239721737802 0.89474887955701 0.891432429677807 0.553509446678218 0.589866708717309 0.140666234614328 0.0178343417891301 0.976995602590032 0.804479499857407 0.570396348247305 0.267885070741177 0.273179663557094 0.397640636260621 0.0625136862578802 0.0512479511415586 0.796798378964886 0.923726880571339 0.855453660544008 0.657572692458052 0.628138026206288 0.298094538559671 0.833000408974476 0.108556310753338 0.832469320525415 0.312681442399044 0.267561250915751 0.94275835952023 0.0431749260262586 0.0453139870241284 0.851628944252152 0.974205382631626 0.203461330332793 0.0598411863786168 0.487905947593972 0.362917575170286 0.939749107481912 0.194880642259959 0.403994730764534 0.766737606821116 0.0225150232086889 0.647840078175068 0.432462646241765 0.258636337798089 0.184169172372203 0.273314397244249 0.663314741482027 0.900638591835741 0.292115704626776 0.503222890598699 0.977480235367548 0.186390703879297 0.435263121479657 0.0177528917137533 0.234711808941793 0.588526239662897 0.794538365092594 0.267351129825693 0.0666637957841158 0.177899133081082 0.108314466318116 0.632871688588057 0.295737295574509 0.0750599960098043 0.111672243191861 0.430729776232038 0.352677118137945 0.205341287571937 0.641973752893973 0.301027068817057 0.739340316383168 0.390480403627735 0.3437204404152 0.245036009547766 0.109373795129359 0.686538896593265 0.0816016710107215 0.55963549623033 0.0433197580208071 0.859344683599193 0.690682318555191 0.21691411081003 0.0235774642624892 0.763836148048285 0.4973642574111 0.165251213288866 0.264305485617369 0.562489424268715 0.951310263383202 0.711773636692669 0.695946019217372 0.0158906755479984 0.188271533339284 0.520603370971512 0.907857769678812 0.0988639868958853 0.759294451700989 0.341131030174438 0.613400821473915 0.996144221674185 0.135295014292933 0.535802357401699 0.805367625132203 0.951217269520275 0.100989025975578 0.664451013356447 0.281082809141371 0.732726069565397 0.196878867021296 0.35341521382099 0.573240819005296 0.869943633771036 0.285113257989287 0.76691110500833 0.844967675879598 0.620107727695722 0.979063962758519 0.118048196462914 0.686939751221798 0.0677876878390089 0.295242407287005 0.335792996196542 0.305855391824152 0.171590372393839 0.859819020067807 0.440136885717511 0.941659251076635 0.49850621485617 0.0173824839084409 0.851402945930604 0.883136783561204 0.364655856913887 0.095935449169483 0.365547444333788 0.70256966937799 0.16067155712517 0.417947784063872 0.326675974824466 0.739945000540465 0.885725275711156 0.238770643230528 0.024019976425916 0.84776226547081 0.103543799552135 0.300951961474493 0.238668728005141 0.562177751916461 0.467104415150825 0.446879659024999 0.927369230098557 0.955436943729874 0.892666623785626 0.371919548446313 0.955388581804 0.403418445417192 0.203894609033596 0.351268228383269 0.0745562310772948 0.0851297559193335 0.0435795002710074 0.413160808796529 0.491813454562798 0.993963065878488 0.571056339826901 0.531927865513135 0.149992676349357 0.110708063209895 0.678679228129331 0.878952402716968 0.943941309961956 0.422639644846786 0.97516444200417 0.818235392521601 0.299473546221852 0.918503517357167 0.926261394144967 0.573903157559689 0.133136258253362 0.494949016580358 0.261046479686629 0.169698485967238 0.863576888376847 0.839203618031461 0.390403583652806 0.392374475446995 0.148122023106553 0.774781011464074 0.326768694850616 0.262097033734899 0.964546406469308 0.837621167392936 0.794666271070018 0.236543270102702 0.43391609163722 0.304100319598801 0.548961479514837 0.441727159144357 0.358229424091987 0.58607292606961 0.140348666473292 0.943887257394381 0.481447115824558 0.822713460081723 0.163245170349255 0.0458981087594293 0.317659692424349 0.0184817933500744 0.488430286243092 0.814111212664284 0.124269036874175 0.831835344592109 0.907351104335394 0.940772710505407 0.321900714838412 0.309913119932171 0.915148490606807 0.676862750311848 0.411928765967023 0.939227197174914 0.628863862161525 0.120228209889028 0.546025964021683 0.989046145840548 0.618239193921909 0.72738731757272 0.310219714317936 0.6742620491446 0.271322818095796 0.48178790822858 0.409444908970036 0.580792814102024 0.715090278810821 0.427436198177747 0.888515576806385 0.904468065926339 0.470538319570478 0.624135105099995 0.846496405643411 0.632773750911001 0.193320531907957 0.928123045349494 0.0590841334918514 0.0601344556547701 0.339856228008866 0.201125702473801 0.351224300169852 0.881702633977402 0.435189041025005 0.57349037489621 0.206976458244026 0.056827312768437 0.192170680679847 0.730318124133628 0.0665617021499202 0.45520211256342 0.870690862878691 0.704537687038537 0.871145737112965 0.472296836883761 0.222757344827987 0.891630118163303 0.593903533720877 0.46363499654457 0.777529500357341 0.117753637987189 0.635960031049326 0.715095718435477 0.636413356077392 0.299998194205109 0.30917206114158 0.720606695320457 0.866046703401953 0.614382983404212 0.304858864527196 0.0899480345565826 0.952276762679685 0.202807079413906 0.693610360010061 0.197269739054609 0.370425194187555 0.265474505650345 0.0764554394106381 0.0829867408843711 0.53598143927753 0.395152306596283 0.367314186200965 0.290099868564866 0.982478667024989 0.770891166506335 0.540642155045644 0.168669119693805 0.846852519076783 0.813931201864034 0.494601951746736 0.939557829957921 0.865391951601487 0.347690360271372 0.427091890843585 0.835654652607627 0.271880144164898 0.571494319161866 0.964185636658221 0.753017238485627 0.411831988638733 0.504567161097657 0.558775820014998 0.15231826352654 0.0794982394506223 0.666808556455653 0.595641393645201 0.957207002295181 0.125043374670204 0.0686911541968584 0.205064333712216 0.903531286448706 0.140770034196321 0.998870793944225 0.593852607456502 0.206035645666998 0.393595406219829 0.937912971964106 0.218073434301186 0.115321915547829 0.37840637749061 0.458061982030049 0.97782343121944 0.347299967452418 0.834617182563525 0.792311372293625 0.967149428795092 0.363769061868079 0.457316809925251 0.833536487568636 0.471572022284381 0.349620095181745 0.259149990589358 0.567674660552293 0.313503505473491 0.381723291371018 0.252578751358669 0.861129696464632 0.621221302466001 0.544567162904423 0.783165230408777 0.613994620388839 0.330501222193707 0.79826946885325 0.476768396901898 0.963409964945167 0.810098547302186 0.268626087119337 0.688993725278415 0.509928818338085 0.256853230725974 0.625228447297122 0.156581756460946 0.783170193124097 0.866924774856307 0.932408306233119 0.473813618328422 0.488822660460137 0.607795868094545 0.253431169285905 0.0609084327146411 0.41193397393683 0.0318652820587158 0.438473877047654 0.265790766612627 0.565030139507726 0.669521748756524 0.997293911089655 0.349760992501397 0.0938546805991791 0.089924224356655 0.0406241763290018 0.146209266998339 0.0363332531554624 0.503225468306337 0.909179490825627 0.296051201494411 0.0902696934225969 0.714830203254242 0.0880663317232393 0.0910244641057216 0.499916512519121 0.727295728621539 0.75105591830099 0.098325338892173 0.433447420916054 0.646741011682898 0.0137049993709661 0.893459291819017 0.698135619235691 0.906435121700633 0.0982411518320441 0.345253250992391 0.328512433506548 0.166828157918062 0.591749787880108 0.600356695132796 0.714346214500256 0.748268393375911 0.664823412010446 0.07246905984357 0.33084674266167 0.23014792190399 0.196061302891467 0.419359538962599 0.817035576223861 0.296328449014109 0.493341119636316 0.250520338518545 0.831720973481424 0.985529974214733 0.552595269798767 0.40218731330242 0.138433396506589 0.966223611547612 0.610785925511736 0.519787643253803 0.627348660810385 0.73616283705458 0.993700280075427 0.821892116866075 0.127149668608326 0.0130923993024044 0.514256840401795 0.697171161728911 0.941515729026869 0.169669112593401 0.389973822417669 0.196440234212205 0.982855004963931 0.777090651798062 0.950707731426228 0.446665158160031 0.282254075419623 0.798258151649497 0.117429141867906 0.78785564340651 0.33718278007349 0.311540188677609 0.479809046816081 0.978157238711137 0.75708762624301 0.972009557667188 0.410828358873259 0.720231045430992 0.975782486998942 0.0926211600191891 0.931974131569732 0.943874127981253 0.0703519857721403 0.918424028626177 0.877293303136248 0.115721562113613 0.756802832307294 0.394592944500037 0.339389921089169 0.424745375437196 0.340782321628649 0.813899513785727 0.962669562855735 0.379705823813565 0.394816997151356 0.776576729319058 0.690134561560117 0.857127247657627 0.477408014379907 0.51353466344066 0.811121522206813 0.0360904950089753 0.273106037422549 0.714193341662176 0.886603822000325 0.547784878720995 0.941556919333525 0.281722076947335 0.648561411267147 0.492572839902714 0.752601057295687 0.735535899510141 0.475629649201874 0.38865945613943 0.361183601284865 0.0611721001891419 0.236688567250967 0.850796410378534 0.998049353687093 0.0934261338808574 0.0428429577127099 0.384576600741129 0.930736852649134 0.824598158984445 0.0699044458917342 0.760589195776265 0.0785372512345202 0.314078547030222 0.212632802349981 0.668961606409866 0.282739302432165 0.3039006384206 0.466382650788873 0.967362790748011 0.464555478584953 0.116510461894795 0.410318271031138 0.599540519088041 0.920545936101116 0.848300299877301 0.823963489700109 0.676405238208827 0.507081101646181 0.716903747881297 0.222135429468472 0.451042712179478 0.451445780552458 0.195566585175693 0.473463549588341 0.524860361204483 0.87869357394753 0.298244020938873 0.902663915834855 0.664236199238803 0.620457969543058 0.956840833197348 0.828112292508595 0.938578538934234 0.508156509839464 0.0427002680068836 0.528606944810599 0.436411170409992 0.0635394901176915 0.504806886524893 0.299940190827474 0.574806952844374 0.660986304373946 0.0247177816834301 0.941236983933486 0.787934502866119 0.686047234877478 0.584356691874564 0.791766029119026 0.269236645398196 0.540525057092309 0.548804042499978 0.810029339205939 0.419637867077254 0.318952467087656 0.0612708496954292 0.702696549159009 0.135752591628116 0.90836677623447 0.102962868199684 0.989562649254221 0.480517529633362 0.753826263195369 0.386401737839915 0.305029272369575 0.518394512252417 0.593459395132959 0.887138484849129 0.81153777024243 0.617516406590585 0.787282471223734 0.952551080975682 0.184202578614932 0.662938058481086 0.395144177700859 0.393950885080267 0.771250555838924 0.932046412492637 0.969697155223694 0.557952246458735 0.041927246148698 0.8976775936177 0.562102466165088 0.63621913757408 0.529406884501223 0.623260333517101 0.0390039793192409 0.255281203172635 0.518171389447525 0.683516808571294 0.993088944542687 0.242388675683178 0.902665163313504 0.832870925439056 0.209584290231578 0.284692635941319 0.608579267859459 0.766421959917061 0.443852495111059 0.0435207429202274 0.0319827608019114 0.0330260017025284 0.383241938271094 0.448248029004317 0.996048660706729 0.0340458408533596 0.59057677739067 0.921587893103715 0.891955560264178 0.348105624062009 0.928000280726701 0.22010414398741 0.76457182046026 0.87414370629238 0.981200942320284 0.0853494145045988 0.23991689193761 0.881051879317965 0.428004455820192 0.861863066158257 0.524707407460082 0.75425246847095 0.562717890578788 0.460232324500103 0.856268382810522 0.797628573009279 0.643091281470843 0.309103110055439 0.536834636994172 0.883658942810725 0.782873985865153 0.54097901185276 0.0846657346608117 0.828646334845107 0.857883679110091 0.82120847182814 0.508657389804721 0.0251448133098893 0.947739817677066 0.269693014440127 0.0922875915584154 0.0131199494027533 0.987075891154818 0.122471453102771 0.82502253822051 0.744014843390323 0.844063004455529 0.806525354238693 0.0534140535211191 0.058963141432032 0.900306505735498 0.549333035682794 0.556298833140172 0.630643571859691 0.194199420954101 0.428654782897793 0.845346424411982 0.0195197177142836 0.156343195992522 0.239446519878693 0.878826844866853 0.696510335730854 0.892969673045445 0.938556320583448 0.454246441575233 0.490735899701249 0.479914408742916 0.778410015597474 0.247710366814863 0.259730952137616 0.907081888669636 0.770354959291872 0.102081222806592 0.438529331991449 0.863212707592174 0.777579859585967 0.20908100774046 0.530201854791958 0.589461491601542 0.864476860780269 0.926866643493995 0.174127158720512 0.801949445581995 0.0357129079778679 0.380364052972291 0.189073257579003 0.104631801471114 0.488543939569499 0.672885497484822 0.390525549585 0.743406334277242 0.81085573411081 0.490403620209545 0.573124464883003 0.19007664716104 0.666142656409647 0.252689232972916 0.0299899316392839 0.106622352348641 0.44281970011536 0.979330287924968 0.745669803840574 0.140861245584674 0.883882676216308 0.520520437152591 0.629689424722455 0.594202871662565 0.531224090014584 0.0455749735259451 0.363358823258895 0.381172529547475 0.219675942100585 0.201480162974913 0.854454758842476 0.871564414182212 0.210084896590561 0.882104991711676 0.260976994987577 0.39924545484595 0.292580102526117 0.658141013488639 0.455712911735754 0.0679623797978274 0.023836478816811 0.786348832570948 0.39506221752381 0.791482422270346 0.261714179494884 0.0683533696178347 0.851007750825956 0.687999640614726 0.6458257650421 0.464988528166432 0.358544387787115 0.71976874118438 0.161519501924049 0.31690619941568 0.645367310876027 0.684906507162377 0.757931847276632 0.162234894509893 0.466123701236211 0.0288042409857735 0.649772040199023 0.53723960562842 0.33515417925315 0.375572015182115 0.994150949255563 0.23500022337772 0.768781744651496 0.613067791005596 0.636756674326025 0.951164289480075 0.955508447168395 0.883730995305814 0.160744869315531 0.692057489736471 0.404237708349247 0.444809795520268 0.673593061980791 0.0545027218223549 0.31639911086997 0.577399448358919 0.587717919137794 0.0576976395747624 0.747108040922321 0.446355162942782 0.747416515515652 0.171643981935922 0.922965577912983 0.865257307810243 0.786511944092344 0.276612500520423 0.617283452400006 0.480500921248458 0.234025556691922 0.411498677879572 0.484217781808693 0.425623472707812 0.692874049567617 0.826328435151372 0.905722519806586 0.420129893447738 0.886205761982128 0.242654107422568 0.363871115855873 0.303692646941636 0.151614973926917 0.47990153795341 0.208072391287424 0.992921121092513 0.0554051405470818 0.155903861534316 0.24522445488954 0.204529791185632 0.176276197703555 0.142491221425589 0.562693708117586 0.928095450531691 0.468298789518885 0.240198818885256 0.952216286242474 0.794927379507571 0.108513040163089 0.700144832965452 0.844961589926388 0.154645646547433 0.608720445239451 0.899807416312397 0.257057349074166 0.510155407206621 0.440571956573986 0.666537996730767 0.450634008024354 0.0907187387137674 0.840000325157307 0.346411734994035 0.938915898236446 0.205351815305185 0.202652148420457 0.600124213933013 0.190450892830268 0.962010752600618 0.916104215993546 0.39227677841438 0.258567337845452 0.501716997623444 0.728036768971942 0.0211582829942927 0.294915714941453 0.333612152962014 0.471747848314699 0.516428276144434 0.827482852630783 0.538996156526264 0.373334038716275 0.0278331168903969 0.639240153529681 0.0767943785758689 0.451952253426425 0.857717734023463 0.163092916409951 0.739649785594083 0.584221897104289 0.489646957102232 0.931134983892553 0.239870069767348 0.569413035418838 0.936955950462725 0.191589571149088 0.758290615405422 0.801842266605236 0.425695503766183 0.685022146957926 0.421708264194895 0.507254574017134 0.970983505095355 0.505722309499979 0.717093820569571 0.280145889287815 0.0419107191311196 0.847220239685848 0.941850075433031 0.121161567559466 0.923992231404409 0.219395885679405 0.710211017783731 0.562432885502931 0.233865763712674 0.881745729155373 0.555543550050352 0.381745808222331 0.635272456177045 0.953514359232504 0.317443555453792 0.78424348784145 0.0413737743091769 0.392512244388927 0.518002718670759 0.790329372361302 0.301832038068678 0.90411323385546 0.844857763606124 0.486051701507531 0.443124769497663 0.222276498512365 0.893033958533779 0.353729803410824 0.197236535653938 0.645873996734153 0.888336265119724 0.946624709605239 0.221624168599956 0.924544313084334 0.838027360916603 0.400512477327138 0.117891063941643 0.281536263020243 0.854116025054827 0.192539478195831 0.563652378632687 0.350570106876548 0.536292329074349 0.970298719762359 0.670755036990158 0.535523030289914 0.906432423901279 0.357020078597125 0.621715949878562 0.960620842638891 0.903226218910422 0.318181904919911 0.929623277878854 0.134459737441503 0.23362180856755 0.191528371626046 0.670538652460091 0.169707228920888 0.654299215590581 0.743841063529253 0.0148590837744996 0.197257020396646 0.592324512726627 0.502802272238769 0.275577019250486 0.0841554112453014 0.160408928524703 0.803571227525827 0.439475314735901 0.486345275968779 0.28751571147237 0.208371406525839 0.558959368104115 0.31697223211173 0.874967688529287 0.101059002566617 0.679809137908742 0.808669599464629 0.34549927766202 0.915215294333175 0.476979996894952 0.105272987748031 0.191981665536296 0.0914289053506218 0.941608874560334 0.195597662192304 0.105160928114783 0.62995232623769 0.853384770220146 0.362854775039013 0.0773491746513173 0.486176728510763 0.960239305719733 0.850044259354472 0.505163337413687 0.347900565725286 0.05888379445998 0.951213625969831 0.524257699935697 0.729416397376917 0.117535645703319 0.302448115495499 0.427725674768444 0.0334865377657115 0.405691680673044 0.992621764710639 0.882505274694413 0.43615779302083 0.204424176858738 0.640811767100822 0.356561461465899 0.774654879432637 0.458070950184483 0.905409029482398 0.732747360835783 0.406228833638597 0.474166280911304 0.508736313804984 0.228285889909603 0.643217726985458 0.513843475950416 0.733324320863467 0.805363910817541 0.535186678743921 0.515367178227752 0.110079283721279 0.378111810255796 0.902613833670039 0.334881949308328 0.868990072340239 0.265664999005385 0.130011255086865 0.792498032625299 0.824533161704894 0.69998218544526 0.603495087949559 0.934090707295109 0.318614114089869 0.23570726325037 0.909936780438293 0.0252965997904539 0.219236059738323 0.704173504179344 0.612534060999751 0.995008205196355 0.327671256947797 0.516233174125664 0.565167008107528 0.77998039690312 0.997357724509202 0.756047185715288 0.187101476506796 0.183592921139207 0.114196431182791 0.204550671009347 0.980976575494278 0.294091186875012 0.986918953177519 0.690371849655639 0.454828217257746 0.220635051261634 0.0572534982208163 0.770250688102096 0.217568451163825 0.49130181774497 0.773905253331177 0.703072866122238 0.471991710336879 0.885274493354373 0.513589992069174 0.500498289123643 0.726817813143134 0.106332030044869 0.194007971014362 0.159505939998198 0.868915342099499 0.707876752885059 0.882984227202833 0.366723072407767 0.27337489143014 0.0111514248675667 0.977868745443411 0.809036493031308 0.130043755916413 0.226671118694358 0.426113655751105 0.381694312847685 0.333159071113914 0.516472134746146 0.231074137459509 0.374171994004864 0.275219607627951 0.972284684104379 0.64496745985467 0.379777293598745 0.0638362111663446 0.706383557131048 0.4059475426469 0.0867016163584776 0.180573236104101 0.377216479938943 0.772540663359687 0.730825338764116 0.419141567193437 0.648739209705964 0.0456818224233575 0.703828609064221 0.916471157043707 0.731739242959302 0.501984346681274 0.622768376066815 0.657202404283453 0.68869352272246 0.808600093098357 0.832327537846286 0.0248581345565617 0.889553526064847 0.260721683683805 0.981021443465725 0.270389412941877 0.571669207508676 0.360494738596026 0.342950646972749 0.97192218022421 0.523069164652843 0.0873802021006122 0.995113250873983 0.976804865133017 0.572947700938676 0.323922416493297 0.606025142224971 0.801316231458914 0.410050971300807 0.334271547079552 0.0833618762926198 0.604549802334513 0.780400339199696 0.816023134123534 0.372358671764378 0.81026836482808 0.393819658025168 0.620544971728232 0.750849539185874 0.141672261604108 0.883956988325808 0.608812343755271 0.91929814419942 0.814452572334558 0.629621842589695 0.644819029718637 0.582507627480663 0.953902693896089 0.961210454017855 0.905867671046872 0.23996549612144 0.726535161265638 0.865753424675204 0.454069649970625 0.402783663878217 0.297492828113027 0.164660427500494 0.59406860843068 0.912362317808438 0.0225526739214547 0.267528629994486 0.273298114098143 0.319264481274877 0.499388342229649 0.711451062732376 0.974327755169943 0.248284089898225 0.129323795926757 0.412173788337968 0.561444191597402 0.0183366114529781 0.162402902131435 0.730765382109676 0.128436927350704 0.74626770270057 0.6200011540181 0.275865852278657 0.86777346855728 0.930950372265652 0.942038245785516 0.422135686753318 0.824611849901266 0.796483316384256 0.229004598963074 0.984900227768812 0.721237120365258 0.262700048363768 0.817693371577188 0.416042458659504 0.320199093108531 0.753093100723345 0.761552928122692 0.221206104436424 0.546732476043981 0.787316937777214 0.0725144051853567 0.974856813815422 0.711810590827372 0.849658731287345 0.625495345261879 0.101497201109305 0.946952187963761 0.743450539093465 0.648226918492001 0.111972560768481 0.557053999134805 0.955295263393782 0.0154563630442135 0.165278322207741 0.595290634089615 0.304574424643069 0.344519861706067 0.900440168969799 0.811105082780123 0.617899365017656 0.929369900259189 0.113670709058642 0.205534285795875 0.777055478293914 0.801478377867024 0.0126188419316895 0.189849097789265 0.452106011623982 0.843384845834225 0.926883726944216 0.0493623910821043 0.107100620034616 0.638667419762351 0.273744103850331 0.845249797371216 0.882978438136633 0.656178436835762 0.362489704976324 0.403871496608481 0.669995298059657 0.0866636618436314 0.751244362029247 0.408957744124345 0.809017839168664 0.696215422512032 0.603855428795796 0.261062435749918 0.10983510222286 0.0748433763673529 0.518032296039164 0.834895415480714 0.584931723058689 0.456884005828761 0.633543446389958 0.938602857161313 0.306765069067478 0.326764469973277 0.971325934987981 0.964376890209969 0.149657994562294 0.849092428996228 0.518532066596672 0.84281095471466 0.700851386708673 0.58541347063845 0.569672096995637 0.542849888221826 0.706343181419652 0.0593586011533625 0.449029200042132 0.17664987702854 0.715159122943878 0.696858694604598 0.41272294747876 0.357241697143763 0.606729887216352 0.340429976677988 0.612185623063706 0.895435288778972 0.868740907381289 0.596881849579513 0.233100717004854 0.513381500400137 0.695739040565677 0.220246856282465 0.570019536856562 0.547284058686346 0.821054356121458 0.759548399352934 0.582991513891611 0.966009720822331 0.351124088817742 0.228423273912631 0.401255985435564 0.95083284325432 0.804117145342752 0.287877654540353 0.291757070419844 0.125839757709764 0.0363288348866627 0.190687149197329 0.921259525006171 0.619043391221203 0.564588507632725 0.649001418331172 0.585538401291706 0.311333540566266 0.484834066687617 0.0205239629209973 0.182202489550691 0.106223727599718 0.314689761318732 0.751002310602926 0.490497101354413 0.210424821153283 0.520478632326704 0.2002835939941 0.873128511994146 0.847755397884175 0.745914626826998 0.297718227820005 0.616389588308521 0.230967182531022 0.907547766854987 0.424265816477127 0.375083653337788 0.670135669833981 0.566848756156396 0.397887564885896 0.369061233717948 0.857437851631548 0.124556813510135 0.374175088959746 0.279822743451223 0.156785416570492 0.208495853124186 0.214287402064074 0.586924361826386 0.385439643443096 0.0893527622707188 0.994294202539604 0.640401774668135 0.626005491882097 0.816740077529103 0.763380859601311 0.192071420610882 0.767917327464092 0.788827604686376 0.234998372443952 0.715803997027688 0.939876937163062 0.604521984390449 0.916888375955168 0.888606566681992 0.660926950252615 0.346365072331391 0.780659920789767 0.846903272694908 0.312139070399571 0.642365097226575 0.298296005900484 0.195661294206511 0.0635107840481214 0.0748547777044587 0.696714596759994 0.775752505746204 0.486176577762235 0.672068706690334 0.835362408836372 0.792816992308944 0.8908676374075 0.743748040392529 0.954133906872012 0.691658102946822 0.887069190314505 0.544943662195001 0.281626044602599 0.8302229832788 0.358279241640121 0.169495373761747 0.577265197804663 0.185923184747808 0.337378748550545 0.223155920018908 0.807008891899604 0.531398104757536 0.393633284899406 0.753582676162478 0.976692228782922 0.752086089488585 0.495893621381838 0.0199749904870987 0.387243938751053 0.786594987630378 0.685244850018062 0.992439412928652 0.516564864453394 0.755602859498467 0.961666002701968 0.240484504404012 0.926719904553611 0.415739412626717 0.402247732344549 0.675266962808091 0.976846697849687 0.559831528556533 0.683162549990229 0.516044819371309 0.15216621219879 0.754720250836108 0.390621531680226 0.292627817662433 0.792210294022225 0.252339737492148 0.267611540993676 0.601563008599915 0.607114474603441 0.998291529584676 0.420685516796075 0.536967193125747 0.229658766901121 0.728122428942006 0.11675460443832 0.646174490184057 0.03404727388639 0.501503524107393 0.85341821357375 0.951463384011295 0.945565682521556 0.329250163612887 0.69224540307885 0.611925407131202 0.2126789201051 0.951149570292328 0.417801213159692 0.324195907516405 0.0822863569972105 0.995301548233256 0.466690105639864 0.760404136052821 0.444476591714192 0.87192928094184 0.208104045712389 0.354412502236664 0.91947817574488 0.369057612987235 0.541635603522882 0.863958142008632 0.021107044168748 0.0523985872301273 0.497240701473784 0.470547930134926 0.520707563098986 0.962805860270746 0.878673755126074 0.323916417439468 0.647621144750156 0.265606716950424 0.553104689875618 0.9831211348949 0.954542886016425 0.428956145802513 0.923852638266981 0.964121895155404 0.107562951019499 0.462094722993206 0.0721551967971027 0.547355675301515 0.324655835053418 0.652326943548396 0.329342066738754 0.138171154228039 0.453564067757688 0.0958514619548805 0.0329890558659099 0.876934870849364 0.230252409765963 0.66671183997998 0.0784222964919172 0.252493045057636 0.372141154315323 0.311142970914952 0.539705990087241 0.477920989724807 0.986462964233942 0.695999297758099 0.360933043169789 0.821216526040807 0.533164013358764 0.915521826022305 0.999032124143559 0.880707578207366 0.600652104392648 0.284481393226888 0.551474403778557 0.251406870561186 0.348937504230998 0.854363839731086 0.316987442960963 0.689643679403234 0.551486089325044 0.904799271507654 0.410522228949703 0.589444106884766 0.366394853445236 0.460922134323046 0.328427610029466 0.0185196918528527 0.224619319427293 0.0732225973391905 0.863434041007422 0.60653697934933 0.124159311538097 0.709915765726473 0.755957714389078 0.0323481766181067 0.362375228526071 0.374831712439191 0.665413562995382 0.787485399949364 0.157573985119816 0.224853750676848 0.135391466151923 0.954968396327458 0.903551149065606 0.0301999819651246 0.830747252546716 0.54270000200253 0.709324635106605 0.724741004602984 0.446049747806974 0.304816248333082 0.0630676615145057 0.445820718149189 0.953848506254144 0.0767703141318634 0.817635588098783 0.476550397241954 0.167337615105789 0.901125766132027 0.0604222587984987 0.213421755377203 0.450983447954059 0.25989429323934 0.132751181740314 0.829079662642907 0.881495032738894 0.232003741168883 0.15097988051828 0.374164786657784 0.834646322207991 0.86211380245164 0.369281174207572 0.386218468658626 0.926772222130094 0.19836450368166 0.721823119081091 0.51457192119211 0.634726788455155 0.209600612102076 0.509686694995034 0.641907970062457 0.84087708390085 0.531628926109988 0.753108682911843 0.530687955408357 0.611512822699733 0.210940731023438 0.201097068781964 0.743458524385933 0.241800342209172 0.52158707749797 0.793599201298784 0.778222179473378 0.664614173052832 0.532997767697088 0.235901257935911 0.307665995750576 0.537782237173524 0.728609262325335 0.798551282624248 0.542104645583313 0.132854034879711 0.757054460183717 0.894314502973575 0.593104007320944 0.246465695914812 0.617436819204595 0.293362893303856 0.509305901676416 0.232868964653462 0.110598022316117 0.596932000895031 0.192143930192105 0.165315853750799 0.272153345216066 0.959433560597245 0.590968558064196 0.483017578267027 0.155677403360605 0.890938135625329 0.129771302384324 0.836270454123151 0.265345508013852 0.556705119786784 0.815062877982855 0.871670259702951 0.817393301329575 0.255240941790398 0.206540877055377 0.849316045767628 0.926008847255725 0.357825642083772 0.498970609989483 0.323079323768616 0.26081559056649 0.261516981518362 0.417064404140692 0.878786397699732 0.0156464534811676 0.936241306548472 0.932129723643884 0.432796854346525 0.56895590917673 0.766912655597553 0.99709293656284 0.265679071403574 0.3415674213483 0.212076390222646 0.0592908516759053 0.114827541050035 0.716342053562403 0.0932589512271807 0.326471615831833 0.44954910336528 0.180391097536776 0.859900968719739 0.907898444812745 0.967199224215001 0.822804361905437 0.266987875199411 0.56065032426035 0.612026868036483 0.924896963911597 0.162614184031263 0.160162547111977 0.679788542294409 0.812707893459592 0.158899921232369 0.958609559459146 0.867245031115599 0.895638134754263 0.601527564025018 0.12102271433454 0.550848437570967 0.665585986350197 0.822550513599999 0.474214796351735 0.280463787738699 0.25971515028039 0.78721249809023 0.627318989166524 0.958395551638678 0.843796612443402 0.120614060659427 0.987922249867115 0.32246104458347 0.210483732940629 0.674465137147345 0.742942718472332 0.701180547503754 0.375964108877815 0.202761209909804 0.424592722037341 0.678248809271026 0.423515306168701 0.573278155312873 0.539787018112838 0.666895859907381 0.647597864014097 0.775060853748582 0.285646829640027 0.429664449058473 0.14149389105849 0.428527573959436 0.435936128143221 0.104658862906508 0.930907662948594 0.489236451571342 0.784023822110612 0.985012282561511 0.548042241034564 0.956343543766998 0.287190834102221 0.680876112943515 0.280935960942879 0.184385546529666 0.0679042093059979 0.0981321809301153 0.489059445830062 0.561710237625521 0.727152709527872 0.378830882119946 0.755153057698626 0.594338566774968 0.0831588419969194 0.85942904699361 0.78690410832176 0.693124596849084 0.779334101541899 0.354412003429607 0.379631189922802 0.70439277920872 0.182120112625416 0.989974033690523 0.0967629255913198 0.295366240749136 0.239412083290517 0.896568283371162 0.0832975504663773 0.423614527743775 0.66634632112924 0.867977541727014 0.794670921685174 0.825745044569485 0.617991332453676 0.258458906318992 0.514270945070311 0.75097133961739 0.994757928524632 0.890259507931769 0.51097610847326 0.751697047874331 0.836899933416862 0.293162856921554 0.896838057083078 0.973924092561938 0.746425777745899 0.974690083176829 0.916616020847578 0.606279360025656 0.266815014120657 0.910157705633901 0.522263090834022 0.019383341697976 0.804096145888325 0.774184897614177 0.480547719676979 0.365081345096696 0.653925608182326 0.297919637535233 0.18821265520528 0.225456485475879 0.53117968581384 0.718224065268878 0.407879962217994 0.026476832840126 0.456702032531612 0.595806001818273 0.0144142677402124 0.263236004330684 0.709714740950149 0.653202711362392 0.0856900478620082 0.740496598856989 0.283994004793931 0.972587096255738 0.936841614618897 0.902599088205025 0.867095108707435 0.701593028670177 0.890076975666452 0.656794192020316 0.790335688125342 0.0844675621204078 0.366167019172572 0.858774097883143 0.0504437939496711 0.19017693642294 0.872777521705721 0.546896440654527 0.157274650174659 0.951260538958013 0.980642668886576 0.335397007933352 0.783307323344052 0.427385049478617 0.728188927252777 0.943715706260409 0.956912259648088 0.161147499503568 0.10176917404402 0.316801512399688 0.373323165690526 0.972516633304767 0.333772465032525 0.417356351485942 0.131761185266078 0.765860831711907 0.187590109882876 0.342524894864764 0.365719214214478 0.0511766420165077 0.486960526353214 0.833912138610613 0.8986789478641 0.958459080848843 0.136668481600937 0.19733565258095 0.945578261725605 0.312755187703297 0.375924873000477 0.013763309547212 0.128075337412301 0.892137531256303 0.37650027183583 0.0575291029503569 0.62924066294916 0.0208401734032668 0.0452491861325689 0.265407805650029 0.0158387210126966 0.779633497339673 0.690278315956239 0.317998952909838 0.619809297241736 0.4907352045062 0.815392962861806 0.21277954082936 0.522674937888514 0.588404246992432 0.0469857342680916 0.908175867053215 0.818235385376029 0.731602350617759 0.0274405670305714 0.843420451069251 0.614734260207042 0.793434389131144 0.995378031213768 0.818774711517617 0.229778191084042 0.814473946124781 0.954640172293875 0.359320287005976 0.229924987419508 0.205007962291129 0.185983215624001 0.915141957018059 0.307354921551887 0.394356569193769 0.10043109875638 0.0423932727775536 0.88940550968051 0.44245449290378 0.835147753534839 0.92313052192796 0.330844997528475 0.220807239504065 0.600083043449558 0.755167555834632 0.464427394429222 0.920837349141948 0.409711179046426 0.0233012788975611 0.743553642327897 0.109296936660539 0.18425386515446 0.209380295202136 0.937136432409752 0.622787933729123 0.970642109005712 0.822680565554183 0.0675261891609989 0.317278496418148 0.643824105104432 0.569063291226048 0.405709275838453 0.151772532877512 0.747678391295485 0.0513597429310903 0.0406443305313587 0.934239387987182 0.260994125460275 0.894686169782653 0.294174451003782 0.221844532061368 0.253187942528166 0.395020497983787 0.646698823531624 0.758796775257215 0.874701433896553 0.220531534275506 0.0830174089898355 0.282863201356959 0.2911975211557 0.568292002284434 0.82808665212011 0.213615393475629 0.309951806752942 0.470764778205194 0.0147208049613982 0.846287997416221 0.0496601062873378 0.4364932744205 0.805669243433513 0.0874201108142734 0.237661932059564 0.207770967299584 0.318206101672258 0.363599428974558 0.999139698662329 0.524376388816163 0.496674297531135 0.482501485378016 0.0193136041378602 0.407078755686525 0.0646387539198622 0.340384035487659 0.415483557798434 0.303950494462624 0.733037251178175 0.462313939244486 0.562112253985833 0.662131220547017 0.57256405077409 0.114041916476563 0.703435537577607 0.487207080873195 0.303664040449075 0.557161154369824 0.229745827172883 0.385345706595108 0.805064138839953 0.208028428498656 0.4371152967331 0.990131333786994 0.97404473771574 0.420880282742437 0.0659988168254495 0.263203976722434 0.466719376670662 0.63883304053219 0.297724585996475 0.621274811509065 0.176332128634676 0.179257001834922 0.678838454303332 0.664483568354044 0.114249781179242 0.102775421624538 0.198315074529964 0.815013087172992 0.275852985868696 0.9992114337557 0.861310125857126 0.871938410678413 0.173315402558073 0.373752477676608 0.0671703080739826 0.810751351357903 0.811560235230718 0.830674517995212 0.120619977423921 0.789851629990153 0.443512654220685 0.214306829031557 0.333583737555891 0.684892772219609 0.114850957551971 0.823777957677375 0.927958055234049 0.316557583992835 0.545347403173801 0.472459429544397 0.457976218103431 0.484345397583675 0.577203286490403 0.191537040818948 0.882718832343817 0.686329939309508 0.138888851606753 0.61223467142554 0.593780671134591 0.582429519689176 0.195858128219843 0.357096067150123 0.19553088843124 0.372497121610213 0.967538439061027 0.649136590894777 0.0755818574503064 0.900119339912199 0.299489071015269 0.290457835698035 0.35428010399919 0.560870054070838 0.323628392782994 0.301725685442798 0.227236831129994 0.642250285856426 0.451306445116643 0.656513407442253 0.697011042588856 0.0117382872756571 0.548545597055927 0.602722492290195 0.927715466045774 0.730010094179306 0.876507345256396 0.0597563654370606 0.594864290051628 0.702164916263428 0.580194337142166 0.620257392632775 0.956679103767965 0.16477470894577 0.664640421045478 0.0482325172610581 0.521365703514311 0.649525221984368 0.690525032519363 0.102139492875431 0.185118561249692 0.439263988579623 0.813083618953824 0.256279733073898 0.908169087748975 0.976168255941011 0.633880317257717 0.409344617403112 0.734524826363195 0.330025693567004 0.0912418333417736 0.421732060564682 0.820944527520333 0.81912170443451 0.721181606643368 0.0518062713672407 0.361497509970795 0.574834057153203 0.351285253977403 0.205441314291675 0.299444088945165 0.301762067931704 0.227999053953681 0.0219485740875825 0.905002280217595 0.0419429209991358 0.841136700527277 0.862230028875638 0.247084829111118 0.511762595355976 0.606254162893165 0.366860035513528 0.828757612153422 0.145798490166198 0.993209553738125 0.834801425617188 0.980094749617856 0.990292886421084 0.637890754123218 0.660005827185232 0.520493980094325 0.0139830441982485 0.523292711351533 0.917095205702353 0.811406231548171 0.417375816255808 0.720632844197098 0.466761528863572 0.233203163538128 0.846045317410026 0.584143128462601 0.196634356596041 0.559649508006405 0.86718355291523 0.822540188017301 0.288216135697439 0.237228650592733 0.90052340451628 0.189129506833851 0.572074611792341 0.248893801772501 0.709718359145336 0.931582214899827 0.610486401093658 0.329626735742204 0.910571558519732 0.0862883134512231 0.761944227968343 0.647290035518818 0.78270941111492 0.113635926716961 0.767309940436389 0.168952293428592 0.204496045412961 0.468955783185083 0.127891613219399 0.260090322569013 0.49117817559978 0.207291612334084 0.859134350216482 0.527322129162494 0.31061457865173 0.691093375447672 0.410639274579007 0.689651690972969 0.295362123746891 0.293125577317551 0.505489065337461 0.454362865078729 0.691420097297523 0.348927180031315 0.18262458312558 0.516982168189716 0.266127186848316 0.309360500029288 0.127965604469646 0.560697473282926 0.515208685512189 0.716013267103117 0.322837047372013 0.445339328539558 0.939594102497213 0.787849453727249 0.401265406988095 0.584826575268526 0.892325052283704 0.0743430998572148 0.425682544233277 0.260243493446615 0.303914497373626 0.581868980878498 0.898927858117968 0.643698620323557 0.642502492985222 0.361403447038028 0.462185055245645 0.815367106262129 0.384629871444777 0.285285748189781 0.216190757825971 0.793099332086276 0.771581302029081 0.451416703143623 0.282492429357953 0.644328305225354 0.967275753065478 0.55632637816947 0.0256462591583841 0.216224974975921 0.0876763842348009 0.670723326783627 0.095441304713022 0.0950205289199948 0.769684651349671 0.903509890299756 0.252485347201582 0.271440812703222 0.0626248453184962 0.837901623044163 0.291176094349939 0.0365428828145377 0.777247028271668 0.384735503981356 0.369442492651287 0.512649035428185 0.833935213969089 0.560565280653536 0.124834223764483 0.434540783397388 0.203638237880077 0.301273458988871 0.516621312862262 0.018596957619302 0.811036864691414 0.403109975203406 0.30719841968501 0.495550909815356 0.546982863356825 0.55658526733052 0.599829711008351 0.917036659722216 0.252862954286393 0.953717209126335 0.0576268624491058 0.190934938287828 0.858328428529203 0.19745061585214 0.771959036120679 0.841658466770314 0.555174879310653 0.812503828818444 0.690601814230904 0.0380593254207633 0.107486686324701 0.506486159209162 0.187670355583541 0.279652840869967 0.872206452626269 0.833366211343091 0.261220392317045 0.419004029906355 0.323584347474389 0.539842072443571 0.232762658358552 0.04899303736398 0.492095381740946 0.713081420054659 0.657624361400958 0.956042725078296 0.0736447314824909 0.109308182178065 0.801423992454074 0.549608344677836 0.549733069492504 0.64556723385118 0.444212506338954 0.319847270476166 0.87987901704153 0.732285632845014 0.770340290814638 0.212616154549178 0.0598562568519264 0.218786159513984 0.0614750643935986 0.536763475390617 0.997961925764102 0.373080541004892 0.913722860850394 0.633543294258416 0.32350442885654 0.324848349683452 0.669534057811834 0.745285618910566 0.328098143127281 0.764699714451563 0.544662095292006 0.43519264515955 0.24948325387435 0.305197611453477 0.413666053093038 0.968377836372238 0.703820643594954 0.678274081777781 0.980308170118369 0.0305203986540437 0.48868185050087 0.757017456491012 0.684721009714995 0.199468770998064 0.036261161013972 0.640520699121989 0.949793759463355 0.0311861763033085 0.754470569551922 0.621497084912844 0.560503256623633 0.303470827166457 0.929658473741729 0.870683659450151 0.0772153735766187 0.468219644466881 0.945220747990534 0.247936668246984 0.264467520462349 0.973594238415826 0.670618710992858 0.810529572842643 0.59535375692416 0.456790093875024 0.880840412785765 0.361277768404689 0.976804602360353 0.772913453637157 0.0499037018488161 0.492092136268038 0.556948469402268 0.239050109565724 0.505334039377049 0.700276412228122 0.433877127061132 0.204932037587278 0.697811993954238 0.793144352419768 0.748570273527876 0.15191306485096 0.231962848210242 0.751152595591266 0.435233750871848 0.380119368287269 0.43292323278496 0.697379548058379 0.399185979710892 0.0744283645157702 0.4756140891416 0.761741044076625 0.0282848154939711 0.712160488765221 0.707282577559818 0.721908584737685 0.198647236695979 0.401466773599386 0.404848571352195 0.0317115054209717 0.361327648649458 0.530947645334527 0.398234077205416 0.552517555935774 0.0407859341101721 0.850946084766183 0.577154937933665 0.126104682574514 0.310169530271087 0.256652678479441 0.542832959208172 0.267197846923955 0.327349203461781 0.473402130396571 0.52160554949427 0.607931622676551 0.99019595972728 0.74638981707627 0.295833440634888 0.54716241015587 0.787220624911133 0.697765528832097 0.085793417787645 0.587374608034734 0.436577051186468 0.768982368584257 0.712254165837076 0.52015229887329 0.027575554039795 0.885497557381168 0.854133954218123 0.983934262315743 0.381795582436025 0.900400975965895 0.266013510241173 0.873074969528243 0.0412278937594965 0.337575972573832 0.169076819780748 0.959079664365854 0.961362864468247 0.971790365388151 0.280356593779288 0.40532405779697 0.54205676010577 0.780483598948922 0.406883874488994 0.29684291570913 0.968562790064607 0.658339762745891 0.341318664147984 0.79524408003781 0.953274174875114 0.963214944524225 0.0295006620767526 0.925446584287565 0.816362397836056 0.219658234450035 0.160266429213807 0.999934395807795 0.262368223653175 0.513367044676561 0.874516875515692 0.305158934544306 0.460951893788297 0.0560168227553368 0.992246003949549 0.198337247702293 0.0124928085552528 0.597443762645125 0.737581870295107 0.985560141208116 0.49436570183374 0.600614182839636 0.34835404449841 0.132498810032848 0.047427195571363 0.692383022655267 0.316391527573578 0.512796485007275 0.811717790954281 0.217729536569677 0.177794091782998 0.506408307044767 0.121314487650525 0.474427150317933 0.102524921365548 0.474200643969234 0.405696405048948 0.0265000169957057 0.656932458847295 0.893906513606198 0.330377950696275 0.73358233549865 0.377701481289696 0.154855900406837 0.462779938674066 0.581485373126343 0.0669955460424535 0.069265668594744 0.125979096603114 0.735390331982635 0.180827897391282 0.893888433463871 0.748772467873059 0.937436054791324 0.448730413001031 0.0310537165217102 0.163037865075748 0.407406146454159 0.534227198935114 0.164725180217065 0.959230797372293 0.704753297772258 0.254741930507589 0.0972521225456148 0.527757317344658 0.324129586231429 0.18097965851659 0.475680290334858 0.746452110332902 0.557344648060389 0.957338324086741 0.167910635157023 0.69256802406162 0.0906769977370277 0.0260897258319892 0.835374401181471 0.425214889566414 0.61218246956123 0.312234329639468 0.834573467564769 0.750536343443673 0.145176685908809 0.743364867137279 0.338262551215012 0.0300053054536693 0.496255659186281 0.0586249375692569 0.944268715020735 0.241844443529844 0.561252935049124 0.545386461103335 0.904727534109261 0.509876717894804 0.537933198455721 0.831970765637234 0.264299630627502 0.814498135731555 0.52328144347528 0.478411608878523 0.0852016233210452 0.27000559105305 0.635739839312155 0.164668065195438 0.759709358674008 0.693948685347568 0.272578707083594 0.711434845970944 0.712165432348847 0.340739550306462 0.535896739580203 0.868797702926677 0.746521901830565 0.443597180349752 0.0915040703187697 0.158004177394323 0.931196767969523 0.932559660752304 0.42682413702365 0.816726717152633 0.170639840224758 0.47430446844548 0.420948144013528 0.181128637709189 0.313349452693947 0.570671070152894 0.073701294681523 0.141248123473488 0.127642757364083 0.281767805153504 0.290433570255991 0.5836423229496 0.301074852182064 0.727759366324171 0.137148115243763 0.146656230853405 0.0737643868592568 0.254506609749515 0.549063800424337 0.181395874512382 0.788656075680628 0.479400981843937 0.969147648946382 0.059089488061145 0.796327583242673 0.583631528294645 0.803838028910104 0.424452125984244 0.757944282877725 0.886679347935133 0.0905889008962549 0.933922291914932 0.887604212055448 0.17018407901749 0.0894891071692109 0.608833296878729 0.633084320540074 0.235167154553346 0.945891813824419 0.571631914074533 0.630452848232817 0.689748431420885 0.010122650063131 0.602380735694896 0.580576218431816 0.0800968777621165 0.9053629433061 0.0649331727111712 0.135286862116773 0.459645722559653 0.702811285154894 0.527940306696109 0.353649741881527 0.0309792236983776 0.121369833105709 0.0384266968187876 0.0756155813252553 0.942002456609625 0.997917137315962 0.0280925106210634 0.0288288671639748 0.0578955537220463 0.716764675679151 0.504763824078254 0.634685173332691 0.0551867269049399 0.16967357511865 0.289571617138572 0.816530753055122 0.256082644816488 0.414533484559506 0.441816424862482 0.0591588111780584 0.654787454116158 0.683783630931284 0.923130596380215 0.303039843116421 0.912652439805679 0.812112419714686 0.889057479733601 0.449940685806796 0.288527168175206 0.0723899963893928 0.0525258671632037 0.995611509797163 0.260051681157202 0.69081681689946 0.10414480097359 0.450220943456516 0.509190703753848 0.95075838316232 0.482187040543649 0.627678712035995 0.536709373034537 0.310212135401089 0.229903996954672 0.630963689356577 0.398957608367782 0.728885025870986 0.258682130775414 0.456588598873932 0.839536730558611 0.734628812191077 0.56614945954876 0.115958248137031 0.872600724569056 0.870711328259204 0.862272879721131 0.706982998512685 0.0386152532626875 0.870075588061009 0.214236240456812 0.440360987465829 0.381300428148825 0.716505267196335 0.795397559097037 0.869400170342997 0.410921951120254 0.700644231953192 0.561356867630966 0.727650899300352 0.898737927419133 0.762038902884815 0.81796340322122 0.0372515998221934 0.234266764479689 0.68050676798448 0.55312541272724 0.666316014220938 0.985665166601539 0.292889697360806 0.753870542694349 0.352879970336799 0.731632504472509 0.282261039586738 0.0414961436204612 0.21889147810638 0.595563168297522 0.877545952368528 0.79470081968233 0.0547962833754718 0.637799570395146 0.12070477001369 0.249917368376628 0.575841828815173 0.396860595145263 0.612254805343691 0.981101585901342 0.410789889185689 0.916583092436194 0.211990147542674 0.77282160675386 0.418904038222972 0.193252596645616 0.910005847697612 0.0993618242302909 0.334758630327415 0.409181653633714 0.215234386341181 0.218940312792547 0.135114805030171 0.715884405924007 0.0688925157370977 0.637860248982906 0.910352479878347 0.906346691553481 0.34636003954336 0.489074905160815 0.815613137541804 0.171059702767525 0.743091336237267 0.82255445565097 0.266132914370392 0.196092016636394 0.26982236912474 0.285819237781689 0.604244189197198 0.615366464960389 0.362275033539627 0.286088602812961 0.731268427183386 0.836863003945909 0.531131846436765 0.618542445101775 0.0163228383869864 0.225947718226817 0.723607986269053 0.432251807828434 0.370096075574402 0.865881805948447 0.054454378336668 0.773600490055978 0.591047441035043 0.74129611119628 0.544468594803475 0.31432711222209 0.548934386961628 0.741234731650911 0.451645099611487 0.363191400421783 0.232640187856741 0.0218332240334712 0.628546616032254 0.0734681715327315 0.997940250707325 0.656424776297063 0.75751405533636 0.38093588616699 0.0692080245702527 0.0499941507354379 0.454861323386431 0.42790015835315 0.865236222378444 0.339122956739739 0.379272581532132 0.994302404504269 0.554115684421267 0.79896976584103 0.657028672366869 0.398862952352501 0.467333774657454 0.366529692241456 0.779801720711403 0.240366749519017 0.143015440674499 0.709681444426533 0.922912744702771 0.509358136272058 0.580168441126589 0.0511795442714356 0.543828849857673 0.366908271585125 0.0869069775752723 0.521503348676488 0.867102505988441 0.246682142450009 0.915025802280288 0.69237592802383 0.337423172804993 0.230761384281795 0.16602238882333 0.568524558627978 0.172179353118408 0.521022788875271 0.895614340228494 0.657706059957854 0.151339755749796 0.92804353449028 0.301175270755775 0.0390193743398413 0.28761380842654 0.783533244447317 0.290970696252771 0.858418141652364 0.633758231233805 0.168083528275602 0.041867088265717 0.847348108091392 0.0295693231909536 0.959777772964444 0.508643072152045 0.0617780627124012 0.84526363650104 0.32578512662556 0.55418274999829 0.450369365063962 0.316152547360398 0.593998219931964 0.40908524971921 0.54988148026634 0.142585479363333 0.0463556008087471 0.955190762393177 0.886736084702425 0.266656097050291 0.560709643114824 0.141920218961313 0.790415884268004 0.477897128583863 0.418871528403834 0.759676930452697 0.725624000278767 0.474855578327551 0.831814466612414 0.875900754383765 0.602900919769891 0.654337535682134 0.755938142435625 0.892697265844327 0.894458036087453 0.0553980581322685 0.451741970062722 0.312850135995541 0.833469166825525 0.641986956067849 0.176222474062815 0.450321572248358 0.378430606743786 0.364416495449841 0.731858823883813 0.0520689536747523 0.178799088427331 0.441189821315929 0.618803943779785 0.453220536294393 0.554359619512688 0.591367901980411 0.0385359226563014 0.758643983555958 0.468537889362779 0.461489224932156 0.410109131650534 0.447699715807103 0.305114577596541 0.195137884712312 0.435534417890012 0.592717493395321 0.0664996391651221 0.0780762152117677 0.640923961116932 0.652729929632042 0.602183505678549 0.363933170542587 0.0150858450587839 0.977824137709103 0.398611183869652 0.562251096146647 0.718499111721758 0.812304240302183 0.615578351928852 0.380532373155002 0.731738515724428 0.932624612392392 0.810320394507144 0.384112380098086 0.0860790413012728 0.93862087322399 0.218193610613234 0.815787156203296 0.562271080007777 0.659903833128046 0.540450646788813 0.56754736217903 0.559325198363513 0.294574529069941 0.767022342439741 0.446229625607375 0.118977511583362 0.0544375359918922 0.8313936822908 0.0411204354139045 0.8284179243166 0.563896865085699 0.733913563669194 0.424335708934814 0.480145153799094 0.992072768996004 0.158645886681043 0.955289828840178 0.188737760044169 0.0998485352168791 0.883576555743348 0.469683322091587 0.781306337164715 0.676175819232594 0.22189545302419 0.165203687625472 0.492732253705617 0.222055181923788 0.439362336550839 0.595840438867454 0.654225245085545 0.577064032882918 0.193510506632738 0.0508219072176144 0.35962538612308 0.28316044887295 0.506800496629439 0.951775492012966 0.920857513947412 0.971601241216995 0.689131254267413 0.570104387302417 0.788519224137999 0.814315779570024 0.527039483047556 0.581627481735777 0.153806998829823 0.390632990642916 0.264344000022393 0.465874493173324 0.765203968971036 0.0937989190872759 0.646862942809239 0.3169371392834 0.214731431854889 0.286506844693795 0.317221211516298 0.900143359638751 0.516811590697616 0.604093271940947 0.701415467879269 0.614750475124456 0.143958743598778 0.486016896346118 0.350450800249819 0.701107833927963 0.558777558694128 0.463203990596812 0.543493396579288 0.0970534933800809 0.251186361422297 0.957416985544842 0.646330292476341 0.460200838341843 0.298290791937616 0.446467863372527 0.422618863678072 0.375688166692853 0.263438929137774 0.975389408597257 0.256906606077682 0.159344905072358 0.743255207724869 0.591049684053287 0.304195629088208 0.707640840427484 0.112290071744937 0.338594469048549 0.686681509541813 0.239596973133739 0.39027129282942 0.762553622440901 0.841200013065245 0.978621739414521 0.560729098434094 0.213759638380725 0.124375766140874 0.596414218884893 0.0793200470833108 0.505998807426076 0.294829398961738 0.933719956041314 0.0651825603353791 0.689513566826936 0.273663066835143 0.387564849867485 0.614522015498951 0.549406826396007 0.397735810675658 0.995438865621109 0.621380321648903 0.82082510126289 0.553102714009583 0.935216708907392 0.048136426829733 0.928745445916429 0.518126271150541 0.914877299997024 0.188767834375612 0.211520221736282 0.658251035481226 0.839927475815639 0.543689917570446 0.604293634714559 0.944942747880705 0.443606190686114 0.123866819746327 0.52510840062052 0.721377041738015 0.928916285950691 0.457316102283075 0.590340112573467 0.0865253456891514 0.462652094701771 0.748389054203872 0.0750249988399446 0.0637338563730009 0.539172000074759 0.587158146747388 0.718493640057277 0.279784492279869 0.102920111860149 0.794871373893693 0.097867457063403 0.3860767060332 0.479529865612276 0.565200906472746 0.351091143349186 0.541751361335628 0.507100203144364 0.0596552053373307 0.200623930925503 0.546769065293483 0.388942014202476 0.286448011277244 0.912274639098905 0.714448346167337 0.797457376848906 0.147251706903335 0.181965014978778 0.767348691106308 0.291790727218613 0.116816033772193 0.587106459133793 0.381708299499005 0.431268220702186 0.467717342302203 0.131236978464294 0.241076386230998 0.281457677397411 0.537936138513032 0.809528082369361 0.428618911893573 0.400903253701981 0.462382341965567 0.819585350896232 0.656902144101914 0.126607630837243 0.103832147603389 0.539207430128008 0.0817312287678942 0.891471833360847 0.780263065837789 0.107732943957672 0.378889553262852 0.504045648868196 0.741022887786385 0.755053392867558 0.105654781907797 0.725406296122819 0.034209229669068 0.191903948676772 0.380985547665041 0.243339498746209 0.919646788435057 0.052597418546211 0.0575277552031912 0.325198437324725 0.901221251033712 0.846403825993184 0.895937272619922 0.510720172738656 0.315737360096537 0.523103063940071 0.385215400166344 0.252004056246951 0.406703477827832 0.299717988648918 0.697594515460078 0.757482618966606 0.956648849183694 0.0664965449017473 0.171896516839042 0.350876895806287 0.989979549150448 0.192134057315998 0.013596425394062 0.240450424633455 0.54449312670622 0.940597449436318 0.319630986445118 0.537427135184407 0.835026400277857 0.636446630472783 0.20741706277011 0.112035586561542 0.458790986009408 0.505089821228757 0.466566201413516 0.0193623473145999 0.372323891727719 0.805586685333401 0.665815463182516 0.970640912468079 0.562428279605228 0.259997227054555 0.0885896771377884 0.847898449939676 0.0729579599108547 0.231061590064783 0.709070775967557 0.843002703846432 0.674952159081586 0.307899437223095 0.0433777849096805 0.511848214527126 0.700473784464411 0.420242040902376 0.149504942854401 0.607867728811689 0.923960409404244 0.602556371330284 0.334217776646838 0.123371937451884 0.126755970155355 0.439373537120409 0.343204037039541 0.965569689555559 0.961384788237046 0.415494262096472 0.340498258615844 0.573271097331308 0.216538439944852 0.847821459854022 0.595578231164254 0.0548634289368056 0.663244598929305 0.0321222269325517 0.806688004985917 0.143001993168145 0.813079759192187 0.859628041274846 0.491766811031848 0.0495552159682848 0.114111864485312 0.913698655108456 0.249180395700969 0.696543694490101 0.103946024286561 0.84289484995883 0.6391882305732 0.637200025517959 0.0894608328305185 0.885169233309571 0.199070093233604 0.360998685394879 0.50846110023791 0.34943877812475 0.821621832591481 0.55752528029494 0.412973696910776 0.405219621337019 0.742243273651693 0.20626473525539 0.999081089524552 0.574566828187089 0.920290755722672 0.218808646630496 0.214773780205287 0.440001148884185 0.268350852346048 0.359397368140053 0.911503827527631 0.65771344732726 0.78086861230433 0.871536429354455 0.199396887461189 0.967386264875531 0.520156973691192 0.640837951474823 0.8380564641417 0.845356576195918 0.0593105635442771 0.586268670728896 0.874351451825351 0.677138805212453 0.52418021150399 0.654331430597231 0.267708047942724 0.425628521631006 0.635151004726067 0.369207488833927 0.493802250395529 0.171309217168018 0.984934360093903 0.691381164069753 0.0342968530580401 0.199104983911384 0.656034232268576 0.28141038776841 0.95307306734845 0.33826913021272 0.250277156017255 0.839643946646247 0.94846458041342 0.741090132694226 0.7619704672019 0.399357111791614 0.22943127515493 0.752846720463131 0.491361199526582 0.621707532855216 0.388163802123163 0.661769933488686 0.399704282656312 0.895779426002409 0.804980556848459 0.713841989485081 0.0418745293421671 0.793494700298179 0.0782877619587816 0.538264197967947 0.254306385507807 0.995050777595025 0.453901208313182 0.370512456379365 0.189579782315996 0.652973865184467 0.613997084689327 0.0443334522098303 0.106453626020811 0.592361317495815 0.907848036026116 0.982223894866183 0.8163789412193 0.684762597177178 0.309078401818406 0.175767791375984 0.82735563216731 0.375463963523507 0.5738475355017 0.171802724285517 0.929478133553639 0.0527995117008686 0.278799783068243 0.57905693350127 0.345287099569105 0.873244885709137 0.240320352625567 0.29266639061505 0.295533275650814 0.771158813603688 0.39803386886837 0.822302157704253 0.862463829470798 0.441289807697758 0.744864259716123 0.382646155422553 0.717185682666022 0.978832769144792 0.205247261058539 0.833403000899125 0.486582608090248 0.252957382565364 0.60598321269732 0.221271471902728 0.254254493438639 0.138073319355026 0.854921558345668 0.702339537458029 0.370122907890473 0.73448776250938 0.783700817571953 0.908731647373643 0.81181297643343 0.847062735594809 0.463338350409176 0.879514611286577 0.514657808206975 0.330519402143545 0.0705072454619221 0.359986377677415 0.122179006258957 0.706161924984772 0.0574673204869032 0.515618585282937 0.879923749938607 0.483527596958447 0.226828691475093 0.386841112405527 0.776994512500241 0.254153191579971 0.231965985347051 0.191959238350391 0.473989014010876 0.979471581939142 0.412098335241899 0.0842158277519047 0.979090416820254 0.438025421611965 0.304027359385509 0.477865414689295 0.468867561412044 0.757792272579391 0.331303414814174 0.630717274060007 0.710943523554597 0.691778645757586 0.455669186133891 0.267488053515553 0.844040860326495 0.426057986670639 0.598283015200868 0.974089123706799 0.158473199170548 0.755715042219963 0.136832986278459 0.304875772334635 0.562055171004031 0.994921721180435 0.264092479790561 0.313938379480969 0.898100991835818 0.222034552886616 0.973849132971372 0.0146867242688313 0.614194241866935 0.0373383023543283 0.333640129491687 0.37256793722976 0.507857897980139 0.985783126403112 0.570510009180289 0.396132441489026 0.0807782837003469 0.738156356341206 0.0912548859976232 0.750786397911143 0.352995584316086 0.689472418702208 0.524400512038264 0.089572199343238 0.341324432007968 0.139631502707489 0.662357281334698 0.372836244024802 0.199382090594154 0.209545233224053 0.223208468097728 0.874598654978909 0.11998128679581 0.0843624046491459 0.722234787957277 0.398523979303427 0.947348706612829 0.0827598175569437 0.761754769338295 0.231269188537262 0.0469943220936693 0.86770526614273 0.881316483784467 0.337818046589382 0.0502111260429956 0.410187672786415 0.806865970769431 0.100319605236873 0.196561672985554 0.803911391349975 0.631768364487216 0.316933435110841 0.168469182888512 0.967160813997034 0.976813408010639 0.490744314880576 0.474359755122568 0.717847130328882 0.156162705747411 0.167245831380133 0.30289012700785 0.467106092746835 0.509890756178647 0.954413250579964 0.890700182300061 0.790698524850886 0.0970648506912403 0.185675259891432 0.0972587637789547 0.653085267194547 0.213868153349031 0.347458811914548 0.475111235845834 0.678741062916815 0.735829722683411 0.376040133389179 0.403339086920023 0.791431819861755 0.553683787581977 0.757923960639164 0.199719024850056 0.945460974760354 0.399833278218284 0.282560686862562 0.417345667472109 0.40754065978108 0.0704896152601577 0.214963452972006 0.490890434922185 0.59219824654283 0.224197041911539 0.877490355204791 0.757597153503448 0.761181795387529 0.775128339300863 0.450527815136593 0.228631880141329 0.247590242135338 0.877391466705594 0.476360811605118 0.307303288336843 0.195517181609757 0.0524968720437027 0.0950316983717494 0.993299183880445 0.0688566389703192 0.269782614156138 0.0630542870773934 0.939776675561443 0.749016694319435 0.534858914562501 0.904798705163412 0.433912922230083 0.337342980811372 0.68069203446852 0.911634758156724 0.87067431880394 0.286169375902973 0.7481894942699 0.0663333494774997 0.351464254946914 0.250054790873546 0.136465803661849 0.912021479073446 0.404185627268162 0.846270250349771 0.187257217946462 0.864158137361519 0.232653247197159 0.942765979235992 0.707697593560442 0.972210140801035 0.511905968040228 0.858761741574854 0.859088802724145 0.745520562566817 0.27348667123355 0.706688869001809 0.965987525521778 0.391024414268322 0.282947102133185 0.131405458846129 0.34677944868803 0.0428402068978176 0.685450536473654 0.883605841295794 0.759871923443861 0.503241722409148 0.433335720174946 0.470934013021179 0.52122493642848 0.500099806594662 0.698295012062881 0.674507211199962 0.682023420347832 0.967839254983701 0.0162922364356928 0.659760620181914 0.825738037298434 0.936064172417391 0.551956344519276 0.547863006105181 0.897242562868632 0.706731664065737 0.863594272171613 0.751152753946371 0.140516665335745 0.52945179004455 0.842092518345453 0.866863566574175 0.64939238256542 0.136500825495459 0.743551364042796 0.850022952179424 0.268788251276128 0.805290260710753 0.188516588902567 0.434391013351269 0.765510661320295 0.848720921464264 0.706383074228652 0.058374029090628 0.0417401766753756 0.876273070517927 0.854602483410854 0.912296605510637 0.80958674982423 0.779574009526987 0.709721990248654 0.567418138189241 0.0798388543678448 0.0250551543547772 0.246076034479775 0.101462856722064 0.945020001200028 0.1479555036081 0.443643627031706 0.103220017529093 0.110000810583588 0.134884672418702 0.573929661870934 0.366717351339757 0.593423356323037 0.54230291700922 0.799493219130673 0.705710952694062 0.416131129220594 0.308962643314153 0.667283524500672 0.843936333509628 0.461284585187677 0.436518679696601 0.303565837694332 0.226674313456751 0.222140327643137 0.913041369395796 0.140593727338128 0.436744447515812 0.799244578334037 0.937426461053547 0.343712041601539 0.890918355758768 0.0764733637333848 0.998251573618036 0.666510384855792 0.4003675674228 0.226312922441866 0.0247730158059858 0.273996484547388 0.167715775396209 0.158299020540435 0.28818561211694 0.412599628497846 0.60908777376404 0.669588086637668 0.805997733005788 0.821863327354658 0.316303380713798 0.243863363021519 0.5730080701923 0.289576444779523 0.409962364588864 0.212344858599827 0.611226181518286 0.594684700609651 0.804682407837827 0.372537035164423 0.525174140578602 0.881881722998805 0.211445708628744 0.388803331088275 0.587014524198603 0.524616195610724 0.661582406468224 0.213712115022354 0.555034670501482 0.418469083770178 0.387788987574168 0.761020759539679 0.177928849211894 0.0719216820248403 0.236088490143884 0.325630344075616 0.938840363773052 0.948634192792233 0.134899080428295 0.789552263696678 0.990478455324192 0.079404373827856 0.330191958590876 0.813905531740747 0.296417481233366 0.276577991324011 0.338267810125835 0.742682916983031 0.767592331615742 0.664029266457073 0.808337049363181 0.675594611738343 0.510289955108892 0.704664968815632 0.603861718052067 0.276690131172072 0.668552733527031 0.600700368585531 0.413638807025272 0.160734599514399 0.317797532822005 0.577861449494958 0.151815655254759 0.575659265432041 0.896325198833365 0.0278979205479845 0.220916852355003 0.557774425891694 0.261179224138614 0.767533970267978 0.402286371220835 0.587860382029321 0.773647115838248 0.820156359123066 0.483764310642146 0.872807191736065 0.784667578949593 0.890608977826778 0.563877653637901 0.606312827351503 0.477080970057286 0.492703989278525 0.149972969091032 0.155509900539182 0.531567988207098 0.78208810382057 0.342890728120692 0.0796809706394561 0.934744845267851 0.837371861366555 0.982943513251375 0.829505906873383 0.820574978105724 0.0467839380004443 0.0652655227365904 0.546790367166977 0.605710853440687 0.105443849680014 0.202211315697059 0.224022089254577 0.85778707327554 0.198747188502457 0.94046012467239 0.900113104593474 0.708440036517568 0.537145413153339 0.678414590931497 0.942393667942379 0.29342483850196 0.418144401866011 0.73634109234903 0.847156456923112 0.145317916765343 0.712382270277012 0.248631303175353 0.0785666647157632 0.606251525715925 0.421495368778706 0.580128310208675 0.030483249053359 0.0297601800481789 0.938128935596906 0.246619872243609 0.80525869917823 0.256966507642064 0.492017405566294 0.127117236007471 0.425681589031592 0.713423785867635 0.981384292868897 0.216353472652845 0.237531322520226 0.250632562730461 0.531774170473218 0.968172184261493 0.608490110707935 0.329812475447543 0.376102147737984 0.597259722203016 0.594590405330528 0.687153677905444 0.743780892968643 0.688266543650534 0.85440662557492 0.667942805672064 0.652922856630757 0.625083616685588 0.965834966166876 0.834107883730903 0.171455558952875 0.57499930197373 0.591480547089595 0.749677955505904 0.799342509096023 0.464826548872516 0.233187465867959 0.651195570540149 0.170107835067902 0.657271765663754 0.406904263342731 0.428398018968292 0.645879948535003 0.555492432699539 0.474860777307767 0.875566169177182 0.108064678772353 0.477043180582114 0.526499897129834 0.624177011577412 0.563218623483554 0.663623700360768 0.661317463854794 0.802323768239003 0.478583182832226 0.57026836827863 0.640753145054914 0.11838712917408 0.923143060102593 0.0170479466463439 0.0464409924740903 0.975254498345312 0.830109117429238 0.951322424686514 0.648997854534537 0.293668258420657 0.338999462577049 0.968911854045 0.687120707542636 0.236202500979416 0.202708757950459 0.96178572077537 0.791028034626506 0.916071197686251 0.274437506513204 0.58860417642165 0.221690841400996 0.619224811773747 0.355965079541784 0.158508058269508 0.939772914685309 0.203810286438093 0.240759894305374 0.655422131929081 0.179907504094299 0.431771168273408 0.135679560650606 0.0681502014002763 0.861658487496898 0.313709307641257 0.180560077186674 0.876417632133234 0.356970095087308 0.307165901567787 0.756464153840207 0.269639453764539 0.433640354368836 0.0931768285459839 0.56685120040318 0.809928834654856 0.227301326836459 0.248797346225474 0.374746559343766 0.425623616310768 0.239285670507234 0.324110670057125 0.190058242010418 0.270079269050621 0.547045402098447 0.753646632032469 0.0690744768176228 0.460513442384545 0.808153533544391 0.745072077396326 0.743456537225284 0.206076343851164 0.190131999531295 0.626909834609833 0.978517297883518 0.859404045096599 0.665029813945293 0.720725705521181 0.0824110548431054 0.689321539017838 0.935913469297811 0.321409128035884 0.618327853418887 0.0244631747948006 0.895008557958063 0.328309012888931 0.705385501834098 0.216208988947328 0.258331721122377 0.658075416672509 0.894223414442968 0.171736248333473 0.580747708252165 0.225074069190305 0.783380279869307 0.588637701834086 0.306380360666662 0.254166056145914 0.715776635478251 0.643480007757898 0.80380345240701 0.134034550525248 0.156578838992864 0.779507952858694 0.742977567659691 0.461025151119102 0.939142757945228 0.237265382984187 0.485127919595689 0.793187345715705 0.949628063088749 0.629508471167646 0.39996310059214 0.113382080947049 0.293526881195139 0.927022793614306 0.907819338946138 0.663647265075706 0.491096210121177 0.938741105317604 0.0547568024741486 0.787562683694996 0.88408529053675 0.411488230130635 0.987469101173338 0.894630788138602 0.0529131352924742 0.221204424996395 0.612541019173805 0.0825741041288711 0.840822063914966 0.354972204093356 0.12325605655089 0.196913305683993 0.0609448163560592 0.547884246665053 0.541017744773999 0.928933860140387 0.302502100064885 0.333851466020569 0.470367387565784 0.444971820453648 0.948126845622901 0.722346773368772 0.994222974090371 0.0134717399952933 0.455523671852425 0.414075620709918 0.433359207671601 0.415554865309969 0.254714268613607 0.0527639329736121 0.877739851626102 0.98659987870371 0.255376070558559 0.613054182147607 0.944811388517264 0.738366325530224 0.127442720059771 0.0870877974387258 0.710785398490261 0.429608351013158 0.484794829427265 0.772650987540837 0.396306732143275 0.238861887350213 0.969323589305859 0.984353780027013 0.543725804018322 0.0359384681144729 0.0783392866072245 0.642949071901385 0.961994439028203 0.113698127081152 0.531914890536573 0.561179444219451 0.882727089398541 0.953137117263395 0.36908237170428 0.840141900845338 0.421221060855314 0.183291110137943 0.530496643309016 0.431361450599506 0.017835302061867 0.250380480303429 0.856080130399205 0.811201471020468 0.880075735803694 0.408059846241958 0.591615635289345 0.606487982159015 0.0944923588610254 0.361329500735737 0.0188816533610225 0.507770188383292 0.849200692486484 0.403079262610991 0.0920530648808926 0.838663303265348 0.934495825525373 0.980455720196478 0.9208376895939 0.4238952000672 0.411595786439721 0.269251930930186 0.034120345201809 0.712130302179139 0.651573588149622 0.68462746080244 0.568755753624719 0.309841328826733 0.636858315945137 0.132518272958696 0.913757137239445 0.15245699389372 0.758993628171738 0.848788520423695 0.652863507119473 0.880860679473262 0.664246444606688 0.0611429467145354 0.725642310001422 0.177584188056644 0.119527967991307 0.194882180402055 0.0170778114511631 0.508311033535283 0.538372675594874 0.611912701150868 0.389058807662223 0.215474340196233 0.0331308611342683 0.48017003975343 0.240462652551942 0.691910479725338 0.0654515466513112 0.548586173995864 0.795979370507412 0.281964021651074 0.202450444353744 0.339412668212317 0.236934522464871 0.975427869295236 0.764470286485739 0.573559619181324 0.0318250363506377 0.580250336993486 0.262805798687041 0.8524134716345 0.588073089816608 0.555562083590776 0.587708497354761 0.944762924478855 0.573511794556398 0.196232263939455 0.863689528645482 0.243783966721967 0.380107637331821 0.402149303236511 0.636959342814516 0.392588566017803 0.254447439799551 0.512336911982857 0.0218230708665214 0.025807897078339 0.0273304516845383 0.903523827393074 0.988002037790138 0.205483804862015 0.0439673186093569 0.30096150588477 0.502219039550982 0.393523580769543 0.199431279101409 0.606555417922791 0.75958306275541 0.994033038320486 0.837226442282554 0.0559808729193173 0.867993985994253 0.855311608638149 0.394297375271563 0.559114846310113 0.32136586482171 0.596233020997606 0.543610985041596 0.395453970306553 0.397162838338409 0.302653620545752 0.295252214239445 0.691595945225563 0.367788084023632 0.532208158890717 0.402463419605047 0.960876606879756 0.149786114215385 0.559325632629916 0.999552351783495 0.367077774244826 0.970466661690734 0.991077269508969 0.522660961840302 0.243813128264155 0.376658247765154 0.807549608661793 0.741632342881057 0.0375126139842905 0.308487943573855 0.445928650177084 0.9229951762571 0.472266809344292 0.133690384950023 0.905340142936911 0.1494246344571 0.420444811272901 0.540002329654526 0.412989627157804 0.21606766888639 0.44750819256762 0.873304855271708 0.845721983253025 0.0749804791575298 0.939039784483612 0.175188503505196 0.623265460580587 0.122130061392672 0.822140638493001 0.900353585837875 0.981944474400952 0.473645405329298 0.909145056542475 0.612796642347239 0.923491655471735 0.692911115726456 0.596231048358604 0.0333275766693987 0.330950464103371 0.463075415932108 0.416237001940608 0.314179734098725 0.0630324827088043 0.662552730950993 0.575702476552688 0.165913432904053 0.913039237479679 0.8425850144797 0.589033607807942 0.173526707508136 0.995974528158549 0.637921430987772 0.35416282994207 0.799491229203995 0.707935123452917 0.879775616689585 0.352587970206514 0.49359527427936 0.589306446509436 0.811852473239414 0.0651273771538399 0.24617682623677 0.412604078806471 0.868682870350312 0.105053637805395 0.633484811205417 0.226711239009164 0.191490247922484 0.736839711086359 0.722885557138361 0.247889716995414 0.50665443375241 0.988389516598545 0.384768288789783 0.355293219627347 0.115357680059969 0.931868322698865 0.808195578323212 0.0495383911416866 0.921826486994978 0.41079655416077 0.859876914648339 0.923213283100631 0.924666452815291 0.258903816628736 0.302464127340354 0.470660243320744 0.131283771360759 0.92694401828805 0.115897634550929 0.626994215752929 0.348668879803736 0.537116444311105 0.344450942890253 0.728450485630892 0.0619438747991808 0.317562979406212 0.911196519967634 0.298847523310687 0.549895113557577 0.113312256718054 0.340968402246945 0.458079625831451 0.072546466907952 0.650545442386065 0.949626771814655 0.579017580298241 0.489221546137705 0.325290226582438 0.6839809268713 0.532780017210171 0.90595382360043 0.750139382230118 0.0869806322921067 0.727733828048222 0.837484698023181 0.266261608435307 0.756126140372362 0.102909428307321 0.98092647143174 0.272053845424671 0.574639696890954 0.264410332371481 0.571219263949897 0.907324903365225 0.939943580920808 0.532814629210625 0.337867642163765 0.811979741416872 0.580438391633797 0.867837835182436 0.281347242114134 0.861944264755584 0.134213486032095 0.766074442146346 0.364999841083772 0.717919278943446 0.399097920903005 0.909193048281595 0.493586328022648 0.701667996328324 0.0888659390294924 0.0786256147664972 0.715705595349427 0.971062035167124 0.366734201752115 0.468951927111484 0.0113668173155747 0.397156036675442 0.217466208164115 0.99112722097896 0.153282904052176 0.0183291630004533 0.911844377904199 0.536137967421673 0.209087217242923 0.566506836365443 0.016445620758459 0.724938855362125 0.14015483060386 0.164293181034736 0.850583047503605 0.764579694881104 0.949432182433084 0.0477921662875451 0.762473764675669 0.42632230992429 0.440233499850146 0.372151399683207 0.533205926981755 0.734790000631474 0.578213164482731 0.495038192863576 0.40105655250838 0.487716948355082 0.689661076797638 0.229584112034645 0.86633095496567 0.7176272234926 0.135950505544897 0.613987884188537 0.0903591387020424 0.262838920720387 0.0508903742488474 0.0568590266630054 0.114170337626711 0.421098451591097 0.737257560882717 0.160342921644915 0.354667137477081 0.595291258520447 0.428713248663116 0.172581957029179 0.0315126683423296 0.0996856041788124 0.997307114724535 0.473679979988374 0.215131851064507 0.355011986030731 0.584739867434837 0.664710234440863 0.37683269101195 0.271965756190475 0.27838725441834 0.400359882474877 0.905362018991727 0.224845068806317 0.827818531570956 0.900036523418967 0.123970389978494 0.494863920188509 0.809785562930629 0.69351154596312 0.427581676500849 0.0157172677177005 0.691535646275152 0.265072086371947 0.70516577594215 0.726152720777318 0.0413528015930206 0.595075916091446 0.242210602255072 0.54975532426266 0.240724297368433 0.153379615917802 0.524187331490684 0.750078263613395 0.021401918202173 0.0689562275051139 0.60274510987103 0.582313399526756 0.853049016827717 0.478412825930864 0.345965552541893 0.910451675176155 0.0895810296572745 0.57128008083906 0.595541746793315 0.59206489702221 0.127913838485256 0.461127744482364 0.754779369153548 0.0211739626852795 0.20099498114083 0.841697901110165 0.122445050673559 0.589151286396664 0.689714654760901 0.88175121718552 0.869512240118347 0.95367241330212 0.162582523152232 0.411964513652492 0.199754706381354 0.396159846833907 0.73807273078477 0.712809335787315 0.378309563742951 0.640748843420297 0.239335768576711 0.29667881164467 0.333040787226055 0.652453723982908 0.46360991189722 0.215164708250668 0.052808478011284 0.053045861995779 0.957510429348331 0.22344736763509 0.40015566017013 0.693872471593786 0.635827382716816 0.0316929753380828 0.325278617562726 0.814048309959471 0.147744527354371 0.747937301432248 0.305472899933811 0.840368296783418 0.549516557494644 0.69401768184267 0.323501994060352 0.348490166962147 0.531259823869914 0.370930880587548 0.795818230703007 0.671225315695628 0.817723389666062 0.169627239077818 0.944244079852942 0.961244425682817 0.329236314801965 0.637949103254359 0.268461955164094 0.812253650110215 0.657687527569942 0.594794737123884 0.787887346006464 0.0666523518040776 0.251250187058467 0.574440058586188 0.382636113588233 0.542775030743796 0.696200517078396 0.502845119165722 0.656162611006293 0.926192434991244 0.414812262614723 0.726980758241843 0.829335110404063 0.600709979149979 0.527004189221188 0.959434346840717 0.78794888413744 0.188416529220995 0.660570837280247 0.58179943440482 0.0735102432803251 0.15111731108278 0.837034438676201 0.661371708661318 0.02620723961154 0.0149461889942177 0.831901615166571 0.286188776823692 0.366228855573572 0.700556893926114 0.445702967643738 0.73369407196762 0.893913797480054 0.0924834770546295 0.245855849888176 0.0949774618633091 0.470087980239186 0.55759754992323 0.737169559930917 0.270478386152536 0.14021552094724 0.561351449443027 0.96396148419939 0.138368469299749 0.128279318611603 0.312906968882307 0.891038289121352 0.625172393047251 0.947404865049757 0.968762214232702 0.505266933231615 0.47067864293931 0.568103697779588 0.946149812554941 0.673517164476216 0.171749650430866 0.895404093514662 0.867909384490922 0.0918193479580805 0.554022891556378 0.647609167848714 0.31755367517937 0.928925042503979 0.0922116235201247 0.968460312413517 0.85290695524076 0.230392335057259 0.346754875755869 0.1695621661935 0.759024634885136 0.801737385275774 0.109361354918219 0.21066323202569 0.285534762630705 0.610029916800559 0.949142702384852 0.760096110247541 0.575018353452906 0.809005040065385 0.793384619527496 0.758169071984012 0.544220480935182 0.262360476008616 0.265157135280315 0.989755034341943 0.425312738269568 0.618239908479154 0.194957027968485 0.986122121580411 0.885682373924647 0.857571311332285 0.722855662368238 0.0987504656473175 0.592987523886841 0.294072720871773 0.615975308532361 0.716979882572778 0.0875991477421485 0.714797608840745 0.791610518873204 0.145769404228777 0.184083655774593 0.196790045020171 0.0300322656985372 0.64111733206315 0.69115724326577 0.266785034064669 0.95608012016397 0.616115317496005 0.249381296697538 0.516576775892172 0.378691182951443 0.220148413574789 0.397309951153584 0.628946134438738 0.36784417930292 0.0703957613930106 0.709053515722044 0.784687811753247 0.126140878126025 0.568341164975427 0.166855620888527 0.476340748681687 0.589386510804761 0.943892076506745 0.108578657493927 0.0307248788909055 0.750287441257387 0.381712725604884 0.0871794451680034 0.915472094912548 0.848936726741958 0.770124104055576 0.729926330782473 0.288794861603528 0.109313603132032 0.369669489278458 0.153090459955856 0.268147798457649 0.189089380525984 0.0356610170612112 0.59697712656809 0.684563741427846 0.788851028103381 0.495524597512558 0.104083781472873 0.739887756668031 0.349430834783707 0.361663763008546 0.827411456836853 0.449910161304288 0.0188898829859681 0.528371804535855 0.355089975805022 0.179830992531497 0.631394541559275 0.912469118761364 0.224889044272713 0.850435879598372 0.791861384478398 0.157763318817597 0.630214322800748 0.549408896998502 0.722868568655103 0.913059106320143 0.108436688107904 0.218957292286213 0.792296453490853 0.735612019679975 0.773232623538934 0.16133935213089 0.840000570642296 0.295952525057364 0.452563947851304 0.509043029895984 0.176452200759668 0.899065166516229 0.999674539228436 0.251010804849211 0.772217488018796 0.958097477310803 0.514644569074735 0.225336346735712 0.522330527289305 0.489231042142492 0.373480825370643 0.488084471423645 0.598735795090906 0.540693567439448 0.214250136059709 0.607526752005797 0.570843271303456 0.686511335659307 0.274686906815041 0.428798680205364 0.588137336811051 0.132671888014302 0.680859890419524 0.713488266821951 0.896406801270787 0.577402369054034 0.766854276962113 0.229532028879039 0.340459503105376 0.168285980552901 0.897607191519346 0.80471066650236 0.602848824397661 0.626656935282517 0.571604230282828 0.499687549015507 0.514674181248993 0.714538029555697 0.0315914621087722 0.788315171482973 0.0224828725121915 0.670085259664338 0.934386875368655 0.532399077292066 0.569721691187005 0.251769252736121 0.88324113473529 0.497354244620074 0.0414264085958712 0.355325225107372 0.142727277716622 0.729679748832714 0.935395874225069 0.151996566397138 0.558884618501179 0.913537962248083 0.890279970776755 0.425080107243266 0.939141475891229 0.559039835778531 0.1408991191932 0.478692266219296 0.419177339081652 0.911964222984389 0.575933384113014 0.99849902686663 0.389656223619822 0.911564489288721 0.172859627520666 0.278065447569825 0.593545639887452 0.153023009209428 0.447599220015109 0.130195514275692 0.575629353835247 0.980022170194425 0.804853890973609 0.14850742992945 0.65684974746313 0.0690661038202234 0.377445785508025 0.269520106569398 0.870439101771917 0.137744822176173 0.282442235399503 0.651698254416697 0.391214093258604 0.493942490092013 0.99322591871256 0.254044264473487 0.379899524839129 0.896719410845544 0.622422566318419 0.907592898982111 0.347191237886436 0.316801556195132 0.37587475234177 0.747263007182628 0.404886663246434 0.753425199040212 0.961849512988701 0.812404718806501 0.9717186420504 0.153588408622891 0.204771812877152 0.466196776470169 0.996970732060727 0.629100110230502 0.725450953184627 0.63563168046996 0.958093784893863 0.411094122536015 0.331165920631029 0.635467422199436 0.0635190646140836 0.279869139883667 0.876852556620724 0.563559767864645 0.71937540485058 0.340819618750829 0.467340335214976 0.487420984506607 0.304578601114918 0.843466227911413 0.730107168855611 0.779845241166186 0.784593410212547 0.473919356665574 0.860636301140767 0.353265791833401 0.158891962908674 0.0193239649874158 0.244825529796071 0.678149546436034 0.262535043035168 0.283041044974234 0.0790532867284492 0.177535026748665 0.0951927904621698 0.167121641561389 0.784416194253135 0.108670383363497 0.2398135443707 0.848777004296426 0.434820480926428 0.585904892631806 0.715794546662364 0.401943723042496 0.652947141204495 0.465878402723465 0.532934701566119 0.745532495672815 0.13813942742534 0.798367938760202 0.0649098000046797 0.580612757892814 0.957375235809013 0.831802423556801 0.576753421532922 0.184915882388595 0.184168512444012 0.676010726082604 0.31458255053265 0.210733167817816 0.164241294728126 0.764085281197913 0.53483394816285 0.988668794843834 0.630093223787844 0.933670618860051 0.420506511908025 0.224467359608971 0.52891812273534 0.364187562372535 0.417618321080226 0.209300033827312 0.368139257791918 0.639312285548076 0.252527263360098 0.214491476847325 0.412694649859332 0.574287198656239 0.817400603182614 0.651349705148023 0.107916027815081 0.889436224116944 0.794466558082495 0.284204846434295 0.987197959891055 0.681895963158458 0.0602493216539733 0.846232977430336 0.765512472838163 0.399899421324953 0.974154619793408 0.682763477375265 0.139212033401709 0.945406974516809 0.575383156132884 0.201828271523118 0.148745594164357 0.691821274859831 0.940106302662753 0.924862155062147 0.331589466370642 0.0272624687082134 0.586804612174164 0.947371825075243 0.547252604106907 0.0105445092171431 0.332507164403796 0.275623167201411 0.298279027559329 0.378251944151707 0.0973460697662085 0.15690713240765 0.78847343968926 0.481543929572217 0.87039296350209 0.0102096743765287 0.686281828170177 0.932646682991181 0.613776691723615 0.926303748488426 0.385972705222666 0.161044748476706 0.413788555634674 0.63032638381701 0.136860818283167 0.415841020361986 0.0131720403954387 0.572040415618103 0.272322604004294 0.0641219024476595 0.123972897382919 0.919308318342082 0.635525553505868 0.674096172747668 0.385803775130771 0.199974632579833 0.0624547673249617 0.784566805632785 0.0165103990607895 0.842110522422008 0.474125387030654 0.728596359726507 0.388055155077018 0.485878341391217 0.252130054817535 0.0703147241473198 0.413922940110788 0.496509593238588 0.621182495553512 0.735119104031473 0.809705162101891 0.749794256843161 0.896587284370326 0.889924597255886 0.675988832740113 0.186640307253692 0.53650134974625 0.906744495714083 0.0286761252512224 0.859460652321577 0.863980069926474 0.927525663967244 0.178111881897785 0.657396936730947 0.301033439440653 0.414675867927726 0.392024886843283 0.538393081275281 0.190882946411148 0.867140398728661 0.330039947140031 0.620095833314117 0.763243621736765 0.312003568448126 0.69484096219996 0.233747519471217 0.627660568505526 0.667282108755317 0.0296989869792014 0.962088925624266 0.857367039008532 0.507879442803096 0.555606433162466 0.472386100296862 0.187575284203049 0.936789690279402 0.119168693679385 0.98965011843713 0.0981539117684588 0.833299947222695 0.191217173878103 0.892741091714706 0.887048621438444 0.0158629140770063 0.449156906404532 0.428203714948613 0.233194704332855 0.508868531559128 0.228408979310188 0.0209779753070325 0.909818419793155 0.933731060491409 0.675879047242925 0.836737209369894 0.741347679409664 0.405198377550114 0.207281136924867 0.665307028503157 0.54810411154991 0.985415137258824 0.907447649778333 0.785689516132697 0.472762973231729 0.0153418241278268 0.916932022033725 0.0468527899705805 0.861628184046131 0.197759583489969 0.283478988120332 0.0760762554593384 0.232170524362009 0.824872531678993 0.590327535213437 0.793201789914165 0.581451186863706 0.58793389521772 0.682016218993813 0.651814440272283 0.100391940788832 0.764053357085213 0.384397182101384 0.386696180833969 0.95662666863529 0.242475608487148 0.844513843054883 0.256235645813867 0.772145975129679 0.202736219768412 0.565597133536357 0.252779799185228 0.092135838731192 0.678475781234447 0.913350461965892 0.606715681126807 0.348190304858144 0.989366457650904 0.220592150166631 0.549416502423119 0.638959414130077 0.599317228246946 0.0751522497297265 0.0229462748719379 0.189441902732942 0.06893797010649 0.160887292791158 0.645363334941212 0.147585954193491 0.650984963090159 0.805773719078861 0.593341626878828 0.193738312784117 0.262358963682782 0.898112202777993 0.844618918928318 0.265283371729311 0.928643596384209 0.737251092987135 0.187392158624716 0.193942070626654 0.886922196669038 0.593826474023517 0.618766121112276 0.0718276557419449 0.281427847398445 0.526139075225219 0.027214589684736 0.237248128731735 0.171264022113755 0.377922352317255 0.430085670182016 0.607365267830901 0.634594453605823 0.297840210348368 0.332096929021645 0.479090080983005 0.63564820172498 0.1282004301087 0.58523134336574 0.725160288815387 0.260166652956977 0.960947216660716 0.617694503299426 0.185403899631929 0.734915648146998 0.60314278956037 0.762366245707963 0.579982512870338 0.195470604002476 0.0548948786756955 0.580704037970863 0.0557339751813561 0.460402372528333 0.777066905447282 0.963024834955577 0.259764908819925 0.584526553887408 0.108961652801372 0.707937407731079 0.621183446145151 0.75524387469748 0.916323561556637 0.452475851471536 0.925744798299856 0.727715263620485 0.73154411904281 0.0766788816917688 0.154069002538454 0.868425804001745 0.188660427662544 0.788473225091584 0.420549181809183 0.207531985933892 0.998197346099187 0.650479629358742 0.106346201098058 0.099336505853571 0.629365986147895 0.504338189065456 0.293600802142173 0.630303928970825 0.597199651910923 0.158439560350962 0.235155282530468 0.663235231083818 0.488118806590792 0.770427491923328 0.845855782483704 0.461736283099744 0.404865785958245 0.757985872644931 0.547112138979137 0.370989797445945 0.594446465149522 0.477474317224696 0.0590370914223604 0.341849800080527 0.316340825357474 0.994514941950329 0.420206308430061 0.410090221930295 0.972911126299296 0.857644716415089 0.847728672751691 0.114635224652011 0.663306355576497 0.69827160685556 0.206045269370079 0.133328202620614 0.763411184488796 0.396092654480599 0.364476992862765 0.382165739915799 0.283536638368387 0.0762109543406404 0.12543050426757 0.141141881027725 0.531397125583608 0.908398344221059 0.128261107082944 0.561961237613577 0.720517965289764 0.703057063573506 0.107548593950924 0.652489005592652 0.050374907173682 0.177404258623719 0.594888885573018 0.111090050069615 0.344258074439131 0.997951838751324 0.763712953308131 0.35989055854734 0.0886351990443654 0.268591680726968 0.846020107830409 0.42860915887868 0.849916507813614 0.26053014039062 0.261487131004687 0.941403972734697 0.24925075515639 0.575490015402902 0.838946346535813 0.354216275366489 0.504895934648812 0.913903164619114 0.676283074275125 0.517630060932133 0.600224935617298 0.318420371804386 0.41746362704318 0.771010424036067 0.907067660451867 0.836254967823625 0.334329479001462 0.335159048615023 0.365796543599572 0.3347901289328 0.968371353724506 0.368221306942869 0.157065412139054 0.870474340969231 0.511307897686493 0.970622889490332 0.118398762166034 0.483715972458012 0.247316051768139 0.890821775970981 0.484272833373398 0.54821745346766 0.0143896060646512 0.993336311352905 0.596875556635205 0.948696202761494 0.850566833047196 0.662928846685682 0.204302844807971 0.926495862735901 0.948624495097902 0.0760747929220088 0.400769702491816 0.438229040000588 0.461058262549341 0.993366120145656 0.921238354288507 0.190206635266077 0.414260440710932 0.140772810596973 0.969569505795371 0.588659168516751 0.26287506417837 0.379907601180021 0.527169517483562 0.68547406937927 0.413247530460358 0.799536794214509 0.0971635727677494 0.374290165868588 0.795812604601961 0.054088147925213 0.0478237603208981 0.0458814994525164 0.940491230501793 0.337397120969836 0.0296166630694643 0.495637701551896 0.207347611724399 0.852071192029398 0.869294851520099 0.977163562267087 0.012184134577401 0.0865641950140707 0.256653030226007 0.0170855431910604 0.563128468026407 0.928886969741434 0.206382545921952 0.791294613345526 0.70503161666682 0.590460017584264 0.493009604490362 0.857320902582724 0.0576737620681524 0.226621346324682 0.553710780558176 0.887018225786742 0.611751689275261 0.752616932913661 0.438984442490619 0.749532114602625 0.958467476896476 0.633504686960951 0.944278631231282 0.598553799435031 0.0203385148011148 0.214918242013082 0.732674508267082 0.865337940754835 0.0696560581866652 0.951692983931862 0.332034234690946 0.876586627457291 0.193846044735983 0.106964457693975 0.99335032220697 0.29638722918462 0.0384699936863035 0.597661044981796 0.127990534449928 0.934192263858858 0.431667358088307 0.850469392794184 0.737351705182809 0.193502557759639 0.275853191015776 0.35793149451958 0.588468724489212 0.721143086014781 0.595796114420518 0.163812236064114 0.847924026018009 0.799545784036163 0.0452637474262156 0.215802202802151 0.590344852854032 0.784820179103408 0.447871072397102 0.23880576786818 0.573315770758782 0.624410836836323 0.491827771523967 0.948960713644046 0.0734616390964948 0.52722666800255 0.61617937824456 0.546624631837476 0.50935817591846 0.656991204672959 0.982181493269745 0.427990934322588 0.862457806444727 0.142325509837829 0.473464430337772 0.630819711834192 0.174833875198383 0.72204679393908 0.319713554917835 0.681168489484116 0.549205116797239 0.0738677683100104 0.958171901674941 0.394531043097377 0.327161192616913 0.973677148954011 0.662982994681224 0.746135820788331 0.460187428868376 0.657590735720005 0.705792861008085 0.473407200064976 0.898118813585024 0.500793416248634 0.0478769727074541 0.548802539394237 0.419994316122029 0.652794112777337 0.318541244463995 0.861731693656184 0.998624309266452 0.898780654023867 0.989066985556856 0.16054610830266 0.449815620770678 0.26341187162092 0.314241008535028 0.282517718691379 0.899828781804536 0.454512530937791 0.139833122640848 0.788236193084158 0.634796853328589 0.279627621839754 0.129303345759399 0.317179872766137 0.759303070874885 0.802925544148311 0.364959801214281 0.787153360410593 0.497916763445828 0.490501276673749 0.339796361019835 0.12039503803011 0.518863385124132 0.559673348632641 0.806575991222635 0.299436402153224 0.291065744813532 0.566693283943459 0.378767771041021 0.769551402558573 0.589863696512766 0.273106087902561 0.710598078691401 0.911641005000565 0.870403479018714 0.700381135202479 0.142730871017557 0.028627000823617 0.545041305290069 0.906350838751532 0.692699495449197 0.961519069448113 0.704808072273154 0.386873912427109 0.932112763281912 0.757050297542009 0.0896468765684403 0.0168491275468841 0.609233541367576 0.774537761656102 0.918985983412713 0.0791247141011991 0.754696113783866 0.791114549760241 0.57121076694224 0.0292941409721971 0.207861538121942 0.093274141792208 0.33578963893 0.336764668656979 0.578127865018323 0.728844871902838 0.105437204297632 0.790880170834716 0.339676895576995 0.0564956321218051 0.250839862010907 0.90534153332701 0.289180215871893 0.715377545345109 0.778889513704926 0.734684927985072 0.204891290997621 0.373391171486583 0.720799779982772 0.730002399550285 0.567082988712937 0.326082275025547 0.274580048928037 0.825221172687598 0.147278889352456 0.618068659303244 0.211306762511376 0.206193104118574 0.129591559888795 0.397964899111539 0.114728479443584 0.504504211370367 0.56970153813716 0.0305952678876929 0.944413087624125 0.994566269058269 0.245778779126704 0.445293597567361 0.175331092942506 0.328219253665302 0.702117613265291 0.765131806295831 0.392146462765522 0.670687575179618 0.350754622614477 0.670080603286624 0.464448230457492 0.318757337869611 0.569382457439788 0.874388500235509 0.03542684558779 0.483759595025331 0.977425538776442 0.188695372969378 0.106174793106038 0.806391378443223 0.683844329572748 0.139385139965452 0.940521754543297 0.0844398479023948 0.149542077011429 0.470208563848864 0.941541029424407 0.387532892331947 0.01534541627625 0.0693693135096692 0.452862230783794 0.130947499799076 0.4404985729279 0.025400460686069 0.946288329707459 0.0500377023080364 0.37836486724671 0.398392032389529 0.81632449264871 0.994396512615494 0.833079917067662 0.325613503805362 0.0831680913642049 0.288967033249792 0.114738423314411 0.834125131068286 0.907231997093186 0.428035142135341 0.432877403618768 0.934394589359872 0.518318219436333 0.893443260150962 0.96733822772745 0.267233938518912 0.518381600663997 0.890967027479783 0.866839182423428 0.55779206116451 0.0256533501017839 0.0521780688711442 0.296236178237014 0.994560947450809 0.568572824895382 0.81528630297631 0.785078850900754 0.909812480439432 0.640354261682369 0.210321766785346 0.80595325642731 0.413782861535437 0.0630108512169681 0.140229731646832 0.399791834128555 0.735932608323637 0.496147335765418 0.446428605366964 0.323043597289361 0.604151481618173 0.928206227649935 0.705548726993147 0.918201969820075 0.394756373423152 0.0961687249108218 0.251790807009675 0.764708205005154 0.150555640275124 0.730700350946281 0.874004389066249 0.246506853951141 0.372193716224283 0.730085308705457 0.254941874458455 0.432385102028493 0.258713099455927 0.204615004442167 0.845735745395068 0.886186437588185 0.333353495916817 0.59431633551605 0.252935197406914 0.453583777551539 0.787764618033543 0.133943156348541 0.109252017056569 0.153135558890644 0.821899931586813 0.081136423710268 0.560230913271662 0.966843263604678 0.546610949449241 0.501372713570017 0.839271901813336 0.235007212439086 0.14309315730352 0.676718615356367 0.512622556472197 0.531135142389685 0.180754897531588 0.392962196476292 0.653109421303961 0.234803337731864 0.889677161294967 0.592570913732052 0.0937668114947155 0.0215361616108567 0.663858932375442 0.157784821458627 0.532166113881394 0.476243324333336 0.747203090866096 0.660352463745512 0.881267845486291 0.991726224175654 0.523118774518371 0.0723891303921118 0.661649011501577 0.0882687699398957 0.494406300901901 0.310772868986242 0.732317281046417 0.881354454434477 0.758867728486657 0.109505166709423 0.85082912695827 0.0504373032343574 0.682601833001245 0.943696581942495 0.989312602393329 0.569507480754983 0.364329328455497 0.273527146060951 0.212185914560687 0.852416048189625 0.749509360103402 0.0964249543054029 0.5513279338344 0.490355575915892 0.237077388735488 0.330218601895031 0.101239778404124 0.594408796918578 0.458699997747317 0.398278291702736 0.583569317557849 0.684144555870444 0.688923763439525 0.570527500389144 0.144659627906512 0.952865589889698 0.5804014971992 0.696072135805152 0.504165420187637 0.026774814275559 0.482576192568522 0.0230778209422715 0.135300708392169 0.831145580869634 0.339812051544432 0.826029831590131 0.334810724777635 0.216559485499747 0.457519706611056 0.31943657892989 0.189792027946096 0.659323113607243 0.420673415423371 0.950994805721566 0.833351921120193 0.727007412379608 0.363774680593051 0.172079697737936 0.0759681258909404 0.950058788745664 0.793367265928537 0.521554363684263 0.269428527529817 0.459009782746434 0.715659150741994 0.23452396820765 0.415871310443617 0.0801207525026984 0.52894391156733 0.123049463299103 0.396768387986813 0.123845169814304 0.42202800297644 0.639559153551236 0.0651771276257932 0.374529066327959 0.907982721077278 0.307066634814255 0.750568397098687 0.576132606361061 0.914798919751775 0.834963509328663 0.858700402597897 0.5127136445418 0.343231109539047 0.841405822839588 0.557659459162969 0.536109368074685 0.713742723653559 0.742087224030402 0.214139178688638 0.848359597756062 0.876708937759977 0.621680229853373 0.89677173856413 0.759449693642091 0.145012175238226 0.781175705036148 0.242859705365263 0.357513337924611 0.234798967868555 0.407481312113814 0.567541674533859 0.398681110441685 0.223689148451667 0.696893282171804 0.503313598569948 0.79424114293186 0.837950044670142 0.0434305438981391 0.308472019319888 0.83276908028638 0.897292931086849 0.730856423617806 0.656183628900908 0.911787741866428 0.758413921939209 0.2533790665376 0.266111201050226 0.511411803991068 0.5710027581756 0.282908038902096 0.689984387443401 0.716609332317021 0.905282586503308 0.334132418173831 0.292606164503377 0.0376267430675216 0.813069046365563 0.183180513964035 0.871237038166728 0.914614873547107 0.953179630883969 0.939763184490148 0.550904369885102 0.218207758155186 0.234269414795563 0.232729675087612 0.322357856524177 0.185399957119953 0.992811209280044 0.400432295245118 0.014174999629613 0.231429296382703 0.794249095492996 0.249677858469076 0.503881287563127 0.420347137060016 0.587099392623641 0.394631164553575 0.875410174876451 0.903605703897774 0.494488736835774 0.472540730484761 0.0778987397067249 0.112614449616522 0.39686924313195 0.422486637395341 0.215133230159991 0.847075962510426 0.510421215817332 0.0218283419939689 0.627671021325514 0.321227342367638 0.121702609790955 0.0904595879325643 0.348296559520531 0.625068715631496 0.515290120604914 0.650428070134949 0.335480681895278 0.222638374273665 0.820672757658176 0.845727997289505 0.45705317103304 0.870225923298858 0.395323766912334 0.583977398434654 0.599085954879411 0.924118245649151 0.680261459329631 0.996412462545559 0.416581279770471 0.702115553035401 0.539322464393918 0.330332557871006 0.604557190625928 0.931666651132982 0.194041981403716 0.0414327552472241 0.845949179495219 0.202262180878315 0.685658579585142 0.418212180617265 0.715553313288838 0.664501688373275 0.915241316203028 0.380109402518719 0.780690682940185 0.261890312323812 0.660039454940706 0.968510227003135 0.589320605576504 0.169721840694547 0.269883072376251 0.792127569499426 0.852798333088867 0.911698444338981 0.764212117644492 0.680837132462766 0.109418630830478 0.28954005768057 0.512172188558616 0.205629954868928 0.90925934674684 0.982470335057005 0.903481328294147 0.122955757414456 0.21933636052534 0.961416702899151 0.76368489794666 0.801838031124789 0.286814762854483 0.973966607335024 0.260119036706164 0.541516123558395 0.397707302146591 0.818053475928027 0.753562047816813 0.335186104979366 0.295704117759597 0.779594182400033 0.33972919263877 0.462103505362757 0.211026717615314 0.310979229891673 0.795853710314259 0.250018828359898 0.17969505446963 0.0848334334092215 0.989020268726163 0.47229371542111 0.938631183363032 0.171329232377466 0.58878964505624 0.144778849938884 0.11454727394972 0.439977698267903 0.453818058283068 0.398848805041052 0.0172822764748707 0.363987079507206 0.510711781531572 0.12069341662107 0.848731339247897 0.097009579918813 0.24488158865599 0.927709471601993 0.225321463199798 0.698831932682078 0.141136579704471 0.0649090955895372 0.92130120075075 0.628617581708822 0.0427857670863159 0.679244296310935 0.824067005533725 0.0907186172390357 0.569335032505915 0.962713945619762 0.838038410507143 0.125205157576129 0.92135881411843 0.211063544512726 0.150806050638203 0.309402466898318 0.637010984788649 0.0937826804281212 0.476392833911814 0.907824942457955 0.0942459101416171 0.860360543127172 0.585595659224782 0.680805591444951 0.985850782527123 0.411452543528285 0.16672234259313 0.52455827913247 0.636899175941944 0.975570869026706 0.801827864588704 0.406907760754693 0.23191423595883 0.9622453147755 0.48420913727954 0.64679022946395 0.614938306177501 0.343126722406596 0.373449708246626 0.837714120226447 0.116545981152449 0.134413129868917 0.161418562415056 0.906008790801279 0.0562732017459348 0.954134703027084 0.150698208275717 0.963964108237997 0.856363572899718 0.680428633224219 0.684341988728847 0.261598312193528 0.772027006649878 0.67922318367986 0.259850180624053 0.373216888208408 0.384657460269518 0.899798113929573 0.937745563648641 0.860521995031741 0.990678595202044 0.707845369530842 0.765151619354729 0.0518046965752728 0.130549226105213 0.849898315647151 0.737233129017986 0.9363722208119 0.0248541498626582 0.669628936031368 0.0815691830893047 0.38820146482205 0.470926013668068 0.5842921765754 0.830286642031278 0.451820764059667 0.478747897497378 0.266339266516734 0.3284862740268 0.511094654672779 0.582703636065125 0.455296729623806 0.989184096879326 0.691672049490735 0.210054562252481 0.728093452723697 0.309262143529486 0.205426375896204 0.429991218161304 0.812390462467447 0.1880368921021 0.702447597875726 0.818447221633978 0.455219722711481 0.271974615547806 0.462980966907926 0.227356277210638 0.877859165628906 0.278679782859981 0.743425448453054 0.112724871761166 0.555362518585753 0.703224615722429 0.99983697399497 0.816426039992366 0.203372651934624 0.621267514957581 0.649352139162365 0.0873301210883073 0.0130617600097321 0.846908751735464 0.814210251681507 0.882812824973371 0.207880744037684 0.96465565189952 0.801522781606764 0.44386415138375 0.822225491704885 0.456089556242805 0.969605132467113 0.682755926118698 0.349912680326961 0.596004402786493 0.668104100143537 0.318367617656477 0.840351450981107 0.13765392242698 0.719433380567934 0.121532199182548 0.0665125857898966 0.965610447900835 0.598719873372465 0.585187673775945 0.962333396403119 0.0974249640316702 0.476841926455963 0.154009271084797 0.813973877527751 0.940163950375281 0.436673803851008 0.28844812661875 0.377361535059754 0.767497458006255 0.216823821892031 0.0697181603568606 0.687055225286167 0.896472541228868 0.278083999780938 0.520472782407887 0.307736961657647 0.0917486452846788 0.536763873468153 0.360692929807119 0.332331822428387 0.442139836468268 0.979495766013861 0.41307778946124 0.700996802335139 0.27732031626394 0.170439841644838 0.0132903355779126 0.407272894436028 0.61537875741953 0.594884470531251 0.889793562209234 0.667625837528612 0.75157849844778 0.942510158291552 0.626299712671898 0.994204583691899 0.455955650059041 0.129113547599409 0.812251968365163 0.0667901465622708 0.969658278238494 0.309024387514219 0.996235245433636 0.641318708355539 0.0560112558933906 0.940642269924283 0.355267114315648 0.26955619078828 0.202543194114696 0.481884840454441 0.1063757722429 0.70666224782588 0.833683177873027 0.706887982222252 0.0686858344334178 0.382934414269403 0.662571844665799 0.66898313601967 0.123522757897153 0.672692046784796 0.990050774372648 0.930123041060288 0.335269589929376 0.985825864071958 0.0603754352452233 0.126944356027525 0.0999319814424962 0.610815330464393 0.327429848392494 0.645932247210294 0.899951399136335 0.644564553063829 0.93519939057529 0.499989643765148 0.467548306640238 0.341363417790271 0.31175821761135 0.809981728487182 0.4390823432873 0.856017009639181 0.170326517936774 0.678405023009982 0.239478697313461 0.823018792006187 0.266673459638841 0.399290155011695 0.902164427873213 0.136324638959486 0.958593729019631 0.371870010958519 0.872716346615925 0.187863888342399 0.266475457900669 0.107973522474058 0.370180290064309 0.704450615702663 0.465365899677854 0.120009516186547 0.8000619386998 0.0263896285044029 0.610511647092644 0.854885324991774 0.057934939195402 0.366376359320711 0.050514928123448 0.290113667356782 0.156448344474193 0.737226143875159 0.71513346642023 0.322646548254415 0.251441231314093 0.995873613313306 0.715152112215292 0.644575997043867 0.946146796431858 0.982099773276132 0.054733088624198 0.3469010176952 0.024240864510648 0.159088546365965 0.525472033270635 0.909928199297283 0.103129352431279 0.182916352292523 0.964939558170736 0.261656413765159 0.858899894533679 0.856475383820944 0.670524406032637 0.654927548135165 0.484877992135007 0.980350739520509 0.23221529413946 0.598434663610533 0.93124006691156 0.560186503999867 0.0518657243740745 0.697301532928832 0.708120315484703 0.0341836427571252 0.357642444358207 0.928699743757024 0.212975852063391 0.867866165533196 0.156009948621504 0.974987540449947 0.686855146721937 0.32849856441142 0.915706366193481 0.252391528140288 0.531289284834638 0.554742286584806 0.336982557214797 0.653829256130848 0.339355141052511 0.0606910625565797 0.393197621421423 0.996848223065026 0.266000178446993 0.723105824480299 0.697466032996308 0.512875973738264 0.0810507967020385 0.94389086291194 0.508779825961683 0.917738169843797 0.197046212179121 0.441257858229801 0.258293990886305 0.422355654442217 0.396726245936006 0.927005747735966 0.0359191409545019 0.742907275049947 0.606048331451602 0.557154671722092 0.818767444009427 0.200262245559134 0.641905144334305 0.626230065699201 0.658905604723841 0.833956470894627 0.316955576934852 0.275894987313077 0.280487926404458 0.196049130293541 0.929469895861112 0.541009482187219 0.362705235034227 0.643319140407257 0.140850504636765 0.0480518854875118 0.784453377737664 0.603580873312894 0.723261717129499 0.33712775363354 0.0582880761520937 0.614595543670002 0.15290682312334 0.723697361475788 0.335478542372584 0.0572043772507459 0.51569869176019 0.615292098221835 0.986170566948131 0.131594725006726 0.654012301494367 0.0627273637684993 0.783108127603773 0.690737699046731 0.990701887002215 0.283727633757517 0.57589618334081 0.298410031257663 0.808148787501268 0.0242908623116091 0.984694443580229 0.686388428355567 0.541295290102716 0.522224249115679 0.566400176249444 0.986138480792288 0.376978422887623 0.356212395180482 0.780542931633536 0.236978682794143 0.291949268800672 0.247889398210682 0.528194603328593 0.213640904321801 0.110780126538593 0.897470294798259 0.967610334814526 0.741439741351642 0.71957332360791 0.718547317828052 0.752608089691494 0.573212319004815 0.502057821375783 0.527011546394788 0.929199309628457 0.986084314817563 0.784759496597108 0.801965626385063 0.366054782283027 0.898923001433723 0.0762034888309427 0.72732222763123 0.477866688906215 0.842300780895166 0.656464473179076 0.304650643467903 0.0281522033503279 0.0215399075043388 0.979168837864418 0.969830693525728 0.713874753317796 0.192399285752326 0.989921767746564 0.83059377948055 0.213162635483313 0.913331423394848 0.985996899572201 0.913462849603966 0.795719993603416 0.208973874864168 0.646438063383102 0.182882887963206 0.955377595601603 0.294844131518621 0.424155612387694 0.920690831483807 0.895107726517599 0.322335745817982 0.91194540892262 0.305706590118352 0.0429079589108005 0.718141840705648 0.330027501396835 0.243987561368849 0.736967576495372 0.750476234888192 0.0813077353523113 0.549984756608028 0.862838628576137 0.140621111015789 0.596483697129879 0.25451095656259 0.625814517699182 0.908178938957863 0.850851999244187 0.90200875489274 0.562430760732386 0.320203760550357 0.106671960139647 0.590246714639943 0.84394168300787 0.124634972703643 0.146002835789695 0.959092622054741 0.892390438190196 0.20936030580895 0.656288983912673 0.0105362948053516 0.792211683259811 0.825375501378439 0.502926604738459 0.73948398595443 0.0593854302424006 0.487752132231835 0.719779580095783 0.188515068739653 0.830018418908585 0.454515340530779 0.638804674223065 0.685731760389171 0.145070155565627 0.550526288656983 0.311966441667173 0.826504456417169 0.145491818792652 0.668942675022408 0.533530835700221 0.49783519489225 0.879547212845646 0.296357684547547 0.344038419541903 0.250177149351221 0.416006216316018 0.66626477009384 0.138845302108675 0.253834374116268 0.718240904156119 0.736817687510047 0.923828966137953 0.0328778924257494 0.450809780347627 0.295675670083147 0.65887889664853 0.138401743464638 0.833437364879064 0.176916666426696 0.0325055216625333 0.213809359809384 0.262690921623725 0.825527678329963 0.672149736790452 0.904931272359099 0.173758621211164 0.614878777335398 0.86276660673786 0.291821642883588 0.62928256182 0.252880270774476 0.308104105319362 0.526061694668606 0.494118096684106 0.855019439319149 0.445247282963246 0.989068637336604 0.399306093556806 0.596081773892511 0.956654949197546 0.759509349721484 0.337182913303841 0.574775533762295 0.152235638350248 0.220354414666072 0.187596223726869 0.469794519646093 0.970365853568073 0.48306200413499 0.305775956339203 0.138965515070595 0.816541336339433 0.726604261486791 0.562778839084785 0.964914825269952 0.8323966440605 0.0164419191214256 0.700084604318254 0.255449027775321 0.738906215250026 0.519234182939399 0.870553214028478 0.980043324085418 0.559741783624049 0.156521454053 0.357907729498111 0.154812124785967 0.453242172626778 0.653133542912547 0.557788833209779 0.523690439215861 0.897191843825858 0.0409918538341299 0.796148209781386 0.894277202854864 0.0702539542806335 0.250081153886858 0.0961218430404551 0.92467069060076 0.482141210455447 0.992717527828645 0.728580458983779 0.797978652813472 0.770350925731473 0.73552250640234 0.555118907580618 0.0149944743933156 0.918229893795215 0.919547366092447 0.471273189834319 0.471293547339737 0.738276846366934 0.0657168002123944 0.910257637847681 0.359682246209122 0.489565339221153 0.330890934569761 0.603422943253536 0.332611532865558 0.706067538887728 0.290026669781655 0.674514555004425 0.0730560133000836 0.657211072323844 0.312809354830533 0.46170908359345 0.72490751465084 0.0330644522584043 0.478336733882315 0.841664127907716 0.84354006242007 0.155614532234613 0.772742707647849 0.946137350907084 0.678110435951967 0.612098721838556 0.530478032780811 0.045374217745848 0.932676585367881 0.748253615410067 0.584117367290892 0.129376172050834 0.921709328419529 0.330956932229456 0.803949361308478 0.293222205510829 0.968113232366741 0.52653272619471 0.143993825824 0.938095399811864 0.746191396745853 0.599444703185 0.710556671251543 0.526374269207008 0.536686570129823 0.90095095200697 0.342137610139325 0.236267704097554 0.494403659575619 0.760127367747482 0.937929271014873 0.558934384416789 0.410399662097916 0.658222951076459 0.657461563132238 0.658752506223973 0.599397082554642 0.307586043479387 0.675893631356303 0.37223694809014 0.117502250294201 0.599650655179285 0.175882342508994 0.121597140450031 0.0687008749414235 0.703688657726161 0.915197668280452 0.38954786285758 0.173397985552438 0.137702653617598 0.438583868844435 0.442681035210844 0.555220077361446 0.775628271901514 0.0888891971763223 0.307407638819423 0.579317745743319 0.825068259511609 0.813557182778604 0.424804168285336 0.362240752771031 0.981398666072637 0.592940175479744 0.444847102554049 0.177945624710992 0.344650157301221 0.124200037843548 0.628658390764613 0.834419237067923 0.617662501507439 0.733938043939415 0.570423815597314 0.255802937375847 0.4832622779347 0.0165757736726664 0.636768646847922 0.3203671823279 0.619689710324165 0.410940511168446 0.908957788376138 0.220440450124443 0.344859842741862 0.744305128583219 0.485841786025558 0.0223224689322524 0.905573993551079 0.0218974219309166 0.788047507328447 0.0634344979166053 0.95362785074627 0.69256100111641 0.43238110949751 0.907274679441471 0.365322855995037 0.645273835032713 0.802987277745269 0.906666414660867 0.217620567281265 0.659978342547547 0.595660720805172 0.918647198453546 0.822210057959892 0.444908616943285 0.764769506871235 0.951214098730125 0.850373316884506 0.415016313195229 0.431787400247995 0.438609714841004 0.707824163315818 0.0290825946861878 0.985448030403349 0.783591455968563 0.782999024163 0.937398710416164 0.119653127994388 0.644430037892889 0.530652863041032 0.657985329444055 0.464050121342298 0.584951837845147 0.873981366031803 0.0812494101934135 0.468803950143047 0.0863186950422823 0.249407990481704 0.10565593810752 0.415286797084846 0.390947179850191 0.91979954025941 0.176378208587412 0.653281788646709 0.387838153953198 0.202055397001095 0.552737311332021 0.443852438868489 0.931527935517952 0.441840635214467 0.0972958066570573 0.243364212284796 0.500601325512398 0.576979210097343 0.390668530876283 0.857133361732122 0.790566447242163 0.838093105484731 0.118325727269985 0.494137303752359 0.445453650783747 0.774511195339728 0.163513336537872 0.464110558133107 0.592470486629754 0.665275332818273 0.871740259574726 0.556306846323423 0.142844757842831 0.964304210287519 0.0186784607102163 0.662942502335645 0.626582087716088 0.0348810524726287 0.0239525328250602 0.484025358227082 0.16374090296682 0.964980881016236 0.339318968781736 0.139679961213842 0.23369705859106 0.424352301184554 0.847271742897574 0.280156111605465 0.214020082049537 0.744223120231181 0.44557005815208 0.56763562936103 0.706238170778379 0.555557596401777 0.576653976831585 0.836328052277677 0.279812622785103 0.145729018836282 0.306926522585563 0.934083803058602 0.151359667694196 0.464564147547353 0.982992550088093 0.604312243398745 0.695117547486443 0.859807857761625 0.238770850913133 0.0372306506172754 0.355375175424851 0.574683990681078 0.920570407381747 0.168915724463295 0.336710680630058 0.354054504677188 0.35021381042432 0.463472393511329 0.0588488698983565 0.682911120576318 0.0640016973228194 0.717247115687933 0.623183470899239 0.521765231601894 0.846911541505251 0.0340037843189202 0.449222488007508 0.977132196892053 0.878788024124224 0.87714948005043 0.48148571989499 0.35359993585851 0.0168595061451197 0.414999482606072 0.262112941162195 0.811953959499951 0.124521676886361 0.170622751472984 0.938467608762439 0.056718195497524 0.391997111772653 0.929243123512715 0.477578981190454 0.55740861176746 0.430297624687664 0.4720052532712 0.953899433901534 0.781383808769751 0.680007164080162 0.798195340915117 0.229852176571731 0.673113682582043 0.173490070544649 0.974839289644733 0.600623950376175 0.393055314349476 0.545039561539888 0.479535380841698 0.12519634178374 0.314233441834804 0.126731028880458 0.300092517375015 0.612747984456364 0.856752662919462 0.336921909744851 0.0604270412609913 0.962162138929125 0.553905797521584 0.600738327710424 0.299076256542467 0.303055514048319 0.536553990487009 0.326510670303833 0.483983062431216 0.817559818523005 0.165479232424404 0.857808509762399 0.919630462415516 0.304221924333833 0.238382956970017 0.635008987856563 0.899890299881808 0.726569770961069 0.982270119574387 0.772861327608116 0.318056749526877 0.136576524076518 0.545360846300609 0.932487803492695 0.381043427262921 0.211100698492955 0.59985082986299 0.398811739573721 0.926491589453071 0.988515970180742 0.834484334154986 0.106359914604109 0.238925322976429 0.825377931564581 0.660248194169253 0.402230070794467 0.554990211671684 0.772283815527335 0.508463680711575 0.345164446739946 0.316296812319197 0.979337325391825 0.329876254291739 0.504451875353698 0.695037954568397 0.910736799882725 0.918853464392014 0.43275836644927 0.569684384844731 0.487787524943706 0.940810976428911 0.11975822530454 0.751408461714163 0.89447450962849 0.0752114616311155 0.772650766258594 0.85401124975644 0.897512802656274 0.947068591183051 0.173449939396232 0.519335878265556 0.917825988929253 0.977183225499466 0.353039249295834 0.882224940978922 0.762411785824224 0.815725518956315 0.601849862535018 0.993585175506305 0.52816158317728 0.294706275446806 0.657798104151152 0.861112138410099 0.349113718427252 0.526321415943094 0.728099879128858 0.360921731037088 0.322292097434402 0.289747660302091 0.435122716051992 0.315961243328638 0.885743919892702 0.103435245398432 0.0141460224892944 0.486503088702448 0.111972815243062 0.0694717356096953 0.310189571527299 0.125996399952564 0.607744040335529 0.805811714162119 0.361271303044632 0.501413085823879 0.497199816352222 0.864359560445882 0.394060737884138 0.190178246367723 0.0732907310640439 0.678638497674838 0.34394261331996 0.0454355534957722 0.620483496293891 0.640357384758536 0.455839946875349 0.419845250491053 0.9872418809589 0.566424264896195 0.209200741718523 0.697484744484536 0.771957142313477 0.0269694292428903 0.710427275998518 0.546718824082054 0.855730358315632 0.306808711457998 0.480587679792661 0.820036624914501 0.301316360314377 0.46685494201025 0.0823133813217282 0.938400076879188 0.0830317068193108 0.170985118665267 0.219302136690821 0.221446324060671 0.323871940169483 0.98780188154662 0.829497461959254 0.880791139914654 0.588641610923223 0.0668122598039918 0.419747296448331 0.940565103965346 0.876367610590532 0.986924972976558 0.489598499978892 0.808396304599009 0.576360196992755 0.547366734112147 0.468240654754918 0.449630630658939 0.524239277958404 0.387002567076124 0.249423914505169 0.879377490978222 0.613047187323682 0.172332324380986 0.744730574353598 0.81750329059083 0.332156666007359 0.322768802775536 0.961590708422009 0.237916103990283 0.752194882442709 0.828768704847898 0.990325034351554 0.656740596308373 0.376951876394451 0.352646176195703 0.649013037262484 0.288155098448042 0.633200554570649 0.0274142902251333 0.381554599157535 0.147971110229846 0.587966206574347 0.681108846312854 0.339830880819354 0.0681273650727235 0.194544998125639 0.350561981899664 0.103887272467837 0.111867248860653 0.801297392963897 0.840759391020983 0.856483663234394 0.673441725440789 0.551287108643446 0.798573527482804 0.814963412075304 0.825860310029238 0.852379379877821 0.487011960644741 0.944500596683938 0.648475055641029 0.919780240068212 0.448912755562924 0.141034229982179 0.664892526292242 0.551453102135565 0.793549913906027 0.585990372579545 0.23813079317566 0.262715570621658 0.198641675827093 0.292848993414082 0.477248136575799 0.553535514418036 0.538712137308903 0.309571943280753 0.639537118910812 0.735368774482049 0.998410114278086 0.657526833326556 0.873624245303217 0.81191629541805 0.451622988905292 0.808329367872793 0.0426546612754464 0.889787816016469 0.321459402670152 0.987949565085582 0.946199400522746 0.831678168505896 0.100973944668658 0.35104338580044 0.619293825787026 0.091485159676522 0.837606534874067 0.560496371288318 0.590186263788491 0.747802660407033 0.771823363597505 0.659092079962138 0.381739151775837 0.2771073270333 0.829848606914747 0.786895488456357 0.777993195455056 0.186931865741499 0.518648878035601 0.932422377017792 0.640879153767601 0.50748149918858 0.232980378649663 0.390025358130224 0.530144056100398 0.466607273472473 0.738171766805463 0.250231799841858 0.772229030423332 0.42902972284006 0.622093379246071 0.478541994600091 0.800850306251086 0.0760983995883726 0.695425958230626 0.862950767502189 0.318924393977504 0.788829377479851 0.970617349136155 0.478036712270696 0.105936911005992 0.971432780888863 0.13357329898281 0.59730809795903 0.798254226655699 0.0513528292439878 0.314116154869553 0.160492961839773 0.920130173042417 0.560331474065315 0.0271113707381301 0.952476012127008 0.280988284281921 0.704611608446576 0.398175393154379 0.0812710283161141 0.482520228445064 0.30885406357469 0.364282887997106 0.100203389185481 0.516958234440535 0.0183692747866735 0.617450276853051 0.74730460732244 0.192080018809065 0.283001389121637 0.298307391332928 0.858988934129011 0.306459034802392 0.136432367223315 0.951544624560047 0.836716330929194 0.825160921220668 0.391792316669598 0.569105532623362 0.415251201300416 0.496929775027093 0.436349865547381 0.31463966970332 0.263465625457466 0.228988609015942 0.0770740897045471 0.18604587929789 0.919808177181985 0.91501623412827 0.101105336993933 0.103269103923812 0.518822103999555 0.0950630844919942 0.596802024776116 0.528548929446843 0.767979522296228 0.963310990699101 0.400056774667464 0.260775505979545 0.20313784404425 0.0907029442326166 0.529825645934325 0.55620914168423 0.290605613512453 0.863500390183181 0.201341436526272 0.945037222029641 0.0598741323081777 0.0507921184785664 0.78945542643778 0.376569727952592 0.939211771267001 0.156114643244073 0.605793093447573 0.419235725554172 0.676627134741284 0.949499298029114 0.976887824307196 0.685726496637799 0.790972278416157 0.353534176538233 0.525291610101704 0.594206294622272 0.964513922927436 0.887312287068926 0.510000608752016 0.248014477537945 0.36625866989838 0.305901333475485 0.71657470879145 0.193444351539947 0.52750702430727 0.477765792270657 0.908668088659178 0.930006295084022 0.213127981300931 0.252856289311312 0.163553828191943 0.251257063173689 0.620368270941544 0.0304711043462157 0.582027936673257 0.758558360005263 0.532936700021382 0.0585263593262062 0.604028694406152 0.19440266523743 0.829491567092482 0.37269229831174 0.856634557209909 0.263303204521071 0.996115316220094 0.886268712861929 0.504858593270183 0.652718157416675 0.269125605276786 0.43696893789107 0.248160700614098 0.83990037150681 0.2962052291492 0.887239074225072 0.219242968123872 0.43426634662319 0.310185536583886 0.871325632892549 0.727385833598673 0.436737764100544 0.193230916978791 0.633906033020467 0.39089990013279 0.610090541911777 0.351831628188957 0.852455257328693 0.0264215367124416 0.49776982097188 0.334592122815084 0.0787652109004557 0.225081054333132 0.332692587398924 0.0637925314344466 0.364272347586229 0.540405300986022 0.845483585288748 0.126500531844795 0.638970199103933 0.395963767485227 0.695760748584289 0.166778506562114 0.0377489219838753 0.492166808191687 0.0493005489185452 0.260831276250537 0.215569534434471 0.400725465866271 0.785666982915718 0.115939410564024 0.814911798222456 0.711042176710907 0.627385761775076 0.331850840116385 0.362885754092131 0.015196531128604 0.719604243421927 0.0425322583108209 0.556626936621033 0.831390672852285 0.561452582804486 0.329655889908317 0.723447579231579 0.745268549520988 0.175829594123643 0.334584674593061 0.0392866473319009 0.95209026992321 0.196133860647678 0.164567393299658 0.602921812271234 0.662943150047213 0.379450629143976 0.312274439351168 0.677316232542507 0.992970442138612 0.212412387486547 0.239030460393988 0.311086265265476 0.932505710066762 0.298835110529326 0.334130391136277 0.91298855047673 0.829947634406853 0.408477651320863 0.260005155412946 0.358304723904002 0.750496921781451 0.415002203916665 0.886931489601266 0.0872189521160908 0.462313029451761 0.285069623435847 0.547256686994806 0.880260390304029 0.554518095632084 0.204033201329876 0.924238145588897 0.80997846388258 0.963490527125541 0.0872029704670422 0.711940133832395 0.0931752696586773 0.417355404121336 0.728723966281395 0.184042654940859 0.455851739605423 0.254014076734893 0.532574387458153 0.157058821616229 0.218630510736257 0.742447636793368 0.520228782775812 0.87433250245871 0.824839293011464 0.239148648392875 0.739657614605967 0.97558448917931 0.327904681132641 0.994407059941441 0.449511148619931 0.424057114128955 0.0666026073251851 0.490458114880603 0.637417967552319 0.960169973382726 0.479489098968916 0.62598867996363 0.194892486853059 0.62310821903171 0.227657055791933 0.965299787223339 0.312404831065796 0.0215141686913557 0.718849888565019 0.554488107047509 0.745538031416945 0.706014653583989 0.985568292923272 0.810057666790672 0.638957478140946 0.87751393282786 0.574403438218869 0.513300276678056 0.774595641253982 0.445141049737576 0.691453677800018 0.0205440320679918 0.103037916303147 0.403502767090686 0.892795885116793 0.412053432925604 0.141157429793384 0.866938666310161 0.200079161701724 0.683406700831838 0.460137418620288 0.417741840598173 0.164061641206499 0.299550420595333 0.448973236610182 0.297487116956618 0.740065079811029 0.3945740250987 0.310471662592608 0.444592966581695 0.264437096228357 0.404424455580302 0.567130617641378 0.965885616289452 0.238902055379003 0.966148376045749 0.770097118224949 0.333459770402405 0.401393599479925 0.0229695781972259 0.0309427490085363 0.773213141942397 0.949474655024242 0.456462783091702 0.606515850813594 0.916700275214389 0.912727445957717 0.996867644039448 0.757421880909242 0.853768000409473 0.912736122296192 0.0572489868290722 0.886448613021057 0.20011572167743 0.0366588310222141 0.998761858770158 0.0613467407459393 0.661398594453931 0.289218097317498 0.469956673660781 0.813137287274003 0.885614424140658 0.390554470482748 0.327943450473249 0.596255727552343 0.458985259141773 0.734983851483557 0.0743526583281346 0.556890556612052 0.722675073698629 0.918534495718777 0.0962752109975554 0.242646784132812 0.453857078640722 0.963472364002373 0.681843969207257 0.17309432108188 0.104288766279351 0.849165868654381 0.584127384691965 0.605047572131734 0.0502995644882321 0.551340069782455 0.352372254594229 0.298761279939208 0.528931147039402 0.450174033925869 0.577097471626476 0.631088874714915 0.268826809476595 0.430352534493431 0.638975864390377 0.773311695521697 0.732613045740873 0.107953527318314 0.485966480183415 0.144227135910187 0.487333566956222 0.897516554081813 0.48749298122013 0.616441943917889 0.574742899932899 0.752611990713049 0.0622023716452532 0.256410414529964 0.781909079800826 0.813227243116125 0.0663539354107343 0.659667462662328 0.486769001730718 0.931279357648455 0.145699664824642 0.987047870138194 0.181075656285975 0.806508891761769 0.215282896249555 0.869462826179806 0.0833302824897692 0.0368179751373827 0.0973807924077846 0.735110369836912 0.043647130348254 0.185893576261587 0.25337940675905 0.726077005139086 0.813958604212385 0.577540909026284 0.536668960442767 0.503043162163813 0.119504003124312 0.0355374237825163 0.126625084013212 0.146338097520638 0.768935340805911 0.956132806083188 0.395341255816165 0.773193514207378 0.313754437232856 0.602779935777653 0.773503894824535 0.771649673401844 0.401597560856026 0.922673740286846 0.70095424376661 0.869196100169793 0.688276377571747 0.435580791733228 0.621638607354835 0.578219759846106 0.812388773576822 0.568565082782879 0.789592052779626 0.27599129948765 0.586997963297181 0.347276811418124 0.482966577550396 0.785098010485526 0.0370748243527487 0.0880949004134163 0.81120557004353 0.662083030345384 0.481136389453895 0.64073956039967 0.452669224722777 0.157425658479333 0.689929026775062 0.676029154513963 0.587867041011341 0.0450853731925599 0.842145108606201 0.624602497916203 0.743641270557418 0.557306663349736 0.397811807526741 0.73014231977053 0.972501241972204 0.736112013133243 0.844180986615829 0.908561694542877 0.550874429014511 0.151955367331393 0.796729618043173 0.372624142689165 0.428652216945775 0.889232934885658 0.780943321799859 0.594466898029204 0.986818045477848 0.359706188947894 0.0553316815267317 0.303573500744533 0.902937189263757 0.0722818539128639 0.954998398281168 0.773794919007923 0.69256916412618 0.188832127470523 0.341418632781133 0.707321503181011 0.543357491479255 0.760993323768489 0.216837702512275 0.657069594829809 0.674072734578513 0.984887638422661 0.107729819728993 0.80361822049832 0.594559772722423 0.433423832689878 0.668482741722837 0.388548562156502 0.190917913154699 0.955803616475314 0.839717530598864 0.0850226117484272 0.945750787423458 0.805283287323546 0.44540763375815 0.18453543551499 0.0420347671909258 0.155765267163515 0.516908666756935 0.416529028348159 0.755994110477623 0.904274863938335 0.777170746058691 0.62389472896466 0.974442818479147 0.976912856400013 0.045134262277279 0.626128251894843 0.367104208483361 0.29898953902768 0.413574779699557 0.0966587804863229 0.313522340049967 0.69801911436487 0.592695140431169 0.694037352220621 0.988371589048766 0.349829281123821 0.423304084660485 0.875127492342144 0.543430830868892 0.183186374255456 0.744654258256778 0.934212847026065 0.959663916565478 0.986898893711623 0.0573327571409754 0.650267776504625 0.167296584998257 0.308361444813199 0.472061600950547 0.222754297126085 0.0280441108928062 0.381779795330949 0.0122923001041636 0.810734295567963 0.407597387097776 0.673242365582846 0.377520895155612 0.02239763781894 0.452134730832186 0.564052122931462 0.600592047008686 0.943623384081293 0.775727655289229 0.546403451936785 0.0722641326626763 0.015465317138005 0.600907505592331 0.832137093127239 0.0581711621396244 0.493508539937902 0.870213424540125 0.52246333881747 0.0872342775249854 0.936595923099667 0.88327683217125 0.589758185911924 0.45506526977988 0.0119667759444565 0.564899061357137 0.300808196936268 0.921373890815303 0.289632166875526 0.677298796884716 0.488198322751559 0.85025719510857 0.35592434217222 0.113889113941696 0.0266881234990433 0.111322342026979 0.260752774761058 0.793286320192274 0.238749637783039 0.9125127134379 0.867747927515302 0.0961345135234296 0.276643801585305 0.340846377306152 0.223011477342807 0.27543859199388 0.549420314931776 0.307215282774996 0.693858874491416 0.874519545654766 0.0913574800523929 0.287045675024856 0.504769206999335 0.106752931692172 0.787108847643249 0.257407186620403 0.0387416671984829 0.418074034804013 0.361725526570808 0.509317702704575 0.203742970074527 0.724802890331484 0.309782235634048 0.903023052536882 0.818808375231456 0.259232372355182 0.433769595415797 0.321547799624968 0.738758060103282 0.0427165440074168 0.252692986011971 0.0678485346934758 0.263026900216937 0.847999753642362 0.466522470049094 0.169875905690715 0.712733482308686 0.430852497981396 0.441362280168105 0.1781729405839 0.695886505357921 0.743273415565491 0.886647950750776 0.582050012343098 0.500061507709324 0.611305196105968 0.624045649447944 0.0824165470222942 0.788106575857382 0.785560971433297 0.270801381471101 0.157826119409874 0.473686963978689 0.654624810745008 0.759369473296683 0.498713352093473 0.064291544330772 0.472713123413268 0.16106658188859 0.352862488117535 0.0731933350674808 0.530619181809016 0.0418282735161483 0.313404479825404 0.225505089429207 0.0625790212233551 0.539594950196333 0.854507357862312 0.0211614581639878 0.502940276523586 0.580986923347227 0.510428894772194 0.455490228959825 0.116841136629228 0.841320054763928 0.362481833091006 0.524570249579847 0.684701572144404 0.183613904688973 0.246964527636301 0.656293902141042 0.743648159119766 0.340668906872161 0.852137770554982 0.154217620994896 0.264551026388071 0.0388332570716739 0.680779455937445 0.817754627112299 0.684758943254128 0.911818935978226 0.14227183368057 0.0952605277230032 0.663068738323636 0.487844204085413 0.869559036011342 0.54810274858959 0.102349884805735 0.482995874627959 0.976232568167616 0.98207431867253 0.732010019356385 0.761334044255782 0.268830342155416 0.515383948886301 0.433140286693815 0.104264661266934 0.314629053226672 0.566427529500797 0.468728736769408 0.258540939795785 0.817877860115841 0.556268307485152 0.0392518864269368 0.325171155759599 0.0818753959937021 0.950681923001539 0.549322888969909 0.606337061445229 0.654283523452468 0.446750643409323 0.620655609162059 0.0572251644125208 0.634700792401563 0.178431300972588 0.326690168697387 0.817156388491858 0.766139760054648 0.260455268390942 0.687544693311211 0.701280488937628 0.610291117208544 0.320143127832562 0.231958525138907 0.95993883601157 0.151629713859875 0.592557113557123 0.212619518269785 0.271170599653851 0.421582548220176 0.998297944234218 0.0523901287163608 0.247020352997351 0.356512110454496 0.788259556570556 0.834751271074638 0.618084535843227 0.624723722783383 0.249151292475872 0.42461661521811 0.582807348517235 0.225486447783187 0.691787466851529 0.980006864608731 0.62773193318164 0.969905178281479 0.836335964270402 0.677302721878514 0.386145376367494 0.628265401567332 0.923277946382295 0.478942653301638 0.770781056692358 0.66118334468687 0.348230354869738 0.781270974879153 0.214867270339746 0.753004104462452 0.394483038450126 0.902821428454481 0.200494688034523 0.649914913615212 0.412837777750101 0.489475394904148 0.284231068380177 0.408898279361892 0.758866419233382 0.103723229716998 0.338016357892193 0.813443350812886 0.63158088932978 0.87004290859215 0.842517359738704 0.589859611550346 0.559047847578768 0.159685495095328 0.0869600986829027 0.133288252416532 0.303889423329383 0.175938142053783 0.223976668769028 0.155050211572088 0.637702620651107 0.553630731245503 0.0711907900008373 0.321200281854253 0.345750760552473 0.943426964511163 0.982031306936406 0.0834486687206663 0.765087133329362 0.0275280862324871 0.930742251244374 0.663799596233293 0.328505033459514 0.741396421664394 0.450032058546785 0.550158985948656 0.632821438387036 0.780968459001742 0.200127637034748 0.903681566596497 0.0783713580109179 0.520039793448523 0.181783376601525 0.905351338665932 0.407245771917514 0.862214259980246 0.415862088736612 0.295528419427574 0.589312965807039 0.476214069668204 0.646384687800892 0.183672499766108 0.934861863006372 0.907158442414366 0.121807106642518 0.401019416046329 0.127673500382807 0.567131895546336 0.0786393093713559 0.172513474093284 0.0122599878255278 0.35251767759677 0.0149931077449583 0.40236989420373 0.35867480186047 0.563546816168819 0.665167789417319 0.751421748099383 0.119384707331192 0.0933005981589667 0.816067829218227 0.42981193782296 0.688629010650329 0.551995931221172 0.59768565663835 0.681419616478961 0.822783236366231 0.21003788909642 0.478350282809697 0.238575848932378 0.329839317444712 0.711138294111006 0.168690934204496 0.255010120898951 0.86384090321837 0.896894240875263 0.149475822802633 0.189499846871477 0.907170089927968 0.172193444878794 0.520871871849522 0.773296920552384 0.663565756222233 0.247989287320524 0.914880034676753 0.91064687631093 0.230668667252176 0.394954444312025 0.239628062366974 0.850374874619301 0.317610551400576 0.268993893705774 0.901855414134916 0.497175369043835 0.846484050718136 0.393941991839092 0.359465912850574 0.881468689548783 0.787437014051247 0.325233912095428 0.2960754123074 0.769760695914738 0.765982968215831 0.224820733752567 0.110870849953499 0.582144504932221 0.0129835293604992 0.221748637787532 0.663721001851372 0.062349164292682 0.723550085003953 0.862046080864966 0.515682328629773 0.323804517774843 0.556692428328097 0.475358026630711 0.147266883638222 0.342294607355725 0.444215530760121 0.508550123467576 0.149878056065645 0.37783206086373 0.145983161262702 0.317475549639203 0.0697641153773293 0.416619453262538 0.0998103375220671 0.564805970913731 0.683480409025215 0.502447326069232 0.151596645764075 0.463216874524951 0.723983898470178 0.377803735814523 0.0970635723252781 0.893923077043146 0.486991170255933 0.109528709296137 0.839194828285836 0.464035918018781 0.314059329819866 0.328647121093236 0.985807910244912 0.621109673872124 0.0132283403608017 0.0247816944494843 0.716007257676683 0.851750758744311 0.698139541924465 0.294245247722138 0.185016382790636 0.928162389562931 0.742089136047289 0.903400905337185 0.469291361165233 0.680586132013705 0.226259617393371 0.578667441024445 0.827979921700899 0.409468163198326 0.107782979100011 0.890070615184959 0.0937206252804026 0.392894213269465 0.799858698565513 0.465320017035119 0.682353270575404 0.550186949339695 0.136612743369769 0.473514780115802 0.925360916480422 0.35878207257716 0.239823139491491 0.426707547558472 0.138935288607609 0.667433168923017 0.669179164427333 0.580705845109187 0.642516634995118 0.233119128148537 0.71277654429432 0.0707611281122081 0.429678859603591 0.187582833385095 0.822205282412469 0.518675056416541 0.0159690569457598 0.433448344999924 0.828166823138017 0.58743617382599 0.291864277056884 0.958875122123863 0.558633292121813 0.382431353752036 0.586781344346236 0.887202085976023 0.671340229408816 0.897837614794262 0.508117929510772 0.245784782099072 0.799271583065856 0.832393774536904 0.483546838141046 0.840789700234309 0.232643043550197 0.521213631671853 0.166053373869509 0.15220224294113 0.047606106644962 0.253592299409211 0.0541050354484469 0.38676366039319 0.971683245650493 0.0925133589166216 0.588132545589469 0.585996223189868 0.145053272191435 0.244164049862884 0.570655847548042 0.0537213753722608 0.540242218968924 0.555931199891493 0.979546420515981 0.158337658955716 0.242483101196121 0.434613331933506 0.604171313808765 0.514987274648156 0.668123993186746 0.185307980002835 0.846346744394396 0.625017241232563 0.0909368487843312 0.382153964934405 0.808234244398773 0.212345559096429 0.0511363525129855 0.044604844970163 0.962513960869983 0.897286478404421 0.56159227805445 0.555968837465625 0.0246426999266259 0.570681709679775 0.0672114545851946 0.809267465593293 0.672337112831883 0.982064900808036 0.400589330263902 0.178863410565536 0.260911400937475 0.782141253279988 0.437949939703103 0.623430303405039 0.660523009428289 0.670627725017257 0.140020729876123 0.384053204385564 0.880635835968424 0.314872760812286 0.395145845846273 0.866863404531032 0.675482452297583 0.351103092590347 0.475069052996114 0.988230183010455 0.778226194363087 0.595914673067164 0.905966559776571 0.679239711158443 0.805799041374121 0.668930347757414 0.954391371067613 0.0101700888271444 0.785880706757307 0.172327067544684 0.091655464945361 0.523350440661889 0.887995566760655 0.541981025566347 0.320257923528552 0.114526941108052 0.952644501498435 0.177252141833305 0.85123304058332 0.491573830787092 0.697669073515572 0.238973831271287 0.445365110917483 0.977822270179167 0.869553071532864 0.195549394311383 0.680786148342304 0.473913660491817 0.60356800759444 0.348987540756352 0.504492083489895 0.127267949038651 0.756887676990591 0.289540142274927 0.604524266363587 0.553481533997692 0.423923174983356 0.0618839981290512 0.0292547923792154 0.754347829362378 0.144109547447879 0.79827382995747 0.900035745243076 0.383302160464227 0.160903694645967 0.458371540906373 0.729445045359898 0.550296629266813 0.125111201365944 0.92590534133371 0.264460420990363 0.514930720208213 0.236738886372186 0.0563756270729937 0.700291016856208 0.0844744204869494 0.871298049369361 0.197122958623804 0.555125300562941 0.311064692090731 0.749684403578285 0.098015467224177 0.132724526450038 0.363559082997963 0.560592646352015 0.102976966183633 0.17347927934723 0.580154131310992 0.206244017935824 0.358145764651708 0.173594083571807 0.963204814177006 0.868249413010199 0.882969557112083 0.442720132556278 0.471860128077678 0.855806069574319 0.87328063477762 0.64860652357107 0.916527047867421 0.323668574872427 0.982364815005567 0.0284190902509727 0.785727012178395 0.598900589279365 0.0375756185711361 0.273765246907715 0.770039782612585 0.816906087386888 0.664775756113231 0.344132533646189 0.735466617422644 0.547748041220475 0.251163257942535 0.489817239090335 0.125382466888987 0.392942917030305 0.838328202886041 0.324310587730724 0.141721779499203 0.343171574012376 0.564953006049618 0.0242538888147101 0.625082011006307 0.920739405932836 0.895494366066996 0.969743131911382 0.493879776629619 0.779014576666523 0.265899779926985 0.256369639819022 0.422995819132775 0.459234463747125 0.600033168045338 0.817305925730616 0.323427055676002 0.26338239636505 0.926161306572612 0.364590686988085 0.409700956498273 0.586098444061354 0.588837324464694 0.913638155621011 0.799229979929514 0.197240563912783 0.604499485518318 0.408182564994786 0.375029212834779 0.979794940068387 0.100552513557486 0.543466355658602 0.36232303242432 0.14263629729161 0.741513286118861 0.2878050631308 0.684257515384816 0.429163642853964 0.285706157253589 0.0612325035571121 0.57060567617882 0.724288554331288 0.584506714320742 0.0484205050556921 0.948174504286144 0.767309631563257 0.019707709888462 0.207641626906116 0.567432737746276 0.398533699125983 0.43364758384414 0.846375513621606 0.304321801688056 0.663626614371315 0.16616051850142 0.818508611551952 0.892437543878332 0.649626308553852 0.248099266439676 0.41137707406655 0.77574012915371 0.62564881878905 0.357150155445561 0.265529197861906 0.285156390739139 0.106505604067352 0.853255512346514 0.924104181318544 0.758088667928241 0.624420831187163 0.493207939304411 0.765816269617062 0.139121479175519 0.860026416159235 0.394222001468297 0.626373018177692 0.758602280381601 0.167667666331399 0.640321946637705 0.727073867125437 0.182134181105066 0.610290345717222 0.322405523255002 0.760459474131931 0.685091265388764 0.563045734975021 0.286365186024923 0.742131347248796 0.122842125985771 0.0717526758671738 0.720001247969922 0.838153169553261 0.252677755339537 0.566624598857015 0.884545122415293 0.854722310742363 0.465983997688163 0.0563438696134835 0.182116836956702 0.0707215107535012 0.618376278732903 0.89769446500577 0.773685285642277 0.255376909587067 0.776918702817056 0.291414744022768 0.251238456564024 0.0924930890020914 0.3219981527864 0.728250664076768 0.80456280755112 0.555515846204944 0.188146151823457 0.989454303244129 0.723346238879021 0.649713698443957 0.102210229893681 0.403911927179433 0.242074888932984 0.581423503763508 0.306421157736331 0.772235654138494 0.11651182139758 0.874668653928675 0.905410419411492 0.53683501156047 0.408928197873756 0.741677171206102 0.156388914056588 0.346591006342787 0.475115505210124 0.8993310500402 0.0938038416951895 0.939345600462984 0.395899676540866 0.50064517719904 0.659800418254454 0.0531145961792208 0.0306454148236662 0.251770849425811 0.297724330830388 0.906305049923249 0.760883476957679 0.475939302123152 0.669565346890595 0.153724774036091 0.490152268705424 0.444439506884664 0.375096104152035 0.255866705847438 0.663501172233373 0.0698761291406117 0.137723380387761 0.756258699500468 0.833079472659156 0.997475625071675 0.18760932686273 0.480953062186018 0.392465129019693 0.0195982699142769 0.771542643790599 0.0812557635293342 0.778007236274425 0.306048959158361 0.0179095523967408 0.242583753499202 0.393266479154117 0.839382753844839 0.013885368371848 0.54814057033509 0.679180245012976 0.195098695626948 0.539894833737053 0.225345370902214 0.693616738931742 0.202783455459867 0.167589230074082 0.200200297133997 0.939396396724042 0.328636782832909 0.909310944464523 0.767367980233394 0.0539828406274319 0.741879692173097 0.757568778435234 0.427491360614076 0.083983083779458 0.407062012918759 0.434398215166293 0.770550224045291 0.0906631662137806 0.808234269062523 0.596323667655233 0.859441761272028 0.712792924712412 0.764822113497648 0.0520850042439997 0.449375321429689 0.971958112542052 0.521483079914469 0.774044989610557 0.641992418281734 0.391452141781338 0.791220979604404 0.162901432125364 0.627108222669922 0.740496031360235 0.910146075407974 0.203931509230752 0.658237575758249 0.849439542696346 0.976247549436521 0.722535951477476 0.483498387932777 0.302645178167149 0.795358694097958 0.288992739331443 0.886204851497896 0.197445482334588 0.116973633752204 0.15299226181116 0.0420601385831833 0.304314035372809 0.157609625160694 0.793851808349136 0.634472595318221 0.205862701837905 0.615661941987928 0.8098685115017 0.560729942994658 0.354722353620455 0.438350332404953 0.375008050184697 0.585458162045106 0.899573380143847 0.759402827676386 0.621838437207043 0.679288975039963 0.82685478447238 0.331348810174968 0.09339845769573 0.198963325242512 0.262172581106424 0.456656057918444 0.0201305343862623 0.111127752875909 0.175646037966944 0.387623477214947 0.623612977429293 0.614166301065125 0.469073667151388 0.728433826304972 0.499260905785486 0.976009482243098 0.163783498185221 0.239269642296713 0.988669520926196 0.851107410124969 0.572491346648894 0.0270758459484205 0.696962558957748 0.0810067354887724 0.798593432742637 0.939022777790669 0.762133218909148 0.848859460975509 0.503781586082186 0.0825844034343027 0.0704148783348501 0.63257813095348 0.225526620191522 0.330193880980369 0.284308236644138 0.617664462621324 0.98354780463269 0.23790239025373 0.703941037270706 0.268873982701916 0.36396426069783 0.40853720713174 0.143050602192525 0.323683830439113 0.707221801239066 0.802218396400567 0.108997146934271 0.251987304950599 0.835201619856525 0.403820066004992 0.0779788819118403 0.789574612281285 0.64617113038199 0.782592276281212 0.455613623315003 0.26119772241218 0.638230717179831 0.188705904390663 0.59039252188988 0.885074452592526 0.542478559559677 0.0457812184887007 0.577217111790087 0.256070008678362 0.45366819165647 0.586932591912337 0.625839853363577 0.329509609898087 0.501921965833753 0.652843540546019 0.699488427080214 0.819821485097054 0.800366864709649 0.400448294873349 0.370118885394186 0.043816503926646 0.247544350503013 0.573605059951078 0.786236418194603 0.372095369636081 0.862539154868573 0.406662974418141 0.282578183833975 0.921411934534553 0.534435430828016 0.666566291584168 0.47160102316644 0.532342946054414 0.368578321870882 0.769900384249631 0.99946506930748 0.777231865136419 0.241258698366582 0.630224050229881 0.282306028802414 0.441945017967373 0.471873959370423 0.0137063639448024 0.126656847926788 0.490918612219393 0.608498852739576 0.0843104611779563 0.935330902070273 0.202524056197144 0.911712189193349 0.878207224158104 0.8776775219501 0.270435098044109 0.633992062716279 0.229507962591015 0.854793916062918 0.288029080515262 0.700434373866301 0.419758744346909 0.257784858476371 0.55707988408627 0.558790467516519 0.201022503119893 0.320208016776014 0.596391389011405 0.542381164715625 0.974255998870358 0.606682615797035 0.422686479464173 0.564622019215021 0.866284703749698 0.757603922896087 0.80289790207753 0.373771049019415 0.319600858867634 0.325502900716383 0.69472813015338 0.265935475288425 0.550967674585991 0.572440544625279 0.878474220316857 0.471649520627689 0.914259893263225 0.771138543458656 0.582194998082705 0.824487509794999 0.585544327045791 0.0896947874012403 0.0593435795465484 0.716485144342296 0.674463265929371 0.794727433712687 0.157336152808275 0.540522069551516 0.759407624891028 0.194547002573963 0.749225663358811 0.653451198413968 0.0904054016736336 0.542258395021781 0.135362836839631 0.961655593677424 0.178707292024046 0.307920338944532 0.578535829491448 0.624855107041076 0.241102750396822 0.907882164893672 0.806109852339141 0.124661068334244 0.795396428944077 0.887878900999203 0.0633958034892566 0.821679742385168 0.155298800044693 0.517640979827847 0.0429440866946243 0.712244873596355 0.689885216348339 0.386776382047683 0.137638829133939 0.44128741923254 0.851594257338438 0.204124310605694 0.386896160743199 0.496473119931761 0.357840129155666 0.66591288292082 0.173871125944424 0.664653134401888 0.793403487757314 0.507192144994624 0.160382990096696 0.674691244035494 0.894736452945508 0.608266485407948 0.0416552838170901 0.0603967880597338 0.27850313693285 0.681496151322499 0.0946611405094154 0.402682854833547 0.222831269924063 0.418662619525567 0.597005006517284 0.509084077982698 0.393070317285601 0.624867321129423 0.847250462230295 0.745724992554169 0.592922533983365 0.593735950915143 0.782056496879086 0.547588184622582 0.440985131091438 0.987024077225942 0.222272860263474 0.252030061290134 0.157214642118197 0.711766168186441 0.990352139812894 0.411031399853528 0.690090601998381 0.386596691876184 0.938083144463599 0.794402855765075 0.529562080341857 0.737981173873413 0.175509782503359 0.72148448763648 0.717378977315966 0.174326342013665 0.242990496770944 0.616984552182257 0.580852960920893 0.705732878537383 0.0386547862575389 0.0219199567614123 0.290441668955609 0.561607066853903 0.635935278786346 0.0255623108986765 0.844547924438957 0.26131518087117 0.371359679475427 0.545897285861429 0.0129414389422163 0.831858588447794 0.550941026441287 0.459422143360134 0.129136959030293 0.188785094621126 0.607827676725574 0.28797476102598 0.209985620616935 0.643208380807191 0.680872457867954 0.475870248693973 0.507147498535924 0.851176267166156 0.262988513049204 0.617530112951063 0.382433463539928 0.0993587896670215 0.14640010564588 0.938018224863336 0.9633809041325 0.606045630886219 0.568693157718517 0.980582491180394 0.209083717986941 0.437441101414151 0.850398324083071 0.390142972639296 0.860498337193858 0.563500624191947 0.0548384374123998 0.0732219549291767 0.402367557601538 0.0760584408557042 0.0847564762854017 0.281118368506432 0.749439251895528 0.0361055910680443 0.725626942641102 0.0149859995138831 0.730604297164828 0.513966711719986 0.881476026207674 0.0103635141719133 0.839191312894691 0.938551908538211 0.115707358329091 0.620983726012055 0.169090247924905 0.259425366430078 0.225332151823677 0.793277199445292 0.734630960011855 0.0350760138849728 0.668257234832272 0.702081188594457 0.690274150318 0.747262026856188 0.0188708347338252 0.503386124977842 0.225978839730378 0.673791386422236 0.496170756416395 0.42455734891817 0.983614572170191 0.948466421896592 0.759367409609258 0.286707807234488 0.943039372065105 0.452055309868883 0.54376893838169 0.98298481489066 0.160441178106703 0.518803015179001 0.579599626359996 0.403492086534388 0.858206071665045 0.333028516203631 0.172804262933787 0.259227635071147 0.579436673885211 0.764578666149173 0.474369291234761 0.9006660640263 0.89944354578387 0.175045008654706 0.88676794819301 0.446784704278689 0.861616583555005 0.997363074929453 0.737905576482881 0.320215544060338 0.509763137637638 0.8999472141359 0.998012568280101 0.320488495707978 0.524986177908722 0.780726109535899 0.249511309696827 0.215548292261083 0.717122828136198 0.222212950862013 0.611525984844193 0.541265628139954 0.158899399375077 0.810337803887669 0.268815703643486 0.751939289234579 0.828155219650362 0.109781654032413 0.994561596314888 0.474303927686997 0.676304876108188 0.49575572059257 0.87211012016749 0.605465248590335 0.74474593595136 0.386476306959521 0.147741223103367 0.517978624722455 0.924188990965486 0.478006531908177 0.346744896387681 0.264423678456806 0.645531189048197 0.492440738091245 0.436100997014437 0.0290938272955827 0.559189464757219 0.822438350471202 0.250845251155552 0.371936337775551 0.107558402977884 0.964604041965213 0.979520681241993 0.19063350853743 0.844864550055936 0.675933837878983 0.49072941935854 0.282010164069943 0.746942012163345 0.788300531818531 0.0100196597748436 0.0924190373602323 0.131210962587502 0.531454406336416 0.416224232802633 0.901830725260079 0.611327908653766 0.339921739539132 0.44472786208149 0.558351867208257 0.241018678126857 0.449359167595394 0.0718823555600829 0.199239946948364 0.0711080509563908 0.467988744513132 0.688611196738202 0.793853442610707 0.836864690070506 0.952018772016745 0.989223445933312 0.403787576931063 0.406915270290338 0.848277344149537 0.179581053776201 0.56579580004327 0.488880345514044 0.792490230351687 0.181650209638756 0.443486442647409 0.554782068291679 0.16260972104501 0.483182759699412 0.3182226941525 0.768912002213765 0.11707306554541 0.966170963891782 0.55309977279976 0.505663124797866 0.42452396319015 0.752289227279834 0.371473087086342 0.0703048173873685 0.095941008424852 0.311153567798901 0.679552040903363 0.0746713644592091 0.821544750535395 0.538755489957985 0.803413457665592 0.0414945916482247 0.136086001733784 0.316230245549232 0.10544783368241 0.0169230312062427 0.0870214325888082 0.647754640870262 0.621847320536617 0.0702332494081929 0.0113141675852239 0.0269317995058373 0.387025871784426 0.280172317302786 0.293931383062154 0.248451934093609 0.496541533025447 0.698887761500664 0.180337215079926 0.65514433281729 0.388230226903688 0.83438079665415 0.650422045495361 0.515520240077749 0.629183628372848 0.643732662061229 0.907880464247428 0.763673519429285 0.595612341822125 0.881507633379661 0.459584497911856 0.884207476829179 0.847301163063385 0.481058224497829 0.746798220195342 0.385396802739706 0.224460398207884 0.507503751653712 0.0924183767405339 0.06899848688161 0.256302708855364 0.367413969510235 0.789723993008956 0.866024546364788 0.495548499913421 0.919405500662979 0.747974518109113 0.799450364366639 0.614882611511275 0.59548420995241 0.765620799025055 0.586780459908769 0.595394160987344 0.280036291419528 0.649474270595238 0.841830207607709 0.954303200466093 0.808429786907509 0.584293977951165 0.0923711657128297 0.397551127823535 0.0373695232043974 0.807259221586864 0.319657484071795 0.530873186164536 0.498179987433832 0.0429033765243366 0.852686049176846 0.448912368088495 0.30639634807827 0.851641183695756 0.930752483704127 0.668401619652286 0.690942636139225 0.853835233561695 0.760422582924366 0.123675473302137 0.36355782330269 0.801370971384458 0.948958469242789 0.81414302890189 0.407784371054731 0.137018298632465 0.642725198580883 0.83154448406538 0.788310575957876 0.898058454704005 0.96808142650174 0.936549998505507 0.539846324750688 0.8543491857755 0.092977389395237 0.968270894121379 0.0968639902630821 0.98415116662858 0.359050466502085 0.378738773385994 0.57079691613093 0.170444649462588 0.0598652775608934 0.761440405410249 0.974640202701557 0.895686757608782 0.563730918616056 0.584661474281456 0.395573052193504 0.783716729378793 0.268150205824059 0.619414901519194 0.432859416599385 0.23395664294716 0.325625266800635 0.162388297272846 0.248386802431196 0.636803379631601 0.97001617714297 0.234981981653254 0.276493302460294 0.638298257361166 0.228309573794249 0.216617986531928 0.326848799944855 0.431889709401876 0.785244151272345 0.0420776046672836 0.595921974459197 0.951574657170568 0.916104091522284 0.390607202963438 0.215603861764539 0.454908742096741 0.525604015912395 0.354018514272757 0.689571645578835 0.300162952896208 0.187343012760393 0.363903226675466 0.409440407489892 0.423559927272145 0.861080734541174 0.688304427631665 0.484194866188336 0.475171252661385 0.935528644723818 0.14621347527951 0.159628689868841 0.0988458959199488 0.500844630410429 0.549469688993413 0.779279237145092 0.777800688201096 0.0216807886888273 0.782077824338339 0.935339818361681 0.911052586701699 0.286388429419603 0.755714602191001 0.981636118977331 0.909615381578915 0.631011795655359 0.657101059320848 0.379847650288139 0.885657066381536 0.826204498885199 0.223327323400881 0.419032872894313 0.0949514035740867 0.528207875192165 0.206857484923676 0.167464697498363 0.478069987127092 0.992890258443076 0.901568923471496 0.78843665151624 0.14985313069541 0.306286717017647 0.813414167372975 0.933350466787815 0.450911834796425 0.805757516378071 0.649164511412382 0.752756860970985 0.250302583191078 0.165177890956402 0.787554621645249 0.744153775216546 0.585825032792054 0.133459668937139 0.422750979780685 0.112924833230209 0.390319674808998 0.901274126195349 0.98860018766718 0.865802399967797 0.944262357766274 0.420315256051254 0.480271701426245 0.474770860881545 0.227517900147941 0.20712731464766 0.0943325776373967 0.397349959674757 0.403654047157615 0.446244298925158 0.87853905509226 0.34900792776607 0.830572248718236 0.773794331687968 0.173142077939119 0.142440493162721 0.913663309419062 0.543452317374758 0.457190107861534 0.664190231771208 0.431823629222345 0.376724431670737 0.103485369053669 0.431871317620389 0.756168671972118 0.0521111870044842 0.475462011306081 0.990943093176465 0.884688132288866 0.279744424750097 0.940573316302616 0.472483735324349 0.960632981122471 0.2365415341896 0.690246752349194 0.223287459635176 0.102961919913068 0.144242457861546 0.921029046871699 0.779713766782079 0.0119263891689479 0.402672024220228 0.0315893373382278 0.564321480817161 0.595182799333707 0.809232931963634 0.720005268852692 0.161036740364507 0.491819140594453 0.99350544659188 0.740545996660367 0.435350089550484 0.0238675065059215 0.417140491579194 0.648688489971682 0.503895049013663 0.934800076393876 0.957620307507459 0.911639698974323 0.762915222060401 0.733533791706432 0.135466478527524 0.672662828078028 0.70540777389193 0.482256155977957 0.352600149028003 0.243908399029169 0.442466741336975 0.894207282736897 0.546015426837839 0.291067035857122 0.0531604029866867 0.0152628708537668 0.854402455096133 0.817637212679256 0.248671772931702 0.835255175922066 0.936358132739551 0.797907480837312 0.458082239036448 0.772849644136149 0.705203614514321 0.568541702930816 0.193459676487837 0.157360385518987 0.199816256037448 0.435338153908961 0.909588528287131 0.459982791889925 0.56169228333747 0.708621282810345 0.828830047973897 0.147693664017133 0.853796392995864 0.430035822438076 0.240606591349933 0.426875466436613 0.114946633309592 0.378022089987062 0.70543952443637 0.347041754354723 0.041253797612153 0.736352079473436 0.0878361011482775 0.564235633218195 0.618327786342707 0.616001293752342 0.906127424130682 0.989675483375322 0.525628727376461 0.432777122654952 0.429815090172924 0.0798070339811966 0.0912983963103034 0.468332632794045 0.395271603772417 0.638906102858018 0.0301027521607466 0.864386880735401 0.221361110343132 0.294111581260804 0.716620805570856 0.568795671327971 0.0926925989170559 0.941553260569926 0.635239424500614 0.174112882327754 0.114045769784134 0.20309250630904 0.125541389491409 0.530461377834436 0.381181172693614 0.865313877232838 0.279759900216013 0.651505536483601 0.971987234668341 0.329638322633691 0.346226614417974 0.153731790527236 0.618010816585738 0.331959007256664 0.0735053603188135 0.0510516152437776 0.906403576533776 0.520005904994905 0.141256510070525 0.557429130394012 0.217790933633223 0.761697977250442 0.39927078797482 0.42389995072037 0.762801313798409 0.681771702344995 0.719775088757742 0.998658722804394 0.486211175471544 0.477741672967095 0.6822566200234 0.86162727171788 0.16303180885734 0.207602555146441 0.799875352359377 0.0610507054417394 0.0992225272883661 0.780137341334485 0.993897103485651 0.381445075511001 0.812765750929248 0.872549473296385 0.0558326739771292 0.812584320004098 0.923084140017163 0.0124674687418155 0.815723378972616 0.896607142838184 0.381274900706485 0.144349310908001 0.662816727813333 0.452052268621046 0.789675258360803 0.450565775875002 0.155955889369361 0.265122676333413 0.496117917674128 0.586846661563031 0.0982335475599393 0.537221511194948 0.559398769638501 0.235285580661148 0.0787247930071317 0.52061157224467 0.401640194337815 0.867205304498784 0.590223944927566 0.016091558104381 0.823747853841633 0.289471521037631 0.586221743219066 0.529978165412322 0.724768591122702 0.801891696909443 0.0764547101012431 0.849241933503654 0.349408898106776 0.517957143979147 0.426577134637628 0.315788153130561 0.194291260691825 0.929284462723881 0.595502340574749 0.599167396656703 0.28938902517315 0.10435917575378 0.453128429634962 0.0400666736951098 0.12023651212221 0.402754889810458 0.315273788317572 0.217355436347425 0.0209464764711447 0.661842493549921 0.270835326397792 0.720882813839708 0.50030881620245 0.149504424454644 0.681944245791528 0.341488992697559 0.104998493809253 0.685042948871851 0.910375629919581 0.320698212957941 0.172802674081177 0.835001654468942 0.293946268903092 0.819342785449699 0.7272057810775 0.556659903065301 0.781177921316121 0.501443828842603 0.58741744343657 0.218025264614262 0.697249906167854 0.459613678124733 0.46447871346958 0.253631521917414 0.0948217188101262 0.245932578353677 0.145593199944124 0.972418004812207 0.828485366073437 0.313238743804395 0.214666167192627 0.651455816898961 0.531125350189395 0.69233312973287 0.848393516174983 0.581567225889303 0.322122065541334 0.0931400394509546 0.594649140553083 0.223134719105437 0.671874548348133 0.189542335367296 0.946533584885765 0.165013785508927 0.884890161594376 0.714679214081261 0.501540731333662 0.817423740315717 0.896332556928974 0.464358504887205 0.163673447379842 0.941164835088421 0.626793268194888 0.600648190232459 0.461649123250972 0.752267195635941 0.879521037000231 0.306818220831919 0.706654955192935 0.172381359373685 0.684582356105093 0.41649167913245 0.350431405552663 0.429178419667296 0.352165138793644 0.764121553967707 0.0160238512698561 0.0660751059534959 0.566821545355488 0.313079870990478 0.675106895992067 0.418339402002748 0.258324896870181 0.281645157856401 0.362759376345202 0.649369818922132 0.262407226723153 0.947820557574742 0.790592995579354 0.770200651807245 0.350191411820706 0.258157336653676 0.676172732575797 0.388534463020042 0.361349480447825 0.747248193719424 0.325550166834146 0.0817063342849724 0.828649538827594 0.893460510715377 0.0738893348001875 0.424805117954966 0.214481328290422 0.165178307704628 0.935730460123159 0.629801138141193 0.649539858652279 0.86798782074824 0.7722939603962 0.909741036470514 0.939565461198799 0.406218062264379 0.71405789480079 0.83223839729093 0.608931984840892 0.628816188976634 0.307132976383436 0.0158853219007142 0.080226877622772 0.0977630611718632 0.177527840838302 0.6702775403345 0.186649537719786 0.414941410999745 0.350318264863454 0.0862206294364296 0.698578526941128 0.0963858380587772 0.123101128323469 0.857022658605128 0.675352453589439 0.797985204611905 0.256493795753922 0.319755720249377 0.53184132571565 0.128359787208028 0.78547775801504 0.953138140232768 0.904383792888839 0.175786995908711 0.16247611704981 0.869390112834517 0.616535217610653 0.788110612183809 0.433645299104974 0.755167971891351 0.900299661660101 0.818116197688505 0.63643475107383 0.129704675914254 0.130075631854124 0.401927077316213 0.649982147228438 0.846646838614251 0.92125150098931 0.629419005603995 0.932647782487329 0.461995408295188 0.64042212203145 0.988543594502844 0.991918432929087 0.765314482394606 0.555907104329672 0.488944185902365 0.577515378356911 0.124865985603537 0.338184769123327 0.449812712292187 0.289936732610222 0.279787283893675 0.996114819948561 0.950542057640851 0.663336939087603 0.506332439505495 0.998521939720958 0.711828351032455 0.695083170137368 0.255121069971938 0.300666276877746 0.0277072215848602 0.458077672785148 0.773783576909918 0.341524348529056 0.562800889860373 0.640666324505582 0.861790684505831 0.994170193434693 0.166618919651955 0.22417772973422 0.350023496861104 0.19506206050748 0.141532937232405 0.789519226949196 0.38095100896433 0.148259805187117 0.226459828726947 0.200493842090946 0.420323419983033 0.0651396018452942 0.768540034829639 0.368707674941979 0.139204298434779 0.143727758820169 0.989327691998333 0.98150992447976 0.700862090776209 0.967574580444489 0.443223741208203 0.515359539380297 0.17631739285076 0.519494412932545 0.736881534813438 0.682589629285503 0.162381134643219 0.333385961479507 0.934503155038692 0.629797653406858 0.339375060833991 0.206510631460696 0.930595510229468 0.952317293980159 0.51800618335139 0.382493016354274 0.674623142580967 0.133355362480506 0.56181448553456 0.163561586670112 0.115007476245519 0.558569202099461 0.336576590044424 0.251078082949389 0.0196126906014979 0.214357572738081 0.321022469585296 0.929399010860361 0.677498558047228 0.631000370576512 0.643797458573245 0.842800716261845 0.613982969417702 0.306495653325692 0.0718631865247153 0.665145037223119 0.345136699790601 0.8382314303983 0.0464050456346013 0.775644991158042 0.882631865886506 0.86448787602596 0.438486090213992 0.864351276191883 0.437414398640394 0.369612978864461 0.597796916889492 0.581009114729241 0.642780917910859 0.125388041588012 0.0570572148775682 0.607436236042995 0.538573623383418 0.223219779077917 0.494459143101703 0.808601553791668 0.50272576689953 0.439540611437988 0.498633658906911 0.526902033120859 0.5699305041763 0.762053359299898 0.823480087113567 0.870555385129992 0.744237663776148 0.38198514041258 0.237105497573502 0.267767877820879 0.455603334612679 0.817780852746218 0.296047873040661 0.233323643421754 0.543885332380887 0.79627453773981 0.858305209337268 0.308141292030923 0.127321219511796 0.738203172518406 0.0148474991880357 0.277729600362945 0.826703792072367 0.535640125016216 0.981510754288174 0.731573839322664 0.733101605356205 0.0284861247101799 0.304045334649272 0.524063305098098 0.538225083795842 0.939493436363991 0.969700507419184 0.506374724928755 0.272204700906295 0.652464927088004 0.76411065351218 0.078324817053508 0.484087403924204 0.557518641597126 0.493587152990513 0.375355066843331 0.539451105673797 0.283160742532928 0.867002880803775 0.252303537791595 0.941729334390257 0.838025486241095 0.508664246788248 0.0182206528726965 0.572222540124785 0.654293271857314 0.118093863816466 0.228696713303216 0.768094523139298 0.831338422351982 0.0642745922668837 0.0488087530503981 0.566512873221654 0.656801931597292 0.53515255425591 0.664195827676449 0.552343305388931 0.0571334987040609 0.569054052000865 0.990711694646161 0.399545363280922 0.412704525040463 0.587224998187739 0.223608907591552 0.927169881304726 0.397649167843629 0.176440940720495 0.613988046001177 0.324592271267902 0.65714387743501 0.561410089929122 0.0568459576414898 0.357016601930372 0.56125359244179 0.0915605788887478 0.0613821772532538 0.566536355647258 0.360245743286796 0.798948478950188 0.675746116545051 0.721466737112496 0.835551490134094 0.185810772445984 0.140151340567973 0.558458152296953 0.874432939472608 0.165454797563143 0.113011051246431 0.405759338180069 0.422055198103189 0.348328074952587 0.513861460664775 0.923100708986167 0.850775266399141 0.661461638687178 0.80983305378817 0.724931773638818 0.0162202171329409 0.638617625494953 0.486179515745025 0.780146751592401 0.939746444718912 0.369438301888295 0.897621648856439 0.67601700888481 0.529829848683439 0.549496003601234 0.315384184415452 0.150945837858599 0.736535413656384 0.703713671378791 0.135564406062476 0.518367526421789 0.205282021733001 0.35848383505363 0.78719901047647 0.938305770305451 0.584785358684603 0.462466762985568 0.216317142257467 0.141797596097458 0.86938529741019 0.95353010392515 0.693364898532163 0.0375706768315285 0.336711749238893 0.440215566307306 0.480102140449453 0.129221757613122 0.88939355859533 0.387596375211142 0.642915347334929 0.604814013333525 0.597116164886393 0.775581261871848 0.0527650732686743 0.104136537695304 0.0688091259845532 0.0573388172779232 0.136868265352678 0.404877582376357 0.549088806931395 0.94292754846625 0.447808565464802 0.125326450672001 0.143670681370422 0.921902170593385 0.703622170940507 0.574099495301489 0.134991696497891 0.181286118980497 0.550186537662521 0.845246500726789 0.663411104367115 0.207911629737355 0.0736350780446082 0.683606608132832 0.206533307589125 0.963784449414816 0.984422803721391 0.113357258611359 0.667825766496826 0.461990514961071 0.87437923772959 0.218787399616558 0.764645572910085 0.834214587872848 0.257306175194681 0.0196411903714761 0.49100896590855 0.683194494156633 0.741774051799439 0.14041461226996 0.955693817378487 0.464143150702585 0.993322717016563 0.771405163437594 0.0801102035632357 0.179524156118277 0.0966290705790743 0.813539577932097 0.612621193188243 0.960241131989751 0.310189967299812 0.0225675157364458 0.95086768160807 0.749943766652141 0.949444568476174 0.731596651908476 0.101570609419141 0.615622034887783 0.327558491516393 0.86253913481487 0.986512019049842 0.263943836439867 0.609757159005385 0.785439008497633 0.893665030368138 0.421439067199826 0.669751088900957 0.86089897077065 0.587937851790339 0.141624027607031 0.309506918340921 0.649912425342482 0.291932268331293 0.828833337703254 0.480358171381522 0.469607290665153 0.702394234279636 0.334083950447384 0.530506636737846 0.0352168761682697 0.790404068487696 0.150970649821684 0.590214163791388 0.151649331683293 0.107996775319334 0.603231128428597 0.417633013299201 0.37714148208499 0.470562692657113 0.989924831353128 0.707968114330433 0.670220986355562 0.122055732687004 0.932065363242291 0.687302339004818 0.0963821728411131 0.130035682111047 0.865605899952352 0.744323688631412 0.670996990913991 0.612185230287723 0.803135646337178 0.62707527466584 0.624689000602812 0.284735378220212 0.383073170452844 0.92391636617016 0.809202672769316 0.485972877084278 0.399673986120615 0.52204797614133 0.155016274251975 0.123105454160832 0.738528719728347 0.814752858793363 0.553757685939781 0.209919750425033 0.110026560691185 0.636396770051215 0.381782457632944 0.666139611012768 0.792085440126248 0.23812035787385 0.305436351022217 0.911015126383863 0.964831100136507 0.537066705364268 0.861436489082407 0.396647596003022 0.726725323158316 0.939128386355005 0.337903057695366 0.100845696856268 0.659820591358002 0.142969095413573 0.550564209979493 0.26948255912168 0.860634237683844 0.453377185452264 0.790786200102884 0.804025194041897 0.799989522472024 0.173633805578575 0.62707191855181 0.722525623128749 0.238359859252814 0.031684322510846 0.251215636371635 0.994383421465755 0.965832556956448 0.292408040137962 0.75114241222851 0.458069073664956 0.855215441449545 0.716614135985728 0.101638391166925 0.526181029186118 0.919383172362577 0.545741250531282 0.607977057453245 0.521589737725444 0.593507379265502 0.344965368325356 0.225955356152263 0.890697243164759 0.873669222532772 0.551905109381769 0.313587508823257 0.796775603028946 0.271860863796901 0.270608205299359 0.759730417598039 0.807694457944017 0.498208482824266 0.895338416253217 0.459497459307313 0.28279190329602 0.680359898579773 0.741117324593943 0.533057174372952 0.661574217872694 0.34796196071431 0.903500805280637 0.414523044417147 0.72327227874659 0.502777293622494 0.255587914423086 0.558302744855173 0.970736827026121 0.0861841662717052 0.87735281607369 0.426045013999101 0.14378096383065 0.314127760431729 0.307061105985194 0.122733468106017 0.564627813582774 0.245639155332465 0.427395716204774 0.609130662411917 0.123316607209854 0.189657391991932 0.0759491228172555 0.117028426693287 0.725553096376825 0.37005127905868 0.713192473775707 0.832301079635508 0.645354487800505 0.109059603386559 0.039834501137957 0.750657274420373 0.1676886434271 0.314339067917317 0.612031958219595 0.720106315545272 0.464634526134469 0.170371273653582 0.479752719651442 0.797993583371863 0.558310326538049 0.244388435359579 0.171596322120167 0.451367712637875 0.320211039353162 0.363112954944372 0.564346989127807 0.0870364039461128 0.839997765428852 0.228920079518575 0.686681403049733 0.291417686846107 0.534017426364589 0.0733650895045139 0.389387299309019 0.396894854246639 0.161505518499762 0.396858506102581 0.364289737835061 0.535567257464863 0.751102089071646 0.586430180489551 0.586226049924735 0.0463927250541747 0.20878380471142 0.358223528303206 0.768068595314398 0.220415491792373 0.493075632806867 0.540890715166461 0.937670206441544 0.812568569779396 0.586574735650793 0.170458055248018 0.587458037203178 0.121900287903845 0.961056516028475 0.381637103781104 0.732134134492371 0.158817540619057 0.997228909661062 0.299902297626249 0.396868967451155 0.71721838172758 0.176068350980058 0.793688497904222 0.659143224281725 0.253474142297637 0.153333044303581 0.671722156798933 0.251277804004494 0.209401016901247 0.323130980264395 0.906180391262751 0.135448086515535 0.0207482801890001 0.097871595271863 0.339587670888286 0.097010316834785 0.68213379155146 0.946391033250839 0.533289672399405 0.753536822102033 0.979175834071357 0.809769125808962 0.156219187579118 0.850952148591168 0.573399340994656 0.466365256160498 0.132440725979395 0.638746220443863 0.742473598732613 0.0565886112325825 0.131323848341126 0.152591521281283 0.983743147756904 0.543502816287801 0.465068411056418 0.0389117684727535 0.353795999533031 0.686555624608882 0.706120433642063 0.969672599579208 0.698369332009461 0.643933945922181 0.30489496280672 0.733648128933273 0.201930756089278 0.0700023844907992 0.459693610342219 0.452618534262292 0.13068442148855 0.335158507626038 0.20473235179903 0.734354610068258 0.33319783722749 0.599255468142219 0.817040436135139 0.0989754988555796 0.209019769493025 0.632006503597368 0.441322275795974 0.0950456200214103 0.624338311811443 0.0214377555530518 0.0516978414542973 0.643474805781152 0.720675281982403 0.563599290717393 0.0687905062362552 0.879924711594358 0.59241016670363 0.200883213784546 0.398038899120875 0.248812738249544 0.149475473822095 0.997378745861351 0.674280285106506 0.065415650291834 0.135563462846912 0.196072176839225 0.949940193218645 0.131724319644272 0.0691222313698381 0.613937545244116 0.86183891965542 0.359432045142166 0.926859511982184 0.462881145796273 0.0371389201376587 0.0156446564849466 0.339821928800084 0.0960732655948959 0.141262548540253 0.429394661285914 0.475131182365585 0.462913336830679 0.294567873084452 0.648487719669938 0.893989788799081 0.936716849235818 0.712528786091134 0.972906981406268 0.919690290449653 0.657202586610802 0.487376686567441 0.907605414567515 0.361976329709869 0.311786507854704 0.0193166317860596 0.246603574806359 0.349034480482806 0.948988285411615 0.395521597617772 0.609666885300539 0.97083660434233 0.345071780651342 0.0222540496150032 0.40693391908193 0.283323139266577 0.703021554457955 0.352214890879113 0.713636817510705 0.299776051035151 0.535111085271928 0.98703120942926 0.953331849786919 0.630609629468527 0.328008046217728 0.543408776405267 0.013740242025815 0.827969104226213 0.724990839171223 0.443927329077851 0.688893963866867 0.55011966155842 0.577642767548095 0.401399207371287 0.980420184342656 0.172196149823722 0.155343062717002 0.34953460970195 0.40049488031771 0.6617086705775 0.0157812099880539 0.677379490681924 0.716182635379955 0.175041977087967 0.21894371754257 0.180096889885608 0.27893230877351 0.969169657540042 0.440904652122408 0.0309596448298544 0.314911607140675 0.759874914442189 0.435531413753051 0.639750195501838 0.881936179636978 0.83593047654489 0.537374271547888 0.214627845257055 0.758006655657664 0.0932520868675783 0.902718189454172 0.306211357966531 0.959587885139044 0.0907434582454152 0.0224141927273013 0.509340403496753 0.874636724283919 0.249721209965646 0.589844268853776 0.536825548517518 0.684562373626977 0.711496569425799 0.436777469741646 0.705367013933137 0.560428887349553 0.0662001237366348 0.847793788048439 0.547554480109829 0.122430149388965 0.462273330264725 0.454934958510567 0.262074535323773 0.528128098333254 0.0338917170790955 0.594690055870451 0.942295020548627 0.238058543831576 0.880751896891743 0.513560200564098 0.615583493283484 0.65248593138298 0.357555570332333 0.254391320317518 0.635318387455773 0.700802652982529 0.90039687970886 0.198751033972949 0.668366043230053 0.501114087873138 0.82126098832814 0.525156418175902 0.115776524473913 0.993184517726768 0.405541561415885 0.645212887218222 0.592001868924126 0.849957796544768 0.761697523852345 0.168042272967286 0.36711755894823 0.911505260560662 0.0134590222593397 0.150936890679877 0.655387011901476 0.961667864238843 0.488453684074339 0.804176122823264 0.507215242481325 0.251414566803724 0.614397863021586 0.797001901464537 0.187582138190046 0.0621693053934723 0.954136910086963 0.740327839106321 0.919480168668088 0.51361982506467 0.424813619342167 0.0129952646954916 0.323423626031727 0.336798534060363 0.471231730531435 0.344472120061982 0.8140460740868 0.202972066993825 0.506120865559205 0.896101774992421 0.763608490801416 0.631068070034962 0.453705042295624 0.289192639947869 0.481252002050169 0.850945827525575 0.0601123839034699 0.245061685664114 0.935768601805903 0.54870146434987 0.75927332293475 0.310838237374555 0.776783654263709 0.625886674842332 0.401594816725701 0.410031951630954 0.374186973429751 0.7006818769034 0.174797247224487 0.666593396584503 0.154861926429439 0.263272049594671 0.516362747095991 0.511664705623407 0.0990125219104812 0.232418659897521 0.251438437164761 0.934852532732766 0.470367273928132 0.647777432019357 0.139416082368698 0.557813368800562 0.737771672373638 0.913654077108949 0.541561599134002 0.985485295716207 0.499476566538215 0.177938482365571 0.0802661289437674 0.14767871248303 0.609779064103495 0.427140236634295 0.350311031700112 0.458090909381863 0.981065642980393 0.351450426650699 0.272060819272883 0.083459529990796 0.278319794912823 0.531775743882172 0.732419589969795 0.350786159944255 0.347073147159535 0.840073564969935 0.557330315425061 0.771659495106433 0.915435688912403 0.883657974700909 0.26684551142389 0.595056623506825 0.580283484843094 0.883651963660959 0.567756047931034 0.677279798882082 0.731202447502874 0.387367960994598 0.0202840109099634 0.599812885259744 0.823769322829321 0.145952788200229 0.488362389013637 0.952337844185531 0.515165586185176 0.228766966727562 0.75533272966044 0.632217537246179 0.673998818241525 0.140422697139438 0.368690037594642 0.235135111270938 0.418310855440795 0.475351252628025 0.697971487971954 0.135943382792175 0.106002549543045 0.852609952518251 0.716111314268783 0.969847828838974 0.975998355895281 0.121922807290684 0.585081309624948 0.748573937132023 0.263609593759757 0.59831519194413 0.627274982812814 0.89017995903967 0.712742127759848 0.0893219371931627 0.981965537474025 0.832193904577289 0.140491170394234 0.0197636733204126 0.100406774997246 0.229113048699219 0.0217550489353016 0.0304231146816164 0.766209577599075 0.235569648053497 0.896095325537026 0.981194028633181 0.671638522944413 0.01414164617192 0.0340020184405148 0.827778751708101 0.059924635370262 0.782385349031538 0.652480045966804 0.848256327176932 0.262763813147321 0.196121758352965 0.678617671097163 0.50721299047349 0.297686158951838 0.306241061419714 0.477697054399177 0.9976858810056 0.577857443133835 0.725666378133465 0.805993498216849 0.707607586777303 0.149469086832833 0.609330924917012 0.624532813371625 0.86804833752336 0.665244233442936 0.781884749126621 0.378272852557711 0.541426187078468 0.198208341575228 0.762319576821756 0.0500255557568744 0.305584322919603 0.826422278876416 0.732502956672106 0.0968068298324943 0.335074765896425 0.65067624992691 0.611804115187842 0.582404232199769 0.156224364431109 0.810365486757364 0.171059974760283 0.0325291580636986 0.126854440984316 0.101098831065465 0.484134658747353 0.798385679833591 0.719164029366802 0.0398211914720014 0.344479640200734 0.0911057830252685 0.762960370322689 0.121263724120799 0.36126922391355 0.972705260282382 0.199717066963203 0.614541473353747 0.103100075637922 0.582099105652887 0.451082001302857 0.194129079477862 0.769660722671542 0.832133766978513 0.805824334856588 0.325272921388969 0.827881292977836 0.258438058535103 0.655422202232294 0.887582058014814 0.0710832318477333 0.445040101238992 0.578328179847449 0.741765513762366 0.748372588269413 0.586695077694021 0.217267437009141 0.854227175586857 0.0861218635644764 0.0661207069223747 0.391001822964754 0.727510159413796 0.753943934177514 0.679156335005537 0.22751246006228 0.931471506932285 0.812320705314633 0.343228604900651 0.974877845770679 0.539803437716328 0.965393467291724 0.914400320819113 0.937355962374713 0.393256080732681 0.270414706424344 0.34640252803918 0.629783347740304 0.408029189892113 0.183851683062967 0.140962453167886 0.860850116261281 0.875299273286946 0.80387750312686 0.128964691264555 0.895117025212385 0.211868936505634 0.71420736519387 0.377030816068873 0.492519052643329 0.606980109489523 0.742448201754596 0.61863813999109 0.919435129663907 0.336110302947927 0.683982774808537 0.351800461276434 0.623866821585689 0.705831268460024 0.484216676088981 0.672704090301413 0.172418541244697 0.401905671486165 0.144864468418527 0.447110688751563 0.324347773289774 0.535400925134309 0.873794403050561 0.0372529408847913 0.248697280320339 0.0439406119170599 0.133758258207235 0.287349829773884 0.964502756702714 0.0651763335452415 0.513581963442266 0.746000290715601 0.442910675238818 0.190019495950546 0.33861273405375 0.523239647869486 0.387928715094458 0.0879402752965689 0.849144618643913 0.234015031263698 0.989321336818393 0.23253836483229 0.674998527392745 0.0263748067431152 0.799719769735821 0.665481181547511 0.689673202142585 0.618468232569285 0.885259649464861 0.384687749198638 0.921243059763219 0.70024990123231 0.198123842414934 0.68887649709126 0.0161675411253236 0.464581869950052 0.912826613825746 0.314701401225757 0.646656963154674 0.470112534039654 0.950271971598268 0.234832697506063 0.536783947225194 0.69218613977544 0.26739274333464 0.382189064447302 0.903624842045829 0.795609635077417 0.518380975080654 0.917875147701707 0.759915927953552 0.0336908506578766 0.511448894352652 0.289877434731461 0.113364019014407 0.707042416944168 0.23595887015108 0.254887571565341 0.436330382106826 0.191891860442702 0.698618927777279 0.880132321591955 0.812676189246122 0.775357455627527 0.680658001259435 0.210054144582246 0.346013461530674 0.956720550162718 0.291226289230399 0.267191858242732 0.789884611647576 0.403821279138792 0.122157625092659 0.665855341700371 0.993344422269147 0.947542985507753 0.917077690290753 0.391397071084939 0.38065340947127 0.173419296415523 0.187293097940274 0.693275300429668 0.0582636433653533 0.81682408986846 0.22488828061847 0.377402022334281 0.483071355384309 0.683558063879609 0.27393980240915 0.441481106658466 0.760115990382619 0.0177518470771611 0.202416629891377 0.0857283359137364 0.446590834294911 0.712412387712393 0.937866427318659 0.2495820785244 0.312992257282604 0.123034941882361 0.0934245044598356 0.652039438674692 0.307196218157187 0.89943182151299 0.579347885767929 0.916656465018168 0.496578838676214 0.472885976193938 0.286749439644627 0.575890205262695 0.582853244759608 0.470423505664803 0.706920616051648 0.809365319136996 0.712812514184043 0.777646732232533 0.444660044605844 0.790459226544481 0.482446669156197 0.751680187550373 0.269773061908782 0.209446585599799 0.118710710429586 0.864353615560103 0.940982430982403 0.654719483817462 0.10243691672571 0.0156006960012019 0.353343587294221 0.466023133527488 0.127369812170509 0.606156846419908 0.419712651716545 0.916212206799537 0.542465474864002 0.53531914451858 0.478585355777759 0.210621249251999 0.316862353491597 0.2633298452897 0.0604740621242672 0.5914407928125 0.485522738751024 0.600907566675451 0.376762471932452 0.522719319039024 0.25815640311921 0.711509779745247 0.79307745995 0.285290671258699 0.75981425867416 0.807184413205832 0.855073339755181 0.907599111020099 0.385849006834906 0.122483968688175 0.379662818301003 0.732841880624183 0.761537033834029 0.277810854511336 0.498092856858857 0.72394893795019 0.632525399625301 0.539283258712385 0.362023905853275 0.157650198182091 0.6034063809691 0.498782200375572 0.189216337525286 0.982448201761581 0.171774175879546 0.23079356333008 0.288724625927862 0.0434899157681502 0.772216079188511 0.837652538761031 0.339601737754419 0.506175324041396 0.29342574184062 0.929337453597691 0.390008301418275 0.503570023200009 0.590668519395404 0.733964742333628 0.39752710187342 0.857220701142214 0.242030314852018 0.157626458976883 0.0775150798610412 0.750424334290437 0.463633554982953 0.536320431919303 0.68417992945062 0.904214656497352 0.0552097923518158 0.22545232859673 0.382168872903567 0.569518397345673 0.828274349020794 0.76662241604412 0.0273191114305519 0.941081262086518 0.564676294447854 0.585447688479908 0.938987310396042 0.839471138352528 0.342772908234037 0.741067431441043 0.718407253543846 0.865422435535584 0.389194798509125 0.0390469041559845 0.945247524294537 0.463340716515668 0.317058606408536 0.239109911322594 0.677618875887711 0.848457589601167 0.307317213674542 0.146607744917274 0.0993045745952986 0.194877642963547 0.0455224411212839 0.369050629688427 0.383252894969191 0.442635570929851 0.225782941326033 0.771867972253822 0.735032432847656 0.48949253667146 0.908940108616371 0.424824512652122 0.480059625215363 0.137671312214807 0.102362939766608 0.823602593112737 0.993273306535557 0.400933227303904 0.593591121917125 0.531689681224525 0.963819728028029 0.324556915436406 0.761108453001361 0.165863852312323 0.399937365467194 0.533886162890121 0.424210538328625 0.42751803641906 0.65654416452162 0.186282643922605 0.300789494207129 0.675359664624557 0.635528702859301 0.759380475864746 0.330185908365529 0.113229004805908 0.691952376982663 0.544505529345479 0.741132493030746 0.518308463655412 0.645291660008952 0.421747287318576 0.22604671690613 0.338739892512094 0.577241748801898 0.409651862496976 0.463513020700775 0.650471702613868 0.397392331766896 0.997983999589924 0.703736028491985 0.272188685142901 0.124811765460763 0.210349108050577 0.0387338727619499 0.752274315392133 0.54581418170128 0.450360552498605 0.247582090650685 0.776099379954394 0.561761294354219 0.658099098252133 0.66172186821932 0.679841368359048 0.916647931821644 0.252423418369144 0.15691202113172 0.473677595672198 0.529266151299234 0.806573106485885 0.416512970863841 0.435836338379886 0.978880582475103 0.954255527972709 0.427186376287136 0.882575453436002 0.162677253619768 0.0547843014029786 0.77764997563092 0.918220748845488 0.649727214409504 0.673641406849492 0.358193132190499 0.610068214763887 0.914881023762282 0.465830990006216 0.6234748671134 0.676260204063728 0.161528474458028 0.228338815551251 0.722092124067713 0.79500599924475 0.844261366699357 0.660037376040127 0.0849316903320141 0.162097315962892 0.928647056915797 0.656329919744749 0.502398153927643 0.919505469757132 0.865411914947908 0.567847640339751 0.244442123502959 0.7956704243063 0.888005118086003 0.731081668196712 0.625101521646138 0.0950185512099415 0.195877658452373 0.814248359710909 0.118756771020126 0.526561860076617 0.80390163810458 0.746231340034865 0.928835093115922 0.10300003969809 0.807818967008498 0.870275612226687 0.961370047843084 0.183112650618423 0.278658802537248 0.262286608307622 0.67652284096228 0.862122194119729 0.355851365593262 0.433616753695533 0.944710609898902 0.16254189043073 0.822546474277042 0.0649956012726761 0.228598202827852 0.829661570172757 0.121556193092838 0.910638104313985 0.916486786024179 0.566218763303477 0.707970488043502 0.701618107093964 0.307379483189434 0.294479082892649 0.117640372135211 0.241410548926797 0.0322120894212276 0.073400800540112 0.630833730525337 0.767905681103002 0.695145383870695 0.240859957674984 0.367316751461476 0.866783005776815 0.771519300588407 0.567235347300302 0.464975963714533 0.401720581566915 0.367656768225133 0.122440704090986 0.178159740176052 0.867967380031478 0.357447674262803 0.094288855032064 0.654947710866109 0.853016729904339 0.883863678905182 0.830048449675087 0.443110785842873 0.469880287952255 0.711694199594203 0.640502229891717 0.714942764921579 0.0636565597192384 0.957609868748113 0.325832105767913 0.9921743202582 0.72354350854177 0.476696184438188 0.797328458505217 0.0414346555084921 0.533636810071766 0.54522136149928 0.47059865701478 0.0604051313223317 0.269403909188695 0.207154090490658 0.609299562769011 0.767235880957451 0.569591887253337 0.212478849838953 0.974548140990082 0.614731525988318 0.4096553857252 0.953318904775661 0.523461368298158 0.0341139358538203 0.141536213131621 0.665445973698515 0.776092017479241 0.125781964089256 0.96637913424056 0.195508158134762 0.256090882509016 0.516826720640529 0.712545399086084 0.959636736190878 0.445794758053962 0.334485866078176 0.70398962601088 0.65511674122652 0.59356558802072 0.783882395788096 0.935317856098991 0.459049954924267 0.783668184434064 0.0738891725265421 0.493483857286628 0.0325958979409188 0.852257247753441 0.407299001361243 0.193423217702657 0.381016954530496 0.656585255942773 0.132589653308969 0.187152899964713 0.368159803156741 0.360353136169724 0.402546312625054 0.725413898320403 0.870381395511795 0.242408211447764 0.0753850672324188 0.73450408553239 0.521045741376001 0.462335667777807 0.383043214830104 0.91101143465843 0.503466298761778 0.236376659325324 0.234715377348475 0.799228797683027 0.516895876182243 0.269598577863071 0.561880274589639 0.283840526656713 0.214000282590278 0.715675238652621 0.626343409230467 0.30441820168402 0.289868955933489 0.109035905210767 0.240580479814671 0.525556959321257 0.836526179178618 0.864249647941906 0.549247012671549 0.630266527200583 0.601673597858753 0.597464595907368 0.953348065165337 0.556157490720507 0.317463639352936 0.840015160057228 0.525793409079779 0.0991744168405421 0.529756681018043 0.519343982727733 0.20663598992629 0.0259125416819006 0.777786903008819 0.862058889879845 0.16501358358888 0.403410124513321 0.092570255191531 0.593866756611969 0.421096766388509 0.81918807735201 0.341244245315902 0.74379860522924 0.204326668377034 0.0931251377053559 0.0735784634435549 0.91245081987232 0.273782937270589 0.612127609082963 0.479168354966678 0.682993383633439 0.502071789125912 0.46630726730451 0.231074635805562 0.64089839886874 0.263133586149197 0.602572715559509 0.287129281219095 0.605965695211198 0.414015819414053 0.307806196031161 0.661780959337484 0.601497772058938 0.31464206231758 0.865568780777976 0.868336810737383 0.486909592943266 0.300293377803173 0.179693927082699 0.523304849143606 0.121533621842973 0.408509966365527 0.148795261885971 0.770871501890942 0.48123292959528 0.195013650867622 0.962190411884803 0.186051809201017 0.0380337408138439 0.637824180207681 0.554094657767564 0.411870421445929 0.362908746008761 0.464352533032652 0.229698387717363 0.792447651729453 0.18796994315926 0.160702612013556 0.593153324448504 0.800679544126615 0.707412396015134 0.95296665755799 0.0572997139394283 0.538032651916146 0.588601382733323 0.106420134492218 0.355689556640573 0.545458893235773 0.183234294999857 0.726556869975757 0.875375320157036 0.834213592563756 0.120564044418279 0.710525969953742 0.764211301435716 0.889548798692413 0.473650902810041 0.187698395962361 0.36952778566163 0.158873704127036 0.420590744377114 0.900307070466224 0.23771379831247 0.0812335274298675 0.103905957217794 0.57980831510853 0.274478620523587 0.807522013843991 0.995087724353652 0.81185858546989 0.826441107690334 0.132293748699594 0.141959267440252 0.865214894919191 0.466960089569911 0.607336395569146 0.161253849132918 0.906266829639208 0.665913529018871 0.907697171324398 0.374099880657159 0.533722537348513 0.613488229804207 0.238713379073888 0.405839385648724 0.38986067481339 0.202684790317435 0.253651420492679 0.878357952171937 0.36180681736907 0.589382511589211 0.115505834515207 0.315419278857298 0.714500549645163 0.527165956222452 0.849811660367995 0.817746147161815 0.632055854147766 0.24208014208125 0.164530588760972 0.073697933035437 0.325715439545456 0.857266173721291 0.200475455611013 0.0740013550175354 0.843141028990503 0.898975309790112 0.136590729244053 0.459738016617484 0.503263012757525 0.175098302869592 0.382387878475711 0.520483155243564 0.3313713781978 0.141933443341404 0.0605389024317265 0.908497958572116 0.227157587422989 0.686216118638404 0.814956674491987 0.940427833830472 0.845617793200072 0.374540360942483 0.687229396770708 0.220230486467481 0.877921428920236 0.113313492441084 0.331148783473764 0.786497870772146 0.566686838867609 0.928806114131585 0.0790673356154002 0.571500818866771 0.314676309893839 0.565658502017613 0.773641382323112 0.0241942772222683 0.959799554743804 0.607590369959362 0.854371839314699 0.532711006193422 0.476890830984339 0.15925040810369 0.328864940730855 0.816225218058098 0.2308721673931 0.635441574589349 0.142613210638519 0.770962556998711 0.380998422142584 0.52108482927084 0.307628244538792 0.922935987175442 0.448030434336979 0.245924606430344 0.352883691797033 0.661559044595342 0.97556646597106 0.59644434784539 0.380149544500746 0.936699850149453 0.2884441373148 0.615993435466662 0.216955941221677 0.415737376138568 0.587542002520058 0.205547095732763 0.0992780963308178 0.571305914619006 0.261730804475956 0.903189119789749 0.812927443017252 0.901511875295546 0.110533428185154 0.367029918732587 0.290274532863405 0.58969815503573 0.872200839894358 0.564327896619216 0.786127746484708 0.368996570666786 0.947972702947445 0.450391482224222 0.922972667934373 0.907368821667042 0.538641699021682 0.933911789306439 0.0539822560735047 0.930931519709993 0.856112337799277 0.411918533737771 0.919442754911724 0.322372364802286 0.718769401758909 0.3589787496184 0.779592569114175 0.671347297993489 0.331869661093224 0.641921778074466 0.614412677176297 0.0128142751823179 0.487815699244384 0.943823881237768 0.947941126201768 0.888548211327288 0.107894184952602 0.412744828374125 0.266867122401018 0.948453561249189 0.32600846034009 0.245240971534513 0.0230831658304669 0.122013338466641 0.542156305997632 0.101505944062956 0.73815116427606 0.133419542629272 0.555866441873368 0.265521087176166 0.228868626095355 0.0269075898453593 0.611434675953351 0.0812165675288997 0.200100879401434 0.34538911921205 0.757281567682512 0.193849647718016 0.917174873303156 0.171142575964332 0.863433568247128 0.336007443354465 0.768191386675462 0.81886523347348 0.256240469766781 0.793870932436548 0.762684556527529 0.518904578427319 0.31315972391516 0.234316435197834 0.550041688380297 0.162923028350342 0.240828750424553 0.413516647471115 0.990702141707297 0.474044979286846 0.145026497270446 0.205274835361633 0.55250169806648 0.0611944667529315 0.15486552918097 0.732644754794892 0.670739575584885 0.267840838034172 0.555674889821094 0.328891988797113 0.515875421820674 0.877314282767475 0.983495573494583 0.235815071959514 0.983612973636482 0.209198064894881 0.773584972638637 0.109101416971534 0.739170360094868 0.383360203949269 0.417083163342904 0.0441508694645017 0.098595699693542 0.279130082775373 0.090564531267155 0.255169474079739 0.24610675490927 0.363508986542001 0.230984922682401 0.919800978363492 0.479128889509011 0.851679219116922 0.0222401814418845 0.782471646110062 0.0669759547268041 0.225842933708336 0.289246622903738 0.629739785564598 0.231317644969095 0.860953684418928 0.661983201627154 0.906017373094801 0.789464536120649 0.554384357023519 0.358752547532786 0.340562943334226 0.0277992097660899 0.0717212404194288 0.528742106771097 0.494900807477534 0.3260020606732 0.437893769741058 0.135235746609978 0.666207457992714 0.120486303817015 0.735107239154167 0.697319891748484 0.793135139932856 0.214236088786274 0.822188785360195 0.823396506274585 0.848328968144488 0.607545965758618 0.189434336954728 0.330497851097025 0.980987977522891 0.335282619304489 0.88973463290371 0.257464387849905 0.0491192710469477 0.0583794152387418 0.53076751743909 0.0728494790568948 0.900751607592683 0.870366501142271 0.0614289581635967 0.801299556919839 0.984292948385701 0.412751022432931 0.750871654271614 0.601047519627027 0.753549037112389 0.62230007622391 0.435420242245309 0.474038502401672 0.444871761924587 0.100534044327214 0.25582858744543 0.346224758182652 0.776350676137954 0.586658455943689 0.663730092863552 0.785993214948103 0.443804174906109 0.0916412950446829 0.741315721643623 0.270516467443667 0.305868583933916 0.556793449204415 0.736453869766556 0.200460586135741 0.648890669103712 0.667106084953994 0.402913452137727 0.0718160375021398 0.65492544895038 0.366281327356119 0.658970236426685 0.373733906103298 0.677447729054838 0.655432220324874 0.0426557153626345 0.279453725805506 0.722658693511039 0.889735103819985 0.656170429876074 0.7206408426282 0.485731098572724 0.777273873726372 0.837894356457982 0.361565976541024 0.783370336689986 0.156811857493594 0.154331295527518 0.136491650810931 0.0563247395330109 0.823015290675685 0.602402922466863 0.342786439412739 0.643871805258095 0.240228951764293 0.118305603724439 0.849765294822864 0.411772796791047 0.772652961332351 0.42535326150246 0.71195532716345 0.398683842355385 0.626735168006271 0.762263145931065 0.412826605762821 0.760115942207631 0.108601852713618 0.251935439619701 0.0993105897842906 0.525091351284645 0.152968815113418 0.788764699215535 0.78486180390697 0.984135134269018 0.750296123127919 0.678724160641432 0.80990458373446 0.0333706695423462 0.431352943680249 0.942677536411211 0.936705319969915 0.352086689858697 0.443792461699341 0.425148412000854 0.160500135994516 0.358448244570754 0.686285516668577 0.587171516574454 0.386295485021546 0.0567804486467503 0.258902233308181 0.786559441403952 0.463074376827572 0.060117158528883 0.974376994618215 0.873591534025036 0.359514217381366 0.775168026501779 0.665252818041481 0.121592285840306 0.37521461347118 0.386018420981709 0.917202407037839 0.0859808461531065 0.974946801236365 0.524284966518171 0.144830995791126 0.181026163285133 0.440415779945906 0.45404483316699 0.836193683475722 0.752606935796793 0.600396921939682 0.893975621894933 0.434412601739168 0.297292038679589 0.822197334922384 0.91905724874232 0.297914344740566 0.314324467438273 0.233402770725079 0.553909946563654 0.92939781247871 0.329126677056775 0.181198690596502 0.342411320600659 0.753961207561661 0.723630039349664 0.342523359488696 0.597038171885069 0.404224475671072 0.938967287810519 0.258875127846841 0.874983136795927 0.529676985526457 0.968549618700054 0.918883807028178 0.120343847379554 0.880602301796898 0.883396420010831 0.841682559105102 0.19029052889673 0.59286409772234 0.141415674239397 0.246372862712014 0.822435617174488 0.896264332616702 0.77646947058849 0.775088405462448 0.021452186612878 0.667992252111435 0.879999705068767 0.0603011176036671 0.206839456644375 0.469061434392352 0.0257665085396729 0.299204310732894 0.871406405521557 0.934187527266331 0.917341744317673 0.973309958039317 0.177302568368614 0.0956936967046931 0.0577115317201242 0.0983409549645148 0.114275667513721 0.370546607605647 0.129202967293095 0.52359687094111 0.905244270330295 0.899683674820699 0.461567529111635 0.196224029934965 0.265718888377305 0.081527659476269 0.143894881312735 0.0465161818754859 0.33501708706608 0.0433992541278712 0.994160642800853 0.696086214657407 0.19610090803355 0.531069644459058 0.0174021381512284 0.978058726391755 0.0601495247450657 0.251926219756715 0.743172739981674 0.331689603039995 0.943457157781813 0.566393605088815 0.825004521927331 0.288562983167358 0.386158953185659 0.444971808698028 0.398118199300952 0.390815371007193 0.358487221363466 0.183655740863178 0.40507601907244 0.0145747695141472 0.276088494255673 0.0353142226068303 0.910891752082389 0.778100269783754 0.653756060574669 0.289353850055486 0.340128967133351 0.330387916695327 0.815989995033015 0.948956451886333 0.842113591791131 0.454679272640497 0.942786661980208 0.714638940712903 0.627611344270408 0.544555426877923 0.97090465877438 0.713500289132353 0.268308576603886 0.207641500590835 0.979335728010628 0.770639443893451 0.992450443618 0.214683210535441 0.892177029906306 0.366985400663689 0.302481476329267 0.15277612161357 0.154998132796027 0.839650806856807 0.297667826639954 0.43866415603552 0.50561903500231 0.338926062565297 0.0951515259337611 0.368492166320793 0.0406520127132535 0.0181689857738093 0.84047798800515 0.146696515055373 0.568436792097054 0.204576468369924 0.530620748302899 0.886607707808726 0.515058960414026 0.873252761743497 0.219111957049463 0.280924155535176 0.689459672844969 0.155122021348216 0.998492896656971 0.623968880414031 0.92923452116549 0.46761828645831 0.808315108767711 0.0304206439270638 0.85554105020361 0.163587245498784 0.952931212752592 0.81260571039049 0.181255451336037 0.891717354077846 0.0933789786347188 0.139786997509655 0.056281718115788 0.236197037613019 0.605574718760327 0.820179816654418 0.035955444611609 0.26394947798457 0.391637867195532 0.333205572885927 0.844476924187038 0.440204577799886 0.611645232231822 0.329645297403913 0.54633352905279 0.075387433108408 0.440785066818353 0.201338875184301 0.543146128903609 0.17783846025588 0.109371013657656 0.0239348256355152 0.623630337943323 0.723846243857406 0.119160620565526 0.960727321580052 0.0468634626897983 0.352467699158005 0.115180257570464 0.39852945119841 0.554354648729786 0.364406956341118 0.0227509220666252 0.591837868355215 0.81491433029063 0.714311862967443 0.412618708789814 0.64469804180786 0.327672172964085 0.78236048451392 0.420911791028921 0.929044567416422 0.774717363084201 0.640453885945026 0.394856733679771 0.0779389953264035 0.547645259767305 0.755075475913472 0.493233162483666 0.519735593290534 0.819625850617886 0.724025845516007 0.869467257817741 0.974062679556664 0.872535751261748 0.342546696697827 0.625237321637105 0.436166502782144 0.323081628561486 0.933366522658616 0.683388284617104 0.83450881857425 0.242379484863486 0.842073319344781 0.0805266058049165 0.745693940431811 0.264728922098875 0.857105426462367 0.535552398823202 0.250711449158844 0.178741811132059 0.786977643868886 0.331606060694903 0.872350319507532 0.632168295031879 0.299692552946508 0.220562383555807 0.537475716779009 0.271244413647801 0.183266324452125 0.102346008678433 0.423024432309903 0.058243821777869 0.682420625663362 0.123415331360884 0.711876676077954 0.946742317890748 0.201413736119866 0.884412930016406 0.244884513039142 0.333595740965102 0.687610188936815 0.396268113320693 0.981112982167397 0.186126967945602 0.681741876034066 0.0563769319467247 0.0924018554855138 0.091169018575456 0.607007098316681 0.0762410056218505 0.502926691868342 0.816983387728687 0.414925304187927 0.298778693468776 0.955736561962403 0.453351026203018 0.68251244004583 0.777786198132671 0.322942345680203 0.255403853696771 0.354777291086502 0.644880006115418 0.833863281565718 0.757095868545584 0.373191741325427 0.661384478951804 0.758612904464826 0.613503224211745 0.792516401356552 0.069519133574795 0.474837548434734 0.127301150595304 0.771781433147844 0.330964428165462 0.247567960857414 0.915101964401547 0.572033460671082 0.952862263279967 0.704475001466926 0.308087473653723 0.84815283439355 0.695482190889306 0.989287882631179 0.103903723650146 0.313754759475123 0.4873920085188 0.163854038584977 0.960261880196631 0.898199000507593 0.0423118203971535 0.639890447875951 0.424940870462451 0.21174543104833 0.968424859079532 0.213129916598555 0.545829545604065 0.224069524561055 0.0323885737662204 0.421458821480628 0.147133253135253 0.444641556013376 0.562659388624597 0.722215647273697 0.775435933144763 0.559269909611903 0.441164481502492 0.0950878153182566 0.0266120385960676 0.657070506466553 0.759639875818975 0.764451386216097 0.238088649972342 0.138831088412553 0.775686426488683 0.296549754077569 0.780018327445723 0.0512671688129194 0.043358605040703 0.049108702975791 0.867934996758122 0.606993434829637 0.660152733931318 0.452159218017478 0.347614600837696 0.722917706912849 0.493977751417551 0.255717568069231 0.399183711567894 0.25031502662925 0.361977481299546 0.452005620249547 0.537565421834588 0.96095394018339 0.846869363957085 0.559065521575976 0.651097439471632 0.54338715759106 0.220903537617996 0.552378239862155 0.725377263200935 0.0311263856105506 0.338953764105681 0.692957416730933 0.830287830962334 0.184659137821291 0.0197718420927413 0.324616090226918 0.689086883028504 0.421368084466085 0.595404907236807 0.219533119164407 0.12673018086236 0.733265714952722 0.0196370496274903 0.139776967891958 0.452303232650738 0.318955266538542 0.316181426076219 0.891582488773856 0.683752026755828 0.785558830066584 0.58408096751431 0.15449004848022 0.145235256552696 0.940058532436378 0.729055613735691 0.0494450879446231 0.758984409922268 0.149982173049357 0.501838576542214 0.150950553705916 0.135972692316864 0.0976339959981851 0.382686922065914 0.199631468767766 0.0162136510433629 0.0343388489703648 0.714760864232667 0.868652637202758 0.955197670317721 0.677003329999279 0.617516504554078 0.799618959308136 0.82426566443406 0.69013246514136 0.733945134421811 0.369872931563295 0.976129414453171 0.642803380594123 0.711342635585461 0.837876864096615 0.509149798578583 0.963056203788146 0.319169733289164 0.269218579547014 0.283755557502154 0.668567750754301 0.762465384302195 0.680991327692755 0.514153919955716 0.0462557478877716 0.768470409063157 0.0326919839926995 0.91203376784455 0.284776837292593 0.251600555451587 0.77054497228004 0.178404655593913 0.789370100696105 0.20440592107363 0.0983346707792953 0.405097397472709 0.0984862339030951 0.445263054855168 0.918784552952275 0.533684989209287 0.353483121192548 0.926460578129627 0.538768632048741 0.773181447410025 0.348107103195507 0.0951718806731515 0.723638277964201 0.992619190691039 0.744947877435479 0.0537611506250687 0.648682374744676 0.514406373491511 0.759507921529002 0.0944352952414192 0.304420883578714 0.544819232884329 0.0399382094410248 0.988909452422522 0.210806471710093 0.189189782042522 0.829314768342301 0.814944950451609 0.521096307134721 0.526304438754451 0.77132261110004 0.31887479333207 0.245386181322392 0.738824704552535 0.295452520539984 0.646694149635732 0.278058241144754 0.694217394138686 0.648025826639496 0.582214851710014 0.490171191103291 0.635090103703551 0.680594469744246 0.299217695773114 0.112360779950395 0.206796594504267 0.966271910546348 0.17562101601623 0.109872440143954 0.983951612457167 0.567206806500908 0.397687374758534 0.446961365418974 0.529346076140646 0.96314131539315 0.751864483619574 0.831787324501202 0.725152118660044 0.702378062005155 0.893048279413488 0.321923645671923 0.683420151795726 0.335657272732351 0.498637943945359 0.581876663982403 0.0749445980112068 0.233697656283621 0.589122407219838 0.579398596282117 0.344555719802156 0.251140763680451 0.0163584537641145 0.669584571246523 0.102580193981994 0.444190119951963 0.205698639955372 0.152803081627935 0.154174676334951 0.414975714818574 0.764247599330265 0.243209349059034 0.719658182582352 0.758909649024717 0.0347862235805951 0.0130683297873475 0.713925547734834 0.0965236023906618 0.824947983622551 0.779402819129173 0.606244775915984 0.673841186221689 0.538267402641941 0.752284614697564 0.130933526055887 0.403234364637174 0.841616255568806 0.818443373397458 0.613540401011705 0.437251296800096 0.994495888627134 0.876968281010632 0.330675067056436 0.99276214616606 0.875723253062461 0.903133739067707 0.378116893293336 0.828876372489613 0.494254300515167 0.0688743168860674 0.686222241932992 0.868145648464561 0.685280102123506 0.779365531227086 0.62509185483912 0.73038486124482 0.343576007189695 0.491009923876263 0.926059322657529 0.267788320151158 0.122653873574454 0.0258384752878919 0.87653904001927 0.94220890764147 0.213961711020675 0.924437282320578 0.582170459495392 0.838067225373816 0.312271192495245 0.940289524591062 0.53479559487896 0.574460087856278 0.183768631457351 0.328299042971339 0.249571253443137 0.424536013160832 0.470720300935209 0.749360879256856 0.394213414564729 0.181023627759423 0.796340734092519 0.586734341923147 0.95975849674549 0.328606447342318 0.0726287774485536 0.872274259268306 0.150503608060535 0.530523188419174 0.732798506768886 0.925533447940834 0.343435688891914 0.2779501947877 0.287270070663653 0.254777851761319 0.393610337700229 0.448338998365216 0.549967463861685 0.352570194327272 0.970160439105239 0.586490566569846 0.509019638749305 0.245526505152229 0.349823863627389 0.703371230652556 0.403302736470941 0.795223856454249 0.255252258994151 0.33480366287753 0.463837960537057 0.983935538146179 0.311161731039174 0.708959411990363 0.83270294109825 0.754280891714152 0.238238898541313 0.870737645172048 0.267757110365201 0.456912101989146 0.596806833285373 0.807537267797161 0.769900730925146 0.675760756670497 0.924252806690056 0.43857974400511 0.910301032909192 0.768110069599934 0.182336268036161 0.729175838222727 0.944310137443244 0.0309166895668022 0.334468546363059 0.997953836054076 0.863035863433033 0.805456505219918 0.614255876347888 0.973947689777706 0.578224245421588 0.360426030228846 0.507629640044179 0.444953722332139 0.901925774973351 0.739364649823401 0.808900571335107 0.17809880411718 0.94286446251208 0.542190291953739 0.206569628533907 0.262302621074487 0.2104701694916 0.213311105265748 0.351836687254254 0.638369644396007 0.319821099240798 0.54293121175142 0.404220452944282 0.468323557686526 0.875051102484576 0.834507880429737 0.353756672607269 0.869218697005417 0.338692870035302 0.154718401152641 0.860229618491139 0.570934701899532 0.153597555647139 0.506441218398977 0.431339580076747 0.810875114516821 0.924084586084355 0.217618628065102 0.936160525851883 0.569288629849907 0.605254236378241 0.0474864674033597 0.33478497789707 0.72900535362307 0.715668933261186 0.927101026338059 0.0291444320091978 0.304500698240008 0.743420723616146 0.253853367278352 0.0423639699374326 0.852410046830773 0.218869858600665 0.848646614656318 0.110681345453486 0.405873789505567 0.148147951622959 0.62470067139715 0.153613753968384 0.530308003653772 0.431902184188366 0.386744339917786 0.433022696387488 0.265414751146454 0.858478222778067 0.364695068357978 0.430195871735923 0.0500500035262667 0.229831987333018 0.0808978985087015 0.993970605379436 0.469657173675951 0.536459970197175 0.475930993435904 0.146189074763097 0.534709069833625 0.195034701724071 0.206688230745494 0.680059543200769 0.635213158067781 0.285329441982321 0.6538452578336 0.941240487569012 0.820386106795631 0.4420681410213 0.284857676075771 0.860185730154626 0.404467067394871 0.936867137451191 0.252471777298488 0.381533603160642 0.0904965054173954 0.634434093821328 0.603190740500577 0.519864485587459 0.90456393991597 0.638202033007983 0.334715174182784 0.970439338174183 0.369824820193462 0.964319298970513 0.920170479833614 0.668177829082124 0.888928462273907 0.78017259943299 0.595556802283972 0.787253283173777 0.793024388630874 0.836249191896059 0.585730847923551 0.683267115070485 0.691721397966612 0.232723683409858 0.784288181553129 0.639650551185478 0.612209971717093 0.403630078602582 0.0106594144017436 0.829384151850827 0.548719909146894 0.47739016197389 0.750722742385697 0.176836088111158 0.606975961599965 0.177430347800255 0.341219201697968 0.855353586340789 0.354220116226934 0.125823826079723 0.638963896248024 0.341083785493393 0.355769053208642 0.419022240974009 0.644681266769767 0.221450667416211 0.195422047071625 0.187877422056627 0.916834670524113 0.532210853002034 0.685175334892701 0.679295697179623 0.163422081815079 0.838744055840652 0.090698361385148 0.503942142485175 0.516359471196774 0.984495682106353 0.252999634796288 0.0803182012657635 0.945829544770531 0.0797779480437748 0.279790051535238 0.491718321407679 0.666405956693925 0.972376095568761 0.145130191743374 0.0776434632088058 0.382086974962149 0.764350410979241 0.772666406072676 0.917858117728028 0.155233707798179 0.431899875246454 0.714482927280478 0.379737076703459 0.962270521589089 0.732345127803274 0.898153731692582 0.0731435334240086 0.197639195807278 0.472132778689265 0.95071212134324 0.472360989833251 0.224740206608549 0.968219602049794 0.703731084216852 0.122953459767159 0.647144031880889 0.547630917681381 0.259877119662706 0.37401247855043 0.381622644599993 0.173875932840165 0.543822833055165 0.672799146238249 0.513776573338546 0.598003035075963 0.623354780927766 0.0774288830510341 0.315664858582895 0.217541497834027 0.647778472045902 0.765593307241797 0.147597672471311 0.693409940302372 0.928793918252923 0.786727743376978 0.386475792247802 0.72438631313853 0.290179736011196 0.547856400599703 0.258199662414845 0.934378161919303 0.238823671445716 0.0311245574965142 0.404379833324347 0.442031795873772 0.420837209692691 0.281014724283013 0.649282670598477 0.26919430027483 0.696058285611216 0.85713250357192 0.0718363869399764 0.112392304833047 0.778572280483786 0.868642381923273 0.290104370736517 0.900138639872894 0.738697763457894 0.717869530085009 0.255526887546293 0.391216837158427 0.865679340302013 0.104772551960777 0.0428559363773093 0.114177002832293 0.259672356368974 0.297990278895013 0.583860964097548 0.799044375529047 0.188310941171367 0.824977123958524 0.0724442400434054 0.484901663572527 0.964830278626177 0.974908381567802 0.0258632614347152 0.53422329998808 0.676890700103249 0.939801752371713 0.0972669145721011 0.154981168746017 0.797935920676682 0.551391687784344 0.14725511188386 0.989396208818071 0.974002478800248 0.800696897725575 0.21096780306194 0.5991303044511 0.337753921530675 0.742551298304461 0.304883711757138 0.778315562885255 0.485766184024978 0.311331709916703 0.530370985651389 0.150612367130816 0.720538618990686 0.537601964753121 0.967411966577638 0.689902241020463 0.23476239221869 0.60001096629072 0.150507614652161 0.933476974999066 0.95729340148624 0.44311784198042 0.433085999013856 0.197339285528287 0.868228957771789 0.405468421180267 0.365636031683534 0.615563128862996 0.843767082788981 0.309125335321296 0.377540185204707 0.259698103249539 0.191166488719173 0.257012066198513 0.22368696720805 0.424615035355091 0.289443254075013 0.850465222084895 0.353421795123722 0.0693804062041454 0.20514513745904 0.387407554842066 0.458238741594832 0.750896279758308 0.311091544230003 0.607834791180212 0.59459906760836 0.493073677455541 0.583792892147321 0.920306992998812 0.0496786469733343 0.919890648843721 0.724960022852756 0.416421038003173 0.261172706685029 0.64791569423629 0.967288948863279 0.0820718614337966 0.16969777509803 0.159218186642975 0.961590294209309 0.24171518150717 0.365420397899579 0.53224880751688 0.657410894338973 0.950450044334866 0.757559135139454 0.0966137481667101 0.854991876310669 0.857898296415806 0.0312842522817664 0.721404280890711 0.110548743221443 0.150243567309808 0.466681643668562 0.773201624662615 0.226908832527697 0.890935352770612 0.0190507883694954 0.766855922518298 0.0756698284368031 0.643501782161184 0.789564817084465 0.572078901440837 0.634490871618036 0.619474029517733 0.186468731225468 0.141299556843005 0.735872528811451 0.105422281806823 0.752615774869919 0.530893159883562 0.608380488406401 0.384555126221385 0.218964243314695 0.736383957024664 0.828773516584188 0.477757153043058 0.0129890787042677 0.716880060078111 0.0819582622754387 0.418371544862166 0.340086985051166 0.452140143027063 0.515705125310924 0.924883118327707 0.417521145213395 0.760421652155928 0.378101067233365 0.96425240304321 0.28591828163946 0.645689713112079 0.694126719359774 0.202139065430965 0.988734585281927 0.83353819812648 0.964197666805703 0.716192775638774 0.577465910250321 0.940301628960297 0.56698960138252 0.328798511340283 0.479506356909405 0.360677060873713 0.272007340656128 0.308688130243681 0.283662881962955 0.58807805276243 0.704461301791016 0.589175192716066 0.724580433217343 0.905890562003478 0.427299656199757 0.892339119610842 0.922141798518132 0.110953113010619 0.886357224606909 0.559635373142082 0.38513411997119 0.609516162357759 0.803559367028065 0.167258689261507 0.746989221577533 0.822500751141924 0.125197907586116 0.816873983943369 0.541060940681491 0.358933649761602 0.596441306367051 0.124236262668855 0.796764563580509 0.749314055473078 0.227320068520494 0.404531810891349 0.350935426112264 0.209667285364121 0.0983904802356847 0.848373400005512 0.0670110763679258 0.707213871728163 0.943937319274992 0.254428722779267 0.218122443708126 0.625515020941384 0.276149327741005 0.687659672948066 0.491112378477119 0.317777382999193 0.687387581304647 0.114819483610336 0.394296954374295 0.699846197364386 0.940769107753877 0.10325489414623 0.796660912903026 0.381377709589433 0.107821202611085 0.816703934532125 0.78495731393341 0.110671581604984 0.0852215343434364 0.973166184511501 0.0724522705143318 0.32897320214659 0.410004837641027 0.99765739483526 0.665257852904033 0.999226638842374 0.633074620310217 0.363205536208116 0.0805682976846583 0.125137890770566 0.429198707330506 0.415646915265825 0.226239535338245 0.269525571549311 0.712003244219814 0.463725297679193 0.534682104056701 0.211002921937034 0.320886946427636 0.633084795374889 0.763259593704715 0.426135680940934 0.786002665774431 0.873911121136043 0.204111907274928 0.761672227373347 0.976872618298512 0.194465819420293 0.308916354065295 0.826159932180308 0.906042139648926 0.36583087392617 0.780255215850193 0.542680341997184 0.94645266266074 0.0566587189794518 0.693692968590185 0.358368378968444 0.378059257797431 0.593541529569775 0.0879468464571983 0.46737147861626 0.442246967961546 0.692972071839031 0.0730466009676456 0.97862158451695 0.691219968944788 0.690868246119935 0.418814575425349 0.495145279639401 0.148232304644771 0.617544493991882 0.0720461069559678 0.258412380113732 0.569711236061994 0.986009309357032 0.412000431448687 0.832913895223755 0.682131492060143 0.135291974197607 0.407487017277163 0.362544119432569 0.305603160723113 0.372241397707257 0.798274397454225 0.735663976750802 0.839757875653449 0.0763484644284472 0.916603362581227 0.843704559952021 0.673785688173957 0.0906743190693669 0.334762071727309 0.663574228105135 0.314620272701141 0.566102212562691 0.760959209192079 0.941422084916849 0.247526203976013 0.595054104577284 0.329843259956688 0.400720892008394 0.752241802345961 0.964749166928232 0.757810065746307 0.207949111491907 0.609241511677392 0.59993037783308 0.873736473203171 0.329766797260381 0.833860120226163 0.698936133107636 0.245387417736929 0.0671862032846548 0.937027531119529 0.511864490988664 0.543209317661822 0.716550536702853 0.0314255988504738 0.0889874056936242 0.537188833339605 0.572804621914402 0.816582667483017 0.354065557264257 0.84888917895034 0.421150537973735 0.594679308468476 0.297419473510236 0.820387194075156 0.736552195609547 0.913273916749749 0.399513907318469 0.921523562206421 0.523602825046983 0.717783032469451 0.896503910522442 0.053732758499682 0.946378888774198 0.787837195151951 0.806565214085858 0.0267483892571181 0.328127539551351 0.800936986654997 0.0504429929540493 0.22725495161023 0.178344782842323 0.0291864793235436 0.947714148936793 0.202247726076748 0.0176696441811509 0.977184457534458 0.508171556110028 0.769052315209992 0.846364462187048 0.796934358978178 0.378503453319427 0.914162923926488 0.138662018405739 0.0928145708423108 0.3934790189052 0.828864563393872 0.394577841064893 0.218735597212799 0.135070836709347 0.907419060342945 0.714021659372374 0.514522658924107 0.811024669043254 0.179699781842064 0.341752372735646 0.783996340008453 0.536414061277174 0.682463366098236 0.462671677949838 0.872228464907967 0.295482526873238 0.675075358201284 0.601315550971776 0.61489956910722 0.240266043739393 0.464965560913552 0.26411335615674 0.766909313544165 0.0360308108082972 0.13822510283906 0.679002233359497 0.0501741403294727 0.544441110396292 0.886657602805644 0.121877124262974 0.479773854641244 0.326374626902398 0.581633689394221 0.862669227567967 0.739607808813453 0.637858452678192 0.49397642188007 0.984081448891666 0.292588701646309 0.809450684755575 0.0783921080618165 0.468765157982707 0.124359807081055 0.186086801299825 0.665830961237662 0.0400580206373706 0.7770353480638 0.480781908438075 0.455066488676239 0.192692893866915 0.76420275809709 0.8151744738454 0.771946759796701 0.739009740303736 0.943231192652602 0.677539844242856 0.639744889338035 0.201150924731046 0.220771028047893 0.398240636379924 0.955890773097053 0.610685721996706 0.746071791849099 0.293997065164149 0.745726586016826 0.657583038785961 0.199592191630509 0.342434612861834 0.62895895451773 0.0213255719095469 0.734218302280642 0.561990617902484 0.322762511444744 0.747927677729167 0.700588974319398 0.42384669453837 0.606584656913765 0.254569329896476 0.604284699982964 0.63902488301741 0.594928462132812 0.644769767681137 0.380185529373121 0.995058057550341 0.40343118919991 0.89286935266573 0.672934782572556 0.190336566206533 0.527990830733907 0.0455909565580077 0.51985771527281 0.862967769354582 0.353268206114881 0.337408235101029 0.368470959875267 0.94404335311614 0.23860154325841 0.375918255278375 0.0148219542275183 0.666287462818436 0.959485019783024 0.602641118050087 0.65955674132565 0.413357843807898 0.995880798762664 0.477997481233906 0.274289768806193 0.257831546724774 0.222244343666825 0.334317928990349 0.379288847621065 0.399635613013525 0.295310393951368 0.767454395329114 0.637641275450587 0.0484695059340447 0.498907660262194 0.932433478240855 0.358950827256776 0.183634835223202 0.357596187840682 0.343651536121033 0.987726202788763 0.0760654976847581 0.39007217384642 0.909959096752573 0.387471835950855 0.575998866830487 0.735869693171699 0.0970386833744123 0.156780852854718 0.771066449242644 0.557537247515284 0.426810571039096 0.432918422662187 0.435256224849727 0.216922197984532 0.131310135987587 0.128991490849294 0.698464483374264 0.421533371007536 0.264794391677715 0.409064938083757 0.316723542218097 0.813023571711965 0.220555222770199 0.140112632079981 0.83823589891661 0.464288806742989 0.605133367176168 0.402513079950586 0.687138166711666 0.312288126810454 0.768638335547876 0.557830775876064 0.296924007583875 0.0265216715377755 0.315588860579301 0.315099609687459 0.648177989991382 0.804663543987554 0.685908315498382 0.650902583629359 0.53041392500978 0.950701261456124 0.06389050045982 0.133161288041156 0.343336413609795 0.0397893332829699 0.810797474875581 0.4989086175384 0.569931841089856 0.711989841661416 0.514594879685901 0.255718010633718 0.0580464094341733 0.860886436975561 0.644932713240851 0.316831852500327 0.850879186303355 0.816439149582293 0.614302160986699 0.0777059583854861 0.776290498431772 0.713182395752519 0.813063299020287 0.853457351487596 0.563902099563275 0.659939032448456 0.273193556854967 0.45002307840623 0.584018661580049 0.50639072594 0.285862154089846 0.269610166137572 0.857864368315786 0.15502986397827 0.145366545151919 0.361420081930701 0.438765227161348 0.0921136473491788 0.736740495734848 0.922316583830398 0.589062913183588 0.49324556765845 0.882688374917489 0.796787103021052 0.920762125856709 0.839167130894493 0.135504512565676 0.782242245113011 0.674449106170796 0.134403976160102 0.572276543134358 0.419252776273061 0.31193592753727 0.577692621976603 0.371830768857617 0.387001477261074 0.0873265637457371 0.603670447443146 0.294153237873688 0.810906003674027 0.393437700208742 0.748646418361459 0.877519499920309 0.582812821334228 0.15994296920253 0.483226734243799 0.503990397918969 0.386148206936196 0.215651918735821 0.305976175279357 0.279558532452211 0.795689485927578 0.796218809189741 0.237230386275332 0.953242905389052 0.878538652404677 0.981410695298109 0.581654418238904 0.400992465482559 0.442051047889981 0.27115108901402 0.756196818843018 0.424684095929842 0.310530108765233 0.703942814213224 0.783791493733879 0.354680671191309 0.0304559243842959 0.415295016337186 0.185288609277923 0.298386886056978 0.869420019821264 0.20657764286967 0.472231292852666 0.460268470032606 0.676962940688245 0.186173136641737 0.870811714101583 0.605551799682435 0.908123707601335 0.234211115222424 0.995731889642775 0.222134205962066 0.184728549912106 0.67073372681858 0.288846707111225 0.460044112657197 0.858699638021644 0.538038087622263 0.548438845661003 0.557463927948847 0.860682892578188 0.56928136856528 0.0284914216538891 0.162349278298207 0.979755859780125 0.574617238817737 0.721167558678426 0.28449301907327 0.144363180925138 0.505257265502587 0.176290161535144 0.366432207270991 0.626067563625984 0.89505646164529 0.163092019525357 0.763429852412082 0.8628309915727 0.568057316560298 0.675622980582994 0.32732100518886 0.0377420209744014 0.423655418858398 0.0619055042276159 0.398846895790193 0.41859748855466 0.828334739941638 0.193872873364016 0.329862085774075 0.0177279190905392 0.444320397337433 0.823417960971128 0.0694546219636686 0.747500425742473 0.854742352920584 0.134391596340574 0.77319553225534 0.0149035568954423 0.621906854449771 0.801670227958821 0.853027749299072 0.887238262626342 0.401903921281919 0.774180004049558 0.248678247742355 0.302069447869435 0.184355102933478 0.940585742683615 0.64444286281243 0.262765391857829 0.573578777613584 0.107165656269062 0.41100285974564 0.218189817927778 0.324517170609906 0.81113719498273 0.271822544396855 0.344397082100622 0.576118919593282 0.0565969782369211 0.780523323721718 0.602586914503481 0.367761728616897 0.730882367347367 0.579088434642181 0.672345045800321 0.370838533283677 0.358167844009586 0.81617948501138 0.692927219541743 0.682359708044678 0.61724958676612 0.925642586648464 0.205079846058507 0.839088813576382 0.428909083909821 0.335855652955361 0.49878789954586 0.759041050109081 0.266473146423232 0.418511316408403 0.95597906263778 0.236660520187579 0.933937634150498 0.93422266642563 0.285910572488792 0.776362079549581 0.532161879092455 0.149288688097149 0.786351887879428 0.213936077777762 0.901068764056545 0.127367589205969 0.0765581941255368 0.691720547412988 0.821626149439253 0.577187208260875 0.382873487200122 0.587310337990057 0.406102577366401 0.538709433055483 0.47097596329404 0.992112825692166 0.670951528938022 0.745829546570312 0.329405599867459 0.150526407507714 0.31658100533532 0.376150642894208 0.370283292799722 0.345841376783792 0.926835767705925 0.874013765901327 0.705971335279755 0.441058591033798 0.444736022555735 0.959220765910577 0.739893179466017 0.342476218072698 0.583783550348599 0.76123071028851 0.284881809439976 0.473655876819976 0.448826616378501 0.819613648976665 0.979003138032276 0.176267806496471 0.297812380648684 0.512868866198696 0.512617896406446 0.653679059194401 0.1905310564721 0.751309564225376 0.60809142856393 0.457108448490035 0.458083767266944 0.0208202197379433 0.0503088717116043 0.237999070540536 0.0601766716968268 0.871022415135521 0.663914340066258 0.947762481127866 0.253258743165061 0.812808459093794 0.341658740842249 0.548758180832956 0.40505320971366 0.0391156689962372 0.69066380599048 0.251652580059599 0.234345631315373 0.0681315682828426 0.0155894043832086 0.46354265131522 0.822985315460246 0.350207511256449 0.180407800197136 0.669393494951073 0.785492223189212 0.0529965799045749 0.0863936631614342 0.775470667080954 0.914445999236777 0.342157103260979 0.812865176037885 0.523609665664844 0.675052133707795 0.718327018907294 0.453230812549591 0.570199137593154 0.38787725890521 0.466825044243596 0.494077012178022 0.344130889242515 0.773882342320867 0.107910799100064 0.511904275000561 0.376302385348827 0.0825692442175932 0.715215315956157 0.527000815358479 0.0609994361898862 0.232238908181898 0.539836502354592 0.955393031882122 0.168907632217743 0.365125856250525 0.102347881740425 0.845445118136704 0.18571033773711 0.60102940191282 0.69105713241268 0.401064975294285 0.307566621813457 0.747802493753843 0.0455799081199803 0.416963548073545 0.130450285973493 0.712060766539071 0.624070588878822 0.956354139728937 0.630589861588087 0.978473910659086 0.225433045232203 0.805447325003333 0.934846113703679 0.933834729148075 0.199768724841997 0.477169758866075 0.673011024908628 0.783767340315972 0.913058249773458 0.518815102491062 0.965479178663809 0.664063268087339 0.682199969924986 0.0183982178126462 0.574473669284489 0.789597559019457 0.847876097206026 0.768166475135367 0.856338542650919 0.261996611934155 0.110125162906479 0.440818367952015 0.028139013084583 0.890000175975729 0.909412360191345 0.16550078692846 0.345497438714374 0.694655861908104 0.883930641678162 0.678842189824209 0.70559597928077 0.0316410682862625 0.536507247609552 0.221748289267998 0.166297387562227 0.884627729151398 0.429852218797896 0.385872505856678 0.96938920294866 0.451482909868937 0.354087730206084 0.659798039931338 0.416355507802218 0.467032219744287 0.709026441609021 0.0182531977281906 0.473467533129733 0.334004790412728 0.608842697916552 0.789391105221584 0.442834380117711 0.590708046166692 0.91784930493217 0.104940270071384 0.0404098204500042 0.15707482723752 0.158765810132027 0.495693504323717 0.714134966023266 0.480810575783253 0.541863971177954 0.201980659845285 0.194464557650499 0.846103814984672 0.333019950275775 0.813986515048891 0.793605670807883 0.334412462147884 0.831607190151699 0.121718466046732 0.627464087391272 0.90482820300851 0.947184293214232 0.320099019366317 0.23459903382929 0.38221876836149 0.595098576776218 0.197211675746366 0.33251209692331 0.634275925422553 0.279525533507112 0.398327065305784 0.634535387842916 0.879696374826599 0.0495605772221461 0.12904054336017 0.921664660293609 0.19883898767177 0.984304717604537 0.512767877823208 0.912425647403579 0.643437987873331 0.557483415307943 0.284005860220641 0.0976774175674655 0.480266115432605 0.59883266646415 0.145725494916551 0.716864362638444 0.234847801171709 0.622561484775506 0.72168004028732 0.818801183558535 0.529659056363162 0.923297502892092 0.749531756401993 0.89373141043121 0.30899069821462 0.0224223066400737 0.647847621825058 0.0359767255093902 0.0136962483497337 0.170258669804316 0.747417756309733 0.0240654455474578 0.131570958141238 0.192278955464717 0.703983436331619 0.612832756992429 0.717971345502883 0.467569523458369 0.511069472292438 0.213830476820003 0.305895980750211 0.983456784561276 0.674628624157049 0.618359371847473 0.859390137277078 0.057633637834806 0.977389346682467 0.879573925761506 0.368664955482818 0.462837662452366 0.985156334075145 0.776968302309979 0.668060933509842 0.875150667738635 0.777494098194875 0.25173148999922 0.129460740131326 0.391948756761849 0.751344031931367 0.842553465394303 0.459327454613522 0.711636856836267 0.539673826943617 0.761653842967935 0.923395529082045 0.71151442321483 0.0427705737552606 0.891238011559471 0.214724857467227 0.50164906904567 0.351331074154004 0.345930098977406 0.234731361763552 0.638858219224494 0.749137006858364 0.563102067441214 0.897227582752239 0.583399065074045 0.827452460206114 0.959556322684512 0.216747416129801 0.5454939365061 0.721093693051953 0.602720399789978 0.523042667717673 0.29180782311596 0.0519227488082834 0.202312245985959 0.497949424705002 0.891220344016328 0.036163908620365 0.514007908941712 0.0495106252911501 0.318030005032197 0.363775280821137 0.361607892008033 0.48208085664548 0.645069342118222 0.416928931463044 0.593723761260044 0.918093162805308 0.798531886774581 0.973904819109011 0.89738847568864 0.521335891955532 0.641375966980122 0.137485950994305 0.904603787777014 0.492102214752231 0.418555657221004 0.503519319831394 0.42481978551019 0.922953668779228 0.13666935866233 0.141945341641549 0.173862514607608 0.414186507316772 0.714458592918236 0.563023106330074 0.765403541813139 0.882127278291155 0.660167476860806 0.111017318284139 0.802112839468755 0.48567702940898 0.25627714845119 0.820847484883852 0.873445936762728 0.121525603358168 0.13582476605894 0.127701093587093 0.965035964159761 0.847423456769902 0.585668540836778 0.486899121913593 0.838389816391282 0.623468714545015 0.847234074205626 0.0662062723864801 0.388263512593694 0.482412375248969 0.578286906790454 0.0217923266952857 0.211026844391599 0.925046600957867 0.0259307711897418 0.561561128660105 0.838572106629144 0.073911029449664 0.883610875005834 0.256949608593713 0.179256343289744 0.220348758369219 0.365107621902134 0.539534521012101 0.944503109620418 0.498480069437064 0.509925122924615 0.806853631287813 0.326883006491698 0.182929959075991 0.281967673960608 0.970707969286013 0.418460587915033 0.748084094771184 0.785214753695764 0.0780086273164488 0.516761444683652 0.38763463168405 0.504804507740773 0.244322655063588 0.312577440897003 0.102409565318376 0.247838653582148 0.166490631271154 0.0230832677124999 0.120321956342086 0.880217146221548 0.105142353083938 0.69008325842442 0.151518017037306 0.081964110811241 0.763087087369058 0.976276138180401 0.944226952607278 0.557324214489199 0.572679051156156 0.662804223522544 0.494575555541087 0.233647612843197 0.757984217868652 0.721525762306992 0.58419098789338 0.938792021209374 0.77039277204778 0.654071607671212 0.0230953607871197 0.716445621028542 0.242892463204917 0.608683335976675 0.340260406481102 0.18659953646129 0.290619493902195 0.703189165154472 0.931078474400565 0.0598448034212925 0.912043894503731 0.203784972440917 0.173089751603548 0.074797035024967 0.749176394636743 0.355580681397114 0.0562087108800188 0.522677459353581 0.78009012339171 0.26893159537809 0.760621076324023 0.678782168629114 0.140535973594524 0.919755829179194 0.201939120327588 0.375551827787422 0.152458826387301 0.580716119059361 0.937705335228238 0.936476932952646 0.522389045609161 0.145865435882006 0.802855378314853 0.678514194679447 0.299280489911325 0.109675815196242 0.976433103587478 0.142139895756263 0.475549947947729 0.568273085188121 0.615447292218451 0.775515539201442 0.691133987193462 0.954767182078213 0.142705594592262 0.357752377607394 0.31999036033405 0.147448879755102 0.208034250065684 0.0704922072589397 0.836341866052244 0.393244698988274 0.423941196347587 0.230550050288439 0.237040146242362 0.560270410538651 0.0841234124498442 0.0365401151729748 0.428268709231634 0.385184427797794 0.574755794464145 0.0936871687881649 0.206611463094596 0.204514144686982 0.0392800141661428 0.108685957023408 0.854840374500491 0.523812161737587 0.09164349403698 0.704230079825502 0.982134494073689 0.948933484172448 0.878963678891305 0.823972382941283 0.871395222470164 0.386639875797555 0.149884434065316 0.253257155003957 0.29176594406832 0.213399755773135 0.590393438597675 0.768009854329284 0.104749887357466 0.467347367610782 0.325671920473687 0.176059547404293 0.0566136543895118 0.409789094829466 0.663688342666719 0.773102438354399 0.213037334643304 0.585708275982179 0.849096059408039 0.28914552711416 0.669730829359032 0.0490674951509573 0.819979244123679 0.0149474443099461 0.85286628425587 0.240966931735165 0.598803006114904 0.230518127097748 0.191711303351913 0.512064882575069 0.0108984614606015 0.363275368965697 0.130914329129737 0.737871477811132 0.759135688145179 0.7743824309716 0.185920771849342 0.398788219115231 0.171207186921965 0.332886325996369 0.903440382780973 0.43013948394917 0.884431872467976 0.768657458021771 0.142353091978002 0.218723255195655 0.970423139622435 0.29750716028735 0.477464605700225 0.746517672804184 0.803163283106405 0.360914335139096 0.729265289495234 0.173658978047315 0.0680835652491078 0.779519592765719 0.688639814294875 0.668247935215477 0.480054707909003 0.656723685273901 0.437427048378158 0.0422554950765334 0.310058300446253 0.316774136559106 0.333608432193287 0.391823152119759 0.515797733082436 0.193179681841284 0.287198054818437 0.827697674355004 0.206190075087361 0.835844782921486 0.929689800161868 0.376241052595433 0.438677559976932 0.223778325426392 0.787199208938982 0.78175838889787 0.0869573891279288 0.878876293150242 0.0111463399860077 0.443152246759273 0.25805608919356 0.166683605061844 0.341267791129649 0.540207285417709 0.0840698778210208 0.637608732669614 0.837205446746666 0.608342322520912 0.281542333760299 0.824163297424093 0.267181186676025 0.395034654976334 0.770315435286611 0.733792226777878 0.780309864727315 0.329448464312591 0.758225425425917 0.115836757500656 0.294245841957163 0.260366620649584 0.495393765538465 0.539364199377596 0.102324004694819 0.308601263824385 0.430064197736792 0.698070506243966 0.0215994711522944 0.494293805849738 0.997828094954602 0.605697491911706 0.517200949483085 0.480504871136509 0.180165033522062 0.587687188566197 0.0939590151770972 0.937569823595695 0.989829777260311 0.942364810432773 0.673623026823625 0.644199753380381 0.775610515614972 0.331381015500519 0.152180370574351 0.218984507927671 0.868546334365383 0.75564760484267 0.907341467493679 0.0367405717610382 0.249260163570289 0.0429314724542201 0.768846212467179 0.362608524782117 0.196468702864368 0.0435989461396821 0.953424285373185 0.766792268606368 0.276707355228718 0.295599401008803 0.620345782903023 0.0298130519827828 0.514092698073946 0.17841059241211 0.173686531605199 0.0112452997104265 0.305099310043734 0.572813993678428 0.61601277714828 0.364020295585506 0.348518889627885 0.111126343815122 0.104019179735333 0.537810162531678 0.665748535676394 0.759840096372645 0.414389619522262 0.602377985571511 0.693404968136456 0.89718308335403 0.289835712194908 0.809068838963285 0.860137635380961 0.981073023665231 0.229831530016381 0.138008596142754 0.889265022424515 0.362746316313278 0.39478465721244 0.355729893397074 0.175185468019918 0.574702282655053 0.908962570608128 0.593263695421629 0.699828486717306 0.964112762191799 0.226215543963481 0.939813829541672 0.400570872097742 0.791034194801468 0.365827147625387 0.360794639193919 0.666123122028075 0.927245539547875 0.497589510749094 0.919139635579195 0.718911047750153 0.944865207816474 0.417502521546558 0.0779923651460558 0.970353449315298 0.727011574560311 0.0227391374041326 0.893418260328472 0.873852609731257 0.560249455571175 0.779310069829226 0.498007487552241 0.721612228113227 0.920269236254971 0.820396362997126 0.608173025469296 0.493466714597307 0.0641638727742247 0.281289742845111 0.362285529694054 0.783984229185153 0.11212735760957 0.458406079837587 0.747849086343776 0.0427307770657353 0.865858659364749 0.344375157640316 0.960699571173172 0.944291743126232 0.0991336227674037 0.371956007231493 0.222638011001982 0.477676381797064 0.524218610888347 0.433570517692715 0.79027622635942 0.680947994866874 0.40810406972887 0.790565967105795 0.386528239597101 0.70352606944507 0.527095077214763 0.110806151404977 0.792419816267211 0.273030831655487 0.56161295526661 0.92958686496364 0.694389735665172 0.0944941270444542 0.167092564613558 0.532766674121376 0.394931767031085 0.851636715638451 0.806656702307519 0.496436362646055 0.0416982310125604 0.151818405378144 0.219842297942378 0.106284210721496 0.547285290260334 0.635945148204919 0.453296327767894 0.538236863848288 0.202299162212294 0.133192287378479 0.106565313162282 0.688233282854781 0.588697451036423 0.615624759886414 0.468335004663095 0.466608971122187 0.200706722985487 0.0757411163556389 0.785323881569784 0.633920467998833 0.324276853022166 0.0541056354460306 0.629419358964078 0.290287928045727 0.214843282653019 0.224062582522165 0.349248002173845 0.993642556297127 0.173627365573775 0.490812639691867 0.918891452560201 0.927724892669357 0.739667556632776 0.753609316470101 0.0912458477704786 0.767719256344717 0.48484316092683 0.172165114528034 0.838188222504687 0.37984722339781 0.314024786278605 0.981169715477154 0.63793092722306 0.790611258510035 0.117442200977821 0.779615663143341 0.0116901853564195 0.173795053258073 0.483151290828828 0.788187139190268 0.109534287452698 0.321773598331492 0.340775798643008 0.0392251806566492 0.188658366971649 0.371038438279647 0.939917341687251 0.237725024698302 0.211669528242201 0.467010034124833 0.457344016807619 0.37919867556775 0.745587353615556 0.705314368121326 0.0855745975393802 0.0882483504293486 0.268243545901496 0.882533388142474 0.638273435255978 0.484448830436449 0.0435875531006604 0.174443025293294 0.353036385304295 0.602216421181802 0.15936288425466 0.120452105107252 0.0427576847560704 0.0506572259753011 0.60063245107187 0.199941451537889 0.599798995419405 0.0758842211961746 0.811440219578799 0.213685155468993 0.908446450750343 0.916481294997502 0.274245654807892 0.706655018350575 0.806880652846303 0.878910173766781 0.114146457584575 0.847333166238386 0.672550537942443 0.271977705201134 0.132641957977321 0.384982738713734 0.135347826757934 0.465817035855725 0.413995606894605 0.892346632834524 0.598935343960766 0.788853467970621 0.194348620737437 0.0488050090009347 0.265224633740727 0.219900919296779 0.987842036897782 0.806961963467766 0.910584727118257 0.592785596924368 0.472217359908391 0.29641840278171 0.321744390919339 0.34060034049442 0.768172628164757 0.220394437247887 0.336008276159409 0.0993869259348139 0.587973431900609 0.96900224461453 0.61341994187329 0.729748813095503 0.471355031072162 0.421067812759429 0.584065116560087 0.0808445220044814 0.408247551901732 0.679985677574296 0.878926160256378 0.763507606843486 0.573069795260671 0.554435877061915 0.887129153653514 0.307122317033354 0.221718733336311 0.795615763904061 0.111338165551424 0.217415750280488 0.0851658027968369 0.42067408987321 0.675199507682119 0.488979847149458 0.327976700435393 0.0812507212907076 0.939098013753537 0.125748569832649 0.630728514275979 0.887003582434263 0.877648178080563 0.135289511741139 0.995123965314124 0.10785995881306 0.265014768277761 0.950541943081189 0.998962200568058 0.0197519163182005 0.10828941762913 0.707587536531501 0.561300959750079 0.21603781099664 0.741106813456863 0.498511774572544 0.398597737515811 0.97936982391635 0.0147652953700162 0.874145613929722 0.721417612684891 0.871904518997762 0.689524034629576 0.412100218906999 0.549423041082919 0.0327903068391606 0.328411430839915 0.590950024062768 0.343222873690538 0.702978052673861 0.315095933866687 0.472782315604854 0.0758915387233719 0.492338455906138 0.991657207396347 0.103131535518914 0.564279749291018 0.292189758804161 0.252735663980711 0.80645553415874 0.416983416222502 0.809992509081494 0.270270278500393 0.916131193065085 0.676752418985125 0.466493687452748 0.60530106615508 0.178140518125147 0.498548732625786 0.173138220482506 0.0901014032051898 0.0983707974106073 0.823179430007003 0.994231727416627 0.171164877065457 0.673863087862264 0.95223333673086 0.831532007895876 0.841356962106656 0.141814621230587 0.924640571551863 0.773742490329314 0.782683456090745 0.860086346997414 0.578752622471657 0.534172758662607 0.556525314364117 0.672598945738282 0.581500391967129 0.730114543547388 0.590085885783192 0.490794089324772 0.980058413459919 0.3412903609965 0.416453312709928 0.554842110001482 0.210999760827981 0.775175901153125 0.513943159913179 0.96597954230383 0.489393326852005 0.947719061863609 0.843562339087948 0.0963276588078588 0.947847248362377 0.155822123331018 0.639475518313702 0.227719436869957 0.576478624944575 0.866944358565379 0.387681536374148 0.438950322612654 0.764603071736638 0.467975736344233 0.681373759191483 0.258808127271477 0.281466233413667 0.804615908144042 0.72015112058958 0.231830414244905 0.0212634194898419 0.120311301602051 0.413720747840125 0.671289873868227 0.795057723508216 0.311183570674621 0.524863869450055 0.6946193809947 0.785228226787876 0.269040760593489 0.526093161464669 0.232434361255728 0.585278546556365 0.753404135967139 0.396211921460927 0.596364293692168 0.115957189209294 0.948460743471514 0.82360025604954 0.170427137508523 0.562791921705939 0.0138320723129436 0.150535339703783 0.97389324166812 0.907426307105925 0.587248551377561 0.345265989704058 0.454531173966825 0.0710608247155324 0.819527449861635 0.836785093925428 0.019031928437762 0.77061013114173 0.666479242837522 0.988079870592337 0.362752166693099 0.142756933455821 0.142065437047277 0.24228032713756 0.134348991671577 0.511160686907824 0.267246019376908 0.683758318778127 0.946726568127051 0.643584195505828 0.492507436708547 0.813518307176419 0.873333684660029 0.805834616643842 0.922579827641603 0.387944821214769 0.267915933160111 0.0295404124353081 0.491503811322618 0.749297228571959 0.758095680270344 0.727162221898325 0.161037214738317 0.781622505465057 0.885196352831554 0.776030021109618 0.436030429415405 0.845751118056942 0.0375697518256493 0.158139925983269 0.944979186151177 0.216610345609952 0.550972755779512 0.733607657793909 0.671286055136006 0.293396954864729 0.905009302932303 0.647359705541749 0.860636135640088 0.282913011529017 0.782972539444454 0.936657382629346 0.601387406387366 0.0929439054732211 0.0399551940057427 0.564436453077942 0.780935339503922 0.375328815854155 0.822521034886595 0.52827535221586 0.432294489946216 0.671914825174026 0.433246536515653 0.367076775017194 0.517969816997647 0.053406060161069 0.244506032119971 0.156010476702359 0.178163676464465 0.386480340750422 0.496994520828594 0.666418327062856 0.902062847567722 0.0419455395056866 0.833260789485648 0.329492357259151 0.0850516331451945 0.879246360734105 0.757455252576619 0.72470067453105 0.375642305717338 0.85891066913493 0.805610321965069 0.757783936462365 0.591491720229387 0.915909486236051 0.746584762122948 0.975552799487487 0.0164540363987908 0.141178625635803 0.235160809054505 0.5977875780873 0.106885598234367 0.294279379125219 0.954151512410026 0.1397234102129 0.0337662705616094 0.0442607400170527 0.0772328544128686 0.357778641965706 0.991282078442164 0.828202775740065 0.278042179280892 0.557465986795723 0.978157450773288 0.247046526537742 0.113667794126086 0.933965148983989 0.183332817230839 0.0186483478848822 0.553421190790832 0.637116198041476 0.548777859278489 0.380782240454573 0.74369998664828 0.814880727198906 0.346270764835645 0.342545830700547 0.564541836441495 0.171369958682917 0.393234446705319 0.170297103072517 0.753479285261128 0.917715813191608 0.652298970706761 0.728478530158754 0.415493929712102 0.874328959176783 0.372540353245568 0.631312836317811 0.316309756408446 0.960941877765581 0.858071417962201 0.768674814847764 0.343410295371432 0.695000223640818 0.418122810942587 0.0714860743284225 0.0895039024227299 0.633113943547942 0.331969600683078 0.333131835418753 0.264643216719851 0.885578783638775 0.0940446442598477 0.50095763325924 0.776538384563755 0.815097519718111 0.264082515174523 0.925993220580276 0.516917760074139 0.840616646225099 0.208376535433345 0.5502321386314 0.211881858466659 0.283251826222986 0.0927239705156535 0.753549492585007 0.649098520667758 0.749015699471347 0.342696142888162 0.354432580834255 0.532780445483513 0.762196654765867 0.683345265735406 0.658185681384057 0.90613886119565 0.976215365317184 0.573227610990871 0.68866134713171 0.992298620718066 0.735098111492116 0.0177722041215748 0.778160234505776 0.149609751345124 0.981712870262563 0.0968482077680528 0.668272742107511 0.221001867149025 0.0447626567818224 0.821016071757767 0.0310071744117886 0.570806516322773 0.633176297196187 0.224140035917517 0.670683830899652 0.400259550570045 0.572942481213249 0.939651684747077 0.0980293264077045 0.849175826355349 0.972716176412068 0.0272140078968368 0.598680621359963 0.46808742210269 0.906912446401548 0.457083045518957 0.917202581989113 0.774670921242796 0.225669653115328 0.436095598880202 0.817116611164529 0.811279079082888 0.0537760173343122 0.726166133016814 0.635258072139695 0.339697731835768 0.883052448288072 0.574123039271217 0.87354225769639 0.024925904548727 0.839820491843857 0.780520941019058 0.844814638232347 0.0161112570646219 0.403437577802688 0.883113209856674 0.693752376649063 0.870666707616765 0.22423472766066 0.150624664430507 0.577373100097757 0.691434899696615 0.571086735478602 0.666361533361487 0.100543380593881 0.937884519908112 0.464818919936661 0.513861034696456 0.846913340345491 0.172471302768681 0.210635401173495 0.196263164621778 0.437273474121466 0.395548215566669 0.739429100812413 0.499582471067552 0.0274784676078707 0.657489240239374 0.46240116040688 0.343085491531529 0.245874783580657 0.28830988837406 0.30917065968737 0.877447451113258 0.483504416490905 0.754194094676059 0.820090867416002 0.666538078559097 0.220532993816305 0.520986588713713 0.578437715710606 0.995133199468255 0.806790809489321 0.946091464576311 0.818380601617973 0.0291194503963925 0.0125900319055654 0.229266799520701 0.362418464771472 0.397924045338295 0.195215745174792 0.794565650806762 0.0522648467775434 0.460734449408483 0.184680429783184 0.254110801047645 0.973965305918828 0.214155606820714 0.995787360721733 0.979122100749519 0.249643021498341 0.872553472050931 0.0671234778361395 0.874578284334857 0.342816415550187 0.158448058511131 0.878339890008792 0.391042010816745 0.806218663272448 0.0246839745971374 0.173568742375355 0.623697653845884 0.155639361715876 0.769778628305066 0.781412536967546 0.89439897170756 0.406281857013237 0.38989774604328 0.769434205028228 0.684502889271826 0.709676155780908 0.497025913402904 0.854605508984532 0.490084335287102 0.880931773539633 0.928032643024344 0.967212772450875 0.381153447641991 0.64363700912334 0.5445074249967 0.766500117727555 0.634227320777718 0.0428553296951577 0.0597482831031084 0.892762901154347 0.936420757689048 0.973286996548995 0.908140589131508 0.407499532401562 0.0888976891129278 0.26872697730083 0.741708636849653 0.800900799862575 0.205707370692398 0.641869302373379 0.460267603343818 0.750179169008043 0.383673618207686 0.140786011696327 0.95197730464628 0.818867866962682 0.891335745933466 0.392700889115222 0.364506461203564 0.626978856460191 0.327548875650391 0.131493965520058 0.521993927261792 0.459240448740311 0.2149752673693 0.0144690484646708 0.0698476222250611 0.76816120700445 0.390186829857994 0.988307569790632 0.41119225153001 0.392907825354487 0.477281738976017 0.612527747771237 0.740936088212766 0.990997130069882 0.652986868051812 0.880414871356916 0.374995762796607 0.212102720274124 0.964417146290652 0.711853040829301 0.380429514253046 0.414086464231368 0.990773566544522 0.505029630844947 0.0728211330319755 0.679007850931957 0.939606905980036 0.669564524227753 0.317129932360258 0.902223837545607 0.03558688336052 0.0530932316090912 0.146178536887746 0.38999521764461 0.492070208580699 0.87300834674621 0.903536806288175 0.325808125687763 0.983934009915683 0.289830282712355 0.496214222703129 0.520403923061676 0.298218763645273 0.458598147754092 0.429812565941829 0.780985120171681 0.813140837240498 0.523298184399027 0.555011414429173 0.133102471451275 0.940202076844871 0.647343160314485 0.417474511594046 0.241663951671217 0.66028332917951 0.7287125856895 0.897659550816752 0.888651270766277 0.264154422914144 0.0841733507812023 0.623486591614783 0.671190224480815 0.933862140947022 0.228576328617055 0.184576881909743 0.812752070154529 0.531806645717006 0.824595886692405 0.677559916155878 0.0284322037594393 0.662895864336751 0.68426863251254 0.190782974320464 0.70960068608867 0.895467730369419 0.115721500799991 0.30080317129381 0.757975191627629 0.584305785663892 0.234987783858087 0.913832298519555 0.579801794658415 0.182545412257314 0.714666243945248 0.254283723901026 0.463534450042062 0.658756579430774 0.0501938999118283 0.0679359220480546 0.934026093340945 0.491028472629841 0.0127439636713825 0.223792860673275 0.14462589481147 0.721002721847035 0.615720748666208 0.561827514448669 0.210701109552756 0.997479268622119 0.429331081134733 0.620325574071612 0.119521221187897 0.904715083295014 0.673112720234785 0.29485425103223 0.178550061769783 0.369687627046369 0.139578172073234 0.27952610630542 0.101745237528812 0.590167519107927 0.792595666961279 0.389494566337671 0.903548631288577 0.863185509699397 0.119703700207174 0.899490068070591 0.364529486312531 0.983401906103827 0.548930840222165 0.744181145064067 0.321991874363739 0.4249605800258 0.879987407308072 0.600908056262415 0.566322611060459 0.419799703459721 0.50053228890989 0.329746313670184 0.608563910180237 0.353012064311188 0.301800800161436 0.169983744134661 0.30089109917637 0.199994409219362 0.897716720928438 0.675817992014345 0.907296073976904 0.750419789936859 0.623663010497112 0.493044313071296 0.514215394698549 0.456667349305935 0.882822332503274 0.144945341777056 0.736249120763969 0.252820561449043 0.309935684727971 0.0560429209214635 0.679608935334254 0.81476162110921 0.109342562754173 0.250132700433023 0.395432357715908 0.0285903341253288 0.263125002472661 0.759662699007895 0.035443898611702 0.864834992031101 0.479496511924081 0.166265991299879 0.611067193683703 0.23283595648827 0.952222658249084 0.618384979504626 0.154029051412363 0.324981887063477 0.153681473941542 0.186097648739815 0.934927907227538 0.178360640711617 0.490529090929776 0.823526831374038 0.552934174388647 0.220435711687896 0.785139031372964 0.0698047439497896 0.436940616760403 0.755007621557452 0.036902854857035 0.964987371731549 0.0634980063815601 0.945392062168103 0.631146959459875 0.973065379615873 0.158781752365176 0.0834101395634934 0.814002981674857 0.680140134193934 0.656457792990841 0.0161991086509079 0.751719050013926 0.939423436722718 0.290417450766545 0.955001439759508 0.905194527003914 0.860615383514669 0.862796200932935 0.99749636198394 0.621623075876851 0.294782052398659 0.170968973820563 0.964385764088947 0.105948930780869 0.473354683334474 0.536865296801552 0.543829936445691 0.31652353303507 0.0872004586830735 0.12970001262147 0.527391449743882 0.756645518841688 0.694341365902219 0.545134519052226 0.514704861801583 0.191809994080104 0.896364679504186 0.0114165509608574 0.339240068753716 0.882382558477111 0.396882716224063 0.320956451410893 0.173163546235301 0.693513066587038 0.910727137455251 0.0783054391830228 0.372823183070868 0.943889203064609 0.654046259790193 0.565693379787263 0.747156706650276 0.383046405904461 0.660089069185778 0.846580901346169 0.98756459068507 0.806691696480848 0.356508043471258 0.104619841396343 0.12570648863446 0.594137378111482 0.752540559191257 0.207059529903345 0.478695455680136 0.392401822705288 0.510850324730854 0.145221376162954 0.165006977391895 0.84783356560627 0.247009573094547 0.0878013791982084 0.802052437714301 0.420174763493706 0.323036892206874 0.736478633093648 0.559087924559135 0.346020168918185 0.270416198696475 0.207701563967858 0.206186932187993 0.290805453967769 0.910832914055791 0.772197252449114 0.514517110502347 0.949608022754546 0.369898007912561 0.513160243050661 0.633644398115575 0.560267691302579 0.820566103765741 0.0600730479881167 0.971375325645786 0.564895444314461 0.426232316510286 0.962024008098524 0.247059314807411 0.0969526633596979 0.304268226721324 0.724265283506829 0.234255753152538 0.388293472134974 0.250213565723971 0.103609920069575 0.231281968047842 0.861681660357863 0.886147483384702 0.241585547914729 0.723719145560171 0.853717111025471 0.0868389729317278 0.777810068032704 0.472698194929399 0.169965300951153 0.602117898950819 0.462686197522562 0.601462182498071 0.406445388740394 0.542199139324948 0.795626605581492 0.712355439574458 0.0502694926923141 0.289862827337347 0.896012860790361 0.922857389796991 0.779719862877391 0.961194795072079 0.893467921365518 0.685127899586223 0.324370090987068 0.0961451793275774 0.0895377542264759 0.270203113115858 0.430440448545851 0.928926209998317 0.134371334263124 0.199567060421687 0.463866431263741 0.734190446764696 0.511449269379955 0.482014786608052 0.724645147901028 0.068321892679669 0.225268092458136 0.347845608897042 0.860901217937935 0.21017139835516 0.0969388166232966 0.514944119309075 0.881138021959923 0.105489604163449 0.299176952410489 0.986789723886177 0.0696045316942036 0.327150728963315 0.848410900891759 0.399168420964852 0.426800389289856 0.753328288942575 0.950437823100947 0.751135362545028 0.290663007902913 0.486447945397813 0.993403004438151 0.712689277492464 0.716541100167669 0.886124782362022 0.283137234521564 0.0308197437413037 0.521281241464894 0.588113670444582 0.593447507205419 0.325680277566426 0.110420455301646 0.0697234695171937 0.752536424209829 0.588387266115751 0.67554219458485 0.842519561497029 0.691338709227275 0.882426269787829 0.505582046061754 0.354070903996471 0.214461369093042 0.165968201872893 0.485389920768794 0.171724413882475 0.544464621634688 0.580427049766295 0.847039249250665 0.770934922304004 0.25713258757256 0.860786684323102 0.310657646399923 0.288966221190058 0.0784262950159609 0.555187252906617 0.758947431123815 0.149150909935124 0.973160552186891 0.403154543521814 0.900594840187114 0.0819272145326249 0.374800962274894 0.597236397671513 0.828839427344501 0.211884095030837 0.0342873061122373 0.79419749362627 0.184643339652102 0.46273507761769 0.461395807866938 0.629507812391967 0.182826124688145 0.344600076749921 0.809766503844876 0.336224851545412 0.934203183676582 0.399137264655437 0.12193401131779 0.120332898518536 0.0249059762386605 0.889852940302808 0.870560567053035 0.684874866798054 0.713277210814413 0.893061879512388 0.64353965576971 0.469885326272342 0.142036072432529 0.923666441475507 0.457083882933948 0.165818888451904 0.186881890760269 0.949191067076754 0.364421405841131 0.806713810644578 0.279998932061717 0.0403556088358164 0.65765758854337 0.789143258966506 0.628658662757371 0.43225868048612 0.434638667597901 0.510073326937854 0.319191017413978 0.521438045520335 0.418496528069954 0.769395110448822 0.0487773503339849 0.500895422752947 0.98866534168832 0.762225849730894 0.570228298674338 0.4195250474778 0.672871830540244 0.204138732445426 0.417826841562055 0.445097647760995 0.918721326161176 0.728710006137844 0.830510321268812 0.125564542298671 0.917178057001438 0.417738346874248 0.994081443580799 0.485392645767424 0.537907328486908 0.218362867787946 0.49168876524549 0.476636768081225 0.600860634786077 0.190567547297105 0.812305650515482 0.36912385036936 0.519932772365864 0.125536802955903 0.84082245784346 0.590681010317057 0.263794549987651 0.976461938507855 0.816759593931492 0.892706485707313 0.892811163272709 0.718814924356993 0.128051481572911 0.740955561280716 0.222854106251616 0.681377714150585 0.787446166377049 0.403701953841373 0.332368631807622 0.738009616017807 0.75477766320575 0.0776781664881855 0.422775439075194 0.300624964635354 0.858778511772398 0.659505245720502 0.0807325372844934 0.856331872143783 0.230857622926123 0.339568904540502 0.78808958299458 0.620601021137554 0.874819343448617 0.170561187295243 0.65002241690876 0.557892592223361 0.926239312712569 0.629641913119704 0.545414862448815 0.829440556694753 0.715404097139835 0.508892997307703 0.609429242000915 0.486452505195048 0.234011598161887 0.927999194599688 0.351100871700328 0.574022593037225 0.684157403148711 0.706430367315188 0.163736841054633 0.280701713173185 0.26926874446217 0.723268810608424 0.393008337281644 0.506086470922455 0.546668642340228 0.540125156051945 0.268758506332524 0.0879044600739144 0.260690845237114 0.0909098505065776 0.0268698951066472 0.056113074538298 0.0170412136730738 0.700011269308161 0.0354265272640623 0.843725602049381 0.471451696606819 0.747684193269815 0.654024695144035 0.789040598988067 0.113951702702325 0.984728757310659 0.332267448657658 0.986145970043726 0.734819810807239 0.723198615270667 0.820365232273471 0.80571364694275 0.300659095346928 0.0299721771967597 0.855694864643738 0.738996863290667 0.696802957986947 0.24453644920839 0.39762756862212 0.620274754760321 0.472332053261343 0.734687960934825 0.432031160849147 0.316595849916339 0.715888339907397 0.586130865598097 0.309369894382544 0.326698375272099 0.903942939420231 0.586189300245605 0.783111764700152 0.940043099613395 0.363165435947012 0.997058891828638 0.781396440067329 0.704393442133442 0.0702598537574522 0.38206505027134 0.273472359573934 0.991956306998618 0.489989844080992 0.280302978935651 0.246706289644353 0.564338834646624 0.331913337367587 0.658108615693636 0.648368232098874 0.487943455395289 0.0596505814604461 0.817505672601983 0.979452680055983 0.479394990166184 0.694090118585154 0.522747077974491 0.420285905036144 0.460811635882128 0.543035556701943 0.675557814114727 0.0628046929230913 0.397313693820033 0.426514328974299 0.332191223839764 0.950497632694896 0.398596408439334 0.745114330779761 0.723130023307167 0.500500585618429 0.666347977749538 0.641907100377139 0.920271036708727 0.930570604451932 0.0154117940342985 0.468342907896731 0.591790341769811 0.173796252100728 0.980581465905998 0.566187425358221 0.0800842962530442 0.194126118444838 0.143528042605612 0.514744302134495 0.986004974530079 0.836377331602853 0.348852621514816 0.90856661207974 0.785613048134837 0.292821070360951 0.21597177622607 0.859740046509542 0.545769946458749 0.187040132458787 0.0448598474008031 0.358539883079939 0.384907677471638 0.347858962588944 0.19248709861422 0.833294603487011 0.893222458043601 0.199658840459306 0.205387888690457 0.701910986590665 0.724323532369453 0.580954637806863 0.694388202363625 0.181455245921388 0.247314078898635 0.914951544799842 0.925802100258879 0.316579393432476 0.582779886929784 0.828183121266775 0.834827065544669 0.323299476781394 0.0924392415815964 0.940386073030531 0.494570732510183 0.555677414974198 0.315812475737184 0.614815387118142 0.451346365816426 0.30770224777516 0.542753341165371 0.324914924290497 0.397089864525478 0.398633434721269 0.165188333403785 0.942363474441227 0.448077508446295 0.177819058874156 0.402085953357164 0.962965211377014 0.806130165357608 0.13847162762424 0.0662659957725555 0.978533965046518 0.0642046313500032 0.560618568875361 0.381095597087406 0.478465509084053 0.529278325280175 0.906776467079762 0.904664132136386 0.715027801613323 0.199721756994259 0.532539804039989 0.306232799524441 0.572964418581687 0.800315623118076 0.536119098039344 0.189671502653509 0.552770221994724 0.296178622494917 0.283839178679045 0.208037081786897 0.835011210865341 0.453050666444469 0.11319158367347 0.316499824486673 0.0221741522033699 0.333900256911293 0.281648242438678 0.215034909849055 0.763554363781586 0.279403221821412 0.46177070493577 0.622670629937202 0.412042765738443 0.586782825093251 0.454366023652256 0.882765795581508 0.670795238211285 0.583331670109183 0.272080093417317 0.106859045056626 0.633241144418716 0.820149983889423 0.412653791937046 0.628980991693679 0.900444820737466 0.165900973791722 0.196029248314444 0.965424992635381 0.29694600580493 0.802784128659405 0.183320452854969 0.126719034691341 0.0943673751922324 0.68669445247855 0.820915238510352 0.237528806587216 0.238334664425347 0.359399530482478 0.46805557198124 0.417544217575341 0.406905448585749 0.027698184279725 0.123953638912644 0.470199899496511 0.267925010111649 0.64123974240385 0.572546552650165 0.792577655969653 0.92696759107057 0.710371510798577 0.0279367857775651 0.220020284701604 0.532754603405483 0.678520877172705 0.603903620610945 0.911159768674988 0.744812629958615 0.789856595702004 0.354856344398577 0.0881597119080834 0.809202354445588 0.379962010795716 0.773786440670956 0.6027072950406 0.605514277589973 0.55175461740233 0.274105753949843 0.864853406171314 0.765346441082656 0.456898093670607 0.423016872755252 0.70351234810194 0.728068971761968 0.907345413924195 0.133163596061058 0.994096284473781 0.551534202077892 0.925517062912695 0.43353297554655 0.310035446139518 0.538757229559124 0.104539334767032 0.315860812307801 0.921237605155911 0.960252590030432 0.175361731313169 0.119327965262346 0.582352229489479 0.488824898868334 0.392637512497604 0.936264541414566 0.632346979982685 0.11960539188236 0.37456433871761 0.0990996764576994 0.718120691885706 0.619339089761488 0.83903330469504 0.897210783050396 0.572953706677072 0.448483657713514 0.932461449468974 0.496884579742327 0.0317128340364434 0.977509526913054 0.660539365874138 0.0125366807566024 0.168147212152835 0.971125320736319 0.167933835908771 0.981778169730678 0.799441822180525 0.693468702493701 0.793300828470383 0.729262169415597 0.944376606249716 0.813068070879672 0.0138533665798604 0.431583106718026 0.938539928640239 0.302692671790719 0.489172752941959 0.272568823373877 0.143437703668606 0.294117336904164 0.819869336690754 0.226229317169636 0.892635023067705 0.512862960959319 0.218737399741076 0.450176501222886 0.602242313970346 0.860747472418007 0.323209670765791 0.497441470853519 0.848172979836818 0.860860627628863 0.15967872985173 0.448465386023745 0.701986906684469 0.0185230364417657 0.887397997288499 0.936977113804314 0.50472831957275 0.759197658007033 0.937996657451149 0.113380860437173 0.381809295250569 0.0120783063443378 0.992012525366154 0.248406408729497 0.107629648023285 0.471691765021533 0.430031273013446 0.0303868163260631 0.895107174925506 0.2769483080809 0.713332344898954 0.976226315100212 0.248189363810234 0.537064460963011 0.533384491840843 0.540574993810151 0.418333959612064 0.678054907938931 0.409445003245492 0.825111859489698 0.92439585413551 0.940649399131071 0.57030856189318 0.969057228872553 0.810739470575936 0.937564324731939 0.716534588015638 0.379791692618746 0.700899022321682 0.0356075103231706 0.26827273763949 0.104551462647505 0.902429279668722 0.0101118321274407 0.435784072435927 0.363427907114383 0.148573996468913 0.117351617708337 0.270922801343258 0.769859024523757 0.337028118767776 0.172880519099999 0.858656916026957 0.97348533482058 0.448028080216609 0.687938087962102 0.0292232578154653 0.678039116223808 0.625918880167883 0.259492089250125 0.823896216209978 0.700085526558105 0.87947561720619 0.69027855083812 0.549570986933541 0.120765752173029 0.097118486049585 0.656607432111632 0.137928601228632 0.803525349954143 0.187860352206044 0.506242404370569 0.364639517294709 0.322082151065115 0.248938898863271 0.130903877001256 0.230289280689321 0.806410193427 0.991038570241071 0.0841819054144435 0.423610864831135 0.619099241015501 0.192862590379082 0.912940304493532 0.330907235234044 0.929126999201253 0.926777050693054 0.649247368704528 0.549495976401959 0.873497584038414 0.0273563234973699 0.0196367873158306 0.452242638426833 0.224971665299963 0.577316734900232 0.946007874517236 0.860601661480032 0.606979580025654 0.923202502736822 0.722073217805009 0.129509948692285 0.684623751328327 0.937071131789125 0.323512162440456 0.495728152743541 0.671965566806029 0.561560736114625 0.24531550815329 0.674331443256233 0.159542766204104 0.673311092159711 0.0512202761089429 0.698876345872413 0.824457632312551 0.999727515580598 0.715605877041817 0.547686050613411 0.357293399279006 0.247005171652418 0.911597862800118 0.907458774051629 0.153540834554005 0.191768774499651 0.83235166821396 0.695872799227946 0.710287980670109 0.814926622058265 0.318858920710627 0.0295068837958388 0.685729906689376 0.7109053864819 0.420959452688694 0.545601596771739 0.813958865832537 0.217866252807435 0.411368273256812 0.193778221267276 0.150882024900056 0.386709059460554 0.0274995025596581 0.386251834102441 0.222897189443465 0.504335584389046 0.9614739778894 0.112358693904243 0.231250477279536 0.749822621538769 0.342083236251492 0.814080832456239 0.693469324389007 0.816980330115184 0.488904508382548 0.0901597820711322 0.352669187244028 0.773120868399274 0.761926071529742 0.653514968499076 0.64978461133549 0.873103842481505 0.288848645174876 0.297905877237208 0.78828913877951 0.125137885008007 0.12670087318169 0.941807128929067 0.235133083541878 0.843532999597955 0.223984385756776 0.884518719755579 0.616020447805058 0.212624145834707 0.424763518737163 0.487662841619458 0.955083154221065 0.988860035487451 0.546551425908692 0.951459191404283 0.235697457680944 0.964727642850485 0.950742759022396 0.638478465240914 0.720390857080929 0.818566791494377 0.941099231818225 0.7711203618953 0.0826539966999553 0.0191659132228233 0.676132214413956 0.757103958716616 0.235905156421941 0.430495955122169 0.353578985270578 0.667504094492178 0.217355552520603 0.554097833167762 0.566509632589296 0.494187177773565 0.806999975147191 0.1295442511281 0.83191174851032 0.076143353767693 0.168923912136815 0.254891686493065 0.567311200087424 0.221332160632592 0.181527367567178 0.314886366904248 0.125280823425855 0.584418336036615 0.351796951186843 0.883684550006874 0.926345903908368 0.105407364156563 0.551864303553011 0.820947715598158 0.646610194460954 0.631862463839352 0.476347174856346 0.134479103325866 0.926644715382718 0.110047157227527 0.194195368262008 0.633506341506727 0.397307355236262 0.14760444970103 0.561171664074063 0.0895938923791982 0.89831029579509 0.779729436330963 0.62216095331125 0.727228098544292 0.686822994181421 0.156142603869084 0.921591463354416 0.11302526563406 0.586777779858094 0.245973921022378 0.35815811335342 0.843122242589015 0.279215863298159 0.621652730233036 0.692132707259152 0.511826140470803 0.355838927456643 0.623371346208733 0.864227171197999 0.926565303870011 0.21392369749723 0.732082525480073 0.226587018994614 0.0426837903168052 0.585672933980823 0.253306483656634 0.127302339987364 0.0560042394022457 0.126617160725873 0.212397251781076 0.132664897108916 0.604472027849406 0.419243671200238 0.0822893228707835 0.0322819913295098 0.34141878537368 0.487507256229874 0.783906865916215 0.77048552549677 0.886138223644812 0.179219066912774 0.381190521176904 0.100828006954398 0.325301891614217 0.0958536544931121 0.951250359052792 0.83468367050169 0.656300864233635 0.543862375731114 0.290966536146589 0.0154360852926038 0.832017195262015 0.103031919093337 0.53306552846916 0.102616384231951 0.904286579450127 0.296781597477384 0.795668409715872 0.153334788514767 0.0578178606042638 0.626382318024989 0.0272341231442988 0.853647079574876 0.30043724214891 0.966792184517253 0.374066166463308 0.211400329172611 0.195935875505675 0.374152637340594 0.155238554570824 0.426614840440452 0.858586139131803 0.861142738517374 0.960521151761059 0.511617641195189 0.701190649268683 0.143408414658625 0.600026511368342 0.601911931512877 0.0768984367814846 0.193092739817221 0.911232891853433 0.0248033837974072 0.769658494866453 0.231027448519599 0.786027543661185 0.874855969578493 0.0641510520037264 0.546771409963258 0.991947434272151 0.0765055757435039 0.840255191822071 0.30506259447895 0.450240537538193 0.248306288195308 0.47312148204539 0.549262668620795 0.145312628811225 0.150823395478074 0.0371149734803475 0.896255341642536 0.427144585752394 0.686406351525802 0.745441575639415 0.345665231968742 0.510202962143812 0.70585176080931 0.379959443691187 0.752187010326888 0.643732626333367 0.369124775144737 0.958095716503449 0.662106310159434 0.649987224042416 0.259255444025621 0.299766435169149 0.80841645718785 0.422083635176532 0.57193738038186 0.620040796732064 0.700282472595573 0.899933954488952 0.127286754110828 0.35121645064326 0.514508432089351 0.270531529618893 0.206404144451953 0.571248167098966 0.63063796996139 0.43522232072195 0.324090883736499 0.591904454026371 0.537208333145827 0.189097342537716 0.911145749292336 0.0242600086517632 0.515899072282482 0.510474981178995 0.271682648379356 0.240484369790647 0.659326343636494 0.628004940610845 0.615893824112136 0.448463472393341 0.343082704066765 0.267309667987283 0.282329475730658 0.538279672050849 0.134353258500341 0.646244539383333 0.553820946614724 0.233630156670697 0.819041159311309 0.330824752969202 0.922014968986623 0.349065075519029 0.243348187762313 0.0663474977109581 0.122606022211257 0.701104491874576 0.522256115602795 0.172908785832115 0.999960341381375 0.259693647408858 0.789745161191095 0.313822258627042 0.158180075571872 0.982245088864584 0.794357996091712 0.677241444445681 0.331509432040621 0.239846779350191 0.414704178685788 0.355397790009156 0.646957252149004 0.639109570959117 0.63233047394082 0.846494449139573 0.551043195910752 0.361483217442874 0.40015752608655 0.712942059033085 0.633240073043853 0.814872420355678 0.036776979144197 0.505281787724234 0.830799635816366 0.963647832293063 0.779490440443624 0.582546555637382 0.70683761354303 0.163706605371553 0.10688075123122 0.0812513807578944 0.353769092764705 0.535963480379432 0.897349769736175 0.889476201289799 0.995045756332111 0.0141454824223183 0.705216505127028 0.223892090085428 0.587965314530302 0.986760430035647 0.771656882823445 0.5180013617035 0.496969974634703 0.8710682035028 0.67711622820003 0.438342676500324 0.513409321571235 0.981028053350747 0.426613528421149 0.33789466925431 0.996461331807077 0.893924259289633 0.543330173725262 0.420375432604924 0.785026793330908 0.397801239455584 0.545189662587363 0.970356374389958 0.191820587967522 0.994648025010247 0.393014893920626 0.0131270972802304 0.445058666819241 0.468872256514151 0.464361122471746 0.131445569940843 0.788165414114483 0.593797910865396 0.770517205968499 0.687393335103989 0.307196294222958 0.942936518003698 0.694251317628659 0.995581390287261 0.183109817053191 0.175420071685221 0.704134951741435 0.959843558561988 0.261305403653532 0.977359866816551 0.601973744172137 0.343880035853945 0.0679113956773654 0.547791980498005 0.0734165364736691 0.731903973529115 0.883964725597762 0.811557399360463 0.469704438410699 0.777902997354977 0.87787023435114 0.663382828645408 0.5762148613506 0.915719906131271 0.86313199051423 0.607980193437543 0.600071802311577 0.996933085727505 0.286963496562094 0.416814453860279 0.20276871667942 0.281137419755105 0.523432982165832 0.202509750300087 0.42358302222332 0.915816667324398 0.0964562106528319 0.8025258653122 0.49702720098896 0.105980398959946 0.875297307563014 0.684859980496112 0.124684859863482 0.395499693902675 0.697534464760683 0.859845918307547 0.204536882590037 0.047804328512866 0.764218282890506 0.629289188762195 0.442600755165331 0.269371345201507 0.0221539735677652 0.979424478325527 0.418435622898396 0.801726732149254 0.22862175463466 0.781050914989319 0.252981717158109 0.839491451370995 0.409414774477482 0.934741078629158 0.834243199205957 0.338434201234486 0.409527823657263 0.687775128111243 0.371650566279423 0.0573500634869561 0.590777771049179 0.278282867746893 0.980598297647666 0.658573125617113 0.190892974645831 0.259244205653667 0.884517590755131 0.878614152753726 0.50798470699694 0.439524607660715 0.743676566227805 0.912005062927492 0.745866158639547 0.246893543519545 0.0615516418800689 0.969128371113911 0.742844218369573 0.702042082950939 0.202334100604057 0.843911688430235 0.766281114690937 0.960550550720654 0.774904304398224 0.823078242707998 0.982779453443363 0.315844368501566 0.436660624418873 0.52511259207502 0.880564772789367 0.862287791147828 0.858327271637972 0.673869893443771 0.21325599123491 0.2716413299134 0.0700990011589602 0.352398558368441 0.523308241216 0.460738156116568 0.673295649655629 0.552703083809465 0.236952301801648 0.44253347084159 0.35734538170509 0.554066526570823 0.19729897090001 0.998289089486934 0.0770115037099458 0.363161675531883 0.0669341939268634 0.223787282747217 0.834896369299386 0.300136389576364 0.667168056659866 0.280538587130141 0.694199769238476 0.880553433687892 0.264377561162692 0.544957508239895 0.0992675487743691 0.665037370964419 0.687755120738875 0.061777477466967 0.29708272826625 0.909374705790542 0.575754020102322 0.344146565706469 0.0766332763433456 0.535347604872659 0.883526222100481 0.638328237186652 0.79671563992044 0.528594692919869 0.849595646716189 0.82200876718387 0.967295832354575 0.82005419841269 0.154975550251547 0.849441958591342 0.892079869022127 0.576050246262457 0.291607721270993 0.324613836144563 0.655636736059096 0.0162336097797379 0.389815683292691 0.475852313537616 0.77500095310621 0.987798459969927 0.835533565811347 0.476854717952665 0.533797797283623 0.605567639111541 0.475337066592183 0.757389384689741 0.0990050529432483 0.455198092602659 0.0664309849659912 0.597116764883976 0.796127542250324 0.520898172627203 0.303256213816348 0.057147451932542 0.0979214891162701 0.0177378742559813 0.33146268985467 0.182186787961982 0.910324044418521 0.416177661649417 0.617867210863624 0.587402453869581 0.729215007715393 0.955556371139828 0.480860252263956 0.615703080431558 0.451805401539896 0.222450659854803 0.838124870781321 0.562133660507388 0.196540580638684 0.522745132765267 0.687451782198623 0.832265147548169 0.659058236225974 0.80697820604546 0.165057523096912 0.277111870234367 0.623522646098863 0.423463399577886 0.226666536538396 0.748782452312298 0.867551766568795 0.148064221418463 0.942944986429065 0.352025807967875 0.48222209303407 0.576491873527411 0.358783161009196 0.819815944742877 0.116378915593959 0.227489107639994 0.618657869838644 0.909123499733396 0.780776862232015 0.864368033711798 0.583641609544866 0.927862375096884 0.71078148801811 0.550054121906869 0.0272477956209332 0.398347371639684 0.245310936139431 0.766919705972541 0.12495724816341 0.0769617550820112 0.0522226231289096 0.89693357125856 0.452254821397364 0.664997096213046 0.0637572890101001 0.743884054059163 0.383443324475084 0.310685653125402 0.693504367889836 0.715324646211229 0.98341551035177 0.560102471606806 0.451535800013226 0.972459919126704 0.521391817815602 0.209301576348953 0.0405513424309902 0.289442572940607 0.935843921902124 0.0977817466133274 0.508633526128251 0.0634296089620329 0.803926823020447 0.378288696827367 0.442588987560011 0.0865031047491357 0.590756116968114 0.107612106795423 0.637172923514154 0.454852463568095 0.203225556637626 0.0577191069489345 0.716522932664957 0.754095097840764 0.926430706179235 0.589989320056047 0.513375881444663 0.859055512885097 0.24328835811466 0.470055075800046 0.803367110099643 0.563457867852412 0.718015614398755 0.820499909026548 0.150156859706622 0.366365573885851 0.246288889327552 0.744912257448304 0.387019132126588 0.710954767458607 0.63640991098946 0.939054881695192 0.388325884682126 0.966126292077825 0.579637865545228 0.553300331269857 0.988970596394502 0.914181879516691 0.60875993259484 0.650732893340755 0.455978811855894 0.876806345742661 0.134786164939869 0.600372243206948 0.137190505776089 0.354071681480855 0.199166439522523 0.299201377821155 0.952089029820636 0.357344350668136 0.508411317726131 0.0934262226242572 0.27500404921826 0.206629741007928 0.65248440868454 0.0898030840838328 0.8771094166697 0.9141823734832 0.423634708223399 0.299120938268024 0.263784391058143 0.190760553819127 0.697662332013715 0.283803145862184 0.0574324701470323 0.445893720313907 0.267942385377828 0.726232695637737 0.140689051810186 0.737595243349206 0.484948385935277 0.875182658927515 0.93601091116434 0.0837264380976558 0.804421346653253 0.903380591857713 0.792353379731067 0.115551804057322 0.726752010949422 0.811325262992177 0.516484802693594 0.773732486758381 0.592516431277618 0.121416556159966 0.781693675827701 0.0478173251566477 0.488566379663534 0.407251186186913 0.0696829538908787 0.230251973886043 0.176220070845447 0.33695995922666 0.59036874004174 0.0481900107860565 0.63599983649794 0.618005906655453 0.315592386343051 0.740114092906006 0.500821910256054 0.374663093294948 0.444815796187613 0.838144247729797 0.633267760523595 0.505473647497129 0.7934956787806 0.654867962358985 0.0949106756551191 0.56485407006694 0.59054964242503 0.39291525490582 0.226030524347443 0.864596404132899 0.0922806721087545 0.253058373245876 0.22714209881844 0.260418603306171 0.600565900206566 0.613840151091572 0.0820350548205897 0.989904048340395 0.466891926571261 0.725082978100982 0.303157846021932 0.327482346452307 0.618193024303764 0.338360833032057 0.100581366457045 0.853473686727229 0.559854420896154 0.120714532940183 0.678242624893319 0.702078397441655 0.501983632354531 0.744924547832925 0.560894376446959 0.908712329433765 0.0430552111798897 0.846551974916365 0.775900010415353 0.523495628091041 0.376481624657754 0.598094758410007 0.480130509755109 0.170073472701479 0.733557967944071 0.198275530471001 0.499148721680976 0.310396181836259 0.946422051258851 0.697643368816935 0.747592114731669 0.0844814775465056 0.201320083711762 0.513134142579511 0.736620255573653 0.238325941986404 0.943708047128748 0.852273437085096 0.42591230942402 0.131189454414416 0.706163123596925 0.885398920590524 0.67335641214624 0.296254576242063 0.0901655658357777 0.301417908580042 0.461709004300646 0.3799869310949 0.12964929496171 0.778154647590127 0.60920727562625 0.712620465860236 0.640282023402397 0.253652018646244 0.185936732983682 0.713133422534447 0.453520959210582 0.0504341229936108 0.25951074818382 0.886844836166129 0.663038383931853 0.0199353616032749 0.292326039161999 0.932613402602728 0.948741753711365 0.882824413478374 0.617251698167529 0.740918607837521 0.676849732692353 0.129200347173028 0.530732463565655 0.627845793499146 0.505205416767858 0.452377427204046 0.374255969233345 0.819566926383413 0.287865715210792 0.323039369415492 0.894786186590791 0.945256605856121 0.256056680111215 0.588929423978552 0.861600189306773 0.231426328895614 0.922653918699361 0.411873935684562 0.487574638978112 0.0132554209278896 0.372904403796419 0.122604725174606 0.494682981616352 0.829760905154981 0.485728698121384 0.256080274560954 0.629708946426399 0.491758405072615 0.63769639386097 0.905842329158913 0.663884879332036 0.425908446435351 0.513219293139409 0.885604978615884 0.77387814325979 0.530042587588541 0.0675812130654231 0.216953169892076 0.669604088570923 0.99753469360061 0.56883112996351 0.575222742641345 0.654222644327674 0.754292021289002 0.29875648410758 0.758720494657755 0.458967081035953 0.511887858854607 0.426613825999666 0.426513636084273 0.978341763208155 0.120105184798595 0.760004310156219 0.85497561944183 0.831680243718438 0.592915722869802 0.188322616575751 0.980575432046317 0.466395884389058 0.31819870024221 0.888709576562978 0.997527979067527 0.145380845977925 0.267856330096256 0.310455093623605 0.879641835438088 0.991648043084424 0.0634865789976902 0.0499606691184454 0.133519237656146 0.500112057332881 0.388703699449543 0.417172369130421 0.798077850416303 0.205854798834771 0.264550595118199 0.383415192586835 0.821567928467412 0.586322860445362 0.311875005308539 0.464960759088863 0.0944324893364683 0.254246912216768 0.525114418345038 0.386494181493763 0.76881893758662 0.203313329853117 0.263027198025957 0.497858258956112 0.993412059491966 0.191389787397347 0.616086394062731 0.367888085849117 0.692412050275598 0.186248923505191 0.571378481364809 0.232561400774866 0.405562769244425 0.287128701736219 0.750835404552054 0.984434635636862 0.759191625530366 0.582992532020435 0.422835841751657 0.21711716077989 0.867780713476241 0.068571406158153 0.289117074597161 0.307503430519719 0.628621786993463 0.618103721474763 0.408170004000422 0.0425392132578418 0.792457587532699 0.408184896064922 0.397131389060523 0.463151361611672 0.367652903622948 0.670476772955153 0.842145257971715 0.733719844433945 0.36138879192993 0.828142727115192 0.391052861483768 0.921347602484748 0.440211436857935 0.306201486934442 0.237461739627179 0.377243157587945 0.51901713848114 0.326288593518548 0.0704856798937544 0.661081763228867 0.410054698984604 0.2023463635589 0.124847406423651 0.48143165303627 0.207574451148976 0.266801251287106 0.518959350392688 0.0796319494768977 0.247289038507734 0.53601846417645 0.296417088457383 0.540377308551688 0.855729175608139 0.365603008074686 0.905161856524646 0.751278858317528 0.707239265248645 0.8243638471351 0.342592575422022 0.0955233361152932 0.334355529453605 0.692377372120973 0.429575951143634 0.0787602428835817 0.839964027493261 0.920248752664775 0.0173542764154263 0.426607218189165 0.628813064056449 0.396345791225322 0.755414018153679 0.364499593386427 0.744696699730121 0.149932299489155 0.879156338276807 0.530851400466636 0.743982512902003 0.9364452508674 0.627641738308594 0.158511176505126 0.655636644088663 0.944809929206967 0.337655299722683 0.791787662685383 0.651621855108533 0.103715151301585 0.613445903812535 0.832632275305223 0.629787908920553 0.136038610222749 0.0404830904584378 0.366591082620434 0.15761531326687 0.448609640609939 0.106132973989006 0.998761669066735 0.452892455863766 0.747166454133112 0.964871801317204 0.634506524801254 0.577422279154416 0.570263975365087 0.0557170500862412 0.798056321267504 0.176339946351945 0.97141990341479 0.116928612035699 0.279061275292188 0.399285969319753 0.903710930058733 0.834283115065191 0.669769129396882 0.660465090414509 0.97289600004442 0.745444971399847 0.704392894690391 0.176977244284935 0.552096496163867 0.827421937778126 0.231045613256283 0.646899536668789 0.223645438754465 0.323263206086122 0.696644514598884 0.192663041048218 0.131499716783874 0.1464799228427 0.346343221170828 0.354378584048245 0.217656146239024 0.113137135563884 0.740984754632227 0.913050855949987 0.37432936463505 0.981312053666916 0.252817008255515 0.139765340893064 0.56424131141277 0.237601277444046 0.54454703474883 0.814399864517618 0.195247128990013 0.535422157857101 0.195905256036203 0.124542623786256 0.285758087586146 0.412135407854803 0.700320635254029 0.860316162898671 0.725922389472835 0.61370804997161 0.0671371235745028 0.573829274645541 0.132828525877558 0.0365065201488323 0.878400113584939 0.249715273377951 0.777414385185111 0.116187320207246 0.406297564134002 0.345680967441294 0.900093206248712 0.615459458131809 0.202201528337318 0.505952615449205 0.298128200890496 0.591460496843793 0.208568851370364 0.054571172487922 0.395974360220134 0.249625619032886 0.510667229809333 0.66370706821559 0.028495984908659 0.934950166607741 0.287277049352415 0.865240994237829 0.677926550176926 0.662672783713788 0.356367932395078 0.141338133253157 0.724128487284761 0.255379816913046 0.478542312001809 0.478680856584106 0.922249683293048 0.723461410985328 0.0650980551820248 0.21042385235196 0.537385675651021 0.348767038993537 0.941664291932248 0.230558804075699 0.541373755633831 0.771766111426987 0.707707326521631 0.233228938309476 0.747148733343929 0.245338169068564 0.406459060295019 0.819918879480101 0.926652077166364 0.515042089025956 0.301443304866552 0.223503514777403 0.811144934559707 0.379004763632547 0.978173900342081 0.489587898715399 0.0353503195033409 0.423250679112971 0.374446444609202 0.778694559438154 0.288107090112753 0.700269522513263 0.41412398932036 0.380707683782093 0.0668397375266068 0.262848852144089 0.945040550944395 0.571342407518532 0.080569702826906 0.475927088956814 0.557444741625804 0.484281252701767 0.940791212928016 0.121581893411931 0.661339545517694 0.998313842902426 0.903843497945927 0.626145167078357 0.315018971671816 0.585774132804945 0.602813948011026 0.230434549485799 0.114755343568977 0.0169407743541524 0.88995623185765 0.985997568489984 0.280244914705399 0.506386622537393 0.48981501958333 0.377140219393186 0.317639988162555 0.122650442316663 0.541220620253589 0.214656451749615 0.834514646595344 0.164718218585476 0.850631718072109 0.0136879156902432 0.77998190876795 0.309903457965702 0.216272708552424 0.256779470900074 0.534748758648056 0.554819982929621 0.683214652047027 0.485291727464646 0.187800049567595 0.27529123807326 0.142417139126919 0.990911294457037 0.0604178831726313 0.157331745373085 0.556813584966585 0.0481192825268954 0.23610680101905 0.982693952980917 0.355337116953451 0.772443657142576 0.994858997345436 0.528314397006761 0.459187221601605 0.784623104445636 0.537902044912335 0.530396781398449 0.138873308834154 0.343946823906153 0.194315892863087 0.702036110635381 0.0867856821743771 0.857447490547784 0.114834798877127 0.480921925008297 0.0645255212602206 0.712573203661013 0.344480009695981 0.493916231035255 0.663758270160761 0.719714019929525 0.727760945726186 0.0519706089305691 0.649784915598575 0.693832571639214 0.0796778328111395 0.750651367106475 0.199143011495471 0.445029120568652 0.599177924850956 0.492498304666951 0.607599069809075 0.655132664097473 0.0196480381349102 0.682889504528139 0.0918419507867657 0.28232550048735 0.940169412358664 0.438657767663244 0.265672359406017 0.989730436746031 0.936641426105052 0.512276096246205 0.508398497186136 0.211129571446218 0.332393158408813 0.153673827026505 0.656258490066975 0.464920558559243 0.183589915619232 0.553454008791596 0.543598054782487 0.83934358804021 0.492490767010022 0.357259482934605 0.575816440365743 0.680176210345235 0.520231572315097 0.904653809089214 0.468422372424975 0.660967479939572 0.274406556042377 0.642715190630406 0.0831159805483185 0.871649431050755 0.478979482273571 0.934254781624768 0.0794491986953653 0.164664043160155 0.798258687336929 0.40352132437285 0.289306092737243 0.323528323420323 0.360262832730077 0.0703785493224859 0.915862984694541 0.434617806675378 0.564202742609195 0.930718958291691 0.20971591605572 0.568453388956841 0.933193537800107 0.0837720236228779 0.109376810560934 0.816514747664332 0.0839681580616161 0.513764249070082 0.486141120740212 0.908866510372609 0.198904534929898 0.741632908764295 0.527534666147549 0.537870722871739 0.118879988810513 0.586794902724214 0.083961190667469 0.231580322205555 0.361501448333729 0.575553286680952 0.701778749935329 0.0689418058958836 0.15828158949269 0.257481960195582 0.86276602494996 0.410374772686046 0.039638997123111 0.575579567635432 0.315165861591231 0.811278211702593 0.260486284093931 0.49091359694954 0.371584773997311 0.155930716439616 0.667635345750023 0.0470331363822334 0.905038161133416 0.4246699393983 0.711434325496666 0.247798533497844 0.530083894759882 0.25440433378797 0.229108379413374 0.19350594752701 0.944305931928102 0.455727794119157 0.203054118680302 0.92353278354276 0.460238727163523 0.664649759386666 0.947203666244168 0.658637858510483 0.887861928190105 0.86196498991223 0.639478418263607 0.107583302762359 0.22699991760077 0.438318404834718 0.609849548721686 0.87502262161579 0.403066530814394 0.151856895580422 0.404652776904404 0.362879618811421 0.709107225302141 0.233168619996868 0.0715605487115681 0.950071437330916 0.0376690473919734 0.761509237096179 0.290898286248557 0.872808665337507 0.693032512087375 0.248757832131814 0.844874871950597 0.458147281955462 0.364282699676696 0.466120557875838 0.0925162637070753 0.279489231002517 0.308839360752609 0.49876083857147 0.746072455926333 0.401816737460904 0.0294726984552108 0.133796964620706 0.160665858185384 0.955198551297654 0.487373622038867 0.384639986348338 0.847413107675966 0.856814524214715 0.38971645710757 0.0663816171279177 0.323279053813312 0.757266362365335 0.263400481578428 0.756324486020021 0.0784363209456205 0.544600629077759 0.180629755046684 0.608667052600067 0.812740838467144 0.222539837521035 0.303157974181231 0.286253039261792 0.525156648447737 0.651598798420746 0.0546232342068106 0.515062458517496 0.110342682660557 0.361202127910219 0.394895306632388 0.913193982918747 0.806200714746956 0.460651591655333 0.905310163111426 0.47924777592998 0.842937582326122 0.0118296395009384 0.402027737225872 0.589731384713668 0.546363530314993 0.0655238116695546 0.293083548904397 0.0975909024337307 0.34305551931262 0.512548710668925 0.336274234827142 0.9453136372054 0.880210590274073 0.25476822137367 0.897554044825956 0.845625293976627 0.322517596948892 0.478070659502409 0.016341783835087 0.549553778781556 0.951302049662918 0.78567718264414 0.412895110826939 0.721464807116427 0.830081385693047 0.860561872166581 0.787508978263941 0.887570450147614 0.425108745545149 0.793063996538986 0.88862266358221 0.909900346086361 0.0466322121419944 0.370671454356052 0.41437067684019 0.0518645209213719 0.545917540332302 0.65937652929686 0.464722284136806 0.127334549922962 0.67638154049404 0.455272561914753 0.201491803573444 0.847278073644266 0.179006782327779 0.43427384693874 0.465171147100627 0.605921412024181 0.366917190412059 0.216902838784736 0.757942296869587 0.979459197048564 0.0590517038875259 0.950700961803086 0.396696814475581 0.984042387965601 0.703236808604561 0.0235466758348048 0.6543976723589 0.788209291847888 0.577251798473299 0.389262120865751 0.710760125061497 0.699264291217551 0.603008756139316 0.302716921558604 0.313074033979792 0.8557645969023 0.0685800907947123 0.567435425403528 0.31793017861899 0.582393722676206 0.393061596921179 0.584051874661818 0.761095250057988 0.775723081431352 0.738045755787753 0.869508553233463 0.0759738280577585 0.721974868911784 0.112575610203203 0.881199877262115 0.672268851178233 0.0976492746151052 0.399281324236654 0.804950529539492 0.521029659688938 0.15639194885036 0.705033406747971 0.667922303411178 0.544195775003173 0.401284954277799 0.255187615996692 0.885853577230591 0.443372960353736 0.60674278290011 0.523849500580691 0.710389813375659 0.483369334745221 0.593073807135224 0.517725046565756 0.695732277166098 0.282444124366157 0.492316739128437 0.464340085214935 0.592737091165036 0.0386217976850457 0.179213995630853 0.524750604059082 0.0620866924338043 0.335486660434399 0.342470307762269 0.156917580848094 0.181420664808247 0.578474947370123 0.679784356141463 0.908628245177679 0.627147936609108 0.292442398816347 0.060062576958444 0.498796549607068 0.872032109417487 0.102528248897288 0.610018336593639 0.803473050587345 0.558701580283232 0.113708006641828 0.0432877666014247 0.555166743961163 0.0181488424050622 0.0336865326575935 0.57448413616512 0.0236920193140395 0.757434313283302 0.508641855330206 0.831899209413677 0.668464884476271 0.841663445390295 0.755269095802214 0.993792992264498 0.523304825401865 0.236803401210345 0.693892983766273 0.192276586131193 0.0393462252710015 0.427978752504569 0.895453077796847 0.774747111254837 0.163027014639229 0.674456025159452 0.320454626155552 0.36714143345831 0.194779086157214 0.687254982069135 0.149695096679498 0.865952373777982 0.910572625745554 0.716939070750959 0.991373654715717 0.467625620812178 0.708033151717391 0.415863896105439 0.0455334148765542 0.784567358838394 0.52406841787044 0.417432390749454 0.723441694967914 0.283014580078889 0.890561747206375 0.436789942684118 0.562930305858608 0.792630426483229 0.814679651481565 0.294761710797902 0.0520217334269546 0.440925036135595 0.708883122401312 0.545361439844128 0.900303368829191 0.609526360703167 0.188123849108815 0.0941377303237095 0.044720929635223 0.602669036723673 0.628323808093555 0.570290875448845 0.720767406160012 0.728631745984312 0.897240360188298 0.475433775461279 0.631283117651474 0.470725405409467 0.0983758726110682 0.71298209337052 0.571086800480262 0.517825443472248 0.250735912371892 0.175932939155027 0.872117390441708 0.0222848267480731 0.0725904167885892 0.865829120720737 0.0692514313873835 0.503233939036727 0.605593384148087 0.409377681810874 0.965688204176258 0.221916432424914 0.255091032981873 0.819554819017649 0.583236340566073 0.121309193242341 0.0884169995388947 0.954988514801953 0.383556551602669 0.494238821822219 0.279742214693688 0.165080267915037 0.929562944814097 0.85278541573789 0.948020861570258 0.509127006507479 0.202271318912972 0.595762412443291 0.957069537385833 0.979477068816777 0.480723355542868 0.687792228618637 0.0608415877283551 0.164783611407038 0.489516313218046 0.472331308508292 0.956702182122972 0.358183318092488 0.301287680291571 0.185669142589904 0.744095535113011 0.74850075794151 0.703461450880859 0.28319256430259 0.403298409942072 0.847446992211044 0.917528511141427 0.114402106804773 0.358172578988597 0.350663697279524 0.438856232480612 0.503586067315191 0.510476394619327 0.236709624791984 0.90304469693685 0.678603168581612 0.803926200894639 0.301391010570806 0.739823983586393 0.0955803312757052 0.747787110258359 0.375062601789832 0.785317326313816 0.44500185721321 0.454634527757298 0.601190656968392 0.675050543241668 0.836736130618956 0.84038399675861 0.843038270126563 0.14961238713935 0.278668927582912 0.242124700257555 0.601909401980229 0.70869422550546 0.516760462052189 0.923169455616735 0.516638413600158 0.791109936947469 0.879453553983476 0.117667424581014 0.830706303576007 0.522108158457559 0.593236922114156 0.686497532026842 0.371263727806509 0.688182918555103 0.0426340089575388 0.741688379382249 0.0748585915961303 0.977999271771405 0.265136290031951 0.934448194061406 0.0165064293495379 0.833258203249425 0.134162937791552 0.897152737490833 0.0856224696477875 0.103471815516241 0.416953358717728 0.674423571121879 0.135960375654977 0.0294423871673644 0.931027480138 0.902776451916434 0.396357721104287 0.03853449446382 0.224233000506647 0.806865542035084 0.533286606257316 0.839152118968777 0.51155523983296 0.92688796818722 0.0654859094787389 0.454281312660314 0.860467268705834 0.463398595883045 0.119912219305988 0.381859578182921 0.0387894906708971 0.616364198476076 0.252781245126389 0.364476867930498 0.562714315948542 0.381636507932562 0.871812091940083 0.815666515429039 0.165577702792361 0.155770066913683 0.570031262049451 0.423833837118 0.704465753252152 0.671306717365515 0.902255694812629 0.316122165999841 0.653338821609505 0.423133446085267 0.802638574731536 0.308506859748159 0.88100263848668 0.405184823321179 0.296691451240331 0.333499583227094 0.345044707460329 0.193905097360257 0.110255716664251 0.356737485958729 0.929318027091213 0.675132339762058 0.256422489164397 0.896975666517392 0.865067764124833 0.44903552249074 0.268147128848359 0.31928398223361 0.156050590793602 0.537483433536254 0.818072171742097 0.0771147397137247 0.16007596374955 0.824296643026173 0.672511727572419 0.133371018429752 0.404069367651828 0.415256749030668 0.529620899697766 0.432976848320104 0.425154317009728 0.150823204852641 0.506757273522671 0.655548055816907 0.67214941408718 0.428918921749573 0.854011260359548 0.53602304126136 0.89182623969391 0.390853174773511 0.271799374301918 0.102403097883798 0.185890475083143 0.11002169709187 0.475321518748533 0.528343847368378 0.455501486463472 0.633548728581518 0.851418663884979 0.407490630170796 0.391864460443612 0.736745919454843 0.986583393176552 0.0574537821626291 0.228802973497659 0.188796899337322 0.425433117423672 0.75941571506206 0.631671149895992 0.94080086452188 0.934676427333616 0.395428357578348 0.65971672977088 0.960957919114735 0.384636131427251 0.0282363622891717 0.435203197556548 0.56367517254781 0.486046469795983 0.0798252634890377 0.306348803744186 0.204507892080583 0.751685831861105 0.759447748202365 0.910964887246955 0.263050308190286 0.480563418038655 0.0933461228315718 0.885691923175473 0.14304378393339 0.403062263524625 0.665542041771114 0.413618698001374 0.524074343394022 0.0165266501670703 0.333069084153976 0.508935564635322 0.353050359508488 0.696446491193492 0.18938424971886 0.720263295704499 0.44196260206867 0.763207160646562 0.440371263951529 0.992078719874844 0.745797993566375 0.827398612785619 0.644006479014643 0.734959290998522 0.707668846000452 0.415159007050097 0.161038341433741 0.881046238695271 0.0781045266613364 0.278252032296732 0.470456316750497 0.575772076502908 0.0258531048102304 0.855377846942283 0.747981617581099 0.738303737230599 0.96280026182998 0.138081644868944 0.219661567513831 0.87628993821796 0.490148642673157 0.564013073991518 0.566494039567187 0.0919618062395602 0.34882286850363 0.0220466802618466 0.341844235523604 0.583356893979944 0.948918688918929 0.994566985459533 0.980301371451933 0.247600297569297 0.492736272974871 0.553753594292793 0.448360554021783 0.363273635357618 0.124569548764266 0.678464735331945 0.874219019243028 0.250251653469168 0.298831109239254 0.483449842988048 0.331687473889906 0.503300744837616 0.616586416559294 0.227300037175883 0.445442033235449 0.927821301193908 0.744008310954086 0.0921413717092946 0.579139951223042 0.870018021024298 0.169834250921849 0.14530012982199 0.0830262356158346 0.494109841473401 0.440208527687937 0.161991529911757 0.62166804872686 0.672633792620618 0.196876264880411 0.99026471742196 0.977382376752794 0.284342527785338 0.443913430708926 0.603823633533902 0.189766676607542 0.685623092136811 0.15012742962921 0.469512912405189 0.870263321611565 0.0222986852400936 0.897840598647017 0.36079626953695 0.338897343587596 0.233611052867491 0.921529484502971 0.397340022257995 0.931142491353676 0.399609763328917 0.19256222831551 0.996066302664112 0.0931257335538976 0.309010974122211 0.0551614968106151 0.785286197434179 0.0763515628408641 0.0185847695777193 0.110491669459734 0.829024353607092 0.416917111072689 0.424694762194995 0.725157989093568 0.93222414846532 0.204490745703224 0.9722420220403 0.589603108779993 0.65132527904585 0.246492710097227 0.574321094024926 0.55071411394747 0.222534329437185 0.0576801953883842 0.142461345326155 0.251576591967605 0.649755330854096 0.753486511739902 0.877967643025331 0.535328290851321 0.212981056114659 0.0113605086971074 0.254260985075962 0.78414823228959 0.288355604594108 0.991153606350999 0.916962846419774 0.972323936808389 0.0840263343160041 0.273658381414134 0.494982188863214 0.459500976542477 0.339060779195279 0.989435132825747 0.579559542464558 0.485004421975464 0.402199788319413 0.59420927086845 0.81689515235601 0.994098876933567 0.08650814675726 0.910809560480993 0.359464043246116 0.445475407899357 0.0765404230868444 0.62397396529559 0.937855215915479 0.533603001141455 0.515846184212714 0.826611080805305 0.707806257894263 0.415517872220371 0.326164871389046 0.33906193216797 0.842986990271602 0.710839232772123 0.252359736105427 0.013776940763928 0.0687049942486919 0.548621125987265 0.852636011959985 0.177314881803468 0.0468014451139607 0.984776632646099 0.850030315346085 0.517176437403541 0.846388956748415 0.238259877020027 0.25860678762896 0.746633160698693 0.936870621955022 0.178651778532658 0.551652011591941 0.272768242701422 0.839264394813217 0.79437654876383 0.303465259613004 0.808729832030367 0.264286255729385 0.979512215352151 0.260346451925579 0.333421501482371 0.265273050065152 0.643348507788032 0.0717670442303643 0.928484063872602 0.859437978728674 0.818841599838342 0.441593080314342 0.16363058477873 0.816957387526054 0.718224330116063 0.198635221070144 0.11445244736271 0.255290142053273 0.223701033382677 0.949497404452413 0.697964739094023 0.68179244617233 0.550805155225098 0.423235564844217 0.679186431465205 0.868754779472947 0.812360276803374 0.238794427153189 0.783421897757798 0.458695769181941 0.24528938601492 0.850816471918952 0.176773641109467 0.79464793829713 0.688315986632369 0.883594977720641 0.528319197909441 0.84965542588383 0.665206536860205 0.177100785009097 0.147582620668691 0.632758676749654 0.929420208085794 0.951462682823185 0.324064604395535 0.693222109249327 0.615742803360335 0.807148533212021 0.450227672280744 0.780399347809143 0.848927060395945 0.728575820124242 0.701807185625657 0.553567555164918 0.205294953605626 0.0661514245858416 0.34119412811473 0.718575740840752 0.361282967154402 0.0276831423887052 0.700111708166078 0.796078226505779 0.882947036572732 0.115880058286712 0.45001845798688 0.21526386551559 0.53135033430066 0.563914863169193 0.30547580126673 0.909191214866005 0.316753941788338 0.667034102531616 0.790122110191733 0.638830600664951 0.208584739665966 0.101247652133461 0.890098720104434 0.834049026572611 0.307270029385109 0.200954543885309 0.522840536299627 0.175524619708303 0.170518370564096 0.506002187512349 0.696771546511445 0.386718298455235 0.0845446158247068 0.308711076520849 0.346085474148858 0.314843599270098 0.873823208927643 0.0794339548842981 0.0434029370942153 0.934474104829133 0.978244775892235 0.889272992503829 0.0227222952898592 0.996840079647955 0.275262274071574 0.44614237862872 0.90829287441913 0.339626337885857 0.0981936153350398 0.348796261388343 0.298052961931098 0.644326551794074 0.0911615966306999 0.817014022641815 0.118379648220725 0.490165122437757 0.227081947389524 0.424882776036393 0.144672174840234 0.681887784013525 0.683536981674843 0.238621880940627 0.282782166877296 0.865869370577857 0.317634404934943 0.756085137694608 0.3968004785222 0.998097059833817 0.342371775389183 0.388926730975509 0.886276519976091 0.554377801076043 0.725455180366989 0.684012992281932 0.496393373729661 0.639952053774614 0.0755700303753838 0.302687458058354 0.646631758876611 0.92554975183215 0.481424429323524 0.616389284736943 0.906371135634836 0.297773180499207 0.224592639473267 0.0278044472401962 0.981878901787568 0.0177719503385015 0.640674339763355 0.406083499840461 0.309114468288608 0.472683143818285 0.359664587886073 0.531565455216914 0.89128443012014 0.9279936729162 0.68689502408728 0.859843369643204 0.233390486333519 0.937708809820469 0.786593702118844 0.0173207749752328 0.883939474758226 0.942068666561972 0.567309245427605 0.468518142227549 0.544648646863643 0.0397019553789869 0.546195273520425 0.0368777653691359 0.525311417167541 0.937397382261697 0.455599715034477 0.894570771323051 0.963531919121742 0.875206381536555 0.0659425790957175 0.47569976455532 0.440700614911038 0.384901441922411 0.690339519628324 0.558194381326903 0.133536683917046 0.859414700067136 0.277502409883309 0.893972987944726 0.720333875289653 0.13419865966076 0.25400564127136 0.280326537657529 0.315136637813412 0.276039631217718 0.544023165632971 0.23149621351622 0.874731729971245 0.846068104640581 0.717937319669873 0.383357115448453 0.128008484819438 0.910996395302936 0.732949367321562 0.523972711686511 0.333130507725291 0.927200814487878 0.655046117384918 0.528910442166962 0.189377011484467 0.616792535898276 0.0262959763268009 0.136016269014217 0.619488378288224 0.86162856368348 0.955216938930098 0.275679996630643 0.92269872374367 0.273658132932615 0.317006162977777 0.807867510570213 0.304851048884448 0.0784767960035242 0.555891752182506 0.920865502236411 0.760393201252446 0.658643638356589 0.843272788044997 0.173085085544735 0.474251790593844 0.665102698553819 0.573584501447622 0.904378458603751 0.276204277654178 0.632722735672724 0.401858097878285 0.086870873994194 0.0629049833375029 0.873381356461905 0.039807342661079 0.715505212061107 0.142407948998734 0.20890054515563 0.426578561216593 0.9464019666682 0.93273865734227 0.897573629226536 0.660459723859094 0.70085356403375 0.0163874117727391 0.565059112499002 0.0654967880365439 0.841251316661947 0.186540832126047 0.318507830384187 0.405114991946612 0.297671249138657 0.729123123951722 0.420597014271189 0.760576747728046 0.505625213617459 0.881795492996462 0.174408652554266 0.556258064422291 0.0383391559496522 0.403029414406046 0.148145445832051 0.970416243684012 0.50641578200506 0.183118203189224 0.693844660334289 0.821513295264449 0.887208924980369 0.7026791314804 0.462099278641399 0.19749352455372 0.895251334083732 0.168369812408928 0.904423010095488 0.187373119592667 0.500325188783463 0.387772118491121 0.525547501118854 0.862977675884031 0.579053833244834 0.210767884235829 0.141573510484304 0.0354582134983502 0.656049769048113 0.435449495527428 0.282048948393203 0.61072607281385 0.491146417679265 0.332736441621091 0.414444290527608 0.814734725174494 0.964786764394958 0.253870956220198 0.942134183393791 0.687199465581216 0.3183045015065 0.845774753997102 0.864102728518192 0.0426197530794889 0.122153264910448 0.237060820457991 0.319260109798051 0.948771231733262 0.657638375482056 0.194569807783701 0.0804709789063781 0.698579198855441 0.264390912319068 0.461764197393786 0.0926868388941511 0.3992792872875 0.195490724551491 0.0962416328000836 0.14217179981526 0.801365519312676 0.21177780487109 0.603811144917272 0.10829976119101 0.663624241119251 0.0679503222205676 0.446785897358786 0.573950357984286 0.867579673947766 0.684433346255682 0.177954702815041 0.197020168411545 0.0588975342432968 0.153005082351156 0.3025914436928 0.230385976880789 0.855620906355325 0.528013077897485 0.255252632407937 0.969604314414319 0.17997721952619 0.627236604865175 0.326452602155041 0.137856653381605 0.0471819712803699 0.82086308873957 0.169213901825715 0.0779223147942684 0.692579552636016 0.191375201900955 0.816226139836945 0.511485136235133 0.583934480282478 0.674199787005782 0.339521174652036 0.992646711056586 0.821855298958253 0.50344304776052 0.584838453745469 0.655043080747128 0.0901311363931745 0.165847035322804 0.0275579964462668 0.583227580555249 0.60364318754524 0.421415771711618 0.247509894783143 0.989735177948605 0.212651431318372 0.883472940793727 0.240792216726113 0.606931322056334 0.678143248420674 0.540387456647586 0.921157178971916 0.33668190079974 0.210007584954146 0.0874469975288957 0.288327175818849 0.425425681418274 0.981890091984533 0.0180907242372632 0.861882155439816 0.701740634760354 0.831457893326879 0.188574066043366 0.47143134601647 0.295795999909751 0.149387583511416 0.411325770008843 0.314897371546831 0.55194988907082 0.155394294166472 0.598380448769312 0.952966185489204 0.59388499787543 0.288157884990796 0.768041486395523 0.88017385304207 0.918609024269972 0.0995503002288751 0.786154685984366 0.652830852083862 0.380382403954864 0.817011075669434 0.597366369641386 0.751145945598837 0.205084589796606 0.991827235601377 0.395900671619456 0.0577088613505475 0.817116710050032 0.179977944225539 0.355669619340915 0.317061971973162 0.38478157794103 0.358856716610026 0.250680740484968 0.886701071166899 0.709105335413478 0.517212774713989 0.0952301256172359 0.175949682844803 0.260307063916698 0.863505646097474 0.0385861537256278 0.24917334532598 0.228004952508491 0.360670017413795 0.212424800728913 0.215899447819684 0.392656654333696 0.56290643250104 0.265326056843624 0.986941663189791 0.0534105826169252 0.902283680562396 0.277123765998986 0.850588540143799 0.0630978096066974 0.517836238127202 0.0307221529702656 0.785585859001149 0.407442413691897 0.437491763061844 0.344854823092464 0.423012461632024 0.476135229570791 0.558006973476149 0.796800364051014 0.487567760327365 0.703219329151325 0.599875127344858 0.963004925546702 0.449504581838846 0.285691450512968 0.737685348787345 0.883993834124412 0.957056655993219 0.259764500600286 0.473995743987616 0.898631801377051 0.786024837333243 0.202970946752466 0.721456690437626 0.945948012599256 0.472949509783648 0.238811840221751 0.958267919037025 0.743798459551763 0.406584116802551 0.813226477848366 0.523914149801712 0.501356144831516 0.606203252994455 0.797100665953476 0.605280909647699 0.203439504757989 0.319542860791553 0.504570776526816 0.942237301380374 0.0634701577806845 0.678990416196175 0.819213413246907 0.981712497770786 0.845368384600151 0.272904652601574 0.170810547489673 0.403214128836989 0.672215755656362 0.661875332065392 0.548829937824048 0.586857916531153 0.695816095191985 0.0129556904407218 0.914778666894417 0.614880436260719 0.0635575207020156 0.764826672603376 0.498355387265328 0.876821253711823 0.234641913257074 0.364575234111398 0.266525031807832 0.0588324309326708 0.167149473105092 0.346876195359509 0.514623162322678 0.58168257847894 0.354674622579478 0.180246885593515 0.461158481277525 0.980596515173092 0.832453532728832 0.460639930542093 0.243477789314929 0.74310389216058 0.577977433660999 0.0599831334059127 0.569284810656682 0.160842973645777 0.124878458085004 0.487525677285157 0.668716829062905 0.747087681572884 0.809452997385524 0.316115124614444 0.324761287798174 0.686544734064955 0.868699218498077 0.49275888410164 0.686424050186761 0.424792976705357 0.656007808633149 0.472634439826943 0.0961391111230478 0.896142074407544 0.320324110200163 0.977498000643682 0.187918695113622 0.626806651160587 0.0251876802905463 0.612787847069558 0.502197023350745 0.857369611645117 0.76784900150029 0.54349409500137 0.813738935254514 0.23692427548347 0.664833745430224 0.601645535582211 0.0163447153638117 0.732374133986887 0.031640626413282 0.481528046347667 0.567588281414937 0.689336883097421 0.807161093053874 0.0890139358211309 0.0206235901801847 0.355020833171438 0.909850417436101 0.218147812334355 0.876168430754915 0.273162981641945 0.760578369542491 0.182204522581305 0.0693487580027431 0.0592349746823311 0.832542294568848 0.447892914568074 0.682383251783904 0.88249612720916 0.517828374309465 0.229637325573713 0.631841471530497 0.567224770931061 0.996138284625486 0.957102403331082 0.83857645344222 0.610960584969725 0.796154000461102 0.3584274889878 0.0123573958082125 0.440524572669528 0.227310044434853 0.630745765762404 0.519078361745924 0.0486091389483772 0.0841914246999659 0.713504897796083 0.605010750766378 0.636095945369452 0.972039295234717 0.31440728047397 0.233715088022873 0.477732347534038 0.781679240618832 0.935004595355131 0.404787401102949 0.540987045781221 0.378236065306701 0.300552430620883 0.317508458227385 0.631136436336674 0.367327255222481 0.539126015088987 0.147523146686144 0.90839050483657 0.837880919785239 0.303925285805017 0.876743668930139 0.491796958432533 0.457097810115665 0.891604405397084 0.259261372776236 0.332912056280766 0.539675278647337 0.749542247946374 0.460776716622058 0.691368868614081 0.145161550203338 0.530400792139117 0.131435896910261 0.413704567959066 0.200919922203757 0.763662107028067 0.742302795809228 0.330997923843097 0.277809252981096 0.0148963772086427 0.126308649252169 0.262028792595956 0.688913486723322 0.912905011589173 0.207104464950971 0.148199536432512 0.121795604575891 0.309320813750383 0.673845330653712 0.221268435034435 0.443559225834906 0.133181566714775 0.515070370740723 0.937840469528455 0.920366248004138 0.33114413009258 0.795156395104714 0.886881637247279 0.788032529978082 0.535024727340788 0.106486836797558 0.470848504952155 0.912263733111322 0.330768489884213 0.996871523624286 0.181581908799708 0.689807268986478 0.777809367305599 0.136062581313308 0.142333367662504 0.576570464451797 0.373405316032004 0.838693471641745 0.686622911698651 0.84143775501987 0.422056480157189 0.998607987165451 0.789186159370001 0.853512654991355 0.336980801247992 0.826775361665059 0.178382573931012 0.447381244788412 0.994971221096348 0.361450339511503 0.72366890711477 0.4062873860728 0.544332029314246 0.753013026746921 0.0347873505065218 0.464191399682313 0.133769757968839 0.512640359550715 0.426080164222512 0.96721986685181 0.215915904764552 0.287983307591639 0.406364756256808 0.41722309647128 0.767107897992246 0.555067509247456 0.271064683368895 0.136262900982983 0.77133264094824 0.506011673836038 0.280703397914767 0.315350823581684 0.296545754401013 0.858102761439513 0.241245515476912 0.482267807410099 0.449834285697434 0.712262587009463 0.808810517990496 0.708341537336819 0.546206294759177 0.427019696589559 0.744558519111015 0.405691040568054 0.912374774154741 0.277496286588721 0.311078309477307 0.18540841471171 0.989461706287693 0.384070399168413 0.153928167915437 0.368152158085722 0.459246722322423 0.897413456148934 0.987964175706729 0.529161703544669 0.0749196465942077 0.73348764606053 0.649703191686422 0.580494874618016 0.991041075340472 0.849266097755171 0.126710165191907 0.45200677045621 0.855629187843297 0.178017914392985 0.366205859046895 0.755081306009088 0.642533889017068 0.586470037570689 0.657929174234159 0.0571248371177353 0.407833806199487 0.456779244591016 0.17802243177779 0.919832779387943 0.494021927651484 0.105428532338701 0.0743995339749381 0.0497941846563481 0.728068708758801 0.182587870787829 0.860459829934407 0.535415579320397 0.253414409691468 0.352794019703288 0.621187428995036 0.653700736556202 0.452124502290972 0.291530579745304 0.615930118779652 0.661873332227115 0.647460665334947 0.493180255512707 0.242211831524037 0.104246072866954 0.272219758932479 0.683155042298604 0.556000139683019 0.763225009825546 0.8935445394204 0.899585992540233 0.602800335464999 0.494977052810136 0.271567886797711 0.482568416572176 0.59221943062963 0.240877570358571 0.86513086252613 0.0818106679408811 0.0482074522064067 0.934171622374561 0.769434249284677 0.721093408381566 0.623574261565227 0.0642642588471063 0.209835805392358 0.877520251127426 0.284983007342089 0.733272823183797 0.336266720911954 0.108138688462786 0.427658205351327 0.946433453978971 0.875914759475272 0.84143252999289 0.109119155509397 0.550949271048885 0.951857101595961 0.295572589898948 0.744938028301112 0.898106846364681 0.749242909082677 0.066422386537306 0.282502952711657 0.514794769468717 0.35547045448795 0.226884532049298 0.454405398983508 0.991870206999592 0.732189231466036 0.0995847031637095 0.356021528872661 0.771425939304754 0.716538861298468 0.572154333791696 0.414498806404881 0.373442057643551 0.536325454104226 0.129824550037738 0.544707424498629 0.682117312247865 0.204916740530171 0.787571777934209 0.489037785525434 0.271351366501767 0.480401205937378 0.223750219584908 0.531900433660485 0.746457923601847 0.256197574203834 0.501554743801244 0.673445575060323 0.498876536914613 0.356956781963818 0.190830896908883 0.359128132420592 0.944407187686302 0.11378725795541 0.0546043101954274 0.0685918994294479 0.734014463762287 0.0350997814419679 0.0760790247144178 0.782137690635864 0.167206652206369 0.925281806003768 0.0942596029024571 0.0304853540007025 0.900823092360515 0.109171560676768 0.984543924401514 0.230355496173725 0.294016694743186 0.149957036538981 0.0482800046610646 0.797050529390108 0.774537176180165 0.578516739748884 0.336563394707628 0.819497985439375 0.549155040855985 0.982777019569185 0.612913134309929 0.671874514464289 0.546671264534816 0.273803384671919 0.860779823421035 0.0572099519497715 0.950371656252537 0.635598613526672 0.304220003096852 0.909441806864925 0.133449603822082 0.546710087812971 0.847642713589594 0.836868973956443 0.394486167519353 0.263989273291081 0.393282409401145 0.199994388013147 0.896190919696819 0.121577694581356 0.567712051719427 0.288588648219593 0.844461232970934 0.977669677631929 0.109746489056852 0.0777363010216504 0.412343905286398 0.547697855560109 0.404831554747652 0.708321840912104 0.788015994201414 0.151513722087257 0.887544427816756 0.162156186259817 0.618819013100583 0.636156021654606 0.510577032170259 0.175532748373225 0.793697947117034 0.497536319799256 0.236591894340236 0.136227035971824 0.950118152778596 0.804749421321321 0.609789770706557 0.935387060507201 0.664876414639875 0.76678808614146 0.607254899854306 0.227250968529843 0.906217773440294 0.703675409373827 0.779560707237106 0.698678313707933 0.623263275648933 0.404291508516762 0.508038256147411 0.789980566082522 0.897118310122751 0.989265425940976 0.810475277556106 0.597944167314563 0.483635056687053 0.56709411759628 0.516618279682007 0.0454740669787861 0.896705775940791 0.321400451005902 0.671401818711311 0.45820124116959 0.921915071117692 0.0134422527533025 0.120003532806877 0.429624509457499 0.932008489556611 0.360934209742118 0.182854315354489 0.683739446860272 0.683446093450766 0.554539089784957 0.196932493851054 0.64371376501862 0.608314072384965 0.816704699338879 0.968125874958932 0.776078836664092 0.601557738855481 0.87498965010047 0.255267434807029 0.144740752282087 0.687507930032443 0.939151801473927 0.843962915269658 0.641693567391485 0.0870209296327084 0.671817197061609 0.976108275314327 0.614118708786555 0.196345879693981 0.301392792353872 0.365561028989032 0.730364116725978 0.0631392705230974 0.553786199078895 0.0471054341318086 0.762423417433165 0.934752828255296 0.229357197466306 0.927439825357869 0.431356212894898 0.265414706429001 0.719106586570851 0.244641981937457 0.217566420207731 0.143813707148656 0.948079639435746 0.460101660331711 0.722186233792454 0.0985965898935683 0.349353982538451 0.409088859155308 0.130084796166047 0.528872933213133 0.152464941614307 0.0920660188817419 0.197708104711492 0.437214162643068 0.382711972598918 0.952702832880896 0.887332754754461 0.0619160282728262 0.346275250872131 0.660417034365237 0.559292890925426 0.784356854192447 0.330256359560881 0.0582475420855917 0.255020452013705 0.261522837660741 0.50127701937221 0.208990138417576 0.219398769955151 0.677033136487007 0.925044009650592 0.606461928479839 0.113860172298737 0.366825850403402 0.669713867153041 0.591683714385144 0.360827627535909 0.114247858098242 0.400318747719284 0.636862476742826 0.185386538195889 0.720140864849091 0.55703819335904 0.874681479539722 0.172948575837072 0.634807425087784 0.538250314351171 0.633295388072729 0.268900722817052 0.110168264077511 0.914460822842084 0.376614637183957 0.55375533758197 0.0408176622958854 0.32106085099047 0.301648631046992 0.25059168844251 0.19829392156098 0.027111249724403 0.516850516779814 0.635683518832084 0.407246850898955 0.554745966324117 0.491132613816299 0.0859063249779865 0.381852835759055 0.71161830623867 0.32929801451508 0.296911425383296 0.191369085521437 0.881504547183868 0.283263905697968 0.337203637077473 0.554928254487459 0.966000684900209 0.272037448179908 0.29936671806965 0.913974361259025 0.479973417571746 0.726542760466691 0.468982427180745 0.584361197042745 0.680921132354997 0.933917259818409 0.0270854412997142 0.388690941606183 0.932701332329307 0.116593551302794 0.207825729583856 0.882936217945535 0.070090148486197 0.461027974772733 0.349697011276148 0.165113958367147 0.0565872353641316 0.425033778117504 0.302685163407586 0.261459127736744 0.872352978582494 0.050209349100478 0.51230985123897 0.994055060744286 0.934018507509027 0.0850265752361156 0.656338485903107 0.898578182845376 0.266515310602263 0.0474333177134395 0.3355460115592 0.262536129853688 0.835332328050863 0.422874094536528 0.681564160806593 0.849760658268351 0.384419952735771 0.844222143499646 0.0385006710118614 0.258211834321264 0.9526554648811 0.509128737349529 0.573336385504808 0.246671579680406 0.0496894999453798 0.912878563059494 0.653190922550857 0.102483841008507 0.153067271881737 0.798105940122623 0.258342451697681 0.781819866176229 0.0433842168468982 0.274095164211467 0.36384891364025 0.578798077071551 0.863682603663765 0.409060935180169 0.631300000334159 0.251237761368975 0.481900623179972 0.550034637544304 0.45832071053097 0.300597571968101 0.773049100574572 0.542694706672337 0.195741041791625 0.362176695019007 0.144318539537489 0.603551061984617 0.952677364677656 0.681224290872924 0.322653013614472 0.352505879565142 0.49410893306369 0.779372171538416 0.711225840281695 0.226163369989954 0.0572261959104799 0.152150835848879 0.994798479648307 0.778762865348253 0.567128005127888 0.679640857602935 0.653582208566368 0.605815894508269 0.0741942780977115 0.809457294179592 0.479497977688443 0.717421861584298 0.101604067524895 0.805498191106599 0.701880088213366 0.142023316202685 0.829546070753131 0.277770804038737 0.496348968606908 0.594298026023898 0.140030818502419 0.278110087343957 0.0214834872167557 0.0487117991573177 0.414648768920451 0.141453377276193 0.196602137901355 0.812316588312388 0.502052807949949 0.498659736327827 0.256342375311069 0.72197719306685 0.120280309640802 0.6267017477029 0.682020102036186 0.0141387314698659 0.605798164498992 0.616196745904163 0.353818321840372 0.911602905960754 0.671621771878563 0.58591643180931 0.462617498375475 0.405333182923496 0.831885814922862 0.890511391204782 0.694879489743616 0.568584379747044 0.851984822112136 0.606391309709288 0.852420363193378 0.404061190581415 0.339781497537624 0.0753335868404247 0.672525158943608 0.633577969647013 0.687026719062123 0.668065358002204 0.636153385399375 0.102930424534716 0.0757959424890578 0.937802019203082 0.624332247064449 0.503966867779382 0.692067409865558 0.690944927101955 0.150118165509775 0.640882952907123 0.263774249646813 0.521548633165657 0.0260644761449657 0.81491307382239 0.164798697324004 0.13071768989088 0.753427817777265 0.877206553120632 0.196380859576166 0.40693210733356 0.158522182530724 0.986006698226556 0.812152788280509 0.0514773897104897 0.90853331716964 0.886495111796539 0.746687522830907 0.753056883735117 0.365141663870309 0.109139046247583 0.296005568255205 0.512400403851643 0.886776454190258 0.291265990952961 0.444787290424574 0.851885805914644 0.629404625485185 0.155841771350242 0.795455193901434 0.880044517719653 0.753467685692012 0.786774390365463 0.349996080452111 0.0903271652618423 0.628749204305932 0.113227562783286 0.863664194594603 0.0996184385637753 0.113882825607434 0.644240177958272 0.26433409210993 0.721525334033649 0.976993797526229 0.075715620953124 0.816893925622571 0.0755280418391339 0.526920636503492 0.0601628482411616 0.168236512215808 0.455653568909038 0.640980239415076 0.660808495101519 0.784950546845794 0.559775986252353 0.312869297654834 0.121164608807303 0.803896260024048 0.430041549960151 0.820931727495045 0.265376844345592 0.0846117613860406 0.354169922268484 0.603775121090002 0.602204743011389 0.254934298538137 0.935686022038572 0.506333792554215 0.122029047431424 0.781090217712335 0.883444077752065 0.679337712684646 0.102617916150484 0.529086338961497 0.601149139117915 0.423720920938067 0.786217508243862 0.204374766608235 0.35767557192361 0.094466219895985 0.568523597894236 0.868512205497827 0.889726766319945 0.514551241444424 0.717031383248977 0.2116400695825 0.664309628754854 0.572135616079904 0.275485466027167 0.848470766267274 0.36466398073826 0.61893653540872 0.713148373146541 0.776113202949055 0.462271653129719 0.0966399067244492 0.0667524266988039 0.626042856541462 0.64597774537513 0.0784630695893429 0.247766909268685 0.016368547922466 0.236729552871548 0.359650683985092 0.906319595081732 0.127970840099733 0.323915731695015 0.895740864805412 0.534167143164668 0.821722324695438 0.351785073170904 0.0955593776912428 0.883993178575765 0.410137833110057 0.359117268384434 0.161813674538862 0.256240296659525 0.29392443664372 0.59506208272418 0.774046905776486 0.175538838244975 0.567579978720751 0.51536431492772 0.420540678347461 0.824585456692148 0.791773965083994 0.078050080165267 0.905801385028753 0.878066334214527 0.616763023762032 0.163541026322637 0.719959023168776 0.641115791155025 0.224869626294822 0.78008762820391 0.97506544171134 0.625828073080629 0.53991011304548 0.283388897434343 0.805422159910668 0.728418510577176 0.731699803548399 0.801147869785782 0.489703654684126 0.775988339832984 0.970311486825813 0.152616252338048 0.351980324094184 0.0651477007754147 0.594251409000717 0.43758563951822 0.252306495597586 0.292805913679767 0.505559943192638 0.9094192888611 0.471718896068633 0.85006660701707 0.207712723277509 0.586957130038645 0.509553818926215 0.70630919292802 0.508917480574455 0.280837147356942 0.250422410983592 0.79829921633238 0.528941552606411 0.546633474598639 0.632995719360188 0.153433983121067 0.45414385604905 0.992086805666331 0.573356852498837 0.826906176120974 0.205022547096014 0.305411449393723 0.951446275897324 0.0997578272456303 0.848203002535738 0.891722302963026 0.650922179785557 0.557683187073562 0.0462734730564989 0.75114492908353 0.727414507397916 0.577762004563119 0.371181318841409 0.332853225860745 0.332218963182531 0.420354024008848 0.701731767104939 0.926146637403872 0.317047173031606 0.860830592482816 0.500378961982205 0.817684410337824 0.679712886125781 0.657556394559797 0.937477187011391 0.791405463072006 0.639426059196703 0.952844045527745 0.039054331863299 0.100132580711506 0.386275736733805 0.0779204905987717 0.476641911510378 0.242014088639989 0.517054218610283 0.24922900195932 0.982706493230071 0.429697349348571 0.644896284651477 0.612748334589414 0.300445400318131 0.175496754050255 0.177988331492525 0.567901695673354 0.867166828126647 0.868142498880625 0.727565024963114 0.582105001672171 0.426566018662415 0.491805123286322 0.0963864551135339 0.252710663697217 0.894310961535666 0.0576057110936381 0.385420653277542 0.348788510747254 0.621487980070524 0.189898704888765 0.938763259358238 0.465034860980231 0.604094071323052 0.610053824502975 0.0640900391875766 0.991141545085702 0.828897248394787 0.647004224376287 0.150602752647828 0.385471656299196 0.249040685237851 0.275041063975077 0.91884515109472 0.187361181876622 0.567980263086502 0.998501824012492 0.263780446241144 0.774437877156306 0.0516095825703815 0.0739474571170285 0.963278134895954 0.330427972930484 0.308010784604121 0.660368495183066 0.544276851434261 0.192538933518808 0.492110509148333 0.641483487791847 0.21049530046992 0.784170157671906 0.0340704564284533 0.406098735814448 0.188638372968417 0.870284742654767 0.893860773874912 0.285094615190756 0.475034545643721 0.894362442619167 0.846363129653037 0.730969331960659 0.189336408036761 0.315296546043828 0.289689212746453 0.0271043743006885 0.329809495513327 0.3154256697651 0.0395592239522375 0.307399175465107 0.575506603042595 0.507581610272173 0.0129863523226231 0.277428206570912 0.641885833078995 0.560405665161088 0.377304413123056 0.880198313950095 0.0517119212285616 0.570166849517263 0.612080888564233 0.237432495334651 0.92645784068387 0.587311024656519 0.206534597249702 0.252525470743421 0.441424308116548 0.423449829674792 0.421071405829862 0.186829578254838 0.0696763075864874 0.60773335078964 0.54483026887523 0.448652629987337 0.560654079604428 0.757281106677838 0.49220138262026 0.399765691705979 0.156920597893186 0.820048416031059 0.159370491062291 0.335491900674533 0.891365709393285 0.276041551532689 0.624004158335738 0.847606497523375 0.635685823855456 0.337354478498455 0.559720064310823 0.556408074421342 0.146190257470589 0.211008214501198 0.106034058982041 0.315204335427843 0.186964028885122 0.289453200711869 0.232152663427405 0.917425734067801 0.473160339668393 0.725974215618335 0.702153833019547 0.761263391370885 0.811618834917899 0.505813250278588 0.925145609779283 0.198099984731525 0.823148179422133 0.136814812321682 0.26589593215147 0.0668554024654441 0.400645800570492 0.288334228268359 0.992324235520791 0.657535388881806 0.638795774758328 0.291156233116053 0.599943787537049 0.835168790330645 0.126999362644274 0.0430129810771905 0.908355351616629 0.0401507962145843 0.333268979468849 0.186253742848057 0.579761250910815 0.140547341739293 0.151115026804619 0.84720981544815 0.119563987669535 0.829794908859767 0.99028758601984 0.614534692896996 0.945490839795675 0.13131449732231 0.522504565312993 0.234488978183363 0.333598240762949 0.540919208712876 0.0146352883637883 0.92637692583492 0.949230410829186 0.7223411447322 0.179945905092172 0.662076042206027 0.990990777425468 0.179917347235605 0.640780458429363 0.108986292579211 0.257633431118447 0.893806160034146 0.775439670740161 0.0871983207738958 0.793884071530774 0.323007165472954 0.280468158985022 0.951237705626991 0.688212103147525 0.0585028252680786 0.949434599711094 0.876929077634122 0.913749420943204 0.834979108343832 0.925046002343297 0.776487981078681 0.489317158046179 0.638217132063583 0.314741495263297 0.84165128961904 0.343196708217729 0.283257544524968 0.156032244651578 0.184742400336545 0.314791058567353 0.711461902335286 0.542694237600081 0.114290757810231 0.351932261590846 0.660121954493225 0.92275360727217 0.205790802165866 0.543891766392626 0.251963746228721 0.102212505182251 0.0975111350254156 0.843002284793183 0.921671257962007 0.686643736662809 0.280951273213141 0.588054280364886 0.472461576212663 0.199703846732154 0.316993318235036 0.0917170669254847 0.288626826552209 0.565981291497592 0.709444265589118 0.218585613260511 0.362568009386305 0.306066018405836 0.66349379500607 0.0840462663141079 0.415039456321392 0.864858723168727 0.317004293142818 0.244450171492063 0.791905956715345 0.11768719315296 0.824438959087711 0.668115834787022 0.959464663430117 0.618247338952497 0.932001391698141 0.857173553272151 0.176297833344433 0.657201146432199 0.317522215067875 0.287859471363481 0.148173219289165 0.458775833938271 0.205735863316804 0.947753887770232 0.241155111077242 0.527061845692806 0.177414450284559 0.507167370833922 0.0889068838511594 0.370791156524792 0.636528739784844 0.0822820807178505 0.343838180778548 0.394383314840961 0.0240135184419341 0.446789419434499 0.424966980384197 0.963752402213868 0.602934185636695 0.0414163934998214 0.139156757097226 0.990345174262766 0.692433966898825 0.184163791756146 0.020994644544553 0.344067464910913 0.605853243493475 0.272787652842235 0.936686188045423 0.0471378895523958 0.564726035699714 0.730621141584124 0.153349903014023 0.205862281632144 0.740648424753454 0.349740484477952 0.157137535628863 0.554768509913702 0.992903510022443 0.399072900565807 0.998962077018805 0.909331934698857 0.447051445962861 0.557481243975926 0.427958562113345 0.788270403549541 0.770556852601003 0.526800615089014 0.359685734861996 0.516957899059635 0.984654564831872 0.340170304961503 0.350587261090986 0.0140846961899661 0.810093963993713 0.663075848629233 0.337077566820662 0.739624575783964 0.138795999733266 0.12182269021403 0.685378582403064 0.375718211289495 0.302324103163555 0.660264974278398 0.304270917144604 0.92101181267295 0.283941293980461 0.133400921267457 0.23342016881099 0.401802914696746 0.037039689111989 0.763281257466879 0.581557796038687 0.470673981260043 0.574559321878478 0.28025571097387 0.933687645837199 0.833859824491665 0.359372044000775 0.71529747874476 0.78946698497748 0.177491552394349 0.60569252666086 0.22524752312107 0.12091528872028 0.809665961721912 0.389370429764967 0.0274607313750312 0.270104181512725 0.773284007580951 0.189907231861725 0.802915142730344 0.874191904792097 0.0974094952503219 0.843634688700549 0.390671124027576 0.979560321881436 0.766605233708397 0.550991441681981 0.500447114377748 0.0779027707315981 0.977763846595772 0.728387812275905 0.415569957911503 0.599071273494046 0.508585861010943 0.507931458421517 0.534459103879053 0.671177090227138 0.317753114330117 0.67316407246748 0.0126739522744901 0.928809886071831 0.0210423965612426 0.683676562134642 0.0439027634332888 0.0469052304048091 0.976496422118507 0.952989096038509 0.166071239875164 0.226596887030173 0.420860802067909 0.0813041849248111 0.781513322961982 0.73913948753383 0.824596803169698 0.198627286949195 0.641935462076217 0.989781684330665 0.0561343141761608 0.277349230016116 0.639690847143065 0.760268993685022 0.616063331612386 0.944778674473055 0.361611879698467 0.5171542432555 0.454345371795353 0.394469351451844 0.170910315355286 0.949092874003109 0.886720507584978 0.874246334461495 0.29403129914077 0.980893089852761 0.686908582004253 0.361155689756852 0.658558599129319 0.733463977389038 0.744623609283008 0.285126194702461 0.837368488425855 0.797623636571225 0.247536570818629 0.451679902928881 0.630116217548493 0.110288283647969 0.702905975515023 0.668729270196054 0.885039667945821 0.830237825785298 0.633930580827873 0.0356590720824897 0.647275834961329 0.9550889566564 0.117692806345876 0.500129650423769 0.152020407253876 0.925371394194663 0.720659672133625 0.449615801982582 0.175746587926988 0.726788424325641 0.235294221041258 0.404806077554822 0.811903465196956 0.722483845963143 0.0447236885176972 0.868789826431312 0.592482800064608 0.661496172777843 0.13821572969202 0.529200928127393 0.143650552753825 0.184691980716307 0.280427074939944 0.922524240158964 0.741133513695095 0.997977380945813 0.0158165434608236 0.789670303021558 0.862015423593111 0.885862968587317 0.125771973195951 0.417058626138605 0.265417016753927 0.620441655970644 0.0865061222552322 0.722799077271484 0.812442435212433 0.504435832160525 0.592081514396705 0.304092960350681 0.861513093307149 0.307664007206913 0.177701130881906 0.50778240546817 0.0644313522963785 0.581083363450598 0.344439550542738 0.364282672016416 0.588825744949281 0.482255024211481 0.594482011836953 0.360339612828102 0.330808252459392 0.321268831174821 0.840638914825395 0.579568037397694 0.0532526689232327 0.895231372120325 0.243921505622566 0.153914145536255 0.516459097533952 0.014118379727006 0.0631442832574248 0.881651800374966 0.904105844642036 0.471923996356782 0.579431759114377 0.133008279437199 0.1729073839169 0.673478041545022 0.743723906336818 0.733719258266501 0.496844119897578 0.660317137879319 0.505549498901237 0.398727887202986 0.0839018079638481 0.805415224325843 0.144665995303076 0.468556694434956 0.191643156718928 0.833077822492924 0.801846587832551 0.411945731861051 0.717674726797268 0.385517651427072 0.108331558527425 0.995231513325125 0.820926693324 0.10943411482498 0.560606476261746 0.372989329155535 0.800535284699872 0.879809631227981 0.872656426150352 0.565966147724539 0.593058779074345 0.688060715666506 0.867852015225217 0.574709711975884 0.176446491908282 0.904691986269318 0.779302491373382 0.0975930896704085 0.206109805414453 0.950383352632634 0.343185439419467 0.538660659913439 0.0608645289344713 0.863341663507745 0.774452151244041 0.608415240552276 0.54768121306086 0.744644170782994 0.853344506302383 0.379164335790556 0.164792502573691 0.98876072447747 0.383951028923038 0.973132253645454 0.73752420298988 0.695509427275974 0.224793397558387 0.849945238546934 0.827089155560825 0.728130163217429 0.74099955818383 0.982616729165893 0.745971140468027 0.0222305720299482 0.867587765040807 0.511210228775162 0.522672208049335 0.405416475634556 0.765686234028544 0.824562590399291 0.58631464303704 0.635127718918957 0.172148529193364 0.476918928297237 0.351994724266697 0.631042413511314 0.117623080310877 0.797655931792688 0.252666000642348 0.40197232792154 0.485705362525769 0.407218873447273 0.623630500677973 0.0724901710916311 0.490736113146413 0.046852010411676 0.611241233781911 0.203741580836941 0.641009821393527 0.0384350753482431 0.0415051832306199 0.624583783431444 0.771041611232795 0.558097818826791 0.318948720272165 0.847464257988613 0.955278151822276 0.729985860546585 0.268074133368209 0.201109717136715 0.613469192155171 0.238222221927717 0.982539823213592 0.943792149133515 0.677969833905809 0.0912423144001514 0.0679458755999803 0.194990408394951 0.0891387168783694 0.401285895418841 0.0597320458269678 0.0165995227894746 0.728166458576452 0.569353703195229 0.433689230084419 0.808747176409233 0.471508698221296 0.32947577676503 0.317462748000398 0.608473821799271 0.34198298133444 0.794134084507823 0.649147062385455 0.178235785202123 0.78177161419997 0.867507348076906 0.91925522858277 0.95254134778399 0.56021424587816 0.171173544183839 0.0281108745117672 0.86462786585791 0.929908285951242 0.734364320440218 0.315295107939746 0.561270580003038 0.908655063663609 0.435939172157086 0.790131266897079 0.933368058956694 0.711551252647769 0.260584290691186 0.0382955981534906 0.594185199278872 0.925993029724341 0.0110696769831702 0.0584053103323095 0.187475041733123 0.29927114880411 0.921249630923849 0.158919186156709 0.833948616066482 0.876986575059127 0.247453989898786 0.773199209689628 0.387013218589127 0.920649911556393 0.297098424092401 0.754365167748183 0.790605140978005 0.392492680733558 0.988833841201849 0.0249159860331565 0.761808247494046 0.671211635842919 0.58622053746134 0.234152922832873 0.863642563794274 0.70284094850067 0.68408496479271 0.559188427035697 0.422011199817061 0.915038144988939 0.768668613643385 0.558162401202135 0.649153950025793 0.149833946677391 0.580444123996422 0.148769744355232 0.0717627684120089 0.157319401511922 0.259808362659533 0.40422640658915 0.892741476884112 0.398573523706291 0.514194295897614 0.701436519657727 0.68025637813611 0.0711561973625794 0.167102410520893 0.562182088356931 0.610667710544076 0.674176763279829 0.559241124480031 0.654746662578546 0.764550082937349 0.304259420149028 0.634820293341763 0.341119320194703 0.675965619771741 0.22422359324526 0.118686160778161 0.984873174401 0.254469263760839 0.196427513940725 0.906315444195643 0.91604280417785 0.684564132820815 0.473709069613833 0.454181616250426 0.241108340078499 0.685335175355431 0.557859082254581 0.874411196187139 0.900906953720842 0.559222231816966 0.79174613538431 0.176408044348937 0.679836914592888 0.40001011292683 0.916134026169311 0.589822928486392 0.924148268809076 0.490277999662794 0.361716197680216 0.101333335384261 0.600347368316725 0.760660869095009 0.253871263479814 0.0867431478085928 0.545269681012724 0.0511046570586041 0.636495080911554 0.964360196078196 0.912398938867264 0.159931089342572 0.189587545865215 0.705054546347819 0.402608822784387 0.832168541252613 0.0117901526065543 0.441988437462132 0.719058021341916 0.478209388256073 0.069106654021889 0.82793391735293 0.927548314048909 0.5213665801147 0.593936558251735 0.0708002035599202 0.507150243127253 0.16624798791483 0.145087917845231 0.227313372888602 0.636599463203456 0.02316281568259 0.782960066040978 0.233843778630253 0.727863916421775 0.987098831669427 0.400060638117138 0.915050420851912 0.123546740973834 0.100022577620111 0.987853334278334 0.825686210230924 0.948794763716869 0.246451399237849 0.527046217864845 0.572396573768929 0.117334236449096 0.551306166346185 0.0409026093222201 0.850165697666816 0.0367537237633951 0.218097429363988 0.998241590561811 0.875317096419167 0.618415956022218 0.653184219542891 0.657756313846912 0.778790690668393 0.383556989326607 0.197125915738288 0.468006062384229 0.166106351374183 0.560685603795573 0.71916299948236 0.477885305888485 0.93915154838236 0.415692615120206 0.0278267836081795 0.563030779291876 0.812914373995736 0.749078066949733 0.79557400402613 0.623308714574669 0.559760476672091 0.328892723408062 0.824439474029932 0.278870016208384 0.788879680235405 0.490772478578147 0.0560689697600901 0.646126536938827 0.158466966848355 0.192459628498182 0.175448063889053 0.726476215133444 0.395809093962889 0.191813640627079 0.302711040060967 0.266146202138625 0.465786839588545 0.135111849990208 0.133599216204602 0.513438653685153 0.462621806003153 0.145602006746922 0.560572435676586 0.927877825207543 0.615060515981168 0.88498193517793 0.630919094069395 0.109725912343711 0.68296791151166 0.964340406761039 0.633843193473294 0.983646659478545 0.168978735504206 0.309792630136944 0.412357073423918 0.0455124947149307 0.757287665852346 0.859216206206474 0.926772962964606 0.999286558846943 0.765580672025681 0.0970092516834848 0.633120912325103 0.97121255642036 0.965268405943643 0.910085632393602 0.555656136150938 0.328834646961186 0.188550487959292 0.672449115531053 0.0385591298621148 0.217675413237885 0.450491457311437 0.397488002453465 0.627861714987084 0.536942541361786 0.826096848070156 0.572629117665347 0.799539424015675 0.0732192082633264 0.933249931810424 0.936192660643719 0.404358285735361 0.817851929063909 0.210479321586899 0.798600722148549 0.414204346584156 0.796239456667099 0.164480017931201 0.139005286865868 0.778037133349571 0.661011921712197 0.992794839234557 0.527982197729871 0.202651472357102 0.96636462388793 0.206289343684912 0.224026362076402 0.548628563375678 0.738817077460699 0.178070289825555 0.348087568583433 0.771792286119889 0.501661807987839 0.402465108034667 0.0892619033204392 0.812238804376684 0.119047058518045 0.111084506718908 0.465445696129464 0.228507925204467 0.0511898507224396 0.750797602629755 0.623225800348446 0.189172715418972 0.462160436904524 0.208569408033509 0.563411729121581 0.850187423664611 0.266305514751002 0.195537502234802 0.955578752916772 0.80288638502825 0.95761317714816 0.668751128041185 0.516691043276805 0.93799675818067 0.986435719318688 0.471942357020453 0.896779476988595 0.239469086749014 0.990013857348822 0.957563104203436 0.0217211883724667 0.814734920640476 0.672911574675236 0.798985425017308 0.678711831301916 0.343610592451878 0.865438688716386 0.0640568231092766 0.67170922123827 0.949012514664792 0.550729977118317 0.91286048314767 0.0715066722477786 0.402711945381016 0.804334941930138 0.066303771417588 0.104367536534555 0.289686632733792 0.50775389371207 0.451039387644269 0.0585448188753799 0.100540869270917 0.420694470889866 0.0588952264538966 0.38190059123328 0.220958337243646 0.125639034199994 0.0521716733532958 0.376367766875774 0.534830936880317 0.490071723582223 0.457280694819055 0.156103702911641 0.555285960230976 0.045453483350575 0.341364469111431 0.803042131769471 0.242124410516117 0.47100771084195 0.849535119798966 0.63824330329895 0.829022920343559 0.268258069392759 0.698042310276069 0.220703799275216 0.872073154277168 0.729418087881058 0.173328318987042 0.505164045055863 0.300873019495048 0.375918401186354 0.867215398196131 0.349272469305433 0.325315050531644 0.34289588883752 0.0857137206825428 0.0894913762342185 0.95788963197032 0.0101936648366973 0.700486593709793 0.254166491334327 0.544285983475856 0.834331092052162 0.626397050812375 0.418386724824086 0.0438641697354615 0.135561952826101 0.788150805567857 0.570714539897162 0.841078984355554 0.576425951702986 0.265952491892967 0.626756613482721 0.476324143754318 0.382065812081564 0.701191065325402 0.398929628841579 0.319560549540911 0.262035742471926 0.0297219957225025 0.778804928336758 0.354937149297912 0.366033618019428 0.86504460232798 0.926632690767292 0.187290620501153 0.748580013173632 0.956615575479809 0.79246840062784 0.965269540476147 0.71933703474002 0.768083157760557 0.632508362736553 0.12044592234306 0.413357313191518 0.556835138779134 0.838299905497115 0.761671123267151 0.801388837620616 0.0521291827829555 0.16079536892008 0.0970297804521397 0.67319754394237 0.547781675660517 0.0913466648827307 0.624802602988202 0.363103302889504 0.544145526876673 0.237653416842222 0.76944497870747 0.441780003188178 0.738218269268982 0.165254908010829 0.475306062875316 0.448688085395843 0.766528009201866 0.836126037032809 0.212172060678713 0.619475218218286 0.195527178957127 0.882899327659979 0.698629349709954 0.370336990854703 0.336813187554944 0.25017574789701 0.344176320792176 0.167228863411583 0.721310337127652 0.231649725306779 0.863326877935324 0.216519454158843 0.793283653741237 0.345644319183193 0.780083549465053 0.041304280620534 0.925274241608568 0.4924594226107 0.447340124323964 0.238260314282961 0.933596404714044 0.649028243271168 0.302477649990469 0.957392824059352 0.342746964734979 0.827358814713079 0.437181711832527 0.389996456133667 0.131464553882834 0.839420390266459 0.795278013208881 0.260685237576254 0.190528519332875 0.823136180392466 0.951860513491556 0.566806851292495 0.59821863359306 0.792988928842824 0.925253144882154 0.797915063442197 0.975259614114184 0.246355510265566 0.370387434908189 0.438939072024077 0.0195269222953357 0.61877900757594 0.243221580896061 0.798580624880269 0.719537460901775 0.259253559899516 0.159845885767136 0.931090093101375 0.671119286925532 0.0367397640808485 0.0188363119377755 0.877299741297029 0.688013435718603 0.952805438921787 0.838672778985929 0.936691708806902 0.375640472762752 0.948722160782199 0.421008488603402 0.2947197466949 0.142209676650818 0.781431791288778 0.777373508822639 0.333598714906257 0.437261448584031 0.970612884305883 0.797557819164358 0.647071095870342 0.817514252129476 0.516455672730226 0.613372181789018 0.0668701818143018 0.941575672542676 0.26758770336397 0.334785803786945 0.977284484945703 0.902248976822011 0.627252552399877 0.161112887272611 0.125223032571375 0.543314344899263 0.386528246973176 0.365708405268379 0.0185926073486917 0.875760212037712 0.0500386446015909 0.450560266869143 0.479618064335082 0.452612766863313 0.264576764970552 0.535541609239299 0.398166085931007 0.50137198794866 0.67765468765283 0.995486761701759 0.890444630812854 0.364024979162496 0.709149411378894 0.192559337585699 0.649634046978317 0.0913286709482782 0.331218848577701 0.573624925564509 0.359839573274367 0.966941478806548 0.128924350359011 0.103258723712061 0.186386317189317 0.467569336751476 0.770234074415639 0.690409419692587 0.307859576223418 0.388597719545942 0.0992681024409831 0.0594520103815012 0.166044093384407 0.834121872687247 0.741791104823351 0.702207942290697 0.490513202403672 0.1816692283866 0.716416818378493 0.115381174702197 0.605780882355757 0.152374272597954 0.243206638121046 0.139244960660581 0.640784772280604 0.984079535261262 0.200086756984238 0.0542600249894895 0.498270086878911 0.409781160478014 0.294378114340361 0.940968107106164 0.58099305102136 0.962377571023535 0.237860807401594 0.215091131904628 0.335479712402448 0.19557883867994 0.54018143849913 0.277168384336401 0.845839161421172 0.86733575015096 0.569095964701846 0.315060314801522 0.846880728183314 0.806353244136553 0.829206215110607 0.988660943242721 0.556679672559258 0.0559864649060182 0.937333149788901 0.256146906332579 0.738386403897312 0.238497238184791 0.795010751280934 0.720784037825651 0.500642069336027 0.730953146317042 0.810931910984218 0.906708742266055 0.180816380111501 0.0933859204431064 0.656403178458568 0.963244041064754 0.0709226706041954 0.417770922617056 0.250505111995153 0.455209805578925 0.758678361135535 0.224045222238638 0.300210352705326 0.0173845519754104 0.90430501525756 0.0130276156985201 0.755120800049044 0.799640231216326 0.444631979102269 0.666042930034455 0.966314603728242 0.897299394602887 0.265550966733135 0.395218888579402 0.0395676059392281 0.0371843205695041 0.407387199853547 0.0625205858843401 0.349520538686775 0.405423027663492 0.818192990925163 0.530977395349182 0.722411912637763 0.515074191316962 0.689241545717232 0.823080894637387 0.978947108676657 0.928361193910241 0.243470512125641 0.543849682889413 0.585204579508863 0.994011142442469 0.720107763330452 0.719239129563794 0.692523822702933 0.419528224722017 0.931346959143411 0.622052737304475 0.809880573458504 0.271242217421532 0.831312563216779 0.250969902670477 0.916782308691181 0.176731551613193 0.279857759061269 0.372795883296058 0.416735104352701 0.672926711072214 0.183189109396189 0.298068536513019 0.250897273228038 0.604805206300225 0.902007285670843 0.102132110116072 0.382166071839165 0.223995480986778 0.974814501884393 0.489845758222509 0.0276530641387217 0.0271430438337848 0.514823563820683 0.973682910129428 0.920610866995994 0.553255830258131 0.117755707437173 0.805022383572068 0.576949310947675 0.321658643819392 0.406353774203453 0.918675064342096 0.807845667477232 0.488004007437266 0.229558279637713 0.15876670793863 0.222499149939977 0.674183380310424 0.296380645346362 0.739707103227265 0.95507052015746 0.384214358711615 0.487285603107885 0.47360350968549 0.434217914394103 0.554504103448708 0.15957353411708 0.488432083469816 0.330764857858885 0.4441862378316 0.104034833610058 0.251919527121354 0.518798336212058 0.6079864418949 0.569287530814763 0.626190123562701 0.13067889865255 0.137597238214221 0.360633245606441 0.300173736948054 0.844931229311042 0.478076712954789 0.389283005530015 0.186098251503427 0.658033360599074 0.705100937709212 0.717645728681237 0.212189469137229 0.16790932521224 0.265162023082376 0.765160775368568 0.10544390845811 0.634541026391089 0.238098865374923 0.807845801399089 0.622753519730177 0.550939728482626 0.553440363744739 0.207489116878714 0.392672526955139 0.973037966894917 0.976509656410199 0.347344067159574 0.914371873373166 0.885192771055736 0.722725192282815 0.374425442158245 0.805593749769032 0.0195902583445422 0.792950578785967 0.717321440014057 0.262426112471148 0.714314542326611 0.667125319221523 0.902511007268913 0.992218736675568 0.618184127374552 0.857185068016406 0.582064447551966 0.8080353056686 0.224656202336773 0.787328766004648 0.699944538420532 0.555098842813168 0.818288339369465 0.585119420189876 0.129186611999758 0.627045710897073 0.246857511394192 0.700936937881634 0.938658608761616 0.770716777427588 0.154491824961733 0.315398044290487 0.452808064809069 0.874060536669567 0.727650506985374 0.117065344639122 0.446184833010193 0.544172628880478 0.532746663291473 0.685696433139965 0.538397759320214 0.0274558769958094 0.588750668724533 0.243272392370272 0.608263362101279 0.653396552302875 0.260974379477557 0.534670637717936 0.067521370279137 0.650247817307245 0.495124329973478 0.988376853722148 0.869752256670035 0.0340794116747566 0.67889496586984 0.778002872173674 0.846192457885481 0.904014274822548 0.907609109980986 0.181439649672247 0.973054559836164 0.129807083492633 0.441916356845759 0.69384636559058 0.370053279357962 0.0571898625185713 0.151740092670079 0.0500115538924001 0.708744045358617 0.694969421613496 0.127465174444951 0.896207350133918 0.928543372815475 0.236634880951606 0.527455680833664 0.229469312189613 0.395685989118647 0.663604202168062 0.0165291264536791 0.0967144421907142 0.289663764596917 0.184264541331213 0.863568266667426 0.571552768331021 0.79424188261386 0.353399580691475 0.721976683887187 0.363226408194751 0.38932862885762 0.785971346499864 0.75490396511741 0.818538041168358 0.40337152459193 0.446558156670071 0.466245509504806 0.579793905715924 0.552528192696627 0.852764255392831 0.805035700614098 0.813157412202563 0.0818013782356866 0.0532675515371375 0.065225957701914 0.404856448769569 0.273962495825253 0.624025310843717 0.700886657484807 0.515316753766965 0.666323760021478 0.428939773452003 0.72419312244514 0.969059028173797 0.440153890566435 0.594465479978826 0.0161048841360025 0.451539422126953 0.537273187744431 0.764503034874797 0.659727569604292 0.52345038094325 0.341384809329174 0.568644092530012 0.0171059820638038 0.929867179316934 0.640617115483619 0.351360392668285 0.249049626193009 0.826464509901125 0.400107955636922 0.841965829650871 0.553252718246076 0.340582302764524 0.0524858233751729 0.349722746401094 0.0735260232398286 0.0323595606675372 0.555919739315286 0.417079945760779 0.811380224891473 0.906603752369992 0.52937776099192 0.331834543140139 0.554118413338438 0.252953495604452 0.982902720100246 0.672216586386785 0.251997147861402 0.487734978478402 0.797409865707159 0.0760713284718804 0.628305339785293 0.354215236261953 0.796132813377772 0.539457985016052 0.974364593592472 0.57060270661721 0.436856040151324 0.0833687726920471 0.0300533527438529 0.414541803158354 0.248950902272481 0.135903788253199 0.143479369040579 0.937591535302345 0.428501741332002 0.350989652017597 0.346466637193225 0.439173137466423 0.715777650610544 0.23434999011457 0.195089415833354 0.637960929407272 0.850715836212039 0.0406402829103172 0.989672337018419 0.205864711818285 0.682543952481356 0.900571911658626 0.174887563802768 0.823294198503718 0.478712044011336 0.659596707203891 0.2709212274733 0.173668039324693 0.522109715500847 0.546649060475174 0.994628833155148 0.943573339949362 0.950113726211712 0.425017122249119 0.455279736991506 0.624512146301568 0.3411686608335 0.542323026724625 0.0175614131917246 0.66713012289023 0.33131578564411 0.66004899704596 0.531672412680928 0.549026862885803 0.915869093928486 0.617108555985615 0.131360985264182 0.442528365214821 0.284863286272157 0.985029072121251 0.536676838551648 0.458849780932069 0.959029021849856 0.809963089376688 0.0749900519195944 0.0270241804630496 0.545485571115278 0.74533809829969 0.2420560732577 0.627018636092544 0.512659294856712 0.969796162662096 0.937258522352204 0.424773322693072 0.774721724879928 0.609889524281025 0.265363651083317 0.77943996803835 0.123536444895435 0.580207622374874 0.568213472212665 0.850658357688226 0.549041298786178 0.199492342167068 0.704994163033552 0.826902663034853 0.727214811006561 0.117196202198975 0.608548425033223 0.47804204425076 0.95600623217877 0.0554238886851817 0.492144876585808 0.466139086114708 0.373854917064309 0.257806365266442 0.437897927081212 0.629400489812251 0.0798626304534264 0.218494599182159 0.35195975406561 0.0678266100026667 0.965558499358594 0.818455979800783 0.248723002076149 0.745632407602388 0.947224218524061 0.0349115845817141 0.250961015883367 0.463749651634134 0.370907140690833 0.724393591249827 0.103368181204423 0.969040540042333 0.367141977443825 0.979799871204887 0.460410205919761 0.801731986911036 0.075140765872784 0.0243934955517761 0.938380467584357 0.879043910992332 0.731451618685387 0.407697459456976 0.720685889238957 0.637835768943187 0.583438582164235 0.336371056872886 0.210829879913945 0.256318455161527 0.854785259778146 0.298212775425054 0.693187389373779 0.0967231498775072 0.737461392024998 0.415162736577913 0.612865989205893 0.986294907515403 0.251531513778027 0.562159816760104 0.144793668473139 0.987041580651421 0.762327581245918 0.628452532123774 0.679141961340793 0.018140051276423 0.481872249955777 0.84098223722307 0.945923992411699 0.156258470709436 0.716733065510634 0.395126644540578 0.79448459074134 0.0778724156483076 0.835939991681371 0.396714072185569 0.0343615308613516 0.417172142316122 0.801130050111096 0.254959388717543 0.972476472191047 0.65284654468298 0.240176929922309 0.678623290052637 0.623304705447517 0.0246564473165199 0.860629530595616 0.512694780922029 0.650439414076973 0.762426566556096 0.61107765134424 0.617499178384896 0.142638166665565 0.186930185840465 0.427379549462348 0.67574253638275 0.632134400354698 0.231501518988516 0.149961422537453 0.166986319401767 0.762088909444865 0.405902803295758 0.274121789305937 0.956795607716776 0.590112029588781 0.338035947824828 0.923701673527248 0.929700845142361 0.389023224785924 0.997189755842555 0.183567786011845 0.391202180667315 0.314293965524994 0.542693177058827 0.302165582326706 0.672307140612975 0.196958000087179 0.436965235793032 0.481232970163692 0.350188893582672 0.765068786034826 0.883189259723295 0.101767725567333 0.956238504312932 0.0700064931949601 0.0507904376555234 0.887789102590177 0.508102381897625 0.377147858701646 0.360020957638044 0.16959343544906 0.387116907299496 0.845999488474335 0.549102355397772 0.285275733785238 0.948617044340353 0.423337344764732 0.572380830228794 0.606958447340876 0.835444309082814 0.483077906491235 0.745897914946545 0.719114101408049 0.416375989317894 0.825998410433531 0.759159974332433 0.322838425084483 0.727089677280746 0.480919767275918 0.74535909014754 0.764836326732766 0.0624007366551086 0.198536635681521 0.602778068478219 0.649756961888634 0.597037685986143 0.219074319014326 0.341131015883293 0.0604364114115015 0.483632587315515 0.690439776158892 0.54646837960463 0.840959810728673 0.192273083648179 0.54461536440067 0.448418657667935 0.302053580088541 0.406189254543278 0.78857576751383 0.358892719461583 0.0505588134634309 0.28716070675524 0.0497132161003538 0.789146719728597 0.407747649035882 0.684535951835569 0.304926545545459 0.0634634501626715 0.196371090195607 0.439871973991394 0.521685560082551 0.875334158663172 0.395120067847893 0.070805238422472 0.438841081331484 0.943611061656848 0.669300428018905 0.586678647487424 0.660102723683231 0.951067513304297 0.343660528939217 0.842237821025774 0.183508042572066 0.909777983920649 0.312448484520428 0.320218722687569 0.518128314092755 0.967923151610885 0.845647392466199 0.599724912659731 0.356462061712518 0.754779434385709 0.502782972278073 0.482055289556738 0.113945208759978 0.580052812164649 0.336821730663069 0.970640807128511 0.565263155011926 0.368133037686348 0.406403146421071 0.13346973935375 0.70942897636909 0.792327508840244 0.144152824722696 0.862223580342252 0.942970637881663 0.483623325270601 0.637843474866822 0.202947165595833 0.680652363633271 0.91332943346817 0.653750366244931 0.274633416442666 0.948106551275123 0.96374439525418 0.244633702524006 0.106137353302911 0.466111470782198 0.462212326207664 0.531853832541965 0.9114670382021 0.855782852456905 0.376372408501338 0.491767147104256 0.378086267600302 0.270120119135827 0.474362108551431 0.46206922643818 0.698794373939745 0.419727095454 0.013945285610389 0.878989184896927 0.714689452303574 0.888907490018755 0.0578117578243837 0.848745926357806 0.928315529783722 0.0335200315993279 0.622661777955946 0.618601535758935 0.47733842065325 0.41468149080174 0.368752707953099 0.544920211348217 0.773109648928512 0.163516870830208 0.219403334592935 0.978569924794138 0.0879226204310544 0.503859598445706 0.878592659102287 0.773515384444036 0.42176321917912 0.148462975248694 0.50837230843259 0.0815584522834979 0.764039265324827 0.219999376756605 0.129633682807907 0.81290049521951 0.115898308770265 0.689542952878401 0.969709807957988 0.0415730820735917 0.0220582063007168 0.190344937359914 0.71649215783691 0.652132601726335 0.228418009239249 0.3284858598141 0.798132491917349 0.103675872781314 0.192158213730436 0.864213162648957 0.551318606557325 0.26398341207765 0.465534312292002 0.469658897372428 0.806046358165331 0.211896164594218 0.599748979639262 0.24303405295359 0.0301139022503048 0.626684206014033 0.844619309629779 0.179134363066405 0.978110379660502 0.240626084932592 0.243564778130967 0.909584459459875 0.0456733254157007 0.673168006681371 0.146848616632633 0.633553634593263 0.641435486602131 0.615250412335154 0.692592731837649 0.156888223609421 0.773135286089964 0.467689561238512 0.992939880525228 0.349952466413379 0.567706855966244 0.3828482573363 0.763260743450373 0.822465340681374 0.470929426024668 0.779742832204793 0.10205393179087 0.389283073989209 0.944597613734659 0.541728447789792 0.983811852897052 0.400495116813108 0.445254671254661 0.950257210689597 0.578273471731227 0.972237691823393 0.622157906761859 0.27818613444455 0.365428088610061 0.0979687271127477 0.761442310281564 0.368049612666946 0.403944912524894 0.336617443817668 0.0124945497699082 0.395220230103005 0.0685904546407983 0.360957409571856 0.745582143110223 0.967994419937022 0.487677795689087 0.314488914951216 0.303412124905735 0.541711635640822 0.206017636058386 0.824224592144601 0.410754129053093 0.490085410580505 0.0108276788028888 0.442515232344158 0.972089859840926 0.160511395342182 0.494200986016076 0.222658160594292 0.741534519994166 0.508877355880104 0.354802664092276 0.770377931846306 0.136903666823637 0.238811011104845 0.577703214250505 0.625180727089755 0.473666675162967 0.0782040105480701 0.545508860379923 0.137924210159108 0.454636046076193 0.415385668526869 0.443440675716847 0.691045758966357 0.930782148893923 0.667970318431035 0.713206383208744 0.556847710146103 0.838009475779254 0.256934881107882 0.811766519148368 0.620940427761525 0.0755615469673648 0.895549963230733 0.957014486512635 0.615712478472851 0.824178986565676 0.444094200553373 0.331625648322515 0.482062538855243 0.982008775332943 0.0142665973398834 0.470788110573776 0.234072728534229 0.762656261213124 0.876423934067134 0.904221584245097 0.50321268026717 0.613916691236664 0.294735076483339 0.603279582785908 0.836720603290014 0.0349038459267467 0.0253961523668841 0.975430464060046 0.456317263508681 0.58900114109274 0.766204609351698 0.199453689691145 0.25344404791249 0.779414299067576 0.555131094239186 0.156956627252512 0.49080064158421 0.992125007740688 0.835992643486243 0.551025345579255 0.0870279878447764 0.307656446038745 0.665497016136069 0.0121036708215252 0.967207489798311 0.0415358801488765 0.625476277186535 0.313189897593111 0.846199957740027 0.408026337195188 0.208728339856025 0.843358411134686 0.312644913541153 0.219190812821034 0.473615964187775 0.218270361667965 0.297919060357381 0.226842896181624 0.573069718042389 0.320251185023226 0.644229115690105 0.38875733803492 0.632077645377722 0.419050465063192 0.565752096339129 0.693341990287881 0.958962329456117 0.969205162737053 0.612051139932592 0.405156420362182 0.683988339826465 0.286676235559862 0.82895965206204 0.176779733516742 0.222142500127666 0.614354464963544 0.516205290718935 0.265921144727618 0.943961136850994 0.44958560064435 0.115139840138145 0.592757501685992 0.203838126279879 0.78097548263846 0.232604843089357 0.236562949931249 0.605492548365146 0.155523064066656 0.348224569952581 0.679365981952287 0.858009142223746 0.77907326371409 0.0164625327149406 0.614258922436275 0.0369981150189415 0.774983989747707 0.987836346256081 0.53355492411647 0.713820734173059 0.614284612382762 0.613043940698262 0.26914462010609 0.139869574049953 0.901847110749222 0.956653943976853 0.126422021365725 0.418032930705231 0.453299171014223 0.275715472553857 0.296378788189031 0.768096156017855 0.271891901397612 0.248295584358275 0.703112067193724 0.990159369325265 0.373450194145553 0.665163229389582 0.862309753180016 0.756317588007078 0.382664127920289 0.183557274183258 0.296706207538955 0.858046368351206 0.504669954767451 0.0756906912033446 0.883492975134868 0.831055536514614 0.84544449047884 0.329449372722302 0.224348197276704 0.799427833685186 0.238493152530864 0.391582887778059 0.197297582584433 0.341180488830432 0.816543694378343 0.537650819953997 0.68135681058513 0.956121909315698 0.493061249691527 0.963601316229906 0.37986820833059 0.996893146357033 0.90441257594619 0.5052748906333 0.863346335098613 0.54428080708487 0.944448982139584 0.0453855215804651 0.6720325581613 0.634602171746083 0.675227335768286 0.192367685725912 0.712316727398429 0.699047542954795 0.232723480106797 0.847934287290555 0.999460801787209 0.612851824606769 0.669161114941817 0.673699230435304 0.317343998267315 0.879431893678848 0.26723489602562 0.421179854182992 0.976623217535671 0.4228073440562 0.0891696097236127 0.69265473396983 0.781810018655378 0.475154920187779 0.0389419723465107 0.0561385911470279 0.135513929277658 0.213069377925713 0.463869641469792 0.530461482943501 0.155313166563865 0.114813228929415 0.469810825150926 0.786687709961552 0.252614118945785 0.997969597803894 0.516350148529746 0.578890116193797 0.152880295300856 0.702050012000836 0.205774792626034 0.817891991753131 0.487859101912472 0.0320776055986062 0.0731408909452148 0.994184024266433 0.68120388841955 0.12433502969332 0.370690583284013 0.956808478736784 0.806149887598585 0.869768517457414 0.486524381125346 0.229746332895011 0.437561287176795 0.7487207641243 0.305976323953364 0.992392958640121 0.462692275638692 0.118822691000532 0.98720446558902 0.540496547871735 0.535425516506657 0.734178870015312 0.824145301415119 0.68888460293645 0.497565505083185 0.473986561005004 0.656485766523983 0.030408470868133 0.418921414411161 0.801963453900535 0.613416050071828 0.228413846136536 0.712319324929267 0.937094844256062 0.486429700676817 0.337556499505881 0.562920975585002 0.461101122384425 0.953776309464592 0.795515159775969 0.649772048727609 0.72295453265775 0.0561447448679246 0.917528099464253 0.910883387152571 0.994617735850625 0.476773388199508 0.838540348939132 0.324235866710078 0.488673485571053 0.402421781432349 0.968032520820852 0.176174565765541 0.0193657723488286 0.568906654054299 0.734749420695007 0.802985528693534 0.111448888501618 0.772518040477298 0.678415607216302 0.335143378835637 0.385375000445638 0.890854524590541 0.893655464982148 0.754367181186099 0.633624675644096 0.719901663584169 0.0310716385394335 0.837036982269492 0.541434332109056 0.321091193857137 0.825153057633433 0.810196157896426 0.440033636344597 0.168973355118651 0.0873787667625584 0.351957779352088 0.061635979458224 0.981887691533193 0.706889309915714 0.227558475704864 0.493639546171762 0.48435662535252 0.913393472319003 0.203431409976911 0.515914982245304 0.0906524768983945 0.358077145949937 0.661191460213158 0.170948404252995 0.960738676355686 0.0963843453256413 0.418738976882305 0.45798511872068 0.682830784979742 0.179935899216216 0.0346459285635501 0.128785929786973 0.397634625451174 0.202013136933092 0.0763668525218964 0.984884094218723 0.629099522449542 0.498338125636801 0.114286978954915 0.778034712383524 0.507975461317692 0.272035017532762 0.7201170090097 0.271762939027976 0.711599668741692 0.840250507323071 0.461497980332933 0.0741371222771704 0.898022475363687 0.594450464595575 0.433609811656643 0.117701632741373 0.499619533538353 0.298174169280101 0.425663370126858 0.854897779263556 0.314802324138582 0.875201496961527 0.985221298392862 0.233929638445843 0.262644711898174 0.0393581846542656 0.65122139002895 0.0703222631872632 0.222193456357345 0.337970968293957 0.19474617249798 0.845362676670775 0.0544326232955791 0.0791853622626513 0.546341161215678 0.14905726836063 0.412354571321048 0.800052916838322 0.740672887505498 0.349947824557312 0.202784990144428 0.643587373672053 0.780780124531593 0.392333148682956 0.589776634396985 0.994051520689391 0.712991951033473 0.404767201722134 0.663111318559386 0.213808992619161 0.59772903372068 0.769871792278718 0.572746131254826 0.767408551641274 0.253874108800665 0.434818806326948 0.167036681626923 0.374864836316556 0.901919505079277 0.264726452266332 0.523069737220649 0.717515892016236 0.159825206710957 0.873709776191972 0.226585212086793 0.279623968377709 0.247470769316424 0.238472566367127 0.588144465787336 0.692379156670067 0.434298240079079 0.0296778877172619 0.711426279351581 0.244255422141869 0.0924454236542806 0.984783785594627 0.0438654411863536 0.778791790625546 0.0654450561664999 0.460137651197147 0.455661571950186 0.0900145063595846 0.570513118195813 0.627289365928154 0.588131303642876 0.656375230741687 0.0914893548190594 0.896285666760523 0.682679446134716 0.256508856085129 0.467714064558968 0.310888473745435 0.305951928508002 0.22588193931384 0.82264798427932 0.855158111138735 0.846194585883059 0.289952900274657 0.729666265137494 0.0566122752940282 0.989912205126602 0.697665175260045 0.469919912226032 0.340578296172898 0.211726389941759 0.846262677425984 0.762085352332797 0.186528499559499 0.632887621140108 0.295280339904129 0.360069693899713 0.995816228603944 0.768617527179886 0.380491040858906 0.122513656928204 0.327592128261458 0.578473507422023 0.802158329566009 0.609456949303858 0.182424301949795 0.470016996583436 0.617932611522265 0.294515746133402 0.29719418260036 0.486551569567528 0.171552020031959 0.537380879358389 0.756385129110422 0.967191860356834 0.445108891204 0.153367992837448 0.855406832150184 0.79873563493602 0.245679265044164 0.106301213034894 0.286186717515811 0.613234108353499 0.235127249988727 0.0863961837044917 0.659270976053085 0.297112536136992 0.765185613839421 0.306722043962218 0.470332298655994 0.892058693924919 0.0285305526526645 0.383109656898305 0.130556737945881 0.67401022833772 0.600158608108759 0.430121069347952 0.184417015861254 0.33605097487336 0.402871303402353 0.701651586405933 0.918213778224308 0.551666069237981 0.361949157863855 0.88150917382678 0.23457527364837 0.0556024733674712 0.689455835672561 0.629021528756712 0.573517679972574 0.528651145708282 0.483226942848414 0.80144742578268 0.855399190767202 0.48915340826381 0.0313738303305581 0.149617038215511 0.847748790995684 0.985067083339673 0.25534851354314 0.975404740690719 0.404058407496195 0.125310929566622 0.221869893772528 0.0470498955156654 0.10295118011767 0.541385281903204 0.174898120118305 0.828093387628905 0.514887747657485 0.833175967622083 0.511606288494077 0.840132569188718 0.259341202650685 0.394859060139861 0.978099363262299 0.854429594902322 0.725530223629903 0.431205009354744 0.33175628621364 0.488440217666794 0.0169087289972231 0.162425426819827 0.730681375532877 0.744297407215927 0.3999012701842 0.445824249444995 0.730764010851271 0.302725882336963 0.444155650862958 0.30808367935475 0.86858984536957 0.320949370379094 0.284730536288116 0.977321813877206 0.584657896193676 0.616805945832748 0.538639215128496 0.230000821535941 0.0115166604309343 0.853205343743321 0.786174741992727 0.682697797808796 0.370223541983869 0.216423064996488 0.440001780460589 0.102274290411733 0.995942315226421 0.303406211598776 0.651993750114925 0.425702912111301 0.505001892885193 0.302681783321314 0.186147966939025 0.322314037568867 0.0572321901237592 0.14558059261879 0.721972956894897 0.0704509404255077 0.177979900178034 0.0346528627653606 0.0110540922591463 0.38545435041422 0.0936392346746288 0.251721191385295 0.870280697338749 0.485645874943584 0.807138664254453 0.303028082195669 0.664759006199893 0.525912150053773 0.0978324744151905 0.075494393799454 0.161646905867383 0.581422880715691 0.702682261010632 0.419350951137021 0.151895858312491 0.0843281413987279 0.775057336282916 0.198965249937028 0.627048750531394 0.309929062395822 0.0704247728781775 0.426313405388501 0.0881429403275251 0.915486625088379 0.57807323965244 0.453048464455642 0.277544976749923 0.824504718638491 0.903831542942207 0.538311578184366 0.696862766428385 0.730935486380477 0.139656105835456 0.700370200863108 0.0691539330477826 0.516373618047219 0.188638403394725 0.126427386077121 0.506843333875295 0.977221679743379 0.618856632004026 0.923880606498569 0.871302262260579 0.0288882899750024 0.735509521283675 0.4009843824571 0.645879123106133 0.087655379017815 0.267883257148787 0.832701237916481 0.489002147559077 0.64231801827671 0.114791089871433 0.775765360861551 0.784143547790591 0.742328968888614 0.763033863226883 0.869566625070292 0.18618978144601 0.911810225755908 0.405611399244517 0.19511229687836 0.721808139425702 0.561473709265702 0.912221335894428 0.588678844657261 0.0541581111471169 0.942079460294917 0.378895746399649 0.532513661617413 0.826012689361814 0.0470002349396236 0.357798171506729 0.462925679078326 0.852546606557444 0.175471297372133 0.481035421823617 0.599260485025588 0.912820803092327 0.402942808684893 0.619310035402887 0.336638561750296 0.821069025981706 0.668140762001276 0.574007408926263 0.289528886154294 0.940773507351987 0.392549807280302 0.969131770331878 0.0883199509093538 0.841005309585016 0.242557038047817 0.74561029459117 0.525673463961575 0.24622344717849 0.795845674080774 0.596921703203116 0.528284271503799 0.916676581418142 0.0400356188067235 0.839841021534521 0.0221365632652305 0.15698877011193 0.53940462902654 0.811441261218861 0.160923872820567 0.767348331753165 0.617364070592448 0.81557786376914 0.340235259828623 0.501817829257343 0.513171075738501 0.751869707263541 0.498714727500919 0.481040168558247 0.239855687113013 0.477686975914985 0.837111102601048 0.412895968065131 0.108775774103124 0.565260409268085 0.321157894318458 0.800403790953569 0.0250212241802365 0.333635751560796 0.209783001455944 0.776548420405015 0.395935142091475 0.673193909381516 0.640503157433122 0.46955628072843 0.195850322027691 0.690232516985852 0.167863687362988 0.439542154190131 0.387032462537754 0.472339898408391 0.0664366680011153 0.978316156012006 0.097135142609477 0.730806665308773 0.0793129250220954 0.706012174300849 0.641140864046756 0.862476914166473 0.103819719147868 0.15256998475641 0.342933218921535 0.740425720771309 0.380266660433263 0.816436903567519 0.388600680348463 0.758571764638182 0.373835127055645 0.646283748983406 0.279027961019892 0.546550421149004 0.816575411269441 0.954939070206601 0.432237255985383 0.848557276560459 0.495993896813598 0.871571473546792 0.319549075595569 0.337049443922006 0.482552213640884 0.909019947019406 0.816768505843356 0.498985376660712 0.798840800474863 0.32910507921828 0.411177375600673 0.7134442761424 0.0516616894677281 0.912247867404949 0.114307792163454 0.622891373496968 0.879640913659241 0.261199776188005 0.513709608491045 0.8883539458015 0.322182215356734 0.60159992654575 0.822079525638837 0.125786203949247 0.552238411381841 0.765255140028894 0.836347563148011 0.797547104263213 0.739125499729998 0.354537679066416 0.410754743572324 0.129546878854744 0.758248635167256 0.664588463283144 0.790248403113801 0.795069508631714 0.828109541924205 0.921958892147522 0.682374818394892 0.89943504647119 0.282490893751383 0.889462505301926 0.436999458244536 0.663579971070867 0.0195772340404801 0.25285829306813 0.343247840320691 0.555247728191316 0.855121008791029 0.68492585322354 0.295417431399692 0.96004787906073 0.474133580005728 0.591233292764518 0.661559996800497 0.804059276578482 0.475135217770003 0.574562855940312 0.535866626985371 0.415741880384739 0.887035633092746 0.0387806877866387 0.910086144569796 0.206821219760459 0.0737845963821746 0.590795083157718 0.0487079124269076 0.596511083343066 0.342732546352781 0.862113540139981 0.337952775205486 0.532634260670748 0.593644456239417 0.0168793570064008 0.326181927178986 0.620880810637027 0.399790089686867 0.332041108270641 0.228905689257663 0.211245432293508 0.99711032565916 0.0486394640663639 0.292742000683211 0.51416741586756 0.31426650670357 0.933755365349352 0.404351123336237 0.421529541441705 0.830358228681143 0.908495668070391 0.887574096464086 0.45127790247323 0.144096677580383 0.0642040677717887 0.676653380889911 0.580909665878862 0.532835080299992 0.419191300377715 0.914854867509566 0.486950513562188 0.55102969331434 0.886805938896723 0.230989597961307 0.684904020964168 0.110168228119146 0.976471480613109 0.509776280419901 0.657699923755135 0.762223996953107 0.811452019684948 0.0771330946148373 0.769321043132804 0.0319522194727324 0.79018614950357 0.721607277845033 0.910465559484437 0.317066424125805 0.320446869982407 0.595538119608536 0.357608813606203 0.795561137616169 0.0210891521163285 0.93864816009067 0.0384586727945134 0.617624938616063 0.446113031762652 0.0219833469786681 0.393289823969826 0.0114786150981672 0.850846970374696 0.880830080979504 0.955915115526877 0.145438538868912 0.263121013399214 0.681714712025132 0.492939343459439 0.147523773652501 0.661144756521098 0.972862666640431 0.25005451703677 0.343894365723245 0.647889280512463 0.254060309971683 0.226396440814715 0.0603357925312594 0.750758723109029 0.585709129071329 0.784615555494092 0.504248488619924 0.831225255385507 0.805269864941947 0.348827276399825 0.869652407437097 0.684066877735313 0.469316943236627 0.964892475532834 0.0666687847767025 0.205108267227188 0.048743586812634 0.0604863596544601 0.945281085665338 0.16082757309312 0.570940974790137 0.898188075388316 0.33049171627732 0.310359419248998 0.148079302264377 0.998708717378322 0.898741011770908 0.737440133255441 0.515806341883726 0.795545880205464 0.302788997334428 0.517076691666152 0.620405252736527 0.429071700312197 0.476716650740709 0.371393175383564 0.93075579763623 0.494479254430626 0.687982176144142 0.402377613265999 0.178148276372813 0.239081921654288 0.721458685665857 0.979224347206764 0.251362198286224 0.724552407821175 0.966180118061602 0.151258776129689 0.0182777178753167 0.0486906282091513 0.828598756857682 0.383964544427581 0.114905541657936 0.967204144056886 0.113750436129048 0.0302013490744866 0.03587558707688 0.318818142081145 0.968117003384978 0.673035308790859 0.707985115721822 0.43952749977354 0.450430585332215 0.464274250289891 0.968750195610337 0.173446244443767 0.174263501313981 0.89136944076512 0.979638783955015 0.20165385870263 0.349232612454798 0.40143891900545 0.784296146100387 0.934069169848226 0.637558003484737 0.993799527005758 0.723076122640632 0.186962722167373 0.660383705571294 0.773689424542245 0.693094930506777 0.979830025290139 0.283174024769105 0.40622611786006 0.539735548554454 0.725566629399546 0.496340602755081 0.342879011225887 0.278011100650765 0.309614361703862 0.171245148121379 0.256210385984741 0.463002641503699 0.198551031243987 0.752402702197433 0.773537577439565 0.975475208712742 0.307804694999941 0.95155026610475 0.351678951277863 0.43686333186226 0.447718981653452 0.306677124358248 0.901818452624138 0.911038364015985 0.943087477672379 0.722673266560305 0.579446325479075 0.497772269137204 0.122236999955494 0.252208210553508 0.59823528992245 0.334820059430785 0.963532038060948 0.657922569420189 0.0527316677174531 0.35295812584227 0.13382107631769 0.462905317654368 0.335903245694935 0.691022343847435 0.0131966843223199 0.254946149815805 0.208574708434753 0.206078161592595 0.939665331176948 0.701179928835481 0.0215995204797946 0.421014208288398 0.935653288401663 0.736044754856266 0.620021928271744 0.299148559132591 0.357720163753256 0.140625777996611 0.21879167312989 0.771173230141867 0.154328507371247 0.619165678243153 0.395272217369638 0.998839262607507 0.510166505202651 0.769299453131389 0.865566526465118 0.469778098890092 0.994718690111768 0.912018613237888 0.0918731594202109 0.259106489957776 0.806358695977833 0.310936608626507 0.943502656868659 0.564116119369864 0.0508937511080876 0.397972944565117 0.439651186866686 0.525051932849456 0.633335653834511 0.415526936263777 0.789954035033006 0.385398459360003 0.0756289606029168 0.578402471211739 0.679138913177885 0.979513883728068 0.493847925816663 0.512212342757266 0.791312478429172 0.425933912794571 0.780058450987563 0.100051292679273 0.63858464383753 0.275151857458986 0.635999208840076 0.469385496706236 0.175910418846179 0.987466603680514 0.915229628121015 0.63597023193026 0.37711225531064 0.836962892133743 0.62086459341459 0.823721310805995 0.0177748574339785 0.274000553374644 0.381002617976628 0.774858140542638 0.511240089430939 0.617740979716182 0.799510333929211 0.858242892108392 0.337544936586637 0.323900321691763 0.114423846402206 0.501460622320883 0.0868031964334659 0.574534782369155 0.484545244723558 0.721258527808823 0.195355341539253 0.411543367442209 0.107136670139153 0.585061328529846 0.744582310179248 0.950074009045493 0.295722507005557 0.017163556246087 0.949637557710521 0.225097756762989 0.20380659379065 0.411276220073923 0.624371330579743 0.49088170141913 0.536550841825083 0.948047175486572 0.624419812827837 0.517746325850021 0.104027219656855 0.3951338560367 0.123313436880708 0.42837953890441 0.0425390498316847 0.438159383346792 0.239505644189194 0.413887138026766 0.0277396299829707 0.0419266701233573 0.017773206345737 0.62958686063299 0.452463415178936 0.191490042544901 0.315912764999084 0.512423029039055 0.707900983060245 0.33175197835546 0.0157077352935448 0.719782976547722 0.686566035707947 0.0758801615890115 0.296287840725854 0.0716776561154984 0.427307721937541 0.900018472780939 0.492811586617027 0.0281565930368379 0.0391268499731086 0.0580055058724247 0.16513681843644 0.80081223141402 0.261269862728659 0.469292814712971 0.569517063198145 0.484467780725099 0.562691576662473 0.5934184314101 0.607098684271332 0.0895565786608495 0.162368032198865 0.268705523295794 0.499319592602551 0.288253524329048 0.154565955665894 0.108217854490504 0.9514636804373 0.872513331912924 0.747534911888652 0.429633737157565 0.0174898694152944 0.761467468689661 0.215268695692066 0.6043442912912 0.522897155510727 0.3956327677425 0.0158436825755052 0.553793349491898 0.0848266089265235 0.545237530777231 0.296649070850108 0.413290283111855 0.626552778191399 0.527325018509291 0.160539912399836 0.686472469046712 0.889953280505724 0.480147927203216 0.796907523435075 0.20250545949908 0.938844939474948 0.131719731956255 0.212460814875085 0.752026709550992 0.368946944435593 0.385152733726427 0.789837566351052 0.90174961125711 0.951430661438499 0.807423413703218 0.789221319735516 0.871981335284654 0.856307713193819 0.44285242798971 0.168824702086858 0.264089547800831 0.913911573574878 0.567495438070036 0.160027689184062 0.171163825283293 0.0876650280761532 0.245022122703958 0.291831646454521 0.873030810581986 0.573034679151606 0.939135083830915 0.180699337248225 0.289294907611329 0.347903465905692 0.0497453091712669 0.673229940815363 0.334377827097196 0.150360037835781 0.0816817207843997 0.474327517987695 0.414593890001997 0.911818581696134 0.704565888999496 0.0455272851279005 0.541783945837524 0.0388014675723389 0.244435685803182 0.257660536349285 0.781739266884979 0.831695138779469 0.859035161603242 0.461513392410707 0.837004321701825 0.349629170058761 0.105276331875939 0.708423879686743 0.431139342926908 0.236026875486132 0.757814061273821 0.827700075728353 0.563243438212667 0.244791835655924 0.0884502826933749 0.246462736264803 0.984989285112824 0.350608111179899 0.135220637642778 0.110255188583396 0.623586536506191 0.867073890045285 0.34246213898994 0.328846531200688 0.366500316101592 0.103469525475521 0.991618002636824 0.440937943805475 0.792607090887614 0.0473772964254022 0.655873220392968 0.206664064880461 0.700457803737372 0.882442253280897 0.783705210024491 0.435512989009731 0.442625427674502 0.505280745162163 0.357244855947793 0.835431636525318 0.892144531612284 0.866276009893045 0.352041682433337 0.105297348157037 0.934275877429172 0.283809781793971 0.373745986730792 0.439336385445204 0.644096116072033 0.0337774082040414 0.295222295497078 0.537975835395046 0.700175651588943 0.61069754330907 0.41313780812081 0.715459750546142 0.761493234010413 0.42790884898277 0.511713851026725 0.638667084611952 0.796769301095046 0.743327152344864 0.632699580790941 0.0373713877378032 0.659778414962348 0.640453081030864 0.880331380644348 0.483581529664807 0.641273347339593 0.745921528066974 0.210011684899218 0.0238910560077056 0.972235304049682 0.412906658994034 0.673411184572615 0.46922149959486 0.0881257105083205 0.929655636718962 0.349090690321755 0.0337146857520565 0.253236280712299 0.854733727062121 0.837200444845948 0.382869285142515 0.705218506578822 0.862923165769316 0.876653323539067 0.441927399290726 0.347277376840357 0.594733404139988 0.461189860021695 0.294794597027358 0.877842113757506 0.535829901508987 0.641518632483203 0.0776647544791922 0.594818792117294 0.67535138659412 0.953300426555797 0.610301648860332 0.955484653564636 0.369490955306683 0.955860521739814 0.909072742427234 0.509680387529079 0.349912551476154 0.161389293228276 0.468411892175209 0.794639884314965 0.845455659008585 0.484112005208153 0.701140076133888 0.723728189780377 0.903889885619283 0.847087639297824 0.296833951473236 0.491061527126003 0.589651561523788 0.262412346410565 0.715124090507161 0.271439186970238 0.355344061297365 0.391613579394761 0.906496270052157 0.957193205116782 0.176475538199302 0.128009432645049 0.712454762801062 0.364942680653185 0.487516450276598 0.0176772724254988 0.87047100744443 0.5898687887704 0.63822456207592 0.714366550568957 0.144615064659156 0.949727627881803 0.607842805976979 0.370499413404614 0.901461321983952 0.562495069501456 0.628992128875107 0.81423978064442 0.949330805891659 0.0227426265180111 0.301176107709762 0.379729203204624 0.909465289060026 0.250578131447546 0.916993502769619 0.661551580929663 0.380822014554869 0.774626945545897 0.268864881547634 0.806312101774383 0.645227244286798 0.735566024552099 0.0225790528394282 0.424172956997063 0.0794413429452106 0.894273985503241 0.190915156577248 0.206897063327488 0.620811640804168 0.544265522474889 0.954269549660385 0.43986630178988 0.518272143402137 0.311813365526032 0.807570447456092 0.765372830142733 0.677436917573214 0.239266311076935 0.808626024611294 0.433676864095032 0.196895823003724 0.523172558781225 0.950301616273355 0.314472401763778 0.0224341028276831 0.164917208948173 0.697871706737205 0.822282636000309 0.20180103905499 0.310882810533512 0.276414733203128 0.748965679772664 0.321052859704942 0.981303644941654 0.464005526746623 0.418317550611682 0.569588273898698 0.297315380729269 0.572809376255609 0.900870353407227 0.0507673853472807 0.151768399279099 0.0508292385749519 0.196505094342865 0.432264680231456 0.0108942089229822 0.51247709935531 0.343887524644379 0.696291406915989 0.611391609588172 0.766606835008133 0.45447888773866 0.169535170912277 0.63356864951551 0.60319324974902 0.734021025702823 0.0321593580930494 0.684654784549493 0.862534646242857 0.108266648147255 0.970110811721534 0.310318507389165 0.46564823691966 0.740149575974792 0.603717781098094 0.292947056714911 0.794709352648351 0.2227484206995 0.493578064513858 0.300478385433089 0.432407431711908 0.595397751752753 0.0592308021290228 0.749701045847032 0.081777049866505 0.367292808722705 0.538229161382187 0.316326957414858 0.449225493296981 0.513249518219382 0.660814997111447 0.939259883097839 0.675132400614675 0.916946307646576 0.138315335744992 0.706783746529836 0.114849687945098 0.0626098536769859 0.374442155421711 0.987421996637713 0.155110103916377 0.623366912496276 0.926329712041188 0.87189977502916 0.24080186463194 0.963016768295784 0.206302607941907 0.607024684492499 0.779486064126249 0.85047811454162 0.1458064491814 0.0472252858965658 0.442331999582239 0.48192995529389 0.0971572519326583 0.820397126651369 0.0453647533198819 0.413059874819592 0.884971890347078 0.716567921880633 0.288508658837527 0.974251400809735 0.795050295109395 0.328230445936788 0.315572513353545 0.625880429151002 0.561103343411814 0.953054425471928 0.854997762648854 0.1520654308144 0.0796373658208176 0.350986375657376 0.0172384277847595 0.992174882914405 0.940274751926772 0.185320868310519 0.459470994181465 0.512943122987635 0.643233327614144 0.638506406042725 0.757859227054287 0.680888887152541 0.572732601228636 0.630220422584098 0.0354319491400383 0.429055005258415 0.589846587937791 0.972310268019792 0.227024546083994 0.96736397207249 0.322554262033664 0.986507221604697 0.579931314843707 0.377390743163414 0.217911414438859 0.656451167892665 0.0275427858275361 0.386600438461173 0.837066434014123 0.802886710728053 0.553833095931914 0.31329908747226 0.904248107918538 0.918428288770374 0.407232438279316 0.485628887612838 0.836284869278315 0.0428384488564916 0.257109349479433 0.12312493391335 0.0558101672679186 0.679500690975692 0.276539421137422 0.62652127428446 0.95317730050534 0.568375599258579 0.310666437528562 0.245380643964745 0.356463608383201 0.858350697360001 0.814089222510811 0.798679482953157 0.869942001353484 0.879907359839417 0.735917769505177 0.851786963746417 0.917840244576801 0.230448678587563 0.551758956378326 0.0475127847772092 0.837060184634756 0.252312785084359 0.404591760169715 0.943691312428564 0.220793227497488 0.13098553291522 0.666835593227297 0.350309201742057 0.590819688129704 0.502704114892986 0.0599613882764243 0.534241656272206 0.245427010662388 0.150933261881582 0.63141554862028 0.972951297785621 0.344531635304447 0.890422855026554 0.286470751715824 0.852840582784265 0.412280273963697 0.96320878112223 0.115327807879075 0.585411782439332 0.547559815547429 0.497682308454532 0.781134259332903 0.660763064473867 0.56131986486027 0.250821090361569 0.761447414525319 0.643218764245976 0.156233002275694 0.615460476952139 0.12074604353169 0.233007641774602 0.0739093375625089 0.86087623240659 0.178116467972286 0.804166420518886 0.611425648329314 0.383467977391556 0.868790566343814 0.343908120950218 0.678112701098435 0.652855010572821 0.616912282784469 0.380767509280704 0.92469730094308 0.760415543843992 0.43717113776831 0.738314130119979 0.992277279428672 0.578543495077174 0.956654375477228 0.122536871971097 0.958029153421521 0.46027675866615 0.199343953521457 0.568210367346182 0.309163501898292 0.787873930309434 0.884056743513793 0.22071388283046 0.765722223280463 0.0220614084391855 0.124962336502504 0.870714744073339 0.825433817086741 0.296762815224938 0.862194016573485 0.727211631918326 0.70858910376206 0.0160291505185887 0.614097525621764 0.0150653342693113 0.399450249026995 0.945627485960722 0.562682886954863 0.891321373421233 0.996080265343189 0.533465647103731 0.80112656214973 0.137993194207083 0.631856939850841 0.588727643385064 0.584570946332533 0.667302800489124 0.363520778119564 0.0845244199014269 0.454125925272237 0.15343990172958 0.703751927160192 0.17337842696812 0.570370057842229 0.892883967205416 0.971327184541151 0.109067659673747 0.896866940408945 0.104723863182589 0.858119989645202 0.34123649144778 0.305140261549968 0.0670713584916666 0.611733800680377 0.125342675731517 0.42238753844751 0.270997260743752 0.859002267075703 0.334912380226888 0.213440429063048 0.851730085681193 0.762295566776302 0.214970755286049 0.0126400359300897 0.159347536026035 0.864502617572434 0.875700855380856 0.783189966075588 0.297942647431046 0.559544977962505 0.293516211241949 0.642962584178895 0.150175422520842 0.0760158742195927 0.0317116391123272 0.053371852922719 0.127466667408589 0.703920623292215 0.809436841246206 0.395483523933217 0.499060940397903 0.241909422830213 0.225215098818298 0.955679989082273 0.947927097599022 0.0245845799148083 0.954254403812811 0.0809218391729519 0.490431144032627 0.437027009727899 0.106590460506268 0.230266193575226 0.969315857104957 0.755728774396703 0.403941763401963 0.44692586875055 0.0936861206940375 0.828009194345213 0.794638689390849 0.520447627687827 0.452319687290583 0.543078235823195 0.422678279343527 0.785042903600261 0.0783588260598481 0.756366258114576 0.759677406670526 0.945219661172014 0.822405780490953 0.348601851798594 0.396211453080177 0.715620772102848 0.960752857781481 0.952708842768334 0.388720491083805 0.918302144752815 0.48533030110877 0.682828332895879 0.821376903804485 0.153638057443313 0.510360788016114 0.852867986285128 0.798414801729377 0.192730367323384 0.804793029827997 0.621798243361991 0.936826734310016 0.702427092618309 0.654853561494965 0.400784423754085 0.909116421698127 0.679139390778728 0.861907073664479 0.664142799230758 0.841869578559417 0.80218350203475 0.998381656690035 0.366015398884192 0.198729985882528 0.895910337730311 0.449835153769236 0.0967295991024002 0.0819987186626531 0.614148246047553 0.773830858240835 0.782575712613761 0.167524171480909 0.213710951216053 0.956999020266812 0.164262103557121 0.984412216057535 0.475161540214904 0.795211883010343 0.832589064876083 0.917049025711604 0.196396607956849 0.430244704117067 0.187473841276951 0.366963173553813 0.235265773134306 0.491681623591576 0.686398630850017 0.998248641858809 0.305174485384487 0.427525681720581 0.628629310589749 0.899587138136849 0.915036151374225 0.740963839541655 0.0129925832618028 0.664732461089734 0.797125968195032 0.164599555751774 0.950720043017063 0.947905991422012 0.209805158032104 0.106719402361196 0.927212518705055 0.561776828828733 0.409524833580945 0.711727638337761 0.874419162578415 0.601383239366114 0.286400191262364 0.747179198376834 0.22143274562899 0.590525492234156 0.743143900220748 0.33739914616337 0.674979153901804 0.167688664863817 0.160855595031753 0.7685046255216 0.399264905094169 0.682637333818711 0.963902810290456 0.986994523138274 0.418248288577888 0.525921423162799 0.701671022132505 0.84642886292655 0.552381222101394 0.960222762336489 0.821729136500508 0.202078196217772 0.0943351147766225 0.975552687924355 0.48355305363657 0.669388372728135 0.903913868234958 0.726661154304165 0.225522674452513 0.842613784167916 0.566694697153289 0.248812835060526 0.929787066155113 0.192692659215536 0.0626852993969805 0.0385341475578025 0.840255433158018 0.0509486224199645 0.186380005804822 0.510701784645207 0.497821487840265 0.123044272155967 0.194119040640071 0.419623196294997 0.724190818343777 0.867182205168065 0.273332788334228 0.682599233165383 0.531803343540523 0.85755072632106 0.555326880619396 0.810668883384205 0.230855455743149 0.46174077397678 0.539913378572091 0.822837471030653 0.408268505255692 0.182368813352659 0.648122027020436 0.46913966757711 0.817102801769506 0.187705819520634 0.675410211251583 0.0303834189521149 0.09069234757917 0.878369306256063 0.321775187184103 0.537432630821131 0.189440698127728 0.108056813802104 0.291249336698093 0.336335584868211 0.780051410754677 0.762545674489811 0.313328930379357 0.0989342914917506 0.339304526657797 0.220334581783973 0.634118543497752 0.559350947779603 0.303756935195997 0.152230230765417 0.77306198150618 0.939284161217511 0.582976507497951 0.802755271610804 0.142052231337875 0.0355665419902653 0.614728255390655 0.050875459134113 0.383490716908127 0.379693436156958 0.494877045913599 0.380302552413195 0.692635630166624 0.847739687075373 0.0963816196355037 0.217391631437931 0.340170360282063 0.437191727620084 0.929997333614156 0.0857178445998579 0.876371738887392 0.76573560209712 0.681724238456227 0.196233121869154 0.320897206317168 0.510388391593006 0.118597771890927 0.775838224955369 0.293668643129058 0.557865247961599 0.359462641561404 0.424991107755341 0.338819355426822 0.392626479272731 0.12384233509656 0.220106353352312 0.78792859739624 0.450656098215841 0.391003613276407 0.273084602549206 0.83998015320627 0.759782045050524 0.979679130162112 0.707613094400149 0.257455581277609 0.334712701123208 0.295568796291482 0.184502405682579 0.496955181455705 0.225396036929451 0.38158897258807 0.146176677886397 0.218143845850136 0.727879932185169 0.704981542339083 0.103996193581261 0.208913426548243 0.425996056455188 0.0322260806825943 0.0157816191297024 0.0592398237599991 0.0108391089527868 0.573648549979553 0.975232409075834 0.249245005045086 0.352012787582353 0.165061653007288 0.654932126142085 0.287415618828963 0.200645651160739 0.546247959439643 0.340223251809366 0.748114571790211 0.454523367083166 0.916306744567119 0.856826954514254 0.342656418806873 0.193529741822276 0.34738901488483 0.891136318999343 0.33739756422583 0.159400047915988 0.764767706878483 0.435322362654842 0.60771411145106 0.571936863134615 0.925168275074102 0.777422301096376 0.676582104957197 0.279121286114678 0.176424347087741 0.795621287201066 0.756575414321851 0.322097310051322 0.536699705997016 0.197817179569975 0.630178984026425 0.414727121966425 0.662855217324104 0.873420665638987 0.341853869368788 0.0945881756860763 0.416117261969484 0.745987309976481 0.842193915401585 0.247366119411308 0.251315247265156 0.513644792847335 0.509845591781195 0.0435115763032809 0.0260794004797935 0.500813561230898 0.282114119471516 0.701567576141097 0.244273005321156 0.577603450303432 0.212673446827102 0.845132092505228 0.361913064194378 0.10743558695307 0.559351852731779 0.727286518209148 0.0922039897437207 0.263720271531492 0.629417667307425 0.411360720847733 0.772512235045433 0.561086195881944 0.245715419796761 0.793947300857399 0.765360804144293 0.285920219011605 0.897188265507575 0.703900410311762 0.460227982297074 0.565441219680943 0.448727056887001 0.249534620859195 0.529463843933772 0.718298936346546 0.83296929000644 0.414327662799042 0.378430094567593 0.506278990854043 0.729589416580275 0.28543585453881 0.447767293790821 0.0525928691215813 0.303987251748331 0.233178243699949 0.501156717436388 0.431370092362631 0.350160459044855 0.818785143361893 0.582450557406992 0.456666787802242 0.570816466878168 0.848989728679881 0.0561108826915734 0.0814603198319673 0.409269756928552 0.965617397085298 0.564774637117516 0.0942210848093964 0.792729755472392 0.554186434578151 0.337121727149934 0.0588259296142496 0.408356046585832 0.504564370636363 0.718619011431001 0.954787845460232 0.211736834694166 0.0302670620637946 0.186034612113144 0.856849535675719 0.399236844200641 0.807755576099735 0.279662386432756 0.637175274176989 0.209181672260165 0.0398130883928388 0.905936231431551 0.18628085545497 0.507426106249914 0.389039898172487 0.529687516486738 0.760951042955276 0.306694757787045 0.151648911477532 0.0603425439447165 0.556488316203468 0.978111948228907 0.542140840443317 0.97476660349872 0.506586305559613 0.665225052421447 0.77517122887075 0.932731402511708 0.66284826306859 0.256935644070618 0.981513379018288 0.0584370680223219 0.898149279770441 0.852956311784219 0.425025654754136 0.698170007187873 0.534469398343936 0.251802317604888 0.610942926646676 0.637409157522488 0.910370388296433 0.328514611984137 0.387805087009911 0.817317147736903 0.0573637488717213 0.993472364204936 0.50411326096626 0.912814720135648 0.661288094399497 0.0949301706207916 0.920079243090004 0.59586213351693 0.685126453414559 0.108896424788982 0.831736289209221 0.77668068057159 0.41939270087285 0.580466920908075 0.848405792959966 0.604276084266603 0.392609436621424 0.23213075003121 0.0256322572939098 0.212281705108471 0.924916839436628 0.156938452834729 0.920296833147295 0.509956264251377 0.249232014163863 0.55417639182182 0.349150844516698 0.817993137331214 0.284665884531569 0.520363548963796 0.206396065806039 0.741616224083118 0.633807076984085 0.830403925999999 0.0945830477005802 0.894466537474655 0.173212486952543 0.417015169302467 0.562322912837844 0.0204615650163032 0.415283161832485 0.97804357455112 0.613485330084804 0.216865401747636 0.336276833049487 0.891712317371275 0.938790316414088 0.0245067468821071 0.030130849473644 0.838030761748087 0.98527007291792 0.013422224635724 0.807112998510711 0.274344825211447 0.732971783212852 0.323761378801428 0.184689844420645 0.271250385963358 0.252178948051296 0.949462182312273 0.75239738220349 0.361298596826382 0.366799548703712 0.858157806089148 0.812384062339552 0.996751043971162 0.413967889219057 0.681005018148571 0.323340695439838 0.696923451009206 0.287521322821267 0.541456076547038 0.963610674394295 0.309320260314271 0.812194753766526 0.503202015615534 0.784157238937914 0.628928556330502 0.762312074431684 0.406688337742817 0.716108469869941 0.103913250311743 0.176788425298873 0.0623609968996607 0.576757505573332 0.63969393057283 0.0563197572249919 0.892554436684586 0.813007725598291 0.321589113480877 0.565845881055575 0.569058258207515 0.578877535376232 0.945218764517922 0.109691130002029 0.0542076414893381 0.457981966140214 0.239127070838586 0.180185920260847 0.170770996515639 0.990089376138058 0.378470672890544 0.315984563019592 0.321299058559816 0.609387499410659 0.970246919663623 0.290073603284545 0.928493401983287 0.905266616609879 0.859558897719253 0.946600982155651 0.219351429846138 0.686939214381855 0.260957036251202 0.744221832414623 0.81762342472095 0.116234961813316 0.881946404259652 0.0608245081966743 0.582682502458338 0.0597666698135436 0.0501688005123287 0.62823035576148 0.358235601324122 0.305431162875611 0.821823041078169 0.373931321904529 0.715762154399417 0.856196946217679 0.710399126592092 0.583364240550436 0.939132275620941 0.842894219534937 0.563401190093718 0.858400923819281 0.171724475196097 0.507594048178289 0.0395529957790859 0.39528673279332 0.859227331171278 0.0116989018023014 0.660615158269648 0.511939897292759 0.346289400719106 0.0304306311323307 0.256637546231505 0.12096021224279 0.700015003215522 0.99721803041175 0.0342188794189133 0.24813781933859 0.260524563847575 0.815727269160561 0.36294598181732 0.916358824495692 0.988386908695102 0.186851216892246 0.36738948693499 0.693297087510582 0.157607302388642 0.615467069318984 0.25302459635539 0.11247277227696 0.53205419854261 0.344564242856577 0.847159256835002 0.0903506463044323 0.179295171638951 0.177521937673446 0.203904525705148 0.955733063858934 0.82848794239806 0.983207295285538 0.957544017687906 0.996979242668022 0.0878880194947124 0.975681104694959 0.620977676247712 0.140376765169203 0.563071045514662 0.282295200033113 0.359298172842246 0.113198635661975 0.249572029544506 0.460383626925759 0.385220690425485 0.391148130635265 0.219685004530475 0.845137343117967 0.308905683420598 0.940479525132105 0.346063241967931 0.534602134267334 0.940483037757222 0.713731043408625 0.54374971287325 0.605030549303629 0.501164989243261 0.289283926710486 0.20046340955887 0.99429832945345 0.295592806106433 0.567339237700216 0.346744995734189 0.583887006021105 0.969674756389577 0.345396370585076 0.0629524615174159 0.70959811990615 0.528441965759266 0.456326472999062 0.433085278233048 0.358085778031964 0.879215280490462 0.845315458036494 0.473876964058727 0.369362919786945 0.367929769200273 0.981726327450015 0.403557860145811 0.727316923541948 0.327713601149153 0.160871209029574 0.455898848751094 0.197113601842429 0.437265724402387 0.367392816310748 0.100658120277803 0.402934293237049 0.391377077542711 0.507818706820253 0.547729914516676 0.0118423019163311 0.290676777651533 0.247305275553372 0.487887295114342 0.47143180656014 0.178581724492833 0.566916459533386 0.619661479319911 0.609780744004529 0.203478345784824 0.615617084389087 0.520590956807137 0.158135939214844 0.734452800145373 0.416920365074184 0.224760357353371 0.0696666622161865 0.802196286385879 0.505696857201401 0.835717423234601 0.043543236721307 0.417001132401638 0.740159300407395 0.472363135349005 0.603005773669574 0.385322085176595 0.379714537723921 0.501258828819264 0.125600133242551 0.702396585864481 0.0617808559397236 0.367101448678877 0.191946401905734 0.986262497964781 0.0719906782894395 0.202042207426857 0.261007242426276 0.536266550845467 0.111777901314199 0.555127337973099 0.0342010719608516 0.462929851862136 0.4051395084057 0.553485094336793 0.202653686101548 0.12889761462342 0.919835692015477 0.396955709168687 0.196387272381689 0.836324108382687 0.93355919794878 0.0700197148090228 0.629044440919533 0.0231676668347791 0.858947315549012 0.320843652787153 0.205716090826318 0.624501019723248 0.421473062606528 0.841459884166252 0.941700774689671 0.794401755807921 0.692861012585927 0.67258862568764 0.758982401094399 0.51276139655849 0.416602129859384 0.241917715612799 0.116208943170495 0.320831264669541 0.608017973692622 0.309032352291979 0.195864111138508 0.238077134536579 0.129287183627021 0.948777321835514 0.383737023868598 0.42366239962168 0.791051316054072 0.317647712526377 0.0165824506338686 0.746438982763793 0.10695867784787 0.558253772328608 0.986107867085375 0.606712182792835 0.207969951438718 0.275812989564147 0.826132686112542 0.479625475215726 0.218739417789038 0.201288339390885 0.127812074930407 0.637327878940851 0.409578905280214 0.947437994689681 0.139563709895592 0.430746787304524 0.73716561926296 0.721526472254191 0.883657411122695 0.0191320226946846 0.334960137775633 0.634802129988093 0.916688766693696 0.334790865387768 0.890234994008206 0.453017391818576 0.487467865685467 0.73570039289305 0.847261433680542 0.641701761749573 0.555622546658851 0.491422936581075 0.231472461402882 0.624291822486557 0.875825006244704 0.317215966435615 0.902471964091528 0.776419441900216 0.110180613931734 0.780941613086034 0.184915088308044 0.0512687770277262 0.352718398340512 0.279900688047055 0.511202858693432 0.799580223851372 0.701865751428995 0.294586143391207 0.110538053445052 0.0443576461961493 0.246746916833799 0.863113715136424 0.271324872102123 0.625484981415793 0.463077280926518 0.085992564430926 0.940454481744673 0.860855066068471 0.633872106072959 0.555412721072789 0.0528000727435574 0.139425084176473 0.924924002066255 0.420551057867706 0.793312929612584 0.763200516186189 0.429265461729374 0.305026007303968 0.681170429852791 0.200763239162043 0.500205346469302 0.809651785597671 0.398112780191004 0.873740788898431 0.914074696160387 0.132133056300227 0.749082843649667 0.1621487089945 0.447092308725696 0.360701993850525 0.218014683634974 0.780044741861057 0.941771641480736 0.953445361354388 0.701801892139483 0.132434278137516 0.0254616417689249 0.411805086019449 0.684592185416259 0.39417944220826 0.618439570064656 0.467247462596279 0.934055609165225 0.60609675584361 0.325094791948795 0.448417719062418 0.391262725794222 0.517455958137289 0.692704256935976 0.306765212439932 0.0961003235727549 0.509654420979787 0.523009892359842 0.421998884999193 0.0353746160631999 0.829072722448036 0.919532635379583 0.996933501553722 0.786112037750427 0.795010152435861 0.139856590314303 0.734436385382432 0.706129957537632 0.554931858622003 0.829146253154613 0.551162993737962 0.240359489156399 0.676506885590497 0.387852160658222 0.117288098409772 0.487126919305883 0.601536962296814 0.781792032558005 0.0263364878040738 0.642896083793603 0.313660744025838 0.969394858323503 0.631396496449597 0.219592724994291 0.927273187150713 0.701534902204294 0.755484675187618 0.147393085050862 0.896656887086574 0.71780068871798 0.73539311760338 0.169219466843642 0.345919035787228 0.804590939208865 0.693339771933388 0.185533155661542 0.946963278122712 0.878094598411117 0.0107466687564738 0.442302864317317 0.678183912720997 0.338702700729482 0.163488768215757 0.376662711903919 0.809565062320326 0.918245393002871 0.878803159599192 0.427377004486043 0.856048906552605 0.630956216470804 0.136417715572752 0.870066219754517 0.433913211741019 0.999194419225678 0.319903955610935 0.365918330661953 0.234856974012218 0.167759446599521 0.479928948830348 0.31282728307182 0.557161881143693 0.373283204422332 0.0806269432418048 0.901819271829445 0.695027362063993 0.668649956416339 0.722553885711823 0.401856654242147 0.0180296872183681 0.429175974959508 0.431052865595557 0.94826831666287 0.149007833215874 0.85983611850068 0.290668953710701 0.801465394592378 0.32630165331997 0.195779032264836 0.652387589404825 0.213386645491701 0.345200175985228 0.110000070671085 0.493180125048384 0.521142894884106 0.190092722163536 0.994251640974544 0.905718235920649 0.817375921683852 0.720783202715684 0.453961921015289 0.498742000998463 0.467718349827919 0.0635664999205619 0.816809103298001 0.738714844603091 0.9650899146148 0.0769625408644788 0.453763340024743 0.716284969889093 0.503044376450125 0.253544945931062 0.362647268536966 0.700356863536872 0.750879773716442 0.272313780144323 0.726257320432924 0.450216878086794 0.597239521900192 0.848552750416566 0.272993890428916 0.92553560636472 0.439043144290335 0.186210636605974 0.732487974250689 0.544386630938388 0.979224500029814 0.821181198100094 0.685730576529168 0.208930242154747 0.507891387895215 0.187462914544158 0.0276944556739181 0.33147742794361 0.5804576134542 0.703653362977784 0.856408387625124 0.521142898572143 0.913820622423664 0.963585379759315 0.535261235416401 0.394711253743153 0.14672032617731 0.631007961709984 0.778153291314375 0.335439634039067 0.0202069233218208 0.474796725548804 0.56757874783827 0.670703692364041 0.59156452070456 0.398460837337188 0.563954495971557 0.46887979025254 0.48791084692115 0.871762343773153 0.399554988367017 0.666841580295004 0.0476326162577607 0.61955679921899 0.851122190165333 0.101585056844633 0.846366212391295 0.569763243151829 0.268414408063982 0.552891357426997 0.532809281325899 0.738089625684079 0.368376971164253 0.547107280220371 0.832424248789903 0.876995725079905 0.24198398411274 0.647133797577117 0.920211963339243 0.0125297191250138 0.702826360929757 0.452005678105634 0.890820324728265 0.0157565623731352 0.506202199230902 0.0274941818742081 0.408772317210678 0.330997496491764 0.653809554635081 0.543613905506209 0.844751399685629 0.0496660071471706 0.678040857668966 0.0660225454275496 0.184650079770945 0.812992028158624 0.503545178505592 0.493322229508776 0.500620429315604 0.391213314852212 0.301756447132211 0.708442373580765 0.872538349023089 0.142740999981761 0.055194708048366 0.166490283443127 0.240901169879362 0.12086080764886 0.365524812000804 0.223638924988918 0.429900987329893 0.158872435672674 0.285003660121001 0.851387542150915 0.894994551483542 0.731253272115719 0.225481489677913 0.0458899418311194 0.665315996427089 0.992046143210027 0.254776691643055 0.368922741920687 0.81774961322546 0.702644112182315 0.715505111101084 0.464287624957506 0.165861276909709 0.79123665814288 0.794275303608738 0.906514607665595 0.179605625786353 0.0736590698803775 0.233028880029451 0.902684418095741 0.598196201797109 0.975173796250019 0.369446079728659 0.0142511587543413 0.108922068865504 0.240413222478237 0.92636965440819 0.908410297150258 0.983142364621162 0.869024140355177 0.632934803585522 0.647054487946443 0.92258480188204 0.371689207230229 0.616362289686222 0.815910238227807 0.469364249922801 0.0752819379512221 0.0774745709192939 0.287297751458827 0.194890623241663 0.261547457154375 0.728186788652092 0.723535890439525 0.436663091485389 0.893092761985026 0.648352934811264 0.302014523772523 0.111484695887193 0.964321269765496 0.550362864113413 0.86568533728132 0.170355879554991 0.778507530072238 0.616154223063495 0.232394261225127 0.87761029294692 0.855831180498935 0.925629410212859 0.142527559197042 0.708661814110819 0.110160166530404 0.335932137779892 0.429759476643521 0.936951543258037 0.809629557796288 0.52286425130209 0.448298847163096 0.991316373271402 0.651934645858128 0.0828643003478646 0.848756534305867 0.596061536939815 0.865388314966112 0.378337227250449 0.566377861779183 0.683259673994035 0.663047277864534 0.180660459341016 0.434694219813682 0.458746168056969 0.0320985206891783 0.636011834605597 0.611788045486901 0.707604790783953 0.398843568488956 0.80805946623208 0.926912574772723 0.473862688126974 0.0640832236944698 0.997493380436208 0.247975920720492 0.481654196588788 0.741550443095621 0.429612864709925 0.239838621872477 0.643615727995057 0.674150788662955 0.515809358237311 0.0429866968956776 0.0875688387593254 0.13136939168442 0.7773341842019 0.488198963087052 0.847041382319294 0.355885139948223 0.177907437388785 0.511013210129458 0.459758996940218 0.338235036612023 0.486358509799466 0.950415210130159 0.57174629924586 0.0100010033766739 0.781133880848065 0.467334568507504 0.602877222516108 0.583207876754459 0.0435269549582154 0.444510522349738 0.760048137870617 0.179441809388809 0.735531524114776 0.410292424343061 0.500114697737154 0.871565867729951 0.224772527185269 0.926515696309507 0.832231505271047 0.172006071372889 0.272458275605459 0.29518947703531 0.558758367761038 0.698418742259964 0.802337173332926 0.163524396270514 0.704653047234751 0.925538205048069 0.336970677124336 0.0495826245401986 0.885927705860231 0.592421755439136 0.774046796518378 0.901460937275551 0.393383933694568 0.751275802317541 0.129347825795412 0.195716341391671 0.911986474297009 0.0697338405088521 0.216036266169976 0.142033732833806 0.465286815017462 0.451840206470806 0.656859799439553 0.690499919059221 0.247781473789364 0.513839876656421 0.873436247135978 0.0927604034845717 0.259800963534508 0.860306181686465 0.398075430744793 0.910353677798994 0.54604812520789 0.0662007152056321 0.739092039549723 0.552394436800387 0.216735973993782 0.554675857885741 0.362184458568227 0.136144830079284 0.917171046503354 0.634561368222348 0.917651719250716 0.16594519497361 0.876506548870821 0.956223623773549 0.342018482382409 0.574391349984799 0.785509005372878 0.888277412110474 0.30157059378922 0.139290504234377 0.563321606165264 0.810420433213003 0.894688350104261 0.864863663755823 0.919181749047711 0.157173171520699 0.963207482702564 0.691506149352062 0.955360511920881 0.0943757043941878 0.544375069632661 0.185852534859441 0.114845797065645 0.21843098975718 0.815928537116852 0.916397515696008 0.381969935325906 0.675572143984027 0.166851346453186 0.810901331622153 0.0159333797940053 0.850535346658435 0.587624027237762 0.553663508447353 0.877506997473538 0.871920792001765 0.0195197361544706 0.159846655183937 0.807191437303554 0.117833741698414 0.0978644312592223 0.676910780544858 0.711892688383814 0.359614804221783 0.135578351223376 0.424678196222521 0.733106675946619 0.579825953838881 0.976467097380664 0.514231801393908 0.112039886582643 0.109806001533288 0.46494425535202 0.20746655945899 0.0312439973535948 0.371943493490107 0.75811484123813 0.0835572184948251 0.957027641972527 0.600346498631407 0.660394340488128 0.188000483335927 0.373805200476199 0.652296835102607 0.818800063086674 0.642906335154548 0.428214756010566 0.740582299856469 0.88442429862218 0.717767200877424 0.373682023254223 0.471543403344695 0.459864398513455 0.631112901817542 0.225847205838654 0.60106088622706 0.944704215303063 0.280026915045455 0.134392649505753 0.920854383725673 0.765280088910367 0.343355907422956 0.92112853836501 0.84402829333907 0.221059548514895 0.697761832496617 0.308211970271077 0.938863897139672 0.152549510155804 0.0898662398802116 0.448661734599154 0.858622580629308 0.541158164492808 0.784076829350088 0.858969076813664 0.965763979745097 0.847871147168335 0.116094110824633 0.340422434872016 0.130541391561273 0.620640859086998 0.443213916737586 0.90615274826996 0.571058621800039 0.6362061213376 0.457619234754238 0.85954754501814 0.826878889484797 0.670712791674305 0.855789953311905 0.452772675324231 0.667368386241142 0.107947439290583 0.858776811356656 0.941342808709014 0.83561640996486 0.392850302343722 0.196680869201664 0.402934243909549 0.85115360509837 0.657800232840236 0.349902104188222 0.755476336535066 0.224289800662082 0.401318835355341 0.60047437003348 0.357011974134948 0.624761827355251 0.98834592491854 0.940167110792827 0.659276125936303 0.426954465580638 0.911269707686733 0.0311066414718516 0.970465765267145 0.68682569636032 0.190789102225099 0.64371768332785 0.922556918014307 0.817690515192226 0.796935710874386 0.412021987105254 0.119937219819985 0.687209958508611 0.629803990146611 0.153147793032695 0.763131855071988 0.31247468180256 0.0678795907343738 0.426087242027279 0.0532482001744211 0.935467321190517 0.983610294507816 0.412455612942576 0.879238575287163 0.702792569287121 0.451147694468964 0.720708151385188 0.132908671540208 0.977172110446263 0.0517263707285747 0.992843512569089 0.269335926673375 0.596278913321439 0.399082655194215 0.368345709745772 0.834042107583955 0.272608757442795 0.812022016006522 0.969262521630153 0.295720868364442 0.431310145619791 0.413191752813291 0.409554797271267 0.457834607148543 0.608588161331136 0.649096850447822 0.22654244514415 0.296386934372131 0.832853729503695 0.586616400792263 0.0589021477475762 0.960757561642677 0.362931635812856 0.511583842406981 0.898507036224473 0.362818824280985 0.197908543550875 0.547516065512318 0.954341237731278 0.840474465698935 0.328186636662576 0.99595653353259 0.516841599796899 0.103601261710282 0.904876786908135 0.697364818267524 0.143263504062779 0.302309957004618 0.979991678423248 0.639037206824869 0.717717785786372 0.545308392727748 0.629785671203863 0.520280980260577 0.190867584121879 0.20211661842186 0.151857408678625 0.435791408633813 0.21123115682276 0.55761403268436 0.268006388270296 0.953853108463809 0.214177798433229 0.430667211443651 0.179279352955055 0.572057406175882 0.381041907791514 0.25419951148564 0.857882489257026 0.378674545292743 0.84727775946958 0.843722162493505 0.195694801639766 0.619383035954088 0.405743366442621 0.438840374611318 0.371931636219379 0.802107448480092 0.786131569826976 0.994287032072898 0.425968280001543 0.572148465663195 0.028720513547305 0.896198892542161 0.613753357511014 0.787509663086384 0.262143841153011 0.684702545786276 0.178895437712781 0.92803639813792 0.8214542253525 0.0979890369041823 0.996654383507557 0.873666276251897 0.0678153172321618 0.811437090740073 0.583606145838276 0.387221681445371 0.817960236119106 0.464012194948737 0.139018914625049 0.242254081219435 0.905432036381681 0.502378280016128 0.447116278663743 0.332482090820558 0.147772026052699 0.099490492939949 0.40957045391202 0.11060965023702 0.4217833657749 0.812189309762325 0.570838551307097 0.310099051876459 0.504730841037817 0.604485494026449 0.151142166610807 0.0331928699510172 0.298189015474636 0.556048935414292 0.641015663014259 0.330767218894325 0.7261153213121 0.309170552964788 0.0556044017500244 0.196378807413857 0.969349750168622 0.391334384821821 0.233784952589776 0.358204862915445 0.355460500475019 0.0539520886191167 0.321835003001615 0.280336741534993 0.839662646378856 0.0162892636470497 0.277521629629191 0.249680773171131 0.537254747557454 0.206566283022985 0.85628203292843 0.574149830096867 0.891728167172987 0.520467073787004 0.785250284709036 0.487340939573478 0.0983191406843252 0.597575706792995 0.586494771393482 0.334903929089196 0.934198572707828 0.364547818393912 0.398887602733448 0.0933459799201228 0.792655519889668 0.875469147516414 0.026089355184231 0.335971425981261 0.323659719203133 0.234979860340245 0.0140172751783393 0.105835558897816 0.76127797225723 0.400583160868846 0.91683222143678 0.565969726734329 0.308242674104404 0.393820363823324 0.2743980767834 0.79390608957503 0.0729770166915841 0.119397823375184 0.705979974968359 0.012457073777914 0.138339716207702 0.342875449503772 0.988201573751867 0.886449261424132 0.666981041354593 0.344662423022091 0.21588054155698 0.54548507622676 0.588124907433521 0.637408065863419 0.783071615342051 0.812918918810319 0.995190945374779 0.382145321788266 0.518145082215778 0.228353112919722 0.868395510693081 0.241678544543684 0.305066250476521 0.613999135929626 0.719314539325424 0.513487008695956 0.012824861924164 0.69022308252519 0.22754415828269 0.649222482980695 0.270013505350798 0.703024860552978 0.832135800700635 0.966186248501763 0.0360819592769258 0.0547765396977775 0.541043689656071 0.668884306298569 0.859731281197164 0.437859804760665 0.483311532135122 0.983866712683812 0.624122005882673 0.775031608303543 0.993005685023963 0.614606897293124 0.51879838876659 0.340496952820104 0.147925481370185 0.989306227851193 0.615581002244726 0.114032225697301 0.91523368404014 0.243229408063926 0.409422215784434 0.161979814399965 0.183824989278801 0.923863610408735 0.104433850212954 0.889746275115758 0.277719055803027 0.683189685186371 0.408053518952802 0.333081907921005 0.185094181247987 0.433491554507054 0.807385973900091 0.320818894070107 0.082850552496966 0.175673754489981 0.48507534800563 0.01347393599106 0.0515543788741343 0.518996563381515 0.672984780373517 0.97063845185563 0.443991579529829 0.091688403498847 0.896582475861069 0.748440580004826 0.702917479886673 0.183313489609864 0.847021713785362 0.92822486883495 0.0403558561648242 0.788595278614666 0.572953968758229 0.701399948387407 0.227985056699254 0.0271415393450297 0.11258721184684 0.860015378554817 0.46125756385969 0.162157725323923 0.628078210158274 0.0864180823485367 0.802728290620726 0.624109998785425 0.53750712133944 0.0759747039666399 0.209398555827793 0.436121728855651 0.845554456689861 0.299699246734381 0.293978095282801 0.965786589949857 0.925362079134211 0.625415850307327 0.409516765538137 0.471834002712276 0.735149911821354 0.915618247224484 0.813455898668617 0.39354965634644 0.0411639109207317 0.304303272988182 0.285887215225957 0.820246558606159 0.80185333048692 0.757046142967884 0.481916499028448 0.700339612511452 0.302326427779626 0.490706467779819 0.710606555875856 0.436863046269864 0.203025533163454 0.243625959213823 0.469044445678592 0.508348250903655 0.661284669595771 0.764581380083691 0.88167350654956 0.893729856845457 0.928688563932665 0.0441302733891644 0.495460445946082 0.834865194780286 0.291347717170138 0.583408469108399 0.602769019186962 0.783711138775107 0.386735601804685 0.140630055889487 0.381887469657231 0.706526194512844 0.471428356862161 0.399700492275879 0.253979343720712 0.0197579061519355 0.573399185636081 0.284500576553401 0.718787930228282 0.304817145909183 0.250268997156527 0.575361248960253 0.986900231547188 0.213886274520773 0.533773385703098 0.866511320739519 0.235574170739856 0.27138455030974 0.348914522686973 0.736710159091745 0.929526589524467 0.466526315750089 0.492862334933598 0.574525526317302 0.307190089561045 0.287507666710299 0.123510923907161 0.0779736174689606 0.232062300518155 0.0922771926759742 0.818197680495214 0.334688157464843 0.452544276320841 0.977779616643675 0.124571859780699 0.336604569801129 0.206157118785195 0.198921170514077 0.312595441746525 0.312040423697326 0.995670198227744 0.0587953175208531 0.129352524585556 0.635240323920734 0.236516581159085 0.793981073137838 0.691202545734122 0.614870855661575 0.435319840037264 0.433747660582885 0.334644372162875 0.740287536003161 0.103384800883941 0.316425917369779 0.776567883330863 0.817795051920693 0.106610551320482 0.169654028520454 0.105773879699409 0.66470237292815 0.624925241065212 0.87024363509845 0.0863734056940302 0.498815785949118 0.139955526066478 0.24613055058755 0.893877540614922 0.265388294549193 0.848943178963382 0.0685978950257413 0.08483730123844 0.275282731384505 0.768564281139988 0.660293215194251 0.882158834291622 0.743672945958097 0.746614404262509 0.565441620294005 0.376393828622531 0.464994609509595 0.571315894909203 0.531136275308672 0.598630227555986 0.728908301305491 0.976296648508869 0.615488295357209 0.466469443677925 0.100578775380272 0.643425688038115 0.843380103479139 0.563766953737941 0.0934247342706658 0.0647829817677848 0.429895494689699 0.601982800378464 0.469991309172474 0.839645925739314 0.115868849419057 0.873327903891914 0.618549767469522 0.824436934816185 0.322050714234356 0.457627889194991 0.520213460363448 0.278056086408906 0.558411573306657 0.805761075795162 0.607568060560152 0.495997085352428 0.952698940618429 0.789562061890028 0.305262599973939 0.458311575262342 0.857605648804456 0.208791853392031 0.16884730952559 0.301225041742437 0.395474079330452 0.55628507215064 0.304761223276146 0.799998146025464 0.360538988821208 0.990486979761627 0.749848476063926 0.0304527754918672 0.766255682676565 0.760201175517868 0.932407067974564 0.480842745841946 0.451401800245512 0.28622134081088 0.5041518855514 0.820897342769895 0.838780235026497 0.386429984748829 0.753811676315963 0.245022879443131 0.474213512223214 0.512754093322437 0.601020068181679 0.598254913047422 0.792333520341199 0.866008595833555 0.0138029785384424 0.17391033784952 0.668636786895804 0.887121809388045 0.736453489668202 0.672275827100966 0.385064537769649 0.713547879566904 0.0116089959791861 0.909741279419977 0.281548679028638 0.154778060228564 0.814642600074876 0.695299107031897 0.161873706798069 0.656915250464808 0.881574748284183 0.022684956677258 0.259990883860737 0.29464885385707 0.786036313583609 0.0963349544373341 0.598522041975521 0.908785072283354 0.233697003039997 0.348956364854239 0.216401760587469 0.355743619811256 0.914103056015447 0.422313919919543 0.861193605773151 0.69911403873004 0.116357350717299 0.353973156253342 0.381477909416426 0.434003715487197 0.761421361307148 0.516836929358542 0.627106850489508 0.892061045740265 0.108153777606785 0.284309168334585 0.384116163332947 0.587889920673333 0.979627695640083 0.947202874238137 0.653305451555643 0.267707389628049 0.786358887543902 0.34404865730321 0.921773667153902 0.848550639706664 0.866474956229795 0.839746852570679 0.835037029432133 0.25118839145638 0.0696714488277212 0.0114924482349306 0.917418984267861 0.540897579065058 0.238751314918045 0.493648558582645 0.383117668929044 0.9629226445104 0.0182306161057204 0.982592059192248 0.189879793094005 0.225502648409456 0.302929130538832 0.283568976232782 0.748323838408105 0.852893702278379 0.761176041588187 0.336410234894138 0.748809774676338 0.587540844015311 0.253815667929593 0.686559385946021 0.863355841476005 0.141348562792409 0.276317689183634 0.392306312678847 0.17045941544231 0.583951962501742 0.596529999056365 0.820420007004868 0.365298224284779 0.996926225516945 0.586296276149806 0.482324302610941 0.682983360930812 0.0282755758077838 0.911592204428744 0.039609004619997 0.142072449158877 0.966765853774268 0.648252395223826 0.0676555046602152 0.119287402383052 0.129604858721141 0.124202863110695 0.0175884001748636 0.28817029892467 0.190014564353041 0.608770589639898 0.722833615741692 0.85174123369623 0.631927869799547 0.657699669280555 0.792580493453424 0.517026357792783 0.476752082637977 0.827468775853049 0.334548257759307 0.206720899611246 0.263069044803269 0.465915948557667 0.69555910398718 0.880069745739456 0.0160013104462996 0.0926033716928214 0.0122511879377998 0.936950687863864 0.485563933667727 0.0707798262313008 0.764095637437422 0.7856481541018 0.933160400553606 0.335205331179313 0.302411551831756 0.304996179379523 0.356070030252449 0.329586057381239 0.932774720815942 0.37275918801548 0.776409690729342 0.433859829935245 0.587329243561253 0.657122710174881 0.206419853186235 0.830825609050226 0.0911640298133716 0.66951013351325 0.329286916980054 0.0362418843340129 0.918702621588018 0.214002624033019 0.0314846738334745 0.637878161089029 0.172267576735467 0.57927100563189 0.0328522919141687 0.0714673987985589 0.218218101717066 0.625886764507741 0.886135201298166 0.731906653349288 0.0552431402774528 0.347663338943385 0.687919166486245 0.0205909007997252 0.538161415131763 0.453982120396104 0.691673079375178 0.395568916751072 0.0570533219235949 0.937055533695966 0.161200215157587 0.309112307559699 0.591121073623654 0.863042553763371 0.520836363886483 0.791924670739099 0.0789556362573057 0.134114635104779 0.570381999937817 0.469630071441643 0.869247795620468 0.629993917157408 0.79949225332588 0.914454208116513 0.299144567062613 0.916602315178607 0.497799122198485 0.373303882325999 0.0186255880841054 0.497387510025874 0.612887475250754 0.875953483867925 0.183839199517388 0.182575430115685 0.193242288811598 0.531316728442907 0.906553318458609 0.325978463687934 0.127671947719064 0.476629229732789 0.258368874411099 0.469029691223986 0.695391618683934 0.970218945899978 0.379383484274149 0.828112630655523 0.932300929254852 0.672345550830942 0.326791536710225 0.0382482211641036 0.322196499356069 0.31920397072332 0.153982256210875 0.792993348494638 0.0591723199980333 0.202033042884432 0.632105220372323 0.508589782316703 0.823263508500531 0.759099141769111 0.227362542725168 0.461542067362461 0.725723670411389 0.488317087697797 0.700196798334364 0.343810497447848 0.615831559898797 0.70688764776336 0.144313787270803 0.890900959286373 0.957386940487195 0.262726105500478 0.486798283825628 0.0760318800713867 0.548574938389938 0.68654147107387 0.549770229235292 0.824191740951501 0.0746581663563848 0.164173860347364 0.30646580995759 0.386843301947229 0.237992533955257 0.194434521351941 0.111508929058909 0.754983008748386 0.436678817046341 0.70284712319728 0.597529681008309 0.627178520120215 0.821868048273027 0.160124918296933 0.232872430256102 0.0664217879227363 0.18448831761023 0.588534132062923 0.0832764235441573 0.735969936102629 0.323694853521883 0.541960846008733 0.794700728172902 0.875708900603931 0.496015592385083 0.441390818201471 0.807098262957297 0.794042691022623 0.424954707748257 0.878541432032362 0.239643296727445 0.572465971568599 0.480053741182201 0.478199719374534 0.533098724954762 0.564335912337992 0.891384784844704 0.909332429356873 0.458165655757766 0.956342247421853 0.655068660282996 0.913558929201681 0.778318620037753 0.823255540034734 0.849284041209612 0.117885540414136 0.941832675503101 0.499540499818977 0.895854213868734 0.792220442579128 0.616676250696182 0.163135846087243 0.596465520868078 0.612441761870869 0.178446306444239 0.0654632909758948 0.434255950967781 0.461514982415829 0.325059316486586 0.635257200840861 0.532176443382632 0.0834856159402989 0.314565079838503 0.246618957149331 0.814094259908889 0.919957771585323 0.156162615390494 0.781926529058255 0.230090122751426 0.368313736536074 0.158640656813513 0.421725092018023 0.621324282612186 0.314038397211116 0.510447947634384 0.238759745541029 0.0943966010445729 0.0437017983570695 0.0146545705758035 0.0306462397915311 0.229512911245693 0.62369656956289 0.633378523581196 0.7203341659531 0.367033498203382 0.754554076630157 0.380281028335448 0.562775202218909 0.0102558762650006 0.114009207733907 0.678735165284015 0.381342318491079 0.87730943899136 0.648319864179939 0.0488366885506548 0.712912896799389 0.10247735789977 0.710368230058812 0.0874036013148725 0.478390311845578 0.993238376902882 0.269040577805135 0.128016437380575 0.779816578431055 0.692858554970007 0.413566462944727 0.0551341246580705 0.609732616730034 0.905077963124495 0.224798887432553 0.150455263652839 0.0872643029899336 0.429473345333245 0.142883190189023 0.770184846953489 0.474265596992336 0.0744615764450282 0.912428898639046 0.74249644335825 0.687935025738552 0.532034543838818 0.123768926556222 0.558510546400212 0.12657566108508 0.450796114786062 0.55006276528351 0.255248251019511 0.763894668903668 0.866512678628787 0.497903340372723 0.638557012139354 0.171219394095242 0.133321748555172 0.449464856605045 0.0921164539456368 0.965709129408933 0.116645554013085 0.140189910293557 0.837362177963369 0.709236597043928 0.445779402449261 0.79385701701045 0.899341274662875 0.469204007233493 0.644782975926064 0.125818309006281 0.93050191959599 0.470403256956488 0.0200446319277398 0.792192581531126 0.0663153182016686 0.380600784404669 0.651955633095931 0.18599437862169 0.827282003497239 0.981946352764498 0.778260047088843 0.139849464795552 0.637854792762082 0.986474151664879 0.25376237094868 0.722049412445631 0.874436539458111 0.440043103997596 0.495141362021677 0.321803896711208 0.0526613965444267 0.500251729532611 0.078805978235323 0.0462352069024928 0.061922406964004 0.922293386997189 0.348677180192899 0.827465912553016 0.921582781483885 0.854191028210334 0.793402188646141 0.88232047543861 0.54654553104192 0.270556307006627 0.317991287554614 0.302983415913768 0.129443552494049 0.12179071769584 0.264199848470744 0.47130598294083 0.613370417063124 0.761738913774025 0.786627982426435 0.784058816975448 0.0493950329790823 0.218770796533208 0.131131027142983 0.954469103601296 0.762510630297475 0.934310759117361 0.0299821319011971 0.570276291335467 0.358691693763249 0.824081469324883 0.150864994004369 0.789818229740486 0.43701764165191 0.873181048317347 0.974994776148815 0.877816179017536 0.5079052330181 0.424611603405792 0.710153235227335 0.0731650217738934 0.93843274574494 0.118667121054605 0.546013993113302 0.310578078837134 0.275798966032453 0.155658680577762 0.640212302207947 0.0253445256059058 0.0784347180323675 0.315681785752531 0.501005113283172 0.0800217293901369 0.146839326696936 0.0338737063179724 0.0581735499133356 0.39726453020703 0.965965289191809 0.248560416791588 0.917082496494986 0.991724552803207 0.779642580284271 0.415334424860775 0.115931608981919 0.55832351841731 0.398921781850513 0.654762925670948 0.689532336401753 0.245318886165041 0.24114445380168 0.277963336417452 0.893319180281833 0.718339210406411 0.0681950843543746 0.579646360939369 0.734668895625509 0.813758151081856 0.170175343439914 0.566667975708842 0.0247947318921797 0.159017844614573 0.325416934408713 0.498415553907398 0.81279209919041 0.642303427478764 0.44331522712484 0.404408547000494 0.900191685836762 0.79025245442288 0.267560555490199 0.977763454280794 0.229622430743184 0.864010805108119 0.123976956068072 0.198059058119543 0.933299311634619 0.444787039868534 0.922448431858793 0.552098596962169 0.295533191978466 0.698466215368826 0.197698785040993 0.100380231500603 0.991304646234494 0.64244867045898 0.868563536063302 0.592131312121637 0.283345317509957 0.806853633131832 0.0979929782636464 0.962545861701947 0.0197650627885014 0.388704309819732 0.663524322044104 0.596511846766807 0.325014067264274 0.107445847073104 0.182306938227266 0.865318122394383 0.39238556307042 0.704825056607369 0.960491340432782 0.532022844692692 0.0346483898675069 0.948283871882595 0.705585816663224 0.178264080055524 0.384085242366418 0.633121433260385 0.256010503808502 0.0808742710971273 0.051638063439168 0.96146226744866 0.610317184026353 0.735498349526897 0.753432470697444 0.564918391283136 0.607644216457847 0.725946623105556 0.736497106703464 0.959465991123579 0.635881243045442 0.0859050728892908 0.19713256803574 0.722051072292961 0.947594372085296 0.764237395913806 0.608386187346187 0.550375783999916 0.885784862178843 0.497733477898873 0.25591725892853 0.305453189909458 0.155174559745938 0.054199859960936 0.975525119844824 0.797803672726732 0.491729135885835 0.460480183202308 0.990273136058822 0.70984378676163 0.395964829639997 0.704388648145832 0.0311421807832085 0.353274808393326 0.942877900798339 0.137419339276385 0.969526720873546 0.0725919224298559 0.799381587079261 0.48801064406056 0.274467905391939 0.019723954310175 0.573267651321366 0.0668779640342109 0.244698671221267 0.0236242875852622 0.496655938941985 0.559212571003009 0.844727985258214 0.337151860028971 0.973921363414265 0.138891575683374 0.228149476321414 0.639078801663127 0.835198378763162 0.760154648621101 0.472584000614006 0.477118259803392 0.98802728932118 0.782613317456562 0.901736837278586 0.793337208423764 0.475362674249336 0.052462999955751 0.480352396145463 0.10491221747594 0.0488501819269732 0.489566399762407 0.504971427621785 0.328168394246604 0.163348035474774 0.673900616869796 0.20733065366745 0.292063371837139 0.0440375561290421 0.204647626054939 0.376938030810561 0.949306358583272 0.875286423934158 0.110348331581336 0.174957793485373 0.740491707827896 0.977406484300736 0.222757002071012 0.68425481551094 0.635782059733756 0.550965258460492 0.402214055492077 0.628141370564699 0.395952820698731 0.0402894641156308 0.594204230934847 0.237028543676715 0.512108118128963 0.35495393079007 0.523442975594662 0.499660142287612 0.793883168883622 0.202362004064489 0.732415663362481 0.629268504404463 0.489990249304101 0.124525864883326 0.0775480541423894 0.0265848310221918 0.468831396517344 0.0275510387332179 0.58087301854277 0.467422799500637 0.387847463020589 0.316913769573439 0.794436637726612 0.392376936750952 0.979265131598804 0.139883101079613 0.172880310264882 0.0622765025799163 0.612761963962112 0.871312391455285 0.633584123828914 0.598632352557033 0.66175811701687 0.915175106250681 0.620767324424814 0.835131864547729 0.152338387763593 0.35205963994842 0.0995511890458874 0.520689090411179 0.670513379953336 0.626427586378995 0.194404796692543 0.278281683195382 0.585324390244205 0.988664325634018 0.651292073570658 0.536248266247567 0.527181374523789 0.302760066064075 0.114464589303825 0.353035041475669 0.269491262889933 0.460948767946102 0.294876223898027 0.247682622401044 0.575402368733194 0.975990785276517 0.162477071559988 0.491290386673063 0.640099091907032 0.464858156044502 0.900301884624641 0.673598547014408 0.408491156913806 0.84469610309694 0.745019039730541 0.800736681967974 0.217824629617389 0.371919073611498 0.721165660261177 0.892319703937974 0.153848663510289 0.881254013732541 0.893482141054701 0.270551278828643 0.973718541872222 0.498988564047031 0.158225880074315 0.736042512068525 0.657226844215766 0.0190842241165228 0.914794425878208 0.790652137408033 0.675575369864237 0.867511678063311 0.499170817174017 0.772425696861465 0.859940182007849 0.587645141021349 0.705621618055739 0.697069615998771 0.977358133899979 0.233719312900212 0.69400737585267 0.658672025871929 0.149298720941879 0.146607808305416 0.155356583292596 0.0982230673101731 0.347442452702671 0.683054256304167 0.509549764159601 0.768587630565744 0.733474864244927 0.441004440272227 0.408233703551814 0.986445267878007 0.011199394017458 0.641456107110716 0.196351186318789 0.12084286719095 0.69003785453504 0.36982386038173 0.825423590850551 0.600684176718351 0.0280320362583734 0.964307316076011 0.926010410522576 0.534044620338827 0.663411174209323 0.928863741329405 0.865338404295035 0.676789490906522 0.212359169798438 0.711710445629433 0.0793104388238862 0.191501555906143 0.793445550745819 0.0665658677881584 0.373339392594062 0.132889650026336 0.477851246402133 0.017688754668925 0.170838470081799 0.714936612353195 0.473115946531761 0.269518936309032 0.697875689356588 0.170870804488659 0.108200762050692 0.148993567887228 0.452090754904784 0.726845265510492 0.0720790690206923 0.193077819861937 0.850802801055834 0.270360168649349 0.11078343793517 0.341568254614249 0.219253409418743 0.230573052577674 0.194350703556556 0.480379913053475 0.0189959292742424 0.518250374991912 0.384289461444132 0.239318932686001 0.295879485551268 0.716305630274583 0.639993337204214 0.500643491304945 0.938559666555375 0.725019181508105 0.498475642639678 0.72493363771122 0.138723244667053 0.697131888279691 0.841141790249385 0.223771277817432 0.504159030432347 0.645237994685303 0.970894370763563 0.833374516803306 0.90014370677527 0.331986419286113 0.518967903642915 0.687580127974507 0.247739392591175 0.538909832478967 0.197041438936722 0.240357496233191 0.780705802510492 0.755003856762778 0.913991493345238 0.5431290565175 0.107911867478397 0.348848599479534 0.290184340295382 0.511113984137774 0.456743541623 0.385759950643405 0.179279305932578 0.196593159604818 0.473909348254092 0.582346838500816 0.220601387317292 0.222479152248707 0.210667151717935 0.661554942114744 0.822165412884206 0.747708437736146 0.0762905486417003 0.572791121162008 0.835629103959072 0.256829832664225 0.648494565128349 0.388354725595564 0.030759624352213 0.244522361827549 0.374069039905444 0.0515345531376079 0.250178856682032 0.977620274296496 0.46459872335894 0.790067046640906 0.113286645833869 0.618160682981834 0.414684894629754 0.373777767932042 0.389463215945289 0.592470914903097 0.801712285876274 0.0796709419437684 0.24600427426165 0.873540022284724 0.35644297542749 0.881172869764268 0.645442681682762 0.561212086807936 0.0859737787209451 0.284077002231497 0.606811606518459 0.507030875417404 0.188163208996411 0.655810107700527 0.0767088011256419 0.0373091488797218 0.419204629405867 0.697164108357392 0.74274074033834 0.946943025956862 0.340540385453496 0.94995546054095 0.399086589408107 0.10453336291248 0.246602800088003 0.355337908267975 0.357924734577537 0.0360445342259482 0.717850781024899 0.555408176719211 0.0513210379006341 0.853232895687688 0.18379354737699 0.359170623682439 0.252784491290804 0.378448860454373 0.113065248799976 0.506701422345359 0.966029005339369 0.0279673533840105 0.125666053683963 0.58704624685226 0.687809617714956 0.520818984010257 0.268266302936245 0.023267720292788 0.521417986976448 0.555087934290059 0.119062805054709 0.642164319548756 0.60167776925955 0.417175176418386 0.246464084472973 0.698987381844781 0.14498296667356 0.379753834223375 0.614591588480398 0.429511172380298 0.436609284633305 0.539209293969907 0.222159705744125 0.183090643868782 0.774081863530446 0.448845537623856 0.954533681366593 0.391883403125685 0.0914252223842777 0.113288777288981 0.045432495882269 0.430526803019457 0.779372535501607 0.0957124556764029 0.166603474381845 0.205795311944094 0.657807646947913 0.24698393455008 0.560603048230987 0.708474108912051 0.0982273712498136 0.919682542574592 0.494930857836735 0.62311521431664 0.497271528164856 0.585786672823597 0.501918443988543 0.217998574287631 0.0474656475102529 0.0767080169566907 0.34401873325929 0.749725512056612 0.356402220078744 0.134525353158824 0.320041528625879 0.829705162313767 0.853197037591599 0.320647614237387 0.898187959676143 0.203065363736823 0.62011278583901 0.35771090147784 0.547694849579129 0.491545998090878 0.476536790458486 0.411578873330727 0.547799825645052 0.797247990369797 0.501163116411772 0.221478395925369 0.236551656469237 0.190750398808159 0.840631009978242 0.452348534197081 0.580639318216126 0.437801962043159 0.657559757127892 0.128222047539894 0.047988556122873 0.476396049188916 0.872380499639548 0.506886697588488 0.575293580389116 0.626524148879107 0.619711822182871 0.679082281289156 0.108029956822284 0.3455462890747 0.258460344423074 0.735256503247656 0.322438625465147 0.74029913188424 0.585399387637153 0.521130690015852 0.300735673755407 0.0816520237852819 0.853336897650734 0.24563546936959 0.908098348656204 0.889912641791161 0.639806658201851 0.0979135169624351 0.120355144760106 0.921352974341717 0.713448335519061 0.548032334505115 0.592462085741572 0.180077515011653 0.0958336837706156 0.327951135421172 0.325304428292438 0.97785090940306 0.0462128979642875 0.132615038300864 0.143373892093077 0.755423726912122 0.769240475650877 0.44989878048189 0.417561600909103 0.977543445562478 0.117709614345804 0.182864703172818 0.574152767849155 0.725817904376891 0.826842931811698 0.798194000774529 0.981202609774191 0.897018468035385 0.589753486430272 0.271240384005941 0.132970096725039 0.757676080039237 0.816922947249841 0.768034211972263 0.627091843634844 0.972365580052137 0.716698325811885 0.0757741584046744 0.603771461404394 0.696159367570654 0.176650682634208 0.856687291534618 0.942217060048133 0.263904630988836 0.810065179092344 0.495950338556431 0.0591611777455546 0.439634599226993 0.445067649034318 0.863752077759709 0.729856045548804 0.768853606982157 0.0229919396899641 0.742170424310025 0.990613507104572 0.384187933001667 0.307717028737534 0.392135152015835 0.940489326321986 0.77923303617863 0.101725702686235 0.748298111120239 0.851105276134331 0.775317128321622 0.567541512951721 0.572052133434918 0.353397333293688 0.0880853571556508 0.823902242463082 0.0244000478112139 0.292444774603937 0.375031369645149 0.760042988448404 0.641357133325655 0.101064511111472 0.0394866744941101 0.307661203606986 0.765612966786139 0.943002081627492 0.58795071428176 0.307067695355508 0.427547892003786 0.124899085508659 0.443118572672829 0.8157261092728 0.359259259898681 0.895336746263783 0.951457332172431 0.104286981269252 0.0561923355329782 0.402484056479298 0.271384775049519 0.511948865908198 0.0519545180234127 0.271068468678277 0.427530870097689 0.37345627986826 0.761396899246611 0.165425407132134 0.876545706838369 0.973423079135828 0.899408806776628 0.104752376321703 0.0172741166921332 0.429168807719834 0.110729583369102 0.0184382906439714 0.80197667966364 0.215580662626307 0.396695781594608 0.99127361624036 0.837548489314504 0.332273707026616 0.359359033757355 0.0435461968323216 0.452011566979345 0.320011755099986 0.626002930079121 0.569830932929181 0.695961854727939 0.590332753094845 0.928923041743692 0.726133948436473 0.416253294767812 0.805003750454634 0.929313579318114 0.522776899905875 0.542430426983628 0.711691964643542 0.529805058157071 0.0222724858834408 0.214399331694003 0.953100460937712 0.702385044842958 0.521703346334398 0.262067334200256 0.175381028277334 0.832555822520517 0.181743444607127 0.549550262698904 0.822339046376292 0.1121008212585 0.315152436904609 0.542538707070053 0.0892291906592436 0.761862440437544 0.932937718238682 0.86112139722798 0.686790388703812 0.301732262135483 0.0895449341437779 0.896575463518966 0.640756888643373 0.962038705158047 0.740179807969835 0.157997821522877 0.403214625569526 0.568444670436438 0.128206512834877 0.222450358818751 0.923397683587391 0.414434093334712 0.922958615589887 0.422885713237338 0.371925578617956 0.987965256532188 0.842185776594561 0.696286381734535 0.840990819286089 0.98366617634194 0.163066028542817 0.38056504271226 0.414811275603715 0.97083554218756 0.0248112333239987 0.0156883500469849 0.750792021015659 0.339680185536854 0.936829669065773 0.86451468068175 0.521524506486021 0.304768689707853 0.255933043728583 0.586759345203172 0.443500501906965 0.233085222176742 0.405182553334162 0.4149568804726 0.470580702726729 0.114013467647601 0.581005445132032 0.888751657069661 0.159925368505064 0.938632670103107 0.38945974757662 0.996537540950812 0.0183929423056543 0.457266866753343 0.266127385080326 0.252012634391431 0.0974437711783685 0.386594353429973 0.388416545169894 0.155814355171751 0.0745689923781902 0.695121474093758 0.971746780162211 0.549753488081042 0.462401204432827 0.591717949053273 0.259472527669277 0.634118060825858 0.0818669190397486 0.549854058094788 0.0277801463007927 0.734381662283558 0.743892421063501 0.712214690467808 0.0257248231139965 0.388311746590771 0.208241243930534 0.748491700813174 0.728739793032873 0.879556289336178 0.336941898216028 0.164482553687412 0.334083016451914 0.280355433430523 0.045852296189405 0.725340979828034 0.167844447793905 0.0879920039395802 0.386472805398516 0.820055407627951 0.723791570316535 0.874342861925252 0.0668430834985338 0.191065087283496 0.0437154835113324 0.256399846228305 0.580674688108265 0.608918652585708 0.0801591919944622 0.709781877291389 0.648561713686213 0.345340330395848 0.125047142461408 0.2444334981055 0.516263448302634 0.183314200709574 0.257251391704194 0.444504129136913 0.869144726961385 0.926258252628613 0.379637454976328 0.640623059908394 0.582501608603634 0.339517722188029 0.979681971794926 0.826496196365915 0.28171665023081 0.354572942696977 0.135751220600214 0.156881829244085 0.276405747991521 0.419154423000291 0.267483108087908 0.387369830368552 0.205601255022921 0.729307135581039 0.569720146590844 0.0142949269991368 0.469918621643446 0.653434521108866 0.4852250837069 0.616816641141195 0.826867850497365 0.263145283681806 0.689065160027239 0.736463183213491 0.207361294343136 0.818010859733913 0.502518560050521 0.601838290165179 0.881119334213436 0.75622446391033 0.375211174145807 0.466985478249844 0.807583196770865 0.82072431595996 0.740309130153619 0.659227191903628 0.450905920336954 0.423439272206742 0.232657616599463 0.0685691700549796 0.825907710068859 0.549550828812644 0.509320752711501 0.673554176236503 0.329291981346905 0.10013036604505 0.844333419885952 0.0408295426168479 0.851546209817752 0.108954136811662 0.673259632512927 0.413381866761483 0.462460608573165 0.402698891342152 0.415357377131004 0.313331176394131 0.124508006023243 0.566933948206715 0.324005289920606 0.0569158766069449 0.749511074810289 0.896355067787226 0.88278257730417 0.637933898859192 0.535444758611266 0.141674031862058 0.30382364971796 0.0280850121495314 0.76062349129701 0.411737941610627 0.736440030867234 0.779813009332865 0.622480952099431 0.525977633462753 0.099759230313357 0.154225801292341 0.562581839801278 0.186444067705888 0.518080310828518 0.145474414944183 0.772974093731027 0.0547297813766636 0.86072959442623 0.673402980533429 0.518875255533494 0.808000729165506 0.227817668898497 0.858713548146188 0.154490663460456 0.96361606469145 0.23584334860323 0.461862631572876 0.193485063784756 0.469360948668327 0.856038616467267 0.121066915462725 0.176658563970123 0.224908281536773 0.54266761043109 0.80122576758964 0.174281876729801 0.888341229218058 0.382376148672774 0.547767529271077 0.995490020082798 0.0967056026565842 0.569684412044007 0.662991075862665 0.0495914799789898 0.451374661361333 0.163803286810871 0.987900993633084 0.063730440789368 0.504591359694023 0.792697382571641 0.610152334747836 0.129857035884634 0.740652645942755 0.817485505721998 0.841978668861557 0.0734857028489932 0.216836399943568 0.467343988216016 0.185836431274656 0.0192396707437001 0.293324182741344 0.39720903423382 0.0582382950233296 0.924894328578375 0.449217665207107 0.375640734382905 0.531219140437897 0.372051004851237 0.462325357408263 0.962516374459956 0.225041687069461 0.80390372392023 0.495364958508872 0.348825135033112 0.515019513627049 0.870936364463996 0.635487560497131 0.593117386598606 0.300794376938138 0.833502086016815 0.940524731711485 0.871886944808066 0.747896225685254 0.300886047717649 0.686346820839681 0.798745336087886 0.0193517557322048 0.119379213538487 0.189450097552035 0.94156123157125 0.773405635827221 0.561902433701325 0.150387897500768 0.925562950165477 0.297972967477981 0.746303004364017 0.542164527324494 0.915398487448692 0.172448174164165 0.609382423057687 0.463412450456526 0.467170970165171 0.85578244562028 0.906177183361724 0.64951255910797 0.771241333670914 0.963890025708824 0.393589308972005 0.604293935750611 0.806837648486253 0.987902504345402 0.297961600255221 0.456297534583136 0.604047481499147 0.755756724418607 0.347746740451548 0.613367323491257 0.617142656731885 0.26894314308418 0.275177949171048 0.223867344968021 0.921091737053357 0.146142665192019 0.415692917078268 0.324136245443951 0.36465605445439 0.817950856748503 0.201472725355998 0.0342244119360112 0.230890955638606 0.450023614785168 0.434131948316935 0.587557620436419 0.0804447322967462 0.128382676090114 0.825379380502272 0.726430936637334 0.291947262047324 0.399432404688559 0.0241589407529682 0.834188583982177 0.948319642848801 0.273384143563453 0.662844017215539 0.533139765895903 0.584203749194276 0.23900142217055 0.0114268758520484 0.0353679222753271 0.975472216561902 0.210519088541623 0.198797139741946 0.393018809694331 0.293970113447867 0.900381452878937 0.562025389180053 0.612752219014801 0.865724411807023 0.342835161383264 0.668652951794211 0.099597372955177 0.89641981981229 0.659681492648087 0.498846742643509 0.28679299260024 0.105894094044343 0.762039832270239 0.454981498545967 0.220697995917872 0.929974129404873 0.628283918511588 0.440800045090728 0.958490789902862 0.562089673515875 0.358816866443958 0.476958748959005 0.617591036101803 0.557581349066459 0.944777039750479 0.368274814833421 0.805405614683405 0.136929903060663 0.0191600321861915 0.783642816499341 0.40313772007823 0.0182824007607996 0.206883199533913 0.805179285129998 0.194000641270541 0.355236382361036 0.947812664483208 0.528581787094008 0.546143148874398 0.872414022055455 0.601241111163981 0.776134892988484 0.702378509871196 0.816356154219247 0.891110815068241 0.58130978428293 0.0748182458500378 0.212621335780714 0.630101666396949 0.659814648546744 0.616142609664239 0.403022512474563 0.778093643533066 0.105226109104697 0.633795276647434 0.399100315591786 0.165453574748244 0.888051471645013 0.331125818756409 0.760714151784778 0.159819014957175 0.0780219201557338 0.486212183458265 0.890974771436304 0.72970087045338 0.737970546332654 0.836006379120518 0.276136518726125 0.379404996596277 0.763699394238647 0.281818046134431 0.83343225187622 0.320515400862787 0.46852071440313 0.528217542921193 0.64439916809788 0.982643210887909 0.485557889665943 0.618106866679154 0.109826771407388 0.502310688663274 0.872676804631483 0.675004966245033 0.387887231127825 0.484794926929753 0.167646788121201 0.858055287639145 0.223448628252372 0.850591307093855 0.18041343298275 0.421191261052154 0.133016797420569 0.346398788138758 0.618587692710571 0.231786055914126 0.726267601989675 0.438320761951618 0.607721168741118 0.435770050287247 0.684377827232238 0.925980645294767 0.0223586059361696 0.161934368559159 0.214969427362084 0.35086542439647 0.664849647094961 0.116427327999845 0.903783265149686 0.858695532314014 0.790048545831814 0.1472201048024 0.589524169566575 0.208161384321284 0.283264067741111 0.310732204916421 0.0820360028767027 0.254340171387885 0.178563370744232 0.607972542834468 0.265693772381637 0.75119016332319 0.540206828101072 0.833694979592692 0.935882414409425 0.656954652764834 0.448890144897159 0.353236743237358 0.307275568586774 0.393408747501671 0.602376204479951 0.336775501575321 0.43779895514017 0.77651740009198 0.77735752717359 0.731785706467927 0.543749181104358 0.885979786480311 0.986022265432402 0.978246452105232 0.455018076731358 0.404804403416347 0.264041610921267 0.871116758820135 0.138219854300842 0.442209189550485 0.645055077481084 0.994081747382879 0.0591189227486029 0.57047593125375 0.103532050848007 0.880606181612238 0.876376029227395 0.922890737492125 0.513742818115279 0.240168136488646 0.251064346623607 0.217940765914973 0.775379404751584 0.424999948672485 0.101120720489416 0.272548381965607 0.696213603848591 0.534784672756214 0.171132813729346 0.929359726808034 0.517265883604996 0.30790984624764 0.694250700112898 0.162011850075796 0.0307509906566702 0.864855746231042 0.367181873479858 0.718774451373611 0.0501704294723459 0.765327043849975 0.623979153903201 0.908016146682203 0.846250579510815 0.0798007327388041 0.858731445730664 0.89592964207055 0.666245833404828 0.237452509391587 0.639396088130306 0.598263774940278 0.968371813115664 0.157745920962188 0.991024823542684 0.551871529570781 0.490618872742634 0.355041787447408 0.603676145921927 0.614522871815134 0.468771021731664 0.018339314784389 0.893604107217398 0.768131416882388 0.755788677805103 0.657149264735635 0.454996092340443 0.448110706775915 0.1579860384739 0.181753690666519 0.963842021522578 0.320599558649119 0.252635727848392 0.472137137949467 0.322006318562198 0.42557516817702 0.881109974205028 0.411310992734507 0.724172160793096 0.37804547514068 0.859019127399661 0.944721505974885 0.174914932728279 0.394373868163675 0.932855324486736 0.823567034439184 0.740975802382454 0.966204534713179 0.941712640027981 0.95462535767816 0.23240865356056 0.362265228431206 0.1912646898604 0.474657359456178 0.235381548234727 0.7101863985206 0.253090154677629 0.546083103937563 0.165242701298557 0.599215564499609 0.335922774083447 0.302679384944495 0.263798351893201 0.583584271396976 0.739994573756121 0.271011945356149 0.660488427623641 0.388724060642999 0.140756140437443 0.942514635799453 0.299337868858129 0.948825769277755 0.127213331970852 0.690249075121246 0.710075350331608 0.645359379751608 0.522547679161653 0.664902511883993 0.192358050267212 0.558965595355257 0.35749014869798 0.0916887884377502 0.262758150396403 0.712913100102451 0.382534287106246 0.392170596821234 0.0784065384301357 0.470732320249081 0.261443556151353 0.315805678684264 0.64403964253841 0.495999464597553 0.857700721567962 0.190031264247373 0.731036264076829 0.262635051084217 0.3742601858126 0.659983887050766 0.105258298986591 0.345768744344823 0.242222501938231 0.848221405842342 0.250068539415952 0.380553402344231 0.636191479368135 0.655757250979077 0.934818525800947 0.492753175480757 0.783808479681611 0.851567662439775 0.706695023644716 0.920124154626392 0.781556483602617 0.0912784129101783 0.131188114043325 0.592958998300601 0.654069567264523 0.307423535874113 0.0536298514227383 0.325623221322894 0.105365223719273 0.0869461390003562 0.179872562014498 0.182166033531539 0.178251431239769 0.932883271281607 0.29622168724658 0.991273425153922 0.776135031059384 0.102028972997796 0.48607458278304 0.824373878366314 0.969310890701599 0.925127472933382 0.208518461254425 0.883900342837442 0.162034689860884 0.252215781402774 0.639476644778624 0.604077503045555 0.579123766040429 0.383185145030729 0.444823544523679 0.941451339581981 0.627811813305598 0.0990681455819867 0.875642388002016 0.349291672224645 0.592627967209555 0.0203199623594992 0.876211962965317 0.271302867427003 0.251109469300136 0.966422463608906 0.119060649857856 0.670790783523116 0.564232104457915 0.439009817109909 0.0856594484462403 0.703323488086462 0.694694421491586 0.890651968356688 0.474166954900138 0.911769400103949 0.439222463353071 0.188435915850569 0.356380437838379 0.840444759940729 0.428391206471715 0.42340404199902 0.973350325222127 0.822089233014267 0.489396294108592 0.770290274112485 0.304416484672111 0.697937742660288 0.218369523773436 0.969119364235084 0.0916880782600492 0.913723716014065 0.526169768685941 0.25004159161821 0.0764213665551506 0.636986635674257 0.731796711571515 0.463781989037525 0.705785428229719 0.531851902315393 0.225867491196841 0.762880860154983 0.311636348029133 0.374524701305199 0.732776629331056 0.4945947881951 0.0552796018286608 0.472763236465398 0.719297287147492 0.753801594143733 0.232919781890232 0.655509089857806 0.281689518953208 0.142639528012369 0.102026184150018 0.0384254308999516 0.50497730497038 0.72788738709176 0.359362748994026 0.479147742756177 0.744591039302759 0.98934549115831 0.0673893957049586 0.889786667192821 0.723461593082175 0.275285553655121 0.324587922149803 0.205595254816581 0.991948194238357 0.872094108322635 0.963983978922479 0.699569367745426 0.978048666808754 0.650381419458427 0.895914541862439 0.445746993129142 0.636852147933096 0.946331131225452 0.252779986353125 0.954496908867732 0.339118532247376 0.206577753741294 0.0883854495314881 0.279405652468558 0.734473518847954 0.760683898814023 0.241853736231569 0.16664084687829 0.0748322898964398 0.42215369152138 0.144651911149267 0.926483732780907 0.501587748278398 0.96240633771522 0.331920738797635 0.402366311736405 0.916268470806535 0.716279320276808 0.604158558270428 0.239201069234405 0.139902707147412 0.851999576105736 0.909108388461173 0.304434114643373 0.0563628332712688 0.112411720505916 0.338974561870564 0.920232986765914 0.684319097772241 0.844263633228838 0.970972901987843 0.425942423862871 0.385442685382441 0.0732022548164241 0.352680549165234 0.692157220260706 0.875259648321662 0.599360199875664 0.253933664842043 0.0751253643981181 0.169614929561503 0.407319215494208 0.539844661906827 0.208961520169396 0.325930196959525 0.958580128229223 0.347605544400867 0.58303581989836 0.371146070424002 0.912223562777508 0.172301917895675 0.159866250879131 0.203483408077154 0.545651304831263 0.522498689347412 0.627787563998718 0.218031963934191 0.532464590435848 0.857879917081446 0.887565862690099 0.214792871561367 0.891137165634427 0.463375193441752 0.32441832452314 0.198837603274733 0.716960676426534 0.711820868235081 0.335368206205312 0.219521476260852 0.905977256007027 0.9853831910179 0.452289165093098 0.0909391035581939 0.872506065787747 0.910250950283371 0.834852515538223 0.750573906335048 0.853750876390841 0.905850681641605 0.277648863692302 0.321893616979942 0.883028070130385 0.0682681399956346 0.63502442989964 0.823846929969732 0.679961510787252 0.320691533230711 0.863346790110227 0.921955125278328 0.962153565394692 0.975782534251921 0.515564335635863 0.585482050615828 0.235380340171978 0.512804433419369 0.431304564927705 0.671903649498709 0.475647059734911 0.389738234046381 0.824281392069533 0.335602598499972 0.401271710305009 0.0753541149175726 0.888139139520936 0.658117618884426 0.978709554581437 0.439488612876739 0.607063204890583 0.703699586533476 0.421208810117096 0.244737004451454 0.482941280149389 0.704949921336956 0.793770129845943 0.44098071097862 0.647766088538338 0.61494018684607 0.793762800793629 0.961564837992191 0.517235571625642 0.340778985107318 0.138980371637736 0.964650889490731 0.76221863708226 0.606412335901987 0.19548718979815 0.414224916612729 0.955772593857255 0.0989419040619396 0.116870416649617 0.927106882019434 0.836079726808239 0.766580808758736 0.0840955145214684 0.686766203476582 0.910723514880519 0.283060411780607 0.62432163934689 0.279510435604025 0.986589112400543 0.746720814744476 0.655487469660584 0.0487921515805647 0.468321368375327 0.0777159308386035 0.891862401361577 0.689783709112089 0.603590688563418 0.709475066463929 0.74800367158372 0.189898002087139 0.0421361167635769 0.0251313296146691 0.718566739954986 0.952083238910418 0.390890904318076 0.588385898775887 0.501270260582678 0.387227173163556 0.0603615705296397 0.258573011890985 0.047771093302872 0.082811857839115 0.106961848177016 0.805287570287474 0.0771795989223756 0.568139513924252 0.704779306503478 0.277474280761089 0.0558033838146366 0.975485321772285 0.463635700268205 0.0806682084617205 0.0591156314057298 0.989501267634332 0.233225333944429 0.5722767445934 0.685997514831834 0.190440338589251 0.73067101560533 0.555465816825163 0.15342441105051 0.554771352699026 0.815657145739533 0.450164832042065 0.758226859841961 0.812715678676032 0.101369511804078 0.448132764005568 0.63706899369834 0.59705342491623 0.50406343189301 0.501341168633662 0.555497286617756 0.0815968675725162 0.661699246028438 0.296064000136685 0.783925657619256 0.143733174472582 0.37769959992962 0.579851522541139 0.446336661442183 0.236971894730814 0.959668108480982 0.905105168162845 0.356308966670185 0.959177324518096 0.823192465144675 0.874873986793682 0.327445043337066 0.959900551186875 0.848698523782659 0.74875324835768 0.311913717023563 0.886681520650163 0.577194047495723 0.773872884579469 0.802370169742499 0.0908866838691756 0.556638202883769 0.491216682167724 0.020382839939557 0.862028362841811 0.854268209843431 0.0496469049574807 0.567381761232391 0.0969269628101029 0.781373151724692 0.479698823594954 0.507591748686973 0.289574400684796 0.734532834705897 0.299005668198224 0.604595390856266 0.921817196598277 0.628821030447725 0.518263590612914 0.479988599838689 0.122076147357002 0.431054370775819 0.396178505306598 0.130300282428507 0.62026988862548 0.136825575628318 0.159933994133025 0.518012640413363 0.329187751417048 0.648737236375455 0.996391506656073 0.446393022490665 0.597462852618191 0.318811970381066 0.844699964011088 0.200323330522515 0.265678084162064 0.601803079780657 0.302669610262383 0.506858484563418 0.861154511193745 0.475816224247683 0.799398448786233 0.372980879631359 0.790528988768347 0.862576449916232 0.702396483982448 0.567613882848527 0.286543532367796 0.747218467216007 0.878074926419649 0.827005566193256 0.912436146785039 0.762182664196007 0.882793372420128 0.642909656693228 0.822518139316235 0.679900301583111 0.118847448334564 0.287076700178441 0.471700609396212 0.873473980368581 0.952042537499219 0.771706899295095 0.39405062828213 0.435462352256291 0.422294307167176 0.748731576988939 0.875868402228225 0.0507296809274703 0.450588917157147 0.949479444171302 0.257604068117216 0.919286171677522 0.145243798969313 0.972463534325361 0.0530057036480866 0.578891957446467 0.96309815913206 0.701662430157885 0.126696842156816 0.906997688931879 0.843577656890266 0.243117161723785 0.0337254543602467 0.244880800799001 0.188306611645967 0.663258773901034 0.750194616583176 0.792084090074059 0.536916110350285 0.0141462108097039 0.949518726149108 0.588841261444613 0.601025544686709 0.969874527694192 0.4766689658002 0.432860516556539 0.855269699625205 0.0322540961671621 0.298407426120248 0.981724119237624 0.279337007259019 0.0391646011848934 0.543018485698849 0.868558445419185 0.0196510282112285 0.567696868299972 0.994722753406968 0.548072792044841 0.152463089528028 0.572039753845893 0.416918091860134 0.121865726613905 0.374002425421495 0.057970348733943 0.0205370480776764 0.694487089249305 0.701457679080777 0.0395340627781115 0.653262676084414 0.522799597471021 0.521269995486364 0.933629068739247 0.705682839476503 0.984415050083771 0.44357670413563 0.324260657466948 0.383858636440709 0.243423874126747 0.365943841508124 0.242304569529369 0.515044619250111 0.137934627020732 0.058514637821354 0.175118654842954 0.657091561011039 0.718460837039165 0.858747451582458 0.211381856715307 0.454959347501863 0.557655181500595 0.954539092408959 0.352186043050606 0.12327594867209 0.0244467531167902 0.0854358955239877 0.893737813094631 0.233796960148029 0.0696944393613376 0.0898955814447254 0.296436437976081 0.720721461512148 0.667340794650372 0.138152522493619 0.28228593706619 0.731886065572035 0.929849677043967 0.981088529787958 0.823770561087877 0.484677588562481 0.924322375983465 0.824233376819175 0.754901862705592 0.287141554085538 0.551422538678162 0.0816194966784678 0.37395482668886 0.4792439809395 0.0577474916982465 0.196135037823115 0.879295604561921 0.333898618961684 0.471809703847393 0.945616026998032 0.283212235141546 0.0845132532157004 0.975929432238918 0.576481099387165 0.32444918256253 0.0246792652038857 0.380395038018469 0.749734444252681 0.0947018481441773 0.674917385959998 0.0593843289022334 0.385560288827401 0.0408919778629206 0.865048205310013 0.356541312334593 0.794835974727757 0.842661156547256 0.560394936660305 0.595787096938584 0.911239467854612 0.84823856005678 0.266583826038986 0.417567586132791 0.274492798261344 0.360825244372245 0.554684007065371 0.446310180872679 0.803332944582216 0.336416484273504 0.67117384867277 0.823656210952904 0.697080166321248 0.520429947236553 0.648636171242688 0.70392884300556 0.28536750621628 0.618766828062944 0.188736438574269 0.527943934341893 0.655468510151841 0.347558260303922 0.181987940510735 0.220308326645754 0.529346500725951 0.431967442396563 0.711113116340712 0.940817103411537 0.516102027054876 0.534773072034586 0.482367568821646 0.677456458869856 0.589323839063291 0.884330344256014 0.332646645056084 0.237681320072152 0.981025352324359 0.873711885979865 0.611530399424955 0.226296393119264 0.0165304486150853 0.720262377152685 0.642229911524337 0.255193960573524 0.752925584763289 0.971510628904216 0.62042276930064 0.0530543447122909 0.506782507766038 0.188891554891597 0.453306616931222 0.760247464766726 0.247989671337418 0.855141777512617 0.393834991501644 0.263337286827154 0.484092841474339 0.731579607182648 0.813145711903926 0.349812458602246 0.922256334207486 0.717002765692305 0.694178099252749 0.597498981093522 0.868822824454401 0.584535419007298 0.329922228674404 0.019503737448249 0.870294745073188 0.0850770490244031 0.540676583566237 0.897439944094513 0.66101461144397 0.326769593348727 0.233486314683687 0.904592652209103 0.88357725024689 0.290065747995395 0.0328855925868265 0.237475965309422 0.825873861261643 0.676100781501736 0.204304973497055 0.0480123421200551 0.0751184152136557 0.845169976947364 0.280722209902015 0.672169299293309 0.157188386749476 0.189371688493993 0.660440025820862 0.425632080587093 0.391582355087157 0.903025129593443 0.401983304212336 0.401388294699136 0.934012257899158 0.96115925553022 0.537270569698885 0.341042668947484 0.05091199652059 0.298846748131327 0.0354120565578342 0.395212227983866 0.747558303265832 0.877375577026978 0.287194481340703 0.476309175854549 0.0652753446716815 0.819988916693255 0.180750977608841 0.0107606851425953 0.11397987769451 0.837144425632432 0.316641030448955 0.668397943831515 0.74917339626234 0.751627004668117 0.753982744317036 0.765603652186692 0.811686538755894 0.526801923650783 0.344610341249499 0.490146899153478 0.497545027025044 0.420749968937598 0.559291630077641 0.443427217837889 0.553267062176019 0.248542256434448 0.422487283032387 0.33001436437713 0.771369303036481 0.196882683678996 0.8441322148568 0.589894096083008 0.567214542850852 0.376368613741361 0.489262252619956 0.330455040819943 0.0989666473353282 0.028447598319035 0.492723690543789 0.761535784511361 0.352352307843976 0.966245655408129 0.736803026408888 0.65920942524448 0.467185930458363 0.752530561382882 0.471562591281254 0.801481719920412 0.838048600784969 0.286057496753056 0.861475526036229 0.344667344016489 0.0995196630107239 0.489233185583726 0.380881750157569 0.632747688242234 0.981738663474098 0.999626886558253 0.903019888892304 0.121050408729352 0.431821684243623 0.608872182162013 0.179237967182416 0.595074470380787 0.855131967102643 0.656968085980043 0.0695195258897729 0.223591212849133 0.37028645045124 0.0994985236413777 0.375202467381023 0.236859336060006 0.571059370241128 0.995080548815895 0.113799652066082 0.175334899688605 0.149292207406834 0.637625785693526 0.679185833081137 0.265024202738423 0.520765961327124 0.145578507264145 0.073494216913823 0.26608764947392 0.581983346226625 0.896730164471082 0.231246518862899 0.130652506134938 0.577728623675648 0.408594483505003 0.761895701924805 0.293631500212941 0.589491581376642 0.725324219772592 0.429876561458223 0.833593424181454 0.0899068059865385 0.92747854168294 0.801918422041927 0.103509549901355 0.41713937479537 0.54851747116074 0.0564540506526828 0.743599533729721 0.284243853653315 0.268048106196802 0.216965290165972 0.385442298369017 0.0958682630397379 0.0545022889389657 0.829015940271784 0.566353688307572 0.73357835218776 0.256964286060538 0.181038283098023 0.883269268698059 0.678474033796229 0.874863142119721 0.603251193196047 0.725392623876687 0.645222829936538 0.0976542578451335 0.164355654313695 0.571871072235517 0.114815597801935 0.620793558817822 0.538415620485321 0.204599621868692 0.524124237238429 0.0277883083885536 0.878628981660586 0.814052642250899 0.892976743243635 0.014000715429429 0.168269594833255 0.711671679054853 0.0230968950106762 0.511289413012564 0.172378751470242 0.261819393669721 0.247289291368797 0.764669955677818 0.630180352518801 0.735745323561132 0.425620910443831 0.114987380821258 0.528862527876627 0.557541547305882 0.543328022446949 0.662281870881561 0.0598962178896181 0.120528476524632 0.64497892965097 0.579914729739539 0.927385149281472 0.0691627679718658 0.70223779856693 0.769058871848974 0.137533758792561 0.0216877348767594 0.108694869165774 0.0331681916792877 0.0481683142925613 0.775656744241714 0.0698973263660446 0.509753613511566 0.795929113391321 0.76093664946733 0.792346744260285 0.247130557317287 0.652201709784567 0.406406621704809 0.271240562875755 0.183580860334914 0.477351094132755 0.806017857473344 0.553690436882898 0.388952522343025 0.290881515590008 0.824875281341374 0.519676949577406 0.643802462317981 0.713498040582053 0.759725365678314 0.540080591882579 0.12468528859783 0.53221492966637 0.481555984383449 0.747452823782805 0.677729938828852 0.61718939638231 0.271413533904124 0.0272203049901873 0.148889536880888 0.639758586247917 0.323004239245784 0.190464017172344 0.65453619366046 0.115190014042892 0.616351078513544 0.769217473822646 0.743447951935232 0.607106241751462 0.77932650280185 0.982426440496929 0.35289481122978 0.852372641833499 0.817129745648708 0.15813369320007 0.396375006705057 0.860199260641821 0.456972629136872 0.347953133857809 0.869803579628933 0.576722211746965 0.354177222508006 0.941655163117684 0.590800239033997 0.807191772684455 0.297981006938498 0.912176936303731 0.725733084818348 0.352067442452535 0.781545128365979 0.743063279723283 0.284480885430239 0.648187704512384 0.557721075895242 0.066055959968362 0.448718510321341 0.278152271807194 0.849431990978774 0.15495441180421 0.370955143724568 0.883830888795201 0.142886267164722 0.651490574807394 0.215750489833299 0.176878738419618 0.100100581916049 0.674533259116579 0.890482007919345 0.369589699511416 0.359969701294322 0.808532829750329 0.851716602446977 0.621029673886951 0.259572496763431 0.390255671455525 0.0635697370953858 0.257418365753256 0.0459145265188999 0.841783882861491 0.0720201493962668 0.0798137019528076 0.943769373889081 0.181544947980437 0.621955815912224 0.756962518794462 0.429723503296264 0.532072900810745 0.0948466162895784 0.982701602661982 0.596531536737457 0.841059343712404 0.391865900391713 0.310688601941802 0.191185492484365 0.0953720869356766 0.241254960771184 0.856890312691685 0.911730003796984 0.291264368447009 0.264421860023867 0.713010903166141 0.939862513940316 0.362713689168449 0.89691329442896 0.800353075137827 0.0924732828582637 0.928455481582787 0.72170182506321 0.591678681366611 0.325669397856109 0.861117445495911 0.545176326413639 0.0517309699417092 0.479447692451067 0.976046848746482 0.923808995184954 0.230563647621311 0.0131034631840885 0.528079848201014 0.835135669219308 0.644442520516459 0.64151121284347 0.236860065369401 0.597917067154776 0.406990269527305 0.153592094355263 0.481390890541952 0.0972722684498876 0.536006983777042 0.693281388457399 0.0609171288763173 0.309553580312058 0.0380085881683044 0.596071081350092 0.420287840794772 0.210646493637469 0.362824167325161 0.643194054625928 0.394755884988699 0.840475274070632 0.343226032494567 0.785745035156142 0.872128060394898 0.430201545320451 0.47335816046223 0.725059694598895 0.672637454611249 0.224205318097956 0.551166676012799 0.92495072835125 0.654618518953212 0.333750565466471 0.020010852040723 0.323675190289505 0.404523440198973 0.188069489051122 0.765764314620756 0.198245867125224 0.48073775064433 0.212010571432766 0.557684947880916 0.418818681593984 0.711355017940514 0.401622522184625 0.593644976022188 0.402622048547491 0.826102877780795 0.847328245935496 0.777704805913381 0.412944115162827 0.221041255157907 0.465992987048812 0.265542221474461 0.499192771138623 0.768056020950899 0.581317863850854 0.786131705823354 0.504604270590935 0.616699815872125 0.519706162521616 0.585430649286136 0.273001926892903 0.495871315670665 0.473344995782245 0.612823586687446 0.0378691388643347 0.70326948807342 0.873564382463228 0.58588266736595 0.194103251229972 0.275119683020748 0.437316775368527 0.929641064822208 0.42239417276578 0.59512450390961 0.930215823091567 0.166106034433469 0.891587114955764 0.0669806791027076 0.589581991999876 0.791519642404746 0.732989538577385 0.728877740614116 0.432778357916977 0.627283731759526 0.425376649422105 0.136239822166972 0.532252794285305 0.739745690471027 0.133250995401759 0.38201175167691 0.283327544627246 0.0578768164175563 0.637190807498991 0.105726018655114 0.422022947368678 0.257883848396596 0.946807145290077 0.3749331071903 0.58429771024501 0.503951047020964 0.977023253880907 0.267776446514763 0.932541022102814 0.434466025265865 0.772234018493909 0.298531948323362 0.257638456069399 0.487902838347945 0.333361598304473 0.26322437341325 0.990333821561653 0.545265142652206 0.442047115059104 0.505329487186391 0.742280485718511 0.517531459177844 0.381169902973343 0.320814426934812 0.556440142136998 0.265621368600987 0.0695226789312437 0.818464619719889 0.609109051665291 0.267609392020386 0.667049324905965 0.107968942392617 0.744842282470781 0.475791075059678 0.357645748839714 0.699348152116872 0.413987251645885 0.126374575686641 0.0981758408388123 0.427304348074831 0.377894647088833 0.714171412822325 0.234037689412944 0.514717927135061 0.829894027630799 0.0678243992547505 0.209128869937267 0.551928125731647 0.922603081869893 0.988860115471762 0.69885546512669 0.144398751123808 0.231455920324661 0.364188031444792 0.60396451264387 0.604743784111924 0.0803150383126922 0.0457479288801551 0.807828960437328 0.392373578792904 0.629787768083625 0.80176660582656 0.286544744810089 0.63428263834212 0.683338164649904 0.846425168896094 0.506154570993967 0.720796727209818 0.39181756128557 0.0648585584131069 0.0201390966260806 0.803247610081453 0.196424450334162 0.371694514546543 0.619088603102136 0.72984645111952 0.0416882585594431 0.918093468220904 0.319331786804833 0.431762279872783 0.683958876326215 0.733731587375514 0.912844003844075 0.981805782758165 0.266421358771622 0.288579838650767 0.291950531492475 0.592352062365971 0.55097473395057 0.982571316056419 0.579639578638598 0.177040742377285 0.942865257284138 0.167357977682259 0.662476179972291 0.320833679642528 0.709160946176853 0.643207739088684 0.0784549632831477 0.575463324845769 0.0844039775896817 0.500828016723972 0.3220002731774 0.381593130619731 0.700357586853206 0.994883573043626 0.947397835650481 0.696345305969007 0.74439413060667 0.767838195089717 0.230245529732201 0.785987237561494 0.06009640409844 0.333361354202498 0.473660384984687 0.886883076042868 0.0993101124139503 0.166018215348013 0.830210725395009 0.867147844876163 0.962174557703547 0.488554654470645 0.177623767612968 0.929962734982837 0.797755220904946 0.776939165892545 0.65574466209393 0.430346991142724 0.644351274783257 0.464014382185414 0.427509953624103 0.0614031068654731 0.748219770521391 0.425028484170325 0.969488391561899 0.748016814596485 0.159755368882325 0.193361448377837 0.750602679941803 0.113499458038714 0.810298859134782 0.777915338219609 0.196068583077285 0.122108809307683 0.27821833469905 0.988338765285444 0.383132963220123 0.695463888542727 0.416359752963763 0.539889158308506 0.418214805116877 0.776493646826129 0.281855119899847 0.753643018908333 0.545854228024837 0.86045557370875 0.976862557562999 0.780080051361583 0.332047411587555 0.0229454116406851 0.134269427335821 0.142441909369081 0.0575031287944876 0.9833295933716 0.674715596376918 0.930721864004154 0.729200033822563 0.92242923170561 0.0215277141612023 0.912607021164149 0.301590052335523 0.907133731411304 0.220746135178488 0.478515431971755 0.617170919314958 0.123994088845793 0.392588897019159 0.0503342896653339 0.896220378126018 0.954047386667226 0.766040546086151 0.2597193624801 0.697567534239497 0.0393677424336784 0.969702314096503 0.108092565175612 0.57796925497707 0.514480077305343 0.080001995624043 0.641882443542127 0.946682955010328 0.697097842853982 0.0244607584387995 0.27186687276233 0.525650715916418 0.140276182938833 0.250574059162755 0.662838935791515 0.393632033502217 0.393293328757863 0.18189325453015 0.306130631668493 0.651099369698204 0.156261094287038 0.0595656346646138 0.296421614370774 0.355303807982709 0.365554982912727 0.584261378466617 0.521090187989175 0.67266672679456 0.980936789868865 0.15378934212029 0.430932500271592 0.469073324624915 0.0588211849541403 0.697140737725422 0.130294877379201 0.119511015466414 0.667479201392271 0.59061480820179 0.51183606751496 0.732180952974595 0.445142869553529 0.177311581471004 0.837538340066094 0.621066195829772 0.212093069141265 0.940044131341856 0.529014813855756 0.959682443190832 0.354951684775297 0.78060988887446 0.187641515822615 0.399822584062349 0.144926030291244 0.653787583152298 0.281978506417945 0.379115807902999 0.905304445270449 0.963987230157945 0.888856539782137 0.60529442791827 0.214640089080203 0.693516682016198 0.667472316748463 0.659080708820838 0.0126850371318869 0.486437215283513 0.213008159270976 0.644767910754308 0.667645976287313 0.799164792485535 0.860067809307948 0.360387753932737 0.971845520217903 0.749905279215891 0.139960468036588 0.0179220380168408 0.566426131043117 0.669066406602506 0.90074954113923 0.177067780992948 0.527810316747054 0.424976943617221 0.177531177590135 0.70380540301092 0.262710147132166 0.848213165153284 0.289719280623831 0.643360771895386 0.854405003990978 0.272175924994517 0.733285862240009 0.352327589234337 0.446908465363085 0.788076666104607 0.334732726013754 0.621604829311836 0.822794986914378 0.176627923524939 0.474689324598294 0.61962088808883 0.599123228029348 0.122124375361018 0.591699718853924 0.998526736705098 0.162304902679753 0.126247448346112 0.66400382153457 0.202474593392108 0.758913936598692 0.156591053772718 0.27780707081547 0.82262592243962 0.539902234014589 0.358546810366679 0.0707943356619216 0.337669372351375 0.504993073865771 0.616782703590579 0.476066357316449 0.0443487116950564 0.401343489654828 0.135325053357519 0.320241930354387 0.628431077888235 0.561401317471173 0.863732604922261 0.676304623938631 0.773114563007839 0.975815139038023 0.935742267835885 0.481036707565654 0.376641365773976 0.725362189039588 0.643553948989138 0.749522693511099 0.655666025760584 0.644286560099572 0.418319531548768 0.281053356705233 0.0973991899518296 0.7437000970589 0.438194553393405 0.158750649993308 0.14383259474067 0.739450837413315 0.829665178917348 0.642063034977764 0.836467848487664 0.440964927331079 0.31746068592649 0.371039217377547 0.310053367696237 0.295763484328054 0.585837738080882 0.532052173118573 0.634033553597983 0.510077370179351 0.0583327975240536 0.738933539227583 0.207308400741313 0.836762254601344 0.358199145996477 0.227697950133588 0.585074425903149 0.68111523952568 0.600932042105123 0.339897780204192 0.40880932850996 0.448033410583157 0.599130842674058 0.129164655038621 0.386705460166559 0.729901195655111 0.976501109614037 0.61846028116066 0.453358886793721 0.754045717786066 0.140465548676439 0.906403645453975 0.585614791379776 0.133420795409475 0.0712429787265137 0.597649729622062 0.140976491912734 0.0464127909741364 0.611513316896744 0.4960861288663 0.909073613034561 0.0164896690635942 0.609562504622154 0.273328391041141 0.629413509736769 0.141500779620837 0.480641337970737 0.310428573868703 0.652274900730699 0.800434540656861 0.853981034588069 0.241881926436909 0.850115710699465 0.817725509135053 0.401580446057487 0.316316900828388 0.983256114758551 0.364802887900732 0.593504373515025 0.195184287598822 0.559138435919303 0.779160266129766 0.708599904179573 0.138439495598432 0.599937768199015 0.460650262578856 0.6959807075141 0.993719970507082 0.579844511812553 0.241958218330983 0.0331904383818619 0.114173741454724 0.401808003957849 0.0656668872362934 0.322859581972007 0.118332061243709 0.837335397971328 0.0815306396409869 0.504896983203944 0.224836296117865 0.709301408308093 0.965818610643037 0.193780613881536 0.737314612746704 0.0675391973298974 0.464825376076624 0.273425663949456 0.589671646114439 0.429043568884954 0.375473014658783 0.664939584266394 0.577018176978454 0.0143536435510032 0.0263496538670734 0.797888209228404 0.9006429962744 0.331083854422905 0.404588484039996 0.764657562028151 0.147587673971429 0.411064470023848 0.314057565785479 0.562109066369012 0.539621679247357 0.766466804838274 0.771424089292996 0.0553270242270082 0.717687920981552 0.243959876885638 0.3702718898491 0.0333992499881424 0.227603310944978 0.393630968811922 0.578536952729337 0.95085189311998 0.892167918379419 0.840806317378301 0.426849203691818 0.942581582667772 0.587663093695883 0.696208296762779 0.849628222228494 0.440266724226531 0.536216309403535 0.288953819242306 0.157989995968528 0.0158372925897129 0.773328554462641 0.576696637973655 0.416589073284995 0.479598799641244 0.423191109241452 0.761802175140474 0.72958465762902 0.875480673785787 0.551263869397808 0.463701346642338 0.937689403598197 0.224156218334101 0.0565653263474815 0.125208650378045 0.895129518439062 0.739908440564759 0.604173738693353 0.938352288673632 0.254877164615318 0.501659973189235 0.174560483521782 0.646047491002828 0.965965266141575 0.309104018004145 0.940027273553424 0.467910595461726 0.616905980159063 0.997355387676507 0.231218728579115 0.761755923002493 0.399568481973838 0.574563112950418 0.116014653672464 0.751635573592503 0.552981494904961 0.941591816234868 0.346714456249028 0.260638703533914 0.55510547044687 0.304824778302573 0.678475681426935 0.10299613614101 0.53148238102207 0.472538553390186 0.705467350448016 0.389524485080037 0.33685787988361 0.378738872040994 0.0720216822368093 0.26701896189712 0.696615953976288 0.832185073341243 0.399116686559282 0.0827350742835551 0.0292449441668578 0.0167974777356721 0.880618544605095 0.711900247938465 0.380410829042085 0.430314407101832 0.523982461243868 0.27678124344442 0.0139976165560074 0.468524679734837 0.314863587510772 0.780615088085178 0.620197005860973 0.551604963298887 0.205683430489153 0.745911606324371 0.37656149279559 0.178922478633467 0.0578224346926436 0.419156081003603 0.273979841356631 0.30248545503011 0.0802323783305474 0.587589674782939 0.035948697347194 0.0964843826484866 0.135087287200149 0.120473377937451 0.927904206200037 0.683103654568549 0.770642756442539 0.662569245290943 0.163024506312795 0.0837222330435179 0.319028179498855 0.372274356314447 0.0680856971652247 0.979612491244916 0.459190439183731 0.671583871070761 0.936944073368795 0.652385974044446 0.655414875254501 0.397121770658996 0.314403593589086 0.689499087592121 0.57063174207462 0.338363191762473 0.940460964392405 0.668336081844755 0.147424008783419 0.72086306393845 0.25336581956828 0.116260060982313 0.780826613625977 0.770561245053541 0.162996411304921 0.0664505719020963 0.274163969850633 0.796534425206482 0.977687640679069 0.18638920123456 0.301208143385593 0.674363259954844 0.905634879360441 0.0522855209931731 0.931971738494467 0.285967105261516 0.389757957209367 0.593953300558496 0.0727703208662569 0.996974438768812 0.0669906944292597 0.616674447245896 0.496183245955035 0.0479060063208453 0.70680827336153 0.836874727755785 0.388427192303352 0.63474633297883 0.964590603909455 0.099336466207169 0.338106056493707 0.0795620113797486 0.332699178382754 0.495926487788092 0.247143507860601 0.760180044216104 0.297437927527353 0.714475786548574 0.43429183464963 0.160942009205464 0.674904785549734 0.286331737369765 0.150300996736623 0.924963923918549 0.420181380063295 0.216724841883406 0.617901730893645 0.836405027150177 0.989519079241436 0.131284103284124 0.226108394721523 0.37936861502938 0.413300150455907 0.458344917655923 0.246673081403133 0.296723911501467 0.793649782270659 0.847654025491793 0.700257319719531 0.221038303575478 0.193207548421342 0.155095378505066 0.706689968497958 0.429499912341125 0.322224588601384 0.936319288716186 0.421091136138421 0.625370446187444 0.720990160852671 0.356202592607588 0.268746958626434 0.99428258337779 0.868072757401969 0.120565946293063 0.342692458999809 0.563002492275555 0.286614714255556 0.227352626514621 0.609071653352585 0.620292662256397 0.677956825506408 0.335943290635478 0.702570897724945 0.499539448728319 0.171727240532637 0.429721835611854 0.771277566794306 0.46556634174427 0.770231862976216 0.454192281363066 0.932526435684413 0.201688141545746 0.0112276920978911 0.131977227269672 0.0642342018033378 0.711101539130323 0.601986174241174 0.0182198191457428 0.347437004779931 0.778000865881331 0.742247704828624 0.180411790192593 0.606011089188978 0.527763393155765 0.821584337237291 0.315719280415215 0.170230269150343 0.277365371633787 0.527075965343974 0.500471548778005 0.123197139231488 0.0213385717803612 0.46210365657229 0.634495479820762 0.915619335195515 0.396148479611147 0.92635309765581 0.762052485235035 0.283712237584405 0.746591171240434 0.322913358397782 0.19211140101077 0.502249604621902 0.406915213125758 0.677936616444495 0.0896965228533372 0.253046104528476 0.969820175473578 0.894912748509087 0.908336308666039 0.438253854268696 0.970443463705014 0.306990711032413 0.93357312144246 0.780743582996074 0.919082082603127 0.344231649651192 0.0137394387251697 0.0290580424992368 0.761210600803606 0.118346764296293 0.332504846702796 0.52894581298111 0.010424029333517 0.749250516581815 0.0504131553485058 0.24869924304774 0.887100806476083 0.480313487350941 0.876633454929106 0.990779538629577 0.547125693669077 0.560973510434851 0.097857666707132 0.769243607947137 0.473361323415302 0.706010000202805 0.275151423423085 0.832112732718233 0.419148464514874 0.421758588387165 0.562462503439747 0.685284952353686 0.633711565344129 0.243732586367987 0.349587404879276 0.520010622225236 0.176406507820357 0.110077070207335 0.319923363446724 0.496943230601028 0.986926811232697 0.309718426594045 0.552770202171523 0.702339699501172 0.890504873751197 0.260919091417454 0.265466517591849 0.970053451906424 0.104422379725147 0.0915929619316012 0.20791623794008 0.0925627186871134 0.140213631519582 0.842958522310946 0.0663281309045851 0.157296747742221 0.570232048025355 0.893781383568421 0.345383936366998 0.297860524749849 0.47351228285348 0.619100934977178 0.949798056257423 0.773103589944076 0.614184986967593 0.975036943093874 0.101584971097764 0.298405177339446 0.392649761852808 0.962861539262813 0.922752584994305 0.990556538912933 0.987164563790429 0.666697910954244 0.36086043239804 0.0101829600776546 0.354702314669266 0.600426900843158 0.970568268734496 0.654726396352053 0.833868548083119 0.107570851026103 0.471696227085777 0.407416358629707 0.475060073777568 0.959073792549316 0.950324380914681 0.46803058299236 0.893528829533607 0.216082629871089 0.588319213066716 0.579083176192362 0.531315800671 0.619505457128398 0.641742725702934 0.645780507752206 0.301897296046372 0.809563940004446 0.417843928239308 0.160199369399343 0.962058052371722 0.58742980274139 0.825863912550267 0.394862049524672 0.71819269459229 0.460831022050697 0.523675798398908 0.674318758021109 0.764781652269885 0.972078460808843 0.718300062119961 0.0776566048385575 0.378195269620046 0.362616457750555 0.472218464475591 0.0266207829327323 0.0125507105118595 0.587388328225352 0.679014415869024 0.310292926931288 0.346143768189941 0.404915794131812 0.767464036089368 0.0618392002303153 0.0655559141910635 0.711312542122323 0.683937732577324 0.496979980971664 0.265572814897168 0.313428205661476 0.298616264695302 0.464351307451725 0.401516692338046 0.172697764169425 0.67968778073322 0.450765037077945 0.78253502180567 0.494081175972242 0.192108266178984 0.0804632169706747 0.032638482786715 0.768359407666139 0.212158950166777 0.435981130267028 0.834211240056902 0.328202544550877 0.312888906488661 0.207113363954704 0.141891128183343 0.876031436761841 0.752874662878458 0.119433168603573 0.708404469776433 0.734889262544457 0.478818835052662 0.715549334587995 0.824015259603038 0.598893351044972 0.177975634732284 0.176234715350438 0.100302989706397 0.815993786565959 0.289735605260357 0.542629600595683 0.884299878531601 0.762898094814736 0.462350300988182 0.411623007843737 0.25388347457163 0.757270296348725 0.495927182752639 0.500942555640359 0.908839542521164 0.257303550464567 0.646773895376828 0.144591642394662 0.914296813053079 0.0678828989039175 0.0476561606884934 0.397173046134412 0.290221140685026 0.942366347191855 0.708282592587639 0.41445443700999 0.610896630021743 0.528307327269577 0.933002432461362 0.290185257464182 0.31971397258807 0.240893065647688 0.031528818027582 0.912010672893375 0.436636831506621 0.889427992417477 0.703102518403903 0.160466474816203 0.319211560934782 0.452826303306501 0.765590793383308 0.605100575913675 0.168847845674027 0.620876216955949 0.144819189922418 0.168480499400757 0.826384595432319 0.926966350045986 0.387112580309622 0.917154449413065 0.283285016485024 0.109303107669111 0.869581685401499 0.976267365261447 0.157795416268054 0.845733578673098 0.133434872878715 0.19763698482886 0.355307433323469 0.412509170160629 0.290906190865207 0.261912991679274 0.0773201670846902 0.523249633922242 0.144958694085944 0.987106537823565 0.108691574595869 0.685492791009601 0.506280610363465 0.835454339853022 0.0478033456509002 0.953018155698664 0.600217260811478 0.0406412063026801 0.526473872954957 0.324980508659501 0.737087876817677 0.615165959275328 0.72079678760143 0.163653160408139 0.065486233565025 0.596937653964851 0.868656219439581 0.622345813189167 0.888862913863268 0.597276893935632 0.0200730348867364 0.690126872002147 0.864552474305965 0.444342971122824 0.717401474574581 0.0115655594272539 0.812112623939756 0.710321385068819 0.539815713348798 0.936396130819339 0.783117977660149 0.653077265536413 0.91597367860144 0.182656256682239 0.426393902797718 0.885910229173023 0.389131840253249 0.308936172656249 0.310935863642953 0.179799671873916 0.611207958464511 0.271548032478895 0.344128254139796 0.0212043145415373 0.806684991398361 0.580051219393499 0.629137154261116 0.897355189537629 0.0558362356992438 0.957089834499639 0.503988555974793 0.839039780888706 0.384385911459103 0.381497370267753 0.64039914094843 0.362997938657645 0.72223994521657 0.489984824431594 0.893510636445135 0.955738999755122 0.227124451329 0.137316210917197 0.811002336132806 0.315056103523821 0.570163662822451 0.866416693767533 0.641431262646802 0.747641721831169 0.316497693031561 0.376169751537964 0.367401661837939 0.0980816681869328 0.21528928946238 0.751860402114689 0.112149746762589 0.937888337026816 0.845283788398374 0.133915251505096 0.510932853096165 0.101112655673642 0.381498605529778 0.138662453594152 0.96990230944939 0.312516500689089 0.636654658601619 0.696478093294427 0.904416741123423 0.271653327099048 0.180004641236737 0.620479300229344 0.2805269061937 0.411642251100857 0.225128897628747 0.347621290246025 0.582574197708163 0.524944019953255 0.873162647315767 0.91547753315419 0.792682644713204 0.0297041186527349 0.233746111101937 0.944780747841578 0.442484577146824 0.028623458694201 0.23652941045817 0.535092852306552 0.721617587523069 0.866997526003979 0.783592603870202 0.444290383397602 0.69168254541466 0.414339105165564 0.110838272827677 0.594596644798294 0.586632535033859 0.551417828132398 0.149978737642523 0.992931245216168 0.406980454968289 0.826583341232035 0.937906118668616 0.232930270668585 0.995886650294997 0.0610533589846455 0.0838149929465726 0.605695806478616 0.396058906863909 0.458260621568188 0.0597319676866755 0.414805137556978 0.527703907417599 0.539398362820502 0.18136494732229 0.409128516621422 0.171168285273016 0.666141272473615 0.271496767606586 0.121534001710825 0.888821027209051 0.418178514828905 0.996391074925195 0.614166388195008 0.720191356847063 0.65863952296786 0.277178426170722 0.0986608567112125 0.216703897288535 0.787216501915827 0.23822086519096 0.738822209825739 0.601671374202706 0.312306351247244 0.992513033992145 0.539299968979321 0.53854137103539 0.538353917084169 0.488030035530683 0.76112013278529 0.732208644833881 0.0199771814118139 0.178298520331737 0.84444289074745 0.788582608131692 0.466813895076048 0.445006222005468 0.2024128844589 0.456949220702518 0.259290505505633 0.874284304881003 0.216627293294296 0.0408408296247944 0.401686813205015 0.362807173309848 0.715657834573649 0.134507603556849 0.576322652772069 0.24355432047043 0.682399825823959 0.323911809236743 0.897298118772451 0.881527830916457 0.845437543599401 0.0865135183837265 0.731659681389574 0.891975213354453 0.798171717422083 0.704185059492011 0.876859489900526 0.707360026575625 0.0125710099306889 0.854242182902526 0.182718094466254 0.345263907576445 0.751739433796611 0.107363343371544 0.873507178006694 0.91905002963962 0.0902581632346846 0.477726108066272 0.98978444528766 0.622884516282938 0.815698595361318 0.933191770308185 0.423884348478168 0.406614048222546 0.640112821317743 0.618699027413968 0.49066919347737 0.683430498354137 0.128182210742962 0.344850433636457 0.462609164102469 0.384017613211181 0.947805967007298 0.994944694887381 0.197614364481997 0.793063417286612 0.0576418261998333 0.529332078425214 0.118991543182638 0.0931442212243564 0.883941987694707 0.743098929675762 0.474402362327091 0.963725011851639 0.735463969181292 0.772219842369668 0.264302119591739 0.87232653258834 0.335605758687016 0.837234391386155 0.976829329037573 0.138263410713989 0.301212486510631 0.310879848347977 0.0589111931202933 0.554504389963113 0.612530865776353 0.704147040667012 0.518220994242001 0.295992564696353 0.784458548827097 0.0124238434084691 0.160279370537028 0.589736269749701 0.958115375356283 0.827472073649988 0.069572052070871 0.158522081801202 0.954587695440277 0.33541095493827 0.543321282558609 0.291053449127357 0.153563690704759 0.456459070390556 0.721028561850544 0.358460462347139 0.0639533169567585 0.715003325031139 0.549547613766044 0.256079404645134 0.628556513802614 0.696336789138149 0.49398633739911 0.100175166018307 0.365618522495497 0.712322594604921 0.811454430047888 0.492964098257944 0.679262141801882 0.809228557490278 0.523026314037852 0.0472372952988371 0.291295356489718 0.581807499681599 0.14327568795532 0.0327142115635797 0.0242850937601179 0.651504760151729 0.375933404352982 0.439041962043848 0.744935005954467 0.864886704077944 0.299795602243394 0.906551044783555 0.956430777376518 0.261026786488947 0.142520207094494 0.24162931177998 0.580333193133119 0.634158579679206 0.491064054353628 0.126320280400105 0.644568881436717 0.164366135024466 0.0382699241116643 0.684989968140144 0.171801131744869 0.742004141076468 0.401061333357356 0.554846156931017 0.103505818068515 0.172187233532313 0.0835435697599314 0.258386532734148 0.975454381904565 0.994665616718121 0.0359852135274559 0.56194160111947 0.533225708692335 0.325153527401853 0.259013467973564 0.391077108485624 0.390062822136097 0.241923153623939 0.715068034643773 0.499885795316659 0.575866682729684 0.503968016142026 0.655726250489242 0.720316402981989 0.286320816860534 0.92102774015395 0.967978654499166 0.872471630352084 0.196261262746993 0.61538264899049 0.129404263140168 0.835992925851606 0.242154304133728 0.0810635845107026 0.76456631537294 0.782275297534652 0.997754263672978 0.192735406104475 0.623967016111128 0.435188719474245 0.516624210507143 0.381264602553565 0.241609382317401 0.846536788269877 0.472282113546971 0.87887990051182 0.278563320171088 0.470156140241306 0.583954737058375 0.33759652831126 0.136683499980718 0.597804057390895 0.0160710996389389 0.264802911735605 0.870099201872945 0.115984260095283 0.905563550412189 0.277915239799768 0.262783312031534 0.284828981070314 0.755687211367767 0.284116521857213 0.0730571644287556 0.537167583329137 0.514298643844668 0.919456066191196 0.0393252573953941 0.734117992965039 0.824523407767992 0.366044659081381 0.0386885622260161 0.840072811457794 0.802729387350846 0.150305823455565 0.436534456659574 0.340754209333099 0.535431604073383 0.680960201348644 0.695596325735096 0.70782493572915 0.948899876470678 0.1032667456544 0.158849726582412 0.0222113702632487 0.24068262116285 0.609545426703989 0.945462964226026 0.679941408447921 0.612071115265135 0.99819215587806 0.664987146810163 0.804604033585638 0.286997159353923 0.978461091732606 0.0853848842042498 0.953494558159728 0.142478467270266 0.917428315002471 0.902004067858215 0.0831711985357106 0.873492679640185 0.133108434085734 0.0389493064698763 0.986811465788633 0.842077437038533 0.521771883899346 0.543397627698723 0.268818156418856 0.903168526710942 0.772045197663829 0.946152427373454 0.0858628921140917 0.670776312816888 0.444036022685468 0.858827231437899 0.526610594033264 0.235204843990505 0.745479703722522 0.9994202177017 0.594876689694356 0.801916886204854 0.300633380045183 0.959295138181187 0.928717236809898 0.904531978922896 0.0689755834778771 0.184888477504719 0.755987941313069 0.272932111422997 0.9979787900066 0.0708112026704475 0.139194713225588 0.489321988453157 0.621374228089116 0.759251387179829 0.762881277825218 0.905196884351317 0.248641053193714 0.74638946901774 0.391187972733751 0.449446335050743 0.0622390496381559 0.412778501077555 0.698273321562447 0.905401585870422 0.81330856180517 0.522692411579192 0.873879555223975 0.11117996764835 0.834671405011322 0.806454149992205 0.921630050137173 0.532796198704746 0.920349393212236 0.57322314431658 0.518115157019347 0.77935221464606 0.525441721521784 0.862613890641369 0.442045517216902 0.886443043623585 0.343247663064394 0.480572790955193 0.282011992644984 0.873992647968698 0.348794097893406 0.320067030943465 0.119023490115069 0.394655599414837 0.515508019304834 0.314609878889751 0.187782088594977 0.32433243912179 0.274010863513686 0.168878994376864 0.824180297432467 0.46457447105553 0.617503608639818 0.610948617749382 0.411611094791442 0.497383544233162 0.872506985261571 0.777852571511175 0.319119324272033 0.975013464356307 0.552995470492169 0.729504947385285 0.508150712475181 0.758353897517081 0.0262762017617933 0.245918357742485 0.446590300682001 0.920985819846392 0.327141909482889 0.298972515277565 0.532342950664461 0.689521031184122 0.347194813669194 0.305999853631947 0.184964230945334 0.806326948199421 0.472596751542296 0.635368510650005 0.799243435272947 0.336007583499886 0.0767783448332921 0.668322901721112 0.569652596497908 0.687570285294205 0.134961105149705 0.717912196067628 0.264853508842643 0.635934460042045 0.549248713548295 0.0788628795812838 0.20637559489347 0.42122952420963 0.605082791505847 0.922143622483127 0.100315756769851 0.968151540933177 0.250633268528618 0.173875009447802 0.262965707839467 0.867336876615882 0.993321930542588 0.315453143569175 0.974656407937873 0.204653362797108 0.71818163117161 0.967480118512176 0.24058010202134 0.985351694717538 0.191242922833189 0.73993626012234 0.265435604923405 0.128844703503419 0.635462168820668 0.109906916839536 0.390047451548744 0.335072902976535 0.146699388497509 0.743026613485999 0.794725186084397 0.877589306631126 0.101839973989408 0.782052546299528 0.905778330876492 0.0556276940112002 0.955242645933759 0.697320870230906 0.714049989031628 0.983371481639333 0.528469510327559 0.0841199311730452 0.916676585797686 0.987121468381956 0.0955633082170971 0.196806760819163 0.808198949189391 0.760220648816321 0.568611681596376 0.251134714607615 0.905686203241348 0.572440186655149 0.483613214516081 0.216305396780372 0.555953823465388 0.998237607020419 0.389675299993251 0.986171450694092 0.679494003641885 0.668818194079213 0.761475743493065 0.884485168065876 0.652855286023114 0.0244649249990471 0.494567005748395 0.872025748013984 0.450418764019851 0.740965865426697 0.188365356319118 0.445570242092945 0.838819651387166 0.635622756341472 0.0777023609355092 0.911053772866726 0.63899835058488 0.489314182261005 0.510338732860982 0.0525630607898347 0.532075360270683 0.81435630902648 0.253571623810567 0.420782456167508 0.37375326392008 0.868481116725598 0.777537008509971 0.375220088823698 0.710537771673407 0.55340110112913 0.494661930990405 0.173766914454754 0.99338679274777 0.819083768129349 0.841753623897675 0.0891439174721017 0.206775159861427 0.565158278523013 0.21227964971913 0.479829133250751 0.77009188743541 0.633530368609354 0.179544334753882 0.114118379403371 0.18279517352581 0.3779744195682 0.458749434505589 0.491568378254306 0.73500000508735 0.280591232250445 0.0391263290378265 0.94851565903984 0.929352711699903 0.391312093632296 0.759498732092325 0.971369903308805 0.90501502469182 0.927869569766335 0.610179211089853 0.466555302571505 0.0331932371412404 0.114367499414366 0.89592768925475 0.992922833263874 0.455686044613831 0.0555023210239597 0.368378315453883 0.69832383246161 0.674444848792627 0.615428791178856 0.997610948383808 0.173669336361345 0.830786012206227 0.462842791129369 0.756234935401008 0.482990826396272 0.951774401967414 0.401729608268943 0.476447534651961 0.432335975756869 0.105104807480238 0.757809635398444 0.213223752717022 0.830576928376686 0.34931130157318 0.457967180337291 0.893500730837695 0.282300138776191 0.566225345297717 0.72723077490693 0.754653267778922 0.829491597518791 0.30021694899071 0.128636777948122 0.12855655714171 0.6743507897784 0.84839429988293 0.298373329984024 0.882585195617285 0.808030936035793 0.499580669922289 0.749198777105194 0.886373333954252 0.281218973326031 0.37088014540961 0.752740725346375 0.623970820321701 0.855878470358439 0.178211297325324 0.931809510258026 0.407472344189882 0.0537243898818269 0.311652279659174 0.653417974268086 0.67912696946878 0.121988278252538 0.200842190822586 0.104964557180647 0.883836016550195 0.380795456306078 0.243444638468791 0.0539642022084445 0.14753524921136 0.802985968952999 0.861840908660088 0.886487807177473 0.81293014611816 0.410626022999641 0.998363179392181 0.853491674899124 0.512105804115999 0.548866885504685 0.211723987646401 0.42534807197284 0.868652736549266 0.586532483880874 0.741938140189741 0.926559853642248 0.922015856420621 0.871931142478716 0.678712827533018 0.0126284914510325 0.611228856036905 0.170845362562686 0.278626976157539 0.991953808353283 0.488946016090922 0.802140980116092 0.867778740606736 0.294623936554417 0.141862214431167 0.919604277580511 0.985006596299354 0.077921575573273 0.114436728025321 0.648788529599551 0.935986234506127 0.0556161656673066 0.274188504519407 0.176492138747126 0.720056899301708 0.533428168115206 0.0654604341299273 0.874922541650012 0.10889750353992 0.652235574957449 0.54749953065766 0.288562137454282 0.857197697469965 0.665348231487442 0.194592402775306 0.519520865380764 0.0948975849663839 0.302459001429379 0.521800699227024 0.0970299920532852 0.295502862711437 0.914042345157359 0.342005860535428 0.400867851309013 0.411678714957088 0.67788420505356 0.703974183045793 0.0281068610050716 0.406718627824448 0.904444376740139 0.423464379443321 0.0688395253242925 0.979696064477321 0.968862419130746 0.599053263885435 0.397462580581196 0.845703675374389 0.491178827229887 0.635688614547253 0.270256032072939 0.317062741159461 0.0448856809502468 0.855038300864398 0.566180556388572 0.340764648783952 0.255065675650258 0.739704779302701 0.111690158755518 0.303554317879025 0.611755434246734 0.633321797647514 0.451913072408643 0.78637915630592 0.748365800206084 0.553766750905197 0.622794413149823 0.131318842521869 0.469056542441249 0.486377208840568 0.540669182136189 0.957131175093819 0.701724251115229 0.498940943186171 0.235689450721256 0.981073261082638 0.510493807226885 0.355520891856868 0.191423479232471 0.682729716158938 0.203335360575002 0.347252083588392 0.700062899526674 0.323032180969603 0.759102236954495 0.789863484033849 0.506246617953293 0.300400161237922 0.446603127906565 0.965918760451023 0.978594647552818 0.325474367062561 0.350660593335051 0.852844026489183 0.583885693540797 0.645299961320125 0.681408597545233 0.124548934709746 0.44790855968371 0.786072391578928 0.772276027083863 0.392945727084298 0.572923616671469 0.897387878687587 0.160200939811766 0.307371369968168 0.245009849607013 0.539016507577617 0.0801064189453609 0.018450333699584 0.826477820950095 0.573252490952145 0.188786981282756 0.45783469957998 0.788001368597615 0.7694300008961 0.94913679368794 0.260427495164331 0.0522998545505106 0.892436339964624 0.0492333040107042 0.0250650684908032 0.769440122023225 0.621575797542464 0.817078003636561 0.416414350669365 0.61387952596182 0.649425574440975 0.684454518586863 0.47159056619741 0.233752768239938 0.90693980748998 0.925285606295802 0.900867623568047 0.78423913273029 0.367221604476217 0.386701462334022 0.0347299109376036 0.812947950118687 0.562890183930285 0.570446310089901 0.897902730091009 0.651189475597348 0.79584515683353 0.108633195960429 0.255732148494571 0.90829170369776 0.273037987831049 0.022958723611664 0.283988293868024 0.793958118332084 0.963706039665267 0.628417793116532 0.450635822077747 0.320211097900756 0.330500581397209 0.303863797001541 0.751961329637561 0.24811700405553 0.0555264329514466 0.941756222487893 0.97224245100515 0.0282976387999952 0.526891291942447 0.288366640124004 0.0785349561227486 0.0861351494886912 0.555991870872676 0.471917905563023 0.287408063192852 0.781189292226918 0.515475616669282 0.796142469812185 0.0250865923380479 0.81329258499667 0.774598162949551 0.275544564982411 0.697627932536416 0.0550678732153028 0.809109806143679 0.794622929946054 0.54949145763414 0.389889955986291 0.706766843562946 0.106431684272829 0.699291401749942 0.766714409065898 0.810314901405945 0.381465698094107 0.0916266069747508 0.462486578118987 0.802502776584588 0.286823562972713 0.549268637939822 0.467003943792079 0.148393821089994 0.923426709594205 0.964127462247852 0.0655616324930452 0.99060910935048 0.546879039111081 0.7994891191856 0.323331237006933 0.212893906177487 0.320690806226339 0.823373276940547 0.788240166944452 0.488304777489975 0.419962075760122 0.574633205253631 0.667880190173164 0.893649704728741 0.630034771161154 0.293534388886765 0.898239138110075 0.498757961210795 0.290154126740526 0.045701378241647 0.292252174227033 0.59240480360575 0.284371659362223 0.342637276740279 0.0924047983088531 0.916727303226944 0.109721519891173 0.815671304345597 0.557354630194604 0.194270883363206 0.64535645191092 0.851487308403011 0.667959703798406 0.237686076948885 0.315027097109705 0.233369513847865 0.154087158516049 0.602245125176851 0.814300319778267 0.879938343041576 0.609281901218928 0.192232618271373 0.646310382375959 0.218313180012628 0.719713709673379 0.209429658660665 0.140838767227251 0.416627609818242 0.427749534526374 0.326524076550268 0.797372510267887 0.200439442847855 0.391322907188442 0.0893085129675455 0.0928079049452208 0.89533575971378 0.574366864182521 0.07391332202591 0.5586164560006 0.746250458359718 0.11597906526411 0.610327157631982 0.963861406308133 0.726918821111321 0.0439708340005018 0.654917972607072 0.628743365451228 0.125133316682186 0.792174614565447 0.326084490153007 0.30665972949937 0.0273220014688559 0.0242169565777294 0.646284199615475 0.754891176617239 0.799515034332871 0.353694003631827 0.111551261504646 0.711640076492913 0.926360374384094 0.765008256351575 0.0367687197844498 0.102234297334217 0.926120667397045 0.573600604801904 0.296200609421358 0.786476210237015 0.777315316202585 0.170597187611274 0.807723974459805 0.17354186718585 0.638087042076513 0.76870397224091 0.433330326650757 0.396172730531544 0.891480193219613 0.574637449032161 0.785260759196244 0.028507278370671 0.211579363795463 0.0244750691764057 0.520573667057324 0.356126328143291 0.654576871329918 0.757397768290248 0.81599861028837 0.434325902895071 0.709670305170584 0.922128695382271 0.549703364425804 0.534723622829188 0.919777553793974 0.872718051641714 0.780228461904917 0.905882286969572 0.545884797475301 0.503274604489561 0.478430833464954 0.442193516774569 0.802117409408093 0.0924651887686923 0.341266938962508 0.19395690506557 0.5375271969405 0.726604973508511 0.268717319713905 0.50459974629106 0.983204008322209 0.757601076653227 0.730840209391899 0.50812751541147 0.45491941596847 0.562461140940432 0.563820390172768 0.294705361044034 0.628695521464106 0.449335504225455 0.375680320162792 0.81326826262055 0.823971293126233 0.731161834604573 0.153087453052867 0.0972954357787967 0.48930212906329 0.960377849149518 0.384937423337251 0.447827955782413 0.992277569400612 0.64553602083819 0.434809171329252 0.773134135883301 0.507216235946398 0.205239798084367 0.682324748907704 0.793865289969835 0.212132880352437 0.702972119543701 0.295485090289731 0.336900858196896 0.365569846394938 0.927714974153787 0.0508462291327305 0.963454789582174 0.70936264678603 0.135058008562773 0.686726271712687 0.589362313360907 0.571089025519323 0.788892869118135 0.860566629504319 0.111346127332654 0.0412200951739214 0.889324523375835 0.513383048223332 0.800582670448348 0.888178179932293 0.806437703880947 0.436529222412501 0.902751373953652 0.0925998514611274 0.379293456976302 0.405559499338269 0.536539851934649 0.928934803586453 0.943116206100676 0.186090334670153 0.95113420615904 0.991762407280039 0.722801235925872 0.863336210052948 0.352838997854851 0.0514020361914299 0.190363787149545 0.52472707161447 0.606979697120842 0.762697993200272 0.937960654830094 0.178662693740334 0.223171349614859 0.173441100784112 0.149495287572499 0.808950693146326 0.897703758860007 0.086159430143889 0.727494887481444 0.34997870702995 0.0996294072479941 0.239767726038117 0.558935184490401 0.581795353821944 0.629142021087464 0.753870345614851 0.590803911858238 0.602734189131297 0.307451082977932 0.91930667209439 0.497424424975179 0.969639893372077 0.87388661504956 0.60536997667281 0.439408724224195 0.87499593636021 0.379403338592965 0.472860008953139 0.412543478589505 0.671601593703963 0.833735470324755 0.0901517781079747 0.885837918054312 0.173224001005292 0.0531751973181963 0.81421635676641 0.917981640473008 0.722216049039271 0.26651999786729 0.357097554351203 0.77503681327682 0.627111405907199 0.629252812957857 0.917266361985821 0.0372717690072022 0.398605472713243 0.0948371956590563 0.62397554515861 0.363204432332423 0.302215768217575 0.581549205447081 0.547755077995826 0.49713774806587 0.421605577017181 0.901796634655911 0.973135011605918 0.101017180914059 0.392628648760729 0.528182128772605 0.482942616371438 0.546165969758295 0.216901334295981 0.748214028247166 0.254918751155492 0.0856207150639966 0.570527980986517 0.0323425364564173 0.350160190048628 0.763325508383568 0.714939956711605 0.141794805405661 0.0182971116504632 0.350498853994068 0.777265512023587 0.648759854647797 0.549611688114237 0.710308187888004 0.957019702319521 0.491497901934199 0.295899881320074 0.518813970033079 0.0339605310163461 0.025475575865712 0.124801384327002 0.992127606885042 0.784624956301413 0.601254167968873 0.077231591490563 0.376257982992101 0.861109524283093 0.738046951403376 0.415300638058688 0.948648517359979 0.751669192588888 0.846623532753438 0.305036165311467 0.686360064581968 0.954138185456395 0.532815618757159 0.914597174886148 0.311425188756548 0.887111552034039 0.793098652104381 0.947887218850665 0.29942529885564 0.525000328216702 0.939277137350291 0.361639506786596 0.921141597474925 0.749223911541048 0.744310730020516 0.734272459265776 0.133599370641168 0.476190197232645 0.147812728616409 0.476992844634224 0.184437558690552 0.0814860579534434 0.652559208997991 0.0229153333907016 0.439397733872756 0.373060142931063 0.685418219123967 0.759057934405282 0.356299877502024 0.0255824249936268 0.90614087209804 0.353445913505275 0.32647311755456 0.605762641092297 0.46125675018644 0.655560360492673 0.75299443327589 0.247494648206048 0.293088870742358 0.920048021548428 0.218046596683562 0.68305489364313 0.975182605588343 0.80611607037019 0.581098960391246 0.221086936802603 0.8170758180134 0.831147861459758 0.146473250261042 0.174971522896085 0.0810433533205651 0.469798823355231 0.407023261557333 0.732208960622083 0.585450805332512 0.156645063466858 0.625869934379589 0.448452275742311 0.313487355788238 0.164305461968761 0.163284223668743 0.359664954384789 0.824008205540013 0.565475058576558 0.187725485749543 0.837732145739719 0.399256251575425 0.722849305113778 0.68877395927906 0.564164467696101 0.590612585928757 0.841745557237882 0.361027932683937 0.0641189865930937 0.814842101922259 0.0632225397229195 0.466612035881262 0.892544155819342 0.258113899871241 0.685541955544613 0.365009446116164 0.215166536134202 0.51058274747571 0.267719617085531 0.193393122164998 0.33489641540451 0.270671036087442 0.654773870613426 0.278763283253647 0.13010807137005 0.785639730624389 0.931957558912691 0.0559174100938253 0.225343741711695 0.0831192873348482 0.973604896382894 0.842938763420098 0.405083908706438 0.0644968151906505 0.906568693195004 0.859053456112742 0.975492026854772 0.645379195576534 0.571644608068746 0.449205988419708 0.802529914316256 0.846534378828947 0.164356044093147 0.424367644342128 0.515186840344686 0.913377862239722 0.971246336768381 0.526636112486012 0.856634883370716 0.274912315281108 0.409886487368494 0.560468538822606 0.654851377254818 0.356366366823204 0.325892300531268 0.578242117189802 0.257628496754915 0.129386191295926 0.854336776912678 0.91049107540166 0.949577678043861 0.183207199911121 0.16419417129131 0.788059019076172 0.39688621801557 0.346536433531437 0.8241888610553 0.198934823398013 0.610428727564868 0.447402210128494 0.702342118392698 0.577286472709384 0.53417442565551 0.457724080125336 0.153524640842807 0.17347160753794 0.179146378231235 0.1866667191335 0.427467311613727 0.285679600387812 0.710023181198631 0.521279167635366 0.583660785725806 0.228059132543858 0.834833648230415 0.413900468437932 0.8995495383651 0.771620259459596 0.913300348913763 0.53949924262939 0.883471608951222 0.658199889548123 0.508603657865897 0.810024199003819 0.348211204044055 0.667935492524412 0.365266339818481 0.373882180419751 0.900346957282163 0.67774313139962 0.354436931335367 0.113901629296597 0.546736413254403 0.700604372797534 0.995462935827673 0.782270617645699 0.312253594333306 0.153689585088287 0.462213441608474 0.341670107143 0.896742081902921 0.914248520277906 0.46582056899555 0.400057764905505 0.659836265977938 0.837178784080315 0.26377737871604 0.708421516115777 0.525884666799102 0.120784131968394 0.81800437109312 0.142929456157144 0.620293809236027 0.290958108289633 0.171783279569354 0.973647612154018 0.0918751620245166 0.908281810767949 0.945604336149991 0.0404349855426699 0.928822227397468 0.960197107426357 0.990347131688613 0.262536707031541 0.366112023389433 0.844994897053111 0.891235865582712 0.505205398097169 0.856187041993253 0.52102263697423 0.569226411737036 0.416741167255677 0.583031155453063 0.814335354520008 0.604467430249788 0.71521260709269 0.118963409450371 0.43639146937523 0.0320820616697893 0.414570328283589 0.120529319010675 0.593790638286155 0.231084674873855 0.224214534503408 0.241639627681579 0.93634154325584 0.295207933587953 0.241481612566859 0.563675729210954 0.794826420175377 0.412323394727428 0.510808121827431 0.740417875163257 0.0208417039387859 0.492400952004828 0.153151352910791 0.886121245764662 0.725383306972217 0.508644812675193 0.423007975595538 0.401117534667719 0.0571925780666061 0.924681991208345 0.365102829758544 0.88659940327052 0.09236230451148 0.600423409654759 0.345095123853534 0.981457821270451 0.192820044257678 0.599098179801367 0.545064510882366 0.255938809514046 0.84400831039995 0.352561704926193 0.213189042753074 0.867995377997868 0.358612738184165 0.0372693113912828 0.521564718079753 0.770274955618661 0.434408014051151 0.5172808056348 0.585997582231648 0.168861642160919 0.499537130335812 0.340233026260976 0.253823559638113 0.531765612382442 0.903368001128547 0.809564561899751 0.651899810731411 0.7809201692231 0.0167426884826273 0.316873712416273 0.429486614661291 0.257227026454639 0.723468903924804 0.631645365674049 0.685428343939129 0.19689822898712 0.598679852865171 0.833783133598045 0.82526437551016 0.142337352817412 0.92316137397429 0.627358326695394 0.0992260952340439 0.720698275743052 0.922562232937198 0.900411838388536 0.733894422985613 0.228358170141 0.15608475147048 0.643645097680856 0.462365427934565 0.38320473058382 0.547145852481481 0.270286235485692 0.910906231317203 0.0758877949044108 0.72510400429368 0.683522606627084 0.543650439665653 0.0781070575769991 0.298458722340874 0.727611961462535 0.313946716520004 0.812620773948729 0.0254659293428995 0.239637178734411 0.867136646842118 0.960670212320983 0.694925561859272 0.694218268895056 0.231981104917359 0.561635709074326 0.880786986723542 0.968570136635099 0.432206716961227 0.331138379059266 0.750050755694974 0.543029865368735 0.523454795754515 0.485112021849491 0.417393301702105 0.850753642513882 0.846462926561944 0.616082129769493 0.376642419630662 0.747350256005302 0.0969361294270493 0.275683196003083 0.733997330523562 0.435074458082672 0.908547971586231 0.498439573172946 0.446097316574305 0.119942488411907 0.906138824084774 0.540154734342359 0.942682948606089 0.244259966956452 0.800270251038019 0.0880225846846588 0.28420061210636 0.516731011690572 0.316643189333845 0.290776186394505 0.339647879481781 0.501216729641892 0.38330899531953 0.349253321476281 0.0601010125316679 0.775138350939378 0.767565852659754 0.396991002764553 0.33038726022467 0.0802521489770152 0.825404004144948 0.0376512950239703 0.405317515679635 0.942467632915359 0.544647969878279 0.908695475794375 0.36146940205479 0.0124444463988766 0.108914364785887 0.172046845853329 0.987236982784234 0.679319920439739 0.584378787137102 0.232277522163931 0.790846109504346 0.141425972392317 0.175760470160749 0.154310289849527 0.811277980739251 0.632600612076931 0.0249530314467847 0.0502148235309869 0.40640012453543 0.345623425298836 0.599431239543483 0.9877949759271 0.0949986687698401 0.605639776892494 0.846529343735892 0.114487552868668 0.833425870188512 0.126351067214273 0.554686943434645 0.822036764919758 0.685223461014684 0.369375428918283 0.159582376417238 0.36569993476849 0.410607684694696 0.988360508570913 0.0349267350393347 0.434950522508007 0.880196177423932 0.109311649624724 0.779076804921497 0.967847024064977 0.926840608716011 0.468298451371957 0.185417008760851 0.810055190504063 0.574056084104814 0.0648812905536033 0.166496378385928 0.580232356428169 0.709987908578478 0.665587691145483 0.690409112893976 0.278285184756387 0.668987431200221 0.103591047690716 0.947600088543259 0.114647557218559 0.856557302046567 0.96827608480351 0.255938566795085 0.466120527680032 0.430044946181588 0.108079000343569 0.553014506758191 0.782399232187308 0.667169654041063 0.310829702334013 0.542865310902707 0.928464131643996 0.908676761079114 0.401934365108609 0.39348890584195 0.905487737962976 0.144536093866918 0.764172811694443 0.708475257735699 0.570614489435684 0.165564881330356 0.865477536658291 0.5157525702985 0.434174909342546 0.445771586115006 0.052103697983548 0.497249307278544 0.374786187536083 leidenbase/tests/cpp_tests/tests_out/edgelist.edg0000644000176200001440000200100414451337435022033 0ustar liggesusers0 0 0 29 0 51 0 197 0 220 0 251 0 298 0 301 0 338 0 358 0 367 0 398 0 436 0 442 0 467 0 545 0 560 0 597 0 663 0 676 0 699 0 715 0 721 0 771 0 821 0 824 0 828 0 866 0 872 0 892 0 895 0 973 0 983 0 996 0 1011 0 1083 0 1085 0 1124 0 1145 0 1305 0 1330 0 1371 0 1398 0 1400 1 1 1 100 1 260 1 265 1 417 1 421 1 616 1 656 1 672 1 712 1 717 1 806 1 850 1 855 1 856 1 945 1 1074 1 1117 1 1195 1 1226 1 1317 1 1337 1 1342 1 1387 1 1397 1 1473 2 2 2 25 2 93 2 95 2 97 2 111 2 117 2 126 2 153 2 194 2 197 2 227 2 231 2 241 2 247 2 282 2 296 2 353 2 362 2 384 2 450 2 454 2 463 2 499 2 516 2 554 2 564 2 654 2 662 2 670 2 675 2 796 2 801 2 825 2 838 2 970 2 982 2 1001 2 1002 2 1012 2 1036 2 1050 2 1056 2 1083 2 1105 2 1119 2 1122 2 1186 2 1194 2 1248 2 1256 2 1280 2 1282 2 1298 2 1302 2 1329 2 1354 2 1384 2 1385 2 1394 2 1396 2 1447 2 1478 3 3 3 8 3 19 3 64 3 183 3 407 3 473 3 499 3 527 3 599 3 614 3 628 3 660 3 709 3 816 3 849 3 951 3 1040 3 1132 3 1227 3 1419 3 1478 4 4 4 71 4 155 4 169 4 177 4 248 4 331 4 469 4 519 4 632 4 716 4 977 4 1053 4 1073 4 1357 4 1367 4 1423 4 1451 4 1480 5 5 5 12 5 13 5 52 5 65 5 85 5 165 5 202 5 218 5 230 5 234 5 240 5 291 5 365 5 434 5 441 5 528 5 569 5 603 5 609 5 630 5 642 5 730 5 742 5 883 5 939 5 1018 5 1028 5 1076 5 1129 5 1159 5 1265 5 1331 5 1369 5 1461 5 1472 6 6 6 42 6 45 6 48 6 108 6 124 6 172 6 256 6 268 6 303 6 374 6 382 6 392 6 406 6 413 6 438 6 512 6 521 6 575 6 576 6 635 6 686 6 718 6 722 6 757 6 782 6 786 6 810 6 961 6 968 6 1052 6 1081 6 1086 6 1160 6 1163 6 1201 6 1208 6 1228 6 1263 6 1349 6 1362 6 1363 6 1399 7 7 7 20 7 31 7 37 7 87 7 148 7 156 7 167 7 170 7 204 7 219 7 242 7 292 7 336 7 350 7 446 7 449 7 508 7 583 7 613 7 621 7 671 7 703 7 763 7 873 7 886 7 900 7 903 7 916 7 928 7 948 7 987 7 994 7 1029 7 1071 7 1106 7 1156 7 1161 7 1171 7 1184 7 1211 7 1224 7 1257 7 1268 7 1273 7 1289 7 1326 7 1402 7 1431 7 1444 7 1450 7 1458 7 1464 7 1490 8 3 8 8 8 19 8 64 8 97 8 119 8 183 8 330 8 407 8 427 8 473 8 499 8 599 8 614 8 628 8 660 8 709 8 816 8 849 8 951 8 1132 8 1227 8 1419 9 9 9 15 9 54 9 73 9 121 9 130 9 152 9 158 9 182 9 205 9 285 9 381 9 462 9 485 9 490 9 536 9 618 9 685 9 698 9 735 9 778 9 815 9 823 9 827 9 837 9 864 9 905 9 1044 9 1144 9 1153 9 1183 9 1221 9 1258 9 1343 9 1360 9 1389 9 1448 9 1452 9 1455 10 10 10 23 10 103 10 184 10 198 10 210 10 290 10 299 10 357 10 364 10 376 10 379 10 503 10 504 10 517 10 542 10 551 10 559 10 578 10 582 10 601 10 643 10 657 10 666 10 687 10 704 10 725 10 750 10 811 10 898 10 913 10 915 10 1008 10 1095 10 1168 10 1189 10 1240 10 1246 10 1297 10 1300 10 1338 10 1364 10 1374 10 1429 10 1433 10 1437 10 1457 10 1492 10 1495 11 11 11 41 11 48 11 94 11 179 11 225 11 276 11 310 11 339 11 347 11 459 11 496 11 509 11 545 11 664 11 713 11 787 11 790 11 821 11 828 11 845 11 912 11 996 11 1019 11 1033 11 1045 11 1063 11 1081 11 1170 11 1304 11 1335 11 1465 12 5 12 12 12 13 12 52 12 63 12 65 12 85 12 165 12 234 12 240 12 365 12 434 12 528 12 609 12 642 12 730 12 742 12 751 12 759 12 939 12 1026 12 1028 12 1129 12 1159 12 1265 12 1461 13 5 13 12 13 13 13 14 13 47 13 65 13 85 13 92 13 165 13 218 13 234 13 240 13 291 13 377 13 434 13 441 13 452 13 492 13 528 13 544 13 562 13 603 13 606 13 608 13 609 13 612 13 620 13 630 13 648 13 690 13 730 13 883 13 939 13 1018 13 1028 13 1076 13 1091 13 1129 13 1159 13 1225 13 1236 13 1265 13 1291 13 1369 13 1461 14 13 14 14 14 47 14 79 14 92 14 125 14 160 14 165 14 218 14 230 14 234 14 240 14 272 14 279 14 291 14 295 14 373 14 387 14 404 14 408 14 434 14 441 14 483 14 484 14 526 14 528 14 569 14 603 14 606 14 612 14 624 14 630 14 640 14 648 14 680 14 690 14 730 14 784 14 809 14 822 14 839 14 882 14 883 14 910 14 939 14 1018 14 1075 14 1076 14 1097 14 1098 14 1159 14 1196 14 1206 14 1229 14 1236 14 1281 14 1369 14 1373 14 1441 14 1476 14 1484 15 9 15 15 15 54 15 73 15 121 15 130 15 158 15 182 15 205 15 221 15 229 15 259 15 285 15 351 15 381 15 462 15 485 15 490 15 536 15 610 15 618 15 619 15 685 15 698 15 701 15 735 15 752 15 823 15 827 15 837 15 864 15 1044 15 1102 15 1118 15 1144 15 1153 15 1183 15 1221 15 1258 15 1340 15 1343 15 1360 15 1382 15 1389 15 1448 15 1452 15 1463 16 16 16 32 16 40 16 71 16 150 16 177 16 207 16 237 16 274 16 297 16 317 16 432 16 453 16 588 16 632 16 641 16 738 16 744 16 848 16 853 16 869 16 964 16 1041 16 1053 16 1073 16 1247 16 1252 16 1262 16 1274 16 1276 16 1296 16 1322 16 1328 16 1416 16 1480 17 17 17 129 17 162 17 174 17 175 17 192 17 255 17 283 17 304 17 322 17 394 17 395 17 399 17 440 17 531 17 575 17 590 17 634 17 681 17 695 17 786 17 881 17 887 17 969 17 991 17 992 17 1039 17 1092 17 1125 17 1140 17 1209 17 1213 17 1332 18 18 18 146 18 700 18 851 18 876 18 907 18 998 18 1004 18 1123 18 1177 18 1193 18 1306 18 1397 18 1473 19 3 19 8 19 19 19 64 19 73 19 97 19 152 19 197 19 259 19 288 19 330 19 338 19 407 19 473 19 499 19 587 19 599 19 614 19 628 19 655 19 734 19 765 19 778 19 802 19 816 19 849 19 866 19 871 19 892 19 951 19 1132 19 1214 19 1242 19 1343 19 1382 19 1419 19 1442 19 1455 19 1463 20 7 20 20 20 31 20 37 20 75 20 87 20 123 20 128 20 148 20 167 20 170 20 203 20 204 20 219 20 242 20 292 20 300 20 333 20 336 20 350 20 402 20 403 20 538 20 583 20 593 20 671 20 673 20 703 20 756 20 763 20 873 20 886 20 900 20 903 20 916 20 928 20 948 20 987 20 1029 20 1071 20 1100 20 1106 20 1112 20 1161 20 1166 20 1171 20 1184 20 1188 20 1203 20 1211 20 1224 20 1257 20 1268 20 1273 20 1326 20 1402 20 1404 20 1433 20 1458 20 1462 20 1464 20 1490 21 21 21 80 21 151 21 226 21 245 21 256 21 276 21 278 21 339 21 358 21 412 21 437 21 445 21 496 21 509 21 535 21 545 21 602 21 828 21 912 21 922 21 938 21 949 21 952 21 966 21 1033 21 1042 21 1045 21 1052 21 1070 21 1170 21 1181 21 1201 21 1208 21 1239 21 1288 22 22 22 107 22 156 22 266 22 378 22 396 22 403 22 449 22 507 22 530 22 543 22 558 22 570 22 583 22 604 22 607 22 613 22 621 22 669 22 739 22 764 22 791 22 854 22 862 22 873 22 900 22 903 22 920 22 935 22 948 22 994 22 1005 22 1037 22 1038 22 1090 22 1162 22 1176 22 1224 22 1287 22 1289 22 1324 22 1326 22 1386 22 1436 22 1444 22 1493 23 10 23 23 23 49 23 184 23 198 23 290 23 376 23 457 23 503 23 517 23 542 23 555 23 582 23 601 23 627 23 643 23 666 23 693 23 725 23 750 23 766 23 770 23 898 23 933 23 1008 23 1020 23 1101 23 1166 23 1185 23 1240 23 1246 23 1323 23 1344 23 1364 23 1429 23 1433 23 1457 23 1492 24 24 24 116 24 193 24 206 24 261 24 323 24 325 24 327 24 425 24 429 24 482 24 502 24 506 24 539 24 629 24 731 24 769 24 824 24 885 24 944 24 985 24 1039 24 1064 24 1178 24 1238 24 1244 24 1261 24 1336 24 1339 24 1400 24 1403 24 1468 25 2 25 25 25 69 25 111 25 163 25 181 25 220 25 303 25 362 25 450 25 454 25 512 25 523 25 692 25 780 25 794 25 894 25 970 25 982 25 1004 25 1012 25 1031 25 1052 25 1055 25 1083 25 1105 25 1186 25 1228 25 1239 25 1256 25 1260 25 1298 25 1363 25 1385 25 1396 25 1447 25 1488 26 26 26 82 26 86 26 193 26 200 26 222 26 233 26 267 26 312 26 327 26 332 26 355 26 405 26 436 26 465 26 475 26 482 26 563 26 579 26 598 26 626 26 658 26 755 26 758 26 863 26 895 26 934 26 959 26 1009 26 1024 26 1035 26 1054 26 1079 26 1113 26 1124 26 1135 26 1204 26 1266 26 1314 26 1321 26 1327 26 1330 26 1341 26 1467 26 1485 27 27 27 28 27 89 27 96 27 138 27 162 27 228 27 263 27 289 27 328 27 470 27 479 27 501 27 552 27 561 27 634 27 678 27 711 27 714 27 741 27 753 27 775 27 786 27 789 27 830 27 831 27 887 27 890 27 909 27 921 27 942 27 991 27 995 27 1072 27 1111 27 1120 27 1213 27 1286 27 1410 27 1414 27 1446 28 27 28 28 28 89 28 138 28 172 28 267 28 380 28 440 28 444 28 470 28 505 28 552 28 625 28 652 28 705 28 708 28 753 28 795 28 832 28 865 28 890 28 921 28 931 28 965 28 995 28 1059 28 1111 28 1120 28 1160 28 1316 28 1403 28 1414 28 1425 28 1446 29 0 29 29 29 41 29 45 29 51 29 339 29 367 29 380 29 459 29 467 29 545 29 594 29 676 29 683 29 699 29 715 29 726 29 729 29 787 29 821 29 845 29 872 29 895 29 931 29 973 29 1026 29 1086 29 1208 29 1239 29 1304 29 1362 29 1398 29 1399 29 1417 30 30 30 53 30 78 30 90 30 102 30 175 30 191 30 212 30 270 30 286 30 460 30 506 30 511 30 534 30 537 30 549 30 563 30 610 30 637 30 761 30 785 30 812 30 815 30 829 30 884 30 897 30 905 30 923 30 967 30 980 30 1003 30 1057 30 1065 30 1084 30 1137 30 1141 30 1204 30 1219 30 1249 30 1334 30 1336 30 1390 30 1418 30 1459 30 1481 31 7 31 20 31 31 31 123 31 148 31 167 31 170 31 178 31 242 31 292 31 333 31 336 31 402 31 457 31 593 31 607 31 622 31 673 31 703 31 736 31 763 31 900 31 916 31 928 31 997 31 1015 31 1071 31 1100 31 1106 31 1112 31 1161 31 1166 31 1171 31 1184 31 1211 31 1224 31 1257 31 1294 31 1326 31 1402 31 1404 31 1426 31 1433 31 1462 31 1464 31 1490 32 16 32 32 32 34 32 40 32 115 32 139 32 150 32 171 32 177 32 207 32 213 32 237 32 248 32 274 32 307 32 317 32 366 32 439 32 453 32 495 32 744 32 833 32 835 32 848 32 853 32 859 32 868 32 869 32 889 32 926 32 936 32 1041 32 1053 32 1061 32 1103 32 1110 32 1138 32 1237 32 1247 32 1262 32 1276 32 1296 32 1322 32 1347 32 1376 32 1381 32 1406 32 1482 33 33 33 50 33 61 33 110 33 141 33 155 33 169 33 299 33 341 33 342 33 364 33 379 33 447 33 458 33 493 33 504 33 514 33 586 33 749 33 773 33 843 33 904 33 913 33 941 33 943 33 956 33 1109 33 1189 33 1269 33 1312 33 1338 33 1345 33 1420 33 1421 33 1437 34 32 34 34 34 40 34 136 34 171 34 207 34 213 34 237 34 274 34 307 34 317 34 423 34 439 34 495 34 588 34 744 34 783 34 813 34 835 34 848 34 853 34 859 34 868 34 869 34 889 34 936 34 1041 34 1110 34 1138 34 1174 34 1237 34 1255 34 1262 34 1284 34 1296 34 1322 34 1347 34 1376 34 1422 35 35 35 140 35 172 35 188 35 199 35 284 35 313 35 321 35 363 35 374 35 382 35 406 35 411 35 498 35 540 35 577 35 594 35 695 35 718 35 741 35 772 35 781 35 782 35 790 35 852 35 918 35 929 35 961 35 963 35 1049 35 1094 35 1123 35 1158 35 1164 35 1223 35 1251 35 1292 36 36 36 55 36 56 36 101 36 164 36 202 36 218 36 230 36 291 36 391 36 524 36 547 36 569 36 608 36 620 36 667 36 730 36 867 36 870 36 906 36 1034 36 1091 36 1098 36 1225 36 1299 36 1331 36 1373 36 1476 37 7 37 20 37 37 37 49 37 75 37 87 37 128 37 167 37 170 37 184 37 198 37 203 37 204 37 219 37 242 37 290 37 350 37 360 37 376 37 402 37 418 37 443 37 503 37 551 37 555 37 559 37 573 37 574 37 583 37 593 37 622 37 627 37 639 37 657 37 671 37 673 37 703 37 725 37 756 37 766 37 770 37 800 37 805 37 836 37 886 37 916 37 928 37 933 37 987 37 1020 37 1029 37 1087 37 1088 37 1100 37 1101 37 1106 37 1107 37 1161 37 1166 37 1169 37 1171 37 1185 37 1203 37 1205 37 1211 37 1257 37 1268 37 1273 37 1311 37 1326 37 1388 37 1431 37 1433 37 1458 37 1460 37 1483 37 1490 38 38 38 53 38 58 38 137 38 174 38 192 38 212 38 216 38 261 38 262 38 322 38 428 38 431 38 464 38 506 38 534 38 549 38 561 38 637 38 720 38 792 38 808 38 874 38 923 38 980 38 1017 38 1046 38 1065 38 1084 38 1089 38 1209 38 1219 38 1234 38 1238 38 1249 38 1336 38 1351 38 1359 38 1418 39 39 39 77 39 104 39 109 39 112 39 168 39 208 39 215 39 258 39 280 39 302 39 346 39 409 39 410 39 500 39 633 39 724 39 861 39 891 39 954 39 976 39 989 39 1025 39 1114 39 1128 39 1134 39 1148 39 1207 39 1233 39 1301 39 1310 39 1319 39 1368 39 1405 39 1439 40 16 40 32 40 34 40 40 40 115 40 171 40 177 40 207 40 213 40 237 40 274 40 307 40 317 40 366 40 453 40 495 40 588 40 744 40 813 40 833 40 835 40 848 40 853 40 859 40 869 40 926 40 936 40 1041 40 1061 40 1103 40 1110 40 1138 40 1237 40 1245 40 1247 40 1262 40 1276 40 1296 40 1322 40 1347 40 1376 40 1381 40 1406 40 1482 41 11 41 29 41 41 41 81 41 94 41 99 41 151 41 199 41 245 41 278 41 284 41 339 41 374 41 380 41 382 41 406 41 430 41 459 41 501 41 510 41 513 41 594 41 686 41 713 41 781 41 782 41 787 41 790 41 828 41 912 41 929 41 949 41 965 41 1019 41 1033 41 1045 41 1048 41 1081 41 1094 41 1152 41 1164 41 1190 41 1223 41 1226 41 1251 41 1304 41 1335 41 1408 41 1417 41 1425 41 1445 41 1471 42 6 42 42 42 45 42 48 42 124 42 172 42 256 42 263 42 303 42 392 42 406 42 413 42 498 42 575 42 576 42 635 42 649 42 718 42 722 42 757 42 782 42 810 42 961 42 969 42 1039 42 1052 42 1155 42 1160 42 1163 42 1201 42 1208 42 1333 42 1349 42 1362 42 1363 42 1399 42 1499 43 43 43 46 43 60 43 77 43 104 43 118 43 154 43 176 43 280 43 287 43 309 43 369 43 385 43 456 43 500 43 532 43 541 43 557 43 565 43 651 43 724 43 747 43 779 43 861 43 878 43 891 43 902 43 927 43 957 43 976 43 1013 43 1128 43 1150 43 1182 43 1210 43 1243 43 1279 43 1295 43 1366 43 1380 43 1439 43 1489 44 44 44 57 44 72 44 76 44 135 44 144 44 147 44 149 44 224 44 344 44 370 44 375 44 388 44 397 44 491 44 733 44 799 44 860 44 893 44 993 44 1027 44 1136 44 1202 44 1235 44 1278 44 1358 44 1393 44 1456 45 6 45 29 45 42 45 45 45 108 45 124 45 268 45 303 45 321 45 380 45 392 45 413 45 438 45 470 45 505 45 521 45 540 45 594 45 635 45 676 45 686 45 689 45 722 45 810 45 921 45 931 45 950 45 968 45 1086 45 1152 45 1160 45 1164 45 1263 45 1304 45 1349 45 1399 45 1417 45 1487 46 43 46 46 46 104 46 109 46 112 46 118 46 176 46 258 46 309 46 369 46 385 46 500 46 532 46 541 46 557 46 565 46 724 46 747 46 779 46 927 46 957 46 1013 46 1025 46 1114 46 1128 46 1150 46 1182 46 1243 46 1270 46 1279 46 1366 46 1368 46 1380 46 1439 46 1489 47 13 47 14 47 47 47 63 47 92 47 125 47 160 47 218 47 223 47 230 47 234 47 240 47 272 47 279 47 291 47 295 47 305 47 371 47 377 47 404 47 408 47 434 47 441 47 452 47 478 47 483 47 603 47 612 47 624 47 630 47 648 47 680 47 690 47 743 47 784 47 809 47 814 47 822 47 839 47 882 47 883 47 1014 47 1018 47 1075 47 1076 47 1097 47 1142 47 1196 47 1206 47 1229 47 1277 47 1281 47 1369 47 1370 47 1407 47 1472 47 1484 47 1498 48 6 48 11 48 42 48 48 48 94 48 140 48 163 48 256 48 276 48 303 48 310 48 313 48 339 48 392 48 406 48 413 48 512 48 635 48 664 48 688 48 713 48 718 48 726 48 740 48 746 48 757 48 772 48 782 48 810 48 880 48 961 48 1033 48 1049 48 1052 48 1081 48 1163 48 1181 48 1201 48 1208 48 1239 48 1362 48 1363 48 1399 49 23 49 37 49 49 49 75 49 128 49 184 49 198 49 203 49 290 49 350 49 360 49 368 49 376 49 443 49 503 49 517 49 551 49 555 49 559 49 573 49 574 49 582 49 589 49 627 49 639 49 657 49 671 49 673 49 697 49 725 49 756 49 770 49 800 49 805 49 836 49 886 49 916 49 933 49 955 49 1020 49 1088 49 1101 49 1107 49 1166 49 1200 49 1203 49 1273 49 1364 49 1429 49 1433 49 1457 49 1460 49 1483 49 1492 50 33 50 50 50 68 50 75 50 141 50 294 50 299 50 300 50 314 50 333 50 357 50 364 50 368 50 379 50 433 50 504 50 514 50 538 50 571 50 578 50 671 50 697 50 704 50 836 50 913 50 916 50 930 50 1088 50 1188 50 1189 50 1203 50 1300 50 1312 50 1338 50 1364 50 1437 50 1460 50 1495 51 0 51 29 51 51 51 70 51 151 51 186 51 235 51 278 51 281 51 321 51 358 51 367 51 380 51 412 51 419 51 437 51 522 51 545 51 594 51 597 51 635 51 661 51 676 51 695 51 699 51 708 51 729 51 731 51 768 51 810 51 872 51 921 51 931 51 1007 51 1011 51 1052 51 1086 51 1208 51 1239 51 1261 51 1339 51 1362 51 1398 51 1399 51 1417 51 1468 51 1487 52 5 52 12 52 52 52 63 52 65 52 160 52 165 52 202 52 230 52 234 52 240 52 365 52 603 52 609 52 630 52 642 52 694 52 742 52 759 52 809 52 882 52 939 52 1026 52 1028 52 1075 52 1108 52 1265 52 1461 52 1472 53 30 53 38 53 53 53 78 53 82 53 86 53 90 53 102 53 130 53 191 53 211 53 212 53 262 53 270 53 308 53 332 53 348 53 405 53 428 53 431 53 451 53 460 53 506 53 511 53 533 53 534 53 537 53 549 53 563 53 579 53 580 53 610 53 626 53 631 53 637 53 658 53 685 53 702 53 752 53 761 53 812 53 829 53 846 53 863 53 884 53 901 53 923 53 1003 53 1024 53 1035 53 1046 53 1057 53 1065 53 1066 53 1084 53 1102 53 1131 53 1135 53 1137 53 1183 53 1219 53 1221 53 1249 53 1309 53 1334 53 1336 53 1340 53 1390 53 1418 53 1459 53 1475 53 1481 53 1494 54 9 54 15 54 54 54 121 54 130 54 152 54 158 54 182 54 205 54 221 54 229 54 262 54 285 54 312 54 381 54 462 54 485 54 490 54 536 54 599 54 610 54 618 54 619 54 685 54 698 54 701 54 735 54 752 54 815 54 823 54 827 54 837 54 864 54 905 54 1044 54 1066 54 1102 54 1144 54 1153 54 1183 54 1212 54 1221 54 1258 54 1340 54 1343 54 1360 54 1382 54 1389 54 1448 54 1452 54 1455 54 1463 54 1486 55 36 55 55 55 83 55 85 55 101 55 187 55 218 55 291 55 377 55 441 55 492 55 497 55 524 55 547 55 562 55 608 55 609 55 620 55 648 55 667 55 870 55 908 55 1091 55 1098 55 1180 55 1225 55 1291 55 1299 55 1373 55 1496 56 36 56 56 56 101 56 164 56 230 56 343 56 391 56 408 56 524 56 547 56 592 56 608 56 620 56 638 56 667 56 680 56 784 56 844 56 867 56 870 56 906 56 940 56 972 56 1034 56 1098 56 1179 56 1198 56 1299 56 1373 56 1496 57 44 57 57 57 76 57 144 57 149 57 232 57 344 57 370 57 375 57 388 57 397 57 424 57 455 57 491 57 591 57 733 57 799 57 860 57 893 57 990 57 993 57 1027 57 1136 57 1179 57 1202 57 1235 57 1278 57 1358 57 1393 57 1456 58 38 58 58 58 86 58 137 58 193 58 211 58 212 58 216 58 250 58 257 58 351 58 405 58 428 58 431 58 440 58 444 58 451 58 464 58 533 58 534 58 563 58 619 58 626 58 702 58 720 58 785 58 808 58 863 58 874 58 959 58 1024 58 1035 58 1046 58 1054 58 1135 58 1187 58 1219 58 1234 58 1238 58 1249 58 1283 58 1309 58 1334 58 1341 58 1390 58 1459 59 59 59 67 59 161 59 190 59 335 59 414 59 435 59 774 59 840 59 841 59 857 59 919 59 953 59 1021 59 1231 59 1320 59 1365 59 1409 59 1432 59 1443 59 1454 59 1477 59 1491 59 1497 60 43 60 60 60 77 60 112 60 118 60 154 60 208 60 280 60 287 60 369 60 385 60 410 60 456 60 541 60 565 60 633 60 724 60 747 60 779 60 861 60 878 60 891 60 902 60 927 60 957 60 976 60 1013 60 1025 60 1128 60 1148 60 1150 60 1210 60 1279 60 1295 60 1310 60 1439 60 1489 61 33 61 61 61 110 61 141 61 169 61 299 61 341 61 342 61 364 61 379 61 447 61 458 61 493 61 504 61 514 61 578 61 586 61 687 61 704 61 749 61 773 61 843 61 904 61 913 61 915 61 941 61 943 61 956 61 1109 61 1189 61 1269 61 1312 61 1338 61 1345 61 1420 61 1421 61 1437 62 62 62 104 62 105 62 209 62 254 62 346 62 426 62 489 62 532 62 572 62 659 62 710 62 723 62 728 62 737 62 818 62 826 62 899 62 917 62 1093 62 1104 62 1114 62 1115 62 1149 62 1207 62 1220 62 1270 62 1310 62 1350 62 1383 63 12 63 47 63 52 63 63 63 125 63 160 63 165 63 234 63 240 63 272 63 387 63 404 63 603 63 630 63 642 63 648 63 694 63 742 63 759 63 809 63 882 63 888 63 939 63 1026 63 1075 63 1108 63 1265 63 1461 63 1472 63 1476 64 3 64 8 64 19 64 64 64 97 64 183 64 407 64 473 64 499 64 527 64 599 64 614 64 628 64 660 64 709 64 765 64 802 64 816 64 849 64 892 64 951 64 1132 64 1227 64 1419 65 5 65 12 65 13 65 52 65 65 65 85 65 165 65 202 65 218 65 234 65 240 65 291 65 365 65 377 65 434 65 452 65 492 65 528 65 603 65 609 65 612 65 630 65 642 65 742 65 759 65 883 65 939 65 1026 65 1028 65 1076 65 1129 65 1159 65 1265 65 1291 65 1461 65 1472 66 66 66 96 66 131 66 137 66 174 66 206 66 211 66 216 66 250 66 261 66 263 66 322 66 328 66 349 66 356 66 392 66 394 66 405 66 444 66 464 66 479 66 486 66 502 66 539 66 576 66 580 66 625 66 678 66 720 66 767 66 792 66 830 66 879 66 887 66 942 66 944 66 985 66 1017 66 1047 66 1064 66 1072 66 1089 66 1165 66 1173 66 1213 66 1238 66 1244 66 1283 66 1316 66 1332 66 1341 66 1353 66 1372 67 59 67 67 67 161 67 190 67 335 67 414 67 435 67 774 67 840 67 857 67 1021 67 1231 67 1320 67 1365 67 1409 67 1432 67 1443 67 1454 67 1477 67 1491 67 1497 68 50 68 68 68 75 68 141 68 198 68 203 68 210 68 294 68 299 68 300 68 314 68 333 68 357 68 368 68 379 68 433 68 514 68 538 68 551 68 559 68 571 68 582 68 627 68 657 68 671 68 673 68 697 68 704 68 836 68 916 68 930 68 1029 68 1088 68 1100 68 1107 68 1189 68 1203 68 1300 68 1338 68 1364 68 1374 68 1460 68 1490 69 25 69 69 69 111 69 119 69 146 69 330 69 427 69 454 69 780 69 794 69 951 69 1133 69 1222 69 1256 69 1260 69 1298 69 1385 69 1396 69 1466 70 51 70 70 70 98 70 108 70 163 70 256 70 273 70 281 70 303 70 339 70 438 70 635 70 692 70 722 70 729 70 731 70 768 70 794 70 803 70 810 70 832 70 894 70 1011 70 1012 70 1031 70 1032 70 1033 70 1039 70 1052 70 1055 70 1086 70 1208 70 1228 70 1239 70 1263 70 1363 70 1399 70 1417 70 1466 70 1487 70 1488 71 4 71 16 71 71 71 177 71 248 71 274 71 297 71 331 71 390 71 423 71 432 71 469 71 519 71 632 71 706 71 738 71 964 71 977 71 1053 71 1073 71 1130 71 1188 71 1252 71 1274 71 1328 71 1357 71 1367 71 1416 71 1423 71 1451 71 1480 72 44 72 72 72 76 72 135 72 144 72 149 72 217 72 223 72 224 72 232 72 343 72 370 72 389 72 391 72 397 72 401 72 424 72 455 72 478 72 491 72 520 72 556 72 584 72 592 72 611 72 638 72 733 72 844 72 860 72 906 72 911 72 940 72 972 72 978 72 1034 72 1068 72 1078 72 1099 72 1136 72 1142 72 1179 72 1180 72 1198 72 1230 72 1235 72 1278 72 1358 72 1361 72 1393 72 1407 72 1441 73 9 73 15 73 19 73 73 73 121 73 130 73 152 73 205 73 259 73 270 73 285 73 338 73 490 73 549 73 560 73 599 73 618 73 655 73 698 73 701 73 734 73 752 73 761 73 778 73 802 73 815 73 871 73 892 73 905 73 967 73 983 73 1044 73 1124 73 1145 73 1153 73 1214 73 1221 73 1330 73 1343 73 1382 73 1400 73 1413 73 1448 73 1452 73 1455 74 74 74 84 74 95 74 113 74 132 74 201 74 227 74 231 74 239 74 241 74 271 74 293 74 306 74 315 74 324 74 420 74 461 74 488 74 515 74 525 74 554 74 564 74 659 74 668 74 798 74 804 74 818 74 858 74 971 74 975 74 1002 74 1116 74 1119 74 1122 74 1157 74 1192 74 1232 74 1248 74 1259 74 1272 74 1280 74 1285 74 1354 74 1391 74 1394 75 20 75 37 75 49 75 50 75 68 75 75 75 123 75 128 75 141 75 198 75 203 75 290 75 292 75 294 75 300 75 314 75 333 75 357 75 360 75 368 75 402 75 433 75 538 75 551 75 555 75 571 75 582 75 593 75 622 75 627 75 657 75 671 75 673 75 697 75 703 75 756 75 805 75 836 75 916 75 930 75 933 75 1020 75 1088 75 1101 75 1106 75 1107 75 1166 75 1203 75 1257 75 1300 75 1364 75 1433 75 1460 75 1490 76 44 76 57 76 72 76 76 76 135 76 144 76 149 76 189 76 232 76 305 76 370 76 375 76 388 76 397 76 401 76 424 76 455 76 591 76 611 76 684 76 733 76 814 76 860 76 893 76 940 76 978 76 990 76 993 76 1014 76 1136 76 1179 76 1216 76 1235 76 1278 76 1290 76 1358 76 1370 76 1393 77 39 77 43 77 60 77 77 77 104 77 109 77 112 77 154 77 208 77 280 77 346 77 385 77 410 77 456 77 500 77 541 77 633 77 724 77 747 77 779 77 861 77 878 77 891 77 902 77 957 77 976 77 1013 77 1025 77 1030 77 1128 77 1134 77 1148 77 1207 77 1210 77 1279 77 1301 77 1310 77 1380 77 1439 78 30 78 53 78 78 78 82 78 102 78 130 78 191 78 200 78 211 78 212 78 270 78 286 78 308 78 332 78 348 78 405 78 428 78 451 78 460 78 464 78 511 78 533 78 534 78 537 78 549 78 579 78 610 78 626 78 631 78 637 78 658 78 685 78 702 78 752 78 761 78 812 78 829 78 863 78 884 78 901 78 923 78 959 78 1003 78 1024 78 1035 78 1057 78 1065 78 1066 78 1084 78 1124 78 1131 78 1135 78 1183 78 1212 78 1221 78 1238 78 1249 78 1309 78 1327 78 1336 78 1340 78 1351 78 1390 78 1418 78 1459 78 1481 78 1494 79 14 79 79 79 125 79 189 79 279 79 295 79 373 79 404 79 408 79 483 79 484 79 491 79 520 79 526 79 556 79 567 79 600 79 606 79 624 79 638 79 640 79 684 79 690 79 743 79 784 79 807 79 822 79 839 79 844 79 875 79 910 79 911 79 1069 79 1075 79 1082 79 1097 79 1196 79 1206 79 1217 79 1229 79 1230 79 1236 79 1277 79 1355 79 1356 79 1375 79 1441 79 1484 80 21 80 80 80 114 80 179 80 181 80 225 80 226 80 235 80 245 80 251 80 276 80 278 80 318 80 339 80 358 80 412 80 419 80 430 80 437 80 467 80 496 80 509 80 535 80 653 80 664 80 665 80 699 80 768 80 825 80 912 80 949 80 952 80 966 80 1011 80 1022 80 1032 80 1045 80 1063 80 1170 80 1175 80 1288 80 1308 81 41 81 81 81 99 81 106 81 199 81 245 81 318 81 329 81 337 81 347 81 406 81 430 81 487 81 510 81 513 81 529 81 550 81 585 81 602 81 665 81 713 81 781 81 790 81 820 81 834 81 929 81 949 81 965 81 988 81 1000 81 1019 81 1022 81 1048 81 1070 81 1158 81 1190 81 1215 81 1223 81 1226 81 1241 81 1251 81 1408 81 1425 81 1445 81 1465 81 1471 82 26 82 53 82 78 82 82 82 90 82 102 82 191 82 193 82 200 82 211 82 233 82 244 82 308 82 332 82 405 82 428 82 451 82 465 82 511 82 533 82 537 82 549 82 563 82 579 82 610 82 623 82 626 82 658 82 702 82 752 82 761 82 812 82 863 82 884 82 901 82 934 82 959 82 1003 82 1024 82 1035 82 1066 82 1084 82 1102 82 1113 82 1118 82 1124 82 1135 82 1183 82 1212 82 1327 82 1340 82 1341 82 1378 82 1459 82 1467 82 1481 82 1494 83 55 83 83 83 187 83 217 83 223 83 224 83 305 83 371 83 377 83 441 83 452 83 492 83 497 83 524 83 544 83 547 83 562 83 584 83 592 83 612 83 648 83 680 83 908 83 972 83 1034 83 1068 83 1078 83 1091 83 1098 83 1099 83 1142 83 1180 83 1225 83 1299 83 1313 83 1356 83 1361 83 1370 83 1373 83 1474 83 1496 84 74 84 84 84 88 84 120 84 173 84 194 84 209 84 239 84 271 84 293 84 311 84 315 84 334 84 361 84 420 84 477 84 488 84 515 84 554 84 564 84 668 84 675 84 677 84 719 84 788 84 818 84 858 84 1023 84 1058 84 1062 84 1157 84 1192 84 1248 84 1293 84 1303 84 1307 84 1329 84 1354 84 1394 84 1424 84 1435 84 1469 85 5 85 12 85 13 85 55 85 65 85 85 85 218 85 234 85 291 85 365 85 492 85 562 85 603 85 608 85 609 85 620 85 642 85 730 85 742 85 870 85 939 85 1028 85 1091 85 1129 85 1159 85 1265 85 1291 85 1369 86 26 86 53 86 58 86 86 86 102 86 175 86 191 86 193 86 211 86 233 86 250 86 277 86 332 86 349 86 405 86 431 86 440 86 444 86 451 86 534 86 563 86 579 86 625 86 626 86 658 86 720 86 846 86 863 86 901 86 959 86 1024 86 1035 86 1046 86 1054 86 1131 86 1135 86 1137 86 1165 86 1283 86 1309 86 1341 86 1390 86 1475 86 1494 87 7 87 20 87 37 87 87 87 148 87 203 87 204 87 242 87 292 87 294 87 300 87 336 87 403 87 446 87 449 87 530 87 583 87 671 87 703 87 873 87 903 87 928 87 948 87 953 87 987 87 1029 87 1100 87 1106 87 1169 87 1171 87 1184 87 1188 87 1211 87 1224 87 1273 87 1326 87 1404 87 1450 87 1458 87 1460 87 1464 87 1490 88 84 88 88 88 173 88 209 88 306 88 334 88 420 88 461 88 472 88 477 88 488 88 489 88 553 88 572 88 581 88 659 88 668 88 723 88 728 88 737 88 748 88 788 88 798 88 818 88 917 88 1062 88 1080 88 1093 88 1096 88 1104 88 1115 88 1143 88 1192 88 1293 88 1469 89 27 89 28 89 89 89 127 89 138 89 267 89 268 89 392 89 444 89 470 89 501 89 505 89 540 89 678 89 686 89 705 89 753 89 786 89 789 89 795 89 830 89 831 89 865 89 896 89 921 89 931 89 950 89 965 89 986 89 995 89 1009 89 1111 89 1120 89 1160 89 1314 89 1321 89 1349 89 1410 89 1414 89 1425 89 1446 89 1449 90 30 90 53 90 82 90 90 90 102 90 191 90 193 90 212 90 262 90 270 90 285 90 323 90 327 90 451 90 506 90 511 90 533 90 536 90 537 90 563 90 610 90 618 90 658 90 701 90 734 90 785 90 808 90 812 90 815 90 829 90 884 90 905 90 934 90 967 90 1003 90 1035 90 1057 90 1118 90 1124 90 1135 90 1141 90 1187 90 1219 90 1334 90 1390 90 1459 90 1481 90 1486 91 91 91 143 91 219 91 326 91 416 91 418 91 446 91 508 91 604 91 613 91 617 91 636 91 639 91 644 91 669 91 732 91 739 91 854 91 933 91 958 91 962 91 997 91 1010 91 1146 91 1151 91 1154 91 1167 91 1205 91 1268 91 1431 91 1479 92 13 92 14 92 47 92 92 92 125 92 160 92 218 92 230 92 240 92 272 92 291 92 373 92 387 92 434 92 441 92 452 92 483 92 484 92 528 92 569 92 600 92 603 92 606 92 612 92 620 92 624 92 630 92 640 92 690 92 694 92 730 92 743 92 809 92 867 92 882 92 883 92 910 92 911 92 999 92 1018 92 1075 92 1076 92 1082 92 1108 92 1159 92 1196 92 1206 92 1236 92 1277 92 1331 92 1369 92 1461 92 1472 92 1476 92 1484 93 2 93 93 93 95 93 111 93 126 93 153 93 194 93 227 93 231 93 239 93 241 93 247 93 271 93 282 93 296 93 311 93 315 93 362 93 450 93 454 93 463 93 481 93 515 93 516 93 564 93 654 93 670 93 796 93 801 93 838 93 858 93 970 93 975 93 982 93 1001 93 1002 93 1023 93 1036 93 1050 93 1083 93 1116 93 1119 93 1122 93 1157 93 1194 93 1248 93 1253 93 1256 93 1280 93 1282 93 1298 93 1354 93 1384 93 1394 93 1395 93 1396 93 1435 93 1478 94 11 94 41 94 48 94 94 94 179 94 226 94 245 94 246 94 276 94 310 94 321 94 339 94 382 94 406 94 459 94 467 94 496 94 501 94 653 94 664 94 679 94 713 94 772 94 782 94 787 94 790 94 810 94 852 94 880 94 912 94 929 94 946 94 952 94 961 94 1033 94 1045 94 1081 94 1158 94 1163 94 1170 94 1181 94 1201 94 1208 94 1239 94 1241 94 1251 94 1288 94 1335 94 1362 94 1363 94 1445 95 2 95 74 95 93 95 95 95 111 95 126 95 132 95 194 95 201 95 227 95 231 95 239 95 241 95 247 95 271 95 275 95 282 95 296 95 306 95 311 95 315 95 362 95 450 95 463 95 481 95 515 95 516 95 554 95 564 95 654 95 662 95 670 95 796 95 801 95 838 95 858 95 970 95 971 95 975 95 1001 95 1002 95 1023 95 1036 95 1050 95 1058 95 1116 95 1119 95 1122 95 1157 95 1194 95 1232 95 1248 95 1280 95 1282 95 1354 95 1384 95 1394 95 1396 95 1478 96 27 96 66 96 96 96 131 96 162 96 243 96 261 96 263 96 322 96 328 96 354 96 356 96 394 96 479 96 486 96 501 96 561 96 634 96 649 96 711 96 714 96 726 96 746 96 786 96 789 96 792 96 830 96 879 96 881 96 887 96 909 96 942 96 1017 96 1047 96 1072 96 1089 96 1125 96 1165 96 1173 96 1209 96 1213 96 1244 96 1283 96 1372 96 1414 97 2 97 8 97 19 97 64 97 97 97 153 97 183 97 197 97 220 97 247 97 296 97 362 97 384 97 407 97 499 97 614 97 628 97 654 97 662 97 765 97 816 97 871 97 892 97 951 97 970 97 1001 97 1036 97 1050 97 1105 97 1132 97 1186 97 1222 97 1227 97 1242 97 1256 97 1329 97 1354 97 1384 98 70 98 98 98 151 98 185 98 186 98 256 98 264 98 281 98 301 98 358 98 367 98 398 98 412 98 419 98 437 98 546 98 597 98 645 98 663 98 682 98 683 98 692 98 729 98 731 98 760 98 768 98 794 98 803 98 1011 98 1012 98 1031 98 1032 98 1055 98 1083 98 1085 98 1197 98 1208 98 1263 98 1305 98 1417 98 1440 98 1488 99 41 99 81 99 99 99 106 99 188 99 245 99 249 99 329 99 337 99 430 99 487 99 505 99 510 99 529 99 550 99 585 99 602 99 682 99 686 99 717 99 754 99 820 99 890 99 929 99 949 99 968 99 988 99 1000 99 1019 99 1022 99 1042 99 1048 99 1063 99 1070 99 1190 99 1223 99 1226 99 1251 99 1317 99 1408 99 1428 99 1445 100 1 100 100 100 134 100 140 100 246 100 260 100 265 100 320 100 393 100 406 100 417 100 421 100 445 100 487 100 596 100 616 100 672 100 712 100 717 100 754 100 762 100 806 100 856 100 922 100 945 100 974 100 1049 100 1074 100 1077 100 1094 100 1139 100 1158 100 1181 100 1195 100 1226 100 1315 100 1317 100 1337 100 1342 100 1387 100 1397 100 1438 100 1453 100 1470 100 1473 101 36 101 55 101 56 101 101 101 164 101 187 101 202 101 218 101 230 101 291 101 391 101 497 101 524 101 547 101 562 101 592 101 606 101 608 101 620 101 667 101 680 101 730 101 822 101 844 101 867 101 870 101 906 101 908 101 972 101 1018 101 1034 101 1091 101 1098 101 1198 101 1225 101 1299 101 1331 101 1348 101 1369 101 1373 102 30 102 53 102 78 102 82 102 86 102 90 102 102 102 130 102 191 102 200 102 211 102 270 102 308 102 312 102 332 102 405 102 428 102 451 102 511 102 533 102 536 102 537 102 549 102 563 102 579 102 610 102 626 102 658 102 685 102 702 102 752 102 761 102 812 102 829 102 863 102 884 102 901 102 905 102 923 102 959 102 967 102 1003 102 1024 102 1035 102 1057 102 1066 102 1084 102 1102 102 1113 102 1118 102 1124 102 1135 102 1137 102 1183 102 1212 102 1221 102 1327 102 1330 102 1336 102 1340 102 1390 102 1459 102 1475 102 1481 103 10 103 103 103 184 103 210 103 341 103 376 103 542 103 578 103 601 103 643 103 666 103 687 103 704 103 811 103 898 103 913 103 915 103 1008 103 1095 103 1109 103 1168 103 1297 103 1312 103 1421 103 1457 104 39 104 43 104 46 104 62 104 77 104 104 104 105 104 109 104 118 104 176 104 208 104 258 104 309 104 346 104 369 104 409 104 500 104 532 104 557 104 565 104 633 104 651 104 710 104 724 104 779 104 826 104 878 104 899 104 917 104 927 104 954 104 957 104 1025 104 1030 104 1114 104 1128 104 1134 104 1243 104 1270 104 1279 104 1301 104 1310 104 1350 104 1366 104 1368 104 1380 104 1383 104 1439 105 62 105 104 105 105 105 109 105 176 105 208 105 254 105 309 105 346 105 426 105 456 105 489 105 500 105 532 105 633 105 651 105 710 105 826 105 899 105 917 105 1030 105 1114 105 1149 105 1207 105 1220 105 1243 105 1270 105 1310 105 1350 105 1380 105 1383 106 81 106 99 106 106 106 151 106 179 106 188 106 199 106 245 106 249 106 329 106 347 106 430 106 487 106 510 106 529 106 550 106 585 106 602 106 665 106 682 106 683 106 686 106 760 106 768 106 787 106 820 106 821 106 842 106 949 106 950 106 986 106 1019 106 1022 106 1060 106 1063 106 1070 106 1152 106 1190 106 1223 106 1241 106 1304 106 1408 106 1428 106 1465 107 22 107 107 107 266 107 378 107 449 107 507 107 558 107 570 107 607 107 621 107 791 107 854 107 862 107 900 107 935 107 937 107 1071 107 1127 107 1146 107 1156 107 1162 107 1176 107 1184 107 1294 107 1444 108 6 108 45 108 70 108 108 108 124 108 146 108 256 108 273 108 303 108 313 108 363 108 413 108 438 108 512 108 635 108 722 108 731 108 780 108 803 108 852 108 872 108 998 108 1004 108 1031 108 1086 108 1163 108 1228 108 1263 108 1363 108 1399 108 1466 108 1488 109 39 109 46 109 77 109 104 109 105 109 109 109 112 109 208 109 258 109 309 109 346 109 409 109 410 109 500 109 633 109 651 109 724 109 747 109 826 109 878 109 899 109 917 109 954 109 1025 109 1114 109 1128 109 1134 109 1148 109 1207 109 1243 109 1270 109 1301 109 1310 109 1350 109 1368 109 1380 109 1383 109 1439 110 33 110 61 110 110 110 155 110 169 110 341 110 342 110 364 110 379 110 447 110 458 110 493 110 504 110 578 110 586 110 687 110 749 110 773 110 843 110 904 110 913 110 915 110 941 110 943 110 956 110 1109 110 1269 110 1312 110 1345 110 1420 110 1421 110 1437 111 2 111 25 111 69 111 93 111 95 111 111 111 153 111 194 111 227 111 241 111 247 111 282 111 353 111 362 111 384 111 427 111 450 111 454 111 463 111 466 111 481 111 516 111 554 111 670 111 794 111 796 111 970 111 982 111 1001 111 1012 111 1036 111 1083 111 1105 111 1116 111 1119 111 1122 111 1186 111 1194 111 1222 111 1253 111 1256 111 1260 111 1280 111 1282 111 1298 111 1302 111 1385 111 1396 111 1478 112 39 112 46 112 60 112 77 112 109 112 112 112 154 112 168 112 208 112 215 112 258 112 280 112 302 112 346 112 409 112 410 112 500 112 633 112 724 112 861 112 878 112 891 112 954 112 976 112 989 112 1013 112 1025 112 1128 112 1134 112 1148 112 1207 112 1233 112 1301 112 1310 112 1319 112 1368 112 1380 112 1439 113 74 113 113 113 132 113 201 113 227 113 231 113 241 113 275 113 282 113 293 113 306 113 315 113 324 113 353 113 362 113 372 113 384 113 386 113 474 113 481 113 515 113 516 113 554 113 566 113 675 113 798 113 838 113 971 113 1002 113 1116 113 1119 113 1122 113 1232 113 1259 113 1280 113 1282 113 1285 113 1302 113 1391 114 80 114 114 114 181 114 220 114 225 114 238 114 298 114 301 114 358 114 467 114 663 114 664 114 670 114 689 114 699 114 721 114 825 114 966 114 996 114 1011 114 1012 114 1050 114 1055 114 1147 114 1170 114 1175 114 1186 114 1228 114 1308 114 1384 115 32 115 40 115 115 115 139 115 177 115 237 115 307 115 366 115 453 115 833 115 848 115 869 115 926 115 1061 115 1103 115 1245 115 1247 115 1262 115 1276 115 1296 115 1347 115 1381 115 1406 115 1482 116 24 116 116 116 174 116 175 116 206 116 235 116 261 116 267 116 325 116 355 116 356 116 425 116 429 116 444 116 479 116 522 116 539 116 552 116 568 116 646 116 652 116 678 116 708 116 714 116 755 116 771 116 776 116 885 116 897 116 944 116 985 116 995 116 1007 116 1064 116 1072 116 1141 116 1165 116 1178 116 1199 116 1204 116 1244 116 1261 116 1316 116 1339 116 1353 116 1401 116 1403 117 2 117 117 117 153 117 247 117 275 117 282 117 353 117 372 117 384 117 450 117 454 117 463 117 516 117 971 117 982 117 1056 117 1105 117 1186 117 1194 117 1253 117 1256 117 1280 117 1282 117 1307 117 1377 117 1385 117 1396 117 1447 118 43 118 46 118 60 118 104 118 118 118 176 118 287 118 309 118 369 118 385 118 456 118 500 118 532 118 541 118 557 118 565 118 651 118 724 118 747 118 779 118 878 118 902 118 927 118 957 118 1013 118 1114 118 1150 118 1182 118 1210 118 1243 118 1264 118 1270 118 1279 118 1295 118 1366 118 1368 118 1380 118 1489 119 8 119 69 119 119 119 298 119 330 119 407 119 427 119 442 119 454 119 765 119 780 119 794 119 951 119 983 119 1031 119 1133 119 1222 119 1228 119 1260 119 1298 119 1371 119 1396 120 84 120 120 120 201 120 239 120 241 120 271 120 275 120 293 120 311 120 315 120 361 120 515 120 564 120 647 120 677 120 719 120 793 120 858 120 971 120 1006 120 1023 120 1058 120 1157 120 1248 120 1307 120 1377 120 1394 120 1395 120 1424 120 1435 121 9 121 15 121 54 121 73 121 121 121 130 121 152 121 158 121 205 121 221 121 229 121 262 121 285 121 312 121 351 121 462 121 485 121 490 121 536 121 610 121 618 121 619 121 685 121 698 121 701 121 752 121 761 121 778 121 815 121 823 121 827 121 837 121 864 121 905 121 1044 121 1102 121 1118 121 1144 121 1153 121 1183 121 1212 121 1221 121 1258 121 1340 121 1343 121 1360 121 1382 121 1452 121 1455 121 1486 122 122 122 184 122 319 122 350 122 360 122 422 122 443 122 468 122 517 122 573 122 589 122 622 122 643 122 671 122 693 122 725 122 750 122 756 122 800 122 805 122 819 122 886 122 955 122 1087 122 1101 122 1107 122 1185 122 1200 122 1240 122 1246 122 1311 122 1323 122 1344 122 1479 123 20 123 31 123 75 123 123 123 148 123 167 123 178 123 198 123 219 123 242 123 333 123 336 123 402 123 457 123 555 123 593 123 607 123 622 123 673 123 703 123 736 123 756 123 777 123 900 123 916 123 928 123 935 123 958 123 997 123 1015 123 1071 123 1106 123 1112 123 1154 123 1166 123 1211 123 1257 123 1294 123 1311 123 1326 123 1402 123 1426 123 1433 123 1462 123 1464 123 1490 124 6 124 42 124 45 124 108 124 124 124 131 124 145 124 172 124 235 124 268 124 321 124 392 124 413 124 470 124 501 124 531 124 540 124 552 124 576 124 594 124 634 124 649 124 678 124 689 124 695 124 726 124 729 124 746 124 753 124 757 124 786 124 810 124 852 124 885 124 896 124 921 124 961 124 991 124 992 124 1039 124 1052 124 1086 124 1160 124 1173 124 1178 124 1201 124 1213 124 1339 124 1349 124 1353 124 1362 124 1372 124 1425 125 14 125 47 125 63 125 79 125 92 125 125 125 160 125 240 125 272 125 279 125 295 125 373 125 387 125 404 125 483 125 600 125 612 125 624 125 640 125 690 125 694 125 743 125 807 125 809 125 882 125 888 125 910 125 999 125 1026 125 1075 125 1082 125 1099 125 1196 125 1217 125 1277 125 1355 125 1476 125 1484 126 2 126 93 126 95 126 126 126 153 126 194 126 227 126 231 126 247 126 271 126 282 126 296 126 362 126 450 126 454 126 463 126 481 126 515 126 516 126 564 126 654 126 662 126 796 126 801 126 838 126 858 126 970 126 975 126 1001 126 1002 126 1036 126 1050 126 1116 126 1119 126 1122 126 1194 126 1227 126 1248 126 1280 126 1282 126 1298 126 1354 126 1394 126 1396 126 1478 127 89 127 127 127 228 127 243 127 289 127 392 127 393 127 486 127 501 127 502 127 513 127 535 127 649 127 678 127 679 127 746 127 753 127 775 127 789 127 797 127 810 127 830 127 831 127 834 127 879 127 896 127 921 127 925 127 946 127 968 127 1000 127 1009 127 1016 127 1048 127 1072 127 1111 127 1160 127 1201 127 1213 127 1241 127 1286 127 1349 127 1372 127 1392 127 1410 127 1414 127 1449 128 20 128 37 128 49 128 75 128 128 128 148 128 198 128 204 128 242 128 290 128 357 128 360 128 402 128 443 128 551 128 555 128 559 128 574 128 593 128 639 128 657 128 671 128 673 128 703 128 756 128 770 128 800 128 805 128 836 128 916 128 933 128 955 128 1020 128 1101 128 1166 128 1203 128 1273 128 1364 128 1433 128 1464 129 17 129 129 129 131 129 133 129 145 129 172 129 174 129 180 129 192 129 255 129 261 129 269 129 304 129 322 129 340 129 352 129 394 129 395 129 522 129 531 129 576 129 590 129 634 129 695 129 745 129 767 129 769 129 851 129 881 129 969 129 980 129 983 129 992 129 1067 129 1125 129 1140 129 1155 129 1173 129 1178 129 1209 129 1244 129 1261 129 1333 129 1353 129 1415 129 1468 130 9 130 15 130 53 130 54 130 73 130 78 130 102 130 121 130 130 130 152 130 205 130 259 130 270 130 286 130 308 130 312 130 338 130 451 130 511 130 549 130 560 130 610 130 637 130 655 130 685 130 698 130 752 130 761 130 778 130 812 130 815 130 823 130 827 130 905 130 967 130 1003 130 1046 130 1065 130 1084 130 1183 130 1221 130 1330 130 1343 130 1360 130 1382 130 1413 130 1455 130 1459 130 1481 131 66 131 96 131 124 131 129 131 131 131 243 131 261 131 322 131 356 131 392 131 486 131 501 131 576 131 649 131 678 131 679 131 695 131 726 131 745 131 746 131 757 131 767 131 772 131 775 131 830 131 879 131 881 131 887 131 942 131 944 131 946 131 1016 131 1017 131 1067 131 1072 131 1089 131 1125 131 1155 131 1173 131 1178 131 1209 131 1213 131 1244 131 1353 131 1362 131 1372 132 74 132 95 132 113 132 132 132 194 132 201 132 227 132 231 132 241 132 275 132 293 132 306 132 324 132 353 132 386 132 474 132 481 132 515 132 554 132 564 132 566 132 581 132 647 132 796 132 798 132 858 132 971 132 975 132 1116 132 1119 132 1232 132 1248 132 1259 132 1280 132 1391 133 129 133 133 133 172 133 180 133 186 133 238 133 281 133 304 133 395 133 438 133 498 133 522 133 590 133 661 133 681 133 722 133 803 133 969 133 992 133 1031 133 1140 133 1199 133 1209 133 1271 133 1305 133 1499 134 100 134 134 134 140 134 337 134 393 134 411 134 417 134 487 134 513 134 521 134 596 134 679 134 717 134 726 134 741 134 746 134 762 134 772 134 775 134 797 134 834 134 890 134 918 134 946 134 968 134 1000 134 1049 134 1077 134 1139 134 1226 134 1241 134 1445 134 1453 134 1470 135 44 135 72 135 76 135 135 135 144 135 149 135 189 135 217 135 232 135 253 135 305 135 343 135 370 135 387 135 389 135 391 135 397 135 401 135 424 135 455 135 478 135 491 135 520 135 556 135 584 135 591 135 600 135 611 135 684 135 733 135 784 135 807 135 844 135 860 135 911 135 940 135 978 135 990 135 1014 135 1078 135 1136 135 1142 135 1179 135 1180 135 1216 135 1229 135 1230 135 1235 135 1290 135 1358 135 1370 135 1393 135 1441 135 1474 135 1498 136 34 136 136 136 171 136 207 136 213 136 252 136 274 136 297 136 317 136 383 136 423 136 432 136 439 136 469 136 495 136 548 136 588 136 615 136 641 136 706 136 783 136 813 136 853 136 859 136 868 136 889 136 936 136 964 136 1110 136 1130 136 1138 136 1174 136 1255 136 1274 136 1284 136 1322 136 1328 136 1416 136 1422 136 1434 137 38 137 58 137 66 137 137 137 145 137 174 137 206 137 212 137 216 137 261 137 269 137 322 137 323 137 356 137 539 137 785 137 874 137 885 137 944 137 985 137 1017 137 1024 137 1064 137 1072 137 1089 137 1178 137 1234 137 1238 137 1244 137 1353 137 1359 137 1401 138 27 138 28 138 89 138 138 138 228 138 267 138 318 138 393 138 470 138 479 138 498 138 505 138 513 138 521 138 540 138 552 138 568 138 646 138 676 138 705 138 753 138 775 138 817 138 832 138 834 138 890 138 909 138 931 138 946 138 965 138 979 138 995 138 1000 138 1016 138 1048 138 1060 138 1120 138 1199 138 1286 138 1321 138 1425 139 32 139 115 139 139 139 150 139 157 139 171 139 177 139 237 139 307 139 366 139 453 139 833 139 835 139 848 139 869 139 926 139 1041 139 1061 139 1103 139 1138 139 1237 139 1245 139 1247 139 1262 139 1276 139 1296 139 1376 139 1381 139 1406 139 1482 140 35 140 48 140 100 140 134 140 140 140 246 140 313 140 320 140 321 140 337 140 363 140 374 140 382 140 393 140 406 140 411 140 413 140 417 140 487 140 498 140 521 140 540 140 577 140 596 140 688 140 718 140 740 140 741 140 746 140 762 140 772 140 781 140 782 140 797 140 806 140 852 140 918 140 945 140 974 140 998 140 1049 140 1094 140 1139 140 1158 140 1181 140 1201 140 1223 140 1251 140 1292 140 1362 140 1387 140 1453 140 1470 141 33 141 50 141 61 141 68 141 75 141 141 141 155 141 169 141 195 141 294 141 299 141 300 141 314 141 333 141 342 141 357 141 364 141 368 141 379 141 433 141 493 141 504 141 514 141 538 141 571 141 657 141 697 141 704 141 749 141 811 141 836 141 904 141 913 141 916 141 930 141 1088 141 1109 141 1168 141 1188 141 1189 141 1203 141 1269 141 1275 141 1300 141 1338 141 1364 141 1374 141 1420 141 1437 141 1460 141 1495 142 142 142 157 142 316 142 819 142 877 142 914 142 1043 142 1121 142 1430 143 91 143 143 143 219 143 266 143 326 143 378 143 416 143 422 143 446 143 507 143 508 143 570 143 604 143 613 143 617 143 621 143 636 143 644 143 669 143 732 143 739 143 777 143 791 143 854 143 900 143 935 143 937 143 958 143 962 143 997 143 1010 143 1015 143 1146 143 1151 143 1154 143 1162 143 1167 143 1176 143 1289 143 1294 143 1311 143 1326 143 1431 144 44 144 57 144 72 144 76 144 135 144 144 144 149 144 217 144 224 144 232 144 295 144 370 144 389 144 397 144 401 144 424 144 455 144 478 144 491 144 520 144 584 144 591 144 611 144 684 144 733 144 784 144 814 144 839 144 860 144 875 144 893 144 911 144 940 144 978 144 990 144 1014 144 1068 144 1136 144 1142 144 1179 144 1216 144 1230 144 1235 144 1281 144 1290 144 1313 144 1356 144 1358 144 1393 144 1407 144 1498 145 124 145 129 145 137 145 145 145 174 145 180 145 192 145 261 145 325 145 356 145 395 145 429 145 522 145 539 145 576 145 590 145 767 145 769 145 881 145 885 145 944 145 992 145 1092 145 1123 145 1155 145 1173 145 1178 145 1244 145 1261 145 1292 145 1339 145 1353 145 1401 145 1411 146 18 146 69 146 108 146 146 146 163 146 273 146 466 146 512 146 700 146 780 146 851 146 907 146 998 146 1004 146 1123 146 1177 146 1193 146 1260 146 1298 146 1306 146 1385 146 1466 147 44 147 147 147 149 147 344 147 375 147 388 147 491 147 556 147 743 147 799 147 888 147 893 147 990 147 993 147 1027 147 1069 147 1202 147 1235 147 1278 147 1355 147 1358 147 1456 148 7 148 20 148 31 148 87 148 123 148 128 148 148 148 167 148 204 148 219 148 242 148 292 148 333 148 336 148 446 148 449 148 548 148 671 148 703 148 763 148 873 148 900 148 903 148 935 148 948 148 987 148 1106 148 1156 148 1161 148 1171 148 1184 148 1188 148 1211 148 1224 148 1324 148 1326 148 1367 148 1404 148 1431 148 1444 148 1450 148 1464 148 1490 149 44 149 57 149 72 149 76 149 135 149 144 149 147 149 149 149 224 149 232 149 253 149 344 149 370 149 375 149 388 149 389 149 397 149 424 149 455 149 478 149 491 149 556 149 591 149 611 149 733 149 860 149 893 149 993 149 1136 149 1142 149 1179 149 1230 149 1235 149 1278 149 1358 149 1393 149 1456 150 16 150 32 150 139 150 150 150 171 150 177 150 207 150 213 150 237 150 248 150 252 150 274 150 297 150 317 150 366 150 423 150 432 150 439 150 453 150 495 150 588 150 706 150 744 150 835 150 848 150 868 150 869 150 889 150 926 150 936 150 964 150 1041 150 1073 150 1103 150 1130 150 1138 150 1237 150 1247 150 1262 150 1274 150 1284 150 1296 150 1322 150 1328 150 1376 150 1381 150 1406 151 21 151 41 151 51 151 98 151 106 151 151 151 179 151 185 151 186 151 199 151 245 151 251 151 256 151 264 151 278 151 281 151 301 151 318 151 339 151 347 151 358 151 380 151 419 151 430 151 437 151 470 151 480 151 496 151 510 151 529 151 540 151 545 151 597 151 645 151 661 151 665 151 674 151 676 151 682 151 683 151 686 151 729 151 731 151 760 151 768 151 787 151 803 151 821 151 828 151 912 151 949 151 950 151 952 151 965 151 986 151 1011 151 1019 151 1022 151 1032 151 1033 151 1048 151 1055 151 1060 151 1063 151 1085 151 1152 151 1190 151 1208 151 1215 151 1251 151 1263 151 1304 151 1318 151 1408 151 1417 151 1425 151 1465 151 1471 151 1487 151 1488 152 9 152 19 152 54 152 73 152 121 152 130 152 152 152 205 152 259 152 270 152 330 152 338 152 560 152 587 152 599 152 655 152 698 152 701 152 734 152 752 152 761 152 778 152 815 152 884 152 905 152 967 152 1118 152 1124 152 1212 152 1214 152 1221 152 1271 152 1330 152 1343 152 1382 152 1400 152 1413 152 1455 152 1481 153 2 153 93 153 97 153 111 153 117 153 126 153 153 153 197 153 231 153 247 153 282 153 296 153 362 153 384 153 407 153 450 153 454 153 463 153 499 153 516 153 654 153 662 153 801 153 838 153 970 153 982 153 1001 153 1036 153 1050 153 1056 153 1105 153 1122 153 1133 153 1186 153 1194 153 1227 153 1253 153 1256 153 1280 153 1282 153 1298 153 1329 153 1354 153 1384 153 1385 153 1394 153 1396 153 1478 154 43 154 60 154 77 154 112 154 154 154 176 154 208 154 280 154 287 154 369 154 385 154 410 154 456 154 541 154 557 154 633 154 724 154 747 154 779 154 861 154 878 154 891 154 902 154 927 154 957 154 976 154 1013 154 1025 154 1030 154 1128 154 1148 154 1150 154 1210 154 1279 154 1295 154 1310 154 1380 154 1439 155 4 155 33 155 110 155 141 155 155 155 169 155 299 155 331 155 458 155 493 155 514 155 519 155 586 155 632 155 716 155 773 155 843 155 904 155 941 155 956 155 1073 155 1269 155 1345 155 1357 155 1367 155 1423 155 1451 156 7 156 22 156 156 156 196 156 266 156 345 156 378 156 396 156 400 156 403 156 446 156 449 156 507 156 530 156 543 156 558 156 570 156 583 156 604 156 605 156 613 156 621 156 669 156 691 156 707 156 727 156 739 156 763 156 764 156 791 156 854 156 862 156 873 156 900 156 903 156 920 156 948 156 960 156 994 156 1005 156 1037 156 1038 156 1090 156 1126 156 1176 156 1224 156 1267 156 1287 156 1324 156 1325 156 1326 156 1386 156 1436 156 1444 156 1450 156 1464 156 1493 157 139 157 142 157 157 157 316 157 819 157 833 157 877 157 914 157 1043 157 1121 157 1430 158 9 158 15 158 54 158 121 158 158 158 182 158 205 158 221 158 229 158 257 158 262 158 351 158 381 158 462 158 473 158 485 158 490 158 599 158 618 158 619 158 685 158 698 158 735 158 823 158 827 158 837 158 864 158 1044 158 1144 158 1153 158 1183 158 1258 158 1360 158 1389 158 1448 158 1452 158 1455 158 1463 159 159 159 196 159 252 159 274 159 345 159 383 159 390 159 400 159 432 159 448 159 543 159 548 159 588 159 605 159 615 159 641 159 707 159 738 159 739 159 764 159 847 159 920 159 947 159 960 159 964 159 1005 159 1037 159 1090 159 1126 159 1172 159 1174 159 1252 159 1287 159 1324 159 1325 159 1386 159 1434 159 1436 159 1493 160 14 160 47 160 52 160 63 160 92 160 125 160 160 160 165 160 230 160 234 160 240 160 272 160 279 160 373 160 377 160 387 160 404 160 434 160 441 160 483 160 528 160 569 160 600 160 603 160 612 160 624 160 630 160 648 160 690 160 694 160 743 160 809 160 882 160 883 160 888 160 910 160 939 160 1075 160 1076 160 1097 160 1108 160 1159 160 1196 160 1206 160 1229 160 1236 160 1277 160 1472 160 1476 160 1484 161 59 161 67 161 161 161 190 161 335 161 414 161 435 161 774 161 840 161 857 161 1021 161 1231 161 1320 161 1365 161 1409 161 1432 161 1443 161 1477 161 1491 161 1497 162 17 162 27 162 96 162 162 162 228 162 263 162 322 162 328 162 374 162 394 162 479 162 498 162 576 162 577 162 634 162 649 162 705 162 711 162 741 162 746 162 757 162 786 162 789 162 830 162 831 162 881 162 887 162 909 162 942 162 946 162 961 162 991 162 1092 162 1120 162 1125 162 1140 162 1209 162 1213 162 1283 162 1332 162 1372 162 1410 162 1414 162 1446 163 25 163 48 163 70 163 146 163 163 163 226 163 246 163 310 163 320 163 415 163 512 163 523 163 664 163 688 163 692 163 718 163 740 163 880 163 894 163 932 163 963 163 974 163 1004 163 1012 163 1032 163 1045 163 1052 163 1163 163 1170 163 1181 163 1239 163 1363 164 36 164 56 164 101 164 164 164 230 164 343 164 391 164 408 164 520 164 524 164 547 164 592 164 638 164 667 164 680 164 784 164 844 164 867 164 870 164 906 164 908 164 940 164 972 164 1034 164 1179 164 1180 164 1198 164 1230 164 1299 164 1373 164 1496 165 5 165 12 165 13 165 14 165 52 165 63 165 65 165 160 165 165 165 234 165 240 165 434 165 528 165 603 165 609 165 624 165 630 165 642 165 690 165 742 165 751 165 759 165 882 165 939 165 1026 165 1028 165 1129 165 1159 165 1196 165 1265 165 1461 166 166 166 173 166 302 166 334 166 409 166 426 166 461 166 471 166 472 166 477 166 489 166 553 166 696 166 710 166 723 166 748 166 899 166 917 166 924 166 1040 166 1080 166 1104 166 1143 166 1191 166 1233 166 1254 166 1285 166 1303 166 1308 166 1329 166 1391 166 1405 166 1427 166 1469 167 7 167 20 167 31 167 37 167 123 167 148 167 167 167 178 167 219 167 242 167 292 167 319 167 326 167 350 167 360 167 378 167 416 167 418 167 422 167 446 167 508 167 555 167 583 167 593 167 617 167 621 167 622 167 636 167 644 167 671 167 703 167 756 167 777 167 900 167 928 167 935 167 958 167 987 167 997 167 1015 167 1071 167 1087 167 1101 167 1106 167 1112 167 1154 167 1161 167 1166 167 1167 167 1171 167 1185 167 1200 167 1205 167 1211 167 1257 167 1268 167 1289 167 1294 167 1311 167 1326 167 1431 167 1464 167 1490 168 39 168 112 168 168 168 215 168 258 168 302 168 346 168 409 168 426 168 461 168 477 168 489 168 899 168 954 168 989 168 1080 168 1134 168 1233 168 1301 168 1319 168 1405 168 1427 168 1469 169 4 169 33 169 61 169 110 169 141 169 155 169 169 169 299 169 342 169 364 169 379 169 447 169 458 169 493 169 504 169 514 169 586 169 716 169 749 169 773 169 843 169 904 169 941 169 943 169 956 169 1109 169 1269 169 1275 169 1345 169 1420 169 1421 169 1437 169 1451 170 7 170 20 170 31 170 37 170 170 170 242 170 350 170 402 170 418 170 558 170 559 170 593 170 622 170 627 170 703 170 736 170 766 170 800 170 886 170 916 170 928 170 933 170 1020 170 1029 170 1071 170 1100 170 1106 170 1112 170 1156 170 1161 170 1166 170 1171 170 1184 170 1211 170 1257 170 1346 170 1388 170 1402 170 1404 170 1433 170 1462 170 1490 171 32 171 34 171 40 171 136 171 139 171 150 171 171 171 177 171 207 171 213 171 237 171 248 171 317 171 366 171 423 171 439 171 453 171 495 171 588 171 744 171 813 171 835 171 848 171 853 171 859 171 868 171 869 171 889 171 926 171 936 171 1041 171 1061 171 1103 171 1110 171 1138 171 1237 171 1247 171 1262 171 1284 171 1296 171 1322 171 1347 171 1376 171 1381 171 1406 171 1482 172 6 172 28 172 35 172 42 172 124 172 129 172 133 172 172 172 180 172 255 172 263 172 304 172 313 172 322 172 352 172 374 172 382 172 394 172 395 172 498 172 522 172 552 172 575 172 576 172 577 172 590 172 634 172 695 172 745 172 781 172 786 172 810 172 852 172 961 172 969 172 992 172 1052 172 1125 172 1140 172 1155 172 1178 172 1209 172 1333 172 1362 172 1363 173 84 173 88 173 166 173 173 173 306 173 334 173 420 173 426 173 461 173 471 173 472 173 477 173 488 173 489 173 554 173 572 173 659 173 668 173 675 173 710 173 728 173 748 173 788 173 818 173 899 173 917 173 1062 173 1080 173 1093 173 1096 173 1115 173 1143 173 1192 173 1285 173 1293 173 1303 173 1427 173 1469 174 17 174 38 174 66 174 116 174 129 174 137 174 145 174 174 174 175 174 180 174 192 174 216 174 261 174 322 174 325 174 356 174 394 174 444 174 479 174 522 174 537 174 539 174 568 174 646 174 705 174 714 174 767 174 776 174 792 174 881 174 885 174 887 174 897 174 942 174 944 174 969 174 980 174 985 174 992 174 1047 174 1072 174 1089 174 1125 174 1141 174 1204 174 1209 174 1244 174 1261 174 1339 174 1353 174 1359 174 1401 175 17 175 30 175 86 175 116 175 174 175 175 175 250 175 261 175 349 175 356 175 440 175 444 175 537 175 539 175 563 175 714 175 720 175 776 175 785 175 884 175 885 175 887 175 897 175 980 175 1057 175 1137 175 1141 175 1204 175 1283 175 1390 176 43 176 46 176 104 176 105 176 118 176 154 176 176 176 208 176 254 176 287 176 309 176 369 176 385 176 410 176 456 176 500 176 532 176 541 176 557 176 565 176 633 176 651 176 724 176 747 176 779 176 826 176 861 176 878 176 891 176 902 176 927 176 957 176 976 176 989 176 1013 176 1025 176 1030 176 1150 176 1182 176 1210 176 1220 176 1243 176 1264 176 1279 176 1295 176 1310 176 1366 176 1380 176 1489 177 4 177 16 177 32 177 40 177 71 177 115 177 139 177 150 177 171 177 177 177 207 177 213 177 237 177 248 177 274 177 297 177 366 177 453 177 632 177 706 177 716 177 738 177 744 177 833 177 835 177 848 177 853 177 869 177 926 177 964 177 1041 177 1053 177 1061 177 1103 177 1138 177 1237 177 1245 177 1247 177 1262 177 1274 177 1296 177 1322 177 1328 177 1347 177 1381 177 1406 177 1416 177 1482 178 31 178 123 178 167 178 178 178 203 178 219 178 319 178 326 178 350 178 360 178 378 178 416 178 418 178 422 178 457 178 468 178 555 178 573 178 593 178 617 178 622 178 636 178 644 178 703 178 732 178 756 178 777 178 805 178 886 178 900 178 928 178 935 178 958 178 962 178 997 178 1015 178 1087 178 1101 178 1106 178 1112 178 1154 178 1166 178 1171 178 1185 178 1205 178 1211 178 1257 178 1268 178 1289 178 1294 178 1311 178 1426 178 1433 179 11 179 80 179 94 179 106 179 151 179 179 179 181 179 225 179 226 179 245 179 246 179 249 179 265 179 276 179 278 179 310 179 339 179 406 179 430 179 509 179 596 179 653 179 664 179 682 179 713 179 754 179 762 179 768 179 787 179 790 179 845 179 880 179 894 179 912 179 932 179 949 179 952 179 963 179 974 179 1022 179 1032 179 1033 179 1045 179 1063 179 1094 179 1152 179 1158 179 1170 179 1181 179 1190 179 1208 179 1223 179 1239 179 1251 179 1288 179 1335 180 129 180 133 180 145 180 172 180 174 180 180 180 192 180 255 180 261 180 304 180 322 180 325 180 340 180 348 180 352 180 394 180 395 180 460 180 506 180 522 180 537 180 549 180 590 180 631 180 634 180 695 180 745 180 767 180 769 180 884 180 897 180 969 180 980 180 983 180 992 180 1067 180 1125 180 1140 180 1141 180 1155 180 1173 180 1178 180 1209 180 1261 180 1333 180 1351 180 1359 180 1415 180 1499 181 25 181 80 181 114 181 179 181 181 181 220 181 226 181 415 181 663 181 692 181 721 181 768 181 825 181 894 181 932 181 952 181 963 181 974 181 1012 181 1022 181 1032 181 1055 181 1175 181 1385 181 1447 182 9 182 15 182 54 182 158 182 182 182 221 182 229 182 257 182 262 182 351 182 381 182 462 182 473 182 485 182 490 182 599 182 618 182 735 182 808 182 823 182 827 182 837 182 849 182 864 182 1044 182 1144 182 1153 182 1183 182 1258 182 1360 182 1389 182 1448 182 1452 182 1455 182 1463 183 3 183 8 183 64 183 97 183 183 183 296 183 407 183 473 183 499 183 527 183 614 183 628 183 660 183 662 183 709 183 816 183 849 183 951 183 1040 183 1132 183 1227 184 10 184 23 184 37 184 49 184 103 184 122 184 184 184 198 184 210 184 350 184 357 184 376 184 457 184 468 184 503 184 517 184 542 184 555 184 559 184 573 184 582 184 589 184 601 184 627 184 657 184 666 184 725 184 750 184 766 184 770 184 800 184 886 184 898 184 933 184 1008 184 1020 184 1087 184 1088 184 1095 184 1101 184 1166 184 1185 184 1300 184 1364 184 1429 184 1457 184 1483 184 1492 185 98 185 151 185 185 185 186 185 264 185 288 185 301 185 359 185 398 185 419 185 436 185 480 185 529 185 546 185 587 185 597 185 598 185 645 185 650 185 663 185 665 185 674 185 676 185 683 185 758 185 760 185 842 185 895 185 996 185 1011 185 1060 185 1079 185 1085 185 1197 185 1218 185 1305 185 1318 185 1412 185 1413 185 1417 185 1440 185 1465 185 1487 186 51 186 98 186 133 186 151 186 185 186 186 186 238 186 256 186 264 186 278 186 281 186 298 186 301 186 303 186 358 186 367 186 419 186 437 186 496 186 545 186 597 186 645 186 661 186 674 186 676 186 682 186 699 186 729 186 803 186 828 186 949 186 950 186 1011 186 1060 186 1063 186 1085 186 1086 186 1152 186 1197 186 1208 186 1263 186 1271 186 1305 186 1398 186 1417 186 1440 186 1487 186 1488 187 55 187 83 187 101 187 187 187 217 187 452 187 497 187 524 187 544 187 547 187 562 187 584 187 592 187 608 187 620 187 667 187 867 187 906 187 908 187 972 187 1034 187 1091 187 1098 187 1225 187 1291 187 1299 187 1313 187 1348 187 1356 187 1361 187 1373 187 1496 188 35 188 99 188 106 188 188 188 199 188 374 188 382 188 406 188 430 188 487 188 510 188 529 188 540 188 550 188 577 188 661 188 682 188 686 188 718 188 781 188 782 188 790 188 820 188 949 188 1019 188 1022 188 1060 188 1063 188 1094 188 1152 188 1190 188 1223 188 1251 189 76 189 79 189 135 189 189 189 253 189 272 189 295 189 305 189 344 189 373 189 387 189 401 189 455 189 484 189 491 189 520 189 556 189 591 189 600 189 611 189 684 189 743 189 807 189 860 189 888 189 910 189 911 189 978 189 990 189 993 189 999 189 1014 189 1018 189 1069 189 1082 189 1216 189 1217 189 1230 189 1235 189 1250 189 1277 189 1290 189 1355 189 1358 189 1370 189 1375 189 1441 189 1484 190 59 190 67 190 161 190 190 190 335 190 414 190 435 190 691 190 727 190 774 190 840 190 841 190 857 190 919 190 953 190 1021 190 1231 190 1320 190 1365 190 1379 190 1409 190 1432 190 1443 190 1454 190 1477 190 1491 190 1497 191 30 191 53 191 78 191 82 191 86 191 90 191 102 191 191 191 257 191 270 191 308 191 332 191 405 191 428 191 451 191 511 191 533 191 534 191 536 191 537 191 549 191 563 191 579 191 610 191 619 191 623 191 626 191 658 191 685 191 701 191 761 191 812 191 829 191 863 191 884 191 905 191 923 191 934 191 959 191 1003 191 1024 191 1035 191 1054 191 1057 191 1065 191 1066 191 1084 191 1102 191 1113 191 1131 191 1135 191 1137 191 1183 191 1212 191 1221 191 1327 191 1334 191 1340 191 1390 191 1459 191 1486 192 17 192 38 192 129 192 145 192 174 192 180 192 192 192 255 192 261 192 322 192 340 192 352 192 395 192 460 192 531 192 590 192 700 192 745 192 769 192 851 192 1067 192 1089 192 1125 192 1155 192 1187 192 1193 192 1209 192 1333 192 1401 192 1415 193 24 193 26 193 58 193 82 193 86 193 90 193 193 193 206 193 211 193 212 193 222 193 250 193 277 193 323 193 332 193 348 193 405 193 425 193 451 193 464 193 465 193 502 193 625 193 626 193 658 193 702 193 720 193 863 193 901 193 959 193 1003 193 1024 193 1035 193 1046 193 1054 193 1064 193 1135 193 1137 193 1165 193 1234 193 1238 193 1283 193 1309 193 1327 193 1336 193 1341 193 1459 193 1481 194 2 194 84 194 93 194 95 194 111 194 126 194 132 194 194 194 201 194 227 194 231 194 241 194 247 194 275 194 282 194 311 194 362 194 372 194 384 194 481 194 516 194 564 194 654 194 670 194 675 194 796 194 970 194 973 194 975 194 1001 194 1012 194 1036 194 1050 194 1105 194 1116 194 1119 194 1122 194 1157 194 1186 194 1194 194 1232 194 1248 194 1256 194 1280 194 1302 194 1329 194 1354 194 1394 194 1478 195 141 195 195 195 294 195 299 195 314 195 342 195 379 195 504 195 571 195 693 195 697 195 704 195 749 195 811 195 836 195 904 195 913 195 930 195 1109 195 1168 195 1189 195 1240 195 1246 195 1269 195 1275 195 1338 195 1352 195 1374 195 1379 195 1420 195 1437 195 1495 196 156 196 159 196 196 196 266 196 345 196 383 196 400 196 448 196 543 196 605 196 615 196 641 196 707 196 739 196 764 196 847 196 862 196 920 196 947 196 960 196 994 196 1037 196 1090 196 1126 196 1172 196 1174 196 1267 196 1324 196 1325 196 1386 196 1434 196 1436 196 1493 197 0 197 2 197 19 197 97 197 153 197 197 197 220 197 247 197 298 197 301 197 330 197 338 197 362 197 384 197 407 197 442 197 499 197 614 197 654 197 721 197 765 197 771 197 794 197 866 197 871 197 892 197 951 197 970 197 983 197 1001 197 1036 197 1050 197 1085 197 1105 197 1145 197 1147 197 1186 197 1222 197 1242 197 1256 197 1260 197 1329 197 1371 197 1384 197 1400 197 1412 198 10 198 23 198 37 198 49 198 68 198 75 198 123 198 128 198 184 198 198 198 290 198 333 198 357 198 360 198 368 198 376 198 402 198 443 198 457 198 503 198 517 198 542 198 551 198 555 198 559 198 578 198 582 198 593 198 601 198 622 198 627 198 657 198 666 198 673 198 697 198 703 198 725 198 756 198 766 198 770 198 805 198 886 198 898 198 916 198 933 198 1008 198 1020 198 1088 198 1100 198 1101 198 1107 198 1166 198 1203 198 1257 198 1300 198 1429 198 1433 198 1457 198 1483 198 1492 199 35 199 41 199 81 199 106 199 151 199 188 199 199 199 245 199 278 199 281 199 284 199 339 199 374 199 380 199 382 199 419 199 430 199 437 199 459 199 510 199 545 199 594 199 661 199 665 199 676 199 682 199 686 199 713 199 726 199 729 199 781 199 782 199 787 199 790 199 929 199 949 199 952 199 965 199 1022 199 1048 199 1060 199 1081 199 1086 199 1094 199 1152 199 1164 199 1190 199 1215 199 1223 199 1226 199 1251 199 1304 199 1408 199 1417 199 1487 200 26 200 78 200 82 200 102 200 200 200 233 200 277 200 308 200 312 200 332 200 338 200 405 200 451 200 465 200 560 200 579 200 625 200 626 200 658 200 752 200 863 200 901 200 959 200 1003 200 1024 200 1035 200 1066 200 1113 200 1124 200 1135 200 1212 200 1327 200 1330 200 1378 200 1400 200 1413 200 1467 200 1481 200 1494 201 74 201 95 201 113 201 120 201 132 201 194 201 201 201 227 201 231 201 239 201 241 201 271 201 275 201 293 201 306 201 311 201 315 201 324 201 372 201 386 201 488 201 515 201 554 201 564 201 566 201 647 201 668 201 677 201 798 201 804 201 818 201 858 201 971 201 975 201 1002 201 1056 201 1116 201 1119 201 1157 201 1192 201 1232 201 1248 201 1259 201 1280 201 1282 201 1285 201 1307 201 1391 201 1394 202 5 202 36 202 52 202 65 202 101 202 202 202 230 202 240 202 272 202 365 202 441 202 569 202 630 202 642 202 730 202 742 202 870 202 999 202 1018 202 1028 202 1076 202 1108 202 1265 202 1331 202 1369 202 1461 202 1472 202 1476 203 20 203 37 203 49 203 68 203 75 203 87 203 178 203 203 203 204 203 219 203 242 203 292 203 294 203 300 203 333 203 350 203 357 203 360 203 368 203 433 203 443 203 468 203 517 203 538 203 551 203 573 203 657 203 671 203 673 203 703 203 756 203 805 203 819 203 836 203 886 203 916 203 930 203 1029 203 1100 203 1101 203 1107 203 1166 203 1169 203 1171 203 1188 203 1203 203 1300 203 1311 203 1364 203 1458 203 1460 203 1490 204 7 204 20 204 37 204 87 204 128 204 148 204 203 204 204 204 242 204 292 204 294 204 300 204 333 204 336 204 403 204 443 204 583 204 657 204 671 204 703 204 836 204 928 204 930 204 948 204 953 204 987 204 1029 204 1106 204 1161 204 1169 204 1171 204 1188 204 1203 204 1211 204 1224 204 1273 204 1326 204 1379 204 1404 204 1450 204 1458 204 1460 204 1464 204 1490 205 9 205 15 205 54 205 73 205 121 205 130 205 152 205 158 205 205 205 259 205 285 205 312 205 338 205 381 205 462 205 485 205 490 205 536 205 560 205 599 205 618 205 655 205 685 205 698 205 701 205 734 205 735 205 752 205 761 205 778 205 802 205 815 205 823 205 827 205 837 205 864 205 905 205 1044 205 1066 205 1102 205 1144 205 1153 205 1183 205 1212 205 1214 205 1221 205 1258 205 1330 205 1340 205 1343 205 1360 205 1382 205 1389 205 1442 205 1448 205 1452 205 1455 205 1463 205 1486 206 24 206 66 206 116 206 137 206 193 206 206 206 211 206 235 206 277 206 325 206 348 206 355 206 356 206 405 206 425 206 451 206 539 206 552 206 568 206 580 206 625 206 646 206 652 206 702 206 708 206 714 206 755 206 776 206 846 206 885 206 944 206 985 206 1007 206 1024 206 1046 206 1064 206 1135 206 1165 206 1204 206 1238 206 1244 206 1261 206 1316 206 1403 206 1459 206 1475 206 1494 207 16 207 32 207 34 207 40 207 136 207 150 207 171 207 177 207 207 207 213 207 237 207 248 207 252 207 274 207 297 207 307 207 317 207 423 207 432 207 439 207 453 207 495 207 588 207 641 207 738 207 744 207 813 207 835 207 848 207 853 207 859 207 868 207 869 207 889 207 936 207 964 207 1041 207 1073 207 1110 207 1130 207 1138 207 1237 207 1247 207 1252 207 1262 207 1276 207 1284 207 1296 207 1322 207 1347 207 1381 207 1416 207 1422 208 39 208 60 208 77 208 104 208 105 208 109 208 112 208 154 208 176 208 208 208 254 208 280 208 302 208 385 208 410 208 456 208 500 208 532 208 541 208 565 208 633 208 651 208 724 208 747 208 779 208 826 208 861 208 878 208 891 208 902 208 927 208 957 208 976 208 989 208 1013 208 1025 208 1030 208 1128 208 1148 208 1207 208 1210 208 1295 208 1310 208 1366 208 1368 208 1380 208 1383 208 1439 208 1489 209 62 209 84 209 88 209 209 209 334 209 420 209 472 209 488 209 554 209 572 209 581 209 659 209 710 209 723 209 728 209 737 209 788 209 798 209 818 209 1006 209 1051 209 1062 209 1093 209 1104 209 1115 209 1143 209 1149 209 1192 209 1293 210 10 210 68 210 103 210 184 210 210 210 299 210 314 210 341 210 342 210 357 210 368 210 376 210 433 210 504 210 542 210 551 210 559 210 571 210 578 210 601 210 627 210 666 210 704 210 725 210 750 210 766 210 811 210 898 210 916 210 930 210 1008 210 1029 210 1088 210 1095 210 1100 210 1189 210 1297 210 1300 210 1312 210 1338 210 1457 210 1460 210 1492 210 1495 211 53 211 58 211 66 211 78 211 82 211 86 211 102 211 193 211 206 211 211 211 212 211 216 211 250 211 277 211 308 211 332 211 348 211 349 211 405 211 428 211 431 211 444 211 451 211 533 211 549 211 563 211 579 211 580 211 610 211 625 211 626 211 658 211 702 211 720 211 812 211 829 211 846 211 863 211 874 211 901 211 959 211 1003 211 1024 211 1046 211 1057 211 1064 211 1084 211 1135 211 1137 211 1165 211 1238 211 1249 211 1309 211 1341 211 1459 211 1475 211 1481 211 1494 212 30 212 38 212 53 212 58 212 78 212 90 212 137 212 193 212 211 212 212 212 216 212 270 212 286 212 349 212 428 212 431 212 451 212 460 212 464 212 511 212 534 212 537 212 549 212 563 212 580 212 623 212 631 212 637 212 720 212 761 212 785 212 792 212 812 212 829 212 874 212 923 212 1003 212 1046 212 1057 212 1064 212 1065 212 1084 212 1219 212 1234 212 1238 212 1249 212 1334 212 1336 212 1351 212 1390 212 1418 212 1459 212 1481 213 32 213 34 213 40 213 136 213 150 213 171 213 177 213 207 213 213 213 237 213 248 213 252 213 274 213 297 213 317 213 423 213 432 213 439 213 453 213 495 213 588 213 706 213 744 213 783 213 813 213 835 213 848 213 853 213 859 213 868 213 869 213 889 213 926 213 936 213 1041 213 1138 213 1237 213 1247 213 1262 213 1274 213 1284 213 1296 213 1322 213 1347 213 1376 213 1381 214 214 214 236 214 476 214 595 214 647 214 793 214 850 214 856 214 876 214 981 214 984 214 1006 214 1051 214 1117 214 1195 214 1306 214 1337 214 1342 215 39 215 112 215 168 215 215 215 258 215 280 215 302 215 346 215 409 215 410 215 426 215 489 215 861 215 954 215 989 215 1134 215 1148 215 1207 215 1233 215 1301 215 1319 215 1405 216 38 216 58 216 66 216 137 216 174 216 211 216 212 216 216 216 269 216 349 216 394 216 428 216 431 216 464 216 534 216 580 216 637 216 720 216 785 216 792 216 808 216 874 216 887 216 1017 216 1046 216 1047 216 1067 216 1089 216 1219 216 1234 216 1238 216 1249 216 1336 216 1351 216 1359 216 1390 216 1418 217 72 217 83 217 135 217 144 217 187 217 217 217 223 217 224 217 232 217 253 217 305 217 343 217 389 217 397 217 401 217 424 217 452 217 455 217 478 217 497 217 520 217 526 217 544 217 547 217 567 217 584 217 591 217 592 217 680 217 684 217 807 217 839 217 860 217 875 217 906 217 908 217 940 217 972 217 1014 217 1034 217 1068 217 1078 217 1142 217 1198 217 1216 217 1217 217 1235 217 1250 217 1290 217 1299 217 1313 217 1348 217 1356 217 1361 217 1370 217 1375 217 1474 217 1496 217 1498 218 5 218 13 218 14 218 36 218 47 218 55 218 65 218 85 218 92 218 101 218 218 218 234 218 291 218 377 218 434 218 441 218 452 218 492 218 497 218 524 218 528 218 547 218 562 218 603 218 608 218 609 218 612 218 620 218 630 218 648 218 667 218 730 218 867 218 870 218 882 218 883 218 939 218 1076 218 1091 218 1098 218 1129 218 1159 218 1225 218 1291 218 1369 218 1373 218 1496 219 7 219 20 219 37 219 91 219 123 219 143 219 148 219 167 219 178 219 203 219 219 219 242 219 292 219 319 219 326 219 350 219 360 219 378 219 416 219 418 219 422 219 443 219 446 219 508 219 555 219 593 219 613 219 617 219 621 219 622 219 636 219 639 219 644 219 671 219 703 219 732 219 756 219 777 219 886 219 900 219 903 219 928 219 933 219 935 219 958 219 987 219 997 219 1010 219 1015 219 1071 219 1101 219 1106 219 1154 219 1161 219 1166 219 1167 219 1171 219 1200 219 1205 219 1211 219 1257 219 1268 219 1289 219 1294 219 1311 219 1326 219 1346 219 1388 219 1426 219 1431 219 1464 219 1479 220 0 220 25 220 97 220 114 220 181 220 197 220 220 220 238 220 298 220 301 220 358 220 367 220 442 220 454 220 463 220 654 220 663 220 670 220 692 220 721 220 765 220 794 220 821 220 824 220 825 220 996 220 1012 220 1050 220 1055 220 1083 220 1085 220 1147 220 1186 220 1222 220 1228 220 1256 220 1260 220 1371 220 1384 220 1385 220 1398 220 1447 220 1488 221 15 221 54 221 121 221 158 221 182 221 221 221 229 221 257 221 262 221 285 221 351 221 381 221 462 221 485 221 490 221 618 221 619 221 735 221 808 221 823 221 827 221 837 221 864 221 1044 221 1144 221 1153 221 1183 221 1258 221 1360 221 1389 221 1448 221 1452 222 26 222 193 222 222 222 312 222 323 222 327 222 436 222 465 222 482 222 506 222 536 222 560 222 629 222 702 222 715 222 734 222 808 222 866 222 897 222 934 222 1024 222 1035 222 1054 222 1102 222 1113 222 1118 222 1124 222 1135 222 1212 222 1214 222 1327 222 1330 222 1334 222 1340 222 1442 222 1486 223 47 223 72 223 83 223 217 223 223 223 224 223 279 223 295 223 343 223 371 223 377 223 387 223 389 223 408 223 452 223 478 223 483 223 567 223 592 223 600 223 638 223 640 223 648 223 680 223 784 223 807 223 814 223 822 223 839 223 844 223 875 223 910 223 911 223 940 223 972 223 978 223 1034 223 1068 223 1078 223 1097 223 1099 223 1142 223 1180 223 1198 223 1206 223 1216 223 1217 223 1230 223 1281 223 1313 223 1361 223 1373 223 1407 223 1441 223 1474 223 1484 223 1496 223 1498 224 44 224 72 224 83 224 144 224 149 224 217 224 223 224 224 224 232 224 253 224 343 224 370 224 371 224 377 224 389 224 397 224 491 224 584 224 592 224 640 224 807 224 814 224 844 224 860 224 875 224 908 224 972 224 1034 224 1068 224 1078 224 1099 224 1136 224 1142 224 1180 224 1217 224 1230 224 1361 224 1373 224 1393 224 1407 224 1474 224 1496 225 11 225 80 225 114 225 179 225 225 225 226 225 249 225 276 225 278 225 329 225 339 225 347 225 412 225 419 225 437 225 496 225 509 225 602 225 653 225 656 225 664 225 682 225 692 225 713 225 760 225 768 225 787 225 821 225 825 225 828 225 845 225 912 225 922 225 952 225 966 225 1022 225 1045 225 1063 225 1152 225 1170 225 1175 225 1190 225 1288 225 1335 225 1465 226 21 226 80 226 94 226 163 226 179 226 181 226 225 226 226 226 245 226 246 226 249 226 276 226 310 226 320 226 329 226 406 226 412 226 445 226 467 226 596 226 616 226 653 226 656 226 664 226 688 226 712 226 713 226 740 226 754 226 762 226 768 226 806 226 855 226 932 226 952 226 963 226 966 226 974 226 1022 226 1032 226 1045 226 1063 226 1158 226 1170 226 1175 226 1181 226 1288 227 2 227 74 227 93 227 95 227 111 227 113 227 126 227 132 227 194 227 201 227 227 227 231 227 241 227 247 227 282 227 306 227 324 227 362 227 386 227 474 227 481 227 515 227 516 227 525 227 554 227 564 227 566 227 581 227 796 227 798 227 801 227 804 227 838 227 975 227 1001 227 1002 227 1116 227 1119 227 1122 227 1232 227 1259 227 1280 227 1282 227 1285 227 1302 227 1391 227 1396 227 1478 228 27 228 127 228 138 228 162 228 228 228 243 228 289 228 337 228 392 228 479 228 501 228 502 228 513 228 535 228 649 228 679 228 757 228 775 228 789 228 797 228 831 228 834 228 879 228 890 228 909 228 918 228 925 228 946 228 968 228 979 228 988 228 1000 228 1016 228 1072 228 1111 228 1120 228 1241 228 1286 228 1392 228 1410 228 1414 229 15 229 54 229 121 229 158 229 182 229 221 229 229 229 257 229 262 229 285 229 351 229 381 229 428 229 462 229 485 229 490 229 533 229 534 229 610 229 618 229 619 229 685 229 735 229 827 229 837 229 864 229 1044 229 1144 229 1153 229 1183 229 1258 229 1360 229 1389 229 1448 229 1452 230 5 230 14 230 36 230 47 230 52 230 56 230 92 230 101 230 160 230 164 230 202 230 230 230 272 230 279 230 291 230 365 230 373 230 387 230 391 230 441 230 483 230 569 230 600 230 603 230 609 230 624 230 630 230 642 230 690 230 694 230 730 230 784 230 809 230 844 230 870 230 882 230 910 230 999 230 1018 230 1075 230 1076 230 1108 230 1196 230 1277 230 1331 230 1369 230 1461 230 1472 230 1476 230 1484 231 2 231 74 231 93 231 95 231 113 231 126 231 132 231 153 231 194 231 201 231 227 231 231 231 239 231 241 231 247 231 271 231 282 231 296 231 306 231 311 231 315 231 362 231 386 231 450 231 454 231 463 231 481 231 515 231 516 231 564 231 796 231 801 231 804 231 838 231 858 231 975 231 1001 231 1002 231 1036 231 1050 231 1116 231 1119 231 1122 231 1194 231 1232 231 1248 231 1259 231 1280 231 1282 231 1391 231 1394 231 1396 231 1478 232 57 232 72 232 76 232 135 232 144 232 149 232 217 232 224 232 232 232 253 232 305 232 343 232 370 232 389 232 397 232 401 232 424 232 455 232 478 232 584 232 591 232 592 232 611 232 684 232 733 232 807 232 814 232 860 232 893 232 940 232 978 232 990 232 1068 232 1078 232 1136 232 1142 232 1179 232 1216 232 1229 232 1230 232 1235 232 1250 232 1278 232 1290 232 1356 232 1358 232 1375 232 1393 232 1407 232 1441 232 1456 233 26 233 82 233 86 233 200 233 233 233 244 233 332 233 355 233 405 233 563 233 623 233 625 233 658 233 708 233 755 233 795 233 865 233 896 233 934 233 1035 233 1059 233 1113 233 1137 233 1204 233 1314 233 1316 233 1327 233 1378 233 1467 233 1485 233 1494 234 5 234 12 234 13 234 14 234 47 234 52 234 63 234 65 234 85 234 160 234 165 234 218 234 234 234 240 234 291 234 371 234 377 234 434 234 441 234 492 234 528 234 544 234 603 234 609 234 624 234 630 234 642 234 648 234 742 234 759 234 882 234 883 234 939 234 1026 234 1028 234 1075 234 1076 234 1129 234 1159 234 1265 234 1461 235 51 235 80 235 116 235 124 235 206 235 235 235 251 235 284 235 301 235 321 235 356 235 358 235 467 235 486 235 539 235 552 235 568 235 594 235 678 235 689 235 695 235 714 235 729 235 753 235 885 235 944 235 985 235 1007 235 1072 235 1178 235 1244 235 1261 235 1308 235 1339 236 214 236 236 236 476 236 595 236 742 236 973 236 981 236 984 236 1117 236 1182 236 1264 237 16 237 32 237 34 237 40 237 115 237 139 237 150 237 171 237 177 237 207 237 213 237 237 237 274 237 307 237 317 237 366 237 423 237 439 237 453 237 495 237 744 237 813 237 833 237 835 237 848 237 853 237 859 237 868 237 869 237 889 237 926 237 936 237 1041 237 1061 237 1103 237 1110 237 1138 237 1237 237 1247 237 1262 237 1276 237 1284 237 1296 237 1322 237 1347 237 1376 237 1381 237 1406 237 1482 238 114 238 133 238 186 238 220 238 238 238 244 238 256 238 264 238 281 238 298 238 301 238 303 238 358 238 367 238 438 238 442 238 475 238 480 238 518 238 597 238 674 238 722 238 729 238 803 238 824 238 996 238 1011 238 1031 238 1085 238 1145 238 1147 238 1228 238 1263 238 1271 238 1305 238 1371 238 1400 238 1403 238 1412 238 1488 238 1499 239 74 239 84 239 93 239 95 239 120 239 201 239 231 239 239 239 241 239 271 239 275 239 282 239 293 239 306 239 311 239 315 239 361 239 372 239 488 239 515 239 554 239 564 239 647 239 677 239 719 239 858 239 971 239 975 239 1023 239 1056 239 1058 239 1157 239 1248 239 1253 239 1280 239 1282 239 1307 239 1354 239 1377 239 1394 239 1395 239 1424 239 1435 240 5 240 12 240 13 240 14 240 47 240 52 240 63 240 65 240 92 240 125 240 160 240 165 240 202 240 234 240 240 240 272 240 365 240 404 240 434 240 441 240 528 240 569 240 603 240 609 240 612 240 624 240 630 240 642 240 648 240 690 240 730 240 742 240 809 240 882 240 883 240 939 240 999 240 1018 240 1026 240 1028 240 1075 240 1076 240 1159 240 1196 240 1265 240 1331 240 1369 240 1461 240 1472 240 1476 240 1484 241 2 241 74 241 93 241 95 241 111 241 113 241 120 241 132 241 194 241 201 241 227 241 231 241 239 241 241 241 247 241 271 241 275 241 282 241 293 241 306 241 311 241 315 241 324 241 353 241 362 241 372 241 384 241 386 241 474 241 488 241 515 241 516 241 554 241 564 241 566 241 675 241 796 241 858 241 971 241 982 241 1023 241 1056 241 1116 241 1122 241 1157 241 1186 241 1232 241 1248 241 1253 241 1259 241 1280 241 1282 241 1329 241 1391 241 1394 242 7 242 20 242 31 242 37 242 87 242 123 242 128 242 148 242 167 242 170 242 203 242 204 242 219 242 242 242 292 242 333 242 336 242 350 242 360 242 418 242 443 242 446 242 583 242 613 242 639 242 644 242 671 242 673 242 703 242 756 242 777 242 836 242 886 242 900 242 903 242 928 242 935 242 948 242 987 242 1071 242 1106 242 1156 242 1161 242 1171 242 1184 242 1205 242 1211 242 1257 242 1268 242 1273 242 1289 242 1311 242 1326 242 1388 242 1402 242 1431 242 1450 242 1458 242 1464 242 1490 243 96 243 127 243 131 243 228 243 243 243 289 243 392 243 459 243 486 243 501 243 502 243 513 243 649 243 678 243 679 243 726 243 746 243 757 243 775 243 789 243 797 243 834 243 879 243 909 243 918 243 925 243 946 243 968 243 991 243 1016 243 1072 243 1111 243 1213 243 1372 243 1410 243 1414 244 82 244 233 244 238 244 244 244 264 244 283 244 355 244 359 244 494 244 623 244 625 244 629 244 681 244 708 244 795 244 842 244 865 244 986 244 1007 244 1009 244 1079 244 1199 244 1271 244 1316 244 1318 244 1378 244 1467 244 1485 244 1494 245 21 245 41 245 80 245 81 245 94 245 99 245 106 245 151 245 179 245 199 245 226 245 245 245 246 245 249 245 276 245 278 245 310 245 318 245 329 245 337 245 339 245 412 245 419 245 430 245 437 245 496 245 509 245 510 245 535 245 540 245 596 245 602 245 664 245 665 245 682 245 683 245 686 245 713 245 768 245 787 245 790 245 912 245 929 245 949 245 950 245 952 245 963 245 974 245 1022 245 1032 245 1033 245 1042 245 1045 245 1048 245 1063 245 1152 245 1158 245 1170 245 1190 245 1208 245 1223 245 1241 245 1251 245 1288 245 1304 245 1408 245 1445 245 1487 246 94 246 100 246 140 246 163 246 179 246 226 246 245 246 246 246 265 246 284 246 310 246 320 246 393 246 406 246 415 246 417 246 445 246 596 246 616 246 653 246 664 246 672 246 688 246 740 246 754 246 762 246 768 246 772 246 806 246 855 246 856 246 880 246 894 246 932 246 945 246 952 246 963 246 974 246 998 246 1004 246 1022 246 1032 246 1042 246 1045 246 1094 246 1139 246 1158 246 1177 246 1181 246 1239 246 1251 246 1387 246 1438 246 1453 246 1473 247 2 247 93 247 95 247 97 247 111 247 117 247 126 247 153 247 194 247 197 247 227 247 231 247 241 247 247 247 282 247 296 247 353 247 362 247 372 247 384 247 450 247 454 247 463 247 499 247 516 247 554 247 566 247 654 247 662 247 670 247 675 247 796 247 970 247 975 247 1001 247 1036 247 1050 247 1083 247 1105 247 1119 247 1122 247 1186 247 1194 247 1248 247 1253 247 1256 247 1272 247 1280 247 1302 247 1329 247 1354 247 1384 247 1396 247 1447 247 1478 248 4 248 32 248 71 248 150 248 171 248 177 248 207 248 213 248 248 248 297 248 317 248 331 248 390 248 423 248 432 248 469 248 519 248 632 248 706 248 716 248 738 248 835 248 889 248 936 248 977 248 1041 248 1053 248 1073 248 1130 248 1237 248 1247 248 1274 248 1322 248 1328 248 1357 248 1367 248 1381 248 1416 248 1423 248 1451 248 1480 249 99 249 106 249 179 249 225 249 226 249 245 249 249 249 310 249 329 249 337 249 509 249 550 249 602 249 653 249 656 249 672 249 754 249 787 249 820 249 845 249 855 249 922 249 932 249 952 249 1022 249 1063 249 1070 249 1074 249 1152 249 1170 249 1175 249 1190 249 1241 249 1288 249 1317 249 1335 249 1428 250 58 250 66 250 86 250 175 250 193 250 211 250 250 250 277 250 332 250 405 250 440 250 444 250 502 250 563 250 626 250 678 250 720 250 909 250 985 250 1016 250 1024 250 1047 250 1054 250 1165 250 1283 250 1309 250 1341 251 0 251 80 251 151 251 235 251 251 251 264 251 276 251 281 251 301 251 318 251 358 251 412 251 467 251 535 251 689 251 699 251 721 251 760 251 768 251 787 251 821 251 925 251 938 251 952 251 979 251 986 251 1009 251 1011 251 1055 251 1079 251 1215 251 1304 251 1318 251 1449 251 1465 251 1471 252 136 252 150 252 159 252 207 252 213 252 252 252 274 252 297 252 317 252 383 252 390 252 400 252 423 252 432 252 439 252 448 252 588 252 615 252 641 252 706 252 738 252 764 252 783 252 847 252 889 252 936 252 964 252 1130 252 1172 252 1174 252 1252 252 1274 252 1284 252 1322 252 1325 252 1434 252 1436 252 1493 253 135 253 149 253 189 253 217 253 224 253 232 253 253 253 305 253 344 253 389 253 397 253 404 253 455 253 478 253 491 253 556 253 567 253 584 253 591 253 611 253 684 253 743 253 807 253 814 253 860 253 875 253 910 253 978 253 990 253 993 253 1014 253 1078 253 1082 253 1136 253 1142 253 1217 253 1229 253 1235 253 1250 253 1290 253 1355 253 1356 253 1358 253 1370 253 1375 253 1456 253 1498 254 62 254 105 254 176 254 208 254 254 254 302 254 410 254 426 254 456 254 633 254 651 254 710 254 747 254 779 254 826 254 878 254 891 254 899 254 917 254 976 254 989 254 1025 254 1030 254 1148 254 1149 254 1207 254 1220 254 1270 254 1295 254 1310 254 1350 254 1383 255 17 255 129 255 172 255 180 255 192 255 255 255 304 255 322 255 328 255 340 255 352 255 354 255 363 255 394 255 395 255 531 255 561 255 590 255 634 255 700 255 711 255 745 255 769 255 786 255 851 255 852 255 881 255 969 255 992 255 1092 255 1123 255 1125 255 1140 255 1155 255 1193 255 1209 256 6 256 21 256 42 256 48 256 70 256 98 256 108 256 151 256 186 256 238 256 256 256 273 256 281 256 303 256 339 256 358 256 367 256 412 256 437 256 438 256 512 256 521 256 597 256 635 256 645 256 692 256 718 256 729 256 731 256 782 256 794 256 803 256 810 256 828 256 1011 256 1031 256 1032 256 1033 256 1052 256 1055 256 1163 256 1201 256 1208 256 1239 256 1263 256 1362 256 1363 256 1399 256 1417 256 1488 257 58 257 158 257 182 257 191 257 221 257 229 257 257 257 262 257 351 257 428 257 490 257 533 257 534 257 610 257 618 257 619 257 626 257 808 257 827 257 864 257 874 257 901 257 1024 257 1044 257 1065 257 1102 257 1183 257 1219 257 1249 257 1258 257 1334 257 1340 257 1360 258 39 258 46 258 104 258 109 258 112 258 168 258 215 258 258 258 309 258 346 258 409 258 489 258 500 258 724 258 899 258 917 258 954 258 1025 258 1114 258 1128 258 1134 258 1148 258 1182 258 1207 258 1233 258 1270 258 1301 258 1319 258 1368 258 1380 259 15 259 19 259 73 259 130 259 152 259 205 259 259 259 285 259 288 259 312 259 338 259 465 259 560 259 587 259 655 259 698 259 701 259 734 259 752 259 761 259 778 259 802 259 815 259 871 259 892 259 905 259 1113 259 1212 259 1214 259 1221 259 1330 259 1343 259 1382 259 1400 259 1413 259 1419 259 1442 259 1455 259 1463 259 1486 260 1 260 100 260 260 260 265 260 393 260 417 260 421 260 445 260 487 260 596 260 616 260 672 260 712 260 717 260 754 260 762 260 806 260 856 260 922 260 1042 260 1074 260 1077 260 1139 260 1195 260 1226 260 1315 260 1317 260 1337 260 1342 260 1387 260 1397 260 1428 260 1438 260 1453 260 1470 261 24 261 38 261 66 261 96 261 116 261 129 261 131 261 137 261 145 261 174 261 175 261 180 261 192 261 261 261 304 261 322 261 323 261 356 261 394 261 431 261 479 261 539 261 576 261 590 261 705 261 714 261 767 261 792 261 881 261 885 261 887 261 942 261 944 261 969 261 980 261 985 261 992 261 1017 261 1047 261 1067 261 1072 261 1089 261 1125 261 1141 261 1155 261 1173 261 1178 261 1209 261 1244 261 1261 261 1353 261 1359 261 1372 261 1401 261 1411 262 38 262 53 262 54 262 90 262 121 262 158 262 182 262 221 262 229 262 257 262 262 262 323 262 351 262 428 262 431 262 451 262 462 262 490 262 506 262 511 262 534 262 536 262 610 262 618 262 637 262 698 262 701 262 702 262 808 262 823 262 827 262 864 262 1003 262 1044 262 1065 262 1084 262 1144 262 1183 262 1187 262 1219 262 1249 262 1258 262 1334 262 1360 262 1415 262 1448 263 27 263 42 263 66 263 96 263 162 263 172 263 263 263 283 263 322 263 328 263 356 263 394 263 479 263 486 263 498 263 501 263 575 263 576 263 580 263 625 263 634 263 649 263 714 263 715 263 726 263 746 263 757 263 786 263 810 263 830 263 879 263 887 263 921 263 942 263 961 263 969 263 1007 263 1016 263 1072 263 1125 263 1140 263 1160 263 1173 263 1209 263 1213 263 1316 264 98 264 151 264 185 264 186 264 238 264 244 264 251 264 264 264 267 264 281 264 288 264 298 264 301 264 338 264 358 264 359 264 398 264 436 264 442 264 475 264 480 264 518 264 546 264 597 264 598 264 645 264 650 264 674 264 699 264 721 264 758 264 771 264 803 264 817 264 824 264 895 264 996 264 1009 264 1011 264 1079 264 1085 264 1145 264 1147 264 1204 264 1218 264 1266 264 1271 264 1305 264 1318 264 1371 264 1412 264 1413 265 1 265 100 265 179 265 246 265 260 265 265 265 310 265 417 265 421 265 550 265 596 265 616 265 672 265 717 265 754 265 762 265 806 265 850 265 855 265 856 265 894 265 932 265 945 265 963 265 974 265 1074 265 1094 265 1158 265 1195 265 1226 265 1317 265 1335 265 1337 265 1342 265 1397 265 1453 265 1473 266 22 266 107 266 143 266 156 266 196 266 266 266 345 266 378 266 396 266 400 266 403 266 449 266 507 266 530 266 543 266 558 266 570 266 583 266 604 266 605 266 607 266 613 266 621 266 669 266 707 266 739 266 791 266 854 266 862 266 873 266 900 266 903 266 920 266 935 266 937 266 947 266 948 266 994 266 1005 266 1037 266 1071 266 1090 266 1126 266 1162 266 1176 266 1224 266 1267 266 1289 266 1324 266 1325 266 1326 266 1386 266 1444 266 1464 267 26 267 28 267 89 267 116 267 138 267 264 267 267 267 318 267 332 267 355 267 425 267 436 267 470 267 475 267 482 267 552 267 598 267 646 267 674 267 708 267 753 267 755 267 817 267 832 267 895 267 896 267 921 267 931 267 965 267 979 267 986 267 995 267 1009 267 1079 267 1204 267 1314 267 1316 267 1321 267 1392 267 1403 267 1449 267 1467 267 1471 267 1485 268 6 268 45 268 89 268 124 268 268 268 283 268 286 268 328 268 399 268 470 268 575 268 652 268 678 268 689 268 722 268 769 268 786 268 795 268 810 268 865 268 896 268 921 268 950 268 968 268 969 268 1007 268 1039 268 1059 268 1140 268 1160 268 1349 268 1425 268 1446 268 1499 269 129 269 137 269 216 269 269 269 340 269 352 269 506 269 745 269 851 269 983 269 1017 269 1067 269 1089 269 1155 269 1178 269 1187 269 1234 269 1359 269 1415 270 30 270 53 270 73 270 78 270 90 270 102 270 130 270 152 270 191 270 212 270 270 270 286 270 308 270 332 270 338 270 451 270 460 270 506 270 511 270 537 270 549 270 563 270 610 270 637 270 655 270 685 270 702 270 752 270 761 270 778 270 785 270 812 270 815 270 829 270 863 270 884 270 905 270 923 270 967 270 1003 270 1057 270 1065 270 1084 270 1141 270 1219 270 1334 270 1336 270 1390 270 1400 270 1413 270 1418 270 1459 270 1481 271 74 271 84 271 93 271 95 271 120 271 126 271 201 271 231 271 239 271 241 271 271 271 282 271 293 271 311 271 315 271 361 271 515 271 564 271 677 271 719 271 801 271 858 271 971 271 975 271 1023 271 1058 271 1116 271 1157 271 1248 271 1280 271 1282 271 1307 271 1354 271 1377 271 1394 271 1395 271 1424 271 1435 272 14 272 47 272 63 272 92 272 125 272 160 272 189 272 202 272 230 272 240 272 272 272 279 272 295 272 373 272 387 272 404 272 483 272 556 272 569 272 600 272 611 272 612 272 624 272 630 272 640 272 690 272 694 272 743 272 809 272 882 272 888 272 910 272 911 272 999 272 1014 272 1069 272 1075 272 1082 272 1097 272 1099 272 1196 272 1277 272 1355 272 1461 272 1472 272 1476 272 1484 273 70 273 108 273 146 273 256 273 273 273 303 273 363 273 438 273 512 273 523 273 635 273 692 273 722 273 731 273 780 273 803 273 845 273 872 273 894 273 1004 273 1031 273 1228 273 1263 273 1363 273 1399 273 1447 273 1466 273 1488 274 16 274 32 274 34 274 40 274 71 274 136 274 150 274 159 274 177 274 207 274 213 274 237 274 252 274 274 274 297 274 307 274 317 274 390 274 432 274 439 274 453 274 469 274 495 274 588 274 641 274 738 274 744 274 813 274 848 274 853 274 869 274 936 274 964 274 1005 274 1041 274 1053 274 1073 274 1110 274 1130 274 1237 274 1252 274 1262 274 1274 274 1296 274 1322 274 1347 274 1416 274 1422 274 1480 274 1493 275 95 275 113 275 117 275 120 275 132 275 194 275 201 275 239 275 241 275 275 275 293 275 311 275 315 275 324 275 353 275 361 275 372 275 384 275 515 275 554 275 564 275 647 275 675 275 677 275 719 275 793 275 858 275 971 275 975 275 982 275 1036 275 1056 275 1105 275 1116 275 1232 275 1248 275 1253 275 1282 275 1302 275 1307 275 1377 275 1424 276 11 276 21 276 48 276 80 276 94 276 179 276 225 276 226 276 245 276 251 276 276 276 310 276 339 276 347 276 358 276 406 276 412 276 437 276 496 276 509 276 513 276 535 276 545 276 664 276 713 276 768 276 790 276 821 276 828 276 912 276 929 276 949 276 952 276 1011 276 1032 276 1033 276 1045 276 1052 276 1055 276 1063 276 1158 276 1170 276 1181 276 1201 276 1208 276 1215 276 1241 276 1251 276 1288 276 1363 277 86 277 193 277 200 277 206 277 211 277 250 277 277 277 332 277 348 277 405 277 440 277 444 277 451 277 561 277 563 277 579 277 580 277 626 277 652 277 658 277 720 277 846 277 863 277 874 277 901 277 1024 277 1131 277 1135 277 1137 277 1283 277 1309 277 1341 277 1351 277 1475 277 1494 278 21 278 41 278 51 278 80 278 151 278 179 278 186 278 199 278 225 278 245 278 278 278 318 278 339 278 347 278 367 278 412 278 419 278 437 278 496 278 509 278 521 278 545 278 597 278 661 278 664 278 665 278 682 278 686 278 699 278 713 278 729 278 821 278 828 278 845 278 855 278 880 278 912 278 949 278 950 278 952 278 1011 278 1022 278 1033 278 1045 278 1063 278 1086 278 1152 278 1163 278 1190 278 1197 278 1208 278 1239 278 1288 278 1399 278 1417 278 1487 279 14 279 47 279 79 279 125 279 160 279 223 279 230 279 272 279 279 279 295 279 371 279 373 279 387 279 389 279 391 279 408 279 478 279 483 279 484 279 526 279 567 279 592 279 600 279 606 279 624 279 638 279 640 279 680 279 690 279 784 279 809 279 814 279 822 279 839 279 844 279 867 279 888 279 910 279 940 279 972 279 978 279 1018 279 1068 279 1075 279 1078 279 1082 279 1097 279 1098 279 1099 279 1142 279 1180 279 1196 279 1206 279 1216 279 1229 279 1236 279 1277 279 1281 279 1356 279 1361 279 1373 279 1375 279 1407 279 1441 279 1484 279 1498 280 39 280 43 280 60 280 77 280 112 280 154 280 208 280 215 280 280 280 287 280 385 280 410 280 456 280 541 280 633 280 724 280 747 280 779 280 861 280 878 280 891 280 902 280 927 280 954 280 976 280 989 280 1013 280 1025 280 1030 280 1128 280 1148 280 1150 280 1207 280 1210 280 1279 280 1295 280 1301 280 1310 280 1439 281 51 281 70 281 98 281 133 281 151 281 186 281 199 281 238 281 251 281 256 281 264 281 281 281 298 281 301 281 303 281 358 281 367 281 398 281 437 281 438 281 442 281 475 281 480 281 518 281 540 281 594 281 661 281 674 281 722 281 729 281 731 281 768 281 803 281 824 281 949 281 1011 281 1031 281 1032 281 1060 281 1085 281 1086 281 1147 281 1208 281 1263 281 1266 281 1271 281 1305 281 1412 281 1417 281 1487 281 1488 282 2 282 93 282 95 282 111 282 113 282 117 282 126 282 153 282 194 282 227 282 231 282 239 282 241 282 247 282 271 282 282 282 296 282 311 282 362 282 450 282 454 282 463 282 515 282 516 282 564 282 796 282 801 282 838 282 858 282 970 282 975 282 982 282 1001 282 1002 282 1036 282 1050 282 1056 282 1105 282 1116 282 1119 282 1122 282 1194 282 1248 282 1253 282 1256 282 1280 282 1282 282 1298 282 1354 282 1394 282 1396 282 1478 283 17 283 244 283 263 283 268 283 283 283 304 283 322 283 328 283 349 283 355 283 382 283 394 283 395 283 399 283 464 283 575 283 580 283 625 283 629 283 631 283 634 283 652 283 681 283 695 283 708 283 767 283 786 283 795 283 810 283 830 283 865 283 896 283 921 283 969 283 980 283 1007 283 1039 283 1059 283 1125 283 1140 283 1199 283 1316 283 1351 283 1378 283 1468 283 1499 284 35 284 41 284 199 284 235 284 246 284 284 284 313 284 321 284 374 284 380 284 382 284 459 284 510 284 540 284 577 284 594 284 726 284 772 284 781 284 782 284 790 284 852 284 929 284 963 284 974 284 1048 284 1077 284 1094 284 1152 284 1158 284 1164 284 1223 284 1226 284 1251 284 1304 285 9 285 15 285 54 285 73 285 90 285 121 285 205 285 221 285 229 285 259 285 285 285 351 285 381 285 462 285 485 285 490 285 536 285 618 285 619 285 655 285 685 285 698 285 701 285 734 285 735 285 802 285 823 285 827 285 837 285 864 285 1044 285 1118 285 1144 285 1153 285 1183 285 1221 285 1258 285 1340 285 1343 285 1360 285 1382 285 1442 285 1448 285 1452 285 1455 285 1463 286 30 286 78 286 130 286 212 286 268 286 270 286 286 286 308 286 328 286 349 286 399 286 460 286 464 286 511 286 549 286 580 286 623 286 631 286 652 286 752 286 769 286 778 286 795 286 815 286 829 286 905 286 923 286 967 286 1046 286 1057 286 1059 286 1084 286 1131 286 1140 286 1238 286 1249 286 1336 286 1351 286 1390 286 1415 286 1418 286 1459 286 1481 286 1499 287 43 287 60 287 118 287 154 287 176 287 280 287 287 287 369 287 385 287 456 287 532 287 541 287 557 287 565 287 633 287 651 287 724 287 747 287 779 287 861 287 891 287 902 287 927 287 957 287 976 287 1013 287 1030 287 1150 287 1210 287 1243 287 1279 287 1295 287 1366 287 1380 287 1489 288 19 288 185 288 259 288 264 288 288 288 359 288 398 288 436 288 546 288 560 288 587 288 598 288 645 288 650 288 683 288 758 288 765 288 802 288 842 288 871 288 892 288 895 288 1079 288 1197 288 1214 288 1218 288 1242 288 1412 288 1419 288 1440 288 1442 289 27 289 127 289 228 289 243 289 289 289 459 289 501 289 679 289 726 289 741 289 775 289 789 289 797 289 830 289 879 289 909 289 925 289 946 289 988 289 1077 289 1111 289 1213 289 1372 289 1392 289 1410 289 1414 289 1446 289 1470 290 10 290 23 290 37 290 49 290 75 290 128 290 198 290 290 290 357 290 360 290 376 290 402 290 443 290 551 290 555 290 559 290 574 290 582 290 657 290 673 290 756 290 770 290 800 290 805 290 916 290 933 290 955 290 1020 290 1101 290 1166 290 1189 290 1203 290 1364 290 1429 290 1433 290 1460 290 1483 291 5 291 13 291 14 291 36 291 47 291 55 291 65 291 85 291 92 291 101 291 218 291 230 291 234 291 291 291 365 291 377 291 434 291 441 291 452 291 492 291 524 291 528 291 547 291 562 291 603 291 608 291 609 291 612 291 620 291 630 291 648 291 667 291 730 291 867 291 870 291 882 291 883 291 939 291 1018 291 1076 291 1091 291 1098 291 1129 291 1159 291 1225 291 1291 291 1331 291 1369 291 1373 291 1472 291 1496 292 7 292 20 292 31 292 75 292 87 292 148 292 167 292 203 292 204 292 219 292 242 292 292 292 294 292 300 292 333 292 336 292 403 292 446 292 449 292 530 292 583 292 671 292 703 292 873 292 903 292 948 292 987 292 1038 292 1071 292 1106 292 1156 292 1161 292 1169 292 1171 292 1184 292 1188 292 1211 292 1224 292 1287 292 1326 292 1404 292 1450 292 1458 292 1464 292 1490 293 74 293 84 293 113 293 120 293 132 293 201 293 239 293 241 293 271 293 275 293 293 293 311 293 315 293 353 293 361 293 372 293 488 293 515 293 554 293 566 293 647 293 677 293 719 293 793 293 818 293 858 293 971 293 1006 293 1023 293 1056 293 1058 293 1157 293 1192 293 1232 293 1253 293 1282 293 1307 293 1377 293 1424 293 1435 294 50 294 68 294 75 294 87 294 141 294 195 294 203 294 204 294 292 294 294 294 300 294 314 294 333 294 336 294 357 294 368 294 433 294 514 294 538 294 571 294 657 294 671 294 697 294 836 294 916 294 930 294 1029 294 1088 294 1100 294 1169 294 1188 294 1203 294 1300 294 1364 294 1379 294 1404 294 1458 294 1460 294 1490 295 14 295 47 295 79 295 125 295 144 295 189 295 223 295 272 295 279 295 295 295 371 295 373 295 387 295 401 295 404 295 408 295 478 295 483 295 526 295 600 295 611 295 612 295 624 295 640 295 680 295 690 295 694 295 784 295 814 295 822 295 839 295 888 295 910 295 911 295 940 295 978 295 990 295 999 295 1014 295 1018 295 1068 295 1069 295 1075 295 1082 295 1097 295 1099 295 1142 295 1196 295 1216 295 1229 295 1236 295 1277 295 1281 295 1290 295 1355 295 1370 295 1375 295 1407 295 1441 295 1484 295 1498 296 2 296 93 296 95 296 97 296 126 296 153 296 183 296 231 296 247 296 282 296 296 296 362 296 407 296 463 296 499 296 516 296 564 296 614 296 628 296 654 296 662 296 801 296 838 296 951 296 970 296 975 296 1001 296 1002 296 1036 296 1050 296 1105 296 1119 296 1122 296 1132 296 1194 296 1227 296 1280 296 1329 296 1354 296 1384 296 1394 296 1396 296 1478 297 16 297 71 297 136 297 150 297 177 297 207 297 213 297 248 297 252 297 274 297 297 297 317 297 390 297 423 297 432 297 469 297 548 297 588 297 632 297 641 297 706 297 738 297 744 297 848 297 889 297 936 297 964 297 977 297 1041 297 1053 297 1073 297 1130 297 1252 297 1255 297 1274 297 1284 297 1322 297 1328 297 1416 297 1422 297 1480 298 0 298 114 298 119 298 186 298 197 298 220 298 238 298 264 298 281 298 298 298 301 298 303 298 327 298 330 298 338 298 358 298 442 298 518 298 663 298 721 298 729 298 731 298 765 298 771 298 794 298 803 298 824 298 866 298 892 298 983 298 996 298 1011 298 1031 298 1052 298 1085 298 1124 298 1145 298 1147 298 1222 298 1228 298 1260 298 1266 298 1271 298 1305 298 1371 298 1400 298 1412 298 1488 299 10 299 33 299 50 299 61 299 68 299 141 299 155 299 169 299 195 299 210 299 299 299 300 299 342 299 364 299 379 299 447 299 458 299 493 299 504 299 514 299 559 299 571 299 578 299 704 299 749 299 811 299 904 299 913 299 915 299 930 299 956 299 1088 299 1109 299 1168 299 1189 299 1269 299 1275 299 1300 299 1312 299 1338 299 1374 299 1420 299 1437 299 1460 300 20 300 50 300 68 300 75 300 87 300 141 300 203 300 204 300 292 300 294 300 299 300 300 300 314 300 333 300 336 300 357 300 368 300 433 300 514 300 538 300 559 300 571 300 627 300 657 300 671 300 703 300 916 300 930 300 1029 300 1088 300 1100 300 1106 300 1169 300 1171 300 1188 300 1203 300 1300 300 1402 300 1404 300 1458 300 1460 300 1462 300 1490 301 0 301 98 301 114 301 151 301 185 301 186 301 197 301 220 301 235 301 238 301 251 301 264 301 281 301 298 301 301 301 303 301 358 301 442 301 480 301 518 301 546 301 597 301 645 301 663 301 674 301 689 301 699 301 721 301 729 301 771 301 803 301 824 301 995 301 996 301 1011 301 1031 301 1085 301 1145 301 1147 301 1266 301 1271 301 1305 301 1371 301 1400 302 39 302 112 302 166 302 168 302 208 302 215 302 254 302 302 302 409 302 410 302 426 302 633 302 710 302 899 302 954 302 976 302 989 302 1030 302 1134 302 1207 302 1233 302 1301 302 1310 302 1319 302 1405 303 6 303 25 303 42 303 45 303 48 303 70 303 108 303 186 303 238 303 256 303 273 303 281 303 298 303 301 303 303 303 339 303 367 303 438 303 512 303 575 303 635 303 722 303 729 303 731 303 782 303 794 303 803 303 810 303 824 303 961 303 996 303 1011 303 1031 303 1052 303 1085 303 1086 303 1147 303 1163 303 1201 303 1208 303 1228 303 1239 303 1263 303 1305 303 1362 303 1363 303 1399 303 1488 303 1499 304 17 304 129 304 133 304 172 304 180 304 255 304 261 304 283 304 304 304 322 304 328 304 363 304 394 304 395 304 399 304 522 304 537 304 575 304 590 304 594 304 634 304 681 304 695 304 767 304 776 304 786 304 795 304 884 304 969 304 980 304 992 304 1039 304 1125 304 1140 304 1141 304 1199 304 1209 304 1261 304 1351 304 1359 304 1468 305 47 305 76 305 83 305 135 305 189 305 217 305 232 305 253 305 305 305 344 305 455 305 478 305 591 305 612 305 684 305 690 305 743 305 807 305 814 305 822 305 839 305 860 305 940 305 978 305 990 305 1014 305 1018 305 1142 305 1180 305 1206 305 1216 305 1217 305 1235 305 1250 305 1290 305 1355 305 1356 305 1358 305 1370 305 1375 305 1498 306 74 306 88 306 95 306 113 306 132 306 173 306 201 306 227 306 231 306 239 306 241 306 306 306 386 306 420 306 461 306 471 306 488 306 515 306 525 306 553 306 554 306 566 306 659 306 668 306 696 306 723 306 748 306 798 306 804 306 818 306 858 306 924 306 975 306 1002 306 1096 306 1116 306 1122 306 1157 306 1192 306 1232 306 1248 306 1254 306 1259 306 1272 306 1280 306 1285 306 1303 306 1329 306 1391 307 32 307 34 307 40 307 115 307 139 307 207 307 237 307 274 307 307 307 366 307 439 307 453 307 495 307 744 307 813 307 833 307 835 307 848 307 853 307 859 307 868 307 869 307 926 307 1041 307 1061 307 1103 307 1110 307 1138 307 1237 307 1245 307 1247 307 1262 307 1276 307 1296 307 1347 307 1376 307 1381 307 1406 307 1482 308 53 308 78 308 82 308 102 308 130 308 191 308 200 308 211 308 270 308 286 308 308 308 348 308 349 308 399 308 428 308 451 308 460 308 511 308 549 308 579 308 610 308 626 308 631 308 658 308 685 308 702 308 752 308 761 308 812 308 829 308 846 308 863 308 884 308 901 308 923 308 1003 308 1057 308 1065 308 1066 308 1084 308 1131 308 1135 308 1137 308 1183 308 1418 308 1459 308 1475 308 1481 309 43 309 46 309 104 309 105 309 109 309 118 309 176 309 258 309 309 309 369 309 409 309 500 309 532 309 557 309 565 309 651 309 710 309 724 309 779 309 826 309 899 309 917 309 927 309 954 309 957 309 1030 309 1114 309 1128 309 1182 309 1243 309 1264 309 1279 309 1366 309 1368 309 1380 310 11 310 48 310 94 310 163 310 179 310 226 310 245 310 246 310 249 310 265 310 276 310 310 310 320 310 339 310 406 310 415 310 523 310 596 310 616 310 653 310 664 310 688 310 713 310 740 310 754 310 762 310 768 310 855 310 880 310 894 310 932 310 945 310 952 310 963 310 974 310 1022 310 1032 310 1045 310 1063 310 1081 310 1094 310 1139 310 1158 310 1163 310 1170 310 1181 310 1201 310 1239 310 1288 310 1335 310 1362 310 1453 311 84 311 93 311 95 311 120 311 194 311 201 311 231 311 239 311 241 311 271 311 275 311 282 311 293 311 311 311 315 311 361 311 372 311 450 311 515 311 564 311 647 311 677 311 719 311 858 311 971 311 975 311 1023 311 1036 311 1058 311 1116 311 1157 311 1248 311 1253 311 1280 311 1282 311 1307 311 1377 311 1394 311 1395 311 1424 311 1435 312 26 312 54 312 102 312 121 312 130 312 200 312 205 312 222 312 259 312 312 312 436 312 465 312 536 312 560 312 579 312 685 312 734 312 758 312 771 312 778 312 802 312 815 312 866 312 871 312 892 312 897 312 934 312 959 312 1035 312 1054 312 1066 312 1102 312 1113 312 1118 312 1124 312 1135 312 1212 312 1214 312 1221 312 1327 312 1330 312 1340 312 1343 312 1382 312 1400 312 1413 312 1419 312 1442 312 1463 312 1486 313 35 313 48 313 108 313 140 313 172 313 284 313 313 313 363 313 374 313 382 313 406 313 411 313 413 313 498 313 531 313 540 313 577 313 718 313 772 313 781 313 782 313 786 313 852 313 881 313 961 313 974 313 998 313 1049 313 1094 313 1123 313 1158 313 1164 313 1177 313 1223 313 1251 313 1292 313 1362 313 1363 314 50 314 68 314 75 314 141 314 195 314 210 314 294 314 300 314 314 314 333 314 342 314 357 314 368 314 379 314 433 314 504 314 514 314 538 314 571 314 627 314 666 314 697 314 704 314 811 314 904 314 916 314 930 314 1008 314 1029 314 1088 314 1100 314 1109 314 1203 314 1269 314 1300 314 1312 314 1338 314 1352 314 1374 314 1420 314 1437 314 1460 314 1495 315 74 315 84 315 93 315 95 315 113 315 120 315 201 315 231 315 239 315 241 315 271 315 275 315 293 315 311 315 315 315 384 315 450 315 463 315 488 315 515 315 554 315 564 315 675 315 719 315 801 315 838 315 858 315 971 315 975 315 1001 315 1023 315 1036 315 1050 315 1058 315 1116 315 1119 315 1122 315 1157 315 1248 315 1253 315 1280 315 1307 315 1354 315 1394 315 1395 315 1424 315 1435 316 142 316 157 316 316 316 709 316 819 316 877 316 914 316 1043 316 1121 316 1430 317 16 317 32 317 34 317 40 317 136 317 150 317 171 317 207 317 213 317 237 317 248 317 252 317 274 317 297 317 317 317 423 317 432 317 439 317 453 317 495 317 588 317 641 317 706 317 738 317 744 317 835 317 848 317 853 317 868 317 889 317 926 317 936 317 964 317 1041 317 1073 317 1130 317 1138 317 1237 317 1247 317 1255 317 1262 317 1274 317 1284 317 1296 317 1322 317 1328 317 1381 318 80 318 81 318 138 318 151 318 245 318 251 318 267 318 278 318 318 318 329 318 347 318 437 318 470 318 494 318 496 318 510 318 513 318 535 318 665 318 674 318 676 318 683 318 686 318 689 318 699 318 760 318 787 318 817 318 834 318 925 318 949 318 950 318 965 318 979 318 986 318 1009 318 1048 318 1070 318 1190 318 1215 318 1286 318 1304 318 1392 318 1408 318 1425 318 1445 318 1449 318 1465 318 1471 319 122 319 167 319 178 319 219 319 319 319 360 319 416 319 418 319 422 319 457 319 468 319 555 319 589 319 593 319 617 319 622 319 644 319 725 319 732 319 750 319 766 319 777 319 800 319 886 319 933 319 997 319 1010 319 1015 319 1087 319 1101 319 1112 319 1166 319 1185 319 1200 319 1205 319 1257 319 1268 319 1311 319 1346 319 1388 319 1426 319 1479 319 1492 320 100 320 140 320 163 320 226 320 246 320 310 320 320 320 393 320 417 320 445 320 596 320 616 320 653 320 672 320 688 320 712 320 740 320 754 320 762 320 772 320 806 320 855 320 856 320 880 320 932 320 945 320 963 320 974 320 998 320 1004 320 1042 320 1045 320 1049 320 1094 320 1139 320 1158 320 1163 320 1177 320 1181 320 1239 320 1306 320 1387 320 1438 320 1453 320 1470 320 1473 321 35 321 45 321 51 321 94 321 124 321 140 321 235 321 284 321 321 321 363 321 374 321 380 321 382 321 393 321 501 321 540 321 552 321 577 321 594 321 695 321 713 321 753 321 772 321 781 321 782 321 797 321 810 321 832 321 852 321 885 321 918 321 929 321 991 321 1120 321 1158 321 1208 321 1223 321 1251 321 1292 321 1339 321 1362 322 17 322 38 322 66 322 96 322 129 322 131 322 137 322 162 322 172 322 174 322 180 322 192 322 255 322 261 322 263 322 283 322 304 322 322 322 328 322 349 322 352 322 354 322 356 322 394 322 395 322 399 322 440 322 464 322 479 322 539 322 552 322 561 322 576 322 580 322 590 322 631 322 634 322 652 322 695 322 711 322 720 322 767 322 786 322 792 322 881 322 887 322 942 322 944 322 969 322 980 322 992 322 1047 322 1089 322 1092 322 1125 322 1140 322 1141 322 1173 322 1209 322 1238 322 1244 322 1261 322 1283 322 1332 322 1351 322 1353 322 1359 323 24 323 90 323 137 323 193 323 222 323 261 323 262 323 323 323 327 323 425 323 431 323 506 323 536 323 539 323 701 323 702 323 734 323 769 323 785 323 885 323 944 323 1003 323 1035 323 1064 323 1118 323 1135 323 1165 323 1178 323 1187 323 1219 323 1234 323 1238 323 1244 323 1334 323 1341 323 1353 323 1390 323 1401 323 1459 323 1486 324 74 324 113 324 132 324 201 324 227 324 241 324 275 324 324 324 386 324 420 324 474 324 515 324 581 324 659 324 677 324 728 324 737 324 788 324 798 324 818 324 1006 324 1093 324 1104 324 1116 324 1232 324 1259 324 1293 324 1391 325 24 325 116 325 145 325 174 325 180 325 206 325 325 325 348 325 429 325 431 325 444 325 522 325 539 325 552 325 568 325 576 325 580 325 590 325 646 325 652 325 708 325 714 325 769 325 771 325 776 325 885 325 897 325 944 325 980 325 985 325 992 325 1007 325 1046 325 1178 325 1204 325 1244 325 1261 325 1316 325 1339 325 1403 326 91 326 143 326 167 326 178 326 219 326 326 326 350 326 378 326 416 326 418 326 422 326 446 326 508 326 555 326 617 326 622 326 636 326 644 326 732 326 777 326 800 326 928 326 933 326 935 326 958 326 962 326 997 326 1010 326 1015 326 1087 326 1146 326 1154 326 1167 326 1200 326 1205 326 1211 326 1257 326 1268 326 1289 326 1294 326 1311 326 1326 326 1346 326 1388 326 1431 326 1479 327 24 327 26 327 90 327 222 327 298 327 323 327 327 327 425 327 436 327 442 327 465 327 475 327 518 327 629 327 701 327 734 327 758 327 771 327 824 327 866 327 934 327 1035 327 1085 327 1118 327 1124 327 1145 327 1147 327 1204 327 1266 327 1327 327 1400 327 1468 328 27 328 66 328 96 328 162 328 255 328 263 328 268 328 283 328 286 328 304 328 322 328 328 328 349 328 354 328 394 328 395 328 399 328 464 328 576 328 580 328 590 328 631 328 634 328 652 328 711 328 720 328 767 328 769 328 786 328 789 328 792 328 887 328 969 328 992 328 1059 328 1125 328 1140 328 1209 328 1238 328 1351 328 1414 328 1446 328 1499 329 81 329 99 329 106 329 225 329 226 329 245 329 249 329 318 329 329 329 337 329 347 329 393 329 417 329 445 329 487 329 510 329 535 329 550 329 585 329 596 329 602 329 653 329 656 329 754 329 762 329 820 329 922 329 968 329 979 329 1000 329 1042 329 1045 329 1070 329 1077 329 1175 329 1190 329 1241 329 1286 329 1288 329 1315 329 1317 329 1408 329 1428 329 1445 329 1449 329 1470 329 1471 330 8 330 19 330 69 330 119 330 152 330 197 330 298 330 330 330 338 330 427 330 442 330 518 330 599 330 628 330 655 330 765 330 794 330 866 330 892 330 951 330 1085 330 1133 330 1145 330 1147 330 1214 330 1222 330 1260 330 1371 330 1400 330 1412 330 1419 330 1455 331 4 331 71 331 155 331 248 331 331 331 469 331 519 331 632 331 716 331 738 331 977 331 1053 331 1073 331 1357 331 1367 331 1416 331 1423 331 1451 331 1480 332 26 332 53 332 78 332 82 332 86 332 102 332 191 332 193 332 200 332 211 332 233 332 250 332 267 332 270 332 277 332 332 332 355 332 405 332 451 332 537 332 563 332 579 332 626 332 658 332 755 332 812 332 846 332 863 332 884 332 901 332 934 332 959 332 1003 332 1024 332 1035 332 1054 332 1066 332 1135 332 1137 332 1204 332 1309 332 1314 332 1327 332 1341 332 1459 332 1467 332 1475 332 1485 332 1494 333 20 333 31 333 50 333 68 333 75 333 123 333 141 333 148 333 198 333 203 333 204 333 242 333 292 333 294 333 300 333 314 333 333 333 336 333 357 333 368 333 402 333 433 333 538 333 571 333 671 333 673 333 703 333 756 333 916 333 1088 333 1106 333 1112 333 1171 333 1184 333 1188 333 1203 333 1224 333 1300 333 1402 333 1404 333 1462 333 1490 334 84 334 88 334 166 334 173 334 209 334 334 334 420 334 426 334 461 334 471 334 472 334 477 334 488 334 489 334 553 334 554 334 572 334 659 334 675 334 696 334 710 334 723 334 818 334 899 334 917 334 924 334 1051 334 1062 334 1080 334 1096 334 1104 334 1115 334 1143 334 1191 334 1192 334 1254 334 1285 334 1293 334 1303 334 1405 334 1427 334 1469 335 59 335 67 335 161 335 190 335 335 335 414 335 435 335 774 335 840 335 857 335 1021 335 1231 335 1320 335 1365 335 1409 335 1432 335 1443 335 1454 335 1477 335 1491 335 1497 336 7 336 20 336 31 336 87 336 123 336 148 336 204 336 242 336 292 336 294 336 300 336 333 336 336 336 403 336 449 336 519 336 530 336 538 336 548 336 607 336 671 336 703 336 763 336 873 336 900 336 948 336 1005 336 1106 336 1161 336 1171 336 1184 336 1188 336 1224 336 1289 336 1326 336 1402 336 1404 336 1458 336 1464 336 1490 337 81 337 99 337 134 337 140 337 228 337 245 337 249 337 329 337 337 337 393 337 417 337 421 337 445 337 487 337 510 337 513 337 535 337 585 337 596 337 602 337 717 337 754 337 762 337 775 337 797 337 820 337 834 337 890 337 918 337 922 337 946 337 950 337 968 337 1000 337 1042 337 1048 337 1070 337 1077 337 1139 337 1190 337 1226 337 1241 337 1251 337 1286 337 1315 337 1408 337 1428 337 1445 337 1453 337 1470 337 1471 338 0 338 19 338 73 338 130 338 152 338 197 338 200 338 205 338 259 338 264 338 270 338 298 338 330 338 338 338 442 338 465 338 475 338 518 338 549 338 560 338 587 338 655 338 734 338 752 338 761 338 765 338 771 338 778 338 802 338 815 338 824 338 871 338 884 338 892 338 905 338 967 338 983 338 1085 338 1124 338 1145 338 1147 338 1212 338 1214 338 1266 338 1271 338 1305 338 1330 338 1343 338 1382 338 1400 338 1412 338 1413 339 11 339 21 339 29 339 41 339 48 339 70 339 80 339 94 339 151 339 179 339 199 339 225 339 245 339 256 339 276 339 278 339 303 339 310 339 339 339 347 339 380 339 419 339 437 339 459 339 496 339 509 339 545 339 635 339 664 339 665 339 682 339 713 339 760 339 768 339 782 339 787 339 790 339 810 339 821 339 828 339 845 339 880 339 912 339 929 339 949 339 950 339 952 339 1032 339 1033 339 1045 339 1052 339 1063 339 1081 339 1086 339 1152 339 1163 339 1170 339 1181 339 1190 339 1201 339 1208 339 1239 339 1241 339 1251 339 1288 339 1304 339 1335 339 1362 339 1399 339 1417 339 1465 340 129 340 180 340 192 340 255 340 269 340 340 340 352 340 394 340 395 340 506 340 590 340 700 340 745 340 767 340 769 340 851 340 969 340 1067 340 1089 340 1125 340 1155 340 1178 340 1187 340 1333 340 1415 340 1499 341 33 341 61 341 103 341 110 341 210 341 341 341 342 341 364 341 379 341 447 341 458 341 493 341 504 341 542 341 578 341 586 341 601 341 643 341 687 341 704 341 749 341 811 341 904 341 913 341 915 341 943 341 956 341 1095 341 1109 341 1168 341 1189 341 1269 341 1297 341 1312 341 1338 341 1420 341 1421 341 1437 341 1495 342 33 342 61 342 110 342 141 342 169 342 195 342 210 342 299 342 314 342 341 342 342 342 364 342 379 342 447 342 458 342 493 342 504 342 514 342 571 342 578 342 586 342 687 342 704 342 749 342 773 342 811 342 843 342 904 342 913 342 915 342 941 342 943 342 956 342 1008 342 1109 342 1168 342 1189 342 1269 342 1275 342 1312 342 1338 342 1345 342 1374 342 1420 342 1421 342 1437 342 1495 343 56 343 72 343 135 343 164 343 217 343 223 343 224 343 232 343 343 343 371 343 389 343 391 343 408 343 478 343 497 343 524 343 547 343 584 343 592 343 638 343 814 343 844 343 860 343 906 343 908 343 972 343 1034 343 1068 343 1078 343 1099 343 1142 343 1179 343 1180 343 1198 343 1229 343 1230 343 1299 343 1361 343 1373 343 1407 343 1441 343 1474 343 1496 344 44 344 57 344 147 344 149 344 189 344 253 344 305 344 344 344 375 344 388 344 397 344 404 344 491 344 556 344 591 344 684 344 733 344 743 344 799 344 807 344 860 344 893 344 990 344 993 344 1027 344 1069 344 1082 344 1136 344 1202 344 1217 344 1235 344 1250 344 1278 344 1355 344 1358 344 1375 344 1456 345 156 345 159 345 196 345 266 345 345 345 383 345 396 345 400 345 448 345 543 345 605 345 615 345 707 345 739 345 764 345 847 345 862 345 920 345 947 345 960 345 994 345 1037 345 1090 345 1126 345 1127 345 1172 345 1267 345 1324 345 1325 345 1386 345 1434 345 1436 345 1493 346 39 346 62 346 77 346 104 346 105 346 109 346 112 346 168 346 215 346 258 346 346 346 409 346 489 346 500 346 826 346 878 346 899 346 917 346 954 346 1025 346 1080 346 1104 346 1114 346 1128 346 1134 346 1148 346 1149 346 1207 346 1233 346 1270 346 1301 346 1310 346 1319 346 1350 346 1368 346 1383 347 11 347 81 347 106 347 151 347 225 347 276 347 278 347 318 347 329 347 339 347 347 347 419 347 430 347 437 347 496 347 509 347 510 347 513 347 529 347 535 347 545 347 665 347 682 347 699 347 713 347 760 347 787 347 820 347 821 347 828 347 912 347 949 347 950 347 986 347 996 347 1019 347 1033 347 1063 347 1070 347 1170 347 1175 347 1215 347 1241 347 1304 347 1408 347 1449 347 1465 347 1471 348 53 348 78 348 180 348 193 348 206 348 211 348 277 348 308 348 325 348 348 348 349 348 399 348 405 348 425 348 431 348 444 348 451 348 522 348 537 348 579 348 580 348 610 348 625 348 626 348 629 348 631 348 652 348 702 348 769 348 829 348 846 348 884 348 980 348 985 348 1003 348 1024 348 1046 348 1059 348 1064 348 1084 348 1135 348 1137 348 1141 348 1238 348 1261 348 1309 348 1316 348 1336 348 1351 348 1378 348 1459 348 1475 348 1481 348 1494 349 66 349 86 349 175 349 211 349 212 349 216 349 283 349 286 349 308 349 322 349 328 349 348 349 349 349 394 349 399 349 405 349 431 349 440 349 444 349 464 349 534 349 537 349 563 349 579 349 580 349 623 349 625 349 626 349 631 349 652 349 681 349 720 349 767 349 776 349 792 349 795 349 829 349 874 349 980 349 1046 349 1057 349 1059 349 1131 349 1137 349 1140 349 1141 349 1199 349 1209 349 1238 349 1249 349 1309 349 1316 349 1351 349 1390 349 1418 349 1475 349 1481 350 7 350 20 350 37 350 49 350 122 350 167 350 170 350 178 350 184 350 203 350 219 350 242 350 326 350 350 350 360 350 416 350 418 350 443 350 457 350 508 350 555 350 559 350 583 350 589 350 593 350 622 350 627 350 639 350 644 350 657 350 671 350 703 350 725 350 732 350 756 350 766 350 777 350 800 350 805 350 886 350 900 350 916 350 928 350 933 350 935 350 958 350 987 350 1010 350 1015 350 1029 350 1071 350 1087 350 1100 350 1101 350 1106 350 1154 350 1161 350 1166 350 1167 350 1171 350 1185 350 1200 350 1205 350 1211 350 1257 350 1268 350 1273 350 1289 350 1294 350 1311 350 1326 350 1388 350 1426 350 1431 350 1479 350 1490 351 15 351 58 351 121 351 158 351 182 351 221 351 229 351 257 351 262 351 285 351 351 351 381 351 428 351 462 351 485 351 490 351 533 351 534 351 536 351 610 351 618 351 619 351 698 351 701 351 808 351 823 351 827 351 837 351 864 351 1044 351 1065 351 1144 351 1153 351 1183 351 1219 351 1258 351 1340 351 1360 351 1448 351 1452 352 129 352 172 352 180 352 192 352 255 352 269 352 322 352 340 352 352 352 394 352 395 352 575 352 590 352 745 352 767 352 769 352 851 352 969 352 1067 352 1125 352 1140 352 1155 352 1209 352 1333 352 1415 353 2 353 111 353 113 353 117 353 132 353 241 353 247 353 275 353 293 353 353 353 362 353 372 353 384 353 386 353 415 353 450 353 466 353 474 353 516 353 554 353 566 353 647 353 793 353 794 353 796 353 982 353 1012 353 1051 353 1056 353 1105 353 1232 353 1253 353 1256 353 1298 353 1377 353 1385 353 1396 353 1447 354 96 354 255 354 322 354 328 354 354 354 394 354 399 354 440 354 479 354 552 354 561 354 580 354 631 354 634 354 652 354 711 354 720 354 786 354 792 354 829 354 874 354 887 354 942 354 969 354 1047 354 1092 354 1125 354 1140 354 1209 354 1238 354 1283 354 1332 354 1351 354 1414 355 26 355 116 355 206 355 233 355 244 355 267 355 283 355 332 355 355 355 399 355 425 355 444 355 475 355 482 355 625 355 629 355 646 355 652 355 708 355 755 355 776 355 795 355 921 355 931 355 986 355 995 355 1007 355 1079 355 1199 355 1204 355 1261 355 1266 355 1314 355 1316 355 1321 355 1339 355 1378 355 1403 355 1467 355 1485 355 1494 356 66 356 96 356 116 356 131 356 137 356 145 356 174 356 175 356 206 356 235 356 261 356 263 356 322 356 356 356 444 356 479 356 486 356 539 356 552 356 568 356 646 356 678 356 714 356 753 356 776 356 885 356 887 356 909 356 942 356 944 356 985 356 1017 356 1047 356 1072 356 1089 356 1120 356 1165 356 1173 356 1178 356 1204 356 1244 356 1261 356 1283 356 1339 356 1353 356 1372 356 1401 356 1411 357 10 357 50 357 68 357 75 357 128 357 141 357 184 357 198 357 203 357 210 357 290 357 294 357 300 357 314 357 333 357 357 357 368 357 376 357 402 357 433 357 457 357 503 357 538 357 551 357 559 357 571 357 578 357 601 357 627 357 657 357 666 357 673 357 703 357 725 357 756 357 898 357 916 357 930 357 1008 357 1020 357 1088 357 1100 357 1166 357 1188 357 1203 357 1300 357 1338 357 1374 357 1433 357 1457 357 1460 357 1462 357 1490 357 1492 358 0 358 21 358 51 358 80 358 98 358 114 358 151 358 186 358 220 358 235 358 238 358 251 358 256 358 264 358 276 358 281 358 298 358 301 358 358 358 367 358 412 358 437 358 442 358 467 358 546 358 594 358 597 358 663 358 674 358 689 358 699 358 721 358 729 358 731 358 760 358 768 358 803 358 821 358 824 358 828 358 912 358 996 358 1011 358 1031 358 1032 358 1033 358 1055 358 1063 358 1079 358 1085 358 1145 358 1147 358 1208 358 1305 358 1398 358 1465 358 1468 358 1487 358 1488 359 185 359 244 359 264 359 288 359 359 359 398 359 436 359 480 359 494 359 546 359 587 359 597 359 598 359 646 359 650 359 676 359 683 359 758 359 771 359 842 359 895 359 897 359 1079 359 1113 359 1218 359 1413 359 1417 359 1440 359 1467 359 1487 360 37 360 49 360 75 360 122 360 128 360 167 360 178 360 198 360 203 360 219 360 242 360 290 360 319 360 350 360 360 360 402 360 416 360 418 360 443 360 457 360 551 360 555 360 582 360 589 360 593 360 622 360 639 360 644 360 657 360 671 360 673 360 703 360 756 360 770 360 777 360 800 360 805 360 886 360 916 360 928 360 933 360 935 360 955 360 958 360 1015 360 1020 360 1087 360 1101 360 1106 360 1107 360 1161 360 1166 360 1167 360 1171 360 1185 360 1200 360 1203 360 1205 360 1211 360 1257 360 1268 360 1289 360 1311 360 1388 360 1426 360 1431 360 1433 360 1479 361 84 361 120 361 239 361 271 361 275 361 293 361 311 361 361 361 372 361 647 361 677 361 719 361 793 361 858 361 971 361 1006 361 1023 361 1056 361 1058 361 1253 361 1307 361 1377 361 1394 361 1395 361 1424 361 1435 362 2 362 25 362 93 362 95 362 97 362 111 362 113 362 126 362 153 362 194 362 197 362 227 362 231 362 241 362 247 362 282 362 296 362 353 362 362 362 384 362 450 362 454 362 463 362 481 362 499 362 516 362 554 362 564 362 566 362 654 362 662 362 670 362 675 362 796 362 970 362 982 362 1001 362 1012 362 1036 362 1050 362 1083 362 1105 362 1116 362 1119 362 1122 362 1186 362 1194 362 1248 362 1256 362 1280 362 1302 362 1329 362 1354 362 1384 362 1385 362 1396 362 1447 362 1478 363 35 363 108 363 140 363 255 363 273 363 304 363 313 363 321 363 363 363 374 363 382 363 413 363 438 363 512 363 540 363 577 363 594 363 634 363 635 363 695 363 772 363 781 363 782 363 786 363 852 363 961 363 998 363 1123 363 1164 363 1177 363 1223 363 1399 363 1466 364 10 364 33 364 50 364 61 364 110 364 141 364 169 364 299 364 341 364 342 364 364 364 379 364 447 364 458 364 493 364 504 364 514 364 578 364 586 364 687 364 704 364 749 364 773 364 811 364 843 364 904 364 913 364 915 364 941 364 943 364 956 364 1095 364 1109 364 1168 364 1189 364 1269 364 1297 364 1312 364 1338 364 1345 364 1420 364 1421 364 1437 364 1495 365 5 365 12 365 52 365 65 365 85 365 202 365 230 365 240 365 291 365 365 365 434 365 569 365 630 365 642 365 730 365 742 365 1018 365 1028 365 1076 365 1129 365 1159 365 1265 365 1331 365 1369 365 1461 365 1472 365 1476 366 32 366 40 366 115 366 139 366 150 366 171 366 177 366 237 366 307 366 366 366 453 366 833 366 835 366 848 366 859 366 869 366 926 366 1041 366 1061 366 1103 366 1138 366 1237 366 1245 366 1247 366 1262 366 1276 366 1296 366 1376 366 1381 366 1406 366 1482 367 0 367 29 367 51 367 98 367 186 367 220 367 238 367 256 367 278 367 281 367 303 367 358 367 367 367 419 367 437 367 438 367 597 367 645 367 661 367 682 367 683 367 699 367 729 367 731 367 760 367 821 367 845 367 872 367 996 367 1011 367 1083 367 1085 367 1197 367 1263 367 1305 367 1371 367 1398 367 1417 367 1440 367 1487 368 49 368 50 368 68 368 75 368 141 368 198 368 203 368 210 368 294 368 300 368 314 368 333 368 357 368 368 368 433 368 443 368 538 368 551 368 571 368 582 368 657 368 671 368 673 368 697 368 756 368 805 368 836 368 916 368 930 368 1088 368 1100 368 1107 368 1203 368 1300 368 1323 368 1364 368 1374 368 1460 368 1483 368 1490 369 43 369 46 369 60 369 104 369 118 369 154 369 176 369 287 369 309 369 369 369 385 369 456 369 500 369 541 369 557 369 565 369 633 369 724 369 747 369 779 369 861 369 902 369 927 369 957 369 1013 369 1128 369 1150 369 1182 369 1210 369 1243 369 1279 369 1295 369 1366 369 1380 369 1439 369 1489 370 44 370 57 370 72 370 76 370 135 370 144 370 149 370 224 370 232 370 370 370 375 370 388 370 397 370 401 370 424 370 455 370 491 370 520 370 584 370 591 370 611 370 733 370 860 370 893 370 990 370 993 370 1136 370 1179 370 1235 370 1358 370 1393 371 47 371 83 371 223 371 224 371 234 371 279 371 295 371 343 371 371 371 377 371 389 371 408 371 478 371 483 371 544 371 547 371 592 371 600 371 603 371 640 371 648 371 690 371 694 371 784 371 807 371 814 371 839 371 875 371 882 371 910 371 940 371 972 371 978 371 1068 371 1078 371 1099 371 1142 371 1180 371 1236 371 1277 371 1281 371 1361 371 1373 371 1407 371 1441 371 1474 371 1496 372 113 372 117 372 194 372 201 372 239 372 241 372 247 372 275 372 293 372 311 372 353 372 361 372 372 372 384 372 415 372 450 372 523 372 647 372 675 372 719 372 793 372 845 372 971 372 973 372 1036 372 1056 372 1105 372 1248 372 1253 372 1302 372 1307 372 1377 372 1447 373 14 373 79 373 92 373 125 373 160 373 189 373 230 373 272 373 279 373 295 373 373 373 387 373 441 373 483 373 484 373 491 373 520 373 526 373 556 373 569 373 600 373 606 373 611 373 612 373 624 373 630 373 638 373 640 373 684 373 690 373 694 373 807 373 809 373 844 373 867 373 882 373 910 373 911 373 978 373 990 373 999 373 1014 373 1018 373 1075 373 1076 373 1082 373 1099 373 1196 373 1206 373 1236 373 1277 373 1355 373 1370 373 1375 373 1441 373 1476 373 1484 374 6 374 35 374 41 374 140 374 162 374 172 374 188 374 199 374 284 374 313 374 321 374 363 374 374 374 380 374 382 374 406 374 411 374 413 374 498 374 521 374 540 374 577 374 594 374 695 374 718 374 772 374 781 374 782 374 786 374 790 374 852 374 929 374 961 374 1049 374 1094 374 1158 374 1164 374 1201 374 1223 374 1251 374 1304 374 1363 375 44 375 57 375 76 375 147 375 149 375 344 375 370 375 375 375 388 375 733 375 799 375 893 375 993 375 1027 375 1136 375 1202 375 1278 375 1358 375 1456 376 10 376 23 376 37 376 49 376 103 376 184 376 198 376 210 376 290 376 357 376 376 376 443 376 457 376 503 376 517 376 542 376 551 376 555 376 559 376 573 376 582 376 589 376 601 376 622 376 627 376 657 376 666 376 704 376 725 376 750 376 756 376 766 376 770 376 800 376 805 376 886 376 898 376 933 376 1008 376 1020 376 1087 376 1088 376 1095 376 1107 376 1166 376 1185 376 1300 376 1364 376 1429 376 1433 376 1457 376 1483 376 1492 377 13 377 47 377 55 377 65 377 83 377 160 377 218 377 223 377 224 377 234 377 291 377 371 377 377 377 441 377 452 377 492 377 497 377 528 377 544 377 547 377 562 377 592 377 603 377 609 377 612 377 620 377 630 377 640 377 648 377 882 377 883 377 939 377 1076 377 1078 377 1091 377 1099 377 1159 377 1225 377 1361 377 1373 377 1474 377 1496 378 22 378 107 378 143 378 156 378 167 378 178 378 219 378 266 378 326 378 378 378 446 378 449 378 507 378 530 378 543 378 558 378 570 378 604 378 607 378 613 378 617 378 621 378 636 378 644 378 669 378 739 378 777 378 791 378 854 378 862 378 873 378 900 378 903 378 935 378 937 378 948 378 958 378 962 378 994 378 1010 378 1071 378 1090 378 1106 378 1146 378 1154 378 1162 378 1176 378 1184 378 1224 378 1289 378 1294 378 1311 378 1324 378 1326 378 1386 378 1431 378 1444 378 1464 379 10 379 33 379 50 379 61 379 68 379 110 379 141 379 169 379 195 379 299 379 314 379 341 379 342 379 364 379 379 379 447 379 458 379 493 379 504 379 514 379 571 379 578 379 586 379 687 379 704 379 749 379 811 379 904 379 913 379 915 379 943 379 956 379 1109 379 1168 379 1189 379 1269 379 1275 379 1312 379 1338 379 1374 379 1420 379 1437 379 1495 380 28 380 29 380 41 380 45 380 51 380 151 380 199 380 284 380 321 380 339 380 374 380 380 380 459 380 470 380 494 380 501 380 505 380 510 380 575 380 594 380 661 380 676 380 683 380 708 380 715 380 726 380 729 380 790 380 895 380 896 380 921 380 929 380 931 380 950 380 965 380 986 380 1007 380 1060 380 1086 380 1152 380 1160 380 1164 380 1304 380 1417 380 1471 380 1487 381 9 381 15 381 54 381 158 381 182 381 205 381 221 381 229 381 285 381 351 381 381 381 462 381 473 381 485 381 490 381 618 381 735 381 823 381 827 381 837 381 849 381 864 381 1044 381 1144 381 1153 381 1258 381 1389 381 1448 381 1452 381 1463 382 6 382 35 382 41 382 94 382 140 382 172 382 188 382 199 382 283 382 284 382 313 382 321 382 363 382 374 382 382 382 406 382 411 382 413 382 487 382 498 382 501 382 510 382 540 382 577 382 681 382 686 382 695 382 713 382 718 382 772 382 781 382 782 382 786 382 790 382 810 382 831 382 852 382 865 382 896 382 929 382 961 382 1048 382 1049 382 1081 382 1094 382 1158 382 1164 382 1201 382 1223 382 1251 382 1363 382 1425 383 136 383 159 383 196 383 252 383 345 383 383 383 400 383 448 383 605 383 615 383 707 383 739 383 783 383 847 383 920 383 947 383 960 383 1090 383 1126 383 1172 383 1174 383 1284 383 1325 383 1386 383 1434 383 1436 384 2 384 97 384 111 384 113 384 117 384 153 384 194 384 197 384 241 384 247 384 275 384 315 384 353 384 362 384 372 384 384 384 386 384 450 384 463 384 488 384 554 384 566 384 670 384 675 384 796 384 970 384 1001 384 1012 384 1036 384 1105 384 1119 384 1122 384 1186 384 1194 384 1248 384 1253 384 1256 384 1302 384 1329 384 1384 384 1391 384 1396 384 1447 384 1478 385 43 385 46 385 60 385 77 385 118 385 154 385 176 385 208 385 280 385 287 385 369 385 385 385 410 385 456 385 541 385 557 385 565 385 633 385 724 385 747 385 779 385 861 385 891 385 902 385 927 385 957 385 976 385 1013 385 1030 385 1128 385 1150 385 1210 385 1243 385 1279 385 1295 385 1366 385 1380 385 1439 385 1489 386 113 386 132 386 201 386 227 386 231 386 241 386 306 386 324 386 353 386 384 386 386 386 474 386 481 386 515 386 554 386 566 386 581 386 696 386 798 386 924 386 1002 386 1116 386 1119 386 1122 386 1232 386 1259 386 1272 386 1280 386 1285 386 1391 386 1478 387 14 387 63 387 92 387 125 387 135 387 160 387 189 387 223 387 230 387 272 387 279 387 295 387 373 387 387 387 391 387 441 387 483 387 520 387 556 387 569 387 600 387 611 387 624 387 630 387 640 387 690 387 694 387 784 387 807 387 809 387 839 387 844 387 888 387 910 387 911 387 940 387 999 387 1014 387 1018 387 1069 387 1075 387 1082 387 1097 387 1099 387 1108 387 1180 387 1196 387 1206 387 1230 387 1277 387 1281 387 1370 387 1441 387 1472 387 1474 387 1476 387 1484 388 44 388 57 388 76 388 147 388 149 388 344 388 370 388 375 388 388 388 397 388 424 388 455 388 491 388 733 388 799 388 860 388 893 388 993 388 1027 388 1136 388 1179 388 1202 388 1235 388 1278 388 1358 388 1393 388 1456 389 72 389 135 389 144 389 149 389 217 389 223 389 224 389 232 389 253 389 279 389 343 389 371 389 389 389 391 389 397 389 408 389 478 389 483 389 584 389 592 389 638 389 680 389 784 389 814 389 839 389 844 389 860 389 906 389 911 389 940 389 972 389 978 389 1034 389 1068 389 1078 389 1099 389 1142 389 1180 389 1198 389 1217 389 1229 389 1230 389 1281 389 1361 389 1373 389 1407 389 1441 389 1474 389 1496 390 71 390 159 390 248 390 252 390 274 390 297 390 390 390 423 390 432 390 448 390 469 390 548 390 588 390 641 390 706 390 707 390 738 390 764 390 960 390 964 390 977 390 1005 390 1037 390 1126 390 1130 390 1172 390 1174 390 1252 390 1274 390 1287 390 1324 390 1328 390 1386 390 1416 390 1422 390 1434 390 1436 390 1493 391 36 391 56 391 72 391 101 391 135 391 164 391 230 391 279 391 343 391 387 391 389 391 391 391 408 391 520 391 524 391 547 391 592 391 600 391 611 391 638 391 680 391 784 391 822 391 839 391 844 391 906 391 911 391 940 391 972 391 1034 391 1068 391 1097 391 1099 391 1180 391 1198 391 1206 391 1230 391 1277 391 1281 391 1299 391 1373 391 1393 391 1407 391 1441 391 1474 392 6 392 42 392 45 392 48 392 66 392 89 392 124 392 127 392 131 392 228 392 243 392 392 392 459 392 470 392 486 392 501 392 502 392 513 392 535 392 576 392 649 392 678 392 679 392 689 392 726 392 746 392 753 392 757 392 775 392 786 392 797 392 810 392 830 392 831 392 879 392 896 392 921 392 929 392 946 392 961 392 968 392 1016 392 1039 392 1072 392 1160 392 1173 392 1201 392 1213 392 1349 392 1353 392 1372 392 1449 393 100 393 127 393 134 393 138 393 140 393 246 393 260 393 320 393 321 393 329 393 337 393 393 393 406 393 417 393 421 393 445 393 487 393 501 393 513 393 521 393 585 393 596 393 679 393 688 393 717 393 726 393 741 393 746 393 754 393 762 393 772 393 775 393 781 393 790 393 797 393 806 393 834 393 918 393 922 393 945 393 946 393 968 393 998 393 1000 393 1042 393 1048 393 1049 393 1077 393 1094 393 1139 393 1158 393 1181 393 1223 393 1226 393 1241 393 1286 393 1315 393 1387 393 1408 393 1428 393 1438 393 1445 393 1453 393 1470 394 17 394 66 394 96 394 129 394 162 394 172 394 174 394 180 394 216 394 255 394 261 394 263 394 283 394 304 394 322 394 328 394 340 394 349 394 352 394 354 394 394 394 395 394 399 394 440 394 444 394 464 394 479 394 575 394 576 394 580 394 590 394 625 394 631 394 634 394 652 394 681 394 695 394 711 394 720 394 745 394 767 394 786 394 792 394 795 394 829 394 874 394 881 394 887 394 942 394 969 394 980 394 992 394 1047 394 1059 394 1067 394 1092 394 1125 394 1140 394 1141 394 1155 394 1173 394 1199 394 1209 394 1213 394 1238 394 1244 394 1283 394 1316 394 1332 394 1351 395 17 395 129 395 133 395 145 395 172 395 180 395 192 395 255 395 283 395 304 395 322 395 328 395 340 395 352 395 394 395 395 395 399 395 531 395 561 395 576 395 590 395 634 395 652 395 681 395 695 395 745 395 767 395 769 395 851 395 969 395 980 395 992 395 1039 395 1125 395 1140 395 1155 395 1209 395 1333 395 1351 395 1415 395 1499 396 22 396 156 396 266 396 345 396 396 396 449 396 530 396 543 396 583 396 604 396 613 396 621 396 669 396 691 396 727 396 739 396 841 396 854 396 873 396 903 396 919 396 920 396 948 396 960 396 987 396 994 396 1005 396 1037 396 1038 396 1090 396 1151 396 1267 396 1287 396 1324 396 1325 396 1436 396 1444 396 1450 397 44 397 57 397 72 397 76 397 135 397 144 397 149 397 217 397 224 397 232 397 253 397 344 397 370 397 388 397 389 397 397 397 401 397 424 397 455 397 478 397 491 397 520 397 556 397 584 397 591 397 611 397 733 397 860 397 893 397 990 397 993 397 1136 397 1142 397 1179 397 1230 397 1235 397 1278 397 1290 397 1358 397 1393 397 1456 398 0 398 98 398 185 398 264 398 281 398 288 398 359 398 398 398 436 398 442 398 475 398 480 398 518 398 546 398 587 398 598 398 645 398 650 398 663 398 674 398 676 398 683 398 758 398 771 398 824 398 842 398 866 398 895 398 1079 398 1085 398 1197 398 1218 398 1266 398 1271 398 1305 398 1318 398 1371 398 1412 398 1413 398 1440 399 17 399 268 399 283 399 286 399 304 399 308 399 322 399 328 399 348 399 349 399 354 399 355 399 394 399 395 399 399 399 440 399 444 399 460 399 464 399 561 399 575 399 580 399 590 399 625 399 631 399 634 399 652 399 681 399 695 399 720 399 786 399 795 399 829 399 865 399 969 399 980 399 992 399 1007 399 1059 399 1125 399 1131 399 1137 399 1140 399 1141 399 1199 399 1209 399 1238 399 1316 399 1351 399 1378 399 1467 399 1481 400 156 400 159 400 196 400 252 400 266 400 345 400 383 400 400 400 448 400 605 400 615 400 707 400 739 400 783 400 847 400 854 400 920 400 947 400 960 400 1037 400 1090 400 1126 400 1172 400 1174 400 1267 400 1325 400 1386 400 1434 400 1436 401 72 401 76 401 135 401 144 401 189 401 217 401 232 401 295 401 370 401 397 401 401 401 424 401 455 401 478 401 520 401 526 401 556 401 591 401 611 401 684 401 733 401 784 401 822 401 839 401 911 401 940 401 978 401 990 401 1014 401 1142 401 1179 401 1216 401 1230 401 1235 401 1281 401 1290 401 1375 401 1393 401 1498 402 20 402 31 402 37 402 75 402 123 402 128 402 170 402 198 402 290 402 333 402 357 402 360 402 402 402 433 402 457 402 538 402 551 402 555 402 559 402 593 402 622 402 657 402 673 402 703 402 736 402 756 402 886 402 916 402 933 402 997 402 1020 402 1100 402 1106 402 1112 402 1166 402 1203 402 1257 402 1311 402 1426 402 1433 402 1457 402 1462 402 1490 403 20 403 22 403 87 403 156 403 204 403 266 403 292 403 336 403 403 403 449 403 530 403 543 403 583 403 621 403 763 403 764 403 873 403 948 403 994 403 1005 403 1037 403 1169 403 1184 403 1188 403 1224 403 1287 403 1324 403 1326 403 1386 403 1404 403 1458 403 1493 404 14 404 47 404 63 404 79 404 125 404 160 404 240 404 253 404 272 404 295 404 344 404 404 404 466 404 484 404 526 404 556 404 624 404 694 404 743 404 807 404 809 404 875 404 882 404 888 404 910 404 990 404 1069 404 1075 404 1082 404 1097 404 1196 404 1355 404 1375 405 26 405 53 405 58 405 66 405 78 405 82 405 86 405 102 405 191 405 193 405 200 405 206 405 211 405 233 405 250 405 277 405 332 405 348 405 349 405 405 405 428 405 431 405 444 405 451 405 465 405 533 405 534 405 563 405 579 405 580 405 625 405 626 405 658 405 702 405 720 405 846 405 863 405 901 405 959 405 1003 405 1024 405 1035 405 1046 405 1054 405 1064 405 1113 405 1131 405 1135 405 1137 405 1309 405 1327 405 1340 405 1341 405 1475 405 1481 405 1494 406 6 406 35 406 41 406 42 406 48 406 81 406 94 406 100 406 140 406 179 406 188 406 226 406 246 406 276 406 310 406 313 406 374 406 382 406 393 406 406 406 487 406 521 406 540 406 577 406 596 406 688 406 713 406 718 406 754 406 762 406 772 406 781 406 782 406 790 406 806 406 810 406 831 406 918 406 929 406 945 406 961 406 963 406 974 406 998 406 1045 406 1048 406 1049 406 1052 406 1081 406 1094 406 1139 406 1158 406 1181 406 1201 406 1223 406 1251 406 1363 406 1425 406 1453 407 3 407 8 407 19 407 64 407 97 407 119 407 153 407 183 407 197 407 296 407 407 407 427 407 499 407 614 407 628 407 660 407 662 407 709 407 765 407 816 407 849 407 951 407 1002 407 1050 407 1132 407 1133 407 1186 407 1227 407 1242 407 1260 407 1354 407 1384 408 14 408 47 408 56 408 79 408 164 408 223 408 279 408 295 408 343 408 371 408 389 408 391 408 408 408 434 408 478 408 483 408 524 408 526 408 547 408 567 408 592 408 606 408 638 408 680 408 784 408 814 408 822 408 839 408 844 408 867 408 906 408 908 408 940 408 972 408 978 408 1018 408 1034 408 1068 408 1076 408 1097 408 1098 408 1142 408 1180 408 1198 408 1206 408 1216 408 1229 408 1236 408 1281 408 1299 408 1361 408 1370 408 1373 408 1375 408 1407 408 1441 408 1474 408 1498 409 39 409 104 409 109 409 112 409 166 409 168 409 215 409 258 409 302 409 309 409 346 409 409 409 426 409 477 409 489 409 710 409 899 409 917 409 954 409 989 409 1080 409 1114 409 1128 409 1134 409 1148 409 1207 409 1233 409 1301 409 1319 409 1368 409 1380 409 1405 409 1469 410 39 410 60 410 77 410 109 410 112 410 154 410 176 410 208 410 215 410 254 410 280 410 302 410 385 410 410 410 456 410 500 410 541 410 633 410 651 410 724 410 747 410 779 410 826 410 861 410 878 410 891 410 927 410 954 410 957 410 976 410 989 410 1013 410 1025 410 1030 410 1128 410 1134 410 1148 410 1207 410 1210 410 1295 410 1301 410 1310 410 1383 410 1439 411 35 411 134 411 140 411 313 411 374 411 382 411 411 411 413 411 498 411 521 411 577 411 718 411 741 411 772 411 781 411 890 411 918 411 998 411 1049 411 1123 411 1164 411 1292 412 21 412 51 412 80 412 98 412 225 412 226 412 245 412 251 412 256 412 276 412 278 412 358 412 412 412 419 412 437 412 445 412 496 412 509 412 535 412 545 412 602 412 663 412 665 412 692 412 699 412 729 412 768 412 821 412 828 412 912 412 938 412 949 412 952 412 966 412 1011 412 1012 412 1032 412 1033 412 1045 412 1055 412 1083 412 1170 412 1208 412 1288 413 6 413 42 413 45 413 48 413 108 413 124 413 140 413 313 413 363 413 374 413 382 413 411 413 413 413 521 413 531 413 634 413 635 413 688 413 740 413 741 413 746 413 772 413 781 413 782 413 786 413 852 413 961 413 991 413 998 413 1049 413 1081 413 1094 413 1123 413 1139 413 1164 413 1181 413 1201 413 1213 413 1362 413 1453 414 59 414 67 414 161 414 190 414 335 414 414 414 435 414 691 414 727 414 774 414 840 414 841 414 857 414 919 414 953 414 1021 414 1231 414 1320 414 1365 414 1409 414 1432 414 1443 414 1454 414 1477 414 1491 414 1497 415 163 415 181 415 246 415 310 415 353 415 372 415 415 415 476 415 523 415 647 415 712 415 793 415 850 415 894 415 932 415 963 415 974 415 1004 415 1117 415 1306 415 1307 415 1342 415 1377 416 91 416 143 416 167 416 178 416 219 416 319 416 326 416 350 416 360 416 416 416 418 416 422 416 457 416 508 416 555 416 589 416 593 416 617 416 622 416 644 416 732 416 777 416 800 416 886 416 928 416 933 416 935 416 958 416 997 416 1010 416 1015 416 1087 416 1112 416 1146 416 1154 416 1161 416 1166 416 1167 416 1171 416 1200 416 1205 416 1211 416 1257 416 1268 416 1289 416 1294 416 1311 416 1346 416 1388 416 1426 416 1431 416 1479 417 1 417 100 417 134 417 140 417 246 417 260 417 265 417 320 417 329 417 337 417 393 417 417 417 421 417 445 417 487 417 596 417 616 417 672 417 717 417 754 417 762 417 772 417 806 417 856 417 918 417 922 417 945 417 1042 417 1045 417 1074 417 1077 417 1139 417 1158 417 1181 417 1195 417 1226 417 1241 417 1315 417 1342 417 1387 417 1397 417 1428 417 1438 417 1445 417 1453 417 1470 418 37 418 91 418 167 418 170 418 178 418 219 418 242 418 319 418 326 418 350 418 360 418 416 418 418 418 422 418 508 418 555 418 593 418 617 418 622 418 644 418 703 418 732 418 777 418 800 418 886 418 900 418 928 418 933 418 935 418 958 418 997 418 1010 418 1015 418 1071 418 1087 418 1106 418 1112 418 1146 418 1154 418 1161 418 1167 418 1171 418 1200 418 1205 418 1211 418 1257 418 1268 418 1289 418 1294 418 1311 418 1346 418 1388 418 1426 418 1431 418 1479 419 51 419 80 419 98 419 151 419 185 419 186 419 199 419 225 419 245 419 278 419 339 419 347 419 367 419 412 419 419 419 430 419 437 419 480 419 496 419 509 419 529 419 545 419 597 419 645 419 661 419 663 419 665 419 676 419 682 419 699 419 713 419 729 419 760 419 768 419 821 419 828 419 842 419 912 419 949 419 952 419 996 419 1011 419 1019 419 1022 419 1033 419 1060 419 1063 419 1152 419 1190 419 1197 419 1208 419 1215 419 1398 419 1417 419 1440 419 1465 419 1487 420 74 420 84 420 88 420 173 420 209 420 306 420 324 420 334 420 420 420 461 420 471 420 472 420 474 420 477 420 488 420 525 420 553 420 554 420 572 420 581 420 659 420 668 420 675 420 696 420 723 420 728 420 737 420 748 420 788 420 798 420 804 420 818 420 924 420 1062 420 1080 420 1093 420 1096 420 1104 420 1115 420 1143 420 1192 420 1254 420 1272 420 1285 420 1293 420 1303 420 1391 420 1469 421 1 421 100 421 260 421 265 421 337 421 393 421 417 421 421 421 596 421 616 421 672 421 717 421 754 421 762 421 806 421 945 421 1042 421 1074 421 1077 421 1139 421 1195 421 1226 421 1315 421 1317 421 1337 421 1342 421 1397 421 1428 421 1453 421 1470 421 1473 422 122 422 143 422 167 422 178 422 219 422 319 422 326 422 416 422 418 422 422 422 457 422 555 422 593 422 617 422 622 422 636 422 644 422 732 422 777 422 933 422 958 422 962 422 997 422 1010 422 1015 422 1101 422 1112 422 1154 422 1166 422 1185 422 1257 422 1294 422 1311 422 1346 422 1426 422 1433 422 1479 423 34 423 71 423 136 423 150 423 171 423 207 423 213 423 237 423 248 423 252 423 297 423 317 423 390 423 423 423 432 423 439 423 469 423 495 423 548 423 588 423 641 423 706 423 738 423 813 423 868 423 889 423 936 423 964 423 977 423 1041 423 1053 423 1110 423 1130 423 1138 423 1237 423 1255 423 1274 423 1284 423 1322 423 1328 423 1376 423 1416 423 1422 424 57 424 72 424 76 424 135 424 144 424 149 424 217 424 232 424 370 424 388 424 397 424 401 424 424 424 455 424 478 424 520 424 584 424 591 424 611 424 733 424 860 424 893 424 940 424 1136 424 1142 424 1179 424 1230 424 1235 424 1358 424 1393 425 24 425 116 425 193 425 206 425 267 425 323 425 327 425 348 425 355 425 425 425 429 425 475 425 502 425 539 425 625 425 678 425 708 425 776 425 885 425 896 425 934 425 938 425 985 425 1007 425 1064 425 1124 425 1135 425 1165 425 1204 425 1244 425 1266 425 1316 425 1339 425 1341 425 1403 426 62 426 105 426 166 426 168 426 173 426 215 426 254 426 302 426 334 426 409 426 426 426 472 426 477 426 489 426 572 426 710 426 723 426 826 426 899 426 917 426 954 426 1104 426 1114 426 1143 426 1149 426 1207 426 1233 426 1319 426 1383 426 1405 426 1427 426 1469 427 8 427 69 427 111 427 119 427 330 427 407 427 427 427 442 427 454 427 499 427 516 427 628 427 765 427 780 427 794 427 951 427 1083 427 1133 427 1194 427 1222 427 1260 427 1298 427 1396 428 38 428 53 428 58 428 78 428 82 428 102 428 191 428 211 428 212 428 216 428 229 428 257 428 262 428 308 428 351 428 405 428 428 428 451 428 464 428 511 428 533 428 534 428 549 428 579 428 610 428 619 428 626 428 637 428 658 428 720 428 812 428 829 428 863 428 874 428 901 428 923 428 1003 428 1017 428 1024 428 1065 428 1084 428 1135 428 1183 428 1219 428 1234 428 1238 428 1249 428 1336 428 1351 428 1360 428 1459 428 1481 429 24 429 116 429 145 429 325 429 425 429 429 429 475 429 539 429 629 429 646 429 689 429 776 429 885 429 944 429 985 429 992 429 1039 429 1046 429 1204 429 1339 429 1349 429 1403 429 1468 429 1499 430 41 430 80 430 81 430 99 430 106 430 151 430 179 430 188 430 199 430 245 430 347 430 419 430 430 430 480 430 487 430 510 430 529 430 550 430 585 430 602 430 661 430 665 430 674 430 682 430 760 430 768 430 820 430 821 430 842 430 949 430 952 430 986 430 1019 430 1022 430 1032 430 1060 430 1063 430 1070 430 1152 430 1175 430 1190 430 1223 430 1251 430 1304 430 1318 430 1408 430 1465 431 38 431 53 431 58 431 86 431 211 431 212 431 216 431 261 431 262 431 323 431 325 431 348 431 349 431 405 431 431 431 444 431 451 431 464 431 506 431 522 431 534 431 549 431 580 431 626 431 637 431 646 431 652 431 702 431 767 431 776 431 792 431 808 431 897 431 923 431 944 431 980 431 1024 431 1046 431 1065 431 1084 431 1135 431 1137 431 1219 431 1238 431 1249 431 1309 431 1316 431 1336 431 1359 431 1418 431 1481 432 16 432 71 432 136 432 150 432 159 432 207 432 213 432 248 432 252 432 274 432 297 432 317 432 390 432 423 432 432 432 439 432 469 432 519 432 548 432 588 432 632 432 641 432 706 432 738 432 889 432 936 432 964 432 977 432 1053 432 1073 432 1130 432 1252 432 1255 432 1274 432 1284 432 1322 432 1328 432 1381 432 1416 432 1422 432 1480 433 50 433 68 433 75 433 141 433 203 433 210 433 294 433 300 433 314 433 333 433 357 433 368 433 402 433 433 433 514 433 538 433 551 433 559 433 571 433 627 433 657 433 673 433 697 433 916 433 930 433 1029 433 1088 433 1100 433 1188 433 1203 433 1300 433 1338 433 1364 433 1433 433 1460 433 1462 433 1490 433 1495 434 5 434 12 434 13 434 14 434 47 434 65 434 92 434 160 434 165 434 218 434 234 434 240 434 291 434 365 434 408 434 434 434 441 434 452 434 528 434 569 434 603 434 606 434 608 434 612 434 624 434 630 434 648 434 730 434 809 434 882 434 883 434 939 434 1018 434 1028 434 1075 434 1076 434 1097 434 1159 434 1206 434 1229 434 1236 434 1265 434 1291 434 1331 434 1369 434 1461 434 1484 435 59 435 67 435 161 435 190 435 335 435 414 435 435 435 774 435 840 435 841 435 857 435 919 435 1021 435 1231 435 1320 435 1365 435 1409 435 1432 435 1443 435 1454 435 1477 435 1491 435 1497 436 0 436 26 436 185 436 222 436 264 436 267 436 288 436 312 436 327 436 359 436 398 436 436 436 465 436 475 436 480 436 482 436 494 436 546 436 597 436 598 436 646 436 650 436 676 436 755 436 758 436 771 436 895 436 934 436 1079 436 1113 436 1218 436 1266 436 1314 436 1327 436 1330 436 1413 436 1442 437 21 437 51 437 80 437 98 437 151 437 186 437 199 437 225 437 245 437 256 437 276 437 278 437 281 437 318 437 339 437 347 437 358 437 367 437 412 437 419 437 437 437 496 437 509 437 535 437 545 437 597 437 635 437 645 437 661 437 665 437 676 437 682 437 699 437 729 437 731 437 768 437 821 437 828 437 872 437 912 437 949 437 950 437 952 437 1011 437 1033 437 1063 437 1086 437 1152 437 1163 437 1197 437 1208 437 1215 437 1239 437 1288 437 1398 437 1399 437 1417 437 1440 437 1487 438 6 438 45 438 70 438 108 438 133 438 238 438 256 438 273 438 281 438 303 438 363 438 367 438 438 438 512 438 635 438 722 438 731 438 780 438 803 438 872 438 1031 438 1086 438 1228 438 1263 438 1305 438 1363 438 1399 438 1466 438 1488 438 1499 439 32 439 34 439 136 439 150 439 171 439 207 439 213 439 237 439 252 439 274 439 307 439 317 439 423 439 432 439 439 439 495 439 588 439 641 439 706 439 744 439 783 439 813 439 835 439 848 439 853 439 859 439 868 439 869 439 889 439 936 439 1041 439 1110 439 1130 439 1138 439 1174 439 1237 439 1247 439 1255 439 1262 439 1276 439 1284 439 1296 439 1322 439 1347 439 1376 439 1381 439 1422 440 17 440 28 440 58 440 86 440 175 440 250 440 277 440 322 440 349 440 354 440 394 440 399 440 440 440 444 440 464 440 561 440 563 440 580 440 626 440 631 440 652 440 720 440 785 440 795 440 829 440 874 440 1057 440 1059 440 1131 440 1137 440 1140 440 1141 440 1238 440 1283 440 1309 440 1332 440 1341 440 1390 441 5 441 13 441 14 441 47 441 55 441 83 441 92 441 160 441 202 441 218 441 230 441 234 441 240 441 291 441 373 441 377 441 387 441 434 441 441 441 483 441 492 441 528 441 569 441 600 441 603 441 609 441 612 441 620 441 624 441 630 441 640 441 642 441 648 441 690 441 694 441 730 441 809 441 870 441 882 441 883 441 1018 441 1028 441 1075 441 1076 441 1098 441 1108 441 1159 441 1180 441 1196 441 1206 441 1236 441 1265 441 1277 441 1291 441 1331 441 1369 441 1461 441 1472 441 1474 441 1476 441 1484 442 0 442 119 442 197 442 220 442 238 442 264 442 281 442 298 442 301 442 327 442 330 442 338 442 358 442 398 442 427 442 442 442 518 442 560 442 729 442 765 442 771 442 803 442 824 442 866 442 892 442 951 442 983 442 1011 442 1031 442 1085 442 1124 442 1145 442 1147 442 1214 442 1222 442 1228 442 1260 442 1266 442 1271 442 1305 442 1330 442 1371 442 1400 442 1412 442 1413 443 37 443 49 443 122 443 128 443 198 443 203 443 204 443 219 443 242 443 290 443 350 443 360 443 368 443 376 443 443 443 468 443 503 443 517 443 551 443 555 443 573 443 574 443 582 443 589 443 639 443 657 443 671 443 673 443 756 443 770 443 800 443 805 443 819 443 836 443 886 443 928 443 955 443 1020 443 1101 443 1107 443 1166 443 1171 443 1185 443 1200 443 1203 443 1211 443 1273 443 1311 443 1364 443 1431 443 1433 443 1460 443 1483 444 28 444 58 444 66 444 86 444 89 444 116 444 174 444 175 444 211 444 250 444 277 444 325 444 348 444 349 444 355 444 356 444 394 444 399 444 405 444 431 444 440 444 444 444 464 444 539 444 552 444 563 444 579 444 580 444 625 444 626 444 646 444 652 444 720 444 776 444 795 444 863 444 887 444 980 444 995 444 1024 444 1046 444 1047 444 1131 444 1137 444 1141 444 1165 444 1204 444 1238 444 1283 444 1309 444 1316 444 1341 444 1390 444 1446 444 1494 445 21 445 100 445 226 445 246 445 260 445 320 445 329 445 337 445 393 445 412 445 417 445 445 445 487 445 596 445 602 445 616 445 653 445 754 445 762 445 806 445 922 445 952 445 1042 445 1045 445 1070 445 1077 445 1139 445 1158 445 1170 445 1241 445 1288 445 1315 445 1317 445 1387 445 1428 445 1438 445 1445 445 1470 446 7 446 87 446 91 446 143 446 148 446 156 446 167 446 219 446 242 446 292 446 326 446 378 446 446 446 449 446 507 446 508 446 583 446 604 446 613 446 621 446 636 446 639 446 644 446 669 446 791 446 854 446 873 446 903 446 928 446 935 446 937 446 948 446 958 446 962 446 987 446 1010 446 1038 446 1071 446 1151 446 1156 446 1161 446 1167 446 1176 446 1211 446 1273 446 1289 446 1324 446 1326 446 1431 446 1444 446 1450 446 1458 447 33 447 61 447 110 447 169 447 299 447 341 447 342 447 364 447 379 447 447 447 458 447 493 447 504 447 578 447 586 447 687 447 704 447 749 447 773 447 843 447 904 447 913 447 915 447 941 447 943 447 956 447 1109 447 1168 447 1189 447 1269 447 1312 447 1345 447 1420 447 1421 447 1437 448 159 448 196 448 252 448 345 448 383 448 390 448 400 448 448 448 543 448 605 448 615 448 641 448 707 448 739 448 764 448 783 448 847 448 920 448 947 448 960 448 1037 448 1090 448 1126 448 1172 448 1174 448 1252 448 1267 448 1324 448 1325 448 1386 448 1434 448 1436 448 1493 449 7 449 22 449 87 449 107 449 148 449 156 449 266 449 292 449 336 449 378 449 396 449 403 449 446 449 449 449 507 449 530 449 543 449 558 449 570 449 583 449 604 449 607 449 613 449 621 449 669 449 739 449 763 449 791 449 854 449 862 449 873 449 900 449 903 449 920 449 935 449 937 449 948 449 960 449 962 449 994 449 1005 449 1037 449 1071 449 1090 449 1106 449 1156 449 1162 449 1176 449 1184 449 1224 449 1267 449 1287 449 1289 449 1294 449 1324 449 1326 449 1386 449 1436 449 1444 449 1464 450 2 450 25 450 93 450 95 450 111 450 117 450 126 450 153 450 231 450 247 450 282 450 311 450 315 450 353 450 362 450 372 450 384 450 450 450 454 450 463 450 516 450 564 450 670 450 692 450 794 450 796 450 801 450 838 450 970 450 982 450 1001 450 1012 450 1023 450 1036 450 1050 450 1056 450 1083 450 1105 450 1119 450 1122 450 1133 450 1186 450 1194 450 1222 450 1253 450 1256 450 1280 450 1282 450 1298 450 1377 450 1385 450 1394 450 1395 450 1396 450 1447 451 53 451 58 451 78 451 82 451 86 451 90 451 102 451 130 451 191 451 193 451 200 451 206 451 211 451 212 451 262 451 270 451 277 451 308 451 332 451 348 451 405 451 428 451 431 451 451 451 511 451 533 451 534 451 537 451 549 451 563 451 579 451 580 451 610 451 626 451 658 451 685 451 702 451 752 451 761 451 812 451 829 451 846 451 863 451 884 451 901 451 923 451 959 451 1003 451 1024 451 1035 451 1046 451 1057 451 1065 451 1066 451 1084 451 1102 451 1124 451 1131 451 1135 451 1137 451 1183 451 1221 451 1238 451 1249 451 1309 451 1327 451 1336 451 1340 451 1459 451 1475 451 1481 451 1494 452 13 452 47 452 65 452 83 452 92 452 187 452 217 452 218 452 223 452 291 452 377 452 434 452 452 452 484 452 497 452 526 452 528 452 544 452 562 452 567 452 606 452 608 452 612 452 640 452 690 452 822 452 839 452 875 452 883 452 972 452 1076 452 1159 452 1216 452 1225 452 1236 452 1250 452 1290 452 1291 452 1313 452 1348 452 1356 452 1361 452 1375 452 1498 453 16 453 32 453 40 453 115 453 139 453 150 453 171 453 177 453 207 453 213 453 237 453 274 453 307 453 317 453 366 453 453 453 744 453 833 453 835 453 848 453 853 453 859 453 869 453 926 453 936 453 1041 453 1061 453 1103 453 1138 453 1237 453 1245 453 1247 453 1262 453 1276 453 1296 453 1322 453 1347 453 1376 453 1381 453 1406 453 1482 454 2 454 25 454 69 454 93 454 111 454 117 454 119 454 126 454 153 454 220 454 231 454 247 454 282 454 362 454 427 454 450 454 454 454 463 454 516 454 564 454 780 454 794 454 801 454 838 454 951 454 970 454 982 454 1001 454 1036 454 1050 454 1083 454 1119 454 1122 454 1133 454 1186 454 1194 454 1222 454 1227 454 1253 454 1256 454 1260 454 1280 454 1282 454 1298 454 1385 454 1396 454 1447 454 1478 455 57 455 72 455 76 455 135 455 144 455 149 455 189 455 217 455 232 455 253 455 305 455 370 455 388 455 397 455 401 455 424 455 455 455 478 455 484 455 520 455 556 455 584 455 591 455 611 455 684 455 733 455 860 455 911 455 940 455 978 455 990 455 993 455 1014 455 1136 455 1142 455 1179 455 1216 455 1230 455 1235 455 1250 455 1290 455 1358 455 1393 455 1498 456 43 456 60 456 77 456 105 456 118 456 154 456 176 456 208 456 254 456 280 456 287 456 369 456 385 456 410 456 456 456 500 456 532 456 541 456 557 456 565 456 633 456 651 456 724 456 747 456 779 456 826 456 861 456 878 456 891 456 902 456 927 456 957 456 976 456 989 456 1013 456 1025 456 1030 456 1150 456 1207 456 1210 456 1220 456 1243 456 1270 456 1279 456 1295 456 1310 456 1366 456 1380 456 1383 456 1489 457 23 457 31 457 123 457 178 457 184 457 198 457 319 457 350 457 357 457 360 457 376 457 402 457 416 457 422 457 457 457 503 457 551 457 555 457 593 457 622 457 627 457 666 457 673 457 703 457 725 457 732 457 736 457 750 457 766 457 770 457 777 457 800 457 886 457 898 457 916 457 933 457 997 457 1015 457 1020 457 1087 457 1112 457 1166 457 1185 457 1200 457 1205 457 1257 457 1346 457 1388 457 1426 457 1429 457 1433 457 1457 457 1479 457 1492 458 33 458 61 458 110 458 155 458 169 458 299 458 341 458 342 458 364 458 379 458 447 458 458 458 493 458 504 458 514 458 586 458 749 458 773 458 843 458 904 458 913 458 941 458 943 458 956 458 1109 458 1269 458 1312 458 1345 458 1420 458 1421 458 1437 459 11 459 29 459 41 459 94 459 199 459 243 459 284 459 289 459 339 459 380 459 392 459 459 459 486 459 501 459 513 459 664 459 679 459 713 459 715 459 726 459 775 459 787 459 828 459 845 459 912 459 921 459 929 459 931 459 946 459 965 459 968 459 973 459 1033 459 1045 459 1077 459 1081 459 1086 459 1152 459 1241 459 1304 459 1315 459 1335 459 1362 459 1445 459 1470 460 30 460 53 460 78 460 180 460 192 460 212 460 270 460 286 460 308 460 399 460 460 460 511 460 537 460 549 460 631 460 637 460 761 460 812 460 829 460 923 460 1057 460 1065 460 1219 460 1249 460 1336 460 1351 460 1390 460 1415 460 1418 460 1459 461 74 461 88 461 166 461 168 461 173 461 306 461 334 461 420 461 461 461 471 461 472 461 525 461 553 461 659 461 668 461 696 461 748 461 804 461 818 461 924 461 1040 461 1062 461 1080 461 1096 461 1143 461 1191 461 1192 461 1254 461 1272 461 1285 461 1293 461 1302 461 1303 461 1319 461 1405 461 1427 461 1469 462 9 462 15 462 54 462 121 462 158 462 182 462 205 462 221 462 229 462 262 462 285 462 351 462 381 462 462 462 485 462 490 462 618 462 619 462 685 462 735 462 823 462 827 462 837 462 864 462 1044 462 1144 462 1153 462 1183 462 1258 462 1360 462 1389 462 1448 462 1452 462 1463 463 2 463 93 463 95 463 111 463 117 463 126 463 153 463 220 463 231 463 247 463 282 463 296 463 315 463 362 463 384 463 450 463 454 463 463 463 516 463 564 463 654 463 670 463 796 463 801 463 838 463 970 463 975 463 982 463 1001 463 1036 463 1050 463 1083 463 1105 463 1119 463 1122 463 1133 463 1186 463 1194 463 1222 463 1248 463 1253 463 1256 463 1260 463 1280 463 1282 463 1298 463 1384 463 1385 463 1394 463 1395 463 1396 463 1447 463 1478 464 38 464 58 464 66 464 78 464 193 464 212 464 216 464 283 464 286 464 322 464 328 464 349 464 394 464 399 464 428 464 431 464 440 464 444 464 464 464 534 464 575 464 580 464 623 464 625 464 637 464 652 464 720 464 767 464 785 464 792 464 829 464 874 464 887 464 923 464 969 464 1017 464 1046 464 1067 464 1140 464 1209 464 1219 464 1234 464 1238 464 1249 464 1316 464 1332 464 1336 464 1351 464 1390 464 1418 464 1459 464 1481 465 26 465 82 465 193 465 200 465 222 465 259 465 312 465 327 465 338 465 405 465 436 465 465 465 518 465 560 465 598 465 658 465 734 465 802 465 871 465 892 465 934 465 1003 465 1035 465 1054 465 1113 465 1118 465 1124 465 1135 465 1147 465 1214 465 1266 465 1327 465 1330 465 1382 465 1442 465 1486 466 111 466 146 466 353 466 404 466 466 466 481 466 743 466 888 466 1232 466 1298 466 1466 466 1478 467 0 467 29 467 80 467 94 467 114 467 226 467 235 467 251 467 358 467 467 467 664 467 679 467 689 467 699 467 821 467 832 467 966 467 1012 467 1170 467 1175 467 1308 467 1399 467 1427 468 122 468 178 468 184 468 203 468 319 468 443 468 468 468 517 468 573 468 805 468 819 468 955 468 1101 468 1240 468 1246 468 1311 468 1323 468 1344 469 4 469 71 469 136 469 248 469 274 469 297 469 331 469 390 469 423 469 432 469 469 469 519 469 548 469 632 469 641 469 706 469 738 469 964 469 977 469 1053 469 1073 469 1130 469 1252 469 1255 469 1274 469 1328 469 1357 469 1367 469 1416 469 1422 469 1423 469 1451 469 1480 470 27 470 28 470 45 470 89 470 124 470 138 470 151 470 267 470 268 470 318 470 380 470 392 470 470 470 501 470 505 470 510 470 540 470 552 470 568 470 676 470 678 470 683 470 686 470 705 470 753 470 755 470 760 470 831 470 832 470 865 470 896 470 921 470 931 470 950 470 965 470 979 470 986 470 995 470 1007 470 1009 470 1060 470 1111 470 1120 470 1160 470 1215 470 1304 470 1321 470 1349 470 1417 470 1425 470 1446 470 1449 470 1465 470 1471 471 166 471 173 471 306 471 334 471 420 471 461 471 471 471 472 471 488 471 553 471 554 471 566 471 654 471 660 471 662 471 668 471 675 471 696 471 748 471 924 471 970 471 1040 471 1143 471 1191 471 1254 471 1272 471 1285 471 1302 471 1303 471 1308 471 1329 471 1405 471 1427 471 1469 472 88 472 166 472 173 472 209 472 334 472 420 472 426 472 461 472 471 472 472 472 488 472 553 472 554 472 572 472 675 472 696 472 710 472 723 472 788 472 899 472 924 472 1051 472 1096 472 1104 472 1143 472 1192 472 1254 472 1285 472 1293 472 1303 472 1391 472 1405 472 1427 472 1469 473 3 473 8 473 19 473 64 473 158 473 182 473 183 473 381 473 473 473 527 473 599 473 614 473 628 473 660 473 709 473 735 473 816 473 837 473 849 473 1040 473 1132 473 1144 473 1389 473 1419 473 1448 473 1455 473 1463 474 113 474 132 474 227 474 241 474 324 474 353 474 386 474 420 474 474 474 481 474 515 474 553 474 554 474 566 474 581 474 696 474 728 474 798 474 924 474 1232 474 1259 474 1285 474 1391 475 26 475 238 475 264 475 267 475 281 475 327 475 338 475 355 475 398 475 425 475 429 475 436 475 475 475 518 475 546 475 598 475 629 475 674 475 758 475 817 475 824 475 934 475 1011 475 1079 475 1085 475 1124 475 1145 475 1204 475 1266 475 1271 475 1305 475 1318 475 1321 475 1400 475 1413 476 214 476 236 476 415 476 476 476 595 476 793 476 850 476 856 476 876 476 981 476 984 476 1051 476 1117 476 1195 476 1306 476 1337 476 1342 477 84 477 88 477 166 477 168 477 173 477 334 477 409 477 420 477 426 477 477 477 488 477 489 477 572 477 710 477 737 477 788 477 899 477 917 477 1051 477 1062 477 1080 477 1093 477 1096 477 1104 477 1115 477 1143 477 1149 477 1192 477 1233 477 1293 477 1469 478 47 478 72 478 135 478 144 478 149 478 217 478 223 478 232 478 253 478 279 478 295 478 305 478 343 478 371 478 389 478 397 478 401 478 408 478 424 478 455 478 478 478 483 478 520 478 526 478 544 478 567 478 584 478 591 478 592 478 638 478 680 478 684 478 733 478 784 478 807 478 814 478 822 478 839 478 860 478 911 478 940 478 978 478 990 478 1014 478 1068 478 1078 478 1082 478 1097 478 1099 478 1136 478 1142 478 1180 478 1206 478 1216 478 1229 478 1235 478 1250 478 1281 478 1290 478 1355 478 1356 478 1361 478 1370 478 1375 478 1407 478 1441 478 1456 478 1474 478 1498 479 27 479 66 479 96 479 116 479 138 479 162 479 174 479 228 479 261 479 263 479 322 479 354 479 356 479 394 479 479 479 486 479 539 479 552 479 561 479 568 479 649 479 678 479 714 479 753 479 757 479 775 479 789 479 792 479 830 479 831 479 887 479 909 479 942 479 946 479 985 479 991 479 1016 479 1047 479 1072 479 1120 479 1125 479 1173 479 1213 479 1283 479 1372 479 1414 479 1446 480 151 480 185 480 238 480 264 480 281 480 301 480 359 480 398 480 419 480 430 480 436 480 480 480 529 480 546 480 597 480 598 480 650 480 663 480 665 480 674 480 721 480 758 480 760 480 821 480 824 480 842 480 986 480 996 480 1011 480 1019 480 1060 480 1070 480 1079 480 1085 480 1147 480 1197 480 1218 480 1266 480 1305 480 1318 480 1412 480 1440 480 1465 481 93 481 95 481 111 481 113 481 126 481 132 481 194 481 227 481 231 481 362 481 386 481 466 481 474 481 481 481 515 481 516 481 525 481 566 481 670 481 796 481 798 481 838 481 975 481 1001 481 1002 481 1036 481 1116 481 1119 481 1122 481 1232 481 1248 481 1259 481 1280 481 1298 481 1302 481 1391 481 1478 482 24 482 26 482 222 482 267 482 355 482 436 482 482 482 494 482 598 482 629 482 650 482 689 482 708 482 715 482 755 482 824 482 895 482 921 482 931 482 986 482 995 482 1007 482 1009 482 1314 482 1321 482 1349 482 1371 482 1403 482 1449 482 1485 483 14 483 47 483 79 483 92 483 125 483 160 483 223 483 230 483 272 483 279 483 295 483 371 483 373 483 387 483 389 483 408 483 441 483 478 483 483 483 600 483 612 483 624 483 630 483 638 483 640 483 648 483 690 483 694 483 784 483 807 483 814 483 839 483 882 483 910 483 911 483 940 483 978 483 1014 483 1018 483 1068 483 1075 483 1076 483 1078 483 1082 483 1099 483 1180 483 1196 483 1206 483 1217 483 1236 483 1277 483 1281 483 1355 483 1361 483 1370 483 1407 483 1441 483 1474 483 1484 484 14 484 79 484 92 484 189 484 279 484 373 484 404 484 452 484 455 484 484 484 491 484 520 484 526 484 556 484 567 484 591 484 600 484 606 484 611 484 612 484 624 484 638 484 640 484 684 484 690 484 743 484 807 484 822 484 844 484 867 484 875 484 910 484 911 484 990 484 999 484 1069 484 1075 484 1082 484 1196 484 1230 484 1236 484 1277 484 1290 484 1355 484 1356 484 1375 484 1484 485 9 485 15 485 54 485 121 485 158 485 182 485 205 485 221 485 229 485 285 485 351 485 381 485 462 485 485 485 490 485 536 485 618 485 685 485 698 485 701 485 735 485 815 485 823 485 827 485 837 485 864 485 905 485 1044 485 1144 485 1153 485 1183 485 1221 485 1258 485 1343 485 1360 485 1389 485 1448 485 1452 485 1455 486 66 486 96 486 127 486 131 486 235 486 243 486 263 486 356 486 392 486 459 486 479 486 486 486 501 486 576 486 649 486 678 486 679 486 715 486 726 486 746 486 757 486 767 486 772 486 775 486 786 486 789 486 797 486 830 486 879 486 881 486 887 486 921 486 929 486 931 486 942 486 946 486 1016 486 1047 486 1072 486 1173 486 1178 486 1213 486 1244 486 1349 486 1353 486 1362 486 1372 486 1410 487 81 487 99 487 100 487 106 487 134 487 140 487 188 487 260 487 329 487 337 487 382 487 393 487 406 487 417 487 430 487 445 487 487 487 505 487 510 487 550 487 585 487 596 487 616 487 717 487 754 487 762 487 781 487 790 487 806 487 820 487 890 487 918 487 929 487 949 487 968 487 988 487 1000 487 1019 487 1022 487 1045 487 1077 487 1094 487 1139 487 1158 487 1223 487 1226 487 1241 487 1251 487 1317 487 1408 487 1428 487 1445 487 1470 488 74 488 84 488 88 488 173 488 201 488 209 488 239 488 241 488 293 488 306 488 315 488 334 488 384 488 420 488 471 488 472 488 477 488 488 488 515 488 554 488 566 488 572 488 647 488 675 488 677 488 788 488 818 488 858 488 971 488 1006 488 1051 488 1062 488 1115 488 1143 488 1157 488 1192 488 1248 488 1293 488 1303 488 1307 488 1329 488 1469 489 62 489 88 489 105 489 166 489 168 489 173 489 215 489 258 489 334 489 346 489 409 489 426 489 477 489 489 489 572 489 710 489 788 489 826 489 899 489 917 489 954 489 1062 489 1080 489 1093 489 1096 489 1104 489 1114 489 1115 489 1134 489 1143 489 1149 489 1233 489 1293 489 1350 489 1405 489 1469 490 9 490 15 490 54 490 73 490 121 490 158 490 182 490 205 490 221 490 229 490 257 490 262 490 285 490 351 490 381 490 462 490 485 490 490 490 536 490 618 490 619 490 685 490 698 490 701 490 735 490 808 490 823 490 827 490 837 490 864 490 1044 490 1066 490 1102 490 1118 490 1144 490 1153 490 1183 490 1212 490 1221 490 1258 490 1340 490 1343 490 1360 490 1389 490 1448 490 1452 491 44 491 57 491 72 491 79 491 135 491 144 491 147 491 149 491 189 491 224 491 253 491 344 491 370 491 373 491 388 491 397 491 484 491 491 491 520 491 556 491 600 491 611 491 733 491 743 491 799 491 807 491 860 491 893 491 910 491 911 491 990 491 993 491 999 491 1027 491 1069 491 1082 491 1202 491 1217 491 1230 491 1235 491 1277 491 1278 491 1355 491 1358 491 1393 491 1456 491 1484 492 13 492 55 492 65 492 83 492 85 492 218 492 234 492 291 492 377 492 441 492 492 492 528 492 562 492 603 492 609 492 620 492 642 492 648 492 730 492 870 492 883 492 939 492 1028 492 1091 492 1098 492 1108 492 1129 492 1159 492 1225 492 1265 492 1291 492 1373 492 1496 493 33 493 61 493 110 493 141 493 155 493 169 493 299 493 341 493 342 493 364 493 379 493 447 493 458 493 493 493 504 493 514 493 578 493 586 493 687 493 704 493 749 493 773 493 843 493 904 493 913 493 915 493 941 493 943 493 956 493 1109 493 1189 493 1269 493 1312 493 1338 493 1345 493 1420 493 1421 493 1437 494 244 494 318 494 359 494 380 494 436 494 482 494 494 494 598 494 645 494 650 494 674 494 676 494 683 494 689 494 699 494 708 494 715 494 842 494 895 494 896 494 950 494 965 494 986 494 1009 494 1079 494 1304 494 1314 494 1321 494 1349 494 1449 495 32 495 34 495 40 495 136 495 150 495 171 495 207 495 213 495 237 495 274 495 307 495 317 495 423 495 439 495 495 495 588 495 744 495 783 495 813 495 835 495 848 495 853 495 859 495 868 495 869 495 889 495 926 495 936 495 1041 495 1103 495 1110 495 1138 495 1174 495 1237 495 1247 495 1262 495 1284 495 1296 495 1322 495 1347 495 1376 495 1381 495 1422 496 11 496 21 496 80 496 94 496 151 496 186 496 225 496 245 496 276 496 278 496 318 496 339 496 347 496 412 496 419 496 437 496 496 496 509 496 513 496 535 496 545 496 597 496 664 496 665 496 713 496 790 496 817 496 821 496 828 496 834 496 912 496 949 496 950 496 952 496 1011 496 1033 496 1045 496 1048 496 1063 496 1070 496 1152 496 1181 496 1201 496 1208 496 1215 496 1241 496 1251 496 1288 496 1408 496 1417 496 1425 496 1445 497 55 497 83 497 101 497 187 497 217 497 218 497 343 497 377 497 452 497 497 497 524 497 544 497 547 497 562 497 584 497 592 497 608 497 620 497 638 497 667 497 844 497 867 497 906 497 908 497 972 497 1034 497 1078 497 1091 497 1098 497 1198 497 1225 497 1291 497 1299 497 1313 497 1348 497 1361 497 1373 497 1474 497 1496 498 35 498 42 498 133 498 138 498 140 498 162 498 172 498 263 498 313 498 374 498 382 498 411 498 498 498 521 498 540 498 576 498 577 498 649 498 661 498 718 498 741 498 757 498 781 498 832 498 961 498 992 498 1049 498 1120 498 1223 498 1363 499 2 499 3 499 8 499 19 499 64 499 97 499 153 499 183 499 197 499 247 499 296 499 362 499 407 499 427 499 499 499 614 499 628 499 654 499 660 499 662 499 765 499 816 499 871 499 892 499 951 499 970 499 1001 499 1036 499 1050 499 1105 499 1132 499 1186 499 1222 499 1227 499 1242 499 1329 499 1354 499 1384 499 1419 500 39 500 43 500 46 500 77 500 104 500 105 500 109 500 112 500 118 500 176 500 208 500 258 500 309 500 346 500 369 500 410 500 456 500 500 500 532 500 557 500 565 500 633 500 651 500 724 500 747 500 779 500 826 500 878 500 891 500 902 500 927 500 957 500 976 500 1025 500 1030 500 1114 500 1128 500 1134 500 1182 500 1220 500 1243 500 1270 500 1279 500 1310 500 1350 500 1366 500 1368 500 1380 500 1439 500 1489 501 27 501 41 501 89 501 94 501 96 501 124 501 127 501 131 501 228 501 243 501 263 501 289 501 321 501 380 501 382 501 392 501 393 501 459 501 470 501 486 501 501 501 502 501 513 501 535 501 594 501 649 501 678 501 679 501 713 501 726 501 741 501 746 501 757 501 772 501 775 501 786 501 789 501 797 501 810 501 830 501 831 501 879 501 896 501 918 501 921 501 925 501 929 501 942 501 946 501 968 501 1016 501 1048 501 1072 501 1111 501 1160 501 1201 501 1213 501 1251 501 1349 501 1372 501 1410 501 1414 501 1425 501 1445 501 1449 502 24 502 66 502 127 502 193 502 228 502 243 502 250 502 392 502 425 502 501 502 502 502 535 502 539 502 649 502 678 502 679 502 753 502 775 502 879 502 925 502 938 502 979 502 985 502 1016 502 1064 502 1072 502 1111 502 1160 502 1165 502 1341 502 1349 502 1353 502 1372 502 1403 502 1449 503 10 503 23 503 37 503 49 503 184 503 198 503 357 503 376 503 443 503 457 503 503 503 517 503 542 503 551 503 555 503 559 503 573 503 582 503 589 503 601 503 627 503 657 503 666 503 673 503 725 503 750 503 756 503 766 503 770 503 805 503 898 503 933 503 1008 503 1020 503 1087 503 1088 503 1101 503 1107 503 1166 503 1185 503 1246 503 1323 503 1344 503 1429 503 1433 503 1457 503 1483 503 1492 503 1495 504 10 504 33 504 50 504 61 504 110 504 141 504 169 504 195 504 210 504 299 504 314 504 341 504 342 504 364 504 379 504 447 504 458 504 493 504 504 504 514 504 571 504 578 504 586 504 687 504 704 504 749 504 811 504 904 504 913 504 915 504 943 504 956 504 1109 504 1168 504 1189 504 1269 504 1275 504 1312 504 1338 504 1352 504 1374 504 1420 504 1421 504 1437 504 1495 505 28 505 45 505 89 505 99 505 138 505 380 505 470 505 487 505 505 505 510 505 540 505 585 505 665 505 676 505 681 505 686 505 717 505 795 505 865 505 890 505 896 505 921 505 950 505 965 505 968 505 986 505 988 505 1000 505 1019 505 1060 505 1160 505 1226 505 1251 505 1304 505 1408 505 1425 505 1445 505 1446 505 1471 506 24 506 30 506 38 506 53 506 90 506 180 506 222 506 262 506 269 506 270 506 323 506 340 506 431 506 506 506 511 506 549 506 610 506 637 506 702 506 769 506 778 506 808 506 923 506 983 506 1187 506 1219 506 1334 506 1336 506 1359 506 1415 506 1486 507 22 507 107 507 143 507 156 507 266 507 378 507 446 507 449 507 507 507 543 507 558 507 570 507 604 507 607 507 613 507 621 507 739 507 791 507 854 507 862 507 873 507 900 507 920 507 935 507 937 507 962 507 1071 507 1090 507 1127 507 1146 507 1156 507 1162 507 1176 507 1184 507 1294 507 1386 507 1444 508 7 508 91 508 143 508 167 508 219 508 326 508 350 508 416 508 418 508 446 508 508 508 555 508 583 508 604 508 613 508 636 508 639 508 644 508 669 508 691 508 727 508 732 508 777 508 800 508 854 508 886 508 903 508 928 508 937 508 987 508 1010 508 1015 508 1038 508 1146 508 1151 508 1154 508 1167 508 1200 508 1205 508 1211 508 1257 508 1268 508 1273 508 1289 508 1346 508 1388 508 1431 508 1450 508 1479 509 11 509 21 509 80 509 179 509 225 509 245 509 249 509 276 509 278 509 339 509 347 509 412 509 419 509 437 509 496 509 509 509 545 509 602 509 656 509 682 509 713 509 768 509 787 509 821 509 828 509 845 509 880 509 912 509 922 509 949 509 952 509 966 509 1022 509 1045 509 1063 509 1152 509 1170 509 1175 509 1190 509 1288 509 1335 510 41 510 81 510 99 510 106 510 151 510 188 510 199 510 245 510 284 510 318 510 329 510 337 510 347 510 380 510 382 510 430 510 470 510 487 510 505 510 510 510 529 510 550 510 585 510 665 510 674 510 686 510 713 510 717 510 760 510 781 510 787 510 790 510 820 510 890 510 929 510 949 510 950 510 965 510 986 510 988 510 1000 510 1019 510 1048 510 1060 510 1081 510 1152 510 1190 510 1223 510 1226 510 1241 510 1251 510 1286 510 1304 510 1408 510 1425 510 1445 510 1449 510 1465 510 1471 511 30 511 53 511 78 511 82 511 90 511 102 511 130 511 191 511 212 511 262 511 270 511 286 511 308 511 428 511 451 511 460 511 506 511 511 511 533 511 537 511 549 511 563 511 610 511 619 511 631 511 637 511 658 511 685 511 702 511 752 511 761 511 785 511 812 511 829 511 863 511 884 511 905 511 923 511 1003 511 1057 511 1065 511 1084 511 1135 511 1141 511 1183 511 1219 511 1336 511 1360 511 1390 511 1418 511 1459 511 1481 512 6 512 25 512 48 512 108 512 146 512 163 512 256 512 273 512 303 512 363 512 438 512 512 512 521 512 635 512 688 512 718 512 740 512 782 512 810 512 852 512 880 512 961 512 998 512 1004 512 1031 512 1049 512 1052 512 1086 512 1163 512 1177 512 1208 512 1239 512 1263 512 1362 512 1363 512 1399 512 1466 512 1488 513 41 513 81 513 127 513 134 513 138 513 228 513 243 513 276 513 318 513 337 513 347 513 392 513 393 513 459 513 496 513 501 513 513 513 535 513 545 513 713 513 726 513 775 513 790 513 817 513 828 513 834 513 912 513 918 513 929 513 946 513 968 513 979 513 1000 513 1016 513 1033 513 1048 513 1070 513 1081 513 1215 513 1241 513 1251 513 1286 513 1392 513 1408 513 1425 513 1445 513 1449 514 33 514 50 514 61 514 68 514 141 514 155 514 169 514 294 514 299 514 300 514 314 514 342 514 364 514 379 514 433 514 458 514 493 514 504 514 514 514 538 514 571 514 578 514 773 514 904 514 913 514 930 514 1188 514 1189 514 1269 514 1312 514 1338 514 1420 514 1437 515 74 515 84 515 93 515 95 515 113 515 120 515 126 515 132 515 201 515 227 515 231 515 239 515 241 515 271 515 275 515 282 515 293 515 306 515 311 515 315 515 324 515 386 515 474 515 481 515 488 515 515 515 554 515 564 515 566 515 581 515 719 515 798 515 804 515 838 515 858 515 971 515 975 515 1002 515 1023 515 1058 515 1116 515 1119 515 1122 515 1157 515 1232 515 1248 515 1259 515 1280 515 1282 515 1285 515 1391 515 1394 515 1435 515 1478 516 2 516 93 516 95 516 111 516 113 516 117 516 126 516 153 516 194 516 227 516 231 516 241 516 247 516 282 516 296 516 353 516 362 516 427 516 450 516 454 516 463 516 481 516 516 516 564 516 670 516 796 516 801 516 838 516 970 516 975 516 982 516 1001 516 1002 516 1036 516 1050 516 1056 516 1105 516 1116 516 1119 516 1122 516 1133 516 1186 516 1194 516 1248 516 1253 516 1256 516 1260 516 1280 516 1282 516 1298 516 1385 516 1394 516 1396 516 1478 517 10 517 23 517 49 517 122 517 184 517 198 517 203 517 376 517 443 517 468 517 503 517 517 517 555 517 573 517 582 517 643 517 693 517 697 517 750 517 756 517 805 517 819 517 898 517 955 517 1008 517 1020 517 1101 517 1107 517 1166 517 1240 517 1246 517 1323 517 1344 517 1352 517 1364 517 1429 517 1433 517 1457 518 238 518 264 518 281 518 298 518 301 518 327 518 330 518 338 518 398 518 442 518 465 518 475 518 518 518 560 518 598 518 674 518 734 518 765 518 803 518 824 518 866 518 1011 518 1085 518 1124 518 1145 518 1147 518 1228 518 1266 518 1271 518 1305 518 1330 518 1371 518 1400 518 1412 518 1413 519 4 519 71 519 155 519 248 519 331 519 336 519 432 519 469 519 519 519 538 519 548 519 632 519 716 519 738 519 977 519 1053 519 1073 519 1188 519 1328 519 1357 519 1367 519 1404 519 1416 519 1423 519 1451 519 1480 520 72 520 79 520 135 520 144 520 164 520 189 520 217 520 370 520 373 520 387 520 391 520 397 520 401 520 424 520 455 520 478 520 484 520 491 520 520 520 526 520 556 520 584 520 591 520 600 520 611 520 638 520 680 520 784 520 844 520 867 520 906 520 911 520 940 520 972 520 978 520 990 520 999 520 1014 520 1034 520 1179 520 1180 520 1198 520 1216 520 1230 520 1277 520 1290 520 1393 520 1484 521 6 521 45 521 134 521 138 521 140 521 256 521 278 521 374 521 393 521 406 521 411 521 413 521 498 521 512 521 521 521 635 521 688 521 718 521 741 521 757 521 772 521 781 521 782 521 797 521 832 521 880 521 918 521 998 521 1048 521 1049 521 1086 521 1094 521 1139 521 1163 521 1164 521 1181 521 1223 521 1239 521 1362 521 1399 521 1453 522 51 522 116 522 129 522 133 522 145 522 172 522 174 522 180 522 304 522 325 522 348 522 431 522 522 522 537 522 590 522 594 522 629 522 695 522 708 522 729 522 731 522 769 522 776 522 884 522 885 522 897 522 944 522 980 522 983 522 992 522 1007 522 1046 522 1141 522 1178 522 1199 522 1204 522 1209 522 1244 522 1261 522 1316 522 1339 522 1468 523 25 523 163 523 273 523 310 523 372 523 415 523 523 523 692 523 740 523 793 523 845 523 850 523 880 523 894 523 932 523 963 523 974 523 982 523 1004 523 1163 523 1239 523 1335 523 1385 523 1447 523 1466 524 36 524 55 524 56 524 83 524 101 524 164 524 187 524 218 524 291 524 343 524 391 524 408 524 497 524 524 524 547 524 562 524 592 524 608 524 620 524 638 524 667 524 680 524 844 524 867 524 870 524 906 524 908 524 972 524 1034 524 1091 524 1098 524 1198 524 1225 524 1299 524 1348 524 1361 524 1373 524 1474 524 1496 525 74 525 227 525 306 525 420 525 461 525 481 525 525 525 553 525 581 525 659 525 668 525 696 525 748 525 788 525 798 525 804 525 818 525 1002 525 1040 525 1080 525 1096 525 1192 525 1272 525 1302 526 14 526 79 526 217 526 279 526 295 526 373 526 401 526 404 526 408 526 452 526 478 526 484 526 520 526 526 526 567 526 606 526 680 526 684 526 784 526 822 526 839 526 867 526 875 526 940 526 978 526 1014 526 1018 526 1097 526 1098 526 1216 526 1229 526 1236 526 1250 526 1281 526 1290 526 1291 526 1313 526 1331 526 1348 526 1356 526 1375 526 1407 526 1441 526 1498 527 3 527 64 527 183 527 473 527 527 527 599 527 660 527 709 527 849 527 1040 527 1132 527 1419 528 5 528 12 528 13 528 14 528 65 528 92 528 160 528 165 528 218 528 234 528 240 528 291 528 377 528 434 528 441 528 452 528 492 528 528 528 544 528 603 528 606 528 609 528 612 528 624 528 630 528 642 528 648 528 690 528 882 528 883 528 939 528 1026 528 1028 528 1075 528 1076 528 1159 528 1196 528 1225 528 1236 528 1265 528 1291 528 1461 529 81 529 99 529 106 529 151 529 185 529 188 529 347 529 419 529 430 529 480 529 510 529 529 529 546 529 550 529 585 529 665 529 674 529 682 529 721 529 760 529 820 529 821 529 842 529 949 529 986 529 996 529 1019 529 1022 529 1060 529 1063 529 1070 529 1197 529 1318 529 1440 529 1465 530 22 530 87 530 156 530 266 530 292 530 336 530 378 530 396 530 403 530 449 530 530 530 543 530 558 530 583 530 604 530 621 530 669 530 707 530 727 530 739 530 763 530 764 530 791 530 873 530 900 530 903 530 920 530 948 530 960 530 994 530 1005 530 1037 530 1038 530 1090 530 1176 530 1224 530 1267 530 1287 530 1289 530 1324 530 1326 530 1386 530 1436 530 1444 530 1464 530 1493 531 17 531 124 531 129 531 192 531 255 531 313 531 395 531 413 531 531 531 577 531 590 531 634 531 700 531 711 531 786 531 851 531 852 531 881 531 991 531 1092 531 1123 531 1125 531 1155 531 1173 531 1193 531 1292 532 43 532 46 532 62 532 104 532 105 532 118 532 176 532 208 532 287 532 309 532 456 532 500 532 532 532 557 532 565 532 651 532 710 532 747 532 826 532 878 532 899 532 902 532 927 532 957 532 1030 532 1114 532 1182 532 1220 532 1243 532 1264 532 1270 532 1350 532 1366 532 1368 532 1380 532 1383 532 1489 533 53 533 58 533 78 533 82 533 90 533 102 533 191 533 211 533 229 533 257 533 351 533 405 533 428 533 451 533 511 533 533 533 534 533 549 533 610 533 619 533 626 533 658 533 702 533 785 533 808 533 812 533 863 533 901 533 923 533 1003 533 1024 533 1054 533 1084 533 1135 533 1183 533 1334 533 1340 533 1360 533 1459 534 30 534 38 534 53 534 58 534 78 534 86 534 191 534 212 534 216 534 229 534 257 534 262 534 349 534 351 534 405 534 428 534 431 534 451 534 464 534 533 534 534 534 579 534 610 534 618 534 619 534 626 534 637 534 720 534 792 534 808 534 812 534 863 534 874 534 923 534 959 534 1017 534 1024 534 1057 534 1065 534 1084 534 1131 534 1137 534 1219 534 1234 534 1238 534 1249 534 1309 534 1334 534 1336 534 1351 534 1360 534 1418 534 1475 535 21 535 80 535 127 535 228 535 245 535 251 535 276 535 318 535 329 535 337 535 347 535 392 535 412 535 437 535 496 535 501 535 502 535 513 535 535 535 678 535 713 535 775 535 790 535 817 535 834 535 912 535 925 535 938 535 946 535 950 535 952 535 979 535 986 535 1009 535 1016 535 1033 535 1045 535 1048 535 1070 535 1201 535 1215 535 1241 535 1286 535 1288 535 1392 535 1408 535 1425 535 1445 535 1449 535 1471 536 9 536 15 536 54 536 90 536 102 536 121 536 191 536 205 536 222 536 262 536 285 536 312 536 323 536 351 536 485 536 490 536 536 536 579 536 610 536 618 536 619 536 658 536 685 536 698 536 701 536 734 536 778 536 802 536 808 536 815 536 823 536 827 536 863 536 864 536 905 536 959 536 1024 536 1035 536 1044 536 1054 536 1102 536 1118 536 1124 536 1153 536 1183 536 1212 536 1221 536 1258 536 1334 536 1340 536 1343 536 1360 536 1382 536 1452 536 1486 537 30 537 53 537 78 537 82 537 90 537 102 537 174 537 175 537 180 537 191 537 212 537 270 537 304 537 332 537 348 537 349 537 451 537 460 537 511 537 522 537 537 537 549 537 610 537 658 537 761 537 776 537 812 537 829 537 863 537 884 537 897 537 923 537 967 537 980 537 1003 537 1057 537 1124 537 1135 537 1137 537 1141 537 1204 537 1334 537 1390 537 1459 537 1481 538 20 538 50 538 68 538 75 538 141 538 203 538 294 538 300 538 314 538 333 538 336 538 357 538 368 538 402 538 433 538 514 538 519 538 538 538 551 538 571 538 671 538 673 538 697 538 916 538 930 538 1088 538 1100 538 1188 538 1203 538 1300 538 1364 538 1404 538 1460 538 1462 538 1490 539 24 539 66 539 116 539 137 539 145 539 174 539 175 539 206 539 235 539 261 539 322 539 323 539 325 539 356 539 425 539 429 539 444 539 479 539 502 539 539 539 552 539 568 539 576 539 646 539 678 539 705 539 714 539 753 539 755 539 767 539 771 539 776 539 885 539 944 539 985 539 995 539 1064 539 1072 539 1165 539 1173 539 1178 539 1204 539 1244 539 1261 539 1339 539 1353 539 1372 539 1401 539 1403 540 35 540 45 540 89 540 124 540 138 540 140 540 151 540 188 540 245 540 281 540 284 540 313 540 321 540 363 540 374 540 382 540 406 540 470 540 498 540 505 540 540 540 577 540 681 540 682 540 686 540 695 540 753 540 772 540 781 540 782 540 831 540 832 540 852 540 865 540 896 540 929 540 950 540 961 540 995 540 1032 540 1060 540 1158 540 1160 540 1201 540 1223 540 1251 540 1304 540 1425 541 43 541 46 541 60 541 77 541 118 541 154 541 176 541 208 541 280 541 287 541 369 541 385 541 410 541 456 541 541 541 557 541 565 541 633 541 724 541 747 541 779 541 861 541 891 541 902 541 927 541 957 541 976 541 1013 541 1025 541 1030 541 1128 541 1150 541 1210 541 1243 541 1279 541 1295 541 1310 541 1366 541 1380 541 1439 541 1489 542 10 542 23 542 103 542 184 542 198 542 210 542 341 542 376 542 503 542 542 542 578 542 582 542 601 542 643 542 666 542 687 542 693 542 704 542 725 542 750 542 811 542 898 542 913 542 915 542 943 542 1008 542 1095 542 1109 542 1168 542 1240 542 1246 542 1275 542 1297 542 1300 542 1312 542 1323 542 1338 542 1352 542 1374 542 1421 542 1429 542 1457 542 1492 542 1495 543 22 543 156 543 159 543 196 543 266 543 345 543 378 543 396 543 403 543 448 543 449 543 507 543 530 543 543 543 570 543 583 543 605 543 621 543 707 543 739 543 763 543 764 543 791 543 854 543 862 543 873 543 900 543 903 543 920 543 947 543 948 543 960 543 994 543 1005 543 1037 543 1038 543 1090 543 1126 543 1162 543 1174 543 1176 543 1224 543 1252 543 1267 543 1287 543 1324 543 1325 543 1386 543 1434 543 1436 543 1444 543 1493 544 13 544 83 544 187 544 217 544 234 544 371 544 377 544 452 544 478 544 497 544 528 544 544 544 562 544 567 544 584 544 603 544 640 544 648 544 807 544 875 544 883 544 972 544 1078 544 1099 544 1142 544 1159 544 1225 544 1236 544 1250 544 1313 544 1348 544 1356 544 1361 544 1373 544 1375 544 1496 545 0 545 11 545 21 545 29 545 51 545 151 545 186 545 199 545 276 545 278 545 339 545 347 545 412 545 419 545 437 545 496 545 509 545 513 545 545 545 597 545 661 545 665 545 676 545 699 545 713 545 729 545 787 545 817 545 821 545 828 545 872 545 880 545 912 545 949 545 950 545 952 545 996 545 1011 545 1033 545 1063 545 1086 545 1152 545 1163 545 1208 545 1215 545 1239 545 1362 545 1398 545 1417 545 1487 546 98 546 185 546 264 546 288 546 301 546 358 546 359 546 398 546 436 546 475 546 480 546 529 546 546 546 597 546 598 546 650 546 663 546 665 546 674 546 721 546 758 546 760 546 771 546 842 546 986 546 996 546 1009 546 1019 546 1079 546 1085 546 1197 546 1218 546 1266 546 1305 546 1318 546 1412 546 1440 546 1465 547 36 547 55 547 56 547 83 547 101 547 164 547 187 547 217 547 218 547 291 547 343 547 371 547 377 547 391 547 408 547 497 547 524 547 547 547 562 547 592 547 606 547 608 547 620 547 638 547 667 547 680 547 730 547 867 547 870 547 906 547 908 547 972 547 1034 547 1091 547 1098 547 1180 547 1198 547 1225 547 1299 547 1348 547 1361 547 1373 547 1474 547 1496 548 136 548 148 548 159 548 297 548 336 548 390 548 423 548 432 548 469 548 519 548 548 548 641 548 706 548 707 548 763 548 764 548 960 548 964 548 977 548 1005 548 1037 548 1130 548 1184 548 1224 548 1252 548 1255 548 1274 548 1287 548 1324 548 1328 548 1367 548 1404 548 1416 548 1422 548 1423 548 1436 548 1464 548 1480 548 1493 549 30 549 38 549 53 549 73 549 78 549 82 549 102 549 130 549 180 549 191 549 211 549 212 549 270 549 286 549 308 549 338 549 428 549 431 549 451 549 460 549 506 549 511 549 533 549 537 549 549 549 610 549 631 549 637 549 655 549 658 549 702 549 752 549 761 549 769 549 778 549 812 549 829 549 863 549 884 549 905 549 923 549 983 549 1003 549 1057 549 1065 549 1084 549 1135 549 1219 549 1249 549 1336 549 1359 549 1390 549 1418 549 1459 549 1481 550 81 550 99 550 106 550 188 550 249 550 265 550 329 550 430 550 487 550 510 550 529 550 550 550 585 550 602 550 656 550 717 550 820 550 855 550 922 550 949 550 1019 550 1022 550 1063 550 1070 550 1190 550 1223 550 1317 550 1408 550 1428 550 1465 551 10 551 37 551 49 551 68 551 75 551 128 551 198 551 203 551 210 551 290 551 357 551 360 551 368 551 376 551 402 551 433 551 443 551 457 551 503 551 538 551 551 551 555 551 559 551 571 551 573 551 582 551 622 551 627 551 657 551 673 551 697 551 703 551 725 551 750 551 756 551 766 551 805 551 811 551 898 551 916 551 930 551 1020 551 1088 551 1100 551 1107 551 1166 551 1203 551 1257 551 1323 551 1352 551 1374 551 1433 551 1457 551 1460 551 1490 551 1492 551 1495 552 27 552 28 552 116 552 124 552 138 552 172 552 206 552 235 552 267 552 321 552 322 552 325 552 354 552 356 552 444 552 470 552 479 552 539 552 552 552 561 552 568 552 580 552 646 552 652 552 678 552 705 552 714 552 753 552 797 552 830 552 832 552 885 552 909 552 931 552 942 552 985 552 991 552 995 552 1064 552 1072 552 1111 552 1120 552 1244 552 1292 552 1316 552 1339 552 1403 552 1414 552 1446 552 1494 553 88 553 166 553 306 553 334 553 420 553 461 553 471 553 472 553 474 553 525 553 553 553 572 553 659 553 668 553 696 553 723 553 728 553 737 553 748 553 804 553 818 553 924 553 1062 553 1080 553 1096 553 1104 553 1143 553 1149 553 1192 553 1254 553 1272 553 1285 553 1293 553 1303 553 1319 553 1391 553 1405 553 1427 553 1469 554 2 554 74 554 84 554 95 554 111 554 113 554 132 554 173 554 201 554 209 554 227 554 239 554 241 554 247 554 275 554 293 554 306 554 315 554 334 554 353 554 362 554 384 554 386 554 420 554 471 554 472 554 474 554 488 554 515 554 554 554 566 554 675 554 723 554 858 554 924 554 970 554 971 554 1105 554 1122 554 1143 554 1157 554 1186 554 1192 554 1232 554 1248 554 1254 554 1256 554 1285 554 1303 554 1329 554 1391 555 23 555 37 555 49 555 75 555 123 555 128 555 167 555 178 555 184 555 198 555 219 555 290 555 319 555 326 555 350 555 360 555 376 555 402 555 416 555 418 555 422 555 443 555 457 555 503 555 508 555 517 555 551 555 555 555 559 555 573 555 574 555 582 555 589 555 593 555 622 555 639 555 644 555 657 555 673 555 703 555 725 555 732 555 756 555 766 555 770 555 777 555 800 555 805 555 886 555 916 555 933 555 955 555 1010 555 1015 555 1020 555 1087 555 1101 555 1107 555 1112 555 1166 555 1167 555 1185 555 1200 555 1203 555 1205 555 1211 555 1257 555 1268 555 1273 555 1311 555 1346 555 1388 555 1431 555 1433 555 1457 555 1479 555 1483 555 1492 556 72 556 79 556 135 556 147 556 149 556 189 556 253 556 272 556 344 556 373 556 387 556 397 556 401 556 404 556 455 556 484 556 491 556 520 556 556 556 591 556 600 556 611 556 640 556 684 556 733 556 743 556 784 556 807 556 844 556 875 556 910 556 911 556 978 556 990 556 993 556 999 556 1014 556 1069 556 1082 556 1180 556 1196 556 1206 556 1217 556 1230 556 1235 556 1277 556 1290 556 1355 556 1358 556 1370 556 1375 556 1393 556 1441 556 1456 556 1474 556 1484 557 43 557 46 557 104 557 118 557 154 557 176 557 287 557 309 557 369 557 385 557 456 557 500 557 532 557 541 557 557 557 565 557 651 557 724 557 747 557 779 557 878 557 902 557 927 557 957 557 1013 557 1128 557 1150 557 1182 557 1210 557 1243 557 1264 557 1270 557 1279 557 1295 557 1366 557 1380 557 1439 557 1489 558 22 558 107 558 156 558 170 558 266 558 378 558 449 558 507 558 530 558 558 558 570 558 607 558 613 558 621 558 763 558 791 558 862 558 873 558 900 558 937 558 1071 558 1127 558 1146 558 1156 558 1161 558 1162 558 1176 558 1184 558 1224 558 1402 558 1404 558 1444 558 1450 558 1464 559 10 559 37 559 49 559 68 559 128 559 170 559 184 559 198 559 210 559 290 559 299 559 300 559 350 559 357 559 376 559 402 559 433 559 503 559 551 559 555 559 559 559 578 559 593 559 601 559 622 559 627 559 657 559 703 559 704 559 725 559 756 559 766 559 770 559 886 559 898 559 916 559 933 559 1008 559 1020 559 1029 559 1088 559 1100 559 1166 559 1169 559 1189 559 1203 559 1257 559 1300 559 1338 559 1388 559 1433 559 1457 559 1460 559 1462 559 1483 559 1490 559 1492 560 0 560 73 560 130 560 152 560 200 560 205 560 222 560 259 560 288 560 312 560 338 560 442 560 465 560 518 560 560 560 587 560 655 560 702 560 734 560 752 560 778 560 815 560 872 560 892 560 983 560 1084 560 1135 560 1214 560 1271 560 1327 560 1330 560 1371 560 1382 560 1398 560 1400 560 1413 560 1481 561 27 561 38 561 96 561 255 561 277 561 322 561 354 561 395 561 399 561 440 561 479 561 552 561 561 561 590 561 652 561 711 561 714 561 881 561 887 561 909 561 942 561 992 561 1092 561 1140 561 1209 561 1283 561 1414 562 13 562 55 562 83 562 85 562 101 562 187 562 218 562 291 562 377 562 452 562 492 562 497 562 524 562 544 562 547 562 562 562 608 562 620 562 667 562 730 562 867 562 870 562 883 562 908 562 1091 562 1098 562 1225 562 1291 562 1313 562 1348 562 1361 562 1373 562 1496 563 26 563 30 563 53 563 58 563 82 563 86 563 90 563 102 563 175 563 191 563 211 563 212 563 233 563 250 563 270 563 277 563 332 563 349 563 405 563 440 563 444 563 451 563 511 563 563 563 579 563 623 563 626 563 658 563 701 563 720 563 785 563 846 563 863 563 901 563 934 563 959 563 1024 563 1035 563 1054 563 1057 563 1102 563 1113 563 1131 563 1137 563 1212 563 1283 563 1309 563 1340 563 1341 563 1390 563 1459 563 1475 564 2 564 74 564 84 564 93 564 95 564 120 564 126 564 132 564 194 564 201 564 227 564 231 564 239 564 241 564 271 564 275 564 282 564 296 564 311 564 315 564 362 564 450 564 454 564 463 564 515 564 516 564 564 564 670 564 719 564 796 564 801 564 838 564 858 564 971 564 975 564 1001 564 1023 564 1036 564 1050 564 1056 564 1058 564 1116 564 1119 564 1122 564 1157 564 1194 564 1248 564 1253 564 1280 564 1282 564 1354 564 1377 564 1384 564 1394 564 1395 564 1396 564 1435 564 1478 565 43 565 46 565 60 565 104 565 118 565 176 565 208 565 287 565 309 565 369 565 385 565 456 565 500 565 532 565 541 565 557 565 565 565 651 565 724 565 747 565 779 565 878 565 902 565 927 565 957 565 1013 565 1025 565 1030 565 1150 565 1182 565 1210 565 1220 565 1243 565 1264 565 1270 565 1279 565 1295 565 1366 565 1380 565 1489 566 113 566 132 566 201 566 227 566 241 566 247 566 293 566 306 566 353 566 362 566 384 566 386 566 471 566 474 566 481 566 488 566 515 566 554 566 566 566 675 566 696 566 798 566 818 566 924 566 1122 566 1186 566 1232 566 1254 566 1259 566 1272 566 1285 566 1302 566 1329 566 1391 567 79 567 217 567 223 567 253 567 279 567 408 567 452 567 478 567 484 567 526 567 544 567 567 567 584 567 591 567 606 567 608 567 624 567 640 567 684 567 690 567 807 567 822 567 839 567 875 567 883 567 908 567 972 567 1034 567 1078 567 1082 567 1206 567 1216 567 1229 567 1236 567 1250 567 1290 567 1313 567 1348 567 1356 567 1361 567 1370 567 1375 567 1498 568 116 568 138 568 174 568 206 568 235 568 325 568 356 568 470 568 479 568 539 568 552 568 568 568 646 568 678 568 705 568 714 568 753 568 755 568 797 568 832 568 885 568 909 568 925 568 942 568 979 568 985 568 995 568 1072 568 1120 568 1204 568 1261 568 1286 568 1339 568 1372 568 1401 568 1411 569 5 569 14 569 36 569 92 569 160 569 202 569 230 569 240 569 272 569 365 569 373 569 387 569 434 569 441 569 569 569 606 569 612 569 624 569 630 569 730 569 809 569 867 569 882 569 999 569 1018 569 1075 569 1076 569 1108 569 1196 569 1277 569 1331 569 1369 569 1461 569 1472 569 1476 569 1484 570 22 570 107 570 143 570 156 570 266 570 378 570 449 570 507 570 543 570 558 570 570 570 604 570 607 570 613 570 621 570 739 570 791 570 854 570 862 570 900 570 920 570 937 570 994 570 1071 570 1090 570 1127 570 1146 570 1156 570 1162 570 1176 570 1386 570 1444 571 50 571 68 571 75 571 141 571 195 571 210 571 294 571 299 571 300 571 314 571 333 571 342 571 357 571 368 571 379 571 433 571 504 571 514 571 538 571 551 571 571 571 657 571 697 571 704 571 811 571 836 571 904 571 916 571 930 571 1088 571 1109 571 1188 571 1189 571 1203 571 1269 571 1275 571 1300 571 1338 571 1352 571 1364 571 1374 571 1420 571 1437 571 1460 571 1495 572 62 572 88 572 173 572 209 572 334 572 420 572 426 572 472 572 477 572 488 572 489 572 553 572 572 572 581 572 659 572 710 572 723 572 728 572 737 572 788 572 818 572 899 572 917 572 1006 572 1062 572 1080 572 1093 572 1096 572 1104 572 1114 572 1115 572 1143 572 1149 572 1192 572 1233 572 1293 572 1469 573 37 573 49 573 122 573 178 573 184 573 203 573 376 573 443 573 468 573 503 573 517 573 551 573 555 573 573 573 589 573 639 573 657 573 693 573 697 573 725 573 750 573 756 573 766 573 805 573 836 573 1087 573 1107 573 1185 573 1200 573 1246 573 1323 573 1364 573 1483 573 1492 574 37 574 49 574 128 574 290 574 443 574 555 574 574 574 582 574 589 574 639 574 770 574 800 574 805 574 933 574 955 574 1020 574 1167 574 1169 574 1246 574 1273 574 1364 574 1379 574 1429 574 1431 574 1433 574 1483 575 6 575 17 575 42 575 172 575 263 575 268 575 283 575 303 575 304 575 352 575 380 575 394 575 399 575 464 575 575 575 576 575 580 575 623 575 625 575 634 575 681 575 695 575 708 575 745 575 767 575 810 575 830 575 896 575 921 575 931 575 961 575 969 575 1007 575 1039 575 1059 575 1067 575 1160 575 1199 575 1316 575 1333 575 1378 575 1468 575 1499 576 6 576 42 576 66 576 124 576 129 576 131 576 145 576 162 576 172 576 261 576 263 576 322 576 325 576 328 576 392 576 394 576 395 576 486 576 498 576 539 576 575 576 576 576 634 576 649 576 678 576 757 576 767 576 786 576 810 576 887 576 921 576 942 576 944 576 946 576 961 576 969 576 992 576 1007 576 1072 576 1125 576 1155 576 1160 576 1173 576 1178 576 1209 576 1244 576 1333 576 1353 577 35 577 140 577 162 577 172 577 188 577 284 577 313 577 321 577 363 577 374 577 382 577 406 577 411 577 498 577 531 577 540 577 577 577 718 577 741 577 781 577 782 577 789 577 831 577 852 577 881 577 918 577 929 577 961 577 991 577 1049 577 1092 577 1094 577 1123 577 1213 577 1223 577 1251 577 1292 578 10 578 50 578 61 578 103 578 110 578 198 578 210 578 299 578 341 578 342 578 357 578 364 578 379 578 447 578 493 578 504 578 514 578 542 578 559 578 578 578 586 578 601 578 643 578 666 578 687 578 704 578 811 578 898 578 913 578 915 578 1008 578 1095 578 1109 578 1168 578 1189 578 1297 578 1312 578 1338 578 1420 578 1437 579 26 579 53 579 78 579 82 579 86 579 102 579 191 579 200 579 211 579 277 579 308 579 312 579 332 579 348 579 349 579 405 579 428 579 444 579 451 579 534 579 536 579 563 579 579 579 610 579 626 579 658 579 846 579 863 579 901 579 959 579 1024 579 1035 579 1066 579 1084 579 1102 579 1113 579 1131 579 1135 579 1137 579 1183 579 1212 579 1221 579 1309 579 1327 579 1340 579 1459 579 1475 579 1481 579 1486 579 1494 580 53 580 66 580 206 580 211 580 212 580 216 580 263 580 277 580 283 580 286 580 322 580 325 580 328 580 348 580 349 580 354 580 394 580 399 580 405 580 431 580 440 580 444 580 451 580 464 580 552 580 575 580 580 580 623 580 625 580 631 580 652 580 681 580 720 580 776 580 792 580 795 580 829 580 874 580 923 580 980 580 1024 580 1046 580 1059 580 1064 580 1131 580 1137 580 1140 580 1141 580 1199 580 1238 580 1316 580 1336 580 1351 580 1378 580 1390 580 1403 580 1481 580 1494 581 88 581 132 581 209 581 227 581 324 581 386 581 420 581 474 581 515 581 525 581 572 581 581 581 659 581 723 581 728 581 737 581 788 581 798 581 818 581 1006 581 1062 581 1093 581 1104 581 1115 581 1149 581 1192 581 1232 581 1259 581 1293 581 1391 582 10 582 23 582 49 582 68 582 75 582 184 582 198 582 290 582 360 582 368 582 376 582 443 582 503 582 517 582 542 582 551 582 555 582 574 582 582 582 643 582 657 582 673 582 693 582 697 582 756 582 770 582 805 582 811 582 898 582 955 582 1008 582 1020 582 1101 582 1107 582 1166 582 1168 582 1203 582 1240 582 1246 582 1323 582 1344 582 1352 582 1364 582 1374 582 1429 582 1433 582 1457 582 1483 583 7 583 20 583 22 583 37 583 87 583 156 583 167 583 204 583 242 583 266 583 292 583 350 583 396 583 403 583 446 583 449 583 508 583 530 583 543 583 583 583 604 583 621 583 703 583 777 583 791 583 873 583 900 583 903 583 928 583 935 583 948 583 958 583 987 583 994 583 1005 583 1029 583 1038 583 1071 583 1106 583 1211 583 1257 583 1268 583 1273 583 1287 583 1289 583 1324 583 1326 583 1450 583 1458 584 72 584 83 584 135 584 144 584 187 584 217 584 224 584 232 584 253 584 343 584 370 584 389 584 397 584 424 584 455 584 478 584 497 584 520 584 544 584 567 584 584 584 591 584 638 584 733 584 860 584 875 584 906 584 908 584 972 584 1034 584 1078 584 1136 584 1142 584 1179 584 1198 584 1216 584 1229 584 1250 584 1348 584 1356 584 1361 584 1375 584 1496 585 81 585 99 585 106 585 329 585 337 585 393 585 430 585 487 585 505 585 510 585 529 585 550 585 585 585 665 585 717 585 754 585 820 585 890 585 918 585 965 585 968 585 988 585 1000 585 1019 585 1060 585 1070 585 1226 585 1241 585 1286 585 1408 585 1428 585 1445 585 1465 585 1471 586 33 586 61 586 110 586 155 586 169 586 341 586 342 586 364 586 379 586 447 586 458 586 493 586 504 586 578 586 586 586 749 586 773 586 843 586 904 586 913 586 941 586 943 586 956 586 1109 586 1269 586 1312 586 1345 586 1421 586 1437 587 19 587 152 587 185 587 259 587 288 587 338 587 359 587 398 587 560 587 587 587 598 587 650 587 765 587 778 587 802 587 871 587 892 587 1214 587 1218 587 1242 587 1330 587 1343 587 1382 587 1412 587 1413 587 1419 587 1440 587 1442 588 16 588 34 588 40 588 136 588 150 588 159 588 171 588 207 588 213 588 252 588 274 588 297 588 317 588 390 588 423 588 432 588 439 588 495 588 588 588 615 588 641 588 706 588 738 588 744 588 764 588 813 588 848 588 853 588 868 588 889 588 936 588 964 588 1005 588 1073 588 1110 588 1130 588 1174 588 1252 588 1255 588 1274 588 1284 588 1322 588 1328 588 1381 588 1416 588 1422 588 1434 588 1436 589 49 589 122 589 184 589 319 589 350 589 360 589 376 589 416 589 443 589 503 589 555 589 573 589 574 589 589 589 622 589 639 589 657 589 725 589 750 589 766 589 770 589 777 589 800 589 805 589 886 589 1020 589 1087 589 1107 589 1166 589 1167 589 1185 589 1200 589 1205 589 1257 589 1273 589 1311 589 1364 589 1388 589 1479 589 1483 589 1492 590 17 590 129 590 133 590 145 590 172 590 180 590 192 590 255 590 261 590 304 590 322 590 325 590 328 590 340 590 352 590 394 590 395 590 399 590 522 590 531 590 561 590 590 590 634 590 681 590 695 590 711 590 745 590 776 590 786 590 969 590 980 590 992 590 1092 590 1125 590 1140 590 1155 590 1199 590 1209 590 1359 590 1415 591 57 591 76 591 135 591 144 591 149 591 189 591 217 591 232 591 253 591 305 591 344 591 370 591 397 591 401 591 424 591 455 591 478 591 484 591 520 591 556 591 567 591 584 591 591 591 611 591 684 591 733 591 807 591 822 591 860 591 875 591 893 591 911 591 978 591 990 591 993 591 1014 591 1082 591 1136 591 1142 591 1216 591 1217 591 1235 591 1250 591 1290 591 1348 591 1355 591 1356 591 1358 591 1370 591 1375 591 1393 591 1498 592 56 592 72 592 83 592 101 592 164 592 187 592 217 592 223 592 224 592 232 592 279 592 343 592 371 592 377 592 389 592 391 592 408 592 478 592 497 592 524 592 547 592 592 592 600 592 638 592 680 592 784 592 814 592 844 592 867 592 906 592 908 592 972 592 1034 592 1068 592 1078 592 1099 592 1142 592 1179 592 1180 592 1198 592 1217 592 1230 592 1299 592 1361 592 1373 592 1407 592 1441 592 1474 592 1496 593 20 593 31 593 37 593 75 593 123 593 128 593 167 593 170 593 178 593 198 593 219 593 319 593 350 593 360 593 402 593 416 593 418 593 422 593 457 593 555 593 559 593 593 593 622 593 627 593 644 593 673 593 703 593 725 593 736 593 756 593 766 593 770 593 777 593 800 593 805 593 886 593 900 593 916 593 928 593 933 593 997 593 1015 593 1020 593 1087 593 1100 593 1101 593 1106 593 1112 593 1154 593 1161 593 1166 593 1171 593 1185 593 1205 593 1211 593 1257 593 1268 593 1289 593 1294 593 1311 593 1346 593 1388 593 1402 593 1426 593 1433 593 1479 593 1490 593 1492 594 29 594 35 594 41 594 45 594 51 594 124 594 199 594 235 594 281 594 284 594 304 594 321 594 358 594 363 594 374 594 380 594 501 594 522 594 594 594 661 594 695 594 726 594 729 594 782 594 872 594 885 594 921 594 929 594 1007 594 1086 594 1164 594 1339 594 1417 594 1468 594 1487 595 214 595 236 595 476 595 595 595 742 595 973 595 981 595 984 595 1117 595 1182 595 1264 596 100 596 134 596 140 596 179 596 226 596 245 596 246 596 260 596 265 596 310 596 320 596 329 596 337 596 393 596 406 596 417 596 421 596 445 596 487 596 596 596 616 596 653 596 688 596 717 596 740 596 754 596 762 596 772 596 806 596 918 596 922 596 932 596 945 596 963 596 968 596 974 596 1000 596 1042 596 1045 596 1077 596 1094 596 1139 596 1158 596 1181 596 1226 596 1241 596 1251 596 1315 596 1387 596 1408 596 1428 596 1438 596 1445 596 1453 596 1470 597 0 597 51 597 98 597 151 597 185 597 186 597 238 597 256 597 264 597 278 597 301 597 358 597 359 597 367 597 419 597 436 597 437 597 480 597 496 597 545 597 546 597 597 597 645 597 646 597 650 597 661 597 663 597 665 597 676 597 682 597 699 597 729 597 758 597 771 597 817 597 821 597 828 597 895 597 996 597 1011 597 1060 597 1085 597 1197 597 1208 597 1215 597 1305 597 1398 597 1417 597 1440 597 1487 598 26 598 185 598 264 598 267 598 288 598 359 598 398 598 436 598 465 598 475 598 480 598 482 598 494 598 518 598 546 598 587 598 598 598 650 598 674 598 758 598 760 598 771 598 842 598 895 598 1009 598 1079 598 1147 598 1218 598 1242 598 1266 598 1314 598 1318 598 1321 598 1327 598 1412 598 1440 599 3 599 8 599 19 599 54 599 64 599 73 599 152 599 158 599 182 599 205 599 330 599 473 599 527 599 599 599 628 599 655 599 660 599 734 599 837 599 849 599 892 599 951 599 1132 599 1144 599 1382 599 1419 599 1448 599 1455 599 1463 600 79 600 92 600 125 600 135 600 160 600 189 600 223 600 230 600 272 600 279 600 295 600 371 600 373 600 387 600 391 600 441 600 483 600 484 600 491 600 520 600 556 600 592 600 600 600 611 600 624 600 638 600 640 600 690 600 694 600 784 600 807 600 809 600 814 600 844 600 888 600 910 600 911 600 978 600 999 600 1014 600 1068 600 1069 600 1075 600 1078 600 1082 600 1097 600 1099 600 1180 600 1196 600 1206 600 1217 600 1230 600 1236 600 1277 600 1281 600 1355 600 1361 600 1370 600 1407 600 1441 600 1474 600 1476 600 1484 601 10 601 23 601 103 601 184 601 198 601 210 601 341 601 357 601 376 601 503 601 542 601 559 601 578 601 601 601 627 601 666 601 687 601 704 601 725 601 736 601 750 601 766 601 898 601 915 601 1008 601 1095 601 1297 601 1300 601 1312 601 1338 601 1429 601 1457 601 1492 602 21 602 81 602 99 602 106 602 225 602 245 602 249 602 329 602 337 602 412 602 430 602 445 602 509 602 550 602 602 602 656 602 787 602 820 602 922 602 949 602 952 602 1022 602 1042 602 1070 602 1152 602 1175 602 1190 602 1241 602 1288 602 1317 602 1408 602 1428 603 5 603 13 603 14 603 47 603 52 603 63 603 65 603 85 603 92 603 160 603 165 603 218 603 230 603 234 603 240 603 291 603 371 603 377 603 434 603 441 603 492 603 528 603 544 603 603 603 609 603 612 603 620 603 624 603 630 603 642 603 648 603 690 603 730 603 882 603 883 603 939 603 1028 603 1075 603 1076 603 1108 603 1159 603 1196 603 1236 603 1265 603 1291 603 1369 603 1373 603 1472 604 22 604 91 604 143 604 156 604 266 604 378 604 396 604 446 604 449 604 507 604 508 604 530 604 570 604 583 604 604 604 613 604 621 604 636 604 644 604 669 604 691 604 727 604 739 604 841 604 854 604 873 604 903 604 920 604 948 604 962 604 987 604 994 604 1010 604 1038 604 1090 604 1151 604 1176 604 1324 604 1326 604 1431 604 1444 604 1450 605 156 605 159 605 196 605 266 605 345 605 383 605 400 605 448 605 543 605 605 605 615 605 707 605 739 605 862 605 920 605 947 605 960 605 1037 605 1090 605 1126 605 1127 605 1172 605 1267 605 1325 605 1386 605 1434 605 1436 606 13 606 14 606 79 606 92 606 101 606 279 606 373 606 408 606 434 606 452 606 484 606 526 606 528 606 547 606 567 606 569 606 606 606 608 606 624 606 690 606 730 606 822 606 867 606 882 606 883 606 910 606 1018 606 1076 606 1097 606 1098 606 1159 606 1196 606 1236 606 1291 606 1331 606 1348 606 1369 606 1476 606 1484 607 22 607 31 607 107 607 123 607 266 607 336 607 378 607 449 607 507 607 558 607 570 607 607 607 621 607 763 607 791 607 854 607 862 607 873 607 900 607 935 607 937 607 1071 607 1127 607 1146 607 1156 607 1161 607 1162 607 1176 607 1184 607 1224 607 1289 607 1294 607 1402 607 1404 607 1444 607 1464 608 13 608 36 608 55 608 56 608 85 608 101 608 187 608 218 608 291 608 434 608 452 608 497 608 524 608 547 608 562 608 567 608 606 608 608 608 620 608 667 608 730 608 822 608 867 608 870 608 883 608 908 608 1034 608 1091 608 1098 608 1225 608 1250 608 1290 608 1291 608 1313 608 1348 608 1498 609 5 609 12 609 13 609 52 609 55 609 65 609 85 609 165 609 218 609 230 609 234 609 240 609 291 609 377 609 441 609 492 609 528 609 603 609 609 609 620 609 630 609 642 609 648 609 730 609 742 609 870 609 882 609 883 609 939 609 1028 609 1076 609 1091 609 1108 609 1129 609 1159 609 1265 609 1369 609 1461 609 1472 610 15 610 30 610 53 610 54 610 78 610 82 610 90 610 102 610 121 610 130 610 191 610 211 610 229 610 257 610 262 610 270 610 308 610 348 610 351 610 428 610 451 610 506 610 511 610 533 610 534 610 536 610 537 610 549 610 579 610 610 610 619 610 637 610 658 610 685 610 701 610 702 610 752 610 761 610 812 610 827 610 829 610 863 610 884 610 901 610 923 610 1003 610 1057 610 1065 610 1066 610 1084 610 1135 610 1183 610 1219 610 1258 610 1336 610 1340 610 1360 610 1390 610 1459 610 1481 611 72 611 76 611 135 611 144 611 149 611 189 611 232 611 253 611 272 611 295 611 370 611 373 611 387 611 391 611 397 611 401 611 424 611 455 611 484 611 491 611 520 611 556 611 591 611 600 611 611 611 684 611 743 611 784 611 844 611 910 611 911 611 940 611 978 611 990 611 999 611 1014 611 1069 611 1179 611 1216 611 1230 611 1235 611 1277 611 1290 611 1355 611 1358 611 1370 611 1393 611 1441 611 1484 612 13 612 14 612 47 612 65 612 83 612 92 612 125 612 160 612 218 612 240 612 272 612 291 612 295 612 305 612 373 612 377 612 434 612 441 612 452 612 483 612 484 612 528 612 569 612 603 612 612 612 624 612 630 612 640 612 648 612 690 612 809 612 882 612 883 612 999 612 1014 612 1018 612 1075 612 1076 612 1082 612 1159 612 1196 612 1206 612 1229 612 1236 612 1265 612 1277 612 1331 612 1356 612 1369 612 1370 612 1375 612 1461 612 1472 612 1484 613 7 613 22 613 91 613 143 613 156 613 219 613 242 613 266 613 378 613 396 613 446 613 449 613 507 613 508 613 558 613 570 613 604 613 613 613 621 613 636 613 639 613 644 613 669 613 791 613 854 613 903 613 935 613 937 613 948 613 962 613 987 613 1038 613 1071 613 1151 613 1156 613 1161 613 1171 613 1176 613 1273 613 1326 613 1431 613 1444 613 1450 613 1464 614 3 614 8 614 19 614 64 614 97 614 183 614 197 614 296 614 407 614 473 614 499 614 614 614 628 614 654 614 660 614 662 614 670 614 709 614 765 614 796 614 816 614 849 614 892 614 951 614 1001 614 1036 614 1050 614 1132 614 1227 614 1242 614 1354 614 1419 615 136 615 159 615 196 615 252 615 345 615 383 615 400 615 448 615 588 615 605 615 615 615 641 615 707 615 739 615 764 615 783 615 813 615 847 615 947 615 1037 615 1090 615 1126 615 1172 615 1174 615 1252 615 1284 615 1325 615 1386 615 1434 615 1436 615 1493 616 1 616 100 616 226 616 246 616 260 616 265 616 310 616 320 616 417 616 421 616 445 616 487 616 596 616 616 616 653 616 656 616 672 616 688 616 712 616 717 616 740 616 754 616 762 616 806 616 855 616 856 616 880 616 922 616 945 616 1042 616 1045 616 1074 616 1077 616 1139 616 1158 616 1195 616 1226 616 1315 616 1317 616 1387 616 1397 616 1428 616 1438 616 1453 616 1470 616 1473 617 91 617 143 617 167 617 178 617 219 617 319 617 326 617 378 617 416 617 418 617 422 617 617 617 636 617 644 617 732 617 777 617 854 617 900 617 935 617 958 617 962 617 997 617 1010 617 1015 617 1146 617 1154 617 1176 617 1205 617 1289 617 1294 617 1311 617 1426 617 1431 617 1479 618 9 618 15 618 54 618 73 618 90 618 121 618 158 618 182 618 205 618 221 618 229 618 257 618 262 618 285 618 351 618 381 618 462 618 485 618 490 618 534 618 536 618 618 618 619 618 698 618 701 618 735 618 808 618 815 618 823 618 827 618 837 618 864 618 905 618 1044 618 1144 618 1153 618 1183 618 1221 618 1258 618 1343 618 1360 618 1389 618 1448 618 1452 618 1455 619 15 619 54 619 58 619 121 619 158 619 191 619 221 619 229 619 257 619 285 619 351 619 428 619 462 619 490 619 511 619 533 619 534 619 536 619 610 619 618 619 619 619 701 619 827 619 864 619 1044 619 1065 619 1153 619 1183 619 1258 619 1340 619 1360 619 1452 620 13 620 36 620 55 620 56 620 85 620 92 620 101 620 187 620 218 620 291 620 377 620 441 620 492 620 497 620 524 620 547 620 562 620 603 620 608 620 609 620 620 620 667 620 730 620 867 620 870 620 883 620 908 620 1076 620 1091 620 1098 620 1129 620 1225 620 1291 620 1299 620 1369 620 1373 620 1496 621 7 621 22 621 107 621 143 621 156 621 167 621 219 621 266 621 378 621 396 621 403 621 446 621 449 621 507 621 530 621 543 621 558 621 570 621 583 621 604 621 607 621 613 621 621 621 636 621 644 621 669 621 739 621 791 621 854 621 862 621 873 621 900 621 903 621 920 621 935 621 937 621 948 621 958 621 962 621 987 621 994 621 1005 621 1038 621 1071 621 1090 621 1154 621 1162 621 1176 621 1224 621 1289 621 1294 621 1324 621 1326 621 1386 621 1431 621 1444 621 1450 621 1464 622 31 622 37 622 75 622 122 622 123 622 167 622 170 622 178 622 198 622 219 622 319 622 326 622 350 622 360 622 376 622 402 622 416 622 418 622 422 622 457 622 551 622 555 622 559 622 589 622 593 622 622 622 673 622 703 622 725 622 756 622 766 622 770 622 777 622 800 622 886 622 916 622 928 622 933 622 935 622 958 622 997 622 1015 622 1020 622 1071 622 1087 622 1106 622 1112 622 1154 622 1166 622 1185 622 1200 622 1205 622 1211 622 1257 622 1268 622 1289 622 1294 622 1311 622 1388 622 1426 622 1433 622 1457 622 1479 622 1490 622 1492 623 82 623 191 623 212 623 233 623 244 623 286 623 349 623 464 623 563 623 575 623 580 623 623 623 625 623 767 623 795 623 934 623 959 623 967 623 1007 623 1035 623 1064 623 1113 623 1199 623 1316 623 1341 623 1378 623 1390 623 1467 624 14 624 47 624 79 624 92 624 125 624 160 624 165 624 230 624 234 624 240 624 272 624 279 624 295 624 373 624 387 624 404 624 434 624 441 624 483 624 484 624 528 624 567 624 569 624 600 624 603 624 606 624 612 624 624 624 630 624 640 624 648 624 690 624 694 624 743 624 807 624 809 624 882 624 910 624 999 624 1018 624 1075 624 1076 624 1082 624 1099 624 1159 624 1196 624 1236 624 1277 624 1355 624 1375 624 1472 624 1476 624 1484 625 28 625 66 625 86 625 193 625 200 625 206 625 211 625 233 625 244 625 263 625 283 625 348 625 349 625 355 625 394 625 399 625 405 625 425 625 444 625 464 625 575 625 580 625 623 625 625 625 652 625 708 625 720 625 767 625 829 625 830 625 896 625 921 625 931 625 969 625 1007 625 1059 625 1064 625 1140 625 1165 625 1238 625 1244 625 1309 625 1316 625 1341 625 1378 625 1390 625 1403 625 1467 625 1468 625 1494 626 26 626 53 626 58 626 78 626 82 626 86 626 102 626 191 626 193 626 200 626 211 626 250 626 257 626 277 626 308 626 332 626 348 626 349 626 405 626 428 626 431 626 440 626 444 626 451 626 533 626 534 626 563 626 579 626 626 626 658 626 846 626 863 626 901 626 959 626 1024 626 1035 626 1084 626 1102 626 1131 626 1135 626 1137 626 1249 626 1309 626 1340 626 1341 626 1459 626 1475 626 1481 626 1494 627 23 627 37 627 49 627 68 627 75 627 170 627 184 627 198 627 210 627 300 627 314 627 350 627 357 627 376 627 433 627 457 627 503 627 551 627 559 627 593 627 601 627 627 627 657 627 666 627 703 627 704 627 725 627 750 627 756 627 766 627 770 627 886 627 898 627 916 627 930 627 933 627 1008 627 1020 627 1029 627 1088 627 1100 627 1166 627 1185 627 1300 627 1338 627 1429 627 1457 627 1460 627 1483 627 1492 627 1495 628 3 628 8 628 19 628 64 628 97 628 183 628 296 628 330 628 407 628 427 628 473 628 499 628 599 628 614 628 628 628 660 628 662 628 709 628 765 628 802 628 816 628 849 628 892 628 951 628 1132 628 1227 628 1242 628 1419 629 24 629 222 629 244 629 283 629 327 629 348 629 355 629 429 629 475 629 482 629 522 629 629 629 708 629 755 629 824 629 866 629 884 629 1007 629 1204 629 1261 629 1314 629 1339 629 1400 629 1403 629 1468 629 1485 629 1494 630 5 630 13 630 14 630 47 630 52 630 63 630 65 630 92 630 160 630 165 630 202 630 218 630 230 630 234 630 240 630 272 630 291 630 365 630 373 630 377 630 387 630 434 630 441 630 483 630 528 630 569 630 603 630 609 630 612 630 624 630 630 630 642 630 648 630 690 630 742 630 809 630 882 630 883 630 939 630 1018 630 1028 630 1075 630 1076 630 1108 630 1159 630 1196 630 1206 630 1236 630 1265 630 1331 630 1369 630 1461 630 1472 630 1476 630 1484 631 53 631 78 631 180 631 212 631 283 631 286 631 308 631 322 631 328 631 348 631 349 631 354 631 394 631 399 631 440 631 460 631 511 631 549 631 580 631 631 631 652 631 720 631 752 631 761 631 795 631 812 631 829 631 923 631 980 631 1057 631 1059 631 1131 631 1137 631 1140 631 1238 631 1316 631 1336 631 1351 631 1378 631 1390 631 1418 631 1459 631 1481 632 4 632 16 632 71 632 155 632 177 632 248 632 297 632 331 632 432 632 469 632 519 632 632 632 706 632 716 632 738 632 977 632 1053 632 1073 632 1274 632 1328 632 1357 632 1367 632 1416 632 1423 632 1451 632 1480 633 39 633 60 633 77 633 104 633 105 633 109 633 112 633 154 633 176 633 208 633 254 633 280 633 287 633 302 633 369 633 385 633 410 633 456 633 500 633 541 633 633 633 651 633 724 633 747 633 779 633 826 633 861 633 878 633 891 633 902 633 927 633 957 633 976 633 989 633 1013 633 1025 633 1030 633 1128 633 1148 633 1207 633 1210 633 1243 633 1279 633 1295 633 1301 633 1310 633 1380 633 1383 633 1439 634 17 634 27 634 96 634 124 634 129 634 162 634 172 634 180 634 255 634 263 634 283 634 304 634 322 634 328 634 354 634 363 634 394 634 395 634 399 634 413 634 531 634 575 634 576 634 590 634 634 634 652 634 681 634 695 634 711 634 786 634 830 634 881 634 887 634 969 634 991 634 992 634 1059 634 1092 634 1123 634 1125 634 1140 634 1173 634 1209 634 1213 634 1332 634 1351 634 1414 634 1446 635 6 635 42 635 45 635 48 635 51 635 70 635 108 635 256 635 273 635 303 635 339 635 363 635 413 635 437 635 438 635 512 635 521 635 635 635 661 635 718 635 722 635 729 635 731 635 780 635 782 635 810 635 852 635 880 635 961 635 1033 635 1049 635 1052 635 1081 635 1086 635 1163 635 1201 635 1208 635 1239 635 1263 635 1362 635 1363 635 1399 635 1417 635 1466 635 1487 635 1488 636 91 636 143 636 167 636 178 636 219 636 326 636 378 636 422 636 446 636 508 636 604 636 613 636 617 636 621 636 636 636 644 636 669 636 732 636 854 636 903 636 935 636 958 636 962 636 987 636 997 636 1010 636 1038 636 1146 636 1151 636 1154 636 1167 636 1326 636 1431 637 30 637 38 637 53 637 78 637 130 637 212 637 216 637 262 637 270 637 428 637 431 637 460 637 464 637 506 637 511 637 534 637 549 637 610 637 637 637 808 637 812 637 874 637 923 637 1057 637 1065 637 1084 637 1187 637 1219 637 1234 637 1238 637 1249 637 1336 637 1360 637 1415 637 1418 638 56 638 72 638 79 638 164 638 223 638 279 638 343 638 373 638 389 638 391 638 408 638 478 638 483 638 484 638 497 638 520 638 524 638 547 638 584 638 592 638 600 638 638 638 680 638 784 638 814 638 822 638 839 638 844 638 867 638 906 638 908 638 911 638 940 638 972 638 1034 638 1068 638 1078 638 1097 638 1098 638 1099 638 1179 638 1180 638 1198 638 1206 638 1229 638 1230 638 1281 638 1299 638 1361 638 1373 638 1407 638 1441 638 1474 638 1496 639 37 639 49 639 91 639 128 639 219 639 242 639 350 639 360 639 443 639 446 639 508 639 555 639 573 639 574 639 589 639 613 639 639 639 644 639 770 639 777 639 800 639 805 639 903 639 933 639 955 639 1087 639 1161 639 1167 639 1185 639 1200 639 1205 639 1273 639 1379 639 1388 639 1431 639 1450 639 1479 639 1483 640 14 640 79 640 92 640 125 640 223 640 224 640 272 640 279 640 295 640 371 640 373 640 377 640 387 640 441 640 452 640 483 640 484 640 544 640 556 640 567 640 600 640 612 640 624 640 640 640 648 640 684 640 690 640 694 640 807 640 875 640 882 640 910 640 972 640 1068 640 1075 640 1078 640 1082 640 1099 640 1180 640 1196 640 1217 640 1236 640 1277 640 1355 640 1356 640 1361 640 1373 640 1375 640 1407 640 1441 640 1474 640 1476 640 1484 641 16 641 136 641 159 641 196 641 207 641 252 641 274 641 297 641 317 641 390 641 423 641 432 641 439 641 448 641 469 641 548 641 588 641 615 641 641 641 706 641 707 641 738 641 763 641 764 641 889 641 936 641 960 641 964 641 977 641 1005 641 1037 641 1126 641 1130 641 1172 641 1174 641 1252 641 1255 641 1274 641 1284 641 1287 641 1322 641 1324 641 1328 641 1386 641 1416 641 1422 641 1434 641 1436 641 1493 642 5 642 12 642 52 642 63 642 65 642 85 642 165 642 202 642 230 642 234 642 240 642 365 642 441 642 492 642 528 642 603 642 609 642 630 642 642 642 742 642 759 642 939 642 1026 642 1028 642 1108 642 1129 642 1159 642 1265 642 1461 642 1472 643 10 643 23 643 103 643 122 643 341 643 517 643 542 643 578 643 582 643 643 643 666 643 687 643 693 643 750 643 811 643 898 643 913 643 915 643 943 643 1008 643 1095 643 1109 643 1168 643 1240 643 1246 643 1275 643 1297 643 1323 643 1344 643 1352 643 1429 643 1495 644 91 644 143 644 167 644 178 644 219 644 242 644 319 644 326 644 350 644 360 644 378 644 416 644 418 644 422 644 446 644 508 644 555 644 593 644 604 644 613 644 617 644 621 644 636 644 639 644 644 644 732 644 777 644 800 644 854 644 886 644 900 644 903 644 928 644 935 644 958 644 962 644 997 644 1010 644 1015 644 1087 644 1146 644 1151 644 1154 644 1161 644 1167 644 1171 644 1200 644 1205 644 1211 644 1257 644 1268 644 1289 644 1294 644 1311 644 1326 644 1346 644 1388 644 1426 644 1431 644 1479 645 98 645 151 645 185 645 186 645 256 645 264 645 288 645 301 645 367 645 398 645 419 645 437 645 494 645 597 645 645 645 650 645 663 645 676 645 682 645 683 645 699 645 760 645 803 645 842 645 895 645 1011 645 1060 645 1083 645 1197 645 1263 645 1305 645 1371 645 1417 645 1440 645 1487 646 116 646 138 646 174 646 206 646 267 646 325 646 355 646 356 646 359 646 429 646 431 646 436 646 444 646 539 646 552 646 568 646 597 646 646 646 650 646 652 646 676 646 708 646 714 646 755 646 758 646 771 646 776 646 885 646 897 646 944 646 965 646 985 646 992 646 995 646 1007 646 1046 646 1204 646 1244 646 1316 646 1321 646 1339 647 120 647 132 647 201 647 214 647 239 647 275 647 293 647 311 647 353 647 361 647 372 647 415 647 488 647 647 647 677 647 719 647 793 647 858 647 971 647 1006 647 1023 647 1051 647 1058 647 1157 647 1192 647 1307 647 1377 647 1395 647 1424 647 1435 648 13 648 14 648 47 648 55 648 63 648 83 648 160 648 218 648 223 648 234 648 240 648 291 648 371 648 377 648 434 648 441 648 483 648 492 648 528 648 544 648 603 648 609 648 612 648 624 648 630 648 640 648 648 648 690 648 694 648 814 648 882 648 883 648 939 648 1068 648 1075 648 1076 648 1078 648 1099 648 1108 648 1159 648 1180 648 1196 648 1373 648 1407 648 1441 649 42 649 96 649 124 649 127 649 131 649 162 649 228 649 243 649 263 649 392 649 479 649 486 649 498 649 501 649 502 649 576 649 649 649 678 649 679 649 726 649 746 649 757 649 775 649 786 649 789 649 797 649 834 649 879 649 942 649 946 649 961 649 1016 649 1072 649 1160 649 1173 649 1213 649 1332 649 1353 649 1372 650 185 650 264 650 288 650 359 650 398 650 436 650 480 650 482 650 494 650 546 650 587 650 597 650 598 650 645 650 646 650 650 650 674 650 676 650 683 650 699 650 708 650 758 650 842 650 895 650 1079 650 1085 650 1197 650 1218 650 1266 650 1305 650 1314 650 1371 650 1412 650 1413 650 1440 651 43 651 104 651 105 651 109 651 118 651 176 651 208 651 254 651 287 651 309 651 410 651 456 651 500 651 532 651 557 651 565 651 633 651 651 651 747 651 779 651 826 651 878 651 899 651 902 651 927 651 957 651 989 651 1025 651 1030 651 1150 651 1182 651 1210 651 1220 651 1243 651 1264 651 1270 651 1279 651 1295 651 1310 651 1350 651 1366 651 1380 651 1383 651 1489 652 28 652 116 652 206 652 268 652 277 652 283 652 286 652 322 652 325 652 328 652 348 652 349 652 354 652 355 652 394 652 395 652 399 652 431 652 440 652 444 652 464 652 552 652 561 652 580 652 625 652 631 652 634 652 646 652 652 652 708 652 720 652 755 652 776 652 795 652 829 652 887 652 942 652 969 652 980 652 995 652 1007 652 1046 652 1059 652 1064 652 1125 652 1140 652 1199 652 1209 652 1238 652 1244 652 1316 652 1351 652 1403 652 1414 652 1446 652 1481 652 1494 652 1499 653 80 653 94 653 179 653 225 653 226 653 246 653 249 653 310 653 320 653 329 653 445 653 596 653 616 653 653 653 656 653 664 653 672 653 688 653 712 653 740 653 754 653 762 653 806 653 855 653 856 653 880 653 922 653 963 653 966 653 974 653 1022 653 1032 653 1042 653 1045 653 1063 653 1077 653 1139 653 1170 653 1175 653 1181 653 1195 653 1288 653 1317 653 1387 653 1428 653 1438 654 2 654 93 654 95 654 97 654 126 654 153 654 194 654 197 654 220 654 247 654 296 654 362 654 463 654 471 654 499 654 614 654 654 654 662 654 670 654 765 654 796 654 816 654 871 654 970 654 1001 654 1036 654 1040 654 1050 654 1105 654 1186 654 1191 654 1218 654 1242 654 1248 654 1329 654 1354 654 1384 654 1394 654 1478 655 19 655 73 655 130 655 152 655 205 655 259 655 270 655 285 655 330 655 338 655 549 655 560 655 599 655 655 655 698 655 701 655 734 655 752 655 761 655 778 655 802 655 815 655 866 655 871 655 892 655 905 655 983 655 1044 655 1084 655 1118 655 1145 655 1212 655 1214 655 1330 655 1343 655 1382 655 1400 655 1413 655 1442 655 1455 656 1 656 225 656 226 656 249 656 329 656 509 656 550 656 602 656 616 656 653 656 656 656 672 656 712 656 820 656 825 656 845 656 855 656 922 656 966 656 1063 656 1074 656 1170 656 1175 656 1288 656 1317 656 1335 656 1342 656 1428 657 10 657 37 657 49 657 68 657 75 657 128 657 141 657 184 657 198 657 203 657 204 657 290 657 294 657 300 657 350 657 357 657 360 657 368 657 376 657 402 657 433 657 443 657 503 657 551 657 555 657 559 657 571 657 573 657 582 657 589 657 627 657 657 657 671 657 673 657 697 657 703 657 725 657 756 657 770 657 805 657 836 657 886 657 898 657 916 657 930 657 1020 657 1029 657 1088 657 1100 657 1101 657 1107 657 1166 657 1185 657 1203 657 1257 657 1300 657 1311 657 1364 657 1374 657 1433 657 1457 657 1460 657 1483 657 1490 657 1492 658 26 658 53 658 78 658 82 658 86 658 90 658 102 658 191 658 193 658 200 658 211 658 233 658 277 658 308 658 332 658 405 658 428 658 451 658 465 658 511 658 533 658 536 658 537 658 549 658 563 658 579 658 610 658 626 658 658 658 685 658 701 658 702 658 752 658 761 658 812 658 846 658 863 658 884 658 901 658 934 658 959 658 1003 658 1024 658 1035 658 1054 658 1066 658 1084 658 1102 658 1113 658 1118 658 1124 658 1135 658 1137 658 1212 658 1221 658 1309 658 1327 658 1340 658 1341 658 1459 658 1467 658 1475 658 1481 658 1486 658 1494 659 62 659 74 659 88 659 173 659 209 659 306 659 324 659 334 659 420 659 461 659 525 659 553 659 572 659 581 659 659 659 668 659 696 659 723 659 728 659 737 659 748 659 788 659 798 659 804 659 818 659 917 659 924 659 1006 659 1062 659 1080 659 1093 659 1096 659 1104 659 1115 659 1143 659 1149 659 1192 659 1254 659 1259 659 1272 659 1285 659 1293 660 3 660 8 660 64 660 183 660 407 660 471 660 473 660 499 660 527 660 599 660 614 660 628 660 660 660 662 660 709 660 816 660 849 660 951 660 1040 660 1132 660 1191 660 1227 660 1272 661 51 661 133 661 151 661 186 661 188 661 199 661 278 661 281 661 367 661 380 661 419 661 430 661 437 661 498 661 545 661 594 661 597 661 635 661 661 661 665 661 676 661 682 661 729 661 872 661 949 661 1060 661 1086 661 1152 661 1190 661 1208 661 1223 661 1417 661 1440 661 1487 662 2 662 95 662 97 662 126 662 153 662 183 662 247 662 296 662 362 662 407 662 471 662 499 662 614 662 628 662 654 662 660 662 662 662 709 662 816 662 970 662 1001 662 1002 662 1040 662 1050 662 1105 662 1132 662 1191 662 1227 662 1272 662 1329 662 1354 662 1384 662 1394 663 0 663 98 663 114 663 181 663 185 663 220 663 298 663 301 663 358 663 398 663 412 663 419 663 480 663 546 663 597 663 645 663 663 663 665 663 670 663 692 663 699 663 721 663 758 663 760 663 765 663 768 663 821 663 825 663 842 663 996 663 1011 663 1012 663 1050 663 1055 663 1083 663 1085 663 1186 663 1197 663 1218 663 1222 663 1318 663 1384 663 1412 663 1440 663 1465 664 11 664 48 664 80 664 94 664 114 664 163 664 179 664 225 664 226 664 245 664 246 664 276 664 278 664 310 664 339 664 459 664 467 664 496 664 653 664 664 664 712 664 713 664 768 664 787 664 821 664 828 664 880 664 912 664 952 664 966 664 1012 664 1032 664 1033 664 1045 664 1063 664 1081 664 1158 664 1163 664 1170 664 1175 664 1181 664 1201 664 1208 664 1239 664 1251 664 1288 664 1308 664 1335 664 1362 664 1399 665 80 665 81 665 106 665 151 665 185 665 199 665 245 665 278 665 318 665 339 665 347 665 412 665 419 665 430 665 437 665 480 665 496 665 505 665 510 665 529 665 545 665 546 665 585 665 597 665 661 665 663 665 665 665 674 665 676 665 682 665 699 665 760 665 768 665 787 665 821 665 842 665 912 665 949 665 950 665 952 665 965 665 986 665 1019 665 1022 665 1060 665 1063 665 1070 665 1152 665 1175 665 1190 665 1215 665 1251 665 1304 665 1318 665 1408 665 1417 665 1440 665 1465 665 1471 665 1487 666 10 666 23 666 103 666 184 666 198 666 210 666 314 666 357 666 376 666 457 666 503 666 542 666 578 666 601 666 627 666 643 666 666 666 687 666 693 666 704 666 725 666 750 666 766 666 811 666 898 666 915 666 1008 666 1095 666 1168 666 1240 666 1246 666 1297 666 1300 666 1312 666 1338 666 1352 666 1429 666 1457 666 1492 666 1495 667 36 667 55 667 56 667 101 667 164 667 187 667 218 667 291 667 497 667 524 667 547 667 562 667 608 667 620 667 667 667 730 667 867 667 870 667 906 667 908 667 1091 667 1098 667 1225 667 1299 667 1373 668 74 668 84 668 88 668 173 668 201 668 306 668 420 668 461 668 471 668 525 668 553 668 659 668 668 668 696 668 723 668 728 668 748 668 788 668 798 668 804 668 818 668 858 668 924 668 1040 668 1062 668 1080 668 1096 668 1115 668 1191 668 1192 668 1248 668 1254 668 1272 668 1285 668 1293 668 1302 668 1303 669 22 669 91 669 143 669 156 669 266 669 378 669 396 669 446 669 449 669 508 669 530 669 604 669 613 669 621 669 636 669 669 669 691 669 727 669 739 669 841 669 854 669 873 669 903 669 919 669 920 669 948 669 962 669 994 669 1010 669 1038 669 1090 669 1151 669 1267 669 1324 669 1326 669 1431 669 1444 669 1450 670 2 670 93 670 95 670 111 670 114 670 194 670 220 670 247 670 362 670 384 670 450 670 463 670 481 670 516 670 564 670 614 670 654 670 663 670 670 670 675 670 721 670 796 670 825 670 970 670 975 670 1001 670 1012 670 1036 670 1050 670 1083 670 1105 670 1116 670 1122 670 1186 670 1194 670 1248 670 1256 670 1280 670 1302 670 1329 670 1354 670 1478 671 7 671 20 671 37 671 49 671 50 671 68 671 75 671 87 671 122 671 128 671 148 671 167 671 203 671 204 671 219 671 242 671 292 671 294 671 300 671 333 671 336 671 350 671 360 671 368 671 443 671 538 671 657 671 671 671 673 671 703 671 756 671 805 671 819 671 836 671 886 671 916 671 928 671 1088 671 1101 671 1106 671 1161 671 1166 671 1169 671 1171 671 1203 671 1211 671 1257 671 1273 671 1311 671 1326 671 1364 671 1404 671 1460 671 1464 671 1490 672 1 672 100 672 246 672 249 672 260 672 265 672 320 672 417 672 421 672 616 672 653 672 656 672 672 672 688 672 712 672 740 672 762 672 806 672 850 672 855 672 856 672 945 672 974 672 1074 672 1139 672 1195 672 1306 672 1317 672 1337 672 1342 672 1387 672 1397 672 1428 672 1438 672 1453 672 1473 673 20 673 31 673 37 673 49 673 68 673 75 673 123 673 128 673 198 673 203 673 242 673 290 673 333 673 357 673 360 673 368 673 402 673 433 673 443 673 457 673 503 673 538 673 551 673 555 673 582 673 593 673 622 673 657 673 671 673 673 673 703 673 756 673 770 673 800 673 805 673 836 673 886 673 916 673 933 673 955 673 1020 673 1100 673 1101 673 1106 673 1107 673 1166 673 1203 673 1211 673 1257 673 1311 673 1364 673 1433 673 1460 673 1490 674 151 674 185 674 186 674 238 674 264 674 267 674 281 674 301 674 318 674 358 674 398 674 430 674 475 674 480 674 494 674 510 674 518 674 529 674 546 674 598 674 650 674 665 674 674 674 758 674 760 674 803 674 824 674 842 674 896 674 986 674 996 674 1009 674 1011 674 1019 674 1060 674 1079 674 1085 674 1147 674 1218 674 1266 674 1271 674 1305 674 1318 674 1412 674 1449 674 1465 674 1471 675 2 675 84 675 113 675 173 675 194 675 241 675 247 675 275 675 315 675 334 675 362 675 372 675 384 675 420 675 471 675 472 675 488 675 554 675 566 675 670 675 675 675 788 675 796 675 825 675 966 675 1001 675 1036 675 1105 675 1122 675 1143 675 1157 675 1186 675 1192 675 1248 675 1302 675 1303 675 1308 675 1329 675 1469 676 0 676 29 676 45 676 51 676 138 676 151 676 185 676 186 676 199 676 318 676 359 676 380 676 398 676 419 676 436 676 437 676 470 676 494 676 505 676 545 676 597 676 645 676 646 676 650 676 661 676 665 676 676 676 683 676 699 676 708 676 729 676 895 676 931 676 950 676 965 676 979 676 1060 676 1079 676 1086 676 1197 676 1304 676 1305 676 1398 676 1417 676 1440 676 1471 676 1487 677 84 677 120 677 201 677 239 677 271 677 275 677 293 677 311 677 324 677 361 677 488 677 647 677 677 677 719 677 793 677 858 677 971 677 1006 677 1023 677 1051 677 1058 677 1157 677 1307 677 1377 677 1395 677 1424 677 1435 678 27 678 66 678 89 678 116 678 124 678 127 678 131 678 235 678 243 678 250 678 268 678 356 678 392 678 425 678 470 678 479 678 486 678 501 678 502 678 535 678 539 678 552 678 568 678 576 678 649 678 678 678 753 678 757 678 775 678 810 678 830 678 831 678 865 678 879 678 887 678 896 678 909 678 921 678 925 678 942 678 985 678 986 678 995 678 1007 678 1009 678 1016 678 1064 678 1072 678 1160 678 1165 678 1341 678 1349 678 1414 678 1425 678 1446 678 1449 679 94 679 127 679 131 679 134 679 228 679 243 679 289 679 392 679 393 679 459 679 467 679 486 679 501 679 502 679 649 679 679 679 726 679 741 679 746 679 772 679 775 679 789 679 797 679 879 679 909 679 918 679 925 679 946 679 968 679 1016 679 1072 679 1077 679 1111 679 1213 679 1315 679 1372 679 1392 679 1410 679 1470 680 14 680 47 680 56 680 83 680 101 680 164 680 217 680 223 680 279 680 295 680 389 680 391 680 408 680 478 680 520 680 524 680 526 680 547 680 592 680 638 680 680 680 784 680 814 680 822 680 839 680 844 680 867 680 906 680 908 680 911 680 940 680 978 680 1014 680 1018 680 1034 680 1097 680 1098 680 1142 680 1180 680 1198 680 1206 680 1216 680 1229 680 1230 680 1281 680 1290 680 1299 680 1370 680 1407 680 1441 680 1474 680 1498 681 17 681 133 681 244 681 283 681 304 681 349 681 382 681 394 681 395 681 399 681 505 681 540 681 575 681 580 681 590 681 634 681 681 681 695 681 776 681 786 681 795 681 865 681 969 681 980 681 992 681 1039 681 1059 681 1140 681 1160 681 1199 681 1271 681 1351 681 1378 681 1425 681 1446 681 1467 681 1499 682 98 682 99 682 106 682 151 682 179 682 186 682 188 682 199 682 225 682 245 682 278 682 339 682 347 682 367 682 419 682 430 682 437 682 509 682 529 682 540 682 597 682 645 682 661 682 665 682 682 682 686 682 760 682 768 682 821 682 845 682 949 682 950 682 1019 682 1022 682 1060 682 1063 682 1152 682 1190 682 1197 682 1263 682 1417 682 1440 682 1487 683 29 683 98 683 106 683 151 683 185 683 245 683 288 683 318 683 359 683 367 683 380 683 398 683 470 683 494 683 645 683 650 683 676 683 683 683 686 683 699 683 760 683 821 683 842 683 895 683 949 683 950 683 965 683 986 683 1060 683 1079 683 1197 683 1304 683 1417 683 1440 683 1465 683 1487 684 76 684 79 684 135 684 144 684 189 684 217 684 232 684 253 684 305 684 344 684 373 684 401 684 455 684 478 684 484 684 526 684 556 684 567 684 591 684 611 684 640 684 684 684 690 684 743 684 807 684 814 684 822 684 839 684 860 684 875 684 911 684 978 684 990 684 1014 684 1068 684 1082 684 1136 684 1142 684 1216 684 1217 684 1235 684 1236 684 1250 684 1277 684 1290 684 1348 684 1355 684 1356 684 1358 684 1370 684 1375 684 1407 684 1441 684 1498 685 9 685 15 685 53 685 54 685 78 685 102 685 121 685 130 685 158 685 191 685 205 685 229 685 270 685 285 685 308 685 312 685 451 685 462 685 485 685 490 685 511 685 536 685 610 685 658 685 685 685 698 685 752 685 761 685 812 685 823 685 827 685 837 685 863 685 864 685 884 685 959 685 1044 685 1066 685 1084 685 1102 685 1137 685 1144 685 1153 685 1183 685 1212 685 1221 685 1258 685 1340 685 1343 685 1382 685 1442 685 1452 685 1459 685 1475 686 6 686 41 686 45 686 89 686 99 686 106 686 151 686 188 686 199 686 245 686 278 686 318 686 382 686 470 686 505 686 510 686 540 686 682 686 683 686 686 686 722 686 865 686 890 686 896 686 921 686 949 686 950 686 965 686 968 686 986 686 1000 686 1048 686 1060 686 1063 686 1152 686 1160 686 1190 686 1251 686 1304 686 1349 686 1408 686 1417 686 1425 686 1445 686 1471 686 1487 687 10 687 61 687 103 687 110 687 341 687 342 687 364 687 379 687 447 687 493 687 504 687 542 687 578 687 601 687 643 687 666 687 687 687 704 687 749 687 811 687 843 687 913 687 915 687 943 687 956 687 1008 687 1095 687 1109 687 1168 687 1269 687 1297 687 1312 687 1374 687 1420 687 1421 687 1437 688 48 688 140 688 163 688 226 688 246 688 310 688 320 688 393 688 406 688 413 688 512 688 521 688 596 688 616 688 653 688 672 688 688 688 712 688 718 688 740 688 746 688 762 688 772 688 806 688 852 688 855 688 856 688 880 688 907 688 945 688 963 688 974 688 998 688 1004 688 1049 688 1094 688 1139 688 1158 688 1163 688 1177 688 1181 688 1306 688 1362 688 1387 688 1438 688 1453 688 1473 689 45 689 114 689 124 689 235 689 251 689 268 689 301 689 318 689 358 689 392 689 429 689 467 689 482 689 494 689 689 689 699 689 722 689 731 689 768 689 821 689 824 689 996 689 1007 689 1009 689 1055 689 1160 689 1228 689 1304 689 1349 689 1371 689 1403 689 1449 689 1468 690 13 690 14 690 47 690 79 690 92 690 125 690 160 690 165 690 230 690 240 690 272 690 279 690 295 690 305 690 371 690 373 690 387 690 441 690 452 690 483 690 484 690 528 690 567 690 600 690 603 690 606 690 612 690 624 690 630 690 640 690 648 690 684 690 690 690 694 690 807 690 809 690 882 690 883 690 910 690 939 690 999 690 1018 690 1075 690 1076 690 1082 690 1099 690 1180 690 1196 690 1206 690 1236 690 1277 690 1355 690 1356 690 1370 690 1375 690 1441 690 1484 691 156 691 190 691 396 691 414 691 508 691 604 691 669 691 691 691 727 691 739 691 841 691 854 691 903 691 919 691 920 691 994 691 1037 691 1038 691 1151 691 1267 691 1450 691 1454 691 1491 692 25 692 70 692 98 692 163 692 181 692 220 692 225 692 256 692 273 692 412 692 450 692 523 692 663 692 692 692 768 692 845 692 894 692 932 692 1012 692 1032 692 1055 692 1083 692 1175 692 1239 692 1385 692 1447 692 1488 693 23 693 122 693 195 693 517 693 542 693 573 693 582 693 643 693 666 693 693 693 697 693 811 693 898 693 915 693 943 693 1008 693 1095 693 1101 693 1107 693 1168 693 1240 693 1246 693 1275 693 1323 693 1344 693 1352 693 1374 693 1495 694 52 694 63 694 92 694 125 694 160 694 230 694 272 694 295 694 371 694 373 694 387 694 404 694 441 694 483 694 600 694 624 694 640 694 648 694 690 694 694 694 743 694 807 694 809 694 814 694 882 694 888 694 910 694 911 694 999 694 1014 694 1068 694 1069 694 1075 694 1082 694 1097 694 1099 694 1108 694 1180 694 1196 694 1277 694 1281 694 1355 694 1441 694 1456 694 1472 694 1476 694 1484 695 17 695 35 695 51 695 124 695 129 695 131 695 172 695 180 695 235 695 283 695 304 695 321 695 322 695 363 695 374 695 382 695 394 695 395 695 399 695 522 695 540 695 575 695 590 695 594 695 634 695 681 695 695 695 708 695 767 695 786 695 795 695 885 695 929 695 961 695 969 695 980 695 992 695 1007 695 1039 695 1052 695 1125 695 1140 695 1164 695 1199 695 1201 695 1209 695 1261 695 1316 695 1339 695 1359 695 1362 695 1468 696 166 696 306 696 334 696 386 696 420 696 461 696 471 696 472 696 474 696 525 696 553 696 566 696 659 696 668 696 696 696 723 696 748 696 804 696 924 696 1040 696 1096 696 1104 696 1143 696 1191 696 1254 696 1259 696 1272 696 1285 696 1302 696 1303 696 1319 696 1391 696 1405 696 1427 697 49 697 50 697 68 697 75 697 141 697 195 697 198 697 294 697 314 697 368 697 433 697 517 697 538 697 551 697 571 697 573 697 582 697 657 697 693 697 697 697 811 697 836 697 930 697 1008 697 1107 697 1168 697 1203 697 1240 697 1246 697 1275 697 1300 697 1323 697 1352 697 1364 697 1374 697 1460 698 9 698 15 698 54 698 73 698 121 698 130 698 152 698 158 698 205 698 259 698 262 698 285 698 351 698 485 698 490 698 536 698 618 698 655 698 685 698 698 698 701 698 752 698 761 698 778 698 815 698 823 698 827 698 837 698 864 698 905 698 1044 698 1118 698 1144 698 1153 698 1183 698 1212 698 1221 698 1258 698 1343 698 1360 698 1382 698 1448 698 1452 698 1455 699 0 699 29 699 51 699 80 699 114 699 186 699 251 699 264 699 278 699 301 699 318 699 347 699 358 699 367 699 412 699 419 699 437 699 467 699 494 699 545 699 597 699 645 699 650 699 663 699 665 699 676 699 683 699 689 699 699 699 721 699 729 699 760 699 768 699 787 699 821 699 828 699 895 699 912 699 950 699 986 699 996 699 1011 699 1055 699 1083 699 1197 699 1304 699 1305 699 1398 699 1417 699 1487 700 18 700 146 700 192 700 255 700 340 700 531 700 700 700 851 700 907 700 1004 700 1123 700 1155 700 1177 700 1193 700 1415 700 1466 701 15 701 54 701 73 701 90 701 121 701 152 701 191 701 205 701 259 701 262 701 285 701 323 701 327 701 351 701 485 701 490 701 536 701 563 701 610 701 618 701 619 701 655 701 658 701 698 701 701 701 734 701 752 701 778 701 802 701 808 701 815 701 823 701 864 701 905 701 934 701 959 701 1024 701 1035 701 1044 701 1054 701 1102 701 1113 701 1118 701 1124 701 1153 701 1183 701 1212 701 1258 701 1330 701 1334 701 1340 701 1360 701 1382 701 1452 701 1455 701 1486 702 53 702 58 702 78 702 82 702 102 702 193 702 206 702 211 702 222 702 262 702 270 702 308 702 323 702 348 702 405 702 431 702 451 702 506 702 511 702 533 702 549 702 560 702 610 702 658 702 702 702 752 702 761 702 769 702 808 702 863 702 897 702 901 702 923 702 983 702 1003 702 1024 702 1035 702 1046 702 1065 702 1084 702 1118 702 1124 702 1135 702 1219 702 1334 702 1336 702 1340 702 1459 702 1475 702 1481 702 1486 703 7 703 20 703 31 703 37 703 75 703 87 703 123 703 128 703 148 703 167 703 170 703 178 703 198 703 203 703 204 703 219 703 242 703 292 703 300 703 333 703 336 703 350 703 357 703 360 703 402 703 418 703 457 703 551 703 555 703 559 703 583 703 593 703 622 703 627 703 657 703 671 703 673 703 703 703 725 703 756 703 766 703 777 703 886 703 916 703 928 703 933 703 1020 703 1029 703 1071 703 1087 703 1100 703 1106 703 1112 703 1161 703 1166 703 1171 703 1185 703 1203 703 1205 703 1211 703 1224 703 1257 703 1268 703 1273 703 1311 703 1326 703 1388 703 1402 703 1433 703 1462 703 1490 704 10 704 50 704 61 704 68 704 103 704 141 704 195 704 210 704 299 704 314 704 341 704 342 704 364 704 376 704 379 704 447 704 493 704 504 704 542 704 559 704 571 704 578 704 601 704 627 704 666 704 687 704 704 704 749 704 811 704 898 704 904 704 913 704 915 704 1008 704 1088 704 1095 704 1109 704 1168 704 1189 704 1269 704 1297 704 1300 704 1312 704 1338 704 1374 704 1420 704 1421 704 1437 704 1457 704 1460 704 1495 705 28 705 89 705 138 705 162 705 174 705 261 705 470 705 539 705 552 705 568 705 705 705 753 705 797 705 831 705 832 705 931 705 944 705 995 705 1111 705 1120 705 1292 705 1372 706 71 706 136 706 150 706 177 706 213 706 248 706 252 706 297 706 317 706 390 706 423 706 432 706 439 706 469 706 548 706 588 706 632 706 641 706 706 706 738 706 835 706 868 706 889 706 936 706 964 706 977 706 1053 706 1073 706 1130 706 1247 706 1255 706 1274 706 1284 706 1322 706 1328 706 1381 706 1416 706 1422 706 1480 707 156 707 159 707 196 707 266 707 345 707 383 707 390 707 400 707 448 707 530 707 543 707 548 707 605 707 615 707 641 707 707 707 739 707 763 707 764 707 862 707 920 707 947 707 960 707 964 707 994 707 1005 707 1037 707 1090 707 1126 707 1172 707 1252 707 1267 707 1287 707 1324 707 1325 707 1386 707 1434 707 1436 707 1493 708 28 708 51 708 116 708 206 708 233 708 244 708 267 708 283 708 325 708 355 708 380 708 425 708 482 708 494 708 522 708 575 708 625 708 629 708 646 708 650 708 652 708 676 708 695 708 708 708 715 708 755 708 896 708 921 708 931 708 965 708 986 708 995 708 1007 708 1009 708 1064 708 1079 708 1113 708 1199 708 1204 708 1244 708 1261 708 1314 708 1316 708 1321 708 1378 708 1403 708 1449 708 1468 708 1485 708 1494 709 3 709 8 709 64 709 183 709 316 709 407 709 473 709 527 709 614 709 628 709 660 709 662 709 709 709 816 709 849 709 951 709 1040 709 1043 709 1132 709 1419 709 1463 710 62 710 104 710 105 710 166 710 173 710 209 710 254 710 302 710 309 710 334 710 409 710 426 710 472 710 477 710 489 710 532 710 572 710 710 710 723 710 826 710 899 710 917 710 1051 710 1080 710 1093 710 1114 710 1143 710 1149 710 1233 710 1270 710 1350 710 1380 710 1405 710 1469 711 27 711 96 711 162 711 255 711 322 711 328 711 354 711 394 711 531 711 561 711 590 711 634 711 711 711 786 711 830 711 874 711 887 711 942 711 969 711 1047 711 1092 711 1125 711 1140 711 1209 711 1414 711 1446 712 1 712 100 712 226 712 260 712 320 712 415 712 616 712 653 712 656 712 664 712 672 712 688 712 712 712 740 712 806 712 850 712 855 712 856 712 880 712 966 712 973 712 1077 712 1170 712 1175 712 1181 712 1195 712 1306 712 1317 712 1337 712 1342 712 1387 712 1397 712 1428 712 1438 712 1473 713 11 713 41 713 48 713 81 713 94 713 179 713 199 713 225 713 226 713 245 713 276 713 278 713 310 713 321 713 339 713 347 713 382 713 406 713 419 713 459 713 496 713 501 713 509 713 510 713 513 713 535 713 545 713 664 713 713 713 768 713 781 713 782 713 787 713 790 713 821 713 828 713 834 713 912 713 929 713 946 713 949 713 952 713 1033 713 1045 713 1048 713 1063 713 1081 713 1158 713 1163 713 1170 713 1181 713 1201 713 1208 713 1215 713 1241 713 1251 713 1288 713 1304 713 1335 713 1362 713 1425 713 1445 714 27 714 96 714 116 714 174 714 175 714 206 714 235 714 261 714 263 714 325 714 356 714 479 714 539 714 552 714 561 714 568 714 646 714 714 714 753 714 885 714 887 714 909 714 942 714 944 714 985 714 995 714 1047 714 1072 714 1120 714 1173 714 1244 714 1283 714 1339 714 1372 714 1401 714 1411 714 1414 715 0 715 29 715 222 715 263 715 380 715 459 715 482 715 486 715 494 715 708 715 715 715 879 715 895 715 931 715 973 715 996 715 1016 715 1215 715 1321 715 1398 715 1403 716 4 716 155 716 169 716 177 716 248 716 331 716 519 716 632 716 716 716 1053 716 1073 716 1357 716 1367 716 1423 716 1451 717 1 717 99 717 100 717 134 717 260 717 265 717 337 717 393 717 417 717 421 717 487 717 505 717 510 717 550 717 585 717 596 717 616 717 717 717 754 717 762 717 806 717 890 717 918 717 968 717 988 717 1000 717 1042 717 1074 717 1077 717 1139 717 1226 717 1315 717 1317 717 1397 717 1428 717 1445 717 1470 718 6 718 35 718 42 718 48 718 140 718 163 718 188 718 256 718 313 718 374 718 382 718 406 718 411 718 498 718 512 718 521 718 577 718 635 718 688 718 718 718 740 718 772 718 781 718 782 718 810 718 852 718 894 718 932 718 945 718 961 718 998 718 1022 718 1049 718 1052 718 1081 718 1094 718 1139 718 1158 718 1163 718 1181 718 1201 718 1208 718 1223 718 1362 718 1363 718 1399 719 84 719 120 719 239 719 271 719 275 719 293 719 311 719 315 719 361 719 372 719 515 719 564 719 647 719 677 719 719 719 793 719 858 719 971 719 975 719 1023 719 1056 719 1058 719 1157 719 1248 719 1253 719 1307 719 1377 719 1394 719 1395 719 1424 719 1435 720 38 720 58 720 66 720 86 720 175 720 193 720 211 720 212 720 216 720 250 720 277 720 322 720 328 720 349 720 354 720 394 720 399 720 405 720 428 720 440 720 444 720 464 720 534 720 563 720 580 720 625 720 631 720 652 720 720 720 785 720 792 720 829 720 874 720 923 720 1017 720 1046 720 1047 720 1131 720 1137 720 1234 720 1238 720 1249 720 1283 720 1309 720 1332 720 1336 720 1341 720 1351 720 1390 720 1418 721 0 721 114 721 181 721 197 721 220 721 251 721 264 721 298 721 301 721 358 721 480 721 529 721 546 721 663 721 670 721 699 721 721 721 758 721 765 721 771 721 825 721 996 721 1011 721 1050 721 1055 721 1079 721 1145 721 1186 721 1218 721 1222 721 1318 721 1384 721 1440 722 6 722 42 722 45 722 70 722 108 722 133 722 238 722 268 722 273 722 281 722 303 722 438 722 635 722 686 722 689 722 722 722 731 722 780 722 803 722 810 722 961 722 1031 722 1147 722 1160 722 1228 722 1263 722 1305 722 1333 722 1349 722 1363 722 1399 722 1466 722 1488 722 1499 723 62 723 88 723 166 723 209 723 306 723 334 723 420 723 426 723 472 723 553 723 554 723 572 723 581 723 659 723 668 723 696 723 710 723 723 723 728 723 737 723 748 723 788 723 798 723 804 723 818 723 899 723 917 723 924 723 1062 723 1093 723 1096 723 1104 723 1143 723 1149 723 1192 723 1254 723 1272 723 1285 723 1293 723 1303 723 1383 723 1391 723 1469 724 39 724 43 724 46 724 60 724 77 724 104 724 109 724 112 724 118 724 154 724 176 724 208 724 258 724 280 724 287 724 309 724 369 724 385 724 410 724 456 724 500 724 541 724 557 724 565 724 633 724 724 724 747 724 779 724 826 724 861 724 878 724 891 724 902 724 927 724 957 724 976 724 1013 724 1025 724 1030 724 1114 724 1128 724 1148 724 1150 724 1182 724 1207 724 1210 724 1243 724 1279 724 1295 724 1310 724 1366 724 1368 724 1380 724 1439 724 1489 725 10 725 23 725 37 725 49 725 122 725 184 725 198 725 210 725 319 725 350 725 357 725 376 725 457 725 503 725 542 725 551 725 555 725 559 725 573 725 589 725 593 725 601 725 622 725 627 725 657 725 666 725 703 725 725 725 750 725 756 725 766 725 770 725 800 725 805 725 886 725 898 725 933 725 1008 725 1020 725 1087 725 1088 725 1107 725 1166 725 1185 725 1200 725 1257 725 1429 725 1433 725 1457 725 1483 725 1492 726 29 726 48 726 96 726 124 726 131 726 134 726 199 726 243 726 263 726 284 726 289 726 380 726 392 726 393 726 459 726 486 726 501 726 513 726 594 726 649 726 679 726 726 726 741 726 746 726 757 726 772 726 775 726 786 726 789 726 797 726 810 726 830 726 879 726 921 726 929 726 931 726 942 726 946 726 1016 726 1072 726 1086 726 1164 726 1173 726 1213 726 1304 726 1349 726 1362 726 1372 727 156 727 190 727 396 727 414 727 508 727 530 727 604 727 669 727 691 727 727 727 739 727 841 727 854 727 903 727 919 727 920 727 994 727 1037 727 1038 727 1090 727 1151 727 1267 727 1450 727 1454 728 62 728 88 728 173 728 209 728 324 728 420 728 474 728 553 728 572 728 581 728 659 728 668 728 723 728 728 728 737 728 748 728 788 728 798 728 818 728 917 728 924 728 1062 728 1080 728 1093 728 1096 728 1104 728 1115 728 1143 728 1149 728 1192 728 1259 728 1293 728 1391 729 29 729 51 729 70 729 98 729 124 729 151 729 186 729 199 729 235 729 238 729 256 729 278 729 281 729 298 729 301 729 303 729 358 729 367 729 380 729 412 729 419 729 437 729 442 729 522 729 545 729 594 729 597 729 635 729 661 729 676 729 699 729 729 729 731 729 768 729 803 729 872 729 949 729 1011 729 1031 729 1052 729 1085 729 1086 729 1208 729 1239 729 1263 729 1305 729 1339 729 1362 729 1398 729 1399 729 1417 729 1468 729 1487 729 1488 730 5 730 12 730 13 730 14 730 36 730 85 730 92 730 101 730 202 730 218 730 230 730 240 730 291 730 365 730 434 730 441 730 492 730 547 730 562 730 569 730 603 730 606 730 608 730 609 730 620 730 667 730 730 730 867 730 870 730 883 730 1018 730 1028 730 1076 730 1091 730 1098 730 1129 730 1159 730 1225 730 1291 730 1331 730 1369 730 1373 730 1461 730 1472 731 24 731 51 731 70 731 98 731 108 731 151 731 256 731 273 731 281 731 298 731 303 731 358 731 367 731 437 731 438 731 522 731 635 731 689 731 722 731 729 731 731 731 780 731 794 731 803 731 824 731 1011 731 1031 731 1039 731 1052 731 1085 731 1086 731 1178 731 1208 731 1228 731 1239 731 1263 731 1363 731 1371 731 1399 731 1417 731 1466 731 1468 731 1487 731 1488 732 91 732 143 732 178 732 219 732 319 732 326 732 350 732 416 732 418 732 422 732 457 732 508 732 555 732 617 732 636 732 644 732 732 732 777 732 800 732 935 732 958 732 962 732 997 732 1010 732 1015 732 1087 732 1146 732 1154 732 1167 732 1200 732 1205 732 1268 732 1289 732 1294 732 1311 732 1346 732 1388 732 1426 732 1431 732 1479 733 44 733 57 733 72 733 76 733 135 733 144 733 149 733 232 733 344 733 370 733 375 733 388 733 397 733 401 733 424 733 455 733 478 733 491 733 556 733 584 733 591 733 733 733 799 733 860 733 893 733 993 733 1136 733 1142 733 1179 733 1235 733 1278 733 1290 733 1358 733 1393 733 1456 734 19 734 73 734 90 734 152 734 205 734 222 734 259 734 285 734 312 734 323 734 327 734 338 734 465 734 518 734 536 734 560 734 599 734 655 734 701 734 734 734 752 734 761 734 778 734 802 734 815 734 866 734 871 734 892 734 934 734 1035 734 1044 734 1113 734 1118 734 1124 734 1212 734 1214 734 1266 734 1327 734 1330 734 1334 734 1382 734 1400 734 1413 734 1419 734 1442 734 1486 735 9 735 15 735 54 735 158 735 182 735 205 735 221 735 229 735 285 735 381 735 462 735 473 735 485 735 490 735 618 735 735 735 823 735 837 735 849 735 864 735 1044 735 1144 735 1153 735 1258 735 1389 735 1448 735 1452 735 1463 736 31 736 123 736 170 736 402 736 457 736 593 736 601 736 736 736 1100 736 1112 736 1346 736 1402 736 1426 736 1462 737 62 737 88 737 209 737 324 737 420 737 477 737 553 737 572 737 581 737 659 737 723 737 728 737 737 737 788 737 798 737 818 737 917 737 1006 737 1062 737 1080 737 1093 737 1096 737 1104 737 1115 737 1149 737 1192 737 1293 737 1350 738 16 738 71 738 159 738 177 738 207 738 248 738 252 738 274 738 297 738 317 738 331 738 390 738 423 738 432 738 469 738 519 738 588 738 632 738 641 738 706 738 738 738 853 738 936 738 964 738 977 738 1053 738 1073 738 1130 738 1252 738 1274 738 1328 738 1357 738 1367 738 1416 738 1422 738 1423 738 1451 738 1480 739 22 739 91 739 143 739 156 739 159 739 196 739 266 739 345 739 378 739 383 739 396 739 400 739 448 739 449 739 507 739 530 739 543 739 570 739 604 739 605 739 615 739 621 739 669 739 691 739 707 739 727 739 739 739 791 739 847 739 854 739 873 739 903 739 920 739 947 739 994 739 1037 739 1090 739 1126 739 1172 739 1176 739 1267 739 1324 739 1325 739 1386 739 1434 739 1436 739 1444 740 48 740 140 740 163 740 226 740 246 740 310 740 320 740 413 740 512 740 523 740 596 740 616 740 653 740 672 740 688 740 712 740 718 740 740 740 751 740 762 740 772 740 806 740 852 740 855 740 856 740 880 740 932 740 945 740 963 740 974 740 998 740 1004 740 1049 740 1094 740 1139 740 1158 740 1163 740 1177 740 1181 740 1239 740 1306 740 1387 740 1438 740 1453 740 1473 741 27 741 35 741 134 741 140 741 162 741 289 741 393 741 411 741 413 741 498 741 501 741 521 741 577 741 679 741 726 741 741 741 746 741 772 741 775 741 781 741 789 741 797 741 832 741 890 741 918 741 946 741 1048 741 1049 741 1164 741 1173 741 1213 741 1292 741 1362 741 1410 742 5 742 12 742 52 742 63 742 65 742 85 742 165 742 202 742 234 742 236 742 240 742 365 742 595 742 609 742 630 742 642 742 742 742 759 742 939 742 984 742 1026 742 1028 742 1129 742 1159 742 1265 742 1461 742 1472 743 47 743 79 743 92 743 125 743 147 743 160 743 189 743 253 743 272 743 305 743 344 743 404 743 466 743 484 743 491 743 556 743 611 743 624 743 684 743 694 743 743 743 809 743 882 743 888 743 990 743 999 743 1014 743 1027 743 1069 743 1075 743 1082 743 1277 743 1355 743 1370 743 1375 743 1456 743 1484 744 16 744 32 744 34 744 40 744 150 744 171 744 177 744 207 744 213 744 237 744 274 744 297 744 307 744 317 744 439 744 453 744 495 744 588 744 744 744 813 744 835 744 848 744 853 744 859 744 869 744 936 744 1041 744 1061 744 1110 744 1138 744 1237 744 1247 744 1262 744 1276 744 1284 744 1296 744 1322 744 1347 744 1381 745 129 745 131 745 172 745 180 745 192 745 255 745 269 745 340 745 352 745 394 745 395 745 575 745 590 745 745 745 767 745 769 745 851 745 969 745 983 745 1067 745 1089 745 1125 745 1155 745 1178 745 1209 745 1332 745 1333 745 1353 745 1359 745 1415 745 1468 746 48 746 96 746 124 746 127 746 131 746 134 746 140 746 162 746 243 746 263 746 392 746 393 746 413 746 486 746 501 746 649 746 679 746 688 746 726 746 741 746 746 746 757 746 772 746 775 746 786 746 797 746 830 746 879 746 942 746 946 746 961 746 1016 746 1049 746 1072 746 1173 746 1181 746 1201 746 1213 746 1362 746 1372 747 43 747 46 747 60 747 77 747 109 747 118 747 154 747 176 747 208 747 254 747 280 747 287 747 369 747 385 747 410 747 456 747 500 747 532 747 541 747 557 747 565 747 633 747 651 747 724 747 747 747 779 747 861 747 878 747 891 747 902 747 927 747 957 747 976 747 989 747 1013 747 1025 747 1030 747 1114 747 1128 747 1148 747 1150 747 1182 747 1207 747 1210 747 1243 747 1279 747 1295 747 1310 747 1366 747 1368 747 1380 747 1439 747 1489 748 88 748 166 748 173 748 306 748 420 748 461 748 471 748 525 748 553 748 659 748 668 748 696 748 723 748 728 748 748 748 804 748 924 748 1040 748 1062 748 1080 748 1096 748 1143 748 1191 748 1254 748 1272 748 1285 748 1293 748 1303 748 1319 748 1391 748 1405 748 1427 748 1469 749 33 749 61 749 110 749 141 749 169 749 195 749 299 749 341 749 342 749 364 749 379 749 447 749 458 749 493 749 504 749 586 749 687 749 704 749 749 749 773 749 811 749 843 749 904 749 913 749 915 749 941 749 943 749 956 749 1109 749 1168 749 1189 749 1269 749 1275 749 1312 749 1338 749 1345 749 1374 749 1420 749 1421 749 1437 750 10 750 23 750 122 750 184 750 210 750 319 750 376 750 457 750 503 750 517 750 542 750 551 750 573 750 589 750 601 750 627 750 643 750 666 750 725 750 750 750 766 750 898 750 1008 750 1087 750 1095 750 1185 750 1240 750 1246 750 1344 750 1429 750 1457 750 1492 751 12 751 165 751 740 751 751 751 759 751 1292 751 1411 751 1438 751 1497 752 15 752 53 752 54 752 73 752 78 752 82 752 102 752 121 752 130 752 152 752 200 752 205 752 259 752 270 752 286 752 308 752 338 752 451 752 511 752 549 752 560 752 610 752 631 752 655 752 658 752 685 752 698 752 701 752 702 752 734 752 752 752 761 752 778 752 812 752 815 752 827 752 829 752 846 752 863 752 901 752 905 752 923 752 959 752 967 752 1003 752 1066 752 1084 752 1102 752 1113 752 1118 752 1124 752 1131 752 1135 752 1183 752 1212 752 1221 752 1330 752 1336 752 1340 752 1343 752 1382 752 1400 752 1413 752 1455 752 1459 752 1475 752 1481 753 27 753 28 753 89 753 124 753 127 753 138 753 235 753 267 753 321 753 356 753 392 753 470 753 479 753 502 753 539 753 540 753 552 753 568 753 678 753 705 753 714 753 753 753 775 753 797 753 831 753 832 753 921 753 925 753 931 753 979 753 985 753 995 753 1072 753 1111 753 1120 753 1160 753 1201 753 1292 753 1349 753 1372 754 99 754 100 754 179 754 226 754 246 754 249 754 260 754 265 754 310 754 320 754 329 754 337 754 393 754 406 754 417 754 421 754 445 754 487 754 585 754 596 754 616 754 653 754 717 754 754 754 762 754 790 754 806 754 820 754 912 754 918 754 922 754 945 754 1000 754 1022 754 1042 754 1045 754 1063 754 1070 754 1077 754 1094 754 1139 754 1158 754 1170 754 1181 754 1226 754 1241 754 1251 754 1288 754 1315 754 1317 754 1387 754 1408 754 1428 754 1438 754 1445 754 1453 754 1470 755 26 755 116 755 206 755 233 755 267 755 332 755 355 755 436 755 470 755 482 755 539 755 568 755 629 755 646 755 652 755 708 755 755 755 895 755 931 755 965 755 985 755 995 755 1009 755 1204 755 1314 755 1316 755 1321 755 1403 755 1485 755 1494 756 20 756 37 756 49 756 75 756 122 756 123 756 128 756 167 756 178 756 198 756 203 756 219 756 242 756 290 756 333 756 350 756 357 756 360 756 368 756 376 756 402 756 443 756 503 756 517 756 551 756 555 756 559 756 573 756 582 756 593 756 622 756 627 756 657 756 671 756 673 756 703 756 725 756 756 756 766 756 770 756 800 756 805 756 836 756 886 756 898 756 916 756 928 756 933 756 955 756 1020 756 1087 756 1088 756 1100 756 1101 756 1107 756 1166 756 1171 756 1185 756 1203 756 1211 756 1257 756 1311 756 1433 756 1457 756 1460 756 1483 756 1490 756 1492 757 6 757 42 757 48 757 124 757 131 757 162 757 228 757 243 757 263 757 392 757 479 757 486 757 498 757 501 757 521 757 576 757 649 757 678 757 726 757 746 757 757 757 775 757 786 757 789 757 810 757 834 757 879 757 946 757 961 757 1016 757 1052 757 1072 757 1160 757 1163 757 1173 757 1201 757 1213 757 1349 757 1353 757 1362 758 26 758 185 758 264 758 288 758 312 758 327 758 359 758 398 758 436 758 475 758 480 758 546 758 597 758 598 758 646 758 650 758 663 758 674 758 721 758 758 758 771 758 817 758 934 758 1054 758 1079 758 1113 758 1124 758 1204 758 1218 758 1266 758 1305 758 1318 758 1327 758 1330 758 1412 758 1413 759 12 759 52 759 63 759 65 759 165 759 234 759 642 759 742 759 751 759 759 759 939 759 1026 759 1028 759 1042 759 1077 759 1265 759 1315 759 1337 759 1438 759 1470 760 98 760 106 760 151 760 185 760 225 760 251 760 318 760 339 760 347 760 358 760 367 760 419 760 430 760 470 760 480 760 510 760 529 760 546 760 598 760 645 760 663 760 665 760 674 760 682 760 683 760 699 760 760 760 768 760 787 760 821 760 842 760 949 760 986 760 996 760 1009 760 1019 760 1060 760 1063 760 1079 760 1152 760 1190 760 1197 760 1218 760 1304 760 1318 760 1412 760 1417 760 1440 760 1465 760 1471 761 30 761 53 761 73 761 78 761 82 761 102 761 121 761 130 761 152 761 191 761 205 761 212 761 259 761 270 761 308 761 338 761 451 761 460 761 511 761 537 761 549 761 610 761 631 761 655 761 658 761 685 761 698 761 702 761 734 761 752 761 761 761 778 761 802 761 812 761 815 761 829 761 863 761 884 761 905 761 923 761 967 761 1003 761 1057 761 1065 761 1084 761 1124 761 1135 761 1183 761 1212 761 1330 761 1334 761 1336 761 1382 761 1390 761 1413 761 1418 761 1455 761 1459 761 1481 762 100 762 134 762 140 762 179 762 226 762 246 762 260 762 265 762 310 762 320 762 329 762 337 762 393 762 406 762 417 762 421 762 445 762 487 762 596 762 616 762 653 762 672 762 688 762 717 762 740 762 754 762 762 762 772 762 790 762 806 762 880 762 918 762 922 762 945 762 963 762 974 762 1042 762 1045 762 1049 762 1077 762 1094 762 1139 762 1158 762 1181 762 1223 762 1226 762 1241 762 1315 762 1387 762 1438 762 1445 762 1453 762 1470 763 7 763 20 763 31 763 148 763 156 763 336 763 403 763 449 763 530 763 543 763 548 763 558 763 607 763 641 763 707 763 763 763 764 763 862 763 873 763 948 763 960 763 994 763 1005 763 1037 763 1126 763 1156 763 1184 763 1188 763 1224 763 1255 763 1267 763 1287 763 1324 763 1386 763 1402 763 1404 763 1436 763 1444 763 1464 763 1493 764 22 764 156 764 159 764 196 764 252 764 345 764 390 764 403 764 448 764 530 764 543 764 548 764 588 764 615 764 641 764 707 764 763 764 764 764 847 764 920 764 948 764 960 764 964 764 994 764 1005 764 1037 764 1126 764 1172 764 1174 764 1252 764 1267 764 1287 764 1324 764 1325 764 1386 764 1434 764 1436 764 1493 765 19 765 64 765 97 765 119 765 197 765 220 765 288 765 298 765 330 765 338 765 407 765 427 765 442 765 499 765 518 765 587 765 614 765 628 765 654 765 663 765 721 765 765 765 802 765 816 765 866 765 871 765 892 765 951 765 1050 765 1085 765 1132 765 1133 765 1145 765 1147 765 1214 765 1222 765 1242 765 1260 765 1371 765 1400 765 1412 765 1419 766 23 766 37 766 170 766 184 766 198 766 210 766 319 766 350 766 376 766 457 766 503 766 551 766 555 766 559 766 573 766 589 766 593 766 601 766 622 766 627 766 666 766 703 766 725 766 750 766 756 766 766 766 800 766 886 766 898 766 916 766 933 766 1008 766 1020 766 1029 766 1087 766 1088 766 1100 766 1107 766 1112 766 1166 766 1185 766 1257 766 1300 766 1338 766 1388 766 1457 766 1492 767 66 767 129 767 131 767 145 767 174 767 180 767 261 767 283 767 304 767 322 767 328 767 340 767 349 767 352 767 394 767 395 767 431 767 464 767 486 767 539 767 575 767 576 767 623 767 625 767 695 767 745 767 767 767 769 767 792 767 885 767 887 767 944 767 969 767 980 767 1007 767 1046 767 1067 767 1072 767 1125 767 1141 767 1155 767 1178 767 1209 767 1244 767 1261 767 1333 767 1353 767 1468 768 51 768 70 768 80 768 98 768 106 768 151 768 179 768 181 768 225 768 226 768 245 768 246 768 251 768 276 768 281 768 310 768 339 768 358 768 412 768 419 768 430 768 437 768 509 768 663 768 664 768 665 768 682 768 689 768 692 768 699 768 713 768 729 768 760 768 768 768 787 768 821 768 845 768 912 768 932 768 949 768 950 768 952 768 963 768 974 768 1011 768 1022 768 1032 768 1045 768 1055 768 1063 768 1170 768 1190 768 1208 768 1251 768 1288 768 1398 768 1465 768 1487 769 24 769 129 769 145 769 180 769 192 769 255 769 268 769 286 769 323 769 325 769 328 769 340 769 348 769 352 769 395 769 506 769 522 769 549 769 702 769 745 769 767 769 769 769 969 769 983 769 1046 769 1064 769 1155 769 1178 769 1238 769 1336 769 1415 769 1459 769 1499 770 23 770 37 770 49 770 128 770 184 770 198 770 290 770 360 770 376 770 443 770 457 770 503 770 555 770 559 770 574 770 582 770 589 770 593 770 622 770 627 770 639 770 657 770 673 770 725 770 756 770 770 770 800 770 805 770 886 770 933 770 955 770 1020 770 1088 770 1101 770 1166 770 1268 770 1346 770 1364 770 1388 770 1429 770 1433 770 1457 770 1479 770 1483 770 1492 771 0 771 116 771 197 771 264 771 298 771 301 771 312 771 325 771 327 771 338 771 359 771 398 771 436 771 442 771 539 771 546 771 597 771 598 771 646 771 721 771 758 771 771 771 866 771 885 771 892 771 897 771 934 771 944 771 1011 771 1079 771 1085 771 1124 771 1145 771 1178 771 1244 771 1266 771 1305 771 1327 771 1330 771 1400 771 1413 772 35 772 48 772 94 772 131 772 134 772 140 772 246 772 284 772 313 772 320 772 321 772 363 772 374 772 382 772 393 772 406 772 411 772 413 772 417 772 486 772 501 772 521 772 540 772 596 772 679 772 688 772 718 772 726 772 740 772 741 772 746 772 762 772 772 772 775 772 781 772 782 772 797 772 806 772 852 772 880 772 918 772 945 772 946 772 961 772 963 772 974 772 998 772 1048 772 1049 772 1094 772 1139 772 1158 772 1164 772 1181 772 1213 772 1223 772 1292 772 1362 772 1387 772 1453 773 33 773 61 773 110 773 155 773 169 773 342 773 364 773 447 773 458 773 493 773 514 773 586 773 749 773 773 773 843 773 904 773 941 773 943 773 956 773 1269 773 1345 773 1421 773 1437 774 59 774 67 774 161 774 190 774 335 774 414 774 435 774 774 774 840 774 841 774 857 774 919 774 1021 774 1231 774 1320 774 1365 774 1409 774 1432 774 1443 774 1454 774 1477 774 1491 774 1497 775 27 775 127 775 131 775 134 775 138 775 228 775 243 775 289 775 337 775 392 775 393 775 459 775 479 775 486 775 501 775 502 775 513 775 535 775 649 775 678 775 679 775 726 775 741 775 746 775 753 775 757 775 772 775 775 775 789 775 797 775 830 775 831 775 834 775 879 775 890 775 909 775 918 775 921 775 925 775 946 775 968 775 1000 775 1016 775 1048 775 1072 775 1111 775 1120 775 1160 775 1213 775 1286 775 1349 775 1410 775 1414 775 1446 776 116 776 174 776 175 776 206 776 304 776 325 776 349 776 355 776 356 776 425 776 429 776 431 776 444 776 522 776 537 776 539 776 580 776 590 776 646 776 652 776 681 776 776 776 795 776 884 776 885 776 897 776 923 776 980 776 985 776 992 776 1039 776 1046 776 1131 776 1140 776 1141 776 1204 776 1261 776 1316 776 1339 776 1446 776 1499 777 123 777 143 777 167 777 178 777 219 777 242 777 319 777 326 777 350 777 360 777 378 777 416 777 418 777 422 777 457 777 508 777 555 777 583 777 589 777 593 777 617 777 622 777 639 777 644 777 703 777 732 777 777 777 800 777 886 777 900 777 928 777 935 777 958 777 997 777 1010 777 1015 777 1071 777 1087 777 1106 777 1146 777 1154 777 1161 777 1167 777 1171 777 1185 777 1200 777 1205 777 1211 777 1257 777 1268 777 1289 777 1294 777 1311 777 1326 777 1346 777 1388 777 1426 777 1431 777 1479 778 9 778 19 778 73 778 121 778 130 778 152 778 205 778 259 778 270 778 286 778 312 778 338 778 506 778 536 778 549 778 560 778 587 778 655 778 698 778 701 778 734 778 752 778 761 778 778 778 802 778 815 778 892 778 905 778 959 778 967 778 983 778 1084 778 1113 778 1118 778 1124 778 1145 778 1212 778 1214 778 1221 778 1330 778 1343 778 1382 778 1400 778 1413 778 1442 778 1455 778 1481 778 1486 779 43 779 46 779 60 779 77 779 104 779 118 779 154 779 176 779 208 779 254 779 280 779 287 779 309 779 369 779 385 779 410 779 456 779 500 779 541 779 557 779 565 779 633 779 651 779 724 779 747 779 779 779 826 779 861 779 891 779 902 779 927 779 957 779 976 779 989 779 1013 779 1025 779 1030 779 1128 779 1150 779 1182 779 1207 779 1210 779 1243 779 1279 779 1295 779 1310 779 1366 779 1380 779 1439 779 1489 780 25 780 69 780 108 780 119 780 146 780 273 780 427 780 438 780 454 780 635 780 722 780 731 780 780 780 794 780 872 780 970 780 982 780 1133 780 1186 780 1222 780 1228 780 1260 780 1263 780 1298 780 1384 780 1385 780 1466 780 1488 781 35 781 41 781 81 781 140 781 172 781 188 781 199 781 284 781 313 781 321 781 363 781 374 781 382 781 393 781 406 781 411 781 413 781 487 781 498 781 510 781 521 781 540 781 577 781 713 781 718 781 741 781 772 781 781 781 782 781 790 781 852 781 918 781 929 781 961 781 963 781 998 781 1048 781 1049 781 1094 781 1158 781 1164 781 1181 781 1223 781 1251 781 1425 781 1453 782 6 782 35 782 41 782 42 782 48 782 94 782 140 782 188 782 199 782 256 782 284 782 303 782 313 782 321 782 339 782 363 782 374 782 382 782 406 782 413 782 512 782 521 782 540 782 577 782 594 782 635 782 713 782 718 782 772 782 781 782 782 782 790 782 810 782 831 782 852 782 929 782 961 782 998 782 1052 782 1081 782 1094 782 1158 782 1163 782 1164 782 1201 782 1208 782 1223 782 1251 782 1362 782 1363 782 1399 782 1488 783 34 783 136 783 213 783 252 783 383 783 400 783 439 783 448 783 495 783 615 783 783 783 813 783 847 783 868 783 869 783 889 783 1110 783 1138 783 1174 783 1255 783 1284 783 1376 783 1434 784 14 784 47 784 56 784 79 784 135 784 144 784 164 784 223 784 230 784 279 784 295 784 371 784 387 784 389 784 391 784 401 784 408 784 478 784 483 784 520 784 526 784 556 784 592 784 600 784 611 784 638 784 680 784 784 784 809 784 814 784 822 784 839 784 844 784 888 784 906 784 910 784 911 784 940 784 978 784 1014 784 1034 784 1068 784 1097 784 1099 784 1142 784 1180 784 1206 784 1216 784 1229 784 1230 784 1277 784 1281 784 1299 784 1370 784 1373 784 1407 784 1441 784 1474 784 1484 784 1498 785 30 785 58 785 90 785 137 785 175 785 212 785 216 785 270 785 323 785 440 785 464 785 511 785 533 785 563 785 720 785 785 785 808 785 887 785 1047 785 1057 785 1089 785 1141 785 1187 785 1219 785 1234 785 1238 785 1283 785 1332 785 1334 785 1390 785 1459 786 6 786 17 786 27 786 89 786 96 786 124 786 162 786 172 786 255 786 263 786 268 786 283 786 304 786 313 786 322 786 328 786 354 786 363 786 374 786 382 786 392 786 394 786 399 786 413 786 486 786 501 786 531 786 576 786 590 786 634 786 649 786 681 786 695 786 711 786 726 786 746 786 757 786 786 786 789 786 810 786 830 786 865 786 881 786 887 786 921 786 942 786 946 786 961 786 969 786 991 786 992 786 1039 786 1059 786 1092 786 1125 786 1140 786 1160 786 1173 786 1201 786 1209 786 1213 786 1351 786 1410 786 1414 786 1446 787 11 787 29 787 41 787 94 787 106 787 151 787 179 787 199 787 225 787 245 787 249 787 251 787 318 787 339 787 347 787 459 787 509 787 510 787 545 787 602 787 664 787 665 787 699 787 713 787 760 787 768 787 787 787 820 787 821 787 828 787 845 787 912 787 949 787 950 787 952 787 986 787 1019 787 1026 787 1033 787 1063 787 1152 787 1170 787 1190 787 1304 787 1335 787 1408 787 1465 787 1471 788 84 788 88 788 173 788 209 788 324 788 420 788 472 788 477 788 488 788 489 788 525 788 572 788 581 788 659 788 668 788 675 788 723 788 728 788 737 788 788 788 798 788 818 788 1006 788 1062 788 1080 788 1093 788 1096 788 1104 788 1115 788 1143 788 1149 788 1192 788 1259 788 1293 788 1303 788 1469 789 27 789 89 789 96 789 127 789 162 789 228 789 243 789 289 789 328 789 479 789 486 789 501 789 577 789 649 789 679 789 726 789 741 789 757 789 775 789 786 789 789 789 797 789 830 789 831 789 881 789 890 789 909 789 918 789 921 789 942 789 946 789 968 789 988 789 991 789 1000 789 1092 789 1111 789 1120 789 1213 789 1410 789 1414 789 1446 790 11 790 35 790 41 790 81 790 94 790 179 790 188 790 199 790 245 790 276 790 284 790 339 790 374 790 380 790 382 790 393 790 406 790 487 790 496 790 510 790 513 790 535 790 713 790 754 790 762 790 781 790 782 790 790 790 828 790 834 790 912 790 929 790 946 790 949 790 963 790 1033 790 1045 790 1048 790 1070 790 1081 790 1094 790 1152 790 1158 790 1164 790 1190 790 1201 790 1215 790 1223 790 1241 790 1251 790 1304 790 1335 790 1408 790 1425 790 1445 791 22 791 107 791 143 791 156 791 266 791 378 791 446 791 449 791 507 791 530 791 543 791 558 791 570 791 583 791 607 791 613 791 621 791 739 791 791 791 854 791 862 791 873 791 900 791 903 791 935 791 937 791 948 791 962 791 994 791 1071 791 1090 791 1127 791 1146 791 1156 791 1162 791 1176 791 1184 791 1224 791 1289 791 1294 791 1324 791 1326 791 1386 791 1444 791 1464 792 38 792 66 792 96 792 174 792 212 792 216 792 261 792 322 792 328 792 349 792 354 792 394 792 431 792 464 792 479 792 534 792 580 792 720 792 767 792 792 792 808 792 874 792 887 792 942 792 969 792 980 792 1017 792 1046 792 1047 792 1067 792 1089 792 1125 792 1140 792 1141 792 1209 792 1219 792 1234 792 1238 792 1244 792 1249 792 1283 792 1332 792 1359 792 1418 793 120 793 214 793 275 793 293 793 353 793 361 793 372 793 415 793 476 793 523 793 647 793 677 793 719 793 793 793 850 793 932 793 1051 793 1056 793 1117 793 1195 793 1306 793 1307 793 1342 793 1377 793 1424 794 25 794 69 794 70 794 98 794 111 794 119 794 197 794 220 794 256 794 298 794 303 794 330 794 353 794 427 794 450 794 454 794 731 794 780 794 794 794 796 794 982 794 1012 794 1031 794 1052 794 1055 794 1083 794 1186 794 1222 794 1228 794 1256 794 1260 794 1263 794 1298 794 1371 794 1385 794 1396 794 1447 794 1466 794 1488 795 28 795 89 795 233 795 244 795 268 795 283 795 286 795 304 795 349 795 355 795 394 795 399 795 440 795 444 795 505 795 580 795 623 795 631 795 652 795 681 795 695 795 776 795 795 795 829 795 865 795 992 795 1007 795 1059 795 1131 795 1140 795 1199 795 1316 795 1351 795 1378 795 1425 795 1446 795 1467 796 2 796 93 796 95 796 111 796 126 796 132 796 194 796 227 796 231 796 241 796 247 796 282 796 353 796 362 796 384 796 450 796 463 796 481 796 516 796 564 796 614 796 654 796 670 796 675 796 794 796 796 796 970 796 975 796 1001 796 1012 796 1036 796 1050 796 1105 796 1116 796 1119 796 1122 796 1186 796 1194 796 1248 796 1256 796 1280 796 1298 796 1302 796 1329 796 1354 796 1384 796 1396 796 1478 797 127 797 134 797 140 797 228 797 243 797 289 797 321 797 337 797 392 797 393 797 486 797 501 797 521 797 552 797 568 797 649 797 679 797 705 797 726 797 741 797 746 797 753 797 772 797 775 797 789 797 797 797 879 797 890 797 918 797 946 797 968 797 991 797 1000 797 1042 797 1048 797 1072 797 1111 797 1120 797 1139 797 1173 797 1213 797 1292 797 1372 797 1414 798 74 798 88 798 113 798 132 798 201 798 209 798 227 798 306 798 324 798 386 798 420 798 474 798 481 798 515 798 525 798 566 798 581 798 659 798 668 798 723 798 728 798 737 798 788 798 798 798 804 798 818 798 1002 798 1093 798 1104 798 1192 798 1232 798 1259 798 1293 798 1391 799 44 799 57 799 147 799 344 799 375 799 388 799 491 799 733 799 799 799 893 799 990 799 993 799 1027 799 1202 799 1278 799 1355 799 1358 799 1456 800 37 800 49 800 122 800 128 800 170 800 184 800 290 800 319 800 326 800 350 800 360 800 376 800 416 800 418 800 443 800 457 800 508 800 555 800 574 800 589 800 593 800 622 800 639 800 644 800 673 800 725 800 732 800 756 800 766 800 770 800 777 800 800 800 886 800 933 800 955 800 1010 800 1015 800 1020 800 1087 800 1101 800 1146 800 1166 800 1167 800 1185 800 1200 800 1205 800 1257 800 1268 800 1273 800 1311 800 1346 800 1388 800 1429 800 1431 800 1433 800 1457 800 1479 801 2 801 93 801 95 801 126 801 153 801 227 801 231 801 271 801 282 801 296 801 315 801 450 801 454 801 463 801 516 801 564 801 801 801 838 801 858 801 975 801 1001 801 1002 801 1036 801 1116 801 1119 801 1122 801 1194 801 1227 801 1280 801 1282 801 1298 801 1354 801 1394 801 1396 801 1478 802 19 802 64 802 73 802 205 802 259 802 285 802 288 802 312 802 338 802 465 802 536 802 587 802 628 802 655 802 701 802 734 802 761 802 765 802 778 802 802 802 871 802 892 802 1044 802 1113 802 1118 802 1124 802 1212 802 1214 802 1242 802 1327 802 1330 802 1343 802 1382 802 1419 802 1442 802 1455 802 1463 802 1486 803 70 803 98 803 108 803 133 803 151 803 186 803 238 803 256 803 264 803 273 803 281 803 298 803 301 803 303 803 358 803 438 803 442 803 518 803 645 803 674 803 722 803 729 803 731 803 803 803 824 803 1011 803 1031 803 1032 803 1085 803 1147 803 1228 803 1263 803 1271 803 1305 803 1363 803 1371 803 1412 803 1488 803 1499 804 74 804 201 804 227 804 231 804 306 804 420 804 461 804 515 804 525 804 553 804 659 804 668 804 696 804 723 804 748 804 798 804 804 804 858 804 924 804 1002 804 1040 804 1096 804 1119 804 1254 804 1259 804 1272 804 1285 804 1302 804 1303 804 1391 805 37 805 49 805 75 805 122 805 128 805 178 805 198 805 203 805 290 805 350 805 360 805 368 805 376 805 443 805 468 805 503 805 517 805 551 805 555 805 573 805 574 805 582 805 589 805 593 805 639 805 657 805 671 805 673 805 725 805 756 805 770 805 805 805 819 805 836 805 886 805 955 805 1020 805 1101 805 1107 805 1166 805 1171 805 1185 805 1200 805 1203 805 1205 805 1273 805 1311 805 1364 805 1433 805 1460 805 1483 806 1 806 100 806 140 806 226 806 246 806 260 806 265 806 320 806 393 806 406 806 417 806 421 806 445 806 487 806 596 806 616 806 653 806 672 806 688 806 712 806 717 806 740 806 754 806 762 806 772 806 806 806 855 806 856 806 922 806 945 806 974 806 1042 806 1045 806 1074 806 1077 806 1094 806 1139 806 1158 806 1181 806 1195 806 1315 806 1317 806 1342 806 1387 806 1397 806 1428 806 1438 806 1453 806 1470 806 1473 807 79 807 125 807 135 807 189 807 217 807 223 807 224 807 232 807 253 807 305 807 344 807 371 807 373 807 387 807 404 807 478 807 483 807 484 807 491 807 544 807 556 807 567 807 591 807 600 807 624 807 640 807 684 807 690 807 694 807 807 807 860 807 875 807 910 807 911 807 990 807 1068 807 1078 807 1082 807 1099 807 1142 807 1196 807 1206 807 1217 807 1235 807 1236 807 1250 807 1277 807 1355 807 1356 807 1361 807 1375 807 1441 807 1456 807 1474 808 38 808 58 808 90 808 182 808 216 808 221 808 222 808 257 808 262 808 351 808 431 808 490 808 506 808 533 808 534 808 536 808 618 808 637 808 701 808 702 808 785 808 792 808 808 808 827 808 1044 808 1065 808 1118 808 1187 808 1219 808 1249 808 1258 808 1334 808 1360 808 1415 808 1448 808 1486 809 14 809 47 809 52 809 63 809 92 809 125 809 160 809 230 809 240 809 272 809 279 809 373 809 387 809 404 809 434 809 441 809 569 809 600 809 612 809 624 809 630 809 690 809 694 809 743 809 784 809 809 809 882 809 888 809 910 809 999 809 1026 809 1069 809 1075 809 1097 809 1108 809 1196 809 1206 809 1277 809 1461 809 1472 809 1476 809 1484 810 6 810 42 810 45 810 48 810 51 810 70 810 94 810 124 810 127 810 172 810 256 810 263 810 268 810 283 810 303 810 321 810 339 810 382 810 392 810 406 810 501 810 512 810 575 810 576 810 635 810 678 810 718 810 722 810 726 810 757 810 782 810 786 810 810 810 896 810 921 810 961 810 1007 810 1033 810 1039 810 1052 810 1081 810 1086 810 1160 810 1163 810 1181 810 1201 810 1208 810 1349 810 1362 810 1363 810 1399 810 1468 810 1488 811 10 811 103 811 141 811 195 811 210 811 299 811 314 811 341 811 342 811 364 811 379 811 504 811 542 811 551 811 571 811 578 811 582 811 643 811 666 811 687 811 693 811 697 811 704 811 749 811 811 811 898 811 904 811 913 811 915 811 943 811 1008 811 1095 811 1109 811 1168 811 1240 811 1246 811 1269 811 1275 811 1297 811 1312 811 1323 811 1338 811 1352 811 1374 811 1420 811 1437 811 1457 811 1495 812 30 812 53 812 78 812 82 812 90 812 102 812 130 812 191 812 211 812 212 812 270 812 308 812 332 812 428 812 451 812 460 812 511 812 533 812 534 812 537 812 549 812 610 812 631 812 637 812 658 812 685 812 752 812 761 812 812 812 827 812 829 812 863 812 884 812 905 812 923 812 967 812 1003 812 1057 812 1065 812 1084 812 1135 812 1137 812 1141 812 1183 812 1219 812 1249 812 1334 812 1336 812 1390 812 1418 812 1459 812 1481 813 34 813 40 813 136 813 171 813 207 813 213 813 237 813 274 813 307 813 423 813 439 813 495 813 588 813 615 813 744 813 783 813 813 813 847 813 848 813 853 813 859 813 868 813 869 813 889 813 936 813 1041 813 1110 813 1130 813 1138 813 1174 813 1237 813 1255 813 1284 813 1322 813 1347 813 1376 813 1422 813 1434 814 47 814 76 814 144 814 223 814 224 814 232 814 253 814 279 814 295 814 305 814 343 814 371 814 389 814 408 814 478 814 483 814 592 814 600 814 638 814 648 814 680 814 684 814 694 814 784 814 814 814 822 814 839 814 860 814 940 814 978 814 1014 814 1068 814 1078 814 1097 814 1099 814 1142 814 1180 814 1216 814 1217 814 1229 814 1277 814 1281 814 1299 814 1355 814 1356 814 1361 814 1370 814 1375 814 1407 814 1441 814 1474 814 1498 815 9 815 30 815 54 815 73 815 90 815 121 815 130 815 152 815 205 815 259 815 270 815 286 815 312 815 338 815 485 815 536 815 560 815 618 815 655 815 698 815 701 815 734 815 752 815 761 815 778 815 815 815 823 815 884 815 905 815 967 815 1221 815 1330 815 1343 815 1382 815 1400 815 1413 815 1415 815 1455 815 1481 815 1486 816 3 816 8 816 19 816 64 816 97 816 183 816 407 816 473 816 499 816 614 816 628 816 654 816 660 816 662 816 709 816 765 816 816 816 849 816 951 816 1132 816 1227 816 1242 816 1419 816 1463 817 138 817 264 817 267 817 318 817 475 817 496 817 513 817 535 817 545 817 597 817 758 817 817 817 824 817 828 817 834 817 979 817 1009 817 1011 817 1033 817 1204 817 1215 817 1318 817 1321 817 1425 817 1449 818 62 818 74 818 84 818 88 818 173 818 201 818 209 818 293 818 306 818 324 818 334 818 420 818 461 818 488 818 525 818 553 818 566 818 572 818 581 818 659 818 668 818 723 818 728 818 737 818 788 818 798 818 818 818 924 818 1006 818 1062 818 1080 818 1093 818 1096 818 1104 818 1115 818 1143 818 1149 818 1192 818 1293 818 1391 818 1469 819 122 819 142 819 157 819 203 819 316 819 443 819 468 819 517 819 671 819 805 819 819 819 836 819 877 819 914 819 1043 819 1101 819 1121 819 1169 819 1171 819 1430 820 81 820 99 820 106 820 188 820 249 820 329 820 337 820 347 820 430 820 487 820 510 820 529 820 550 820 585 820 602 820 656 820 754 820 787 820 820 820 922 820 949 820 1019 820 1022 820 1063 820 1070 820 1152 820 1175 820 1190 820 1241 820 1317 820 1408 820 1428 820 1445 821 0 821 11 821 29 821 106 821 151 821 220 821 225 821 251 821 276 821 278 821 339 821 347 821 358 821 367 821 412 821 419 821 430 821 437 821 467 821 480 821 496 821 509 821 529 821 545 821 597 821 663 821 664 821 665 821 682 821 683 821 689 821 699 821 713 821 760 821 768 821 787 821 821 821 828 821 845 821 912 821 986 821 996 821 1011 821 1019 821 1033 821 1055 821 1063 821 1170 821 1197 821 1208 821 1215 821 1304 821 1335 821 1398 821 1465 822 14 822 47 822 79 822 101 822 223 822 279 822 295 822 305 822 391 822 401 822 408 822 452 822 478 822 484 822 526 822 567 822 591 822 606 822 608 822 638 822 680 822 684 822 784 822 814 822 822 822 839 822 867 822 908 822 940 822 978 822 1014 822 1018 822 1076 822 1097 822 1098 822 1142 822 1206 822 1216 822 1229 822 1236 822 1250 822 1281 822 1290 822 1313 822 1348 822 1356 822 1370 822 1375 822 1407 822 1441 822 1498 823 9 823 15 823 54 823 121 823 130 823 158 823 182 823 205 823 221 823 262 823 285 823 351 823 381 823 462 823 485 823 490 823 536 823 618 823 685 823 698 823 701 823 735 823 815 823 823 823 827 823 837 823 864 823 905 823 1044 823 1144 823 1153 823 1183 823 1221 823 1258 823 1340 823 1343 823 1360 823 1389 823 1448 823 1452 823 1455 823 1463 824 0 824 24 824 220 824 238 824 264 824 281 824 298 824 301 824 303 824 327 824 338 824 358 824 398 824 442 824 475 824 480 824 482 824 518 824 629 824 674 824 689 824 731 824 803 824 817 824 824 824 866 824 996 824 1007 824 1011 824 1031 824 1085 824 1145 824 1147 824 1204 824 1228 824 1266 824 1271 824 1305 824 1371 824 1400 824 1403 824 1412 824 1468 824 1488 825 2 825 80 825 114 825 181 825 220 825 225 825 656 825 663 825 670 825 675 825 721 825 825 825 966 825 1012 825 1050 825 1055 825 1170 825 1175 825 1186 825 1308 825 1329 825 1384 825 1395 826 62 826 104 826 105 826 109 826 176 826 208 826 254 826 309 826 346 826 410 826 426 826 456 826 489 826 500 826 532 826 633 826 651 826 710 826 724 826 779 826 826 826 878 826 899 826 917 826 927 826 957 826 976 826 1025 826 1030 826 1114 826 1149 826 1207 826 1220 826 1243 826 1270 826 1310 826 1350 826 1380 826 1383 827 9 827 15 827 54 827 121 827 130 827 158 827 182 827 205 827 221 827 229 827 257 827 262 827 285 827 351 827 381 827 462 827 485 827 490 827 536 827 610 827 618 827 619 827 685 827 698 827 752 827 808 827 812 827 823 827 827 827 837 827 864 827 905 827 1044 827 1065 827 1144 827 1153 827 1183 827 1221 827 1258 827 1343 827 1360 827 1448 827 1452 828 0 828 11 828 21 828 41 828 151 828 186 828 225 828 256 828 276 828 278 828 339 828 347 828 358 828 412 828 419 828 437 828 459 828 496 828 509 828 513 828 545 828 597 828 664 828 699 828 713 828 787 828 790 828 817 828 821 828 828 828 912 828 996 828 1011 828 1033 828 1045 828 1052 828 1055 828 1063 828 1081 828 1201 828 1208 828 1215 828 1304 828 1335 828 1398 828 1417 828 1465 828 1488 829 30 829 53 829 78 829 90 829 102 829 191 829 211 829 212 829 270 829 286 829 308 829 348 829 349 829 354 829 394 829 399 829 428 829 440 829 451 829 460 829 464 829 511 829 537 829 549 829 580 829 610 829 625 829 631 829 652 829 720 829 752 829 761 829 795 829 812 829 829 829 863 829 923 829 980 829 1003 829 1057 829 1059 829 1065 829 1084 829 1131 829 1137 829 1140 829 1141 829 1199 829 1238 829 1249 829 1316 829 1336 829 1351 829 1390 829 1418 829 1459 829 1481 830 27 830 66 830 89 830 96 830 127 830 131 830 162 830 263 830 283 830 289 830 392 830 479 830 486 830 501 830 552 830 575 830 625 830 634 830 678 830 711 830 726 830 746 830 775 830 786 830 789 830 830 830 865 830 879 830 887 830 896 830 909 830 921 830 929 830 942 830 946 830 1016 830 1047 830 1059 830 1111 830 1160 830 1165 830 1213 830 1316 830 1410 830 1414 830 1425 830 1446 831 27 831 89 831 127 831 162 831 228 831 382 831 392 831 406 831 470 831 479 831 501 831 540 831 577 831 678 831 705 831 753 831 775 831 782 831 789 831 831 831 865 831 896 831 991 831 995 831 1009 831 1016 831 1120 831 1160 831 1201 831 1372 831 1410 831 1414 831 1425 831 1449 832 28 832 70 832 138 832 267 832 321 832 467 832 470 832 498 832 521 832 540 832 552 832 568 832 705 832 741 832 753 832 832 832 931 832 995 832 1086 832 1111 832 1120 832 1208 832 1292 832 1339 832 1417 833 32 833 40 833 115 833 139 833 157 833 177 833 237 833 307 833 366 833 453 833 833 833 835 833 848 833 859 833 869 833 914 833 926 833 1041 833 1061 833 1103 833 1138 833 1245 833 1247 833 1262 833 1276 833 1296 833 1347 833 1376 833 1406 833 1482 834 81 834 127 834 134 834 138 834 228 834 243 834 318 834 337 834 393 834 496 834 513 834 535 834 649 834 713 834 757 834 775 834 790 834 817 834 834 834 909 834 912 834 918 834 925 834 946 834 968 834 979 834 1000 834 1016 834 1033 834 1048 834 1070 834 1215 834 1241 834 1286 834 1392 834 1408 834 1425 834 1445 834 1449 834 1471 835 32 835 34 835 40 835 139 835 150 835 171 835 177 835 207 835 213 835 237 835 248 835 307 835 317 835 366 835 439 835 453 835 495 835 706 835 744 835 833 835 835 835 848 835 853 835 859 835 868 835 869 835 889 835 926 835 936 835 1041 835 1061 835 1103 835 1110 835 1138 835 1237 835 1247 835 1262 835 1276 835 1296 835 1322 835 1347 835 1376 835 1381 835 1406 835 1482 836 37 836 49 836 50 836 68 836 75 836 128 836 141 836 195 836 203 836 204 836 242 836 294 836 368 836 443 836 571 836 573 836 657 836 671 836 673 836 697 836 756 836 805 836 819 836 836 836 916 836 930 836 953 836 1029 836 1107 836 1169 836 1203 836 1273 836 1364 836 1379 836 1460 836 1483 837 9 837 15 837 54 837 121 837 158 837 182 837 205 837 221 837 229 837 285 837 351 837 381 837 462 837 473 837 485 837 490 837 599 837 618 837 685 837 698 837 735 837 823 837 827 837 837 837 849 837 864 837 1044 837 1144 837 1153 837 1183 837 1221 837 1258 837 1343 837 1360 837 1382 837 1389 837 1448 837 1452 837 1455 837 1463 838 2 838 93 838 95 838 113 838 126 838 153 838 227 838 231 838 282 838 296 838 315 838 450 838 454 838 463 838 481 838 515 838 516 838 564 838 801 838 838 838 975 838 982 838 1001 838 1002 838 1116 838 1119 838 1122 838 1194 838 1227 838 1253 838 1280 838 1282 838 1298 838 1354 838 1394 838 1396 838 1478 839 14 839 47 839 79 839 144 839 217 839 223 839 279 839 295 839 305 839 371 839 387 839 389 839 391 839 401 839 408 839 452 839 478 839 483 839 526 839 567 839 638 839 680 839 684 839 784 839 814 839 822 839 839 839 844 839 911 839 940 839 978 839 1014 839 1068 839 1097 839 1098 839 1142 839 1206 839 1216 839 1229 839 1236 839 1250 839 1281 839 1290 839 1313 839 1355 839 1356 839 1370 839 1375 839 1407 839 1441 839 1498 840 59 840 67 840 161 840 190 840 335 840 414 840 435 840 774 840 840 840 841 840 857 840 919 840 953 840 1021 840 1231 840 1320 840 1365 840 1409 840 1432 840 1443 840 1454 840 1477 840 1491 840 1497 841 59 841 190 841 396 841 414 841 435 841 604 841 669 841 691 841 727 841 774 841 840 841 841 841 919 841 953 841 987 841 1021 841 1038 841 1151 841 1267 841 1320 841 1379 841 1432 841 1450 841 1454 841 1477 841 1491 842 106 842 185 842 244 842 288 842 359 842 398 842 419 842 430 842 480 842 494 842 529 842 546 842 598 842 645 842 650 842 663 842 665 842 674 842 683 842 760 842 842 842 996 842 1019 842 1060 842 1070 842 1079 842 1197 842 1218 842 1318 842 1412 842 1440 842 1465 843 33 843 61 843 110 843 155 843 169 843 342 843 364 843 447 843 458 843 493 843 586 843 687 843 749 843 773 843 843 843 904 843 913 843 941 843 943 843 956 843 1109 843 1269 843 1345 843 1421 843 1437 844 56 844 72 844 79 844 101 844 135 844 164 844 223 844 224 844 230 844 279 844 343 844 373 844 387 844 389 844 391 844 408 844 484 844 497 844 520 844 524 844 556 844 592 844 600 844 611 844 638 844 680 844 784 844 839 844 844 844 867 844 906 844 911 844 940 844 972 844 1034 844 1068 844 1078 844 1097 844 1099 844 1180 844 1196 844 1198 844 1206 844 1230 844 1277 844 1299 844 1361 844 1370 844 1373 844 1393 844 1407 844 1441 844 1474 844 1484 844 1496 845 11 845 29 845 179 845 225 845 249 845 273 845 278 845 339 845 367 845 372 845 459 845 509 845 523 845 656 845 682 845 692 845 768 845 787 845 821 845 845 845 855 845 872 845 880 845 973 845 1026 845 1063 845 1152 845 1170 845 1175 845 1197 845 1335 845 1399 846 53 846 86 846 206 846 211 846 277 846 308 846 332 846 348 846 405 846 451 846 563 846 579 846 626 846 658 846 752 846 846 846 863 846 901 846 1024 846 1066 846 1084 846 1131 846 1137 846 1309 846 1475 846 1494 847 159 847 196 847 252 847 345 847 383 847 400 847 448 847 615 847 739 847 764 847 783 847 813 847 847 847 920 847 1037 847 1090 847 1126 847 1172 847 1174 847 1267 847 1287 847 1325 847 1386 847 1434 847 1436 847 1493 848 16 848 32 848 34 848 40 848 115 848 139 848 150 848 171 848 177 848 207 848 213 848 237 848 274 848 297 848 307 848 317 848 366 848 439 848 453 848 495 848 588 848 744 848 813 848 833 848 835 848 848 848 853 848 859 848 869 848 926 848 936 848 1041 848 1103 848 1110 848 1138 848 1237 848 1247 848 1262 848 1276 848 1284 848 1296 848 1322 848 1347 848 1376 848 1381 848 1482 849 3 849 8 849 19 849 64 849 182 849 183 849 381 849 407 849 473 849 527 849 599 849 614 849 628 849 660 849 709 849 735 849 816 849 837 849 849 849 1132 849 1144 849 1227 849 1389 849 1419 849 1452 849 1455 849 1463 850 1 850 214 850 265 850 415 850 476 850 523 850 672 850 712 850 793 850 850 850 855 850 856 850 876 850 932 850 945 850 974 850 1051 850 1074 850 1117 850 1195 850 1317 850 1337 850 1342 850 1397 850 1473 851 18 851 129 851 146 851 192 851 255 851 269 851 340 851 352 851 395 851 531 851 700 851 745 851 851 851 907 851 1089 851 1123 851 1155 851 1177 851 1193 851 1415 852 35 852 94 852 108 852 124 852 140 852 172 852 255 852 284 852 313 852 321 852 363 852 374 852 382 852 413 852 512 852 531 852 540 852 577 852 635 852 688 852 718 852 740 852 772 852 781 852 782 852 852 852 907 852 961 852 998 852 1049 852 1086 852 1123 852 1163 852 1177 852 1223 852 1292 852 1362 853 16 853 32 853 34 853 40 853 136 853 171 853 177 853 207 853 213 853 237 853 274 853 307 853 317 853 439 853 453 853 495 853 588 853 738 853 744 853 813 853 835 853 848 853 853 853 859 853 868 853 869 853 926 853 936 853 1041 853 1110 853 1138 853 1237 853 1247 853 1262 853 1276 853 1284 853 1296 853 1322 853 1347 853 1381 854 22 854 91 854 107 854 143 854 156 854 266 854 378 854 396 854 400 854 446 854 449 854 507 854 508 854 543 854 570 854 604 854 607 854 613 854 617 854 621 854 636 854 644 854 669 854 691 854 727 854 739 854 791 854 854 854 873 854 900 854 903 854 920 854 935 854 937 854 962 854 994 854 1010 854 1038 854 1090 854 1146 854 1151 854 1162 854 1176 854 1294 854 1324 854 1386 854 1444 855 1 855 226 855 246 855 249 855 265 855 278 855 310 855 320 855 550 855 616 855 653 855 656 855 672 855 688 855 712 855 740 855 806 855 845 855 850 855 855 855 856 855 880 855 932 855 945 855 963 855 974 855 1042 855 1074 855 1094 855 1139 855 1317 855 1335 855 1337 855 1342 855 1387 855 1399 855 1428 855 1438 855 1453 855 1473 856 1 856 100 856 214 856 246 856 260 856 265 856 320 856 417 856 476 856 616 856 653 856 672 856 688 856 712 856 740 856 806 856 850 856 855 856 856 856 876 856 945 856 974 856 1074 856 1117 856 1139 856 1177 856 1195 856 1306 856 1337 856 1342 856 1387 856 1397 856 1438 856 1453 856 1473 857 59 857 67 857 161 857 190 857 335 857 414 857 435 857 774 857 840 857 857 857 1021 857 1231 857 1320 857 1365 857 1409 857 1432 857 1443 857 1477 857 1491 857 1497 858 74 858 84 858 93 858 95 858 120 858 126 858 132 858 201 858 231 858 239 858 241 858 271 858 275 858 282 858 293 858 306 858 311 858 315 858 361 858 488 858 515 858 554 858 564 858 647 858 668 858 677 858 719 858 801 858 804 858 858 858 971 858 975 858 1002 858 1023 858 1058 858 1116 858 1157 858 1248 858 1282 858 1307 858 1354 858 1394 858 1395 858 1424 858 1435 859 32 859 34 859 40 859 136 859 171 859 207 859 213 859 237 859 307 859 366 859 439 859 453 859 495 859 744 859 813 859 833 859 835 859 848 859 853 859 859 859 868 859 869 859 889 859 926 859 936 859 1041 859 1061 859 1103 859 1110 859 1138 859 1237 859 1247 859 1262 859 1276 859 1284 859 1296 859 1322 859 1347 859 1376 859 1381 859 1482 860 44 860 57 860 72 860 76 860 135 860 144 860 149 860 189 860 217 860 224 860 232 860 253 860 305 860 343 860 344 860 370 860 388 860 389 860 397 860 424 860 455 860 478 860 491 860 584 860 591 860 684 860 733 860 807 860 814 860 860 860 893 860 978 860 990 860 993 860 1078 860 1136 860 1142 860 1179 860 1235 860 1250 860 1278 860 1355 860 1356 860 1358 860 1375 860 1393 860 1456 861 39 861 43 861 60 861 77 861 112 861 154 861 176 861 208 861 215 861 280 861 287 861 369 861 385 861 410 861 456 861 541 861 633 861 724 861 747 861 779 861 861 861 891 861 902 861 927 861 954 861 957 861 976 861 989 861 1013 861 1025 861 1030 861 1128 861 1148 861 1150 861 1207 861 1210 861 1243 861 1279 861 1295 861 1310 861 1380 861 1439 861 1489 862 22 862 107 862 156 862 196 862 266 862 345 862 378 862 449 862 507 862 543 862 558 862 570 862 605 862 607 862 621 862 707 862 763 862 791 862 862 862 900 862 937 862 947 862 960 862 1071 862 1090 862 1126 862 1127 862 1156 862 1162 862 1176 862 1184 862 1224 862 1267 862 1386 862 1404 862 1444 862 1464 863 26 863 53 863 58 863 78 863 82 863 86 863 102 863 191 863 193 863 200 863 211 863 270 863 277 863 308 863 332 863 405 863 428 863 444 863 451 863 511 863 533 863 534 863 536 863 537 863 549 863 563 863 579 863 610 863 626 863 658 863 685 863 702 863 752 863 761 863 812 863 829 863 846 863 863 863 901 863 923 863 959 863 1003 863 1024 863 1035 863 1054 863 1066 863 1084 863 1102 863 1113 863 1131 863 1135 863 1137 863 1183 863 1212 863 1221 863 1249 863 1309 863 1327 863 1336 863 1340 863 1341 863 1459 863 1475 863 1481 863 1494 864 9 864 15 864 54 864 121 864 158 864 182 864 205 864 221 864 229 864 257 864 262 864 285 864 351 864 381 864 462 864 485 864 490 864 536 864 618 864 619 864 685 864 698 864 701 864 735 864 823 864 827 864 837 864 864 864 1044 864 1144 864 1153 864 1183 864 1258 864 1360 864 1389 864 1448 864 1452 865 28 865 89 865 233 865 244 865 268 865 283 865 382 865 399 865 470 865 505 865 540 865 678 865 681 865 686 865 786 865 795 865 830 865 831 865 865 865 896 865 921 865 965 865 995 865 1007 865 1009 865 1059 865 1060 865 1140 865 1160 865 1199 865 1314 865 1351 865 1378 865 1425 865 1446 865 1467 866 0 866 19 866 197 866 222 866 298 866 312 866 327 866 330 866 398 866 442 866 518 866 629 866 655 866 734 866 765 866 771 866 824 866 866 866 892 866 934 866 938 866 951 866 983 866 1085 866 1145 866 1147 866 1214 866 1222 866 1327 866 1330 866 1371 866 1400 866 1412 867 36 867 56 867 92 867 101 867 164 867 187 867 218 867 279 867 291 867 373 867 408 867 484 867 497 867 520 867 524 867 526 867 547 867 562 867 569 867 592 867 606 867 608 867 620 867 638 867 667 867 680 867 730 867 822 867 844 867 867 867 870 867 906 867 908 867 972 867 1018 867 1034 867 1098 867 1198 867 1225 867 1236 867 1291 867 1299 867 1331 867 1348 867 1369 867 1373 868 32 868 34 868 136 868 150 868 171 868 207 868 213 868 237 868 307 868 317 868 423 868 439 868 495 868 588 868 706 868 783 868 813 868 835 868 853 868 859 868 868 868 869 868 889 868 936 868 1041 868 1103 868 1110 868 1138 868 1174 868 1237 868 1247 868 1255 868 1262 868 1276 868 1284 868 1296 868 1322 868 1347 868 1376 868 1381 868 1422 869 16 869 32 869 34 869 40 869 115 869 139 869 150 869 171 869 177 869 207 869 213 869 237 869 274 869 307 869 366 869 439 869 453 869 495 869 744 869 783 869 813 869 833 869 835 869 848 869 853 869 859 869 868 869 869 869 926 869 936 869 1041 869 1061 869 1103 869 1110 869 1138 869 1237 869 1247 869 1262 869 1276 869 1296 869 1347 869 1376 869 1381 869 1406 869 1482 870 36 870 55 870 56 870 85 870 101 870 164 870 202 870 218 870 230 870 291 870 441 870 492 870 524 870 547 870 562 870 608 870 609 870 620 870 667 870 730 870 867 870 870 870 1091 870 1098 870 1108 870 1129 870 1225 870 1299 870 1369 870 1373 870 1496 871 19 871 73 871 97 871 197 871 259 871 288 871 312 871 338 871 465 871 499 871 587 871 654 871 655 871 734 871 765 871 802 871 871 871 892 871 1214 871 1218 871 1242 871 1330 871 1343 871 1382 871 1412 871 1419 871 1442 871 1463 872 0 872 29 872 51 872 108 872 273 872 367 872 437 872 438 872 545 872 560 872 594 872 661 872 729 872 780 872 845 872 872 872 895 872 973 872 1083 872 1086 872 1239 872 1371 872 1398 872 1417 872 1466 872 1487 873 7 873 20 873 22 873 87 873 148 873 156 873 266 873 292 873 336 873 378 873 396 873 403 873 446 873 449 873 507 873 530 873 543 873 558 873 583 873 604 873 607 873 621 873 669 873 739 873 763 873 791 873 854 873 873 873 900 873 903 873 920 873 935 873 948 873 960 873 994 873 1005 873 1037 873 1038 873 1071 873 1090 873 1106 873 1162 873 1176 873 1184 873 1224 873 1267 873 1287 873 1289 873 1324 873 1326 873 1386 873 1436 873 1444 873 1464 874 38 874 58 874 137 874 211 874 212 874 216 874 257 874 277 874 349 874 354 874 394 874 428 874 440 874 464 874 534 874 580 874 637 874 711 874 720 874 792 874 874 874 1017 874 1047 874 1234 874 1238 874 1249 874 1283 874 1332 874 1336 874 1351 874 1418 875 79 875 144 875 217 875 223 875 224 875 253 875 371 875 404 875 452 875 484 875 526 875 544 875 556 875 567 875 584 875 591 875 640 875 684 875 807 875 875 875 893 875 910 875 972 875 993 875 1078 875 1082 875 1099 875 1216 875 1217 875 1235 875 1236 875 1250 875 1290 875 1313 875 1348 875 1356 875 1361 875 1375 875 1498 876 18 876 214 876 476 876 850 876 856 876 876 876 907 876 945 876 1074 876 1117 876 1177 876 1193 876 1195 876 1306 876 1337 876 1342 876 1397 876 1473 877 142 877 157 877 316 877 819 877 877 877 914 877 1043 877 1121 877 1430 878 43 878 60 878 77 878 104 878 109 878 112 878 118 878 154 878 176 878 208 878 254 878 280 878 346 878 410 878 456 878 500 878 532 878 557 878 565 878 633 878 651 878 724 878 747 878 826 878 878 878 891 878 902 878 957 878 976 878 989 878 1013 878 1025 878 1030 878 1128 878 1148 878 1207 878 1210 878 1220 878 1270 878 1301 878 1310 878 1350 878 1366 878 1368 878 1383 878 1439 878 1489 879 66 879 96 879 127 879 131 879 228 879 243 879 263 879 289 879 392 879 486 879 501 879 502 879 649 879 678 879 679 879 715 879 726 879 746 879 757 879 775 879 797 879 830 879 879 879 909 879 925 879 942 879 946 879 968 879 1016 879 1072 879 1111 879 1165 879 1213 879 1372 879 1414 880 48 880 94 880 163 880 179 880 246 880 278 880 310 880 320 880 339 880 509 880 512 880 521 880 523 880 545 880 616 880 635 880 653 880 664 880 688 880 712 880 740 880 762 880 772 880 845 880 855 880 880 880 963 880 1086 880 1094 880 1139 880 1158 880 1163 880 1181 880 1208 880 1239 880 1306 880 1335 880 1362 880 1387 880 1399 880 1438 881 17 881 96 881 129 881 131 881 145 881 162 881 174 881 255 881 261 881 313 881 322 881 394 881 486 881 531 881 561 881 577 881 634 881 786 881 789 881 881 881 887 881 942 881 969 881 991 881 1089 881 1092 881 1123 881 1125 881 1173 881 1209 881 1213 881 1244 881 1292 881 1372 882 14 882 47 882 52 882 63 882 92 882 125 882 160 882 165 882 218 882 230 882 234 882 240 882 272 882 291 882 371 882 373 882 377 882 404 882 434 882 441 882 483 882 528 882 569 882 603 882 606 882 609 882 612 882 624 882 630 882 640 882 648 882 690 882 694 882 743 882 809 882 882 882 883 882 888 882 910 882 939 882 1026 882 1075 882 1076 882 1097 882 1108 882 1159 882 1196 882 1236 882 1277 882 1461 882 1472 882 1476 882 1484 883 5 883 13 883 14 883 47 883 65 883 92 883 160 883 218 883 234 883 240 883 291 883 377 883 434 883 441 883 452 883 492 883 528 883 544 883 562 883 567 883 603 883 606 883 608 883 609 883 612 883 620 883 630 883 648 883 690 883 730 883 882 883 883 883 939 883 1018 883 1076 883 1159 883 1206 883 1225 883 1236 883 1265 883 1291 883 1313 883 1369 884 30 884 53 884 78 884 82 884 90 884 102 884 152 884 175 884 180 884 191 884 270 884 304 884 308 884 332 884 338 884 348 884 451 884 511 884 522 884 537 884 549 884 610 884 629 884 658 884 685 884 761 884 776 884 812 884 815 884 884 884 897 884 905 884 923 884 967 884 980 884 1003 884 1035 884 1057 884 1084 884 1124 884 1137 884 1141 884 1204 884 1271 884 1334 884 1390 884 1459 885 24 885 116 885 124 885 137 885 145 885 174 885 175 885 206 885 235 885 261 885 321 885 323 885 325 885 356 885 425 885 429 885 522 885 539 885 552 885 568 885 594 885 646 885 695 885 714 885 767 885 771 885 776 885 885 885 944 885 985 885 992 885 1064 885 1072 885 1178 885 1204 885 1244 885 1261 885 1333 885 1339 885 1353 885 1372 885 1401 885 1468 886 7 886 20 886 37 886 49 886 122 886 170 886 178 886 184 886 198 886 203 886 219 886 242 886 319 886 350 886 360 886 376 886 402 886 416 886 418 886 443 886 457 886 508 886 555 886 559 886 589 886 593 886 622 886 627 886 644 886 657 886 671 886 673 886 703 886 725 886 756 886 766 886 770 886 777 886 800 886 805 886 886 886 916 886 928 886 933 886 1015 886 1020 886 1029 886 1087 886 1100 886 1106 886 1112 886 1161 886 1166 886 1167 886 1171 886 1185 886 1200 886 1205 886 1211 886 1257 886 1268 886 1273 886 1311 886 1346 886 1388 886 1426 886 1431 886 1433 886 1479 886 1490 886 1492 887 17 887 27 887 66 887 96 887 131 887 162 887 174 887 175 887 216 887 261 887 263 887 322 887 328 887 354 887 356 887 394 887 444 887 464 887 479 887 486 887 561 887 576 887 634 887 652 887 678 887 711 887 714 887 767 887 785 887 786 887 792 887 830 887 881 887 887 887 909 887 942 887 969 887 1017 887 1047 887 1067 887 1089 887 1092 887 1125 887 1140 887 1165 887 1209 887 1213 887 1244 887 1283 887 1332 887 1414 887 1446 888 63 888 125 888 147 888 160 888 189 888 272 888 279 888 295 888 387 888 404 888 466 888 600 888 694 888 743 888 784 888 809 888 882 888 888 888 910 888 978 888 990 888 999 888 1069 888 1075 888 1082 888 1097 888 1108 888 1277 888 1281 888 1355 888 1407 888 1456 888 1476 888 1484 889 32 889 34 889 136 889 150 889 171 889 207 889 213 889 237 889 248 889 252 889 297 889 317 889 423 889 432 889 439 889 495 889 588 889 641 889 706 889 783 889 813 889 835 889 859 889 868 889 889 889 936 889 964 889 1073 889 1110 889 1130 889 1138 889 1247 889 1255 889 1274 889 1284 889 1322 889 1328 889 1376 889 1381 889 1422 890 27 890 28 890 99 890 134 890 138 890 228 890 337 890 411 890 487 890 505 890 510 890 585 890 686 890 717 890 741 890 775 890 789 890 797 890 890 890 918 890 968 890 988 890 1000 890 1060 890 1120 890 1226 890 1286 890 1414 890 1445 890 1446 891 39 891 43 891 60 891 77 891 112 891 154 891 176 891 208 891 254 891 280 891 287 891 385 891 410 891 456 891 500 891 541 891 633 891 724 891 747 891 779 891 861 891 878 891 891 891 902 891 927 891 957 891 976 891 989 891 1013 891 1025 891 1030 891 1128 891 1148 891 1150 891 1207 891 1210 891 1279 891 1295 891 1301 891 1310 891 1439 892 0 892 19 892 64 892 73 892 97 892 197 892 259 892 288 892 298 892 312 892 330 892 338 892 442 892 465 892 499 892 560 892 587 892 599 892 614 892 628 892 655 892 734 892 765 892 771 892 778 892 802 892 866 892 871 892 892 892 951 892 983 892 1085 892 1145 892 1147 892 1214 892 1222 892 1242 892 1305 892 1327 892 1330 892 1371 892 1382 892 1400 892 1412 892 1419 892 1442 892 1455 893 44 893 57 893 76 893 144 893 147 893 149 893 232 893 344 893 370 893 375 893 388 893 397 893 424 893 491 893 591 893 733 893 799 893 860 893 875 893 893 893 993 893 1027 893 1136 893 1179 893 1202 893 1235 893 1278 893 1358 893 1393 893 1456 894 25 894 70 894 163 894 179 894 181 894 246 894 265 894 273 894 310 894 415 894 523 894 692 894 718 894 894 894 932 894 945 894 963 894 974 894 982 894 1004 894 1022 894 1032 894 1055 894 1094 894 1158 894 1239 894 1335 894 1363 894 1385 894 1447 894 1488 895 0 895 26 895 29 895 185 895 264 895 267 895 288 895 359 895 380 895 398 895 436 895 482 895 494 895 597 895 598 895 645 895 650 895 676 895 683 895 699 895 715 895 755 895 872 895 895 895 931 895 1009 895 1079 895 1218 895 1314 895 1321 895 1398 895 1417 895 1485 896 89 896 124 896 127 896 233 896 267 896 268 896 283 896 380 896 382 896 392 896 425 896 470 896 494 896 501 896 505 896 540 896 575 896 625 896 674 896 678 896 686 896 708 896 810 896 830 896 831 896 865 896 896 896 921 896 965 896 986 896 995 896 1007 896 1009 896 1059 896 1064 896 1160 896 1304 896 1314 896 1316 896 1321 896 1341 896 1349 896 1425 896 1446 896 1449 896 1468 897 30 897 116 897 174 897 175 897 180 897 222 897 312 897 325 897 359 897 431 897 522 897 537 897 646 897 702 897 771 897 776 897 884 897 897 897 980 897 1046 897 1057 897 1113 897 1124 897 1135 897 1141 897 1204 897 1212 897 1330 897 1413 897 1486 898 10 898 23 898 103 898 184 898 198 898 210 898 357 898 376 898 457 898 503 898 517 898 542 898 551 898 559 898 578 898 582 898 601 898 627 898 643 898 657 898 666 898 693 898 704 898 725 898 750 898 756 898 766 898 811 898 898 898 915 898 1008 898 1095 898 1166 898 1168 898 1185 898 1240 898 1246 898 1297 898 1300 898 1323 898 1338 898 1429 898 1457 898 1492 898 1495 899 62 899 104 899 105 899 109 899 166 899 168 899 173 899 254 899 258 899 302 899 309 899 334 899 346 899 409 899 426 899 472 899 477 899 489 899 532 899 572 899 651 899 710 899 723 899 826 899 899 899 917 899 954 899 1080 899 1104 899 1114 899 1143 899 1149 899 1207 899 1220 899 1233 899 1270 899 1310 899 1350 899 1368 899 1383 899 1405 899 1469 900 7 900 20 900 22 900 31 900 107 900 123 900 143 900 148 900 156 900 167 900 178 900 219 900 242 900 266 900 336 900 350 900 378 900 418 900 449 900 507 900 530 900 543 900 558 900 570 900 583 900 593 900 607 900 617 900 621 900 644 900 777 900 791 900 854 900 862 900 873 900 900 900 903 900 928 900 935 900 937 900 958 900 962 900 1015 900 1071 900 1106 900 1154 900 1156 900 1161 900 1162 900 1171 900 1176 900 1184 900 1205 900 1211 900 1224 900 1268 900 1289 900 1294 900 1311 900 1326 900 1431 900 1444 900 1464 901 53 901 78 901 82 901 86 901 102 901 193 901 200 901 211 901 257 901 277 901 308 901 332 901 405 901 428 901 451 901 533 901 563 901 579 901 610 901 626 901 658 901 702 901 752 901 846 901 863 901 901 901 959 901 1003 901 1024 901 1035 901 1066 901 1084 901 1131 901 1135 901 1183 901 1309 901 1327 901 1340 901 1459 901 1475 901 1481 901 1494 902 43 902 60 902 77 902 118 902 154 902 176 902 208 902 280 902 287 902 369 902 385 902 456 902 500 902 532 902 541 902 557 902 565 902 633 902 651 902 724 902 747 902 779 902 861 902 878 902 891 902 902 902 927 902 957 902 976 902 1013 902 1025 902 1030 902 1148 902 1150 902 1182 902 1210 902 1243 902 1279 902 1295 902 1310 902 1366 902 1439 902 1489 903 7 903 20 903 22 903 87 903 148 903 156 903 219 903 242 903 266 903 292 903 378 903 396 903 446 903 449 903 508 903 530 903 543 903 583 903 604 903 613 903 621 903 636 903 639 903 644 903 669 903 691 903 727 903 739 903 791 903 854 903 873 903 900 903 903 903 920 903 928 903 935 903 948 903 987 903 994 903 1005 903 1038 903 1071 903 1106 903 1151 903 1176 903 1211 903 1268 903 1273 903 1289 903 1324 903 1326 903 1431 903 1444 903 1450 903 1458 903 1464 904 33 904 61 904 110 904 141 904 155 904 169 904 195 904 299 904 314 904 341 904 342 904 364 904 379 904 447 904 458 904 493 904 504 904 514 904 571 904 586 904 704 904 749 904 773 904 811 904 843 904 904 904 913 904 915 904 941 904 943 904 956 904 1109 904 1189 904 1269 904 1312 904 1338 904 1345 904 1374 904 1420 904 1421 904 1437 905 9 905 30 905 54 905 73 905 90 905 102 905 121 905 130 905 152 905 191 905 205 905 259 905 270 905 286 905 338 905 485 905 511 905 536 905 549 905 618 905 655 905 698 905 701 905 752 905 761 905 778 905 812 905 815 905 823 905 827 905 884 905 905 905 967 905 1044 905 1183 905 1221 905 1258 905 1343 905 1382 905 1390 905 1413 905 1452 905 1455 906 36 906 56 906 72 906 101 906 164 906 187 906 217 906 343 906 389 906 391 906 408 906 497 906 520 906 524 906 547 906 584 906 592 906 638 906 667 906 680 906 784 906 844 906 867 906 906 906 908 906 972 906 1034 906 1068 906 1078 906 1098 906 1179 906 1180 906 1198 906 1230 906 1299 906 1361 906 1373 906 1407 906 1441 906 1474 906 1496 907 18 907 146 907 688 907 700 907 851 907 852 907 876 907 907 907 998 907 1004 907 1123 907 1177 907 1193 907 1306 907 1397 907 1453 907 1473 908 55 908 83 908 101 908 164 908 187 908 217 908 224 908 343 908 408 908 497 908 524 908 547 908 562 908 567 908 584 908 592 908 608 908 620 908 638 908 667 908 680 908 822 908 867 908 906 908 908 908 972 908 1034 908 1098 908 1198 908 1217 908 1225 908 1250 908 1299 908 1348 908 1356 908 1361 908 1474 908 1496 909 27 909 96 909 138 909 162 909 228 909 243 909 250 909 289 909 356 909 479 909 552 909 561 909 568 909 678 909 679 909 714 909 775 909 789 909 830 909 834 909 879 909 887 909 909 909 925 909 942 909 946 909 988 909 1016 909 1072 909 1111 909 1120 909 1283 909 1286 909 1410 909 1414 909 1446 910 14 910 79 910 92 910 125 910 160 910 189 910 223 910 230 910 253 910 272 910 279 910 295 910 371 910 373 910 387 910 404 910 483 910 484 910 491 910 556 910 600 910 606 910 611 910 624 910 640 910 690 910 694 910 784 910 807 910 809 910 875 910 882 910 888 910 910 910 911 910 999 910 1014 910 1069 910 1075 910 1078 910 1082 910 1099 910 1180 910 1196 910 1217 910 1230 910 1236 910 1277 910 1355 910 1407 910 1441 910 1474 910 1476 910 1484 911 72 911 79 911 92 911 135 911 144 911 189 911 223 911 272 911 295 911 373 911 387 911 389 911 391 911 401 911 455 911 478 911 483 911 484 911 491 911 520 911 556 911 591 911 600 911 611 911 638 911 680 911 684 911 694 911 784 911 807 911 839 911 844 911 910 911 911 911 940 911 978 911 990 911 999 911 1014 911 1018 911 1068 911 1069 911 1082 911 1099 911 1142 911 1180 911 1196 911 1206 911 1217 911 1230 911 1277 911 1281 911 1290 911 1355 911 1370 911 1393 911 1407 911 1441 911 1474 911 1484 912 11 912 21 912 41 912 80 912 94 912 151 912 179 912 225 912 245 912 276 912 278 912 339 912 347 912 358 912 412 912 419 912 437 912 459 912 496 912 509 912 513 912 535 912 545 912 664 912 665 912 699 912 713 912 754 912 768 912 787 912 790 912 821 912 828 912 834 912 912 912 922 912 949 912 952 912 996 912 1022 912 1033 912 1045 912 1048 912 1063 912 1070 912 1081 912 1170 912 1215 912 1241 912 1251 912 1288 912 1335 912 1445 912 1465 913 10 913 33 913 50 913 61 913 103 913 110 913 141 913 195 913 299 913 341 913 342 913 364 913 379 913 447 913 458 913 493 913 504 913 514 913 542 913 578 913 586 913 643 913 687 913 704 913 749 913 811 913 843 913 904 913 913 913 915 913 943 913 956 913 1095 913 1109 913 1168 913 1189 913 1269 913 1297 913 1312 913 1338 913 1374 913 1420 913 1421 913 1437 913 1495 914 142 914 157 914 316 914 819 914 833 914 877 914 914 914 1043 914 1121 914 1430 915 10 915 61 915 103 915 110 915 299 915 341 915 342 915 364 915 379 915 447 915 493 915 504 915 542 915 578 915 601 915 643 915 666 915 687 915 693 915 704 915 749 915 811 915 898 915 904 915 913 915 915 915 943 915 1008 915 1095 915 1109 915 1168 915 1189 915 1240 915 1269 915 1275 915 1297 915 1312 915 1352 915 1374 915 1420 915 1421 915 1437 915 1457 915 1495 916 7 916 20 916 31 916 37 916 49 916 50 916 68 916 75 916 123 916 128 916 141 916 170 916 198 916 203 916 210 916 290 916 294 916 300 916 314 916 333 916 350 916 357 916 360 916 368 916 402 916 433 916 457 916 538 916 551 916 555 916 559 916 571 916 593 916 622 916 627 916 657 916 671 916 673 916 703 916 756 916 766 916 836 916 886 916 916 916 930 916 933 916 1020 916 1029 916 1088 916 1100 916 1106 916 1107 916 1112 916 1166 916 1171 916 1188 916 1203 916 1211 916 1257 916 1300 916 1364 916 1402 916 1433 916 1457 916 1460 916 1462 916 1490 917 62 917 88 917 104 917 105 917 109 917 166 917 173 917 254 917 258 917 309 917 334 917 346 917 409 917 426 917 477 917 489 917 572 917 659 917 710 917 723 917 728 917 737 917 826 917 899 917 917 917 1080 917 1093 917 1104 917 1114 917 1115 917 1134 917 1143 917 1149 917 1207 917 1220 917 1233 917 1270 917 1293 917 1350 917 1383 917 1469 918 35 918 134 918 140 918 228 918 243 918 321 918 337 918 393 918 406 918 411 918 417 918 487 918 501 918 513 918 521 918 577 918 585 918 596 918 679 918 717 918 741 918 754 918 762 918 772 918 775 918 781 918 789 918 797 918 834 918 890 918 918 918 946 918 968 918 991 918 1000 918 1042 918 1049 918 1077 918 1120 918 1139 918 1226 918 1241 918 1286 918 1445 918 1453 918 1470 919 59 919 190 919 396 919 414 919 435 919 669 919 691 919 727 919 774 919 840 919 841 919 919 919 953 919 987 919 1038 919 1151 919 1267 919 1320 919 1379 919 1450 919 1454 919 1477 919 1491 920 22 920 156 920 159 920 196 920 266 920 345 920 383 920 396 920 400 920 448 920 449 920 507 920 530 920 543 920 570 920 604 920 605 920 621 920 669 920 691 920 707 920 727 920 739 920 764 920 847 920 854 920 873 920 903 920 920 920 947 920 948 920 960 920 994 920 1005 920 1037 920 1038 920 1090 920 1126 920 1172 920 1176 920 1267 920 1287 920 1324 920 1325 920 1386 920 1434 920 1436 920 1444 920 1493 921 27 921 28 921 45 921 51 921 89 921 124 921 127 921 263 921 267 921 268 921 283 921 355 921 380 921 392 921 459 921 470 921 482 921 486 921 501 921 505 921 575 921 576 921 594 921 625 921 678 921 686 921 708 921 726 921 753 921 775 921 786 921 789 921 810 921 830 921 865 921 896 921 921 921 929 921 931 921 950 921 965 921 968 921 986 921 995 921 1007 921 1009 921 1111 921 1160 921 1304 921 1314 921 1316 921 1321 921 1349 921 1378 921 1410 921 1414 921 1417 921 1425 921 1446 921 1449 921 1468 922 21 922 100 922 225 922 249 922 260 922 329 922 337 922 393 922 417 922 445 922 509 922 550 922 596 922 602 922 616 922 653 922 656 922 754 922 762 922 806 922 820 922 912 922 922 922 1022 922 1042 922 1045 922 1070 922 1077 922 1139 922 1190 922 1241 922 1288 922 1315 922 1317 922 1387 922 1408 922 1428 922 1438 922 1445 922 1470 923 30 923 38 923 53 923 78 923 102 923 191 923 212 923 270 923 286 923 308 923 428 923 431 923 451 923 460 923 464 923 506 923 511 923 533 923 534 923 537 923 549 923 580 923 610 923 631 923 637 923 702 923 720 923 752 923 761 923 776 923 812 923 829 923 863 923 884 923 923 923 1003 923 1024 923 1046 923 1057 923 1065 923 1084 923 1131 923 1135 923 1219 923 1238 923 1249 923 1336 923 1351 923 1390 923 1418 923 1459 923 1481 924 166 924 306 924 334 924 386 924 420 924 461 924 471 924 472 924 474 924 553 924 554 924 566 924 659 924 668 924 696 924 723 924 728 924 748 924 804 924 818 924 924 924 1096 924 1104 924 1143 924 1192 924 1254 924 1259 924 1272 924 1285 924 1303 924 1391 924 1427 924 1469 925 127 925 228 925 243 925 251 925 289 925 318 925 501 925 502 925 535 925 568 925 678 925 679 925 753 925 775 925 834 925 879 925 909 925 925 925 979 925 988 925 1009 925 1016 925 1072 925 1111 925 1286 925 1392 925 1410 925 1449 925 1471 926 32 926 40 926 115 926 139 926 150 926 171 926 177 926 213 926 237 926 307 926 317 926 366 926 453 926 495 926 833 926 835 926 848 926 853 926 859 926 869 926 926 926 936 926 1041 926 1061 926 1103 926 1138 926 1237 926 1245 926 1247 926 1262 926 1276 926 1296 926 1322 926 1347 926 1376 926 1381 926 1406 926 1482 927 43 927 46 927 60 927 104 927 118 927 154 927 176 927 208 927 280 927 287 927 309 927 369 927 385 927 410 927 456 927 500 927 532 927 541 927 557 927 565 927 633 927 651 927 724 927 747 927 779 927 826 927 861 927 891 927 902 927 927 927 957 927 976 927 989 927 1013 927 1025 927 1030 927 1150 927 1182 927 1210 927 1243 927 1264 927 1279 927 1295 927 1310 927 1366 927 1380 927 1439 927 1489 928 7 928 20 928 31 928 37 928 87 928 123 928 167 928 170 928 178 928 204 928 219 928 242 928 326 928 350 928 360 928 416 928 418 928 443 928 446 928 508 928 583 928 593 928 622 928 644 928 671 928 703 928 756 928 777 928 886 928 900 928 903 928 928 928 935 928 958 928 987 928 1015 928 1029 928 1071 928 1087 928 1106 928 1154 928 1161 928 1166 928 1167 928 1171 928 1200 928 1205 928 1211 928 1257 928 1268 928 1273 928 1289 928 1294 928 1311 928 1326 928 1431 928 1458 928 1490 929 35 929 41 929 81 929 94 929 99 929 199 929 245 929 276 929 284 929 321 929 339 929 374 929 380 929 382 929 392 929 406 929 459 929 486 929 487 929 501 929 510 929 513 929 540 929 577 929 594 929 695 929 713 929 726 929 781 929 782 929 790 929 830 929 921 929 929 929 946 929 949 929 965 929 1045 929 1048 929 1081 929 1094 929 1152 929 1158 929 1164 929 1190 929 1201 929 1215 929 1223 929 1226 929 1251 929 1304 929 1408 929 1410 929 1417 929 1425 929 1445 929 1471 930 50 930 68 930 75 930 141 930 195 930 203 930 204 930 210 930 294 930 299 930 300 930 314 930 357 930 368 930 433 930 514 930 538 930 551 930 571 930 627 930 657 930 697 930 836 930 916 930 930 930 1029 930 1088 930 1100 930 1107 930 1169 930 1203 930 1275 930 1300 930 1338 930 1352 930 1364 930 1374 930 1379 930 1460 930 1490 930 1495 931 28 931 29 931 45 931 51 931 89 931 138 931 267 931 355 931 380 931 459 931 470 931 482 931 486 931 552 931 575 931 625 931 676 931 705 931 708 931 715 931 726 931 753 931 755 931 832 931 895 931 921 931 931 931 965 931 986 931 995 931 1007 931 1086 931 1111 931 1160 931 1261 931 1304 931 1316 931 1349 931 1403 931 1417 931 1485 931 1494 932 163 932 179 932 181 932 226 932 246 932 249 932 265 932 310 932 320 932 415 932 523 932 596 932 692 932 718 932 740 932 768 932 793 932 850 932 855 932 894 932 932 932 945 932 952 932 963 932 974 932 1004 932 1022 932 1032 932 1045 932 1094 932 1158 932 1239 932 1335 932 1453 933 23 933 37 933 49 933 75 933 91 933 128 933 170 933 184 933 198 933 219 933 290 933 319 933 326 933 350 933 360 933 376 933 402 933 416 933 418 933 422 933 457 933 503 933 555 933 559 933 574 933 593 933 622 933 627 933 639 933 673 933 703 933 725 933 756 933 766 933 770 933 800 933 886 933 916 933 933 933 955 933 1015 933 1020 933 1087 933 1100 933 1101 933 1106 933 1112 933 1166 933 1167 933 1200 933 1205 933 1211 933 1257 933 1268 933 1311 933 1346 933 1388 933 1426 933 1429 933 1431 933 1433 933 1457 933 1479 933 1492 934 26 934 82 934 90 934 191 934 222 934 233 934 312 934 327 934 332 934 425 934 436 934 465 934 475 934 563 934 623 934 658 934 701 934 734 934 758 934 771 934 866 934 934 934 959 934 1024 934 1035 934 1054 934 1102 934 1113 934 1118 934 1124 934 1212 934 1266 934 1318 934 1327 934 1330 934 1442 934 1485 934 1486 935 22 935 107 935 123 935 143 935 148 935 167 935 178 935 219 935 242 935 266 935 326 935 350 935 360 935 378 935 416 935 418 935 446 935 449 935 507 935 583 935 607 935 613 935 617 935 621 935 622 935 636 935 644 935 732 935 777 935 791 935 854 935 873 935 900 935 903 935 928 935 935 935 937 935 948 935 958 935 962 935 997 935 1010 935 1015 935 1071 935 1106 935 1154 935 1162 935 1176 935 1211 935 1257 935 1289 935 1294 935 1311 935 1326 935 1426 935 1431 935 1444 935 1464 936 32 936 34 936 40 936 136 936 150 936 171 936 207 936 213 936 237 936 248 936 252 936 274 936 297 936 317 936 423 936 432 936 439 936 453 936 495 936 588 936 641 936 706 936 738 936 744 936 813 936 835 936 848 936 853 936 859 936 868 936 869 936 889 936 926 936 936 936 1041 936 1073 936 1103 936 1110 936 1130 936 1138 936 1237 936 1247 936 1255 936 1262 936 1284 936 1296 936 1322 936 1347 936 1376 936 1381 937 107 937 143 937 266 937 378 937 446 937 449 937 507 937 508 937 558 937 570 937 607 937 613 937 621 937 791 937 854 937 862 937 900 937 935 937 937 937 962 937 1010 937 1071 937 1127 937 1146 937 1151 937 1156 937 1162 937 1176 937 1294 937 1444 937 1450 938 21 938 251 938 412 938 425 938 502 938 535 938 866 938 938 938 1054 938 1165 938 1401 938 1411 939 5 939 12 939 13 939 14 939 52 939 63 939 65 939 85 939 160 939 165 939 218 939 234 939 240 939 291 939 377 939 434 939 492 939 528 939 603 939 609 939 630 939 642 939 648 939 690 939 742 939 759 939 882 939 883 939 939 939 1026 939 1028 939 1129 939 1159 939 1265 939 1461 940 56 940 72 940 76 940 135 940 144 940 164 940 217 940 223 940 232 940 279 940 295 940 305 940 371 940 387 940 389 940 391 940 401 940 408 940 424 940 455 940 478 940 483 940 520 940 526 940 611 940 638 940 680 940 784 940 814 940 822 940 839 940 844 940 911 940 940 940 978 940 990 940 1014 940 1068 940 1078 940 1097 940 1099 940 1142 940 1179 940 1180 940 1216 940 1229 940 1281 940 1290 940 1299 940 1313 940 1356 940 1370 940 1373 940 1375 940 1407 940 1441 940 1498 941 33 941 61 941 110 941 155 941 169 941 342 941 364 941 447 941 458 941 493 941 586 941 749 941 773 941 843 941 904 941 941 941 943 941 956 941 1269 941 1345 941 1421 941 1437 942 27 942 66 942 96 942 131 942 162 942 174 942 261 942 263 942 322 942 354 942 356 942 394 942 479 942 486 942 501 942 552 942 561 942 568 942 576 942 649 942 652 942 678 942 711 942 714 942 726 942 746 942 786 942 789 942 792 942 830 942 879 942 881 942 887 942 909 942 942 942 946 942 1017 942 1047 942 1072 942 1089 942 1092 942 1125 942 1165 942 1173 942 1213 942 1244 942 1283 942 1372 942 1414 943 33 943 61 943 110 943 169 943 341 943 342 943 364 943 379 943 447 943 458 943 493 943 504 943 542 943 586 943 643 943 687 943 693 943 749 943 773 943 811 943 843 943 904 943 913 943 915 943 941 943 943 943 956 943 1095 943 1109 943 1168 943 1269 943 1275 943 1312 943 1345 943 1374 943 1421 943 1437 944 24 944 66 944 116 944 131 944 137 944 145 944 174 944 206 944 235 944 261 944 322 944 323 944 325 944 356 944 429 944 431 944 522 944 539 944 576 944 646 944 705 944 714 944 767 944 771 944 885 944 944 944 985 944 992 944 1064 944 1072 944 1173 944 1178 944 1209 944 1244 944 1339 944 1353 944 1372 944 1401 944 1403 945 1 945 100 945 140 945 246 945 265 945 310 945 320 945 393 945 406 945 417 945 421 945 596 945 616 945 672 945 688 945 718 945 740 945 754 945 762 945 772 945 806 945 850 945 855 945 856 945 876 945 894 945 932 945 945 945 963 945 974 945 998 945 1049 945 1074 945 1094 945 1139 945 1158 945 1177 945 1342 945 1387 945 1397 945 1438 945 1453 945 1473 946 94 946 127 946 131 946 134 946 138 946 162 946 228 946 243 946 289 946 337 946 392 946 393 946 459 946 479 946 486 946 501 946 513 946 535 946 576 946 649 946 679 946 713 946 726 946 741 946 746 946 757 946 772 946 775 946 786 946 789 946 790 946 797 946 830 946 834 946 879 946 909 946 918 946 929 946 942 946 946 946 968 946 1000 946 1016 946 1048 946 1072 946 1173 946 1213 946 1241 946 1286 946 1372 946 1392 946 1410 946 1445 947 159 947 196 947 266 947 345 947 383 947 400 947 448 947 543 947 605 947 615 947 707 947 739 947 862 947 920 947 947 947 960 947 1037 947 1090 947 1126 947 1127 947 1172 947 1174 947 1267 947 1325 947 1386 947 1434 947 1436 947 1493 948 7 948 20 948 22 948 87 948 148 948 156 948 204 948 242 948 266 948 292 948 336 948 378 948 396 948 403 948 446 948 449 948 530 948 543 948 583 948 604 948 613 948 621 948 669 948 763 948 764 948 791 948 873 948 903 948 920 948 935 948 948 948 960 948 987 948 994 948 1005 948 1037 948 1038 948 1176 948 1224 948 1287 948 1289 948 1324 948 1326 948 1386 948 1404 948 1436 948 1444 948 1450 948 1458 948 1464 948 1493 949 21 949 41 949 80 949 81 949 99 949 106 949 151 949 179 949 186 949 188 949 199 949 245 949 276 949 278 949 281 949 318 949 339 949 347 949 412 949 419 949 430 949 437 949 487 949 496 949 509 949 510 949 529 949 545 949 550 949 602 949 661 949 665 949 682 949 683 949 686 949 713 949 729 949 760 949 768 949 787 949 790 949 820 949 912 949 929 949 949 949 950 949 952 949 1011 949 1019 949 1022 949 1032 949 1033 949 1045 949 1060 949 1063 949 1086 949 1152 949 1170 949 1190 949 1208 949 1223 949 1251 949 1288 949 1304 949 1408 949 1417 949 1465 949 1487 950 45 950 89 950 106 950 151 950 186 950 245 950 268 950 278 950 318 950 337 950 339 950 347 950 380 950 437 950 470 950 494 950 496 950 505 950 510 950 535 950 540 950 545 950 665 950 676 950 682 950 683 950 686 950 699 950 768 950 787 950 921 950 949 950 950 950 952 950 965 950 968 950 986 950 1033 950 1048 950 1060 950 1160 950 1190 950 1251 950 1304 950 1349 950 1408 950 1417 950 1425 950 1445 950 1471 951 3 951 8 951 19 951 64 951 69 951 97 951 119 951 183 951 197 951 296 951 330 951 407 951 427 951 442 951 454 951 499 951 599 951 614 951 628 951 660 951 709 951 765 951 816 951 866 951 892 951 951 951 1132 951 1133 951 1186 951 1222 951 1227 951 1242 951 1260 951 1419 952 21 952 80 952 94 952 151 952 179 952 181 952 199 952 225 952 226 952 245 952 246 952 249 952 251 952 276 952 278 952 310 952 339 952 412 952 419 952 430 952 437 952 445 952 496 952 509 952 535 952 545 952 602 952 664 952 665 952 713 952 768 952 787 952 912 952 932 952 949 952 950 952 952 952 963 952 966 952 974 952 1022 952 1032 952 1033 952 1045 952 1063 952 1152 952 1158 952 1170 952 1181 952 1190 952 1215 952 1223 952 1251 952 1288 953 59 953 87 953 190 953 204 953 414 953 836 953 840 953 841 953 919 953 953 953 987 953 1029 953 1038 953 1151 953 1167 953 1169 953 1273 953 1320 953 1379 953 1454 953 1458 953 1491 954 39 954 104 954 109 954 112 954 168 954 215 954 258 954 280 954 302 954 309 954 346 954 409 954 410 954 426 954 489 954 861 954 899 954 954 954 989 954 1025 954 1114 954 1128 954 1134 954 1148 954 1207 954 1233 954 1301 954 1319 954 1368 954 1380 954 1405 955 49 955 122 955 128 955 290 955 360 955 443 955 468 955 517 955 555 955 574 955 582 955 639 955 673 955 756 955 770 955 800 955 805 955 933 955 955 955 1020 955 1101 955 1311 955 1364 955 1388 955 1433 956 33 956 61 956 110 956 155 956 169 956 299 956 341 956 342 956 364 956 379 956 447 956 458 956 493 956 504 956 586 956 687 956 749 956 773 956 843 956 904 956 913 956 941 956 943 956 956 956 1109 956 1269 956 1312 956 1345 956 1421 956 1437 957 43 957 46 957 60 957 77 957 104 957 118 957 154 957 176 957 208 957 287 957 309 957 369 957 385 957 410 957 456 957 500 957 532 957 541 957 557 957 565 957 633 957 651 957 724 957 747 957 779 957 826 957 861 957 878 957 891 957 902 957 927 957 957 957 976 957 1013 957 1025 957 1030 957 1150 957 1182 957 1210 957 1243 957 1264 957 1270 957 1279 957 1295 957 1310 957 1366 957 1380 957 1439 957 1489 958 91 958 123 958 143 958 167 958 178 958 219 958 326 958 350 958 360 958 378 958 416 958 418 958 422 958 446 958 583 958 617 958 621 958 622 958 636 958 644 958 732 958 777 958 900 958 928 958 935 958 958 958 962 958 997 958 1010 958 1015 958 1146 958 1154 958 1167 958 1200 958 1205 958 1211 958 1257 958 1268 958 1289 958 1294 958 1311 958 1326 958 1426 958 1431 959 26 959 58 959 78 959 82 959 86 959 102 959 191 959 193 959 200 959 211 959 312 959 332 959 405 959 451 959 534 959 536 959 563 959 579 959 623 959 626 959 658 959 685 959 701 959 752 959 778 959 863 959 901 959 934 959 959 959 1024 959 1035 959 1054 959 1066 959 1102 959 1113 959 1124 959 1131 959 1135 959 1212 959 1221 959 1309 959 1327 959 1330 959 1340 959 1341 959 1413 959 1467 959 1481 959 1486 960 156 960 159 960 196 960 345 960 383 960 390 960 396 960 400 960 448 960 449 960 530 960 543 960 548 960 605 960 641 960 707 960 763 960 764 960 862 960 873 960 920 960 947 960 948 960 960 960 994 960 1005 960 1037 960 1090 960 1126 960 1127 960 1172 960 1184 960 1224 960 1267 960 1287 960 1324 960 1325 960 1386 960 1404 960 1434 960 1436 960 1493 961 6 961 35 961 42 961 48 961 94 961 124 961 162 961 172 961 263 961 303 961 313 961 363 961 374 961 382 961 392 961 406 961 413 961 498 961 512 961 540 961 575 961 576 961 577 961 635 961 649 961 695 961 718 961 722 961 746 961 757 961 772 961 781 961 782 961 786 961 810 961 852 961 961 961 1049 961 1052 961 1163 961 1181 961 1201 961 1208 961 1223 961 1333 961 1362 961 1363 961 1399 962 91 962 143 962 178 962 326 962 378 962 422 962 446 962 449 962 507 962 604 962 613 962 617 962 621 962 636 962 644 962 669 962 732 962 791 962 854 962 900 962 935 962 937 962 958 962 962 962 997 962 1010 962 1015 962 1146 962 1151 962 1154 962 1176 962 1289 962 1294 962 1326 962 1426 963 35 963 163 963 179 963 181 963 226 963 245 963 246 963 265 963 284 963 310 963 320 963 406 963 415 963 523 963 596 963 653 963 688 963 740 963 762 963 768 963 772 963 781 963 790 963 855 963 880 963 894 963 932 963 945 963 952 963 963 963 974 963 1004 963 1022 963 1032 963 1045 963 1094 963 1139 963 1158 963 1181 963 1223 963 1239 963 1335 963 1453 964 16 964 71 964 136 964 150 964 159 964 177 964 207 964 252 964 274 964 297 964 317 964 390 964 423 964 432 964 469 964 548 964 588 964 641 964 706 964 707 964 738 964 764 964 889 964 964 964 977 964 1005 964 1053 964 1073 964 1130 964 1252 964 1255 964 1274 964 1287 964 1322 964 1328 964 1416 964 1422 964 1436 964 1480 964 1493 965 28 965 41 965 81 965 89 965 138 965 151 965 199 965 267 965 318 965 380 965 459 965 470 965 494 965 505 965 510 965 585 965 646 965 665 965 676 965 683 965 686 965 708 965 755 965 865 965 896 965 921 965 929 965 931 965 950 965 965 965 979 965 986 965 995 965 1009 965 1019 965 1060 965 1152 965 1160 965 1215 965 1286 965 1304 965 1314 965 1321 965 1392 965 1408 965 1417 965 1425 965 1445 965 1446 965 1449 965 1471 966 21 966 80 966 114 966 225 966 226 966 412 966 467 966 509 966 653 966 656 966 664 966 675 966 712 966 825 966 952 966 966 966 1012 966 1170 966 1175 966 1288 966 1308 966 1427 967 30 967 73 967 90 967 102 967 130 967 152 967 270 967 286 967 338 967 537 967 623 967 752 967 761 967 778 967 812 967 815 967 884 967 905 967 967 967 980 967 1003 967 1057 967 1124 967 1141 967 1204 967 1271 967 1334 967 1390 967 1413 967 1415 968 6 968 45 968 99 968 127 968 134 968 228 968 243 968 268 968 329 968 337 968 392 968 393 968 459 968 487 968 501 968 505 968 513 968 585 968 596 968 679 968 686 968 717 968 775 968 789 968 797 968 834 968 879 968 890 968 918 968 921 968 946 968 950 968 968 968 1000 968 1048 968 1160 968 1241 968 1286 968 1349 968 1408 968 1414 968 1428 968 1445 968 1446 969 17 969 42 969 129 969 133 969 172 969 174 969 180 969 255 969 261 969 263 969 268 969 283 969 304 969 322 969 328 969 340 969 352 969 354 969 394 969 395 969 399 969 464 969 575 969 576 969 590 969 625 969 634 969 652 969 681 969 695 969 711 969 745 969 767 969 769 969 786 969 792 969 881 969 887 969 969 969 980 969 992 969 1039 969 1067 969 1125 969 1140 969 1155 969 1173 969 1209 969 1244 969 1332 969 1333 969 1499 970 2 970 25 970 93 970 95 970 97 970 111 970 126 970 153 970 194 970 197 970 247 970 282 970 296 970 362 970 384 970 450 970 454 970 463 970 471 970 499 970 516 970 554 970 654 970 662 970 670 970 780 970 796 970 970 970 982 970 1001 970 1012 970 1036 970 1050 970 1083 970 1105 970 1122 970 1186 970 1194 970 1256 970 1329 970 1354 970 1384 970 1385 970 1394 970 1396 970 1447 970 1478 971 74 971 95 971 113 971 117 971 120 971 132 971 201 971 239 971 241 971 271 971 275 971 293 971 311 971 315 971 361 971 372 971 488 971 515 971 554 971 564 971 647 971 677 971 719 971 858 971 971 971 1006 971 1023 971 1056 971 1058 971 1157 971 1192 971 1232 971 1248 971 1253 971 1282 971 1307 971 1377 971 1394 971 1424 971 1435 972 56 972 72 972 83 972 101 972 164 972 187 972 217 972 223 972 224 972 279 972 343 972 371 972 389 972 391 972 408 972 452 972 497 972 520 972 524 972 544 972 547 972 567 972 584 972 592 972 638 972 640 972 844 972 867 972 875 972 906 972 908 972 972 972 1034 972 1068 972 1078 972 1098 972 1099 972 1142 972 1179 972 1180 972 1198 972 1216 972 1225 972 1250 972 1299 972 1313 972 1348 972 1356 972 1361 972 1373 972 1407 972 1441 972 1474 972 1496 973 0 973 29 973 194 973 236 973 372 973 459 973 595 973 712 973 715 973 845 973 872 973 973 973 981 973 984 973 996 973 1398 974 100 974 140 974 163 974 179 974 181 974 226 974 245 974 246 974 265 974 284 974 310 974 313 974 320 974 406 974 415 974 523 974 596 974 653 974 672 974 688 974 740 974 762 974 768 974 772 974 806 974 850 974 855 974 856 974 894 974 932 974 945 974 952 974 963 974 974 974 998 974 1004 974 1022 974 1032 974 1045 974 1094 974 1139 974 1158 974 1177 974 1181 974 1335 974 1387 974 1438 974 1453 974 1473 975 74 975 93 975 95 975 126 975 132 975 194 975 201 975 227 975 231 975 239 975 247 975 271 975 275 975 282 975 296 975 306 975 311 975 315 975 463 975 481 975 515 975 516 975 564 975 670 975 719 975 796 975 801 975 838 975 858 975 975 975 1001 975 1002 975 1023 975 1036 975 1058 975 1116 975 1119 975 1122 975 1157 975 1194 975 1232 975 1248 975 1280 975 1282 975 1354 975 1394 975 1435 975 1478 976 39 976 43 976 60 976 77 976 112 976 154 976 176 976 208 976 254 976 280 976 287 976 302 976 385 976 410 976 456 976 500 976 541 976 633 976 724 976 747 976 779 976 826 976 861 976 878 976 891 976 902 976 927 976 957 976 976 976 989 976 1013 976 1025 976 1030 976 1128 976 1148 976 1150 976 1207 976 1210 976 1279 976 1295 976 1301 976 1310 976 1439 977 4 977 71 977 248 977 297 977 331 977 390 977 423 977 432 977 469 977 519 977 548 977 632 977 641 977 706 977 738 977 964 977 977 977 1053 977 1073 977 1130 977 1188 977 1255 977 1274 977 1328 977 1357 977 1367 977 1416 977 1422 977 1423 977 1451 977 1480 978 72 978 76 978 135 978 144 978 189 978 223 978 232 978 253 978 279 978 295 978 305 978 371 978 373 978 389 978 401 978 408 978 455 978 478 978 483 978 520 978 526 978 556 978 591 978 600 978 611 978 680 978 684 978 784 978 814 978 822 978 839 978 860 978 888 978 911 978 940 978 978 978 990 978 999 978 1014 978 1068 978 1078 978 1097 978 1099 978 1142 978 1180 978 1206 978 1216 978 1229 978 1230 978 1235 978 1277 978 1281 978 1290 978 1355 978 1370 978 1375 978 1407 978 1441 978 1498 979 138 979 228 979 251 979 267 979 318 979 329 979 470 979 502 979 513 979 535 979 568 979 676 979 753 979 817 979 834 979 925 979 965 979 979 979 986 979 988 979 995 979 1009 979 1016 979 1111 979 1286 979 1304 979 1321 979 1392 979 1449 979 1471 980 30 980 38 980 129 980 174 980 175 980 180 980 261 980 283 980 304 980 322 980 325 980 348 980 349 980 394 980 395 980 399 980 431 980 444 980 522 980 537 980 580 980 590 980 631 980 652 980 681 980 695 980 767 980 776 980 792 980 829 980 884 980 897 980 967 980 969 980 980 980 992 980 1057 980 1125 980 1137 980 1140 980 1141 980 1199 980 1204 980 1209 980 1219 980 1244 980 1249 980 1261 980 1271 980 1351 980 1359 980 1378 981 214 981 236 981 476 981 595 981 973 981 981 981 984 981 1117 981 1182 981 1264 982 2 982 25 982 93 982 111 982 117 982 153 982 241 982 275 982 282 982 353 982 362 982 450 982 454 982 463 982 516 982 523 982 780 982 794 982 838 982 894 982 970 982 982 982 1056 982 1105 982 1122 982 1186 982 1194 982 1253 982 1256 982 1260 982 1280 982 1282 982 1298 982 1377 982 1384 982 1385 982 1396 982 1447 983 0 983 73 983 119 983 129 983 180 983 197 983 269 983 298 983 338 983 442 983 506 983 522 983 549 983 560 983 655 983 702 983 745 983 769 983 778 983 866 983 892 983 983 983 1084 983 1085 983 1145 983 1178 983 1260 983 1330 983 1333 983 1371 983 1400 983 1455 984 214 984 236 984 476 984 595 984 742 984 973 984 981 984 984 984 1117 984 1182 984 1264 985 24 985 66 985 116 985 137 985 174 985 206 985 235 985 250 985 261 985 325 985 348 985 356 985 425 985 429 985 479 985 502 985 539 985 552 985 568 985 646 985 678 985 714 985 753 985 755 985 776 985 885 985 944 985 985 985 995 985 1064 985 1072 985 1165 985 1178 985 1244 985 1261 985 1339 985 1401 985 1403 986 89 986 106 986 151 986 244 986 251 986 267 986 318 986 347 986 355 986 380 986 430 986 470 986 480 986 482 986 494 986 505 986 510 986 529 986 535 986 546 986 665 986 674 986 678 986 683 986 686 986 699 986 708 986 760 986 787 986 821 986 896 986 921 986 931 986 950 986 965 986 979 986 986 986 996 986 1007 986 1009 986 1019 986 1060 986 1063 986 1079 986 1160 986 1215 986 1304 986 1318 986 1408 986 1417 986 1425 986 1449 986 1465 986 1471 986 1485 987 7 987 20 987 37 987 87 987 148 987 167 987 204 987 219 987 242 987 292 987 350 987 396 987 446 987 508 987 583 987 604 987 613 987 621 987 636 987 841 987 903 987 919 987 928 987 948 987 953 987 987 987 1038 987 1106 987 1151 987 1161 987 1167 987 1169 987 1171 987 1211 987 1257 987 1268 987 1273 987 1326 987 1379 987 1431 987 1450 987 1454 987 1458 988 81 988 99 988 228 988 289 988 487 988 505 988 510 988 585 988 717 988 789 988 890 988 909 988 925 988 979 988 988 988 1000 988 1226 988 1286 988 1392 988 1410 988 1414 988 1445 988 1471 989 39 989 112 989 168 989 176 989 208 989 215 989 254 989 280 989 302 989 409 989 410 989 456 989 633 989 651 989 747 989 779 989 861 989 878 989 891 989 927 989 954 989 976 989 989 989 1025 989 1030 989 1128 989 1134 989 1148 989 1207 989 1233 989 1295 989 1301 989 1310 989 1319 989 1368 989 1383 990 57 990 76 990 135 990 144 990 147 990 189 990 232 990 253 990 295 990 305 990 344 990 370 990 373 990 397 990 401 990 404 990 455 990 478 990 484 990 491 990 520 990 556 990 591 990 611 990 684 990 743 990 799 990 807 990 860 990 888 990 911 990 940 990 978 990 990 990 993 990 999 990 1014 990 1069 990 1082 990 1202 990 1216 990 1217 990 1235 990 1250 990 1277 990 1290 990 1355 990 1356 990 1358 990 1370 990 1375 990 1456 991 17 991 27 991 124 991 162 991 243 991 321 991 413 991 479 991 531 991 552 991 577 991 634 991 786 991 789 991 797 991 831 991 881 991 918 991 991 991 1092 991 1120 991 1123 991 1173 991 1213 991 1292 991 1372 991 1410 991 1414 991 1446 992 17 992 124 992 129 992 133 992 145 992 172 992 174 992 180 992 255 992 261 992 304 992 322 992 325 992 328 992 394 992 395 992 399 992 429 992 498 992 522 992 561 992 576 992 590 992 634 992 646 992 681 992 695 992 776 992 786 992 795 992 885 992 944 992 969 992 980 992 992 992 1039 992 1046 992 1125 992 1140 992 1160 992 1173 992 1199 992 1209 992 1244 992 1353 993 44 993 57 993 76 993 147 993 149 993 189 993 253 993 344 993 370 993 375 993 388 993 397 993 455 993 491 993 556 993 591 993 733 993 799 993 860 993 875 993 893 993 990 993 993 993 1027 993 1069 993 1082 993 1136 993 1202 993 1235 993 1278 993 1355 993 1358 993 1456 994 7 994 22 994 156 994 196 994 266 994 345 994 378 994 396 994 403 994 449 994 530 994 543 994 570 994 583 994 604 994 621 994 669 994 691 994 707 994 727 994 739 994 763 994 764 994 791 994 854 994 873 994 903 994 920 994 948 994 960 994 994 994 1005 994 1037 994 1038 994 1090 994 1126 994 1176 994 1224 994 1267 994 1287 994 1324 994 1325 994 1326 994 1386 994 1436 994 1444 994 1450 994 1493 995 27 995 28 995 89 995 116 995 138 995 267 995 301 995 355 995 444 995 470 995 482 995 539 995 540 995 552 995 568 995 646 995 652 995 678 995 705 995 708 995 714 995 753 995 755 995 831 995 832 995 865 995 896 995 921 995 931 995 965 995 979 995 985 995 995 995 1007 995 1009 995 1064 995 1111 995 1120 995 1160 995 1199 995 1292 995 1316 995 1321 995 1339 995 1403 995 1414 995 1425 995 1446 995 1494 996 0 996 11 996 114 996 185 996 220 996 238 996 264 996 298 996 301 996 303 996 347 996 358 996 367 996 419 996 480 996 529 996 545 996 546 996 597 996 663 996 674 996 689 996 699 996 715 996 721 996 760 996 821 996 824 996 828 996 842 996 912 996 973 996 986 996 996 996 1011 996 1033 996 1085 996 1147 996 1197 996 1215 996 1218 996 1305 996 1398 996 1412 996 1440 996 1465 996 1488 997 31 997 91 997 123 997 143 997 167 997 178 997 219 997 319 997 326 997 402 997 416 997 418 997 422 997 457 997 593 997 617 997 622 997 636 997 644 997 732 997 777 997 935 997 958 997 962 997 997 997 1010 997 1015 997 1112 997 1146 997 1154 997 1200 997 1205 997 1257 997 1294 997 1311 997 1346 997 1388 997 1426 997 1479 998 18 998 108 998 140 998 146 998 246 998 313 998 320 998 363 998 393 998 406 998 411 998 413 998 512 998 521 998 688 998 718 998 740 998 772 998 781 998 782 998 852 998 907 998 945 998 974 998 998 998 1004 998 1049 998 1094 998 1123 998 1139 998 1158 998 1177 998 1387 998 1397 998 1453 998 1466 998 1473 999 92 999 125 999 189 999 202 999 230 999 240 999 272 999 295 999 373 999 387 999 484 999 491 999 520 999 556 999 569 999 600 999 611 999 612 999 624 999 690 999 694 999 743 999 809 999 888 999 910 999 911 999 978 999 990 999 999 999 1014 999 1018 999 1069 999 1075 999 1196 999 1277 999 1331 999 1355 999 1369 999 1461 999 1472 999 1476 999 1484 1000 81 1000 99 1000 127 1000 134 1000 138 1000 228 1000 329 1000 337 1000 393 1000 487 1000 505 1000 510 1000 513 1000 585 1000 596 1000 686 1000 717 1000 754 1000 775 1000 789 1000 797 1000 834 1000 890 1000 918 1000 946 1000 968 1000 988 1000 1000 1000 1048 1000 1226 1000 1241 1000 1251 1000 1286 1000 1408 1000 1414 1000 1428 1000 1445 1000 1471 1001 2 1001 93 1001 95 1001 97 1001 111 1001 126 1001 153 1001 194 1001 197 1001 227 1001 231 1001 247 1001 282 1001 296 1001 315 1001 362 1001 384 1001 450 1001 454 1001 463 1001 481 1001 499 1001 516 1001 564 1001 614 1001 654 1001 662 1001 670 1001 675 1001 796 1001 801 1001 838 1001 970 1001 975 1001 1001 1001 1002 1001 1036 1001 1050 1001 1105 1001 1116 1001 1119 1001 1122 1001 1157 1001 1186 1001 1194 1001 1248 1001 1256 1001 1280 1001 1282 1001 1302 1001 1329 1001 1354 1001 1384 1001 1394 1001 1396 1001 1478 1002 2 1002 74 1002 93 1002 95 1002 113 1002 126 1002 201 1002 227 1002 231 1002 282 1002 296 1002 306 1002 386 1002 407 1002 481 1002 515 1002 516 1002 525 1002 662 1002 798 1002 801 1002 804 1002 838 1002 858 1002 975 1002 1001 1002 1002 1002 1116 1002 1119 1002 1122 1002 1227 1002 1259 1002 1272 1002 1280 1002 1282 1002 1354 1002 1391 1002 1396 1002 1478 1003 30 1003 53 1003 78 1003 82 1003 90 1003 102 1003 130 1003 191 1003 193 1003 200 1003 211 1003 212 1003 262 1003 270 1003 308 1003 323 1003 332 1003 348 1003 405 1003 428 1003 451 1003 465 1003 511 1003 533 1003 537 1003 549 1003 610 1003 658 1003 702 1003 752 1003 761 1003 812 1003 829 1003 863 1003 884 1003 901 1003 923 1003 967 1003 1003 1003 1024 1003 1035 1003 1046 1003 1057 1003 1084 1003 1118 1003 1124 1003 1135 1003 1137 1003 1141 1003 1183 1003 1327 1003 1334 1003 1336 1003 1340 1003 1390 1003 1459 1003 1481 1004 18 1004 25 1004 108 1004 146 1004 163 1004 246 1004 273 1004 320 1004 415 1004 512 1004 523 1004 688 1004 700 1004 740 1004 894 1004 907 1004 932 1004 963 1004 974 1004 998 1004 1004 1004 1094 1004 1123 1004 1177 1004 1193 1004 1239 1004 1306 1004 1453 1004 1466 1004 1473 1005 22 1005 156 1005 159 1005 266 1005 274 1005 336 1005 390 1005 396 1005 403 1005 449 1005 530 1005 543 1005 548 1005 583 1005 588 1005 621 1005 641 1005 707 1005 763 1005 764 1005 873 1005 903 1005 920 1005 948 1005 960 1005 964 1005 994 1005 1005 1005 1037 1005 1038 1005 1126 1005 1224 1005 1252 1005 1267 1005 1287 1005 1324 1005 1386 1005 1436 1005 1444 1005 1493 1006 120 1006 209 1006 214 1006 293 1006 324 1006 361 1006 488 1006 572 1006 581 1006 647 1006 659 1006 677 1006 737 1006 788 1006 818 1006 971 1006 1006 1006 1051 1006 1062 1006 1093 1006 1115 1006 1149 1006 1192 1006 1293 1006 1307 1006 1424 1007 51 1007 116 1007 206 1007 235 1007 244 1007 263 1007 268 1007 283 1007 325 1007 355 1007 380 1007 399 1007 425 1007 470 1007 482 1007 522 1007 575 1007 576 1007 594 1007 623 1007 625 1007 629 1007 646 1007 652 1007 678 1007 689 1007 695 1007 708 1007 767 1007 795 1007 810 1007 824 1007 865 1007 896 1007 921 1007 931 1007 986 1007 995 1007 1007 1007 1039 1007 1059 1007 1064 1007 1160 1007 1199 1007 1204 1007 1244 1007 1261 1007 1316 1007 1321 1007 1339 1007 1349 1007 1378 1007 1403 1007 1449 1007 1468 1007 1494 1008 10 1008 23 1008 103 1008 184 1008 198 1008 210 1008 314 1008 342 1008 357 1008 376 1008 503 1008 517 1008 542 1008 559 1008 578 1008 582 1008 601 1008 627 1008 643 1008 666 1008 687 1008 693 1008 697 1008 704 1008 725 1008 750 1008 766 1008 811 1008 898 1008 915 1008 1008 1008 1095 1008 1168 1008 1240 1008 1246 1008 1297 1008 1300 1008 1312 1008 1338 1008 1352 1008 1374 1008 1429 1008 1457 1008 1492 1008 1495 1009 26 1009 89 1009 127 1009 244 1009 251 1009 264 1009 267 1009 318 1009 470 1009 482 1009 494 1009 535 1009 546 1009 598 1009 674 1009 678 1009 689 1009 708 1009 755 1009 760 1009 817 1009 831 1009 865 1009 895 1009 896 1009 921 1009 925 1009 965 1009 979 1009 986 1009 995 1009 1009 1009 1079 1009 1160 1009 1215 1009 1314 1009 1318 1009 1321 1009 1341 1009 1425 1009 1449 1009 1465 1009 1467 1009 1471 1010 91 1010 143 1010 219 1010 319 1010 326 1010 350 1010 378 1010 416 1010 418 1010 422 1010 446 1010 508 1010 555 1010 604 1010 617 1010 636 1010 644 1010 669 1010 732 1010 777 1010 800 1010 854 1010 935 1010 937 1010 958 1010 962 1010 997 1010 1010 1010 1015 1010 1087 1010 1146 1010 1151 1010 1154 1010 1167 1010 1200 1010 1205 1010 1268 1010 1289 1010 1294 1010 1311 1010 1346 1010 1388 1010 1431 1010 1479 1011 0 1011 51 1011 70 1011 80 1011 98 1011 114 1011 151 1011 185 1011 186 1011 238 1011 251 1011 256 1011 264 1011 276 1011 278 1011 281 1011 298 1011 301 1011 303 1011 358 1011 367 1011 412 1011 419 1011 437 1011 442 1011 475 1011 480 1011 496 1011 518 1011 545 1011 597 1011 645 1011 663 1011 674 1011 699 1011 721 1011 729 1011 731 1011 768 1011 771 1011 803 1011 817 1011 821 1011 824 1011 828 1011 949 1011 996 1011 1011 1011 1031 1011 1032 1011 1033 1011 1052 1011 1055 1011 1060 1011 1085 1011 1145 1011 1147 1011 1208 1011 1215 1011 1263 1011 1271 1011 1305 1011 1318 1011 1363 1011 1412 1011 1417 1011 1465 1011 1488 1012 2 1012 25 1012 70 1012 98 1012 111 1012 114 1012 163 1012 181 1012 194 1012 220 1012 353 1012 362 1012 384 1012 412 1012 450 1012 467 1012 663 1012 664 1012 670 1012 692 1012 794 1012 796 1012 825 1012 966 1012 970 1012 1012 1012 1032 1012 1055 1012 1083 1012 1105 1012 1170 1012 1186 1012 1228 1012 1239 1012 1256 1012 1298 1012 1302 1012 1308 1012 1385 1012 1396 1012 1466 1012 1478 1013 43 1013 46 1013 60 1013 77 1013 112 1013 118 1013 154 1013 176 1013 208 1013 280 1013 287 1013 369 1013 385 1013 410 1013 456 1013 541 1013 557 1013 565 1013 633 1013 724 1013 747 1013 779 1013 861 1013 878 1013 891 1013 902 1013 927 1013 957 1013 976 1013 1013 1013 1025 1013 1030 1013 1128 1013 1148 1013 1150 1013 1210 1013 1243 1013 1279 1013 1295 1013 1310 1013 1366 1013 1380 1013 1439 1013 1489 1014 47 1014 76 1014 135 1014 144 1014 189 1014 217 1014 253 1014 272 1014 295 1014 305 1014 373 1014 387 1014 401 1014 455 1014 478 1014 483 1014 520 1014 526 1014 556 1014 591 1014 600 1014 611 1014 612 1014 680 1014 684 1014 694 1014 743 1014 784 1014 814 1014 822 1014 839 1014 910 1014 911 1014 940 1014 978 1014 990 1014 999 1014 1014 1014 1018 1014 1069 1014 1075 1014 1082 1014 1099 1014 1142 1014 1180 1014 1206 1014 1216 1014 1217 1014 1229 1014 1230 1014 1250 1014 1277 1014 1281 1014 1290 1014 1355 1014 1370 1014 1375 1014 1407 1014 1441 1014 1474 1014 1484 1014 1498 1015 31 1015 123 1015 143 1015 167 1015 178 1015 219 1015 319 1015 326 1015 350 1015 360 1015 416 1015 418 1015 422 1015 457 1015 508 1015 555 1015 593 1015 617 1015 622 1015 644 1015 732 1015 777 1015 800 1015 886 1015 900 1015 928 1015 933 1015 935 1015 958 1015 962 1015 997 1015 1010 1015 1015 1015 1071 1015 1087 1015 1106 1015 1112 1015 1146 1015 1154 1015 1161 1015 1171 1015 1200 1015 1205 1015 1211 1015 1257 1015 1268 1015 1289 1015 1294 1015 1311 1015 1346 1015 1388 1015 1426 1015 1431 1015 1479 1016 127 1016 131 1016 138 1016 228 1016 243 1016 250 1016 263 1016 392 1016 479 1016 486 1016 501 1016 502 1016 513 1016 535 1016 649 1016 678 1016 679 1016 715 1016 726 1016 746 1016 757 1016 775 1016 830 1016 831 1016 834 1016 879 1016 909 1016 925 1016 946 1016 979 1016 1016 1016 1072 1016 1213 1016 1215 1016 1286 1016 1392 1017 38 1017 66 1017 96 1017 131 1017 137 1017 216 1017 261 1017 269 1017 356 1017 428 1017 464 1017 534 1017 720 1017 792 1017 874 1017 887 1017 942 1017 1017 1017 1047 1017 1067 1017 1089 1017 1219 1017 1234 1017 1238 1017 1244 1017 1336 1017 1359 1018 5 1018 13 1018 14 1018 47 1018 92 1018 101 1018 189 1018 202 1018 230 1018 240 1018 279 1018 291 1018 295 1018 305 1018 365 1018 373 1018 387 1018 408 1018 434 1018 441 1018 483 1018 526 1018 569 1018 606 1018 612 1018 624 1018 630 1018 680 1018 690 1018 730 1018 822 1018 867 1018 883 1018 911 1018 999 1018 1014 1018 1018 1018 1075 1018 1076 1018 1196 1018 1206 1018 1229 1018 1236 1018 1277 1018 1281 1018 1290 1018 1331 1018 1369 1018 1370 1018 1461 1018 1472 1018 1476 1018 1484 1018 1498 1019 11 1019 41 1019 81 1019 99 1019 106 1019 151 1019 188 1019 347 1019 419 1019 430 1019 480 1019 487 1019 505 1019 510 1019 529 1019 546 1019 550 1019 585 1019 665 1019 674 1019 682 1019 760 1019 787 1019 820 1019 821 1019 842 1019 949 1019 965 1019 986 1019 1019 1019 1022 1019 1060 1019 1063 1019 1070 1019 1175 1019 1190 1019 1304 1019 1318 1019 1408 1019 1440 1019 1465 1019 1471 1020 23 1020 37 1020 49 1020 75 1020 128 1020 170 1020 184 1020 198 1020 290 1020 357 1020 360 1020 376 1020 402 1020 443 1020 457 1020 503 1020 517 1020 551 1020 555 1020 559 1020 574 1020 582 1020 589 1020 593 1020 622 1020 627 1020 657 1020 673 1020 703 1020 725 1020 756 1020 766 1020 770 1020 800 1020 805 1020 886 1020 916 1020 933 1020 955 1020 1020 1020 1087 1020 1088 1020 1101 1020 1107 1020 1166 1020 1203 1020 1257 1020 1268 1020 1346 1020 1364 1020 1388 1020 1429 1020 1433 1020 1457 1020 1483 1020 1492 1021 59 1021 67 1021 161 1021 190 1021 335 1021 414 1021 435 1021 774 1021 840 1021 841 1021 857 1021 1021 1021 1231 1021 1320 1021 1365 1021 1409 1021 1432 1021 1443 1021 1454 1021 1477 1021 1491 1021 1497 1022 80 1022 81 1022 99 1022 106 1022 151 1022 179 1022 181 1022 188 1022 199 1022 225 1022 226 1022 245 1022 246 1022 249 1022 278 1022 310 1022 419 1022 430 1022 487 1022 509 1022 529 1022 550 1022 602 1022 653 1022 665 1022 682 1022 718 1022 754 1022 768 1022 820 1022 894 1022 912 1022 922 1022 932 1022 949 1022 952 1022 963 1022 974 1022 1019 1022 1022 1022 1032 1022 1045 1022 1063 1022 1070 1022 1152 1022 1158 1022 1170 1022 1190 1022 1223 1022 1251 1022 1288 1022 1465 1023 84 1023 93 1023 95 1023 120 1023 239 1023 241 1023 271 1023 293 1023 311 1023 315 1023 361 1023 450 1023 515 1023 564 1023 647 1023 677 1023 719 1023 858 1023 971 1023 975 1023 1023 1023 1058 1023 1157 1023 1248 1023 1307 1023 1377 1023 1394 1023 1395 1023 1424 1023 1435 1024 26 1024 53 1024 58 1024 78 1024 82 1024 86 1024 102 1024 137 1024 191 1024 193 1024 200 1024 206 1024 211 1024 222 1024 250 1024 257 1024 277 1024 332 1024 348 1024 405 1024 428 1024 431 1024 444 1024 451 1024 533 1024 534 1024 536 1024 563 1024 579 1024 580 1024 626 1024 658 1024 701 1024 702 1024 846 1024 863 1024 901 1024 923 1024 934 1024 959 1024 1003 1024 1024 1024 1035 1024 1046 1024 1054 1024 1084 1024 1102 1024 1113 1024 1131 1024 1135 1024 1137 1024 1309 1024 1327 1024 1334 1024 1340 1024 1341 1024 1459 1024 1475 1024 1481 1024 1486 1024 1494 1025 39 1025 46 1025 60 1025 77 1025 104 1025 109 1025 112 1025 154 1025 176 1025 208 1025 254 1025 258 1025 280 1025 346 1025 410 1025 456 1025 500 1025 541 1025 565 1025 633 1025 651 1025 724 1025 747 1025 779 1025 826 1025 861 1025 878 1025 891 1025 902 1025 927 1025 954 1025 957 1025 976 1025 989 1025 1013 1025 1025 1025 1030 1025 1114 1025 1128 1025 1134 1025 1148 1025 1207 1025 1210 1025 1243 1025 1270 1025 1301 1025 1310 1025 1350 1025 1368 1025 1380 1025 1439 1026 12 1026 29 1026 52 1026 63 1026 65 1026 125 1026 165 1026 234 1026 240 1026 528 1026 642 1026 742 1026 759 1026 787 1026 809 1026 845 1026 882 1026 939 1026 1026 1026 1028 1026 1075 1026 1265 1026 1461 1027 44 1027 57 1027 147 1027 344 1027 375 1027 388 1027 491 1027 743 1027 799 1027 893 1027 993 1027 1027 1027 1069 1027 1202 1027 1278 1027 1456 1028 5 1028 12 1028 13 1028 52 1028 65 1028 85 1028 165 1028 202 1028 234 1028 240 1028 365 1028 434 1028 441 1028 492 1028 528 1028 603 1028 609 1028 630 1028 642 1028 730 1028 742 1028 759 1028 939 1028 1026 1028 1028 1028 1108 1028 1129 1028 1159 1028 1265 1028 1369 1028 1461 1028 1472 1029 7 1029 20 1029 37 1029 68 1029 87 1029 170 1029 203 1029 204 1029 210 1029 294 1029 300 1029 314 1029 350 1029 433 1029 559 1029 583 1029 627 1029 657 1029 703 1029 766 1029 836 1029 886 1029 916 1029 928 1029 930 1029 953 1029 1029 1029 1088 1029 1100 1029 1106 1029 1169 1029 1171 1029 1211 1029 1300 1029 1338 1029 1458 1029 1460 1029 1462 1029 1490 1030 77 1030 104 1030 105 1030 154 1030 176 1030 208 1030 254 1030 280 1030 287 1030 302 1030 309 1030 385 1030 410 1030 456 1030 500 1030 532 1030 541 1030 565 1030 633 1030 651 1030 724 1030 747 1030 779 1030 826 1030 861 1030 878 1030 891 1030 902 1030 927 1030 957 1030 976 1030 989 1030 1013 1030 1025 1030 1030 1030 1148 1030 1207 1030 1210 1030 1279 1030 1295 1030 1310 1030 1366 1030 1380 1030 1383 1030 1489 1031 25 1031 70 1031 98 1031 108 1031 119 1031 133 1031 238 1031 256 1031 273 1031 281 1031 298 1031 301 1031 303 1031 358 1031 438 1031 442 1031 512 1031 722 1031 729 1031 731 1031 794 1031 803 1031 824 1031 1011 1031 1031 1031 1032 1031 1052 1031 1055 1031 1085 1031 1133 1031 1147 1031 1228 1031 1263 1031 1271 1031 1363 1031 1371 1031 1412 1031 1468 1031 1488 1032 70 1032 80 1032 98 1032 151 1032 163 1032 179 1032 181 1032 226 1032 245 1032 246 1032 256 1032 276 1032 281 1032 310 1032 339 1032 358 1032 412 1032 430 1032 540 1032 653 1032 664 1032 692 1032 768 1032 803 1032 894 1032 932 1032 949 1032 952 1032 963 1032 974 1032 1011 1032 1012 1032 1022 1032 1031 1032 1032 1032 1045 1032 1055 1032 1063 1032 1158 1032 1170 1032 1190 1032 1208 1032 1251 1032 1263 1032 1288 1032 1363 1032 1488 1033 11 1033 21 1033 41 1033 48 1033 70 1033 94 1033 151 1033 179 1033 245 1033 256 1033 276 1033 278 1033 339 1033 347 1033 358 1033 412 1033 419 1033 437 1033 459 1033 496 1033 513 1033 535 1033 545 1033 635 1033 664 1033 713 1033 787 1033 790 1033 810 1033 817 1033 821 1033 828 1033 834 1033 912 1033 949 1033 950 1033 952 1033 996 1033 1011 1033 1033 1033 1045 1033 1048 1033 1052 1033 1063 1033 1081 1033 1163 1033 1170 1033 1181 1033 1201 1033 1208 1033 1215 1033 1239 1033 1241 1033 1251 1033 1288 1033 1362 1033 1399 1033 1465 1033 1488 1034 36 1034 56 1034 72 1034 83 1034 101 1034 164 1034 187 1034 217 1034 223 1034 224 1034 343 1034 389 1034 391 1034 408 1034 497 1034 520 1034 524 1034 547 1034 567 1034 584 1034 592 1034 608 1034 638 1034 680 1034 784 1034 844 1034 867 1034 906 1034 908 1034 972 1034 1034 1034 1068 1034 1078 1034 1098 1034 1099 1034 1142 1034 1180 1034 1198 1034 1225 1034 1230 1034 1299 1034 1348 1034 1361 1034 1373 1034 1474 1034 1496 1034 1498 1035 26 1035 53 1035 58 1035 78 1035 82 1035 86 1035 90 1035 102 1035 191 1035 193 1035 200 1035 222 1035 233 1035 312 1035 323 1035 327 1035 332 1035 405 1035 451 1035 465 1035 536 1035 563 1035 579 1035 623 1035 626 1035 658 1035 701 1035 702 1035 734 1035 863 1035 884 1035 901 1035 934 1035 959 1035 1003 1035 1024 1035 1035 1035 1054 1035 1102 1035 1113 1035 1118 1035 1124 1035 1135 1035 1212 1035 1266 1035 1309 1035 1327 1035 1330 1035 1334 1035 1340 1035 1341 1035 1390 1035 1481 1035 1486 1036 2 1036 93 1036 95 1036 97 1036 111 1036 126 1036 153 1036 194 1036 197 1036 231 1036 247 1036 275 1036 282 1036 296 1036 311 1036 315 1036 362 1036 372 1036 384 1036 450 1036 454 1036 463 1036 481 1036 499 1036 516 1036 564 1036 614 1036 654 1036 670 1036 675 1036 796 1036 801 1036 970 1036 975 1036 1001 1036 1036 1036 1050 1036 1083 1036 1105 1036 1116 1036 1119 1036 1122 1036 1186 1036 1194 1036 1248 1036 1256 1036 1280 1036 1302 1036 1329 1036 1354 1036 1384 1036 1394 1036 1478 1037 22 1037 156 1037 159 1037 196 1037 266 1037 345 1037 390 1037 396 1037 400 1037 403 1037 448 1037 449 1037 530 1037 543 1037 548 1037 605 1037 615 1037 641 1037 691 1037 707 1037 727 1037 739 1037 763 1037 764 1037 847 1037 873 1037 920 1037 947 1037 948 1037 960 1037 994 1037 1005 1037 1037 1037 1090 1037 1126 1037 1172 1037 1252 1037 1267 1037 1287 1037 1324 1037 1325 1037 1386 1037 1436 1037 1493 1038 22 1038 156 1038 292 1038 396 1038 446 1038 508 1038 530 1038 543 1038 583 1038 604 1038 613 1038 621 1038 636 1038 669 1038 691 1038 727 1038 841 1038 854 1038 873 1038 903 1038 919 1038 920 1038 948 1038 953 1038 987 1038 994 1038 1005 1038 1038 1038 1151 1038 1267 1038 1273 1038 1287 1038 1324 1038 1326 1038 1450 1038 1454 1038 1458 1039 17 1039 24 1039 42 1039 70 1039 124 1039 268 1039 283 1039 304 1039 392 1039 395 1039 429 1039 575 1039 681 1039 695 1039 731 1039 776 1039 786 1039 810 1039 969 1039 992 1039 1007 1039 1039 1039 1155 1039 1160 1039 1201 1039 1339 1039 1468 1040 3 1040 166 1040 183 1040 461 1040 471 1040 473 1040 525 1040 527 1040 654 1040 660 1040 662 1040 668 1040 696 1040 709 1040 748 1040 804 1040 1040 1040 1143 1040 1191 1040 1254 1040 1272 1040 1285 1040 1302 1040 1303 1040 1329 1040 1405 1040 1427 1040 1469 1041 16 1041 32 1041 34 1041 40 1041 139 1041 150 1041 171 1041 177 1041 207 1041 213 1041 237 1041 248 1041 274 1041 297 1041 307 1041 317 1041 366 1041 423 1041 439 1041 453 1041 495 1041 744 1041 813 1041 833 1041 835 1041 848 1041 853 1041 859 1041 868 1041 869 1041 926 1041 936 1041 1041 1041 1053 1041 1103 1041 1110 1041 1138 1041 1237 1041 1247 1041 1262 1041 1284 1041 1296 1041 1322 1041 1347 1041 1376 1041 1381 1041 1422 1041 1482 1042 21 1042 99 1042 245 1042 246 1042 260 1042 320 1042 329 1042 337 1042 393 1042 417 1042 421 1042 445 1042 596 1042 602 1042 616 1042 653 1042 717 1042 754 1042 759 1042 762 1042 797 1042 806 1042 855 1042 918 1042 922 1042 1042 1042 1048 1042 1077 1042 1139 1042 1190 1042 1241 1042 1315 1042 1317 1042 1387 1042 1408 1042 1428 1042 1438 1042 1445 1042 1453 1042 1470 1043 142 1043 157 1043 316 1043 709 1043 819 1043 877 1043 914 1043 1043 1043 1121 1043 1430 1044 9 1044 15 1044 54 1044 73 1044 121 1044 158 1044 182 1044 205 1044 221 1044 229 1044 257 1044 262 1044 285 1044 351 1044 381 1044 462 1044 485 1044 490 1044 536 1044 618 1044 619 1044 655 1044 685 1044 698 1044 701 1044 734 1044 735 1044 802 1044 808 1044 823 1044 827 1044 837 1044 864 1044 905 1044 1044 1044 1118 1044 1144 1044 1153 1044 1183 1044 1221 1044 1258 1044 1340 1044 1343 1044 1360 1044 1382 1044 1448 1044 1452 1044 1455 1045 11 1045 21 1045 41 1045 80 1045 94 1045 163 1045 179 1045 225 1045 226 1045 245 1045 246 1045 276 1045 278 1045 310 1045 320 1045 329 1045 339 1045 406 1045 412 1045 417 1045 445 1045 459 1045 487 1045 496 1045 509 1045 535 1045 596 1045 616 1045 653 1045 664 1045 713 1045 754 1045 762 1045 768 1045 790 1045 806 1045 828 1045 912 1045 922 1045 929 1045 932 1045 949 1045 952 1045 963 1045 974 1045 1022 1045 1032 1045 1033 1045 1045 1045 1063 1045 1077 1045 1139 1045 1158 1045 1163 1045 1170 1045 1181 1045 1201 1045 1208 1045 1239 1045 1241 1045 1251 1045 1288 1045 1315 1045 1335 1045 1445 1045 1470 1046 38 1046 53 1046 58 1046 86 1046 130 1046 193 1046 206 1046 211 1046 212 1046 216 1046 286 1046 325 1046 348 1046 349 1046 405 1046 429 1046 431 1046 444 1046 451 1046 464 1046 522 1046 580 1046 646 1046 652 1046 702 1046 720 1046 767 1046 769 1046 776 1046 792 1046 897 1046 923 1046 992 1046 1003 1046 1024 1046 1046 1046 1084 1046 1135 1046 1137 1046 1219 1046 1238 1046 1249 1046 1309 1046 1316 1046 1336 1046 1459 1046 1481 1047 66 1047 96 1047 174 1047 216 1047 250 1047 261 1047 322 1047 354 1047 356 1047 394 1047 444 1047 479 1047 486 1047 711 1047 714 1047 720 1047 785 1047 792 1047 830 1047 874 1047 887 1047 942 1047 1017 1047 1047 1047 1089 1047 1165 1047 1283 1047 1332 1047 1359 1047 1414 1048 41 1048 81 1048 99 1048 127 1048 138 1048 151 1048 199 1048 245 1048 284 1048 318 1048 337 1048 382 1048 393 1048 406 1048 496 1048 501 1048 510 1048 513 1048 521 1048 535 1048 686 1048 713 1048 741 1048 772 1048 775 1048 781 1048 790 1048 797 1048 834 1048 912 1048 929 1048 946 1048 950 1048 968 1048 1000 1048 1033 1048 1042 1048 1048 1048 1070 1048 1164 1048 1190 1048 1223 1048 1226 1048 1241 1048 1251 1048 1286 1048 1304 1048 1408 1048 1410 1048 1425 1048 1445 1048 1470 1049 35 1049 48 1049 100 1049 134 1049 140 1049 313 1049 320 1049 374 1049 382 1049 393 1049 406 1049 411 1049 413 1049 498 1049 512 1049 521 1049 577 1049 635 1049 688 1049 718 1049 740 1049 741 1049 746 1049 762 1049 772 1049 781 1049 852 1049 918 1049 945 1049 961 1049 998 1049 1049 1049 1094 1049 1139 1049 1158 1049 1163 1049 1181 1049 1362 1049 1387 1049 1453 1050 2 1050 93 1050 95 1050 97 1050 114 1050 126 1050 153 1050 194 1050 197 1050 220 1050 231 1050 247 1050 282 1050 296 1050 315 1050 362 1050 407 1050 450 1050 454 1050 463 1050 499 1050 516 1050 564 1050 614 1050 654 1050 662 1050 663 1050 670 1050 721 1050 765 1050 796 1050 825 1050 970 1050 1001 1050 1036 1050 1050 1050 1083 1050 1105 1050 1122 1050 1186 1050 1194 1050 1222 1050 1242 1050 1248 1050 1256 1050 1280 1050 1329 1050 1354 1050 1384 1050 1394 1050 1395 1050 1396 1051 209 1051 214 1051 334 1051 353 1051 472 1051 476 1051 477 1051 488 1051 647 1051 677 1051 710 1051 793 1051 850 1051 1006 1051 1051 1051 1115 1051 1192 1051 1195 1052 6 1052 21 1052 25 1052 42 1052 48 1052 51 1052 70 1052 124 1052 163 1052 172 1052 256 1052 276 1052 298 1052 303 1052 339 1052 406 1052 512 1052 635 1052 695 1052 718 1052 729 1052 731 1052 757 1052 782 1052 794 1052 810 1052 828 1052 961 1052 1011 1052 1031 1052 1033 1052 1052 1052 1086 1052 1163 1052 1178 1052 1181 1052 1201 1052 1208 1052 1228 1052 1239 1052 1263 1052 1362 1052 1363 1052 1399 1052 1488 1053 4 1053 16 1053 32 1053 71 1053 177 1053 248 1053 274 1053 297 1053 331 1053 423 1053 432 1053 469 1053 519 1053 632 1053 706 1053 716 1053 738 1053 964 1053 977 1053 1041 1053 1053 1053 1073 1053 1130 1053 1274 1053 1322 1053 1328 1053 1357 1053 1367 1053 1416 1053 1423 1053 1451 1053 1480 1054 26 1054 58 1054 86 1054 191 1054 193 1054 222 1054 250 1054 312 1054 332 1054 405 1054 465 1054 533 1054 536 1054 563 1054 658 1054 701 1054 758 1054 863 1054 934 1054 938 1054 959 1054 1024 1054 1035 1054 1054 1054 1102 1054 1118 1054 1135 1054 1212 1054 1327 1054 1334 1054 1340 1054 1341 1054 1485 1054 1486 1055 25 1055 70 1055 98 1055 114 1055 151 1055 181 1055 220 1055 251 1055 256 1055 276 1055 358 1055 412 1055 663 1055 689 1055 692 1055 699 1055 721 1055 768 1055 794 1055 821 1055 825 1055 828 1055 894 1055 1011 1055 1012 1055 1031 1055 1032 1055 1055 1055 1083 1055 1263 1055 1363 1055 1385 1055 1447 1055 1488 1056 2 1056 117 1056 153 1056 201 1056 239 1056 241 1056 275 1056 282 1056 293 1056 353 1056 361 1056 372 1056 450 1056 516 1056 564 1056 719 1056 793 1056 971 1056 982 1056 1056 1056 1105 1056 1253 1056 1256 1056 1280 1056 1282 1056 1307 1056 1377 1056 1385 1056 1394 1056 1395 1056 1396 1056 1424 1056 1447 1057 30 1057 53 1057 78 1057 90 1057 102 1057 175 1057 191 1057 211 1057 212 1057 270 1057 286 1057 308 1057 349 1057 440 1057 451 1057 460 1057 511 1057 534 1057 537 1057 549 1057 563 1057 610 1057 631 1057 637 1057 761 1057 785 1057 812 1057 829 1057 884 1057 897 1057 923 1057 967 1057 980 1057 1003 1057 1057 1057 1065 1057 1084 1057 1137 1057 1141 1057 1204 1057 1219 1057 1249 1057 1334 1057 1336 1057 1390 1057 1418 1057 1459 1057 1481 1058 84 1058 95 1058 120 1058 239 1058 271 1058 293 1058 311 1058 315 1058 361 1058 515 1058 564 1058 647 1058 677 1058 719 1058 858 1058 971 1058 975 1058 1023 1058 1058 1058 1116 1058 1157 1058 1248 1058 1307 1058 1377 1058 1394 1058 1395 1058 1424 1058 1435 1059 28 1059 233 1059 268 1059 283 1059 286 1059 328 1059 348 1059 349 1059 394 1059 399 1059 440 1059 575 1059 580 1059 625 1059 631 1059 634 1059 652 1059 681 1059 786 1059 795 1059 829 1059 830 1059 865 1059 896 1059 1007 1059 1059 1059 1064 1059 1140 1059 1199 1059 1316 1059 1351 1059 1378 1059 1403 1059 1481 1059 1494 1059 1499 1060 106 1060 138 1060 151 1060 185 1060 186 1060 188 1060 199 1060 281 1060 380 1060 419 1060 430 1060 470 1060 480 1060 505 1060 510 1060 529 1060 540 1060 585 1060 597 1060 645 1060 661 1060 665 1060 674 1060 676 1060 682 1060 683 1060 686 1060 760 1060 842 1060 865 1060 890 1060 949 1060 950 1060 965 1060 986 1060 1011 1060 1019 1060 1060 1060 1152 1060 1160 1060 1197 1060 1304 1060 1305 1060 1417 1060 1425 1060 1440 1060 1465 1060 1471 1060 1487 1061 32 1061 40 1061 115 1061 139 1061 171 1061 177 1061 237 1061 307 1061 366 1061 453 1061 744 1061 833 1061 835 1061 859 1061 869 1061 926 1061 1061 1061 1103 1061 1138 1061 1237 1061 1245 1061 1247 1061 1262 1061 1276 1061 1296 1061 1322 1061 1347 1061 1376 1061 1381 1061 1406 1061 1482 1062 84 1062 88 1062 173 1062 209 1062 334 1062 420 1062 461 1062 477 1062 488 1062 489 1062 553 1062 572 1062 581 1062 659 1062 668 1062 723 1062 728 1062 737 1062 748 1062 788 1062 818 1062 1006 1062 1062 1062 1080 1062 1093 1062 1096 1062 1104 1062 1115 1062 1143 1062 1149 1062 1192 1062 1293 1062 1469 1063 11 1063 80 1063 99 1063 106 1063 151 1063 179 1063 186 1063 188 1063 225 1063 226 1063 245 1063 249 1063 276 1063 278 1063 310 1063 339 1063 347 1063 358 1063 419 1063 430 1063 437 1063 496 1063 509 1063 529 1063 545 1063 550 1063 653 1063 656 1063 664 1063 665 1063 682 1063 686 1063 713 1063 754 1063 760 1063 768 1063 787 1063 820 1063 821 1063 828 1063 845 1063 912 1063 949 1063 952 1063 986 1063 1019 1063 1022 1063 1032 1063 1033 1063 1045 1063 1063 1063 1070 1063 1152 1063 1170 1063 1175 1063 1190 1063 1197 1063 1208 1063 1251 1063 1288 1063 1304 1063 1335 1063 1465 1064 24 1064 66 1064 116 1064 137 1064 193 1064 206 1064 211 1064 212 1064 323 1064 348 1064 405 1064 425 1064 502 1064 539 1064 552 1064 580 1064 623 1064 625 1064 652 1064 678 1064 708 1064 769 1064 885 1064 896 1064 944 1064 985 1064 995 1064 1007 1064 1059 1064 1064 1064 1165 1064 1178 1064 1204 1064 1238 1064 1244 1064 1316 1064 1341 1064 1378 1064 1403 1064 1494 1065 30 1065 38 1065 53 1065 78 1065 130 1065 191 1065 212 1065 257 1065 262 1065 270 1065 308 1065 351 1065 428 1065 431 1065 451 1065 460 1065 511 1065 534 1065 549 1065 610 1065 619 1065 637 1065 702 1065 761 1065 808 1065 812 1065 827 1065 829 1065 923 1065 1057 1065 1065 1065 1084 1065 1137 1065 1219 1065 1249 1065 1336 1065 1359 1065 1415 1065 1418 1065 1459 1066 53 1066 54 1066 78 1066 82 1066 102 1066 191 1066 200 1066 205 1066 308 1066 312 1066 332 1066 451 1066 490 1066 579 1066 610 1066 658 1066 685 1066 752 1066 846 1066 863 1066 901 1066 959 1066 1066 1066 1102 1066 1113 1066 1135 1066 1183 1066 1212 1066 1221 1066 1327 1066 1340 1066 1442 1066 1463 1066 1475 1066 1486 1067 129 1067 131 1067 180 1067 192 1067 216 1067 261 1067 269 1067 340 1067 352 1067 394 1067 464 1067 575 1067 745 1067 767 1067 792 1067 887 1067 969 1067 1017 1067 1067 1067 1089 1067 1125 1067 1155 1067 1173 1067 1209 1067 1332 1067 1333 1067 1353 1067 1359 1068 72 1068 83 1068 144 1068 217 1068 223 1068 224 1068 232 1068 279 1068 295 1068 343 1068 371 1068 389 1068 391 1068 408 1068 478 1068 483 1068 592 1068 600 1068 638 1068 640 1068 648 1068 684 1068 694 1068 784 1068 807 1068 814 1068 839 1068 844 1068 906 1068 911 1068 940 1068 972 1068 978 1068 1034 1068 1068 1068 1078 1068 1099 1068 1142 1068 1180 1068 1198 1068 1216 1068 1217 1068 1229 1068 1230 1068 1277 1068 1281 1068 1299 1068 1361 1068 1373 1068 1407 1068 1441 1068 1474 1069 79 1069 147 1069 189 1069 272 1069 295 1069 344 1069 387 1069 404 1069 484 1069 491 1069 556 1069 600 1069 611 1069 694 1069 743 1069 809 1069 888 1069 910 1069 911 1069 990 1069 993 1069 999 1069 1014 1069 1027 1069 1069 1069 1075 1069 1082 1069 1277 1069 1281 1069 1355 1069 1456 1069 1484 1070 21 1070 81 1070 99 1070 106 1070 249 1070 318 1070 329 1070 337 1070 347 1070 430 1070 445 1070 480 1070 496 1070 513 1070 529 1070 535 1070 550 1070 585 1070 602 1070 665 1070 754 1070 790 1070 820 1070 834 1070 842 1070 912 1070 922 1070 1019 1070 1022 1070 1048 1070 1063 1070 1070 1070 1190 1070 1241 1070 1288 1070 1315 1070 1318 1070 1408 1070 1428 1070 1445 1070 1465 1070 1471 1071 7 1071 20 1071 31 1071 107 1071 123 1071 167 1071 170 1071 219 1071 242 1071 266 1071 292 1071 350 1071 378 1071 418 1071 446 1071 449 1071 507 1071 558 1071 570 1071 583 1071 607 1071 613 1071 621 1071 622 1071 703 1071 777 1071 791 1071 862 1071 873 1071 900 1071 903 1071 928 1071 935 1071 937 1071 1015 1071 1071 1071 1106 1071 1112 1071 1156 1071 1161 1071 1162 1071 1176 1071 1184 1071 1200 1071 1205 1071 1211 1071 1224 1071 1257 1071 1268 1071 1289 1071 1311 1071 1326 1071 1388 1071 1402 1071 1444 1071 1450 1071 1479 1071 1490 1072 27 1072 66 1072 96 1072 116 1072 127 1072 131 1072 137 1072 174 1072 228 1072 235 1072 243 1072 261 1072 263 1072 356 1072 392 1072 479 1072 486 1072 501 1072 502 1072 539 1072 552 1072 568 1072 576 1072 649 1072 678 1072 679 1072 714 1072 726 1072 746 1072 753 1072 757 1072 767 1072 775 1072 797 1072 879 1072 885 1072 909 1072 925 1072 942 1072 944 1072 946 1072 985 1072 1016 1072 1072 1072 1173 1072 1178 1072 1213 1072 1244 1072 1349 1072 1353 1072 1372 1072 1414 1073 4 1073 16 1073 71 1073 150 1073 155 1073 207 1073 248 1073 274 1073 297 1073 317 1073 331 1073 432 1073 469 1073 519 1073 588 1073 632 1073 706 1073 716 1073 738 1073 889 1073 936 1073 964 1073 977 1073 1053 1073 1073 1073 1274 1073 1322 1073 1328 1073 1357 1073 1367 1073 1416 1073 1423 1073 1451 1073 1480 1074 1 1074 100 1074 249 1074 260 1074 265 1074 417 1074 421 1074 616 1074 656 1074 672 1074 717 1074 806 1074 850 1074 855 1074 856 1074 876 1074 945 1074 1074 1074 1195 1074 1226 1074 1317 1074 1337 1074 1342 1074 1397 1074 1453 1074 1473 1075 14 1075 47 1075 52 1075 63 1075 79 1075 92 1075 125 1075 160 1075 230 1075 234 1075 240 1075 272 1075 279 1075 295 1075 373 1075 387 1075 404 1075 434 1075 441 1075 483 1075 484 1075 528 1075 569 1075 600 1075 603 1075 612 1075 624 1075 630 1075 640 1075 648 1075 690 1075 694 1075 743 1075 809 1075 882 1075 888 1075 910 1075 999 1075 1014 1075 1018 1075 1026 1075 1069 1075 1075 1075 1076 1075 1082 1075 1097 1075 1196 1075 1206 1075 1229 1075 1236 1075 1277 1075 1331 1075 1355 1075 1375 1075 1472 1075 1476 1075 1484 1076 5 1076 13 1076 14 1076 47 1076 65 1076 92 1076 160 1076 202 1076 218 1076 230 1076 234 1076 240 1076 291 1076 365 1076 373 1076 377 1076 408 1076 434 1076 441 1076 452 1076 483 1076 528 1076 569 1076 603 1076 606 1076 609 1076 612 1076 620 1076 624 1076 630 1076 648 1076 690 1076 730 1076 822 1076 882 1076 883 1076 1018 1076 1075 1076 1076 1076 1097 1076 1159 1076 1196 1076 1206 1076 1229 1076 1236 1076 1291 1076 1331 1076 1369 1076 1461 1076 1472 1076 1476 1076 1484 1077 100 1077 134 1077 260 1077 284 1077 289 1077 329 1077 337 1077 393 1077 417 1077 421 1077 445 1077 459 1077 487 1077 596 1077 616 1077 653 1077 679 1077 712 1077 717 1077 754 1077 759 1077 762 1077 806 1077 918 1077 922 1077 1042 1077 1045 1077 1077 1077 1139 1077 1226 1077 1241 1077 1315 1077 1428 1077 1438 1077 1445 1077 1470 1078 72 1078 83 1078 135 1078 217 1078 223 1078 224 1078 232 1078 253 1078 279 1078 343 1078 371 1078 377 1078 389 1078 478 1078 483 1078 497 1078 544 1078 567 1078 584 1078 592 1078 600 1078 638 1078 640 1078 648 1078 807 1078 814 1078 844 1078 860 1078 875 1078 906 1078 910 1078 940 1078 972 1078 978 1078 1034 1078 1068 1078 1078 1078 1099 1078 1142 1078 1180 1078 1198 1078 1217 1078 1356 1078 1361 1078 1373 1078 1407 1078 1441 1078 1474 1078 1496 1079 26 1079 185 1079 244 1079 251 1079 264 1079 267 1079 288 1079 355 1079 358 1079 359 1079 398 1079 436 1079 475 1079 480 1079 494 1079 546 1079 598 1079 650 1079 674 1079 676 1079 683 1079 708 1079 721 1079 758 1079 760 1079 771 1079 842 1079 895 1079 986 1079 1009 1079 1079 1079 1113 1079 1204 1079 1218 1079 1266 1079 1314 1079 1318 1079 1321 1079 1327 1079 1412 1079 1413 1079 1440 1079 1465 1079 1467 1079 1485 1080 88 1080 166 1080 168 1080 173 1080 334 1080 346 1080 409 1080 420 1080 461 1080 477 1080 489 1080 525 1080 553 1080 572 1080 659 1080 668 1080 710 1080 728 1080 737 1080 748 1080 788 1080 818 1080 899 1080 917 1080 1062 1080 1080 1080 1093 1080 1096 1080 1104 1080 1115 1080 1134 1080 1143 1080 1149 1080 1233 1080 1254 1080 1293 1080 1303 1080 1319 1080 1469 1081 6 1081 11 1081 41 1081 48 1081 94 1081 199 1081 310 1081 339 1081 382 1081 406 1081 413 1081 459 1081 510 1081 513 1081 635 1081 664 1081 713 1081 718 1081 782 1081 790 1081 810 1081 828 1081 912 1081 929 1081 1033 1081 1081 1081 1163 1081 1164 1081 1201 1081 1241 1081 1251 1081 1304 1081 1335 1081 1362 1081 1399 1082 79 1082 92 1082 125 1082 189 1082 253 1082 272 1082 279 1082 295 1082 344 1082 373 1082 387 1082 404 1082 478 1082 483 1082 484 1082 491 1082 556 1082 567 1082 591 1082 600 1082 612 1082 624 1082 640 1082 684 1082 690 1082 694 1082 743 1082 807 1082 875 1082 888 1082 910 1082 911 1082 990 1082 993 1082 1014 1082 1069 1082 1075 1082 1082 1082 1099 1082 1196 1082 1217 1082 1235 1082 1236 1082 1277 1082 1355 1082 1356 1082 1375 1082 1441 1082 1456 1082 1484 1083 0 1083 2 1083 25 1083 93 1083 98 1083 111 1083 220 1083 247 1083 362 1083 367 1083 412 1083 427 1083 450 1083 454 1083 463 1083 645 1083 663 1083 670 1083 692 1083 699 1083 794 1083 872 1083 970 1083 1012 1083 1036 1083 1050 1083 1055 1083 1083 1083 1105 1083 1133 1083 1194 1083 1197 1083 1222 1083 1253 1083 1256 1083 1260 1083 1371 1083 1385 1083 1396 1083 1398 1083 1447 1084 30 1084 38 1084 53 1084 78 1084 82 1084 102 1084 130 1084 191 1084 211 1084 212 1084 262 1084 270 1084 286 1084 308 1084 348 1084 428 1084 431 1084 451 1084 511 1084 533 1084 534 1084 549 1084 560 1084 579 1084 610 1084 626 1084 637 1084 655 1084 658 1084 685 1084 702 1084 752 1084 761 1084 778 1084 812 1084 829 1084 846 1084 863 1084 884 1084 901 1084 923 1084 983 1084 1003 1084 1024 1084 1046 1084 1057 1084 1065 1084 1084 1084 1124 1084 1131 1084 1135 1084 1137 1084 1219 1084 1249 1084 1309 1084 1336 1084 1418 1084 1459 1084 1475 1084 1481 1085 0 1085 98 1085 151 1085 185 1085 186 1085 197 1085 220 1085 238 1085 264 1085 281 1085 298 1085 301 1085 303 1085 327 1085 330 1085 338 1085 358 1085 367 1085 398 1085 442 1085 475 1085 480 1085 518 1085 546 1085 597 1085 650 1085 663 1085 674 1085 729 1085 731 1085 765 1085 771 1085 803 1085 824 1085 866 1085 892 1085 983 1085 996 1085 1011 1085 1031 1085 1085 1085 1124 1085 1145 1085 1147 1085 1263 1085 1266 1085 1271 1085 1305 1085 1330 1085 1371 1085 1400 1085 1412 1085 1413 1085 1468 1085 1488 1086 6 1086 29 1086 45 1086 51 1086 70 1086 108 1086 124 1086 186 1086 199 1086 278 1086 281 1086 303 1086 339 1086 380 1086 437 1086 438 1086 459 1086 512 1086 521 1086 545 1086 594 1086 635 1086 661 1086 676 1086 726 1086 729 1086 731 1086 810 1086 832 1086 852 1086 872 1086 880 1086 931 1086 949 1086 1052 1086 1086 1086 1163 1086 1208 1086 1239 1086 1362 1086 1399 1086 1417 1086 1468 1086 1487 1087 37 1087 122 1087 167 1087 178 1087 184 1087 319 1087 326 1087 350 1087 360 1087 376 1087 416 1087 418 1087 457 1087 503 1087 555 1087 573 1087 589 1087 593 1087 622 1087 639 1087 644 1087 703 1087 725 1087 732 1087 750 1087 756 1087 766 1087 777 1087 800 1087 886 1087 928 1087 933 1087 1010 1087 1015 1087 1020 1087 1087 1087 1107 1087 1112 1087 1166 1087 1167 1087 1185 1087 1200 1087 1205 1087 1257 1087 1268 1087 1289 1087 1311 1087 1388 1087 1457 1087 1479 1087 1483 1087 1492 1088 37 1088 49 1088 50 1088 68 1088 75 1088 141 1088 184 1088 198 1088 210 1088 294 1088 299 1088 300 1088 314 1088 333 1088 357 1088 368 1088 376 1088 433 1088 503 1088 538 1088 551 1088 559 1088 571 1088 627 1088 657 1088 671 1088 704 1088 725 1088 756 1088 766 1088 770 1088 916 1088 930 1088 1020 1088 1029 1088 1088 1088 1100 1088 1166 1088 1169 1088 1203 1088 1300 1088 1338 1088 1364 1088 1374 1088 1457 1088 1460 1088 1490 1088 1492 1088 1495 1089 38 1089 66 1089 96 1089 131 1089 137 1089 174 1089 192 1089 216 1089 261 1089 269 1089 322 1089 340 1089 356 1089 745 1089 785 1089 792 1089 851 1089 881 1089 887 1089 942 1089 1017 1089 1047 1089 1067 1089 1089 1089 1155 1089 1173 1089 1234 1089 1244 1089 1283 1089 1332 1089 1359 1089 1372 1090 22 1090 156 1090 159 1090 196 1090 266 1090 345 1090 378 1090 383 1090 396 1090 400 1090 448 1090 449 1090 507 1090 530 1090 543 1090 570 1090 604 1090 605 1090 615 1090 621 1090 669 1090 707 1090 727 1090 739 1090 791 1090 847 1090 854 1090 862 1090 873 1090 920 1090 947 1090 960 1090 994 1090 1037 1090 1090 1090 1126 1090 1172 1090 1176 1090 1267 1090 1324 1090 1325 1090 1386 1090 1434 1090 1436 1090 1444 1091 13 1091 36 1091 55 1091 83 1091 85 1091 101 1091 187 1091 218 1091 291 1091 377 1091 492 1091 497 1091 524 1091 547 1091 562 1091 608 1091 609 1091 620 1091 667 1091 730 1091 870 1091 1091 1091 1098 1091 1129 1091 1225 1091 1291 1091 1373 1091 1496 1092 17 1092 145 1092 162 1092 255 1092 322 1092 354 1092 394 1092 531 1092 561 1092 577 1092 590 1092 634 1092 711 1092 786 1092 789 1092 881 1092 887 1092 942 1092 991 1092 1092 1092 1123 1092 1125 1092 1173 1092 1213 1092 1292 1092 1414 1092 1446 1093 62 1093 88 1093 173 1093 209 1093 324 1093 420 1093 477 1093 489 1093 572 1093 581 1093 659 1093 710 1093 723 1093 728 1093 737 1093 788 1093 798 1093 818 1093 917 1093 1006 1093 1062 1093 1080 1093 1093 1093 1096 1093 1104 1093 1115 1093 1149 1093 1192 1093 1293 1093 1350 1093 1469 1094 35 1094 41 1094 100 1094 140 1094 179 1094 188 1094 199 1094 246 1094 265 1094 284 1094 310 1094 313 1094 320 1094 374 1094 382 1094 393 1094 406 1094 413 1094 487 1094 521 1094 577 1094 596 1094 688 1094 718 1094 740 1094 754 1094 762 1094 772 1094 781 1094 782 1094 790 1094 806 1094 855 1094 880 1094 894 1094 929 1094 932 1094 945 1094 963 1094 974 1094 998 1094 1004 1094 1049 1094 1094 1094 1139 1094 1158 1094 1164 1094 1223 1094 1226 1094 1251 1094 1387 1094 1438 1094 1453 1094 1473 1095 10 1095 103 1095 184 1095 210 1095 341 1095 364 1095 376 1095 542 1095 578 1095 601 1095 643 1095 666 1095 687 1095 693 1095 704 1095 750 1095 811 1095 898 1095 913 1095 915 1095 943 1095 1008 1095 1095 1095 1109 1095 1168 1095 1240 1095 1297 1095 1312 1095 1338 1095 1352 1095 1374 1095 1421 1095 1429 1095 1437 1095 1457 1095 1495 1096 88 1096 173 1096 306 1096 334 1096 420 1096 461 1096 472 1096 477 1096 489 1096 525 1096 553 1096 572 1096 659 1096 668 1096 696 1096 723 1096 728 1096 737 1096 748 1096 788 1096 804 1096 818 1096 924 1096 1062 1096 1080 1096 1093 1096 1096 1096 1104 1096 1115 1096 1143 1096 1192 1096 1254 1096 1272 1096 1285 1096 1293 1096 1303 1096 1391 1096 1405 1096 1427 1096 1469 1097 14 1097 47 1097 79 1097 160 1097 223 1097 272 1097 279 1097 295 1097 387 1097 391 1097 404 1097 408 1097 434 1097 478 1097 526 1097 600 1097 606 1097 638 1097 680 1097 694 1097 784 1097 809 1097 814 1097 822 1097 839 1097 844 1097 882 1097 888 1097 940 1097 978 1097 1075 1097 1076 1097 1097 1097 1098 1097 1142 1097 1206 1097 1216 1097 1229 1097 1236 1097 1281 1097 1370 1097 1407 1097 1441 1097 1484 1097 1498 1098 14 1098 36 1098 55 1098 56 1098 83 1098 101 1098 187 1098 218 1098 279 1098 291 1098 408 1098 441 1098 492 1098 497 1098 524 1098 526 1098 547 1098 562 1098 606 1098 608 1098 620 1098 638 1098 667 1098 680 1098 730 1098 822 1098 839 1098 867 1098 870 1098 906 1098 908 1098 972 1098 1034 1098 1091 1098 1097 1098 1098 1098 1225 1098 1299 1098 1313 1098 1348 1098 1361 1098 1373 1098 1496 1099 72 1099 83 1099 125 1099 223 1099 224 1099 272 1099 279 1099 295 1099 343 1099 371 1099 373 1099 377 1099 387 1099 389 1099 391 1099 478 1099 483 1099 544 1099 592 1099 600 1099 624 1099 638 1099 640 1099 648 1099 690 1099 694 1099 784 1099 807 1099 814 1099 844 1099 875 1099 910 1099 911 1099 940 1099 972 1099 978 1099 1014 1099 1034 1099 1068 1099 1078 1099 1082 1099 1099 1099 1142 1099 1180 1099 1196 1099 1198 1099 1217 1099 1277 1099 1299 1099 1361 1099 1373 1099 1407 1099 1441 1099 1474 1099 1484 1099 1496 1100 20 1100 31 1100 37 1100 68 1100 87 1100 170 1100 198 1100 203 1100 210 1100 294 1100 300 1100 314 1100 350 1100 357 1100 368 1100 402 1100 433 1100 538 1100 551 1100 559 1100 593 1100 627 1100 657 1100 673 1100 703 1100 736 1100 756 1100 766 1100 886 1100 916 1100 930 1100 933 1100 1029 1100 1088 1100 1100 1100 1166 1100 1169 1100 1171 1100 1188 1100 1203 1100 1211 1100 1300 1100 1402 1100 1433 1100 1460 1100 1462 1100 1490 1101 23 1101 37 1101 49 1101 75 1101 122 1101 128 1101 167 1101 178 1101 184 1101 198 1101 203 1101 219 1101 290 1101 319 1101 350 1101 360 1101 422 1101 443 1101 468 1101 503 1101 517 1101 555 1101 582 1101 593 1101 657 1101 671 1101 673 1101 693 1101 756 1101 770 1101 800 1101 805 1101 819 1101 933 1101 955 1101 1020 1101 1101 1101 1107 1101 1166 1101 1203 1101 1240 1101 1257 1101 1311 1101 1323 1101 1344 1101 1364 1101 1433 1101 1483 1102 15 1102 53 1102 54 1102 82 1102 102 1102 121 1102 191 1102 205 1102 222 1102 257 1102 312 1102 451 1102 490 1102 536 1102 563 1102 579 1102 626 1102 658 1102 685 1102 701 1102 752 1102 863 1102 934 1102 959 1102 1024 1102 1035 1102 1054 1102 1066 1102 1102 1102 1113 1102 1118 1102 1135 1102 1183 1102 1212 1102 1214 1102 1221 1102 1327 1102 1330 1102 1340 1102 1343 1102 1413 1102 1442 1102 1463 1102 1486 1103 32 1103 40 1103 115 1103 139 1103 150 1103 171 1103 177 1103 237 1103 307 1103 366 1103 453 1103 495 1103 833 1103 835 1103 848 1103 859 1103 868 1103 869 1103 926 1103 936 1103 1041 1103 1061 1103 1103 1103 1138 1103 1237 1103 1245 1103 1247 1103 1262 1103 1276 1103 1296 1103 1347 1103 1376 1103 1381 1103 1406 1103 1482 1104 62 1104 88 1104 166 1104 209 1104 324 1104 334 1104 346 1104 420 1104 426 1104 472 1104 477 1104 489 1104 553 1104 572 1104 581 1104 659 1104 696 1104 723 1104 728 1104 737 1104 788 1104 798 1104 818 1104 899 1104 917 1104 924 1104 1062 1104 1080 1104 1093 1104 1096 1104 1104 1104 1115 1104 1143 1104 1149 1104 1192 1104 1254 1104 1285 1104 1293 1104 1350 1104 1383 1104 1391 1104 1469 1105 2 1105 25 1105 97 1105 111 1105 117 1105 153 1105 194 1105 197 1105 247 1105 275 1105 282 1105 296 1105 353 1105 362 1105 372 1105 384 1105 450 1105 463 1105 499 1105 516 1105 554 1105 654 1105 662 1105 670 1105 675 1105 796 1105 970 1105 982 1105 1001 1105 1012 1105 1036 1105 1050 1105 1056 1105 1083 1105 1105 1105 1122 1105 1186 1105 1194 1105 1253 1105 1256 1105 1282 1105 1329 1105 1354 1105 1377 1105 1384 1105 1385 1105 1396 1105 1447 1105 1478 1106 7 1106 20 1106 31 1106 37 1106 75 1106 87 1106 123 1106 148 1106 167 1106 170 1106 178 1106 204 1106 219 1106 242 1106 292 1106 300 1106 333 1106 336 1106 350 1106 360 1106 378 1106 402 1106 418 1106 449 1106 583 1106 593 1106 622 1106 671 1106 673 1106 703 1106 777 1106 873 1106 886 1106 900 1106 903 1106 916 1106 928 1106 933 1106 935 1106 987 1106 1015 1106 1029 1106 1071 1106 1106 1106 1112 1106 1161 1106 1166 1106 1171 1106 1205 1106 1211 1106 1224 1106 1257 1106 1268 1106 1289 1106 1311 1106 1326 1106 1402 1106 1433 1106 1458 1106 1464 1106 1490 1107 37 1107 49 1107 68 1107 75 1107 122 1107 198 1107 203 1107 360 1107 368 1107 376 1107 443 1107 503 1107 517 1107 551 1107 555 1107 573 1107 582 1107 589 1107 657 1107 673 1107 693 1107 697 1107 725 1107 756 1107 766 1107 805 1107 836 1107 916 1107 930 1107 1020 1107 1087 1107 1101 1107 1107 1107 1166 1107 1185 1107 1203 1107 1240 1107 1246 1107 1323 1107 1352 1107 1364 1107 1374 1107 1483 1107 1492 1107 1495 1108 52 1108 63 1108 92 1108 160 1108 202 1108 230 1108 387 1108 441 1108 492 1108 569 1108 603 1108 609 1108 630 1108 642 1108 648 1108 694 1108 809 1108 870 1108 882 1108 888 1108 1028 1108 1108 1108 1265 1108 1369 1108 1472 1108 1476 1109 33 1109 61 1109 103 1109 110 1109 141 1109 169 1109 195 1109 299 1109 314 1109 341 1109 342 1109 364 1109 379 1109 447 1109 458 1109 493 1109 504 1109 542 1109 571 1109 578 1109 586 1109 643 1109 687 1109 704 1109 749 1109 811 1109 843 1109 904 1109 913 1109 915 1109 943 1109 956 1109 1095 1109 1109 1109 1168 1109 1189 1109 1269 1109 1275 1109 1297 1109 1312 1109 1338 1109 1345 1109 1352 1109 1374 1109 1420 1109 1421 1109 1437 1109 1495 1110 32 1110 34 1110 40 1110 136 1110 171 1110 207 1110 237 1110 274 1110 307 1110 423 1110 439 1110 495 1110 588 1110 744 1110 783 1110 813 1110 835 1110 848 1110 853 1110 859 1110 868 1110 869 1110 889 1110 936 1110 1041 1110 1110 1110 1138 1110 1174 1110 1237 1110 1247 1110 1255 1110 1262 1110 1276 1110 1284 1110 1296 1110 1322 1110 1347 1110 1376 1110 1422 1111 27 1111 28 1111 89 1111 127 1111 228 1111 243 1111 289 1111 470 1111 501 1111 502 1111 552 1111 679 1111 705 1111 753 1111 775 1111 789 1111 797 1111 830 1111 832 1111 879 1111 909 1111 921 1111 925 1111 931 1111 979 1111 995 1111 1111 1111 1120 1111 1286 1111 1372 1111 1392 1111 1410 1111 1414 1111 1471 1112 20 1112 31 1112 123 1112 167 1112 170 1112 178 1112 319 1112 333 1112 402 1112 416 1112 418 1112 422 1112 457 1112 555 1112 593 1112 622 1112 703 1112 736 1112 766 1112 886 1112 916 1112 933 1112 997 1112 1015 1112 1071 1112 1087 1112 1106 1112 1112 1112 1166 1112 1185 1112 1211 1112 1224 1112 1257 1112 1294 1112 1346 1112 1388 1112 1402 1112 1426 1112 1433 1112 1462 1112 1490 1112 1492 1113 26 1113 82 1113 102 1113 191 1113 200 1113 222 1113 233 1113 259 1113 312 1113 359 1113 405 1113 436 1113 465 1113 563 1113 579 1113 623 1113 658 1113 701 1113 708 1113 734 1113 752 1113 758 1113 778 1113 802 1113 863 1113 897 1113 934 1113 959 1113 1024 1113 1035 1113 1066 1113 1079 1113 1102 1113 1113 1113 1118 1113 1124 1113 1135 1113 1145 1113 1212 1113 1214 1113 1221 1113 1327 1113 1330 1113 1340 1113 1378 1113 1400 1113 1413 1113 1442 1113 1467 1113 1486 1114 39 1114 46 1114 62 1114 104 1114 105 1114 109 1114 118 1114 258 1114 309 1114 346 1114 409 1114 426 1114 489 1114 500 1114 532 1114 572 1114 710 1114 724 1114 747 1114 826 1114 899 1114 917 1114 954 1114 1025 1114 1114 1114 1128 1114 1134 1114 1149 1114 1207 1114 1233 1114 1243 1114 1270 1114 1350 1114 1368 1114 1380 1115 62 1115 88 1115 173 1115 209 1115 334 1115 420 1115 477 1115 488 1115 489 1115 572 1115 581 1115 659 1115 668 1115 728 1115 737 1115 788 1115 818 1115 917 1115 1006 1115 1051 1115 1062 1115 1080 1115 1093 1115 1096 1115 1104 1115 1115 1115 1149 1115 1192 1115 1293 1115 1469 1116 74 1116 93 1116 95 1116 111 1116 113 1116 126 1116 132 1116 194 1116 201 1116 227 1116 231 1116 241 1116 271 1116 275 1116 282 1116 306 1116 311 1116 315 1116 324 1116 362 1116 386 1116 481 1116 515 1116 516 1116 564 1116 670 1116 796 1116 801 1116 838 1116 858 1116 975 1116 1001 1116 1002 1116 1036 1116 1058 1116 1116 1116 1119 1116 1122 1116 1157 1116 1194 1116 1232 1116 1248 1116 1280 1116 1282 1116 1394 1116 1478 1117 1 1117 214 1117 236 1117 415 1117 476 1117 595 1117 793 1117 850 1117 856 1117 876 1117 981 1117 984 1117 1117 1117 1195 1117 1306 1117 1337 1117 1342 1117 1397 1118 15 1118 82 1118 90 1118 102 1118 121 1118 152 1118 222 1118 285 1118 312 1118 323 1118 327 1118 465 1118 490 1118 536 1118 655 1118 658 1118 698 1118 701 1118 702 1118 734 1118 752 1118 778 1118 802 1118 808 1118 934 1118 1003 1118 1035 1118 1044 1118 1054 1118 1102 1118 1113 1118 1118 1118 1124 1118 1135 1118 1153 1118 1212 1118 1327 1118 1330 1118 1334 1118 1340 1118 1382 1118 1442 1118 1486 1119 2 1119 74 1119 93 1119 95 1119 111 1119 113 1119 126 1119 132 1119 194 1119 201 1119 227 1119 231 1119 247 1119 282 1119 296 1119 315 1119 362 1119 384 1119 386 1119 450 1119 454 1119 463 1119 481 1119 515 1119 516 1119 564 1119 796 1119 801 1119 804 1119 838 1119 975 1119 1001 1119 1002 1119 1036 1119 1116 1119 1119 1119 1122 1119 1194 1119 1232 1119 1248 1119 1280 1119 1282 1119 1298 1119 1302 1119 1394 1119 1396 1119 1478 1120 27 1120 28 1120 89 1120 138 1120 162 1120 228 1120 321 1120 356 1120 470 1120 479 1120 498 1120 552 1120 568 1120 705 1120 714 1120 753 1120 775 1120 789 1120 797 1120 831 1120 832 1120 890 1120 909 1120 918 1120 991 1120 995 1120 1111 1120 1120 1120 1213 1120 1292 1120 1414 1120 1446 1121 142 1121 157 1121 316 1121 819 1121 877 1121 914 1121 1043 1121 1121 1121 1430 1122 2 1122 74 1122 93 1122 95 1122 111 1122 113 1122 126 1122 153 1122 194 1122 227 1122 231 1122 241 1122 247 1122 282 1122 296 1122 306 1122 315 1122 362 1122 384 1122 386 1122 450 1122 454 1122 463 1122 481 1122 515 1122 516 1122 554 1122 564 1122 566 1122 670 1122 675 1122 796 1122 801 1122 838 1122 970 1122 975 1122 982 1122 1001 1122 1002 1122 1036 1122 1050 1122 1105 1122 1116 1122 1119 1122 1122 1122 1194 1122 1248 1122 1256 1122 1280 1122 1282 1122 1298 1122 1302 1122 1394 1122 1396 1122 1478 1123 18 1123 35 1123 145 1123 146 1123 255 1123 313 1123 363 1123 411 1123 413 1123 531 1123 577 1123 634 1123 700 1123 851 1123 852 1123 881 1123 907 1123 991 1123 998 1123 1004 1123 1092 1123 1123 1123 1177 1123 1193 1123 1292 1124 0 1124 26 1124 73 1124 78 1124 82 1124 90 1124 102 1124 152 1124 200 1124 222 1124 298 1124 312 1124 327 1124 338 1124 425 1124 442 1124 451 1124 465 1124 475 1124 518 1124 536 1124 537 1124 658 1124 701 1124 702 1124 734 1124 752 1124 758 1124 761 1124 771 1124 778 1124 802 1124 884 1124 897 1124 934 1124 959 1124 967 1124 1003 1124 1035 1124 1084 1124 1085 1124 1113 1124 1118 1124 1124 1124 1135 1124 1145 1124 1212 1124 1266 1124 1271 1124 1327 1124 1330 1124 1334 1124 1382 1124 1390 1124 1400 1124 1413 1124 1442 1124 1459 1124 1481 1124 1486 1125 17 1125 96 1125 129 1125 131 1125 162 1125 172 1125 174 1125 180 1125 192 1125 255 1125 261 1125 263 1125 283 1125 304 1125 322 1125 328 1125 340 1125 352 1125 354 1125 394 1125 395 1125 399 1125 479 1125 531 1125 576 1125 590 1125 634 1125 652 1125 695 1125 711 1125 745 1125 767 1125 786 1125 792 1125 881 1125 887 1125 942 1125 969 1125 980 1125 992 1125 1067 1125 1092 1125 1125 1125 1140 1125 1155 1125 1173 1125 1209 1125 1213 1125 1244 1125 1332 1125 1351 1125 1359 1126 156 1126 159 1126 196 1126 266 1126 345 1126 383 1126 390 1126 400 1126 448 1126 543 1126 605 1126 615 1126 641 1126 707 1126 739 1126 763 1126 764 1126 847 1126 862 1126 920 1126 947 1126 960 1126 994 1126 1005 1126 1037 1126 1090 1126 1126 1126 1172 1126 1174 1126 1267 1126 1287 1126 1324 1126 1325 1126 1386 1126 1434 1126 1436 1126 1493 1127 107 1127 345 1127 507 1127 558 1127 570 1127 605 1127 607 1127 791 1127 862 1127 937 1127 947 1127 960 1127 1127 1127 1146 1127 1156 1127 1162 1127 1184 1127 1386 1127 1402 1127 1404 1128 39 1128 43 1128 46 1128 60 1128 77 1128 104 1128 109 1128 112 1128 154 1128 208 1128 258 1128 280 1128 309 1128 346 1128 369 1128 385 1128 409 1128 410 1128 500 1128 541 1128 557 1128 633 1128 724 1128 747 1128 779 1128 861 1128 878 1128 891 1128 954 1128 976 1128 989 1128 1013 1128 1025 1128 1114 1128 1128 1128 1134 1128 1148 1128 1207 1128 1210 1128 1243 1128 1279 1128 1301 1128 1310 1128 1368 1128 1380 1128 1439 1129 5 1129 12 1129 13 1129 65 1129 85 1129 165 1129 218 1129 234 1129 291 1129 365 1129 492 1129 609 1129 620 1129 642 1129 730 1129 742 1129 870 1129 939 1129 1028 1129 1091 1129 1129 1129 1159 1129 1265 1129 1291 1129 1369 1129 1461 1130 71 1130 136 1130 150 1130 207 1130 248 1130 252 1130 274 1130 297 1130 317 1130 390 1130 423 1130 432 1130 439 1130 469 1130 548 1130 588 1130 641 1130 706 1130 738 1130 813 1130 889 1130 936 1130 964 1130 977 1130 1053 1130 1130 1130 1252 1130 1255 1130 1274 1130 1284 1130 1322 1130 1328 1130 1367 1130 1416 1130 1422 1130 1480 1131 53 1131 78 1131 86 1131 191 1131 277 1131 286 1131 308 1131 349 1131 399 1131 405 1131 440 1131 444 1131 451 1131 534 1131 563 1131 579 1131 580 1131 626 1131 631 1131 720 1131 752 1131 776 1131 795 1131 829 1131 846 1131 863 1131 901 1131 923 1131 959 1131 1024 1131 1084 1131 1131 1131 1137 1131 1309 1131 1475 1131 1481 1132 3 1132 8 1132 19 1132 64 1132 97 1132 183 1132 296 1132 407 1132 473 1132 499 1132 527 1132 599 1132 614 1132 628 1132 660 1132 662 1132 709 1132 765 1132 816 1132 849 1132 951 1132 1132 1132 1227 1132 1419 1133 69 1133 119 1133 153 1133 330 1133 407 1133 427 1133 450 1133 454 1133 463 1133 516 1133 765 1133 780 1133 951 1133 1031 1133 1083 1133 1133 1133 1194 1133 1222 1133 1260 1133 1298 1133 1385 1133 1396 1134 39 1134 77 1134 104 1134 109 1134 112 1134 168 1134 215 1134 258 1134 302 1134 346 1134 409 1134 410 1134 489 1134 500 1134 917 1134 954 1134 989 1134 1025 1134 1080 1134 1114 1134 1128 1134 1134 1134 1148 1134 1207 1134 1233 1134 1301 1134 1319 1134 1350 1134 1368 1134 1405 1134 1439 1135 26 1135 53 1135 58 1135 78 1135 82 1135 86 1135 90 1135 102 1135 191 1135 193 1135 200 1135 206 1135 211 1135 222 1135 277 1135 308 1135 312 1135 323 1135 332 1135 348 1135 405 1135 425 1135 428 1135 431 1135 451 1135 465 1135 511 1135 533 1135 537 1135 549 1135 560 1135 579 1135 610 1135 626 1135 658 1135 702 1135 752 1135 761 1135 812 1135 863 1135 897 1135 901 1135 923 1135 959 1135 1003 1135 1024 1135 1035 1135 1046 1135 1054 1135 1066 1135 1084 1135 1102 1135 1113 1135 1118 1135 1124 1135 1135 1135 1212 1135 1309 1135 1327 1135 1334 1135 1336 1135 1340 1135 1459 1135 1475 1135 1481 1135 1486 1135 1494 1136 44 1136 57 1136 72 1136 76 1136 135 1136 144 1136 149 1136 224 1136 232 1136 253 1136 344 1136 370 1136 375 1136 388 1136 397 1136 424 1136 455 1136 478 1136 584 1136 591 1136 684 1136 733 1136 860 1136 893 1136 993 1136 1136 1136 1142 1136 1179 1136 1235 1136 1278 1136 1358 1136 1393 1136 1456 1137 30 1137 53 1137 86 1137 102 1137 175 1137 191 1137 193 1137 211 1137 233 1137 277 1137 308 1137 332 1137 348 1137 349 1137 399 1137 405 1137 431 1137 440 1137 444 1137 451 1137 534 1137 537 1137 563 1137 579 1137 580 1137 626 1137 631 1137 658 1137 685 1137 720 1137 812 1137 829 1137 846 1137 863 1137 884 1137 980 1137 1003 1137 1024 1137 1046 1137 1057 1137 1065 1137 1084 1137 1131 1137 1137 1137 1141 1137 1249 1137 1309 1137 1351 1137 1459 1137 1475 1137 1494 1138 32 1138 34 1138 40 1138 136 1138 139 1138 150 1138 171 1138 177 1138 207 1138 213 1138 237 1138 307 1138 317 1138 366 1138 423 1138 439 1138 453 1138 495 1138 744 1138 783 1138 813 1138 833 1138 835 1138 848 1138 853 1138 859 1138 868 1138 869 1138 889 1138 926 1138 936 1138 1041 1138 1061 1138 1103 1138 1110 1138 1138 1138 1237 1138 1247 1138 1262 1138 1276 1138 1284 1138 1296 1138 1322 1138 1347 1138 1376 1138 1381 1138 1406 1139 100 1139 134 1139 140 1139 246 1139 260 1139 310 1139 320 1139 337 1139 393 1139 406 1139 413 1139 417 1139 421 1139 445 1139 487 1139 521 1139 596 1139 616 1139 653 1139 672 1139 688 1139 717 1139 718 1139 740 1139 754 1139 762 1139 772 1139 797 1139 806 1139 855 1139 856 1139 880 1139 918 1139 922 1139 945 1139 963 1139 974 1139 998 1139 1042 1139 1045 1139 1049 1139 1077 1139 1094 1139 1139 1139 1158 1139 1181 1139 1315 1139 1387 1139 1438 1139 1445 1139 1453 1139 1470 1139 1473 1140 17 1140 129 1140 133 1140 162 1140 172 1140 180 1140 255 1140 263 1140 268 1140 283 1140 286 1140 304 1140 322 1140 328 1140 349 1140 352 1140 354 1140 394 1140 395 1140 399 1140 440 1140 464 1140 561 1140 580 1140 590 1140 625 1140 631 1140 634 1140 652 1140 681 1140 695 1140 711 1140 776 1140 786 1140 792 1140 795 1140 829 1140 865 1140 887 1140 969 1140 980 1140 992 1140 1059 1140 1125 1140 1140 1140 1199 1140 1209 1140 1316 1140 1351 1140 1446 1141 30 1141 90 1141 116 1141 174 1141 175 1141 180 1141 261 1141 270 1141 304 1141 322 1141 348 1141 349 1141 394 1141 399 1141 440 1141 444 1141 511 1141 522 1141 537 1141 580 1141 767 1141 776 1141 785 1141 792 1141 812 1141 829 1141 884 1141 897 1141 967 1141 980 1141 1003 1141 1057 1141 1137 1141 1141 1141 1199 1141 1204 1141 1209 1141 1244 1141 1261 1141 1334 1141 1359 1141 1390 1142 47 1142 72 1142 83 1142 135 1142 144 1142 149 1142 217 1142 223 1142 224 1142 232 1142 253 1142 279 1142 295 1142 305 1142 343 1142 371 1142 389 1142 397 1142 401 1142 408 1142 424 1142 455 1142 478 1142 544 1142 584 1142 591 1142 592 1142 680 1142 684 1142 733 1142 784 1142 807 1142 814 1142 822 1142 839 1142 860 1142 911 1142 940 1142 972 1142 978 1142 1014 1142 1034 1142 1068 1142 1078 1142 1097 1142 1099 1142 1136 1142 1142 1142 1180 1142 1206 1142 1216 1142 1229 1142 1235 1142 1250 1142 1281 1142 1290 1142 1356 1142 1361 1142 1370 1142 1375 1142 1407 1142 1441 1142 1474 1142 1498 1143 88 1143 166 1143 173 1143 209 1143 334 1143 420 1143 426 1143 461 1143 471 1143 472 1143 477 1143 488 1143 489 1143 553 1143 554 1143 572 1143 659 1143 675 1143 696 1143 710 1143 723 1143 728 1143 748 1143 788 1143 818 1143 899 1143 917 1143 924 1143 1040 1143 1062 1143 1080 1143 1096 1143 1104 1143 1143 1143 1191 1143 1192 1143 1254 1143 1272 1143 1285 1143 1293 1143 1303 1143 1319 1143 1391 1143 1405 1143 1427 1143 1469 1144 9 1144 15 1144 54 1144 121 1144 158 1144 182 1144 205 1144 221 1144 229 1144 262 1144 285 1144 351 1144 381 1144 462 1144 473 1144 485 1144 490 1144 599 1144 618 1144 685 1144 698 1144 735 1144 823 1144 827 1144 837 1144 849 1144 864 1144 1044 1144 1144 1144 1153 1144 1183 1144 1221 1144 1258 1144 1343 1144 1360 1144 1389 1144 1448 1144 1452 1144 1455 1144 1463 1145 0 1145 73 1145 197 1145 238 1145 264 1145 298 1145 301 1145 327 1145 330 1145 338 1145 358 1145 442 1145 475 1145 518 1145 655 1145 721 1145 765 1145 771 1145 778 1145 824 1145 866 1145 892 1145 983 1145 1011 1145 1085 1145 1113 1145 1124 1145 1145 1145 1147 1145 1212 1145 1214 1145 1222 1145 1266 1145 1271 1145 1305 1145 1330 1145 1371 1145 1400 1145 1412 1145 1413 1146 91 1146 107 1146 143 1146 326 1146 378 1146 416 1146 418 1146 507 1146 508 1146 558 1146 570 1146 607 1146 617 1146 636 1146 644 1146 732 1146 777 1146 791 1146 800 1146 854 1146 937 1146 958 1146 962 1146 997 1146 1010 1146 1015 1146 1127 1146 1146 1146 1154 1146 1162 1146 1167 1146 1200 1146 1205 1146 1268 1146 1294 1146 1346 1146 1431 1146 1444 1146 1479 1147 114 1147 197 1147 220 1147 238 1147 264 1147 281 1147 298 1147 301 1147 303 1147 327 1147 330 1147 338 1147 358 1147 442 1147 465 1147 480 1147 518 1147 598 1147 674 1147 722 1147 765 1147 803 1147 824 1147 866 1147 892 1147 996 1147 1011 1147 1031 1147 1085 1147 1145 1147 1147 1147 1218 1147 1228 1147 1263 1147 1266 1147 1271 1147 1305 1147 1371 1147 1400 1147 1412 1148 39 1148 60 1148 77 1148 109 1148 112 1148 154 1148 208 1148 215 1148 254 1148 258 1148 280 1148 346 1148 409 1148 410 1148 633 1148 724 1148 747 1148 861 1148 878 1148 891 1148 902 1148 954 1148 976 1148 989 1148 1013 1148 1025 1148 1030 1148 1128 1148 1134 1148 1148 1148 1207 1148 1210 1148 1233 1148 1301 1148 1310 1148 1319 1148 1368 1148 1439 1149 62 1149 105 1149 209 1149 254 1149 346 1149 426 1149 477 1149 489 1149 553 1149 572 1149 581 1149 659 1149 710 1149 723 1149 728 1149 737 1149 788 1149 818 1149 826 1149 899 1149 917 1149 1006 1149 1062 1149 1080 1149 1093 1149 1104 1149 1114 1149 1115 1149 1149 1149 1220 1149 1270 1149 1293 1149 1350 1149 1383 1150 43 1150 46 1150 60 1150 118 1150 154 1150 176 1150 280 1150 287 1150 369 1150 385 1150 456 1150 541 1150 557 1150 565 1150 651 1150 724 1150 747 1150 779 1150 861 1150 891 1150 902 1150 927 1150 957 1150 976 1150 1013 1150 1150 1150 1182 1150 1210 1150 1243 1150 1264 1150 1279 1150 1295 1150 1366 1150 1489 1151 91 1151 143 1151 396 1151 446 1151 508 1151 604 1151 613 1151 636 1151 644 1151 669 1151 691 1151 727 1151 841 1151 854 1151 903 1151 919 1151 937 1151 953 1151 962 1151 987 1151 1010 1151 1038 1151 1151 1151 1273 1151 1431 1151 1450 1151 1454 1152 41 1152 45 1152 106 1152 151 1152 179 1152 186 1152 188 1152 199 1152 225 1152 245 1152 249 1152 278 1152 284 1152 339 1152 380 1152 419 1152 430 1152 437 1152 459 1152 496 1152 509 1152 510 1152 545 1152 602 1152 661 1152 665 1152 682 1152 686 1152 760 1152 787 1152 790 1152 820 1152 845 1152 929 1152 949 1152 952 1152 965 1152 1022 1152 1060 1152 1063 1152 1152 1152 1190 1152 1223 1152 1251 1152 1304 1152 1408 1152 1417 1152 1487 1153 9 1153 15 1153 54 1153 73 1153 121 1153 158 1153 182 1153 205 1153 221 1153 229 1153 285 1153 351 1153 381 1153 462 1153 485 1153 490 1153 536 1153 618 1153 619 1153 685 1153 698 1153 701 1153 735 1153 823 1153 827 1153 837 1153 864 1153 1044 1153 1118 1153 1144 1153 1153 1153 1183 1153 1221 1153 1258 1153 1343 1153 1382 1153 1389 1153 1442 1153 1448 1153 1452 1153 1463 1154 91 1154 123 1154 143 1154 167 1154 178 1154 219 1154 326 1154 350 1154 378 1154 416 1154 418 1154 422 1154 508 1154 593 1154 617 1154 621 1154 622 1154 636 1154 644 1154 732 1154 777 1154 900 1154 928 1154 935 1154 958 1154 962 1154 997 1154 1010 1154 1015 1154 1146 1154 1154 1154 1176 1154 1200 1154 1205 1154 1211 1154 1257 1154 1268 1154 1289 1154 1294 1154 1311 1154 1326 1154 1388 1154 1426 1154 1431 1154 1479 1155 42 1155 129 1155 131 1155 145 1155 172 1155 180 1155 192 1155 255 1155 261 1155 269 1155 340 1155 352 1155 394 1155 395 1155 531 1155 576 1155 590 1155 700 1155 745 1155 767 1155 769 1155 851 1155 969 1155 1039 1155 1067 1155 1089 1155 1125 1155 1155 1155 1173 1155 1178 1155 1193 1155 1209 1155 1353 1155 1466 1155 1499 1156 7 1156 107 1156 148 1156 170 1156 242 1156 292 1156 446 1156 449 1156 507 1156 558 1156 570 1156 607 1156 613 1156 763 1156 791 1156 862 1156 900 1156 937 1156 1071 1156 1127 1156 1156 1156 1161 1156 1162 1156 1176 1156 1184 1156 1224 1156 1402 1156 1404 1156 1431 1156 1444 1156 1450 1156 1464 1157 74 1157 84 1157 93 1157 95 1157 120 1157 194 1157 201 1157 239 1157 241 1157 271 1157 293 1157 306 1157 311 1157 315 1157 488 1157 515 1157 554 1157 564 1157 647 1157 675 1157 677 1157 719 1157 858 1157 971 1157 975 1157 1001 1157 1023 1157 1058 1157 1116 1157 1157 1157 1192 1157 1248 1157 1307 1157 1329 1157 1354 1157 1377 1157 1394 1157 1424 1157 1435 1158 35 1158 81 1158 94 1158 100 1158 140 1158 179 1158 226 1158 245 1158 246 1158 265 1158 276 1158 284 1158 310 1158 313 1158 320 1158 321 1158 374 1158 382 1158 393 1158 406 1158 417 1158 445 1158 487 1158 540 1158 596 1158 616 1158 664 1158 688 1158 713 1158 718 1158 740 1158 754 1158 762 1158 772 1158 781 1158 782 1158 790 1158 806 1158 880 1158 894 1158 929 1158 932 1158 945 1158 952 1158 963 1158 974 1158 998 1158 1022 1158 1032 1158 1045 1158 1049 1158 1094 1158 1139 1158 1158 1158 1181 1158 1201 1158 1223 1158 1251 1158 1335 1158 1387 1158 1453 1159 5 1159 12 1159 13 1159 14 1159 65 1159 85 1159 92 1159 160 1159 165 1159 218 1159 234 1159 240 1159 291 1159 365 1159 377 1159 434 1159 441 1159 452 1159 492 1159 528 1159 544 1159 603 1159 606 1159 609 1159 612 1159 624 1159 630 1159 642 1159 648 1159 730 1159 742 1159 882 1159 883 1159 939 1159 1028 1159 1076 1159 1129 1159 1159 1159 1196 1159 1236 1159 1265 1159 1291 1159 1369 1159 1461 1160 6 1160 28 1160 42 1160 45 1160 89 1160 124 1160 127 1160 263 1160 268 1160 380 1160 392 1160 470 1160 501 1160 502 1160 505 1160 540 1160 575 1160 576 1160 649 1160 678 1160 681 1160 686 1160 689 1160 722 1160 753 1160 757 1160 775 1160 786 1160 810 1160 830 1160 831 1160 865 1160 896 1160 921 1160 931 1160 950 1160 965 1160 968 1160 986 1160 992 1160 995 1160 1007 1160 1009 1160 1039 1160 1060 1160 1160 1160 1201 1160 1349 1160 1425 1160 1446 1160 1449 1161 7 1161 20 1161 31 1161 37 1161 148 1161 167 1161 170 1161 204 1161 219 1161 242 1161 292 1161 336 1161 350 1161 360 1161 416 1161 418 1161 446 1161 558 1161 593 1161 607 1161 613 1161 639 1161 644 1161 671 1161 703 1161 777 1161 886 1161 900 1161 928 1161 987 1161 1015 1161 1071 1161 1106 1161 1156 1161 1161 1161 1171 1161 1184 1161 1200 1161 1205 1161 1211 1161 1224 1161 1257 1161 1268 1161 1273 1161 1289 1161 1311 1161 1326 1161 1346 1161 1388 1161 1402 1161 1404 1161 1426 1161 1431 1161 1450 1161 1464 1161 1479 1161 1490 1162 22 1162 107 1162 143 1162 266 1162 378 1162 449 1162 507 1162 543 1162 558 1162 570 1162 607 1162 621 1162 791 1162 854 1162 862 1162 873 1162 900 1162 935 1162 937 1162 1071 1162 1127 1162 1146 1162 1156 1162 1162 1162 1176 1162 1184 1162 1224 1162 1289 1162 1294 1162 1386 1162 1444 1162 1464 1163 6 1163 42 1163 48 1163 94 1163 108 1163 163 1163 256 1163 278 1163 303 1163 310 1163 320 1163 339 1163 437 1163 512 1163 521 1163 523 1163 545 1163 635 1163 664 1163 688 1163 713 1163 718 1163 740 1163 757 1163 782 1163 810 1163 852 1163 880 1163 961 1163 1033 1163 1045 1163 1049 1163 1052 1163 1081 1163 1086 1163 1163 1163 1181 1163 1201 1163 1208 1163 1239 1163 1335 1163 1362 1163 1399 1164 35 1164 41 1164 45 1164 199 1164 284 1164 313 1164 363 1164 374 1164 380 1164 382 1164 411 1164 413 1164 521 1164 594 1164 695 1164 726 1164 741 1164 772 1164 781 1164 782 1164 790 1164 929 1164 1048 1164 1081 1164 1094 1164 1164 1164 1223 1164 1399 1165 66 1165 86 1165 96 1165 116 1165 193 1165 206 1165 211 1165 250 1165 323 1165 356 1165 425 1165 444 1165 502 1165 539 1165 625 1165 678 1165 830 1165 879 1165 887 1165 938 1165 942 1165 985 1165 1047 1165 1064 1165 1165 1165 1204 1165 1244 1165 1283 1165 1332 1165 1341 1166 20 1166 23 1166 31 1166 37 1166 49 1166 75 1166 123 1166 128 1166 167 1166 170 1166 178 1166 184 1166 198 1166 203 1166 219 1166 290 1166 319 1166 350 1166 357 1166 360 1166 376 1166 402 1166 416 1166 422 1166 443 1166 457 1166 503 1166 517 1166 551 1166 555 1166 559 1166 582 1166 589 1166 593 1166 622 1166 627 1166 657 1166 671 1166 673 1166 703 1166 725 1166 756 1166 766 1166 770 1166 800 1166 805 1166 886 1166 898 1166 916 1166 928 1166 933 1166 1020 1166 1087 1166 1088 1166 1100 1166 1101 1166 1106 1166 1107 1166 1112 1166 1166 1166 1171 1166 1185 1166 1200 1166 1203 1166 1205 1166 1211 1166 1257 1166 1311 1166 1388 1166 1429 1166 1433 1166 1457 1166 1483 1166 1490 1166 1492 1167 91 1167 143 1167 167 1167 219 1167 326 1167 350 1167 360 1167 416 1167 418 1167 446 1167 508 1167 555 1167 574 1167 589 1167 636 1167 639 1167 644 1167 732 1167 777 1167 800 1167 886 1167 928 1167 933 1167 953 1167 958 1167 987 1167 1010 1167 1087 1167 1146 1167 1167 1167 1185 1167 1200 1167 1205 1167 1211 1167 1257 1167 1268 1167 1273 1167 1311 1167 1346 1167 1388 1167 1431 1167 1479 1168 10 1168 103 1168 141 1168 195 1168 299 1168 341 1168 342 1168 364 1168 379 1168 447 1168 504 1168 542 1168 578 1168 582 1168 643 1168 666 1168 687 1168 693 1168 697 1168 704 1168 749 1168 811 1168 898 1168 913 1168 915 1168 943 1168 1008 1168 1095 1168 1109 1168 1168 1168 1240 1168 1246 1168 1269 1168 1275 1168 1297 1168 1312 1168 1352 1168 1374 1168 1420 1168 1421 1168 1437 1168 1495 1169 37 1169 87 1169 203 1169 204 1169 292 1169 294 1169 300 1169 403 1169 559 1169 574 1169 671 1169 819 1169 836 1169 930 1169 953 1169 987 1169 1029 1169 1088 1169 1100 1169 1169 1169 1171 1169 1188 1169 1203 1169 1273 1169 1300 1169 1379 1169 1458 1169 1460 1169 1490 1170 11 1170 21 1170 80 1170 94 1170 114 1170 163 1170 179 1170 225 1170 226 1170 245 1170 249 1170 276 1170 310 1170 339 1170 347 1170 412 1170 445 1170 467 1170 509 1170 653 1170 656 1170 664 1170 712 1170 713 1170 754 1170 768 1170 787 1170 821 1170 825 1170 845 1170 912 1170 949 1170 952 1170 966 1170 1012 1170 1022 1170 1032 1170 1033 1170 1045 1170 1063 1170 1170 1170 1175 1170 1190 1170 1288 1170 1308 1170 1335 1171 7 1171 20 1171 31 1171 37 1171 87 1171 148 1171 167 1171 170 1171 178 1171 203 1171 204 1171 219 1171 242 1171 292 1171 300 1171 333 1171 336 1171 350 1171 360 1171 416 1171 418 1171 443 1171 593 1171 613 1171 644 1171 671 1171 703 1171 756 1171 777 1171 805 1171 819 1171 886 1171 900 1171 916 1171 928 1171 987 1171 1015 1171 1029 1171 1100 1171 1106 1171 1161 1171 1166 1171 1169 1171 1171 1171 1205 1171 1211 1171 1257 1171 1268 1171 1273 1171 1289 1171 1294 1171 1311 1171 1326 1171 1402 1171 1426 1171 1431 1171 1464 1171 1490 1172 159 1172 196 1172 252 1172 345 1172 383 1172 390 1172 400 1172 448 1172 605 1172 615 1172 641 1172 707 1172 739 1172 764 1172 847 1172 920 1172 947 1172 960 1172 1037 1172 1090 1172 1126 1172 1172 1172 1174 1172 1252 1172 1267 1172 1325 1172 1386 1172 1434 1172 1436 1173 66 1173 96 1173 124 1173 129 1173 131 1173 145 1173 180 1173 261 1173 263 1173 322 1173 356 1173 392 1173 394 1173 479 1173 486 1173 531 1173 539 1173 576 1173 634 1173 649 1173 714 1173 726 1173 741 1173 746 1173 757 1173 786 1173 797 1173 881 1173 942 1173 944 1173 946 1173 969 1173 991 1173 992 1173 1067 1173 1072 1173 1089 1173 1092 1173 1125 1173 1155 1173 1173 1173 1178 1173 1209 1173 1213 1173 1244 1173 1292 1173 1353 1173 1372 1174 34 1174 136 1174 159 1174 196 1174 252 1174 383 1174 390 1174 400 1174 439 1174 448 1174 495 1174 543 1174 588 1174 615 1174 641 1174 764 1174 783 1174 813 1174 847 1174 868 1174 947 1174 1110 1174 1126 1174 1172 1174 1174 1174 1252 1174 1255 1174 1284 1174 1287 1174 1325 1174 1386 1174 1422 1174 1434 1174 1436 1174 1493 1175 80 1175 114 1175 181 1175 225 1175 226 1175 249 1175 329 1175 347 1175 430 1175 467 1175 509 1175 602 1175 653 1175 656 1175 664 1175 665 1175 692 1175 712 1175 820 1175 825 1175 845 1175 966 1175 1019 1175 1063 1175 1170 1175 1175 1175 1288 1175 1308 1175 1317 1175 1428 1176 22 1176 107 1176 143 1176 156 1176 266 1176 378 1176 446 1176 449 1176 507 1176 530 1176 543 1176 558 1176 570 1176 604 1176 607 1176 613 1176 617 1176 621 1176 739 1176 791 1176 854 1176 862 1176 873 1176 900 1176 903 1176 920 1176 935 1176 937 1176 948 1176 962 1176 994 1176 1071 1176 1090 1176 1154 1176 1156 1176 1162 1176 1176 1176 1184 1176 1224 1176 1289 1176 1294 1176 1324 1176 1326 1176 1386 1176 1444 1176 1464 1177 18 1177 146 1177 246 1177 313 1177 320 1177 363 1177 512 1177 688 1177 700 1177 740 1177 851 1177 852 1177 856 1177 876 1177 907 1177 945 1177 974 1177 998 1177 1004 1177 1123 1177 1177 1177 1193 1177 1306 1177 1387 1177 1453 1177 1466 1177 1473 1178 24 1178 116 1178 124 1178 129 1178 131 1178 137 1178 145 1178 172 1178 180 1178 235 1178 261 1178 269 1178 323 1178 325 1178 340 1178 356 1178 486 1178 522 1178 539 1178 576 1178 731 1178 745 1178 767 1178 769 1178 771 1178 885 1178 944 1178 983 1178 985 1178 1052 1178 1064 1178 1072 1178 1155 1178 1173 1178 1178 1178 1244 1178 1261 1178 1333 1178 1339 1178 1353 1178 1403 1178 1468 1179 56 1179 57 1179 72 1179 76 1179 135 1179 144 1179 149 1179 164 1179 232 1179 343 1179 370 1179 388 1179 397 1179 401 1179 424 1179 455 1179 520 1179 584 1179 592 1179 611 1179 638 1179 733 1179 860 1179 893 1179 906 1179 940 1179 972 1179 1136 1179 1179 1179 1198 1179 1230 1179 1235 1179 1358 1179 1393 1180 55 1180 72 1180 83 1180 135 1180 164 1180 223 1180 224 1180 279 1180 305 1180 343 1180 371 1180 387 1180 389 1180 391 1180 408 1180 441 1180 478 1180 483 1180 520 1180 547 1180 556 1180 592 1180 600 1180 638 1180 640 1180 648 1180 680 1180 690 1180 694 1180 784 1180 814 1180 844 1180 906 1180 910 1180 911 1180 940 1180 972 1180 978 1180 1014 1180 1034 1180 1068 1180 1078 1180 1099 1180 1142 1180 1180 1180 1198 1180 1206 1180 1217 1180 1230 1180 1277 1180 1299 1180 1361 1180 1370 1180 1407 1180 1441 1180 1474 1180 1496 1181 21 1181 48 1181 94 1181 100 1181 140 1181 163 1181 179 1181 226 1181 246 1181 276 1181 310 1181 320 1181 339 1181 393 1181 406 1181 413 1181 417 1181 496 1181 521 1181 596 1181 653 1181 664 1181 688 1181 712 1181 713 1181 718 1181 740 1181 746 1181 754 1181 762 1181 772 1181 781 1181 806 1181 810 1181 880 1181 952 1181 961 1181 963 1181 974 1181 1033 1181 1045 1181 1049 1181 1052 1181 1139 1181 1158 1181 1163 1181 1181 1181 1201 1181 1208 1181 1239 1181 1251 1181 1335 1181 1362 1181 1363 1181 1387 1181 1453 1182 43 1182 46 1182 118 1182 176 1182 236 1182 258 1182 309 1182 369 1182 500 1182 532 1182 557 1182 565 1182 595 1182 651 1182 724 1182 747 1182 779 1182 902 1182 927 1182 957 1182 981 1182 984 1182 1150 1182 1182 1182 1220 1182 1243 1182 1264 1182 1270 1182 1279 1182 1366 1182 1368 1182 1380 1182 1489 1183 9 1183 15 1183 53 1183 54 1183 78 1183 82 1183 102 1183 121 1183 130 1183 158 1183 182 1183 191 1183 205 1183 221 1183 229 1183 257 1183 262 1183 285 1183 308 1183 351 1183 428 1183 451 1183 462 1183 485 1183 490 1183 511 1183 533 1183 536 1183 579 1183 610 1183 618 1183 619 1183 685 1183 698 1183 701 1183 752 1183 761 1183 812 1183 823 1183 827 1183 837 1183 863 1183 864 1183 901 1183 905 1183 1003 1183 1044 1183 1066 1183 1102 1183 1144 1183 1153 1183 1183 1183 1212 1183 1221 1183 1258 1183 1340 1183 1343 1183 1360 1183 1448 1183 1452 1183 1459 1184 7 1184 20 1184 31 1184 87 1184 107 1184 148 1184 170 1184 242 1184 292 1184 333 1184 336 1184 378 1184 403 1184 449 1184 507 1184 548 1184 558 1184 607 1184 763 1184 791 1184 862 1184 873 1184 900 1184 960 1184 1071 1184 1127 1184 1156 1184 1161 1184 1162 1184 1176 1184 1184 1184 1224 1184 1402 1184 1404 1184 1444 1184 1450 1184 1464 1185 23 1185 37 1185 122 1185 167 1185 178 1185 184 1185 319 1185 350 1185 360 1185 376 1185 422 1185 443 1185 457 1185 503 1185 555 1185 573 1185 589 1185 593 1185 622 1185 627 1185 639 1185 657 1185 703 1185 725 1185 750 1185 756 1185 766 1185 777 1185 800 1185 805 1185 886 1185 898 1185 1087 1185 1107 1185 1112 1185 1166 1185 1167 1185 1185 1185 1200 1185 1205 1185 1211 1185 1257 1185 1300 1185 1311 1185 1457 1185 1479 1185 1483 1185 1492 1186 2 1186 25 1186 97 1186 111 1186 114 1186 117 1186 153 1186 194 1186 197 1186 220 1186 241 1186 247 1186 362 1186 384 1186 407 1186 450 1186 454 1186 463 1186 499 1186 516 1186 554 1186 566 1186 654 1186 663 1186 670 1186 675 1186 721 1186 780 1186 794 1186 796 1186 825 1186 951 1186 970 1186 982 1186 1001 1186 1012 1186 1036 1186 1050 1186 1105 1186 1186 1186 1222 1186 1256 1186 1260 1186 1298 1186 1302 1186 1329 1186 1384 1186 1385 1186 1396 1186 1447 1187 58 1187 90 1187 192 1187 262 1187 269 1187 323 1187 340 1187 506 1187 637 1187 785 1187 808 1187 1187 1187 1219 1187 1234 1187 1249 1187 1334 1187 1360 1187 1401 1187 1415 1188 20 1188 50 1188 71 1188 87 1188 141 1188 148 1188 203 1188 204 1188 292 1188 294 1188 300 1188 333 1188 336 1188 357 1188 403 1188 433 1188 514 1188 519 1188 538 1188 571 1188 763 1188 916 1188 977 1188 1100 1188 1169 1188 1188 1188 1224 1188 1357 1188 1367 1188 1402 1188 1404 1188 1423 1188 1458 1188 1462 1188 1490 1189 10 1189 33 1189 50 1189 61 1189 68 1189 141 1189 195 1189 210 1189 290 1189 299 1189 341 1189 342 1189 364 1189 379 1189 447 1189 493 1189 504 1189 514 1189 559 1189 571 1189 578 1189 704 1189 749 1189 904 1189 913 1189 915 1189 1109 1189 1189 1189 1269 1189 1300 1189 1312 1189 1338 1189 1374 1189 1420 1189 1437 1189 1460 1189 1495 1190 41 1190 81 1190 99 1190 106 1190 151 1190 179 1190 188 1190 199 1190 225 1190 245 1190 249 1190 278 1190 318 1190 329 1190 337 1190 339 1190 419 1190 430 1190 509 1190 510 1190 550 1190 602 1190 661 1190 665 1190 682 1190 686 1190 760 1190 768 1190 787 1190 790 1190 820 1190 922 1190 929 1190 949 1190 950 1190 952 1190 1019 1190 1022 1190 1032 1190 1042 1190 1048 1190 1063 1190 1070 1190 1152 1190 1170 1190 1190 1190 1223 1190 1241 1190 1251 1190 1288 1190 1304 1190 1408 1190 1428 1190 1445 1190 1471 1190 1487 1191 166 1191 334 1191 461 1191 471 1191 654 1191 660 1191 662 1191 668 1191 696 1191 748 1191 1040 1191 1143 1191 1191 1191 1254 1191 1272 1191 1285 1191 1302 1191 1303 1191 1308 1191 1319 1191 1329 1191 1405 1191 1427 1191 1469 1192 74 1192 84 1192 88 1192 173 1192 201 1192 209 1192 293 1192 306 1192 334 1192 420 1192 461 1192 472 1192 477 1192 488 1192 525 1192 553 1192 554 1192 572 1192 581 1192 647 1192 659 1192 668 1192 675 1192 723 1192 728 1192 737 1192 788 1192 798 1192 818 1192 924 1192 971 1192 1006 1192 1051 1192 1062 1192 1093 1192 1096 1192 1104 1192 1115 1192 1143 1192 1157 1192 1192 1192 1285 1192 1293 1192 1303 1192 1469 1193 18 1193 146 1193 192 1193 255 1193 531 1193 700 1193 851 1193 876 1193 907 1193 1004 1193 1123 1193 1155 1193 1177 1193 1193 1193 1306 1193 1466 1194 2 1194 93 1194 95 1194 111 1194 117 1194 126 1194 153 1194 194 1194 231 1194 247 1194 282 1194 296 1194 362 1194 384 1194 427 1194 450 1194 454 1194 463 1194 516 1194 564 1194 670 1194 796 1194 801 1194 838 1194 970 1194 975 1194 982 1194 1001 1194 1036 1194 1050 1194 1083 1194 1105 1194 1116 1194 1119 1194 1122 1194 1133 1194 1194 1194 1222 1194 1248 1194 1253 1194 1256 1194 1260 1194 1280 1194 1282 1194 1298 1194 1384 1194 1385 1194 1394 1194 1396 1194 1478 1195 1 1195 100 1195 214 1195 260 1195 265 1195 417 1195 421 1195 476 1195 616 1195 653 1195 672 1195 712 1195 793 1195 806 1195 850 1195 856 1195 876 1195 1051 1195 1074 1195 1117 1195 1195 1195 1306 1195 1317 1195 1337 1195 1342 1195 1387 1195 1397 1195 1438 1195 1473 1196 14 1196 47 1196 79 1196 92 1196 125 1196 160 1196 165 1196 230 1196 240 1196 272 1196 279 1196 295 1196 373 1196 387 1196 404 1196 441 1196 483 1196 484 1196 528 1196 556 1196 569 1196 600 1196 603 1196 606 1196 612 1196 624 1196 630 1196 640 1196 648 1196 690 1196 694 1196 807 1196 809 1196 844 1196 882 1196 910 1196 911 1196 999 1196 1018 1196 1075 1196 1076 1196 1082 1196 1099 1196 1159 1196 1196 1196 1236 1196 1277 1196 1375 1196 1441 1196 1472 1196 1476 1196 1484 1197 98 1197 185 1197 186 1197 278 1197 288 1197 367 1197 398 1197 419 1197 437 1197 480 1197 529 1197 546 1197 597 1197 645 1197 650 1197 663 1197 676 1197 682 1197 683 1197 699 1197 760 1197 821 1197 842 1197 845 1197 996 1197 1060 1197 1063 1197 1083 1197 1197 1197 1263 1197 1398 1197 1417 1197 1440 1197 1465 1198 56 1198 72 1198 101 1198 164 1198 217 1198 223 1198 343 1198 389 1198 391 1198 408 1198 497 1198 520 1198 524 1198 547 1198 584 1198 592 1198 638 1198 680 1198 844 1198 867 1198 906 1198 908 1198 972 1198 1034 1198 1068 1198 1078 1198 1099 1198 1179 1198 1180 1198 1198 1198 1230 1198 1299 1198 1361 1198 1441 1198 1474 1198 1496 1199 116 1199 133 1199 138 1199 244 1199 283 1199 304 1199 349 1199 355 1199 394 1199 399 1199 522 1199 575 1199 580 1199 590 1199 623 1199 652 1199 681 1199 695 1199 708 1199 795 1199 829 1199 865 1199 980 1199 992 1199 995 1199 1007 1199 1059 1199 1140 1199 1141 1199 1199 1199 1204 1199 1271 1199 1316 1199 1378 1199 1425 1199 1467 1200 49 1200 122 1200 167 1200 219 1200 319 1200 326 1200 350 1200 360 1200 416 1200 418 1200 443 1200 457 1200 508 1200 555 1200 573 1200 589 1200 622 1200 639 1200 644 1200 725 1200 732 1200 777 1200 800 1200 805 1200 886 1200 928 1200 933 1200 958 1200 997 1200 1010 1200 1015 1200 1071 1200 1087 1200 1146 1200 1154 1200 1161 1200 1166 1200 1167 1200 1185 1200 1200 1200 1205 1200 1257 1200 1268 1200 1273 1200 1311 1200 1346 1200 1388 1200 1431 1200 1479 1200 1483 1201 6 1201 21 1201 42 1201 48 1201 94 1201 124 1201 127 1201 140 1201 256 1201 276 1201 303 1201 310 1201 339 1201 374 1201 382 1201 392 1201 406 1201 413 1201 496 1201 501 1201 535 1201 540 1201 635 1201 664 1201 695 1201 713 1201 718 1201 746 1201 753 1201 757 1201 782 1201 786 1201 790 1201 810 1201 828 1201 831 1201 929 1201 961 1201 1033 1201 1039 1201 1045 1201 1052 1201 1081 1201 1158 1201 1160 1201 1163 1201 1181 1201 1201 1201 1208 1201 1241 1201 1251 1201 1349 1201 1362 1201 1363 1201 1372 1201 1399 1202 44 1202 57 1202 147 1202 344 1202 375 1202 388 1202 491 1202 799 1202 893 1202 990 1202 993 1202 1027 1202 1202 1202 1278 1202 1355 1202 1358 1202 1456 1203 20 1203 37 1203 49 1203 50 1203 68 1203 75 1203 128 1203 141 1203 198 1203 203 1203 204 1203 290 1203 294 1203 300 1203 314 1203 333 1203 357 1203 360 1203 368 1203 402 1203 433 1203 443 1203 538 1203 551 1203 555 1203 559 1203 571 1203 582 1203 657 1203 671 1203 673 1203 697 1203 703 1203 756 1203 805 1203 836 1203 916 1203 930 1203 1020 1203 1088 1203 1100 1203 1101 1203 1107 1203 1166 1203 1169 1203 1203 1203 1257 1203 1273 1203 1300 1203 1364 1203 1379 1203 1433 1203 1460 1203 1483 1203 1490 1204 26 1204 30 1204 116 1204 174 1204 175 1204 206 1204 233 1204 264 1204 267 1204 325 1204 327 1204 332 1204 355 1204 356 1204 425 1204 429 1204 444 1204 475 1204 522 1204 537 1204 539 1204 568 1204 629 1204 646 1204 708 1204 755 1204 758 1204 776 1204 817 1204 824 1204 884 1204 885 1204 897 1204 967 1204 980 1204 1007 1204 1057 1204 1064 1204 1079 1204 1141 1204 1165 1204 1199 1204 1204 1204 1244 1204 1266 1204 1316 1204 1318 1204 1339 1204 1403 1204 1468 1205 37 1205 91 1205 167 1205 178 1205 219 1205 242 1205 319 1205 326 1205 350 1205 360 1205 416 1205 418 1205 457 1205 508 1205 555 1205 589 1205 593 1205 617 1205 622 1205 639 1205 644 1205 703 1205 732 1205 777 1205 800 1205 805 1205 886 1205 900 1205 928 1205 933 1205 958 1205 997 1205 1010 1205 1015 1205 1071 1205 1087 1205 1106 1205 1146 1205 1154 1205 1161 1205 1166 1205 1167 1205 1171 1205 1185 1205 1200 1205 1205 1205 1211 1205 1257 1205 1268 1205 1273 1205 1289 1205 1311 1205 1346 1205 1388 1205 1426 1205 1431 1205 1479 1206 14 1206 47 1206 79 1206 92 1206 160 1206 223 1206 279 1206 305 1206 373 1206 387 1206 391 1206 408 1206 434 1206 441 1206 478 1206 483 1206 556 1206 567 1206 600 1206 612 1206 630 1206 638 1206 680 1206 690 1206 784 1206 807 1206 809 1206 822 1206 839 1206 844 1206 883 1206 911 1206 978 1206 1014 1206 1018 1206 1075 1206 1076 1206 1097 1206 1142 1206 1180 1206 1206 1206 1217 1206 1229 1206 1230 1206 1236 1206 1277 1206 1281 1206 1290 1206 1369 1206 1370 1206 1441 1206 1474 1206 1484 1206 1498 1207 39 1207 62 1207 77 1207 105 1207 109 1207 112 1207 208 1207 215 1207 254 1207 258 1207 280 1207 302 1207 346 1207 409 1207 410 1207 426 1207 456 1207 633 1207 724 1207 747 1207 779 1207 826 1207 861 1207 878 1207 891 1207 899 1207 917 1207 954 1207 976 1207 989 1207 1025 1207 1030 1207 1114 1207 1128 1207 1134 1207 1148 1207 1207 1207 1233 1207 1301 1207 1310 1207 1350 1207 1368 1207 1383 1207 1439 1208 6 1208 21 1208 29 1208 42 1208 48 1208 51 1208 70 1208 94 1208 98 1208 151 1208 179 1208 186 1208 245 1208 256 1208 276 1208 278 1208 281 1208 303 1208 321 1208 339 1208 358 1208 412 1208 419 1208 437 1208 496 1208 512 1208 545 1208 597 1208 635 1208 661 1208 664 1208 713 1208 718 1208 729 1208 731 1208 768 1208 782 1208 810 1208 821 1208 828 1208 832 1208 880 1208 949 1208 961 1208 1011 1208 1032 1208 1033 1208 1045 1208 1052 1208 1063 1208 1086 1208 1163 1208 1181 1208 1201 1208 1208 1208 1239 1208 1251 1208 1362 1208 1363 1208 1399 1208 1417 1208 1487 1208 1488 1209 17 1209 38 1209 96 1209 129 1209 131 1209 133 1209 162 1209 172 1209 174 1209 180 1209 192 1209 255 1209 261 1209 263 1209 304 1209 322 1209 328 1209 349 1209 352 1209 354 1209 394 1209 395 1209 399 1209 464 1209 522 1209 561 1209 576 1209 590 1209 634 1209 652 1209 695 1209 711 1209 745 1209 767 1209 786 1209 792 1209 881 1209 887 1209 944 1209 969 1209 980 1209 992 1209 1067 1209 1125 1209 1140 1209 1141 1209 1155 1209 1173 1209 1209 1209 1244 1209 1351 1209 1353 1209 1359 1210 43 1210 60 1210 77 1210 118 1210 154 1210 176 1210 208 1210 280 1210 287 1210 369 1210 385 1210 410 1210 456 1210 541 1210 557 1210 565 1210 633 1210 651 1210 724 1210 747 1210 779 1210 861 1210 878 1210 891 1210 902 1210 927 1210 957 1210 976 1210 1013 1210 1025 1210 1030 1210 1128 1210 1148 1210 1150 1210 1210 1210 1279 1210 1295 1210 1310 1210 1366 1210 1380 1210 1439 1210 1489 1211 7 1211 20 1211 31 1211 37 1211 87 1211 123 1211 148 1211 167 1211 170 1211 178 1211 204 1211 219 1211 242 1211 292 1211 326 1211 350 1211 360 1211 416 1211 418 1211 443 1211 446 1211 508 1211 555 1211 583 1211 593 1211 622 1211 644 1211 671 1211 673 1211 703 1211 756 1211 777 1211 886 1211 900 1211 903 1211 916 1211 928 1211 933 1211 935 1211 958 1211 987 1211 1015 1211 1029 1211 1071 1211 1100 1211 1106 1211 1112 1211 1154 1211 1161 1211 1166 1211 1167 1211 1171 1211 1185 1211 1205 1211 1211 1211 1257 1211 1268 1211 1273 1211 1289 1211 1311 1211 1326 1211 1402 1211 1426 1211 1431 1211 1433 1211 1458 1211 1464 1211 1490 1212 54 1212 78 1212 82 1212 102 1212 121 1212 152 1212 191 1212 200 1212 205 1212 222 1212 259 1212 312 1212 338 1212 490 1212 536 1212 563 1212 579 1212 655 1212 658 1212 685 1212 698 1212 701 1212 734 1212 752 1212 761 1212 778 1212 802 1212 863 1212 897 1212 934 1212 959 1212 1035 1212 1054 1212 1066 1212 1102 1212 1113 1212 1118 1212 1124 1212 1135 1212 1145 1212 1183 1212 1212 1212 1214 1212 1221 1212 1327 1212 1330 1212 1340 1212 1343 1212 1382 1212 1400 1212 1413 1212 1442 1212 1481 1212 1486 1213 17 1213 27 1213 66 1213 96 1213 124 1213 127 1213 131 1213 162 1213 243 1213 263 1213 289 1213 392 1213 394 1213 413 1213 479 1213 486 1213 501 1213 577 1213 634 1213 649 1213 679 1213 726 1213 741 1213 746 1213 757 1213 772 1213 775 1213 786 1213 789 1213 797 1213 830 1213 879 1213 881 1213 887 1213 942 1213 946 1213 991 1213 1016 1213 1072 1213 1092 1213 1120 1213 1125 1213 1173 1213 1213 1213 1292 1213 1332 1213 1372 1213 1410 1213 1414 1213 1446 1214 19 1214 73 1214 152 1214 205 1214 222 1214 259 1214 288 1214 312 1214 330 1214 338 1214 442 1214 465 1214 560 1214 587 1214 655 1214 734 1214 765 1214 778 1214 802 1214 866 1214 871 1214 892 1214 1102 1214 1113 1214 1145 1214 1212 1214 1214 1214 1242 1214 1327 1214 1330 1214 1340 1214 1371 1214 1382 1214 1400 1214 1413 1214 1419 1214 1442 1214 1486 1215 81 1215 151 1215 199 1215 251 1215 276 1215 318 1215 347 1215 419 1215 437 1215 470 1215 496 1215 513 1215 535 1215 545 1215 597 1215 665 1215 713 1215 715 1215 790 1215 817 1215 821 1215 828 1215 834 1215 912 1215 929 1215 952 1215 965 1215 986 1215 996 1215 1009 1215 1011 1215 1016 1215 1033 1215 1215 1215 1241 1215 1304 1215 1318 1215 1392 1215 1449 1215 1465 1215 1471 1216 76 1216 135 1216 144 1216 189 1216 217 1216 223 1216 232 1216 279 1216 295 1216 305 1216 401 1216 408 1216 452 1216 455 1216 478 1216 520 1216 526 1216 567 1216 584 1216 591 1216 611 1216 680 1216 684 1216 784 1216 814 1216 822 1216 839 1216 875 1216 940 1216 972 1216 978 1216 990 1216 1014 1216 1068 1216 1097 1216 1142 1216 1216 1216 1229 1216 1250 1216 1281 1216 1290 1216 1313 1216 1348 1216 1356 1216 1361 1216 1370 1216 1375 1216 1407 1216 1498 1217 79 1217 125 1217 189 1217 217 1217 223 1217 224 1217 253 1217 305 1217 344 1217 389 1217 483 1217 491 1217 556 1217 591 1217 592 1217 600 1217 640 1217 684 1217 807 1217 814 1217 875 1217 908 1217 910 1217 911 1217 990 1217 1014 1217 1068 1217 1078 1217 1082 1217 1099 1217 1180 1217 1206 1217 1217 1217 1230 1217 1250 1217 1277 1217 1290 1217 1355 1217 1356 1217 1370 1217 1375 1217 1441 1217 1474 1217 1484 1218 185 1218 264 1218 288 1218 359 1218 398 1218 436 1218 480 1218 546 1218 587 1218 598 1218 650 1218 654 1218 663 1218 674 1218 721 1218 758 1218 760 1218 842 1218 871 1218 895 1218 996 1218 1079 1218 1147 1218 1218 1218 1242 1218 1318 1218 1412 1218 1440 1219 30 1219 38 1219 53 1219 58 1219 90 1219 212 1219 216 1219 257 1219 262 1219 270 1219 323 1219 351 1219 428 1219 431 1219 460 1219 464 1219 506 1219 511 1219 534 1219 549 1219 610 1219 637 1219 702 1219 785 1219 792 1219 808 1219 812 1219 923 1219 980 1219 1017 1219 1046 1219 1057 1219 1065 1219 1084 1219 1187 1219 1219 1219 1234 1219 1249 1219 1334 1219 1336 1219 1359 1219 1360 1219 1415 1219 1418 1220 62 1220 105 1220 176 1220 254 1220 456 1220 500 1220 532 1220 565 1220 651 1220 826 1220 878 1220 899 1220 917 1220 1149 1220 1182 1220 1220 1220 1264 1220 1270 1220 1310 1220 1350 1220 1366 1220 1383 1220 1489 1221 9 1221 15 1221 53 1221 54 1221 73 1221 78 1221 102 1221 121 1221 130 1221 152 1221 191 1221 205 1221 259 1221 285 1221 312 1221 451 1221 485 1221 490 1221 536 1221 579 1221 618 1221 658 1221 685 1221 698 1221 752 1221 778 1221 815 1221 823 1221 827 1221 837 1221 863 1221 905 1221 959 1221 1044 1221 1066 1221 1102 1221 1113 1221 1144 1221 1153 1221 1183 1221 1212 1221 1221 1221 1258 1221 1327 1221 1330 1221 1340 1221 1343 1221 1382 1221 1442 1221 1448 1221 1452 1221 1463 1221 1486 1222 69 1222 97 1222 111 1222 119 1222 197 1222 220 1222 298 1222 330 1222 427 1222 442 1222 450 1222 454 1222 463 1222 499 1222 663 1222 721 1222 765 1222 780 1222 794 1222 866 1222 892 1222 951 1222 1050 1222 1083 1222 1133 1222 1145 1222 1186 1222 1194 1222 1222 1222 1242 1222 1256 1222 1260 1222 1371 1222 1396 1222 1412 1223 35 1223 41 1223 81 1223 99 1223 106 1223 140 1223 179 1223 188 1223 199 1223 245 1223 284 1223 313 1223 321 1223 363 1223 374 1223 382 1223 393 1223 406 1223 430 1223 487 1223 498 1223 510 1223 521 1223 540 1223 550 1223 577 1223 661 1223 718 1223 762 1223 772 1223 781 1223 782 1223 790 1223 852 1223 929 1223 949 1223 952 1223 961 1223 963 1223 1022 1223 1048 1223 1094 1223 1152 1223 1158 1223 1164 1223 1190 1223 1223 1223 1251 1223 1335 1224 7 1224 20 1224 22 1224 31 1224 87 1224 148 1224 156 1224 204 1224 266 1224 292 1224 333 1224 336 1224 378 1224 403 1224 449 1224 530 1224 543 1224 548 1224 558 1224 607 1224 621 1224 703 1224 763 1224 791 1224 862 1224 873 1224 900 1224 948 1224 960 1224 994 1224 1005 1224 1071 1224 1106 1224 1112 1224 1156 1224 1161 1224 1162 1224 1176 1224 1184 1224 1188 1224 1224 1224 1289 1224 1324 1224 1326 1224 1402 1224 1404 1224 1444 1224 1458 1224 1464 1224 1490 1225 13 1225 36 1225 55 1225 83 1225 101 1225 187 1225 218 1225 291 1225 377 1225 452 1225 492 1225 497 1225 524 1225 528 1225 544 1225 547 1225 562 1225 608 1225 620 1225 667 1225 730 1225 867 1225 870 1225 883 1225 908 1225 972 1225 1034 1225 1091 1225 1098 1225 1225 1225 1291 1225 1299 1225 1313 1225 1348 1225 1361 1225 1373 1225 1496 1226 1 1226 41 1226 81 1226 99 1226 100 1226 134 1226 199 1226 260 1226 265 1226 284 1226 337 1226 393 1226 417 1226 421 1226 487 1226 505 1226 510 1226 585 1226 596 1226 616 1226 717 1226 754 1226 762 1226 890 1226 918 1226 929 1226 988 1226 1000 1226 1048 1226 1074 1226 1077 1226 1094 1226 1226 1226 1251 1226 1317 1226 1397 1226 1445 1226 1470 1227 3 1227 8 1227 64 1227 97 1227 126 1227 153 1227 183 1227 296 1227 407 1227 454 1227 499 1227 614 1227 628 1227 660 1227 662 1227 801 1227 816 1227 838 1227 849 1227 951 1227 1002 1227 1132 1227 1227 1227 1354 1228 6 1228 25 1228 70 1228 108 1228 114 1228 119 1228 220 1228 238 1228 273 1228 298 1228 303 1228 438 1228 442 1228 518 1228 689 1228 722 1228 731 1228 780 1228 794 1228 803 1228 824 1228 1012 1228 1031 1228 1052 1228 1147 1228 1228 1228 1260 1228 1263 1228 1363 1228 1371 1228 1399 1228 1466 1228 1488 1229 14 1229 47 1229 79 1229 135 1229 160 1229 232 1229 253 1229 279 1229 295 1229 343 1229 389 1229 408 1229 434 1229 478 1229 526 1229 567 1229 584 1229 612 1229 638 1229 680 1229 784 1229 814 1229 822 1229 839 1229 940 1229 978 1229 1014 1229 1018 1229 1068 1229 1075 1229 1076 1229 1097 1229 1142 1229 1206 1229 1216 1229 1229 1229 1236 1229 1250 1229 1281 1229 1290 1229 1356 1229 1370 1229 1375 1229 1407 1229 1441 1229 1498 1230 72 1230 79 1230 135 1230 144 1230 149 1230 164 1230 189 1230 223 1230 224 1230 232 1230 343 1230 387 1230 389 1230 391 1230 397 1230 401 1230 424 1230 455 1230 484 1230 491 1230 520 1230 556 1230 592 1230 600 1230 611 1230 638 1230 680 1230 784 1230 844 1230 906 1230 910 1230 911 1230 978 1230 1014 1230 1034 1230 1068 1230 1179 1230 1180 1230 1198 1230 1206 1230 1217 1230 1230 1230 1235 1230 1277 1230 1370 1230 1393 1230 1441 1230 1474 1230 1484 1231 59 1231 67 1231 161 1231 190 1231 335 1231 414 1231 435 1231 774 1231 840 1231 857 1231 1021 1231 1231 1231 1320 1231 1365 1231 1409 1231 1432 1231 1443 1231 1454 1231 1477 1231 1491 1231 1497 1232 74 1232 95 1232 113 1232 132 1232 194 1232 201 1232 227 1232 231 1232 241 1232 275 1232 293 1232 306 1232 324 1232 353 1232 386 1232 466 1232 474 1232 481 1232 515 1232 554 1232 566 1232 581 1232 798 1232 971 1232 975 1232 1116 1232 1119 1232 1232 1232 1259 1232 1280 1232 1391 1233 39 1233 112 1233 166 1233 168 1233 215 1233 258 1233 302 1233 346 1233 409 1233 426 1233 477 1233 489 1233 572 1233 710 1233 899 1233 917 1233 954 1233 989 1233 1080 1233 1114 1233 1134 1233 1148 1233 1207 1233 1233 1233 1301 1233 1319 1233 1368 1233 1405 1233 1469 1234 38 1234 58 1234 137 1234 193 1234 212 1234 216 1234 269 1234 323 1234 428 1234 464 1234 534 1234 637 1234 720 1234 785 1234 792 1234 874 1234 1017 1234 1089 1234 1187 1234 1219 1234 1234 1234 1238 1234 1249 1234 1336 1234 1359 1234 1459 1235 44 1235 57 1235 72 1235 76 1235 135 1235 144 1235 147 1235 149 1235 189 1235 217 1235 232 1235 253 1235 305 1235 344 1235 370 1235 388 1235 397 1235 401 1235 424 1235 455 1235 478 1235 491 1235 556 1235 591 1235 611 1235 684 1235 733 1235 807 1235 860 1235 875 1235 893 1235 978 1235 990 1235 993 1235 1082 1235 1136 1235 1142 1235 1179 1235 1230 1235 1235 1235 1250 1235 1278 1235 1290 1235 1358 1235 1375 1235 1393 1235 1456 1236 13 1236 14 1236 79 1236 92 1236 160 1236 279 1236 295 1236 371 1236 373 1236 408 1236 434 1236 441 1236 452 1236 483 1236 484 1236 526 1236 528 1236 544 1236 567 1236 600 1236 603 1236 606 1236 612 1236 624 1236 630 1236 640 1236 684 1236 690 1236 807 1236 822 1236 839 1236 867 1236 875 1236 882 1236 883 1236 910 1236 1018 1236 1075 1236 1076 1236 1082 1236 1097 1236 1159 1236 1196 1236 1206 1236 1229 1236 1236 1236 1250 1236 1277 1236 1291 1236 1313 1236 1348 1236 1355 1236 1356 1236 1361 1236 1369 1236 1375 1237 32 1237 34 1237 40 1237 139 1237 150 1237 171 1237 177 1237 207 1237 213 1237 237 1237 248 1237 274 1237 307 1237 317 1237 366 1237 423 1237 439 1237 453 1237 495 1237 744 1237 813 1237 835 1237 848 1237 853 1237 859 1237 868 1237 869 1237 926 1237 936 1237 1041 1237 1061 1237 1103 1237 1110 1237 1138 1237 1237 1237 1245 1237 1247 1237 1262 1237 1276 1237 1284 1237 1296 1237 1322 1237 1347 1237 1376 1237 1381 1237 1482 1238 24 1238 38 1238 58 1238 66 1238 78 1238 137 1238 193 1238 206 1238 211 1238 212 1238 216 1238 286 1238 322 1238 323 1238 328 1238 348 1238 349 1238 354 1238 394 1238 399 1238 428 1238 431 1238 440 1238 444 1238 451 1238 464 1238 534 1238 580 1238 625 1238 631 1238 637 1238 652 1238 720 1238 769 1238 785 1238 792 1238 829 1238 874 1238 923 1238 1017 1238 1046 1238 1064 1238 1234 1238 1238 1238 1249 1238 1332 1238 1336 1238 1351 1238 1390 1238 1418 1238 1459 1238 1481 1239 21 1239 25 1239 29 1239 48 1239 51 1239 70 1239 94 1239 163 1239 179 1239 246 1239 256 1239 278 1239 303 1239 310 1239 320 1239 339 1239 437 1239 512 1239 521 1239 523 1239 545 1239 635 1239 664 1239 692 1239 729 1239 731 1239 740 1239 872 1239 880 1239 894 1239 932 1239 963 1239 1004 1239 1012 1239 1033 1239 1045 1239 1052 1239 1086 1239 1163 1239 1181 1239 1208 1239 1239 1239 1362 1239 1363 1239 1399 1239 1417 1239 1487 1240 10 1240 23 1240 122 1240 195 1240 468 1240 517 1240 542 1240 582 1240 643 1240 666 1240 693 1240 697 1240 750 1240 811 1240 898 1240 915 1240 1008 1240 1095 1240 1101 1240 1107 1240 1168 1240 1240 1240 1246 1240 1275 1240 1323 1240 1344 1240 1352 1240 1374 1240 1495 1241 81 1241 94 1241 106 1241 127 1241 134 1241 228 1241 245 1241 249 1241 276 1241 329 1241 337 1241 339 1241 347 1241 393 1241 417 1241 445 1241 459 1241 487 1241 496 1241 510 1241 513 1241 535 1241 585 1241 596 1241 602 1241 713 1241 754 1241 762 1241 790 1241 820 1241 834 1241 912 1241 918 1241 922 1241 946 1241 968 1241 1000 1241 1033 1241 1042 1241 1045 1241 1048 1241 1070 1241 1077 1241 1081 1241 1190 1241 1201 1241 1215 1241 1241 1241 1251 1241 1286 1241 1315 1241 1392 1241 1408 1241 1428 1241 1445 1241 1470 1241 1471 1242 19 1242 97 1242 197 1242 288 1242 407 1242 499 1242 587 1242 598 1242 614 1242 628 1242 654 1242 765 1242 802 1242 816 1242 871 1242 892 1242 951 1242 1050 1242 1214 1242 1218 1242 1222 1242 1242 1242 1384 1242 1412 1242 1419 1242 1442 1243 43 1243 46 1243 104 1243 105 1243 109 1243 118 1243 176 1243 287 1243 309 1243 369 1243 385 1243 456 1243 500 1243 532 1243 541 1243 557 1243 565 1243 633 1243 651 1243 724 1243 747 1243 779 1243 826 1243 861 1243 902 1243 927 1243 957 1243 1013 1243 1025 1243 1114 1243 1128 1243 1150 1243 1182 1243 1243 1243 1270 1243 1279 1243 1366 1243 1368 1243 1380 1243 1489 1244 24 1244 66 1244 96 1244 116 1244 129 1244 131 1244 137 1244 145 1244 174 1244 206 1244 235 1244 261 1244 322 1244 323 1244 325 1244 356 1244 394 1244 425 1244 486 1244 522 1244 539 1244 552 1244 576 1244 625 1244 646 1244 652 1244 708 1244 714 1244 767 1244 771 1244 792 1244 881 1244 885 1244 887 1244 942 1244 944 1244 969 1244 980 1244 985 1244 992 1244 1007 1244 1017 1244 1064 1244 1072 1244 1089 1244 1125 1244 1141 1244 1165 1244 1173 1244 1178 1244 1204 1244 1209 1244 1244 1244 1261 1244 1316 1244 1339 1244 1353 1244 1372 1244 1403 1244 1468 1245 40 1245 115 1245 139 1245 177 1245 307 1245 366 1245 453 1245 833 1245 926 1245 1061 1245 1103 1245 1237 1245 1245 1245 1262 1245 1276 1245 1296 1245 1347 1245 1406 1245 1482 1246 10 1246 23 1246 122 1246 195 1246 468 1246 503 1246 517 1246 542 1246 573 1246 574 1246 582 1246 643 1246 666 1246 693 1246 697 1246 750 1246 811 1246 898 1246 1008 1246 1107 1246 1168 1246 1240 1246 1246 1246 1275 1246 1323 1246 1344 1246 1352 1246 1374 1246 1429 1246 1483 1246 1495 1247 16 1247 32 1247 40 1247 115 1247 139 1247 150 1247 171 1247 177 1247 207 1247 213 1247 237 1247 248 1247 307 1247 317 1247 366 1247 439 1247 453 1247 495 1247 706 1247 744 1247 833 1247 835 1247 848 1247 853 1247 859 1247 868 1247 869 1247 889 1247 926 1247 936 1247 1041 1247 1061 1247 1103 1247 1110 1247 1138 1247 1237 1247 1247 1247 1262 1247 1276 1247 1296 1247 1322 1247 1347 1247 1376 1247 1381 1247 1406 1247 1482 1248 2 1248 74 1248 84 1248 93 1248 95 1248 120 1248 126 1248 132 1248 194 1248 201 1248 231 1248 239 1248 241 1248 247 1248 271 1248 275 1248 282 1248 306 1248 311 1248 315 1248 362 1248 372 1248 384 1248 463 1248 481 1248 488 1248 515 1248 516 1248 554 1248 564 1248 654 1248 668 1248 670 1248 675 1248 719 1248 796 1248 858 1248 971 1248 975 1248 1001 1248 1023 1248 1036 1248 1050 1248 1058 1248 1116 1248 1119 1248 1122 1248 1157 1248 1194 1248 1248 1248 1280 1248 1282 1248 1302 1248 1329 1248 1354 1248 1384 1248 1394 1248 1435 1248 1478 1249 30 1249 38 1249 53 1249 58 1249 78 1249 211 1249 212 1249 216 1249 257 1249 262 1249 286 1249 349 1249 428 1249 431 1249 451 1249 460 1249 464 1249 534 1249 549 1249 626 1249 637 1249 720 1249 792 1249 808 1249 812 1249 829 1249 863 1249 874 1249 923 1249 980 1249 1046 1249 1057 1249 1065 1249 1084 1249 1137 1249 1187 1249 1219 1249 1234 1249 1238 1249 1249 1249 1334 1249 1336 1249 1390 1249 1415 1249 1418 1249 1459 1249 1481 1250 189 1250 217 1250 232 1250 253 1250 305 1250 344 1250 452 1250 455 1250 478 1250 526 1250 544 1250 567 1250 584 1250 591 1250 608 1250 684 1250 807 1250 822 1250 839 1250 860 1250 875 1250 908 1250 972 1250 990 1250 1014 1250 1142 1250 1216 1250 1217 1250 1229 1250 1235 1250 1236 1250 1250 1250 1290 1250 1313 1250 1348 1250 1355 1250 1356 1250 1358 1250 1361 1250 1370 1250 1375 1250 1498 1251 35 1251 41 1251 81 1251 94 1251 99 1251 140 1251 151 1251 179 1251 188 1251 199 1251 245 1251 246 1251 276 1251 284 1251 313 1251 321 1251 337 1251 339 1251 374 1251 382 1251 406 1251 430 1251 487 1251 496 1251 501 1251 505 1251 510 1251 513 1251 540 1251 577 1251 596 1251 664 1251 665 1251 686 1251 713 1251 754 1251 768 1251 781 1251 782 1251 790 1251 912 1251 929 1251 949 1251 950 1251 952 1251 1000 1251 1022 1251 1032 1251 1033 1251 1045 1251 1048 1251 1063 1251 1081 1251 1094 1251 1152 1251 1158 1251 1181 1251 1190 1251 1201 1251 1208 1251 1223 1251 1226 1251 1241 1251 1251 1251 1288 1251 1304 1251 1408 1251 1425 1251 1445 1251 1471 1252 16 1252 71 1252 159 1252 207 1252 252 1252 274 1252 297 1252 390 1252 432 1252 448 1252 469 1252 543 1252 548 1252 588 1252 615 1252 641 1252 707 1252 738 1252 764 1252 964 1252 1005 1252 1037 1252 1130 1252 1172 1252 1174 1252 1252 1252 1255 1252 1274 1252 1287 1252 1324 1252 1386 1252 1416 1252 1422 1252 1436 1252 1493 1253 93 1253 111 1253 117 1253 153 1253 239 1253 241 1253 247 1253 275 1253 282 1253 293 1253 311 1253 315 1253 353 1253 361 1253 372 1253 384 1253 450 1253 454 1253 463 1253 516 1253 564 1253 719 1253 838 1253 971 1253 982 1253 1056 1253 1083 1253 1105 1253 1194 1253 1253 1253 1256 1253 1280 1253 1282 1253 1307 1253 1377 1253 1385 1253 1394 1253 1395 1253 1396 1253 1447 1254 166 1254 306 1254 334 1254 420 1254 461 1254 471 1254 472 1254 553 1254 554 1254 566 1254 659 1254 668 1254 696 1254 723 1254 748 1254 804 1254 924 1254 1040 1254 1080 1254 1096 1254 1104 1254 1143 1254 1191 1254 1254 1254 1272 1254 1285 1254 1303 1254 1308 1254 1329 1254 1391 1254 1405 1254 1427 1254 1469 1255 34 1255 136 1255 297 1255 317 1255 423 1255 432 1255 439 1255 469 1255 548 1255 588 1255 641 1255 706 1255 763 1255 783 1255 813 1255 868 1255 889 1255 936 1255 964 1255 977 1255 1110 1255 1130 1255 1174 1255 1252 1255 1255 1255 1274 1255 1284 1255 1328 1255 1367 1255 1416 1255 1422 1255 1434 1255 1480 1256 2 1256 25 1256 69 1256 93 1256 97 1256 111 1256 117 1256 153 1256 194 1256 197 1256 220 1256 247 1256 282 1256 353 1256 362 1256 384 1256 450 1256 454 1256 463 1256 516 1256 554 1256 670 1256 794 1256 796 1256 970 1256 982 1256 1001 1256 1012 1256 1036 1256 1050 1256 1056 1256 1083 1256 1105 1256 1122 1256 1186 1256 1194 1256 1222 1256 1253 1256 1256 1256 1260 1256 1280 1256 1298 1256 1329 1256 1384 1256 1385 1256 1396 1256 1447 1256 1478 1257 7 1257 20 1257 31 1257 37 1257 75 1257 123 1257 167 1257 170 1257 178 1257 198 1257 219 1257 242 1257 319 1257 326 1257 350 1257 360 1257 402 1257 416 1257 418 1257 422 1257 457 1257 508 1257 551 1257 555 1257 559 1257 583 1257 589 1257 593 1257 622 1257 644 1257 657 1257 671 1257 673 1257 703 1257 725 1257 756 1257 766 1257 777 1257 800 1257 886 1257 916 1257 928 1257 933 1257 935 1257 958 1257 987 1257 997 1257 1015 1257 1020 1257 1071 1257 1087 1257 1101 1257 1106 1257 1112 1257 1154 1257 1161 1257 1166 1257 1167 1257 1171 1257 1185 1257 1200 1257 1203 1257 1205 1257 1211 1257 1257 1257 1268 1257 1273 1257 1289 1257 1311 1257 1326 1257 1388 1257 1433 1257 1479 1257 1490 1258 9 1258 15 1258 54 1258 121 1258 158 1258 182 1258 205 1258 221 1258 229 1258 257 1258 262 1258 285 1258 351 1258 381 1258 462 1258 485 1258 490 1258 536 1258 610 1258 618 1258 619 1258 685 1258 698 1258 701 1258 735 1258 808 1258 823 1258 827 1258 837 1258 864 1258 905 1258 1044 1258 1144 1258 1153 1258 1183 1258 1221 1258 1258 1258 1360 1258 1389 1258 1448 1258 1452 1258 1455 1259 74 1259 113 1259 132 1259 201 1259 227 1259 231 1259 241 1259 306 1259 324 1259 386 1259 474 1259 481 1259 515 1259 566 1259 581 1259 659 1259 696 1259 728 1259 788 1259 798 1259 804 1259 924 1259 1002 1259 1232 1259 1259 1259 1285 1259 1391 1260 25 1260 69 1260 111 1260 119 1260 146 1260 197 1260 220 1260 298 1260 330 1260 407 1260 427 1260 442 1260 454 1260 463 1260 516 1260 765 1260 780 1260 794 1260 951 1260 982 1260 983 1260 1083 1260 1133 1260 1186 1260 1194 1260 1222 1260 1228 1260 1256 1260 1260 1260 1298 1260 1371 1260 1385 1260 1396 1260 1466 1261 24 1261 51 1261 116 1261 129 1261 145 1261 174 1261 180 1261 206 1261 235 1261 261 1261 304 1261 322 1261 325 1261 348 1261 355 1261 356 1261 522 1261 539 1261 568 1261 629 1261 695 1261 708 1261 767 1261 776 1261 885 1261 931 1261 980 1261 985 1261 1007 1261 1141 1261 1178 1261 1244 1261 1261 1261 1316 1261 1339 1261 1403 1261 1468 1262 16 1262 32 1262 34 1262 40 1262 115 1262 139 1262 150 1262 171 1262 177 1262 207 1262 213 1262 237 1262 274 1262 307 1262 317 1262 366 1262 439 1262 453 1262 495 1262 744 1262 833 1262 835 1262 848 1262 853 1262 859 1262 868 1262 869 1262 926 1262 936 1262 1041 1262 1061 1262 1103 1262 1110 1262 1138 1262 1237 1262 1245 1262 1247 1262 1262 1262 1276 1262 1296 1262 1322 1262 1347 1262 1376 1262 1381 1262 1406 1262 1482 1263 6 1263 45 1263 70 1263 98 1263 108 1263 151 1263 186 1263 238 1263 256 1263 273 1263 281 1263 303 1263 367 1263 438 1263 512 1263 635 1263 645 1263 682 1263 722 1263 729 1263 731 1263 780 1263 794 1263 803 1263 1011 1263 1031 1263 1032 1263 1052 1263 1055 1263 1085 1263 1147 1263 1197 1263 1228 1263 1263 1263 1305 1263 1363 1263 1371 1263 1399 1263 1466 1263 1488 1264 118 1264 176 1264 236 1264 309 1264 532 1264 557 1264 565 1264 595 1264 651 1264 927 1264 957 1264 981 1264 984 1264 1150 1264 1182 1264 1220 1264 1264 1264 1270 1264 1295 1264 1366 1264 1489 1265 5 1265 12 1265 13 1265 52 1265 63 1265 65 1265 85 1265 165 1265 202 1265 234 1265 240 1265 365 1265 434 1265 441 1265 492 1265 528 1265 603 1265 609 1265 612 1265 630 1265 642 1265 742 1265 759 1265 883 1265 939 1265 1026 1265 1028 1265 1108 1265 1129 1265 1159 1265 1265 1265 1461 1265 1472 1266 26 1266 264 1266 281 1266 298 1266 301 1266 327 1266 338 1266 355 1266 398 1266 425 1266 436 1266 442 1266 465 1266 475 1266 480 1266 518 1266 546 1266 598 1266 650 1266 674 1266 734 1266 758 1266 771 1266 824 1266 934 1266 1035 1266 1079 1266 1085 1266 1124 1266 1145 1266 1147 1266 1204 1266 1266 1266 1271 1266 1305 1266 1400 1266 1412 1266 1413 1267 156 1267 196 1267 266 1267 345 1267 396 1267 400 1267 448 1267 449 1267 530 1267 543 1267 605 1267 669 1267 691 1267 707 1267 727 1267 739 1267 763 1267 764 1267 841 1267 847 1267 862 1267 873 1267 919 1267 920 1267 947 1267 960 1267 994 1267 1005 1267 1037 1267 1038 1267 1090 1267 1126 1267 1172 1267 1267 1267 1287 1267 1324 1267 1325 1267 1436 1267 1493 1268 7 1268 20 1268 37 1268 91 1268 167 1268 178 1268 219 1268 242 1268 319 1268 326 1268 350 1268 360 1268 416 1268 418 1268 508 1268 555 1268 583 1268 593 1268 622 1268 644 1268 703 1268 732 1268 770 1268 777 1268 800 1268 886 1268 900 1268 903 1268 928 1268 933 1268 958 1268 987 1268 1010 1268 1015 1268 1020 1268 1071 1268 1087 1268 1106 1268 1146 1268 1154 1268 1161 1268 1167 1268 1171 1268 1200 1268 1205 1268 1211 1268 1257 1268 1268 1268 1273 1268 1289 1268 1311 1268 1326 1268 1346 1268 1388 1268 1426 1268 1431 1268 1433 1268 1458 1268 1479 1269 33 1269 61 1269 110 1269 141 1269 155 1269 169 1269 195 1269 299 1269 314 1269 341 1269 342 1269 364 1269 379 1269 447 1269 458 1269 493 1269 504 1269 514 1269 571 1269 586 1269 687 1269 704 1269 749 1269 773 1269 811 1269 843 1269 904 1269 913 1269 915 1269 941 1269 943 1269 956 1269 1109 1269 1168 1269 1189 1269 1269 1269 1275 1269 1312 1269 1338 1269 1345 1269 1374 1269 1420 1269 1421 1269 1437 1270 46 1270 62 1270 104 1270 105 1270 109 1270 118 1270 254 1270 258 1270 346 1270 456 1270 500 1270 532 1270 557 1270 565 1270 651 1270 710 1270 826 1270 878 1270 899 1270 917 1270 957 1270 1025 1270 1114 1270 1149 1270 1182 1270 1220 1270 1243 1270 1264 1270 1270 1270 1310 1270 1350 1270 1366 1270 1380 1270 1383 1270 1489 1271 133 1271 152 1271 186 1271 238 1271 244 1271 264 1271 281 1271 298 1271 301 1271 338 1271 398 1271 442 1271 475 1271 518 1271 560 1271 674 1271 681 1271 803 1271 824 1271 884 1271 967 1271 980 1271 1011 1271 1031 1271 1085 1271 1124 1271 1145 1271 1147 1271 1199 1271 1266 1271 1271 1271 1305 1271 1330 1271 1371 1271 1378 1271 1400 1271 1412 1271 1413 1271 1468 1271 1499 1272 74 1272 247 1272 306 1272 386 1272 420 1272 461 1272 471 1272 525 1272 553 1272 566 1272 659 1272 660 1272 662 1272 668 1272 696 1272 723 1272 748 1272 804 1272 924 1272 1002 1272 1040 1272 1096 1272 1143 1272 1191 1272 1254 1272 1272 1272 1285 1272 1302 1272 1303 1272 1391 1273 7 1273 20 1273 37 1273 49 1273 87 1273 128 1273 204 1273 242 1273 350 1273 443 1273 446 1273 508 1273 555 1273 574 1273 583 1273 589 1273 613 1273 639 1273 671 1273 703 1273 800 1273 805 1273 836 1273 886 1273 903 1273 928 1273 953 1273 987 1273 1038 1273 1151 1273 1161 1273 1167 1273 1169 1273 1171 1273 1200 1273 1203 1273 1205 1273 1211 1273 1257 1273 1268 1273 1273 1273 1326 1273 1379 1273 1431 1273 1450 1273 1454 1273 1458 1273 1483 1274 16 1274 71 1274 136 1274 150 1274 177 1274 213 1274 248 1274 252 1274 274 1274 297 1274 317 1274 390 1274 423 1274 432 1274 469 1274 548 1274 588 1274 632 1274 641 1274 706 1274 738 1274 889 1274 964 1274 977 1274 1053 1274 1073 1274 1130 1274 1252 1274 1255 1274 1274 1274 1284 1274 1322 1274 1328 1274 1416 1274 1422 1274 1480 1275 141 1275 169 1275 195 1275 299 1275 342 1275 379 1275 504 1275 542 1275 571 1275 643 1275 693 1275 697 1275 749 1275 811 1275 915 1275 930 1275 943 1275 1109 1275 1168 1275 1240 1275 1246 1275 1269 1275 1275 1275 1323 1275 1344 1275 1352 1275 1374 1275 1420 1275 1437 1275 1495 1276 16 1276 32 1276 40 1276 115 1276 139 1276 207 1276 237 1276 307 1276 366 1276 439 1276 453 1276 744 1276 833 1276 835 1276 848 1276 853 1276 859 1276 868 1276 869 1276 926 1276 1061 1276 1103 1276 1110 1276 1138 1276 1237 1276 1245 1276 1247 1276 1262 1276 1276 1276 1296 1276 1322 1276 1347 1276 1376 1276 1381 1276 1406 1276 1482 1277 47 1277 79 1277 92 1277 125 1277 160 1277 189 1277 230 1277 272 1277 279 1277 295 1277 371 1277 373 1277 387 1277 391 1277 441 1277 483 1277 484 1277 491 1277 520 1277 556 1277 569 1277 600 1277 611 1277 612 1277 624 1277 640 1277 684 1277 690 1277 694 1277 743 1277 784 1277 807 1277 809 1277 814 1277 844 1277 882 1277 888 1277 910 1277 911 1277 978 1277 990 1277 999 1277 1014 1277 1018 1277 1068 1277 1069 1277 1075 1277 1082 1277 1099 1277 1180 1277 1196 1277 1206 1277 1217 1277 1230 1277 1236 1277 1277 1277 1281 1277 1355 1277 1370 1277 1441 1277 1472 1277 1474 1277 1476 1277 1484 1278 44 1278 57 1278 72 1278 76 1278 147 1278 149 1278 232 1278 344 1278 375 1278 388 1278 397 1278 491 1278 733 1278 799 1278 860 1278 893 1278 993 1278 1027 1278 1136 1278 1202 1278 1235 1278 1278 1278 1355 1278 1358 1278 1456 1279 43 1279 46 1279 60 1279 77 1279 104 1279 118 1279 154 1279 176 1279 280 1279 287 1279 309 1279 369 1279 385 1279 456 1279 500 1279 541 1279 557 1279 565 1279 633 1279 651 1279 724 1279 747 1279 779 1279 861 1279 891 1279 902 1279 927 1279 957 1279 976 1279 1013 1279 1030 1279 1128 1279 1150 1279 1182 1279 1210 1279 1243 1279 1279 1279 1295 1279 1366 1279 1380 1279 1439 1279 1489 1280 2 1280 74 1280 93 1280 95 1280 111 1280 113 1280 117 1280 126 1280 132 1280 153 1280 194 1280 201 1280 227 1280 231 1280 239 1280 241 1280 247 1280 271 1280 282 1280 296 1280 306 1280 311 1280 315 1280 362 1280 386 1280 450 1280 454 1280 463 1280 481 1280 515 1280 516 1280 564 1280 670 1280 796 1280 801 1280 838 1280 975 1280 982 1280 1001 1280 1002 1280 1036 1280 1050 1280 1056 1280 1116 1280 1119 1280 1122 1280 1194 1280 1232 1280 1248 1280 1253 1280 1256 1280 1280 1280 1282 1280 1298 1280 1302 1280 1394 1280 1396 1280 1478 1281 14 1281 47 1281 144 1281 223 1281 279 1281 295 1281 371 1281 387 1281 389 1281 391 1281 401 1281 408 1281 478 1281 483 1281 526 1281 600 1281 638 1281 680 1281 694 1281 784 1281 814 1281 822 1281 839 1281 888 1281 911 1281 940 1281 978 1281 1014 1281 1018 1281 1068 1281 1069 1281 1097 1281 1142 1281 1206 1281 1216 1281 1229 1281 1277 1281 1281 1281 1299 1281 1355 1281 1370 1281 1375 1281 1407 1281 1441 1281 1498 1282 2 1282 93 1282 95 1282 111 1282 113 1282 117 1282 126 1282 153 1282 201 1282 227 1282 231 1282 239 1282 241 1282 271 1282 275 1282 282 1282 293 1282 311 1282 450 1282 454 1282 463 1282 515 1282 516 1282 564 1282 801 1282 838 1282 858 1282 971 1282 975 1282 982 1282 1001 1282 1002 1282 1056 1282 1105 1282 1116 1282 1119 1282 1122 1282 1194 1282 1248 1282 1253 1282 1280 1282 1282 1282 1298 1282 1377 1282 1394 1282 1396 1282 1447 1283 58 1283 66 1283 86 1283 96 1283 162 1283 175 1283 193 1283 250 1283 277 1283 322 1283 354 1283 356 1283 394 1283 440 1283 444 1283 479 1283 561 1283 563 1283 714 1283 720 1283 785 1283 792 1283 874 1283 887 1283 909 1283 942 1283 1047 1283 1089 1283 1165 1283 1283 1283 1332 1283 1341 1284 34 1284 136 1284 150 1284 171 1284 207 1284 213 1284 237 1284 252 1284 297 1284 317 1284 383 1284 423 1284 432 1284 439 1284 495 1284 588 1284 615 1284 641 1284 706 1284 744 1284 783 1284 813 1284 848 1284 853 1284 859 1284 868 1284 889 1284 936 1284 1041 1284 1110 1284 1130 1284 1138 1284 1174 1284 1237 1284 1255 1284 1274 1284 1284 1284 1322 1284 1328 1284 1376 1284 1422 1285 74 1285 113 1285 166 1285 173 1285 201 1285 227 1285 306 1285 334 1285 386 1285 420 1285 461 1285 471 1285 472 1285 474 1285 515 1285 553 1285 554 1285 566 1285 659 1285 668 1285 696 1285 723 1285 748 1285 804 1285 924 1285 1040 1285 1096 1285 1104 1285 1143 1285 1191 1285 1192 1285 1254 1285 1259 1285 1272 1285 1285 1285 1303 1285 1329 1285 1391 1285 1405 1285 1427 1285 1469 1286 27 1286 127 1286 138 1286 228 1286 318 1286 329 1286 337 1286 393 1286 510 1286 513 1286 535 1286 568 1286 585 1286 775 1286 834 1286 890 1286 909 1286 918 1286 925 1286 946 1286 965 1286 968 1286 979 1286 988 1286 1000 1286 1016 1286 1048 1286 1111 1286 1241 1286 1286 1286 1314 1286 1321 1286 1392 1286 1408 1286 1445 1286 1471 1287 22 1287 156 1287 159 1287 292 1287 390 1287 396 1287 403 1287 449 1287 530 1287 543 1287 548 1287 583 1287 641 1287 707 1287 763 1287 764 1287 847 1287 873 1287 920 1287 948 1287 960 1287 964 1287 994 1287 1005 1287 1037 1287 1038 1287 1126 1287 1174 1287 1252 1287 1267 1287 1287 1287 1324 1287 1325 1287 1386 1287 1436 1287 1493 1288 21 1288 80 1288 94 1288 179 1288 225 1288 226 1288 245 1288 249 1288 276 1288 278 1288 310 1288 329 1288 339 1288 412 1288 437 1288 445 1288 496 1288 509 1288 535 1288 602 1288 653 1288 656 1288 664 1288 713 1288 754 1288 768 1288 912 1288 922 1288 949 1288 952 1288 966 1288 1022 1288 1032 1288 1033 1288 1045 1288 1063 1288 1070 1288 1170 1288 1175 1288 1190 1288 1251 1288 1288 1289 7 1289 22 1289 143 1289 167 1289 178 1289 219 1289 242 1289 266 1289 326 1289 336 1289 350 1289 360 1289 378 1289 416 1289 418 1289 446 1289 449 1289 508 1289 530 1289 583 1289 593 1289 607 1289 617 1289 621 1289 622 1289 644 1289 732 1289 777 1289 791 1289 873 1289 900 1289 903 1289 928 1289 935 1289 948 1289 958 1289 962 1289 1010 1289 1015 1289 1071 1289 1087 1289 1106 1289 1154 1289 1161 1289 1162 1289 1171 1289 1176 1289 1205 1289 1211 1289 1224 1289 1257 1289 1268 1289 1289 1289 1294 1289 1311 1289 1326 1289 1431 1289 1444 1289 1464 1290 76 1290 135 1290 144 1290 189 1290 217 1290 232 1290 253 1290 295 1290 305 1290 397 1290 401 1290 452 1290 455 1290 478 1290 484 1290 520 1290 526 1290 556 1290 567 1290 591 1290 608 1290 611 1290 680 1290 684 1290 733 1290 822 1290 839 1290 875 1290 911 1290 940 1290 978 1290 990 1290 1014 1290 1018 1290 1142 1290 1206 1290 1216 1290 1217 1290 1229 1290 1235 1290 1250 1290 1290 1290 1313 1290 1348 1290 1355 1290 1356 1290 1358 1290 1370 1290 1375 1290 1498 1291 13 1291 55 1291 65 1291 85 1291 187 1291 218 1291 291 1291 434 1291 441 1291 452 1291 492 1291 497 1291 526 1291 528 1291 562 1291 603 1291 606 1291 608 1291 620 1291 730 1291 867 1291 883 1291 1076 1291 1091 1291 1129 1291 1159 1291 1225 1291 1236 1291 1291 1291 1313 1291 1348 1292 35 1292 140 1292 145 1292 313 1292 321 1292 411 1292 531 1292 552 1292 577 1292 705 1292 741 1292 751 1292 753 1292 772 1292 797 1292 832 1292 852 1292 881 1292 991 1292 995 1292 1092 1292 1120 1292 1123 1292 1173 1292 1213 1292 1292 1292 1372 1293 84 1293 88 1293 173 1293 209 1293 324 1293 334 1293 420 1293 461 1293 472 1293 477 1293 488 1293 489 1293 553 1293 572 1293 581 1293 659 1293 668 1293 723 1293 728 1293 737 1293 748 1293 788 1293 798 1293 818 1293 917 1293 1006 1293 1062 1293 1080 1293 1093 1293 1096 1293 1104 1293 1115 1293 1143 1293 1149 1293 1192 1293 1293 1293 1469 1294 31 1294 107 1294 123 1294 143 1294 167 1294 178 1294 219 1294 326 1294 350 1294 378 1294 416 1294 418 1294 422 1294 449 1294 507 1294 593 1294 607 1294 617 1294 621 1294 622 1294 644 1294 732 1294 777 1294 791 1294 854 1294 900 1294 928 1294 935 1294 937 1294 958 1294 962 1294 997 1294 1010 1294 1015 1294 1112 1294 1146 1294 1154 1294 1162 1294 1171 1294 1176 1294 1289 1294 1294 1294 1311 1294 1326 1294 1426 1294 1444 1294 1464 1295 43 1295 60 1295 118 1295 154 1295 176 1295 208 1295 254 1295 280 1295 287 1295 369 1295 385 1295 410 1295 456 1295 541 1295 557 1295 565 1295 633 1295 651 1295 724 1295 747 1295 779 1295 861 1295 891 1295 902 1295 927 1295 957 1295 976 1295 989 1295 1013 1295 1030 1295 1150 1295 1210 1295 1264 1295 1279 1295 1295 1295 1310 1295 1366 1295 1380 1295 1489 1296 16 1296 32 1296 34 1296 40 1296 115 1296 139 1296 150 1296 171 1296 177 1296 207 1296 213 1296 237 1296 274 1296 307 1296 317 1296 366 1296 439 1296 453 1296 495 1296 744 1296 833 1296 835 1296 848 1296 853 1296 859 1296 868 1296 869 1296 926 1296 936 1296 1041 1296 1061 1296 1103 1296 1110 1296 1138 1296 1237 1296 1245 1296 1247 1296 1262 1296 1276 1296 1296 1296 1322 1296 1347 1296 1376 1296 1381 1296 1406 1296 1482 1297 10 1297 103 1297 210 1297 341 1297 364 1297 542 1297 578 1297 601 1297 643 1297 666 1297 687 1297 704 1297 811 1297 898 1297 913 1297 915 1297 1008 1297 1095 1297 1109 1297 1168 1297 1297 1297 1312 1297 1338 1297 1421 1297 1457 1298 2 1298 25 1298 69 1298 93 1298 111 1298 119 1298 126 1298 146 1298 153 1298 282 1298 353 1298 427 1298 450 1298 454 1298 463 1298 466 1298 481 1298 516 1298 780 1298 794 1298 796 1298 801 1298 838 1298 982 1298 1012 1298 1119 1298 1122 1298 1133 1298 1186 1298 1194 1298 1256 1298 1260 1298 1280 1298 1282 1298 1298 1298 1385 1298 1396 1298 1447 1298 1466 1298 1478 1299 36 1299 55 1299 56 1299 83 1299 101 1299 164 1299 187 1299 217 1299 343 1299 391 1299 408 1299 497 1299 524 1299 547 1299 592 1299 620 1299 638 1299 667 1299 680 1299 784 1299 814 1299 844 1299 867 1299 870 1299 906 1299 908 1299 940 1299 972 1299 1034 1299 1068 1299 1098 1299 1099 1299 1180 1299 1198 1299 1225 1299 1281 1299 1299 1299 1361 1299 1373 1299 1407 1299 1441 1299 1474 1299 1496 1299 1498 1300 10 1300 50 1300 68 1300 75 1300 141 1300 184 1300 198 1300 203 1300 210 1300 294 1300 299 1300 300 1300 314 1300 333 1300 357 1300 368 1300 376 1300 433 1300 538 1300 542 1300 559 1300 571 1300 601 1300 627 1300 657 1300 666 1300 697 1300 704 1300 766 1300 898 1300 916 1300 930 1300 1008 1300 1029 1300 1088 1300 1100 1300 1169 1300 1185 1300 1189 1300 1203 1300 1300 1300 1338 1300 1364 1300 1374 1300 1460 1300 1490 1300 1495 1301 39 1301 77 1301 104 1301 109 1301 112 1301 168 1301 215 1301 258 1301 280 1301 302 1301 346 1301 409 1301 410 1301 633 1301 878 1301 891 1301 954 1301 976 1301 989 1301 1025 1301 1128 1301 1134 1301 1148 1301 1207 1301 1233 1301 1301 1301 1319 1301 1350 1301 1439 1302 2 1302 111 1302 113 1302 194 1302 227 1302 247 1302 275 1302 362 1302 372 1302 384 1302 461 1302 471 1302 481 1302 525 1302 566 1302 668 1302 670 1302 675 1302 696 1302 796 1302 804 1302 1001 1302 1012 1302 1036 1302 1040 1302 1119 1302 1122 1302 1186 1302 1191 1302 1248 1302 1272 1302 1280 1302 1302 1302 1303 1302 1329 1302 1391 1302 1478 1303 84 1303 166 1303 173 1303 306 1303 334 1303 420 1303 461 1303 471 1303 472 1303 488 1303 553 1303 554 1303 668 1303 675 1303 696 1303 723 1303 748 1303 788 1303 804 1303 924 1303 1040 1303 1080 1303 1096 1303 1143 1303 1191 1303 1192 1303 1254 1303 1272 1303 1285 1303 1302 1303 1303 1303 1308 1303 1319 1303 1329 1303 1391 1303 1405 1303 1427 1303 1469 1304 11 1304 29 1304 41 1304 45 1304 106 1304 151 1304 199 1304 245 1304 251 1304 284 1304 318 1304 339 1304 347 1304 374 1304 380 1304 430 1304 459 1304 470 1304 494 1304 505 1304 510 1304 540 1304 665 1304 676 1304 683 1304 686 1304 689 1304 699 1304 713 1304 726 1304 760 1304 787 1304 790 1304 821 1304 828 1304 896 1304 921 1304 929 1304 931 1304 949 1304 950 1304 965 1304 979 1304 986 1304 1019 1304 1048 1304 1060 1304 1063 1304 1081 1304 1152 1304 1190 1304 1215 1304 1251 1304 1304 1304 1349 1304 1408 1304 1417 1304 1425 1304 1445 1304 1449 1304 1465 1304 1471 1305 0 1305 98 1305 133 1305 185 1305 186 1305 238 1305 264 1305 281 1305 298 1305 301 1305 303 1305 338 1305 358 1305 367 1305 398 1305 438 1305 442 1305 475 1305 480 1305 518 1305 546 1305 597 1305 645 1305 650 1305 674 1305 676 1305 699 1305 722 1305 729 1305 758 1305 771 1305 803 1305 824 1305 892 1305 996 1305 1011 1305 1060 1305 1085 1305 1145 1305 1147 1305 1263 1305 1266 1305 1271 1305 1305 1305 1371 1305 1400 1305 1412 1305 1413 1305 1488 1305 1499 1306 18 1306 146 1306 214 1306 320 1306 415 1306 476 1306 672 1306 688 1306 712 1306 740 1306 793 1306 856 1306 876 1306 880 1306 907 1306 1004 1306 1117 1306 1177 1306 1193 1306 1195 1306 1306 1306 1337 1306 1387 1306 1397 1306 1438 1306 1473 1307 84 1307 117 1307 120 1307 201 1307 239 1307 271 1307 275 1307 293 1307 311 1307 315 1307 361 1307 372 1307 415 1307 488 1307 647 1307 677 1307 719 1307 793 1307 858 1307 971 1307 1006 1307 1023 1307 1056 1307 1058 1307 1157 1307 1253 1307 1307 1307 1377 1307 1394 1307 1395 1307 1424 1307 1435 1307 1447 1308 80 1308 114 1308 166 1308 235 1308 467 1308 471 1308 664 1308 675 1308 825 1308 966 1308 1012 1308 1170 1308 1175 1308 1191 1308 1254 1308 1303 1308 1308 1308 1329 1308 1427 1309 53 1309 58 1309 78 1309 86 1309 193 1309 211 1309 250 1309 277 1309 332 1309 348 1309 349 1309 405 1309 431 1309 440 1309 444 1309 451 1309 534 1309 563 1309 579 1309 625 1309 626 1309 658 1309 720 1309 846 1309 863 1309 901 1309 959 1309 1024 1309 1035 1309 1046 1309 1084 1309 1131 1309 1135 1309 1137 1309 1309 1309 1341 1309 1351 1309 1475 1309 1494 1310 39 1310 60 1310 62 1310 77 1310 104 1310 105 1310 109 1310 112 1310 154 1310 176 1310 208 1310 254 1310 280 1310 302 1310 346 1310 410 1310 456 1310 500 1310 541 1310 633 1310 651 1310 724 1310 747 1310 779 1310 826 1310 861 1310 878 1310 891 1310 899 1310 902 1310 927 1310 957 1310 976 1310 989 1310 1013 1310 1025 1310 1030 1310 1128 1310 1148 1310 1207 1310 1210 1310 1220 1310 1270 1310 1295 1310 1310 1310 1350 1310 1380 1310 1383 1310 1439 1311 37 1311 122 1311 123 1311 143 1311 167 1311 178 1311 203 1311 219 1311 242 1311 319 1311 326 1311 350 1311 360 1311 378 1311 402 1311 416 1311 418 1311 422 1311 443 1311 468 1311 555 1311 589 1311 593 1311 617 1311 622 1311 644 1311 657 1311 671 1311 673 1311 703 1311 732 1311 756 1311 777 1311 800 1311 805 1311 886 1311 900 1311 928 1311 933 1311 935 1311 955 1311 958 1311 997 1311 1010 1311 1015 1311 1071 1311 1087 1311 1101 1311 1106 1311 1154 1311 1161 1311 1166 1311 1167 1311 1171 1311 1185 1311 1200 1311 1205 1311 1211 1311 1257 1311 1268 1311 1289 1311 1294 1311 1311 1311 1326 1311 1346 1311 1388 1311 1426 1311 1431 1311 1433 1311 1479 1312 33 1312 50 1312 61 1312 103 1312 110 1312 210 1312 299 1312 314 1312 341 1312 342 1312 364 1312 379 1312 447 1312 458 1312 493 1312 504 1312 514 1312 542 1312 578 1312 586 1312 601 1312 666 1312 687 1312 704 1312 749 1312 811 1312 904 1312 913 1312 915 1312 943 1312 956 1312 1008 1312 1095 1312 1109 1312 1168 1312 1189 1312 1269 1312 1297 1312 1312 1312 1338 1312 1420 1312 1421 1312 1437 1313 83 1313 144 1313 187 1313 217 1313 223 1313 452 1313 497 1313 526 1313 544 1313 562 1313 567 1313 608 1313 822 1313 839 1313 875 1313 883 1313 940 1313 972 1313 1098 1313 1216 1313 1225 1313 1236 1313 1250 1313 1290 1313 1291 1313 1313 1313 1348 1313 1356 1313 1361 1313 1375 1313 1498 1314 26 1314 89 1314 233 1314 267 1314 332 1314 355 1314 436 1314 482 1314 494 1314 598 1314 629 1314 650 1314 708 1314 755 1314 865 1314 895 1314 896 1314 921 1314 965 1314 1009 1314 1079 1314 1286 1314 1314 1314 1321 1314 1341 1314 1349 1314 1403 1314 1467 1314 1485 1314 1494 1315 100 1315 260 1315 329 1315 337 1315 393 1315 417 1315 421 1315 445 1315 459 1315 596 1315 616 1315 679 1315 717 1315 754 1315 759 1315 762 1315 806 1315 922 1315 1042 1315 1045 1315 1070 1315 1077 1315 1139 1315 1241 1315 1315 1315 1317 1315 1387 1315 1428 1315 1438 1315 1445 1315 1470 1316 28 1316 66 1316 116 1316 206 1316 233 1316 244 1316 263 1316 267 1316 283 1316 325 1316 348 1316 349 1316 355 1316 394 1316 399 1316 425 1316 431 1316 444 1316 464 1316 522 1316 552 1316 575 1316 580 1316 623 1316 625 1316 631 1316 646 1316 652 1316 695 1316 708 1316 755 1316 776 1316 795 1316 829 1316 830 1316 896 1316 921 1316 931 1316 995 1316 1007 1316 1046 1316 1059 1316 1064 1316 1140 1316 1199 1316 1204 1316 1244 1316 1261 1316 1316 1316 1378 1316 1403 1316 1446 1316 1467 1316 1468 1316 1481 1316 1494 1317 1 1317 99 1317 100 1317 249 1317 260 1317 265 1317 329 1317 421 1317 445 1317 487 1317 550 1317 602 1317 616 1317 653 1317 656 1317 672 1317 712 1317 717 1317 754 1317 806 1317 820 1317 850 1317 855 1317 922 1317 1042 1317 1074 1317 1175 1317 1195 1317 1226 1317 1315 1317 1317 1317 1337 1317 1342 1317 1397 1317 1428 1317 1438 1318 151 1318 185 1318 244 1318 251 1318 264 1318 398 1318 430 1318 475 1318 480 1318 529 1318 546 1318 598 1318 663 1318 665 1318 674 1318 721 1318 758 1318 760 1318 817 1318 842 1318 934 1318 986 1318 1009 1318 1011 1318 1019 1318 1070 1318 1079 1318 1204 1318 1215 1318 1218 1318 1318 1318 1449 1318 1465 1319 39 1319 112 1319 168 1319 215 1319 258 1319 302 1319 346 1319 409 1319 426 1319 461 1319 553 1319 696 1319 748 1319 954 1319 989 1319 1080 1319 1134 1319 1143 1319 1148 1319 1191 1319 1233 1319 1301 1319 1303 1319 1319 1319 1405 1319 1427 1320 59 1320 67 1320 161 1320 190 1320 335 1320 414 1320 435 1320 774 1320 840 1320 841 1320 857 1320 919 1320 953 1320 1021 1320 1231 1320 1320 1320 1365 1320 1409 1320 1432 1320 1443 1320 1454 1320 1477 1320 1491 1320 1497 1321 26 1321 89 1321 138 1321 267 1321 355 1321 470 1321 475 1321 482 1321 494 1321 598 1321 646 1321 708 1321 715 1321 755 1321 817 1321 895 1321 896 1321 921 1321 965 1321 979 1321 995 1321 1007 1321 1009 1321 1079 1321 1286 1321 1314 1321 1321 1321 1392 1321 1449 1321 1467 1321 1485 1322 16 1322 32 1322 34 1322 40 1322 136 1322 150 1322 171 1322 177 1322 207 1322 213 1322 237 1322 248 1322 252 1322 274 1322 297 1322 317 1322 423 1322 432 1322 439 1322 453 1322 495 1322 588 1322 641 1322 706 1322 744 1322 813 1322 835 1322 848 1322 853 1322 859 1322 868 1322 889 1322 926 1322 936 1322 964 1322 1041 1322 1053 1322 1061 1322 1073 1322 1110 1322 1130 1322 1138 1322 1237 1322 1247 1322 1262 1322 1274 1322 1276 1322 1284 1322 1296 1322 1322 1322 1328 1322 1347 1322 1376 1322 1381 1322 1422 1323 23 1323 122 1323 368 1323 468 1323 503 1323 517 1323 542 1323 551 1323 573 1323 582 1323 643 1323 693 1323 697 1323 811 1323 898 1323 1101 1323 1107 1323 1240 1323 1246 1323 1275 1323 1323 1323 1344 1323 1352 1323 1374 1323 1429 1323 1495 1324 22 1324 148 1324 156 1324 159 1324 196 1324 266 1324 345 1324 378 1324 390 1324 396 1324 403 1324 446 1324 448 1324 449 1324 530 1324 543 1324 548 1324 583 1324 604 1324 621 1324 641 1324 669 1324 707 1324 739 1324 763 1324 764 1324 791 1324 854 1324 873 1324 903 1324 920 1324 948 1324 960 1324 994 1324 1005 1324 1037 1324 1038 1324 1090 1324 1126 1324 1176 1324 1224 1324 1252 1324 1267 1324 1287 1324 1324 1324 1325 1324 1326 1324 1386 1324 1434 1324 1436 1324 1444 1324 1493 1325 156 1325 159 1325 196 1325 252 1325 266 1325 345 1325 383 1325 396 1325 400 1325 448 1325 543 1325 605 1325 615 1325 707 1325 739 1325 764 1325 847 1325 920 1325 947 1325 960 1325 994 1325 1037 1325 1090 1325 1126 1325 1172 1325 1174 1325 1267 1325 1287 1325 1324 1325 1325 1325 1386 1325 1434 1325 1436 1325 1493 1326 7 1326 20 1326 22 1326 31 1326 37 1326 87 1326 123 1326 143 1326 148 1326 156 1326 167 1326 204 1326 219 1326 242 1326 266 1326 292 1326 326 1326 336 1326 350 1326 378 1326 403 1326 446 1326 449 1326 530 1326 583 1326 604 1326 613 1326 621 1326 636 1326 644 1326 669 1326 671 1326 703 1326 777 1326 791 1326 873 1326 900 1326 903 1326 928 1326 935 1326 948 1326 958 1326 962 1326 987 1326 994 1326 1038 1326 1071 1326 1106 1326 1154 1326 1161 1326 1171 1326 1176 1326 1211 1326 1224 1326 1257 1326 1268 1326 1273 1326 1289 1326 1294 1326 1311 1326 1324 1326 1326 1326 1431 1326 1444 1326 1450 1326 1458 1326 1464 1326 1490 1327 26 1327 78 1327 82 1327 102 1327 191 1327 193 1327 200 1327 222 1327 233 1327 312 1327 327 1327 332 1327 405 1327 436 1327 451 1327 465 1327 560 1327 579 1327 598 1327 658 1327 734 1327 758 1327 771 1327 802 1327 863 1327 866 1327 892 1327 901 1327 934 1327 959 1327 1003 1327 1024 1327 1035 1327 1054 1327 1066 1327 1079 1327 1102 1327 1113 1327 1118 1327 1124 1327 1135 1327 1212 1327 1214 1327 1221 1327 1327 1327 1330 1327 1340 1327 1413 1327 1442 1327 1485 1327 1486 1327 1494 1328 16 1328 71 1328 136 1328 150 1328 177 1328 248 1328 297 1328 317 1328 390 1328 423 1328 432 1328 469 1328 519 1328 548 1328 588 1328 632 1328 641 1328 706 1328 738 1328 889 1328 964 1328 977 1328 1053 1328 1073 1328 1130 1328 1255 1328 1274 1328 1284 1328 1322 1328 1328 1328 1367 1328 1416 1328 1422 1328 1480 1329 2 1329 84 1329 97 1329 153 1329 166 1329 194 1329 197 1329 241 1329 247 1329 296 1329 306 1329 362 1329 384 1329 471 1329 488 1329 499 1329 554 1329 566 1329 654 1329 662 1329 670 1329 675 1329 796 1329 825 1329 970 1329 1001 1329 1036 1329 1040 1329 1050 1329 1105 1329 1157 1329 1186 1329 1191 1329 1248 1329 1254 1329 1256 1329 1285 1329 1302 1329 1303 1329 1308 1329 1329 1329 1354 1329 1384 1329 1427 1330 0 1330 26 1330 73 1330 102 1330 130 1330 152 1330 200 1330 205 1330 222 1330 259 1330 312 1330 338 1330 436 1330 442 1330 465 1330 518 1330 560 1330 587 1330 655 1330 701 1330 734 1330 752 1330 758 1330 761 1330 771 1330 778 1330 802 1330 815 1330 866 1330 871 1330 892 1330 897 1330 934 1330 959 1330 983 1330 1035 1330 1085 1330 1102 1330 1113 1330 1118 1330 1124 1330 1145 1330 1212 1330 1214 1330 1221 1330 1271 1330 1327 1330 1330 1330 1340 1330 1382 1330 1400 1330 1413 1330 1442 1330 1486 1331 5 1331 36 1331 92 1331 101 1331 202 1331 230 1331 240 1331 291 1331 365 1331 434 1331 441 1331 526 1331 569 1331 606 1331 612 1331 630 1331 730 1331 867 1331 999 1331 1018 1331 1075 1331 1076 1331 1331 1331 1369 1331 1461 1331 1472 1331 1476 1331 1484 1332 17 1332 66 1332 162 1332 322 1332 354 1332 394 1332 440 1332 464 1332 634 1332 649 1332 720 1332 745 1332 785 1332 792 1332 874 1332 887 1332 969 1332 1047 1332 1067 1332 1089 1332 1125 1332 1165 1332 1213 1332 1238 1332 1283 1332 1332 1332 1372 1333 42 1333 129 1333 172 1333 180 1333 192 1333 340 1333 352 1333 395 1333 575 1333 576 1333 722 1333 745 1333 767 1333 885 1333 961 1333 969 1333 983 1333 1067 1333 1178 1333 1333 1333 1415 1333 1499 1334 30 1334 53 1334 58 1334 90 1334 191 1334 212 1334 222 1334 257 1334 262 1334 270 1334 323 1334 506 1334 533 1334 534 1334 536 1334 537 1334 701 1334 702 1334 734 1334 761 1334 785 1334 808 1334 812 1334 884 1334 967 1334 1003 1334 1024 1334 1035 1334 1054 1334 1057 1334 1118 1334 1124 1334 1135 1334 1141 1334 1187 1334 1219 1334 1249 1334 1334 1334 1390 1334 1459 1334 1486 1335 11 1335 41 1335 94 1335 179 1335 225 1335 249 1335 265 1335 310 1335 339 1335 459 1335 509 1335 523 1335 656 1335 664 1335 713 1335 787 1335 790 1335 821 1335 828 1335 845 1335 855 1335 880 1335 894 1335 912 1335 932 1335 963 1335 974 1335 1045 1335 1063 1335 1081 1335 1158 1335 1163 1335 1170 1335 1181 1335 1223 1335 1335 1336 24 1336 30 1336 38 1336 53 1336 78 1336 102 1336 193 1336 212 1336 216 1336 270 1336 286 1336 348 1336 428 1336 431 1336 451 1336 460 1336 464 1336 506 1336 511 1336 534 1336 549 1336 580 1336 610 1336 631 1336 637 1336 702 1336 720 1336 752 1336 761 1336 769 1336 812 1336 829 1336 863 1336 874 1336 923 1336 1003 1336 1017 1336 1046 1336 1057 1336 1065 1336 1084 1336 1135 1336 1219 1336 1234 1336 1238 1336 1249 1336 1336 1336 1351 1336 1390 1336 1415 1336 1418 1336 1459 1336 1481 1337 1 1337 100 1337 214 1337 260 1337 265 1337 421 1337 476 1337 672 1337 712 1337 759 1337 850 1337 855 1337 856 1337 876 1337 1074 1337 1117 1337 1195 1337 1306 1337 1317 1337 1337 1337 1342 1337 1397 1337 1438 1338 10 1338 33 1338 50 1338 61 1338 68 1338 141 1338 195 1338 210 1338 299 1338 314 1338 341 1338 342 1338 357 1338 364 1338 379 1338 433 1338 493 1338 504 1338 514 1338 542 1338 559 1338 571 1338 578 1338 601 1338 627 1338 666 1338 704 1338 749 1338 766 1338 811 1338 898 1338 904 1338 913 1338 930 1338 1008 1338 1029 1338 1088 1338 1095 1338 1109 1338 1189 1338 1269 1338 1297 1338 1300 1338 1312 1338 1338 1338 1374 1338 1420 1338 1421 1338 1437 1338 1460 1338 1495 1339 24 1339 51 1339 116 1339 124 1339 145 1339 174 1339 235 1339 321 1339 325 1339 355 1339 356 1339 425 1339 429 1339 522 1339 539 1339 552 1339 568 1339 594 1339 629 1339 646 1339 695 1339 714 1339 729 1339 776 1339 832 1339 885 1339 944 1339 985 1339 995 1339 1007 1339 1039 1339 1178 1339 1204 1339 1244 1339 1261 1339 1339 1339 1468 1340 15 1340 53 1340 54 1340 78 1340 82 1340 102 1340 121 1340 191 1340 205 1340 222 1340 257 1340 285 1340 312 1340 351 1340 405 1340 451 1340 490 1340 533 1340 536 1340 563 1340 579 1340 610 1340 619 1340 626 1340 658 1340 685 1340 701 1340 702 1340 752 1340 823 1340 863 1340 901 1340 959 1340 1003 1340 1024 1340 1035 1340 1044 1340 1054 1340 1066 1340 1102 1340 1113 1340 1118 1340 1135 1340 1183 1340 1212 1340 1214 1340 1221 1340 1327 1340 1330 1340 1340 1340 1442 1340 1463 1340 1481 1340 1486 1341 26 1341 58 1341 66 1341 82 1341 86 1341 193 1341 211 1341 250 1341 277 1341 323 1341 332 1341 405 1341 425 1341 440 1341 444 1341 502 1341 563 1341 623 1341 625 1341 626 1341 658 1341 678 1341 720 1341 863 1341 896 1341 959 1341 1009 1341 1024 1341 1035 1341 1054 1341 1064 1341 1165 1341 1283 1341 1309 1341 1314 1341 1341 1341 1390 1341 1449 1342 1 1342 100 1342 214 1342 260 1342 265 1342 415 1342 417 1342 421 1342 476 1342 656 1342 672 1342 712 1342 793 1342 806 1342 850 1342 855 1342 856 1342 876 1342 945 1342 1074 1342 1117 1342 1195 1342 1317 1342 1337 1342 1342 1342 1387 1342 1397 1343 9 1343 15 1343 19 1343 54 1343 73 1343 121 1343 130 1343 152 1343 205 1343 259 1343 285 1343 312 1343 338 1343 485 1343 490 1343 536 1343 587 1343 618 1343 655 1343 685 1343 698 1343 752 1343 778 1343 802 1343 815 1343 823 1343 827 1343 837 1343 871 1343 905 1343 1044 1343 1102 1343 1144 1343 1153 1343 1183 1343 1212 1343 1221 1343 1343 1343 1382 1343 1442 1343 1452 1343 1455 1343 1463 1344 23 1344 122 1344 468 1344 503 1344 517 1344 582 1344 643 1344 693 1344 750 1344 1101 1344 1240 1344 1246 1344 1275 1344 1323 1344 1344 1344 1352 1344 1429 1345 33 1345 61 1345 110 1345 155 1345 169 1345 342 1345 364 1345 447 1345 458 1345 493 1345 586 1345 749 1345 773 1345 843 1345 904 1345 941 1345 943 1345 956 1345 1109 1345 1269 1345 1345 1345 1421 1345 1437 1346 170 1346 219 1346 319 1346 326 1346 416 1346 418 1346 422 1346 457 1346 508 1346 555 1346 593 1346 644 1346 732 1346 736 1346 770 1346 777 1346 800 1346 886 1346 933 1346 997 1346 1010 1346 1015 1346 1020 1346 1112 1346 1146 1346 1161 1346 1167 1346 1200 1346 1205 1346 1268 1346 1311 1346 1346 1346 1388 1346 1402 1346 1426 1346 1431 1346 1433 1346 1462 1346 1479 1347 32 1347 34 1347 40 1347 115 1347 171 1347 177 1347 207 1347 213 1347 237 1347 274 1347 307 1347 439 1347 453 1347 495 1347 744 1347 813 1347 833 1347 835 1347 848 1347 853 1347 859 1347 868 1347 869 1347 926 1347 936 1347 1041 1347 1061 1347 1103 1347 1110 1347 1138 1347 1237 1347 1245 1347 1247 1347 1262 1347 1276 1347 1296 1347 1322 1347 1347 1347 1376 1347 1381 1347 1482 1348 101 1348 187 1348 217 1348 452 1348 497 1348 524 1348 526 1348 544 1348 547 1348 562 1348 567 1348 584 1348 591 1348 606 1348 608 1348 684 1348 822 1348 867 1348 875 1348 908 1348 972 1348 1034 1348 1098 1348 1216 1348 1225 1348 1236 1348 1250 1348 1290 1348 1291 1348 1313 1348 1348 1348 1356 1348 1375 1348 1498 1349 6 1349 42 1349 45 1349 89 1349 124 1349 127 1349 268 1349 392 1349 429 1349 470 1349 482 1349 486 1349 494 1349 501 1349 502 1349 678 1349 686 1349 689 1349 722 1349 726 1349 753 1349 757 1349 775 1349 810 1349 896 1349 921 1349 931 1349 950 1349 968 1349 1007 1349 1072 1349 1160 1349 1201 1349 1304 1349 1314 1349 1349 1349 1399 1349 1403 1350 62 1350 104 1350 105 1350 109 1350 254 1350 346 1350 489 1350 500 1350 532 1350 651 1350 710 1350 737 1350 826 1350 878 1350 899 1350 917 1350 1025 1350 1093 1350 1104 1350 1114 1350 1134 1350 1149 1350 1207 1350 1220 1350 1270 1350 1301 1350 1310 1350 1350 1350 1383 1351 38 1351 78 1351 180 1351 212 1351 216 1351 277 1351 283 1351 286 1351 304 1351 322 1351 328 1351 348 1351 349 1351 354 1351 394 1351 395 1351 399 1351 428 1351 460 1351 464 1351 534 1351 580 1351 631 1351 634 1351 652 1351 681 1351 720 1351 786 1351 795 1351 829 1351 865 1351 874 1351 923 1351 980 1351 1059 1351 1125 1351 1137 1351 1140 1351 1209 1351 1238 1351 1309 1351 1336 1351 1351 1351 1378 1351 1418 1352 195 1352 314 1352 504 1352 517 1352 542 1352 551 1352 571 1352 582 1352 643 1352 666 1352 693 1352 697 1352 811 1352 915 1352 930 1352 1008 1352 1095 1352 1107 1352 1109 1352 1168 1352 1240 1352 1246 1352 1275 1352 1323 1352 1344 1352 1352 1352 1374 1352 1437 1352 1495 1353 66 1353 116 1353 124 1353 129 1353 131 1353 137 1353 145 1353 174 1353 261 1353 322 1353 323 1353 356 1353 392 1353 486 1353 502 1353 539 1353 576 1353 649 1353 745 1353 757 1353 767 1353 885 1353 944 1353 992 1353 1067 1353 1072 1353 1155 1353 1173 1353 1178 1353 1209 1353 1244 1353 1353 1353 1372 1353 1401 1354 2 1354 74 1354 84 1354 93 1354 95 1354 97 1354 126 1354 153 1354 194 1354 239 1354 247 1354 271 1354 282 1354 296 1354 315 1354 362 1354 407 1354 499 1354 564 1354 614 1354 654 1354 662 1354 670 1354 796 1354 801 1354 838 1354 858 1354 970 1354 975 1354 1001 1354 1002 1354 1036 1354 1050 1354 1105 1354 1157 1354 1227 1354 1248 1354 1329 1354 1354 1354 1384 1354 1394 1354 1395 1354 1478 1355 79 1355 125 1355 147 1355 189 1355 253 1355 272 1355 295 1355 305 1355 344 1355 373 1355 404 1355 478 1355 483 1355 484 1355 491 1355 556 1355 591 1355 600 1355 611 1355 624 1355 640 1355 684 1355 690 1355 694 1355 743 1355 799 1355 807 1355 814 1355 839 1355 860 1355 888 1355 910 1355 911 1355 978 1355 990 1355 993 1355 999 1355 1014 1355 1069 1355 1075 1355 1082 1355 1202 1355 1217 1355 1236 1355 1250 1355 1277 1355 1278 1355 1281 1355 1290 1355 1355 1355 1356 1355 1370 1355 1375 1355 1407 1355 1456 1355 1484 1356 79 1356 83 1356 144 1356 187 1356 217 1356 232 1356 253 1356 279 1356 305 1356 452 1356 478 1356 484 1356 526 1356 544 1356 567 1356 584 1356 591 1356 612 1356 640 1356 684 1356 690 1356 807 1356 814 1356 822 1356 839 1356 860 1356 875 1356 908 1356 940 1356 972 1356 990 1356 1078 1356 1082 1356 1142 1356 1216 1356 1217 1356 1229 1356 1236 1356 1250 1356 1290 1356 1313 1356 1348 1356 1355 1356 1356 1356 1361 1356 1370 1356 1375 1356 1498 1357 4 1357 71 1357 155 1357 248 1357 331 1357 469 1357 519 1357 632 1357 716 1357 738 1357 977 1357 1053 1357 1073 1357 1188 1357 1357 1357 1367 1357 1416 1357 1423 1357 1451 1357 1480 1358 44 1358 57 1358 72 1358 76 1358 135 1358 144 1358 147 1358 149 1358 189 1358 232 1358 253 1358 305 1358 344 1358 370 1358 375 1358 388 1358 397 1358 424 1358 455 1358 491 1358 556 1358 591 1358 611 1358 684 1358 733 1358 799 1358 860 1358 893 1358 990 1358 993 1358 1136 1358 1179 1358 1202 1358 1235 1358 1250 1358 1278 1358 1290 1358 1358 1358 1393 1358 1456 1359 38 1359 137 1359 174 1359 180 1359 216 1359 261 1359 269 1359 304 1359 322 1359 431 1359 506 1359 549 1359 590 1359 695 1359 745 1359 792 1359 980 1359 1017 1359 1047 1359 1065 1359 1067 1359 1089 1359 1125 1359 1141 1359 1209 1359 1219 1359 1234 1359 1359 1360 9 1360 15 1360 54 1360 121 1360 130 1360 158 1360 182 1360 205 1360 221 1360 229 1360 257 1360 262 1360 285 1360 351 1360 428 1360 462 1360 485 1360 490 1360 511 1360 533 1360 534 1360 536 1360 610 1360 618 1360 619 1360 637 1360 698 1360 701 1360 808 1360 823 1360 827 1360 837 1360 864 1360 1044 1360 1144 1360 1183 1360 1187 1360 1219 1360 1258 1360 1360 1360 1448 1361 72 1361 83 1361 187 1361 217 1361 223 1361 224 1361 279 1361 343 1361 371 1361 377 1361 389 1361 408 1361 452 1361 478 1361 483 1361 497 1361 524 1361 544 1361 547 1361 562 1361 567 1361 584 1361 592 1361 600 1361 638 1361 640 1361 807 1361 814 1361 844 1361 875 1361 906 1361 908 1361 972 1361 1034 1361 1068 1361 1078 1361 1098 1361 1099 1361 1142 1361 1180 1361 1198 1361 1216 1361 1225 1361 1236 1361 1250 1361 1299 1361 1313 1361 1356 1361 1361 1361 1373 1361 1407 1361 1474 1361 1496 1362 6 1362 29 1362 42 1362 48 1362 51 1362 94 1362 124 1362 131 1362 140 1362 172 1362 256 1362 303 1362 310 1362 313 1362 321 1362 339 1362 413 1362 459 1362 486 1362 512 1362 521 1362 545 1362 635 1362 664 1362 688 1362 695 1362 713 1362 718 1362 726 1362 729 1362 741 1362 746 1362 757 1362 772 1362 782 1362 810 1362 852 1362 880 1362 961 1362 1033 1362 1049 1362 1052 1362 1081 1362 1086 1362 1163 1362 1181 1362 1201 1362 1208 1362 1239 1362 1362 1362 1363 1362 1399 1363 6 1363 25 1363 42 1363 48 1363 70 1363 94 1363 108 1363 163 1363 172 1363 256 1363 273 1363 276 1363 303 1363 313 1363 374 1363 382 1363 406 1363 438 1363 498 1363 512 1363 635 1363 718 1363 722 1363 731 1363 782 1363 803 1363 810 1363 894 1363 961 1363 1011 1363 1031 1363 1032 1363 1052 1363 1055 1363 1181 1363 1201 1363 1208 1363 1228 1363 1239 1363 1263 1363 1362 1363 1363 1363 1399 1363 1488 1364 10 1364 23 1364 49 1364 50 1364 68 1364 75 1364 128 1364 141 1364 184 1364 203 1364 290 1364 294 1364 368 1364 376 1364 433 1364 443 1364 517 1364 538 1364 571 1364 573 1364 574 1364 582 1364 589 1364 657 1364 671 1364 673 1364 697 1364 770 1364 805 1364 836 1364 916 1364 930 1364 955 1364 1020 1364 1088 1364 1101 1364 1107 1364 1203 1364 1300 1364 1364 1364 1429 1364 1460 1364 1483 1365 59 1365 67 1365 161 1365 190 1365 335 1365 414 1365 435 1365 774 1365 840 1365 857 1365 1021 1365 1231 1365 1320 1365 1365 1365 1409 1365 1432 1365 1443 1365 1477 1365 1491 1365 1497 1366 43 1366 46 1366 104 1366 118 1366 176 1366 208 1366 287 1366 309 1366 369 1366 385 1366 456 1366 500 1366 532 1366 541 1366 557 1366 565 1366 651 1366 724 1366 747 1366 779 1366 878 1366 902 1366 927 1366 957 1366 1013 1366 1030 1366 1150 1366 1182 1366 1210 1366 1220 1366 1243 1366 1264 1366 1270 1366 1279 1366 1295 1366 1366 1366 1380 1366 1489 1367 4 1367 71 1367 148 1367 155 1367 248 1367 331 1367 469 1367 519 1367 548 1367 632 1367 716 1367 738 1367 977 1367 1053 1367 1073 1367 1130 1367 1188 1367 1255 1367 1328 1367 1357 1367 1367 1367 1416 1367 1423 1367 1451 1367 1480 1368 39 1368 46 1368 104 1368 109 1368 112 1368 118 1368 208 1368 258 1368 309 1368 346 1368 409 1368 500 1368 532 1368 724 1368 747 1368 878 1368 899 1368 954 1368 989 1368 1025 1368 1114 1368 1128 1368 1134 1368 1148 1368 1182 1368 1207 1368 1233 1368 1243 1368 1368 1368 1380 1369 5 1369 13 1369 14 1369 47 1369 85 1369 92 1369 101 1369 202 1369 218 1369 230 1369 240 1369 291 1369 365 1369 434 1369 441 1369 569 1369 603 1369 606 1369 609 1369 612 1369 620 1369 630 1369 730 1369 867 1369 870 1369 883 1369 999 1369 1018 1369 1028 1369 1076 1369 1108 1369 1129 1369 1159 1369 1206 1369 1236 1369 1331 1369 1369 1369 1461 1369 1472 1369 1476 1370 47 1370 76 1370 83 1370 135 1370 189 1370 217 1370 253 1370 295 1370 305 1370 373 1370 387 1370 408 1370 478 1370 483 1370 556 1370 567 1370 591 1370 600 1370 611 1370 612 1370 680 1370 684 1370 690 1370 743 1370 784 1370 814 1370 822 1370 839 1370 844 1370 911 1370 940 1370 978 1370 990 1370 1014 1370 1018 1370 1097 1370 1142 1370 1180 1370 1206 1370 1216 1370 1217 1370 1229 1370 1230 1370 1250 1370 1277 1370 1281 1370 1290 1370 1355 1370 1356 1370 1370 1370 1375 1370 1407 1370 1441 1370 1474 1370 1484 1370 1498 1371 0 1371 119 1371 197 1371 220 1371 238 1371 264 1371 298 1371 301 1371 330 1371 367 1371 398 1371 442 1371 482 1371 518 1371 560 1371 645 1371 650 1371 689 1371 731 1371 765 1371 794 1371 803 1371 824 1371 866 1371 872 1371 892 1371 983 1371 1031 1371 1083 1371 1085 1371 1145 1371 1147 1371 1214 1371 1222 1371 1228 1371 1260 1371 1263 1371 1271 1371 1305 1371 1371 1371 1398 1371 1400 1371 1468 1371 1488 1372 66 1372 96 1372 124 1372 127 1372 131 1372 162 1372 243 1372 261 1372 289 1372 356 1372 392 1372 479 1372 486 1372 501 1372 502 1372 539 1372 568 1372 649 1372 679 1372 705 1372 714 1372 726 1372 746 1372 753 1372 797 1372 831 1372 879 1372 881 1372 885 1372 942 1372 944 1372 946 1372 991 1372 1072 1372 1089 1372 1111 1372 1173 1372 1201 1372 1213 1372 1244 1372 1292 1372 1332 1372 1353 1372 1372 1373 14 1373 36 1373 55 1373 56 1373 83 1373 101 1373 164 1373 187 1373 218 1373 223 1373 224 1373 279 1373 291 1373 343 1373 371 1373 377 1373 389 1373 391 1373 408 1373 492 1373 497 1373 524 1373 544 1373 547 1373 562 1373 592 1373 603 1373 620 1373 638 1373 640 1373 648 1373 667 1373 730 1373 784 1373 844 1373 867 1373 870 1373 906 1373 940 1373 972 1373 1034 1373 1068 1373 1078 1373 1091 1373 1098 1373 1099 1373 1225 1373 1299 1373 1361 1373 1373 1373 1407 1373 1441 1373 1474 1373 1496 1374 10 1374 68 1374 141 1374 195 1374 299 1374 314 1374 342 1374 357 1374 368 1374 379 1374 504 1374 542 1374 551 1374 571 1374 582 1374 657 1374 687 1374 693 1374 697 1374 704 1374 749 1374 811 1374 904 1374 913 1374 915 1374 930 1374 943 1374 1008 1374 1088 1374 1095 1374 1107 1374 1109 1374 1168 1374 1189 1374 1240 1374 1246 1374 1269 1374 1275 1374 1300 1374 1323 1374 1338 1374 1352 1374 1374 1374 1420 1374 1437 1374 1460 1374 1495 1375 79 1375 189 1375 217 1375 232 1375 253 1375 279 1375 295 1375 305 1375 344 1375 373 1375 401 1375 404 1375 408 1375 452 1375 478 1375 484 1375 526 1375 544 1375 556 1375 567 1375 584 1375 591 1375 612 1375 624 1375 640 1375 684 1375 690 1375 743 1375 807 1375 814 1375 822 1375 839 1375 860 1375 875 1375 940 1375 978 1375 990 1375 1014 1375 1075 1375 1082 1375 1142 1375 1196 1375 1216 1375 1217 1375 1229 1375 1235 1375 1236 1375 1250 1375 1281 1375 1290 1375 1313 1375 1348 1375 1355 1375 1356 1375 1370 1375 1375 1375 1498 1376 32 1376 34 1376 40 1376 139 1376 150 1376 171 1376 213 1376 237 1376 307 1376 366 1376 423 1376 439 1376 453 1376 495 1376 783 1376 813 1376 833 1376 835 1376 848 1376 859 1376 868 1376 869 1376 889 1376 926 1376 936 1376 1041 1376 1061 1376 1103 1376 1110 1376 1138 1376 1237 1376 1247 1376 1262 1376 1276 1376 1284 1376 1296 1376 1322 1376 1347 1376 1376 1376 1381 1376 1406 1377 117 1377 120 1377 239 1377 271 1377 275 1377 293 1377 311 1377 353 1377 361 1377 372 1377 415 1377 450 1377 564 1377 647 1377 677 1377 719 1377 793 1377 971 1377 982 1377 1023 1377 1056 1377 1058 1377 1105 1377 1157 1377 1253 1377 1282 1377 1307 1377 1377 1377 1394 1377 1395 1377 1424 1377 1435 1377 1447 1378 82 1378 200 1378 233 1378 244 1378 283 1378 348 1378 355 1378 399 1378 575 1378 580 1378 623 1378 625 1378 631 1378 681 1378 708 1378 795 1378 865 1378 921 1378 980 1378 1007 1378 1059 1378 1064 1378 1113 1378 1199 1378 1271 1378 1316 1378 1351 1378 1378 1378 1403 1378 1467 1378 1485 1378 1494 1379 190 1379 195 1379 204 1379 294 1379 574 1379 639 1379 836 1379 841 1379 919 1379 930 1379 953 1379 987 1379 1169 1379 1203 1379 1273 1379 1379 1379 1454 1379 1458 1379 1460 1380 43 1380 46 1380 77 1380 104 1380 105 1380 109 1380 112 1380 118 1380 154 1380 176 1380 208 1380 258 1380 287 1380 309 1380 369 1380 385 1380 409 1380 456 1380 500 1380 532 1380 541 1380 557 1380 565 1380 633 1380 651 1380 710 1380 724 1380 747 1380 779 1380 826 1380 861 1380 927 1380 954 1380 957 1380 1013 1380 1025 1380 1030 1380 1114 1380 1128 1380 1182 1380 1210 1380 1243 1380 1270 1380 1279 1380 1295 1380 1310 1380 1366 1380 1368 1380 1380 1380 1439 1380 1489 1381 32 1381 40 1381 115 1381 139 1381 150 1381 171 1381 177 1381 207 1381 213 1381 237 1381 248 1381 307 1381 317 1381 366 1381 432 1381 439 1381 453 1381 495 1381 588 1381 706 1381 744 1381 835 1381 848 1381 853 1381 859 1381 868 1381 869 1381 889 1381 926 1381 936 1381 1041 1381 1061 1381 1103 1381 1138 1381 1237 1381 1247 1381 1262 1381 1276 1381 1296 1381 1322 1381 1347 1381 1376 1381 1381 1381 1406 1381 1482 1382 15 1382 19 1382 54 1382 73 1382 121 1382 130 1382 152 1382 205 1382 259 1382 285 1382 312 1382 338 1382 465 1382 536 1382 560 1382 587 1382 599 1382 655 1382 685 1382 698 1382 701 1382 734 1382 752 1382 761 1382 778 1382 802 1382 815 1382 837 1382 871 1382 892 1382 905 1382 1044 1382 1118 1382 1124 1382 1153 1382 1212 1382 1214 1382 1221 1382 1330 1382 1343 1382 1382 1382 1400 1382 1413 1382 1419 1382 1442 1382 1455 1382 1463 1382 1486 1383 62 1383 104 1383 105 1383 109 1383 208 1383 254 1383 346 1383 410 1383 426 1383 456 1383 532 1383 633 1383 651 1383 723 1383 826 1383 878 1383 899 1383 917 1383 989 1383 1030 1383 1104 1383 1149 1383 1207 1383 1220 1383 1270 1383 1310 1383 1350 1383 1383 1384 2 1384 93 1384 95 1384 97 1384 114 1384 153 1384 197 1384 220 1384 247 1384 296 1384 362 1384 384 1384 407 1384 463 1384 499 1384 564 1384 654 1384 662 1384 663 1384 721 1384 780 1384 796 1384 825 1384 970 1384 982 1384 1001 1384 1036 1384 1050 1384 1105 1384 1186 1384 1194 1384 1242 1384 1248 1384 1256 1384 1329 1384 1354 1384 1384 1384 1385 1384 1394 1385 2 1385 25 1385 69 1385 111 1385 117 1385 146 1385 153 1385 181 1385 220 1385 353 1385 362 1385 450 1385 454 1385 463 1385 516 1385 523 1385 692 1385 780 1385 794 1385 894 1385 970 1385 982 1385 1012 1385 1055 1385 1056 1385 1083 1385 1105 1385 1133 1385 1186 1385 1194 1385 1253 1385 1256 1385 1260 1385 1298 1385 1384 1385 1385 1385 1396 1385 1447 1385 1488 1386 22 1386 156 1386 159 1386 196 1386 266 1386 345 1386 378 1386 383 1386 390 1386 400 1386 403 1386 448 1386 449 1386 507 1386 530 1386 543 1386 570 1386 605 1386 615 1386 621 1386 641 1386 707 1386 739 1386 763 1386 764 1386 791 1386 847 1386 854 1386 862 1386 873 1386 920 1386 947 1386 948 1386 960 1386 994 1386 1005 1386 1037 1386 1090 1386 1126 1386 1127 1386 1162 1386 1172 1386 1174 1386 1176 1386 1252 1386 1287 1386 1324 1386 1325 1386 1386 1386 1434 1386 1436 1386 1444 1386 1493 1387 1 1387 100 1387 140 1387 246 1387 260 1387 320 1387 393 1387 417 1387 445 1387 596 1387 616 1387 653 1387 672 1387 688 1387 712 1387 740 1387 754 1387 762 1387 772 1387 806 1387 855 1387 856 1387 880 1387 922 1387 945 1387 974 1387 998 1387 1042 1387 1049 1387 1094 1387 1139 1387 1158 1387 1177 1387 1181 1387 1195 1387 1306 1387 1315 1387 1342 1387 1387 1387 1397 1387 1438 1387 1453 1387 1470 1387 1473 1388 37 1388 170 1388 219 1388 242 1388 319 1388 326 1388 350 1388 360 1388 416 1388 418 1388 457 1388 508 1388 555 1388 559 1388 589 1388 593 1388 622 1388 639 1388 644 1388 703 1388 732 1388 766 1388 770 1388 777 1388 800 1388 886 1388 933 1388 955 1388 997 1388 1010 1388 1015 1388 1020 1388 1071 1388 1087 1388 1112 1388 1154 1388 1161 1388 1166 1388 1167 1388 1200 1388 1205 1388 1257 1388 1268 1388 1311 1388 1346 1388 1388 1388 1426 1388 1431 1388 1479 1389 9 1389 15 1389 54 1389 158 1389 182 1389 205 1389 221 1389 229 1389 381 1389 462 1389 473 1389 485 1389 490 1389 618 1389 735 1389 823 1389 837 1389 849 1389 864 1389 1144 1389 1153 1389 1258 1389 1389 1389 1448 1389 1452 1389 1463 1390 30 1390 53 1390 58 1390 78 1390 86 1390 90 1390 102 1390 175 1390 191 1390 212 1390 216 1390 270 1390 286 1390 323 1390 349 1390 440 1390 444 1390 460 1390 464 1390 511 1390 537 1390 549 1390 563 1390 580 1390 610 1390 623 1390 625 1390 631 1390 720 1390 761 1390 785 1390 812 1390 829 1390 884 1390 905 1390 923 1390 967 1390 1003 1390 1035 1390 1057 1390 1124 1390 1141 1390 1238 1390 1249 1390 1334 1390 1336 1390 1341 1390 1390 1390 1418 1390 1459 1390 1481 1391 74 1391 113 1391 132 1391 166 1391 201 1391 227 1391 231 1391 241 1391 306 1391 324 1391 384 1391 386 1391 420 1391 472 1391 474 1391 481 1391 515 1391 553 1391 554 1391 566 1391 581 1391 696 1391 723 1391 728 1391 748 1391 798 1391 804 1391 818 1391 924 1391 1002 1391 1096 1391 1104 1391 1143 1391 1232 1391 1254 1391 1259 1391 1272 1391 1285 1391 1302 1391 1303 1391 1391 1392 127 1392 228 1392 267 1392 289 1392 318 1392 513 1392 535 1392 679 1392 834 1392 925 1392 946 1392 965 1392 979 1392 988 1392 1016 1392 1111 1392 1215 1392 1241 1392 1286 1392 1321 1392 1392 1392 1408 1392 1449 1392 1471 1393 44 1393 57 1393 72 1393 76 1393 135 1393 144 1393 149 1393 224 1393 232 1393 370 1393 388 1393 391 1393 397 1393 401 1393 424 1393 455 1393 491 1393 520 1393 556 1393 591 1393 611 1393 733 1393 844 1393 860 1393 893 1393 911 1393 1136 1393 1179 1393 1230 1393 1235 1393 1358 1393 1393 1394 2 1394 74 1394 84 1394 93 1394 95 1394 120 1394 126 1394 153 1394 194 1394 201 1394 231 1394 239 1394 241 1394 271 1394 282 1394 296 1394 311 1394 315 1394 361 1394 450 1394 463 1394 515 1394 516 1394 564 1394 654 1394 662 1394 719 1394 801 1394 838 1394 858 1394 970 1394 971 1394 975 1394 1001 1394 1023 1394 1036 1394 1050 1394 1056 1394 1058 1394 1116 1394 1119 1394 1122 1394 1157 1394 1194 1394 1248 1394 1253 1394 1280 1394 1282 1394 1307 1394 1354 1394 1377 1394 1384 1394 1394 1394 1395 1394 1424 1394 1435 1394 1478 1395 93 1395 120 1395 239 1395 271 1395 311 1395 315 1395 361 1395 450 1395 463 1395 564 1395 647 1395 677 1395 719 1395 825 1395 858 1395 1023 1395 1050 1395 1056 1395 1058 1395 1253 1395 1307 1395 1354 1395 1377 1395 1394 1395 1395 1395 1424 1395 1435 1396 2 1396 25 1396 69 1396 93 1396 95 1396 111 1396 117 1396 119 1396 126 1396 153 1396 227 1396 231 1396 247 1396 282 1396 296 1396 353 1396 362 1396 384 1396 427 1396 450 1396 454 1396 463 1396 516 1396 564 1396 794 1396 796 1396 801 1396 838 1396 970 1396 982 1396 1001 1396 1002 1396 1012 1396 1050 1396 1056 1396 1083 1396 1105 1396 1119 1396 1122 1396 1133 1396 1186 1396 1194 1396 1222 1396 1253 1396 1256 1396 1260 1396 1280 1396 1282 1396 1298 1396 1385 1396 1396 1396 1478 1397 1 1397 18 1397 100 1397 260 1397 265 1397 417 1397 421 1397 616 1397 672 1397 712 1397 717 1397 806 1397 850 1397 856 1397 876 1397 907 1397 945 1397 998 1397 1074 1397 1117 1397 1195 1397 1226 1397 1306 1397 1317 1397 1337 1397 1342 1397 1387 1397 1397 1397 1438 1397 1453 1397 1473 1398 0 1398 29 1398 51 1398 186 1398 220 1398 358 1398 367 1398 419 1398 437 1398 545 1398 560 1398 597 1398 676 1398 699 1398 715 1398 729 1398 768 1398 821 1398 828 1398 872 1398 895 1398 973 1398 996 1398 1083 1398 1197 1398 1371 1398 1398 1399 6 1399 29 1399 42 1399 45 1399 48 1399 51 1399 70 1399 108 1399 256 1399 273 1399 278 1399 303 1399 339 1399 363 1399 437 1399 438 1399 467 1399 512 1399 521 1399 635 1399 664 1399 718 1399 722 1399 729 1399 731 1399 782 1399 810 1399 845 1399 855 1399 880 1399 961 1399 1033 1399 1052 1399 1081 1399 1086 1399 1163 1399 1164 1399 1201 1399 1208 1399 1228 1399 1239 1399 1263 1399 1349 1399 1362 1399 1363 1399 1399 1399 1466 1399 1487 1399 1488 1400 0 1400 24 1400 73 1400 152 1400 197 1400 200 1400 238 1400 259 1400 270 1400 298 1400 301 1400 312 1400 327 1400 330 1400 338 1400 442 1400 475 1400 518 1400 560 1400 629 1400 655 1400 734 1400 752 1400 765 1400 771 1400 778 1400 815 1400 824 1400 866 1400 892 1400 983 1400 1085 1400 1113 1400 1124 1400 1145 1400 1147 1400 1212 1400 1214 1400 1266 1400 1271 1400 1305 1400 1330 1400 1371 1400 1382 1400 1400 1400 1412 1400 1413 1400 1468 1400 1486 1401 116 1401 137 1401 145 1401 174 1401 192 1401 261 1401 323 1401 356 1401 539 1401 568 1401 714 1401 885 1401 938 1401 944 1401 985 1401 1187 1401 1353 1401 1401 1401 1411 1402 7 1402 20 1402 31 1402 123 1402 170 1402 242 1402 300 1402 333 1402 336 1402 558 1402 593 1402 607 1402 703 1402 736 1402 763 1402 916 1402 1071 1402 1100 1402 1106 1402 1112 1402 1127 1402 1156 1402 1161 1402 1171 1402 1184 1402 1188 1402 1211 1402 1224 1402 1346 1402 1402 1402 1404 1402 1462 1402 1490 1403 24 1403 28 1403 116 1403 206 1403 238 1403 267 1403 325 1403 355 1403 425 1403 429 1403 482 1403 502 1403 539 1403 552 1403 580 1403 625 1403 629 1403 652 1403 689 1403 708 1403 715 1403 755 1403 824 1403 931 1403 944 1403 985 1403 995 1403 1007 1403 1059 1403 1064 1403 1178 1403 1204 1403 1244 1403 1261 1403 1314 1403 1316 1403 1349 1403 1378 1403 1403 1403 1499 1404 20 1404 31 1404 87 1404 148 1404 170 1404 204 1404 292 1404 294 1404 300 1404 333 1404 336 1404 403 1404 519 1404 538 1404 548 1404 558 1404 607 1404 671 1404 763 1404 862 1404 948 1404 960 1404 1127 1404 1156 1404 1161 1404 1184 1404 1188 1404 1224 1404 1402 1404 1404 1404 1458 1404 1462 1404 1490 1405 39 1405 166 1405 168 1405 215 1405 302 1405 334 1405 409 1405 426 1405 461 1405 471 1405 472 1405 489 1405 553 1405 696 1405 710 1405 748 1405 899 1405 954 1405 1040 1405 1096 1405 1134 1405 1143 1405 1191 1405 1233 1405 1254 1405 1285 1405 1303 1405 1319 1405 1405 1405 1427 1405 1469 1406 32 1406 40 1406 115 1406 139 1406 150 1406 171 1406 177 1406 237 1406 307 1406 366 1406 453 1406 833 1406 835 1406 869 1406 926 1406 1061 1406 1103 1406 1138 1406 1245 1406 1247 1406 1262 1406 1276 1406 1296 1406 1376 1406 1381 1406 1406 1406 1482 1407 47 1407 72 1407 144 1407 223 1407 224 1407 232 1407 279 1407 295 1407 343 1407 371 1407 389 1407 391 1407 408 1407 478 1407 483 1407 526 1407 592 1407 600 1407 638 1407 640 1407 648 1407 680 1407 684 1407 784 1407 814 1407 822 1407 839 1407 844 1407 888 1407 906 1407 910 1407 911 1407 940 1407 972 1407 978 1407 1014 1407 1068 1407 1078 1407 1097 1407 1099 1407 1142 1407 1180 1407 1216 1407 1229 1407 1281 1407 1299 1407 1355 1407 1361 1407 1370 1407 1373 1407 1407 1407 1441 1407 1474 1407 1498 1408 41 1408 81 1408 99 1408 106 1408 151 1408 199 1408 245 1408 318 1408 329 1408 337 1408 347 1408 393 1408 430 1408 487 1408 496 1408 505 1408 510 1408 513 1408 535 1408 550 1408 585 1408 596 1408 602 1408 665 1408 686 1408 754 1408 787 1408 790 1408 820 1408 834 1408 922 1408 929 1408 949 1408 950 1408 965 1408 968 1408 986 1408 1000 1408 1019 1408 1042 1408 1048 1408 1070 1408 1152 1408 1190 1408 1241 1408 1251 1408 1286 1408 1304 1408 1392 1408 1408 1408 1425 1408 1428 1408 1445 1408 1449 1408 1465 1408 1471 1409 59 1409 67 1409 161 1409 190 1409 335 1409 414 1409 435 1409 774 1409 840 1409 857 1409 1021 1409 1231 1409 1320 1409 1365 1409 1409 1409 1432 1409 1443 1409 1477 1409 1491 1409 1497 1410 27 1410 89 1410 127 1410 162 1410 228 1410 243 1410 289 1410 486 1410 501 1410 679 1410 741 1410 775 1410 786 1410 789 1410 830 1410 831 1410 909 1410 921 1410 925 1410 929 1410 946 1410 988 1410 991 1410 1048 1410 1111 1410 1213 1410 1410 1410 1414 1410 1425 1410 1446 1411 145 1411 261 1411 356 1411 568 1411 714 1411 751 1411 938 1411 1401 1411 1411 1411 1497 1412 185 1412 197 1412 238 1412 264 1412 281 1412 288 1412 298 1412 330 1412 338 1412 398 1412 442 1412 480 1412 518 1412 546 1412 587 1412 598 1412 650 1412 663 1412 674 1412 758 1412 760 1412 765 1412 803 1412 824 1412 842 1412 866 1412 871 1412 892 1412 996 1412 1011 1412 1031 1412 1079 1412 1085 1412 1145 1412 1147 1412 1218 1412 1222 1412 1242 1412 1266 1412 1271 1412 1305 1412 1400 1412 1412 1412 1413 1412 1440 1413 73 1413 130 1413 152 1413 185 1413 200 1413 259 1413 264 1413 270 1413 312 1413 338 1413 359 1413 398 1413 436 1413 442 1413 475 1413 518 1413 560 1413 587 1413 650 1413 655 1413 734 1413 752 1413 758 1413 761 1413 771 1413 778 1413 815 1413 897 1413 905 1413 959 1413 967 1413 1079 1413 1085 1413 1102 1413 1113 1413 1124 1413 1145 1413 1212 1413 1214 1413 1266 1413 1271 1413 1305 1413 1327 1413 1330 1413 1382 1413 1400 1413 1412 1413 1413 1413 1486 1414 27 1414 28 1414 89 1414 96 1414 127 1414 162 1414 228 1414 243 1414 289 1414 328 1414 354 1414 479 1414 501 1414 552 1414 561 1414 634 1414 652 1414 678 1414 711 1414 714 1414 775 1414 786 1414 789 1414 797 1414 830 1414 831 1414 879 1414 887 1414 890 1414 909 1414 921 1414 942 1414 968 1414 988 1414 991 1414 995 1414 1000 1414 1047 1414 1072 1414 1092 1414 1111 1414 1120 1414 1213 1414 1410 1414 1414 1414 1446 1415 129 1415 180 1415 192 1415 262 1415 269 1415 286 1415 340 1415 352 1415 395 1415 460 1415 506 1415 590 1415 637 1415 700 1415 745 1415 769 1415 808 1415 815 1415 851 1415 967 1415 1065 1415 1187 1415 1219 1415 1249 1415 1333 1415 1336 1415 1415 1415 1418 1416 16 1416 71 1416 136 1416 177 1416 207 1416 248 1416 274 1416 297 1416 331 1416 390 1416 423 1416 432 1416 469 1416 519 1416 548 1416 588 1416 632 1416 641 1416 706 1416 738 1416 964 1416 977 1416 1053 1416 1073 1416 1130 1416 1252 1416 1255 1416 1274 1416 1328 1416 1357 1416 1367 1416 1416 1416 1422 1416 1423 1416 1451 1416 1480 1417 29 1417 41 1417 45 1417 51 1417 70 1417 98 1417 151 1417 185 1417 186 1417 199 1417 256 1417 278 1417 281 1417 339 1417 359 1417 367 1417 380 1417 419 1417 437 1417 470 1417 496 1417 545 1417 594 1417 597 1417 635 1417 645 1417 661 1417 665 1417 676 1417 682 1417 683 1417 686 1417 699 1417 729 1417 731 1417 760 1417 828 1417 832 1417 872 1417 895 1417 921 1417 929 1417 931 1417 949 1417 950 1417 965 1417 986 1417 1011 1417 1060 1417 1086 1417 1152 1417 1197 1417 1208 1417 1239 1417 1304 1417 1417 1417 1440 1417 1487 1418 30 1418 38 1418 53 1418 78 1418 212 1418 216 1418 270 1418 286 1418 308 1418 349 1418 431 1418 460 1418 464 1418 511 1418 534 1418 549 1418 631 1418 637 1418 720 1418 761 1418 792 1418 812 1418 829 1418 874 1418 923 1418 1057 1418 1065 1418 1084 1418 1219 1418 1238 1418 1249 1418 1336 1418 1351 1418 1390 1418 1415 1418 1418 1418 1459 1418 1481 1419 3 1419 8 1419 19 1419 64 1419 259 1419 288 1419 312 1419 330 1419 473 1419 499 1419 527 1419 587 1419 599 1419 614 1419 628 1419 709 1419 734 1419 765 1419 802 1419 816 1419 849 1419 871 1419 892 1419 951 1419 1132 1419 1214 1419 1242 1419 1382 1419 1419 1419 1442 1419 1463 1420 33 1420 61 1420 110 1420 141 1420 169 1420 195 1420 299 1420 314 1420 341 1420 342 1420 364 1420 379 1420 447 1420 458 1420 493 1420 504 1420 514 1420 571 1420 578 1420 687 1420 704 1420 749 1420 811 1420 904 1420 913 1420 915 1420 1109 1420 1168 1420 1189 1420 1269 1420 1275 1420 1312 1420 1338 1420 1374 1420 1420 1420 1421 1420 1437 1420 1495 1421 33 1421 61 1421 103 1421 110 1421 169 1421 341 1421 342 1421 364 1421 447 1421 458 1421 493 1421 504 1421 542 1421 586 1421 687 1421 704 1421 749 1421 773 1421 843 1421 904 1421 913 1421 915 1421 941 1421 943 1421 956 1421 1095 1421 1109 1421 1168 1421 1269 1421 1297 1421 1312 1421 1338 1421 1345 1421 1420 1421 1421 1421 1437 1422 34 1422 136 1422 207 1422 274 1422 297 1422 390 1422 423 1422 432 1422 439 1422 469 1422 495 1422 548 1422 588 1422 641 1422 706 1422 738 1422 813 1422 868 1422 889 1422 964 1422 977 1422 1041 1422 1110 1422 1130 1422 1174 1422 1252 1422 1255 1422 1274 1422 1284 1422 1322 1422 1328 1422 1416 1422 1422 1422 1480 1422 1493 1423 4 1423 71 1423 155 1423 248 1423 331 1423 469 1423 519 1423 548 1423 632 1423 716 1423 738 1423 977 1423 1053 1423 1073 1423 1188 1423 1357 1423 1367 1423 1416 1423 1423 1423 1451 1423 1480 1424 84 1424 120 1424 239 1424 271 1424 275 1424 293 1424 311 1424 315 1424 361 1424 647 1424 677 1424 719 1424 793 1424 858 1424 971 1424 1006 1424 1023 1424 1056 1424 1058 1424 1157 1424 1307 1424 1377 1424 1394 1424 1395 1424 1424 1424 1435 1425 28 1425 41 1425 81 1425 89 1425 124 1425 138 1425 151 1425 268 1425 318 1425 382 1425 406 1425 470 1425 496 1425 501 1425 505 1425 510 1425 513 1425 535 1425 540 1425 678 1425 681 1425 686 1425 713 1425 781 1425 790 1425 795 1425 817 1425 830 1425 831 1425 834 1425 865 1425 896 1425 921 1425 929 1425 950 1425 965 1425 986 1425 995 1425 1009 1425 1048 1425 1060 1425 1160 1425 1199 1425 1251 1425 1304 1425 1408 1425 1410 1425 1425 1425 1445 1425 1446 1425 1449 1426 31 1426 123 1426 178 1426 219 1426 319 1426 350 1426 360 1426 402 1426 416 1426 418 1426 422 1426 457 1426 593 1426 617 1426 622 1426 644 1426 732 1426 736 1426 777 1426 886 1426 933 1426 935 1426 958 1426 962 1426 997 1426 1015 1426 1112 1426 1154 1426 1161 1426 1171 1426 1205 1426 1211 1426 1268 1426 1294 1426 1311 1426 1346 1426 1388 1426 1426 1426 1431 1426 1433 1426 1479 1427 166 1427 168 1427 173 1427 334 1427 426 1427 461 1427 467 1427 471 1427 472 1427 553 1427 696 1427 748 1427 924 1427 966 1427 1040 1427 1096 1427 1143 1427 1191 1427 1254 1427 1285 1427 1303 1427 1308 1427 1319 1427 1329 1427 1405 1427 1427 1427 1469 1428 99 1428 106 1428 249 1428 260 1428 329 1428 337 1428 393 1428 417 1428 421 1428 445 1428 487 1428 550 1428 585 1428 596 1428 602 1428 616 1428 653 1428 656 1428 672 1428 712 1428 717 1428 754 1428 806 1428 820 1428 855 1428 922 1428 968 1428 1000 1428 1042 1428 1070 1428 1077 1428 1175 1428 1190 1428 1241 1428 1315 1428 1317 1428 1408 1428 1428 1428 1438 1428 1445 1428 1470 1429 10 1429 23 1429 49 1429 184 1429 198 1429 290 1429 376 1429 457 1429 503 1429 517 1429 542 1429 574 1429 582 1429 601 1429 627 1429 643 1429 666 1429 725 1429 750 1429 770 1429 800 1429 898 1429 933 1429 1008 1429 1020 1429 1095 1429 1166 1429 1246 1429 1323 1429 1344 1429 1364 1429 1429 1429 1433 1429 1457 1429 1492 1430 142 1430 157 1430 316 1430 819 1430 877 1430 914 1430 1043 1430 1121 1430 1430 1431 7 1431 37 1431 91 1431 143 1431 148 1431 167 1431 219 1431 242 1431 326 1431 350 1431 360 1431 378 1431 416 1431 418 1431 443 1431 446 1431 508 1431 555 1431 574 1431 604 1431 613 1431 617 1431 621 1431 636 1431 639 1431 644 1431 669 1431 732 1431 777 1431 800 1431 886 1431 900 1431 903 1431 928 1431 933 1431 935 1431 958 1431 987 1431 1010 1431 1015 1431 1146 1431 1151 1431 1154 1431 1156 1431 1161 1431 1167 1431 1171 1431 1200 1431 1205 1431 1211 1431 1268 1431 1273 1431 1289 1431 1311 1431 1326 1431 1346 1431 1388 1431 1426 1431 1431 1431 1450 1431 1464 1431 1479 1432 59 1432 67 1432 161 1432 190 1432 335 1432 414 1432 435 1432 774 1432 840 1432 841 1432 857 1432 1021 1432 1231 1432 1320 1432 1365 1432 1409 1432 1432 1432 1443 1432 1454 1432 1477 1432 1491 1432 1497 1433 10 1433 20 1433 23 1433 31 1433 37 1433 49 1433 75 1433 123 1433 128 1433 170 1433 178 1433 198 1433 290 1433 357 1433 360 1433 376 1433 402 1433 422 1433 433 1433 443 1433 457 1433 503 1433 517 1433 551 1433 555 1433 559 1433 574 1433 582 1433 593 1433 622 1433 657 1433 673 1433 703 1433 725 1433 756 1433 770 1433 800 1433 805 1433 886 1433 916 1433 933 1433 955 1433 1020 1433 1100 1433 1101 1433 1106 1433 1112 1433 1166 1433 1203 1433 1211 1433 1257 1433 1268 1433 1311 1433 1346 1433 1426 1433 1429 1433 1433 1433 1457 1433 1462 1433 1490 1434 136 1434 159 1434 196 1434 252 1434 345 1434 383 1434 390 1434 400 1434 448 1434 543 1434 588 1434 605 1434 615 1434 641 1434 707 1434 739 1434 764 1434 783 1434 813 1434 847 1434 920 1434 947 1434 960 1434 1090 1434 1126 1434 1172 1434 1174 1434 1255 1434 1324 1434 1325 1434 1386 1434 1434 1434 1436 1434 1493 1435 84 1435 93 1435 120 1435 239 1435 271 1435 293 1435 311 1435 315 1435 361 1435 515 1435 564 1435 647 1435 677 1435 719 1435 858 1435 971 1435 975 1435 1023 1435 1058 1435 1157 1435 1248 1435 1307 1435 1377 1435 1394 1435 1395 1435 1424 1435 1435 1436 22 1436 156 1436 159 1436 196 1436 252 1436 345 1436 383 1436 390 1436 396 1436 400 1436 448 1436 449 1436 530 1436 543 1436 548 1436 588 1436 605 1436 615 1436 641 1436 707 1436 739 1436 763 1436 764 1436 847 1436 873 1436 920 1436 947 1436 948 1436 960 1436 964 1436 994 1436 1005 1436 1037 1436 1090 1436 1126 1436 1172 1436 1174 1436 1252 1436 1267 1436 1287 1436 1324 1436 1325 1436 1386 1436 1434 1436 1436 1436 1493 1437 10 1437 33 1437 50 1437 61 1437 110 1437 141 1437 169 1437 195 1437 299 1437 314 1437 341 1437 342 1437 364 1437 379 1437 447 1437 458 1437 493 1437 504 1437 514 1437 571 1437 578 1437 586 1437 687 1437 704 1437 749 1437 773 1437 811 1437 843 1437 904 1437 913 1437 915 1437 941 1437 943 1437 956 1437 1095 1437 1109 1437 1168 1437 1189 1437 1269 1437 1275 1437 1312 1437 1338 1437 1345 1437 1352 1437 1374 1437 1420 1437 1421 1437 1437 1437 1495 1438 100 1438 246 1438 260 1438 320 1438 393 1438 417 1438 445 1438 596 1438 616 1438 653 1438 672 1438 688 1438 712 1438 740 1438 751 1438 754 1438 759 1438 762 1438 806 1438 855 1438 856 1438 880 1438 922 1438 945 1438 974 1438 1042 1438 1077 1438 1094 1438 1139 1438 1195 1438 1306 1438 1315 1438 1317 1438 1337 1438 1387 1438 1397 1438 1428 1438 1438 1438 1453 1438 1470 1438 1473 1439 39 1439 43 1439 46 1439 60 1439 77 1439 104 1439 109 1439 112 1439 154 1439 208 1439 280 1439 369 1439 385 1439 410 1439 500 1439 541 1439 557 1439 633 1439 724 1439 747 1439 779 1439 861 1439 878 1439 891 1439 902 1439 927 1439 957 1439 976 1439 1013 1439 1025 1439 1128 1439 1134 1439 1148 1439 1207 1439 1210 1439 1279 1439 1301 1439 1310 1439 1380 1439 1439 1440 98 1440 185 1440 186 1440 288 1440 359 1440 367 1440 398 1440 419 1440 437 1440 480 1440 529 1440 546 1440 587 1440 597 1440 598 1440 645 1440 650 1440 661 1440 663 1440 665 1440 676 1440 682 1440 683 1440 721 1440 760 1440 842 1440 996 1440 1019 1440 1060 1440 1079 1440 1197 1440 1218 1440 1412 1440 1417 1440 1440 1440 1465 1441 14 1441 72 1441 79 1441 135 1441 189 1441 223 1441 232 1441 279 1441 295 1441 343 1441 371 1441 373 1441 387 1441 389 1441 391 1441 408 1441 478 1441 483 1441 526 1441 556 1441 592 1441 600 1441 611 1441 638 1441 640 1441 648 1441 680 1441 684 1441 690 1441 694 1441 784 1441 807 1441 814 1441 822 1441 839 1441 844 1441 906 1441 910 1441 911 1441 940 1441 972 1441 978 1441 1014 1441 1068 1441 1078 1441 1082 1441 1097 1441 1099 1441 1142 1441 1180 1441 1196 1441 1198 1441 1206 1441 1217 1441 1229 1441 1230 1441 1277 1441 1281 1441 1299 1441 1370 1441 1373 1441 1407 1441 1441 1441 1474 1441 1484 1442 19 1442 205 1442 222 1442 259 1442 285 1442 288 1442 312 1442 436 1442 465 1442 587 1442 655 1442 685 1442 734 1442 778 1442 802 1442 871 1442 892 1442 934 1442 1066 1442 1102 1442 1113 1442 1118 1442 1124 1442 1153 1442 1212 1442 1214 1442 1221 1442 1242 1442 1327 1442 1330 1442 1340 1442 1343 1442 1382 1442 1419 1442 1442 1442 1452 1442 1463 1442 1486 1443 59 1443 67 1443 161 1443 190 1443 335 1443 414 1443 435 1443 774 1443 840 1443 857 1443 1021 1443 1231 1443 1320 1443 1365 1443 1409 1443 1432 1443 1443 1443 1477 1443 1491 1443 1497 1444 7 1444 22 1444 107 1444 148 1444 156 1444 266 1444 378 1444 396 1444 446 1444 449 1444 507 1444 530 1444 543 1444 558 1444 570 1444 604 1444 607 1444 613 1444 621 1444 669 1444 739 1444 763 1444 791 1444 854 1444 862 1444 873 1444 900 1444 903 1444 920 1444 935 1444 937 1444 948 1444 994 1444 1005 1444 1071 1444 1090 1444 1146 1444 1156 1444 1162 1444 1176 1444 1184 1444 1224 1444 1289 1444 1294 1444 1324 1444 1326 1444 1386 1444 1444 1444 1450 1444 1464 1445 41 1445 81 1445 94 1445 99 1445 134 1445 245 1445 318 1445 329 1445 337 1445 393 1445 417 1445 445 1445 459 1445 487 1445 496 1445 501 1445 505 1445 510 1445 513 1445 535 1445 585 1445 596 1445 686 1445 713 1445 717 1445 754 1445 762 1445 790 1445 820 1445 834 1445 890 1445 912 1445 918 1445 922 1445 929 1445 946 1445 950 1445 965 1445 968 1445 988 1445 1000 1445 1042 1445 1045 1445 1048 1445 1070 1445 1077 1445 1139 1445 1190 1445 1226 1445 1241 1445 1251 1445 1286 1445 1304 1445 1315 1445 1408 1445 1425 1445 1428 1445 1445 1445 1470 1445 1471 1446 27 1446 28 1446 89 1446 162 1446 268 1446 289 1446 328 1446 444 1446 470 1446 479 1446 505 1446 552 1446 634 1446 652 1446 678 1446 681 1446 711 1446 775 1446 776 1446 786 1446 789 1446 795 1446 830 1446 865 1446 887 1446 890 1446 896 1446 909 1446 921 1446 965 1446 968 1446 991 1446 995 1446 1092 1446 1120 1446 1140 1446 1160 1446 1213 1446 1316 1446 1410 1446 1414 1446 1425 1446 1446 1447 2 1447 25 1447 117 1447 181 1447 220 1447 247 1447 273 1447 353 1447 362 1447 372 1447 384 1447 450 1447 454 1447 463 1447 523 1447 692 1447 794 1447 894 1447 970 1447 982 1447 1055 1447 1056 1447 1083 1447 1105 1447 1186 1447 1253 1447 1256 1447 1282 1447 1298 1447 1307 1447 1377 1447 1385 1447 1447 1447 1488 1448 9 1448 15 1448 54 1448 73 1448 158 1448 182 1448 205 1448 221 1448 229 1448 262 1448 285 1448 351 1448 381 1448 462 1448 473 1448 485 1448 490 1448 599 1448 618 1448 698 1448 735 1448 808 1448 823 1448 827 1448 837 1448 864 1448 1044 1448 1144 1448 1153 1448 1183 1448 1221 1448 1258 1448 1360 1448 1389 1448 1448 1448 1452 1448 1455 1449 89 1449 127 1449 251 1449 267 1449 318 1449 329 1449 347 1449 392 1449 470 1449 482 1449 494 1449 501 1449 502 1449 510 1449 513 1449 535 1449 674 1449 678 1449 689 1449 708 1449 817 1449 831 1449 834 1449 896 1449 921 1449 925 1449 965 1449 979 1449 986 1449 1007 1449 1009 1449 1160 1449 1215 1449 1304 1449 1318 1449 1321 1449 1341 1449 1392 1449 1408 1449 1425 1449 1449 1449 1471 1450 7 1450 87 1450 148 1450 156 1450 204 1450 242 1450 292 1450 396 1450 446 1450 508 1450 558 1450 583 1450 604 1450 613 1450 621 1450 639 1450 669 1450 691 1450 727 1450 841 1450 903 1450 919 1450 937 1450 948 1450 987 1450 994 1450 1038 1450 1071 1450 1151 1450 1156 1450 1161 1450 1184 1450 1273 1450 1326 1450 1431 1450 1444 1450 1450 1450 1458 1450 1464 1451 4 1451 71 1451 155 1451 169 1451 248 1451 331 1451 469 1451 519 1451 632 1451 716 1451 738 1451 977 1451 1053 1451 1073 1451 1357 1451 1367 1451 1416 1451 1423 1451 1451 1451 1480 1452 9 1452 15 1452 54 1452 73 1452 121 1452 158 1452 182 1452 205 1452 221 1452 229 1452 285 1452 351 1452 381 1452 462 1452 485 1452 490 1452 536 1452 618 1452 619 1452 685 1452 698 1452 701 1452 735 1452 823 1452 827 1452 837 1452 849 1452 864 1452 905 1452 1044 1452 1144 1452 1153 1452 1183 1452 1221 1452 1258 1452 1343 1452 1389 1452 1442 1452 1448 1452 1452 1452 1455 1452 1463 1453 100 1453 134 1453 140 1453 246 1453 260 1453 265 1453 310 1453 320 1453 337 1453 393 1453 406 1453 413 1453 417 1453 421 1453 521 1453 596 1453 616 1453 672 1453 688 1453 740 1453 754 1453 762 1453 772 1453 781 1453 806 1453 855 1453 856 1453 907 1453 918 1453 932 1453 945 1453 963 1453 974 1453 998 1453 1004 1453 1042 1453 1049 1453 1074 1453 1094 1453 1139 1453 1158 1453 1177 1453 1181 1453 1387 1453 1397 1453 1438 1453 1453 1453 1470 1453 1473 1454 59 1454 67 1454 190 1454 335 1454 414 1454 435 1454 691 1454 727 1454 774 1454 840 1454 841 1454 919 1454 953 1454 987 1454 1021 1454 1038 1454 1151 1454 1231 1454 1273 1454 1320 1454 1379 1454 1432 1454 1454 1454 1477 1454 1491 1454 1497 1455 9 1455 19 1455 54 1455 73 1455 121 1455 130 1455 152 1455 158 1455 182 1455 205 1455 259 1455 285 1455 330 1455 473 1455 485 1455 599 1455 618 1455 655 1455 698 1455 701 1455 752 1455 761 1455 778 1455 802 1455 815 1455 823 1455 837 1455 849 1455 892 1455 905 1455 983 1455 1044 1455 1144 1455 1258 1455 1343 1455 1382 1455 1448 1455 1452 1455 1455 1456 44 1456 57 1456 147 1456 149 1456 232 1456 253 1456 344 1456 375 1456 388 1456 397 1456 478 1456 491 1456 556 1456 694 1456 733 1456 743 1456 799 1456 807 1456 860 1456 888 1456 893 1456 990 1456 993 1456 1027 1456 1069 1456 1082 1456 1136 1456 1202 1456 1235 1456 1278 1456 1355 1456 1358 1456 1456 1457 10 1457 23 1457 49 1457 103 1457 184 1457 198 1457 210 1457 357 1457 376 1457 402 1457 457 1457 503 1457 517 1457 542 1457 551 1457 555 1457 559 1457 582 1457 601 1457 622 1457 627 1457 657 1457 666 1457 704 1457 725 1457 750 1457 756 1457 766 1457 770 1457 800 1457 811 1457 898 1457 915 1457 916 1457 933 1457 1008 1457 1020 1457 1087 1457 1088 1457 1095 1457 1166 1457 1185 1457 1297 1457 1429 1457 1433 1457 1457 1457 1492 1457 1495 1458 7 1458 20 1458 37 1458 87 1458 203 1458 204 1458 242 1458 292 1458 294 1458 300 1458 336 1458 403 1458 446 1458 583 1458 903 1458 928 1458 948 1458 953 1458 987 1458 1029 1458 1038 1458 1106 1458 1169 1458 1188 1458 1211 1458 1224 1458 1268 1458 1273 1458 1326 1458 1379 1458 1404 1458 1450 1458 1458 1458 1460 1459 30 1459 53 1459 58 1459 78 1459 82 1459 90 1459 102 1459 130 1459 191 1459 193 1459 206 1459 211 1459 212 1459 270 1459 286 1459 308 1459 323 1459 332 1459 348 1459 428 1459 451 1459 460 1459 464 1459 511 1459 533 1459 537 1459 549 1459 563 1459 579 1459 610 1459 626 1459 631 1459 658 1459 685 1459 702 1459 752 1459 761 1459 769 1459 785 1459 812 1459 829 1459 863 1459 884 1459 901 1459 923 1459 1003 1459 1024 1459 1046 1459 1057 1459 1065 1459 1084 1459 1124 1459 1135 1459 1137 1459 1183 1459 1234 1459 1238 1459 1249 1459 1334 1459 1336 1459 1390 1459 1418 1459 1459 1459 1481 1460 37 1460 49 1460 50 1460 68 1460 75 1460 87 1460 141 1460 203 1460 204 1460 210 1460 290 1460 294 1460 299 1460 300 1460 314 1460 357 1460 368 1460 433 1460 443 1460 538 1460 551 1460 559 1460 571 1460 627 1460 657 1460 671 1460 673 1460 697 1460 704 1460 756 1460 805 1460 836 1460 916 1460 930 1460 1029 1460 1088 1460 1100 1460 1169 1460 1189 1460 1203 1460 1300 1460 1338 1460 1364 1460 1374 1460 1379 1460 1458 1460 1460 1460 1462 1460 1490 1461 5 1461 12 1461 13 1461 52 1461 63 1461 65 1461 92 1461 165 1461 202 1461 230 1461 234 1461 240 1461 272 1461 365 1461 434 1461 441 1461 528 1461 569 1461 609 1461 612 1461 630 1461 642 1461 730 1461 742 1461 809 1461 882 1461 939 1461 999 1461 1018 1461 1026 1461 1028 1461 1076 1461 1129 1461 1159 1461 1265 1461 1331 1461 1369 1461 1461 1461 1472 1461 1476 1462 20 1462 31 1462 123 1462 170 1462 300 1462 333 1462 357 1462 402 1462 433 1462 538 1462 559 1462 703 1462 736 1462 916 1462 1029 1462 1100 1462 1112 1462 1188 1462 1346 1462 1402 1462 1404 1462 1433 1462 1460 1462 1462 1462 1490 1463 15 1463 19 1463 54 1463 158 1463 182 1463 205 1463 259 1463 285 1463 312 1463 381 1463 462 1463 473 1463 599 1463 709 1463 735 1463 802 1463 816 1463 823 1463 837 1463 849 1463 871 1463 1066 1463 1102 1463 1144 1463 1153 1463 1221 1463 1340 1463 1343 1463 1382 1463 1389 1463 1419 1463 1442 1463 1452 1463 1463 1463 1486 1464 7 1464 20 1464 31 1464 87 1464 123 1464 128 1464 148 1464 156 1464 167 1464 204 1464 219 1464 242 1464 266 1464 292 1464 336 1464 378 1464 449 1464 530 1464 548 1464 558 1464 607 1464 613 1464 621 1464 671 1464 763 1464 791 1464 862 1464 873 1464 900 1464 903 1464 935 1464 948 1464 1106 1464 1156 1464 1161 1464 1162 1464 1171 1464 1176 1464 1184 1464 1211 1464 1224 1464 1289 1464 1294 1464 1326 1464 1431 1464 1444 1464 1450 1464 1464 1465 11 1465 81 1465 106 1465 151 1465 185 1465 225 1465 251 1465 318 1465 339 1465 347 1465 358 1465 419 1465 430 1465 470 1465 480 1465 510 1465 529 1465 546 1465 550 1465 585 1465 663 1465 665 1465 674 1465 683 1465 760 1465 768 1465 787 1465 821 1465 828 1465 842 1465 912 1465 949 1465 986 1465 996 1465 1009 1465 1011 1465 1019 1465 1022 1465 1033 1465 1060 1465 1063 1465 1070 1465 1079 1465 1197 1465 1215 1465 1304 1465 1318 1465 1408 1465 1440 1465 1465 1465 1471 1466 69 1466 70 1466 108 1466 146 1466 273 1466 363 1466 438 1466 466 1466 512 1466 523 1466 635 1466 700 1466 722 1466 731 1466 780 1466 794 1466 872 1466 998 1466 1004 1466 1012 1466 1155 1466 1177 1466 1193 1466 1228 1466 1260 1466 1263 1466 1298 1466 1399 1466 1466 1467 26 1467 82 1467 200 1467 233 1467 244 1467 267 1467 332 1467 355 1467 359 1467 399 1467 623 1467 625 1467 658 1467 681 1467 795 1467 865 1467 959 1467 1009 1467 1079 1467 1113 1467 1199 1467 1314 1467 1316 1467 1321 1467 1378 1467 1467 1467 1485 1467 1494 1468 24 1468 51 1468 129 1468 283 1468 304 1468 327 1468 358 1468 429 1468 522 1468 575 1468 594 1468 625 1468 629 1468 689 1468 695 1468 708 1468 729 1468 731 1468 745 1468 767 1468 810 1468 824 1468 885 1468 896 1468 921 1468 1007 1468 1031 1468 1039 1468 1085 1468 1086 1468 1178 1468 1204 1468 1244 1468 1261 1468 1271 1468 1316 1468 1339 1468 1371 1468 1400 1468 1468 1469 84 1469 88 1469 166 1469 168 1469 173 1469 334 1469 409 1469 420 1469 426 1469 461 1469 471 1469 472 1469 477 1469 488 1469 489 1469 553 1469 572 1469 675 1469 710 1469 723 1469 748 1469 788 1469 818 1469 899 1469 917 1469 924 1469 1040 1469 1062 1469 1080 1469 1093 1469 1096 1469 1104 1469 1115 1469 1143 1469 1191 1469 1192 1469 1233 1469 1254 1469 1285 1469 1293 1469 1303 1469 1405 1469 1427 1469 1469 1470 100 1470 134 1470 140 1470 260 1470 289 1470 320 1470 329 1470 337 1470 393 1470 417 1470 421 1470 445 1470 459 1470 487 1470 596 1470 616 1470 679 1470 717 1470 754 1470 759 1470 762 1470 806 1470 918 1470 922 1470 1042 1470 1045 1470 1048 1470 1077 1470 1139 1470 1226 1470 1241 1470 1315 1470 1387 1470 1428 1470 1438 1470 1445 1470 1453 1470 1470 1471 41 1471 81 1471 151 1471 251 1471 267 1471 318 1471 329 1471 337 1471 347 1471 380 1471 470 1471 505 1471 510 1471 535 1471 585 1471 665 1471 674 1471 676 1471 686 1471 760 1471 787 1471 834 1471 925 1471 929 1471 950 1471 965 1471 979 1471 986 1471 988 1471 1000 1471 1009 1471 1019 1471 1060 1471 1070 1471 1111 1471 1190 1471 1215 1471 1241 1471 1251 1471 1286 1471 1304 1471 1392 1471 1408 1471 1445 1471 1449 1471 1465 1471 1471 1472 5 1472 47 1472 52 1472 63 1472 65 1472 92 1472 160 1472 202 1472 230 1472 240 1472 272 1472 291 1472 365 1472 387 1472 441 1472 569 1472 603 1472 609 1472 612 1472 624 1472 630 1472 642 1472 694 1472 730 1472 742 1472 809 1472 882 1472 999 1472 1018 1472 1028 1472 1075 1472 1076 1472 1108 1472 1196 1472 1265 1472 1277 1472 1331 1472 1369 1472 1461 1472 1472 1472 1476 1472 1484 1473 1 1473 18 1473 100 1473 246 1473 265 1473 320 1473 421 1473 616 1473 672 1473 688 1473 712 1473 740 1473 806 1473 850 1473 855 1473 856 1473 876 1473 907 1473 945 1473 974 1473 998 1473 1004 1473 1074 1473 1094 1473 1139 1473 1177 1473 1195 1473 1306 1473 1387 1473 1397 1473 1438 1473 1453 1473 1473 1474 83 1474 135 1474 217 1474 223 1474 224 1474 343 1474 371 1474 377 1474 387 1474 389 1474 391 1474 408 1474 441 1474 478 1474 483 1474 497 1474 524 1474 547 1474 556 1474 592 1474 600 1474 638 1474 640 1474 680 1474 784 1474 807 1474 814 1474 844 1474 906 1474 908 1474 910 1474 911 1474 972 1474 1014 1474 1034 1474 1068 1474 1078 1474 1099 1474 1142 1474 1180 1474 1198 1474 1206 1474 1217 1474 1230 1474 1277 1474 1299 1474 1361 1474 1370 1474 1373 1474 1407 1474 1441 1474 1474 1474 1496 1475 53 1475 86 1475 102 1475 206 1475 211 1475 277 1475 308 1475 332 1475 348 1475 349 1475 405 1475 451 1475 534 1475 563 1475 579 1475 626 1475 658 1475 685 1475 702 1475 752 1475 846 1475 863 1475 901 1475 1024 1475 1066 1475 1084 1475 1131 1475 1135 1475 1137 1475 1309 1475 1475 1475 1494 1476 14 1476 36 1476 63 1476 92 1476 125 1476 160 1476 202 1476 230 1476 240 1476 272 1476 365 1476 373 1476 387 1476 441 1476 569 1476 600 1476 606 1476 624 1476 630 1476 640 1476 694 1476 809 1476 882 1476 888 1476 910 1476 999 1476 1018 1476 1075 1476 1076 1476 1108 1476 1196 1476 1277 1476 1331 1476 1369 1476 1461 1476 1472 1476 1476 1476 1484 1477 59 1477 67 1477 161 1477 190 1477 335 1477 414 1477 435 1477 774 1477 840 1477 841 1477 857 1477 919 1477 1021 1477 1231 1477 1320 1477 1365 1477 1409 1477 1432 1477 1443 1477 1454 1477 1477 1477 1491 1477 1497 1478 2 1478 3 1478 93 1478 95 1478 111 1478 126 1478 153 1478 194 1478 227 1478 231 1478 247 1478 282 1478 296 1478 362 1478 384 1478 386 1478 454 1478 463 1478 466 1478 481 1478 515 1478 516 1478 564 1478 654 1478 670 1478 796 1478 801 1478 838 1478 970 1478 975 1478 1001 1478 1002 1478 1012 1478 1036 1478 1105 1478 1116 1478 1119 1478 1122 1478 1194 1478 1248 1478 1256 1478 1280 1478 1298 1478 1302 1478 1354 1478 1394 1478 1396 1478 1478 1479 91 1479 122 1479 219 1479 319 1479 326 1479 350 1479 360 1479 416 1479 418 1479 422 1479 457 1479 508 1479 555 1479 589 1479 593 1479 617 1479 622 1479 639 1479 644 1479 732 1479 770 1479 777 1479 800 1479 886 1479 933 1479 997 1479 1010 1479 1015 1479 1071 1479 1087 1479 1146 1479 1154 1479 1161 1479 1167 1479 1185 1479 1200 1479 1205 1479 1257 1479 1268 1479 1311 1479 1346 1479 1388 1479 1426 1479 1431 1479 1479 1480 4 1480 16 1480 71 1480 248 1480 274 1480 297 1480 331 1480 432 1480 469 1480 519 1480 548 1480 632 1480 706 1480 738 1480 964 1480 977 1480 1053 1480 1073 1480 1130 1480 1255 1480 1274 1480 1328 1480 1357 1480 1367 1480 1416 1480 1422 1480 1423 1480 1451 1480 1480 1481 30 1481 53 1481 78 1481 82 1481 90 1481 102 1481 130 1481 152 1481 193 1481 200 1481 211 1481 212 1481 270 1481 286 1481 308 1481 348 1481 349 1481 399 1481 405 1481 428 1481 431 1481 451 1481 464 1481 511 1481 537 1481 549 1481 560 1481 579 1481 580 1481 610 1481 626 1481 631 1481 652 1481 658 1481 702 1481 752 1481 761 1481 778 1481 812 1481 815 1481 829 1481 863 1481 901 1481 923 1481 959 1481 1003 1481 1024 1481 1035 1481 1046 1481 1057 1481 1059 1481 1084 1481 1124 1481 1131 1481 1135 1481 1212 1481 1238 1481 1249 1481 1316 1481 1336 1481 1340 1481 1390 1481 1418 1481 1459 1481 1481 1482 32 1482 40 1482 115 1482 139 1482 171 1482 177 1482 237 1482 307 1482 366 1482 453 1482 833 1482 835 1482 848 1482 859 1482 869 1482 926 1482 1041 1482 1061 1482 1103 1482 1237 1482 1245 1482 1247 1482 1262 1482 1276 1482 1296 1482 1347 1482 1381 1482 1406 1482 1482 1483 37 1483 49 1483 184 1483 198 1483 290 1483 368 1483 376 1483 443 1483 503 1483 555 1483 559 1483 573 1483 574 1483 582 1483 589 1483 627 1483 639 1483 657 1483 725 1483 756 1483 770 1483 805 1483 836 1483 1020 1483 1087 1483 1101 1483 1107 1483 1166 1483 1185 1483 1200 1483 1203 1483 1246 1483 1273 1483 1364 1483 1483 1483 1492 1484 14 1484 47 1484 79 1484 92 1484 125 1484 160 1484 189 1484 223 1484 230 1484 240 1484 272 1484 279 1484 295 1484 373 1484 387 1484 434 1484 441 1484 483 1484 484 1484 491 1484 520 1484 556 1484 569 1484 600 1484 606 1484 611 1484 612 1484 624 1484 630 1484 640 1484 690 1484 694 1484 743 1484 784 1484 809 1484 844 1484 882 1484 888 1484 910 1484 911 1484 999 1484 1014 1484 1018 1484 1069 1484 1075 1484 1076 1484 1082 1484 1097 1484 1099 1484 1196 1484 1206 1484 1217 1484 1230 1484 1277 1484 1331 1484 1355 1484 1370 1484 1441 1484 1472 1484 1476 1484 1484 1485 26 1485 233 1485 244 1485 267 1485 332 1485 355 1485 482 1485 629 1485 708 1485 755 1485 895 1485 931 1485 934 1485 986 1485 1054 1485 1079 1485 1314 1485 1321 1485 1327 1485 1378 1485 1467 1485 1485 1485 1494 1486 54 1486 90 1486 121 1486 191 1486 205 1486 222 1486 259 1486 312 1486 323 1486 465 1486 506 1486 536 1486 579 1486 658 1486 701 1486 702 1486 734 1486 778 1486 802 1486 808 1486 815 1486 897 1486 934 1486 959 1486 1024 1486 1035 1486 1054 1486 1066 1486 1102 1486 1113 1486 1118 1486 1124 1486 1135 1486 1212 1486 1214 1486 1221 1486 1327 1486 1330 1486 1334 1486 1340 1486 1382 1486 1400 1486 1413 1486 1442 1486 1463 1486 1486 1487 45 1487 51 1487 70 1487 151 1487 185 1487 186 1487 199 1487 245 1487 278 1487 281 1487 358 1487 359 1487 367 1487 380 1487 419 1487 437 1487 545 1487 594 1487 597 1487 635 1487 645 1487 661 1487 665 1487 676 1487 682 1487 683 1487 686 1487 699 1487 729 1487 731 1487 768 1487 872 1487 949 1487 1060 1487 1086 1487 1152 1487 1190 1487 1208 1487 1239 1487 1399 1487 1417 1487 1487 1488 25 1488 70 1488 98 1488 108 1488 151 1488 186 1488 220 1488 238 1488 256 1488 273 1488 281 1488 298 1488 303 1488 358 1488 438 1488 512 1488 635 1488 692 1488 722 1488 729 1488 731 1488 780 1488 782 1488 794 1488 803 1488 810 1488 824 1488 828 1488 894 1488 996 1488 1011 1488 1031 1488 1032 1488 1033 1488 1052 1488 1055 1488 1085 1488 1208 1488 1228 1488 1263 1488 1305 1488 1363 1488 1371 1488 1385 1488 1399 1488 1447 1488 1488 1489 43 1489 46 1489 60 1489 118 1489 176 1489 208 1489 287 1489 369 1489 385 1489 456 1489 500 1489 532 1489 541 1489 557 1489 565 1489 651 1489 724 1489 747 1489 779 1489 861 1489 878 1489 902 1489 927 1489 957 1489 1013 1489 1030 1489 1150 1489 1182 1489 1210 1489 1220 1489 1243 1489 1264 1489 1270 1489 1279 1489 1295 1489 1366 1489 1380 1489 1489 1490 7 1490 20 1490 31 1490 37 1490 68 1490 75 1490 87 1490 123 1490 148 1490 167 1490 170 1490 203 1490 204 1490 242 1490 292 1490 294 1490 300 1490 333 1490 336 1490 350 1490 357 1490 368 1490 402 1490 433 1490 538 1490 551 1490 559 1490 593 1490 622 1490 657 1490 671 1490 673 1490 703 1490 756 1490 886 1490 916 1490 928 1490 930 1490 1029 1490 1071 1490 1088 1490 1100 1490 1106 1490 1112 1490 1161 1490 1166 1490 1169 1490 1171 1490 1188 1490 1203 1490 1211 1490 1224 1490 1257 1490 1300 1490 1326 1490 1402 1490 1404 1490 1433 1490 1460 1490 1462 1490 1490 1491 59 1491 67 1491 161 1491 190 1491 335 1491 414 1491 435 1491 691 1491 774 1491 840 1491 841 1491 857 1491 919 1491 953 1491 1021 1491 1231 1491 1320 1491 1365 1491 1409 1491 1432 1491 1443 1491 1454 1491 1477 1491 1491 1491 1497 1492 10 1492 23 1492 49 1492 184 1492 198 1492 210 1492 319 1492 357 1492 376 1492 457 1492 503 1492 542 1492 551 1492 555 1492 559 1492 573 1492 589 1492 593 1492 601 1492 622 1492 627 1492 657 1492 666 1492 725 1492 750 1492 756 1492 766 1492 770 1492 886 1492 898 1492 933 1492 1008 1492 1020 1492 1087 1492 1088 1492 1107 1492 1112 1492 1166 1492 1185 1492 1429 1492 1457 1492 1483 1492 1492 1493 22 1493 156 1493 159 1493 196 1493 252 1493 274 1493 345 1493 390 1493 403 1493 448 1493 530 1493 543 1493 548 1493 615 1493 641 1493 707 1493 763 1493 764 1493 847 1493 920 1493 947 1493 948 1493 960 1493 964 1493 994 1493 1005 1493 1037 1493 1126 1493 1174 1493 1252 1493 1267 1493 1287 1493 1324 1493 1325 1493 1386 1493 1422 1493 1434 1493 1436 1493 1493 1494 53 1494 78 1494 82 1494 86 1494 200 1494 206 1494 211 1494 233 1494 244 1494 277 1494 332 1494 348 1494 355 1494 405 1494 444 1494 451 1494 552 1494 579 1494 580 1494 625 1494 626 1494 629 1494 652 1494 658 1494 708 1494 755 1494 846 1494 863 1494 901 1494 931 1494 995 1494 1007 1494 1024 1494 1059 1494 1064 1494 1135 1494 1137 1494 1309 1494 1314 1494 1316 1494 1327 1494 1378 1494 1467 1494 1475 1494 1485 1494 1494 1495 10 1495 50 1495 141 1495 195 1495 210 1495 314 1495 341 1495 342 1495 364 1495 379 1495 433 1495 503 1495 504 1495 542 1495 551 1495 571 1495 627 1495 643 1495 666 1495 693 1495 704 1495 811 1495 898 1495 913 1495 915 1495 930 1495 1008 1495 1088 1495 1095 1495 1107 1495 1109 1495 1168 1495 1189 1495 1240 1495 1246 1495 1275 1495 1300 1495 1323 1495 1338 1495 1352 1495 1374 1495 1420 1495 1437 1495 1457 1495 1495 1496 55 1496 56 1496 83 1496 164 1496 187 1496 217 1496 218 1496 223 1496 224 1496 291 1496 343 1496 371 1496 377 1496 389 1496 492 1496 497 1496 524 1496 544 1496 547 1496 562 1496 584 1496 592 1496 620 1496 638 1496 844 1496 870 1496 906 1496 908 1496 972 1496 1034 1496 1078 1496 1091 1496 1098 1496 1099 1496 1180 1496 1198 1496 1225 1496 1299 1496 1361 1496 1373 1496 1474 1496 1496 1497 59 1497 67 1497 161 1497 190 1497 335 1497 414 1497 435 1497 751 1497 774 1497 840 1497 857 1497 1021 1497 1231 1497 1320 1497 1365 1497 1409 1497 1411 1497 1432 1497 1443 1497 1454 1497 1477 1497 1491 1497 1497 1498 47 1498 135 1498 144 1498 217 1498 223 1498 253 1498 279 1498 295 1498 305 1498 401 1498 408 1498 452 1498 455 1498 478 1498 526 1498 567 1498 591 1498 608 1498 680 1498 684 1498 784 1498 814 1498 822 1498 839 1498 875 1498 940 1498 978 1498 1014 1498 1018 1498 1034 1498 1097 1498 1142 1498 1206 1498 1216 1498 1229 1498 1250 1498 1281 1498 1290 1498 1299 1498 1313 1498 1348 1498 1356 1498 1370 1498 1375 1498 1407 1498 1498 1499 42 1499 133 1499 180 1499 238 1499 268 1499 283 1499 286 1499 303 1499 328 1499 340 1499 395 1499 429 1499 438 1499 575 1499 652 1499 681 1499 722 1499 769 1499 776 1499 803 1499 969 1499 1059 1499 1155 1499 1271 1499 1305 1499 1333 1499 1403 1499 1499 leidenbase/tests/cpp_tests/node_sizes.txt0000644000176200001440000006137714444624071020442 0ustar liggesusers1.04319524322636 9.18539066496305 7.3950812832918 8.08751137298532 2.48324930784293 9.78038286953233 9.81939685484394 9.22817424987443 1.66596373799257 3.09403179213405 3.89495791331865 5.70282639935613 2.57659792434424 2.51919495710172 1.30058186850511 3.65293961646967 4.78708565793931 8.45830704667605 4.90736872400157 9.83921470819041 1.11792826047167 5.56951951328665 7.24362500361167 1.45771213294938 1.95803053374402 3.52722900616936 4.50263416697271 3.25591327133588 3.94382058246993 6.7857012799941 3.16205308842473 2.11359785613604 2.87432080740109 4.20657243463211 5.76445892103948 8.58561934437603 7.8135299666319 1.52064163261093 5.47755729919299 8.27887950954027 4.77901371545158 1.41421487508342 3.97755770501681 7.36709783645347 5.25119247683324 4.13254857249558 5.1177376920823 4.67248424189165 9.74024390708655 9.48471829062328 8.95618241187185 2.71248598606326 7.86928405216895 3.21311569283716 9.24194761109538 8.19254885101691 5.3591792259831 1.10773300169967 6.81760554853827 2.62174283806235 3.63405648362823 6.94919357029721 6.56253806594759 8.74935692269355 8.2654846184887 1.75599072151817 1.28300224104896 1.70159647194669 6.32394332392141 9.06440299516544 5.84905392839573 2.05242780805565 4.91846309485845 6.34418963291682 8.96307333372533 3.23258469346911 2.82170670852065 8.23672658530995 7.12730720639229 9.19257991341874 9.13243666943163 4.80285889515653 3.91508182138205 9.92945382301696 2.09488765662536 7.51317953085527 7.39139341353439 8.37861218792386 5.37753299134783 1.21890068729408 6.21120168245398 4.00326300296001 7.71030903351493 3.10418102378026 5.87094099493697 7.82431028434075 9.11444759648293 1.15156865376048 7.67954969941638 3.44667728012428 7.20721249491908 8.02590694953687 1.39643483003601 7.95322153274901 7.78815653547645 1.95670486870222 6.28501179767773 2.04052948276512 5.68008609488606 1.50687454943545 1.91162856505252 4.44971037353389 1.69331526686437 8.86744253872894 1.73828494222835 3.97745305276476 4.9855928143952 2.85854735225439 4.27781745698303 9.16327456082217 6.17695191013627 5.09904220071621 6.92414326989092 2.73707004520111 4.68351322552189 8.6118817999959 9.82132927118801 1.18540996755473 6.93910248810425 2.94983339193277 5.88654003525153 9.11830258043483 7.62917621736415 3.71353477914818 8.05292311217636 8.23208756023087 6.40133681171574 7.96230540354736 7.23818157776259 5.85532944463193 1.07346196658909 9.79147175652906 2.65849841595627 6.23527676519006 5.24239507433958 2.36155190668069 6.65742700803094 5.30400540283881 4.79274397902191 6.12746591446921 1.01704594120383 8.94052138109691 1.60399947105907 5.79780545947142 5.08948573097587 5.16298583731987 4.39993900759146 4.11191051220521 4.08532951492816 8.55309791839682 4.72580458945595 5.02368502086028 5.79855336202309 3.30912413448095 4.86952177830972 4.0730984301772 6.16023967135698 6.10610630433075 4.94146033399738 7.00829499401152 7.44768404774368 5.12115932744928 8.28995434637181 9.39317217096686 6.14585106167942 9.10170748713426 6.27613697573543 6.26548047969118 6.50884305988438 3.44900240539573 3.15270481049083 8.3813463835977 7.82847114698961 6.53809512662701 4.15600305912085 9.45278007118031 5.54578123637475 5.91817277413793 2.53989393915981 3.4323073788546 5.93104140320793 2.52675584866665 2.43797892751172 3.12577467551455 5.72768297721632 6.7365847104229 6.41593060619198 2.80483357282355 6.8580763253849 5.77476617880166 5.66640373179689 9.67941283574328 8.84107485041022 1.6489734693896 7.8665390543174 5.58147123968229 3.05608131526969 1.89311309391633 6.61374499835074 2.0639214864932 2.54070426593535 8.03178960178047 5.92443005554378 2.78939159889705 6.7505933160428 2.22719071968459 8.84204083750956 6.25280735013075 7.15778283611871 6.93014697358012 2.16087902151048 8.93168873270042 5.70703073474579 2.90940300538205 5.16385152656585 9.51286332588643 4.88375400472432 9.21096651279368 5.45117664826103 3.1644957489334 8.86087091080844 3.63116353470832 5.2784365999978 2.73525486025028 4.90267851063982 4.38977003027685 6.67435301886871 6.69301352836192 3.27053962741047 9.08220036141574 4.31998088792898 1.0440551196225 8.9442712245509 3.83979444392025 2.87292609433644 8.60445919306949 6.28549345955253 6.70272026676685 7.41652244096622 7.3792146507185 8.11439775233157 2.99636812997051 4.74168794602156 8.87275453424081 3.10654574306682 4.55631559435278 7.38480160199106 4.59137743897736 9.01217390643433 7.81772071914747 9.31750229583122 7.43374603241682 8.28455323236994 9.71069149998948 2.82415793533437 2.30601590569131 6.48669196129777 2.77351389173418 9.64894220372662 3.37164647481404 4.75200951378793 5.41121035302058 2.52521758712828 5.61964437970892 1.51681688427925 5.44564749440178 4.02855101204477 3.93562281923369 1.3046365135815 1.30982255632989 4.21693814359605 4.58776643336751 6.97439038008451 6.40472392830998 6.38899086555466 2.49744288111106 9.56144806160592 2.61719299433753 7.61007538973354 7.93555544596165 9.52408446674235 2.91407817322761 6.07249113637954 6.56729499087669 3.93016203027219 1.80477406643331 4.39339434006251 6.62474501202814 1.3633677798789 4.91488951654173 5.14032756444067 2.77126729441807 8.04445570521057 5.58599299774505 6.95640817610547 5.59127267473377 5.16561390343122 7.42165232286789 7.67052101087756 8.01802202407271 1.34738174290396 9.9113971143961 6.45818890351802 2.01887193368748 2.37868518102914 2.17265490186401 6.24533296190202 3.16627598972991 3.25016977125779 6.8132501419168 7.80950231966563 8.28637997806072 8.71726355841383 9.37451937492006 6.38415863760747 2.33319262578152 1.82571107987314 2.12901356327347 5.94773496710695 3.99393189745024 3.83132524741814 1.50626295758411 1.2881348785013 1.64682773360983 1.42752493289299 1.93693474610336 4.88329211995006 7.52548700617626 3.02465808205307 2.3921529087238 1.95326589327306 2.26950056781061 7.94547227048315 4.34167090011761 5.3974607733544 1.66972531192005 1.3131431855727 5.46529996651225 8.39526492147706 6.01185042015277 4.23846040037461 5.06430319976062 1.65494950651191 1.53362444625236 8.88377681863494 2.80744478083216 9.80267019080929 2.56571591109969 9.66023133648559 1.61912957113236 2.77521832031198 5.72466089879163 7.88472253922373 9.55687731760554 6.7242026780732 5.76568061695434 5.8344468108844 5.8356138211675 7.99269156693481 4.54347171913832 4.40421134536155 7.16962190554477 1.35850343876518 1.23909634863958 9.92263725074008 6.85895411809906 2.52055829460733 9.48242546501569 7.54030264029279 5.84765750332735 3.82546444470063 4.44563251477666 2.63809934468009 4.80391915980726 3.02439787425101 5.49898126558401 4.70513860904612 1.52504913276061 9.14550600526854 5.24063457292505 6.06698298547417 7.39441935392097 2.14088273211382 5.88234777608886 3.06723307911307 4.40310599235818 3.97176808561198 7.8626407966949 7.35927894152701 6.80389990680851 7.00511337234639 2.63070954661816 5.52314574550837 4.73486101999879 6.7600533561781 2.74778442038223 7.04075276781805 1.59416699153371 4.06494637974538 2.99938083114102 8.21600475837477 5.26515056891367 9.2464002687484 3.32129229209386 3.18080744799227 7.70346303866245 7.1787979437504 5.07270585652441 5.74867678852752 6.09640810708515 8.75508068758063 8.01597340940498 3.25402308511548 1.99667640891857 1.90362687967718 8.28132195421495 5.96687072841451 8.70704850158654 4.01338832103647 4.62109186616726 7.66599160223268 1.78584448737092 5.39021236542612 4.5673517130781 5.21761354804039 6.83895778469741 1.45447073993273 5.087519407738 9.91865464183502 9.1269989348948 3.44995983876288 6.60503722983412 8.43082582461648 2.54274207632989 1.08799600647762 9.83124734880403 5.82872290769592 9.79296589153819 1.87159385881387 6.47221417236142 6.48403073428199 8.61192114884034 9.92063675657846 9.11498032300733 8.55545578966849 5.72469105687924 2.81520003196783 5.78146841563284 8.14194500911981 9.88264502189122 4.44977410533465 7.14365364843979 9.73663750942796 9.41764392936602 8.50089461239986 3.27623152011074 4.76442139409482 5.03553973510861 8.806874248432 5.0505686509423 9.92095851898193 6.33113226015121 1.90884668473154 5.82383351097815 6.64072613720782 1.29983768123202 8.23342384514399 2.74872635770589 8.41338782198727 8.30709649296477 4.86423249985091 8.24652907438576 4.85022363229655 4.82796066463925 3.20828758878633 5.77166440943256 5.5434378804639 9.44235613523051 2.06330103706568 6.91084417561069 3.932693061186 2.70850644283928 2.17454843455926 4.09451342583634 1.18333962280303 4.9959122762084 4.73231012816541 4.88826762815006 3.62117314222269 6.46578421746381 4.25242409994826 7.19285090640187 1.33526551537216 4.38309220364317 4.80075901886448 8.63000915967859 2.06409857724793 5.577469995711 8.33781199390069 2.62768296920694 6.43966522021219 3.11668637697585 5.73243348370306 5.48374081146903 6.6360675173346 2.95022391946986 8.54691630671732 4.66552376910113 9.94295593956485 8.20021712733433 7.70533536514267 2.79104186990298 5.70153603889048 6.75169946951792 6.35167670925148 3.61042754654773 1.74996201042086 5.71646629553288 7.81278001051396 1.22816229215823 4.89357767696492 3.70069307065569 8.00485573057085 2.75772337522358 6.35828304872848 4.39719992736354 3.31227227044292 5.06543013826013 2.26471275556833 5.65598049364053 4.57984167081304 3.58720357902348 8.15805835463107 9.039770077914 5.95343825710006 5.84748071851209 4.52671904186718 5.37062994297594 5.67492707329802 9.47266847500578 4.05498449830338 4.00843284768052 2.53586889896542 8.02430775365792 8.33878355496563 3.6434255214408 2.44866447942331 7.90760411438532 6.51480135880411 8.94252308015712 7.54933292977512 9.29425606597215 7.27190781012177 1.74253667518497 6.83051700913347 6.19789422093891 6.64498548093252 2.5473895042669 1.42583782132715 3.21410906570964 7.79661309416406 9.9523754992988 1.59611119073816 5.72659925580956 7.04656662349589 5.24471534439363 6.45865682745352 2.45809234143235 3.63254482205957 5.62710679019801 8.50831765518524 1.6249489588663 2.73481649928726 9.88560677156784 4.17660079407506 3.57764683058485 5.00433777365834 9.94869650178589 7.94151476118714 4.79413782665506 5.03684099833481 6.33571318816394 1.30030533694662 6.38929625181481 9.12418752303347 7.67792249540798 5.67957759625278 6.06850712560117 9.96430848794989 4.37101276847534 1.77190210507251 3.78844059980474 3.2470210485626 3.57842575456016 5.03540396085009 1.01018908759579 3.78596846433356 5.54490030673333 6.27258450724185 1.79368967632763 4.22150230361149 3.46009160252288 2.52909854240716 3.07225930201821 2.03933987906203 6.74185920949094 8.94330113870092 7.87693694978952 4.32864772132598 1.51334009808488 5.42000159691088 8.2371448171325 4.69611489935778 4.24413517094217 4.5542239532806 9.28975110314786 7.08308066637255 7.47948677791283 6.31912888237275 7.88467512908392 6.74357094289735 3.50558955362067 4.49172952887602 1.37770269927569 7.89375654817559 6.4193409322761 3.5061030080542 9.72568298014812 4.69767989916727 4.37766810017638 9.67046089819632 1.6246192692779 1.11212955508381 3.93227518768981 4.70077590807341 7.47853873437271 9.56212568189949 8.78117888933048 6.01468159025535 4.42408018792048 4.33412959286943 8.04337530094199 4.60895830905065 8.11411684541963 6.1350047532469 1.32600826071575 4.24290551850572 4.56129533960484 6.64738673274405 3.35187459830195 3.28285626624711 6.72830353677273 6.74022991838865 3.84028440178372 7.99783487035893 7.13456541066989 6.75468080979772 7.54204055876471 2.9925713960547 5.1758568615187 6.5615268626716 5.32794019766152 6.20002729166299 2.02652285946533 2.61309093493037 1.42568622622639 7.11988725443371 2.38165448489599 5.20442420430481 8.45435957890004 9.82825601310469 8.52642564848065 8.32976208743639 3.53441497730091 1.12356970459223 2.01611989922822 4.35129874176346 2.52393299131654 8.14064419851638 4.17228786065243 6.21644156635739 2.02957692113705 7.13230049679987 3.22992830071598 8.2938144474756 8.1326039081905 1.30301843956113 2.47672270541079 8.11550171812996 3.65622060978785 1.83721688902006 1.14723596628755 3.02282183966599 5.19552208040841 7.47565117082559 6.27153415209614 6.8156244836282 7.78563644504175 4.86698633851483 4.89884683676064 7.38115685293451 1.47378359828144 4.31999227474444 1.28435912239365 2.25075603602454 4.27644238690846 9.74772106134333 9.59904820425436 5.67323433118872 7.00984459626488 1.81158554460853 4.89900834136643 9.26071442407556 6.52527822437696 1.6038553903345 2.42100520059466 2.43178273132071 1.37042172974907 5.28730007703416 5.28428716212511 7.18416452012025 9.96309317066334 2.96327886776999 5.72242665220983 4.33517422527075 7.05130909592845 3.40947294561192 2.0137566823978 4.48128178622574 8.88751946203411 3.49824873311445 9.14676707098261 4.87053082324564 3.42025387939066 7.12623640568927 6.87907270365395 1.16858758637682 7.07178584649228 6.22646175860427 9.01484092953615 7.64391837152652 5.14383425097913 4.94256837549619 8.29866906558163 9.45261698029935 2.99010036699474 5.83977926243097 2.15500868856907 6.61174911214039 4.84329365915619 5.0090847115498 7.5584513193462 4.41937667247839 6.19579754234292 5.83135299175046 7.58042039442807 6.33740327949636 1.92932450398803 9.94568539317697 5.74381736130454 3.5047484904062 1.5302953554783 5.87262116209604 1.52810129174031 5.91520366305485 6.66952305822633 1.93139765877277 9.23836609721184 1.59602228389122 2.50146809103899 9.20843093469739 5.51136457198299 3.60304336855188 7.6189514962025 7.17493071383797 4.47896455461159 1.96067742980085 3.61414436111227 1.20884095132351 3.41646366659552 9.05803545401432 2.00441318843514 1.02250547707081 8.88341218070127 3.98594752908684 9.01784826838411 6.6584324571304 2.46122533129528 8.77987719024532 2.49003507243469 9.15088531165384 3.44572066399269 8.97762745036744 5.59791315160692 2.38604781962931 3.8120827069506 4.01026908797212 1.49187848647125 6.62250597518869 9.88135448331013 7.09118017274886 9.76422794559039 9.62360339192674 4.69606157578528 1.91757594025694 4.44055108027533 3.07856145384721 7.78767073503695 7.32604484632611 8.58043822599575 6.43935925140977 9.86324972123839 4.11291626514867 1.06691778311506 5.64200008264743 4.62275046249852 8.94928734516725 1.8685229641851 9.9335574854631 7.00514382170513 4.66234395373613 3.86114089656621 5.00937083829194 4.95943821500987 1.3082012028899 9.06615577894263 6.79568873881362 5.40413528494537 2.81528636766598 9.00966251431964 2.98685096506961 9.0859644038137 2.0848561571911 5.72817371459678 5.78763380204327 7.54763679928146 3.4324862214271 4.83514337730594 2.48721401300281 3.63172363233753 6.09710420947522 2.26664848066866 1.78755665454082 6.43879535468295 1.62070367578417 8.67568647302687 1.12026833905838 7.195762274554 8.2600040063262 9.15959845716134 2.40955713856965 9.62591657298617 9.15462378086522 1.05782309966162 8.63879389083013 1.41167590231635 8.8909296351485 3.61374800396152 4.70390702039003 7.1929536559619 4.30294688255526 8.92572283558547 1.62212541420013 4.916370611405 3.97990029607899 5.10741455270909 1.93166745547205 4.92728285817429 2.30887422268279 2.81732801278122 6.99071884923615 2.23329743067734 6.52125382539816 5.09316886705346 2.78473402676173 1.22276578820311 1.45092712691985 1.34372729388997 8.65190578158945 5.09301916207187 4.84702909830958 3.84327325015329 1.14309008629061 7.98689071997069 4.6456050039269 9.96922879293561 1.82870882772841 6.18293760321103 2.26300661289133 8.08405439951457 4.41169432923198 7.35005581169389 7.91689379024319 8.25873631471768 8.73880629637279 2.13744354923256 5.08242138754576 2.00781230581924 9.16786315618083 1.11750117316842 8.48685048427433 9.97852200595662 2.80341740627773 1.80038357106969 3.07279676222242 6.25500209699385 7.14539847359993 6.54409145005047 2.92353686387651 7.22795612108894 2.95121719595045 7.74118598247878 8.70545753464103 2.52599918283522 2.33089230046608 8.71127007016912 6.79031572723761 6.09219919308089 7.48944593104534 3.2192058369983 6.54720961442217 9.09163101040758 6.5689970033709 4.85331607470289 3.92805049265735 3.13802669616416 7.78986479877494 8.63554093497805 2.0401073701214 5.2173885400407 3.75464106770232 5.26419921871275 9.07079701684415 7.99670010525733 9.93173161777668 4.16319533553906 2.93798929755576 1.33663614932448 6.7687260673847 8.86143201217055 7.90902276406996 8.65467278612778 7.16390157723799 2.24303580657579 8.73038306622766 5.47901336569339 5.29018445964903 3.15135991945863 7.98082222416997 6.26707289880142 3.05806898721494 7.33096436341293 8.04320723959245 9.89047352038324 6.03510208567604 3.87319039157592 1.8604006820824 6.59875717689283 3.95166657608934 7.06895268149674 4.52440941473469 2.23944992362522 8.83256336092018 4.99290988058783 9.22754639922641 3.79881786950864 8.56558693107218 3.07696984359063 2.53812867682427 7.02390640601516 9.66679846751504 8.52713205851614 1.46130936499685 3.03556410945021 4.28548369859345 4.64947764645331 1.67086830595508 4.14773062989116 6.15563987987116 5.12216038443148 9.59751978516579 2.71666815550998 2.46656217915006 7.72283740341663 4.39731638971716 2.85699736862443 2.37124923639931 7.00915329880081 6.7145049313549 3.0696331365034 1.32963626482524 8.25515394168906 2.05235835141502 1.59112951555289 6.05809562001377 7.43187539908104 5.6127177698072 1.6550830155611 2.80314656184055 6.57951991911978 8.95007659774274 9.70519936480559 8.20005282945931 5.03497301158495 8.78584306221455 3.18066929746419 7.55805327743292 7.20878200419247 8.6924861476291 3.18353292020038 9.29635945009068 9.74367574742064 2.51233287947252 9.58300267253071 1.88745438936166 3.68232839205302 2.11382311559282 2.11442754720338 7.54751290008426 3.0804354546126 6.94673927151598 2.03881574608386 3.25197074050084 8.51222480391152 1.75651141791604 4.53415926755406 7.2140635587275 3.48159317276441 2.96162007655948 1.54945575539023 6.45608835667372 4.31729301903397 5.68695106217638 4.82018206571229 1.47547274245881 2.75248352065682 3.48782378714532 8.28822645894252 3.66905193100683 9.11574458912946 9.71659241849557 7.46158965025097 6.89686125004664 8.38125712051988 9.20666827913374 9.36152027733624 4.50624411646277 3.36902696662582 6.78288282942958 5.09698706073686 9.43610654002987 5.10388957057148 8.87666351860389 2.61768198828213 2.85630463785492 8.259884608211 3.99200363224372 5.81975439074449 9.54177333135158 7.99608029285446 3.69953889306635 6.91692899307236 2.58889601402916 6.23668193258345 3.58497272920795 7.19957608659752 5.37615275382996 7.01899557886645 8.03182619297877 4.94504821393639 5.06448743399233 8.48994903289713 6.34586562588811 4.31507389969192 1.42355705937371 5.30438063968904 6.13829176058061 5.41390736447647 9.60652076732367 5.41090131853707 2.7265454614535 2.00351250683889 9.02546766144224 5.20304337167181 2.49823663057759 2.19278773036785 4.14509290573187 6.66955789551139 3.73623539321125 6.54905530111864 4.82749668229371 6.95357837434858 6.38495073164813 8.97897333675064 8.94293158268556 7.94802800286561 2.15624519530684 2.89716162555851 3.35209365095943 3.70218853000551 4.25760737038217 6.52407049690373 3.1636702362448 6.86397070810199 2.66254810313694 4.13262285920791 5.60040088160895 1.09770572255366 9.97975903027691 9.89799514482729 7.47448330977932 2.29429619456641 1.33292063814588 3.11665088380687 9.73499417025596 7.62646747753024 3.3387422200758 8.40349311521277 8.92772611463442 2.20078928163275 1.18368473299779 3.77057281718589 9.2170956118498 8.60466950968839 3.48623930988833 5.62692515435629 4.70759537210688 3.54680698411539 7.16300218226388 7.33452817890793 5.57506384886801 9.21251079882495 2.02668238594197 3.21897393488325 6.77454905933701 6.66340076946653 7.09243859397247 7.46580150420777 6.31617087731138 7.73814113461412 7.27721447683871 9.18882038677111 2.89248609519564 4.4633858341258 8.1684314312879 3.63277401472442 6.99631306552328 8.3909066147171 2.58697132999077 3.41367088351399 8.49826512555592 7.46402601595037 1.1546654778067 4.54421296855435 2.8947861941997 5.83523356984369 2.78969138604589 6.60782613209449 9.11895651137456 8.3294113362208 3.16995236789808 4.16363988444209 5.39612100366503 1.39274732489139 9.22327253175899 4.13111352571286 4.86570799560286 9.89554193988442 1.2010521076154 6.10489942971617 8.64954310539179 2.85659960540943 6.97467373660766 6.16427491651848 9.32084305211902 6.22265032911673 1.17886673961766 5.79922811989672 7.95682526286691 1.97715141717345 4.28826810186729 6.49539274559356 9.30783010553569 2.42550667654723 7.69470757921226 5.74810259463266 5.83743882761337 5.43307243729942 3.44072033069097 1.93235690891743 2.18748615356162 3.84593328484334 8.97501735924743 1.84037293749861 7.28854769002646 9.01852479903027 3.56533566094004 2.48032669117674 5.48016743850894 9.5225555615034 5.89875038107857 1.87872691499069 4.04775307630189 3.83172544138506 9.06353494222276 5.05163991474546 7.02137815370224 7.1654900694266 4.78959400532767 4.36548626748845 5.86449120217003 9.64484458672814 9.73312182282098 3.03829280869104 7.19126646476798 4.12007779884152 7.5615981623996 9.29759038286284 9.3938352256082 2.32980187563226 4.45709039620124 2.22988533391617 8.22373676439747 8.39004713017493 7.88900947617367 8.79366129497066 8.73802503594197 9.63368147797883 3.98489418998361 4.04519647848792 6.58399489778094 9.77242210460827 9.03897639969364 3.69829548173584 3.77106966078281 5.52287775930017 1.61153178242967 3.43507251213305 1.0771338311024 9.00492631783709 4.31216242676601 1.85857236059383 7.38985188514926 4.41509320563637 3.81020900793374 7.00252598989755 6.35192588018253 1.12945442297496 9.06288096727803 9.86878835922107 3.35240156436339 5.29173587448895 9.80473881936632 1.29165758285671 4.78184516634792 9.76990470057353 3.1352930306457 6.03651058906689 2.98730812035501 7.11366257653572 1.13187784492038 2.26958896545693 5.28006509901024 2.60983836464584 9.96370334597304 7.7252301434055 2.82393217505887 1.65154301933944 2.25088796089403 7.01937751914375 9.27268160879612 2.93387057073414 6.70170802832581 1.67252273228951 8.43666244763881 8.09274241817184 6.5733302209992 9.92190940398723 1.81527173379436 2.02886770945042 1.63831814262085 3.40372194373049 7.20372902834788 2.1879282486625 5.2873342668172 3.75683877337724 2.51219906029291 5.77801589504816 7.19183933222666 9.01833188533783 6.67505455901846 4.53023152449168 7.63564170734026 1.33723553083837 4.41501470492221 2.66593511076644 6.21380852349102 1.61311190528795 7.60415056813508 8.13550310162827 3.08660894213244 5.81408480857499 3.17559090768918 3.16601335955784 5.86815523169935 8.97638902207837 6.10439161630347 1.99600020726211 4.14044309523888 5.12679124763235 8.3833477369044 4.01769788912497 1.86332320445217 2.8078008859884 1.06917406362481 1.3409542334266 6.55385075346567 5.73375920532271 1.94404978118837 9.97197909024544 7.8620945145376 8.1593562127091 1.1320157062728 9.83371031866409 3.16593834152445 8.53944901376963 5.69741002609953 8.95124944183044 8.66060056863353 5.41121308552101 9.20018901140429 2.81871298188344 2.23115229839459 5.24841371038929 2.60744185489602 9.52273476868868 4.43430548952892 9.57691370602697 2.8480049779173 5.78351940657012 9.90460852300748 7.57326552015729 8.51571874995716 5.50678598461673 7.70585002657026 5.45316869136877 4.81502335844561 3.17974023055285 4.16057294397615 5.48015303420834 6.92583878431469 7.66325659980066 8.74328161659651 6.57159092160873 3.12705428828485 1.55360458791256 5.10958654480055 1.66301800822839 8.11121727479622 4.93743857950903 3.51387778064236 9.84571163239889 9.50017211236991 7.82647097762674 1.40183084784076 5.1953215894755 2.58228930155747 7.01166751142591 6.14269824861549 5.17654949380085 9.33338923985139 8.80559220071882 8.44161514029838 8.8943681998644 8.12296198075637 2.74222886143252 3.87383516947739 5.74498054524884 8.6830016952008 4.21602466702461 3.93890820257366 3.51158190821297 2.58764222590253 2.08911774936132 5.29552288120613 1.64548060460947 3.93423123890534 9.20062927086838 7.42290219035931 6.40952457953244 8.96969321207143 7.2085259789601 8.61960162501782 9.02196666621603 8.33217598963529 5.87142361234874 7.70683911629021 3.06360177043825 5.32156840898097 2.14691399340518 1.20216230954975 8.83519936050288 3.2753178444691 8.61288188677281 3.52247653831728 2.75940650748089 2.26855921302922 4.97318298765458 1.08121562935412 8.56787826470099 5.20289897872135 2.73264065571129 5.4077553555835 1.7716172314249 7.84572871029377 7.47586362692527 2.09821549849585 1.28663306566887 9.88610287127085 2.51433792500757 2.3650938894134 2.64404062204994 2.00834519788623 9.60450964490883 4.70493706618436 7.90752556128427 6.95438316906802 6.3784797557164 6.57403056253679 1.21758897183463 3.59450925001875 4.43400749401189 5.9340381892398 6.88308534491807 6.96082757646218 9.209107599454 6.06726395525038 5.15968720638193 1.31029395875521 5.26441815402359 4.86612411309034 5.7794421010185 7.03463619342074 6.79410422593355 8.23046464985237 8.06897941255011 6.9530750871636 7.19999043340795 5.42946922266856 6.34750774758868 9.32192119956017 9.08457038016059 2.8820205682423 5.66732001421042 3.79055909230374 5.59874965297058 2.5333921785932 9.91301691927947 8.31383411609568 4.59239522204734 7.42961805616505 9.0702529810369 2.0053395961877 9.72770922980271 4.67023349343799 9.78118073241785 8.9832858426962 9.80512457340956 4.49647857691161 4.11111917463131 3.13001727010123 3.87373227532953 5.02846845984459 3.85665631224401 5.84008268313482 6.94023765763268 4.99903381848708 4.1856260439381 6.7817015866749 8.33062290260568 5.89247034699656 6.72942979005165 2.46141477068886 8.58496909937821 5.62259964598343 8.06316513358615 1.12612556898966 8.60121048055589 7.24128404911608 1.64497002097778 leidenbase/tests/cpp_tests/test_files/0000755000176200001440000000000014451330317017655 5ustar liggesusersleidenbase/tests/cpp_tests/test_files/test_set_1.txt0000644000176200001440000000277614451337356022516 0ustar liggesuserstest_start test_name: 'test_1_1' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'CPMVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_1_1' test_end test_start test_name: 'test_1_2' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'ModularityVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_1_2' test_end test_start test_name: 'test_1_3' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'RBConfigurationVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_1_3' test_end test_start test_name: 'test_1_4' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'RBERVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_1_4' test_end test_start test_name: 'test_1_5' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'SignificanceVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_1_5' test_end test_start test_name: 'test_1_6' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'SurpriseVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_1_6' test_end leidenbase/tests/cpp_tests/test_files/test_set_2.txt0000644000176200001440000000331514451337356022505 0ustar liggesuserstest_start test_name: 'test_2_1' edgelist_file: 'edgelist.edg' weights_file:'edge_weights.txt' membership_file:'initial_memberships.txt' directed: False partition_type_name: 'CPMVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_2_1' test_end test_start test_name: 'test_2_2' edgelist_file: 'edgelist.edg' weights_file:'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: False partition_type_name: 'ModularityVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_2_2' test_end test_start test_name: 'test_2_3' edgelist_file: 'edgelist.edg' weights_file: 'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: False partition_type_name: 'RBConfigurationVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_2_3' test_end test_start test_name: 'test_2_4' edgelist_file: 'edgelist.edg' weights_file: 'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: False partition_type_name: 'RBERVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_2_4' test_end test_start test_name: 'test_2_5' edgelist_file: 'edgelist.edg' weights_file: 'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: False partition_type_name: 'SignificanceVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_2_5' test_end test_start test_name: 'test_2_6' edgelist_file: 'edgelist.edg' weights_file: 'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: False partition_type_name: 'SurpriseVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_2_6' test_end leidenbase/tests/cpp_tests/test_files/test_set_4.txt0000644000176200001440000000277614451337356022521 0ustar liggesuserstest_start test_name: 'test_4_1' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'CPMVertexPartition' resolution_parameter: 0.1 n_iterations: 2 seed: 2016 outname_root: 'test_4_1' test_end test_start test_name: 'test_4_2' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'ModularityVertexPartition' resolution_parameter: 0.1 n_iterations: 2 seed: 2016 outname_root: 'test_4_2' test_end test_start test_name: 'test_4_3' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'RBConfigurationVertexPartition' resolution_parameter: 0.1 n_iterations: 2 seed: 2016 outname_root: 'test_4_3' test_end test_start test_name: 'test_4_4' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'RBERVertexPartition' resolution_parameter: 0.1 n_iterations: 2 seed: 2016 outname_root: 'test_4_4' test_end test_start test_name: 'test_4_5' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'SignificanceVertexPartition' resolution_parameter: 0.1 n_iterations: 2 seed: 2016 outname_root: 'test_4_5' test_end test_start test_name: 'test_4_6' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'SurpriseVertexPartition' resolution_parameter: 0.1 n_iterations: 2 seed: 2016 outname_root: 'test_4_6' test_end leidenbase/tests/cpp_tests/test_files/test_set_3.txt0000644000176200001440000000330714451337356022507 0ustar liggesuserstest_start test_name: 'test_3_1' edgelist_file: 'edgelist.edg' weights_file:'edge_weights.txt' membership_file:'initial_memberships.txt' directed: True partition_type_name: 'CPMVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_3_1' test_end test_start test_name: 'test_3_2' edgelist_file: 'edgelist.edg' weights_file:'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: True partition_type_name: 'ModularityVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_3_2' test_end test_start test_name: 'test_3_3' edgelist_file: 'edgelist.edg' weights_file: 'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: True partition_type_name: 'RBConfigurationVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_3_3' test_end test_start test_name: 'test_3_4' edgelist_file: 'edgelist.edg' weights_file: 'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: True partition_type_name: 'RBERVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_3_4' test_end test_start test_name: 'test_3_5' edgelist_file: 'edgelist.edg' weights_file: 'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: True partition_type_name: 'SignificanceVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_3_5' test_end test_start test_name: 'test_3_6' edgelist_file: 'edgelist.edg' weights_file: 'edge_weights.txt' membership_file: 'initial_memberships.txt' directed: True partition_type_name: 'SurpriseVertexPartition' resolution_parameter: 0.5 n_iterations: 2 seed: 2016 outname_root: 'test_3_6' test_end leidenbase/tests/cpp_tests/test_files/equals/0000755000176200001440000000000014451330404021144 5ustar liggesusersleidenbase/tests/cpp_tests/test_files/equals/test_set_1.txt0000644000176200001440000000310614451337356023774 0ustar liggesusers#test_start test_name = 'test_1_1' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_1_1' #test_end #test_start test_name = 'test_1_2' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_1_2' #test_end #test_start test_name = 'test_1_3' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_1_3' #test_end #test_start test_name = 'test_1_4' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_1_4' #test_end #test_start test_name = 'test_1_5' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_1_5' #test_end #test_start test_name = 'test_1_6' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_1_6' #test_end leidenbase/tests/cpp_tests/test_files/equals/test_set_2.txt0000644000176200001440000000340614451337356024000 0ustar liggesuserstest_start test_name = 'test_2_1' edgelist_file = 'edgelist.edg' weights_file:'edge_weights.txt' membership_file:'initial_memberships.txt' directed = False partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_2_1' test_end test_start test_name = 'test_2_2' edgelist_file = 'edgelist.edg' weights_file:'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_2_2' test_end test_start test_name = 'test_2_3' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_2_3' test_end test_start test_name = 'test_2_4' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_2_4' test_end test_start test_name = 'test_2_5' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_2_5' test_end test_start test_name = 'test_2_6' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_2_6' test_end leidenbase/tests/cpp_tests/test_files/equals/test_set_4.txt0000644000176200001440000000307214451337356024001 0ustar liggesuserstest_start test_name = 'test_4_1' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'test_4_1' test_end test_start test_name = 'test_4_2' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'test_4_2' test_end test_start test_name = 'test_4_3' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'test_4_3' test_end test_start test_name = 'test_4_4' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'test_4_4' test_end test_start test_name = 'test_4_5' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'test_4_5' test_end test_start test_name = 'test_4_6' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'test_4_6' test_end leidenbase/tests/cpp_tests/test_files/equals/test_set_3.txt0000644000176200001440000000340014451337356023773 0ustar liggesuserstest_start test_name = 'test_3_1' edgelist_file = 'edgelist.edg' weights_file:'edge_weights.txt' membership_file:'initial_memberships.txt' directed = True partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_3_1' test_end test_start test_name = 'test_3_2' edgelist_file = 'edgelist.edg' weights_file:'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_3_2' test_end test_start test_name = 'test_3_3' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_3_3' test_end test_start test_name = 'test_3_4' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_3_4' test_end test_start test_name = 'test_3_5' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_3_5' test_end test_start test_name = 'test_3_6' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'test_3_6' test_end leidenbase/tests/cpp_tests/test_files/equals/test_set_5.txt0000644000176200001440000000307214451337356024002 0ustar liggesuserstest_start test_name = 'test_5_1' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'test_5_1' test_end test_start test_name = 'test_5_2' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'test_5_2' test_end test_start test_name = 'test_5_3' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'test_5_3' test_end test_start test_name = 'test_5_4' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'test_5_4' test_end test_start test_name = 'test_5_5' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'test_5_5' test_end test_start test_name = 'test_5_6' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'test_5_6' test_end leidenbase/tests/cpp_tests/test_files/test_set_5.txt0000644000176200001440000000277614451337356022522 0ustar liggesuserstest_start test_name: 'test_5_1' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'CPMVertexPartition' resolution_parameter: 0.1 n_iterations: 3 seed: 2016 outname_root: 'test_5_1' test_end test_start test_name: 'test_5_2' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'ModularityVertexPartition' resolution_parameter: 0.1 n_iterations: 3 seed: 2016 outname_root: 'test_5_2' test_end test_start test_name: 'test_5_3' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'RBConfigurationVertexPartition' resolution_parameter: 0.1 n_iterations: 3 seed: 2016 outname_root: 'test_5_3' test_end test_start test_name: 'test_5_4' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'RBERVertexPartition' resolution_parameter: 0.1 n_iterations: 3 seed: 2016 outname_root: 'test_5_4' test_end test_start test_name: 'test_5_5' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'SignificanceVertexPartition' resolution_parameter: 0.1 n_iterations: 3 seed: 2016 outname_root: 'test_5_5' test_end test_start test_name: 'test_5_6' edgelist_file: 'edgelist.edg' weights_file: None membership_file: None directed: False partition_type_name: 'SurpriseVertexPartition' resolution_parameter: 0.1 n_iterations: 3 seed: 2016 outname_root: 'test_5_6' test_end leidenbase/tests/cpp_tests/edge_weights.txt0000644000176200001440000416416614444624071020742 0ustar liggesusers0.79490859863814 0.931301039159298 0.972387232058681 0.760992606214713 0.788359774376731 0.459851952770259 0.953903821744025 0.0902801301074214 0.440764791832771 0.805843545151874 0.265288385846652 0.0294845965248533 0.654374293198343 0.120589254919905 0.689030879028142 0.611943721694406 0.39933788098162 0.219940175919328 0.349626077869907 0.070124077508226 0.302261099498719 0.609767822504509 0.80906865801895 0.441521257630084 0.251783711225726 0.190329059206415 0.270689954105765 0.220709832212888 0.642924462780356 0.544415256101638 0.944740430677775 0.676276938763913 0.613690819921903 0.161340886815451 0.0621931792120449 0.363723371003289 0.58405420434894 0.279845784464851 0.498390989734326 0.214139961244073 0.0199226809781976 0.0804447295307182 0.357149578959215 0.0328935184096917 0.165607609087601 0.427531060953625 0.178110514327418 0.776757337811869 0.440928035893012 0.0583284663851373 0.723140240784269 0.506729069256689 0.971951574804261 0.303470852060709 0.369749043472111 0.759283016941044 0.476183621231467 0.310984140974469 0.819048855784349 0.35759318854427 0.0560099692293443 0.600755621378776 0.765346399131231 0.550013569169678 0.507245026610326 0.178926267861389 0.876003149515018 0.954743837262504 0.517888952859212 0.723174489282537 0.0961568687926047 0.426369771508034 0.137805656353012 0.594132546090987 0.278866262477823 0.421052794840653 0.0472701326617971 0.97801856481703 0.600084328961093 0.578720494594891 0.448755539369304 0.849029090411495 0.545180141688325 0.925187562818173 0.680860116772819 0.624971891741734 0.604818270020187 0.537580021391623 0.582724344625603 0.609657275888603 0.62674765155185 0.569702672900166 0.874553525848314 0.61319177567726 0.0226687147910707 0.661499663274735 0.710370488290209 0.76399133997038 0.443822950473987 0.38066981040407 0.333691205352079 0.147327897376381 0.511556042442098 0.345780209300574 0.340735497153364 0.098114639010746 0.0758998416480608 0.323397570508532 0.050871422807686 0.216192572109867 0.908421270214021 0.523689337184187 0.962970110704191 0.181862862335984 0.524640998814721 0.0399739928543568 0.88250089653302 0.588968982789665 0.984582581717987 0.280488253256772 0.625339040474501 0.617036058621015 0.159355436032638 0.86615209414158 0.888539697031956 0.79722136458382 0.582457743086852 0.387659523861948 0.0675976575631648 0.28984922170639 0.774079898959026 0.164803178980947 0.839262626399286 0.419891425410751 0.082494852815289 0.921590181530919 0.737774491186719 0.457308835696895 0.153753038924187 0.980996720707044 0.259226069038268 0.37751696186373 0.0402149786683731 0.803308585325722 0.274920837183017 0.578503571611363 0.747691088747233 0.873313928304706 0.1100604784186 0.504936974206939 0.603467006541323 0.604944812115282 0.0768286051764153 0.237820303300396 0.206184888323769 0.292276143934578 0.0616812752420083 0.18998146652244 0.0887953269435093 0.264762605866417 0.560839155693538 0.408940549571998 0.855565023829695 0.942689588225912 0.941524936903734 0.543292712946422 0.956641293547582 0.201370248396415 0.470059499139898 0.451204710374586 0.884056551274844 0.510226409763563 0.623952425543684 0.320829611506779 0.773782222478185 0.217870980640873 0.645605159322731 0.81164103390649 0.494852600449231 0.864056601081975 0.689409598286729 0.376444228880573 0.772017023593653 0.872871890515089 0.734688924895599 0.674167877875734 0.185148180108517 0.407573622076306 0.122955192453228 0.778909690496512 0.0302396793081425 0.0985345333628356 0.74828716410324 0.521661338205449 0.0772830004268326 0.442064171771053 0.372860975312069 0.840193314161152 0.491081883017905 0.733975380477495 0.886755856962409 0.0497791351587512 0.483817792485934 0.678807214552071 0.0591772073390894 0.0625757718319073 0.941707439664751 0.0277989665861242 0.78265712534776 0.260580019021872 0.126433720050845 0.280239638276398 0.106376232095063 0.828495356736239 0.469097249845508 0.0222999728261493 0.443358958489262 0.509768019216135 0.121207163918298 0.0542175026098266 0.851398011336569 0.429179915627465 0.975612228522077 0.134200009712949 0.287591861146502 0.059582445891574 0.133314414662309 0.871899260086939 0.100882633933797 0.991362312156707 0.63550333999563 0.159498805028852 0.356640751273371 0.653573583399411 0.38701112908544 0.222308959695511 0.0161210084659979 0.20471806434216 0.220224694404751 0.574863557303324 0.374992219975684 0.253992737750523 0.355873112336267 0.716744317251723 0.975698742272798 0.687607491828967 0.363684262824245 0.236450999095105 0.386013874092605 0.386160163783934 0.954083832774777 0.716702561522834 0.0456960467225872 0.883116559977643 0.983382222126238 0.535272189117968 0.686101609226316 0.649400397823192 0.751814732686616 0.646071513495408 0.382386765149422 0.015923986362759 0.411761497796979 0.312382669649087 0.750154036877211 0.10252746311482 0.725331998534966 0.0557572342501953 0.711954168197699 0.0518684270139784 0.0621630032290705 0.143257909540553 0.564831366739236 0.48853624609299 0.811666583938058 0.0925170942069963 0.46569784401916 0.226251019656193 0.47603936733678 0.0642104609846137 0.0413447432313114 0.170494605312124 0.0782287794072181 0.286142012279015 0.486325675894041 0.605286435941234 0.79501757461112 0.635748150304426 0.0464023072668351 0.274958372644614 0.827982701098081 0.626585831074044 0.978468891240191 0.256100948776584 0.270159493084066 0.0155597193702124 0.0293853890104219 0.165480786471162 0.386343166965526 0.369741227368359 0.848046363058966 0.615763549953699 0.933491120466497 0.138165014798287 0.152761151869781 0.4694453570107 0.264474903221708 0.586722802976146 0.0610579634993337 0.292865812939126 0.928558178441599 0.738380757973064 0.133006581787486 0.52154782963451 0.182882763722446 0.87195764771197 0.217077888022177 0.97864534469787 0.934804093588609 0.0241699322569184 0.814229310536757 0.0361952698463574 0.557681137216277 0.0508323199301958 0.081390114352107 0.983319347312208 0.500351752564311 0.0102482302719727 0.910740180660505 0.385231701752637 0.467475084345788 0.895201711310074 0.852317363223992 0.574044643582311 0.518705267896876 0.392142121484503 0.535323607043829 0.859085901621729 0.913951824815012 0.0625504760444164 0.236032757675275 0.875567996830214 0.586316308185924 0.968146607491653 0.0973583467816934 0.135131750178989 0.62687921698438 0.272868978446349 0.370109673598781 0.218399459342472 0.569734750757925 0.45884448398836 0.559932799527887 0.393787221044768 0.226840310175903 0.756837713303976 0.940298464163207 0.339469562412705 0.0456153734400868 0.15458570349263 0.610352798942477 0.839242577997502 0.970399698456749 0.852296127735171 0.410717527586967 0.865780976850074 0.752265465254895 0.920955538523849 0.297697016994935 0.242959428743925 0.762315026936121 0.118127659608144 0.320124629558995 0.917150834214408 0.388752879197709 0.0884747111005709 0.987803084768821 0.201107573464978 0.888115806460846 0.206243064347655 0.897852374780923 0.889050178802572 0.546037008310668 0.184723420543596 0.0274268987029791 0.764833232699893 0.765481903618202 0.0948827839503065 0.19976872023195 0.921325535804499 0.888870312988292 0.214097496489994 0.0984192215721123 0.940941555311438 0.99743921515299 0.916316853708122 0.947782035332639 0.415092850113288 0.37913608081406 0.280507964203134 0.320303816082887 0.878315156186 0.931651065486949 0.425552123244852 0.80038149838103 0.707888951529749 0.759813974234276 0.902885284055956 0.67433423302602 0.470819760849699 0.294480958490167 0.0960167026263662 0.471522656290326 0.872408906286582 0.400065562799573 0.652390814363025 0.821999235451221 0.674084810365457 0.615383926434442 0.820346810296178 0.732110421103425 0.0884602198796347 0.687858607990202 0.182171282530762 0.525160037984606 0.852955095192883 0.323558260141872 0.385529878423549 0.82202684963122 0.674520073460881 0.835482954643667 0.120723363715224 0.576340667451732 0.365779473287985 0.731069516113494 0.425249088737182 0.554132459689863 0.439295310389716 0.0148376274644397 0.392881604100112 0.996716869233642 0.0477696328400634 0.591127095497213 0.0400449121999554 0.237953432460781 0.946240481340792 0.823403124688193 0.316483599657658 0.155651009920985 0.583060980380978 0.0458380439993925 0.0346752277156338 0.976494286053348 0.755826346727554 0.502155295973644 0.118639065001626 0.191617293434683 0.266809950906318 0.278556875556242 0.173746329213027 0.386504913682584 0.396297259419225 0.900571503438987 0.574022860189434 0.467218830517959 0.0250140894413926 0.625850567573216 0.237369298508856 0.989275761204772 0.444868226479739 0.593725017958786 0.325253291348927 0.650262048521545 0.217125637042336 0.950892565718386 0.601646362624597 0.561836380029563 0.966796865328215 0.375765111600049 0.262945538193453 0.696921407375485 0.870942035512999 0.0369348455849104 0.911159153694753 0.616792519071605 0.126394431388471 0.676263873199932 0.604350613278802 0.869709644855466 0.659397195214406 0.386961797205731 0.523562938692048 0.849347588859964 0.565377748557366 0.160831259286497 0.391813286158722 0.263716621757485 0.616158509023953 0.376494985034224 0.808983004733454 0.655326465852559 0.576212970539927 0.395898949305993 0.644938557627611 0.0470785531797446 0.37630534430733 0.504273983330932 0.642898338567466 0.469387320901733 0.989147923917044 0.969086619303562 0.304461058522575 0.749720958252437 0.835444120992906 0.0353228574548848 0.793391628412064 0.557704538966063 0.263517702620011 0.903914176416583 0.98865717775654 0.0295304895401932 0.136053409164306 0.529053530180827 0.848930398991797 0.0956764396862127 0.222601578263566 0.575545259437058 0.214849575136323 0.383630842736457 0.469543042748701 0.516874968467746 0.810394162170123 0.733428158708848 0.198383807791397 0.400072848056443 0.217438819415402 0.668239175204653 0.291440387868788 0.443885971657 0.918575180533808 0.108725661973003 0.083890644966159 0.434882093509659 0.637586363570299 0.764007973019034 0.0380529547971673 0.327484638337046 0.504103295889217 0.0267804827890359 0.979520118355285 0.677421336537227 0.583884627928492 0.311815805623773 0.357038449863903 0.499449400685262 0.910311290032696 0.582850503395312 0.996643848398235 0.863138336013071 0.315329314256087 0.360866167526692 0.991424900225829 0.83875496920431 0.506345107452944 0.365811857252847 0.647503691362217 0.938832073525991 0.952231166551355 0.913143906746991 0.110026737486478 0.854161754183006 0.801200094008818 0.0814547183946706 0.869503767082933 0.899590889562387 0.452611410818063 0.409173078716267 0.558935601469129 0.32336332754232 0.581059276186861 0.718726693824865 0.700416429028846 0.485503192844335 0.466586696989834 0.0879031863179989 0.69653569905553 0.892863287457731 0.56048873221036 0.779904832243919 0.247274861691985 0.387959606556687 0.0608457001205534 0.801272978847846 0.450598914735019 0.90229536288185 0.12388802388683 0.77814103896264 0.318372469500173 0.0308039921335876 0.74461259334581 0.46446190224262 0.744674382954836 0.660611756746657 0.302745381912682 0.77021894585574 0.242391820196062 0.406658581965603 0.541536490975413 0.263525009774603 0.636446202660445 0.554246115321294 0.0954490468255244 0.0374242002028041 0.811988800389226 0.743318694983609 0.182305676457472 0.596208648141474 0.203516034760978 0.333433661402669 0.480567202887032 0.407406837730668 0.973380589256994 0.904302125449758 0.678897808655165 0.654207363636233 0.893948532107752 0.489239490283653 0.472817686419003 0.710587549805641 0.832770295725204 0.294106834526174 0.0497472813492641 0.425061012429651 0.905786821430083 0.299329524904024 0.0510125782899559 0.676231615089346 0.324353387174197 0.287820279742591 0.537605791552924 0.0723188449279405 0.942794003479648 0.578780253478326 0.166775916176848 0.0558159782318398 0.829885208611377 0.554026638141368 0.917091839676723 0.286085713696666 0.0646836126712151 0.482152056281921 0.814398923607077 0.214538512923755 0.474495273209177 0.0148419694369659 0.927617617803626 0.36068395819515 0.750929703058209 0.920509991566651 0.490081398687325 0.82481440129457 0.162747442964464 0.102519595839549 0.86304971362697 0.175321461632848 0.947475642866921 0.0284277670504525 0.661150773784611 0.713673077141866 0.0141955943219364 0.062206913693808 0.697969501963817 0.19522625423735 0.859756183517165 0.556694314067718 0.269952176285442 0.362708461605944 0.891093465848826 0.475912516368553 0.163986993255094 0.506693943466526 0.226742351753637 0.487322849058546 0.243065897081979 0.0203326826309785 0.743170815748163 0.756044609160162 0.0757860159059055 0.348397375710774 0.314923023460433 0.878161316390615 0.655250417599455 0.452308142581023 0.715192723269574 0.958773657991551 0.0401725162193179 0.294842913083266 0.579997347309254 0.646862050073687 0.0391985979746096 0.879383204209153 0.437287135303486 0.80552932044724 0.227773029585369 0.998616535805631 0.253541749094147 0.0459294630703516 0.404788645354565 0.0528770556836389 0.154403738032561 0.418247439407278 0.55336887137033 0.951694975702558 0.740708276990335 0.615590512540657 0.52919445032021 0.364959680661559 0.311376758832485 0.662705505134072 0.207935578008182 0.175105119054206 0.838274617546704 0.419442435209639 0.736298401241656 0.0514675048482604 0.364698439224158 0.948990315215197 0.087229922413826 0.385477939562406 0.96296169022331 0.314227270134725 0.476196216340177 0.742350929998793 0.935494345284533 0.150573964749929 0.663550564735197 0.170200120827649 0.100582383663859 0.688196716194507 0.894054725687019 0.296848956944887 0.798558854395524 0.178715635978151 0.0676427518879063 0.0128411930147558 0.605926036823075 0.647664213420358 0.334820771222003 0.823097681661602 0.889411348996218 0.809249622407369 0.285762001054827 0.379592512322124 0.127681752596982 0.357390210030135 0.462750601028092 0.973464072593488 0.785040951706469 0.234225705328863 0.930736044046935 0.32633776105009 0.804825946483761 0.551869666189887 0.186130676036701 0.417424839953892 0.610782121301163 0.091239189018961 0.747016234146431 0.937956770865712 0.94980511931004 0.896988501579035 0.632335915178992 0.726558967316523 0.283261834403966 0.469986240426078 0.927524547413923 0.882865504208021 0.724037006439175 0.568233523610979 0.476743019286077 0.985218336207326 0.831586954582017 0.379558269816916 0.189732882890385 0.171215703983326 0.094135204940103 0.822304726191796 0.0590257085254416 0.249073291867971 0.36956988368649 0.951037131021731 0.0704064228176139 0.0912586784525774 0.597453028378077 0.055211841056589 0.950155283939093 0.178685479587875 0.591925108188298 0.443053890028968 0.539457058857661 0.319808442357462 0.439831779685337 0.0205153896170668 0.369828357021324 0.832771923302207 0.425744873217773 0.139751552934758 0.369366263453849 0.751553927129134 0.900086215343326 0.858784292771015 0.832903530916665 0.98309678001795 0.54623681580415 0.866868901781272 0.497611601862591 0.597089441136923 0.635869607056957 0.410156047865748 0.178052879753523 0.732833474203944 0.357742942455225 0.0225145340827294 0.131219892017543 0.0938554564700462 0.247987188596744 0.818526546016801 0.603561433667783 0.834069370247889 0.205389333479106 0.92127872469835 0.462881779216696 0.334271122955251 0.282710496094078 0.0874338125647046 0.176431297655217 0.472876509693451 0.507216179473326 0.311022119922563 0.994878495999146 0.0219027055054903 0.900712810822297 0.13854588349117 0.0631125135812908 0.25775681210449 0.817390051016118 0.76542589270277 0.288916557847988 0.144822778613307 0.485089497852605 0.858096315672155 0.734706002352759 0.108064386725891 0.255917246942408 0.545826204472687 0.343409916656092 0.833757255792152 0.237559382491745 0.237988744035829 0.953586545418948 0.542130453085993 0.545786813467275 0.229142127260566 0.269854792275 0.32386631245492 0.806781140146777 0.760639285317156 0.199973247721791 0.746775799694005 0.380296514634974 0.544835331628565 0.85959150596289 0.135942517025396 0.686733829192817 0.869993852393236 0.992592914116103 0.018531971864868 0.950678281756118 0.788895106834825 0.98349303958239 0.66484060033923 0.931534600032028 0.0713666134956293 0.145657375482842 0.259378881715238 0.691189901528414 0.564155660201795 0.335484327289741 0.244346213785466 0.867070020372048 0.501598219769075 0.627620885453653 0.677591531856451 0.780619848419447 0.590261358914431 0.231652119534556 0.837894639975857 0.928466767207719 0.251836989074945 0.882969224958215 0.360761403292418 0.290900040832348 0.872943360069767 0.183202547682449 0.280942187733017 0.337129880709108 0.787539226855151 0.468215399766341 0.973314920293633 0.936731581792701 0.0146603820007294 0.273827050116379 0.757812213106081 0.780230820635334 0.901821196293458 0.0502738312073052 0.654108663226943 0.51351414204808 0.649117393738124 0.0450167789240368 0.0916847147699445 0.369217047996353 0.781537489057519 0.0639141179597937 0.478155597308651 0.101747289921623 0.448695387479383 0.40873213166371 0.22504994366318 0.82287961215945 0.261270342865027 0.917152752685361 0.227261120544281 0.0805503307189792 0.133940092280973 0.312822017937433 0.379419659310952 0.926026921635494 0.505049566992093 0.398143730200827 0.703830148589332 0.888876015846618 0.201198979858309 0.429661172928754 0.715169440689497 0.0397305528819561 0.913007782669738 0.550168931663502 0.134640524343122 0.0787985869473778 0.201988600189798 0.664787204472814 0.202901797434315 0.815079291593283 0.0643276792601682 0.962301868293434 0.119475651797839 0.836545316174161 0.635970398583449 0.12260046111187 0.676160275768489 0.617547641040292 0.282753286086954 0.519952187577728 0.506257664777804 0.428006023466587 0.725421308048535 0.167511704300996 0.346517020394094 0.58648165143095 0.375253498062957 0.0633126615267247 0.0494692275323905 0.352999916146509 0.918095287575852 0.899544090211857 0.369583915746771 0.950752889830619 0.835222040519584 0.325051301689818 0.3479743368458 0.584176173508167 0.293996029286645 0.409548342514317 0.105082514677197 0.244891380395275 0.429280681568198 0.791005051468965 0.597765922623221 0.023588054231368 0.758571750808042 0.0773283252539113 0.308471764384303 0.889271785132587 0.0531780292699114 0.964990584473126 0.220770042419899 0.868419864417519 0.0428467208938673 0.664110847918782 0.213894179367926 0.0642995625850745 0.400376750405412 0.898783406221773 0.793291598004289 0.663901697935071 0.605139887856785 0.838633777529467 0.0931456897547469 0.137096844839398 0.429474089164287 0.410798727106303 0.960894542958122 0.706567418011837 0.509231968051754 0.29212241431931 0.367436534767039 0.595225782487541 0.194020207000431 0.163457329771481 0.658223269169685 0.0572916585742496 0.749985086962115 0.595985431061126 0.576262231424917 0.653607735086698 0.486955826180056 0.0724516843468882 0.538912608879618 0.312250474253669 0.995064366168808 0.942042942040134 0.19735738595482 0.617759882751852 0.588059696939308 0.24849574820837 0.445881325972732 0.699812144101597 0.786669937078841 0.474063910904806 0.131563504617661 0.36225055972347 0.304077621803153 0.312231390504166 0.546586003103294 0.86363160548266 0.0118289286317304 0.883674529148266 0.934260928430594 0.952944551692344 0.773700455231592 0.755176015731413 0.424146967858542 0.135975540864747 0.305633538856637 0.890776829167735 0.959724011521321 0.137428105049767 0.349490969846956 0.136865792062599 0.976569341071881 0.460628002507146 0.481160109527409 0.786430251528509 0.691984207741916 0.387984488822985 0.499149857826997 0.303888372008223 0.753405743259937 0.586870608450845 0.545028840645682 0.515420814277604 0.227460105835926 0.739281108169816 0.606559878143016 0.824165277208667 0.847411539799068 0.546953895206097 0.403361794396769 0.71696412981255 0.920522679567803 0.22080520831747 0.442364741747733 0.0334396286960691 0.365273394342512 0.0285496790450998 0.955362869037781 0.29012669327436 0.260268789234106 0.167532649817877 0.690292966223788 0.969233502077404 0.485670949218329 0.0988231833721511 0.666413328850176 0.200960095995106 0.315945192528889 0.98622372839367 0.708881623214111 0.277642029528506 0.433134390674531 0.295722944268491 0.163221054964233 0.415464810812846 0.427167782124598 0.861663174531423 0.132965441730339 0.788759930583183 0.612463272348978 0.618167260366026 0.0868930656067096 0.0818549741781317 0.404720841939561 0.12089622594649 0.497831542582717 0.476054585331585 0.601099112734664 0.0891777623607777 0.749294100885745 0.650995774802286 0.737660863676574 0.643343708729371 0.333911256482825 0.63929676375119 0.434999557270203 0.337537858090363 0.872706699862611 0.847575908941217 0.420508606482763 0.163152466227766 0.27404965613503 0.727856311919168 0.864169804006815 0.34556223730091 0.497580098186154 0.298178543061949 0.216401583561674 0.832808037486393 0.319101556460373 0.129426171234809 0.0358225740748458 0.808271661151666 0.0354071332584135 0.965932062049396 0.0897640381404199 0.534452356153633 0.78693900591461 0.512168495450169 0.731055925004184 0.45088960976107 0.959563876476604 0.653544179138262 0.158156181008089 0.22464604294626 0.466572635655757 0.339847539223265 0.433280502187554 0.395285305983853 0.64995316225104 0.164644083501771 0.842441518707201 0.549098217880819 0.784067623778246 0.317704718289897 0.452704270989634 0.399527908030432 0.26966741830809 0.208883071464952 0.648628266165033 0.557782629469875 0.810715978699736 0.6364769092598 0.711449551789556 0.0149895344977267 0.393339342786931 0.139692099236418 0.348984700967558 0.738175937975757 0.439177298955619 0.670011918891687 0.235123949886765 0.667404640801251 0.609844410133082 0.12581991053652 0.890572014241479 0.954995846620295 0.162681668892037 0.462083539019804 0.797146124241408 0.542917108465917 0.441117437819485 0.288604004515801 0.184180962566752 0.753015722241253 0.58746515304083 0.36026296619093 0.0290430978802033 0.241808305373415 0.300911161408294 0.669882606850006 0.232124505031388 0.937050989342388 0.931603419501334 0.474588366879616 0.0318320837290958 0.999337802052032 0.39071141076507 0.187902600518428 0.202665495658293 0.432349895793013 0.750550071932375 0.136594690196216 0.598509381865151 0.327460096753202 0.0234630680270493 0.0864506502542645 0.806779511878267 0.919203182307538 0.661048900280148 0.374117896719836 0.764333911852445 0.0959763342910446 0.865629873808939 0.791741414235439 0.929872334501706 0.28425702617038 0.996435864064842 0.050697156356182 0.583248428339139 0.645866288966499 0.460828341539018 0.0595824078586884 0.661362165864557 0.113769061409403 0.0881244123191573 0.333462083262857 0.4098982635024 0.297992824562825 0.204600301620085 0.869375231142621 0.799881347494666 0.694247892824933 0.360176386516541 0.995807128832676 0.440779421816114 0.588901036463212 0.633227029377595 0.520808370991144 0.525628213125747 0.956897943378426 0.257353222335223 0.325808426032308 0.862447660192847 0.395613324870355 0.0674877466727048 0.67424016778823 0.52767579420004 0.171464253270533 0.640601085198578 0.932810117907356 0.291033650129102 0.168242610616144 0.748885970220435 0.679178949359339 0.204014513352886 0.512821606073994 0.912725351613481 0.840358509423677 0.0362310772319324 0.369321041661315 0.124560067511629 0.0471032489696518 0.956851241760887 0.790696439035237 0.83100769137498 0.660278234155849 0.0327841030992568 0.811062595436815 0.293110332353972 0.0956108670728281 0.406763792682905 0.882286949565169 0.972935394046363 0.653419189476408 0.820293082967401 0.809349547245074 0.216761960135773 0.845006799963303 0.926284053446725 0.410148310363293 0.84999513423536 0.863127071363851 0.304094341059681 0.141302288065199 0.338346044002101 0.0931372708873823 0.537663875606377 0.853904782570899 0.210192335804459 0.531723597338423 0.476040636943653 0.6520671918476 0.4634686824237 0.644402958478313 0.702585355753545 0.370192905918229 0.509039550232701 0.584869199760724 0.261822290853597 0.0545701264683157 0.316895288587548 0.622128033428453 0.671189556024037 0.329548301098403 0.108420705306344 0.646653469430748 0.109241112452 0.0532934922701679 0.758658239895012 0.770813078538049 0.845487719348166 0.189136209380813 0.0233031422784552 0.440962326112203 0.655775349561591 0.718351201829501 0.807961532243062 0.883589749466628 0.473016422998626 0.527032801476307 0.156020301172975 0.401992138675414 0.793338364623487 0.180112469077576 0.0222616619546898 0.880070130447857 0.310550381215289 0.414124178101774 0.462772119804285 0.351231337867212 0.204324318405706 0.746399438474327 0.54950094418833 0.326616222395096 0.13981323950924 0.162883591013961 0.556810721205547 0.531872008112259 0.773778552650474 0.666900520434137 0.869172269455157 0.995765813824255 0.228651415444911 0.141302287834696 0.227965066384058 0.441046621508431 0.994930717917159 0.371627203945536 0.997739719897509 0.374878904796205 0.494076339111198 0.317036615102552 0.771675706335809 0.403951737468597 0.349864730769768 0.991982758063823 0.258814959591255 0.603905227903742 0.17719919383293 0.0599863726552576 0.635910984992515 0.760481647765264 0.988679886616301 0.358443672556896 0.702132358038798 0.872403551486786 0.406480329898186 0.96315678924555 0.855152607664932 0.487882745689712 0.872073987082113 0.151379423588514 0.752446660837159 0.218003444571514 0.330082808127627 0.685955930827186 0.417175006999169 0.233998374473304 0.751920404869597 0.873074542637914 0.995399671003688 0.829016819407698 0.664523421516642 0.0624403528613038 0.21700979440473 0.721052028832492 0.788955409703776 0.97847844371805 0.363931297711097 0.516320234166924 0.0778377739130519 0.657746818303131 0.529974373879377 0.62603717765538 0.490869029553141 0.113265997665003 0.275884078559466 0.778430341985077 0.564011325170286 0.656564276772551 0.502013985363301 0.873467850850429 0.86162898573326 0.789853999784682 0.346053352495655 0.279162253525574 0.679136610920541 0.743865699388553 0.181752725092229 0.229910655475687 0.309596435767598 0.237757398751564 0.527190249555279 0.0583939239778556 0.714291320368648 0.0146310109319165 0.435434909800533 0.628136566895992 0.701859085301403 0.0796265909890644 0.467733472394757 0.290078851361759 0.213762061882298 0.618546320307069 0.154119126885198 0.175933904498816 0.983125686624553 0.136460012290627 0.838367004496977 0.670719900366385 0.947156407041475 0.677584693774115 0.739000468116719 0.0803277975390665 0.086515805888921 0.436561855319887 0.860215482474305 0.1276923859003 0.116309107039124 0.977061843429692 0.0144307652534917 0.320097367125563 0.309736291447189 0.754325422691181 0.217256668170448 0.552592825551983 0.393682414628565 0.295707984205801 0.175941960094497 0.645330622510519 0.99462003234541 0.724730618628673 0.137583488288801 0.0617680868017487 0.387703434557188 0.971263028364629 0.809460723593365 0.349403490521945 0.353011069232598 0.16927278595278 0.106687653430272 0.227090073288418 0.576689107231796 0.719175961089786 0.499889138522558 0.148638418645132 0.591329169059172 0.813558988994919 0.540138063030317 0.544693148566876 0.699223797488958 0.822011478813365 0.83884941108292 0.403231962572318 0.425438225124963 0.826462340874132 0.576043499459047 0.629886775522027 0.808647871853318 0.681905031581409 0.849107966006268 0.577451506850775 0.59411838425789 0.0674025917332619 0.862531690972391 0.148049730889034 0.811784257455729 0.929309241264127 0.951077947453596 0.107347137443721 0.822211804937106 0.76091798315756 0.672993230128195 0.738823122614995 0.315390300333966 0.888048869504128 0.977378529668786 0.181124492355157 0.698805625219829 0.240959867760539 0.019850439010188 0.728074556833599 0.169528952881228 0.0106689599645324 0.924703295617364 0.614511811621487 0.528855990138836 0.999411342900712 0.262668351065367 0.722396452154499 0.394494882582221 0.636170284678228 0.625777165256441 0.304469397866633 0.2384038040624 0.477477244373877 0.492802130489144 0.327366965971887 0.202760157666635 0.270151110175066 0.995914703351445 0.511287639066577 0.225496104448102 0.208176385643892 0.323372342258226 0.303182530978229 0.975960519397631 0.545422379130032 0.646982785584405 0.931841784964781 0.489069511636626 0.4242815736169 0.0765700470167212 0.293387540227268 0.160042167496867 0.236860122994985 0.595349972306285 0.742588262350764 0.738699329721276 0.629223519337829 0.329857758784201 0.788786290599965 0.779029300925322 0.134712318906095 0.726417752825655 0.0657810126314871 0.952814703041222 0.878074791575782 0.27752422623802 0.557129977545701 0.866350373865571 0.887358972781803 0.142099785814062 0.956157152892556 0.0969737061485648 0.362068332643248 0.639280076073483 0.213950169999152 0.789349605580792 0.142757550049573 0.456676300172694 0.528783994808327 0.408489475399256 0.548791997830849 0.13263987792423 0.767801268845797 0.40131685096072 0.0648873668257147 0.0248290854995139 0.656557301310822 0.212132640860509 0.884733996030409 0.644539341179188 0.430206324786413 0.813616201288533 0.554797681828495 0.708264447904658 0.593054194152355 0.123393453462049 0.113316599382088 0.566124369369354 0.577282665963285 0.498893185637426 0.661752600404434 0.454886916982941 0.142955642144661 0.112162187204231 0.97570762444986 0.274172830821481 0.510375219075941 0.903343747442123 0.667611088375561 0.96160891026957 0.0763702646479942 0.871253830031492 0.0959154249704443 0.673472038803156 0.113359400900081 0.724321713706013 0.193117248208728 0.764933499833569 0.71004960114602 0.0380513392062858 0.181065738692414 0.450026816693135 0.545109408588614 0.931988664972596 0.980625642600935 0.804332206097897 0.63372626908822 0.267565414248966 0.37978886942612 0.182662909210194 0.678421596128028 0.643963440309744 0.54500049139373 0.0243344851094298 0.466290894723497 0.759797857049853 0.235838315815199 0.762354391433764 0.344382065334357 0.392121385494247 0.372179455505684 0.0929760893620551 0.084254637430422 0.617820322769694 0.942305994534399 0.664559976882301 0.0508508066786453 0.273628434089478 0.169076418706682 0.234067958749365 0.792056134520099 0.213036386356689 0.729810149536934 0.375070230725687 0.137480853204615 0.272103444226086 0.594374486415181 0.595435070772655 0.938562188481446 0.156502950247377 0.674108669201378 0.0642020257515833 0.0549569960590452 0.852851609094068 0.115990739746485 0.112001460460015 0.5099184348993 0.809330165686551 0.867835971110035 0.838995013646781 0.943908645245247 0.841103626207914 0.755324007913005 0.289688449783716 0.734171847761609 0.111937838818412 0.370209947417025 0.201677181851119 0.252026421658229 0.585444031560328 0.743575486342888 0.788544125074986 0.347122548881453 0.445007201409899 0.258387072109617 0.900942948274314 0.0711790816346183 0.415769657529891 0.552812980639283 0.585043424721807 0.577408265764825 0.375947573101148 0.727440129807219 0.777245907569304 0.351548205742147 0.47096887327265 0.376713482118212 0.0798800753313117 0.989541101204231 0.765863950869534 0.927860831192229 0.891854100280907 0.0639846456819214 0.946778855277225 0.48480761239538 0.355037323308643 0.838855017360766 0.248437833804637 0.288338657140266 0.202600917662494 0.822923707487062 0.897600408066064 0.109181407506112 0.19632827046793 0.733579316840041 0.449266479378566 0.0336849486455321 0.253496994760353 0.14870399056701 0.342074846427422 0.262543158330955 0.0347035891842097 0.884043115754612 0.426956367916428 0.0694879177957773 0.647579046033788 0.821464438680559 0.293576208695304 0.796182496082038 0.322300334896427 0.771887043095194 0.498558142422698 0.343219348848797 0.92884785464732 0.646050035287626 0.826136577683501 0.0397218103893101 0.583025784748606 0.919388559893705 0.059538350563962 0.742598048557993 0.429740488091484 0.638237128371838 0.0697340415068902 0.132751042055897 0.0596149075357243 0.621271281826775 0.334016887866892 0.288333942214958 0.564300870450679 0.0272024140902795 0.560092154552694 0.613618597085588 0.0918893863237463 0.247585387756117 0.520386371230707 0.287182091840077 0.665731995981187 0.434782847962342 0.738157953952905 0.838491548828315 0.858634866403881 0.93250817252323 0.434651766815223 0.54261101588374 0.414959449651651 0.527637691472191 0.805439018851612 0.727330493906047 0.620546577638015 0.550474926282186 0.696406096580904 0.881094357441179 0.132760363800917 0.396075594311114 0.609770977620501 0.131164228469133 0.115411006545182 0.925758715569973 0.398976801375393 0.275530489587691 0.699936271454208 0.50074930985691 0.232038263042923 0.36266993429279 0.397348941776436 0.0880907412292436 0.313220817407127 0.808687359208707 0.73679700960638 0.166165402615443 0.534254940813407 0.306786186539102 0.781868482115678 0.450127617209218 0.16963313993765 0.578561474489979 0.146536872594152 0.688325753016397 0.0700725376466289 0.441254760739394 0.129543501765002 0.531196904338431 0.322903393320739 0.489271553389262 0.334237772955094 0.941514797797427 0.835382710790727 0.0631287015299313 0.513375913023483 0.731730521211866 0.862725593918003 0.38442674978869 0.226659145480953 0.523456887793727 0.0739217448118143 0.0947834962210618 0.931617723784875 0.101953543182462 0.0256359849777073 0.864840368959121 0.761878130040131 0.804321633877698 0.483880410059355 0.3351681195735 0.0543794060684741 0.146303113489412 0.964948412687518 0.106738106242847 0.0910812935349531 0.149062665342353 0.476515568569303 0.670823803904932 0.360566235580482 0.932447930276394 0.738849444137886 0.116260397054721 0.730709612530191 0.972357088576537 0.299871343236882 0.344165439007338 0.611998131771106 0.288630872329231 0.0838516209204681 0.9455945241265 0.453800846904051 0.400667199715972 0.597480765646324 0.399549386007711 0.569392754440196 0.208057818929665 0.574581652483903 0.444027803894132 0.91279053905746 0.870328190962318 0.172006383934058 0.936873986828141 0.277232596755493 0.71786052205367 0.102524384756107 0.631342428438365 0.726829123201314 0.853775942136999 0.454500933443196 0.430578618100844 0.554223535081837 0.27317285820609 0.385396589525044 0.810875018166844 0.460329879082274 0.0922123862523585 0.35846864817664 0.465377953336574 0.329017304389272 0.81742115569301 0.709916235951241 0.874711922674905 0.166399465752766 0.0396488082245924 0.178150917929597 0.833037103102542 0.0277900993917137 0.285384723588359 0.988898974477779 0.158827379150316 0.857354171676561 0.996446203708183 0.0580324552836828 0.120977135032881 0.519871423938312 0.0777222037292086 0.378490065743681 0.602368069130462 0.940410211235285 0.643634574788157 0.888079690202139 0.0597352972929366 0.333369293163996 0.615281541906297 0.738722016913816 0.278589000205975 0.890639714160934 0.388769192539621 0.948963346441742 0.495761841351632 0.494051593532786 0.356486975557636 0.925959769620094 0.192093151910231 0.270186016296502 0.840438060390297 0.553364043268375 0.177290536838118 0.0803941570874303 0.426547531452961 0.636372998806182 0.588402074277401 0.654998247120529 0.999318046849221 0.707888380114455 0.0895572713203728 0.45856779151829 0.136709177019075 0.703534420083743 0.42503884202335 0.682466569619719 0.973178266291507 0.901933155427687 0.123508930983953 0.0734093381161801 0.0679272314184345 0.199697033544071 0.425217724053655 0.571296755378135 0.195334974122234 0.106921628285199 0.968797403411008 0.514929376379587 0.717720755347982 0.359739695459139 0.967593413407449 0.120400815571193 0.974570260455366 0.19124307473423 0.29629843046423 0.393861525547691 0.142814110021573 0.635537242970895 0.610241856554057 0.769900841105264 0.405994418293703 0.696768404534087 0.134644989173394 0.39318415224785 0.549520936578047 0.164215755069163 0.905943546653725 0.316600976518821 0.371604266888462 0.581326321673114 0.0334332069009542 0.351690860872623 0.684870961166453 0.611061896048486 0.30870650450699 0.0692006413498893 0.665497481981292 0.791711059382651 0.316514483743813 0.690914903020021 0.463616329773795 0.436451547043398 0.864062559797894 0.825187061568722 0.105566028365865 0.878372639319859 0.916396856920328 0.432887197432574 0.820853605642915 0.372018418505322 0.387613983976189 0.713813137968537 0.796545809025411 0.074384377063252 0.914792105411179 0.879296889381949 0.57329644751735 0.0165558313019574 0.100988135314547 0.940146096355747 0.628717528905254 0.462232504843269 0.984132432551123 0.282123802644201 0.659177916957997 0.0849116398557089 0.333978190673515 0.891531875762157 0.522960867970251 0.322426992473193 0.733852345475461 0.0254007624136284 0.762201343874913 0.47747621310642 0.417192933396436 0.214677392656449 0.124610120402649 0.433580941699911 0.25213213925017 0.3560725106881 0.696801050810609 0.358804367685225 0.7494810650195 0.16022600509692 0.0415957646560855 0.789247067999095 0.595559889171273 0.302995167614426 0.70833969908068 0.331976212642621 0.494858895237558 0.500316085785162 0.0343454708415084 0.885364888303448 0.958227213476785 0.284163900921121 0.154947499500122 0.340798993632197 0.72910039319424 0.112912758134771 0.995582524819765 0.556993519931566 0.78802910263883 0.582706702437717 0.228757680710405 0.0788094111066312 0.919591475480702 0.224382085038815 0.111831706322264 0.725549331351649 0.448400772761088 0.378543844243977 0.371597736757249 0.576782060526311 0.683477598971222 0.931082126940601 0.0969015563814901 0.942480925985146 0.317542264391668 0.0619594463845715 0.430379528161138 0.0256040173000656 0.337074834215455 0.946292014517821 0.344605269045569 0.87024760665372 0.505519865520764 0.381983110839501 0.180300152378622 0.479473419047426 0.768036748419981 0.739071056691464 0.926813661148772 0.963150863721967 0.83827688154066 0.600747300474904 0.304470449648797 0.928939397498034 0.874850821539294 0.908941944106482 0.0166758875222877 0.874684909645002 0.646132639718708 0.626443900642917 0.742815207345411 0.270222040815279 0.277896134613548 0.207083050592337 0.114558249088004 0.659457947793417 0.34264922989998 0.574431966340635 0.735648798632901 0.109841664163396 0.0656164819072001 0.641998955789022 0.0381530746398494 0.366266036292072 0.0812910739518702 0.604672308103181 0.549182603172958 0.749948455530684 0.234603994931094 0.79934395757271 0.846595579965506 0.485152167750057 0.943915046295151 0.177838062639348 0.985697585372254 0.760215323751327 0.797866222762968 0.244117598109879 0.753467418770306 0.398656463518273 0.661685717385262 0.219919435319025 0.72878672423074 0.863356840934139 0.956355974527542 0.179527850840241 0.663056952739134 0.0364794326666743 0.429872380145825 0.257726928167976 0.0168334547709674 0.11662958458066 0.923642353750765 0.605977656668983 0.894101708747912 0.328392596954945 0.50018153580837 0.190964021920227 0.370129009056836 0.495429456289858 0.626013046365697 0.94145420242101 0.687077792156488 0.546470699841157 0.569315873843152 0.0572782938182354 0.673015050631948 0.707363915380556 0.0204418005933985 0.961807505320758 0.559731396266725 0.255882779927924 0.721747105864342 0.496480618864298 0.777807113453746 0.382372758213896 0.79922107885126 0.786750001374167 0.605415750748943 0.32185528513277 0.833102999341208 0.419248637142591 0.988070649807341 0.94503799905302 0.310801508901641 0.436951745182741 0.738106464110315 0.764649996941444 0.919102814905345 0.505360538156237 0.677570574814454 0.606966608276125 0.787465321812779 0.113648753250018 0.451600267367903 0.596091905622743 0.766755724996328 0.199597449619323 0.379105107292999 0.352155388314277 0.179259959871415 0.053960927692242 0.831120846816339 0.252317706078757 0.3885733063519 0.441055119207595 0.104788848476019 0.595379191243555 0.651727887566667 0.940815652629826 0.570948194123339 0.445131892340723 0.0304999590897933 0.261678415443748 0.979366133804433 0.278035922525451 0.0135858538653702 0.29776938873576 0.90741459620418 0.27217577931704 0.92317071946105 0.114097766501363 0.476301246343646 0.50720130561851 0.436951969692018 0.74888883467298 0.955359827328939 0.347164357164875 0.128252527094446 0.569404486087151 0.747695753423031 0.280419946655165 0.994655603696592 0.419596990714781 0.198243260604795 0.394149573945906 0.724880694090389 0.269848191149067 0.0191351980948821 0.685886892380659 0.278934176303446 0.187621864576358 0.96473374125082 0.927374615555163 0.469930516255554 0.0633541484898888 0.930717714040075 0.292488022604957 0.224276208630763 0.270123398953583 0.967924598704558 0.405989132875111 0.198519764293451 0.928626680048183 0.98997403438203 0.0146588574582711 0.894769137946423 0.498606243419927 0.248180510676466 0.596315211676993 0.0852499290043488 0.909696346907876 0.529778275629506 0.754211637517437 0.0319712958461605 0.254844677846413 0.626453963683452 0.456647511583287 0.0213739458215423 0.88486461870838 0.28708691050997 0.443747378438711 0.13829356756527 0.286809803135693 0.713634803842288 0.883756335810758 0.981765824717004 0.694251754661091 0.599349875445478 0.698533247292507 0.577374367399607 0.399901748937555 0.715623224647716 0.304889158296864 0.409628608960193 0.205826792339794 0.933249400733039 0.885635001545306 0.649554002967197 0.408042905242182 0.441399555392563 0.874156090952456 0.612893755747937 0.621445750659332 0.211250885978807 0.612825657289941 0.906894444169011 0.31144910890609 0.575840931700077 0.889086316959001 0.518189021262806 0.455415132911876 0.0548289384110831 0.407733760578558 0.681234717415646 0.0567322731972672 0.955121989024337 0.505766900638118 0.0771821192349307 0.271995169210713 0.667497596170288 0.847358672013506 0.0653044356801547 0.236362078899983 0.862049315965269 0.594830145048909 0.922192010686267 0.639540709676221 0.114619367935229 0.815343607009854 0.25745728953043 0.200475462065078 0.126553708733991 0.487760707610287 0.579560591711197 0.379403092877474 0.446794726520311 0.787661814913154 0.524582113074139 0.727673952069599 0.0357156869140454 0.598467520335689 0.857426429779734 0.532003415420186 0.832854068342131 0.367989519324619 0.942291277651675 0.534770740503445 0.336410489138216 0.58442344028037 0.466743856710382 0.775455101719126 0.930390425615478 0.642344042912591 0.528123982714023 0.499577716956846 0.276074683708139 0.355269463134464 0.161709296396002 0.489566376942676 0.448916147174314 0.755201580745634 0.75950672499137 0.504904241953045 0.370458187139593 0.364402223897632 0.859157548202202 0.822507883806247 0.273017969855573 0.4892647916032 0.882564749137964 0.406377523089759 0.461387091882061 0.633534447809216 0.945582171736751 0.150099295896944 0.853412045561708 0.134500958635472 0.289117510246579 0.428822766547091 0.544948804932646 0.0649000921682455 0.307332492982969 0.872063765225466 0.766515690234955 0.173513420431409 0.0490530758467503 0.183183970346581 0.391385505860671 0.110435190163553 0.923260065393988 0.251020971846301 0.303502477211878 0.827058365519624 0.371849106240552 0.274443450476974 0.0531338991364464 0.618047047634609 0.169209491163492 0.448093296703883 0.686496884315275 0.532582499065902 0.826031034812331 0.214257729037199 0.994033648690674 0.994691696905065 0.387090825499035 0.553122460453305 0.53717758390354 0.291127751325257 0.328534434954636 0.788724168606568 0.146231563258916 0.713424091283232 0.858451714087278 0.639692314520944 0.808300059039611 0.223154104121495 0.573422440094873 0.352574764958117 0.25394698649412 0.14610736237606 0.524725144845434 0.823100610424299 0.737926581699867 0.458591662570834 0.900465481814463 0.806648252091836 0.774731402290054 0.954765302562155 0.43740143426694 0.107148615231272 0.283828599313274 0.188604344369378 0.048911872189492 0.441260225719307 0.125419263590593 0.50113673173124 0.953602150888182 0.134881055145524 0.949492461099289 0.69087914634496 0.387675096599851 0.593515520608053 0.347367308018729 0.441046662307344 0.290887991553172 0.578918580235913 0.940347382060718 0.115692359081004 0.572935476247221 0.526810215511359 0.12697427661391 0.520200581736863 0.132433822203893 0.231631062454544 0.383920527701266 0.267405823881272 0.415826831099112 0.904231123584323 0.946940385091584 0.0471615709015168 0.34835584633518 0.223290361429099 0.0296703286236152 0.846896080560982 0.795854689257685 0.796863301331177 0.714770258816425 0.803001812070142 0.0380113106314093 0.757457497669384 0.793002403548453 0.728945438920055 0.828823559563607 0.244209626629017 0.628131568452809 0.517045189603232 0.194306497587822 0.968427044241689 0.389369253511541 0.919862460712902 0.310210001871455 0.375683639396448 0.678627800061367 0.740077311878558 0.508290568385273 0.430604199711233 0.0357028486253694 0.142295487138908 0.931154863566626 0.333437963728793 0.183768977902364 0.195218416466378 0.671333327477332 0.645047777702566 0.802045861713123 0.521777149033733 0.186443722874392 0.543304765913636 0.211664506057277 0.744531606580131 0.448769890214317 0.953495718508493 0.704351219406817 0.678774336390197 0.681338361178059 0.667822566663381 0.527068296300713 0.625989527981728 0.0660315714380704 0.114805121931713 0.148478864235804 0.486778033734299 0.982695898651145 0.732760545569472 0.387443853428122 0.149349526192527 0.163984755538404 0.681226313069928 0.387941654343158 0.978733448453713 0.435782557574566 0.178187931303401 0.332872992588673 0.774188308126759 0.270901506615337 0.862586383414455 0.207647421965376 0.885310959054623 0.122914101723582 0.482433209663723 0.328990977564827 0.461952652186155 0.20146680029342 0.951992466398515 0.899127767032478 0.129496106104925 0.922989730869886 0.565508535814006 0.813172397390008 0.621074094914366 0.188223259234801 0.953461024679709 0.57696350320708 0.819406987265684 0.572934157312848 0.493336066103075 0.393018273315392 0.829072721065022 0.784185860182624 0.336444058115594 0.070852854673285 0.094008063999936 0.598369457726367 0.263822656520642 0.0569875335600227 0.504813593681902 0.263320479518734 0.792368424849119 0.394077352492604 0.59827597865602 0.852728578241076 0.96582076883642 0.68748648225097 0.118127624802291 0.305939453030005 0.957010937468149 0.282123257045168 0.416891946441028 0.887281897410285 0.504187876186334 0.70055895277299 0.756168664135039 0.235351312321145 0.371449174773879 0.616940229118336 0.0448489623889327 0.0215262995683588 0.857395958984271 0.215844950152095 0.743308859679382 0.422147796654608 0.796867688943166 0.763064653037582 0.623932705838233 0.0991393067245372 0.370057295861188 0.686311030050274 0.18227529855445 0.615917494397145 0.512362067624927 0.232917494385038 0.401710965700913 0.399142242583912 0.210811338305939 0.218286062565166 0.3316390299052 0.761654348229058 0.591087464538869 0.629123959385324 0.583527672700584 0.127026644439902 0.665074499589391 0.906168985546101 0.139207098577172 0.651050385646522 0.21246115763206 0.66571292767534 0.696557735539973 0.580455132557545 0.125463902442716 0.901462471268605 0.717833527924959 0.060326589725446 0.131667217761278 0.88054745998932 0.687644897056743 0.92123076453805 0.134010888538323 0.956119144670665 0.357178511382081 0.389252101390157 0.0807420415873639 0.133149280482903 0.243562338724732 0.896387014489155 0.417147088325582 0.42312203967711 0.460315039111301 0.578880865443498 0.580844981621485 0.899114371619653 0.303482928308658 0.0558073804946616 0.60211774220923 0.344202533287462 0.892898625079542 0.204832866031211 0.521735644782893 0.694258392206393 0.185236559775658 0.111917312585283 0.540429573573638 0.535117873104755 0.402619278600905 0.626532435899135 0.899564222746994 0.336919095311314 0.901801410664339 0.734981487682089 0.119258105996996 0.705557065415196 0.987786071621813 0.993750536961015 0.316081998201553 0.348653053513262 0.308729056394659 0.105865168075543 0.788440200560726 0.381431957161985 0.404992668505292 0.925107388573233 0.197693924668711 0.355530921705067 0.668732286549639 0.0370659580803476 0.643264716269914 0.443044659793377 0.66900118296966 0.248018098960165 0.18595217802329 0.246621902738698 0.887989436320495 0.173804984220769 0.880108572244644 0.308381885068957 0.14030626349384 0.257711900568102 0.371515046579298 0.346399640997406 0.887068199384958 0.799685808212962 0.944099998374004 0.264268995483872 0.323760230208281 0.751643454006407 0.154610476731323 0.780368813164532 0.410525866737589 0.174420539329294 0.282006993279792 0.868503856703173 0.106309193486813 0.135725884705316 0.498713097157888 0.954322070770431 0.123629376522731 0.612314419010654 0.82440061848145 0.935274637371767 0.406669041931164 0.0358693330874667 0.0605619187816046 0.242994023456704 0.944318276711274 0.415966092774179 0.36271072168136 0.160329260693397 0.750427137890365 0.486026137645822 0.82490185180679 0.748481166395359 0.426046688829083 0.1569475429249 0.486735228528269 0.970985511157196 0.163376729788724 0.846108228643425 0.768356740523595 0.633039002858568 0.0202422337443568 0.938167230794206 0.951204511446413 0.156814103508368 0.747934114045929 0.268825850817375 0.414914439690765 0.956703494142275 0.208611733333673 0.980862443414517 0.103123638508841 0.112583908287343 0.122422970624175 0.946587374911178 0.97148599834647 0.265714457661379 0.384138367623091 0.508432548835408 0.318380591941532 0.873758071502671 0.367044746256433 0.827853248680476 0.0446114348014817 0.716810307074338 0.571225433575455 0.662171484464779 0.854640399201307 0.851454373076558 0.876025632943492 0.349993609467056 0.493765091805253 0.605313498298638 0.951595005686395 0.964614161939826 0.719420459067915 0.123703430469614 0.371136941378936 0.726067010788247 0.683844399414957 0.949649307106156 0.496353640658781 0.349657166411635 0.810941924927756 0.0350315603567287 0.568469153933693 0.154252514669206 0.203145821730141 0.51688549481798 0.456666405859869 0.159320928449742 0.0113613647827879 0.577221624564845 0.229725717226975 0.959053737232462 0.954818506189622 0.516481897442136 0.641142742871307 0.731563187348656 0.137732546543702 0.26993004022399 0.234662980248686 0.578665106727276 0.715226055521052 0.640447270297445 0.732133362079039 0.823143656735774 0.819145639797207 0.402365861795843 0.378028148510493 0.643536757894326 0.519584362781607 0.469058671360835 0.263343813039828 0.586196973207407 0.0152901134639978 0.227345319821034 0.225831906015519 0.145871923831291 0.559003096241504 0.770306798594538 0.409298562575132 0.582799377976917 0.914701333129779 0.88110629077768 0.101605383693241 0.976834440196399 0.809163387103472 0.345029099916574 0.390537270167843 0.653738253577612 0.222419154103845 0.835537114855833 0.520480825556442 0.938421952934004 0.387439412800595 0.728456447343342 0.149818299487233 0.969243269152939 0.72976715070894 0.760043078113813 0.0704632215900347 0.328632304172497 0.485157970415894 0.444989221075084 0.440050899356138 0.611005310490727 0.535197277702391 0.377673792887945 0.0538288274942897 0.655555297739338 0.986439739048947 0.135822347397916 0.833011097598355 0.257442436651327 0.17597022959264 0.842655165100004 0.443052594605833 0.840196550413966 0.688048545143101 0.582278953718487 0.446392023263034 0.376512239056174 0.261167560259346 0.021615823910106 0.143654418969527 0.526753407288343 0.606635689439718 0.882504941618536 0.884559408489149 0.448248745405581 0.802552630321588 0.679957863548771 0.433540010016877 0.158787311390042 0.799894760886673 0.439847221958917 0.625482626603916 0.555094609407242 0.904047306498978 0.559757246873341 0.210958809782751 0.694759982810356 0.739927556815091 0.205161411385052 0.764571940090973 0.260113831041381 0.883153726404998 0.916332001630217 0.149425791117828 0.213917048887815 0.404114131436218 0.917550936022308 0.811777235432528 0.193562232509721 0.635138793634251 0.711880275832955 0.0961928135575727 0.781479543996975 0.321454692585394 0.0184646801650524 0.357993539986201 0.239115574995521 0.635561533076689 0.82629141993355 0.130001961463131 0.462041047757957 0.386974909331184 0.462396691427566 0.226567775967997 0.723471048749052 0.164236831972376 0.0453938846662641 0.791308417438995 0.462070967652835 0.369773355475627 0.670892887529917 0.153596075591631 0.0696011725836433 0.933516097699758 0.840013650958426 0.62817814606009 0.231457540295087 0.432943965317681 0.0311955171800219 0.264075518506579 0.708731252248399 0.805407272225712 0.463641963477712 0.447253794283606 0.612221857109107 0.414583672063891 0.267601900002919 0.510493030895013 0.036763097140938 0.26611307434272 0.0821279110736214 0.612224212842993 0.939243648357224 0.243695751863997 0.878288679765537 0.929497983031906 0.526354420420248 0.239119211630896 0.0737847674149088 0.171253088465892 0.162639153196942 0.177781225834042 0.638976725316606 0.871247575811576 0.941570364304353 0.884519301312976 0.171558148628101 0.596805089535192 0.137092931601219 0.519454067877959 0.631674514077604 0.912880309806205 0.581784931889269 0.64032299450133 0.494185663603712 0.126480167654809 0.382252261964604 0.0728955228207633 0.900902673983946 0.188258715334814 0.968280202497263 0.657646157701965 0.402852617499884 0.729939273027703 0.19115154317813 0.686675582174212 0.361409803600982 0.486182456493843 0.552726720902137 0.902905570566654 0.603739210669883 0.550454746724572 0.152201960575767 0.906961579818744 0.0515580291091464 0.994654486682266 0.235085067139007 0.596269200413953 0.527817735234275 0.243372997881379 0.325500498421025 0.263736989635509 0.255251635024324 0.573252799825277 0.981472593243234 0.270108142464887 0.0305011809826829 0.559920160162728 0.93341561343288 0.82562990519451 0.995463106860407 0.3245117063215 0.767761900429614 0.62582892916631 0.0700429134862497 0.366252630967647 0.589975052883383 0.283582093429286 0.229100310679059 0.0535794709878974 0.0934300941415131 0.37243644279195 0.994489542667288 0.658499654380139 0.290883737171534 0.672893810782116 0.283441266182344 0.814482793265488 0.25147525184555 0.969421202205122 0.759538121714722 0.293398030849639 0.33902131742565 0.139837167495862 0.56780166342156 0.0751443402725272 0.596982522627804 0.49586172608193 0.543070128825493 0.0963519094977528 0.880905377794988 0.552365462426096 0.969155542268418 0.21002294286387 0.81001559619559 0.0101299030496739 0.505555904330686 0.988400350669399 0.0981340936385095 0.0493660376290791 0.169090594369918 0.432147289079148 0.253081966543104 0.866472506450955 0.261713556677569 0.980986259588972 0.740014709057286 0.951044176325668 0.121751608825289 0.741774246804416 0.647678143598605 0.342050655668136 0.392768051503226 0.466455766130239 0.424350660007913 0.832564346266445 0.831819599899463 0.988633298866916 0.693259153971449 0.686158318333328 0.755129562825896 0.605045407023281 0.246925808084197 0.71166909489315 0.687054506810382 0.220016323057935 0.59790002657799 0.697779157974292 0.153549519651569 0.312016332054045 0.870220744141843 0.77478824601043 0.995050986430142 0.0513018679432571 0.813742134857457 0.828650556034409 0.425731237160508 0.956213853009976 0.604389299177565 0.939070290545933 0.989066545988899 0.548411888412666 0.0272153796162456 0.617125783269294 0.21780320788268 0.893909771065228 0.297198810165282 0.475142506484408 0.462286287031602 0.491342425341718 0.729901378212962 0.850014842876699 0.191843621144071 0.488412767834961 0.882650904688053 0.564212511528749 0.494530540970154 0.144541242828127 0.966442805440165 0.745092436054256 0.0341004639142193 0.535993692320772 0.847171899196692 0.136626409161836 0.450669094168115 0.712965792475734 0.980215031269472 0.815332564334385 0.728888296238147 0.470092977299355 0.606604255374987 0.950793135999702 0.892392405988649 0.361073734650854 0.930028510899283 0.498577270198148 0.496315088681877 0.466211985014379 0.7376699000597 0.409508569105528 0.179217190393247 0.45130524558248 0.135639171339571 0.209201594346669 0.692413912273478 0.536403455864638 0.495557810133323 0.504235364738852 0.718636438329704 0.815372835628223 0.854602923670318 0.815079458015971 0.655333603357431 0.538671653952915 0.425943605187349 0.0241811074712314 0.847874070168473 0.182583729582839 0.355608849704731 0.628477752537001 0.513625726385508 0.904864650038071 0.330441623278894 0.729829804010224 0.42094239251921 0.511930965327192 0.431225437163375 0.200484384810552 0.0592884904099628 0.646737009009812 0.991643972413149 0.844752361110877 0.382934754721355 0.470424662556034 0.346545173949562 0.70162357530091 0.35604919537669 0.290156861420255 0.139366365319584 0.258570663072169 0.0550267813331448 0.414251252657268 0.105415510800667 0.0778539369674399 0.267235550191253 0.534210449713282 0.0508607337228023 0.367814348381944 0.528245091638528 0.0724941477179527 0.856893217943143 0.971914853246417 0.281995767354965 0.0198844530875795 0.181567425876856 0.971544855965767 0.368892520528752 0.871685413848609 0.518297739073168 0.665418139619287 0.0530027852579951 0.0559077933058143 0.62521858871216 0.764622171390802 0.223771529756486 0.438464819458313 0.0780187569721602 0.566886205640622 0.32950356958434 0.922260516441893 0.782706218196545 0.929435210330412 0.958258800134063 0.980616639410146 0.433749496303499 0.0949860909488052 0.427162786447443 0.369345204299316 0.392337678053882 0.71757067527622 0.915579523984343 0.0758251860900782 0.974245426419657 0.783150826778728 0.0343913327390328 0.0717774680070579 0.294626504580956 0.0536832108697854 0.693336802141275 0.257248226676602 0.634677893377375 0.294747278585564 0.749688551928848 0.256714512114413 0.112663033516146 0.194942307397723 0.229305962789804 0.275364881034475 0.477111089797691 0.0527160366624594 0.210306079487782 0.587632226666901 0.217055973012466 0.455813224508893 0.441599606066011 0.741510483671445 0.122529109113384 0.430450823686551 0.745741833746433 0.472618155528326 0.608030152283609 0.862175047383644 0.394754778807983 0.513796562040225 0.85912624921184 0.313025444317609 0.307341134054586 0.978948981047142 0.539760492825881 0.875051342437509 0.615536465044133 0.498933717168402 0.666238392328378 0.378884244794026 0.628736531056929 0.566425726050511 0.596357038170099 0.636302168664988 0.611671125942375 0.561721260938793 0.149131745509803 0.603111825720407 0.652264851520304 0.700606454925146 0.946349587547593 0.917445556807797 0.261308381513227 0.627611161251552 0.386290724226274 0.960625439085998 0.383185090171173 0.724930508180987 0.399550942820497 0.649298966883216 0.0558431544573978 0.124676782139577 0.837305882147048 0.193616427297238 0.107452096682973 0.464848611403722 0.679509743263479 0.345432885382324 0.650085649692919 0.622478890486527 0.405644405335188 0.5070495048468 0.192594616890419 0.60018653715495 0.497200596141629 0.709709905011114 0.994868171799462 0.425611277751159 0.204284238198306 0.843202573806047 0.835026738194283 0.720151399497408 0.55396478030365 0.528610276260879 0.821103189885616 0.957151247698348 0.188933108700439 0.524233659463935 0.634151222736109 0.943587065441534 0.482995532331988 0.69084276546957 0.191142444559373 0.476548999936786 0.496439467743039 0.394291290240362 0.387353274538182 0.975855297616217 0.875802030463237 0.195857907398604 0.986699795704335 0.925097285886295 0.67546340404544 0.744983217592817 0.826729036918841 0.146427824243438 0.709243774656206 0.263083743476309 0.590791066654492 0.88356768785743 0.305429282898549 0.553273522695526 0.153441227118019 0.75805842717411 0.0230145399831235 0.0418622338864952 0.765603192104027 0.682256063590758 0.504954995801672 0.486770112060476 0.603366206255741 0.964558919288684 0.0641383188241161 0.909431911399588 0.0742984799062833 0.719618793190457 0.436679618272465 0.468677771319635 0.631071895451751 0.872104890069459 0.397910620882176 0.53330359243555 0.613788643961307 0.618415019952226 0.118313140228856 0.620043953922577 0.220423902361654 0.749561247101519 0.691680819182657 0.544287108327262 0.610389495606068 0.426569292256609 0.535732194795273 0.32573986472562 0.289470294765197 0.633797454203013 0.231375971280504 0.528858065120876 0.982259075976908 0.76050305636134 0.909843938476406 0.0747396560781635 0.533089022419881 0.631838487908244 0.335652962338645 0.558995713712648 0.0993686060700566 0.64747056633234 0.504646853823215 0.742637521161232 0.443057373610791 0.816750275644008 0.50057608527597 0.480062293971423 0.81034731810214 0.23337987170089 0.874326441169251 0.0760527087235823 0.181016580611467 0.548492084324826 0.59016716736136 0.638662268957123 0.241266045859084 0.142617825064808 0.997181502014864 0.795220497804694 0.594374624255579 0.906872818439733 0.829243140893523 0.755466258511879 0.992104409590829 0.284807490415405 0.839264754627366 0.502772340357769 0.763617816464976 0.547797884123866 0.0898934654332697 0.834819496539421 0.281291119635571 0.610808505059686 0.285293083235156 0.125642026811838 0.156005776990205 0.736711443450768 0.719994244847912 0.736225272761658 0.199507854513358 0.820049039770383 0.278249513136689 0.46795145315351 0.430612335982732 0.0220598483993672 0.865071568335406 0.274330636179075 0.389807023319881 0.669201309247874 0.763471919549629 0.193519655731507 0.452336214308161 0.780554583065677 0.892664547881577 0.862573363720439 0.0861727965134196 0.135693287295289 0.0864981224411167 0.117349325823598 0.175493258712813 0.840833316578064 0.130616193949245 0.377709366774652 0.0706588906445541 0.0985555434203707 0.274608607476111 0.734337787316181 0.599403694283683 0.617017436798196 0.244419764084741 0.435615648988169 0.502795105921105 0.749376283958554 0.371998446860816 0.0992215840728022 0.179694007528014 0.339420679090545 0.0140362494392321 0.818992930154782 0.141032513431273 0.533680116159376 0.737143249933142 0.699499773327261 0.902763830991462 0.898304874149617 0.560498067555018 0.0822697352431715 0.885612260645721 0.718158895112574 0.157175775966607 0.834658814973664 0.114751128372736 0.556418178260792 0.510936598989647 0.0777144959615543 0.890176285984926 0.326713059884496 0.0909874878427945 0.585328620192595 0.919836413026787 0.684698821329512 0.485655122697353 0.153739187116735 0.293029730527196 0.696689204622526 0.60516363858711 0.983214430715889 0.143010533279739 0.501678821134847 0.824541639811359 0.903479835561011 0.518164203076158 0.0381441608839668 0.568468171993736 0.492988847754896 0.246505528101698 0.873643743034918 0.881451636985876 0.340045818025246 0.583623862708919 0.512676785604563 0.0173521113069728 0.58349698984297 0.580444703940302 0.175518226264976 0.660244306977838 0.859944405732676 0.116094949392136 0.427748680515215 0.856705325115472 0.758850256178994 0.565850660060532 0.0588884909451008 0.0923501120903529 0.479124296980444 0.739220003613737 0.28870524344733 0.0979812592943199 0.0986626168270595 0.613269637061749 0.389457486348692 0.253107247808948 0.059086127106566 0.536607225693297 0.390972905755043 0.263479987136088 0.135865464934614 0.61873854957521 0.635907158653717 0.784120269359555 0.565568903915118 0.12998124967562 0.577004364356399 0.448924517405685 0.632057324522175 0.125048107344192 0.038363852892071 0.660424864529632 0.203358243233524 0.102979884804226 0.0375946642877534 0.386086886399426 0.711689458852634 0.443500553078484 0.969509010917973 0.250867889481597 0.17506604522001 0.933026221224572 0.380283938196953 0.204978501095902 0.0872750333347358 0.65188411974581 0.640957627827302 0.545033476047683 0.789174856457394 0.245184568304103 0.819524480991531 0.360255623308476 0.281073753857054 0.155846294267103 0.140682671966497 0.243060391764157 0.93501725246897 0.207647796301171 0.713333651386201 0.996174635074567 0.351470672823489 0.0946202182769775 0.329658662851434 0.579295850095805 0.0919371719937772 0.0922501805680804 0.157449312629178 0.411733155229595 0.173764855377376 0.780514437626116 0.281375317298807 0.646118209350389 0.682415191109758 0.19288595294347 0.477343726125546 0.118281244467944 0.165687211225741 0.071935314394068 0.570672035496682 0.0350866497238167 0.215596195717808 0.547864881933201 0.755647458704188 0.918741486587096 0.859523655755911 0.403463248847984 0.0496007417934015 0.261512159178965 0.486788806030527 0.689545465584379 0.447112119249068 0.440367194432765 0.710353259393014 0.371724554763641 0.96301835184684 0.779977484045085 0.594723970831837 0.438774258473422 0.138787675371859 0.919046839026269 0.630405585803092 0.978905969311018 0.581544335393701 0.442051911121234 0.802808357221074 0.885192281238269 0.494281501173973 0.644020503237844 0.501463732258417 0.337303243130445 0.708216997385025 0.399387842593715 0.298433958091773 0.15602588463109 0.775058546881191 0.303277637164574 0.656248617651872 0.992646100225393 0.786413893008139 0.547650145264342 0.675431136484258 0.249174551314209 0.209860274598468 0.912353492795955 0.0553340614633635 0.0247807839652523 0.220973839217331 0.759688115117606 0.447846460279543 0.632206483276095 0.0304458346054889 0.315384185798466 0.671704933203291 0.21095547925448 0.899919471335597 0.341438989364542 0.345947403248865 0.209161218174268 0.345285009834915 0.27869765024865 0.24424947333755 0.385880113355815 0.889434376410209 0.743078588766512 0.772382182630245 0.787814019985963 0.560597099887673 0.910834087773692 0.673699228591286 0.111493643296417 0.718891273415647 0.662376516063232 0.522613098260481 0.533524933457375 0.752913643820211 0.999765833828133 0.900565574688371 0.913221387341619 0.166038433860522 0.555976383881643 0.734711330183782 0.885549825399648 0.378676803293638 0.122910708498675 0.111596492517274 0.850745281502605 0.382173603733536 0.387369424684439 0.735132009396329 0.215077840217855 0.988923855591565 0.769690532616805 0.791119573789183 0.362482299166732 0.459091468625702 0.638369617888238 0.432543087408412 0.876866828403436 0.882514959941618 0.22865859905025 0.437975431417581 0.517778526104521 0.546740084926132 0.145784438513219 0.811655914445873 0.769211921482347 0.259078253421467 0.858929789995309 0.189175225589424 0.769732348967809 0.379294711370021 0.539644613307901 0.215787941622548 0.819712927716319 0.0683227886422537 0.41880366390571 0.500350726367906 0.407806116875727 0.397632342556026 0.225018177444581 0.0214421302569099 0.389139431847725 0.479139807713218 0.703833681729157 0.984938566531055 0.66348552942276 0.483147422308102 0.94678874359699 0.679905926531646 0.360482818398159 0.560634830815252 0.795774042943958 0.738884479571134 0.292588602760807 0.347817850192077 0.0134931972273625 0.678937189287972 0.842188149846625 0.363549485341646 0.163229436490219 0.808944698933046 0.691986061441712 0.865860669806134 0.704202387735713 0.802398917071987 0.909239922775887 0.858984823119827 0.494645466899965 0.732754697955679 0.506393588779029 0.86576675508637 0.855532449239399 0.484432407375425 0.710144797458779 0.342705461406149 0.355564634515904 0.21719440695364 0.990039225053042 0.710953861123417 0.432598503627814 0.692002600445412 0.634968035197817 0.0798826122400351 0.756725896159187 0.394849434592761 0.444665702977218 0.769745943073649 0.7558128498937 0.994527058766689 0.251933912541717 0.898881848468445 0.743108842428774 0.335991689672228 0.238339764750563 0.316218087242451 0.436936819925904 0.182210291593801 0.683999470092822 0.552843975597061 0.991232026012149 0.993154369404074 0.322500510732643 0.920240249203052 0.49450238280464 0.921152420712169 0.966001674677245 0.870053645852022 0.727780543495901 0.478771788603626 0.817584908471908 0.646961422397289 0.706544731280301 0.534045039622579 0.9232371762814 0.218781556843314 0.799353469482157 0.792626693958882 0.615655297527555 0.651113107868005 0.517152960048988 0.399810404549353 0.753005227469839 0.586395159577951 0.579025557062123 0.551162329430226 0.253417421665508 0.24109935763292 0.523748427380342 0.0958067615586333 0.295854767402634 0.462050267390441 0.323147038670722 0.956350962023716 0.907934536407702 0.605953024958726 0.782765989988111 0.989802319591399 0.79262630717596 0.0514113537874073 0.644368360769004 0.0860914089041762 0.971091574272141 0.566996542038396 0.580167467484716 0.401815788482781 0.832458478156477 0.72501859810669 0.935077110698912 0.201998806372285 0.0806253152037971 0.718435438447632 0.290745529814158 0.817540102044586 0.204578685110901 0.72986277806107 0.761072929133661 0.827263355627656 0.880985598140396 0.0998064256669022 0.064576899309177 0.826297577342484 0.953756969396491 0.270937274124008 0.142943276385777 0.985914218614344 0.543976584337652 0.0695605666004121 0.586654235676397 0.826744809963275 0.505765463225543 0.667122213433031 0.441385511346161 0.157287621463183 0.117141684247181 0.407660853611305 0.740281412247568 0.386372449060436 0.501694606626406 0.358072617270518 0.296141207816545 0.541416149162687 0.450396579091903 0.222453872826882 0.442416383030359 0.419845776727889 0.737066174561623 0.253945547007024 0.713082817129325 0.201127338348888 0.190986705655232 0.453178012070712 0.800761887168046 0.538076181591023 0.0242867238726467 0.684123740817886 0.477853706323076 0.0831357350596227 0.756198750913609 0.0513844935805537 0.911780665444676 0.718294993373565 0.105619205485564 0.407170384745114 0.264541666379664 0.0490886435098946 0.325414329271298 0.149662213907577 0.476911396402866 0.854071304835379 0.438517215175089 0.0300005727796815 0.196795693479944 0.748589789238758 0.0817242740513757 0.83702854888048 0.345196881415322 0.154043540558778 0.126916426981334 0.717564415524248 0.0856675872532651 0.118732783563901 0.486737718645018 0.935602653722744 0.76225319445366 0.388084292646963 0.378832688797265 0.0933442629082128 0.313021770340856 0.19014613162959 0.906011915490963 0.308924964710604 0.449603444060776 0.77219784184359 0.413137907467317 0.542243754665833 0.335069521046244 0.676285847909749 0.308037179657258 0.519320782897994 0.109370240322314 0.797959575518034 0.389836155588273 0.418900192982983 0.268136713830754 0.195001913688611 0.345864592979196 0.907215442645829 0.990727470456623 0.845422710543498 0.816798236495815 0.100762403223198 0.731035457318649 0.0840200093318708 0.556193390768021 0.568632870293222 0.332401989875361 0.769823756513651 0.513249559018295 0.365787466878537 0.816453156287316 0.509963785081636 0.939073057956994 0.778709438825026 0.61609914775705 0.769818258571904 0.497901274841279 0.668326307162643 0.130567126455717 0.233898597157095 0.834260399059858 0.308370111701079 0.480058599018957 0.0283858165470883 0.511008377647959 0.443530801669694 0.336139991187956 0.42065333774779 0.0214564439910464 0.621963551801164 0.38660702713998 0.921043325569481 0.852970324251801 0.805358402503189 0.73744422997348 0.482905449483078 0.928449749681167 0.543012254068162 0.769723933788482 0.964358800156042 0.963475145013072 0.0346384317055345 0.699095193550456 0.0713207492930815 0.17127234831918 0.37247354560066 0.935070998237934 0.462088854173198 0.682008607345633 0.157681087569799 0.518632007108536 0.279268901885953 0.695013698346447 0.5812070954917 0.404088983631227 0.579847806151956 0.199061779244803 0.341932068669703 0.171252571679652 0.248515998530202 0.671007697747555 0.191899184654467 0.461464305093978 0.533827447490767 0.128460542545654 0.636622282243334 0.45847985280212 0.819127593077719 0.349473344485741 0.713567162700929 0.761287801568396 0.533943555897567 0.840410215246957 0.556240895916708 0.550662767938338 0.74752490947023 0.806000345058274 0.841885104735848 0.952767626857385 0.333874971265905 0.911592683182098 0.920882936972193 0.647657470535487 0.541816203717608 0.723460265619215 0.365501377289183 0.434684130265377 0.300799277878832 0.668890280919149 0.318310756648425 0.390039248662069 0.69724677848164 0.0184443646110594 0.560424374113791 0.350389622163493 0.0545293453033082 0.0554472823673859 0.915773038303014 0.169474274499808 0.329014208973385 0.0915071502909996 0.397003337866627 0.458776835701428 0.315414700389374 0.439619558257982 0.527136321689468 0.29323921012925 0.779663750771433 0.955266543955076 0.998387233924586 0.408326211976819 0.962207340206951 0.376823841796722 0.926022042823024 0.780902152929921 0.980024318245705 0.320777404110413 0.759211506356951 0.657799586511683 0.365563184416387 0.831286841460969 0.209426543191075 0.155159324002452 0.603335585864261 0.255605862948578 0.137043537255377 0.218889853064902 0.717389137858991 0.297698148530908 0.267240822932217 0.0848553332057781 0.26489126028493 0.782799251475371 0.607734864267986 0.370371382725425 0.994337332062423 0.429205261433963 0.261180606922135 0.295707300996874 0.844384999854956 0.314334923485294 0.724926385416184 0.182415569138248 0.74050343740033 0.655253512093332 0.517731473662425 0.605696872090921 0.476001878206152 0.390268303905614 0.328317537095863 0.202627907642163 0.351924087977968 0.913863749410957 0.936405825286638 0.370875210124068 0.58271826028591 0.535258202466648 0.137451882518362 0.232964175026864 0.586829959133174 0.2316931113787 0.222099448284134 0.449786812588573 0.186648143411148 0.152226236159913 0.322446774644777 0.0252556660328992 0.431522214224096 0.554752030840609 0.147890234566294 0.0289671284588985 0.231101372693665 0.733466357095167 0.970144415504765 0.282671678347979 0.780891266765539 0.827613809076138 0.395562790690456 0.160035689459182 0.848255374510772 0.0684426187397912 0.334296802298632 0.536781671475619 0.877400296789128 0.521148552102968 0.140761489935685 0.644034119010903 0.683361706775613 0.823826745341066 0.0330806780094281 0.763631998121273 0.741780058690347 0.34380364530487 0.186476466883905 0.573296361309476 0.142987067680806 0.115854090123903 0.479947759895585 0.957831669622101 0.933096226397902 0.0179578223521821 0.43585768266581 0.685375593940262 0.613754805526696 0.433232613482978 0.701946031013504 0.67045419594273 0.191144032720476 0.684367472375743 0.64054987864336 0.0954535130388103 0.548770237718709 0.380933648219798 0.387707042149268 0.955262891876046 0.954674996817484 0.631554544987157 0.649055676506832 0.506693412389141 0.23982221033657 0.148712591992226 0.700176255044062 0.40579371714266 0.492304063113406 0.68372771544382 0.839774397138972 0.999109696478117 0.313383785325568 0.43326725683175 0.143353331054095 0.198234529867768 0.620492811584845 0.847849985440262 0.451306327329949 0.0967995330505073 0.695782676041126 0.789321648643818 0.626725694590714 0.799901226938237 0.984337568336632 0.0557559166988358 0.956695949339774 0.345012329949532 0.263952078050934 0.091330640129745 0.593517652985174 0.516913150027394 0.458639939671848 0.520358477451373 0.989901856954675 0.651234291936271 0.611214773957618 0.156394030516967 0.509887780854479 0.931968183226418 0.777579686939716 0.593787554625887 0.425952821362298 0.150278453838546 0.0414353082911111 0.0737814136059023 0.669936308593024 0.278954252596013 0.258021765782032 0.486603642120026 0.339540242957883 0.758199992028531 0.361265575522557 0.58128331293352 0.0233658575848676 0.890818460655864 0.123415028941818 0.818244961365126 0.68710295494413 0.103486984414048 0.685047956535127 0.79733147370629 0.57321002850309 0.536680937574711 0.853365348323714 0.700684589224402 0.0896644122642465 0.519169630990364 0.26522823971929 0.290005205865018 0.492694266459439 0.777144735944457 0.389448156536091 0.786403425205499 0.43238897562027 0.693181430888362 0.810541330766864 0.0164647425408475 0.79231814814033 0.568062565098517 0.954119798284955 0.486560644214042 0.63872392349178 0.957880613796879 0.794390208562836 0.381236386531964 0.974261899499688 0.0324279200541787 0.761273519643582 0.719521260967013 0.507180201285519 0.128500742844772 0.356780124972574 0.838763362485915 0.418874798540492 0.0318570796330459 0.117711214262526 0.467893957803026 0.257143329211976 0.922104801509995 0.310399817319121 0.0748393089231104 0.626697251063306 0.353522373435553 0.123491865282413 0.367794036976993 0.156659589032643 0.920347381157335 0.11117722697556 0.410640476418193 0.767383190852124 0.212165339922067 0.553421742613427 0.536342986342497 0.881181825702079 0.2082343074237 0.890113563763443 0.520023782986682 0.248174071363173 0.270484609946143 0.175077654009219 0.983972720247693 0.187955645099282 0.593626927919686 0.140981612291653 0.595344047013205 0.0563184173149057 0.349986101083923 0.207767091402784 0.228695225641131 0.413541699617635 0.19392006064998 0.944156017126516 0.563234303866047 0.708946093565319 0.68361021756893 0.760684286288451 0.400687931326684 0.609816874323878 0.845056801452301 0.925751843603793 0.952343502556905 0.963581677200273 0.596584479666781 0.480466245859861 0.152579909956548 0.355814697742462 0.709174004825763 0.590081003052182 0.52355256770039 0.333962509599514 0.667884006139357 0.155798771369737 0.78592574991053 0.355758750676177 0.158922814724501 0.478927814944182 0.127962208709214 0.0826019750884734 0.382485245659482 0.537428604406305 0.242054545949213 0.708548553790897 0.490835845514666 0.0760071119037457 0.92370580989169 0.365370925413445 0.046540516007226 0.868482789481059 0.191155600710772 0.913114068449941 0.927944947949145 0.987419063034467 0.410427867977414 0.572213175506331 0.460265613186639 0.321110565043055 0.853572273037862 0.0561648755590431 0.191465096429456 0.145561643713154 0.910088208948728 0.988739853412844 0.595286233338993 0.475119440346025 0.18647672181949 0.643438061403576 0.514256845011842 0.134597285562195 0.572110339424107 0.810310210222378 0.990646589491516 0.599711215519346 0.497212327558082 0.572131694313139 0.798251556747127 0.450231966769788 0.159283345965669 0.559507288294844 0.207250508004799 0.841247944182251 0.594484780631028 0.667037977506407 0.906043676177505 0.239829526711255 0.367584783036727 0.996227858755737 0.85269301634049 0.335805584851187 0.0428717308584601 0.392091074436903 0.493291403278708 0.167258491029497 0.768115003041457 0.698811573563144 0.92143274751259 0.439058705272619 0.104176075069699 0.311012428682297 0.987830176400021 0.982027403379325 0.636995185927954 0.507525277575478 0.769733122994658 0.290259697963484 0.0580812793667428 0.590955823732074 0.435569366423879 0.992260446073487 0.773045647419058 0.215887114331126 0.253521002039779 0.0979106308426708 0.203126558880322 0.339955981813837 0.869025153412949 0.138988245597575 0.593615445445757 0.377808633067179 0.27100926092593 0.601979234968312 0.217236831139307 0.741782613117248 0.210912466596346 0.927966369683854 0.568615991990082 0.759859020845033 0.256204953505658 0.0642982136853971 0.292813456177246 0.98664822841296 0.520496360952966 0.309234272339381 0.716056372884195 0.0606120071699843 0.807921090607997 0.590325681513641 0.703713721858803 0.105056082513183 0.703609722431284 0.270001728294883 0.18540311477147 0.406258696138393 0.0133730801544152 0.182642964764964 0.155847597296815 0.334870913086925 0.629398953053169 0.595908552077599 0.472867991018575 0.689994494970888 0.933174437915441 0.214985090917908 0.537287684497423 0.843767130502965 0.220410086512566 0.68639623362571 0.62606522195274 0.61288945319131 0.228608365906402 0.65714659644058 0.368075183443725 0.126230494207703 0.987218377788086 0.114428960096557 0.895546463513747 0.0774074760684743 0.406415036423132 0.312435902780853 0.877226139826234 0.214467280094977 0.747930225240998 0.195173618798144 0.257184356322978 0.238214114238508 0.786248884913512 0.80414301577257 0.381889256741852 0.948613025993109 0.578745644474402 0.427662206871901 0.115413653634023 0.485834086325485 0.106822065336164 0.375828825673088 0.707377330616582 0.194462629037444 0.895225745327771 0.99448488582857 0.0156247664382681 0.189716951490846 0.982285859656986 0.147527710171416 0.360560683240183 0.817105155198369 0.286120487970766 0.958722332497127 0.0725682420027442 0.142286042766646 0.0711560353194363 0.174197288134601 0.369057681446429 0.899224046936724 0.957117144647054 0.123882612383459 0.0208366036135703 0.894866436440498 0.48743430085713 0.415657410959248 0.879126943466254 0.668602377506904 0.85708550990792 0.301479861154221 0.343078548340127 0.327236251092982 0.113386554305907 0.984898937877733 0.720066822196823 0.607710620032158 0.958318839077838 0.118026728627738 0.918182798479684 0.770944882079493 0.881329216042068 0.358403381209355 0.667965393287595 0.32857400667388 0.42013217081083 0.357594424497802 0.981578734267969 0.248137805277947 0.138082852009684 0.0707919515762478 0.361218696648721 0.440211500707082 0.624648902646732 0.606253744531423 0.243705977178179 0.0233875319501385 0.268779260301962 0.119082022956572 0.770048542162403 0.724408946393523 0.802608483573422 0.273196982811205 0.147403431839775 0.264479902356397 0.713024904339109 0.338882604115643 0.442880625340622 0.818341876072809 0.154307229239494 0.327447562958114 0.684846658613533 0.649862551551778 0.223070341185667 0.249692525563296 0.514261992590036 0.570845491040964 0.0996478750952519 0.383200086653233 0.14922834396828 0.648197635244578 0.848231441453099 0.908572769949678 0.109536391017027 0.490159626801033 0.914240656690672 0.516914759394713 0.0676622254168615 0.128677387619391 0.824552469733171 0.785901348933112 0.488316941328812 0.629807449986692 0.0120128962351009 0.209756110131275 0.98776370574953 0.340529148464557 0.911959216012619 0.279139927530196 0.494392398614436 0.238946428922936 0.656408590653446 0.489086929545738 0.0985933416546322 0.321800075904466 0.362621278015431 0.42376590692671 0.765828918663319 0.119320240898523 0.273746001115069 0.925595905776136 0.621659002201632 0.996948019051924 0.823935875981115 0.604967577217612 0.198478136262856 0.407662887563929 0.76818693659734 0.582404191400856 0.528365460189525 0.680889931328129 0.190726805510931 0.18204726443626 0.0500485870894045 0.785755055784248 0.712888249645475 0.248233820335008 0.714219659727532 0.54996490413323 0.906753618766088 0.568923993131611 0.69861339410767 0.212542563450988 0.820113855644595 0.995978983077221 0.233352034394629 0.346796034944709 0.3010304164025 0.0704260293464176 0.600606887901667 0.359149249892216 0.632853553816676 0.545226765857078 0.973352952026762 0.232804534179159 0.175517088966444 0.957245129917283 0.0808428598521277 0.489875272894278 0.642976549854502 0.624258371295873 0.100575361640658 0.873298365708906 0.675298382120673 0.812158663093578 0.556226861551404 0.600123594112229 0.697870527026244 0.433280032654293 0.720918890682515 0.91945876191603 0.973816237291321 0.607448449439835 0.926471259838436 0.110698134782724 0.108201728085987 0.254155394029804 0.256141355375294 0.855710074570961 0.172025197995827 0.359689218443818 0.403938523922116 0.173588691891637 0.196713174795732 0.540444993257988 0.587808169561904 0.386690899564419 0.0366409585624933 0.659888165423181 0.864607864248101 0.586718911174685 0.336439364165999 0.797693878239952 0.63406831680797 0.367497306938749 0.0984724724525586 0.726154774553142 0.24482795675518 0.0397167282737792 0.946298800045624 0.305083127396647 0.786398659339175 0.690877631944604 0.372212558868341 0.959564683695789 0.401518939044327 0.876950184733141 0.893851680557709 0.4804730841727 0.79076100850245 0.281143028107472 0.0684038885845803 0.98194614485139 0.441342760999687 0.963436365760863 0.900981645006686 0.231620961381122 0.782472431431524 0.696724082392175 0.957456945430022 0.0234626466687769 0.448569235855248 0.267933900586795 0.259651728484314 0.107848586288746 0.676511149422731 0.928827928872779 0.882714446806349 0.0189502582326531 0.275991501407698 0.304758986481465 0.50786378293531 0.214522014027461 0.988430477324873 0.551009998042136 0.847332433701959 0.97567776056705 0.736434975720476 0.181138742240146 0.986051176879555 0.252457743624691 0.0399551391461864 0.462742219502106 0.837349982315209 0.292932722005062 0.86964455537498 0.846377737508155 0.134700423371978 0.824729600176215 0.964795647494029 0.369493296057917 0.836832020513248 0.77496251499746 0.881856705658138 0.403988747384865 0.392628212189302 0.20390198741341 0.729518001885153 0.533520660866052 0.825653503101785 0.467778320773505 0.71343758465955 0.967391487136483 0.311258125733584 0.498653741192538 0.425677750015166 0.384336603551637 0.859940518310759 0.54018497209996 0.84371901106555 0.951334053990431 0.659169151415117 0.330282017467543 0.538847247175872 0.324351986641996 0.404758287966251 0.754236589856446 0.504773646013346 0.769221130742226 0.0503319334704429 0.836343081260566 0.952905437059235 0.402780053981114 0.342430752408691 0.868195160597097 0.543369452476036 0.423687090340536 0.406488443119451 0.293298712924588 0.576678146154154 0.842500992228743 0.7748522293102 0.945340667292476 0.749881542315707 0.416817061302718 0.972943087292369 0.246586130389478 0.433576678559184 0.64216004465241 0.909204322381411 0.254961179720703 0.35000522471033 0.928194089396857 0.851671039049979 0.540705042076297 0.329992463658564 0.8539321307512 0.0823426336818375 0.496128370494116 0.587235729915556 0.359658295863774 0.739949146355502 0.128132458196487 0.176556801567785 0.381815148396418 0.94341160176089 0.804316401474643 0.620473120000679 0.593085632827133 0.485105443082284 0.521192151620053 0.304302876293659 0.997177223430481 0.320728987785988 0.569529942977242 0.701778087471612 0.794252981531899 0.0306025377009064 0.862043150027748 0.839907797139604 0.178972173784859 0.512908868035302 0.373023754218593 0.48754756786162 0.0104918417381123 0.476774748624302 0.691635744681116 0.985464899486396 0.668309473576955 0.861708562977146 0.384722772876266 0.571707922450732 0.223252641565632 0.417062647021376 0.676784970064182 0.58911299880594 0.0570884165959433 0.784892253496218 0.641106827380136 0.651513473370578 0.656989255545195 0.523633584431373 0.702118502082303 0.228936799005605 0.986367426086217 0.842984813638031 0.0646606942848302 0.773589556177612 0.698857081178576 0.569550599674694 0.368942397546489 0.946127928432543 0.656825201499742 0.742762277324218 0.634341301647946 0.228910342869349 0.894647850382607 0.185046896920539 0.112877302034758 0.191615338083357 0.140101792938076 0.46637389377458 0.798389898026362 0.884234652824234 0.92123285242822 0.173564233288635 0.607924738263246 0.644106546533294 0.925976018651854 0.182114766123705 0.795284489172045 0.36909476258792 0.805068641011603 0.439754149955697 0.739977233756799 0.237676601919811 0.586018965933472 0.099651856792625 0.931211187965237 0.449411781828385 0.848118574600667 0.53145317107439 0.303108026860282 0.218573138704523 0.442748172935098 0.775042456665542 0.037664928776212 0.0602354659279808 0.593059462513775 0.385782304990571 0.888382067547645 0.370100300451741 0.158325002072379 0.857161531422753 0.502642493781168 0.82002027515322 0.345242534477729 0.752846187541727 0.794502435771283 0.914038251896855 0.200684931986034 0.0871060555288568 0.61255587320542 0.860402856902219 0.695789766293019 0.772889882468153 0.450571454991587 0.639123931254726 0.0303384954296052 0.968500369340181 0.449656908155885 0.146952803689055 0.255848830160685 0.546842421048786 0.123571871260647 0.0292479909467511 0.634985095136799 0.158490062491037 0.597196391916368 0.830696953018196 0.68579195054248 0.38017900938401 0.666747522894293 0.640713741602376 0.436762494926807 0.0113657185109332 0.797821753560565 0.106397944032215 0.737284081790131 0.644493386850227 0.743183162144851 0.20678644756088 0.666627901631873 0.802312735936139 0.0866630173590966 0.555177168198861 0.927344733232167 0.475986415187363 0.37000291551929 0.468360456500668 0.183671573607717 0.129573289121035 0.536695173860062 0.129965889691375 0.421901556309313 0.778523179797921 0.913300974497106 0.0169620570959523 0.0478552070632577 0.850837883511558 0.745318812169135 0.497833682796918 0.622324573551305 0.743303073840216 0.848523519262671 0.199798670553137 0.945916168701369 0.742231459023897 0.741338539530989 0.828017856623046 0.0276920891064219 0.388567773373798 0.721458896344993 0.0994359346502461 0.557908307411708 0.0573921965481713 0.476031265410129 0.626974941377994 0.321380498954095 0.135798509076703 0.642446619218681 0.0522251125541516 0.411461958396249 0.0252103778556921 0.338203138315585 0.546695309155621 0.11110198686365 0.0454552722792141 0.889479744341224 0.684665460495744 0.67689152461011 0.246264305792283 0.469023085027002 0.0450373696978204 0.815494408092927 0.753594824327156 0.102230378794484 0.4550734081259 0.694428595823701 0.326856285969261 0.878725355840288 0.479407089003362 0.129974489272572 0.286504095722921 0.300723491015378 0.219503059354611 0.627042839990463 0.307557495995425 0.0872915142518468 0.850938569698483 0.542062530731782 0.785207130983472 0.203411046247929 0.0514278400060721 0.632261367726605 0.293233093980234 0.169946774786804 0.434389158498961 0.264387070536613 0.222510216126684 0.667142323609441 0.688128884197213 0.12713608764112 0.267177146200556 0.180468147092033 0.920766727605369 0.608001560312696 0.542892017134 0.674845535615459 0.216887927819043 0.120464429606218 0.476446849368513 0.8623009150289 0.90593651333591 0.287079191447701 0.996036524528172 0.665916867845226 0.172333327988163 0.935345641311724 0.65293370337924 0.711571850567125 0.174724286089186 0.361116678849794 0.324444217311684 0.938326539027039 0.15153820051346 0.575895468783565 0.505580641380511 0.0204885665210895 0.283461044435389 0.807626577541232 0.991207547585946 0.724849048885517 0.934485771474428 0.77702885665698 0.357324386630207 0.763177280628588 0.152437332274858 0.791408459832892 0.361200932064094 0.233056100280955 0.577616635728627 0.626154102501459 0.23023356965743 0.570945220643189 0.214208277987782 0.864947745245881 0.411697149381507 0.973158151505049 0.814396220275667 0.0661518927360885 0.227016273124609 0.555302762698848 0.31706808443414 0.231288954804186 0.242413295637816 0.603878142035101 0.73232148563955 0.612050801094156 0.309521364844404 0.36802379271714 0.118485387710389 0.19071192819858 0.676735239645932 0.211716422790196 0.306915466079954 0.761090440626722 0.627424462656491 0.227995117434766 0.983300038592424 0.354902934913989 0.241143269711174 0.888988822768442 0.2768159467238 0.0151601643138565 0.150366386792157 0.368357142431196 0.20630351358559 0.0161643071775325 0.353268137655687 0.604971814311575 0.419767953145783 0.738720519340131 0.259336396676954 0.239607441858389 0.862156890714541 0.245564009265509 0.514812739200424 0.642157620689832 0.703603704245761 0.252945375237614 0.117929059255403 0.0510403570486233 0.705211753090844 0.10951852385886 0.329025683379732 0.725660684495233 0.373551070035901 0.186546025113203 0.723803571881726 0.0795861076330766 0.347879173264373 0.775066494601779 0.843513833789621 0.631117503796704 0.52294319673907 0.736113900025375 0.28469861448044 0.181203573788516 0.488453283230774 0.19186756457435 0.321464235612657 0.867867008249741 0.946304421306122 0.750363453552127 0.286431682491675 0.65588742025895 0.817542278447654 0.0850727054383606 0.85155854630284 0.808641374222934 0.602523136350792 0.83610839945497 0.557316413137596 0.575495762287173 0.717343013649806 0.31703474111855 0.222512263217941 0.966255794514436 0.793443923399318 0.77748423154233 0.871920730227139 0.684309630580246 0.788205957170576 0.0879636420099996 0.643146812480409 0.0571003875043243 0.688831462236121 0.674570363077801 0.682103147648741 0.684537831351627 0.468146777376533 0.97292175729759 0.139831404476427 0.617097682729363 0.131403221820947 0.980820001249667 0.623389543446247 0.620992899774574 0.240095801858697 0.922268432353158 0.468074916198384 0.375360432707239 0.52972824486671 0.842909017323982 0.664100277542602 0.275469646882266 0.946738039075863 0.600003794441 0.0585806389385834 0.631575875903945 0.337319460813887 0.65912423803471 0.0237388140545227 0.303139857619535 0.941047472748905 0.278998603320215 0.63434673804557 0.87895332103828 0.0951175897661597 0.921366470253561 0.0100686938455328 0.265471752299927 0.995880313555244 0.7974134004605 0.977513704998419 0.260503049450927 0.492283385440242 0.38990176392952 0.487363458038308 0.304538615643978 0.317900437824428 0.682534045721404 0.479744696556591 0.363806653802749 0.266898402951192 0.25384240020765 0.933034265295137 0.307358215660788 0.830119509857614 0.0698510620114394 0.843932964487467 0.147636327943765 0.572715817200951 0.993440054692328 0.705207320300397 0.648546006334946 0.920470827606041 0.550995919650886 0.610538098157849 0.972418933045119 0.867514700179454 0.954780493127182 0.748978637231048 0.0168219149019569 0.947186586251482 0.104145089793019 0.0752320436458103 0.454377942467108 0.0709750937507488 0.472472776321229 0.871134995934553 0.834374307091348 0.116939535310958 0.613006037354935 0.37063374878373 0.418408508677967 0.971269030184485 0.718168569987174 0.686488852922339 0.609695239162538 0.114987213476561 0.327458913815208 0.204427275962662 0.284118432491086 0.0442133139306679 0.0770621077320538 0.627170416580047 0.983414313583635 0.559627905557863 0.652912526438013 0.491722007601056 0.777915937295183 0.865692972901743 0.606462465550285 0.0507513557537459 0.837667175889947 0.961194211440161 0.764426011827309 0.318080070600845 0.979542881383095 0.17378248650115 0.853031964956317 0.190187288974412 0.367209046478383 0.561792305216659 0.171393214294221 0.335982702847105 0.950269966688938 0.206451062050182 0.294185649729334 0.413438003070187 0.950773248258047 0.441264960006811 0.346385904671624 0.0926342248916626 0.858930181388278 0.0803714943281375 0.996786075255368 0.918534007514827 0.758281237648334 0.0563909923587926 0.827454450132791 0.815561685271096 0.897609977601096 0.37400063003879 0.187592193854507 0.36552092988044 0.363901921571232 0.189629257107154 0.0432730469526723 0.783424537470564 0.795990256902296 0.0434552698838525 0.679797538109124 0.0504353515710682 0.390467525462154 0.26009192294674 0.216530613468494 0.349680483797565 0.744154075330589 0.590240963376127 0.715538140011486 0.21751209380338 0.784645013231784 0.537305338210426 0.107262896215543 0.845793427452445 0.837570247352123 0.679484273907728 0.289082808350213 0.330453511667438 0.989171429162379 0.166683365800418 0.501769530258607 0.21340184020577 0.760823732826393 0.824948011974338 0.23538338095881 0.123249052506872 0.327467877590097 0.560409996300004 0.853400148644578 0.333789534883108 0.787641533473507 0.953355249231681 0.534707512559835 0.870336671604309 0.547663450089749 0.339896619394422 0.674895100994036 0.636913899278734 0.61567051344784 0.458430457073264 0.29401498602936 0.92484052057378 0.124181964155287 0.317377196366433 0.603216817921493 0.38062358016381 0.392070215358399 0.0838621440436691 0.688686222713441 0.873511191052385 0.821340754122939 0.0852691174019128 0.909673133017495 0.0263436151668429 0.913410788807087 0.228341011547018 0.618173957611434 0.899455627794377 0.613812981089577 0.767234916535672 0.755721348763909 0.0955738110560924 0.0181283143279143 0.140843957217876 0.601226383678149 0.0818626722646877 0.793928346880712 0.158449498689733 0.802268721284345 0.965768944995943 0.0681192670646124 0.392598635051399 0.33452594075352 0.513534388681874 0.141313545107841 0.896625072923489 0.0989515701774508 0.478355913751293 0.781719564467203 0.780865218618419 0.9187115747598 0.391365426802076 0.0126064999145456 0.931629144945182 0.750867956092116 0.348748903069645 0.331645596916787 0.106779692091513 0.382325331666507 0.682715260204859 0.768266757712699 0.975306668861303 0.53494894600939 0.924424210302532 0.0932197261834517 0.011523347995244 0.339809772567824 0.50897425606614 0.0632965600164607 0.0786092380364425 0.838602004395798 0.445251452059019 0.0586163840885274 0.0826498135435395 0.0464140780991875 0.177949617241975 0.097887890865095 0.857024538121186 0.519806479674298 0.483414103831165 0.512637085034512 0.0765575849078596 0.766436080490239 0.211995325086173 0.50699747655075 0.392781738501508 0.303556705422234 0.704480053156149 0.614186337019783 0.872994753792882 0.774510308136232 0.0468367361743003 0.410678230165504 0.0297302832035348 0.0164592957706191 0.0502712866920047 0.302766531424131 0.587287524712738 0.21345584390685 0.519020840348676 0.163368919908535 0.892560853639152 0.203461588034406 0.468409669210669 0.498869780891109 0.351870687732007 0.716954445948359 0.571995203276165 0.538980965039227 0.605480962165166 0.333813277084846 0.432557535525411 0.274238152187318 0.21867888741428 0.676974069110584 0.274821716567967 0.114338619315531 0.308102119772229 0.394055687347427 0.517545287243556 0.223129542253446 0.81411402110476 0.854976877984591 0.364724498204887 0.851264451597817 0.0826225981325842 0.991037393757142 0.801980691787321 0.590732709686272 0.438965855012648 0.180345475361682 0.21416283352999 0.100505868874025 0.673073662074748 0.422689831890166 0.679028483426664 0.588154226178303 0.527481472662184 0.905753429709002 0.571659385573585 0.340298729338683 0.911668993977364 0.48408018136397 0.470674179953057 0.415204575057141 0.718041941914707 0.526905850470066 0.520006466268096 0.393294998286292 0.314099751862232 0.717837965786457 0.335410914369859 0.415768162952736 0.748595597897656 0.0340792065276764 0.999555044742301 0.719336992097087 0.78396407936234 0.87495333537925 0.971037744369823 0.610234837988392 0.986914404444396 0.287016462311149 0.213071073270403 0.909235359521117 0.371725647575222 0.0981406097090803 0.300599655017722 0.698181163961999 0.346770813839976 0.423197061733808 0.461151682611089 0.792505884456914 0.237897229997907 0.653488689849619 0.113659774027765 0.668731288244017 0.589672226980329 0.125764799732715 0.996041564461775 0.236378865693696 0.607774094843771 0.406895267528016 0.694378457416315 0.243184029990807 0.621571106358897 0.0222784552024677 0.0306919615436345 0.607297018163372 0.827522011750843 0.0605226061469875 0.658255718366709 0.926315605989657 0.436757826332469 0.726353684701025 0.997676818114705 0.473809859526809 0.380409067312721 0.778013506629504 0.0539084287104197 0.346032668137923 0.310625607497059 0.9634070686833 0.701216438100673 0.791879794700071 0.323099952805787 0.0811299415235408 0.286318484176882 0.629610343750101 0.118103923629969 0.0452935274061747 0.343545658790972 0.055006935542915 0.681307720963378 0.0495016232528724 0.84093585992232 0.126969198647421 0.09165322907269 0.725781601872295 0.914755956882145 0.379931793552823 0.823513826432172 0.225231513120234 0.904223008288536 0.279889917825349 0.85285275422968 0.589865040341392 0.0604061810299754 0.473251295429654 0.494749618920032 0.733414212395437 0.645320197811816 0.508837548817974 0.279529673329089 0.140146050078329 0.69419894519262 0.420197114613839 0.901146713492926 0.411674179362599 0.754124759342521 0.203097148856614 0.108466046038084 0.684793795438018 0.97813619292574 0.208935663108714 0.924481640651356 0.376722495912109 0.0760513291670941 0.796779662866611 0.607317462337669 0.736856537295971 0.413531814294402 0.689492683545686 0.656513024577871 0.651501372689381 0.487005165435839 0.950546387627255 0.23765406755032 0.355582805245649 0.0627500016335398 0.768525400927756 0.0277212529536337 0.94874170092633 0.976449643282685 0.141886372920126 0.0586958638299257 0.112913800927345 0.309169055160601 0.960432984617073 0.734074139895383 0.95118077270221 0.103408658797853 0.246765015877318 0.634007505911868 0.309132775475737 0.168636873108335 0.448257847942878 0.7792336841207 0.103765629238915 0.986285806130618 0.832698918601964 0.290305856517516 0.663302787400316 0.656013539382257 0.726877074141521 0.882199443962891 0.946558972643688 0.688366396341007 0.823577317609452 0.3848163197143 0.134710484798998 0.174617748369928 0.208181402066257 0.82265950639965 0.678472123853862 0.573311492174398 0.577841598172672 0.813862026729621 0.42896502751857 0.277680115660187 0.491755146922078 0.940713589882944 0.915997545735445 0.851616077150684 0.252542651004624 0.30318672151072 0.448180988552049 0.857545862491243 0.424082009303384 0.282214047766756 0.172850499167107 0.38931633755099 0.86784480626462 0.629916133452207 0.916171991287265 0.692961894238833 0.977881570593454 0.742518706887495 0.391546026074793 0.336799639088567 0.747343421841506 0.613026163666509 0.0577779283793643 0.763752000865061 0.558125838460401 0.379341400309932 0.0137848642817698 0.144266806975938 0.740486956483219 0.164785877706017 0.250006709699519 0.245680789817125 0.686645532276016 0.204253698943649 0.564646538440138 0.427945578608196 0.214127837973647 0.38603544334881 0.231534609904047 0.68628365997225 0.18618633751059 0.922702656574547 0.508482145562302 0.680837383940816 0.616462449405808 0.952121107447892 0.0730374493333511 0.0233160538668744 0.345813130335882 0.187238940724637 0.976826793511864 0.875371381102595 0.549291629856452 0.511523484678473 0.203974364686292 0.598853116170503 0.782611806513742 0.0460699819051661 0.334318909316789 0.786890515829436 0.691261525980663 0.30951687419787 0.172359656195622 0.427608653341886 0.238216062674765 0.945144181798678 0.552600452874321 0.893834533949848 0.397041981583461 0.963235279901419 0.188767658041324 0.783712554750964 0.972290763142519 0.0128815793292597 0.646946787803899 0.760255704994779 0.709833849575371 0.677689381020609 0.950772707730066 0.938516370379366 0.735435168605764 0.507955053101759 0.272254918375984 0.488484917141031 0.428003015641589 0.494950841006357 0.517790501853451 0.284253944815136 0.838367660045624 0.347910477095284 0.902004995630123 0.165197865597438 0.903772610640153 0.474864498076495 0.362087427226361 0.653586612774525 0.764788659771439 0.215758276893757 0.697895986470394 0.365473154583015 0.462850988944992 0.370790339855012 0.811068734866567 0.295787288073916 0.822906690191012 0.0614979924610816 0.798867704016156 0.496467471241485 0.537530503266025 0.761712584875058 0.941713995612226 0.28132659210125 0.119621096698102 0.75345393553609 0.118249456121121 0.533104519783519 0.810206133115571 0.229250961013604 0.226066008568741 0.420460072371643 0.438957082324196 0.89237093400443 0.170549740088172 0.953631979965139 0.336105168508366 0.468898613534402 0.986271837688983 0.720360864577815 0.394598280398641 0.552478398890235 0.259806137389969 0.413440105943009 0.918218705442268 0.487396581685171 0.735697398206685 0.464648198841605 0.98294024634175 0.336175538797397 0.15071678215405 0.558613044796512 0.497663482867647 0.664787587798201 0.797697650641203 0.0765102906688116 0.658116398835555 0.0104607020248659 0.463348494586535 0.492502371189184 0.0170039762509987 0.138520667226985 0.116231564439367 0.463095874628052 0.755243456796743 0.871209601473529 0.806527121961117 0.370228070432786 0.655742313275114 0.0122278680163436 0.720286720274016 0.343819946430158 0.98632862332277 0.824879786509555 0.613139636970591 0.577487381773535 0.069710070877336 0.0548361512902193 0.263475605056155 0.291078488135245 0.270954933830071 0.452214358786587 0.643889258203562 0.0869547401950695 0.338428591729607 0.583499116457533 0.261937473332509 0.557994663037825 0.978809486334212 0.138119958045427 0.035232938262634 0.830688595694955 0.32905906887725 0.0483870105305687 0.577391549043823 0.813178870126139 0.0203415147890337 0.1629794066865 0.0820094462414272 0.429871709614526 0.13243306546472 0.722716257320717 0.240360000180081 0.235183223101776 0.415687810990494 0.286024702033028 0.062338049930986 0.406231392906047 0.401762878745794 0.800161471683532 0.574595507287886 0.742469184382353 0.0386114686448127 0.577448903096374 0.805648865182884 0.857229646476917 0.936390116091352 0.832952312817797 0.819076293169055 0.194632626585662 0.776206259047613 0.129068345399573 0.356122597232461 0.866355867658276 0.190377546295058 0.228387818504125 0.368013151807245 0.0893338744482025 0.707776403462049 0.240124400514178 0.827618243480101 0.180531379184686 0.658365847773384 0.528292065709829 0.296183631080203 0.169293568274006 0.100361463078298 0.888994072459173 0.470921897818334 0.109255012664944 0.710374638945796 0.338745963713154 0.119869570611045 0.333394053494558 0.118069684812799 0.0878377893473953 0.506459797117859 0.0910758820315823 0.646101585982833 0.0851924089901149 0.173545349384658 0.864743708265014 0.565055812627543 0.590424640546553 0.697154972627759 0.252826257161796 0.73390684314305 0.856942288433202 0.353710840444546 0.873334580622613 0.0589304794813506 0.457618444361724 0.11814594581956 0.296112386265304 0.619939738283865 0.0939296655450016 0.803257951107808 0.596651541094761 0.251205496343318 0.605235170838423 0.919248400181532 0.335973164199386 0.874638600111939 0.889987621896435 0.587589659339283 0.405706578730606 0.988158292097505 0.956938405297697 0.0371490438003093 0.28807288356591 0.995585698836949 0.986131066223606 0.392097445291001 0.795769440042786 0.141508033759892 0.778680094724987 0.263766265045851 0.38242182432441 0.510643376044463 0.344813701706007 0.0841725470195524 0.68324441957986 0.506104262245353 0.378648670252878 0.398857956675347 0.837864720541984 0.208040809931699 0.394093038176652 0.0693990010581911 0.211193781790789 0.253490738465916 0.822667101682164 0.0892293017613701 0.636973548673559 0.0143158340221271 0.247165831089951 0.546512522415724 0.425053298899438 0.891735349625815 0.547730739484541 0.421236577581149 0.608707183748484 0.0991823984449729 0.743528713269625 0.893060576482676 0.287076153196394 0.501763668353669 0.36737168754451 0.23962689533364 0.437786420653574 0.985756328431889 0.167819590652362 0.959273490554187 0.300634783573914 0.752172534088604 0.25239520303905 0.610712891307194 0.608198409308679 0.91972165513318 0.223269673383329 0.795362890393008 0.765123333029915 0.653072839200031 0.194021616522223 0.450722205133643 0.745316297619138 0.49873439188581 0.975196567114908 0.692366090875585 0.0942725089588203 0.271962142605335 0.849503513087984 0.015167213305831 0.258987760969903 0.127698446959257 0.244920620769262 0.163285391854588 0.882895671201404 0.0292269735131413 0.909920881539583 0.69646444916958 0.859440942297224 0.657513112444431 0.35455338710919 0.537694681091234 0.239337296807207 0.207938033088576 0.335445306471083 0.423302230499685 0.26373700162163 0.130875624790788 0.8155535197258 0.523931837859564 0.612423749726731 0.720096552849282 0.176648743187543 0.644983632129151 0.955363322666381 0.614712337129749 0.954946773825213 0.506015355188865 0.087052498771809 0.161132888651919 0.062680597610306 0.984016162101179 0.754513993887231 0.982508650769014 0.111851954569574 0.019500571268145 0.393828139589168 0.99300822423771 0.133818113440648 0.698924318940844 0.456730325079989 0.227423603946809 0.512367482816335 0.973619494556915 0.708188300074544 0.535824507754296 0.859755048293155 0.483750034018885 0.625393431189004 0.558750747123268 0.292526785260998 0.110634279411752 0.855140346093103 0.690373071318027 0.0966515853558667 0.994103303269949 0.813768936286215 0.846318104248494 0.542071803149302 0.372309102467261 0.954385848231614 0.780671203879174 0.973465301862452 0.324397220420651 0.732149934275076 0.492712795620318 0.758605541528668 0.221639593816362 0.089699178931769 0.242816656057257 0.615303813272622 0.112757523108739 0.506431267843582 0.225000167835969 0.237516433452256 0.218560476289131 0.997023097812198 0.561275123434607 0.656216996419243 0.334252139013261 0.981965289223008 0.790525256474502 0.397448832269292 0.321234275186434 0.545568758717272 0.80081090694759 0.268207946659531 0.951271595463622 0.626941595526878 0.228051948477514 0.844220331290271 0.666101167371962 0.699327279899735 0.48680226437049 0.945749184510205 0.305752276603598 0.45847374702571 0.364187934172805 0.234996726426762 0.43470326034585 0.740288209069986 0.134474014525767 0.181134747634642 0.931026817213278 0.665546879323665 0.388204928119667 0.610926769815851 0.952677816001233 0.209743646408897 0.657864358359948 0.660970373204909 0.740895220148377 0.514674982705619 0.86056535044685 0.738373169144615 0.580734742034692 0.540879722971004 0.926881620613858 0.0826812711195089 0.50228060741676 0.91673162745079 0.31802063718671 0.909708348242566 0.855770802947227 0.472389899666887 0.0906353528797626 0.231155557108577 0.477173921738286 0.961581877185963 0.122149093509652 0.92862346961163 0.243073633662425 0.463924385544378 0.350542375601362 0.474924958839547 0.459070522878319 0.308015551392455 0.120656058185268 0.88240522284992 0.367507689225022 0.904897506532725 0.408637545260135 0.646660430140328 0.110443678873125 0.657761661040131 0.59150240332121 0.147429743220564 0.491774153222796 0.460836867359467 0.324842337721493 0.353785082250833 0.716529932098929 0.127891188173089 0.201018966522533 0.917896369821392 0.433009526866954 0.0908856632048264 0.658875784866978 0.0769902735226788 0.852010738181416 0.76962090062676 0.652146264521871 0.331054299182724 0.0138236006605439 0.15502743194811 0.0569355928548612 0.286965733817779 0.826593616334721 0.313530092996079 0.111204036241397 0.778262236630544 0.609645218772348 0.98298547758488 0.154357779554557 0.107458374414127 0.612444601890165 0.723707064702176 0.560916389650665 0.221055291367229 0.525567765040323 0.759726690836251 0.384603531712201 0.0969759376416914 0.133738934274297 0.51077843635343 0.0415474783349782 0.344623058754951 0.956909673411865 0.587077783951536 0.960355066068005 0.870201118020341 0.322896694461815 0.758244135300629 0.467574020097964 0.555634747378063 0.658023536819965 0.16450546446722 0.306867003424559 0.454932730244473 0.454577407434117 0.493234596208204 0.592472299991641 0.155982751189731 0.170939386310056 0.520067798790988 0.784784625961911 0.816973255306948 0.420629643260036 0.523023387119174 0.36575613769237 0.425469000183512 0.227878696005791 0.0810187282948755 0.826812104198616 0.295314280451275 0.398430186749902 0.0778506297199056 0.178215786127839 0.0603102939017117 0.961059460695833 0.116567821479402 0.109130594187882 0.641208622974809 0.88938104347093 0.844086557184346 0.730223459359258 0.737680499709677 0.587587094539776 0.532096549889538 0.21337842232082 0.411393804617692 0.839091122057289 0.557715631430037 0.549127042198088 0.876008517914452 0.743605090449564 0.793268982267473 0.968341496987268 0.177456730406266 0.758184710876085 0.46815227831481 0.0933087385795079 0.0690434025670402 0.93888265588088 0.108018026021309 0.769930756390095 0.0797091403300874 0.11999069544021 0.395307842888869 0.0864470942947082 0.448716277906205 0.306597007277887 0.101379722596612 0.373595005164389 0.786942194914445 0.803653920239303 0.458366190486122 0.257491844827309 0.401296495760325 0.356665226703044 0.800459074634127 0.0206562378397211 0.0726785853155889 0.670008307842072 0.195091345598921 0.452673451674636 0.765797216985375 0.102371938577853 0.659189046532847 0.171672380976379 0.769523116925266 0.0124110069638118 0.300172664190177 0.41670395034831 0.77244941808749 0.0257292231731117 0.853044441586826 0.284164979211055 0.173394101588055 0.564399611658882 0.375841409487184 0.4068641801388 0.0510466739651747 0.242040453266818 0.749289001713041 0.517582837687805 0.343408907055855 0.882697704269085 0.55100777738262 0.372639011472929 0.788330242647789 0.422327554132789 0.399239358750638 0.871754393056035 0.871311250699218 0.272644381579012 0.910738834526855 0.173795418143272 0.293663798200432 0.961242696915288 0.0602441473375075 0.36522413714556 0.394767405956518 0.051672226882074 0.0929390658461489 0.354074242361821 0.571267759797629 0.539980812030844 0.0876991553301923 0.64736836274853 0.887723000512924 0.379767403434962 0.250531636821106 0.430029463109095 0.748469444199 0.144975428325124 0.125543349452782 0.755831372370012 0.648505363701843 0.607688508403953 0.17593524025986 0.477073248459492 0.542990039635915 0.342641809338238 0.263933152656537 0.031823807542678 0.206047907008324 0.266398634698708 0.935278674620204 0.814876118996181 0.504662567167543 0.486813753989991 0.818727992381901 0.700114816720597 0.215565494189505 0.37106709824875 0.944734623171389 0.692268272137735 0.290701732987072 0.960061566520017 0.798947854749858 0.969381794142537 0.298300514987204 0.1102687199926 0.319651114139706 0.690350210096221 0.0314270346495323 0.267580175157636 0.733706457780208 0.0613304940192029 0.878492409947794 0.677441502034199 0.172762544085272 0.0798918968741782 0.357735087627079 0.225157233050559 0.106320682875812 0.448444697055966 0.0110041382536292 0.902476483781356 0.113148938436061 0.400961580243893 0.208393119154498 0.016182656546589 0.277244439274073 0.674970579445362 0.975119102885947 0.577529631699435 0.94317520248238 0.917095848112367 0.382361454379279 0.0281931516295299 0.264581048625987 0.80587940878002 0.285811158213764 0.854981782613322 0.318060630494729 0.310278807741124 0.686344714739826 0.298271355750039 0.196688576738816 0.768142816605978 0.798953876162414 0.564171331594698 0.405102469907142 0.9646171969641 0.798690404384397 0.787167183174752 0.3076736117783 0.533668174063787 0.989724302156828 0.380559859867208 0.216024191766046 0.480867147971876 0.305666320899036 0.860034786851611 0.265426630314905 0.992591567060444 0.230277325224597 0.222873851542827 0.386592567958869 0.0126982520613819 0.546512157530524 0.211131955301389 0.723588034217246 0.594153815694153 0.74739442785969 0.0703024028753862 0.893412401420064 0.384492561894003 0.882937583671883 0.991743468055502 0.920199062584434 0.692819941909984 0.887564843408763 0.0309199564764276 0.706188129412476 0.469632317917421 0.0400676906714216 0.236445385902189 0.648580676882993 0.498237996804528 0.144125449573621 0.9201012355485 0.31770112475846 0.23697242396418 0.251102056805976 0.398169377043378 0.212946233435068 0.397113648909144 0.665835099907126 0.862228967412375 0.386894231208134 0.900817879550159 0.19835870078532 0.447801936217584 0.50762207979802 0.885459706361871 0.887605436483864 0.504722007496748 0.781091189279687 0.880253747457173 0.878190965675749 0.755822914547753 0.556531084298622 0.795168512151577 0.349988704838324 0.597751147192903 0.302197609473951 0.355418375711888 0.711319594110828 0.312042580738198 0.412275379246566 0.529289857081603 0.591006211081985 0.280580216543749 0.888943211887963 0.479597174830269 0.927021396078635 0.236899329137523 0.353388930791989 0.160336195586715 0.383863736535422 0.948693217295222 0.381035202939529 0.070222035930492 0.803985939493869 0.819345483479556 0.8516742660827 0.957640724251978 0.275737536007073 0.0734870741073973 0.879232924522366 0.0482062994642183 0.590850644824095 0.921812361350749 0.447235726818908 0.436845649336465 0.334463924791198 0.355707779233344 0.311815714114346 0.153372491551563 0.41180266989395 0.367764520000201 0.982799926891457 0.851932607109193 0.196103297881782 0.117221239132341 0.485840223680716 0.967697784404736 0.426398656216916 0.279482627341058 0.555121869535651 0.376595050247852 0.141914682295173 0.512741280389018 0.294099519534502 0.519603997201193 0.299091858784668 0.599948540264741 0.90762702024309 0.287297230293043 0.372715799869038 0.667715912309941 0.553964935892727 0.826086928402074 0.399316125018522 0.271725394576788 0.951645323885605 0.741314358452801 0.504782029613852 0.0353770610014908 0.815358898304403 0.861327707422897 0.355889406546485 0.268716225980315 0.572388898271602 0.201661871194374 0.717402445450425 0.880876624472439 0.632462003184482 0.752663636836223 0.925122851131018 0.0912715619197115 0.901812884609681 0.90109769647941 0.720869598218706 0.651066128264647 0.228158507863991 0.638247293755412 0.916007691987324 0.642616775352508 0.721013945236336 0.941885139448568 0.595381338372827 0.145428800375666 0.928551626182161 0.521325390038546 0.579961015530862 0.301009078801144 0.380635525025427 0.266157083231956 0.742772554731928 0.404257770350669 0.0804823548882268 0.299794727717526 0.744574928572401 0.331760529992171 0.56228535202099 0.0452862389222719 0.901178278943989 0.789288378166966 0.806919084039982 0.916252959382255 0.56219217836624 0.884108033510856 0.370757201686502 0.521944509404711 0.794736090688966 0.434051242072601 0.544976005130447 0.140519027293194 0.830179494402837 0.973939049397595 0.585572957741097 0.0260225975583307 0.246344935970847 0.040662250474561 0.724264488273766 0.767680223309435 0.608245533667505 0.32145865584258 0.0356536582740955 0.0949848960246891 0.109471054899041 0.319408746003173 0.96223299580859 0.30259844197426 0.753920243838802 0.47286711971974 0.388872834688518 0.507392454522196 0.400067981921602 0.469099577227607 0.428688771850429 0.97718788879225 0.94313550099032 0.772323560123332 0.431019930269104 0.902523763037752 0.0687571942689829 0.678682710558642 0.572064933460206 0.0633484230423346 0.53385005700402 0.72227788036922 0.368662283730228 0.754519293135963 0.229792585032992 0.399575985977426 0.595860909549519 0.77864362741122 0.82595491095446 0.26082603670191 0.952726358410437 0.320854860271793 0.278075961472932 0.316283407455776 0.15152220687829 0.399827604172751 0.145503898498137 0.970790496498812 0.603786526806653 0.205437450150494 0.408896529388148 0.71583840664709 0.244190010649618 0.504233084609732 0.246286879347172 0.611573016771581 0.0138117293291725 0.268562236588914 0.866298551638611 0.982697939288337 0.502243269495666 0.487256226737518 0.20562476165127 0.0526339139812626 0.318181434234139 0.920404766788706 0.232913241616916 0.173123080627993 0.0585339714353904 0.0427096508350223 0.310219772404525 0.540953518063761 0.246421191445552 0.958805998160969 0.121394326514564 0.837202708609402 0.505480759416241 0.091664368098136 0.812207195821684 0.789378582029603 0.406868905897718 0.301400929316878 0.800374311087653 0.135157727792393 0.486852476308122 0.558721195340622 0.872587815516163 0.054131969185546 0.478540085810237 0.577920169504359 0.638209217304829 0.856931219019461 0.915698504680768 0.125020977449603 0.132740475367755 0.89459676023107 0.231511749604251 0.66557354936609 0.925248206830584 0.301814843285829 0.109788758575451 0.536522219427861 0.295097885779105 0.20125970777357 0.406874615671113 0.793964249002747 0.44700396109838 0.942090328941122 0.923667937205173 0.562670900833327 0.484550057151355 0.437522036777809 0.665264199555386 0.721159273271915 0.229704317850992 0.586924170278944 0.520269430018961 0.819004667333793 0.40606638780795 0.975837882703636 0.822301795354579 0.666766606182791 0.569378950577229 0.316995687107556 0.275464786970988 0.858199428357184 0.51570204695221 0.268945183721371 0.0910424336069263 0.487725841826759 0.748398362579755 0.322032867590897 0.644181697901804 0.942235681870952 0.648399978033267 0.885055149174295 0.563524106156547 0.42404989156872 0.610885627684183 0.185236604493111 0.835605547081213 0.353960766983218 0.959948264018167 0.758540900144726 0.946252825662959 0.91909409707645 0.432623393039685 0.629769334350713 0.81029528289102 0.446138906341512 0.270547872465104 0.0483590268553235 0.781522723999806 0.610740746592637 0.126111321041826 0.296037097286899 0.229169716085307 0.233956949515268 0.227171014875639 0.500187013235409 0.758536801582668 0.700765048600733 0.240041574339848 0.26618132009171 0.193353405690286 0.694618107469287 0.240029880495276 0.272669488815591 0.384545851037838 0.489178955529351 0.870378664520103 0.828602188576478 0.725221616497729 0.182814673562534 0.193820437770337 0.270740885671694 0.513180821607821 0.557911595297046 0.106865498430561 0.0789247309649363 0.244795614280738 0.826290121283382 0.47105792254908 0.687519796753768 0.118933643761557 0.155878362213261 0.585245578959584 0.277844439623877 0.119189892518334 0.462112736981362 0.340730180386454 0.197596954640467 0.555705226003192 0.816971976249479 0.804211179462727 0.882478824090213 0.964024429316632 0.0747338736965321 0.243675732275005 0.380597363058478 0.554326138356701 0.663569790474139 0.536725910424721 0.422986500153784 0.166823956551962 0.262881513633765 0.157177808766719 0.51908250940498 0.503784790756181 0.988432551154401 0.551710108553525 0.237761342185549 0.536934209163301 0.264839341477491 0.907849580391776 0.624073128092568 0.540022433837876 0.507481352358591 0.945637513503898 0.625573583748192 0.632560132639483 0.647342883250676 0.0858122028061189 0.54181682722643 0.174839757618029 0.282094420741778 0.468593451259658 0.581666702169459 0.314850088371895 0.44370308003854 0.654086845489219 0.838409352155868 0.922264451116789 0.866828033025376 0.817415043001529 0.39972039937973 0.828033081993926 0.297219958985224 0.30216739038704 0.346774169031996 0.439862271226011 0.921115670802537 0.565517330861185 0.117309796747286 0.47743367228657 0.219077085964382 0.316787280263379 0.870457616872154 0.625200922091026 0.762308903411031 0.921799916760065 0.564663755812217 0.399144673922565 0.673563654723112 0.298880151608028 0.682808409656864 0.127830966210458 0.820243535798509 0.251465602556709 0.22079416264547 0.0387251980369911 0.23298400076339 0.977400925506372 0.167183509310707 0.401230079738889 0.434058873082977 0.767372803264298 0.311161319131497 0.577467710704077 0.879167186869308 0.0877128261933103 0.284156090118922 0.285944377961569 0.257537817596458 0.552599379885942 0.988080798825249 0.145363892992027 0.236542697534896 0.660593430427834 0.554516090953257 0.598490320474375 0.488714214181527 0.16734318934381 0.97733339846367 0.0235616886825301 0.631167379431427 0.674751090048812 0.0939176838030107 0.983667441799771 0.364986026848201 0.0568006643932313 0.255942997511011 0.810789124928415 0.971109606239479 0.739228474113625 0.0305729469633661 0.335395716659259 0.0348865418857895 0.945134906384628 0.610468474235386 0.392139618459623 0.0537224619602785 0.17161481901072 0.108941265100148 0.558313031482976 0.745777088617906 0.0834759000362828 0.959995394600555 0.435447218625341 0.580326578407548 0.565291489742231 0.136518060155213 0.110868554611225 0.497395132507663 0.464386137046386 0.631414307595696 0.255525160392281 0.697608052862342 0.55430721065728 0.978578271975275 0.998080664202571 0.361470565861091 0.201724104520399 0.990186518121045 0.970818710906897 0.21920560576953 0.744328367828857 0.540527768721804 0.0418397248722613 0.113044937164523 0.872899218180683 0.217468365896493 0.536757533270866 0.532617253977805 0.139826990817674 0.869243170591071 0.89314728685189 0.998843329360243 0.297599186731968 0.135225034705363 0.898070855499245 0.49940160994418 0.572228276175447 0.811580112138763 0.147576831832994 0.483691596374847 0.248613110317383 0.21382858693134 0.916027793404646 0.275876278821379 0.301143614486791 0.531776344801765 0.950160172663163 0.49079081872711 0.566219877090771 0.437414636518806 0.328565257957671 0.933961576889269 0.264609859343618 0.624557428946719 0.956454697295558 0.845299073238857 0.611050003971905 0.889278273081873 0.806617809417658 0.930160783973988 0.718715973161161 0.104688599552028 0.758689719829708 0.24764008411672 0.370166139295325 0.723819955987856 0.746078484023456 0.482814934672788 0.0714768542349339 0.775416437487584 0.270042012035847 0.119632649014238 0.488820009683259 0.591358801056631 0.607294437689707 0.774113049574662 0.506446922640316 0.171360435478855 0.725702925892547 0.159038127667736 0.0752403899049386 0.684401128022 0.935634345489088 0.911831207231153 0.624428914673626 0.585419789629523 0.292101646519732 0.176073767554481 0.474331629918888 0.762689045791049 0.340478666608687 0.760444904309697 0.0185148192639463 0.0188131863297895 0.943284416333772 0.917893436218146 0.333430921882391 0.603763380914461 0.540052510704845 0.307945212682243 0.245227542929351 0.568873739242554 0.779270612208638 0.276831600137521 0.587918522786349 0.74047598088393 0.450348678401206 0.0463983105868101 0.571762638173532 0.0488261460652575 0.247267729258165 0.244227790674195 0.65349788458785 0.811455391703639 0.847978227490094 0.508915670439601 0.308264740784653 0.898676451523788 0.257195576024242 0.221018207459711 0.88204414785374 0.804684619968757 0.0851768304896541 0.751477773766965 0.324936266040895 0.214203421303537 0.830859524703119 0.381713444080669 0.018745048455894 0.256037879879586 0.337256527913269 0.922213369032834 0.719378066000063 0.390512413256802 0.562702950108796 0.201087412347551 0.526161377939861 0.419945966182277 0.242864210072439 0.363191327813547 0.980969974137843 0.902443144384306 0.111324511053972 0.84243770781206 0.588287233402953 0.0137075533368625 0.255296572376974 0.710327752926387 0.98560313611757 0.210204065376893 0.488931526944507 0.066913916405756 0.575844329304527 0.0836551665444858 0.168509359676391 0.886816640428733 0.543656900876667 0.509169684706721 0.199648121178616 0.505679194959812 0.975542885812465 0.622648580544628 0.925460929831024 0.0333634937740862 0.192076978944242 0.765592583694961 0.581905864018481 0.0768366305762902 0.720233925788198 0.295539945005439 0.196411649617367 0.572563011900056 0.0701021765591577 0.0335434303525835 0.179535637670197 0.56162696266314 0.428488098820671 0.35942659168737 0.422166794887744 0.124034586492926 0.134592779472005 0.208982417511288 0.357027793049347 0.148390745266806 0.439858239279129 0.88914533062838 0.64572488799924 0.857493960740976 0.660453169294633 0.172097624596208 0.186948321303353 0.983647731083911 0.712468468009029 0.210167018119246 0.316549344917294 0.0716350620496087 0.427533066093456 0.650138288820162 0.227493842388503 0.742708243427333 0.221675008886959 0.746559099836741 0.357831481860485 0.0422735823644325 0.338134902478196 0.696041366509162 0.22910561269382 0.274713247930631 0.518369037595112 0.657538347379304 0.42237506066449 0.927532373890281 0.525516532438342 0.164898448593449 0.41743335978128 0.307137145940214 0.605651136508677 0.732083816754166 0.0419373091892339 0.704567723337095 0.497836336339824 0.901878489493392 0.83470682307845 0.56396250546677 0.161146362435538 0.335135870222002 0.443068949668668 0.86909416857874 0.681956739248708 0.533220831723884 0.675538440623786 0.893561032323632 0.898508486545179 0.575067722904496 0.614029628161807 0.884020246695727 0.500408585220575 0.785285152336583 0.790725608875509 0.18406443787273 0.454683809387498 0.496318551057484 0.0490971322194673 0.907680278038606 0.840651223650202 0.789924131734297 0.93781354800798 0.167044246483129 0.570036304749083 0.833321204378735 0.657926670978777 0.329818735660519 0.94432539485395 0.24387311396189 0.600504062883556 0.997388417969924 0.337738101233263 0.539092473771889 0.87757961055031 0.129050817310344 0.729162483378313 0.471436740693171 0.447627452402376 0.745038317793515 0.770916693257168 0.88210392102832 0.117614956717007 0.495450789972674 0.946287420836743 0.509538336314727 0.0131663545942865 0.637496981217992 0.368967679273337 0.719059125678614 0.141034988334868 0.830573310181498 0.357201813554857 0.823335466720164 0.373903530698735 0.250526381367818 0.36782675770577 0.820779697143007 0.317045799468178 0.148200101854745 0.774554782179184 0.28424879216589 0.422836860110983 0.84792438122211 0.791043877513148 0.139860916151665 0.0275981806102209 0.430824409197085 0.0657188809569925 0.969971402755473 0.430058351967018 0.871766003689263 0.363188098936807 0.960895412873942 0.254117249581031 0.271927091497928 0.544478174711112 0.577013080110773 0.226616974386852 0.617846287935972 0.242212168287952 0.402843585496303 0.787691841991618 0.55676704055164 0.738537446316332 0.604030103697441 0.0331470382492989 0.151993430182338 0.411992690949701 0.516928825338837 0.0715647786599584 0.809084647274576 0.102699074870907 0.494358139282558 0.841528805978596 0.111328815915622 0.585191841027699 0.263672492315527 0.886764817510266 0.125917634076905 0.711554956589825 0.0389565652189776 0.574972734504845 0.161376774415839 0.796839152292814 0.552670832844451 0.275443875568453 0.634583009395283 0.134415050183889 0.600483579293359 0.132773412077222 0.0798379830690101 0.280036590611562 0.677564061970916 0.443507924543228 0.673145770812407 0.0808834109758027 0.043381870102603 0.433709355012979 0.263474251315929 0.421961573124863 0.899287487633992 0.429553173133172 0.0675419241725467 0.891558318990283 0.0840239758160897 0.0931528436252847 0.817975906128995 0.0270226821978576 0.54431059605442 0.851173014778178 0.247501997542568 0.816092896577902 0.75104696628172 0.394265929681715 0.157242445771117 0.917494860796723 0.397990715142805 0.770956406043842 0.734654104521032 0.179294376866892 0.182108653662726 0.886064102391247 0.357562463274226 0.0578348838933744 0.283409289054107 0.873621347888838 0.295447488673963 0.145192786036059 0.778043112810701 0.252842669619713 0.597138450543862 0.252925816192292 0.246363144733477 0.634969523551408 0.854860953288153 0.0524075830448419 0.967755013294518 0.821944613081869 0.285493367637973 0.249740863977931 0.759355076120701 0.513195103532635 0.483908991427161 0.837232439953368 0.239786851739045 0.261238210378215 0.85658812090056 0.836232441521715 0.390262177614495 0.713934033447877 0.812570607420057 0.289176256994251 0.25413187610684 0.582841237201355 0.996536314447876 0.514595016604289 0.158959329982754 0.946249907042366 0.308671072609723 0.0314935115235858 0.528513269121759 0.80983515643049 0.781386149059981 0.192579111920204 0.971278218238149 0.0584052377240732 0.91737153490074 0.833988884133287 0.015484247833956 0.609795091392007 0.189318175762892 0.0446372736524791 0.113578271628357 0.902239930527285 0.668460788910743 0.727675217066426 0.39149787528906 0.302502090383787 0.722362236618064 0.122427848284133 0.496627271596808 0.170936267152429 0.124246165510267 0.951138403606601 0.728251021124888 0.810997942297254 0.920050347086508 0.537270839617122 0.827033083562274 0.500269352127798 0.178365818255115 0.236112992772833 0.4472628472629 0.0171416527614929 0.39678944068728 0.676647386907134 0.442113536843099 0.452525196028873 0.452961204107851 0.674171943936963 0.42111602347577 0.73287991512334 0.209574794687796 0.418964527568314 0.755022969786078 0.971950975728687 0.972006267707329 0.226111380418297 0.760683698737994 0.383212962974794 0.514704368296079 0.390539974651765 0.764055884082336 0.636287412827369 0.0458942448487505 0.221399333162699 0.939019516874105 0.636351214260794 0.451436764914542 0.412505343591329 0.164794099263381 0.0453752308036201 0.074140539013315 0.014426828965079 0.466451511057094 0.569422491316218 0.810935343625024 0.0474439431796782 0.47842238509329 0.155656352504157 0.181541161518544 0.815740268109366 0.99949807632016 0.727786646736786 0.744444638048299 0.948048212977592 0.423797578178346 0.966097678670194 0.93335504733026 0.982415157407522 0.990414749779739 0.373542569109704 0.38096439308254 0.834201853079721 0.497892828313634 0.0118010906339623 0.228119076751173 0.180829185438342 0.992000964751933 0.417840409851633 0.748395546071697 0.828099227866624 0.750001156893559 0.564817581085954 0.838167724623345 0.82857086123433 0.259463910108898 0.952995625478215 0.902087885192595 0.522360060631763 0.0622826735884883 0.80362050754251 0.998001917458605 0.951724904587027 0.985698445145972 0.651175781222992 0.502853491702117 0.890876360307448 0.411933568713721 0.302492926532868 0.139742474139202 0.457778566959314 0.895513208019547 0.398809589678422 0.438661305413116 0.75393244617153 0.856638464916032 0.938158169516828 0.132332207553554 0.0850326217734255 0.749519163828809 0.805513513979968 0.96378555444302 0.480222530898172 0.849098883292172 0.656310130197089 0.0910919775487855 0.308562135361135 0.835066130582709 0.48003149286611 0.742029684423469 0.353590359869413 0.392159516573884 0.581847499443684 0.397425820990466 0.347725481912494 0.937611497265752 0.716921218805946 0.731602162527852 0.955424287999049 0.46298401968088 0.359212566118222 0.108963812377769 0.525339699573815 0.896128061248455 0.370899245524779 0.36738626105478 0.950664045701269 0.28440993450582 0.435437398534268 0.32086473015137 0.574831970876548 0.0242303690477274 0.212842531125061 0.642535040606745 0.626403032348026 0.992293580092955 0.240911697151605 0.815491790738888 0.460549181310926 0.192940330058336 0.453903792705387 0.294096372947097 0.741689927205443 0.330852035456337 0.161740067766514 0.0339967175782658 0.920222100832034 0.301712768552825 0.284266203620937 0.035928029816132 0.0484765625325963 0.874736419541296 0.644834253706504 0.92090479043778 0.794955541130621 0.789855433509219 0.673466588805895 0.658659302834421 0.122871918643359 0.441864063702524 0.119468907299452 0.537993527140934 0.338544167445507 0.328170892430935 0.72597388968803 0.969963820842095 0.418268711776473 0.114068902998697 0.50055789725855 0.161130271067377 0.0165086412499659 0.332133334791288 0.392283753645606 0.748104818775319 0.0829749269480817 0.234250927125104 0.117276296229102 0.35598938670475 0.853424745548982 0.862313448132481 0.882051953815389 0.59648260846734 0.0548321940260939 0.667111878860742 0.0290444666030817 0.872656528954394 0.772878419586923 0.712765554864891 0.788591830530204 0.345295734647661 0.023299528923817 0.979607497181278 0.322477238294669 0.979349222078454 0.422736855058465 0.41894775345223 0.230709424214438 0.0327679040865041 0.601654749221634 0.48151004711166 0.635230582200456 0.356778343650512 0.183509278064594 0.819949929988943 0.072862033827696 0.570812858133577 0.593387168608606 0.948098102903459 0.8371501918789 0.410017713271081 0.965248571909033 0.585754935187288 0.0575302679091692 0.501613023551181 0.887285301238298 0.415444236174226 0.035212720441632 0.153851033765823 0.315988742948975 0.626738350552041 0.865993573765736 0.741827184432186 0.131466645000037 0.704413614775986 0.397285020251293 0.472744257133454 0.311572732841596 0.749487196381669 0.288001988423057 0.196690804774407 0.81932828408666 0.358660380712245 0.525588212441653 0.727903156217653 0.566247839098796 0.258837731608655 0.0993126931181177 0.686535079013556 0.739176242975518 0.535743495172355 0.539215981534217 0.719308433779515 0.489756893808953 0.372475661612116 0.819536685859784 0.758955133589916 0.501580465326551 0.482626972694416 0.452621605244931 0.0666327213030308 0.979167163725942 0.534104634849355 0.723845160957426 0.924794890792109 0.572833410273306 0.491135197516996 0.203203166793101 0.777233439467382 0.123965774399694 0.0864769021654501 0.384079633783549 0.0474345080275089 0.205226460527629 0.151922361932229 0.518968552276492 0.10214276900515 0.557350839583669 0.191459527031984 0.501488272920251 0.559662262853235 0.353780176930595 0.0548489536205307 0.32189756364096 0.0876799074630253 0.332421401168685 0.0456944456533529 0.956685648420826 0.876400994474534 0.603285690406337 0.867136288871989 0.724357579408679 0.289523513375316 0.978713933895342 0.850785255678929 0.390604597826023 0.29407333308598 0.79152657499304 0.830458111106418 0.53123565108981 0.213252930163872 0.914876577141695 0.0487057906528935 0.941153994102497 0.935706240781583 0.392416801899672 0.946954947537743 0.0399548111413605 0.330641681558918 0.584388340767473 0.588691790360026 0.231991938988212 0.190608654853422 0.978915533774998 0.472855262910016 0.554958528664429 0.543510756171309 0.39925544527825 0.755777597327251 0.354775271886028 0.29677751804702 0.420968000176363 0.261595796721522 0.728812642144039 0.166904160301201 0.129920197213069 0.295486798312049 0.770713579668663 0.850667477974203 0.693345597879961 0.148667612457648 0.0303908736282028 0.357013523802161 0.701295278889593 0.580079635952134 0.902094880247023 0.0114785201312043 0.433066417840309 0.865326168308966 0.376173942300957 0.0373813818581402 0.287097971395124 0.335605954152998 0.588482184673194 0.0715938602178358 0.268492995530833 0.942652138511185 0.0462583345849998 0.357836089602206 0.76451618849067 0.625512487029191 0.848983689057641 0.187124346026685 0.046141349808313 0.925811092846561 0.377455575864296 0.456723726489581 0.995606227836106 0.9251503256266 0.0972423550090752 0.639992902937811 0.0702564331027679 0.755915659698658 0.638072297072504 0.85543841857696 0.308535731318407 0.0124609201704152 0.248906257888302 0.597336922045797 0.755266754820477 0.875291462945752 0.872080820554402 0.655719998343848 0.423938014723826 0.383183558713645 0.270664750519209 0.738742739765439 0.0380722950957715 0.0662704559927806 0.809614707222208 0.622351065415423 0.758250168468803 0.196525936133694 0.400227076478768 0.113858913755976 0.2797822172218 0.900466558260377 0.35927158070961 0.270520873956848 0.520277657338884 0.983103895164095 0.478091046973132 0.662175286600832 0.590203925569076 0.469234980063047 0.427122954260558 0.518432482671924 0.254151793813799 0.90755982673727 0.400152008552104 0.490896176735405 0.346521870393772 0.0376269440655597 0.56807236559689 0.802418044847436 0.677870206877124 0.794863556406926 0.139565451571252 0.569275433821604 0.260021170254331 0.161377435035538 0.541676085265353 0.104872958548367 0.612312893776689 0.0273265827028081 0.991605228888802 0.74277725329157 0.50938355053775 0.966982835996896 0.726110208539758 0.679675785622094 0.503784539047629 0.48253319397103 0.713684247285128 0.581353324330412 0.523805099145975 0.273839992822614 0.87637582661584 0.659695579337422 0.545640878058039 0.796834803405218 0.133720588593278 0.425461734749842 0.250300627839752 0.792351142475382 0.564387561457697 0.024113783731591 0.254238896728493 0.0984285553032532 0.3561681055394 0.53308855980169 0.492480927556753 0.104807908483781 0.0857409994816408 0.169062772968318 0.338175706693437 0.321788478640374 0.0570028149429709 0.836786099376623 0.0138698336668313 0.776810006904416 0.893853750929702 0.142999235438183 0.290253389114514 0.948390753741842 0.43781041318085 0.0249535970995203 0.0916675356612541 0.362102954555303 0.0328227758593857 0.531724654652644 0.0999698502104729 0.700003362386487 0.362755510360003 0.444067736349534 0.275463258740492 0.377426125272177 0.800727960912045 0.712962257261388 0.992237860993482 0.725071813950781 0.748853836581111 0.14944358474575 0.856018741172738 0.155312491883524 0.780190828249324 0.788307274703402 0.912057838512119 0.261794740522746 0.120165195851587 0.0982294466928579 0.945712171597406 0.97675809759181 0.890031561865471 0.816190359650645 0.182853997030761 0.567938932634424 0.77392476212699 0.260383414588869 0.757296541575342 0.359418276315555 0.564105843806174 0.6026217991882 0.109615602684207 0.0604167873645201 0.349843271002173 0.809850627747364 0.8136566037382 0.482318065217696 0.731650996753015 0.71266831192188 0.73706484479364 0.876854574899189 0.763389773587696 0.325740280321334 0.0852199798356742 0.595251235477626 0.373521074766759 0.644307684486266 0.280844414404128 0.843389011933468 0.755623855034355 0.805906360496301 0.504312588784378 0.255742910418194 0.550990743259899 0.346410055093002 0.340402270758059 0.896328533971682 0.7624864900182 0.554638683390804 0.276754448930733 0.0412327880156226 0.506627145272214 0.814137937105261 0.733713426787872 0.74044249857543 0.194668531934731 0.026371193388477 0.0708488985616714 0.964179497458972 0.709448455430102 0.901217504909728 0.509865652399603 0.647672531558201 0.67988433745224 0.542622462168802 0.322189267575741 0.562471768250689 0.717226955492515 0.107868545486126 0.851839675020892 0.932625175279099 0.866036005096976 0.344172649811953 0.102252614202443 0.384941841145046 0.146697464033496 0.132370494683273 0.588498666512314 0.169249223312363 0.431288169296458 0.764843202386983 0.320588694382459 0.824242581008002 0.109072879168671 0.749447123550344 0.866845878977329 0.73634883423103 0.179628482628614 0.592703916346654 0.104989970293827 0.9045437154104 0.313029606959317 0.240445942976512 0.411658251651097 0.719313525806647 0.224279180497397 0.0426912519079633 0.586175321661867 0.479653143563773 0.198939859182574 0.778240193461534 0.171661813135725 0.393349994069431 0.689896302127745 0.635234565972351 0.17808135578176 0.931493375380523 0.827599183011334 0.584299028718378 0.453811222275253 0.393893182277679 0.602818406387232 0.330777117817197 0.0836509220744483 0.734800954102539 0.671463158379775 0.872184973496478 0.610634462425951 0.89431645025732 0.419203451308422 0.448082993249409 0.0324919616710395 0.266312203467824 0.76848298181314 0.633186011025682 0.310556031058077 0.97721256014891 0.320210886991117 0.648074943230022 0.729243946361821 0.481790419551544 0.146453909731936 0.673716278388165 0.0301885174703784 0.662088214803953 0.383313506019767 0.940230847224593 0.583440863445867 0.577418978130445 0.445689945414197 0.224139704685658 0.867181031680666 0.353741083503701 0.76260201848112 0.556599345260765 0.131971896211617 0.69295182059519 0.239868220677599 0.065365934856236 0.0867803508858196 0.639105435516685 0.228874387962278 0.428837363338098 0.102573828890454 0.19291415306041 0.0559347136737779 0.703113207258284 0.428011164821219 0.326780396301765 0.393681536645163 0.541668179726694 0.504593428221997 0.712296723022591 0.321693953089416 0.896409060654696 0.668743864221033 0.031748616527766 0.898996651771013 0.358779298251029 0.366548415715806 0.328620354009327 0.913198805488646 0.939609519185033 0.756120028141886 0.110186948366463 0.704803804983385 0.409601530006621 0.840569456864614 0.123091833086219 0.087369782011956 0.499349590176716 0.0990957871917635 0.420676969538908 0.393866589453537 0.325354367084801 0.112618669883814 0.129766684961505 0.739683751726989 0.139511566117872 0.676046509956941 0.0732780255447142 0.878766651486512 0.120567161270883 0.607931357598864 0.981676621004008 0.394733624225482 0.565540165575221 0.999172647588421 0.213964173707645 0.184889239775948 0.434757104769815 0.689470125895459 0.19632559687132 0.583929360595066 0.443298249014188 0.350314644363243 0.867795361899771 0.744819806187879 0.902967279730365 0.448844976581167 0.620854827261064 0.853729338252451 0.164070714469999 0.674950933731161 0.697833416149952 0.198269365224987 0.374977480734233 0.0911295533482917 0.104477442123462 0.732915323739871 0.0586077660671435 0.41100135179935 0.332415129891597 0.945556225932669 0.752179031027481 0.828510225520004 0.305204494483769 0.559300175029784 0.0736347777000628 0.194780995408073 0.864148515732959 0.46955511208158 0.918846989581361 0.393324841654394 0.358957116974052 0.510993682201952 0.389324072978925 0.386387569091748 0.255235568089411 0.542150369409937 0.29742247995222 0.247517744540237 0.360246025191154 0.792528135769535 0.919771525235847 0.222345631925855 0.269966398971155 0.17992266838206 0.192036919021048 0.80358211484272 0.583824648223817 0.060291104351636 0.325254428647459 0.420915757052135 0.0937550037819892 0.0132834933465347 0.217091081745457 0.128755068981554 0.243224426677916 0.793489974078257 0.819041775213554 0.357694241921417 0.152224811655469 0.267493413616903 0.386063454684336 0.0212242827285081 0.357102453678381 0.528822334262077 0.286222938653082 0.168964407478925 0.119550203629769 0.757474719190504 0.348732956917956 0.134685659466777 0.275922253434546 0.622266851386521 0.636248339454178 0.40153025140753 0.925393040899653 0.325434837294742 0.765747149111703 0.708676743977703 0.379862919454463 0.517387628485449 0.346848462009802 0.128963852236047 0.330029801349156 0.534528940094169 0.969058057528455 0.262163248297293 0.743695965535007 0.213136869932059 0.262080278059002 0.654896171465516 0.563707514100242 0.794718200250063 0.83734944201773 0.715307683774736 0.175359565974213 0.249249400724657 0.585668313561473 0.044844904395286 0.743893050565384 0.722520366061944 0.31947109388886 0.882810250031762 0.240152027141303 0.0867383220116608 0.588135246385355 0.683902146934997 0.02233918127371 0.44248077086173 0.486602183270734 0.80653671131935 0.310855989051051 0.121786114564165 0.767738978585694 0.99239087858703 0.735288668926805 0.590443900630344 0.467546194547322 0.440779676982202 0.817486641868018 0.147296886283439 0.673402502241079 0.387916599200107 0.885229112976231 0.95785630939994 0.162590571141336 0.957648558334913 0.947790965915192 0.182372340960428 0.79267591127893 0.861629804708064 0.443334775797557 0.343987145449501 0.463777021712158 0.915149813920725 0.0185256535653025 0.0223387548443861 0.684952748697251 0.74449461717857 0.849951490692329 0.362375904128421 0.457563033443876 0.422675279125106 0.779486079800408 0.534254891024902 0.525471079451963 0.0993115963879973 0.599554394637234 0.583898943506647 0.751712940318976 0.717763274039607 0.924330891661812 0.163924407721497 0.882952436089981 0.975680096708238 0.896911140154116 0.0816862003668211 0.932567843585275 0.577234638726804 0.260504117829259 0.77355039682705 0.236173223725054 0.763702298568096 0.85471641080454 0.996259726395365 0.929043556433171 0.829175035289954 0.568349035708234 0.194883755424526 0.750479506407864 0.392855424797162 0.870503953143489 0.117028090620879 0.595283471229486 0.351421853119973 0.795285752324853 0.881091536784079 0.389594353104476 0.558990562446415 0.401180570833385 0.536843416828196 0.456051795810927 0.141986229068134 0.162709261174314 0.978378655568231 0.204916868458968 0.500713916914537 0.898111468628049 0.0941935519967228 0.261168742275331 0.894527785403188 0.221814659880474 0.843427912660409 0.674253432736732 0.368405903356615 0.196002346847672 0.298622752414085 0.249527535447851 0.748493826966733 0.535385253280401 0.166205954661127 0.421149856378324 0.419853523450438 0.549883599043824 0.925681053800508 0.851361018707976 0.694020389784128 0.688012093503494 0.16460884753149 0.300909911163617 0.246620793100446 0.103861302000005 0.113133187980857 0.67108274515951 0.866085336976685 0.0545732656796463 0.237015118990093 0.529471788657829 0.751667430629022 0.353243912551552 0.321634002889041 0.0274934083083644 0.542973171935882 0.872771817464381 0.706929665803909 0.836923372738529 0.813053367827088 0.44046898126835 0.29823083966272 0.190644253864884 0.979666843004525 0.6741824903409 0.736384552642703 0.744949970396701 0.985902698107529 0.250587589880452 0.856187305687927 0.58641516602831 0.934291305181105 0.810097781112418 0.532747089490294 0.249604778394569 0.842479047023226 0.224347223634832 0.648556678132154 0.635444307425059 0.311500842159148 0.0140855582687072 0.980513104444835 0.767453024531715 0.45873189258622 0.241160579975694 0.103866438975092 0.361998187324498 0.60734914488392 0.260320758752059 0.300328515579458 0.461838228290435 0.724342180469539 0.515987817526329 0.0958699828176759 0.595837335614487 0.817336424416862 0.0968886881275102 0.753691288172267 0.156658664257266 0.540834127764683 0.82212509940844 0.176597942546941 0.615944492444396 0.648916345911566 0.275947815913241 0.840272077962291 0.422585930656642 0.16170118547976 0.710245939348824 0.683503049425781 0.395033162934706 0.458659759184811 0.598653524657711 0.169219723392744 0.39425673171645 0.0794145311438478 0.991035751197487 0.854621240538545 0.420329971089959 0.0890757507854141 0.0474593183770776 0.335176232564263 0.374516705640126 0.568388331746683 0.526923471221235 0.734450301500037 0.389151920003351 0.567927127457224 0.884916753727011 0.874331923206337 0.3848550586286 0.192304687593132 0.127793008238077 0.869690081200097 0.880829208297655 0.697349476031959 0.545614129414316 0.2394080478861 0.100469644279219 0.546448694474529 0.248357886373997 0.356946395759005 0.600318468394689 0.433370345083531 0.16138891589595 0.528771425515879 0.85100585955428 0.907359354475047 0.742264108296949 0.274614154053852 0.427961614655796 0.994865040886216 0.307374580635224 0.256188702860381 0.0446857273182832 0.988651676818263 0.668203076233622 0.395479674544185 0.733281830293126 0.638998156501912 0.947738844265696 0.987440591030754 0.823939365094993 0.171497005117126 0.0862947523035109 0.801625279081054 0.258668303631712 0.0785532504017465 0.816865545252804 0.900405414057896 0.346885753138922 0.0188634810177609 0.0502841883688234 0.622604506423231 0.866862764426041 0.813916933999863 0.933071564952843 0.229705530523788 0.748839589923155 0.325538274066057 0.475681195056532 0.576668034708127 0.411540750779677 0.688859977910761 0.609202147179749 0.547994322825689 0.840734370453283 0.286614519250579 0.997218729064334 0.51785950987367 0.558522621265147 0.677415125651751 0.899949945819098 0.906835088664666 0.371303018543404 0.666250491396058 0.101174633372575 0.862962846055161 0.395933621928561 0.971427520595025 0.911595561464783 0.838205187015701 0.412225220324472 0.13044117490761 0.695479917444754 0.223107933350839 0.969186570418533 0.983354205028154 0.546255214270204 0.971173449163325 0.727898476559203 0.364349252847023 0.712638789874036 0.341097035920247 0.874299936627503 0.113050427499693 0.60564386139391 0.877377108715009 0.418398003072944 0.830231696267147 0.960633327336982 0.267625937939156 0.965590819935314 0.405509321053978 0.130612596038263 0.218844413908664 0.233902924607974 0.396149686521385 0.094860720958095 0.151213888796046 0.991152757180389 0.010496573029086 0.537618869794533 0.586061179670505 0.221349326372147 0.399945578495972 0.242026941911317 0.0716163501003757 0.109792432552204 0.222413417131174 0.177751608819235 0.864653119463474 0.735739035918377 0.889139984818175 0.0325675173406489 0.607980614334811 0.531585178149398 0.891299232288729 0.304615823323838 0.678747943181079 0.798284258344211 0.0281566803972237 0.0138438387657516 0.517148121574428 0.603622094506864 0.277669014667627 0.581263022965286 0.809150279588066 0.523835205286741 0.785283836168237 0.446151092078071 0.0505195003678091 0.776093870257027 0.85611839447869 0.386468075721059 0.59455887399381 0.287115661988501 0.164416344426572 0.114434571445454 0.772139404430054 0.560524688039441 0.700687651678454 0.458164499558043 0.755491611463949 0.127603537160903 0.936296836175024 0.158039881053846 0.218470321292989 0.82274204951711 0.980744709735736 0.914884440498427 0.102201753170229 0.609846733596642 0.0959172759042121 0.0436798337893561 0.345659322580323 0.552018872888293 0.759719437158201 0.448591911292169 0.319744043461978 0.791607631600928 0.571314539094456 0.708747444807086 0.161889825596008 0.397544548134319 0.204260683855973 0.42723375396803 0.284874466327019 0.0983923270204104 0.229882763079368 0.0387498488789424 0.781117819214705 0.901721544831526 0.21337037663674 0.861689534548204 0.389353625222575 0.165500771715306 0.136823101646733 0.660812650367152 0.244779636319727 0.172853082637303 0.721891916652676 0.864375545782968 0.870248560241889 0.10354410773376 0.37895816182252 0.54656437184196 0.05066271815449 0.822322582055349 0.0903811864810996 0.397223610740621 0.0986701021599583 0.765919716991484 0.527754712668247 0.120037394291721 0.581354113800917 0.716149256106 0.627401933588553 0.407864817753434 0.845753221390769 0.246570024038665 0.244587263679132 0.0830261731497012 0.819552937196568 0.315529699157923 0.426123431124724 0.632806825921871 0.338277753535658 0.798209257032722 0.722613508137874 0.45716646177927 0.544979540575296 0.966597771700472 0.64202176699182 0.102338011399843 0.385850413360167 0.291073950696737 0.630409648176283 0.408935238798149 0.285391420603264 0.656403128439561 0.229226936216 0.329418203274254 0.976457047017757 0.76925208974164 0.21233314746758 0.163079512929544 0.634999561924487 0.430055172417779 0.133735297869425 0.164781506229192 0.463920048873406 0.183998923806939 0.911974750026129 0.0692693879804574 0.933392252482008 0.268195202415809 0.0567776026343927 0.421540935402736 0.829214096216019 0.490114585952833 0.922097683828324 0.337121383240446 0.502907771083992 0.0481503865122795 0.76478747936897 0.104965567702893 0.969460458366666 0.0576928103202954 0.153907527583651 0.55835565067362 0.987406743837055 0.946529722819105 0.127092231805436 0.245084554261994 0.161063125275541 0.140121814601589 0.711941279429011 0.23722247451311 0.634324234563392 0.121483070375398 0.940544725714717 0.965507961029653 0.532426427085884 0.0681617163750343 0.182981885490008 0.408426713070367 0.0224318420607597 0.772403435406741 0.651318064092193 0.61507670807885 0.411121408019681 0.954894974878989 0.587094594947994 0.733053702129982 0.707489428513218 0.187303799472284 0.0286263786978088 0.325670186635107 0.907924528457224 0.554158348098863 0.484392524247523 0.838652564622462 0.932169316108339 0.170349329831079 0.989602608908899 0.2647097424604 0.891117532597855 0.411036305634771 0.366360474943649 0.98241972734686 0.260769111614209 0.421497783060186 0.476368090407923 0.0372347173700109 0.150221827481873 0.400873973912094 0.998517596826423 0.908539721907582 0.835411119512282 0.728131929556839 0.891934337222483 0.055173028842546 0.887968407131266 0.179680272815749 0.480450173623394 0.399759788771626 0.758581443661824 0.0546649048803374 0.550938724644948 0.234114316687919 0.388474353773054 0.605113577628508 0.541454130876809 0.497613980646711 0.736717347307131 0.798419917037245 0.728297641375102 0.5698631449393 0.914489089113194 0.188369740704075 0.850085034526419 0.176729421310592 0.0717961983964778 0.432975862461608 0.316664113183506 0.169385321803857 0.108905044423882 0.330647195866331 0.233865760485642 0.299773069487419 0.70262521560071 0.352847725364845 0.452219355385751 0.375676083990838 0.855714186502155 0.0808585939416662 0.764852105309255 0.853356529304292 0.0832664229697548 0.0281030842242762 0.555096536176279 0.849783576193731 0.163318805473391 0.368289167522453 0.766121078992728 0.943381766229868 0.709431195876095 0.0938902012398466 0.440618448203895 0.745984913213179 0.57721842081286 0.174784933328629 0.627191916455049 0.511610014333855 0.495265931938775 0.373296485275496 0.425877252323553 0.0266104296897538 0.901567451022565 0.417329139532521 0.486046282397583 0.966606766823679 0.238129682615399 0.812355541363359 0.912168661269825 0.242678310859483 0.593014966112096 0.135350486524403 0.143490215558559 0.930499828248285 0.335693405817728 0.877916173927952 0.122098922601435 0.970933683859184 0.890985265055206 0.770599153928924 0.261024058724288 0.352853481008206 0.472619398857933 0.215978711810894 0.310574266789481 0.202321697734296 0.955842363457195 0.242266683012713 0.188978432144504 0.240266226297244 0.0398869507922791 0.139074942367151 0.535253244822379 0.201312926383689 0.39980642584851 0.995916492510587 0.478860543067567 0.0113047630898654 0.399118830231018 0.0309971752204001 0.177987790734042 0.799111279754434 0.2053033833066 0.717086612069979 0.0275441912002862 0.0595617354870774 0.95300216160249 0.188480023164302 0.755509987340774 0.20671949562151 0.307265791599639 0.79097557967063 0.173493034574203 0.716142533505335 0.351972935572267 0.579349609925412 0.893116271840408 0.874463700470515 0.872253035765607 0.1419407705497 0.691281330280472 0.600219514202327 0.874715790273622 0.657485907175578 0.83365630452754 0.0768696311349049 0.959049182967283 0.81996437695343 0.402418056284077 0.498071642576251 0.451441649028566 0.177147863036953 0.281371860916261 0.948364176361356 0.253915172331035 0.317653656951152 0.42587042138679 0.43029093274381 0.0994295292207971 0.554277673396282 0.720706350009423 0.556658172914758 0.516414788300172 0.653809518907219 0.0484807475330308 0.472902656956576 0.363916830462404 0.383830022341572 0.969055762416683 0.260703791400883 0.281687049351167 0.262499167190399 0.0710304235317744 0.191287658957299 0.0410429723374546 0.737679289111402 0.285148157887161 0.810042820596136 0.209972320632078 0.177068845452741 0.330573292206973 0.180749234550167 0.980770082280505 0.153804037335794 0.295538811625447 0.996872839562129 0.69005186193157 0.198288870332763 0.471583865494467 0.222471671756357 0.914295542293694 0.72602356686024 0.92548856245121 0.159537908597849 0.913074067996349 0.09053683756385 0.939655993757769 0.765188806527294 0.669552989199292 0.878673092892859 0.877976084251422 0.659543649945408 0.301182532270905 0.686808081602212 0.714722052479629 0.469110840263311 0.548407606831752 0.487359754557256 0.360803377537522 0.410735087946523 0.214518995829858 0.374971311800182 0.309651358711999 0.790458816019818 0.0402805847045965 0.762082591836806 0.305915936259553 0.412564675584435 0.61002863382455 0.96704774776008 0.978749051387422 0.320607705523726 0.949414737785701 0.540357285274658 0.720148253371008 0.309146538309287 0.293824022219051 0.822543628725689 0.532565751688089 0.96057385773398 0.24121486535063 0.328992235185578 0.227578562139533 0.0986043308535591 0.736869978578761 0.574708123584278 0.795055673881434 0.88095821699826 0.356870156188961 0.855756232663989 0.550350216911174 0.146822835176717 0.0544201240758412 0.90131914952537 0.872847282777075 0.376964306002483 0.587917302506976 0.30118570651859 0.239511506785639 0.446176584253553 0.369442352505866 0.129298047202174 0.432492561526597 0.333651506626047 0.339500614765566 0.521487445167731 0.0878458059881814 0.315250055796932 0.724281122935936 0.409213297225069 0.200064397796523 0.846926656926516 0.365039371082094 0.0269923165114596 0.0667477763141505 0.811440597141627 0.563978296029381 0.0462965343543328 0.64629554171348 0.57833527678391 0.0723326361132786 0.587941196379252 0.324381941342726 0.189493545859586 0.748149833576754 0.794867594807874 0.433157189891208 0.92592576314928 0.0397234962834045 0.0443297210684978 0.448794905019458 0.785130464062095 0.700708677410148 0.318760085918475 0.387168406131677 0.104674121469725 0.367092245873064 0.997697471585125 0.916811961203348 0.917483511783648 0.0625588451232761 0.422382918719668 0.308663655736018 0.292803641848732 0.951274316313211 0.701636380627751 0.0472682526847348 0.746346948712599 0.896560505069792 0.618199469610117 0.410618366173003 0.0314398925309069 0.166605370033067 0.485161504247226 0.0243240161542781 0.604696100093424 0.903988404162228 0.955530581616331 0.258731434994843 0.921568070363719 0.0221328475675546 0.233189360827673 0.677838723715395 0.88741444662679 0.356343196958769 0.264568281101529 0.0228776628547348 0.700799349884037 0.0437940790457651 0.656804875342641 0.887706337498967 0.367653762013651 0.555868623808492 0.376302889918443 0.56931169598829 0.124918201067485 0.17807362473337 0.656136420639232 0.248469808627851 0.569330437672324 0.329764322126284 0.381371091636829 0.154020578607451 0.671412407527678 0.351619932076428 0.590737454576883 0.615738431422506 0.249582051325124 0.889798422812019 0.39979766122764 0.274454011402559 0.622051752137486 0.290439360935707 0.150780854427721 0.786977386167273 0.408731752717867 0.920166840662714 0.980609764447436 0.561557001285255 0.385836237696931 0.758588597993366 0.124677421783563 0.950669328814838 0.641717758842278 0.852171579024289 0.207918914302718 0.106935144942254 0.313121978004929 0.431486972030252 0.667568016247824 0.577422009005677 0.0237112054065801 0.980758161852136 0.561406614414882 0.112824444852304 0.44012658549007 0.394532676667441 0.140585645695683 0.401070843192283 0.0605447749397717 0.722627035628539 0.3425325712841 0.56254682995379 0.517696049832739 0.317552862658631 0.252943948197644 0.705255519952625 0.228711220889818 0.705107573410496 0.449375634451862 0.752504335287958 0.487615499205422 0.464538989139255 0.822563498257659 0.660018710652366 0.361306964983232 0.681017913140822 0.420892181964591 0.171055630482733 0.88266135543352 0.728575839255936 0.926714279374573 0.737353669523727 0.0924498285539448 0.286299049833324 0.837970729027875 0.591286180603784 0.589950168081559 0.622942044595256 0.810719752714504 0.869207105964888 0.561776154378895 0.359929876253009 0.387946062700357 0.871257445691153 0.857858803758863 0.753185159899294 0.890916559454054 0.922653719775844 0.404599598632194 0.283805880080909 0.630363946477883 0.749905223664828 0.0882278898893855 0.622366114221513 0.661452898499556 0.177590751149692 0.576074489115272 0.19845066729933 0.811237112905364 0.398421355283353 0.706298702075146 0.0223219991684891 0.23003218437545 0.259281881260686 0.376572260020766 0.360971837865654 0.188919108910486 0.156219519502483 0.638278784523718 0.154208659525029 0.0249265225254931 0.453556011701003 0.277921610192861 0.841239267152268 0.379449362764135 0.0408900835947134 0.565334981845226 0.553040623364504 0.40958205094561 0.489109740979038 0.0879724727850407 0.402654190945905 0.438640938918106 0.435075798914768 0.809936987522524 0.427895087993238 0.250579480808228 0.68895385667216 0.509852343886159 0.27094917910872 0.944860473298468 0.947806392745115 0.664320108313113 0.814626732754987 0.691609820083249 0.571363466442563 0.720720017645508 0.416234970984515 0.177348531917669 0.133178798151203 0.350169850171078 0.311742720478214 0.622658462179825 0.849743947079405 0.047628027186729 0.230845764041878 0.479591388991103 0.131221408031415 0.601098298369907 0.254966919689905 0.132464559229556 0.195763882498723 0.786575247179717 0.579866622288246 0.64389049761463 0.460464181269053 0.669310188870877 0.839335128373932 0.885108395214193 0.03750542138936 0.0907152569759637 0.119108313822653 0.702324735058937 0.74145810178481 0.904660183170345 0.658009244522546 0.442156162718311 0.155903261075728 0.114455251423642 0.590476689357311 0.970337708541192 0.998671775921248 0.205934718605131 0.582392939198762 0.540000632926822 0.258498318761121 0.795244853834156 0.719616788281128 0.0684931545332074 0.0305241099721752 0.0827725922269747 0.409228025402408 0.0529391115228646 0.430999633616302 0.06564068880165 0.795191527118441 0.702577640379313 0.847424130528234 0.939567357080523 0.265435493360274 0.619457638035528 0.374465996969957 0.762964798964094 0.116521094737109 0.637306381370872 0.629168444261886 0.210313266089652 0.330060578482226 0.169587948571425 0.0428450107970275 0.733726182095707 0.727985665912274 0.704723401388619 0.62926484517986 0.517463382156566 0.0909280150127597 0.536014833764639 0.110626907716505 0.833509829742834 0.646296631759033 0.312037896700203 0.63154253304936 0.636180836844724 0.401378032043576 0.966846732434351 0.0827890056069009 0.762171801773366 0.475419403410051 0.596570044457912 0.173381417274941 0.247119989015628 0.985736761088483 0.255480580779258 0.568731891792268 0.76129770164378 0.922010180992074 0.686241962560453 0.952349348326679 0.510857904108707 0.760844130439218 0.989750754374545 0.254423841200769 0.232966894262936 0.877774912875611 0.382900605800096 0.565477772741579 0.803704308741726 0.299939812112134 0.283639598460868 0.412289924866054 0.0971709933294915 0.169030159884132 0.804100315445103 0.376885197830852 0.802561887525953 0.110243917249609 0.433291954465676 0.322186904235277 0.504425935081672 0.188562469240278 0.17219099072041 0.789028924044687 0.624437825893983 0.248388141880278 0.544501351490617 0.145942681825254 0.120314621296711 0.802483832519501 0.896052364511415 0.977998899049126 0.721733792740852 0.922433399648871 0.378134270864539 0.976936268291902 0.971825155797414 0.78198659358779 0.362873075311072 0.18395428633783 0.486606477990281 0.126129193962552 0.787011603086721 0.790487837186083 0.495098699035589 0.282762313710991 0.162693593699951 0.932175194609445 0.987629401949234 0.0875570444157347 0.911277468469925 0.288339201586787 0.72278919494478 0.348345114837866 0.554506983114406 0.208925627728458 0.412807826737408 0.43858821865404 0.310123081053607 0.951119053165894 0.889329476871062 0.638226473862305 0.743925969295669 0.5600412264443 0.162924921466038 0.78718188668834 0.573094160740729 0.904967835561838 0.772635266820434 0.711461615129374 0.345486106066965 0.953732180483639 0.25094453335274 0.138548936264124 0.0650983283272944 0.17335509874858 0.216333343575243 0.944522381229326 0.588436500031967 0.995082733978052 0.815148914363235 0.112967716346029 0.801098183162976 0.828171886813361 0.919346689605154 0.380377510851249 0.968565596430562 0.512412494390737 0.987711014989764 0.694116308260709 0.960991030314472 0.059024387516547 0.779764992699493 0.625463792949449 0.056639877257403 0.559298049798235 0.637938114746939 0.963350684815086 0.231265493584797 0.904612829000689 0.0860688164480962 0.476345214203466 0.886658808332868 0.529352265819907 0.217391245116014 0.770689169010148 0.0253935631341301 0.260895474378485 0.367072298200801 0.0995371553720906 0.760051401322708 0.37506734137889 0.802697226512246 0.351261081888806 0.252029028870165 0.171690452820621 0.226368641080335 0.354203888401389 0.888653966952115 0.977626898703165 0.19661013471894 0.819346763228532 0.305090538968798 0.7591053143912 0.0624567800713703 0.329916413100436 0.213976782876998 0.945303159721661 0.173148323399946 0.0368544415291399 0.58919156345306 0.159737188701984 0.892881514891051 0.469114928683266 0.81013795029372 0.827118400314357 0.233976486201864 0.311806508312002 0.803582394672558 0.37313819747651 0.356932859739754 0.0520516913547181 0.869187032668851 0.140791964188684 0.82381195331458 0.852411772140767 0.788557132321876 0.477320473741274 0.543320690628607 0.78195553339785 0.423417618586682 0.78585206799442 0.421762643153779 0.360999572137371 0.936186115990859 0.347445076741278 0.89292993651703 0.591163622280583 0.146980951712467 0.781857887767255 0.371868396750651 0.527989475149661 0.0987919189571403 0.760234596973751 0.349059254643507 0.579910878967494 0.725140494427178 0.695680712640751 0.721426500163507 0.734698524165433 0.413498514774255 0.222458302159794 0.0108389552077278 0.13558365853969 0.727895409725606 0.446298307466786 0.932615158569533 0.0231220504222438 0.0640264389826916 0.951630413841922 0.20793995663058 0.0429696971178055 0.200413497735281 0.347953922636807 0.762176144898403 0.23629531113198 0.541633880056906 0.603755628198851 0.619561007730663 0.531850933744572 0.967628049380146 0.828140310067683 0.974592309156433 0.460362990051508 0.901178043140098 0.838681674993131 0.875586608280428 0.980877872318961 0.968233702569269 0.215569450762123 0.761960587410722 0.646383305247873 0.36679495963268 0.612708139130846 0.246054946281947 0.171005412782542 0.0401837824820541 0.966826243312098 0.357704201235902 0.928667711077724 0.232170850983821 0.585149429519661 0.928783838616218 0.559618281854782 0.210837607735302 0.792122355306055 0.0134941959939897 0.229185065696947 0.105866989505012 0.337975221753586 0.589841210779268 0.592388940204401 0.479046346161049 0.789935261309147 0.966814678779338 0.785203932072036 0.689295075044502 0.959863756790292 0.799845945793204 0.489543455329258 0.515159603497014 0.187516517862678 0.0956235647550784 0.0920678633614443 0.734944627131335 0.628174467703793 0.913763339365833 0.814558773981407 0.51335446432 0.298503370643593 0.101184725456405 0.791554709877819 0.750834899060428 0.566611195146106 0.383077340009622 0.109228876926936 0.647630274947733 0.121102568872739 0.611548762163147 0.280743601210415 0.415971946381032 0.602779252799228 0.971956708782818 0.0759097772208042 0.368745125117712 0.887335160276853 0.791950102753472 0.220295088435523 0.691002074854914 0.561106989728287 0.484398525836878 0.177436562143266 0.366336907693185 0.963001490600873 0.0946692269924097 0.905876652109437 0.848958649588749 0.442821397073567 0.877274186424911 0.0786808281438425 0.597410752635915 0.8801787871751 0.890640153498389 0.680692438078113 0.513197808016557 0.915174858230166 0.303802025371697 0.161003103619441 0.784553045795765 0.513188949581236 0.243627774419729 0.157168806728441 0.618658900645096 0.520370442136191 0.37532204991905 0.304364792448469 0.182200161246583 0.0127728403126821 0.399634401954245 0.636651808670722 0.531191162064206 0.469414099049754 0.9762275565858 0.592036287763622 0.580132559519261 0.786304652187973 0.383647706748452 0.25195838497486 0.633450820408762 0.461156363652553 0.662991099834908 0.0966840824973769 0.219329631701112 0.792544994940981 0.360937657365575 0.804506875697989 0.264903735762928 0.470123724236619 0.720824267629068 0.318572917098645 0.681989713530056 0.987216978408396 0.841971636004746 0.491621317956597 0.144201090068091 0.873600288042799 0.998608256161679 0.542550621735863 0.739765813325066 0.574158821071032 0.657646236764267 0.504109003127087 0.507491479248274 0.458608119515702 0.307953227018006 0.777342648478225 0.292179243979044 0.955838310765103 0.65624771892326 0.965900386187714 0.385236067927908 0.586719070221297 0.483484367397614 0.170723666318227 0.342029856750742 0.427566385206301 0.90197443516925 0.96219551820308 0.494678135535214 0.867865487164818 0.526198668377474 0.444744359825272 0.105704688890837 0.720412270517554 0.909210356932599 0.603281634948216 0.790474022950511 0.234472604910843 0.255895750063937 0.919350313793402 0.186618849330116 0.713597289356403 0.537048980656546 0.25268917119829 0.27675601473311 0.43374117862666 0.143428163176868 0.0847327191010118 0.373636687824037 0.52615797134582 0.41079586080974 0.572520291057881 0.754975320573431 0.795623603749555 0.954667073760647 0.872655502988491 0.314843489781488 0.0150081904348917 0.749071179309394 0.624961560165975 0.0285487471241504 0.576957941185683 0.323127441362012 0.722226197135169 0.786081973100081 0.67593462458346 0.845224609919824 0.3177395126177 0.952023284561001 0.0282464285567403 0.0780173923983239 0.581485765210819 0.0602308927616104 0.724977294392884 0.455769255957566 0.83106696159346 0.901317261941731 0.0739237215998582 0.621538143141661 0.44830140089849 0.632579083389137 0.269650690061972 0.612267307790462 0.372483069957234 0.307451150284614 0.440395058938302 0.0492659316165373 0.833303621890955 0.380442841898184 0.497844401386101 0.0406131650018506 0.151435882139485 0.804864757775795 0.350694964691065 0.533242026413791 0.0308719052677043 0.735428776084445 0.30023276905762 0.848772205929272 0.155701449133921 0.125118960766122 0.33043987238314 0.845949951217044 0.0578601782978512 0.335629909569398 0.869700786881149 0.0235042677843012 0.476299509508535 0.910035839970224 0.18456683892291 0.190209366718773 0.794459698102437 0.236051384569146 0.820334810805507 0.177088992048521 0.445807603257708 0.351014469743241 0.757898652865551 0.713914220849983 0.917273655079771 0.365641773957759 0.0372177770617418 0.8267693497031 0.828633921141736 0.0466804484440945 0.894270283866208 0.133873626010027 0.377725914306939 0.802477057594806 0.036009352884721 0.0410198167641647 0.449136742060073 0.894723962484859 0.283967070826329 0.831797092268243 0.674397311373614 0.874827595893294 0.318753184217494 0.809648361485451 0.85545978130307 0.791843687200453 0.916124568427913 0.985948598959949 0.988934235342313 0.369989272546954 0.44261919350829 0.186854065670632 0.293224130205344 0.953441777043045 0.888614375870675 0.0894827856426127 0.912695825877599 0.0913177559711039 0.616028383539524 0.16882450500736 0.134035425051115 0.592855862334836 0.250308717319276 0.193930001063272 0.371992670702748 0.393683840285521 0.079019510759972 0.813599665511865 0.759868786998559 0.660574189936742 0.682431224160828 0.455841912829783 0.288031101790257 0.430519006969407 0.527114240487572 0.29755926257465 0.512118244788144 0.618108976467047 0.780178335483652 0.976499718071427 0.797272139869165 0.152417619023472 0.0441190861887299 0.358261865912937 0.30724748740904 0.225572383434046 0.428282764111646 0.197894511951599 0.231702471387107 0.101311992942356 0.499063586795237 0.606798299618531 0.856992678549141 0.415813898765482 0.76926085136598 0.489007448651828 0.114831008957699 0.365191935047042 0.0854252479295246 0.819197987569496 0.358157923880499 0.299510487448424 0.133068362637423 0.449003609903157 0.748340680061374 0.549890353453811 0.835169274385553 0.160678080110811 0.757062628034037 0.439707121716347 0.576762205285486 0.123008458777331 0.651420970938634 0.383193298589904 0.29529391925782 0.364233576632105 0.6014978571143 0.288985525991302 0.384841219268274 0.901278003244661 0.949508120275568 0.882634074098896 0.856652066167444 0.227909455390181 0.933308182978071 0.135271800402552 0.514741924502887 0.719712729807943 0.874953154204413 0.619718379282858 0.887158865865786 0.536193817215972 0.0432248800317757 0.811056687200908 0.765124314278364 0.0628689519036561 0.216051017858554 0.106986812271643 0.247677006672602 0.535171265513636 0.661348829921335 0.803244849815965 0.612966296446975 0.334734632268082 0.37129947272595 0.604190145388711 0.740743081460241 0.0134808529051952 0.135664502624422 0.0785070900036953 0.167012279035989 0.194355780370533 0.0229414741997607 0.617896709169727 0.673245557118207 0.046908171614632 0.635825967662968 0.652374605899677 0.724411862017587 0.436581081750337 0.178545128789265 0.699126243137289 0.145201794528402 0.796389123448171 0.678977700765245 0.772000959424768 0.714149474531878 0.758606429423671 0.161872760355473 0.73494474791456 0.441558061016258 0.785063362065703 0.852771182449069 0.0467561156768352 0.360010731401853 0.547569456307683 0.697337223680224 0.516399416099303 0.0357049782364629 0.723099399458151 0.460053879041225 0.796159561790992 0.123193428835366 0.279989341781475 0.350460401594173 0.756773421822581 0.648456308885943 0.745838989790063 0.580108298917767 0.972294084220193 0.772777666784823 0.159974021094386 0.767587634439114 0.187883324760478 0.894453307101503 0.75575640033232 0.580873168599792 0.825447463977616 0.565101243716199 0.341526999997441 0.727156106440816 0.801136832181364 0.549705346054398 0.287648561724927 0.485530064806808 0.436236912487075 0.739447174270172 0.473284944852348 0.394212567238137 0.717847387338988 0.790731137474068 0.550882315651979 0.297388856115285 0.291914909661282 0.335184231225867 0.472774123321287 0.122267392149661 0.22264756440185 0.597883972090203 0.671676203852985 0.263402470583096 0.139693092009984 0.833979943869635 0.829172722199 0.472776839330327 0.374007618639152 0.156610783620272 0.727094266121276 0.0693040073569864 0.0943206606665626 0.504829848706722 0.580695758787915 0.379365171324462 0.775071303341538 0.982650374209043 0.0276947101484984 0.322347610003781 0.0529276862135157 0.500953784561716 0.289854967207648 0.987151230382733 0.343588228423614 0.0923509635659866 0.840996661828831 0.631837316495366 0.363072805816773 0.153739150236361 0.998725515005644 0.846450910244603 0.500294921982568 0.168284449556377 0.0247516360227019 0.689033490619622 0.150749754591379 0.749350794318598 0.140837758318521 0.6124727817229 0.399904671707191 0.724944872395135 0.0428684190008789 0.829608872267418 0.0130353462859057 0.0426281643402763 0.744549693407025 0.398514046496712 0.510384028183762 0.522148294216022 0.682759616000112 0.69062804147834 0.617465686856303 0.947542843518313 0.135204841778614 0.0141069979825988 0.578413152920548 0.765421815116424 0.720412012124434 0.0226926589128561 0.373541165119968 0.0330701147788204 0.109026843011379 0.175313310378697 0.653738086463418 0.685480122601148 0.138803404620849 0.921402625697665 0.465902597862296 0.54277620861074 0.33814661337994 0.223361064333003 0.159922796329483 0.0224722664081492 0.545210384977981 0.941759405264165 0.845368380220607 0.955149936280213 0.0841212763846852 0.922703042665962 0.132468728094827 0.05744535200065 0.167608906445093 0.652147880112752 0.512902306786273 0.707049046882894 0.0509577392484061 0.373076993573923 0.482358216189314 0.321366811494809 0.297867688301485 0.800327695216984 0.331800923452247 0.803114955986384 0.372943453888875 0.908833404704928 0.305546550040599 0.613549908541609 0.588108932930045 0.839588094316423 0.101451336676255 0.692903897084761 0.178322369025555 0.864174708866049 0.81630940143019 0.627811093677301 0.426843317353632 0.675113486514892 0.445506223987322 0.457420244622044 0.861865930841304 0.485836068876088 0.826518293472473 0.0249682125612162 0.843671436305158 0.189245618698187 0.764302395037375 0.207476180396043 0.86118943391135 0.542251997198909 0.577875654892996 0.252554327331018 0.0180887013487518 0.587337761544622 0.977860317586456 0.271599474607501 0.543117015075404 0.611921950518154 0.285411508190446 0.0175714660901576 0.320321844362188 0.0136550278472714 0.026994986650534 0.06926752229454 0.398271550892387 0.323255876572803 0.622947787330486 0.665741888219491 0.460109201446176 0.497428039021324 0.558560689417645 0.358329709896352 0.822570508294739 0.520501663428731 0.763515570699237 0.515874033505097 0.802977124808822 0.169071174087003 0.650128642527852 0.678055784308817 0.825479126700666 0.195734273320995 0.782261557290331 0.839131217708346 0.658387440310325 0.444536462391261 0.887351464859676 0.466197534131352 0.611009283890016 0.954259894378483 0.496619053496979 0.834557199631818 0.785665070668329 0.330477167891804 0.575670010528993 0.935326207659673 0.925046784898732 0.68588255409617 0.800941330241039 0.904176189806312 0.306421268838458 0.663326031025499 0.879848376826849 0.0258046608255245 0.751870560813695 0.338484018091112 0.506766879707575 0.43436610734323 0.733652351505589 0.479417202754412 0.418669095719233 0.802706781064626 0.27504438781878 0.408910701132845 0.472157676168717 0.900320583204739 0.446680298936553 0.995918859078083 0.622499129283242 0.264277167483233 0.968708303654566 0.628129614253994 0.620824015322141 0.66786019801395 0.45294032566715 0.857642024839297 0.937127708818298 0.0292907788651064 0.659016538353171 0.722395653924905 0.419712158902548 0.42849770154804 0.59767443532357 0.83107072500512 0.603950974780601 0.674369041644968 0.79552325778408 0.385005367819685 0.348560546701774 0.345011459111702 0.284888212794904 0.738344447400887 0.504242900782265 0.670151177339722 0.674315241707955 0.103642051173374 0.943184569175355 0.913573531755246 0.752690885670017 0.319348856655415 0.513129118089564 0.259031455223449 0.459417897737585 0.240118258087896 0.791806201988365 0.0259306808328256 0.651064204953145 0.318957215666305 0.279402918019332 0.236771118205506 0.829294435270131 0.699832384281326 0.966980304389726 0.280499644912779 0.861942644554656 0.0292039295029826 0.265730661975686 0.712882842060644 0.427730604291428 0.490039193017874 0.271188580910675 0.526412683804519 0.558641048986465 0.981051804542076 0.961240318131167 0.101188157175202 0.30453568181023 0.715144557270687 0.227487845178694 0.75597925275797 0.901718938311096 0.452720732775051 0.625783411639277 0.972144288357813 0.1640646886779 0.0634380981326103 0.647861097913701 0.811405666817445 0.40082145902561 0.694129599025473 0.950090283663012 0.294885630006902 0.866320624081418 0.577442705580033 0.035798336523585 0.650847323921043 0.515469333867077 0.283548658143263 0.396121065276675 0.144717236203142 0.0213910477119498 0.992215920859016 0.287826000580098 0.538570724355523 0.861939275762998 0.622325467900373 0.979301380626857 0.542802969932091 0.0885065831197426 0.417729462622665 0.153794743942563 0.523481903751381 0.329764842139557 0.397548253689893 0.892008305422496 0.875079564221669 0.464070107047446 0.798834480331279 0.808029565468896 0.299521548103075 0.791363706651609 0.294253972235601 0.978361076076981 0.627859064671211 0.110072923239786 0.206088957630564 0.107929639439099 0.792947988170199 0.414274676996283 0.436685492855031 0.585147222920787 0.582965678959154 0.767323358899448 0.124181246832013 0.517175098876469 0.884235620012041 0.193179993710946 0.234178693916183 0.657480143464636 0.0574803547025658 0.879729298858438 0.845474483903963 0.703593867789023 0.590410395963118 0.601137069324031 0.227428871616721 0.898033696217462 0.249267339799553 0.170339284539223 0.126471440605819 0.0487582004303113 0.0957781230262481 0.925573971634731 0.662860241122544 0.919068725684192 0.659247686327435 0.829723504306748 0.911571108624339 0.401755944313481 0.0359110676101409 0.538228387816343 0.0916369164222851 0.362657226468436 0.696222875805106 0.414694293362554 0.983264658097178 0.348271227774676 0.202190870831255 0.226278461881448 0.718680616177153 0.560560120628215 0.841278823888861 0.577677802750841 0.316662374043372 0.900801847651601 0.580456373121124 0.362677799954545 0.521127021801658 0.741613024249673 0.649222701266408 0.833324625955429 0.404675822297577 0.627355163972825 0.327776142195798 0.07703212905908 0.096350202166941 0.359114887756296 0.990713052996434 0.0305279141827486 0.0975549853290431 0.832880515258294 0.287465448132716 0.109128160774708 0.680959460053127 0.17635398671031 0.648406788916327 0.245702362300362 0.0578634410584346 0.743249857304618 0.854157239564229 0.39975213609403 0.874284470612183 0.765572130531073 0.765872153525706 0.938325998038053 0.4394389032037 0.804469781417865 0.50760341348825 0.140309834897053 0.344441160140559 0.1029284505127 0.746204482594039 0.218991133947857 0.277449799107853 0.143687748454977 0.19044554771157 0.418905136336107 0.150001590335742 0.529385264073499 0.36145522800507 0.882725305771455 0.69344039081363 0.976191783084068 0.701605764846317 0.667667247965001 0.139965768668335 0.758656249968335 0.405624777830672 0.660891194038559 0.691905161805917 0.322796304009389 0.384438892882317 0.582623514835723 0.034255972316023 0.849392558252439 0.0592289841570891 0.532439547509421 0.819188016729895 0.958622300014831 0.84917978315847 0.93572510993341 0.39274930866668 0.945130461147055 0.537379181708675 0.822111420708243 0.956579362410121 0.0608767990348861 0.551355792577378 0.153709116934333 0.847794353009667 0.933764806494582 0.413635638309643 0.941665851741563 0.376982641541399 0.298363313965965 0.949904513531365 0.619557528528385 0.156498894558754 0.430579277798533 0.385630516665988 0.575561745655723 0.610923690304626 0.408669760497287 0.538298700940795 0.0840051744319499 0.535267115070019 0.922700580439996 0.778959227984306 0.173763866522349 0.08329405259341 0.275766003506724 0.594671131859068 0.840951610608026 0.595338051416911 0.311621462879702 0.0115605554520153 0.407011004134547 0.102671846782323 0.083649934141431 0.35410543555161 0.127793151380029 0.0562721953727305 0.549669511239044 0.352517898648512 0.807079375365283 0.985575797387864 0.43448221459752 0.557768393184524 0.991246372938622 0.733892029218841 0.630036941110157 0.772092789020389 0.0728915581805631 0.847742621139623 0.379585541470442 0.206697910460643 0.177322443202138 0.487811127922032 0.517442026345525 0.125051209675148 0.688378314694855 0.912072045984678 0.162714379478712 0.589602637402713 0.351640026117675 0.111903417443391 0.295659069765825 0.688362930507865 0.614387328603771 0.547829113733023 0.610172357333358 0.365126824129838 0.771110023865476 0.0424495079717599 0.937902909154072 0.619785047704354 0.50402500461787 0.774898420134559 0.562615582346916 0.746158298223745 0.0979089239728637 0.603391059709247 0.283472323145252 0.232798186375294 0.985560357649811 0.0429158607614227 0.93728384533897 0.507368228496052 0.0114206767221913 0.216835218158085 0.218964459525887 0.592318598497659 0.56558998565888 0.899859106922522 0.478478414218407 0.853698891890235 0.262832318441942 0.940943628679961 0.324280319316313 0.786770512394141 0.208563931758981 0.821098076882772 0.474198160998058 0.541512135867961 0.749503533695824 0.230711700886022 0.546820981334895 0.406803801204078 0.751529128765687 0.548883256472182 0.445667250845581 0.184799362074118 0.93530429841252 0.808044428720605 0.454619250984397 0.165119489040226 0.384025722052902 0.28235006442992 0.495699438836891 0.29094199502375 0.0820459299208596 0.389587515252642 0.307829213072546 0.165584026162978 0.960910766634624 0.306807970162481 0.600901345647871 0.246815664155874 0.717249649830628 0.781816994808614 0.200099349787924 0.810340079867747 0.456847315619234 0.110002509155311 0.78531858024653 0.762436291680206 0.0613141461019404 0.850800308403559 0.760277471791487 0.51413162576966 0.115842879873235 0.842214376633056 0.442930336396676 0.503836235881317 0.175994292423129 0.391662349770777 0.392320324685425 0.647089987611398 0.0608160814922303 0.85391250785673 0.708578448100016 0.4710544924438 0.89574014079757 0.0452384587842971 0.984765385976061 0.977977045814041 0.218340750627685 0.399298984403722 0.759483814211562 0.481286261612549 0.368447546369862 0.326588823273778 0.889005469647236 0.755639773756266 0.26035930842394 0.340289376245346 0.565928574691061 0.24982074018335 0.335701348697767 0.149034841174725 0.708526637628675 0.142212115826551 0.392495863048825 0.638285492602736 0.0596186502021737 0.863856454750057 0.149764806579333 0.0926736601535231 0.370904726870358 0.0160368836415 0.35385906658601 0.148068107687868 0.490647068249527 0.813519942590501 0.934327601462137 0.915820984863676 0.584342074799351 0.317069088502321 0.022670773176942 0.394694245436694 0.573074817445595 0.814692643745802 0.821799661456607 0.270691725746729 0.378524946740363 0.103954597590491 0.934306464397814 0.0364823293895461 0.103371007854585 0.56931492486503 0.188775646791328 0.641683814607095 0.265132321934216 0.646426578373648 0.720674513026606 0.0698397600208409 0.148522908622399 0.0725755447777919 0.84329820438521 0.583580041218083 0.275506613233592 0.661001917219255 0.674591591190547 0.795466438266449 0.964099983142223 0.98054878551513 0.98121640994912 0.855302064919379 0.401938269357197 0.938719852310605 0.93754231729079 0.0513549669226632 0.260820675217547 0.615877395058051 0.924804013383109 0.257965896164533 0.840707856691442 0.169193761914503 0.959438446785789 0.244203924923204 0.339431810278911 0.226137052385602 0.650558488818351 0.865124588713515 0.620622420052532 0.687482066978701 0.682028294780757 0.715984979856294 0.294504860660527 0.481919774005655 0.772456674301065 0.2865127921151 0.271904030891601 0.677898777641822 0.701571250578854 0.160114715571981 0.334846672769636 0.948929498095531 0.431286763462704 0.535491645091679 0.566296451580711 0.41463829604676 0.697421469287947 0.095833905513864 0.153599576922134 0.262046804970596 0.42689115304267 0.582915372285061 0.97173147480702 0.896216868727934 0.557299888425041 0.416460335655138 0.890687330642249 0.100502136119176 0.269150603255257 0.453830836641137 0.685552274442743 0.103365789051168 0.0891612175945193 0.224259193870239 0.383089377994183 0.583413973043207 0.701412844071165 0.399246679504868 0.778173354698811 0.810626071954612 0.354486094717868 0.949032244051341 0.109421833199449 0.933439182757866 0.635757257221267 0.142293423912488 0.739055085184518 0.675057594538666 0.08882917920826 0.212400928984862 0.508662942836527 0.117819453780539 0.07414932184387 0.166595354937017 0.66196336229099 0.2553367537749 0.851901703199837 0.144837422887795 0.402323610025924 0.781482905412558 0.554757756057661 0.480436180979013 0.760461401361972 0.48217695744941 0.937518749118317 0.333619081862271 0.319110820579808 0.97736642714357 0.528247156708967 0.761000339107122 0.810512328732293 0.198486714407336 0.497644715136848 0.407658855156042 0.193052808975335 0.634131836106535 0.193478719438426 0.15556614080444 0.066258096457459 0.95824964965228 0.914357458679006 0.147277366654016 0.777819629730657 0.184767988862004 0.337020988177974 0.444060765728354 0.0514955175668001 0.45315583958989 0.684686731251422 0.432361070315819 0.399705690103583 0.831568450545892 0.488560190214775 0.0687292573857121 0.542319831270725 0.908997330821585 0.496964833971579 0.574465317493305 0.653992438646965 0.368360880487598 0.80036577996565 0.162166793977376 0.665604714665096 0.0700485690915957 0.626573296356946 0.958242878185119 0.613256691358984 0.730122110247612 0.630972134040203 0.60865324182203 0.0400956759601831 0.869880957880523 0.130686504307669 0.286934182427358 0.680665583403315 0.0985883007990196 0.143432093933225 0.424979054096621 0.33551476304885 0.426854450386018 0.119832987815607 0.723283006094862 0.796944501772523 0.339389439339284 0.377349265420344 0.0930712374998257 0.940781994909048 0.910380941845942 0.708217850704677 0.193026389719453 0.16783314718632 0.571932238105219 0.0843980894074775 0.832938973186538 0.963927454447839 0.572491966008674 0.685960719052237 0.444470097771846 0.756942439735867 0.259827081293333 0.0621585365547799 0.691520465391222 0.913476851929445 0.730925803438295 0.648165659960359 0.0362412626692094 0.284884512771387 0.308901767416392 0.645912388742436 0.790592936801259 0.532590899262577 0.825621994815301 0.128292829506099 0.0176881816401146 0.337670426438563 0.0300497633614577 0.389368359623477 0.991952926220838 0.433609305243008 0.573200462656096 0.566184254337568 0.387126892891247 0.896401113625616 0.788042102048639 0.88151635259157 0.439587199878879 0.746698263778817 0.942513375873677 0.467264009437058 0.919934663956519 0.295069145595189 0.778141526705585 0.0182753165019676 0.722739649619907 0.323458801149391 0.212596013946459 0.582214624895714 0.780168358189985 0.583861500015482 0.0638536180113442 0.108106207917444 0.338503956312779 0.81401743601542 0.591543508572504 0.0106269041216001 0.303434321819805 0.406758994085249 0.852905080795754 0.317772125471383 0.112403487192933 0.507414112752303 0.397732582259923 0.709498958031181 0.347737568533048 0.880715330231469 0.466398188720923 0.45390919360565 0.281922132922336 0.85434153471142 0.851787861322518 0.866201155642047 0.825307144988328 0.943848825509194 0.51892667299835 0.0965516010485589 0.858494661282748 0.893603152246214 0.229338226432446 0.892827506810427 0.740724103511311 0.355375967430882 0.364740781581495 0.961909229229204 0.319593959471677 0.762740585652646 0.879952224814333 0.161818387389649 0.650866790304426 0.910238422250841 0.39174334483454 0.504666832152288 0.0753412443585694 0.980366070922464 0.701939793850761 0.725865891966969 0.107040941135492 0.500053289378993 0.0218979887361638 0.271983684431762 0.0682630228437483 0.119930433370173 0.75681222573854 0.539090207933914 0.134578223479912 0.341281148279086 0.727114914520644 0.0796674235560931 0.980990529414266 0.996911626420915 0.979490017746575 0.124113334389403 0.431675088214688 0.267364838721696 0.144935123608448 0.872434728541411 0.636233922454994 0.105379763806704 0.127987640032079 0.65517892176751 0.34951894845115 0.199112194715999 0.2639362457674 0.568542392363306 0.957416301183402 0.488470791957807 0.360418542590924 0.808338277249131 0.563864520075731 0.377890684984159 0.935935116002802 0.176396230873652 0.684681525586639 0.172363328558858 0.693952026248444 0.732570744412951 0.683528946132865 0.114571685299743 0.692349613416009 0.113072165253106 0.675569273999427 0.456588425766677 0.745954342840705 0.293176482375711 0.297810445812065 0.377821452224161 0.0295280858618207 0.122486237753183 0.102382614985108 0.527355690302793 0.260264076152816 0.611753229722381 0.415991806923412 0.633626900913659 0.491404408342205 0.537640591873787 0.851892239926383 0.610210326600354 0.852488016551361 0.69110818545334 0.0472642958816141 0.803522203366738 0.713554645041004 0.106247077947482 0.469086207400542 0.192378516800236 0.364714962784201 0.156514879665338 0.709543912210502 0.541545615640935 0.697714568222873 0.780512187001295 0.61626240956597 0.371193486829288 0.726882982146926 0.574891047012061 0.680377824055031 0.495120578086935 0.554723530379124 0.597223668640945 0.783231993566733 0.70853389384225 0.77494099161122 0.27711364187533 0.742178403609432 0.640621907857712 0.90387734352611 0.182268584021367 0.388070077106822 0.640184290411416 0.783758692790288 0.906504811316263 0.562641248090658 0.186197504657321 0.569809649265371 0.462179760837462 0.214619311830029 0.898865069972817 0.924780983664095 0.825769867135677 0.117498521918897 0.581323711234145 0.671343467736151 0.250397370823193 0.425838883826509 0.296081637714524 0.53501892559696 0.321910043037497 0.207060009348206 0.171201556671876 0.0748294814559631 0.902772225195076 0.991638939625118 0.252321184589528 0.326996535577346 0.0915059041953646 0.507509534265846 0.837081618125085 0.794256114058662 0.708683143183589 0.684691930462141 0.71391648392193 0.540358786305878 0.39976212560432 0.160066141122952 0.334257909869775 0.951163895090576 0.495486572463997 0.0545052531990223 0.413013906890992 0.598460747485515 0.552748957693111 0.899805648128968 0.182447608963121 0.926630065576173 0.527398385559209 0.934981698405463 0.0880694716260768 0.584072681646794 0.53060846690787 0.826446396796964 0.970755899020005 0.833404437850695 0.350276840596925 0.641878338756505 0.836120706205256 0.453862404627725 0.207288322374225 0.612995808583219 0.426141490521841 0.854917838959955 0.41139090097975 0.928435827109497 0.963062523931731 0.878748420134652 0.759980326388031 0.638669430895243 0.784523481796496 0.584869817276485 0.765236453434918 0.923311281399801 0.777331375761423 0.209573517013341 0.847527146863285 0.347176110709552 0.112420972869731 0.976931114720646 0.0238565670954995 0.653715643833857 0.57223678563023 0.80924739160575 0.508590113087557 0.441272680452094 0.0323883308167569 0.399492503562942 0.992054524275009 0.490027190761175 0.0448299535526894 0.751830646337476 0.631118397454265 0.953562306484673 0.630727467795368 0.312459018246736 0.318560079040471 0.708724084317219 0.909559104433283 0.977284451983869 0.578953273834195 0.798304017235059 0.629409977979958 0.941584798130207 0.753590742130764 0.886782207298093 0.693106009832118 0.5972585766064 0.896426467269193 0.934163839924149 0.936836850596592 0.136980429633986 0.660033305599354 0.609559768098407 0.462431107270531 0.884243037577253 0.848920523119159 0.0958674567425623 0.810459110122174 0.142130467749666 0.675915942830034 0.047297266474925 0.228815907214303 0.57016233028844 0.341593104840722 0.882530180241447 0.121074299144093 0.324388834284619 0.761844433364458 0.66392516215099 0.343876361416187 0.856584681344684 0.975420251653995 0.632304455759004 0.201954031523783 0.256810297360644 0.156151170949452 0.545576803940348 0.796392363850027 0.56431936618872 0.0321128116035834 0.160696258677635 0.105007304069586 0.808002431886271 0.273718714939896 0.352109201869462 0.821809078399092 0.337573952451348 0.287233173002023 0.71356411937857 0.866472378061153 0.844468758872244 0.362508359299973 0.823133406988345 0.39319958968088 0.601190787202213 0.193558492148295 0.287353036983404 0.941275473905262 0.808056832742877 0.345853169974871 0.169881610854063 0.0505224673938938 0.435389061041642 0.904075808343478 0.0395243708463386 0.665939160648268 0.551215021803509 0.29655088538304 0.487791023738682 0.436660353117622 0.985616353582591 0.752871199811343 0.323359666934703 0.323557771015912 0.36562394506298 0.661768052359112 0.187536156661809 0.0494188291183673 0.369939328222536 0.498468914506957 0.473527867577504 0.778693559519015 0.228249218140263 0.8809808449517 0.571574141890742 0.540828365667257 0.212591712311842 0.32568161240546 0.0410214920551516 0.571254169379827 0.853272648120765 0.946769924233668 0.780144490364473 0.138372297482565 0.0681501700519584 0.129638269573916 0.161318230049219 0.359411185602658 0.810629505517427 0.173746710924897 0.241062236153521 0.805184768550098 0.925267690732144 0.643727171265055 0.347026171935722 0.58865645919228 0.323452163604088 0.105817570034415 0.321123354695737 0.0105241418001242 0.0706466463604011 0.503462648526765 0.608103245035745 0.118234358679038 0.540299203756731 0.999121893278789 0.703360007724259 0.721400803762954 0.611052465967368 0.837241603804287 0.31329438614659 0.0798911369079724 0.0400875641219318 0.14001591675682 0.570430393442512 0.07230552097084 0.833534141515847 0.192457518940791 0.539245169584174 0.980971230375581 0.947971484742593 0.0522013825690374 0.90224853287451 0.39073011649074 0.524416734101251 0.186162871450651 0.196645297389478 0.940449525252916 0.634826076184399 0.984269915670156 0.554986318717711 0.755845411345363 0.348136600810103 0.640913558085449 0.531168414249551 0.729243349360768 0.816487209319603 0.40792877500644 0.196143500946928 0.225189536339603 0.358573518211488 0.442360810069367 0.0549860596377403 0.768418497170787 0.0399336839886382 0.553433385516983 0.530083985116798 0.149370354614221 0.63816933440743 0.856978688670788 0.927592491665855 0.709485820550472 0.662144472587388 0.860601500819903 0.7523002499016 0.544549391404726 0.983184431067202 0.37719501740532 0.645832053606864 0.45759619765915 0.838909781258553 0.585667328163981 0.945072350355331 0.0451668264949694 0.0337176569271833 0.273825784197543 0.839320108150132 0.468490105536766 0.0434767349530011 0.335129332945216 0.55501122772228 0.992377883556765 0.657422827905975 0.574308432762045 0.943264210959896 0.106133032767102 0.58055017558625 0.246473291888833 0.681797694941051 0.578546551077161 0.0101184286433272 0.964633380533196 0.633537129934411 0.194117299655918 0.22712230719626 0.750318643206265 0.424362835141364 0.386594686044846 0.236983269099146 0.0424083941918798 0.999041568976827 0.337637564872857 0.584327581734396 0.733641479862854 0.702053467461374 0.196470953028183 0.803990059953649 0.359349492804613 0.520159012484364 0.998892413680442 0.916736991701182 0.629237913978286 0.337506075045094 0.223283217009157 0.27059146621963 0.663294360234868 0.0125119538488798 0.692633363867644 0.425544067188166 0.79793346767081 0.512098889506888 0.685943672712892 0.428194336269517 0.790173509907909 0.385559067626018 0.872800848542247 0.750990347531624 0.15769438294461 0.194963554642163 0.466806557725649 0.895251176189631 0.0362907180981711 0.230824756519869 0.4378627669462 0.965335182240233 0.931756966789253 0.212152367942035 0.32373289286159 0.732701184072066 0.0365851675462909 0.348352894752752 0.440828811321408 0.257184082947206 0.346426026369445 0.320968586206436 0.125934012650978 0.699592609987594 0.0452495853626169 0.785856990371831 0.78278810899239 0.265652426485904 0.54523709674133 0.623103574640118 0.870922547231894 0.314839261677116 0.694692741821054 0.280217405864969 0.489263286883943 0.222960418078583 0.445826901374385 0.165845150505193 0.39541446773801 0.138851797434036 0.389098776536994 0.475138061938342 0.214674758936744 0.559166058858391 0.3279122217861 0.564739387317095 0.0466139660379849 0.764555389562156 0.297379242554307 0.983796742546838 0.229300773260184 0.61220195046626 0.686156647421885 0.802697329777293 0.77935427879449 0.406409117584117 0.506021222856361 0.0913027689396404 0.765831644353457 0.760796146537177 0.431188093018718 0.714523983204272 0.847694608655293 0.628084345438983 0.0850481781456619 0.150846099266782 0.463780511056539 0.230890103010461 0.407832351499237 0.296230730775278 0.966385227800347 0.588068477003835 0.648441830573138 0.794697331951465 0.13500392165035 0.336596679245122 0.774912111051381 0.146344460768159 0.958600202908274 0.775144762822892 0.262160243238322 0.462611955024768 0.0253402645397 0.353488932386972 0.795498733948916 0.0378491895785555 0.492805051645264 0.336244280587416 0.690697097904049 0.574250943635125 0.901096762022935 0.691720488865394 0.44151668215869 0.180250246087089 0.245472647359129 0.445783070893958 0.281258982999716 0.664750530167948 0.0656867129728198 0.571470741077792 0.249258100804873 0.881242433986627 0.169060283312574 0.234965836808551 0.252985994589981 0.23039526128443 0.514957467699423 0.326770500375424 0.347152411611751 0.822417511215899 0.865518867571373 0.114928949861787 0.794463820636738 0.286013299082406 0.347930506365374 0.698503744145855 0.594029954571743 0.124332881872542 0.159365623544436 0.951484590917826 0.525645918701775 0.259485624351073 0.697321369498968 0.741406095386483 0.427590894980822 0.722261047244538 0.388179075438529 0.652412685116287 0.991020352949854 0.959328782302327 0.191411089501344 0.0561279221158475 0.683633997573052 0.925538827634882 0.505545570910908 0.403399169889744 0.256121781116817 0.449249180639163 0.608104028743692 0.282495487432461 0.0431980189029127 0.732900505897123 0.345783854925539 0.939756632000208 0.960554880015552 0.152167250150815 0.704683219990693 0.862668719310313 0.621362581728026 0.577107257603202 0.1315654316172 0.462393781105056 0.343796119634062 0.589938230826519 0.496237535018008 0.787770110673737 0.943032752729487 0.169201887352392 0.749044467776548 0.890645068499725 0.21788783197524 0.0913843536283821 0.640525977856014 0.791601603964809 0.320876864485908 0.679821819455829 0.159599156295881 0.488669379863422 0.069195892540738 0.845314390349667 0.395570258044172 0.448982965191826 0.881524283254985 0.0529693340673111 0.301705887597054 0.552420485869516 0.87001364332391 0.329101195945404 0.165509811786469 0.432661153010558 0.370846533558797 0.652847640030086 0.438063601097092 0.298489208579995 0.0762864565337077 0.718319424316287 0.709082269505598 0.682688138838857 0.0800303476420231 0.837061719780322 0.923500193047803 0.439187398415525 0.658713232313748 0.0626420371048152 0.757471554623917 0.818299840975087 0.263689795434475 0.965130730355158 0.151492140153423 0.0261022522510029 0.361530569538008 0.306634473588783 0.737905092888977 0.754137740312144 0.824923282992095 0.712634336338378 0.988642538092099 0.725289992250036 0.092578999067191 0.796209130627103 0.264297628253698 0.26435090633342 0.24720416754717 0.219881101627834 0.174581242331769 0.709334343634546 0.132524483152665 0.820499066771008 0.920257078639697 0.182402669305447 0.766069893643726 0.783792833182961 0.854689006842673 0.384935901099816 0.61501998929074 0.0747527831862681 0.690877735670656 0.808341030369047 0.78366027451586 0.37864384676097 0.129001365799922 0.803492296610493 0.55812157001812 0.159020849212538 0.667385797235183 0.838035540522542 0.967405737712979 0.978875279307831 0.413839824886527 0.807296929003205 0.254976103594527 0.85514651756268 0.0109876817697659 0.562000464731827 0.915707370722666 0.852589015299454 0.540271779510658 0.932501595139038 0.474433422056027 0.313018410769291 0.559962252655532 0.948588113300502 0.04538800339913 0.33908014577115 0.88239231310552 0.677366907328833 0.0797419002442621 0.630440550241619 0.376921280205715 0.414708182741888 0.73909168019658 0.0477325309533626 0.0458840038604103 0.12101223569829 0.584375433097594 0.881949171670713 0.292023423477076 0.941982340901159 0.712154072502162 0.616929874492343 0.430368388674688 0.177455924570095 0.822453632084653 0.332032280261628 0.640593636976555 0.91508225990925 0.489583679139614 0.294053142233752 0.704834754301701 0.262435019081458 0.42378378123045 0.531740152016282 0.192071405397728 0.699788483036682 0.16982322899159 0.926652632907499 0.924557158979587 0.137348268721253 0.417949801420327 0.699326248862781 0.52324198562419 0.660630644108169 0.929249988794327 0.548202511384152 0.606818674642127 0.563130426143762 0.794520945569966 0.479132123917807 0.529569346697535 0.611207212558947 0.471683260637801 0.553040884984657 0.060861403553281 0.816364135593176 0.256780675044283 0.558043883584905 0.100307108322158 0.944745801612735 0.680983585810754 0.472420056287665 0.678571327219252 0.400735119304154 0.108494404049125 0.563036079462618 0.0912076270254329 0.467282066759653 0.0315228106756695 0.495970007781871 0.494607774927281 0.284969499905128 0.492353434178513 0.619189189481549 0.287922112678643 0.354859392100479 0.906894620733801 0.112924247293267 0.440644389628433 0.798238220342901 0.567336468906142 0.758178127959836 0.42863960662391 0.621005347131286 0.540566767181735 0.120349779818207 0.38327556326054 0.829339867972303 0.0586459204275161 0.690783726444934 0.841147581159603 0.946679312151391 0.894187515778467 0.697000423115678 0.629965185271576 0.246996087555308 0.262279162390623 0.979031882365234 0.253912558895536 0.938376971555408 0.0603708480182104 0.20861625878606 0.140483257940505 0.469904423160478 0.503388628694229 0.921371821134817 0.730088473272044 0.739533179763239 0.104976858398877 0.588671763855964 0.943990350717213 0.503688866978045 0.196643383298069 0.374674471351318 0.265971276450437 0.0195600496302359 0.137485992715228 0.343640653183684 0.614358302135952 0.398775135572068 0.669329966201913 0.445970070755575 0.34984139286913 0.539766635252163 0.012479620364029 0.528403838367667 0.57768925572047 0.845485553087201 0.705848783871625 0.35352697287919 0.334206594286952 0.781612161903177 0.758216666798107 0.46588541621808 0.578503113833722 0.946768277755473 0.683866121263709 0.729603185637388 0.800525769793894 0.183412010918837 0.461004338371567 0.882782789135817 0.844770310097374 0.582710056707729 0.422935030825902 0.179715454848483 0.777272399894428 0.283154248590581 0.0123430843790993 0.600376342460513 0.389380003449041 0.0861202571936883 0.127159423928242 0.431559036050458 0.185499682803638 0.121450994131155 0.444210083298385 0.584332927083597 0.70079540529754 0.485361989648081 0.995577365255449 0.35096369584091 0.262652230192907 0.620236849572975 0.733862433871254 0.306659519511741 0.187399097436573 0.316780883132014 0.0759908861527219 0.381807175320573 0.14009072398534 0.274764127633534 0.377901780675165 0.585911707894411 0.439325539388228 0.803306478303857 0.314801607045811 0.80222045985749 0.324411198773887 0.0885325014940463 0.0768297675997019 0.302827497217804 0.344263475569896 0.87611080609262 0.835697873178869 0.538651389339939 0.901476599217858 0.567660359495785 0.276129852368031 0.163051046351902 0.769437862869818 0.622313230070285 0.131099510097411 0.658302897815593 0.466386639401317 0.5334118750575 0.550633701593615 0.543628630687017 0.680383366022725 0.155230723023415 0.639947356597986 0.285857866976876 0.457326856139116 0.328405668050982 0.846960308654234 0.874642396946438 0.0623637431045063 0.465194039901253 0.315713415283244 0.23656080695102 0.920767454148736 0.564111972632818 0.104625020092353 0.496591592831537 0.661072032572702 0.818023106323089 0.13444857513532 0.0505670188856311 0.0447502389294095 0.571125063637737 0.546563854825217 0.153921465598978 0.0140009371726774 0.347329305559397 0.560072585365269 0.811208481057547 0.960946591768879 0.638197414432652 0.257364621367306 0.296639393439982 0.684037963522133 0.359643718665466 0.28464487309102 0.812868316401728 0.623421799021307 0.579723013339099 0.957708533429541 0.126122308396734 0.376439520639833 0.510240812010597 0.107625623682979 0.429249452881049 0.317929460373707 0.727778314307798 0.27994473035913 0.408055076918099 0.905547750398982 0.444483028722461 0.57819618153153 0.994627742187586 0.561023054607213 0.233789752570447 0.810661705310922 0.329848968808074 0.701910570303444 0.13691452256171 0.54751365146134 0.588381700406317 0.290351702279877 0.841546119931154 0.0905944304168224 0.591760442620143 0.416536093475297 0.748912900038995 0.960550435238984 0.848254633215256 0.881271248161793 0.766330975112505 0.84468201387208 0.662828964721412 0.695636545626912 0.14022157439962 0.102051162996795 0.817236431580968 0.386774912364781 0.432672924303915 0.752198844547384 0.909093629857525 0.608408416991588 0.989158328562044 0.553905606665648 0.8888860341697 0.963320238683373 0.124879512402695 0.8748561871727 0.543705347166397 0.150124929600861 0.663487329646014 0.188596792882308 0.112977426026482 0.841634655187372 0.765206084521487 0.612406832929701 0.982413447771687 0.350809459581506 0.208513057127129 0.740326701807789 0.0607388572162017 0.193745305072516 0.502259513225872 0.965178481680341 0.0129722167667933 0.442575683656614 0.587283771443181 0.838583273314871 0.982717459148262 0.904158396869898 0.0827761232922785 0.150577939301729 0.98755535768345 0.555647086168174 0.989546425577719 0.573597225176636 0.946976281912066 0.313972251799423 0.858563090972602 0.508953911007848 0.0852513749455102 0.0583489213930443 0.74303583380999 0.305812135294545 0.0327880511432886 0.331242266693152 0.987079614689574 0.376902000759728 0.553266523953062 0.0490537685062736 0.0160259921755642 0.022172163890209 0.649344235467724 0.738273667048197 0.614431089933496 0.815851641076151 0.346450506870169 0.60260854230728 0.237735327691771 0.880644951183349 0.271070586303249 0.581366048981436 0.738847778527997 0.440845416248776 0.6692544891336 0.947443936578929 0.257894221693277 0.399004609177355 0.817130407420918 0.407273754901253 0.714200718889479 0.707404661048204 0.259916250661481 0.739492548655253 0.106371480750386 0.354542205210309 0.241301027585287 0.016282554876525 0.826095944500994 0.629014052182902 0.313921117391437 0.64575154859107 0.974754177809227 0.959473755594809 0.822574218690861 0.980663829923142 0.294939544964582 0.553135155369528 0.328687138834503 0.829296902567148 0.153371578762308 0.883604652595241 0.762045736126602 0.0949488802650012 0.220285703763366 0.812818102620076 0.601540041808039 0.557129832098726 0.131567717047874 0.0124613655009307 0.259545353038702 0.809854250783101 0.521513523510657 0.451537658092566 0.336828895367216 0.154846573129762 0.499431581932586 0.576047836591024 0.420145093463361 0.683131360949483 0.630386197329499 0.0487581819901243 0.0251413313415833 0.176130733671598 0.542911977944896 0.744288742172066 0.224316391411703 0.459674347261898 0.469836328621022 0.0111827575112693 0.565388674137648 0.758595519748051 0.0296126235160045 0.521993641208392 0.206253427271731 0.61762157028541 0.346192079635803 0.810907187534031 0.266930024875328 0.911778872827999 0.0521681021805853 0.584414323221427 0.332929946258664 0.326392189566977 0.204972328473814 0.691487551962491 0.835587114270311 0.981781804522034 0.211769269600045 0.648982201120816 0.101972229776438 0.701410795827396 0.62111326325452 0.726570999308024 0.66965158887906 0.333124886695296 0.569213376829866 0.233522480730899 0.299756729868241 0.582463076219428 0.820710950512439 0.230532751549035 0.579116633606609 0.231402709782124 0.215445640811231 0.735397466260474 0.814001614104491 0.519597784932703 0.778898877862375 0.340609045415185 0.653158696249593 0.575500438488089 0.684892828001175 0.928880249445792 0.0484862060588785 0.804802547961008 0.568332165242173 0.547130720464047 0.902477429071441 0.429813038471621 0.619455645573325 0.0411613110848702 0.512943676423747 0.477040609328542 0.0565304296766408 0.188258308498189 0.764608133798465 0.282498631714843 0.766179472149815 0.122767679493409 0.934790659451392 0.543322112828027 0.324219150450081 0.856289586259518 0.636673783150036 0.696582444699015 0.218158185170032 0.100299526178278 0.912750676674768 0.127730212255847 0.653747000680305 0.299242129020859 0.0328573205531575 0.958124380391091 0.285513502708636 0.851984696027357 0.718092471945565 0.622723745051771 0.946278418337461 0.103640058250166 0.0524955072393641 0.697776246038265 0.837444330148865 0.771285374369472 0.895837804868352 0.950058558704332 0.0933630311000161 0.512081451774575 0.878060191557743 0.719023093322758 0.439295290336013 0.383070913373958 0.110785836311989 0.669164479353931 0.0336420369474217 0.907116414923221 0.557016992445569 0.511546393844765 0.428184225514997 0.905179528216831 0.0885382769606076 0.239518822007813 0.571327030938119 0.555929945267271 0.411418309090659 0.146145783888642 0.970659972475842 0.670473518492654 0.934160769172013 0.404909807064105 0.110108101814985 0.0892721134214662 0.460065734698437 0.576750467414968 0.41829307126347 0.207116759484634 0.717117779213004 0.0679840191267431 0.345533228120767 0.280359446476214 0.351623584616464 0.242411355038639 0.984015674819238 0.760364396297373 0.87310360229807 0.450892119009513 0.346061128722504 0.665693189068697 0.547484918884002 0.798593037431128 0.576062232614495 0.657139996697661 0.539400948134717 0.712573283645324 0.400084980546962 0.0479744821111672 0.156385995435994 0.265041506087873 0.796153419134207 0.37210712133674 0.291140209976584 0.431509440706577 0.267020069691353 0.0845087123196572 0.80327171117533 0.812920764673036 0.373279174319468 0.0369875974277966 0.610059243151918 0.257287267087959 0.920543801649474 0.310419297763146 0.457826492774766 0.296109087546356 0.603549818424508 0.769405581708998 0.422311563033145 0.546893002020661 0.0331366799352691 0.647026692361105 0.393033888465725 0.190597634075675 0.139832869088277 0.521818847598042 0.994735270144883 0.298221051150467 0.0919199022976682 0.845810587198939 0.103142379731871 0.594192290452775 0.162466791155748 0.819994431000669 0.182316830926575 0.642956880629063 0.445138846596237 0.519387245711405 0.988005700241774 0.53789516557008 0.257983521986753 0.710746663033497 0.299712645835243 0.0604745507892221 0.297080495159607 0.726939785068389 0.99984096422093 0.668939959243871 0.0990272708330303 0.915727794612758 0.186741563242394 0.993863882797305 0.960530050995294 0.912977800769731 0.390790270916186 0.752045497335494 0.36974014262436 0.446490661667194 0.341862831760664 0.561683524018154 0.82568764579948 0.122047041596379 0.909984462612774 0.468713187773246 0.775754257563967 0.957211497090757 0.699747667757329 0.661763254683465 0.30051938880235 0.101204143434297 0.640034459512681 0.30565154569922 0.117326260607224 0.219052642113529 0.551839715638198 0.0538729613157921 0.87717454602709 0.713208385582548 0.251309027159587 0.162762932260521 0.690165125248022 0.924688766363543 0.612078770017251 0.517638512761332 0.227679267458152 0.132038015346043 0.10673342497088 0.473308990395162 0.97216784408316 0.878842279303353 0.601991304070689 0.450143367894925 0.604748930537607 0.199717125510797 0.933769127491396 0.336478693396784 0.0327878547552973 0.967727164924145 0.435784218804911 0.469451182726771 0.333064076951705 0.0363334048260003 0.067434283499606 0.664924114563037 0.287356576807797 0.392227737198118 0.371898754138965 0.895077291449998 0.150915156153496 0.122466146938968 0.617528258329257 0.77124412620673 0.87729524719296 0.55668235237943 0.103659824978095 0.776591598333325 0.589996048188768 0.0953867985168472 0.425035021447111 0.886658699535765 0.934526038619224 0.578549997317605 0.471215911617037 0.945667770393193 0.620824507675134 0.306894419142045 0.154237025834154 0.111614210770931 0.877134120066185 0.889897109160665 0.871434288006276 0.69662333696615 0.365066008854192 0.175990332392976 0.637307794350199 0.36855252796784 0.149952139055822 0.583755976506509 0.0348879781458527 0.647399933731649 0.246801556260325 0.252804217450321 0.950692505824845 0.472074576618616 0.485218262220733 0.483760462636128 0.9092453384283 0.481487674324308 0.47615346968174 0.0236464861128479 0.856255376716144 0.0909424380050041 0.413018035418354 0.890001825450454 0.868370557662565 0.814157430457417 0.07336151602678 0.994436827013269 0.172468480498064 0.236014375344384 0.171739503948484 0.828978139271494 0.888558214667719 0.930013722099829 0.156775827442762 0.386110480388161 0.829816416110843 0.601525801143143 0.572789689511992 0.207791319964454 0.889990751887672 0.0317757577169687 0.810382860179525 0.764505040706135 0.680688125609886 0.583654445759021 0.91351190488087 0.208906862072181 0.334304084328469 0.497253277911805 0.805433671658393 0.468656670905184 0.81548114360543 0.652492549796589 0.506002255510539 0.958836668340955 0.0150405066320673 0.932345684510656 0.712975253444165 0.709191411901265 0.890483852399047 0.460684020107146 0.813026623332407 0.488748023572844 0.357674894707743 0.880531759783626 0.409190115835518 0.74566254486097 0.200773591022007 0.274615754662082 0.72678749217419 0.649890524393413 0.296552481381223 0.10654475903837 0.0600757121341303 0.871725416607223 0.84726500162622 0.0746225756430067 0.538123826193623 0.633160568638705 0.64391672232654 0.390720044921618 0.884465668490157 0.85018015315989 0.836665966168512 0.501407775511034 0.792527365661226 0.784523574458435 0.215938204482663 0.15686275517568 0.639786143263336 0.541209278616589 0.979194498767611 0.844495378895663 0.36950504430104 0.82248254791135 0.749112363161985 0.390939765512012 0.916162300969008 0.261936555472203 0.909495322823059 0.894736946451012 0.396551169038285 0.255247997236438 0.613887543063611 0.670668355433736 0.447060131290928 0.269651783104055 0.286062318631448 0.277437120326795 0.379238691464998 0.687042363947257 0.229429755683523 0.90464011494536 0.183763070357963 0.239264238630421 0.200466021611355 0.118303717293311 0.148835122885648 0.732782919278834 0.21595489999745 0.949638666657265 0.903850466953591 0.0556626040511765 0.233244417693932 0.775424717131536 0.193013372791465 0.734806059498806 0.744333735997789 0.344701473114546 0.697019985388033 0.803436935020145 0.506742097940296 0.947190224500373 0.193608019724488 0.133328845491633 0.970241787759587 0.139513531380799 0.392999314037152 0.904575578209478 0.115097792593297 0.444337430307642 0.956158754653297 0.826171128831338 0.613971866811626 0.92535759563325 0.420355345478747 0.72765044843778 0.60445879010018 0.211689470843412 0.437121478575282 0.639909302275628 0.838909052410163 0.547497832085937 0.630868188780732 0.59680931533454 0.13007673596032 0.171786803258583 0.561901955408975 0.0925030964915641 0.914831440404523 0.980122458534315 0.876780610156711 0.407795777001884 0.8700353886839 0.15691822049208 0.0225856933812611 0.282623945001978 0.689512033064384 0.75231390716508 0.292437047013082 0.750128686230164 0.441672565357294 0.117616678108461 0.96957525636768 0.44102103090845 0.503024169923738 0.750235595288686 0.496942764755804 0.135624444775749 0.94984866120154 0.94667263726471 0.113347825303208 0.0802884908975102 0.780777625886258 0.0680218618479557 0.917900999691337 0.434105934745166 0.356136445812881 0.867284717394505 0.759865285668056 0.754466896497179 0.853639469540212 0.0732398158637807 0.308826382549014 0.933450803302694 0.445619960986078 0.189336133969482 0.692083582831547 0.630933880794328 0.52926189922262 0.815980655539315 0.354697540043853 0.790599222599994 0.813737413017079 0.936817726048175 0.307826721111778 0.956021350366063 0.791324960130733 0.0380726309376769 0.435607682135887 0.0797431179881096 0.459719462562352 0.538219069067854 0.869677390202414 0.424539056944195 0.794991415592376 0.0710765530425124 0.191547564172652 0.0453004046739079 0.385230452890974 0.395063001692761 0.419668782050721 0.100029521964025 0.83224459273275 0.813362541073002 0.188052870524116 0.117787158789579 0.211416712587234 0.0948214906128123 0.94733648929745 0.860022088016849 0.113786077322438 0.912780883775558 0.650218475512229 0.536654391773045 0.629741811680142 0.724889410536271 0.713506493794266 0.474351763145532 0.100902183298022 0.36667838676367 0.984664088496938 0.400278651837725 0.269618048164994 0.146960411188193 0.0423430712125264 0.127866688540671 0.894888347301167 0.713240089104511 0.162343345629051 0.284637047306169 0.779414944243617 0.312946766032837 0.461588115736376 0.98518666195916 0.238804010057356 0.486924587581307 0.750572978563141 0.987102417363785 0.60715552914422 0.254241341897286 0.352360145153943 0.0772238913294859 0.649910649091471 0.423095320768189 0.95076317922445 0.532255309526809 0.168958017723635 0.44452900448814 0.757942763406318 0.0251735147694126 0.266112074423581 0.272268738143612 0.315486278741155 0.329516163540538 0.895230498285964 0.93341610647738 0.644873108563479 0.931004648650996 0.0672127769771032 0.176028256712016 0.297746366392821 0.61184944093693 0.829263266052585 0.0613625280815177 0.0271380262589082 0.918409168832004 0.735548957467545 0.491062711447012 0.619335629690904 0.155077911037952 0.0740286448807456 0.963643257974181 0.0900279298936948 0.58329541624058 0.43174865487963 0.789155484579969 0.328518847464584 0.933190595668275 0.424254795007873 0.454798503201455 0.672994644260034 0.979906650951598 0.191426739918534 0.135949745578691 0.901803874964826 0.462756790246349 0.585242536789738 0.636062788530253 0.206885532909073 0.681699424188118 0.405929985283874 0.198733163126744 0.826933572937269 0.621941178322304 0.913751630077604 0.0403242178750224 0.707859128906857 0.687265415065922 0.741657488150522 0.41568547323579 0.920455438117497 0.197239384201821 0.777933767342474 0.898679124198388 0.911534851298202 0.95588770856848 0.249122773343697 0.906838011434302 0.550643798978999 0.466118186237291 0.313294534129091 0.652279413044453 0.621932223076001 0.970436242297292 0.31665335586993 0.990779316194821 0.5405229357793 0.658985233830754 0.337523029414006 0.485250816526823 0.413259510127828 0.870949040709529 0.11827504464658 0.277988458867185 0.5400295469095 0.495610298512038 0.765733602489345 0.45365171373589 0.224546695977915 0.399797513014637 0.387502296834718 0.706507263586391 0.99707148324931 0.516064983715769 0.909263993443456 0.839982700026594 0.582730977560859 0.600028666565195 0.963277202052996 0.251875183312222 0.0742528185457922 0.881813616242725 0.388738482482731 0.189294165717438 0.84090758189559 0.836728198111523 0.993351726427209 0.518539435986895 0.593337703498546 0.581903666178696 0.473410389064811 0.409723027558066 0.0704538945434615 0.60828571299091 0.339722095241304 0.817892505773343 0.0215888754208572 0.333166640349664 0.325078722478356 0.732225180841051 0.964426459507085 0.525378936603665 0.323956165031996 0.920464420563076 0.995515127549879 0.721799151217565 0.0732095875567757 0.349050489561632 0.613802383744623 0.503590527074412 0.45715145238908 0.151875970801339 0.467710016246419 0.806954340755474 0.608660364113748 0.710548665905371 0.595646085289773 0.714639969675336 0.397271065639798 0.802154168537818 0.484339624652639 0.320676927219611 0.0652414299407974 0.660607300675474 0.320953701057006 0.352820760740433 0.698798576458357 0.731806754097343 0.0264808417367749 0.375084414687008 0.362933181792032 0.44099079222884 0.33618742511142 0.464743024737108 0.802908316173125 0.696090908837505 0.464966803090647 0.915106166920159 0.0310035684332252 0.0638056871248409 0.174270418689121 0.930564193029422 0.568177781000268 0.851259168714751 0.149005097844638 0.507244575978257 0.953830736137461 0.146232161181979 0.395260534358677 0.354277501166798 0.667655171256047 0.291551249350887 0.653251583850943 0.810448144434486 0.814850472614635 0.926728246894199 0.0493654765863903 0.614856400399003 0.725459567517973 0.516488216202706 0.557986372099258 0.892159522562288 0.494185898024589 0.64912703565089 0.653607956368942 0.397612181438599 0.731297451576684 0.15431296275463 0.746147802991327 0.44015808455646 0.577643160093576 0.303799151468556 0.976524162383284 0.115866211089306 0.141364858155139 0.666775753898546 0.592496907499153 0.388747243185062 0.554238215545192 0.210742503162473 0.540391276301816 0.427439432356041 0.195397567723412 0.79975286341738 0.131139176783618 0.69036859611515 0.222218561058398 0.582546680800151 0.322390503722709 0.45263490937883 0.738197753408458 0.862609942136332 0.308376956467982 0.891270159720443 0.449857653793879 0.867219121039379 0.0800221618125215 0.3146482084319 0.803160632329527 0.917513617693912 0.259197345450521 0.154648383762687 0.0450454040872864 0.417337467581965 0.0977038036310114 0.931140427435748 0.0675617821794003 0.50541617634939 0.818246324555948 0.790281042014249 0.438364325279836 0.676285174612422 0.757411179607734 0.167659379772376 0.0807388320728205 0.851267747781239 0.656832634278107 0.892728320732713 0.332466753886547 0.934048692942597 0.755169838499278 0.0394316342240199 0.647515155165456 0.0232321772933938 0.25493680087151 0.754005272001959 0.480273637184873 0.166805581597146 0.212688393520657 0.347984249598812 0.875313473844435 0.990808276047464 0.650383363284636 0.18797592953546 0.806212705478538 0.767931468551978 0.999416070042644 0.0299315389432013 0.626809126986191 0.0107155502494425 0.0473795590363443 0.535814506257884 0.471453612772748 0.529722604935523 0.12158355418127 0.197283881986514 0.12433222586289 0.50401294012554 0.550200426119845 0.855351918195374 0.436643876580056 0.762282763754483 0.84569686264731 0.158445515378844 0.646878851389047 0.466654269902501 0.385847156592645 0.521749308269937 0.281084217510652 0.643230935230386 0.439038073238917 0.342951322344597 0.359622749637347 0.609496309652459 0.579836352260318 0.446882453865837 0.7551664480404 0.935845388818998 0.56992094270885 0.598047779037151 0.49650817910675 0.875707836835645 0.178665380706079 0.918300841723103 0.32728373180842 0.630964069224428 0.0636898739915341 0.629676164384 0.771977573349141 0.0539293822948821 0.724299816905987 0.912377906912006 0.714419015666936 0.60889951605117 0.496986028661486 0.0669061964214779 0.77268100355519 0.405148830611724 0.986051351369824 0.13111589812208 0.469852267857641 0.578547755221371 0.43323634854285 0.248320361746009 0.641976383156143 0.913439178396948 0.933147637869697 0.209387354797218 0.299675149328541 0.546349451923743 0.173532737910282 0.452053978487384 0.789429034381174 0.0901338607002981 0.815784231589641 0.337476051885169 0.22110742822988 0.280547610144131 0.514851755870041 0.36386355514871 0.665070824460126 0.865532546732575 0.506828504737932 0.801453826832585 0.323251133295707 0.908621476707049 0.341691405789461 0.274640378074255 0.743506051432341 0.963526564552449 0.527815056797117 0.625456223944202 0.744859582823701 0.0480670666019432 0.279582777149044 0.0629196324525401 0.132469590865076 0.586431213140022 0.253775173970498 0.169616684145294 0.104720817324705 0.625801035847981 0.521616861857474 0.997168492693454 0.046392764239572 0.0874789866432547 0.0664262525225058 0.463556480994448 0.403337609169539 0.668688849997707 0.18663620431209 0.614086284714285 0.931689056882169 0.392889069379307 0.625347329569049 0.100503075185698 0.153956204375718 0.110324588918593 0.432592706724536 0.0142241441109218 0.325459959744476 0.817863772043493 0.319966121169273 0.318986846511252 0.155515019535087 0.287829133567866 0.871202921285294 0.12769518281566 0.0572420420241542 0.330213780938648 0.442513743068557 0.882251585205086 0.281596039191354 0.0386958223581314 0.61235230737133 0.719468027374242 0.674939064704813 0.357655442846008 0.0453212863416411 0.936264828159474 0.309117611648981 0.274604059664998 0.281869900862221 0.193125964885112 0.962061962152366 0.452602098523639 0.482253718415741 0.815058602164499 0.947280942613725 0.394441431625746 0.0656764240399934 0.720982945668511 0.633944899863564 0.239410724940244 0.0729843743261881 0.717019824017771 0.650348624277394 0.534661828840617 0.713724490918685 0.774646117347293 0.0467647648160346 0.631407670511398 0.226728400138672 0.091882127574645 0.182570147463121 0.83860064950306 0.352648702731822 0.479462669340428 0.15262162742205 0.253958611418493 0.12357746347785 0.255323159208056 0.488788886796683 0.891301517719403 0.533406045883894 0.362083498314023 0.422073837905191 0.0483293771091849 0.125031869607046 0.0487588880187832 0.95497949247947 0.973035675701685 0.59074788549915 0.470240945739206 0.858552567618899 0.869554702797905 0.765742155970074 0.248123239835259 0.533323315137532 0.58694714698242 0.776251270391513 0.194689484136179 0.202147877996322 0.902361585281324 0.178284460611176 0.927361370429862 0.916663732987363 0.987673561817501 0.674761072644033 0.71889474316733 0.190811139631551 0.296392226475291 0.0405849759490229 0.651237169988453 0.763152630708646 0.316065766687971 0.952752099989448 0.589631375512108 0.243486869493499 0.408723631890025 0.822462283759378 0.73627697581891 0.216931932559237 0.265075651782099 0.0658765699109062 0.0857884555333294 0.0421475240937434 0.739511407664977 0.585781802309211 0.075892317360267 0.625174196497537 0.711310955574736 0.460233400946017 0.971857135922182 0.111575544003863 0.473125830241479 0.634029345316812 0.66821332989959 0.905248546379153 0.122521095008124 0.445191934511531 0.538441894985735 0.311510767820291 0.53742388187442 0.0985154597554356 0.346999989175238 0.178307633933146 0.507355306996033 0.898629199466668 0.362979066278785 0.0945068646036088 0.0965996573283337 0.923131977089215 0.292487301824149 0.148899040492252 0.564088621824049 0.361521675144322 0.0882699443493038 0.626475981727708 0.877111790843774 0.400876476475969 0.487530594822019 0.406572072133422 0.421144823129289 0.450937246757094 0.13012333615683 0.299666922008619 0.772976880504284 0.599295304247644 0.149149373176042 0.17357019361807 0.478651151056401 0.0296615363424644 0.859131256875116 0.891675345487893 0.942133744286839 0.211389834401198 0.0876900546369143 0.254124690887984 0.596903342539445 0.867376292746048 0.164554980287794 0.567617864084896 0.494918272870127 0.984556701146066 0.642640349748544 0.626080289429519 0.76425052002538 0.916792366430163 0.151901061902754 0.148092846812215 0.645433975839987 0.445735091601964 0.399250235694926 0.0974405144108459 0.377155970309395 0.624213013737463 0.664365719654597 0.685405297162943 0.957691572606564 0.455632682400756 0.815614320940804 0.607602600182872 0.217457178696059 0.669857996115461 0.689464958955068 0.818145943554118 0.327306543933228 0.577022972349078 0.483163938031066 0.863856110379566 0.990650404305197 0.0241053999005817 0.399870634349063 0.664580028511118 0.428561465409584 0.283734869225882 0.790166780853178 0.94971241703257 0.73684316792991 0.854804951823317 0.443048198234756 0.87476743086474 0.405115255410783 0.854421318715904 0.289649960503448 0.0830022898805328 0.584818202732131 0.981246749127749 0.779256790596992 0.939622044682037 0.377438091801014 0.935325530674309 0.959096855921671 0.772085701995529 0.872300612139516 0.94449682059465 0.223528067194857 0.160957544140983 0.838314465177245 0.971070159913506 0.278630520130973 0.694671360885259 0.541061304644681 0.51963089912897 0.2239965680358 0.849302556540351 0.218958965502679 0.575665048274677 0.817676702339668 0.225708846580237 0.749329253644683 0.899150465980638 0.734240095585119 0.978035499593243 0.752554037354421 0.295990880415775 0.667367750285193 0.893141324908938 0.41199970490532 0.990299868797883 0.352222510825377 0.479350831911434 0.99922386221122 0.733289124078583 0.432041273447685 0.852442308398895 0.741269994820468 0.629580879327841 0.152652039439417 0.0222455078898929 0.746391690138262 0.099848907017149 0.452199331186712 0.106804421995766 0.106457580749411 0.273368704516906 0.23670201567933 0.115724078046624 0.619885139425751 0.666301060612313 0.490260017714463 0.597662773288321 0.797212727661245 0.272650598918553 0.406052440342028 0.728078471224289 0.0742696569720283 0.81799227594398 0.913519538196269 0.831905223450158 0.936364496448077 0.219498693870846 0.0775514487503096 0.0332206957321614 0.0954313546186313 0.944138221193571 0.177186703833286 0.569258480374701 0.206628458262421 0.859056281840894 0.233024765562732 0.813979216422886 0.258698901203461 0.118050374940503 0.854929381133989 0.711834324039519 0.263154651757795 0.68330491076922 0.176320229873527 0.0749705067044124 0.947154962944333 0.375431287742686 0.0231936354585923 0.658403186616488 0.5271328533208 0.246313096222002 0.160830362862907 0.441881557216402 0.18623628298752 0.665061900101136 0.558336512525566 0.44425805774983 0.941610337328166 0.837362416533288 0.379465529045556 0.316841994372662 0.351873660981655 0.719073299036827 0.340242898676079 0.33999349514721 0.754226701997686 0.701997469915077 0.33190661753295 0.493496458388399 0.272370311764535 0.8063723124424 0.645953014318366 0.10532961871475 0.386991073999088 0.228719477483537 0.372791062339675 0.714500493633095 0.388910892468411 0.761052475278266 0.101357200213242 0.108656523949467 0.319871475065593 0.356452919298317 0.939559838094283 0.687847248374019 0.589674011990428 0.920718067178968 0.622373223144095 0.358050404451787 0.733649145679083 0.639681606765371 0.605386530889664 0.663864025785588 0.30439306471264 0.194547682094853 0.104727943995968 0.382674456730019 0.525524895063136 0.443255186567549 0.283597380113788 0.505594339442905 0.513179015161004 0.716983935495373 0.159986175252125 0.81728989014402 0.496943933633156 0.364831869651098 0.74108053019736 0.339412364640739 0.786841422519647 0.839490165628959 0.742744605862536 0.975771674595308 0.504775417423807 0.181284725132864 0.194072484239005 0.419212404480204 0.699029605493415 0.26297915234929 0.62792594745988 0.860187766181771 0.928939986431506 0.516010404680856 0.346773187783547 0.477264880265575 0.898061384388711 0.73581245967187 0.682855732478201 0.607029448514804 0.127276008322369 0.853185807978734 0.371497174580582 0.359688767120242 0.0831147247715853 0.113315831809305 0.200423798884731 0.814885184653103 0.349399916583207 0.707025181362405 0.0285134989372455 0.264310049563646 0.724063766377512 0.313967618471943 0.0155472736270167 0.326380189615302 0.913467625842895 0.914343720509205 0.771359322976787 0.0668176033091731 0.358904258408584 0.374140488945413 0.799631966555025 0.976640372672118 0.182136796845589 0.711771393904928 0.270095821653958 0.424791635181755 0.260957073131576 0.948124006986618 0.287251348111313 0.979118723659776 0.53426167309517 0.682758432140108 0.757123005585745 0.782528462861665 0.698755737137981 0.693422760842368 0.983808174771257 0.545138063486665 0.0668580048368312 0.347953731780872 0.30691331964219 0.0375313065713272 0.316839900258929 0.883695963791106 0.178515801976901 0.229632190442644 0.827812981535681 0.946006786315702 0.439025547280908 0.570808293956798 0.496431782795116 0.36317199512152 0.489163573186379 0.394971870519221 0.346060509132221 0.496117151945364 0.546187113276683 0.418611502866261 0.709853034284897 0.0974694159463979 0.991522842743434 0.659808323562611 0.645659847846255 0.129755696684588 0.53940368627198 0.591981733392458 0.952022889249492 0.342830871043261 0.625543020060286 0.467072043402586 0.0370817442634143 0.448378647302743 0.705101092606783 0.818863430484198 0.251862292008009 0.679667184196878 0.882104229901452 0.407045565193985 0.670504454672337 0.988685039496049 0.348840073889587 0.995538384544198 0.405469220562372 0.423717371432576 0.749626500699669 0.578662996939384 0.810300295164343 0.843923375129234 0.518047433819156 0.251508470689878 0.201280606728978 0.564962838587817 0.461352420873009 0.106918934634887 0.877858665669337 0.997187677863985 0.261968826260418 0.881722670162562 0.252578873294406 0.281941196848638 0.740028481571935 0.340676596891135 0.300126705942675 0.618095440678298 0.630770425593946 0.907023670463823 0.42858202483505 0.0396222972287796 0.615954978917725 0.0634251936897635 0.589404033592436 0.570203399120364 0.724459601817653 0.163234236931894 0.746697518103756 0.256808546925895 0.197760765505955 0.994700006744824 0.121321248975582 0.825448851371184 0.366869891332462 0.980543447542004 0.920341707342304 0.908383074363228 0.578555003136862 0.279224111593794 0.554510107112583 0.920358023450244 0.0775531848939136 0.3378950528102 0.808080786776263 0.125721912467852 0.717337967031635 0.91035470606992 0.95890385746723 0.199255062139127 0.88018400920555 0.773464029214811 0.816046845668461 0.554264366726857 0.200905433287844 0.0986010786960833 0.146271191681735 0.12391548040323 0.624540565165225 0.0888166550942697 0.387805207332131 0.112536678127944 0.167231179038063 0.755361795544159 0.464964223769493 0.782157125209924 0.924896211551968 0.568239453744609 0.866901250940282 0.941534797332715 0.566562455657404 0.805550623242743 0.523009110034909 0.927912495064083 0.178964913652744 0.679623333893251 0.810551196958404 0.152846329859458 0.582197878670413 0.748304792460985 0.235853232312948 0.231198535882868 0.117721578800119 0.357607704889961 0.563001873837784 0.941407278599218 0.542198349393439 0.566708876735065 0.296276545880828 0.219616925434675 0.813994696037844 0.117942290550563 0.921856804045383 0.0590226310887374 0.550302173078526 0.667890970306471 0.710108088348061 0.0326276477938518 0.0587745580193587 0.648685437429231 0.540195673862472 0.495977251778822 0.747906719304156 0.327274696347304 0.548190219155513 0.231572130613495 0.352014836287126 0.987684297463857 0.577303059888072 0.512386440711562 0.402886987472884 0.904600971268956 0.373406458171085 0.786218327910174 0.19135714158183 0.515028339792043 0.814574928046204 0.798489796125796 0.218520321398973 0.740989329642616 0.588232231165748 0.839989929501899 0.75422901508864 0.284669343219139 0.310034925895743 0.817056524045765 0.956355132502504 0.300223764253315 0.972873438014649 0.485502794305794 0.884526916188188 0.0458952535269782 0.0192127443826757 0.450048799701035 0.588388520048466 0.938621388857719 0.127387091547716 0.131974088058341 0.332366093746386 0.17962871497497 0.537086389341857 0.0871257883729413 0.236335428680759 0.758527355366386 0.474798668222502 0.0853535524825565 0.516758342583198 0.11065856997855 0.615822997197975 0.217419559792615 0.782929410613142 0.197835278382991 0.873404604466632 0.0655111225158908 0.0962718777032569 0.873352226498537 0.448200913174078 0.773902309585828 0.171879427395761 0.968540686503984 0.562904076075647 0.660802301503718 0.014997286060825 0.918174312997144 0.10814225202892 0.251518870033324 0.924349633345846 0.865348610938527 0.256393509488553 0.411704075054731 0.944223959764931 0.964303324928041 0.0121032771235332 0.873266062650364 0.79413308020914 0.303731810441241 0.886168193097692 0.034665863327682 0.97687752062222 0.71501439260086 0.915300329411402 0.96611095975386 0.17074806683464 0.739512333592866 0.353000093633309 0.0443683749274351 0.262931929565966 0.311527232602239 0.162647678556386 0.452349450213369 0.524711780089419 0.634445466806646 0.0466117640491575 0.811159302922897 0.850217693001032 0.590839783553965 0.652701084569562 0.162754000986461 0.739337049934547 0.878065202678554 0.685896666832268 0.73181525018299 0.77898062159773 0.588489915952086 0.12145391090773 0.511938547932077 0.09709921766771 0.226378894054797 0.535183628736995 0.239909973870963 0.944544634385966 0.664596554145683 0.161364152338356 0.528778900015168 0.0253325952659361 0.479839031251613 0.574350403780118 0.532312673029955 0.991420605506282 0.340995198604651 0.860136331890244 0.527693488942459 0.789062244771048 0.40273303035181 0.406988371801563 0.321970513942651 0.477106090432499 0.235924286041409 0.747292109485716 0.572197530390695 0.74877454884816 0.293012385687325 0.172107932199724 0.381367500179913 0.470654166818131 0.578366489105392 0.467646559413988 0.521986858677119 0.40367529186653 0.100155520073604 0.424467879435979 0.988577465438284 0.457334728715941 0.79240739173023 0.979920534798875 0.171672517433763 0.377452400925104 0.0765024635009467 0.891801154816057 0.544214458370116 0.305931460361462 0.142813933917787 0.711924330822658 0.274038441274315 0.642142298277467 0.844884514554869 0.3047250835062 0.214709681193344 0.979639720947016 0.271973123275675 0.385443869472947 0.561792932874523 0.81443231740268 0.805845848792233 0.278909232954029 0.353615446821786 0.422222611028701 0.034607741010841 0.0797438950114883 0.0624186884076335 0.23057371688541 0.0339931111386977 0.0237720930599608 0.639088634431828 0.202340972109232 0.340007577918004 0.277237527891994 0.623228729111142 0.0286835746257566 0.0906205758359283 0.181937388582155 0.296791392674204 0.728625503750518 0.502270080836024 0.640441328177694 0.259883124018088 0.0794343123934232 0.637421204496641 0.905211526781786 0.238541497399565 0.600100102005526 0.801574123005848 0.0317420345335267 0.172189381122589 0.645494336795527 0.501019653601106 0.922361383112147 0.222937583134044 0.652044182643294 0.560097698594909 0.965158092596103 0.0815187079180032 0.383251505501103 0.498558729051147 0.0648530710744672 0.52894568274729 0.65247769345995 0.297908641190734 0.940675176898949 0.17262718250975 0.698981439033523 0.647275366119575 0.128000845741481 0.88608477798989 0.734621833271813 0.256446912270039 0.530048679304309 0.432186455805786 0.705414795684628 0.462586591700092 0.765341081903316 0.503976373695768 0.520860025181901 0.289529548157006 0.45855068547884 0.126250657399651 0.965741865120363 0.15541379858274 0.529780850340612 0.750138663984835 0.796337080169469 0.988843064291868 0.123671461178455 0.745230293278582 0.702229264217895 0.285355588323437 0.225745681084227 0.472019051371608 0.50654418655904 0.478216096335091 0.518786871947814 0.179379198038951 0.853415398218203 0.458962061156053 0.333270706853364 0.0189405561587773 0.107206028061919 0.232180672227405 0.114497138999868 0.491297954064794 0.272668014983647 0.992282767458819 0.550738496484701 0.730556638962589 0.414426921023987 0.974287659518886 0.719830806935206 0.725651503817644 0.20651209538104 0.206784747375641 0.979595293926541 0.139232031092979 0.585850235226098 0.421413566265255 0.672016825454775 0.320217138445005 0.305079955453984 0.770247167178895 0.342866374165751 0.62961171155097 0.398785058236681 0.493549740156159 0.237387120258063 0.945759916929528 0.0596279491274618 0.0349918660102412 0.243185911120381 0.614130985571537 0.663581944170874 0.932905794817489 0.503978315216955 0.614475765665993 0.163646528855898 0.28535208261339 0.888573277534451 0.925514720778447 0.924870346884709 0.48648999478668 0.943549374390859 0.579269199646078 0.331324550034478 0.479177252817899 0.988740090369247 0.11978949847864 0.870954108303413 0.935216416860931 0.222002619323321 0.0624258314445615 0.304267414892092 0.206032441684511 0.146487030151766 0.859662752391305 0.885720998048782 0.651667572020087 0.288579965657555 0.773562033276539 0.263274652888067 0.478229860782158 0.761485927086323 0.499624816421419 0.757630084911361 0.428781531753484 0.944990837122314 0.563621531426907 0.612417861083522 0.836997950386722 0.192880268064328 0.873047458382789 0.108893625799101 0.0803431377001107 0.948406538541894 0.0489418416423723 0.58167831211118 0.0231462448695675 0.138578375331126 0.884626582632773 0.912800180509221 0.693194488384761 0.46149280624697 0.877441158399451 0.332022231051233 0.441985697711352 0.459931962206028 0.95143069901038 0.549225716560613 0.90418079524301 0.503675387201365 0.638482253777329 0.238829144032206 0.146803354041185 0.656868591720704 0.747521886893082 0.544595199595206 0.651255934722722 0.61406327550998 0.121127556709107 0.0652612512977794 0.286597889889963 0.824229000732303 0.746722159956116 0.96124463313492 0.988312561088242 0.309130663152318 0.604975070157088 0.36046659011161 0.619066095240414 0.614789868434891 0.676281965789385 0.708408176254015 0.279650832503103 0.522522785831243 0.81235624670051 0.450628405204043 0.734009489291348 0.644959274716675 0.240183850293979 0.708937266247813 0.0743119585304521 0.751983681910206 0.44952911258908 0.599223042686935 0.679110091396142 0.615221526243258 0.231773246438243 0.969686065525748 0.90354079605313 0.0505986477248371 0.2162162645231 0.499431215664372 0.408034189026803 0.0268436892959289 0.188287835847586 0.740530113205314 0.738504440686665 0.978816404631361 0.183630150032695 0.538738075275905 0.817463811303023 0.511931085188407 0.84780140384566 0.291712573787663 0.0346187786152586 0.363508543286007 0.726579944642726 0.701460000239313 0.95006095108809 0.321018019968178 0.170882875665557 0.487122311103158 0.0454611353366636 0.138479117106181 0.31142954017967 0.352541539429221 0.142113802200183 0.130684900241904 0.909463952146471 0.705182588321623 0.30416678218171 0.216487832465209 0.856711308725644 0.157608264505398 0.881445655680727 0.967370113576762 0.827295397988055 0.637547264150344 0.817428012215532 0.0838424517679959 0.457326072431169 0.295120578964707 0.383356143650599 0.981085621539969 0.486486617466435 0.312126808597241 0.270137623713817 0.916311979966704 0.297159399567172 0.119277307994198 0.446116838278249 0.459203425224405 0.939314776076935 0.772603684773203 0.846818558014929 0.927218046151102 0.371931094769388 0.421329420234542 0.173181112357415 0.411884344017599 0.765009999179747 0.843382007428445 0.32155695886584 0.482214670167305 0.173220557761379 0.559883926578332 0.319898610492237 0.777595365247689 0.204798873851541 0.864537826112937 0.180114670374896 0.319038180764765 0.907460005164612 0.145919425983448 0.643532962442841 0.941301421783864 0.592896569278091 0.856994818763342 0.595098037861753 0.411583044962026 0.544934991158079 0.410764346530195 0.627926597937476 0.612374707127456 0.350832709199749 0.649034153351095 0.666046948842704 0.811164361757692 0.824857317141723 0.373072726975661 0.726297704442404 0.487646619325969 0.440094324843958 0.0240044580865651 0.523328918889165 0.2744414706924 0.865299016516656 0.667103391995188 0.11511223817477 0.479716714955866 0.57802717998391 0.783485210295767 0.723909922663588 0.466432836218737 0.0170545546873473 0.128886361499317 0.733797833516728 0.563014767677523 0.134145767441951 0.932215971394908 0.708866064767353 0.680081460515503 0.0430464458675124 0.345849015631247 0.497056522730272 0.0248149741464294 0.959230988919735 0.873833041004837 0.465552415484562 0.0247654982027598 0.564446585960686 0.200810737626161 0.466708906562999 0.133528243382461 0.0165081876213662 0.876605425383896 0.79579086316051 0.0899106401624158 0.937621145863086 0.298051640230697 0.380522806847002 0.092125825479161 0.985417677164078 0.639133811737411 0.331285545581486 0.543831151884515 0.878576563354582 0.821797592698131 0.873672560206614 0.209742344070692 0.0791059479839168 0.428525501051918 0.597045086955186 0.611907686572522 0.0223828003834933 0.0545515867043287 0.739100254883524 0.960569696014281 0.666558344555087 0.443751158446539 0.0255641500768252 0.187372106304392 0.065154878157191 0.76157978187548 0.53921703124186 0.264310957051348 0.506900841672905 0.474495922303759 0.230989411254413 0.0407699715928175 0.616975264782086 0.476459234489594 0.554441040544771 0.255484427402262 0.753523007405456 0.512310302101541 0.702733967064414 0.0702518668514676 0.480052496700082 0.871564758783206 0.128136260102037 0.133650779577438 0.156768088096287 0.519489661587868 0.925050199790858 0.614232210442424 0.920693981989752 0.834241330754012 0.270968694358598 0.125349896447733 0.342824290201534 0.890811914158985 0.182712121689692 0.46463840018725 0.79122530083172 0.630940403779969 0.627262757199351 0.181566389307845 0.503002685492393 0.792135159019381 0.734691539253108 0.126125404965132 0.177805868838914 0.564632384674624 0.747933987730648 0.30074567732634 0.0732042562682182 0.893417847037781 0.676486216676422 0.82691215719562 0.213195164895151 0.916693868401926 0.292011320260353 0.0351127047860064 0.183581591488328 0.758687973774504 0.623331734151579 0.583228254544083 0.395359543410596 0.207563305899967 0.084056777220685 0.669187548719346 0.0132878689724021 0.378307614845689 0.911303738821298 0.197176998283248 0.422697233781219 0.781940979019273 0.692517095261719 0.325614887971897 0.0354990257811733 0.159427081460599 0.771848693038337 0.997640008043963 0.155470622249413 0.883358385742176 0.473795754397288 0.430313497078605 0.554887861027382 0.513775003617629 0.26485397399636 0.816482123285532 0.564433306260034 0.478922782847658 0.837204595962539 0.286173797168303 0.513895350731909 0.8360225318023 0.468403577955905 0.084832931375131 0.788966706623323 0.0297223532316275 0.900034938254394 0.673735072626732 0.888102143895812 0.267321422684472 0.548500752595719 0.724236475094222 0.202564298908692 0.352719778358005 0.592818391874898 0.597162372537423 0.704943757012952 0.366035693462472 0.0142840346111916 0.663211533599533 0.65019007531926 0.585428896546364 0.0558221607655287 0.298210995025001 0.543173894754145 0.694801917639561 0.375909758731723 0.853312515344005 0.232115881477948 0.399003928042948 0.584087432643864 0.346359135513194 0.469316413542256 0.77691934522707 0.689121640014928 0.987981676135678 0.249839623165317 0.469194133896381 0.269540513863321 0.517757547395304 0.118506093965843 0.945703189612832 0.539983308140654 0.440972369099036 0.724863450902049 0.774815268260427 0.583089807233773 0.458283733807039 0.173441760251299 0.716546714052092 0.729922535100486 0.804960446211044 0.930067099526059 0.401849099528044 0.282640766601544 0.370738923542667 0.898047451674938 0.447897620734293 0.0591852624737658 0.26485486650141 0.26141727196984 0.283857428701594 0.812298041172326 0.175087801644113 0.463316042853985 0.832249409309588 0.83691309832735 0.030631017878186 0.0377933810441755 0.710917809405364 0.725819799336605 0.924962470831815 0.528140386873856 0.953834725902416 0.664444759828039 0.0758831475162879 0.309220318649896 0.725838077710941 0.67653802000219 0.84993219926022 0.966250908556394 0.313275040776934 0.777529287373181 0.829101914186031 0.520996946797241 0.316704759504646 0.867455338682048 0.0244543479382992 0.201133377740625 0.239274986954406 0.138500968036242 0.532009432683699 0.951652023205534 0.770041251373477 0.982058207942173 0.424895285167731 0.012865694030188 0.943964842176065 0.926718069524504 0.586330140861683 0.756401811025571 0.902515380128752 0.785243997296784 0.031666382283438 0.767503448762 0.128474541183095 0.478197756647132 0.175853083003312 0.419691504049115 0.883106715222821 0.325984510455746 0.523767347242683 0.298432152797468 0.174135397104546 0.371700797579251 0.190822067977861 0.187843109017704 0.848329945935402 0.496792530016974 0.193448049027938 0.36050104490947 0.503179088931065 0.30419467365602 0.827312644403428 0.655382769044954 0.0457116563408636 0.831979124573991 0.786033285704907 0.338599587122444 0.0272601982601918 0.830236706926953 0.860562669935171 0.349190216159914 0.259741784364451 0.449685956521425 0.0790361299784854 0.115415253089741 0.0541918594553135 0.340910197871272 0.752264345474541 0.265793341093231 0.148081161496229 0.393040732771624 0.22415103364503 0.352192765190266 0.101201782398857 0.824354739757255 0.475778546796646 0.983890268639661 0.503580370449927 0.987688774049748 0.835275622170884 0.420822127924766 0.463677839322481 0.332627252433449 0.552774783405475 0.996911972635426 0.90395022260258 0.992607391737402 0.896348374229856 0.700919594194274 0.286228678852785 0.410472455427516 0.343707064364571 0.795385353076272 0.303627222771756 0.738169685138855 0.336987898645457 0.376913864023518 0.833907298753038 0.825686516338028 0.935773435209412 0.482481622761115 0.997317532277666 0.87351183853345 0.0254472116311081 0.16674691045424 0.0748029174446128 0.160436468021944 0.445353066478856 0.985271216440015 0.574532859288156 0.653204441282432 0.445885951693635 0.791251566112042 0.270888290763833 0.30350453767227 0.976658036296722 0.59035607094178 0.161881991513073 0.896121219478082 0.653302539389115 0.820708677067887 0.0970762527198531 0.724384927127976 0.877517481872346 0.383031780761667 0.343369201875757 0.456814319670666 0.700206580853555 0.775093916312326 0.0832181394146755 0.993947652878705 0.944335145563818 0.813931099059992 0.737612831369042 0.0210228257603012 0.756253658414353 0.95604334282456 0.25565625237301 0.149157837913372 0.0425232216971926 0.169975647048559 0.620483719420154 0.064831579728052 0.170567842589226 0.695154923440423 0.28567605180433 0.0848977041454054 0.37431661370676 0.717955382294022 0.0660431230627 0.589343496533111 0.510214431940112 0.168553912781645 0.585778938778676 0.112337283694651 0.970362896453589 0.811082274573855 0.886910952304024 0.51349981125677 0.904161223981064 0.440227960417978 0.183893675287254 0.187704834814649 0.237382623157464 0.465355296570342 0.744240799760446 0.677634098723065 0.388662565385457 0.513441735040396 0.967150544195902 0.812577779730782 0.319782236085739 0.110901160088833 0.0211595339304768 0.224291592587251 0.812948846311774 0.139973694721702 0.820575049330946 0.648825658685528 0.142634185198694 0.231106129800901 0.092170952304732 0.253896704944782 0.70124868537765 0.490943750343286 0.627420891022775 0.615944972350262 0.627443867265247 0.848016194221564 0.0613804950471967 0.936148077112157 0.67126590784872 0.0936077568144537 0.679212142387405 0.196908932132646 0.174007960199378 0.388317204655614 0.915032827761024 0.530795656933915 0.419391171950847 0.150079185720533 0.0547217928571627 0.613675637193955 0.891448268184904 0.654511732982937 0.669263348029926 0.788589870568831 0.421637854720466 0.0377332699531689 0.680321806916036 0.440710351560265 0.273728609483223 0.318748207211029 0.572553863953799 0.774341462869197 0.808664424917661 0.973901827419177 0.411063175983727 0.517485120831989 0.639476645470131 0.854302725493908 0.0829239066387527 0.615920045597013 0.105042781606317 0.386793005184736 0.948403409242164 0.651657707903069 0.339299552878365 0.616029539739247 0.803508441685699 0.444259148256388 0.6487631884031 0.699881490038242 0.171941456035711 0.208088535671122 0.759796336425934 0.479415104261134 0.628975243195891 0.223066696252208 0.746453570795711 0.576159414013382 0.650006390542258 0.296922715618275 0.75243169501191 0.44890748973703 0.354760463724379 0.0695469750300981 0.730568173069041 0.961952390561346 0.142731463178061 0.600893754283898 0.923768332037143 0.651937717532273 0.224505255806725 0.484216028377414 0.710769335934892 0.0104701166623272 0.0612851555924863 0.405143083496951 0.383706005860586 0.591188885336742 0.248980319902767 0.874015384027734 0.433329763303045 0.299271836392581 0.796514557749033 0.188806310978252 0.808818300440908 0.840732874493115 0.476677438835613 0.913972977553494 0.679097768049687 0.465001529881265 0.420687107031699 0.034582438999787 0.669507380162831 0.863885902806651 0.563395790806971 0.88266403202666 0.943412469371688 0.267621279717423 0.475586897702888 0.173121527964249 0.216642415630631 0.21442942008609 0.323457657166291 0.348022222553846 0.425814620228484 0.458132090237923 0.787168415209744 0.418143734792247 0.691032975767739 0.777781310791615 0.456299985053483 0.626617419575341 0.797689781982917 0.129897593462374 0.622111339066178 0.901593101783656 0.571032811300829 0.984177031526342 0.107690914392006 0.833619125653058 0.884475291732233 0.771796440463513 0.31978933210019 0.0219179716752842 0.209290972549934 0.267982835541479 0.394948469460942 0.187051048818976 0.756519292534795 0.824972200428601 0.78566536271479 0.685952493345831 0.59857087389566 0.83541379887145 0.679070632392541 0.292752578435466 0.920317198950797 0.664189330276567 0.329863398484886 0.0693358415737748 0.0318901332071982 0.0575618043169379 0.132187535066623 0.302151378311682 0.617738963973243 0.676082641659305 0.154312690070365 0.516784959840588 0.308379391494673 0.23365049688844 0.393702976128552 0.442709334213287 0.747534391644876 0.922936893741135 0.397478521200828 0.459670261838473 0.308816032302566 0.560824061478488 0.341078085401095 0.366552857265342 0.670897246329114 0.675617782985792 0.45749104041839 0.986657928873319 0.304423862360418 0.924311095429584 0.646732544410042 0.753319208994508 0.903337513506413 0.413889206554741 0.796490709746722 0.269700835384429 0.99105948994169 0.880024538007565 0.345294054285623 0.275005208875518 0.0332020151312463 0.48879917780403 0.442301348303445 0.307064248884562 0.567754463227466 0.383954802246299 0.519113168981858 0.721576373013668 0.272596821340267 0.330339015393984 0.38711574095767 0.945381866358221 0.104736074735411 0.598159418234136 0.663596995742992 0.800426632813178 0.101892614730168 0.299989561431576 0.489338843706064 0.610728996505495 0.36478070251178 0.913346074814908 0.18824361881474 0.488659859655891 0.427887604043353 0.307574273338541 0.739876314762514 0.63876663396135 0.420145876479801 0.784267843409907 0.764117649719119 0.804977548331954 0.824587246773299 0.736475335988216 0.783700617956929 0.320445254161023 0.281421022454742 0.896685538066085 0.238523661359213 0.385741038387641 0.841083274234552 0.745069978442043 0.294835014920682 0.558315505925566 0.394390276933555 0.970248670789879 0.62549563039327 0.565939950442407 0.569274169977289 0.428083436293527 0.967511582081206 0.303872554937843 0.342578129610047 0.157309225755744 0.728073538474273 0.688987222346477 0.237759284721687 0.752300380826928 0.0359046612586826 0.336815348053351 0.757429902851582 0.510478863529861 0.0757692699111067 0.739900828916579 0.38285065087257 0.914073756863363 0.476549920793623 0.944042949045543 0.193339159262832 0.589178382868413 0.37530322387116 0.951347983477172 0.546109405406751 0.305330110881478 0.939514343156479 0.038867921626661 0.158511759215035 0.388952495835256 0.0591424918430857 0.71402541148942 0.0795777957187965 0.283837123289704 0.0478704162989743 0.808536479754839 0.804285064912401 0.631964346563909 0.882189849764109 0.807441326500848 0.758892606603913 0.859352343422361 0.797325892322697 0.120432833498344 0.179439263490494 0.908156618033536 0.424023223831318 0.933222941139247 0.930742520240601 0.504575989567675 0.220748427524231 0.340426794593222 0.957381037783343 0.300972473185975 0.492340770149603 0.268725533895195 0.326894610670861 0.934639009658713 0.661154834774788 0.749946285581682 0.237186726597138 0.945383366697934 0.809008134098258 0.0493300347775221 0.125168163334019 0.308125010037329 0.0456182503397577 0.570094032906927 0.578400337682106 0.501604074067436 0.29864237876609 0.222095432241913 0.506272139863577 0.176206800825894 0.935329885324463 0.646845819021109 0.152230999951717 0.556564029767178 0.464388828161173 0.716830249445047 0.827998399459757 0.934426870520692 0.924864956818055 0.882803472110536 0.727411145521328 0.941715317773633 0.0637476938893087 0.144562249197625 0.665893230752554 0.829026435043197 0.384856239953078 0.089054773459211 0.896351531881373 0.558836406632327 0.499304260739591 0.265948384802323 0.877034156504087 0.921981278995518 0.316691189601552 0.585816629829351 0.131408872355241 0.0201178152672946 0.291599667058326 0.258606128392275 0.28763477353612 0.0311800251179375 0.433216817157809 0.569175702836365 0.217549079747405 0.052071529077366 0.341750297523104 0.83414692713879 0.0477119254274294 0.937846850294154 0.0545617218920961 0.752516492442228 0.697442560712807 0.35447442692006 0.274275422110222 0.84994031985756 0.678864471102133 0.0704553720634431 0.326309598966036 0.741452495276462 0.308374873418361 0.723385473603848 0.496776929618791 0.97012516095303 0.913409567836206 0.0392905349843204 0.782072756283451 0.801913519948721 0.204433204021771 0.870998238897882 0.897239113170654 0.610880390901584 0.0601184823038056 0.155620017037727 0.967257172272075 0.314580507129431 0.46806577147916 0.547717799774837 0.530237005476374 0.445136668579653 0.232845926405862 0.909018743566703 0.398335031005554 0.713612113653217 0.83269661542261 0.479717056790832 0.206809453538153 0.673230996285565 0.720120299430564 0.0589358050073497 0.372274915513117 0.45163640529383 0.502086790909525 0.71755421026377 0.168227089510765 0.709707180473488 0.742571768986527 0.715791383248288 0.823268968870398 0.144258625986986 0.292475876053795 0.346822908520699 0.92898427630309 0.0840946706524119 0.37609533846844 0.864436815839726 0.326056351810694 0.124738486462738 0.995012338564266 0.0474163421383128 0.125669457511976 0.32081223831512 0.888573298510164 0.24734883795958 0.658572667839471 0.548735132443253 0.945878963780124 0.782751844751183 0.84341581774177 0.66468283186201 0.136874111583456 0.725052406575996 0.453692089908291 0.148706416143104 0.924956236665603 0.532100340500474 0.685516897635534 0.0134023631713353 0.49569882132113 0.792559845054057 0.720157217837404 0.336084887990728 0.854681628693361 0.282154731217306 0.217086421218701 0.265364695719909 0.20258167302236 0.265907040059101 0.877768506985158 0.10361385658849 0.591251831836998 0.698093753557187 0.579365706825629 0.132980082547292 0.0370768871181645 0.0699172634351999 0.69160268972395 0.0492448242870159 0.118948992451187 0.878833668658044 0.522078662686981 0.81199896669481 0.895292306104675 0.242407995467074 0.414659007603768 0.63591467003338 0.473037692832295 0.699354309064802 0.715304456511512 0.22050275859423 0.358318208060227 0.094298883266747 0.811439368333667 0.339531706303824 0.259250188802835 0.233582489478868 0.644856185773388 0.559545087451115 0.753044888854493 0.138988630997483 0.664330609769095 0.236357983564958 0.86349142433377 0.524324494672474 0.515744428725447 0.348140764604323 0.464676574140321 0.0810593287460506 0.246213571997359 0.174622077664826 0.738649860462174 0.791350003979169 0.705351414226461 0.778396513001062 0.580942041084636 0.503963868943974 0.687444096789695 0.645465668528341 0.323234033940826 0.600260932245292 0.444359051887877 0.523813253857661 0.852851455810014 0.659905142611824 0.785483717191964 0.161508036507294 0.892509671747684 0.257085371473804 0.0742404318111949 0.092855510362424 0.4815884165233 0.200632500310894 0.221995274596848 0.20876829236513 0.975560798610095 0.249049636565614 0.753167668920942 0.916132213729434 0.3682409950695 0.273966960425023 0.988224800089374 0.743117798597086 0.972928925689776 0.183219907043967 0.734730348931625 0.309976768081542 0.248106056808028 0.74476192566799 0.50417588338023 0.523209443765227 0.796107389891986 0.129054079609923 0.587844487740658 0.188047187027987 0.142551188452635 0.110970890503377 0.379038556197193 0.859986300223973 0.109455912970006 0.719445561463945 0.895036180205643 0.44396439431468 0.322319293944165 0.522320748919155 0.706678808035795 0.747940149749629 0.40712996592978 0.493042566555087 0.885982742211781 0.0454387832945213 0.715603959953878 0.193263866365887 0.41239100959152 0.0854148944560438 0.4576364011853 0.0757319557317533 0.998971879822202 0.917709493048023 0.47686540911207 0.0745235241786577 0.996208620569669 0.216767764415126 0.331818309091032 0.986078840156551 0.703664591207635 0.303817129037343 0.806229115170427 0.233560427639168 0.0945810344931669 0.306420386475511 0.393123118455987 0.409414584313054 0.226385656762868 0.426466752830893 0.512744304579683 0.164776389768813 0.510004690487403 0.137892647013068 0.886074397778139 0.0208590492396615 0.315963160647079 0.624830043830443 0.681146809125785 0.550728600097354 0.69564716210356 0.301909111365676 0.265943015941884 0.0399203406693414 0.479245128610637 0.0712180443666875 0.0282733818865381 0.526270881302189 0.97314688985236 0.983393637984991 0.354643801881466 0.76567419673549 0.507412737805862 0.337895745239221 0.0723912616167217 0.0919850701489486 0.0409645934752189 0.965158557749819 0.15834465078311 0.92975808463525 0.636682351613417 0.795179789478425 0.312836438394152 0.71214540630579 0.326575006733183 0.329199965274893 0.425004833247513 0.093090527318418 0.59566188046243 0.997387961114291 0.951204735725187 0.206229043120984 0.0956528254132718 0.809487392252777 0.365993807499763 0.433324890253134 0.0994246769160964 0.0507035205257125 0.0527475474844687 0.19164168542251 0.367195135201328 0.122099824326579 0.355000640705694 0.602545974983368 0.118050235717092 0.929101399150677 0.583091582793277 0.32592015858274 0.728349097333848 0.861083851854783 0.0413944423012435 0.998895339907613 0.931334468913265 0.717011395469308 0.536907533127815 0.0975836370000616 0.0176081320969388 0.626747638643719 0.470208417018876 0.923946022370364 0.125433064226527 0.821183895438444 0.610123425375205 0.903643360373098 0.548962002063636 0.949382202380803 0.0795384819316678 0.670898721774574 0.39653006631881 0.775297240810469 0.834334731684066 0.781342882157769 0.699400638190564 0.545021432070062 0.963513295915909 0.269224792507011 0.769744625522289 0.861129094853532 0.599242216562852 0.423893625966739 0.0963773274514824 0.303414004191291 0.224878167328425 0.682468186363112 0.09327819932485 0.918816864539403 0.97408535245806 0.833099495014176 0.136450122587848 0.777073195625562 0.044578599052038 0.598782260904554 0.531249927252065 0.0231890376284719 0.870018106540665 0.417878251189832 0.230237462611403 0.764161544048693 0.784601463733707 0.925889039516915 0.256259021977894 0.375136841752101 0.164101613308303 0.36924712947337 0.495050161236431 0.142529498643707 0.713461033431813 0.636320039741695 0.473081097344402 0.718788514782209 0.185059701786377 0.496579562223051 0.764074415778741 0.0238937955279835 0.727414795295335 0.815423940070905 0.268333111503161 0.611786081145983 0.0406215679645538 0.141900970172137 0.507975115103181 0.585096406836528 0.913204590636306 0.831602480758447 0.0325575043191202 0.317992479251698 0.312643471288029 0.819136306296568 0.488256007805467 0.280852334233932 0.699883134441916 0.312010436726268 0.409596616618801 0.792684497260489 0.0939798078709282 0.740182785368524 0.408366346352268 0.284708614363335 0.839048067908734 0.282330008652061 0.229247826642822 0.492184480344877 0.0494498263811693 0.264501162969973 0.620762559019495 0.526397681098897 0.074000202966854 0.388770340902265 0.864945748865139 0.987041095905006 0.711258889476303 0.489619765433017 0.979200110577513 0.251187561186962 0.07365027990425 0.431128843314946 0.0911851170891896 0.94504951909883 0.0418373942631297 0.850013741306029 0.394968418055214 0.781949250134639 0.573475919633638 0.152826414918527 0.944954539919272 0.38143147633411 0.449932178196032 0.204508954696357 0.166710545022506 0.0878542534378357 0.171325370080303 0.948859488081653 0.746273225075565 0.534454902051948 0.26429511646973 0.652469598678872 0.152774996301159 0.24539360050112 0.0320735918614082 0.713027949274983 0.345552537532058 0.267646331633441 0.601436944336165 0.15109897715738 0.941536961749662 0.248441314620432 0.762064205356874 0.722870095733087 0.718997694500722 0.225919482612517 0.874092166430783 0.795625739123207 0.819771413765848 0.243044056755025 0.992616152900737 0.116861869161949 0.27649475669954 0.587694234100636 0.152923455249984 0.402271616996732 0.586929322697688 0.557869810524862 0.887776092116255 0.879290610037278 0.704291930056643 0.332565389294177 0.997024002533872 0.0263068253803067 0.330971334245987 0.893853578744456 0.96185008094646 0.0249530314467847 0.939399182344787 0.518362779917661 0.981053734307643 0.735576422512531 0.144537479877472 0.208443522639573 0.29892492645653 0.849828598140739 0.0845045321597718 0.243458630882669 0.913507126797922 0.522845654604025 0.619259285703301 0.739665244002827 0.526519836965017 0.900614420899656 0.544943750938401 0.273869512795936 0.159429238962475 0.455374619360082 0.0639161408483051 0.913580568069592 0.276603698327672 0.958281168541871 0.222064414003398 0.598211801273283 0.559906285305042 0.265202916963026 0.206404581253883 0.111945040172432 0.958989099536557 0.648623176212423 0.108757553815376 0.1966501123528 0.406623512418009 0.337668623449281 0.97408996411832 0.756254535245243 0.0455236563296057 0.20455582043156 0.678059057442006 0.911015073598828 0.143652687666472 0.404280147056561 0.0427347751287743 0.573373654505704 0.126385873528197 0.869952799696475 0.217096701622941 0.302499195504934 0.955746334800497 0.28670169869205 0.32836040799506 0.237280561793596 0.0987270131870173 0.983885074499995 0.964674559545238 0.367246888047084 0.338473574952222 0.696894927036483 0.326993235475384 0.251857708238531 0.187341419528238 0.433872858618852 0.713309193244204 0.14889560831245 0.929060294360388 0.340244980342686 0.76540670084767 0.878953893145081 0.496346201656852 0.359738136110827 0.997887647999451 0.393168864410836 0.0102613336383365 0.896369204034563 0.565222106003203 0.978796067871153 0.349858308283146 0.282571375716943 0.968939261694904 0.306487403877545 0.411693817931227 0.233228492748458 0.791249527088366 0.270008765070234 0.0643840688909404 0.277998134894297 0.654966358735692 0.257351485961117 0.342618514080532 0.0300561349070631 0.779849920363631 0.244262165948749 0.23869746058248 0.807287586743478 0.428600142088253 0.735629558141809 0.410825013362337 0.695098764772993 0.912108173768502 0.704797320491634 0.644126152831595 0.806237522512674 0.0466177126229741 0.602130211233161 0.376956355976872 0.0223036207561381 0.266422501832712 0.92461033656029 0.630077032151166 0.85035518741468 0.48646866871044 0.799886624615174 0.93731599718798 0.0897368960292079 0.415617483113892 0.430178114296868 0.333003851301037 0.903311435393989 0.999590609408915 0.488924271191936 0.144409465794452 0.590407451756764 0.126245056423359 0.851897868562955 0.587336340497714 0.508302264073864 0.690287838929799 0.914051845311187 0.620678613295313 0.452570468992926 0.158624486152548 0.45878985700896 0.949408754636534 0.477215548155364 0.947001828716602 0.801032545778435 0.299255021708086 0.0289605478476733 0.602485456364229 0.0862446461664513 0.4143038413045 0.93733502446441 0.572893827932421 0.468061613678001 0.605962854961399 0.350094691195991 0.919008407602087 0.148916728780605 0.0357839282834902 0.0487619875837117 0.733152578182053 0.845236897307914 0.347296880565118 0.881741746996995 0.582206161080394 0.978663435443304 0.1885876004491 0.611088508004323 0.608903199939523 0.263690817942843 0.0711896854336374 0.444913070017938 0.412508118839469 0.612950794242788 0.694155692120548 0.165944778225385 0.405214837722015 0.591024868863169 0.636350761784706 0.507797316894867 0.655769953501877 0.649474798676092 0.219322827272117 0.242684625240508 0.893491602945142 0.0168273639772087 0.237301239697263 0.377882102229632 0.406458159722388 0.113753671690356 0.923497490407899 0.416034241020679 0.64588150258176 0.337208128415514 0.326895891572349 0.0871677660755813 0.763376792618074 0.282212517692242 0.131435998561792 0.567711802776903 0.249877678640187 0.461673684888519 0.470989903153386 0.0918840259918943 0.366292978327256 0.966277597500011 0.530037583843805 0.51037356706569 0.144108479761053 0.514180601984263 0.44730755872326 0.686206441228278 0.753028685692698 0.491734054344706 0.456982476196718 0.799695714050904 0.149234737872612 0.72742764326511 0.225090607963502 0.623728642810602 0.52449613800738 0.175931520874146 0.521345254729968 0.340734609258361 0.139246255853213 0.806074179797433 0.563238356788643 0.73397465209011 0.905211642032955 0.734794911022764 0.21473326434847 0.514607861577533 0.967366686468013 0.96492322869366 0.217703703020234 0.857552240951918 0.213195988710504 0.349646520430688 0.148589799709152 0.527960509995464 0.819432359349448 0.855937945262995 0.702428969368339 0.555864784331061 0.765391102985013 0.203277739139739 0.92401618889533 0.552223723081406 0.348738498424645 0.239989699558355 0.846853926754557 0.382731251814403 0.180569240576588 0.981101982826367 0.481503535651136 0.54168838510057 0.0924901583953761 0.439783744381275 0.244998725794721 0.945831597624347 0.77032952935202 0.984057359553408 0.2917606065562 0.974355953442864 0.388183916218113 0.307457938578445 0.66964426812483 0.674279482497368 0.404172128359787 0.294385263831355 0.847583205723204 0.187418316029944 0.283228413178585 0.94792391090421 0.590644529634155 0.228639116531704 0.614647393096238 0.517133645105641 0.376789726759307 0.706763941769022 0.513906747458968 0.0629452387266792 0.495496877531987 0.921467051792424 0.291918189479038 0.42172133713495 0.0354103035875596 0.373721397663467 0.579570816103369 0.897947847465985 0.348896301938221 0.59542582832044 0.120629485184327 0.716353334346786 0.865245177163742 0.502347954898141 0.203031605286524 0.901372424147557 0.600133215279784 0.231398065160029 0.386146900679451 0.239984446871094 0.050187352723442 0.616607554776128 0.129088225073647 0.652332474451978 0.0267433804413304 0.723882606523111 0.846733391089365 0.848073344510049 0.133099002852105 0.0442488426389173 0.631991580184549 0.979498355477117 0.201240537355188 0.161574544729665 0.474760172488168 0.200468392558396 0.303975883142557 0.125102787108626 0.974448127869982 0.645494820619933 0.841862431142945 0.446971256504767 0.0617560435156338 0.237989532584324 0.532246463538613 0.314953116923571 0.692610595999286 0.407179092431907 0.55334868328413 0.584726415087935 0.303672118403483 0.255491914809681 0.0839596248650923 0.180384394298308 0.927536299114581 0.102167482774239 0.73306664806325 0.186072385683656 0.412071558246389 0.879284190316685 0.633806820204482 0.553065676894039 0.715995889070909 0.39052091833204 0.170648076534271 0.882747940639965 0.254760241152253 0.691569482865743 0.733381351060234 0.577813806736376 0.702222667241003 0.374695337344892 0.741110693502706 0.919746249963064 0.283708604406565 0.23834595304681 0.0195323739061132 0.368356176856905 0.885210499681998 0.926337406670209 0.569222444100305 0.88341023493791 0.690503305138554 0.898017767122947 0.862747515842784 0.98762364791939 0.164638949292712 0.77072547520278 0.184387629579287 0.896335086922627 0.0178494355431758 0.143458482071292 0.0534495504200459 0.285151278427802 0.715700311544351 0.548903523851186 0.553748523702379 0.299355024686083 0.751849608151242 0.8804221086693 0.373943357814569 0.866929564694874 0.0620646923687309 0.866139214592986 0.931829677138012 0.812524819974788 0.650203891398851 0.918112531916704 0.252503579705954 0.636583683243953 0.446162231564522 0.426991993205156 0.315673497579992 0.0372351011564024 0.577435617172159 0.172396911596879 0.0389712519058958 0.263209920225199 0.259863981259987 0.243943128355313 0.591180485140067 0.912593990406022 0.0318558245478198 0.102046017493121 0.807279750816524 0.847855680922512 0.362094555050135 0.189639899630565 0.52355556584429 0.487352602300234 0.83666816032026 0.873697039785329 0.820981800900772 0.119430396812968 0.706545367236249 0.154057843228802 0.12264638478402 0.587129520201124 0.224535941891372 0.853679777022917 0.71020817730343 0.195530335456133 0.465312829050235 0.324393215903547 0.415556223890744 0.257025412053335 0.27510187394917 0.0235858711437322 0.833957564397715 0.858510562716983 0.785985070609022 0.867961675329134 0.0662346361600794 0.588236453507561 0.547079763773363 0.809134611883201 0.705607956182212 0.927568370518275 0.499419363234192 0.103066568896174 0.47591825495474 0.885217479984276 0.537228775245603 0.493698156231549 0.193551781072747 0.411932352352887 0.362117556417361 0.678279462854844 0.183485760833137 0.556425235550851 0.36666359934723 0.0285076384153217 0.45267846994102 0.322366814767011 0.235814956016839 0.122941082022153 0.11430397112621 0.731927493065596 0.615891144752968 0.958961771870963 0.18448358470574 0.639110555895604 0.712343825944699 0.580051820313092 0.875489928915631 0.0360470211156644 0.393542888336815 0.700155368074775 0.656973098022863 0.702020799978636 0.785993087710813 0.146470355382189 0.36451780237956 0.4361590031581 0.144429374511819 0.209113979947288 0.371019097520038 0.20242241342552 0.69377172708977 0.927013086238876 0.737870787226129 0.59894102008082 0.0766680787387304 0.171618011698592 0.0262009823950939 0.804366910068784 0.685503055739682 0.805910663744435 0.797953240161296 0.664761072883848 0.988585077547468 0.0507458995329216 0.443019787438679 0.11339718415169 0.909735385475215 0.643837482999079 0.154961459413171 0.473095485761296 0.733464878422674 0.693393295037094 0.531655136530753 0.3066858970467 0.920350275575183 0.877168948738836 0.164563383019995 0.390902939767111 0.947886982124765 0.477391636958346 0.46936839596834 0.200903290077113 0.167522600376979 0.613447136769537 0.687199780677911 0.729782191908453 0.977119843580294 0.766256707489956 0.50027424500091 0.887765376062598 0.333698419614229 0.715458013941534 0.122946245505009 0.516841162764467 0.839178333999589 0.641477545672096 0.35677606720943 0.581152958099265 0.916704689334147 0.523354097811971 0.922572496284265 0.0154996559931897 0.971650646396447 0.388730057622306 0.841294857170433 0.162906880048104 0.749554693920072 0.71330284451833 0.0472588196070865 0.841840817630291 0.387843417704571 0.36041964877164 0.756159556526691 0.30639755130047 0.437653803669382 0.29184921695618 0.300476513523608 0.245122659064364 0.47558743938338 0.983718768677209 0.134164281620178 0.174962451015599 0.383471595817246 0.921037164703012 0.16396733348025 0.74838627088815 0.0455442408798262 0.0435700722644106 0.595699510429986 0.425769849529024 0.779022954504471 0.838770411247387 0.476576306396164 0.958300255979411 0.152023583806586 0.105781925613992 0.796692560412921 0.175547072479967 0.967764014641289 0.681516534413677 0.528557785807643 0.222000252755824 0.222237669241149 0.421112475583795 0.647218891894445 0.888396541711409 0.702921342414338 0.0157023763447069 0.273171583989169 0.900099220746197 0.784046518523246 0.657010058150627 0.878593491676729 0.420795300218742 0.645568502305541 0.0270284599694423 0.461918302727863 0.914158802083693 0.723683539403137 0.329017495936714 0.349406472300179 0.426231831302866 0.606717150809709 0.619687696194742 0.720614581957925 0.0579789195023477 0.992545086725149 0.471495663083624 0.74952417886816 0.108259690664709 0.792960597570054 0.296121616731398 0.226285146679729 0.18170160912443 0.264409280589316 0.896493160815444 0.600884466653224 0.913260087762028 0.909015936970245 0.391793822310865 0.532426022554282 0.436504328851588 0.997069040846545 0.415685906119179 0.60125123367412 0.16813003258314 0.997532301216852 0.133993972202297 0.524244621463586 0.653620905759744 0.854194983860944 0.0982382258353755 0.223335463129915 0.703178558819927 0.10147550761234 0.991708672805689 0.442236525975168 0.945618212851696 0.746629532591905 0.765541853357572 0.496723728065845 0.34175513161812 0.449134492818266 0.502359510441311 0.936627702226397 0.793391571708489 0.326308472270612 0.367369008646347 0.415652475904208 0.757921181011479 0.750416977577843 0.118624536669813 0.801429917055648 0.918941802107729 0.84165226303041 0.482436047377996 0.187017820985056 0.303605718286708 0.806540862666443 0.304728948799893 0.125757054162677 0.543484957888722 0.516796548806597 0.982930322294123 0.540426448883954 0.502437338172458 0.24553124404978 0.699760574044194 0.647138555606361 0.824215442584828 0.40623369009234 0.871943808582146 0.583950016601011 0.187839961969294 0.35866443063831 0.128833788526244 0.883332981618587 0.873015595583711 0.982169096623547 0.0479583990410902 0.946699375074822 0.537931462081615 0.650453693927266 0.628091519824229 0.242215892053209 0.419519205165561 0.0340191277069971 0.884281818212476 0.0876661471650004 0.203173935178202 0.0587959786015563 0.645813142503612 0.695484929718077 0.382742658453062 0.790978687764145 0.358558359225281 0.852837945837527 0.102456235126592 0.375008349837735 0.784350602969062 0.473676898172125 0.58943088988075 0.656660315801855 0.602296297617722 0.996678978798445 0.495347643634304 0.17514233665308 0.0271382652898319 0.726561205033213 0.306055312955286 0.729851530469023 0.290968618965708 0.0458879555924796 0.146990905725397 0.98646784973098 0.396655306767207 0.562164128306322 0.121929315293673 0.436902776805218 0.286320979825687 0.72686262187548 0.425492133167572 0.228970646660309 0.283651222693734 0.511585324767511 0.607206434893887 0.45639912111219 0.0480668842745945 0.493782626809552 0.829111198359169 0.180179946562275 0.950316571725998 0.907008778629825 0.96389217422111 0.256193391508423 0.38836728082737 0.746961643586401 0.966149598399643 0.555041633746587 0.910764642951544 0.471923462052364 0.618991513904184 0.8545815208368 0.730841077924706 0.51343029613141 0.0622196408803575 0.502153609849047 0.790552590133157 0.252769077599514 0.650594845721498 0.287917336209212 0.938058686091099 0.309930683057755 0.849713783774059 0.0353567643486895 0.312104118177667 0.435729464357719 0.915718012554571 0.855338194316719 0.16366715305252 0.206160739054903 0.329193300530314 0.950121867554262 0.348866027530748 0.842808663982432 0.117645324938931 0.31576776473783 0.217459993360098 0.597442214130424 0.750581740878988 0.388776673031971 0.0247500453260727 0.362989818060305 0.25379522606032 0.627395519400015 0.368741191595327 0.728903403361328 0.725329637038521 0.543742334723938 0.756232016780414 0.738152036727406 0.913425017716363 0.438836761487182 0.369407770931721 0.0689864087896422 0.449625399408396 0.930451134399045 0.632708946561906 0.703807105501182 0.59879427860491 0.485397171450313 0.516699720998295 0.334604483272415 0.97948887422448 0.234834380403627 0.0101932987989858 0.676669697458856 0.357588614225388 0.355930680064484 0.26435432353057 0.900781642969232 0.989691420998424 0.894920792349149 0.592294420185499 0.439690326163545 0.650636513859499 0.881517940061167 0.0166624206537381 0.187910152236 0.524065352419857 0.821306122299284 0.904553931273986 0.988051209931727 0.917402362513822 0.91599407275673 0.822971718357876 0.153490451353136 0.597634697181638 0.72358290530974 0.881678380751982 0.0983770785992965 0.778492220337503 0.795373414207716 0.653668229964096 0.460365483856294 0.187828835160471 0.335149972354993 0.707238848269917 0.21416300410172 0.500993209450971 0.63750985131599 0.58701968583744 0.812158150686882 0.915078676519915 0.292959253515583 0.565082534532994 0.0928774108504876 0.655174124783371 0.724708439002279 0.233377252502833 0.29131429917179 0.296764168965165 0.259237780170515 0.774266806619707 0.172325970123056 0.0690028629684821 0.582731863842346 0.972901345624123 0.440765687795356 0.33896849620156 0.965372099955566 0.309529538457282 0.540899218858685 0.765288548807148 0.524121471671388 0.342725847493857 0.195593669430818 0.185089836048428 0.329542228514329 0.449763783100061 0.33982940007234 0.447338201012462 0.844293659846298 0.67884678673232 0.924538184949197 0.692895209451672 0.92423639630666 0.838978048674762 0.284191997542512 0.497935357147362 0.90241491706809 0.79834207570646 0.579603611975908 0.844692042567767 0.305013291412033 0.0392180473008193 0.979570898481179 0.107363076219335 0.222592481258325 0.540897556936834 0.0718894481169991 0.0753151759272441 0.201759970223065 0.631422856927384 0.108730679778382 0.444387421654537 0.581986922700889 0.116775974310003 0.144235319204163 0.335556172332726 0.495877792555839 0.368554097688757 0.471966468256433 0.319141277084127 0.905900610061362 0.287292577142362 0.182774698233698 0.587999835943337 0.855276600634679 0.851337548729498 0.328741179185454 0.467536395431962 0.64568932863418 0.556842211051844 0.0314607746596448 0.471250069758389 0.272437518869992 0.556818087138236 0.0462991710705683 0.0400503366114572 0.379200347401202 0.899100632527843 0.0305075642839074 0.950492518770043 0.611841536550783 0.176353258553427 0.364082808510866 0.876095700813457 0.785600484143943 0.220520965973847 0.385024125177879 0.149299973030575 0.539299101599026 0.145798806184903 0.264392952956259 0.78852653705515 0.398308629498351 0.163569066931959 0.31602868254995 0.13568423869554 0.266287870719098 0.762274564325344 0.630035040387884 0.708055976980831 0.282129696588963 0.615562515726779 0.804953497948591 0.238808359175455 0.787796458243392 0.267395940402057 0.79047286398476 0.609030644912273 0.0664080324652605 0.784516303031705 0.715988692787942 0.36263465706259 0.825520846932195 0.117222355224658 0.183362701397855 0.844390187310055 0.585558075127192 0.47413819581503 0.401451479769312 0.195928372885101 0.619940469437279 0.246605268537533 0.829930471894331 0.215514235540759 0.738651351351291 0.760916679436341 0.147389695513994 0.384704863536172 0.980337145875674 0.929786959432531 0.68102496051928 0.604930239527021 0.191083822282963 0.29593416116666 0.618994205479976 0.957439192140009 0.0880741999205202 0.220014513614587 0.371075991720427 0.440320173799992 0.632948518474586 0.62134006556822 0.960465662011411 0.935226302414667 0.983732427323703 0.675978873656131 0.31082090198528 0.241737943151966 0.845695808329619 0.310440721111372 0.672959350203164 0.0278831847640686 0.428504613391124 0.918763002827764 0.478441880058963 0.206578737294767 0.890841269553639 0.663887559152208 0.757646768440027 0.688233299681451 0.112127075935714 0.154938358468935 0.521629997263663 0.500162172459532 0.390737738742027 0.371505333902314 0.968780573282856 0.419420536335092 0.104988638912328 0.474135080806445 0.148996987158898 0.354963098790031 0.905581435088534 0.942153974324465 0.0215400441922247 0.672508982750587 0.678002172922716 0.6381870243093 0.106446816290263 0.551167068327777 0.198592683016323 0.912850312001538 0.158559153031092 0.0110096931294538 0.856835267811548 0.0242523301579058 0.878455582589377 0.216773970229551 0.836780574696604 0.640830063684844 0.296486214725301 0.689851071576122 0.634643404695671 0.122733429381624 0.297980602406897 0.163388103004545 0.907222769162618 0.278802630233113 0.984075932509731 0.590063283415511 0.590536295187194 0.495197997828946 0.264753637250979 0.146564413704909 0.770679762440268 0.091605768641457 0.334694116411265 0.370541911581531 0.529221537341364 0.905147266418207 0.349658884576056 0.66371405266691 0.308665858646855 0.760454167046119 0.499424702359829 0.0417201660759747 0.201020228292327 0.389763330910355 0.94537922226591 0.103994090938941 0.322844540080987 0.14334385786904 0.81040105949156 0.115124969510362 0.0769128835154697 0.998697086691391 0.964064645059407 0.0975284540490247 0.339214945151471 0.756740329524036 0.589719358484726 0.754449235869106 0.262894867095165 0.66466396732023 0.905298905838281 0.505089732024353 0.754932457972318 0.798077664170414 0.26810808129143 0.298719445609022 0.42150687845191 0.306240541406441 0.995911543625407 0.0858446941850707 0.672552429905627 0.363003843205515 0.906320140219759 0.250557155734859 0.913423858750611 0.835984854351263 0.28894220192451 0.647383686313406 0.669609618782997 0.488392786509357 0.610161670784 0.629254556708038 0.503290045841131 0.353668752331287 0.0668701232667081 0.253751239990816 0.22134604355786 0.408457890124992 0.0270999094704166 0.167184251528233 0.0235991434683092 0.506475602663122 0.658080446003005 0.02542058077408 0.563648397857323 0.142761475043371 0.807314206766896 0.0325171710201539 0.337683285472449 0.342866883806419 0.337398598259315 0.987597137384582 0.491872982252389 0.755475622208323 0.372459684573114 0.82163221049821 0.349264300763607 0.5315291803726 0.109933101444039 0.224050423754379 0.388857221612707 0.175467228314374 0.233716704996768 0.345461899172515 0.688945962197613 0.872347360318527 0.249621627423912 0.536616647706833 0.107688282516319 0.572809646404348 0.069137893312145 0.666936737422366 0.438977281935513 0.119575904179364 0.10584137216676 0.344247509595007 0.874216703155544 0.6289607268502 0.77362705913838 0.662108538425528 0.678383781758603 0.0199841444264166 0.343253215865698 0.425862368787639 0.88036516306689 0.265075054320041 0.307680853931233 0.128394199823961 0.415499887736514 0.341531279042829 0.231506056657527 0.840392789731268 0.210823612094391 0.826453753279056 0.196809209214989 0.0904270546021871 0.329480285160244 0.488643761372659 0.814542382268701 0.646844743727706 0.60592079058988 0.378135099059436 0.867257475475781 0.849749464383349 0.815425694424193 0.561021705938037 0.748294935259037 0.632407115967944 0.899159729869571 0.768059142413549 0.221014778737444 0.283861168371513 0.568664273931645 0.0468489629402757 0.149190716766752 0.36487740492681 0.217731877320912 0.592553229823243 0.379156022954267 0.438656358141452 0.813474501590244 0.926075468885247 0.466756121970247 0.481261559599079 0.18555853396887 0.298908284418285 0.0481028903531842 0.106085983782541 0.813593104262836 0.783227178142406 0.386737680705264 0.0511023416626267 0.909566917771008 0.520281588556245 0.443490085045341 0.555034381682053 0.9885206505307 0.42306637221016 0.874864306617528 0.493969874461181 0.415923721604049 0.223823145914357 0.0934386709029786 0.809712819159031 0.154719579019584 0.11106116789626 0.0792772628529929 0.51636823927518 0.615744832933415 0.427952531711198 0.843956428933889 0.470519460099749 0.253055401840247 0.151647824889515 0.24217557719443 0.949241270946804 0.291492868179921 0.264257500332315 0.20593603315996 0.62596354506677 0.331161710505839 0.450665682503022 0.352352907611057 0.983873707738239 0.676778532594908 0.733163189587649 0.48118792516645 0.81019746807171 0.712690556088928 0.989742425864097 0.837625187584199 0.264325211085379 0.749246881790459 0.273770728022791 0.214355687459465 0.96505082556745 0.20849750536494 0.976388841376174 0.710043627216946 0.637885210542008 0.240804056478664 0.672773391520604 0.891926842669491 0.122245354512706 0.548976619830355 0.0960297942371108 0.829253154606558 0.966527299990412 0.429509614415001 0.610860094018281 0.40965517366305 0.829936300145928 0.816829028381035 0.892693008005153 0.142478564772755 0.177070887011942 0.865482254580129 0.475058133869898 0.938183041180018 0.473040593934711 0.289635886030737 0.503983971283305 0.396019117550459 0.106042707199231 0.69414939226117 0.148849339117296 0.925282130551059 0.534915097663179 0.254947147660423 0.307255055953283 0.209738641050644 0.24438112659147 0.846391653395258 0.59996243517613 0.934495653801132 0.757637433786877 0.916327306989115 0.305466435726266 0.623312072993722 0.0241988985636272 0.38794092272874 0.44876825641375 0.820130155156367 0.315007206602022 0.777510595016647 0.854513459028676 0.964895413054619 0.0941754718543962 0.631480995148886 0.379624014615547 0.777213394984137 0.641247929846868 0.718791695022956 0.0545629891939461 0.0545385176828131 0.332723823462147 0.286484694802202 0.862030407397542 0.707458721913863 0.66856733054854 0.113111845308449 0.617680758214556 0.507169477625284 0.565268962057307 0.639324944736436 0.511422966066748 0.409156376977917 0.387319236949552 0.0504640504950657 0.536955560825299 0.498354728720151 0.217881421705242 0.652519128329586 0.764568424469326 0.0123729692376219 0.275824835540261 0.410682102143764 0.335269440102857 0.159268975527957 0.749247571914457 0.470894494778477 0.597069359773304 0.463537722483743 0.511548316925764 0.595063341727946 0.859786310633644 0.687646877532825 0.953838146787602 0.0497491083107889 0.433931648700964 0.975208044517785 0.41565610055346 0.527999701846857 0.452605437580496 0.494496753937565 0.925919123759959 0.449876924019773 0.739442870330531 0.0697565864794888 0.0230912066739984 0.952871837655548 0.458207137419377 0.408013553535566 0.50545909196604 0.174105998836458 0.194057810229715 0.426532534970902 0.657468486500438 0.821348359086551 0.785901851889212 0.487021824761759 0.652683696625754 0.702153006899171 0.599765909805428 0.843353264939506 0.622300468999892 0.686143590155989 0.0255158148892224 0.156035512944218 0.145949547798373 0.223543966554571 0.299875274454244 0.429530014102347 0.84652125056833 0.536823327166494 0.505754476101138 0.676362373533193 0.576495853611268 0.763395434725098 0.0263907303055748 0.633907953796443 0.0999053782457486 0.176371575421654 0.19716413510032 0.382982559753582 0.762337656042073 0.734400837081485 0.15843880268978 0.55771374108037 0.863297420889139 0.11795756686246 0.910951119572856 0.810085884195287 0.903504155401606 0.140878532107454 0.286836596727371 0.704543663733639 0.90317619828973 0.605805597507861 0.471694042154122 0.845384665671736 0.348119150861166 0.799337199474685 0.173563939859159 0.456382152913138 0.371635248246603 0.870929072292056 0.572710719180759 0.533351151752286 0.234723236556165 0.424855480641127 0.0422593523026444 0.0589975042594597 0.141092494749464 0.236619744554628 0.487545729605481 0.609139934598934 0.511603563725948 0.782221267786808 0.0461786533845589 0.142502166137565 0.31594038286712 0.266741177306976 0.506045685838908 0.0927888527745381 0.976066697072238 0.37378013565205 0.689419920872897 0.844347083372995 0.491333782887086 0.843158507060725 0.0789141045766883 0.20394481520867 0.379926383201964 0.882446679386776 0.146265902575105 0.537874844714534 0.0188933986076154 0.581959728726651 0.649644795532804 0.186255617754068 0.0553543991455808 0.186997630824335 0.481734591193963 0.302216318196151 0.781534840124659 0.531153952993918 0.890716876431834 0.0737672692909837 0.886843935132492 0.930152392075397 0.698962686976884 0.784156387692783 0.454254778614268 0.0971555263921618 0.309446732336655 0.938892121459357 0.574255597246811 0.107104687939864 0.86270409588702 0.0781872442690656 0.411984958518296 0.981920715142041 0.817288302674424 0.476185136784334 0.514874794348143 0.130167371553835 0.358957585124299 0.602370495628566 0.834813885882031 0.0975201880047098 0.462112402752973 0.686301591901574 0.728821259934921 0.349666643976234 0.70237339571584 0.544284598387312 0.26805763585493 0.593342066446785 0.953503386629745 0.732467795615084 0.0119305843114853 0.0291024307953194 0.557175516048446 0.918468492988031 0.933526083522011 0.59645124055678 0.505461174093653 0.850042330510914 0.939143992054742 0.994493581529241 0.408245662704576 0.508283488044981 0.288246114139911 0.272015894597862 0.128603420341387 0.869295112218242 0.671496625244618 0.690748694930226 0.991806510675233 0.944426176007837 0.23677930818405 0.166779970251955 0.582241067432333 0.0888322144630365 0.200373752447776 0.76278344640974 0.775301748283673 0.028110449926462 0.709288630411029 0.537279220221099 0.0662326031294651 0.44146105802618 0.78557431336958 0.381090098915156 0.828098645387217 0.619561043228023 0.609196652695537 0.212298935388681 0.946558666536584 0.648003163188696 0.714029037752189 0.0704278560774401 0.658140781603288 0.219878343897872 0.871889029471204 0.98681419839384 0.48810351206921 0.802157145936508 0.198634817691054 0.0708639033418149 0.0733162870886736 0.964974218807183 0.743336595564615 0.219232332746033 0.578352158775087 0.426349477621261 0.44438837063266 0.0498644028138369 0.977154916124418 0.598795358277857 0.946193149529863 0.548469133898616 0.56252378686564 0.67223179838853 0.971653519147076 0.699533115029335 0.358095680642873 0.137689498388208 0.522846348877065 0.731542695460375 0.934684631603304 0.498503668266349 0.187916382714175 0.322344385737088 0.547472369875759 0.355709354947321 0.326526107045356 0.450987676519435 0.452166858708952 0.128717910160776 0.997759012251627 0.897258680975065 0.71587010002695 0.782452112189494 0.308315164092928 0.846927750660107 0.413000602757093 0.646309960095678 0.0932263863179833 0.100380053322297 0.957369277093094 0.96804382073693 0.928410226828419 0.356879362682812 0.55996830979595 0.313873262109701 0.401072408303153 0.193996052660514 0.804034565805923 0.960875078418758 0.738418044261634 0.761576853112783 0.702864559085574 0.465037605802063 0.548842851947993 0.44245594161097 0.454003138521221 0.363500613083597 0.530872393928003 0.69404536425136 0.82066414240282 0.473474617388565 0.84031264429912 0.169743011873215 0.977577605778351 0.23309031581739 0.684903629801702 0.542446199336555 0.136395592419431 0.792993907693308 0.873104018815793 0.376001716256142 0.165124540268444 0.533950571236201 0.191504409525078 0.176493240317795 0.0246454820898361 0.568890328265261 0.995584075869992 0.865616867945064 0.306797016691417 0.780466372587252 0.594496471940074 0.922911020314787 0.0850966553227045 0.640706980277319 0.0787080062134191 0.18261466461001 0.599624158935621 0.73348710852908 0.104404028512072 0.401041309849825 0.875299986922182 0.204421574026346 0.781785637731664 0.731875561580528 0.203155587883666 0.740524913533591 0.375952684720978 0.52857566080289 0.060063427281566 0.0310296829650179 0.864384928611107 0.353292638210114 0.493806009427644 0.993021120843478 0.817630110671744 0.162359422475565 0.514905580009799 0.0751508538075723 0.134646072764881 0.954131410992704 0.345670843778644 0.939788382544648 0.528456798584666 0.422493908591568 0.199094815300778 0.341304816259071 0.879396471462678 0.0582646209257655 0.570876040668227 0.379817185255233 0.524581404509954 0.847758540322539 0.0384491790947504 0.729823612717446 0.257631811609026 0.504387334468774 0.565441204698291 0.543121798459906 0.0444947487558238 0.0244280932610854 0.163998837617692 0.767612353509758 0.791320650198031 0.482859425311908 0.502209510123357 0.747024213215336 0.992028117696755 0.152756942205597 0.635225482336245 0.566417057779618 0.0270938518689945 0.667372346501797 0.0512648400478065 0.0212525586807169 0.0604385774419643 0.606063296815846 0.578554426881019 0.313324067471549 0.34825739532942 0.873612438281998 0.49881234316621 0.452765561791603 0.225186199818272 0.591381449063774 0.67443644536892 0.314019041468855 0.0981655993894674 0.746874683813658 0.216995246019214 0.136671926458366 0.50557338954648 0.110719183103647 0.564583081838209 0.0307190070743673 0.841398637851234 0.420601413869299 0.27426388892578 0.453627639841288 0.258343320230488 0.0188816736452281 0.521884100735188 0.969785668812692 0.491657297988422 0.874055198235437 0.501460728121456 0.116490740575828 0.735731868448202 0.482208493165672 0.435318276309408 0.913764231179375 0.80429211436538 0.837597165645566 0.577928913149517 0.72202173095895 0.085738262035884 0.282958841617219 0.876331978156231 0.318250043485314 0.255746176636312 0.675368797588162 0.312660822581965 0.231322502575349 0.862643453488126 0.353243338831235 0.79606208511861 0.596014836935792 0.513166963346303 0.310061898357235 0.595092076379806 0.256615102449432 0.103261628272012 0.996500188047066 0.894800359026995 0.37494234318845 0.849495406781789 0.549838750895578 0.818907666648738 0.116787975875195 0.891252490794286 0.246365114836954 0.599963946349453 0.566991456004325 0.500969776352867 0.705442292538937 0.715752172034699 0.639417947588954 0.218978575258516 0.466277602114715 0.601119734395761 0.196076979355421 0.304954947582446 0.972834390918724 0.555497548237909 0.745871559770312 0.724518686942756 0.017589962289203 0.995066999658011 0.755495028200094 0.498513017441146 0.625811891586054 0.453141348599456 0.0125029670237564 0.49509642789606 0.0488564160931855 0.0819657941698097 0.42314050775487 0.68456208688207 0.843161692603026 0.473515602778643 0.383511739643291 0.577065553045832 0.826978235761635 0.649837987609208 0.591432165571023 0.387160652494058 0.21175919480389 0.869893484299537 0.414555221160408 0.902666413558181 0.0874809147953056 0.674176289597526 0.451725944157224 0.900577541908715 0.092076113501098 0.756548290189821 0.779272814197466 0.162598472300451 0.19411887974944 0.470550120137632 0.152859189815354 0.704408951252699 0.449988488764502 0.719091888819821 0.795323780600447 0.632461070572026 0.866942143898923 0.223750586083625 0.149708649525419 0.356174828370567 0.125982260478195 0.15964011517819 0.833427393578459 0.688360275581945 0.14989457685966 0.776139885208104 0.543608996036928 0.439606226463802 0.299518336514011 0.919717722302303 0.486680963668041 0.514631750378758 0.885517483155709 0.149280402229633 0.605412023065146 0.284645394487306 0.0675200093933381 0.467698203462642 0.16492473945953 0.785425166140776 0.224950461850967 0.0117105838912539 0.674207371454686 0.427923025568016 0.119657216183841 0.904673268788029 0.547388341862243 0.382197724650614 0.446616902265232 0.441469404285308 0.921647330897395 0.55450324367499 0.409151775920764 0.525851439195685 0.0811830773833208 0.643513922027778 0.383141143287066 0.596798395747319 0.15778911087662 0.731719103278592 0.899957786125597 0.686716870674863 0.58883995634038 0.620897199122701 0.387049478220288 0.530549117627088 0.501800500091631 0.562933196127415 0.78166894223541 0.26004513143329 0.708301919978112 0.413969304042403 0.922645895374008 0.936707191187888 0.855169991229195 0.780503051502164 0.36119406954851 0.126003522474784 0.367041499400511 0.343547702424694 0.682208114264067 0.657381310516503 0.183035172098316 0.793829732909799 0.365560074478854 0.248088473398238 0.268683584544342 0.643003731842618 0.256959980276879 0.257265927181579 0.382260120250285 0.652701957020909 0.015324324159883 0.412380825076252 0.0790075954026543 0.774026767017785 0.734062382893171 0.510031361682341 0.291827008977998 0.145293963653967 0.165651168727782 0.121906506165396 0.283783506602049 0.0436110053304583 0.0854314631945454 0.715377039161976 0.773697551824152 0.299567234588321 0.23232224238338 0.936675222588237 0.138167250901461 0.0595146039826795 0.534868347870652 0.985637122534681 0.859676337738056 0.442077433031518 0.0435690375394188 0.229346045763232 0.181640654625371 0.441510441538412 0.949292388758622 0.504072430473752 0.89370290950872 0.968121613892727 0.0586289778142236 0.324418620257638 0.661710839834996 0.791330917233136 0.0330510695232078 0.90081427795114 0.446585839309264 0.580679025931749 0.503162191035226 0.467115440999623 0.541579117542133 0.56989295557607 0.598425036910921 0.562000147791114 0.636711452302989 0.494023099755868 0.180682755601592 0.0832375848223455 0.0700516651989892 0.927492481081281 0.855725137437694 0.51878572358517 0.633586856203619 0.054274932728149 0.499409641337115 0.0376296437089331 0.757789242395665 0.146756978353951 0.272454594022129 0.783302499391139 0.626171573195606 0.714328110155184 0.614639557630289 0.654623065611813 0.3030324147176 0.0580026259762235 0.469498792062514 0.294808822018094 0.714830828837585 0.71385908653494 0.691521211296786 0.0490456324652769 0.128272955825087 0.10327611672692 0.209418779180851 0.470856173764914 0.729136945793871 0.192823130453471 0.543437335414346 0.27435279321624 0.428757776874118 0.971693768082187 0.0195562454196624 0.372131005066913 0.460310471937992 0.640869969401974 0.5121497108927 0.109064439556096 0.586623236339074 0.4264328964171 0.349205129430629 0.708947801357135 0.189091948783025 0.506080718506128 0.235746287757065 0.332355506543536 0.617822744427249 0.0292189935222268 0.355817712252028 0.66722550567938 0.617587248948403 0.29878282614518 0.702212931052782 0.246409650193527 0.116390549046919 0.573518353500403 0.73199130325811 0.61366494303802 0.616360213090666 0.78983309160918 0.417269440579694 0.0652991675492376 0.609366571181454 0.0923397122859023 0.134243843650911 0.319180157757364 0.0567206690181047 0.393150624069385 0.715811864533462 0.431455011728685 0.918070217911154 0.190318277920596 0.880368769275956 0.874853153070435 0.979584255861118 0.757387028725352 0.933562534239609 0.794570792622399 0.174880139322486 0.827175325171556 0.330453428917099 0.644393812837079 0.876421059011482 0.493044338426553 0.872093278053217 0.705406443893444 0.979114003202412 0.269965430400334 0.523649451751262 0.285547244332265 0.357966765295714 0.10443285766989 0.417945439163595 0.34690171404276 0.995146691000555 0.156512414442841 0.145450362025294 0.632808359684423 0.941335536590777 0.316464460357092 0.880012380392291 0.558712197451387 0.11076139776269 0.900451955937315 0.0192150530940853 0.144196872566827 0.258548763967119 0.909425012234133 0.053710483906325 0.716060654926114 0.28310181484092 0.557983337996993 0.875361044455785 0.852690115468577 0.862806819714606 0.714699551071972 0.131992567430716 0.319882554851938 0.989065136236604 0.305373874516226 0.231852603321895 0.44386536244303 0.428621583185159 0.229368716129102 0.32566111567663 0.544096004141029 0.186323718056083 0.664493651909288 0.238374458809849 0.993928194332402 0.196961656315252 0.686537403168622 0.252918107502628 0.900610786569305 0.446163249462843 0.920198240382597 0.270399229344912 0.481852160294075 0.772042306934018 0.778667486016639 0.120168976781424 0.240550859111827 0.418456934452988 0.80872104505077 0.223888436623383 0.0853813480678946 0.354442109800875 0.504873376768082 0.374523737113923 0.718484035255387 0.98344973441679 0.644427264488768 0.440550053780898 0.0891936992923729 0.643685116344132 0.67207973230863 0.572306905593723 0.230703507910948 0.688449408991728 0.819648439385928 0.63850022881059 0.335059063385706 0.891937973396853 0.515875932383351 0.749404935629573 0.292268745270558 0.490912028150633 0.301383608218748 0.494400493626017 0.485615083980374 0.833962069104891 0.833565524870064 0.0523987686354667 0.308331141592935 0.828361745364964 0.733484175156336 0.28541338932002 0.954910729252733 0.608904618681408 0.170589959979989 0.588839196374174 0.807779928902164 0.712454193921294 0.583233323981985 0.227604036566336 0.443613835757133 0.900168819774408 0.533969475654885 0.255798038740177 0.209330780303571 0.762608934012242 0.287518245845567 0.67396559179062 0.0235745267407037 0.793658495489508 0.881642384584993 0.722079810863361 0.570553997785319 0.41625241194386 0.168067078706808 0.0230016574379988 0.0172100455709733 0.409084539541509 0.298771222888026 0.713056812316645 0.857600337108597 0.601760905690025 0.553232669152785 0.509478245507926 0.0311665430362336 0.278729243590497 0.890673417290673 0.711788084579166 0.159548797528259 0.392102605546825 0.512634595378768 0.684793057830539 0.0484167912020348 0.286019157760311 0.855910529545508 0.393710911863018 0.58524768713396 0.0995104468357749 0.52912427342264 0.482727326727472 0.899706274191849 0.130627023410052 0.0681286220019683 0.142939127343707 0.517835190724582 0.756427510653157 0.254352651245426 0.0891183114284649 0.373838281710632 0.980539022127632 0.310432374621742 0.355306357799564 0.945527853169479 0.656937162938993 0.0298453990672715 0.239482708745636 0.688371726707555 0.640484646251425 0.310452994669322 0.853319902021904 0.931216421290301 0.214268569562119 0.137413518400863 0.500009564929642 0.303162683574483 0.872077572315466 0.819419568774756 0.722240382249001 0.994864108504262 0.551415616923478 0.224696378202643 0.466483562637586 0.188466791408136 0.0233907359326258 0.134580541641917 0.133470024485141 0.580717458277941 0.0663464240310714 0.540218798087444 0.660330941511784 0.192932296821382 0.46026331738336 0.579524299809709 0.512773695241194 0.230123641248792 0.520025357317645 0.747793423025869 0.331651197662577 0.158982569228392 0.831627520688344 0.678692420008592 0.601341768538114 0.647612069412135 0.312728687310591 0.138141806439962 0.972843841053545 0.544856167887337 0.408383891729172 0.380126915855799 0.83284570018528 0.899972475117538 0.597784629501402 0.545726792502683 0.206268435739912 0.397480229453649 0.409063669859897 0.901204288597219 0.243041410357691 0.699147730334662 0.121614737920463 0.499609981982503 0.464390924118925 0.430243326404598 0.277378735698294 0.614413401875645 0.149629022262525 0.0108579112589359 0.4717649200093 0.904362891628407 0.201714858380146 0.413843050536234 0.394138143335003 0.48992959146155 0.822965256455354 0.524984062588774 0.83801512838807 0.894462963074911 0.600793083310127 0.109594477145001 0.888712049392052 0.775821246614214 0.736686723458115 0.906190377546009 0.313789547809865 0.878785031973384 0.907644268963486 0.820364398085512 0.549186097127385 0.0924061294598505 0.676604787539691 0.744744480559602 0.736509181798901 0.796558676818386 0.355457526764367 0.551226424062625 0.0141973804845475 0.503281139691826 0.803339899298735 0.890365992404986 0.322913321286906 0.452795199321117 0.0511791620985605 0.322784900136758 0.627530329383444 0.253797968577128 0.0565864246874116 0.14246686170809 0.0220178948994726 0.0262084730295464 0.413396995782387 0.484564561971929 0.992447828568984 0.68957882872317 0.103140410319902 0.122764859527815 0.173493146137334 0.635816435699817 0.673561929413117 0.702649816193152 0.523957532185595 0.114857517187484 0.55600590131944 0.14924285731744 0.336756719553377 0.426599176193122 0.0855684611061588 0.772004771241918 0.376673311553895 0.0346862729266286 0.694786740213167 0.591910209669732 0.48728342209477 0.606503521935083 0.115562897443306 0.329756638100371 0.781547614333685 0.0812179392483085 0.204873300059699 0.467435258612968 0.653816832746379 0.464422533826437 0.346307433608454 0.243036901962478 0.608879818704445 0.747989365225658 0.617595383836888 0.860558162000962 0.859411677028984 0.527848402878735 0.299003627561033 0.597191841339227 0.663846115523484 0.801539220341947 0.196671244346071 0.876476710804272 0.960908968946896 0.266476888398174 0.784536338986363 0.217167325234041 0.79876593677327 0.767646243576892 0.921574712288566 0.964349855051842 0.803028708465863 0.708762419621926 0.206636240712833 0.636267772645224 0.748413802778814 0.0906408236222342 0.357138873508666 0.95211709324969 0.725154522338416 0.0116472983220592 0.0548236453859136 0.917050002119504 0.180174305478577 0.338030106665101 0.626860766424797 0.359506704849191 0.417542699717451 0.621430583605543 0.266538751767948 0.84116017396329 0.434131372752599 0.592252794920933 0.395991888078861 0.912987189590931 0.849585210953373 0.525268722602632 0.606373582696542 0.984159437743947 0.598586526617873 0.350309906618204 0.553378525960725 0.717048823977821 0.922120470828377 0.190023716448341 0.438012357430998 0.718688582107425 0.94505265439162 0.394264789847657 0.633985611647367 0.651828050974291 0.191493885018863 0.218634446794167 0.0102197337290272 0.39094952106243 0.21740560909966 0.90017923848005 0.166390996635891 0.380600111568347 0.629062421254348 0.0786528882640414 0.0457032363209873 0.118102579109836 0.939760440820828 0.464123643981293 0.584297742515337 0.902793020193931 0.53744316754397 0.704030194883235 0.366360117665026 0.101068595151883 0.745947224006522 0.446085004752968 0.451229351304937 0.834429141753353 0.498688460607082 0.683402798888273 0.137228492561262 0.444168870171998 0.970788228816818 0.582510414023418 0.419526995683555 0.510045701924246 0.621833699692506 0.248960700926837 0.287133983927779 0.66115678275004 0.296558972557541 0.87985322521301 0.739219968116377 0.0401806799205951 0.567085510639008 0.636166767673567 0.681586928905454 0.626354213566519 0.422015175290871 0.477611341183074 0.949915433349088 0.827897802016232 0.68148637203034 0.926797323373612 0.911255428527947 0.109811289256904 0.668958401966374 0.466462482968345 0.39988364528399 0.793624418484978 0.850262663315516 0.959799956970382 0.443206692333333 0.922229818140622 0.741067696288228 0.373634623675607 0.901923862725962 0.167285792878829 0.578360154209658 0.243257110295817 0.177289033501875 0.521691069088411 0.848463596261572 0.308970086004119 0.98083693994442 0.368926742980257 0.074781069511082 0.585552629509475 0.795448223280255 0.619891114276834 0.479966904267203 0.455548014973756 0.488933454174548 0.941115466097835 0.478321594258305 0.625844482081011 0.996732595255598 0.538468580471817 0.521684773608576 0.942188540685456 0.988608187250793 0.811630851235241 0.256965263851453 0.734905308964662 0.299497308246791 0.599903483742382 0.142792535924818 0.82608554631006 0.648933727401309 0.532179971220903 0.44460978818126 0.577069352876861 0.853788025761023 0.227281997601967 0.404222228964791 0.51612879459979 0.309189666679595 0.421688552557025 0.174340474111959 0.964647239947226 0.568735663271509 0.876843499492388 0.725752438947093 0.523169972545002 0.389799687582999 0.81686847885605 0.410817446201108 0.151901864972897 0.594761390120257 0.807241046708077 0.470374769403134 0.547393376033288 0.68953636880964 0.658271945500746 0.113646645075642 0.289739692988805 0.692660606016871 0.141711541046388 0.828397901270073 0.739157958838623 0.73598914294038 0.0383784072706476 0.33489357215818 0.872628971247468 0.793053615635727 0.795477329501882 0.413023770086002 0.858915307994466 0.397725330656394 0.116504902869929 0.500119576088618 0.227565205912106 0.189650632510893 0.384573436635546 0.524240019484423 0.794350103691686 0.344897445740644 0.430958693404682 0.601205387450755 0.610626791999675 0.717882411708124 0.791177234870847 0.386155029574875 0.82635220893193 0.854557288817596 0.158817265168764 0.668035246790387 0.124007259979844 0.267147575055715 0.982386436124798 0.528018747102469 0.835426393058151 0.883339083245955 0.228602039769758 0.29189229438547 0.193335808680858 0.5199048656784 0.0526051728753373 0.499757261220366 0.524629072854295 0.255319148467388 0.730664199190214 0.636808662975673 0.408679048358463 0.114169257953763 0.778342124361079 0.233942786760163 0.0266849792166613 0.676777081352193 0.810722384129185 0.72436161020305 0.774387223115191 0.153987844048534 0.773907624969725 0.772624894445762 0.0218330795085058 0.71975281762192 0.949581525588874 0.955633110438939 0.78011832051212 0.187912128332537 0.829223625643644 0.490924980076961 0.128478597102221 0.0377087251422927 0.845449713661801 0.436502887289971 0.0624464962095954 0.792427876011934 0.99193224923918 0.512986647360958 0.727931783455424 0.629626930698287 0.624287507482804 0.738222939015832 0.413071572813205 0.23773128998233 0.192996923453175 0.666789879542775 0.773380780990701 0.469682951674331 0.507965797968209 0.8114845603914 0.27889979780186 0.213721663812175 0.723633126467466 0.301925193052739 0.0268442962085828 0.44315331260208 0.380172359161079 0.752111617622431 0.14278455155436 0.548008492495865 0.0183661927399226 0.193579813614488 0.43517211592989 0.100946202559862 0.178346145572141 0.0456079973652959 0.705642529227771 0.628713408675976 0.323272843849845 0.722814168259502 0.825421992777847 0.482618258323055 0.535232170454692 0.990371837390121 0.363277455011848 0.896094185472466 0.762172450637445 0.343246420656797 0.51220490306383 0.422883402220905 0.192182531035505 0.947517814652529 0.0467986399005167 0.683903367675375 0.830339763599914 0.705114063664805 0.681128917303868 0.912809182086494 0.5558483280777 0.584970122904051 0.0582547538122162 0.88668360323878 0.732919165983331 0.431325033074245 0.574293698361144 0.160666175587103 0.120526982408483 0.0975991207640618 0.774088668420445 0.845323314247653 0.847542729512788 0.676871868753806 0.335064540582243 0.948428236648906 0.666599609313998 0.281454195198603 0.322946998830885 0.926998250647448 0.140189869264141 0.443749112046789 0.912265066797845 0.563056215224788 0.639587735841051 0.0405582595756277 0.287691821712069 0.595736555382609 0.888525437696371 0.8175154576567 0.800073554173578 0.0443831054097973 0.95969160312321 0.131822192319669 0.845571063230745 0.381199981684331 0.286241166777909 0.971783943823539 0.900445298107807 0.598988213590346 0.996851734537631 0.10655243384419 0.961383453167509 0.814762178002857 0.899564382715616 0.304302400536835 0.344748723327648 0.53950343408389 0.888603457666468 0.313145251364913 0.851427029736806 0.524017370361835 0.75695637636818 0.774399219609331 0.893759081084281 0.871690579866991 0.624044153718278 0.744041336406954 0.279089002418332 0.872056121998467 0.824662807744462 0.430778378571849 0.797435927453917 0.145079411156476 0.0846997063257731 0.401913340068422 0.582137517714873 0.98261879308382 0.596195462485775 0.52153514877893 0.49711797419237 0.161012525402475 0.564883876093663 0.442846245456021 0.0460324388369918 0.274423030044418 0.428869790176395 0.101418371153995 0.915995139060542 0.195920382521581 0.105246146442369 0.0948695107037201 0.058272012444213 0.335199778839014 0.278636811000761 0.598702623960562 0.432792346642818 0.748706152811646 0.560181627031416 0.649714998246636 0.40458888488356 0.118198852560017 0.174222063678317 0.579638995467685 0.92492326584179 0.351062669625971 0.971414762060158 0.854085129674058 0.504507049084641 0.109926559326705 0.409246828861069 0.511070498258341 0.230803933630232 0.56481965768151 0.566755519344006 0.401432306123897 0.856508747651242 0.430016979102511 0.11084679011954 0.595374355304521 0.946221935583744 0.25617817674065 0.922828410351649 0.990667006927542 0.285029172580689 0.611313523233402 0.502521944055334 0.941563701173291 0.417246416392736 0.40265954966424 0.470713405688293 0.865420165318064 0.931949189142324 0.494792281445116 0.903255486253183 0.601787912726868 0.166270416022744 0.589508078428917 0.464603414312005 0.158543689320795 0.372825873033144 0.895156957898289 0.432558901251759 0.232253953299951 0.966365762338974 0.948968262134586 0.109727255941834 0.70617868273519 0.722907011143398 0.990250718784519 0.112059475362767 0.190150685433764 0.345060247927904 0.843291788122151 0.648908107066527 0.928951927374583 0.294900913925376 0.599825702803209 0.770490156288724 0.309969912481029 0.577239763485268 0.205187796065584 0.141542223480064 0.419638815594371 0.0514255665615201 0.215788998245262 0.458765679618809 0.369456020602956 0.293004512649495 0.998601652039215 0.295410368347075 0.436634782110341 0.112780625896994 0.674029660606757 0.43174324936932 0.717430325399619 0.309121602796949 0.653303599008359 0.556220968298148 0.591065711572301 0.734834231263958 0.919839148859028 0.707129483900499 0.261708206948824 0.0884042101167142 0.681584862682503 0.964472177571151 0.585753595277201 0.200787055355031 0.0582408118783496 0.980908710304648 0.538340951558202 0.441760903764516 0.258102419010829 0.653972271305975 0.554261775419582 0.907044707490131 0.390578944298904 0.477680187390652 0.460153944254853 0.942598245451227 0.710140082533471 0.558720297764521 0.0746861428860575 0.18676770266844 0.801127486925106 0.982980489975307 0.293552798186429 0.648183955852874 0.78533168914495 0.0408884597057477 0.215348891604226 0.198447833273094 0.330254062144086 0.0419586274283938 0.891116565179545 0.19908646028256 0.882709727731999 0.800279373859521 0.35640687668696 0.616530841984786 0.260068019623868 0.212211171393283 0.484290236299858 0.567359235852491 0.188763793208636 0.700250231311657 0.782662042884622 0.986017307327129 0.0166810035216622 0.372803374622017 0.522824675894808 0.843535324905533 0.0847463076747954 0.159267220713664 0.560026275371201 0.413930271698628 0.0779072035220452 0.773973837457597 0.0314929977338761 0.780820286106318 0.806656565619633 0.423298327634111 0.302310869563371 0.57605557409348 0.331194372917525 0.915687532769516 0.0828705951361917 0.740602884637192 0.0980505973938852 0.671085518563632 0.318442269756924 0.967396753653884 0.710950584993698 0.872011020067148 0.0490952172060497 0.37768832444679 0.830522653143853 0.269162048157305 0.591691690457519 0.0794903203123249 0.824281057149638 0.452682921632659 0.943871947890148 0.913536330061033 0.258013198701665 0.543462486215867 0.435219346089289 0.930483191511594 0.297599460568745 0.652492915373296 0.230686265644617 0.0951439550844952 0.647273594017606 0.683080009638797 0.814329474405386 0.965513005112298 0.591354198616464 0.216880247250665 0.123111375996377 0.0231725638569333 0.478823481288273 0.643252468528226 0.0557530729915015 0.029108697923366 0.151843713382259 0.966711009431165 0.0154714994411916 0.32711114825448 0.329362843988929 0.210885681533255 0.103865466485731 0.403865754334256 0.873071274345275 0.562450087661855 0.949304458783008 0.754986710846424 0.439713039863855 0.0782053308654577 0.967077255286276 0.547124027137179 0.455802719595376 0.0798417925811373 0.314862119210884 0.658491276311688 0.289702550533693 0.145569202345796 0.687056810220238 0.531245979208034 0.604179189843126 0.083985482386779 0.0961352732591331 0.204759297752753 0.848787468641531 0.45317418734543 0.908322321553715 0.930386327283923 0.104961814663839 0.93815163892461 0.140002499907278 0.999372190465219 0.557128077745438 0.478136909101158 0.49161974431714 0.955154238606337 0.594082087285351 0.633065431565046 0.0254643155960366 0.0210408259183168 0.626426564562134 0.202005704846233 0.961113324942999 0.175097264917567 0.465587351110298 0.317338704089634 0.117327688338701 0.306554337376729 0.406593776925001 0.0413240376673639 0.48698127225507 0.540242487273645 0.601961160358041 0.945279703803826 0.126719778061379 0.867757080071606 0.483931614309549 0.205456739969086 0.346121656792238 0.760338746919297 0.785488223512657 0.644435299108736 0.603446248883847 0.502829974701162 0.927876244422514 0.991607275749557 0.767918912859168 0.803532111279201 0.583465054435655 0.395909472890198 0.575455318347085 0.62851989481831 0.174697784313466 0.916817368096672 0.758409593796823 0.288146128910594 0.793852376998402 0.698947250004858 0.643348305637483 0.777976110621821 0.372457066988573 0.0655847885273397 0.19377772960579 0.336427483153529 0.11654858098831 0.109675521997269 0.908796868240461 0.378081344761886 0.398198626867961 0.686474202885292 0.8587793404283 0.632812461243011 0.874812613471877 0.402012276512105 0.286403868235648 0.102075852563139 0.108364429082721 0.073463670744095 0.260939055916388 0.204866765087936 0.0906970708025619 0.417317222331185 0.378826479525305 0.0674534011329524 0.753838020428084 0.88978301811032 0.0324179369979538 0.994128381232731 0.477240585549735 0.561874570117798 0.0578589008538984 0.823380019364413 0.718122997600585 0.884915761183947 0.766867677445989 0.474993370550219 0.841587137822062 0.682211342679802 0.24394505512435 0.852474637504201 0.351888101492077 0.357485301694833 0.426479289161507 0.110235639680177 0.633243057818618 0.587385740606114 0.871588063030504 0.0617896638950333 0.0767612772877328 0.509895377981011 0.606093933111988 0.411570909244474 0.836359814808238 0.450766937800217 0.630883217302617 0.527796057872474 0.0382478530518711 0.22863525607856 0.872806041068397 0.644393872767687 0.822921034120955 0.272719925031997 0.77145012314897 0.197231352347881 0.302605933069717 0.338357891822234 0.0877280160668306 0.911257293291856 0.557407802934758 0.979257468548603 0.780930825576652 0.856363755918574 0.423615399503615 0.550981136613991 0.0957098127366044 0.967110789688304 0.772747808895074 0.359187383507378 0.940711983281653 0.665831128351856 0.416203782404773 0.99674752788851 0.973153732544743 0.482686045602895 0.883712166722398 0.631346452087164 0.197954393001273 0.519407517469954 0.284830484406557 0.775506168359425 0.97047652649926 0.651334701750893 0.393604836761951 0.44043454421917 0.469919316607993 0.0989755329699255 0.955972958474886 0.399855247857049 0.685256780127529 0.723651301346254 0.941780187815893 0.375529049546458 0.249982038803864 0.231534260923509 0.980124525448773 0.657849368331954 0.528824391264934 0.900850326903164 0.344284827923402 0.987898570823017 0.158251538441982 0.906591845541261 0.704410177986138 0.0416013414296322 0.907393929134123 0.132234057122841 0.541412897466216 0.468996705648024 0.440626518090721 0.936247840367723 0.553677403358743 0.153123149566818 0.205841627009213 0.112955055774655 0.639659562904853 0.190860884340946 0.541830357944127 0.578335347087123 0.732119789640419 0.399529471758287 0.387464892759454 0.901767762163654 0.880275915327948 0.564712640056387 0.939371651606634 0.524737371611409 0.128203792676795 0.0380537760769948 0.74177865262609 0.891647177410778 0.92176700102631 0.338810751696583 0.313228760517668 0.158551740767434 0.389816667307168 0.412701403577812 0.910317984742578 0.101696143297013 0.629065172760747 0.724572317460552 0.300961953520309 0.832495203402359 0.859287590475287 0.247419959455729 0.230375226712786 0.344198142909445 0.189004318478983 0.838019167711027 0.802388104668353 0.946594555750489 0.753796317945234 0.862824080651626 0.721070994564798 0.929707892520819 0.0912319848989136 0.313515402390622 0.933964750214946 0.0434341544867493 0.882268145415001 0.309536197208799 0.630830270454753 0.230631184806116 0.633250979722943 0.632828507663216 0.112001954657026 0.656393516492099 0.996597495991737 0.94034549954813 0.867469029829372 0.229935305856634 0.965008478830569 0.466301731560379 0.0403521220269613 0.56811174553819 0.268414390315302 0.122957337968983 0.422099167115521 0.194895151460078 0.836591911991127 0.599534191798884 0.488283806156833 0.523817033404484 0.63577058740193 0.822635538997129 0.325687185029965 0.62366211384302 0.239473698870279 0.214407217639964 0.664145177092869 0.535160179503728 0.902813554955646 0.228277906461153 0.779808032095898 0.31450646424666 0.876481552044861 0.842660033309367 0.139181054809596 0.742933064573444 0.345498894106131 0.847514565815218 0.487993343477137 0.579617602084763 0.644414278678596 0.803668760210276 0.132284654921386 0.578923712831456 0.315959527008235 0.303538155285642 0.577832273661625 0.846993907366414 0.551755863728467 0.79152962730499 0.972801796505228 0.0524137600464746 0.448152544102632 0.526383623222355 0.734207489185501 0.96719370322302 0.442382101109251 0.85611765387468 0.278315931924153 0.196878983194474 0.0598318047029898 0.517459799689241 0.517760949148797 0.849285511814523 0.54724569295533 0.780381209349725 0.300576040053274 0.766417952172924 0.697745226877742 0.423616347329225 0.835141479952726 0.290936452825554 0.723596976785921 0.900655419197865 0.244344466116745 0.614545690624509 0.735279714833014 0.398748253697995 0.152954011792317 0.277693020794541 0.0476954355207272 0.488099452231545 0.417784708961844 0.961442833566107 0.677937261851039 0.559557360317558 0.147648298621643 0.615724320069421 0.536751186619513 0.548385137924924 0.293563676974736 0.609875418459997 0.742114639747888 0.236423183686566 0.232247026704717 0.111921011917293 0.113609512071125 0.305044692053925 0.813737146556377 0.475868477975018 0.0305682016117498 0.341226999131031 0.553879590097349 0.587695511544589 0.0651994787459262 0.695378060766961 0.861905505326577 0.980497832051478 0.631540263523348 0.480946970931254 0.166387870793696 0.862642972890753 0.994276953127701 0.852646453715861 0.991767056281678 0.124485564776696 0.701448429252487 0.672722126878798 0.913395929473918 0.097730845012702 0.548786002234556 0.788519032821059 0.609519068992231 0.666547643714584 0.406421647460666 0.572261990369298 0.0357448231009766 0.923073297878727 0.928797847626265 0.780244201065507 0.379403061759658 0.807405288151931 0.534204854269046 0.991994506998453 0.909855001897085 0.439806154279504 0.718918489979114 0.405830560175236 0.111494279943872 0.599657058995217 0.921685734200291 0.729969597684685 0.109218569553923 0.553800073706079 0.732203930600081 0.346253608546685 0.600306759797968 0.22599726262968 0.63441421460826 0.429432972618379 0.186524518092629 0.0814140351931564 0.169098274707794 0.830505063741002 0.884736388183665 0.0174814892723225 0.765884571147617 0.757526487940922 0.232507341983728 0.694450161161367 0.667294647160452 0.98478319412563 0.81950071781408 0.897345703444444 0.546983735116664 0.245766382711008 0.125877390443347 0.325790876736864 0.809889160823077 0.918227732144296 0.835686790856998 0.666982634125743 0.510691506084986 0.278286128432956 0.921839583215769 0.456005217742641 0.17643297548173 0.745539788536262 0.788233541846275 0.237798766775522 0.33616050704848 0.629883297933266 0.105769525279757 0.201049740198068 0.137602856247686 0.890732806909364 0.211099985318724 0.395853131664917 0.431549603894819 0.777075261618011 0.477242382315453 0.104474785353523 0.960190031696111 0.30087520811474 0.386329150579404 0.539120609809179 0.432555142450146 0.289055131243076 0.398608058718964 0.947241257487331 0.197631857765373 0.708139218520373 0.307815542670432 0.203189744181 0.0646483981376514 0.0605657856888138 0.0790328160463832 0.412393919683527 0.669604811656754 0.251719492352568 0.626305813838262 0.0348423958476633 0.978143198583275 0.515553765029181 0.0968543158494867 0.795690470172558 0.884798646403942 0.53594101193361 0.116528708920814 0.560308053414337 0.0428592943353578 0.688021606795955 0.596545556811616 0.836613821238279 0.960420557314064 0.391965207713656 0.149297971578781 0.177487572310492 0.524483726839535 0.488571271614637 0.244960913269315 0.545848015756346 0.986260814145207 0.688935477798805 0.545718543285038 0.494583098269068 0.754232194176875 0.646287520462647 0.27078473482281 0.0409767750627361 0.355255079327617 0.644776515176054 0.247676508557051 0.0267014315514825 0.498004856368061 0.876381716642063 0.481823846769985 0.628981166644953 0.122186449409928 0.759683339339681 0.435428724500816 0.748971361424774 0.0812513563246466 0.392465839427896 0.367449648045003 0.96998071343638 0.524638032019138 0.2422316411254 0.47685079918243 0.480261997277848 0.53636060847668 0.910700862493832 0.622972360032145 0.19825547745917 0.205745541879442 0.29796678863233 0.806590591010172 0.399015074213967 0.246811151611619 0.82180788785452 0.092944850763306 0.682025528983213 0.184010460448917 0.226172623506282 0.772384740514681 0.345428175067063 0.568693709080108 0.625108836407308 0.393326763582882 0.319439184989315 0.296495825750753 0.144263893887401 0.883843830809928 0.75390485757729 0.770340100880712 0.262625600027386 0.755109318266623 0.93274716357002 0.767955393081065 0.590194995447528 0.678401636469644 0.0992590593732893 0.388614479370881 0.903050328108948 0.980987916209269 0.911397120619658 0.684331685735378 0.795874469354749 0.759521054399665 0.325632827507798 0.157572718739975 0.823321065395139 0.341944125324953 0.591852446475532 0.0357991534238681 0.294250680201221 0.2621907647443 0.668214145647362 0.0855275902757421 0.708852807886433 0.593455661686603 0.422097580106929 0.0347623368538916 0.302623080599587 0.562643592068926 0.0566973311174661 0.600789075796492 0.164360455907881 0.168164603093173 0.917543152188882 0.0549815302668139 0.162211419229861 0.0462091693584807 0.508647016738541 0.69178999661468 0.652138899050187 0.525689785601571 0.218755197057035 0.39170965830097 0.729048199628014 0.266645545114297 0.0294770570239052 0.0300479947170243 0.325368108251132 0.658642253498547 0.676900555922184 0.218160151124466 0.512090405176859 0.590167303127237 0.997654450398404 0.0188078880030662 0.624927960070781 0.230040869242512 0.556037300117314 0.985042760502547 0.0942835818300955 0.732514916977379 0.91454345931299 0.401873053330928 0.945022189589217 0.737443159520626 0.878468841314316 0.778925430118106 0.0654720265534706 0.947182571361773 0.142141774811316 0.728832074874081 0.313115338154603 0.481525597490836 0.390353819350712 0.384717251423281 0.338485419084318 0.187015538320411 0.831437339663971 0.845883999427315 0.638329519701656 0.568435597633943 0.781539582018741 0.788014681260102 0.469839740977623 0.300682491564658 0.17752779427683 0.0460407943162136 0.7717740715947 0.0174560256791301 0.876836976045743 0.0590259565459564 0.317663355106488 0.210016765401233 0.990145120362286 0.195303318314254 0.328606543692295 0.14317251395667 0.582856036142912 0.828363601139281 0.875875976074021 0.231764884504955 0.644198885308579 0.157658046095166 0.761362327123061 0.614952095288318 0.910442006294616 0.538963475213386 0.295359883725178 0.251173211724963 0.865227227024734 0.750471494607627 0.6894436695287 0.271790815980639 0.622107922560535 0.792884532720782 0.803324779728428 0.11408530715853 0.454218781064264 0.054175231247209 0.403294724440202 0.464812748236582 0.824189770156518 0.292954812427051 0.282717620921321 0.508009104977827 0.335746746363584 0.192847490401473 0.432074723485857 0.994592561537866 0.254925537835807 0.301801177724265 0.825749978933018 0.756290383890737 0.36680590572767 0.647925233806018 0.567261156416498 0.515518516611774 0.676669264575467 0.359646085463464 0.736929882217664 0.137697535774205 0.093270051528234 0.483847305774689 0.407091617716942 0.312086628812831 0.442028493927792 0.644967181868851 0.754510902389884 0.729635636447929 0.638956004539505 0.056984347095713 0.381070983586833 0.413738470934331 0.0475153933721595 0.0553164379461668 0.617327243695036 0.0181842685397714 0.216731812735088 0.12433096247958 0.197564984427299 0.443678351517301 0.866519737071358 0.603480312519241 0.758740313479211 0.6561541202222 0.711311221574433 0.0274386370345019 0.147095715829637 0.237467518551275 0.622509643647354 0.436082278841641 0.758453392006923 0.194115522943903 0.980595717404503 0.385036851442419 0.802822228621226 0.665285507882945 0.339363443746697 0.263539352321532 0.725873834616505 0.340730146733113 0.43797640575096 0.149978977134451 0.341724378226791 0.366444781173486 0.177391864282545 0.471753020326141 0.186709196334705 0.242853687410243 0.503494884509128 0.847368292950559 0.647368477999698 0.938745461581275 0.635920567435678 0.92927281820681 0.59583872646559 0.527047402416356 0.243225602700841 0.889313227378298 0.0402761899470352 0.89434405475622 0.104435752779245 0.527666667921003 0.67975746643031 0.969303459767252 0.249577938702423 0.453717813277617 0.347672954578884 0.847456009462476 0.518385713747703 0.37423959042877 0.01816812092904 0.615780884190463 0.647580317945685 0.843859068665188 0.73312831573654 0.142461617088411 0.489725353482645 0.954676144719124 0.169262639931403 0.573952371652704 0.178106138932053 0.752084199138917 0.958758867578581 0.518580517957453 0.65962882355554 0.720387976262718 0.294969915261027 0.503019574398641 0.119334082794376 0.359996364652179 0.400781075477134 0.828137767165899 0.366436055507511 0.504451222340576 0.263357868150342 0.219456807677634 0.0295636385423131 0.582253346983343 0.798244354240596 0.032376307353843 0.333757170510944 0.369390698776115 0.585943066354375 0.705368196640629 0.279506307307165 0.59988936662674 0.318168570820708 0.40920834349934 0.443867044649087 0.638641261665616 0.0980262185446918 0.5329089394724 0.316874236348085 0.265024776228238 0.70782617145218 0.34664061666932 0.0735155925480649 0.0968712135148235 0.870015537822619 0.380478793808725 0.0645937720802613 0.715264772998635 0.393060347137507 0.0467119790893048 0.132971618501469 0.218975070931483 0.829626238774508 0.593588049551472 0.189228525797371 0.453513243605848 0.22802294021938 0.997801275085658 0.0569660618063062 0.572412696946412 0.465090545734856 0.546454287844244 0.651304513551295 0.145726819152478 0.321988122246694 0.741887165980879 0.790531533283647 0.188564771497622 0.741153490871657 0.811324398838915 0.676355815972202 0.122795791097451 0.607500640931539 0.759820536635816 0.580378317884169 0.696114702671766 0.0593766239006072 0.714214178381953 0.797313056800049 0.334333964807447 0.684453518667724 0.213040840353351 0.803527288478799 0.397806441662833 0.202433218683582 0.891196080418304 0.966650745747611 0.291279663199093 0.338533710937481 0.827647389809135 0.878791767943185 0.0734838074282743 0.420160133971367 0.47953676961828 0.525157517672051 0.613500199560076 0.721859389084857 0.695444627306424 0.855541348704137 0.505200852130074 0.776646085167304 0.794375617303886 0.868782564224675 0.271752258471679 0.490893568601459 0.0322528166486882 0.285019624482375 0.0496654384979047 0.634266020276118 0.381620497701224 0.450283988842275 0.47109725615941 0.293959410532843 0.695836889960337 0.55079305339139 0.67641960288398 0.558884997216519 0.253118139735889 0.68734678838402 0.739626358028036 0.64623268856667 0.702229360337369 0.358555542947724 0.75743057130836 0.247000287768897 0.110436141216196 0.544054518791381 0.878547594742849 0.670310966630932 0.186024869240355 0.180074359895661 0.890616843258031 0.074651810254436 0.490326006845571 0.753432334701065 0.143025166720618 0.824470319391694 0.0448822402418591 0.710248041760642 0.726498264295515 0.479166015137453 0.517795133797918 0.784499516468495 0.394140390041284 0.612009661267512 0.750424302250613 0.730078220297582 0.16350039613666 0.0712229187996127 0.816809171757195 0.85281460217433 0.476728921993636 0.581350510357879 0.534304881910794 0.0912440793565474 0.123063381260727 0.54375409172615 0.607592524003703 0.572241009585559 0.234635378746316 0.623961047944613 0.693243000598159 0.639895700102206 0.172893246747553 0.927171105041634 0.855041971614119 0.68827019227203 0.771515882930253 0.0245597170107067 0.129242314733565 0.110386177990586 0.435306405669544 0.749789905189536 0.535892190616578 0.843086821064353 0.204071473476943 0.419916501990519 0.677800017532427 0.78232688879827 0.351585847926326 0.888613042414654 0.0510938972095028 0.940310821163002 0.951684449352324 0.90168693167856 0.484659963201266 0.104174374192953 0.341771981799975 0.193148762027267 0.0867970835114829 0.627382331900299 0.593561151081231 0.608382355014328 0.710223724916577 0.78998469322687 0.685915325304959 0.758079884636682 0.333298588185571 0.592154996236786 0.76468773455359 0.970336097099353 0.42136376531329 0.574391750597861 0.950986618739553 0.11138500293484 0.122668575244024 0.565097265476361 0.130820055287331 0.0462438097107224 0.597014783504419 0.58647255949676 0.414723370771389 0.25322729527019 0.449739710588474 0.0330925693945028 0.21331928026164 0.428085048196372 0.536294822187629 0.270886270641349 0.0662954493612051 0.366782251808327 0.264110063661356 0.976229057847522 0.897932481027674 0.612936682198197 0.644342620112002 0.550747433060314 0.525078510229941 0.404374781635124 0.292660024370998 0.3271946046222 0.406791419771034 0.870438465815969 0.0691628401190974 0.608836263674311 0.420806379313581 0.224249201824423 0.877201332012191 0.113392313406803 0.241886805940885 0.384263579028193 0.248452126563061 0.549197913368698 0.323820414599031 0.156894056701567 0.0223171980353072 0.913173726834357 0.193492366559803 0.2799522917578 0.0767272964026779 0.0495573969813995 0.118662065677345 0.0427641222253442 0.350586726095062 0.818412372907624 0.7990062137926 0.137344567314722 0.297965335545596 0.636567248657811 0.560317966628354 0.904016173700802 0.511819525284227 0.0485242666047998 0.87761970550986 0.205352787333541 0.340663697980344 0.664641358959489 0.264209248356055 0.725508649072144 0.503264755585696 0.478346701494884 0.572710460787639 0.484379724452738 0.998234461816028 0.943787967821118 0.428197829762939 0.448800052367151 0.878081105726305 0.669829674523789 0.35319853609195 0.416068492284976 0.38340493431082 0.954876093510538 0.681488605136983 0.349336131284945 0.0752335179387592 0.956196646471508 0.720719865283463 0.981445059508551 0.786396567991469 0.441005906728096 0.669674555209931 0.401224725169595 0.624108753842302 0.347336916746572 0.253252097782679 0.650168727575801 0.294465186598245 0.0595519273821265 0.723951245970093 0.606292404844426 0.796424604442436 0.198156833061948 0.0623514688550495 0.853032952658832 0.895546767315827 0.71861101599643 0.452209189541172 0.89922525960952 0.570655627187807 0.409017824328039 0.309268054992426 0.499590741721913 0.921165540213697 0.767072162292898 0.738515810675453 0.580233351276256 0.567803140019532 0.784037749292329 0.560146427250002 0.29694128373405 0.351236996469088 0.125510312013794 0.820143532820512 0.907001618535724 0.87485977609409 0.8425890086242 0.215830961426254 0.9354742032988 0.634420782541856 0.229891207071487 0.0519843060709536 0.782864501385484 0.377343542047311 0.956312304015737 0.863441886845976 0.632027029369492 0.367563634908292 0.634158210875466 0.993697534792591 0.482219760350417 0.218098679147661 0.290083465557545 0.168936009360477 0.0401679677166976 0.453767897977959 0.904361927898135 0.398977397454437 0.651666394153144 0.952972080355976 0.651001025184523 0.126867642314173 0.0888832882489078 0.625479225541931 0.310244903152343 0.72864571465645 0.170019448255189 0.956825184163172 0.465399710682686 0.662480955289211 0.793001102823764 0.300708042057231 0.928722007977776 0.971954571104143 0.0992965510394424 0.97368206810439 0.659343270345125 0.716643174670171 0.127383377002552 0.953498496983666 0.972848140844144 0.844745489605703 0.0593951809522696 0.632641616137698 0.391326577707659 0.301378704973031 0.346233138556127 0.422682592042256 0.697308498709463 0.76651386719197 0.296932793180458 0.40222035581246 0.611282596734818 0.112395076854154 0.0992179243871942 0.524406038331799 0.152014015654568 0.17179036820773 0.322951068580151 0.178164359903894 0.571041530743241 0.704117571634706 0.739074209041428 0.673078502162825 0.672604532192927 0.899312531482428 0.972222450547852 0.680332719357684 0.970059295371175 0.18342517928686 0.0974482701229863 0.513954596056137 0.360737972038332 0.986869769049808 0.977547823954374 0.684004631731659 0.156328885946423 0.448513135274407 0.0361703039077111 0.435081607573666 0.148016719266307 0.472758060074411 0.434639361179434 0.61876283046091 0.0866525843623094 0.423385597663 0.393686657485086 0.519674532068893 0.195472337841056 0.412258106323425 0.858825469478034 0.0793556758295745 0.95504764856305 0.907735455457587 0.750666984561831 0.799816830120981 0.632576856506057 0.982337503705639 0.63074345267145 0.96233100194484 0.467381088258699 0.48178686774103 0.732453347728588 0.0423234858899377 0.146232579313219 0.64169366351096 0.099275061537046 0.0182701013865881 0.644366487246007 0.622464055125602 0.167835772146937 0.597225280543789 0.677968021004926 0.272790925283916 0.657868443091866 0.396649325692561 0.169868055703118 0.592795721048024 0.820106925822329 0.0872188638336956 0.538241016347893 0.186132876412012 0.293161574406549 0.736776397856884 0.998568845102563 0.396959445150569 0.189638615271542 0.388945249763783 0.325528529349249 0.246520744943991 0.0451599685894325 0.882368990418036 0.107402295731008 0.459221865872387 0.906096474120859 0.617867681549396 0.210593098232057 0.933877814183943 0.691154421225656 0.178739132003393 0.87637520425953 0.781314833711367 0.221872414546087 0.469860155186616 0.862341237724759 0.941901930852328 0.137772933319211 0.12058402251685 0.761005290988833 0.876417030983139 0.912447292264551 0.607620937335305 0.382616060345899 0.0303469228255562 0.386490601792466 0.828536445621867 0.359594642182346 0.338491571191698 0.854070940411184 0.649893951041158 0.999196552294306 0.536954955987167 0.677067228013184 0.974031636423897 0.0586759631801397 0.538610684240703 0.742575088220183 0.529025550193619 0.260822810130194 0.758852920786012 0.394382284034509 0.507470802958123 0.788104817124549 0.379922921978869 0.340087212095968 0.114466586376075 0.328421847010031 0.127910336924251 0.879907165756449 0.748575192908756 0.476961336117238 0.175726331842598 0.0565137715032324 0.847523515529465 0.75314629628323 0.37573961089598 0.996959370370023 0.394254359386396 0.927653755729552 0.876871361692902 0.88812929937616 0.996333622678649 0.25188297820976 0.570997227733023 0.103659192940686 0.793828347129747 0.182959154271521 0.0498614037479274 0.495185475328472 0.460558681464754 0.717766405183356 0.0190842047543265 0.514686250351369 0.960122823207639 0.302245367253199 0.585991757668089 0.0746180854574777 0.73527661181055 0.327266924961004 0.401849648354109 0.995435572434217 0.858487420051824 0.843281657313928 0.572034961702302 0.881796711662319 0.754964896566235 0.890446898264345 0.986188218586613 0.384481394977774 0.536205490776338 0.952476650157478 0.62115085034864 0.730800830603112 0.263479251372628 0.884171429951675 0.0216021299967542 0.602203173751477 0.300595032062847 0.638253348821308 0.971413378124125 0.469495800833683 0.220532251368277 0.991928360895254 0.604160980388988 0.155908798202872 0.0390771840955131 0.916787279243581 0.303017744857352 0.0773798256996088 0.481668826572131 0.436638131078798 0.460372204612941 0.0622640381660312 0.707392271086574 0.0245370261301287 0.912158169725444 0.804713993803598 0.792590806358494 0.593769083090592 0.459557856682222 0.373023484761361 0.858158518110868 0.0185911989794113 0.287847929650452 0.23097618664382 0.0204384523164481 0.550321185602807 0.676598571813665 0.896343619197141 0.816848352313973 0.786089782058261 0.61922037206823 0.285182114108466 0.131958609826397 0.135051117925905 0.849572133633774 0.112652618729044 0.233488212870434 0.167516484688967 0.447014090062585 0.79670272141695 0.26738221537089 0.972915280181915 0.226208474226296 0.89230535793351 0.595391361075453 0.680909332709853 0.964623914724216 0.912258403666783 0.260068669179454 0.0889417305029929 0.0602351367706433 0.531665837832261 0.814934209734201 0.187420979714952 0.795709171749186 0.523448674073443 0.494421875944827 0.688761273813434 0.053124340204522 0.99518596790731 0.910424450775608 0.814170361408032 0.88649095491739 0.0920662039751187 0.37447760022711 0.492708125642967 0.799631474663038 0.88646068765549 0.782179657735396 0.165260469801724 0.89215116454754 0.0825683164456859 0.377298376036342 0.637338345590979 0.0745571231213398 0.81729692484485 0.338466349856462 0.634965198405553 0.553638004285749 0.293349936536979 0.327803793486673 0.940387684241869 0.066074953591451 0.340117733371444 0.885267104140949 0.898109184119385 0.0823878395697102 0.234522151849233 0.531348863004241 0.58792894725455 0.677907104538754 0.521776502244174 0.76887740588747 0.361545848154929 0.32789173681289 0.449904359790962 0.687004141588695 0.867246139140334 0.681331015068572 0.23300684170099 0.254569844838697 0.653095438340679 0.906112946970388 0.94415369504597 0.428588741903659 0.602030062116683 0.437301730019972 0.887153116445988 0.929226981664542 0.491084558228031 0.614463490033522 0.905257840924896 0.716848679950926 0.198440012789797 0.28705947865732 0.593351288614795 0.377634464579169 0.244245372009464 0.98963173126569 0.845337457179558 0.249939121573698 0.226308020809665 0.635296133146621 0.853647053297609 0.056307578634005 0.459286719779484 0.768145828349516 0.386136981241871 0.659312054566108 0.293342258504126 0.29372344690375 0.987447214745916 0.419241493644658 0.326579971523024 0.0496349149174057 0.274335294861812 0.0379207663168199 0.383261123672128 0.312442067796364 0.12565769912675 0.507308109798469 0.893092736399267 0.476523344796151 0.591433386080898 0.210427101512905 0.78270740413107 0.718653240567073 0.977128966171294 0.0502555758832023 0.792387928804383 0.744789985639509 0.144325687414967 0.612792493535671 0.916828114346135 0.881774302225094 0.698336289729923 0.135832194688264 0.240130113745108 0.848275702742394 0.7039551495458 0.569498109451961 0.422294135442935 0.75280741935363 0.717700199380051 0.842937294889707 0.316336217385251 0.23715476422105 0.827278843771201 0.0869426943734288 0.241679808387998 0.125631794121582 0.0133673985023051 0.790602005454712 0.696683278637938 0.849886493873782 0.0441623929678462 0.933040626237635 0.0407340858364478 0.280728934807703 0.987337769009173 0.354868548575323 0.793910760474391 0.620483810699079 0.455623774407432 0.87342797187157 0.913545214773621 0.810104663451202 0.0520465133502148 0.350652194982395 0.275857746663969 0.915440735991579 0.635791293657385 0.2963111892296 0.649913950345945 0.173373745465651 0.851050045238808 0.329298247091938 0.90016195587581 0.902069514156319 0.723416185274255 0.121266760528088 0.566075502873864 0.0922258538124151 0.867006941332947 0.0470862272940576 0.402674518255517 0.418774737014901 0.846120648339856 0.532733684396371 0.564375839030836 0.2256007329165 0.710746975133661 0.667691432270221 0.129057335685939 0.538260061834008 0.302892665530089 0.186413545047399 0.817149478723295 0.442637341648806 0.909251198489219 0.691590579361655 0.47824414846953 0.493806354489643 0.768502111432608 0.0321947141550481 0.31908736835001 0.309960636375472 0.221066750790924 0.953768755441997 0.344351604219992 0.611238716465887 0.134760886209551 0.476885764542967 0.250046058523003 0.226537418810185 0.636418307498097 0.430232245465741 0.722325757548679 0.957448091374245 0.346724844989367 0.440495823265519 0.87520194113953 0.119346954275388 0.837448941809125 0.639493257543072 0.427102172169834 0.310392818576656 0.462401396902278 0.75369484574534 0.786836221003905 0.232501620454714 0.0878628841368481 0.771733596075792 0.0180194625956938 0.227611779600848 0.890507393372245 0.584056281174999 0.245678275728133 0.0302267840853892 0.460235795634799 0.298074928803835 0.536570608553011 0.939680627081543 0.738401610828005 0.941331245559268 0.346131952640135 0.137071097267326 0.426574585973285 0.807679406832904 0.605598916895688 0.61641938511515 0.12991644578753 0.123276541063096 0.480257249621209 0.380071450539399 0.495776627154555 0.838319944448303 0.553275889493525 0.615296968505718 0.746797754811123 0.329144999226555 0.0860631161252968 0.287704864686821 0.734594122972339 0.564625355736353 0.559750162614509 0.342128125429153 0.0139224898512475 0.451706006396562 0.54426154123852 0.234180702513549 0.552328689927235 0.264593301438727 0.829499163988512 0.940144976114389 0.20918121609604 0.993233022794593 0.0914415433327667 0.852890132719185 0.532997888249811 0.232010668916628 0.142260401456151 0.0908672200213186 0.94613494515419 0.947441213885322 0.632968118318822 0.262674437479582 0.16543055978138 0.987223227557261 0.727393737523817 0.149235318277497 0.808252047707792 0.904429659626912 0.243384197989944 0.82322621322237 0.256951634478755 0.919288079314865 0.394031580721494 0.150111353013199 0.458637307104655 0.493818622054532 0.904550192987081 0.136857572118752 0.672993126632646 0.892459764995147 0.789874407770112 0.886080462525133 0.556440072986297 0.829965110633057 0.549479491105303 0.382422656437848 0.793288739775307 0.698304474875331 0.756743652906735 0.975819128802977 0.364727597539313 0.890940523168538 0.159061385123059 0.882216649348848 0.0698794248630293 0.89685385963181 0.740978718006518 0.220931973308325 0.971009997650981 0.710145243019797 0.717056047460064 0.394135911841877 0.0352005270984955 0.277495091664605 0.1760321409069 0.910750967247877 0.889612442462239 0.420894649261609 0.377060270810034 0.73141814052593 0.648144427929074 0.172741173752584 0.359680162467994 0.147772449024487 0.441632778579369 0.0528612699615769 0.988149604464415 0.563518317551352 0.137972232094035 0.0176139209326357 0.915543245912995 0.140622002137825 0.346191727889236 0.455725753712468 0.550488845857326 0.741128819053993 0.590662497291341 0.33799747537123 0.341682155039161 0.449150406238623 0.915085191668477 0.60764232610818 0.977417197818868 0.96839367833687 0.904271868329961 0.0673263291129842 0.814725512687583 0.262530517121777 0.373891772083007 0.158536077442113 0.861756884334609 0.418508406085894 0.634397337227128 0.344525331526529 0.804453400999773 0.105820739672054 0.568498677134048 0.27088143723784 0.762506411182694 0.134386404966936 0.790137868945021 0.234631847911514 0.710385255883448 0.211959373867139 0.776432052222081 0.169258316629566 0.112508802327793 0.0938465512427501 0.691306372976396 0.40456611978123 0.817472856906243 0.537222681224812 0.104590978354681 0.985017170363572 0.371708150603808 0.718322211089544 0.0941825842345133 0.966714071424212 0.450451780022122 0.91431642718846 0.602221534184646 0.17577262454899 0.890060789100826 0.0939711838564835 0.441376918910537 0.416554790211376 0.0959724731463939 0.374453326486982 0.146348258294165 0.495382524400484 0.821958554324228 0.336013083746657 0.267889147866517 0.984980680691078 0.888950791957323 0.165941994909663 0.972118395338766 0.991373401624151 0.373472179688979 0.691302612791769 0.327739948949311 0.0114180245622993 0.367323601990938 0.329198585026897 0.478583042686805 0.232561763816047 0.846105760193895 0.0537277547549456 0.1000656647305 0.521887394152582 0.668338929931633 0.610748536419123 0.903225157908164 0.248963197958656 0.275657360840123 0.408610982401297 0.826581594946329 0.216832994271535 0.82341322530061 0.889175071883947 0.135867423282471 0.367200885082129 0.279302637055516 0.371073650277685 0.0798267055116594 0.940323644238524 0.520993045314681 0.483479303030763 0.906764442694839 0.4412355004251 0.219827900996897 0.246222921402659 0.712054431412835 0.357576462372672 0.173605366661213 0.585339393641334 0.19562513415236 0.201816543333698 0.529894480616786 0.244590532432776 0.255083702777047 0.147988030023407 0.296091928030364 0.59687902961392 0.801980834007263 0.273339430489577 0.429602025798522 0.557684655142948 0.400408055619337 0.186759415648412 0.833290227400139 0.849838689763565 0.5077957324218 0.278428246492986 0.538976211389527 0.964130018749274 0.678191299168393 0.283767325568479 0.36945813938044 0.321947163364384 0.93297791369725 0.0466380775044672 0.391419517402537 0.27042216478847 0.212256570903119 0.906536764933262 0.124468905450776 0.765532501647249 0.130036136892159 0.980448378005531 0.443566922077443 0.991637919652276 0.87058689088095 0.351127990300301 0.420075694280677 0.474761481510941 0.30675097707659 0.277960409959778 0.117206163126975 0.966681205478963 0.533609817095567 0.986271272727754 0.934784451792948 0.131398303592578 0.432658057594672 0.112507256118115 0.465445171736646 0.136750925832894 0.624833420689683 0.749671577275731 0.539309195757378 0.499292118798476 0.316052208309993 0.441971857429016 0.662858407937456 0.369329292492475 0.157597472616471 0.810231935547199 0.373453292788472 0.270047983429395 0.0537982105603442 0.330479223050643 0.715652521033771 0.931233696287963 0.406747143499088 0.79502508668229 0.249422626919113 0.167547497625928 0.142507560583763 0.619719327569474 0.358171479261946 0.639890488674864 0.842804314403329 0.607009634994902 0.178922465033829 0.942609132076614 0.961734720289242 0.993636714906897 0.238606853340752 0.540768865407445 0.835003900253214 0.782847906139214 0.281799222852569 0.0630419660359621 0.771254634116776 0.987390064226929 0.51741960307816 0.90476794462651 0.838783885031007 0.821375543840695 0.307659978026059 0.943341837923508 0.592911248819437 0.714522593966685 0.11936981019564 0.316503767920658 0.742456035376526 0.121286283615045 0.801929186731577 0.135167545117438 0.353845575284213 0.0263852980569936 0.635996518186294 0.940829790029675 0.149411596783903 0.571573661062866 0.299253347339109 0.940091590390075 0.908762804835569 0.27974690241972 0.943382129732054 0.308708501348738 0.083693872957956 0.297086716187187 0.330684037515894 0.0203206596290693 0.523867240040563 0.67562326917192 0.32646106089931 0.495874614850618 0.131072342630941 0.969422866201494 0.161799363109749 0.12639715523459 0.3807690375112 0.308860527090728 0.267728158580139 0.174044221213553 0.902492104233243 0.0718745597405359 0.687865279188845 0.740289735917468 0.81614465541672 0.675637618633918 0.0616116978810169 0.956761635129806 0.567634741235524 0.667778539794963 0.315945762330666 0.660149521189742 0.644116776457522 0.522016572963912 0.805063125321176 0.77016857925104 0.41616274031112 0.375765573526733 0.36741782120429 0.591886202620808 0.239787513050251 0.510170455782209 0.640804724332411 0.431951134125702 0.281748913412448 0.199876729247626 0.177420451873913 0.823723153672181 0.262630563434213 0.405034263113048 0.187851035301574 0.652091642613523 0.21142571255099 0.454842172099743 0.871852170303464 0.547512849313207 0.53346716380911 0.930378084059339 0.588697784112301 0.593713020081632 0.316829347861931 0.0491340939607471 0.174950743110385 0.118674881146289 0.904756170336623 0.804640599323902 0.517554751669522 0.755798986561131 0.298740233692806 0.665706355823204 0.98676163648488 0.144207751585636 0.909412994072773 0.6114158340008 0.71423640065128 0.0803739664657041 0.15437527445145 0.900599732368719 0.994788721562363 0.308902896647342 0.865830169045366 0.247576640192419 0.581188504556194 0.432806041247677 0.826070681675337 0.39699409034336 0.731170125082135 0.881883939970285 0.0848666561720893 0.0621184542728588 0.816512526543811 0.0774325618683361 0.0253539298707619 0.673924870095216 0.272594586620107 0.740602671883535 0.247981605830137 0.262464411125984 0.881929162223823 0.869921650532633 0.336967041410971 0.87138886383269 0.330466774080414 0.0545935780066066 0.572959675535094 0.0812012979015708 0.81330009798985 0.482316819352563 0.995835082773119 0.776862370120361 0.602028830542695 0.880756554882973 0.67684571941616 0.406909065397922 0.725081149295438 0.505356407323852 0.114673945126124 0.826433793851174 0.999895996423438 0.493262410233729 0.53496298291022 0.698063240810297 0.179029492109548 0.984026970816776 0.382213760928717 0.10071162563283 0.470787168049719 0.492446149825118 0.308164741955698 0.691948789213784 0.106145933060907 0.988930326253176 0.826264220196754 0.354444621354342 0.834430389923509 0.676105319631752 0.519402008464094 0.978127796417102 0.445585687824059 0.517884921603836 0.651948619370814 0.0731067060655914 0.195549615132622 0.760618705376983 0.0835631933459081 0.670313255519141 0.207353109435644 0.0190274631464854 0.0499151730281301 0.474406943330541 0.501922409550753 0.402724097694736 0.75660231947666 0.478076291596517 0.817775393067859 0.466599308925215 0.561941209726501 0.623011933595408 0.0695638860645704 0.958928231936879 0.549514639023691 0.49041357768001 0.274864233876578 0.297218334865756 0.695281267764512 0.291509877638891 0.501375292430166 0.0648916504811495 0.169965265223291 0.0954863849771209 0.546955013372935 0.30252333601471 0.642491162412334 0.536416662726551 0.689278894471936 0.406446692692116 0.0983446642081253 0.632692333797459 0.420859614289366 0.153044253457338 0.0818044266290963 0.202555386535823 0.842580687028822 0.909832668064628 0.852000918320846 0.85996092837071 0.08518487571273 0.133568154170644 0.762507249750197 0.958313327075448 0.146486629077699 0.300294215448666 0.489989957718644 0.917709855167195 0.200757780866697 0.526375526366755 0.196533702909946 0.707774402471259 0.997565077496693 0.170094200624153 0.674890670508612 0.886107720809523 0.259721494165715 0.653279150777962 0.854236879504751 0.104160725919064 0.91303304803092 0.11582667671144 0.352644956607837 0.42614424594678 0.0789591528009623 0.658252456758637 0.030934795064386 0.556755265109241 0.715604936361779 0.838061185060069 0.613479688540101 0.980046205134131 0.179490302931517 0.248920042619575 0.848941060646903 0.332436878017616 0.0827162708248943 0.983996522610541 0.323624248811975 0.42440227386076 0.668092399383895 0.579626764552668 0.380922968816012 0.141375836750958 0.591030334304087 0.780030418676324 0.0783669561077841 0.675991639567073 0.875420273183845 0.103703344510868 0.296332759407815 0.963517981336918 0.637655125414021 0.178958113372792 0.883600505166687 0.373025258015841 0.961147959993687 0.995236948339734 0.925323885357939 0.116518981261179 0.837878886754625 0.296506973996293 0.133792464754079 0.0245748220593669 0.740966995579656 0.0295423878403381 0.29916182085406 0.42914358753711 0.763287003198639 0.669334179554135 0.0761186353885569 0.391780757438391 0.27428987598978 0.731207998921163 0.115533049234655 0.812237490743864 0.207796637883876 0.37819934213534 0.600694242524914 0.506780616263859 0.712830955523532 0.317769455793314 0.838760346593335 0.848708394123241 0.69191878288053 0.750567913043778 0.0506537801958621 0.714175649916288 0.660769938053563 0.262475811771583 0.631354558393359 0.322184258990455 0.383920728468802 0.49671120256884 0.213890130594373 0.133551401952282 0.706853097998537 0.411288064436521 0.918993031021673 0.753312550012488 0.474335580267943 0.887350973659195 0.140971382597927 0.195266944123432 0.0665515162516385 0.414606745808851 0.919409577327315 0.67897888278123 0.578482887714636 0.718834764384665 0.483820070540532 0.165845276589971 0.444646823222283 0.706107883250807 0.323947101910599 0.265849667105358 0.779783118711785 0.423230552801397 0.189593227747828 0.823371595887002 0.0773230734886601 0.275646491732914 0.862252911303658 0.149919075800572 0.459417573651299 0.342837355996016 0.181914980297443 0.0232792315795086 0.255292893559672 0.341776366415434 0.0675013702828437 0.759601150965318 0.392089529840741 0.864833130033221 0.649903881081846 0.663084955085069 0.731710947414394 0.461910700760782 0.392548434869386 0.2833501838753 0.998905034374911 0.944697084482759 0.0174819364468567 0.932569172661752 0.692337789337616 0.0575515070860274 0.581464445819147 0.105708286801819 0.994138713038992 0.730019024531357 0.925046201036312 0.428756267775316 0.0848832159209996 0.338872988480143 0.62832900592126 0.551588371049147 0.190470998857636 0.304855397311039 0.943035733124707 0.288300530670676 0.316778593782801 0.170398021605797 0.193376742438413 0.0569151539821178 0.0863692301441915 0.434632828743197 0.40669631266268 0.360421081343666 0.0818910540174693 0.435237223389559 0.511014927832875 0.313798004479613 0.637484290911816 0.684687723333482 0.30901354307076 0.930943787735887 0.752283907516394 0.505138366173487 0.0957536074891686 0.192349107237533 0.801685767504387 0.808384794234298 0.236834758978803 0.36648339815205 0.0127552649704739 0.65100427250145 0.747361659416929 0.559226722002495 0.153162004193291 0.0901917578163557 0.375258758356795 0.859373156169895 0.42897218646016 0.0258673272654414 0.509853841920849 0.303469613341149 0.399595297693741 0.916472274519037 0.764541288812179 0.904129529909696 0.894164281834383 0.608324693241157 0.961507486014161 0.219942529809196 0.391562997500878 0.363046495127492 0.471584308289457 0.770208906556945 0.865852367572952 0.413767509618774 0.276534954463132 0.0155525025725365 0.184917350918986 0.849557545140851 0.70282974493457 0.301777153157163 0.436662120609544 0.189010749263689 0.43733894116478 0.949098088196479 0.725745619765949 0.503796744146384 0.0897887636651285 0.867685728303622 0.276593985650688 0.732155906821135 0.941115337016527 0.511390651252586 0.414810056937858 0.206827174327336 0.716987327106763 0.317163351280615 0.41327657997841 0.571544285153504 0.698748476083856 0.600115100101102 0.840952323321253 0.758826390197501 0.425588755137287 0.348071014827583 0.776396678872406 0.55158377944259 0.812309954455122 0.890170393192675 0.275884738948662 0.909139808465261 0.506044491145294 0.877164568272419 0.124922986065503 0.129728978928179 0.763484938091133 0.307386954922695 0.902862179423682 0.82660364318639 0.332160151663702 0.946546536812093 0.954117542128079 0.41260695547564 0.992461141000967 0.0974990924308076 0.325642271649558 0.136355830535758 0.131302741011605 0.824124214600306 0.467598244280089 0.161451399778016 0.447476719778497 0.12888366346946 0.626374223474413 0.178199856802821 0.118338828561828 0.38844990485115 0.45449685677886 0.786851508149412 0.803339327652939 0.0823738496913575 0.381888790435623 0.137700791389216 0.742597963502631 0.632274761295412 0.857919191222172 0.189085850843694 0.585111068629194 0.606611105443444 0.963724421074148 0.0558943937439471 0.290914178462699 0.0419155285623856 0.125047268546186 0.178400455610827 0.380060113051441 0.863100206316449 0.55496783773182 0.31974586419994 0.286920532770455 0.531844749366865 0.862760831040796 0.71907853720244 0.0888392906542867 0.380731291600969 0.0258358113723807 0.848122418918647 0.723722834980581 0.792597459808458 0.884826082866639 0.700765080640558 0.355813381113112 0.514703919047024 0.892334997537546 0.158059095959179 0.62085582395317 0.622973186383024 0.81968559958972 0.665434067561291 0.0470596132637002 0.340480484811123 0.878085285425186 0.98835165889468 0.587770885347854 0.316681226829533 0.450591767549049 0.811967673467006 0.766871971935034 0.273792985328473 0.753303104487713 0.260663423757069 0.502143389836419 0.329111155259889 0.583576483184006 0.911826965988148 0.543267954229377 0.13496231966652 0.176585908711422 0.19808284457773 0.593514671667945 0.122940957320388 0.820158433183096 0.356714128234889 0.583083745713811 0.888091960533056 0.36012568844948 0.320253053014167 0.702370951008052 0.0957077776314691 0.170970528097823 0.153060418355744 0.767615761947818 0.288782450435683 0.788694998305291 0.0379787182924338 0.0754657386709005 0.828736136942171 0.658465667271521 0.153375614166725 0.798002217067406 0.89680376916891 0.957523832598235 0.976646829964593 0.886384805594571 0.0989856826793402 0.971896951743402 0.833771146785002 0.902194392946549 0.0336709288018756 0.306825386688579 0.894629259447101 0.738189709568396 0.652420533490367 0.139601931101643 0.6694985208055 0.909459795728326 0.485911647826433 0.671238434966654 0.65284089069115 0.819416820956394 0.384278342011385 0.741867852420546 0.13198389293626 0.0413960032630712 0.370148614202626 0.125891528304201 0.966661311744247 0.563454311201349 0.21740908253938 0.20173746996792 0.0849975312501192 0.856662194901146 0.738841391769238 0.716842918084003 0.0242973615555093 0.185257347167935 0.141951268087141 0.638432640454266 0.786353681187611 0.182334798814263 0.226146896218415 0.495028970234562 0.0790092156035826 0.320786508261226 0.404762567472644 0.88458046349464 0.0441941951448098 0.365751200332306 0.208422760833055 0.47105529920198 0.280651551254559 0.523677651637699 0.871097523169592 0.170259831766598 0.305822900675703 0.794320705193095 0.140882683685049 0.80296209651744 0.253018695956562 0.502373318914324 0.632564982408658 0.982354162570555 0.980551897757687 0.723402270539664 0.242013053223491 0.241909370506182 0.0613796640862711 0.591262821035925 0.9490215196996 0.521902842419222 0.916855106400326 0.567525803525932 0.610082656657323 0.848244327455759 0.428554506083019 0.91454684101278 0.119755439683795 0.31777647343697 0.685627849935554 0.63743688441813 0.701522235639859 0.556951384565327 0.503308834778145 0.210972769234795 0.901356128554326 0.561839987852145 0.433411114723422 0.0538561385637149 0.862223533319775 0.924885889426805 0.41434110385133 0.118785831141286 0.434048904548399 0.0842475642357021 0.689265072168782 0.366559424968436 0.359672880207654 0.879663889210206 0.190249422723427 0.180206338849384 0.941303085319232 0.835257312678732 0.799437422351912 0.0821900067897513 0.450383557553869 0.826331351005938 0.543094500529114 0.025630449464079 0.552526985325385 0.344207449902315 0.158502828401979 0.916471097574104 0.747690595933236 0.857338134015445 0.170829771845601 0.968641539113596 0.412209853655659 0.899878251524642 0.437732817796059 0.0222020724904723 0.612447786049452 0.817103611524217 0.0710681394767016 0.222869238038547 0.784692741506733 0.360659567129333 0.305409713480622 0.0921806382434443 0.164194627685938 0.36829744163435 0.46475394340232 0.243992781785782 0.972772197239101 0.319615768450312 0.060364551616367 0.620423796188552 0.293837622087449 0.0287696223007515 0.559168632416986 0.779882887729909 0.310250535937957 0.859919970640913 0.759050756793003 0.924746663710102 0.929059302047826 0.196974581733812 0.4788808231242 0.729996610945091 0.359130018160213 0.895741730802692 0.167677537593991 0.133252081067767 0.784866309766658 0.783195207698736 0.172672055552248 0.0883667018543929 0.060280242851004 0.988823147967923 0.940763400285505 0.925426407495979 0.143734139124863 0.712619184267241 0.226904049834702 0.0129637123830616 0.393785957430955 0.760750727434643 0.166334895824548 0.403403752967715 0.160132979885675 0.876053389343433 0.518349717811216 0.457957358171698 0.503889219379053 0.440875282436609 0.927838657328393 0.33963655259693 0.154585779097397 0.452995855524205 0.571429430448916 0.247155204010196 0.270084355545696 0.457045187354088 0.260105140872765 0.75584475717973 0.563906270964071 0.326444836070295 0.694422388165258 0.511014253844041 0.132182197324 0.645557464470621 0.3888447452127 0.640846395466942 0.156392644275911 0.708873601502273 0.870814879359677 0.235178040487226 0.212604372652713 0.44449813653715 0.366470089638606 0.834020570367575 0.156424828164745 0.118324367075693 0.777905701377895 0.271399623318575 0.638230406232178 0.961782498352695 0.372115662831347 0.535336590318475 0.386694080957677 0.559479043229949 0.662603752412833 0.829457828234881 0.129533417979255 0.992653597774915 0.414377384919208 0.294994985847734 0.89905000338098 0.988989538154565 0.0381009990908205 0.582059380649589 0.647759010964073 0.0446002505975775 0.208610156697687 0.614185610245913 0.912961772098206 0.608947594228666 0.346700730295852 0.105312559697777 0.237244342269842 0.950533713456243 0.964929326171987 0.386059744288214 0.307827400863171 0.408542715446092 0.193577971209306 0.317122772266157 0.593942070023622 0.0319236982660368 0.456714528524317 0.764429263754282 0.263491384785157 0.423082305914722 0.738069642975461 0.167543320462573 0.614529764987528 0.910853460573126 0.314041349946056 0.362954940521158 0.86726374882739 0.950151085108519 0.94315848599188 0.552057029323187 0.0476944323745556 0.817504201305564 0.898549401862547 0.212467429831158 0.461040221361909 0.486629782698583 0.616851252911147 0.870599293289706 0.142690411633812 0.629506895914674 0.514938473845832 0.841594972596504 0.282183271094691 0.585204823149834 0.766464700351935 0.144662547218613 0.739621114791371 0.354771877969615 0.721756576744374 0.970386073463596 0.983659039989579 0.182639222559519 0.856006956049241 0.535407226607204 0.186149394670501 0.327981674445327 0.618098891067784 0.995191993238404 0.628778910294641 0.328176170703955 0.414152690088376 0.229315047117416 0.313514950145036 0.653139076351654 0.633078412304167 0.81320171313826 0.0192681389348581 0.886112417064141 0.606202061988879 0.125096247526817 0.816769161161501 0.214157116841525 0.836063173513394 0.284241012942512 0.327836791970767 0.571671536965296 0.3940290269861 0.745616605745163 0.0976000397768803 0.212540450897068 0.344604946111795 0.750328528068494 0.257806298190262 0.837809093182441 0.260787644693628 0.605449623758905 0.778916531344876 0.763148449626751 0.867864510756917 0.167084845781792 0.904140575351194 0.788452689407859 0.244758055768907 0.832997922776267 0.264821809469722 0.14664747568313 0.187545849515591 0.910285385949537 0.273313892905135 0.143692110020202 0.683132167477161 0.966211359426379 0.786131750540808 0.54071054255357 0.265418513866607 0.889324116308708 0.48969870418543 0.0996818124153651 0.15109118202934 0.0714090222376399 0.165169112505391 0.511822136645205 0.716031205256004 0.740431303537916 0.227836218574084 0.109014464344364 0.498811694532633 0.812254159059375 0.474426318204496 0.602218412721995 0.169515569685027 0.868207830619067 0.210712412234861 0.169291638277937 0.671014170714188 0.658318890759256 0.122563036060892 0.939174296427518 0.469919703621417 0.288739664822351 0.505659214325715 0.675704355975613 0.124167891296092 0.93194298932096 0.919003582266159 0.867803312155884 0.422579473594669 0.74750357048586 0.305051165020559 0.0764485987927765 0.0517751420265995 0.0469453763053752 0.348593194822315 0.230382252654526 0.296693935825024 0.537219825761858 0.625813464534003 0.243886282790918 0.0736204681149684 0.285516498547513 0.083008217709139 0.510694257130381 0.437936721777078 0.584512902847491 0.238704659861978 0.297660766583867 0.162888612276874 0.308181036165915 0.607688343594782 0.196605526977219 0.488631166494451 0.194804765270092 0.65374118741136 0.408944141720422 0.505057174952235 0.312474302626215 0.195846713974606 0.200253831532318 0.452967996550724 0.0322159021603875 0.28110653659096 0.387372812607791 0.797531407515053 0.201953596796375 0.0755088861729018 0.913160249823704 0.401567325403448 0.676765313516371 0.369980600357521 0.840028204184491 0.411356822822709 0.491684161422309 0.451744444505312 0.205950571403373 0.698482982108835 0.530285338589456 0.486561991730705 0.122097681115847 0.0718278518994339 0.165661347480491 0.96314798820531 0.866520111868158 0.700659222211689 0.36102822680492 0.49146706671454 0.208935753004625 0.235719800272491 0.755909568904899 0.445008190956432 0.428211809960194 0.925879481276497 0.418766256603412 0.604289790627081 0.0821879089879803 0.332292889431119 0.442477530459873 0.156572069830727 0.507459820674267 0.600058548657689 0.312701534826774 0.858604052851442 0.483227516338229 0.558268539921846 0.309658348464873 0.0711489598196931 0.247146703775506 0.0379281310969964 0.187786240172572 0.490756941568106 0.32446237328928 0.845810573829804 0.39186131616123 0.79194367634831 0.898384826651309 0.0128908116393723 0.447979819711763 0.322779541418422 0.64096860043006 0.278539749002084 0.629260443507228 0.100017977023963 0.766003813925199 0.836218740693293 0.586438162554987 0.583145760523621 0.436425885218196 0.496052169878967 0.456953983111307 0.274293569098227 0.996250400501303 0.154665174705442 0.472694761136081 0.549694991658907 0.983459562805947 0.938226343118586 0.290908144603018 0.134914931843523 0.583804854527116 0.944095424285624 0.85457700091647 0.106654995167628 0.567184126684442 0.461806533758063 0.614850284710992 0.470837837534491 0.33765277572209 0.467356430962682 0.231688121464103 0.0271787147619762 0.863908542285208 0.1239202015521 0.475354738053866 0.0845756582659669 0.0976432928489521 0.917165554324165 0.651462797892746 0.897662607738748 0.810773136133794 0.290637851799838 0.856207125661895 0.412560381556395 0.446714160882402 0.0865973797440529 0.548146299701184 0.857768634702079 0.323457683213055 0.280624933305662 0.0643455180665478 0.263609515619464 0.317009032270871 0.167576857630629 0.380448580484372 0.670037436422426 0.481059968709014 0.668370116667356 0.919551611945499 0.267436068553943 0.52578029234428 0.879150334612932 0.116000868480187 0.76752645842731 0.0548440305516124 0.0550285151717253 0.15096732390346 0.378877586734016 0.987725610858761 0.801934123630635 0.579353006377351 0.411922398339957 0.69599479581695 0.785786216934212 0.941450250458438 0.641853979269508 0.538401586120017 0.537750904299319 0.439320585893001 0.161500009493902 0.251406629225239 0.151341798000503 0.223706326177344 0.724537754787598 0.373241007742472 0.540634681698866 0.154713614771608 0.839331466383301 0.662327243883628 0.424098182499874 0.599945168707054 0.0534884333983064 0.026869627032429 0.699318375363946 0.803605301533826 0.343051196932793 0.333590299496427 0.189332574782893 0.0214174065762199 0.26956649285974 0.991559552084655 0.243894232125022 0.703012299558613 0.414826934549492 0.0281054346566088 0.959603832443245 0.836724923825823 0.131607697678264 0.131716754557565 0.781630092910491 0.0326069814153016 0.796464112773538 0.976816096128896 0.340257184519432 0.969376498120837 0.93915362036787 0.871647019765805 0.521745636598207 0.259869554575998 0.897171024163254 0.664601552358363 0.602135736604687 0.835158419569489 0.813079195844475 0.089919632289093 0.334553896768484 0.736657261571381 0.583869607243687 0.132888982952572 0.439610858408269 0.299646139687393 0.806310988909099 0.664503009843174 0.487037375140935 0.0468095968291163 0.0956612226134166 0.162292827584315 0.932908656504005 0.607010115822777 0.494151067738421 0.231397412838414 0.0599009381164797 0.42359015465714 0.148616985385306 0.422618509165477 0.781707208158914 0.591401494469028 0.606882990787271 0.0720304198889062 0.888575389396865 0.638192680606153 0.319422235921957 0.314542345623486 0.687792385360226 0.934414892005734 0.373109468817711 0.106286930649076 0.969633218024392 0.871392846913077 0.689609710504301 0.104102928149514 0.749317198372446 0.249134623238351 0.572999914789107 0.0160711775487289 0.1603122682916 0.2481585606304 0.374796213004738 0.202365108700469 0.469123438599054 0.505887050903402 0.247950627929531 0.158443926987238 0.927818347536959 0.831302709241863 0.495992765969131 0.828852896748576 0.795711017842404 0.632857941428665 0.990057999929413 0.984148225188255 0.985404013907537 0.187059289047029 0.12849408271024 0.872629001904279 0.324316403996199 0.822983876203652 0.759555380346719 0.188006560299546 0.473006548509002 0.792937260360923 0.312645775850397 0.118991932270583 0.207324785308447 0.951236897024792 0.389099799275864 0.732924303649925 0.0995576956658624 0.0339981485367753 0.415141961863264 0.784252167406958 0.0692044958099723 0.684313760721125 0.213286444742698 0.968746439574752 0.17701259596739 0.412356952179689 0.376137096732855 0.781754060524981 0.0389653948415071 0.29220805907622 0.0250037196022458 0.510869852888864 0.818950271548238 0.763005160153843 0.113749135634862 0.0810362397879362 0.26853529847227 0.404987032262143 0.436523002998438 0.786203017944936 0.380711523029022 0.896628132842015 0.274254608440679 0.881341236047447 0.575474163757172 0.956803873069584 0.606638490965124 0.593219564596657 0.582959716324694 0.77359928014921 0.03802520070225 0.364074369589798 0.0452770153712481 0.966149057410657 0.235265773364808 0.579722339119762 0.597894390565343 0.200666304400656 0.904528976168949 0.551035967357457 0.130306254283059 0.189635633493308 0.276408431038726 0.9180811202107 0.921158243662212 0.658449019240215 0.492396688864101 0.0548236138070934 0.279935992246028 0.202799684207421 0.316190848781262 0.059628436639905 0.331925422374625 0.539842350659892 0.824926111486275 0.0107212876831181 0.709161045062356 0.793727966819424 0.548783278388437 0.960739259065595 0.275036056081299 0.367104869794566 0.418526494987309 0.662135796479415 0.215878144332673 0.0103232977376319 0.627263905561995 0.725212392255198 0.993790219321381 0.854977751588449 0.778565667832736 0.264670544154942 0.312625275664032 0.60653381754877 0.409324400965124 0.220103081371635 0.119342954598833 0.0749245256371796 0.409391135771293 0.278751222218853 0.0240352930757217 0.465339084649459 0.91797404772602 0.412204416336026 0.574066720635165 0.928912030647043 0.183369167218916 0.385392126077786 0.786102408745792 0.315776551486924 0.734723710233811 0.484923446504399 0.749012350733392 0.953168838303536 0.550442504284438 0.930154085115064 0.625501078546513 0.856940840878524 0.391641055964865 0.544559869118966 0.0743364298110828 0.896158979218453 0.109028747882694 0.320079074690584 0.597662548548542 0.856833542962559 0.947197781288996 0.961799948532134 0.572779526894446 0.160571888145059 0.949979615572374 0.558590297212359 0.390465689050034 0.0772476697200909 0.376823135307059 0.449921344816685 0.672001036736183 0.244442067029886 0.0266478008031845 0.461992568967398 0.39395219802158 0.726489039361477 0.934931097610388 0.83802898388356 0.600991067760624 0.71440573066473 0.652094971297774 0.468650463707745 0.704174780240282 0.962108160583302 0.203852198217064 0.47390042666113 0.564749500146136 0.76956075864844 0.950027958136052 0.622496776545886 0.495980155877769 0.175209207916632 0.512483807895333 0.176979827985633 0.309934122613631 0.854661575912032 0.707704054540955 0.652482696282677 0.537786355097778 0.525150119008031 0.915867675878108 0.940422693628352 0.260824061066378 0.616584636159241 0.918125925255008 0.46516044579912 0.584292439578567 0.114157210979611 0.725387520785443 0.127411387877073 0.98338984875707 0.405336360859219 0.676350932088681 0.519263361999765 0.800434647148941 0.210728215705603 0.41833123230841 0.606640472593717 0.719927441582549 0.778746036372613 0.655926371926908 0.516347696445882 0.432154901188333 0.550141224130057 0.854585033922922 0.262443929149304 0.415429748410825 0.326095339437015 0.532230567636434 0.106417361549102 0.759208089159802 0.857736409092322 0.305619323546998 0.186108284578659 0.433017408663873 0.452997842915356 0.639867964447476 0.927254936897662 0.337881161125842 0.565787065618206 0.0582938682148233 0.989581529470161 0.127610530601814 0.0619749094033614 0.461921420963481 0.176197356223129 0.133430884496775 0.0816153589310124 0.595128088681959 0.0673823400284164 0.806224206392653 0.207257258957252 0.0278218785184436 0.925974587693345 0.0664905820367858 0.377839808969293 0.0706978068151511 0.562601047791541 0.644682100957725 0.852619217098691 0.846449565263465 0.669383123037405 0.266703322138637 0.201578139606863 0.355795034971088 0.906224938605446 0.475779968535062 0.570328179947101 0.799451696670148 0.552126371571794 0.951866279277019 0.552696275461931 0.729325451296754 0.446124674205203 0.358095094014425 0.729135747181717 0.103161526639014 0.914578206618316 0.987435755783226 0.766917361994274 0.766685570457485 0.899809493829962 0.963660365166143 0.474064098533709 0.220846429050434 0.478789456607774 0.0564815060165711 0.841812821046915 0.476711143578868 0.267147661263589 0.796763611836359 0.0967125546070747 0.695954580765683 0.0779126330045983 0.604261695158202 0.50937130256556 0.0453744927351363 0.895679993748199 0.779396774896886 0.127931372106541 0.0959804821806028 0.682272940971889 0.426803312520497 0.56231978307711 0.0107825731835328 0.972001074950676 0.174915676559322 0.385385596407577 0.588330155934673 0.696203503927682 0.77504690236412 0.224026305372827 0.103935922752134 0.130805047280155 0.382192496627104 0.490286535625346 0.481004940425046 0.529053356382065 0.490921068913303 0.764444643792231 0.552587127995212 0.0645730141922831 0.459323089821264 0.385419693696313 0.198049145597033 0.803396112825722 0.781018798407167 0.643196925993543 0.16637197420001 0.824326746861916 0.253428367068991 0.0858474122686312 0.0456748448871076 0.489624130455777 0.576393564972095 0.742795460440684 0.225313991697039 0.210649850443006 0.813830573302694 0.697675835071132 0.779191617905162 0.458320885943249 0.9986463266192 0.0841682977089658 0.968148341791239 0.956858843266964 0.70652867149096 0.582150051048957 0.795702706619631 0.148118123468012 0.0188222725014202 0.177291602911428 0.78036801908398 0.896780527618248 0.917773496631999 0.247622497479897 0.959653756483458 0.338297551150899 0.665588736473583 0.404582405462861 0.252966599892825 0.67327911272645 0.906828349006828 0.648955601612106 0.76260138229467 0.259002140397206 0.216905460287817 0.108192958624568 0.925954498262145 0.431278452009428 0.0821165805007331 0.541482268297113 0.164846601011232 0.35573023223551 0.902262261824217 0.210503787796479 0.436586348728742 0.729479238998611 0.824544701573905 0.963511993116699 0.466653087886516 0.890114904365037 0.744862742780242 0.141969129943755 0.307195516508073 0.735856942473911 0.824121122641955 0.396281933779828 0.694416267175693 0.714260383497458 0.186606503855437 0.518201240191702 0.663783269983251 0.0531849913625047 0.0550064498744905 0.0421774278534576 0.392717234957963 0.79734476700658 0.488270068909042 0.546254040091299 0.619436801085249 0.891632869669702 0.151239844281226 0.586696813837625 0.565966136660427 0.215602761115879 0.464570153746754 0.280586292124353 0.474015556355007 0.795687393427361 0.945805548324715 0.430837748136837 0.332862966198009 0.224604220371693 0.10908913903404 0.315278916533571 0.024028582230676 0.826764501547441 0.30833564030705 0.339410703179892 0.831516299392097 0.507727494509891 0.480746302050538 0.863533077719621 0.252338902843185 0.0694998566643335 0.88662795352051 0.177642750402447 0.282810781898443 0.739690016780514 0.583348732122686 0.408089322880842 0.235964414423797 0.69085247192299 0.111766464940738 0.652638098192401 0.0774802094674669 0.930112124239095 0.327247060730588 0.938960363750812 0.0941342992964201 0.869969210771378 0.0523339315550402 0.543274848554283 0.614691140134819 0.116206460429821 0.187613248859998 0.254131890167482 0.393605683397036 0.815394210570958 0.0488743685372174 0.588938269505743 0.127733243131079 0.567956785270944 0.565403814222664 0.962531197373755 0.985116199008189 0.826200744002126 0.291732410127297 0.0312218580651097 0.461580587991048 0.325342987184413 0.642099743396975 0.0746142376819625 0.230822884149384 0.869957138211466 0.0149139186670072 0.398099899950903 0.644353452569339 0.059067670092918 0.144893682284746 0.15466566659743 0.669380411638413 0.74896561730653 0.968955440653954 0.0575171993486583 0.713709556672256 0.279885265827179 0.810162725145929 0.643253784696572 0.952894562650472 0.120771204475313 0.372086189419497 0.755908402102068 0.903695877103601 0.0266222115862183 0.0467431950988248 0.662070364472456 0.603394856774248 0.307832644791342 0.0350083964853548 0.722677562662866 0.263073415127583 0.193715595626272 0.587226700908504 0.48256474328693 0.592469313142356 0.852686952746008 0.16941523731919 0.282647723623086 0.493348434397485 0.650424481674563 0.37977674776921 0.225323234379757 0.557763417561073 0.674250572202727 0.157333573948126 0.233371654292569 0.668989620050415 0.162253771498799 0.951155963044148 0.109145016258117 0.460212073256262 0.483557259843219 0.381972306042444 0.116669214616995 0.113253121573944 0.463941000152845 0.990800508810207 0.33795735966647 0.80772191768745 0.666241055782884 0.315469829863869 0.297124904892407 0.661459510689601 0.436407959512435 0.878069806271233 0.85749311594991 0.33921074378537 0.940384646451566 0.260752427394036 0.885224751180503 0.166672283939552 0.241426278636791 0.956965054825414 0.501391592402943 0.133619569560979 0.506861208179034 0.325399806932546 0.161137642532121 0.96356576124439 0.922727265234571 0.616640941426158 0.703133831915911 0.354741856653709 0.790017035240307 0.743818250251934 0.641545999334194 0.87967555769952 0.62034988722764 0.250890110598411 0.111575991178397 0.973419907884672 0.501745558246039 0.882572044997942 0.451030262748245 0.923629014811013 0.397543480447493 0.585191416442394 0.742925496951211 0.25311361704953 0.49806756637292 0.102203113595024 0.390579639724456 0.279663561533671 0.341069436261896 0.562617576653138 0.112820919088554 0.706686443425715 0.160568395112641 0.265200308137573 0.873316900401842 0.754066386008635 0.341688342874404 0.649377683661878 0.728258123593405 0.200592770006042 0.342210828284733 0.423862163780723 0.714495996532496 0.107234019343741 0.974492706099991 0.529682539710775 0.978763447641395 0.563734591209795 0.162343446589075 0.708268561218865 0.198430514249485 0.327164575469214 0.8555406546616 0.109723455649801 0.0896074369270354 0.798342635596637 0.178183058944996 0.32534959268989 0.804331111211795 0.880743439991493 0.974095491564367 0.229029737317469 0.531620154113043 0.899385836988222 0.174203180926852 0.407827219364699 0.626542611194309 0.548489118451253 0.322259851540439 0.119066170849837 0.33590923944721 0.487622997676954 0.699845723451581 0.808509639832191 0.761034494251944 0.407901192174759 0.140696512709837 0.916130285807885 0.134419349052478 0.0314777308725752 0.120571070590522 0.748772346167825 0.245342204472981 0.460150475655682 0.593374008538667 0.252946401434019 0.678331105981488 0.935042969153728 0.211599917919375 0.832508557094261 0.204746335223317 0.301034295756835 0.598397810435854 0.785926765273325 0.0359918499202468 0.586309725039173 0.686185402127448 0.13803078291472 0.753450579191558 0.980010648765601 0.31294947051676 0.0816925382590853 0.880322408340871 0.194713264601305 0.303289867618587 0.961114191401284 0.430132868762594 0.724112767486367 0.908525111516938 0.0395505234110169 0.789016937231645 0.767205485766754 0.239686582991853 0.640789020669181 0.208442133401986 0.145756447000895 0.61952541955281 0.658809759777505 0.854317837918643 0.91801896433346 0.136527613094077 0.405658959713764 0.208985166251659 0.983086063042283 0.125936375991441 0.314633777141571 0.450167531224433 0.662677320230287 0.801608154370915 0.364281546012498 0.81735211401945 0.0236657902225852 0.645272552287206 0.947185159211513 0.715846781258006 0.86189181095222 0.887956543406472 0.87234630438732 0.802699682514649 0.599186974603217 0.816231868742034 0.316439596300479 0.813598441544455 0.558052140639629 0.296198486955836 0.510660282468889 0.221449562618509 0.575972954910248 0.414173556542955 0.746384083100129 0.399857043700758 0.751754026669078 0.934977642255835 0.0220935323974118 0.363857142804191 0.128754169561435 0.931835926517379 0.0556497860467061 0.674957638583146 0.432108559384942 0.37585931790527 0.523595558921807 0.874863649224862 0.327381705674343 0.725700795359444 0.319867032133043 0.962151661906391 0.862738904275466 0.82754578138236 0.124984896918759 0.770438435713295 0.689709810984787 0.715538644811604 0.600370950780343 0.72440871819621 0.0831125504430383 0.827521618974861 0.967263545892201 0.919215752983 0.218430608506314 0.806545955385081 0.54650205323007 0.234237869628705 0.3063541998039 0.652585391758475 0.888618809122127 0.31670602818951 0.505773132038303 0.298638521539979 0.0334670937410556 0.952655773062725 0.0850572880590335 0.281170948394574 0.374121209268924 0.687813440135215 0.9686895193276 0.21658098353073 0.650974835508969 0.0891050423309207 0.488870084241498 0.395073992044199 0.163922130358405 0.598369742396753 0.0567737797531299 0.415808940660208 0.638134050031658 0.936327377504203 0.483847306005191 0.590243654260412 0.617535790915135 0.897906714093406 0.977165761720389 0.330366994459182 0.551362329162657 0.076805104771629 0.0191564736911096 0.27103760303231 0.973789367864374 0.785325849598739 0.220612810782623 0.915248224588577 0.09700161191402 0.323593828727026 0.354034312441945 0.334926097651478 0.272917584474199 0.259278723148163 0.887484124256298 0.0674121988401748 0.932741715186276 0.282399825504981 0.0878482813527807 0.537205688131507 0.985643031001091 0.160160417731386 0.808971407008357 0.665338660108391 0.944873519500252 0.0893335429858416 0.24933354583336 0.295799632857088 0.317096997264307 0.85551325046923 0.155528272036463 0.824178875694051 0.309641622523777 0.0974890282377601 0.665424583081622 0.196879924796522 0.967648607422598 0.218239086880349 0.0506514811655506 0.305232110046782 0.124454677002504 0.977133682018612 0.647682338049635 0.705728627843782 0.0464736869256012 0.103807659957092 0.130271407170221 0.0945804338040762 0.788162146974355 0.513703875206411 0.778190851439722 0.937682372815907 0.499919644584879 0.997137010453735 0.933385896149557 0.997764642271213 0.379918947427068 0.636855967126321 0.66410222413484 0.788305997028947 0.928279708798509 0.22120510405628 0.919034952942748 0.298536507890094 0.213991719658952 0.922875102979597 0.391719509279355 0.603865607548505 0.566888350003865 0.252908818488941 0.203470582927112 0.907534416159615 0.978279148631264 0.562814356037416 0.252785146378446 0.549183468709234 0.842962751106825 0.657305604789872 0.26696514651645 0.850491133083124 0.685924167835619 0.844479701048695 0.185277670098003 0.797979033142328 0.469599463497289 0.91119134680368 0.991093801136594 0.215068386625499 0.0980495405406691 0.831591208963655 0.123601649166085 0.79799633764429 0.126966549023055 0.543556312883738 0.409173474258278 0.435980467111804 0.741701307797339 0.914831557730213 0.154024692843668 0.239531810123008 0.942509454798419 0.891907947701402 0.191378566774074 0.963622939193156 0.823935058619827 0.114719168532174 0.493326816274785 0.65122307454003 0.435721642952412 0.283625981765799 0.570040138233453 0.723067960552871 0.540336212059483 0.719346802968066 0.271721335661132 0.218531138182152 0.394036691188812 0.099942576251924 0.276975790874567 0.467386331264861 0.982635968043469 0.511672481850255 0.989235471701249 0.576585022979416 0.454040893421043 0.258795260170009 0.850504628303461 0.0966773937805556 0.393850300314371 0.567580076453742 0.153079293961637 0.112055251868442 0.491418692111038 0.364544208957814 0.335144559007604 0.197453190332744 0.865845206326339 0.699519431258086 0.380314824818633 0.475381877168547 0.65001733594574 0.580981452604756 0.15299521754263 0.403545962767676 0.271212609626818 0.0864291833410971 0.885652454951778 0.898352042534389 0.281313371409196 0.71942975084763 0.941192746616434 0.499901737549808 0.830293286030646 0.114287293590605 0.210779602974653 0.119146352931857 0.439470116908196 0.0818463065987453 0.639892622435 0.665911600405816 0.978033442129381 0.299611563414801 0.777675279255491 0.0408729183161631 0.282844451605342 0.546454165678006 0.88775951507967 0.3786332083866 0.588517267589923 0.423114825645462 0.705961772198789 0.882649819944054 0.852782336687669 0.35047305455897 0.468939167424105 0.550700724758208 0.580992729701102 0.267798914499581 0.517887325973716 0.161309423937928 0.0553854699386284 0.347075507733971 0.68509902455844 0.350137609117664 0.955975079557393 0.417752428723034 0.61691911833128 0.798886379315518 0.224497406280134 0.627440242615994 0.102613431497011 0.882136849670205 0.689968672946561 0.775438490568195 0.042884385206271 0.98648483844474 0.312141439733095 0.662199593994301 0.123732953669969 0.895100788166747 0.549169219976757 0.703752729308326 0.721238719590474 0.703518439817708 0.242374540818855 0.412197066307999 0.097231815289706 0.852807702086866 0.519886214351282 0.232013424572069 0.292396135844756 0.746593570539262 0.26191050110152 0.634327428864781 0.44706076862989 0.52361695645377 0.0626463163807057 0.198819234082475 0.309390161300544 0.461763846108224 0.721866846526973 0.760178210339509 0.195345604890026 0.423039081194438 0.146291400052141 0.473297410649247 0.624690286575351 0.238267523704562 0.384931408609264 0.461851838300936 0.134806456521619 0.679168566842563 0.586588897483889 0.689309040028602 0.255512398860883 0.477362668116111 0.368948862676043 0.309219894525595 0.536877206396312 0.123504508566111 0.235857350467704 0.706468937501777 0.673431957212742 0.2977540962887 0.036215797001496 0.0246406987053342 0.884732244904153 0.607349137277342 0.680641018308233 0.885719446076546 0.397791783788707 0.402231168677099 0.731547232898884 0.820941499411128 0.986203390019946 0.318257552098949 0.0126020493754186 0.488113743376452 0.906139811326284 0.738227423899807 0.249881161530502 0.871095694594551 0.781860290293116 0.851344992341474 0.701778094617184 0.152058285702951 0.720858825691976 0.189686425835826 0.233486682104412 0.157066435799934 0.555795243850444 0.699048195276409 0.983063977691345 0.931725211404264 0.626815866183024 0.951274015738163 0.604323328025639 0.692295257046353 0.903323956280947 0.861200866827276 0.289176933057606 0.412827320550568 0.791019121792633 0.819095740190241 0.876945133274421 0.380756959880237 0.362646331314463 0.0817902813921682 0.776936430751812 0.766933528506197 0.396969968043268 0.872888045501895 0.593641852024011 0.507474134638905 0.819623566570226 0.562283530822024 0.993660229602829 0.360994722368196 0.810029154343065 0.201503127231263 0.509528884335887 0.414813174251467 0.0851506839180365 0.771775936128106 0.427049302770756 0.0890970692550763 0.173382167790551 0.933889155359939 0.663301222750451 0.548640998054761 0.747075577664655 0.103500808330718 0.641036798004061 0.901122821695171 0.567300546038896 0.487233030595817 0.524682794190012 0.856448958341498 0.136194825344719 0.573265006768052 0.130455111770425 0.814769533332437 0.497542599374428 0.237681079888716 0.365067364899442 0.531906019654125 0.230404859171249 0.210033368945587 0.488083661899436 0.165563394359779 0.746711656656116 0.158709722228814 0.697772422234993 0.159868130164687 0.555885982478503 0.953043528704438 0.0251034485129639 0.913229367332533 0.274201745956671 0.684664183512796 0.667937782565132 0.256310552619398 0.406111306950916 0.707975263360422 0.637927793082781 0.084438950556796 0.896825621712487 0.309102757617366 0.347849061130546 0.051149600634817 0.377628403289709 0.942807433467824 0.453787471314427 0.1965298816422 0.626940358420834 0.212882911907509 0.980314901017118 0.109720903066918 0.32360417666845 0.539407078113873 0.732811874060426 0.774813237304334 0.955891322845127 0.597402480829041 0.962100695765112 0.38980419666972 0.183880562470295 0.577444543836173 0.809848992102779 0.172412173617631 0.029607588192448 0.672159073979128 0.722824495455716 0.546898721936159 0.0782658342714421 0.138650202625431 0.149347499154974 0.144504651734605 0.328468444901519 0.344457198954187 0.145504451012239 0.0288240236183628 0.44810089429142 0.361428171179723 0.285586162116379 0.266551522058435 0.247192981268745 0.294362884589937 0.636699854577892 0.321740821129642 0.118979027597234 0.22886531193275 0.23171550468076 0.381407421801705 0.768672321503982 0.0404148318013176 0.720808177413419 0.904807834899984 0.908735692228656 0.893349099485204 0.669930027173832 0.299962748938706 0.29533763471758 0.940927807230037 0.814287535888143 0.760976757796016 0.148225213470869 0.465368604622781 0.473564724670723 0.167567600887269 0.581774834273383 0.452431487839203 0.537540121898055 0.726974942437373 0.0497152855503373 0.591929756267928 0.562478600339964 0.364069407335483 0.0965555645362474 0.310655334000476 0.618196298819967 0.288963687047362 0.850951578328386 0.149148323007394 0.930336409467272 0.299550134772435 0.649321213124786 0.944577860836871 0.294045280490536 0.737322313829791 0.331646258688997 0.0642869193013757 0.863401923964266 0.306478601684794 0.0973280822858214 0.803182942650747 0.509894433151931 0.430239618313499 0.11860719159944 0.0113338119164109 0.211317064121831 0.207538786213845 0.763066289143171 0.912594486216549 0.0455383660667576 0.361516002020799 0.0109113610628992 0.0204780092835426 0.749633077622857 0.861290060859174 0.531883430425078 0.99356049377704 0.109279931120109 0.166679064396303 0.0709203280089423 0.289701143547427 0.270411585422698 0.885621108477935 0.775366977679078 0.494819971460383 0.277122423322871 0.878921852398198 0.351993238679133 0.100964336178731 0.460963635577355 0.444612166273873 0.527196631012484 0.660351922756527 0.317025185183156 0.140479939398356 0.24967675321037 0.90370630641235 0.214037775408942 0.441474613407627 0.0661199635523371 0.161957224018406 0.348460377070587 0.651958512531128 0.23138683116762 0.554713158465456 0.403733838307671 0.0222798905405216 0.170968105518259 0.706859046802856 0.21840593668865 0.197321904269047 0.177418854492716 0.0701443280605599 0.97549283038592 0.315338576301001 0.829106649856549 0.0387425659270957 0.444807320616674 0.826879855750594 0.813234485499561 0.797410508117173 0.909884866471402 0.0738799653411843 0.719182063639164 0.181866521099582 0.320061505802441 0.569690503759775 0.37550132495584 0.285303416654933 0.702256644899026 0.709779565813951 0.0986394707043655 0.581345851905644 0.979190833780449 0.168247366340365 0.966710136057809 0.302337999457959 0.170488652819768 0.709439375943039 0.233389418877196 0.29505680104252 0.266395250002388 0.0671182394400239 0.791095958594233 0.539923057134729 0.0279859083611518 0.546792370693292 0.235493925500195 0.566335857799277 0.0832756163249724 0.992030714305583 0.319049219060689 0.706543304701336 0.169780106383842 0.769527353097219 0.321737261712551 0.0594354098336771 0.550608539266978 0.200979638674762 0.576943556687329 0.608442948777229 0.100132984321099 0.872360082203522 0.54699139079079 0.53541102712974 0.92886120419018 0.998854667770211 0.218610431216657 0.329094921902288 0.989835721454583 0.252627883392852 0.706651611756533 0.718770092113409 0.695023522125557 0.415694549956825 0.824117743938696 0.635454550026916 0.288085117938463 0.014747202550061 0.0622705682972446 0.726907615240198 0.421879847829696 0.181257801537868 0.686419295154046 0.656904155695811 0.351084766502026 0.0595550096593797 0.43131234184606 0.302822277031373 0.0424877711292356 0.309300975797232 0.862768752023112 0.713327146379743 0.990471511210781 0.808433939868119 0.380225825330708 0.362052166131325 0.752420468856581 0.53282096618088 0.261189434009139 0.939583810798358 0.20202714709565 0.915370885946322 0.132853447559755 0.169635448418558 0.516660869829357 0.160469284639694 0.737332701417618 0.524309040412772 0.100589235115331 0.375125413676724 0.974138911289629 0.872636358847376 0.961555969184265 0.694960278046783 0.762423532914836 0.241148169729859 0.891179780215025 0.77791116266977 0.536374678339343 0.218165689865127 0.0509202535753138 0.734576893153135 0.889881253826898 0.756229694469366 0.853042291230522 0.103030149757396 0.827166139192414 0.570169388500508 0.364768035947345 0.734180255795363 0.313851941104513 0.482062537933234 0.78067062554881 0.160322239131201 0.096433463068679 0.389912470532581 0.696262872801162 0.746806257350836 0.551461634640582 0.398531124184374 0.145072132584173 0.522073491597548 0.051752185607329 0.414052856299095 0.326876169561874 0.925981455971487 0.868635589941405 0.0346811539307237 0.986440254452173 0.896913991007023 0.282082143495791 0.606263638613746 0.390417661352549 0.912939172727056 0.542981095453724 0.619128589495085 0.332471222635359 0.548507661672775 0.661561330026016 0.491611688951962 0.998762373942882 0.244858461434487 0.634956885338761 0.689506348876748 0.772792117206845 0.238253230946139 0.60695067526307 0.837636863219086 0.149094967017882 0.483953453022987 0.738348985300399 0.29415431109257 0.131326993545517 0.331804340649396 0.0311089660879225 0.747593566665892 0.212394080760423 0.496014046175405 0.994745701528154 0.593192984911147 0.87485922772903 0.167021151992958 0.408514708490111 0.426014312470797 0.690233069499955 0.777769616947044 0.44112066531321 0.719410932406317 0.143319487317931 0.661356220978778 0.505794175749179 0.456296786833555 0.353086115492042 0.59161266826326 0.129439955735579 0.612701135086827 0.144504588576965 0.760616649757139 0.280318554900587 0.643774679410271 0.393826071291696 0.195846365916077 0.388166573913768 0.04933978341287 0.310897004406434 0.0495753904548474 0.295256232125685 0.208558036892209 0.402455526744016 0.18614197019022 0.147973769996315 0.448961876763497 0.511847148914821 0.0760074313799851 0.583927246658131 0.579054568777792 0.102814746245276 0.800520827593282 0.68492952696979 0.808636728217825 0.793587465272285 0.262978710476309 0.931272368356586 0.423578967917711 0.189629848576151 0.554391805706546 0.126680489860009 0.461286445802543 0.384608734841459 0.785658298509661 0.460852903868072 0.69322933457559 0.452050828442443 0.989791002848651 0.110807582824491 0.603578151080292 0.899473301330581 0.787851124408189 0.0348855087743141 0.729897766932845 0.989176657877397 0.811992185777053 0.285534015111625 0.50034677002579 0.860910778944381 0.617618053972255 0.535039210724644 0.635741348410957 0.0358855922613293 0.529183691162616 0.153588107356336 0.469374820990488 0.362659501296002 0.537413482300471 0.577162186771166 0.144352472247556 0.751669782444369 0.588417886507232 0.80706388537772 0.0126693599764258 0.828587559284642 0.108944189944305 0.618978816221934 0.802065198093187 0.627965615068097 0.120485448653344 0.0714502812339924 0.248830987811089 0.213845742528792 0.821461279646028 0.157593072326854 0.507357612480409 0.256630946027581 0.404778459686786 0.983442328607198 0.234903709052596 0.900300733265467 0.753115253611468 0.83225206146948 0.0116993736405857 0.0353447683155537 0.566216966076754 0.987725008786656 0.945416393994819 0.343612741194665 0.32385242837714 0.760465066810138 0.260323127163574 0.611804449877236 0.119761435510591 0.49388567334041 0.0188171505089849 0.228468151334673 0.658302492361981 0.710435281805694 0.736516845540609 0.307642336990684 0.686766228831839 0.832854599189013 0.150513756386936 0.662457733561751 0.230802401020192 0.954830306065269 0.701918657247443 0.697190408674069 0.398202088782564 0.576794454867486 0.780640554213896 0.100572835796047 0.658615575619042 0.957890232889913 0.823642974817194 0.794365616498981 0.0700603191787377 0.623192033830564 0.518406537789851 0.416163574960083 0.982830524693709 0.0373830728232861 0.51486440814333 0.812336479972582 0.916217306433246 0.257422165814787 0.799058960333932 0.333734362996183 0.570608606324531 0.110531335915439 0.167912356548477 0.28803529554978 0.366741659885738 0.948817688096315 0.680323088739533 0.794153555501252 0.624524885935243 0.522496502802242 0.739412015287671 0.806537226953078 0.257254683738574 0.704223065178376 0.936937545542605 0.328860357883386 0.517239541106392 0.882707362317015 0.903837102658581 0.528184225652367 0.684898619141895 0.102063640779816 0.586583276453894 0.454781190170907 0.486986811687239 0.276181671367958 0.854933358221315 0.377367059739772 0.932054167052265 0.0352388914464973 0.493549724020995 0.943013697331771 0.837188600713853 0.771486321927514 0.643788931600284 0.199499748668168 0.89546248667175 0.472014856229071 0.10274957286194 0.384500481723808 0.575188603170682 0.0856609794427641 0.45513523853384 0.60954842392588 0.0765012648887932 0.246842972459272 0.472444255345035 0.870814154660329 0.489903622607235 0.0281433156412095 0.123221097413916 0.394526190101169 0.553626864799298 0.027621410866268 0.332374892020598 0.718803087139968 0.275609948353376 0.444334343881346 0.179576901276596 0.686462714418303 0.209194113854319 0.525786763236392 0.668654614868574 0.368034553257748 0.93475703884149 0.182314128747676 0.370682606059127 0.836823180979118 0.213761293387506 0.797973484951071 0.0783405649731867 0.63006307246862 0.0657434972235933 0.729010664627422 0.506100587346591 0.744866932390723 0.83540005378658 0.496001126749907 0.145657316243742 0.594771684585139 0.688278939605225 0.607308457533363 0.0269067309936509 0.127588871449698 0.764815147717018 0.287136491793208 0.331315614380874 0.759486882428173 0.172299104614649 0.498103098999709 0.472972413648386 0.939050080331508 0.531954790721647 0.331783568931278 0.0612717963685282 0.48009152535582 0.31254365939647 0.517074897896964 0.222642210524064 0.689844853314571 0.467876757718623 0.677521322227549 0.492463587787934 0.71819797885837 0.860245401447173 0.496200174507685 0.690727598434314 0.537011205242015 0.0722557214018889 0.906049394479487 0.322479840666056 0.0563413274032064 0.420240740177687 0.0638457309128717 0.681640842480119 0.502789180858526 0.953230736479163 0.780723657682538 0.872258722949773 0.175116461152211 0.274184794123285 0.764685138405766 0.0730179926310666 0.185389080175664 0.892324085556902 0.185349755554926 0.811715587121435 0.319391170891468 0.860879154023714 0.121650859250221 0.456070267576724 0.442000211521517 0.545614539477974 0.579402774367481 0.175027668424882 0.881183264036663 0.620773253405932 0.161474125694949 0.89160732332617 0.132394291514065 0.216847107699141 0.625670010482427 0.508342075285036 0.0842577141756192 0.621787796304561 0.737325530720409 0.792760607518721 0.949325937451795 0.74554809537949 0.211124694708269 0.416183186329436 0.253836630964652 0.956569293837529 0.6233691831748 0.261751806235407 0.419680404670071 0.611909009425435 0.831605198381003 0.201265065339394 0.954038402377628 0.263664991077967 0.133085897872224 0.209660889385268 0.307015077203978 0.0658427577535622 0.74895911206957 0.613044837813359 0.343674705524463 0.133352031721734 0.216731255841441 0.805203172548208 0.123788980029058 0.139317503664643 0.571838138983585 0.617481499547139 0.712111971941777 0.614227732243016 0.969160745858681 0.934025329456199 0.584779173845891 0.479933531447314 0.589204852143303 0.670349057142157 0.790706404803786 0.587613157208543 0.737739160018973 0.797074115772266 0.711289751664735 0.56366513670655 0.308151092759799 0.838059135202784 0.806412859647535 0.236934412515257 0.253166208693292 0.327188104456291 0.4103392345272 0.632095501010772 0.832490456898231 0.970572709362023 0.569867421449162 0.421085853946861 0.542784251759294 0.976788410032168 0.597099929223768 0.0941464363969862 0.794780926620588 0.652844273082446 0.846068744976074 0.988779488981236 0.44098637880059 0.257241950328462 0.688321552341804 0.803823951440863 0.812987163637299 0.756877106153406 0.115195019401144 0.0444061955204234 0.410564267965965 0.743507697219029 0.116135640661232 0.398767997836694 0.790479404949583 0.63311471757479 0.759397596656345 0.371394122287165 0.306686527009588 0.123481942387298 0.0231789729744196 0.486313690925017 0.391802057006862 0.878023282140493 0.988611695726868 0.309421585223172 0.578597460284363 0.29477845079964 0.405368922771886 0.054784225106705 0.969877613198478 0.787295492070261 0.476342275529169 0.753484703218564 0.63627676661592 0.507513612313196 0.831823009259533 0.254231617925689 0.394388378746808 0.234320014899131 0.202163797640242 0.366710763813462 0.562762344798539 0.334657871532254 0.955505997159053 0.503870086763054 0.281416741104331 0.6927746166219 0.879457018664107 0.794338000244461 0.748564124647528 0.667266403248068 0.69462122224737 0.15472999611171 0.908079233558383 0.596703269276768 0.317395364560653 0.104662471881602 0.12080213212641 0.499831696648616 0.797143329400569 0.841301878963131 0.580328221428208 0.311742622745223 0.296905338969082 0.228281008331105 0.117634904850274 0.863343094466254 0.207157383908052 0.928527237882372 0.0466179781616665 0.571386464582756 0.239183827890083 0.0481236339500174 0.163375058185775 0.0365219995332882 0.954684475765098 0.722655524795409 0.919684864194132 0.871131847503129 0.334920553609263 0.354008451693226 0.334301585683133 0.0187371030403301 0.693615003940649 0.54477699194802 0.708111386976671 0.709410378749017 0.135656463855412 0.130486326396931 0.610747143262997 0.480047560262028 0.111924752509221 0.700832067385782 0.247309069621842 0.144353607702069 0.269799952080939 0.624066542410292 0.481334581125993 0.899792121560313 0.349063024509232 0.575844691884704 0.491826797882095 0.945706321217585 0.0990989674325101 0.799292352939956 0.175261771208607 0.0143109399965033 0.484777602374088 0.442648248097394 0.847165559460409 0.390994592797942 0.469837491505314 0.247946617649868 0.785320444088429 0.552059364772867 0.031214241576381 0.639020714382641 0.642466429742053 0.773737913705409 0.978515341610182 0.556361775030382 0.125624731990974 0.724450109500904 0.174086884199642 0.0959282591100782 0.843172478959896 0.397020104145631 0.744727563762572 0.703537805932574 0.821169245401397 0.891355608319864 0.883773110618349 0.0676810385566205 0.478733378616162 0.768395207906142 0.498559953479562 0.83225893343566 0.773345697382465 0.251670610874426 0.789126051045023 0.789818967578467 0.970559436806943 0.776670370893553 0.341924637504853 0.0657262996747158 0.279208066787105 0.550729787875898 0.341185567257926 0.403315786360763 0.0464633839321323 0.595382055465598 0.202003254375886 0.793945154880639 0.248684660547879 0.957192792287096 0.42710423101671 0.394288979915436 0.564097773919348 0.771912806802429 0.97467149685137 0.791994282675441 0.542534416960552 0.308485753110144 0.592763865394518 0.29137687318027 0.699321063021198 0.969416232574731 0.300803196879569 0.0357003059540875 0.306477924238425 0.993304935144261 0.760874319560826 0.542358251400292 0.0489075940661132 0.173250974158291 0.660892499373294 0.267816859567538 0.467620144076645 0.372266691420227 0.947885161847807 0.168824416955467 0.056361838884186 0.920442426721565 0.150978200386744 0.0825504744122736 0.0983731522224843 0.381818553376943 0.757111926260404 0.0329552967241034 0.571609307788312 0.0198017156566493 0.106528170937672 0.461350693718996 0.226645925249904 0.116375835852232 0.392338486195076 0.515636067271698 0.110575765932444 0.521728439279832 0.628014066428877 0.951510038375854 0.993773231760133 0.592350950883701 0.986589539060369 0.257631845953874 0.560414530050475 0.608549557260703 0.969879643232562 0.225800529806875 0.535391078996472 0.600752307216171 0.497980908097234 0.619839140379336 0.538824435973074 0.875455230937805 0.0123510067444295 0.154203121014871 0.560851012733765 0.437758626912255 0.284916096893139 0.300905819977634 0.412780432226136 0.418336767361034 0.472312326640822 0.106916588582098 0.894763084955048 0.0342468979000114 0.365831121716183 0.113036641615909 0.342882684741635 0.687638292012271 0.863553609715309 0.793489533127286 0.550394255074207 0.821271724204998 0.897815518148709 0.803970761836972 0.0302367747481912 0.869666891512461 0.477041756308172 0.150679016420618 0.313235863447189 0.725359206569847 0.22411947741406 0.50103150049923 0.827335430250969 0.207144681846257 0.567883601239882 0.314857601134572 0.604430177153554 0.530749448360875 0.72942498474149 0.65939491254976 0.874701846034732 0.310245882095769 0.797439350183122 0.395436032845173 0.420507190506905 0.776307305740193 0.137137897766661 0.671438343420159 0.477737238332629 0.458332348132972 0.136590452871751 0.833430618536659 0.413826610648539 0.343856146130711 0.277195161792915 0.164112517221365 0.0972412880137563 0.348083098912612 0.0333440854772925 0.820964963396545 0.381691520081367 0.192148764748126 0.749016187444795 0.840249109326396 0.336022302226629 0.411622097129002 0.379402426956221 0.0513095199293457 0.499672191566788 0.0977565879747272 0.830155374638271 0.384623616072349 0.688301717615686 0.334854161099065 0.458006874914281 0.0719310692325234 0.0763416298036464 0.103616517968476 0.486797689360101 0.491357961660251 0.118079720193055 0.506746682401281 0.103765748639125 0.463254668149166 0.55016222312348 0.788457487544511 0.263755178344436 0.102837752914056 0.897447150289081 0.976489352611825 0.357863220188301 0.0754680291726254 0.237415970391594 0.677313291332684 0.412201127528679 0.557705007346813 0.497951705756132 0.166801715381444 0.488352462660987 0.730413370465394 0.946491236535367 0.153615916771814 0.522163012251258 0.213540194393136 0.996469174879603 0.478604336031713 0.287179828076623 0.24181012541987 0.696498703660909 0.553521373791155 0.0514522564271465 0.304377743913792 0.869970744072925 0.0569069427973591 0.54400576754706 0.838335375196766 0.249456236695405 0.0375623992620967 0.49729034084361 0.840646166659426 0.873067675051279 0.369347254156601 0.0435166722489521 0.847205155382398 0.0538017188059166 0.859223593345378 0.366658154190518 0.0116718350653537 0.942397194397636 0.21355231651105 0.101413525764365 0.353119036757853 0.233583850825671 0.821341013207566 0.931831923383288 0.637142113880254 0.823688617276493 0.79991557985777 0.461175392081495 0.731918378542177 0.0537550614448264 0.23886532506207 0.287815308729187 0.590843987225089 0.924604777765926 0.20772739544278 0.334499051272869 0.083436801538337 0.982452752799727 0.603051054009702 0.982963492502458 0.770626383400522 0.987939126326237 0.248844183839392 0.751171152642928 0.753485649430659 0.114444709399249 0.711494812997989 0.392122260250617 0.172854204261675 0.55995093153324 0.670137871131301 0.926916105377022 0.311024808271322 0.753912742140237 0.50817861570511 0.418895226118621 0.143986137418542 0.595133542367257 0.851606192979962 0.734337453779299 0.287216752246022 0.573007245224435 0.947998016483616 0.26163416567957 0.452447652046103 0.629545253117103 0.891473174192943 0.622585787328426 0.0809891573805362 0.576428806474432 0.345063088177703 0.519328451249748 0.590091565360781 0.313461039566901 0.0412492638616823 0.108961636896711 0.586686448839027 0.62425774571253 0.214433557603043 0.938819104081485 0.151442042314447 0.0512989659188315 0.921084017069079 0.19039126095362 0.704133411294315 0.683599167978391 0.396779370040167 0.597664802400395 0.579590756860562 0.659993956314865 0.0219232875201851 0.659109873820562 0.301266109421849 0.313609699052759 0.774050713675097 0.252419928563759 0.195114968861453 0.887346836833749 0.658554151586723 0.991410529788118 0.0552242598310113 0.950586306252517 0.812502960746642 0.249726062500849 0.0140197247266769 0.402631790498272 0.369243586191442 0.667587582208216 0.766657835955266 0.179397611257155 0.203517750850879 0.868433224102482 0.832003656246234 0.021721740195062 0.409511811351404 0.175623214086518 0.616864612826612 0.33037649461301 0.939722577123903 0.706638639776502 0.725923800838646 0.507580625796691 0.704183005485684 0.776581806133036 0.232904382490087 0.03883876377251 0.89350873549236 0.780243282052688 0.0498588297283277 0.481164502671454 0.346839315907564 0.877738654857967 0.325815631074365 0.994131793128327 0.97099747054046 0.751397785537411 0.835460942592472 0.788339980219025 0.712407705518417 0.33273294536164 0.504862619224004 0.573478754120879 0.526178848173004 0.543329675609712 0.609600056218915 0.271256566653028 0.739943448798731 0.41207908714423 0.314150134832598 0.119188113501295 0.190809444286861 0.815318793663755 0.483268041184638 0.236090523635503 0.227902071939316 0.63685305173276 0.624057580940425 0.551140405891929 0.832389809666201 0.603734893361107 0.700420777455438 0.528661613971926 0.0445319490670227 0.625124805839732 0.509601267832331 0.574452777935658 0.666680165731814 0.775203385329805 0.0641559310466982 0.631165850970428 0.474134278658312 0.654538383202162 0.318867088791449 0.315006485129707 0.704396711117588 0.316463513914496 0.115781010740902 0.260604184425902 0.496447947924025 0.606116969976574 0.951555754134897 0.858437726974953 0.507209725177381 0.514338278260548 0.822652021988761 0.29397809228627 0.160588894838002 0.70827495835023 0.976224855789915 0.459075804839376 0.290746729348321 0.0514922522706911 0.0779991430672817 0.51283811903093 0.321561955926009 0.716773034615908 0.823053123946302 0.326715316963382 0.560624554329552 0.540113636697643 0.621478824978694 0.433165031350218 0.48130865491461 0.536168072179426 0.082425334462896 0.423754075702745 0.974608989688568 0.29263590045739 0.532409124427941 0.858456863048486 0.253572284199763 0.278529397833627 0.946332886961754 0.760857853856869 0.834814598595258 0.844487942890264 0.36196524070343 0.517114800387062 0.844334985457826 0.53753616071539 0.061678823849652 0.274364501582459 0.374772117903922 0.180165076625999 0.494958582427353 0.861938231126405 0.607352277871687 0.989977739707101 0.858648939954583 0.211758214707952 0.446869907854125 0.910634019121062 0.811652909617405 0.710995311206207 0.131698069346603 0.182141027024481 0.424742649516556 0.692015022677369 0.70925196163822 0.654807529025711 0.274376202803105 0.422838245199528 0.163931910572574 0.922850580757949 0.555696019278839 0.987320564545225 0.518475247309543 0.165128303680103 0.266793672370259 0.563788714541588 0.960469603140373 0.95157502228627 0.489701627646573 0.261472651769873 0.504929554567207 0.617951377409045 0.169404650577344 0.169566519691143 0.614738080552779 0.279683156998362 0.85285898724338 0.623636232579593 0.136145091007929 0.0423293332732283 0.788737706469838 0.482816845767666 0.247767285217997 0.371408604288008 0.823875911259092 0.607131789478008 0.360686877737753 0.0809175956249237 0.0558563885185868 0.479172322833911 0.885394831248559 0.361726230755448 0.233190137851052 0.0264066642406397 0.0347799310972914 0.836849304961506 0.70657274883939 0.939658741115127 0.409093574311119 0.602928898143582 0.969656570446678 0.928686466130894 0.269384921097662 0.95975660224678 0.489243230414577 0.330489901301917 0.60959720951505 0.306099773629103 0.958361381050199 0.527932893049438 0.917867199981119 0.424182009976357 0.299381667990237 0.398295066510327 0.605953575398307 0.225177953597158 0.12853004545439 0.977877499691676 0.418707581541967 0.825975594851188 0.850355065017939 0.907981549203396 0.283043247654568 0.929178679669276 0.541820009541698 0.430182527955622 0.0846857321215793 0.91947189248167 0.956102165407501 0.259934280784801 0.544460228951648 0.704085852438584 0.648557077362202 0.823903540652245 0.30480511368718 0.0535032685287297 0.352349607509095 0.884839369251858 0.148764845719561 0.600852437200956 0.124343247562647 0.142811407842673 0.207995906462893 0.144331410557497 0.291514165443368 0.593847017313819 0.808198859754484 0.36641340773087 0.729338986624498 0.128563210822176 0.0830440391553566 0.820323750150856 0.877447912117932 0.72560453735292 0.992222024330404 0.885519829669502 0.493345488116611 0.786484371863771 0.660878124556039 0.138232412529178 0.401384965323377 0.319680047254078 0.262427290568594 0.234557348634116 0.574797141742893 0.320783200322185 0.219623887988273 0.173006899151951 0.74520631596446 0.621505539738573 0.857838780481834 0.664782671644352 0.140880035904702 0.285894035790116 0.0612574257003143 0.721638489014003 0.865973255445715 0.825821768655442 0.547838346043136 0.193529296030756 0.817142255471554 0.815275574936531 0.889871968270745 0.107398662553169 0.874339165128768 0.802919405871071 0.667177011445165 0.829285184750333 0.905122648077086 0.576903330110945 0.0926074933051132 0.500396657877136 0.966004297793843 0.760962174835149 0.101350666393992 0.560969003653154 0.398490090619307 0.513496892175172 0.82863964658929 0.367834395631216 0.81088759714039 0.465780489940662 0.580245448960923 0.670965714743361 0.842713320839684 0.671680836258456 0.569981683301739 0.543913566612173 0.39931375683751 0.70275075915968 0.605358153746929 0.832855384049471 0.165052329648752 0.446169974368531 0.186808802157175 0.466649966423865 0.070318122212775 0.445340713167097 0.812144487199839 0.806312702693976 0.258188904870767 0.0983652526768856 0.404370064404793 0.599029984993394 0.760171898724511 0.951840934162028 0.304592686882243 0.156723032495938 0.963295353651047 0.0186898631998338 0.242670991027262 0.251394974335562 0.0957937646843493 0.488844930904452 0.407780603724532 0.414445969737135 0.748092531848233 0.372832488680724 0.125139983270783 0.390890133057255 0.760524402952287 0.110147960048635 0.159046398783103 0.551214630871546 0.22863394636428 0.594319630777463 0.328320018453524 0.84434371780837 0.348781762099825 0.846083331163973 0.952650440621655 0.449600348183885 0.288395850763191 0.393784995775204 0.0427897586952895 0.392832527155988 0.406414957591333 0.829719213505741 0.723212449098937 0.59917326040566 0.26145230763359 0.393743762825616 0.998648973016534 0.846698445091024 0.164171477644704 0.790525443872903 0.243292770159896 0.986901304996572 0.326607002301607 0.328899248007219 0.763990048926789 0.979469847178552 0.753346773386002 0.134055534305517 0.427442050632089 0.467830444728024 0.762445565711241 0.456412999657914 0.0402415717230178 0.0477409452106804 0.321484572603367 0.0579706907994114 0.339725854734425 0.279782156830188 0.0690083816554397 0.252892011641525 0.881448532580398 0.238625810544472 0.977843026223127 0.0821531877294183 0.898152299351059 0.2411152634467 0.984810318488162 0.467989579392597 0.871723367210943 0.923444542177022 0.377636477095075 0.947725339133758 0.490110392884817 0.817839310213458 0.995783387091942 0.506039418710861 0.181304047221784 0.853740034021903 0.914003628832288 0.956448351796717 0.476345953424461 0.061126859264914 0.651423586679157 0.306206068398897 0.306442459148821 0.887583375335671 0.663773055963684 0.549041359638795 0.38140814327402 0.202627906028647 0.646257231994532 0.431734743372072 0.529944826015271 0.655987406410277 0.452615967388265 0.861396821013186 0.882614936872851 0.614772931814659 0.507639258676209 0.294603999485262 0.951962389070541 0.363485320636537 0.362623458337039 0.534328809897415 0.735544785836246 0.883389047393575 0.153187076163013 0.554906772591639 0.80044049337972 0.762986910592299 0.905171089526266 0.164615706359036 0.579998150840402 0.419958614537027 0.241629996371921 0.313891073947307 0.788028043941595 0.506504136086442 0.533032904551365 0.481052209539339 0.122214339962229 0.0970199444564059 0.0188950826576911 0.412982836097945 0.501977339410223 0.612551013755146 0.80613606713945 0.898557026879862 0.111327686454169 0.298273407912347 0.494793785933871 0.182995465765707 0.564193547179457 0.963462966652587 0.814646230486687 0.13182847373886 0.255466619252693 0.87875284508802 0.163782516245265 0.100115644091275 0.894578174366616 0.327170070414431 0.978560600052588 0.0117528169904836 0.927699551703408 0.115017947275192 0.10441794993123 0.844643249833025 0.730860596632119 0.376906131361611 0.0444722750084475 0.0761333511187695 0.0625528891733848 0.143826205215883 0.471505097774789 0.450197564295959 0.964963454578537 0.880865629971959 0.212698923558928 0.325293206977658 0.104629639128689 0.986389958381187 0.405823879064992 0.128038558689877 0.325657947191503 0.118423031065613 0.352477829735726 0.851361262579449 0.444129782277159 0.0355778151680715 0.415373427700251 0.830851935413666 0.769692393001169 0.396885129353031 0.980767005074304 0.979332861944567 0.448100167748053 0.13354364416562 0.794028965069447 0.629084689854644 0.779305502194911 0.83678125974955 0.949472080082633 0.973009053834248 0.644792077771854 0.098720153667964 0.443035279270262 0.214025612953119 0.67026197474217 0.622601429678034 0.453358152182773 0.875787720186636 0.838364488794468 0.487897926343139 0.700062990575097 0.923807196344715 0.767737253506202 0.0112517438642681 0.784230694039725 0.768867833125405 0.201887700557709 0.119622765304521 0.731714266878553 0.736793370665982 0.121513756921049 0.415631283980329 0.559054917315952 0.210934227399994 0.810202443464659 0.303312121697236 0.283280226415955 0.972821566229686 0.522967610394117 0.0992039946699515 0.962631797583308 0.869032853804529 0.160464547586162 0.951892984816805 0.314059711531736 0.5783724367572 0.180445972075686 0.886493924940005 0.108589896787889 0.738623047047295 0.393701103297062 0.659059863572475 0.746181516724173 0.0539891994954087 0.985794215179049 0.435788058051839 0.399339990769513 0.512620715911035 0.823122326740995 0.756698645942379 0.0214223303366452 0.80378251680173 0.456976563350763 0.782517643773463 0.857991356432904 0.453350215295795 0.190794740312267 0.0290109190624207 0.588932152895723 0.524916272773407 0.594576557441615 0.632540542476345 0.318928089390975 0.556967130640987 0.188092761258595 0.220247127353214 0.539561924051959 0.0218602896179073 0.118058011713438 0.0720661913161166 0.629675792353228 0.231234232627321 0.746837590686046 0.513426197799854 0.419373006522655 0.101599385330919 0.539972064236645 0.93383808180457 0.583804332439322 0.991809875087347 0.402063453102019 0.719063576448243 0.386224064102862 0.111744734332897 0.290996214936022 0.0211245445976965 0.856819231302943 0.265304337069392 0.799016672605649 0.849298193822615 0.573320364670362 0.684022737690248 0.875671208631247 0.696575283452403 0.969787575758528 0.795957131872419 0.842255832478404 0.895253572952934 0.490435167450923 0.688133662510663 0.867486461568624 0.408269391767681 0.781545109003782 0.51838773917174 0.670407335739583 0.477013795452658 0.17169322991278 0.637085773807485 0.539195169247687 0.921145515092649 0.310474066040479 0.394485329182353 0.645848850773182 0.917780541474931 0.335508571295068 0.504888566872105 0.322039752695709 0.643956513023004 0.157429859614931 0.846954189047683 0.106184202211443 0.488738076474983 0.118747584579978 0.877814538993407 0.627249220719095 0.507637309778947 0.386513281147927 0.285606480205897 0.571591639784165 0.494546518009156 0.515866676562 0.676829214526806 0.726624825061299 0.719122618930414 0.380660848242696 0.310057345936075 0.305200070452411 0.23455410131719 0.404410529090092 0.0417233352526091 0.314937088021543 0.511782784364186 0.105332334723789 0.775012405845337 0.584306329649407 0.120440513375215 0.385021512664389 0.772693295783829 0.67544386390131 0.50122973781079 0.219850125571247 0.890558895200957 0.273882151700091 0.902896615089849 0.863490058607422 0.70345146344509 0.426361136429477 0.15492935182061 0.546339279164095 0.742030444159173 0.918808926730417 0.370218956370372 0.52885838505812 0.521844563360792 0.157814058605582 0.435111827352084 0.498565604013857 0.447908435212448 0.566668273748364 0.75384601932019 0.344441312272102 0.912921203686856 0.339884316562675 0.813712862904649 0.405064513087273 0.0119441214832477 0.372573683653027 0.751017021031585 0.739940564753488 0.0695267253997736 0.615105208079331 0.182255505088251 0.291852189744823 0.806238833840471 0.734363864737097 0.570343434591778 0.48779272668995 0.504598529469222 0.78949471463915 0.231110571580939 0.780820240466855 0.301250850858632 0.738543104457203 0.201567644374445 0.996462818086147 0.87061104360735 0.954691947498359 0.931206975074019 0.109659152182285 0.680459607436787 0.472959919730201 0.545769342773128 0.477601033118553 0.491773123338353 0.940879598818719 0.354267927021719 0.474469696900342 0.125499444981106 0.356266646671575 0.546558730297256 0.493195804739371 0.872183718641754 0.905811507538892 0.751577483776491 0.66443018355174 0.0317215799866244 0.05648708302062 0.617840707474388 0.366102146825288 0.282648025350645 0.731741762349848 0.569793396315072 0.343993724216707 0.205075372469146 0.448686547484249 0.295516845213715 0.18026777832536 0.198945569877978 0.992421601091046 0.652003529176582 0.740591252797749 0.562630042450037 0.934107676185667 0.830237813568674 0.770020473662298 0.109526426631492 0.427063469674904 0.578387929049786 0.847255756868981 0.360024338415824 0.558259694625158 0.536916197941173 0.327929022640456 0.477731641966384 0.478062628109474 0.723752769166604 0.2324237270304 0.874982923811767 0.15057260686066 0.876195872519165 0.572967690101359 0.15763972138986 0.699447631854564 0.265246027584653 0.784525583286304 0.551061638402753 0.610376999382861 0.528930726603139 0.544706264610868 0.926612286008894 0.20721330861561 0.10076086784713 0.773197262175381 0.68824944014661 0.385683938579168 0.997385582330171 0.0517917273612693 0.89973277712008 0.50745409199968 0.0761652726959437 0.648605442284606 0.305833635630552 0.795583196228836 0.29728514112765 0.572447548669297 0.990226102287415 0.602925748329144 0.470342087629251 0.983471958069131 0.66165381470928 0.726708292954136 0.274088212952483 0.814422802727204 0.429648330260534 0.509739851600025 0.894345207037404 0.216641893542837 0.794532562887762 0.660876785798464 0.54593423792161 0.0434607590665109 0.373528326370288 0.222873269063421 0.788519943535794 0.601612324574962 0.920882969934028 0.380020391505677 0.5066182481125 0.277190925620962 0.490712068064604 0.796996524075512 0.330375939102378 0.803608540091664 0.954101488792803 0.144007494612597 0.504292098048609 0.708276233489159 0.334211769064423 0.904062013470102 0.788126739510335 0.735945251837838 0.211099555431865 0.688939075018279 0.712113659218885 0.402982640410773 0.383994959441479 0.1609129585349 0.144845012177248 0.287820353042334 0.949859044870827 0.650686487688217 0.671120813542511 0.444102618037723 0.649330242131837 0.426200931081548 0.189502224733587 0.663221501673106 0.926499752693344 0.731971718627028 0.513287445534952 0.34949246534612 0.0886419428512454 0.309707171395421 0.130716889125761 0.696928658287507 0.585638156018686 0.895598112172447 0.70312003450701 0.521196776649449 0.718228929329198 0.955357525993604 0.0958770843641832 0.942034085679334 0.496118911139201 0.650340236297343 0.319548681897577 0.939534121640027 0.991486224681139 0.201570377210155 0.103619330788497 0.877074498562142 0.885299389220308 0.22813140032813 0.291212231814861 0.360030273620505 0.702665078213904 0.631038923014421 0.578565301981289 0.576200995713007 0.610971352194902 0.204398317723535 0.515257556848228 0.866631431588903 0.668717288684566 0.787747285871301 0.290230601192452 0.790271538633388 0.860709594429936 0.438667097245343 0.365729014712852 0.228730282972101 0.428032284367364 0.803552119343076 0.729984582641628 0.587593538002111 0.990125764620025 0.759752966028173 0.783096350086853 0.867045655814 0.328183994414285 0.677040100193117 0.987741872798651 0.578994152040686 0.529124097549357 0.2616163277952 0.193518901758362 0.42125853408128 0.812307188657578 0.4637474489538 0.0320448957034387 0.440299093208741 0.61749977446394 0.123258089351002 0.933168254920747 0.179100002313498 0.739904957904946 0.259339704154991 0.495808999824803 0.0946591683314182 0.80419897713 0.635723197734915 0.837999117234722 0.621640298780985 0.911173374997452 0.4099068633141 0.73983619467821 0.756967687117867 0.535616181124933 0.860600418841932 0.817453892095946 0.94804369490128 0.892679185010493 0.761383894996252 0.157498898752965 0.619877095585689 0.906743558030575 0.673242890206166 0.517904047535267 0.512905416262802 0.383506915229373 0.959972103722393 0.862104336412158 0.0449151721107773 0.175002182472963 0.78643931603292 0.43715679614339 0.244312590640038 0.487774535675999 0.668264379713219 0.155955732627772 0.819587527760305 0.354012250141241 0.740058788941242 0.540154296387918 0.467685806124937 0.85233780255774 0.919676129308064 0.257335774460807 0.899811059862841 0.156095717388671 0.1952327288175 0.869835028445814 0.457395702577196 0.196630829449277 0.309217731491663 0.272073238738813 0.093729511606507 0.947114165183157 0.924038192417938 0.185093097195495 0.325082385852002 0.388917516414076 0.498708438014146 0.744516752548516 0.591894670124166 0.116775259522256 0.151091850486118 0.938065060863737 0.71264183273539 0.0328717951779254 0.0768713529873639 0.980025591079611 0.37805851604091 0.426263778926805 0.880009798996616 0.156343814660795 0.460060018009972 0.333777740309015 0.405013991815504 0.574848733698018 0.0609162352187559 0.58285833194619 0.114157530225348 0.692575481964741 0.29517423391575 0.261176013471559 0.014831451845821 0.119769901630934 0.517044932362623 0.543362326957285 0.144477798903827 0.744830709178932 0.78698574810056 0.691741165847052 0.766707490538247 0.35243527646875 0.945396432031412 0.894002075956669 0.776628872866277 0.441886436028872 0.364784016904887 0.851567688025534 0.708260436702985 0.644753938855138 0.165169799632858 0.537117089026142 0.359418389492203 0.472853814433329 0.687259281629231 0.644712183817755 0.165073700211942 0.911119923118968 0.906696280618198 0.0144628684665076 0.910325124091469 0.638994950214401 0.0853863264573738 0.723086058213375 0.305678314627148 0.220382693614811 0.627172720220406 0.858871713087428 0.5783458284894 0.238500223651063 0.667934195948765 0.504082767581567 0.469199932413176 0.285150347889867 0.92120819674572 0.37599788161926 0.328694034772925 0.630437260512263 0.666906592096202 0.796128224767745 0.420567354152445 0.869471297601704 0.0214996548811905 0.875696080063935 0.329298609902617 0.648839588172268 0.320250858170912 0.137360444776714 0.9172261317214 0.676253167979885 0.873704625386745 0.185359565503895 0.413758535701782 0.436937393876724 0.375083504202776 0.247064580863807 0.39822644319851 0.564916772465222 0.33952954211738 0.984704431938007 0.653227100353688 0.0546430518757552 0.76628086943645 0.458226673644967 0.41431789111346 0.443408026674297 0.478290027885232 0.67341046517482 0.986243075607344 0.623548699778039 0.663824691714253 0.462766026705503 0.406079427555669 0.493036659932695 0.809939630001318 0.109257812115829 0.787976304925978 0.156019010129385 0.86171196680516 0.514562423804309 0.193612186976243 0.982363420927431 0.992151578206103 0.362454959284514 0.103850782795344 0.947801584235858 0.515711751100607 0.173547705118544 0.461090114284307 0.48527769978391 0.308473399337381 0.740561862136237 0.456277422101703 0.418405845453963 0.505200572300237 0.55141141486587 0.870320089957677 0.597424781469163 0.920375790570397 0.328445381990168 0.40530623074621 0.74707798157353 0.347691730146762 0.129161858584266 0.830235434554052 0.502755289177876 0.936208937105257 0.854590270014014 0.745849813949317 0.250833328422159 0.10948277617339 0.0921947002690285 0.898242592418101 0.555784891298972 0.891951627663802 0.453207076801918 0.850728600739967 0.756383987432346 0.654674386957195 0.390049312855117 0.861240531669464 0.727465066472068 0.07693252323661 0.312010698807426 0.865401919214055 0.788570530270226 0.713626206335612 0.120913151272107 0.313666989486665 0.230291678835638 0.856992321731523 0.92796480803052 0.57953090854222 0.886653760562185 0.541267132628709 0.0208169387676753 0.520307115998585 0.970617752284743 0.564271420089062 0.117414871007204 0.888071759769227 0.50614261529874 0.0563682019012049 0.38864451082889 0.680864662739914 0.926181435880717 0.49529467995977 0.758538117751014 0.0828462550113909 0.815957180489786 0.18839153977111 0.090932166359853 0.6942853759625 0.637996900219005 0.14364657681901 0.816193996055517 0.290160937854089 0.474912233266514 0.996264855763875 0.535423669952434 0.0734645616356283 0.568254590372089 0.246711746326182 0.446178266690113 0.341515679336153 0.461557830495294 0.574777461683843 0.663929497899953 0.370158192266244 0.612308616575319 0.296723753376864 0.148606859878637 0.621572270165198 0.353754221214913 0.0415531906438991 0.0211516267783009 0.492782657882199 0.96425069778692 0.132793311343994 0.596584997144528 0.383184425632935 0.967187884652521 0.909004965981003 0.225369615599047 0.582911324894521 0.291720072259195 0.518623675140552 0.0886566127114929 0.355056473212317 0.798010717532597 0.856593350998592 0.592301248356234 0.775890181104187 0.754683251292445 0.493151004305109 0.360966921942309 0.347620750640053 0.498241026527248 0.282318147001788 0.533201711555012 0.625503988177516 0.690534969936125 0.770242427359335 0.6028584932792 0.305744065188337 0.127222769428045 0.592519509636331 0.459611036567949 0.862308279348072 0.658420796073042 0.396266831266694 0.0928714207862504 0.387424892536364 0.493798087292816 0.351550102315377 0.927994128849823 0.485550473483745 0.454618271810468 0.563321472473908 0.98842285253806 0.936901921406388 0.0197828787751496 0.117567253566813 0.167207848282997 0.649211004886311 0.282635187292472 0.531768866844941 0.219375006086193 0.172139435876161 0.978255758637097 0.215164555197116 0.33897246867884 0.886451185196638 0.249731206621509 0.781904280050658 0.43423484363826 0.525705625952687 0.917342716115527 0.016028274379205 0.852681877776049 0.0548761754855514 0.997976475993637 0.0722043601796031 0.446432455217 0.73724586450262 0.0395913884788752 0.183205561039504 0.596766263721511 0.646095660228748 0.408286053398624 0.34109692965867 0.613433898559306 0.221706790549215 0.527732637689915 0.518566095887218 0.536384536002297 0.394991448696237 0.677621248909272 0.891150403153151 0.252832376998849 0.121742400717922 0.811115159650799 0.995574945441913 0.972065093517303 0.884925643971656 0.494343691857066 0.296500378402416 0.250418814686127 0.904542680224404 0.159521712581627 0.403787344354205 0.814523291373625 0.493178983831313 0.304517370704561 0.700366858118214 0.0483444176171906 0.776479844576679 0.1182414853503 0.753498548571952 0.164335406296887 0.0523973162402399 0.118213434829377 0.683937966306694 0.479078460899182 0.300080434903502 0.337143259525765 0.997733279201202 0.627187383165583 0.485962418040726 0.990716208342928 0.0906993387150578 0.345632533137687 0.53147207895061 0.762460344599094 0.310857613862026 0.49938934629783 0.94673949354561 0.991029250570573 0.733968792259693 0.250472224843688 0.652128483110573 0.867510109725408 0.289738411165308 0.065305916427169 0.528231710977852 0.538459370289929 0.83203696268145 0.0411719582183287 0.933050881747622 0.762218597435858 0.43799702280201 0.113993641680572 0.885462643422652 0.505587110198103 0.82859024555888 0.721478332071565 0.785051829803269 0.788832898633555 0.51076519330265 0.808537345982622 0.424709248114377 0.733616587684955 0.109862859083805 0.210415899329819 0.46802513806615 0.575966135037597 0.172441123789176 0.681914141955785 0.507875503287651 0.643060333535541 0.768648988443892 0.0825461312872358 0.301717174374498 0.627622858553659 0.0714227099274285 0.0830390667589381 0.530049252794124 0.281142700794153 0.238734859586693 0.477659069688525 0.854680909295566 0.224153901094105 0.488746505023446 0.687468737950549 0.634329185062088 0.171299223047681 0.30984281579731 0.928893108710181 0.0517057094210759 0.8552518089558 0.40594287382206 0.921666862973943 0.364589669781271 0.379960514144041 0.759878924030345 0.734817584385164 0.448822657961864 0.89877581393579 0.73956822741311 0.183644765263889 0.375637366974261 0.487568111151923 0.907719196053222 0.843260313258506 0.607331567006186 0.622428083161358 0.321268801440019 0.153800678686239 0.261951641619671 0.642072863136418 0.669391591001768 0.754852943655569 0.668888658413198 0.401214039081242 0.476590826890897 0.706577844554558 0.160064263450913 0.275609813279007 0.659558988262434 0.661615116132889 0.126305905582849 0.237860675093252 0.364307019747794 0.964943772444967 0.953346762366127 0.598227603822015 0.215715105650015 0.64807222399395 0.665274381304625 0.733365041636862 0.735440475922078 0.318975533917546 0.484939107755199 0.51349366606446 0.860389784192666 0.37738695854554 0.850418739905581 0.0591117707220837 0.651295743167866 0.099443075612653 0.509258650771808 0.357703149914742 0.237288781045936 0.0810421231295913 0.760755691071972 0.774574825970922 0.267923808963969 0.856596567197703 0.313174086285289 0.226614061989822 0.984826621918473 0.216291511319578 0.119826850229874 0.753792766595725 0.406084708594717 0.300646275267936 0.413613979388028 0.0249221941526048 0.0880992168001831 0.782655056589283 0.29891136392951 0.321070597090293 0.28454556415556 0.353216616003774 0.0148864782857709 0.109171414768789 0.151921200430952 0.915790887943003 0.667652637804858 0.614039250481874 0.71798886944307 0.237567617418244 0.609597795912996 0.811388312987983 0.469741747980006 0.807322375539225 0.489472756343894 0.0507204723590985 0.0447224428830668 0.362338621527888 0.953957644961774 0.0419832351664081 0.790494620408863 0.924498350457288 0.772793420697562 0.869027380065527 0.662761523886584 0.282088533481583 0.864149029061664 0.584446373418905 0.50263540790882 0.500790689405985 0.833827161388472 0.435478306706063 0.711421632424463 0.302277635505889 0.0316598904156126 0.632074638013728 0.21533445754787 0.308907602583058 0.60216684934916 0.809972156877629 0.0176473382394761 0.753907932478469 0.0208751535159536 0.407862585107796 0.614014204789419 0.014271024367772 0.447345043935347 0.999593254653737 0.341873851155397 0.740029695166741 0.136427023026627 0.360140740713105 0.555313006683718 0.437327217354905 0.216240677486639 0.531779985586181 0.747641949106474 0.906984074080829 0.41232977779815 0.433962778963614 0.780828636514489 0.476624666708522 0.695971331370529 0.186194470324554 0.0887208620109595 0.732517166910693 0.272760151147377 0.434751771867741 0.653163774677087 0.470408333078958 0.498981145329308 0.103671331885271 0.37966159802163 0.813428469120991 0.913960245526396 0.103578423769213 0.975476687385235 0.377910384635907 0.116231245424133 0.813836096138693 0.87121271809563 0.878469258062542 0.776644971841015 0.845976190220099 0.925817962277215 0.582451874497347 0.901069384568837 0.905686663324013 0.866654352280311 0.556786349271424 0.12543844438158 0.717629939040635 0.794582151316572 0.0491146787488833 0.95447868719697 0.310087977852672 0.929772867211141 0.535109470833559 0.678119851280935 0.175870446052868 0.220927369024139 0.2360269414098 0.584249188120011 0.322755189538002 0.414977971897461 0.671054142815992 0.619472625758499 0.0369505992671475 0.948719550112728 0.300265177455731 0.142468518328387 0.406217033071443 0.44400835525943 0.659990514914971 0.811358505578246 0.692816534854937 0.875712885989342 0.810761289927177 0.551063650688156 0.221168397020083 0.285583433660213 0.310933844211977 0.848081830453593 0.770351048589218 0.447532016597688 0.807068505105562 0.270364881039131 0.907183728751261 0.931171222317498 0.312022597568575 0.395739452061243 0.995636443004478 0.576384813028853 0.956406215277966 0.719966769660823 0.634344434635714 0.117430598873179 0.161062630617525 0.462501852586865 0.860624000844546 0.793119243800174 0.682063893100712 0.861977449946571 0.400547858052887 0.647490102557931 0.0693894324451685 0.642878678101115 0.402138286607806 0.998678228834178 0.552193437840324 0.461768303331919 0.806510928941425 0.149689476802014 0.754287710664794 0.280385366925038 0.636917659924366 0.968597063918132 0.331830408389214 0.279914129329845 0.305589667346794 0.897059000488371 0.823390140030533 0.526125566174742 0.746858488488942 0.316480577541515 0.652585355108604 0.380278041947167 0.130811695428565 0.113464546385221 0.124921802205499 0.527355735942256 0.928158512513619 0.677323215149809 0.613598077767529 0.944870746557135 0.769110922042746 0.856731930386741 0.228507691475097 0.602152164045256 0.263385418481194 0.297967931462918 0.423977127282415 0.890591325266287 0.610597936334088 0.932066697620321 0.963519559586421 0.566466761690099 0.645046113936696 0.899285970698111 0.0749537395033985 0.468505866825581 0.168045874566305 0.277146315351129 0.841724227243103 0.472962688063271 0.288834611962084 0.143047921219841 0.566466364765074 0.0830384497041814 0.363714623439591 0.820479926548433 0.188477442921139 0.905561857372522 0.446240487799514 0.121438823838253 0.768455136900302 0.108617520187981 0.823543824467342 0.441142530303914 0.922481135299895 0.339160356896464 0.641387912533246 0.740342119417619 0.371538416058756 0.756051516623702 0.188793097431771 0.980359561766963 0.84225508449832 0.0746075849235058 0.987134419616778 0.27341643325286 0.992694363265764 0.737326035059523 0.795796043700539 0.240369882276282 0.872346128283534 0.66329826194793 0.553189676778857 0.91852325988235 0.871580345812254 0.67574778907001 0.552325112991966 0.328121844299603 0.90748471086612 0.683615850354545 0.680952963575255 0.720411415584385 0.515023647455964 0.626457441272214 0.872630310235545 0.361117763824295 0.995206194026396 0.855629730676301 0.506519370677415 0.103626309016254 0.887211561235599 0.158177399439737 0.387259386326186 0.966340473466553 0.85429251032183 0.571656646514311 0.348228707700036 0.0759104712633416 0.411744317996781 0.968664231838193 0.66940004121745 0.606539725093171 0.962609924064018 0.712414138838649 0.184429226261564 0.356096623768099 0.408970465548336 0.87541877169162 0.931105844248086 0.124076028047129 0.0455445137945935 0.798879461709876 0.304558461434208 0.295297957658768 0.320563389374875 0.993919098940678 0.418594119993504 0.333089178195223 0.103659452025313 0.41229151026113 0.369083750338759 0.107748877892736 0.684271554821171 0.518951669593807 0.647191936490126 0.471330212655012 0.472065339698456 0.597740682847798 0.495732728214934 0.813910886079539 0.583451341851614 0.71184583832277 0.400359816781711 0.955531930516008 0.355106054726057 0.756631546481513 0.704455177343916 0.675555750657804 0.982535107135773 0.684484546817839 0.350416882291902 0.255554154820275 0.101045179571956 0.54129874325823 0.0920450676023029 0.13713967586169 0.401169653551187 0.856605362936389 0.415050629922189 0.875954980289098 0.283368698514532 0.0687968044821173 0.96554394129198 0.371602855522651 0.785547868527938 0.0993549096211791 0.225357052069157 0.663664810683113 0.0458953134575859 0.0173374550463632 0.709912774497643 0.778495386748109 0.529884531674907 0.76513033085037 0.882136756316759 0.247317921142094 0.268701355583034 0.287765118228272 0.343616548401769 0.0148479869309813 0.355824933890253 0.0527812711289153 0.0973428793833591 0.638698064356577 0.310149781752843 0.931431411972735 0.893816521575209 0.0150972122815438 0.71113132879138 0.483501641242765 0.727613896529656 0.581459290634375 0.18356416113209 0.908084806182887 0.648745411371347 0.846448228810914 0.883131742244586 0.091824604102876 0.176661061462946 0.167757327822037 0.157115536716301 0.426314560666215 0.143838157914579 0.160744020375423 0.0505064629251137 0.822668879316188 0.521424497284461 0.960050913162995 0.458170621469617 0.529717363081872 0.625863866866566 0.350648324848153 0.263210283727385 0.572800003800075 0.164173393810634 0.723683559917845 0.142606423266698 0.299535778395366 0.629204832743853 0.368745181360282 0.634287782693282 0.472562268623151 0.98275734688621 0.823505385667086 0.729348710826598 0.368633799864911 0.268026827373542 0.500513889521826 0.32119979042327 0.693939585115295 0.416710465727374 0.127884985355195 0.116441194559447 0.492461378423031 0.891601891999599 0.296445209051017 0.0414373270305805 0.891076945515815 0.21503294873517 0.378994246963412 0.0528822931577452 0.0244751433981583 0.355669270129874 0.873093154318631 0.698802143712528 0.636858156898525 0.649879798197653 0.539672233711462 0.631373017251026 0.0823707805527374 0.701867948346771 0.978303674079943 0.661107777261641 0.811087640668266 0.659369126483798 0.548275000450667 0.426487660084385 0.493576852993574 0.0209738732874393 0.757486489561852 0.869147873548791 0.572439387734048 0.663536358645652 0.235690176573116 0.547920671105385 0.766132576218806 0.508781946352683 0.337731288736686 0.103414184169378 0.515913337380625 0.591599015609827 0.672171910193283 0.0691953688394278 0.162268328873906 0.196669164523482 0.696829756880179 0.82270162908826 0.537028766754083 0.43733720041113 0.997913959380239 0.913163232062943 0.478100773249753 0.436583814816549 0.460208571925759 0.6926394051034 0.65577636238886 0.627438682115171 0.0911647178628482 0.102420886210166 0.914700098789763 0.152110022874549 0.499048604604322 0.850973227107897 0.255489279245958 0.158056865388062 0.364892138866708 0.146869742171839 0.300395471437369 0.9318657422252 0.0723771387385204 0.462191245616414 0.355161494917702 0.229334568821359 0.0476567807397805 0.538691371583846 0.78185226973379 0.0440096745663323 0.372747179535218 0.742172942778561 0.201804426978342 0.552836735288147 0.57176259760512 0.0566526055964641 0.946036148394924 0.303284954922274 0.266668054589536 0.804864603108726 0.873062630968634 0.904060740175191 0.794149542455561 0.204348848003428 0.835120447766967 0.530541352233849 0.787211237472948 0.47035445085261 0.230766216763295 0.333800673447549 0.712378209978342 0.329256386714987 0.960565557575319 0.341691978818271 0.251905289452989 0.955130642773584 0.250571316184942 0.168089766821358 0.542194193897303 0.313522997903638 0.0653151466627605 0.596840613863897 0.0767156615667045 0.148031958928332 0.811547899206635 0.0484343776083551 0.493742232427467 0.338921965847258 0.995463188227732 0.0923905834602192 0.315214347757865 0.512103595212102 0.504526829412207 0.213156566126272 0.152563783782534 0.595180269340053 0.950753560131416 0.238436391791329 0.940121787809767 0.305383481853642 0.0590195128531195 0.667102758805267 0.508537973689381 0.342592069930397 0.384711302388459 0.0543755285581574 0.657203969855327 0.696132761377376 0.91631745117018 0.0460407316195779 0.268419456295669 0.915485131433234 0.704822148589883 0.162612865096889 0.45005452722311 0.84897890774766 0.96782370414352 0.438180360211991 0.688901929336134 0.863242773625534 0.421581475462299 0.37730088874232 0.8478003426129 0.338842954717111 0.0737469996069558 0.941144149117172 0.235445347593632 0.0108874554350041 0.437898603144567 0.838016481667291 0.126593982793856 0.581154593513347 0.0210104602319188 0.341119508745614 0.981591942512896 0.227434986613225 0.702443175688386 0.380294629356358 0.904644751960877 0.78332985148998 0.488839314254001 0.571402971316129 0.411010438201483 0.729377353047021 0.439730459616985 0.55901318786433 0.286000653032679 0.743713687937707 0.207488662558608 0.653449075717945 0.902929377309047 0.426019432849716 0.618272250492591 0.256524730320089 0.774606778896414 0.814078176838811 0.412635595160536 0.0329122128407471 0.582260522060096 0.813474671009462 0.163174892722163 0.0903063896251842 0.680561045522336 0.708273776334245 0.0489762920606881 0.496481644599699 0.767474488448352 0.872339013828896 0.329007501585875 0.763844647591468 0.794480987528805 0.915541434164625 0.487363381281029 0.437666718484834 0.979934784453362 0.336078978602309 0.747910558320582 0.376242697460111 0.432687300273683 0.375638211534824 0.565367153056432 0.145807534616906 0.650709292667452 0.339650619924068 0.661550467833877 0.241231861209963 0.979076427402906 0.534287529233843 0.238378422989044 0.175263239969499 0.642558793642092 0.738321759055834 0.85848459017463 0.0378886649478227 0.473869250298012 0.623517354456708 0.0838154189148918 0.467552705316339 0.596627564011142 0.177083620883059 0.472516405803617 0.121250279380474 0.793037252044305 0.568650972102769 0.431071643007454 0.86215502364561 0.78310605031671 0.5319260671339 0.220698677974287 0.248412218540907 0.0499710537097417 0.314170976162422 0.62764229220571 0.313963538580574 0.23882242327556 0.129860780856106 0.305750909724738 0.809549826115835 0.589975022918079 0.900553541774861 0.836524875687901 0.728447196593042 0.750329501249362 0.231240881006233 0.574238719635177 0.325883577631321 0.615660416292958 0.959492012071423 0.363610021939967 0.840736032836139 0.735225313976407 0.465076119746082 0.903851357153617 0.461645596334711 0.543190779280849 0.818069234450813 0.544678752312902 0.765570921085309 0.198404357766267 0.29473881638376 0.254317328836769 0.473869096091948 0.212067087378819 0.755867224242538 0.0869099339982495 0.958717195061035 0.365096131130122 0.840043101320043 0.796129372438882 0.207832518569194 0.164119161451235 0.555359913448337 0.751349000178743 0.433783703772351 0.205800708003808 0.294468411556445 0.156549594700336 0.819096830927301 0.494684239698108 0.913317428906448 0.399958840217441 0.297218489763327 0.0764293400919996 0.863356251078658 0.392733368508052 0.644984911417123 0.0968709025671706 0.883738396044355 0.0901848851586692 0.243513385329861 0.989925003999379 0.677641711293254 0.760805998668075 0.505546656115912 0.376900450401008 0.265694346793462 0.794316400331445 0.376018958061468 0.498660061336122 0.509021640431602 0.106490032712463 0.551730611736421 0.212672701843549 0.293116297523957 0.226649461847264 0.406259918492287 0.517862286043819 0.161984431592282 0.667696513694245 0.719860983609688 0.697458357729483 0.28219775171252 0.192336406097747 0.289801759200636 0.947034753900953 0.0100577369169332 0.589598143068142 0.577872238848358 0.291234972022939 0.0140299924532883 0.0738790974998847 0.810028830256779 0.700678713719826 0.671524734543636 0.98106565750204 0.483068691007793 0.178727821484208 0.703043255100492 0.640408342371229 0.266258947746828 0.736878272744361 0.506775620586704 0.0626766753825359 0.118509412738495 0.567651106901467 0.94630561346421 0.816010762602091 0.910376312898006 0.635431740898639 0.245348851929884 0.942899619650561 0.79821090673795 0.907315138364211 0.33021598338848 0.963634781481232 0.910997889880091 0.570980425726157 0.901460742962081 0.658295363155194 0.975281231084373 0.708769105111714 0.242047100032214 0.0383639997220598 0.229399670287967 0.56463563982863 0.403247964966577 0.726502556249034 0.368473481109831 0.353576045213267 0.649027641199064 0.819345879482571 0.65619494702667 0.771945796757937 0.162959324631374 0.92601022842573 0.353092419500463 0.221078016823158 0.584756633944344 0.629006668271031 0.472429431509227 0.546103734588251 0.694678084407933 0.0970396602433175 0.747854256280698 0.63460434215609 0.107461706786416 0.896528649877291 0.866001311959699 0.215401114213746 0.293819405257236 0.384002007280942 0.806467681401409 0.999566825025249 0.141681386039127 0.915251148280222 0.147969788298942 0.203835285799578 0.419885104806162 0.433199322260916 0.380145235029049 0.414360943187494 0.662348149523605 0.283094991280232 0.923984735929407 0.0783218537154607 0.187028006883338 0.318627661864739 0.255353715289384 0.623634702505078 0.550640297187492 0.526366484912578 0.290589424872305 0.588066016391385 0.811367508538533 0.25716926141642 0.158876719328109 0.0525705910706893 0.583078392988536 0.418764681119937 0.80595409176778 0.47756189935375 0.100757758831605 0.438016747809015 0.985371173778549 0.279093889759388 0.922819134476595 0.906758029197808 0.879715137947351 0.0511570530058816 0.526285519583616 0.296690016593784 0.641284194088075 0.512639047761913 0.294556126454845 0.436468496110756 0.832764018224552 0.571980565686245 0.517044449690729 0.32090952943312 0.830734283102211 0.0938217164599337 0.115175797119737 0.776584699398372 0.715767650036141 0.844401132713538 0.787360800297465 0.584542523319833 0.816326401438564 0.156979060892481 0.646224415376782 0.64275478102034 0.12674340316793 0.763320885198191 0.322626276956871 0.536612546148244 0.905335522517562 0.992354667822365 0.403051687616389 0.53265382363461 0.207093550434802 0.945414006682113 0.243325665839948 0.104755545959342 0.904573851055466 0.545283820717596 0.973995959502645 0.165090594419744 0.653258560465183 0.221816335401963 0.749874825708102 0.834905097270384 0.612055625738576 0.316359955668449 0.224251738272142 0.960099409932736 0.990428275195882 0.432238224556204 0.182090494919103 0.3936360161216 0.936435383062344 0.0388732849550433 0.216359567826148 0.368208251059987 0.0425941481883638 0.822165847842116 0.455016628485173 0.389228777089156 0.117993226957042 0.159344106381759 0.581806446746923 0.53578112214338 0.363785846817773 0.434173259176314 0.270056739060674 0.925206650255714 0.976987807000987 0.479877145965584 0.877003124665935 0.278927217207383 0.322381488315295 0.689013705682009 0.725539478990249 0.62742956044618 0.83172665075399 0.953325616542716 0.0586650101700798 0.698855623481795 0.860265103403945 0.469718161136843 0.171591012959834 0.895817998724524 0.0953406943613663 0.504496950546745 0.659037668732926 0.154969391920604 0.978779616458341 0.0574179468862712 0.938256517718546 0.377120718434453 0.405816891156137 0.229050426054746 0.80032688915031 0.0158552475692704 0.717030394624453 0.715702949874103 0.923464056274388 0.0890197343379259 0.89815242474433 0.784001957580913 0.240216495878994 0.311904630390927 0.401616049678996 0.646170319013763 0.465947315776721 0.242415682259016 0.721104247984476 0.612028681628872 0.0239235616778024 0.294127602786757 0.0230019985814579 0.399106855865102 0.624582675867714 0.621091264341958 0.869963432077784 0.795974704218097 0.386276615408715 0.111743183513172 0.4936900939513 0.784998742809985 0.721390211950056 0.195174083029851 0.823252724218182 0.190489080382977 0.139157021022402 0.944064067669678 0.167582275588065 0.38808329825988 0.988472872697748 0.721853474394884 0.698970421482809 0.995393147557043 0.14680237025721 0.103189382385463 0.689522120307665 0.837771505857818 0.26025664037792 0.961302043891046 0.988810385514516 0.701220376463607 0.43681076511275 0.0143058039434254 0.356275388933718 0.439727843184955 0.581257233899087 0.581774209381547 0.811194758100901 0.259679265676532 0.0154516919143498 0.910517098193523 0.556901799824554 0.32914575020317 0.813601736805867 0.569896021718159 0.291780081698671 0.131425018352456 0.055782360387966 0.0232437492022291 0.557144232040737 0.273537588047329 0.429682584982365 0.274703384274617 0.088953308404889 0.413352837988641 0.82228419534862 0.598483085697517 0.734054920380004 0.648866864896845 0.188353614299558 0.834526003214996 0.966747962182853 0.747139848170336 0.426022200260777 0.549899004898034 0.60479685543105 0.825647954680026 0.907201753573026 0.295647204888519 0.541701064803638 0.751149039862212 0.946337036234327 0.420309269444551 0.70604448312195 0.729329407408368 0.342845138907433 0.983561101160012 0.263386216710787 0.0784563704999164 0.817847216213122 0.13640609963797 0.776032820791006 0.541608565829229 0.887689351551235 0.401989632884506 0.96951321689412 0.73389210897265 0.577661601663567 0.330888208649121 0.40228015849134 0.0857012313744053 0.930112682746258 0.526185916296672 0.106001048281323 0.36314709879458 0.293438037757296 0.344843209693208 0.135044356139842 0.200458629401401 0.39965305397287 0.580837535934988 0.290954248989001 0.447145774664823 0.449565384897869 0.200763944729697 0.458516198410653 0.101358840698376 0.706140471901745 0.35686260746792 0.108747538488824 0.985456186267547 0.152341646144632 0.971501896323171 0.836229864275083 0.75066261354601 0.832734969628509 0.389154694329482 0.556320184571669 0.669134968600702 0.765595692018978 0.185480209274683 0.332065846472979 0.81786784294527 0.639743180854712 0.954185975736473 0.672465274436399 0.466576503254473 0.637621845025569 0.039006913844496 0.598179512044881 0.0731172792077996 0.0413708683662117 0.620026851801667 0.261108443785924 0.858164744901005 0.167466880355496 0.0341034044325352 0.693012534449808 0.0557730245823041 0.567270399790723 0.0407898224540986 0.824537915124092 0.528430974946823 0.909949833324645 0.357415160525125 0.789161977139302 0.327712288899347 0.0172718386375345 0.212765975305811 0.849474421849009 0.35963277003495 0.426802862810437 0.229387165536173 0.940376762349624 0.87999294674024 0.413942658433225 0.0289003233495168 0.778272423220333 0.549686039639637 0.065571397494059 0.340714413565584 0.639087188951671 0.217287976150401 0.177101554425899 0.404247693018988 0.106029320775997 0.510066537491512 0.434609412471764 0.640929714455269 0.808040547983255 0.90706714896718 0.780947115176823 0.574922038281802 0.0737030912167393 0.871773786600679 0.437428861970548 0.408913999390788 0.285423121128697 0.771634458403569 0.611065087122843 0.836393848478328 0.30674102306366 0.11488439537352 0.0638040929706767 0.0198392478912137 0.371259082723409 0.727199451944325 0.424797153177205 0.316501795973163 0.539033147310838 0.0874121133051813 0.398512726409826 0.989732734393328 0.0311596724530682 0.540032173714135 0.508978469187859 0.178085989339743 0.411399993605446 0.0295178628526628 0.312450858694501 0.984184291427955 0.776556624905206 0.524268710571341 0.506009480606299 0.913796244265977 0.886070421382319 0.871948535724077 0.180273945415393 0.353589386227541 0.136697967920918 0.980582419033162 0.654421793045476 0.833296681465581 0.0731919089495204 0.417912391352002 0.340962341187987 0.500811487170868 0.243536905788351 0.697543111364357 0.0960709151625633 0.427381400857121 0.386072662330698 0.0588741142838262 0.688926617288962 0.608562280759215 0.479851994242053 0.345332161854021 0.50517168505583 0.783905299883336 0.128665231848136 0.549050902205054 0.867226466457359 0.0491987143689767 0.515681049802806 0.178312365685124 0.584733132156543 0.738434978807345 0.943866604384966 0.837743641352281 0.330707728085108 0.81122570972424 0.423018853692338 0.267331339586526 0.70150133368792 0.423613766625058 0.173150843943004 0.267291157497093 0.314646318543237 0.0117960278806277 0.971514906797092 0.689420884142164 0.363333567809314 0.536702948703896 0.43481266920222 0.876126204570755 0.197998613261152 0.508857199833728 0.443036354563665 0.532492552213371 0.142612163927406 0.351385016771965 0.621475072861649 0.867490765969269 0.215075334196445 0.848997836599592 0.517493823217228 0.944855986800976 0.43677955993684 0.275277336016297 0.138553260718472 0.634217087395955 0.368868332765996 0.734334466008004 0.722654615002684 0.118537589113694 0.444032305143774 0.932317974672187 0.634320084829815 0.797098234384321 0.976721818598453 0.596133512447123 0.409890949893743 0.833679554606788 0.12463058463065 0.199813908601645 0.756203170795925 0.0755569542082958 0.773960262022447 0.244597724797204 0.619708096804097 0.0325839549233206 0.541020857016556 0.368568124908488 0.165499008372426 0.16915627716342 0.835810007264372 0.836870306720957 0.653165864180773 0.6690199449379 0.346254310887307 0.766993499912787 0.120794486824889 0.755435040427837 0.861281208647415 0.210214847584721 0.712359710782766 0.330590080614202 0.0412199594080448 0.774726203309838 0.951312713392545 0.173195182220079 0.612166729939636 0.539713584447745 0.439061069765594 0.264733769102022 0.769066916380543 0.750450715743937 0.375278067537583 0.617157530817203 0.217503744086716 0.540698392083868 0.47411661318969 0.946642539883032 0.700547870681621 0.978988640357275 0.58643850807799 0.415435814310331 0.642609695242718 0.253065155085642 0.0923825373151339 0.317235293134581 0.244136929188389 0.177381435204297 0.749783179131337 0.211625962378457 0.117645993626211 0.394723940361291 0.94959241221426 0.111258422806859 0.913893655706197 0.480631492524408 0.630207127670292 0.346773089359049 0.307747546324972 0.464414612152614 0.825481313245837 0.530562072319444 0.536056813311297 0.958632569585461 0.349429946197197 0.959450986343436 0.924014686942101 0.783337039013859 0.0964747437322512 0.203661810201593 0.516528505706228 0.464595855679363 0.0122440877743065 0.522742555288132 0.730125703548547 0.590512032511178 0.74768129816046 0.815665532106068 0.0513574950722978 0.427871510139667 0.485382745692041 0.193345364846755 0.462273615396116 0.521804940009024 0.516885371960234 0.807619702809025 0.681190877254121 0.703269769977778 0.68704221919179 0.367590919930954 0.304617556931917 0.26103397539584 0.874577639158815 0.488101232631598 0.111460225067567 0.259820784430485 0.801510242279619 0.189486607278232 0.661015035337769 0.772895791165065 0.979367324118502 0.243492268549744 0.128040391183458 0.127852896663826 0.704129262021743 0.35295566131128 0.0776134418928996 0.0990331467986107 0.0787594981305301 0.0596418440388516 0.641099005283322 0.138362095679622 0.461606584736146 0.626712924991734 0.66864871193422 0.367111439802684 0.858266156478785 0.346305380293634 0.902510472042486 0.161357543375343 0.808478026436642 0.13262288529193 0.813765224276576 0.861293900106102 0.385433502399828 0.170785760190338 0.716177441470791 0.16936446249485 0.839755994754378 0.936921984099317 0.918177151172422 0.463915123499464 0.961526457739528 0.139848747933283 0.109288731699344 0.56871474057436 0.738397076616529 0.792794669310097 0.523231589507777 0.951229366974439 0.509295500949956 0.464508837589528 0.95069643151015 0.277051257570274 0.325040232737083 0.593022525436245 0.346286296774633 0.947035363810137 0.294219503146596 0.294531118334271 0.611115777352825 0.86552342368057 0.513613725742325 0.180930727249943 0.410094174584374 0.116111479636747 0.864790115761571 0.793471114377026 0.556718777741771 0.34031921684742 0.698703590594232 0.254319662903435 0.28047427628655 0.975492593890522 0.963563215576578 0.441054240763187 0.614273311775178 0.721518449620344 0.642592958698515 0.255433099833317 0.785796314319596 0.695798577244859 0.653277154166717 0.909778797593899 0.904837352107279 0.143752276892774 0.637666314458475 0.554025375219062 0.293346269936301 0.545868120170198 0.0949899032269605 0.187692998289131 0.937335677016526 0.25986273700837 0.864731659216341 0.0526730138622224 0.607666671304032 0.862005633928347 0.317282922985032 0.199300636600237 0.097701626305934 0.94081228406867 0.534894200782292 0.313007426180411 0.299609591697808 0.553942715467419 0.789866886709351 0.274569118968211 0.271311511956155 0.0786951865954325 0.752003494969103 0.0999234563135542 0.629525255886838 0.873537905351259 0.326042712065391 0.338107271471526 0.449963300621603 0.652514883168042 0.294999250140972 0.958998183864169 0.161275563144591 0.856919373043347 0.871982147113886 0.560929685947485 0.919897333180998 0.558788245934993 0.941980720469728 0.162471233627293 0.630386835359968 0.983943725819699 0.205640790092293 0.649858892557677 0.28387940825196 0.0678289159480482 0.602119863522239 0.613604021731298 0.4075422200514 0.894461024780758 0.556352091166191 0.531068983839359 0.49238816972822 0.546347255927976 0.701987644522451 0.669357753950171 0.591809649337083 0.216840996621177 0.367576599281747 0.723391893324442 0.961591802616604 0.541997658384498 0.874556465444621 0.502805355899036 0.451483965339139 0.808133508653846 0.178852808380034 0.439771390608512 0.666788529721089 0.651533672059886 0.56140110909706 0.793026410597377 0.683511424497701 0.836810433969367 0.666394521011971 0.361195747375023 0.470164243089966 0.681404755071271 0.486475469912402 0.638879145609681 0.910233414357062 0.206387906023301 0.978048730427399 0.181776174094994 0.45312059578253 0.873893200501334 0.0818266802467406 0.895538387172855 0.481673486637883 0.0802071168879047 0.702777550215833 0.172645774136763 0.973732280503027 0.91670022404287 0.166701229962055 0.526461001704447 0.33573559765704 0.182480607908219 0.675041833249852 0.691019969673362 0.820607738711406 0.439745581722818 0.83342756438069 0.812259634642396 0.291302262800746 0.0857037892588414 0.216063359645195 0.912557497045491 0.14838861542521 0.830119651616551 0.921489642173983 0.0982791805686429 0.388173223675694 0.764232396779116 0.27925653635757 0.228272857768461 0.927198364248034 0.0423927306360565 0.737132051438093 0.952503743171692 0.323723222827539 0.0329140324261971 0.0422550446749665 0.860247899631504 0.945402011801489 0.0377490270929411 0.282917937824968 0.118533266042359 0.513447190569714 0.628989566841628 0.42330472914502 0.910409186910838 0.18354419501964 0.827100507109426 0.543744958993048 0.447975543893408 0.368908396377228 0.239486665087752 0.343652427704074 0.420668431501836 0.952702751052566 0.30307008064352 0.682000432810746 0.650401297518983 0.842000763202086 0.85456828170456 0.658252921451349 0.654789282691199 0.921162965963595 0.879498853916302 0.203622473133728 0.553195696577895 0.831104757061694 0.423738050488755 0.281049337896984 0.189857470786665 0.424363357690163 0.897190391430631 0.793742804485373 0.705938304755837 0.84795885077212 0.60504634678131 0.730847648393828 0.459351362085436 0.174723703609779 0.285862350016832 0.990096430201083 0.31984587432351 0.703112323281821 0.890927744579967 0.462330986044835 0.512726086827461 0.37346164688468 0.453206569696777 0.690439040856436 0.26634062717203 0.705706032621674 0.190293003800325 0.410060301113408 0.747242961085867 0.0947692313534208 0.0534811068815179 0.442277184743434 0.457377018518746 0.387585356738418 0.985318438070826 0.81777076872997 0.769036579045933 0.675202330874745 0.165109842747916 0.126754770390689 0.564694015467539 0.663064380676951 0.902413728828542 0.469853460937738 0.0787610563263297 0.935571990918834 0.92952023065649 0.16870548627805 0.888381197862327 0.621917369505391 0.213920245955233 0.986878704011906 0.307487683522049 0.637020170306787 0.959459712931421 0.749870683581103 0.0860042488249019 0.899051911018323 0.588777750674635 0.454610557819251 0.0816339208232239 0.318217879189178 0.626482548969798 0.909916175142862 0.248381504565477 0.842198076660279 0.687039740600157 0.262780065867119 0.12432146117324 0.545034767321777 0.138109700691421 0.118504497737158 0.922298728197347 0.891365455840714 0.618467935912777 0.496146657397039 0.395752436257899 0.199973579645157 0.829443312350195 0.787566021138337 0.19519799787784 0.950890578557737 0.423481235387735 0.826828994487878 0.917334309234284 0.971214716688264 0.192678861806635 0.31295956951566 0.159979891297407 0.199629514338449 0.635049650543369 0.782732072952203 0.0356573154241778 0.149348262809217 0.415275377768557 0.732902390945237 0.12148306369083 0.132310506680515 0.663173387767747 0.784772399426438 0.371832328897435 0.0958689764444716 0.881110204015858 0.305228419704363 0.154474868748803 0.195021372004412 0.618631298681721 0.753081143184099 0.47719366149744 0.749640413820744 0.0820689287525602 0.672550248431507 0.166110796381254 0.765093899033964 0.582960997917689 0.166419221877586 0.183537480947562 0.55960876256926 0.709507121962961 0.931456140263472 0.722125504263677 0.34496288835071 0.939958135529887 0.57800560727017 0.33061979443999 0.635789005460683 0.210409347300883 0.434340722351335 0.0911277298443019 0.332082530693151 0.930790648206603 0.190768130661454 0.777270863365848 0.119044112006668 0.770826292545535 0.313064204899129 0.461929749473929 0.409608921986073 0.0107171328784898 0.499813021118753 0.036252695354633 0.346968262142036 0.684366607300471 0.965080102360807 0.804671683486085 0.940261029661633 0.761982547598891 0.130938282702118 0.547989202677272 0.630001207715832 0.0219658479327336 0.967992262204643 0.82355549618369 0.490836234833114 0.536130471024662 0.32133556505898 0.160256238474976 0.505850028309505 0.78481265435461 0.816894693886861 0.221005792373326 0.714393561293837 0.641315983126406 0.29653463335475 0.0942299921112135 0.574371065779123 0.549780967186671 0.954212481661234 0.460238227895461 0.0848267564480193 0.0860030078003183 0.255119371861219 0.57653526236536 0.819533052681945 0.111468301177956 0.396570695121773 0.920700231830124 0.765811824148987 0.420086890931707 0.192622837522067 0.251453680745326 0.624703296588268 0.188439904693514 0.278883861331269 0.430821621271316 0.680728926367592 0.903784146129619 0.447622615541331 0.841620627506636 0.535560479313135 0.719768685402814 0.939009442769457 0.73450602843659 0.638284625452943 0.0460409001167864 0.988126046434045 0.378393050306477 0.709744858385529 0.3440637948527 0.635981060930062 0.398744681372773 0.866341628145892 0.744791769727599 0.77767469331855 0.919800221393816 0.119365228731185 0.085192769265268 0.88013910735026 0.0839177543460391 0.442277335491963 0.0585981455910951 0.405185773451813 0.981844398123212 0.106138684453908 0.539265651560854 0.0569998914818279 0.510313231465407 0.650381730867084 0.59364904738497 0.599642990515567 0.0831187613285147 0.286626112135127 0.0874792837607674 0.327296994912904 0.579089793683961 0.867032489751 0.329018676800188 0.739641356354114 0.637783444221132 0.740015071867965 0.844552447355818 0.858315940373577 0.217820006893016 0.770138842144515 0.823702441193163 0.274624571145978 0.592646867018193 0.122282008763868 0.105840927988756 0.846700317922514 0.696195699118543 0.219101337345783 0.517193341753446 0.0470843931869604 0.609093121879268 0.470897184740752 0.527249795224052 0.0719870458031073 0.283507912014611 0.389698561136611 0.336259625589009 0.44675588687649 0.990983846220188 0.320727260401472 0.26203792832559 0.225331750519108 0.130709311822429 0.078718163529411 0.959530531778 0.0333549066400155 0.390449611742515 0.490467413805891 0.106119279153645 0.621604886015411 0.410187125343364 0.796060844324529 0.302050011681858 0.342930611248594 0.737740016104653 0.208117655261885 0.392125287437811 0.0759027538145892 0.0614583603502251 0.773145121394191 0.390320674267132 0.86996971787652 0.0724114017584361 0.0338348832703196 0.0840169441117905 0.206610438511707 0.072711845189333 0.254658263691235 0.111838593962602 0.387176684162114 0.410707826204598 0.716117519852705 0.790082816919312 0.0563736258517019 0.891173732755706 0.152342118443921 0.443135546403937 0.30164214540273 0.160753457832616 0.41903330255067 0.998052419137675 0.321082228929736 0.798727393785957 0.120527403075248 0.900067899627611 0.556663230136037 0.561830909517594 0.266324067192618 0.346593698379584 0.940389762911946 0.588690903848037 0.6024887868925 0.126594576337375 0.892473364172038 0.462528481830377 0.0820295167714357 0.219547822908498 0.611999496344943 0.92527736422373 0.864187223990448 0.47368191159796 0.858081572973169 0.849399735634215 0.49315313852625 0.622168649092782 0.686425977877807 0.121338047755416 0.338778391703963 0.54850447566947 0.761402522120625 0.511671641438734 0.570425498955883 0.0159785100771114 0.0637985403998755 0.199160742657259 0.735305285609793 0.188431539533194 0.421340268135536 0.798484131991863 0.659070414125454 0.287627586703747 0.412173913500737 0.884282029352617 0.813896015682258 0.220643885033205 0.84271722877631 0.924702657817397 0.90514864735771 0.982056350323837 0.738170269231778 0.745109501525294 0.0357294838619418 0.714369333654176 0.815570095609873 0.608407252032775 0.984393279599026 0.570822505117394 0.849297539426479 0.517414667792618 0.264608734953217 0.893179867896251 0.913988764428068 0.0258374707587063 0.694588818920311 0.607022056765854 0.976398991777096 0.593890938381665 0.859096178568434 0.280032304881606 0.176821598273236 0.116929376842454 0.261549616730772 0.990125260280911 0.269686413544696 0.483877082297113 0.475829918622039 0.888280688701197 0.87729271950433 0.971279121576808 0.643624881934375 0.676731359139085 0.989088828188833 0.881957860686816 0.647539304434322 0.263709091015626 0.22162882105913 0.807269844978582 0.310466710480396 0.142035629868042 0.666221684135962 0.805424866238609 0.521610154008958 0.502301711980253 0.988622882005293 0.0323211868689395 0.235118563738652 0.526660696712788 0.517909951622132 0.333624443807639 0.449670615438372 0.539576935286168 0.51934075362049 0.467954332588706 0.71955546889687 0.450128552818205 0.728907682867721 0.86454624382779 0.582488393443637 0.412978540456388 0.978277512295172 0.940035918082576 0.0976016811840236 0.801530964439735 0.578045391512569 0.931726331876125 0.497357257055119 0.383572762832046 0.23043744321214 0.326306969625875 0.516918892993126 0.199048866964877 0.143039455329999 0.264593902819324 0.607836162438616 0.161078342348337 0.4960215902864 0.354710279447027 0.293961240490899 0.0949404802988283 0.915907996729948 0.415827618495096 0.949307553507388 0.306432698066346 0.254607139655855 0.982123750129249 0.214687118241563 0.24660788082052 0.734776293809991 0.792368539408781 0.258547882987186 0.971137966555543 0.376992512112483 0.140548752644099 0.070598291810602 0.800718092876486 0.504478678165469 0.438600975805894 0.95824882514542 0.151571462231223 0.864376495913602 0.412967660976574 0.764448023417499 0.938363639761228 0.66788521950366 0.84768879561685 0.309305222802795 0.409218442037236 0.177401258866303 0.677073203555774 0.0236636059824377 0.776593544925563 0.655040838881396 0.214662264557555 0.474323510243557 0.343979437681846 0.762820549679454 0.994337107092142 0.264234401693102 0.128925215664785 0.69748316692654 0.282836102810688 0.832778637374286 0.348713581582997 0.296829446074553 0.384819665455725 0.864900245859753 0.146931148685981 0.997682724506594 0.984127401837613 0.127750641677994 0.471587063483894 0.441277608131059 0.206099073225632 0.52721268042922 0.224142976896837 0.955126707637683 0.353348870868795 0.790222334912978 0.286683237298857 0.995958718233742 0.440936284419149 0.20474917086307 0.88778538182145 0.842659131814726 0.903100004359148 0.481834316877648 0.351992638912052 0.444199041775428 0.0453761016414501 0.795479560072999 0.108609779688995 0.498310365318321 0.269683703298215 0.432983439534437 0.904839383985382 0.664526158270892 0.980312859227415 0.78248902621679 0.622270635543391 0.0735150001570582 0.756237830971368 0.779157400524709 0.0839165525068529 0.0422364442888647 0.423474870526697 0.682099477360025 0.0352026387304068 0.0124696744186804 0.787355859018862 0.355844905534759 0.796086341571063 0.138604347412474 0.6588424131996 0.842847523910459 0.987505385468248 0.66673009991413 0.360692765919957 0.334092275269795 0.940863707757089 0.64329171178164 0.342590091528837 0.154749672252219 0.703577368431725 0.161362883192487 0.593254885852803 0.453784540246706 0.6184263786464 0.667473302837461 0.316888285235036 0.618470134905074 0.608154741562903 0.0830643991963007 0.728959827336948 0.501556627235841 0.0293507426651195 0.183762425181922 0.27653814968653 0.825601734812371 0.362573866911698 0.886806264135521 0.881353307685349 0.30254281092668 0.903944235765375 0.712430074156728 0.970659706245642 0.150379219548777 0.975538764430676 0.904855089262128 0.556832374364603 0.0696602607052773 0.806336356382817 0.842515732392203 0.353582357750274 0.493525887543801 0.600258590341546 0.585214672745205 0.814251847672276 0.596772334692068 0.130206056530587 0.972369466782548 0.818871174671222 0.368039505139459 0.339779277569614 0.883450898546726 0.592293935900088 0.614755543179344 0.577920598238707 0.314563900127541 0.326395599388052 0.823201008022297 0.463891074268613 0.709560716752894 0.172463572411798 0.610289524667896 0.0912278068135493 0.941749009839259 0.657426146678627 0.478206600560807 0.851034954942297 0.380127629260533 0.522428931272589 0.227367589112837 0.607036379489582 0.31153436319204 0.0245167188742198 0.423347617562395 0.404690536183771 0.152669032993726 0.792616191350389 0.219080190369859 0.132816777864937 0.959254187596962 0.781301288472023 0.503626527851447 0.760165276622865 0.774805448860861 0.806886510371696 0.382053391232621 0.340967984115705 0.521139689979609 0.620844559534453 0.0740846813819371 0.826170162796043 0.50577040289063 0.94160548548447 0.773633358306251 0.898848819788545 0.755014606239274 0.0926894557871856 0.0733197863446549 0.161331338947639 0.587710043333937 0.329965857234783 0.967469569342211 0.0691037169611081 0.611206379523501 0.657340203190688 0.951944295098074 0.507627527951263 0.555687611245085 0.0280927565670572 0.453845704733394 0.0851421705447137 0.529685324870516 0.0676210920442827 0.881297707525082 0.627588686812669 0.169160899196286 0.600719145997427 0.559609429873526 0.508882948788814 0.855257704053074 0.679569969836157 0.83778965953039 0.507469865044113 0.210880522660445 0.0892527712788433 0.933351708273403 0.710648303076159 0.47610565450741 0.766901404547971 0.222571600743104 0.350164896214847 0.654597979350947 0.173944641437847 0.721865842689294 0.395906702943612 0.731572186390404 0.0882089672610164 0.173234608492348 0.200244286430534 0.450238587027416 0.269975981414318 0.338563995487057 0.988966510510072 0.900780917347874 0.140223798977677 0.598400906312745 0.241806618787814 0.791611141229514 0.609787810284179 0.276145123378374 0.0772272292338312 0.4322627516184 0.628520455630496 0.291513123342302 0.0873220991459675 0.737610923962202 0.303528767386451 0.23030034503201 0.676951874271035 0.850993157261983 0.847191576950718 0.229797606756911 0.807011190238409 0.187707074144855 0.979873054313939 0.418476932605263 0.0506566594005562 0.506122250878252 0.661025930261239 0.899097629312891 0.459210438949522 0.877745952331461 0.670680513510015 0.977431949276943 0.0409014639561065 0.040106054788921 0.73968516217079 0.237870283352677 0.11281107525574 0.394455311323982 0.811869353847578 0.18827183668036 0.192841059616767 0.0108045548084192 0.882230673341546 0.987324237830471 0.225306127879303 0.457455381245818 0.279344171041157 0.670115062233526 0.426615407937206 0.633429346580524 0.511540114961099 0.385614866248798 0.654887312338687 0.0274323311820626 0.489532581150997 0.296170421452262 0.575758032456506 0.282034922556486 0.347778949926142 0.964268351730425 0.892744327506516 0.669905555662699 0.608453436633572 0.733895544379484 0.568614421116654 0.704687151669059 0.288693364048377 0.24678494672291 0.941507825101726 0.225883370733354 0.337617311323993 0.887109959954396 0.0997684054588899 0.365419506777544 0.013440506006591 0.456978052626364 0.358914450760931 0.125531216270756 0.655166446059011 0.0378656098735519 0.0798693263158202 0.667222692398354 0.0899192646378651 0.905395107371733 0.617596104617696 0.0393958860775456 0.158829503459856 0.014214187792968 0.399789380431175 0.577787277991883 0.464181823462714 0.885883452408016 0.923281509256922 0.957661015833728 0.265045766923577 0.0125587808596902 0.14552373575978 0.0545837777387351 0.759154043046292 0.12498826110037 0.233904836624861 0.179275268684141 0.400356951868162 0.641083332046401 0.574806544855237 0.0390798738272861 0.856324418159202 0.0804281872999854 0.644648794983514 0.236565163675696 0.586351335090585 0.558915321412496 0.994887203916442 0.823498421269469 0.825376167991199 0.832247957375366 0.916887840728741 0.0627561419853009 0.424741186057217 0.603026299211197 0.475078211314976 0.439184367770795 0.805430074208416 0.239258269080892 0.917619866593741 0.244753827664535 0.940727580913808 0.0219449925422668 0.932168384417892 0.210357910704333 0.085527208794374 0.711285690905061 0.848707289556041 0.517442747587338 0.824322295861784 0.591078484859318 0.0322628568694927 0.3681468795822 0.501761364943814 0.564047833052464 0.615204927078448 0.624106350163929 0.915078533838969 0.511041925880127 0.382627554114442 0.271238630113658 0.0189100205921568 0.169270657724701 0.789800135768019 0.539080897253007 0.694774976295885 0.598460867577232 0.418573688727338 0.24441873535281 0.972194631220773 0.743501250990666 0.310769073765259 0.307186268754303 0.0705850902502425 0.871038983643521 0.04016134446254 0.822889010200743 0.163748398672324 0.401734791113995 0.0474348701466806 0.203752174493857 0.87967906179605 0.794912653174251 0.0791563537740149 0.894901851972099 0.536197297570761 0.336455430639908 0.482362022935413 0.320192316800822 0.19962829843862 0.403814482546877 0.638400555681437 0.401699888680596 0.585128282313235 0.95533580990741 0.0165318138804287 0.741871211531106 0.973536514176521 0.543612745157443 0.160614970414899 0.490255561182275 0.215323232545052 0.124285029817838 0.449729546587914 0.488319556838833 0.670501148577314 0.742634260244667 0.0392993888095953 0.628421682382468 0.175826892866753 0.655438306278084 0.113841490314808 0.391297224618029 0.633751469447743 0.0406949659017846 0.58183686060831 0.886895522247069 0.313668970884755 0.726795364520513 0.630210417399649 0.67815253328532 0.52620234166272 0.0445342462533154 0.950968570637051 0.856997357055079 0.0224262477690354 0.361516198639292 0.31901614013128 0.8544410132966 0.608460230228957 0.550296339294873 0.206733928755857 0.271651815695222 0.206369048396591 0.967715267776512 0.242823329560924 0.389502442372032 0.607204039744101 0.709222517269664 0.525872064083815 0.703866553897969 0.464199984050356 0.889813288138248 0.440872371883597 0.457960882321931 0.202158676569816 0.636096597691067 0.842115377262235 0.677047033472918 0.7469762791018 0.761432991994079 0.99936786785489 0.191571600725874 0.104799056733027 0.734238996319473 0.836565015595406 0.990771402358077 0.128778030471876 0.883402915336192 0.386420734229032 0.941487048312556 0.841612910979893 0.698066620666068 0.306238439225126 0.732710642274469 0.526334176091477 0.69833837531507 0.257288214222062 0.272346756730694 0.521863000781741 0.568666036122013 0.0916370173823088 0.491181729715317 0.690473110484891 0.774863983546384 0.773773200847208 0.54788169200765 0.0203254287224263 0.0790483237826265 0.623212226526812 0.649729016476776 0.590699785654433 0.740810348496307 0.082590854964219 0.645288195558824 0.521199107489083 0.471267804838717 0.712047436819412 0.655256476122886 0.931567257603165 0.492374998824671 0.875867678681388 0.281062689283863 0.575476041659713 0.0890790900727734 0.582708808537573 0.31813498017611 0.201859372050967 0.643870831846725 0.423688982073218 0.670413894683588 0.218334335747641 0.264055012327153 0.433052234570496 0.172276949652005 0.0670798891526647 0.557712532556616 0.273591772462241 0.853821650058962 0.665916147986427 0.183970696029719 0.765740152213257 0.600899741582107 0.439287594323978 0.928713511892129 0.0266358570940793 0.593928717714734 0.501895290259272 0.964843102162704 0.25628331623273 0.847143326587975 0.581140945008956 0.0619342033821158 0.0298967377003282 0.688841930960771 0.965708165678661 0.120854100491852 0.923989405215252 0.89436588978162 0.347622933958191 0.886212462224066 0.699086516289972 0.361767968274653 0.204924773767125 0.446732957886998 0.491748089401517 0.936568673343863 0.468340006563812 0.757030309531838 0.209191978711169 0.914124857618008 0.22229416720802 0.394196321663912 0.638706218376756 0.205875843467657 0.994595038054977 0.307272691917606 0.400857453118078 0.914483997316565 0.152221221120562 0.322915658350103 0.251053448934108 0.898139345811214 0.829599283600692 0.630200347905047 0.743225472231861 0.446131607946008 0.881167277547065 0.34759630079614 0.568753314218484 0.371216435411479 0.529343063475099 0.115460317449179 0.924216220898088 0.345378549527377 0.622048536860384 0.260426030321978 0.230938219681848 0.0492289488995448 0.310909995979164 0.0443996849819087 0.43356288576033 0.430845967158675 0.371976921400055 0.170066116910893 0.515891635816079 0.162908287495375 0.552685578309465 0.489519852811936 0.0873230990651064 0.892118896064348 0.305420599183999 0.205714719106909 0.572597998927813 0.643675221570302 0.761417499701493 0.268972294023261 0.264664853282738 0.729989974782802 0.496223450403195 0.714029650888406 0.961979978464078 0.161583328251727 0.72502457272727 0.789207892974373 0.598628672126215 0.517803709867876 0.0887003307067789 0.0248989235586487 0.893061533758882 0.334004297368228 0.96128997386666 0.47836979160551 0.91455182839185 0.895340917895082 0.408387483647093 0.634553007902578 0.190595515067689 0.694345858853776 0.974071438645478 0.584244732970837 0.054951306108851 0.253633848377503 0.794325772325974 0.148933527099434 0.622008997180965 0.470906408291776 0.759786344149616 0.0449793195282109 0.271128398594446 0.406319600848947 0.144947068239562 0.91668581234524 0.642442049509846 0.130068860847969 0.311537669517566 0.26252286329167 0.0339179673767649 0.0452798413299024 0.717172762088012 0.567965187772643 0.336942936168052 0.369705647258088 0.991777611905709 0.706936542149633 0.0722069503343664 0.0169795024348423 0.625525790932588 0.697716905977577 0.691136932782829 0.31880377026042 0.522331970925443 0.482278664761689 0.0962728734733537 0.69180798340356 0.921825704670046 0.0424263809807599 0.916776819739025 0.80054931353312 0.40955006966833 0.285699196313508 0.97401696564164 0.831670849365182 0.271720655679237 0.375490787541494 0.0172778072650544 0.644302851313259 0.368360494165681 0.198081602631137 0.691363164372742 0.238895998469088 0.998331481863279 0.190553405978717 0.37394256696105 0.335062289035413 0.63949059846811 0.540887002004311 0.339454196204897 0.612330851983279 0.776094402256422 0.0399023084715009 0.443818023025524 0.644005939408671 0.240825067458209 0.769275629331823 0.628928376999684 0.690012924324255 0.730667124034371 0.541683148548473 0.367155622029677 0.944542862053495 0.853850999691058 0.99276461069705 0.549421176319011 0.270056899490301 0.46556751338765 0.808377957765479 0.156625623591244 0.0317214031913318 0.463454805491492 0.704124658659566 0.997498719331343 0.379581102456432 0.225337403819431 0.715263470429927 0.0397430599387735 0.411841559095774 0.420877859701868 0.0202068221312948 0.39343095916789 0.0120844012871385 0.095587598553393 0.387105933774728 0.588617890619207 0.101870249549393 0.0912785161752254 0.329865364208818 0.30022500643041 0.687149145998992 0.300996676853392 0.311317933714017 0.99714389578905 0.384003213730175 0.378260164326057 0.0341623888281174 0.280471654322464 0.579697679518722 0.554620097065344 0.459161076874007 0.229370984733105 0.530553238778375 0.997235014745966 0.747143316078 0.971208171804901 0.995235795367043 0.831354900042061 0.41924358061282 0.525112983237486 0.952080067198258 0.0579041125043295 0.52824532859493 0.183410685299896 0.170555690506008 0.54504574338207 0.0469380186707713 0.240182634624653 0.0738062539207749 0.355216547634918 0.508203758669551 0.824688864189666 0.37555058791535 0.558373206192628 0.67166889047483 0.333701389867347 0.756551605043933 0.86755072262371 0.248895344985649 0.871991083920002 0.741915158876218 0.303733910317533 0.0128649949165992 0.0906241709808819 0.712075722222216 0.607649354585446 0.357226478457451 0.94427174220793 0.919414200973697 0.611595302659553 0.0835575052397326 0.733459661693778 0.352567867867183 0.0469316192343831 0.247551362845115 0.728040366652422 0.652411182471551 0.511811393392272 0.958268705280498 0.288790083751082 0.881433883695863 0.161146928549279 0.525363158949185 0.577129453825764 0.639144420837984 0.864507235456258 0.438250516594853 0.129375256956555 0.100577712995 0.916980630827602 0.0436006368743256 0.123028447018005 0.738924735421315 0.237565427415539 0.0538493184605613 0.254020301911514 0.784753891702276 0.820978881127667 0.359103048925754 0.457458456838504 0.088318995477166 0.406546274311841 0.080238508079201 0.118169943878893 0.774473091920372 0.873809700568672 0.755370441456325 0.147136445592623 0.211555940839462 0.140192728876136 0.748655077873263 0.0943544813524932 0.30946974638151 0.810370703025255 0.57863373236265 0.486360521623865 0.893398687453009 0.0287904461123981 0.828114443095401 0.508023729890119 0.493375329871196 0.654302957796026 0.643063190151006 0.370906949373893 0.0543562244484201 0.919387851099018 0.603785943866242 0.604640151413623 0.26739381240448 0.99037820340367 0.0229946086765267 0.0271996752615087 0.145958041809499 0.256871601531748 0.473920817589387 0.751201816368848 0.79264490640955 0.278430060315877 0.74235971305985 0.54774951413041 0.946367316865362 0.479577650821302 0.184936804163735 0.494390519328881 0.206901198539417 0.923810565366875 0.602519359339494 0.251931360650342 0.805287762756925 0.367231541662477 0.292306619570591 0.812770893436391 0.231018262309954 0.717240511334967 0.902762997034006 0.197609598154668 0.923100962077733 0.0894408220006153 0.435494680900592 0.241570755427238 0.629466399420053 0.933688135885168 0.0289352684258483 0.938754217212554 0.990689766728319 0.570440188869834 0.474530721702613 0.237761933424044 0.139259110046551 0.612239076325204 0.940716663170606 0.465753850324545 0.135502598474268 0.510578578379936 0.818299081008881 0.0388254038570449 0.680454614986666 0.617485097688623 0.36948603177676 0.552083981039468 0.79149237559177 0.0743522482644766 0.919636856089346 0.735310739295091 0.565804407461546 0.984539240133017 0.997224051132798 0.279346572645009 0.890321757853963 0.87204493456753 0.142180708039086 0.937591128004715 0.984361002587248 0.590476122321561 0.353609050151426 0.287558835463133 0.924123230262194 0.762778549618088 0.279778144245502 0.668498184918426 0.694360679693054 0.296203564000316 0.521011363796424 0.0792322639562189 0.57538911254378 0.512979238785338 0.687003698332701 0.861338856590446 0.741404180603567 0.230810280742589 0.874159485560376 0.949165529953316 0.713030017341953 0.570555857247673 0.833336035129614 0.144869331556838 0.518093913693447 0.37353385243332 0.923618256575428 0.103592884333339 0.730058820759878 0.663747120532207 0.470813367636874 0.916065826981794 0.187282684766687 0.0248788691638038 0.687635598131455 0.555916370293125 0.885504762423225 0.963503279206343 0.245662631304003 0.147059430843219 0.96518675994128 0.736230045543052 0.440639738782775 0.110980624156073 0.351868877136149 0.259976835434791 0.321761111558881 0.540770625523292 0.880077274867799 0.968911747091915 0.671325219327118 0.0928919089864939 0.363437090558 0.321654019251 0.875363003495149 0.748614600049332 0.694657332743518 0.246722387005575 0.45541960488772 0.518647674352396 0.881934445798397 0.508973727063276 0.0177894786582328 0.26504388256697 0.129655563011765 0.873610253580846 0.111000785734504 0.227768929179292 0.335942676116247 0.706529324043076 0.138026940440759 0.291455721114762 0.536486580308992 0.791423303491902 0.206931929341517 0.749234157830942 0.198604174710345 0.0162744264421053 0.59127011067234 0.602931575658731 0.234993234546855 0.146386288874783 0.426116863882635 0.549643555984367 0.103896608734503 0.417198338906746 0.617190006291494 0.622702986472286 0.615130803289358 0.559453970799223 0.137302742665634 0.793262515524402 0.0265915208915249 0.792758314481471 0.492447982549202 0.524731192304753 0.812555287773721 0.84494009235641 0.701387562113814 0.355212791599333 0.755731501930859 0.0779526592744514 0.773050475060008 0.793119366888423 0.152041186348069 0.497697286726907 0.890349425280001 0.734731314736418 0.919488659452181 0.833640963674989 0.755167480460368 0.362798625130672 0.43130993056111 0.506899167073425 0.270644476916641 0.930110652712174 0.682353316214867 0.227723016110249 0.180819240645506 0.926418266659602 0.609479263313115 0.795149912687484 0.793927922756411 0.448877459431533 0.730646925575566 0.576525568359066 0.689548170068301 0.153897899270523 0.183976145335473 0.562020383591298 0.40619528148789 0.971934544830583 0.933478708837647 0.0296671569114551 0.657371073907707 0.816289497322869 0.997781755225733 0.482894948949106 0.136098326002248 0.41169555200031 0.114022412982304 0.0834576301905327 0.550958297981415 0.119459110489115 0.267099379552528 0.523710742322728 0.78769428900443 0.252122465528082 0.192746928224806 0.584603645163588 0.58897860487923 0.403451030610595 0.450815284282435 0.821133329449221 0.674865827197209 0.241482332886662 0.324992304386105 0.690327736579347 0.205067975649145 0.786728085442446 0.158860941673629 0.0181384843215346 0.240278504695743 0.603217976887245 0.879586560286116 0.454889409404714 0.456950338177849 0.193791976033244 0.184665700914338 0.899138280013576 0.420306038262788 0.0399479276500642 0.357039164421149 0.276129194283858 0.403731001284905 0.584774598374497 0.181381541416049 0.93433807940688 0.242265906219836 0.706611114339903 0.218421689909883 0.488690310167149 0.288466732767411 0.61361683489522 0.773881069717463 0.937006122292951 0.404446853031404 0.582676023037639 0.899627141125966 0.781456329876091 0.926292926634196 0.646415905884933 0.199237921293825 0.760030270020943 0.985124927440193 0.0750007638242096 0.68901088318089 0.771337112693582 0.0355714007490315 0.891445465276483 0.803156050404068 0.619339488991536 0.375984832651447 0.222129101487808 0.243212666218169 0.64811524518067 0.714442740811501 0.671302471742965 0.75447042433545 0.856939275537152 0.446519017373212 0.742736962405033 0.206406934221741 0.6971742080478 0.7129002150218 0.68654970507836 0.983290560336318 0.966447536500637 0.786692958730273 0.373039499602746 0.817095499685966 0.279095634892583 0.31467292727204 0.488707592771389 0.251093746044207 0.183166011909489 0.214178476340603 0.062647383606527 0.0420465663750656 0.561054408226628 0.128157869696151 0.491388725193683 0.742200148508418 0.7982210698165 0.961344070460182 0.895366727241781 0.185803405130282 0.827669176890049 0.186204417883419 0.320365176266059 0.147347617081832 0.397106686586048 0.727708279399667 0.25576814166503 0.470613005785272 0.649732355994638 0.801472762599587 0.146402155733667 0.170121088260785 0.7826544171758 0.347910875864327 0.633387401609216 0.741425613171887 0.78784305613488 0.720893795201555 0.321875976405572 0.68568623410305 0.551693634320982 0.398813661502209 0.0564792376430705 0.545410623049829 0.571096991910599 0.0731156336516142 0.186181293888949 0.762728914166801 0.92134497936815 0.769350025344174 0.0732172081945464 0.202875903262757 0.504490903548431 0.0953016541805118 0.551254509619903 0.971596146423835 0.455713794790208 0.66336036457913 0.890278823336121 0.58911407870939 0.958986133893486 0.600854973648675 0.69051258216612 0.231758038355038 0.431571107918862 0.097368769175373 0.75055311986478 0.157348206928 0.419607493092772 0.194930332570802 0.189200981690083 0.945333147845231 0.243443197829183 0.914962986013852 0.926672883459833 0.428304516386706 0.8081023394363 0.854467970544938 0.533532322209794 0.181779776616022 0.272242165834177 0.0211609411472455 0.639807146405801 0.402458346479107 0.595749133895151 0.122521760468371 0.245016178509686 0.790573052056134 0.935928234125022 0.0601840150402859 0.524873895840719 0.42204843654763 0.27174416461261 0.912305819611065 0.979387189501431 0.290854299718048 0.0962464355467819 0.755672083038371 0.472443199413829 0.273297875297721 0.358655604703818 0.11194216419477 0.581993699469604 0.0436712632514536 0.389473383403383 0.548389210670721 0.911457501628902 0.567247140952386 0.301336361924186 0.675796487759799 0.791927155554295 0.824383134418167 0.164874485339969 0.0891569191869348 0.812613650735002 0.271784455960151 0.806673980762716 0.677698291549459 0.167810427953955 0.707953157725278 0.293996917412151 0.461022791697178 0.89755029063439 0.359110863876995 0.059858898408711 0.0479794973810203 0.666662779632024 0.235228102367837 0.619919561722782 0.101013588765636 0.301586437828373 0.165258437693119 0.629733351783361 0.315085893184878 0.930155862518586 0.880421044440009 0.606159104190301 0.252901874836534 0.0396100252843462 0.96830388937844 0.461282196030952 0.721811362770386 0.0266070002759807 0.796693449229933 0.022933658096008 0.109721043673344 0.976457190851215 0.477109782849439 0.825465457681566 0.857212203212548 0.653786603747867 0.379434858174063 0.177574614603072 0.0299543243297376 0.399168999986723 0.777556938433554 0.787070070696063 0.170189333318267 0.544692316453438 0.681868857236113 0.157763706292026 0.153551281611435 0.0160188251663931 0.869143129810691 0.957511369797867 0.774813151326962 0.353683982542716 0.58166669341037 0.923004183135927 0.732266262811609 0.0165881041646935 0.330252872291021 0.894486758061685 0.683165924083441 0.156151379784569 0.728544001581613 0.921161156059243 0.607223156455439 0.213950724126771 0.127490958666895 0.59495145289693 0.384290224406868 0.234407700293232 0.706433549399953 0.335450752549805 0.503277281774208 0.557243115699384 0.143507308459375 0.134679995793849 0.328517888113856 0.191121139919851 0.414657162202057 0.380051032181364 0.42642662306549 0.551232140520588 0.224816205995157 0.39059649474686 0.520027654273435 0.864075566583779 0.574931857450865 0.88350326268468 0.80873231661506 0.704727261150256 0.721945966915227 0.451357639224734 0.466773783059325 0.588913743826561 0.619837728783023 0.771430246471427 0.839206717596389 0.47639615314547 0.190161979126278 0.686293397543486 0.0653842431958765 0.982715056161396 0.673894751737826 0.594301956088748 0.103384033080656 0.12167153530987 0.555187480873428 0.536486412733793 0.615936135121156 0.244129645545036 0.847097424813546 0.0965297139296308 0.467217500519473 0.832491872413084 0.73775735956151 0.587337158781011 0.138042369114701 0.952523525112774 0.118530708618928 0.541940122235101 0.54709945143899 0.773752933237702 0.974475184464827 0.711042877899017 0.645667385964189 0.84513201782247 0.135686650210992 0.874703388556372 0.228122484497726 0.149534898938146 0.65045207695337 0.147204153118655 0.0698702052305453 0.76255270227557 0.515198660735041 0.194929206566885 0.906336966198869 0.127433963506483 0.33783579250332 0.717364960699342 0.949823874593712 0.795211618163157 0.873949237233028 0.0348883833689615 0.119443553886376 0.598378704788629 0.274120889655314 0.302421951175202 0.3470778775285 0.249497161924373 0.39852055150317 0.938822572450154 0.464505065649282 0.0143425079830922 0.830070366759319 0.706474924108479 0.987671202165075 0.455626464600209 0.267760613078717 0.860995605417993 0.869993857925292 0.0150475194351748 0.843528971108608 0.941893874334637 0.582295075512957 0.725559817133471 0.652570099080913 0.219215125746559 0.54831402080832 0.524581113616005 0.594424836654216 0.378210663718637 0.969982694603968 0.949938459841069 0.156175208655186 0.674432832475286 0.191772712632082 0.102249396389816 0.695085941466969 0.540672091997694 0.823591378482524 0.782517869435251 0.623525333064608 0.743447710368782 0.305692328477744 0.358362136965152 0.0240049511310644 0.712164532006718 0.794657022855245 0.783863659405615 0.595299287608359 0.353448868545238 0.579956147552002 0.57112888951553 0.331162978499196 0.56124985069735 0.602349464134313 0.146418788090814 0.538211039518937 0.992348549368326 0.878668910658453 0.927746082057711 0.345718671861105 0.936352872906718 0.48527894634055 0.0591040682559833 0.203085939758457 0.215053387838416 0.828320263011847 0.876580039008986 0.960113965924829 0.857598871805239 0.191115314664785 0.086795467690099 0.984767834832892 0.169659380784724 0.35492082120385 0.360215477177408 0.772852981348988 0.219130277605727 0.0282993770181201 0.444758857269771 0.401489492370747 0.0425822473526932 0.028920788730029 0.320107652370352 0.192751119448803 0.258324191763531 0.222987960802857 0.244453486346174 0.159024999176618 0.631119771017693 0.950919883011375 0.471141419024207 0.71866771611385 0.257197825496551 0.0549759820755571 0.191872272123583 0.290968793686479 0.343413821596187 0.187956121547613 0.4016166319279 0.221252566331532 0.139515417120419 0.53883684322238 0.175064673500601 0.563114189559128 0.304758176726755 0.190916607128456 0.336098805491347 0.224214182526339 0.209725688202307 0.808741455802228 0.717537466573995 0.22451922609238 0.299267563570756 0.0595002655847929 0.488300099675544 0.461086789749097 0.66744063397171 0.683347980361432 0.184537676458713 0.637378898558672 0.69772484931862 0.474527763435617 0.494057620938402 0.735083147280384 0.75140675323084 0.254299754647072 0.849848379851319 0.989940144775901 0.645307888756506 0.320003605689853 0.26297775389161 0.191200006986037 0.845902670808136 0.284341232362203 0.49571185230976 0.88885264152661 0.815695624416694 0.197144070563372 0.787212301471736 0.398203082247637 0.551258699230384 0.567200540525373 0.948311475689989 0.381409373925999 0.603215616082307 0.991141070250887 0.324802202193532 0.619071437593084 0.79398044017842 0.969654382748995 0.560652298512869 0.86860907871509 0.385330465089064 0.192958355802111 0.216875019227155 0.618391692424193 0.131424086892512 0.162599025045056 0.408150896970183 0.956732131291646 0.173404953177087 0.644881273878273 0.285610224946868 0.258316679692361 0.773314991474617 0.895120058853645 0.525978299153503 0.738277766993269 0.36267644736683 0.940048230595421 0.108847281690687 0.472051350281108 0.77230032548774 0.64162296199007 0.402386273699813 0.52697926938301 0.994429464538116 0.213976769968867 0.311838953359984 0.770881314375438 0.217053167799022 0.953114402871579 0.261432601066772 0.574795740749687 0.355256878628861 0.171539280859288 0.835623551849276 0.510416191327386 0.44167597333435 0.662694423964713 0.875814651618712 0.721046149178874 0.533713902269956 0.278518340175506 0.565315760024823 0.338816697504371 0.932867827394512 0.12616951066535 0.958168697692454 0.0819709827774204 0.41258293597959 0.201126422793604 0.108253618080635 0.556259367913008 0.847155795381405 0.69567450129427 0.578308142048772 0.357065902922768 0.745457309267949 0.284306528391317 0.0384179409570061 0.453839905064087 0.385194719266146 0.508140513207763 0.200557109680958 0.372521630693227 0.392981120257173 0.259411331142765 0.555871049384587 0.739275083760731 0.494027641804423 0.903035934621003 0.0837889245152473 0.633652165583335 0.174239230339881 0.433003175375052 0.98071511346614 0.798999039176852 0.163491328866221 0.97872095960658 0.683156744327862 0.330327654855791 0.338381561185233 0.975144827868789 0.176071047857404 0.291918628355488 0.766809475836344 0.942752764767501 0.78170345419785 0.2285987302172 0.682600346952677 0.508990041788202 0.743027574219741 0.923239486145321 0.803423614290077 0.856423441271763 0.983324277296197 0.944251404064707 0.422015380207449 0.621093250350095 0.649785088244826 0.400611606240273 0.216196825338993 0.586984877448995 0.328187928397674 0.543330522705801 0.475460481001064 0.842498945598491 0.688931010433007 0.825916503272019 0.886197271198034 0.823349587293342 0.359431661586277 0.221766152738128 0.137174352402799 0.0512924496177584 0.169707009252161 0.72763068147935 0.703363283623476 0.400833810723852 0.688796227648854 0.0284041583095677 0.168162221773528 0.8880453361338 0.791900026812218 0.334440973903984 0.581128905871883 0.0308898196788505 0.0677918142918497 0.802265035782475 0.631709496956319 0.403258190741763 0.676880849585868 0.933785424928647 0.573749772545416 0.607611441100016 0.251940010711551 0.0546817384660244 0.758827148780692 0.913791603562422 0.871538464229088 0.428530873369891 0.436354719926603 0.607003306553233 0.512033250278328 0.232118439362384 0.681809749752283 0.583446783206891 0.877225956807379 0.508187659925316 0.39000791140832 0.314838160106447 0.0141711705247872 0.576848825067282 0.810782131487504 0.847089668640401 0.0721803217823617 0.857613980080932 0.773341494633351 0.173649299254175 0.324513443848118 0.456192049798556 0.958165054142009 0.916247074657585 0.441827955511399 0.384014387330972 0.668645531001966 0.890607288936153 0.708715652541723 0.525375066930428 0.735533293911722 0.956314171776176 0.334314840028528 0.349407566264272 0.163267905025277 0.248160715366248 0.267976497649215 0.273370105049107 0.620994148175232 0.870890522850677 0.905872775751632 0.217126298353542 0.772502077959944 0.848579105592798 0.428417324461043 0.53503168044379 0.968923381236382 0.574565074064303 0.152271757835988 0.926654253799934 0.777311713681556 0.219955584770069 0.0990500785782933 0.628338010495063 0.0534977316320874 0.254506440560799 0.0624321866245009 0.356809899881482 0.194750667063054 0.502863359046169 0.834255210913252 0.557856030634139 0.873863857092801 0.206901039953809 0.0149223091825843 0.396919388223905 0.468596736839972 0.492032022872008 0.856945130066015 0.970803677544463 0.201276387383696 0.743502379299607 0.307598699901719 0.895147799118422 0.534548965906724 0.175248311255127 0.661174813564867 0.166748253821861 0.793334080046043 0.933466327865608 0.337172988564707 0.381278631847817 0.867832289757207 0.215042834980413 0.36814766167663 0.460732855023816 0.871066297478974 0.269163652684074 0.29643856620416 0.291053343096282 0.284211935533676 0.599555058483966 0.547621579570696 0.478389756565448 0.641700487993658 0.839578675990924 0.127635773834772 0.286776594433468 0.710678400457837 0.99346257039113 0.170153240801301 0.893750733672641 0.995731531211641 0.399490696655121 0.368362758620642 0.703842172974255 0.636428356708493 0.984323716529179 0.883645756002516 0.155299077108502 0.434740672258195 0.98542937700171 0.888733050690498 0.865091984388419 0.0580508161778562 0.697911736695096 0.87011455793865 0.13108121558791 0.0811237417021766 0.421242512324825 0.380690875551663 0.913473221748136 0.912408435102552 0.412693712406326 0.208498284232337 0.798945194522385 0.687358863940463 0.0847435861336999 0.304764366636518 0.689800192103721 0.0724904721276835 0.747800506593194 0.0682826383621432 0.780105962359812 0.526535161451902 0.125890183784068 0.715265157015529 0.851588247681502 0.772346376397181 0.556842040941119 0.44431791667128 0.042908756909892 0.402142493044958 0.0538222892954946 0.858062875545584 0.190194348799996 0.466379443118349 0.480393486414105 0.0997146089794114 0.573978953873739 0.94263730822131 0.826009198173415 0.188710830686614 0.123989378530532 0.525414236653596 0.972155481551308 0.342151500440668 0.91849639713997 0.342437129716855 0.936239351658151 0.918011194791179 0.727778517149854 0.935801331293769 0.258434733769391 0.664019038146362 0.0409701674827374 0.859606122577097 0.354527837308124 0.861243159165606 0.353003521203063 0.139112808830105 0.456076738468837 0.402151861812454 0.104071131274104 0.148892300142907 0.582617396151181 0.112632213509642 0.972787091839127 0.832738952708896 0.639778812136501 0.444392311992124 0.155995911720674 0.227511483193375 0.947288927906193 0.814710188892204 0.524403636727948 0.280492136529647 0.809723401982337 0.985214379404206 0.848003035534639 0.214368908151519 0.245315271196887 0.546276251296513 0.0252954961452633 0.152562987166457 0.445334033439867 0.688311036364175 0.82528091751039 0.164475839845836 0.607790124206804 0.380735393159557 0.565221937275492 0.412331195387524 0.138419574203435 0.132196174985729 0.93058039250318 0.522874797245022 0.263844247905072 0.461629028979223 0.317385975739453 0.625486362355296 0.610168026885949 0.457339779944159 0.172357370303944 0.877503150620032 0.781303454732988 0.754204706081655 0.137247065287083 0.512261358618271 0.503635856281035 0.971973296883516 0.266687068957835 0.0109819888230413 0.0172295557498001 0.989723360554781 0.648673171016853 0.421448635351844 0.368949650533032 0.532783294261899 0.0468007782706991 0.905219948876184 0.668262445107102 0.778158752145246 0.789695381214842 0.842695264439099 0.0638266893452965 0.177698992050719 0.647113249215763 0.104420933322981 0.291756262739655 0.76740399484057 0.913805526364595 0.0540772458561696 0.715748913884163 0.370266162096523 0.413799663311802 0.820122685728129 0.0602284750225954 0.875640409139451 0.708469556951895 0.854743522258941 0.0222288672346622 0.939246744234115 0.0725732789398171 0.595114459770266 0.267732520145364 0.629631034792401 0.771213719490916 0.049233668204397 0.811358616219368 0.223940923849586 0.700494485418312 0.32022269239882 0.808764837959316 0.135917982817627 0.286856747011188 0.472056255370844 0.416547776486259 0.800414497326128 0.469974982230924 0.055047309640795 0.868366704124492 0.0328795587271452 0.96745077971369 0.608256601928733 0.999409638105426 0.957076014732011 0.286363691447768 0.916693504208233 0.472050090124831 0.904797618805896 0.483997988610063 0.502786202307325 0.793355465822387 0.160130089155864 0.115488059788477 0.448254356754478 0.490840440578759 0.273829663321376 0.499416591443587 0.154709310370963 0.0464418033813126 0.970225304537453 0.0646269153198227 0.189428062681109 0.774472075405065 0.236553164646029 0.11048322201008 0.272052218539175 0.551081773703918 0.799752123043872 0.150349931230303 0.940385502767749 0.12349856344983 0.2741424964834 0.77427445607027 0.187303426058497 0.414954985973891 0.125688125665765 0.127925888686441 0.870432897571009 0.502662864886224 0.186859692002181 0.389739629968535 0.494350230516866 0.0999478605180047 0.925894890127238 0.880059787807986 0.327030889876187 0.681333793313243 0.727023412238341 0.151840511474293 0.287695553775411 0.976622910506558 0.516119924178347 0.0370396201917902 0.433027482077014 0.643336532039102 0.625694730014075 0.199950945929158 0.537219761221204 0.795275486903265 0.761806661637966 0.539358518647496 0.238105639377609 0.679849430408794 0.280993829246145 0.122149098580703 0.040054225185886 0.50347345701186 0.402027441491373 0.759564398289658 0.176895189371426 0.429515888919123 0.593125160750933 0.374628668923397 0.494279540060088 0.804220759831369 0.984742157794535 0.803561295641121 0.624977478887886 0.554395266007632 0.179196738612372 0.589865192933939 0.438906879145652 0.972294932699297 0.371355012494605 0.44864196925424 0.639724326916039 0.248320628667716 0.528025187798776 0.688764474568889 0.956946287094615 0.742845708336681 0.193544897811953 0.649885309969541 0.662103842862416 0.451412904004101 0.534154302109964 0.223045976166613 0.557259949976578 0.54174502113834 0.961927703069523 0.928713873780798 0.65708123934688 0.0973339181439951 0.901986327245831 0.0958276434568688 0.267306651403196 0.0673418287816457 0.188975159702823 0.375553071117029 0.828735272327904 0.451228566905484 0.436764866565354 0.166426887463313 0.522522623096593 0.530144372580107 0.436781104994006 0.654181014683563 0.855344424103387 0.710882503592875 0.403697024779394 0.154639403622132 0.344678477048874 0.109261263427325 0.501076124138199 0.509055835222825 0.0354731233115308 0.931602808670141 0.0428543265489861 0.581593542341143 0.0107191868848167 0.638239344190806 0.704457913867664 0.811311741725076 0.242784624991473 0.158477311332244 0.935283244098537 0.878265484084841 0.230416709065903 0.977538592796773 0.503870170665905 0.580045546269976 0.195232283717487 0.666735616987571 0.902519726480823 0.0252731503266841 0.638929827080574 0.994215075927787 0.23146981223952 0.333066816010978 0.938528124846052 0.941513118357398 0.850584426138084 0.0924011024343781 0.900685946696904 0.530758475984912 0.717436667671427 0.567550680490676 0.825958139139693 0.751722947808448 0.866128830232192 0.670191115327179 0.861128777221311 0.519418484540656 0.0869717270648107 0.585730164484121 0.0434949865890667 0.548768781404942 0.364621232235804 0.238508193499874 0.133180697490461 0.575080550359562 0.549621693759691 0.0669460516585968 0.0530384294479154 0.157058904366568 0.499637466850691 0.27126497929683 0.192041059534531 0.583914261769969 0.977806992484257 0.147463521955069 0.899678936845157 0.253320984328166 0.580586237215903 0.360809452887625 0.547038051148411 0.534703031824902 0.357519928447437 0.415771918296814 0.252391265367623 0.574149376007263 0.0475202037254348 0.684619263217319 0.13104652706068 0.199246588873211 0.089474713220261 0.355563235597219 0.640170287163928 0.223483553966507 0.0879817375959829 0.423789244135842 0.346112084491178 0.447000546436757 0.651271987135988 0.912178289121948 0.966113870998379 0.554283245790284 0.219837174566928 0.317316978322342 0.707951240176335 0.444459031124134 0.0816061798669398 0.251430734929163 0.213874755166471 0.299083746946417 0.252580404060427 0.861537962204311 0.835318296912592 0.477273270781152 0.950807438900229 0.598142662558239 0.446635230658576 0.701404867768288 0.343233567385469 0.129490260104649 0.986406561003532 0.0741783310240135 0.103151500709355 0.204292617188767 0.0108534459676594 0.881275747567415 0.452549789936747 0.144926839123946 0.172148759926204 0.932877481984906 0.472278919476084 0.797634403104894 0.0876884028571658 0.849133043508045 0.115626013132278 0.556747812968679 0.507669866390061 0.096123201160226 0.705980056796689 0.141320974428672 0.385275669151451 0.33712823884096 0.439235252083745 0.877717964968178 0.368057913517114 0.551485798200592 0.769631943532731 0.155590076628141 0.159039009569678 0.195410428831819 0.825234701100271 0.920014334784355 0.676207608501427 0.948416369005572 0.127251891554333 0.50138179697562 0.0166455921391025 0.639939766617026 0.289846384453122 0.353994347485714 0.832059119718615 0.033020772987511 0.974323064447381 0.4443618944427 0.12737371180905 0.71822072713403 0.0631517146527767 0.886973566650413 0.779864175550174 0.0280112523236312 0.470926103563979 0.611179879822303 0.358321724834386 0.435967791096773 0.0214606672548689 0.0802711621928029 0.873917520802934 0.947981900221203 0.896938143041916 0.197607213607989 0.471763919629157 0.430754753004294 0.485345466779545 0.136738324961625 0.100999879869632 0.922538211366627 0.425876170806587 0.689222938185558 0.108239006537478 0.886629903109279 0.40273307368625 0.967347256965004 0.349173061253969 0.502312800064683 0.484555284483358 0.918904136412311 0.747539484363515 0.115614813484717 0.576188797759823 0.841516094696708 0.883327488056384 0.01620643355418 0.597236498170532 0.295507877750788 0.194572369356174 0.752039304890204 0.97039210755378 0.42587431503227 0.842535102886613 0.959833844271488 0.485645531264599 0.495451607794967 0.214219092696439 0.909653076778632 0.500164531189948 0.048193321491126 0.285175653358456 0.829896376910619 0.415059658007231 0.0931665220949799 0.242911159479991 0.917907358098309 0.0458252635668032 0.0348291776911356 0.505544776599854 0.185496017355472 0.124406983302906 0.619983206414618 0.518351722720545 0.404793514024932 0.35369099004427 0.271645275421906 0.264690246111713 0.0471291816351004 0.909158703663852 0.162306053808425 0.483109985040501 0.459478865836281 0.148666596633848 0.660042130381335 0.653975455926266 0.529779197638854 0.025355316803325 0.410998103560414 0.841687818707433 0.357958599519916 0.789500317689963 0.661743043086026 0.739821520899422 0.0986291822325438 0.908991211445537 0.708404272005428 0.453322260433342 0.74010610000696 0.116372984077316 0.91370227699168 0.903938997599762 0.821906437976286 0.425658971450757 0.533695359278936 0.380108301639557 0.739842064881232 0.586342026945204 0.0534214641712606 0.804281179334503 0.0868396443850361 0.174886095733382 0.206544558638707 0.0393276352575049 0.575135094819125 0.410912018774543 0.0552419209200889 0.282686685663648 0.989626050766092 0.802585449013859 0.831749329878949 0.079133156479802 0.846092255522963 0.620547063536942 0.187792638686951 0.392471471291501 0.678382249148563 0.614173799536657 0.88925893393578 0.958357031932101 0.200838058376685 0.534074997089338 0.822110055903904 0.555115929490421 0.408519229793455 0.541134235353675 0.158444160716608 0.572527547732461 0.390745558994822 0.560055855275132 0.903934887973592 0.260536773325875 0.779925361934584 0.365749032688327 0.84814798024483 0.250671141906641 0.0162006223597564 0.661719826890621 0.49332731485134 0.306054869238287 0.349321320818271 0.827247223460581 0.637065062711481 0.424409588621929 0.0541992502822541 0.682809006657917 0.582523661453743 0.949519323380664 0.732406863705255 0.0374670800915919 0.187616646003444 0.918746105392929 0.485884759728797 0.583327489488292 0.720283203960862 0.631356201644521 0.387251714516897 0.238892210393678 0.629886787508149 0.297559260500129 0.268080630537588 0.884678364060819 0.807932838390116 0.617356971811969 0.185002445927821 0.0157454793597572 0.873964207207318 0.291888983910903 0.600434736078605 0.916129390997812 0.469413775193971 0.638488959551323 0.729324673351366 0.382688226017635 0.0720026639499702 0.147554586052429 0.813881023579743 0.365299841950182 0.279776875330135 0.89211882022908 0.464023481956683 0.931830568721052 0.228622677105013 0.216348558343016 0.806451096066739 0.0731435640808195 0.263941531877499 0.914566429562401 0.115660534775816 0.563466275425162 0.677579762868117 0.832694193765055 0.307483668862842 0.503200214470271 0.474021606810857 0.478038293516729 0.609771689872723 0.626947178062983 0.914466979098506 0.0691763385664672 0.488178297630511 0.08899239952676 0.199308061311021 0.0539770840620622 0.845989758279175 0.333579397888388 0.440220362599939 0.619325264231302 0.595230197298806 0.454693732282612 0.366363734707702 0.136690632645041 0.294945772676729 0.537835901575163 0.24018066982273 0.299612394606229 0.994927420581225 0.912061159359291 0.815347032044083 0.413471303051338 0.239728002417833 0.225570370457135 0.592862827193458 0.659194744320121 0.74669668114977 0.114456281308085 0.0229988895659335 0.650006030728109 0.0367955355043523 0.410961181465536 0.142756224430632 0.172796385516413 0.776617585397326 0.992581228108611 0.499537074093241 0.989685070889536 0.263831589869224 0.342041549903806 0.688970380693208 0.666640461243223 0.417349889352918 0.930188915631734 0.102841976177879 0.227605559034273 0.740992561515886 0.38410922659561 0.0446423135860823 0.297290684017353 0.0728636178397574 0.808884476509411 0.0863020679866895 0.414074444225989 0.242063456708565 0.292465023312252 0.430917599678505 0.709311988134868 0.175957796066068 0.64623758812435 0.317833498101681 0.500848090481013 0.800184341203421 0.0150378334964626 0.920326772634871 0.989178663939238 0.938590575535782 0.163039576094598 0.240220005968586 0.431037915905472 0.0365885923500173 0.511506278831512 0.293351442178246 0.677809930054937 0.691462029130198 0.0535332439746708 0.990745763122104 0.619272108087316 0.363612459271681 0.592101590689272 0.527506428228226 0.686790405760985 0.438490297803655 0.358086026743986 0.420957492035814 0.225500071393326 0.537904141100589 0.0633409930299968 0.0760477626044303 0.604462217900436 0.792048909424338 0.932551804771647 0.380157182887197 0.782610110708047 0.0491032926249318 0.619167248194572 0.145964129606728 0.64783830906963 0.377497124371585 0.939005257999525 0.608036765856668 0.563942648381926 0.512145579829812 0.940097761398647 0.884887094299775 0.529521140591241 0.88781502188649 0.791987548319157 0.427325305116829 0.955976957229432 0.388253760500811 0.963272876676638 0.928351792411413 0.289585304367356 0.350652697016485 0.965257793385536 0.64393443205161 0.811608130158856 0.885802871556953 0.0800006135320291 0.661280050559435 0.440878165329341 0.132167296039406 0.776153463870287 0.896777136467863 0.390595473391004 0.755106377748307 0.739314486060757 0.909362495851237 0.615012365886942 0.268388916119002 0.0944445404596627 0.879637636607513 0.10999086279422 0.574416205051821 0.250122498169076 0.826006294074468 0.558769854153506 0.0999216457176954 0.811017217594199 0.139506968057249 0.341970881575253 0.81481922064675 0.400868327296339 0.274091085011605 0.477032020811457 0.318465463824105 0.270816264546011 0.541971097830683 0.779559373089578 0.966908809018787 0.319706702083349 0.138091909829527 0.524041592930444 0.893428010116331 0.590961935732048 0.52818190633785 0.462916349957231 0.820244041059632 0.407912959780078 0.966376031218097 0.309384620024357 0.302984673073515 0.55340207753703 0.905141334901564 0.175021021889988 0.341691413857043 0.914241671592463 0.397572028161958 0.598363100241404 0.973100118392613 0.243507493229117 0.0192290939134546 0.804394617371727 0.370953186529223 0.717514795055613 0.860100704757497 0.725754120692145 0.968188396643382 0.474554755028803 0.433906503200997 0.122671960401349 0.41260099376319 0.939471368300729 0.863024382111616 0.96488301133737 0.781141144207213 0.370483837670181 0.198783625620417 0.788539184257388 0.035970819578506 0.187526573527139 0.0733615515241399 0.993557469355874 0.0410364548838697 0.278486255402677 0.566905919814017 0.919035649290308 0.747523796143942 0.765971120856702 0.258063866111916 0.786516006465536 0.122360452858265 0.881065822404344 0.244792586171534 0.508868648884818 0.669647816016804 0.0161102963308804 0.234929090586957 0.0471726504573599 0.225105279898271 0.963615989778191 0.0510794647666626 0.350772988349199 0.659148859833367 0.905988976128865 0.25109471576754 0.650051551251672 0.157669538711198 0.325910303224809 0.921880938331597 0.672816377901472 0.520602021380328 0.707596633536741 0.462846677398775 0.290770504050888 0.825755055746995 0.906256651347503 0.207986799315549 0.441151770451106 0.102897968192119 0.446179552201647 0.181671234909445 0.0538690409320407 0.778282768395729 0.739120632442646 0.774105219640769 0.446468027259689 0.16219428345561 0.0306195508479141 0.337009218037128 0.101562466002069 0.647631837292574 0.48475086110644 0.874806937121321 0.901182725795079 0.88828564081341 0.392371425440069 0.225069857682101 0.583005395433866 0.807846488757059 0.930113095345441 0.133994354836177 0.642948864218779 0.298685935179237 0.242523513326887 0.605951468837447 0.910497230736073 0.705744744567201 0.85576619658852 0.831464797332883 0.750166708512697 0.784370869426057 0.564853636031039 0.648067025935743 0.858589080802631 0.748129881294444 0.48180849761935 0.686592078784015 0.855814236963633 0.0231577865825966 0.0165900991624221 0.717897538193502 0.842433726345189 0.887984372875653 0.214907176748384 0.841412291196175 0.424352695113048 0.0694035931257531 0.666905592407566 0.0899194709374569 0.134994177164044 0.768743565166369 0.518039609647822 0.810835245910566 0.65492989188293 0.622355079613626 0.177428108470049 0.540862716969568 0.110936170397326 0.226962901230436 0.553730204529129 0.241216394272633 0.408428807645105 0.21105954668019 0.0328667061473243 0.299595116612036 0.758835251859855 0.460627871812321 0.132201443577651 0.290185769640375 0.389762422270142 0.223186085168272 0.0353985691745766 0.579452242935076 0.728554835421965 0.984457924671005 0.553408152887132 0.0630123310419731 0.554547035431024 0.590220586969517 0.714928400476929 0.279438374119345 0.999512155863922 0.985147841677535 0.131559838016983 0.719443541341461 0.922796872560866 0.816413530169521 0.924662634313572 0.0438321524998173 0.119106449289247 0.840788148723077 0.453025243419688 0.333438738216646 0.142630897774361 0.762542006967124 0.0684851335128769 0.0166837022430263 0.200667169245426 0.407644407961052 0.532936910470016 0.512112894828897 0.566982162150089 0.178609502790496 0.614688596311025 0.271987692406401 0.524228843578603 0.644941530185752 0.161133592145052 0.374710706549231 0.979144356672186 0.279458266932052 0.597202886319719 0.54535186869558 0.674412013273686 0.422156268768013 0.379741258707363 0.19525894661434 0.630513264278416 0.224434482830111 0.747436458347365 0.146270708548836 0.416461062198505 0.142227206584066 0.629483665428124 0.66326624909183 0.744267680021003 0.552159461104311 0.46570935922442 0.590882275276817 0.191195886756759 0.661459354178514 0.10954940748401 0.490202646374237 0.270685909711756 0.767398446879815 0.330908504379913 0.537408017781563 0.797257500435226 0.0153675265214406 0.240978861153126 0.577474640756846 0.634357921557967 0.827171561759897 0.281325801708736 0.156566184414551 0.529196652770042 0.126433687550016 0.983450479861349 0.770337289443705 0.80317280262243 0.371772126988508 0.807274082072545 0.217915839161724 0.52597601971589 0.610106554217637 0.712586867148057 0.414546530530788 0.526080606002361 0.918235774370842 0.31622489213245 0.476808581757359 0.29478828241583 0.809451304806862 0.320468113538809 0.96240577851655 0.0501769423158839 0.931330878839362 0.864353094163816 0.110834570960142 0.208817433849908 0.580127636680845 0.12103273242712 0.970299226406496 0.460013835253194 0.669162984776776 0.13965164745925 0.659596609240398 0.47216722403653 0.804189960800577 0.10497356567299 0.739897463582456 0.40622462074738 0.303667722032405 0.743359860857017 0.217917055292055 0.980063107640017 0.961026322988328 0.78332815222675 0.433247269743588 0.379036885977257 0.0247945843706839 0.556688198379707 0.261161182490177 0.0166406344948336 0.52191515723709 0.287325301559176 0.535864452656824 0.0447392711672001 0.712023627771996 0.0135561278229579 0.208306861261372 0.772734282787424 0.747423150294926 0.66146301755216 0.504556712426711 0.591595557613764 0.865096445991658 0.903935103954282 0.716003941209056 0.703874792051502 0.159418224177789 0.840612170330714 0.442725072451867 0.678271048367023 0.0128068502410315 0.967495065897238 0.610634680020157 0.516776915770024 0.275336943920702 0.578341383251827 0.421954083873425 0.607513127934653 0.786195105491206 0.686565601211041 0.477124879830517 0.575473194033839 0.554609188772738 0.294678980743047 0.574506468153559 0.687941900701262 0.0769631196558475 0.331932997603435 0.617836597617716 0.47126144597074 0.931172759768087 0.739681810897309 0.640350680137053 0.360264585700352 0.173489060252905 0.11772151080193 0.330605035836343 0.980108952249866 0.912271965271793 0.501815569412429 0.143316239770502 0.917343215844594 0.409422545863781 0.208770548983011 0.612692827782594 0.0189020270016044 0.720245149638504 0.807495206652675 0.131072427916806 0.342090079635382 0.135603538444266 0.964008700989652 0.262379620149732 0.251655147625133 0.273619144845288 0.934617643936071 0.105227361884899 0.368342481330037 0.293683339958079 0.44384258858161 0.63352958513191 0.371333913232666 0.632680025664158 0.719408877247479 0.0727623560884967 0.502431854060851 0.924859473628458 0.497860855795443 0.507890072879381 0.207821957413107 0.537740755281411 0.889233151096851 0.404698379717302 0.265543123430107 0.0848862225934863 0.937462131520733 0.0317243709089234 0.174978345995769 0.188286379994825 0.443020667727105 0.32287642500829 0.131695493482985 0.237215560826007 0.286216930840164 0.595782796456479 0.508282675754745 0.324085952138994 0.0494450003537349 0.366496307665948 0.847996145128272 0.873227213325445 0.809039536584169 0.501460749327671 0.412935724186245 0.0871469551720656 0.370010414912831 0.372608935066964 0.603258924244437 0.324544000851456 0.2307846498047 0.942122315750457 0.499723217869177 0.499237586094532 0.998872323788237 0.796366463685408 0.585695290633012 0.0123496852745302 0.0172695204755291 0.622869986568112 0.930295674633235 0.792725609887857 0.958943939979654 0.969443699233234 0.803131128721871 0.29422429068014 0.588615106842481 0.445319965882227 0.465869390312582 0.222778959954157 0.0791387918009423 0.60929307528073 0.914709678005893 0.202778284600936 0.194666898595169 0.43246073238086 0.508531994228251 0.164597938316874 0.716442227112129 0.790419379835948 0.443738610590808 0.114823557047639 0.656271090016235 0.338096884344704 0.234080795655027 0.583270964322146 0.5801436091098 0.710532240769826 0.349775235240813 0.962399321224075 0.0606401697150432 0.340495469537564 0.843277707195375 0.568275152563583 0.64249299836345 0.271963891887572 0.442864675500896 0.380280204520095 0.912842331088614 0.482079809703864 0.794769602501765 0.851837555090897 0.785321595447604 0.684147582135629 0.290695487065241 0.293798714214936 0.102316507375799 0.44515566888731 0.734705479573458 0.631017836199608 0.699710757879075 0.688750324721914 0.797623120245989 0.70746354033472 0.571259490526281 0.0162327449349687 0.340566517733969 0.124222104523797 0.592616224267986 0.233101556494366 0.268374528393615 0.284182212718297 0.14466639614664 0.316332340335939 0.342416474632919 0.0451302105071954 0.42172664306825 0.941456468028482 0.0755337647511624 0.975842470391654 0.868340867348015 0.0251046326034702 0.754448722079396 0.819584085207898 0.616375140191522 0.388346451253165 0.961343524861149 0.894124851643573 0.183068986560684 0.609859786482994 0.326121381821577 0.553579193227924 0.694229955363553 0.51031003647251 0.220953462349717 0.0912626101309433 0.226795605400112 0.639989949511364 0.577850395985879 0.72855913590407 0.224965931323823 0.761979422448203 0.517007861132734 0.238096230502706 0.0396359203779139 0.0102145854593255 0.342447503013536 0.859340816922486 0.247325582117774 0.0171651999582537 0.189738433386665 0.642897020324599 0.895858913350385 0.891522704074159 0.483109517581761 0.150586280720308 0.803740936485119 0.526512692545075 0.408146932329983 0.398759497832507 0.678395661157556 0.813588931018021 0.4549412440788 0.5780437869858 0.117746915156022 0.997272862999234 0.210037405041512 0.754042322025634 0.449601740879007 0.785189042543061 0.816340104111005 0.634989373260178 0.420986028916668 0.46757540149847 0.961041356350761 0.73264082749607 0.613595766520593 0.545048036880326 0.023458996664267 0.923195304379333 0.166949114480522 0.339023379038554 0.807346943630837 0.854982372007798 0.331270826163236 0.202164147081785 0.388536563357338 0.470696534069721 0.908988864240237 0.6502327927039 0.525766860281583 0.395970777522307 0.429793017960619 0.0483557788468897 0.711381167969666 0.241560980745126 0.563237565704621 0.598942809239961 0.518195467030164 0.047650224561803 0.420922338354867 0.792639475774486 0.23298399684485 0.0117398572270758 0.285145815983415 0.810446450703312 0.817573709515855 0.21290293633705 0.155828282583971 0.545803041753825 0.123258344056085 0.107372202959377 0.865155877792276 0.974294881157111 0.538568816257175 0.915533151524141 0.863965099952184 0.278447509803809 0.288324312749319 0.408950923099183 0.673289932967164 0.256454947351012 0.692348069511354 0.292129588935059 0.697034438806586 0.265287192536052 0.527634489794727 0.282443663822487 0.0659443060192279 0.752213871225249 0.557657652946655 0.761770132780075 0.336528174642008 0.115192376461346 0.939331627411302 0.739274102512281 0.454828999121673 0.402523466616403 0.226905344105326 0.800329242809676 0.800221356190741 0.514848110936582 0.405264868023805 0.94308661974268 0.863609007264022 0.0985192021913826 0.129214346040972 0.591756837563589 0.79049898220459 0.875638667002786 0.0524449589988217 0.706228909655474 0.610859569625463 0.888865374245215 0.414378433013335 0.149905054573901 0.874232683421578 0.0236781186400913 0.559427515815478 0.891092453943566 0.897503388018813 0.406545986414421 0.0702786791138351 0.565683487779461 0.765060345039237 0.121914399487432 0.447969547144603 0.0620596293848939 0.0701132060959935 0.876180398897268 0.730456615700386 0.624446628086735 0.21799525159644 0.468127402041573 0.0986454478604719 0.246454157428816 0.440998582746834 0.612337893829681 0.95543634073576 0.82534910909133 0.158580114452634 0.698226246300619 0.280835960269906 0.415642539639957 0.947045289240777 0.376801830437034 0.242170028311666 0.43934628782561 0.103447424680926 0.518068394088186 0.71050684586633 0.181109382235445 0.708495969753712 0.855823296166491 0.727567011662759 0.91117007189896 0.278987788611557 0.0699609014461748 0.291524641774595 0.919153636982665 0.613450674288906 0.966690170636866 0.703334114935715 0.497447446396109 0.397821211561095 0.343723388309591 0.474659974274691 0.719493522315752 0.513175538263749 0.998730055440683 0.655995922549628 0.526788600615691 0.841848406689242 0.610460339807905 0.471609159207437 0.437823585006408 0.550029250474181 0.852291592371184 0.269468547576107 0.0896220498532057 0.426465912419371 0.0833092018985189 0.837558980628382 0.342099686050788 0.469106921262573 0.920359674307983 0.231191067837644 0.646308897018898 0.0956647020461969 0.83653680694988 0.288965752809308 0.694632901800796 0.27472101240186 0.562069236948155 0.545450925691985 0.338447882470209 0.146780683444813 0.763047405008692 0.281703783129342 0.0491277037444524 0.832381791642401 0.155365255712532 0.93205934713129 0.270137021641713 0.138031426246744 0.808041396462359 0.384239546163008 0.549265579404309 0.878578199229669 0.808192197545432 0.0322843076474965 0.974259252180345 0.914797804811969 0.889721288892906 0.584500850341283 0.48211485182168 0.139232389063109 0.861721737107728 0.475784543084446 0.764775788059924 0.453794882886577 0.589782671944704 0.927498440488707 0.645245004261378 0.54111305172788 0.939917469155043 0.424556851033121 0.716270528917667 0.0964345017122105 0.903199621015228 0.630123824586626 0.955000399732962 0.607863345348742 0.798999212745111 0.216588717575651 0.922792660591658 0.996246230253018 0.547084210163448 0.914161577331834 0.293834988137241 0.139514167336747 0.335725444720592 0.440230936664157 0.954170021978207 0.913843759326264 0.176028607306071 0.34662860542303 0.545345051358454 0.138107001739554 0.036776746797841 0.385843073474243 0.626786963033956 0.418490324330051 0.507921177786775 0.35195666026324 0.101905546602793 0.410807294878177 0.613595220230054 0.709835260941181 0.0111889027035795 0.36760867760051 0.0862733722897246 0.378908579617273 0.562453194602858 0.194390302475076 0.205096332738176 0.13961958527565 0.349099385791924 0.773782358013559 0.207892052021343 0.347349733368028 0.626000503120013 0.0468400729261339 0.34246845083544 0.295227920215111 0.555964863144327 0.697968423212878 0.615305199513677 0.834623658987694 0.501080916051287 0.23473209429998 0.851508475432638 0.0854376095393673 0.906125977267511 0.0926504017761908 0.0486766867362894 0.840235663894564 0.6101157717756 0.880923306266777 0.955279805446044 0.899443754618987 0.308175920858048 0.431179888518527 0.353877504698467 0.688286223248579 0.773604926764965 0.423113902944606 0.990305865316186 0.725598348365165 0.74226882253075 0.784220983437262 0.314156853053719 0.803243648207281 0.48784112872323 0.12844738685526 0.427191134546883 0.0820091417478397 0.329240679594222 0.361699447766878 0.142674601017497 0.524918879293837 0.052748832073994 0.14804914771812 0.200607452082913 0.0245719191129319 0.179739318755455 0.48488018582575 0.905509615631308 0.795355605597142 0.71181702184258 0.623982880895492 0.0605390236759558 0.0532767329062335 0.218998103647027 0.439954043426551 0.774118207986467 0.457954124454409 0.455974615560845 0.606183423800394 0.637904127638321 0.722912506780122 0.652045845487155 0.404024100450333 0.449901554577518 0.108911155040842 0.6075520588574 0.103069166427013 0.123070198136847 0.916348388502374 0.0844431014428847 0.968223900918383 0.357356217389461 0.989316836260259 0.627218683308456 0.818959980537184 0.807325955240522 0.683433229576331 0.354850629784632 0.187078551896848 0.712827983656898 0.296293638551142 0.108726896774024 0.89765102960635 0.168338522177655 0.0697670127917081 0.188508479369339 0.356549788136035 0.254824425911065 0.0774375773686916 0.413417451020796 0.220081362749916 0.82282066648826 0.49019659130834 0.255034716881346 0.731440407282207 0.680310875573195 0.276564252693206 0.73889659592649 0.225505218971521 0.637193732343148 0.244086838955991 0.414078852352686 0.287054060699884 0.297768799571786 0.809771809778176 0.343430917263031 0.539975043479353 0.0719791271258146 0.545063484224957 0.472853387543 0.937040704328101 0.159833195921965 0.75560540816281 0.273371825518552 0.599709716101643 0.0198959314124659 0.594436427003238 0.068268719248008 0.267487316599581 0.197487562149763 0.354411575617269 0.0901648171641864 0.93543912522262 0.0328795704827644 0.249668974447995 0.746489960891195 0.859584750400391 0.449894917954225 0.8208314732695 0.526844411455095 0.247212637586053 0.345290765478276 0.526369741449598 0.202316849117633 0.49933058203198 0.238133430122398 0.96585932334885 0.158527711820789 0.252996209992562 0.0909824527497403 0.434403097897302 0.494426040430553 0.177845889346208 0.859592735001352 0.927060904640239 0.381011410949286 0.980252860621549 0.517443660607096 0.540815899178851 0.142265148190781 0.55973946799757 0.435833573734853 0.322815796439536 0.563265418224037 0.583062860127538 0.0915769652999006 0.260091695901938 0.560215624051634 0.132218748079613 0.0696104509942234 0.519338650747668 0.339210175597109 0.726619394887239 0.699399098434951 0.987967770621181 0.78046175585594 0.73548400813248 0.598588232565671 0.458121181023307 0.693238120402675 0.392471047167201 0.105583535940386 0.381195396992844 0.108674767748453 0.641947048276197 0.0370196335646324 0.599134557910729 0.399998466565739 0.476208298350684 0.293585384762846 0.725046778861433 0.856896571982652 0.863108029565774 0.936573620846029 0.4948187797633 0.756469332766719 0.533425791405607 0.825821581718046 0.0408186154230498 0.959392692071851 0.482555879550055 0.993636054287199 0.42532268951647 0.24067599767819 0.938694075234234 0.403515918171033 0.442568613919429 0.921251384124625 0.877972222184762 0.731991409519687 0.370335842492059 0.73560658604838 0.603703538819682 0.899799721222371 0.17523020345252 0.393677167934366 0.931821521734819 0.997593117875513 0.848000679800753 0.227680498801637 0.112649306410458 0.879357235124335 0.813500302408356 0.795589162781835 0.668556947340258 0.478769186923746 0.782191923917271 0.147036577458493 0.637242995994166 0.632637217692099 0.32771964837797 0.897943692430854 0.196515717043076 0.485854022933636 0.0283790227212012 0.490768373792525 0.938328859263565 0.790434383694082 0.81826867452357 0.309658335787244 0.480433570770547 0.225962120704353 0.30561988090165 0.0993940207967535 0.528813010442536 0.315357250217348 0.930181312512141 0.640141597921029 0.0998514994769357 0.437091749536339 0.537006390739698 0.210454418805894 0.0996113354037516 0.625635448961984 0.146510328636505 0.859164974296 0.597729280127678 0.327880660945084 0.712242942678276 0.496660445954185 0.507196457001846 0.171868305427488 0.837960457382724 0.793114336635917 0.144739689205308 0.975845471532084 0.454236234931741 0.411950795305893 0.863124104107264 0.529349216273986 0.572246983514633 0.0104595880070701 0.303295377776958 0.998709443460684 0.99337239879882 0.870437742499635 0.868628094235901 0.0291048835706897 0.825138892342802 0.322643334821332 0.470576581114437 0.291120290195104 0.0207599823316559 0.882125579488929 0.0644502447289415 0.813382797157392 0.261865051342174 0.225247751779389 0.429712759351823 0.543078850572929 0.454046314605512 0.0375198383885436 0.0626220852835104 0.649266214345116 0.324215427837335 0.809283336370718 0.840544578977861 0.464631007746793 0.482955966375303 0.878342899908312 0.344808546521235 0.112668093503453 0.215562621208373 0.748221052575391 0.520315840051044 0.58182788991835 0.311112211069558 0.109677494405769 0.12899453394115 0.282987355217338 0.972074650144204 0.56174348712666 0.469291923129931 0.524763898281381 0.840663979188539 0.736473445408046 0.672064635788556 0.35902586060809 0.635335606441367 0.150846425888594 0.0753985004476272 0.920045845375862 0.317293633737136 0.75156583441887 0.213247611783445 0.740249708725605 0.662590238752309 0.652767667935696 0.349683123510331 0.75282336757984 0.960019022473134 0.534799325098284 0.970029061532114 0.917240662588738 0.69767995829694 0.997966720443219 0.164618790480308 0.935372967133299 0.450568824959919 0.785737236801069 0.489416865289677 0.367805082879495 0.93676832547877 0.993923747711815 0.668288378003053 0.675588582258206 0.712082915969659 0.414625764787197 0.942508651958779 0.888162175463513 0.373845581258647 0.205899414175656 0.67963892507134 0.425432953997515 0.199459540070966 0.536124076889828 0.323392332803924 0.332233522862662 0.864044385841116 0.890096119577065 0.126983204430435 0.582149024852551 0.278300610433798 0.231398604996502 0.256566204144619 0.316363139597233 0.841699130148627 0.993074349826202 0.944338635138702 0.467846786421724 0.349845960964449 0.16734223068459 0.99058555731317 0.0870666995598003 0.502673125236761 0.16782550787786 0.569038271349855 0.190324688421097 0.232413365258835 0.474666707247961 0.37564480505418 0.732939803549088 0.54570009018993 0.864135431498289 0.56378098072717 0.623692057940643 0.303383098437916 0.619895840496756 0.325530513282865 0.401780609216075 0.193427849186119 0.746087272155564 0.663098045312799 0.114531335174106 0.553848333288915 0.296894997942727 0.209165334485006 0.80280265344074 0.217928138305433 0.784251746048685 0.344725732794032 0.485916270320304 0.564037366632838 0.492510994512122 0.302551778389607 0.979818698174786 0.774811258672271 0.101547595835291 0.292910846411251 0.744946378248278 0.831609973928426 0.642382422473747 0.465361225090455 0.0490174565510824 0.558630600085016 0.930591269447468 0.0562680707639083 0.181322933200281 0.179315443628002 0.431935346329119 0.444048947873525 0.679755813959055 0.573942367851269 0.682596304402687 0.422159508708864 0.805508968012873 0.716372725355905 0.498040955569595 0.33147410732694 0.350523378059734 0.55334734798409 0.0107356217014603 0.2784914156585 0.161373551762663 0.998781924920622 0.274961904401425 0.290217420377303 0.372541601185221 0.194942800442223 0.169242873433977 0.836174356085248 0.883791849075351 0.255598739043344 0.808398079928011 0.954000427348074 0.342757463885937 0.251711429380812 0.477641225119587 0.0754501315881498 0.353531815963797 0.470927302176133 0.864013146089856 0.886780714334454 0.110515465138014 0.517982506381813 0.441161709942389 0.203284273650497 0.640300905923359 0.177870032391511 0.981974773241673 0.622662586788647 0.567675248333253 0.318948988115881 0.499282925443258 0.929953194952104 0.340136991380714 0.388680596200284 0.427456034286879 0.578897120468318 0.369567772515584 0.443053799672052 0.522994834333658 0.781113260108978 0.0854633661010303 0.373457667261828 0.237922203773633 0.288562008603476 0.617239481082652 0.311493602080736 0.617070834739134 0.702944228760898 0.245458984563593 0.104288533010986 0.497850375315174 0.949717510212213 0.591208534969483 0.067519349695649 0.929135015611537 0.328027685477864 0.903693579917308 0.99211183199659 0.887802704302594 0.901821658450644 0.463554239359219 0.957452395313885 0.883829106551129 0.617807109453715 0.51923010397004 0.341023083624896 0.345772980747279 0.182193034114316 0.654830028358847 0.061663060716819 0.38778724221047 0.50400762243662 0.952805176379625 0.687944985283539 0.671228897010442 0.462913251314312 0.80135323031107 0.437758541395888 0.50566444672877 0.695483520887792 0.35378418836277 0.213885748283938 0.596654811000917 0.810631510657258 0.644905936245341 0.579991001118906 0.942578954941127 0.741549307641108 0.927920614508912 0.181559313116595 0.625861704524141 0.567951499391347 0.871830279496498 0.723170492602512 0.423184397474397 0.544243153836578 0.441452384684235 0.045919573137071 0.896032971658278 0.919733876136597 0.388058811305091 0.772605771510862 0.426060073177796 0.533892115382478 0.189656616351567 0.627670835310128 0.246222998159938 0.794760081602726 0.123751694431994 0.203379815025255 0.0379677164158784 0.70340289683314 0.984535556936171 0.103070741910487 0.420796586882789 0.419124704333954 0.391142260662746 0.785642250475939 0.304595616105944 0.421058624936268 0.925505541022867 0.976230142822023 0.260752844142262 0.31424057980068 0.954941282337531 0.39667741332436 0.726887764378916 0.817332970339339 0.780312183119822 0.0221233349665999 0.219440502172802 0.179401074324269 0.359572478691116 0.0953211774979718 0.0119420499587432 0.584969630551059 0.813828516530339 0.738224585955031 0.521237802146934 0.843323380311485 0.899209674654994 0.29485500846291 0.166584966427181 0.0479753003944643 0.885364643279463 0.562683721603826 0.200350303214509 0.736707718071993 0.389104925878346 0.0708246849826537 0.360276722800918 0.916492562182248 0.73812568616122 0.377179607402068 0.0294166647200473 0.197396413458046 0.58812615099363 0.975805899351835 0.727293202315923 0.780701706714462 0.493094397771638 0.722762375075836 0.0109378854278475 0.106430542133749 0.946481523858383 0.989664484495297 0.0692115113791078 0.752275269441307 0.256462378515862 0.813492037286051 0.936186838385183 0.202782004217152 0.858053195138928 0.8810855130665 0.0873865524400026 0.482181535917334 0.933818415575661 0.614449977064505 0.881339759679977 0.368129849839024 0.873488750727847 0.6766389316204 0.869158429633826 0.102531258335803 0.40132043388905 0.263116566317622 0.597361135394312 0.199715889557265 0.352922655681614 0.187194265683647 0.0762490575294942 0.272444550343789 0.616804800927639 0.329579058869276 0.919044950290117 0.20339351216564 0.930897739131469 0.0989395250473171 0.942009256889578 0.533329026985448 0.613212301218882 0.750814429991879 0.165912977661937 0.715147157798056 0.55775540622184 0.969629968402442 0.343532545052003 0.179036022010259 0.334373814973515 0.885393074820749 0.130955999803264 0.68336464544991 0.465754723006394 0.953291061015334 0.0883830087422393 0.883741990036797 0.438374738683924 0.855507937851362 0.836854532754514 0.68482392785605 0.702260215610731 0.128684046140406 0.283250611936674 0.133895794111304 0.655037291680928 0.511364583051763 0.571327654216438 0.59260336039355 0.430313426775392 0.961364821894094 0.389175464895088 0.767108764220029 0.561011151927523 0.566115910625085 0.257381961136125 0.436368554215878 0.786408431485761 0.409210888475645 0.590441497182474 0.884578844446223 0.527522529277485 0.624230535142124 0.506515034006443 0.692681982803624 0.247434766925871 0.0963008285663091 0.390952652897686 0.432212452550884 0.853106339762453 0.377897661367897 0.575243525423575 0.913770577830728 0.783039885081816 0.342052083860617 0.564479076417629 0.0490049197594635 0.0200277775968425 0.0360575937968679 0.395034799731802 0.830592303113081 0.945048517335672 0.364050819857512 0.939502409589477 0.487293344298378 0.113444063256029 0.743710008198395 0.353755113258958 0.338524082393851 0.923003893624991 0.745078078294173 0.125675174891949 0.705197096369229 0.494323208727874 0.782327202742454 0.387330631371588 0.222003789583687 0.264937419299968 0.985262212096713 0.671423252201639 0.148316792740952 0.432055260790512 0.73413844935596 0.734133148954716 0.988918579393066 0.850260928785428 0.294479838248808 0.785975360698067 0.134115386772901 0.293468329913449 0.339598001772538 0.484117046063766 0.711314665509854 0.610469026518986 0.971479275515303 0.456262422853615 0.299783328454942 0.374892987336498 0.223681218710262 0.942896829189267 0.300507124925498 0.781976446413901 0.749772334226873 0.85555161458673 0.716321649034508 0.191104413748253 0.252807141372468 0.260278137947898 0.359914626909886 0.390893464277033 0.477199614220299 0.14176703217905 0.245055144238286 0.409220420208294 0.602632686044089 0.62587431922555 0.627763359178789 0.954246227664407 0.97810465836199 0.838735326256137 0.201972871862818 0.773969816344324 0.774047018492129 0.527933230735362 0.707840853759553 0.579619759817142 0.632172936887946 0.324741845617536 0.985586179443635 0.202783363258932 0.276279255454428 0.926465737232938 0.522094675453845 0.225107619266491 0.644463450820185 0.303825006454717 0.51360725070117 0.7562628349429 0.73404357344145 0.836762013034895 0.429273602149915 0.122408161771018 0.127455107485875 0.102054531096946 0.883102720617317 0.844259034015704 0.593068512496538 0.402072883413639 0.83024467931129 0.366656659843866 0.970617096966598 0.543570053589065 0.0558508092095144 0.941664711907506 0.533896124279127 0.104772031947505 0.560175883374177 0.545508932757657 0.136726269458886 0.401688391915523 0.849753480886575 0.357315177139826 0.218051234160084 0.999409799457062 0.450056137281936 0.093436280132737 0.537895103103947 0.2098223475134 0.810485556116328 0.258464503146242 0.172184048220515 0.894742545813788 0.692097324919887 0.987887501178775 0.0470941074774601 0.348525767817628 0.923331231146585 0.442739573814906 0.0899791021225974 0.660277906151023 0.370202004767489 0.791232138683554 0.511214341858868 0.3375822023605 0.662624976146035 0.50335504196817 0.32153112669941 0.560282067963853 0.640161088737659 0.811485582208261 0.945322247389704 0.178020212270785 0.327514915049542 0.757359940551687 0.487709154610056 0.233929231378715 0.0269296973245218 0.487975360837299 0.968381619607098 0.36501722211251 0.111238305715378 0.490318485323805 0.228236761102453 0.864010964154731 0.312645943425596 0.77064577832818 0.573132328009233 0.0961102582234889 0.866335329669528 0.638168834678363 0.884035376177635 0.121429383154027 0.333801119469572 0.606991463343147 0.558625659728423 0.82078349443851 0.724946913032327 0.312367583040614 0.866791998133995 0.740528940639924 0.0626942362030968 0.56417866341304 0.998271414798219 0.5981720580603 0.681708327571396 0.238647517641075 0.236594415805303 0.534593675523065 0.856773432563059 0.399654515357688 0.28222882181406 0.493538203744683 0.114827078201342 0.259713674604427 0.689622122363653 0.203054332816973 0.853781118758488 0.199600914069451 0.513425268875435 0.854570964751765 0.335701600175817 0.0125738626276143 0.631625253653619 0.304776627055835 0.415689891504589 0.427894218538422 0.499940948993899 0.828245105419774 0.851196466316469 0.323842498566955 0.852928033065982 0.15489902831614 0.622198724576738 0.179249282772653 0.125673712124117 0.994308894758578 0.143955435659736 0.142742890792433 0.50468014435377 0.962045816155151 0.521488598601427 0.026872775463853 0.414018197045662 0.0672647557151504 0.823078244091012 0.154552463903092 0.0966242348705418 0.0793804808775894 0.222075044771191 0.70222046271665 0.978999715072569 0.104271048256196 0.323474315800704 0.483930147162173 0.730496224991512 0.382420796053484 0.957956727282144 0.290540722955484 0.996862230000552 0.81796952766832 0.359675777161028 0.959158242151607 0.60788160413038 0.0194353748345748 0.667785349756014 0.0691948022646829 0.979035448236391 0.306012076479383 0.755198741417844 0.804114387151785 0.0257856312440708 0.187502717687748 0.910913949918468 0.063833704914432 0.630774120546412 0.137294147463981 0.711069103302434 0.247481088675559 0.962803318290971 0.759060275156517 0.39611278839875 0.52600400385214 0.810528568774462 0.312494676266797 0.884378392468207 0.951043183782604 0.441340640839189 0.383069936505053 0.733097844710574 0.70783648343524 0.598464532333892 0.115162713115569 0.915890543784481 0.0386896167742088 0.118638263775501 0.226788351030555 0.0756377289118245 0.679942846782505 0.940833059013821 0.623314962340519 0.431589908611495 0.666569405670743 0.769360694375355 0.397715376873966 0.841550369011238 0.737618512329645 0.906584560745396 0.611112341484986 0.24558339566458 0.947036772179417 0.126336500158068 0.425199747867882 0.165586602257099 0.666532144506928 0.0611494369688444 0.225926415661816 0.693445967817679 0.335158093874343 0.883829713002779 0.479046357225161 0.52074488626793 0.361116873163264 0.280296211617533 0.596866398777347 0.69891299067298 0.963057556145359 0.550109987375326 0.9752569430531 0.231872114653233 0.76460810175864 0.872715759756975 0.212024088550825 0.411521289467346 0.0658768075588159 0.367457028038334 0.67251246241387 0.211999511239119 0.640672991555184 0.543231934320647 0.287635578911286 0.112472061638255 0.596417748106178 0.697915577555541 0.726608445334714 0.178918147725053 0.679342820846941 0.0340215196297504 0.834350747908466 0.659525504109915 0.0233658566628583 0.374231379474513 0.289227212762926 0.255637285027187 0.165044561028481 0.262421904881485 0.989614444512408 0.468172798554879 0.951489333042409 0.60285174647579 0.482704934577923 0.200097006270662 0.198305843602866 0.248327208817936 0.741912845093757 0.397233160682954 0.37516311763553 0.428544411924668 0.465959263404366 0.16239636600716 0.560711540379562 0.935555352799129 0.48316701546777 0.486708835780155 0.67106793492334 0.290141532092821 0.626307580638677 0.315624267351814 0.614522206585389 0.277357074010652 0.876091264795978 0.380618655020371 0.545563542910386 0.522969637892675 0.682921201826539 0.177150160223246 0.783935372370761 0.482065496891737 0.555469153346494 0.222673807092942 0.436420456427149 0.0989238554984331 0.891502135889605 0.989698887660634 0.185408386820927 0.0722580586955883 0.474086088917684 0.539131234122906 0.86770349980332 0.357081195830833 0.946373307160102 0.751924424138852 0.834854316452984 0.285855233487673 0.278875513458624 0.624528948769439 0.627138734955806 0.0989362682797946 0.309213776532561 0.222274908968247 0.968990555380005 0.712512778625824 0.404417786456179 0.389409204868134 0.777698734251317 0.0752087997901253 0.913937709082384 0.444749554886948 0.521228361693211 0.14726518714102 0.927618546728045 0.456148329498246 0.697517661601305 0.882290614091326 0.247640164562035 0.315799367299769 0.050960222450085 0.312716119401157 0.143818480160553 0.576958148637786 0.439769500028342 0.798547954401001 0.132109309027437 0.427534429284278 0.292550953431055 0.36875339047052 0.241474945517257 0.556358063020743 0.0496736376965418 0.184710527395364 0.299134249086492 0.317041456112638 0.797516967696138 0.213115040208213 0.683308801648673 0.666174993813038 0.60727443146985 0.800259241785388 0.031769841182977 0.301230419822969 0.621195416823029 0.0489940430456772 0.126647414388135 0.938986142440699 0.42027315963991 0.161702203839086 0.600452332166024 0.198082942541223 0.295664108546916 0.381955374493264 0.242380810482427 0.0921402427088469 0.470204823487438 0.577134659029543 0.410565778217278 0.212328645065427 0.253070048880763 0.545808322101366 0.868196487138048 0.0512898845877498 0.0638319332734682 0.118723022250924 0.856972512591165 0.926421429843176 0.516912572849542 0.920355761761311 0.175286098655779 0.164953705996741 0.16224145068787 0.949594475210179 0.230045204760972 0.933224078437779 0.627791232443415 0.473975794471335 0.766282848990522 0.432464599288069 0.545694367047399 0.63395596005721 0.958447221042588 0.372914182166569 0.340186971894 0.841954814635683 0.822516792260576 0.126067860748153 0.328129925250541 0.333252501087263 0.891982893461827 0.408394106440246 0.60166450454155 0.895197949972935 0.315450151187833 0.492002768898383 0.607394004787784 0.77368358960608 0.282961878024507 0.277268763494212 0.439284000562038 0.728787247701548 0.714033898354974 0.905752299325541 0.0319198952079751 0.351892865514383 0.95711685721064 0.307196446585003 0.0264315854618326 0.750694776459131 0.330787885503378 0.927704405160621 0.391693579610437 0.956082685885485 0.362361324164085 0.680893201003782 0.941581048318185 0.512669000849128 0.298654411679599 0.290553048145957 0.0108121904288419 0.149559548627585 0.659887505494989 0.902010716928635 0.485997493811883 0.369466339962091 0.311420839407947 0.0730809172336012 0.709468312284444 0.202572064071428 0.339266294618137 0.264494269106071 0.268415102567524 0.999539976574015 0.624757380734663 0.394992710005026 0.330004331762902 0.362154004829936 0.796619966698345 0.757595500110183 0.302247984376736 0.765709944881964 0.936474952937569 0.832266771437135 0.603544510186184 0.175911039819475 0.0528189755487256 0.181278984472156 0.987391988229938 0.18653310730122 0.15992729319958 0.351755169641692 0.125716235195287 0.456594986785203 0.212376102039125 0.199911590651609 0.209083737118635 0.497890411957633 0.249240924001206 0.942648036491591 0.931963878825773 0.986861043383833 0.506315740763675 0.436806641425937 0.723023331151344 0.213107669434976 0.627910846099258 0.409676092211157 0.169285330120474 0.865612168463413 0.642966243634 0.611372406668961 0.271807110651862 0.363851359039545 0.636499134295154 0.385178115260787 0.376232501880731 0.436160124551971 0.723872586817015 0.454950138011482 0.910371628860012 0.284501765023451 0.784847374921665 0.496522749850992 0.166164447413757 0.301871590425726 0.480147365930025 0.468668366593774 0.0308436074177735 0.541437094218563 0.942462738889735 0.487463579264004 0.817311860013287 0.706369266216643 0.95175153106451 0.859250578484498 0.904994022701867 0.771075448975898 0.394857368252706 0.994105198229663 0.679469198132865 0.639998299689032 0.905274221573491 0.904933892940171 0.635041665942408 0.462081214173231 0.801032120962627 0.811887077172287 0.716360732088797 0.692138745037373 0.897008231887594 0.767463234402239 0.732505047328304 0.0420115039730445 0.55273421545513 0.408441938902251 0.366414732888807 0.333130057554226 0.960879198648036 0.828426846831571 0.804688321836293 0.244879680557642 0.449940565945581 0.920009571914561 0.280516787371598 0.429591788498219 0.663741872915998 0.886556168408133 0.943675491900649 0.668600827609189 0.672018911731429 0.42100639264565 0.615862401342019 0.588556492172647 0.576783341197297 0.131955524783116 0.467480604415759 0.626379853263497 0.730504216968548 0.67307725007413 0.17849890292855 0.52739786301041 0.461820915951394 0.421624574097805 0.793285118122585 0.201943109401036 0.989410986553412 0.34053762242198 0.982924767648801 0.731735051965807 0.642061809396837 0.824891729296651 0.235352533292025 0.972087077216711 0.482881550078746 0.999739728055429 0.0628533826232888 0.524947598963045 0.36068932521157 0.656067318804562 0.126011957477313 0.692037991313264 0.793870075198356 0.291751384618692 0.436349727706984 0.0869555116863921 0.595404262060765 0.914482248034328 0.285959285700228 0.235049647919368 0.212202397782821 0.0260806177626364 0.88316232345067 0.963195562274195 0.847387760716956 0.552612353709992 0.752237878504675 0.026144232028164 0.353323574389797 0.559091350284871 0.167118232201319 0.556119129138533 0.744073256140109 0.629024697933346 0.0754930144734681 0.0207061277655885 0.336980071708094 0.733171152982395 0.612471158064436 0.0949618709157221 0.513467837355565 0.666508527467959 0.0143686084542424 0.911289184212219 0.470154245742597 0.55318812480662 0.810808803373948 0.657476011479739 0.288826787790749 0.854097899042536 0.536726552143227 0.230416062506847 0.337598053545225 0.764085128605366 0.815496389030013 0.2649233588879 0.215283760402817 0.215474102778826 0.555966322685126 0.739314323556609 0.135748811389785 0.900578265225049 0.144157405495644 0.075887310388498 0.351914985210169 0.893789283344522 0.96265501746675 0.94727032152703 0.176386589421891 0.559745972543023 0.986963657031301 0.964643093671184 0.656189463376068 0.444347992155235 0.869175983769819 0.639931344292127 0.630221860457677 0.340396467631217 0.132366647829767 0.45532704459969 0.323868531961925 0.524766218978912 0.451205756855197 0.999504154666793 0.698567482652143 0.0619995779939927 0.350731319980696 0.62409323250642 0.224958109457511 0.121908923443407 0.270809562921058 0.795352623127401 0.604927692245692 0.35620096756611 0.138882141914219 0.482641945434734 0.74846501509659 0.778118490302004 0.792355740997009 0.659592073645908 0.775438933824189 0.0244594100001268 0.982995627524797 0.240913056423888 0.989122710188385 0.484403326278552 0.710110473125242 0.363981313721742 0.0501010989793576 0.704285074686632 0.571234380754177 0.654133947489318 0.418812795947306 0.618623161949217 0.788498817305081 0.360297621295322 0.0907025648257695 0.895123923225328 0.826504868785851 0.013441060364712 0.415323997165542 0.280740900184028 0.119700914125424 0.318048305534758 0.33713608721504 0.304584579654038 0.438814769489691 0.415267406075727 0.222421213642228 0.674693636880256 0.615770256649703 0.906969167264178 0.178720833805855 0.108046443732455 0.500414318044204 0.397074328898452 0.292880548262037 0.872071563580539 0.124694778148551 0.039879885665141 0.589878227610607 0.284915670694318 0.764258280117065 0.646875202998053 0.654238459093031 0.342138250013813 0.698700625412166 0.926315840180032 0.281758506458718 0.249418418868445 0.867666506713722 0.771816703232471 0.990440608453937 0.989574673639145 0.561136036249809 0.617451650185976 0.990767057389021 0.314250543725211 0.272456997700501 0.628628278169781 0.55040478534298 0.781397330497857 0.723231688207015 0.206246215775609 0.362234120066278 0.404965796312317 0.640718705470208 0.386557568022981 0.908527651652694 0.806508246816229 0.25658961718902 0.472813902262133 0.354410122530535 0.521043542153202 0.273226782153361 0.263499648985453 0.547533718533814 0.0869752823328599 0.212592979844194 0.553890065506566 0.780826746625826 0.784859181942884 0.258834239037242 0.561866704917047 0.656745395367034 0.765444235617761 0.836160230902024 0.438996088851709 0.842581773847342 0.329400847139768 0.246335973117966 0.784289038330316 0.677930755922571 0.283202562802471 0.135956325728912 0.802099481166806 0.807331584568601 0.309092765110545 0.226008224629331 0.611829711550381 0.0804719631513581 0.725130305532366 0.275875029037707 0.0806271672900766 0.189491535187699 0.526326004553121 0.114615944284014 0.127815779333469 0.45803817367414 0.286710819669534 0.724067474007607 0.587654256927781 0.573891611006111 0.250088971373625 0.459090691371821 0.389091819515452 0.113133883406408 0.824518692842685 0.929127433928661 0.153648686828092 0.875580295973923 0.935602082537953 0.903261726181954 0.762189722408075 0.407107770168222 0.23787464768393 0.760315457885154 0.161417826651596 0.604626372444909 0.435844640382566 0.929211174966767 0.0436942473310046 0.992755580767989 0.0746801901631989 0.376771554416046 0.384602920881007 0.839708695444278 0.811957213270944 0.792041327049956 0.756730353382882 0.468022502732929 0.0681421123817563 0.569118712055497 0.122245038955007 0.892434659833089 0.87313979577506 0.827656112017576 0.363368250112981 0.511747326189652 0.793662515911274 0.220622787615284 0.155067145426292 0.814278727010824 0.0138237813743763 0.944564946251921 0.386354312675539 0.373377576919738 0.0746932280668989 0.258947044115048 0.693999353910331 0.683409332707524 0.444285654642154 0.896222270089202 0.280440519910771 0.854022435804363 0.895608009481803 0.900538991775829 0.518945893666241 0.116362941320986 0.91638093451038 0.141753326510079 0.150661208962556 0.0308457953459583 0.407894087631721 0.312125346751418 0.881524353558198 0.600639245589264 0.0202581893466413 0.0541146856592968 0.239795188086573 0.209988591331057 0.664437809260562 0.126448066055309 0.67967635427136 0.921154026852455 0.966185316580813 0.575573615373578 0.118027317330707 0.572579814367928 0.788199928842951 0.714442991367541 0.31585582976928 0.668914461075328 0.284590106196702 0.48181746439077 0.519713110553566 0.135703673039097 0.716426790140104 0.358542827747297 0.151924638373312 0.963350354966242 0.0570447762799449 0.766078815006185 0.524936976032332 0.512620448758826 0.0855661862785928 0.219667562188115 0.0258052197936922 0.861389706097543 0.448806149384472 0.334211613475345 0.261143008072395 0.536125151491724 0.0758737206622027 0.528921542468015 0.229138511139899 0.435645428737625 0.7785633960017 0.756677176493686 0.812871725761797 0.0770366402203217 0.357731010271236 0.0847392964852042 0.270459129295778 0.775162160908803 0.154800903471187 0.923793954907451 0.743762495655101 0.852317510053981 0.915985318508465 0.923299578335136 0.99099314353196 0.152532887479756 0.305618027893361 0.698926997608505 0.168589469841681 0.500738206098322 0.38275536673842 0.967767547089607 0.294577192293946 0.55907124702353 0.816302521165926 0.0669171678717248 0.942348974000197 0.242218894807156 0.677490578978322 0.618585387456696 0.761913882335648 0.325145106229465 0.295307946247049 0.872033882210962 0.534517609521281 0.634257032298483 0.0574555344413966 0.402004887529183 0.351142833498307 0.855944106820971 0.49511265226407 0.987737855373416 0.946833547258284 0.363639766192064 0.919001129260287 0.697324794302694 0.316089861788787 0.0172246942250058 0.193729887693189 0.0948089973861352 0.868843647113536 0.60476194700459 0.61376292451052 0.804394748758059 0.823475739608984 0.18807881356217 0.675815115806181 0.715934657969046 0.0760011737025343 0.999245298467576 0.573373824616428 0.265595897401217 0.642334214753937 0.310195815605111 0.200922411859501 0.826511064458173 0.819512280963827 0.774840729318094 0.640916817849502 0.762034946081694 0.902807674149517 0.0434762225463055 0.139366992285941 0.912385496892966 0.904842831839342 0.19712262877496 0.569073739666492 0.819260934530757 0.226627632123418 0.764087698936928 0.69359341647476 0.731800408137497 0.983024118305184 0.167456980971619 0.176723236702383 0.910695992901456 0.601227457127534 0.932733436464332 0.296305508499499 0.918006456124131 0.185458897720091 0.97858428647276 0.762148361760192 0.11056240209844 0.676534978293348 0.514242393437307 0.713463856854942 0.362350992818829 0.190397709256504 0.891844960632734 0.299575670051854 0.535534835236613 0.0868321705772541 0.0198282294184901 0.793952103834599 0.11787869841326 0.916072029569186 0.126372452529613 0.540753638192546 0.654207228100859 0.876363175725564 0.807406083154492 0.919199750127736 0.0955837053689174 0.456591453645378 0.702613768624142 0.29224789863918 0.837339141098782 0.963239832092077 0.588568280292675 0.664636408460792 0.386783574642614 0.9264577844413 0.839479840276763 0.0525429231836461 0.419697974480223 0.0157737751351669 0.580168613081332 0.351379657592624 0.700301896566525 0.895029637396801 0.0978306894050911 0.446293561423663 0.416611103545874 0.989288445748389 0.763358955655713 0.937887576599605 0.889082230383065 0.245491410710383 0.498519331361167 0.461898449561559 0.176260880592745 0.896141946939751 0.335026358100586 0.585540337050334 0.669852350652218 0.402023197021335 0.0447411075793207 0.185385799205396 0.507242988969665 0.14263959716307 0.350199048132636 0.0927933023916557 0.934264876013622 0.0242337940819561 0.745610070081893 0.347550649808254 0.710808036355302 0.236089062020183 0.674766555603128 0.577006529925857 0.131752287645359 0.881003505636472 0.476219167227391 0.240643535573035 0.986977414332796 0.652723844139837 0.94121547668241 0.0455376243102364 0.184596064775251 0.174774938747287 0.811690430787858 0.476397943226621 0.605493596689776 0.649214296690188 0.559080017867964 0.209199374378659 0.898464027715381 0.857051232827362 0.352845623875037 0.823087923575658 0.406552092190832 0.433750744934659 0.134369633155875 0.236220819230657 0.792660433738492 0.113865339700133 0.538668691075873 0.461101400370244 0.377514746044762 0.324639301351272 0.103646330910269 0.661348372143693 0.258359504030086 0.853021190355066 0.924868467138149 0.13634025618434 0.061345815048553 0.85590272565838 0.675001789231319 0.360930490125902 0.03427437400911 0.237333748594392 0.359343955216464 0.951142381385434 0.12659354921896 0.228413882786408 0.488386246697046 0.332222706540488 0.100762677059975 0.795799297702033 0.847458471918944 0.188062141328119 0.131076795014087 0.953723189970478 0.27304538856959 0.536612326249015 0.675469892686233 0.661751372287981 0.698895769151859 0.60756081748521 0.227383290932048 0.851179760198575 0.0152380031091161 0.311839797459543 0.861049745806958 0.339474462200888 0.0409089273912832 0.516569034932181 0.828902574612293 0.261379001205787 0.713831281268503 0.153325831654947 0.683028078384232 0.234893789154012 0.543849412740674 0.903470129338093 0.321891861704644 0.853150347729679 0.341559017924592 0.586713139396161 0.931979450872168 0.966838336847723 0.721200521434657 0.151725455310661 0.490950713127386 0.973875271475408 0.843493990534916 0.411624134078156 0.595204103051219 0.301000950136222 0.157525090503041 0.960024016536772 0.616513838288374 0.518107872914988 0.978989352839999 0.175845292024314 0.462493052238133 0.059368382981047 0.817409252321813 0.221880481205881 0.014247695687227 0.424114707442932 0.878107707540039 0.606813510237262 0.209644365133718 0.0537641231832095 0.985820420759264 0.250563246067613 0.750641414246056 0.678232522667386 0.246470312646125 0.0585273410356604 0.573041432870086 0.652449064608663 0.373387492208276 0.718056197562255 0.305458843901288 0.413081273965072 0.958790633566678 0.603398665133864 0.936839189273305 0.163862894023769 0.371038825984579 0.216866417340934 0.369658061894588 0.778059510055464 0.676695784791373 0.31378035468515 0.537228873900603 0.195697432132438 0.0152239855704829 0.0536884469608776 0.0269749772036448 0.75698946520919 0.395041360980831 0.942994415580761 0.21706523805391 0.197645652869251 0.286733262990601 0.226791436765343 0.641571631885599 0.175553369342815 0.073122465510387 0.899696739923675 0.480730410066899 0.254251242203172 0.492474986128509 0.24297949005384 0.234339401528705 0.291311238331255 0.96788506801473 0.598552060755901 0.320767863157671 0.320092409942299 0.0394570245174691 0.450660956513602 0.406905519810971 0.941334022420924 0.0662025737459771 0.297219023837242 0.570629794790875 0.601741556171328 0.288543904488906 0.984511002905201 0.672039558056276 0.911356082675047 0.965599516557995 0.0208365701907314 0.647547499714419 0.89833630452631 0.698255726858042 0.09103110026801 0.110376501271967 0.26844131506281 0.830043719306123 0.964610815967899 0.916367028995883 0.276474018634763 0.112954260772094 0.395371523078065 0.842704705123324 0.339451823413838 0.366809151200578 0.277992921622936 0.168518527906854 0.213979184250347 0.336567362805363 0.806515351589769 0.894167262229603 0.159384051053785 0.292263144063763 0.0191438264888711 0.356105536140967 0.241102163768373 0.834634595632087 0.302543913649861 0.0688228775234893 0.532877227191348 0.299526989110745 0.174892810496967 0.0520530589250848 0.264205947793089 0.692847306686454 0.928064967289101 0.918232074808329 0.897903152832296 0.16319567803992 0.101562102960888 0.957847343781032 0.806821041945368 0.121850843308493 0.375849841723684 0.571401457376778 0.782272824014071 0.772897446863353 0.720033894015942 0.882007081003394 0.815907728748862 0.587534988794941 0.419873678805307 0.0198509002453648 0.796039230811875 0.990517615596764 0.50280256728176 0.960024428905454 0.367468543013092 0.930153516926803 0.186571919745766 0.0762879476533271 0.253255931497551 0.620476110538002 0.677003522468731 0.681406930782832 0.622921719129663 0.140914569534361 0.379382369564846 0.55387072497746 0.952007835833356 0.0701978871226311 0.260531632893253 0.556554700415581 0.433939801799133 0.985816327959765 0.944110836824402 0.743884210339747 0.683952332364861 0.396432041742373 0.330837154916953 0.483209457402118 0.133061320330016 0.241244226968847 0.100090879842173 0.388309863386676 0.861636137990281 0.79375191393774 0.812432135215495 0.630797540505882 0.0126690363511443 0.104155975957401 0.409066612683237 0.842683009551838 0.135755675288383 0.262595147441607 0.540254703897517 0.795339401974343 0.390682466125581 0.949609296510462 0.797887727939524 0.313719509905204 0.423021345883608 0.751294919028878 0.282361949591432 0.239652466340922 0.448568582381122 0.633916507277172 0.576992119380739 0.862554041401017 0.768987778243609 0.902654372807592 0.893217577848118 0.627939625468571 0.291863488969393 0.780534877881873 0.20876759209903 0.938077841065824 0.331802569008432 0.73757058513118 0.381173176337034 0.223419004552998 0.394865099992603 0.69626456791535 0.779722147155553 0.552182379951701 0.0565273165120743 0.899560300749727 0.844647896990646 0.341985536683351 0.404709873716347 0.169699203060009 0.108625973400194 0.365309940257575 0.69526328074513 0.709197436310351 0.166200998630375 0.214776672779117 0.991806394732557 0.203259016817901 0.816661921562627 0.949157725605182 0.9504807981872 0.233124660896137 0.188908475607168 0.543470641849563 0.569843635682482 0.334868268072605 0.934966841377318 0.926985256769694 0.0524312524078414 0.500333956861868 0.231335289462004 0.395723784356378 0.441920345919207 0.390871210659388 0.447055785169359 0.552653757000808 0.683992710611783 0.434634294738062 0.771336127065588 0.453534997494426 0.682051565835718 0.856411818421911 0.855709195204545 0.722000558397267 0.661881003114395 0.926852201600559 0.787319218828343 0.809370828834362 0.872237597641069 0.63914221032057 0.741765958862379 0.812123652093578 0.3994898661552 0.239933118380141 0.203526553274132 0.536821326175705 0.429462266468909 0.869843779467046 0.608069225195795 0.19662148419302 0.467923331637867 0.485872154477984 0.285287939114496 0.443699734988622 0.787565744535532 0.921718575251289 0.416746860893909 0.108732833361719 0.550179968576413 0.543863225132227 0.443879623853136 0.261857411111705 0.713825517096557 0.135845862093847 0.115672960234806 0.445904519348405 0.165826043705456 0.661712513742968 0.891176328212023 0.896932933689095 0.70809517044574 0.747544899093919 0.428910318480339 0.0750890927808359 0.540177714733873 0.982865727010649 0.694104013727047 0.877251530811191 0.950056677574758 0.537465766684618 0.991144938080106 0.54683456714265 0.672902782163583 0.0109612136473879 0.342226067255251 0.849396243062802 0.628989478328731 0.581333247115836 0.521805375658441 0.274344035279937 0.779026009812951 0.586561572353821 0.566877459229436 0.335334648753051 0.866828602596652 0.894664927839767 0.734359157187864 0.690791624607518 0.203807529399637 0.239376530610025 0.493794569827151 0.932508790038992 0.492172698678914 0.292580881624017 0.401138302467298 0.601990471957251 0.664101766818203 0.979634666722268 0.295771743918303 0.0362657519290224 0.177639299321454 0.695587970947381 0.586774226664565 0.0389492829586379 0.613719573935959 0.0612731750030071 0.813871472023893 0.0309543462726288 0.0638672289438546 0.600863380299415 0.50617930182023 0.55144929285394 0.195004858125467 0.347748629648704 0.878466475668829 0.940228780310135 0.262544853445143 0.117690053456463 0.304317501436453 0.845447537719738 0.402799845603295 0.401872005928308 0.985450235158205 0.0310886267921887 0.0146760633052327 0.455257715720218 0.121123595065437 0.352511435823981 0.613540063095279 0.250552934315056 0.703103947057389 0.689867831401061 0.536991254112218 0.965456332655158 0.689938430117909 0.866957969497889 0.480948357402813 0.776920966811013 0.173385319218505 0.218242659205571 0.879149983557872 0.490977000074927 0.831893103637267 0.568613603294361 0.832509003116284 0.873282680716366 0.442002786693629 0.361817565923557 0.310983405441511 0.980915251038969 0.701133099289145 0.110387603878044 0.560254697424825 0.0989088654704392 0.775705810582731 0.710917755237315 0.489198229904287 0.920474971346557 0.089983036336489 0.61866164869396 0.930080350644421 0.995063650459051 0.825820637580473 0.860687254604418 0.410732690261211 0.045026404010132 0.571549138380215 0.622140248669311 0.443506692508236 0.693839820476715 0.949970360212028 0.738691075202078 0.859488746637944 0.7478582506557 0.118568293638527 0.401539309227373 0.72233568597585 0.461085635393392 0.843457072128076 0.32955734946765 0.638987023239024 0.669057172448374 0.229774549377616 0.267725935846101 0.86165532592684 0.96590969087556 0.45615319494158 0.822471614724491 0.25213467085734 0.667021974190138 0.35568994595902 0.338900624096859 0.459697007024661 0.76459205579944 0.157984171174467 0.715436041536741 0.821761597222649 0.770606262851506 0.814903891761787 0.590550316183362 0.38895598448813 0.407971932189539 0.31567762772087 0.100231595064979 0.384264334384352 0.279308316633105 0.218670295439661 0.566132359271869 0.84385720689781 0.0664802831923589 0.651735997791402 0.120767849744298 0.553695177393965 0.363568560101558 0.828813446504064 0.510695823393762 0.146669218738098 0.635334295344073 0.740072211783845 0.45039533322677 0.321673753017094 0.094168160550762 0.868030973782297 0.828425813259091 0.568229940913152 0.614582661124878 0.79604192469269 0.475656199383084 0.525794618756045 0.229390691760927 0.377758796387352 0.14051533441525 0.855981426071376 0.200558478864841 0.467921094612684 0.308174916789867 0.960316838407889 0.231866305302829 0.795516365994699 0.515010961990338 0.551977388230152 0.262869608879555 0.932643871784676 0.721196432323195 0.650534452034626 0.0886875629518181 0.45614864344243 0.556596836242825 0.741916025565006 0.784757543781307 0.982587717680726 0.196204806270543 0.275423138425685 0.887304281031247 0.519497557906434 0.133348069847561 0.807861845053267 0.31831529178191 0.117850105981342 0.252639466826804 0.89035543424543 0.670547798562329 0.107390118292533 0.697411765600555 0.55222928579431 0.44381972782081 0.341712956144474 0.188002113909461 0.738732638231013 0.564879853136372 0.152486371647101 0.773539626144338 0.657238067835569 0.111021253650542 0.181580012917984 0.889740929536056 0.67259560022736 0.0815507811657153 0.684496816687752 0.666710910133552 0.490234026731923 0.0617809774144553 0.357636234164238 0.756691441591829 0.256028603543527 0.566511232506018 0.411840315996669 0.85032234221464 0.661106552141719 0.894792813532986 0.960874453526922 0.600662006773055 0.479704846621025 0.882409725252073 0.811923297157045 0.890252791785169 0.591277713330928 0.0249519296456128 0.470751882521436 0.45149751910707 0.663956401671749 0.49532315322198 0.840552856086288 0.802842640064191 0.613233120420482 0.72302575787995 0.320762997714337 0.148534123713616 0.753955096253194 0.626518409140408 0.856165554334875 0.286679191291332 0.782384059831966 0.65281171716284 0.592815431994386 0.967842492158525 0.134699919954874 0.415541432555765 0.567576038052794 0.463494201567955 0.240470357092563 0.472881527268328 0.286412878802512 0.338790004411712 0.727001338643022 0.200592557943892 0.113949099639431 0.0137743061222136 0.0116021807165816 0.532207851861604 0.67060357759241 0.0539184659346938 0.3356759763835 0.142397412506398 0.691771639639046 0.403054651876446 0.133440196791198 0.0355087105673738 0.356026989703532 0.939333606965374 0.373743337106425 0.298348353903275 0.925553179171402 0.116335094564129 0.198127992379013 0.186397773616482 0.932433636134956 0.641702092059422 0.574520537094213 0.503932509562001 0.476653835857287 0.666752259486821 0.779691385005135 0.218237658687867 0.638079617596231 0.104273402607068 0.379367314996198 0.909252148619853 0.0120547342533246 0.36838709551841 0.631002757658716 0.686929261751939 0.409569248615298 0.465039109599311 0.988490336246323 0.302610884490423 0.169870743821375 0.535644051393028 0.37332829736406 0.920362969338894 0.622455219971016 0.789172190697864 0.357990444339812 0.605281638957094 0.883999000603799 0.57324275937397 0.954499654150568 0.47903152232524 0.954772389817517 0.321928809385281 0.238321273853071 0.986573808197863 0.172549792272039 0.237337016656529 0.0752493502222933 0.138773963018321 0.118410243487451 0.178345050916541 0.600745773166418 0.842412841450423 0.267445849920623 0.554071125553455 0.280903127267957 0.638894890532829 0.381491216546856 0.722936983592808 0.0165740121738054 0.909760335739702 0.312488552280702 0.563790639466606 0.814796783549245 0.909526558425278 0.176170323831029 0.0762102425494231 0.129133025738411 0.5537335942965 0.0432177121005952 0.7019441074715 0.394235305832699 0.159165348361712 0.623836429622024 0.656948652327992 0.5062868369231 0.136701235291548 0.124540184841026 0.497098100511357 0.117771856200416 0.131268271692097 0.407743905447423 0.343248502553906 0.444423041180708 0.490606995648704 0.148886965627316 0.851136167135555 0.297204302113969 0.724189870518167 0.515503737032413 0.703370946673676 0.399653181440663 0.773329124494921 0.525328097238671 0.30854527042713 0.315074035222642 0.864070448279381 0.830681263876613 0.752390649691224 0.100752398730256 0.244531361330301 0.718677203129046 0.571483672028407 0.19265093137743 0.636258751014248 0.179725307670888 0.976430843742564 0.708778657820076 0.977211427460425 0.980869263056666 0.296851311065257 0.148903453920502 0.938109664449003 0.583554539131001 0.302877659597434 0.578700770740397 0.57540199163137 0.972298354045488 0.056032345474232 0.931938610007055 0.434928609803319 0.928495221107733 0.588488107661251 0.975462628356181 0.325112170903012 0.261138120500837 0.430374819228891 0.228227996712085 0.456578644169495 0.514221174544655 0.939393724279944 0.750609388712328 0.472311068559065 0.606420985732693 0.680155782536603 0.640309505274054 0.318333671346772 0.79817286901176 0.500639914830681 0.794125322191976 0.423591278125532 0.720467963570263 0.628415014871862 0.78340135585051 0.419188675647601 0.0439495752309449 0.907987612797879 0.767694349875674 0.434820319574792 0.561205081611406 0.0471881316858344 0.73978223039303 0.300202146591619 0.673590838094242 0.0608335445798002 0.895765580879524 0.799815070235636 0.617138627320528 0.950179383419454 0.882035463447683 0.152206781993154 0.364599050073884 0.950675686991308 0.220889062071219 0.578847705377266 0.987407251864206 0.179455365692265 0.338066228455864 0.796408555025701 0.92015848103445 0.339312327087391 0.18450611400418 0.664733718710486 0.0580992318107747 0.50417912009405 0.664142587629613 0.611908604893833 0.220958937010728 0.675389558933675 0.13326904350426 0.311200745864771 0.223028767553624 0.845300834737718 0.331401922293007 0.451204449445941 0.294836841421202 0.273230580370873 0.701692055931781 0.813963015335612 0.974195786588825 0.314441726973746 0.11955746721942 0.0625200822367333 0.22815819806885 0.886435581801925 0.998921612333506 0.558261452896986 0.964768284792081 0.111952838988509 0.803702902446967 0.577574884609785 0.986524746697396 0.690490695047192 0.314253744711168 0.593234526733868 0.628248040131293 0.266014507163782 0.893260445289779 0.719032759899274 0.649009238814469 0.661206869755406 0.142092643468641 0.480663824626245 0.891565140015446 0.437663090378046 0.989064305967186 0.643077254251111 0.769761469250079 0.417199820114765 0.507937064468861 0.777085790273268 0.218765574272256 0.226445601200685 0.278501605014317 0.52473024724517 0.946349525311962 0.723292373248842 0.361179236262105 0.359007156265434 0.608358666519634 0.837043127000798 0.0342166541493498 0.833876865298953 0.151480695020873 0.684058118877001 0.0275692149950191 0.091945174112916 0.422882284054067 0.160733328985516 0.664197510113008 0.125074502397329 0.499851728454232 0.21814216272207 0.360914402676281 0.24492675190093 0.808379946539644 0.132687478961889 0.45982500912156 0.391113606917206 0.489464778658003 0.033279959957581 0.559731273869984 0.713553360681981 0.0926864154613577 0.897117899137083 0.404109790155198 0.690426007101778 0.122589770643972 0.355957573463675 0.661465176206548 0.120228055452462 0.162534239366651 0.13084677096922 0.148831230853684 0.275401573318522 0.673754048270639 0.92034003527835 0.372685713320971 0.0301375531731173 0.0391717239376158 0.676716229426675 0.483335232154932 0.0162589124822989 0.564522020386066 0.334994262494147 0.721532203003298 0.320256425493862 0.975901812065858 0.838923843053635 0.458404733473435 0.329139744464774 0.602294578300789 0.983292186760809 0.873928107083775 0.16831360072596 0.60009256757563 0.941347334161401 0.481274592892733 0.0203260165033862 0.0941572651662864 0.339265574298333 0.580533649260178 0.485976810145658 0.799570477060042 0.839648716661613 0.319417175704148 0.389162756148726 0.0202918749582022 0.859416416848544 0.750920050772838 0.126075025452301 0.236637166382279 0.691637354048435 0.619611461234745 0.114124495782889 0.451517371120863 0.694493272705004 0.517904129594099 0.0658368626562879 0.0862054335698485 0.204966248744167 0.0744731301441789 0.826253660423681 0.457171744662337 0.713214732003398 0.744682570628356 0.175688191542868 0.446876472330187 0.0423694056435488 0.598942465791479 0.686565972550306 0.270580535107292 0.463559290356934 0.0247210479015484 0.549193671434186 0.542379494726192 0.881361966736149 0.237721548953559 0.265566890295595 0.569870446100831 0.356982810518239 0.50879893575795 0.999402158535086 0.355174287797417 0.894057200590614 0.216640939493664 0.816238686079159 0.962465401634108 0.387092516233679 0.56089190315688 0.533485952515621 0.378128558325116 0.832008198755793 0.874223220839631 0.54343817997491 0.624344103643671 0.101838998503517 0.502697331900708 0.356634717183188 0.847562260436825 0.285274637746625 0.826306925825775 0.61287743111141 0.0340336272260174 0.200311784890946 0.773036327979062 0.471406546961516 0.205334665239789 0.142121593640186 0.681882595636416 0.500431916897651 0.924417871257756 0.628868685653433 0.511105099655688 0.255423288962338 0.28015064339852 0.13297330001602 0.307595768372994 0.470242626101244 0.670319403938483 0.555407887899782 0.365976975066587 0.786305814380758 0.546664297140669 0.337958342297934 0.488785866524559 0.79230904329801 0.316642236898188 0.466307742369827 0.864331422564574 0.675405166707933 0.871166591581423 0.852119502553251 0.138452997503337 0.241943768139463 0.0426967355585657 0.631247108115349 0.677983320136554 0.136873716271948 0.547200747996103 0.572790928462055 0.161710817250423 0.678833796312101 0.462817207213957 0.326810807166621 0.0653989773662761 0.884682809759397 0.287675566687249 0.110710574071854 0.380018919056747 0.279616524304729 0.857912085987627 0.765121409948915 0.825387229337357 0.320820911887568 0.880010049322154 0.0554568853252567 0.846929351729341 0.446217223198619 0.86801205230644 0.639712397267576 0.710553653514944 0.15282808098942 0.246148275986779 0.105175997666083 0.937519546886906 0.825403619206045 0.718328489051201 0.385887228962965 0.260306580553297 0.0736517198523507 0.333766583765391 0.28797440005932 0.0715562802692875 0.270885567839723 0.533553874869831 0.196967597512994 0.249328124879394 0.0374197618803009 0.697227599765174 0.940962899597362 0.720295959268697 0.85731382708298 0.741583816146012 0.427087373228278 0.696064619815443 0.216430449599866 0.777589867536444 0.0365930348215625 0.640782878012396 0.519137635652442 0.379961626778822 0.88895572286332 0.508678794021252 0.242140752901323 0.355391791416332 0.887033382237423 0.624550359209534 0.914489985997789 0.100927947696764 0.527666528928094 0.429258579851594 0.0321240047970787 0.416493096491322 0.512825774708763 0.90533276686212 0.956051749244798 0.256352643268183 0.911689337652642 0.631929491152987 0.512995630959049 0.99659469746286 0.998917845233809 0.79423892688239 0.836941699287854 0.729666918150615 0.143823375338688 0.939625786656979 0.452020206898451 0.579100654954091 0.871996327387169 0.910516954590566 0.309719894432928 0.817618701267056 0.376886522297282 0.248188655476552 0.932581662430894 0.835888006719761 0.580394198803697 0.618400186204817 0.0907000233069993 0.349379434376024 0.803362622219138 0.285832700501196 0.104478299822658 0.525310629310552 0.640117228291929 0.907673426356632 0.957098553020041 0.221308224578388 0.147682912005112 0.817796834164765 0.394316285683308 0.541265753763728 0.736801157726441 0.475673128166236 0.636917946669273 0.315234604994766 0.902884571573231 0.146222652269062 0.901692880252376 0.423640716727823 0.145440016158391 0.432367995067034 0.0472416531760246 0.606066451701336 0.326645598073956 0.580629355213605 0.480329412526917 0.143208407319617 0.0239009364903904 0.724186861310154 0.758658204858657 0.0265910469787195 0.211730864683632 0.861675744054373 0.17047927506268 0.390526570940856 0.759792707397137 0.0210276942001656 0.50801633030409 0.833948416912463 0.95002622314496 0.38461662378395 0.139923512749374 0.614428406194784 0.38235491087893 0.599610628909431 0.146312626320869 0.0928358171647415 0.921273735936265 0.888505579459015 0.0197461154963821 0.367822075742297 0.675502842073329 0.111817801729776 0.557454837628175 0.298392925679218 0.493851097528823 0.0937759460718371 0.157220310862176 0.866290726775769 0.0989446693984792 0.787467109358404 0.633739951245952 0.194259271577466 0.846550794974901 0.417387087820098 0.334811301724985 0.319229363552295 0.743638067035936 0.0372826302773319 0.401200054965448 0.56374852507608 0.0586667216499336 0.604873405948747 0.566562954233959 0.11740803799592 0.344982343439478 0.155508068045601 0.93414612743305 0.506500554080121 0.335409078879748 0.50974489568267 0.839066620580852 0.968700669417158 0.111337979305536 0.591820244607516 0.875878135650419 0.468675667755306 0.835965348782484 0.389447254810948 0.201565689714625 0.404141679231543 0.330939450471196 0.322486257851124 0.53867009322159 0.238972654326353 0.333897992456332 0.878750432650559 0.0501811137166806 0.171832267309073 0.633964981457684 0.138636077903211 0.632644912321121 0.550893373079598 0.719154358641244 0.926610545255244 0.796563126896508 0.771868310170248 0.826495973700658 0.256177970902063 0.635293059397955 0.218173148459755 0.4742825663439 0.709916143750306 0.969991788151674 0.480597063081805 0.573855701738503 0.499724339724053 0.23412948789075 0.94631552598672 0.225841580659617 0.81988447885029 0.157208042836282 0.379379256169777 0.583043924130034 0.715927634101827 0.888041061467957 0.0987775250081904 0.868782445976976 0.358048541531898 0.252243492393754 0.887928358733188 0.940641002622433 0.964514642094728 0.490807805827353 0.260447822243441 0.97842350509949 0.83813100398751 0.125670291699935 0.762364064003341 0.214749676575884 0.108161652488634 0.333136391297448 0.26145046730293 0.114962597901467 0.697832708046772 0.281488652992994 0.840866897080559 0.59188653223915 0.754873349105474 0.5934144075308 0.895348411756568 0.292730558777694 0.42707990472205 0.542909573114011 0.688876484644134 0.149792186568957 0.67912175827194 0.648997421190143 0.114816290000454 0.768312741315458 0.51318263819674 0.345526927339379 0.363955121741164 0.299215115990955 0.792336885905825 0.567948465519585 0.304253575531766 0.263123120190576 0.225513215328101 0.681854258370586 0.226373998415656 0.236022741196211 0.918381715773139 0.541390792522579 0.285712370444089 0.372378691122867 0.0242439025314525 0.714965770437848 0.17416951790452 0.484704989988822 0.524322021612898 0.271482585719787 0.757530512742232 0.283171986206435 0.224943501602393 0.0145032453304157 0.904644549579825 0.739431371029932 0.267881365185604 0.955137453887146 0.931067368797958 0.176387888533063 0.841003618158866 0.89057894452475 0.327621539207175 0.882434730145615 0.960944815287367 0.764514737939462 0.771387333390303 0.934925148345064 0.766912463128101 0.81679475660203 0.72895503842039 0.356448089813348 0.969918808806688 0.104336458134931 0.360832467854489 0.244839460435323 0.628741974830627 0.104350706867408 0.813470866337884 0.291113311967347 0.704204135404434 0.534715940416791 0.0792471048492007 0.062639056018088 0.926587555643637 0.159037650066894 0.636505016023293 0.0248770583374426 0.881118769713212 0.193810259709135 0.285321348814759 0.509114291537553 0.384029629989527 0.613290015312377 0.627458597286604 0.545688295846339 0.953803016156889 0.512938398842234 0.608127316625323 0.149088490824215 0.159899949629325 0.710063589871861 0.82729705529986 0.869565402024891 0.870012195538729 0.960950534280855 0.305655404077843 0.18231434910791 0.94912192928372 0.190402671741322 0.163964665415697 0.640412462600507 0.935751325886231 0.95574743475765 0.0153956514946185 0.625944339612033 0.126249856173526 0.88575506698573 0.0302869435818866 0.638234974327497 0.952172033481765 0.0154737267852761 0.533644641158171 0.969431876768358 0.0511280899262056 0.713034279330168 0.0220680874749087 0.518276270315982 0.536004001537804 0.32350570099894 0.336191689635161 0.686000871867873 0.653952747066505 0.946206547478214 0.83000577401137 0.341023122118786 0.231730729129631 0.748742037646007 0.950243514471222 0.180852949768305 0.0199175760429353 0.28449456643546 0.240855380590074 0.140341848675162 0.989714987787884 0.0743655378767289 0.770346526594367 0.334383946242742 0.903941795667633 0.475198881593533 0.12673842869699 0.475331604839303 0.520546216303483 0.0250168748316355 0.116451578459237 0.0277257521287538 0.525294731794857 0.665848420406692 0.663105505981948 0.144976710840128 0.195868974968325 0.793255655774847 0.596077247748617 0.481486248667352 0.961075538694859 0.322178956284188 0.500678556933999 0.190927470012102 0.657367411686573 0.926196607544553 0.0184067641478032 0.926929897023365 0.756798807505984 0.109870417255443 0.758628031411208 0.752889929970261 0.208389525392558 0.320489992129151 0.498906266184058 0.964007756621577 0.5434958435921 0.314406823387835 0.100104396960232 0.553808604367077 0.394660554754082 0.796996028495487 0.445480588669889 0.674494277252816 0.247855447521433 0.229207074521109 0.357407228709199 0.67448131080484 0.0430972886900418 0.0684269708581269 0.830818982108031 0.959751357627101 0.190577763391193 0.967158696833067 0.932580606730189 0.231785689876415 0.195916112926789 0.778593296534382 0.817111336579546 0.435715382969938 0.634767999276519 0.281553251503501 0.479200957217254 0.617252119295299 0.846414594601374 0.17176797098713 0.125721140285023 0.013316629671026 0.178194135734811 0.849173892671242 0.387752558523789 0.290959016007837 0.214486180595122 0.311475141148549 0.588070142383222 0.906052745291963 0.862819418511353 0.330900976634584 0.142511601520237 0.710016122295056 0.692705060697626 0.366624197047204 0.561727566791233 0.48001886525657 0.534989867550321 0.444817848119419 0.535179685764015 0.588996257900726 0.0156450236751698 0.445901344870217 0.277939234632067 0.770685009825975 0.607439671219327 0.0442246449645609 0.458083537917119 0.932045174464583 0.0834415676351637 0.404439384986181 0.400402978344355 0.119770995364524 0.908515169490129 0.584628060432151 0.292246035027783 0.20454078937415 0.909521801548544 0.661803510303143 0.116971882856451 0.352425730905961 0.202568340997677 0.678935413036961 0.0368443925492465 0.0717183494591154 0.75454052424524 0.652080184803344 0.518059087786824 0.534074812687468 0.154929956428241 0.265273386598565 0.430113054551184 0.111471586066764 0.517431816936005 0.0292753649433143 0.328852691836655 0.352481131451204 0.700962930708192 0.212238092452753 0.286646848355886 0.839947821104433 0.230574756681453 0.064374255023431 0.477139128332492 0.342371712692548 0.730905048316345 0.751899581518956 0.554386398813222 0.652782266340219 0.64176128413761 0.0908917618356645 0.0341928577795625 0.805666219242848 0.674150567841716 0.232783191506751 0.500615559723228 0.354550265185535 0.513044269487727 0.863931382300798 0.169325017090887 0.38900511629181 0.290345499461982 0.165284095138777 0.848879050216638 0.387398905702867 0.562108020118903 0.478977511939593 0.48633536252426 0.0684956070780754 0.462304050924722 0.22855763718253 0.637249477719888 0.798768071455415 0.708330352902412 0.415991158981342 0.683129445014056 0.646942719437648 0.557362388903275 0.270874747599009 0.218782039054204 0.765111669842154 0.160256287802476 0.836499745170586 0.678241474917158 0.593064529185649 0.434981472056825 0.454343683365732 0.166745079113171 0.776363101827446 0.547809609316755 0.365993194594048 0.637439619789366 0.289283413842786 0.0287192971864715 0.977859280786943 0.637060325427447 0.257759832376614 0.782441749956925 0.682966502450872 0.990379849651363 0.0687518486892804 0.456054582123179 0.141439571569208 0.797226113392971 0.770057526452001 0.988582938946784 0.493595984687563 0.788458096070681 0.275944775126409 0.117859217047226 0.771481116954237 0.31391213310184 0.774563905000687 0.441659051235765 0.120163741842844 0.888243752545677 0.556410770607181 0.411476089803036 0.998846574372146 0.682312579075806 0.0659388382732868 0.662114305133 0.63727875105571 0.239649602579884 0.224530877524521 0.620092474434059 0.179609217473771 0.30361488352064 0.617655466345605 0.972649374529719 0.792580955610611 0.760409390123095 0.382668680341449 0.920999936270528 0.257555438808631 0.457477262141183 0.500406737974845 0.880261073973961 0.264589096615091 0.994398643148597 0.412665283400565 0.949620816095266 0.09183150511235 0.488504366697744 0.873715232643299 0.0450706076738425 0.472271964759566 0.702874939527828 0.301281262184493 0.0101527082594112 0.358023890228942 0.431460547472816 0.242155745695345 0.805158916560467 0.293427446405403 0.27825251635164 0.573894762203563 0.398964322439861 0.487440124268178 0.988987101283856 0.0272378616617061 0.631287710410543 0.181551659977995 0.436963285051752 0.0377050248882733 0.417039950839244 0.403451552698389 0.462000879959669 0.323468716207426 0.912760295076296 0.388145106770098 0.803487197668292 0.867476887654048 0.796853206250817 0.71835427189013 0.268676366363652 0.559698563052807 0.690718935234472 0.614579650533851 0.786016592725646 0.0144205565354787 0.42700653352309 0.298342513204552 0.504140569730662 0.780344053064473 0.733308016511146 0.307059398884885 0.807372231120244 0.918685085892212 0.224698903816752 0.371716516455635 0.707107211612165 0.338622953605372 0.754219008060172 0.882514388987329 0.0896260811085813 0.781030948646367 0.426854706704617 0.635574534791522 0.45525616951054 0.966413206174038 0.957587867991533 0.238588248344604 0.606418069878127 0.241163758602925 0.875257462006994 0.518127950590569 0.0209612592775375 0.777839254238643 0.34411065736087 0.179406739841215 0.805638429881073 0.0504065198777243 0.661868592407554 0.753603334242944 0.095126927185338 0.6946867895592 0.394785085485783 0.208632872472517 0.0106444301363081 0.265251660831273 0.372931722011417 0.826053909403272 0.475365631594323 0.972612107603345 0.831380150651094 0.89734727316536 0.554472698657773 0.992268671779893 0.335928350626491 0.215778281500097 0.513398179318756 0.393112515578978 0.960790209763218 0.818730107010342 0.993834950374439 0.745563728739507 0.53143408755539 0.0213526425650343 0.152175591799896 0.549842662059236 0.296876493215095 0.201567953017075 0.681943011451513 0.707715067942627 0.204833527803421 0.152165625109337 0.316528779498767 0.115142209702171 0.716647293977439 0.78091736931121 0.766062655870337 0.730356704692822 0.0632108557899483 0.719521999265999 0.350756755452603 0.595048720042687 0.738017550369259 0.816392507664859 0.548548798963893 0.161820795217063 0.318156105945818 0.153221504683606 0.236010594414547 0.133167426548898 0.67252235326916 0.299048693303484 0.892145099339541 0.881780765971635 0.435103609943762 0.400857399641536 0.949710368788801 0.562192871947773 0.543330430043861 0.101571069962811 0.996352558676153 0.410339262187481 0.729497938500717 0.528330049037468 0.544767689565197 0.906519641145133 0.680447443367448 0.937150063626468 0.937627712183166 0.694254100483377 0.349927853604313 0.126183641150128 0.100088026453741 0.186975559303537 0.121562753419857 0.858155946165789 0.555975645352155 0.0998746910085902 0.229134525062982 0.0891995450621471 0.552273153385613 0.596111749568954 0.565637267681304 0.821231762014795 0.510739042812493 0.871867980228271 0.570701579442248 0.710031631644815 0.124971555443481 0.934214603223372 0.688817988452502 0.940037605590187 0.139743459767196 0.497255180017091 0.730427510400768 0.773067446486093 0.746926252257544 0.0973534739622846 0.373356963787228 0.448638584327418 0.924642400357407 0.953222830710001 0.552976907447446 0.153909738101065 0.405643721665256 0.894656720573548 0.199371294095181 0.163357140086591 0.0599738395516761 0.4005194066884 0.611981586774345 0.896265537682921 0.101285681792069 0.289035445190966 0.609706377496477 0.19305878106039 0.522954749746714 0.903736837599426 0.809516110999975 0.734104197861161 0.14937788927462 0.666285373545252 0.7952670975402 0.593648611966055 0.158639089628123 0.319649661513977 0.270070320488885 0.994570993434172 0.815679092558567 0.965396656983066 0.838114646619652 0.363773156281095 0.829100948150735 0.0612082099937834 0.747168687239755 0.5959908132907 0.286563216345385 0.460280957496725 0.0612141546490602 0.913207439184189 0.308918917942792 0.275954672435764 0.7412663784693 0.341716151367873 0.0343464818247594 0.8687289751973 0.739041225770488 0.244721245006658 0.226874734547455 0.403201476794202 0.265449704059865 0.872965424675494 0.728092846963555 0.208101809609216 0.434000845041592 0.14044176106574 0.710503226057626 0.718108112681657 0.542352899136022 0.653914680988528 0.105978481872007 0.505355540404562 0.420608106735162 0.776833717066329 0.231300215995871 0.332409887346439 0.541836675091181 0.232997391566169 0.583033325632568 0.581905780576635 0.0687996680126525 0.883003980331123 0.926686069576535 0.604834715900943 0.699754623856861 0.164158069784753 0.310434003351256 0.269372870896477 0.280475116698071 0.806560652905609 0.413240552924108 0.0842883460922167 0.843530605139676 0.960916547633242 0.226198797507677 0.339771390471142 0.117319577652961 0.270149066310842 0.564810770202894 0.163758774965536 0.545163350976072 0.481712565773632 0.0105735787888989 0.2084308523871 0.613649146251846 0.552549389230553 0.0242648473568261 0.957501112443861 0.585122450604104 0.945273153157905 0.245624762075022 0.265001577781513 0.593860736121424 0.87059479250107 0.271755040865391 0.75177129175514 0.0856007238267921 0.770624939072877 0.404650617789011 0.384364046237897 0.752606057813391 0.185988098585512 0.873941522319801 0.583678871861193 0.550625610961579 0.617729238618631 0.363484759363346 0.505287538066041 0.430239820925053 0.710773908179253 0.151371659808792 0.799283996769227 0.615278775878251 0.0415918659395538 0.338626760351472 0.571521243217867 0.548008080588188 0.465747367446311 0.360936696862336 0.751329955384135 0.164106947132386 0.199934096669313 0.584034625249915 0.57209576522233 0.47067164857639 0.55037461673608 0.59018889197614 0.574454522146843 0.762694267590996 0.231525060653221 0.287435145373456 0.430015470695216 0.589868416739628 0.760871656336822 0.955051803137176 0.187588861482218 0.368827721250709 0.519852806495037 0.908241122956388 0.698406061404385 0.487449929376598 0.416060986667872 0.345531472845469 0.490231523015536 0.790081961294636 0.632520741634071 0.651911294588354 0.0571569578489289 0.219164165137336 0.718789445089642 0.146479156652931 0.0326301169348881 0.249312746685464 0.387414342213888 0.520477564178873 0.569443493536673 0.791810626941733 0.282385375774465 0.226296953470446 0.250340592334978 0.635601327230688 0.920971002695151 0.932387499709148 0.749042582958937 0.300755862302613 0.7421455985168 0.212940072338097 0.750332974228077 0.841085669153836 0.907744404019322 0.0408167151617818 0.183287612495478 0.559643206994515 0.487559142536484 0.777996255834587 0.551587006705813 0.27267112584319 0.721595612352248 0.158625627139118 0.519316362324171 0.0723411983530968 0.845146751531865 0.461765964655206 0.764501230502501 0.552996992499102 0.185955359186046 0.428426586044952 0.943222565411124 0.87625522203045 0.471849340107292 0.70175837260671 0.644000275966246 0.706301554311067 0.199473762065172 0.670295400347095 0.29743443795247 0.385205696939956 0.0353955613495782 0.234100303759333 0.842391193823423 0.034636859910097 0.559781252539251 0.877810024605133 0.83220464275917 0.797590036015026 0.815964199746959 0.768005756919738 0.034290139907971 0.638669543380383 0.213462975649163 0.30415060806321 0.874049271098338 0.434938095896505 0.0276677840179764 0.543735938745085 0.814838050843682 0.674977139311377 0.871797735563014 0.775714709816966 0.452008818930481 0.58901192744961 0.198919282008428 0.292055824960116 0.264798585667741 0.50704361505108 0.439837486923207 0.788578133620322 0.636744730155915 0.372526630288921 0.748506534330081 0.808550168597139 0.211499004918151 0.748897583389189 0.52239721737802 0.89474887955701 0.891432429677807 0.553509446678218 0.589866708717309 0.140666234614328 0.0178343417891301 0.976995602590032 0.804479499857407 0.570396348247305 0.267885070741177 0.273179663557094 0.397640636260621 0.0625136862578802 0.0512479511415586 0.796798378964886 0.923726880571339 0.855453660544008 0.657572692458052 0.628138026206288 0.298094538559671 0.833000408974476 0.108556310753338 0.832469320525415 0.312681442399044 0.267561250915751 0.94275835952023 0.0431749260262586 0.0453139870241284 0.851628944252152 0.974205382631626 0.203461330332793 0.0598411863786168 0.487905947593972 0.362917575170286 0.939749107481912 0.194880642259959 0.403994730764534 0.766737606821116 0.0225150232086889 0.647840078175068 0.432462646241765 0.258636337798089 0.184169172372203 0.273314397244249 0.663314741482027 0.900638591835741 0.292115704626776 0.503222890598699 0.977480235367548 0.186390703879297 0.435263121479657 0.0177528917137533 0.234711808941793 0.588526239662897 0.794538365092594 0.267351129825693 0.0666637957841158 0.177899133081082 0.108314466318116 0.632871688588057 0.295737295574509 0.0750599960098043 0.111672243191861 0.430729776232038 0.352677118137945 0.205341287571937 0.641973752893973 0.301027068817057 0.739340316383168 0.390480403627735 0.3437204404152 0.245036009547766 0.109373795129359 0.686538896593265 0.0816016710107215 0.55963549623033 0.0433197580208071 0.859344683599193 0.690682318555191 0.21691411081003 0.0235774642624892 0.763836148048285 0.4973642574111 0.165251213288866 0.264305485617369 0.562489424268715 0.951310263383202 0.711773636692669 0.695946019217372 0.0158906755479984 0.188271533339284 0.520603370971512 0.907857769678812 0.0988639868958853 0.759294451700989 0.341131030174438 0.613400821473915 0.996144221674185 0.135295014292933 0.535802357401699 0.805367625132203 0.951217269520275 0.100989025975578 0.664451013356447 0.281082809141371 0.732726069565397 0.196878867021296 0.35341521382099 0.573240819005296 0.869943633771036 0.285113257989287 0.76691110500833 0.844967675879598 0.620107727695722 0.979063962758519 0.118048196462914 0.686939751221798 0.0677876878390089 0.295242407287005 0.335792996196542 0.305855391824152 0.171590372393839 0.859819020067807 0.440136885717511 0.941659251076635 0.49850621485617 0.0173824839084409 0.851402945930604 0.883136783561204 0.364655856913887 0.095935449169483 0.365547444333788 0.70256966937799 0.16067155712517 0.417947784063872 0.326675974824466 0.739945000540465 0.885725275711156 0.238770643230528 0.024019976425916 0.84776226547081 0.103543799552135 0.300951961474493 0.238668728005141 0.562177751916461 0.467104415150825 0.446879659024999 0.927369230098557 0.955436943729874 0.892666623785626 0.371919548446313 0.955388581804 0.403418445417192 0.203894609033596 0.351268228383269 0.0745562310772948 0.0851297559193335 0.0435795002710074 0.413160808796529 0.491813454562798 0.993963065878488 0.571056339826901 0.531927865513135 0.149992676349357 0.110708063209895 0.678679228129331 0.878952402716968 0.943941309961956 0.422639644846786 0.97516444200417 0.818235392521601 0.299473546221852 0.918503517357167 0.926261394144967 0.573903157559689 0.133136258253362 0.494949016580358 0.261046479686629 0.169698485967238 0.863576888376847 0.839203618031461 0.390403583652806 0.392374475446995 0.148122023106553 0.774781011464074 0.326768694850616 0.262097033734899 0.964546406469308 0.837621167392936 0.794666271070018 0.236543270102702 0.43391609163722 0.304100319598801 0.548961479514837 0.441727159144357 0.358229424091987 0.58607292606961 0.140348666473292 0.943887257394381 0.481447115824558 0.822713460081723 0.163245170349255 0.0458981087594293 0.317659692424349 0.0184817933500744 0.488430286243092 0.814111212664284 0.124269036874175 0.831835344592109 0.907351104335394 0.940772710505407 0.321900714838412 0.309913119932171 0.915148490606807 0.676862750311848 0.411928765967023 0.939227197174914 0.628863862161525 0.120228209889028 0.546025964021683 0.989046145840548 0.618239193921909 0.72738731757272 0.310219714317936 0.6742620491446 0.271322818095796 0.48178790822858 0.409444908970036 0.580792814102024 0.715090278810821 0.427436198177747 0.888515576806385 0.904468065926339 0.470538319570478 0.624135105099995 0.846496405643411 0.632773750911001 0.193320531907957 0.928123045349494 0.0590841334918514 0.0601344556547701 0.339856228008866 0.201125702473801 0.351224300169852 0.881702633977402 0.435189041025005 0.57349037489621 0.206976458244026 0.056827312768437 0.192170680679847 0.730318124133628 0.0665617021499202 0.45520211256342 0.870690862878691 0.704537687038537 0.871145737112965 0.472296836883761 0.222757344827987 0.891630118163303 0.593903533720877 0.46363499654457 0.777529500357341 0.117753637987189 0.635960031049326 0.715095718435477 0.636413356077392 0.299998194205109 0.30917206114158 0.720606695320457 0.866046703401953 0.614382983404212 0.304858864527196 0.0899480345565826 0.952276762679685 0.202807079413906 0.693610360010061 0.197269739054609 0.370425194187555 0.265474505650345 0.0764554394106381 0.0829867408843711 0.53598143927753 0.395152306596283 0.367314186200965 0.290099868564866 0.982478667024989 0.770891166506335 0.540642155045644 0.168669119693805 0.846852519076783 0.813931201864034 0.494601951746736 0.939557829957921 0.865391951601487 0.347690360271372 0.427091890843585 0.835654652607627 0.271880144164898 0.571494319161866 0.964185636658221 0.753017238485627 0.411831988638733 0.504567161097657 0.558775820014998 0.15231826352654 0.0794982394506223 0.666808556455653 0.595641393645201 0.957207002295181 0.125043374670204 0.0686911541968584 0.205064333712216 0.903531286448706 0.140770034196321 0.998870793944225 0.593852607456502 0.206035645666998 0.393595406219829 0.937912971964106 0.218073434301186 0.115321915547829 0.37840637749061 0.458061982030049 0.97782343121944 0.347299967452418 0.834617182563525 0.792311372293625 0.967149428795092 0.363769061868079 0.457316809925251 0.833536487568636 0.471572022284381 0.349620095181745 0.259149990589358 0.567674660552293 0.313503505473491 0.381723291371018 0.252578751358669 0.861129696464632 0.621221302466001 0.544567162904423 0.783165230408777 0.613994620388839 0.330501222193707 0.79826946885325 0.476768396901898 0.963409964945167 0.810098547302186 0.268626087119337 0.688993725278415 0.509928818338085 0.256853230725974 0.625228447297122 0.156581756460946 0.783170193124097 0.866924774856307 0.932408306233119 0.473813618328422 0.488822660460137 0.607795868094545 0.253431169285905 0.0609084327146411 0.41193397393683 0.0318652820587158 0.438473877047654 0.265790766612627 0.565030139507726 0.669521748756524 0.997293911089655 0.349760992501397 0.0938546805991791 0.089924224356655 0.0406241763290018 0.146209266998339 0.0363332531554624 0.503225468306337 0.909179490825627 0.296051201494411 0.0902696934225969 0.714830203254242 0.0880663317232393 0.0910244641057216 0.499916512519121 0.727295728621539 0.75105591830099 0.098325338892173 0.433447420916054 0.646741011682898 0.0137049993709661 0.893459291819017 0.698135619235691 0.906435121700633 0.0982411518320441 0.345253250992391 0.328512433506548 0.166828157918062 0.591749787880108 0.600356695132796 0.714346214500256 0.748268393375911 0.664823412010446 0.07246905984357 0.33084674266167 0.23014792190399 0.196061302891467 0.419359538962599 0.817035576223861 0.296328449014109 0.493341119636316 0.250520338518545 0.831720973481424 0.985529974214733 0.552595269798767 0.40218731330242 0.138433396506589 0.966223611547612 0.610785925511736 0.519787643253803 0.627348660810385 0.73616283705458 0.993700280075427 0.821892116866075 0.127149668608326 0.0130923993024044 0.514256840401795 0.697171161728911 0.941515729026869 0.169669112593401 0.389973822417669 0.196440234212205 0.982855004963931 0.777090651798062 0.950707731426228 0.446665158160031 0.282254075419623 0.798258151649497 0.117429141867906 0.78785564340651 0.33718278007349 0.311540188677609 0.479809046816081 0.978157238711137 0.75708762624301 0.972009557667188 0.410828358873259 0.720231045430992 0.975782486998942 0.0926211600191891 0.931974131569732 0.943874127981253 0.0703519857721403 0.918424028626177 0.877293303136248 0.115721562113613 0.756802832307294 0.394592944500037 0.339389921089169 0.424745375437196 0.340782321628649 0.813899513785727 0.962669562855735 0.379705823813565 0.394816997151356 0.776576729319058 0.690134561560117 0.857127247657627 0.477408014379907 0.51353466344066 0.811121522206813 0.0360904950089753 0.273106037422549 0.714193341662176 0.886603822000325 0.547784878720995 0.941556919333525 0.281722076947335 0.648561411267147 0.492572839902714 0.752601057295687 0.735535899510141 0.475629649201874 0.38865945613943 0.361183601284865 0.0611721001891419 0.236688567250967 0.850796410378534 0.998049353687093 0.0934261338808574 0.0428429577127099 0.384576600741129 0.930736852649134 0.824598158984445 0.0699044458917342 0.760589195776265 0.0785372512345202 0.314078547030222 0.212632802349981 0.668961606409866 0.282739302432165 0.3039006384206 0.466382650788873 0.967362790748011 0.464555478584953 0.116510461894795 0.410318271031138 0.599540519088041 0.920545936101116 0.848300299877301 0.823963489700109 0.676405238208827 0.507081101646181 0.716903747881297 0.222135429468472 0.451042712179478 0.451445780552458 0.195566585175693 0.473463549588341 0.524860361204483 0.87869357394753 0.298244020938873 0.902663915834855 0.664236199238803 0.620457969543058 0.956840833197348 0.828112292508595 0.938578538934234 0.508156509839464 0.0427002680068836 0.528606944810599 0.436411170409992 0.0635394901176915 0.504806886524893 0.299940190827474 0.574806952844374 0.660986304373946 0.0247177816834301 0.941236983933486 0.787934502866119 0.686047234877478 0.584356691874564 0.791766029119026 0.269236645398196 0.540525057092309 0.548804042499978 0.810029339205939 0.419637867077254 0.318952467087656 0.0612708496954292 0.702696549159009 0.135752591628116 0.90836677623447 0.102962868199684 0.989562649254221 0.480517529633362 0.753826263195369 0.386401737839915 0.305029272369575 0.518394512252417 0.593459395132959 0.887138484849129 0.81153777024243 0.617516406590585 0.787282471223734 0.952551080975682 0.184202578614932 0.662938058481086 0.395144177700859 0.393950885080267 0.771250555838924 0.932046412492637 0.969697155223694 0.557952246458735 0.041927246148698 0.8976775936177 0.562102466165088 0.63621913757408 0.529406884501223 0.623260333517101 0.0390039793192409 0.255281203172635 0.518171389447525 0.683516808571294 0.993088944542687 0.242388675683178 0.902665163313504 0.832870925439056 0.209584290231578 0.284692635941319 0.608579267859459 0.766421959917061 0.443852495111059 0.0435207429202274 0.0319827608019114 0.0330260017025284 0.383241938271094 0.448248029004317 0.996048660706729 0.0340458408533596 0.59057677739067 0.921587893103715 0.891955560264178 0.348105624062009 0.928000280726701 0.22010414398741 0.76457182046026 0.87414370629238 0.981200942320284 0.0853494145045988 0.23991689193761 0.881051879317965 0.428004455820192 0.861863066158257 0.524707407460082 0.75425246847095 0.562717890578788 0.460232324500103 0.856268382810522 0.797628573009279 0.643091281470843 0.309103110055439 0.536834636994172 0.883658942810725 0.782873985865153 0.54097901185276 0.0846657346608117 0.828646334845107 0.857883679110091 0.82120847182814 0.508657389804721 0.0251448133098893 0.947739817677066 0.269693014440127 0.0922875915584154 0.0131199494027533 0.987075891154818 0.122471453102771 0.82502253822051 0.744014843390323 0.844063004455529 0.806525354238693 0.0534140535211191 0.058963141432032 0.900306505735498 0.549333035682794 0.556298833140172 0.630643571859691 0.194199420954101 0.428654782897793 0.845346424411982 0.0195197177142836 0.156343195992522 0.239446519878693 0.878826844866853 0.696510335730854 0.892969673045445 0.938556320583448 0.454246441575233 0.490735899701249 0.479914408742916 0.778410015597474 0.247710366814863 0.259730952137616 0.907081888669636 0.770354959291872 0.102081222806592 0.438529331991449 0.863212707592174 0.777579859585967 0.20908100774046 0.530201854791958 0.589461491601542 0.864476860780269 0.926866643493995 0.174127158720512 0.801949445581995 0.0357129079778679 0.380364052972291 0.189073257579003 0.104631801471114 0.488543939569499 0.672885497484822 0.390525549585 0.743406334277242 0.81085573411081 0.490403620209545 0.573124464883003 0.19007664716104 0.666142656409647 0.252689232972916 0.0299899316392839 0.106622352348641 0.44281970011536 0.979330287924968 0.745669803840574 0.140861245584674 0.883882676216308 0.520520437152591 0.629689424722455 0.594202871662565 0.531224090014584 0.0455749735259451 0.363358823258895 0.381172529547475 0.219675942100585 0.201480162974913 0.854454758842476 0.871564414182212 0.210084896590561 0.882104991711676 0.260976994987577 0.39924545484595 0.292580102526117 0.658141013488639 0.455712911735754 0.0679623797978274 0.023836478816811 0.786348832570948 0.39506221752381 0.791482422270346 0.261714179494884 0.0683533696178347 0.851007750825956 0.687999640614726 0.6458257650421 0.464988528166432 0.358544387787115 0.71976874118438 0.161519501924049 0.31690619941568 0.645367310876027 0.684906507162377 0.757931847276632 0.162234894509893 0.466123701236211 0.0288042409857735 0.649772040199023 0.53723960562842 0.33515417925315 0.375572015182115 0.994150949255563 0.23500022337772 0.768781744651496 0.613067791005596 0.636756674326025 0.951164289480075 0.955508447168395 0.883730995305814 0.160744869315531 0.692057489736471 0.404237708349247 0.444809795520268 0.673593061980791 0.0545027218223549 0.31639911086997 0.577399448358919 0.587717919137794 0.0576976395747624 0.747108040922321 0.446355162942782 0.747416515515652 0.171643981935922 0.922965577912983 0.865257307810243 0.786511944092344 0.276612500520423 0.617283452400006 0.480500921248458 0.234025556691922 0.411498677879572 0.484217781808693 0.425623472707812 0.692874049567617 0.826328435151372 0.905722519806586 0.420129893447738 0.886205761982128 0.242654107422568 0.363871115855873 0.303692646941636 0.151614973926917 0.47990153795341 0.208072391287424 0.992921121092513 0.0554051405470818 0.155903861534316 0.24522445488954 0.204529791185632 0.176276197703555 0.142491221425589 0.562693708117586 0.928095450531691 0.468298789518885 0.240198818885256 0.952216286242474 0.794927379507571 0.108513040163089 0.700144832965452 0.844961589926388 0.154645646547433 0.608720445239451 0.899807416312397 0.257057349074166 0.510155407206621 0.440571956573986 0.666537996730767 0.450634008024354 0.0907187387137674 0.840000325157307 0.346411734994035 0.938915898236446 0.205351815305185 0.202652148420457 0.600124213933013 0.190450892830268 0.962010752600618 0.916104215993546 0.39227677841438 0.258567337845452 0.501716997623444 0.728036768971942 0.0211582829942927 0.294915714941453 0.333612152962014 0.471747848314699 0.516428276144434 0.827482852630783 0.538996156526264 0.373334038716275 0.0278331168903969 0.639240153529681 0.0767943785758689 0.451952253426425 0.857717734023463 0.163092916409951 0.739649785594083 0.584221897104289 0.489646957102232 0.931134983892553 0.239870069767348 0.569413035418838 0.936955950462725 0.191589571149088 0.758290615405422 0.801842266605236 0.425695503766183 0.685022146957926 0.421708264194895 0.507254574017134 0.970983505095355 0.505722309499979 0.717093820569571 0.280145889287815 0.0419107191311196 0.847220239685848 0.941850075433031 0.121161567559466 0.923992231404409 0.219395885679405 0.710211017783731 0.562432885502931 0.233865763712674 0.881745729155373 0.555543550050352 0.381745808222331 0.635272456177045 0.953514359232504 0.317443555453792 0.78424348784145 0.0413737743091769 0.392512244388927 0.518002718670759 0.790329372361302 0.301832038068678 0.90411323385546 0.844857763606124 0.486051701507531 0.443124769497663 0.222276498512365 0.893033958533779 0.353729803410824 0.197236535653938 0.645873996734153 0.888336265119724 0.946624709605239 0.221624168599956 0.924544313084334 0.838027360916603 0.400512477327138 0.117891063941643 0.281536263020243 0.854116025054827 0.192539478195831 0.563652378632687 0.350570106876548 0.536292329074349 0.970298719762359 0.670755036990158 0.535523030289914 0.906432423901279 0.357020078597125 0.621715949878562 0.960620842638891 0.903226218910422 0.318181904919911 0.929623277878854 0.134459737441503 0.23362180856755 0.191528371626046 0.670538652460091 0.169707228920888 0.654299215590581 0.743841063529253 0.0148590837744996 0.197257020396646 0.592324512726627 0.502802272238769 0.275577019250486 0.0841554112453014 0.160408928524703 0.803571227525827 0.439475314735901 0.486345275968779 0.28751571147237 0.208371406525839 0.558959368104115 0.31697223211173 0.874967688529287 0.101059002566617 0.679809137908742 0.808669599464629 0.34549927766202 0.915215294333175 0.476979996894952 0.105272987748031 0.191981665536296 0.0914289053506218 0.941608874560334 0.195597662192304 0.105160928114783 0.62995232623769 0.853384770220146 0.362854775039013 0.0773491746513173 0.486176728510763 0.960239305719733 0.850044259354472 0.505163337413687 0.347900565725286 0.05888379445998 0.951213625969831 0.524257699935697 0.729416397376917 0.117535645703319 0.302448115495499 0.427725674768444 0.0334865377657115 0.405691680673044 0.992621764710639 0.882505274694413 0.43615779302083 0.204424176858738 0.640811767100822 0.356561461465899 0.774654879432637 0.458070950184483 0.905409029482398 0.732747360835783 0.406228833638597 0.474166280911304 0.508736313804984 0.228285889909603 0.643217726985458 0.513843475950416 0.733324320863467 0.805363910817541 0.535186678743921 0.515367178227752 0.110079283721279 0.378111810255796 0.902613833670039 0.334881949308328 0.868990072340239 0.265664999005385 0.130011255086865 0.792498032625299 0.824533161704894 0.69998218544526 0.603495087949559 0.934090707295109 0.318614114089869 0.23570726325037 0.909936780438293 0.0252965997904539 0.219236059738323 0.704173504179344 0.612534060999751 0.995008205196355 0.327671256947797 0.516233174125664 0.565167008107528 0.77998039690312 0.997357724509202 0.756047185715288 0.187101476506796 0.183592921139207 0.114196431182791 0.204550671009347 0.980976575494278 0.294091186875012 0.986918953177519 0.690371849655639 0.454828217257746 0.220635051261634 0.0572534982208163 0.770250688102096 0.217568451163825 0.49130181774497 0.773905253331177 0.703072866122238 0.471991710336879 0.885274493354373 0.513589992069174 0.500498289123643 0.726817813143134 0.106332030044869 0.194007971014362 0.159505939998198 0.868915342099499 0.707876752885059 0.882984227202833 0.366723072407767 0.27337489143014 0.0111514248675667 0.977868745443411 0.809036493031308 0.130043755916413 0.226671118694358 0.426113655751105 0.381694312847685 0.333159071113914 0.516472134746146 0.231074137459509 0.374171994004864 0.275219607627951 0.972284684104379 0.64496745985467 0.379777293598745 0.0638362111663446 0.706383557131048 0.4059475426469 0.0867016163584776 0.180573236104101 0.377216479938943 0.772540663359687 0.730825338764116 0.419141567193437 0.648739209705964 0.0456818224233575 0.703828609064221 0.916471157043707 0.731739242959302 0.501984346681274 0.622768376066815 0.657202404283453 0.68869352272246 0.808600093098357 0.832327537846286 0.0248581345565617 0.889553526064847 0.260721683683805 0.981021443465725 0.270389412941877 0.571669207508676 0.360494738596026 0.342950646972749 0.97192218022421 0.523069164652843 0.0873802021006122 0.995113250873983 0.976804865133017 0.572947700938676 0.323922416493297 0.606025142224971 0.801316231458914 0.410050971300807 0.334271547079552 0.0833618762926198 0.604549802334513 0.780400339199696 0.816023134123534 0.372358671764378 0.81026836482808 0.393819658025168 0.620544971728232 0.750849539185874 0.141672261604108 0.883956988325808 0.608812343755271 0.91929814419942 0.814452572334558 0.629621842589695 0.644819029718637 0.582507627480663 0.953902693896089 0.961210454017855 0.905867671046872 0.23996549612144 0.726535161265638 0.865753424675204 0.454069649970625 0.402783663878217 0.297492828113027 0.164660427500494 0.59406860843068 0.912362317808438 0.0225526739214547 0.267528629994486 0.273298114098143 0.319264481274877 0.499388342229649 0.711451062732376 0.974327755169943 0.248284089898225 0.129323795926757 0.412173788337968 0.561444191597402 0.0183366114529781 0.162402902131435 0.730765382109676 0.128436927350704 0.74626770270057 0.6200011540181 0.275865852278657 0.86777346855728 0.930950372265652 0.942038245785516 0.422135686753318 0.824611849901266 0.796483316384256 0.229004598963074 0.984900227768812 0.721237120365258 0.262700048363768 0.817693371577188 0.416042458659504 0.320199093108531 0.753093100723345 0.761552928122692 0.221206104436424 0.546732476043981 0.787316937777214 0.0725144051853567 0.974856813815422 0.711810590827372 0.849658731287345 0.625495345261879 0.101497201109305 0.946952187963761 0.743450539093465 0.648226918492001 0.111972560768481 0.557053999134805 0.955295263393782 0.0154563630442135 0.165278322207741 0.595290634089615 0.304574424643069 0.344519861706067 0.900440168969799 0.811105082780123 0.617899365017656 0.929369900259189 0.113670709058642 0.205534285795875 0.777055478293914 0.801478377867024 0.0126188419316895 0.189849097789265 0.452106011623982 0.843384845834225 0.926883726944216 0.0493623910821043 0.107100620034616 0.638667419762351 0.273744103850331 0.845249797371216 0.882978438136633 0.656178436835762 0.362489704976324 0.403871496608481 0.669995298059657 0.0866636618436314 0.751244362029247 0.408957744124345 0.809017839168664 0.696215422512032 0.603855428795796 0.261062435749918 0.10983510222286 0.0748433763673529 0.518032296039164 0.834895415480714 0.584931723058689 0.456884005828761 0.633543446389958 0.938602857161313 0.306765069067478 0.326764469973277 0.971325934987981 0.964376890209969 0.149657994562294 0.849092428996228 0.518532066596672 0.84281095471466 0.700851386708673 0.58541347063845 0.569672096995637 0.542849888221826 0.706343181419652 0.0593586011533625 0.449029200042132 0.17664987702854 0.715159122943878 0.696858694604598 0.41272294747876 0.357241697143763 0.606729887216352 0.340429976677988 0.612185623063706 0.895435288778972 0.868740907381289 0.596881849579513 0.233100717004854 0.513381500400137 0.695739040565677 0.220246856282465 0.570019536856562 0.547284058686346 0.821054356121458 0.759548399352934 0.582991513891611 0.966009720822331 0.351124088817742 0.228423273912631 0.401255985435564 0.95083284325432 0.804117145342752 0.287877654540353 0.291757070419844 0.125839757709764 0.0363288348866627 0.190687149197329 0.921259525006171 0.619043391221203 0.564588507632725 0.649001418331172 0.585538401291706 0.311333540566266 0.484834066687617 0.0205239629209973 0.182202489550691 0.106223727599718 0.314689761318732 0.751002310602926 0.490497101354413 0.210424821153283 0.520478632326704 0.2002835939941 0.873128511994146 0.847755397884175 0.745914626826998 0.297718227820005 0.616389588308521 0.230967182531022 0.907547766854987 0.424265816477127 0.375083653337788 0.670135669833981 0.566848756156396 0.397887564885896 0.369061233717948 0.857437851631548 0.124556813510135 0.374175088959746 0.279822743451223 0.156785416570492 0.208495853124186 0.214287402064074 0.586924361826386 0.385439643443096 0.0893527622707188 0.994294202539604 0.640401774668135 0.626005491882097 0.816740077529103 0.763380859601311 0.192071420610882 0.767917327464092 0.788827604686376 0.234998372443952 0.715803997027688 0.939876937163062 0.604521984390449 0.916888375955168 0.888606566681992 0.660926950252615 0.346365072331391 0.780659920789767 0.846903272694908 0.312139070399571 0.642365097226575 0.298296005900484 0.195661294206511 0.0635107840481214 0.0748547777044587 0.696714596759994 0.775752505746204 0.486176577762235 0.672068706690334 0.835362408836372 0.792816992308944 0.8908676374075 0.743748040392529 0.954133906872012 0.691658102946822 0.887069190314505 0.544943662195001 0.281626044602599 0.8302229832788 0.358279241640121 0.169495373761747 0.577265197804663 0.185923184747808 0.337378748550545 0.223155920018908 0.807008891899604 0.531398104757536 0.393633284899406 0.753582676162478 0.976692228782922 0.752086089488585 0.495893621381838 0.0199749904870987 0.387243938751053 0.786594987630378 0.685244850018062 0.992439412928652 0.516564864453394 0.755602859498467 0.961666002701968 0.240484504404012 0.926719904553611 0.415739412626717 0.402247732344549 0.675266962808091 0.976846697849687 0.559831528556533 0.683162549990229 0.516044819371309 0.15216621219879 0.754720250836108 0.390621531680226 0.292627817662433 0.792210294022225 0.252339737492148 0.267611540993676 0.601563008599915 0.607114474603441 0.998291529584676 0.420685516796075 0.536967193125747 0.229658766901121 0.728122428942006 0.11675460443832 0.646174490184057 0.03404727388639 0.501503524107393 0.85341821357375 0.951463384011295 0.945565682521556 0.329250163612887 0.69224540307885 0.611925407131202 0.2126789201051 0.951149570292328 0.417801213159692 0.324195907516405 0.0822863569972105 0.995301548233256 0.466690105639864 0.760404136052821 0.444476591714192 0.87192928094184 0.208104045712389 0.354412502236664 0.91947817574488 0.369057612987235 0.541635603522882 0.863958142008632 0.021107044168748 0.0523985872301273 0.497240701473784 0.470547930134926 0.520707563098986 0.962805860270746 0.878673755126074 0.323916417439468 0.647621144750156 0.265606716950424 0.553104689875618 0.9831211348949 0.954542886016425 0.428956145802513 0.923852638266981 0.964121895155404 0.107562951019499 0.462094722993206 0.0721551967971027 0.547355675301515 0.324655835053418 0.652326943548396 0.329342066738754 0.138171154228039 0.453564067757688 0.0958514619548805 0.0329890558659099 0.876934870849364 0.230252409765963 0.66671183997998 0.0784222964919172 0.252493045057636 0.372141154315323 0.311142970914952 0.539705990087241 0.477920989724807 0.986462964233942 0.695999297758099 0.360933043169789 0.821216526040807 0.533164013358764 0.915521826022305 0.999032124143559 0.880707578207366 0.600652104392648 0.284481393226888 0.551474403778557 0.251406870561186 0.348937504230998 0.854363839731086 0.316987442960963 0.689643679403234 0.551486089325044 0.904799271507654 0.410522228949703 0.589444106884766 0.366394853445236 0.460922134323046 0.328427610029466 0.0185196918528527 0.224619319427293 0.0732225973391905 0.863434041007422 0.60653697934933 0.124159311538097 0.709915765726473 0.755957714389078 0.0323481766181067 0.362375228526071 0.374831712439191 0.665413562995382 0.787485399949364 0.157573985119816 0.224853750676848 0.135391466151923 0.954968396327458 0.903551149065606 0.0301999819651246 0.830747252546716 0.54270000200253 0.709324635106605 0.724741004602984 0.446049747806974 0.304816248333082 0.0630676615145057 0.445820718149189 0.953848506254144 0.0767703141318634 0.817635588098783 0.476550397241954 0.167337615105789 0.901125766132027 0.0604222587984987 0.213421755377203 0.450983447954059 0.25989429323934 0.132751181740314 0.829079662642907 0.881495032738894 0.232003741168883 0.15097988051828 0.374164786657784 0.834646322207991 0.86211380245164 0.369281174207572 0.386218468658626 0.926772222130094 0.19836450368166 0.721823119081091 0.51457192119211 0.634726788455155 0.209600612102076 0.509686694995034 0.641907970062457 0.84087708390085 0.531628926109988 0.753108682911843 0.530687955408357 0.611512822699733 0.210940731023438 0.201097068781964 0.743458524385933 0.241800342209172 0.52158707749797 0.793599201298784 0.778222179473378 0.664614173052832 0.532997767697088 0.235901257935911 0.307665995750576 0.537782237173524 0.728609262325335 0.798551282624248 0.542104645583313 0.132854034879711 0.757054460183717 0.894314502973575 0.593104007320944 0.246465695914812 0.617436819204595 0.293362893303856 0.509305901676416 0.232868964653462 0.110598022316117 0.596932000895031 0.192143930192105 0.165315853750799 0.272153345216066 0.959433560597245 0.590968558064196 0.483017578267027 0.155677403360605 0.890938135625329 0.129771302384324 0.836270454123151 0.265345508013852 0.556705119786784 0.815062877982855 0.871670259702951 0.817393301329575 0.255240941790398 0.206540877055377 0.849316045767628 0.926008847255725 0.357825642083772 0.498970609989483 0.323079323768616 0.26081559056649 0.261516981518362 0.417064404140692 0.878786397699732 0.0156464534811676 0.936241306548472 0.932129723643884 0.432796854346525 0.56895590917673 0.766912655597553 0.99709293656284 0.265679071403574 0.3415674213483 0.212076390222646 0.0592908516759053 0.114827541050035 0.716342053562403 0.0932589512271807 0.326471615831833 0.44954910336528 0.180391097536776 0.859900968719739 0.907898444812745 0.967199224215001 0.822804361905437 0.266987875199411 0.56065032426035 0.612026868036483 0.924896963911597 0.162614184031263 0.160162547111977 0.679788542294409 0.812707893459592 0.158899921232369 0.958609559459146 0.867245031115599 0.895638134754263 0.601527564025018 0.12102271433454 0.550848437570967 0.665585986350197 0.822550513599999 0.474214796351735 0.280463787738699 0.25971515028039 0.78721249809023 0.627318989166524 0.958395551638678 0.843796612443402 0.120614060659427 0.987922249867115 0.32246104458347 0.210483732940629 0.674465137147345 0.742942718472332 0.701180547503754 0.375964108877815 0.202761209909804 0.424592722037341 0.678248809271026 0.423515306168701 0.573278155312873 0.539787018112838 0.666895859907381 0.647597864014097 0.775060853748582 0.285646829640027 0.429664449058473 0.14149389105849 0.428527573959436 0.435936128143221 0.104658862906508 0.930907662948594 0.489236451571342 0.784023822110612 0.985012282561511 0.548042241034564 0.956343543766998 0.287190834102221 0.680876112943515 0.280935960942879 0.184385546529666 0.0679042093059979 0.0981321809301153 0.489059445830062 0.561710237625521 0.727152709527872 0.378830882119946 0.755153057698626 0.594338566774968 0.0831588419969194 0.85942904699361 0.78690410832176 0.693124596849084 0.779334101541899 0.354412003429607 0.379631189922802 0.70439277920872 0.182120112625416 0.989974033690523 0.0967629255913198 0.295366240749136 0.239412083290517 0.896568283371162 0.0832975504663773 0.423614527743775 0.66634632112924 0.867977541727014 0.794670921685174 0.825745044569485 0.617991332453676 0.258458906318992 0.514270945070311 0.75097133961739 0.994757928524632 0.890259507931769 0.51097610847326 0.751697047874331 0.836899933416862 0.293162856921554 0.896838057083078 0.973924092561938 0.746425777745899 0.974690083176829 0.916616020847578 0.606279360025656 0.266815014120657 0.910157705633901 0.522263090834022 0.019383341697976 0.804096145888325 0.774184897614177 0.480547719676979 0.365081345096696 0.653925608182326 0.297919637535233 0.18821265520528 0.225456485475879 0.53117968581384 0.718224065268878 0.407879962217994 0.026476832840126 0.456702032531612 0.595806001818273 0.0144142677402124 0.263236004330684 0.709714740950149 0.653202711362392 0.0856900478620082 0.740496598856989 0.283994004793931 0.972587096255738 0.936841614618897 0.902599088205025 0.867095108707435 0.701593028670177 0.890076975666452 0.656794192020316 0.790335688125342 0.0844675621204078 0.366167019172572 0.858774097883143 0.0504437939496711 0.19017693642294 0.872777521705721 0.546896440654527 0.157274650174659 0.951260538958013 0.980642668886576 0.335397007933352 0.783307323344052 0.427385049478617 0.728188927252777 0.943715706260409 0.956912259648088 0.161147499503568 0.10176917404402 0.316801512399688 0.373323165690526 0.972516633304767 0.333772465032525 0.417356351485942 0.131761185266078 0.765860831711907 0.187590109882876 0.342524894864764 0.365719214214478 0.0511766420165077 0.486960526353214 0.833912138610613 0.8986789478641 0.958459080848843 0.136668481600937 0.19733565258095 0.945578261725605 0.312755187703297 0.375924873000477 0.013763309547212 0.128075337412301 0.892137531256303 0.37650027183583 0.0575291029503569 0.62924066294916 0.0208401734032668 0.0452491861325689 0.265407805650029 0.0158387210126966 0.779633497339673 0.690278315956239 0.317998952909838 0.619809297241736 0.4907352045062 0.815392962861806 0.21277954082936 0.522674937888514 0.588404246992432 0.0469857342680916 0.908175867053215 0.818235385376029 0.731602350617759 0.0274405670305714 0.843420451069251 0.614734260207042 0.793434389131144 0.995378031213768 0.818774711517617 0.229778191084042 0.814473946124781 0.954640172293875 0.359320287005976 0.229924987419508 0.205007962291129 0.185983215624001 0.915141957018059 0.307354921551887 0.394356569193769 0.10043109875638 0.0423932727775536 0.88940550968051 0.44245449290378 0.835147753534839 0.92313052192796 0.330844997528475 0.220807239504065 0.600083043449558 0.755167555834632 0.464427394429222 0.920837349141948 0.409711179046426 0.0233012788975611 0.743553642327897 0.109296936660539 0.18425386515446 0.209380295202136 0.937136432409752 0.622787933729123 0.970642109005712 0.822680565554183 0.0675261891609989 0.317278496418148 0.643824105104432 0.569063291226048 0.405709275838453 0.151772532877512 0.747678391295485 0.0513597429310903 0.0406443305313587 0.934239387987182 0.260994125460275 0.894686169782653 0.294174451003782 0.221844532061368 0.253187942528166 0.395020497983787 0.646698823531624 0.758796775257215 0.874701433896553 0.220531534275506 0.0830174089898355 0.282863201356959 0.2911975211557 0.568292002284434 0.82808665212011 0.213615393475629 0.309951806752942 0.470764778205194 0.0147208049613982 0.846287997416221 0.0496601062873378 0.4364932744205 0.805669243433513 0.0874201108142734 0.237661932059564 0.207770967299584 0.318206101672258 0.363599428974558 0.999139698662329 0.524376388816163 0.496674297531135 0.482501485378016 0.0193136041378602 0.407078755686525 0.0646387539198622 0.340384035487659 0.415483557798434 0.303950494462624 0.733037251178175 0.462313939244486 0.562112253985833 0.662131220547017 0.57256405077409 0.114041916476563 0.703435537577607 0.487207080873195 0.303664040449075 0.557161154369824 0.229745827172883 0.385345706595108 0.805064138839953 0.208028428498656 0.4371152967331 0.990131333786994 0.97404473771574 0.420880282742437 0.0659988168254495 0.263203976722434 0.466719376670662 0.63883304053219 0.297724585996475 0.621274811509065 0.176332128634676 0.179257001834922 0.678838454303332 0.664483568354044 0.114249781179242 0.102775421624538 0.198315074529964 0.815013087172992 0.275852985868696 0.9992114337557 0.861310125857126 0.871938410678413 0.173315402558073 0.373752477676608 0.0671703080739826 0.810751351357903 0.811560235230718 0.830674517995212 0.120619977423921 0.789851629990153 0.443512654220685 0.214306829031557 0.333583737555891 0.684892772219609 0.114850957551971 0.823777957677375 0.927958055234049 0.316557583992835 0.545347403173801 0.472459429544397 0.457976218103431 0.484345397583675 0.577203286490403 0.191537040818948 0.882718832343817 0.686329939309508 0.138888851606753 0.61223467142554 0.593780671134591 0.582429519689176 0.195858128219843 0.357096067150123 0.19553088843124 0.372497121610213 0.967538439061027 0.649136590894777 0.0755818574503064 0.900119339912199 0.299489071015269 0.290457835698035 0.35428010399919 0.560870054070838 0.323628392782994 0.301725685442798 0.227236831129994 0.642250285856426 0.451306445116643 0.656513407442253 0.697011042588856 0.0117382872756571 0.548545597055927 0.602722492290195 0.927715466045774 0.730010094179306 0.876507345256396 0.0597563654370606 0.594864290051628 0.702164916263428 0.580194337142166 0.620257392632775 0.956679103767965 0.16477470894577 0.664640421045478 0.0482325172610581 0.521365703514311 0.649525221984368 0.690525032519363 0.102139492875431 0.185118561249692 0.439263988579623 0.813083618953824 0.256279733073898 0.908169087748975 0.976168255941011 0.633880317257717 0.409344617403112 0.734524826363195 0.330025693567004 0.0912418333417736 0.421732060564682 0.820944527520333 0.81912170443451 0.721181606643368 0.0518062713672407 0.361497509970795 0.574834057153203 0.351285253977403 0.205441314291675 0.299444088945165 0.301762067931704 0.227999053953681 0.0219485740875825 0.905002280217595 0.0419429209991358 0.841136700527277 0.862230028875638 0.247084829111118 0.511762595355976 0.606254162893165 0.366860035513528 0.828757612153422 0.145798490166198 0.993209553738125 0.834801425617188 0.980094749617856 0.990292886421084 0.637890754123218 0.660005827185232 0.520493980094325 0.0139830441982485 0.523292711351533 0.917095205702353 0.811406231548171 0.417375816255808 0.720632844197098 0.466761528863572 0.233203163538128 0.846045317410026 0.584143128462601 0.196634356596041 0.559649508006405 0.86718355291523 0.822540188017301 0.288216135697439 0.237228650592733 0.90052340451628 0.189129506833851 0.572074611792341 0.248893801772501 0.709718359145336 0.931582214899827 0.610486401093658 0.329626735742204 0.910571558519732 0.0862883134512231 0.761944227968343 0.647290035518818 0.78270941111492 0.113635926716961 0.767309940436389 0.168952293428592 0.204496045412961 0.468955783185083 0.127891613219399 0.260090322569013 0.49117817559978 0.207291612334084 0.859134350216482 0.527322129162494 0.31061457865173 0.691093375447672 0.410639274579007 0.689651690972969 0.295362123746891 0.293125577317551 0.505489065337461 0.454362865078729 0.691420097297523 0.348927180031315 0.18262458312558 0.516982168189716 0.266127186848316 0.309360500029288 0.127965604469646 0.560697473282926 0.515208685512189 0.716013267103117 0.322837047372013 0.445339328539558 0.939594102497213 0.787849453727249 0.401265406988095 0.584826575268526 0.892325052283704 0.0743430998572148 0.425682544233277 0.260243493446615 0.303914497373626 0.581868980878498 0.898927858117968 0.643698620323557 0.642502492985222 0.361403447038028 0.462185055245645 0.815367106262129 0.384629871444777 0.285285748189781 0.216190757825971 0.793099332086276 0.771581302029081 0.451416703143623 0.282492429357953 0.644328305225354 0.967275753065478 0.55632637816947 0.0256462591583841 0.216224974975921 0.0876763842348009 0.670723326783627 0.095441304713022 0.0950205289199948 0.769684651349671 0.903509890299756 0.252485347201582 0.271440812703222 0.0626248453184962 0.837901623044163 0.291176094349939 0.0365428828145377 0.777247028271668 0.384735503981356 0.369442492651287 0.512649035428185 0.833935213969089 0.560565280653536 0.124834223764483 0.434540783397388 0.203638237880077 0.301273458988871 0.516621312862262 0.018596957619302 0.811036864691414 0.403109975203406 0.30719841968501 0.495550909815356 0.546982863356825 0.55658526733052 0.599829711008351 0.917036659722216 0.252862954286393 0.953717209126335 0.0576268624491058 0.190934938287828 0.858328428529203 0.19745061585214 0.771959036120679 0.841658466770314 0.555174879310653 0.812503828818444 0.690601814230904 0.0380593254207633 0.107486686324701 0.506486159209162 0.187670355583541 0.279652840869967 0.872206452626269 0.833366211343091 0.261220392317045 0.419004029906355 0.323584347474389 0.539842072443571 0.232762658358552 0.04899303736398 0.492095381740946 0.713081420054659 0.657624361400958 0.956042725078296 0.0736447314824909 0.109308182178065 0.801423992454074 0.549608344677836 0.549733069492504 0.64556723385118 0.444212506338954 0.319847270476166 0.87987901704153 0.732285632845014 0.770340290814638 0.212616154549178 0.0598562568519264 0.218786159513984 0.0614750643935986 0.536763475390617 0.997961925764102 0.373080541004892 0.913722860850394 0.633543294258416 0.32350442885654 0.324848349683452 0.669534057811834 0.745285618910566 0.328098143127281 0.764699714451563 0.544662095292006 0.43519264515955 0.24948325387435 0.305197611453477 0.413666053093038 0.968377836372238 0.703820643594954 0.678274081777781 0.980308170118369 0.0305203986540437 0.48868185050087 0.757017456491012 0.684721009714995 0.199468770998064 0.036261161013972 0.640520699121989 0.949793759463355 0.0311861763033085 0.754470569551922 0.621497084912844 0.560503256623633 0.303470827166457 0.929658473741729 0.870683659450151 0.0772153735766187 0.468219644466881 0.945220747990534 0.247936668246984 0.264467520462349 0.973594238415826 0.670618710992858 0.810529572842643 0.59535375692416 0.456790093875024 0.880840412785765 0.361277768404689 0.976804602360353 0.772913453637157 0.0499037018488161 0.492092136268038 0.556948469402268 0.239050109565724 0.505334039377049 0.700276412228122 0.433877127061132 0.204932037587278 0.697811993954238 0.793144352419768 0.748570273527876 0.15191306485096 0.231962848210242 0.751152595591266 0.435233750871848 0.380119368287269 0.43292323278496 0.697379548058379 0.399185979710892 0.0744283645157702 0.4756140891416 0.761741044076625 0.0282848154939711 0.712160488765221 0.707282577559818 0.721908584737685 0.198647236695979 0.401466773599386 0.404848571352195 0.0317115054209717 0.361327648649458 0.530947645334527 0.398234077205416 0.552517555935774 0.0407859341101721 0.850946084766183 0.577154937933665 0.126104682574514 0.310169530271087 0.256652678479441 0.542832959208172 0.267197846923955 0.327349203461781 0.473402130396571 0.52160554949427 0.607931622676551 0.99019595972728 0.74638981707627 0.295833440634888 0.54716241015587 0.787220624911133 0.697765528832097 0.085793417787645 0.587374608034734 0.436577051186468 0.768982368584257 0.712254165837076 0.52015229887329 0.027575554039795 0.885497557381168 0.854133954218123 0.983934262315743 0.381795582436025 0.900400975965895 0.266013510241173 0.873074969528243 0.0412278937594965 0.337575972573832 0.169076819780748 0.959079664365854 0.961362864468247 0.971790365388151 0.280356593779288 0.40532405779697 0.54205676010577 0.780483598948922 0.406883874488994 0.29684291570913 0.968562790064607 0.658339762745891 0.341318664147984 0.79524408003781 0.953274174875114 0.963214944524225 0.0295006620767526 0.925446584287565 0.816362397836056 0.219658234450035 0.160266429213807 0.999934395807795 0.262368223653175 0.513367044676561 0.874516875515692 0.305158934544306 0.460951893788297 0.0560168227553368 0.992246003949549 0.198337247702293 0.0124928085552528 0.597443762645125 0.737581870295107 0.985560141208116 0.49436570183374 0.600614182839636 0.34835404449841 0.132498810032848 0.047427195571363 0.692383022655267 0.316391527573578 0.512796485007275 0.811717790954281 0.217729536569677 0.177794091782998 0.506408307044767 0.121314487650525 0.474427150317933 0.102524921365548 0.474200643969234 0.405696405048948 0.0265000169957057 0.656932458847295 0.893906513606198 0.330377950696275 0.73358233549865 0.377701481289696 0.154855900406837 0.462779938674066 0.581485373126343 0.0669955460424535 0.069265668594744 0.125979096603114 0.735390331982635 0.180827897391282 0.893888433463871 0.748772467873059 0.937436054791324 0.448730413001031 0.0310537165217102 0.163037865075748 0.407406146454159 0.534227198935114 0.164725180217065 0.959230797372293 0.704753297772258 0.254741930507589 0.0972521225456148 0.527757317344658 0.324129586231429 0.18097965851659 0.475680290334858 0.746452110332902 0.557344648060389 0.957338324086741 0.167910635157023 0.69256802406162 0.0906769977370277 0.0260897258319892 0.835374401181471 0.425214889566414 0.61218246956123 0.312234329639468 0.834573467564769 0.750536343443673 0.145176685908809 0.743364867137279 0.338262551215012 0.0300053054536693 0.496255659186281 0.0586249375692569 0.944268715020735 0.241844443529844 0.561252935049124 0.545386461103335 0.904727534109261 0.509876717894804 0.537933198455721 0.831970765637234 0.264299630627502 0.814498135731555 0.52328144347528 0.478411608878523 0.0852016233210452 0.27000559105305 0.635739839312155 0.164668065195438 0.759709358674008 0.693948685347568 0.272578707083594 0.711434845970944 0.712165432348847 0.340739550306462 0.535896739580203 0.868797702926677 0.746521901830565 0.443597180349752 0.0915040703187697 0.158004177394323 0.931196767969523 0.932559660752304 0.42682413702365 0.816726717152633 0.170639840224758 0.47430446844548 0.420948144013528 0.181128637709189 0.313349452693947 0.570671070152894 0.073701294681523 0.141248123473488 0.127642757364083 0.281767805153504 0.290433570255991 0.5836423229496 0.301074852182064 0.727759366324171 0.137148115243763 0.146656230853405 0.0737643868592568 0.254506609749515 0.549063800424337 0.181395874512382 0.788656075680628 0.479400981843937 0.969147648946382 0.059089488061145 0.796327583242673 0.583631528294645 0.803838028910104 0.424452125984244 0.757944282877725 0.886679347935133 0.0905889008962549 0.933922291914932 0.887604212055448 0.17018407901749 0.0894891071692109 0.608833296878729 0.633084320540074 0.235167154553346 0.945891813824419 0.571631914074533 0.630452848232817 0.689748431420885 0.010122650063131 0.602380735694896 0.580576218431816 0.0800968777621165 0.9053629433061 0.0649331727111712 0.135286862116773 0.459645722559653 0.702811285154894 0.527940306696109 0.353649741881527 0.0309792236983776 0.121369833105709 0.0384266968187876 0.0756155813252553 0.942002456609625 0.997917137315962 0.0280925106210634 0.0288288671639748 0.0578955537220463 0.716764675679151 0.504763824078254 0.634685173332691 0.0551867269049399 0.16967357511865 0.289571617138572 0.816530753055122 0.256082644816488 0.414533484559506 0.441816424862482 0.0591588111780584 0.654787454116158 0.683783630931284 0.923130596380215 0.303039843116421 0.912652439805679 0.812112419714686 0.889057479733601 0.449940685806796 0.288527168175206 0.0723899963893928 0.0525258671632037 0.995611509797163 0.260051681157202 0.69081681689946 0.10414480097359 0.450220943456516 0.509190703753848 0.95075838316232 0.482187040543649 0.627678712035995 0.536709373034537 0.310212135401089 0.229903996954672 0.630963689356577 0.398957608367782 0.728885025870986 0.258682130775414 0.456588598873932 0.839536730558611 0.734628812191077 0.56614945954876 0.115958248137031 0.872600724569056 0.870711328259204 0.862272879721131 0.706982998512685 0.0386152532626875 0.870075588061009 0.214236240456812 0.440360987465829 0.381300428148825 0.716505267196335 0.795397559097037 0.869400170342997 0.410921951120254 0.700644231953192 0.561356867630966 0.727650899300352 0.898737927419133 0.762038902884815 0.81796340322122 0.0372515998221934 0.234266764479689 0.68050676798448 0.55312541272724 0.666316014220938 0.985665166601539 0.292889697360806 0.753870542694349 0.352879970336799 0.731632504472509 0.282261039586738 0.0414961436204612 0.21889147810638 0.595563168297522 0.877545952368528 0.79470081968233 0.0547962833754718 0.637799570395146 0.12070477001369 0.249917368376628 0.575841828815173 0.396860595145263 0.612254805343691 0.981101585901342 0.410789889185689 0.916583092436194 0.211990147542674 0.77282160675386 0.418904038222972 0.193252596645616 0.910005847697612 0.0993618242302909 0.334758630327415 0.409181653633714 0.215234386341181 0.218940312792547 0.135114805030171 0.715884405924007 0.0688925157370977 0.637860248982906 0.910352479878347 0.906346691553481 0.34636003954336 0.489074905160815 0.815613137541804 0.171059702767525 0.743091336237267 0.82255445565097 0.266132914370392 0.196092016636394 0.26982236912474 0.285819237781689 0.604244189197198 0.615366464960389 0.362275033539627 0.286088602812961 0.731268427183386 0.836863003945909 0.531131846436765 0.618542445101775 0.0163228383869864 0.225947718226817 0.723607986269053 0.432251807828434 0.370096075574402 0.865881805948447 0.054454378336668 0.773600490055978 0.591047441035043 0.74129611119628 0.544468594803475 0.31432711222209 0.548934386961628 0.741234731650911 0.451645099611487 0.363191400421783 0.232640187856741 0.0218332240334712 0.628546616032254 0.0734681715327315 0.997940250707325 0.656424776297063 0.75751405533636 0.38093588616699 0.0692080245702527 0.0499941507354379 0.454861323386431 0.42790015835315 0.865236222378444 0.339122956739739 0.379272581532132 0.994302404504269 0.554115684421267 0.79896976584103 0.657028672366869 0.398862952352501 0.467333774657454 0.366529692241456 0.779801720711403 0.240366749519017 0.143015440674499 0.709681444426533 0.922912744702771 0.509358136272058 0.580168441126589 0.0511795442714356 0.543828849857673 0.366908271585125 0.0869069775752723 0.521503348676488 0.867102505988441 0.246682142450009 0.915025802280288 0.69237592802383 0.337423172804993 0.230761384281795 0.16602238882333 0.568524558627978 0.172179353118408 0.521022788875271 0.895614340228494 0.657706059957854 0.151339755749796 0.92804353449028 0.301175270755775 0.0390193743398413 0.28761380842654 0.783533244447317 0.290970696252771 0.858418141652364 0.633758231233805 0.168083528275602 0.041867088265717 0.847348108091392 0.0295693231909536 0.959777772964444 0.508643072152045 0.0617780627124012 0.84526363650104 0.32578512662556 0.55418274999829 0.450369365063962 0.316152547360398 0.593998219931964 0.40908524971921 0.54988148026634 0.142585479363333 0.0463556008087471 0.955190762393177 0.886736084702425 0.266656097050291 0.560709643114824 0.141920218961313 0.790415884268004 0.477897128583863 0.418871528403834 0.759676930452697 0.725624000278767 0.474855578327551 0.831814466612414 0.875900754383765 0.602900919769891 0.654337535682134 0.755938142435625 0.892697265844327 0.894458036087453 0.0553980581322685 0.451741970062722 0.312850135995541 0.833469166825525 0.641986956067849 0.176222474062815 0.450321572248358 0.378430606743786 0.364416495449841 0.731858823883813 0.0520689536747523 0.178799088427331 0.441189821315929 0.618803943779785 0.453220536294393 0.554359619512688 0.591367901980411 0.0385359226563014 0.758643983555958 0.468537889362779 0.461489224932156 0.410109131650534 0.447699715807103 0.305114577596541 0.195137884712312 0.435534417890012 0.592717493395321 0.0664996391651221 0.0780762152117677 0.640923961116932 0.652729929632042 0.602183505678549 0.363933170542587 0.0150858450587839 0.977824137709103 0.398611183869652 0.562251096146647 0.718499111721758 0.812304240302183 0.615578351928852 0.380532373155002 0.731738515724428 0.932624612392392 0.810320394507144 0.384112380098086 0.0860790413012728 0.93862087322399 0.218193610613234 0.815787156203296 0.562271080007777 0.659903833128046 0.540450646788813 0.56754736217903 0.559325198363513 0.294574529069941 0.767022342439741 0.446229625607375 0.118977511583362 0.0544375359918922 0.8313936822908 0.0411204354139045 0.8284179243166 0.563896865085699 0.733913563669194 0.424335708934814 0.480145153799094 0.992072768996004 0.158645886681043 0.955289828840178 0.188737760044169 0.0998485352168791 0.883576555743348 0.469683322091587 0.781306337164715 0.676175819232594 0.22189545302419 0.165203687625472 0.492732253705617 0.222055181923788 0.439362336550839 0.595840438867454 0.654225245085545 0.577064032882918 0.193510506632738 0.0508219072176144 0.35962538612308 0.28316044887295 0.506800496629439 0.951775492012966 0.920857513947412 0.971601241216995 0.689131254267413 0.570104387302417 0.788519224137999 0.814315779570024 0.527039483047556 0.581627481735777 0.153806998829823 0.390632990642916 0.264344000022393 0.465874493173324 0.765203968971036 0.0937989190872759 0.646862942809239 0.3169371392834 0.214731431854889 0.286506844693795 0.317221211516298 0.900143359638751 0.516811590697616 0.604093271940947 0.701415467879269 0.614750475124456 0.143958743598778 0.486016896346118 0.350450800249819 0.701107833927963 0.558777558694128 0.463203990596812 0.543493396579288 0.0970534933800809 0.251186361422297 0.957416985544842 0.646330292476341 0.460200838341843 0.298290791937616 0.446467863372527 0.422618863678072 0.375688166692853 0.263438929137774 0.975389408597257 0.256906606077682 0.159344905072358 0.743255207724869 0.591049684053287 0.304195629088208 0.707640840427484 0.112290071744937 0.338594469048549 0.686681509541813 0.239596973133739 0.39027129282942 0.762553622440901 0.841200013065245 0.978621739414521 0.560729098434094 0.213759638380725 0.124375766140874 0.596414218884893 0.0793200470833108 0.505998807426076 0.294829398961738 0.933719956041314 0.0651825603353791 0.689513566826936 0.273663066835143 0.387564849867485 0.614522015498951 0.549406826396007 0.397735810675658 0.995438865621109 0.621380321648903 0.82082510126289 0.553102714009583 0.935216708907392 0.048136426829733 0.928745445916429 0.518126271150541 0.914877299997024 0.188767834375612 0.211520221736282 0.658251035481226 0.839927475815639 0.543689917570446 0.604293634714559 0.944942747880705 0.443606190686114 0.123866819746327 0.52510840062052 0.721377041738015 0.928916285950691 0.457316102283075 0.590340112573467 0.0865253456891514 0.462652094701771 0.748389054203872 0.0750249988399446 0.0637338563730009 0.539172000074759 0.587158146747388 0.718493640057277 0.279784492279869 0.102920111860149 0.794871373893693 0.097867457063403 0.3860767060332 0.479529865612276 0.565200906472746 0.351091143349186 0.541751361335628 0.507100203144364 0.0596552053373307 0.200623930925503 0.546769065293483 0.388942014202476 0.286448011277244 0.912274639098905 0.714448346167337 0.797457376848906 0.147251706903335 0.181965014978778 0.767348691106308 0.291790727218613 0.116816033772193 0.587106459133793 0.381708299499005 0.431268220702186 0.467717342302203 0.131236978464294 0.241076386230998 0.281457677397411 0.537936138513032 0.809528082369361 0.428618911893573 0.400903253701981 0.462382341965567 0.819585350896232 0.656902144101914 0.126607630837243 0.103832147603389 0.539207430128008 0.0817312287678942 0.891471833360847 0.780263065837789 0.107732943957672 0.378889553262852 0.504045648868196 0.741022887786385 0.755053392867558 0.105654781907797 0.725406296122819 0.034209229669068 0.191903948676772 0.380985547665041 0.243339498746209 0.919646788435057 0.052597418546211 0.0575277552031912 0.325198437324725 0.901221251033712 0.846403825993184 0.895937272619922 0.510720172738656 0.315737360096537 0.523103063940071 0.385215400166344 0.252004056246951 0.406703477827832 0.299717988648918 0.697594515460078 0.757482618966606 0.956648849183694 0.0664965449017473 0.171896516839042 0.350876895806287 0.989979549150448 0.192134057315998 0.013596425394062 0.240450424633455 0.54449312670622 0.940597449436318 0.319630986445118 0.537427135184407 0.835026400277857 0.636446630472783 0.20741706277011 0.112035586561542 0.458790986009408 0.505089821228757 0.466566201413516 0.0193623473145999 0.372323891727719 0.805586685333401 0.665815463182516 0.970640912468079 0.562428279605228 0.259997227054555 0.0885896771377884 0.847898449939676 0.0729579599108547 0.231061590064783 0.709070775967557 0.843002703846432 0.674952159081586 0.307899437223095 0.0433777849096805 0.511848214527126 0.700473784464411 0.420242040902376 0.149504942854401 0.607867728811689 0.923960409404244 0.602556371330284 0.334217776646838 0.123371937451884 0.126755970155355 0.439373537120409 0.343204037039541 0.965569689555559 0.961384788237046 0.415494262096472 0.340498258615844 0.573271097331308 0.216538439944852 0.847821459854022 0.595578231164254 0.0548634289368056 0.663244598929305 0.0321222269325517 0.806688004985917 0.143001993168145 0.813079759192187 0.859628041274846 0.491766811031848 0.0495552159682848 0.114111864485312 0.913698655108456 0.249180395700969 0.696543694490101 0.103946024286561 0.84289484995883 0.6391882305732 0.637200025517959 0.0894608328305185 0.885169233309571 0.199070093233604 0.360998685394879 0.50846110023791 0.34943877812475 0.821621832591481 0.55752528029494 0.412973696910776 0.405219621337019 0.742243273651693 0.20626473525539 0.999081089524552 0.574566828187089 0.920290755722672 0.218808646630496 0.214773780205287 0.440001148884185 0.268350852346048 0.359397368140053 0.911503827527631 0.65771344732726 0.78086861230433 0.871536429354455 0.199396887461189 0.967386264875531 0.520156973691192 0.640837951474823 0.8380564641417 0.845356576195918 0.0593105635442771 0.586268670728896 0.874351451825351 0.677138805212453 0.52418021150399 0.654331430597231 0.267708047942724 0.425628521631006 0.635151004726067 0.369207488833927 0.493802250395529 0.171309217168018 0.984934360093903 0.691381164069753 0.0342968530580401 0.199104983911384 0.656034232268576 0.28141038776841 0.95307306734845 0.33826913021272 0.250277156017255 0.839643946646247 0.94846458041342 0.741090132694226 0.7619704672019 0.399357111791614 0.22943127515493 0.752846720463131 0.491361199526582 0.621707532855216 0.388163802123163 0.661769933488686 0.399704282656312 0.895779426002409 0.804980556848459 0.713841989485081 0.0418745293421671 0.793494700298179 0.0782877619587816 0.538264197967947 0.254306385507807 0.995050777595025 0.453901208313182 0.370512456379365 0.189579782315996 0.652973865184467 0.613997084689327 0.0443334522098303 0.106453626020811 0.592361317495815 0.907848036026116 0.982223894866183 0.8163789412193 0.684762597177178 0.309078401818406 0.175767791375984 0.82735563216731 0.375463963523507 0.5738475355017 0.171802724285517 0.929478133553639 0.0527995117008686 0.278799783068243 0.57905693350127 0.345287099569105 0.873244885709137 0.240320352625567 0.29266639061505 0.295533275650814 0.771158813603688 0.39803386886837 0.822302157704253 0.862463829470798 0.441289807697758 0.744864259716123 0.382646155422553 0.717185682666022 0.978832769144792 0.205247261058539 0.833403000899125 0.486582608090248 0.252957382565364 0.60598321269732 0.221271471902728 0.254254493438639 0.138073319355026 0.854921558345668 0.702339537458029 0.370122907890473 0.73448776250938 0.783700817571953 0.908731647373643 0.81181297643343 0.847062735594809 0.463338350409176 0.879514611286577 0.514657808206975 0.330519402143545 0.0705072454619221 0.359986377677415 0.122179006258957 0.706161924984772 0.0574673204869032 0.515618585282937 0.879923749938607 0.483527596958447 0.226828691475093 0.386841112405527 0.776994512500241 0.254153191579971 0.231965985347051 0.191959238350391 0.473989014010876 0.979471581939142 0.412098335241899 0.0842158277519047 0.979090416820254 0.438025421611965 0.304027359385509 0.477865414689295 0.468867561412044 0.757792272579391 0.331303414814174 0.630717274060007 0.710943523554597 0.691778645757586 0.455669186133891 0.267488053515553 0.844040860326495 0.426057986670639 0.598283015200868 0.974089123706799 0.158473199170548 0.755715042219963 0.136832986278459 0.304875772334635 0.562055171004031 0.994921721180435 0.264092479790561 0.313938379480969 0.898100991835818 0.222034552886616 0.973849132971372 0.0146867242688313 0.614194241866935 0.0373383023543283 0.333640129491687 0.37256793722976 0.507857897980139 0.985783126403112 0.570510009180289 0.396132441489026 0.0807782837003469 0.738156356341206 0.0912548859976232 0.750786397911143 0.352995584316086 0.689472418702208 0.524400512038264 0.089572199343238 0.341324432007968 0.139631502707489 0.662357281334698 0.372836244024802 0.199382090594154 0.209545233224053 0.223208468097728 0.874598654978909 0.11998128679581 0.0843624046491459 0.722234787957277 0.398523979303427 0.947348706612829 0.0827598175569437 0.761754769338295 0.231269188537262 0.0469943220936693 0.86770526614273 0.881316483784467 0.337818046589382 0.0502111260429956 0.410187672786415 0.806865970769431 0.100319605236873 0.196561672985554 0.803911391349975 0.631768364487216 0.316933435110841 0.168469182888512 0.967160813997034 0.976813408010639 0.490744314880576 0.474359755122568 0.717847130328882 0.156162705747411 0.167245831380133 0.30289012700785 0.467106092746835 0.509890756178647 0.954413250579964 0.890700182300061 0.790698524850886 0.0970648506912403 0.185675259891432 0.0972587637789547 0.653085267194547 0.213868153349031 0.347458811914548 0.475111235845834 0.678741062916815 0.735829722683411 0.376040133389179 0.403339086920023 0.791431819861755 0.553683787581977 0.757923960639164 0.199719024850056 0.945460974760354 0.399833278218284 0.282560686862562 0.417345667472109 0.40754065978108 0.0704896152601577 0.214963452972006 0.490890434922185 0.59219824654283 0.224197041911539 0.877490355204791 0.757597153503448 0.761181795387529 0.775128339300863 0.450527815136593 0.228631880141329 0.247590242135338 0.877391466705594 0.476360811605118 0.307303288336843 0.195517181609757 0.0524968720437027 0.0950316983717494 0.993299183880445 0.0688566389703192 0.269782614156138 0.0630542870773934 0.939776675561443 0.749016694319435 0.534858914562501 0.904798705163412 0.433912922230083 0.337342980811372 0.68069203446852 0.911634758156724 0.87067431880394 0.286169375902973 0.7481894942699 0.0663333494774997 0.351464254946914 0.250054790873546 0.136465803661849 0.912021479073446 0.404185627268162 0.846270250349771 0.187257217946462 0.864158137361519 0.232653247197159 0.942765979235992 0.707697593560442 0.972210140801035 0.511905968040228 0.858761741574854 0.859088802724145 0.745520562566817 0.27348667123355 0.706688869001809 0.965987525521778 0.391024414268322 0.282947102133185 0.131405458846129 0.34677944868803 0.0428402068978176 0.685450536473654 0.883605841295794 0.759871923443861 0.503241722409148 0.433335720174946 0.470934013021179 0.52122493642848 0.500099806594662 0.698295012062881 0.674507211199962 0.682023420347832 0.967839254983701 0.0162922364356928 0.659760620181914 0.825738037298434 0.936064172417391 0.551956344519276 0.547863006105181 0.897242562868632 0.706731664065737 0.863594272171613 0.751152753946371 0.140516665335745 0.52945179004455 0.842092518345453 0.866863566574175 0.64939238256542 0.136500825495459 0.743551364042796 0.850022952179424 0.268788251276128 0.805290260710753 0.188516588902567 0.434391013351269 0.765510661320295 0.848720921464264 0.706383074228652 0.058374029090628 0.0417401766753756 0.876273070517927 0.854602483410854 0.912296605510637 0.80958674982423 0.779574009526987 0.709721990248654 0.567418138189241 0.0798388543678448 0.0250551543547772 0.246076034479775 0.101462856722064 0.945020001200028 0.1479555036081 0.443643627031706 0.103220017529093 0.110000810583588 0.134884672418702 0.573929661870934 0.366717351339757 0.593423356323037 0.54230291700922 0.799493219130673 0.705710952694062 0.416131129220594 0.308962643314153 0.667283524500672 0.843936333509628 0.461284585187677 0.436518679696601 0.303565837694332 0.226674313456751 0.222140327643137 0.913041369395796 0.140593727338128 0.436744447515812 0.799244578334037 0.937426461053547 0.343712041601539 0.890918355758768 0.0764733637333848 0.998251573618036 0.666510384855792 0.4003675674228 0.226312922441866 0.0247730158059858 0.273996484547388 0.167715775396209 0.158299020540435 0.28818561211694 0.412599628497846 0.60908777376404 0.669588086637668 0.805997733005788 0.821863327354658 0.316303380713798 0.243863363021519 0.5730080701923 0.289576444779523 0.409962364588864 0.212344858599827 0.611226181518286 0.594684700609651 0.804682407837827 0.372537035164423 0.525174140578602 0.881881722998805 0.211445708628744 0.388803331088275 0.587014524198603 0.524616195610724 0.661582406468224 0.213712115022354 0.555034670501482 0.418469083770178 0.387788987574168 0.761020759539679 0.177928849211894 0.0719216820248403 0.236088490143884 0.325630344075616 0.938840363773052 0.948634192792233 0.134899080428295 0.789552263696678 0.990478455324192 0.079404373827856 0.330191958590876 0.813905531740747 0.296417481233366 0.276577991324011 0.338267810125835 0.742682916983031 0.767592331615742 0.664029266457073 0.808337049363181 0.675594611738343 0.510289955108892 0.704664968815632 0.603861718052067 0.276690131172072 0.668552733527031 0.600700368585531 0.413638807025272 0.160734599514399 0.317797532822005 0.577861449494958 0.151815655254759 0.575659265432041 0.896325198833365 0.0278979205479845 0.220916852355003 0.557774425891694 0.261179224138614 0.767533970267978 0.402286371220835 0.587860382029321 0.773647115838248 0.820156359123066 0.483764310642146 0.872807191736065 0.784667578949593 0.890608977826778 0.563877653637901 0.606312827351503 0.477080970057286 0.492703989278525 0.149972969091032 0.155509900539182 0.531567988207098 0.78208810382057 0.342890728120692 0.0796809706394561 0.934744845267851 0.837371861366555 0.982943513251375 0.829505906873383 0.820574978105724 0.0467839380004443 0.0652655227365904 0.546790367166977 0.605710853440687 0.105443849680014 0.202211315697059 0.224022089254577 0.85778707327554 0.198747188502457 0.94046012467239 0.900113104593474 0.708440036517568 0.537145413153339 0.678414590931497 0.942393667942379 0.29342483850196 0.418144401866011 0.73634109234903 0.847156456923112 0.145317916765343 0.712382270277012 0.248631303175353 0.0785666647157632 0.606251525715925 0.421495368778706 0.580128310208675 0.030483249053359 0.0297601800481789 0.938128935596906 0.246619872243609 0.80525869917823 0.256966507642064 0.492017405566294 0.127117236007471 0.425681589031592 0.713423785867635 0.981384292868897 0.216353472652845 0.237531322520226 0.250632562730461 0.531774170473218 0.968172184261493 0.608490110707935 0.329812475447543 0.376102147737984 0.597259722203016 0.594590405330528 0.687153677905444 0.743780892968643 0.688266543650534 0.85440662557492 0.667942805672064 0.652922856630757 0.625083616685588 0.965834966166876 0.834107883730903 0.171455558952875 0.57499930197373 0.591480547089595 0.749677955505904 0.799342509096023 0.464826548872516 0.233187465867959 0.651195570540149 0.170107835067902 0.657271765663754 0.406904263342731 0.428398018968292 0.645879948535003 0.555492432699539 0.474860777307767 0.875566169177182 0.108064678772353 0.477043180582114 0.526499897129834 0.624177011577412 0.563218623483554 0.663623700360768 0.661317463854794 0.802323768239003 0.478583182832226 0.57026836827863 0.640753145054914 0.11838712917408 0.923143060102593 0.0170479466463439 0.0464409924740903 0.975254498345312 0.830109117429238 0.951322424686514 0.648997854534537 0.293668258420657 0.338999462577049 0.968911854045 0.687120707542636 0.236202500979416 0.202708757950459 0.96178572077537 0.791028034626506 0.916071197686251 0.274437506513204 0.58860417642165 0.221690841400996 0.619224811773747 0.355965079541784 0.158508058269508 0.939772914685309 0.203810286438093 0.240759894305374 0.655422131929081 0.179907504094299 0.431771168273408 0.135679560650606 0.0681502014002763 0.861658487496898 0.313709307641257 0.180560077186674 0.876417632133234 0.356970095087308 0.307165901567787 0.756464153840207 0.269639453764539 0.433640354368836 0.0931768285459839 0.56685120040318 0.809928834654856 0.227301326836459 0.248797346225474 0.374746559343766 0.425623616310768 0.239285670507234 0.324110670057125 0.190058242010418 0.270079269050621 0.547045402098447 0.753646632032469 0.0690744768176228 0.460513442384545 0.808153533544391 0.745072077396326 0.743456537225284 0.206076343851164 0.190131999531295 0.626909834609833 0.978517297883518 0.859404045096599 0.665029813945293 0.720725705521181 0.0824110548431054 0.689321539017838 0.935913469297811 0.321409128035884 0.618327853418887 0.0244631747948006 0.895008557958063 0.328309012888931 0.705385501834098 0.216208988947328 0.258331721122377 0.658075416672509 0.894223414442968 0.171736248333473 0.580747708252165 0.225074069190305 0.783380279869307 0.588637701834086 0.306380360666662 0.254166056145914 0.715776635478251 0.643480007757898 0.80380345240701 0.134034550525248 0.156578838992864 0.779507952858694 0.742977567659691 0.461025151119102 0.939142757945228 0.237265382984187 0.485127919595689 0.793187345715705 0.949628063088749 0.629508471167646 0.39996310059214 0.113382080947049 0.293526881195139 0.927022793614306 0.907819338946138 0.663647265075706 0.491096210121177 0.938741105317604 0.0547568024741486 0.787562683694996 0.88408529053675 0.411488230130635 0.987469101173338 0.894630788138602 0.0529131352924742 0.221204424996395 0.612541019173805 0.0825741041288711 0.840822063914966 0.354972204093356 0.12325605655089 0.196913305683993 0.0609448163560592 0.547884246665053 0.541017744773999 0.928933860140387 0.302502100064885 0.333851466020569 0.470367387565784 0.444971820453648 0.948126845622901 0.722346773368772 0.994222974090371 0.0134717399952933 0.455523671852425 0.414075620709918 0.433359207671601 0.415554865309969 0.254714268613607 0.0527639329736121 0.877739851626102 0.98659987870371 0.255376070558559 0.613054182147607 0.944811388517264 0.738366325530224 0.127442720059771 0.0870877974387258 0.710785398490261 0.429608351013158 0.484794829427265 0.772650987540837 0.396306732143275 0.238861887350213 0.969323589305859 0.984353780027013 0.543725804018322 0.0359384681144729 0.0783392866072245 0.642949071901385 0.961994439028203 0.113698127081152 0.531914890536573 0.561179444219451 0.882727089398541 0.953137117263395 0.36908237170428 0.840141900845338 0.421221060855314 0.183291110137943 0.530496643309016 0.431361450599506 0.017835302061867 0.250380480303429 0.856080130399205 0.811201471020468 0.880075735803694 0.408059846241958 0.591615635289345 0.606487982159015 0.0944923588610254 0.361329500735737 0.0188816533610225 0.507770188383292 0.849200692486484 0.403079262610991 0.0920530648808926 0.838663303265348 0.934495825525373 0.980455720196478 0.9208376895939 0.4238952000672 0.411595786439721 0.269251930930186 0.034120345201809 0.712130302179139 0.651573588149622 0.68462746080244 0.568755753624719 0.309841328826733 0.636858315945137 0.132518272958696 0.913757137239445 0.15245699389372 0.758993628171738 0.848788520423695 0.652863507119473 0.880860679473262 0.664246444606688 0.0611429467145354 0.725642310001422 0.177584188056644 0.119527967991307 0.194882180402055 0.0170778114511631 0.508311033535283 0.538372675594874 0.611912701150868 0.389058807662223 0.215474340196233 0.0331308611342683 0.48017003975343 0.240462652551942 0.691910479725338 0.0654515466513112 0.548586173995864 0.795979370507412 0.281964021651074 0.202450444353744 0.339412668212317 0.236934522464871 0.975427869295236 0.764470286485739 0.573559619181324 0.0318250363506377 0.580250336993486 0.262805798687041 0.8524134716345 0.588073089816608 0.555562083590776 0.587708497354761 0.944762924478855 0.573511794556398 0.196232263939455 0.863689528645482 0.243783966721967 0.380107637331821 0.402149303236511 0.636959342814516 0.392588566017803 0.254447439799551 0.512336911982857 0.0218230708665214 0.025807897078339 0.0273304516845383 0.903523827393074 0.988002037790138 0.205483804862015 0.0439673186093569 0.30096150588477 0.502219039550982 0.393523580769543 0.199431279101409 0.606555417922791 0.75958306275541 0.994033038320486 0.837226442282554 0.0559808729193173 0.867993985994253 0.855311608638149 0.394297375271563 0.559114846310113 0.32136586482171 0.596233020997606 0.543610985041596 0.395453970306553 0.397162838338409 0.302653620545752 0.295252214239445 0.691595945225563 0.367788084023632 0.532208158890717 0.402463419605047 0.960876606879756 0.149786114215385 0.559325632629916 0.999552351783495 0.367077774244826 0.970466661690734 0.991077269508969 0.522660961840302 0.243813128264155 0.376658247765154 0.807549608661793 0.741632342881057 0.0375126139842905 0.308487943573855 0.445928650177084 0.9229951762571 0.472266809344292 0.133690384950023 0.905340142936911 0.1494246344571 0.420444811272901 0.540002329654526 0.412989627157804 0.21606766888639 0.44750819256762 0.873304855271708 0.845721983253025 0.0749804791575298 0.939039784483612 0.175188503505196 0.623265460580587 0.122130061392672 0.822140638493001 0.900353585837875 0.981944474400952 0.473645405329298 0.909145056542475 0.612796642347239 0.923491655471735 0.692911115726456 0.596231048358604 0.0333275766693987 0.330950464103371 0.463075415932108 0.416237001940608 0.314179734098725 0.0630324827088043 0.662552730950993 0.575702476552688 0.165913432904053 0.913039237479679 0.8425850144797 0.589033607807942 0.173526707508136 0.995974528158549 0.637921430987772 0.35416282994207 0.799491229203995 0.707935123452917 0.879775616689585 0.352587970206514 0.49359527427936 0.589306446509436 0.811852473239414 0.0651273771538399 0.24617682623677 0.412604078806471 0.868682870350312 0.105053637805395 0.633484811205417 0.226711239009164 0.191490247922484 0.736839711086359 0.722885557138361 0.247889716995414 0.50665443375241 0.988389516598545 0.384768288789783 0.355293219627347 0.115357680059969 0.931868322698865 0.808195578323212 0.0495383911416866 0.921826486994978 0.41079655416077 0.859876914648339 0.923213283100631 0.924666452815291 0.258903816628736 0.302464127340354 0.470660243320744 0.131283771360759 0.92694401828805 0.115897634550929 0.626994215752929 0.348668879803736 0.537116444311105 0.344450942890253 0.728450485630892 0.0619438747991808 0.317562979406212 0.911196519967634 0.298847523310687 0.549895113557577 0.113312256718054 0.340968402246945 0.458079625831451 0.072546466907952 0.650545442386065 0.949626771814655 0.579017580298241 0.489221546137705 0.325290226582438 0.6839809268713 0.532780017210171 0.90595382360043 0.750139382230118 0.0869806322921067 0.727733828048222 0.837484698023181 0.266261608435307 0.756126140372362 0.102909428307321 0.98092647143174 0.272053845424671 0.574639696890954 0.264410332371481 0.571219263949897 0.907324903365225 0.939943580920808 0.532814629210625 0.337867642163765 0.811979741416872 0.580438391633797 0.867837835182436 0.281347242114134 0.861944264755584 0.134213486032095 0.766074442146346 0.364999841083772 0.717919278943446 0.399097920903005 0.909193048281595 0.493586328022648 0.701667996328324 0.0888659390294924 0.0786256147664972 0.715705595349427 0.971062035167124 0.366734201752115 0.468951927111484 0.0113668173155747 0.397156036675442 0.217466208164115 0.99112722097896 0.153282904052176 0.0183291630004533 0.911844377904199 0.536137967421673 0.209087217242923 0.566506836365443 0.016445620758459 0.724938855362125 0.14015483060386 0.164293181034736 0.850583047503605 0.764579694881104 0.949432182433084 0.0477921662875451 0.762473764675669 0.42632230992429 0.440233499850146 0.372151399683207 0.533205926981755 0.734790000631474 0.578213164482731 0.495038192863576 0.40105655250838 0.487716948355082 0.689661076797638 0.229584112034645 0.86633095496567 0.7176272234926 0.135950505544897 0.613987884188537 0.0903591387020424 0.262838920720387 0.0508903742488474 0.0568590266630054 0.114170337626711 0.421098451591097 0.737257560882717 0.160342921644915 0.354667137477081 0.595291258520447 0.428713248663116 0.172581957029179 0.0315126683423296 0.0996856041788124 0.997307114724535 0.473679979988374 0.215131851064507 0.355011986030731 0.584739867434837 0.664710234440863 0.37683269101195 0.271965756190475 0.27838725441834 0.400359882474877 0.905362018991727 0.224845068806317 0.827818531570956 0.900036523418967 0.123970389978494 0.494863920188509 0.809785562930629 0.69351154596312 0.427581676500849 0.0157172677177005 0.691535646275152 0.265072086371947 0.70516577594215 0.726152720777318 0.0413528015930206 0.595075916091446 0.242210602255072 0.54975532426266 0.240724297368433 0.153379615917802 0.524187331490684 0.750078263613395 0.021401918202173 0.0689562275051139 0.60274510987103 0.582313399526756 0.853049016827717 0.478412825930864 0.345965552541893 0.910451675176155 0.0895810296572745 0.57128008083906 0.595541746793315 0.59206489702221 0.127913838485256 0.461127744482364 0.754779369153548 0.0211739626852795 0.20099498114083 0.841697901110165 0.122445050673559 0.589151286396664 0.689714654760901 0.88175121718552 0.869512240118347 0.95367241330212 0.162582523152232 0.411964513652492 0.199754706381354 0.396159846833907 0.73807273078477 0.712809335787315 0.378309563742951 0.640748843420297 0.239335768576711 0.29667881164467 0.333040787226055 0.652453723982908 0.46360991189722 0.215164708250668 0.052808478011284 0.053045861995779 0.957510429348331 0.22344736763509 0.40015566017013 0.693872471593786 0.635827382716816 0.0316929753380828 0.325278617562726 0.814048309959471 0.147744527354371 0.747937301432248 0.305472899933811 0.840368296783418 0.549516557494644 0.69401768184267 0.323501994060352 0.348490166962147 0.531259823869914 0.370930880587548 0.795818230703007 0.671225315695628 0.817723389666062 0.169627239077818 0.944244079852942 0.961244425682817 0.329236314801965 0.637949103254359 0.268461955164094 0.812253650110215 0.657687527569942 0.594794737123884 0.787887346006464 0.0666523518040776 0.251250187058467 0.574440058586188 0.382636113588233 0.542775030743796 0.696200517078396 0.502845119165722 0.656162611006293 0.926192434991244 0.414812262614723 0.726980758241843 0.829335110404063 0.600709979149979 0.527004189221188 0.959434346840717 0.78794888413744 0.188416529220995 0.660570837280247 0.58179943440482 0.0735102432803251 0.15111731108278 0.837034438676201 0.661371708661318 0.02620723961154 0.0149461889942177 0.831901615166571 0.286188776823692 0.366228855573572 0.700556893926114 0.445702967643738 0.73369407196762 0.893913797480054 0.0924834770546295 0.245855849888176 0.0949774618633091 0.470087980239186 0.55759754992323 0.737169559930917 0.270478386152536 0.14021552094724 0.561351449443027 0.96396148419939 0.138368469299749 0.128279318611603 0.312906968882307 0.891038289121352 0.625172393047251 0.947404865049757 0.968762214232702 0.505266933231615 0.47067864293931 0.568103697779588 0.946149812554941 0.673517164476216 0.171749650430866 0.895404093514662 0.867909384490922 0.0918193479580805 0.554022891556378 0.647609167848714 0.31755367517937 0.928925042503979 0.0922116235201247 0.968460312413517 0.85290695524076 0.230392335057259 0.346754875755869 0.1695621661935 0.759024634885136 0.801737385275774 0.109361354918219 0.21066323202569 0.285534762630705 0.610029916800559 0.949142702384852 0.760096110247541 0.575018353452906 0.809005040065385 0.793384619527496 0.758169071984012 0.544220480935182 0.262360476008616 0.265157135280315 0.989755034341943 0.425312738269568 0.618239908479154 0.194957027968485 0.986122121580411 0.885682373924647 0.857571311332285 0.722855662368238 0.0987504656473175 0.592987523886841 0.294072720871773 0.615975308532361 0.716979882572778 0.0875991477421485 0.714797608840745 0.791610518873204 0.145769404228777 0.184083655774593 0.196790045020171 0.0300322656985372 0.64111733206315 0.69115724326577 0.266785034064669 0.95608012016397 0.616115317496005 0.249381296697538 0.516576775892172 0.378691182951443 0.220148413574789 0.397309951153584 0.628946134438738 0.36784417930292 0.0703957613930106 0.709053515722044 0.784687811753247 0.126140878126025 0.568341164975427 0.166855620888527 0.476340748681687 0.589386510804761 0.943892076506745 0.108578657493927 0.0307248788909055 0.750287441257387 0.381712725604884 0.0871794451680034 0.915472094912548 0.848936726741958 0.770124104055576 0.729926330782473 0.288794861603528 0.109313603132032 0.369669489278458 0.153090459955856 0.268147798457649 0.189089380525984 0.0356610170612112 0.59697712656809 0.684563741427846 0.788851028103381 0.495524597512558 0.104083781472873 0.739887756668031 0.349430834783707 0.361663763008546 0.827411456836853 0.449910161304288 0.0188898829859681 0.528371804535855 0.355089975805022 0.179830992531497 0.631394541559275 0.912469118761364 0.224889044272713 0.850435879598372 0.791861384478398 0.157763318817597 0.630214322800748 0.549408896998502 0.722868568655103 0.913059106320143 0.108436688107904 0.218957292286213 0.792296453490853 0.735612019679975 0.773232623538934 0.16133935213089 0.840000570642296 0.295952525057364 0.452563947851304 0.509043029895984 0.176452200759668 0.899065166516229 0.999674539228436 0.251010804849211 0.772217488018796 0.958097477310803 0.514644569074735 0.225336346735712 0.522330527289305 0.489231042142492 0.373480825370643 0.488084471423645 0.598735795090906 0.540693567439448 0.214250136059709 0.607526752005797 0.570843271303456 0.686511335659307 0.274686906815041 0.428798680205364 0.588137336811051 0.132671888014302 0.680859890419524 0.713488266821951 0.896406801270787 0.577402369054034 0.766854276962113 0.229532028879039 0.340459503105376 0.168285980552901 0.897607191519346 0.80471066650236 0.602848824397661 0.626656935282517 0.571604230282828 0.499687549015507 0.514674181248993 0.714538029555697 0.0315914621087722 0.788315171482973 0.0224828725121915 0.670085259664338 0.934386875368655 0.532399077292066 0.569721691187005 0.251769252736121 0.88324113473529 0.497354244620074 0.0414264085958712 0.355325225107372 0.142727277716622 0.729679748832714 0.935395874225069 0.151996566397138 0.558884618501179 0.913537962248083 0.890279970776755 0.425080107243266 0.939141475891229 0.559039835778531 0.1408991191932 0.478692266219296 0.419177339081652 0.911964222984389 0.575933384113014 0.99849902686663 0.389656223619822 0.911564489288721 0.172859627520666 0.278065447569825 0.593545639887452 0.153023009209428 0.447599220015109 0.130195514275692 0.575629353835247 0.980022170194425 0.804853890973609 0.14850742992945 0.65684974746313 0.0690661038202234 0.377445785508025 0.269520106569398 0.870439101771917 0.137744822176173 0.282442235399503 0.651698254416697 0.391214093258604 0.493942490092013 0.99322591871256 0.254044264473487 0.379899524839129 0.896719410845544 0.622422566318419 0.907592898982111 0.347191237886436 0.316801556195132 0.37587475234177 0.747263007182628 0.404886663246434 0.753425199040212 0.961849512988701 0.812404718806501 0.9717186420504 0.153588408622891 0.204771812877152 0.466196776470169 0.996970732060727 0.629100110230502 0.725450953184627 0.63563168046996 0.958093784893863 0.411094122536015 0.331165920631029 0.635467422199436 0.0635190646140836 0.279869139883667 0.876852556620724 0.563559767864645 0.71937540485058 0.340819618750829 0.467340335214976 0.487420984506607 0.304578601114918 0.843466227911413 0.730107168855611 0.779845241166186 0.784593410212547 0.473919356665574 0.860636301140767 0.353265791833401 0.158891962908674 0.0193239649874158 0.244825529796071 0.678149546436034 0.262535043035168 0.283041044974234 0.0790532867284492 0.177535026748665 0.0951927904621698 0.167121641561389 0.784416194253135 0.108670383363497 0.2398135443707 0.848777004296426 0.434820480926428 0.585904892631806 0.715794546662364 0.401943723042496 0.652947141204495 0.465878402723465 0.532934701566119 0.745532495672815 0.13813942742534 0.798367938760202 0.0649098000046797 0.580612757892814 0.957375235809013 0.831802423556801 0.576753421532922 0.184915882388595 0.184168512444012 0.676010726082604 0.31458255053265 0.210733167817816 0.164241294728126 0.764085281197913 0.53483394816285 0.988668794843834 0.630093223787844 0.933670618860051 0.420506511908025 0.224467359608971 0.52891812273534 0.364187562372535 0.417618321080226 0.209300033827312 0.368139257791918 0.639312285548076 0.252527263360098 0.214491476847325 0.412694649859332 0.574287198656239 0.817400603182614 0.651349705148023 0.107916027815081 0.889436224116944 0.794466558082495 0.284204846434295 0.987197959891055 0.681895963158458 0.0602493216539733 0.846232977430336 0.765512472838163 0.399899421324953 0.974154619793408 0.682763477375265 0.139212033401709 0.945406974516809 0.575383156132884 0.201828271523118 0.148745594164357 0.691821274859831 0.940106302662753 0.924862155062147 0.331589466370642 0.0272624687082134 0.586804612174164 0.947371825075243 0.547252604106907 0.0105445092171431 0.332507164403796 0.275623167201411 0.298279027559329 0.378251944151707 0.0973460697662085 0.15690713240765 0.78847343968926 0.481543929572217 0.87039296350209 0.0102096743765287 0.686281828170177 0.932646682991181 0.613776691723615 0.926303748488426 0.385972705222666 0.161044748476706 0.413788555634674 0.63032638381701 0.136860818283167 0.415841020361986 0.0131720403954387 0.572040415618103 0.272322604004294 0.0641219024476595 0.123972897382919 0.919308318342082 0.635525553505868 0.674096172747668 0.385803775130771 0.199974632579833 0.0624547673249617 0.784566805632785 0.0165103990607895 0.842110522422008 0.474125387030654 0.728596359726507 0.388055155077018 0.485878341391217 0.252130054817535 0.0703147241473198 0.413922940110788 0.496509593238588 0.621182495553512 0.735119104031473 0.809705162101891 0.749794256843161 0.896587284370326 0.889924597255886 0.675988832740113 0.186640307253692 0.53650134974625 0.906744495714083 0.0286761252512224 0.859460652321577 0.863980069926474 0.927525663967244 0.178111881897785 0.657396936730947 0.301033439440653 0.414675867927726 0.392024886843283 0.538393081275281 0.190882946411148 0.867140398728661 0.330039947140031 0.620095833314117 0.763243621736765 0.312003568448126 0.69484096219996 0.233747519471217 0.627660568505526 0.667282108755317 0.0296989869792014 0.962088925624266 0.857367039008532 0.507879442803096 0.555606433162466 0.472386100296862 0.187575284203049 0.936789690279402 0.119168693679385 0.98965011843713 0.0981539117684588 0.833299947222695 0.191217173878103 0.892741091714706 0.887048621438444 0.0158629140770063 0.449156906404532 0.428203714948613 0.233194704332855 0.508868531559128 0.228408979310188 0.0209779753070325 0.909818419793155 0.933731060491409 0.675879047242925 0.836737209369894 0.741347679409664 0.405198377550114 0.207281136924867 0.665307028503157 0.54810411154991 0.985415137258824 0.907447649778333 0.785689516132697 0.472762973231729 0.0153418241278268 0.916932022033725 0.0468527899705805 0.861628184046131 0.197759583489969 0.283478988120332 0.0760762554593384 0.232170524362009 0.824872531678993 0.590327535213437 0.793201789914165 0.581451186863706 0.58793389521772 0.682016218993813 0.651814440272283 0.100391940788832 0.764053357085213 0.384397182101384 0.386696180833969 0.95662666863529 0.242475608487148 0.844513843054883 0.256235645813867 0.772145975129679 0.202736219768412 0.565597133536357 0.252779799185228 0.092135838731192 0.678475781234447 0.913350461965892 0.606715681126807 0.348190304858144 0.989366457650904 0.220592150166631 0.549416502423119 0.638959414130077 0.599317228246946 0.0751522497297265 0.0229462748719379 0.189441902732942 0.06893797010649 0.160887292791158 0.645363334941212 0.147585954193491 0.650984963090159 0.805773719078861 0.593341626878828 0.193738312784117 0.262358963682782 0.898112202777993 0.844618918928318 0.265283371729311 0.928643596384209 0.737251092987135 0.187392158624716 0.193942070626654 0.886922196669038 0.593826474023517 0.618766121112276 0.0718276557419449 0.281427847398445 0.526139075225219 0.027214589684736 0.237248128731735 0.171264022113755 0.377922352317255 0.430085670182016 0.607365267830901 0.634594453605823 0.297840210348368 0.332096929021645 0.479090080983005 0.63564820172498 0.1282004301087 0.58523134336574 0.725160288815387 0.260166652956977 0.960947216660716 0.617694503299426 0.185403899631929 0.734915648146998 0.60314278956037 0.762366245707963 0.579982512870338 0.195470604002476 0.0548948786756955 0.580704037970863 0.0557339751813561 0.460402372528333 0.777066905447282 0.963024834955577 0.259764908819925 0.584526553887408 0.108961652801372 0.707937407731079 0.621183446145151 0.75524387469748 0.916323561556637 0.452475851471536 0.925744798299856 0.727715263620485 0.73154411904281 0.0766788816917688 0.154069002538454 0.868425804001745 0.188660427662544 0.788473225091584 0.420549181809183 0.207531985933892 0.998197346099187 0.650479629358742 0.106346201098058 0.099336505853571 0.629365986147895 0.504338189065456 0.293600802142173 0.630303928970825 0.597199651910923 0.158439560350962 0.235155282530468 0.663235231083818 0.488118806590792 0.770427491923328 0.845855782483704 0.461736283099744 0.404865785958245 0.757985872644931 0.547112138979137 0.370989797445945 0.594446465149522 0.477474317224696 0.0590370914223604 0.341849800080527 0.316340825357474 0.994514941950329 0.420206308430061 0.410090221930295 0.972911126299296 0.857644716415089 0.847728672751691 0.114635224652011 0.663306355576497 0.69827160685556 0.206045269370079 0.133328202620614 0.763411184488796 0.396092654480599 0.364476992862765 0.382165739915799 0.283536638368387 0.0762109543406404 0.12543050426757 0.141141881027725 0.531397125583608 0.908398344221059 0.128261107082944 0.561961237613577 0.720517965289764 0.703057063573506 0.107548593950924 0.652489005592652 0.050374907173682 0.177404258623719 0.594888885573018 0.111090050069615 0.344258074439131 0.997951838751324 0.763712953308131 0.35989055854734 0.0886351990443654 0.268591680726968 0.846020107830409 0.42860915887868 0.849916507813614 0.26053014039062 0.261487131004687 0.941403972734697 0.24925075515639 0.575490015402902 0.838946346535813 0.354216275366489 0.504895934648812 0.913903164619114 0.676283074275125 0.517630060932133 0.600224935617298 0.318420371804386 0.41746362704318 0.771010424036067 0.907067660451867 0.836254967823625 0.334329479001462 0.335159048615023 0.365796543599572 0.3347901289328 0.968371353724506 0.368221306942869 0.157065412139054 0.870474340969231 0.511307897686493 0.970622889490332 0.118398762166034 0.483715972458012 0.247316051768139 0.890821775970981 0.484272833373398 0.54821745346766 0.0143896060646512 0.993336311352905 0.596875556635205 0.948696202761494 0.850566833047196 0.662928846685682 0.204302844807971 0.926495862735901 0.948624495097902 0.0760747929220088 0.400769702491816 0.438229040000588 0.461058262549341 0.993366120145656 0.921238354288507 0.190206635266077 0.414260440710932 0.140772810596973 0.969569505795371 0.588659168516751 0.26287506417837 0.379907601180021 0.527169517483562 0.68547406937927 0.413247530460358 0.799536794214509 0.0971635727677494 0.374290165868588 0.795812604601961 0.054088147925213 0.0478237603208981 0.0458814994525164 0.940491230501793 0.337397120969836 0.0296166630694643 0.495637701551896 0.207347611724399 0.852071192029398 0.869294851520099 0.977163562267087 0.012184134577401 0.0865641950140707 0.256653030226007 0.0170855431910604 0.563128468026407 0.928886969741434 0.206382545921952 0.791294613345526 0.70503161666682 0.590460017584264 0.493009604490362 0.857320902582724 0.0576737620681524 0.226621346324682 0.553710780558176 0.887018225786742 0.611751689275261 0.752616932913661 0.438984442490619 0.749532114602625 0.958467476896476 0.633504686960951 0.944278631231282 0.598553799435031 0.0203385148011148 0.214918242013082 0.732674508267082 0.865337940754835 0.0696560581866652 0.951692983931862 0.332034234690946 0.876586627457291 0.193846044735983 0.106964457693975 0.99335032220697 0.29638722918462 0.0384699936863035 0.597661044981796 0.127990534449928 0.934192263858858 0.431667358088307 0.850469392794184 0.737351705182809 0.193502557759639 0.275853191015776 0.35793149451958 0.588468724489212 0.721143086014781 0.595796114420518 0.163812236064114 0.847924026018009 0.799545784036163 0.0452637474262156 0.215802202802151 0.590344852854032 0.784820179103408 0.447871072397102 0.23880576786818 0.573315770758782 0.624410836836323 0.491827771523967 0.948960713644046 0.0734616390964948 0.52722666800255 0.61617937824456 0.546624631837476 0.50935817591846 0.656991204672959 0.982181493269745 0.427990934322588 0.862457806444727 0.142325509837829 0.473464430337772 0.630819711834192 0.174833875198383 0.72204679393908 0.319713554917835 0.681168489484116 0.549205116797239 0.0738677683100104 0.958171901674941 0.394531043097377 0.327161192616913 0.973677148954011 0.662982994681224 0.746135820788331 0.460187428868376 0.657590735720005 0.705792861008085 0.473407200064976 0.898118813585024 0.500793416248634 0.0478769727074541 0.548802539394237 0.419994316122029 0.652794112777337 0.318541244463995 0.861731693656184 0.998624309266452 0.898780654023867 0.989066985556856 0.16054610830266 0.449815620770678 0.26341187162092 0.314241008535028 0.282517718691379 0.899828781804536 0.454512530937791 0.139833122640848 0.788236193084158 0.634796853328589 0.279627621839754 0.129303345759399 0.317179872766137 0.759303070874885 0.802925544148311 0.364959801214281 0.787153360410593 0.497916763445828 0.490501276673749 0.339796361019835 0.12039503803011 0.518863385124132 0.559673348632641 0.806575991222635 0.299436402153224 0.291065744813532 0.566693283943459 0.378767771041021 0.769551402558573 0.589863696512766 0.273106087902561 0.710598078691401 0.911641005000565 0.870403479018714 0.700381135202479 0.142730871017557 0.028627000823617 0.545041305290069 0.906350838751532 0.692699495449197 0.961519069448113 0.704808072273154 0.386873912427109 0.932112763281912 0.757050297542009 0.0896468765684403 0.0168491275468841 0.609233541367576 0.774537761656102 0.918985983412713 0.0791247141011991 0.754696113783866 0.791114549760241 0.57121076694224 0.0292941409721971 0.207861538121942 0.093274141792208 0.33578963893 0.336764668656979 0.578127865018323 0.728844871902838 0.105437204297632 0.790880170834716 0.339676895576995 0.0564956321218051 0.250839862010907 0.90534153332701 0.289180215871893 0.715377545345109 0.778889513704926 0.734684927985072 0.204891290997621 0.373391171486583 0.720799779982772 0.730002399550285 0.567082988712937 0.326082275025547 0.274580048928037 0.825221172687598 0.147278889352456 0.618068659303244 0.211306762511376 0.206193104118574 0.129591559888795 0.397964899111539 0.114728479443584 0.504504211370367 0.56970153813716 0.0305952678876929 0.944413087624125 0.994566269058269 0.245778779126704 0.445293597567361 0.175331092942506 0.328219253665302 0.702117613265291 0.765131806295831 0.392146462765522 0.670687575179618 0.350754622614477 0.670080603286624 0.464448230457492 0.318757337869611 0.569382457439788 0.874388500235509 0.03542684558779 0.483759595025331 0.977425538776442 0.188695372969378 0.106174793106038 0.806391378443223 0.683844329572748 0.139385139965452 0.940521754543297 0.0844398479023948 0.149542077011429 0.470208563848864 0.941541029424407 0.387532892331947 0.01534541627625 0.0693693135096692 0.452862230783794 0.130947499799076 0.4404985729279 0.025400460686069 0.946288329707459 0.0500377023080364 0.37836486724671 0.398392032389529 0.81632449264871 0.994396512615494 0.833079917067662 0.325613503805362 0.0831680913642049 0.288967033249792 0.114738423314411 0.834125131068286 0.907231997093186 0.428035142135341 0.432877403618768 0.934394589359872 0.518318219436333 0.893443260150962 0.96733822772745 0.267233938518912 0.518381600663997 0.890967027479783 0.866839182423428 0.55779206116451 0.0256533501017839 0.0521780688711442 0.296236178237014 0.994560947450809 0.568572824895382 0.81528630297631 0.785078850900754 0.909812480439432 0.640354261682369 0.210321766785346 0.80595325642731 0.413782861535437 0.0630108512169681 0.140229731646832 0.399791834128555 0.735932608323637 0.496147335765418 0.446428605366964 0.323043597289361 0.604151481618173 0.928206227649935 0.705548726993147 0.918201969820075 0.394756373423152 0.0961687249108218 0.251790807009675 0.764708205005154 0.150555640275124 0.730700350946281 0.874004389066249 0.246506853951141 0.372193716224283 0.730085308705457 0.254941874458455 0.432385102028493 0.258713099455927 0.204615004442167 0.845735745395068 0.886186437588185 0.333353495916817 0.59431633551605 0.252935197406914 0.453583777551539 0.787764618033543 0.133943156348541 0.109252017056569 0.153135558890644 0.821899931586813 0.081136423710268 0.560230913271662 0.966843263604678 0.546610949449241 0.501372713570017 0.839271901813336 0.235007212439086 0.14309315730352 0.676718615356367 0.512622556472197 0.531135142389685 0.180754897531588 0.392962196476292 0.653109421303961 0.234803337731864 0.889677161294967 0.592570913732052 0.0937668114947155 0.0215361616108567 0.663858932375442 0.157784821458627 0.532166113881394 0.476243324333336 0.747203090866096 0.660352463745512 0.881267845486291 0.991726224175654 0.523118774518371 0.0723891303921118 0.661649011501577 0.0882687699398957 0.494406300901901 0.310772868986242 0.732317281046417 0.881354454434477 0.758867728486657 0.109505166709423 0.85082912695827 0.0504373032343574 0.682601833001245 0.943696581942495 0.989312602393329 0.569507480754983 0.364329328455497 0.273527146060951 0.212185914560687 0.852416048189625 0.749509360103402 0.0964249543054029 0.5513279338344 0.490355575915892 0.237077388735488 0.330218601895031 0.101239778404124 0.594408796918578 0.458699997747317 0.398278291702736 0.583569317557849 0.684144555870444 0.688923763439525 0.570527500389144 0.144659627906512 0.952865589889698 0.5804014971992 0.696072135805152 0.504165420187637 0.026774814275559 0.482576192568522 0.0230778209422715 0.135300708392169 0.831145580869634 0.339812051544432 0.826029831590131 0.334810724777635 0.216559485499747 0.457519706611056 0.31943657892989 0.189792027946096 0.659323113607243 0.420673415423371 0.950994805721566 0.833351921120193 0.727007412379608 0.363774680593051 0.172079697737936 0.0759681258909404 0.950058788745664 0.793367265928537 0.521554363684263 0.269428527529817 0.459009782746434 0.715659150741994 0.23452396820765 0.415871310443617 0.0801207525026984 0.52894391156733 0.123049463299103 0.396768387986813 0.123845169814304 0.42202800297644 0.639559153551236 0.0651771276257932 0.374529066327959 0.907982721077278 0.307066634814255 0.750568397098687 0.576132606361061 0.914798919751775 0.834963509328663 0.858700402597897 0.5127136445418 0.343231109539047 0.841405822839588 0.557659459162969 0.536109368074685 0.713742723653559 0.742087224030402 0.214139178688638 0.848359597756062 0.876708937759977 0.621680229853373 0.89677173856413 0.759449693642091 0.145012175238226 0.781175705036148 0.242859705365263 0.357513337924611 0.234798967868555 0.407481312113814 0.567541674533859 0.398681110441685 0.223689148451667 0.696893282171804 0.503313598569948 0.79424114293186 0.837950044670142 0.0434305438981391 0.308472019319888 0.83276908028638 0.897292931086849 0.730856423617806 0.656183628900908 0.911787741866428 0.758413921939209 0.2533790665376 0.266111201050226 0.511411803991068 0.5710027581756 0.282908038902096 0.689984387443401 0.716609332317021 0.905282586503308 0.334132418173831 0.292606164503377 0.0376267430675216 0.813069046365563 0.183180513964035 0.871237038166728 0.914614873547107 0.953179630883969 0.939763184490148 0.550904369885102 0.218207758155186 0.234269414795563 0.232729675087612 0.322357856524177 0.185399957119953 0.992811209280044 0.400432295245118 0.014174999629613 0.231429296382703 0.794249095492996 0.249677858469076 0.503881287563127 0.420347137060016 0.587099392623641 0.394631164553575 0.875410174876451 0.903605703897774 0.494488736835774 0.472540730484761 0.0778987397067249 0.112614449616522 0.39686924313195 0.422486637395341 0.215133230159991 0.847075962510426 0.510421215817332 0.0218283419939689 0.627671021325514 0.321227342367638 0.121702609790955 0.0904595879325643 0.348296559520531 0.625068715631496 0.515290120604914 0.650428070134949 0.335480681895278 0.222638374273665 0.820672757658176 0.845727997289505 0.45705317103304 0.870225923298858 0.395323766912334 0.583977398434654 0.599085954879411 0.924118245649151 0.680261459329631 0.996412462545559 0.416581279770471 0.702115553035401 0.539322464393918 0.330332557871006 0.604557190625928 0.931666651132982 0.194041981403716 0.0414327552472241 0.845949179495219 0.202262180878315 0.685658579585142 0.418212180617265 0.715553313288838 0.664501688373275 0.915241316203028 0.380109402518719 0.780690682940185 0.261890312323812 0.660039454940706 0.968510227003135 0.589320605576504 0.169721840694547 0.269883072376251 0.792127569499426 0.852798333088867 0.911698444338981 0.764212117644492 0.680837132462766 0.109418630830478 0.28954005768057 0.512172188558616 0.205629954868928 0.90925934674684 0.982470335057005 0.903481328294147 0.122955757414456 0.21933636052534 0.961416702899151 0.76368489794666 0.801838031124789 0.286814762854483 0.973966607335024 0.260119036706164 0.541516123558395 0.397707302146591 0.818053475928027 0.753562047816813 0.335186104979366 0.295704117759597 0.779594182400033 0.33972919263877 0.462103505362757 0.211026717615314 0.310979229891673 0.795853710314259 0.250018828359898 0.17969505446963 0.0848334334092215 0.989020268726163 0.47229371542111 0.938631183363032 0.171329232377466 0.58878964505624 0.144778849938884 0.11454727394972 0.439977698267903 0.453818058283068 0.398848805041052 0.0172822764748707 0.363987079507206 0.510711781531572 0.12069341662107 0.848731339247897 0.097009579918813 0.24488158865599 0.927709471601993 0.225321463199798 0.698831932682078 0.141136579704471 0.0649090955895372 0.92130120075075 0.628617581708822 0.0427857670863159 0.679244296310935 0.824067005533725 0.0907186172390357 0.569335032505915 0.962713945619762 0.838038410507143 0.125205157576129 0.92135881411843 0.211063544512726 0.150806050638203 0.309402466898318 0.637010984788649 0.0937826804281212 0.476392833911814 0.907824942457955 0.0942459101416171 0.860360543127172 0.585595659224782 0.680805591444951 0.985850782527123 0.411452543528285 0.16672234259313 0.52455827913247 0.636899175941944 0.975570869026706 0.801827864588704 0.406907760754693 0.23191423595883 0.9622453147755 0.48420913727954 0.64679022946395 0.614938306177501 0.343126722406596 0.373449708246626 0.837714120226447 0.116545981152449 0.134413129868917 0.161418562415056 0.906008790801279 0.0562732017459348 0.954134703027084 0.150698208275717 0.963964108237997 0.856363572899718 0.680428633224219 0.684341988728847 0.261598312193528 0.772027006649878 0.67922318367986 0.259850180624053 0.373216888208408 0.384657460269518 0.899798113929573 0.937745563648641 0.860521995031741 0.990678595202044 0.707845369530842 0.765151619354729 0.0518046965752728 0.130549226105213 0.849898315647151 0.737233129017986 0.9363722208119 0.0248541498626582 0.669628936031368 0.0815691830893047 0.38820146482205 0.470926013668068 0.5842921765754 0.830286642031278 0.451820764059667 0.478747897497378 0.266339266516734 0.3284862740268 0.511094654672779 0.582703636065125 0.455296729623806 0.989184096879326 0.691672049490735 0.210054562252481 0.728093452723697 0.309262143529486 0.205426375896204 0.429991218161304 0.812390462467447 0.1880368921021 0.702447597875726 0.818447221633978 0.455219722711481 0.271974615547806 0.462980966907926 0.227356277210638 0.877859165628906 0.278679782859981 0.743425448453054 0.112724871761166 0.555362518585753 0.703224615722429 0.99983697399497 0.816426039992366 0.203372651934624 0.621267514957581 0.649352139162365 0.0873301210883073 0.0130617600097321 0.846908751735464 0.814210251681507 0.882812824973371 0.207880744037684 0.96465565189952 0.801522781606764 0.44386415138375 0.822225491704885 0.456089556242805 0.969605132467113 0.682755926118698 0.349912680326961 0.596004402786493 0.668104100143537 0.318367617656477 0.840351450981107 0.13765392242698 0.719433380567934 0.121532199182548 0.0665125857898966 0.965610447900835 0.598719873372465 0.585187673775945 0.962333396403119 0.0974249640316702 0.476841926455963 0.154009271084797 0.813973877527751 0.940163950375281 0.436673803851008 0.28844812661875 0.377361535059754 0.767497458006255 0.216823821892031 0.0697181603568606 0.687055225286167 0.896472541228868 0.278083999780938 0.520472782407887 0.307736961657647 0.0917486452846788 0.536763873468153 0.360692929807119 0.332331822428387 0.442139836468268 0.979495766013861 0.41307778946124 0.700996802335139 0.27732031626394 0.170439841644838 0.0132903355779126 0.407272894436028 0.61537875741953 0.594884470531251 0.889793562209234 0.667625837528612 0.75157849844778 0.942510158291552 0.626299712671898 0.994204583691899 0.455955650059041 0.129113547599409 0.812251968365163 0.0667901465622708 0.969658278238494 0.309024387514219 0.996235245433636 0.641318708355539 0.0560112558933906 0.940642269924283 0.355267114315648 0.26955619078828 0.202543194114696 0.481884840454441 0.1063757722429 0.70666224782588 0.833683177873027 0.706887982222252 0.0686858344334178 0.382934414269403 0.662571844665799 0.66898313601967 0.123522757897153 0.672692046784796 0.990050774372648 0.930123041060288 0.335269589929376 0.985825864071958 0.0603754352452233 0.126944356027525 0.0999319814424962 0.610815330464393 0.327429848392494 0.645932247210294 0.899951399136335 0.644564553063829 0.93519939057529 0.499989643765148 0.467548306640238 0.341363417790271 0.31175821761135 0.809981728487182 0.4390823432873 0.856017009639181 0.170326517936774 0.678405023009982 0.239478697313461 0.823018792006187 0.266673459638841 0.399290155011695 0.902164427873213 0.136324638959486 0.958593729019631 0.371870010958519 0.872716346615925 0.187863888342399 0.266475457900669 0.107973522474058 0.370180290064309 0.704450615702663 0.465365899677854 0.120009516186547 0.8000619386998 0.0263896285044029 0.610511647092644 0.854885324991774 0.057934939195402 0.366376359320711 0.050514928123448 0.290113667356782 0.156448344474193 0.737226143875159 0.71513346642023 0.322646548254415 0.251441231314093 0.995873613313306 0.715152112215292 0.644575997043867 0.946146796431858 0.982099773276132 0.054733088624198 0.3469010176952 0.024240864510648 0.159088546365965 0.525472033270635 0.909928199297283 0.103129352431279 0.182916352292523 0.964939558170736 0.261656413765159 0.858899894533679 0.856475383820944 0.670524406032637 0.654927548135165 0.484877992135007 0.980350739520509 0.23221529413946 0.598434663610533 0.93124006691156 0.560186503999867 0.0518657243740745 0.697301532928832 0.708120315484703 0.0341836427571252 0.357642444358207 0.928699743757024 0.212975852063391 0.867866165533196 0.156009948621504 0.974987540449947 0.686855146721937 0.32849856441142 0.915706366193481 0.252391528140288 0.531289284834638 0.554742286584806 0.336982557214797 0.653829256130848 0.339355141052511 0.0606910625565797 0.393197621421423 0.996848223065026 0.266000178446993 0.723105824480299 0.697466032996308 0.512875973738264 0.0810507967020385 0.94389086291194 0.508779825961683 0.917738169843797 0.197046212179121 0.441257858229801 0.258293990886305 0.422355654442217 0.396726245936006 0.927005747735966 0.0359191409545019 0.742907275049947 0.606048331451602 0.557154671722092 0.818767444009427 0.200262245559134 0.641905144334305 0.626230065699201 0.658905604723841 0.833956470894627 0.316955576934852 0.275894987313077 0.280487926404458 0.196049130293541 0.929469895861112 0.541009482187219 0.362705235034227 0.643319140407257 0.140850504636765 0.0480518854875118 0.784453377737664 0.603580873312894 0.723261717129499 0.33712775363354 0.0582880761520937 0.614595543670002 0.15290682312334 0.723697361475788 0.335478542372584 0.0572043772507459 0.51569869176019 0.615292098221835 0.986170566948131 0.131594725006726 0.654012301494367 0.0627273637684993 0.783108127603773 0.690737699046731 0.990701887002215 0.283727633757517 0.57589618334081 0.298410031257663 0.808148787501268 0.0242908623116091 0.984694443580229 0.686388428355567 0.541295290102716 0.522224249115679 0.566400176249444 0.986138480792288 0.376978422887623 0.356212395180482 0.780542931633536 0.236978682794143 0.291949268800672 0.247889398210682 0.528194603328593 0.213640904321801 0.110780126538593 0.897470294798259 0.967610334814526 0.741439741351642 0.71957332360791 0.718547317828052 0.752608089691494 0.573212319004815 0.502057821375783 0.527011546394788 0.929199309628457 0.986084314817563 0.784759496597108 0.801965626385063 0.366054782283027 0.898923001433723 0.0762034888309427 0.72732222763123 0.477866688906215 0.842300780895166 0.656464473179076 0.304650643467903 0.0281522033503279 0.0215399075043388 0.979168837864418 0.969830693525728 0.713874753317796 0.192399285752326 0.989921767746564 0.83059377948055 0.213162635483313 0.913331423394848 0.985996899572201 0.913462849603966 0.795719993603416 0.208973874864168 0.646438063383102 0.182882887963206 0.955377595601603 0.294844131518621 0.424155612387694 0.920690831483807 0.895107726517599 0.322335745817982 0.91194540892262 0.305706590118352 0.0429079589108005 0.718141840705648 0.330027501396835 0.243987561368849 0.736967576495372 0.750476234888192 0.0813077353523113 0.549984756608028 0.862838628576137 0.140621111015789 0.596483697129879 0.25451095656259 0.625814517699182 0.908178938957863 0.850851999244187 0.90200875489274 0.562430760732386 0.320203760550357 0.106671960139647 0.590246714639943 0.84394168300787 0.124634972703643 0.146002835789695 0.959092622054741 0.892390438190196 0.20936030580895 0.656288983912673 0.0105362948053516 0.792211683259811 0.825375501378439 0.502926604738459 0.73948398595443 0.0593854302424006 0.487752132231835 0.719779580095783 0.188515068739653 0.830018418908585 0.454515340530779 0.638804674223065 0.685731760389171 0.145070155565627 0.550526288656983 0.311966441667173 0.826504456417169 0.145491818792652 0.668942675022408 0.533530835700221 0.49783519489225 0.879547212845646 0.296357684547547 0.344038419541903 0.250177149351221 0.416006216316018 0.66626477009384 0.138845302108675 0.253834374116268 0.718240904156119 0.736817687510047 0.923828966137953 0.0328778924257494 0.450809780347627 0.295675670083147 0.65887889664853 0.138401743464638 0.833437364879064 0.176916666426696 0.0325055216625333 0.213809359809384 0.262690921623725 0.825527678329963 0.672149736790452 0.904931272359099 0.173758621211164 0.614878777335398 0.86276660673786 0.291821642883588 0.62928256182 0.252880270774476 0.308104105319362 0.526061694668606 0.494118096684106 0.855019439319149 0.445247282963246 0.989068637336604 0.399306093556806 0.596081773892511 0.956654949197546 0.759509349721484 0.337182913303841 0.574775533762295 0.152235638350248 0.220354414666072 0.187596223726869 0.469794519646093 0.970365853568073 0.48306200413499 0.305775956339203 0.138965515070595 0.816541336339433 0.726604261486791 0.562778839084785 0.964914825269952 0.8323966440605 0.0164419191214256 0.700084604318254 0.255449027775321 0.738906215250026 0.519234182939399 0.870553214028478 0.980043324085418 0.559741783624049 0.156521454053 0.357907729498111 0.154812124785967 0.453242172626778 0.653133542912547 0.557788833209779 0.523690439215861 0.897191843825858 0.0409918538341299 0.796148209781386 0.894277202854864 0.0702539542806335 0.250081153886858 0.0961218430404551 0.92467069060076 0.482141210455447 0.992717527828645 0.728580458983779 0.797978652813472 0.770350925731473 0.73552250640234 0.555118907580618 0.0149944743933156 0.918229893795215 0.919547366092447 0.471273189834319 0.471293547339737 0.738276846366934 0.0657168002123944 0.910257637847681 0.359682246209122 0.489565339221153 0.330890934569761 0.603422943253536 0.332611532865558 0.706067538887728 0.290026669781655 0.674514555004425 0.0730560133000836 0.657211072323844 0.312809354830533 0.46170908359345 0.72490751465084 0.0330644522584043 0.478336733882315 0.841664127907716 0.84354006242007 0.155614532234613 0.772742707647849 0.946137350907084 0.678110435951967 0.612098721838556 0.530478032780811 0.045374217745848 0.932676585367881 0.748253615410067 0.584117367290892 0.129376172050834 0.921709328419529 0.330956932229456 0.803949361308478 0.293222205510829 0.968113232366741 0.52653272619471 0.143993825824 0.938095399811864 0.746191396745853 0.599444703185 0.710556671251543 0.526374269207008 0.536686570129823 0.90095095200697 0.342137610139325 0.236267704097554 0.494403659575619 0.760127367747482 0.937929271014873 0.558934384416789 0.410399662097916 0.658222951076459 0.657461563132238 0.658752506223973 0.599397082554642 0.307586043479387 0.675893631356303 0.37223694809014 0.117502250294201 0.599650655179285 0.175882342508994 0.121597140450031 0.0687008749414235 0.703688657726161 0.915197668280452 0.38954786285758 0.173397985552438 0.137702653617598 0.438583868844435 0.442681035210844 0.555220077361446 0.775628271901514 0.0888891971763223 0.307407638819423 0.579317745743319 0.825068259511609 0.813557182778604 0.424804168285336 0.362240752771031 0.981398666072637 0.592940175479744 0.444847102554049 0.177945624710992 0.344650157301221 0.124200037843548 0.628658390764613 0.834419237067923 0.617662501507439 0.733938043939415 0.570423815597314 0.255802937375847 0.4832622779347 0.0165757736726664 0.636768646847922 0.3203671823279 0.619689710324165 0.410940511168446 0.908957788376138 0.220440450124443 0.344859842741862 0.744305128583219 0.485841786025558 0.0223224689322524 0.905573993551079 0.0218974219309166 0.788047507328447 0.0634344979166053 0.95362785074627 0.69256100111641 0.43238110949751 0.907274679441471 0.365322855995037 0.645273835032713 0.802987277745269 0.906666414660867 0.217620567281265 0.659978342547547 0.595660720805172 0.918647198453546 0.822210057959892 0.444908616943285 0.764769506871235 0.951214098730125 0.850373316884506 0.415016313195229 0.431787400247995 0.438609714841004 0.707824163315818 0.0290825946861878 0.985448030403349 0.783591455968563 0.782999024163 0.937398710416164 0.119653127994388 0.644430037892889 0.530652863041032 0.657985329444055 0.464050121342298 0.584951837845147 0.873981366031803 0.0812494101934135 0.468803950143047 0.0863186950422823 0.249407990481704 0.10565593810752 0.415286797084846 0.390947179850191 0.91979954025941 0.176378208587412 0.653281788646709 0.387838153953198 0.202055397001095 0.552737311332021 0.443852438868489 0.931527935517952 0.441840635214467 0.0972958066570573 0.243364212284796 0.500601325512398 0.576979210097343 0.390668530876283 0.857133361732122 0.790566447242163 0.838093105484731 0.118325727269985 0.494137303752359 0.445453650783747 0.774511195339728 0.163513336537872 0.464110558133107 0.592470486629754 0.665275332818273 0.871740259574726 0.556306846323423 0.142844757842831 0.964304210287519 0.0186784607102163 0.662942502335645 0.626582087716088 0.0348810524726287 0.0239525328250602 0.484025358227082 0.16374090296682 0.964980881016236 0.339318968781736 0.139679961213842 0.23369705859106 0.424352301184554 0.847271742897574 0.280156111605465 0.214020082049537 0.744223120231181 0.44557005815208 0.56763562936103 0.706238170778379 0.555557596401777 0.576653976831585 0.836328052277677 0.279812622785103 0.145729018836282 0.306926522585563 0.934083803058602 0.151359667694196 0.464564147547353 0.982992550088093 0.604312243398745 0.695117547486443 0.859807857761625 0.238770850913133 0.0372306506172754 0.355375175424851 0.574683990681078 0.920570407381747 0.168915724463295 0.336710680630058 0.354054504677188 0.35021381042432 0.463472393511329 0.0588488698983565 0.682911120576318 0.0640016973228194 0.717247115687933 0.623183470899239 0.521765231601894 0.846911541505251 0.0340037843189202 0.449222488007508 0.977132196892053 0.878788024124224 0.87714948005043 0.48148571989499 0.35359993585851 0.0168595061451197 0.414999482606072 0.262112941162195 0.811953959499951 0.124521676886361 0.170622751472984 0.938467608762439 0.056718195497524 0.391997111772653 0.929243123512715 0.477578981190454 0.55740861176746 0.430297624687664 0.4720052532712 0.953899433901534 0.781383808769751 0.680007164080162 0.798195340915117 0.229852176571731 0.673113682582043 0.173490070544649 0.974839289644733 0.600623950376175 0.393055314349476 0.545039561539888 0.479535380841698 0.12519634178374 0.314233441834804 0.126731028880458 0.300092517375015 0.612747984456364 0.856752662919462 0.336921909744851 0.0604270412609913 0.962162138929125 0.553905797521584 0.600738327710424 0.299076256542467 0.303055514048319 0.536553990487009 0.326510670303833 0.483983062431216 0.817559818523005 0.165479232424404 0.857808509762399 0.919630462415516 0.304221924333833 0.238382956970017 0.635008987856563 0.899890299881808 0.726569770961069 0.982270119574387 0.772861327608116 0.318056749526877 0.136576524076518 0.545360846300609 0.932487803492695 0.381043427262921 0.211100698492955 0.59985082986299 0.398811739573721 0.926491589453071 0.988515970180742 0.834484334154986 0.106359914604109 0.238925322976429 0.825377931564581 0.660248194169253 0.402230070794467 0.554990211671684 0.772283815527335 0.508463680711575 0.345164446739946 0.316296812319197 0.979337325391825 0.329876254291739 0.504451875353698 0.695037954568397 0.910736799882725 0.918853464392014 0.43275836644927 0.569684384844731 0.487787524943706 0.940810976428911 0.11975822530454 0.751408461714163 0.89447450962849 0.0752114616311155 0.772650766258594 0.85401124975644 0.897512802656274 0.947068591183051 0.173449939396232 0.519335878265556 0.917825988929253 0.977183225499466 0.353039249295834 0.882224940978922 0.762411785824224 0.815725518956315 0.601849862535018 0.993585175506305 0.52816158317728 0.294706275446806 0.657798104151152 0.861112138410099 0.349113718427252 0.526321415943094 0.728099879128858 0.360921731037088 0.322292097434402 0.289747660302091 0.435122716051992 0.315961243328638 0.885743919892702 0.103435245398432 0.0141460224892944 0.486503088702448 0.111972815243062 0.0694717356096953 0.310189571527299 0.125996399952564 0.607744040335529 0.805811714162119 0.361271303044632 0.501413085823879 0.497199816352222 0.864359560445882 0.394060737884138 0.190178246367723 0.0732907310640439 0.678638497674838 0.34394261331996 0.0454355534957722 0.620483496293891 0.640357384758536 0.455839946875349 0.419845250491053 0.9872418809589 0.566424264896195 0.209200741718523 0.697484744484536 0.771957142313477 0.0269694292428903 0.710427275998518 0.546718824082054 0.855730358315632 0.306808711457998 0.480587679792661 0.820036624914501 0.301316360314377 0.46685494201025 0.0823133813217282 0.938400076879188 0.0830317068193108 0.170985118665267 0.219302136690821 0.221446324060671 0.323871940169483 0.98780188154662 0.829497461959254 0.880791139914654 0.588641610923223 0.0668122598039918 0.419747296448331 0.940565103965346 0.876367610590532 0.986924972976558 0.489598499978892 0.808396304599009 0.576360196992755 0.547366734112147 0.468240654754918 0.449630630658939 0.524239277958404 0.387002567076124 0.249423914505169 0.879377490978222 0.613047187323682 0.172332324380986 0.744730574353598 0.81750329059083 0.332156666007359 0.322768802775536 0.961590708422009 0.237916103990283 0.752194882442709 0.828768704847898 0.990325034351554 0.656740596308373 0.376951876394451 0.352646176195703 0.649013037262484 0.288155098448042 0.633200554570649 0.0274142902251333 0.381554599157535 0.147971110229846 0.587966206574347 0.681108846312854 0.339830880819354 0.0681273650727235 0.194544998125639 0.350561981899664 0.103887272467837 0.111867248860653 0.801297392963897 0.840759391020983 0.856483663234394 0.673441725440789 0.551287108643446 0.798573527482804 0.814963412075304 0.825860310029238 0.852379379877821 0.487011960644741 0.944500596683938 0.648475055641029 0.919780240068212 0.448912755562924 0.141034229982179 0.664892526292242 0.551453102135565 0.793549913906027 0.585990372579545 0.23813079317566 0.262715570621658 0.198641675827093 0.292848993414082 0.477248136575799 0.553535514418036 0.538712137308903 0.309571943280753 0.639537118910812 0.735368774482049 0.998410114278086 0.657526833326556 0.873624245303217 0.81191629541805 0.451622988905292 0.808329367872793 0.0426546612754464 0.889787816016469 0.321459402670152 0.987949565085582 0.946199400522746 0.831678168505896 0.100973944668658 0.35104338580044 0.619293825787026 0.091485159676522 0.837606534874067 0.560496371288318 0.590186263788491 0.747802660407033 0.771823363597505 0.659092079962138 0.381739151775837 0.2771073270333 0.829848606914747 0.786895488456357 0.777993195455056 0.186931865741499 0.518648878035601 0.932422377017792 0.640879153767601 0.50748149918858 0.232980378649663 0.390025358130224 0.530144056100398 0.466607273472473 0.738171766805463 0.250231799841858 0.772229030423332 0.42902972284006 0.622093379246071 0.478541994600091 0.800850306251086 0.0760983995883726 0.695425958230626 0.862950767502189 0.318924393977504 0.788829377479851 0.970617349136155 0.478036712270696 0.105936911005992 0.971432780888863 0.13357329898281 0.59730809795903 0.798254226655699 0.0513528292439878 0.314116154869553 0.160492961839773 0.920130173042417 0.560331474065315 0.0271113707381301 0.952476012127008 0.280988284281921 0.704611608446576 0.398175393154379 0.0812710283161141 0.482520228445064 0.30885406357469 0.364282887997106 0.100203389185481 0.516958234440535 0.0183692747866735 0.617450276853051 0.74730460732244 0.192080018809065 0.283001389121637 0.298307391332928 0.858988934129011 0.306459034802392 0.136432367223315 0.951544624560047 0.836716330929194 0.825160921220668 0.391792316669598 0.569105532623362 0.415251201300416 0.496929775027093 0.436349865547381 0.31463966970332 0.263465625457466 0.228988609015942 0.0770740897045471 0.18604587929789 0.919808177181985 0.91501623412827 0.101105336993933 0.103269103923812 0.518822103999555 0.0950630844919942 0.596802024776116 0.528548929446843 0.767979522296228 0.963310990699101 0.400056774667464 0.260775505979545 0.20313784404425 0.0907029442326166 0.529825645934325 0.55620914168423 0.290605613512453 0.863500390183181 0.201341436526272 0.945037222029641 0.0598741323081777 0.0507921184785664 0.78945542643778 0.376569727952592 0.939211771267001 0.156114643244073 0.605793093447573 0.419235725554172 0.676627134741284 0.949499298029114 0.976887824307196 0.685726496637799 0.790972278416157 0.353534176538233 0.525291610101704 0.594206294622272 0.964513922927436 0.887312287068926 0.510000608752016 0.248014477537945 0.36625866989838 0.305901333475485 0.71657470879145 0.193444351539947 0.52750702430727 0.477765792270657 0.908668088659178 0.930006295084022 0.213127981300931 0.252856289311312 0.163553828191943 0.251257063173689 0.620368270941544 0.0304711043462157 0.582027936673257 0.758558360005263 0.532936700021382 0.0585263593262062 0.604028694406152 0.19440266523743 0.829491567092482 0.37269229831174 0.856634557209909 0.263303204521071 0.996115316220094 0.886268712861929 0.504858593270183 0.652718157416675 0.269125605276786 0.43696893789107 0.248160700614098 0.83990037150681 0.2962052291492 0.887239074225072 0.219242968123872 0.43426634662319 0.310185536583886 0.871325632892549 0.727385833598673 0.436737764100544 0.193230916978791 0.633906033020467 0.39089990013279 0.610090541911777 0.351831628188957 0.852455257328693 0.0264215367124416 0.49776982097188 0.334592122815084 0.0787652109004557 0.225081054333132 0.332692587398924 0.0637925314344466 0.364272347586229 0.540405300986022 0.845483585288748 0.126500531844795 0.638970199103933 0.395963767485227 0.695760748584289 0.166778506562114 0.0377489219838753 0.492166808191687 0.0493005489185452 0.260831276250537 0.215569534434471 0.400725465866271 0.785666982915718 0.115939410564024 0.814911798222456 0.711042176710907 0.627385761775076 0.331850840116385 0.362885754092131 0.015196531128604 0.719604243421927 0.0425322583108209 0.556626936621033 0.831390672852285 0.561452582804486 0.329655889908317 0.723447579231579 0.745268549520988 0.175829594123643 0.334584674593061 0.0392866473319009 0.95209026992321 0.196133860647678 0.164567393299658 0.602921812271234 0.662943150047213 0.379450629143976 0.312274439351168 0.677316232542507 0.992970442138612 0.212412387486547 0.239030460393988 0.311086265265476 0.932505710066762 0.298835110529326 0.334130391136277 0.91298855047673 0.829947634406853 0.408477651320863 0.260005155412946 0.358304723904002 0.750496921781451 0.415002203916665 0.886931489601266 0.0872189521160908 0.462313029451761 0.285069623435847 0.547256686994806 0.880260390304029 0.554518095632084 0.204033201329876 0.924238145588897 0.80997846388258 0.963490527125541 0.0872029704670422 0.711940133832395 0.0931752696586773 0.417355404121336 0.728723966281395 0.184042654940859 0.455851739605423 0.254014076734893 0.532574387458153 0.157058821616229 0.218630510736257 0.742447636793368 0.520228782775812 0.87433250245871 0.824839293011464 0.239148648392875 0.739657614605967 0.97558448917931 0.327904681132641 0.994407059941441 0.449511148619931 0.424057114128955 0.0666026073251851 0.490458114880603 0.637417967552319 0.960169973382726 0.479489098968916 0.62598867996363 0.194892486853059 0.62310821903171 0.227657055791933 0.965299787223339 0.312404831065796 0.0215141686913557 0.718849888565019 0.554488107047509 0.745538031416945 0.706014653583989 0.985568292923272 0.810057666790672 0.638957478140946 0.87751393282786 0.574403438218869 0.513300276678056 0.774595641253982 0.445141049737576 0.691453677800018 0.0205440320679918 0.103037916303147 0.403502767090686 0.892795885116793 0.412053432925604 0.141157429793384 0.866938666310161 0.200079161701724 0.683406700831838 0.460137418620288 0.417741840598173 0.164061641206499 0.299550420595333 0.448973236610182 0.297487116956618 0.740065079811029 0.3945740250987 0.310471662592608 0.444592966581695 0.264437096228357 0.404424455580302 0.567130617641378 0.965885616289452 0.238902055379003 0.966148376045749 0.770097118224949 0.333459770402405 0.401393599479925 0.0229695781972259 0.0309427490085363 0.773213141942397 0.949474655024242 0.456462783091702 0.606515850813594 0.916700275214389 0.912727445957717 0.996867644039448 0.757421880909242 0.853768000409473 0.912736122296192 0.0572489868290722 0.886448613021057 0.20011572167743 0.0366588310222141 0.998761858770158 0.0613467407459393 0.661398594453931 0.289218097317498 0.469956673660781 0.813137287274003 0.885614424140658 0.390554470482748 0.327943450473249 0.596255727552343 0.458985259141773 0.734983851483557 0.0743526583281346 0.556890556612052 0.722675073698629 0.918534495718777 0.0962752109975554 0.242646784132812 0.453857078640722 0.963472364002373 0.681843969207257 0.17309432108188 0.104288766279351 0.849165868654381 0.584127384691965 0.605047572131734 0.0502995644882321 0.551340069782455 0.352372254594229 0.298761279939208 0.528931147039402 0.450174033925869 0.577097471626476 0.631088874714915 0.268826809476595 0.430352534493431 0.638975864390377 0.773311695521697 0.732613045740873 0.107953527318314 0.485966480183415 0.144227135910187 0.487333566956222 0.897516554081813 0.48749298122013 0.616441943917889 0.574742899932899 0.752611990713049 0.0622023716452532 0.256410414529964 0.781909079800826 0.813227243116125 0.0663539354107343 0.659667462662328 0.486769001730718 0.931279357648455 0.145699664824642 0.987047870138194 0.181075656285975 0.806508891761769 0.215282896249555 0.869462826179806 0.0833302824897692 0.0368179751373827 0.0973807924077846 0.735110369836912 0.043647130348254 0.185893576261587 0.25337940675905 0.726077005139086 0.813958604212385 0.577540909026284 0.536668960442767 0.503043162163813 0.119504003124312 0.0355374237825163 0.126625084013212 0.146338097520638 0.768935340805911 0.956132806083188 0.395341255816165 0.773193514207378 0.313754437232856 0.602779935777653 0.773503894824535 0.771649673401844 0.401597560856026 0.922673740286846 0.70095424376661 0.869196100169793 0.688276377571747 0.435580791733228 0.621638607354835 0.578219759846106 0.812388773576822 0.568565082782879 0.789592052779626 0.27599129948765 0.586997963297181 0.347276811418124 0.482966577550396 0.785098010485526 0.0370748243527487 0.0880949004134163 0.81120557004353 0.662083030345384 0.481136389453895 0.64073956039967 0.452669224722777 0.157425658479333 0.689929026775062 0.676029154513963 0.587867041011341 0.0450853731925599 0.842145108606201 0.624602497916203 0.743641270557418 0.557306663349736 0.397811807526741 0.73014231977053 0.972501241972204 0.736112013133243 0.844180986615829 0.908561694542877 0.550874429014511 0.151955367331393 0.796729618043173 0.372624142689165 0.428652216945775 0.889232934885658 0.780943321799859 0.594466898029204 0.986818045477848 0.359706188947894 0.0553316815267317 0.303573500744533 0.902937189263757 0.0722818539128639 0.954998398281168 0.773794919007923 0.69256916412618 0.188832127470523 0.341418632781133 0.707321503181011 0.543357491479255 0.760993323768489 0.216837702512275 0.657069594829809 0.674072734578513 0.984887638422661 0.107729819728993 0.80361822049832 0.594559772722423 0.433423832689878 0.668482741722837 0.388548562156502 0.190917913154699 0.955803616475314 0.839717530598864 0.0850226117484272 0.945750787423458 0.805283287323546 0.44540763375815 0.18453543551499 0.0420347671909258 0.155765267163515 0.516908666756935 0.416529028348159 0.755994110477623 0.904274863938335 0.777170746058691 0.62389472896466 0.974442818479147 0.976912856400013 0.045134262277279 0.626128251894843 0.367104208483361 0.29898953902768 0.413574779699557 0.0966587804863229 0.313522340049967 0.69801911436487 0.592695140431169 0.694037352220621 0.988371589048766 0.349829281123821 0.423304084660485 0.875127492342144 0.543430830868892 0.183186374255456 0.744654258256778 0.934212847026065 0.959663916565478 0.986898893711623 0.0573327571409754 0.650267776504625 0.167296584998257 0.308361444813199 0.472061600950547 0.222754297126085 0.0280441108928062 0.381779795330949 0.0122923001041636 0.810734295567963 0.407597387097776 0.673242365582846 0.377520895155612 0.02239763781894 0.452134730832186 0.564052122931462 0.600592047008686 0.943623384081293 0.775727655289229 0.546403451936785 0.0722641326626763 0.015465317138005 0.600907505592331 0.832137093127239 0.0581711621396244 0.493508539937902 0.870213424540125 0.52246333881747 0.0872342775249854 0.936595923099667 0.88327683217125 0.589758185911924 0.45506526977988 0.0119667759444565 0.564899061357137 0.300808196936268 0.921373890815303 0.289632166875526 0.677298796884716 0.488198322751559 0.85025719510857 0.35592434217222 0.113889113941696 0.0266881234990433 0.111322342026979 0.260752774761058 0.793286320192274 0.238749637783039 0.9125127134379 0.867747927515302 0.0961345135234296 0.276643801585305 0.340846377306152 0.223011477342807 0.27543859199388 0.549420314931776 0.307215282774996 0.693858874491416 0.874519545654766 0.0913574800523929 0.287045675024856 0.504769206999335 0.106752931692172 0.787108847643249 0.257407186620403 0.0387416671984829 0.418074034804013 0.361725526570808 0.509317702704575 0.203742970074527 0.724802890331484 0.309782235634048 0.903023052536882 0.818808375231456 0.259232372355182 0.433769595415797 0.321547799624968 0.738758060103282 0.0427165440074168 0.252692986011971 0.0678485346934758 0.263026900216937 0.847999753642362 0.466522470049094 0.169875905690715 0.712733482308686 0.430852497981396 0.441362280168105 0.1781729405839 0.695886505357921 0.743273415565491 0.886647950750776 0.582050012343098 0.500061507709324 0.611305196105968 0.624045649447944 0.0824165470222942 0.788106575857382 0.785560971433297 0.270801381471101 0.157826119409874 0.473686963978689 0.654624810745008 0.759369473296683 0.498713352093473 0.064291544330772 0.472713123413268 0.16106658188859 0.352862488117535 0.0731933350674808 0.530619181809016 0.0418282735161483 0.313404479825404 0.225505089429207 0.0625790212233551 0.539594950196333 0.854507357862312 0.0211614581639878 0.502940276523586 0.580986923347227 0.510428894772194 0.455490228959825 0.116841136629228 0.841320054763928 0.362481833091006 0.524570249579847 0.684701572144404 0.183613904688973 0.246964527636301 0.656293902141042 0.743648159119766 0.340668906872161 0.852137770554982 0.154217620994896 0.264551026388071 0.0388332570716739 0.680779455937445 0.817754627112299 0.684758943254128 0.911818935978226 0.14227183368057 0.0952605277230032 0.663068738323636 0.487844204085413 0.869559036011342 0.54810274858959 0.102349884805735 0.482995874627959 0.976232568167616 0.98207431867253 0.732010019356385 0.761334044255782 0.268830342155416 0.515383948886301 0.433140286693815 0.104264661266934 0.314629053226672 0.566427529500797 0.468728736769408 0.258540939795785 0.817877860115841 0.556268307485152 0.0392518864269368 0.325171155759599 0.0818753959937021 0.950681923001539 0.549322888969909 0.606337061445229 0.654283523452468 0.446750643409323 0.620655609162059 0.0572251644125208 0.634700792401563 0.178431300972588 0.326690168697387 0.817156388491858 0.766139760054648 0.260455268390942 0.687544693311211 0.701280488937628 0.610291117208544 0.320143127832562 0.231958525138907 0.95993883601157 0.151629713859875 0.592557113557123 0.212619518269785 0.271170599653851 0.421582548220176 0.998297944234218 0.0523901287163608 0.247020352997351 0.356512110454496 0.788259556570556 0.834751271074638 0.618084535843227 0.624723722783383 0.249151292475872 0.42461661521811 0.582807348517235 0.225486447783187 0.691787466851529 0.980006864608731 0.62773193318164 0.969905178281479 0.836335964270402 0.677302721878514 0.386145376367494 0.628265401567332 0.923277946382295 0.478942653301638 0.770781056692358 0.66118334468687 0.348230354869738 0.781270974879153 0.214867270339746 0.753004104462452 0.394483038450126 0.902821428454481 0.200494688034523 0.649914913615212 0.412837777750101 0.489475394904148 0.284231068380177 0.408898279361892 0.758866419233382 0.103723229716998 0.338016357892193 0.813443350812886 0.63158088932978 0.87004290859215 0.842517359738704 0.589859611550346 0.559047847578768 0.159685495095328 0.0869600986829027 0.133288252416532 0.303889423329383 0.175938142053783 0.223976668769028 0.155050211572088 0.637702620651107 0.553630731245503 0.0711907900008373 0.321200281854253 0.345750760552473 0.943426964511163 0.982031306936406 0.0834486687206663 0.765087133329362 0.0275280862324871 0.930742251244374 0.663799596233293 0.328505033459514 0.741396421664394 0.450032058546785 0.550158985948656 0.632821438387036 0.780968459001742 0.200127637034748 0.903681566596497 0.0783713580109179 0.520039793448523 0.181783376601525 0.905351338665932 0.407245771917514 0.862214259980246 0.415862088736612 0.295528419427574 0.589312965807039 0.476214069668204 0.646384687800892 0.183672499766108 0.934861863006372 0.907158442414366 0.121807106642518 0.401019416046329 0.127673500382807 0.567131895546336 0.0786393093713559 0.172513474093284 0.0122599878255278 0.35251767759677 0.0149931077449583 0.40236989420373 0.35867480186047 0.563546816168819 0.665167789417319 0.751421748099383 0.119384707331192 0.0933005981589667 0.816067829218227 0.42981193782296 0.688629010650329 0.551995931221172 0.59768565663835 0.681419616478961 0.822783236366231 0.21003788909642 0.478350282809697 0.238575848932378 0.329839317444712 0.711138294111006 0.168690934204496 0.255010120898951 0.86384090321837 0.896894240875263 0.149475822802633 0.189499846871477 0.907170089927968 0.172193444878794 0.520871871849522 0.773296920552384 0.663565756222233 0.247989287320524 0.914880034676753 0.91064687631093 0.230668667252176 0.394954444312025 0.239628062366974 0.850374874619301 0.317610551400576 0.268993893705774 0.901855414134916 0.497175369043835 0.846484050718136 0.393941991839092 0.359465912850574 0.881468689548783 0.787437014051247 0.325233912095428 0.2960754123074 0.769760695914738 0.765982968215831 0.224820733752567 0.110870849953499 0.582144504932221 0.0129835293604992 0.221748637787532 0.663721001851372 0.062349164292682 0.723550085003953 0.862046080864966 0.515682328629773 0.323804517774843 0.556692428328097 0.475358026630711 0.147266883638222 0.342294607355725 0.444215530760121 0.508550123467576 0.149878056065645 0.37783206086373 0.145983161262702 0.317475549639203 0.0697641153773293 0.416619453262538 0.0998103375220671 0.564805970913731 0.683480409025215 0.502447326069232 0.151596645764075 0.463216874524951 0.723983898470178 0.377803735814523 0.0970635723252781 0.893923077043146 0.486991170255933 0.109528709296137 0.839194828285836 0.464035918018781 0.314059329819866 0.328647121093236 0.985807910244912 0.621109673872124 0.0132283403608017 0.0247816944494843 0.716007257676683 0.851750758744311 0.698139541924465 0.294245247722138 0.185016382790636 0.928162389562931 0.742089136047289 0.903400905337185 0.469291361165233 0.680586132013705 0.226259617393371 0.578667441024445 0.827979921700899 0.409468163198326 0.107782979100011 0.890070615184959 0.0937206252804026 0.392894213269465 0.799858698565513 0.465320017035119 0.682353270575404 0.550186949339695 0.136612743369769 0.473514780115802 0.925360916480422 0.35878207257716 0.239823139491491 0.426707547558472 0.138935288607609 0.667433168923017 0.669179164427333 0.580705845109187 0.642516634995118 0.233119128148537 0.71277654429432 0.0707611281122081 0.429678859603591 0.187582833385095 0.822205282412469 0.518675056416541 0.0159690569457598 0.433448344999924 0.828166823138017 0.58743617382599 0.291864277056884 0.958875122123863 0.558633292121813 0.382431353752036 0.586781344346236 0.887202085976023 0.671340229408816 0.897837614794262 0.508117929510772 0.245784782099072 0.799271583065856 0.832393774536904 0.483546838141046 0.840789700234309 0.232643043550197 0.521213631671853 0.166053373869509 0.15220224294113 0.047606106644962 0.253592299409211 0.0541050354484469 0.38676366039319 0.971683245650493 0.0925133589166216 0.588132545589469 0.585996223189868 0.145053272191435 0.244164049862884 0.570655847548042 0.0537213753722608 0.540242218968924 0.555931199891493 0.979546420515981 0.158337658955716 0.242483101196121 0.434613331933506 0.604171313808765 0.514987274648156 0.668123993186746 0.185307980002835 0.846346744394396 0.625017241232563 0.0909368487843312 0.382153964934405 0.808234244398773 0.212345559096429 0.0511363525129855 0.044604844970163 0.962513960869983 0.897286478404421 0.56159227805445 0.555968837465625 0.0246426999266259 0.570681709679775 0.0672114545851946 0.809267465593293 0.672337112831883 0.982064900808036 0.400589330263902 0.178863410565536 0.260911400937475 0.782141253279988 0.437949939703103 0.623430303405039 0.660523009428289 0.670627725017257 0.140020729876123 0.384053204385564 0.880635835968424 0.314872760812286 0.395145845846273 0.866863404531032 0.675482452297583 0.351103092590347 0.475069052996114 0.988230183010455 0.778226194363087 0.595914673067164 0.905966559776571 0.679239711158443 0.805799041374121 0.668930347757414 0.954391371067613 0.0101700888271444 0.785880706757307 0.172327067544684 0.091655464945361 0.523350440661889 0.887995566760655 0.541981025566347 0.320257923528552 0.114526941108052 0.952644501498435 0.177252141833305 0.85123304058332 0.491573830787092 0.697669073515572 0.238973831271287 0.445365110917483 0.977822270179167 0.869553071532864 0.195549394311383 0.680786148342304 0.473913660491817 0.60356800759444 0.348987540756352 0.504492083489895 0.127267949038651 0.756887676990591 0.289540142274927 0.604524266363587 0.553481533997692 0.423923174983356 0.0618839981290512 0.0292547923792154 0.754347829362378 0.144109547447879 0.79827382995747 0.900035745243076 0.383302160464227 0.160903694645967 0.458371540906373 0.729445045359898 0.550296629266813 0.125111201365944 0.92590534133371 0.264460420990363 0.514930720208213 0.236738886372186 0.0563756270729937 0.700291016856208 0.0844744204869494 0.871298049369361 0.197122958623804 0.555125300562941 0.311064692090731 0.749684403578285 0.098015467224177 0.132724526450038 0.363559082997963 0.560592646352015 0.102976966183633 0.17347927934723 0.580154131310992 0.206244017935824 0.358145764651708 0.173594083571807 0.963204814177006 0.868249413010199 0.882969557112083 0.442720132556278 0.471860128077678 0.855806069574319 0.87328063477762 0.64860652357107 0.916527047867421 0.323668574872427 0.982364815005567 0.0284190902509727 0.785727012178395 0.598900589279365 0.0375756185711361 0.273765246907715 0.770039782612585 0.816906087386888 0.664775756113231 0.344132533646189 0.735466617422644 0.547748041220475 0.251163257942535 0.489817239090335 0.125382466888987 0.392942917030305 0.838328202886041 0.324310587730724 0.141721779499203 0.343171574012376 0.564953006049618 0.0242538888147101 0.625082011006307 0.920739405932836 0.895494366066996 0.969743131911382 0.493879776629619 0.779014576666523 0.265899779926985 0.256369639819022 0.422995819132775 0.459234463747125 0.600033168045338 0.817305925730616 0.323427055676002 0.26338239636505 0.926161306572612 0.364590686988085 0.409700956498273 0.586098444061354 0.588837324464694 0.913638155621011 0.799229979929514 0.197240563912783 0.604499485518318 0.408182564994786 0.375029212834779 0.979794940068387 0.100552513557486 0.543466355658602 0.36232303242432 0.14263629729161 0.741513286118861 0.2878050631308 0.684257515384816 0.429163642853964 0.285706157253589 0.0612325035571121 0.57060567617882 0.724288554331288 0.584506714320742 0.0484205050556921 0.948174504286144 0.767309631563257 0.019707709888462 0.207641626906116 0.567432737746276 0.398533699125983 0.43364758384414 0.846375513621606 0.304321801688056 0.663626614371315 0.16616051850142 0.818508611551952 0.892437543878332 0.649626308553852 0.248099266439676 0.41137707406655 0.77574012915371 0.62564881878905 0.357150155445561 0.265529197861906 0.285156390739139 0.106505604067352 0.853255512346514 0.924104181318544 0.758088667928241 0.624420831187163 0.493207939304411 0.765816269617062 0.139121479175519 0.860026416159235 0.394222001468297 0.626373018177692 0.758602280381601 0.167667666331399 0.640321946637705 0.727073867125437 0.182134181105066 0.610290345717222 0.322405523255002 0.760459474131931 0.685091265388764 0.563045734975021 0.286365186024923 0.742131347248796 0.122842125985771 0.0717526758671738 0.720001247969922 0.838153169553261 0.252677755339537 0.566624598857015 0.884545122415293 0.854722310742363 0.465983997688163 0.0563438696134835 0.182116836956702 0.0707215107535012 0.618376278732903 0.89769446500577 0.773685285642277 0.255376909587067 0.776918702817056 0.291414744022768 0.251238456564024 0.0924930890020914 0.3219981527864 0.728250664076768 0.80456280755112 0.555515846204944 0.188146151823457 0.989454303244129 0.723346238879021 0.649713698443957 0.102210229893681 0.403911927179433 0.242074888932984 0.581423503763508 0.306421157736331 0.772235654138494 0.11651182139758 0.874668653928675 0.905410419411492 0.53683501156047 0.408928197873756 0.741677171206102 0.156388914056588 0.346591006342787 0.475115505210124 0.8993310500402 0.0938038416951895 0.939345600462984 0.395899676540866 0.50064517719904 0.659800418254454 0.0531145961792208 0.0306454148236662 0.251770849425811 0.297724330830388 0.906305049923249 0.760883476957679 0.475939302123152 0.669565346890595 0.153724774036091 0.490152268705424 0.444439506884664 0.375096104152035 0.255866705847438 0.663501172233373 0.0698761291406117 0.137723380387761 0.756258699500468 0.833079472659156 0.997475625071675 0.18760932686273 0.480953062186018 0.392465129019693 0.0195982699142769 0.771542643790599 0.0812557635293342 0.778007236274425 0.306048959158361 0.0179095523967408 0.242583753499202 0.393266479154117 0.839382753844839 0.013885368371848 0.54814057033509 0.679180245012976 0.195098695626948 0.539894833737053 0.225345370902214 0.693616738931742 0.202783455459867 0.167589230074082 0.200200297133997 0.939396396724042 0.328636782832909 0.909310944464523 0.767367980233394 0.0539828406274319 0.741879692173097 0.757568778435234 0.427491360614076 0.083983083779458 0.407062012918759 0.434398215166293 0.770550224045291 0.0906631662137806 0.808234269062523 0.596323667655233 0.859441761272028 0.712792924712412 0.764822113497648 0.0520850042439997 0.449375321429689 0.971958112542052 0.521483079914469 0.774044989610557 0.641992418281734 0.391452141781338 0.791220979604404 0.162901432125364 0.627108222669922 0.740496031360235 0.910146075407974 0.203931509230752 0.658237575758249 0.849439542696346 0.976247549436521 0.722535951477476 0.483498387932777 0.302645178167149 0.795358694097958 0.288992739331443 0.886204851497896 0.197445482334588 0.116973633752204 0.15299226181116 0.0420601385831833 0.304314035372809 0.157609625160694 0.793851808349136 0.634472595318221 0.205862701837905 0.615661941987928 0.8098685115017 0.560729942994658 0.354722353620455 0.438350332404953 0.375008050184697 0.585458162045106 0.899573380143847 0.759402827676386 0.621838437207043 0.679288975039963 0.82685478447238 0.331348810174968 0.09339845769573 0.198963325242512 0.262172581106424 0.456656057918444 0.0201305343862623 0.111127752875909 0.175646037966944 0.387623477214947 0.623612977429293 0.614166301065125 0.469073667151388 0.728433826304972 0.499260905785486 0.976009482243098 0.163783498185221 0.239269642296713 0.988669520926196 0.851107410124969 0.572491346648894 0.0270758459484205 0.696962558957748 0.0810067354887724 0.798593432742637 0.939022777790669 0.762133218909148 0.848859460975509 0.503781586082186 0.0825844034343027 0.0704148783348501 0.63257813095348 0.225526620191522 0.330193880980369 0.284308236644138 0.617664462621324 0.98354780463269 0.23790239025373 0.703941037270706 0.268873982701916 0.36396426069783 0.40853720713174 0.143050602192525 0.323683830439113 0.707221801239066 0.802218396400567 0.108997146934271 0.251987304950599 0.835201619856525 0.403820066004992 0.0779788819118403 0.789574612281285 0.64617113038199 0.782592276281212 0.455613623315003 0.26119772241218 0.638230717179831 0.188705904390663 0.59039252188988 0.885074452592526 0.542478559559677 0.0457812184887007 0.577217111790087 0.256070008678362 0.45366819165647 0.586932591912337 0.625839853363577 0.329509609898087 0.501921965833753 0.652843540546019 0.699488427080214 0.819821485097054 0.800366864709649 0.400448294873349 0.370118885394186 0.043816503926646 0.247544350503013 0.573605059951078 0.786236418194603 0.372095369636081 0.862539154868573 0.406662974418141 0.282578183833975 0.921411934534553 0.534435430828016 0.666566291584168 0.47160102316644 0.532342946054414 0.368578321870882 0.769900384249631 0.99946506930748 0.777231865136419 0.241258698366582 0.630224050229881 0.282306028802414 0.441945017967373 0.471873959370423 0.0137063639448024 0.126656847926788 0.490918612219393 0.608498852739576 0.0843104611779563 0.935330902070273 0.202524056197144 0.911712189193349 0.878207224158104 0.8776775219501 0.270435098044109 0.633992062716279 0.229507962591015 0.854793916062918 0.288029080515262 0.700434373866301 0.419758744346909 0.257784858476371 0.55707988408627 0.558790467516519 0.201022503119893 0.320208016776014 0.596391389011405 0.542381164715625 0.974255998870358 0.606682615797035 0.422686479464173 0.564622019215021 0.866284703749698 0.757603922896087 0.80289790207753 0.373771049019415 0.319600858867634 0.325502900716383 0.69472813015338 0.265935475288425 0.550967674585991 0.572440544625279 0.878474220316857 0.471649520627689 0.914259893263225 0.771138543458656 0.582194998082705 0.824487509794999 0.585544327045791 0.0896947874012403 0.0593435795465484 0.716485144342296 0.674463265929371 0.794727433712687 0.157336152808275 0.540522069551516 0.759407624891028 0.194547002573963 0.749225663358811 0.653451198413968 0.0904054016736336 0.542258395021781 0.135362836839631 0.961655593677424 0.178707292024046 0.307920338944532 0.578535829491448 0.624855107041076 0.241102750396822 0.907882164893672 0.806109852339141 0.124661068334244 0.795396428944077 0.887878900999203 0.0633958034892566 0.821679742385168 0.155298800044693 0.517640979827847 0.0429440866946243 0.712244873596355 0.689885216348339 0.386776382047683 0.137638829133939 0.44128741923254 0.851594257338438 0.204124310605694 0.386896160743199 0.496473119931761 0.357840129155666 0.66591288292082 0.173871125944424 0.664653134401888 0.793403487757314 0.507192144994624 0.160382990096696 0.674691244035494 0.894736452945508 0.608266485407948 0.0416552838170901 0.0603967880597338 0.27850313693285 0.681496151322499 0.0946611405094154 0.402682854833547 0.222831269924063 0.418662619525567 0.597005006517284 0.509084077982698 0.393070317285601 0.624867321129423 0.847250462230295 0.745724992554169 0.592922533983365 0.593735950915143 0.782056496879086 0.547588184622582 0.440985131091438 0.987024077225942 0.222272860263474 0.252030061290134 0.157214642118197 0.711766168186441 0.990352139812894 0.411031399853528 0.690090601998381 0.386596691876184 0.938083144463599 0.794402855765075 0.529562080341857 0.737981173873413 0.175509782503359 0.72148448763648 0.717378977315966 0.174326342013665 0.242990496770944 0.616984552182257 0.580852960920893 0.705732878537383 0.0386547862575389 0.0219199567614123 0.290441668955609 0.561607066853903 0.635935278786346 0.0255623108986765 0.844547924438957 0.26131518087117 0.371359679475427 0.545897285861429 0.0129414389422163 0.831858588447794 0.550941026441287 0.459422143360134 0.129136959030293 0.188785094621126 0.607827676725574 0.28797476102598 0.209985620616935 0.643208380807191 0.680872457867954 0.475870248693973 0.507147498535924 0.851176267166156 0.262988513049204 0.617530112951063 0.382433463539928 0.0993587896670215 0.14640010564588 0.938018224863336 0.9633809041325 0.606045630886219 0.568693157718517 0.980582491180394 0.209083717986941 0.437441101414151 0.850398324083071 0.390142972639296 0.860498337193858 0.563500624191947 0.0548384374123998 0.0732219549291767 0.402367557601538 0.0760584408557042 0.0847564762854017 0.281118368506432 0.749439251895528 0.0361055910680443 0.725626942641102 0.0149859995138831 0.730604297164828 0.513966711719986 0.881476026207674 0.0103635141719133 0.839191312894691 0.938551908538211 0.115707358329091 0.620983726012055 0.169090247924905 0.259425366430078 0.225332151823677 0.793277199445292 0.734630960011855 0.0350760138849728 0.668257234832272 0.702081188594457 0.690274150318 0.747262026856188 0.0188708347338252 0.503386124977842 0.225978839730378 0.673791386422236 0.496170756416395 0.42455734891817 0.983614572170191 0.948466421896592 0.759367409609258 0.286707807234488 0.943039372065105 0.452055309868883 0.54376893838169 0.98298481489066 0.160441178106703 0.518803015179001 0.579599626359996 0.403492086534388 0.858206071665045 0.333028516203631 0.172804262933787 0.259227635071147 0.579436673885211 0.764578666149173 0.474369291234761 0.9006660640263 0.89944354578387 0.175045008654706 0.88676794819301 0.446784704278689 0.861616583555005 0.997363074929453 0.737905576482881 0.320215544060338 0.509763137637638 0.8999472141359 0.998012568280101 0.320488495707978 0.524986177908722 0.780726109535899 0.249511309696827 0.215548292261083 0.717122828136198 0.222212950862013 0.611525984844193 0.541265628139954 0.158899399375077 0.810337803887669 0.268815703643486 0.751939289234579 0.828155219650362 0.109781654032413 0.994561596314888 0.474303927686997 0.676304876108188 0.49575572059257 0.87211012016749 0.605465248590335 0.74474593595136 0.386476306959521 0.147741223103367 0.517978624722455 0.924188990965486 0.478006531908177 0.346744896387681 0.264423678456806 0.645531189048197 0.492440738091245 0.436100997014437 0.0290938272955827 0.559189464757219 0.822438350471202 0.250845251155552 0.371936337775551 0.107558402977884 0.964604041965213 0.979520681241993 0.19063350853743 0.844864550055936 0.675933837878983 0.49072941935854 0.282010164069943 0.746942012163345 0.788300531818531 0.0100196597748436 0.0924190373602323 0.131210962587502 0.531454406336416 0.416224232802633 0.901830725260079 0.611327908653766 0.339921739539132 0.44472786208149 0.558351867208257 0.241018678126857 0.449359167595394 0.0718823555600829 0.199239946948364 0.0711080509563908 0.467988744513132 0.688611196738202 0.793853442610707 0.836864690070506 0.952018772016745 0.989223445933312 0.403787576931063 0.406915270290338 0.848277344149537 0.179581053776201 0.56579580004327 0.488880345514044 0.792490230351687 0.181650209638756 0.443486442647409 0.554782068291679 0.16260972104501 0.483182759699412 0.3182226941525 0.768912002213765 0.11707306554541 0.966170963891782 0.55309977279976 0.505663124797866 0.42452396319015 0.752289227279834 0.371473087086342 0.0703048173873685 0.095941008424852 0.311153567798901 0.679552040903363 0.0746713644592091 0.821544750535395 0.538755489957985 0.803413457665592 0.0414945916482247 0.136086001733784 0.316230245549232 0.10544783368241 0.0169230312062427 0.0870214325888082 0.647754640870262 0.621847320536617 0.0702332494081929 0.0113141675852239 0.0269317995058373 0.387025871784426 0.280172317302786 0.293931383062154 0.248451934093609 0.496541533025447 0.698887761500664 0.180337215079926 0.65514433281729 0.388230226903688 0.83438079665415 0.650422045495361 0.515520240077749 0.629183628372848 0.643732662061229 0.907880464247428 0.763673519429285 0.595612341822125 0.881507633379661 0.459584497911856 0.884207476829179 0.847301163063385 0.481058224497829 0.746798220195342 0.385396802739706 0.224460398207884 0.507503751653712 0.0924183767405339 0.06899848688161 0.256302708855364 0.367413969510235 0.789723993008956 0.866024546364788 0.495548499913421 0.919405500662979 0.747974518109113 0.799450364366639 0.614882611511275 0.59548420995241 0.765620799025055 0.586780459908769 0.595394160987344 0.280036291419528 0.649474270595238 0.841830207607709 0.954303200466093 0.808429786907509 0.584293977951165 0.0923711657128297 0.397551127823535 0.0373695232043974 0.807259221586864 0.319657484071795 0.530873186164536 0.498179987433832 0.0429033765243366 0.852686049176846 0.448912368088495 0.30639634807827 0.851641183695756 0.930752483704127 0.668401619652286 0.690942636139225 0.853835233561695 0.760422582924366 0.123675473302137 0.36355782330269 0.801370971384458 0.948958469242789 0.81414302890189 0.407784371054731 0.137018298632465 0.642725198580883 0.83154448406538 0.788310575957876 0.898058454704005 0.96808142650174 0.936549998505507 0.539846324750688 0.8543491857755 0.092977389395237 0.968270894121379 0.0968639902630821 0.98415116662858 0.359050466502085 0.378738773385994 0.57079691613093 0.170444649462588 0.0598652775608934 0.761440405410249 0.974640202701557 0.895686757608782 0.563730918616056 0.584661474281456 0.395573052193504 0.783716729378793 0.268150205824059 0.619414901519194 0.432859416599385 0.23395664294716 0.325625266800635 0.162388297272846 0.248386802431196 0.636803379631601 0.97001617714297 0.234981981653254 0.276493302460294 0.638298257361166 0.228309573794249 0.216617986531928 0.326848799944855 0.431889709401876 0.785244151272345 0.0420776046672836 0.595921974459197 0.951574657170568 0.916104091522284 0.390607202963438 0.215603861764539 0.454908742096741 0.525604015912395 0.354018514272757 0.689571645578835 0.300162952896208 0.187343012760393 0.363903226675466 0.409440407489892 0.423559927272145 0.861080734541174 0.688304427631665 0.484194866188336 0.475171252661385 0.935528644723818 0.14621347527951 0.159628689868841 0.0988458959199488 0.500844630410429 0.549469688993413 0.779279237145092 0.777800688201096 0.0216807886888273 0.782077824338339 0.935339818361681 0.911052586701699 0.286388429419603 0.755714602191001 0.981636118977331 0.909615381578915 0.631011795655359 0.657101059320848 0.379847650288139 0.885657066381536 0.826204498885199 0.223327323400881 0.419032872894313 0.0949514035740867 0.528207875192165 0.206857484923676 0.167464697498363 0.478069987127092 0.992890258443076 0.901568923471496 0.78843665151624 0.14985313069541 0.306286717017647 0.813414167372975 0.933350466787815 0.450911834796425 0.805757516378071 0.649164511412382 0.752756860970985 0.250302583191078 0.165177890956402 0.787554621645249 0.744153775216546 0.585825032792054 0.133459668937139 0.422750979780685 0.112924833230209 0.390319674808998 0.901274126195349 0.98860018766718 0.865802399967797 0.944262357766274 0.420315256051254 0.480271701426245 0.474770860881545 0.227517900147941 0.20712731464766 0.0943325776373967 0.397349959674757 0.403654047157615 0.446244298925158 0.87853905509226 0.34900792776607 0.830572248718236 0.773794331687968 0.173142077939119 0.142440493162721 0.913663309419062 0.543452317374758 0.457190107861534 0.664190231771208 0.431823629222345 0.376724431670737 0.103485369053669 0.431871317620389 0.756168671972118 0.0521111870044842 0.475462011306081 0.990943093176465 0.884688132288866 0.279744424750097 0.940573316302616 0.472483735324349 0.960632981122471 0.2365415341896 0.690246752349194 0.223287459635176 0.102961919913068 0.144242457861546 0.921029046871699 0.779713766782079 0.0119263891689479 0.402672024220228 0.0315893373382278 0.564321480817161 0.595182799333707 0.809232931963634 0.720005268852692 0.161036740364507 0.491819140594453 0.99350544659188 0.740545996660367 0.435350089550484 0.0238675065059215 0.417140491579194 0.648688489971682 0.503895049013663 0.934800076393876 0.957620307507459 0.911639698974323 0.762915222060401 0.733533791706432 0.135466478527524 0.672662828078028 0.70540777389193 0.482256155977957 0.352600149028003 0.243908399029169 0.442466741336975 0.894207282736897 0.546015426837839 0.291067035857122 0.0531604029866867 0.0152628708537668 0.854402455096133 0.817637212679256 0.248671772931702 0.835255175922066 0.936358132739551 0.797907480837312 0.458082239036448 0.772849644136149 0.705203614514321 0.568541702930816 0.193459676487837 0.157360385518987 0.199816256037448 0.435338153908961 0.909588528287131 0.459982791889925 0.56169228333747 0.708621282810345 0.828830047973897 0.147693664017133 0.853796392995864 0.430035822438076 0.240606591349933 0.426875466436613 0.114946633309592 0.378022089987062 0.70543952443637 0.347041754354723 0.041253797612153 0.736352079473436 0.0878361011482775 0.564235633218195 0.618327786342707 0.616001293752342 0.906127424130682 0.989675483375322 0.525628727376461 0.432777122654952 0.429815090172924 0.0798070339811966 0.0912983963103034 0.468332632794045 0.395271603772417 0.638906102858018 0.0301027521607466 0.864386880735401 0.221361110343132 0.294111581260804 0.716620805570856 0.568795671327971 0.0926925989170559 0.941553260569926 0.635239424500614 0.174112882327754 0.114045769784134 0.20309250630904 0.125541389491409 0.530461377834436 0.381181172693614 0.865313877232838 0.279759900216013 0.651505536483601 0.971987234668341 0.329638322633691 0.346226614417974 0.153731790527236 0.618010816585738 0.331959007256664 0.0735053603188135 0.0510516152437776 0.906403576533776 0.520005904994905 0.141256510070525 0.557429130394012 0.217790933633223 0.761697977250442 0.39927078797482 0.42389995072037 0.762801313798409 0.681771702344995 0.719775088757742 0.998658722804394 0.486211175471544 0.477741672967095 0.6822566200234 0.86162727171788 0.16303180885734 0.207602555146441 0.799875352359377 0.0610507054417394 0.0992225272883661 0.780137341334485 0.993897103485651 0.381445075511001 0.812765750929248 0.872549473296385 0.0558326739771292 0.812584320004098 0.923084140017163 0.0124674687418155 0.815723378972616 0.896607142838184 0.381274900706485 0.144349310908001 0.662816727813333 0.452052268621046 0.789675258360803 0.450565775875002 0.155955889369361 0.265122676333413 0.496117917674128 0.586846661563031 0.0982335475599393 0.537221511194948 0.559398769638501 0.235285580661148 0.0787247930071317 0.52061157224467 0.401640194337815 0.867205304498784 0.590223944927566 0.016091558104381 0.823747853841633 0.289471521037631 0.586221743219066 0.529978165412322 0.724768591122702 0.801891696909443 0.0764547101012431 0.849241933503654 0.349408898106776 0.517957143979147 0.426577134637628 0.315788153130561 0.194291260691825 0.929284462723881 0.595502340574749 0.599167396656703 0.28938902517315 0.10435917575378 0.453128429634962 0.0400666736951098 0.12023651212221 0.402754889810458 0.315273788317572 0.217355436347425 0.0209464764711447 0.661842493549921 0.270835326397792 0.720882813839708 0.50030881620245 0.149504424454644 0.681944245791528 0.341488992697559 0.104998493809253 0.685042948871851 0.910375629919581 0.320698212957941 0.172802674081177 0.835001654468942 0.293946268903092 0.819342785449699 0.7272057810775 0.556659903065301 0.781177921316121 0.501443828842603 0.58741744343657 0.218025264614262 0.697249906167854 0.459613678124733 0.46447871346958 0.253631521917414 0.0948217188101262 0.245932578353677 0.145593199944124 0.972418004812207 0.828485366073437 0.313238743804395 0.214666167192627 0.651455816898961 0.531125350189395 0.69233312973287 0.848393516174983 0.581567225889303 0.322122065541334 0.0931400394509546 0.594649140553083 0.223134719105437 0.671874548348133 0.189542335367296 0.946533584885765 0.165013785508927 0.884890161594376 0.714679214081261 0.501540731333662 0.817423740315717 0.896332556928974 0.464358504887205 0.163673447379842 0.941164835088421 0.626793268194888 0.600648190232459 0.461649123250972 0.752267195635941 0.879521037000231 0.306818220831919 0.706654955192935 0.172381359373685 0.684582356105093 0.41649167913245 0.350431405552663 0.429178419667296 0.352165138793644 0.764121553967707 0.0160238512698561 0.0660751059534959 0.566821545355488 0.313079870990478 0.675106895992067 0.418339402002748 0.258324896870181 0.281645157856401 0.362759376345202 0.649369818922132 0.262407226723153 0.947820557574742 0.790592995579354 0.770200651807245 0.350191411820706 0.258157336653676 0.676172732575797 0.388534463020042 0.361349480447825 0.747248193719424 0.325550166834146 0.0817063342849724 0.828649538827594 0.893460510715377 0.0738893348001875 0.424805117954966 0.214481328290422 0.165178307704628 0.935730460123159 0.629801138141193 0.649539858652279 0.86798782074824 0.7722939603962 0.909741036470514 0.939565461198799 0.406218062264379 0.71405789480079 0.83223839729093 0.608931984840892 0.628816188976634 0.307132976383436 0.0158853219007142 0.080226877622772 0.0977630611718632 0.177527840838302 0.6702775403345 0.186649537719786 0.414941410999745 0.350318264863454 0.0862206294364296 0.698578526941128 0.0963858380587772 0.123101128323469 0.857022658605128 0.675352453589439 0.797985204611905 0.256493795753922 0.319755720249377 0.53184132571565 0.128359787208028 0.78547775801504 0.953138140232768 0.904383792888839 0.175786995908711 0.16247611704981 0.869390112834517 0.616535217610653 0.788110612183809 0.433645299104974 0.755167971891351 0.900299661660101 0.818116197688505 0.63643475107383 0.129704675914254 0.130075631854124 0.401927077316213 0.649982147228438 0.846646838614251 0.92125150098931 0.629419005603995 0.932647782487329 0.461995408295188 0.64042212203145 0.988543594502844 0.991918432929087 0.765314482394606 0.555907104329672 0.488944185902365 0.577515378356911 0.124865985603537 0.338184769123327 0.449812712292187 0.289936732610222 0.279787283893675 0.996114819948561 0.950542057640851 0.663336939087603 0.506332439505495 0.998521939720958 0.711828351032455 0.695083170137368 0.255121069971938 0.300666276877746 0.0277072215848602 0.458077672785148 0.773783576909918 0.341524348529056 0.562800889860373 0.640666324505582 0.861790684505831 0.994170193434693 0.166618919651955 0.22417772973422 0.350023496861104 0.19506206050748 0.141532937232405 0.789519226949196 0.38095100896433 0.148259805187117 0.226459828726947 0.200493842090946 0.420323419983033 0.0651396018452942 0.768540034829639 0.368707674941979 0.139204298434779 0.143727758820169 0.989327691998333 0.98150992447976 0.700862090776209 0.967574580444489 0.443223741208203 0.515359539380297 0.17631739285076 0.519494412932545 0.736881534813438 0.682589629285503 0.162381134643219 0.333385961479507 0.934503155038692 0.629797653406858 0.339375060833991 0.206510631460696 0.930595510229468 0.952317293980159 0.51800618335139 0.382493016354274 0.674623142580967 0.133355362480506 0.56181448553456 0.163561586670112 0.115007476245519 0.558569202099461 0.336576590044424 0.251078082949389 0.0196126906014979 0.214357572738081 0.321022469585296 0.929399010860361 0.677498558047228 0.631000370576512 0.643797458573245 0.842800716261845 0.613982969417702 0.306495653325692 0.0718631865247153 0.665145037223119 0.345136699790601 0.8382314303983 0.0464050456346013 0.775644991158042 0.882631865886506 0.86448787602596 0.438486090213992 0.864351276191883 0.437414398640394 0.369612978864461 0.597796916889492 0.581009114729241 0.642780917910859 0.125388041588012 0.0570572148775682 0.607436236042995 0.538573623383418 0.223219779077917 0.494459143101703 0.808601553791668 0.50272576689953 0.439540611437988 0.498633658906911 0.526902033120859 0.5699305041763 0.762053359299898 0.823480087113567 0.870555385129992 0.744237663776148 0.38198514041258 0.237105497573502 0.267767877820879 0.455603334612679 0.817780852746218 0.296047873040661 0.233323643421754 0.543885332380887 0.79627453773981 0.858305209337268 0.308141292030923 0.127321219511796 0.738203172518406 0.0148474991880357 0.277729600362945 0.826703792072367 0.535640125016216 0.981510754288174 0.731573839322664 0.733101605356205 0.0284861247101799 0.304045334649272 0.524063305098098 0.538225083795842 0.939493436363991 0.969700507419184 0.506374724928755 0.272204700906295 0.652464927088004 0.76411065351218 0.078324817053508 0.484087403924204 0.557518641597126 0.493587152990513 0.375355066843331 0.539451105673797 0.283160742532928 0.867002880803775 0.252303537791595 0.941729334390257 0.838025486241095 0.508664246788248 0.0182206528726965 0.572222540124785 0.654293271857314 0.118093863816466 0.228696713303216 0.768094523139298 0.831338422351982 0.0642745922668837 0.0488087530503981 0.566512873221654 0.656801931597292 0.53515255425591 0.664195827676449 0.552343305388931 0.0571334987040609 0.569054052000865 0.990711694646161 0.399545363280922 0.412704525040463 0.587224998187739 0.223608907591552 0.927169881304726 0.397649167843629 0.176440940720495 0.613988046001177 0.324592271267902 0.65714387743501 0.561410089929122 0.0568459576414898 0.357016601930372 0.56125359244179 0.0915605788887478 0.0613821772532538 0.566536355647258 0.360245743286796 0.798948478950188 0.675746116545051 0.721466737112496 0.835551490134094 0.185810772445984 0.140151340567973 0.558458152296953 0.874432939472608 0.165454797563143 0.113011051246431 0.405759338180069 0.422055198103189 0.348328074952587 0.513861460664775 0.923100708986167 0.850775266399141 0.661461638687178 0.80983305378817 0.724931773638818 0.0162202171329409 0.638617625494953 0.486179515745025 0.780146751592401 0.939746444718912 0.369438301888295 0.897621648856439 0.67601700888481 0.529829848683439 0.549496003601234 0.315384184415452 0.150945837858599 0.736535413656384 0.703713671378791 0.135564406062476 0.518367526421789 0.205282021733001 0.35848383505363 0.78719901047647 0.938305770305451 0.584785358684603 0.462466762985568 0.216317142257467 0.141797596097458 0.86938529741019 0.95353010392515 0.693364898532163 0.0375706768315285 0.336711749238893 0.440215566307306 0.480102140449453 0.129221757613122 0.88939355859533 0.387596375211142 0.642915347334929 0.604814013333525 0.597116164886393 0.775581261871848 0.0527650732686743 0.104136537695304 0.0688091259845532 0.0573388172779232 0.136868265352678 0.404877582376357 0.549088806931395 0.94292754846625 0.447808565464802 0.125326450672001 0.143670681370422 0.921902170593385 0.703622170940507 0.574099495301489 0.134991696497891 0.181286118980497 0.550186537662521 0.845246500726789 0.663411104367115 0.207911629737355 0.0736350780446082 0.683606608132832 0.206533307589125 0.963784449414816 0.984422803721391 0.113357258611359 0.667825766496826 0.461990514961071 0.87437923772959 0.218787399616558 0.764645572910085 0.834214587872848 0.257306175194681 0.0196411903714761 0.49100896590855 0.683194494156633 0.741774051799439 0.14041461226996 0.955693817378487 0.464143150702585 0.993322717016563 0.771405163437594 0.0801102035632357 0.179524156118277 0.0966290705790743 0.813539577932097 0.612621193188243 0.960241131989751 0.310189967299812 0.0225675157364458 0.95086768160807 0.749943766652141 0.949444568476174 0.731596651908476 0.101570609419141 0.615622034887783 0.327558491516393 0.86253913481487 0.986512019049842 0.263943836439867 0.609757159005385 0.785439008497633 0.893665030368138 0.421439067199826 0.669751088900957 0.86089897077065 0.587937851790339 0.141624027607031 0.309506918340921 0.649912425342482 0.291932268331293 0.828833337703254 0.480358171381522 0.469607290665153 0.702394234279636 0.334083950447384 0.530506636737846 0.0352168761682697 0.790404068487696 0.150970649821684 0.590214163791388 0.151649331683293 0.107996775319334 0.603231128428597 0.417633013299201 0.37714148208499 0.470562692657113 0.989924831353128 0.707968114330433 0.670220986355562 0.122055732687004 0.932065363242291 0.687302339004818 0.0963821728411131 0.130035682111047 0.865605899952352 0.744323688631412 0.670996990913991 0.612185230287723 0.803135646337178 0.62707527466584 0.624689000602812 0.284735378220212 0.383073170452844 0.92391636617016 0.809202672769316 0.485972877084278 0.399673986120615 0.52204797614133 0.155016274251975 0.123105454160832 0.738528719728347 0.814752858793363 0.553757685939781 0.209919750425033 0.110026560691185 0.636396770051215 0.381782457632944 0.666139611012768 0.792085440126248 0.23812035787385 0.305436351022217 0.911015126383863 0.964831100136507 0.537066705364268 0.861436489082407 0.396647596003022 0.726725323158316 0.939128386355005 0.337903057695366 0.100845696856268 0.659820591358002 0.142969095413573 0.550564209979493 0.26948255912168 0.860634237683844 0.453377185452264 0.790786200102884 0.804025194041897 0.799989522472024 0.173633805578575 0.62707191855181 0.722525623128749 0.238359859252814 0.031684322510846 0.251215636371635 0.994383421465755 0.965832556956448 0.292408040137962 0.75114241222851 0.458069073664956 0.855215441449545 0.716614135985728 0.101638391166925 0.526181029186118 0.919383172362577 0.545741250531282 0.607977057453245 0.521589737725444 0.593507379265502 0.344965368325356 0.225955356152263 0.890697243164759 0.873669222532772 0.551905109381769 0.313587508823257 0.796775603028946 0.271860863796901 0.270608205299359 0.759730417598039 0.807694457944017 0.498208482824266 0.895338416253217 0.459497459307313 0.28279190329602 0.680359898579773 0.741117324593943 0.533057174372952 0.661574217872694 0.34796196071431 0.903500805280637 0.414523044417147 0.72327227874659 0.502777293622494 0.255587914423086 0.558302744855173 0.970736827026121 0.0861841662717052 0.87735281607369 0.426045013999101 0.14378096383065 0.314127760431729 0.307061105985194 0.122733468106017 0.564627813582774 0.245639155332465 0.427395716204774 0.609130662411917 0.123316607209854 0.189657391991932 0.0759491228172555 0.117028426693287 0.725553096376825 0.37005127905868 0.713192473775707 0.832301079635508 0.645354487800505 0.109059603386559 0.039834501137957 0.750657274420373 0.1676886434271 0.314339067917317 0.612031958219595 0.720106315545272 0.464634526134469 0.170371273653582 0.479752719651442 0.797993583371863 0.558310326538049 0.244388435359579 0.171596322120167 0.451367712637875 0.320211039353162 0.363112954944372 0.564346989127807 0.0870364039461128 0.839997765428852 0.228920079518575 0.686681403049733 0.291417686846107 0.534017426364589 0.0733650895045139 0.389387299309019 0.396894854246639 0.161505518499762 0.396858506102581 0.364289737835061 0.535567257464863 0.751102089071646 0.586430180489551 0.586226049924735 0.0463927250541747 0.20878380471142 0.358223528303206 0.768068595314398 0.220415491792373 0.493075632806867 0.540890715166461 0.937670206441544 0.812568569779396 0.586574735650793 0.170458055248018 0.587458037203178 0.121900287903845 0.961056516028475 0.381637103781104 0.732134134492371 0.158817540619057 0.997228909661062 0.299902297626249 0.396868967451155 0.71721838172758 0.176068350980058 0.793688497904222 0.659143224281725 0.253474142297637 0.153333044303581 0.671722156798933 0.251277804004494 0.209401016901247 0.323130980264395 0.906180391262751 0.135448086515535 0.0207482801890001 0.097871595271863 0.339587670888286 0.097010316834785 0.68213379155146 0.946391033250839 0.533289672399405 0.753536822102033 0.979175834071357 0.809769125808962 0.156219187579118 0.850952148591168 0.573399340994656 0.466365256160498 0.132440725979395 0.638746220443863 0.742473598732613 0.0565886112325825 0.131323848341126 0.152591521281283 0.983743147756904 0.543502816287801 0.465068411056418 0.0389117684727535 0.353795999533031 0.686555624608882 0.706120433642063 0.969672599579208 0.698369332009461 0.643933945922181 0.30489496280672 0.733648128933273 0.201930756089278 0.0700023844907992 0.459693610342219 0.452618534262292 0.13068442148855 0.335158507626038 0.20473235179903 0.734354610068258 0.33319783722749 0.599255468142219 0.817040436135139 0.0989754988555796 0.209019769493025 0.632006503597368 0.441322275795974 0.0950456200214103 0.624338311811443 0.0214377555530518 0.0516978414542973 0.643474805781152 0.720675281982403 0.563599290717393 0.0687905062362552 0.879924711594358 0.59241016670363 0.200883213784546 0.398038899120875 0.248812738249544 0.149475473822095 0.997378745861351 0.674280285106506 0.065415650291834 0.135563462846912 0.196072176839225 0.949940193218645 0.131724319644272 0.0691222313698381 0.613937545244116 0.86183891965542 0.359432045142166 0.926859511982184 0.462881145796273 0.0371389201376587 0.0156446564849466 0.339821928800084 0.0960732655948959 0.141262548540253 0.429394661285914 0.475131182365585 0.462913336830679 0.294567873084452 0.648487719669938 0.893989788799081 0.936716849235818 0.712528786091134 0.972906981406268 0.919690290449653 0.657202586610802 0.487376686567441 0.907605414567515 0.361976329709869 0.311786507854704 0.0193166317860596 0.246603574806359 0.349034480482806 0.948988285411615 0.395521597617772 0.609666885300539 0.97083660434233 0.345071780651342 0.0222540496150032 0.40693391908193 0.283323139266577 0.703021554457955 0.352214890879113 0.713636817510705 0.299776051035151 0.535111085271928 0.98703120942926 0.953331849786919 0.630609629468527 0.328008046217728 0.543408776405267 0.013740242025815 0.827969104226213 0.724990839171223 0.443927329077851 0.688893963866867 0.55011966155842 0.577642767548095 0.401399207371287 0.980420184342656 0.172196149823722 0.155343062717002 0.34953460970195 0.40049488031771 0.6617086705775 0.0157812099880539 0.677379490681924 0.716182635379955 0.175041977087967 0.21894371754257 0.180096889885608 0.27893230877351 0.969169657540042 0.440904652122408 0.0309596448298544 0.314911607140675 0.759874914442189 0.435531413753051 0.639750195501838 0.881936179636978 0.83593047654489 0.537374271547888 0.214627845257055 0.758006655657664 0.0932520868675783 0.902718189454172 0.306211357966531 0.959587885139044 0.0907434582454152 0.0224141927273013 0.509340403496753 0.874636724283919 0.249721209965646 0.589844268853776 0.536825548517518 0.684562373626977 0.711496569425799 0.436777469741646 0.705367013933137 0.560428887349553 0.0662001237366348 0.847793788048439 0.547554480109829 0.122430149388965 0.462273330264725 0.454934958510567 0.262074535323773 0.528128098333254 0.0338917170790955 0.594690055870451 0.942295020548627 0.238058543831576 0.880751896891743 0.513560200564098 0.615583493283484 0.65248593138298 0.357555570332333 0.254391320317518 0.635318387455773 0.700802652982529 0.90039687970886 0.198751033972949 0.668366043230053 0.501114087873138 0.82126098832814 0.525156418175902 0.115776524473913 0.993184517726768 0.405541561415885 0.645212887218222 0.592001868924126 0.849957796544768 0.761697523852345 0.168042272967286 0.36711755894823 0.911505260560662 0.0134590222593397 0.150936890679877 0.655387011901476 0.961667864238843 0.488453684074339 0.804176122823264 0.507215242481325 0.251414566803724 0.614397863021586 0.797001901464537 0.187582138190046 0.0621693053934723 0.954136910086963 0.740327839106321 0.919480168668088 0.51361982506467 0.424813619342167 0.0129952646954916 0.323423626031727 0.336798534060363 0.471231730531435 0.344472120061982 0.8140460740868 0.202972066993825 0.506120865559205 0.896101774992421 0.763608490801416 0.631068070034962 0.453705042295624 0.289192639947869 0.481252002050169 0.850945827525575 0.0601123839034699 0.245061685664114 0.935768601805903 0.54870146434987 0.75927332293475 0.310838237374555 0.776783654263709 0.625886674842332 0.401594816725701 0.410031951630954 0.374186973429751 0.7006818769034 0.174797247224487 0.666593396584503 0.154861926429439 0.263272049594671 0.516362747095991 0.511664705623407 0.0990125219104812 0.232418659897521 0.251438437164761 0.934852532732766 0.470367273928132 0.647777432019357 0.139416082368698 0.557813368800562 0.737771672373638 0.913654077108949 0.541561599134002 0.985485295716207 0.499476566538215 0.177938482365571 0.0802661289437674 0.14767871248303 0.609779064103495 0.427140236634295 0.350311031700112 0.458090909381863 0.981065642980393 0.351450426650699 0.272060819272883 0.083459529990796 0.278319794912823 0.531775743882172 0.732419589969795 0.350786159944255 0.347073147159535 0.840073564969935 0.557330315425061 0.771659495106433 0.915435688912403 0.883657974700909 0.26684551142389 0.595056623506825 0.580283484843094 0.883651963660959 0.567756047931034 0.677279798882082 0.731202447502874 0.387367960994598 0.0202840109099634 0.599812885259744 0.823769322829321 0.145952788200229 0.488362389013637 0.952337844185531 0.515165586185176 0.228766966727562 0.75533272966044 0.632217537246179 0.673998818241525 0.140422697139438 0.368690037594642 0.235135111270938 0.418310855440795 0.475351252628025 0.697971487971954 0.135943382792175 0.106002549543045 0.852609952518251 0.716111314268783 0.969847828838974 0.975998355895281 0.121922807290684 0.585081309624948 0.748573937132023 0.263609593759757 0.59831519194413 0.627274982812814 0.89017995903967 0.712742127759848 0.0893219371931627 0.981965537474025 0.832193904577289 0.140491170394234 0.0197636733204126 0.100406774997246 0.229113048699219 0.0217550489353016 0.0304231146816164 0.766209577599075 0.235569648053497 0.896095325537026 0.981194028633181 0.671638522944413 0.01414164617192 0.0340020184405148 0.827778751708101 0.059924635370262 0.782385349031538 0.652480045966804 0.848256327176932 0.262763813147321 0.196121758352965 0.678617671097163 0.50721299047349 0.297686158951838 0.306241061419714 0.477697054399177 0.9976858810056 0.577857443133835 0.725666378133465 0.805993498216849 0.707607586777303 0.149469086832833 0.609330924917012 0.624532813371625 0.86804833752336 0.665244233442936 0.781884749126621 0.378272852557711 0.541426187078468 0.198208341575228 0.762319576821756 0.0500255557568744 0.305584322919603 0.826422278876416 0.732502956672106 0.0968068298324943 0.335074765896425 0.65067624992691 0.611804115187842 0.582404232199769 0.156224364431109 0.810365486757364 0.171059974760283 0.0325291580636986 0.126854440984316 0.101098831065465 0.484134658747353 0.798385679833591 0.719164029366802 0.0398211914720014 0.344479640200734 0.0911057830252685 0.762960370322689 0.121263724120799 0.36126922391355 0.972705260282382 0.199717066963203 0.614541473353747 0.103100075637922 0.582099105652887 0.451082001302857 0.194129079477862 0.769660722671542 0.832133766978513 0.805824334856588 0.325272921388969 0.827881292977836 0.258438058535103 0.655422202232294 0.887582058014814 0.0710832318477333 0.445040101238992 0.578328179847449 0.741765513762366 0.748372588269413 0.586695077694021 0.217267437009141 0.854227175586857 0.0861218635644764 0.0661207069223747 0.391001822964754 0.727510159413796 0.753943934177514 0.679156335005537 0.22751246006228 0.931471506932285 0.812320705314633 0.343228604900651 0.974877845770679 0.539803437716328 0.965393467291724 0.914400320819113 0.937355962374713 0.393256080732681 0.270414706424344 0.34640252803918 0.629783347740304 0.408029189892113 0.183851683062967 0.140962453167886 0.860850116261281 0.875299273286946 0.80387750312686 0.128964691264555 0.895117025212385 0.211868936505634 0.71420736519387 0.377030816068873 0.492519052643329 0.606980109489523 0.742448201754596 0.61863813999109 0.919435129663907 0.336110302947927 0.683982774808537 0.351800461276434 0.623866821585689 0.705831268460024 0.484216676088981 0.672704090301413 0.172418541244697 0.401905671486165 0.144864468418527 0.447110688751563 0.324347773289774 0.535400925134309 0.873794403050561 0.0372529408847913 0.248697280320339 0.0439406119170599 0.133758258207235 0.287349829773884 0.964502756702714 0.0651763335452415 0.513581963442266 0.746000290715601 0.442910675238818 0.190019495950546 0.33861273405375 0.523239647869486 0.387928715094458 0.0879402752965689 0.849144618643913 0.234015031263698 0.989321336818393 0.23253836483229 0.674998527392745 0.0263748067431152 0.799719769735821 0.665481181547511 0.689673202142585 0.618468232569285 0.885259649464861 0.384687749198638 0.921243059763219 0.70024990123231 0.198123842414934 0.68887649709126 0.0161675411253236 0.464581869950052 0.912826613825746 0.314701401225757 0.646656963154674 0.470112534039654 0.950271971598268 0.234832697506063 0.536783947225194 0.69218613977544 0.26739274333464 0.382189064447302 0.903624842045829 0.795609635077417 0.518380975080654 0.917875147701707 0.759915927953552 0.0336908506578766 0.511448894352652 0.289877434731461 0.113364019014407 0.707042416944168 0.23595887015108 0.254887571565341 0.436330382106826 0.191891860442702 0.698618927777279 0.880132321591955 0.812676189246122 0.775357455627527 0.680658001259435 0.210054144582246 0.346013461530674 0.956720550162718 0.291226289230399 0.267191858242732 0.789884611647576 0.403821279138792 0.122157625092659 0.665855341700371 0.993344422269147 0.947542985507753 0.917077690290753 0.391397071084939 0.38065340947127 0.173419296415523 0.187293097940274 0.693275300429668 0.0582636433653533 0.81682408986846 0.22488828061847 0.377402022334281 0.483071355384309 0.683558063879609 0.27393980240915 0.441481106658466 0.760115990382619 0.0177518470771611 0.202416629891377 0.0857283359137364 0.446590834294911 0.712412387712393 0.937866427318659 0.2495820785244 0.312992257282604 0.123034941882361 0.0934245044598356 0.652039438674692 0.307196218157187 0.89943182151299 0.579347885767929 0.916656465018168 0.496578838676214 0.472885976193938 0.286749439644627 0.575890205262695 0.582853244759608 0.470423505664803 0.706920616051648 0.809365319136996 0.712812514184043 0.777646732232533 0.444660044605844 0.790459226544481 0.482446669156197 0.751680187550373 0.269773061908782 0.209446585599799 0.118710710429586 0.864353615560103 0.940982430982403 0.654719483817462 0.10243691672571 0.0156006960012019 0.353343587294221 0.466023133527488 0.127369812170509 0.606156846419908 0.419712651716545 0.916212206799537 0.542465474864002 0.53531914451858 0.478585355777759 0.210621249251999 0.316862353491597 0.2633298452897 0.0604740621242672 0.5914407928125 0.485522738751024 0.600907566675451 0.376762471932452 0.522719319039024 0.25815640311921 0.711509779745247 0.79307745995 0.285290671258699 0.75981425867416 0.807184413205832 0.855073339755181 0.907599111020099 0.385849006834906 0.122483968688175 0.379662818301003 0.732841880624183 0.761537033834029 0.277810854511336 0.498092856858857 0.72394893795019 0.632525399625301 0.539283258712385 0.362023905853275 0.157650198182091 0.6034063809691 0.498782200375572 0.189216337525286 0.982448201761581 0.171774175879546 0.23079356333008 0.288724625927862 0.0434899157681502 0.772216079188511 0.837652538761031 0.339601737754419 0.506175324041396 0.29342574184062 0.929337453597691 0.390008301418275 0.503570023200009 0.590668519395404 0.733964742333628 0.39752710187342 0.857220701142214 0.242030314852018 0.157626458976883 0.0775150798610412 0.750424334290437 0.463633554982953 0.536320431919303 0.68417992945062 0.904214656497352 0.0552097923518158 0.22545232859673 0.382168872903567 0.569518397345673 0.828274349020794 0.76662241604412 0.0273191114305519 0.941081262086518 0.564676294447854 0.585447688479908 0.938987310396042 0.839471138352528 0.342772908234037 0.741067431441043 0.718407253543846 0.865422435535584 0.389194798509125 0.0390469041559845 0.945247524294537 0.463340716515668 0.317058606408536 0.239109911322594 0.677618875887711 0.848457589601167 0.307317213674542 0.146607744917274 0.0993045745952986 0.194877642963547 0.0455224411212839 0.369050629688427 0.383252894969191 0.442635570929851 0.225782941326033 0.771867972253822 0.735032432847656 0.48949253667146 0.908940108616371 0.424824512652122 0.480059625215363 0.137671312214807 0.102362939766608 0.823602593112737 0.993273306535557 0.400933227303904 0.593591121917125 0.531689681224525 0.963819728028029 0.324556915436406 0.761108453001361 0.165863852312323 0.399937365467194 0.533886162890121 0.424210538328625 0.42751803641906 0.65654416452162 0.186282643922605 0.300789494207129 0.675359664624557 0.635528702859301 0.759380475864746 0.330185908365529 0.113229004805908 0.691952376982663 0.544505529345479 0.741132493030746 0.518308463655412 0.645291660008952 0.421747287318576 0.22604671690613 0.338739892512094 0.577241748801898 0.409651862496976 0.463513020700775 0.650471702613868 0.397392331766896 0.997983999589924 0.703736028491985 0.272188685142901 0.124811765460763 0.210349108050577 0.0387338727619499 0.752274315392133 0.54581418170128 0.450360552498605 0.247582090650685 0.776099379954394 0.561761294354219 0.658099098252133 0.66172186821932 0.679841368359048 0.916647931821644 0.252423418369144 0.15691202113172 0.473677595672198 0.529266151299234 0.806573106485885 0.416512970863841 0.435836338379886 0.978880582475103 0.954255527972709 0.427186376287136 0.882575453436002 0.162677253619768 0.0547843014029786 0.77764997563092 0.918220748845488 0.649727214409504 0.673641406849492 0.358193132190499 0.610068214763887 0.914881023762282 0.465830990006216 0.6234748671134 0.676260204063728 0.161528474458028 0.228338815551251 0.722092124067713 0.79500599924475 0.844261366699357 0.660037376040127 0.0849316903320141 0.162097315962892 0.928647056915797 0.656329919744749 0.502398153927643 0.919505469757132 0.865411914947908 0.567847640339751 0.244442123502959 0.7956704243063 0.888005118086003 0.731081668196712 0.625101521646138 0.0950185512099415 0.195877658452373 0.814248359710909 0.118756771020126 0.526561860076617 0.80390163810458 0.746231340034865 0.928835093115922 0.10300003969809 0.807818967008498 0.870275612226687 0.961370047843084 0.183112650618423 0.278658802537248 0.262286608307622 0.67652284096228 0.862122194119729 0.355851365593262 0.433616753695533 0.944710609898902 0.16254189043073 0.822546474277042 0.0649956012726761 0.228598202827852 0.829661570172757 0.121556193092838 0.910638104313985 0.916486786024179 0.566218763303477 0.707970488043502 0.701618107093964 0.307379483189434 0.294479082892649 0.117640372135211 0.241410548926797 0.0322120894212276 0.073400800540112 0.630833730525337 0.767905681103002 0.695145383870695 0.240859957674984 0.367316751461476 0.866783005776815 0.771519300588407 0.567235347300302 0.464975963714533 0.401720581566915 0.367656768225133 0.122440704090986 0.178159740176052 0.867967380031478 0.357447674262803 0.094288855032064 0.654947710866109 0.853016729904339 0.883863678905182 0.830048449675087 0.443110785842873 0.469880287952255 0.711694199594203 0.640502229891717 0.714942764921579 0.0636565597192384 0.957609868748113 0.325832105767913 0.9921743202582 0.72354350854177 0.476696184438188 0.797328458505217 0.0414346555084921 0.533636810071766 0.54522136149928 0.47059865701478 0.0604051313223317 0.269403909188695 0.207154090490658 0.609299562769011 0.767235880957451 0.569591887253337 0.212478849838953 0.974548140990082 0.614731525988318 0.4096553857252 0.953318904775661 0.523461368298158 0.0341139358538203 0.141536213131621 0.665445973698515 0.776092017479241 0.125781964089256 0.96637913424056 0.195508158134762 0.256090882509016 0.516826720640529 0.712545399086084 0.959636736190878 0.445794758053962 0.334485866078176 0.70398962601088 0.65511674122652 0.59356558802072 0.783882395788096 0.935317856098991 0.459049954924267 0.783668184434064 0.0738891725265421 0.493483857286628 0.0325958979409188 0.852257247753441 0.407299001361243 0.193423217702657 0.381016954530496 0.656585255942773 0.132589653308969 0.187152899964713 0.368159803156741 0.360353136169724 0.402546312625054 0.725413898320403 0.870381395511795 0.242408211447764 0.0753850672324188 0.73450408553239 0.521045741376001 0.462335667777807 0.383043214830104 0.91101143465843 0.503466298761778 0.236376659325324 0.234715377348475 0.799228797683027 0.516895876182243 0.269598577863071 0.561880274589639 0.283840526656713 0.214000282590278 0.715675238652621 0.626343409230467 0.30441820168402 0.289868955933489 0.109035905210767 0.240580479814671 0.525556959321257 0.836526179178618 0.864249647941906 0.549247012671549 0.630266527200583 0.601673597858753 0.597464595907368 0.953348065165337 0.556157490720507 0.317463639352936 0.840015160057228 0.525793409079779 0.0991744168405421 0.529756681018043 0.519343982727733 0.20663598992629 0.0259125416819006 0.777786903008819 0.862058889879845 0.16501358358888 0.403410124513321 0.092570255191531 0.593866756611969 0.421096766388509 0.81918807735201 0.341244245315902 0.74379860522924 0.204326668377034 0.0931251377053559 0.0735784634435549 0.91245081987232 0.273782937270589 0.612127609082963 0.479168354966678 0.682993383633439 0.502071789125912 0.46630726730451 0.231074635805562 0.64089839886874 0.263133586149197 0.602572715559509 0.287129281219095 0.605965695211198 0.414015819414053 0.307806196031161 0.661780959337484 0.601497772058938 0.31464206231758 0.865568780777976 0.868336810737383 0.486909592943266 0.300293377803173 0.179693927082699 0.523304849143606 0.121533621842973 0.408509966365527 0.148795261885971 0.770871501890942 0.48123292959528 0.195013650867622 0.962190411884803 0.186051809201017 0.0380337408138439 0.637824180207681 0.554094657767564 0.411870421445929 0.362908746008761 0.464352533032652 0.229698387717363 0.792447651729453 0.18796994315926 0.160702612013556 0.593153324448504 0.800679544126615 0.707412396015134 0.95296665755799 0.0572997139394283 0.538032651916146 0.588601382733323 0.106420134492218 0.355689556640573 0.545458893235773 0.183234294999857 0.726556869975757 0.875375320157036 0.834213592563756 0.120564044418279 0.710525969953742 0.764211301435716 0.889548798692413 0.473650902810041 0.187698395962361 0.36952778566163 0.158873704127036 0.420590744377114 0.900307070466224 0.23771379831247 0.0812335274298675 0.103905957217794 0.57980831510853 0.274478620523587 0.807522013843991 0.995087724353652 0.81185858546989 0.826441107690334 0.132293748699594 0.141959267440252 0.865214894919191 0.466960089569911 0.607336395569146 0.161253849132918 0.906266829639208 0.665913529018871 0.907697171324398 0.374099880657159 0.533722537348513 0.613488229804207 0.238713379073888 0.405839385648724 0.38986067481339 0.202684790317435 0.253651420492679 0.878357952171937 0.36180681736907 0.589382511589211 0.115505834515207 0.315419278857298 0.714500549645163 0.527165956222452 0.849811660367995 0.817746147161815 0.632055854147766 0.24208014208125 0.164530588760972 0.073697933035437 0.325715439545456 0.857266173721291 0.200475455611013 0.0740013550175354 0.843141028990503 0.898975309790112 0.136590729244053 0.459738016617484 0.503263012757525 0.175098302869592 0.382387878475711 0.520483155243564 0.3313713781978 0.141933443341404 0.0605389024317265 0.908497958572116 0.227157587422989 0.686216118638404 0.814956674491987 0.940427833830472 0.845617793200072 0.374540360942483 0.687229396770708 0.220230486467481 0.877921428920236 0.113313492441084 0.331148783473764 0.786497870772146 0.566686838867609 0.928806114131585 0.0790673356154002 0.571500818866771 0.314676309893839 0.565658502017613 0.773641382323112 0.0241942772222683 0.959799554743804 0.607590369959362 0.854371839314699 0.532711006193422 0.476890830984339 0.15925040810369 0.328864940730855 0.816225218058098 0.2308721673931 0.635441574589349 0.142613210638519 0.770962556998711 0.380998422142584 0.52108482927084 0.307628244538792 0.922935987175442 0.448030434336979 0.245924606430344 0.352883691797033 0.661559044595342 0.97556646597106 0.59644434784539 0.380149544500746 0.936699850149453 0.2884441373148 0.615993435466662 0.216955941221677 0.415737376138568 0.587542002520058 0.205547095732763 0.0992780963308178 0.571305914619006 0.261730804475956 0.903189119789749 0.812927443017252 0.901511875295546 0.110533428185154 0.367029918732587 0.290274532863405 0.58969815503573 0.872200839894358 0.564327896619216 0.786127746484708 0.368996570666786 0.947972702947445 0.450391482224222 0.922972667934373 0.907368821667042 0.538641699021682 0.933911789306439 0.0539822560735047 0.930931519709993 0.856112337799277 0.411918533737771 0.919442754911724 0.322372364802286 0.718769401758909 0.3589787496184 0.779592569114175 0.671347297993489 0.331869661093224 0.641921778074466 0.614412677176297 0.0128142751823179 0.487815699244384 0.943823881237768 0.947941126201768 0.888548211327288 0.107894184952602 0.412744828374125 0.266867122401018 0.948453561249189 0.32600846034009 0.245240971534513 0.0230831658304669 0.122013338466641 0.542156305997632 0.101505944062956 0.73815116427606 0.133419542629272 0.555866441873368 0.265521087176166 0.228868626095355 0.0269075898453593 0.611434675953351 0.0812165675288997 0.200100879401434 0.34538911921205 0.757281567682512 0.193849647718016 0.917174873303156 0.171142575964332 0.863433568247128 0.336007443354465 0.768191386675462 0.81886523347348 0.256240469766781 0.793870932436548 0.762684556527529 0.518904578427319 0.31315972391516 0.234316435197834 0.550041688380297 0.162923028350342 0.240828750424553 0.413516647471115 0.990702141707297 0.474044979286846 0.145026497270446 0.205274835361633 0.55250169806648 0.0611944667529315 0.15486552918097 0.732644754794892 0.670739575584885 0.267840838034172 0.555674889821094 0.328891988797113 0.515875421820674 0.877314282767475 0.983495573494583 0.235815071959514 0.983612973636482 0.209198064894881 0.773584972638637 0.109101416971534 0.739170360094868 0.383360203949269 0.417083163342904 0.0441508694645017 0.098595699693542 0.279130082775373 0.090564531267155 0.255169474079739 0.24610675490927 0.363508986542001 0.230984922682401 0.919800978363492 0.479128889509011 0.851679219116922 0.0222401814418845 0.782471646110062 0.0669759547268041 0.225842933708336 0.289246622903738 0.629739785564598 0.231317644969095 0.860953684418928 0.661983201627154 0.906017373094801 0.789464536120649 0.554384357023519 0.358752547532786 0.340562943334226 0.0277992097660899 0.0717212404194288 0.528742106771097 0.494900807477534 0.3260020606732 0.437893769741058 0.135235746609978 0.666207457992714 0.120486303817015 0.735107239154167 0.697319891748484 0.793135139932856 0.214236088786274 0.822188785360195 0.823396506274585 0.848328968144488 0.607545965758618 0.189434336954728 0.330497851097025 0.980987977522891 0.335282619304489 0.88973463290371 0.257464387849905 0.0491192710469477 0.0583794152387418 0.53076751743909 0.0728494790568948 0.900751607592683 0.870366501142271 0.0614289581635967 0.801299556919839 0.984292948385701 0.412751022432931 0.750871654271614 0.601047519627027 0.753549037112389 0.62230007622391 0.435420242245309 0.474038502401672 0.444871761924587 0.100534044327214 0.25582858744543 0.346224758182652 0.776350676137954 0.586658455943689 0.663730092863552 0.785993214948103 0.443804174906109 0.0916412950446829 0.741315721643623 0.270516467443667 0.305868583933916 0.556793449204415 0.736453869766556 0.200460586135741 0.648890669103712 0.667106084953994 0.402913452137727 0.0718160375021398 0.65492544895038 0.366281327356119 0.658970236426685 0.373733906103298 0.677447729054838 0.655432220324874 0.0426557153626345 0.279453725805506 0.722658693511039 0.889735103819985 0.656170429876074 0.7206408426282 0.485731098572724 0.777273873726372 0.837894356457982 0.361565976541024 0.783370336689986 0.156811857493594 0.154331295527518 0.136491650810931 0.0563247395330109 0.823015290675685 0.602402922466863 0.342786439412739 0.643871805258095 0.240228951764293 0.118305603724439 0.849765294822864 0.411772796791047 0.772652961332351 0.42535326150246 0.71195532716345 0.398683842355385 0.626735168006271 0.762263145931065 0.412826605762821 0.760115942207631 0.108601852713618 0.251935439619701 0.0993105897842906 0.525091351284645 0.152968815113418 0.788764699215535 0.78486180390697 0.984135134269018 0.750296123127919 0.678724160641432 0.80990458373446 0.0333706695423462 0.431352943680249 0.942677536411211 0.936705319969915 0.352086689858697 0.443792461699341 0.425148412000854 0.160500135994516 0.358448244570754 0.686285516668577 0.587171516574454 0.386295485021546 0.0567804486467503 0.258902233308181 0.786559441403952 0.463074376827572 0.060117158528883 0.974376994618215 0.873591534025036 0.359514217381366 0.775168026501779 0.665252818041481 0.121592285840306 0.37521461347118 0.386018420981709 0.917202407037839 0.0859808461531065 0.974946801236365 0.524284966518171 0.144830995791126 0.181026163285133 0.440415779945906 0.45404483316699 0.836193683475722 0.752606935796793 0.600396921939682 0.893975621894933 0.434412601739168 0.297292038679589 0.822197334922384 0.91905724874232 0.297914344740566 0.314324467438273 0.233402770725079 0.553909946563654 0.92939781247871 0.329126677056775 0.181198690596502 0.342411320600659 0.753961207561661 0.723630039349664 0.342523359488696 0.597038171885069 0.404224475671072 0.938967287810519 0.258875127846841 0.874983136795927 0.529676985526457 0.968549618700054 0.918883807028178 0.120343847379554 0.880602301796898 0.883396420010831 0.841682559105102 0.19029052889673 0.59286409772234 0.141415674239397 0.246372862712014 0.822435617174488 0.896264332616702 0.77646947058849 0.775088405462448 0.021452186612878 0.667992252111435 0.879999705068767 0.0603011176036671 0.206839456644375 0.469061434392352 0.0257665085396729 0.299204310732894 0.871406405521557 0.934187527266331 0.917341744317673 0.973309958039317 0.177302568368614 0.0956936967046931 0.0577115317201242 0.0983409549645148 0.114275667513721 0.370546607605647 0.129202967293095 0.52359687094111 0.905244270330295 0.899683674820699 0.461567529111635 0.196224029934965 0.265718888377305 0.081527659476269 0.143894881312735 0.0465161818754859 0.33501708706608 0.0433992541278712 0.994160642800853 0.696086214657407 0.19610090803355 0.531069644459058 0.0174021381512284 0.978058726391755 0.0601495247450657 0.251926219756715 0.743172739981674 0.331689603039995 0.943457157781813 0.566393605088815 0.825004521927331 0.288562983167358 0.386158953185659 0.444971808698028 0.398118199300952 0.390815371007193 0.358487221363466 0.183655740863178 0.40507601907244 0.0145747695141472 0.276088494255673 0.0353142226068303 0.910891752082389 0.778100269783754 0.653756060574669 0.289353850055486 0.340128967133351 0.330387916695327 0.815989995033015 0.948956451886333 0.842113591791131 0.454679272640497 0.942786661980208 0.714638940712903 0.627611344270408 0.544555426877923 0.97090465877438 0.713500289132353 0.268308576603886 0.207641500590835 0.979335728010628 0.770639443893451 0.992450443618 0.214683210535441 0.892177029906306 0.366985400663689 0.302481476329267 0.15277612161357 0.154998132796027 0.839650806856807 0.297667826639954 0.43866415603552 0.50561903500231 0.338926062565297 0.0951515259337611 0.368492166320793 0.0406520127132535 0.0181689857738093 0.84047798800515 0.146696515055373 0.568436792097054 0.204576468369924 0.530620748302899 0.886607707808726 0.515058960414026 0.873252761743497 0.219111957049463 0.280924155535176 0.689459672844969 0.155122021348216 0.998492896656971 0.623968880414031 0.92923452116549 0.46761828645831 0.808315108767711 0.0304206439270638 0.85554105020361 0.163587245498784 0.952931212752592 0.81260571039049 0.181255451336037 0.891717354077846 0.0933789786347188 0.139786997509655 0.056281718115788 0.236197037613019 0.605574718760327 0.820179816654418 0.035955444611609 0.26394947798457 0.391637867195532 0.333205572885927 0.844476924187038 0.440204577799886 0.611645232231822 0.329645297403913 0.54633352905279 0.075387433108408 0.440785066818353 0.201338875184301 0.543146128903609 0.17783846025588 0.109371013657656 0.0239348256355152 0.623630337943323 0.723846243857406 0.119160620565526 0.960727321580052 0.0468634626897983 0.352467699158005 0.115180257570464 0.39852945119841 0.554354648729786 0.364406956341118 0.0227509220666252 0.591837868355215 0.81491433029063 0.714311862967443 0.412618708789814 0.64469804180786 0.327672172964085 0.78236048451392 0.420911791028921 0.929044567416422 0.774717363084201 0.640453885945026 0.394856733679771 0.0779389953264035 0.547645259767305 0.755075475913472 0.493233162483666 0.519735593290534 0.819625850617886 0.724025845516007 0.869467257817741 0.974062679556664 0.872535751261748 0.342546696697827 0.625237321637105 0.436166502782144 0.323081628561486 0.933366522658616 0.683388284617104 0.83450881857425 0.242379484863486 0.842073319344781 0.0805266058049165 0.745693940431811 0.264728922098875 0.857105426462367 0.535552398823202 0.250711449158844 0.178741811132059 0.786977643868886 0.331606060694903 0.872350319507532 0.632168295031879 0.299692552946508 0.220562383555807 0.537475716779009 0.271244413647801 0.183266324452125 0.102346008678433 0.423024432309903 0.058243821777869 0.682420625663362 0.123415331360884 0.711876676077954 0.946742317890748 0.201413736119866 0.884412930016406 0.244884513039142 0.333595740965102 0.687610188936815 0.396268113320693 0.981112982167397 0.186126967945602 0.681741876034066 0.0563769319467247 0.0924018554855138 0.091169018575456 0.607007098316681 0.0762410056218505 0.502926691868342 0.816983387728687 0.414925304187927 0.298778693468776 0.955736561962403 0.453351026203018 0.68251244004583 0.777786198132671 0.322942345680203 0.255403853696771 0.354777291086502 0.644880006115418 0.833863281565718 0.757095868545584 0.373191741325427 0.661384478951804 0.758612904464826 0.613503224211745 0.792516401356552 0.069519133574795 0.474837548434734 0.127301150595304 0.771781433147844 0.330964428165462 0.247567960857414 0.915101964401547 0.572033460671082 0.952862263279967 0.704475001466926 0.308087473653723 0.84815283439355 0.695482190889306 0.989287882631179 0.103903723650146 0.313754759475123 0.4873920085188 0.163854038584977 0.960261880196631 0.898199000507593 0.0423118203971535 0.639890447875951 0.424940870462451 0.21174543104833 0.968424859079532 0.213129916598555 0.545829545604065 0.224069524561055 0.0323885737662204 0.421458821480628 0.147133253135253 0.444641556013376 0.562659388624597 0.722215647273697 0.775435933144763 0.559269909611903 0.441164481502492 0.0950878153182566 0.0266120385960676 0.657070506466553 0.759639875818975 0.764451386216097 0.238088649972342 0.138831088412553 0.775686426488683 0.296549754077569 0.780018327445723 0.0512671688129194 0.043358605040703 0.049108702975791 0.867934996758122 0.606993434829637 0.660152733931318 0.452159218017478 0.347614600837696 0.722917706912849 0.493977751417551 0.255717568069231 0.399183711567894 0.25031502662925 0.361977481299546 0.452005620249547 0.537565421834588 0.96095394018339 0.846869363957085 0.559065521575976 0.651097439471632 0.54338715759106 0.220903537617996 0.552378239862155 0.725377263200935 0.0311263856105506 0.338953764105681 0.692957416730933 0.830287830962334 0.184659137821291 0.0197718420927413 0.324616090226918 0.689086883028504 0.421368084466085 0.595404907236807 0.219533119164407 0.12673018086236 0.733265714952722 0.0196370496274903 0.139776967891958 0.452303232650738 0.318955266538542 0.316181426076219 0.891582488773856 0.683752026755828 0.785558830066584 0.58408096751431 0.15449004848022 0.145235256552696 0.940058532436378 0.729055613735691 0.0494450879446231 0.758984409922268 0.149982173049357 0.501838576542214 0.150950553705916 0.135972692316864 0.0976339959981851 0.382686922065914 0.199631468767766 0.0162136510433629 0.0343388489703648 0.714760864232667 0.868652637202758 0.955197670317721 0.677003329999279 0.617516504554078 0.799618959308136 0.82426566443406 0.69013246514136 0.733945134421811 0.369872931563295 0.976129414453171 0.642803380594123 0.711342635585461 0.837876864096615 0.509149798578583 0.963056203788146 0.319169733289164 0.269218579547014 0.283755557502154 0.668567750754301 0.762465384302195 0.680991327692755 0.514153919955716 0.0462557478877716 0.768470409063157 0.0326919839926995 0.91203376784455 0.284776837292593 0.251600555451587 0.77054497228004 0.178404655593913 0.789370100696105 0.20440592107363 0.0983346707792953 0.405097397472709 0.0984862339030951 0.445263054855168 0.918784552952275 0.533684989209287 0.353483121192548 0.926460578129627 0.538768632048741 0.773181447410025 0.348107103195507 0.0951718806731515 0.723638277964201 0.992619190691039 0.744947877435479 0.0537611506250687 0.648682374744676 0.514406373491511 0.759507921529002 0.0944352952414192 0.304420883578714 0.544819232884329 0.0399382094410248 0.988909452422522 0.210806471710093 0.189189782042522 0.829314768342301 0.814944950451609 0.521096307134721 0.526304438754451 0.77132261110004 0.31887479333207 0.245386181322392 0.738824704552535 0.295452520539984 0.646694149635732 0.278058241144754 0.694217394138686 0.648025826639496 0.582214851710014 0.490171191103291 0.635090103703551 0.680594469744246 0.299217695773114 0.112360779950395 0.206796594504267 0.966271910546348 0.17562101601623 0.109872440143954 0.983951612457167 0.567206806500908 0.397687374758534 0.446961365418974 0.529346076140646 0.96314131539315 0.751864483619574 0.831787324501202 0.725152118660044 0.702378062005155 0.893048279413488 0.321923645671923 0.683420151795726 0.335657272732351 0.498637943945359 0.581876663982403 0.0749445980112068 0.233697656283621 0.589122407219838 0.579398596282117 0.344555719802156 0.251140763680451 0.0163584537641145 0.669584571246523 0.102580193981994 0.444190119951963 0.205698639955372 0.152803081627935 0.154174676334951 0.414975714818574 0.764247599330265 0.243209349059034 0.719658182582352 0.758909649024717 0.0347862235805951 0.0130683297873475 0.713925547734834 0.0965236023906618 0.824947983622551 0.779402819129173 0.606244775915984 0.673841186221689 0.538267402641941 0.752284614697564 0.130933526055887 0.403234364637174 0.841616255568806 0.818443373397458 0.613540401011705 0.437251296800096 0.994495888627134 0.876968281010632 0.330675067056436 0.99276214616606 0.875723253062461 0.903133739067707 0.378116893293336 0.828876372489613 0.494254300515167 0.0688743168860674 0.686222241932992 0.868145648464561 0.685280102123506 0.779365531227086 0.62509185483912 0.73038486124482 0.343576007189695 0.491009923876263 0.926059322657529 0.267788320151158 0.122653873574454 0.0258384752878919 0.87653904001927 0.94220890764147 0.213961711020675 0.924437282320578 0.582170459495392 0.838067225373816 0.312271192495245 0.940289524591062 0.53479559487896 0.574460087856278 0.183768631457351 0.328299042971339 0.249571253443137 0.424536013160832 0.470720300935209 0.749360879256856 0.394213414564729 0.181023627759423 0.796340734092519 0.586734341923147 0.95975849674549 0.328606447342318 0.0726287774485536 0.872274259268306 0.150503608060535 0.530523188419174 0.732798506768886 0.925533447940834 0.343435688891914 0.2779501947877 0.287270070663653 0.254777851761319 0.393610337700229 0.448338998365216 0.549967463861685 0.352570194327272 0.970160439105239 0.586490566569846 0.509019638749305 0.245526505152229 0.349823863627389 0.703371230652556 0.403302736470941 0.795223856454249 0.255252258994151 0.33480366287753 0.463837960537057 0.983935538146179 0.311161731039174 0.708959411990363 0.83270294109825 0.754280891714152 0.238238898541313 0.870737645172048 0.267757110365201 0.456912101989146 0.596806833285373 0.807537267797161 0.769900730925146 0.675760756670497 0.924252806690056 0.43857974400511 0.910301032909192 0.768110069599934 0.182336268036161 0.729175838222727 0.944310137443244 0.0309166895668022 0.334468546363059 0.997953836054076 0.863035863433033 0.805456505219918 0.614255876347888 0.973947689777706 0.578224245421588 0.360426030228846 0.507629640044179 0.444953722332139 0.901925774973351 0.739364649823401 0.808900571335107 0.17809880411718 0.94286446251208 0.542190291953739 0.206569628533907 0.262302621074487 0.2104701694916 0.213311105265748 0.351836687254254 0.638369644396007 0.319821099240798 0.54293121175142 0.404220452944282 0.468323557686526 0.875051102484576 0.834507880429737 0.353756672607269 0.869218697005417 0.338692870035302 0.154718401152641 0.860229618491139 0.570934701899532 0.153597555647139 0.506441218398977 0.431339580076747 0.810875114516821 0.924084586084355 0.217618628065102 0.936160525851883 0.569288629849907 0.605254236378241 0.0474864674033597 0.33478497789707 0.72900535362307 0.715668933261186 0.927101026338059 0.0291444320091978 0.304500698240008 0.743420723616146 0.253853367278352 0.0423639699374326 0.852410046830773 0.218869858600665 0.848646614656318 0.110681345453486 0.405873789505567 0.148147951622959 0.62470067139715 0.153613753968384 0.530308003653772 0.431902184188366 0.386744339917786 0.433022696387488 0.265414751146454 0.858478222778067 0.364695068357978 0.430195871735923 0.0500500035262667 0.229831987333018 0.0808978985087015 0.993970605379436 0.469657173675951 0.536459970197175 0.475930993435904 0.146189074763097 0.534709069833625 0.195034701724071 0.206688230745494 0.680059543200769 0.635213158067781 0.285329441982321 0.6538452578336 0.941240487569012 0.820386106795631 0.4420681410213 0.284857676075771 0.860185730154626 0.404467067394871 0.936867137451191 0.252471777298488 0.381533603160642 0.0904965054173954 0.634434093821328 0.603190740500577 0.519864485587459 0.90456393991597 0.638202033007983 0.334715174182784 0.970439338174183 0.369824820193462 0.964319298970513 0.920170479833614 0.668177829082124 0.888928462273907 0.78017259943299 0.595556802283972 0.787253283173777 0.793024388630874 0.836249191896059 0.585730847923551 0.683267115070485 0.691721397966612 0.232723683409858 0.784288181553129 0.639650551185478 0.612209971717093 0.403630078602582 0.0106594144017436 0.829384151850827 0.548719909146894 0.47739016197389 0.750722742385697 0.176836088111158 0.606975961599965 0.177430347800255 0.341219201697968 0.855353586340789 0.354220116226934 0.125823826079723 0.638963896248024 0.341083785493393 0.355769053208642 0.419022240974009 0.644681266769767 0.221450667416211 0.195422047071625 0.187877422056627 0.916834670524113 0.532210853002034 0.685175334892701 0.679295697179623 0.163422081815079 0.838744055840652 0.090698361385148 0.503942142485175 0.516359471196774 0.984495682106353 0.252999634796288 0.0803182012657635 0.945829544770531 0.0797779480437748 0.279790051535238 0.491718321407679 0.666405956693925 0.972376095568761 0.145130191743374 0.0776434632088058 0.382086974962149 0.764350410979241 0.772666406072676 0.917858117728028 0.155233707798179 0.431899875246454 0.714482927280478 0.379737076703459 0.962270521589089 0.732345127803274 0.898153731692582 0.0731435334240086 0.197639195807278 0.472132778689265 0.95071212134324 0.472360989833251 0.224740206608549 0.968219602049794 0.703731084216852 0.122953459767159 0.647144031880889 0.547630917681381 0.259877119662706 0.37401247855043 0.381622644599993 0.173875932840165 0.543822833055165 0.672799146238249 0.513776573338546 0.598003035075963 0.623354780927766 0.0774288830510341 0.315664858582895 0.217541497834027 0.647778472045902 0.765593307241797 0.147597672471311 0.693409940302372 0.928793918252923 0.786727743376978 0.386475792247802 0.72438631313853 0.290179736011196 0.547856400599703 0.258199662414845 0.934378161919303 0.238823671445716 0.0311245574965142 0.404379833324347 0.442031795873772 0.420837209692691 0.281014724283013 0.649282670598477 0.26919430027483 0.696058285611216 0.85713250357192 0.0718363869399764 0.112392304833047 0.778572280483786 0.868642381923273 0.290104370736517 0.900138639872894 0.738697763457894 0.717869530085009 0.255526887546293 0.391216837158427 0.865679340302013 0.104772551960777 0.0428559363773093 0.114177002832293 0.259672356368974 0.297990278895013 0.583860964097548 0.799044375529047 0.188310941171367 0.824977123958524 0.0724442400434054 0.484901663572527 0.964830278626177 0.974908381567802 0.0258632614347152 0.53422329998808 0.676890700103249 0.939801752371713 0.0972669145721011 0.154981168746017 0.797935920676682 0.551391687784344 0.14725511188386 0.989396208818071 0.974002478800248 0.800696897725575 0.21096780306194 0.5991303044511 0.337753921530675 0.742551298304461 0.304883711757138 0.778315562885255 0.485766184024978 0.311331709916703 0.530370985651389 0.150612367130816 0.720538618990686 0.537601964753121 0.967411966577638 0.689902241020463 0.23476239221869 0.60001096629072 0.150507614652161 0.933476974999066 0.95729340148624 0.44311784198042 0.433085999013856 0.197339285528287 0.868228957771789 0.405468421180267 0.365636031683534 0.615563128862996 0.843767082788981 0.309125335321296 0.377540185204707 0.259698103249539 0.191166488719173 0.257012066198513 0.22368696720805 0.424615035355091 0.289443254075013 0.850465222084895 0.353421795123722 0.0693804062041454 0.20514513745904 0.387407554842066 0.458238741594832 0.750896279758308 0.311091544230003 0.607834791180212 0.59459906760836 0.493073677455541 0.583792892147321 0.920306992998812 0.0496786469733343 0.919890648843721 0.724960022852756 0.416421038003173 0.261172706685029 0.64791569423629 0.967288948863279 0.0820718614337966 0.16969777509803 0.159218186642975 0.961590294209309 0.24171518150717 0.365420397899579 0.53224880751688 0.657410894338973 0.950450044334866 0.757559135139454 0.0966137481667101 0.854991876310669 0.857898296415806 0.0312842522817664 0.721404280890711 0.110548743221443 0.150243567309808 0.466681643668562 0.773201624662615 0.226908832527697 0.890935352770612 0.0190507883694954 0.766855922518298 0.0756698284368031 0.643501782161184 0.789564817084465 0.572078901440837 0.634490871618036 0.619474029517733 0.186468731225468 0.141299556843005 0.735872528811451 0.105422281806823 0.752615774869919 0.530893159883562 0.608380488406401 0.384555126221385 0.218964243314695 0.736383957024664 0.828773516584188 0.477757153043058 0.0129890787042677 0.716880060078111 0.0819582622754387 0.418371544862166 0.340086985051166 0.452140143027063 0.515705125310924 0.924883118327707 0.417521145213395 0.760421652155928 0.378101067233365 0.96425240304321 0.28591828163946 0.645689713112079 0.694126719359774 0.202139065430965 0.988734585281927 0.83353819812648 0.964197666805703 0.716192775638774 0.577465910250321 0.940301628960297 0.56698960138252 0.328798511340283 0.479506356909405 0.360677060873713 0.272007340656128 0.308688130243681 0.283662881962955 0.58807805276243 0.704461301791016 0.589175192716066 0.724580433217343 0.905890562003478 0.427299656199757 0.892339119610842 0.922141798518132 0.110953113010619 0.886357224606909 0.559635373142082 0.38513411997119 0.609516162357759 0.803559367028065 0.167258689261507 0.746989221577533 0.822500751141924 0.125197907586116 0.816873983943369 0.541060940681491 0.358933649761602 0.596441306367051 0.124236262668855 0.796764563580509 0.749314055473078 0.227320068520494 0.404531810891349 0.350935426112264 0.209667285364121 0.0983904802356847 0.848373400005512 0.0670110763679258 0.707213871728163 0.943937319274992 0.254428722779267 0.218122443708126 0.625515020941384 0.276149327741005 0.687659672948066 0.491112378477119 0.317777382999193 0.687387581304647 0.114819483610336 0.394296954374295 0.699846197364386 0.940769107753877 0.10325489414623 0.796660912903026 0.381377709589433 0.107821202611085 0.816703934532125 0.78495731393341 0.110671581604984 0.0852215343434364 0.973166184511501 0.0724522705143318 0.32897320214659 0.410004837641027 0.99765739483526 0.665257852904033 0.999226638842374 0.633074620310217 0.363205536208116 0.0805682976846583 0.125137890770566 0.429198707330506 0.415646915265825 0.226239535338245 0.269525571549311 0.712003244219814 0.463725297679193 0.534682104056701 0.211002921937034 0.320886946427636 0.633084795374889 0.763259593704715 0.426135680940934 0.786002665774431 0.873911121136043 0.204111907274928 0.761672227373347 0.976872618298512 0.194465819420293 0.308916354065295 0.826159932180308 0.906042139648926 0.36583087392617 0.780255215850193 0.542680341997184 0.94645266266074 0.0566587189794518 0.693692968590185 0.358368378968444 0.378059257797431 0.593541529569775 0.0879468464571983 0.46737147861626 0.442246967961546 0.692972071839031 0.0730466009676456 0.97862158451695 0.691219968944788 0.690868246119935 0.418814575425349 0.495145279639401 0.148232304644771 0.617544493991882 0.0720461069559678 0.258412380113732 0.569711236061994 0.986009309357032 0.412000431448687 0.832913895223755 0.682131492060143 0.135291974197607 0.407487017277163 0.362544119432569 0.305603160723113 0.372241397707257 0.798274397454225 0.735663976750802 0.839757875653449 0.0763484644284472 0.916603362581227 0.843704559952021 0.673785688173957 0.0906743190693669 0.334762071727309 0.663574228105135 0.314620272701141 0.566102212562691 0.760959209192079 0.941422084916849 0.247526203976013 0.595054104577284 0.329843259956688 0.400720892008394 0.752241802345961 0.964749166928232 0.757810065746307 0.207949111491907 0.609241511677392 0.59993037783308 0.873736473203171 0.329766797260381 0.833860120226163 0.698936133107636 0.245387417736929 0.0671862032846548 0.937027531119529 0.511864490988664 0.543209317661822 0.716550536702853 0.0314255988504738 0.0889874056936242 0.537188833339605 0.572804621914402 0.816582667483017 0.354065557264257 0.84888917895034 0.421150537973735 0.594679308468476 0.297419473510236 0.820387194075156 0.736552195609547 0.913273916749749 0.399513907318469 0.921523562206421 0.523602825046983 0.717783032469451 0.896503910522442 0.053732758499682 0.946378888774198 0.787837195151951 0.806565214085858 0.0267483892571181 0.328127539551351 0.800936986654997 0.0504429929540493 0.22725495161023 0.178344782842323 0.0291864793235436 0.947714148936793 0.202247726076748 0.0176696441811509 0.977184457534458 0.508171556110028 0.769052315209992 0.846364462187048 0.796934358978178 0.378503453319427 0.914162923926488 0.138662018405739 0.0928145708423108 0.3934790189052 0.828864563393872 0.394577841064893 0.218735597212799 0.135070836709347 0.907419060342945 0.714021659372374 0.514522658924107 0.811024669043254 0.179699781842064 0.341752372735646 0.783996340008453 0.536414061277174 0.682463366098236 0.462671677949838 0.872228464907967 0.295482526873238 0.675075358201284 0.601315550971776 0.61489956910722 0.240266043739393 0.464965560913552 0.26411335615674 0.766909313544165 0.0360308108082972 0.13822510283906 0.679002233359497 0.0501741403294727 0.544441110396292 0.886657602805644 0.121877124262974 0.479773854641244 0.326374626902398 0.581633689394221 0.862669227567967 0.739607808813453 0.637858452678192 0.49397642188007 0.984081448891666 0.292588701646309 0.809450684755575 0.0783921080618165 0.468765157982707 0.124359807081055 0.186086801299825 0.665830961237662 0.0400580206373706 0.7770353480638 0.480781908438075 0.455066488676239 0.192692893866915 0.76420275809709 0.8151744738454 0.771946759796701 0.739009740303736 0.943231192652602 0.677539844242856 0.639744889338035 0.201150924731046 0.220771028047893 0.398240636379924 0.955890773097053 0.610685721996706 0.746071791849099 0.293997065164149 0.745726586016826 0.657583038785961 0.199592191630509 0.342434612861834 0.62895895451773 0.0213255719095469 0.734218302280642 0.561990617902484 0.322762511444744 0.747927677729167 0.700588974319398 0.42384669453837 0.606584656913765 0.254569329896476 0.604284699982964 0.63902488301741 0.594928462132812 0.644769767681137 0.380185529373121 0.995058057550341 0.40343118919991 0.89286935266573 0.672934782572556 0.190336566206533 0.527990830733907 0.0455909565580077 0.51985771527281 0.862967769354582 0.353268206114881 0.337408235101029 0.368470959875267 0.94404335311614 0.23860154325841 0.375918255278375 0.0148219542275183 0.666287462818436 0.959485019783024 0.602641118050087 0.65955674132565 0.413357843807898 0.995880798762664 0.477997481233906 0.274289768806193 0.257831546724774 0.222244343666825 0.334317928990349 0.379288847621065 0.399635613013525 0.295310393951368 0.767454395329114 0.637641275450587 0.0484695059340447 0.498907660262194 0.932433478240855 0.358950827256776 0.183634835223202 0.357596187840682 0.343651536121033 0.987726202788763 0.0760654976847581 0.39007217384642 0.909959096752573 0.387471835950855 0.575998866830487 0.735869693171699 0.0970386833744123 0.156780852854718 0.771066449242644 0.557537247515284 0.426810571039096 0.432918422662187 0.435256224849727 0.216922197984532 0.131310135987587 0.128991490849294 0.698464483374264 0.421533371007536 0.264794391677715 0.409064938083757 0.316723542218097 0.813023571711965 0.220555222770199 0.140112632079981 0.83823589891661 0.464288806742989 0.605133367176168 0.402513079950586 0.687138166711666 0.312288126810454 0.768638335547876 0.557830775876064 0.296924007583875 0.0265216715377755 0.315588860579301 0.315099609687459 0.648177989991382 0.804663543987554 0.685908315498382 0.650902583629359 0.53041392500978 0.950701261456124 0.06389050045982 0.133161288041156 0.343336413609795 0.0397893332829699 0.810797474875581 0.4989086175384 0.569931841089856 0.711989841661416 0.514594879685901 0.255718010633718 0.0580464094341733 0.860886436975561 0.644932713240851 0.316831852500327 0.850879186303355 0.816439149582293 0.614302160986699 0.0777059583854861 0.776290498431772 0.713182395752519 0.813063299020287 0.853457351487596 0.563902099563275 0.659939032448456 0.273193556854967 0.45002307840623 0.584018661580049 0.50639072594 0.285862154089846 0.269610166137572 0.857864368315786 0.15502986397827 0.145366545151919 0.361420081930701 0.438765227161348 0.0921136473491788 0.736740495734848 0.922316583830398 0.589062913183588 0.49324556765845 0.882688374917489 0.796787103021052 0.920762125856709 0.839167130894493 0.135504512565676 0.782242245113011 0.674449106170796 0.134403976160102 0.572276543134358 0.419252776273061 0.31193592753727 0.577692621976603 0.371830768857617 0.387001477261074 0.0873265637457371 0.603670447443146 0.294153237873688 0.810906003674027 0.393437700208742 0.748646418361459 0.877519499920309 0.582812821334228 0.15994296920253 0.483226734243799 0.503990397918969 0.386148206936196 0.215651918735821 0.305976175279357 0.279558532452211 0.795689485927578 0.796218809189741 0.237230386275332 0.953242905389052 0.878538652404677 0.981410695298109 0.581654418238904 0.400992465482559 0.442051047889981 0.27115108901402 0.756196818843018 0.424684095929842 0.310530108765233 0.703942814213224 0.783791493733879 0.354680671191309 0.0304559243842959 0.415295016337186 0.185288609277923 0.298386886056978 0.869420019821264 0.20657764286967 0.472231292852666 0.460268470032606 0.676962940688245 0.186173136641737 0.870811714101583 0.605551799682435 0.908123707601335 0.234211115222424 0.995731889642775 0.222134205962066 0.184728549912106 0.67073372681858 0.288846707111225 0.460044112657197 0.858699638021644 0.538038087622263 0.548438845661003 0.557463927948847 0.860682892578188 0.56928136856528 0.0284914216538891 0.162349278298207 0.979755859780125 0.574617238817737 0.721167558678426 0.28449301907327 0.144363180925138 0.505257265502587 0.176290161535144 0.366432207270991 0.626067563625984 0.89505646164529 0.163092019525357 0.763429852412082 0.8628309915727 0.568057316560298 0.675622980582994 0.32732100518886 0.0377420209744014 0.423655418858398 0.0619055042276159 0.398846895790193 0.41859748855466 0.828334739941638 0.193872873364016 0.329862085774075 0.0177279190905392 0.444320397337433 0.823417960971128 0.0694546219636686 0.747500425742473 0.854742352920584 0.134391596340574 0.77319553225534 0.0149035568954423 0.621906854449771 0.801670227958821 0.853027749299072 0.887238262626342 0.401903921281919 0.774180004049558 0.248678247742355 0.302069447869435 0.184355102933478 0.940585742683615 0.64444286281243 0.262765391857829 0.573578777613584 0.107165656269062 0.41100285974564 0.218189817927778 0.324517170609906 0.81113719498273 0.271822544396855 0.344397082100622 0.576118919593282 0.0565969782369211 0.780523323721718 0.602586914503481 0.367761728616897 0.730882367347367 0.579088434642181 0.672345045800321 0.370838533283677 0.358167844009586 0.81617948501138 0.692927219541743 0.682359708044678 0.61724958676612 0.925642586648464 0.205079846058507 0.839088813576382 0.428909083909821 0.335855652955361 0.49878789954586 0.759041050109081 0.266473146423232 0.418511316408403 0.95597906263778 0.236660520187579 0.933937634150498 0.93422266642563 0.285910572488792 0.776362079549581 0.532161879092455 0.149288688097149 0.786351887879428 0.213936077777762 0.901068764056545 0.127367589205969 0.0765581941255368 0.691720547412988 0.821626149439253 0.577187208260875 0.382873487200122 0.587310337990057 0.406102577366401 0.538709433055483 0.47097596329404 0.992112825692166 0.670951528938022 0.745829546570312 0.329405599867459 0.150526407507714 0.31658100533532 0.376150642894208 0.370283292799722 0.345841376783792 0.926835767705925 0.874013765901327 0.705971335279755 0.441058591033798 0.444736022555735 0.959220765910577 0.739893179466017 0.342476218072698 0.583783550348599 0.76123071028851 0.284881809439976 0.473655876819976 0.448826616378501 0.819613648976665 0.979003138032276 0.176267806496471 0.297812380648684 0.512868866198696 0.512617896406446 0.653679059194401 0.1905310564721 0.751309564225376 0.60809142856393 0.457108448490035 0.458083767266944 0.0208202197379433 0.0503088717116043 0.237999070540536 0.0601766716968268 0.871022415135521 0.663914340066258 0.947762481127866 0.253258743165061 0.812808459093794 0.341658740842249 0.548758180832956 0.40505320971366 0.0391156689962372 0.69066380599048 0.251652580059599 0.234345631315373 0.0681315682828426 0.0155894043832086 0.46354265131522 0.822985315460246 0.350207511256449 0.180407800197136 0.669393494951073 0.785492223189212 0.0529965799045749 0.0863936631614342 0.775470667080954 0.914445999236777 0.342157103260979 0.812865176037885 0.523609665664844 0.675052133707795 0.718327018907294 0.453230812549591 0.570199137593154 0.38787725890521 0.466825044243596 0.494077012178022 0.344130889242515 0.773882342320867 0.107910799100064 0.511904275000561 0.376302385348827 0.0825692442175932 0.715215315956157 0.527000815358479 0.0609994361898862 0.232238908181898 0.539836502354592 0.955393031882122 0.168907632217743 0.365125856250525 0.102347881740425 0.845445118136704 0.18571033773711 0.60102940191282 0.69105713241268 0.401064975294285 0.307566621813457 0.747802493753843 0.0455799081199803 0.416963548073545 0.130450285973493 0.712060766539071 0.624070588878822 0.956354139728937 0.630589861588087 0.978473910659086 0.225433045232203 0.805447325003333 0.934846113703679 0.933834729148075 0.199768724841997 0.477169758866075 0.673011024908628 0.783767340315972 0.913058249773458 0.518815102491062 0.965479178663809 0.664063268087339 0.682199969924986 0.0183982178126462 0.574473669284489 0.789597559019457 0.847876097206026 0.768166475135367 0.856338542650919 0.261996611934155 0.110125162906479 0.440818367952015 0.028139013084583 0.890000175975729 0.909412360191345 0.16550078692846 0.345497438714374 0.694655861908104 0.883930641678162 0.678842189824209 0.70559597928077 0.0316410682862625 0.536507247609552 0.221748289267998 0.166297387562227 0.884627729151398 0.429852218797896 0.385872505856678 0.96938920294866 0.451482909868937 0.354087730206084 0.659798039931338 0.416355507802218 0.467032219744287 0.709026441609021 0.0182531977281906 0.473467533129733 0.334004790412728 0.608842697916552 0.789391105221584 0.442834380117711 0.590708046166692 0.91784930493217 0.104940270071384 0.0404098204500042 0.15707482723752 0.158765810132027 0.495693504323717 0.714134966023266 0.480810575783253 0.541863971177954 0.201980659845285 0.194464557650499 0.846103814984672 0.333019950275775 0.813986515048891 0.793605670807883 0.334412462147884 0.831607190151699 0.121718466046732 0.627464087391272 0.90482820300851 0.947184293214232 0.320099019366317 0.23459903382929 0.38221876836149 0.595098576776218 0.197211675746366 0.33251209692331 0.634275925422553 0.279525533507112 0.398327065305784 0.634535387842916 0.879696374826599 0.0495605772221461 0.12904054336017 0.921664660293609 0.19883898767177 0.984304717604537 0.512767877823208 0.912425647403579 0.643437987873331 0.557483415307943 0.284005860220641 0.0976774175674655 0.480266115432605 0.59883266646415 0.145725494916551 0.716864362638444 0.234847801171709 0.622561484775506 0.72168004028732 0.818801183558535 0.529659056363162 0.923297502892092 0.749531756401993 0.89373141043121 0.30899069821462 0.0224223066400737 0.647847621825058 0.0359767255093902 0.0136962483497337 0.170258669804316 0.747417756309733 0.0240654455474578 0.131570958141238 0.192278955464717 0.703983436331619 0.612832756992429 0.717971345502883 0.467569523458369 0.511069472292438 0.213830476820003 0.305895980750211 0.983456784561276 0.674628624157049 0.618359371847473 0.859390137277078 0.057633637834806 0.977389346682467 0.879573925761506 0.368664955482818 0.462837662452366 0.985156334075145 0.776968302309979 0.668060933509842 0.875150667738635 0.777494098194875 0.25173148999922 0.129460740131326 0.391948756761849 0.751344031931367 0.842553465394303 0.459327454613522 0.711636856836267 0.539673826943617 0.761653842967935 0.923395529082045 0.71151442321483 0.0427705737552606 0.891238011559471 0.214724857467227 0.50164906904567 0.351331074154004 0.345930098977406 0.234731361763552 0.638858219224494 0.749137006858364 0.563102067441214 0.897227582752239 0.583399065074045 0.827452460206114 0.959556322684512 0.216747416129801 0.5454939365061 0.721093693051953 0.602720399789978 0.523042667717673 0.29180782311596 0.0519227488082834 0.202312245985959 0.497949424705002 0.891220344016328 0.036163908620365 0.514007908941712 0.0495106252911501 0.318030005032197 0.363775280821137 0.361607892008033 0.48208085664548 0.645069342118222 0.416928931463044 0.593723761260044 0.918093162805308 0.798531886774581 0.973904819109011 0.89738847568864 0.521335891955532 0.641375966980122 0.137485950994305 0.904603787777014 0.492102214752231 0.418555657221004 0.503519319831394 0.42481978551019 0.922953668779228 0.13666935866233 0.141945341641549 0.173862514607608 0.414186507316772 0.714458592918236 0.563023106330074 0.765403541813139 0.882127278291155 0.660167476860806 0.111017318284139 0.802112839468755 0.48567702940898 0.25627714845119 0.820847484883852 0.873445936762728 0.121525603358168 0.13582476605894 0.127701093587093 0.965035964159761 0.847423456769902 0.585668540836778 0.486899121913593 0.838389816391282 0.623468714545015 0.847234074205626 0.0662062723864801 0.388263512593694 0.482412375248969 0.578286906790454 0.0217923266952857 0.211026844391599 0.925046600957867 0.0259307711897418 0.561561128660105 0.838572106629144 0.073911029449664 0.883610875005834 0.256949608593713 0.179256343289744 0.220348758369219 0.365107621902134 0.539534521012101 0.944503109620418 0.498480069437064 0.509925122924615 0.806853631287813 0.326883006491698 0.182929959075991 0.281967673960608 0.970707969286013 0.418460587915033 0.748084094771184 0.785214753695764 0.0780086273164488 0.516761444683652 0.38763463168405 0.504804507740773 0.244322655063588 0.312577440897003 0.102409565318376 0.247838653582148 0.166490631271154 0.0230832677124999 0.120321956342086 0.880217146221548 0.105142353083938 0.69008325842442 0.151518017037306 0.081964110811241 0.763087087369058 0.976276138180401 0.944226952607278 0.557324214489199 0.572679051156156 0.662804223522544 0.494575555541087 0.233647612843197 0.757984217868652 0.721525762306992 0.58419098789338 0.938792021209374 0.77039277204778 0.654071607671212 0.0230953607871197 0.716445621028542 0.242892463204917 0.608683335976675 0.340260406481102 0.18659953646129 0.290619493902195 0.703189165154472 0.931078474400565 0.0598448034212925 0.912043894503731 0.203784972440917 0.173089751603548 0.074797035024967 0.749176394636743 0.355580681397114 0.0562087108800188 0.522677459353581 0.78009012339171 0.26893159537809 0.760621076324023 0.678782168629114 0.140535973594524 0.919755829179194 0.201939120327588 0.375551827787422 0.152458826387301 0.580716119059361 0.937705335228238 0.936476932952646 0.522389045609161 0.145865435882006 0.802855378314853 0.678514194679447 0.299280489911325 0.109675815196242 0.976433103587478 0.142139895756263 0.475549947947729 0.568273085188121 0.615447292218451 0.775515539201442 0.691133987193462 0.954767182078213 0.142705594592262 0.357752377607394 0.31999036033405 0.147448879755102 0.208034250065684 0.0704922072589397 0.836341866052244 0.393244698988274 0.423941196347587 0.230550050288439 0.237040146242362 0.560270410538651 0.0841234124498442 0.0365401151729748 0.428268709231634 0.385184427797794 0.574755794464145 0.0936871687881649 0.206611463094596 0.204514144686982 0.0392800141661428 0.108685957023408 0.854840374500491 0.523812161737587 0.09164349403698 0.704230079825502 0.982134494073689 0.948933484172448 0.878963678891305 0.823972382941283 0.871395222470164 0.386639875797555 0.149884434065316 0.253257155003957 0.29176594406832 0.213399755773135 0.590393438597675 0.768009854329284 0.104749887357466 0.467347367610782 0.325671920473687 0.176059547404293 0.0566136543895118 0.409789094829466 0.663688342666719 0.773102438354399 0.213037334643304 0.585708275982179 0.849096059408039 0.28914552711416 0.669730829359032 0.0490674951509573 0.819979244123679 0.0149474443099461 0.85286628425587 0.240966931735165 0.598803006114904 0.230518127097748 0.191711303351913 0.512064882575069 0.0108984614606015 0.363275368965697 0.130914329129737 0.737871477811132 0.759135688145179 0.7743824309716 0.185920771849342 0.398788219115231 0.171207186921965 0.332886325996369 0.903440382780973 0.43013948394917 0.884431872467976 0.768657458021771 0.142353091978002 0.218723255195655 0.970423139622435 0.29750716028735 0.477464605700225 0.746517672804184 0.803163283106405 0.360914335139096 0.729265289495234 0.173658978047315 0.0680835652491078 0.779519592765719 0.688639814294875 0.668247935215477 0.480054707909003 0.656723685273901 0.437427048378158 0.0422554950765334 0.310058300446253 0.316774136559106 0.333608432193287 0.391823152119759 0.515797733082436 0.193179681841284 0.287198054818437 0.827697674355004 0.206190075087361 0.835844782921486 0.929689800161868 0.376241052595433 0.438677559976932 0.223778325426392 0.787199208938982 0.78175838889787 0.0869573891279288 0.878876293150242 0.0111463399860077 0.443152246759273 0.25805608919356 0.166683605061844 0.341267791129649 0.540207285417709 0.0840698778210208 0.637608732669614 0.837205446746666 0.608342322520912 0.281542333760299 0.824163297424093 0.267181186676025 0.395034654976334 0.770315435286611 0.733792226777878 0.780309864727315 0.329448464312591 0.758225425425917 0.115836757500656 0.294245841957163 0.260366620649584 0.495393765538465 0.539364199377596 0.102324004694819 0.308601263824385 0.430064197736792 0.698070506243966 0.0215994711522944 0.494293805849738 0.997828094954602 0.605697491911706 0.517200949483085 0.480504871136509 0.180165033522062 0.587687188566197 0.0939590151770972 0.937569823595695 0.989829777260311 0.942364810432773 0.673623026823625 0.644199753380381 0.775610515614972 0.331381015500519 0.152180370574351 0.218984507927671 0.868546334365383 0.75564760484267 0.907341467493679 0.0367405717610382 0.249260163570289 0.0429314724542201 0.768846212467179 0.362608524782117 0.196468702864368 0.0435989461396821 0.953424285373185 0.766792268606368 0.276707355228718 0.295599401008803 0.620345782903023 0.0298130519827828 0.514092698073946 0.17841059241211 0.173686531605199 0.0112452997104265 0.305099310043734 0.572813993678428 0.61601277714828 0.364020295585506 0.348518889627885 0.111126343815122 0.104019179735333 0.537810162531678 0.665748535676394 0.759840096372645 0.414389619522262 0.602377985571511 0.693404968136456 0.89718308335403 0.289835712194908 0.809068838963285 0.860137635380961 0.981073023665231 0.229831530016381 0.138008596142754 0.889265022424515 0.362746316313278 0.39478465721244 0.355729893397074 0.175185468019918 0.574702282655053 0.908962570608128 0.593263695421629 0.699828486717306 0.964112762191799 0.226215543963481 0.939813829541672 0.400570872097742 0.791034194801468 0.365827147625387 0.360794639193919 0.666123122028075 0.927245539547875 0.497589510749094 0.919139635579195 0.718911047750153 0.944865207816474 0.417502521546558 0.0779923651460558 0.970353449315298 0.727011574560311 0.0227391374041326 0.893418260328472 0.873852609731257 0.560249455571175 0.779310069829226 0.498007487552241 0.721612228113227 0.920269236254971 0.820396362997126 0.608173025469296 0.493466714597307 0.0641638727742247 0.281289742845111 0.362285529694054 0.783984229185153 0.11212735760957 0.458406079837587 0.747849086343776 0.0427307770657353 0.865858659364749 0.344375157640316 0.960699571173172 0.944291743126232 0.0991336227674037 0.371956007231493 0.222638011001982 0.477676381797064 0.524218610888347 0.433570517692715 0.79027622635942 0.680947994866874 0.40810406972887 0.790565967105795 0.386528239597101 0.70352606944507 0.527095077214763 0.110806151404977 0.792419816267211 0.273030831655487 0.56161295526661 0.92958686496364 0.694389735665172 0.0944941270444542 0.167092564613558 0.532766674121376 0.394931767031085 0.851636715638451 0.806656702307519 0.496436362646055 0.0416982310125604 0.151818405378144 0.219842297942378 0.106284210721496 0.547285290260334 0.635945148204919 0.453296327767894 0.538236863848288 0.202299162212294 0.133192287378479 0.106565313162282 0.688233282854781 0.588697451036423 0.615624759886414 0.468335004663095 0.466608971122187 0.200706722985487 0.0757411163556389 0.785323881569784 0.633920467998833 0.324276853022166 0.0541056354460306 0.629419358964078 0.290287928045727 0.214843282653019 0.224062582522165 0.349248002173845 0.993642556297127 0.173627365573775 0.490812639691867 0.918891452560201 0.927724892669357 0.739667556632776 0.753609316470101 0.0912458477704786 0.767719256344717 0.48484316092683 0.172165114528034 0.838188222504687 0.37984722339781 0.314024786278605 0.981169715477154 0.63793092722306 0.790611258510035 0.117442200977821 0.779615663143341 0.0116901853564195 0.173795053258073 0.483151290828828 0.788187139190268 0.109534287452698 0.321773598331492 0.340775798643008 0.0392251806566492 0.188658366971649 0.371038438279647 0.939917341687251 0.237725024698302 0.211669528242201 0.467010034124833 0.457344016807619 0.37919867556775 0.745587353615556 0.705314368121326 0.0855745975393802 0.0882483504293486 0.268243545901496 0.882533388142474 0.638273435255978 0.484448830436449 0.0435875531006604 0.174443025293294 0.353036385304295 0.602216421181802 0.15936288425466 0.120452105107252 0.0427576847560704 0.0506572259753011 0.60063245107187 0.199941451537889 0.599798995419405 0.0758842211961746 0.811440219578799 0.213685155468993 0.908446450750343 0.916481294997502 0.274245654807892 0.706655018350575 0.806880652846303 0.878910173766781 0.114146457584575 0.847333166238386 0.672550537942443 0.271977705201134 0.132641957977321 0.384982738713734 0.135347826757934 0.465817035855725 0.413995606894605 0.892346632834524 0.598935343960766 0.788853467970621 0.194348620737437 0.0488050090009347 0.265224633740727 0.219900919296779 0.987842036897782 0.806961963467766 0.910584727118257 0.592785596924368 0.472217359908391 0.29641840278171 0.321744390919339 0.34060034049442 0.768172628164757 0.220394437247887 0.336008276159409 0.0993869259348139 0.587973431900609 0.96900224461453 0.61341994187329 0.729748813095503 0.471355031072162 0.421067812759429 0.584065116560087 0.0808445220044814 0.408247551901732 0.679985677574296 0.878926160256378 0.763507606843486 0.573069795260671 0.554435877061915 0.887129153653514 0.307122317033354 0.221718733336311 0.795615763904061 0.111338165551424 0.217415750280488 0.0851658027968369 0.42067408987321 0.675199507682119 0.488979847149458 0.327976700435393 0.0812507212907076 0.939098013753537 0.125748569832649 0.630728514275979 0.887003582434263 0.877648178080563 0.135289511741139 0.995123965314124 0.10785995881306 0.265014768277761 0.950541943081189 0.998962200568058 0.0197519163182005 0.10828941762913 0.707587536531501 0.561300959750079 0.21603781099664 0.741106813456863 0.498511774572544 0.398597737515811 0.97936982391635 0.0147652953700162 0.874145613929722 0.721417612684891 0.871904518997762 0.689524034629576 0.412100218906999 0.549423041082919 0.0327903068391606 0.328411430839915 0.590950024062768 0.343222873690538 0.702978052673861 0.315095933866687 0.472782315604854 0.0758915387233719 0.492338455906138 0.991657207396347 0.103131535518914 0.564279749291018 0.292189758804161 0.252735663980711 0.80645553415874 0.416983416222502 0.809992509081494 0.270270278500393 0.916131193065085 0.676752418985125 0.466493687452748 0.60530106615508 0.178140518125147 0.498548732625786 0.173138220482506 0.0901014032051898 0.0983707974106073 0.823179430007003 0.994231727416627 0.171164877065457 0.673863087862264 0.95223333673086 0.831532007895876 0.841356962106656 0.141814621230587 0.924640571551863 0.773742490329314 0.782683456090745 0.860086346997414 0.578752622471657 0.534172758662607 0.556525314364117 0.672598945738282 0.581500391967129 0.730114543547388 0.590085885783192 0.490794089324772 0.980058413459919 0.3412903609965 0.416453312709928 0.554842110001482 0.210999760827981 0.775175901153125 0.513943159913179 0.96597954230383 0.489393326852005 0.947719061863609 0.843562339087948 0.0963276588078588 0.947847248362377 0.155822123331018 0.639475518313702 0.227719436869957 0.576478624944575 0.866944358565379 0.387681536374148 0.438950322612654 0.764603071736638 0.467975736344233 0.681373759191483 0.258808127271477 0.281466233413667 0.804615908144042 0.72015112058958 0.231830414244905 0.0212634194898419 0.120311301602051 0.413720747840125 0.671289873868227 0.795057723508216 0.311183570674621 0.524863869450055 0.6946193809947 0.785228226787876 0.269040760593489 0.526093161464669 0.232434361255728 0.585278546556365 0.753404135967139 0.396211921460927 0.596364293692168 0.115957189209294 0.948460743471514 0.82360025604954 0.170427137508523 0.562791921705939 0.0138320723129436 0.150535339703783 0.97389324166812 0.907426307105925 0.587248551377561 0.345265989704058 0.454531173966825 0.0710608247155324 0.819527449861635 0.836785093925428 0.019031928437762 0.77061013114173 0.666479242837522 0.988079870592337 0.362752166693099 0.142756933455821 0.142065437047277 0.24228032713756 0.134348991671577 0.511160686907824 0.267246019376908 0.683758318778127 0.946726568127051 0.643584195505828 0.492507436708547 0.813518307176419 0.873333684660029 0.805834616643842 0.922579827641603 0.387944821214769 0.267915933160111 0.0295404124353081 0.491503811322618 0.749297228571959 0.758095680270344 0.727162221898325 0.161037214738317 0.781622505465057 0.885196352831554 0.776030021109618 0.436030429415405 0.845751118056942 0.0375697518256493 0.158139925983269 0.944979186151177 0.216610345609952 0.550972755779512 0.733607657793909 0.671286055136006 0.293396954864729 0.905009302932303 0.647359705541749 0.860636135640088 0.282913011529017 0.782972539444454 0.936657382629346 0.601387406387366 0.0929439054732211 0.0399551940057427 0.564436453077942 0.780935339503922 0.375328815854155 0.822521034886595 0.52827535221586 0.432294489946216 0.671914825174026 0.433246536515653 0.367076775017194 0.517969816997647 0.053406060161069 0.244506032119971 0.156010476702359 0.178163676464465 0.386480340750422 0.496994520828594 0.666418327062856 0.902062847567722 0.0419455395056866 0.833260789485648 0.329492357259151 0.0850516331451945 0.879246360734105 0.757455252576619 0.72470067453105 0.375642305717338 0.85891066913493 0.805610321965069 0.757783936462365 0.591491720229387 0.915909486236051 0.746584762122948 0.975552799487487 0.0164540363987908 0.141178625635803 0.235160809054505 0.5977875780873 0.106885598234367 0.294279379125219 0.954151512410026 0.1397234102129 0.0337662705616094 0.0442607400170527 0.0772328544128686 0.357778641965706 0.991282078442164 0.828202775740065 0.278042179280892 0.557465986795723 0.978157450773288 0.247046526537742 0.113667794126086 0.933965148983989 0.183332817230839 0.0186483478848822 0.553421190790832 0.637116198041476 0.548777859278489 0.380782240454573 0.74369998664828 0.814880727198906 0.346270764835645 0.342545830700547 0.564541836441495 0.171369958682917 0.393234446705319 0.170297103072517 0.753479285261128 0.917715813191608 0.652298970706761 0.728478530158754 0.415493929712102 0.874328959176783 0.372540353245568 0.631312836317811 0.316309756408446 0.960941877765581 0.858071417962201 0.768674814847764 0.343410295371432 0.695000223640818 0.418122810942587 0.0714860743284225 0.0895039024227299 0.633113943547942 0.331969600683078 0.333131835418753 0.264643216719851 0.885578783638775 0.0940446442598477 0.50095763325924 0.776538384563755 0.815097519718111 0.264082515174523 0.925993220580276 0.516917760074139 0.840616646225099 0.208376535433345 0.5502321386314 0.211881858466659 0.283251826222986 0.0927239705156535 0.753549492585007 0.649098520667758 0.749015699471347 0.342696142888162 0.354432580834255 0.532780445483513 0.762196654765867 0.683345265735406 0.658185681384057 0.90613886119565 0.976215365317184 0.573227610990871 0.68866134713171 0.992298620718066 0.735098111492116 0.0177722041215748 0.778160234505776 0.149609751345124 0.981712870262563 0.0968482077680528 0.668272742107511 0.221001867149025 0.0447626567818224 0.821016071757767 0.0310071744117886 0.570806516322773 0.633176297196187 0.224140035917517 0.670683830899652 0.400259550570045 0.572942481213249 0.939651684747077 0.0980293264077045 0.849175826355349 0.972716176412068 0.0272140078968368 0.598680621359963 0.46808742210269 0.906912446401548 0.457083045518957 0.917202581989113 0.774670921242796 0.225669653115328 0.436095598880202 0.817116611164529 0.811279079082888 0.0537760173343122 0.726166133016814 0.635258072139695 0.339697731835768 0.883052448288072 0.574123039271217 0.87354225769639 0.024925904548727 0.839820491843857 0.780520941019058 0.844814638232347 0.0161112570646219 0.403437577802688 0.883113209856674 0.693752376649063 0.870666707616765 0.22423472766066 0.150624664430507 0.577373100097757 0.691434899696615 0.571086735478602 0.666361533361487 0.100543380593881 0.937884519908112 0.464818919936661 0.513861034696456 0.846913340345491 0.172471302768681 0.210635401173495 0.196263164621778 0.437273474121466 0.395548215566669 0.739429100812413 0.499582471067552 0.0274784676078707 0.657489240239374 0.46240116040688 0.343085491531529 0.245874783580657 0.28830988837406 0.30917065968737 0.877447451113258 0.483504416490905 0.754194094676059 0.820090867416002 0.666538078559097 0.220532993816305 0.520986588713713 0.578437715710606 0.995133199468255 0.806790809489321 0.946091464576311 0.818380601617973 0.0291194503963925 0.0125900319055654 0.229266799520701 0.362418464771472 0.397924045338295 0.195215745174792 0.794565650806762 0.0522648467775434 0.460734449408483 0.184680429783184 0.254110801047645 0.973965305918828 0.214155606820714 0.995787360721733 0.979122100749519 0.249643021498341 0.872553472050931 0.0671234778361395 0.874578284334857 0.342816415550187 0.158448058511131 0.878339890008792 0.391042010816745 0.806218663272448 0.0246839745971374 0.173568742375355 0.623697653845884 0.155639361715876 0.769778628305066 0.781412536967546 0.89439897170756 0.406281857013237 0.38989774604328 0.769434205028228 0.684502889271826 0.709676155780908 0.497025913402904 0.854605508984532 0.490084335287102 0.880931773539633 0.928032643024344 0.967212772450875 0.381153447641991 0.64363700912334 0.5445074249967 0.766500117727555 0.634227320777718 0.0428553296951577 0.0597482831031084 0.892762901154347 0.936420757689048 0.973286996548995 0.908140589131508 0.407499532401562 0.0888976891129278 0.26872697730083 0.741708636849653 0.800900799862575 0.205707370692398 0.641869302373379 0.460267603343818 0.750179169008043 0.383673618207686 0.140786011696327 0.95197730464628 0.818867866962682 0.891335745933466 0.392700889115222 0.364506461203564 0.626978856460191 0.327548875650391 0.131493965520058 0.521993927261792 0.459240448740311 0.2149752673693 0.0144690484646708 0.0698476222250611 0.76816120700445 0.390186829857994 0.988307569790632 0.41119225153001 0.392907825354487 0.477281738976017 0.612527747771237 0.740936088212766 0.990997130069882 0.652986868051812 0.880414871356916 0.374995762796607 0.212102720274124 0.964417146290652 0.711853040829301 0.380429514253046 0.414086464231368 0.990773566544522 0.505029630844947 0.0728211330319755 0.679007850931957 0.939606905980036 0.669564524227753 0.317129932360258 0.902223837545607 0.03558688336052 0.0530932316090912 0.146178536887746 0.38999521764461 0.492070208580699 0.87300834674621 0.903536806288175 0.325808125687763 0.983934009915683 0.289830282712355 0.496214222703129 0.520403923061676 0.298218763645273 0.458598147754092 0.429812565941829 0.780985120171681 0.813140837240498 0.523298184399027 0.555011414429173 0.133102471451275 0.940202076844871 0.647343160314485 0.417474511594046 0.241663951671217 0.66028332917951 0.7287125856895 0.897659550816752 0.888651270766277 0.264154422914144 0.0841733507812023 0.623486591614783 0.671190224480815 0.933862140947022 0.228576328617055 0.184576881909743 0.812752070154529 0.531806645717006 0.824595886692405 0.677559916155878 0.0284322037594393 0.662895864336751 0.68426863251254 0.190782974320464 0.70960068608867 0.895467730369419 0.115721500799991 0.30080317129381 0.757975191627629 0.584305785663892 0.234987783858087 0.913832298519555 0.579801794658415 0.182545412257314 0.714666243945248 0.254283723901026 0.463534450042062 0.658756579430774 0.0501938999118283 0.0679359220480546 0.934026093340945 0.491028472629841 0.0127439636713825 0.223792860673275 0.14462589481147 0.721002721847035 0.615720748666208 0.561827514448669 0.210701109552756 0.997479268622119 0.429331081134733 0.620325574071612 0.119521221187897 0.904715083295014 0.673112720234785 0.29485425103223 0.178550061769783 0.369687627046369 0.139578172073234 0.27952610630542 0.101745237528812 0.590167519107927 0.792595666961279 0.389494566337671 0.903548631288577 0.863185509699397 0.119703700207174 0.899490068070591 0.364529486312531 0.983401906103827 0.548930840222165 0.744181145064067 0.321991874363739 0.4249605800258 0.879987407308072 0.600908056262415 0.566322611060459 0.419799703459721 0.50053228890989 0.329746313670184 0.608563910180237 0.353012064311188 0.301800800161436 0.169983744134661 0.30089109917637 0.199994409219362 0.897716720928438 0.675817992014345 0.907296073976904 0.750419789936859 0.623663010497112 0.493044313071296 0.514215394698549 0.456667349305935 0.882822332503274 0.144945341777056 0.736249120763969 0.252820561449043 0.309935684727971 0.0560429209214635 0.679608935334254 0.81476162110921 0.109342562754173 0.250132700433023 0.395432357715908 0.0285903341253288 0.263125002472661 0.759662699007895 0.035443898611702 0.864834992031101 0.479496511924081 0.166265991299879 0.611067193683703 0.23283595648827 0.952222658249084 0.618384979504626 0.154029051412363 0.324981887063477 0.153681473941542 0.186097648739815 0.934927907227538 0.178360640711617 0.490529090929776 0.823526831374038 0.552934174388647 0.220435711687896 0.785139031372964 0.0698047439497896 0.436940616760403 0.755007621557452 0.036902854857035 0.964987371731549 0.0634980063815601 0.945392062168103 0.631146959459875 0.973065379615873 0.158781752365176 0.0834101395634934 0.814002981674857 0.680140134193934 0.656457792990841 0.0161991086509079 0.751719050013926 0.939423436722718 0.290417450766545 0.955001439759508 0.905194527003914 0.860615383514669 0.862796200932935 0.99749636198394 0.621623075876851 0.294782052398659 0.170968973820563 0.964385764088947 0.105948930780869 0.473354683334474 0.536865296801552 0.543829936445691 0.31652353303507 0.0872004586830735 0.12970001262147 0.527391449743882 0.756645518841688 0.694341365902219 0.545134519052226 0.514704861801583 0.191809994080104 0.896364679504186 0.0114165509608574 0.339240068753716 0.882382558477111 0.396882716224063 0.320956451410893 0.173163546235301 0.693513066587038 0.910727137455251 0.0783054391830228 0.372823183070868 0.943889203064609 0.654046259790193 0.565693379787263 0.747156706650276 0.383046405904461 0.660089069185778 0.846580901346169 0.98756459068507 0.806691696480848 0.356508043471258 0.104619841396343 0.12570648863446 0.594137378111482 0.752540559191257 0.207059529903345 0.478695455680136 0.392401822705288 0.510850324730854 0.145221376162954 0.165006977391895 0.84783356560627 0.247009573094547 0.0878013791982084 0.802052437714301 0.420174763493706 0.323036892206874 0.736478633093648 0.559087924559135 0.346020168918185 0.270416198696475 0.207701563967858 0.206186932187993 0.290805453967769 0.910832914055791 0.772197252449114 0.514517110502347 0.949608022754546 0.369898007912561 0.513160243050661 0.633644398115575 0.560267691302579 0.820566103765741 0.0600730479881167 0.971375325645786 0.564895444314461 0.426232316510286 0.962024008098524 0.247059314807411 0.0969526633596979 0.304268226721324 0.724265283506829 0.234255753152538 0.388293472134974 0.250213565723971 0.103609920069575 0.231281968047842 0.861681660357863 0.886147483384702 0.241585547914729 0.723719145560171 0.853717111025471 0.0868389729317278 0.777810068032704 0.472698194929399 0.169965300951153 0.602117898950819 0.462686197522562 0.601462182498071 0.406445388740394 0.542199139324948 0.795626605581492 0.712355439574458 0.0502694926923141 0.289862827337347 0.896012860790361 0.922857389796991 0.779719862877391 0.961194795072079 0.893467921365518 0.685127899586223 0.324370090987068 0.0961451793275774 0.0895377542264759 0.270203113115858 0.430440448545851 0.928926209998317 0.134371334263124 0.199567060421687 0.463866431263741 0.734190446764696 0.511449269379955 0.482014786608052 0.724645147901028 0.068321892679669 0.225268092458136 0.347845608897042 0.860901217937935 0.21017139835516 0.0969388166232966 0.514944119309075 0.881138021959923 0.105489604163449 0.299176952410489 0.986789723886177 0.0696045316942036 0.327150728963315 0.848410900891759 0.399168420964852 0.426800389289856 0.753328288942575 0.950437823100947 0.751135362545028 0.290663007902913 0.486447945397813 0.993403004438151 0.712689277492464 0.716541100167669 0.886124782362022 0.283137234521564 0.0308197437413037 0.521281241464894 0.588113670444582 0.593447507205419 0.325680277566426 0.110420455301646 0.0697234695171937 0.752536424209829 0.588387266115751 0.67554219458485 0.842519561497029 0.691338709227275 0.882426269787829 0.505582046061754 0.354070903996471 0.214461369093042 0.165968201872893 0.485389920768794 0.171724413882475 0.544464621634688 0.580427049766295 0.847039249250665 0.770934922304004 0.25713258757256 0.860786684323102 0.310657646399923 0.288966221190058 0.0784262950159609 0.555187252906617 0.758947431123815 0.149150909935124 0.973160552186891 0.403154543521814 0.900594840187114 0.0819272145326249 0.374800962274894 0.597236397671513 0.828839427344501 0.211884095030837 0.0342873061122373 0.79419749362627 0.184643339652102 0.46273507761769 0.461395807866938 0.629507812391967 0.182826124688145 0.344600076749921 0.809766503844876 0.336224851545412 0.934203183676582 0.399137264655437 0.12193401131779 0.120332898518536 0.0249059762386605 0.889852940302808 0.870560567053035 0.684874866798054 0.713277210814413 0.893061879512388 0.64353965576971 0.469885326272342 0.142036072432529 0.923666441475507 0.457083882933948 0.165818888451904 0.186881890760269 0.949191067076754 0.364421405841131 0.806713810644578 0.279998932061717 0.0403556088358164 0.65765758854337 0.789143258966506 0.628658662757371 0.43225868048612 0.434638667597901 0.510073326937854 0.319191017413978 0.521438045520335 0.418496528069954 0.769395110448822 0.0487773503339849 0.500895422752947 0.98866534168832 0.762225849730894 0.570228298674338 0.4195250474778 0.672871830540244 0.204138732445426 0.417826841562055 0.445097647760995 0.918721326161176 0.728710006137844 0.830510321268812 0.125564542298671 0.917178057001438 0.417738346874248 0.994081443580799 0.485392645767424 0.537907328486908 0.218362867787946 0.49168876524549 0.476636768081225 0.600860634786077 0.190567547297105 0.812305650515482 0.36912385036936 0.519932772365864 0.125536802955903 0.84082245784346 0.590681010317057 0.263794549987651 0.976461938507855 0.816759593931492 0.892706485707313 0.892811163272709 0.718814924356993 0.128051481572911 0.740955561280716 0.222854106251616 0.681377714150585 0.787446166377049 0.403701953841373 0.332368631807622 0.738009616017807 0.75477766320575 0.0776781664881855 0.422775439075194 0.300624964635354 0.858778511772398 0.659505245720502 0.0807325372844934 0.856331872143783 0.230857622926123 0.339568904540502 0.78808958299458 0.620601021137554 0.874819343448617 0.170561187295243 0.65002241690876 0.557892592223361 0.926239312712569 0.629641913119704 0.545414862448815 0.829440556694753 0.715404097139835 0.508892997307703 0.609429242000915 0.486452505195048 0.234011598161887 0.927999194599688 0.351100871700328 0.574022593037225 0.684157403148711 0.706430367315188 0.163736841054633 0.280701713173185 0.26926874446217 0.723268810608424 0.393008337281644 0.506086470922455 0.546668642340228 0.540125156051945 0.268758506332524 0.0879044600739144 0.260690845237114 0.0909098505065776 0.0268698951066472 0.056113074538298 0.0170412136730738 0.700011269308161 0.0354265272640623 0.843725602049381 0.471451696606819 0.747684193269815 0.654024695144035 0.789040598988067 0.113951702702325 0.984728757310659 0.332267448657658 0.986145970043726 0.734819810807239 0.723198615270667 0.820365232273471 0.80571364694275 0.300659095346928 0.0299721771967597 0.855694864643738 0.738996863290667 0.696802957986947 0.24453644920839 0.39762756862212 0.620274754760321 0.472332053261343 0.734687960934825 0.432031160849147 0.316595849916339 0.715888339907397 0.586130865598097 0.309369894382544 0.326698375272099 0.903942939420231 0.586189300245605 0.783111764700152 0.940043099613395 0.363165435947012 0.997058891828638 0.781396440067329 0.704393442133442 0.0702598537574522 0.38206505027134 0.273472359573934 0.991956306998618 0.489989844080992 0.280302978935651 0.246706289644353 0.564338834646624 0.331913337367587 0.658108615693636 0.648368232098874 0.487943455395289 0.0596505814604461 0.817505672601983 0.979452680055983 0.479394990166184 0.694090118585154 0.522747077974491 0.420285905036144 0.460811635882128 0.543035556701943 0.675557814114727 0.0628046929230913 0.397313693820033 0.426514328974299 0.332191223839764 0.950497632694896 0.398596408439334 0.745114330779761 0.723130023307167 0.500500585618429 0.666347977749538 0.641907100377139 0.920271036708727 0.930570604451932 0.0154117940342985 0.468342907896731 0.591790341769811 0.173796252100728 0.980581465905998 0.566187425358221 0.0800842962530442 0.194126118444838 0.143528042605612 0.514744302134495 0.986004974530079 0.836377331602853 0.348852621514816 0.90856661207974 0.785613048134837 0.292821070360951 0.21597177622607 0.859740046509542 0.545769946458749 0.187040132458787 0.0448598474008031 0.358539883079939 0.384907677471638 0.347858962588944 0.19248709861422 0.833294603487011 0.893222458043601 0.199658840459306 0.205387888690457 0.701910986590665 0.724323532369453 0.580954637806863 0.694388202363625 0.181455245921388 0.247314078898635 0.914951544799842 0.925802100258879 0.316579393432476 0.582779886929784 0.828183121266775 0.834827065544669 0.323299476781394 0.0924392415815964 0.940386073030531 0.494570732510183 0.555677414974198 0.315812475737184 0.614815387118142 0.451346365816426 0.30770224777516 0.542753341165371 0.324914924290497 0.397089864525478 0.398633434721269 0.165188333403785 0.942363474441227 0.448077508446295 0.177819058874156 0.402085953357164 0.962965211377014 0.806130165357608 0.13847162762424 0.0662659957725555 0.978533965046518 0.0642046313500032 0.560618568875361 0.381095597087406 0.478465509084053 0.529278325280175 0.906776467079762 0.904664132136386 0.715027801613323 0.199721756994259 0.532539804039989 0.306232799524441 0.572964418581687 0.800315623118076 0.536119098039344 0.189671502653509 0.552770221994724 0.296178622494917 0.283839178679045 0.208037081786897 0.835011210865341 0.453050666444469 0.11319158367347 0.316499824486673 0.0221741522033699 0.333900256911293 0.281648242438678 0.215034909849055 0.763554363781586 0.279403221821412 0.46177070493577 0.622670629937202 0.412042765738443 0.586782825093251 0.454366023652256 0.882765795581508 0.670795238211285 0.583331670109183 0.272080093417317 0.106859045056626 0.633241144418716 0.820149983889423 0.412653791937046 0.628980991693679 0.900444820737466 0.165900973791722 0.196029248314444 0.965424992635381 0.29694600580493 0.802784128659405 0.183320452854969 0.126719034691341 0.0943673751922324 0.68669445247855 0.820915238510352 0.237528806587216 0.238334664425347 0.359399530482478 0.46805557198124 0.417544217575341 0.406905448585749 0.027698184279725 0.123953638912644 0.470199899496511 0.267925010111649 0.64123974240385 0.572546552650165 0.792577655969653 0.92696759107057 0.710371510798577 0.0279367857775651 0.220020284701604 0.532754603405483 0.678520877172705 0.603903620610945 0.911159768674988 0.744812629958615 0.789856595702004 0.354856344398577 0.0881597119080834 0.809202354445588 0.379962010795716 0.773786440670956 0.6027072950406 0.605514277589973 0.55175461740233 0.274105753949843 0.864853406171314 0.765346441082656 0.456898093670607 0.423016872755252 0.70351234810194 0.728068971761968 0.907345413924195 0.133163596061058 0.994096284473781 0.551534202077892 0.925517062912695 0.43353297554655 0.310035446139518 0.538757229559124 0.104539334767032 0.315860812307801 0.921237605155911 0.960252590030432 0.175361731313169 0.119327965262346 0.582352229489479 0.488824898868334 0.392637512497604 0.936264541414566 0.632346979982685 0.11960539188236 0.37456433871761 0.0990996764576994 0.718120691885706 0.619339089761488 0.83903330469504 0.897210783050396 0.572953706677072 0.448483657713514 0.932461449468974 0.496884579742327 0.0317128340364434 0.977509526913054 0.660539365874138 0.0125366807566024 0.168147212152835 0.971125320736319 0.167933835908771 0.981778169730678 0.799441822180525 0.693468702493701 0.793300828470383 0.729262169415597 0.944376606249716 0.813068070879672 0.0138533665798604 0.431583106718026 0.938539928640239 0.302692671790719 0.489172752941959 0.272568823373877 0.143437703668606 0.294117336904164 0.819869336690754 0.226229317169636 0.892635023067705 0.512862960959319 0.218737399741076 0.450176501222886 0.602242313970346 0.860747472418007 0.323209670765791 0.497441470853519 0.848172979836818 0.860860627628863 0.15967872985173 0.448465386023745 0.701986906684469 0.0185230364417657 0.887397997288499 0.936977113804314 0.50472831957275 0.759197658007033 0.937996657451149 0.113380860437173 0.381809295250569 0.0120783063443378 0.992012525366154 0.248406408729497 0.107629648023285 0.471691765021533 0.430031273013446 0.0303868163260631 0.895107174925506 0.2769483080809 0.713332344898954 0.976226315100212 0.248189363810234 0.537064460963011 0.533384491840843 0.540574993810151 0.418333959612064 0.678054907938931 0.409445003245492 0.825111859489698 0.92439585413551 0.940649399131071 0.57030856189318 0.969057228872553 0.810739470575936 0.937564324731939 0.716534588015638 0.379791692618746 0.700899022321682 0.0356075103231706 0.26827273763949 0.104551462647505 0.902429279668722 0.0101118321274407 0.435784072435927 0.363427907114383 0.148573996468913 0.117351617708337 0.270922801343258 0.769859024523757 0.337028118767776 0.172880519099999 0.858656916026957 0.97348533482058 0.448028080216609 0.687938087962102 0.0292232578154653 0.678039116223808 0.625918880167883 0.259492089250125 0.823896216209978 0.700085526558105 0.87947561720619 0.69027855083812 0.549570986933541 0.120765752173029 0.097118486049585 0.656607432111632 0.137928601228632 0.803525349954143 0.187860352206044 0.506242404370569 0.364639517294709 0.322082151065115 0.248938898863271 0.130903877001256 0.230289280689321 0.806410193427 0.991038570241071 0.0841819054144435 0.423610864831135 0.619099241015501 0.192862590379082 0.912940304493532 0.330907235234044 0.929126999201253 0.926777050693054 0.649247368704528 0.549495976401959 0.873497584038414 0.0273563234973699 0.0196367873158306 0.452242638426833 0.224971665299963 0.577316734900232 0.946007874517236 0.860601661480032 0.606979580025654 0.923202502736822 0.722073217805009 0.129509948692285 0.684623751328327 0.937071131789125 0.323512162440456 0.495728152743541 0.671965566806029 0.561560736114625 0.24531550815329 0.674331443256233 0.159542766204104 0.673311092159711 0.0512202761089429 0.698876345872413 0.824457632312551 0.999727515580598 0.715605877041817 0.547686050613411 0.357293399279006 0.247005171652418 0.911597862800118 0.907458774051629 0.153540834554005 0.191768774499651 0.83235166821396 0.695872799227946 0.710287980670109 0.814926622058265 0.318858920710627 0.0295068837958388 0.685729906689376 0.7109053864819 0.420959452688694 0.545601596771739 0.813958865832537 0.217866252807435 0.411368273256812 0.193778221267276 0.150882024900056 0.386709059460554 0.0274995025596581 0.386251834102441 0.222897189443465 0.504335584389046 0.9614739778894 0.112358693904243 0.231250477279536 0.749822621538769 0.342083236251492 0.814080832456239 0.693469324389007 0.816980330115184 0.488904508382548 0.0901597820711322 0.352669187244028 0.773120868399274 0.761926071529742 0.653514968499076 0.64978461133549 0.873103842481505 0.288848645174876 0.297905877237208 0.78828913877951 0.125137885008007 0.12670087318169 0.941807128929067 0.235133083541878 0.843532999597955 0.223984385756776 0.884518719755579 0.616020447805058 0.212624145834707 0.424763518737163 0.487662841619458 0.955083154221065 0.988860035487451 0.546551425908692 0.951459191404283 0.235697457680944 0.964727642850485 0.950742759022396 0.638478465240914 0.720390857080929 0.818566791494377 0.941099231818225 0.7711203618953 0.0826539966999553 0.0191659132228233 0.676132214413956 0.757103958716616 0.235905156421941 0.430495955122169 0.353578985270578 0.667504094492178 0.217355552520603 0.554097833167762 0.566509632589296 0.494187177773565 0.806999975147191 0.1295442511281 0.83191174851032 0.076143353767693 0.168923912136815 0.254891686493065 0.567311200087424 0.221332160632592 0.181527367567178 0.314886366904248 0.125280823425855 0.584418336036615 0.351796951186843 0.883684550006874 0.926345903908368 0.105407364156563 0.551864303553011 0.820947715598158 0.646610194460954 0.631862463839352 0.476347174856346 0.134479103325866 0.926644715382718 0.110047157227527 0.194195368262008 0.633506341506727 0.397307355236262 0.14760444970103 0.561171664074063 0.0895938923791982 0.89831029579509 0.779729436330963 0.62216095331125 0.727228098544292 0.686822994181421 0.156142603869084 0.921591463354416 0.11302526563406 0.586777779858094 0.245973921022378 0.35815811335342 0.843122242589015 0.279215863298159 0.621652730233036 0.692132707259152 0.511826140470803 0.355838927456643 0.623371346208733 0.864227171197999 0.926565303870011 0.21392369749723 0.732082525480073 0.226587018994614 0.0426837903168052 0.585672933980823 0.253306483656634 0.127302339987364 0.0560042394022457 0.126617160725873 0.212397251781076 0.132664897108916 0.604472027849406 0.419243671200238 0.0822893228707835 0.0322819913295098 0.34141878537368 0.487507256229874 0.783906865916215 0.77048552549677 0.886138223644812 0.179219066912774 0.381190521176904 0.100828006954398 0.325301891614217 0.0958536544931121 0.951250359052792 0.83468367050169 0.656300864233635 0.543862375731114 0.290966536146589 0.0154360852926038 0.832017195262015 0.103031919093337 0.53306552846916 0.102616384231951 0.904286579450127 0.296781597477384 0.795668409715872 0.153334788514767 0.0578178606042638 0.626382318024989 0.0272341231442988 0.853647079574876 0.30043724214891 0.966792184517253 0.374066166463308 0.211400329172611 0.195935875505675 0.374152637340594 0.155238554570824 0.426614840440452 0.858586139131803 0.861142738517374 0.960521151761059 0.511617641195189 0.701190649268683 0.143408414658625 0.600026511368342 0.601911931512877 0.0768984367814846 0.193092739817221 0.911232891853433 0.0248033837974072 0.769658494866453 0.231027448519599 0.786027543661185 0.874855969578493 0.0641510520037264 0.546771409963258 0.991947434272151 0.0765055757435039 0.840255191822071 0.30506259447895 0.450240537538193 0.248306288195308 0.47312148204539 0.549262668620795 0.145312628811225 0.150823395478074 0.0371149734803475 0.896255341642536 0.427144585752394 0.686406351525802 0.745441575639415 0.345665231968742 0.510202962143812 0.70585176080931 0.379959443691187 0.752187010326888 0.643732626333367 0.369124775144737 0.958095716503449 0.662106310159434 0.649987224042416 0.259255444025621 0.299766435169149 0.80841645718785 0.422083635176532 0.57193738038186 0.620040796732064 0.700282472595573 0.899933954488952 0.127286754110828 0.35121645064326 0.514508432089351 0.270531529618893 0.206404144451953 0.571248167098966 0.63063796996139 0.43522232072195 0.324090883736499 0.591904454026371 0.537208333145827 0.189097342537716 0.911145749292336 0.0242600086517632 0.515899072282482 0.510474981178995 0.271682648379356 0.240484369790647 0.659326343636494 0.628004940610845 0.615893824112136 0.448463472393341 0.343082704066765 0.267309667987283 0.282329475730658 0.538279672050849 0.134353258500341 0.646244539383333 0.553820946614724 0.233630156670697 0.819041159311309 0.330824752969202 0.922014968986623 0.349065075519029 0.243348187762313 0.0663474977109581 0.122606022211257 0.701104491874576 0.522256115602795 0.172908785832115 0.999960341381375 0.259693647408858 0.789745161191095 0.313822258627042 0.158180075571872 0.982245088864584 0.794357996091712 0.677241444445681 0.331509432040621 0.239846779350191 0.414704178685788 0.355397790009156 0.646957252149004 0.639109570959117 0.63233047394082 0.846494449139573 0.551043195910752 0.361483217442874 0.40015752608655 0.712942059033085 0.633240073043853 0.814872420355678 0.036776979144197 0.505281787724234 0.830799635816366 0.963647832293063 0.779490440443624 0.582546555637382 0.70683761354303 0.163706605371553 0.10688075123122 0.0812513807578944 0.353769092764705 0.535963480379432 0.897349769736175 0.889476201289799 0.995045756332111 0.0141454824223183 0.705216505127028 0.223892090085428 0.587965314530302 0.986760430035647 0.771656882823445 0.5180013617035 0.496969974634703 0.8710682035028 0.67711622820003 0.438342676500324 0.513409321571235 0.981028053350747 0.426613528421149 0.33789466925431 0.996461331807077 0.893924259289633 0.543330173725262 0.420375432604924 0.785026793330908 0.397801239455584 0.545189662587363 0.970356374389958 0.191820587967522 0.994648025010247 0.393014893920626 0.0131270972802304 0.445058666819241 0.468872256514151 0.464361122471746 0.131445569940843 0.788165414114483 0.593797910865396 0.770517205968499 0.687393335103989 0.307196294222958 0.942936518003698 0.694251317628659 0.995581390287261 0.183109817053191 0.175420071685221 0.704134951741435 0.959843558561988 0.261305403653532 0.977359866816551 0.601973744172137 0.343880035853945 0.0679113956773654 0.547791980498005 0.0734165364736691 0.731903973529115 0.883964725597762 0.811557399360463 0.469704438410699 0.777902997354977 0.87787023435114 0.663382828645408 0.5762148613506 0.915719906131271 0.86313199051423 0.607980193437543 0.600071802311577 0.996933085727505 0.286963496562094 0.416814453860279 0.20276871667942 0.281137419755105 0.523432982165832 0.202509750300087 0.42358302222332 0.915816667324398 0.0964562106528319 0.8025258653122 0.49702720098896 0.105980398959946 0.875297307563014 0.684859980496112 0.124684859863482 0.395499693902675 0.697534464760683 0.859845918307547 0.204536882590037 0.047804328512866 0.764218282890506 0.629289188762195 0.442600755165331 0.269371345201507 0.0221539735677652 0.979424478325527 0.418435622898396 0.801726732149254 0.22862175463466 0.781050914989319 0.252981717158109 0.839491451370995 0.409414774477482 0.934741078629158 0.834243199205957 0.338434201234486 0.409527823657263 0.687775128111243 0.371650566279423 0.0573500634869561 0.590777771049179 0.278282867746893 0.980598297647666 0.658573125617113 0.190892974645831 0.259244205653667 0.884517590755131 0.878614152753726 0.50798470699694 0.439524607660715 0.743676566227805 0.912005062927492 0.745866158639547 0.246893543519545 0.0615516418800689 0.969128371113911 0.742844218369573 0.702042082950939 0.202334100604057 0.843911688430235 0.766281114690937 0.960550550720654 0.774904304398224 0.823078242707998 0.982779453443363 0.315844368501566 0.436660624418873 0.52511259207502 0.880564772789367 0.862287791147828 0.858327271637972 0.673869893443771 0.21325599123491 0.2716413299134 0.0700990011589602 0.352398558368441 0.523308241216 0.460738156116568 0.673295649655629 0.552703083809465 0.236952301801648 0.44253347084159 0.35734538170509 0.554066526570823 0.19729897090001 0.998289089486934 0.0770115037099458 0.363161675531883 0.0669341939268634 0.223787282747217 0.834896369299386 0.300136389576364 0.667168056659866 0.280538587130141 0.694199769238476 0.880553433687892 0.264377561162692 0.544957508239895 0.0992675487743691 0.665037370964419 0.687755120738875 0.061777477466967 0.29708272826625 0.909374705790542 0.575754020102322 0.344146565706469 0.0766332763433456 0.535347604872659 0.883526222100481 0.638328237186652 0.79671563992044 0.528594692919869 0.849595646716189 0.82200876718387 0.967295832354575 0.82005419841269 0.154975550251547 0.849441958591342 0.892079869022127 0.576050246262457 0.291607721270993 0.324613836144563 0.655636736059096 0.0162336097797379 0.389815683292691 0.475852313537616 0.77500095310621 0.987798459969927 0.835533565811347 0.476854717952665 0.533797797283623 0.605567639111541 0.475337066592183 0.757389384689741 0.0990050529432483 0.455198092602659 0.0664309849659912 0.597116764883976 0.796127542250324 0.520898172627203 0.303256213816348 0.057147451932542 0.0979214891162701 0.0177378742559813 0.33146268985467 0.182186787961982 0.910324044418521 0.416177661649417 0.617867210863624 0.587402453869581 0.729215007715393 0.955556371139828 0.480860252263956 0.615703080431558 0.451805401539896 0.222450659854803 0.838124870781321 0.562133660507388 0.196540580638684 0.522745132765267 0.687451782198623 0.832265147548169 0.659058236225974 0.80697820604546 0.165057523096912 0.277111870234367 0.623522646098863 0.423463399577886 0.226666536538396 0.748782452312298 0.867551766568795 0.148064221418463 0.942944986429065 0.352025807967875 0.48222209303407 0.576491873527411 0.358783161009196 0.819815944742877 0.116378915593959 0.227489107639994 0.618657869838644 0.909123499733396 0.780776862232015 0.864368033711798 0.583641609544866 0.927862375096884 0.71078148801811 0.550054121906869 0.0272477956209332 0.398347371639684 0.245310936139431 0.766919705972541 0.12495724816341 0.0769617550820112 0.0522226231289096 0.89693357125856 0.452254821397364 0.664997096213046 0.0637572890101001 0.743884054059163 0.383443324475084 0.310685653125402 0.693504367889836 0.715324646211229 0.98341551035177 0.560102471606806 0.451535800013226 0.972459919126704 0.521391817815602 0.209301576348953 0.0405513424309902 0.289442572940607 0.935843921902124 0.0977817466133274 0.508633526128251 0.0634296089620329 0.803926823020447 0.378288696827367 0.442588987560011 0.0865031047491357 0.590756116968114 0.107612106795423 0.637172923514154 0.454852463568095 0.203225556637626 0.0577191069489345 0.716522932664957 0.754095097840764 0.926430706179235 0.589989320056047 0.513375881444663 0.859055512885097 0.24328835811466 0.470055075800046 0.803367110099643 0.563457867852412 0.718015614398755 0.820499909026548 0.150156859706622 0.366365573885851 0.246288889327552 0.744912257448304 0.387019132126588 0.710954767458607 0.63640991098946 0.939054881695192 0.388325884682126 0.966126292077825 0.579637865545228 0.553300331269857 0.988970596394502 0.914181879516691 0.60875993259484 0.650732893340755 0.455978811855894 0.876806345742661 0.134786164939869 0.600372243206948 0.137190505776089 0.354071681480855 0.199166439522523 0.299201377821155 0.952089029820636 0.357344350668136 0.508411317726131 0.0934262226242572 0.27500404921826 0.206629741007928 0.65248440868454 0.0898030840838328 0.8771094166697 0.9141823734832 0.423634708223399 0.299120938268024 0.263784391058143 0.190760553819127 0.697662332013715 0.283803145862184 0.0574324701470323 0.445893720313907 0.267942385377828 0.726232695637737 0.140689051810186 0.737595243349206 0.484948385935277 0.875182658927515 0.93601091116434 0.0837264380976558 0.804421346653253 0.903380591857713 0.792353379731067 0.115551804057322 0.726752010949422 0.811325262992177 0.516484802693594 0.773732486758381 0.592516431277618 0.121416556159966 0.781693675827701 0.0478173251566477 0.488566379663534 0.407251186186913 0.0696829538908787 0.230251973886043 0.176220070845447 0.33695995922666 0.59036874004174 0.0481900107860565 0.63599983649794 0.618005906655453 0.315592386343051 0.740114092906006 0.500821910256054 0.374663093294948 0.444815796187613 0.838144247729797 0.633267760523595 0.505473647497129 0.7934956787806 0.654867962358985 0.0949106756551191 0.56485407006694 0.59054964242503 0.39291525490582 0.226030524347443 0.864596404132899 0.0922806721087545 0.253058373245876 0.22714209881844 0.260418603306171 0.600565900206566 0.613840151091572 0.0820350548205897 0.989904048340395 0.466891926571261 0.725082978100982 0.303157846021932 0.327482346452307 0.618193024303764 0.338360833032057 0.100581366457045 0.853473686727229 0.559854420896154 0.120714532940183 0.678242624893319 0.702078397441655 0.501983632354531 0.744924547832925 0.560894376446959 0.908712329433765 0.0430552111798897 0.846551974916365 0.775900010415353 0.523495628091041 0.376481624657754 0.598094758410007 0.480130509755109 0.170073472701479 0.733557967944071 0.198275530471001 0.499148721680976 0.310396181836259 0.946422051258851 0.697643368816935 0.747592114731669 0.0844814775465056 0.201320083711762 0.513134142579511 0.736620255573653 0.238325941986404 0.943708047128748 0.852273437085096 0.42591230942402 0.131189454414416 0.706163123596925 0.885398920590524 0.67335641214624 0.296254576242063 0.0901655658357777 0.301417908580042 0.461709004300646 0.3799869310949 0.12964929496171 0.778154647590127 0.60920727562625 0.712620465860236 0.640282023402397 0.253652018646244 0.185936732983682 0.713133422534447 0.453520959210582 0.0504341229936108 0.25951074818382 0.886844836166129 0.663038383931853 0.0199353616032749 0.292326039161999 0.932613402602728 0.948741753711365 0.882824413478374 0.617251698167529 0.740918607837521 0.676849732692353 0.129200347173028 0.530732463565655 0.627845793499146 0.505205416767858 0.452377427204046 0.374255969233345 0.819566926383413 0.287865715210792 0.323039369415492 0.894786186590791 0.945256605856121 0.256056680111215 0.588929423978552 0.861600189306773 0.231426328895614 0.922653918699361 0.411873935684562 0.487574638978112 0.0132554209278896 0.372904403796419 0.122604725174606 0.494682981616352 0.829760905154981 0.485728698121384 0.256080274560954 0.629708946426399 0.491758405072615 0.63769639386097 0.905842329158913 0.663884879332036 0.425908446435351 0.513219293139409 0.885604978615884 0.77387814325979 0.530042587588541 0.0675812130654231 0.216953169892076 0.669604088570923 0.99753469360061 0.56883112996351 0.575222742641345 0.654222644327674 0.754292021289002 0.29875648410758 0.758720494657755 0.458967081035953 0.511887858854607 0.426613825999666 0.426513636084273 0.978341763208155 0.120105184798595 0.760004310156219 0.85497561944183 0.831680243718438 0.592915722869802 0.188322616575751 0.980575432046317 0.466395884389058 0.31819870024221 0.888709576562978 0.997527979067527 0.145380845977925 0.267856330096256 0.310455093623605 0.879641835438088 0.991648043084424 0.0634865789976902 0.0499606691184454 0.133519237656146 0.500112057332881 0.388703699449543 0.417172369130421 0.798077850416303 0.205854798834771 0.264550595118199 0.383415192586835 0.821567928467412 0.586322860445362 0.311875005308539 0.464960759088863 0.0944324893364683 0.254246912216768 0.525114418345038 0.386494181493763 0.76881893758662 0.203313329853117 0.263027198025957 0.497858258956112 0.993412059491966 0.191389787397347 0.616086394062731 0.367888085849117 0.692412050275598 0.186248923505191 0.571378481364809 0.232561400774866 0.405562769244425 0.287128701736219 0.750835404552054 0.984434635636862 0.759191625530366 0.582992532020435 0.422835841751657 0.21711716077989 0.867780713476241 0.068571406158153 0.289117074597161 0.307503430519719 0.628621786993463 0.618103721474763 0.408170004000422 0.0425392132578418 0.792457587532699 0.408184896064922 0.397131389060523 0.463151361611672 0.367652903622948 0.670476772955153 0.842145257971715 0.733719844433945 0.36138879192993 0.828142727115192 0.391052861483768 0.921347602484748 0.440211436857935 0.306201486934442 0.237461739627179 0.377243157587945 0.51901713848114 0.326288593518548 0.0704856798937544 0.661081763228867 0.410054698984604 0.2023463635589 0.124847406423651 0.48143165303627 0.207574451148976 0.266801251287106 0.518959350392688 0.0796319494768977 0.247289038507734 0.53601846417645 0.296417088457383 0.540377308551688 0.855729175608139 0.365603008074686 0.905161856524646 0.751278858317528 0.707239265248645 0.8243638471351 0.342592575422022 0.0955233361152932 0.334355529453605 0.692377372120973 0.429575951143634 0.0787602428835817 0.839964027493261 0.920248752664775 0.0173542764154263 0.426607218189165 0.628813064056449 0.396345791225322 0.755414018153679 0.364499593386427 0.744696699730121 0.149932299489155 0.879156338276807 0.530851400466636 0.743982512902003 0.9364452508674 0.627641738308594 0.158511176505126 0.655636644088663 0.944809929206967 0.337655299722683 0.791787662685383 0.651621855108533 0.103715151301585 0.613445903812535 0.832632275305223 0.629787908920553 0.136038610222749 0.0404830904584378 0.366591082620434 0.15761531326687 0.448609640609939 0.106132973989006 0.998761669066735 0.452892455863766 0.747166454133112 0.964871801317204 0.634506524801254 0.577422279154416 0.570263975365087 0.0557170500862412 0.798056321267504 0.176339946351945 0.97141990341479 0.116928612035699 0.279061275292188 0.399285969319753 0.903710930058733 0.834283115065191 0.669769129396882 0.660465090414509 0.97289600004442 0.745444971399847 0.704392894690391 0.176977244284935 0.552096496163867 0.827421937778126 0.231045613256283 0.646899536668789 0.223645438754465 0.323263206086122 0.696644514598884 0.192663041048218 0.131499716783874 0.1464799228427 0.346343221170828 0.354378584048245 0.217656146239024 0.113137135563884 0.740984754632227 0.913050855949987 0.37432936463505 0.981312053666916 0.252817008255515 0.139765340893064 0.56424131141277 0.237601277444046 0.54454703474883 0.814399864517618 0.195247128990013 0.535422157857101 0.195905256036203 0.124542623786256 0.285758087586146 0.412135407854803 0.700320635254029 0.860316162898671 0.725922389472835 0.61370804997161 0.0671371235745028 0.573829274645541 0.132828525877558 0.0365065201488323 0.878400113584939 0.249715273377951 0.777414385185111 0.116187320207246 0.406297564134002 0.345680967441294 0.900093206248712 0.615459458131809 0.202201528337318 0.505952615449205 0.298128200890496 0.591460496843793 0.208568851370364 0.054571172487922 0.395974360220134 0.249625619032886 0.510667229809333 0.66370706821559 0.028495984908659 0.934950166607741 0.287277049352415 0.865240994237829 0.677926550176926 0.662672783713788 0.356367932395078 0.141338133253157 0.724128487284761 0.255379816913046 0.478542312001809 0.478680856584106 0.922249683293048 0.723461410985328 0.0650980551820248 0.21042385235196 0.537385675651021 0.348767038993537 0.941664291932248 0.230558804075699 0.541373755633831 0.771766111426987 0.707707326521631 0.233228938309476 0.747148733343929 0.245338169068564 0.406459060295019 0.819918879480101 0.926652077166364 0.515042089025956 0.301443304866552 0.223503514777403 0.811144934559707 0.379004763632547 0.978173900342081 0.489587898715399 0.0353503195033409 0.423250679112971 0.374446444609202 0.778694559438154 0.288107090112753 0.700269522513263 0.41412398932036 0.380707683782093 0.0668397375266068 0.262848852144089 0.945040550944395 0.571342407518532 0.080569702826906 0.475927088956814 0.557444741625804 0.484281252701767 0.940791212928016 0.121581893411931 0.661339545517694 0.998313842902426 0.903843497945927 0.626145167078357 0.315018971671816 0.585774132804945 0.602813948011026 0.230434549485799 0.114755343568977 0.0169407743541524 0.88995623185765 0.985997568489984 0.280244914705399 0.506386622537393 0.48981501958333 0.377140219393186 0.317639988162555 0.122650442316663 0.541220620253589 0.214656451749615 0.834514646595344 0.164718218585476 0.850631718072109 0.0136879156902432 0.77998190876795 0.309903457965702 0.216272708552424 0.256779470900074 0.534748758648056 0.554819982929621 0.683214652047027 0.485291727464646 0.187800049567595 0.27529123807326 0.142417139126919 0.990911294457037 0.0604178831726313 0.157331745373085 0.556813584966585 0.0481192825268954 0.23610680101905 0.982693952980917 0.355337116953451 0.772443657142576 0.994858997345436 0.528314397006761 0.459187221601605 0.784623104445636 0.537902044912335 0.530396781398449 0.138873308834154 0.343946823906153 0.194315892863087 0.702036110635381 0.0867856821743771 0.857447490547784 0.114834798877127 0.480921925008297 0.0645255212602206 0.712573203661013 0.344480009695981 0.493916231035255 0.663758270160761 0.719714019929525 0.727760945726186 0.0519706089305691 0.649784915598575 0.693832571639214 0.0796778328111395 0.750651367106475 0.199143011495471 0.445029120568652 0.599177924850956 0.492498304666951 0.607599069809075 0.655132664097473 0.0196480381349102 0.682889504528139 0.0918419507867657 0.28232550048735 0.940169412358664 0.438657767663244 0.265672359406017 0.989730436746031 0.936641426105052 0.512276096246205 0.508398497186136 0.211129571446218 0.332393158408813 0.153673827026505 0.656258490066975 0.464920558559243 0.183589915619232 0.553454008791596 0.543598054782487 0.83934358804021 0.492490767010022 0.357259482934605 0.575816440365743 0.680176210345235 0.520231572315097 0.904653809089214 0.468422372424975 0.660967479939572 0.274406556042377 0.642715190630406 0.0831159805483185 0.871649431050755 0.478979482273571 0.934254781624768 0.0794491986953653 0.164664043160155 0.798258687336929 0.40352132437285 0.289306092737243 0.323528323420323 0.360262832730077 0.0703785493224859 0.915862984694541 0.434617806675378 0.564202742609195 0.930718958291691 0.20971591605572 0.568453388956841 0.933193537800107 0.0837720236228779 0.109376810560934 0.816514747664332 0.0839681580616161 0.513764249070082 0.486141120740212 0.908866510372609 0.198904534929898 0.741632908764295 0.527534666147549 0.537870722871739 0.118879988810513 0.586794902724214 0.083961190667469 0.231580322205555 0.361501448333729 0.575553286680952 0.701778749935329 0.0689418058958836 0.15828158949269 0.257481960195582 0.86276602494996 0.410374772686046 0.039638997123111 0.575579567635432 0.315165861591231 0.811278211702593 0.260486284093931 0.49091359694954 0.371584773997311 0.155930716439616 0.667635345750023 0.0470331363822334 0.905038161133416 0.4246699393983 0.711434325496666 0.247798533497844 0.530083894759882 0.25440433378797 0.229108379413374 0.19350594752701 0.944305931928102 0.455727794119157 0.203054118680302 0.92353278354276 0.460238727163523 0.664649759386666 0.947203666244168 0.658637858510483 0.887861928190105 0.86196498991223 0.639478418263607 0.107583302762359 0.22699991760077 0.438318404834718 0.609849548721686 0.87502262161579 0.403066530814394 0.151856895580422 0.404652776904404 0.362879618811421 0.709107225302141 0.233168619996868 0.0715605487115681 0.950071437330916 0.0376690473919734 0.761509237096179 0.290898286248557 0.872808665337507 0.693032512087375 0.248757832131814 0.844874871950597 0.458147281955462 0.364282699676696 0.466120557875838 0.0925162637070753 0.279489231002517 0.308839360752609 0.49876083857147 0.746072455926333 0.401816737460904 0.0294726984552108 0.133796964620706 0.160665858185384 0.955198551297654 0.487373622038867 0.384639986348338 0.847413107675966 0.856814524214715 0.38971645710757 0.0663816171279177 0.323279053813312 0.757266362365335 0.263400481578428 0.756324486020021 0.0784363209456205 0.544600629077759 0.180629755046684 0.608667052600067 0.812740838467144 0.222539837521035 0.303157974181231 0.286253039261792 0.525156648447737 0.651598798420746 0.0546232342068106 0.515062458517496 0.110342682660557 0.361202127910219 0.394895306632388 0.913193982918747 0.806200714746956 0.460651591655333 0.905310163111426 0.47924777592998 0.842937582326122 0.0118296395009384 0.402027737225872 0.589731384713668 0.546363530314993 0.0655238116695546 0.293083548904397 0.0975909024337307 0.34305551931262 0.512548710668925 0.336274234827142 0.9453136372054 0.880210590274073 0.25476822137367 0.897554044825956 0.845625293976627 0.322517596948892 0.478070659502409 0.016341783835087 0.549553778781556 0.951302049662918 0.78567718264414 0.412895110826939 0.721464807116427 0.830081385693047 0.860561872166581 0.787508978263941 0.887570450147614 0.425108745545149 0.793063996538986 0.88862266358221 0.909900346086361 0.0466322121419944 0.370671454356052 0.41437067684019 0.0518645209213719 0.545917540332302 0.65937652929686 0.464722284136806 0.127334549922962 0.67638154049404 0.455272561914753 0.201491803573444 0.847278073644266 0.179006782327779 0.43427384693874 0.465171147100627 0.605921412024181 0.366917190412059 0.216902838784736 0.757942296869587 0.979459197048564 0.0590517038875259 0.950700961803086 0.396696814475581 0.984042387965601 0.703236808604561 0.0235466758348048 0.6543976723589 0.788209291847888 0.577251798473299 0.389262120865751 0.710760125061497 0.699264291217551 0.603008756139316 0.302716921558604 0.313074033979792 0.8557645969023 0.0685800907947123 0.567435425403528 0.31793017861899 0.582393722676206 0.393061596921179 0.584051874661818 0.761095250057988 0.775723081431352 0.738045755787753 0.869508553233463 0.0759738280577585 0.721974868911784 0.112575610203203 0.881199877262115 0.672268851178233 0.0976492746151052 0.399281324236654 0.804950529539492 0.521029659688938 0.15639194885036 0.705033406747971 0.667922303411178 0.544195775003173 0.401284954277799 0.255187615996692 0.885853577230591 0.443372960353736 0.60674278290011 0.523849500580691 0.710389813375659 0.483369334745221 0.593073807135224 0.517725046565756 0.695732277166098 0.282444124366157 0.492316739128437 0.464340085214935 0.592737091165036 0.0386217976850457 0.179213995630853 0.524750604059082 0.0620866924338043 0.335486660434399 0.342470307762269 0.156917580848094 0.181420664808247 0.578474947370123 0.679784356141463 0.908628245177679 0.627147936609108 0.292442398816347 0.060062576958444 0.498796549607068 0.872032109417487 0.102528248897288 0.610018336593639 0.803473050587345 0.558701580283232 0.113708006641828 0.0432877666014247 0.555166743961163 0.0181488424050622 0.0336865326575935 0.57448413616512 0.0236920193140395 0.757434313283302 0.508641855330206 0.831899209413677 0.668464884476271 0.841663445390295 0.755269095802214 0.993792992264498 0.523304825401865 0.236803401210345 0.693892983766273 0.192276586131193 0.0393462252710015 0.427978752504569 0.895453077796847 0.774747111254837 0.163027014639229 0.674456025159452 0.320454626155552 0.36714143345831 0.194779086157214 0.687254982069135 0.149695096679498 0.865952373777982 0.910572625745554 0.716939070750959 0.991373654715717 0.467625620812178 0.708033151717391 0.415863896105439 0.0455334148765542 0.784567358838394 0.52406841787044 0.417432390749454 0.723441694967914 0.283014580078889 0.890561747206375 0.436789942684118 0.562930305858608 0.792630426483229 0.814679651481565 0.294761710797902 0.0520217334269546 0.440925036135595 0.708883122401312 0.545361439844128 0.900303368829191 0.609526360703167 0.188123849108815 0.0941377303237095 0.044720929635223 0.602669036723673 0.628323808093555 0.570290875448845 0.720767406160012 0.728631745984312 0.897240360188298 0.475433775461279 0.631283117651474 0.470725405409467 0.0983758726110682 0.71298209337052 0.571086800480262 0.517825443472248 0.250735912371892 0.175932939155027 0.872117390441708 0.0222848267480731 0.0725904167885892 0.865829120720737 0.0692514313873835 0.503233939036727 0.605593384148087 0.409377681810874 0.965688204176258 0.221916432424914 0.255091032981873 0.819554819017649 0.583236340566073 0.121309193242341 0.0884169995388947 0.954988514801953 0.383556551602669 0.494238821822219 0.279742214693688 0.165080267915037 0.929562944814097 0.85278541573789 0.948020861570258 0.509127006507479 0.202271318912972 0.595762412443291 0.957069537385833 0.979477068816777 0.480723355542868 0.687792228618637 0.0608415877283551 0.164783611407038 0.489516313218046 0.472331308508292 0.956702182122972 0.358183318092488 0.301287680291571 0.185669142589904 0.744095535113011 0.74850075794151 0.703461450880859 0.28319256430259 0.403298409942072 0.847446992211044 0.917528511141427 0.114402106804773 0.358172578988597 0.350663697279524 0.438856232480612 0.503586067315191 0.510476394619327 0.236709624791984 0.90304469693685 0.678603168581612 0.803926200894639 0.301391010570806 0.739823983586393 0.0955803312757052 0.747787110258359 0.375062601789832 0.785317326313816 0.44500185721321 0.454634527757298 0.601190656968392 0.675050543241668 0.836736130618956 0.84038399675861 0.843038270126563 0.14961238713935 0.278668927582912 0.242124700257555 0.601909401980229 0.70869422550546 0.516760462052189 0.923169455616735 0.516638413600158 0.791109936947469 0.879453553983476 0.117667424581014 0.830706303576007 0.522108158457559 0.593236922114156 0.686497532026842 0.371263727806509 0.688182918555103 0.0426340089575388 0.741688379382249 0.0748585915961303 0.977999271771405 0.265136290031951 0.934448194061406 0.0165064293495379 0.833258203249425 0.134162937791552 0.897152737490833 0.0856224696477875 0.103471815516241 0.416953358717728 0.674423571121879 0.135960375654977 0.0294423871673644 0.931027480138 0.902776451916434 0.396357721104287 0.03853449446382 0.224233000506647 0.806865542035084 0.533286606257316 0.839152118968777 0.51155523983296 0.92688796818722 0.0654859094787389 0.454281312660314 0.860467268705834 0.463398595883045 0.119912219305988 0.381859578182921 0.0387894906708971 0.616364198476076 0.252781245126389 0.364476867930498 0.562714315948542 0.381636507932562 0.871812091940083 0.815666515429039 0.165577702792361 0.155770066913683 0.570031262049451 0.423833837118 0.704465753252152 0.671306717365515 0.902255694812629 0.316122165999841 0.653338821609505 0.423133446085267 0.802638574731536 0.308506859748159 0.88100263848668 0.405184823321179 0.296691451240331 0.333499583227094 0.345044707460329 0.193905097360257 0.110255716664251 0.356737485958729 0.929318027091213 0.675132339762058 0.256422489164397 0.896975666517392 0.865067764124833 0.44903552249074 0.268147128848359 0.31928398223361 0.156050590793602 0.537483433536254 0.818072171742097 0.0771147397137247 0.16007596374955 0.824296643026173 0.672511727572419 0.133371018429752 0.404069367651828 0.415256749030668 0.529620899697766 0.432976848320104 0.425154317009728 0.150823204852641 0.506757273522671 0.655548055816907 0.67214941408718 0.428918921749573 0.854011260359548 0.53602304126136 0.89182623969391 0.390853174773511 0.271799374301918 0.102403097883798 0.185890475083143 0.11002169709187 0.475321518748533 0.528343847368378 0.455501486463472 0.633548728581518 0.851418663884979 0.407490630170796 0.391864460443612 0.736745919454843 0.986583393176552 0.0574537821626291 0.228802973497659 0.188796899337322 0.425433117423672 0.75941571506206 0.631671149895992 0.94080086452188 0.934676427333616 0.395428357578348 0.65971672977088 0.960957919114735 0.384636131427251 0.0282363622891717 0.435203197556548 0.56367517254781 0.486046469795983 0.0798252634890377 0.306348803744186 0.204507892080583 0.751685831861105 0.759447748202365 0.910964887246955 0.263050308190286 0.480563418038655 0.0933461228315718 0.885691923175473 0.14304378393339 0.403062263524625 0.665542041771114 0.413618698001374 0.524074343394022 0.0165266501670703 0.333069084153976 0.508935564635322 0.353050359508488 0.696446491193492 0.18938424971886 0.720263295704499 0.44196260206867 0.763207160646562 0.440371263951529 0.992078719874844 0.745797993566375 0.827398612785619 0.644006479014643 0.734959290998522 0.707668846000452 0.415159007050097 0.161038341433741 0.881046238695271 0.0781045266613364 0.278252032296732 0.470456316750497 0.575772076502908 0.0258531048102304 0.855377846942283 0.747981617581099 0.738303737230599 0.96280026182998 0.138081644868944 0.219661567513831 0.87628993821796 0.490148642673157 0.564013073991518 0.566494039567187 0.0919618062395602 0.34882286850363 0.0220466802618466 0.341844235523604 0.583356893979944 0.948918688918929 0.994566985459533 0.980301371451933 0.247600297569297 0.492736272974871 0.553753594292793 0.448360554021783 0.363273635357618 0.124569548764266 0.678464735331945 0.874219019243028 0.250251653469168 0.298831109239254 0.483449842988048 0.331687473889906 0.503300744837616 0.616586416559294 0.227300037175883 0.445442033235449 0.927821301193908 0.744008310954086 0.0921413717092946 0.579139951223042 0.870018021024298 0.169834250921849 0.14530012982199 0.0830262356158346 0.494109841473401 0.440208527687937 0.161991529911757 0.62166804872686 0.672633792620618 0.196876264880411 0.99026471742196 0.977382376752794 0.284342527785338 0.443913430708926 0.603823633533902 0.189766676607542 0.685623092136811 0.15012742962921 0.469512912405189 0.870263321611565 0.0222986852400936 0.897840598647017 0.36079626953695 0.338897343587596 0.233611052867491 0.921529484502971 0.397340022257995 0.931142491353676 0.399609763328917 0.19256222831551 0.996066302664112 0.0931257335538976 0.309010974122211 0.0551614968106151 0.785286197434179 0.0763515628408641 0.0185847695777193 0.110491669459734 0.829024353607092 0.416917111072689 0.424694762194995 0.725157989093568 0.93222414846532 0.204490745703224 0.9722420220403 0.589603108779993 0.65132527904585 0.246492710097227 0.574321094024926 0.55071411394747 0.222534329437185 0.0576801953883842 0.142461345326155 0.251576591967605 0.649755330854096 0.753486511739902 0.877967643025331 0.535328290851321 0.212981056114659 0.0113605086971074 0.254260985075962 0.78414823228959 0.288355604594108 0.991153606350999 0.916962846419774 0.972323936808389 0.0840263343160041 0.273658381414134 0.494982188863214 0.459500976542477 0.339060779195279 0.989435132825747 0.579559542464558 0.485004421975464 0.402199788319413 0.59420927086845 0.81689515235601 0.994098876933567 0.08650814675726 0.910809560480993 0.359464043246116 0.445475407899357 0.0765404230868444 0.62397396529559 0.937855215915479 0.533603001141455 0.515846184212714 0.826611080805305 0.707806257894263 0.415517872220371 0.326164871389046 0.33906193216797 0.842986990271602 0.710839232772123 0.252359736105427 0.013776940763928 0.0687049942486919 0.548621125987265 0.852636011959985 0.177314881803468 0.0468014451139607 0.984776632646099 0.850030315346085 0.517176437403541 0.846388956748415 0.238259877020027 0.25860678762896 0.746633160698693 0.936870621955022 0.178651778532658 0.551652011591941 0.272768242701422 0.839264394813217 0.79437654876383 0.303465259613004 0.808729832030367 0.264286255729385 0.979512215352151 0.260346451925579 0.333421501482371 0.265273050065152 0.643348507788032 0.0717670442303643 0.928484063872602 0.859437978728674 0.818841599838342 0.441593080314342 0.16363058477873 0.816957387526054 0.718224330116063 0.198635221070144 0.11445244736271 0.255290142053273 0.223701033382677 0.949497404452413 0.697964739094023 0.68179244617233 0.550805155225098 0.423235564844217 0.679186431465205 0.868754779472947 0.812360276803374 0.238794427153189 0.783421897757798 0.458695769181941 0.24528938601492 0.850816471918952 0.176773641109467 0.79464793829713 0.688315986632369 0.883594977720641 0.528319197909441 0.84965542588383 0.665206536860205 0.177100785009097 0.147582620668691 0.632758676749654 0.929420208085794 0.951462682823185 0.324064604395535 0.693222109249327 0.615742803360335 0.807148533212021 0.450227672280744 0.780399347809143 0.848927060395945 0.728575820124242 0.701807185625657 0.553567555164918 0.205294953605626 0.0661514245858416 0.34119412811473 0.718575740840752 0.361282967154402 0.0276831423887052 0.700111708166078 0.796078226505779 0.882947036572732 0.115880058286712 0.45001845798688 0.21526386551559 0.53135033430066 0.563914863169193 0.30547580126673 0.909191214866005 0.316753941788338 0.667034102531616 0.790122110191733 0.638830600664951 0.208584739665966 0.101247652133461 0.890098720104434 0.834049026572611 0.307270029385109 0.200954543885309 0.522840536299627 0.175524619708303 0.170518370564096 0.506002187512349 0.696771546511445 0.386718298455235 0.0845446158247068 0.308711076520849 0.346085474148858 0.314843599270098 0.873823208927643 0.0794339548842981 0.0434029370942153 0.934474104829133 0.978244775892235 0.889272992503829 0.0227222952898592 0.996840079647955 0.275262274071574 0.44614237862872 0.90829287441913 0.339626337885857 0.0981936153350398 0.348796261388343 0.298052961931098 0.644326551794074 0.0911615966306999 0.817014022641815 0.118379648220725 0.490165122437757 0.227081947389524 0.424882776036393 0.144672174840234 0.681887784013525 0.683536981674843 0.238621880940627 0.282782166877296 0.865869370577857 0.317634404934943 0.756085137694608 0.3968004785222 0.998097059833817 0.342371775389183 0.388926730975509 0.886276519976091 0.554377801076043 0.725455180366989 0.684012992281932 0.496393373729661 0.639952053774614 0.0755700303753838 0.302687458058354 0.646631758876611 0.92554975183215 0.481424429323524 0.616389284736943 0.906371135634836 0.297773180499207 0.224592639473267 0.0278044472401962 0.981878901787568 0.0177719503385015 0.640674339763355 0.406083499840461 0.309114468288608 0.472683143818285 0.359664587886073 0.531565455216914 0.89128443012014 0.9279936729162 0.68689502408728 0.859843369643204 0.233390486333519 0.937708809820469 0.786593702118844 0.0173207749752328 0.883939474758226 0.942068666561972 0.567309245427605 0.468518142227549 0.544648646863643 0.0397019553789869 0.546195273520425 0.0368777653691359 0.525311417167541 0.937397382261697 0.455599715034477 0.894570771323051 0.963531919121742 0.875206381536555 0.0659425790957175 0.47569976455532 0.440700614911038 0.384901441922411 0.690339519628324 0.558194381326903 0.133536683917046 0.859414700067136 0.277502409883309 0.893972987944726 0.720333875289653 0.13419865966076 0.25400564127136 0.280326537657529 0.315136637813412 0.276039631217718 0.544023165632971 0.23149621351622 0.874731729971245 0.846068104640581 0.717937319669873 0.383357115448453 0.128008484819438 0.910996395302936 0.732949367321562 0.523972711686511 0.333130507725291 0.927200814487878 0.655046117384918 0.528910442166962 0.189377011484467 0.616792535898276 0.0262959763268009 0.136016269014217 0.619488378288224 0.86162856368348 0.955216938930098 0.275679996630643 0.92269872374367 0.273658132932615 0.317006162977777 0.807867510570213 0.304851048884448 0.0784767960035242 0.555891752182506 0.920865502236411 0.760393201252446 0.658643638356589 0.843272788044997 0.173085085544735 0.474251790593844 0.665102698553819 0.573584501447622 0.904378458603751 0.276204277654178 0.632722735672724 0.401858097878285 0.086870873994194 0.0629049833375029 0.873381356461905 0.039807342661079 0.715505212061107 0.142407948998734 0.20890054515563 0.426578561216593 0.9464019666682 0.93273865734227 0.897573629226536 0.660459723859094 0.70085356403375 0.0163874117727391 0.565059112499002 0.0654967880365439 0.841251316661947 0.186540832126047 0.318507830384187 0.405114991946612 0.297671249138657 0.729123123951722 0.420597014271189 0.760576747728046 0.505625213617459 0.881795492996462 0.174408652554266 0.556258064422291 0.0383391559496522 0.403029414406046 0.148145445832051 0.970416243684012 0.50641578200506 0.183118203189224 0.693844660334289 0.821513295264449 0.887208924980369 0.7026791314804 0.462099278641399 0.19749352455372 0.895251334083732 0.168369812408928 0.904423010095488 0.187373119592667 0.500325188783463 0.387772118491121 0.525547501118854 0.862977675884031 0.579053833244834 0.210767884235829 0.141573510484304 0.0354582134983502 0.656049769048113 0.435449495527428 0.282048948393203 0.61072607281385 0.491146417679265 0.332736441621091 0.414444290527608 0.814734725174494 0.964786764394958 0.253870956220198 0.942134183393791 0.687199465581216 0.3183045015065 0.845774753997102 0.864102728518192 0.0426197530794889 0.122153264910448 0.237060820457991 0.319260109798051 0.948771231733262 0.657638375482056 0.194569807783701 0.0804709789063781 0.698579198855441 0.264390912319068 0.461764197393786 0.0926868388941511 0.3992792872875 0.195490724551491 0.0962416328000836 0.14217179981526 0.801365519312676 0.21177780487109 0.603811144917272 0.10829976119101 0.663624241119251 0.0679503222205676 0.446785897358786 0.573950357984286 0.867579673947766 0.684433346255682 0.177954702815041 0.197020168411545 0.0588975342432968 0.153005082351156 0.3025914436928 0.230385976880789 0.855620906355325 0.528013077897485 0.255252632407937 0.969604314414319 0.17997721952619 0.627236604865175 0.326452602155041 0.137856653381605 0.0471819712803699 0.82086308873957 0.169213901825715 0.0779223147942684 0.692579552636016 0.191375201900955 0.816226139836945 0.511485136235133 0.583934480282478 0.674199787005782 0.339521174652036 0.992646711056586 0.821855298958253 0.50344304776052 0.584838453745469 0.655043080747128 0.0901311363931745 0.165847035322804 0.0275579964462668 0.583227580555249 0.60364318754524 0.421415771711618 0.247509894783143 0.989735177948605 0.212651431318372 0.883472940793727 0.240792216726113 0.606931322056334 0.678143248420674 0.540387456647586 0.921157178971916 0.33668190079974 0.210007584954146 0.0874469975288957 0.288327175818849 0.425425681418274 0.981890091984533 0.0180907242372632 0.861882155439816 0.701740634760354 0.831457893326879 0.188574066043366 0.47143134601647 0.295795999909751 0.149387583511416 0.411325770008843 0.314897371546831 0.55194988907082 0.155394294166472 0.598380448769312 0.952966185489204 0.59388499787543 0.288157884990796 0.768041486395523 0.88017385304207 0.918609024269972 0.0995503002288751 0.786154685984366 0.652830852083862 0.380382403954864 0.817011075669434 0.597366369641386 0.751145945598837 0.205084589796606 0.991827235601377 0.395900671619456 0.0577088613505475 0.817116710050032 0.179977944225539 0.355669619340915 0.317061971973162 0.38478157794103 0.358856716610026 0.250680740484968 0.886701071166899 0.709105335413478 0.517212774713989 0.0952301256172359 0.175949682844803 0.260307063916698 0.863505646097474 0.0385861537256278 0.24917334532598 0.228004952508491 0.360670017413795 0.212424800728913 0.215899447819684 0.392656654333696 0.56290643250104 0.265326056843624 0.986941663189791 0.0534105826169252 0.902283680562396 0.277123765998986 0.850588540143799 0.0630978096066974 0.517836238127202 0.0307221529702656 0.785585859001149 0.407442413691897 0.437491763061844 0.344854823092464 0.423012461632024 0.476135229570791 0.558006973476149 0.796800364051014 0.487567760327365 0.703219329151325 0.599875127344858 0.963004925546702 0.449504581838846 0.285691450512968 0.737685348787345 0.883993834124412 0.957056655993219 0.259764500600286 0.473995743987616 0.898631801377051 0.786024837333243 0.202970946752466 0.721456690437626 0.945948012599256 0.472949509783648 0.238811840221751 0.958267919037025 0.743798459551763 0.406584116802551 0.813226477848366 0.523914149801712 0.501356144831516 0.606203252994455 0.797100665953476 0.605280909647699 0.203439504757989 0.319542860791553 0.504570776526816 0.942237301380374 0.0634701577806845 0.678990416196175 0.819213413246907 0.981712497770786 0.845368384600151 0.272904652601574 0.170810547489673 0.403214128836989 0.672215755656362 0.661875332065392 0.548829937824048 0.586857916531153 0.695816095191985 0.0129556904407218 0.914778666894417 0.614880436260719 0.0635575207020156 0.764826672603376 0.498355387265328 0.876821253711823 0.234641913257074 0.364575234111398 0.266525031807832 0.0588324309326708 0.167149473105092 0.346876195359509 0.514623162322678 0.58168257847894 0.354674622579478 0.180246885593515 0.461158481277525 0.980596515173092 0.832453532728832 0.460639930542093 0.243477789314929 0.74310389216058 0.577977433660999 0.0599831334059127 0.569284810656682 0.160842973645777 0.124878458085004 0.487525677285157 0.668716829062905 0.747087681572884 0.809452997385524 0.316115124614444 0.324761287798174 0.686544734064955 0.868699218498077 0.49275888410164 0.686424050186761 0.424792976705357 0.656007808633149 0.472634439826943 0.0961391111230478 0.896142074407544 0.320324110200163 0.977498000643682 0.187918695113622 0.626806651160587 0.0251876802905463 0.612787847069558 0.502197023350745 0.857369611645117 0.76784900150029 0.54349409500137 0.813738935254514 0.23692427548347 0.664833745430224 0.601645535582211 0.0163447153638117 0.732374133986887 0.031640626413282 0.481528046347667 0.567588281414937 0.689336883097421 0.807161093053874 0.0890139358211309 0.0206235901801847 0.355020833171438 0.909850417436101 0.218147812334355 0.876168430754915 0.273162981641945 0.760578369542491 0.182204522581305 0.0693487580027431 0.0592349746823311 0.832542294568848 0.447892914568074 0.682383251783904 0.88249612720916 0.517828374309465 0.229637325573713 0.631841471530497 0.567224770931061 0.996138284625486 0.957102403331082 0.83857645344222 0.610960584969725 0.796154000461102 0.3584274889878 0.0123573958082125 0.440524572669528 0.227310044434853 0.630745765762404 0.519078361745924 0.0486091389483772 0.0841914246999659 0.713504897796083 0.605010750766378 0.636095945369452 0.972039295234717 0.31440728047397 0.233715088022873 0.477732347534038 0.781679240618832 0.935004595355131 0.404787401102949 0.540987045781221 0.378236065306701 0.300552430620883 0.317508458227385 0.631136436336674 0.367327255222481 0.539126015088987 0.147523146686144 0.90839050483657 0.837880919785239 0.303925285805017 0.876743668930139 0.491796958432533 0.457097810115665 0.891604405397084 0.259261372776236 0.332912056280766 0.539675278647337 0.749542247946374 0.460776716622058 0.691368868614081 0.145161550203338 0.530400792139117 0.131435896910261 0.413704567959066 0.200919922203757 0.763662107028067 0.742302795809228 0.330997923843097 0.277809252981096 0.0148963772086427 0.126308649252169 0.262028792595956 0.688913486723322 0.912905011589173 0.207104464950971 0.148199536432512 0.121795604575891 0.309320813750383 0.673845330653712 0.221268435034435 0.443559225834906 0.133181566714775 0.515070370740723 0.937840469528455 0.920366248004138 0.33114413009258 0.795156395104714 0.886881637247279 0.788032529978082 0.535024727340788 0.106486836797558 0.470848504952155 0.912263733111322 0.330768489884213 0.996871523624286 0.181581908799708 0.689807268986478 0.777809367305599 0.136062581313308 0.142333367662504 0.576570464451797 0.373405316032004 0.838693471641745 0.686622911698651 0.84143775501987 0.422056480157189 0.998607987165451 0.789186159370001 0.853512654991355 0.336980801247992 0.826775361665059 0.178382573931012 0.447381244788412 0.994971221096348 0.361450339511503 0.72366890711477 0.4062873860728 0.544332029314246 0.753013026746921 0.0347873505065218 0.464191399682313 0.133769757968839 0.512640359550715 0.426080164222512 0.96721986685181 0.215915904764552 0.287983307591639 0.406364756256808 0.41722309647128 0.767107897992246 0.555067509247456 0.271064683368895 0.136262900982983 0.77133264094824 0.506011673836038 0.280703397914767 0.315350823581684 0.296545754401013 0.858102761439513 0.241245515476912 0.482267807410099 0.449834285697434 0.712262587009463 0.808810517990496 0.708341537336819 0.546206294759177 0.427019696589559 0.744558519111015 0.405691040568054 0.912374774154741 0.277496286588721 0.311078309477307 0.18540841471171 0.989461706287693 0.384070399168413 0.153928167915437 0.368152158085722 0.459246722322423 0.897413456148934 0.987964175706729 0.529161703544669 0.0749196465942077 0.73348764606053 0.649703191686422 0.580494874618016 0.991041075340472 0.849266097755171 0.126710165191907 0.45200677045621 0.855629187843297 0.178017914392985 0.366205859046895 0.755081306009088 0.642533889017068 0.586470037570689 0.657929174234159 0.0571248371177353 0.407833806199487 0.456779244591016 0.17802243177779 0.919832779387943 0.494021927651484 0.105428532338701 0.0743995339749381 0.0497941846563481 0.728068708758801 0.182587870787829 0.860459829934407 0.535415579320397 0.253414409691468 0.352794019703288 0.621187428995036 0.653700736556202 0.452124502290972 0.291530579745304 0.615930118779652 0.661873332227115 0.647460665334947 0.493180255512707 0.242211831524037 0.104246072866954 0.272219758932479 0.683155042298604 0.556000139683019 0.763225009825546 0.8935445394204 0.899585992540233 0.602800335464999 0.494977052810136 0.271567886797711 0.482568416572176 0.59221943062963 0.240877570358571 0.86513086252613 0.0818106679408811 0.0482074522064067 0.934171622374561 0.769434249284677 0.721093408381566 0.623574261565227 0.0642642588471063 0.209835805392358 0.877520251127426 0.284983007342089 0.733272823183797 0.336266720911954 0.108138688462786 0.427658205351327 0.946433453978971 0.875914759475272 0.84143252999289 0.109119155509397 0.550949271048885 0.951857101595961 0.295572589898948 0.744938028301112 0.898106846364681 0.749242909082677 0.066422386537306 0.282502952711657 0.514794769468717 0.35547045448795 0.226884532049298 0.454405398983508 0.991870206999592 0.732189231466036 0.0995847031637095 0.356021528872661 0.771425939304754 0.716538861298468 0.572154333791696 0.414498806404881 0.373442057643551 0.536325454104226 0.129824550037738 0.544707424498629 0.682117312247865 0.204916740530171 0.787571777934209 0.489037785525434 0.271351366501767 0.480401205937378 0.223750219584908 0.531900433660485 0.746457923601847 0.256197574203834 0.501554743801244 0.673445575060323 0.498876536914613 0.356956781963818 0.190830896908883 0.359128132420592 0.944407187686302 0.11378725795541 0.0546043101954274 0.0685918994294479 0.734014463762287 0.0350997814419679 0.0760790247144178 0.782137690635864 0.167206652206369 0.925281806003768 0.0942596029024571 0.0304853540007025 0.900823092360515 0.109171560676768 0.984543924401514 0.230355496173725 0.294016694743186 0.149957036538981 0.0482800046610646 0.797050529390108 0.774537176180165 0.578516739748884 0.336563394707628 0.819497985439375 0.549155040855985 0.982777019569185 0.612913134309929 0.671874514464289 0.546671264534816 0.273803384671919 0.860779823421035 0.0572099519497715 0.950371656252537 0.635598613526672 0.304220003096852 0.909441806864925 0.133449603822082 0.546710087812971 0.847642713589594 0.836868973956443 0.394486167519353 0.263989273291081 0.393282409401145 0.199994388013147 0.896190919696819 0.121577694581356 0.567712051719427 0.288588648219593 0.844461232970934 0.977669677631929 0.109746489056852 0.0777363010216504 0.412343905286398 0.547697855560109 0.404831554747652 0.708321840912104 0.788015994201414 0.151513722087257 0.887544427816756 0.162156186259817 0.618819013100583 0.636156021654606 0.510577032170259 0.175532748373225 0.793697947117034 0.497536319799256 0.236591894340236 0.136227035971824 0.950118152778596 0.804749421321321 0.609789770706557 0.935387060507201 0.664876414639875 0.76678808614146 0.607254899854306 0.227250968529843 0.906217773440294 0.703675409373827 0.779560707237106 0.698678313707933 0.623263275648933 0.404291508516762 0.508038256147411 0.789980566082522 0.897118310122751 0.989265425940976 0.810475277556106 0.597944167314563 0.483635056687053 0.56709411759628 0.516618279682007 0.0454740669787861 0.896705775940791 0.321400451005902 0.671401818711311 0.45820124116959 0.921915071117692 0.0134422527533025 0.120003532806877 0.429624509457499 0.932008489556611 0.360934209742118 0.182854315354489 0.683739446860272 0.683446093450766 0.554539089784957 0.196932493851054 0.64371376501862 0.608314072384965 0.816704699338879 0.968125874958932 0.776078836664092 0.601557738855481 0.87498965010047 0.255267434807029 0.144740752282087 0.687507930032443 0.939151801473927 0.843962915269658 0.641693567391485 0.0870209296327084 0.671817197061609 0.976108275314327 0.614118708786555 0.196345879693981 0.301392792353872 0.365561028989032 0.730364116725978 0.0631392705230974 0.553786199078895 0.0471054341318086 0.762423417433165 0.934752828255296 0.229357197466306 0.927439825357869 0.431356212894898 0.265414706429001 0.719106586570851 0.244641981937457 0.217566420207731 0.143813707148656 0.948079639435746 0.460101660331711 0.722186233792454 0.0985965898935683 0.349353982538451 0.409088859155308 0.130084796166047 0.528872933213133 0.152464941614307 0.0920660188817419 0.197708104711492 0.437214162643068 0.382711972598918 0.952702832880896 0.887332754754461 0.0619160282728262 0.346275250872131 0.660417034365237 0.559292890925426 0.784356854192447 0.330256359560881 0.0582475420855917 0.255020452013705 0.261522837660741 0.50127701937221 0.208990138417576 0.219398769955151 0.677033136487007 0.925044009650592 0.606461928479839 0.113860172298737 0.366825850403402 0.669713867153041 0.591683714385144 0.360827627535909 0.114247858098242 0.400318747719284 0.636862476742826 0.185386538195889 0.720140864849091 0.55703819335904 0.874681479539722 0.172948575837072 0.634807425087784 0.538250314351171 0.633295388072729 0.268900722817052 0.110168264077511 0.914460822842084 0.376614637183957 0.55375533758197 0.0408176622958854 0.32106085099047 0.301648631046992 0.25059168844251 0.19829392156098 0.027111249724403 0.516850516779814 0.635683518832084 0.407246850898955 0.554745966324117 0.491132613816299 0.0859063249779865 0.381852835759055 0.71161830623867 0.32929801451508 0.296911425383296 0.191369085521437 0.881504547183868 0.283263905697968 0.337203637077473 0.554928254487459 0.966000684900209 0.272037448179908 0.29936671806965 0.913974361259025 0.479973417571746 0.726542760466691 0.468982427180745 0.584361197042745 0.680921132354997 0.933917259818409 0.0270854412997142 0.388690941606183 0.932701332329307 0.116593551302794 0.207825729583856 0.882936217945535 0.070090148486197 0.461027974772733 0.349697011276148 0.165113958367147 0.0565872353641316 0.425033778117504 0.302685163407586 0.261459127736744 0.872352978582494 0.050209349100478 0.51230985123897 0.994055060744286 0.934018507509027 0.0850265752361156 0.656338485903107 0.898578182845376 0.266515310602263 0.0474333177134395 0.3355460115592 0.262536129853688 0.835332328050863 0.422874094536528 0.681564160806593 0.849760658268351 0.384419952735771 0.844222143499646 0.0385006710118614 0.258211834321264 0.9526554648811 0.509128737349529 0.573336385504808 0.246671579680406 0.0496894999453798 0.912878563059494 0.653190922550857 0.102483841008507 0.153067271881737 0.798105940122623 0.258342451697681 0.781819866176229 0.0433842168468982 0.274095164211467 0.36384891364025 0.578798077071551 0.863682603663765 0.409060935180169 0.631300000334159 0.251237761368975 0.481900623179972 0.550034637544304 0.45832071053097 0.300597571968101 0.773049100574572 0.542694706672337 0.195741041791625 0.362176695019007 0.144318539537489 0.603551061984617 0.952677364677656 0.681224290872924 0.322653013614472 0.352505879565142 0.49410893306369 0.779372171538416 0.711225840281695 0.226163369989954 0.0572261959104799 0.152150835848879 0.994798479648307 0.778762865348253 0.567128005127888 0.679640857602935 0.653582208566368 0.605815894508269 0.0741942780977115 0.809457294179592 0.479497977688443 0.717421861584298 0.101604067524895 0.805498191106599 0.701880088213366 0.142023316202685 0.829546070753131 0.277770804038737 0.496348968606908 0.594298026023898 0.140030818502419 0.278110087343957 0.0214834872167557 0.0487117991573177 0.414648768920451 0.141453377276193 0.196602137901355 0.812316588312388 0.502052807949949 0.498659736327827 0.256342375311069 0.72197719306685 0.120280309640802 0.6267017477029 0.682020102036186 0.0141387314698659 0.605798164498992 0.616196745904163 0.353818321840372 0.911602905960754 0.671621771878563 0.58591643180931 0.462617498375475 0.405333182923496 0.831885814922862 0.890511391204782 0.694879489743616 0.568584379747044 0.851984822112136 0.606391309709288 0.852420363193378 0.404061190581415 0.339781497537624 0.0753335868404247 0.672525158943608 0.633577969647013 0.687026719062123 0.668065358002204 0.636153385399375 0.102930424534716 0.0757959424890578 0.937802019203082 0.624332247064449 0.503966867779382 0.692067409865558 0.690944927101955 0.150118165509775 0.640882952907123 0.263774249646813 0.521548633165657 0.0260644761449657 0.81491307382239 0.164798697324004 0.13071768989088 0.753427817777265 0.877206553120632 0.196380859576166 0.40693210733356 0.158522182530724 0.986006698226556 0.812152788280509 0.0514773897104897 0.90853331716964 0.886495111796539 0.746687522830907 0.753056883735117 0.365141663870309 0.109139046247583 0.296005568255205 0.512400403851643 0.886776454190258 0.291265990952961 0.444787290424574 0.851885805914644 0.629404625485185 0.155841771350242 0.795455193901434 0.880044517719653 0.753467685692012 0.786774390365463 0.349996080452111 0.0903271652618423 0.628749204305932 0.113227562783286 0.863664194594603 0.0996184385637753 0.113882825607434 0.644240177958272 0.26433409210993 0.721525334033649 0.976993797526229 0.075715620953124 0.816893925622571 0.0755280418391339 0.526920636503492 0.0601628482411616 0.168236512215808 0.455653568909038 0.640980239415076 0.660808495101519 0.784950546845794 0.559775986252353 0.312869297654834 0.121164608807303 0.803896260024048 0.430041549960151 0.820931727495045 0.265376844345592 0.0846117613860406 0.354169922268484 0.603775121090002 0.602204743011389 0.254934298538137 0.935686022038572 0.506333792554215 0.122029047431424 0.781090217712335 0.883444077752065 0.679337712684646 0.102617916150484 0.529086338961497 0.601149139117915 0.423720920938067 0.786217508243862 0.204374766608235 0.35767557192361 0.094466219895985 0.568523597894236 0.868512205497827 0.889726766319945 0.514551241444424 0.717031383248977 0.2116400695825 0.664309628754854 0.572135616079904 0.275485466027167 0.848470766267274 0.36466398073826 0.61893653540872 0.713148373146541 0.776113202949055 0.462271653129719 0.0966399067244492 0.0667524266988039 0.626042856541462 0.64597774537513 0.0784630695893429 0.247766909268685 0.016368547922466 0.236729552871548 0.359650683985092 0.906319595081732 0.127970840099733 0.323915731695015 0.895740864805412 0.534167143164668 0.821722324695438 0.351785073170904 0.0955593776912428 0.883993178575765 0.410137833110057 0.359117268384434 0.161813674538862 0.256240296659525 0.29392443664372 0.59506208272418 0.774046905776486 0.175538838244975 0.567579978720751 0.51536431492772 0.420540678347461 0.824585456692148 0.791773965083994 0.078050080165267 0.905801385028753 0.878066334214527 0.616763023762032 0.163541026322637 0.719959023168776 0.641115791155025 0.224869626294822 0.78008762820391 0.97506544171134 0.625828073080629 0.53991011304548 0.283388897434343 0.805422159910668 0.728418510577176 0.731699803548399 0.801147869785782 0.489703654684126 0.775988339832984 0.970311486825813 0.152616252338048 0.351980324094184 0.0651477007754147 0.594251409000717 0.43758563951822 0.252306495597586 0.292805913679767 0.505559943192638 0.9094192888611 0.471718896068633 0.85006660701707 0.207712723277509 0.586957130038645 0.509553818926215 0.70630919292802 0.508917480574455 0.280837147356942 0.250422410983592 0.79829921633238 0.528941552606411 0.546633474598639 0.632995719360188 0.153433983121067 0.45414385604905 0.992086805666331 0.573356852498837 0.826906176120974 0.205022547096014 0.305411449393723 0.951446275897324 0.0997578272456303 0.848203002535738 0.891722302963026 0.650922179785557 0.557683187073562 0.0462734730564989 0.75114492908353 0.727414507397916 0.577762004563119 0.371181318841409 0.332853225860745 0.332218963182531 0.420354024008848 0.701731767104939 0.926146637403872 0.317047173031606 0.860830592482816 0.500378961982205 0.817684410337824 0.679712886125781 0.657556394559797 0.937477187011391 0.791405463072006 0.639426059196703 0.952844045527745 0.039054331863299 0.100132580711506 0.386275736733805 0.0779204905987717 0.476641911510378 0.242014088639989 0.517054218610283 0.24922900195932 0.982706493230071 0.429697349348571 0.644896284651477 0.612748334589414 0.300445400318131 0.175496754050255 0.177988331492525 0.567901695673354 0.867166828126647 0.868142498880625 0.727565024963114 0.582105001672171 0.426566018662415 0.491805123286322 0.0963864551135339 0.252710663697217 0.894310961535666 0.0576057110936381 0.385420653277542 0.348788510747254 0.621487980070524 0.189898704888765 0.938763259358238 0.465034860980231 0.604094071323052 0.610053824502975 0.0640900391875766 0.991141545085702 0.828897248394787 0.647004224376287 0.150602752647828 0.385471656299196 0.249040685237851 0.275041063975077 0.91884515109472 0.187361181876622 0.567980263086502 0.998501824012492 0.263780446241144 0.774437877156306 0.0516095825703815 0.0739474571170285 0.963278134895954 0.330427972930484 0.308010784604121 0.660368495183066 0.544276851434261 0.192538933518808 0.492110509148333 0.641483487791847 0.21049530046992 0.784170157671906 0.0340704564284533 0.406098735814448 0.188638372968417 0.870284742654767 0.893860773874912 0.285094615190756 0.475034545643721 0.894362442619167 0.846363129653037 0.730969331960659 0.189336408036761 0.315296546043828 0.289689212746453 0.0271043743006885 0.329809495513327 0.3154256697651 0.0395592239522375 0.307399175465107 0.575506603042595 0.507581610272173 0.0129863523226231 0.277428206570912 0.641885833078995 0.560405665161088 0.377304413123056 0.880198313950095 0.0517119212285616 0.570166849517263 0.612080888564233 0.237432495334651 0.92645784068387 0.587311024656519 0.206534597249702 0.252525470743421 0.441424308116548 0.423449829674792 0.421071405829862 0.186829578254838 0.0696763075864874 0.60773335078964 0.54483026887523 0.448652629987337 0.560654079604428 0.757281106677838 0.49220138262026 0.399765691705979 0.156920597893186 0.820048416031059 0.159370491062291 0.335491900674533 0.891365709393285 0.276041551532689 0.624004158335738 0.847606497523375 0.635685823855456 0.337354478498455 0.559720064310823 0.556408074421342 0.146190257470589 0.211008214501198 0.106034058982041 0.315204335427843 0.186964028885122 0.289453200711869 0.232152663427405 0.917425734067801 0.473160339668393 0.725974215618335 0.702153833019547 0.761263391370885 0.811618834917899 0.505813250278588 0.925145609779283 0.198099984731525 0.823148179422133 0.136814812321682 0.26589593215147 0.0668554024654441 0.400645800570492 0.288334228268359 0.992324235520791 0.657535388881806 0.638795774758328 0.291156233116053 0.599943787537049 0.835168790330645 0.126999362644274 0.0430129810771905 0.908355351616629 0.0401507962145843 0.333268979468849 0.186253742848057 0.579761250910815 0.140547341739293 0.151115026804619 0.84720981544815 0.119563987669535 0.829794908859767 0.99028758601984 0.614534692896996 0.945490839795675 0.13131449732231 0.522504565312993 0.234488978183363 0.333598240762949 0.540919208712876 0.0146352883637883 0.92637692583492 0.949230410829186 0.7223411447322 0.179945905092172 0.662076042206027 0.990990777425468 0.179917347235605 0.640780458429363 0.108986292579211 0.257633431118447 0.893806160034146 0.775439670740161 0.0871983207738958 0.793884071530774 0.323007165472954 0.280468158985022 0.951237705626991 0.688212103147525 0.0585028252680786 0.949434599711094 0.876929077634122 0.913749420943204 0.834979108343832 0.925046002343297 0.776487981078681 0.489317158046179 0.638217132063583 0.314741495263297 0.84165128961904 0.343196708217729 0.283257544524968 0.156032244651578 0.184742400336545 0.314791058567353 0.711461902335286 0.542694237600081 0.114290757810231 0.351932261590846 0.660121954493225 0.92275360727217 0.205790802165866 0.543891766392626 0.251963746228721 0.102212505182251 0.0975111350254156 0.843002284793183 0.921671257962007 0.686643736662809 0.280951273213141 0.588054280364886 0.472461576212663 0.199703846732154 0.316993318235036 0.0917170669254847 0.288626826552209 0.565981291497592 0.709444265589118 0.218585613260511 0.362568009386305 0.306066018405836 0.66349379500607 0.0840462663141079 0.415039456321392 0.864858723168727 0.317004293142818 0.244450171492063 0.791905956715345 0.11768719315296 0.824438959087711 0.668115834787022 0.959464663430117 0.618247338952497 0.932001391698141 0.857173553272151 0.176297833344433 0.657201146432199 0.317522215067875 0.287859471363481 0.148173219289165 0.458775833938271 0.205735863316804 0.947753887770232 0.241155111077242 0.527061845692806 0.177414450284559 0.507167370833922 0.0889068838511594 0.370791156524792 0.636528739784844 0.0822820807178505 0.343838180778548 0.394383314840961 0.0240135184419341 0.446789419434499 0.424966980384197 0.963752402213868 0.602934185636695 0.0414163934998214 0.139156757097226 0.990345174262766 0.692433966898825 0.184163791756146 0.020994644544553 0.344067464910913 0.605853243493475 0.272787652842235 0.936686188045423 0.0471378895523958 0.564726035699714 0.730621141584124 0.153349903014023 0.205862281632144 0.740648424753454 0.349740484477952 0.157137535628863 0.554768509913702 0.992903510022443 0.399072900565807 0.998962077018805 0.909331934698857 0.447051445962861 0.557481243975926 0.427958562113345 0.788270403549541 0.770556852601003 0.526800615089014 0.359685734861996 0.516957899059635 0.984654564831872 0.340170304961503 0.350587261090986 0.0140846961899661 0.810093963993713 0.663075848629233 0.337077566820662 0.739624575783964 0.138795999733266 0.12182269021403 0.685378582403064 0.375718211289495 0.302324103163555 0.660264974278398 0.304270917144604 0.92101181267295 0.283941293980461 0.133400921267457 0.23342016881099 0.401802914696746 0.037039689111989 0.763281257466879 0.581557796038687 0.470673981260043 0.574559321878478 0.28025571097387 0.933687645837199 0.833859824491665 0.359372044000775 0.71529747874476 0.78946698497748 0.177491552394349 0.60569252666086 0.22524752312107 0.12091528872028 0.809665961721912 0.389370429764967 0.0274607313750312 0.270104181512725 0.773284007580951 0.189907231861725 0.802915142730344 0.874191904792097 0.0974094952503219 0.843634688700549 0.390671124027576 0.979560321881436 0.766605233708397 0.550991441681981 0.500447114377748 0.0779027707315981 0.977763846595772 0.728387812275905 0.415569957911503 0.599071273494046 0.508585861010943 0.507931458421517 0.534459103879053 0.671177090227138 0.317753114330117 0.67316407246748 0.0126739522744901 0.928809886071831 0.0210423965612426 0.683676562134642 0.0439027634332888 0.0469052304048091 0.976496422118507 0.952989096038509 0.166071239875164 0.226596887030173 0.420860802067909 0.0813041849248111 0.781513322961982 0.73913948753383 0.824596803169698 0.198627286949195 0.641935462076217 0.989781684330665 0.0561343141761608 0.277349230016116 0.639690847143065 0.760268993685022 0.616063331612386 0.944778674473055 0.361611879698467 0.5171542432555 0.454345371795353 0.394469351451844 0.170910315355286 0.949092874003109 0.886720507584978 0.874246334461495 0.29403129914077 0.980893089852761 0.686908582004253 0.361155689756852 0.658558599129319 0.733463977389038 0.744623609283008 0.285126194702461 0.837368488425855 0.797623636571225 0.247536570818629 0.451679902928881 0.630116217548493 0.110288283647969 0.702905975515023 0.668729270196054 0.885039667945821 0.830237825785298 0.633930580827873 0.0356590720824897 0.647275834961329 0.9550889566564 0.117692806345876 0.500129650423769 0.152020407253876 0.925371394194663 0.720659672133625 0.449615801982582 0.175746587926988 0.726788424325641 0.235294221041258 0.404806077554822 0.811903465196956 0.722483845963143 0.0447236885176972 0.868789826431312 0.592482800064608 0.661496172777843 0.13821572969202 0.529200928127393 0.143650552753825 0.184691980716307 0.280427074939944 0.922524240158964 0.741133513695095 0.997977380945813 0.0158165434608236 0.789670303021558 0.862015423593111 0.885862968587317 0.125771973195951 0.417058626138605 0.265417016753927 0.620441655970644 0.0865061222552322 0.722799077271484 0.812442435212433 0.504435832160525 0.592081514396705 0.304092960350681 0.861513093307149 0.307664007206913 0.177701130881906 0.50778240546817 0.0644313522963785 0.581083363450598 0.344439550542738 0.364282672016416 0.588825744949281 0.482255024211481 0.594482011836953 0.360339612828102 0.330808252459392 0.321268831174821 0.840638914825395 0.579568037397694 0.0532526689232327 0.895231372120325 0.243921505622566 0.153914145536255 0.516459097533952 0.014118379727006 0.0631442832574248 0.881651800374966 0.904105844642036 0.471923996356782 0.579431759114377 0.133008279437199 0.1729073839169 0.673478041545022 0.743723906336818 0.733719258266501 0.496844119897578 0.660317137879319 0.505549498901237 0.398727887202986 0.0839018079638481 0.805415224325843 0.144665995303076 0.468556694434956 0.191643156718928 0.833077822492924 0.801846587832551 0.411945731861051 0.717674726797268 0.385517651427072 0.108331558527425 0.995231513325125 0.820926693324 0.10943411482498 0.560606476261746 0.372989329155535 0.800535284699872 0.879809631227981 0.872656426150352 0.565966147724539 0.593058779074345 0.688060715666506 0.867852015225217 0.574709711975884 0.176446491908282 0.904691986269318 0.779302491373382 0.0975930896704085 0.206109805414453 0.950383352632634 0.343185439419467 0.538660659913439 0.0608645289344713 0.863341663507745 0.774452151244041 0.608415240552276 0.54768121306086 0.744644170782994 0.853344506302383 0.379164335790556 0.164792502573691 0.98876072447747 0.383951028923038 0.973132253645454 0.73752420298988 0.695509427275974 0.224793397558387 0.849945238546934 0.827089155560825 0.728130163217429 0.74099955818383 0.982616729165893 0.745971140468027 0.0222305720299482 0.867587765040807 0.511210228775162 0.522672208049335 0.405416475634556 0.765686234028544 0.824562590399291 0.58631464303704 0.635127718918957 0.172148529193364 0.476918928297237 0.351994724266697 0.631042413511314 0.117623080310877 0.797655931792688 0.252666000642348 0.40197232792154 0.485705362525769 0.407218873447273 0.623630500677973 0.0724901710916311 0.490736113146413 0.046852010411676 0.611241233781911 0.203741580836941 0.641009821393527 0.0384350753482431 0.0415051832306199 0.624583783431444 0.771041611232795 0.558097818826791 0.318948720272165 0.847464257988613 0.955278151822276 0.729985860546585 0.268074133368209 0.201109717136715 0.613469192155171 0.238222221927717 0.982539823213592 0.943792149133515 0.677969833905809 0.0912423144001514 0.0679458755999803 0.194990408394951 0.0891387168783694 0.401285895418841 0.0597320458269678 0.0165995227894746 0.728166458576452 0.569353703195229 0.433689230084419 0.808747176409233 0.471508698221296 0.32947577676503 0.317462748000398 0.608473821799271 0.34198298133444 0.794134084507823 0.649147062385455 0.178235785202123 0.78177161419997 0.867507348076906 0.91925522858277 0.95254134778399 0.56021424587816 0.171173544183839 0.0281108745117672 0.86462786585791 0.929908285951242 0.734364320440218 0.315295107939746 0.561270580003038 0.908655063663609 0.435939172157086 0.790131266897079 0.933368058956694 0.711551252647769 0.260584290691186 0.0382955981534906 0.594185199278872 0.925993029724341 0.0110696769831702 0.0584053103323095 0.187475041733123 0.29927114880411 0.921249630923849 0.158919186156709 0.833948616066482 0.876986575059127 0.247453989898786 0.773199209689628 0.387013218589127 0.920649911556393 0.297098424092401 0.754365167748183 0.790605140978005 0.392492680733558 0.988833841201849 0.0249159860331565 0.761808247494046 0.671211635842919 0.58622053746134 0.234152922832873 0.863642563794274 0.70284094850067 0.68408496479271 0.559188427035697 0.422011199817061 0.915038144988939 0.768668613643385 0.558162401202135 0.649153950025793 0.149833946677391 0.580444123996422 0.148769744355232 0.0717627684120089 0.157319401511922 0.259808362659533 0.40422640658915 0.892741476884112 0.398573523706291 0.514194295897614 0.701436519657727 0.68025637813611 0.0711561973625794 0.167102410520893 0.562182088356931 0.610667710544076 0.674176763279829 0.559241124480031 0.654746662578546 0.764550082937349 0.304259420149028 0.634820293341763 0.341119320194703 0.675965619771741 0.22422359324526 0.118686160778161 0.984873174401 0.254469263760839 0.196427513940725 0.906315444195643 0.91604280417785 0.684564132820815 0.473709069613833 0.454181616250426 0.241108340078499 0.685335175355431 0.557859082254581 0.874411196187139 0.900906953720842 0.559222231816966 0.79174613538431 0.176408044348937 0.679836914592888 0.40001011292683 0.916134026169311 0.589822928486392 0.924148268809076 0.490277999662794 0.361716197680216 0.101333335384261 0.600347368316725 0.760660869095009 0.253871263479814 0.0867431478085928 0.545269681012724 0.0511046570586041 0.636495080911554 0.964360196078196 0.912398938867264 0.159931089342572 0.189587545865215 0.705054546347819 0.402608822784387 0.832168541252613 0.0117901526065543 0.441988437462132 0.719058021341916 0.478209388256073 0.069106654021889 0.82793391735293 0.927548314048909 0.5213665801147 0.593936558251735 0.0708002035599202 0.507150243127253 0.16624798791483 0.145087917845231 0.227313372888602 0.636599463203456 0.02316281568259 0.782960066040978 0.233843778630253 0.727863916421775 0.987098831669427 0.400060638117138 0.915050420851912 0.123546740973834 0.100022577620111 0.987853334278334 0.825686210230924 0.948794763716869 0.246451399237849 0.527046217864845 0.572396573768929 0.117334236449096 0.551306166346185 0.0409026093222201 0.850165697666816 0.0367537237633951 0.218097429363988 0.998241590561811 0.875317096419167 0.618415956022218 0.653184219542891 0.657756313846912 0.778790690668393 0.383556989326607 0.197125915738288 0.468006062384229 0.166106351374183 0.560685603795573 0.71916299948236 0.477885305888485 0.93915154838236 0.415692615120206 0.0278267836081795 0.563030779291876 0.812914373995736 0.749078066949733 0.79557400402613 0.623308714574669 0.559760476672091 0.328892723408062 0.824439474029932 0.278870016208384 0.788879680235405 0.490772478578147 0.0560689697600901 0.646126536938827 0.158466966848355 0.192459628498182 0.175448063889053 0.726476215133444 0.395809093962889 0.191813640627079 0.302711040060967 0.266146202138625 0.465786839588545 0.135111849990208 0.133599216204602 0.513438653685153 0.462621806003153 0.145602006746922 0.560572435676586 0.927877825207543 0.615060515981168 0.88498193517793 0.630919094069395 0.109725912343711 0.68296791151166 0.964340406761039 0.633843193473294 0.983646659478545 0.168978735504206 0.309792630136944 0.412357073423918 0.0455124947149307 0.757287665852346 0.859216206206474 0.926772962964606 0.999286558846943 0.765580672025681 0.0970092516834848 0.633120912325103 0.97121255642036 0.965268405943643 0.910085632393602 0.555656136150938 0.328834646961186 0.188550487959292 0.672449115531053 0.0385591298621148 0.217675413237885 0.450491457311437 0.397488002453465 0.627861714987084 0.536942541361786 0.826096848070156 0.572629117665347 0.799539424015675 0.0732192082633264 0.933249931810424 0.936192660643719 0.404358285735361 0.817851929063909 0.210479321586899 0.798600722148549 0.414204346584156 0.796239456667099 0.164480017931201 0.139005286865868 0.778037133349571 0.661011921712197 0.992794839234557 0.527982197729871 0.202651472357102 0.96636462388793 0.206289343684912 0.224026362076402 0.548628563375678 0.738817077460699 0.178070289825555 0.348087568583433 0.771792286119889 0.501661807987839 0.402465108034667 0.0892619033204392 0.812238804376684 0.119047058518045 0.111084506718908 0.465445696129464 0.228507925204467 0.0511898507224396 0.750797602629755 0.623225800348446 0.189172715418972 0.462160436904524 0.208569408033509 0.563411729121581 0.850187423664611 0.266305514751002 0.195537502234802 0.955578752916772 0.80288638502825 0.95761317714816 0.668751128041185 0.516691043276805 0.93799675818067 0.986435719318688 0.471942357020453 0.896779476988595 0.239469086749014 0.990013857348822 0.957563104203436 0.0217211883724667 0.814734920640476 0.672911574675236 0.798985425017308 0.678711831301916 0.343610592451878 0.865438688716386 0.0640568231092766 0.67170922123827 0.949012514664792 0.550729977118317 0.91286048314767 0.0715066722477786 0.402711945381016 0.804334941930138 0.066303771417588 0.104367536534555 0.289686632733792 0.50775389371207 0.451039387644269 0.0585448188753799 0.100540869270917 0.420694470889866 0.0588952264538966 0.38190059123328 0.220958337243646 0.125639034199994 0.0521716733532958 0.376367766875774 0.534830936880317 0.490071723582223 0.457280694819055 0.156103702911641 0.555285960230976 0.045453483350575 0.341364469111431 0.803042131769471 0.242124410516117 0.47100771084195 0.849535119798966 0.63824330329895 0.829022920343559 0.268258069392759 0.698042310276069 0.220703799275216 0.872073154277168 0.729418087881058 0.173328318987042 0.505164045055863 0.300873019495048 0.375918401186354 0.867215398196131 0.349272469305433 0.325315050531644 0.34289588883752 0.0857137206825428 0.0894913762342185 0.95788963197032 0.0101936648366973 0.700486593709793 0.254166491334327 0.544285983475856 0.834331092052162 0.626397050812375 0.418386724824086 0.0438641697354615 0.135561952826101 0.788150805567857 0.570714539897162 0.841078984355554 0.576425951702986 0.265952491892967 0.626756613482721 0.476324143754318 0.382065812081564 0.701191065325402 0.398929628841579 0.319560549540911 0.262035742471926 0.0297219957225025 0.778804928336758 0.354937149297912 0.366033618019428 0.86504460232798 0.926632690767292 0.187290620501153 0.748580013173632 0.956615575479809 0.79246840062784 0.965269540476147 0.71933703474002 0.768083157760557 0.632508362736553 0.12044592234306 0.413357313191518 0.556835138779134 0.838299905497115 0.761671123267151 0.801388837620616 0.0521291827829555 0.16079536892008 0.0970297804521397 0.67319754394237 0.547781675660517 0.0913466648827307 0.624802602988202 0.363103302889504 0.544145526876673 0.237653416842222 0.76944497870747 0.441780003188178 0.738218269268982 0.165254908010829 0.475306062875316 0.448688085395843 0.766528009201866 0.836126037032809 0.212172060678713 0.619475218218286 0.195527178957127 0.882899327659979 0.698629349709954 0.370336990854703 0.336813187554944 0.25017574789701 0.344176320792176 0.167228863411583 0.721310337127652 0.231649725306779 0.863326877935324 0.216519454158843 0.793283653741237 0.345644319183193 0.780083549465053 0.041304280620534 0.925274241608568 0.4924594226107 0.447340124323964 0.238260314282961 0.933596404714044 0.649028243271168 0.302477649990469 0.957392824059352 0.342746964734979 0.827358814713079 0.437181711832527 0.389996456133667 0.131464553882834 0.839420390266459 0.795278013208881 0.260685237576254 0.190528519332875 0.823136180392466 0.951860513491556 0.566806851292495 0.59821863359306 0.792988928842824 0.925253144882154 0.797915063442197 0.975259614114184 0.246355510265566 0.370387434908189 0.438939072024077 0.0195269222953357 0.61877900757594 0.243221580896061 0.798580624880269 0.719537460901775 0.259253559899516 0.159845885767136 0.931090093101375 0.671119286925532 0.0367397640808485 0.0188363119377755 0.877299741297029 0.688013435718603 0.952805438921787 0.838672778985929 0.936691708806902 0.375640472762752 0.948722160782199 0.421008488603402 0.2947197466949 0.142209676650818 0.781431791288778 0.777373508822639 0.333598714906257 0.437261448584031 0.970612884305883 0.797557819164358 0.647071095870342 0.817514252129476 0.516455672730226 0.613372181789018 0.0668701818143018 0.941575672542676 0.26758770336397 0.334785803786945 0.977284484945703 0.902248976822011 0.627252552399877 0.161112887272611 0.125223032571375 0.543314344899263 0.386528246973176 0.365708405268379 0.0185926073486917 0.875760212037712 0.0500386446015909 0.450560266869143 0.479618064335082 0.452612766863313 0.264576764970552 0.535541609239299 0.398166085931007 0.50137198794866 0.67765468765283 0.995486761701759 0.890444630812854 0.364024979162496 0.709149411378894 0.192559337585699 0.649634046978317 0.0913286709482782 0.331218848577701 0.573624925564509 0.359839573274367 0.966941478806548 0.128924350359011 0.103258723712061 0.186386317189317 0.467569336751476 0.770234074415639 0.690409419692587 0.307859576223418 0.388597719545942 0.0992681024409831 0.0594520103815012 0.166044093384407 0.834121872687247 0.741791104823351 0.702207942290697 0.490513202403672 0.1816692283866 0.716416818378493 0.115381174702197 0.605780882355757 0.152374272597954 0.243206638121046 0.139244960660581 0.640784772280604 0.984079535261262 0.200086756984238 0.0542600249894895 0.498270086878911 0.409781160478014 0.294378114340361 0.940968107106164 0.58099305102136 0.962377571023535 0.237860807401594 0.215091131904628 0.335479712402448 0.19557883867994 0.54018143849913 0.277168384336401 0.845839161421172 0.86733575015096 0.569095964701846 0.315060314801522 0.846880728183314 0.806353244136553 0.829206215110607 0.988660943242721 0.556679672559258 0.0559864649060182 0.937333149788901 0.256146906332579 0.738386403897312 0.238497238184791 0.795010751280934 0.720784037825651 0.500642069336027 0.730953146317042 0.810931910984218 0.906708742266055 0.180816380111501 0.0933859204431064 0.656403178458568 0.963244041064754 0.0709226706041954 0.417770922617056 0.250505111995153 0.455209805578925 0.758678361135535 0.224045222238638 0.300210352705326 0.0173845519754104 0.90430501525756 0.0130276156985201 0.755120800049044 0.799640231216326 0.444631979102269 0.666042930034455 0.966314603728242 0.897299394602887 0.265550966733135 0.395218888579402 0.0395676059392281 0.0371843205695041 0.407387199853547 0.0625205858843401 0.349520538686775 0.405423027663492 0.818192990925163 0.530977395349182 0.722411912637763 0.515074191316962 0.689241545717232 0.823080894637387 0.978947108676657 0.928361193910241 0.243470512125641 0.543849682889413 0.585204579508863 0.994011142442469 0.720107763330452 0.719239129563794 0.692523822702933 0.419528224722017 0.931346959143411 0.622052737304475 0.809880573458504 0.271242217421532 0.831312563216779 0.250969902670477 0.916782308691181 0.176731551613193 0.279857759061269 0.372795883296058 0.416735104352701 0.672926711072214 0.183189109396189 0.298068536513019 0.250897273228038 0.604805206300225 0.902007285670843 0.102132110116072 0.382166071839165 0.223995480986778 0.974814501884393 0.489845758222509 0.0276530641387217 0.0271430438337848 0.514823563820683 0.973682910129428 0.920610866995994 0.553255830258131 0.117755707437173 0.805022383572068 0.576949310947675 0.321658643819392 0.406353774203453 0.918675064342096 0.807845667477232 0.488004007437266 0.229558279637713 0.15876670793863 0.222499149939977 0.674183380310424 0.296380645346362 0.739707103227265 0.95507052015746 0.384214358711615 0.487285603107885 0.47360350968549 0.434217914394103 0.554504103448708 0.15957353411708 0.488432083469816 0.330764857858885 0.4441862378316 0.104034833610058 0.251919527121354 0.518798336212058 0.6079864418949 0.569287530814763 0.626190123562701 0.13067889865255 0.137597238214221 0.360633245606441 0.300173736948054 0.844931229311042 0.478076712954789 0.389283005530015 0.186098251503427 0.658033360599074 0.705100937709212 0.717645728681237 0.212189469137229 0.16790932521224 0.265162023082376 0.765160775368568 0.10544390845811 0.634541026391089 0.238098865374923 0.807845801399089 0.622753519730177 0.550939728482626 0.553440363744739 0.207489116878714 0.392672526955139 0.973037966894917 0.976509656410199 0.347344067159574 0.914371873373166 0.885192771055736 0.722725192282815 0.374425442158245 0.805593749769032 0.0195902583445422 0.792950578785967 0.717321440014057 0.262426112471148 0.714314542326611 0.667125319221523 0.902511007268913 0.992218736675568 0.618184127374552 0.857185068016406 0.582064447551966 0.8080353056686 0.224656202336773 0.787328766004648 0.699944538420532 0.555098842813168 0.818288339369465 0.585119420189876 0.129186611999758 0.627045710897073 0.246857511394192 0.700936937881634 0.938658608761616 0.770716777427588 0.154491824961733 0.315398044290487 0.452808064809069 0.874060536669567 0.727650506985374 0.117065344639122 0.446184833010193 0.544172628880478 0.532746663291473 0.685696433139965 0.538397759320214 0.0274558769958094 0.588750668724533 0.243272392370272 0.608263362101279 0.653396552302875 0.260974379477557 0.534670637717936 0.067521370279137 0.650247817307245 0.495124329973478 0.988376853722148 0.869752256670035 0.0340794116747566 0.67889496586984 0.778002872173674 0.846192457885481 0.904014274822548 0.907609109980986 0.181439649672247 0.973054559836164 0.129807083492633 0.441916356845759 0.69384636559058 0.370053279357962 0.0571898625185713 0.151740092670079 0.0500115538924001 0.708744045358617 0.694969421613496 0.127465174444951 0.896207350133918 0.928543372815475 0.236634880951606 0.527455680833664 0.229469312189613 0.395685989118647 0.663604202168062 0.0165291264536791 0.0967144421907142 0.289663764596917 0.184264541331213 0.863568266667426 0.571552768331021 0.79424188261386 0.353399580691475 0.721976683887187 0.363226408194751 0.38932862885762 0.785971346499864 0.75490396511741 0.818538041168358 0.40337152459193 0.446558156670071 0.466245509504806 0.579793905715924 0.552528192696627 0.852764255392831 0.805035700614098 0.813157412202563 0.0818013782356866 0.0532675515371375 0.065225957701914 0.404856448769569 0.273962495825253 0.624025310843717 0.700886657484807 0.515316753766965 0.666323760021478 0.428939773452003 0.72419312244514 0.969059028173797 0.440153890566435 0.594465479978826 0.0161048841360025 0.451539422126953 0.537273187744431 0.764503034874797 0.659727569604292 0.52345038094325 0.341384809329174 0.568644092530012 0.0171059820638038 0.929867179316934 0.640617115483619 0.351360392668285 0.249049626193009 0.826464509901125 0.400107955636922 0.841965829650871 0.553252718246076 0.340582302764524 0.0524858233751729 0.349722746401094 0.0735260232398286 0.0323595606675372 0.555919739315286 0.417079945760779 0.811380224891473 0.906603752369992 0.52937776099192 0.331834543140139 0.554118413338438 0.252953495604452 0.982902720100246 0.672216586386785 0.251997147861402 0.487734978478402 0.797409865707159 0.0760713284718804 0.628305339785293 0.354215236261953 0.796132813377772 0.539457985016052 0.974364593592472 0.57060270661721 0.436856040151324 0.0833687726920471 0.0300533527438529 0.414541803158354 0.248950902272481 0.135903788253199 0.143479369040579 0.937591535302345 0.428501741332002 0.350989652017597 0.346466637193225 0.439173137466423 0.715777650610544 0.23434999011457 0.195089415833354 0.637960929407272 0.850715836212039 0.0406402829103172 0.989672337018419 0.205864711818285 0.682543952481356 0.900571911658626 0.174887563802768 0.823294198503718 0.478712044011336 0.659596707203891 0.2709212274733 0.173668039324693 0.522109715500847 0.546649060475174 0.994628833155148 0.943573339949362 0.950113726211712 0.425017122249119 0.455279736991506 0.624512146301568 0.3411686608335 0.542323026724625 0.0175614131917246 0.66713012289023 0.33131578564411 0.66004899704596 0.531672412680928 0.549026862885803 0.915869093928486 0.617108555985615 0.131360985264182 0.442528365214821 0.284863286272157 0.985029072121251 0.536676838551648 0.458849780932069 0.959029021849856 0.809963089376688 0.0749900519195944 0.0270241804630496 0.545485571115278 0.74533809829969 0.2420560732577 0.627018636092544 0.512659294856712 0.969796162662096 0.937258522352204 0.424773322693072 0.774721724879928 0.609889524281025 0.265363651083317 0.77943996803835 0.123536444895435 0.580207622374874 0.568213472212665 0.850658357688226 0.549041298786178 0.199492342167068 0.704994163033552 0.826902663034853 0.727214811006561 0.117196202198975 0.608548425033223 0.47804204425076 0.95600623217877 0.0554238886851817 0.492144876585808 0.466139086114708 0.373854917064309 0.257806365266442 0.437897927081212 0.629400489812251 0.0798626304534264 0.218494599182159 0.35195975406561 0.0678266100026667 0.965558499358594 0.818455979800783 0.248723002076149 0.745632407602388 0.947224218524061 0.0349115845817141 0.250961015883367 0.463749651634134 0.370907140690833 0.724393591249827 0.103368181204423 0.969040540042333 0.367141977443825 0.979799871204887 0.460410205919761 0.801731986911036 0.075140765872784 0.0243934955517761 0.938380467584357 0.879043910992332 0.731451618685387 0.407697459456976 0.720685889238957 0.637835768943187 0.583438582164235 0.336371056872886 0.210829879913945 0.256318455161527 0.854785259778146 0.298212775425054 0.693187389373779 0.0967231498775072 0.737461392024998 0.415162736577913 0.612865989205893 0.986294907515403 0.251531513778027 0.562159816760104 0.144793668473139 0.987041580651421 0.762327581245918 0.628452532123774 0.679141961340793 0.018140051276423 0.481872249955777 0.84098223722307 0.945923992411699 0.156258470709436 0.716733065510634 0.395126644540578 0.79448459074134 0.0778724156483076 0.835939991681371 0.396714072185569 0.0343615308613516 0.417172142316122 0.801130050111096 0.254959388717543 0.972476472191047 0.65284654468298 0.240176929922309 0.678623290052637 0.623304705447517 0.0246564473165199 0.860629530595616 0.512694780922029 0.650439414076973 0.762426566556096 0.61107765134424 0.617499178384896 0.142638166665565 0.186930185840465 0.427379549462348 0.67574253638275 0.632134400354698 0.231501518988516 0.149961422537453 0.166986319401767 0.762088909444865 0.405902803295758 0.274121789305937 0.956795607716776 0.590112029588781 0.338035947824828 0.923701673527248 0.929700845142361 0.389023224785924 0.997189755842555 0.183567786011845 0.391202180667315 0.314293965524994 0.542693177058827 0.302165582326706 0.672307140612975 0.196958000087179 0.436965235793032 0.481232970163692 0.350188893582672 0.765068786034826 0.883189259723295 0.101767725567333 0.956238504312932 0.0700064931949601 0.0507904376555234 0.887789102590177 0.508102381897625 0.377147858701646 0.360020957638044 0.16959343544906 0.387116907299496 0.845999488474335 0.549102355397772 0.285275733785238 0.948617044340353 0.423337344764732 0.572380830228794 0.606958447340876 0.835444309082814 0.483077906491235 0.745897914946545 0.719114101408049 0.416375989317894 0.825998410433531 0.759159974332433 0.322838425084483 0.727089677280746 0.480919767275918 0.74535909014754 0.764836326732766 0.0624007366551086 0.198536635681521 0.602778068478219 0.649756961888634 0.597037685986143 0.219074319014326 0.341131015883293 0.0604364114115015 0.483632587315515 0.690439776158892 0.54646837960463 0.840959810728673 0.192273083648179 0.54461536440067 0.448418657667935 0.302053580088541 0.406189254543278 0.78857576751383 0.358892719461583 0.0505588134634309 0.28716070675524 0.0497132161003538 0.789146719728597 0.407747649035882 0.684535951835569 0.304926545545459 0.0634634501626715 0.196371090195607 0.439871973991394 0.521685560082551 0.875334158663172 0.395120067847893 0.070805238422472 0.438841081331484 0.943611061656848 0.669300428018905 0.586678647487424 0.660102723683231 0.951067513304297 0.343660528939217 0.842237821025774 0.183508042572066 0.909777983920649 0.312448484520428 0.320218722687569 0.518128314092755 0.967923151610885 0.845647392466199 0.599724912659731 0.356462061712518 0.754779434385709 0.502782972278073 0.482055289556738 0.113945208759978 0.580052812164649 0.336821730663069 0.970640807128511 0.565263155011926 0.368133037686348 0.406403146421071 0.13346973935375 0.70942897636909 0.792327508840244 0.144152824722696 0.862223580342252 0.942970637881663 0.483623325270601 0.637843474866822 0.202947165595833 0.680652363633271 0.91332943346817 0.653750366244931 0.274633416442666 0.948106551275123 0.96374439525418 0.244633702524006 0.106137353302911 0.466111470782198 0.462212326207664 0.531853832541965 0.9114670382021 0.855782852456905 0.376372408501338 0.491767147104256 0.378086267600302 0.270120119135827 0.474362108551431 0.46206922643818 0.698794373939745 0.419727095454 0.013945285610389 0.878989184896927 0.714689452303574 0.888907490018755 0.0578117578243837 0.848745926357806 0.928315529783722 0.0335200315993279 0.622661777955946 0.618601535758935 0.47733842065325 0.41468149080174 0.368752707953099 0.544920211348217 0.773109648928512 0.163516870830208 0.219403334592935 0.978569924794138 0.0879226204310544 0.503859598445706 0.878592659102287 0.773515384444036 0.42176321917912 0.148462975248694 0.50837230843259 0.0815584522834979 0.764039265324827 0.219999376756605 0.129633682807907 0.81290049521951 0.115898308770265 0.689542952878401 0.969709807957988 0.0415730820735917 0.0220582063007168 0.190344937359914 0.71649215783691 0.652132601726335 0.228418009239249 0.3284858598141 0.798132491917349 0.103675872781314 0.192158213730436 0.864213162648957 0.551318606557325 0.26398341207765 0.465534312292002 0.469658897372428 0.806046358165331 0.211896164594218 0.599748979639262 0.24303405295359 0.0301139022503048 0.626684206014033 0.844619309629779 0.179134363066405 0.978110379660502 0.240626084932592 0.243564778130967 0.909584459459875 0.0456733254157007 0.673168006681371 0.146848616632633 0.633553634593263 0.641435486602131 0.615250412335154 0.692592731837649 0.156888223609421 0.773135286089964 0.467689561238512 0.992939880525228 0.349952466413379 0.567706855966244 0.3828482573363 0.763260743450373 0.822465340681374 0.470929426024668 0.779742832204793 0.10205393179087 0.389283073989209 0.944597613734659 0.541728447789792 0.983811852897052 0.400495116813108 0.445254671254661 0.950257210689597 0.578273471731227 0.972237691823393 0.622157906761859 0.27818613444455 0.365428088610061 0.0979687271127477 0.761442310281564 0.368049612666946 0.403944912524894 0.336617443817668 0.0124945497699082 0.395220230103005 0.0685904546407983 0.360957409571856 0.745582143110223 0.967994419937022 0.487677795689087 0.314488914951216 0.303412124905735 0.541711635640822 0.206017636058386 0.824224592144601 0.410754129053093 0.490085410580505 0.0108276788028888 0.442515232344158 0.972089859840926 0.160511395342182 0.494200986016076 0.222658160594292 0.741534519994166 0.508877355880104 0.354802664092276 0.770377931846306 0.136903666823637 0.238811011104845 0.577703214250505 0.625180727089755 0.473666675162967 0.0782040105480701 0.545508860379923 0.137924210159108 0.454636046076193 0.415385668526869 0.443440675716847 0.691045758966357 0.930782148893923 0.667970318431035 0.713206383208744 0.556847710146103 0.838009475779254 0.256934881107882 0.811766519148368 0.620940427761525 0.0755615469673648 0.895549963230733 0.957014486512635 0.615712478472851 0.824178986565676 0.444094200553373 0.331625648322515 0.482062538855243 0.982008775332943 0.0142665973398834 0.470788110573776 0.234072728534229 0.762656261213124 0.876423934067134 0.904221584245097 0.50321268026717 0.613916691236664 0.294735076483339 0.603279582785908 0.836720603290014 0.0349038459267467 0.0253961523668841 0.975430464060046 0.456317263508681 0.58900114109274 0.766204609351698 0.199453689691145 0.25344404791249 0.779414299067576 0.555131094239186 0.156956627252512 0.49080064158421 0.992125007740688 0.835992643486243 0.551025345579255 0.0870279878447764 0.307656446038745 0.665497016136069 0.0121036708215252 0.967207489798311 0.0415358801488765 0.625476277186535 0.313189897593111 0.846199957740027 0.408026337195188 0.208728339856025 0.843358411134686 0.312644913541153 0.219190812821034 0.473615964187775 0.218270361667965 0.297919060357381 0.226842896181624 0.573069718042389 0.320251185023226 0.644229115690105 0.38875733803492 0.632077645377722 0.419050465063192 0.565752096339129 0.693341990287881 0.958962329456117 0.969205162737053 0.612051139932592 0.405156420362182 0.683988339826465 0.286676235559862 0.82895965206204 0.176779733516742 0.222142500127666 0.614354464963544 0.516205290718935 0.265921144727618 0.943961136850994 0.44958560064435 0.115139840138145 0.592757501685992 0.203838126279879 0.78097548263846 0.232604843089357 0.236562949931249 0.605492548365146 0.155523064066656 0.348224569952581 0.679365981952287 0.858009142223746 0.77907326371409 0.0164625327149406 0.614258922436275 0.0369981150189415 0.774983989747707 0.987836346256081 0.53355492411647 0.713820734173059 0.614284612382762 0.613043940698262 0.26914462010609 0.139869574049953 0.901847110749222 0.956653943976853 0.126422021365725 0.418032930705231 0.453299171014223 0.275715472553857 0.296378788189031 0.768096156017855 0.271891901397612 0.248295584358275 0.703112067193724 0.990159369325265 0.373450194145553 0.665163229389582 0.862309753180016 0.756317588007078 0.382664127920289 0.183557274183258 0.296706207538955 0.858046368351206 0.504669954767451 0.0756906912033446 0.883492975134868 0.831055536514614 0.84544449047884 0.329449372722302 0.224348197276704 0.799427833685186 0.238493152530864 0.391582887778059 0.197297582584433 0.341180488830432 0.816543694378343 0.537650819953997 0.68135681058513 0.956121909315698 0.493061249691527 0.963601316229906 0.37986820833059 0.996893146357033 0.90441257594619 0.5052748906333 0.863346335098613 0.54428080708487 0.944448982139584 0.0453855215804651 0.6720325581613 0.634602171746083 0.675227335768286 0.192367685725912 0.712316727398429 0.699047542954795 0.232723480106797 0.847934287290555 0.999460801787209 0.612851824606769 0.669161114941817 0.673699230435304 0.317343998267315 0.879431893678848 0.26723489602562 0.421179854182992 0.976623217535671 0.4228073440562 0.0891696097236127 0.69265473396983 0.781810018655378 0.475154920187779 0.0389419723465107 0.0561385911470279 0.135513929277658 0.213069377925713 0.463869641469792 0.530461482943501 0.155313166563865 0.114813228929415 0.469810825150926 0.786687709961552 0.252614118945785 0.997969597803894 0.516350148529746 0.578890116193797 0.152880295300856 0.702050012000836 0.205774792626034 0.817891991753131 0.487859101912472 0.0320776055986062 0.0731408909452148 0.994184024266433 0.68120388841955 0.12433502969332 0.370690583284013 0.956808478736784 0.806149887598585 0.869768517457414 0.486524381125346 0.229746332895011 0.437561287176795 0.7487207641243 0.305976323953364 0.992392958640121 0.462692275638692 0.118822691000532 0.98720446558902 0.540496547871735 0.535425516506657 0.734178870015312 0.824145301415119 0.68888460293645 0.497565505083185 0.473986561005004 0.656485766523983 0.030408470868133 0.418921414411161 0.801963453900535 0.613416050071828 0.228413846136536 0.712319324929267 0.937094844256062 0.486429700676817 0.337556499505881 0.562920975585002 0.461101122384425 0.953776309464592 0.795515159775969 0.649772048727609 0.72295453265775 0.0561447448679246 0.917528099464253 0.910883387152571 0.994617735850625 0.476773388199508 0.838540348939132 0.324235866710078 0.488673485571053 0.402421781432349 0.968032520820852 0.176174565765541 0.0193657723488286 0.568906654054299 0.734749420695007 0.802985528693534 0.111448888501618 0.772518040477298 0.678415607216302 0.335143378835637 0.385375000445638 0.890854524590541 0.893655464982148 0.754367181186099 0.633624675644096 0.719901663584169 0.0310716385394335 0.837036982269492 0.541434332109056 0.321091193857137 0.825153057633433 0.810196157896426 0.440033636344597 0.168973355118651 0.0873787667625584 0.351957779352088 0.061635979458224 0.981887691533193 0.706889309915714 0.227558475704864 0.493639546171762 0.48435662535252 0.913393472319003 0.203431409976911 0.515914982245304 0.0906524768983945 0.358077145949937 0.661191460213158 0.170948404252995 0.960738676355686 0.0963843453256413 0.418738976882305 0.45798511872068 0.682830784979742 0.179935899216216 0.0346459285635501 0.128785929786973 0.397634625451174 0.202013136933092 0.0763668525218964 0.984884094218723 0.629099522449542 0.498338125636801 0.114286978954915 0.778034712383524 0.507975461317692 0.272035017532762 0.7201170090097 0.271762939027976 0.711599668741692 0.840250507323071 0.461497980332933 0.0741371222771704 0.898022475363687 0.594450464595575 0.433609811656643 0.117701632741373 0.499619533538353 0.298174169280101 0.425663370126858 0.854897779263556 0.314802324138582 0.875201496961527 0.985221298392862 0.233929638445843 0.262644711898174 0.0393581846542656 0.65122139002895 0.0703222631872632 0.222193456357345 0.337970968293957 0.19474617249798 0.845362676670775 0.0544326232955791 0.0791853622626513 0.546341161215678 0.14905726836063 0.412354571321048 0.800052916838322 0.740672887505498 0.349947824557312 0.202784990144428 0.643587373672053 0.780780124531593 0.392333148682956 0.589776634396985 0.994051520689391 0.712991951033473 0.404767201722134 0.663111318559386 0.213808992619161 0.59772903372068 0.769871792278718 0.572746131254826 0.767408551641274 0.253874108800665 0.434818806326948 0.167036681626923 0.374864836316556 0.901919505079277 0.264726452266332 0.523069737220649 0.717515892016236 0.159825206710957 0.873709776191972 0.226585212086793 0.279623968377709 0.247470769316424 0.238472566367127 0.588144465787336 0.692379156670067 0.434298240079079 0.0296778877172619 0.711426279351581 0.244255422141869 0.0924454236542806 0.984783785594627 0.0438654411863536 0.778791790625546 0.0654450561664999 0.460137651197147 0.455661571950186 0.0900145063595846 0.570513118195813 0.627289365928154 0.588131303642876 0.656375230741687 0.0914893548190594 0.896285666760523 0.682679446134716 0.256508856085129 0.467714064558968 0.310888473745435 0.305951928508002 0.22588193931384 0.82264798427932 0.855158111138735 0.846194585883059 0.289952900274657 0.729666265137494 0.0566122752940282 0.989912205126602 0.697665175260045 0.469919912226032 0.340578296172898 0.211726389941759 0.846262677425984 0.762085352332797 0.186528499559499 0.632887621140108 0.295280339904129 0.360069693899713 0.995816228603944 0.768617527179886 0.380491040858906 0.122513656928204 0.327592128261458 0.578473507422023 0.802158329566009 0.609456949303858 0.182424301949795 0.470016996583436 0.617932611522265 0.294515746133402 0.29719418260036 0.486551569567528 0.171552020031959 0.537380879358389 0.756385129110422 0.967191860356834 0.445108891204 0.153367992837448 0.855406832150184 0.79873563493602 0.245679265044164 0.106301213034894 0.286186717515811 0.613234108353499 0.235127249988727 0.0863961837044917 0.659270976053085 0.297112536136992 0.765185613839421 0.306722043962218 0.470332298655994 0.892058693924919 0.0285305526526645 0.383109656898305 0.130556737945881 0.67401022833772 0.600158608108759 0.430121069347952 0.184417015861254 0.33605097487336 0.402871303402353 0.701651586405933 0.918213778224308 0.551666069237981 0.361949157863855 0.88150917382678 0.23457527364837 0.0556024733674712 0.689455835672561 0.629021528756712 0.573517679972574 0.528651145708282 0.483226942848414 0.80144742578268 0.855399190767202 0.48915340826381 0.0313738303305581 0.149617038215511 0.847748790995684 0.985067083339673 0.25534851354314 0.975404740690719 0.404058407496195 0.125310929566622 0.221869893772528 0.0470498955156654 0.10295118011767 0.541385281903204 0.174898120118305 0.828093387628905 0.514887747657485 0.833175967622083 0.511606288494077 0.840132569188718 0.259341202650685 0.394859060139861 0.978099363262299 0.854429594902322 0.725530223629903 0.431205009354744 0.33175628621364 0.488440217666794 0.0169087289972231 0.162425426819827 0.730681375532877 0.744297407215927 0.3999012701842 0.445824249444995 0.730764010851271 0.302725882336963 0.444155650862958 0.30808367935475 0.86858984536957 0.320949370379094 0.284730536288116 0.977321813877206 0.584657896193676 0.616805945832748 0.538639215128496 0.230000821535941 0.0115166604309343 0.853205343743321 0.786174741992727 0.682697797808796 0.370223541983869 0.216423064996488 0.440001780460589 0.102274290411733 0.995942315226421 0.303406211598776 0.651993750114925 0.425702912111301 0.505001892885193 0.302681783321314 0.186147966939025 0.322314037568867 0.0572321901237592 0.14558059261879 0.721972956894897 0.0704509404255077 0.177979900178034 0.0346528627653606 0.0110540922591463 0.38545435041422 0.0936392346746288 0.251721191385295 0.870280697338749 0.485645874943584 0.807138664254453 0.303028082195669 0.664759006199893 0.525912150053773 0.0978324744151905 0.075494393799454 0.161646905867383 0.581422880715691 0.702682261010632 0.419350951137021 0.151895858312491 0.0843281413987279 0.775057336282916 0.198965249937028 0.627048750531394 0.309929062395822 0.0704247728781775 0.426313405388501 0.0881429403275251 0.915486625088379 0.57807323965244 0.453048464455642 0.277544976749923 0.824504718638491 0.903831542942207 0.538311578184366 0.696862766428385 0.730935486380477 0.139656105835456 0.700370200863108 0.0691539330477826 0.516373618047219 0.188638403394725 0.126427386077121 0.506843333875295 0.977221679743379 0.618856632004026 0.923880606498569 0.871302262260579 0.0288882899750024 0.735509521283675 0.4009843824571 0.645879123106133 0.087655379017815 0.267883257148787 0.832701237916481 0.489002147559077 0.64231801827671 0.114791089871433 0.775765360861551 0.784143547790591 0.742328968888614 0.763033863226883 0.869566625070292 0.18618978144601 0.911810225755908 0.405611399244517 0.19511229687836 0.721808139425702 0.561473709265702 0.912221335894428 0.588678844657261 0.0541581111471169 0.942079460294917 0.378895746399649 0.532513661617413 0.826012689361814 0.0470002349396236 0.357798171506729 0.462925679078326 0.852546606557444 0.175471297372133 0.481035421823617 0.599260485025588 0.912820803092327 0.402942808684893 0.619310035402887 0.336638561750296 0.821069025981706 0.668140762001276 0.574007408926263 0.289528886154294 0.940773507351987 0.392549807280302 0.969131770331878 0.0883199509093538 0.841005309585016 0.242557038047817 0.74561029459117 0.525673463961575 0.24622344717849 0.795845674080774 0.596921703203116 0.528284271503799 0.916676581418142 0.0400356188067235 0.839841021534521 0.0221365632652305 0.15698877011193 0.53940462902654 0.811441261218861 0.160923872820567 0.767348331753165 0.617364070592448 0.81557786376914 0.340235259828623 0.501817829257343 0.513171075738501 0.751869707263541 0.498714727500919 0.481040168558247 0.239855687113013 0.477686975914985 0.837111102601048 0.412895968065131 0.108775774103124 0.565260409268085 0.321157894318458 0.800403790953569 0.0250212241802365 0.333635751560796 0.209783001455944 0.776548420405015 0.395935142091475 0.673193909381516 0.640503157433122 0.46955628072843 0.195850322027691 0.690232516985852 0.167863687362988 0.439542154190131 0.387032462537754 0.472339898408391 0.0664366680011153 0.978316156012006 0.097135142609477 0.730806665308773 0.0793129250220954 0.706012174300849 0.641140864046756 0.862476914166473 0.103819719147868 0.15256998475641 0.342933218921535 0.740425720771309 0.380266660433263 0.816436903567519 0.388600680348463 0.758571764638182 0.373835127055645 0.646283748983406 0.279027961019892 0.546550421149004 0.816575411269441 0.954939070206601 0.432237255985383 0.848557276560459 0.495993896813598 0.871571473546792 0.319549075595569 0.337049443922006 0.482552213640884 0.909019947019406 0.816768505843356 0.498985376660712 0.798840800474863 0.32910507921828 0.411177375600673 0.7134442761424 0.0516616894677281 0.912247867404949 0.114307792163454 0.622891373496968 0.879640913659241 0.261199776188005 0.513709608491045 0.8883539458015 0.322182215356734 0.60159992654575 0.822079525638837 0.125786203949247 0.552238411381841 0.765255140028894 0.836347563148011 0.797547104263213 0.739125499729998 0.354537679066416 0.410754743572324 0.129546878854744 0.758248635167256 0.664588463283144 0.790248403113801 0.795069508631714 0.828109541924205 0.921958892147522 0.682374818394892 0.89943504647119 0.282490893751383 0.889462505301926 0.436999458244536 0.663579971070867 0.0195772340404801 0.25285829306813 0.343247840320691 0.555247728191316 0.855121008791029 0.68492585322354 0.295417431399692 0.96004787906073 0.474133580005728 0.591233292764518 0.661559996800497 0.804059276578482 0.475135217770003 0.574562855940312 0.535866626985371 0.415741880384739 0.887035633092746 0.0387806877866387 0.910086144569796 0.206821219760459 0.0737845963821746 0.590795083157718 0.0487079124269076 0.596511083343066 0.342732546352781 0.862113540139981 0.337952775205486 0.532634260670748 0.593644456239417 0.0168793570064008 0.326181927178986 0.620880810637027 0.399790089686867 0.332041108270641 0.228905689257663 0.211245432293508 0.99711032565916 0.0486394640663639 0.292742000683211 0.51416741586756 0.31426650670357 0.933755365349352 0.404351123336237 0.421529541441705 0.830358228681143 0.908495668070391 0.887574096464086 0.45127790247323 0.144096677580383 0.0642040677717887 0.676653380889911 0.580909665878862 0.532835080299992 0.419191300377715 0.914854867509566 0.486950513562188 0.55102969331434 0.886805938896723 0.230989597961307 0.684904020964168 0.110168228119146 0.976471480613109 0.509776280419901 0.657699923755135 0.762223996953107 0.811452019684948 0.0771330946148373 0.769321043132804 0.0319522194727324 0.79018614950357 0.721607277845033 0.910465559484437 0.317066424125805 0.320446869982407 0.595538119608536 0.357608813606203 0.795561137616169 0.0210891521163285 0.93864816009067 0.0384586727945134 0.617624938616063 0.446113031762652 0.0219833469786681 0.393289823969826 0.0114786150981672 0.850846970374696 0.880830080979504 0.955915115526877 0.145438538868912 0.263121013399214 0.681714712025132 0.492939343459439 0.147523773652501 0.661144756521098 0.972862666640431 0.25005451703677 0.343894365723245 0.647889280512463 0.254060309971683 0.226396440814715 0.0603357925312594 0.750758723109029 0.585709129071329 0.784615555494092 0.504248488619924 0.831225255385507 0.805269864941947 0.348827276399825 0.869652407437097 0.684066877735313 0.469316943236627 0.964892475532834 0.0666687847767025 0.205108267227188 0.048743586812634 0.0604863596544601 0.945281085665338 0.16082757309312 0.570940974790137 0.898188075388316 0.33049171627732 0.310359419248998 0.148079302264377 0.998708717378322 0.898741011770908 0.737440133255441 0.515806341883726 0.795545880205464 0.302788997334428 0.517076691666152 0.620405252736527 0.429071700312197 0.476716650740709 0.371393175383564 0.93075579763623 0.494479254430626 0.687982176144142 0.402377613265999 0.178148276372813 0.239081921654288 0.721458685665857 0.979224347206764 0.251362198286224 0.724552407821175 0.966180118061602 0.151258776129689 0.0182777178753167 0.0486906282091513 0.828598756857682 0.383964544427581 0.114905541657936 0.967204144056886 0.113750436129048 0.0302013490744866 0.03587558707688 0.318818142081145 0.968117003384978 0.673035308790859 0.707985115721822 0.43952749977354 0.450430585332215 0.464274250289891 0.968750195610337 0.173446244443767 0.174263501313981 0.89136944076512 0.979638783955015 0.20165385870263 0.349232612454798 0.40143891900545 0.784296146100387 0.934069169848226 0.637558003484737 0.993799527005758 0.723076122640632 0.186962722167373 0.660383705571294 0.773689424542245 0.693094930506777 0.979830025290139 0.283174024769105 0.40622611786006 0.539735548554454 0.725566629399546 0.496340602755081 0.342879011225887 0.278011100650765 0.309614361703862 0.171245148121379 0.256210385984741 0.463002641503699 0.198551031243987 0.752402702197433 0.773537577439565 0.975475208712742 0.307804694999941 0.95155026610475 0.351678951277863 0.43686333186226 0.447718981653452 0.306677124358248 0.901818452624138 0.911038364015985 0.943087477672379 0.722673266560305 0.579446325479075 0.497772269137204 0.122236999955494 0.252208210553508 0.59823528992245 0.334820059430785 0.963532038060948 0.657922569420189 0.0527316677174531 0.35295812584227 0.13382107631769 0.462905317654368 0.335903245694935 0.691022343847435 0.0131966843223199 0.254946149815805 0.208574708434753 0.206078161592595 0.939665331176948 0.701179928835481 0.0215995204797946 0.421014208288398 0.935653288401663 0.736044754856266 0.620021928271744 0.299148559132591 0.357720163753256 0.140625777996611 0.21879167312989 0.771173230141867 0.154328507371247 0.619165678243153 0.395272217369638 0.998839262607507 0.510166505202651 0.769299453131389 0.865566526465118 0.469778098890092 0.994718690111768 0.912018613237888 0.0918731594202109 0.259106489957776 0.806358695977833 0.310936608626507 0.943502656868659 0.564116119369864 0.0508937511080876 0.397972944565117 0.439651186866686 0.525051932849456 0.633335653834511 0.415526936263777 0.789954035033006 0.385398459360003 0.0756289606029168 0.578402471211739 0.679138913177885 0.979513883728068 0.493847925816663 0.512212342757266 0.791312478429172 0.425933912794571 0.780058450987563 0.100051292679273 0.63858464383753 0.275151857458986 0.635999208840076 0.469385496706236 0.175910418846179 0.987466603680514 0.915229628121015 0.63597023193026 0.37711225531064 0.836962892133743 0.62086459341459 0.823721310805995 0.0177748574339785 0.274000553374644 0.381002617976628 0.774858140542638 0.511240089430939 0.617740979716182 0.799510333929211 0.858242892108392 0.337544936586637 0.323900321691763 0.114423846402206 0.501460622320883 0.0868031964334659 0.574534782369155 0.484545244723558 0.721258527808823 0.195355341539253 0.411543367442209 0.107136670139153 0.585061328529846 0.744582310179248 0.950074009045493 0.295722507005557 0.017163556246087 0.949637557710521 0.225097756762989 0.20380659379065 0.411276220073923 0.624371330579743 0.49088170141913 0.536550841825083 0.948047175486572 0.624419812827837 0.517746325850021 0.104027219656855 0.3951338560367 0.123313436880708 0.42837953890441 0.0425390498316847 0.438159383346792 0.239505644189194 0.413887138026766 0.0277396299829707 0.0419266701233573 0.017773206345737 0.62958686063299 0.452463415178936 0.191490042544901 0.315912764999084 0.512423029039055 0.707900983060245 0.33175197835546 0.0157077352935448 0.719782976547722 0.686566035707947 0.0758801615890115 0.296287840725854 0.0716776561154984 0.427307721937541 0.900018472780939 0.492811586617027 0.0281565930368379 0.0391268499731086 0.0580055058724247 0.16513681843644 0.80081223141402 0.261269862728659 0.469292814712971 0.569517063198145 0.484467780725099 0.562691576662473 0.5934184314101 0.607098684271332 0.0895565786608495 0.162368032198865 0.268705523295794 0.499319592602551 0.288253524329048 0.154565955665894 0.108217854490504 0.9514636804373 0.872513331912924 0.747534911888652 0.429633737157565 0.0174898694152944 0.761467468689661 0.215268695692066 0.6043442912912 0.522897155510727 0.3956327677425 0.0158436825755052 0.553793349491898 0.0848266089265235 0.545237530777231 0.296649070850108 0.413290283111855 0.626552778191399 0.527325018509291 0.160539912399836 0.686472469046712 0.889953280505724 0.480147927203216 0.796907523435075 0.20250545949908 0.938844939474948 0.131719731956255 0.212460814875085 0.752026709550992 0.368946944435593 0.385152733726427 0.789837566351052 0.90174961125711 0.951430661438499 0.807423413703218 0.789221319735516 0.871981335284654 0.856307713193819 0.44285242798971 0.168824702086858 0.264089547800831 0.913911573574878 0.567495438070036 0.160027689184062 0.171163825283293 0.0876650280761532 0.245022122703958 0.291831646454521 0.873030810581986 0.573034679151606 0.939135083830915 0.180699337248225 0.289294907611329 0.347903465905692 0.0497453091712669 0.673229940815363 0.334377827097196 0.150360037835781 0.0816817207843997 0.474327517987695 0.414593890001997 0.911818581696134 0.704565888999496 0.0455272851279005 0.541783945837524 0.0388014675723389 0.244435685803182 0.257660536349285 0.781739266884979 0.831695138779469 0.859035161603242 0.461513392410707 0.837004321701825 0.349629170058761 0.105276331875939 0.708423879686743 0.431139342926908 0.236026875486132 0.757814061273821 0.827700075728353 0.563243438212667 0.244791835655924 0.0884502826933749 0.246462736264803 0.984989285112824 0.350608111179899 0.135220637642778 0.110255188583396 0.623586536506191 0.867073890045285 0.34246213898994 0.328846531200688 0.366500316101592 0.103469525475521 0.991618002636824 0.440937943805475 0.792607090887614 0.0473772964254022 0.655873220392968 0.206664064880461 0.700457803737372 0.882442253280897 0.783705210024491 0.435512989009731 0.442625427674502 0.505280745162163 0.357244855947793 0.835431636525318 0.892144531612284 0.866276009893045 0.352041682433337 0.105297348157037 0.934275877429172 0.283809781793971 0.373745986730792 0.439336385445204 0.644096116072033 0.0337774082040414 0.295222295497078 0.537975835395046 0.700175651588943 0.61069754330907 0.41313780812081 0.715459750546142 0.761493234010413 0.42790884898277 0.511713851026725 0.638667084611952 0.796769301095046 0.743327152344864 0.632699580790941 0.0373713877378032 0.659778414962348 0.640453081030864 0.880331380644348 0.483581529664807 0.641273347339593 0.745921528066974 0.210011684899218 0.0238910560077056 0.972235304049682 0.412906658994034 0.673411184572615 0.46922149959486 0.0881257105083205 0.929655636718962 0.349090690321755 0.0337146857520565 0.253236280712299 0.854733727062121 0.837200444845948 0.382869285142515 0.705218506578822 0.862923165769316 0.876653323539067 0.441927399290726 0.347277376840357 0.594733404139988 0.461189860021695 0.294794597027358 0.877842113757506 0.535829901508987 0.641518632483203 0.0776647544791922 0.594818792117294 0.67535138659412 0.953300426555797 0.610301648860332 0.955484653564636 0.369490955306683 0.955860521739814 0.909072742427234 0.509680387529079 0.349912551476154 0.161389293228276 0.468411892175209 0.794639884314965 0.845455659008585 0.484112005208153 0.701140076133888 0.723728189780377 0.903889885619283 0.847087639297824 0.296833951473236 0.491061527126003 0.589651561523788 0.262412346410565 0.715124090507161 0.271439186970238 0.355344061297365 0.391613579394761 0.906496270052157 0.957193205116782 0.176475538199302 0.128009432645049 0.712454762801062 0.364942680653185 0.487516450276598 0.0176772724254988 0.87047100744443 0.5898687887704 0.63822456207592 0.714366550568957 0.144615064659156 0.949727627881803 0.607842805976979 0.370499413404614 0.901461321983952 0.562495069501456 0.628992128875107 0.81423978064442 0.949330805891659 0.0227426265180111 0.301176107709762 0.379729203204624 0.909465289060026 0.250578131447546 0.916993502769619 0.661551580929663 0.380822014554869 0.774626945545897 0.268864881547634 0.806312101774383 0.645227244286798 0.735566024552099 0.0225790528394282 0.424172956997063 0.0794413429452106 0.894273985503241 0.190915156577248 0.206897063327488 0.620811640804168 0.544265522474889 0.954269549660385 0.43986630178988 0.518272143402137 0.311813365526032 0.807570447456092 0.765372830142733 0.677436917573214 0.239266311076935 0.808626024611294 0.433676864095032 0.196895823003724 0.523172558781225 0.950301616273355 0.314472401763778 0.0224341028276831 0.164917208948173 0.697871706737205 0.822282636000309 0.20180103905499 0.310882810533512 0.276414733203128 0.748965679772664 0.321052859704942 0.981303644941654 0.464005526746623 0.418317550611682 0.569588273898698 0.297315380729269 0.572809376255609 0.900870353407227 0.0507673853472807 0.151768399279099 0.0508292385749519 0.196505094342865 0.432264680231456 0.0108942089229822 0.51247709935531 0.343887524644379 0.696291406915989 0.611391609588172 0.766606835008133 0.45447888773866 0.169535170912277 0.63356864951551 0.60319324974902 0.734021025702823 0.0321593580930494 0.684654784549493 0.862534646242857 0.108266648147255 0.970110811721534 0.310318507389165 0.46564823691966 0.740149575974792 0.603717781098094 0.292947056714911 0.794709352648351 0.2227484206995 0.493578064513858 0.300478385433089 0.432407431711908 0.595397751752753 0.0592308021290228 0.749701045847032 0.081777049866505 0.367292808722705 0.538229161382187 0.316326957414858 0.449225493296981 0.513249518219382 0.660814997111447 0.939259883097839 0.675132400614675 0.916946307646576 0.138315335744992 0.706783746529836 0.114849687945098 0.0626098536769859 0.374442155421711 0.987421996637713 0.155110103916377 0.623366912496276 0.926329712041188 0.87189977502916 0.24080186463194 0.963016768295784 0.206302607941907 0.607024684492499 0.779486064126249 0.85047811454162 0.1458064491814 0.0472252858965658 0.442331999582239 0.48192995529389 0.0971572519326583 0.820397126651369 0.0453647533198819 0.413059874819592 0.884971890347078 0.716567921880633 0.288508658837527 0.974251400809735 0.795050295109395 0.328230445936788 0.315572513353545 0.625880429151002 0.561103343411814 0.953054425471928 0.854997762648854 0.1520654308144 0.0796373658208176 0.350986375657376 0.0172384277847595 0.992174882914405 0.940274751926772 0.185320868310519 0.459470994181465 0.512943122987635 0.643233327614144 0.638506406042725 0.757859227054287 0.680888887152541 0.572732601228636 0.630220422584098 0.0354319491400383 0.429055005258415 0.589846587937791 0.972310268019792 0.227024546083994 0.96736397207249 0.322554262033664 0.986507221604697 0.579931314843707 0.377390743163414 0.217911414438859 0.656451167892665 0.0275427858275361 0.386600438461173 0.837066434014123 0.802886710728053 0.553833095931914 0.31329908747226 0.904248107918538 0.918428288770374 0.407232438279316 0.485628887612838 0.836284869278315 0.0428384488564916 0.257109349479433 0.12312493391335 0.0558101672679186 0.679500690975692 0.276539421137422 0.62652127428446 0.95317730050534 0.568375599258579 0.310666437528562 0.245380643964745 0.356463608383201 0.858350697360001 0.814089222510811 0.798679482953157 0.869942001353484 0.879907359839417 0.735917769505177 0.851786963746417 0.917840244576801 0.230448678587563 0.551758956378326 0.0475127847772092 0.837060184634756 0.252312785084359 0.404591760169715 0.943691312428564 0.220793227497488 0.13098553291522 0.666835593227297 0.350309201742057 0.590819688129704 0.502704114892986 0.0599613882764243 0.534241656272206 0.245427010662388 0.150933261881582 0.63141554862028 0.972951297785621 0.344531635304447 0.890422855026554 0.286470751715824 0.852840582784265 0.412280273963697 0.96320878112223 0.115327807879075 0.585411782439332 0.547559815547429 0.497682308454532 0.781134259332903 0.660763064473867 0.56131986486027 0.250821090361569 0.761447414525319 0.643218764245976 0.156233002275694 0.615460476952139 0.12074604353169 0.233007641774602 0.0739093375625089 0.86087623240659 0.178116467972286 0.804166420518886 0.611425648329314 0.383467977391556 0.868790566343814 0.343908120950218 0.678112701098435 0.652855010572821 0.616912282784469 0.380767509280704 0.92469730094308 0.760415543843992 0.43717113776831 0.738314130119979 0.992277279428672 0.578543495077174 0.956654375477228 0.122536871971097 0.958029153421521 0.46027675866615 0.199343953521457 0.568210367346182 0.309163501898292 0.787873930309434 0.884056743513793 0.22071388283046 0.765722223280463 0.0220614084391855 0.124962336502504 0.870714744073339 0.825433817086741 0.296762815224938 0.862194016573485 0.727211631918326 0.70858910376206 0.0160291505185887 0.614097525621764 0.0150653342693113 0.399450249026995 0.945627485960722 0.562682886954863 0.891321373421233 0.996080265343189 0.533465647103731 0.80112656214973 0.137993194207083 0.631856939850841 0.588727643385064 0.584570946332533 0.667302800489124 0.363520778119564 0.0845244199014269 0.454125925272237 0.15343990172958 0.703751927160192 0.17337842696812 0.570370057842229 0.892883967205416 0.971327184541151 0.109067659673747 0.896866940408945 0.104723863182589 0.858119989645202 0.34123649144778 0.305140261549968 0.0670713584916666 0.611733800680377 0.125342675731517 0.42238753844751 0.270997260743752 0.859002267075703 0.334912380226888 0.213440429063048 0.851730085681193 0.762295566776302 0.214970755286049 0.0126400359300897 0.159347536026035 0.864502617572434 0.875700855380856 0.783189966075588 0.297942647431046 0.559544977962505 0.293516211241949 0.642962584178895 0.150175422520842 0.0760158742195927 0.0317116391123272 0.053371852922719 0.127466667408589 0.703920623292215 0.809436841246206 0.395483523933217 0.499060940397903 0.241909422830213 0.225215098818298 0.955679989082273 0.947927097599022 0.0245845799148083 0.954254403812811 0.0809218391729519 0.490431144032627 0.437027009727899 0.106590460506268 0.230266193575226 0.969315857104957 0.755728774396703 0.403941763401963 0.44692586875055 0.0936861206940375 0.828009194345213 0.794638689390849 0.520447627687827 0.452319687290583 0.543078235823195 0.422678279343527 0.785042903600261 0.0783588260598481 0.756366258114576 0.759677406670526 0.945219661172014 0.822405780490953 0.348601851798594 0.396211453080177 0.715620772102848 0.960752857781481 0.952708842768334 0.388720491083805 0.918302144752815 0.48533030110877 0.682828332895879 0.821376903804485 0.153638057443313 0.510360788016114 0.852867986285128 0.798414801729377 0.192730367323384 0.804793029827997 0.621798243361991 0.936826734310016 0.702427092618309 0.654853561494965 0.400784423754085 0.909116421698127 0.679139390778728 0.861907073664479 0.664142799230758 0.841869578559417 0.80218350203475 0.998381656690035 0.366015398884192 0.198729985882528 0.895910337730311 0.449835153769236 0.0967295991024002 0.0819987186626531 0.614148246047553 0.773830858240835 0.782575712613761 0.167524171480909 0.213710951216053 0.956999020266812 0.164262103557121 0.984412216057535 0.475161540214904 0.795211883010343 0.832589064876083 0.917049025711604 0.196396607956849 0.430244704117067 0.187473841276951 0.366963173553813 0.235265773134306 0.491681623591576 0.686398630850017 0.998248641858809 0.305174485384487 0.427525681720581 0.628629310589749 0.899587138136849 0.915036151374225 0.740963839541655 0.0129925832618028 0.664732461089734 0.797125968195032 0.164599555751774 0.950720043017063 0.947905991422012 0.209805158032104 0.106719402361196 0.927212518705055 0.561776828828733 0.409524833580945 0.711727638337761 0.874419162578415 0.601383239366114 0.286400191262364 0.747179198376834 0.22143274562899 0.590525492234156 0.743143900220748 0.33739914616337 0.674979153901804 0.167688664863817 0.160855595031753 0.7685046255216 0.399264905094169 0.682637333818711 0.963902810290456 0.986994523138274 0.418248288577888 0.525921423162799 0.701671022132505 0.84642886292655 0.552381222101394 0.960222762336489 0.821729136500508 0.202078196217772 0.0943351147766225 0.975552687924355 0.48355305363657 0.669388372728135 0.903913868234958 0.726661154304165 0.225522674452513 0.842613784167916 0.566694697153289 0.248812835060526 0.929787066155113 0.192692659215536 0.0626852993969805 0.0385341475578025 0.840255433158018 0.0509486224199645 0.186380005804822 0.510701784645207 0.497821487840265 0.123044272155967 0.194119040640071 0.419623196294997 0.724190818343777 0.867182205168065 0.273332788334228 0.682599233165383 0.531803343540523 0.85755072632106 0.555326880619396 0.810668883384205 0.230855455743149 0.46174077397678 0.539913378572091 0.822837471030653 0.408268505255692 0.182368813352659 0.648122027020436 0.46913966757711 0.817102801769506 0.187705819520634 0.675410211251583 0.0303834189521149 0.09069234757917 0.878369306256063 0.321775187184103 0.537432630821131 0.189440698127728 0.108056813802104 0.291249336698093 0.336335584868211 0.780051410754677 0.762545674489811 0.313328930379357 0.0989342914917506 0.339304526657797 0.220334581783973 0.634118543497752 0.559350947779603 0.303756935195997 0.152230230765417 0.77306198150618 0.939284161217511 0.582976507497951 0.802755271610804 0.142052231337875 0.0355665419902653 0.614728255390655 0.050875459134113 0.383490716908127 0.379693436156958 0.494877045913599 0.380302552413195 0.692635630166624 0.847739687075373 0.0963816196355037 0.217391631437931 0.340170360282063 0.437191727620084 0.929997333614156 0.0857178445998579 0.876371738887392 0.76573560209712 0.681724238456227 0.196233121869154 0.320897206317168 0.510388391593006 0.118597771890927 0.775838224955369 0.293668643129058 0.557865247961599 0.359462641561404 0.424991107755341 0.338819355426822 0.392626479272731 0.12384233509656 0.220106353352312 0.78792859739624 0.450656098215841 0.391003613276407 0.273084602549206 0.83998015320627 0.759782045050524 0.979679130162112 0.707613094400149 0.257455581277609 0.334712701123208 0.295568796291482 0.184502405682579 0.496955181455705 0.225396036929451 0.38158897258807 0.146176677886397 0.218143845850136 0.727879932185169 0.704981542339083 0.103996193581261 0.208913426548243 0.425996056455188 0.0322260806825943 0.0157816191297024 0.0592398237599991 0.0108391089527868 0.573648549979553 0.975232409075834 0.249245005045086 0.352012787582353 0.165061653007288 0.654932126142085 0.287415618828963 0.200645651160739 0.546247959439643 0.340223251809366 0.748114571790211 0.454523367083166 0.916306744567119 0.856826954514254 0.342656418806873 0.193529741822276 0.34738901488483 0.891136318999343 0.33739756422583 0.159400047915988 0.764767706878483 0.435322362654842 0.60771411145106 0.571936863134615 0.925168275074102 0.777422301096376 0.676582104957197 0.279121286114678 0.176424347087741 0.795621287201066 0.756575414321851 0.322097310051322 0.536699705997016 0.197817179569975 0.630178984026425 0.414727121966425 0.662855217324104 0.873420665638987 0.341853869368788 0.0945881756860763 0.416117261969484 0.745987309976481 0.842193915401585 0.247366119411308 0.251315247265156 0.513644792847335 0.509845591781195 0.0435115763032809 0.0260794004797935 0.500813561230898 0.282114119471516 0.701567576141097 0.244273005321156 0.577603450303432 0.212673446827102 0.845132092505228 0.361913064194378 0.10743558695307 0.559351852731779 0.727286518209148 0.0922039897437207 0.263720271531492 0.629417667307425 0.411360720847733 0.772512235045433 0.561086195881944 0.245715419796761 0.793947300857399 0.765360804144293 0.285920219011605 0.897188265507575 0.703900410311762 0.460227982297074 0.565441219680943 0.448727056887001 0.249534620859195 0.529463843933772 0.718298936346546 0.83296929000644 0.414327662799042 0.378430094567593 0.506278990854043 0.729589416580275 0.28543585453881 0.447767293790821 0.0525928691215813 0.303987251748331 0.233178243699949 0.501156717436388 0.431370092362631 0.350160459044855 0.818785143361893 0.582450557406992 0.456666787802242 0.570816466878168 0.848989728679881 0.0561108826915734 0.0814603198319673 0.409269756928552 0.965617397085298 0.564774637117516 0.0942210848093964 0.792729755472392 0.554186434578151 0.337121727149934 0.0588259296142496 0.408356046585832 0.504564370636363 0.718619011431001 0.954787845460232 0.211736834694166 0.0302670620637946 0.186034612113144 0.856849535675719 0.399236844200641 0.807755576099735 0.279662386432756 0.637175274176989 0.209181672260165 0.0398130883928388 0.905936231431551 0.18628085545497 0.507426106249914 0.389039898172487 0.529687516486738 0.760951042955276 0.306694757787045 0.151648911477532 0.0603425439447165 0.556488316203468 0.978111948228907 0.542140840443317 0.97476660349872 0.506586305559613 0.665225052421447 0.77517122887075 0.932731402511708 0.66284826306859 0.256935644070618 0.981513379018288 0.0584370680223219 0.898149279770441 0.852956311784219 0.425025654754136 0.698170007187873 0.534469398343936 0.251802317604888 0.610942926646676 0.637409157522488 0.910370388296433 0.328514611984137 0.387805087009911 0.817317147736903 0.0573637488717213 0.993472364204936 0.50411326096626 0.912814720135648 0.661288094399497 0.0949301706207916 0.920079243090004 0.59586213351693 0.685126453414559 0.108896424788982 0.831736289209221 0.77668068057159 0.41939270087285 0.580466920908075 0.848405792959966 0.604276084266603 0.392609436621424 0.23213075003121 0.0256322572939098 0.212281705108471 0.924916839436628 0.156938452834729 0.920296833147295 0.509956264251377 0.249232014163863 0.55417639182182 0.349150844516698 0.817993137331214 0.284665884531569 0.520363548963796 0.206396065806039 0.741616224083118 0.633807076984085 0.830403925999999 0.0945830477005802 0.894466537474655 0.173212486952543 0.417015169302467 0.562322912837844 0.0204615650163032 0.415283161832485 0.97804357455112 0.613485330084804 0.216865401747636 0.336276833049487 0.891712317371275 0.938790316414088 0.0245067468821071 0.030130849473644 0.838030761748087 0.98527007291792 0.013422224635724 0.807112998510711 0.274344825211447 0.732971783212852 0.323761378801428 0.184689844420645 0.271250385963358 0.252178948051296 0.949462182312273 0.75239738220349 0.361298596826382 0.366799548703712 0.858157806089148 0.812384062339552 0.996751043971162 0.413967889219057 0.681005018148571 0.323340695439838 0.696923451009206 0.287521322821267 0.541456076547038 0.963610674394295 0.309320260314271 0.812194753766526 0.503202015615534 0.784157238937914 0.628928556330502 0.762312074431684 0.406688337742817 0.716108469869941 0.103913250311743 0.176788425298873 0.0623609968996607 0.576757505573332 0.63969393057283 0.0563197572249919 0.892554436684586 0.813007725598291 0.321589113480877 0.565845881055575 0.569058258207515 0.578877535376232 0.945218764517922 0.109691130002029 0.0542076414893381 0.457981966140214 0.239127070838586 0.180185920260847 0.170770996515639 0.990089376138058 0.378470672890544 0.315984563019592 0.321299058559816 0.609387499410659 0.970246919663623 0.290073603284545 0.928493401983287 0.905266616609879 0.859558897719253 0.946600982155651 0.219351429846138 0.686939214381855 0.260957036251202 0.744221832414623 0.81762342472095 0.116234961813316 0.881946404259652 0.0608245081966743 0.582682502458338 0.0597666698135436 0.0501688005123287 0.62823035576148 0.358235601324122 0.305431162875611 0.821823041078169 0.373931321904529 0.715762154399417 0.856196946217679 0.710399126592092 0.583364240550436 0.939132275620941 0.842894219534937 0.563401190093718 0.858400923819281 0.171724475196097 0.507594048178289 0.0395529957790859 0.39528673279332 0.859227331171278 0.0116989018023014 0.660615158269648 0.511939897292759 0.346289400719106 0.0304306311323307 0.256637546231505 0.12096021224279 0.700015003215522 0.99721803041175 0.0342188794189133 0.24813781933859 0.260524563847575 0.815727269160561 0.36294598181732 0.916358824495692 0.988386908695102 0.186851216892246 0.36738948693499 0.693297087510582 0.157607302388642 0.615467069318984 0.25302459635539 0.11247277227696 0.53205419854261 0.344564242856577 0.847159256835002 0.0903506463044323 0.179295171638951 0.177521937673446 0.203904525705148 0.955733063858934 0.82848794239806 0.983207295285538 0.957544017687906 0.996979242668022 0.0878880194947124 0.975681104694959 0.620977676247712 0.140376765169203 0.563071045514662 0.282295200033113 0.359298172842246 0.113198635661975 0.249572029544506 0.460383626925759 0.385220690425485 0.391148130635265 0.219685004530475 0.845137343117967 0.308905683420598 0.940479525132105 0.346063241967931 0.534602134267334 0.940483037757222 0.713731043408625 0.54374971287325 0.605030549303629 0.501164989243261 0.289283926710486 0.20046340955887 0.99429832945345 0.295592806106433 0.567339237700216 0.346744995734189 0.583887006021105 0.969674756389577 0.345396370585076 0.0629524615174159 0.70959811990615 0.528441965759266 0.456326472999062 0.433085278233048 0.358085778031964 0.879215280490462 0.845315458036494 0.473876964058727 0.369362919786945 0.367929769200273 0.981726327450015 0.403557860145811 0.727316923541948 0.327713601149153 0.160871209029574 0.455898848751094 0.197113601842429 0.437265724402387 0.367392816310748 0.100658120277803 0.402934293237049 0.391377077542711 0.507818706820253 0.547729914516676 0.0118423019163311 0.290676777651533 0.247305275553372 0.487887295114342 0.47143180656014 0.178581724492833 0.566916459533386 0.619661479319911 0.609780744004529 0.203478345784824 0.615617084389087 0.520590956807137 0.158135939214844 0.734452800145373 0.416920365074184 0.224760357353371 0.0696666622161865 0.802196286385879 0.505696857201401 0.835717423234601 0.043543236721307 0.417001132401638 0.740159300407395 0.472363135349005 0.603005773669574 0.385322085176595 0.379714537723921 0.501258828819264 0.125600133242551 0.702396585864481 0.0617808559397236 0.367101448678877 0.191946401905734 0.986262497964781 0.0719906782894395 0.202042207426857 0.261007242426276 0.536266550845467 0.111777901314199 0.555127337973099 0.0342010719608516 0.462929851862136 0.4051395084057 0.553485094336793 0.202653686101548 0.12889761462342 0.919835692015477 0.396955709168687 0.196387272381689 0.836324108382687 0.93355919794878 0.0700197148090228 0.629044440919533 0.0231676668347791 0.858947315549012 0.320843652787153 0.205716090826318 0.624501019723248 0.421473062606528 0.841459884166252 0.941700774689671 0.794401755807921 0.692861012585927 0.67258862568764 0.758982401094399 0.51276139655849 0.416602129859384 0.241917715612799 0.116208943170495 0.320831264669541 0.608017973692622 0.309032352291979 0.195864111138508 0.238077134536579 0.129287183627021 0.948777321835514 0.383737023868598 0.42366239962168 0.791051316054072 0.317647712526377 0.0165824506338686 0.746438982763793 0.10695867784787 0.558253772328608 0.986107867085375 0.606712182792835 0.207969951438718 0.275812989564147 0.826132686112542 0.479625475215726 0.218739417789038 0.201288339390885 0.127812074930407 0.637327878940851 0.409578905280214 0.947437994689681 0.139563709895592 0.430746787304524 0.73716561926296 0.721526472254191 0.883657411122695 0.0191320226946846 0.334960137775633 0.634802129988093 0.916688766693696 0.334790865387768 0.890234994008206 0.453017391818576 0.487467865685467 0.73570039289305 0.847261433680542 0.641701761749573 0.555622546658851 0.491422936581075 0.231472461402882 0.624291822486557 0.875825006244704 0.317215966435615 0.902471964091528 0.776419441900216 0.110180613931734 0.780941613086034 0.184915088308044 0.0512687770277262 0.352718398340512 0.279900688047055 0.511202858693432 0.799580223851372 0.701865751428995 0.294586143391207 0.110538053445052 0.0443576461961493 0.246746916833799 0.863113715136424 0.271324872102123 0.625484981415793 0.463077280926518 0.085992564430926 0.940454481744673 0.860855066068471 0.633872106072959 0.555412721072789 0.0528000727435574 0.139425084176473 0.924924002066255 0.420551057867706 0.793312929612584 0.763200516186189 0.429265461729374 0.305026007303968 0.681170429852791 0.200763239162043 0.500205346469302 0.809651785597671 0.398112780191004 0.873740788898431 0.914074696160387 0.132133056300227 0.749082843649667 0.1621487089945 0.447092308725696 0.360701993850525 0.218014683634974 0.780044741861057 0.941771641480736 0.953445361354388 0.701801892139483 0.132434278137516 0.0254616417689249 0.411805086019449 0.684592185416259 0.39417944220826 0.618439570064656 0.467247462596279 0.934055609165225 0.60609675584361 0.325094791948795 0.448417719062418 0.391262725794222 0.517455958137289 0.692704256935976 0.306765212439932 0.0961003235727549 0.509654420979787 0.523009892359842 0.421998884999193 0.0353746160631999 0.829072722448036 0.919532635379583 0.996933501553722 0.786112037750427 0.795010152435861 0.139856590314303 0.734436385382432 0.706129957537632 0.554931858622003 0.829146253154613 0.551162993737962 0.240359489156399 0.676506885590497 0.387852160658222 0.117288098409772 0.487126919305883 0.601536962296814 0.781792032558005 0.0263364878040738 0.642896083793603 0.313660744025838 0.969394858323503 0.631396496449597 0.219592724994291 0.927273187150713 0.701534902204294 0.755484675187618 0.147393085050862 0.896656887086574 0.71780068871798 0.73539311760338 0.169219466843642 0.345919035787228 0.804590939208865 0.693339771933388 0.185533155661542 0.946963278122712 0.878094598411117 0.0107466687564738 0.442302864317317 0.678183912720997 0.338702700729482 0.163488768215757 0.376662711903919 0.809565062320326 0.918245393002871 0.878803159599192 0.427377004486043 0.856048906552605 0.630956216470804 0.136417715572752 0.870066219754517 0.433913211741019 0.999194419225678 0.319903955610935 0.365918330661953 0.234856974012218 0.167759446599521 0.479928948830348 0.31282728307182 0.557161881143693 0.373283204422332 0.0806269432418048 0.901819271829445 0.695027362063993 0.668649956416339 0.722553885711823 0.401856654242147 0.0180296872183681 0.429175974959508 0.431052865595557 0.94826831666287 0.149007833215874 0.85983611850068 0.290668953710701 0.801465394592378 0.32630165331997 0.195779032264836 0.652387589404825 0.213386645491701 0.345200175985228 0.110000070671085 0.493180125048384 0.521142894884106 0.190092722163536 0.994251640974544 0.905718235920649 0.817375921683852 0.720783202715684 0.453961921015289 0.498742000998463 0.467718349827919 0.0635664999205619 0.816809103298001 0.738714844603091 0.9650899146148 0.0769625408644788 0.453763340024743 0.716284969889093 0.503044376450125 0.253544945931062 0.362647268536966 0.700356863536872 0.750879773716442 0.272313780144323 0.726257320432924 0.450216878086794 0.597239521900192 0.848552750416566 0.272993890428916 0.92553560636472 0.439043144290335 0.186210636605974 0.732487974250689 0.544386630938388 0.979224500029814 0.821181198100094 0.685730576529168 0.208930242154747 0.507891387895215 0.187462914544158 0.0276944556739181 0.33147742794361 0.5804576134542 0.703653362977784 0.856408387625124 0.521142898572143 0.913820622423664 0.963585379759315 0.535261235416401 0.394711253743153 0.14672032617731 0.631007961709984 0.778153291314375 0.335439634039067 0.0202069233218208 0.474796725548804 0.56757874783827 0.670703692364041 0.59156452070456 0.398460837337188 0.563954495971557 0.46887979025254 0.48791084692115 0.871762343773153 0.399554988367017 0.666841580295004 0.0476326162577607 0.61955679921899 0.851122190165333 0.101585056844633 0.846366212391295 0.569763243151829 0.268414408063982 0.552891357426997 0.532809281325899 0.738089625684079 0.368376971164253 0.547107280220371 0.832424248789903 0.876995725079905 0.24198398411274 0.647133797577117 0.920211963339243 0.0125297191250138 0.702826360929757 0.452005678105634 0.890820324728265 0.0157565623731352 0.506202199230902 0.0274941818742081 0.408772317210678 0.330997496491764 0.653809554635081 0.543613905506209 0.844751399685629 0.0496660071471706 0.678040857668966 0.0660225454275496 0.184650079770945 0.812992028158624 0.503545178505592 0.493322229508776 0.500620429315604 0.391213314852212 0.301756447132211 0.708442373580765 0.872538349023089 0.142740999981761 0.055194708048366 0.166490283443127 0.240901169879362 0.12086080764886 0.365524812000804 0.223638924988918 0.429900987329893 0.158872435672674 0.285003660121001 0.851387542150915 0.894994551483542 0.731253272115719 0.225481489677913 0.0458899418311194 0.665315996427089 0.992046143210027 0.254776691643055 0.368922741920687 0.81774961322546 0.702644112182315 0.715505111101084 0.464287624957506 0.165861276909709 0.79123665814288 0.794275303608738 0.906514607665595 0.179605625786353 0.0736590698803775 0.233028880029451 0.902684418095741 0.598196201797109 0.975173796250019 0.369446079728659 0.0142511587543413 0.108922068865504 0.240413222478237 0.92636965440819 0.908410297150258 0.983142364621162 0.869024140355177 0.632934803585522 0.647054487946443 0.92258480188204 0.371689207230229 0.616362289686222 0.815910238227807 0.469364249922801 0.0752819379512221 0.0774745709192939 0.287297751458827 0.194890623241663 0.261547457154375 0.728186788652092 0.723535890439525 0.436663091485389 0.893092761985026 0.648352934811264 0.302014523772523 0.111484695887193 0.964321269765496 0.550362864113413 0.86568533728132 0.170355879554991 0.778507530072238 0.616154223063495 0.232394261225127 0.87761029294692 0.855831180498935 0.925629410212859 0.142527559197042 0.708661814110819 0.110160166530404 0.335932137779892 0.429759476643521 0.936951543258037 0.809629557796288 0.52286425130209 0.448298847163096 0.991316373271402 0.651934645858128 0.0828643003478646 0.848756534305867 0.596061536939815 0.865388314966112 0.378337227250449 0.566377861779183 0.683259673994035 0.663047277864534 0.180660459341016 0.434694219813682 0.458746168056969 0.0320985206891783 0.636011834605597 0.611788045486901 0.707604790783953 0.398843568488956 0.80805946623208 0.926912574772723 0.473862688126974 0.0640832236944698 0.997493380436208 0.247975920720492 0.481654196588788 0.741550443095621 0.429612864709925 0.239838621872477 0.643615727995057 0.674150788662955 0.515809358237311 0.0429866968956776 0.0875688387593254 0.13136939168442 0.7773341842019 0.488198963087052 0.847041382319294 0.355885139948223 0.177907437388785 0.511013210129458 0.459758996940218 0.338235036612023 0.486358509799466 0.950415210130159 0.57174629924586 0.0100010033766739 0.781133880848065 0.467334568507504 0.602877222516108 0.583207876754459 0.0435269549582154 0.444510522349738 0.760048137870617 0.179441809388809 0.735531524114776 0.410292424343061 0.500114697737154 0.871565867729951 0.224772527185269 0.926515696309507 0.832231505271047 0.172006071372889 0.272458275605459 0.29518947703531 0.558758367761038 0.698418742259964 0.802337173332926 0.163524396270514 0.704653047234751 0.925538205048069 0.336970677124336 0.0495826245401986 0.885927705860231 0.592421755439136 0.774046796518378 0.901460937275551 0.393383933694568 0.751275802317541 0.129347825795412 0.195716341391671 0.911986474297009 0.0697338405088521 0.216036266169976 0.142033732833806 0.465286815017462 0.451840206470806 0.656859799439553 0.690499919059221 0.247781473789364 0.513839876656421 0.873436247135978 0.0927604034845717 0.259800963534508 0.860306181686465 0.398075430744793 0.910353677798994 0.54604812520789 0.0662007152056321 0.739092039549723 0.552394436800387 0.216735973993782 0.554675857885741 0.362184458568227 0.136144830079284 0.917171046503354 0.634561368222348 0.917651719250716 0.16594519497361 0.876506548870821 0.956223623773549 0.342018482382409 0.574391349984799 0.785509005372878 0.888277412110474 0.30157059378922 0.139290504234377 0.563321606165264 0.810420433213003 0.894688350104261 0.864863663755823 0.919181749047711 0.157173171520699 0.963207482702564 0.691506149352062 0.955360511920881 0.0943757043941878 0.544375069632661 0.185852534859441 0.114845797065645 0.21843098975718 0.815928537116852 0.916397515696008 0.381969935325906 0.675572143984027 0.166851346453186 0.810901331622153 0.0159333797940053 0.850535346658435 0.587624027237762 0.553663508447353 0.877506997473538 0.871920792001765 0.0195197361544706 0.159846655183937 0.807191437303554 0.117833741698414 0.0978644312592223 0.676910780544858 0.711892688383814 0.359614804221783 0.135578351223376 0.424678196222521 0.733106675946619 0.579825953838881 0.976467097380664 0.514231801393908 0.112039886582643 0.109806001533288 0.46494425535202 0.20746655945899 0.0312439973535948 0.371943493490107 0.75811484123813 0.0835572184948251 0.957027641972527 0.600346498631407 0.660394340488128 0.188000483335927 0.373805200476199 0.652296835102607 0.818800063086674 0.642906335154548 0.428214756010566 0.740582299856469 0.88442429862218 0.717767200877424 0.373682023254223 0.471543403344695 0.459864398513455 0.631112901817542 0.225847205838654 0.60106088622706 0.944704215303063 0.280026915045455 0.134392649505753 0.920854383725673 0.765280088910367 0.343355907422956 0.92112853836501 0.84402829333907 0.221059548514895 0.697761832496617 0.308211970271077 0.938863897139672 0.152549510155804 0.0898662398802116 0.448661734599154 0.858622580629308 0.541158164492808 0.784076829350088 0.858969076813664 0.965763979745097 0.847871147168335 0.116094110824633 0.340422434872016 0.130541391561273 0.620640859086998 0.443213916737586 0.90615274826996 0.571058621800039 0.6362061213376 0.457619234754238 0.85954754501814 0.826878889484797 0.670712791674305 0.855789953311905 0.452772675324231 0.667368386241142 0.107947439290583 0.858776811356656 0.941342808709014 0.83561640996486 0.392850302343722 0.196680869201664 0.402934243909549 0.85115360509837 0.657800232840236 0.349902104188222 0.755476336535066 0.224289800662082 0.401318835355341 0.60047437003348 0.357011974134948 0.624761827355251 0.98834592491854 0.940167110792827 0.659276125936303 0.426954465580638 0.911269707686733 0.0311066414718516 0.970465765267145 0.68682569636032 0.190789102225099 0.64371768332785 0.922556918014307 0.817690515192226 0.796935710874386 0.412021987105254 0.119937219819985 0.687209958508611 0.629803990146611 0.153147793032695 0.763131855071988 0.31247468180256 0.0678795907343738 0.426087242027279 0.0532482001744211 0.935467321190517 0.983610294507816 0.412455612942576 0.879238575287163 0.702792569287121 0.451147694468964 0.720708151385188 0.132908671540208 0.977172110446263 0.0517263707285747 0.992843512569089 0.269335926673375 0.596278913321439 0.399082655194215 0.368345709745772 0.834042107583955 0.272608757442795 0.812022016006522 0.969262521630153 0.295720868364442 0.431310145619791 0.413191752813291 0.409554797271267 0.457834607148543 0.608588161331136 0.649096850447822 0.22654244514415 0.296386934372131 0.832853729503695 0.586616400792263 0.0589021477475762 0.960757561642677 0.362931635812856 0.511583842406981 0.898507036224473 0.362818824280985 0.197908543550875 0.547516065512318 0.954341237731278 0.840474465698935 0.328186636662576 0.99595653353259 0.516841599796899 0.103601261710282 0.904876786908135 0.697364818267524 0.143263504062779 0.302309957004618 0.979991678423248 0.639037206824869 0.717717785786372 0.545308392727748 0.629785671203863 0.520280980260577 0.190867584121879 0.20211661842186 0.151857408678625 0.435791408633813 0.21123115682276 0.55761403268436 0.268006388270296 0.953853108463809 0.214177798433229 0.430667211443651 0.179279352955055 0.572057406175882 0.381041907791514 0.25419951148564 0.857882489257026 0.378674545292743 0.84727775946958 0.843722162493505 0.195694801639766 0.619383035954088 0.405743366442621 0.438840374611318 0.371931636219379 0.802107448480092 0.786131569826976 0.994287032072898 0.425968280001543 0.572148465663195 0.028720513547305 0.896198892542161 0.613753357511014 0.787509663086384 0.262143841153011 0.684702545786276 0.178895437712781 0.92803639813792 0.8214542253525 0.0979890369041823 0.996654383507557 0.873666276251897 0.0678153172321618 0.811437090740073 0.583606145838276 0.387221681445371 0.817960236119106 0.464012194948737 0.139018914625049 0.242254081219435 0.905432036381681 0.502378280016128 0.447116278663743 0.332482090820558 0.147772026052699 0.099490492939949 0.40957045391202 0.11060965023702 0.4217833657749 0.812189309762325 0.570838551307097 0.310099051876459 0.504730841037817 0.604485494026449 0.151142166610807 0.0331928699510172 0.298189015474636 0.556048935414292 0.641015663014259 0.330767218894325 0.7261153213121 0.309170552964788 0.0556044017500244 0.196378807413857 0.969349750168622 0.391334384821821 0.233784952589776 0.358204862915445 0.355460500475019 0.0539520886191167 0.321835003001615 0.280336741534993 0.839662646378856 0.0162892636470497 0.277521629629191 0.249680773171131 0.537254747557454 0.206566283022985 0.85628203292843 0.574149830096867 0.891728167172987 0.520467073787004 0.785250284709036 0.487340939573478 0.0983191406843252 0.597575706792995 0.586494771393482 0.334903929089196 0.934198572707828 0.364547818393912 0.398887602733448 0.0933459799201228 0.792655519889668 0.875469147516414 0.026089355184231 0.335971425981261 0.323659719203133 0.234979860340245 0.0140172751783393 0.105835558897816 0.76127797225723 0.400583160868846 0.91683222143678 0.565969726734329 0.308242674104404 0.393820363823324 0.2743980767834 0.79390608957503 0.0729770166915841 0.119397823375184 0.705979974968359 0.012457073777914 0.138339716207702 0.342875449503772 0.988201573751867 0.886449261424132 0.666981041354593 0.344662423022091 0.21588054155698 0.54548507622676 0.588124907433521 0.637408065863419 0.783071615342051 0.812918918810319 0.995190945374779 0.382145321788266 0.518145082215778 0.228353112919722 0.868395510693081 0.241678544543684 0.305066250476521 0.613999135929626 0.719314539325424 0.513487008695956 0.012824861924164 0.69022308252519 0.22754415828269 0.649222482980695 0.270013505350798 0.703024860552978 0.832135800700635 0.966186248501763 0.0360819592769258 0.0547765396977775 0.541043689656071 0.668884306298569 0.859731281197164 0.437859804760665 0.483311532135122 0.983866712683812 0.624122005882673 0.775031608303543 0.993005685023963 0.614606897293124 0.51879838876659 0.340496952820104 0.147925481370185 0.989306227851193 0.615581002244726 0.114032225697301 0.91523368404014 0.243229408063926 0.409422215784434 0.161979814399965 0.183824989278801 0.923863610408735 0.104433850212954 0.889746275115758 0.277719055803027 0.683189685186371 0.408053518952802 0.333081907921005 0.185094181247987 0.433491554507054 0.807385973900091 0.320818894070107 0.082850552496966 0.175673754489981 0.48507534800563 0.01347393599106 0.0515543788741343 0.518996563381515 0.672984780373517 0.97063845185563 0.443991579529829 0.091688403498847 0.896582475861069 0.748440580004826 0.702917479886673 0.183313489609864 0.847021713785362 0.92822486883495 0.0403558561648242 0.788595278614666 0.572953968758229 0.701399948387407 0.227985056699254 0.0271415393450297 0.11258721184684 0.860015378554817 0.46125756385969 0.162157725323923 0.628078210158274 0.0864180823485367 0.802728290620726 0.624109998785425 0.53750712133944 0.0759747039666399 0.209398555827793 0.436121728855651 0.845554456689861 0.299699246734381 0.293978095282801 0.965786589949857 0.925362079134211 0.625415850307327 0.409516765538137 0.471834002712276 0.735149911821354 0.915618247224484 0.813455898668617 0.39354965634644 0.0411639109207317 0.304303272988182 0.285887215225957 0.820246558606159 0.80185333048692 0.757046142967884 0.481916499028448 0.700339612511452 0.302326427779626 0.490706467779819 0.710606555875856 0.436863046269864 0.203025533163454 0.243625959213823 0.469044445678592 0.508348250903655 0.661284669595771 0.764581380083691 0.88167350654956 0.893729856845457 0.928688563932665 0.0441302733891644 0.495460445946082 0.834865194780286 0.291347717170138 0.583408469108399 0.602769019186962 0.783711138775107 0.386735601804685 0.140630055889487 0.381887469657231 0.706526194512844 0.471428356862161 0.399700492275879 0.253979343720712 0.0197579061519355 0.573399185636081 0.284500576553401 0.718787930228282 0.304817145909183 0.250268997156527 0.575361248960253 0.986900231547188 0.213886274520773 0.533773385703098 0.866511320739519 0.235574170739856 0.27138455030974 0.348914522686973 0.736710159091745 0.929526589524467 0.466526315750089 0.492862334933598 0.574525526317302 0.307190089561045 0.287507666710299 0.123510923907161 0.0779736174689606 0.232062300518155 0.0922771926759742 0.818197680495214 0.334688157464843 0.452544276320841 0.977779616643675 0.124571859780699 0.336604569801129 0.206157118785195 0.198921170514077 0.312595441746525 0.312040423697326 0.995670198227744 0.0587953175208531 0.129352524585556 0.635240323920734 0.236516581159085 0.793981073137838 0.691202545734122 0.614870855661575 0.435319840037264 0.433747660582885 0.334644372162875 0.740287536003161 0.103384800883941 0.316425917369779 0.776567883330863 0.817795051920693 0.106610551320482 0.169654028520454 0.105773879699409 0.66470237292815 0.624925241065212 0.87024363509845 0.0863734056940302 0.498815785949118 0.139955526066478 0.24613055058755 0.893877540614922 0.265388294549193 0.848943178963382 0.0685978950257413 0.08483730123844 0.275282731384505 0.768564281139988 0.660293215194251 0.882158834291622 0.743672945958097 0.746614404262509 0.565441620294005 0.376393828622531 0.464994609509595 0.571315894909203 0.531136275308672 0.598630227555986 0.728908301305491 0.976296648508869 0.615488295357209 0.466469443677925 0.100578775380272 0.643425688038115 0.843380103479139 0.563766953737941 0.0934247342706658 0.0647829817677848 0.429895494689699 0.601982800378464 0.469991309172474 0.839645925739314 0.115868849419057 0.873327903891914 0.618549767469522 0.824436934816185 0.322050714234356 0.457627889194991 0.520213460363448 0.278056086408906 0.558411573306657 0.805761075795162 0.607568060560152 0.495997085352428 0.952698940618429 0.789562061890028 0.305262599973939 0.458311575262342 0.857605648804456 0.208791853392031 0.16884730952559 0.301225041742437 0.395474079330452 0.55628507215064 0.304761223276146 0.799998146025464 0.360538988821208 0.990486979761627 0.749848476063926 0.0304527754918672 0.766255682676565 0.760201175517868 0.932407067974564 0.480842745841946 0.451401800245512 0.28622134081088 0.5041518855514 0.820897342769895 0.838780235026497 0.386429984748829 0.753811676315963 0.245022879443131 0.474213512223214 0.512754093322437 0.601020068181679 0.598254913047422 0.792333520341199 0.866008595833555 0.0138029785384424 0.17391033784952 0.668636786895804 0.887121809388045 0.736453489668202 0.672275827100966 0.385064537769649 0.713547879566904 0.0116089959791861 0.909741279419977 0.281548679028638 0.154778060228564 0.814642600074876 0.695299107031897 0.161873706798069 0.656915250464808 0.881574748284183 0.022684956677258 0.259990883860737 0.29464885385707 0.786036313583609 0.0963349544373341 0.598522041975521 0.908785072283354 0.233697003039997 0.348956364854239 0.216401760587469 0.355743619811256 0.914103056015447 0.422313919919543 0.861193605773151 0.69911403873004 0.116357350717299 0.353973156253342 0.381477909416426 0.434003715487197 0.761421361307148 0.516836929358542 0.627106850489508 0.892061045740265 0.108153777606785 0.284309168334585 0.384116163332947 0.587889920673333 0.979627695640083 0.947202874238137 0.653305451555643 0.267707389628049 0.786358887543902 0.34404865730321 0.921773667153902 0.848550639706664 0.866474956229795 0.839746852570679 0.835037029432133 0.25118839145638 0.0696714488277212 0.0114924482349306 0.917418984267861 0.540897579065058 0.238751314918045 0.493648558582645 0.383117668929044 0.9629226445104 0.0182306161057204 0.982592059192248 0.189879793094005 0.225502648409456 0.302929130538832 0.283568976232782 0.748323838408105 0.852893702278379 0.761176041588187 0.336410234894138 0.748809774676338 0.587540844015311 0.253815667929593 0.686559385946021 0.863355841476005 0.141348562792409 0.276317689183634 0.392306312678847 0.17045941544231 0.583951962501742 0.596529999056365 0.820420007004868 0.365298224284779 0.996926225516945 0.586296276149806 0.482324302610941 0.682983360930812 0.0282755758077838 0.911592204428744 0.039609004619997 0.142072449158877 0.966765853774268 0.648252395223826 0.0676555046602152 0.119287402383052 0.129604858721141 0.124202863110695 0.0175884001748636 0.28817029892467 0.190014564353041 0.608770589639898 0.722833615741692 0.85174123369623 0.631927869799547 0.657699669280555 0.792580493453424 0.517026357792783 0.476752082637977 0.827468775853049 0.334548257759307 0.206720899611246 0.263069044803269 0.465915948557667 0.69555910398718 0.880069745739456 0.0160013104462996 0.0926033716928214 0.0122511879377998 0.936950687863864 0.485563933667727 0.0707798262313008 0.764095637437422 0.7856481541018 0.933160400553606 0.335205331179313 0.302411551831756 0.304996179379523 0.356070030252449 0.329586057381239 0.932774720815942 0.37275918801548 0.776409690729342 0.433859829935245 0.587329243561253 0.657122710174881 0.206419853186235 0.830825609050226 0.0911640298133716 0.66951013351325 0.329286916980054 0.0362418843340129 0.918702621588018 0.214002624033019 0.0314846738334745 0.637878161089029 0.172267576735467 0.57927100563189 0.0328522919141687 0.0714673987985589 0.218218101717066 0.625886764507741 0.886135201298166 0.731906653349288 0.0552431402774528 0.347663338943385 0.687919166486245 0.0205909007997252 0.538161415131763 0.453982120396104 0.691673079375178 0.395568916751072 0.0570533219235949 0.937055533695966 0.161200215157587 0.309112307559699 0.591121073623654 0.863042553763371 0.520836363886483 0.791924670739099 0.0789556362573057 0.134114635104779 0.570381999937817 0.469630071441643 0.869247795620468 0.629993917157408 0.79949225332588 0.914454208116513 0.299144567062613 0.916602315178607 0.497799122198485 0.373303882325999 0.0186255880841054 0.497387510025874 0.612887475250754 0.875953483867925 0.183839199517388 0.182575430115685 0.193242288811598 0.531316728442907 0.906553318458609 0.325978463687934 0.127671947719064 0.476629229732789 0.258368874411099 0.469029691223986 0.695391618683934 0.970218945899978 0.379383484274149 0.828112630655523 0.932300929254852 0.672345550830942 0.326791536710225 0.0382482211641036 0.322196499356069 0.31920397072332 0.153982256210875 0.792993348494638 0.0591723199980333 0.202033042884432 0.632105220372323 0.508589782316703 0.823263508500531 0.759099141769111 0.227362542725168 0.461542067362461 0.725723670411389 0.488317087697797 0.700196798334364 0.343810497447848 0.615831559898797 0.70688764776336 0.144313787270803 0.890900959286373 0.957386940487195 0.262726105500478 0.486798283825628 0.0760318800713867 0.548574938389938 0.68654147107387 0.549770229235292 0.824191740951501 0.0746581663563848 0.164173860347364 0.30646580995759 0.386843301947229 0.237992533955257 0.194434521351941 0.111508929058909 0.754983008748386 0.436678817046341 0.70284712319728 0.597529681008309 0.627178520120215 0.821868048273027 0.160124918296933 0.232872430256102 0.0664217879227363 0.18448831761023 0.588534132062923 0.0832764235441573 0.735969936102629 0.323694853521883 0.541960846008733 0.794700728172902 0.875708900603931 0.496015592385083 0.441390818201471 0.807098262957297 0.794042691022623 0.424954707748257 0.878541432032362 0.239643296727445 0.572465971568599 0.480053741182201 0.478199719374534 0.533098724954762 0.564335912337992 0.891384784844704 0.909332429356873 0.458165655757766 0.956342247421853 0.655068660282996 0.913558929201681 0.778318620037753 0.823255540034734 0.849284041209612 0.117885540414136 0.941832675503101 0.499540499818977 0.895854213868734 0.792220442579128 0.616676250696182 0.163135846087243 0.596465520868078 0.612441761870869 0.178446306444239 0.0654632909758948 0.434255950967781 0.461514982415829 0.325059316486586 0.635257200840861 0.532176443382632 0.0834856159402989 0.314565079838503 0.246618957149331 0.814094259908889 0.919957771585323 0.156162615390494 0.781926529058255 0.230090122751426 0.368313736536074 0.158640656813513 0.421725092018023 0.621324282612186 0.314038397211116 0.510447947634384 0.238759745541029 0.0943966010445729 0.0437017983570695 0.0146545705758035 0.0306462397915311 0.229512911245693 0.62369656956289 0.633378523581196 0.7203341659531 0.367033498203382 0.754554076630157 0.380281028335448 0.562775202218909 0.0102558762650006 0.114009207733907 0.678735165284015 0.381342318491079 0.87730943899136 0.648319864179939 0.0488366885506548 0.712912896799389 0.10247735789977 0.710368230058812 0.0874036013148725 0.478390311845578 0.993238376902882 0.269040577805135 0.128016437380575 0.779816578431055 0.692858554970007 0.413566462944727 0.0551341246580705 0.609732616730034 0.905077963124495 0.224798887432553 0.150455263652839 0.0872643029899336 0.429473345333245 0.142883190189023 0.770184846953489 0.474265596992336 0.0744615764450282 0.912428898639046 0.74249644335825 0.687935025738552 0.532034543838818 0.123768926556222 0.558510546400212 0.12657566108508 0.450796114786062 0.55006276528351 0.255248251019511 0.763894668903668 0.866512678628787 0.497903340372723 0.638557012139354 0.171219394095242 0.133321748555172 0.449464856605045 0.0921164539456368 0.965709129408933 0.116645554013085 0.140189910293557 0.837362177963369 0.709236597043928 0.445779402449261 0.79385701701045 0.899341274662875 0.469204007233493 0.644782975926064 0.125818309006281 0.93050191959599 0.470403256956488 0.0200446319277398 0.792192581531126 0.0663153182016686 0.380600784404669 0.651955633095931 0.18599437862169 0.827282003497239 0.981946352764498 0.778260047088843 0.139849464795552 0.637854792762082 0.986474151664879 0.25376237094868 0.722049412445631 0.874436539458111 0.440043103997596 0.495141362021677 0.321803896711208 0.0526613965444267 0.500251729532611 0.078805978235323 0.0462352069024928 0.061922406964004 0.922293386997189 0.348677180192899 0.827465912553016 0.921582781483885 0.854191028210334 0.793402188646141 0.88232047543861 0.54654553104192 0.270556307006627 0.317991287554614 0.302983415913768 0.129443552494049 0.12179071769584 0.264199848470744 0.47130598294083 0.613370417063124 0.761738913774025 0.786627982426435 0.784058816975448 0.0493950329790823 0.218770796533208 0.131131027142983 0.954469103601296 0.762510630297475 0.934310759117361 0.0299821319011971 0.570276291335467 0.358691693763249 0.824081469324883 0.150864994004369 0.789818229740486 0.43701764165191 0.873181048317347 0.974994776148815 0.877816179017536 0.5079052330181 0.424611603405792 0.710153235227335 0.0731650217738934 0.93843274574494 0.118667121054605 0.546013993113302 0.310578078837134 0.275798966032453 0.155658680577762 0.640212302207947 0.0253445256059058 0.0784347180323675 0.315681785752531 0.501005113283172 0.0800217293901369 0.146839326696936 0.0338737063179724 0.0581735499133356 0.39726453020703 0.965965289191809 0.248560416791588 0.917082496494986 0.991724552803207 0.779642580284271 0.415334424860775 0.115931608981919 0.55832351841731 0.398921781850513 0.654762925670948 0.689532336401753 0.245318886165041 0.24114445380168 0.277963336417452 0.893319180281833 0.718339210406411 0.0681950843543746 0.579646360939369 0.734668895625509 0.813758151081856 0.170175343439914 0.566667975708842 0.0247947318921797 0.159017844614573 0.325416934408713 0.498415553907398 0.81279209919041 0.642303427478764 0.44331522712484 0.404408547000494 0.900191685836762 0.79025245442288 0.267560555490199 0.977763454280794 0.229622430743184 0.864010805108119 0.123976956068072 0.198059058119543 0.933299311634619 0.444787039868534 0.922448431858793 0.552098596962169 0.295533191978466 0.698466215368826 0.197698785040993 0.100380231500603 0.991304646234494 0.64244867045898 0.868563536063302 0.592131312121637 0.283345317509957 0.806853633131832 0.0979929782636464 0.962545861701947 0.0197650627885014 0.388704309819732 0.663524322044104 0.596511846766807 0.325014067264274 0.107445847073104 0.182306938227266 0.865318122394383 0.39238556307042 0.704825056607369 0.960491340432782 0.532022844692692 0.0346483898675069 0.948283871882595 0.705585816663224 0.178264080055524 0.384085242366418 0.633121433260385 0.256010503808502 0.0808742710971273 0.051638063439168 0.96146226744866 0.610317184026353 0.735498349526897 0.753432470697444 0.564918391283136 0.607644216457847 0.725946623105556 0.736497106703464 0.959465991123579 0.635881243045442 0.0859050728892908 0.19713256803574 0.722051072292961 0.947594372085296 0.764237395913806 0.608386187346187 0.550375783999916 0.885784862178843 0.497733477898873 0.25591725892853 0.305453189909458 0.155174559745938 0.054199859960936 0.975525119844824 0.797803672726732 0.491729135885835 0.460480183202308 0.990273136058822 0.70984378676163 0.395964829639997 0.704388648145832 0.0311421807832085 0.353274808393326 0.942877900798339 0.137419339276385 0.969526720873546 0.0725919224298559 0.799381587079261 0.48801064406056 0.274467905391939 0.019723954310175 0.573267651321366 0.0668779640342109 0.244698671221267 0.0236242875852622 0.496655938941985 0.559212571003009 0.844727985258214 0.337151860028971 0.973921363414265 0.138891575683374 0.228149476321414 0.639078801663127 0.835198378763162 0.760154648621101 0.472584000614006 0.477118259803392 0.98802728932118 0.782613317456562 0.901736837278586 0.793337208423764 0.475362674249336 0.052462999955751 0.480352396145463 0.10491221747594 0.0488501819269732 0.489566399762407 0.504971427621785 0.328168394246604 0.163348035474774 0.673900616869796 0.20733065366745 0.292063371837139 0.0440375561290421 0.204647626054939 0.376938030810561 0.949306358583272 0.875286423934158 0.110348331581336 0.174957793485373 0.740491707827896 0.977406484300736 0.222757002071012 0.68425481551094 0.635782059733756 0.550965258460492 0.402214055492077 0.628141370564699 0.395952820698731 0.0402894641156308 0.594204230934847 0.237028543676715 0.512108118128963 0.35495393079007 0.523442975594662 0.499660142287612 0.793883168883622 0.202362004064489 0.732415663362481 0.629268504404463 0.489990249304101 0.124525864883326 0.0775480541423894 0.0265848310221918 0.468831396517344 0.0275510387332179 0.58087301854277 0.467422799500637 0.387847463020589 0.316913769573439 0.794436637726612 0.392376936750952 0.979265131598804 0.139883101079613 0.172880310264882 0.0622765025799163 0.612761963962112 0.871312391455285 0.633584123828914 0.598632352557033 0.66175811701687 0.915175106250681 0.620767324424814 0.835131864547729 0.152338387763593 0.35205963994842 0.0995511890458874 0.520689090411179 0.670513379953336 0.626427586378995 0.194404796692543 0.278281683195382 0.585324390244205 0.988664325634018 0.651292073570658 0.536248266247567 0.527181374523789 0.302760066064075 0.114464589303825 0.353035041475669 0.269491262889933 0.460948767946102 0.294876223898027 0.247682622401044 0.575402368733194 0.975990785276517 0.162477071559988 0.491290386673063 0.640099091907032 0.464858156044502 0.900301884624641 0.673598547014408 0.408491156913806 0.84469610309694 0.745019039730541 0.800736681967974 0.217824629617389 0.371919073611498 0.721165660261177 0.892319703937974 0.153848663510289 0.881254013732541 0.893482141054701 0.270551278828643 0.973718541872222 0.498988564047031 0.158225880074315 0.736042512068525 0.657226844215766 0.0190842241165228 0.914794425878208 0.790652137408033 0.675575369864237 0.867511678063311 0.499170817174017 0.772425696861465 0.859940182007849 0.587645141021349 0.705621618055739 0.697069615998771 0.977358133899979 0.233719312900212 0.69400737585267 0.658672025871929 0.149298720941879 0.146607808305416 0.155356583292596 0.0982230673101731 0.347442452702671 0.683054256304167 0.509549764159601 0.768587630565744 0.733474864244927 0.441004440272227 0.408233703551814 0.986445267878007 0.011199394017458 0.641456107110716 0.196351186318789 0.12084286719095 0.69003785453504 0.36982386038173 0.825423590850551 0.600684176718351 0.0280320362583734 0.964307316076011 0.926010410522576 0.534044620338827 0.663411174209323 0.928863741329405 0.865338404295035 0.676789490906522 0.212359169798438 0.711710445629433 0.0793104388238862 0.191501555906143 0.793445550745819 0.0665658677881584 0.373339392594062 0.132889650026336 0.477851246402133 0.017688754668925 0.170838470081799 0.714936612353195 0.473115946531761 0.269518936309032 0.697875689356588 0.170870804488659 0.108200762050692 0.148993567887228 0.452090754904784 0.726845265510492 0.0720790690206923 0.193077819861937 0.850802801055834 0.270360168649349 0.11078343793517 0.341568254614249 0.219253409418743 0.230573052577674 0.194350703556556 0.480379913053475 0.0189959292742424 0.518250374991912 0.384289461444132 0.239318932686001 0.295879485551268 0.716305630274583 0.639993337204214 0.500643491304945 0.938559666555375 0.725019181508105 0.498475642639678 0.72493363771122 0.138723244667053 0.697131888279691 0.841141790249385 0.223771277817432 0.504159030432347 0.645237994685303 0.970894370763563 0.833374516803306 0.90014370677527 0.331986419286113 0.518967903642915 0.687580127974507 0.247739392591175 0.538909832478967 0.197041438936722 0.240357496233191 0.780705802510492 0.755003856762778 0.913991493345238 0.5431290565175 0.107911867478397 0.348848599479534 0.290184340295382 0.511113984137774 0.456743541623 0.385759950643405 0.179279305932578 0.196593159604818 0.473909348254092 0.582346838500816 0.220601387317292 0.222479152248707 0.210667151717935 0.661554942114744 0.822165412884206 0.747708437736146 0.0762905486417003 0.572791121162008 0.835629103959072 0.256829832664225 0.648494565128349 0.388354725595564 0.030759624352213 0.244522361827549 0.374069039905444 0.0515345531376079 0.250178856682032 0.977620274296496 0.46459872335894 0.790067046640906 0.113286645833869 0.618160682981834 0.414684894629754 0.373777767932042 0.389463215945289 0.592470914903097 0.801712285876274 0.0796709419437684 0.24600427426165 0.873540022284724 0.35644297542749 0.881172869764268 0.645442681682762 0.561212086807936 0.0859737787209451 0.284077002231497 0.606811606518459 0.507030875417404 0.188163208996411 0.655810107700527 0.0767088011256419 0.0373091488797218 0.419204629405867 0.697164108357392 0.74274074033834 0.946943025956862 0.340540385453496 0.94995546054095 0.399086589408107 0.10453336291248 0.246602800088003 0.355337908267975 0.357924734577537 0.0360445342259482 0.717850781024899 0.555408176719211 0.0513210379006341 0.853232895687688 0.18379354737699 0.359170623682439 0.252784491290804 0.378448860454373 0.113065248799976 0.506701422345359 0.966029005339369 0.0279673533840105 0.125666053683963 0.58704624685226 0.687809617714956 0.520818984010257 0.268266302936245 0.023267720292788 0.521417986976448 0.555087934290059 0.119062805054709 0.642164319548756 0.60167776925955 0.417175176418386 0.246464084472973 0.698987381844781 0.14498296667356 0.379753834223375 0.614591588480398 0.429511172380298 0.436609284633305 0.539209293969907 0.222159705744125 0.183090643868782 0.774081863530446 0.448845537623856 0.954533681366593 0.391883403125685 0.0914252223842777 0.113288777288981 0.045432495882269 0.430526803019457 0.779372535501607 0.0957124556764029 0.166603474381845 0.205795311944094 0.657807646947913 0.24698393455008 0.560603048230987 0.708474108912051 0.0982273712498136 0.919682542574592 0.494930857836735 0.62311521431664 0.497271528164856 0.585786672823597 0.501918443988543 0.217998574287631 0.0474656475102529 0.0767080169566907 0.34401873325929 0.749725512056612 0.356402220078744 0.134525353158824 0.320041528625879 0.829705162313767 0.853197037591599 0.320647614237387 0.898187959676143 0.203065363736823 0.62011278583901 0.35771090147784 0.547694849579129 0.491545998090878 0.476536790458486 0.411578873330727 0.547799825645052 0.797247990369797 0.501163116411772 0.221478395925369 0.236551656469237 0.190750398808159 0.840631009978242 0.452348534197081 0.580639318216126 0.437801962043159 0.657559757127892 0.128222047539894 0.047988556122873 0.476396049188916 0.872380499639548 0.506886697588488 0.575293580389116 0.626524148879107 0.619711822182871 0.679082281289156 0.108029956822284 0.3455462890747 0.258460344423074 0.735256503247656 0.322438625465147 0.74029913188424 0.585399387637153 0.521130690015852 0.300735673755407 0.0816520237852819 0.853336897650734 0.24563546936959 0.908098348656204 0.889912641791161 0.639806658201851 0.0979135169624351 0.120355144760106 0.921352974341717 0.713448335519061 0.548032334505115 0.592462085741572 0.180077515011653 0.0958336837706156 0.327951135421172 0.325304428292438 0.97785090940306 0.0462128979642875 0.132615038300864 0.143373892093077 0.755423726912122 0.769240475650877 0.44989878048189 0.417561600909103 0.977543445562478 0.117709614345804 0.182864703172818 0.574152767849155 0.725817904376891 0.826842931811698 0.798194000774529 0.981202609774191 0.897018468035385 0.589753486430272 0.271240384005941 0.132970096725039 0.757676080039237 0.816922947249841 0.768034211972263 0.627091843634844 0.972365580052137 0.716698325811885 0.0757741584046744 0.603771461404394 0.696159367570654 0.176650682634208 0.856687291534618 0.942217060048133 0.263904630988836 0.810065179092344 0.495950338556431 0.0591611777455546 0.439634599226993 0.445067649034318 0.863752077759709 0.729856045548804 0.768853606982157 0.0229919396899641 0.742170424310025 0.990613507104572 0.384187933001667 0.307717028737534 0.392135152015835 0.940489326321986 0.77923303617863 0.101725702686235 0.748298111120239 0.851105276134331 0.775317128321622 0.567541512951721 0.572052133434918 0.353397333293688 0.0880853571556508 0.823902242463082 0.0244000478112139 0.292444774603937 0.375031369645149 0.760042988448404 0.641357133325655 0.101064511111472 0.0394866744941101 0.307661203606986 0.765612966786139 0.943002081627492 0.58795071428176 0.307067695355508 0.427547892003786 0.124899085508659 0.443118572672829 0.8157261092728 0.359259259898681 0.895336746263783 0.951457332172431 0.104286981269252 0.0561923355329782 0.402484056479298 0.271384775049519 0.511948865908198 0.0519545180234127 0.271068468678277 0.427530870097689 0.37345627986826 0.761396899246611 0.165425407132134 0.876545706838369 0.973423079135828 0.899408806776628 0.104752376321703 0.0172741166921332 0.429168807719834 0.110729583369102 0.0184382906439714 0.80197667966364 0.215580662626307 0.396695781594608 0.99127361624036 0.837548489314504 0.332273707026616 0.359359033757355 0.0435461968323216 0.452011566979345 0.320011755099986 0.626002930079121 0.569830932929181 0.695961854727939 0.590332753094845 0.928923041743692 0.726133948436473 0.416253294767812 0.805003750454634 0.929313579318114 0.522776899905875 0.542430426983628 0.711691964643542 0.529805058157071 0.0222724858834408 0.214399331694003 0.953100460937712 0.702385044842958 0.521703346334398 0.262067334200256 0.175381028277334 0.832555822520517 0.181743444607127 0.549550262698904 0.822339046376292 0.1121008212585 0.315152436904609 0.542538707070053 0.0892291906592436 0.761862440437544 0.932937718238682 0.86112139722798 0.686790388703812 0.301732262135483 0.0895449341437779 0.896575463518966 0.640756888643373 0.962038705158047 0.740179807969835 0.157997821522877 0.403214625569526 0.568444670436438 0.128206512834877 0.222450358818751 0.923397683587391 0.414434093334712 0.922958615589887 0.422885713237338 0.371925578617956 0.987965256532188 0.842185776594561 0.696286381734535 0.840990819286089 0.98366617634194 0.163066028542817 0.38056504271226 0.414811275603715 0.97083554218756 0.0248112333239987 0.0156883500469849 0.750792021015659 0.339680185536854 0.936829669065773 0.86451468068175 0.521524506486021 0.304768689707853 0.255933043728583 0.586759345203172 0.443500501906965 0.233085222176742 0.405182553334162 0.4149568804726 0.470580702726729 0.114013467647601 0.581005445132032 0.888751657069661 0.159925368505064 0.938632670103107 0.38945974757662 0.996537540950812 0.0183929423056543 0.457266866753343 0.266127385080326 0.252012634391431 0.0974437711783685 0.386594353429973 0.388416545169894 0.155814355171751 0.0745689923781902 0.695121474093758 0.971746780162211 0.549753488081042 0.462401204432827 0.591717949053273 0.259472527669277 0.634118060825858 0.0818669190397486 0.549854058094788 0.0277801463007927 0.734381662283558 0.743892421063501 0.712214690467808 0.0257248231139965 0.388311746590771 0.208241243930534 0.748491700813174 0.728739793032873 0.879556289336178 0.336941898216028 0.164482553687412 0.334083016451914 0.280355433430523 0.045852296189405 0.725340979828034 0.167844447793905 0.0879920039395802 0.386472805398516 0.820055407627951 0.723791570316535 0.874342861925252 0.0668430834985338 0.191065087283496 0.0437154835113324 0.256399846228305 0.580674688108265 0.608918652585708 0.0801591919944622 0.709781877291389 0.648561713686213 0.345340330395848 0.125047142461408 0.2444334981055 0.516263448302634 0.183314200709574 0.257251391704194 0.444504129136913 0.869144726961385 0.926258252628613 0.379637454976328 0.640623059908394 0.582501608603634 0.339517722188029 0.979681971794926 0.826496196365915 0.28171665023081 0.354572942696977 0.135751220600214 0.156881829244085 0.276405747991521 0.419154423000291 0.267483108087908 0.387369830368552 0.205601255022921 0.729307135581039 0.569720146590844 0.0142949269991368 0.469918621643446 0.653434521108866 0.4852250837069 0.616816641141195 0.826867850497365 0.263145283681806 0.689065160027239 0.736463183213491 0.207361294343136 0.818010859733913 0.502518560050521 0.601838290165179 0.881119334213436 0.75622446391033 0.375211174145807 0.466985478249844 0.807583196770865 0.82072431595996 0.740309130153619 0.659227191903628 0.450905920336954 0.423439272206742 0.232657616599463 0.0685691700549796 0.825907710068859 0.549550828812644 0.509320752711501 0.673554176236503 0.329291981346905 0.10013036604505 0.844333419885952 0.0408295426168479 0.851546209817752 0.108954136811662 0.673259632512927 0.413381866761483 0.462460608573165 0.402698891342152 0.415357377131004 0.313331176394131 0.124508006023243 0.566933948206715 0.324005289920606 0.0569158766069449 0.749511074810289 0.896355067787226 0.88278257730417 0.637933898859192 0.535444758611266 0.141674031862058 0.30382364971796 0.0280850121495314 0.76062349129701 0.411737941610627 0.736440030867234 0.779813009332865 0.622480952099431 0.525977633462753 0.099759230313357 0.154225801292341 0.562581839801278 0.186444067705888 0.518080310828518 0.145474414944183 0.772974093731027 0.0547297813766636 0.86072959442623 0.673402980533429 0.518875255533494 0.808000729165506 0.227817668898497 0.858713548146188 0.154490663460456 0.96361606469145 0.23584334860323 0.461862631572876 0.193485063784756 0.469360948668327 0.856038616467267 0.121066915462725 0.176658563970123 0.224908281536773 0.54266761043109 0.80122576758964 0.174281876729801 0.888341229218058 0.382376148672774 0.547767529271077 0.995490020082798 0.0967056026565842 0.569684412044007 0.662991075862665 0.0495914799789898 0.451374661361333 0.163803286810871 0.987900993633084 0.063730440789368 0.504591359694023 0.792697382571641 0.610152334747836 0.129857035884634 0.740652645942755 0.817485505721998 0.841978668861557 0.0734857028489932 0.216836399943568 0.467343988216016 0.185836431274656 0.0192396707437001 0.293324182741344 0.39720903423382 0.0582382950233296 0.924894328578375 0.449217665207107 0.375640734382905 0.531219140437897 0.372051004851237 0.462325357408263 0.962516374459956 0.225041687069461 0.80390372392023 0.495364958508872 0.348825135033112 0.515019513627049 0.870936364463996 0.635487560497131 0.593117386598606 0.300794376938138 0.833502086016815 0.940524731711485 0.871886944808066 0.747896225685254 0.300886047717649 0.686346820839681 0.798745336087886 0.0193517557322048 0.119379213538487 0.189450097552035 0.94156123157125 0.773405635827221 0.561902433701325 0.150387897500768 0.925562950165477 0.297972967477981 0.746303004364017 0.542164527324494 0.915398487448692 0.172448174164165 0.609382423057687 0.463412450456526 0.467170970165171 0.85578244562028 0.906177183361724 0.64951255910797 0.771241333670914 0.963890025708824 0.393589308972005 0.604293935750611 0.806837648486253 0.987902504345402 0.297961600255221 0.456297534583136 0.604047481499147 0.755756724418607 0.347746740451548 0.613367323491257 0.617142656731885 0.26894314308418 0.275177949171048 0.223867344968021 0.921091737053357 0.146142665192019 0.415692917078268 0.324136245443951 0.36465605445439 0.817950856748503 0.201472725355998 0.0342244119360112 0.230890955638606 0.450023614785168 0.434131948316935 0.587557620436419 0.0804447322967462 0.128382676090114 0.825379380502272 0.726430936637334 0.291947262047324 0.399432404688559 0.0241589407529682 0.834188583982177 0.948319642848801 0.273384143563453 0.662844017215539 0.533139765895903 0.584203749194276 0.23900142217055 0.0114268758520484 0.0353679222753271 0.975472216561902 0.210519088541623 0.198797139741946 0.393018809694331 0.293970113447867 0.900381452878937 0.562025389180053 0.612752219014801 0.865724411807023 0.342835161383264 0.668652951794211 0.099597372955177 0.89641981981229 0.659681492648087 0.498846742643509 0.28679299260024 0.105894094044343 0.762039832270239 0.454981498545967 0.220697995917872 0.929974129404873 0.628283918511588 0.440800045090728 0.958490789902862 0.562089673515875 0.358816866443958 0.476958748959005 0.617591036101803 0.557581349066459 0.944777039750479 0.368274814833421 0.805405614683405 0.136929903060663 0.0191600321861915 0.783642816499341 0.40313772007823 0.0182824007607996 0.206883199533913 0.805179285129998 0.194000641270541 0.355236382361036 0.947812664483208 0.528581787094008 0.546143148874398 0.872414022055455 0.601241111163981 0.776134892988484 0.702378509871196 0.816356154219247 0.891110815068241 0.58130978428293 0.0748182458500378 0.212621335780714 0.630101666396949 0.659814648546744 0.616142609664239 0.403022512474563 0.778093643533066 0.105226109104697 0.633795276647434 0.399100315591786 0.165453574748244 0.888051471645013 0.331125818756409 0.760714151784778 0.159819014957175 0.0780219201557338 0.486212183458265 0.890974771436304 0.72970087045338 0.737970546332654 0.836006379120518 0.276136518726125 0.379404996596277 0.763699394238647 0.281818046134431 0.83343225187622 0.320515400862787 0.46852071440313 0.528217542921193 0.64439916809788 0.982643210887909 0.485557889665943 0.618106866679154 0.109826771407388 0.502310688663274 0.872676804631483 0.675004966245033 0.387887231127825 0.484794926929753 0.167646788121201 0.858055287639145 0.223448628252372 0.850591307093855 0.18041343298275 0.421191261052154 0.133016797420569 0.346398788138758 0.618587692710571 0.231786055914126 0.726267601989675 0.438320761951618 0.607721168741118 0.435770050287247 0.684377827232238 0.925980645294767 0.0223586059361696 0.161934368559159 0.214969427362084 0.35086542439647 0.664849647094961 0.116427327999845 0.903783265149686 0.858695532314014 0.790048545831814 0.1472201048024 0.589524169566575 0.208161384321284 0.283264067741111 0.310732204916421 0.0820360028767027 0.254340171387885 0.178563370744232 0.607972542834468 0.265693772381637 0.75119016332319 0.540206828101072 0.833694979592692 0.935882414409425 0.656954652764834 0.448890144897159 0.353236743237358 0.307275568586774 0.393408747501671 0.602376204479951 0.336775501575321 0.43779895514017 0.77651740009198 0.77735752717359 0.731785706467927 0.543749181104358 0.885979786480311 0.986022265432402 0.978246452105232 0.455018076731358 0.404804403416347 0.264041610921267 0.871116758820135 0.138219854300842 0.442209189550485 0.645055077481084 0.994081747382879 0.0591189227486029 0.57047593125375 0.103532050848007 0.880606181612238 0.876376029227395 0.922890737492125 0.513742818115279 0.240168136488646 0.251064346623607 0.217940765914973 0.775379404751584 0.424999948672485 0.101120720489416 0.272548381965607 0.696213603848591 0.534784672756214 0.171132813729346 0.929359726808034 0.517265883604996 0.30790984624764 0.694250700112898 0.162011850075796 0.0307509906566702 0.864855746231042 0.367181873479858 0.718774451373611 0.0501704294723459 0.765327043849975 0.623979153903201 0.908016146682203 0.846250579510815 0.0798007327388041 0.858731445730664 0.89592964207055 0.666245833404828 0.237452509391587 0.639396088130306 0.598263774940278 0.968371813115664 0.157745920962188 0.991024823542684 0.551871529570781 0.490618872742634 0.355041787447408 0.603676145921927 0.614522871815134 0.468771021731664 0.018339314784389 0.893604107217398 0.768131416882388 0.755788677805103 0.657149264735635 0.454996092340443 0.448110706775915 0.1579860384739 0.181753690666519 0.963842021522578 0.320599558649119 0.252635727848392 0.472137137949467 0.322006318562198 0.42557516817702 0.881109974205028 0.411310992734507 0.724172160793096 0.37804547514068 0.859019127399661 0.944721505974885 0.174914932728279 0.394373868163675 0.932855324486736 0.823567034439184 0.740975802382454 0.966204534713179 0.941712640027981 0.95462535767816 0.23240865356056 0.362265228431206 0.1912646898604 0.474657359456178 0.235381548234727 0.7101863985206 0.253090154677629 0.546083103937563 0.165242701298557 0.599215564499609 0.335922774083447 0.302679384944495 0.263798351893201 0.583584271396976 0.739994573756121 0.271011945356149 0.660488427623641 0.388724060642999 0.140756140437443 0.942514635799453 0.299337868858129 0.948825769277755 0.127213331970852 0.690249075121246 0.710075350331608 0.645359379751608 0.522547679161653 0.664902511883993 0.192358050267212 0.558965595355257 0.35749014869798 0.0916887884377502 0.262758150396403 0.712913100102451 0.382534287106246 0.392170596821234 0.0784065384301357 0.470732320249081 0.261443556151353 0.315805678684264 0.64403964253841 0.495999464597553 0.857700721567962 0.190031264247373 0.731036264076829 0.262635051084217 0.3742601858126 0.659983887050766 0.105258298986591 0.345768744344823 0.242222501938231 0.848221405842342 0.250068539415952 0.380553402344231 0.636191479368135 0.655757250979077 0.934818525800947 0.492753175480757 0.783808479681611 0.851567662439775 0.706695023644716 0.920124154626392 0.781556483602617 0.0912784129101783 0.131188114043325 0.592958998300601 0.654069567264523 0.307423535874113 0.0536298514227383 0.325623221322894 0.105365223719273 0.0869461390003562 0.179872562014498 0.182166033531539 0.178251431239769 0.932883271281607 0.29622168724658 0.991273425153922 0.776135031059384 0.102028972997796 0.48607458278304 0.824373878366314 0.969310890701599 0.925127472933382 0.208518461254425 0.883900342837442 0.162034689860884 0.252215781402774 0.639476644778624 0.604077503045555 0.579123766040429 0.383185145030729 0.444823544523679 0.941451339581981 0.627811813305598 0.0990681455819867 0.875642388002016 0.349291672224645 0.592627967209555 0.0203199623594992 0.876211962965317 0.271302867427003 0.251109469300136 0.966422463608906 0.119060649857856 0.670790783523116 0.564232104457915 0.439009817109909 0.0856594484462403 0.703323488086462 0.694694421491586 0.890651968356688 0.474166954900138 0.911769400103949 0.439222463353071 0.188435915850569 0.356380437838379 0.840444759940729 0.428391206471715 0.42340404199902 0.973350325222127 0.822089233014267 0.489396294108592 0.770290274112485 0.304416484672111 0.697937742660288 0.218369523773436 0.969119364235084 0.0916880782600492 0.913723716014065 0.526169768685941 0.25004159161821 0.0764213665551506 0.636986635674257 0.731796711571515 0.463781989037525 0.705785428229719 0.531851902315393 0.225867491196841 0.762880860154983 0.311636348029133 0.374524701305199 0.732776629331056 0.4945947881951 0.0552796018286608 0.472763236465398 0.719297287147492 0.753801594143733 0.232919781890232 0.655509089857806 0.281689518953208 0.142639528012369 0.102026184150018 0.0384254308999516 0.50497730497038 0.72788738709176 0.359362748994026 0.479147742756177 0.744591039302759 0.98934549115831 0.0673893957049586 0.889786667192821 0.723461593082175 0.275285553655121 0.324587922149803 0.205595254816581 0.991948194238357 0.872094108322635 0.963983978922479 0.699569367745426 0.978048666808754 0.650381419458427 0.895914541862439 0.445746993129142 0.636852147933096 0.946331131225452 0.252779986353125 0.954496908867732 0.339118532247376 0.206577753741294 0.0883854495314881 0.279405652468558 0.734473518847954 0.760683898814023 0.241853736231569 0.16664084687829 0.0748322898964398 0.42215369152138 0.144651911149267 0.926483732780907 0.501587748278398 0.96240633771522 0.331920738797635 0.402366311736405 0.916268470806535 0.716279320276808 0.604158558270428 0.239201069234405 0.139902707147412 0.851999576105736 0.909108388461173 0.304434114643373 0.0563628332712688 0.112411720505916 0.338974561870564 0.920232986765914 0.684319097772241 0.844263633228838 0.970972901987843 0.425942423862871 0.385442685382441 0.0732022548164241 0.352680549165234 0.692157220260706 0.875259648321662 0.599360199875664 0.253933664842043 0.0751253643981181 0.169614929561503 0.407319215494208 0.539844661906827 0.208961520169396 0.325930196959525 0.958580128229223 0.347605544400867 0.58303581989836 0.371146070424002 0.912223562777508 0.172301917895675 0.159866250879131 0.203483408077154 0.545651304831263 0.522498689347412 0.627787563998718 0.218031963934191 0.532464590435848 0.857879917081446 0.887565862690099 0.214792871561367 0.891137165634427 0.463375193441752 0.32441832452314 0.198837603274733 0.716960676426534 0.711820868235081 0.335368206205312 0.219521476260852 0.905977256007027 0.9853831910179 0.452289165093098 0.0909391035581939 0.872506065787747 0.910250950283371 0.834852515538223 0.750573906335048 0.853750876390841 0.905850681641605 0.277648863692302 0.321893616979942 0.883028070130385 0.0682681399956346 0.63502442989964 0.823846929969732 0.679961510787252 0.320691533230711 0.863346790110227 0.921955125278328 0.962153565394692 0.975782534251921 0.515564335635863 0.585482050615828 0.235380340171978 0.512804433419369 0.431304564927705 0.671903649498709 0.475647059734911 0.389738234046381 0.824281392069533 0.335602598499972 0.401271710305009 0.0753541149175726 0.888139139520936 0.658117618884426 0.978709554581437 0.439488612876739 0.607063204890583 0.703699586533476 0.421208810117096 0.244737004451454 0.482941280149389 0.704949921336956 0.793770129845943 0.44098071097862 0.647766088538338 0.61494018684607 0.793762800793629 0.961564837992191 0.517235571625642 0.340778985107318 0.138980371637736 0.964650889490731 0.76221863708226 0.606412335901987 0.19548718979815 0.414224916612729 0.955772593857255 0.0989419040619396 0.116870416649617 0.927106882019434 0.836079726808239 0.766580808758736 0.0840955145214684 0.686766203476582 0.910723514880519 0.283060411780607 0.62432163934689 0.279510435604025 0.986589112400543 0.746720814744476 0.655487469660584 0.0487921515805647 0.468321368375327 0.0777159308386035 0.891862401361577 0.689783709112089 0.603590688563418 0.709475066463929 0.74800367158372 0.189898002087139 0.0421361167635769 0.0251313296146691 0.718566739954986 0.952083238910418 0.390890904318076 0.588385898775887 0.501270260582678 0.387227173163556 0.0603615705296397 0.258573011890985 0.047771093302872 0.082811857839115 0.106961848177016 0.805287570287474 0.0771795989223756 0.568139513924252 0.704779306503478 0.277474280761089 0.0558033838146366 0.975485321772285 0.463635700268205 0.0806682084617205 0.0591156314057298 0.989501267634332 0.233225333944429 0.5722767445934 0.685997514831834 0.190440338589251 0.73067101560533 0.555465816825163 0.15342441105051 0.554771352699026 0.815657145739533 0.450164832042065 0.758226859841961 0.812715678676032 0.101369511804078 0.448132764005568 0.63706899369834 0.59705342491623 0.50406343189301 0.501341168633662 0.555497286617756 0.0815968675725162 0.661699246028438 0.296064000136685 0.783925657619256 0.143733174472582 0.37769959992962 0.579851522541139 0.446336661442183 0.236971894730814 0.959668108480982 0.905105168162845 0.356308966670185 0.959177324518096 0.823192465144675 0.874873986793682 0.327445043337066 0.959900551186875 0.848698523782659 0.74875324835768 0.311913717023563 0.886681520650163 0.577194047495723 0.773872884579469 0.802370169742499 0.0908866838691756 0.556638202883769 0.491216682167724 0.020382839939557 0.862028362841811 0.854268209843431 0.0496469049574807 0.567381761232391 0.0969269628101029 0.781373151724692 0.479698823594954 0.507591748686973 0.289574400684796 0.734532834705897 0.299005668198224 0.604595390856266 0.921817196598277 0.628821030447725 0.518263590612914 0.479988599838689 0.122076147357002 0.431054370775819 0.396178505306598 0.130300282428507 0.62026988862548 0.136825575628318 0.159933994133025 0.518012640413363 0.329187751417048 0.648737236375455 0.996391506656073 0.446393022490665 0.597462852618191 0.318811970381066 0.844699964011088 0.200323330522515 0.265678084162064 0.601803079780657 0.302669610262383 0.506858484563418 0.861154511193745 0.475816224247683 0.799398448786233 0.372980879631359 0.790528988768347 0.862576449916232 0.702396483982448 0.567613882848527 0.286543532367796 0.747218467216007 0.878074926419649 0.827005566193256 0.912436146785039 0.762182664196007 0.882793372420128 0.642909656693228 0.822518139316235 0.679900301583111 0.118847448334564 0.287076700178441 0.471700609396212 0.873473980368581 0.952042537499219 0.771706899295095 0.39405062828213 0.435462352256291 0.422294307167176 0.748731576988939 0.875868402228225 0.0507296809274703 0.450588917157147 0.949479444171302 0.257604068117216 0.919286171677522 0.145243798969313 0.972463534325361 0.0530057036480866 0.578891957446467 0.96309815913206 0.701662430157885 0.126696842156816 0.906997688931879 0.843577656890266 0.243117161723785 0.0337254543602467 0.244880800799001 0.188306611645967 0.663258773901034 0.750194616583176 0.792084090074059 0.536916110350285 0.0141462108097039 0.949518726149108 0.588841261444613 0.601025544686709 0.969874527694192 0.4766689658002 0.432860516556539 0.855269699625205 0.0322540961671621 0.298407426120248 0.981724119237624 0.279337007259019 0.0391646011848934 0.543018485698849 0.868558445419185 0.0196510282112285 0.567696868299972 0.994722753406968 0.548072792044841 0.152463089528028 0.572039753845893 0.416918091860134 0.121865726613905 0.374002425421495 0.057970348733943 0.0205370480776764 0.694487089249305 0.701457679080777 0.0395340627781115 0.653262676084414 0.522799597471021 0.521269995486364 0.933629068739247 0.705682839476503 0.984415050083771 0.44357670413563 0.324260657466948 0.383858636440709 0.243423874126747 0.365943841508124 0.242304569529369 0.515044619250111 0.137934627020732 0.058514637821354 0.175118654842954 0.657091561011039 0.718460837039165 0.858747451582458 0.211381856715307 0.454959347501863 0.557655181500595 0.954539092408959 0.352186043050606 0.12327594867209 0.0244467531167902 0.0854358955239877 0.893737813094631 0.233796960148029 0.0696944393613376 0.0898955814447254 0.296436437976081 0.720721461512148 0.667340794650372 0.138152522493619 0.28228593706619 0.731886065572035 0.929849677043967 0.981088529787958 0.823770561087877 0.484677588562481 0.924322375983465 0.824233376819175 0.754901862705592 0.287141554085538 0.551422538678162 0.0816194966784678 0.37395482668886 0.4792439809395 0.0577474916982465 0.196135037823115 0.879295604561921 0.333898618961684 0.471809703847393 0.945616026998032 0.283212235141546 0.0845132532157004 0.975929432238918 0.576481099387165 0.32444918256253 0.0246792652038857 0.380395038018469 0.749734444252681 0.0947018481441773 0.674917385959998 0.0593843289022334 0.385560288827401 0.0408919778629206 0.865048205310013 0.356541312334593 0.794835974727757 0.842661156547256 0.560394936660305 0.595787096938584 0.911239467854612 0.84823856005678 0.266583826038986 0.417567586132791 0.274492798261344 0.360825244372245 0.554684007065371 0.446310180872679 0.803332944582216 0.336416484273504 0.67117384867277 0.823656210952904 0.697080166321248 0.520429947236553 0.648636171242688 0.70392884300556 0.28536750621628 0.618766828062944 0.188736438574269 0.527943934341893 0.655468510151841 0.347558260303922 0.181987940510735 0.220308326645754 0.529346500725951 0.431967442396563 0.711113116340712 0.940817103411537 0.516102027054876 0.534773072034586 0.482367568821646 0.677456458869856 0.589323839063291 0.884330344256014 0.332646645056084 0.237681320072152 0.981025352324359 0.873711885979865 0.611530399424955 0.226296393119264 0.0165304486150853 0.720262377152685 0.642229911524337 0.255193960573524 0.752925584763289 0.971510628904216 0.62042276930064 0.0530543447122909 0.506782507766038 0.188891554891597 0.453306616931222 0.760247464766726 0.247989671337418 0.855141777512617 0.393834991501644 0.263337286827154 0.484092841474339 0.731579607182648 0.813145711903926 0.349812458602246 0.922256334207486 0.717002765692305 0.694178099252749 0.597498981093522 0.868822824454401 0.584535419007298 0.329922228674404 0.019503737448249 0.870294745073188 0.0850770490244031 0.540676583566237 0.897439944094513 0.66101461144397 0.326769593348727 0.233486314683687 0.904592652209103 0.88357725024689 0.290065747995395 0.0328855925868265 0.237475965309422 0.825873861261643 0.676100781501736 0.204304973497055 0.0480123421200551 0.0751184152136557 0.845169976947364 0.280722209902015 0.672169299293309 0.157188386749476 0.189371688493993 0.660440025820862 0.425632080587093 0.391582355087157 0.903025129593443 0.401983304212336 0.401388294699136 0.934012257899158 0.96115925553022 0.537270569698885 0.341042668947484 0.05091199652059 0.298846748131327 0.0354120565578342 0.395212227983866 0.747558303265832 0.877375577026978 0.287194481340703 0.476309175854549 0.0652753446716815 0.819988916693255 0.180750977608841 0.0107606851425953 0.11397987769451 0.837144425632432 0.316641030448955 0.668397943831515 0.74917339626234 0.751627004668117 0.753982744317036 0.765603652186692 0.811686538755894 0.526801923650783 0.344610341249499 0.490146899153478 0.497545027025044 0.420749968937598 0.559291630077641 0.443427217837889 0.553267062176019 0.248542256434448 0.422487283032387 0.33001436437713 0.771369303036481 0.196882683678996 0.8441322148568 0.589894096083008 0.567214542850852 0.376368613741361 0.489262252619956 0.330455040819943 0.0989666473353282 0.028447598319035 0.492723690543789 0.761535784511361 0.352352307843976 0.966245655408129 0.736803026408888 0.65920942524448 0.467185930458363 0.752530561382882 0.471562591281254 0.801481719920412 0.838048600784969 0.286057496753056 0.861475526036229 0.344667344016489 0.0995196630107239 0.489233185583726 0.380881750157569 0.632747688242234 0.981738663474098 0.999626886558253 0.903019888892304 0.121050408729352 0.431821684243623 0.608872182162013 0.179237967182416 0.595074470380787 0.855131967102643 0.656968085980043 0.0695195258897729 0.223591212849133 0.37028645045124 0.0994985236413777 0.375202467381023 0.236859336060006 0.571059370241128 0.995080548815895 0.113799652066082 0.175334899688605 0.149292207406834 0.637625785693526 0.679185833081137 0.265024202738423 0.520765961327124 0.145578507264145 0.073494216913823 0.26608764947392 0.581983346226625 0.896730164471082 0.231246518862899 0.130652506134938 0.577728623675648 0.408594483505003 0.761895701924805 0.293631500212941 0.589491581376642 0.725324219772592 0.429876561458223 0.833593424181454 0.0899068059865385 0.92747854168294 0.801918422041927 0.103509549901355 0.41713937479537 0.54851747116074 0.0564540506526828 0.743599533729721 0.284243853653315 0.268048106196802 0.216965290165972 0.385442298369017 0.0958682630397379 0.0545022889389657 0.829015940271784 0.566353688307572 0.73357835218776 0.256964286060538 0.181038283098023 0.883269268698059 0.678474033796229 0.874863142119721 0.603251193196047 0.725392623876687 0.645222829936538 0.0976542578451335 0.164355654313695 0.571871072235517 0.114815597801935 0.620793558817822 0.538415620485321 0.204599621868692 0.524124237238429 0.0277883083885536 0.878628981660586 0.814052642250899 0.892976743243635 0.014000715429429 0.168269594833255 0.711671679054853 0.0230968950106762 0.511289413012564 0.172378751470242 0.261819393669721 0.247289291368797 0.764669955677818 0.630180352518801 0.735745323561132 0.425620910443831 0.114987380821258 0.528862527876627 0.557541547305882 0.543328022446949 0.662281870881561 0.0598962178896181 0.120528476524632 0.64497892965097 0.579914729739539 0.927385149281472 0.0691627679718658 0.70223779856693 0.769058871848974 0.137533758792561 0.0216877348767594 0.108694869165774 0.0331681916792877 0.0481683142925613 0.775656744241714 0.0698973263660446 0.509753613511566 0.795929113391321 0.76093664946733 0.792346744260285 0.247130557317287 0.652201709784567 0.406406621704809 0.271240562875755 0.183580860334914 0.477351094132755 0.806017857473344 0.553690436882898 0.388952522343025 0.290881515590008 0.824875281341374 0.519676949577406 0.643802462317981 0.713498040582053 0.759725365678314 0.540080591882579 0.12468528859783 0.53221492966637 0.481555984383449 0.747452823782805 0.677729938828852 0.61718939638231 0.271413533904124 0.0272203049901873 0.148889536880888 0.639758586247917 0.323004239245784 0.190464017172344 0.65453619366046 0.115190014042892 0.616351078513544 0.769217473822646 0.743447951935232 0.607106241751462 0.77932650280185 0.982426440496929 0.35289481122978 0.852372641833499 0.817129745648708 0.15813369320007 0.396375006705057 0.860199260641821 0.456972629136872 0.347953133857809 0.869803579628933 0.576722211746965 0.354177222508006 0.941655163117684 0.590800239033997 0.807191772684455 0.297981006938498 0.912176936303731 0.725733084818348 0.352067442452535 0.781545128365979 0.743063279723283 0.284480885430239 0.648187704512384 0.557721075895242 0.066055959968362 0.448718510321341 0.278152271807194 0.849431990978774 0.15495441180421 0.370955143724568 0.883830888795201 0.142886267164722 0.651490574807394 0.215750489833299 0.176878738419618 0.100100581916049 0.674533259116579 0.890482007919345 0.369589699511416 0.359969701294322 0.808532829750329 0.851716602446977 0.621029673886951 0.259572496763431 0.390255671455525 0.0635697370953858 0.257418365753256 0.0459145265188999 0.841783882861491 0.0720201493962668 0.0798137019528076 0.943769373889081 0.181544947980437 0.621955815912224 0.756962518794462 0.429723503296264 0.532072900810745 0.0948466162895784 0.982701602661982 0.596531536737457 0.841059343712404 0.391865900391713 0.310688601941802 0.191185492484365 0.0953720869356766 0.241254960771184 0.856890312691685 0.911730003796984 0.291264368447009 0.264421860023867 0.713010903166141 0.939862513940316 0.362713689168449 0.89691329442896 0.800353075137827 0.0924732828582637 0.928455481582787 0.72170182506321 0.591678681366611 0.325669397856109 0.861117445495911 0.545176326413639 0.0517309699417092 0.479447692451067 0.976046848746482 0.923808995184954 0.230563647621311 0.0131034631840885 0.528079848201014 0.835135669219308 0.644442520516459 0.64151121284347 0.236860065369401 0.597917067154776 0.406990269527305 0.153592094355263 0.481390890541952 0.0972722684498876 0.536006983777042 0.693281388457399 0.0609171288763173 0.309553580312058 0.0380085881683044 0.596071081350092 0.420287840794772 0.210646493637469 0.362824167325161 0.643194054625928 0.394755884988699 0.840475274070632 0.343226032494567 0.785745035156142 0.872128060394898 0.430201545320451 0.47335816046223 0.725059694598895 0.672637454611249 0.224205318097956 0.551166676012799 0.92495072835125 0.654618518953212 0.333750565466471 0.020010852040723 0.323675190289505 0.404523440198973 0.188069489051122 0.765764314620756 0.198245867125224 0.48073775064433 0.212010571432766 0.557684947880916 0.418818681593984 0.711355017940514 0.401622522184625 0.593644976022188 0.402622048547491 0.826102877780795 0.847328245935496 0.777704805913381 0.412944115162827 0.221041255157907 0.465992987048812 0.265542221474461 0.499192771138623 0.768056020950899 0.581317863850854 0.786131705823354 0.504604270590935 0.616699815872125 0.519706162521616 0.585430649286136 0.273001926892903 0.495871315670665 0.473344995782245 0.612823586687446 0.0378691388643347 0.70326948807342 0.873564382463228 0.58588266736595 0.194103251229972 0.275119683020748 0.437316775368527 0.929641064822208 0.42239417276578 0.59512450390961 0.930215823091567 0.166106034433469 0.891587114955764 0.0669806791027076 0.589581991999876 0.791519642404746 0.732989538577385 0.728877740614116 0.432778357916977 0.627283731759526 0.425376649422105 0.136239822166972 0.532252794285305 0.739745690471027 0.133250995401759 0.38201175167691 0.283327544627246 0.0578768164175563 0.637190807498991 0.105726018655114 0.422022947368678 0.257883848396596 0.946807145290077 0.3749331071903 0.58429771024501 0.503951047020964 0.977023253880907 0.267776446514763 0.932541022102814 0.434466025265865 0.772234018493909 0.298531948323362 0.257638456069399 0.487902838347945 0.333361598304473 0.26322437341325 0.990333821561653 0.545265142652206 0.442047115059104 0.505329487186391 0.742280485718511 0.517531459177844 0.381169902973343 0.320814426934812 0.556440142136998 0.265621368600987 0.0695226789312437 0.818464619719889 0.609109051665291 0.267609392020386 0.667049324905965 0.107968942392617 0.744842282470781 0.475791075059678 0.357645748839714 0.699348152116872 0.413987251645885 0.126374575686641 0.0981758408388123 0.427304348074831 0.377894647088833 0.714171412822325 0.234037689412944 0.514717927135061 0.829894027630799 0.0678243992547505 0.209128869937267 0.551928125731647 0.922603081869893 0.988860115471762 0.69885546512669 0.144398751123808 0.231455920324661 0.364188031444792 0.60396451264387 0.604743784111924 0.0803150383126922 0.0457479288801551 0.807828960437328 0.392373578792904 0.629787768083625 0.80176660582656 0.286544744810089 0.63428263834212 0.683338164649904 0.846425168896094 0.506154570993967 0.720796727209818 0.39181756128557 0.0648585584131069 0.0201390966260806 0.803247610081453 0.196424450334162 0.371694514546543 0.619088603102136 0.72984645111952 0.0416882585594431 0.918093468220904 0.319331786804833 0.431762279872783 0.683958876326215 0.733731587375514 0.912844003844075 0.981805782758165 0.266421358771622 0.288579838650767 0.291950531492475 0.592352062365971 0.55097473395057 0.982571316056419 0.579639578638598 0.177040742377285 0.942865257284138 0.167357977682259 0.662476179972291 0.320833679642528 0.709160946176853 0.643207739088684 0.0784549632831477 0.575463324845769 0.0844039775896817 0.500828016723972 0.3220002731774 0.381593130619731 0.700357586853206 0.994883573043626 0.947397835650481 0.696345305969007 0.74439413060667 0.767838195089717 0.230245529732201 0.785987237561494 0.06009640409844 0.333361354202498 0.473660384984687 0.886883076042868 0.0993101124139503 0.166018215348013 0.830210725395009 0.867147844876163 0.962174557703547 0.488554654470645 0.177623767612968 0.929962734982837 0.797755220904946 0.776939165892545 0.65574466209393 0.430346991142724 0.644351274783257 0.464014382185414 0.427509953624103 0.0614031068654731 0.748219770521391 0.425028484170325 0.969488391561899 0.748016814596485 0.159755368882325 0.193361448377837 0.750602679941803 0.113499458038714 0.810298859134782 0.777915338219609 0.196068583077285 0.122108809307683 0.27821833469905 0.988338765285444 0.383132963220123 0.695463888542727 0.416359752963763 0.539889158308506 0.418214805116877 0.776493646826129 0.281855119899847 0.753643018908333 0.545854228024837 0.86045557370875 0.976862557562999 0.780080051361583 0.332047411587555 0.0229454116406851 0.134269427335821 0.142441909369081 0.0575031287944876 0.9833295933716 0.674715596376918 0.930721864004154 0.729200033822563 0.92242923170561 0.0215277141612023 0.912607021164149 0.301590052335523 0.907133731411304 0.220746135178488 0.478515431971755 0.617170919314958 0.123994088845793 0.392588897019159 0.0503342896653339 0.896220378126018 0.954047386667226 0.766040546086151 0.2597193624801 0.697567534239497 0.0393677424336784 0.969702314096503 0.108092565175612 0.57796925497707 0.514480077305343 0.080001995624043 0.641882443542127 0.946682955010328 0.697097842853982 0.0244607584387995 0.27186687276233 0.525650715916418 0.140276182938833 0.250574059162755 0.662838935791515 0.393632033502217 0.393293328757863 0.18189325453015 0.306130631668493 0.651099369698204 0.156261094287038 0.0595656346646138 0.296421614370774 0.355303807982709 0.365554982912727 0.584261378466617 0.521090187989175 0.67266672679456 0.980936789868865 0.15378934212029 0.430932500271592 0.469073324624915 0.0588211849541403 0.697140737725422 0.130294877379201 0.119511015466414 0.667479201392271 0.59061480820179 0.51183606751496 0.732180952974595 0.445142869553529 0.177311581471004 0.837538340066094 0.621066195829772 0.212093069141265 0.940044131341856 0.529014813855756 0.959682443190832 0.354951684775297 0.78060988887446 0.187641515822615 0.399822584062349 0.144926030291244 0.653787583152298 0.281978506417945 0.379115807902999 0.905304445270449 0.963987230157945 0.888856539782137 0.60529442791827 0.214640089080203 0.693516682016198 0.667472316748463 0.659080708820838 0.0126850371318869 0.486437215283513 0.213008159270976 0.644767910754308 0.667645976287313 0.799164792485535 0.860067809307948 0.360387753932737 0.971845520217903 0.749905279215891 0.139960468036588 0.0179220380168408 0.566426131043117 0.669066406602506 0.90074954113923 0.177067780992948 0.527810316747054 0.424976943617221 0.177531177590135 0.70380540301092 0.262710147132166 0.848213165153284 0.289719280623831 0.643360771895386 0.854405003990978 0.272175924994517 0.733285862240009 0.352327589234337 0.446908465363085 0.788076666104607 0.334732726013754 0.621604829311836 0.822794986914378 0.176627923524939 0.474689324598294 0.61962088808883 0.599123228029348 0.122124375361018 0.591699718853924 0.998526736705098 0.162304902679753 0.126247448346112 0.66400382153457 0.202474593392108 0.758913936598692 0.156591053772718 0.27780707081547 0.82262592243962 0.539902234014589 0.358546810366679 0.0707943356619216 0.337669372351375 0.504993073865771 0.616782703590579 0.476066357316449 0.0443487116950564 0.401343489654828 0.135325053357519 0.320241930354387 0.628431077888235 0.561401317471173 0.863732604922261 0.676304623938631 0.773114563007839 0.975815139038023 0.935742267835885 0.481036707565654 0.376641365773976 0.725362189039588 0.643553948989138 0.749522693511099 0.655666025760584 0.644286560099572 0.418319531548768 0.281053356705233 0.0973991899518296 0.7437000970589 0.438194553393405 0.158750649993308 0.14383259474067 0.739450837413315 0.829665178917348 0.642063034977764 0.836467848487664 0.440964927331079 0.31746068592649 0.371039217377547 0.310053367696237 0.295763484328054 0.585837738080882 0.532052173118573 0.634033553597983 0.510077370179351 0.0583327975240536 0.738933539227583 0.207308400741313 0.836762254601344 0.358199145996477 0.227697950133588 0.585074425903149 0.68111523952568 0.600932042105123 0.339897780204192 0.40880932850996 0.448033410583157 0.599130842674058 0.129164655038621 0.386705460166559 0.729901195655111 0.976501109614037 0.61846028116066 0.453358886793721 0.754045717786066 0.140465548676439 0.906403645453975 0.585614791379776 0.133420795409475 0.0712429787265137 0.597649729622062 0.140976491912734 0.0464127909741364 0.611513316896744 0.4960861288663 0.909073613034561 0.0164896690635942 0.609562504622154 0.273328391041141 0.629413509736769 0.141500779620837 0.480641337970737 0.310428573868703 0.652274900730699 0.800434540656861 0.853981034588069 0.241881926436909 0.850115710699465 0.817725509135053 0.401580446057487 0.316316900828388 0.983256114758551 0.364802887900732 0.593504373515025 0.195184287598822 0.559138435919303 0.779160266129766 0.708599904179573 0.138439495598432 0.599937768199015 0.460650262578856 0.6959807075141 0.993719970507082 0.579844511812553 0.241958218330983 0.0331904383818619 0.114173741454724 0.401808003957849 0.0656668872362934 0.322859581972007 0.118332061243709 0.837335397971328 0.0815306396409869 0.504896983203944 0.224836296117865 0.709301408308093 0.965818610643037 0.193780613881536 0.737314612746704 0.0675391973298974 0.464825376076624 0.273425663949456 0.589671646114439 0.429043568884954 0.375473014658783 0.664939584266394 0.577018176978454 0.0143536435510032 0.0263496538670734 0.797888209228404 0.9006429962744 0.331083854422905 0.404588484039996 0.764657562028151 0.147587673971429 0.411064470023848 0.314057565785479 0.562109066369012 0.539621679247357 0.766466804838274 0.771424089292996 0.0553270242270082 0.717687920981552 0.243959876885638 0.3702718898491 0.0333992499881424 0.227603310944978 0.393630968811922 0.578536952729337 0.95085189311998 0.892167918379419 0.840806317378301 0.426849203691818 0.942581582667772 0.587663093695883 0.696208296762779 0.849628222228494 0.440266724226531 0.536216309403535 0.288953819242306 0.157989995968528 0.0158372925897129 0.773328554462641 0.576696637973655 0.416589073284995 0.479598799641244 0.423191109241452 0.761802175140474 0.72958465762902 0.875480673785787 0.551263869397808 0.463701346642338 0.937689403598197 0.224156218334101 0.0565653263474815 0.125208650378045 0.895129518439062 0.739908440564759 0.604173738693353 0.938352288673632 0.254877164615318 0.501659973189235 0.174560483521782 0.646047491002828 0.965965266141575 0.309104018004145 0.940027273553424 0.467910595461726 0.616905980159063 0.997355387676507 0.231218728579115 0.761755923002493 0.399568481973838 0.574563112950418 0.116014653672464 0.751635573592503 0.552981494904961 0.941591816234868 0.346714456249028 0.260638703533914 0.55510547044687 0.304824778302573 0.678475681426935 0.10299613614101 0.53148238102207 0.472538553390186 0.705467350448016 0.389524485080037 0.33685787988361 0.378738872040994 0.0720216822368093 0.26701896189712 0.696615953976288 0.832185073341243 0.399116686559282 0.0827350742835551 0.0292449441668578 0.0167974777356721 0.880618544605095 0.711900247938465 0.380410829042085 0.430314407101832 0.523982461243868 0.27678124344442 0.0139976165560074 0.468524679734837 0.314863587510772 0.780615088085178 0.620197005860973 0.551604963298887 0.205683430489153 0.745911606324371 0.37656149279559 0.178922478633467 0.0578224346926436 0.419156081003603 0.273979841356631 0.30248545503011 0.0802323783305474 0.587589674782939 0.035948697347194 0.0964843826484866 0.135087287200149 0.120473377937451 0.927904206200037 0.683103654568549 0.770642756442539 0.662569245290943 0.163024506312795 0.0837222330435179 0.319028179498855 0.372274356314447 0.0680856971652247 0.979612491244916 0.459190439183731 0.671583871070761 0.936944073368795 0.652385974044446 0.655414875254501 0.397121770658996 0.314403593589086 0.689499087592121 0.57063174207462 0.338363191762473 0.940460964392405 0.668336081844755 0.147424008783419 0.72086306393845 0.25336581956828 0.116260060982313 0.780826613625977 0.770561245053541 0.162996411304921 0.0664505719020963 0.274163969850633 0.796534425206482 0.977687640679069 0.18638920123456 0.301208143385593 0.674363259954844 0.905634879360441 0.0522855209931731 0.931971738494467 0.285967105261516 0.389757957209367 0.593953300558496 0.0727703208662569 0.996974438768812 0.0669906944292597 0.616674447245896 0.496183245955035 0.0479060063208453 0.70680827336153 0.836874727755785 0.388427192303352 0.63474633297883 0.964590603909455 0.099336466207169 0.338106056493707 0.0795620113797486 0.332699178382754 0.495926487788092 0.247143507860601 0.760180044216104 0.297437927527353 0.714475786548574 0.43429183464963 0.160942009205464 0.674904785549734 0.286331737369765 0.150300996736623 0.924963923918549 0.420181380063295 0.216724841883406 0.617901730893645 0.836405027150177 0.989519079241436 0.131284103284124 0.226108394721523 0.37936861502938 0.413300150455907 0.458344917655923 0.246673081403133 0.296723911501467 0.793649782270659 0.847654025491793 0.700257319719531 0.221038303575478 0.193207548421342 0.155095378505066 0.706689968497958 0.429499912341125 0.322224588601384 0.936319288716186 0.421091136138421 0.625370446187444 0.720990160852671 0.356202592607588 0.268746958626434 0.99428258337779 0.868072757401969 0.120565946293063 0.342692458999809 0.563002492275555 0.286614714255556 0.227352626514621 0.609071653352585 0.620292662256397 0.677956825506408 0.335943290635478 0.702570897724945 0.499539448728319 0.171727240532637 0.429721835611854 0.771277566794306 0.46556634174427 0.770231862976216 0.454192281363066 0.932526435684413 0.201688141545746 0.0112276920978911 0.131977227269672 0.0642342018033378 0.711101539130323 0.601986174241174 0.0182198191457428 0.347437004779931 0.778000865881331 0.742247704828624 0.180411790192593 0.606011089188978 0.527763393155765 0.821584337237291 0.315719280415215 0.170230269150343 0.277365371633787 0.527075965343974 0.500471548778005 0.123197139231488 0.0213385717803612 0.46210365657229 0.634495479820762 0.915619335195515 0.396148479611147 0.92635309765581 0.762052485235035 0.283712237584405 0.746591171240434 0.322913358397782 0.19211140101077 0.502249604621902 0.406915213125758 0.677936616444495 0.0896965228533372 0.253046104528476 0.969820175473578 0.894912748509087 0.908336308666039 0.438253854268696 0.970443463705014 0.306990711032413 0.93357312144246 0.780743582996074 0.919082082603127 0.344231649651192 0.0137394387251697 0.0290580424992368 0.761210600803606 0.118346764296293 0.332504846702796 0.52894581298111 0.010424029333517 0.749250516581815 0.0504131553485058 0.24869924304774 0.887100806476083 0.480313487350941 0.876633454929106 0.990779538629577 0.547125693669077 0.560973510434851 0.097857666707132 0.769243607947137 0.473361323415302 0.706010000202805 0.275151423423085 0.832112732718233 0.419148464514874 0.421758588387165 0.562462503439747 0.685284952353686 0.633711565344129 0.243732586367987 0.349587404879276 0.520010622225236 0.176406507820357 0.110077070207335 0.319923363446724 0.496943230601028 0.986926811232697 0.309718426594045 0.552770202171523 0.702339699501172 0.890504873751197 0.260919091417454 0.265466517591849 0.970053451906424 0.104422379725147 0.0915929619316012 0.20791623794008 0.0925627186871134 0.140213631519582 0.842958522310946 0.0663281309045851 0.157296747742221 0.570232048025355 0.893781383568421 0.345383936366998 0.297860524749849 0.47351228285348 0.619100934977178 0.949798056257423 0.773103589944076 0.614184986967593 0.975036943093874 0.101584971097764 0.298405177339446 0.392649761852808 0.962861539262813 0.922752584994305 0.990556538912933 0.987164563790429 0.666697910954244 0.36086043239804 0.0101829600776546 0.354702314669266 0.600426900843158 0.970568268734496 0.654726396352053 0.833868548083119 0.107570851026103 0.471696227085777 0.407416358629707 0.475060073777568 0.959073792549316 0.950324380914681 0.46803058299236 0.893528829533607 0.216082629871089 0.588319213066716 0.579083176192362 0.531315800671 0.619505457128398 0.641742725702934 0.645780507752206 0.301897296046372 0.809563940004446 0.417843928239308 0.160199369399343 0.962058052371722 0.58742980274139 0.825863912550267 0.394862049524672 0.71819269459229 0.460831022050697 0.523675798398908 0.674318758021109 0.764781652269885 0.972078460808843 0.718300062119961 0.0776566048385575 0.378195269620046 0.362616457750555 0.472218464475591 0.0266207829327323 0.0125507105118595 0.587388328225352 0.679014415869024 0.310292926931288 0.346143768189941 0.404915794131812 0.767464036089368 0.0618392002303153 0.0655559141910635 0.711312542122323 0.683937732577324 0.496979980971664 0.265572814897168 0.313428205661476 0.298616264695302 0.464351307451725 0.401516692338046 0.172697764169425 0.67968778073322 0.450765037077945 0.78253502180567 0.494081175972242 0.192108266178984 0.0804632169706747 0.032638482786715 0.768359407666139 0.212158950166777 0.435981130267028 0.834211240056902 0.328202544550877 0.312888906488661 0.207113363954704 0.141891128183343 0.876031436761841 0.752874662878458 0.119433168603573 0.708404469776433 0.734889262544457 0.478818835052662 0.715549334587995 0.824015259603038 0.598893351044972 0.177975634732284 0.176234715350438 0.100302989706397 0.815993786565959 0.289735605260357 0.542629600595683 0.884299878531601 0.762898094814736 0.462350300988182 0.411623007843737 0.25388347457163 0.757270296348725 0.495927182752639 0.500942555640359 0.908839542521164 0.257303550464567 0.646773895376828 0.144591642394662 0.914296813053079 0.0678828989039175 0.0476561606884934 0.397173046134412 0.290221140685026 0.942366347191855 0.708282592587639 0.41445443700999 0.610896630021743 0.528307327269577 0.933002432461362 0.290185257464182 0.31971397258807 0.240893065647688 0.031528818027582 0.912010672893375 0.436636831506621 0.889427992417477 0.703102518403903 0.160466474816203 0.319211560934782 0.452826303306501 0.765590793383308 0.605100575913675 0.168847845674027 0.620876216955949 0.144819189922418 0.168480499400757 0.826384595432319 0.926966350045986 0.387112580309622 0.917154449413065 0.283285016485024 0.109303107669111 0.869581685401499 0.976267365261447 0.157795416268054 0.845733578673098 0.133434872878715 0.19763698482886 0.355307433323469 0.412509170160629 0.290906190865207 0.261912991679274 0.0773201670846902 0.523249633922242 0.144958694085944 0.987106537823565 0.108691574595869 0.685492791009601 0.506280610363465 0.835454339853022 0.0478033456509002 0.953018155698664 0.600217260811478 0.0406412063026801 0.526473872954957 0.324980508659501 0.737087876817677 0.615165959275328 0.72079678760143 0.163653160408139 0.065486233565025 0.596937653964851 0.868656219439581 0.622345813189167 0.888862913863268 0.597276893935632 0.0200730348867364 0.690126872002147 0.864552474305965 0.444342971122824 0.717401474574581 0.0115655594272539 0.812112623939756 0.710321385068819 0.539815713348798 0.936396130819339 0.783117977660149 0.653077265536413 0.91597367860144 0.182656256682239 0.426393902797718 0.885910229173023 0.389131840253249 0.308936172656249 0.310935863642953 0.179799671873916 0.611207958464511 0.271548032478895 0.344128254139796 0.0212043145415373 0.806684991398361 0.580051219393499 0.629137154261116 0.897355189537629 0.0558362356992438 0.957089834499639 0.503988555974793 0.839039780888706 0.384385911459103 0.381497370267753 0.64039914094843 0.362997938657645 0.72223994521657 0.489984824431594 0.893510636445135 0.955738999755122 0.227124451329 0.137316210917197 0.811002336132806 0.315056103523821 0.570163662822451 0.866416693767533 0.641431262646802 0.747641721831169 0.316497693031561 0.376169751537964 0.367401661837939 0.0980816681869328 0.21528928946238 0.751860402114689 0.112149746762589 0.937888337026816 0.845283788398374 0.133915251505096 0.510932853096165 0.101112655673642 0.381498605529778 0.138662453594152 0.96990230944939 0.312516500689089 0.636654658601619 0.696478093294427 0.904416741123423 0.271653327099048 0.180004641236737 0.620479300229344 0.2805269061937 0.411642251100857 0.225128897628747 0.347621290246025 0.582574197708163 0.524944019953255 0.873162647315767 0.91547753315419 0.792682644713204 0.0297041186527349 0.233746111101937 0.944780747841578 0.442484577146824 0.028623458694201 0.23652941045817 0.535092852306552 0.721617587523069 0.866997526003979 0.783592603870202 0.444290383397602 0.69168254541466 0.414339105165564 0.110838272827677 0.594596644798294 0.586632535033859 0.551417828132398 0.149978737642523 0.992931245216168 0.406980454968289 0.826583341232035 0.937906118668616 0.232930270668585 0.995886650294997 0.0610533589846455 0.0838149929465726 0.605695806478616 0.396058906863909 0.458260621568188 0.0597319676866755 0.414805137556978 0.527703907417599 0.539398362820502 0.18136494732229 0.409128516621422 0.171168285273016 0.666141272473615 0.271496767606586 0.121534001710825 0.888821027209051 0.418178514828905 0.996391074925195 0.614166388195008 0.720191356847063 0.65863952296786 0.277178426170722 0.0986608567112125 0.216703897288535 0.787216501915827 0.23822086519096 0.738822209825739 0.601671374202706 0.312306351247244 0.992513033992145 0.539299968979321 0.53854137103539 0.538353917084169 0.488030035530683 0.76112013278529 0.732208644833881 0.0199771814118139 0.178298520331737 0.84444289074745 0.788582608131692 0.466813895076048 0.445006222005468 0.2024128844589 0.456949220702518 0.259290505505633 0.874284304881003 0.216627293294296 0.0408408296247944 0.401686813205015 0.362807173309848 0.715657834573649 0.134507603556849 0.576322652772069 0.24355432047043 0.682399825823959 0.323911809236743 0.897298118772451 0.881527830916457 0.845437543599401 0.0865135183837265 0.731659681389574 0.891975213354453 0.798171717422083 0.704185059492011 0.876859489900526 0.707360026575625 0.0125710099306889 0.854242182902526 0.182718094466254 0.345263907576445 0.751739433796611 0.107363343371544 0.873507178006694 0.91905002963962 0.0902581632346846 0.477726108066272 0.98978444528766 0.622884516282938 0.815698595361318 0.933191770308185 0.423884348478168 0.406614048222546 0.640112821317743 0.618699027413968 0.49066919347737 0.683430498354137 0.128182210742962 0.344850433636457 0.462609164102469 0.384017613211181 0.947805967007298 0.994944694887381 0.197614364481997 0.793063417286612 0.0576418261998333 0.529332078425214 0.118991543182638 0.0931442212243564 0.883941987694707 0.743098929675762 0.474402362327091 0.963725011851639 0.735463969181292 0.772219842369668 0.264302119591739 0.87232653258834 0.335605758687016 0.837234391386155 0.976829329037573 0.138263410713989 0.301212486510631 0.310879848347977 0.0589111931202933 0.554504389963113 0.612530865776353 0.704147040667012 0.518220994242001 0.295992564696353 0.784458548827097 0.0124238434084691 0.160279370537028 0.589736269749701 0.958115375356283 0.827472073649988 0.069572052070871 0.158522081801202 0.954587695440277 0.33541095493827 0.543321282558609 0.291053449127357 0.153563690704759 0.456459070390556 0.721028561850544 0.358460462347139 0.0639533169567585 0.715003325031139 0.549547613766044 0.256079404645134 0.628556513802614 0.696336789138149 0.49398633739911 0.100175166018307 0.365618522495497 0.712322594604921 0.811454430047888 0.492964098257944 0.679262141801882 0.809228557490278 0.523026314037852 0.0472372952988371 0.291295356489718 0.581807499681599 0.14327568795532 0.0327142115635797 0.0242850937601179 0.651504760151729 0.375933404352982 0.439041962043848 0.744935005954467 0.864886704077944 0.299795602243394 0.906551044783555 0.956430777376518 0.261026786488947 0.142520207094494 0.24162931177998 0.580333193133119 0.634158579679206 0.491064054353628 0.126320280400105 0.644568881436717 0.164366135024466 0.0382699241116643 0.684989968140144 0.171801131744869 0.742004141076468 0.401061333357356 0.554846156931017 0.103505818068515 0.172187233532313 0.0835435697599314 0.258386532734148 0.975454381904565 0.994665616718121 0.0359852135274559 0.56194160111947 0.533225708692335 0.325153527401853 0.259013467973564 0.391077108485624 0.390062822136097 0.241923153623939 0.715068034643773 0.499885795316659 0.575866682729684 0.503968016142026 0.655726250489242 0.720316402981989 0.286320816860534 0.92102774015395 0.967978654499166 0.872471630352084 0.196261262746993 0.61538264899049 0.129404263140168 0.835992925851606 0.242154304133728 0.0810635845107026 0.76456631537294 0.782275297534652 0.997754263672978 0.192735406104475 0.623967016111128 0.435188719474245 0.516624210507143 0.381264602553565 0.241609382317401 0.846536788269877 0.472282113546971 0.87887990051182 0.278563320171088 0.470156140241306 0.583954737058375 0.33759652831126 0.136683499980718 0.597804057390895 0.0160710996389389 0.264802911735605 0.870099201872945 0.115984260095283 0.905563550412189 0.277915239799768 0.262783312031534 0.284828981070314 0.755687211367767 0.284116521857213 0.0730571644287556 0.537167583329137 0.514298643844668 0.919456066191196 0.0393252573953941 0.734117992965039 0.824523407767992 0.366044659081381 0.0386885622260161 0.840072811457794 0.802729387350846 0.150305823455565 0.436534456659574 0.340754209333099 0.535431604073383 0.680960201348644 0.695596325735096 0.70782493572915 0.948899876470678 0.1032667456544 0.158849726582412 0.0222113702632487 0.24068262116285 0.609545426703989 0.945462964226026 0.679941408447921 0.612071115265135 0.99819215587806 0.664987146810163 0.804604033585638 0.286997159353923 0.978461091732606 0.0853848842042498 0.953494558159728 0.142478467270266 0.917428315002471 0.902004067858215 0.0831711985357106 0.873492679640185 0.133108434085734 0.0389493064698763 0.986811465788633 0.842077437038533 0.521771883899346 0.543397627698723 0.268818156418856 0.903168526710942 0.772045197663829 0.946152427373454 0.0858628921140917 0.670776312816888 0.444036022685468 0.858827231437899 0.526610594033264 0.235204843990505 0.745479703722522 0.9994202177017 0.594876689694356 0.801916886204854 0.300633380045183 0.959295138181187 0.928717236809898 0.904531978922896 0.0689755834778771 0.184888477504719 0.755987941313069 0.272932111422997 0.9979787900066 0.0708112026704475 0.139194713225588 0.489321988453157 0.621374228089116 0.759251387179829 0.762881277825218 0.905196884351317 0.248641053193714 0.74638946901774 0.391187972733751 0.449446335050743 0.0622390496381559 0.412778501077555 0.698273321562447 0.905401585870422 0.81330856180517 0.522692411579192 0.873879555223975 0.11117996764835 0.834671405011322 0.806454149992205 0.921630050137173 0.532796198704746 0.920349393212236 0.57322314431658 0.518115157019347 0.77935221464606 0.525441721521784 0.862613890641369 0.442045517216902 0.886443043623585 0.343247663064394 0.480572790955193 0.282011992644984 0.873992647968698 0.348794097893406 0.320067030943465 0.119023490115069 0.394655599414837 0.515508019304834 0.314609878889751 0.187782088594977 0.32433243912179 0.274010863513686 0.168878994376864 0.824180297432467 0.46457447105553 0.617503608639818 0.610948617749382 0.411611094791442 0.497383544233162 0.872506985261571 0.777852571511175 0.319119324272033 0.975013464356307 0.552995470492169 0.729504947385285 0.508150712475181 0.758353897517081 0.0262762017617933 0.245918357742485 0.446590300682001 0.920985819846392 0.327141909482889 0.298972515277565 0.532342950664461 0.689521031184122 0.347194813669194 0.305999853631947 0.184964230945334 0.806326948199421 0.472596751542296 0.635368510650005 0.799243435272947 0.336007583499886 0.0767783448332921 0.668322901721112 0.569652596497908 0.687570285294205 0.134961105149705 0.717912196067628 0.264853508842643 0.635934460042045 0.549248713548295 0.0788628795812838 0.20637559489347 0.42122952420963 0.605082791505847 0.922143622483127 0.100315756769851 0.968151540933177 0.250633268528618 0.173875009447802 0.262965707839467 0.867336876615882 0.993321930542588 0.315453143569175 0.974656407937873 0.204653362797108 0.71818163117161 0.967480118512176 0.24058010202134 0.985351694717538 0.191242922833189 0.73993626012234 0.265435604923405 0.128844703503419 0.635462168820668 0.109906916839536 0.390047451548744 0.335072902976535 0.146699388497509 0.743026613485999 0.794725186084397 0.877589306631126 0.101839973989408 0.782052546299528 0.905778330876492 0.0556276940112002 0.955242645933759 0.697320870230906 0.714049989031628 0.983371481639333 0.528469510327559 0.0841199311730452 0.916676585797686 0.987121468381956 0.0955633082170971 0.196806760819163 0.808198949189391 0.760220648816321 0.568611681596376 0.251134714607615 0.905686203241348 0.572440186655149 0.483613214516081 0.216305396780372 0.555953823465388 0.998237607020419 0.389675299993251 0.986171450694092 0.679494003641885 0.668818194079213 0.761475743493065 0.884485168065876 0.652855286023114 0.0244649249990471 0.494567005748395 0.872025748013984 0.450418764019851 0.740965865426697 0.188365356319118 0.445570242092945 0.838819651387166 0.635622756341472 0.0777023609355092 0.911053772866726 0.63899835058488 0.489314182261005 0.510338732860982 0.0525630607898347 0.532075360270683 0.81435630902648 0.253571623810567 0.420782456167508 0.37375326392008 0.868481116725598 0.777537008509971 0.375220088823698 0.710537771673407 0.55340110112913 0.494661930990405 0.173766914454754 0.99338679274777 0.819083768129349 0.841753623897675 0.0891439174721017 0.206775159861427 0.565158278523013 0.21227964971913 0.479829133250751 0.77009188743541 0.633530368609354 0.179544334753882 0.114118379403371 0.18279517352581 0.3779744195682 0.458749434505589 0.491568378254306 0.73500000508735 0.280591232250445 0.0391263290378265 0.94851565903984 0.929352711699903 0.391312093632296 0.759498732092325 0.971369903308805 0.90501502469182 0.927869569766335 0.610179211089853 0.466555302571505 0.0331932371412404 0.114367499414366 0.89592768925475 0.992922833263874 0.455686044613831 0.0555023210239597 0.368378315453883 0.69832383246161 0.674444848792627 0.615428791178856 0.997610948383808 0.173669336361345 0.830786012206227 0.462842791129369 0.756234935401008 0.482990826396272 0.951774401967414 0.401729608268943 0.476447534651961 0.432335975756869 0.105104807480238 0.757809635398444 0.213223752717022 0.830576928376686 0.34931130157318 0.457967180337291 0.893500730837695 0.282300138776191 0.566225345297717 0.72723077490693 0.754653267778922 0.829491597518791 0.30021694899071 0.128636777948122 0.12855655714171 0.6743507897784 0.84839429988293 0.298373329984024 0.882585195617285 0.808030936035793 0.499580669922289 0.749198777105194 0.886373333954252 0.281218973326031 0.37088014540961 0.752740725346375 0.623970820321701 0.855878470358439 0.178211297325324 0.931809510258026 0.407472344189882 0.0537243898818269 0.311652279659174 0.653417974268086 0.67912696946878 0.121988278252538 0.200842190822586 0.104964557180647 0.883836016550195 0.380795456306078 0.243444638468791 0.0539642022084445 0.14753524921136 0.802985968952999 0.861840908660088 0.886487807177473 0.81293014611816 0.410626022999641 0.998363179392181 0.853491674899124 0.512105804115999 0.548866885504685 0.211723987646401 0.42534807197284 0.868652736549266 0.586532483880874 0.741938140189741 0.926559853642248 0.922015856420621 0.871931142478716 0.678712827533018 0.0126284914510325 0.611228856036905 0.170845362562686 0.278626976157539 0.991953808353283 0.488946016090922 0.802140980116092 0.867778740606736 0.294623936554417 0.141862214431167 0.919604277580511 0.985006596299354 0.077921575573273 0.114436728025321 0.648788529599551 0.935986234506127 0.0556161656673066 0.274188504519407 0.176492138747126 0.720056899301708 0.533428168115206 0.0654604341299273 0.874922541650012 0.10889750353992 0.652235574957449 0.54749953065766 0.288562137454282 0.857197697469965 0.665348231487442 0.194592402775306 0.519520865380764 0.0948975849663839 0.302459001429379 0.521800699227024 0.0970299920532852 0.295502862711437 0.914042345157359 0.342005860535428 0.400867851309013 0.411678714957088 0.67788420505356 0.703974183045793 0.0281068610050716 0.406718627824448 0.904444376740139 0.423464379443321 0.0688395253242925 0.979696064477321 0.968862419130746 0.599053263885435 0.397462580581196 0.845703675374389 0.491178827229887 0.635688614547253 0.270256032072939 0.317062741159461 0.0448856809502468 0.855038300864398 0.566180556388572 0.340764648783952 0.255065675650258 0.739704779302701 0.111690158755518 0.303554317879025 0.611755434246734 0.633321797647514 0.451913072408643 0.78637915630592 0.748365800206084 0.553766750905197 0.622794413149823 0.131318842521869 0.469056542441249 0.486377208840568 0.540669182136189 0.957131175093819 0.701724251115229 0.498940943186171 0.235689450721256 0.981073261082638 0.510493807226885 0.355520891856868 0.191423479232471 0.682729716158938 0.203335360575002 0.347252083588392 0.700062899526674 0.323032180969603 0.759102236954495 0.789863484033849 0.506246617953293 0.300400161237922 0.446603127906565 0.965918760451023 0.978594647552818 0.325474367062561 0.350660593335051 0.852844026489183 0.583885693540797 0.645299961320125 0.681408597545233 0.124548934709746 0.44790855968371 0.786072391578928 0.772276027083863 0.392945727084298 0.572923616671469 0.897387878687587 0.160200939811766 0.307371369968168 0.245009849607013 0.539016507577617 0.0801064189453609 0.018450333699584 0.826477820950095 0.573252490952145 0.188786981282756 0.45783469957998 0.788001368597615 0.7694300008961 0.94913679368794 0.260427495164331 0.0522998545505106 0.892436339964624 0.0492333040107042 0.0250650684908032 0.769440122023225 0.621575797542464 0.817078003636561 0.416414350669365 0.61387952596182 0.649425574440975 0.684454518586863 0.47159056619741 0.233752768239938 0.90693980748998 0.925285606295802 0.900867623568047 0.78423913273029 0.367221604476217 0.386701462334022 0.0347299109376036 0.812947950118687 0.562890183930285 0.570446310089901 0.897902730091009 0.651189475597348 0.79584515683353 0.108633195960429 0.255732148494571 0.90829170369776 0.273037987831049 0.022958723611664 0.283988293868024 0.793958118332084 0.963706039665267 0.628417793116532 0.450635822077747 0.320211097900756 0.330500581397209 0.303863797001541 0.751961329637561 0.24811700405553 0.0555264329514466 0.941756222487893 0.97224245100515 0.0282976387999952 0.526891291942447 0.288366640124004 0.0785349561227486 0.0861351494886912 0.555991870872676 0.471917905563023 0.287408063192852 0.781189292226918 0.515475616669282 0.796142469812185 0.0250865923380479 0.81329258499667 0.774598162949551 0.275544564982411 0.697627932536416 0.0550678732153028 0.809109806143679 0.794622929946054 0.54949145763414 0.389889955986291 0.706766843562946 0.106431684272829 0.699291401749942 0.766714409065898 0.810314901405945 0.381465698094107 0.0916266069747508 0.462486578118987 0.802502776584588 0.286823562972713 0.549268637939822 0.467003943792079 0.148393821089994 0.923426709594205 0.964127462247852 0.0655616324930452 0.99060910935048 0.546879039111081 0.7994891191856 0.323331237006933 0.212893906177487 0.320690806226339 0.823373276940547 0.788240166944452 0.488304777489975 0.419962075760122 0.574633205253631 0.667880190173164 0.893649704728741 0.630034771161154 0.293534388886765 0.898239138110075 0.498757961210795 0.290154126740526 0.045701378241647 0.292252174227033 0.59240480360575 0.284371659362223 0.342637276740279 0.0924047983088531 0.916727303226944 0.109721519891173 0.815671304345597 0.557354630194604 0.194270883363206 0.64535645191092 0.851487308403011 0.667959703798406 0.237686076948885 0.315027097109705 0.233369513847865 0.154087158516049 0.602245125176851 0.814300319778267 0.879938343041576 0.609281901218928 0.192232618271373 0.646310382375959 0.218313180012628 0.719713709673379 0.209429658660665 0.140838767227251 0.416627609818242 0.427749534526374 0.326524076550268 0.797372510267887 0.200439442847855 0.391322907188442 0.0893085129675455 0.0928079049452208 0.89533575971378 0.574366864182521 0.07391332202591 0.5586164560006 0.746250458359718 0.11597906526411 0.610327157631982 0.963861406308133 0.726918821111321 0.0439708340005018 0.654917972607072 0.628743365451228 0.125133316682186 0.792174614565447 0.326084490153007 0.30665972949937 0.0273220014688559 0.0242169565777294 0.646284199615475 0.754891176617239 0.799515034332871 0.353694003631827 0.111551261504646 0.711640076492913 0.926360374384094 0.765008256351575 0.0367687197844498 0.102234297334217 0.926120667397045 0.573600604801904 0.296200609421358 0.786476210237015 0.777315316202585 0.170597187611274 0.807723974459805 0.17354186718585 0.638087042076513 0.76870397224091 0.433330326650757 0.396172730531544 0.891480193219613 0.574637449032161 0.785260759196244 0.028507278370671 0.211579363795463 0.0244750691764057 0.520573667057324 0.356126328143291 0.654576871329918 0.757397768290248 0.81599861028837 0.434325902895071 0.709670305170584 0.922128695382271 0.549703364425804 0.534723622829188 0.919777553793974 0.872718051641714 0.780228461904917 0.905882286969572 0.545884797475301 0.503274604489561 0.478430833464954 0.442193516774569 0.802117409408093 0.0924651887686923 0.341266938962508 0.19395690506557 0.5375271969405 0.726604973508511 0.268717319713905 0.50459974629106 0.983204008322209 0.757601076653227 0.730840209391899 0.50812751541147 0.45491941596847 0.562461140940432 0.563820390172768 0.294705361044034 0.628695521464106 0.449335504225455 0.375680320162792 0.81326826262055 0.823971293126233 0.731161834604573 0.153087453052867 0.0972954357787967 0.48930212906329 0.960377849149518 0.384937423337251 0.447827955782413 0.992277569400612 0.64553602083819 0.434809171329252 0.773134135883301 0.507216235946398 0.205239798084367 0.682324748907704 0.793865289969835 0.212132880352437 0.702972119543701 0.295485090289731 0.336900858196896 0.365569846394938 0.927714974153787 0.0508462291327305 0.963454789582174 0.70936264678603 0.135058008562773 0.686726271712687 0.589362313360907 0.571089025519323 0.788892869118135 0.860566629504319 0.111346127332654 0.0412200951739214 0.889324523375835 0.513383048223332 0.800582670448348 0.888178179932293 0.806437703880947 0.436529222412501 0.902751373953652 0.0925998514611274 0.379293456976302 0.405559499338269 0.536539851934649 0.928934803586453 0.943116206100676 0.186090334670153 0.95113420615904 0.991762407280039 0.722801235925872 0.863336210052948 0.352838997854851 0.0514020361914299 0.190363787149545 0.52472707161447 0.606979697120842 0.762697993200272 0.937960654830094 0.178662693740334 0.223171349614859 0.173441100784112 0.149495287572499 0.808950693146326 0.897703758860007 0.086159430143889 0.727494887481444 0.34997870702995 0.0996294072479941 0.239767726038117 0.558935184490401 0.581795353821944 0.629142021087464 0.753870345614851 0.590803911858238 0.602734189131297 0.307451082977932 0.91930667209439 0.497424424975179 0.969639893372077 0.87388661504956 0.60536997667281 0.439408724224195 0.87499593636021 0.379403338592965 0.472860008953139 0.412543478589505 0.671601593703963 0.833735470324755 0.0901517781079747 0.885837918054312 0.173224001005292 0.0531751973181963 0.81421635676641 0.917981640473008 0.722216049039271 0.26651999786729 0.357097554351203 0.77503681327682 0.627111405907199 0.629252812957857 0.917266361985821 0.0372717690072022 0.398605472713243 0.0948371956590563 0.62397554515861 0.363204432332423 0.302215768217575 0.581549205447081 0.547755077995826 0.49713774806587 0.421605577017181 0.901796634655911 0.973135011605918 0.101017180914059 0.392628648760729 0.528182128772605 0.482942616371438 0.546165969758295 0.216901334295981 0.748214028247166 0.254918751155492 0.0856207150639966 0.570527980986517 0.0323425364564173 0.350160190048628 0.763325508383568 0.714939956711605 0.141794805405661 0.0182971116504632 0.350498853994068 0.777265512023587 0.648759854647797 0.549611688114237 0.710308187888004 0.957019702319521 0.491497901934199 0.295899881320074 0.518813970033079 0.0339605310163461 0.025475575865712 0.124801384327002 0.992127606885042 0.784624956301413 0.601254167968873 0.077231591490563 0.376257982992101 0.861109524283093 0.738046951403376 0.415300638058688 0.948648517359979 0.751669192588888 0.846623532753438 0.305036165311467 0.686360064581968 0.954138185456395 0.532815618757159 0.914597174886148 0.311425188756548 0.887111552034039 0.793098652104381 0.947887218850665 0.29942529885564 0.525000328216702 0.939277137350291 0.361639506786596 0.921141597474925 0.749223911541048 0.744310730020516 0.734272459265776 0.133599370641168 0.476190197232645 0.147812728616409 0.476992844634224 0.184437558690552 0.0814860579534434 0.652559208997991 0.0229153333907016 0.439397733872756 0.373060142931063 0.685418219123967 0.759057934405282 0.356299877502024 0.0255824249936268 0.90614087209804 0.353445913505275 0.32647311755456 0.605762641092297 0.46125675018644 0.655560360492673 0.75299443327589 0.247494648206048 0.293088870742358 0.920048021548428 0.218046596683562 0.68305489364313 0.975182605588343 0.80611607037019 0.581098960391246 0.221086936802603 0.8170758180134 0.831147861459758 0.146473250261042 0.174971522896085 0.0810433533205651 0.469798823355231 0.407023261557333 0.732208960622083 0.585450805332512 0.156645063466858 0.625869934379589 0.448452275742311 0.313487355788238 0.164305461968761 0.163284223668743 0.359664954384789 0.824008205540013 0.565475058576558 0.187725485749543 0.837732145739719 0.399256251575425 0.722849305113778 0.68877395927906 0.564164467696101 0.590612585928757 0.841745557237882 0.361027932683937 0.0641189865930937 0.814842101922259 0.0632225397229195 0.466612035881262 0.892544155819342 0.258113899871241 0.685541955544613 0.365009446116164 0.215166536134202 0.51058274747571 0.267719617085531 0.193393122164998 0.33489641540451 0.270671036087442 0.654773870613426 0.278763283253647 0.13010807137005 0.785639730624389 0.931957558912691 0.0559174100938253 0.225343741711695 0.0831192873348482 0.973604896382894 0.842938763420098 0.405083908706438 0.0644968151906505 0.906568693195004 0.859053456112742 0.975492026854772 0.645379195576534 0.571644608068746 0.449205988419708 0.802529914316256 0.846534378828947 0.164356044093147 0.424367644342128 0.515186840344686 0.913377862239722 0.971246336768381 0.526636112486012 0.856634883370716 0.274912315281108 0.409886487368494 0.560468538822606 0.654851377254818 0.356366366823204 0.325892300531268 0.578242117189802 0.257628496754915 0.129386191295926 0.854336776912678 0.91049107540166 0.949577678043861 0.183207199911121 0.16419417129131 0.788059019076172 0.39688621801557 0.346536433531437 0.8241888610553 0.198934823398013 0.610428727564868 0.447402210128494 0.702342118392698 0.577286472709384 0.53417442565551 0.457724080125336 0.153524640842807 0.17347160753794 0.179146378231235 0.1866667191335 0.427467311613727 0.285679600387812 0.710023181198631 0.521279167635366 0.583660785725806 0.228059132543858 0.834833648230415 0.413900468437932 0.8995495383651 0.771620259459596 0.913300348913763 0.53949924262939 0.883471608951222 0.658199889548123 0.508603657865897 0.810024199003819 0.348211204044055 0.667935492524412 0.365266339818481 0.373882180419751 0.900346957282163 0.67774313139962 0.354436931335367 0.113901629296597 0.546736413254403 0.700604372797534 0.995462935827673 0.782270617645699 0.312253594333306 0.153689585088287 0.462213441608474 0.341670107143 0.896742081902921 0.914248520277906 0.46582056899555 0.400057764905505 0.659836265977938 0.837178784080315 0.26377737871604 0.708421516115777 0.525884666799102 0.120784131968394 0.81800437109312 0.142929456157144 0.620293809236027 0.290958108289633 0.171783279569354 0.973647612154018 0.0918751620245166 0.908281810767949 0.945604336149991 0.0404349855426699 0.928822227397468 0.960197107426357 0.990347131688613 0.262536707031541 0.366112023389433 0.844994897053111 0.891235865582712 0.505205398097169 0.856187041993253 0.52102263697423 0.569226411737036 0.416741167255677 0.583031155453063 0.814335354520008 0.604467430249788 0.71521260709269 0.118963409450371 0.43639146937523 0.0320820616697893 0.414570328283589 0.120529319010675 0.593790638286155 0.231084674873855 0.224214534503408 0.241639627681579 0.93634154325584 0.295207933587953 0.241481612566859 0.563675729210954 0.794826420175377 0.412323394727428 0.510808121827431 0.740417875163257 0.0208417039387859 0.492400952004828 0.153151352910791 0.886121245764662 0.725383306972217 0.508644812675193 0.423007975595538 0.401117534667719 0.0571925780666061 0.924681991208345 0.365102829758544 0.88659940327052 0.09236230451148 0.600423409654759 0.345095123853534 0.981457821270451 0.192820044257678 0.599098179801367 0.545064510882366 0.255938809514046 0.84400831039995 0.352561704926193 0.213189042753074 0.867995377997868 0.358612738184165 0.0372693113912828 0.521564718079753 0.770274955618661 0.434408014051151 0.5172808056348 0.585997582231648 0.168861642160919 0.499537130335812 0.340233026260976 0.253823559638113 0.531765612382442 0.903368001128547 0.809564561899751 0.651899810731411 0.7809201692231 0.0167426884826273 0.316873712416273 0.429486614661291 0.257227026454639 0.723468903924804 0.631645365674049 0.685428343939129 0.19689822898712 0.598679852865171 0.833783133598045 0.82526437551016 0.142337352817412 0.92316137397429 0.627358326695394 0.0992260952340439 0.720698275743052 0.922562232937198 0.900411838388536 0.733894422985613 0.228358170141 0.15608475147048 0.643645097680856 0.462365427934565 0.38320473058382 0.547145852481481 0.270286235485692 0.910906231317203 0.0758877949044108 0.72510400429368 0.683522606627084 0.543650439665653 0.0781070575769991 0.298458722340874 0.727611961462535 0.313946716520004 0.812620773948729 0.0254659293428995 0.239637178734411 0.867136646842118 0.960670212320983 0.694925561859272 0.694218268895056 0.231981104917359 0.561635709074326 0.880786986723542 0.968570136635099 0.432206716961227 0.331138379059266 0.750050755694974 0.543029865368735 0.523454795754515 0.485112021849491 0.417393301702105 0.850753642513882 0.846462926561944 0.616082129769493 0.376642419630662 0.747350256005302 0.0969361294270493 0.275683196003083 0.733997330523562 0.435074458082672 0.908547971586231 0.498439573172946 0.446097316574305 0.119942488411907 0.906138824084774 0.540154734342359 0.942682948606089 0.244259966956452 0.800270251038019 0.0880225846846588 0.28420061210636 0.516731011690572 0.316643189333845 0.290776186394505 0.339647879481781 0.501216729641892 0.38330899531953 0.349253321476281 0.0601010125316679 0.775138350939378 0.767565852659754 0.396991002764553 0.33038726022467 0.0802521489770152 0.825404004144948 0.0376512950239703 0.405317515679635 0.942467632915359 0.544647969878279 0.908695475794375 0.36146940205479 0.0124444463988766 0.108914364785887 0.172046845853329 0.987236982784234 0.679319920439739 0.584378787137102 0.232277522163931 0.790846109504346 0.141425972392317 0.175760470160749 0.154310289849527 0.811277980739251 0.632600612076931 0.0249530314467847 0.0502148235309869 0.40640012453543 0.345623425298836 0.599431239543483 0.9877949759271 0.0949986687698401 0.605639776892494 0.846529343735892 0.114487552868668 0.833425870188512 0.126351067214273 0.554686943434645 0.822036764919758 0.685223461014684 0.369375428918283 0.159582376417238 0.36569993476849 0.410607684694696 0.988360508570913 0.0349267350393347 0.434950522508007 0.880196177423932 0.109311649624724 0.779076804921497 0.967847024064977 0.926840608716011 0.468298451371957 0.185417008760851 0.810055190504063 0.574056084104814 0.0648812905536033 0.166496378385928 0.580232356428169 0.709987908578478 0.665587691145483 0.690409112893976 0.278285184756387 0.668987431200221 0.103591047690716 0.947600088543259 0.114647557218559 0.856557302046567 0.96827608480351 0.255938566795085 0.466120527680032 0.430044946181588 0.108079000343569 0.553014506758191 0.782399232187308 0.667169654041063 0.310829702334013 0.542865310902707 0.928464131643996 0.908676761079114 0.401934365108609 0.39348890584195 0.905487737962976 0.144536093866918 0.764172811694443 0.708475257735699 0.570614489435684 0.165564881330356 0.865477536658291 0.5157525702985 0.434174909342546 0.445771586115006 0.052103697983548 0.497249307278544 0.374786187536083 leidenbase/tests/cpp_tests/leidenalg_refs.py0000755000176200001440000007177614451636360021065 0ustar liggesusers#!/usr/bin/env python3 import sys import platform import leidenalg import igraph as ig def read_edge_weights(weights_file): fp = open(weights_file, 'r') w = fp.read().splitlines() fp.close() v = [0] * len(w) for i in range(len(w)): v[i] = float(w[i]) return(v) def read_initial_memberships(membership_file): fp = open(membership_file, 'r') w = fp.read().splitlines() fp.close() m = [0] * len(w) for i in range(len(w)): m[i] = int(w[i]) return(m) def get_partition_type(partition_type_name): if(partition_type_name == 'CPMVertexPartition'): partition_type = leidenalg.CPMVertexPartition elif(partition_type_name == 'RBConfigurationVertexPartition'): partition_type = leidenalg.RBConfigurationVertexPartition elif(partition_type_name == 'RBERVertexPartition'): partition_type = leidenalg.RBERVertexPartition elif(partition_type_name == 'SignificanceVertexPartition'): partition_type = leidenalg.SignificanceVertexPartition elif(partition_type_name == 'SurpriseVertexPartition'): partition_type = leidenalg.SurpriseVertexPartition elif(partition_type_name == 'ModularityVertexPartition'): partition_type = leidenalg.ModularityVertexPartition else: print('Error: get_partition_type: unknown partition type: %s' % (partition_type_name)) return(partition_type) def print_comm_info(partition_type_name, part): print('python version info: %s' % (platform.python_version())) print('igraph version: %s' % (ig.__version__ )) print('leidenalg version: %s' % (leidenalg.version)) print() print('==== partition type: %s' % (partition_type_name)) print() print(part) ncomm = len(part) print() print('Quality: %.0f ' % (part.quality())) print('Significance: %.0f ' % (leidenalg.SignificanceVertexPartition.FromPartition(part).quality())) print('Total weight in all communities: %.0f' % (part.total_weight_in_all_comms())) print('Apparently the total weight in all communities is the sum of the edge') print('weights in communities.') print() print('Edge weight within community') for i in range(ncomm): print('%.0f' % part.total_weight_in_comm(i), end=' ') print() print() print('Edge weight from community') for i in range(ncomm): print('%.0f' % part.total_weight_from_comm(i), end=' ') print() print() print('Edge weight to community') for i in range(ncomm): print('%.0f' % part.total_weight_to_comm(i), end=' ') print() def write_comm_file(edgelist_file=None, weights_file=None, membership_file=None, partition_type_name=None, directed=None, resolution_parameter=None, n_iterations=None, seed=None, part=None, outname_root=None): fp = open(outname_root, 'w+') n_node = len(part.membership) n_comm = len(part) print('python_version <- \'%s\'' % (platform.python_version()), file=fp) print('igraph_version <- \'%s\'' % (ig.__version__), file=fp) print('leidenalg_version <- \'%s\'' % (leidenalg.version), file=fp) print(file=fp) print('leidenalg_edgelist_file <- \'%s\'' % (edgelist_file), file=fp) print('leidenalg_weights_file <- \'%s\'' % (weights_file if(weights_file != None) else 'NULL'), file=fp) print('leidenalg_membership_file <- \'%s\'' % (membership_file if(membership_file != None) else 'NULL'), file=fp) print(file=fp) print('leidenalg_graph_directed <- %s' % ('TRUE' if(directed == True) else 'FALSE'), file=fp) print('leidenalg_partition_type <- \'%s\'' % (partition_type_name), file=fp) print('leidenalg_resolution_parameter <- %f' % (resolution_parameter), file=fp) print('leidenalg_n_iterations <- %d' % (n_iterations), file=fp) print('leidenalg_seed <- %d' % (seed), file=fp) print(file=fp) print('leidenalg_n_node <- %d' % (n_node), file=fp) print('leidenalg_n_comm <- %d' % (n_comm), file=fp) print('leidenalg_quality <- %.2f' % (part.quality()), file=fp) print('leidenalg_modularity <- %.4f' % (part.modularity), file=fp) print('leidenalg_significance <- %.2f' % (leidenalg.SignificanceVertexPartition.FromPartition(part).quality()), file=fp) print('leidenalg_tot_weight_in_all_comms <- %.2f' % (part.total_weight_in_all_comms()), file=fp) print(file=fp) print('leidenalg_membership <- c(', file=fp) for i in range(n_node-1): print('%d, ' % (part.membership[i]+1), end='', file=fp) if((i+1) % 25 == 0): print(file=fp) print('%d)' % (part.membership[n_node-1]+1), file=fp) print(file=fp) print('leidenalg_edge_weight_in_comm <- c(', end='', file=fp) for i in range(n_comm-1): print('%.0f, ' % (part.total_weight_in_comm(i)), end='', file=fp) print('%.0f)' % (part.total_weight_in_comm(n_comm-1)), file=fp) print(file=fp) print('leidenalg_edge_weight_from_comm <- c(', end='', file=fp) for i in range(n_comm-1): print('%.0f, ' % (part.total_weight_from_comm(i)), end='', file=fp) print('%.0f)' % (part.total_weight_from_comm(n_comm-1)), file=fp) print(file=fp) print('leidenalg_edge_weight_from_comm <- c(', end='', file=fp) for i in range(n_comm-1): print('%.0f, ' % (part.total_weight_from_comm(i)), end='', file=fp) print('%.0f)' % (part.total_weight_from_comm(n_comm-1)), file=fp) print(file=fp) fp.close() def write_call_leidenbase(fp): print('run_leidenbase <- function(part) {', file=fp) print(' library(igraph)', file=fp) print(' library(leidenbase)', file=fp) print(' graph <- read_graph(part$edgelist_file, format=\'edgelist\', directed=part$graph_directed)', file=fp) print(' if(!is.null(part$membership_file))', file=fp) print(' initial_membership <- as.numeric(read.table(part$membership_file)$V1)', file=fp) print(' else', file=fp) print(' initial_membership <- NULL', file=fp) print(' if(!is.null(part$weights_file))', file=fp) print(' edge_weights <- as.numeric(read.table(part$weights_file)$V1)', file=fp) print(' else', file=fp) print(' edge_weights <- NULL', file=fp) print(' comm <- leiden_find_partition(graph, partition_type=part$partition_type, initial_membership=initial_membership, edge_weights=edge_weights, seed=part$seed, resolution_parameter=part$resolution_parameter, num_iter=part$n_iterations)', file=fp) print('}', file=fp) print(file=fp) def write_cmp_comms(fp): print('cmp_comms <- function(leidenalg_part) {', file=fp) print(' leidenbase_part <- run_leidenbase(leidenalg_part)', file=fp) print(' message(\'Test if community attributes are the same\')', file=fp) print(' message(\' comm memberships: \', setequal(leidenbase_part$membership, leidenalg_part$membership))', file=fp) print(' message(\' compare comm edge weight in community: \', setequal(round(leidenbase_part$edge_weight_within_community), leidenalg_part$edge_weight_in_comm))', file=fp) print(' message(\' compare comm edge weight from community: \', setequal(round(leidenbase_part$edge_weight_from_community), leidenalg_part$edge_weight_from_comm))', file=fp) print(' message(\' compare comm edge weight to community: \', setequal(round(leidenbase_part$edge_weight_to_community), leidenalg_part$edge_weight_to_comm))', file=fp) print(' message(\'Quality values: leidenalg: \', leidenalg_part$quality, \' leidenbase: \', leidenbase_part$quality)', file=fp) # the significance is defined only for unweighted graphs according to leidenalg print(' if(is.null(leidenalg_part$weights_file))', file=fp) print(' message(\'Significance values: leidenalg: \', leidenalg_part$significance, \' leidenbase: \', leidenbase_part$significance)', file=fp) print(' message(\'Modularity values: leidenalg: \', leidenalg_part$modularity, \' leidenbase: \', leidenbase_part$modularity)', file=fp) print('}', file=fp) def write_comm_file_as_list(edgelist_file=None, weights_file=None, membership_file=None, partition_type_name=None, directed=None, resolution_parameter=None, n_iterations=None, seed=None, part=None, outname_root=None): fnam = outname_root + '.R' fp = open(fnam, 'w+') n_node = len(part.membership) n_comm = len(part) print('# In R, source this file and run \'cmp_comms(leidenalg_part)\'', file=fp) print('#', file=fp) print('leidenalg_part <- list(', file=fp) print('python_version=\'%s\',' % (platform.python_version()), file=fp) print('igraph_version=\'%s\',' % (ig.__version__), file=fp) print('version=\'%s\',' % (leidenalg.version), file=fp) print('edgelist_file=\'%s\',' % (edgelist_file), file=fp) if(weights_file != None): print('weights_file=\'%s\',' % (weights_file if(weights_file != None) else 'NULL'), file=fp) else: print('weights_file=NULL,', file=fp) if(membership_file != None): print('membership_file=\'%s\',' % (membership_file if(membership_file != None) else 'NULL'), file=fp) else: print('membership_file=NULL,', file=fp) print('graph_directed=%s,' % ('TRUE' if(directed == True) else 'FALSE'), file=fp) print('partition_type=\'%s\',' % (partition_type_name), file=fp) print('resolution_parameter=%f,' % (resolution_parameter), file=fp) print('n_iterations=%d,' % (n_iterations), file=fp) print('seed=%d,' % (seed), file=fp) print('n_node=%d,' % (n_node), file=fp) print('n_comm=%d,' % (n_comm), file=fp) print('quality=%.2f,' % (part.quality()), file=fp) print('modularity=%.4f,' % (part.modularity), file=fp) print('significance=%.2f,' % (leidenalg.SignificanceVertexPartition.FromPartition(part).quality()), file=fp) print('tot_weight_in_all_comms=%.2f,' % (part.total_weight_in_all_comms()), file=fp) print('membership=c(', file=fp) for i in range(n_node-1): print('%d, ' % (part.membership[i]+1), end='', file=fp) print('%d),' % (part.membership[n_node-1]+1), file=fp) print('edge_weight_in_comm=c(', end='', file=fp) for i in range(n_comm-1): print('%.0f, ' % (part.total_weight_in_comm(i)), end='', file=fp) print('%.0f),' % (part.total_weight_in_comm(n_comm-1)), file=fp) print('edge_weight_from_comm=c(', end='', file=fp) for i in range(n_comm-1): print('%.0f, ' % (part.total_weight_from_comm(i)), end='', file=fp) print('%.0f),' % (part.total_weight_from_comm(n_comm-1)), file=fp) print('edge_weight_to_comm=c(', end='', file=fp) for i in range(n_comm-1): print('%.0f, ' % (part.total_weight_to_comm(i)), end='', file=fp) print('%.0f)' % (part.total_weight_to_comm(n_comm-1)), file=fp) print(')', file=fp) print(file=fp) write_call_leidenbase(fp) write_cmp_comms(fp) fp.close() def make_ref(edgelist_file=None, weights_file=None, membership_file=None, directed=False, partition_type_name=None, resolution_parameter=0.5, n_iterations=2, seed=2016, outname_root=None): graph = ig.read(filename=edgelist_file, format='edgelist', directed=directed) if(weights_file != None): edge_wghts = read_edge_weights(weights_file) else: edge_wghts = None if(membership_file != None): init_members = read_initial_memberships(membership_file) else: init_members = None partition_type = get_partition_type(partition_type_name) # part = leidenalg.find_partition(graph, partition_type=partition_type, initial_membership=init_members, weights=edge_wghts, n_iterations=n_iterations, resolution_parameter=resolution_parameter, seed=seed) if(partition_type_name != 'SignificanceVertexPartition' and partition_type_name != 'SurpriseVertexPartition' and partition_type_name != 'ModularityVertexPartition'): part = leidenalg.find_partition(graph, partition_type=partition_type, initial_membership=init_members, weights=edge_wghts, n_iterations=n_iterations, resolution_parameter=resolution_parameter, seed=seed) elif(partition_type_name == 'SignificanceVertexPartition'): part = leidenalg.find_partition(graph, partition_type=partition_type, initial_membership=init_members, n_iterations=n_iterations, seed=seed) else: part = leidenalg.find_partition(graph, partition_type=partition_type, initial_membership=init_members, weights=edge_wghts, n_iterations=n_iterations, seed=seed) # print_comm_info(partition_type_name, part) write_comm_file_as_list(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, partition_type_name=partition_type_name, directed=directed, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, part=part, outname_root=outname_root) # weights_file = 'edge_weights.txt' # membership_file = 'initial_memberships.txt' # edgelist_file = 'edgelist.edg' # weights_file = None # membership_file = None # directed = False # partition_type_name = 'ModularityVertexPartition' # resolution_parameter = 0.5 # n_iterations = 2 # seed = 2016 # outname_root = 'foo' # make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) ## top #test_start test_name = 'test_1_1' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_1_1' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_1_2' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_1_2' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_1_3' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_1_3' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_1_4' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_1_4' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_1_5' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_1_5' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_1_6' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_1_6' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_2_1' edgelist_file = 'edgelist.edg' weights_file:'edge_weights.txt' membership_file:'initial_memberships.txt' directed = False partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_2_1' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_2_2' edgelist_file = 'edgelist.edg' weights_file:'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_2_2' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_2_3' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_2_3' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_2_4' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_2_4' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_2_5' edgelist_file = 'edgelist.edg' weights_file = None membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_2_5' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_2_6' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = False partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_2_6' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_3_1' edgelist_file = 'edgelist.edg' weights_file:'edge_weights.txt' membership_file:'initial_memberships.txt' directed = True partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_3_1' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_3_2' edgelist_file = 'edgelist.edg' weights_file:'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_3_2' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_3_3' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_3_3' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_3_4' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_3_4' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_3_5' edgelist_file = 'edgelist.edg' weights_file = None membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_3_5' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_3_6' edgelist_file = 'edgelist.edg' weights_file = 'edge_weights.txt' membership_file = 'initial_memberships.txt' directed = True partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.5 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_3_6' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_4_1' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_4_1' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_4_2' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_4_2' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_4_3' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_4_3' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_4_4' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_4_4' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_4_5' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_4_5' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_4_6' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.1 n_iterations = 2 seed = 2016 outname_root = 'tests_out/test_4_6' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_5_1' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'CPMVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'tests_out/test_5_1' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_5_2' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'ModularityVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'tests_out/test_5_2' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_5_3' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBConfigurationVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'tests_out/test_5_3' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_5_4' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'RBERVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'tests_out/test_5_4' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_5_5' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SignificanceVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'tests_out/test_5_5' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) #test_start test_name = 'test_5_6' edgelist_file = 'edgelist.edg' weights_file = None membership_file = None directed = False partition_type_name = 'SurpriseVertexPartition' resolution_parameter = 0.1 n_iterations = 3 seed = 2016 outname_root = 'tests_out/test_5_6' #test_end make_ref(edgelist_file=edgelist_file, weights_file=weights_file, membership_file=membership_file, directed=directed, partition_type_name=partition_type_name, resolution_parameter=resolution_parameter, n_iterations=n_iterations, seed=seed, outname_root=outname_root) ## bottom leidenbase/tests/cpp_tests/Makefile0000644000176200001440000000110614532173045017155 0ustar liggesusersCXX= c++ CXXFLAGS= -g -I/usr/local/include -I. -I/usr/local/include/igraph -std=c++11 CXXLIB= -L/usr/local/lib -ligraph -lm OBJ01= leiden.o leidenFindPartition.o \ CPMVertexPartition.o \ LinearResolutionParameterVertexPartition.o \ ModularityVertexPartition.o \ MutableVertexPartition.o \ RBConfigurationVertexPartition.o \ ResolutionParameterVertexPartition.o \ RBERVertexPartition.o \ SignificanceVertexPartition.o \ SurpriseVertexPartition.o \ GraphHelper.o Optimiser.o all: leiden leiden: $(OBJ01) $(CXX) $(CXXFLAGS) -o $@ $(OBJ01) $(CXXLIB) clean: rm -f $(OBJ01) leiden leidenbase/tests/cpp_tests/igraph_edgelist.txt.gz0000644000176200001440000203216214444624071022041 0ustar liggesusersC`]igraph_edgelist.txtDɁ-+CߊgB2ՑzQWJf$߿y~?w~ڷ~}|y|MwUT:kß|P LNJ̫ŝoQoj 8j:OsC[d  '9oϯP÷<0*uﯸ+lw-%< t `iqs>BXEn{aRw;ݕ ,+XPޖ="}~6 ~?y6OWoO%D_~-!~ gu~/o*_Vm\O\HryW!c1-(7FȱH~f_ V~}ZbSѻF45Os-((`WV3Y|m]k7O7{rr~~Czw(pyK:7 4)g@o# ^)e.le#pT>(oI} ߯Q9}8|\/ _KEt?W*`q#p*Îs~2M!R4$T_&oY_鈰A$￟uJw/ߥߟ$"6"~~&9?n(קr]qPW%M!/y_yuzZ|i \_G?4,RaZ4sڏuk[dZN"gGYsxӎ6gnۓ8Z͵ƣ5z{2g @@sXBB ฾@lϭ__Q/=:W} 5Wǯϯuju߭)Ujꇇ~_@*ݡ7J%}Co<J e ^&8Dv{ ,;>~uܡ;q:P='swq9;}G@;Hq?q-q1wqbosh ހ[}rpЀ8pGD}%~$v4)i8*Olpp\&~y̏ cBLU;~Y~~5~59{=bIK?o*?R&`^េh"~%%f@3P'oM~/'}l_P?>C}O_:~|D};ˇ\IG՗*aoY_|h}#W֗Ϭ/Y_>|i}c֗/Z kok{3LF/8 D56:F@ҚDv7"C~r}m8dljݏ Mw\1~5RGL;,F>yTO7^Iwlt5~hNDV⯔{={pMZ jCdc-nKf%שǯs|. Ӆ~s[cwCw_An>][`tLn|ׯ4vWWӧ:>M\Y*?K:KH}!vt_?]BIABH]_@I{:1H`>-2^J9+F ]FCBI*L96:߄ f<><[;-|,@ RteM.uyG]Qwu9Kk2[]ޭ @Znx. GJwGݣQv,pQzI7+:AVJ%-Dݣ䦮tQj(n_,5LZF*AydiGH>'pR@ 9,gY4 V3P4&Bu V3|w}zztatYAjοh_/*ݟ~o*kix{8j"$8~:ĖjvvV*u P0T(Ə*nO3@sυN/ey>#xNy~ri%2gveٶp+1/݋kSpRf^W kw)5@#nx#:zx>YtFu.t<كNQ?F#w)}@78JcOGzs:=D<[~(}gz&p~+/%PGtQ`ݖJx1.^#`@, ?fKtMg^~[x)巟: :R*t3W[v*z3t/Oڳ Xd , ^+ҕW'VΕY+=<+Ta 4 7?e%+'rnWƯZYbnn\^jW^q՛۱_y墧s2hyuStdWʬoU*c-ׯf]_z}߼7+zƲpQ~Soo7zM6' 5>yoo~|e2߬ߨߝF[v;w;?~N9`g3ؙ]/w-;s)Ŀi\Zw<=[?s9a{t=Wؙ+@sag3wZ.: nvrиܥ)ׯ;|֯lRnGU0ػ :sO2`(/;\cri"!W%qRm_w, e@m|~~bNNptu,2}ns<6ѡvtؖ;;sf$wU‡%8 e[QH +@m?Ԓ`u>GĶp?xp]9(`g\|Zs!a&^*xS9ll^Dm%S(NI8gM :]4((n_?~tkw__ݧijX.o| tWx7U{2n&S%0:X!3EZ~EGv]ZBH-= Z "pyBU !hMGJZP,Bn;$"w C)kG\Nf!jxmh w&dkh 76k-t0ٵ`-hA.oX^5 H_mN2hpTXn2 Db?cL /FR ~28r+w ]2Q%p\$}ia\u\}A3ܜ]c^ۜm~5nTE(;`5~#ivێFO[i{0X ~+)`3xbR^Wp۴ΘaZar^7\$LM10g_-$,q_KcLIw_% 2QFR<,O6s"TEAsW8* pWpw)vzj*ug+;R]|S^ uR0F Qj`6=:/G^=ApV­GGVr}Uy~:w>GpQRpq. g~) µ~ 퓠sF8s.̉viNW!z3.#.kIF $ꀖ۠݃qOB+ZD-s <NkZMS<]F`քK9|}^VƟ(ߋ]#xY?Hpa;MGs6K*瑹\G}~)`{.B |.Z\Z]F'M#fՒJzhK9ۅ% ضqyM>n&UgEӉty|I֏z,ZN>8j}~r" /~3i-jg5i{VQ &\{#~ ۽ t46ru> L]ktx}B[ƕh%jY&6x7u:?o?6~Y2/=p+鬤C}IW*9o T|W/@&PFlQ8A)!~ Zf Nɯ F?KQh$ۈ{o:xw~2\yN~2|(Fqz.7O_N{nvDLӮJ!V\iknNOd@ >rJ,*d#Dg@ XN3ZAtGe$PH7&60mWN`MI&q\&o%e!4%, t 1^ǻ-8*P_epֳٵ. {wy:HLTJr//|eZ>]匉񥇛<.r>itr&gtՔ-)! @j)CQ3Rl_$IMtN2q L_Y6=D:95@(e4)]IySudx"rj) vF':}ܲxM̂H>7ׂgi3^wόAWhto}Yq >N19ހ n3g͓/e!\E~lc].7̳#ӯ^/#;ŁK0! s/ *YIU?'3$!:Ǒs!}^6`늬I4Ohay+6SOgRo{Q0?Uh غ" F60cAK^WO[qz>obw97^&~O꾠cu_HB8\ƊB@c!A(c^Љptゅ}ᲟJe2>BԎގ0al7Ef]vpej;a3^gIY(<Fi^,+|n2>#?;oX欗.'堛rξ)p;r9Y77:}}E.4q}$>B!gtf!5Z(y?TT 6²Tӈ(FD?FÆi$ ğ #PGxȖy%! p`57k$wFD>ĝ)<[|1n*ݠ5+ | -gd-oFHB+ֶ+ֶ+ֶ+ֶ+ֶ+ֶ+ֶ+ֶ+ֶ+V+V+V+Vyw-|FI+bubu `:]Z[BW5#k9:}]4vP<һN2NAd(pܸ9$OαxH'8~^A'1Ukǃ3i)}[=Ek0 3|PiT7 03< 0#3");p9eƙqfxDcx6Ucp #ë `"7&]BaڟaedXVFaedXNWcTp12\ 1k6Ȱk=I`xlyvCxXF`d|rʅKkwW]a+Lw7t=bGL1#{t=bGLuN9\=bGL1fzLO G23=bG1#fzL3=bG1#fzLy􌙞13fzLϘ3=cG1#fzL3=a'􄙞 ~%;e_ l&I2*5?\:2 _1޲Wx ,g[M'Z\i`# 8.v$lzf#f{;# g`hi.14 Xl=p`җJ<=xE]a9rKx3jN|v]90]]_*k:N҉ug >ٮݻ`ߋd`/gr]^n7]g73]k+ty{.=0 t{~^z qtF1~Lhx+%`d;M'>6w4v+dm{7&]/.:x_c=%t@]B7|wsB?Ӓ=$? uGpl[g|{:kھTl*oi_ٍ Կ8V :Dz8ea Ry+$6(I 4\p qȺd0N„ȀsTj>Wo۝9`!=N+1wvAa&Ψ/p;+-} QBdj֩ KPXGpE{gǓ {5"xl8^tNYԲXmKg]u8MW.}-F 4uղ071Spy`݄hd+[<PqOxH1Mebb 9 $҂H+ <tm--|w굓Lw#Z1i#GiqK_΋ފYA*~@/m}7Z_zg%:.hA>ry%_; t{YuH(lQVpp9KWz>>,Bʺ  tp²3:qH^, "ᆓn#u? \vD+'.w#/4L\,G^(7$3t.Jו2 #x]v;ωN݈poKկFj⫽C@,Y?6GDӲisr;p>hsXcN9?mӥeF7yUo 9QH' -<߸/+–y+8>Sz 82fθ`;_;Eoғ}r.V uo+p/vzRkt3l[/[hsu~}܍MyI_sOkK^@m8~7NyoxуyAU$B>!햆^jTd9o0:rqgԡY6>ttկ 20n- ~CUsvGYtcLap!%5tIJV,־'n}ؖk \`70ވk-S] 7`=6ui`FǗ~'O#澩K튻{t_js Fϩ<^g4:#;7@u_t̄~/0 j;2( w ֨:rKmFljz`Zehqc`ZpIIJ@,Ri O$ˢ3Yl]2/W0v<>Lr~N ܂G#hxY{[э_-hS?_^('Mn}nd0k'[àtKii?+8[lYsS3Lhn/!uPZkVXawm[O=z\A?Dg}o#&ˢY0M7FwuzN#}pl2u)GOZyv{۵vsݵ׿C7w2`/J[ (X$ťJᨅbw !;Ta*_0.gwܳM[_t+yеc[q##;J]^)vl p9 s= 1`O$<ɐHp "S!iw dW x^{gWC} Πkz2(BJcH_xӸ|VZefd]x n 3:OP։A7&`1oOsc@~ UqQ xuIӱDeK0ֺ*i%88j+6 ?VLWt¬x u Wp_}Ьh]*Vy~%`sp+]m6:0)/\+at:Z ,et#|"%Z\ÎpU lA7:=2Imߧ_udL_}}=|p')2%pqr@lm ُ*aG{=)Wɓ)hau?VwN5Ɲ{Ng8ZpS.&k&2ڝoo| >jȥ;'ۂvw!Vs4q- 3?}_93iNWkxl6އ$5}Gyhv3ql&A8T9mGg$s3ol!M}[ ]C}xۈ \}*NWTh9xhhew:#cl;S #sBCsbd~bd~bd>Stel~bl~bl~b\~b\v> {_]mq2ΠK?Cˠ;''G䤐cccsp8}Mp\SӞ)EaG PMش+PҲ*' MG ҧr&Q+gGx9hJ9?"ᮾaDiȷ-mV9Q?}h%\ӱ,OSj?ߢ]Q1nf>dtϸ=5󢞟Ӂ)GX:Tt+._6qp_#;ckM\j` ,?=F4@'f g4>HaGi̔2 T|:Iˢ] )=*l֚Smҏ/LE~g &Nz5b.:po5}k׵8{d]祀tfѺ<p3q4UUӹL0VݎCgmMH-qIIJ*ӛRHK2=Qv4uLgCAGkBcm3 "“t3-jڠle?EН_?s>I~Y"WJHMP*}n>?PH'}i'N%+P_!A- .9H_wg0<>, -T7ڝ(*޷۝Fly<,l,6Ƀ0:<_1v˨3_-P1781t3n\|e@ÏQs{ܬ)`=oۣ=jn=jnۣ=jnG?RN|=xn/e3 ;Π3 ;`3X #gg^w܏4w͝As{ywK?At\4:|w5ζdg/hwT#7E{p'kx- Ѡ˅I]S%+i]UPwkCO?]CiPZ*JTAbR-pkQQ˅E|Z]WLw kϟAd+\}:*xx498iGm7]AL#N5 +-cFG*Kp[+,3t ] p%F*Kk]GqWey|=>8fBGcO0$Ɵ^;ϋ~&Cyq\ΟE!r鳘Nku߇"8~{^;/pcx|Sav}G4eL9V'e;[2MI &u'`tNS@w=8rc0/d6]\+U=&bPaGmlk{GmK4 Gd,y'wl l\=%]/&s=RavŁ)2wfûx> ׶B`Pیv_o[ng :r L}ˮ70刀vs#wvVOSn ]n+=n6:R k|\!\@׃<@7@ח =OWc l(@ ݰu1SPt.G Ik=GւFlh%VȈ%^kfLA:[\1PDteJ}LsNrr3=w+~8txk L~+N=ټ֯^ h ``iC84>1\`Qf.N8Fazy|^%DcqREҁQ;qy<5tX0ʟ vex]>P. es|NZ$(&>äp9xn1:43|]=u?@^e`t/@!pzK_F3WJw@lOJ 1.on:8aP>=Z!8.\'8@VQ\DS|Rc|gF4zbt6*^gt AX=ZM7M{5wvuuÕɏUCVyv}883nzse_q7捇yax.Óp &=扜bxx|:!y.4=O<O'w2;n |nX]#?N/-XFLdt8Ҁ2lM.`-@vD>'e)=su gzJtz/; 3|$5ϡnɷwחt]˵$8Fc&Yr 'ϖF狼E/To@o{(qI-?BdBz 0LOF~CSWd'5HW`vt-ƪGtY Ϲ?Ӊl]9ۍ[Y^9q2uꎷ /&x>_lnw}o]>Nb{DkF5! wI7뗪I Wůhuf:[KkD\pxa{Btk7 F2gΎd+6 =DIgV,t{R=-Rg #red8_ poh8P{x & ?W~~ۉI+78)2]_ox)A k͸6}p.5' ZJ~9Q<*$m}Y7m {~ 'aYg/W=qrfC<[P8%?Y{{u( hk9 @BDk)߅Z:{X yԳS|dt*e) ۘs>&5NGKbBZp\|x,J-8-C_$-Dž&orLCzJtMޏ i'G '} )y:ׁxz2>Jval(uF $4U6\0#4^׽Y M&]N6ӕ9̅.' x"TF֗z`PNݥ4YruOmspx$=3KK-~d O៝)q^/M'tM'vmmv77 mwƂ}6 $:NG ;bCtOo30^;`{|/`{o&=: zCt~p[%#;`wzawv{_߫_uI_ARI9䇓6q4gKb˜ mG- gQi=s's3]+5 Ԩ[j8zp"買ǧ#"C+2׺u^5}NlTDpo #:Ȋf;6𒮌;vlatʲ 줇;6]/NGy<dgoDΑp:-es׻M8_i%Vvg&F%]]|#;sBr}b:Н]&wӍm'm O]׵'n(MK(Ow7Sn_(6Elw=)I9d[$dJ~m޵-)Ox wMwx9[X(3_~x;tv9SLa0PNp;}M:߯Y|jᇖ jS75` x ihAgWGiU~shy8qN믤hs_ &_mgly@}ʾheAC-LnL|>+-/Z|K_G]-t{ѲhWx%ѶsvG|oċEuu?r8h]_/m.+`/ߗˁ BKgNg%N9NOolN0j{oDpV=ZH%K&7RW1fZvBLqd$̬W+yֿI}Z4f9IYoy^n*j7۵GPﯥ௛T$|Mk$ I5*呞h plr+rfF`S ֐6eV`D*ܸe球0>?x&q1a gNܟfw6C 喵2lvoy!D*̋0F_d9+&奙sq0!KxhfLNOk}EA!&U35)i*&\* Ko+taV`2u1_ut\3QߪտUIS!_J@ٕBI/#?#ưfA83^Wh2ЕE-R/8.a{Wen8kZWMfH p@эN7]/\_>p#\Aq?gp_w~9rҺc?S 4! %MAjvx/龤R^SBn/rRBF="2!2y&.M7$EԘƻ)XAfyrN_&}~դn_pط%Tv>QL^3HY$%V I^iipd^yA\IחH>폜"^¬dz+SdD_LO4y!Kx5rOY)!gk qOO1J qu 'xnw@Z,\'fצ߮|4.`K7_t́;K(Rw%}&S#-\Wz/>OAϤ)g$"gTevN&@V!$T,lK Bfm \W=]-XK3^gH,r]x5i2e4gW﷼^BeHyjDtHF 鵕C>&7mdA[8}8U~Țpu k&}Z-"|ǰV8K%P%#/d^!(zTFы&}F!TYBn°9jC$jCUHeʪIvyE^eOh"qa䦱[Ĥ\NN^a7t+:TjHZS.2߯l!&&2 Lٖ?|rHOYT c;nvpXt{ys=~,tn 8j=ӂǗK8$%h8k*XhT!#,E= "pXvZIsBLR#|̉TKnarΩ.pӖ\y_r^o[19Xdiw^$.7$mYznŠwHeQ]GLIfFL^bJyW1-/:_K<9ΜggE"$nypϟ;sҍ<\Ir8%l-؃.POũsm%}=fkł EhfUW+'S&S"7^ULtw]*ۊ+טZHQOҕV$ +B㼿"3횋mn5C u>],H|#-2U\n\i_JW'qOR^U[女z~F8ֲa\ݷ=> vu?}7aUK<o[x ~t|6S{6P}2"V$g^tx}{uaul4HyGS.yyQJr$yC 9FEreRHe SHe;έzY4^ye*} R"!wYokPs"'duzV*$ZAL9$5)dJXj~ѼUu[He1$ ct^S0C҄V)@*?$ Ð,Q@^uY}b19ct1r-ڣ{t!(uqsJ3w!wACg㱌:_=x@C6f.z{UR(z`.7|#/ $Y†T `xqd&/N0ZjrYi$!i!7ZsA {-" ՌI¬ˇCDLR06%1mqH+Abr>X ^m&a$=yW8NpF:~}f/[Yg }%" Y&LK~q $bCI`/R^X%X1^ȬLgcj9ERUXU]5լ|4@Vr"x**;C_ Ksj^Evd8L8OnbbRv @'u_8iwZ'Gs;֍&wCZX]DX멱-) +^2Ei_?a0} >dȋBZȬy0ƤqFyU1yfuY.;/41"%:1lEf!" H斂YIM94x<1d:1+wM&+cg@QxkBQ?db`o0ˑ<dǎqy>-tljQ| p~9?0>螣e8s{K9^e+!7.-i{7U^ @rىz$Ypލ2SRLH%#|o9wZC*8^4ÔZpyҋO^U~hCҾM+$]{Z٪cR^HDݿoLvoߞmvb;|tPMewNw;yn(got3wۙtwm>sxwn}Nݭwv]s&WVźվh!돔Kg55_cڤs]s5i5i^rw_5Oksdl5IjouIyNxvծ_q׿⮩Gj":W}t]^'?r׿Ξձgusww-T0f\`$*г3ՄpƟuvg?kοR=燵8V.],Qwae}pW+p말պ%y3Ty$yTK03a#کb~"l[/BfG=Iqti_1v";$]U䎐BIauV}D^C\T8g^'GA{P>B^{⏽ٝ#ʅ^BY^^pu Wp;59 t~w.it9X}0{) ͹ƍCfz@$E1u% \Bn/.L%ָ1ՂT_:QS-xZt֋$V5+cqKZgA>+Fق"U@vTxKdW1X3Q:OFky.Fxza5N]i)iӵ !–䅌";UI m)/.T@^< HT:j[Y܈Կq#d٥&\!iZy% @ Ij^m'<}U^ u!l1<<'46fSgIn8l%Nwo~>H4ے 㳀+.K98@s#ol^b!/dU s) VH֘l$03N4I`hD8UQ$hP 7)j I ;ozHgðë =d$AL%&gQm 㾦<tg.zeԷ= >FHvf\Ft“|Y?:faKFܓe!5% o>?T)@jJJxAo^<ȋh CZ4#gvX;lɎ"I0d'óA:]q7ͦI䌒M/Ta>  I˩IˉxB^*}aWC8rI9ڌ:A6.x[DtMn5kVn!Yd嶑EVn *|=h-ˁEjAzjM (lcAvbHH$±-(kU13IAZ|u{nYMV^/^R渞b dRT_؝R]k<ްgrCHp|EwQ]TkS~ۍ}+rr-mvOvrm*F?gs5Irt^j]S|RBWrX!Q/S>$֪0;5Ȑ:x䄰k JX*)yɫ.HP"/&3I:()Zؒr|oAM΋T|'VjA o2Hjѫ)ffk{DU^VެZX I2 '!͗D8u7ѣO8{|=ʮ|ݍ%a_jd&-V.WN: 9U+'Cn$*J`N'Coqd_i/Oʮy!)Ym$\vwĶLpv$?h txK;o\k<~D8ߢ52z-L*H+u+$0/ l[<3 /E2h+}2> :=/l:M:(d`}@6q8jVj}9%xWz9yD2yz1ht<־k_v Ie3 _ /=*ujud'AǯW+諱#_+NKPk_ H>VzLc dQar*L-}X폃~ R~n;ߟ}؟}*ca$P<_2=ƝsRf9p7^s| U aR^k!w<'x)B Y'd'L/y`RRBZT:3IrkuܹS2 Hxċ4 =ٷHRfetPC,dDυ?b>-ȻE |M/]Lƅn hpwt7> Zݬ5c |^0њ¤T؃j7H Ѣ m֢-*)Hf)BHiE%>UU>[ )IY]BB y PM`-fVXT G9R]^hHw3j;TE j#|vG(<w0kmE"L>@?{cZ 嬪X݉Rw+7RO0w9r %Z@TQ b{ӄDv6PfX,@"9,@Rw[*@ v9JXjЙ?ւ ᠥ+2&623!yN6,*X$˰xd&T49!{$c/BVbw$l|U@v(6gm%G̑/#;% 'p\0;)w,ٽOI `$6"i3L;%k/ ft cX+!9" YtP.)7g_?c),9|I&uFH*is=c i+d8c$0X{2l)Qz<$wuWƀD\b=R%ĄRT&Bq#fty:$ڨڨRY2yº(Lgl}Eimi] X Wbgˣ 8#Э)IG4CWVF?Qp:/^phj\ijDlZ|ExU4VTƶ {ńpj[5x,\WW U+02պ@1MFnavAjg)va .cTN&sBM7wȮdtr{cɎ7䌐9$Ď9qaYqa_tlCYHym'}eDrg;sytv+X0,h;v2t 片Nqz':ܝƗ| @x9#B 'ca.+tx a;nrs"7rd:wI_$fSAW!'[!!+Y8uЩ3 }ꌽzc%y$-h[49 hiۂ=@f2y&#L8f0kf(?d!N0yUN}N3 I dY+LU,>N2#b"r٫UY0y8-sN!r,R.#BxC^fnC<~tљ> >@á,>ggtzǀ3ݷ Ǖٯp W ]N>ݳ_agxq񿭪toRof'+WӫG}!k5{&Jh$2t 0jY-,Q2+K CFbݴŐblSj0}Ent/γ?gtz:wB yqal2%e澐b?HϔNI0=xr>= ak1mj #q-4lK(<mE~f0+g䦔R(tg%[x[3|hp_*`ۖS7@ jFn@T`v5}'].'q,s5:rǐJX3bKR ؐ;b" ـI/5*-]=,$WyaIl$@N+kHdh{3bY(2#4EB$vN݉r&F_gaLn[83aLoX8n9 SϡWM iáK󼌬 < 0W5!H*-gD%䅌6^&H2HS8AʃʦOH5iƦ]gf$X4lerC^:CӣЧ3k3Z!7dFP3(Z־+ wpŬH 08-Oق geäȺRi.O5z2yY@D/h7t'sYPGG 'E?9 3Sתy4GdHgFYTc8bb=YY55Y5#Y5X5XAJ_/-ƪʉ 4_f"- iꊦ rBFyy(ΪIƪIƪIƪ)Ū);NV! .Z8N8Φ6!]x~]i{m7vsP/[ȩ*vјGVHF-Y}5H\fK:A`GHиMiIT`evN6I-n~#oxHZK_! Vgc $ELdAtl!z㱊˷؟^1!x9vrkp;<{Ij=]~ówK|99BNǃsrr0d0'VΐBfԲⰑ*f{B^`-t8%$a89R 9`#}K,>'{ 3}SU.IL^H!˙z$e(Nդu? qy7^oW8y\[ 2YGpl?oePvzA|C_gTvWU. y_vsn7 "#5̐2S(_lR.+P TyL`Dn+RyETHD۔!HòaMs JKjBq,B"U/$elDfWXH勖!|hI@Z ywt49Zqx,j]@nN?7*OR!BnH!#<{(ŁlU_\neWȌh0D(kk&-yͣ*ZS]żߨ}ElTǻ팄g&.\~ H87@@#1@8 $e/2o% 4F/+d&<*S.)'wd)-[efqM;IQdI- iFݑ<$@V_~ECx̽!\7q +}\F. ܝr3/Ȳp8g'7z!? OA→[!37fH8!Е< '<_mYC#C3'$wvTKrXh /aJlDJB>E$ -}jER}FU$N9./ag:NR%|?;K&&=:!Gݙ;)nm  ) n 7$[WHՙI$ŘU?N:3I^Щ6p leX] :U e[+ul:&zQ_ {lzwu?oN`.l.ovEN)S./kWV^#%q2s!mR>!׮Kg^枒J{=Xw!/J3*zմn )/DAT l)`4';=۝+ڴ?g\FK?Ϸ {LQ GVs^63$J?&0ق"ߘ0_?j!gFrh8P)eI/.eD}W{ ɍ)JM;b>q2K8%Nf ;bgNf'o[جWdN#.{|뫐w[mnzNn]lqWιވ,GLܺ$X5RW@wC'e3Jbu{zzzUzY"ܺwxzMz;BRO :H⩗O&^Ի.,.gq{}ݽ>S^^SHׇt3Fr}8p9rp`Fr}QٝC; =x)K>Rᖚh˞j~<Ȋ: +&̌|XBKD>!DKssjI 2%"ېÁyɹ9ǃPnw@^R=Hyi߼wo0)=LZ2|QzdKG>rvzm$YfRB6E*Y?::U0͸\ /Wvk\g5Dfɍ77"ïCsc͍77% S.onH&nH$}խ;!I\W%ߺ*U 9ycrbxVbIyH&(U.3e-34kD,͗)2GI3YdI_諢{\[o]|'APEOJJ)T&VeT=;ٝgniF {h㯌.Tc" Y_ȍvm"T i9uSƅ|A8Vamg\'WJ;'Ʊ }9/qwAϘ=s.jF3a^q:L+'ʷ*Ijepf}3GBN[U':p.d.r୔9_)뾙cu! -$oX]Hw:}TQ9\=֖^#oL. 6Њ?5<_NxR۝ 7*ULNr[JbC* Y[IJiJE9)xH?$tJV|~BVKroHr8dV3"I7!7(wV% G0 9O`^}\@bV -uCdwOB8faq, T񎇦RN@0.W ͋ٺr0yڊݸ)BXQ};˦ogJU,rC* )DߎFVF*'"i毚"LeUW؎{JLHRXU/FHO M҃X+۫@& s0|:Oآ[t>.52[x |cOpV=|ǖ~8},?z?|_ ɫq4;ٴja #d|!7U5('GCmJrHbaٴxSoۇ" NGqID|>p@dl i (ƽ,qzI]/%w3݌CK`=;?x쾒煎SO讗+K i#drs2,.C° y͚2$ɍD͚2 1skYSN+2_xݬ CvIM i S 4"$eOGD*?}o ="#a(3=6 ޳#o vx(++O̎Uln0&_n0~Q|sF1jLn0~/GIZYBJ z7RCJb\ sRo`H$,:xݫ[MŎoHv.7~uˍ_]e*DZERBxP R\Z8ބė2LpRPtLNJ.M:ROs8?$G (wLVv(CV^ \Ru4!&;4Y!;A%d22Khr&Lf|I5cZqlc£H24P$H|(AfjѤbIj$B@dRa6rQ:@p>é3cNUB0vk+xzp7b\ÓrRG^x!œiF "&7ɱi2_kJ _ފ"u"aSj`S"wzFdʬt#cH>G8??xZ_WWs: :/!Ɲj}-r:smt\?/%qB~]&e3ɶuەή0' YC^!α3&ǁ9WѤ$+Lo'd!)a'Ʉ$AMMnj"'Ř/,z0k<1RύQCFz H2!#=cG +90;s6b:ݛr1Fz9H`?!'wO%lȟK1Q: U<\"j݋ī̖r{AF&+rC31Y+zO3pvg I l:Td&{v!Ҝ1`RjdN+wI:L&w+$23A Mx-83A L&wPp3L9äG>~KuK&#W 9&7VYȟKb|ƅ[!b-*%Gf#ʡS&+af@h8 U;hތ;mv6AwPhPגN=w~70ɟgiG:dF FkE$!!ApOt&[џ}3@G8ck>G'+wʷNmuNiIw|K>/DZ&Y܄iY7mq|(2+ 7PͱcͤSj,ᴽH+/^'l(y#Ջ$w_LJZ|7dC\"y6v:X I~ףNg -Lsfj=I+Yտ3d'MoFfnnF8ifnF8٢fĻΰ~ oF[#᭑Hx}M*_FBlH(R &xkRB<o ƽ=&gK,ޭqָwk{+'ˋ 8d*rROf|\|8ip&u9 xQ(^/|H2SSR.W",Sn!ޏ:ë|L JS]x"{^}{SxSxJJJJ3g$F$«ϼW=r߸>3=mgB 1/tW_qGk+|~f+\tQЦC⢴2X So'rC"!+h$l Q! 3 BrqvdXO!7.l!ɋu Wy[F9È욿Jz գKtfHf{yo v|-ihkv|m[q/$% ^밬fZ 5S6GGH+d6̄9ũ,nę GG0+*sBHK"NҒ;g\I 0"C'?A&u.nݙtp&տ :/'-;+™r벟touh 1ZBfS^E?$z 9!EX3oi dz'w"/$aLi{M MX+fy$. ?̇e`D "'?DӄD8w?6P vw="mx-T<٭d2D?+.m/DUuE%`O4D[Czzq[-r7ԂАMZ`k4+ˁe&x'L΋7:I9/V4Fq:_4xJ>+9cͧa'tN{s:|"H9~/$rF\7-d^rf,rb0}w~E}dW\n*Y74 *:EH~:L!L_/r" ҨOțpHS!=YtO}9N2fJ++b%#t)=6m!܂N}6, y'=.%5M;$=CMSgr[6)ՊX^ϺjֻJ{ ºr_ (,1%~CF+&pKYm$^#Y㺭|SCn\%MrJ6dW,\5SmKVB:4m#?&&7b]7Xr:o;{7lNKMdeȊ';KM"3cRd슾gLO&H&H&>SIya rIƹ\x@vlHJ1Lv,gDve$H7)xacQx|o<^>NjaO;>Nߤa=>Wkxz6u3kt;{~pCo =zelԣ!Cz𯯒 ?#Uv?($9@zBv9@VUҙS ?/п HCB/&di zd0|/ǤTU݋4lv܄൯.Lx:2Vȧ9ܤuVYyC &DY~֮-:[(wS/97#{ȐrT7d%ԕLVŒ*Ƭf {V,m*#s䜸/%VGcdȭWv ^ K>Gr4[Q-&H"A̿l !s!܀!m;guʮq7~X8>NL? !o4NSuW9TN=7_F х&)4Z,ȣaԅSR[@^ҭ&\vEޗ.suLNv;_F;*B M"Zw:tc*{+f`.}# H6ehͣRiIp9>&,FaStpú};ʦ>lW_wq9^ҷ d͐-ٖĵ!-Ɵ*/w# f&cqwDS) ܑ _$~?G^Z՜;!Q½z%Fu>$+k _# b@$Rx[NO&[p)8 7Э  78oNg67+=z霑bmw+)^)@-xQ$"VZ Z+R~T%1/^CF/Rȋܿ[ &Y岒kf993말QdQ!Ux@*0k4ϐ+&yIy=-W r MʫEqHzܗ>f,'A̐G}rW:@/q$k/=/ 5f2G8d_rB.νK7St<[>?!Ml 5Bh%!ޚx,)5W#xaH bJ/k9B,-=)sI[AyZcL}U1 )X&Jyla^4ػy#E=Ro:\v³׷#m/ G❑wg2eYhϮ}EeyrG5b;f?A*!eud[|YӂD`,["o_>aXʂ :9V~@8ѝNNt&+':cuR!cB 2,QwDZn t֩<ѩPĦR^T^VNA^RVbg'~JAEneQBJ3BF$l)Ji!7ր!#Md FH%+^XrJrf=c8m91 ږCѶl3IGwX)t鶏1f" mDievm^ L|oDׁ8CSDOu=s? bOoqY]=}AP?rS~ {~f;2^QE\Cm 8S@/iaٰl:tg?+!Ϲns{> \ @NB-^&7륣pԹQ:COGBsijX_ɵ<~S0. y=?pBzJ$J]ve. ur~Pږ<X#&OOmdntZ-cy&WHur@_>Goonn%=g=n0{YɎt_Lltv21@=>|灵h*UW+7Ac,9NiO8I{QBqT'\(Ȕrݞ)9&cq~D2]퐗3PABxx{D3$!^dp'B$ C!rѼn- C ra9h~,D1,{GZO?FF Tq3kD!-=n.FLj2&Rdd~iFHԎdD2"@< {= !=F#rLjCD<DFD"#"dzWD"#"Ȉ$dDnN.K+9So+7]Y"DP\{*g~­T^+ JW%<|5§p q^~F 5YC6HwZE'".grNSQs>x; ݵ\s㽁mgA *t7s  Y6dN|p.N ɵWCoѡ[,wꐌy ߭w+~Gw.xo)|at8wp]?ׇ}2BGU;,PYN3\'?JyÎXGާCaǣ0_서 /SBS4; @x L ;byF ٧'@"f?#oؑе:"lP2qIh q NTs{X2,{hQF'"7CFB"IF ;Q'zEAs \>!i XqzFhΥ}􇶈GCٙk!KuIhѧeD2"=x.UѻK]vO@َЄֲڼ]2toƒ3o{N'ɒh!tTsXTZt9?N3AՋbQ:T JsFՏk,rrBZ &<"gt;G5BsMJ;$F1Sd:6"N=-LOx K#6U2[qðy4[-zno9?Ffeyl)H Q+^m% nǖ۟©0nӃқ{}7PF 25StK|jw;V.& nD-$'d7tœY .Kms\Sr8:GJW(*D}Zt|dk„[ՃAS8~ت9>$*2BoO>UNp#cSHk&`2&"c+ qӰj|*6@<A&͐Èv7ۿBssIPƕp+]?D~9,>t?H(s~MCmuT }Wd#"ƈ\r՟GH Ԟ* t{0b, q{^`zpqvgڛNoQwPV#2Eo9Ly߿!zHY&{[? (\tPdo|4dnT{к+\j%#s*lAէ=w5«k8)nB\z@kkií{v9Bޱ$8d!Nk$gs'Qwa7ٟgr3BF0fI7wGmgi°e)@"NO7h~!ӹv yLJBD>K[`NL!@E+qz1naX=*|.x/tPUfᚳ-6?.~) "gEv+i_r!39u Yyrvѿ/䎤2J;nUwrW9ddS1>1W.bOOO8#7tdr![]>y.A`sDzDzDt~T5}"]Eyٙ##"&lTzzz˃k㏨2xt q99/ĹvT;sd 5'df$WBzPؐn!6$i=NN!Mzr=Sp(9ؓ@!lZOu\ .e]a*r%k]ո>9|.^>O 9ZX;saub_VGVx}lOW>6@ T8XAW\Wkqh7rU?5C!43)F]hW1)H D0WpT" I;bD4$`!AI<rAtŚ /H]N[Id9xAZ%8OҤe5d&%OVllllmm}:-0ٖa٧8Aߗmm}9-rZmXl˰l˰biņabaPaSӊ,y﬘ZZqbiai```Ŋ`x`x`B`iҊ6G.Ku0`0``Yh9]N~x * )(Xe4>0 v:J#>_ǃY' e\!o)Y2yQ>ԣњ+u+‘d-Щ413q~+Je5\lle 2r. %ygNl* !q9@fBvQpG8tb\,N3կ_'#<'xŽ4󚴄xgr}9 A0[pB-:/d ⳹+^^xUJw_oUW^ NVb&Vxm,[/ͨ8/|BN ]s>N V1=cԾVw:\p)*fɵ=N M5}.KDx!ۄ]>$ 㜝M2s9]@IaQ@ڹNίMy&s,5\K@k{ =c٭O{hçp$2]KVPz.)Y=j&-- q\vTI..WޒFӐAd= A4$$c;(m}-=k{kr~].W^+:Oڗc\=i4:ñ \[ZkˊemY2?Jiز[[+Ri,\jrcPi,j".rQY\G@CBBT!Aet<F+(B4'A9*n\rxyNcEG]'E"nI/NB8$K/?/i*B<,:bxu yNBi!B\ n| kg.=yʇ,/OvXh+.ٳ6j֕EɺR*\G^1>Gk]ݵ K­rЈYW"[y{]k悸TkCȞ&Q[Zw rfѺ6].\_9j:zY pWΣ5[(+okUFVU>|x)H ‘ :G?cS8@J 9^'h @xߣQ6E6qu.z!i]DӅ:;~'ˁk22e$Xo0R?]9ֳ?OI[uHCA G-䇈 k:HnY&\ rM0n%6\EU*Xj!KC}ꅸR,ӐdfH\ c7~wǍS9\)7KkI]W6N\~|5qV@ o3!f"䩅gM\\ tɸ;6GuvrGsx j+87o jSٝ])-UPU6'KOP83*v<2GPF5¡rU:ttwa ▶榶:X r=6AzHt\LCܙ48;g0y#}YA<'*As6a!uӌ(=Lݞ!)9J~"B*-␬i hM)#x.\h 3*%4pQ72jӮcA"h*e6$h*<ʋi$L(^!B:<$jǭWay 1,脆jɃ Lׁ[HB8Ò=,فl^Kj5NGo.O\"Nwdq{ǿÎo;w98qqаaAÞvaLJ5:٥^i\EnSl˶z6+C«gS:N9n%a)RJo0.;D 7QOeF4UD-4/#<׎jzWe6dDe=lsbb@5wk-;v~I7G;?մݜl@o:['<{dgoo~7['9MBj$,onᄧp)^魓­p7[';.ǛȜ&ns Qvo@&Q|흍F|gB@a 8Jx;{S[=}gG>~)(e |!o5a.7 `幥;_AE#E{{-Jm.U!^lbY8o9=쳐9:2,t;kgf'5C\;5*FQQǦ;.ttwtt! qݜωe)9DwGwG}wG}wGkwGkwGGwGGr܎.ddN}vwE5=,^H \ՎVI)WG#_Ĉ ;m>\Iq[Ȼ.ڕ«Ϩv!*|ʇXWWw}8)ƥr)jbyOgx?N97 Ŋh_{؁DD=Jd†lWĹFrJi@vBҌ\cpnV 24ni!+$@t.ru$L u]7QדݸTz̘ϙf[[s'r77C"xHi,K|I?5ۻyיٵ!OJgxiBwjx$鼈sb}z nOƣ\P'B~E@aTy[&~rQ=٥8lՒ|d~&WE5IcCfr&)O9+X];ܗC8 cUʧiva(V|ZUX|rrZU~ć9d;#F22rtD!,Jgdx>5BV (糡#$8{7B0b ˜|o%j{:%CG[ZL!Bc-9ݿL3.y2Toq&jhgΖf'Qi8ryN$4_Z#+T,\c]c]c]X yX7ccUW=(/Ch)KZ'W333uzr鉂''g[F^:ui@NӣZX4tp?咺~{pBoɅ]=}ɺ\,ΉqYҢ_)1\ZޝqQ!DS".:S";«ΔX(jDWyT@b HLbl'MEA ?*:iʙ@v } kyԚW syz!>ҹ=ֹ=ֹ=ֹ=K ǺǺJAX,6T.bc]c]c]Ba[p}^aQ=v 'gDDD]r#r{r\krS{z+[Y''z'zI@ju  to! ϲa‰6./"%",yh=?ֺh=1"ʶWj*TrmW{Gp(V]6IZ۫s*Oh۫|\hnչ:wVg8S܌I Nh >!?ۚ"nGby$u% q?F;EllJ@FHDaCz4O|v 5K+ O ?U gG 9^kCROd[{⧥ A$Qg\9z$8Gѣř"6'  zp7GT~N1BWbJMB\^j'd,Z$ .gY^'dÈ /c"Z' dÓwJDL<^~'.r,'XGɫNJNG?96*3K]<ڱq]Jۺ­x>L ҡ{}6Yq~fT52$g¿?Yn+]Po t(e4"&rCۤ DuDN*5۬NO~ov~o. j \R)E!(@v6qK[`QHKo׎pHΣ^Uܧx jc^x-%d_{nT c̄q&yݻE۽\լ;[qv!nvԎC$!a!\l4 4h\OzhxDQQqaɼ/vEqaюdDOݡs'TzdEN7= ]_}CօWnGt}%Ȓ k#St-)_yG\drr4+] yx$c3zb>Q N;p!gץo!33>\ZɅ2X],zsDSw| ySLiOK)B:0@-< G^\qJ\ơqZ?Ïi*Ew §hfWm4w#ĉs &!uM+82uö.VxSA V5\f'nݤ'd$#ٻIdI~IfdRZ[زR)"UŅ?]PzŅ­X. y5p!`)Q p nT<&զOUځ§\c * Nw غvI\x~]< W>uwOܸ-q[ I}ŐTVK+=o {˱ ԛ-Ύ!%4~.>DXAqD\Ip ٮ[n\$B?s!s?BJauԛo")WO{xw$1ܸZ,Ӽe[،<[潅W>:^e 3«px) d{w.Ƕ.jvݶս۶wVk_z4;ٱ̅0l{<m#dy#)^#G P !ҡSCUn4B§v<Ax𬤺FF N5чбAdM(lD5CSW"Cq9+iNwNKzHĘԉ86Ϲ!GQ C\ AN5nIV:&asLz ɾ`y%E+μ+;{eV>]":4nţwj{e^8 e25uMP8 䩣 >&m\gǧ"C6G6QInLpiNF0Qv\T/G: dh?ZRljKȱGUMp[_ZwtSʙ«Mf 9 y!C1!6= w7Nx!'sT\vi9|vE:˝m4UnS 5}(V#i#V +<8 |ޢA=-&m|]A\N !z, ['׮cEϵ4RO!|BA2l-iWQx 95QIxֻt8m8zM]ֻ<ș !_*dnT=,p;*/ϐ#[k% \ U vIbK!G֕4ź NvfdGqAd5W*ʇVB Bܞ'ʓs'O1^x"lHꟽb<{xQe4 v)T;g/λXGdaT>Wns>{!~Z vG:>ɚ&BDZc d;;W/4^]_\i@CYU<1G WS0txU0!;m|B ]Oþ2RAv qrzO15dvDh=@x1!i1/8Y A빐]d L ͉q2}BV, jn|hj Lްe1Yj!!3di|)`o5pϞ^T R§pUk4n+ʹ7nu nr$Qb/WA9&)/ct'f]S^Kr/$ua*(i?z>^.{WM&x4䡧r__!de@?!4|K·$ ,|]BF}I~[~!1)JQ(|jB!ʃ\ Qdo!ndzfY!˹0[LGYe[A{}1!jϞs HAT#+Ϟt ѻ{[U.*Ϟu=JwNj,={-t Q~%&nB~d h+u|v8 YN @VIĭDmOMX@擨k/M})/^uJ/^u_8ꋟ"I3[w_(N_\x~u vz/Ny_}nY,2XW7*+˥we, \*G[ʙH!dzԎRDqQ1RhCjZ"^&{Ex)<]?C6x QBi_ج| uщ U^k,S]rgS: J]p5ůٍJݞHI to7*ۋ쿑 e2BqMRүM}@^?]SSdLG[=y݌] #5SLM=/r|s필WǾ@d| y iGSZhM/^ 3KV9窾>*nT; UÏ]g־# 9!O4-,XwZO瞷]Z2g^-rK/Uq՘xc2}Gd/oW9_H۬-;4t|{s\ÿe!r]y; tw-Q3oز;-D½k"nXׯb%kc-26sICvo&:zߎУN*:~NO'%Bsq0q*lR״z?^%grübxnK[B{esi,s<4ZG0&%du}OVEG䌌ɱ:-rxlLbD(Zz61h,㨓ՄfI_3v3vrR8>0N7YrB.|9G\iOSM?Zr!UOќf88hu <H&s8Iwn9^v"@P.4q ,./,)"{u}U\EO4C"rF_ %l-М:y5=M-_L×&xj{TԎUV{‡M)ܫɦ|&n NxDhy>߄ w e,ؗS^O9E qv'לJLs9#kND;;S 4LSģ38h ?91qb%2%A/'וEݳ:{m?Xz݆yP+kNN)e~*0ᬥp:|> VjY7snsu xT>qZNK{sM:d?4χ4a 3K*9'*dN2#$!I*Ի#UnT!gB^RY:Rx9$ⅅ5%+"m5*;0fiaÈhԦ9Un݌J爼5JW?vAnS8޻Tkj&+=^r?Fs*lg/yMIX:f qvڐ(g ih;Ul5& qOvpeH?O "5¦ڱڳ~nTBJr[xVr"R7=HE[v[ƭo"<n'(<=EOyqbn 'Qǵ#,7Mjo8;J.sϋ˨9Ww0LRYVۤLME .g%;CGog! EI x/TzLlS?˒5q_?ozWzշ[)^UZ+W^QfT}/j}k2 w-vDVLwDVBgxZF\+.h[J;c{;qk[<4MDoƙf /Am;&";*[~mk~Ȗ_dNC\`OLe/, A<)}x<#}+sr~ꦟ駬 x<%;T~=]O>Rkh)~h)١\)&W)٪O2@2ܠ6OB˽Y3k}fs7#&*OZ=g4$XACry%ͬU2JfV fCfsU$F ^nn S$]RT%u¤*g~i GQ(J܎B4 tAAx ^~t! GK".! N'$Qi )g%~QKdGq-C6s XH$Ӗ!l,j3feгޤ q;Z=56KӖU9 Y3/^HXnxߩ[ʙl)cVvTV3T,B^mTpyIL\z+rf`vҹfrBqHںKd;N=ps]~w^[wD2z+y.R]uj2ߓ;ǝ֝Y}dM#BHoe YJGzM 9(?CHD gT#}vWQ8Tʏ^WÏ0zT, }dl;-M J-sR`q>V`B>EC"rBxi!iKVձ!M H&y(iQī@*>L܌-ԥ-9n\rFkcTKPa mfZ Y/M:|Ԧ?x4[ln. wSvƥx@A9D+_"۹f [gw[WI "LwE]dyl?w >r뻈;wyL<}OoG[)!èS!BF'.S88]w][a'➴8悬$yx]fr\ "cֆ;ɞqJ9(Bn[<-æo';DRy~=8WxayI󺇅ou͐NNb^&"Y[䬶vMыrr{]LmrL<}{4:.LCg?R T02Ykw՛{QxUz4HAjRsMՊOhM*![|d04ivw@m)=G`7|~zwR=/e~" cY?CzF7Ibͳ܍йxo>$ Eh&" `22'h=t{HB0BGc/⺸CC.iH DQdzYtֺ/0!.0kCgސ$^^R) ҉ܳvt?1!clNE8UPkbn1O4^-) _>)\ G-B#U>b2%v 8J+Ȝ&d>`kG#sz7L/>!Ϲ$Ɓ\5UB&^WtAh!  DSgZR#2EҰL< ~u,K(h^pDSKV6igUei&ű$s/$kdOy$z}' A 1{ӟzU}zIAQ:/ԕl-_DslKreY. !)';7Vw& ߥeCz'^/eOHߥ%"3/U!]~ "_!J#/d͒B<oiqqwdcϪ_Ha ^ ~)4rjqòukVf@ _Pۻnr{7R ۻo{3?ק/]2Olv|crB%P$6$ ^#D}VTo˻Fh}||C{V阜}&ٵi2ٴlv6m;$8a'`ޏdI!G¥pHuxQUtRxQ+t^ r2mS9 l^ZO.Ee5zl=8Kl[ tDc<>}E]tga!r I_/b7,f)!T-/0 9yAssG|2> O #>4LV\0",'n@ )ہRӻoD"20q;Up>OA"2"m>r.#r +cD\3[h&iއx$qm^H; ^v6 )yD{vq8P{Q' \ E87Ej(|?DFU WqeQ7n. vv>9p8ayIk'Jl ~A}GQk;s`7J8c\s{d\ŵ&d:{gGrm!NK `YG'\ypD0(+ǀ= o* %Km88(tAG)!shVB ~o16\Hz錼5F#fi d&\XBܙog.?upFksLc!rfL`wZ& 9(|BVosVF.3620S"QHu1^pdm^xTs$GlBȀσ9%D;dᒬ@KNߚGo>$ѣ2rusOz$kb"+ig0ɈHvr!A.K3|* $iP΅,9@H2ZN3=r@ Ih3eBHFyyXX% I]BF AߤL=P8k;ĕ#{GUһɊjwOSGKފ!$wX%6?`Q8^W:]xʠt|'^+®x8 *C*m*Q5UǍąAU}ҋ2(|j.`!Қ;G˃d\AT-HK%W),=S"'ipey+8` B9c7\cO|@R.Dqg@dxQu~| 蕄L= {(UJw18]X>Ss *tyx2*t:N>ϙ=.ӇЕ/aGs/~=! {BT؛Q⋦ x5E7͈IEM3C 8%'5#ΔF)8Sq4LI$QWo&sHVE]o"HU!ُJ.iF&p39!1qb,F\0`_3i)ӈSL"N3S2q $ivN^o 4a=Rɰ ¡tYneWG ?Sd,Z}2*\Ƨ|Bp,Ƴ(d&ɥgdl(s"Y! q]h0^)yy$d<IÐgQr'AN˒2f+Cg2ۚ+Tc4GMϮdא*_Yn˨pNj@J):tU> {uٛl [-l*E!"\,Ga g"' n8WN.)X2[amBR6 :&̆p:L~gl2M8&§,­b&M&4,fĩRȊ:d3;Me's$ "&,;V+*䨝}6Y+<ޚ g!.3Y^^`>Cgg ;܍g!O<]? 9-ܪO˲ZT>~pgkP ~PS;v{zux;o(|§x'FfT|NG[Փ:~W8N7S\|PؚQp 9(\*\ݎo,!5w5P'ϣ9O64!#1u.l"8ˈ2ZD=W히IBnfSI8xr(rK6>2JsO@G)+n \\+fb;V{sʊpN ~& Sz#\kiJCjNY 56 x$ 9Is}WqG2 ή7nX[="}̐) !'WBT&d+$WڻF(U 6!#!(MCk1׿-StQ8V<~)y!?ҩG!i:i)GQ}'.n>N ^>I@BI@z:Ҽ<.e&1mY㺽@Taیn3dܖBJ 2a<˭hUubrKH qw'g]L ӉILSHYĵOs2dk3J6?Hf)i:R)#)J5Hf)#y3y*A2XU(TeDvv$+4ʈJUr]2\s Ql0LTeDc"@yx<3uf AgF%\2>[?"L]e^ Ue¥2U{gl^][ؔ^____WnfbJ߫Bׯr^ N |Bu\YnaG+#32:浌rVFꃴȞ!9B*CnF{d}|qeʹz q%iAz y&ӉkW ^V=ձ,2qJYξDfW )ՌWn#j+YGƕb&k|J/-TׅGϳtlL䚸I|v6IQzvpu/ˋ}Yg< >Y\b4d9J/_ ω g'~@] qx1Vx1mvK {^u+ $Q|,EUCwg{͒%5KKKk';e/6ժ';𩬮x,O/{JMTVfYp:~Z!^k~Ʋe4jj^j 3F \5Cx/TVTW׬d3dT2݉n\qmrfzj+nVݬ8YQ^qvrnOAZ+Z+oVWWY񃳢gΊ]?8+~pV߬(C I6'J3R,]Q#xΊB L<r+g3Ίհ[ p?j&þd| ҡ9R<6Ӏ.)2CͨpN Q[vp H Gǿp#q y)383cei.dxű y \N^&Iw e@)!Ir]Kod ̄xVdZX˂7&Y1|mBpq26y&UYBd~qe w*CfVpRSjuG-*Q Q({Bh  ]?!~ jY4_}E"V*OwܿъhE@qc$ A"YݪLϣ&yΊϐw>!!5FU$/{ۆm_\5sٵܠR駰+䃺p*^o6TPRո< OI>aTS<`4|)Ӌot'f.2B"(YBFB8 !w 5cB<SAC*7cp)Mq |q$8[˯ԓ?P)t"/0%./)I@nJ⼦oB{]h̃>,rCz4ȏ״5=|<3=-]"B5-]ӚkZ ᑑx29Zz-IMגTtqjmF%竡.\ cn-I? ] : ǥ1)t~m=\w;=FWKWB/_ |tS! 8~Nֲ`H4€u"Xr Ʀx-!!kܕv8gPʩe㗬, @t$g/< N^|+沧r~5m{cp*\-+B77Gk㹽ܺbz\6ϝm& .y} 9 wAN IM!*!9T1#N dZSGum_v"Diw]n_vi㣫M Y&3!;!{x2uɊ9,1BRt"Hk!d:Dm8jaBQh/^ܗ.PV ݨxlkz!8AHT;d).bHQ9zu;weݗ/{u/|\_V|YE<@-#:_i_2}Yϊљz}Yϒ"+!dUeL4ODrMzW ~Y/+YB!UW~RAm7bT0 ?O']!,/4-8؟=CjχLw5˒2ݥĘ>EUNDgs Q9rybIL6˓7d mƸ~:vCJj{s\-_-'nR,ALsi屠Q,ty` O7}5vQ[xU=T G~?ҳ.^lj[sW9=&kr3Rf;2_桷$.$v=c^HzP;٧K#t7ߡ9Շ^f! i{VfHVr{ܻ7­d#iT>DUL}\nųGT9X%ʏcڃʦ2eJ'2Ms. .cN=rCVJ G Âr\vo uC21Ӊe$҇d9)  3c7ƣhRKmzLLP]@CKOn~. ?^v1y&kx1|厬C6KKN cxu *mx$ҿ3=}zeNBeZ_yjߞ8]N3 \-B^[%/|J'ޖm98~W{jidlo?DA >RSG"IpDno*(\Gj.ݘ}$/t}ȡZ{aFMȼp)#}t v{ң^TC<C4#Cr35!/cxv=c/cUyJH@Zy&UD<^?>q{8ۂ\ґHBBy!7=Ey2-} jzE~ Y3ѵ:Ob 4!w{ثJ98qF^KsΧ+$vNeѯoFJ$xʔ{_Ip)|G֏Ǣ zZTQб(T MHX$TȖ XQ qJ[!= E?duy"! &za t<2C8Ӈ l ɮ/Ȃ'CBq;ua IÐ@<=| YIH~N$?'Hr=ۤY0J:tH!C͐t2d  yT:cCs-D(t": 8NXN -#aGcCȚs%i-d0QرB3; +tz\ni)nRS9z̮q~#;+Pu{ݩpK{*-'N<16Do&Dunk H<Jy▬r'X?dWq2I%;qKv ^hd'n Y2/C ADzGe' ^yiZn.+2<~Юn:q]vbl#rLn? o_^T~*o83qA90;v#4,+H)4{4;hv$t4B4inDYd ICnh$)xr%)<5~z@ qYF#_@nǂb=!|1xVj5y,l*+­rjYm|^2͹UeYؕ,*Kkm\ IrȈf; ~nPԅiB!r׮fnO 0Y(2]{_9 ^hetݺb <"?wXv9I:E)!$Up9!7Q/Ik&cdY@{14#פ w P0SQ:/| D*?ԈLɮOBp< ]4u_Α~I>ɇt}iwN{t3NerLsr.>B<ŷ].P oSg\*vyws+|ʷg]Qs|+W|s.Aiz]`|?D.ʖ[ĕZn>D\_\鐓1WHBzHe]y5]U> Ig*GugT5JF9!.p&;_Swg]Ww!\ 1RSO#kw"c@nBoH(t_ߍp}7BU򹹽!nUaPmYxC;  7w(ܡ t 4S;D\hF?=# kε^7Cv9>.Yw1@ 8nrKs74j!Q\N3=}&lq{VL@ TijVr5{,5t$1+\F*ss"Z]Q>$HV8T> µǭ#pգwۑZ=^Gqnq(8 ݏrpWCG9WsҚd8v<<Mc ".Gc9d<( p^Jpϐ~ {D]#FF y^b{קܱtsBҋXދV%\&Agzp+[wXOƸ24-*CTp ç38_fT9M28W҅Sj-T9n烎89\ԎviqST/Du3w_N\8ɵ]>FM^ﵥ+Lͪ\#QTBzX*)(7;8>~3£0O ^XOY5+?T9d)A8Zd@k׏k\vݯNYuy;q+P ~J U?՚oݺvq{a7M?r=``sN<݅!ovBcQ{K !o*Jčǘr'9_/xݓͿ'x\S%B^ɜw{?:-[x'uլ>!n1!o&KU>om3YnΛ^2m ~? %SS)4q^2^<.$́ =l'q][@6xӻd\[@V@R9`4Y#DQ4ʹk75aS65aS.UMOML)|8AMLO@O+\1=n!' όzus53c<5M,wsk<3c<33C;3\-[ɮteo麖@UȪV8f ([x0SU,Guf3/f K9^M_1ĭk3vHc2GE8EqjJ/a޲dz[ q+LB9k4p=3^LVB^ q]+0/]^ܶmyo 1[[-k5jmoNP g\s-זkB['%>okk%ۺkT/>)^{VmEu}oݶH 3!=FQnD2{ִ}ޡog÷m{xnJ dvm89wMohPIx{>w`a}vvu;fng3 zVM+6@.'HA}_!u *]8^s|=.GR˭XnEߑЧp~~ȪkQqfP}nD s +I$Ág2IeBR +*KH[soc'F YR$?dRJA B]"3qHVEN! \D"Aiz= Xxl4@FB p)PHQ;f0uH?RK: f ٫s¥t9 ӣXx­Q{e^_\*`~8ݔMoh1@F<&k$uKyZӠ.iNi=iDyr0)gu"+MՖ␗ 1ցJJ"ѡij! Žяeѹ}g\3j֏q$1~3Wo?n}O^yߓJpvmOB׀T8, y$,ޓ^nOH +_mi犟k2=,J!7\ge)MZw#%#ȁer\ E@<(@hGiV&c%ad{AT/څݯ+ڱd0_`dnKo%IT:rn-|([ j6.څxmoEwYVx"ε~$iߜ: "{ JWw[ trB.LJ[d>Nfn %Ds馈;>zAv|㨲Y.,.DsG4y&z2q/z%wgW ѧG&."r !=,}usX&k;Ou[*jp ރOTʷܜϸQnv}['6UG$q!V]*r~Lk'L6m!747fT\(`̄gILOy&De PīgLXh4U~ X NJp¡|FO^ mJ U^I Pe ./4xS*utO)6qK0&ۣ֎Ixp Pq]ccx [FAV%Tҝw@Iionw͊+QH6sȸ&g-,q~T|Y}4^*8Lk]ꛅ^  1[ѵS,쬲!p~+/<ע;\ݚv+M]c|+˜ Y#fs\]d$j%MK]7$QQ9mu=mOs?HZuG"_Di2<hnk=p͘A'2x-׾ӰۥzNu쬫[w~Nu'Kmn-[% C?%;󒝺G;M '<˲Md%d9H *Å친*嶊a ޭ3֙w+-Kv%[d)/Y2һu:n-ғfdgޭ3֙w+;j9 ^E<~ɮtxGU +_Z‡Sp 7p 6շY[QTfq)N ^Ay}M=!^)EZ P};},y~˹SǶMzIH¼&;4N!s7s{3 [-r3΅m(15ٞ=nl52]׸^=:E,<}xV"=3Zž!uYF4[؜-oQJxKr>?O)] [}y]o޴_)2sTrEٛq\E"L/d$dҽǬr{Ns/n _b=OByBzNӧ:)r'7@y_ZSJs 2矞ăHh4fTqSӝMBۄA!;1QLDv&!8I6PG("6"7@"l4L<:B8Rh~dqd%S~"ƣҢyK#wn.8hNu5 Ki=wnM{xVB}GjմIq~lEܛ+Sutys+>\+N톭4kN7/]B^ZBӼtmlESY8jɍ*A$3`W?è?_4+soa>i7Z y&{ocj=t#[ Y"rFc7PuCNr]SކE_"Da␶]W@ 0yLG asڊY!2Ҕ*O+iX&QV, }:}5CDmͨ|<څO9-tq\MPJgty'_%Zq1oBh KAJd&dX̐`CK.QHH"%Hs5uܯn*V"z9Iw'1BDҝk%-&]&x6s/"D<>E];vc"%<H/"Ekz!a7f*J6 )yae.fRU#XIԱJԴhM_$M(L|Jw\/_$Gפ6o3Z' M'J2F 9&˹Y&W55iwx@sԾ3C0>?ZWQlE?k^l*sٕٞ\lZTn]%6^!kg¡9/)wܺϯFv p*=!?43m>(2nJUCd%&:{Zȭ"G#e4!ӉOw,鐛jAC\; gk&gz@=R:=בdjL%d S} XԡO'@pO4~x9W߮_Wz p(4Jd$HtKӐ&MozȾ6MNB{_A{A\~<*I<a濦C"ɲ*5駬PZx*ǘ>ů؎ۤr .G~()=8[cL\i+DFtbn}2qpp]/նy-= jL&LI_&#Q'QIHB%~V6KH5rŇoC< 8'}]$ԥ'pɝ9=Vye^.y2h堍#LseSyb˦hMV8 n!޷p)=ymXmǣSS]ӳ-^6i1r7tƽxr]_!6Aغ|Qd {9y\9bxlLRdv.$6,B\N„:a9 e1ۑ>.nzv=VT7QLGXvGís[YG[v"s c9 -Xx},,q, 9E^Q͖r,& &ÓMɦ#a{jnJh(HEfWBCqÐL1"+kt!:b8WnƳA!bRvDUp+;JU6z\צ]~m\Vx5Unj>^.W^'GumA3U>C%p]y''2k?rMCzF{(sr%Ά̘m"aj D݄d(my x&'$]~-E 2Mp>x:A:4u"N=}{i)2Sv{h`m6:(Qc˃{! I!<-xI1zPp.*gUnT3Q.\*o~AwڍZgVOڐMI7BM921ltU,ωt!׉s"nISOBO)sgno"Ǔ27ă en֌#Y򜸷?2Cޓ=+D3㨬k~I)ڍ<Wjz[}px(C?z )韞 y oӪ/l.o:? 閫gՃ d./Bs Y]OӝvkC{ ZӐLfCFH -Vpd\Ĭi7swH*g6zv/!G!EִHBG,~EFO/ƴ\JZ(@vB1v.7vI!ٴ/*}P/H7*;rBcC: gS>T9ht|igRH/z5Y!Q6z&iR?qn5wd\70BAnSnL\vE8?\m<årrrViA/7~{xwܽRqY)8Qs^[]VYU]9d›7Ww8|Ql7u;q~t ]q; n Օ-L47Ug!jN =dz({r>h bkd&j;1be*2o~G4$`}*5Ad pIv Kv 4T"cHOǽg!"!.? MӇ`B% ]i)΂o.E>t_xQ:5 ؿN5F8;dXk ?jnn.v?G`O=D>\q-(NdD \Kk␗ۃKjB¡1sJu\߇E'sYE59 PfA?G}H*Tק(qnՏ*yU!=,aP!݆"Ts|~C5ɐ4v$@B9ήDA7#sWqtrC7]m{ x@{fP_ِ2!cҧ?!Yu W_ xFؔ2X\*Tz HݚӫG"M^B5q%`,G#`q'A8Br?pW%6 !Xir9\:W8m{h:ZCs4ޯL{M\i?\f$ 7W.35!:>3)jQ+"%[X'KBItT' ©t>[=Yn3dV8T~_wKsLyKrDA)Am)'.yly y6iBۣˮY5VQp a*G]-;B/ A8U? ßϨ1*t?Q^!L"[|q' OGirLfD\ _EVɛ x"i:"+č/x&)x"W-3Jq'ox"I+M{a TD\WOhqz}윮A3a.ZCVhR'ԤVB.BNFhR#)tz伣IMTI%٤FN֌ݨƣNR8U.$?Dͺ6BT5BfkH_;ߒ kjM4Ӄz)+Qh0ݕLi3s2BMhq{H:ڐqL<\o&L4y@QhAt{TI[!+iV \^7+%2:4,WIBXD.7r]8J 蒷:]r®tB9?'ns; F 'rLNS$'oKrOPi¦tC F yB,u?LQSѪ0 q yBp)= g1qpx!{ 1G!Km\,+&{&RIu9Ϲ:rm |fC ψLzZgrrײ8&{D]-$Qv88v9|/o!M 6>.66|]x P ӛͫ ]zqjG8.s\u:i]rN^Gh[qx ^"]޶$F_};_}Ȕռ"m.-dxpp~r''$q{;_;& 8pn`"\&Ĥ(7Z=H(t>0ڀhс G[rN|Dg혰􏅾>=5]-10=2<H qf+krc_(ָMzY"<;B'n~$4D]IL\! It:t(\kAR ?ς44&MKH4^>RӺ jOϨJKopDuW!0x7n-n4ˍ-ynkERk=!{:|:|>xZ7'SSO)}i;aэʏv*İSR,Sv+)'OnS>0n(87 3]CP$;ztjP쐣R2r[џ R,'#5znCjVuW[m08-Өvo.| ~wН'4g<-_8qwsrwЉ gכ I1/XuE{nJ~))Q9ұ܄<!ۃkt{m򎗄=H}́w |,5EncoUȣ?_ºJC+)PU8^7wP8ͷ GQ]&d7|9ѝ4z:p"@ bWyƹ;Mzv3&j0HÁ״r 9& &w<HB& $QEԐ^t\A Hs xMI(0aN&@vK\hL. <^ %Ņ.NQӻt%tp:~:'P8.|8~?N1 AQSnÄgr-rT4o,LZ @Du~0@@ٵ-\Ґ CJO:?lt>,k0x)hd),+'Q^)h<4%Bq/t&$NI,T$=Z}-XO-g׶̭[@ţr_Ȧo{ӷ,TDZ^a!Af{ :50sKd:B׏ KHD]Yŭjo wv;;ζ/@! 3"n>!l7l{lfԃqzήcnWڿr.3\!O]2a5Y'mE hA+/dv.O8s h{ڂ | mt(,5d=C+ !>:B0׀m)+SB*d4m} ^]~?"yxe4+7ʭ2 *lʧ|e4̃ y̿Aכ͞ ]u:~] vc6T!r+6$*R % wͻڛ<26926*# 3$ualwg+~]fCω̆jrM|ݼnB׮!iPcFkӢYR?,=OUN[<]<5MT5o uEo"$ l.!p$W!+ Cr] 3f3fԮ)Hϐ87t:|XdPGtuɥ2ģ pNfս8ֻzb [tM-8@DQWo/o.TDì2(n5Ch< 3$7~MKof';vdZ)K~P=E&seOQ?Dвz*tOC\$Ap^>9cI< zmşԊ?R6C[V6nt:#\eA^ɭ?)c } q[ H*E@s rd- _! S+>D5TZ9s 键Ss(MX/"ǣ˼vui/߲Nʯ^_Pr|-nYWPo[/\?x~ vQ#\}[ I˷/߮|O/Nߐ5si#ä91wmaS+#/*3T{\LQ?Ў)<'G:D5ҟ&sdHZ Ig8?& qɈE 4cD$ HҼL˜r (Ēֳ ZZ*%=r  8KH_VtS ٗrKe4zւTR,?f|_5srdrdi~~Lιʹ<$9_9_9LtW Z9_9_9jws r \}o zWsss_*k3*R .<zPkC?KbVz:|o o3iKÛi2F;D~e60d 9D8O3S7}8rbcB&_t.|s򞐫rzvEU4xx%mӬgykˁsĈ 7kcFg ؖ,sm>E#,.r?\8uwݖwSWln4LVzvH)(m=i V׆kr[>!-!iZE҆a:i!J&k]-ㄸR[kζU=y\G x4f tJv8jyAI  f~ś`Q 7ΐq ;[aWZ^_fgoYqfƙgoYY:AvRXϨ\טg L sCd]9"[2+ocul]骩 -e"ήӦiy`uM;1Y2})e¹FShVYf.,(+h kJ.\Jr) d8;:\J4ɺ 2ܞYRf.Ȳٺwx]nZS5g匵2SgvW4W7uGԙʎ14!ĦK:Ro( 5ŵVg! w雮kk뛻M]* 7]/WsUUvTR[UgY0! .uNFv˭]Z)2'WŴeȋڤhI!/GCؠ 6cxh8R$tx^o+ґXVڭ+Ȩ] rM|E/ǝ"҉n "B x6LuEmc iά3!/a=pD&5Q]DGՅX:&Bx(M^R6/  D}! @D*"g=;CƖD悼&34vL(ᢦs&-휉$/@LKSݼwRvNnq8$BKRhJ(\5'J᳿vN~x'n_ ӎHpyzD6s-J$$鴓^""QJ4N B}RcR=YOhWTDn:)BkZpn_T?L\/̐_$X sB`yxetY"BP.3YhjRD"ڔMf\5jTxWBnYF5vp_tq:%]MnxJ#Ne;TdN2XyNI_M-q%|H>"LS̈Lbiz"r>\[O=}b"[3Sd3cMw Ai;]_GW 5oT5zIo׮m;'ՃcHtfOw {T㑟Wȅ4n%;ղ=pE`͇R3$^؊miNW`㏌ȁ\\ TDK=RI-t֕12ӿ`<./}ONY TD.D^AʓZC66l m m m m m )P@@@0F1111lWT*G%Z1c'2BCa[6jzkM :^_7.w(6>ijxMd,Ȍ!1_공2 7J:UMXj)L3.ΙPI綶BHKL ]Өro_\&a$l.O.\G߀;}lqP?0%6j`_UC,/(4nǗ equqa_W :KeatlaBdv sa ƇtbE(Ilf"Eq"ܥ("0RU' h&ۓtGajj+`4BA]5 2/=B\=ӝ6aB1&=c`Bd2ӪQEh#F5}mz_>q8.vnӨWaos8G @K'>P8xqY"2~޾{>'r ]RΜ$fUAhyr޺{Zls!>)a~ƾoM#j' ?X4҅҇*lV]ux+lAlmrNG| x~i>:dيBr~ل!k/+Y &I\O[E㴕LWbI9㼛%ӗtm[<6k'Im.AA64O7'Su szy šgQ"'u36=\3Su3f SJSK!:SmC;eTѯCk(bNuDNn\(bIYj3'ЈM4"3^ڱ"RQ<&hD.ydɕ4'7ќDcBT!ѧVP>Fdeob姓+i.Aḫ-&nߛn@&.'̜&)GP_zh U<cWy zLӕpRQ($[N7;!/.a-9r߂#ap &A?g:B5ڢM3@ is8IY\D&E5GXe5wi{DzwC,\&EI fa :R0NPwm̡zHBeEz(BCcNa/uT:f>Jh" FHQ,ȠR [*I1nTKXKM+/Y3 GKPrB|˅K:Ш6P QTp:ӥS\mx0^#Pez2NJDJ 'h"K.T٠eX쇺ԱP|ष)7֛+a&D׹":{!2IGsGR Hdm!p)i >#".G~:$=Yqt"gBP qH^:W"rIG"#o ٌ5KDTW1~7R ;M"y x;qze(W(BUlZp9Mδyq  %+fձYulVUG8O7Ͱ߬B6jd3RQ ߫je{W|^lV-NjEE !eg3yX9FΌg; X,ctP"fn~ ,lv3;뙝^LucgtMɆBώv3;s2dx‘i!e~d*ŏ̤<8Kux[ۅ)?.ǟc:?Ufa=)w3|x ]\Y:rQ$E4߄Lm:1#Lw*SM7~ZZG2F^^4#D^~cGrEM{*"ԔW9Hth5:BO^WZ#\kᜋ`z\dj\C MIp5F֬(Zd^lW"TV G]. 6SOj rWk$Zxh7m/-z!$ FzQYrrI\'EMy2nʺ"+9=>/F:zѝ7E" s!R/-r]B-BQ{Zt $V;$^dFͫ~#H1cJnnu|V-ిןg U:Rj:|7gE݃B|V=/Ηr3D&e|Yw;_֝!ȂM}hԊʳO)tqe5s!xyI8|b[JZ}YDJeI)Lz%˒e%|% t =u?_vo Aa-NDz3QC+v2%sʢMƒȺ&Md~>J\\K>Ro.Y7Si ehv6YKs<8lAF(Ğ5\Ե"VKЪ>lB.'MD2*r]Dy4h$25i7ȫx}Yd3("_+2>"$.'D\hLyI,v?ڜ˷UkW}!WQvBȄ0Hז[^-\m|Td/pB5t!D'y"j޽:$,Q%[-J_gOζf@Ej[SvFr7d%"%+i %#"q\2ʒo#!w#N zm~e , FEVlO^j xyJ}8#(A}q/ 5(cMv,Zw.+{YևfE=|VWW'^ڍQ ~ 5 #YJWy+T~xȔ̧ݽ@~Qi(rz/s8^8(||vM.>EiUד }-̳a))'c9 ևa h6z4z0z0z0z.z.z.z,z,z*z(z(z$z$zu &^L z'bOHM*0:bXŰЋ={B"0۞Ћ 7[ Sz1b"2ЋA?/~^LybŐϋ!C>"tGUd҂bŢϋE>"k@RLy%(1Y0u1XDׄPF} kMv8&T:8~(L OȥB~v,:I/E`yZ$e혫M]EHw@\:sUEE JED2 !2,}>uoNC>oC[x@U 9C>o~CnܯK%@z:rC[8~ė| 4w_j1h辰h~lcѯ!D/AE"}ݾn~FLTiXM}HsMcIs@ËEv+(V%\E."}ǾHaĪ v%EX.+AU?z&6yM[~%/Ɍlڸe\p9&3/ m2CЦIPLa7rx6h%h*wS,?|#fx33< i*1!3SH-M`"4S"fM3s>It #C"ZH2ju -dșt;LQGJpHIݻ-.vg83A LEyn4nh^K'WgW>m:p9Lwm(CSQ3M4}i4+DE"XS#'Mv4y3]T>MNor) !8"=.υ;zgTo,؊" :3&uyt󅨦G'щw=AOֽcŞwl8PcٍRyݨR}.v2 )쬿sq'=⯓t(!C&2f.~!A|DK?ELtDK{Ev7Q ě//^\$_ w;9xV_##(EOVaDYGCd Q_kwC-\^*@n!a?NzaҺVm,|t8IU,cF 2FHŒ4*بEfe"WHb1Ey`h=DvȵEXQdtq:z`+z4!N`ϑz- ly+qڠ/iy<_-Օ׎Ji$ /T-\:gφ ӡ"P|!zFBac l Dp9ܹ?wڽt1I;8@ө] %5&jfr =P\u ,&ԵUҤePA[™,xc2(OY)5 GΣ1 YqY]B1qW2q9be1\HUY9{Pw];¡-͈{vB]{p+jGx\|5cztjWtUjBҾKp- ;55h%p4 bpmMɺIFwJXWˊɈ -wM}*AR^$0M(S&$sdUN&G:t:yi/Jd|xu5a$yDx]&,֎%ڦ)OaOk/D#6(]`T;QDŽ.{FܯMm]sT? s)kcnΝmc*_#t,cE(uk!!PhMZqIMCPUf59 s'aJK7dUA2.iTYYM[PYM5j,7q*s].s$W®0j͉ϸ8$(n~N:n ?7Yu9tf]8Y jN?so8ޣ9?a7YqJڋąT('p-0#hx~ #!c%b̚\uB\H票 OM Mu>݄pi7{dBIsI1VL# =(a濭_ B&TiV5&P{*SǛlBҙ:}8wz2]td&tN!I /4$^iԒ! t1U{^Ҙ5c)˲@2!>k^RzrI¤}d7D&晰koP[7+ 5>--+ouQ '`oNƻc` 8Ji(8o⏘8 N^co*1=bG{(TBG`2-39pԢ[ΖȠI?f:DEe矞0Q95n4ʴb\F#~):[_z+ȊY_ҹr:#c"ċdd66 sh˂D}Rű>K1-߼8+r?#7Cdz飙dפ0 'E Ah(swx˹DHg$R nA.$_]K]^nFbT&j-,l}F_Q7_d >F7Vvɨ_u 3FT>\ sHg-0^=130'G#{}dPLN0M#ӗ,stO1g2NWklbͤ3)3ٛoEXI{&/meaYCm#sυz?d^YCUgQ}q՝r4'KpEUf2!}A Z"zr^\/"֋HKh.)"I֋Khyi}U5NȅڮJt4 lri.qO-AΒc<ohwUᵻMwmp]|mT$g+<'&엖:/)r&y>z3$L"tV&ȟWʬ 6b7 YhoBkIM^t,>hfBu*$a:Q&_c"8Ib5\I!D4KOv&$"Ig~D)O:lm6B5IZĪPnL Uz (T L&H>)ak`]IZ::K8IT|#$S!9L)"-nH\V ]J䯅LSm>G:$O"<x%!ˡD!SˡԋtO"cUԩ5M&xsU LzW2]IP¦";lݣQVm԰6mam egXveരó[pZHxnp ]p ׮ n{vF> (tJQo G-h5$q-ҨUԊ߁vg!4JKZDWKwCƊ<,H9gwNpq3;UAqPue$oATFڠ`Z*r(Oi(i(2E=#th -TKP|Od xi_x?/<&CBDֲHOڹjvM6a,y$|ܐG P}VTwꈴ?r&幨/ 5.1AjEϢ5 mlw,(g^#7{'&1,+"PoTJuۤDE$IEd^D₆*=%!w$p"JSQ0g65ȫty u+aK4|Zl,P *nLqP%Z;i/Zv">iz\4ܺyu\U [ (8D.aƢ㸀m5erԯDH2nvʣv ԻIO$yqyAd?ęA6.i>^"w/tPT2Vݚ\^lLwۧEz\d #^Lw'EN#Msܝw";3&IjI^Mw& M ۙͿMPR▉*$3MW_xٯa]k-,XS8Gbڻи, cM~:oSdoNޥpgp:G=JaC-QQ/=$.zXEN\҄;tEJO:ֱI h7C8u[qarujO׶v}tH:iqԢZ4K_{fԝ ydղA _Iђ:8CiKP߱_^vǓvB] `݄??zwo.WUo2hB#R!0}޴%.N4nEfRi7$xԌhWOȎ˝w!yF{k&F&HȤyyeצ2Io2㥢>}itBxZhQѕ36B?D!BikCd?DCd_'Bnv{|he^/ʕ [ l!MKӀICu[^ zS^&Ϧ jkq g:f(b!˼E$6X 2ɝƋe2x\`R $߮dwMn\vWojo[| Oo7-۔OUxmq>znԼ$Lm.w |܄pޜ"YDI$(/GڭYxiE"BB&.Zx!"B{݊-2hHg&Z[~jP0K5`ym/6݇m:m:m:mǡסŶ9T9T9T9T9TS8Nj:j:j:j:jNwzQttttXT8 9:#r?{4SK{A&piz1!צm'ZөB0Fk:F x=EfL/ы5&أ2f!2 BxM5"4`8$'7=lz9^sxM񚎩7K^E^kk{3zÐg;-enhرg٣Qt$ z2O^lxOCނȅh\25m6-l L*췕 3mɒF emll k@0C z z DFl7_X"՞AJY䑠7"47Lf}} SvWo ٭+(B:l^tɺM)v1LJp9} ZMJyp~(|Ո*,TBM > !Z c5zDFLM:䜈VKs"u ̙,\ij,d]9Ms\ChE!SwK*a'XOt`鵿BPң*\f.:$YO̗ 7~&??ˊd+y) c"TϚc=PToi"\BsL/4LbR +kP3!pz|,Z]a")ITGDhkk|Ɨ ae0ZdHNJ^" BHZ:J\"tD^R2IdF[}kK` 46+ n{BH^mVrܶgA~7%~f%YmVrۛ+8@fEYmVlۛڜ(Wtf Q^/iQYuE#lNxpg mf[靕f+Bd= uuoi̖VcYvVuW#ӗk'C$E}/Kv#&Dg rCӫUݶ%ou:ogY1Y,6D3%,vy־Evܵڏz pF ;J AbWr8IzҴ:j i8Kjk_iϵ:}v^>_ q9qѳ;#nT6%h#; I.:ii\xGg!; DK%\Ju!tBNty7i\g,rX.kƅ6D獺~=.c\dO'ٓNOҵ=8q_o1{q-ߔRkݗpZYz|X٥Sun=.e9rz6P %oo3qߌw3n7fHo܍Fjm6:o9mk3ggM%oOg|8QxרCPb>XxϯCz=N,E9<,-&iE)2zyP߮ $L#"f\KEz5akl۬y v 5 e~m`vS;4 'IWJsksk3k#F̫щ;k&xTCG5g"A.jJd4#hC4ng#D-X:3u@3RxKOd_x~?> H8^)lNo˥u^u~Rn_[Bc ~_;/-"2;dAd3NQ?ZQ"7/^lrكP&+}u?"+.)M(sxZz?%}gG[w鯉܌CpdjPU.r3ze)&c~tnעH$ӹEY!5n/@=0pU6 =cp9 +ݦ>~OS!`i4`l, 6 LL˜؅NRWRr߁l0l0+NN29ANƤ-;Mc7fE.53&+.2KZUğlBlBlBlBlBlBd0|MidY0IFmLpd7J?H˘`#SE3!E_0盙eJD-vĵlh~\Btp;FFF{Rj̲^xh8Z᳿~yxo HQ,I=1{&2Ө͞=1{6i5bLLImaوI!fhDݫa2.f&kوmf#Fl\f"Yضوm3-Kqx$`GH;F얍-/WBE,4-p"zke|'۱^VQr܅]{W eW˛S"Q;,76D.v먅T y5ENn  _8!Tldncuh^rX6]&B}&̤d"mu?mW6F eK8[ :,zxqW 4{Q|X &{Q|X f(>,O'b~: ȃ̐?,EȁX0UnEgxBbx|L>"$u|W>jӉ:*2C̚d_! & Yx,.ت\emKXx]E.^8ܬnVW7&+DR/fKft`/-rC^SfVN=g4fyt4rI$m[-#gD(aQ1 t̬n94rId~QRnx4:R:tBHYcbYypșL"NQ}IdąQ{S+lBcf_62"Pz_ofd=?q*ka kPBCͅ %.$Ϗȃh;]dĚvE6.3.2D1e2 ȂPXKEdNd%NY8#}谼Z i 2]TLhcser6BBCkkt73lT9aIgzU4+Jd mVfG=?+kbœz)(ԅij !db6EK=hNI~,FQDQJڣͤ3SBU&PENs" rt YeXj&r!ҒV9 B[~6MZbeKa=y8̬c7 lɔ)$5LK :kڝl'ypmmh.s{32:Tgh;eAx-ka3̅/\ YJasitzZ]ΡN(i`ᶿTQ q״ҿ.'U/NNFV6,]ۈP|gYxƘTxMê8"gAHH~SL슜d!C")<4 M Ni_?BK9Gd,' ȁl:o*;PM2\| PJOs:riȅKm89"̺_f =ՙ ccNWV Z҃%,$6[F"ZٶD6-#EO} BƁ^{I:ڄyxIgyn$rVCfk%h@tw$VŨL.덾y*>MS}\&_z:]Me-ʥ;@gYIW6Nk-N}'rTf"p4yot|/"Toͷ~%!Zۇ"&D?t!oͷ^$u442K~P7닒 aZלC,[.;"+.A(=#w8o7g $Oӝ^\4z8-S/f.i(qz^>jsjf>ʏ]u~,_iNT~Y*a4?":O/c'=hepY6_G^y+>`#HP[3jDċIȍI\מY_/3I 9#%["/*8ufaB2 y&Jwg}p}Z..P1t}Ve+W?G}JZ&rB#M1f 'Kr8=$M狌xI>-ZH<,d@4WB)IdBNԩ#B*CߒKg\z^Rp^˘ QMG Wӫ` TW=|:6 j>AXx 'Sxު-!g ,z9qy}w!#d aFN"Nڴq^bqLPd ˯*E|4AOXܨҡ@oBK@T,J,ݸ/|W ˀ0>1yut^݊K^H3mR&_:H]NRB܅k\FXsu̐/u࠷XG΁K'Mb$]|qIXRBy$(" /YBg8ERfl@:~<Mk`@fD.'5= f"Mbx,>0.Ν+-mGm-BE-јWlK2ݵGZxn,$}m{"C"\!q9쭋,J)bh#SA^hrMvd݄VӌYFvH#T;"4N q0m0m0mUv-Z/`q@B(v shoVߊ!*zz?oȥ+dL -V7q[1 %Ėmҵe}-N\ :bŵ-V\zk[m1b!gOt)%.,'q-&, >HbCFM$!oBY Ed4K5ZjL[M g%n!%$y& I Ee.(5_ ِ](Ib[WD^(Lґ Ȥ6Cb-ņ&l`+y͒:QPꦡ%I#6gIω!8&%3$= pADr䶮t `jv9RZךoaY|$BתDV)*_.@R")|S ExZ臇Jӭs^kP*E 'BVI?|фs.XM$ $rTJ1RavEh +HKh]캮 }(#W-Z"R$rpc-rk6!;a9*q"O׳,_ϒ|az>~g[*zlm^_{>VnQ7%ٯ^CGx ˧a-$y"tCK3hU KHSFψp:4/D^B>[D^ڜ]A'ekYqI %/rZHg aBOsdqL$uOYJxB1,΋,~eKF~4@d`ȃxۋ0Lo %ԻgKiXRq?NX(*NKKEDǨS5+]1!Jmu^8[Xڟ%߾0|!Qq9qtk=.zS$&=dҒm}Lޛy4E Eh7q Y+dC#v!twE(7Eh[-ޱ Nd1f~zvUw\ͨ>zPpK:! ,\Fm _} Kj[?OVDW@r>eS}(@(ܺ$& Dւ—fB:,)[aܣP-Q5j$v) u)v\p9%*5l}}&s3.kO<{؝كȥR\43fB`-ENNb%A}LHYI vvW_$yZG}\BBa!YHO:z9;{bmxU~ ^WU;x^cU;x^WU[~^%hw~^W;x^uU;xJ +5\.|G^#/ߑ;w;ΕM`|G^#/ߑw;y|G޹#ܑ7v ;y|Ht5:y=Gޞ#oϑȻr]9yW+Gޕ#ʑwȻrY:x TӚUij!Kt] ^)6 ӓtӮȃHUJDm6Q." iATG2DZdK-GՠMJX ]=Qq6 C# mȌ ;&K;VDI>JՎEv\(v"%&ϒ^2Zne-Q#Wk u#' QNv65 ]_ !Mkwi##H_B!ta!"8M{X(I:# fE\$'4JDh+%"Iyv,E"cbB:^?j7l:Cya\K]NXd/tLLVE#k$SK,c^滾-SXO;F{|7 J~##0M!CCx#./gn&u~gvDv\)kM ~4q}`t65iRz予>.6P߹gԓvg7ai4F0 8Cp8]_wю㥼ҩh>XU{p"e;JjBmBmG=-'*DRBI%rM(' }ޖQ \FZZZ I:Ʒ辣nBʃ1uI?htS\갇%Bڮ#btEyՅTʾ߾j_c!HpvwE;Iz]kV ߯2IpR0P8^  p; DŽt::8! x(g\Ǎ Қw+-r!4Q(oYG&-I0tR$ݩ]1ha49d*mRP}[0ܗDWjh +*+ыCsXLC\k3KMD^y_u׾I6(BFZHw[Ds1(B^=dӊ&y6'-KL&K7/)9Eog?:5=YJCzΟ/+$}?oppVk5qFxQQe!w*AV^!$㠾n qy'/?}k-^dlsQcs _/X3fr_)N^{g|혀X}a!Ԕ|R6W1 [~mRu"p;,S#*҆D^ OtDK߻# XR9mk#5{bs]?CHGuidChyޜK]"NMRB>M"d%4[ 9VBNQSry]J!KA:(|vѡ]X#Dm4.iqQ~EHmҷPl_H@$D?qёԇ}z4ᜆ >l&' It67g"9!ЅcTv<݋&`asxm83{l tX.(|_+Å w"?-Dd"?ٟOD'IDR"?˟O&$(q $/O'qN{eD&'W ֏-/%4?ʏ<h)A,h[aSSGyνo'Ro?=u4)ԓ*QugSRѥ9)nT! J%\JPgkJq:d=T)P )_MQvkX$DfȾ!H3^Jjr9r9wr9wRXyyyyy9 7Ln*9TrsD$*9TrsPY#$7Fn9rs %=nƸ1Y|$a5nӰ|b%ߟŧa_׿m Xūj}K2~7.>%zu{IwG2iX44+6i4icQRwZ7bX4P #V:I;XF|dz|]4|d)Y=jArTI:e}B }{{u%=[j4?ИVj4W}7xokj6L,m_#ĝun^#J ֍Oj8=ܾ0҆tj֚"+"B԰5^5YY<+- G2L߸`ȦR."uQ3q6%2:^tEEO`ٮ."ٷh:u#=R/ >F\\?e9, @L.<8,B6^zaw|u=,:Y:ʅ {"e!xZ$'PTRKMr> Aus=4Y".u'":M(rEZ V ʓɂ`f$##ŸeغH^^b.LqYXbƃtH{ĄA;$E.Y P'Гedy jk{ڎ-1'-fkn)]s!ʭ;͵[%/!ӑ=7A)n퇸ZRf.7E} DzRކya.iy\:#Z'"dj P0lbBE~DŽ;^IZ%jJ^(#Ql 6;8Z^dLʚ8lȤA<ґ@t):GܤRȢ/RRu4:| ڄtU_T_T_T_4_4_OH5~p| ,)\NGb|%:}78ner $Mx Ja̋HdR?m#7&xĒE\؏B"|iz[+/oz$BX-D-"CƀLB#Gf/JXNYF%,"kmW[[-jyۢy=n["M"Saܾʦrx(w?_B=geӶ褊]. =uB_H#BX~;oŘEd!'$)!xCt@\v-lF#, H^,|$;'g /وWzGw厐 |Ӽ6R$r ҈LJ;pD2(' eyQKNB(ا?#E#ĪKgXTT>ֻ+\$]\gXOp;}y>Õ)EFgo~:]~{C:_ۍqYBnhhOWdҰ#q"ץVH'e KgDfy^Ip'CtcEhvYt c+!H+^/Z?T'Dn%1C2fԞuI\Z=d@]]YA4B]ktVjIp:/?֕4e-L\)*Ǔm P;lB2Wa{-0I%qp!Ὄ63\$"jHZy\ 4iGXj\lhR.DB;bwhk?B:2&BzM$ zr1`!Bb!gK"/^NI$.#..7u7K[m" 3C{n/W\m,rE}" ׌ =-9\2dƋ)͗w i!kVu-z4r(6WƈpBz& CK~,{|\.=Tӹ$Kuaۨ򓶺ȢXG8ЋQ#TL$,K},[*"L財!6Ȣ눳Bp / p_)Znp:|YXr8c^IoW{@!uJ!˜1KVȅ츜>v6I2n>ȥkZiy RDj?UnA4-dQ2aL/5b}ķK)Mޡ^b :lr:KWPt$e*iBzINic1c1[Z=֚vꝬY@c 6`c 6`c 6`c 6`c 6`c 6`c 6`c 6ݔ*Zu&X! s%^kz-Ce =мE!Ɩ2[c`,2r/|I#g˨l-eTN9B,Fe˨l+ 0[qSc^w[+}AÕcu9$:r)\nK%B|_pIuKՄj]ƖBI%Ud8: R*B`?QV0dqi&)$Ko┥j2F{j!T{ !!7餜>ҹ)B_ԍ [PBvYo|vpڽ?.k3ݟ :ӜMW"mRv?i5^Džr'&e6KNgܖ$C[WS WB1l϶t{ 4K騱r&)_ CQ5FB\)_hL>!Pw(v&tsJf[c:N>oo܏=1|4 ˺8;f9͜Tf3i.Կ!^xN"wvu7sGfNKjMLnZv+riكbNnJ$|L=Ӿ!}zYv!$5q<|g]2dŅ'_>m$ B716]eބ -?HR])a8@yAxՒ8͡6\<_k-=4yZ}x^ 1Zyh7E,<=+CЬ<+EЬ<4+C|IbXy2V'cXy2d6*RSZIXy w>D Oʓd<+eԯ ] 2oe^+C['b(} PK}7Qڲ9Zyixsvډ;u!q5F%k>b-JE7 w@M:/(e5gSed||Z^}BBʞ;kbӿM]nTp뼀Q>j6Kf]~FV:?.;?&k3L}L7uF8 dlɁq4PG_ N+_' cܟz?=]vp9!y wעԋb;+J!2rҾ -^ī'rtDŽIs~'!^@qlnbͳ +V-y&nI O vyCH~:_LZ\Eb,l!#0,A#o&;.4Ú}P>L:~<7ZK+ x7n߿zp׳_m4c%QqQha} /쎯$,2_V˰Kk2 $lCyZ&MFHj)єEI h޴Sy^7TIM\zFV!XL-=5q2 mr?țtI/\jDPV;7zϞz_(~I1fk;ML$yN9q9;]$i M kTXֽ߯.hjxR8$`*$W ݻ"^x?̐ 59^N5?W:Ko gBDk5=iE^mIɅ*DX{ ).7x I sTݽ n7.y7nUm#^jeAK6^}|N9M JBfIzs)&M%$:Cgtx멕5l7u-A Id[bbGf'&Oy!kAG,qɈşv.79cٴM^Lhd)㛤`;ۛ2{P$5=Lo#=z&cIW|gx#&TЂlF7Y-BWū tI#A7I߄1=/>%2N!#IOhR8juΎ*ٴQ2?j:Af\c˴p; ViasM>~M P[:ULIߨ:-GKHU00-aNiNiPoZS{="jF/x͸/ċVH\F-;" Je_e;eeS`-"gBnMM`vԲٲH~HޢiiI^nXek!G Nc?3p9]mH5I, l8dlG3ekC!uCַ\]^b29Vmj~xA"95#J:?E.@(-B3 j_/,8> QBDY"~r{2Ln4l!hp׾}v4gقvwx͖ㄝT¹BUp7?dwmBQh3kXX~b$gBNVhUӼ䵓I Or$,ɦ߬.*ft\ !%: t% ƙИa3Q:̐zɺmT."o"ڧdmIz<号amE:W݉.|, g˲t=KB:Q/$Ry\B"Udlt4;by]!阶 ^چ h`,W4YD SdE!k}=V7dAoʨI8!JUS6@ˈ`c}(VdGXOL@Žj?KmOOӨnk9@wHGnk~·)_}:L~&lH&zjm'/ :L cYtf}&3^Jhֱg2(b"K$o|SB5:L 0<vuHձgrq K:DPMu ̐MIRJD=ՄkPMv ՆN= : b Igo(tZViӭ{хΧN[B&)6}Nf&f&;XW."ʮ=b7I)x(MzbHQ"6oFEځPx]`rE E"[LŢGtwzw/[ֲPeKC]xn #xP ^؅.чwoS{k7!cC(E({g!$ϋutg#9+/}E jX"+2 iFLsR0}H{g7Xd%>4!/Z{gi$"KaM7N ԗCzl ҰD=ci0ci0~x154.ԘB tC5X1lW14؂UI: ,2?2!-d~!3i 8E6%<:4.CkC}=!`% @@(`<4QPdZs[(pV^k6 #])Fg] mm]rقLjIRAMtDw?EV%H`)B[*h̗CI4K_;.22~dd ֟4*[U3j֟gյ,7yV]6ItxVatRa%v Yux>TL^jx!'^/knş߇kP밉lXXSkXPX3WR&K[?̈́7=+m4KtV3&rYFYJVdѼ46/ R3>a;C*oMN H2Kyp4kTVG*7.i.[8><?#B/K_Q吪Np<.N ~y]uZBs 7M&2/RYB2 &vxBt)f& rO;LRKlI2)إ!u)*?kơ= {d܄oȟˁd&2">ŠV,hfvA}U_[C{Bgy%Y?lpkpkp]v|}=XzPke_cp>kp>kQ|I.^ZYtj|"v^EEknG9e˦ҿ^jSGCYa mt[7ynKI-,sq29H@D]?944j?{j6MJ( S,mUDlJ 6*[ M&`jIUHC9`jYC  'HuiBhJ^k?r =.&~dCKFX&.=&5)5E !LX"zi#r3}6 ٤|RL5rF&x4KCIoId>/Yhu Nll8 .Y(FLW[#;m#;mǔӘpT+L2qOfӇaBy>O@>Ǔe3FlZ7JxNӺQÅl{ZJ>X3cJu:ҕRG k$𥕤OUsՙDVFFȍץ`ZĢ .Rj5bpR$f?QI-6-c"iOIu.m-x.^ȡ/̍ ZX"0T#"{0`M- l kjɑn&t#DkLTL䤡HvISǨ ) K>jˡ%t$9Y-/܎-›\B  :tR,(v ]I*Q\}T#GomrT;.r9oGKEVrB%S#E\l|87EGDh*F;c.2'uYGk+]$.-Xl0&.XКfθ;=C/Ż"kӆcKn> 7joB,c}plt%fɼ}pl.,||BbRooacS^o~+\T]x26v{Ӿ5yi HBRycm쬇w;ěɂ^6&r>cg=9h0>MHЋބtqY<,ځR 7g=\Sb!DZX*oN397b~cSq"t" x6BHy0P}rlN<,ؾFWO|yb6c[&Dߩl ǫ.>7|8np8nڱ+a1vXC[~_"q*MAsBs([ֱ8Yk唝Y ^Hby#y" '𺝿xmLʓʴ"9'G}tf#$xhwa"E,^=GyzA BX:> /.~ȩ"&0^5ң4ꅡcB [ eP/O腃"\ӏk=|p|S$(吅^ti56I-V..)5E+V\mJ|?G] &w)l 㸭Q#"iF)P<Ȇ$XR,<#15 cA{HIuC=5HBn:^wiB6d.ecc[ :K[Sd|NHY S>Ή0hNutrdI6S{xBgu*Ѭq]Sv<+]a͔lkvM:Txڂu<]R8^> Sn)?lLgHtDѷYȀD:"{TD_ҹD y#]$h}\&"ZMh˟m6fuz}f5ɍl&7Mnbܼ6qmr䦵Mk&7MnZܴ6imr䦵Mk&7MnZܴ?R]IC0͈PQkZ#"0|4#"#"+ n/z$")ƥVĒc7لF:ѳ# fC}d悵 f.X`m^{fUWm^eҷ` j0k3u^^6 >C.\b5Z؝$KX\8] I\'nßfC=Q;vp!uVfF#c9q!9i|ZUEa:@siP Wv͎AbM\Ҥ#eBbvȔb4{!.%2wͶEfH3)˰B%̛ 쯤aO 4rfԾC4ӜFpWD.c` Н~5:> sYfSrdYDKnx)r#97(.C!։"X22u/m1@:5Ꝃu;ґpS$YxvK!ly~nЫuۨY o:D o[oek6 7UdQW@mAHɆOip bL&ϕ}au\dz1nB$ ەUE"h@Y[;?X3q޿H5WO M6}¹g\F%?3e fDyN{$";""3䐠?T"x=xCbgąCHOfGAzCt$ݽɡ,ɥ@z7u#Qo㭋e-*H*೻ 5xg /Hf xh:9j"Ny؞0XX]OŠVާٸ̤#-=5OVG%L:d-tPz2Y!J-)9Uo}4oB1,!w+̉/$zAh]:hEM+퍂%bZ{c^kmkXp k鉥…sM~]F^K7_ZbꭋJYr?J$S̘3!Jm4!tRZ3BڮH/G#||_>/G#|>MIٟŗge>@,I_7\ۥé&.5 ^ugvפ#@1v+cRO^Qf5 {G7!N:5ׂx=\GkB^:G.rIgS.RX%Ԙ]M{ Mo]ӆ@6/wiB\&h](tz:ֽJ6؍RK$B^L|/Hwr|ȢQъ<\$\F|\kr]Eh`b/B}tt_U/By|ȡtLo(nO3-]Ahb=}=XfA)aY8C5>o6k/9dXOdX=Γf=l'ô>n13mf͌VCvH$eg̘ fȢ~_ϼgkz<3\g^ECkCCd>q;l_̸Gb%pyμgNQSe*ݛmgֲZ6R*i:'2JWkYJD9?]ܠgYp8M~j2ꐞiֲW!Z]"CӴj!4BBf-BE&D;+"HQK=4~DseNZ趈L:,Eӵ0seLeBGJ,Pn/ ջ OбeL \%7-NO ivSLyE}6S' jI3ˠM[Ef*]b5)ŋ_kK"rHY+ն f{? e 48.H" ڞIԫkN}EVtDPXy#]6=0=ͳc; E :\Q&{Px^ZZZZ(6/LR-LQ-LP-LP-LO-LO-WWW,NLt*o}db #ñ}}55dbjEy<ՊbUT+VVRؠZ1=,,cT+ƨD6,UT+VV.YJbjEyyEyy<Պ T++6VWyޭ?[e\~0J*ҪkB>nw:J/rjS5yNU!}l30oR+"5*tU6t(pL'}STJum!Rlbu:K6,a"ǙK_L(8e2eB&/d YB/d B/d B/d }E"s_HW$+<}E"O_W+y}E"F_W+b1}Ez"=_HW+BI?KgZa,X>'^]s},!_]anVn ܎'AIaYVx\^ (~x)VpRK$q$=i4"wFi" / DFFBh}ޠټ>dU^Z P MB4"iK/ Ehm h(;o Gj3ݗ v/RtcruP8 Xsaup8T \:[;g+DqPT|BXtyxIjiZLJ,v琅H!C")I1. t{w$GTtoB m"Avi_He1ۺY.p p]ۦo˩Apᚶ4BzﳈE4[&򜯷SpҢ_[7Vmv~ҪUAU[xq'=iPr^_Z"A(nE(oEv\.azk!xi/`/tlEmx~:oΡy~[DZ&+z6 ./%boaRK "-%M޵@m(l5t{7wovu[`oNnk7J5m%p^o+>[[x D(wkEn9Ί}kBExoVd\<Y3,7"+^ zOUZt{q*$ <;"gCR^GKg}lju[R*v~zee%2zVnm?\Ҙk]ka~RUytR/p>bB:*8!.E>XYD!VO1l)M$wߜ"B mU. 5ƕ]r5(RpP][~R.,nFKaw~2_*tKyT./R6޲^*B6c*2'HimLLi$li9ߐbB1T$wYI1%BK+^%Fx)';#@3JlZT${wΦEEi拔E/I*.bԳ;d/j٧QO*}IiuK:)}?泭)5VhmG :?$Ee]Z|?p.ǡ܇rzR@A9_. iK_\ZFD!lUjzHh`.B}lJdo(GH#%,PdzT}Vu3V}H iS29!7ÒZx6I%F[D)|:tܣl]lB@m>gܽ!ִD&!/iOmmY,b{Z7O;Ω;60Oj<"Ez)ba=Bʢ9Gm>kp:=+o]kí SoH8\iPJm3$BijiŠdNFZn6<,2dXgAN%I.e2 Ly4I1dX&ʑȁHȄXV!bh{> x^#M-S@,ҩt7n ?GVT ɿ1{ϪK"4m 0`(A!˟ n'M:A7c(P9M$AVٵVo ,,"㇒{V^S9@Bbv9<Ϙ>*]n- ݥS|S7E֦$yD.atJe:)j!ȊBVKyKh䦥!^7^MS"4O<;5=]NM&Ē|Sd%"o%̢^~UӐo/ajE""ѧކD(jܷ<28 +2SK k 2]y htt*lPWiUOG M򑡭x~Qt*lןn[ץCx2U/[yt*|z q/M6 s%LOåelyȠL%R#C4HEz !q! nkcX<;[" = \:}h["D-˸IE3a9vrx/P Ὧ3fa6fa6f`x `x `X 9^ 'U8xi)0]? 0}+w aj"3d2C򸤄+Ydd{L$gkvb̈́0;#`}P=tc(P>@I᫋g3._g p '*9V*r.hvEa:%3=N_.5sձLHK1fHOazbAzqS&˸QZUpSgZYDZqf '܃9۞-N'bADrÉ*%r(E 'QDp2=C/zI:StDp~R b"|P2y+44$$2g6' WZv- _D:(e$EQE}}\_W8oE}}޹~O8,."'-Ӌ("/ty- oD7omƅ:"|-b!Ȉ$𠨈oD7jeQND7bFv}#]߈,㯋vI`i$57eF].Z Ԛԙ%0WfZ:*fHBm\(Rr H"[- 523&زGcJ>TȮ}LjXR}#SS7T{sx쏠#t ‰Rj {,t|Uq0W32+_a^a^6[tE Ilc얼lhrhM yzE9x%oP!;cBƗ |\߯kgCg!pAlPS-lG4^OʚjQ]P8\&? ik|W4B秕pO*ߗ{5"@A0Q5.$ =Wd\ډoq j4 = ߯PFv4"\bԈ/8^ecO,alYsDIItká2Pcvu~k[O[6Yݸ@Mf1UJZRX ժ&9Ͳ,C*O*UomlZϳk2 ٮ"ÑyV2WH. E/_VZh#B|r+LRissp !=MIMD悤g8DIbIH/soﺶﺶݚOWFB{].v^;ΫP#խt}]쾪|du}].^{[;6.v_B#Qbu;i GJ;B&ς8nLnLnLDf.eHj(荱H؍ ؍Cl;;;;;2*o;;; ]ڜBMOB ~;N9\wxuk }گ|گ"G&\#<$d\H亚Mzp["r&;l:p>ߣ~~Mwv ru#>Hϥҁ$M!Ѽf^vntEVk! l2!xE֞śq͘  r"HzB&6FîMgo#Dkt5:-2v~̼Ou4!ܲ΋H3GaY鍕WOlΈY~fJg"ve{ŎbGv#؏] "pŞbOv'؏].cnb7v؋]b#dBuuEFK=K˱˱˱˱1TltVcKvcKvcKvcKvcK&lb#̬߯DL$FS7g7ff7ff7ff&¨{j=ڌuٍuYI{:7&d7c"#!M ۚCw[Cnkm BආPIzWa[CHx饆Wxw[ N/V?w#B%D "dnM\hI*(߈ "?Kk<[sT"DLH%  ZF"yĩn ZrJoT[ejb[[P5nmtkp@&"{YVIpm^#i; "R#dJM"SC$N$BW ӑ}&\gj\K~2o~7^]!.b"vtZUEuGFx]]qIkB_#xv1Lnq*oE+{wyˎNEH/j$a2"E> ؄K]\̍[7.H'ec P1%/Qo6!gwoe7Ҳx|{]87b-3 =OtltjDob{)|^}>PesAX|Q.nw";!/. A&gD>CHg'g G{9YZ"".j~CA,yNȅPO(=Ds[dSzX XWB|(pCZߩsr|{>B#c') j98)oD$I8ksI砼E3ZEq\r?ݩ 7K˄ЇT}'t%dk6))\`Uj ӹVT oSqߘ jɼ8L!$\)&ē(XLy4K\F][a2d 趮'0wRK.}k׽6x[_@pV~5@o 6 W8l^;pz^S?_Vޠ^+P7T[HzNIrLװI \dry~GOev.Ҿshlhm 4j:/bG*y}Q1xaaM7Z8w˰&hs< I'B5}X@%z}__j_xz䯯`1v||}=I__"+!~n> B6_VID*IGߝKhDO,Eʈ<%'{L䒪S2 '"wy;G9@cZ"Ϩ?.y±uI;تx4/lN?)gT\M9t~>[ckp5&B>qQ?ȃTU*}(" r!^"#!Iut탊y ~ݴUCȃt=0 8x'ِKR T;LӋۆ„"J7YO:)3%eWkBͬhtY*Tˇ8_J=G\|]F]?k6br!&V4vu*`KZ:U9˿HHmҩ"jH'[ .7ݩCB !.KȠ]]iA.C*B8+9 򨘜?B}6}޳&{֜q?Ԇo {-Tu5 nԳ&Dr҄b{8*"$BHԼөD9Mo&qI{+(K^HϤZtDʛɘ!&|1^RxQs VB27_29t9ZMo!}p}tRP;>* IIXK+ P"#!b3 yd2C. =U"d&գ%J8V&d&A!#\I>d&D%$u=B=C3=mDӡ4Mi UFq{xs:C˃chtg\gFT{}tyoNwoAڄPEP4*)w&sCܖ盐CW;>EYBHȥgZ5 TcrHEyX4\:'ЅL,qhhrNTu/CN609!, ־m;퀆Sx%\VW4!{4;qfZ&;'~Tfi5%~ǟ j;*wJ{DA͍)m·O"&9IYĄ:D0#b2riDGNwlN &r,r~_j7EvT= ȣo9I5F>~uf@4!U"rp>{t˹~k,?<.nF;jɮI>*j6^/˻ڒ=TjaVAm﵋Aee!~I+NTϲWvJVd%1IOQ&T3L&c+[K;nmݲ(\J O_AS& Зl=zN !-2#/BtXd ̾vBjߒ2Ef8OY -6k8ܫ2z#H3j{WХup:tiW0;ro:_~;C?yyuA[t^ou`BOʔ2C$cCyAO%h-9$THJπZ*)KY#lβi9K~\PdA3D?%p(dbVM}PN5B.a.%9)20鉓[ǯ# Lc.m` %B|vRǝ! BKMi7 ҪΚoJёxwC<,tȯvWe)!yp Aw;<VTB?pf#ןvx`Ptx Hsx<sx F97C.8y<<Nn[?On[:G(k$XTc%oٓ;Nnk;N>N8!N~|ԁɃ̏3!jNtUDfB0 "dhHA+,jjomE*H.CZ0*U~ YbX'T3$g<)YW(˶Ǘ< vca#U" Ų>\,," baY]D&·etuHe%t|l7 ,uQ|Wx `,"faYo+?.wyYYoK5r~g9YΫBmu O?<.IKRFK,7ʑ"Ndi m \gYwVV&9Y7:"Tu*~= YU#&I\xښnlm4( z0# pNH<k [ȉ]3/(E>6+ƃ9%鼈 }FDZdL6՘|gIJ?m2f|([T@yoړOOc̑?j(u& -LY]\Ry{Uql~arG $7"Wv&za mB<XJF={"=IٛC<^^z}SMo{)ވ׽,=u( cϤpZ,AՇEERdcBo'(쮈 RuT-Zܲ"rH2bҲҲbBYʚiٜiف\ w#$3qi֤5͡Aou6-n:~:{y(nٓ!7^f,SE޲]#r!,]#\I0,!HmuJ.5߿kρ$m0jIo|FjUtssv34wy|:HF8OߔӓLFȢ s} C _8KnhGl*y>F$n+m t!wRG4YzOȘ0:"Im31^?ƎaE#IYeByսEӽE^[$S_4^J5Hxz5_/deoi KwQapyoxM~L~e{?HY<Թ"ZҴԳ R:dBu ӳҳҳҳ"B#Գҳal@z]--i"zgs@!բ"(]Q=[,"jHS@s5eؘ:nͳ1K:Kwru5;jJYPtT i` xNb޽uB| .Eօ\RyH;Kzʲ"ieC^O.4wi!=Rk NsvJתȡ-Yzy;G3_Hգ^/3*"lC咎t" q}$23JkI$̩[]HꓩÒM2N:$_e&ifiil1ub.C1FҲr.TOݎ񌎧VTg+:LՇ%kݎT;{Jj?.L&e기;DΦ, :LFHuޛْْْى0[Rr&eIK-$٭٤٤:c @׆Q iQA ^4Y LoY?~igU}t{kT6Z7OBMBn ?&3$2ӎUMzB6e׳G.p&VrsGZl2@Л;Gj\BSuݳ#|8">=sF]Mi&tȳ.C΄T;ɵK#$z 49blQϫ2Te{r/}& Kq_( M>u԰>J.P܏B<?z}Mљ&3!:l8~n!{dlaxywlVuvaHjαĞlf]LLB!HPx\Mr6Sx_UvU搟V.#Y!"3W"\ihp\zJ[Iđ& G\S{44sd)2dѱo9_H._%D{W&T̻W&K++2]!!>SJr/qwh2d'f?7g̚n/8%5n_ᲆ/ToF?.BPھ?^^mz78y޼so޹7/V'~ A)KRI/2W{'×߼ڴBw&ˀLHb4}C+֥&2:d9BҜyO7, >~џ=_tg Ubmp9LI MMϒu ϏP|Mo^w|6txkTF2"TMMHm4$_ѱQǤU A>^KKK{K-!csw{cUc"GNsxD>Pվ۽yJ߹|rOoY&"tުr+P!ڨ-ljsުXH~*<1[Fު՜߯J!Tdҏ%ZD1>^C"BvydDhf2!DTQK# 0D=e"Gd2ESa7㗨 !Ċ6>TDת!H>w=aOT !s&DG6H"=-Geh~ԎGCY&j<ĻN7gOKlXHfN,X֍n==-GPQd> uSY+FJ-}`"z^4>]x:|tt jF ~qH,K#'#N,j`!II9D$Vw&! gK:!*q78\D Qy:jS?2$\7Ӹ}Nb5Z}]B;U' /F2|$,n#;mqi2B i+POBmV69D^)K{"B iB4s=kGP#M^:7yE%\&BkGLC đ1|D]ELM)=aS~=GDU3Ǵ1`rO5E"pPq2h YtR!X#ˊ12{1)1SNYB~VTuʘHdGTDzȥȗ /=;8]D:}c*!Q5!UFw ƒЂ#۪d)?=*Г=s2'aB !,\jhQc0 (jlG}TJ&:oHP190b \+FFFVV@ 3Dlj)[.1"q_7"hɽs؏E.g9^mj/$!f+36Puv0d`/q!]htkJXx.Q' #hK~MfBՈ#9;GC^lw:ȋɐY _8pI>z\R5$5^_6Wu,O7[5oui΅Gӷ0r]B#7dƦ!ˊΪM2!OH)rI-I:dsI[`"8'z#rrdKAgL&Etg"KR>qv8ǕyW?TVB,\Z :/JܼrVNbp<>U%ù \UNo~Ǘrb!T.s=Xlu)1G7C̄ 9 BO[/ooK|zRi@[RRt =fǷE,:";dm|;Yg3`v2.*"sQ7URHO%f-E(j"wPY9%LSz8re$B-hm.mlى#M%x.8i1B,z+p>LPS鴅\xrZHuJp8eϮ4 /IłY\^S2G \9Y E~PNY텆 5Ծ# [$}&8?:{0bBjOceRPᶏ dV2wKk~=?k"ZN {$)/Qta t: u+zg_ Z-}z ϥ!~h"  >Sz+!'/$=1'#ɥ^ChJ.i:bcǦT]0P9vǗVas:- \~{˽;v\?_o4ڈ W3\ur>!BM|HJ GU"If59I/Ŕeo"Ha'>%%OddW>AΒ7DjueTs?^[{cBIVO˅=W=:t D軭mکn|΁ d%Is)=Ҵ[*2S}qHJ?tiȠ]PId8rߌېLtTOJrogH :U"tnE.&Cә}2aZjDR&wTI]P68Onğ~*0O7>wR!Q0}Tx}]{9,5!KQ>OҧSNEq$O'Z6̄:7Ci;L ]L *N% ɱA{TWvc&M ;L&M ?>WRDBA]Α %}t2\[&\(vPAmhg9s$̑<"ieڣO 3z+Cd29g$xfݙ9wG󤍐!t:g;fF9g xf[.,,6 m, j[3^Bb[\8fAYPlfAYPlۂ-.^`lfAYPly5cAYP,(v; F+\+bgAYP,(v; փAրB^Y,vV;+Fr;wHϥ"?0,Cv!;cgY}>vV;c#aY}>v;Zcgq3oA*OB-O|j6+.Pwձ,GK׬6o˧YpR)C~5W#}5>W\dlEr $-#^_څ*[t&W]8[*uiY%_"rV}W*N:"$&oȼK W{y,B_Md}}7  \^e}:_"e;u _QKd}$bzTpi'g}Oòq0^pL>2ގ7Kp9_ *StE>d UH}`%_/u97h CȼG"+pIK9Hjin v(]sBz]CގZ6d\\o4"k^,#d2]8"tK_kG#D5ufؚ:,` $\g5}V[YkpuV@znɒ|+TNjKT\fiji͔V I"I9I~YD#۹5/Ĺ :Y]"ˠ̌J,q@iF񃯩oK.rySM8LQKn_צХnYcrR_uD|.]_6NSdsdAH#jvǥՃz . ZHx]zBB# ={F߼hPhO d[dQQ;$W2# G}/"^~Wd&o*Lj&hHd8kSW&^\)2ZA"-HKȄh;Hd$$D~'p9[%;³M*Ch=$#tM;Bgg?KegiLa ,).)L2E&t:I_gCY S/E ԸT\ld+"BS}%]yc-]S 6r6q6p H> %^8|j@&-h֐Vۃtjݠ"nc"㺈\ hS'ERv v\шlz#" w?᭡4#A&C{q<#ҹ$qHww4|.\3vT:\oMZyo֖@H]\G <;C&rp5JRwj|Yҷ쾊,Jf8z#KwI靿BztKBK'\eXB Y,x|lh 6_F}^_ FF}.M6n*) s@{t47 whtW{7ZB辛$snw"3!AHZoŋ\C&rs)tvTwTwwE-75ԦHOHR)bQQQQ!vtwTwTE(k"3! 7 v4w4wwEh7 vETOWjun9haO -΂x~oǓ8}P8 __;(W!ۥCVvPDH$p{H#[R25yj\g]-E&qt4DyG9_Uf"D=rkCw'dd@TDRH# zMx$yafv%νX~e,+J9aVOe/z.w~Rt_!$)|?|oDdt% K]GV+ p릕vAPE&4".1\y$H5t䏜3AhEș5ҝ8RBj˙f:$բJ1E%͵c^h(|-k}=d2n~?! ?{QM~T)M݌MKrOi/"K['lhs\!ODPf_sEFPxM_[n{<- UwmqW]rCVx}]J8\t8 NjX$ DDhρQQ¤&'XBV{<a@Ƿ|ڴޏLhgHKhTЦCi5mщt[6\"L VE,4'Ы>LGKA^d?ȥYl0+W'¼§UĂkzt n#8Ӊ5Nkn7_c[Epqa3n{tB*7qy\rtwt9;,t}gT;Dxܝ!2g: 僶Ǵ(g|!7j =ȥvTUW"MGhVM\ҎSl_ϙ/$!c$dC[EJ-mX0^?B5^"?E-"L>/[E!m=Eg/FǫUC>^zLo {=3mUP4P&ݹl_'p(P{=3ʊp (v<N;ޣ^&8$!1 =@?t*݂M388EVB~!"߄^鉶0x韉ɀ t'y^$E@Dp"?ܟO\~CDMl\޾.1^a~[8>׏BrP:Zx6 1c_۳"Ҳ$ʶF(ƢǨ_$."#ph7Մ^HOl o9a$(RשEV.-ojiE@$ݚ#oZ&D+薾O_ٻ!$ |<[Ib+ DPڙϩ}Y_Z-)oɺR^gܜHOY;Wi"a_zAMjYl$n $/rSMH` _Nʅ'x]`%E9kJ䐏h7ˠv)1#yrm} xlV87˨=BMmSNc 5 \D#GrYn8EW?#Ю|\)gLz=4BB_zEf !䬝eKAo{XÑ x+EyƂ_:HnTk݉-B=ό,7'z\!yϐ,m* ͅu_Y|ڤ5cGIc'MFH"3AS"2|HRDJyaڧ"ÝuynMFgq};~{o/S pz_z>zzWgvwG^6>*r?F:Ki^nFX#o" mi/w˝rC"rr] !?.̅2B { ?#EyE^>x^Y2_D.R˽[zҲԽ?[.ϖw}]Ghփ~P ._ɅAl|?̌EfWR&Em#DXd'䶐k"-e򱽱:-qúXGXs؝]mj굒F?u< m>xK8:x:\ʟ>^62q\%R++=yRi W̧j])SN|m /#GH閈X/ۥ?q'~P/'о|龪<[j|֦(G{WppiS6p:}UvL m!۲mq#79GHX]\I{<8%"ҭ׬Ra%yeE]`z9"dh % Eh5)L(b@+P,2X;֤>?+qce1ʥ.se/^ΕÖe Ͽy9wrlt9rg/^Λ7{9grάwv:2dJ["'yO=;ݢȠmPĠq/#}#iߨ1I{%$Uݩ1@0[p"=S!CDHnI͡"T"f ES+Z%8Ź/[Zz[)~ Nerru)^.q%](t \I 5'^rDp%wDV#rO"Y"Lh,ʒFFFNd"];Zܨߨߨ$F][hq#CQQ(pi,߫߉z?[o"tmdݸqK-Q7oߜ{-& ę Oⅸ-[7no߸qKZK6Er S OT"/>Nit_;3RB5zgn4:n4o4E.!r !4a3#9x3;}ˍ0FF#̿ԫgsUqd(-=2GWۨԱE9 f;(TV6?Jxv\n(υM*ӂE:e4Yߓcō2H[5KX!rG0EEƁtAd!C !ĎCd"VgFLI9d}v0`[^Yk+{P v[<}ﵣ:\^ X0_+Bv+r =͓Id^ NvEI>Kp/E,{+KIt{i ·]C[̄]ΰwrEhhSߦ#rJu$)gŔJhp;jW ý:(5VD)"NMnE8DBxBxBx0xlPY^^^*0S B; // h)/NHeY,_/EˢJ#Œ,qyw&;Z<-$1xZPzυeXH<ɈPx|.Ro}(}lgҴ&ruO~s(&5 vMfJ%KbzђM)V~!'B>ۄh-ڿk֖+T6k^JULs=(Br|.TZrK;5?d k>_iWTHGG=!;~ܴٴS&.idoZCdilj\~t&/dLr!:[;N Y."gݐG;7!A_R.Eץ5+U/T?Vn7õA5j񅽃8@Sa=󄄿:NpMFC=pwQr!􇕒E&=R'tD.V"ƚ")b+7D^Ҋ")$ȥ%cX7gifKc,2D,Hi?AxD M/tY؈\{x)<t~o%_eO˄Gd/IC[:d}˥Aݬ$'6JE^]$}$s\hKmBڶ`&sD_s~H> C޾hr_4٧hPgm)7u`[iZ [n)#EC3mT_Htzi>:2:*TMV|JT? j xOA+zOd ro*rUdЍ@VB.Րa}f1 I{%ID͑T6LYDche$BK{vk,r3?a| .)4gJOBd+r>UrVbO,tޒQ47U޲*pωSK U hY%:?CU GU ˗+Q^V*M}"Y|\hU޲Vi oQOr_$IIK<%\uDڂ!dH$z If=2\!G`&5BER$"}"IB\.ILڊ1arIGL3PULB눉(Eri&/~!4BM^;͑fե*MdĕoSm'?!+u+ -o|m;-.zm5XPmqfuzJ)KAS$|YRtChŘo#43Hz)?HrnĘE6]eyf3ER/ɍ`Sdghv"g6N*f HB!B/wz d :}UTO{=v;ކ4zl*lFx#*Ɓݐ)ËÛÛQsGݒn;{CޏޏޱǮJpW@"<kI/-/>DNB/-EѤn"ҩ!t5^}فyفyفy"1+z9K.'SBn{-?O/N_tf%5Zt3ؕ#b8yAxFc tf)|/q2__0^;{-/˧嵵vWuw}4>?+B=da4UWȗmlRYn|+,2;{rYrGۧDPguK5!J;)b/!]T2(/.F&-:Mjt_+V¸Q$ɽ[v*4}296KI{{r?~v^(cC٫F"kЙ; Vf޳ ֍c1!έ 5 ޳CBc'BcCl>Ć8*$_bć'YBobg/6C"M|&֋,D <Q#K-!NA> M"B*p׋-BhŦsÄ|N9|2!gi7Woz]";/16M&}b=|;z/y#l!Adt?K䑪)V/og߇߿wi|N].<^:#zLZw Nx*zʄ[/RKH 4L~=,hiKU2ŎuzG 4ڵəK}TCZ&c͑:ʲC.~؎Q-_'cl%"܍\~] ɷd!,YEU k}y^w%v{yi_S/$!NKKt-2d&88H2 \ _HBxɹMRK_Hm|]V&{1IEJmr\kEҥ) # eImhտfĒK.>aMp,phkv%S ǷAǯx q|%pSi>@{s~}z|}vpJ$=ݑ!!IU/NHnBS 0=@Ydx9O:yư!K>1*a}Tl{Ϟٌ!y4"BzDf2Woz}Óu7s007<>B(7arcɘ!;$%W#duqgʄ`Wӌ:p~ry7"8:lc81$.hR)* op xwrjD8~Xq!TM"moZ?V !d ,,=y=$6՗"qwmr!?GZ"hdCz$xu?M薞1޳ NCJ 5N/QZ<6I4۵}dܾ(:p\C8nRN"$ɿ8#$e\M_#e!'ǤwYԹ[}ڀJc 5;gCK{$d'i&XiY 'uV45ӑ:e(GVY۷[T<<l?ZEՑpso:Bk+Kqz\DHdCy|&maХmKZ"k!dx\R]U鱍<7 :Yj/eId099VAi97r n2tі pEId>!\9du27ӊq[~~Ձ.˨Jy]v[_[#ߗwN1&C4ǯuER_ȃlJh~8BvڗT磈sEEMG5~OJ;!2{;DZ&^^^^n//"IrMs|WU/_D/_D/ٳe}LQF:-f@fB&qw 86}Vq_cXapzz>Bd&$U@=c~M'B*Xh*󇵝]XZ r97:Є_/}4u2Aۃ4Qg)HfH^*k&Q*k"v 1htLB>n4")kf3ZI\gM?v6])%6!Q/%6Rb3 GJl"fB':׳>ԡ*WKɜ?ζrBzX4W+ 8oy+~P͛p:7&xez|f&Km$n* H# ?/'DuϷCw"˵a&"Wk<k"|AfB$9vd\z\ ozpJiIݴ:>Od7>R~#p-\v:rPO%.)_ҾFBʿyC FQu»{[! 騞KM:CΙ(W$2Mkzh 'npPr"nߝBH*{$3./AHBn a&|;!99223AzOYޙK<@T;ܛ\B{i'ʺ Z$ 5vp$> p8\vmx1[HZ̶U9MNDf5q5-m6XNP%/EI⥢ȦtC"9R1-K8^Nx,Ld~!tԎ}|r&M @۴i"K(?י%-$/A@kӂRKHVHuۦH@Zx/iq: H As-GbKRMri&B&d"_H:}]ZDK3,jH+$DϦ-IKO*6đWdLd57!b`2Wa!#X,B-aMǂ6} I!N7w2Q;k2;"_3AM$zv"Ý 7]Z~R:8q}j)RWth!PMz(eͤIBvs'4G*ymH5=deTm` J ̐ ̐2O*?\Ϳ%-\.3ٹ>8gflL 7׏񌩣tA[Cx[gjYrrBomHFp,Ƴ:7EϺmG Mn qfdFTSfݶ g(6Y4I94ф( 0:`?I}܍p^&oN~_]q˕W :_mڄKL|lN zHc)7U&#BKڢ*rJe2Cmr[kB1rVg$Z)4ځr;#DZiCwLRHdm71IYr[k22my-m>1C K"}:R63)_Y?_iEZY-/!{Pģ2Ր}.#NEz Y B'#?l -Mꄬ̱E+D"kɰz$e۫B<*t^!=oՓSa>Awmzv=9 nnm.puE ˑZe͕q-\.G IPݰ;!z";snP!͟4r3NfUs l29dA*y11a2ʝ avioI&f;uY&p m -d3ثef' ~MLo&w?~Z"҇GVj`ʹZ,(.$\&8/)^$j? kPu_&V Qr!9\U wE !gH'j郄<"my#CD6JL[DY,YZk!QθѿEzLd6ɵ45!$& E躞xN>;9K~?egSXJ3CjK񴒪djNQjV/|@tT\G"^{T8zpwN 5j>ƻÚFyD|l˾=H>:I A"}(/"+!zd< 풽lAmYF4M(--)ܾ.YӞZJ$܅%)w&C}clYͱgAuDŽ8[BC='d:0#ɎIH\;#v`wFm8\/l/u-S kHt{XCnTnw~~ewvGs:ҨAPf~&D^AՇ.ZdkK}ܡei.Hy,<:uҮsVN;7dQ,kh?kL^7\ h e"rVtEo1E3$(hrVLM{&XkDGS2qHY[x;LH yjLj| GP|%ZBrzp < %gaw|O8sx?{Q/d_!وםmQ3y$_ AHv}20H*r\V¬7CIGEVxPT$d8Gnc* rab4m R)I@Xx$և@wǑ]__!e97ߊuzRN0ߤPLt/<.4{-C>ԲG5iأEM[BoQ#-HzjPdP|P&KCY&#Τ mJ2!"7Rgi ;MN/3I{¥8oydP9&ӽ]}og&gb~E}Qg٭"$AJv˲o[*e]߶2w1Ǔo[ ?j-vܶ+K|ivWWw⮰ϴc\i!6&, ƚNIuƚoƚNh$!%1#:M rIm '>8~ĕ=jr;<ӴW 3/BIm*3ʬh ;<|ҟGi3יrAƅYDnk3Kd/NU3^5 AB7ʣs9t:yiN>"D^Ϧۦkl&)Bd>%S_d/k&-| 1N 2{Ct h;~.PպuËVk"L."+.:&d|,?o:j3?j?o._faszϛz>oR6 Ng/Ƞ 46"n˿"X >hwEB>3E}9հxaf "tERym5Pģ(6dO NmF=ԌH"\+(||VU.gHUT7eȅܦå2>KTbk*hZx}]ǡtBDeWu]H"/ҹ$EK5v-JH}='8t\Cd"KzGwߐDʞd"K^(y?p{GPr>E.$_id.#j \F>ka~}݆"%%BY]/[":i|hg`B֡(o.hk9-/M ɅZXmq$ )]"b2d\:N"8Y(B/ 9xQutS2ctknM!TT2Ԛq]2^r]tIoLݑ ^s:ooBFl["vDPE^ qL$AdYCʈL9(T#Fg"°x[zk[cA:Nޣ%r:3$6!A-Ӕ݁BRiX8:oMYv 5Bb^_Bӗ般F#*YoGE2"uD~D?".%IEȧk3LK'ȏ_2B-֋B$%tcؕL(K*ʞ֑>9lӺq-9grp8-FIѝ?ԲB~wrpu_u?rvL֬"U~!4 S2NPu`6V"3/^o\H*r].rB\ 뮉̐G6$a'fYm,y  GB/ 5(bX,8~ 7w'B5%rxI#$ܷ5 .zb&dk0C*W-"\7bCkX,RV5+K OO}x;dv!'9BM%/%tLSIMIl%u:T9bm37)Rq߲I*$|}K:{}$*⧖D!oS/."gC&x $l^ZME%oaė~1=7DŽH{)yJ22amQuVZXQGnTƱ+@l8;:C|lH?JѿNٱ[EzȿJsM| 2IargE^!?+J7G eENhܨ}JOI$W"EhE[iTC~W4e$2a_r o3!vD'!"7o*/ Rɘv }b~(M i_&",J&]܄R;6apAEՁȃđY$.ָ*ƵqVQUk/Qx)Myp81A~k_S"LɴpN!r\?>|^|QBBM, 3!RٮX_d~KC^;k2܉, Ox',+=[]gkB=1 {Zx>p,oއh=+\w=Ტ6zzzIvXd8Ad\LxiWI"G;^d/2'&+qciK)KEidS/MoHsS-c2(6đMB2ô$VE$" E&%r!sCa2}2V\Jd Y9DdMzJ]3Ԍ$(ژT:]~3VND?/܎/Naw9p^GDnOtgtgt燳B&ᒼe2e@d&atu#        ˨T`T`T`T!̀ Ebnx`x`x@YV3V3V3V"63 0cW0?2\)}Н8;i4yg t4L2"3;Bi:a6EȂi4\>!;/DNݚ;E!"R ҳwХB2Su@q3$-$!eh>e)V@~^M֪:/"t4v7䯕'GVxõ(~ڨ|Byp }B"KR7!_"VfpKAOY Mq-@D&urHz-SVhq!B42!'8$NŅH%%) B.gKYZRy!2gƴ)+"IŅ zt3'LeG뎙Yff)2^o2s$ g\gW$qZ)SC/RNd~P^d&m"ĉǗF\_kB#AT8FE65:|jո洛"3-d'EN =ڋ[MI/A +G2Ud%2sDQ7&y)Qj2nO9"hL^紱ߜC<'/kxr|WnDېHv>g^URwnr\Etμ&p"z/M)Qu#*q8Tф6U"\cT{^Wxsx -srwNز2^!<"Kÿ"| BKR5 r/}iSdEy*aRʒ t0EY֘"e"osi0=@ƅ\g(0ZvR_$;g&x%jDXϴ3fr֮Tz#-_O>[Cǵ4 ~ 8$՛)u9?iϝٷQU<-*׍6>q:7NԔF; ޝ%ay c<6(g&D|P BDpmA/nUv;QM33j[K#GLWۺ"TGH>7αA|>p;ȗ|y _O|ynN Ld?\/kE.e-gͣ zypJO zyL<&o7ś;vTy-ڢ($* FIdC "[\۩w/D.dXD"KpI{QrȅXؽP&K|lZg%g^< ]fj'^ _l6J޸]7ђ t2=gu%: *o/B٤!*$?X I&t9{C.G9BvKq}LD£[Ą4i`Kh"6IFR 4VL.w=V +N7NZ*=qB(BaNIRYZ"I%SZ֠)2V+SL^Ozښ"Tr2$BXW"IiRXM ~x5ib5*!JO\QPZ 7^ ԬRQ8)Ej6(:? IHJ⇒ ^ŅץbQ\T,վYB!aBH."Δ9j(O YD΄Ƀ$XtG"ҥZ CbZkCPy3>SdrҮ"閛)PIg}G黙QlK>df[ϴ[3މ"ק"7h#4![!¬1"j`jnBuuk6T-r]rEu|Wfj6R xX}ٮIBN<oU=NA:Z]:D"TUէ!VL-"QCBrl!䣯B#e z *2C*o5aqthKvXɰqٕ7@KwqL^ .^%Ȱűم||v}}|񋐸 %Dz:D$ZBe'^dOv>(2CV.]2> N,kPCuxum|l*BA5>B&k`c;?nrʡkJ ۿ4v[pKፚ+PoOng|]* +]2mӷ8`M4hU/+rRZ3Dh7HYFSzC$$jj倀"/rRȢGwyId_ȥUȻ!IgD\Jkb(Bo{hW~kiov-o. |^,+qw)+t|m7m*s-6j[x"|L hVAsڦ#oӊB4؊A%&i=qV !ERVQm"LΓ~Ȥ5!{"a&73!MhKΏ~"s8rOva$T'D"I*rYk!&nWeL=zZo:imz޶Js:6kmݕR)ܾlրJྲྀ Zpܬ7kZpܬ7"/L|"@%Zpg-1伿 Ƞb^, 7 tV^d%.!Y8,7fK" "^6I"z" KcBe|l"u&[cB-e~y/"5&wNO:Da՚4E(yu3h-OO>m/th%d ND!_DE&ey"Ҹ$˓uuWK؆Xl?,Zq ؆XlC{Uz?\um؎XlC,!m6baeaeA+"I}Nõ!Q?04ُЋĊ+uiZt(D!K[+["뼰uBHw彍{iiiiaB³z֭:\zA=?˧'Js~~藯z+D^{CV|DZs<"eىX 䇦NJ.P8\/_/CuRgڟ;7r F~_|]<9~__\W[ /8~kMTH2,$ڟYRa5gK̐u!y3Jp/B}-o )BV NȠ8҉ڒ<2$򻮏5Dhp(7N"pIbq Twz֪P[$t_P1kI9đ7% %(dC(kfFxP ލ]լr~>nHrRE^߀gȰ7RuIDJztD72Zmd{}nd˨F&ףr#--tZodF6*5J##Hwg],iї&68Kwd"EKdy=҉Z;TwZDx(KWFBߝN k}&t'`&`Bm|N~/><ك ?XHzy[+<h]#|׉,ZϹ=2%G#sj9esaKYH< )ox]1@W[rrt;:0}Ca'/җ޸/hL$etTD&Er&Bzf|/컐A 챙HI}Иce%VNBp*6z#=.F]؜۲-{6,\t^ .|nd AFн72[dsX# PCM\RuZg=T|G*nB%(^ ]y'o"[zFn#g رt}G#T;Sf?"t w"|f y}g1>r}Z2*ܾJ>AӖ>"XxR3(8V *:dR<-tn!4h^\B:9VEG{"4)ASdsIJ&+ gC,I`%LB,&\7"$|D>u".Έ;yDt"W:'|МS %$M澈GBko4>cw|?M{ PM<}M zp9RytȁH^gڰo "E!dyJ<.>HKCd;bi_˲e:^''o4D.GͣFpq/&u餩(~pe7)V||#>˺3n_R|dTrjgOvvWQ}(WGB,ɷ'&66C H#N~O&I=EUmo_^> bѭ^RkbCqӑ" }%OAD\g D.qڃHQZdj@G####qX!J _>TgOnM(v `CWa?尟RX W3䰯r(uKg7ǵ̃aĬdddDdB{{Rczbt dfKI([!X!PJNL NL NL N, NTDUaD8ɦȉ+o.bB6YIlh鈽ԃ4?NźYv.BSsa= 'AX^²x3 ':XHHV8~w_{/i<6E}(Y9nđz.PLc0B%N=jBP LV$IdDgBY-0mB/my4da""ُqMB01=sЏqK[=3gJZ:&”+UÿHT5={ԥs'vؽ9K?)…$[׹:wΝaN)h>ZN.ܮ&B,٨N.~Eq9Dz^ԣ㻯눤#~,cD\FdnÞ#eyJrCaNBҊjtznΚGdhsrZHOiU YL65否_cfy9trƱŭYv|rرH# #8CCΧO@ ;>Χ \u<7r ujs ;.|v>C찚ߩ@_[NogE/ḱ0/|^tÙgdxw,l)|&z3g:n);Y9ݡ~TLZvNID΀n^mİɯ'kJV#)YxNJBk^< 6!P8.rKZK:Mю 5)Yb%Dhhވ/]DɉȠM_D7MI^* 奁=DZBfBa>lmB_z . iB'-y"8d&&!mlAW$JاKW})4-µ,$_5 'm/_U{9&Na)ɁM+4oz:I@Cņ&Ù8^EhŁE$Y%i tr-N= En#(E:K 5_y)ҿPP3#Uz گ44kP-#|xne{PC- ,/)zs64/4m6 l˨mCvBHFZx"2==NZ7{.ܤDф;I˼/iBQnQnQLc ,~OY#;AOF!g!o6Mn6MD!Cl\gEM/dɤ !;sWKE56#mm;$B.r6j_PvǗpPC9,)l>~j˺]wXE.|&&BӚzȀ<oC*ˋP|Rg/dnrC8"C CZ9\J#7"ltBlev0ҢvnuK8/P'@Wesk,1_5֕ ־Xarx뾑XUݲY,Gח BG,riD&tdɍeH'Πbm&d(M"Z oVnlDOfKj9T6D.GdY:Ɲ0ߘ&?BA<#Er0C3?B>= M5WkKaBoUtyG.^?+坾T8* #Yx[ER#~ә{")W{I D[{"^X7DR&Pk2"W5 Y r}0*ݫ"II yojK BmKK%bLs1)\Gww}u1\k.5PPPQŨF^cTs1ܘܘܘPk۰{ZJ)$BkZm#tt0-w'O7f("w@hPDf !)vk6G(6+"m{{o=޷xӾ=ާ-|7u7Zq_.O.G{o+tڷ-<.G;kV!s\ɥđ[]"xVd!chQOvHo!#$Ktw;viE6u֞%{؁VˀkU.=VRdۅSfT-vJەHvvat]x}]-B I_D: y}ҋ4RuJ2"Y{o^M${6K2đȦ>RiqߋrX1[d.vaGvF"K+JBD+`Լ|4q9@p\(܎ ~[ TG9;wbU/s%ū=Qx'r.軧!+ki2IwhNyθC d)T" I.+.M:E,Ƌs2 i47Z]) I*M 4#?'{?O[O^UƓx:q^G/| :v8n\|$B/,د݇>\d ]鳨 åQpATY Q|mo.|.}_U= iJd;/MhC{&"9D"[Z]g̐C!T }?"sTR(3{,E8rm-AEv:W>nV=sxP]Ρگ:۽eMos<h!L\goGd:Cdduʓƿ.B c~T Na;Bk mR8^(uV!np%A6DaD>I!~?7HYG&MN)n!#d%եV+r>]gjuǓq v&ٜ#2c'_V:oUoUx|AFŇww,-|N/cB}TNo^v|@itz ]GwuTE&;hB7 ׈?TO& =dA8|MM#;萋<A>,2riPCɇ_X8I ӟg%(Ÿ{'_y'_y'i"ԨԹtzX,2Cvy59P#ivOixFtE6$Iw/G@"K'tɂl "E&4n!nϔ6Iȅ åE΂ 7y<#Y)k?r!ک}I^nrlb(2>E4!+rg$,D^BS)KZ"|6XD>: )ݯ{X\T.·Mu_ƾKtS|Owv탎wj4=ČnU5)9>oH )G &A!/4r'ɂtt)ٚ!BL5fJ%mwNY'5CMe8;!I^WI!.z0@`O ,qYBlrLOH}2?lK &L8}J4p7iY/&[ ƹ\5)5o_;:oP!FUZChq:l2+4ܢ/f2\Jrh7׆%~ TwM/9tGrIMFmg[edIa(ʄP8Ol[ .< Cx__\ '\|id0<Wg̏f2Vs@uJqOqT䅻q v5zNZ Wjp;.q >m7Kn{nqM'Pϐ  S5ϫ8=9;jnG>SxK,VWxXD@ 4%Ĕĺ>`iUF |-6e>[bo]?6aPmY7)$dy_>d3cc@e9 Gf(=f.Q?S_Rgc0QYGm9\V-4㪇~d۠KokQυ+ȭzw7luԫӝ9r7A3)59j\pkҷen'?CEu-6'J+[  sQnH~AΒdg}h!GGWxձ+LBRy\u+%y$U}Ճxty>I{gx9y=<~owabL}qAɤٍFuju\iZO/\iCԖ|wSRܟ[kTq'xr L7S9 _({*+2Lwb0j;n4Ԉx髰7 "CZ%%\2 s›$ C譫u*% 9î^Wë$ӭ|z]=<IՏCVX !wzȕ-ΐd}3?/OՓC=|T^?!8FE,5~B^?!t?zT^?*׏:Ux}zD>=ԋ Oǻӣ @3|==ԇ /ùzzd==QA}@Ghz^_|~Z~!tɍSe\;|^;|^|~<*!3$[;Ge p9|îm#0P^K1)'3p>#r\u,#P8&pIs7zlmԩvH2^7/>o ԒƷSp99rPdW9 g۹Q|,p*C`CPqPFNAe pp\ٓ\ԍ9o ztY02 W]ϐfJA$k8tgΩqS=6zw{ 2\'h,Q'LqDr @c)N-PGPsJ7Gy)H:>DƇ(y}:Fa. 2 /Q2 ^GK.UCc)-I2_l SlD!Ur-VCT،C<(x%_ށ&bFixR^5@Pe)#PŰ3dH KH KGy$O>Zt)NX)wܵ98/ؓ 6v|E2(喇z݀PY?@'800L%䡼%Ӓ*/pK^Y9}[2)>s<Kn{SX{ 4jS5槪/:cAŹr=սЁPᄊ 0j  [V$$'Z1>=PeÅMdBr^LU>'^?c9F=*t)9eisƲ4VV(덧hЀ P y^xZ, p'CR#{-TU P <DzS|BK|[<`+|JKO r2/Y u8I֧%yO&'N,<2S+uKP.K?q&ZɿP:~BZ,}̏oE Ij$2ZI&'N2B24G%Dv@yM/"ˊ}M:8҈s2Jz$BP*oe`8DcE-& uI05ܜt m8}M/Vd%HT*~\RTK3N) MZR-Ǥc+뤯!/ 3?,+1J̬MYǕ GehAZWlJVW7TfPy٪E:WK.Uk1+4%'á]zRջ<Z;U3 O,y2]CV8U}8C^„ tB\DP]B8XIwxL|XNBg`TlҰq p4'Bc:^1(95Ԅe=>ԃd:A$~%zO%Tt[w0V<| T}8?U9s*X/(Ag*yYTT_(%՗ y84 2wA]@e%/^͟r?yTq*ޔT pYQvUj 5 !vQh&K20' 6Jc$~BN!r+o%S|._0ǘ/VsJ^z`MgbOfNSUJ2\RO,U ` yEs?2\1|3(Nn: Cu(vFP i XGɤ8 J:\x1 zs--$q}y.*MQb&.7E嵒!~*Pxj|K8m{qIÒuIt͒@?V0}"\zMF ״R xqyv py;ƚô.LxLz]ҟyntO LE 鹤1pKo9w[̚/5mAMF@jj7V Ь[-`(2&Pjssbn[M5f1aCy+&sSݢd2VX5~Qr0?셖,1?۪C͢wR9`9d;q\P5SQ0"*PbnRz5 ЅB g`tzKan}{:j)؃`'J{!g<.yN`fzd37xAsm"%N55Ap/aȜ$lS{;!b7Jn еkH~d1/,& #( P(;J%'rP9L=ylQr~(9rFB|IuHg&gPc'9t,j7  Ra*X`\wu,GuN-敎`}/=A ǘ?+ ot'PjLxyde%iUi5iiii]*ՑGhy)U[</Y`KSN9K6)Ts9g.5y9yNT8gKXu2;\O=So#H&%cSFI:N=IJ^z>' Y.uã/=!s2n)~4W!U)0(6M?nS.Jꨁ z@|B9e50ӏҤt6i)g=\ ZwJu\q­i}_lۮawe]IRB9}^룑W`90ZJj56e*lT0*} <]b);%peMm;_Jýl@"Ѵ Uy;FV`mCUT=9+:AmA,MO"cA*54"(Cր1\[Jb ߕ{@x^<}K0[}7NϽ\4֐e)` MC~ zC p- J]x66U m.TXT+?u/~Zڲdɧǁ fs:Xv=P'8\@Bu=X!)Y/%ќӔ(O ?CX㬙-q YIH+-55dR2?Ӓ NK8%lQT,D@rTU͐)u/S #c`4KPd,bL\ %ʵn~jN9"LhP)a!Nh`u V3WmY2K?jݷorhs%Oƃx.t.+ynG }_{?嗋ت-U'8%՞nxX%V:R`ɅZrX: \%7@}KaP}^8px,tB^ZAG4BπC0qNՐ>JT4ӝ0MX۠}-%#V)T_PI&c'J_0~s!U~Wa]r1mkK`Հ #Au/]kUeYNN'ɓn`ϡX(.\ :8yQ(/e!k*9%~Xof4t i)O;O[V̟ӽ$ñV:~h巌dXN/yXޛlܒ7#]!)x.v߆a//aGǹ_`wT!㩧 D,}~y~wQ@T+t*rT #W@( wz}ywԊ p;J>.xttͥSd~*0 GYT|DX ! fCjww6KKڀlEnV ؊ e=ԥP~ * ڎP MT\<`Bw!j׉u?Z[g NM%?j g-qAezTHZ I Jb?ZC$?M(f'1&pII躕T}pX o5Վp/.qI ꆱ.*b*O'x2Ph 3(9T ϣï'7!ϟ_O*mM*a.<@ lΉw]q!OҮ R㗍5gH3ģ"-P#ǵژ|tplU:j7CrsvH};$7YK>JnC T'}D$r"\upܟ"}H;?.·鯒J.D<55Ob@*r>x—[ыa@C0?=!q=mjmjAu?uZ# ᐧpba`yB|^ uGH9E3=uF\] ]F2y%%K?p7' Yn"(~\E#/4Sw+2X>s.x=d X7>'WA6|L;O'K˒zfʏ7Ub1 8XX@`рa OpנT&s:kBd/JL,).~C>H~9$+K{qE TRr?KN^ŕq-T=RVg'<*rw8t}/-(.su5}_n?*kG{ipJy EtPɱ؆`[ [:Å*S}8M=ؽqr:e:^~.UM[Q]r2>T?J*?:؎[,d hqC|cFƟ|ƪ,(m+uG@0Ft08F$O!(]NRT6wOz)pAoC2K%'0/o&Z[Uy<X潽MPtrXB'4ro ELOԫs\{%,l'Ѡy3VgN4WO]ޘPoj; -p ܒ`l zC1%|<~nb|Cq%> 1~}Pʲw-K&$%q)g<ogU#GЇpleaJƃ>);Hsd=ޔd<|uT"PROp@yຳ;N,^ڂFy PmAS\a 0 k#!*@Pr<u>KΠQu}TAT%?9W2! :I,V:+y)>LJd1U)\r1xLBs:d:6c:9QGɱۂRmb Re15~4:[DQt^0Fn lSl pxr X(> j<@M ?<'n2Ln^A2 ɐ!hZrͫpB(,!<%j1 %UNW{j# .ƙ'PsT;V>5Ku ]0,E.Y[5Ƃ#XW_7ZVzܿB܂tKavLA]/:4(zTyh&(~ `;:?iqդ$xd2Fp|WM*ۏb,vó$W5% ,ם)V|V,¡˰KYC%ogPG|#9ԉsY?K[〡TMo[giYf@Ȥ/i%=*L{ϒsz fLW.acCa X̉g ''' )tdpPs8g@n]tdÃTДmO ?8hf}G[=Ǘ=3=ˠPplU{;G _9ˠaG*][PV'`5yV?Q+,%."Vr֐'h YRfʅ#@G`@IU!{HjtR-[j -$qW@,$OqN3cj3Hyj ng| pUyN A2T:!j Jv=Qu2# jӌϹX z.@w;^w;OIsuǹ\驢sHꯐ;՝Rj3tuG#]ݑ x\-j-p XXSRmM\kuI,~ԥ\:7{:{tlI|<X2yy<Dztwt*mIÑ_dRHïGgZGI{|-Z: sꌩh0 P{ 8KNu܉*"CC#C}Ha@X sBKmƟM 94ZA n ̙Ȁ83ƥ[[=K-˩cܣ.Y^ Iܦp:)}n vVۥĴxP;Z{ %Aups>asF@<:,vl\:_$)${.?a+C~kAC|`% PI߬h+ޚϥsEx<MiD@OOqZ1ƍ,n 8Z0}I-[ro|JGʆz!/hSzd|ƇoIU|"_P!ߐoz|y|b&VEyR䭖pA0 aH. sթTLju^@(7u 'aݰn +wszs:av2[[iPUr<5tÞ~~~c!xXm zKAˇtV:6t8m ZAWjt堓t(xР)nI*'DƠDr`:U- mPiP!<ť+( oS>s!vV>pW5/pp|T(C<+h|28Q'jtYT:Ԏ!w@ >ͨxG , + Ur \H|!k%U7LǺ f0x p*JLE˒~ O{ O>XL*r@GƧ* Dߩ0~K`W |ʂ]Z0vGRp)ýMu8|ɝ>RQ 8S'P+h=yƲz=2_ :aCpTrƆ~qlع|l~ϗOv [e%'ñ(r)(ܕ<ةd2C-X>4cSyu(C q ʗHX܌EcHƱ%P<]5LPy|ۛat8@eaSj< 2 KyR&(dhhO&[K0q&W>S_.Ȥ(; +Q>$!%.-t3'PU983٪* N,au]cZ-'DO>.KO@,K0XW-J>FJe)Iu eL\oIwU8_J^Iˤ'ˤIU/~, $kO1Vd~5l `sHseTZ !VAם(C&k-"dPKPV,%_NUUE t־!$8%.,U2%tlIT'a:F2$qz0}JՃҡByTKtObArH2AK*,QB-&q x=܆ay!AbP+irPRX%G 8c0 ۠TW0A0]!2 ,+ ) hSpr[LI&WNptˠ#hr; EkJDP\M S@AJ>兾*z+t /,^ $] 6?W77GO6%Jj角,RdO')*PoGoG0!zWۑ=ēa a+2}Z{~;z~;#ʛR hP<#`AP|sǚ0hB ɌSq+Bl %Z'l8D-8WU袤=$Rq Pv ؆v_֙k3!ǖ![ޡ[k匵[ mRs3A<2\hd X;XP'w'k-Bq7 (#.SS7'n]0TnGA Y((3_(@:J*>t zC՜WkpTEz*EmT2?A µ` R c:]ZS86TC\PUxU wI!"&zQYsi% 8ѧ+gXgk,Q?SN>+AmI}snx5t}s뾹u_4d<'7aUrR>:u4Ix:\A2>JW7 М 7l;:n4 )}AV4(^}~`[^weX84#n 0N\U,B5WA!(9nل7] Ƙaw8 p5͖ɄNw<{G;q`7(o[6a߯8J̇2AJJ(@2?-Vs/O'e}bW4>wXiPix C3KXD'#cFp5ʷ?@=Ecݐ%RYPPc1eZZTih{ H@s֘kx(p>*2 cséL٪^&g4߇xce14Ra"ϣDCyt}/ A@xrШ,jfICWAWAWAΔ 'CE2 `NJF:[EǗBh]X;[Eŕ+GN.)qz sa(rjp@E?AT1 \]o]o \r>[R/x|I(,=:ONYJ>JAĜzzx<$~O./yw}Wtp$Y2%/jRoK;O78 LwF?A/@?pNˤ: j`8>EhJ#Ȝ)0 "ހRڏ\7JpK) 5/>)r~s T(J04=? t(FT n/9gץ8e7I%W$pm̒uO}@zLɚ ^ᰫ.S<[ޒ/`O E[1=]B*Z(u>F'oSj|=O /TdyP)r p >7j\~0eT1#T~Y2 3tkf\uk؊ S|( o[J@X\SNP;J@ώ-% C_TKv';0n<~=yz<<ϚT>X fd)Р@df/)ЛApӿ@Kuas-ONɅyiaZ] 3=#n!8X(/ㄸ'C!Gy$/%TʥLZrR^!JV> %ߖd8ԈK,Jj%:{R'#HZ'`8DnD@ 3T9F^*ǁ{R9Ch,C4T9~O*ՙ*M fACHć9 1@Mc6:Nۅ@ъ2/_/Y2 I6U~pJ:IhB2ŤGSrS!ᐧ0`lVN{lL__?**A+?ap'`)N_:*45,t HO8}H;\p Wi6hI@5)Ko=Uڦ80br)?ĢuΏ˒fx!, ~%usg>b;QpSS,w?3-;ae%,r䧻9nqQ移9`` m丿ඞ0229&PUy'lA\~-7% SNq4ޙ9p7r%lj#upXrXV2 VxJo2 26gsPX3~Y~89_S:+uV̡ ЄtS}%|'?@ ;^ sCO,lop块E7;Cz ~Jλ*!eQpTG>v*?-QN 3v'(cY*C6GP*(׷ÛOB p薕SÐ'DTRWUO@գ$&ݤ朗gOby[v`܅HgV9=ǐyh"sL9⨱tTu97VV /jC;.w* t$/g!) ƐG ;:DN ~VW[DYk_HXr1\<9OEӐ!SK.7!*%NM.ބ{5Uo j0\N B(W)j4OVFnT>8Chr%6Tu>׽n !i&PyFleSMk:z0 spTExY0I#f_dR";P&T rI* apWr0@`yl.G}Iu?5%Ȑd)6՟Ĉג4OSlTt8¯OwSCr'S,5xK:%-A\:oqsG>]Jg1?#ꊉE ka )lͬy9$Uq]T ܚ;pT*])K3H~jѕ+ \ďT>~[hqYJg.)/ PK0C49sK&aCf80Jqgd8d0>I^ꕕ _zu~o[e^R|.A g/C(g^:8prxh$C9vU*>/7Ce9Gm?G|).@( xJ>UC:o'mG&)PPg[)8ڏ HhHܼhkX 0[J0J]U0OTvTiO ̥vx4t*5N(2mJS*.*a88̙Mi&%Sڀ)mn$:k1 >i jPNpH*N=y\IgXJ8 !SJIװD#Hç4%e(^II$ίMA⿇hr~DNQ:zfuU.3=I}nEHQ;+(YvyuvGK66(0]*"@uUFX y2,;Vp!Kq 1n7e6<5wp z7#- 9m90Mv\=x7#v{n>xDFxFw*>xI8ԪkroEouZu2ÉV0&Ҽe`WQwhd6'9?q+ָ`kkB6\ ㄫ 00( uRҥ<_z[SL.dvX[']zAQ_,_T'Ws'Mw9)+Xae:\ڜG9GhzkqU?J`$` 6|M Ri>p#ԥLTe_o'PuUOpc:`˝4F9mrZ<鄯1 Jt"86Z"ruX(vI~Miz\_{ 9{ >),^Sqt;#89(BH3,]J0nO)kM|\ԭ=p\t\3Ir'NnqX^ ppaM+<ڙTMYNDǟ:]ZZ1|oE[뻷N29HFIv>^d>$ r6ݾz}Uw/Z9Mv+ou0sM'ģSQϊOG">ME%K0 &=Z~E~tjJ}u{.=ZSk_](S(y+1=`#;tJ(\rq/-p٠0AUKr>GjV-ȡ9\,TH㻦l޹k1;!{G޿qNrF'M/#(}5ݶu/\2ܶ/{~eO'-4&϶oyr}MSpxqVOT1;繚1L_kWT!-O^9~s;Ow2Ot"F^F%r%"̡K O",c;qk#sau|YJϣ 3*9Ceބ{`1 c^Tq\wq^/ҵn)6E]7m_,@n869l{ك:,˜4L12>n:ŹNnvEe1 p W!w2)cR} უcC90[q<Ptd=@cÆ=571| 42uM{i@nEsi?rZޔN2h|MGɣ:ٹLn׃0h.!mr &I7=p ~4ةp?~?hNg2\L# |? {B*ۊCOO 3%*gs33&H[ x:E킆sN9#4=h\< ' H&؜Iu [M}=0 rŒ@~t4 Bii.qỀ?B{lAWp Na%JΗ±p,@pU骦3&c\(#xaۦc;lU~s>\=qYtv_MENWq&5MSSvX:izLg|6?>w]3b793,.s=PC6h\M[}-mHD&Me!M=,:9AzsƆS--O`$z]8AKq"=ʣ#%P+Uq*=jwn6([je;ORU:j@V-$7 k8L㚜A-(^+Dl~MΙ ]TF׌ҸRD5hU*D˸.ۤ HH5ZI5t;sBi㭎>sZbVw4u^mnGv+3vSpN;i4 ՞vsw]#>$/KK9B +@,C(w!Wܭ?USp%`(N.x +'W̘Teګe^4ko;MjlMgk ڎx]F[oR?ၙ-|n49_A ehn ͭ5d;5mMu~ NeY2<~34.ypsa9xCā=q{\,a"ba9]xtnzrNq\!0wq]-bqwcN (8۪eԖJΧ|hS # xc9H8w7T ]O%ūߜP;i@]v;xӾKM'#:) ?sLa]ET~mR 傺lxp"*@"nԤ͓& jr>vX:A2$]mOy^0uM_}5 ˟KN~V[*xJc5Ƃ#)Tr.l]*\^2մ}_Yځ^9 rOkԹ A G$2îkŅb HTsP VRU IE8)N47Eale_vdhHrAv;*٣0H̛c7EǻÿݻҒ=]iQ׮hy'?A럦{|Rbn|FnͭD9t-`o۷CmL;o6Cq;oηۿ߹ Zs]w `޻޻޻޻޻޻޻޻޻@! |@]ƆksVה!O~{rw׃9zCCiӹǿ#ǿǿ3wUAn1O~O~Oyx{y>~s<\ߙ]4\}Sv*;V| Rqr3zBOQd.\AKGڡPfwu@4sK3r@H-gꜻ純Z UǥP>b7ti)sZ;I-v9A'%u`׎RzPàz_?8}Tq:rT/ bfi/V})#yӰܩGeŪAO:^ wFӾehm+OGwT`v|VLWɼj3QҪ(g~\EF,룛VQ9lݿڍ1wGlP&_ jPWY{~/&'rA E xlM4]9ݓ@D#5ӆtոu#]I#pYP~:U)YCL' lǹ*Ϻ<po i0\%MC):O Z:=ְ2VfZÊKE|Y:tJ깃w@ 0uvo.դvV*ZêDkXh Ѱl%A?/%?:'8 `%"bA6J %I>2C^`) gpI@En/݉EE3E_qڠK(o]ǣ')T(h6m_Փ݊uO;,LT]Թ+qaC)ri; zn[ w5'ߑ@O:+:E<Μsu| <=kr16E֢OF pRT/ޥM΂T* |5.ʙkPTdn3_גP:)pKe HA=춍Lk56:gsQxXˎHowsٝ3Z@t:=Oeo$ׅ_Ezöޮ0ˎH.@'bve䜳ӦjeZv Zom; 72ײ8{r|Ι/쓓DA{kvm[ovG2BQdR[uٷU s~ۿ,w9n9O,CA5m4 WϿݿ͊sw׳K~))))۞|AW[vvvb%Sx09By㐾iZMsErvmk%vHrB+˞oVcpPڕ)$ T[>U>\y,E'L_ewnuا|~ iwz,W\xm4W66q=?r5"=0wV{] k=Zc{ 21TSƯxE6 <<>'ӕTH?Y:`. ڹ n=v$_19td.ylS^~uǽ*VP ~(kP=g[{Wل t]{-<SD1_X&_>:;} 3& EW6y]mZg[{Gi=gwW?JzSvd8 R{))aN"\_Jzw%]IoBi?W{7-d^M`^Jm4?& sXώmddddd9=ӳgzΞioR]Ϡ{C)tlc3AkR]tl&h90JуtLhi3Wg^Aǵ⽘:K]Gkpctnnek)>nGWh'Uy9%:>)C JaUKZK4w 9mC \ }VC]xEsu6nu~kSAú4}(k&UfA.W[ \Oѧv_Ԙ3J["8`kZ>M#Ҿ/H5h fC [0vY۵~S}47x'\ ~>p\bx(HP٨*277i:&j"}~TIwot2+O.64kOVP>ȵ7wL:Lκ~sN]٣,OE:N?5tx%8t p-u!uhRJεg*% r-[QMO%uWw_+^u9Aw;޽c vݻػwA}wguݨ=nP_]c߽zˮUx荭wwVKw>tv̞~ѱt/Zr߽?{|;u?fN%.t8!w9^˒5!{ޠig})Zk0 kNr򲏝c{9[ s?i奈p]x* 1u6SA#AĢ3gbiVRqI.LV?t6r&lXrSػjUh:z .*BK7Oy{1"z'*77V؁LS8jFt]qݔI;=ZNQEuMRFG] jNK $j_fK\g~rJI>O>8|g%l/lYT |ۇVkS@ Bqxqǁn} ?w݇>i>t1t (Kӊ͵CBw JU^. }\BwDž>$#׊ؠT 0݇j}FAc2cn h7E"}HwD zՑ$AOOCyOŧ}dUvBn-EζmYj~q t_miKZ|4ϏY-x2w\강iENq*N; v۵~DDoww!w;N]sIn!wBޅܽHrίsz=v {Oqkݻ꒖nER_}Ώtww)ven{K%ޔ7ѝr",ۛZHѦ p!O)+p*Mj} .qk UuirM5F:IН>^M{ ]Z:PCe=vMeގN"H-_k)蹌iN Iz6{m6{6mRghQ/޼G&-бjQd[[[O \VV\:6`=V!>[=[=mzn&럶e=m ǔ/}uMs4]2ѪNzi $1kuVkEVmYOۭ[vL<:ܓ[=mz`:ˠ[3{!`@CT+8GӀ )LbBq(pH*a pGŹnA:27{!&7QG\oi\i:mw+">FH\' Ԣ)9ÚE\ Mm*HORn/WoIY`u.u.4&-. A#ϔ?3 p ܚ:Sg QfUR>ܣ:ޣ:ޚ:ޑ:ޑw^&Y4IFr7@ maa=Exz3fhM阢NȠ4n̠}{_LZMN^3-u܂YmiUZ`Lڌ&uCԠtvȹ܁a2 <Ѵ <ݩrl~Mld*lgKR5f!@g fHQr_BpTe0(gܷ>f C\sV(Xʙ_嬛wzP~̢4j7m<N1d)1uWs .utS0~ꂺnuO>_i!'Q8mtTHJn[z u)yn~noS+4R¤OE*QE\y zc??J5G' =Уo2HG>]ھ c@@09ή8y:?k(H~!AWhr~sZ}M:؝4w{_/=H>A<VW;h+v~]S9%8 #"^YRv2.q̂e8X.P"iVe3#?!BEᐫj\cAySJ?JhPt$Zp $ r8 :uteRu.LAgsֲH#tω2)k]{- ,0j4O1atsAS {kA "?EM C jWH+ E%uX-N3tAZ=݂]ri]VUΓPx۽&wΜ3MtXz 쯋SwkeV_pS1\RxBza!ȕ=sLևHW@\ rehh1{i0zϐ\ tA{59y5ٵ.c.c.c;nO 4 1QG0syd7MK}Ff{|x:~(}:Kx>;\p1t] Y#ܬ B9i}nP4,f7K?ez@4&A\-:xiP1]75 rsgAkShV Pxi] WJ]flwI3ϟ$jvD]N'L\ouOֽ\IS;M)n꺜S~81 ]ɤKC ֊ >m)5׀ B!Q$apr*kl×٪!O>m5|jL۝Ч'OtSOO=ӆ[)SOw}iigW'F\}^)ȵ׻Frv}0{ }5]{^y1m}r)(8YmT8Sb$<*\ғɼWIe'1A_PSqiUumn@g7&iyU3hJG"]~t~~74',INۗsQxN~SP4|ؙ'X{![|)|:5?pd=^66{rA(9e R\'KqQL; *\.pt+J{2-6q{{&_ij.Mձ}L/RZqvp o rG.6z p˗—Ag|9S%/ˣ Aqܶu+BOcSPxk4}umMLTsd@r~K΅j3q)AG)dFZtfb@[ MkZ}OG+U #䃠y Up ||^p\!Q*K/!V1(gnBy]ssh3 znT @)^ú]z_쎽MWu w4 9śM"D}DwS.kM #x2js6 O%ƒaɰidޔa)۪srt)mGm=m=m=fϯizAz=4]}mQ pZ=!ڢNm&"AÞLhh hmmmmmmA0-cecece#5SIN"NyjNѽ!QrwN?2t~0U}nGydU".q\;t\bPz}@)@h{r}R%\Yz}di'.>#K,EogZ= \onv _#}"@s4;.Mwaw؅ݾJ;Jr  zNg̣3*& 9$g C$@w79tR}To Zo_3 yWέn qĝzA(@7)oFwꐮ~?uV)ƱEcwʍo P*1]1;L飯@2W7":^lQqveR9@i *C ^ת;@樠V:z_ \EsW̔Z۪rؐeO_844]jw K1$9kp J!@ H[c-˽aPd.VLUm]4XUFs+np)f[$Ua̎#)䆍n⠇mv<^&._ 7zMisgM˅5{ޘӣ;K\mϦIBq"q$"^(ˈ'72fW.?[][][0W{}`MW{}rɉ''^x}G(^x}G(^x}rɉS0 "o"oZ}nǻ7:ytTۧ*>UOU}^^oxE5ͦnnvvjxO_}1kzOU}SoBmBmBmBmtg.>s\}Go7^W}>r*bh\.H۽;vr>k ovA!7d ؂T|t\!;*.ڀ'G*%N~VO!T?-p"/TrA_;sdLRe 괣*h7E_ˍ0k9\v_=58UB WPי_oXtQ:-b@(&mׅJc붽=Zщ+=i΂FkNK"oaYR0+&9lwZZ>{R^VJ侒0`BOG9-'%o;Tp‰tOdRAR_hm-[> C*3aJ\Y0js Kn{Ʊ{ T1:tbVAB43Ԑ:qkz^}JcINrی:˥ h+:l4~rdr䠐apz&"F .-J nDZM+h{z]l8zy`:So~o?;(n W8ܘ(siPPTm}v[[}9#/B\2}q_<uwkZh^>(nxvVr(jE#6i|ȤҼ0q{aڤF#}׼Ts{V}3KY<u r{Z_Tx-Z<)s)냮8 ]g+~ɽ^wzg;Yp;޾(97U]fuz:Wwӻ]uz:GޣNQ77FikrqEV[[[[Ҥcr}5]ndoCnô!G]񺯞67khnroh{9{{9{{9]Y"{+9{+9{+9{Q< ֹW6m/go/go/\?[hNsԫ&U; R7#P);Sti8Ul A8E*  ~NŠTrdΥ{r SCZNZ$SFogkU3s贙"~ `]SEFr.z L@#GSʔynA ~q )!^p K;?wĽGG9<@r&w59l8d='N *Nh:ΏNA_T6~Cxם'pY#o]i(kqàW=Usr_M k?z&NdLrK K_-\#X&ˊ@rrbټVgܪ£+*#s.; zn+|h9m-vb[WۊWI*@.cMk9|7[Nst!vr|9mps>s>#>~q׻2x mɠ/3?J|UOZ׆Eo#Z*8~ Kpdֽ~uiXJϡкW[\ UN7tهW@nj=+a«XL)Ar_-4lKREZ=(ծ" ׽@):^ׅ;@tr؉q5(\?ex ԥ،~ $yVQ'*vl--s>aV{|RsvrKyz:/~ ?O鞉U)@}p嬺R-GWotςՏ.f asן ן ן WGT(>%OW|[irt=9r~HPák[ k=Am7L6$鳱8.Ճlxshr"z6uo~u!nev.Jr3Nቨ#AZ&\{7pWG_?D۟[?="ymc+xXJ: R_-_rj·ZNcjcl]n#}A2\EYA/,(9W RmO=h6`)MQ M@gtv>ǣu=Ubk˝)5@g@A]w~QxT7=Ϙ/xvogQO3mҠ:qcu]1&r<# IÇ Ct!`S*PފR m8V4n(};)ULi8s5LK^ igi w@Þ4en (˙ݱ˹N i봴 ,~2m:szE |Kou.ʺCOɧxշ~qH  n#(bAqX*˳8OCEDHmAq7>`wۇi\0We|j 'MH="\^_N嫻wFq /b$w @9HEu]07AG.vBۀLK{ݶ9C4=oֺ.\&9g~r~Hxۍ|. 8~[t~1ݎ7]8sHqWn[Φ%]r{~s.8\>_Wg ?H׹D_t]a$xP3+Rr`jp`9T· NK<ZtB9c0ZttIIqCyKͅE Iʫ2j|[?\16|Сޔs v嶍]u1lq!u]4EN% qTGQ54::^.%=.) <`sO0>ný6tN憤pk8rD_=S"7x//N. h/X09ڋ{9Ήrj[l^^;\].]YOe=W۾kmkYꉽdv' 9q\t[(wW䫯fr3F9p'n-[As9L`Ūr{rhqM9TW9ֿimHӥT9_>7#X7 zСTfC NK 0REapmWT-ۼNw%G҃(L{_gܓch@ZӴbak9rO͗-Љܮi6.9D[O)h@:L 1M9]HH{8m&\ھkճ'Hkޤq'agז|>Sϟ|\g;;3iPgB*Pz,U]O!o(MS!*sQ:yLRU=1oP0Mlܯ\&e^p0wX'o^}=kus9]贱167gce됥"+EU|1 aPgP!㗚h>P|]Jp&'#'x󌦎|un80;^WsW5^N{kY-TP~_k.m|I7-z]JJ_]':}O~z\u9g5\9VV]ẠG\K,/W`~!G]+_t9?\՘nRr)@@wG\ KnMewKAtIi7iowӹ<5']"Kg+ Ҫēz'}5>%uѦTg:<[EV'\sstII`0]hx0rEro|p }(@½/ᔛ.Rg:g SD.-:?!\mqĶj0}65L-Sj5D;^O ꚋ|U3:jK%>?[H[R7't*[M9. U?]qH*2f~#U{*Cy/t))GgaN\E;îI;4ui\[vNJ;]g&xo rORޮ=WI]ޣB5x{UuO=ii9Ev_QMӾmpZ=-GeS9Lm59ߣ``0R!pCUșʇO aB1>\1)--mR緮ۼݠIiz΅$cȻ &=$L=;w]C c/i&c\%% XI lEmA(fk[E{V7@77 UsϻYO]ՐKt|ilT! w0'NWg,p,o}"^z{67h=ݦȵ{]ilJhr˵i=zӧufxSt_ԓt+/ߟ䜣\Ub G|5=RGŐvR_v-q5#PRqr] ~\U/cPAkY" U\9}"ۗ}Oa'Ԥ3Mw59|Ι{M7ދ5\\s> lpf˯AzS[r^H}~˚'9➦eeN[NI{pMӳ?g(4kr?3TxnHtey!6\]+iXvu ׀n:g8LO-rÃ:-cmRrOơ8z(H)Z'H뤀/ cKAeSr)p) .H*Uz(PrnO 9&(r4S TH)H!O묏Ch==7ZM{59\ǡ/c-bV'(ns KZ( ҵ (9۠3qmΛՇ/GsΙET>\+xnR*n]U=M.f[oSn~Aic8^z]]MǵvYR.-V"94@~p)k0mr'G9 =Uz=/~ ,zri~\-ŏ5 Sp*616 Rqrq9.qu`|ψ03T_\qbu<9 ZC4bw  q :,v.zk\}.#Z V~ڻ]_].m.O?xArM>uzn0w)~{n-`mߓ|<&bL%ݡuVdj2aW)vT6蒖D<+!'òh~Mۦ+ JĎGCqU`}LZwavhNwt(:8~' ;Zy?bKnLy} aPfqc-y~ Y,7 c̲lGa 37W UԹQlc47uw釪*vH=A{챼F|=($p+x"z"-x+"t^W EEȥy(WBݤ]a2^=W_=W_=Wqq]e\}\M]}T[)NJfQ"WQj{&|'&_AR.:upUӊfs{ OPK΃޵KJ{/WWGRy;m?9+~d6;~dj</ńk8A0ߧfU5=U^ե%J+2O =üynIyv~'Zn(CbR/0NKC`C@"S ' q?m"DpIr-#K.,*SC*1@rCo 1|q2э&7b7i'Q&# )&-E7RH6k24- hE}REͳeӓ-=;t4!vISSM/̜>}C4 ]ȥKt%27S>>*?.a2XI}]avSW< (i &ʾv9KLЬVX  Q Ri#$9`8Gji! ۑuUyzvIKAZDgQVED5;HjI˥8)d TTTTO4,C{ =Ă*!t`8=DМ;B΀T^'t\[Y Л.Cpe{G4@>7@ eIKP3ISRϠFͽv/g]ou$fg]Kн$$Ih"J[=\-LS][ddIuYCvMjICpX%Uk"Kxv%KS'߯SZ71=Ԡgsyr0|I2nOY8E'8dOIR w'ei6`.uOh@G|yD-kv1&8oGͷ1h1hWCs pU06e?ƠQvUb4ˊc 1؀vl@!@r>\,>;T6Ib^֠A{Y&^ :\B֠A7|V}P7_e 3iVأr hң.^ҧg ׊6Ծ[C=4WYMEsA0/k~h#l֤~%El?Vh/[ўVD~^?z׏xϿ~_ۈuI~(_Kq1vI;s_%/Ɏ,KgOlBH]7\'9s_ WpmP@da˲^YTWg]цgۭ,gVUXr@2f[oZ΁J!ARMzTvl k`ՖRiOW$`.iӧVE[,Lr!fDbj.iUF_ْ.i.n [&=NzvvOa;~'UλhRI՟vǯ%&ϞԽ՝iuāmu{NjYK{ԟp,Ts(|ylLh}~'\VJzP'6*, u~/\861\Q+=tIq+c tJwZ ,fnjƗv(MGfipMY)O%w_I׮k`z.ƇMTMTMT]_A.F8e|:/% E)|^s85h>hU<*dR;I(#%tfIa|e:ʩ(cQ&IsF]~w|>^[DZj& Q{ ~m#QN*)r_=ʠsTMOIf4fm8c4khF5D!1u7t'nCud:@6e <Ҷp9Wu?r.|~vK &i4hvZuU{vڭ{_i4ͨC `4fQQ+v&a[ҥ[=$+Sk$Zd呤;FC#i-ly0)-k1K@n3m&p |jtw/ F:w{5|ig#[Ri?Q超xt#9gi˒-O p>vKgRuG"ith"' у:a޳Α=Y@DqH^ Igl/E\mio_^"U؅ߛDOZ",>ENIGG[UUw zëǠGt3:Q[tJ cLi/ \Δƴ1[!v9\N˴i 1mp  QUv' Ԩ$qKtxj IgQƪ2vENu(Z MhlJ4R'DӠƋ,=ĶMmSϗd#UM=hV!?L7ޥy$bK\+!%:zJ+VSRFnQƻ5>stZШ0jCTaLMͿ0H;q{JzO'$=ߎ9TJ Zku냆S{ ' Bt> Kz:>MXT 5,:Vyt ;8PK#c\Q|jN8h$EZ$MjݳSgd%x~DZ$1: :Su>uMs;ovNMG {sdl`Q['ѧqZepcD?v9/X{QEƔ,NZYzr{ ;JO[&6?~l_;`~>`~> qպ򾊌[api8w<-0\j]k\Z?;VR/"ekrD})@UjNjEOz]UhW%ѱ6WRkE5Pjf%^kiIKKU)$;f-jjݬtoU 2lpukΉo6l' ȃD7'2rTB e`/ p<^> N.ǝ0i~nuu- L@ԩ]%JT#R)QJz,-JQa>KVtaL4ΒVu9Փ:OjYaIU=j+gIs}%Mh6xK bٛ,"AZS͒=&it'| ywg6ׂc؎au~vǹ'|-?8qt O?v TC s*K$ܝSY~rᩤS:LE9L6ɏoogngniKit` CuXtrx56USIb=gF[%[5>w@nNEc/uhg _}MX:qmYϦ>Y>& vx@>ԫib[W[BRia2M:@褪lE,:vXtڗ*l\\K@&,"v:H&tYD~j~r79Iurj2ɹ3--FFp*'lƄ!Kt"NDrtfD!Au謓F6itN=o܋$K;EI3N)u6鬳Ij ɽ]v9ßiHب!CjfM*"5k3<:}0+~ 49Y X6SbЭ&@kO[sɵemU$8PaZ*ako&sr].+EcBⵊVMCWK1#ȃe!bIb -XI۩H *iSkNaߠvu9"HLIGY׬6 [^%UNTm 0Ѫ9%\3Ph? (\rtݭK$.3v5&&4dYc JHߤ5&^]hA& j7)$O1(âF]m >ƙ KnE IeA<6b 8e9|w-Ggl{N.Gשp L67N";f+:ЭLLZ֫ %VD mɘ4BfaI7H. ҙ9I:ӄoy>hҩϹ D]^Mn} ]T`^VQS>wn}\b:Asͭ[/>T. 2I 3 23ӯϞ泧ih,j3< Dg't?d(L$eP57=tG\uH|KZ\z⪿(r`.W}dsz;K"ocI ]%mv!Tmp%-j-$8͋!]%˴wLNSA.I]gWs"rgKzxF6~^ 9K|χa|$t y4 09N>IG1 L+x->ˑU_?i>hqU?i5mx'J1+ެ94ճs)v MGC=Փ,"?ME n韃N#4r?{F\S8i mfE4O$ZdIԴOF:r1)4/ej:|&w˂|Fn5+e/dj?BP$ռN%ި·B6p-ZpY@>RJp ?TP> d0M$.{E2DsuVTWC!UYv)mU tXƳUSa\T_nf=\nqjuQ+O餴WJ'@h׉I+"v$MAy+'I+A5 #gJH 577'4Q_?M*tvQyש׵#Ս|V\atǑt qG՟q>'y=tA}wwpu =ªm/M*mI4[&#.6UovXI2Ф 4)MzIjun͕ ];IsA\dJtimѥ4<ą؅KOvIt뤨ΰ ~ 9S ۊS)]HSi_rg^ϽN峷WwEO{IB٨V "C/,餿[}ߟ[Pyn"v)N&Q|tFۤ^OIcBk;:\iGƀp 6w3%qfuWc1xw<l' ?_^׳㨡<^^^^^^ ^ ^t%H.zfYq H-l z5_hѡs|dd 4xzzy&}xyꕑgF/W 5QRx*xy%1R߿cȥqKڨ 2 p\?e%O'8wXL:GMˆ۠GnNuEIAhW}:+ IBzTuևwNZ^c:j&MEcN?LZ{AKMj.K;hPwhy=ai;?wBjԛ\q "KfeNP" Lѭ@~ xPSm ?r]b (#K2' Qm{IZݠC =vV2.}VXIX9XZ*WIҴU4鴦 pd"⪼b(ۦZFWDNvikKHD8B4 C跀kИ@_zU:I!9mCw6qmCnwd,GvOuY UqGOV}B$Zum:J {e<]45}uU ]on}2MujW.oIAryļ>sٻ O[1eC_=P P2-'.ȒS%8DIHia8-Ș7 갌8~ |@:$@;O@+ }IEt7.$ߢIBBJ'__"6r *ޤ}IR]NV ޢ| ڔ!۞߭0/q$=>Hb&}/$%>$itiͩAץyIDi[R"ǎm&OuۻޒJRMJ.@4}xӞVxy>.p9z!u68\˒jV۴TƉ$ft;OlE{q{nO|e%-fsIU%|I!2bzo/tݫKqROVxϏNb^[]]#&dGQߺU a7^L%1m.N}ԉoWi)VDkzjZ˨2*Ԏb=g 9 YIKEB6_,Ś+ ]VP_РՍ&5ךtVɆ۔!/IK:؍^ZZZd˒T5.ʕRK$;y/W-W-V-," c|_Qb I8)âpբpղ/=Bથથeߪ^ڝ0/=BXCdp7 !pvG/τJ|,%I-t)Erҡ2Ⱥp7Iћ!Aص}& ¼cD9Aú_t(dއc)>v>5 z LRؘGsJJ?0UV[xkMZ *I#уt<G҆.^V*U~P?jchdIGZ?.k[]69ڀqSj_U~pFЁ%ZiU~ iFLypy\HR/;nnTEn,TR~VC%=JwA.~\ԡGE*ʏbT1qcFĭE *HJPIAԅ[%}QJx\4oMq~=C у4NGtd)\G^H~t4`8C?~6N#Kv4x$Zd]MN+rMTi;M.I{&eQ=j*'!NZVAUD[ubv' 7V.ϩ9Duu4=nfy&?TbIفǠk% $< 3p2?GA @9:Tf4]%FZ&& Lzs&TjIoV}&N:!aЪ1Ѯ\V|Eo1O ErV!cSĤA.?%R<*IL. I"ʀET&eLiœESS̤>QDo&UΫڻꪴjܖIyKwI!A#6ri'Ӽ yl6 x#~"9g|2,`>D#K;(`9q@j;x4L&vip:˒6)c$J[-T[a0-i{t#/iUcgGGIF t^DNҦ.m۶ )d~ԥh1[τC0$-H&@I?N}?.W}zs6̂T.=ӥp9] IApH luO&r'?S2tG6k&q5t2As>ZQtNJZ kl9(HnDTGW$]r3"$=1>ӳ/O>#r߷g`3ʒI#~uR\&太O)4H(՚I\U̾XcУ[v'S,ΤJ+,'}&5SaO=6^<6^<6^<6^</6Ńbu*9=X1L$.|qI׃㙶^88iUԃ`Y$j$9ex)싯(gx^Oll6hx^xdҨl$)S,"OYDlJ>>+Ոn%>^>'4Tc#~d^>M>ǒp` uGM0}RC`[ H\s'z*{8rQҤVaUqջ^AtNADmUio| jړy٫A\WX;:͚tIlqܢLq0aX7LBT0jO_<kǛE贏 3 *zf@% ,{Lőf-l7ճ lG< fDKvѤt 'Ucsjտר][&bTAWu/(E ?ӧk^ ь~uꢝMZߧ ;ꤵ `$,) sEtG *#9gi{"麦Kb}|OO8OtHi҈*sZa K$`9g h*сTȞNY@t $UBbA!i}H=i^DGuشD?49Y7}eQSuB ,;Ӥ9G遒U*bztɇrG>ѵC ;нC ;tgѿT ր2Ipd6ԀZ+8:P;JF 8Nś4ꬫh7Dv^WhMu<;X&UA6\6oLϠIz{'j;w$?7#6. 1WG (4.K3 !fu.bF! eR×$ t7t7΁.Ֆ|3H3j$I\4eQ}S=,ƞ}kfu7XD;,ռ?AVRͻe6L[ w{no0,GվMoq8DvjAKsv["B3H d9v`|SgmO$hzs%ᓰDY^aAm/IT(C<NFcV$?$mZ XҨUa )$D.3E5O>W|Р &dŞӍ:=gٽ~)G7^H $ $X6@C'ڗ=v'pp2 X$W'iQzK7΢ͬ|֊U{/۲"zw!A)@l&U~[[ ӯ/&AK8|kg? ,?G 5!Qr2&e=]%8CZ}VȒigWïgmA-YaTIuRuyNo29J:EҤD3}Bf7IU{wRң\܇uҦ\)e4(A ҼetH)v\cH7a;3'&U΃r}\)cå'?uRR}Rx)ggxөBМ\N˗Q&`9|.t5_ Qv}_G= dGh@ΙY+>GYMqR |![dVEK:f߇3$zfٕa&[,iRڤM%Հ*)!ޅc.ڕ@E_WQ4(mV{e tyлv/Ը*Ų]u/p5fZF"8DQ']GN{S=8Q8 8.BVQQRCtRa@CwþaʈN]dԤيHvѩ"U5NҢ &>ZD:ilCX)dNm{uB[n^ЖSkPǼ\M]ڄ>o$zF]zȥ5rND~mVج(ŠKl3췗'UD.ڐIkw tfRuC3Hg/@w~S\犅,CpSIK⅁Ѣ"f.笚6)")&"WAnApUj$ٶ~ە>˒V#~nMtUfh}lBTp P_LV}|^LގʱX:$'ND 6iQBmE\ t 4dL=3iP[5)GGui?'Y.Վ.{o֊1"Ӯg%IZR7Mz.)~e}r_U%&-]Y,'oRa jdФWԝ7Ez/lJc"K O:Evp)75v孪t:*&e $˨mY-uumkԶZ۶ N%-0_8 pK &~Bsp_%?rt"R/ѡ^nFѬl^NKl+k%"Y%]򛯮>I*)ҠfȽ.!iqIa p !KOp?Ao6j:ei#;+9Mp ulwrs璏^$Exǁm(`g\DGG)[W__ZuKuOXqM>n=H;zIFN]=!J>I$AښY,%ML"Tu9L &]8LDV;Rºzq{QT7:=,'$ϧ'-z9v8U_{믇˷嶻v)1lHl{d<9gWr^;z!s>@țԩ.Lw.[>yD#OzrY{֬5S֡Y(CjDr>n^ֻ5K2\~fє=fΥɌ蓞v07s*ei_='t^\ 1z ДzG8~'>kx%8}|>R8!˒B4sr0<+%rO!\AYfHҭհXJ!7("?#N]_l$;$ݪlO&~Vvf!چFQS[4hAf$ZnW9+ ZJMIk{ ƨTէ״oeo}OX%,BdDilL |DrG$_Y"CDh>DX TtUa_>ч>h" ZI:}1}s@TC>]D#@h߿oG$6 !A\'NMu5TQpcDQ6ȹ#KkRS!9 َOZ$):T/%9O5QFt)-~2&M[UMhu-\=J*ũr!6Dt#ڄuƼ>ZN!ODh[v|v9S]rBF&SՄPNOpt}0 d> D>YfU}HonmRJmE.jd:lB+^a"UEG`Ti5"ڔ1osIdn3D͕\V\DAYSH#mQSs:K f*w0}VlF.[549~0s}0ׇFz4j 编S_Tc=ك=p\^swO58ٗ@7=[u dǞa~~L۶o?zSQܹ:hbpWru1oi*wVDEr>Rwf& Z.tЦA&5;׋{ɜ>hDGM FuY#^MFYy c"^UߓmH}OVOjzI yj-9Jci鬃= (|t{Pᐳ%Cx.UI;%Qֿ VIu[a5,KEZIe,$6֫74)H,b8$o¶Rz*2Q5R FU,"@޺ zh E2e鑖^ 5yy T}t=ks/k;k#,sYГHQ?T^x)3 `}@k@6:=t2\\}rNjÛH?Q.QC^ZǧE+-y+X_t76k<'kvj%52r;r-hUG{Z:yX9KDѴ1LNMWWo+>&zWTifu#GYESS/v]wV\ rW^(4<ЃJ;I@ pIc;e !⒅ W` ݝ᙮ٯνNt .…}d)õJ@{@k$(uӃHkdsQ\{rdQ[];w?i,YjqؤijբU` ݸ%He}봣w%[[CE_.tG/:TWa\ߩ_-?%>yC,c ʯz1S ur }"zM)Q]2^TqS\t-"AV=|kt\u֏\}iwR.Y$,9CP \NkB|Ru ?Qdݞuʿ'An~cj'A\Q&P%D; CIY[$%"W;kRVz|- Ot;aJS h y-zUމ'f#R7H;(K&,O;M~mDР:-@zzGLr]|i7g5hkqWru}^GA :O?jz{ \MO{"D0!xJ;Uڥuޛh-mr:9Go s^4\tzhˤO_:w9?5\G''Q3yN9 8/yegĔru. 'U4UPD`UiHӶȦ ӂuZ1;iVmmXDw6%lY&N0&97NmSYâjm YYi _Qo`b9q8m+m+0Va2q8m+jEAZ-~5U [ c۠WBGr8C"H1e~%,Js .K јϗ>|1vhq\G: |u !޽H0B!c,>NHYx|5DRLpRzVasj~u.T$uH&mjyiDجb[#s1MDi(Ӧ=\`֝ JQ]VjZ߮Ue} /I5]JIW]:IU6-"ެ{y2}V.V:aU 7QBJ _Öa,nho5adr}-'U39ߺt/9P:gmC4źiIVhqUB5eC.ґj6LI^bWr'imi'H4k5 bi%6Evmpu&Rxm4ڶUA'&{0y)iH%+@7x0j\_(98ޅ;' s.]  ǑhWt]ۓhuVJM5J~]UuiguTi+5rD;c՞B^;UM/ΎI9^:?@kEj 4 vNMZzRM).Aqjٮ5,[ʑ tiCN޹$KV 8.:4:^|Uӭ^Ms@&จ:<ǹE\,5%qW xՙY:uUy 1LO:"ƥwiͤş);EmZom̤Sl]1}e&ѡr"/zU"SR0r֦A/Vl,̤K i%ѻL4Ԅe&NZe[q ?n-sm6Int{܃[]˒Gq }[=n~)R7۫[ fyuY*I(ēP{(6gL+6'-jW7ƮCZTMIN]zuۼY^,nsUDi2C*I@r}+^@n4V+bVsۼm"(td%U!n߭_{ Gջ=9r{ $yv&X6/塢YS" {UMRJ8P[KMjQ=j*rM*Ikʴ :&(hНMPI\ؘDnي7uۤ:Ug*MGCS=Ut/Lm$U &Ϥ"zW?F~_-Gja")%]봭*wTY%:M:VtO/MoRMh됮ɟ_t:f6pctH,LfsTגsIztJآpk"'QDvijyr8gԩutEus]@WlvHM}%jcڱDv P; ӰلP|p> aZvV;fՀg9j%ݓB1dv Y;׀ȗ>- صk}E쵗kkr `{2xcdE̤ɰKl!I[ TuwxZE*^A$B˭~vʸU˽nǻk 2eT5kt|Ц4?ʤ7~.\jFX󧗙o/QxO2wEgg /1Hmԇ5(urǟ0yo.]*ߣQ$d7`:=>s?I_"iB;;-T$ UZ +^Ro}:wkr7dkE\~Ҡ^ͺz~}&Δ]OI~3}T.򓘥Vy"dF'5C OݿtkX&TVo=Tc]G3pGVxuʽivM.WDM” m& R}>)thU")_0vE-%MO'X*'ֲF5@CXJ-KaEd/fϞ#KB?JI sW=R$YDWUw{z՝N%3wm Ϊ٪ԪӪOڅ4{lmmmmm1DN;fkӎiǶc[ڱ-Xv H;zb7jKc%ڱ2e8qh/^&LB{2 eg/^柽?&oSL:{u2eˬYg/c^Ɯ9{s2Lu/U>ӶO]I9{p2ep3iVmѲf/^ 7{f&>4q d B'#-EnK\7{}R3L: ēΏiLf Hj:=}ǒ69{4}˥V z2Y2IUG/W+H("QQas@C5~̈́@ty$aޅ<#j筏"KdIcAZ]/YRebGؑ!vd? Îİ#( ЃaGPv_GЁj#H?%%%%%%%C/y]/y]/y].TO]D_%%., zzIN8u"2^^^^R^R^$ޢ~eSO^^9)%go-zEK"Km:z=[dcx T23X۳A 'q{lmǦcS-yٳrItrY)9_ =[d鳏XS8iEmԆW;fv^혽1{OD1KFRH׬sjW^AC۷VD N{](uiU-kW{XsI)X|ڹzKP ӫݧWO^9sz0Hb@ȤՋ6W7Kc|rTr\BH+~|VurϪ N.Uˀ6ptҤ4>J6IIRBN: JE=iRLJzR4ݪI+rߓA0&u[ᅠNZ<~VOvjhG O29 RRYy֤K/WK5(#=TuGyBMڮN Ljzh擄l媔gh5G: Ly^h2蔽bl!!R>g/ACuZ@^yw+\.#Kg~=SIC>`8.K1B6p!uѹUf+&C><5:j񢊷\wʥU<)'Ui5 ơuDxh'dŞ4*Ū)"CZyVQ+߯j{%?]FzI\.R|%IָY8 x>GFrMRœH1Z}Vi2%QmQ^Ez.~ghkџ}] E^nAquǰ>h4âʜpXН!C%8P:!WD~[]\;IVYRu{x K\4Qv[ƢʐȭW4l%JYr{W])Ui]ԙ-u=?h7j:SmT.R fF d7Oѓ}}EԴNiy(3͵\fW)}ě9yqNޗi6'f,`ⴵX(+iC e*#8b x?;gffffffϝR~յtF/+JoT {%i;ob4լjtZ ΫZ\{|ଵ7bmE,VόYЉ%Mmss/TWP;ҿ-7Ϭ'js+:Tfc3=1{owײLvu ]:=a9|#k3@<`Z8g8S5Du)fh$sY[Q+MZz\TK[aXvH+0#Vb˯q*,:}t'?rKg@Pe+$Iy4.Ӥo/6I:u,tN c_ IxK~oog8udB y ntklE\!В9u>넆I*iH^fq4I(3(+S)N譺Tc}|+-WAwK7~V%M]b\]hu^5sh~Ӄ0@WtA)1?xJ gCQbq}. )cvdI%,o%o%oLZhK ȸI;J8JI!/IvOtW])+i(iȳ%IՋ˫_+((((54r4r4r4r4r4rSSQQQrɤy22PPP&DYV;=vv:RJ\#*i8 8N9\@` .J?i:%mtt4:OBtRуN]}~M1AҬ~V:[iReV >G(|L:)W%k 'QGG{4F&5]ҹQEGyIt'QDGMIt'ќ\QDmGYuZP ʶy&"?U{}T$1TUثJ$G+jn[A*I®sջ In?9zkH:[uYLkTS"yu4ZmͮhgתkvC 8]fP*=U&8[{-1Yrr-$>"i&z&bIN`IHd)iRƨM&-JaOi)4(:ЋMM%GYҤZ%UiZ*E18͙jz| UI]eQ3Qr LcU 踐Oǽ.E%uIY&R.$i^X2qUZ" $eRYCe"z4-lM@v ͆ șjQ8@xGxG xYkSԉSԉ/Ԁcj9{:,o&-fϕYMg.U"RG,?ATD9@u[2FcF>*+yfWSK͉@IWN3K K&]W>Iߵ۵t͔lRIw^ǿJGo<(͠;j @Syy9>"+*iW;aeЉkǑu Vx46%Nq@h|/U, muӪ9&'G<)& XA  z伫ҧI#fکڟj婚8O*"9]N\8a:/x| b4 mP+>\AH>*iUސ]+sWx]~@ky-=i87_Cڀ"*]_kקF}#{ZC1rzzpΛqO`8w> 9ah{!f64&}n# 7΃.rĘ4+Z &yiUİ6I4QjJYAU?yJ鶫Vju[u~ U*wxĴhi6)527팓i)-IgnfɤYD{EUf$BXM&o'Vp㷉[%M4yXM&oSkb|%CټMl&-jb6ye6-y-VnQٷͲoe6˪mUx8~1m[CfYͲyKē,Y6olfټͲye6m[̢},YmfYͲ[e6nm, o(ZZ;"j*$͗V;k6c1ti@ Y^K%븺6"q . WL*` Y EH"_͎u5< O|7RK߷^DUJt:i-TCRפK.f6A]#egeI"ZJ T}OωCZ#Ծ7F~Dc&t)h1%{י:&MfܓWe \h"C:HDM)E䲪΋IWhU hEDZ9:[%T3hOmZaBIKtHr BmZ61 խ@3Vz&+&7)G&khsK)r%-WM&[>gicңS?v7}/c93'I¡\A+o(:u R\Ct>5`9CW(@ۍfYY4߆f >]GK͢]D>5i^Bt*#YhojbQ$H֤UaOǯ94R7 V : zMjW+*ERgMe}^_7CHw6TU\#_^}kKu֫4mVW؟**L;DE:kB~cc֫o3rOqljj_A~-8&ԬߚZZZZ2LR.[+Z1AG_ވ uKؔl>[é|LJYZq]0]g}2l2jh $2+M^N#.)Xl_f]&?(FbēZl%U]8 zl+Q2\Kۉ_m Y& bN_:kۈ1a!׶H ͠}5>npH~l+mw bh/~Rm SyۥF@% %ȀKdrs  WL_%LZm4vQŻ7?6vAL:hˤ{|"^"ʕ|.iT[ˡ #.(W=$ɤGim?Di5-)h[Ԫw:Iֵ hm%,\,]矖$ǚ+ z\ccS X:`94;˒fG/I ;`gw`\:5A#/hF۬h\֫*siT T1Es_IZMҷz&I{IRЪա Ae-Yel: ~+*toc85s>r\oON#_"b0@|Ec|ShZ_j(Zs#{h[jiАV9J'M%UoArAD.>KJc[LOuob/.:1{k:osrm%`>2'΀=]S,ؠMC'}EuuWEƠ0;"JBׁhvV?!gkrgtKgif>pR]mN:_׺#sU qUZfGct7?>w3 ?Dwst7?,/7 we32 D;D=N^?8~(TˀJ&=5;zxTOͤAǵ3iM~~&QF ~gҬ{!'%YD.R\NZVɪ9"rkҁt_RMJ>Փ9'M5}*l17BZ*ŔKK"e8Or 5hu[l;VK/IDUa.tP'e̤C0w]BzQMMH]vM]Ij!.נ"r!ZSrG.zMF"GNIaJ$4ۤ1=DMӽh-@_?zS*ˤ&ciWTI;]Iݮ%1K|μ\j*#amޚ[3j˰jVyX##@ 6t+`qiqi;I*id$8CϰF hpd0]/6!K{"{x(`9g8Khc(GJtJITZ{C׮Q),~J ZE!^Q]Q(k|$]J3KCD`SYq+QGI5#UWOM Ib&Gd:Us.TҮ8J{ӑ-g[%;]44&pZ.H^~ ܎C\;;l''; $)SFIb[LPD 0 JXU6T+"u!'.)<)&LIFltQi\kmhA^?Mm7ƌ{y' @Ǫqc̘KU9ۗ[<LG#Ǎqcs9n7v{ٳq^AR,hwF⏊reIyy_,wY>reǸˎq.;]vwY/&Q^#'gbe>qoW2is&~d;&z% !!ꎰ! ۗ5@߆` v%:E׹يA4U{Á'ITy` ZnEuQ)onZh D6\O|Njԋiu0NR&W}}{, DFUj|JG$.-suξ9:'aNẶ -ymTr昰 ɥȓep ȗ8ϗdpϡ 8\zt)RlzSɔ'>J)Orcܺ1nxo"vbOҾEv6Irx1 ߜ!Uuv1 $FAICM}Ҥ2 J|.vR͹̌|9+i ~H>-Hbjz>60JE8h_^Oēw$̓_ ]]!8oFl.!Qx??t ,';%s|aN1 xN 9:0.iE܅2e('R&s")ECdny.J+7Ix^@y.S$8MGi>kQ.S2K ,b*E4[qIԹ o" |{>;³˸Q\\l+%,BJ `9g;}ǝ :D#w\ud X)z}BhvpTeȅGR^}=&C<|ծx7pZ~\t]xp~Ey$ =V?fW ٛ~&SY|ǗtlB 0]Eoz%PCܖfلPmC䗲$Nps眵Jp IpG>R ؤ:IbVEvu/b,4ؒn9k?L6cxX^IUڤb۪j}&K*E|*TeVUoKZ%1O4FILx:Q_QĔu-4PI_BAZL%!uSv*UOy> *`1HpDb@5)7N\*gG~"ShO9:SN'jSÎNwR פ?$btumRj"[*Q}\]t9,"ibϺIQewYIxrTq.#-mK )sDi$)^)G!) äoRߘ YL_ T")']Rx-'pO>h7ޅ8ȏ 9i΢L!³uۮv9qCd͖܃}5/}0ߖrF#:LSQ^$vIY딝X$|I;iJzds4JХcg~>8%Wغ G mG#k' rl!l!`9~ '܁iԝS<ˁ\Q%-j,~I*j)@aW\k:kMs:>׆.Z^<$< Dokms0\$#;%C}0\y)qP!εZw3ZwrRjw|⪗4݊DY[U?/ I dDu21(W "r]rHD[;пVqU II#WSmR +x'1VΉG~H:F٤FDZ} fIoYuBE/$~͹'i'W#ϳד ٹkBng'TDeU}PPz}QG J7I qQK{IM:K/UHpJY:y1JpSPI +ruPCxh{UH]Կ"r9xRܔvV-lT1i8K)YDI;̒Tjd,eO6Yߧ_ou1fSבsl=MoHOlb/eblbC\>´k,r6NJ% ۔MYievTNu=^wh}MHhAdvvnZ1v.Uo$FANjT6g)c_vzsܠڤ5t*:~Ghvv$L?Т'Nk1thWvkMX5h@wY e{UDH&i/TC.M/Hm{d5+M?n$9f.lPsiT›\  ȝ!D,y9M,yb %jih}& rE7RS'-It><&mg/-4{CQHVt"(_:s$g-D݈H+aGR>_kڵ#qdh0G'4 \ _kCETC&YN 9+0 j'F><鎑F!4+L+IwYqIJS[$u.#@Dz jIԪwZ{~+K\#kliF 2 #׵Tn_g<$^hM0An_^ZvT{ݛj ݵEk^{\Reڋ{bI@:DuuKڛJM;uAَ$:aK_IOCE c45*Toutǒ"j% [!mkPҬ[,.-+lsMFMzb:AU )n~ R|i@c4Y<59ux߰gEK0t= 7h3&ge~tF@YN8/a΀wə4Iª'Fb6`o&ѡX3G\-E"ͤJ\o&=;6E\N_dvc7j%MΜW>ЮzLzN@ƣ(X3]R4ڝ"rOsߤyV&gM7L:'oə4+ܵ=Z^:Niy~d) ^ֆX8]ߝ?'trϋC(Bl":8a8h78\zCHք'u ;,q#A_AY4iUX+Ӥ[i&`Taꢏ[W/[ jhjpgT.ncD{֊IdsbDUFu}rJ ѧ> M^}p_IEtmMI2("urP:[~.Eo[o\3J< @ūr\\I~y.^l5%_w # UUEVVcE~j n n n nȷ굶굶굶0Ax^a^a^f A~.zɤKi~z-٪WX9LZ :EOr>tI[P&/!e‹kՋkVkoK&~~%[~Ȗ_5\!%%$ ]4'$a6ľ$}!q Ws7"t8HI@kBk+nR0ƥU7Y[,WتMM}%MIVD~j%WW|A2zM2s dȥ7ZiCW9Y5\[Ua&Rv2/O@x'z~OkǑUL@xG^<77CTAu V\4[!|[T-ʃiKEycvȠCޘLɤfeGqVRϯ%SDiPXa5G.W$zI5[;S=W{D7DҨ0z6MªثUtn/ܓ߭JXfL nn3&ĸwQB<qr%!N`Bj؜,rOhR QQ`W. jN Y嗎YE1;:# t+:hoOF3o!m}VXꀘn,uQ]s9oK? u@[@uZf$lk„K8sgzz~~Ga@.ek8͗rYa_^IݩUˏ3%_&ҎK-E4Sw&<:an]T;_ѣDUTaUX{+|jKt!z7Zk I.mz*I+%lUEI9znF7bu~@PJ* IRR C==v_×V.>Ǘҷr\2Rryéq5^5E@MkzKSI]U7FEͤ$a{vLRܢGEtU ]X5:G^*4CN1}Q+<}3}ӋEd9Y;N%d8Y)NVd8Y Nm'd8Y)Z)Z)Z)Z)Z)Z)Z)Z)Z)Z)ZZZZNⴄVDY3Z3Z3Z)\Ɓ΃􊞵zzzގN:r:r:r:rkUO-XҖՋ% d^]r(p:'ҒŬ{Iu?z'pmGn] DHLNAr,:tfRUUQt0r^˞\ \D[Q/"YuuUخx |85βS5x+Cyg5qǬhSDy+j(*uKh˵cZ17ssDh,3Ex~ y۝>zߠV:MjuսEMrrۣdҢCGR\;yTO/hLhMkN-z]R(\&W ?S͏GV8 G>2 ۗqI[!nG67 ps>|ۤ.-ʚ64FQ]P<4RM.d:I?Z!hvV~^{<1"JەMr*N!+썁m8WJҬW7mRl}i~z 8\&qUw5A +iqBswy4|jYǝ}%?Nx_ya"n+qp>=ޮ$ 8|} UQ"uG^}'=#U/6]ͧy ~5-!ۑS!@,OE3L0 o"gH{KҘ"5l%ZP֨K=6mi/:zCҩήۊV.o.=EԾkIBtAԠwjڵ\Nz&E$MѵƬAO=ͅaknJ35o7{%`!qGgjJfyX>Is֮yY;ؠOˀj %QY'] 2W{0-AyaZDN_XEi<6&]O+хh?=܉ Qon]Zjkzo=rY⭪ۢz 7ƼGXn)0hu˘p|IvA䩡 IӠcPK\ p<0nCb>NѣٓvkQ47օ*g}еO#S6޻-kёMRW]QVt 3"^>_\׊y2 :DZOQ$뺯fJR.GZSE_Э4.Lސ {dwр}\r|Nj|dSBE [47W=Ǒ'x&]?FM$JD.^u"ޠV}VNjWlNJ\~% xv@5 G+L7B2WZȷ >i~T I+!ū|yt[TҦU?/~Ӓj@|_ROM8>Ahq/a9ׂpjI=U0oyHO5}7W{y"WI֜ 7~&yU~^O4VFW5}{Uru*jbȤkQiWg74LG~c=a"hMlhhm9+苯@~#kc=םd,7 uV;m[_2I[-z+׫cU'&V"Rhs+hR+'ͽOS{˿mt-]?/||Oy~0\ouȋjw/CxG: g%L𒏴Zh"ro?v~q\M"F~Vۇ2$hOZݏx56z/b$ c2/DkAk~E[oG 6{|Eݕv Ӭ py*na; |^ •Mn?rS4 HsW3)$QszIJw[Ώmy ҽ}|-8~:a*@k 0Y1$J =,@!y6yR Y$uY+Ip+ 8z-J$iqSGm6)P;Id}׳sѠ4m.E˩KzW%Mn*KK2IIuU$zê-I\N]\&;̤IIY%o5ʕ2L{˓V7?Tvom9D ,=+!n^ "*Amv\n_ybvq gv J/#'͔՜W m}v\H1nK U "VcA3d{aҴ]|K%=j/`Iz&MWK }%MzCgn+"g_ngoSy6{8ǿjLHԛ?!k"!8繈s]袺ڽdz9qKIЭՐ6Qgdߴ\ $17G܀ VlVb9e01':y?|Es+"6J{_Ӭ5Kzk)]nfsO73Zgw eWI+.M&$hԻh)`y;9kke.q/ɻ&ѪBAv\+ :=Wziu߻̈@yUi2eJNZJN]E`1ZMI NZJ:xʭNoΖ'j T=yW_^Β $UqKUv&i#(4I"۝~(v1 Q#fho?>}ه}2@3p2iGjq=]ûN}qf}ɚWDTWti=Y_5PP꭫ړJ">x7BI!"o٤!EW2Fnj7&Wp&g7SIb‘ݠp Be)u$\ɥmimAUu߆s/z66Ι(lFҤ'dDO6iѪ*u>QHڔ-jl %j% )$[imQT9U⊶VX#G҃:Rt:ה裮J#k^Yu*Hm뒙&ͿI;ٗwiolOKK hN-gnv0Idzh,kۍVr*-[Gݿ rkN.H.ؼn xNu0l62 b&Qy0$ j5LEE: '٫hi_Q\d>:FIa4 DmIڟA.%v,4#-ӭa*bDLˆgNI(H{j7W3C;:FM)X'l%}׏nOtY/rY Rw\#IkSUTW\=*&3BV.ڛHA U_$?m㍐WW#% û# %863vM#<mG-AjR%t-pGqU O&ynxR{PnJRPC.oU]q#]9rҼ7tv/Щx}dM:p:_4m@LMtMD&4Q/i.B^B&oR1`8Doǩ@p5]_[VBG+h;< SkRJgQ o<煜&l.RSaTy%;_T60.6ʤ ^MjH#eF̠o~$UG z^R'c@oLmf %5ε;;]Ȝ!@'jxr}I%i6U6.B"Nwt '^ك;|;_I&J??jFwnk咴.)LX|& 鰋[?T<}')H/2N[zz_ZR軨r :U߽H fUM^3ĶIL <lirVՄH+~5/wurs+M\_D0 RKp}GoH?,rM .\&gUIt [.*قN#Ս3Qιd+ tMw}nܸ%׹wz/ҠGēk$anIǸ7¼DXKXx\41 B!X׷y{ؼ9|b 8,?,0qp=|P *q5{|F쯜={3gnaHS;->nO}Q;{374')fR[uW {Sq'Oڒ$͢MZ枚>xO}ܞ=>YGs-q[:=ƵǸ׺^+y BNy<4 zYig(vut;)y$Co 6`;C\.KG5_G|յG?M/Io-ƀGR#[\=fśu\XKGЮrq:=Du&϶I&mqHz,iv$1*:MĸX#'%`#[޵\ys-$l ikl$]nzIkl+tSDY^}t 's5+gIgu% XR *G?8YT2J&Hf+|"z2oVZفt%,CƘ4:=b<$IUgCƘD\Ct]SzQ}ćq<$A Gj,ڕb3,wv=y7. 5?o%<'&v]рs5 ՀAsd1uvMry*7Bge~%LY8>fZF P!"IМj\h…u|P!COu4sk/r_"gthf9@KUKtqڦz-m贬imDKt.)&f; uҬ^}oY1%ѧ>ouӬf4>OVChQY)v>ouӬ0l/ob71KpIrlgsօ ˿obЁob71o]2eԗt\]^2e7˼oy,Y|Lf2e7˔o' ^U]2e7˼oy_E|M^2e f2yTίbiNUbz8x,Y}I),cYzIoT~e[xe7Xo,cz12$~mmSmA͍}S2Y[on&hR'H&E!}OvȺ&뼪ϱ+Ik4rL)O}r {/I۪ynFS9yx&i"9rLHw|L1ATO#nwreLBĥz-:\va8/aemryQzCؾ?~({R=h^;{u|x\KE\Owi>;%1MgrWTKYh$OI/bMIx["͇Yw!ʹk[hG#%QZ tioMIg HIFv岫4i0OAwoJc6p ӑ'qf, ۵c-`;g%8syP_G@:\C2'LG9yoj%=7ItHѩNTVC*\& 5l6iCԘTiKMORC*iW3"kNZb&mfbuIV+] d0 ÉdhH+=e0p ۑWE9 [@r{@rrְBVv]cWSInR.8A־jIhߢ 7}64z[ _뾴φݕ9A:215!6=tЙvʸU[-mf^aUX I!Hqt'^D.%-rq\Rou%< V դKI[UEz7{"i"mZ" oDH-+iMvD4;Vˑ%LMpY"=?xPQa ݔ%}R+?]G_Q~RATz***yz\[D.4ջҞV4.Eu=-K:IwZDv.卤\-.KV.rf%s+O#Ągx~mbxM0ENA#)E=խQa?Gux@YIf!\}gvFDtOqeI@}Yv0iTmVTiox 6dI΃gѣyD/x+tId]kydҥ,"RYZVKRrWv˩VjCJҹJ<&ic"XdZm{X/s.ݫ$$"RʥzČ(_]۝UѤNrٕfT*VINהF;2e&ɞhdMiӒ7\N%V(LK[~gڢ$๢"0!`:#r5zA!ߧ:[}~bݳ|Q Sg㱀イp0(S랸k1s˜9i~+jZ$h?B}P_Πz*YT!YBJa{a.WC!{<}^' wgMm)95_uy@Z&MrZ$hWWi΋C _u,q[[^=ֶF{@#3H9X=ryԺ**[oɆAxqJl6N6JFzȏF9u¦ƠѱB9_ 'z>]s*Y#<!/ZKIZpyᑼ ǹp<XNé>e{.<^рzW zI>iWoJ7uAs_ШA:Ov\.CS׃$f$F;<|$-rс-z.OeNDtOOˀ+_͵8|]׵8<:Z [=׵8<@]}-8PrNHJp\ ã19K yIp>LB6!-E>]hKթ'%$:wIg-"{-Gr`Ru")OvQO7O%3Ob2Xf._pHʓF_M 'ٺMԋ*Ǔf!lГ&eԼ<[@N'uiq|886_?:/tq:8?G#rq8?N'|?=\]Pq8:xuér#̇eM?`DۨձcWGn׫W_:nuJ'".7nվzYЫ!CWzD꽨mCAԀ5߫#WGz(c^;iNFY%:2udqd?~v7V%CάºnXp j)kĕeT%뺀VI u,k >GgP #{.Geeu]h |zzxONEur|hmD<*r>*lVX+3)iou*CS%Ut=Uҥy9 -0z/L}U}I&}e۾$jo퉤S)5?'&ix{7 ! p.DŽ4zqhmC.XRe͏t2ƀ8'nep{չA@z0iE4F[G.iϟUVD~Nj҇J]4ԗ-&"kwP4C"aݸ0IΟv]$WqpISb_i,.GubҬ Xr>]Ӹ:_Od=7}wߞJ۽}in%wwfvz@#ȞYۙqI}Es\5W{^s 5C{Ǝ yI[q"rIҦ ^B]S^sE| zk6&\fc[RMEkyf^6 !j8R x΀r gy..gk9KC*"vM]GTrC񷑧H<O6`F{ TEo5$=׸{xңy}Na.r~]$G.1]9BYovH% B(͠Y9KTt>QwN WvgPOq7k7k7~j7iw?:_CYv-l,mv6`b8!td@n|n|܍/ۀ: xt?|7>o7i5`ՙ.&1"%U.:HEҤЖNz*"e[eTGw/]lwH.o:ʜpW۝Vb.XY'j˫mc6_FMkrZs/)%.YaeSHYl5uYcf/j"!ވ.4QcN\CKzb+&m6 mE\hI%VA:K^K=ҼqZh$=&F^Xy$UicIRňX%iP]垪N?Zyު.Wú^IbX{%2^h$1}l/rlFZ)9}WaaqBS%~ʶ ݽRfە6L nxIݍ>Q!; v:xPywyADggK8,N"e]>~E7֗z*:49@Z5V2<8@Rx^oh [xoaMVLI<*C,p<ЁjZS{#7 =h2C.Żj,JU2d"ωD$8 m#}xN.ӛ'\6:*@3D9`QPOY]9 V|/i-h_u0tSKƏ2L?exqPJjEZ1rJW iYD,SD n2 $u>3Hb !>yk>r]Aܥ+KW IOkErp_ )H^gJ"<2"HA.R"HA.Nj"Ƹ1TuΖU\dY- EȼYpKpt]Voߒ7ܒ-ܒ-ܒ(ܒ#ZZݒ(ZݒZ]l%)E ]NoZ~8Sn~^l=ϋ'Xc=Rec|IA#$(Y<=?lz,5G#{ [Kh!0kW{]aTñ]ҞEwZQE+vk΢բB.@ իīī FX"V%?y%-U^Χ]_{9T"Ah~yO0|6xԡ/ZvkR;I4[ؤ5*s&Qyۑ'zzY6ItIUI&-0vIoU vOIoW+MZTnVIzJzJƚt*9՜2ގ㒘XRϤ-jo#$&"9EҪxJofO˓y='t/`8N4ͦ{ÑwpHGH3&8 UӬ0\aGҦY܏ ۭCeu⩖WwLZE#|/С.:T;Ƥ*쒳0O/9g%1 Z51Z/F|EauF|NFؠ~~OJ4dIuOwGg:xrR~Y[cE.ͩt-GtQ@WF[GҮ5;VJb D۸Xz:{}$"K˥E!"g&1?޺Ior[?>iSʵ|3՗%uHw'MN拵݃.:흝څg2 1.?Vqt4;"ڷi϶n]j)GlUPץ۝EҮUڡڽi7 2no`_dEֳq( gR'LI٪Iv $=΍jcb$W /5ʫr9:?dž _s1sl~G8_y#s|9ԟ/t9N ]#x4͗q{Ҧ$x. A(h*r*9@5L$8"ԣCpSGEYDj ~@Z i%L*W'1/9yeV W-'gN: (.ޛlXzp,=8j'O ?&!2I=g_ϕ C dr܋gŌl*jx3{GcH!‡x!`?Mm M^c_H6=s&xԋ_ć/SO"Ci1(I,٤E6"[I`aKR'X),(QLqi$VD.JfQeJ It`ң~Qsj;N ~N ~.r+{o6/cczur+I:Ne >˒։}ʘf}U^u'=O;'׋րD!8ۏ$LhP%_8y xMrzq@M˼_꣟㊽z0\xD7fءkP~AEN]Nv)%yo#"Eg -gIQ iGTUO79=H6޷&z:hNiT}p+m.eH+iB.eoR69cw/WȕB[IiW[&iNzWyrEuT޴r&֏tp\{ڀS. 90jY!WrP!$oRJ"o 2L"צM-@uS~:5k˨2GIkr|o7iUX#xtS &|V 1*PY9vjZJ]5.Kv)ߥRFۻV(؎MjJVUuxN)K ӑX ЯX{ʀ:Kv,4BSIveLQ2"r{Ҭ7NcU﯈7ݎBRVi5CUu}kQJWԩ@O_)ުv<ʺ9ì4Dot]t;^IU8}%1e=a[-ilhNh5Ѻw'UNa%=@Bb";]JRyER[ xnAȷm'[7i|EoKxsSJ֟X.i@:WJjXtr̿n&24[5ե,IOIնI?fJ {mĒg_tyօ*ޠÓ{DonJ1/HDj ( wM:p.: KlfY7z/kҡ]>¼8 x_eͽ_ڀG{X.4X -IX#%$izI4IfwyI޶.p|y( 7xIU!E0>^Sw~kJ8QռV %S/9MRҺ6']tB$&[+"g9[7LWͶɋQe}ٷH^l)#[p3ө*bxxۮ"/QCpN{3y1kn7&Mr-k$*Z .mI4&]9nsY?infvT:&ߤ%of~_Ѭ^Ƭ^ܷ|&6J4yHzr%Лt R$Mf7^)%Лc7T۫O}o%aH۩oMV:ZݤC2vEg=e} 6(VJs #K=@ApT{/mî# #]$ҝ]p/57:OA&,H:ISZؤ$$z ZN}i4#n4W5}6%]orןt!Fk}7{V2~]7EGeդODٓqJ}KSV!g#)G'Φ9/?\Ǒ2l5H){S>Fy7(_/"hEB*7҄ICKa~zge^D>I!irާ{]/|{HYNI[GR "֛.SIp .P\QC@}hTfݢS[a9ó(I<ٽRҭ|.i.财SDM-i  m`E!sӊ:JwAt(W IH֐tIq-+pDSO/O%LwAZISTOՎޤc5z^Jut]5+P\Bv*iIfU<]G2 0ȓ1SPAn5^’6#r,OZz\'K[('MJ |}&~^I.RHgH8pQ:a҃R[DZl>pNUj1tT4kwև}CVچ DqRކ+l~eP@.P1%Ql=I)}CjZ$5ڧ3Gجx:)JW@vQGE(C ")j/Ýz*.I{B$Mxr ITaAL(%5Utiyc Ф׊(wV @D) ڥ8ϿCI!s7,yR2##߰#`$HI3W<,Er:K#,w=>z GAD-kIϒA['&Ix6XN҉IMz&DGSJA^{ՎGΖ}1> A|)'J{KbK!_m>ñJ AKߐ?]$Cשe5H\1 %>G'G=QhF(0}U-(OZ僉tIE4I7)Ta8.I¨s6 _Jx곀}nE7̻63xf2k@$" R p>ἶ B]$=gҼi|I>xuIEy?;坋wQFIċwVwS9)/16yOhJ%9ktx\/l9^p 2k@p}|w":?a Gݚz[$ª$n{VV=]]ĘV5YV),Ia)n/~?\+Esj|5Z+k$т.7c9c?֋6+h]fyu|Ф魗zxUuaRz}4?N?~o"== a4F9UM~'ij<սd4a1z DžSr-hG)r5DKTH68St(7E{у=t .ՎW=V]"=S.+:hKcFWΩT"0Qc^Ѡ.9Iڕ_QFR3wlܞ&9s™ΣqҦ,Ak\ºI; pnyaUՆϰ]:fuGm > Bᥛq}!Ei'=)b^or 8BZIob9uX`׵]shw$LJZllg8k& Ek;z~?`s>Az͙>Usm3FRM|/?}W&KnJt򲒉P,&)/+9/&h:Ү ոukd4Y!Mjdg'J..DEx<*f*f"Jeh"rYZcN? 䲫~^ZL{=zZ;-_ءs% Et!oQkJdJdJdZcy!yj XK"I5bajrd/,AY<XldUxEii5벤>|U}r*i0.k;{2UW&yhrd"lHQMv+?驧{OQ^reiUvX m=cujAju,I_1(FXbYNAL{DUkoߦ e0 ѷ %SS[F` qDLЭg.L\2|D~qq ˬKDEXEWP6{Gg-6]#+Qf/RfH~\dhίazNm-Ѷۃ AG[Z%S^#:&lmji `M C'j0lyD}6ps1qtv9'5o^[h,o.Z-V:R/űVU.RX+W]?AUFv(cYhk8?XVcjz57*VJV4ֆfiۊ*^ͲhtlE5=ֶVDfRؒ[4z݊QqjqiR kdSlݒ?@샞+"u <ɽrH74P0 jFoG ./X&_a#9x:+gKNAjhE)RЁ׋Hg=EGj.tձr "bGG;Dt*9:ԙ';C=D`ȽGlěһ}}ElR޶,{= 'x xz'k?Ce?$ICbOH[eqckĂGի!{?KD#~Wɑ X$^̼ӽ1ؽFXTG⽒⽒(XVyAtۍdzz) _XTQne" )ٯ\^?hGJ<WʹƲ׸! x%Q|%G|v%\jdjB˃|SokOkl!n퓟\:\CYHI@IzBoITwQӂAǣ.T˻0:D\^ūYVMTkeڇnҤάZHZLMK7!} "~{SdStyZ36lQ/ݢ%uj .9rO٤:u0-]tZ}Hvp]CНkTgIHoN)o3ۓ\@7cN(ɻ^m9qxuuv>Zm ݛ;Z1t_QAR6n):J:>5Ϳ~K&9zr>D;t D~=j[#s 6Ծ m E_ȹʯW~>XصBHx^/Z+l_-sĤ[lAM祌1wAM^q#mvd;BJ w|>a8 I>^\:.\2v|@t/nQJxNuI#A~4t$ Bmeq?ɻhҨk3!8kM*%UDmx-l3NQallӐTqmp@{CM7=Ɩ1rO4`)Q]ڗe wCsy~نEѥP/9g/k/I>E1O?AM[[[[[[[A0oCTuϡ:eCҫ|zӋs.lomomnmomomn}*߿?4!sʞ'76&IV@Qv!7ַDd[I.Oert\ ANaE i']JiH=͢CZ]roKߚ2({Rիrnzu@~ԫI:9CW'ԫqvC|U4\[kU'SȥWghmȥSkU'lkUI:&qJRH;FkU'HW'U $U;U-"ţ׬U6*luh?~uarތ{_futMe4HoR&똻GuU3l-Z-qDR5}!MG JҩCC기LA/#̚4lJ!"a*c5VeZI+$ڮk'EHʒ4*VgSO:~O:CI\IZ&=悞˰u/$a^`Iiեh.VN:n;z'7m vFК-r0kC,9P5W_q|;_-bwo[{zNgggǸ''''''ׇׇׇ7oޫUƤa.2vhW.,S̢ }g7I ^^0jڤ;e I ԅ3ҞMs(܊wI+smtGa]tx*qRHNef{51ݑ+U_n]2kU~pƇqZ9`*e'!`8t ݟ3smN𜡔(\k{4.;zO$SDIJ)rlyDZ:I'b5m&EI <yyQ|"rٕ/IxaPRoEWb+Hq+H \^cL/ I ftd Uj!in"b^Y:SңuRb/J"I ;I )@#PMYDLz<_nw@#DlGb?hEa:÷G>%SD< W/l .oH z W2h=֧An*UXoEZt ے& Qup% {>{ 8v_O MWm| 3oLsO,h;>+BtI -Fp@de " d(+Ӏi^6l ZЭΡ1wHW?'G<*0ibV Vj] S"ɺ"鐋IUgI&$SUj06x/ynN\ID4)Teъ*-#cӜLD&ͯt4-Ïn41~3d;8%m+Kjh *"'IZ&GF.UӪb4f\Ax ;(0fTW1=32:m9]T5IrhE̜>RH/"^M191Ίna a h d>aţG:M X.Tǀ8B^a;c:q#Q MRHJ=bЭSɡ$sNjjKG:L,iN:n~3^ҽIբlPLtk>[Qnr7T6"j_*|eL ":wZ0>Ul' ՘PEgjhZ 0\+ihlB˒)j]UtS,&4yTL m:N5h\h>h͢J{+zL.ʒh+_vʕ*鐳&]&CؤӋH.'rˀZ*17,sJ~ɃgCǜ^whNVSo"ҧ$wDaRҪyɆŽbށw ybބaxk7`Z!~ށw x7@;#X,I:or}ꕸwwwwwwww(oD0IkA'(^       '5R,ױģģIUkUN0'U_(ap_G!^    ']Uzģģ£cV.(((⩦[_8Wc-Vbƶ9@ҔH0tIYPp3mAKt*YQD*/qd\Kd^YDpU% rL*i"F,I;hFiV=CT)$Ir%Izēo.F4ˮVnz_LjTM3*1Po5c#pI 4 koAa%-aJY26"$zlFTe*C"iAJmFKw6uѰX?,cM?2Fe28X&\t"CB`'8".<#/{ zǑ00Ja`E^dz*㩼R"D0J`@R X~(%QJIUS:UKY@D R"D0J`AΣNXx>,łQ :4i F* 4○?z{ۣ5?AlǕC:|9egGs|ur>rgys7܊&ZUkt60' 2>엧~/^E >@/4y$-I=iUة0ɗu$[a?O>ҰWex_@h%8LIlG IaTg@tkv^ ֩5V 6D:Q핂#đ*Z`8ñ'@d>K#8xQn<\v#@ r}iGVȼ*(i?ѷ,E0MzI"i1DJSU6Z$%qFMN % 1zcJS==E iE6/tXO5rk JU?!UimX^xn]gw;W͙ Y.ʀE.d#=8 u8L؀kHC; {rr-~ EG2\ީ[U-iT"m'_߻?^`$tTҡEc}Cшw58V QW16T.Y+ءCZ*IcYds I]l<<9&%ّl֪͛ {7Ӏ킺3taBT7wkt>Tډ'P مBgV#y5s :& sRXϯ[cÜ(T"nl:HZOUAzUҾu~5T$Z io;P)R]ng]a;BI#uy>tWۡxu 8FO@'d;ۇN@N& ( PCCng: y xҩ{cw!lU 9ZQ_3i&>^qLM<9-ux0$=.%GY\ Ǒ]4ÑuN~ߤo]h[9X c@䩄I:겗U}ELg^$7 $QLZ".:ԥK!iκV]Dۺs}EL߇6-1'-JU͙&d?G*i 91iLӀ,kڑT@#D_iHP8"\ <zr+1 uHIoa}X\ÞuU#-hT,t3o`/1OrQ5xQoU'W?)5hC !!*=|"͐k@& |3<<ȇ!8Ci-JzϏ?)ĮF_S'uX}9zӭm@zѵMA:dNͻgSz5a%UX| sYx3|v&)2͜i:T%\d5QaKTagUZ{7PVSK4:v-r}(jgiCeCTaCU6vU΋ e QmIT|]:g}]eviu.]w9d/r\0r-.u XY!\笕Osˋk<..u '9kyqqY:I}]hx:h5i?¤I5iy*& :nOEr{""*a.X6i4ii0J# nt\ugh)#im"iaǜȌgsN5VZqՍnt\uj_ޔ !])y YIȏ@k1hQy.K"aE#(HxpiuMmҤIv'Ɋ3HĤ*WF3+K{οr)r]DBIuir$=[` UO=`eew' ida0^]/̮f zavPev V[vdT/L s镂f*AKٹ5tYuVX2NR*S뤿\V@֫ WX2^eVOFhAlS2^e8-b jҦѫL$UϫLW:2t^e޼ZK\BR$PHW?ؠN'pXR Dͩ&`2 Ѭֺ\ȍ0\U@NV+/!si![^ÚnU(yؘ4ֻ\%TNUG4-ݓ.O/ڪ0 (~q$5ֻL~xТ^Y2fJP>U2zgX J xk63֝]1dNVƲeҮˬa t'E<5OBީ*,ĵ~ΟӲ0 a:7\?RdoX~' iObL@V[aRr ~> ۚ8 E$b'aI@B7ͯ'!/`:5uֲubuu´.L[kb:񁗴x^cf`IأM~/nYǗ㻲SI',8߭pxbx-}|Vrd]*\ yH# WCqHuGqM9ᮭA5:rԫS^ݔS}^a$\fV \&)tKҤ[.c[mBV׻Tա /IίW_$Jz[5Y)=\#ʞ}~tj8O  ⵇHT[!q*   _8lwmf]$-*>Z,Rګr8Rrr I*"TG橴Vg56]oag {!X&V8Ϧ/>[C4H6p\ ,D1qZK}ntLUbVrE&)*Ev%H{*RݧQMYDwSyU%e=ƫ'?.t\{2(xʤOuPcrZ-[$߿OrwXuq DKЀɣMu:'8wv>>ϳ:8 6<8G'zqt}&srYJ˼g>M:_:ش+JjtKZ$m [ R6v!^'Q=&Q;E@$Ivf׈IZݪZ@v;EVv)Tb^Dn'vX̝D ~FѤդ_lD 8߫F= TvIn2߻{9D_Yw!:Npd"m,G*\t#Wj.qtҥ ȏ>1wсN==1~#LIx1i7tIV=U]>cEу?AYB֤"c%"zfI5cRi>܍cȤӱ^std22g?SχI=W?gp'iw;}&no ?`7:;}H?er>.M$`,w\ L%*tvqDO=Asyf&'q]T~5tVkR 9?Zͼ86q~dt.{$]{ YqSt""/f::Cz"j͐vzV{-@wV ؎#%rJ(9ˡ[@sdq ~$eZ҂ %KY[Et$IjTJ$IRI_-鹋DԊ&q*C9Mk"j4)뵤rIoB*!"RhÝTiĺI\?;RK*!{4m?*~+@K- i!(F~Sj`Nb7)Şwf#$ C* inڑF~KXSX4S6#.RRFD*nSai8h8(iQ퉠!i1$bM]b]b1!z͢]$ X$CjzT]G̫]SPf/K&ԍ!V}m?)* IGqfpHNra,c>es'f#VхVl]=Iyפuko Z,"Le+Lbi).+R$M~e_B! ?I~/)*lUh{OYa O }pvͲCvB}7b߿۝%C W"8÷o3N{$NZNeKߦ<tWMo$J+Wl>OtܤWiQ6I79ݾ?k<6":6":!9C$:"8FnD`Mt&:!0Hz:0H ^cуz=ed|`42(W^tDP>*I]2i,"_α;$u.χ sؐY2 ;^m=ERxoG._ZuJZtS4.D.H*V"x62x>M20:ծcD|@hpsgsP,E\k|ױîc] vHiJ.)ȳ1I:D i8'':NuP6l O@.)ٵص({V4x:h %vAʕŤSat:[3?O.ELMnslynM[SrM=]i%ڴ& _~ޤ*^UUoҪ46ՍWAr4j+wx/vRrN=~Pf39g >?X.]Vaݔmh j,ax?oVGDγҮEU=H|.7iK.$urhl9mwV`﨟F]0Qzi-YaC]ە$户+IU܉\ wv,Lp"H~eH 7'1..Cs鞴.pNj(Č1Ex3L?"fP;qK?α1i>h_TO[[[[B[B[BȤWC7}dTuYNҦUܬ۬[ 5o 5o 5o 0o-ENk3$ם%Mri /ެެorA̹^3L35疠3鐟ěI-/5K>_b.yR'.S]]JeEZSerY\+]:0%̲KX,־EbQX,ݎNﵛFi'H>>>> 'IV`'"jѪȕgjjjp}ζvǺiպiպiպi;nZnZnZnZnZnZNkQEvRogx_]˼o $@4Wp-\%& لiLhKgmDoAD.REI7qFk O^w_#/qT(2ы}:2e_8`TQ_ ޔg=ݨULo G_웖Ŭ.[ƤUa>נG_[}H<[5޲je՘moex˾14 -ً`ex>6JKRvIQ- Wg_u.3i]^gu?^? N.O\ %brB9KBy4\C/q.8t|pXt?&uIV4iWy?Ct3V+ouI]%###T cF|5%%0'Q; ꭨT(hL_]ʭidtI^\UO꿮 n{ߧRnh@|W" ߏ'đ: 7 3J^/F&՗ ~2&9HEKǟI͹~*iL`doRb2ho~ӕI rF6:ѡ+?/.&'&!\ϩv"@S. قa$ di'VTO5փKhoK" yVHN:M'XA2|yAyjG7{4;]\q޴4TӫT8UE,`+Bj0J* ϥoo+dΒg$OzO+lޢG~~-ԾYĀxOgo O^n@bd.`:[?+`:To!JT-_Q_m$͑)ԶIP'--:BԢtM]d!QFs ƅa %@~ u*? u`Q΋L[+?H[5/PJ;)ϼ6C}ЎOiWX=]붥'<6I^#_D~Ǿ_T1LIA2 P_G?BsKÃi]В3#p 9iw 葳 f=U/ozUoyM)zEqJyP-،{R ];w;<uzVK|ϺY7 2Y7 `Hg݀0 [8jQ"-5TY#-B$p\wϺH7 PouޫiD7X_ ;{}ߨ| op^M6^= Z;x́YDY@DwIC= ˵6AҜЮj {L($1!HEUt^VI5k$U5'Wm$53&a+HOՈ1 1r{Q'ɝ\Big.\"I%R*?5qqM%HUkK<u 5n]+ZEW&lJ4*lVqκ:Vt/I)?"m-&)Vxյz p75Ԗǰ 2 & $lI/'3\:I;-z\NSt]N9E4[8Eo":A8M-(eC0onE9Em{NQ(UhDEf&o:3>Щx\St+Q>?LJSEz% ۴MN9S__Z88߂woJxɯCaB@kױ[JDYa} `Zڐa/>h˾{sVy PkРreɓ4?"FQ]yUTeW}Ң>?&SOI_L <i>K6=XFZr)0>9ˣ|XΊA'd;:sV+C w)gu>T~Nu']w2YTOGwVxZ,t'ʹӡe|UemUtf ڻ't"jp#ѡ"Ҿ*.bZɭi@ԞeI5 Q*X>xy+z8?8n2b2wd2\52-4Hڠ|Sx} 6Gk;֗;,G Nu#.p򫙺?0U"'֩lU.tV}4K)ch/  ?3ݏ @< }.Tk& R=Ӥp%υJVWT9OzU6]mXnEtnK:eVaN@gIբ}EĻ}fI}]t+Am~к5Е+E. 3NX&q̌3զ0KP:Jp>: `.ClŪ@mr Tx29jßE.8U|TmU׋m,EwP'QgX`X|%i20>IJmjÚ]iw?MoXz!H@A/]B:gPKŊZq,.Ri'%"  )M뉤SIv;v3T;HkТ~ە?j%V HcR~ͮ. #8cEr W^!z w\Un5{^<sB)G~qm- ox`J @h~EWEu}"'G]E5/|a4jpzѠ^lJ4(~D pH d>|tw>󧏢G`u4K rP&]7]G*RdzNժGCQpd94H>l_p$'2CP܀3wYv(@ ͶCRohJ&ŶCٜ¬аZ #R Q0ߪ0-AuSa64@z^vC:H4'+8gY*mshXO axhX)xhXiVDRkxҖ@ӑoNi?yMB@uߍL\Ցow*͊h:N G~w- vk#Bu]4&QHAPvH/xJx+v{ulu񬧛2dw6y?~גoǦ764N'=16^Ƶ$j0ժӳN]qjf@iy)a8iT&} %rT(ЩJk:>9Is;Eep+ i~t E:K@uM?IC J?([IKDҤ3Oo1n-ua˩O%24V~_}۸0~C4j\i~ы] $zwj;-լ'2ք>S/ꬹ-(= ' S!p2 n*Uꢶ ?U~[U걦SH lVKI-E)ڧ)e`׻*I;qhzeW d8|:uC7iΎ9l8ΫabKТ5 O)&\333¨r*NY@ަq߅FEʯ.:sVsUZI?xy|+%m꧓CQg$?kXf |Zmk2OSGE-ymݧmw$ ДN ΥdӶ Nc#xi>mНBpϣPt'GAwmAwҫWhA3콏e-"&ft͸.rmƝĠڌ;iBf}bƝ#7tslt.8EI?=eRX x[D59Υc_|K}I=/eMX,5&8?G QG 8<:.{e0\4:!шj cѬ)}T]B+,c ޤ1`I5W!_X[[aE$lM0db?jj:[1;gvD UB,^XR'g}I+iOz_}[ S}ۼowV=DcNCmIڱZ12\v}ۼ;`;_mu<{mP풾LMX%ÓD.ʂ;鑳$@I¦tvIDt-EF~o,c`}Ț)9t.Q[f'UɨYo,{ɴJmj)uU=2rtbBńy,HE#@cs3+ARA3qtb.1|8cG,rW$U28GVsv6D&-zWGIYS&Uiߪ2֪|Tt|zVQ=!uNΧ+孤OI[W"vǤFy9w i g]#wvC|:5aPF=2|ġBU4F͢ _/äMZ [E<EsmmTeJ#?b_=5QԺzYhqƻdˊ0QWh٭0?rMjV;4j6Eem4]%CY .Jb3l;TNEǧS7=t^u9Y M?aiZ<҄I..!} e4꾜IENsҤ3iW "}Ñt'7A: M: ͎}DC}9>5\S>L<ZDD2+X2icNBB8yh0׎r>9rHÐ+$lc-h(«M G%hnP-5v*yuҦZO'=9H+\M:YhzGcctqtY4WѴE'[5wb-S ;Jh@Iums* Y '#˟Mvvt $-RgG<5POЬx5 }65m5<5<٥VҢ i$]^:jyr{ÎϮF]GKd J^I{Jw{^Hڭmcj HGLT0H2c PշgxH hnAdWth#ee,>u=2IZ :PonI4">u_Oyᐁx5R4zinLs)lBa\:ZpiGr=7SUv%U#IEx:)K)-d6t[ΆMnҭar$ܤ2l4' k-qg6RIIҮ*CZa*mΝފx:gtmfk잲]<6й0xYݙ՝Ymp$Y gYݙ Yh?"R-r]ZO|6*LSdМ]@iCi@ CMQ#&PlP޶phN<$HG s([/_xrJuh.>K ~IniUiFeG[ȵ;W?,bˎ !pSM*YLlzqĸ'J>nGGI>[e]x=h,sԛ4!+d\=S:D]dg7GD ZHbA^at@$љ sb.V"zr?vJ4lG $8gob?e7s-|pG$ XmͭmM ]fSOO=E.Uonm.BbEz#t[[[[@$jλ|6L\ޘqil.ZY%uuFE44yP>vU &dukukuqܵ$jmד D=+^ g7-\8ҒgwM 4ɥ_g5a3~VуnqBˤM~ғ)e+XtY;.\k8y#[]_դY[}-$nioCpCuX!`-g[hQsBJ5l44w~$ >Γ(i'RhSx&aJ0-۳撳lǓWDQò|}Xԉ7*4RVZ𐟎$둔AWn ZFw53.iG|5 f+|_A#ۄj6Z6Aۑet@Y2FtWJ 4: nuQP#3%Ru[ ;DeRmk&-RYvFa]$zШt ɘ.T]cbQFzVR-RRM[Z k %Q^m\R.\VTr"uJɬng2*Y 6R K#~H&ຬE-#dYG <'ֽ^j M.]ttBVuOj,vSDOmT˷>i0xOzoR0냴qq47.87R!k} Eg%W;US"˭:^)iSgN?椯JK~j8'hV$οA;Y)# fTKFGD|' ɵeTkxy˧V\9Y&q%ZH8s,R4?|dyxdr ؀e_ p\Ơ:t\(I%t_uR I;˪Ͳ%dҤ~:Iʪ,chv"PZ(.~JnU=%^quUO[i נEd iBث|J$ʓ*ORrk.Ȋp'UVyZ?*gY%m~gIAW}eQ+鬺LzK$mU>VZ?*I=wϻvc/ذ?v]cWz?ޏch?6ڏmkUbkjjj{ۚ\:[هD;TU~UMd/u#gcM ,VlG_mG_m=_m._m.R$zڞYڃ:9{sR_Ί@|9fp@ё}tr؟G: zѥ,)v,Us:DI9 mhK?I4Q=I!8ItI5 tN&$- p#b,aLE9vәC&< p*Y '8vjc!kx4@'\R]RhnfMs[6%AҞHDOY+žE<TX2UG5yIT2 XՎU&&!f1Ļa2dPQQFS_/:!L5I+"6AI5zM7KK5|M|ЪZL,Im:Ohlmw|n#OnK|M\G)n \$&1,HIC4&f%"aYzq:2o;FdIs#K 0i;Yy1Jb$“h%3s4h@}XJ Z$,%12ǎAMe֕9:tr0GېGuv v&!qv eoq |t`89c؎*/O =]4>H߮F5&$n`҅FC фh݄1FR/E{$urt@t)ErEo'̤=WډHic|q)РwݓI; u(>=ӧgLvɂvI`Ode5l],5 6~Q&/䵘5 qt಼̝0|ܟcnzS>l C&3Ǻ=8lmGX@%/x.{0h!eI<;mhWQ؋F؁g wJ )'uH>&u?L"ʙ[e~Z1~AfjЅtRj0SF UȓA{IEVO$ Io&e$r$ˁ'mmmwω7Ë:G~/^\^ccX`l /6{"^+3cco@]Kw^2enbE_O {m7L0v[:Q BOl> *5w,vT+@E;Z!:Q7=Z}GbG%DsHbGJbGbG]+i̿rՊ}}\KrbkSMOWt\p͏@ΔRU jmej,*G(]0 .sӒHwQkΝ);w܊:k4hv V˔ڡXv؉wnOm;n. fp)ڎB;wc~+9W2$ jt I-=cȦau I1\=MAGv;7ܔrH:/޿s0%9PtT(~>|P| -'g; ['~mÂ3 kM\|oG#pGIPf0)Gp|\R\yGӨԂPܜ+puzrzrzrzrzrzrzrzr|zr| rB@+ncr''Det$ȵc֓Փ#Up|7&WPwtr)uzrzr q7ngry%z^o&敜RA A|t긌C죥'wnΜ.S't|+&?,V|pRP PrAp ?EN}P{N3( nn5aPljr߫๚2Z4Tw?A}4ibW=jvdykQQ4 Od@.`:tbm QT#oAJ)vj<ܠ#-5~S֗Aq|#Цyɯ 7@=v PS@΋sm$(E-@X.L0Z9u*_kuCk4^l~ɐB#4 "%?)x ?5bUW]1vUrM@kqpp-WMӤ{X(壝=8vv ퟳשo4uSuGZLA4L :/uhߥ__?٩ `NƂeإv遾@@G% >=eW[nCW-Po/t.OAOW hmdR 4Bn$*:j?:&NtAaiR tNA[IDs4wCNtOtA@2ubO:\.nK͸m~0fݏ/"OYOYOUel ڟ,# IL3~ժ(cDo)n9&j!x T; tRBB ]煢 ]7]+\57ǒJѝW.%.xm=M"7&ADZ|'KyrrzDl4ܯkxfDGWRhܺM{tZ6PU[ :BʖlsѾF/H~J/4[JhotT]h8Ti8ӛL;ߚkhYԎir3}to^\4(@xq^nmp}:,Ea;SwK [T*̧@\:Vt+Xm׵9Yxxn9ƻAD~Q@WI=B!ьwwÞ秴:w]F2J BH rwUۡ\nOMk)|qt'jQ/,:_Ɣ1ex(S%qxLYKJN<*nxavHT7kzRӳTzh~!WME_?X rE6jk!$9 @4YҠ"(i2I+ONGh.ӳfG#ȠULMչJۊ!(y靼pSӿo?ʃS7Bgp"ȂG[57N]YSé!+PˡˤpǂiP)5gf33ę qfXGN\WF\ /,ZAr^h tN xsx^8}#(;Anq@<+6F ]Hr#)gfqȻ(p]sKp 8\%yظ~}rwIM~9r ( w 5\ 02=E/nX+A wYzٍ2fǃ/]{N^(Z~J!i (!Pw^(Ov @)]@;n{n@qcY4i)/3i:.@?e1{V"wkf ^|W@M&su@)BX'-U62HӅuy Z˴we(6*wq-Lļ\\"Ҵ;utG uZ@RUе"ؾ4vS ݝGsyy-[r8zl^  -p(M,nlt@V;2 |)QGAGw,V=5ET@ȥqOR3䰚D* OJ!ӟIѱO_c'ZoriSzs,2 \C2 rHj58kɐj_ )~9]}'J+wca+=S(XgJl`*[_د *}g}د g}ϯ͇~-4iPb \_>Zjؓkuuj}Tµ:h ^4]K:\t]HSfjq-JٶӍk{3x\K:kIǢy%>ʨ\I+iq-xN&W"@F]UrӍka{-xo&׷v zb}Ҭ/ɢ-}.7G: I eL[euhX噧N8fʩt?Ue ܽRaV +3L%˭} ht]5Vk9:[ibꃺc^iTF:Tv#hPRkZՀfct]ӷg(r[v Xfu򴻖{а4)cM!#oȶ2f*q?0@8=xCRo ?!ԕ "-|&CÊ7B~QnuQc4=uwI}@˱V')ݞRʞV95?uX*à ,ޔ7u~sL@~gT37e} ɧ|LG,5X xG!@)sڟ)p6 葔IOiR׎\-m N͐Kk@vtי95gUt7;UX%vP$Ua\'ɮÓ{,P(O]?@WWO?x9qyq/h5b4iTc 3ȅo z40P._ـ| \kxBn5/ݐ=ҳ՝J7d`Os'޸6t5_E8H#HMn|$}@3au ݝAJX}qF8s>MP9[=פA&;AA}rv>]92`Rw3#H^=R^縍oi81t=j{Pd)elB%Rp@wSnmup5hݜ*?*Y\ :V(n'sm_j۴l^ 9fMֶ6gI.][OռB# 婛6з9=k؀:~,2?jckһW>Tϻ=n\yհUo!4R<m^Jb9.K C,y6w(2,(-wۑ\ m'J̚A[ҹZn >t܀<" ;~E޽ uջJO.:nɣ@k8muzvM;zwirlu^]vkzmw^]nv7kfmwYݬhd}\gmYݬnq7븛uܕqdVt7+͊fECW@k{rzfw'yYޛfwYݬnV~7++!3]5t~A?XЃGF2<4p>#<վM}.E$I+:yn6>Y:Weh:>L;b*r:|ItssNͱN^~蚜gjUQz]Ӵ3}y;)aW ؼ(+.EZ]x>D*2hT}T l *8vye].9|S=*xit"g:y6BL i)9EntRnŒN܎r@X6e[mt*C@˕95Rn yv3[VDzPyݺ[A/@W#r;^n>i>i>(p(U2.Eт KQКA\pC˛.c~KH;ށ&> Lw\ْ3B~ etڟFt4B wAۂ?-q~bܽMvo(]A{ rw}ɏ%jA.vA۽sԎ6htӳ?@S96ݶO׋vA uݎIN̔y1zy<^?sx點_?}_zi]]׋7x=_ ?ן9-ZR">g+xg9>7Ûcxe&rh:fhҨ\-B@+Z$,L#=HC ӤR3{I,en>7қ͇ɝşԛ͇CzeZz|^#]<_^ļuǧ3{9?7 fF!OKhphpho WPrI~p9`;S3>>*~tUg 9AQЇAz~ Yk5H[=L#jn=a r|u M8r^q銢qwJv!H+n/c ۈu؛~vSޔ&7arQT!:ڥq[M.e!-ػ{Wв?'@y{hqԧoR?вt._iJ4g.@W(rQN8h`CInPpnZ3e wvFV&Z}%Pb(_'Ղf7 ]@Y8 O0s?LkrQamvsz)Bu2ΘK/nrH؂xcPX )F שgfb.G+nn=8'dw|쎏?d|G`*p*]r < "dkl}]hߦ`*g}vlgcm9!.p6A~NSԾ :M9W.p5W4C&s5_s l;O]B͟An͚ABq@k295)<޹+@O9 mpR_oNwjc''%\wAiR>!9/i< /9\>7i{tuRݳXP&yfečsWk駔J݊ Y*CNC:]vz2% @Lbkf[,P`(-u[(i'Jk3cغ )F=/dmaWD~(ΑLq7ʰay NVLXh[t?wNe"u*J `9mguH|G~R )ga#588xǴ]4e*V%nZM]3 6h:jԝ3@9ݮO\_=:ԢuL/FAMYԍ_3%&SWvSߎEkCFQoOx 8u.ϴ1} ]#)@5lt鰡ӱd}鰡SdBRʀc47btD鈉RvjT>1Q J(;btlc#JA7O+nM&1L Zww:q^JIägӮy~ &+a `n+=p$ 7IAW8mj_e#pp.[~xPp+[;O֧\,'Sj`Jt%*s޼$x"KS<}f5{Ht9ښfJu$D47.Z.'P6MSKCir"?f&(f6vLYآ:TsY# nrܱy9!hgf@6loK@3MSwrB˦Mq|ýTۤӝ>q*K I {5ԝ8V>X!GzW Pl+OCs7<%[]uԩGTCy~N3 9sZoݔK7d7MAOqfv%9<0d;Y݅f&\iQv4@NCzK W6oi[vO]ZHX MIZf$JjjjJԵ=t9/NlLv/M+]aSʬq}O_+]KB)9m> /XGG?xMҾuM؊8e s\29J9:Y59@q\u :&j44iPn?<8 D~ڠ4x0<|'u+|r%+#Ťir9rX<$_et;r zoJ^R}މZc>{zށG]x41Lcw x~߀7 xvtMiCɶEpMڝvnʑݦ37Ϫie0";EAt3Ҋ֚!eP{dF(1E8&>0LhӴ`pF8* M2x4OWF],0<';.<gzvLr$NZJ tc|=qDE3}@WjI]V(J3, [F飶6"|m4Qk41ј9 P!m%lZqA yݸ.-$,݄na=Ձ́`r)uC]t$rmhOtT6ALcmJCSw \xB5 cCR*ӚӚFCHӚ­Zx9 PFK۠Wq~Jkp,hԢPrEi5;͕V^pjjE3=@'Oy#&1<3ННȝȝVĝֿֿֿE$*NNNm;;;;噂ӊ' / mZӨ2M;C;C;C;C;C;C;/;/;/;/;/;/;/;/;/;/;/;/;/;/;%;%;%;%;%;%;%;%;%;%;;7f_wԁ[SR[BKA kP鞂SaQ<)z\[AJ(8QvY௠ 7P]=G=KCSN$2m39z+힉珗`)f ]Sfjtj1:x*G1 =g E<'ξ.Q-m0_Sj5q'?ɕ>F (>kSM }L珶隴)5_6}_6}/3NrOӭۗˡ An-]\?I4h} *zD ?\W|v\%tP`IjL9Mq4i@폖imӛ!:NEAmQSU P{@McRҀ<&9fn*v5V~Nv䅖J4`[M ]"qbp@1Sp(1?k`ugzʯ僺cΗĒrX~etAqa|ca|R7Z!=u 9sA^%|!={S2}rS=ȭr5ad~5mǜ!tX&C n!9l꾧e~өd~uQX8!p^M{wwﺃV uRgnזlE7n!?\SwډgF ' P k'V}K>qMz9\#U*"SP%\tS=T;NS=Tϛ}:^6Vv=yzޮ*wy9~nryv{=^ϻ{=^4`z޸7Sq֠Ň/GA.\I1JS$Բ(؊S6̐ex4;~,n`S.#F=-#+o V 昹Js/ ȽY5cr%`5c?DyaIP XS'?ɚ9)؊%|;)N 8ILؕ(OCPtvAݨ H? \WU#ᐢTC@.C@Q|-j ykozDtNS4\O [g鶝Je P+> "!..s~z.)LEH :,~#ԅ;kJW%@( Qԏit3I% 궓{\ zj.Qڠ$U@;7%sK^xUhҐ"tLo[Nk t}NQwM"ȭ*խ_zjoӲu*Vڐmp@^,W ~(Rmɬ@_:AU( pU)xǹguJqItJvZ@ AYZNi B@mTWwGW@* Wd策u}vvn1KdhM/xʂV4}3j@[-G"<Z\=S5q/PZ</0.ePy~)3<]U]L_+n.3rܴf:Y_iPQtbмhs/4vrUN lڍ@' (}CjK,X 佹{wjeyf4ܗzz2]T4BE/.ӝj,m{yZW *pЭG^ P\EǛ6o8TURi-:@i]e* U@Gu}wAG,styr X7k+ /u{}&i_)) % 4&-aZ ]'tu:<}>YZЦo &ke&/ &M5<˳ffS^_9YY'h]ݓVדmV AL˷Q/\`(_r=ϭTg4VK4-M j޳c-aWJjۥhM4;~?+UX_sXi%7%:e2O~V9 ̄si$h'7翹>i)iXx]Hrj&ݴW>Cg)i\.r$ԵI##?6O ۶`MO:Æ^(ѶW]ms-pT,y(0muۆւ+ϼgBDAW<۶Z"] 㖕۪ '(] y-̈́M=Ȋ)ȵ%Yxw,)ݟ5$@n*Y"%9/$ho3ҋ]m|Ґ 999o&rJ/bǚ(-(/^ߥ_7P>Us*I4?ShV)F19yW(\Ezi>%]m']4G=M>L2J ݔ&/F;+z:ݱԕ?D62diwsX*J8| gA c=EX_$~@+pVz*xCLV,reеe@ ê+5ix` ?Jg4ekn !%Suv9Vu%P,ɥ;-7_n ,JM%膞괧[h9M=Ҽ-#%D_jF_ӣQR V@ѫܯSyּjd`[Ŭyl?: )f|JRp Ng]\_)K49Z@So^VQGhRj&?mZ67G剠䠻NL,\TBi{$,|E \ACr۝QreQȴyzI= "}1b*mԐDE܂'M ]oǴq,<[ biXZA,ޢ\.IÒIGaI~~X^?,K4{In1kEt^ؤ`k$@PZu,]cRJz3be9|i YbYXW09^yCU>O*.4l˖gڕ:Ģ ]P= 2AAMOOTD CSpLSvJ $Ur쒪 tnpRHRG/JeB:܄r V9U<>Fz,Ow2! i6Jցv ?$咙"4ù}sc=nv1k+J;mE(n[/׍\,%s7pΗ%ݞC2._9˦"@r>P7YbUyPw#){@n:F#PICʰ2 +`l*5CXd +CZ!kⷬDA~Wxejl*{βP67HVCl+ʠ3wIۯ ^mWӤqk'Mt HK=_ڞ/m/imܞ/mӤi=Mڞ&mOIӤ:S<4 sK%|ޞAmi읝Wyg3Gyw^veݙ#;/lig;/茐vymwfK;/hgf:wz}K_R۰Nv[v˺nk\qu=[]zY5@~Ew^[qGI#[qP [^?K,{"<"f! <G,8,U~xz ' q'77 /;AnA$-SSΰNnnD! qB9 wcwPSm ~œϱ]8Pnr.M'7-ܯxr" 2+zzʨ***豚ge^zr*{ye0(-mcZ9Jk3ezJۉQ9IolBqSy0$>xxmva0Wjl.߹Wp1p{(x) ]Ӊc{#R SOm\pF>#}o /?w;GGyёOȧS\+H4!Q\^n.黹j s&}s͕{Eʽ+];)|>}+k]((;G*MoV*xJQYVQɳS_+by;Աgqg )GO>fz*揆 MUHcvټ {鰴i'dFzrܔRà?=󙝖t?+~:ئǝPܺc]S{JwiObͥ-~-8 EPi8޹; PZP>n@Nwy NNg4E\7@GjW 4:GJ]Ԟh8/ۥ,h: Bks|ϵ)׋ЕqY.h-t;G7Ƶgq;qKǢ (5)-ػթelnu뢌G/8zmF-۩펺/ R[ ^[=.;ڦUp\؃|~:W>ÃPB;Zet%Np-տP/(14IU'M9ݮPmjԻi(>ϒ *\rT%Dv`I{-`p`L] NwG{d1)--Ž: ; FYC͑Ώ&fǻǛG J1)\nI{l tANʻ8]pc ׇQ7C]Tq|39XJkv^X~4=i ;:`Pb!4u̚ i3׆',''Աʼ PCbRԎ )ʦ`QܸOr5? g sh9t );I4z3=-.@ҠBrxI >^m>^mR{GOxUpAz法P,+w>NJ7E.ǩ\مb?8M)x'JNt6S;詴Jrڭ]յ@=4:]c ոFR%RroS WWZYyxE n=v)>bAӨTzG~:ܧY>I$Ƿ-N^z[Z YV)5@g6 ~Y'M] MF|m^ WA_'i+f*mJ3 r'5 ]$δR<( &G~kUZ.>`[sPhh"= ysw7~A9pzD-[CKRuVR[eRNHP9 H{2=rkDrMJN㹷tQ\W_h2N5p7/his%g[.ȯS+%ïK-@F@=BVA#n)e7 U PMi=t/݃H<, 3*= =t"6kYѤ{4K2 ,򣱣k xm</ +JDWr=j'pջE3LיlZX|Z JcEonϛhHf;[Eͱyzޥw ȭ}y byfĦ%h9?-VAOPsZ9~CW< ⠜{n W#td2-a(;MJ!9=B'ZELf&\3Ӭ|fr53R2S>3>{3S*\9MDZ4҃Dj303Lf&R3Dj҇73Oj!0K;(X?!G@Q%GK:n޶$fbbl-Xz_9SCxwC6зb6x[4G3LwogW["Я5C):O/U'=Sd3a:,y=Pg^98p 9?9^n=O]W-k3c^Pۮ]3wk9yP,{TުMy ʹ>F@k3<^X7\a@s G݄SZ;f.x.G;xG~@wO2)xGuxl4iis]}'Uб?n3???;&Ӡ"?%HUic3=/ ߕaJ=J)v<˔AŕaASpUӕ!@I\{啴aU6,xͥ/Yk:wE ߵ!Y|ƒEt$EIqsJP⁠\Q(t5p;J]b@31U^f c.: <-`-oُRW4xfS[#JTT2 ukr/Nm?U T2m{CZ7㛉9}psAhVCmCe.caey(+  XWO\O|cPneP4F)̋\l5}pP`bBx7]'m&Nv҅]&4`X^;!Nܞ2ishI4>U,BL)}%WP DzGh!6#0(C8 t?5ǂQ}PL pO٦9 UAnS;$`Kys)nErhoԐ hSS@+nep hLI|.{ۊZ"!e~>s_H94Vɺ-09,$v/kv\MJ]\:nRg\7|eY|oƟ:^h+?iv6/BgU`zSB3ݠ$4l9G嬕EӴ)4 H|-8zpzls5m&@jUCϐ;nQjj+2݄ j{R֜+kӞ3Ownw3_wypR44Pr?RyקI×R;OC{ #vỌGzA_,%){8wwM]S`PDzSCIV/=VPѕq[yV޽wo4ݦo;/7:[;0[;0/, 4ݕݕ i>nӰ69" ɖX1H]]-atj9nҴvSvPvvN4Nr{l]ĀV7vRX( Il&98<=7Pڂ?E*BiR'Cr@/0ۇϛryβ?[#9֜KzrR)ih0;Ž#@9i:Wڧ!nD\X4Aaow< ]x+'+GTC^0^!,zzj^ͨI Z.9@5_/Хmv: q(ɺ5 ݠxԣeϰ, ݰe.m9xNP)ڊ4Z\wL3=!Ff⛻n>Xq \B΋vRYf`+n?9[hftK3M4?~Vh;:0uKWI42=JʹS!9LcY#n;җ۷VOkb0şvV7/#`gOpoޣJ1{T ݯKyOv]޼x u<ߩD?giIti74T9=Θ7Xy1kbRӓlLIU9"76pT m5 qї7IMRkoXIcs^HoWӾ1 e >\Rh/F6l.A~8l `)&?0( TfU< N߇"7h?O@'-;C7*5g&_j;/ӱ Wڧk(T2_Va9ЧB# PyJKleCDo z;.e?\0 NmRސ+q&W4 9]hłp-!2Jڸ`14MN_Ƚ+n6)Inv =Ln> MOi-Hmli)=WZJQuEh:8zKɖy~N9—CPS4LWYjU fU%3YAItLl[9i܆.PиqstL;i6LOoO,=ՉiRe\eJ mEUztꌆt[" X 2GuS=X<,ZJbsG/y>%4[h~rAǩ3+#rtt,J k.%靆~#h^T <8ɓWiTM.r:i iBp?h%!9<~)ڜ?L7=` \Դb u]~ ?<)~s9*W?rVyX8Ex\ NejoN29#:GFl9 (b}<9D֓.O^INld7pE9Ic8g:+XҨLHqNKOImCԆ!v^-z%:\JC/k!Vr9^:I!|ڞl=α)`\o-n 2 ~o}?ǯ+~eQ }ǯ{|&ҫ8VE伴/БgR*j}?1Z5W9y1N^#Ϥ{Kp']%82 15=:qh9W$4i8W]_u/w`,%(n jqi \zޘK逦=x^* ^wYry w(rq]g) 9G{=һx.^IK%\䚜m4@Joi9Zu'I/r|?oWW\H7+\mh/4;\H:nE;nשepr3 "WE.+s$7fع2J;N =#j{/te2e<<@3n;tSm YWWɐ\㒢jO+oJ)R ,lW2QsC"v5.;5-Ak+ u4Rخ}YL\I4Q8t9ݕt[Fn va ~KKY UluҷkAJ%4AAVuv V5AtAPA=g,#Mg3Vz룅&;I|zDHtyZ=u> M {DzDzDzDzDzD@n:K59>%>D0 k%}Ht?weS\^;Oty{joZpjDf%xA΅Owᤆc֮bI(uJ5l=VkLk& @3C!-k^S<o4!_N_N_NA]c"5p3rm?] vkXoti*üg|Rl>ӆ'@ѐ 7J[,O[,.CiqU@+~nP~Rw_ Oj .s=E t )Zj7|tit[a mt~!ل5+nۀR6nܮqM@g܌Rdp7GTMw%nπ\WIy:4!9+OWr"S} );+y&hSXr)`;ׁyu{%)LIN bНg GU3A =ӉQtAZݥhfRqΈbtN@v>". @I#"K771]DҖu?whD%߂HbN;e:mi(`wͯGz$s:#kZ]0O9D6  zj~^>ң wl:''Sx ؞,=yuV9 ؀c%4\al$+lh~@j{F$q/rҍ JS ߸F))PbI%5-p,ryzNQ\-6p b%JKtCB'fM<ܕ@x͑UnKٗkn-x57 )]:KH?Z 8YړVƂi޵`+8Og *[rqMSXRGhxh8`ӖNƆW|xxH\נ@})է/؈:Osy[A#-a5[>^%eF,#Cgh;ϚDznl"9]Rܬ:9&9>z(o#jo&//R%X>64C-Ji{ =_eyCLFGGTGAIw&]Q/ډ/-T֛Dʜ1iĭ`  " 4_A(aز7ZDU-[Fǖт c 0L8Qˠ\9BZ.p%P*߀ 7ЊRz9 #Z\cm*SE$944tکGGiUwY %w,론k )v7crrf(hڍ@AbOt{*(hh )[ܯc"%5) кY^sx *ArGR3\=R,yçP<:@6\˾ yv$eU)RVO.]R]:@εڱ3uMjXk@~nh"Yo];d;YX 6Na)~JG@j:CbZrHL 4(Zݴ(!CL׳?XB\O9٠;/ߔɿVV8Lt`g\:ׯr=~Q_:3W̴X^]P\Y,p: pLAWa8o͌&P^Lj҈pof|73oM׿A{vS7:92!õ쐻;M76^z71͝oצX8?5<'ua<Ӳq[ίLOhhc`ŕu6(4JZiu ifiňard8B4ާ5p׭c.kQ 4C=T׏Ld*ϝBE'0Ɵk7fh69O_8?~PYv`=U.6}B;ʍ_~Ch ]م +iJi ?TQ.!@Vilx JˏS WJt]FiTN%~1)Or$b48'9vi z$]nw#&iߦ9OV1iwmHoxTǜ =7瑴hUyP\yNXDŽ%aǷ(n7!Zi<%?r:8YMM̔ v_¾sGi7v6)!t$x3ݭ.Q`iJ4_$R{Z^>͚ϫ'YТ@Rݬ<^y>EעOV )ϲ5_V6@O1l JJexYY_֬/kgKXZO_VVHq\5$i-l alyUBxYO_V0JLk=E@۽;/5_/k֗Uó+Ģij+u,Z>hׇz?Ow)/]+NHק+w SzM֘9׹PZM錭)1<gU)Ul(f3si0RR uH vOJ/w@Oz*@)u*@ñLש@1h;ۚffo`75tsmԚ@sQiC.Է@W9h95 N% *h4"en׿_u z& ( Op z ]eJ5 Yu;G++aVի9T%@*z^Gzi4:rZ{)j_t2x0jM_"( :;@.NJcPv]: nFߡníG8iNg w_uL~æɇiptڴ^6MA,][m-++z+ax<|!]\3lؾeа),ߺ[pg>kK`Z R-\j\mN(O{Z#akȣ}\2rtAƊE;tE]P2]Fk2 PJI}ڶbe4B{D"+6xW,Rk1I݊]'+uAvHj0 =SznZߠoжɌ|~iy&f}vAƻroO@l#|R_#HC`c)gxR RNExW,j\փ?u%CC]_š+ς&?i\rew]Y-J ?,l2+w G!NPw(IRS@[`:BN2k7 ^j0vinv=V@.lfܮkiNnڛ\צH䖐<&xLrԵ:!?M_г( |?_Lu;O'Gc9wVzT(JvbJϹz3 T<~"gFȅ)6)E]Cz=X/9 a:gjg]!^ov $z=Dc9UZg$wSC/O_R:7=ӟSN{jW6i@.[OM]5.3tB.[&3h؟"˦nd.lRrܸ R0.xw~-9$eUFu6["d%l2V0"Pu=Pcb\8q m<)Zy\jY+vl HĈX49Pjw^dk vӴM4m yPiAj JXN vb7O 8]y*Qĩ\m/Cu.;H~De 35vO`%ZUNA38]w|=suT@*xr& g^^:aڧ48NvLO Pܜ]=Hk u\MFVPJyS nBz%v)z_q|Z;uU9lNm~yY6-&A#[ۧ{`e#ξ 0O!>B(luaaaW>K>KJL)D:J ۧ [i]  Y&t2\E\y&αV9s2LrҺ? eꐱг?9fIH3J{YO#$˲hͱ$0M$=HO/$6N;Cpsǀ^6 re4iBy^vqݴ(7-iQJ%j-"OqsˢHUp@typR}]\ qKLhlDν|&REH Ym3#rd\4FVBp7 :l>>w7Q tUBߠ'9ld)l6iH4:A.G ]?r̔"9H`V9ڔpr~QIMg߶ xxRUɱ>t]Ѵp,ZAp9fJj~ |?;R@ɭC7_kc#w}Zqc^}I>L;nQ46OLėKy}ڎE_śoYfMiu%i!ՁH1\=o gZ.@#nGye{>ۧy<,=H\7%1ɩMN_sAr<}jnͽHGK7S3Par h\h t Ou\esga]BQ`+~e,`!wN cn|BQ#5ʺNmKqkh4U =\PrLC㵟Пt @X])UuhP:$W5 W;Nk tJTtFo;{EBy:簚6V _shDr OBgX#(PbyJY8 S]3S}siaɟ_Z=vl}Z.O`!ql [Upu c;vlڱnuZ;1ϴ(a];1vbbډaj/U9Jc\T\?1vbN ʔi'@QĈ)nE#j'Fδ#j'NLN|~ j'N̩EgќY*YUIw<42˔ B)%sVǻKPQ\Gtr %Dm" htc[E6v>ׁ$tOvO.9˫lZOyԡ_ D x[GUgK`*f)f\o*?7[b@8lle5. d \ ǂ5Z]L¢*PǏ W"϶R,蜐D 䏊$R:^ eW6s\u:-b+[|H)؝['Fa$@\J)76t< Hj sH/ WkCQvb+T&SWW] fW(Xaɏ@ky<R Α9WpA99w`Mޥq`O vPq 9-c{|T0bX#SoLOzsdtMuMM{S; γTΥse\(<kJZ45tPWfΕxd"RRD6??լϹ]9r ˵\d-*9OP]!: jQt&s :ZtO؟r_V|϶M@k5]AVrK@ЗܳE{Yɽ^Vr-՚eM85\6AOeM pC kg%qB~|?ע-40e g~)?Up䙓-ȅߍap<<l4۾~!@|)pϻ C - r^ZP yrgק~]9L,ӥLtG jh8q:K? V^-l/RWb ȝHŠE=L+K)_cyO[-&?~Q6\w+۴rM ۴<3'S.\k۴(X Nł7 JKAӊ:SI< ,Z ȑJEcQ6_ {,XI\6eɱPUiqKX&b4B 7L?MA;tEh~!=h䯌8=*GHR.g`/80<]]%?Xkx2<=~爠'ՆT<"z P/#nEʅ%M\ELAۚvB^ 0.C1Q#~([ek 8ҲYa/pz?&Rw \li+%\0\SZB5RڟmQ⣭GI3vu+wN |t?`u׎r3gp/9Ir܅e&G.nXF/߯E5sZ!c&^y ?*X ΝRx(*Pϱq?2LESgZnq Wl4 -tL7OR 4VzBPd5Gb+_RJ*vu;II4ݬ77lO%7Gݍ*e}a6AIm$-w)ҁc=u ŝ+gHWw +0}m]; g [\t9E'p8tgӣ"]'&QR!qSwt4yiH.z_g\"Gr 1a+s%W JmJ􌄽)AHixօս?rߡEۣӢݾt{P y9+!xЍpp:h-9դ6eg_[]G=RľG/_ωws̷srv]j{r*8-1 ,8vy u:fq,XJ?fʻJT3cElPguݪӝ|V@Ue±N*8ݞ{bvб7)n/nϩtt\qg-бf+(9=)I̍:/č4Nj\cpC?zz3|O{H m'0'L'{ KC{2~sZN<>%4t66wwww7nvn|n|nvznvznvzpCcfWfWf/f/f/f?f?f?f?f?f?fffffwʭ]{Rk]yf$!RpR>]]I'>L)g͢r~nQpMß̫< f@iO#ПU'~kE3*>h?uWg8ى[ {:iӎ1f*h!<=Ys;8]M5ю]J4J5{9/=·Z^s3R')lOgeU/$K]hY9M򆤇:v`>BUpCgַKGv S5Rs&[>˥o-mHAQw:QI6nOOL AiK$k՞%j? ?5t%E(0F/Fפy |8_哯ɂ)}K%ϼRe L*(/|u<ӚGal&9?T JT%P\:Qn-Ʀz~NE DMnW5%Hشm2J\g+(N%?s&/:~>LnJƃ]wx/jAr\!,/zwoxC ;,`ڼ@s l;â0ϝĂ#dػYp@^;neKk@O-?T\}.p$)Iy,/ݒ}ߦBm :߭<8j(:ӤЯ7&,:@Ǩ(%66ϾF/M|TW4CvתԲMhbW(-V PGٯ}=Ncч]kfp]4n ~pcyq5m=uZz*oC^n.?jmOLq9óAl{(=]z{(ݑ,=qص=vmZDS `k{`i]lejn$ɦ#7lir;j㉫:2+[G@ TR1 80!/X CP(FN L|·DpW#8bR8l6jzj`D:>097lj%Py'NI)_~iy0Fs~xq<ͩ`(P ٚ6vf`^У$cNc=)=?^Pqx*̴̣Ӥx6w}TE[; Cy ۢez gݠorz~j)壊CmGLqa7%)44LJ%oDiY`eVIAb%K7۷'=(^/K^PiwTo8rwSA/*lE az-X]b^YPҞWKazOwC2>ٰ&W zki(N#Ji#Iۉdߧݏ* sHJW%A9Ln,,v*{;7c/P(^KSSS^J+Uز&uT1BUdvz m"gI=%(w'#.=k@sZ=5k8_ a1vxI6^$S^l/T yCJhHW %>6MS|m>p7)xR~|S)ʷ\1s)i_d Mڌmcb{UBz +/:w+_*I8 2NTĵ cO0V/0gŽ@K1}`G.xU1RR&>~^oKYy`SQMQ|ô`hU;Mv XM ?CVeAӴCG?Χ<ΐgM{Р9L w]{}*}GuRad75,H-JSor2iAJ=unK1ͤaPJҞ7Kz2}7@`_!oN@00[w2JBVP6l@'R1ܢ5&sĵMg(s\ =]1} k B#ڦPuN2r)h|rhZGE@0iބ zD_ Ty͊@!9RhU4MR|D=P;Q>FMH E&5~q\IxrI2 >8E @0f(`Z9n1DSyܥS9LgTi8vRJcm%Zvv*Xäp>a=>-i>r+g\%m+40FOy܀asa:\H{8ez&9ʔiiIYdAK+K~C@sI=p oI1J >gPc.aܸ3mM=*ߕm%)ɅGsM1*9n/o3.t/ybBC.)Q+{?J8\IMM$ $6 4-l⺓Mɕfn](Θ&u@~[=Z۽7}ZюFAa, ޞURV +85Z K.y*C@DJe~$!0I>]M*ej7MQ8sTkZYMO)ZOH U[Ո @ jq,qR|\v uC`+I<_ڷmӵ3%}]Es(zƶaR{@O[wB5-9 ̡@K"i|Zu 7p/\tS9`Q2]>6&[!z<N(U`|~mzNpczmPM:]kR-k֔=>eC_"|RJauOS1T }ך0Ig  }Rɴol5ga6~? kRzaMkBq{ 3-q=)f1A=)O2T ?1-z;ʞ*caLO \.c]}z*Xi8R\<$\ohvUJm =U4c=6Gn:,oT -~URu<1#R>CJѓK>ێ-tfdKPw?4MG jE?yûbqѢA.(Xa-n nq=rtْөΜѡe.ӵ/P0G(U^W5p{c,nrYr FLnirSVA2A:Ѵ"C²iR(L*Z-#>ݮ[qʛ*+M9=7'W&MݧWkzD401FT/s*_Gq=?MCkT\Iqn΂?vkk5xm [[ͥP Y"CBf`F`[qd^xoEӡStՌOtkIq@îa4g{=i]gR˩p=mOxo'@Hx )qXm n{³=m-Y4- 4 <raiI !g{=m4'-ѕ/{ýnkQblPh0n{y$t:I_ wa$~9 jF0R0nk)Stk AC h􀹷X'+ð%1cN}(-ޠ'egxГL4@]Te ñǁf7k:c1V<\)KA+A{ܾl}IE&#$h־i}ZKq9'~$ Nk*%ߛn!ʥ\x4pӵ>%JyNM6bl5w6)B'6ۍ_?G(q)$q06. Ʉ|2=pU7a0Oe6(wJ)0J ;f$/L]$֘eKVŬ5C` 1'l.R`;tsxJFHXf^r  J0$3" ]u * -, !`OmsH[æ|uOm+@*+ 5a4S'㺵Zi͕8\=rsݎ/NG阔/T eRC7MG1b)ɲ{7qLLo~ӵpk%iMM sqM0Фp`;})UӲVq'm#Oz8=s񋻰k.l`A~aW*40YMFz҇uQQ2(A,50eh;ZN$Xe"}f#10`ϩQ0*0S5O0zǤsT-T[4@\-IqPi+,2t+*0T7T`%e\RL4 MI \ډRm@ Ѵ#]Tb.otD+E T0Դ%=C6u[R.$MP > 0kp6`1U|2 B40:ۺp$fƎ0CSXXi)8`j{ igkq#U%ϛ3 Rt0M3IP&5KNfy@ɍgceM[pQ'-_,&6&Vg/]#u5݋vPJA̔b`ݳ0 ՟mZq8V7#5$sP/uڔ*pG0*Z<*`8\.(e,fq kU]RtEh"pRC湂^`l ZFx#xHE- <wJZܻRMp1i(ߥV|^¯pE$eTbBmRV&WI«$HnkIݴ][ָ^k cz"M.A+{ UrĄS ٤GYk2VHЂ QWO?SiG5LcC4)˄zifJ&U\!t1`Ԩ)x|dh֭=οNBEq8 tx9)`ex `'dWahu%!`\%l 8$S4|=8l UHkm;ƻO)ڤ\-r<-Jq\熣4M[-S~S#MpKGMI0S^ [UPMN2)wy^RxJ<$akхl Pާhi4yH.700?jfa% q20 .Sq` TS\_ozaR8|2Uobjtj]&{Qcd>^Q%p})I;(L Mq|S1j4aIՏW@./VAH0D䮄imIM*[Hr*Hy`AI݂ݩ?]I\:+ I-U_kc͕&&\CRznA\BRk`@i_uKj/s0:pocrБW=-/BAfϒ| n~*rYL=tpT+_<*" R Ց+}܇;=5Cin*<. ] fZj&bOH]T5-jewK.%'&u ZVƧ|3)j&8h-+ԛmu6⾭~HTϸԘTe^.P<)à~#&/޽Q'nijշ4lF[(-ǔ;2 L0'b8j5IjHokRp1(Pz尦̗v*P6Iisd-5u^cC5uVI-nRd_ fs!_\ w5$}T:} *ǙςG,!.!\leRa`vapdT&ʹ&%1` EN\7R|q(J~hwP9(sڗϩ6ݥ8 U"\ R9&9zo^Q\ }P n"kC.YMCJ i_`00BmA0S,<;fN C ϯ(MC%C9ZZ][ڻVO Pn! ү;O@G1^I$iaa0Z!qrl𚶺κ VAśXnRŭ&M= 3&$n5!)_[,;7χ_Rc_5 HHǰXfYg+4wŝXlYt8n;+4 i.Ǩ)s7l&Pd-4ݠ )sVE# ~6=XD.3ݦrdG5REjAŞ#:΃37< n3L6< d&ʌKD8ա ՕfaK4 <3O]1 :Gr@ۤ<839_T|g9hxlY/T:Lrux|sn >8P_pO ZJ$9.^[ lRTկ ڭiTtBylݒ[b'zT,|)Ի TVm:*64-HQt)Ғb#LTb#LSio}a2Da:8节2P7n<}UM/ɂ<#W%' Vi! ]] `طߙO>D*c_W<*T < ]5=AS(N[:zrQn/Zݪ0UquæՅkI7&6֣ H] ]p`EfJצ!⍣ 9h!­Mh'hM;EM[k]O\ݞ %) s&fblUMƕ絮mM7)_,|k[_4^a3%} vvQt04Wצt/(K43tglm4-rGu@4p0Ҵ]QsPdw j,Xl/x­/ -JG}tu]ppqIV[Y/U1UD']^Q&aS?&ʆApCqT lmF訠X#B7iQdt v(t?(  +?xJ)Ah .[ TT܂ܤlP8ڟFYMRMY턑WǦy5=7S 7w 5+%2ViܠܔäؠܴU^ښR~l)Twڝ4mӵ[њԺOẔ)1ZCOMؖ*l*"`KVV*lKP 4W[-=έ[6V 3j2 e=0lRTI5|`V0mDMˇJm%Ѷh[!z *mͶb#ŢPTlcxaR|G-{r1uOYП=yȖA-!+eF-(ւd 2e"tDeІ#`l 2ZM.0m6tXh JBMn-%&M㈦remM* y>믻 |O=hrٰڍi|&J@SۦDw4zjiMGMO)ÀʶQmEGQP^9E{8 hy/g:Bu`e*f:JL`i/kڋK0^%]W&f5=Bo,v_\&x^o}k9eTnz9]J^RҠ^2ԤSRԙA[Xo`n)֛lLV \RAj`fUk~rzN4ϤRbs8..kzrqb7L=e\ȃj6-IwPo~j_DMey_+A?[W%mk[֥IM7Ljٰ/6oX@Jgi (+ZF[ C"]P:xip~  b VvC/NPU]Z}|R#W G)V`6W9MGqk?}qp7}|SuT^S``LI|T;֦H]K^RmMS1 %krzaYp%PִMOא"hJ9X2kzTSY'һ$3V]*1mR{"LWt>SM)STǧTCDu|dɪ"\"~|,\rE^ coCib͵xacb?xuX0 Mu}<96==%5tu^IJMGqRqWVMYzWVJ7uښMIIRv>v>ve)Rkqt 5BMC]8nSg?)xX-vrJWqNn{406?,v;EA$NS~&6=x&)Tp:9kKē*XKn+2yaNU ~?^9Kn+HzqIm;|MDy!hfTrn;wM[؃Rt%'A* vMWbR3M=ŝNj]cPB״.oW,^Y2 x?~oWl۠|BGKW\$2]k|Xhh}-ߔ"^[kr۩ؤ +S㷱¥xmaښ^нyJQ0ebaeZ|Wgu Pd~}1m9\+Z*EM*󀽬&SS~&]I/cIaȿ%˯5=3EMn%H`apQJ4ݳt*z} wro]phyHSvp2 ^wjl^ٖ䛢!²NӲR\m76=h;hAO01]bܩܮݰ {M1Dl) vXoR9S;_&~;Rr@ n]_".^/yAa0*GP%WڒX[YBRS ɕڤ )\O'@y)~CSS%eA%ԭ\VTKMSkm͋gRn|),ݾqy)QUM94J|~5eܡ`3Z/ӴHA̵IRHGwPu4]_))ݧˀgK[Rhh@Ň}@ .['d eN?MJw b )AɃE&__t릳UB`Ӽe&n)!ЦT0ۭT+h:n}̗뫑@Jy)߹/ǯm?:"<7I߶F["QnP\Ww]dtY ?XJzv$`{)}:M.?AmO1|~}WP;Ff 鎛,V!pu݅R&m@W޾hT6jxmr\hs:ܦG驛mJQ?q!R2wwy3ܫLj3T`x*u [*z{AP8l*H5-twx0Tp}rQޠדKf-Cs^o ݪ/]p8٤J|ŠHqh[qj*pnRti6:u f E[:F}Ӵ29)ձ8k0)yL`_Ӱz\mY>#'Ǡ+wԓV(N.71\MR-nؒw[#K/MݾQ69,mXaMrդi^]tDخR5pTYr1ͽ݇_iql<(@;"et,vz ?.|caisǾӂ$cdS :"ቦaCQpɞʟh*&sӞR]i*=.=-Jŝrrt)HphR9/qmթVD:p0ܤ>2qiOaMh\]mNp [.0yj&M60>Js7ijj4Z`08օKtI'W* E}J=F~UGտ^ۿ^ot*$_LnH*ZWФ*e{nboŞ3EJR1!Rz}Sܠh:Ktrz[%=k-DS8GRu:ki5$~zqvz~`ZToMa+Onl|h|سgcNgc&NJ6l|سɱgc&ǞM={69lri~&cMO):sBL~t㵱x-|+hf&\ cO0o 70 .,HƂ~S*SY<@@Y`mc(S BՋAx IxR600oJs|1dmR;P-ݴwTO(pn0/6o5e,K~Htc˂]ӐN޳#=~M/DG̃Iee갼IL|`B>[{J_g/:Bz v@B /TUeHl1);S $.5OWFS.^Fw=i7T%5x)f=ntI)s7m;픱vT8yӨɩ\4aR8\ݤF|9G-2UDg}|QiG6H%Go<XC`4)ܱ|8BgyY,hrWD򎞴thw4;4'{eC. ,Pʜ?m,zqw4;Mӽ$xw<;O92)Jy;7N펧vSxBw<6rxjw<;|GvB4;O펧vSxjw<;O'tGvcYxX$?]ҖeCm]:* ߅K.@\} .MX(/\p xz~rQܱì \`Kqa Q_> 5)r~@Աҋk7NӒMnnfL%Tʥڕ%AO~rvں7Ř&RsOZFo"4-}/j  ckQWQE>* GDbXtLS;K·rhT/t\PFT 4X\Z0G^?@/|,yI@K&WLJFW34I4>cr8liz"liZdHUX%J)Ne;.N7mIpT XǙ9<)FW!\LKhgLۄ%m{<"8ei5 3&tV~??ݑsBCAr x5$ae2谁8]BX -Lfa` Flv 79h֠`25hO҄AS{U869l,1f*8v;*94N릣pPSIU?MTHARHA7/N7-hR\A+hr >Cs4AS\&Mbs #)soGUPZXJ&?]]2$e cGQ)JI-IhKLi$vO4h(Oi zK:&S_MnnnJI&ϒPRZwK@\]tTTS_ED'Zn)wv'?&52?V́ i]ZEVuQQEk)h%3ǹd5[fSbcٵ0;rs|޵:ݽrya{^pu- hKE/nEoY-,.J0q.0=vlCb) T8\dm L5 C6KtC۾t([LQ*,&4ϤZuZ80&8C-ܬ&cJf20ꡁzhACQyxT6xx,G i} FPGۭQ*wݡih&M(FeL)z">#Qtx} @j4EXQuP]BdC낕U@~dg0iM1_f/+fyd(e+]&㏔UMgRqG6댪?G hI4)ˉR>Lo:f_^[tNVȊp.#SUqRRfR֧RF 3'66&}UMlTP†z`P ;!S_P666R |-MZ駴駼Ih8p|LڸS@Sj&b#DTS|!?̐gȏ3 ^ Ɓu<h/&Oނ#^8Y)T,Nh'0ZkڟJIУ\O.ަ@a`{z 6B0rKW<}Wj.5>OE˕Z)az'_NES>h|qg'HǀĖljLZͤeL#@p % g%% 3YJb|c[I H %ZnJ˗nT3\xKm7i ȺRCnܶ65ɩpaߣyRy)ʱ|SL`iњ&vtRƓT|s4I>n(iS6!IoC-(M~0qƵ)М4h7뽡Æ"4P:tsIT)S6ǐ8¶a3H]qStr[kAW=Y(;PA n&P  B0LXV./)`GaΑeneü$rSa㛪O54`c?J2IDгom~n *ʴSU7(| 6,-p)NL tGJ |$j| 5QO605Ly9V2e%He0\0z$c qTೖ@.qU>+8710 Uu>)ESn1=>[n珔2C{_A*LE6 G#u¥iә-s蹓c&Žs1\7$ճǫ}h[NVАjs RgC62?80e ?R6jkA`]9Su=\g Z#`N/洡l` ܊QfcY c(gφE1NPTAK S sEJ0Mˣd\spy ?p{(h$_Nˣo)ƳiI]pSW’)lu?QkEV[4wIM"k'Ue qAZ<ҟh&z?rAp:z4?XEmP-et8?} >G.q;8aP{׽*^N/Uz0p,6S oKY_t{>C`Q=U&J0oh F6do`mWꣂTW!`,'u*|XZ3<\zl9HsQ~cݒ3?OCUkInsT9cmA+zGn~ЊNTz+=Cac8N䦣ZRHG 46x2i 0+2[{R?W+Ye-%Pd2+EPp nW4]=X^l %&T=Bu4$Re 9W,gǔ q^M~ép<4(H -5He~khXX -w<1jyp,P,h sj[ey ×fA0M ; +H*b@AikT5RW,qmeMˤIR YT7=I.[qW^qG)v,sp|RR)΢XRv5ekM!_6l6 ̆eaX$*t6w, \&\Ps  ðq#y`t5QlD*I96)S/6]JUx8KJ$5v4?bjܗ4=H 5&/̪4a)onq+Ȓb!-ýPe F8|TŰ.T|,\r`E˜g^i8`XTd[JKƂjаgC0 (-|Ô9ӣ|UiA.fgD^ 3h!2i ;?cL)Zvs%ayw|\˻Mދ&U6 YeHrgːOSoȮ'I櫖>!lww-ԂC>AO= %fi'эjT?R\YkrΧ˩,>٫M=(.79sSqڃjA) {6zx*яa-@}Ujy30K0PKA1;<ҙʇTC*(UCx<.iblتWX$Il+Պaw&džRcC28zXe= :"(a)_l>6qvoW՛}sYWov Q}t97 8 ͆IdOUv٫Ə/t6gHO$~M/_cwW͠~0IR7K9e> ׏ w Q<#Ǥ!PQzn9%)8j/ɸ]*iun_2?$9|Rc:Ta\mlR]\Rdi}2dO)o#}t{\:M/  x<|hzLs-G/>&[ϒh GqQ(Um(T4o;&?%+F ž3h@S0M5M8ФƄePlQ*84F[MԆ$6'RY3<6$qB\X>u?b*\,>YGXfv)~t1^,H²yO%D?^8) / }~5m6Of5=\MʕC& K$4@DnEM)Ԑ\nyNw4)VT"T@> w4k7;&'ta4d.MZ5Lc`l FʋҖVf ,+  UmE5\S5[~D3Ek\KS SvܰДJ%6 RtI2c[XӲ[Ś[۩5]Ƙ;~ẚШ619]&]MjnmU12~# 6æe]j|Mw障9}Of٧g &C$N+<9E$Bx l;yzyMrêAQkR\Hä>&-YU6Ζd(eO6!VK`AtHs':tntp?`Q|{۹EKn([RU2Cଙ6d$O30: tZ B~>bѲ۲ۖPhfՃ-;Mr UDݦp۹a UZ[R8URM-Iɒ-MTҵ.%<5a¼e:+:rΩI=֧Q槦#X](5iRPqcS[`!U qbПUs0@7.X ReՊ3&gWY*؂ts}IL>TD']^S/U /K%MjIxry 3vL St,y%cA;j8fqVC*; ]Ҏ5l]0:G_ 1om>jSeZ7p =?ؖul:8:eڲNlY'ڱeHsK5.dM1Doԝ-@)KiLѴ۲ڇ:"Z֬5۪ܶ}ճicYgz~ԯ&+X> ږrkZ\\Y}"Mn-Z(za\AMhB^O.X0BPLY喂؅Up),49,4bHT` d--4-f-$KJ1ZXKKMuE )3=Mj7XKGlχ_Tߊq-zoJ`2˽hL/}s*N/˽1/P\pU0؃SuߴT0S%KQBOBٖH3t#ML4)=~&ZSWǡO--PT$lpjZӤRͯ=!l?UXnrn˹C!3IlK}-evT$l? ۟4^Uj:`iCPY1^+W5<Ƃ*npRwp2A[21\~K559c4I,^zA)_lYm w}U'W^LSqҤAӒ0l S q`,pL }UJ.šAU ^vV84_Xe[x?7D-$\< 4; 9v-],&HZ i8R*")GRn!ӴLwT J4I17$_X\lZ&qx\G\"((r$u^uux6蘞};7 P A7 uOwdmR-ؠGO}Z%aux5H59paICa&.3p؟.CT 8)) =@EFev 5%>`_]c+AK2(.w$ b>Db]hJ:6)($stLUz=蚜 '4OÕ̩N!5M]+~Q83n9P>l_u,|t7~2Fq|c b+PbBBa|C{?_pQl/L%C\=Ea7%M3EK1j.!ʯ>&8LwF"N_6҃$σMn@A˦9t=hٴΠ=xIƪ(ekSt:-8Sr3 LvG&a&EæMWM 9̡pӴRKӦUuiIk Ӄ9&K.V@#US4l46Mah19UWT4ڤK=cbE~hI}$PF=tG'.m8o |OSrLK>+%LC@XX *87Iځ1=-IŚ=D4vQ_%Th+y)7,)+J%s¦&ǩhS|G@}kS(XlRrdO-4;Rڋц <.,a)0.n h`,L5ꢺ OL! wƣ@sS*65:MK/4:MaӤRS ^6krc[ 6D8SԦ%Y01mo>tM dI:FMnq)5R䔷:t4阮bJ)/Hytx uEM3u߇MOTh2 tPڡLR V/p`yix弘 /aA*Uh(O_[e/BأYS$Ta*e g:&0)tTسص&󭽦+:m9צ"6'6z-X;tvA4 GcPʖ-; -JJ 2_Z2Z.- []w0e6ӂG1-#vhi<' NiI~SBᖪ6˺'ResnԦTPb4-j@;Kնeئ%IKX6b|In./k}&l_W4-#!Ii)sZ[ݸkXz&;GRxa}K;֍<Wtr."(P6\  P^]pIawS0~CVy۲ $ z0!Rp))HЦ2lJN.E դ(Hy` ns$aa/hQ$_~¤^\rK|Cw󋿮D*ٳ&u 3$MnZ,Rܩ8]ُK?]Ա7Y A--~/ܮSإ/w[I3}5D)EHIхM_n(xL(:`Ȕ9ԑC#R V-\>eHeՃqjKEbi9.f\ϯHe\mhӤTlˇE!EڜT"nThRs{B7d)'Gt׳>T`b_ϴ}q/ٍ<=f:n]#AAɥ |=.@[=7iX(أ0w\wf9| xqSlå*Nd_Jc%M(c(thU~٤MRmhݶ.DZD&M'$ Ynjr8dzI2ӸHݖJI3#M[qZEI&Snnr|4Oa]*DbW'LSS>TՅ?oj͵Lg; rqXUqB4U9OS3=H,BVtOnm4V촶wTP͛cOVUc{׵ݰshS*;|IKFzhsKm soqӤM.Ҭ'LOn0ݽkaEAf}ִI\>uܸ:Za 5l|D6xl4t)Kwe?edCɆ.mL x$6b8p6>~YBɆ.OCS'RbnzG4Rx&uNS\'6]j%iR}\L|:Ӕ)MSR3MFBʋYKS3Mn Oh+K]<]k6|l{ #9m##~L XAKT IPLubTf`N  \]p ` 8 *I&r D,G+Z?ʄ.ݷL*(369XVjr]xӔ/V;>K1Ғb)r*%pSRJDKdKl6p"Z1&,+~;s9Μu[ :a¾hG|H?!0}&hJV1Ƅh;3'r{mGЬ}AN (xLn2#9z==([: mhS&2ޢ\)_G)=h s'誖2YO)弔e~Jehk!ZvS |@Ncb[{U&K&I?(} +p:(w2NVā88} iųvh(/45-Hz=̧QA2eً#;MnK| MrIqaiMQ i\KŖkJ>EnRꦤ//nz"QZ:"~]ڇ_=/W .8\.,A8 ,k ̢^ͥk,ѧ`` jMK]3D*逪(=x9S|zՇ7 򠭇Kq9C!X`P Eԉ*t5y@V,†^ ̩Σ`hg2Gib>ĝ K?`|1?,oRn67=T1U3)=Ϊ Ǔap8 RoUMGˍk}k{TQeEW]јfImƄ q,ަ?rX0ae#/ #Q/i8$ta`GbG^)yRѡڎ^ѽ7EBn4ÅՍT*Rp7Cny&&U.mhD2Odw)M7 F:~הv<V2Wχj"pe|LV U܂,))&t[-*>OPӟ/>AMWՀQAw>LՑ)]qpJ>=AJ#_|)O_ݠ;^~Vne7ItHylu~T6/6L ~h MLG/v`h `˥߀GY Ŕ1/q>P(w6ϐU٦zפ~(E0b>Cf'@%mP 2)nXMOy\W>VjB0m8\ԤqIKMOnK1Zl2%]t+Mobs͟_jQ5 ÂrSc1: J\(e+؂, Nv6O³ΧtYMǤy U\(RRz`i"(\8v$G*jڟ(H-Mǩ1X3T$$x`,Xw~ ho6X,)@mשzaC#`X8hUu$rRB)Pܱ?,+L'(/zxkA2A}^y[ ,bO-?$.# b̿pϔD!yi YgR|?Vibsm&gl_ԴcNlRSo٤i}<>`m8WӞ}OW_ˍ_p__}>WOeP` `j0pi FÃnW4ao\$@zp=P(\YhRhp=xhkyvsn]#Ѷbpq=MP?r8P\(izpeK4q}GӴdz:W=2 sӹ&I8,a l쒄X4/8⇵Mp|xP?Hn͂%F`f0wl(HFͦ YTSrx@ϤA*aR8WO Ϙ0)q߭4-Ɍc+Eϒ>2]ʔ6 &w5ĝlES=aN5t̩vV T\:0)v P7~T7s`CT7`1PuyKyaI `LOy=EO cDM_Z&&FcS\( OJtHA9erP16Yz(IY.MW0vRI ͇O6 DjIMdAE%HyꔊʦtSLRKRp=% ~XGC6% EROWA2 ,L`kWe8S* 40/ T<]_UO~~ڔ"i M2sWsTޚd ̀2.)1ZDmrnZv ۾K ɹsԁww*^@32MG_M| 5ɹ)v];qdTi4PC~P_. N?C}}u:ʿ@b< WJxvAc74%#1 ɵ2nʝ]Gn|v 4-9c']Z(e>Ïн uO1sP= ):شMRSp\R(?KԵ6aN-@Ҳ;iҲ`M3i@N%+̗*`1 &wvAP5h`|OU|;6ץe?*'^-dMf0ǚRJ~Ommzq,q|O%kˤݴ>բ)SeMDX*4Uִik;0iȬ+;Ϯ<ӏo?N?dS@rC6ݴ1SW)7¤s8< 4~Haƕ = ӣƂ=|J0^]",ʴ I}wqmM1Drsm򝎋MO5PCiT]tIttEOa GS(p4]R_4Mʃ˻^Ԧ&@Nei-Y"nhZ wT"n㞍cwpl {6slú4M.I㸛8gb<:lhR]isԮ##URn8:uM)RmL.6=tv?76?*GgTb*g"TFJM*.K70Y:GJXf> G& 7buU`uw>⸻[{mRٸKZ Rz|,K7]Jkm֣r,Nҕ//鏕{i+FF0Qpf)0va .cqM_60${LKuތǧдz6Vm6k- O;]AܶS nnAii(.\s2v-U 6* QS/E|W9naIoj!Y&L4M-:L泚8 ɲf:6Σx!QmR*qj[Amugm-YV-ʹU;X5IpaY}ÙJ~V=$95]6rL߄p]Oy&t7ZțaaS}6>nwd]X8 P0;~Ǎf(~/U*gY`YAR 腭g0 zf]~4-UOʚ\oT!M**7aSHb{YMeM3)\<Ӵ$EXjTV-\k rQv\zAP\Ƌ ~; 0*xX|o`,l*,*Az/0^0Yo憦x"_&LCMqL.Y0ރٴBr!MwL7h0 ɛ$F]AaRD/7SX}CFݛT4z"LM1MhJzmMb籶{o*LBM4)Mx翇 orWg!,009^i9 C'L-XL;6 c _%~ 7?pfrCn:tLϕW=0۴劰ODcmI*lnr<|5MLO7eMnQà)Hq1[lr8(v`6i&zpmX~.~Q 6=Eկ" ԃ-V?tC$Sf^2WqK0P(emqrc!Ti>J^J կZS etTS2}n=nKJy-c6կpW @MK1ɗT[T\lrʟ$#,YnZBq0,٫)@MnMݴVj¹oqcrctUzmX8uzWzQbyKBG coj>Z E0(˦`2AVV]0]a %[G5rm$,40 m Ŋ6kwzishꍚp*`7L[P6=ǡk|clS_ʮecGڔ4ձ;5;*uؔݴLZ{.Q~D/D)SФ{ 8~uC.M꡿IO`6]I)f= TA# tጺ. @ #ybЋ#j\n r Hdf .Ue7"=дj=)T ^v8HnI9jvhTWRmT],x%ŭtM{_xӓ|&.I#%xS]Zuu P/d]nj:n.p[?q)Y -wM]upө'mImR?)ПOz'Ӂ'xf0IK҉?ğtOa.4&o) { JY%޴LR}PMބ<=&ozʗjw¼$NGrr\n\+- Ϫg;2:$NV?ӛ&XV?+ߑi*wdYDoR)yNAqS^}}Wp8GTa8+..M͡ u"$4\T\p0_]ѱ%꩒*4,X>#9JiZ M MT}~ 0p('n5)PNKt]"lnz/ui*.4]=M_iR\Lb@Je).gr2MOAߤBMIn~}Kc444J-i47e+7e+7e+0BN]ARrS榌榌榌榌lll\J[M[mJܴܦ46]sjݴݮ- 3m37m37m37m37m3x%mڢ.Hap iii vtvtvtӗ覭禭禭禭禭禯;K_w?;΁mMY:NEnYJ]i,Jӂ~)٦?!Knw5IVS 7!RQ޴72oU FM K ²o7{"=Yj0AMDMEVrʮTڱ]0S-,EGmM**\e~n3lzJV5ݰ:״ը0 "-MvKTmL]>)Y*}\gP! zqqx6`3P^(T0(  ۂ~cuT Qi[R݂RjUOqtԡƸ tHi*=61 7?R=äpZU';Gז}Ƌ#"#%仧Ͼ.G0xLj(w5N6D>j7Hpr:̓)DjǩqrkOnh-XڔSԹuж^0uΫ~R5,W$,}^ud{* |>:R4C$}TtE6)>٤h}@4VaISRmh |kCΟcqW%C"HFr%)>J zVC7}ȕ仝Q:UgC@p.M ,A&cՒNCA0{ЫJ C&A1b1ԺrQ$F9OޑV!x+)-4p䚮*u()G٢^PGHNy:锧OvrAߖt%i} ThEJi3b2Fޥ ҙ}1YC@ٗo濋<}~a/ s6)mB/U\I:x!"T\c_)CuB5,۠mKsX~ôṀ{xOMq[e9Zs)TsK_O['߃77z[Tj21SR .ܝτo`+ƍ+r]I.h19V嶿?z! Zt'}}"¶8s2RA"`8r |&_]X=-A0I%8RQ9!B*Z+5HBz4%K܆H$U)0Hp&xgmRjs[nno¾R SOZCn+LbY8*Pj6)x>:Mꕭû;؃Z"v+hPuV{}Zʈ%1F)YRH-# |=-WxL{≞?jdL ?'"D֬D=kz!JXRS($ ̈\_tf# 5}|Pw}4NqT,X #妛3Co!r̿'1$~_ ?u< t+6Q<pf8G|h>s49ϜаӘi)4hr!d:^N_֐*1Әi4xrp'/B@O^̆\OT'*Dxr`@19=9OO!R\NO'ǓV~&T-k*r<9-xr`IxRr`Gӓݰmt߂K L9 6a3 Q~snS,0?.Xՙ5s_Λ R,73L.J\uZ)9hmͩD=TuܥJ[Sk %Iy(s9QV&}Gq&t=*Zs6{EXW|9O'J3w/ѱ9+3EK1f(.?݁k}Xs".QΠ3L~9=nKom/I+nIXl4=`䵦fp҉[Xg,B0W2_,ǾeWUܩZp%+m u*[Z*hpQCm ɒ4%ߵo+^NZA?Jz }: eu:.?h%H{aZ+ARiI]de mڨ$2u>,~9OMS,a`uf%rZ^0ew4 IO&I4u7D)_QfH rR旲)Ɩ_T:a՛(I5s\U)R&MJo]NI$ ‰qۆ]'{z88o\Ơ! 1( At0:/ 8:/WIs#Q+WUEyc^,0p/`c^E>x}|w}P(ՋQz+x?Wcil޴ Q46QyL||7{8j\&<06o IuP'>z x}5Oe 1RHaz7?,,DyxI6-sǂsfXyCB)_ #6,ؗs)\6E[IK@[Ҵ =6kX-hHڤom7LJ9T:ǦX^(prq`Ea}Jd1HF&vr`2w<3tr[akr\5O06o,4Ԋ-V͚`i-Q(߫bp]lLwr1ETslJ&@K)O~F=>LJOun} xqa 08 Li8fW.^ b6qbpr&YLʼnB#]Ͼ?@2*Ķ ?gTd٫1Պ# }rDCTFöJ=J>ڗaהo}|"fVcB 9D؃a_Kv_ ,nGO*m0RX\QS|T2y-`@QeT>[򲊁W`FNR7#6461K7] v0H#==Z"GʱC%4)MƳM8IM}gRmҥVImSƧtC=L1R?^hDeR)ؤlҨ{ժ [?$ lQC Bǡ~ʓpS*yyOy;y;IcɳO cU]۞T?pB1} J֦V!&;azzFFFFFFFFFaCeJ_>䍀-vf?Xϊ"21T6 r8&%)qXOcشDaGaGJ6ih71d=z݃9E0>N_-)9vϊx[Y|Ps~'~/{S!PH_wQ7x +w4(D6W Wdv(u_2  &6XTO\H-i΁gHa)lR4eziv$KIaw-gvpk^ TDQr\ݎ= |&'M&򴮸ZUzcҜl4>HkrD8G&MKYnM3L3969mqR46z MJHcb.1A8vp oA@VMjp UޏKHLsdlx`\Ф ؐ!P..pI\!]a6~QW)2`c6􂛎)U2!-gPxԷ9W$=(5^biZU0]=}r;T !mzq]KҐ0H=FO X$L{kIs୦@i2Y05srV0 fh% pDf.؄l%_$ss`+qKZ(4" Marp)GA"[4$t&Ջ禫0Cy7 Hjg a?qwϑ"mS kYoS8zkaR9S[ikTgR򕴜;<~q'rw/~ћ2Oʃ,)/Mm bbjߤ|Qj0iBL=P)v@)] O˽e%ok9/Բ"d Vb/06S8s$Avm)j{anWDRh:v]l]7nu-bB fre?40s׾ *oC/7Lр?L@/ Ƃ.+@U&:1`Ou,0cf^P? 4c(ۀ*tIb=&ݘ0hgr>̏l$mzMG|/I\(/LN6IOuJ?^^([+;W1mkz;4VFtiUB&VN%O4 LF#9Qh .l◷۫1)riP]0@1qRr,)!ZZ)K?akwGu 1F6D{W=lSw4]-Z=R^u4zeФ[tl,MNO!DM.iML +҃ÜQ(%dQ\%\>Џ @?rPac~ڜ;7SU(RoUWCYѾ"$M.!顆3HFw!Jaɟ/f-~x.=#pExR: rzxJ㤶o2b][VڵIm֤6kR5 d.}j&AZgTR&UH9=Lq@:<=^qw'CލIƤwcÞZTH|]N$NԊPH֡=C4F5`@hp~zN rw>MWyKy*S|eo:C9&Ǘ}~2l*oeh>k|S8"Gp/d:  :ۂ$N\ K5M3AcJ(Su [El[M-i[S׿AÞr@RX5yhj={CL4M*)B9$Z4^x2CЦ_f 4141T˜BF;ASأqGf{^gyߌJ2=pEwz6Cp_ kަ9!^r`KI KkUwM{mz*/OCA"iZˎ)/W]ȖIW9_\I*rfNZd(V|uIgTQARX*((l FA[}@Ҥ79Vom'—CӅcִrb0ޤ1l"4OVwm9qd(*”.5E 7=/>7e'Ҍ%ޖb\SPK)eڦSAn\&=-l+i[.@d/TF,Z ҧr0᮳|i}ӦT:N]r-S-]%Ȧz{}M@G[jUpGKo^ 0u&ȳXW90+gt˟eA4hQvtUTž[?vMѻMjPb- :4B٤'f~q߬-Q)l+ʂ6s)B2:XdK)_`4_킟pk+h`]w3,穅ЃO&q lZ!ڢj.1lKGc]>51Rag(/Mn˽j}\J-,%>;ܷXH0zTr ަcZH^5Ks\^8 3kmEmF Җa^0t!&50K˅\V& i` yz4]Z74ƗK{*xǻ4|R< ۓ(>.jX`Ф6j`!l j>u54aRm]2mw3t-&M`:`Дä: ~jzab4eh%kM LiZ^ ʔtPjZj)4gBT. hz_IWn/iPt:U} Xev.ua[̰` P}pc:,]GNk ;7lQcS᧤`83T &J B>P^Ov=i|pX(VMG9`ֳ1}I6&M.$#{vg<2l - ޝm0 6iënr?۲5Ioj&_`a~&ژpûjmqa2)b[M8 Z+`w1䦚, V2 :eSP?2)kGz;btC)z֢TksVjG#ϤRIn_3姩X_zqM -Ȯ4զt6-趁R,A\lźs[cҤ n=Mg}9Qe;3a 40;SqlQ`v(i-K"o %4jW.K_T:l69hnM,49GI*'=-t4y:l,O۹d)n[tRt~=6M[xH6=!-\~,,Ɂl{l{~S%%YQȧ6hdӍb,$LK%#x rK%%=ْϒig#|.R)4H- ˶CC"eeKeKe1Բȩi;%o AS"/v--PMC-8:/ESVDˢ&5퉖U˖EXlK2JNH-+Z-[-[-[-[- \M^,- -@w<-Eb"eۡeزPZu[e_/vVprbp+ W-vS cmw~EO+8 %`sVX+|Qg+wo~Za?Iŏ6pg cQ ahkp֔ .Zu)1qwVJ' 5О\ Κ4'kRKrǦԴNQUdM鵱84 [ky2" R7dS˒?U 9 MsɱKaC]CSWKb@!fI[- k|<ˮiN1AQS!$.CpOQ!pR%'_C|<7O:-fYݔ ~˩M@hqzN)|emOL˵4V<#fm9Mzֻ=exFMTG< ?" OY/KǗMZb/˿֩-Maj)eMj_aa.,ׁ:pbK{`@!X7f)yhM /5XL& /C[K8 lTFV X2_=H$Kk ȡ:z5;t]p5xdܤّAsg i{w<_)Υ Mo*,\xz-|;2ՁÑkU [\64;6)Wnhɣ{\Y; :kҸ\-q {js#¤-zDi\|W–M(g4 ~VyiudHR`˼.x^~]'6Z0,>|O*\:/ ^i01 WwOե vuu_]WץJ_wy]z]W{sQ9Gh y]_hW.@'%w}]o]^]oӵN4q=?qԏ4/OM#4]uyu'AQ)|]ir~`;̥@#f]]_rꒀ@B-rJ!`v,,,,,ϧZ)\&B@ Կi*:P /K{=oϠ( 9,#6i4(Yqm {%O4-_/K䛎IKcK|MGGK@ȯoKJt[L@R}|P]ޤт4Si j_{uo5I}̂ǺS Q6Ncǩq[|k׮qz׸I8TT/wT:o+>M&m8Mۤ6h:̽emIԠ8UU 3#z?*'ȱZ">/t/$D򏪶z@%tWwQ2-F̣jG_Ь!(H6t B?R/Fi0Q-4~R,K>ߚ㸎jث06]bIC}& 2m9ZFN)@cR=ZGKI.5{l@ dtMۤF1(56aX;3EawZW#' xhJuMGW]HRL7M *^7<-}\#Mۀ gu#P腢I}^j.㋡A!i.îJH^l\n\n\n˹¹¹ڰڰڧ)o;*X>e{sssݱ@\{l`9xS܉rwYwYVj48QQGrCtU2wO\@6]AgMa\9m"-p{r ɥG)rٳYrLҖqCy |>[*PDz^aP2#ޒ#nX2ۏ~!p`](<$/T1nG7i[Y$h\GGyZ*ٴUhih R_Tm>F|)dp&}Z }ONfR:noO4ϴJnJ-8|$5-x[ʹX-]uη@Vm|޶i.a~ZB@eW JBa +x`ץDN*Z7גM兽}7yl{Ot=W:H\ݖ;UP88߸on~SЯ^]7AA/V$+ŧ@ZJ|7A-)^KRrSyx]:^Χ 40|soKMpRϧ0}|z7oB J_x- =} `.--a>Xp?Kc36D}E6W eX̚96;<LJfv|fG5-Ll(c.+uL:0̎3k?MQgMQzDۙCώ=;>Ύ:krRzzf+h;s|Y/d\EgC{[WS"<=oi\0X>>* _WXl~dU˙)ڠ4j3g$ZpXSO=rH'JX.<꧖QjqaPI2 Ma xI){Iarl=t>;L7 "odioֽ?XzG r4}T[cS~]s3^`` A6_gѱio@ IPڂrƯ X;tOgȟ?#g[e R}tP_Ʊ}io+C#+IsO]8Jm*tayq隞 =5ibKj\SLSuL/rV۞c V& pc:#Jkf]a4k zz23KmGMa6F@x{ZR0;l{pm6SfL嘚v"/̈́Iǜ} nK&u+!uJjo\f?*W1; e kLA]Pn`SLcbjwwF:Ӭ6d䰭t4@T>mMJM\2ۿ;D*fA{s:zID}OQ i;LON&B1& 54X]{W Baz?>:ZO!@7~&ؤAx?=ΦfZ@%IuʙE_r+__ [RJw;&YR:tZu-j}jAo$ҫ&r7.^?kV˥9 x[RŰIڵ<ʻ%FMNt.(m( t_GQXUe0J5^ 7i cBT 6( 214 {+Ia`]zC67uӤztm' EICO:usC@Px hJO&nlM} Rm8N{jog@2] MK9 -o"|HCMPj4iPiQjkIS: x4UDwRʒʒʒʒʒʒʒʒʒʀʀʀʀ X,, 7~|T$$$$jZtW{mmm---R`StmStmStmSt˯BxqmgtmgtmgtmgtmgtmgtmgT,Ψzƙ*wsyuޖz]CПcl`5=}A&i}q/4Ծ-1cSaSEM&zUqt)K|#m/!(2̛o7Ћ7o(:p\\@~RpGUophÒ%RcT@tD8RPw⚖ GpMjCG:躥^>"GDSlfj*5iM%UAߴzpФ=[T T*5ibkN# ;n@]+^>lg L؆GHFΕÿ\% `9/ Zj6i jP6~p,/6lf6᭾)~1A*@A0es1PBzMڞ)ԂTwICcஎӬK-&~f~1!x,G{u} 4TBspk5x",PbdhVZ >?D=u;&$O=Djoq8#4Γ6pF&ptyh?L& eױm(Xmu6U*6JmIsdZT7=uS IR R7MzI.uq!FUOЧ*H7SɳO K[gױ@GЧ~[,崥)hpҤV鋢)?S[bV,khV{"Y0M{5Աr}&(5ԢjSD2}3>i}34BH?5]ݎZh*[L)W.MKhAڭf\{AEA5lekP`1jOsCpV GL00U]Wc %?URMwOݠ&>_>XRi`S8*GhV)TB->0HS t ;Z \$ նoT6ÎhQp89ËURw=y԰\Λ܂b]W>_ Ӧťg F@tD%P1mRy>j$=_Zyx%+ۓ'|O.\$C@%_sA8lLFA]T䭯`3;T_ ''}oP[_cTTLeg|M/Lçт2}4iRyѤidh69ԣ]\ϒ&DRhH솯 bL|I| ?;{v S^Ra?TkՖG@#~aR1'_\aDNy{aH*D8h݌K 7AODyoM*7"nc-) (7Mߪ5\EJZ죹^pS>QAls,n\7MX%qo2/qA &CR a XQ`dPef܌,Ph`b AlXLJfj5Da{iHot[2& ֆfL´T^8ޖDmItZynm6G| ْAmmr6M= NS8/VK&>MaOnh ڤQ )Ӛ)jR[(j mFhz_ZfmRt>Zp5}nr|qA야 ^G;y6l%>tte]ey!I*x!nL vrhj6|]ߤ&S)Tab#-|\6]\5tΏf~Dg4pgfShV-|H>!Mw:_UkHD_+M݌0y-dM1,k@= 'ne)/-! p%aeQvM6BJ:%,;"U ==_zy~c.;ݡNpy$<ߧjx:=o${e1_<:/y+i SB ? L T8h`fHwźp8vc^KD%ʢta4!RhRf7%):Pv !zhDӔϤtP5-j3 f^꼲&+o_JY{nʲT,Iֵ5㳨Ql,,^) SŨJU*'7+Me4!ޠgrEާaGt1EtA7^R^LhnpIc>ؤut ,Ts[apP"a^-cRG-pkSaO9SyIkX9u,`l~IP]T:hy8~٭vfe̸:2;6xuW4!xExA2*U;+ 1]Ҹ^()Lo?TRB1/*}ː; ܜ L6k<% :4Z!Ru'w)ZMqES^SړE-Ü^ӫqJ - hʩj@ [j rz-eA.:.(؆M.ɶwAVfmѧA.ES}|N$B_ Xn(R48Lh{ æOGӨtHآmZSn;^OՈABS*>(ԃR>)jEhztDyMǝ}]3ԛڈ%\fQn=4V rѸXSmcSkڵb7 # /Lmߧ =77֧fyb{_ٞڱ_ rr0M.-[BY捛 HV4mhm[M^S?[ovAEWAݿ)niD~eRDMC[5`3}xal!Cc&aDn";4Ŧ>yR} nMaӢ"-H t!ջ5B@%@][mEό6" mmy+)h.g;@ h6\N,*-lW;ق\8pu]7r(;5cئ.BڔmWϤtЮ)MTwg;L;&ő mR^Ûj~={7=.g^ve2LR{J"E҅慇 O0ޥqP){:v6(M7gR{j ڦcR)4aovpz^=f/]OKÂd>KWOKvjP7KÂ:GwIP R n1R}tTpXRvS>|LW%ad<3l`9=zZ*lXVشRtOVlx/]N @IH'M ǾYMR/f󥒷knD NIS:Tjsmx[%?o ՑaЛE^zC+o9ZK.@1HXλݪ}Uz.oχãK蕁NB`._VVb7cwq`؀kE,OuLsoи'rjXSzqS599S#6C=j-4iLshGb퐨´Tr8/شIs h(vk$ocLRrR% sso|:҃`Oz["$H ȱ` W7= AL%OWE |? Xhk9wF[*Y>3(/B\[ðU;ʛ7`PSVRas]5qqҝTWJTc&c |=h-(`9AL 2-h﨣W!i;_a|gNW B#(Le@'P)*59mj>9s@^Ɵ? Bױ8wT 9jCSJ~<<31bkV4VDYRXyQ֔~~у6p%uWLSw0u3L T#oadvSS,p]ei[ln-SxL:MUiO*r;TIb[ +ivoiv0XOas8ll7ۖPMK 8}N߀7mr|$50 >)OA ~)̅łd]8,̅o&Ƨx Ql:A(EtOw9G~6/& S@R$y5>}k !Rc w(?M}C_cԠ&:4`Xа èuk);vc}Xn`bl}J{ͺ2Hsa'@wc erFomLK7a_Gjf+4iT*/5MKaظi:*y4^URRGlA m F@ӴHs( M%Stäǥ3pJ1}4FІl5XE&k@cG!*ҫ֐ȻLI&~ Ѹ" & ؗabC૴q\ T>@ {{Tr{x B8oW=H99ִGZ,R} {n}4FFQ8FУ HMVik}4Ҭ1ah[N8lH@\Gq   #W_\G,!X,`Anu1(A7MʻgҤ_c >M6"|5-#.ӂN PQ>AN5%0/Ak ™ X t4 3ٗ mk1>lL!GMy*'VYEǩSi z+*=ZMTy!jZ˯֍Vy,AR:> djJaIXB5ǫAhzq)a1UTBAPײQcU~!>2gX }2M>5ZBaÃXC+vi\xTJa9X:c Vв#liU4 9t5k)J#Y".st?~+څ5$+¾8ZCnRA\=1١XWPdv(Qr^6#TVɚW@ۑ](6C*; 5k8ꌤtZeuӴM{?aܖVKOKE؟.Kk tc겎Gg ;@G%/d,4j?鰥:ӕ5osxڄ:ĸpӼڻڻTZR @iڲT~h؄4Nvj7R b\xv0sR *Oq0Hӈ%R+{IgP{h9uĀ4ڀRh iZsDW&'w.zQSQi^nn?Q+5}AgJ > 0)92 pKXΔ+Ϡd]g Ïa<ɏ%d{;_>!AMF`ZgOfS:jʃh7ͩW]S|o+6Ƨ}6M~44w1Bah"> dVԖVtkK%VX v?T-cB~&hoӤ`v60`@6@tZ\V鬆Ɋz-fc Woi',] "y a+4=.wz[yFlpo4%näMb'wj;y U2җX_ՊݚK'~Slc]yL&äc7=:'j?>mޅo;jv.LK*2Ѷy޷Ovヲl|xK8Ϙ|xkH0xF]C1 %C/-CǴ:j~~~@ (<2 Cv?XsuGH&~Jr*r3W&C7>fpyR/,1ikPlTS+) /Mz[о@gJn/tأA0<ڹ"E>M4kJ >fms*/囖Z |BGIA~q9 1TAn<IOdx$soEA^k.lDn ݄ާ~v<*A@f9T?hz&雰6RlˣaT-{jb״KyWCȘI edX4<8t~F] f *Z ¶OA(dlX H}GhJ맰ue/6l"bz9b۩SJ1SФP^h}jNsOtBSM]p?ФV P-0j1-h1&[Q =T<u'`.޿J&4*P[Uc@a/uqߪ`=*PaIUhuhԥ%MN4N8 4.Ekjo3X4h# ˣvˊAWWSy/>_a/ tϱf4/Ak:^㉴{iMaϔ*%##VIsI5iǞ ?XcmI@eUvIx~k^rq"/r٪6u ٪W\7V {q7}G?!* (;&$;aCUehôSahUN $6M۱W9Q i&Me20hyj<5l|I.Mɱa44EÞ¼V)irc//h6] ~X#d4Uo2QP.pD5dZa*p3lT C!C҂#Cf@$2 Vc "@,^0mj4\t29]j$g{p ROiFڔ*ojph=М'H#M0<  JA{#~}n_:6bi=Ogm&n8"- Jq#l26-y >A׿ d\]]]]=:$o`i|kzkzZ׷g[AqzYz#z~~~~~~պ~~I W[ 5lz5[^ī5F~S)Ia|!~~~~tEnW"Ŧ3D/"4z_\\p3~~.~ETMH鳤}|B!| dSf#j?S=,O؁POpQѭ@̀VEI5>UNQoPW\MVP񼌟Kg-&ձ0[ޔ* p'^i4M4\?rlMZg4D>->4j}yݤ%45UQ9 (6cRv([ mx9'^"c$IJoYuXsx6aIGJ.# ZlMOavHY-¶LA2MuLmmRapSԔI.I} re,NW#(ZMءi'eo3HJ[I9QTV᜵߻SV1['؄$0 (8wE ݠahialΏ6YA0q-xdTzi >M}6m$_MuR$oZ [Ur[atT=-욁RQBƖ M@v =I`~rK&M% @C Gў)MGA`ioGE*hOT#{U ~??>iZ3i?[F+C0Y#\ w(֜`xlVS2߀{2pDi 6kBo#:{"M`ݦntA ~ܴܓLS`.cϤ^ᱧeVDpn޿7w0.֍}ƾucߺoNFUsMVmn[7{=xtt5[O@6qP:5_`qPrOÖ#+bf뱱hCĆ҆>J%[jGд8nO49LKDex~l?^/[:b-9~l?|>yUVŜy+0[uhá`S)ᴔl\*m_T+ZE׭Jq=2,`ӔlZ`i)vs)|d? og&l!c|֠RB:`(*[ r (oQW@%ಮ7o_LCϣ6X㰡.CDkr)WDWg=j8P z[tB9R=6YO b'%6[.t돶[yj5ׂq,ouW~b+/@ -WÑf\oO m2ܥ!EX<40<)s$J0&+XŻǺr0 WIf"81Y/N(kqDyҝ&-q}EL#S0}1tӞ&ࣹ$0Ն@ SфO"+"K-Խ,u/KLR{YjV[Zv{YdvRw:@i1S/RԒJݞRk+k+ZфuO|uJIԁ&E9Eݝw1&3zR¸ҫ'u HX.^[) k5=֫^oU֎Z+*}gK*x"}o}T[,hiIXd$XX ZvK(b1Kji0~.Id{%5ƌmub&'۲fYl,i?R K۲@l,)M~S(ϖ-ږ-ږ=&hv))n"Tm, z{N-nbe1в۲@hY ,Zw[w[wlXe{ԲhYHlWhY4u ޏ$X%QeN*".v&ొ7Y N+8L'˭ABDeri]&:rTnJOG.&4^ B'鉰tRnzjU^KmHt5PUY:ڤVzGMi;u[0Mݐdr k:jW<+Y Vc UdbU@\]rZw1%D =6%3 jto ӀRaohP{8Ha¤لxuGZQ!Bjʹ*M1DK9KYˀze } eMz?\%,7\@p,z/ج (*~X>M \=K/n fэY[xa .dŇn?ۑ6#F ve *\K͚' E75SӵyE8}R|aM&PT fΚ,h7tK"zje &5-e Is5m-9< <i"Et[V }5ic [t{ }-ILv( m-JjdTa(DaFZ}.8.`~g2 Y)l< C)E &) lKRQ(>4-"0`4:BvTϛ6~li06fOӣ!LYm≦j߼XG`X7%,FeS T~~~~~\:ѯ@ܱͯLlp&&&&&yHȖOȣ4=Ǻ 8~?~?~?~?~?~oʛ/i{蘶&MNZ_ >h{)n͇,W3ZDzi+ZDH%!SL SU5fw+;&Wݣ'J[z5x}}"meKSS(}U_bִIU>jfyS* Ee 0#Ҹ%./pbGG꫏'0 }tJ%LG Uս K}=nRQtu,l?Bܟ7] yQ8fS5:oZ[<އ] >Ga i-h֢='(DY(d+2Ɲ k^0V9ˬ9p6\Kha u+suSܛ4Mvd v 5Sw&^S~U\EjuFbMD\C|Lʻ\CRxKnRɼRz]G<Ê<%cxcZ?gҺ C/4(7DSL4rL-3'[=`j\iǣi(hUڞ삾`xcv1M[؀؟6f'㯦퓦ⅱo{@o(~{Թۃ:wt1/ IhT .|~5?$WLue*P{H5IT>k}&iH|Ϛ0i) nNcÖKgSzN x/6vF~,P X,> f [Q  GTiКn<atmާtf2rJ8ߓg`{! ti`Ū\R`.zZǦ^c@6מAS6hMEC}y>& -ț´4\Zch=&Z5Zw:`-ۑ2)a MЁh|y^&M'{ΧJZj9Hu`7i;VMZs)@*=}Iaxl{ܖ3~/cA!S!ȴxOKdq40ٲ2 )ج"- nl4@8&޲)PweRB c @ 4Ex۶ٶ¦V V MKcd0-cضٶhr:8`iJ<ۖ! 2cn=lD@Sc餞ݛ&-HkGٶiAtٶiZxDmjR ]3gRy8n)FF@n[9ŀl޵t+Le^Po`qx3}@Pm YJE]5 n RٌJOP6 i7}Z7@c+ಮTz9 P%i+6bs¤>>cOЧzR[\I@Nyo(3.ɋMO%J la!xI+PKۆMפx[R̸}[tݤ~L4ԖѠ}3{W>X3>0 p>gP, RA|?eR ɺʁ Bub7@Mg R:(u5P|O_6Mx>g1qԐi&푷릧8G>l.bxźcScCaB/ֻ}h- M.}4S 3 M4[5G@qjA3.uQa(~h0;/52Q>ۧmʶ}[fJM(l9 >MKCJէi[ꕪOU>m sWćFLdo=Jة;A*bM{!QIIDp~P%`8flM 7ُ3G!}PB6놼 Y;LCŽ[< Le^ BK.[6jh:]IM 3MSď'51MO%CU)UѨX40dHAj&>QҴLWPpiڊ*j-MSˍo9m/X5]D*hC頮ҤeG˂J* wbmnM}>q*j)HcT(?qzjӰ2]dv~\>z pp{8wB..AXMuøDGdѝ" mM?S Oc9DN"?=g-=.Zgn6qmRz:1G|e|{M{74q|M?_8Jm&|?_ӛ)MnW>_S| l_R5m8n)>ULJ fndcA_?\(1\( \lcpzJĒ!;7F5tlJ#4E΋DV)0N<6e/޶~i 5nMka7k[nZ) ܿ_Lq{N Q)>0*8F5lQe]L*HfO'P±dcn6'R?7--] `Nt DLxICBgvӚm:3Nϖ&۲C)շl0t,xkrKٔK s|Oda4=Ct`RKK3ȱ.ekck0GЬk8mwn5uخ?i o:ǼX=4ؓ?er <nl։=zW!*{6cHy$ÞZ[MQSI6y#]q^>tțB]縚{&]CԤOSy`{L ZrNj!Կ^xmj!O&[lj 'er_uCA!I1 2xPHk`3ʶyZ<10U⤁ބ{ݝDx7Y: 请C}PHn:lրnS* 6dJ.Q^ReѤM ~ 7Je%w4-CioMGZ.9դXL^Vb5~15.< IK3XZ/匦&o^O:%S t("h4<Dr &c5<'&8> 0 5iWM/l*eb:6iӭXaմvvHKT[hyW}YLŮGn=7G|V@>=ë=zݜCG7S9/*>4Q/ȥRk)1⣫h;r>.磋=T*LKh;R=T.X`v^pRh4CC#0-uy|]_Goz]<.xkA0) aMGkf}Tk<:9s<BxIcJڦLsDZ/:rwDS-^uy|5_WlՅqй0:„siA.f)x/UתrhSM2Ҧh:YS9i: ʦ)fٕNQaӔ Ns|RW5V=<Ƿx:/+Z :+gFn\qKicy;U^ ϛϛON4;45xrw욱<-mǖґޱƦų&.75ViMK3I% .2­ؤae9[@$ 9eowdfW4o0 p%NSQp*6i tyP+Dغۃ`Mn ryZJNBeDjU/Ui#cJuI695]mM= u~}[e]AOIcq$ptq,J?邞[^=pUbHGn &ebIf}=įI 6Syxb4-ry*soU/fMg4,&o$Tp - MG0ʦK'twamwpn4 L*v\xR/l> $smUU`#QH靈6/P3i_^cc/80x|~|_SlON>)EsyL*7=PyP>j:&tLӁguo"p9LM{xsvؔjߛiyܵ&Kܝoʥ5~/C|9Ե k=*r?0l7eR:_:tx/]ٿoٿ*ب*SUpXQ*{ح)L\U1@˹* l<^UG.cbBGnPN ;*//MMm)5K>Ha4 n M15f[d7ۇ^M%MSz69 M./r$,&Jizf(kh|hb'DӅGCPr(h VSTquښwB[N*iI%;ِǐ@ xM*6I Tx$O*`la9$ *ŗI< =+Yҵl _t-A[*ojhc?MN-T[Y阜0[NN=*u7f Z;udUZë+Ma*ZMj3 ڢpt&:mnjt灦iK~Li{/?`x> R`r:΀s[j ]T$) آ_8Z l=u] т>(Sb//x hrBK Rif+3i. -ʛ@4J^o:צ%&#Wɖ+]jŧRd__6TABRtT^@2ilwsʤʤʤʤ {XW&X{XW&W&7,oF bë0R.G]^|]Yؼ2222[ZVMKӤ(ljx2mh15imh.hqvma{ma۴ImWaϫjj׶>>¯h^^6m- X^[^[^[^[^6ivmkK=fZS,6ӮnnmmoN ?(B{p˥RX})V_ɨ›¡*i}%Z_IďQ̩ɺF BR_X &$W+@J}%__kZjASaMkZj}-Z7eRSCJZj}-Z_Ka.ײjJ9]˯뢧"I=zns?s^#kLZ}-Ӿi_˴e2kLZ}-Ӿi_˴eMaOaSrk9tZ}-ݾn7- ^b~.oЧK{6,K*0*?;T)d &q^f@}jЧ^ߦdMN; T^}j*e%PR[)-c*Ǯέtp,W#Ƙ;W^T>y5i ͝?TyӥJm)ӛa22ewW&W&η<7e>2z2z. Ĺ`1;uu2q.&CA& v?8lfWWS!)mpW{:IKkkp©}:j8Ӵ)Er#շat4=4)]Yܵs+nڟ֧fUZ|wMMtⅩV%/+u$"~*2[3Oܵ`j i`#0`1Kڿw?8ŁIZ401\6LuԠ4 mJ4,Sn0;_p%nZ2\i+Cm9,`zJ2n|EOz#ep*X,GLwx%c_Iz(C &1>}Ɠ;xH YCMae [sk(vz }-T){Z] S0U2LʞE *Y,l:DGѦ0^XyoEK'= 2G㹡JGE-scn,B7&[W-艔߭oK{) ukd1&䰻݁#%|u<v_ﯺ<;|8bWG=Xn qb+6G,>|!χ(>شLԂtJߣC 0tm# ++C,v*oN p.^. pI3Tf辽G7!v-x>>%; !PEMqSPTj-Z=؟ҭP}rrTp.R4?Ry_:bo:Jz /&y[Yr Nܛbhҝ{tcaݔ^n K6EIq ~qt*~,G $7MV|P%CW,[ʒ=I^wO@Hu &;z>5e.^A^r†Z;6,)kJ4 @W5ngӪMJ&aU}|4i@=֞ekekq/Wױ-x˖Kr4Cek$”LCBZ\G¤7-XH$rh*Xəvs74xPb<º$( ϲ\P*Yj`.'H֎[~| @i0U H?ۇF_dK"UjK堶TFL "U E1? FA%X;4^sP4 &@6xh H)Bt>]JM34DnryK?ILEn05mrX*@򰇦R~@{>ZfӦ9EKܴh(%66UY 2( *@((Lτ~I9>N9>Π(Fa`bH=< US 橅xN9G.X{ޑ]EyOOrDKM S,=M;]PLSnrKcF\,N3$5j|CY5CR7Ez)+J{[nZOSH4 5i镹IFiPBʅ= k?) MBSД5l5%JR+QhJcS2єlJ&2M GS2єL4e(D)ה3eZ^@̙sE):5Ĝi1gZ̙s \ʹp%sOE)-l19vմ`4mr<  W4EMWy+4ӆiմjZ6\MEiAkp5-JMU&`ZiAkژ5-hM ZsJiմjp5mǦı)j l"%MIF͐,rЂ89faYMm^5h uR ˬ|ҧ^MtٝZS^x>tpCdҔd@27} $S:|4e)LYJ,%S)ɔdҔd@2uhԙ3GSME"S"SLjVO6,h/m6LC!Ɛicȴ1dA ƴ1dIc'GS0< 4wlry&1,mИ6hL4 iƴAc/ - 0RqichѴicuSyKMLj M1Ƌy_jˏ/C<4RϣOOC*fcs1e}j,ћT ΋`k޴CQAQ'ʮ bpmIJpB?Ta"x.X y,yyj^R#`pZpY} y!ɲc+x T?uu|%H ސ[tޛ*[V lHn]j7Zf@ 8) l^Kt-xm%:ۋb5UH7i#\r[Esvb9 R:/XzO=?nP>~x>X~/zPJGP't scv0/揮 .7FAZ˻LKmͯy(wB7'M&<45iLjІbBύM1L*V/MiQIkV@@fRp)dM R+xn*Y30Ce:;o0=oR̟zDMaḦ́a(vzܝcO[m^>%irq;(5RRebOpTj|#>ԌV8l􎚶sl`#GQbeҁ|Ȇ\|p԰'%a2uԈV b94|7x'pԀ7 WK Q+q WOc)EoX#ͻETLQ葂gR^rnr{c{c+cIuw\ǻ:r*oib XGi{ P茂4B4m >Ͽ7<0v0!6 b0MNq¡WTTe;Ca]+ \?6/.6GC4Wݢ>83K aRfN4̼ zvm7ۖy҆qyFs^N{ӥzr֧Y"M^!U^LzTczu',-)V/ wi4]}??{DzЅGCGR OLbɴ3-wUf:?%PH8n 9jᷦ`-SG)շ,@*ho㼣!!MiY~,}>69MW{.Kփeѥ'I3GLKh:(h)Igf2[h{OJ_Xa7Rz0lZ[K FťaِL>5J&aY .׭ם[v҆a`ð5]. G )af#Ra R+{Ӧa&FaQ%sQo/MsLFM\oP B~40 {Ӧ!eS8od#mRbAy,4Z[( --BmC\ ApAiap':ހmY.mԉQG躔h`sslZ[)Ǜ)JUF#$WoD'_2l'xi05TlHRWȥ<0 yxn_* օ]Ƃ-,x IT`3S l?J/{;x+J1:G\A"&UOqct]߆|5A٤(CD}ll\)+6iJ"4kJJߛu /ytJ6Jmle=,V۴C 0Qg=:+`!x,jOue{1i|\t4(S U)1l{& ՈPO /Q*Gg 8qܪV:~'=4b4L*%ƋEaR|&gJ/L} s@i:L~5B1J;BJôb]U ntEe翅߁{FI#{̽,_~J&{cbv&݉}[KJɘTF.8\ `.nUwFMrz~A[F n>&ڛK^FRiQTCU7OTJp+"iJ491i:)S"#jJͩ4 3=L1MJQ̿EN,+{A{rm,?Q[էLm&oצ*~ ( q(=+vMV)=Q*>86ث6 C[תiZaR,4 rX87sV:HZu44jZ*ZY|ϲ1TM7M.D قP^>byrʻ4[Tl>=Cc]]+ŐPһ0uTc+X ;khKJsB].Wف#o0)VMf`51~ؚàѤ66=ơ5pmxh Mˤ6`{9r:š6Z0-jԷ @@mRaw VM]1LJ{G6,S:dn7%_l& M["S8$(n@AWőxhǹvP,,[ۂ3@ÀA6ySicdޣ.Ϧh-RyВSHqSaPk*?Hy49liR?p[Ҙ{KEp,~<{J~JӾ- !B\7OO.!v~v~r\fD Y)ow}8` viF=%@@j\ Lִ\r[1u^MF:"A:hs@mZ@0ۣ1sV/%sPl5le9P*bsP3`3;4ê;DSqWB} j5*WS4ՆzU4T֚CJXM3d(a5=S:]jsc6Ծ6}t{(sW9RK3N%&=U\ 4.Tj[EOI/^ Z2$< bAFHF B@}@ [ ,*8L|T ^ի!:7d.#4{O[5 uRkXĕo Ty!idhyw4#(5q8, SӤz_!ϴ$(EwjI->ZO1δ o4j4V4=vhXt4.ܦ ]9PATq%z)aY0D}((+`p&? BBcAOGKrT \'`SPL50g:ƓPS)@J75>Phrr.RRR,Bnsߞ&rxR3zhZl?MWyW(reIS)ڔ*@*/xwfڔqT,̩zH776-a4qҿ)Sn8N9q8qA㔃)wS/C)S>|.N\&ł"k<8Cqڇbu:>mP=='N{N8/q_b꧒="N{D8pᴧ"X2L7o8߰I- WOzN9 =r߃_8Wf~g}Twi R0g6J:7ih&,H서H^+VT ޽鵛^;ޗؗ{=c$3]oo6r?Hir#m]_8l<2ґv®eeHRv+an"DΏg"秏l~.pQ\{?_ ڴoiUaIE'N& o3~'AkN(6]h;/mfSzh9\t,?@ϱX +ԏϾ">EfXNG~+zyC9'>ϡsl:w:Ke2SQ<G ];O,OMBgYЂyv?Zjtdts6Qe:9jNlN3A]3ٗ#0wNgә Ng\&pLÆE/1 oQsH=]UMic$*Ko5giYJIut24%vг|x,<[J!EG0 7=ύ<@Ѽ5+oISZ}]*:ZV ج+]/We\'Yz) y)nZ#) t?w0qk?$ y ;Pr/ tLz!]ٚε@A!%Ȓ*hz:\LGZ3t<7BIqߐy#\JJA@/ajGdZaXJ,(steF=uyB'y9TO7\,C޲g+Iup^Gg"=E_7RՍL|d Y|Ą4fz&dMO:Ρ']$5=Nj~!]-OHS.Gt̀%x7 i/keW0ܪݼfHTrq *}w\ipj m_϶t?TX^)v%H;ȝFdiGs -6@Rmn#%PY?,

*iWڭ܎(˳(SJs7OQTL|9sMW4C; [h5JuJcxEW3Ti.'amK!us6)a46]oa+y>]ӳT;ywΏeI F9VY|)Kw;fPzs-`_u)V>)r)q 4i&$q,і6L=!Nn}B6~on҂ƱF(3a)g5N®ݲ]խO/0V dY:H3CڤO* ޕ k6iKz%}hV\.4tNҨZVeR\~iXSpt0HĚenڟs5M6A{@DZ})ݽ\~#u'(uh3adLިEA_7W )u =2 ]Q.(9 92ܞlE)4A!)4I4b+5i98pДfB0S*BSE }J\)hͰ ʕ(=J *QŠre1x0*xʕj2u*nY"u*o (zb&xЌ0J@aԐ"ߋ,-z)#Qcj cK]QgA!]w1lė JGqIt!*J3~˺e\Q]Y{8 И 6mvà\Hi-hH ;&@0Y߻F:L}.osI+z7SV4p ڶmr7u󃮉@wit<9 ZdtpE%$>hYҕYc{ yX$E兒m eGQteˤϔϔY gJNf¶!att9L/ؓX>Qƒ$9r=%re>qKuc'n'GK\B0=vQeeڨcz`~pgu~啀#c$o7!}Y@ixYս$,GG Cgz_G.kUV>>`6L醥0O+\Dr:8mee}$- =+߱]\ʈTb>fAϱ}h]{5XŠ~Y]̴YvZ# 0#ʹ "$V>{v$c2?yz!o׻.:]UtAJtA3ak֗ <.xt;hVSNR\QGGˇd}\'Wi-*UzQp!U*G \}81Ϸ'g GuHɾTN-z6G4K|4B\ix>N.y&0~9mctt kZGH{JG@鴾zvBrO &r_ hKs؊#0Y'Jӱ?9sd:Z0Y~KdQO(+۠\'y\=e'2hy[zrd~,M5E~*@ӱ׽W`]&7Rn\EnZB)O@iʶ ,8+Xj9cVM)d%-c*Vݡ3MYݼD]An^ܺ'ԠS^Z %lyD|fZ3iH>qmZc1 -(4߰.# AuOTKy(1g.S ,ωXfrIT%!ھWgwi,w3t4?k!4y\2tzv]kJy=%dTyTRku96YcdY1VSeKـ3;bcyCE$`(+ rQ7)WMΥG'~y9 )#dugPux3sUb~TL]d/Mr s?fs##ݧA5 vgmwUծ>LEt_: s7ЃffGsLLKXĮ?^ Z{ޕ{w]۹UJm}*7?B"؆]a?[[[w_>mظmظmظmظmظmX0㶅㶅ac*P;6;6;6;6;6;6;6;6;6;6;;;;;;;;;;;;;;;;;;;;r}" 7lvlwlwlwlwlwlwlwlwlwlw,w,w)5-]QpO/Κ@(j3|鎍y!aߞvT]*'ysw%fYԜn$$ժ|eUz._rCfl -u7 s)\>. UKU~Xy_tz._xAryín,pPJY+8%Ζ׵+Fb˗Z*I@WBzAWT ~l۾@GM$cۦ4]/m?c{ۻXEW>p?r0qmMc2l"hvz#l?O.r \]A| v' Ǯ{$Ht-;z_tѐvPb8v]d{tֵ6f_ڥ+Ǽ}K)XJLs>>;&eF-pb}^?ʯ T |$TϠ(^1SpE}m4i;V5Q]4,X@6ݶcp;a;.6c)]YO-r+EF.c3Y=8e&E,}- +Rx|\==WPC֋ hBxEVb=(ʵqUY,zb??^A/ϛ \z޼橢[|wth[,9ԗ{ye&h6{/،^4H=#dMJγQL/sgNӧLTVT֦(=ʺN7`8 kh7 馂tSK&9.P*5}htS JuϰFbsМ']~$c5&_hgCHE<jN#:ayZ~ty@dIyt72S Ky/SyaE Lxc'N[ j3E Od)yL19"*I'{Rg@?-uv)!=/` C rz7 SP[V . > ҨԻ/zPvz +p.ZUqK.w 7 ;sR g?#1"y<:z +A r\t/ɩ謐=3Cd̈́iO(.䤪h@頕LċI#j4ʶvgJ+aC) >8l_ ;4~-Ω{s-unVGeG)8h>5InY$ǍTTCϟP w>9vt&u,?AÝAJB sIN<2= r<tMiTMC ``:;G%sq-xp]uQYGe ע#4J7jT||j=HohYN=Roi5s6 T||R2=wA:r_A Z+CL=RARA9*K$L\X2#\.vVAu%Ak{S:Uu}4?9I.OOm­yp)z.ݠ2SrOS4f(iJޝlC&8 _C.\~@sނ퐣4T/C?k;`) WӐ\ּG;tMg d tWoa7W蒩E4L;w*V@9]ST 0d' r+ t%,hk ͝<p'r'_?l6T.tT*Ja` S'~pE%?@ُS'H~$C_ص3nwsrH=9F꠪׾zW$]z]D>.Y+iUeO3]%E %mp2K{b1g#K$˲S /KOG[{~@%^AS.z>b/ s)r}WuGs)Z7|dlUJCk׀7A㘞l-k.;uneV &䥊暮khAr]y\8,[h&ϸ\~u+4mrŖ];vw*~ǭ+ CdWk_~.J'/ڗߵ k~.=xwB]xct{[0w}ލ=vk{]y_ƫލWz7^n2oƫލWz70#t{%sV{ (f1jE uiyʮ=7:09@:@* E6 .P_(G| g+ @"Z_1P!V.}(}GUc]ABE$]'? J^ޕjn/dXsǠ'2^y[( d :MN+, i Ob=צ]/ocPphvtʵZ5u*ʽ:pr\+ t PT3$Hȍ" 4,5ܨH[!ԍJ t%K^QN(nS$RMuQNݨ@)?nQ>}!Q9uQI,SM*˩NfDnTR7*ԍJ 4{3r~_ޓwtRU<]*P\ϊ%$T/6 O&jT4meGMV742h3M? {~@/}f6m=ױ7`kZӇzGx~?-9[>'IoZDC7jab5Krt;RWyRm[x$(15?`I0]\H_"I-}V9lNJr:M7itMLA` S& wv@#thl &/hٰ{@gIw?wܙEO_z \w_z~׹:F.ۀ)*+`:4rTQrP9t6R J'TpT;͓e 'Бt\nO0}?fh]1 Xz|z@svʰP<=>y|"CK IPr02{ $OPY_/{֗=˞eoh3(n&=W䂦(n&? U~=k5q%4Cv gpS.usmP.v@/(@O/=>dnKWrHoRxQǽ@RѪEEGrm/%sc~M )ܹ@Ne݋"j݋>ދEmqyߓ'}O=;{vy߳g}=;{vg߳Ͼg}>}={g߳ϾgW}Ϯ]={v/mޒGi-(ShESb(-l*}yWp$- Y.Z~@.Tuϋ t4+nOHC w_`Fh:]zY.ZacaqN;vdJd]vuK9N& > GF^ K+IU^9Yzx/@Hrzr<ѧ:ȲiԻ[)/b m_,Ŋ#y^~̮m&O}FȥHQ# PZ=Keov˷yۼ=WN42QgРrSYrfJZz{/hTS4^/n9,.ːU(}ѓC;s; ;;[E{f\|fbepgW:۾6}np}.˾eβoho]JO)ì]LaZo\-W] 9Gwu٠G4C%絎 ,AQqΡE\Et].m(ү=/Hz-Ԡ<+~hKL! :[)-hcP>t)==qzfr -7PJ ?%Mzl_ *@eWmX4yu,p~uW7(Lz hSr91|GUmbK[۩>//撠v"3O % g+qXE=0 ]unI t]=V9"VRߧxF`@ xpRBR,Q; !EPԭnn],#Y"^Gjn+իc: {NF8{ԁO_z@%-]DU*WԑcT%˕tȱ=M*鄮JRT̒4AzGyy<n!X %/OTQP\oҜe( \{n}i5]eI}4#4+IwŒ\/Lᰳ\ozݔM(=K󌤄LËSX\#Gt5l$!QT9kdlf?˹s,}jsr@h ; a0,H2l+Zg:pyӅ[ti58G\2H L*OoOO+On0RrOy 5CXwdZ#^6H/kʹ/RV] ",oku=㟞pz'xaJ9$.[!۵kȗ?KԲJ|8(uC^7\eo7C;tM_8o?R!i#~;`[L:9V_e0t{&f2ҟcYeVXr z]ۿC$so3%B>j†$鍮0w/Rt>d%Qll%WgWdK7͠:x1_$?97 1= OQ)i\*OL)yĺGxj\˥+Mut-cxI{jDo*zߦ&mGl!a:6=rӮCk={u{x|v/8_g#T;}LC" 4矾),{W6kvix rgyr$ZknQKئLݞ߬w]D#sy۽L# ܍i=]{s`6+zDqoa}-v);tzdYxt5ѹF]3үL՝TM%#8JGRp.o3\%SH%XT^JCT٪.rs,YkY;~Wzҥ\4e:EWWt]+Eع3=]^}!=<wt)ׂ=-6ܢ'[{W{Gx<C􄻺C:ړuSy',D\꺐Tv{({>+B]OAi f=dIX%HxkARSt1!HnQ3y n%'t8_)'hH*6T0E.$ BD-Ag|Fd/ϥR}[B\Go<`ܮkP w1-E"f[Es9lnU$kڋY;INUL˃s\Vs ᛺`*녂+8_@*T<>>_gPsTg=bw[Fo *A#aO5@);c:&ms,?I.ezasA܆Ύ iI<'*z7 cr(+t-s{_ lC9mzU nd)_GCI]aB %/t'vsq&9d(13 Lq&દR \M֧37oS!@n8mft[ J:nPfM*hIZGΫM;I-a6si'ikpnͦ n87q4m5ƛ'I lIڡџø1lItyȱ>ڎ.Zv^MoLRY/K-u›m(z-ĖWbQz!X*g\4*ت7|͖fK8W.AW_6rdI.e$4>u9W芴)5BƍLK5B.&& dgr+8;{Y0Zȝۧ)t_9Vv [ue{ݲn^zo/`0 Jf{%^ldvOjI^l/i4KMdW2+MkI^@CZlÀ; N+ΊggųYx@ggY}v>;kggeCryeCܡe HU*hgYly+gg- YvVAEsTWA;U*hg *ebg[tWzhg=t5?$gS;Rao#EOߔK?x Ƨ`(J9pFHSkM*M[w>: #m\i{Z )&wL$st .X:Ŕ"ޕ5vP:&;"6*@)@HPM{ϳtWaq:"PMw*@-j/Pws\ 0Ib ` &oA[XǭOϢKC䫳KxѸQM~U/@iaeQy(58n[E]NSjPb.890Y%,o1=w6]\4]mYd-ngAyGf^-&t'=Š"6a'M4<[pfh\^o7zaJ)ccq)ҹA]n ǏtNb!Y=y_xfaN]OI9Ln//h%IzAZ<'y< ]ď^NEc2[\ZT` -/|`Pp,gz.K"!UuLľ[F[Đϑ=]vIn;ETaz$4/ȷݥh<r?]#K )>@d}sLK[@HntO9{}i/eaiS- UeS-\ڹK3n[[[T) zZ:iMؾKjm.[}y 4iattWؾ rߵi[ 6^A;a8iۉ̴iV̼H*&e}'6]SzR[_#mZº'(k{B}ySԝWѾl{` : 4\l: +Ѓ|{`+Ah= =6B+Maw݊4Z4Ka4ԗm0Qbq}.F$]IS^<[N@'uФo #-{tү}Uw۵_H.Hg'7C'r6:GƦ^GUY(Y4ItU<!T 8rCc!4턝0B <٤~|6 ѝu,<ӏO)J3N42gC S/ ncW: ,?<ц WUrJJZXMhH) )Cp _J!VSد&w?8M/RZ-dYε7Rla46Ҥ"r^$j])fOS鷡ՎJ9Jᨩ\ԭ{L QC3qIJlOJ p/Z:vNX-#Xz+nSU h:vE|.kl{uey`|p3>᩿r~tB㓳+}ĴtETε`t'3>nq@KOvZ:/+ryܵ]YnAۉGyM)2SulIqt=$v4ie{Bt#;W=*'7ymPry^32_FvO\UӅTn4t%桇`trrve8^ $桇Ѥ*ٝYx 7:=/gؖKci+G}h&98h>&d\<+BNtc;st$^ٻh4Sj3dVr,ϏN'w:{g"̄<&EJ:FKn6r8q&a\B^AB8@,'3 \֌5G_' Eqp^)XZuv*]ξgmJfGqv)븮\ܣv)ʥTtEȀif,NՀj?ʹמ>t%v$$Yrm+,)P7lZ:=$Zv e(P Zݴ(9sL}Ok}E0=\GNf~EI_cNZW<_kYͻ5R*sz*FFKؘ2.4<Yp4E{aװ pBg4qfDEJZF ^FנyMrf@CαR~/1m`=Qy^’'qACMďyPB+ؙ؝ؽMa9ixzi#sI PRxk,~.8Ni9K K%_N<z`+Do%G!]CyCyCy#(; F]Ѐ.MySi_q7PXDu 9/ES^ #7{|3|)|)$ڼse𢊱/#l?y.*- Ӑ@}f5%[QIbM@Ņnj;,b6ήͶW"P>946E=fx\LTz?ݱ1b-swl_rovnc/ *P#CL4(1(Y Pb-Nvl'~*: W)tt)MZĈ ]_G6n25ѡ~];5ǑifAWgytB^,NcK3о![u]pXǑ Ky!o=LxzoqS,1^~t'1ҜrKw7X<Ƚ:8P+]\ (B  ~WK?*sA_>-LNG/znjg"Rq.֫9-K"s˹)V_#gOLw 1< 1a<3lx`?\͡#h[ ׂrVh+?X;Uu.ZE7%*A3C5$£앞nqtK.:t؋C6 ø6QΔ"=xG]@si&;6-p9R7=˲ݻ:Irޝ{%k%/'ä+p.U;'汀Ov(*a攱 @"p 9x}Em ה˜.T0X i\6}v~z<4O4:T]dcʴn 0OCR^MK,Ò_GW~k?o"mq֎yng$T WG>j摏>XK'y2.i,;l&Ni;^Pg 0 y4C Izpt5=׶ܭ2/ {%p\2"IfP9z L!*[0UA׆Ӯ 8KifJLkÂ4*`z7aJӌoBvCp#GB[v71I{"9 3 'lR:Mzm#@ץHO=u '4RAOR#ne)yxFu=`2ip"x/:iPu$Sehty__O PM+ S@-;~ κ^rBUjM3db/a4"9f@\aoi9/]=܎ԏ&.mrLyҞi9Ɛ, /]K h_c޹,,>pY\iM@,Xŗ6dl Pbj\V!M$ږg@,0uq}ȾLi~VtZ@# ]{O,s?qt87]Q)x @Upۦ?@XrQ-qot[)ڮ_;%RM]u^RuﱺHqTo4{cuВr w,@A_^|],nu,EIL OK2E,SoȖp m]bҔt \]æM'93 ގmcqXFzWJ1.ˣJP;),זi<Jy/a4 uKVb%}YH˰Oe,-tL4m% )}%cAL^& A|N^/Ӑxz*YJJûx}2UIKΜʚ`+1weW/s$yݠZ`Ӎ Z3jtYӷiӓ: = p =k#%ˢ3Ϡ;|w7n'vNUJ|a`(#aAU [*XàqǨ)v(T^Q𔋆bn2t\mS:7mHﻏѮ4i:>M&~l39 9lG4^W,-8t/"(u-`W&!Tn,S=.WrA}`+ ..cT#\T74Ji(y^wdmq\#d5턝;Ͳ[!h}&E 7ۛ׾ *ڟôBj {6zK+-R~.O[~ŵGDQZNR[7Alǃʢo=XF+>OFa \\ *;;.+}}Jwr[O *ըZWMCO%>/ ren7oQ09h/\h ׳) (UF|+-!)9@et2 Kгud4ԇɲ&K@v\@ϥr;OeNorPTӰ` Q?!o]OޡKAnHTX 8SVڣgo۪$#A)a,= $RmqyZJбV\ab|nK^{i{=޾co@-akm,m=HgT]?Y1mK0=!YYݶrU!˨JFr^z"!?0;wWt-JKk-8Ӡ4u_붛>삵`)vukhǫgҧDLɫ ;nYw -w8h]7/OqкuA׻"rW-[RvTK꓅t{ydunnQU)^>,O1JXJRcYeRv(l Py4,XuU'TsǸ}211Gɍ{\ "w!IW_D)6:O496441n,:$1OSxJ}ɓ#kG>O=On 07ZSpbb1iϧ#UT?`\2k 0K -â i -K,.PZʓE7.yA"Kh rt Y̬wh4]@3kzgf3ޙYL%ֿ+w_{nUz-p+h='[xBIQtYB$|G,\jei -8:͐{ѴDo6yQYv`G={&j3a;1rY JNA[Ϧ* 9CjeaP@slX 02zEn]\rTamw]y-H4r$ rKe}n%ؠ=2B4A%0.;Efs'pؓRhXt~y< Vaɭ膞dPšeHܩN &}l48_C4n[z]|j9ۮw/띣s;GJF9rw\=ڂr;ڣ(1h*WP7UNM\r87ױ܃M_[BWtGLAwm,6uASڴ :NM]vnc?tz[ob<9jә)[/kmqÁ/>ޠ0y'B<9B?e$5 O0$6!=0ӊfjiL= ʿK̠Zܨ099x6X7hj ۡzOHgK#/~|ޏ 6( &ة Un G" *>$נ\681ṆOW \؂ӵg>SI[QN+mJ Jm/=Pu Q)A3d tUό%uz);=L(.6?צ>Ho.n 9GhsTCUhMWJM;@RHl{c GKר~ AwEr:\ERjAkWAÒ:pm #k{ݱeBJ|%փ =AKIcr7 2+XY Q&݂([Ξ[p?7`٤d-Ww @UNEi]?–ݞ?2L?ڦt 5qt4G#]S Enj (uL?ehdGƓ}۠ 4]w۠qvKzy>xdu,AyzC Vͳ@珜fW{=OCgWx&yNG (>)\*Z ѧѦf2a8;R6T8hG.J*,Mnݖjj^=rcZC`IڹYۗA]G7?*5|b)FZ3t׃F=)ohwijA42~A#z5S\+ny8Ta._dk.tg777;'kCp (ɼ+]e<춖;!jfgfgfg5+.>>>>)ާygp-K@Qk^מniE󌂡*Xzdz)J7=,UG\G=@uP!햊"6:"wÎ7.@9<ζSN:jqht_xs9:^/tZJ6gwFh?rGrᮮL-¢xay4Oj_Lqm&EeWT\RR.uާtYZ{V ҮR{{,5Byѽ@7h/EGz-;FbKè]U ދ4W(xVE\ҩxOzͿ^4}/Z=PcOփ%BYv/ҏ<=HvøqÕN'AgeF(a1A-΃v%9lx#D>>kd: _>XP*`&*r${e K``(D 'Cv"Oxr`(ם:",\c$ՈێW-B7U6]ɵњor 6]*@ê2lAZă 9m$@rׇt;J'wj&Oy{\sfp(~?=A[2 Zl/[dA\|z"/߅B,Prvz ~ehXJC3sEbԁl tۘtkxHoVHuh> }%j[)O_ w<ωǿ#_% =r^pUv?_| hUU;SQ(=e=S|d,nMAiAѢٜIOJ)#9m_[aBtSi*miPb3~ .HMj.0jx;lgZHk`ۇt,a@8hHr/0tK$ӱ3uGɛAh4ey}J?fgF|_йt>(;4S=;:Xʦ\[$}sDtBnwLx˓N7f|kc%JHpʷ(ۥ2up% J4~!΁#-$Eu_>ǿWNךa+1/Ġ32MnAGΖ-SʛyCVX9Ի͐eӝf}E7}u{-y1CKN= T},2^ZwGKܥZz/=OSr+}`vQx_2YTJ?9eMaI\q蹽靶x2Jh-ݴ }sÑ`'̇Ħx~evg[Cnٮ#˚ NgVey9FfۗIT\9V_O]t˽YyK%V3K7-%ؑ`sI=a7'l{V'!)tɫ+XJG=-7_S,hDM;Xk:9Ck.>Här2B"Qfiz.5Ǿo铊1ɲh p7h~.oz"yTt=ݾtKsHOH ;zÏ'gYtgPj)Y/'_$w^-/%-ǦN _t}x]EZ?­cG˯'U$KE/V `SϷ}M\l.Ex1V%,zG<*jg%J BnՎ#l׵݄%GBW>CSb^;Y0\ xMSwܳY֒@4N {F' !躔㞧;v)8BJ`KjGH ҞWOGP^")3^&a ~ Kٞ}S=uk_LxS4! ~(C>Y+\/Ki6*&; HY搫\܃YW!s6nr7,܄@slOO㏞M>aA)f"ǭZ:&D"KMf",Th%,f~֖g^:+!_LÔ%e>Gzױ|˿')aq[ttǙ6\?z#MiSz`[.%ޜ.:inPɚ]HiwT&2 3ucdm]H;Yri h& %}JAAP[>L.vhxLie^LJö[Ƀr| 65؆> p mGw"@Vu'p]y1-kI}'*i$IFwX-s8L)?Z&vAo=LDzꖀ;|%~}$]}1eHiWԜaZӳm~oJXL6}j7xt:-翏'T]f$(ZcN^ xyJS,ʯ34f 萫ڷ :$%tI|=󯏹L協<- L3zu>虊t9֮Oorw `9x!nщ kE$r5j WQTTxџA%9 JssSbT44NžJRw,9I[i9p:FuC%fzWb>H3k۟3a;t<'|Jj\u:;>==קG/O=6{r~nir {Xn< CR&Okr oK9[%Gy<ȟz[S nu~8IaJo ճaˉ-et[s؊ rI /P$=tpe,Njƶ#'(CM[?Z<}x`BㄞizVa8Pt 8F*+ӎ(KrTUTbmA:ο<^7LPo)񻊢nVm^9&]n*dq8Y[-Pd9 ~] ]vk{ݣ@]h+ܛ>ɛƷ;Lw7J†{ZIج$lV6+ Jf%aega||EآSl)ܖX}Eآgl3[7CWtԊEآ{l=[t(z=cEآgl3KWr`@w$Sљ)ਮP1Aixɧ"`H.Z6`}P#WhP9E nS.իҞ|*ǝOT, \3?BCEs6wSk< M)c'7]+HFMfпfj_fnx*honIyqY\rOɴynн#BWd_ O y,;m6@}&>.iwCH!/ƶn/fDpY@vIkSpʚ.)xkh B)p|ҕˍ&)U鄜埛G(%RȀ R\``<$-{9+;Ib*@ [#܏Rzhmӽ9K"K$ODz eRR?Κ3sowxVN6`(1W/W`:䪦R &EU-~S% zҜPa8Gb CS+x:i4oMxH,r#u:&_n0wRK_H&n$woI9Lmg|ë`hNNQyFzj}|C>@kpRxg3yO~W[p]اxԱ>u±Oc,h#G^r]lDu : :Ϋ.>NoRҹi\w 쁶}wm;9Ӈ@,,E{|y#{{ vvvp{{h{w+xEH|dcgcg6|'9&~Mll+=@'qsgsgstwYk g x8]O$KOohgggggsgsgsZ,gügtw-F?vU; s6ەSv20\TT ́OJ.cA%owg;%qNn D]?o5Zޙvi&hB_p93$fҰ c0lXR|ΓCij2>^~ HQ9 $Bd Z״w̐eL۴K^=aRſ f\Q[a,oEmwW޷  %j5FѰvsKqUz(]ǟ5i. N3(n6 Z=o1(;]lCS\νZMW'lIN%wt ;[m-T4ryktr)T΃În`IE.*{VgH4Hyy1N3EnoO~\p3cr̛Iy'|f!C1DC?Гi)c4X-ଙx4p`N><%"f.͕h>(VӋЩլp;_cʺbs'ʹ DGoZtBץ4Ӱ w^ӓk (C:mhPkj4id{fIhfM Aڶ=Gd JOȧǴ6&\t'NGYɑh]t4w'QӧA }G)5wQo#QA }>mZ.o&!/⩿[|,?Kҁ<IVi(aotSB^I tl墵L5<WA;_C?Id= f®x姻l4Z]ph3謅œn=-ӧOcp2R|g:kY0̊fce*8㙆c{fn?jW&&ߗi9%AI^%[clQJb۳~{d//!SHVN.pzCbV>]V^b+,PouV4] x0}^/ӺȂ-d8W!+pכ[{m ǹuYU]M'SfEՂ V h ZNG:w@W,w ԇi[;g{ $իEhJC70Z/C $;r2 h<%ziԤ(d n>nBeL4}&E&e.ey>S%=޵A;:q)әG?߳WQ|m?8d+DkgJCsiۻ]2>i>E?GU_3N!e-;LOU7\gӢ}fȱ R]i<Ju:ތ z&]ނ #tt)](x_h8$l.ox$;\NoxV%*n(+7>9`(y,C_PN\ Ki;)xg JaİC>9i(j.~/8}˵-h&Pbob^~@ 1-_(#̽aPr̙X\He-3qN̐qKG?r:@$X5jL3a;a{Ϳ4Y uR p2+T5v/4tDPU2l%~OQɵ4nsЇ!Lnv\``X^zYrR,zBzh*pe48kt麔n;\L깊kZv-+A3--?A0hP8dǿZ/m]tR@mҾ@赺\.4 ,Aߦ$1J# y+JpdzpܲKRfP.ޠ}-)ϱ]:)9nR"l@9,TFrB}e9irks#2NQk[ؠ̺ ԻiJR]LrZn?ήO.Q&,e*}W!^ ެVv3M^^;*4'̍Xr:ZboVE% Yڅf=յԁz|ݡrf10K1]]˛n׎P,9V7țU#`ٜjն8mwbYO d. N3(JV6Z`zTjT/},ɼvxjf`IPYqR9ԇLE;U!CC+Мj d&L9/]g?YE Ó:dYx4JY1<CώQV @㏒nޓ֊iyOj;#9VJIo|2Z'ߌ‹)+"iFg kjg=ֳS.!7,sne (, @nQװ<]l{ܟۮ5@i n7(̂Jmg6mnZs۵k_⎳gcs&Ȳ _ǚ:!ǽip ;ONvp_hFhMvmTi8594wwr :vx $쮐+3'$g'uhϟ-ݸoM bjؒپjJ+v&PKr }7T N B޾s`J*#',mHt{[mH!rs)Ԏӎӎӆ9s9s=]* Kݼ s(%Y3+a]ݶmm68,WwY06?@uQmTƗPm!#Qy4CB$u+B/xnOpB8ԟi8w8@ϱ=9a!%;L2h<#z.o%l;F毠BHnOȁjs a9\ρg A'a j-f!ԆjgwL@#%l1 {_%g3zMx)Y߫V %?|66h;'x3(4!v 152x:?#Av^[uu'HECNuI=%R*ি$ߍ#,ԑꂡT*zԃᅂr-TOggMvNR 那_j2H4șS2)@,1٘lLkB#=9El|6f>3bQtCԠLK%"!QWLܒXLJY.XLt%))"-@dzA?3lPƴ-)1^|9_>h܆I]t y1\IՂn,49]'s  ]n@RUTzإCqOxld^Zz+*s _ƈ7ei2_>jʹ8ʶEV:A{l;Kۤ!虸g7nL&KwL,=hdicbUfoo S"FNAͩ=vL>1| JS]pv]v6т>tYç 9{9e޹֒,1mEj=u;fQѾkzW} :qF4w4w%啔#:O!s'FF&h97ffhdX^Kc;ڗ;ĝcҴѴ$=1t.wt.wt.A ,;K_iB~z[? ==fO=e5=Ɵs=ןes^ pU=i>^gfςa"/e10t}|^ q{yܞMM;otK!SV`KQ( TrET@]Yf~V,nW 曳TF\ƓnioTVF 9隵6-vmKe~#Ǡ677#>AW)FhwZ=eO9ΧѷsruNP4kvN*0MO] Ӱ.C rVVo:e~@NT@㏞i$Ɖ,mAIeոpoORR%ˠMP͸%T8*As-y()4:{F9e?WwtuځQk$qst#v&0{`;0n>٤.n5fJE*b 0iU+Oޠ²혏Jb5c5ȂtPEryN9e.#4ӵ ۠FVÕhyO"9_#+thh5ŢSqô)M.B\.C--"*2 fݬvM,!pE 7Uf:C 0(.؊!KA(W V^[Ypv(àyp 0<_QrrSX1˨"Aþ<_$ۆPݾY Њnk\ֆ@6ϊ> r5=ÛbqSH/a7(ɗdAWnئt瘝<-r znv, A)w7m|-SmtY{6@ohgx zVжōO/;(nK7w 񄂛F);'XBpNЎx]hG LZ|^ϴ3m)B'`4Nr Nδp v #z8(h=Z@s, '-Zvy!JO:Nfmql_ްt& 2M#F-/*ګa~M(wM AYө[%g I29A]:vkAk4nzηB#M۴Ԛ2-.q"ZS"ydA%ۧops,/MI岬:g6杀-umH -ui%np<mV`< ך϶ =Ӳ/h@#-=sc@B!TvJE}8 )gp>j꩑TNN'Itʬ;NtuA㸖ggr3yp>W+D}2JPI̅𩭍IR 8Aٴ9)TF 97z]/0,0=kJ.<^Wg*r"~fw^Rqf~wh؆kxfJmOߧч@Y]U=*>TڂS+OSS<nO7ߧWFwNߢ\-dz6ĂcK+v)Y7߬o7hMfjqLghtY|۠x|Kh~75.B#Pi0MѻrœٜaI+ bm>@rM $Qt$ E= ]P}vUpAa8o,{qX 8v߮KCݮŃGv E&2OO%.w%FKg]_h:L*3\z%eI뎩"}}ܸ dArWg<ZJOA1x t}dp] -p%g eň;0b|k<! kHl>[0>7_Jgً s2@}P^\(0W •qe:R9)ChK<׺?ڗkwX)fHD$:_Hк?Yr840BqsWҺ^FZ! nէۨkiv|&v&3_;3 6 QtcT\4Zu-8 0uQAzӢFJ^:Y:X|ONN>ftaQw- N{F/)w&/_Fȥ Ӻ2&:84`م3Ϋ}؂X<9vN#,SYy 74 r:!s׼),'0܂-p-x^NjG#d;d{ 7EwP͸%x^|u{Mr߈otT;ݸ&7eаow:NJ83 wŮDuz2չxCˠ'nmYB4V6=q8j*<jGqa+?PP@^Z x: V0XC_]Yh T0+ֳD{yWGh Rt^Dφ8H4Wwsp ^IFt xɾܻ.= 1M5uŃgEԓ /hh2 zAu|v tC'WwEW_HYYYS W߳\ůݫ]+Vq]ax ]]tZjx}! k\$eߡ*5{Q#97( ǝ)tu_B/y WqeVީms;y3Z{KR__x!w)w)HA&G9g-t{ҏ6]߾)[[noG. @f/ioap |lE2G0Wz[^*wNxDA\]@.S1m@Oh׼GCTZ-dYq5ր}WbEEܣ-rdhg4Wt.E ?^a~ ]܆q[>8q4;vzQ'ȭڹ:M}PJ-NݯK9fFܯKw) ]Q %U,X2;0Aя Zgo(3R]%%w;]ZR<rt!:t9O .Kދ_Z iE##\Y}EW!snv^фSIe'7Zb',_~.PymW[EDhM0 S>ѩT6~ )jtBOIFc:~ >(9NHՑke|.^I)rYN|?h9~yorMu/=,[AjGn8|yRQX\A 5%"k{ԕ%UZ LᅖUѮ0z.WZZ͕ґ8PS::ni;L ts%q\Yﶯ 댠{MAPGжn:W!Iы0ZnrCj=di< tnXZ{|+$8!1W!!:r2+oIKC'kvI] /"p&g-:]BM(RKCYP /}G gS`?A)_Z%ԛsIm( ].t )#iaoK'Mڀ,6\FU~k3Sp(L T}5A=){wwׂzC12zNlڭ[ %:JJjN>\{[f R^C =ҁ*೰eXU2h*r ^OYl6cQ*q ~\h`([a§f htӌ,gH1L1E#sJ Wܫ8攊mN 4,hCJIjGr8MvsvsvsvsvsRz 3_> :y\tu羫mM ` ˪륿ڳڃbC6v{iQlJPe1\e1OLx/vFe޳}/%ފ=Bp*ZJ v8C:>+Έ{nuI#4G d4>i]pXT+FD6AEnek,Zh#9Z9M6A9L3qgΔe}Xm9ٖ3 PQOb _/_u޺?fY}պj_oX7 2%BP{a=_NTԄ=߫Ta&}?tM8}zH=_wϻ=y{=wz;M&/_WL X+=2F7(\ZTe/%uq:[Z #;*?'V*t۞Fh>8%"5%צ hLt>f4Ik҉Q\f. (n;n瘞S.=g1)%"r !/ MK2Rd ƽ16{Le <zlөyzv2y0ݩiR2=)H$%b;=6F j^͓GPY3>3ޙwRh[EREw 6Xq{.\5y3ϼgfSLI͸]y03W:zJ&J wz-#5B%m af0u0U43]Sz3߆Q~K|{qQs[rhp0E惷T\üYZ95Mn}OQi8.tr tiRϵz)\%]bie6C3ond< pΚi GAT;*m}r~\P^sI](}ZB&w@ys/Z4ܒ4\^܎cܤJpR|y4>np7J]RW]K,IMKqW{T3|m kF/- +&_?w3T)ksTvAAXgz5vMpuZ$ŸNP; 익YmPMgq.YV-y]P!7MDƊozVͨA. ǘ*0H -jS=L/1Rߝ2kPssYtTݔF.7%u/hz)j@K%2c7U,UxXGty3-)֑P>c\<}&Z`u1p%!:(OC2]GUxi~yNzi<jR6M4E:NJ9WGA;e{sYTP*]c=Sw8}\>?rnn7Y~}%Ƞ[m7p}(+Pg vX xa)󦔯s#hb 27H|LֽEjn~&gٴd 4c&*vDӤ:ȩڴvȾ{7T RjtS9۝v{ݩh &/vtkke A?Jq MOwpLÑ\߾>^//ENI+/+ْl߿tQPIx7܀X#525 n^h2kXp٨ kUyMrosT٢(1 ׌'jh'7K'hO]h4IMj"s̖qL:qxLr#%N\),?)r=Lb.lROS~]œaYz[Qnk2AEʤqƅsl8?IrqN@ǾkٍCK&,ƥ*5%.\Y[o~s!U9(uZ_ֵ]:m/(O]`OV4„<Cy8:mb@a %5&mM*Ў5k^di&ZQHM$׀VH} ӻs}ʛݐ?:MeG#FO=L.-P̴y׷ ؗѭt˧C{Ϻ ^jp=Eqyjg8u%3{MoVuhv_JY噂0ԧeӄB'n7n,9 ̩wќR.7Ghm;UPܞ)s /'$צE#I.M-ifϔ6܈fGn>-qMcIc;m% |j\7=Mަo 3ӣQܤR, &mmzVdJ*GN~0 ^OF gJ8 Ifpnf73t+@O4l(\> 3C)C0 pEuFPbh53BUk}wU[`S؅HPjܧ/XJGcEcWatf9rTuP-:AKIa<+rEKAMKF)ʸB4i;7&!9q]*n}vZ/iv4, >!"B˛.,Ijz39߰aǏCdEqLߛoݥ}Sw׃HIc|3r pk=sIWG?2p mNǸvYMkaxʋh.W.\*r4(j2 jͻ2POe[ r2xGLZƜ" ezD=>rMszs:Jn%itC152(H=\]w-̦o*/)2x)s[>a4 gJ\MqYVCdiQWߔ = w=2]"t>2Ǐp8?u\e @v׺:r\vI<6QI7dg`RRű]ǐ$w"?[^]U.VLͤň'ES wܭN*|/)|tG\HɅstCZS,!RZdpx[0 G^/ʋIO^`(/jA\jTgM|HuPRT^Lr5t6"qpx2;nIeY H5>4$II#^LΗiovsXyjK:ϔp˝1p{8=Cr+f_A9C\ʽӌ_J+0N3o>1Kmrॊ G1Z*5%Yfb;v gF8gpr^q\)-aO -结Ig:C˾)F. 硑 ڗQJ,q)gՠE)Mt((衽Fb0{@C 5R<RRڳ(wN S8yTV`N \Tk&YET-v P;7B+MZ[yB_sʜS:Pr&N(nwPq81;}mpz)"脮r\x.- 78<]qۮvG2LI;h'>'@vNM{\P:wum'-`S&H)?wۊx3Vf$.ՏAI+#ᨃL QtMS@㳯3 R kG3L#|KV-Wwn#0֔c{2DC;⍇EB#eROҍTSԗn$ٗw \>D3Bq$y r> 7 % ˲\ 4?@jߣY@ovp*ZBւ r-ւP^z]k <ZbLebܭX4&KHJP4`C4i:])AMtR 4C;6.% T%eA#"{G|k.ADsN:*A.ȢjN?> ꎡi5r8M[n>@Sl~L0Qc|4FrW"Ge^_]W׎-XԀA +Hq,mcTj:*V{C F.d_}qtMa%xf Pqt٪ki܆?pzU(s~ahJ)6wr*uO& AzSmbz2s(J8& IMO˳|bBgɭSch9e>Rc+(yHy|\v@̀i||jyw||wv- ȱ1a2>w`b4^9h23 ː ,,CxFYR< P^(x{mx8MF, r.BTՏ?'(Kc7/M/V1jx]H0-d_MF|S*'f9Z"Fo%C@iJـD GS,MEH|+\)KuZ-y|:N/^K}t)5t n&p,]X ۥP<^p a\>j}^^$V-8 W?Ffܮk_hGF8rhtƠgRdHMϤ7bqsPBNOЎ)YjhiK/KRCѭ PaB֐1T0lkְ؂k a 65lkְ!aW_ v2@Q5l(0OV~VܜV Fb\h?b kh"91{5bjՈ٫cW#ƮFL\aV#FT*Jki iV>bj8ՈqT#ƩFS1N5bjըooQv' 55/c`7:RpZ)X<^T0`y({SC`˅[C?gt Ҹ9pLE<Z+<:*IӸgz[MgId>J|Ӛr7enYBMNmE<rF=膞nu)O :fa𙳦ǰǰGkba>(`^WKK9~zSj}V:.U> Kd AGQs%# WNLj9*(, |rJp+D壈W@)7 )s4!#!#!#!_YB@'t9_'.||^ TQzQ9KcDcl.:8~ըd>e~x_J/G.8YkA[:G[Q < \h΁0(YXLGWa\pUFC&Ϧ!aQ~mg1@7n1hg 6[1RɖZj|]|6&WkL~KDPQ Wj?qyu%OhZZb)L%!2~kn(sZϬH_kq>Mr'%_m\IgdwMavk"4ʗd$/c@+mf/V,˭K++rRWPWPWPڰP`jlJ_J_J_VC_VC_VC_VC Se eeeeEū͗˧; )Ҫ˺˺Ja„$d^ | ʮM.<, L S[T kUcxCCT1i'9!g#$I"nM3KC)bs#ns]ģp"xڀ 5 sM}[@v @kSYip+yЂ,2Jmt,GƓ˔%de$>;(֦ N!O"6 DlZo r6]2_VVM[j9T0.COZ˴ٷYM(TxbnP SLɷ'ɸ h8_.-hj5yPJ0-6-Y w Кޘ!P p}GxzK@5y1jbqShfp (G2@]!BqKz]L&l^<aI|~)Nc>nv kINl؋8$3j7E]Xܪ}R |uu PMr|T^4WpΏ׊+ThOZH4n:m m,}#>覔>rj^ZkdAi8GMAq92k zBAܞS>1dh 28A_ʆ"0 |n6c1Imm)IJC%ҘdxL2<&R19+xr9.'Ã2 L5J)#f >=UУ" A3nۗR'Δ]WF+PqbLjP5=Rzn\m6##HhbQyL4<gLBӾ.i42v;4Mq=Ow_MAn+]y%tufz52Va:3'SQNlg زSa\e 9u -Cxg,meRfʴ ɴ I\uџSnׅCtVDa_;\`ȅ%3'37, |O_1|2|2RII4)-KRj(s \:;0!ӸoPa9TZ:MP<;08A}JL{/k)sg@׫~F k}絾}uSRJ.:P T1qsshJ~{z@q JYh?d eI&yxtlޢ0?v_Kwpt^8CEn^G*f K FF haz9]P**]rrJ/g(dQJn,b!]ӳ^'c2P➔@+@AMg||Äʊ&Y&5 E=+@n`۩7ҝxtM)3S&+k&4>NJc N.mokf_7NfLEQye9(Aߗ NK Gk)ѯL\NS]Yp/ޮimH&'Ǿza|xMQ:ŵy}sC/ی[8!w8K*܍~nxkwwL nn hPJZQh0e(-\">E^;yE+/v @+`uEk0Z}-e#Lk3fс2-jϕjŒku3@IYy\c4 Wwy>-u36&[g)N3fX=m}zV`\T,֧إ)*g}zaO/,I,*G׫XBm>ӵ03իt,x_EB#k)6,+ 4GJ-țAd(FnƟ8Y_@ KM/հ[?KXM iy5ފ L KMA^\-C\@69Ν? \NZ9[-ނv9kT3B-FdͩgA ٢Ey)v5/}vBGײk5]InJڦk ԦiY&7QW"*ɾ+qh[~ڀAiw( l5F+ovzX]GM y+٤ٲIeft߅_ẓ](y Kʊ V"5FR*iq[mV ō 0 Z7̐Z:֐gCG ]ZC~e!-/1A u #uFְ%趐}yAPCe)RdY̐dFkXtVȩBי$&aV[[Vw/^-۽Z8zJ0 w/mc-Z(=鱱UF>pcycZVƲ,H 9bNʾ r8Ċ\ŦX?VpAcpOmVZimjO|''''2>7u"=ӵ[_tUf퉬-Z1z&*Z;Y1b ~,^k[aw^4\͙yZDXF% }:].V~C.ѹWyB؅%傂s-[|%۟/<`c1lۯ7E~{๨zݷwItVjiW=M[;o{5z{O{w;o7N6[{]6yWos~W??M8ɂ(hnX\GVJL3nwyEjea+T Z )]5:~y^j \?syŝ,QгD4 .!hf<ɂ51{h:|y\zuc#i‚4;N{Dho3Fpܞ3C-=k ^=p.I ;_Rit r*+w 9fOF ǻ'H=q#F.ENj^r{nH 9Nbt\r/׍r {R閕N\-/:[N:!Lr+ֱNxp"iscW ]mp"GLEN(@pKt83)N 0(Ϡ0$-X.wpw׊y/(X T |WA@׳Au˼{cC7靄sݴW7^MZ3|iz&_V%j>6;4bKeܶXf n۶m쯠w[yl+ ã KCa /;A똎}ye A@LϾ=1Ht#1x@9e Aqhhǘ  ˷qcj22Dvl{P>_|܇n9xޓ4Cu?A;yx{CnغZ`O} (8V®) 1fp9E'{=u.K\F U -XvYv9Zp]/Z%=u[@3nP| 3Ä@r3mkK&=h$TvoX(Lnszڈ л}?hϐfsYDTh -.a Ƕ@yhU7w}ϟoj~W/M΂bl^}C܏v^HrK܃?r8nF:H_Z:{l/C ajPSLYNSW(G$UҮ0 4Ckxj<rpW39_ ZtS3I65jc&܌U~ϓ.Wq'h'Z=8R;I鹈 Z&7^z0]f= ˶'}7S)fYu)|;h@q.wZ'P:N"eq;Γ17 죗{SFŋ]+8>ƶV=~ҡA΂GP6W,<3i7keo\6MCpz=;i"i-ӽl}rt<HmSs+t.*lLV>꧇n'NʼBb1@"$1N:P>,g*\ `8;`;g WCwd|b:=@'MQбhN(2di)62;XPw|9$_Y-Ks%;u@1x 4i9 Y3$c*6N G i0ө^ɜ~uղ;l6uY5r:rb ƓECC=$IY״ÿ(jqAhAhA,\tX9o/à44Y:tf~f^5p,S*eg+Aa*pi R\ ֧t3}'ndɚY>ڡ4 7OVOVAnwAᦫ{`gn-Y::=pkiF##ZrMddd],;G|\?Y?X׿+ ##g/_Y(Ł KΖta~̍}9 /&*A5^RpU5ٺL*3@Rj0gʹv1R^%b_SɃr WPAlm"}̀I}yC]iJ/[xlt]EW$t }Է:Pir ^'wF:mϔTx7Q,!4־ ~8QΑx!9|hPeM^4UR{K0@cfN7=N0Ԃ8{'wS @j'7*iy11\0@SB= si";㔗WbNnrsyN`Dv:QZpC]-=W7,p}u .J X(o{|uq<s)pa9U@MTd\ΦU#pBrIdդÓbiȾtҥK~0U7+ _?99bf,Q}2oRjYC u;VnWf+vlv%}wĥܳtrh:MxrrnO=+UܳZlhŗVPNnf: __,?ܲi&%_  PpJ5J;NNa3`,p)S*0@űJ^ \$dpg Խ;=AIeG4:N%[aVEy}hmkE 7C7|; nNZ _8Z_nm\E`ʋXUzƃum -FAt'pT </hGR<%. KHÿ"@ ܖKA>S0rl`F#9= Amam&ޘMre :;*@ )_ "oҟAmD\"o Υ/%[[Frh H^(iS͂ͺl΂W.fPt(p0nP:?Yq:j..OATx45YI-Nk |E&{^%ȕ\qn5 Kg_ڰ$P|gMev+%9=ڰݦxIMwv ڵf6K3MNEV/A]AnSpIePreN64*`aw\`Ki iN v*fM gY5Niw+6ss ΋@n+q^tp<:!DA1n8E/q^tko,vw@K14)4;ܾ:a}[FJN|5Akwɕ; M16wa8RȂX\}(7? ToS8qs_^KV7(soόA5 Fhj,mAg:-1WNȩK[nZU蹚%X;wtޭ*} 7Bi}lsL.);/6y.|*Nݥj%םOXi^:Pi/NTK jcV;Ϝ۫+w$K)E)sg)LkָRijgLϞVru߫ҶYjRl{͐S3PnK\g@%3/A%934eiԸ-/,?3uf nteΙLY>@[2uZn̽u `M?[& [WVVM^^b,JV ¼ߕ$-_IƑ@[ߒ{hk0]4Ņ@ǥ!\Tx%2w$Kǂ[[xtU:"җ5ǝ?l+w j{Rj_Sᷯ)pѹ!XJy{GW2yQuqPyyP,} sof 5arp TK@F7MǥF9T{s-qGF-997.!9_龹_~! 9.5A#nKt@wjۇ@ )iQ }pr.kRrqx>y4MC~gAqqH 9 S715ZZ^w^w^w^w^w^w>^DWɕ0Z |ZRYRYHY>Y4Y4Y*Y*Y YYY YYYYYYYYYYYYYYYYYYYYYYYYYY{Y~?8xhqQՂ0܆+hvaynOާ 8|2XpURj)ߗQb =mGmOHú[AORjڈ97'xC->}3:Yt%9ePژ&'A3BNeu]sʠnߝsv>y0}OCe%p > K T z`-@ d+eB L7] rXRpzM4:2rdD5xy @_dڞi:=@8]-Dk`JvJi8>@n(6E_֮r촀e%XvqR48VF/2%/@. eqZa0.ů˖@^ &/'T`3cr~L7"q]ڟtډ۵zq ꁫMypVK[4XIdɶ18̈́ۡ?ArIK SċYs WzxM_) R¥{q 9/-o!!~P&/LSy]PUvz\r\Yzy+v$wޞ7ޔǂ_]:jof+e+ 3yz% (#g{ M*+d$KbBՠuz etTwcj'j Nw8<k[/[x/[xT%!t!VVɩp V1`Lrˢ`!!k^)Y ]gt< 2>_Up /fJBh`kxʔ2:A(8vqi&相o*Z.{myb-~_y$i׹"ؒu=f,RJzw*.O"t'9HYk2߼!E.etԻi8=CMOk;R"5Bƍٺ#n rSiD\֢SjҢEZ;CFrz vmRB3s8}I-=l.p8nXյ 2]L8-=lwa1.OKC @û4P I  W6c[9k}SyY/ϦE\]ṾyA߉ /lPWZ׫o([*XXPtM]Sw\ H۴G1ذGJ93v1p+nPr$ Է9r ^ vl"-v ]KR^X,\(\:Av-J@;$6m-: GKӼhbp *;Yav-EGe첺 n R,-\j&zەRqMn99>H 7TReGA?r|nOiLryQkNyLZ_m䞰{?kGs5r]Yu-3ٓW\֖õkq; 4ڭ9TV9a,)2Lw&;S7q5):OкRvLqjb3ݙLlw&0sοǟBcA[:NCQޡp`]:[םܓ}JAEj{._-հV*Tq7Gn$Jj5̿_ Kmeǹ_z=_KYr z=m%q?" J%tD<+R"ЌͬfVp3+F)N4LJM9͜fp3g3n 7s ؾ}5{=nf7+SgW>xm[G\/yb!գ;y\KJ;#eVȥ\eV[iݱ̢v ]bA[ נX͍ӹaYDp| nt:&FacU)"^W m4(5%y6T#Ba8 Dh`a|V3lו .A g!6@՞H˞h87\6"iΔer8Kvszՠ]jk7%M8I J{\*shߥz7CW1qvn>\sZlcKٷɥ%6Alȏ'kEķp/i[c '!`8pQdН`ty{UpSMkˋk % 鼒Mf8QYbӡM YN#v,av֜rY Iz$y;)Hɮ#Qp륕ZeߓsͯE#Qrn7'BЋS9ne'҈K@뜤p=izp&ҹnIryt;4*C7{ޠ(FАi`) s ۇ`e+Δ* Gוg.Ϲ jx=P*rv J7gv*< ej#n oq{4B %q>qц!->)<=_$w)p4Fr[^Q->f@ӽHQ_c[Znf`7C28(p`fPCLp/yq} t 5clqM/~}p\lK!7 9-S6@zȧ,vsNY mquˇfqU-Q$U9E@^\+Β2_4S幂.r\kKrmi;hL\#3bW]#啷9ܘNO%= (Kz(e:Ձۢu2ݔrGպhPZ2z 6Sw5\^o#];\u/2L89tA.XImx༛RTu ku&%]VaRiRI4g7\663mf:'۲GZv;:4kC wޝh47қwף,ȒA]Ӻ]_-^\5zK9;MY,s9X'ӒixZr<-9ִxZrx%`(]ӒixZr<-9OK?5ՖuI CsL3-O@N& ' -IMSw~В4]zMTN&*GWV,~OY@QvJ%qrܓRka{Bs29i{Rp\A%is29Lm.5ײe<9МLcN1Pb\tƦ=-O8R3IB h;qr5OiJP`ps =UnE:ݔT Hru!W5kV{ms/^V/{.֤£`X֡#JF GΙ﵂K\Lwʋ*zSRéZASu`0.!7 T?վ/d1BI݅j|55miQWб ײMjI-nmULzs%Qm@'roۭvʼS7?)J 7y;'E"|R>$9q9*` 7RH%s ~A㻤G~vM.KI[IN9s[Rw丰Z7бN[Fo~_jy~ b9Mg ɂAY8S%ZP_ uwœ91[9+xrєԁq^ͻO KL=ȷ;" Om&%}Rrb>)yhbfы 8EuhFr韛BSиgrͩT]/th~;Tfztgd -rݿLӂ%!y|w#QS8(q#y^pE:FwT<؆Ŀ}LO̊tU]^aXCW,ϞZp&3<?E {%= ^¬XIj'/ﵻhrUq-MhE<5 iuHˇ) 'c}Nzu{"m3Đ}ۦfO͌˴ K14?inj7͹?r6}5zjrs | ,y+#xmq5hw9sӀke;\j퐜O+s @Re;W;n۲qs}[>}'9%˷Vv.`Gڸ.X bp_ݷ X那=R AWƻ ^3(7* ]ʳ\rnTv,Kに2s`*tP-byp{Dga#ntAn6uA.O irCh8l%kecX;ȭ]t-5@IEokme]!wHM@-f'@c}e%=hv~Q٤?<<<<<<<4& Y9&.|A,lڲP+xJGة`w7 ;wj*STPTOɻCPT!U8=3]TCnyc[)6LI0v.͒sCNKloc}uXD-PGA.o" v GKZc J9qщ~I::Rp*m{LCՙ =%s"$;Yh) e捋i\#v-Z(im#ET\g${XgX/}[ΝKY]<k:0Sp$/M@}/^wHOh.Ky*/y)kT y;{$H=S?hP|]iěxozMO>['ɦ"7wb'n;x{'Њ^ zm-$ar=oM> J]M4 8Ml~UQ[>`u JglŢxn` `^s\0ͷz<%}iݠfP7_4L=,}uq8ͨAM lޏht۳?r=hZicI&HwR7g;) - h9ui/}n#^8Prx6&r=4`k =SjY#46,I$wew|}SWͺP# :Y`+gmM%%e2pwh 1JeS\N_*VДu:<0}P7/"i4~H6SGd5..L(ٍ @w:J:N/Ѝ[J;)z*ί Él ҂xDP,[1傧0pYpP\9VAV@W%U,LԿP0]g\'66\:]Brz3e\7!f ZW[cpt,㎢K.ff6@۽kr :qoO\W.V(g6@';흁K:Hɍ6f<0agQ1<[_W /Vw+t3'~ r%6yUق+ @Y|TQ41U Ԫ wSA Y+;kJD{N&I;-]Eۅobu&WnZ!;I/r q]@)˒,݁$@+nNSԻiOw$@vɃ3)%#wgw4FqiYb=CŐ悫z/!9Ïm8Aez(gaY\prS:z:᧣6]TB?#Oȓ 䔖HϾ%9ƴ8+ϑ^?GzH0dR^?Gzi}j8>Kk)4W@;癒 *f[_h]̿0s- g #i#͠CR햐3t-wJS\ܐ[ns!hY~陚+=yۻe 43O\xM?A: r6qɍu#`o\RȅM>^K@.|-ia:en80 @U@UL%U T,P: *XJ ޵*U |e_}y<dI1x d9J*\VuXPblK_@T'U }Z.M >9nxlRaJsH3Y@0|R*IyH N,5)NeG/dZ^^5s{qk{q˷MWy6`ZR;^ovvvvvll""*ɀ,gbb"b]"bbbbbbbNNZnzXXXXXXmQ.,SbbbbbGVG3x~Zut+jJ)X管fGR4[?:]V<: tRLOVCN3] I_ϒ3gг/<ΤE<9r hPw8sRnpnz+CCGomrpA O< aig*S &eqӬU1φ\,"9E^mZ4,-%9!ДTKz/qK*sB4ct)MF@D#B=B]{y'&*p|>߿~*.}A*۵V WWfP,ğ/67fMlNSJ)`7ifj-njL.n-U۱MXRi &HuuUѳtՄ2_h֫au^VroS۬G3MiV|O' ڋsɆBF[a8qBM iTIpT%MN *gvRTIZ]ؖ[[[[CV G v #*~@{!MmJn4m8JCkh4MSs>2x\xY6J*TssrК6qN^@liSkh0m7S&8ִAvN8*ޭZ/徴2P0iA`AJp!:@ C9@@aѻt2PuWPV>TR ZezZC>өp:ZM Pޔs<_s14Cs3q#d_Af?(cy()ڼ~:=ԶQ][/k-, ժ%Σe G* ʂ[[y|sd(ϴ@]H@E@;\4pn뛦\Hǹm0&-Q^JBq;"rх+ np`3=H˳ KC⻓σZjׯ B|k54 =PelRh~tR^jk |^..`e..pZ)\OpAo ӽˁtvIиOb%`qy!#-G9xzr׍;GM㍮ JmQf!xO.p}um=ػK|@;6}W rͻj_M\[hS@ 4D,m}m}]Jˠ?Y)xJ:i7)eZFj@7n&Mpͥj<ϰ}BtxuCz"B%Ɗ[q@oC3hM׎Ԏ()ߔT5qAZӌBGcPs ڸ쏶ɍӳL4鶣]S7|c0,SbC:nD(JstʢʂjM^\p>M΀\kϴ:VA# 'J+c1ST Η#2uvYhKMnjF-ˬs mPʼ݂:HBY:N 9]BK+.ܮ08 Ng:k~ R΂0 *Tk5W…)ꎨmӽYS4]*m@nܬ)(lKQ[4mzL097m}F Ȳі (p#ٗ3qKչ}ⷍhg286ែ)/},w 2UΐܱS@ MWΰ8Pr{jDr*r:~&5>ڵC^<Xf80m5 +K,Lp~Ne,L^02O,EZ܉VhVL#()s]s~ Q@%MqwȾ\ =))ENZmEhぎ$-]!w kr?Ӊ?Ј{N^_2 ˠi6}t%g S%JgiYڶVtyv}!;N:pY9֋,rѲa-ȂU8~xJձOPZLB!/XqFv?M:$Gms*댐s[ -,/ɜ|ENbN''K2э<ш=''4ќ/R`[&b9yN"їKoL4'A3;ђtäSSzBMYSȴoUaIB.n9_~21H)KӠM(h˒SMnP,+8ʂvqǁRUew8C{2:~m\!6J&|XloR `$_\kt9p;e9nߣ,1i5Q!5sPW;/M7v}&_ZcPЕFUmk.N6ijtAI%in%tu0hT4Ho%\pZϹi;{Rsn:?7‹@鹷FJNVvBɹNbN87dio%}$e3?: r}뺵jz8i A)op2,SD.I[YMUnu\b~'c [^\Kh i;~DnDZ ٍ[LpUx~ctFy^N~M$P#TIMT쫑87z5T#ަ/GGvN>$(nAI@좍WwWod*`m$6ݍq,&W.^z.(JY ' ֔LfӬrEYA}\vf:wqϤh'@Oœilu5d6i4?ڍ#8kt:pm6 J m:sOv(_/ʮ=v=k[2VЕޮyaS`=]‚0 @׮൭k[&B-z2(u^E՞APB, c.n|XFNY/ELrRY=}Iå;qyc$H"%M"hR6r k{wphwoL%=롉&K=&Do> Q\7DI#̿#37DA QS٩vKw}b~Zl׈AKm!KmwR.L!m|]9e:/^B^pA삭X< w (>CàLiլd-#/ڀ%^G䠶L)a!@Z&w^reA4\FSm_ C@3hho/r#䔗A]Ns{,́C6^j"SڜɪȥQMS ]tH&KCLz H@nZ~DβMJ8~k#|KՔ|v@k ))zKz 5}TbQi`*0*.A)ob;m[oQ,vqyxwHQ-xg> 5-ᯙzv H*.9dVh7Icsjפh; BPzNn06;o(Cl.+l "״_p%=.^|Y /禭ûyB~ gj|Qbza*=qp\}Q1xЫpn/X*>so#wյ}4iMӶĨuw^lGA;n)}Ơ;L+<4۶s k=^ۡEs-۵tHBh>@GA/n_]ۇAZFOweBr#G{xN;?k_ctfV`  yfS`,p,`Ŭ W@Lv:`^UP))q\Y.(xmZ(;Cy-ZܚS գx84L @zt^8vTFOft-u^-zvsd њד1J9d4Tj,<ɪQAS:?Y5*rNQdUitFy" Z-dp'CN@31"hzTZM.Ziт#h8Mݴ5vAmHHiOuOgJ"ˌ nnx "NٗHNo%_Mc JY~Oq7ߧSdx6,~Ul8vsݥ r}:.Yp ..st|OIл@n7=NדRufW0MeB(0O=6 e$D{ɦknu fOXK%Z?gKǦ6òiPn!K&MhؔҐU#~VD`O1~mp$VgGNB Gpw0<\aAszaW/u\r}nqx(4?ML+Nb̗G8i.w1kp7INW:Rk{TxrJHHr)Hr ($IV3?ߝ?`ra8y0yXPn<;/^q$PI($?_Tu\ILfO߬'ya_ GpI8%s} KnWK#o\'yp[+yt$d7jx0MNȦWy  zlre-zUDzDM-~ALPAB86ϫ~yg!н`W^_mf܃rU&UBp P{(;7/@-FʷJWx`JQ. 1_x՞Vd۴Z~on,F$7xZS- f,wDH{8ݶpN^X5͐KFǦ^Vry~,uFL ezut|Ε:@3'td{Mk4XRm`I%48Ж481UXRm4 <-6Jc6Q ,1(eE8ڋK^\;DspYT~V}}^XCWG]೿J/.yZCtrv.Z52\CI$eKORׇu~*tT\1wMe\ΡHj6VǴnXzMmVLD)JY+V 'jh~ѕy, J 55=fX> [+EGLY4/vV;+x5EsJQI#TW'ҡ1"-Nfp=8sڃC}@, ;`O SٹG؃#ep=8F 85.&2F2$Zq8C!e86F!d#H/ȸ!c$зd1} CB!dMn!.eH0>$xq.C\'w-5C!eH>đ Ƈ!1} Ї!c( /^^`kKF(ϊdetEd}{a)IOÅr4OJ)RK*/J^ Θ(O)ϜcRKd4+LʴjF3גn=1mצVbtPN/An;B.y DLIJogEZ?4ODl5 yh W~W~e&)Y6sye0}h-.OɲgO_ȣDMY)yU>w|wyPJLsUACpή1{\<k}6I8ґq !.u\'NU="P8ґ\/],RNxzvtLyy9%G']^-HmczUʛ=1>*n%ˣ i^\ |leidenbase/tests/cpp_tests/edgelist.edg0000644000176200001440000200100414444624071017777 0ustar liggesusers0 0 0 29 0 51 0 197 0 220 0 251 0 298 0 301 0 338 0 358 0 367 0 398 0 436 0 442 0 467 0 545 0 560 0 597 0 663 0 676 0 699 0 715 0 721 0 771 0 821 0 824 0 828 0 866 0 872 0 892 0 895 0 973 0 983 0 996 0 1011 0 1083 0 1085 0 1124 0 1145 0 1305 0 1330 0 1371 0 1398 0 1400 1 1 1 100 1 260 1 265 1 417 1 421 1 616 1 656 1 672 1 712 1 717 1 806 1 850 1 855 1 856 1 945 1 1074 1 1117 1 1195 1 1226 1 1317 1 1337 1 1342 1 1387 1 1397 1 1473 2 2 2 25 2 93 2 95 2 97 2 111 2 117 2 126 2 153 2 194 2 197 2 227 2 231 2 241 2 247 2 282 2 296 2 353 2 362 2 384 2 450 2 454 2 463 2 499 2 516 2 554 2 564 2 654 2 662 2 670 2 675 2 796 2 801 2 825 2 838 2 970 2 982 2 1001 2 1002 2 1012 2 1036 2 1050 2 1056 2 1083 2 1105 2 1119 2 1122 2 1186 2 1194 2 1248 2 1256 2 1280 2 1282 2 1298 2 1302 2 1329 2 1354 2 1384 2 1385 2 1394 2 1396 2 1447 2 1478 3 3 3 8 3 19 3 64 3 183 3 407 3 473 3 499 3 527 3 599 3 614 3 628 3 660 3 709 3 816 3 849 3 951 3 1040 3 1132 3 1227 3 1419 3 1478 4 4 4 71 4 155 4 169 4 177 4 248 4 331 4 469 4 519 4 632 4 716 4 977 4 1053 4 1073 4 1357 4 1367 4 1423 4 1451 4 1480 5 5 5 12 5 13 5 52 5 65 5 85 5 165 5 202 5 218 5 230 5 234 5 240 5 291 5 365 5 434 5 441 5 528 5 569 5 603 5 609 5 630 5 642 5 730 5 742 5 883 5 939 5 1018 5 1028 5 1076 5 1129 5 1159 5 1265 5 1331 5 1369 5 1461 5 1472 6 6 6 42 6 45 6 48 6 108 6 124 6 172 6 256 6 268 6 303 6 374 6 382 6 392 6 406 6 413 6 438 6 512 6 521 6 575 6 576 6 635 6 686 6 718 6 722 6 757 6 782 6 786 6 810 6 961 6 968 6 1052 6 1081 6 1086 6 1160 6 1163 6 1201 6 1208 6 1228 6 1263 6 1349 6 1362 6 1363 6 1399 7 7 7 20 7 31 7 37 7 87 7 148 7 156 7 167 7 170 7 204 7 219 7 242 7 292 7 336 7 350 7 446 7 449 7 508 7 583 7 613 7 621 7 671 7 703 7 763 7 873 7 886 7 900 7 903 7 916 7 928 7 948 7 987 7 994 7 1029 7 1071 7 1106 7 1156 7 1161 7 1171 7 1184 7 1211 7 1224 7 1257 7 1268 7 1273 7 1289 7 1326 7 1402 7 1431 7 1444 7 1450 7 1458 7 1464 7 1490 8 3 8 8 8 19 8 64 8 97 8 119 8 183 8 330 8 407 8 427 8 473 8 499 8 599 8 614 8 628 8 660 8 709 8 816 8 849 8 951 8 1132 8 1227 8 1419 9 9 9 15 9 54 9 73 9 121 9 130 9 152 9 158 9 182 9 205 9 285 9 381 9 462 9 485 9 490 9 536 9 618 9 685 9 698 9 735 9 778 9 815 9 823 9 827 9 837 9 864 9 905 9 1044 9 1144 9 1153 9 1183 9 1221 9 1258 9 1343 9 1360 9 1389 9 1448 9 1452 9 1455 10 10 10 23 10 103 10 184 10 198 10 210 10 290 10 299 10 357 10 364 10 376 10 379 10 503 10 504 10 517 10 542 10 551 10 559 10 578 10 582 10 601 10 643 10 657 10 666 10 687 10 704 10 725 10 750 10 811 10 898 10 913 10 915 10 1008 10 1095 10 1168 10 1189 10 1240 10 1246 10 1297 10 1300 10 1338 10 1364 10 1374 10 1429 10 1433 10 1437 10 1457 10 1492 10 1495 11 11 11 41 11 48 11 94 11 179 11 225 11 276 11 310 11 339 11 347 11 459 11 496 11 509 11 545 11 664 11 713 11 787 11 790 11 821 11 828 11 845 11 912 11 996 11 1019 11 1033 11 1045 11 1063 11 1081 11 1170 11 1304 11 1335 11 1465 12 5 12 12 12 13 12 52 12 63 12 65 12 85 12 165 12 234 12 240 12 365 12 434 12 528 12 609 12 642 12 730 12 742 12 751 12 759 12 939 12 1026 12 1028 12 1129 12 1159 12 1265 12 1461 13 5 13 12 13 13 13 14 13 47 13 65 13 85 13 92 13 165 13 218 13 234 13 240 13 291 13 377 13 434 13 441 13 452 13 492 13 528 13 544 13 562 13 603 13 606 13 608 13 609 13 612 13 620 13 630 13 648 13 690 13 730 13 883 13 939 13 1018 13 1028 13 1076 13 1091 13 1129 13 1159 13 1225 13 1236 13 1265 13 1291 13 1369 13 1461 14 13 14 14 14 47 14 79 14 92 14 125 14 160 14 165 14 218 14 230 14 234 14 240 14 272 14 279 14 291 14 295 14 373 14 387 14 404 14 408 14 434 14 441 14 483 14 484 14 526 14 528 14 569 14 603 14 606 14 612 14 624 14 630 14 640 14 648 14 680 14 690 14 730 14 784 14 809 14 822 14 839 14 882 14 883 14 910 14 939 14 1018 14 1075 14 1076 14 1097 14 1098 14 1159 14 1196 14 1206 14 1229 14 1236 14 1281 14 1369 14 1373 14 1441 14 1476 14 1484 15 9 15 15 15 54 15 73 15 121 15 130 15 158 15 182 15 205 15 221 15 229 15 259 15 285 15 351 15 381 15 462 15 485 15 490 15 536 15 610 15 618 15 619 15 685 15 698 15 701 15 735 15 752 15 823 15 827 15 837 15 864 15 1044 15 1102 15 1118 15 1144 15 1153 15 1183 15 1221 15 1258 15 1340 15 1343 15 1360 15 1382 15 1389 15 1448 15 1452 15 1463 16 16 16 32 16 40 16 71 16 150 16 177 16 207 16 237 16 274 16 297 16 317 16 432 16 453 16 588 16 632 16 641 16 738 16 744 16 848 16 853 16 869 16 964 16 1041 16 1053 16 1073 16 1247 16 1252 16 1262 16 1274 16 1276 16 1296 16 1322 16 1328 16 1416 16 1480 17 17 17 129 17 162 17 174 17 175 17 192 17 255 17 283 17 304 17 322 17 394 17 395 17 399 17 440 17 531 17 575 17 590 17 634 17 681 17 695 17 786 17 881 17 887 17 969 17 991 17 992 17 1039 17 1092 17 1125 17 1140 17 1209 17 1213 17 1332 18 18 18 146 18 700 18 851 18 876 18 907 18 998 18 1004 18 1123 18 1177 18 1193 18 1306 18 1397 18 1473 19 3 19 8 19 19 19 64 19 73 19 97 19 152 19 197 19 259 19 288 19 330 19 338 19 407 19 473 19 499 19 587 19 599 19 614 19 628 19 655 19 734 19 765 19 778 19 802 19 816 19 849 19 866 19 871 19 892 19 951 19 1132 19 1214 19 1242 19 1343 19 1382 19 1419 19 1442 19 1455 19 1463 20 7 20 20 20 31 20 37 20 75 20 87 20 123 20 128 20 148 20 167 20 170 20 203 20 204 20 219 20 242 20 292 20 300 20 333 20 336 20 350 20 402 20 403 20 538 20 583 20 593 20 671 20 673 20 703 20 756 20 763 20 873 20 886 20 900 20 903 20 916 20 928 20 948 20 987 20 1029 20 1071 20 1100 20 1106 20 1112 20 1161 20 1166 20 1171 20 1184 20 1188 20 1203 20 1211 20 1224 20 1257 20 1268 20 1273 20 1326 20 1402 20 1404 20 1433 20 1458 20 1462 20 1464 20 1490 21 21 21 80 21 151 21 226 21 245 21 256 21 276 21 278 21 339 21 358 21 412 21 437 21 445 21 496 21 509 21 535 21 545 21 602 21 828 21 912 21 922 21 938 21 949 21 952 21 966 21 1033 21 1042 21 1045 21 1052 21 1070 21 1170 21 1181 21 1201 21 1208 21 1239 21 1288 22 22 22 107 22 156 22 266 22 378 22 396 22 403 22 449 22 507 22 530 22 543 22 558 22 570 22 583 22 604 22 607 22 613 22 621 22 669 22 739 22 764 22 791 22 854 22 862 22 873 22 900 22 903 22 920 22 935 22 948 22 994 22 1005 22 1037 22 1038 22 1090 22 1162 22 1176 22 1224 22 1287 22 1289 22 1324 22 1326 22 1386 22 1436 22 1444 22 1493 23 10 23 23 23 49 23 184 23 198 23 290 23 376 23 457 23 503 23 517 23 542 23 555 23 582 23 601 23 627 23 643 23 666 23 693 23 725 23 750 23 766 23 770 23 898 23 933 23 1008 23 1020 23 1101 23 1166 23 1185 23 1240 23 1246 23 1323 23 1344 23 1364 23 1429 23 1433 23 1457 23 1492 24 24 24 116 24 193 24 206 24 261 24 323 24 325 24 327 24 425 24 429 24 482 24 502 24 506 24 539 24 629 24 731 24 769 24 824 24 885 24 944 24 985 24 1039 24 1064 24 1178 24 1238 24 1244 24 1261 24 1336 24 1339 24 1400 24 1403 24 1468 25 2 25 25 25 69 25 111 25 163 25 181 25 220 25 303 25 362 25 450 25 454 25 512 25 523 25 692 25 780 25 794 25 894 25 970 25 982 25 1004 25 1012 25 1031 25 1052 25 1055 25 1083 25 1105 25 1186 25 1228 25 1239 25 1256 25 1260 25 1298 25 1363 25 1385 25 1396 25 1447 25 1488 26 26 26 82 26 86 26 193 26 200 26 222 26 233 26 267 26 312 26 327 26 332 26 355 26 405 26 436 26 465 26 475 26 482 26 563 26 579 26 598 26 626 26 658 26 755 26 758 26 863 26 895 26 934 26 959 26 1009 26 1024 26 1035 26 1054 26 1079 26 1113 26 1124 26 1135 26 1204 26 1266 26 1314 26 1321 26 1327 26 1330 26 1341 26 1467 26 1485 27 27 27 28 27 89 27 96 27 138 27 162 27 228 27 263 27 289 27 328 27 470 27 479 27 501 27 552 27 561 27 634 27 678 27 711 27 714 27 741 27 753 27 775 27 786 27 789 27 830 27 831 27 887 27 890 27 909 27 921 27 942 27 991 27 995 27 1072 27 1111 27 1120 27 1213 27 1286 27 1410 27 1414 27 1446 28 27 28 28 28 89 28 138 28 172 28 267 28 380 28 440 28 444 28 470 28 505 28 552 28 625 28 652 28 705 28 708 28 753 28 795 28 832 28 865 28 890 28 921 28 931 28 965 28 995 28 1059 28 1111 28 1120 28 1160 28 1316 28 1403 28 1414 28 1425 28 1446 29 0 29 29 29 41 29 45 29 51 29 339 29 367 29 380 29 459 29 467 29 545 29 594 29 676 29 683 29 699 29 715 29 726 29 729 29 787 29 821 29 845 29 872 29 895 29 931 29 973 29 1026 29 1086 29 1208 29 1239 29 1304 29 1362 29 1398 29 1399 29 1417 30 30 30 53 30 78 30 90 30 102 30 175 30 191 30 212 30 270 30 286 30 460 30 506 30 511 30 534 30 537 30 549 30 563 30 610 30 637 30 761 30 785 30 812 30 815 30 829 30 884 30 897 30 905 30 923 30 967 30 980 30 1003 30 1057 30 1065 30 1084 30 1137 30 1141 30 1204 30 1219 30 1249 30 1334 30 1336 30 1390 30 1418 30 1459 30 1481 31 7 31 20 31 31 31 123 31 148 31 167 31 170 31 178 31 242 31 292 31 333 31 336 31 402 31 457 31 593 31 607 31 622 31 673 31 703 31 736 31 763 31 900 31 916 31 928 31 997 31 1015 31 1071 31 1100 31 1106 31 1112 31 1161 31 1166 31 1171 31 1184 31 1211 31 1224 31 1257 31 1294 31 1326 31 1402 31 1404 31 1426 31 1433 31 1462 31 1464 31 1490 32 16 32 32 32 34 32 40 32 115 32 139 32 150 32 171 32 177 32 207 32 213 32 237 32 248 32 274 32 307 32 317 32 366 32 439 32 453 32 495 32 744 32 833 32 835 32 848 32 853 32 859 32 868 32 869 32 889 32 926 32 936 32 1041 32 1053 32 1061 32 1103 32 1110 32 1138 32 1237 32 1247 32 1262 32 1276 32 1296 32 1322 32 1347 32 1376 32 1381 32 1406 32 1482 33 33 33 50 33 61 33 110 33 141 33 155 33 169 33 299 33 341 33 342 33 364 33 379 33 447 33 458 33 493 33 504 33 514 33 586 33 749 33 773 33 843 33 904 33 913 33 941 33 943 33 956 33 1109 33 1189 33 1269 33 1312 33 1338 33 1345 33 1420 33 1421 33 1437 34 32 34 34 34 40 34 136 34 171 34 207 34 213 34 237 34 274 34 307 34 317 34 423 34 439 34 495 34 588 34 744 34 783 34 813 34 835 34 848 34 853 34 859 34 868 34 869 34 889 34 936 34 1041 34 1110 34 1138 34 1174 34 1237 34 1255 34 1262 34 1284 34 1296 34 1322 34 1347 34 1376 34 1422 35 35 35 140 35 172 35 188 35 199 35 284 35 313 35 321 35 363 35 374 35 382 35 406 35 411 35 498 35 540 35 577 35 594 35 695 35 718 35 741 35 772 35 781 35 782 35 790 35 852 35 918 35 929 35 961 35 963 35 1049 35 1094 35 1123 35 1158 35 1164 35 1223 35 1251 35 1292 36 36 36 55 36 56 36 101 36 164 36 202 36 218 36 230 36 291 36 391 36 524 36 547 36 569 36 608 36 620 36 667 36 730 36 867 36 870 36 906 36 1034 36 1091 36 1098 36 1225 36 1299 36 1331 36 1373 36 1476 37 7 37 20 37 37 37 49 37 75 37 87 37 128 37 167 37 170 37 184 37 198 37 203 37 204 37 219 37 242 37 290 37 350 37 360 37 376 37 402 37 418 37 443 37 503 37 551 37 555 37 559 37 573 37 574 37 583 37 593 37 622 37 627 37 639 37 657 37 671 37 673 37 703 37 725 37 756 37 766 37 770 37 800 37 805 37 836 37 886 37 916 37 928 37 933 37 987 37 1020 37 1029 37 1087 37 1088 37 1100 37 1101 37 1106 37 1107 37 1161 37 1166 37 1169 37 1171 37 1185 37 1203 37 1205 37 1211 37 1257 37 1268 37 1273 37 1311 37 1326 37 1388 37 1431 37 1433 37 1458 37 1460 37 1483 37 1490 38 38 38 53 38 58 38 137 38 174 38 192 38 212 38 216 38 261 38 262 38 322 38 428 38 431 38 464 38 506 38 534 38 549 38 561 38 637 38 720 38 792 38 808 38 874 38 923 38 980 38 1017 38 1046 38 1065 38 1084 38 1089 38 1209 38 1219 38 1234 38 1238 38 1249 38 1336 38 1351 38 1359 38 1418 39 39 39 77 39 104 39 109 39 112 39 168 39 208 39 215 39 258 39 280 39 302 39 346 39 409 39 410 39 500 39 633 39 724 39 861 39 891 39 954 39 976 39 989 39 1025 39 1114 39 1128 39 1134 39 1148 39 1207 39 1233 39 1301 39 1310 39 1319 39 1368 39 1405 39 1439 40 16 40 32 40 34 40 40 40 115 40 171 40 177 40 207 40 213 40 237 40 274 40 307 40 317 40 366 40 453 40 495 40 588 40 744 40 813 40 833 40 835 40 848 40 853 40 859 40 869 40 926 40 936 40 1041 40 1061 40 1103 40 1110 40 1138 40 1237 40 1245 40 1247 40 1262 40 1276 40 1296 40 1322 40 1347 40 1376 40 1381 40 1406 40 1482 41 11 41 29 41 41 41 81 41 94 41 99 41 151 41 199 41 245 41 278 41 284 41 339 41 374 41 380 41 382 41 406 41 430 41 459 41 501 41 510 41 513 41 594 41 686 41 713 41 781 41 782 41 787 41 790 41 828 41 912 41 929 41 949 41 965 41 1019 41 1033 41 1045 41 1048 41 1081 41 1094 41 1152 41 1164 41 1190 41 1223 41 1226 41 1251 41 1304 41 1335 41 1408 41 1417 41 1425 41 1445 41 1471 42 6 42 42 42 45 42 48 42 124 42 172 42 256 42 263 42 303 42 392 42 406 42 413 42 498 42 575 42 576 42 635 42 649 42 718 42 722 42 757 42 782 42 810 42 961 42 969 42 1039 42 1052 42 1155 42 1160 42 1163 42 1201 42 1208 42 1333 42 1349 42 1362 42 1363 42 1399 42 1499 43 43 43 46 43 60 43 77 43 104 43 118 43 154 43 176 43 280 43 287 43 309 43 369 43 385 43 456 43 500 43 532 43 541 43 557 43 565 43 651 43 724 43 747 43 779 43 861 43 878 43 891 43 902 43 927 43 957 43 976 43 1013 43 1128 43 1150 43 1182 43 1210 43 1243 43 1279 43 1295 43 1366 43 1380 43 1439 43 1489 44 44 44 57 44 72 44 76 44 135 44 144 44 147 44 149 44 224 44 344 44 370 44 375 44 388 44 397 44 491 44 733 44 799 44 860 44 893 44 993 44 1027 44 1136 44 1202 44 1235 44 1278 44 1358 44 1393 44 1456 45 6 45 29 45 42 45 45 45 108 45 124 45 268 45 303 45 321 45 380 45 392 45 413 45 438 45 470 45 505 45 521 45 540 45 594 45 635 45 676 45 686 45 689 45 722 45 810 45 921 45 931 45 950 45 968 45 1086 45 1152 45 1160 45 1164 45 1263 45 1304 45 1349 45 1399 45 1417 45 1487 46 43 46 46 46 104 46 109 46 112 46 118 46 176 46 258 46 309 46 369 46 385 46 500 46 532 46 541 46 557 46 565 46 724 46 747 46 779 46 927 46 957 46 1013 46 1025 46 1114 46 1128 46 1150 46 1182 46 1243 46 1270 46 1279 46 1366 46 1368 46 1380 46 1439 46 1489 47 13 47 14 47 47 47 63 47 92 47 125 47 160 47 218 47 223 47 230 47 234 47 240 47 272 47 279 47 291 47 295 47 305 47 371 47 377 47 404 47 408 47 434 47 441 47 452 47 478 47 483 47 603 47 612 47 624 47 630 47 648 47 680 47 690 47 743 47 784 47 809 47 814 47 822 47 839 47 882 47 883 47 1014 47 1018 47 1075 47 1076 47 1097 47 1142 47 1196 47 1206 47 1229 47 1277 47 1281 47 1369 47 1370 47 1407 47 1472 47 1484 47 1498 48 6 48 11 48 42 48 48 48 94 48 140 48 163 48 256 48 276 48 303 48 310 48 313 48 339 48 392 48 406 48 413 48 512 48 635 48 664 48 688 48 713 48 718 48 726 48 740 48 746 48 757 48 772 48 782 48 810 48 880 48 961 48 1033 48 1049 48 1052 48 1081 48 1163 48 1181 48 1201 48 1208 48 1239 48 1362 48 1363 48 1399 49 23 49 37 49 49 49 75 49 128 49 184 49 198 49 203 49 290 49 350 49 360 49 368 49 376 49 443 49 503 49 517 49 551 49 555 49 559 49 573 49 574 49 582 49 589 49 627 49 639 49 657 49 671 49 673 49 697 49 725 49 756 49 770 49 800 49 805 49 836 49 886 49 916 49 933 49 955 49 1020 49 1088 49 1101 49 1107 49 1166 49 1200 49 1203 49 1273 49 1364 49 1429 49 1433 49 1457 49 1460 49 1483 49 1492 50 33 50 50 50 68 50 75 50 141 50 294 50 299 50 300 50 314 50 333 50 357 50 364 50 368 50 379 50 433 50 504 50 514 50 538 50 571 50 578 50 671 50 697 50 704 50 836 50 913 50 916 50 930 50 1088 50 1188 50 1189 50 1203 50 1300 50 1312 50 1338 50 1364 50 1437 50 1460 50 1495 51 0 51 29 51 51 51 70 51 151 51 186 51 235 51 278 51 281 51 321 51 358 51 367 51 380 51 412 51 419 51 437 51 522 51 545 51 594 51 597 51 635 51 661 51 676 51 695 51 699 51 708 51 729 51 731 51 768 51 810 51 872 51 921 51 931 51 1007 51 1011 51 1052 51 1086 51 1208 51 1239 51 1261 51 1339 51 1362 51 1398 51 1399 51 1417 51 1468 51 1487 52 5 52 12 52 52 52 63 52 65 52 160 52 165 52 202 52 230 52 234 52 240 52 365 52 603 52 609 52 630 52 642 52 694 52 742 52 759 52 809 52 882 52 939 52 1026 52 1028 52 1075 52 1108 52 1265 52 1461 52 1472 53 30 53 38 53 53 53 78 53 82 53 86 53 90 53 102 53 130 53 191 53 211 53 212 53 262 53 270 53 308 53 332 53 348 53 405 53 428 53 431 53 451 53 460 53 506 53 511 53 533 53 534 53 537 53 549 53 563 53 579 53 580 53 610 53 626 53 631 53 637 53 658 53 685 53 702 53 752 53 761 53 812 53 829 53 846 53 863 53 884 53 901 53 923 53 1003 53 1024 53 1035 53 1046 53 1057 53 1065 53 1066 53 1084 53 1102 53 1131 53 1135 53 1137 53 1183 53 1219 53 1221 53 1249 53 1309 53 1334 53 1336 53 1340 53 1390 53 1418 53 1459 53 1475 53 1481 53 1494 54 9 54 15 54 54 54 121 54 130 54 152 54 158 54 182 54 205 54 221 54 229 54 262 54 285 54 312 54 381 54 462 54 485 54 490 54 536 54 599 54 610 54 618 54 619 54 685 54 698 54 701 54 735 54 752 54 815 54 823 54 827 54 837 54 864 54 905 54 1044 54 1066 54 1102 54 1144 54 1153 54 1183 54 1212 54 1221 54 1258 54 1340 54 1343 54 1360 54 1382 54 1389 54 1448 54 1452 54 1455 54 1463 54 1486 55 36 55 55 55 83 55 85 55 101 55 187 55 218 55 291 55 377 55 441 55 492 55 497 55 524 55 547 55 562 55 608 55 609 55 620 55 648 55 667 55 870 55 908 55 1091 55 1098 55 1180 55 1225 55 1291 55 1299 55 1373 55 1496 56 36 56 56 56 101 56 164 56 230 56 343 56 391 56 408 56 524 56 547 56 592 56 608 56 620 56 638 56 667 56 680 56 784 56 844 56 867 56 870 56 906 56 940 56 972 56 1034 56 1098 56 1179 56 1198 56 1299 56 1373 56 1496 57 44 57 57 57 76 57 144 57 149 57 232 57 344 57 370 57 375 57 388 57 397 57 424 57 455 57 491 57 591 57 733 57 799 57 860 57 893 57 990 57 993 57 1027 57 1136 57 1179 57 1202 57 1235 57 1278 57 1358 57 1393 57 1456 58 38 58 58 58 86 58 137 58 193 58 211 58 212 58 216 58 250 58 257 58 351 58 405 58 428 58 431 58 440 58 444 58 451 58 464 58 533 58 534 58 563 58 619 58 626 58 702 58 720 58 785 58 808 58 863 58 874 58 959 58 1024 58 1035 58 1046 58 1054 58 1135 58 1187 58 1219 58 1234 58 1238 58 1249 58 1283 58 1309 58 1334 58 1341 58 1390 58 1459 59 59 59 67 59 161 59 190 59 335 59 414 59 435 59 774 59 840 59 841 59 857 59 919 59 953 59 1021 59 1231 59 1320 59 1365 59 1409 59 1432 59 1443 59 1454 59 1477 59 1491 59 1497 60 43 60 60 60 77 60 112 60 118 60 154 60 208 60 280 60 287 60 369 60 385 60 410 60 456 60 541 60 565 60 633 60 724 60 747 60 779 60 861 60 878 60 891 60 902 60 927 60 957 60 976 60 1013 60 1025 60 1128 60 1148 60 1150 60 1210 60 1279 60 1295 60 1310 60 1439 60 1489 61 33 61 61 61 110 61 141 61 169 61 299 61 341 61 342 61 364 61 379 61 447 61 458 61 493 61 504 61 514 61 578 61 586 61 687 61 704 61 749 61 773 61 843 61 904 61 913 61 915 61 941 61 943 61 956 61 1109 61 1189 61 1269 61 1312 61 1338 61 1345 61 1420 61 1421 61 1437 62 62 62 104 62 105 62 209 62 254 62 346 62 426 62 489 62 532 62 572 62 659 62 710 62 723 62 728 62 737 62 818 62 826 62 899 62 917 62 1093 62 1104 62 1114 62 1115 62 1149 62 1207 62 1220 62 1270 62 1310 62 1350 62 1383 63 12 63 47 63 52 63 63 63 125 63 160 63 165 63 234 63 240 63 272 63 387 63 404 63 603 63 630 63 642 63 648 63 694 63 742 63 759 63 809 63 882 63 888 63 939 63 1026 63 1075 63 1108 63 1265 63 1461 63 1472 63 1476 64 3 64 8 64 19 64 64 64 97 64 183 64 407 64 473 64 499 64 527 64 599 64 614 64 628 64 660 64 709 64 765 64 802 64 816 64 849 64 892 64 951 64 1132 64 1227 64 1419 65 5 65 12 65 13 65 52 65 65 65 85 65 165 65 202 65 218 65 234 65 240 65 291 65 365 65 377 65 434 65 452 65 492 65 528 65 603 65 609 65 612 65 630 65 642 65 742 65 759 65 883 65 939 65 1026 65 1028 65 1076 65 1129 65 1159 65 1265 65 1291 65 1461 65 1472 66 66 66 96 66 131 66 137 66 174 66 206 66 211 66 216 66 250 66 261 66 263 66 322 66 328 66 349 66 356 66 392 66 394 66 405 66 444 66 464 66 479 66 486 66 502 66 539 66 576 66 580 66 625 66 678 66 720 66 767 66 792 66 830 66 879 66 887 66 942 66 944 66 985 66 1017 66 1047 66 1064 66 1072 66 1089 66 1165 66 1173 66 1213 66 1238 66 1244 66 1283 66 1316 66 1332 66 1341 66 1353 66 1372 67 59 67 67 67 161 67 190 67 335 67 414 67 435 67 774 67 840 67 857 67 1021 67 1231 67 1320 67 1365 67 1409 67 1432 67 1443 67 1454 67 1477 67 1491 67 1497 68 50 68 68 68 75 68 141 68 198 68 203 68 210 68 294 68 299 68 300 68 314 68 333 68 357 68 368 68 379 68 433 68 514 68 538 68 551 68 559 68 571 68 582 68 627 68 657 68 671 68 673 68 697 68 704 68 836 68 916 68 930 68 1029 68 1088 68 1100 68 1107 68 1189 68 1203 68 1300 68 1338 68 1364 68 1374 68 1460 68 1490 69 25 69 69 69 111 69 119 69 146 69 330 69 427 69 454 69 780 69 794 69 951 69 1133 69 1222 69 1256 69 1260 69 1298 69 1385 69 1396 69 1466 70 51 70 70 70 98 70 108 70 163 70 256 70 273 70 281 70 303 70 339 70 438 70 635 70 692 70 722 70 729 70 731 70 768 70 794 70 803 70 810 70 832 70 894 70 1011 70 1012 70 1031 70 1032 70 1033 70 1039 70 1052 70 1055 70 1086 70 1208 70 1228 70 1239 70 1263 70 1363 70 1399 70 1417 70 1466 70 1487 70 1488 71 4 71 16 71 71 71 177 71 248 71 274 71 297 71 331 71 390 71 423 71 432 71 469 71 519 71 632 71 706 71 738 71 964 71 977 71 1053 71 1073 71 1130 71 1188 71 1252 71 1274 71 1328 71 1357 71 1367 71 1416 71 1423 71 1451 71 1480 72 44 72 72 72 76 72 135 72 144 72 149 72 217 72 223 72 224 72 232 72 343 72 370 72 389 72 391 72 397 72 401 72 424 72 455 72 478 72 491 72 520 72 556 72 584 72 592 72 611 72 638 72 733 72 844 72 860 72 906 72 911 72 940 72 972 72 978 72 1034 72 1068 72 1078 72 1099 72 1136 72 1142 72 1179 72 1180 72 1198 72 1230 72 1235 72 1278 72 1358 72 1361 72 1393 72 1407 72 1441 73 9 73 15 73 19 73 73 73 121 73 130 73 152 73 205 73 259 73 270 73 285 73 338 73 490 73 549 73 560 73 599 73 618 73 655 73 698 73 701 73 734 73 752 73 761 73 778 73 802 73 815 73 871 73 892 73 905 73 967 73 983 73 1044 73 1124 73 1145 73 1153 73 1214 73 1221 73 1330 73 1343 73 1382 73 1400 73 1413 73 1448 73 1452 73 1455 74 74 74 84 74 95 74 113 74 132 74 201 74 227 74 231 74 239 74 241 74 271 74 293 74 306 74 315 74 324 74 420 74 461 74 488 74 515 74 525 74 554 74 564 74 659 74 668 74 798 74 804 74 818 74 858 74 971 74 975 74 1002 74 1116 74 1119 74 1122 74 1157 74 1192 74 1232 74 1248 74 1259 74 1272 74 1280 74 1285 74 1354 74 1391 74 1394 75 20 75 37 75 49 75 50 75 68 75 75 75 123 75 128 75 141 75 198 75 203 75 290 75 292 75 294 75 300 75 314 75 333 75 357 75 360 75 368 75 402 75 433 75 538 75 551 75 555 75 571 75 582 75 593 75 622 75 627 75 657 75 671 75 673 75 697 75 703 75 756 75 805 75 836 75 916 75 930 75 933 75 1020 75 1088 75 1101 75 1106 75 1107 75 1166 75 1203 75 1257 75 1300 75 1364 75 1433 75 1460 75 1490 76 44 76 57 76 72 76 76 76 135 76 144 76 149 76 189 76 232 76 305 76 370 76 375 76 388 76 397 76 401 76 424 76 455 76 591 76 611 76 684 76 733 76 814 76 860 76 893 76 940 76 978 76 990 76 993 76 1014 76 1136 76 1179 76 1216 76 1235 76 1278 76 1290 76 1358 76 1370 76 1393 77 39 77 43 77 60 77 77 77 104 77 109 77 112 77 154 77 208 77 280 77 346 77 385 77 410 77 456 77 500 77 541 77 633 77 724 77 747 77 779 77 861 77 878 77 891 77 902 77 957 77 976 77 1013 77 1025 77 1030 77 1128 77 1134 77 1148 77 1207 77 1210 77 1279 77 1301 77 1310 77 1380 77 1439 78 30 78 53 78 78 78 82 78 102 78 130 78 191 78 200 78 211 78 212 78 270 78 286 78 308 78 332 78 348 78 405 78 428 78 451 78 460 78 464 78 511 78 533 78 534 78 537 78 549 78 579 78 610 78 626 78 631 78 637 78 658 78 685 78 702 78 752 78 761 78 812 78 829 78 863 78 884 78 901 78 923 78 959 78 1003 78 1024 78 1035 78 1057 78 1065 78 1066 78 1084 78 1124 78 1131 78 1135 78 1183 78 1212 78 1221 78 1238 78 1249 78 1309 78 1327 78 1336 78 1340 78 1351 78 1390 78 1418 78 1459 78 1481 78 1494 79 14 79 79 79 125 79 189 79 279 79 295 79 373 79 404 79 408 79 483 79 484 79 491 79 520 79 526 79 556 79 567 79 600 79 606 79 624 79 638 79 640 79 684 79 690 79 743 79 784 79 807 79 822 79 839 79 844 79 875 79 910 79 911 79 1069 79 1075 79 1082 79 1097 79 1196 79 1206 79 1217 79 1229 79 1230 79 1236 79 1277 79 1355 79 1356 79 1375 79 1441 79 1484 80 21 80 80 80 114 80 179 80 181 80 225 80 226 80 235 80 245 80 251 80 276 80 278 80 318 80 339 80 358 80 412 80 419 80 430 80 437 80 467 80 496 80 509 80 535 80 653 80 664 80 665 80 699 80 768 80 825 80 912 80 949 80 952 80 966 80 1011 80 1022 80 1032 80 1045 80 1063 80 1170 80 1175 80 1288 80 1308 81 41 81 81 81 99 81 106 81 199 81 245 81 318 81 329 81 337 81 347 81 406 81 430 81 487 81 510 81 513 81 529 81 550 81 585 81 602 81 665 81 713 81 781 81 790 81 820 81 834 81 929 81 949 81 965 81 988 81 1000 81 1019 81 1022 81 1048 81 1070 81 1158 81 1190 81 1215 81 1223 81 1226 81 1241 81 1251 81 1408 81 1425 81 1445 81 1465 81 1471 82 26 82 53 82 78 82 82 82 90 82 102 82 191 82 193 82 200 82 211 82 233 82 244 82 308 82 332 82 405 82 428 82 451 82 465 82 511 82 533 82 537 82 549 82 563 82 579 82 610 82 623 82 626 82 658 82 702 82 752 82 761 82 812 82 863 82 884 82 901 82 934 82 959 82 1003 82 1024 82 1035 82 1066 82 1084 82 1102 82 1113 82 1118 82 1124 82 1135 82 1183 82 1212 82 1327 82 1340 82 1341 82 1378 82 1459 82 1467 82 1481 82 1494 83 55 83 83 83 187 83 217 83 223 83 224 83 305 83 371 83 377 83 441 83 452 83 492 83 497 83 524 83 544 83 547 83 562 83 584 83 592 83 612 83 648 83 680 83 908 83 972 83 1034 83 1068 83 1078 83 1091 83 1098 83 1099 83 1142 83 1180 83 1225 83 1299 83 1313 83 1356 83 1361 83 1370 83 1373 83 1474 83 1496 84 74 84 84 84 88 84 120 84 173 84 194 84 209 84 239 84 271 84 293 84 311 84 315 84 334 84 361 84 420 84 477 84 488 84 515 84 554 84 564 84 668 84 675 84 677 84 719 84 788 84 818 84 858 84 1023 84 1058 84 1062 84 1157 84 1192 84 1248 84 1293 84 1303 84 1307 84 1329 84 1354 84 1394 84 1424 84 1435 84 1469 85 5 85 12 85 13 85 55 85 65 85 85 85 218 85 234 85 291 85 365 85 492 85 562 85 603 85 608 85 609 85 620 85 642 85 730 85 742 85 870 85 939 85 1028 85 1091 85 1129 85 1159 85 1265 85 1291 85 1369 86 26 86 53 86 58 86 86 86 102 86 175 86 191 86 193 86 211 86 233 86 250 86 277 86 332 86 349 86 405 86 431 86 440 86 444 86 451 86 534 86 563 86 579 86 625 86 626 86 658 86 720 86 846 86 863 86 901 86 959 86 1024 86 1035 86 1046 86 1054 86 1131 86 1135 86 1137 86 1165 86 1283 86 1309 86 1341 86 1390 86 1475 86 1494 87 7 87 20 87 37 87 87 87 148 87 203 87 204 87 242 87 292 87 294 87 300 87 336 87 403 87 446 87 449 87 530 87 583 87 671 87 703 87 873 87 903 87 928 87 948 87 953 87 987 87 1029 87 1100 87 1106 87 1169 87 1171 87 1184 87 1188 87 1211 87 1224 87 1273 87 1326 87 1404 87 1450 87 1458 87 1460 87 1464 87 1490 88 84 88 88 88 173 88 209 88 306 88 334 88 420 88 461 88 472 88 477 88 488 88 489 88 553 88 572 88 581 88 659 88 668 88 723 88 728 88 737 88 748 88 788 88 798 88 818 88 917 88 1062 88 1080 88 1093 88 1096 88 1104 88 1115 88 1143 88 1192 88 1293 88 1469 89 27 89 28 89 89 89 127 89 138 89 267 89 268 89 392 89 444 89 470 89 501 89 505 89 540 89 678 89 686 89 705 89 753 89 786 89 789 89 795 89 830 89 831 89 865 89 896 89 921 89 931 89 950 89 965 89 986 89 995 89 1009 89 1111 89 1120 89 1160 89 1314 89 1321 89 1349 89 1410 89 1414 89 1425 89 1446 89 1449 90 30 90 53 90 82 90 90 90 102 90 191 90 193 90 212 90 262 90 270 90 285 90 323 90 327 90 451 90 506 90 511 90 533 90 536 90 537 90 563 90 610 90 618 90 658 90 701 90 734 90 785 90 808 90 812 90 815 90 829 90 884 90 905 90 934 90 967 90 1003 90 1035 90 1057 90 1118 90 1124 90 1135 90 1141 90 1187 90 1219 90 1334 90 1390 90 1459 90 1481 90 1486 91 91 91 143 91 219 91 326 91 416 91 418 91 446 91 508 91 604 91 613 91 617 91 636 91 639 91 644 91 669 91 732 91 739 91 854 91 933 91 958 91 962 91 997 91 1010 91 1146 91 1151 91 1154 91 1167 91 1205 91 1268 91 1431 91 1479 92 13 92 14 92 47 92 92 92 125 92 160 92 218 92 230 92 240 92 272 92 291 92 373 92 387 92 434 92 441 92 452 92 483 92 484 92 528 92 569 92 600 92 603 92 606 92 612 92 620 92 624 92 630 92 640 92 690 92 694 92 730 92 743 92 809 92 867 92 882 92 883 92 910 92 911 92 999 92 1018 92 1075 92 1076 92 1082 92 1108 92 1159 92 1196 92 1206 92 1236 92 1277 92 1331 92 1369 92 1461 92 1472 92 1476 92 1484 93 2 93 93 93 95 93 111 93 126 93 153 93 194 93 227 93 231 93 239 93 241 93 247 93 271 93 282 93 296 93 311 93 315 93 362 93 450 93 454 93 463 93 481 93 515 93 516 93 564 93 654 93 670 93 796 93 801 93 838 93 858 93 970 93 975 93 982 93 1001 93 1002 93 1023 93 1036 93 1050 93 1083 93 1116 93 1119 93 1122 93 1157 93 1194 93 1248 93 1253 93 1256 93 1280 93 1282 93 1298 93 1354 93 1384 93 1394 93 1395 93 1396 93 1435 93 1478 94 11 94 41 94 48 94 94 94 179 94 226 94 245 94 246 94 276 94 310 94 321 94 339 94 382 94 406 94 459 94 467 94 496 94 501 94 653 94 664 94 679 94 713 94 772 94 782 94 787 94 790 94 810 94 852 94 880 94 912 94 929 94 946 94 952 94 961 94 1033 94 1045 94 1081 94 1158 94 1163 94 1170 94 1181 94 1201 94 1208 94 1239 94 1241 94 1251 94 1288 94 1335 94 1362 94 1363 94 1445 95 2 95 74 95 93 95 95 95 111 95 126 95 132 95 194 95 201 95 227 95 231 95 239 95 241 95 247 95 271 95 275 95 282 95 296 95 306 95 311 95 315 95 362 95 450 95 463 95 481 95 515 95 516 95 554 95 564 95 654 95 662 95 670 95 796 95 801 95 838 95 858 95 970 95 971 95 975 95 1001 95 1002 95 1023 95 1036 95 1050 95 1058 95 1116 95 1119 95 1122 95 1157 95 1194 95 1232 95 1248 95 1280 95 1282 95 1354 95 1384 95 1394 95 1396 95 1478 96 27 96 66 96 96 96 131 96 162 96 243 96 261 96 263 96 322 96 328 96 354 96 356 96 394 96 479 96 486 96 501 96 561 96 634 96 649 96 711 96 714 96 726 96 746 96 786 96 789 96 792 96 830 96 879 96 881 96 887 96 909 96 942 96 1017 96 1047 96 1072 96 1089 96 1125 96 1165 96 1173 96 1209 96 1213 96 1244 96 1283 96 1372 96 1414 97 2 97 8 97 19 97 64 97 97 97 153 97 183 97 197 97 220 97 247 97 296 97 362 97 384 97 407 97 499 97 614 97 628 97 654 97 662 97 765 97 816 97 871 97 892 97 951 97 970 97 1001 97 1036 97 1050 97 1105 97 1132 97 1186 97 1222 97 1227 97 1242 97 1256 97 1329 97 1354 97 1384 98 70 98 98 98 151 98 185 98 186 98 256 98 264 98 281 98 301 98 358 98 367 98 398 98 412 98 419 98 437 98 546 98 597 98 645 98 663 98 682 98 683 98 692 98 729 98 731 98 760 98 768 98 794 98 803 98 1011 98 1012 98 1031 98 1032 98 1055 98 1083 98 1085 98 1197 98 1208 98 1263 98 1305 98 1417 98 1440 98 1488 99 41 99 81 99 99 99 106 99 188 99 245 99 249 99 329 99 337 99 430 99 487 99 505 99 510 99 529 99 550 99 585 99 602 99 682 99 686 99 717 99 754 99 820 99 890 99 929 99 949 99 968 99 988 99 1000 99 1019 99 1022 99 1042 99 1048 99 1063 99 1070 99 1190 99 1223 99 1226 99 1251 99 1317 99 1408 99 1428 99 1445 100 1 100 100 100 134 100 140 100 246 100 260 100 265 100 320 100 393 100 406 100 417 100 421 100 445 100 487 100 596 100 616 100 672 100 712 100 717 100 754 100 762 100 806 100 856 100 922 100 945 100 974 100 1049 100 1074 100 1077 100 1094 100 1139 100 1158 100 1181 100 1195 100 1226 100 1315 100 1317 100 1337 100 1342 100 1387 100 1397 100 1438 100 1453 100 1470 100 1473 101 36 101 55 101 56 101 101 101 164 101 187 101 202 101 218 101 230 101 291 101 391 101 497 101 524 101 547 101 562 101 592 101 606 101 608 101 620 101 667 101 680 101 730 101 822 101 844 101 867 101 870 101 906 101 908 101 972 101 1018 101 1034 101 1091 101 1098 101 1198 101 1225 101 1299 101 1331 101 1348 101 1369 101 1373 102 30 102 53 102 78 102 82 102 86 102 90 102 102 102 130 102 191 102 200 102 211 102 270 102 308 102 312 102 332 102 405 102 428 102 451 102 511 102 533 102 536 102 537 102 549 102 563 102 579 102 610 102 626 102 658 102 685 102 702 102 752 102 761 102 812 102 829 102 863 102 884 102 901 102 905 102 923 102 959 102 967 102 1003 102 1024 102 1035 102 1057 102 1066 102 1084 102 1102 102 1113 102 1118 102 1124 102 1135 102 1137 102 1183 102 1212 102 1221 102 1327 102 1330 102 1336 102 1340 102 1390 102 1459 102 1475 102 1481 103 10 103 103 103 184 103 210 103 341 103 376 103 542 103 578 103 601 103 643 103 666 103 687 103 704 103 811 103 898 103 913 103 915 103 1008 103 1095 103 1109 103 1168 103 1297 103 1312 103 1421 103 1457 104 39 104 43 104 46 104 62 104 77 104 104 104 105 104 109 104 118 104 176 104 208 104 258 104 309 104 346 104 369 104 409 104 500 104 532 104 557 104 565 104 633 104 651 104 710 104 724 104 779 104 826 104 878 104 899 104 917 104 927 104 954 104 957 104 1025 104 1030 104 1114 104 1128 104 1134 104 1243 104 1270 104 1279 104 1301 104 1310 104 1350 104 1366 104 1368 104 1380 104 1383 104 1439 105 62 105 104 105 105 105 109 105 176 105 208 105 254 105 309 105 346 105 426 105 456 105 489 105 500 105 532 105 633 105 651 105 710 105 826 105 899 105 917 105 1030 105 1114 105 1149 105 1207 105 1220 105 1243 105 1270 105 1310 105 1350 105 1380 105 1383 106 81 106 99 106 106 106 151 106 179 106 188 106 199 106 245 106 249 106 329 106 347 106 430 106 487 106 510 106 529 106 550 106 585 106 602 106 665 106 682 106 683 106 686 106 760 106 768 106 787 106 820 106 821 106 842 106 949 106 950 106 986 106 1019 106 1022 106 1060 106 1063 106 1070 106 1152 106 1190 106 1223 106 1241 106 1304 106 1408 106 1428 106 1465 107 22 107 107 107 266 107 378 107 449 107 507 107 558 107 570 107 607 107 621 107 791 107 854 107 862 107 900 107 935 107 937 107 1071 107 1127 107 1146 107 1156 107 1162 107 1176 107 1184 107 1294 107 1444 108 6 108 45 108 70 108 108 108 124 108 146 108 256 108 273 108 303 108 313 108 363 108 413 108 438 108 512 108 635 108 722 108 731 108 780 108 803 108 852 108 872 108 998 108 1004 108 1031 108 1086 108 1163 108 1228 108 1263 108 1363 108 1399 108 1466 108 1488 109 39 109 46 109 77 109 104 109 105 109 109 109 112 109 208 109 258 109 309 109 346 109 409 109 410 109 500 109 633 109 651 109 724 109 747 109 826 109 878 109 899 109 917 109 954 109 1025 109 1114 109 1128 109 1134 109 1148 109 1207 109 1243 109 1270 109 1301 109 1310 109 1350 109 1368 109 1380 109 1383 109 1439 110 33 110 61 110 110 110 155 110 169 110 341 110 342 110 364 110 379 110 447 110 458 110 493 110 504 110 578 110 586 110 687 110 749 110 773 110 843 110 904 110 913 110 915 110 941 110 943 110 956 110 1109 110 1269 110 1312 110 1345 110 1420 110 1421 110 1437 111 2 111 25 111 69 111 93 111 95 111 111 111 153 111 194 111 227 111 241 111 247 111 282 111 353 111 362 111 384 111 427 111 450 111 454 111 463 111 466 111 481 111 516 111 554 111 670 111 794 111 796 111 970 111 982 111 1001 111 1012 111 1036 111 1083 111 1105 111 1116 111 1119 111 1122 111 1186 111 1194 111 1222 111 1253 111 1256 111 1260 111 1280 111 1282 111 1298 111 1302 111 1385 111 1396 111 1478 112 39 112 46 112 60 112 77 112 109 112 112 112 154 112 168 112 208 112 215 112 258 112 280 112 302 112 346 112 409 112 410 112 500 112 633 112 724 112 861 112 878 112 891 112 954 112 976 112 989 112 1013 112 1025 112 1128 112 1134 112 1148 112 1207 112 1233 112 1301 112 1310 112 1319 112 1368 112 1380 112 1439 113 74 113 113 113 132 113 201 113 227 113 231 113 241 113 275 113 282 113 293 113 306 113 315 113 324 113 353 113 362 113 372 113 384 113 386 113 474 113 481 113 515 113 516 113 554 113 566 113 675 113 798 113 838 113 971 113 1002 113 1116 113 1119 113 1122 113 1232 113 1259 113 1280 113 1282 113 1285 113 1302 113 1391 114 80 114 114 114 181 114 220 114 225 114 238 114 298 114 301 114 358 114 467 114 663 114 664 114 670 114 689 114 699 114 721 114 825 114 966 114 996 114 1011 114 1012 114 1050 114 1055 114 1147 114 1170 114 1175 114 1186 114 1228 114 1308 114 1384 115 32 115 40 115 115 115 139 115 177 115 237 115 307 115 366 115 453 115 833 115 848 115 869 115 926 115 1061 115 1103 115 1245 115 1247 115 1262 115 1276 115 1296 115 1347 115 1381 115 1406 115 1482 116 24 116 116 116 174 116 175 116 206 116 235 116 261 116 267 116 325 116 355 116 356 116 425 116 429 116 444 116 479 116 522 116 539 116 552 116 568 116 646 116 652 116 678 116 708 116 714 116 755 116 771 116 776 116 885 116 897 116 944 116 985 116 995 116 1007 116 1064 116 1072 116 1141 116 1165 116 1178 116 1199 116 1204 116 1244 116 1261 116 1316 116 1339 116 1353 116 1401 116 1403 117 2 117 117 117 153 117 247 117 275 117 282 117 353 117 372 117 384 117 450 117 454 117 463 117 516 117 971 117 982 117 1056 117 1105 117 1186 117 1194 117 1253 117 1256 117 1280 117 1282 117 1307 117 1377 117 1385 117 1396 117 1447 118 43 118 46 118 60 118 104 118 118 118 176 118 287 118 309 118 369 118 385 118 456 118 500 118 532 118 541 118 557 118 565 118 651 118 724 118 747 118 779 118 878 118 902 118 927 118 957 118 1013 118 1114 118 1150 118 1182 118 1210 118 1243 118 1264 118 1270 118 1279 118 1295 118 1366 118 1368 118 1380 118 1489 119 8 119 69 119 119 119 298 119 330 119 407 119 427 119 442 119 454 119 765 119 780 119 794 119 951 119 983 119 1031 119 1133 119 1222 119 1228 119 1260 119 1298 119 1371 119 1396 120 84 120 120 120 201 120 239 120 241 120 271 120 275 120 293 120 311 120 315 120 361 120 515 120 564 120 647 120 677 120 719 120 793 120 858 120 971 120 1006 120 1023 120 1058 120 1157 120 1248 120 1307 120 1377 120 1394 120 1395 120 1424 120 1435 121 9 121 15 121 54 121 73 121 121 121 130 121 152 121 158 121 205 121 221 121 229 121 262 121 285 121 312 121 351 121 462 121 485 121 490 121 536 121 610 121 618 121 619 121 685 121 698 121 701 121 752 121 761 121 778 121 815 121 823 121 827 121 837 121 864 121 905 121 1044 121 1102 121 1118 121 1144 121 1153 121 1183 121 1212 121 1221 121 1258 121 1340 121 1343 121 1360 121 1382 121 1452 121 1455 121 1486 122 122 122 184 122 319 122 350 122 360 122 422 122 443 122 468 122 517 122 573 122 589 122 622 122 643 122 671 122 693 122 725 122 750 122 756 122 800 122 805 122 819 122 886 122 955 122 1087 122 1101 122 1107 122 1185 122 1200 122 1240 122 1246 122 1311 122 1323 122 1344 122 1479 123 20 123 31 123 75 123 123 123 148 123 167 123 178 123 198 123 219 123 242 123 333 123 336 123 402 123 457 123 555 123 593 123 607 123 622 123 673 123 703 123 736 123 756 123 777 123 900 123 916 123 928 123 935 123 958 123 997 123 1015 123 1071 123 1106 123 1112 123 1154 123 1166 123 1211 123 1257 123 1294 123 1311 123 1326 123 1402 123 1426 123 1433 123 1462 123 1464 123 1490 124 6 124 42 124 45 124 108 124 124 124 131 124 145 124 172 124 235 124 268 124 321 124 392 124 413 124 470 124 501 124 531 124 540 124 552 124 576 124 594 124 634 124 649 124 678 124 689 124 695 124 726 124 729 124 746 124 753 124 757 124 786 124 810 124 852 124 885 124 896 124 921 124 961 124 991 124 992 124 1039 124 1052 124 1086 124 1160 124 1173 124 1178 124 1201 124 1213 124 1339 124 1349 124 1353 124 1362 124 1372 124 1425 125 14 125 47 125 63 125 79 125 92 125 125 125 160 125 240 125 272 125 279 125 295 125 373 125 387 125 404 125 483 125 600 125 612 125 624 125 640 125 690 125 694 125 743 125 807 125 809 125 882 125 888 125 910 125 999 125 1026 125 1075 125 1082 125 1099 125 1196 125 1217 125 1277 125 1355 125 1476 125 1484 126 2 126 93 126 95 126 126 126 153 126 194 126 227 126 231 126 247 126 271 126 282 126 296 126 362 126 450 126 454 126 463 126 481 126 515 126 516 126 564 126 654 126 662 126 796 126 801 126 838 126 858 126 970 126 975 126 1001 126 1002 126 1036 126 1050 126 1116 126 1119 126 1122 126 1194 126 1227 126 1248 126 1280 126 1282 126 1298 126 1354 126 1394 126 1396 126 1478 127 89 127 127 127 228 127 243 127 289 127 392 127 393 127 486 127 501 127 502 127 513 127 535 127 649 127 678 127 679 127 746 127 753 127 775 127 789 127 797 127 810 127 830 127 831 127 834 127 879 127 896 127 921 127 925 127 946 127 968 127 1000 127 1009 127 1016 127 1048 127 1072 127 1111 127 1160 127 1201 127 1213 127 1241 127 1286 127 1349 127 1372 127 1392 127 1410 127 1414 127 1449 128 20 128 37 128 49 128 75 128 128 128 148 128 198 128 204 128 242 128 290 128 357 128 360 128 402 128 443 128 551 128 555 128 559 128 574 128 593 128 639 128 657 128 671 128 673 128 703 128 756 128 770 128 800 128 805 128 836 128 916 128 933 128 955 128 1020 128 1101 128 1166 128 1203 128 1273 128 1364 128 1433 128 1464 129 17 129 129 129 131 129 133 129 145 129 172 129 174 129 180 129 192 129 255 129 261 129 269 129 304 129 322 129 340 129 352 129 394 129 395 129 522 129 531 129 576 129 590 129 634 129 695 129 745 129 767 129 769 129 851 129 881 129 969 129 980 129 983 129 992 129 1067 129 1125 129 1140 129 1155 129 1173 129 1178 129 1209 129 1244 129 1261 129 1333 129 1353 129 1415 129 1468 130 9 130 15 130 53 130 54 130 73 130 78 130 102 130 121 130 130 130 152 130 205 130 259 130 270 130 286 130 308 130 312 130 338 130 451 130 511 130 549 130 560 130 610 130 637 130 655 130 685 130 698 130 752 130 761 130 778 130 812 130 815 130 823 130 827 130 905 130 967 130 1003 130 1046 130 1065 130 1084 130 1183 130 1221 130 1330 130 1343 130 1360 130 1382 130 1413 130 1455 130 1459 130 1481 131 66 131 96 131 124 131 129 131 131 131 243 131 261 131 322 131 356 131 392 131 486 131 501 131 576 131 649 131 678 131 679 131 695 131 726 131 745 131 746 131 757 131 767 131 772 131 775 131 830 131 879 131 881 131 887 131 942 131 944 131 946 131 1016 131 1017 131 1067 131 1072 131 1089 131 1125 131 1155 131 1173 131 1178 131 1209 131 1213 131 1244 131 1353 131 1362 131 1372 132 74 132 95 132 113 132 132 132 194 132 201 132 227 132 231 132 241 132 275 132 293 132 306 132 324 132 353 132 386 132 474 132 481 132 515 132 554 132 564 132 566 132 581 132 647 132 796 132 798 132 858 132 971 132 975 132 1116 132 1119 132 1232 132 1248 132 1259 132 1280 132 1391 133 129 133 133 133 172 133 180 133 186 133 238 133 281 133 304 133 395 133 438 133 498 133 522 133 590 133 661 133 681 133 722 133 803 133 969 133 992 133 1031 133 1140 133 1199 133 1209 133 1271 133 1305 133 1499 134 100 134 134 134 140 134 337 134 393 134 411 134 417 134 487 134 513 134 521 134 596 134 679 134 717 134 726 134 741 134 746 134 762 134 772 134 775 134 797 134 834 134 890 134 918 134 946 134 968 134 1000 134 1049 134 1077 134 1139 134 1226 134 1241 134 1445 134 1453 134 1470 135 44 135 72 135 76 135 135 135 144 135 149 135 189 135 217 135 232 135 253 135 305 135 343 135 370 135 387 135 389 135 391 135 397 135 401 135 424 135 455 135 478 135 491 135 520 135 556 135 584 135 591 135 600 135 611 135 684 135 733 135 784 135 807 135 844 135 860 135 911 135 940 135 978 135 990 135 1014 135 1078 135 1136 135 1142 135 1179 135 1180 135 1216 135 1229 135 1230 135 1235 135 1290 135 1358 135 1370 135 1393 135 1441 135 1474 135 1498 136 34 136 136 136 171 136 207 136 213 136 252 136 274 136 297 136 317 136 383 136 423 136 432 136 439 136 469 136 495 136 548 136 588 136 615 136 641 136 706 136 783 136 813 136 853 136 859 136 868 136 889 136 936 136 964 136 1110 136 1130 136 1138 136 1174 136 1255 136 1274 136 1284 136 1322 136 1328 136 1416 136 1422 136 1434 137 38 137 58 137 66 137 137 137 145 137 174 137 206 137 212 137 216 137 261 137 269 137 322 137 323 137 356 137 539 137 785 137 874 137 885 137 944 137 985 137 1017 137 1024 137 1064 137 1072 137 1089 137 1178 137 1234 137 1238 137 1244 137 1353 137 1359 137 1401 138 27 138 28 138 89 138 138 138 228 138 267 138 318 138 393 138 470 138 479 138 498 138 505 138 513 138 521 138 540 138 552 138 568 138 646 138 676 138 705 138 753 138 775 138 817 138 832 138 834 138 890 138 909 138 931 138 946 138 965 138 979 138 995 138 1000 138 1016 138 1048 138 1060 138 1120 138 1199 138 1286 138 1321 138 1425 139 32 139 115 139 139 139 150 139 157 139 171 139 177 139 237 139 307 139 366 139 453 139 833 139 835 139 848 139 869 139 926 139 1041 139 1061 139 1103 139 1138 139 1237 139 1245 139 1247 139 1262 139 1276 139 1296 139 1376 139 1381 139 1406 139 1482 140 35 140 48 140 100 140 134 140 140 140 246 140 313 140 320 140 321 140 337 140 363 140 374 140 382 140 393 140 406 140 411 140 413 140 417 140 487 140 498 140 521 140 540 140 577 140 596 140 688 140 718 140 740 140 741 140 746 140 762 140 772 140 781 140 782 140 797 140 806 140 852 140 918 140 945 140 974 140 998 140 1049 140 1094 140 1139 140 1158 140 1181 140 1201 140 1223 140 1251 140 1292 140 1362 140 1387 140 1453 140 1470 141 33 141 50 141 61 141 68 141 75 141 141 141 155 141 169 141 195 141 294 141 299 141 300 141 314 141 333 141 342 141 357 141 364 141 368 141 379 141 433 141 493 141 504 141 514 141 538 141 571 141 657 141 697 141 704 141 749 141 811 141 836 141 904 141 913 141 916 141 930 141 1088 141 1109 141 1168 141 1188 141 1189 141 1203 141 1269 141 1275 141 1300 141 1338 141 1364 141 1374 141 1420 141 1437 141 1460 141 1495 142 142 142 157 142 316 142 819 142 877 142 914 142 1043 142 1121 142 1430 143 91 143 143 143 219 143 266 143 326 143 378 143 416 143 422 143 446 143 507 143 508 143 570 143 604 143 613 143 617 143 621 143 636 143 644 143 669 143 732 143 739 143 777 143 791 143 854 143 900 143 935 143 937 143 958 143 962 143 997 143 1010 143 1015 143 1146 143 1151 143 1154 143 1162 143 1167 143 1176 143 1289 143 1294 143 1311 143 1326 143 1431 144 44 144 57 144 72 144 76 144 135 144 144 144 149 144 217 144 224 144 232 144 295 144 370 144 389 144 397 144 401 144 424 144 455 144 478 144 491 144 520 144 584 144 591 144 611 144 684 144 733 144 784 144 814 144 839 144 860 144 875 144 893 144 911 144 940 144 978 144 990 144 1014 144 1068 144 1136 144 1142 144 1179 144 1216 144 1230 144 1235 144 1281 144 1290 144 1313 144 1356 144 1358 144 1393 144 1407 144 1498 145 124 145 129 145 137 145 145 145 174 145 180 145 192 145 261 145 325 145 356 145 395 145 429 145 522 145 539 145 576 145 590 145 767 145 769 145 881 145 885 145 944 145 992 145 1092 145 1123 145 1155 145 1173 145 1178 145 1244 145 1261 145 1292 145 1339 145 1353 145 1401 145 1411 146 18 146 69 146 108 146 146 146 163 146 273 146 466 146 512 146 700 146 780 146 851 146 907 146 998 146 1004 146 1123 146 1177 146 1193 146 1260 146 1298 146 1306 146 1385 146 1466 147 44 147 147 147 149 147 344 147 375 147 388 147 491 147 556 147 743 147 799 147 888 147 893 147 990 147 993 147 1027 147 1069 147 1202 147 1235 147 1278 147 1355 147 1358 147 1456 148 7 148 20 148 31 148 87 148 123 148 128 148 148 148 167 148 204 148 219 148 242 148 292 148 333 148 336 148 446 148 449 148 548 148 671 148 703 148 763 148 873 148 900 148 903 148 935 148 948 148 987 148 1106 148 1156 148 1161 148 1171 148 1184 148 1188 148 1211 148 1224 148 1324 148 1326 148 1367 148 1404 148 1431 148 1444 148 1450 148 1464 148 1490 149 44 149 57 149 72 149 76 149 135 149 144 149 147 149 149 149 224 149 232 149 253 149 344 149 370 149 375 149 388 149 389 149 397 149 424 149 455 149 478 149 491 149 556 149 591 149 611 149 733 149 860 149 893 149 993 149 1136 149 1142 149 1179 149 1230 149 1235 149 1278 149 1358 149 1393 149 1456 150 16 150 32 150 139 150 150 150 171 150 177 150 207 150 213 150 237 150 248 150 252 150 274 150 297 150 317 150 366 150 423 150 432 150 439 150 453 150 495 150 588 150 706 150 744 150 835 150 848 150 868 150 869 150 889 150 926 150 936 150 964 150 1041 150 1073 150 1103 150 1130 150 1138 150 1237 150 1247 150 1262 150 1274 150 1284 150 1296 150 1322 150 1328 150 1376 150 1381 150 1406 151 21 151 41 151 51 151 98 151 106 151 151 151 179 151 185 151 186 151 199 151 245 151 251 151 256 151 264 151 278 151 281 151 301 151 318 151 339 151 347 151 358 151 380 151 419 151 430 151 437 151 470 151 480 151 496 151 510 151 529 151 540 151 545 151 597 151 645 151 661 151 665 151 674 151 676 151 682 151 683 151 686 151 729 151 731 151 760 151 768 151 787 151 803 151 821 151 828 151 912 151 949 151 950 151 952 151 965 151 986 151 1011 151 1019 151 1022 151 1032 151 1033 151 1048 151 1055 151 1060 151 1063 151 1085 151 1152 151 1190 151 1208 151 1215 151 1251 151 1263 151 1304 151 1318 151 1408 151 1417 151 1425 151 1465 151 1471 151 1487 151 1488 152 9 152 19 152 54 152 73 152 121 152 130 152 152 152 205 152 259 152 270 152 330 152 338 152 560 152 587 152 599 152 655 152 698 152 701 152 734 152 752 152 761 152 778 152 815 152 884 152 905 152 967 152 1118 152 1124 152 1212 152 1214 152 1221 152 1271 152 1330 152 1343 152 1382 152 1400 152 1413 152 1455 152 1481 153 2 153 93 153 97 153 111 153 117 153 126 153 153 153 197 153 231 153 247 153 282 153 296 153 362 153 384 153 407 153 450 153 454 153 463 153 499 153 516 153 654 153 662 153 801 153 838 153 970 153 982 153 1001 153 1036 153 1050 153 1056 153 1105 153 1122 153 1133 153 1186 153 1194 153 1227 153 1253 153 1256 153 1280 153 1282 153 1298 153 1329 153 1354 153 1384 153 1385 153 1394 153 1396 153 1478 154 43 154 60 154 77 154 112 154 154 154 176 154 208 154 280 154 287 154 369 154 385 154 410 154 456 154 541 154 557 154 633 154 724 154 747 154 779 154 861 154 878 154 891 154 902 154 927 154 957 154 976 154 1013 154 1025 154 1030 154 1128 154 1148 154 1150 154 1210 154 1279 154 1295 154 1310 154 1380 154 1439 155 4 155 33 155 110 155 141 155 155 155 169 155 299 155 331 155 458 155 493 155 514 155 519 155 586 155 632 155 716 155 773 155 843 155 904 155 941 155 956 155 1073 155 1269 155 1345 155 1357 155 1367 155 1423 155 1451 156 7 156 22 156 156 156 196 156 266 156 345 156 378 156 396 156 400 156 403 156 446 156 449 156 507 156 530 156 543 156 558 156 570 156 583 156 604 156 605 156 613 156 621 156 669 156 691 156 707 156 727 156 739 156 763 156 764 156 791 156 854 156 862 156 873 156 900 156 903 156 920 156 948 156 960 156 994 156 1005 156 1037 156 1038 156 1090 156 1126 156 1176 156 1224 156 1267 156 1287 156 1324 156 1325 156 1326 156 1386 156 1436 156 1444 156 1450 156 1464 156 1493 157 139 157 142 157 157 157 316 157 819 157 833 157 877 157 914 157 1043 157 1121 157 1430 158 9 158 15 158 54 158 121 158 158 158 182 158 205 158 221 158 229 158 257 158 262 158 351 158 381 158 462 158 473 158 485 158 490 158 599 158 618 158 619 158 685 158 698 158 735 158 823 158 827 158 837 158 864 158 1044 158 1144 158 1153 158 1183 158 1258 158 1360 158 1389 158 1448 158 1452 158 1455 158 1463 159 159 159 196 159 252 159 274 159 345 159 383 159 390 159 400 159 432 159 448 159 543 159 548 159 588 159 605 159 615 159 641 159 707 159 738 159 739 159 764 159 847 159 920 159 947 159 960 159 964 159 1005 159 1037 159 1090 159 1126 159 1172 159 1174 159 1252 159 1287 159 1324 159 1325 159 1386 159 1434 159 1436 159 1493 160 14 160 47 160 52 160 63 160 92 160 125 160 160 160 165 160 230 160 234 160 240 160 272 160 279 160 373 160 377 160 387 160 404 160 434 160 441 160 483 160 528 160 569 160 600 160 603 160 612 160 624 160 630 160 648 160 690 160 694 160 743 160 809 160 882 160 883 160 888 160 910 160 939 160 1075 160 1076 160 1097 160 1108 160 1159 160 1196 160 1206 160 1229 160 1236 160 1277 160 1472 160 1476 160 1484 161 59 161 67 161 161 161 190 161 335 161 414 161 435 161 774 161 840 161 857 161 1021 161 1231 161 1320 161 1365 161 1409 161 1432 161 1443 161 1477 161 1491 161 1497 162 17 162 27 162 96 162 162 162 228 162 263 162 322 162 328 162 374 162 394 162 479 162 498 162 576 162 577 162 634 162 649 162 705 162 711 162 741 162 746 162 757 162 786 162 789 162 830 162 831 162 881 162 887 162 909 162 942 162 946 162 961 162 991 162 1092 162 1120 162 1125 162 1140 162 1209 162 1213 162 1283 162 1332 162 1372 162 1410 162 1414 162 1446 163 25 163 48 163 70 163 146 163 163 163 226 163 246 163 310 163 320 163 415 163 512 163 523 163 664 163 688 163 692 163 718 163 740 163 880 163 894 163 932 163 963 163 974 163 1004 163 1012 163 1032 163 1045 163 1052 163 1163 163 1170 163 1181 163 1239 163 1363 164 36 164 56 164 101 164 164 164 230 164 343 164 391 164 408 164 520 164 524 164 547 164 592 164 638 164 667 164 680 164 784 164 844 164 867 164 870 164 906 164 908 164 940 164 972 164 1034 164 1179 164 1180 164 1198 164 1230 164 1299 164 1373 164 1496 165 5 165 12 165 13 165 14 165 52 165 63 165 65 165 160 165 165 165 234 165 240 165 434 165 528 165 603 165 609 165 624 165 630 165 642 165 690 165 742 165 751 165 759 165 882 165 939 165 1026 165 1028 165 1129 165 1159 165 1196 165 1265 165 1461 166 166 166 173 166 302 166 334 166 409 166 426 166 461 166 471 166 472 166 477 166 489 166 553 166 696 166 710 166 723 166 748 166 899 166 917 166 924 166 1040 166 1080 166 1104 166 1143 166 1191 166 1233 166 1254 166 1285 166 1303 166 1308 166 1329 166 1391 166 1405 166 1427 166 1469 167 7 167 20 167 31 167 37 167 123 167 148 167 167 167 178 167 219 167 242 167 292 167 319 167 326 167 350 167 360 167 378 167 416 167 418 167 422 167 446 167 508 167 555 167 583 167 593 167 617 167 621 167 622 167 636 167 644 167 671 167 703 167 756 167 777 167 900 167 928 167 935 167 958 167 987 167 997 167 1015 167 1071 167 1087 167 1101 167 1106 167 1112 167 1154 167 1161 167 1166 167 1167 167 1171 167 1185 167 1200 167 1205 167 1211 167 1257 167 1268 167 1289 167 1294 167 1311 167 1326 167 1431 167 1464 167 1490 168 39 168 112 168 168 168 215 168 258 168 302 168 346 168 409 168 426 168 461 168 477 168 489 168 899 168 954 168 989 168 1080 168 1134 168 1233 168 1301 168 1319 168 1405 168 1427 168 1469 169 4 169 33 169 61 169 110 169 141 169 155 169 169 169 299 169 342 169 364 169 379 169 447 169 458 169 493 169 504 169 514 169 586 169 716 169 749 169 773 169 843 169 904 169 941 169 943 169 956 169 1109 169 1269 169 1275 169 1345 169 1420 169 1421 169 1437 169 1451 170 7 170 20 170 31 170 37 170 170 170 242 170 350 170 402 170 418 170 558 170 559 170 593 170 622 170 627 170 703 170 736 170 766 170 800 170 886 170 916 170 928 170 933 170 1020 170 1029 170 1071 170 1100 170 1106 170 1112 170 1156 170 1161 170 1166 170 1171 170 1184 170 1211 170 1257 170 1346 170 1388 170 1402 170 1404 170 1433 170 1462 170 1490 171 32 171 34 171 40 171 136 171 139 171 150 171 171 171 177 171 207 171 213 171 237 171 248 171 317 171 366 171 423 171 439 171 453 171 495 171 588 171 744 171 813 171 835 171 848 171 853 171 859 171 868 171 869 171 889 171 926 171 936 171 1041 171 1061 171 1103 171 1110 171 1138 171 1237 171 1247 171 1262 171 1284 171 1296 171 1322 171 1347 171 1376 171 1381 171 1406 171 1482 172 6 172 28 172 35 172 42 172 124 172 129 172 133 172 172 172 180 172 255 172 263 172 304 172 313 172 322 172 352 172 374 172 382 172 394 172 395 172 498 172 522 172 552 172 575 172 576 172 577 172 590 172 634 172 695 172 745 172 781 172 786 172 810 172 852 172 961 172 969 172 992 172 1052 172 1125 172 1140 172 1155 172 1178 172 1209 172 1333 172 1362 172 1363 173 84 173 88 173 166 173 173 173 306 173 334 173 420 173 426 173 461 173 471 173 472 173 477 173 488 173 489 173 554 173 572 173 659 173 668 173 675 173 710 173 728 173 748 173 788 173 818 173 899 173 917 173 1062 173 1080 173 1093 173 1096 173 1115 173 1143 173 1192 173 1285 173 1293 173 1303 173 1427 173 1469 174 17 174 38 174 66 174 116 174 129 174 137 174 145 174 174 174 175 174 180 174 192 174 216 174 261 174 322 174 325 174 356 174 394 174 444 174 479 174 522 174 537 174 539 174 568 174 646 174 705 174 714 174 767 174 776 174 792 174 881 174 885 174 887 174 897 174 942 174 944 174 969 174 980 174 985 174 992 174 1047 174 1072 174 1089 174 1125 174 1141 174 1204 174 1209 174 1244 174 1261 174 1339 174 1353 174 1359 174 1401 175 17 175 30 175 86 175 116 175 174 175 175 175 250 175 261 175 349 175 356 175 440 175 444 175 537 175 539 175 563 175 714 175 720 175 776 175 785 175 884 175 885 175 887 175 897 175 980 175 1057 175 1137 175 1141 175 1204 175 1283 175 1390 176 43 176 46 176 104 176 105 176 118 176 154 176 176 176 208 176 254 176 287 176 309 176 369 176 385 176 410 176 456 176 500 176 532 176 541 176 557 176 565 176 633 176 651 176 724 176 747 176 779 176 826 176 861 176 878 176 891 176 902 176 927 176 957 176 976 176 989 176 1013 176 1025 176 1030 176 1150 176 1182 176 1210 176 1220 176 1243 176 1264 176 1279 176 1295 176 1310 176 1366 176 1380 176 1489 177 4 177 16 177 32 177 40 177 71 177 115 177 139 177 150 177 171 177 177 177 207 177 213 177 237 177 248 177 274 177 297 177 366 177 453 177 632 177 706 177 716 177 738 177 744 177 833 177 835 177 848 177 853 177 869 177 926 177 964 177 1041 177 1053 177 1061 177 1103 177 1138 177 1237 177 1245 177 1247 177 1262 177 1274 177 1296 177 1322 177 1328 177 1347 177 1381 177 1406 177 1416 177 1482 178 31 178 123 178 167 178 178 178 203 178 219 178 319 178 326 178 350 178 360 178 378 178 416 178 418 178 422 178 457 178 468 178 555 178 573 178 593 178 617 178 622 178 636 178 644 178 703 178 732 178 756 178 777 178 805 178 886 178 900 178 928 178 935 178 958 178 962 178 997 178 1015 178 1087 178 1101 178 1106 178 1112 178 1154 178 1166 178 1171 178 1185 178 1205 178 1211 178 1257 178 1268 178 1289 178 1294 178 1311 178 1426 178 1433 179 11 179 80 179 94 179 106 179 151 179 179 179 181 179 225 179 226 179 245 179 246 179 249 179 265 179 276 179 278 179 310 179 339 179 406 179 430 179 509 179 596 179 653 179 664 179 682 179 713 179 754 179 762 179 768 179 787 179 790 179 845 179 880 179 894 179 912 179 932 179 949 179 952 179 963 179 974 179 1022 179 1032 179 1033 179 1045 179 1063 179 1094 179 1152 179 1158 179 1170 179 1181 179 1190 179 1208 179 1223 179 1239 179 1251 179 1288 179 1335 180 129 180 133 180 145 180 172 180 174 180 180 180 192 180 255 180 261 180 304 180 322 180 325 180 340 180 348 180 352 180 394 180 395 180 460 180 506 180 522 180 537 180 549 180 590 180 631 180 634 180 695 180 745 180 767 180 769 180 884 180 897 180 969 180 980 180 983 180 992 180 1067 180 1125 180 1140 180 1141 180 1155 180 1173 180 1178 180 1209 180 1261 180 1333 180 1351 180 1359 180 1415 180 1499 181 25 181 80 181 114 181 179 181 181 181 220 181 226 181 415 181 663 181 692 181 721 181 768 181 825 181 894 181 932 181 952 181 963 181 974 181 1012 181 1022 181 1032 181 1055 181 1175 181 1385 181 1447 182 9 182 15 182 54 182 158 182 182 182 221 182 229 182 257 182 262 182 351 182 381 182 462 182 473 182 485 182 490 182 599 182 618 182 735 182 808 182 823 182 827 182 837 182 849 182 864 182 1044 182 1144 182 1153 182 1183 182 1258 182 1360 182 1389 182 1448 182 1452 182 1455 182 1463 183 3 183 8 183 64 183 97 183 183 183 296 183 407 183 473 183 499 183 527 183 614 183 628 183 660 183 662 183 709 183 816 183 849 183 951 183 1040 183 1132 183 1227 184 10 184 23 184 37 184 49 184 103 184 122 184 184 184 198 184 210 184 350 184 357 184 376 184 457 184 468 184 503 184 517 184 542 184 555 184 559 184 573 184 582 184 589 184 601 184 627 184 657 184 666 184 725 184 750 184 766 184 770 184 800 184 886 184 898 184 933 184 1008 184 1020 184 1087 184 1088 184 1095 184 1101 184 1166 184 1185 184 1300 184 1364 184 1429 184 1457 184 1483 184 1492 185 98 185 151 185 185 185 186 185 264 185 288 185 301 185 359 185 398 185 419 185 436 185 480 185 529 185 546 185 587 185 597 185 598 185 645 185 650 185 663 185 665 185 674 185 676 185 683 185 758 185 760 185 842 185 895 185 996 185 1011 185 1060 185 1079 185 1085 185 1197 185 1218 185 1305 185 1318 185 1412 185 1413 185 1417 185 1440 185 1465 185 1487 186 51 186 98 186 133 186 151 186 185 186 186 186 238 186 256 186 264 186 278 186 281 186 298 186 301 186 303 186 358 186 367 186 419 186 437 186 496 186 545 186 597 186 645 186 661 186 674 186 676 186 682 186 699 186 729 186 803 186 828 186 949 186 950 186 1011 186 1060 186 1063 186 1085 186 1086 186 1152 186 1197 186 1208 186 1263 186 1271 186 1305 186 1398 186 1417 186 1440 186 1487 186 1488 187 55 187 83 187 101 187 187 187 217 187 452 187 497 187 524 187 544 187 547 187 562 187 584 187 592 187 608 187 620 187 667 187 867 187 906 187 908 187 972 187 1034 187 1091 187 1098 187 1225 187 1291 187 1299 187 1313 187 1348 187 1356 187 1361 187 1373 187 1496 188 35 188 99 188 106 188 188 188 199 188 374 188 382 188 406 188 430 188 487 188 510 188 529 188 540 188 550 188 577 188 661 188 682 188 686 188 718 188 781 188 782 188 790 188 820 188 949 188 1019 188 1022 188 1060 188 1063 188 1094 188 1152 188 1190 188 1223 188 1251 189 76 189 79 189 135 189 189 189 253 189 272 189 295 189 305 189 344 189 373 189 387 189 401 189 455 189 484 189 491 189 520 189 556 189 591 189 600 189 611 189 684 189 743 189 807 189 860 189 888 189 910 189 911 189 978 189 990 189 993 189 999 189 1014 189 1018 189 1069 189 1082 189 1216 189 1217 189 1230 189 1235 189 1250 189 1277 189 1290 189 1355 189 1358 189 1370 189 1375 189 1441 189 1484 190 59 190 67 190 161 190 190 190 335 190 414 190 435 190 691 190 727 190 774 190 840 190 841 190 857 190 919 190 953 190 1021 190 1231 190 1320 190 1365 190 1379 190 1409 190 1432 190 1443 190 1454 190 1477 190 1491 190 1497 191 30 191 53 191 78 191 82 191 86 191 90 191 102 191 191 191 257 191 270 191 308 191 332 191 405 191 428 191 451 191 511 191 533 191 534 191 536 191 537 191 549 191 563 191 579 191 610 191 619 191 623 191 626 191 658 191 685 191 701 191 761 191 812 191 829 191 863 191 884 191 905 191 923 191 934 191 959 191 1003 191 1024 191 1035 191 1054 191 1057 191 1065 191 1066 191 1084 191 1102 191 1113 191 1131 191 1135 191 1137 191 1183 191 1212 191 1221 191 1327 191 1334 191 1340 191 1390 191 1459 191 1486 192 17 192 38 192 129 192 145 192 174 192 180 192 192 192 255 192 261 192 322 192 340 192 352 192 395 192 460 192 531 192 590 192 700 192 745 192 769 192 851 192 1067 192 1089 192 1125 192 1155 192 1187 192 1193 192 1209 192 1333 192 1401 192 1415 193 24 193 26 193 58 193 82 193 86 193 90 193 193 193 206 193 211 193 212 193 222 193 250 193 277 193 323 193 332 193 348 193 405 193 425 193 451 193 464 193 465 193 502 193 625 193 626 193 658 193 702 193 720 193 863 193 901 193 959 193 1003 193 1024 193 1035 193 1046 193 1054 193 1064 193 1135 193 1137 193 1165 193 1234 193 1238 193 1283 193 1309 193 1327 193 1336 193 1341 193 1459 193 1481 194 2 194 84 194 93 194 95 194 111 194 126 194 132 194 194 194 201 194 227 194 231 194 241 194 247 194 275 194 282 194 311 194 362 194 372 194 384 194 481 194 516 194 564 194 654 194 670 194 675 194 796 194 970 194 973 194 975 194 1001 194 1012 194 1036 194 1050 194 1105 194 1116 194 1119 194 1122 194 1157 194 1186 194 1194 194 1232 194 1248 194 1256 194 1280 194 1302 194 1329 194 1354 194 1394 194 1478 195 141 195 195 195 294 195 299 195 314 195 342 195 379 195 504 195 571 195 693 195 697 195 704 195 749 195 811 195 836 195 904 195 913 195 930 195 1109 195 1168 195 1189 195 1240 195 1246 195 1269 195 1275 195 1338 195 1352 195 1374 195 1379 195 1420 195 1437 195 1495 196 156 196 159 196 196 196 266 196 345 196 383 196 400 196 448 196 543 196 605 196 615 196 641 196 707 196 739 196 764 196 847 196 862 196 920 196 947 196 960 196 994 196 1037 196 1090 196 1126 196 1172 196 1174 196 1267 196 1324 196 1325 196 1386 196 1434 196 1436 196 1493 197 0 197 2 197 19 197 97 197 153 197 197 197 220 197 247 197 298 197 301 197 330 197 338 197 362 197 384 197 407 197 442 197 499 197 614 197 654 197 721 197 765 197 771 197 794 197 866 197 871 197 892 197 951 197 970 197 983 197 1001 197 1036 197 1050 197 1085 197 1105 197 1145 197 1147 197 1186 197 1222 197 1242 197 1256 197 1260 197 1329 197 1371 197 1384 197 1400 197 1412 198 10 198 23 198 37 198 49 198 68 198 75 198 123 198 128 198 184 198 198 198 290 198 333 198 357 198 360 198 368 198 376 198 402 198 443 198 457 198 503 198 517 198 542 198 551 198 555 198 559 198 578 198 582 198 593 198 601 198 622 198 627 198 657 198 666 198 673 198 697 198 703 198 725 198 756 198 766 198 770 198 805 198 886 198 898 198 916 198 933 198 1008 198 1020 198 1088 198 1100 198 1101 198 1107 198 1166 198 1203 198 1257 198 1300 198 1429 198 1433 198 1457 198 1483 198 1492 199 35 199 41 199 81 199 106 199 151 199 188 199 199 199 245 199 278 199 281 199 284 199 339 199 374 199 380 199 382 199 419 199 430 199 437 199 459 199 510 199 545 199 594 199 661 199 665 199 676 199 682 199 686 199 713 199 726 199 729 199 781 199 782 199 787 199 790 199 929 199 949 199 952 199 965 199 1022 199 1048 199 1060 199 1081 199 1086 199 1094 199 1152 199 1164 199 1190 199 1215 199 1223 199 1226 199 1251 199 1304 199 1408 199 1417 199 1487 200 26 200 78 200 82 200 102 200 200 200 233 200 277 200 308 200 312 200 332 200 338 200 405 200 451 200 465 200 560 200 579 200 625 200 626 200 658 200 752 200 863 200 901 200 959 200 1003 200 1024 200 1035 200 1066 200 1113 200 1124 200 1135 200 1212 200 1327 200 1330 200 1378 200 1400 200 1413 200 1467 200 1481 200 1494 201 74 201 95 201 113 201 120 201 132 201 194 201 201 201 227 201 231 201 239 201 241 201 271 201 275 201 293 201 306 201 311 201 315 201 324 201 372 201 386 201 488 201 515 201 554 201 564 201 566 201 647 201 668 201 677 201 798 201 804 201 818 201 858 201 971 201 975 201 1002 201 1056 201 1116 201 1119 201 1157 201 1192 201 1232 201 1248 201 1259 201 1280 201 1282 201 1285 201 1307 201 1391 201 1394 202 5 202 36 202 52 202 65 202 101 202 202 202 230 202 240 202 272 202 365 202 441 202 569 202 630 202 642 202 730 202 742 202 870 202 999 202 1018 202 1028 202 1076 202 1108 202 1265 202 1331 202 1369 202 1461 202 1472 202 1476 203 20 203 37 203 49 203 68 203 75 203 87 203 178 203 203 203 204 203 219 203 242 203 292 203 294 203 300 203 333 203 350 203 357 203 360 203 368 203 433 203 443 203 468 203 517 203 538 203 551 203 573 203 657 203 671 203 673 203 703 203 756 203 805 203 819 203 836 203 886 203 916 203 930 203 1029 203 1100 203 1101 203 1107 203 1166 203 1169 203 1171 203 1188 203 1203 203 1300 203 1311 203 1364 203 1458 203 1460 203 1490 204 7 204 20 204 37 204 87 204 128 204 148 204 203 204 204 204 242 204 292 204 294 204 300 204 333 204 336 204 403 204 443 204 583 204 657 204 671 204 703 204 836 204 928 204 930 204 948 204 953 204 987 204 1029 204 1106 204 1161 204 1169 204 1171 204 1188 204 1203 204 1211 204 1224 204 1273 204 1326 204 1379 204 1404 204 1450 204 1458 204 1460 204 1464 204 1490 205 9 205 15 205 54 205 73 205 121 205 130 205 152 205 158 205 205 205 259 205 285 205 312 205 338 205 381 205 462 205 485 205 490 205 536 205 560 205 599 205 618 205 655 205 685 205 698 205 701 205 734 205 735 205 752 205 761 205 778 205 802 205 815 205 823 205 827 205 837 205 864 205 905 205 1044 205 1066 205 1102 205 1144 205 1153 205 1183 205 1212 205 1214 205 1221 205 1258 205 1330 205 1340 205 1343 205 1360 205 1382 205 1389 205 1442 205 1448 205 1452 205 1455 205 1463 205 1486 206 24 206 66 206 116 206 137 206 193 206 206 206 211 206 235 206 277 206 325 206 348 206 355 206 356 206 405 206 425 206 451 206 539 206 552 206 568 206 580 206 625 206 646 206 652 206 702 206 708 206 714 206 755 206 776 206 846 206 885 206 944 206 985 206 1007 206 1024 206 1046 206 1064 206 1135 206 1165 206 1204 206 1238 206 1244 206 1261 206 1316 206 1403 206 1459 206 1475 206 1494 207 16 207 32 207 34 207 40 207 136 207 150 207 171 207 177 207 207 207 213 207 237 207 248 207 252 207 274 207 297 207 307 207 317 207 423 207 432 207 439 207 453 207 495 207 588 207 641 207 738 207 744 207 813 207 835 207 848 207 853 207 859 207 868 207 869 207 889 207 936 207 964 207 1041 207 1073 207 1110 207 1130 207 1138 207 1237 207 1247 207 1252 207 1262 207 1276 207 1284 207 1296 207 1322 207 1347 207 1381 207 1416 207 1422 208 39 208 60 208 77 208 104 208 105 208 109 208 112 208 154 208 176 208 208 208 254 208 280 208 302 208 385 208 410 208 456 208 500 208 532 208 541 208 565 208 633 208 651 208 724 208 747 208 779 208 826 208 861 208 878 208 891 208 902 208 927 208 957 208 976 208 989 208 1013 208 1025 208 1030 208 1128 208 1148 208 1207 208 1210 208 1295 208 1310 208 1366 208 1368 208 1380 208 1383 208 1439 208 1489 209 62 209 84 209 88 209 209 209 334 209 420 209 472 209 488 209 554 209 572 209 581 209 659 209 710 209 723 209 728 209 737 209 788 209 798 209 818 209 1006 209 1051 209 1062 209 1093 209 1104 209 1115 209 1143 209 1149 209 1192 209 1293 210 10 210 68 210 103 210 184 210 210 210 299 210 314 210 341 210 342 210 357 210 368 210 376 210 433 210 504 210 542 210 551 210 559 210 571 210 578 210 601 210 627 210 666 210 704 210 725 210 750 210 766 210 811 210 898 210 916 210 930 210 1008 210 1029 210 1088 210 1095 210 1100 210 1189 210 1297 210 1300 210 1312 210 1338 210 1457 210 1460 210 1492 210 1495 211 53 211 58 211 66 211 78 211 82 211 86 211 102 211 193 211 206 211 211 211 212 211 216 211 250 211 277 211 308 211 332 211 348 211 349 211 405 211 428 211 431 211 444 211 451 211 533 211 549 211 563 211 579 211 580 211 610 211 625 211 626 211 658 211 702 211 720 211 812 211 829 211 846 211 863 211 874 211 901 211 959 211 1003 211 1024 211 1046 211 1057 211 1064 211 1084 211 1135 211 1137 211 1165 211 1238 211 1249 211 1309 211 1341 211 1459 211 1475 211 1481 211 1494 212 30 212 38 212 53 212 58 212 78 212 90 212 137 212 193 212 211 212 212 212 216 212 270 212 286 212 349 212 428 212 431 212 451 212 460 212 464 212 511 212 534 212 537 212 549 212 563 212 580 212 623 212 631 212 637 212 720 212 761 212 785 212 792 212 812 212 829 212 874 212 923 212 1003 212 1046 212 1057 212 1064 212 1065 212 1084 212 1219 212 1234 212 1238 212 1249 212 1334 212 1336 212 1351 212 1390 212 1418 212 1459 212 1481 213 32 213 34 213 40 213 136 213 150 213 171 213 177 213 207 213 213 213 237 213 248 213 252 213 274 213 297 213 317 213 423 213 432 213 439 213 453 213 495 213 588 213 706 213 744 213 783 213 813 213 835 213 848 213 853 213 859 213 868 213 869 213 889 213 926 213 936 213 1041 213 1138 213 1237 213 1247 213 1262 213 1274 213 1284 213 1296 213 1322 213 1347 213 1376 213 1381 214 214 214 236 214 476 214 595 214 647 214 793 214 850 214 856 214 876 214 981 214 984 214 1006 214 1051 214 1117 214 1195 214 1306 214 1337 214 1342 215 39 215 112 215 168 215 215 215 258 215 280 215 302 215 346 215 409 215 410 215 426 215 489 215 861 215 954 215 989 215 1134 215 1148 215 1207 215 1233 215 1301 215 1319 215 1405 216 38 216 58 216 66 216 137 216 174 216 211 216 212 216 216 216 269 216 349 216 394 216 428 216 431 216 464 216 534 216 580 216 637 216 720 216 785 216 792 216 808 216 874 216 887 216 1017 216 1046 216 1047 216 1067 216 1089 216 1219 216 1234 216 1238 216 1249 216 1336 216 1351 216 1359 216 1390 216 1418 217 72 217 83 217 135 217 144 217 187 217 217 217 223 217 224 217 232 217 253 217 305 217 343 217 389 217 397 217 401 217 424 217 452 217 455 217 478 217 497 217 520 217 526 217 544 217 547 217 567 217 584 217 591 217 592 217 680 217 684 217 807 217 839 217 860 217 875 217 906 217 908 217 940 217 972 217 1014 217 1034 217 1068 217 1078 217 1142 217 1198 217 1216 217 1217 217 1235 217 1250 217 1290 217 1299 217 1313 217 1348 217 1356 217 1361 217 1370 217 1375 217 1474 217 1496 217 1498 218 5 218 13 218 14 218 36 218 47 218 55 218 65 218 85 218 92 218 101 218 218 218 234 218 291 218 377 218 434 218 441 218 452 218 492 218 497 218 524 218 528 218 547 218 562 218 603 218 608 218 609 218 612 218 620 218 630 218 648 218 667 218 730 218 867 218 870 218 882 218 883 218 939 218 1076 218 1091 218 1098 218 1129 218 1159 218 1225 218 1291 218 1369 218 1373 218 1496 219 7 219 20 219 37 219 91 219 123 219 143 219 148 219 167 219 178 219 203 219 219 219 242 219 292 219 319 219 326 219 350 219 360 219 378 219 416 219 418 219 422 219 443 219 446 219 508 219 555 219 593 219 613 219 617 219 621 219 622 219 636 219 639 219 644 219 671 219 703 219 732 219 756 219 777 219 886 219 900 219 903 219 928 219 933 219 935 219 958 219 987 219 997 219 1010 219 1015 219 1071 219 1101 219 1106 219 1154 219 1161 219 1166 219 1167 219 1171 219 1200 219 1205 219 1211 219 1257 219 1268 219 1289 219 1294 219 1311 219 1326 219 1346 219 1388 219 1426 219 1431 219 1464 219 1479 220 0 220 25 220 97 220 114 220 181 220 197 220 220 220 238 220 298 220 301 220 358 220 367 220 442 220 454 220 463 220 654 220 663 220 670 220 692 220 721 220 765 220 794 220 821 220 824 220 825 220 996 220 1012 220 1050 220 1055 220 1083 220 1085 220 1147 220 1186 220 1222 220 1228 220 1256 220 1260 220 1371 220 1384 220 1385 220 1398 220 1447 220 1488 221 15 221 54 221 121 221 158 221 182 221 221 221 229 221 257 221 262 221 285 221 351 221 381 221 462 221 485 221 490 221 618 221 619 221 735 221 808 221 823 221 827 221 837 221 864 221 1044 221 1144 221 1153 221 1183 221 1258 221 1360 221 1389 221 1448 221 1452 222 26 222 193 222 222 222 312 222 323 222 327 222 436 222 465 222 482 222 506 222 536 222 560 222 629 222 702 222 715 222 734 222 808 222 866 222 897 222 934 222 1024 222 1035 222 1054 222 1102 222 1113 222 1118 222 1124 222 1135 222 1212 222 1214 222 1327 222 1330 222 1334 222 1340 222 1442 222 1486 223 47 223 72 223 83 223 217 223 223 223 224 223 279 223 295 223 343 223 371 223 377 223 387 223 389 223 408 223 452 223 478 223 483 223 567 223 592 223 600 223 638 223 640 223 648 223 680 223 784 223 807 223 814 223 822 223 839 223 844 223 875 223 910 223 911 223 940 223 972 223 978 223 1034 223 1068 223 1078 223 1097 223 1099 223 1142 223 1180 223 1198 223 1206 223 1216 223 1217 223 1230 223 1281 223 1313 223 1361 223 1373 223 1407 223 1441 223 1474 223 1484 223 1496 223 1498 224 44 224 72 224 83 224 144 224 149 224 217 224 223 224 224 224 232 224 253 224 343 224 370 224 371 224 377 224 389 224 397 224 491 224 584 224 592 224 640 224 807 224 814 224 844 224 860 224 875 224 908 224 972 224 1034 224 1068 224 1078 224 1099 224 1136 224 1142 224 1180 224 1217 224 1230 224 1361 224 1373 224 1393 224 1407 224 1474 224 1496 225 11 225 80 225 114 225 179 225 225 225 226 225 249 225 276 225 278 225 329 225 339 225 347 225 412 225 419 225 437 225 496 225 509 225 602 225 653 225 656 225 664 225 682 225 692 225 713 225 760 225 768 225 787 225 821 225 825 225 828 225 845 225 912 225 922 225 952 225 966 225 1022 225 1045 225 1063 225 1152 225 1170 225 1175 225 1190 225 1288 225 1335 225 1465 226 21 226 80 226 94 226 163 226 179 226 181 226 225 226 226 226 245 226 246 226 249 226 276 226 310 226 320 226 329 226 406 226 412 226 445 226 467 226 596 226 616 226 653 226 656 226 664 226 688 226 712 226 713 226 740 226 754 226 762 226 768 226 806 226 855 226 932 226 952 226 963 226 966 226 974 226 1022 226 1032 226 1045 226 1063 226 1158 226 1170 226 1175 226 1181 226 1288 227 2 227 74 227 93 227 95 227 111 227 113 227 126 227 132 227 194 227 201 227 227 227 231 227 241 227 247 227 282 227 306 227 324 227 362 227 386 227 474 227 481 227 515 227 516 227 525 227 554 227 564 227 566 227 581 227 796 227 798 227 801 227 804 227 838 227 975 227 1001 227 1002 227 1116 227 1119 227 1122 227 1232 227 1259 227 1280 227 1282 227 1285 227 1302 227 1391 227 1396 227 1478 228 27 228 127 228 138 228 162 228 228 228 243 228 289 228 337 228 392 228 479 228 501 228 502 228 513 228 535 228 649 228 679 228 757 228 775 228 789 228 797 228 831 228 834 228 879 228 890 228 909 228 918 228 925 228 946 228 968 228 979 228 988 228 1000 228 1016 228 1072 228 1111 228 1120 228 1241 228 1286 228 1392 228 1410 228 1414 229 15 229 54 229 121 229 158 229 182 229 221 229 229 229 257 229 262 229 285 229 351 229 381 229 428 229 462 229 485 229 490 229 533 229 534 229 610 229 618 229 619 229 685 229 735 229 827 229 837 229 864 229 1044 229 1144 229 1153 229 1183 229 1258 229 1360 229 1389 229 1448 229 1452 230 5 230 14 230 36 230 47 230 52 230 56 230 92 230 101 230 160 230 164 230 202 230 230 230 272 230 279 230 291 230 365 230 373 230 387 230 391 230 441 230 483 230 569 230 600 230 603 230 609 230 624 230 630 230 642 230 690 230 694 230 730 230 784 230 809 230 844 230 870 230 882 230 910 230 999 230 1018 230 1075 230 1076 230 1108 230 1196 230 1277 230 1331 230 1369 230 1461 230 1472 230 1476 230 1484 231 2 231 74 231 93 231 95 231 113 231 126 231 132 231 153 231 194 231 201 231 227 231 231 231 239 231 241 231 247 231 271 231 282 231 296 231 306 231 311 231 315 231 362 231 386 231 450 231 454 231 463 231 481 231 515 231 516 231 564 231 796 231 801 231 804 231 838 231 858 231 975 231 1001 231 1002 231 1036 231 1050 231 1116 231 1119 231 1122 231 1194 231 1232 231 1248 231 1259 231 1280 231 1282 231 1391 231 1394 231 1396 231 1478 232 57 232 72 232 76 232 135 232 144 232 149 232 217 232 224 232 232 232 253 232 305 232 343 232 370 232 389 232 397 232 401 232 424 232 455 232 478 232 584 232 591 232 592 232 611 232 684 232 733 232 807 232 814 232 860 232 893 232 940 232 978 232 990 232 1068 232 1078 232 1136 232 1142 232 1179 232 1216 232 1229 232 1230 232 1235 232 1250 232 1278 232 1290 232 1356 232 1358 232 1375 232 1393 232 1407 232 1441 232 1456 233 26 233 82 233 86 233 200 233 233 233 244 233 332 233 355 233 405 233 563 233 623 233 625 233 658 233 708 233 755 233 795 233 865 233 896 233 934 233 1035 233 1059 233 1113 233 1137 233 1204 233 1314 233 1316 233 1327 233 1378 233 1467 233 1485 233 1494 234 5 234 12 234 13 234 14 234 47 234 52 234 63 234 65 234 85 234 160 234 165 234 218 234 234 234 240 234 291 234 371 234 377 234 434 234 441 234 492 234 528 234 544 234 603 234 609 234 624 234 630 234 642 234 648 234 742 234 759 234 882 234 883 234 939 234 1026 234 1028 234 1075 234 1076 234 1129 234 1159 234 1265 234 1461 235 51 235 80 235 116 235 124 235 206 235 235 235 251 235 284 235 301 235 321 235 356 235 358 235 467 235 486 235 539 235 552 235 568 235 594 235 678 235 689 235 695 235 714 235 729 235 753 235 885 235 944 235 985 235 1007 235 1072 235 1178 235 1244 235 1261 235 1308 235 1339 236 214 236 236 236 476 236 595 236 742 236 973 236 981 236 984 236 1117 236 1182 236 1264 237 16 237 32 237 34 237 40 237 115 237 139 237 150 237 171 237 177 237 207 237 213 237 237 237 274 237 307 237 317 237 366 237 423 237 439 237 453 237 495 237 744 237 813 237 833 237 835 237 848 237 853 237 859 237 868 237 869 237 889 237 926 237 936 237 1041 237 1061 237 1103 237 1110 237 1138 237 1237 237 1247 237 1262 237 1276 237 1284 237 1296 237 1322 237 1347 237 1376 237 1381 237 1406 237 1482 238 114 238 133 238 186 238 220 238 238 238 244 238 256 238 264 238 281 238 298 238 301 238 303 238 358 238 367 238 438 238 442 238 475 238 480 238 518 238 597 238 674 238 722 238 729 238 803 238 824 238 996 238 1011 238 1031 238 1085 238 1145 238 1147 238 1228 238 1263 238 1271 238 1305 238 1371 238 1400 238 1403 238 1412 238 1488 238 1499 239 74 239 84 239 93 239 95 239 120 239 201 239 231 239 239 239 241 239 271 239 275 239 282 239 293 239 306 239 311 239 315 239 361 239 372 239 488 239 515 239 554 239 564 239 647 239 677 239 719 239 858 239 971 239 975 239 1023 239 1056 239 1058 239 1157 239 1248 239 1253 239 1280 239 1282 239 1307 239 1354 239 1377 239 1394 239 1395 239 1424 239 1435 240 5 240 12 240 13 240 14 240 47 240 52 240 63 240 65 240 92 240 125 240 160 240 165 240 202 240 234 240 240 240 272 240 365 240 404 240 434 240 441 240 528 240 569 240 603 240 609 240 612 240 624 240 630 240 642 240 648 240 690 240 730 240 742 240 809 240 882 240 883 240 939 240 999 240 1018 240 1026 240 1028 240 1075 240 1076 240 1159 240 1196 240 1265 240 1331 240 1369 240 1461 240 1472 240 1476 240 1484 241 2 241 74 241 93 241 95 241 111 241 113 241 120 241 132 241 194 241 201 241 227 241 231 241 239 241 241 241 247 241 271 241 275 241 282 241 293 241 306 241 311 241 315 241 324 241 353 241 362 241 372 241 384 241 386 241 474 241 488 241 515 241 516 241 554 241 564 241 566 241 675 241 796 241 858 241 971 241 982 241 1023 241 1056 241 1116 241 1122 241 1157 241 1186 241 1232 241 1248 241 1253 241 1259 241 1280 241 1282 241 1329 241 1391 241 1394 242 7 242 20 242 31 242 37 242 87 242 123 242 128 242 148 242 167 242 170 242 203 242 204 242 219 242 242 242 292 242 333 242 336 242 350 242 360 242 418 242 443 242 446 242 583 242 613 242 639 242 644 242 671 242 673 242 703 242 756 242 777 242 836 242 886 242 900 242 903 242 928 242 935 242 948 242 987 242 1071 242 1106 242 1156 242 1161 242 1171 242 1184 242 1205 242 1211 242 1257 242 1268 242 1273 242 1289 242 1311 242 1326 242 1388 242 1402 242 1431 242 1450 242 1458 242 1464 242 1490 243 96 243 127 243 131 243 228 243 243 243 289 243 392 243 459 243 486 243 501 243 502 243 513 243 649 243 678 243 679 243 726 243 746 243 757 243 775 243 789 243 797 243 834 243 879 243 909 243 918 243 925 243 946 243 968 243 991 243 1016 243 1072 243 1111 243 1213 243 1372 243 1410 243 1414 244 82 244 233 244 238 244 244 244 264 244 283 244 355 244 359 244 494 244 623 244 625 244 629 244 681 244 708 244 795 244 842 244 865 244 986 244 1007 244 1009 244 1079 244 1199 244 1271 244 1316 244 1318 244 1378 244 1467 244 1485 244 1494 245 21 245 41 245 80 245 81 245 94 245 99 245 106 245 151 245 179 245 199 245 226 245 245 245 246 245 249 245 276 245 278 245 310 245 318 245 329 245 337 245 339 245 412 245 419 245 430 245 437 245 496 245 509 245 510 245 535 245 540 245 596 245 602 245 664 245 665 245 682 245 683 245 686 245 713 245 768 245 787 245 790 245 912 245 929 245 949 245 950 245 952 245 963 245 974 245 1022 245 1032 245 1033 245 1042 245 1045 245 1048 245 1063 245 1152 245 1158 245 1170 245 1190 245 1208 245 1223 245 1241 245 1251 245 1288 245 1304 245 1408 245 1445 245 1487 246 94 246 100 246 140 246 163 246 179 246 226 246 245 246 246 246 265 246 284 246 310 246 320 246 393 246 406 246 415 246 417 246 445 246 596 246 616 246 653 246 664 246 672 246 688 246 740 246 754 246 762 246 768 246 772 246 806 246 855 246 856 246 880 246 894 246 932 246 945 246 952 246 963 246 974 246 998 246 1004 246 1022 246 1032 246 1042 246 1045 246 1094 246 1139 246 1158 246 1177 246 1181 246 1239 246 1251 246 1387 246 1438 246 1453 246 1473 247 2 247 93 247 95 247 97 247 111 247 117 247 126 247 153 247 194 247 197 247 227 247 231 247 241 247 247 247 282 247 296 247 353 247 362 247 372 247 384 247 450 247 454 247 463 247 499 247 516 247 554 247 566 247 654 247 662 247 670 247 675 247 796 247 970 247 975 247 1001 247 1036 247 1050 247 1083 247 1105 247 1119 247 1122 247 1186 247 1194 247 1248 247 1253 247 1256 247 1272 247 1280 247 1302 247 1329 247 1354 247 1384 247 1396 247 1447 247 1478 248 4 248 32 248 71 248 150 248 171 248 177 248 207 248 213 248 248 248 297 248 317 248 331 248 390 248 423 248 432 248 469 248 519 248 632 248 706 248 716 248 738 248 835 248 889 248 936 248 977 248 1041 248 1053 248 1073 248 1130 248 1237 248 1247 248 1274 248 1322 248 1328 248 1357 248 1367 248 1381 248 1416 248 1423 248 1451 248 1480 249 99 249 106 249 179 249 225 249 226 249 245 249 249 249 310 249 329 249 337 249 509 249 550 249 602 249 653 249 656 249 672 249 754 249 787 249 820 249 845 249 855 249 922 249 932 249 952 249 1022 249 1063 249 1070 249 1074 249 1152 249 1170 249 1175 249 1190 249 1241 249 1288 249 1317 249 1335 249 1428 250 58 250 66 250 86 250 175 250 193 250 211 250 250 250 277 250 332 250 405 250 440 250 444 250 502 250 563 250 626 250 678 250 720 250 909 250 985 250 1016 250 1024 250 1047 250 1054 250 1165 250 1283 250 1309 250 1341 251 0 251 80 251 151 251 235 251 251 251 264 251 276 251 281 251 301 251 318 251 358 251 412 251 467 251 535 251 689 251 699 251 721 251 760 251 768 251 787 251 821 251 925 251 938 251 952 251 979 251 986 251 1009 251 1011 251 1055 251 1079 251 1215 251 1304 251 1318 251 1449 251 1465 251 1471 252 136 252 150 252 159 252 207 252 213 252 252 252 274 252 297 252 317 252 383 252 390 252 400 252 423 252 432 252 439 252 448 252 588 252 615 252 641 252 706 252 738 252 764 252 783 252 847 252 889 252 936 252 964 252 1130 252 1172 252 1174 252 1252 252 1274 252 1284 252 1322 252 1325 252 1434 252 1436 252 1493 253 135 253 149 253 189 253 217 253 224 253 232 253 253 253 305 253 344 253 389 253 397 253 404 253 455 253 478 253 491 253 556 253 567 253 584 253 591 253 611 253 684 253 743 253 807 253 814 253 860 253 875 253 910 253 978 253 990 253 993 253 1014 253 1078 253 1082 253 1136 253 1142 253 1217 253 1229 253 1235 253 1250 253 1290 253 1355 253 1356 253 1358 253 1370 253 1375 253 1456 253 1498 254 62 254 105 254 176 254 208 254 254 254 302 254 410 254 426 254 456 254 633 254 651 254 710 254 747 254 779 254 826 254 878 254 891 254 899 254 917 254 976 254 989 254 1025 254 1030 254 1148 254 1149 254 1207 254 1220 254 1270 254 1295 254 1310 254 1350 254 1383 255 17 255 129 255 172 255 180 255 192 255 255 255 304 255 322 255 328 255 340 255 352 255 354 255 363 255 394 255 395 255 531 255 561 255 590 255 634 255 700 255 711 255 745 255 769 255 786 255 851 255 852 255 881 255 969 255 992 255 1092 255 1123 255 1125 255 1140 255 1155 255 1193 255 1209 256 6 256 21 256 42 256 48 256 70 256 98 256 108 256 151 256 186 256 238 256 256 256 273 256 281 256 303 256 339 256 358 256 367 256 412 256 437 256 438 256 512 256 521 256 597 256 635 256 645 256 692 256 718 256 729 256 731 256 782 256 794 256 803 256 810 256 828 256 1011 256 1031 256 1032 256 1033 256 1052 256 1055 256 1163 256 1201 256 1208 256 1239 256 1263 256 1362 256 1363 256 1399 256 1417 256 1488 257 58 257 158 257 182 257 191 257 221 257 229 257 257 257 262 257 351 257 428 257 490 257 533 257 534 257 610 257 618 257 619 257 626 257 808 257 827 257 864 257 874 257 901 257 1024 257 1044 257 1065 257 1102 257 1183 257 1219 257 1249 257 1258 257 1334 257 1340 257 1360 258 39 258 46 258 104 258 109 258 112 258 168 258 215 258 258 258 309 258 346 258 409 258 489 258 500 258 724 258 899 258 917 258 954 258 1025 258 1114 258 1128 258 1134 258 1148 258 1182 258 1207 258 1233 258 1270 258 1301 258 1319 258 1368 258 1380 259 15 259 19 259 73 259 130 259 152 259 205 259 259 259 285 259 288 259 312 259 338 259 465 259 560 259 587 259 655 259 698 259 701 259 734 259 752 259 761 259 778 259 802 259 815 259 871 259 892 259 905 259 1113 259 1212 259 1214 259 1221 259 1330 259 1343 259 1382 259 1400 259 1413 259 1419 259 1442 259 1455 259 1463 259 1486 260 1 260 100 260 260 260 265 260 393 260 417 260 421 260 445 260 487 260 596 260 616 260 672 260 712 260 717 260 754 260 762 260 806 260 856 260 922 260 1042 260 1074 260 1077 260 1139 260 1195 260 1226 260 1315 260 1317 260 1337 260 1342 260 1387 260 1397 260 1428 260 1438 260 1453 260 1470 261 24 261 38 261 66 261 96 261 116 261 129 261 131 261 137 261 145 261 174 261 175 261 180 261 192 261 261 261 304 261 322 261 323 261 356 261 394 261 431 261 479 261 539 261 576 261 590 261 705 261 714 261 767 261 792 261 881 261 885 261 887 261 942 261 944 261 969 261 980 261 985 261 992 261 1017 261 1047 261 1067 261 1072 261 1089 261 1125 261 1141 261 1155 261 1173 261 1178 261 1209 261 1244 261 1261 261 1353 261 1359 261 1372 261 1401 261 1411 262 38 262 53 262 54 262 90 262 121 262 158 262 182 262 221 262 229 262 257 262 262 262 323 262 351 262 428 262 431 262 451 262 462 262 490 262 506 262 511 262 534 262 536 262 610 262 618 262 637 262 698 262 701 262 702 262 808 262 823 262 827 262 864 262 1003 262 1044 262 1065 262 1084 262 1144 262 1183 262 1187 262 1219 262 1249 262 1258 262 1334 262 1360 262 1415 262 1448 263 27 263 42 263 66 263 96 263 162 263 172 263 263 263 283 263 322 263 328 263 356 263 394 263 479 263 486 263 498 263 501 263 575 263 576 263 580 263 625 263 634 263 649 263 714 263 715 263 726 263 746 263 757 263 786 263 810 263 830 263 879 263 887 263 921 263 942 263 961 263 969 263 1007 263 1016 263 1072 263 1125 263 1140 263 1160 263 1173 263 1209 263 1213 263 1316 264 98 264 151 264 185 264 186 264 238 264 244 264 251 264 264 264 267 264 281 264 288 264 298 264 301 264 338 264 358 264 359 264 398 264 436 264 442 264 475 264 480 264 518 264 546 264 597 264 598 264 645 264 650 264 674 264 699 264 721 264 758 264 771 264 803 264 817 264 824 264 895 264 996 264 1009 264 1011 264 1079 264 1085 264 1145 264 1147 264 1204 264 1218 264 1266 264 1271 264 1305 264 1318 264 1371 264 1412 264 1413 265 1 265 100 265 179 265 246 265 260 265 265 265 310 265 417 265 421 265 550 265 596 265 616 265 672 265 717 265 754 265 762 265 806 265 850 265 855 265 856 265 894 265 932 265 945 265 963 265 974 265 1074 265 1094 265 1158 265 1195 265 1226 265 1317 265 1335 265 1337 265 1342 265 1397 265 1453 265 1473 266 22 266 107 266 143 266 156 266 196 266 266 266 345 266 378 266 396 266 400 266 403 266 449 266 507 266 530 266 543 266 558 266 570 266 583 266 604 266 605 266 607 266 613 266 621 266 669 266 707 266 739 266 791 266 854 266 862 266 873 266 900 266 903 266 920 266 935 266 937 266 947 266 948 266 994 266 1005 266 1037 266 1071 266 1090 266 1126 266 1162 266 1176 266 1224 266 1267 266 1289 266 1324 266 1325 266 1326 266 1386 266 1444 266 1464 267 26 267 28 267 89 267 116 267 138 267 264 267 267 267 318 267 332 267 355 267 425 267 436 267 470 267 475 267 482 267 552 267 598 267 646 267 674 267 708 267 753 267 755 267 817 267 832 267 895 267 896 267 921 267 931 267 965 267 979 267 986 267 995 267 1009 267 1079 267 1204 267 1314 267 1316 267 1321 267 1392 267 1403 267 1449 267 1467 267 1471 267 1485 268 6 268 45 268 89 268 124 268 268 268 283 268 286 268 328 268 399 268 470 268 575 268 652 268 678 268 689 268 722 268 769 268 786 268 795 268 810 268 865 268 896 268 921 268 950 268 968 268 969 268 1007 268 1039 268 1059 268 1140 268 1160 268 1349 268 1425 268 1446 268 1499 269 129 269 137 269 216 269 269 269 340 269 352 269 506 269 745 269 851 269 983 269 1017 269 1067 269 1089 269 1155 269 1178 269 1187 269 1234 269 1359 269 1415 270 30 270 53 270 73 270 78 270 90 270 102 270 130 270 152 270 191 270 212 270 270 270 286 270 308 270 332 270 338 270 451 270 460 270 506 270 511 270 537 270 549 270 563 270 610 270 637 270 655 270 685 270 702 270 752 270 761 270 778 270 785 270 812 270 815 270 829 270 863 270 884 270 905 270 923 270 967 270 1003 270 1057 270 1065 270 1084 270 1141 270 1219 270 1334 270 1336 270 1390 270 1400 270 1413 270 1418 270 1459 270 1481 271 74 271 84 271 93 271 95 271 120 271 126 271 201 271 231 271 239 271 241 271 271 271 282 271 293 271 311 271 315 271 361 271 515 271 564 271 677 271 719 271 801 271 858 271 971 271 975 271 1023 271 1058 271 1116 271 1157 271 1248 271 1280 271 1282 271 1307 271 1354 271 1377 271 1394 271 1395 271 1424 271 1435 272 14 272 47 272 63 272 92 272 125 272 160 272 189 272 202 272 230 272 240 272 272 272 279 272 295 272 373 272 387 272 404 272 483 272 556 272 569 272 600 272 611 272 612 272 624 272 630 272 640 272 690 272 694 272 743 272 809 272 882 272 888 272 910 272 911 272 999 272 1014 272 1069 272 1075 272 1082 272 1097 272 1099 272 1196 272 1277 272 1355 272 1461 272 1472 272 1476 272 1484 273 70 273 108 273 146 273 256 273 273 273 303 273 363 273 438 273 512 273 523 273 635 273 692 273 722 273 731 273 780 273 803 273 845 273 872 273 894 273 1004 273 1031 273 1228 273 1263 273 1363 273 1399 273 1447 273 1466 273 1488 274 16 274 32 274 34 274 40 274 71 274 136 274 150 274 159 274 177 274 207 274 213 274 237 274 252 274 274 274 297 274 307 274 317 274 390 274 432 274 439 274 453 274 469 274 495 274 588 274 641 274 738 274 744 274 813 274 848 274 853 274 869 274 936 274 964 274 1005 274 1041 274 1053 274 1073 274 1110 274 1130 274 1237 274 1252 274 1262 274 1274 274 1296 274 1322 274 1347 274 1416 274 1422 274 1480 274 1493 275 95 275 113 275 117 275 120 275 132 275 194 275 201 275 239 275 241 275 275 275 293 275 311 275 315 275 324 275 353 275 361 275 372 275 384 275 515 275 554 275 564 275 647 275 675 275 677 275 719 275 793 275 858 275 971 275 975 275 982 275 1036 275 1056 275 1105 275 1116 275 1232 275 1248 275 1253 275 1282 275 1302 275 1307 275 1377 275 1424 276 11 276 21 276 48 276 80 276 94 276 179 276 225 276 226 276 245 276 251 276 276 276 310 276 339 276 347 276 358 276 406 276 412 276 437 276 496 276 509 276 513 276 535 276 545 276 664 276 713 276 768 276 790 276 821 276 828 276 912 276 929 276 949 276 952 276 1011 276 1032 276 1033 276 1045 276 1052 276 1055 276 1063 276 1158 276 1170 276 1181 276 1201 276 1208 276 1215 276 1241 276 1251 276 1288 276 1363 277 86 277 193 277 200 277 206 277 211 277 250 277 277 277 332 277 348 277 405 277 440 277 444 277 451 277 561 277 563 277 579 277 580 277 626 277 652 277 658 277 720 277 846 277 863 277 874 277 901 277 1024 277 1131 277 1135 277 1137 277 1283 277 1309 277 1341 277 1351 277 1475 277 1494 278 21 278 41 278 51 278 80 278 151 278 179 278 186 278 199 278 225 278 245 278 278 278 318 278 339 278 347 278 367 278 412 278 419 278 437 278 496 278 509 278 521 278 545 278 597 278 661 278 664 278 665 278 682 278 686 278 699 278 713 278 729 278 821 278 828 278 845 278 855 278 880 278 912 278 949 278 950 278 952 278 1011 278 1022 278 1033 278 1045 278 1063 278 1086 278 1152 278 1163 278 1190 278 1197 278 1208 278 1239 278 1288 278 1399 278 1417 278 1487 279 14 279 47 279 79 279 125 279 160 279 223 279 230 279 272 279 279 279 295 279 371 279 373 279 387 279 389 279 391 279 408 279 478 279 483 279 484 279 526 279 567 279 592 279 600 279 606 279 624 279 638 279 640 279 680 279 690 279 784 279 809 279 814 279 822 279 839 279 844 279 867 279 888 279 910 279 940 279 972 279 978 279 1018 279 1068 279 1075 279 1078 279 1082 279 1097 279 1098 279 1099 279 1142 279 1180 279 1196 279 1206 279 1216 279 1229 279 1236 279 1277 279 1281 279 1356 279 1361 279 1373 279 1375 279 1407 279 1441 279 1484 279 1498 280 39 280 43 280 60 280 77 280 112 280 154 280 208 280 215 280 280 280 287 280 385 280 410 280 456 280 541 280 633 280 724 280 747 280 779 280 861 280 878 280 891 280 902 280 927 280 954 280 976 280 989 280 1013 280 1025 280 1030 280 1128 280 1148 280 1150 280 1207 280 1210 280 1279 280 1295 280 1301 280 1310 280 1439 281 51 281 70 281 98 281 133 281 151 281 186 281 199 281 238 281 251 281 256 281 264 281 281 281 298 281 301 281 303 281 358 281 367 281 398 281 437 281 438 281 442 281 475 281 480 281 518 281 540 281 594 281 661 281 674 281 722 281 729 281 731 281 768 281 803 281 824 281 949 281 1011 281 1031 281 1032 281 1060 281 1085 281 1086 281 1147 281 1208 281 1263 281 1266 281 1271 281 1305 281 1412 281 1417 281 1487 281 1488 282 2 282 93 282 95 282 111 282 113 282 117 282 126 282 153 282 194 282 227 282 231 282 239 282 241 282 247 282 271 282 282 282 296 282 311 282 362 282 450 282 454 282 463 282 515 282 516 282 564 282 796 282 801 282 838 282 858 282 970 282 975 282 982 282 1001 282 1002 282 1036 282 1050 282 1056 282 1105 282 1116 282 1119 282 1122 282 1194 282 1248 282 1253 282 1256 282 1280 282 1282 282 1298 282 1354 282 1394 282 1396 282 1478 283 17 283 244 283 263 283 268 283 283 283 304 283 322 283 328 283 349 283 355 283 382 283 394 283 395 283 399 283 464 283 575 283 580 283 625 283 629 283 631 283 634 283 652 283 681 283 695 283 708 283 767 283 786 283 795 283 810 283 830 283 865 283 896 283 921 283 969 283 980 283 1007 283 1039 283 1059 283 1125 283 1140 283 1199 283 1316 283 1351 283 1378 283 1468 283 1499 284 35 284 41 284 199 284 235 284 246 284 284 284 313 284 321 284 374 284 380 284 382 284 459 284 510 284 540 284 577 284 594 284 726 284 772 284 781 284 782 284 790 284 852 284 929 284 963 284 974 284 1048 284 1077 284 1094 284 1152 284 1158 284 1164 284 1223 284 1226 284 1251 284 1304 285 9 285 15 285 54 285 73 285 90 285 121 285 205 285 221 285 229 285 259 285 285 285 351 285 381 285 462 285 485 285 490 285 536 285 618 285 619 285 655 285 685 285 698 285 701 285 734 285 735 285 802 285 823 285 827 285 837 285 864 285 1044 285 1118 285 1144 285 1153 285 1183 285 1221 285 1258 285 1340 285 1343 285 1360 285 1382 285 1442 285 1448 285 1452 285 1455 285 1463 286 30 286 78 286 130 286 212 286 268 286 270 286 286 286 308 286 328 286 349 286 399 286 460 286 464 286 511 286 549 286 580 286 623 286 631 286 652 286 752 286 769 286 778 286 795 286 815 286 829 286 905 286 923 286 967 286 1046 286 1057 286 1059 286 1084 286 1131 286 1140 286 1238 286 1249 286 1336 286 1351 286 1390 286 1415 286 1418 286 1459 286 1481 286 1499 287 43 287 60 287 118 287 154 287 176 287 280 287 287 287 369 287 385 287 456 287 532 287 541 287 557 287 565 287 633 287 651 287 724 287 747 287 779 287 861 287 891 287 902 287 927 287 957 287 976 287 1013 287 1030 287 1150 287 1210 287 1243 287 1279 287 1295 287 1366 287 1380 287 1489 288 19 288 185 288 259 288 264 288 288 288 359 288 398 288 436 288 546 288 560 288 587 288 598 288 645 288 650 288 683 288 758 288 765 288 802 288 842 288 871 288 892 288 895 288 1079 288 1197 288 1214 288 1218 288 1242 288 1412 288 1419 288 1440 288 1442 289 27 289 127 289 228 289 243 289 289 289 459 289 501 289 679 289 726 289 741 289 775 289 789 289 797 289 830 289 879 289 909 289 925 289 946 289 988 289 1077 289 1111 289 1213 289 1372 289 1392 289 1410 289 1414 289 1446 289 1470 290 10 290 23 290 37 290 49 290 75 290 128 290 198 290 290 290 357 290 360 290 376 290 402 290 443 290 551 290 555 290 559 290 574 290 582 290 657 290 673 290 756 290 770 290 800 290 805 290 916 290 933 290 955 290 1020 290 1101 290 1166 290 1189 290 1203 290 1364 290 1429 290 1433 290 1460 290 1483 291 5 291 13 291 14 291 36 291 47 291 55 291 65 291 85 291 92 291 101 291 218 291 230 291 234 291 291 291 365 291 377 291 434 291 441 291 452 291 492 291 524 291 528 291 547 291 562 291 603 291 608 291 609 291 612 291 620 291 630 291 648 291 667 291 730 291 867 291 870 291 882 291 883 291 939 291 1018 291 1076 291 1091 291 1098 291 1129 291 1159 291 1225 291 1291 291 1331 291 1369 291 1373 291 1472 291 1496 292 7 292 20 292 31 292 75 292 87 292 148 292 167 292 203 292 204 292 219 292 242 292 292 292 294 292 300 292 333 292 336 292 403 292 446 292 449 292 530 292 583 292 671 292 703 292 873 292 903 292 948 292 987 292 1038 292 1071 292 1106 292 1156 292 1161 292 1169 292 1171 292 1184 292 1188 292 1211 292 1224 292 1287 292 1326 292 1404 292 1450 292 1458 292 1464 292 1490 293 74 293 84 293 113 293 120 293 132 293 201 293 239 293 241 293 271 293 275 293 293 293 311 293 315 293 353 293 361 293 372 293 488 293 515 293 554 293 566 293 647 293 677 293 719 293 793 293 818 293 858 293 971 293 1006 293 1023 293 1056 293 1058 293 1157 293 1192 293 1232 293 1253 293 1282 293 1307 293 1377 293 1424 293 1435 294 50 294 68 294 75 294 87 294 141 294 195 294 203 294 204 294 292 294 294 294 300 294 314 294 333 294 336 294 357 294 368 294 433 294 514 294 538 294 571 294 657 294 671 294 697 294 836 294 916 294 930 294 1029 294 1088 294 1100 294 1169 294 1188 294 1203 294 1300 294 1364 294 1379 294 1404 294 1458 294 1460 294 1490 295 14 295 47 295 79 295 125 295 144 295 189 295 223 295 272 295 279 295 295 295 371 295 373 295 387 295 401 295 404 295 408 295 478 295 483 295 526 295 600 295 611 295 612 295 624 295 640 295 680 295 690 295 694 295 784 295 814 295 822 295 839 295 888 295 910 295 911 295 940 295 978 295 990 295 999 295 1014 295 1018 295 1068 295 1069 295 1075 295 1082 295 1097 295 1099 295 1142 295 1196 295 1216 295 1229 295 1236 295 1277 295 1281 295 1290 295 1355 295 1370 295 1375 295 1407 295 1441 295 1484 295 1498 296 2 296 93 296 95 296 97 296 126 296 153 296 183 296 231 296 247 296 282 296 296 296 362 296 407 296 463 296 499 296 516 296 564 296 614 296 628 296 654 296 662 296 801 296 838 296 951 296 970 296 975 296 1001 296 1002 296 1036 296 1050 296 1105 296 1119 296 1122 296 1132 296 1194 296 1227 296 1280 296 1329 296 1354 296 1384 296 1394 296 1396 296 1478 297 16 297 71 297 136 297 150 297 177 297 207 297 213 297 248 297 252 297 274 297 297 297 317 297 390 297 423 297 432 297 469 297 548 297 588 297 632 297 641 297 706 297 738 297 744 297 848 297 889 297 936 297 964 297 977 297 1041 297 1053 297 1073 297 1130 297 1252 297 1255 297 1274 297 1284 297 1322 297 1328 297 1416 297 1422 297 1480 298 0 298 114 298 119 298 186 298 197 298 220 298 238 298 264 298 281 298 298 298 301 298 303 298 327 298 330 298 338 298 358 298 442 298 518 298 663 298 721 298 729 298 731 298 765 298 771 298 794 298 803 298 824 298 866 298 892 298 983 298 996 298 1011 298 1031 298 1052 298 1085 298 1124 298 1145 298 1147 298 1222 298 1228 298 1260 298 1266 298 1271 298 1305 298 1371 298 1400 298 1412 298 1488 299 10 299 33 299 50 299 61 299 68 299 141 299 155 299 169 299 195 299 210 299 299 299 300 299 342 299 364 299 379 299 447 299 458 299 493 299 504 299 514 299 559 299 571 299 578 299 704 299 749 299 811 299 904 299 913 299 915 299 930 299 956 299 1088 299 1109 299 1168 299 1189 299 1269 299 1275 299 1300 299 1312 299 1338 299 1374 299 1420 299 1437 299 1460 300 20 300 50 300 68 300 75 300 87 300 141 300 203 300 204 300 292 300 294 300 299 300 300 300 314 300 333 300 336 300 357 300 368 300 433 300 514 300 538 300 559 300 571 300 627 300 657 300 671 300 703 300 916 300 930 300 1029 300 1088 300 1100 300 1106 300 1169 300 1171 300 1188 300 1203 300 1300 300 1402 300 1404 300 1458 300 1460 300 1462 300 1490 301 0 301 98 301 114 301 151 301 185 301 186 301 197 301 220 301 235 301 238 301 251 301 264 301 281 301 298 301 301 301 303 301 358 301 442 301 480 301 518 301 546 301 597 301 645 301 663 301 674 301 689 301 699 301 721 301 729 301 771 301 803 301 824 301 995 301 996 301 1011 301 1031 301 1085 301 1145 301 1147 301 1266 301 1271 301 1305 301 1371 301 1400 302 39 302 112 302 166 302 168 302 208 302 215 302 254 302 302 302 409 302 410 302 426 302 633 302 710 302 899 302 954 302 976 302 989 302 1030 302 1134 302 1207 302 1233 302 1301 302 1310 302 1319 302 1405 303 6 303 25 303 42 303 45 303 48 303 70 303 108 303 186 303 238 303 256 303 273 303 281 303 298 303 301 303 303 303 339 303 367 303 438 303 512 303 575 303 635 303 722 303 729 303 731 303 782 303 794 303 803 303 810 303 824 303 961 303 996 303 1011 303 1031 303 1052 303 1085 303 1086 303 1147 303 1163 303 1201 303 1208 303 1228 303 1239 303 1263 303 1305 303 1362 303 1363 303 1399 303 1488 303 1499 304 17 304 129 304 133 304 172 304 180 304 255 304 261 304 283 304 304 304 322 304 328 304 363 304 394 304 395 304 399 304 522 304 537 304 575 304 590 304 594 304 634 304 681 304 695 304 767 304 776 304 786 304 795 304 884 304 969 304 980 304 992 304 1039 304 1125 304 1140 304 1141 304 1199 304 1209 304 1261 304 1351 304 1359 304 1468 305 47 305 76 305 83 305 135 305 189 305 217 305 232 305 253 305 305 305 344 305 455 305 478 305 591 305 612 305 684 305 690 305 743 305 807 305 814 305 822 305 839 305 860 305 940 305 978 305 990 305 1014 305 1018 305 1142 305 1180 305 1206 305 1216 305 1217 305 1235 305 1250 305 1290 305 1355 305 1356 305 1358 305 1370 305 1375 305 1498 306 74 306 88 306 95 306 113 306 132 306 173 306 201 306 227 306 231 306 239 306 241 306 306 306 386 306 420 306 461 306 471 306 488 306 515 306 525 306 553 306 554 306 566 306 659 306 668 306 696 306 723 306 748 306 798 306 804 306 818 306 858 306 924 306 975 306 1002 306 1096 306 1116 306 1122 306 1157 306 1192 306 1232 306 1248 306 1254 306 1259 306 1272 306 1280 306 1285 306 1303 306 1329 306 1391 307 32 307 34 307 40 307 115 307 139 307 207 307 237 307 274 307 307 307 366 307 439 307 453 307 495 307 744 307 813 307 833 307 835 307 848 307 853 307 859 307 868 307 869 307 926 307 1041 307 1061 307 1103 307 1110 307 1138 307 1237 307 1245 307 1247 307 1262 307 1276 307 1296 307 1347 307 1376 307 1381 307 1406 307 1482 308 53 308 78 308 82 308 102 308 130 308 191 308 200 308 211 308 270 308 286 308 308 308 348 308 349 308 399 308 428 308 451 308 460 308 511 308 549 308 579 308 610 308 626 308 631 308 658 308 685 308 702 308 752 308 761 308 812 308 829 308 846 308 863 308 884 308 901 308 923 308 1003 308 1057 308 1065 308 1066 308 1084 308 1131 308 1135 308 1137 308 1183 308 1418 308 1459 308 1475 308 1481 309 43 309 46 309 104 309 105 309 109 309 118 309 176 309 258 309 309 309 369 309 409 309 500 309 532 309 557 309 565 309 651 309 710 309 724 309 779 309 826 309 899 309 917 309 927 309 954 309 957 309 1030 309 1114 309 1128 309 1182 309 1243 309 1264 309 1279 309 1366 309 1368 309 1380 310 11 310 48 310 94 310 163 310 179 310 226 310 245 310 246 310 249 310 265 310 276 310 310 310 320 310 339 310 406 310 415 310 523 310 596 310 616 310 653 310 664 310 688 310 713 310 740 310 754 310 762 310 768 310 855 310 880 310 894 310 932 310 945 310 952 310 963 310 974 310 1022 310 1032 310 1045 310 1063 310 1081 310 1094 310 1139 310 1158 310 1163 310 1170 310 1181 310 1201 310 1239 310 1288 310 1335 310 1362 310 1453 311 84 311 93 311 95 311 120 311 194 311 201 311 231 311 239 311 241 311 271 311 275 311 282 311 293 311 311 311 315 311 361 311 372 311 450 311 515 311 564 311 647 311 677 311 719 311 858 311 971 311 975 311 1023 311 1036 311 1058 311 1116 311 1157 311 1248 311 1253 311 1280 311 1282 311 1307 311 1377 311 1394 311 1395 311 1424 311 1435 312 26 312 54 312 102 312 121 312 130 312 200 312 205 312 222 312 259 312 312 312 436 312 465 312 536 312 560 312 579 312 685 312 734 312 758 312 771 312 778 312 802 312 815 312 866 312 871 312 892 312 897 312 934 312 959 312 1035 312 1054 312 1066 312 1102 312 1113 312 1118 312 1124 312 1135 312 1212 312 1214 312 1221 312 1327 312 1330 312 1340 312 1343 312 1382 312 1400 312 1413 312 1419 312 1442 312 1463 312 1486 313 35 313 48 313 108 313 140 313 172 313 284 313 313 313 363 313 374 313 382 313 406 313 411 313 413 313 498 313 531 313 540 313 577 313 718 313 772 313 781 313 782 313 786 313 852 313 881 313 961 313 974 313 998 313 1049 313 1094 313 1123 313 1158 313 1164 313 1177 313 1223 313 1251 313 1292 313 1362 313 1363 314 50 314 68 314 75 314 141 314 195 314 210 314 294 314 300 314 314 314 333 314 342 314 357 314 368 314 379 314 433 314 504 314 514 314 538 314 571 314 627 314 666 314 697 314 704 314 811 314 904 314 916 314 930 314 1008 314 1029 314 1088 314 1100 314 1109 314 1203 314 1269 314 1300 314 1312 314 1338 314 1352 314 1374 314 1420 314 1437 314 1460 314 1495 315 74 315 84 315 93 315 95 315 113 315 120 315 201 315 231 315 239 315 241 315 271 315 275 315 293 315 311 315 315 315 384 315 450 315 463 315 488 315 515 315 554 315 564 315 675 315 719 315 801 315 838 315 858 315 971 315 975 315 1001 315 1023 315 1036 315 1050 315 1058 315 1116 315 1119 315 1122 315 1157 315 1248 315 1253 315 1280 315 1307 315 1354 315 1394 315 1395 315 1424 315 1435 316 142 316 157 316 316 316 709 316 819 316 877 316 914 316 1043 316 1121 316 1430 317 16 317 32 317 34 317 40 317 136 317 150 317 171 317 207 317 213 317 237 317 248 317 252 317 274 317 297 317 317 317 423 317 432 317 439 317 453 317 495 317 588 317 641 317 706 317 738 317 744 317 835 317 848 317 853 317 868 317 889 317 926 317 936 317 964 317 1041 317 1073 317 1130 317 1138 317 1237 317 1247 317 1255 317 1262 317 1274 317 1284 317 1296 317 1322 317 1328 317 1381 318 80 318 81 318 138 318 151 318 245 318 251 318 267 318 278 318 318 318 329 318 347 318 437 318 470 318 494 318 496 318 510 318 513 318 535 318 665 318 674 318 676 318 683 318 686 318 689 318 699 318 760 318 787 318 817 318 834 318 925 318 949 318 950 318 965 318 979 318 986 318 1009 318 1048 318 1070 318 1190 318 1215 318 1286 318 1304 318 1392 318 1408 318 1425 318 1445 318 1449 318 1465 318 1471 319 122 319 167 319 178 319 219 319 319 319 360 319 416 319 418 319 422 319 457 319 468 319 555 319 589 319 593 319 617 319 622 319 644 319 725 319 732 319 750 319 766 319 777 319 800 319 886 319 933 319 997 319 1010 319 1015 319 1087 319 1101 319 1112 319 1166 319 1185 319 1200 319 1205 319 1257 319 1268 319 1311 319 1346 319 1388 319 1426 319 1479 319 1492 320 100 320 140 320 163 320 226 320 246 320 310 320 320 320 393 320 417 320 445 320 596 320 616 320 653 320 672 320 688 320 712 320 740 320 754 320 762 320 772 320 806 320 855 320 856 320 880 320 932 320 945 320 963 320 974 320 998 320 1004 320 1042 320 1045 320 1049 320 1094 320 1139 320 1158 320 1163 320 1177 320 1181 320 1239 320 1306 320 1387 320 1438 320 1453 320 1470 320 1473 321 35 321 45 321 51 321 94 321 124 321 140 321 235 321 284 321 321 321 363 321 374 321 380 321 382 321 393 321 501 321 540 321 552 321 577 321 594 321 695 321 713 321 753 321 772 321 781 321 782 321 797 321 810 321 832 321 852 321 885 321 918 321 929 321 991 321 1120 321 1158 321 1208 321 1223 321 1251 321 1292 321 1339 321 1362 322 17 322 38 322 66 322 96 322 129 322 131 322 137 322 162 322 172 322 174 322 180 322 192 322 255 322 261 322 263 322 283 322 304 322 322 322 328 322 349 322 352 322 354 322 356 322 394 322 395 322 399 322 440 322 464 322 479 322 539 322 552 322 561 322 576 322 580 322 590 322 631 322 634 322 652 322 695 322 711 322 720 322 767 322 786 322 792 322 881 322 887 322 942 322 944 322 969 322 980 322 992 322 1047 322 1089 322 1092 322 1125 322 1140 322 1141 322 1173 322 1209 322 1238 322 1244 322 1261 322 1283 322 1332 322 1351 322 1353 322 1359 323 24 323 90 323 137 323 193 323 222 323 261 323 262 323 323 323 327 323 425 323 431 323 506 323 536 323 539 323 701 323 702 323 734 323 769 323 785 323 885 323 944 323 1003 323 1035 323 1064 323 1118 323 1135 323 1165 323 1178 323 1187 323 1219 323 1234 323 1238 323 1244 323 1334 323 1341 323 1353 323 1390 323 1401 323 1459 323 1486 324 74 324 113 324 132 324 201 324 227 324 241 324 275 324 324 324 386 324 420 324 474 324 515 324 581 324 659 324 677 324 728 324 737 324 788 324 798 324 818 324 1006 324 1093 324 1104 324 1116 324 1232 324 1259 324 1293 324 1391 325 24 325 116 325 145 325 174 325 180 325 206 325 325 325 348 325 429 325 431 325 444 325 522 325 539 325 552 325 568 325 576 325 580 325 590 325 646 325 652 325 708 325 714 325 769 325 771 325 776 325 885 325 897 325 944 325 980 325 985 325 992 325 1007 325 1046 325 1178 325 1204 325 1244 325 1261 325 1316 325 1339 325 1403 326 91 326 143 326 167 326 178 326 219 326 326 326 350 326 378 326 416 326 418 326 422 326 446 326 508 326 555 326 617 326 622 326 636 326 644 326 732 326 777 326 800 326 928 326 933 326 935 326 958 326 962 326 997 326 1010 326 1015 326 1087 326 1146 326 1154 326 1167 326 1200 326 1205 326 1211 326 1257 326 1268 326 1289 326 1294 326 1311 326 1326 326 1346 326 1388 326 1431 326 1479 327 24 327 26 327 90 327 222 327 298 327 323 327 327 327 425 327 436 327 442 327 465 327 475 327 518 327 629 327 701 327 734 327 758 327 771 327 824 327 866 327 934 327 1035 327 1085 327 1118 327 1124 327 1145 327 1147 327 1204 327 1266 327 1327 327 1400 327 1468 328 27 328 66 328 96 328 162 328 255 328 263 328 268 328 283 328 286 328 304 328 322 328 328 328 349 328 354 328 394 328 395 328 399 328 464 328 576 328 580 328 590 328 631 328 634 328 652 328 711 328 720 328 767 328 769 328 786 328 789 328 792 328 887 328 969 328 992 328 1059 328 1125 328 1140 328 1209 328 1238 328 1351 328 1414 328 1446 328 1499 329 81 329 99 329 106 329 225 329 226 329 245 329 249 329 318 329 329 329 337 329 347 329 393 329 417 329 445 329 487 329 510 329 535 329 550 329 585 329 596 329 602 329 653 329 656 329 754 329 762 329 820 329 922 329 968 329 979 329 1000 329 1042 329 1045 329 1070 329 1077 329 1175 329 1190 329 1241 329 1286 329 1288 329 1315 329 1317 329 1408 329 1428 329 1445 329 1449 329 1470 329 1471 330 8 330 19 330 69 330 119 330 152 330 197 330 298 330 330 330 338 330 427 330 442 330 518 330 599 330 628 330 655 330 765 330 794 330 866 330 892 330 951 330 1085 330 1133 330 1145 330 1147 330 1214 330 1222 330 1260 330 1371 330 1400 330 1412 330 1419 330 1455 331 4 331 71 331 155 331 248 331 331 331 469 331 519 331 632 331 716 331 738 331 977 331 1053 331 1073 331 1357 331 1367 331 1416 331 1423 331 1451 331 1480 332 26 332 53 332 78 332 82 332 86 332 102 332 191 332 193 332 200 332 211 332 233 332 250 332 267 332 270 332 277 332 332 332 355 332 405 332 451 332 537 332 563 332 579 332 626 332 658 332 755 332 812 332 846 332 863 332 884 332 901 332 934 332 959 332 1003 332 1024 332 1035 332 1054 332 1066 332 1135 332 1137 332 1204 332 1309 332 1314 332 1327 332 1341 332 1459 332 1467 332 1475 332 1485 332 1494 333 20 333 31 333 50 333 68 333 75 333 123 333 141 333 148 333 198 333 203 333 204 333 242 333 292 333 294 333 300 333 314 333 333 333 336 333 357 333 368 333 402 333 433 333 538 333 571 333 671 333 673 333 703 333 756 333 916 333 1088 333 1106 333 1112 333 1171 333 1184 333 1188 333 1203 333 1224 333 1300 333 1402 333 1404 333 1462 333 1490 334 84 334 88 334 166 334 173 334 209 334 334 334 420 334 426 334 461 334 471 334 472 334 477 334 488 334 489 334 553 334 554 334 572 334 659 334 675 334 696 334 710 334 723 334 818 334 899 334 917 334 924 334 1051 334 1062 334 1080 334 1096 334 1104 334 1115 334 1143 334 1191 334 1192 334 1254 334 1285 334 1293 334 1303 334 1405 334 1427 334 1469 335 59 335 67 335 161 335 190 335 335 335 414 335 435 335 774 335 840 335 857 335 1021 335 1231 335 1320 335 1365 335 1409 335 1432 335 1443 335 1454 335 1477 335 1491 335 1497 336 7 336 20 336 31 336 87 336 123 336 148 336 204 336 242 336 292 336 294 336 300 336 333 336 336 336 403 336 449 336 519 336 530 336 538 336 548 336 607 336 671 336 703 336 763 336 873 336 900 336 948 336 1005 336 1106 336 1161 336 1171 336 1184 336 1188 336 1224 336 1289 336 1326 336 1402 336 1404 336 1458 336 1464 336 1490 337 81 337 99 337 134 337 140 337 228 337 245 337 249 337 329 337 337 337 393 337 417 337 421 337 445 337 487 337 510 337 513 337 535 337 585 337 596 337 602 337 717 337 754 337 762 337 775 337 797 337 820 337 834 337 890 337 918 337 922 337 946 337 950 337 968 337 1000 337 1042 337 1048 337 1070 337 1077 337 1139 337 1190 337 1226 337 1241 337 1251 337 1286 337 1315 337 1408 337 1428 337 1445 337 1453 337 1470 337 1471 338 0 338 19 338 73 338 130 338 152 338 197 338 200 338 205 338 259 338 264 338 270 338 298 338 330 338 338 338 442 338 465 338 475 338 518 338 549 338 560 338 587 338 655 338 734 338 752 338 761 338 765 338 771 338 778 338 802 338 815 338 824 338 871 338 884 338 892 338 905 338 967 338 983 338 1085 338 1124 338 1145 338 1147 338 1212 338 1214 338 1266 338 1271 338 1305 338 1330 338 1343 338 1382 338 1400 338 1412 338 1413 339 11 339 21 339 29 339 41 339 48 339 70 339 80 339 94 339 151 339 179 339 199 339 225 339 245 339 256 339 276 339 278 339 303 339 310 339 339 339 347 339 380 339 419 339 437 339 459 339 496 339 509 339 545 339 635 339 664 339 665 339 682 339 713 339 760 339 768 339 782 339 787 339 790 339 810 339 821 339 828 339 845 339 880 339 912 339 929 339 949 339 950 339 952 339 1032 339 1033 339 1045 339 1052 339 1063 339 1081 339 1086 339 1152 339 1163 339 1170 339 1181 339 1190 339 1201 339 1208 339 1239 339 1241 339 1251 339 1288 339 1304 339 1335 339 1362 339 1399 339 1417 339 1465 340 129 340 180 340 192 340 255 340 269 340 340 340 352 340 394 340 395 340 506 340 590 340 700 340 745 340 767 340 769 340 851 340 969 340 1067 340 1089 340 1125 340 1155 340 1178 340 1187 340 1333 340 1415 340 1499 341 33 341 61 341 103 341 110 341 210 341 341 341 342 341 364 341 379 341 447 341 458 341 493 341 504 341 542 341 578 341 586 341 601 341 643 341 687 341 704 341 749 341 811 341 904 341 913 341 915 341 943 341 956 341 1095 341 1109 341 1168 341 1189 341 1269 341 1297 341 1312 341 1338 341 1420 341 1421 341 1437 341 1495 342 33 342 61 342 110 342 141 342 169 342 195 342 210 342 299 342 314 342 341 342 342 342 364 342 379 342 447 342 458 342 493 342 504 342 514 342 571 342 578 342 586 342 687 342 704 342 749 342 773 342 811 342 843 342 904 342 913 342 915 342 941 342 943 342 956 342 1008 342 1109 342 1168 342 1189 342 1269 342 1275 342 1312 342 1338 342 1345 342 1374 342 1420 342 1421 342 1437 342 1495 343 56 343 72 343 135 343 164 343 217 343 223 343 224 343 232 343 343 343 371 343 389 343 391 343 408 343 478 343 497 343 524 343 547 343 584 343 592 343 638 343 814 343 844 343 860 343 906 343 908 343 972 343 1034 343 1068 343 1078 343 1099 343 1142 343 1179 343 1180 343 1198 343 1229 343 1230 343 1299 343 1361 343 1373 343 1407 343 1441 343 1474 343 1496 344 44 344 57 344 147 344 149 344 189 344 253 344 305 344 344 344 375 344 388 344 397 344 404 344 491 344 556 344 591 344 684 344 733 344 743 344 799 344 807 344 860 344 893 344 990 344 993 344 1027 344 1069 344 1082 344 1136 344 1202 344 1217 344 1235 344 1250 344 1278 344 1355 344 1358 344 1375 344 1456 345 156 345 159 345 196 345 266 345 345 345 383 345 396 345 400 345 448 345 543 345 605 345 615 345 707 345 739 345 764 345 847 345 862 345 920 345 947 345 960 345 994 345 1037 345 1090 345 1126 345 1127 345 1172 345 1267 345 1324 345 1325 345 1386 345 1434 345 1436 345 1493 346 39 346 62 346 77 346 104 346 105 346 109 346 112 346 168 346 215 346 258 346 346 346 409 346 489 346 500 346 826 346 878 346 899 346 917 346 954 346 1025 346 1080 346 1104 346 1114 346 1128 346 1134 346 1148 346 1149 346 1207 346 1233 346 1270 346 1301 346 1310 346 1319 346 1350 346 1368 346 1383 347 11 347 81 347 106 347 151 347 225 347 276 347 278 347 318 347 329 347 339 347 347 347 419 347 430 347 437 347 496 347 509 347 510 347 513 347 529 347 535 347 545 347 665 347 682 347 699 347 713 347 760 347 787 347 820 347 821 347 828 347 912 347 949 347 950 347 986 347 996 347 1019 347 1033 347 1063 347 1070 347 1170 347 1175 347 1215 347 1241 347 1304 347 1408 347 1449 347 1465 347 1471 348 53 348 78 348 180 348 193 348 206 348 211 348 277 348 308 348 325 348 348 348 349 348 399 348 405 348 425 348 431 348 444 348 451 348 522 348 537 348 579 348 580 348 610 348 625 348 626 348 629 348 631 348 652 348 702 348 769 348 829 348 846 348 884 348 980 348 985 348 1003 348 1024 348 1046 348 1059 348 1064 348 1084 348 1135 348 1137 348 1141 348 1238 348 1261 348 1309 348 1316 348 1336 348 1351 348 1378 348 1459 348 1475 348 1481 348 1494 349 66 349 86 349 175 349 211 349 212 349 216 349 283 349 286 349 308 349 322 349 328 349 348 349 349 349 394 349 399 349 405 349 431 349 440 349 444 349 464 349 534 349 537 349 563 349 579 349 580 349 623 349 625 349 626 349 631 349 652 349 681 349 720 349 767 349 776 349 792 349 795 349 829 349 874 349 980 349 1046 349 1057 349 1059 349 1131 349 1137 349 1140 349 1141 349 1199 349 1209 349 1238 349 1249 349 1309 349 1316 349 1351 349 1390 349 1418 349 1475 349 1481 350 7 350 20 350 37 350 49 350 122 350 167 350 170 350 178 350 184 350 203 350 219 350 242 350 326 350 350 350 360 350 416 350 418 350 443 350 457 350 508 350 555 350 559 350 583 350 589 350 593 350 622 350 627 350 639 350 644 350 657 350 671 350 703 350 725 350 732 350 756 350 766 350 777 350 800 350 805 350 886 350 900 350 916 350 928 350 933 350 935 350 958 350 987 350 1010 350 1015 350 1029 350 1071 350 1087 350 1100 350 1101 350 1106 350 1154 350 1161 350 1166 350 1167 350 1171 350 1185 350 1200 350 1205 350 1211 350 1257 350 1268 350 1273 350 1289 350 1294 350 1311 350 1326 350 1388 350 1426 350 1431 350 1479 350 1490 351 15 351 58 351 121 351 158 351 182 351 221 351 229 351 257 351 262 351 285 351 351 351 381 351 428 351 462 351 485 351 490 351 533 351 534 351 536 351 610 351 618 351 619 351 698 351 701 351 808 351 823 351 827 351 837 351 864 351 1044 351 1065 351 1144 351 1153 351 1183 351 1219 351 1258 351 1340 351 1360 351 1448 351 1452 352 129 352 172 352 180 352 192 352 255 352 269 352 322 352 340 352 352 352 394 352 395 352 575 352 590 352 745 352 767 352 769 352 851 352 969 352 1067 352 1125 352 1140 352 1155 352 1209 352 1333 352 1415 353 2 353 111 353 113 353 117 353 132 353 241 353 247 353 275 353 293 353 353 353 362 353 372 353 384 353 386 353 415 353 450 353 466 353 474 353 516 353 554 353 566 353 647 353 793 353 794 353 796 353 982 353 1012 353 1051 353 1056 353 1105 353 1232 353 1253 353 1256 353 1298 353 1377 353 1385 353 1396 353 1447 354 96 354 255 354 322 354 328 354 354 354 394 354 399 354 440 354 479 354 552 354 561 354 580 354 631 354 634 354 652 354 711 354 720 354 786 354 792 354 829 354 874 354 887 354 942 354 969 354 1047 354 1092 354 1125 354 1140 354 1209 354 1238 354 1283 354 1332 354 1351 354 1414 355 26 355 116 355 206 355 233 355 244 355 267 355 283 355 332 355 355 355 399 355 425 355 444 355 475 355 482 355 625 355 629 355 646 355 652 355 708 355 755 355 776 355 795 355 921 355 931 355 986 355 995 355 1007 355 1079 355 1199 355 1204 355 1261 355 1266 355 1314 355 1316 355 1321 355 1339 355 1378 355 1403 355 1467 355 1485 355 1494 356 66 356 96 356 116 356 131 356 137 356 145 356 174 356 175 356 206 356 235 356 261 356 263 356 322 356 356 356 444 356 479 356 486 356 539 356 552 356 568 356 646 356 678 356 714 356 753 356 776 356 885 356 887 356 909 356 942 356 944 356 985 356 1017 356 1047 356 1072 356 1089 356 1120 356 1165 356 1173 356 1178 356 1204 356 1244 356 1261 356 1283 356 1339 356 1353 356 1372 356 1401 356 1411 357 10 357 50 357 68 357 75 357 128 357 141 357 184 357 198 357 203 357 210 357 290 357 294 357 300 357 314 357 333 357 357 357 368 357 376 357 402 357 433 357 457 357 503 357 538 357 551 357 559 357 571 357 578 357 601 357 627 357 657 357 666 357 673 357 703 357 725 357 756 357 898 357 916 357 930 357 1008 357 1020 357 1088 357 1100 357 1166 357 1188 357 1203 357 1300 357 1338 357 1374 357 1433 357 1457 357 1460 357 1462 357 1490 357 1492 358 0 358 21 358 51 358 80 358 98 358 114 358 151 358 186 358 220 358 235 358 238 358 251 358 256 358 264 358 276 358 281 358 298 358 301 358 358 358 367 358 412 358 437 358 442 358 467 358 546 358 594 358 597 358 663 358 674 358 689 358 699 358 721 358 729 358 731 358 760 358 768 358 803 358 821 358 824 358 828 358 912 358 996 358 1011 358 1031 358 1032 358 1033 358 1055 358 1063 358 1079 358 1085 358 1145 358 1147 358 1208 358 1305 358 1398 358 1465 358 1468 358 1487 358 1488 359 185 359 244 359 264 359 288 359 359 359 398 359 436 359 480 359 494 359 546 359 587 359 597 359 598 359 646 359 650 359 676 359 683 359 758 359 771 359 842 359 895 359 897 359 1079 359 1113 359 1218 359 1413 359 1417 359 1440 359 1467 359 1487 360 37 360 49 360 75 360 122 360 128 360 167 360 178 360 198 360 203 360 219 360 242 360 290 360 319 360 350 360 360 360 402 360 416 360 418 360 443 360 457 360 551 360 555 360 582 360 589 360 593 360 622 360 639 360 644 360 657 360 671 360 673 360 703 360 756 360 770 360 777 360 800 360 805 360 886 360 916 360 928 360 933 360 935 360 955 360 958 360 1015 360 1020 360 1087 360 1101 360 1106 360 1107 360 1161 360 1166 360 1167 360 1171 360 1185 360 1200 360 1203 360 1205 360 1211 360 1257 360 1268 360 1289 360 1311 360 1388 360 1426 360 1431 360 1433 360 1479 361 84 361 120 361 239 361 271 361 275 361 293 361 311 361 361 361 372 361 647 361 677 361 719 361 793 361 858 361 971 361 1006 361 1023 361 1056 361 1058 361 1253 361 1307 361 1377 361 1394 361 1395 361 1424 361 1435 362 2 362 25 362 93 362 95 362 97 362 111 362 113 362 126 362 153 362 194 362 197 362 227 362 231 362 241 362 247 362 282 362 296 362 353 362 362 362 384 362 450 362 454 362 463 362 481 362 499 362 516 362 554 362 564 362 566 362 654 362 662 362 670 362 675 362 796 362 970 362 982 362 1001 362 1012 362 1036 362 1050 362 1083 362 1105 362 1116 362 1119 362 1122 362 1186 362 1194 362 1248 362 1256 362 1280 362 1302 362 1329 362 1354 362 1384 362 1385 362 1396 362 1447 362 1478 363 35 363 108 363 140 363 255 363 273 363 304 363 313 363 321 363 363 363 374 363 382 363 413 363 438 363 512 363 540 363 577 363 594 363 634 363 635 363 695 363 772 363 781 363 782 363 786 363 852 363 961 363 998 363 1123 363 1164 363 1177 363 1223 363 1399 363 1466 364 10 364 33 364 50 364 61 364 110 364 141 364 169 364 299 364 341 364 342 364 364 364 379 364 447 364 458 364 493 364 504 364 514 364 578 364 586 364 687 364 704 364 749 364 773 364 811 364 843 364 904 364 913 364 915 364 941 364 943 364 956 364 1095 364 1109 364 1168 364 1189 364 1269 364 1297 364 1312 364 1338 364 1345 364 1420 364 1421 364 1437 364 1495 365 5 365 12 365 52 365 65 365 85 365 202 365 230 365 240 365 291 365 365 365 434 365 569 365 630 365 642 365 730 365 742 365 1018 365 1028 365 1076 365 1129 365 1159 365 1265 365 1331 365 1369 365 1461 365 1472 365 1476 366 32 366 40 366 115 366 139 366 150 366 171 366 177 366 237 366 307 366 366 366 453 366 833 366 835 366 848 366 859 366 869 366 926 366 1041 366 1061 366 1103 366 1138 366 1237 366 1245 366 1247 366 1262 366 1276 366 1296 366 1376 366 1381 366 1406 366 1482 367 0 367 29 367 51 367 98 367 186 367 220 367 238 367 256 367 278 367 281 367 303 367 358 367 367 367 419 367 437 367 438 367 597 367 645 367 661 367 682 367 683 367 699 367 729 367 731 367 760 367 821 367 845 367 872 367 996 367 1011 367 1083 367 1085 367 1197 367 1263 367 1305 367 1371 367 1398 367 1417 367 1440 367 1487 368 49 368 50 368 68 368 75 368 141 368 198 368 203 368 210 368 294 368 300 368 314 368 333 368 357 368 368 368 433 368 443 368 538 368 551 368 571 368 582 368 657 368 671 368 673 368 697 368 756 368 805 368 836 368 916 368 930 368 1088 368 1100 368 1107 368 1203 368 1300 368 1323 368 1364 368 1374 368 1460 368 1483 368 1490 369 43 369 46 369 60 369 104 369 118 369 154 369 176 369 287 369 309 369 369 369 385 369 456 369 500 369 541 369 557 369 565 369 633 369 724 369 747 369 779 369 861 369 902 369 927 369 957 369 1013 369 1128 369 1150 369 1182 369 1210 369 1243 369 1279 369 1295 369 1366 369 1380 369 1439 369 1489 370 44 370 57 370 72 370 76 370 135 370 144 370 149 370 224 370 232 370 370 370 375 370 388 370 397 370 401 370 424 370 455 370 491 370 520 370 584 370 591 370 611 370 733 370 860 370 893 370 990 370 993 370 1136 370 1179 370 1235 370 1358 370 1393 371 47 371 83 371 223 371 224 371 234 371 279 371 295 371 343 371 371 371 377 371 389 371 408 371 478 371 483 371 544 371 547 371 592 371 600 371 603 371 640 371 648 371 690 371 694 371 784 371 807 371 814 371 839 371 875 371 882 371 910 371 940 371 972 371 978 371 1068 371 1078 371 1099 371 1142 371 1180 371 1236 371 1277 371 1281 371 1361 371 1373 371 1407 371 1441 371 1474 371 1496 372 113 372 117 372 194 372 201 372 239 372 241 372 247 372 275 372 293 372 311 372 353 372 361 372 372 372 384 372 415 372 450 372 523 372 647 372 675 372 719 372 793 372 845 372 971 372 973 372 1036 372 1056 372 1105 372 1248 372 1253 372 1302 372 1307 372 1377 372 1447 373 14 373 79 373 92 373 125 373 160 373 189 373 230 373 272 373 279 373 295 373 373 373 387 373 441 373 483 373 484 373 491 373 520 373 526 373 556 373 569 373 600 373 606 373 611 373 612 373 624 373 630 373 638 373 640 373 684 373 690 373 694 373 807 373 809 373 844 373 867 373 882 373 910 373 911 373 978 373 990 373 999 373 1014 373 1018 373 1075 373 1076 373 1082 373 1099 373 1196 373 1206 373 1236 373 1277 373 1355 373 1370 373 1375 373 1441 373 1476 373 1484 374 6 374 35 374 41 374 140 374 162 374 172 374 188 374 199 374 284 374 313 374 321 374 363 374 374 374 380 374 382 374 406 374 411 374 413 374 498 374 521 374 540 374 577 374 594 374 695 374 718 374 772 374 781 374 782 374 786 374 790 374 852 374 929 374 961 374 1049 374 1094 374 1158 374 1164 374 1201 374 1223 374 1251 374 1304 374 1363 375 44 375 57 375 76 375 147 375 149 375 344 375 370 375 375 375 388 375 733 375 799 375 893 375 993 375 1027 375 1136 375 1202 375 1278 375 1358 375 1456 376 10 376 23 376 37 376 49 376 103 376 184 376 198 376 210 376 290 376 357 376 376 376 443 376 457 376 503 376 517 376 542 376 551 376 555 376 559 376 573 376 582 376 589 376 601 376 622 376 627 376 657 376 666 376 704 376 725 376 750 376 756 376 766 376 770 376 800 376 805 376 886 376 898 376 933 376 1008 376 1020 376 1087 376 1088 376 1095 376 1107 376 1166 376 1185 376 1300 376 1364 376 1429 376 1433 376 1457 376 1483 376 1492 377 13 377 47 377 55 377 65 377 83 377 160 377 218 377 223 377 224 377 234 377 291 377 371 377 377 377 441 377 452 377 492 377 497 377 528 377 544 377 547 377 562 377 592 377 603 377 609 377 612 377 620 377 630 377 640 377 648 377 882 377 883 377 939 377 1076 377 1078 377 1091 377 1099 377 1159 377 1225 377 1361 377 1373 377 1474 377 1496 378 22 378 107 378 143 378 156 378 167 378 178 378 219 378 266 378 326 378 378 378 446 378 449 378 507 378 530 378 543 378 558 378 570 378 604 378 607 378 613 378 617 378 621 378 636 378 644 378 669 378 739 378 777 378 791 378 854 378 862 378 873 378 900 378 903 378 935 378 937 378 948 378 958 378 962 378 994 378 1010 378 1071 378 1090 378 1106 378 1146 378 1154 378 1162 378 1176 378 1184 378 1224 378 1289 378 1294 378 1311 378 1324 378 1326 378 1386 378 1431 378 1444 378 1464 379 10 379 33 379 50 379 61 379 68 379 110 379 141 379 169 379 195 379 299 379 314 379 341 379 342 379 364 379 379 379 447 379 458 379 493 379 504 379 514 379 571 379 578 379 586 379 687 379 704 379 749 379 811 379 904 379 913 379 915 379 943 379 956 379 1109 379 1168 379 1189 379 1269 379 1275 379 1312 379 1338 379 1374 379 1420 379 1437 379 1495 380 28 380 29 380 41 380 45 380 51 380 151 380 199 380 284 380 321 380 339 380 374 380 380 380 459 380 470 380 494 380 501 380 505 380 510 380 575 380 594 380 661 380 676 380 683 380 708 380 715 380 726 380 729 380 790 380 895 380 896 380 921 380 929 380 931 380 950 380 965 380 986 380 1007 380 1060 380 1086 380 1152 380 1160 380 1164 380 1304 380 1417 380 1471 380 1487 381 9 381 15 381 54 381 158 381 182 381 205 381 221 381 229 381 285 381 351 381 381 381 462 381 473 381 485 381 490 381 618 381 735 381 823 381 827 381 837 381 849 381 864 381 1044 381 1144 381 1153 381 1258 381 1389 381 1448 381 1452 381 1463 382 6 382 35 382 41 382 94 382 140 382 172 382 188 382 199 382 283 382 284 382 313 382 321 382 363 382 374 382 382 382 406 382 411 382 413 382 487 382 498 382 501 382 510 382 540 382 577 382 681 382 686 382 695 382 713 382 718 382 772 382 781 382 782 382 786 382 790 382 810 382 831 382 852 382 865 382 896 382 929 382 961 382 1048 382 1049 382 1081 382 1094 382 1158 382 1164 382 1201 382 1223 382 1251 382 1363 382 1425 383 136 383 159 383 196 383 252 383 345 383 383 383 400 383 448 383 605 383 615 383 707 383 739 383 783 383 847 383 920 383 947 383 960 383 1090 383 1126 383 1172 383 1174 383 1284 383 1325 383 1386 383 1434 383 1436 384 2 384 97 384 111 384 113 384 117 384 153 384 194 384 197 384 241 384 247 384 275 384 315 384 353 384 362 384 372 384 384 384 386 384 450 384 463 384 488 384 554 384 566 384 670 384 675 384 796 384 970 384 1001 384 1012 384 1036 384 1105 384 1119 384 1122 384 1186 384 1194 384 1248 384 1253 384 1256 384 1302 384 1329 384 1384 384 1391 384 1396 384 1447 384 1478 385 43 385 46 385 60 385 77 385 118 385 154 385 176 385 208 385 280 385 287 385 369 385 385 385 410 385 456 385 541 385 557 385 565 385 633 385 724 385 747 385 779 385 861 385 891 385 902 385 927 385 957 385 976 385 1013 385 1030 385 1128 385 1150 385 1210 385 1243 385 1279 385 1295 385 1366 385 1380 385 1439 385 1489 386 113 386 132 386 201 386 227 386 231 386 241 386 306 386 324 386 353 386 384 386 386 386 474 386 481 386 515 386 554 386 566 386 581 386 696 386 798 386 924 386 1002 386 1116 386 1119 386 1122 386 1232 386 1259 386 1272 386 1280 386 1285 386 1391 386 1478 387 14 387 63 387 92 387 125 387 135 387 160 387 189 387 223 387 230 387 272 387 279 387 295 387 373 387 387 387 391 387 441 387 483 387 520 387 556 387 569 387 600 387 611 387 624 387 630 387 640 387 690 387 694 387 784 387 807 387 809 387 839 387 844 387 888 387 910 387 911 387 940 387 999 387 1014 387 1018 387 1069 387 1075 387 1082 387 1097 387 1099 387 1108 387 1180 387 1196 387 1206 387 1230 387 1277 387 1281 387 1370 387 1441 387 1472 387 1474 387 1476 387 1484 388 44 388 57 388 76 388 147 388 149 388 344 388 370 388 375 388 388 388 397 388 424 388 455 388 491 388 733 388 799 388 860 388 893 388 993 388 1027 388 1136 388 1179 388 1202 388 1235 388 1278 388 1358 388 1393 388 1456 389 72 389 135 389 144 389 149 389 217 389 223 389 224 389 232 389 253 389 279 389 343 389 371 389 389 389 391 389 397 389 408 389 478 389 483 389 584 389 592 389 638 389 680 389 784 389 814 389 839 389 844 389 860 389 906 389 911 389 940 389 972 389 978 389 1034 389 1068 389 1078 389 1099 389 1142 389 1180 389 1198 389 1217 389 1229 389 1230 389 1281 389 1361 389 1373 389 1407 389 1441 389 1474 389 1496 390 71 390 159 390 248 390 252 390 274 390 297 390 390 390 423 390 432 390 448 390 469 390 548 390 588 390 641 390 706 390 707 390 738 390 764 390 960 390 964 390 977 390 1005 390 1037 390 1126 390 1130 390 1172 390 1174 390 1252 390 1274 390 1287 390 1324 390 1328 390 1386 390 1416 390 1422 390 1434 390 1436 390 1493 391 36 391 56 391 72 391 101 391 135 391 164 391 230 391 279 391 343 391 387 391 389 391 391 391 408 391 520 391 524 391 547 391 592 391 600 391 611 391 638 391 680 391 784 391 822 391 839 391 844 391 906 391 911 391 940 391 972 391 1034 391 1068 391 1097 391 1099 391 1180 391 1198 391 1206 391 1230 391 1277 391 1281 391 1299 391 1373 391 1393 391 1407 391 1441 391 1474 392 6 392 42 392 45 392 48 392 66 392 89 392 124 392 127 392 131 392 228 392 243 392 392 392 459 392 470 392 486 392 501 392 502 392 513 392 535 392 576 392 649 392 678 392 679 392 689 392 726 392 746 392 753 392 757 392 775 392 786 392 797 392 810 392 830 392 831 392 879 392 896 392 921 392 929 392 946 392 961 392 968 392 1016 392 1039 392 1072 392 1160 392 1173 392 1201 392 1213 392 1349 392 1353 392 1372 392 1449 393 100 393 127 393 134 393 138 393 140 393 246 393 260 393 320 393 321 393 329 393 337 393 393 393 406 393 417 393 421 393 445 393 487 393 501 393 513 393 521 393 585 393 596 393 679 393 688 393 717 393 726 393 741 393 746 393 754 393 762 393 772 393 775 393 781 393 790 393 797 393 806 393 834 393 918 393 922 393 945 393 946 393 968 393 998 393 1000 393 1042 393 1048 393 1049 393 1077 393 1094 393 1139 393 1158 393 1181 393 1223 393 1226 393 1241 393 1286 393 1315 393 1387 393 1408 393 1428 393 1438 393 1445 393 1453 393 1470 394 17 394 66 394 96 394 129 394 162 394 172 394 174 394 180 394 216 394 255 394 261 394 263 394 283 394 304 394 322 394 328 394 340 394 349 394 352 394 354 394 394 394 395 394 399 394 440 394 444 394 464 394 479 394 575 394 576 394 580 394 590 394 625 394 631 394 634 394 652 394 681 394 695 394 711 394 720 394 745 394 767 394 786 394 792 394 795 394 829 394 874 394 881 394 887 394 942 394 969 394 980 394 992 394 1047 394 1059 394 1067 394 1092 394 1125 394 1140 394 1141 394 1155 394 1173 394 1199 394 1209 394 1213 394 1238 394 1244 394 1283 394 1316 394 1332 394 1351 395 17 395 129 395 133 395 145 395 172 395 180 395 192 395 255 395 283 395 304 395 322 395 328 395 340 395 352 395 394 395 395 395 399 395 531 395 561 395 576 395 590 395 634 395 652 395 681 395 695 395 745 395 767 395 769 395 851 395 969 395 980 395 992 395 1039 395 1125 395 1140 395 1155 395 1209 395 1333 395 1351 395 1415 395 1499 396 22 396 156 396 266 396 345 396 396 396 449 396 530 396 543 396 583 396 604 396 613 396 621 396 669 396 691 396 727 396 739 396 841 396 854 396 873 396 903 396 919 396 920 396 948 396 960 396 987 396 994 396 1005 396 1037 396 1038 396 1090 396 1151 396 1267 396 1287 396 1324 396 1325 396 1436 396 1444 396 1450 397 44 397 57 397 72 397 76 397 135 397 144 397 149 397 217 397 224 397 232 397 253 397 344 397 370 397 388 397 389 397 397 397 401 397 424 397 455 397 478 397 491 397 520 397 556 397 584 397 591 397 611 397 733 397 860 397 893 397 990 397 993 397 1136 397 1142 397 1179 397 1230 397 1235 397 1278 397 1290 397 1358 397 1393 397 1456 398 0 398 98 398 185 398 264 398 281 398 288 398 359 398 398 398 436 398 442 398 475 398 480 398 518 398 546 398 587 398 598 398 645 398 650 398 663 398 674 398 676 398 683 398 758 398 771 398 824 398 842 398 866 398 895 398 1079 398 1085 398 1197 398 1218 398 1266 398 1271 398 1305 398 1318 398 1371 398 1412 398 1413 398 1440 399 17 399 268 399 283 399 286 399 304 399 308 399 322 399 328 399 348 399 349 399 354 399 355 399 394 399 395 399 399 399 440 399 444 399 460 399 464 399 561 399 575 399 580 399 590 399 625 399 631 399 634 399 652 399 681 399 695 399 720 399 786 399 795 399 829 399 865 399 969 399 980 399 992 399 1007 399 1059 399 1125 399 1131 399 1137 399 1140 399 1141 399 1199 399 1209 399 1238 399 1316 399 1351 399 1378 399 1467 399 1481 400 156 400 159 400 196 400 252 400 266 400 345 400 383 400 400 400 448 400 605 400 615 400 707 400 739 400 783 400 847 400 854 400 920 400 947 400 960 400 1037 400 1090 400 1126 400 1172 400 1174 400 1267 400 1325 400 1386 400 1434 400 1436 401 72 401 76 401 135 401 144 401 189 401 217 401 232 401 295 401 370 401 397 401 401 401 424 401 455 401 478 401 520 401 526 401 556 401 591 401 611 401 684 401 733 401 784 401 822 401 839 401 911 401 940 401 978 401 990 401 1014 401 1142 401 1179 401 1216 401 1230 401 1235 401 1281 401 1290 401 1375 401 1393 401 1498 402 20 402 31 402 37 402 75 402 123 402 128 402 170 402 198 402 290 402 333 402 357 402 360 402 402 402 433 402 457 402 538 402 551 402 555 402 559 402 593 402 622 402 657 402 673 402 703 402 736 402 756 402 886 402 916 402 933 402 997 402 1020 402 1100 402 1106 402 1112 402 1166 402 1203 402 1257 402 1311 402 1426 402 1433 402 1457 402 1462 402 1490 403 20 403 22 403 87 403 156 403 204 403 266 403 292 403 336 403 403 403 449 403 530 403 543 403 583 403 621 403 763 403 764 403 873 403 948 403 994 403 1005 403 1037 403 1169 403 1184 403 1188 403 1224 403 1287 403 1324 403 1326 403 1386 403 1404 403 1458 403 1493 404 14 404 47 404 63 404 79 404 125 404 160 404 240 404 253 404 272 404 295 404 344 404 404 404 466 404 484 404 526 404 556 404 624 404 694 404 743 404 807 404 809 404 875 404 882 404 888 404 910 404 990 404 1069 404 1075 404 1082 404 1097 404 1196 404 1355 404 1375 405 26 405 53 405 58 405 66 405 78 405 82 405 86 405 102 405 191 405 193 405 200 405 206 405 211 405 233 405 250 405 277 405 332 405 348 405 349 405 405 405 428 405 431 405 444 405 451 405 465 405 533 405 534 405 563 405 579 405 580 405 625 405 626 405 658 405 702 405 720 405 846 405 863 405 901 405 959 405 1003 405 1024 405 1035 405 1046 405 1054 405 1064 405 1113 405 1131 405 1135 405 1137 405 1309 405 1327 405 1340 405 1341 405 1475 405 1481 405 1494 406 6 406 35 406 41 406 42 406 48 406 81 406 94 406 100 406 140 406 179 406 188 406 226 406 246 406 276 406 310 406 313 406 374 406 382 406 393 406 406 406 487 406 521 406 540 406 577 406 596 406 688 406 713 406 718 406 754 406 762 406 772 406 781 406 782 406 790 406 806 406 810 406 831 406 918 406 929 406 945 406 961 406 963 406 974 406 998 406 1045 406 1048 406 1049 406 1052 406 1081 406 1094 406 1139 406 1158 406 1181 406 1201 406 1223 406 1251 406 1363 406 1425 406 1453 407 3 407 8 407 19 407 64 407 97 407 119 407 153 407 183 407 197 407 296 407 407 407 427 407 499 407 614 407 628 407 660 407 662 407 709 407 765 407 816 407 849 407 951 407 1002 407 1050 407 1132 407 1133 407 1186 407 1227 407 1242 407 1260 407 1354 407 1384 408 14 408 47 408 56 408 79 408 164 408 223 408 279 408 295 408 343 408 371 408 389 408 391 408 408 408 434 408 478 408 483 408 524 408 526 408 547 408 567 408 592 408 606 408 638 408 680 408 784 408 814 408 822 408 839 408 844 408 867 408 906 408 908 408 940 408 972 408 978 408 1018 408 1034 408 1068 408 1076 408 1097 408 1098 408 1142 408 1180 408 1198 408 1206 408 1216 408 1229 408 1236 408 1281 408 1299 408 1361 408 1370 408 1373 408 1375 408 1407 408 1441 408 1474 408 1498 409 39 409 104 409 109 409 112 409 166 409 168 409 215 409 258 409 302 409 309 409 346 409 409 409 426 409 477 409 489 409 710 409 899 409 917 409 954 409 989 409 1080 409 1114 409 1128 409 1134 409 1148 409 1207 409 1233 409 1301 409 1319 409 1368 409 1380 409 1405 409 1469 410 39 410 60 410 77 410 109 410 112 410 154 410 176 410 208 410 215 410 254 410 280 410 302 410 385 410 410 410 456 410 500 410 541 410 633 410 651 410 724 410 747 410 779 410 826 410 861 410 878 410 891 410 927 410 954 410 957 410 976 410 989 410 1013 410 1025 410 1030 410 1128 410 1134 410 1148 410 1207 410 1210 410 1295 410 1301 410 1310 410 1383 410 1439 411 35 411 134 411 140 411 313 411 374 411 382 411 411 411 413 411 498 411 521 411 577 411 718 411 741 411 772 411 781 411 890 411 918 411 998 411 1049 411 1123 411 1164 411 1292 412 21 412 51 412 80 412 98 412 225 412 226 412 245 412 251 412 256 412 276 412 278 412 358 412 412 412 419 412 437 412 445 412 496 412 509 412 535 412 545 412 602 412 663 412 665 412 692 412 699 412 729 412 768 412 821 412 828 412 912 412 938 412 949 412 952 412 966 412 1011 412 1012 412 1032 412 1033 412 1045 412 1055 412 1083 412 1170 412 1208 412 1288 413 6 413 42 413 45 413 48 413 108 413 124 413 140 413 313 413 363 413 374 413 382 413 411 413 413 413 521 413 531 413 634 413 635 413 688 413 740 413 741 413 746 413 772 413 781 413 782 413 786 413 852 413 961 413 991 413 998 413 1049 413 1081 413 1094 413 1123 413 1139 413 1164 413 1181 413 1201 413 1213 413 1362 413 1453 414 59 414 67 414 161 414 190 414 335 414 414 414 435 414 691 414 727 414 774 414 840 414 841 414 857 414 919 414 953 414 1021 414 1231 414 1320 414 1365 414 1409 414 1432 414 1443 414 1454 414 1477 414 1491 414 1497 415 163 415 181 415 246 415 310 415 353 415 372 415 415 415 476 415 523 415 647 415 712 415 793 415 850 415 894 415 932 415 963 415 974 415 1004 415 1117 415 1306 415 1307 415 1342 415 1377 416 91 416 143 416 167 416 178 416 219 416 319 416 326 416 350 416 360 416 416 416 418 416 422 416 457 416 508 416 555 416 589 416 593 416 617 416 622 416 644 416 732 416 777 416 800 416 886 416 928 416 933 416 935 416 958 416 997 416 1010 416 1015 416 1087 416 1112 416 1146 416 1154 416 1161 416 1166 416 1167 416 1171 416 1200 416 1205 416 1211 416 1257 416 1268 416 1289 416 1294 416 1311 416 1346 416 1388 416 1426 416 1431 416 1479 417 1 417 100 417 134 417 140 417 246 417 260 417 265 417 320 417 329 417 337 417 393 417 417 417 421 417 445 417 487 417 596 417 616 417 672 417 717 417 754 417 762 417 772 417 806 417 856 417 918 417 922 417 945 417 1042 417 1045 417 1074 417 1077 417 1139 417 1158 417 1181 417 1195 417 1226 417 1241 417 1315 417 1342 417 1387 417 1397 417 1428 417 1438 417 1445 417 1453 417 1470 418 37 418 91 418 167 418 170 418 178 418 219 418 242 418 319 418 326 418 350 418 360 418 416 418 418 418 422 418 508 418 555 418 593 418 617 418 622 418 644 418 703 418 732 418 777 418 800 418 886 418 900 418 928 418 933 418 935 418 958 418 997 418 1010 418 1015 418 1071 418 1087 418 1106 418 1112 418 1146 418 1154 418 1161 418 1167 418 1171 418 1200 418 1205 418 1211 418 1257 418 1268 418 1289 418 1294 418 1311 418 1346 418 1388 418 1426 418 1431 418 1479 419 51 419 80 419 98 419 151 419 185 419 186 419 199 419 225 419 245 419 278 419 339 419 347 419 367 419 412 419 419 419 430 419 437 419 480 419 496 419 509 419 529 419 545 419 597 419 645 419 661 419 663 419 665 419 676 419 682 419 699 419 713 419 729 419 760 419 768 419 821 419 828 419 842 419 912 419 949 419 952 419 996 419 1011 419 1019 419 1022 419 1033 419 1060 419 1063 419 1152 419 1190 419 1197 419 1208 419 1215 419 1398 419 1417 419 1440 419 1465 419 1487 420 74 420 84 420 88 420 173 420 209 420 306 420 324 420 334 420 420 420 461 420 471 420 472 420 474 420 477 420 488 420 525 420 553 420 554 420 572 420 581 420 659 420 668 420 675 420 696 420 723 420 728 420 737 420 748 420 788 420 798 420 804 420 818 420 924 420 1062 420 1080 420 1093 420 1096 420 1104 420 1115 420 1143 420 1192 420 1254 420 1272 420 1285 420 1293 420 1303 420 1391 420 1469 421 1 421 100 421 260 421 265 421 337 421 393 421 417 421 421 421 596 421 616 421 672 421 717 421 754 421 762 421 806 421 945 421 1042 421 1074 421 1077 421 1139 421 1195 421 1226 421 1315 421 1317 421 1337 421 1342 421 1397 421 1428 421 1453 421 1470 421 1473 422 122 422 143 422 167 422 178 422 219 422 319 422 326 422 416 422 418 422 422 422 457 422 555 422 593 422 617 422 622 422 636 422 644 422 732 422 777 422 933 422 958 422 962 422 997 422 1010 422 1015 422 1101 422 1112 422 1154 422 1166 422 1185 422 1257 422 1294 422 1311 422 1346 422 1426 422 1433 422 1479 423 34 423 71 423 136 423 150 423 171 423 207 423 213 423 237 423 248 423 252 423 297 423 317 423 390 423 423 423 432 423 439 423 469 423 495 423 548 423 588 423 641 423 706 423 738 423 813 423 868 423 889 423 936 423 964 423 977 423 1041 423 1053 423 1110 423 1130 423 1138 423 1237 423 1255 423 1274 423 1284 423 1322 423 1328 423 1376 423 1416 423 1422 424 57 424 72 424 76 424 135 424 144 424 149 424 217 424 232 424 370 424 388 424 397 424 401 424 424 424 455 424 478 424 520 424 584 424 591 424 611 424 733 424 860 424 893 424 940 424 1136 424 1142 424 1179 424 1230 424 1235 424 1358 424 1393 425 24 425 116 425 193 425 206 425 267 425 323 425 327 425 348 425 355 425 425 425 429 425 475 425 502 425 539 425 625 425 678 425 708 425 776 425 885 425 896 425 934 425 938 425 985 425 1007 425 1064 425 1124 425 1135 425 1165 425 1204 425 1244 425 1266 425 1316 425 1339 425 1341 425 1403 426 62 426 105 426 166 426 168 426 173 426 215 426 254 426 302 426 334 426 409 426 426 426 472 426 477 426 489 426 572 426 710 426 723 426 826 426 899 426 917 426 954 426 1104 426 1114 426 1143 426 1149 426 1207 426 1233 426 1319 426 1383 426 1405 426 1427 426 1469 427 8 427 69 427 111 427 119 427 330 427 407 427 427 427 442 427 454 427 499 427 516 427 628 427 765 427 780 427 794 427 951 427 1083 427 1133 427 1194 427 1222 427 1260 427 1298 427 1396 428 38 428 53 428 58 428 78 428 82 428 102 428 191 428 211 428 212 428 216 428 229 428 257 428 262 428 308 428 351 428 405 428 428 428 451 428 464 428 511 428 533 428 534 428 549 428 579 428 610 428 619 428 626 428 637 428 658 428 720 428 812 428 829 428 863 428 874 428 901 428 923 428 1003 428 1017 428 1024 428 1065 428 1084 428 1135 428 1183 428 1219 428 1234 428 1238 428 1249 428 1336 428 1351 428 1360 428 1459 428 1481 429 24 429 116 429 145 429 325 429 425 429 429 429 475 429 539 429 629 429 646 429 689 429 776 429 885 429 944 429 985 429 992 429 1039 429 1046 429 1204 429 1339 429 1349 429 1403 429 1468 429 1499 430 41 430 80 430 81 430 99 430 106 430 151 430 179 430 188 430 199 430 245 430 347 430 419 430 430 430 480 430 487 430 510 430 529 430 550 430 585 430 602 430 661 430 665 430 674 430 682 430 760 430 768 430 820 430 821 430 842 430 949 430 952 430 986 430 1019 430 1022 430 1032 430 1060 430 1063 430 1070 430 1152 430 1175 430 1190 430 1223 430 1251 430 1304 430 1318 430 1408 430 1465 431 38 431 53 431 58 431 86 431 211 431 212 431 216 431 261 431 262 431 323 431 325 431 348 431 349 431 405 431 431 431 444 431 451 431 464 431 506 431 522 431 534 431 549 431 580 431 626 431 637 431 646 431 652 431 702 431 767 431 776 431 792 431 808 431 897 431 923 431 944 431 980 431 1024 431 1046 431 1065 431 1084 431 1135 431 1137 431 1219 431 1238 431 1249 431 1309 431 1316 431 1336 431 1359 431 1418 431 1481 432 16 432 71 432 136 432 150 432 159 432 207 432 213 432 248 432 252 432 274 432 297 432 317 432 390 432 423 432 432 432 439 432 469 432 519 432 548 432 588 432 632 432 641 432 706 432 738 432 889 432 936 432 964 432 977 432 1053 432 1073 432 1130 432 1252 432 1255 432 1274 432 1284 432 1322 432 1328 432 1381 432 1416 432 1422 432 1480 433 50 433 68 433 75 433 141 433 203 433 210 433 294 433 300 433 314 433 333 433 357 433 368 433 402 433 433 433 514 433 538 433 551 433 559 433 571 433 627 433 657 433 673 433 697 433 916 433 930 433 1029 433 1088 433 1100 433 1188 433 1203 433 1300 433 1338 433 1364 433 1433 433 1460 433 1462 433 1490 433 1495 434 5 434 12 434 13 434 14 434 47 434 65 434 92 434 160 434 165 434 218 434 234 434 240 434 291 434 365 434 408 434 434 434 441 434 452 434 528 434 569 434 603 434 606 434 608 434 612 434 624 434 630 434 648 434 730 434 809 434 882 434 883 434 939 434 1018 434 1028 434 1075 434 1076 434 1097 434 1159 434 1206 434 1229 434 1236 434 1265 434 1291 434 1331 434 1369 434 1461 434 1484 435 59 435 67 435 161 435 190 435 335 435 414 435 435 435 774 435 840 435 841 435 857 435 919 435 1021 435 1231 435 1320 435 1365 435 1409 435 1432 435 1443 435 1454 435 1477 435 1491 435 1497 436 0 436 26 436 185 436 222 436 264 436 267 436 288 436 312 436 327 436 359 436 398 436 436 436 465 436 475 436 480 436 482 436 494 436 546 436 597 436 598 436 646 436 650 436 676 436 755 436 758 436 771 436 895 436 934 436 1079 436 1113 436 1218 436 1266 436 1314 436 1327 436 1330 436 1413 436 1442 437 21 437 51 437 80 437 98 437 151 437 186 437 199 437 225 437 245 437 256 437 276 437 278 437 281 437 318 437 339 437 347 437 358 437 367 437 412 437 419 437 437 437 496 437 509 437 535 437 545 437 597 437 635 437 645 437 661 437 665 437 676 437 682 437 699 437 729 437 731 437 768 437 821 437 828 437 872 437 912 437 949 437 950 437 952 437 1011 437 1033 437 1063 437 1086 437 1152 437 1163 437 1197 437 1208 437 1215 437 1239 437 1288 437 1398 437 1399 437 1417 437 1440 437 1487 438 6 438 45 438 70 438 108 438 133 438 238 438 256 438 273 438 281 438 303 438 363 438 367 438 438 438 512 438 635 438 722 438 731 438 780 438 803 438 872 438 1031 438 1086 438 1228 438 1263 438 1305 438 1363 438 1399 438 1466 438 1488 438 1499 439 32 439 34 439 136 439 150 439 171 439 207 439 213 439 237 439 252 439 274 439 307 439 317 439 423 439 432 439 439 439 495 439 588 439 641 439 706 439 744 439 783 439 813 439 835 439 848 439 853 439 859 439 868 439 869 439 889 439 936 439 1041 439 1110 439 1130 439 1138 439 1174 439 1237 439 1247 439 1255 439 1262 439 1276 439 1284 439 1296 439 1322 439 1347 439 1376 439 1381 439 1422 440 17 440 28 440 58 440 86 440 175 440 250 440 277 440 322 440 349 440 354 440 394 440 399 440 440 440 444 440 464 440 561 440 563 440 580 440 626 440 631 440 652 440 720 440 785 440 795 440 829 440 874 440 1057 440 1059 440 1131 440 1137 440 1140 440 1141 440 1238 440 1283 440 1309 440 1332 440 1341 440 1390 441 5 441 13 441 14 441 47 441 55 441 83 441 92 441 160 441 202 441 218 441 230 441 234 441 240 441 291 441 373 441 377 441 387 441 434 441 441 441 483 441 492 441 528 441 569 441 600 441 603 441 609 441 612 441 620 441 624 441 630 441 640 441 642 441 648 441 690 441 694 441 730 441 809 441 870 441 882 441 883 441 1018 441 1028 441 1075 441 1076 441 1098 441 1108 441 1159 441 1180 441 1196 441 1206 441 1236 441 1265 441 1277 441 1291 441 1331 441 1369 441 1461 441 1472 441 1474 441 1476 441 1484 442 0 442 119 442 197 442 220 442 238 442 264 442 281 442 298 442 301 442 327 442 330 442 338 442 358 442 398 442 427 442 442 442 518 442 560 442 729 442 765 442 771 442 803 442 824 442 866 442 892 442 951 442 983 442 1011 442 1031 442 1085 442 1124 442 1145 442 1147 442 1214 442 1222 442 1228 442 1260 442 1266 442 1271 442 1305 442 1330 442 1371 442 1400 442 1412 442 1413 443 37 443 49 443 122 443 128 443 198 443 203 443 204 443 219 443 242 443 290 443 350 443 360 443 368 443 376 443 443 443 468 443 503 443 517 443 551 443 555 443 573 443 574 443 582 443 589 443 639 443 657 443 671 443 673 443 756 443 770 443 800 443 805 443 819 443 836 443 886 443 928 443 955 443 1020 443 1101 443 1107 443 1166 443 1171 443 1185 443 1200 443 1203 443 1211 443 1273 443 1311 443 1364 443 1431 443 1433 443 1460 443 1483 444 28 444 58 444 66 444 86 444 89 444 116 444 174 444 175 444 211 444 250 444 277 444 325 444 348 444 349 444 355 444 356 444 394 444 399 444 405 444 431 444 440 444 444 444 464 444 539 444 552 444 563 444 579 444 580 444 625 444 626 444 646 444 652 444 720 444 776 444 795 444 863 444 887 444 980 444 995 444 1024 444 1046 444 1047 444 1131 444 1137 444 1141 444 1165 444 1204 444 1238 444 1283 444 1309 444 1316 444 1341 444 1390 444 1446 444 1494 445 21 445 100 445 226 445 246 445 260 445 320 445 329 445 337 445 393 445 412 445 417 445 445 445 487 445 596 445 602 445 616 445 653 445 754 445 762 445 806 445 922 445 952 445 1042 445 1045 445 1070 445 1077 445 1139 445 1158 445 1170 445 1241 445 1288 445 1315 445 1317 445 1387 445 1428 445 1438 445 1445 445 1470 446 7 446 87 446 91 446 143 446 148 446 156 446 167 446 219 446 242 446 292 446 326 446 378 446 446 446 449 446 507 446 508 446 583 446 604 446 613 446 621 446 636 446 639 446 644 446 669 446 791 446 854 446 873 446 903 446 928 446 935 446 937 446 948 446 958 446 962 446 987 446 1010 446 1038 446 1071 446 1151 446 1156 446 1161 446 1167 446 1176 446 1211 446 1273 446 1289 446 1324 446 1326 446 1431 446 1444 446 1450 446 1458 447 33 447 61 447 110 447 169 447 299 447 341 447 342 447 364 447 379 447 447 447 458 447 493 447 504 447 578 447 586 447 687 447 704 447 749 447 773 447 843 447 904 447 913 447 915 447 941 447 943 447 956 447 1109 447 1168 447 1189 447 1269 447 1312 447 1345 447 1420 447 1421 447 1437 448 159 448 196 448 252 448 345 448 383 448 390 448 400 448 448 448 543 448 605 448 615 448 641 448 707 448 739 448 764 448 783 448 847 448 920 448 947 448 960 448 1037 448 1090 448 1126 448 1172 448 1174 448 1252 448 1267 448 1324 448 1325 448 1386 448 1434 448 1436 448 1493 449 7 449 22 449 87 449 107 449 148 449 156 449 266 449 292 449 336 449 378 449 396 449 403 449 446 449 449 449 507 449 530 449 543 449 558 449 570 449 583 449 604 449 607 449 613 449 621 449 669 449 739 449 763 449 791 449 854 449 862 449 873 449 900 449 903 449 920 449 935 449 937 449 948 449 960 449 962 449 994 449 1005 449 1037 449 1071 449 1090 449 1106 449 1156 449 1162 449 1176 449 1184 449 1224 449 1267 449 1287 449 1289 449 1294 449 1324 449 1326 449 1386 449 1436 449 1444 449 1464 450 2 450 25 450 93 450 95 450 111 450 117 450 126 450 153 450 231 450 247 450 282 450 311 450 315 450 353 450 362 450 372 450 384 450 450 450 454 450 463 450 516 450 564 450 670 450 692 450 794 450 796 450 801 450 838 450 970 450 982 450 1001 450 1012 450 1023 450 1036 450 1050 450 1056 450 1083 450 1105 450 1119 450 1122 450 1133 450 1186 450 1194 450 1222 450 1253 450 1256 450 1280 450 1282 450 1298 450 1377 450 1385 450 1394 450 1395 450 1396 450 1447 451 53 451 58 451 78 451 82 451 86 451 90 451 102 451 130 451 191 451 193 451 200 451 206 451 211 451 212 451 262 451 270 451 277 451 308 451 332 451 348 451 405 451 428 451 431 451 451 451 511 451 533 451 534 451 537 451 549 451 563 451 579 451 580 451 610 451 626 451 658 451 685 451 702 451 752 451 761 451 812 451 829 451 846 451 863 451 884 451 901 451 923 451 959 451 1003 451 1024 451 1035 451 1046 451 1057 451 1065 451 1066 451 1084 451 1102 451 1124 451 1131 451 1135 451 1137 451 1183 451 1221 451 1238 451 1249 451 1309 451 1327 451 1336 451 1340 451 1459 451 1475 451 1481 451 1494 452 13 452 47 452 65 452 83 452 92 452 187 452 217 452 218 452 223 452 291 452 377 452 434 452 452 452 484 452 497 452 526 452 528 452 544 452 562 452 567 452 606 452 608 452 612 452 640 452 690 452 822 452 839 452 875 452 883 452 972 452 1076 452 1159 452 1216 452 1225 452 1236 452 1250 452 1290 452 1291 452 1313 452 1348 452 1356 452 1361 452 1375 452 1498 453 16 453 32 453 40 453 115 453 139 453 150 453 171 453 177 453 207 453 213 453 237 453 274 453 307 453 317 453 366 453 453 453 744 453 833 453 835 453 848 453 853 453 859 453 869 453 926 453 936 453 1041 453 1061 453 1103 453 1138 453 1237 453 1245 453 1247 453 1262 453 1276 453 1296 453 1322 453 1347 453 1376 453 1381 453 1406 453 1482 454 2 454 25 454 69 454 93 454 111 454 117 454 119 454 126 454 153 454 220 454 231 454 247 454 282 454 362 454 427 454 450 454 454 454 463 454 516 454 564 454 780 454 794 454 801 454 838 454 951 454 970 454 982 454 1001 454 1036 454 1050 454 1083 454 1119 454 1122 454 1133 454 1186 454 1194 454 1222 454 1227 454 1253 454 1256 454 1260 454 1280 454 1282 454 1298 454 1385 454 1396 454 1447 454 1478 455 57 455 72 455 76 455 135 455 144 455 149 455 189 455 217 455 232 455 253 455 305 455 370 455 388 455 397 455 401 455 424 455 455 455 478 455 484 455 520 455 556 455 584 455 591 455 611 455 684 455 733 455 860 455 911 455 940 455 978 455 990 455 993 455 1014 455 1136 455 1142 455 1179 455 1216 455 1230 455 1235 455 1250 455 1290 455 1358 455 1393 455 1498 456 43 456 60 456 77 456 105 456 118 456 154 456 176 456 208 456 254 456 280 456 287 456 369 456 385 456 410 456 456 456 500 456 532 456 541 456 557 456 565 456 633 456 651 456 724 456 747 456 779 456 826 456 861 456 878 456 891 456 902 456 927 456 957 456 976 456 989 456 1013 456 1025 456 1030 456 1150 456 1207 456 1210 456 1220 456 1243 456 1270 456 1279 456 1295 456 1310 456 1366 456 1380 456 1383 456 1489 457 23 457 31 457 123 457 178 457 184 457 198 457 319 457 350 457 357 457 360 457 376 457 402 457 416 457 422 457 457 457 503 457 551 457 555 457 593 457 622 457 627 457 666 457 673 457 703 457 725 457 732 457 736 457 750 457 766 457 770 457 777 457 800 457 886 457 898 457 916 457 933 457 997 457 1015 457 1020 457 1087 457 1112 457 1166 457 1185 457 1200 457 1205 457 1257 457 1346 457 1388 457 1426 457 1429 457 1433 457 1457 457 1479 457 1492 458 33 458 61 458 110 458 155 458 169 458 299 458 341 458 342 458 364 458 379 458 447 458 458 458 493 458 504 458 514 458 586 458 749 458 773 458 843 458 904 458 913 458 941 458 943 458 956 458 1109 458 1269 458 1312 458 1345 458 1420 458 1421 458 1437 459 11 459 29 459 41 459 94 459 199 459 243 459 284 459 289 459 339 459 380 459 392 459 459 459 486 459 501 459 513 459 664 459 679 459 713 459 715 459 726 459 775 459 787 459 828 459 845 459 912 459 921 459 929 459 931 459 946 459 965 459 968 459 973 459 1033 459 1045 459 1077 459 1081 459 1086 459 1152 459 1241 459 1304 459 1315 459 1335 459 1362 459 1445 459 1470 460 30 460 53 460 78 460 180 460 192 460 212 460 270 460 286 460 308 460 399 460 460 460 511 460 537 460 549 460 631 460 637 460 761 460 812 460 829 460 923 460 1057 460 1065 460 1219 460 1249 460 1336 460 1351 460 1390 460 1415 460 1418 460 1459 461 74 461 88 461 166 461 168 461 173 461 306 461 334 461 420 461 461 461 471 461 472 461 525 461 553 461 659 461 668 461 696 461 748 461 804 461 818 461 924 461 1040 461 1062 461 1080 461 1096 461 1143 461 1191 461 1192 461 1254 461 1272 461 1285 461 1293 461 1302 461 1303 461 1319 461 1405 461 1427 461 1469 462 9 462 15 462 54 462 121 462 158 462 182 462 205 462 221 462 229 462 262 462 285 462 351 462 381 462 462 462 485 462 490 462 618 462 619 462 685 462 735 462 823 462 827 462 837 462 864 462 1044 462 1144 462 1153 462 1183 462 1258 462 1360 462 1389 462 1448 462 1452 462 1463 463 2 463 93 463 95 463 111 463 117 463 126 463 153 463 220 463 231 463 247 463 282 463 296 463 315 463 362 463 384 463 450 463 454 463 463 463 516 463 564 463 654 463 670 463 796 463 801 463 838 463 970 463 975 463 982 463 1001 463 1036 463 1050 463 1083 463 1105 463 1119 463 1122 463 1133 463 1186 463 1194 463 1222 463 1248 463 1253 463 1256 463 1260 463 1280 463 1282 463 1298 463 1384 463 1385 463 1394 463 1395 463 1396 463 1447 463 1478 464 38 464 58 464 66 464 78 464 193 464 212 464 216 464 283 464 286 464 322 464 328 464 349 464 394 464 399 464 428 464 431 464 440 464 444 464 464 464 534 464 575 464 580 464 623 464 625 464 637 464 652 464 720 464 767 464 785 464 792 464 829 464 874 464 887 464 923 464 969 464 1017 464 1046 464 1067 464 1140 464 1209 464 1219 464 1234 464 1238 464 1249 464 1316 464 1332 464 1336 464 1351 464 1390 464 1418 464 1459 464 1481 465 26 465 82 465 193 465 200 465 222 465 259 465 312 465 327 465 338 465 405 465 436 465 465 465 518 465 560 465 598 465 658 465 734 465 802 465 871 465 892 465 934 465 1003 465 1035 465 1054 465 1113 465 1118 465 1124 465 1135 465 1147 465 1214 465 1266 465 1327 465 1330 465 1382 465 1442 465 1486 466 111 466 146 466 353 466 404 466 466 466 481 466 743 466 888 466 1232 466 1298 466 1466 466 1478 467 0 467 29 467 80 467 94 467 114 467 226 467 235 467 251 467 358 467 467 467 664 467 679 467 689 467 699 467 821 467 832 467 966 467 1012 467 1170 467 1175 467 1308 467 1399 467 1427 468 122 468 178 468 184 468 203 468 319 468 443 468 468 468 517 468 573 468 805 468 819 468 955 468 1101 468 1240 468 1246 468 1311 468 1323 468 1344 469 4 469 71 469 136 469 248 469 274 469 297 469 331 469 390 469 423 469 432 469 469 469 519 469 548 469 632 469 641 469 706 469 738 469 964 469 977 469 1053 469 1073 469 1130 469 1252 469 1255 469 1274 469 1328 469 1357 469 1367 469 1416 469 1422 469 1423 469 1451 469 1480 470 27 470 28 470 45 470 89 470 124 470 138 470 151 470 267 470 268 470 318 470 380 470 392 470 470 470 501 470 505 470 510 470 540 470 552 470 568 470 676 470 678 470 683 470 686 470 705 470 753 470 755 470 760 470 831 470 832 470 865 470 896 470 921 470 931 470 950 470 965 470 979 470 986 470 995 470 1007 470 1009 470 1060 470 1111 470 1120 470 1160 470 1215 470 1304 470 1321 470 1349 470 1417 470 1425 470 1446 470 1449 470 1465 470 1471 471 166 471 173 471 306 471 334 471 420 471 461 471 471 471 472 471 488 471 553 471 554 471 566 471 654 471 660 471 662 471 668 471 675 471 696 471 748 471 924 471 970 471 1040 471 1143 471 1191 471 1254 471 1272 471 1285 471 1302 471 1303 471 1308 471 1329 471 1405 471 1427 471 1469 472 88 472 166 472 173 472 209 472 334 472 420 472 426 472 461 472 471 472 472 472 488 472 553 472 554 472 572 472 675 472 696 472 710 472 723 472 788 472 899 472 924 472 1051 472 1096 472 1104 472 1143 472 1192 472 1254 472 1285 472 1293 472 1303 472 1391 472 1405 472 1427 472 1469 473 3 473 8 473 19 473 64 473 158 473 182 473 183 473 381 473 473 473 527 473 599 473 614 473 628 473 660 473 709 473 735 473 816 473 837 473 849 473 1040 473 1132 473 1144 473 1389 473 1419 473 1448 473 1455 473 1463 474 113 474 132 474 227 474 241 474 324 474 353 474 386 474 420 474 474 474 481 474 515 474 553 474 554 474 566 474 581 474 696 474 728 474 798 474 924 474 1232 474 1259 474 1285 474 1391 475 26 475 238 475 264 475 267 475 281 475 327 475 338 475 355 475 398 475 425 475 429 475 436 475 475 475 518 475 546 475 598 475 629 475 674 475 758 475 817 475 824 475 934 475 1011 475 1079 475 1085 475 1124 475 1145 475 1204 475 1266 475 1271 475 1305 475 1318 475 1321 475 1400 475 1413 476 214 476 236 476 415 476 476 476 595 476 793 476 850 476 856 476 876 476 981 476 984 476 1051 476 1117 476 1195 476 1306 476 1337 476 1342 477 84 477 88 477 166 477 168 477 173 477 334 477 409 477 420 477 426 477 477 477 488 477 489 477 572 477 710 477 737 477 788 477 899 477 917 477 1051 477 1062 477 1080 477 1093 477 1096 477 1104 477 1115 477 1143 477 1149 477 1192 477 1233 477 1293 477 1469 478 47 478 72 478 135 478 144 478 149 478 217 478 223 478 232 478 253 478 279 478 295 478 305 478 343 478 371 478 389 478 397 478 401 478 408 478 424 478 455 478 478 478 483 478 520 478 526 478 544 478 567 478 584 478 591 478 592 478 638 478 680 478 684 478 733 478 784 478 807 478 814 478 822 478 839 478 860 478 911 478 940 478 978 478 990 478 1014 478 1068 478 1078 478 1082 478 1097 478 1099 478 1136 478 1142 478 1180 478 1206 478 1216 478 1229 478 1235 478 1250 478 1281 478 1290 478 1355 478 1356 478 1361 478 1370 478 1375 478 1407 478 1441 478 1456 478 1474 478 1498 479 27 479 66 479 96 479 116 479 138 479 162 479 174 479 228 479 261 479 263 479 322 479 354 479 356 479 394 479 479 479 486 479 539 479 552 479 561 479 568 479 649 479 678 479 714 479 753 479 757 479 775 479 789 479 792 479 830 479 831 479 887 479 909 479 942 479 946 479 985 479 991 479 1016 479 1047 479 1072 479 1120 479 1125 479 1173 479 1213 479 1283 479 1372 479 1414 479 1446 480 151 480 185 480 238 480 264 480 281 480 301 480 359 480 398 480 419 480 430 480 436 480 480 480 529 480 546 480 597 480 598 480 650 480 663 480 665 480 674 480 721 480 758 480 760 480 821 480 824 480 842 480 986 480 996 480 1011 480 1019 480 1060 480 1070 480 1079 480 1085 480 1147 480 1197 480 1218 480 1266 480 1305 480 1318 480 1412 480 1440 480 1465 481 93 481 95 481 111 481 113 481 126 481 132 481 194 481 227 481 231 481 362 481 386 481 466 481 474 481 481 481 515 481 516 481 525 481 566 481 670 481 796 481 798 481 838 481 975 481 1001 481 1002 481 1036 481 1116 481 1119 481 1122 481 1232 481 1248 481 1259 481 1280 481 1298 481 1302 481 1391 481 1478 482 24 482 26 482 222 482 267 482 355 482 436 482 482 482 494 482 598 482 629 482 650 482 689 482 708 482 715 482 755 482 824 482 895 482 921 482 931 482 986 482 995 482 1007 482 1009 482 1314 482 1321 482 1349 482 1371 482 1403 482 1449 482 1485 483 14 483 47 483 79 483 92 483 125 483 160 483 223 483 230 483 272 483 279 483 295 483 371 483 373 483 387 483 389 483 408 483 441 483 478 483 483 483 600 483 612 483 624 483 630 483 638 483 640 483 648 483 690 483 694 483 784 483 807 483 814 483 839 483 882 483 910 483 911 483 940 483 978 483 1014 483 1018 483 1068 483 1075 483 1076 483 1078 483 1082 483 1099 483 1180 483 1196 483 1206 483 1217 483 1236 483 1277 483 1281 483 1355 483 1361 483 1370 483 1407 483 1441 483 1474 483 1484 484 14 484 79 484 92 484 189 484 279 484 373 484 404 484 452 484 455 484 484 484 491 484 520 484 526 484 556 484 567 484 591 484 600 484 606 484 611 484 612 484 624 484 638 484 640 484 684 484 690 484 743 484 807 484 822 484 844 484 867 484 875 484 910 484 911 484 990 484 999 484 1069 484 1075 484 1082 484 1196 484 1230 484 1236 484 1277 484 1290 484 1355 484 1356 484 1375 484 1484 485 9 485 15 485 54 485 121 485 158 485 182 485 205 485 221 485 229 485 285 485 351 485 381 485 462 485 485 485 490 485 536 485 618 485 685 485 698 485 701 485 735 485 815 485 823 485 827 485 837 485 864 485 905 485 1044 485 1144 485 1153 485 1183 485 1221 485 1258 485 1343 485 1360 485 1389 485 1448 485 1452 485 1455 486 66 486 96 486 127 486 131 486 235 486 243 486 263 486 356 486 392 486 459 486 479 486 486 486 501 486 576 486 649 486 678 486 679 486 715 486 726 486 746 486 757 486 767 486 772 486 775 486 786 486 789 486 797 486 830 486 879 486 881 486 887 486 921 486 929 486 931 486 942 486 946 486 1016 486 1047 486 1072 486 1173 486 1178 486 1213 486 1244 486 1349 486 1353 486 1362 486 1372 486 1410 487 81 487 99 487 100 487 106 487 134 487 140 487 188 487 260 487 329 487 337 487 382 487 393 487 406 487 417 487 430 487 445 487 487 487 505 487 510 487 550 487 585 487 596 487 616 487 717 487 754 487 762 487 781 487 790 487 806 487 820 487 890 487 918 487 929 487 949 487 968 487 988 487 1000 487 1019 487 1022 487 1045 487 1077 487 1094 487 1139 487 1158 487 1223 487 1226 487 1241 487 1251 487 1317 487 1408 487 1428 487 1445 487 1470 488 74 488 84 488 88 488 173 488 201 488 209 488 239 488 241 488 293 488 306 488 315 488 334 488 384 488 420 488 471 488 472 488 477 488 488 488 515 488 554 488 566 488 572 488 647 488 675 488 677 488 788 488 818 488 858 488 971 488 1006 488 1051 488 1062 488 1115 488 1143 488 1157 488 1192 488 1248 488 1293 488 1303 488 1307 488 1329 488 1469 489 62 489 88 489 105 489 166 489 168 489 173 489 215 489 258 489 334 489 346 489 409 489 426 489 477 489 489 489 572 489 710 489 788 489 826 489 899 489 917 489 954 489 1062 489 1080 489 1093 489 1096 489 1104 489 1114 489 1115 489 1134 489 1143 489 1149 489 1233 489 1293 489 1350 489 1405 489 1469 490 9 490 15 490 54 490 73 490 121 490 158 490 182 490 205 490 221 490 229 490 257 490 262 490 285 490 351 490 381 490 462 490 485 490 490 490 536 490 618 490 619 490 685 490 698 490 701 490 735 490 808 490 823 490 827 490 837 490 864 490 1044 490 1066 490 1102 490 1118 490 1144 490 1153 490 1183 490 1212 490 1221 490 1258 490 1340 490 1343 490 1360 490 1389 490 1448 490 1452 491 44 491 57 491 72 491 79 491 135 491 144 491 147 491 149 491 189 491 224 491 253 491 344 491 370 491 373 491 388 491 397 491 484 491 491 491 520 491 556 491 600 491 611 491 733 491 743 491 799 491 807 491 860 491 893 491 910 491 911 491 990 491 993 491 999 491 1027 491 1069 491 1082 491 1202 491 1217 491 1230 491 1235 491 1277 491 1278 491 1355 491 1358 491 1393 491 1456 491 1484 492 13 492 55 492 65 492 83 492 85 492 218 492 234 492 291 492 377 492 441 492 492 492 528 492 562 492 603 492 609 492 620 492 642 492 648 492 730 492 870 492 883 492 939 492 1028 492 1091 492 1098 492 1108 492 1129 492 1159 492 1225 492 1265 492 1291 492 1373 492 1496 493 33 493 61 493 110 493 141 493 155 493 169 493 299 493 341 493 342 493 364 493 379 493 447 493 458 493 493 493 504 493 514 493 578 493 586 493 687 493 704 493 749 493 773 493 843 493 904 493 913 493 915 493 941 493 943 493 956 493 1109 493 1189 493 1269 493 1312 493 1338 493 1345 493 1420 493 1421 493 1437 494 244 494 318 494 359 494 380 494 436 494 482 494 494 494 598 494 645 494 650 494 674 494 676 494 683 494 689 494 699 494 708 494 715 494 842 494 895 494 896 494 950 494 965 494 986 494 1009 494 1079 494 1304 494 1314 494 1321 494 1349 494 1449 495 32 495 34 495 40 495 136 495 150 495 171 495 207 495 213 495 237 495 274 495 307 495 317 495 423 495 439 495 495 495 588 495 744 495 783 495 813 495 835 495 848 495 853 495 859 495 868 495 869 495 889 495 926 495 936 495 1041 495 1103 495 1110 495 1138 495 1174 495 1237 495 1247 495 1262 495 1284 495 1296 495 1322 495 1347 495 1376 495 1381 495 1422 496 11 496 21 496 80 496 94 496 151 496 186 496 225 496 245 496 276 496 278 496 318 496 339 496 347 496 412 496 419 496 437 496 496 496 509 496 513 496 535 496 545 496 597 496 664 496 665 496 713 496 790 496 817 496 821 496 828 496 834 496 912 496 949 496 950 496 952 496 1011 496 1033 496 1045 496 1048 496 1063 496 1070 496 1152 496 1181 496 1201 496 1208 496 1215 496 1241 496 1251 496 1288 496 1408 496 1417 496 1425 496 1445 497 55 497 83 497 101 497 187 497 217 497 218 497 343 497 377 497 452 497 497 497 524 497 544 497 547 497 562 497 584 497 592 497 608 497 620 497 638 497 667 497 844 497 867 497 906 497 908 497 972 497 1034 497 1078 497 1091 497 1098 497 1198 497 1225 497 1291 497 1299 497 1313 497 1348 497 1361 497 1373 497 1474 497 1496 498 35 498 42 498 133 498 138 498 140 498 162 498 172 498 263 498 313 498 374 498 382 498 411 498 498 498 521 498 540 498 576 498 577 498 649 498 661 498 718 498 741 498 757 498 781 498 832 498 961 498 992 498 1049 498 1120 498 1223 498 1363 499 2 499 3 499 8 499 19 499 64 499 97 499 153 499 183 499 197 499 247 499 296 499 362 499 407 499 427 499 499 499 614 499 628 499 654 499 660 499 662 499 765 499 816 499 871 499 892 499 951 499 970 499 1001 499 1036 499 1050 499 1105 499 1132 499 1186 499 1222 499 1227 499 1242 499 1329 499 1354 499 1384 499 1419 500 39 500 43 500 46 500 77 500 104 500 105 500 109 500 112 500 118 500 176 500 208 500 258 500 309 500 346 500 369 500 410 500 456 500 500 500 532 500 557 500 565 500 633 500 651 500 724 500 747 500 779 500 826 500 878 500 891 500 902 500 927 500 957 500 976 500 1025 500 1030 500 1114 500 1128 500 1134 500 1182 500 1220 500 1243 500 1270 500 1279 500 1310 500 1350 500 1366 500 1368 500 1380 500 1439 500 1489 501 27 501 41 501 89 501 94 501 96 501 124 501 127 501 131 501 228 501 243 501 263 501 289 501 321 501 380 501 382 501 392 501 393 501 459 501 470 501 486 501 501 501 502 501 513 501 535 501 594 501 649 501 678 501 679 501 713 501 726 501 741 501 746 501 757 501 772 501 775 501 786 501 789 501 797 501 810 501 830 501 831 501 879 501 896 501 918 501 921 501 925 501 929 501 942 501 946 501 968 501 1016 501 1048 501 1072 501 1111 501 1160 501 1201 501 1213 501 1251 501 1349 501 1372 501 1410 501 1414 501 1425 501 1445 501 1449 502 24 502 66 502 127 502 193 502 228 502 243 502 250 502 392 502 425 502 501 502 502 502 535 502 539 502 649 502 678 502 679 502 753 502 775 502 879 502 925 502 938 502 979 502 985 502 1016 502 1064 502 1072 502 1111 502 1160 502 1165 502 1341 502 1349 502 1353 502 1372 502 1403 502 1449 503 10 503 23 503 37 503 49 503 184 503 198 503 357 503 376 503 443 503 457 503 503 503 517 503 542 503 551 503 555 503 559 503 573 503 582 503 589 503 601 503 627 503 657 503 666 503 673 503 725 503 750 503 756 503 766 503 770 503 805 503 898 503 933 503 1008 503 1020 503 1087 503 1088 503 1101 503 1107 503 1166 503 1185 503 1246 503 1323 503 1344 503 1429 503 1433 503 1457 503 1483 503 1492 503 1495 504 10 504 33 504 50 504 61 504 110 504 141 504 169 504 195 504 210 504 299 504 314 504 341 504 342 504 364 504 379 504 447 504 458 504 493 504 504 504 514 504 571 504 578 504 586 504 687 504 704 504 749 504 811 504 904 504 913 504 915 504 943 504 956 504 1109 504 1168 504 1189 504 1269 504 1275 504 1312 504 1338 504 1352 504 1374 504 1420 504 1421 504 1437 504 1495 505 28 505 45 505 89 505 99 505 138 505 380 505 470 505 487 505 505 505 510 505 540 505 585 505 665 505 676 505 681 505 686 505 717 505 795 505 865 505 890 505 896 505 921 505 950 505 965 505 968 505 986 505 988 505 1000 505 1019 505 1060 505 1160 505 1226 505 1251 505 1304 505 1408 505 1425 505 1445 505 1446 505 1471 506 24 506 30 506 38 506 53 506 90 506 180 506 222 506 262 506 269 506 270 506 323 506 340 506 431 506 506 506 511 506 549 506 610 506 637 506 702 506 769 506 778 506 808 506 923 506 983 506 1187 506 1219 506 1334 506 1336 506 1359 506 1415 506 1486 507 22 507 107 507 143 507 156 507 266 507 378 507 446 507 449 507 507 507 543 507 558 507 570 507 604 507 607 507 613 507 621 507 739 507 791 507 854 507 862 507 873 507 900 507 920 507 935 507 937 507 962 507 1071 507 1090 507 1127 507 1146 507 1156 507 1162 507 1176 507 1184 507 1294 507 1386 507 1444 508 7 508 91 508 143 508 167 508 219 508 326 508 350 508 416 508 418 508 446 508 508 508 555 508 583 508 604 508 613 508 636 508 639 508 644 508 669 508 691 508 727 508 732 508 777 508 800 508 854 508 886 508 903 508 928 508 937 508 987 508 1010 508 1015 508 1038 508 1146 508 1151 508 1154 508 1167 508 1200 508 1205 508 1211 508 1257 508 1268 508 1273 508 1289 508 1346 508 1388 508 1431 508 1450 508 1479 509 11 509 21 509 80 509 179 509 225 509 245 509 249 509 276 509 278 509 339 509 347 509 412 509 419 509 437 509 496 509 509 509 545 509 602 509 656 509 682 509 713 509 768 509 787 509 821 509 828 509 845 509 880 509 912 509 922 509 949 509 952 509 966 509 1022 509 1045 509 1063 509 1152 509 1170 509 1175 509 1190 509 1288 509 1335 510 41 510 81 510 99 510 106 510 151 510 188 510 199 510 245 510 284 510 318 510 329 510 337 510 347 510 380 510 382 510 430 510 470 510 487 510 505 510 510 510 529 510 550 510 585 510 665 510 674 510 686 510 713 510 717 510 760 510 781 510 787 510 790 510 820 510 890 510 929 510 949 510 950 510 965 510 986 510 988 510 1000 510 1019 510 1048 510 1060 510 1081 510 1152 510 1190 510 1223 510 1226 510 1241 510 1251 510 1286 510 1304 510 1408 510 1425 510 1445 510 1449 510 1465 510 1471 511 30 511 53 511 78 511 82 511 90 511 102 511 130 511 191 511 212 511 262 511 270 511 286 511 308 511 428 511 451 511 460 511 506 511 511 511 533 511 537 511 549 511 563 511 610 511 619 511 631 511 637 511 658 511 685 511 702 511 752 511 761 511 785 511 812 511 829 511 863 511 884 511 905 511 923 511 1003 511 1057 511 1065 511 1084 511 1135 511 1141 511 1183 511 1219 511 1336 511 1360 511 1390 511 1418 511 1459 511 1481 512 6 512 25 512 48 512 108 512 146 512 163 512 256 512 273 512 303 512 363 512 438 512 512 512 521 512 635 512 688 512 718 512 740 512 782 512 810 512 852 512 880 512 961 512 998 512 1004 512 1031 512 1049 512 1052 512 1086 512 1163 512 1177 512 1208 512 1239 512 1263 512 1362 512 1363 512 1399 512 1466 512 1488 513 41 513 81 513 127 513 134 513 138 513 228 513 243 513 276 513 318 513 337 513 347 513 392 513 393 513 459 513 496 513 501 513 513 513 535 513 545 513 713 513 726 513 775 513 790 513 817 513 828 513 834 513 912 513 918 513 929 513 946 513 968 513 979 513 1000 513 1016 513 1033 513 1048 513 1070 513 1081 513 1215 513 1241 513 1251 513 1286 513 1392 513 1408 513 1425 513 1445 513 1449 514 33 514 50 514 61 514 68 514 141 514 155 514 169 514 294 514 299 514 300 514 314 514 342 514 364 514 379 514 433 514 458 514 493 514 504 514 514 514 538 514 571 514 578 514 773 514 904 514 913 514 930 514 1188 514 1189 514 1269 514 1312 514 1338 514 1420 514 1437 515 74 515 84 515 93 515 95 515 113 515 120 515 126 515 132 515 201 515 227 515 231 515 239 515 241 515 271 515 275 515 282 515 293 515 306 515 311 515 315 515 324 515 386 515 474 515 481 515 488 515 515 515 554 515 564 515 566 515 581 515 719 515 798 515 804 515 838 515 858 515 971 515 975 515 1002 515 1023 515 1058 515 1116 515 1119 515 1122 515 1157 515 1232 515 1248 515 1259 515 1280 515 1282 515 1285 515 1391 515 1394 515 1435 515 1478 516 2 516 93 516 95 516 111 516 113 516 117 516 126 516 153 516 194 516 227 516 231 516 241 516 247 516 282 516 296 516 353 516 362 516 427 516 450 516 454 516 463 516 481 516 516 516 564 516 670 516 796 516 801 516 838 516 970 516 975 516 982 516 1001 516 1002 516 1036 516 1050 516 1056 516 1105 516 1116 516 1119 516 1122 516 1133 516 1186 516 1194 516 1248 516 1253 516 1256 516 1260 516 1280 516 1282 516 1298 516 1385 516 1394 516 1396 516 1478 517 10 517 23 517 49 517 122 517 184 517 198 517 203 517 376 517 443 517 468 517 503 517 517 517 555 517 573 517 582 517 643 517 693 517 697 517 750 517 756 517 805 517 819 517 898 517 955 517 1008 517 1020 517 1101 517 1107 517 1166 517 1240 517 1246 517 1323 517 1344 517 1352 517 1364 517 1429 517 1433 517 1457 518 238 518 264 518 281 518 298 518 301 518 327 518 330 518 338 518 398 518 442 518 465 518 475 518 518 518 560 518 598 518 674 518 734 518 765 518 803 518 824 518 866 518 1011 518 1085 518 1124 518 1145 518 1147 518 1228 518 1266 518 1271 518 1305 518 1330 518 1371 518 1400 518 1412 518 1413 519 4 519 71 519 155 519 248 519 331 519 336 519 432 519 469 519 519 519 538 519 548 519 632 519 716 519 738 519 977 519 1053 519 1073 519 1188 519 1328 519 1357 519 1367 519 1404 519 1416 519 1423 519 1451 519 1480 520 72 520 79 520 135 520 144 520 164 520 189 520 217 520 370 520 373 520 387 520 391 520 397 520 401 520 424 520 455 520 478 520 484 520 491 520 520 520 526 520 556 520 584 520 591 520 600 520 611 520 638 520 680 520 784 520 844 520 867 520 906 520 911 520 940 520 972 520 978 520 990 520 999 520 1014 520 1034 520 1179 520 1180 520 1198 520 1216 520 1230 520 1277 520 1290 520 1393 520 1484 521 6 521 45 521 134 521 138 521 140 521 256 521 278 521 374 521 393 521 406 521 411 521 413 521 498 521 512 521 521 521 635 521 688 521 718 521 741 521 757 521 772 521 781 521 782 521 797 521 832 521 880 521 918 521 998 521 1048 521 1049 521 1086 521 1094 521 1139 521 1163 521 1164 521 1181 521 1223 521 1239 521 1362 521 1399 521 1453 522 51 522 116 522 129 522 133 522 145 522 172 522 174 522 180 522 304 522 325 522 348 522 431 522 522 522 537 522 590 522 594 522 629 522 695 522 708 522 729 522 731 522 769 522 776 522 884 522 885 522 897 522 944 522 980 522 983 522 992 522 1007 522 1046 522 1141 522 1178 522 1199 522 1204 522 1209 522 1244 522 1261 522 1316 522 1339 522 1468 523 25 523 163 523 273 523 310 523 372 523 415 523 523 523 692 523 740 523 793 523 845 523 850 523 880 523 894 523 932 523 963 523 974 523 982 523 1004 523 1163 523 1239 523 1335 523 1385 523 1447 523 1466 524 36 524 55 524 56 524 83 524 101 524 164 524 187 524 218 524 291 524 343 524 391 524 408 524 497 524 524 524 547 524 562 524 592 524 608 524 620 524 638 524 667 524 680 524 844 524 867 524 870 524 906 524 908 524 972 524 1034 524 1091 524 1098 524 1198 524 1225 524 1299 524 1348 524 1361 524 1373 524 1474 524 1496 525 74 525 227 525 306 525 420 525 461 525 481 525 525 525 553 525 581 525 659 525 668 525 696 525 748 525 788 525 798 525 804 525 818 525 1002 525 1040 525 1080 525 1096 525 1192 525 1272 525 1302 526 14 526 79 526 217 526 279 526 295 526 373 526 401 526 404 526 408 526 452 526 478 526 484 526 520 526 526 526 567 526 606 526 680 526 684 526 784 526 822 526 839 526 867 526 875 526 940 526 978 526 1014 526 1018 526 1097 526 1098 526 1216 526 1229 526 1236 526 1250 526 1281 526 1290 526 1291 526 1313 526 1331 526 1348 526 1356 526 1375 526 1407 526 1441 526 1498 527 3 527 64 527 183 527 473 527 527 527 599 527 660 527 709 527 849 527 1040 527 1132 527 1419 528 5 528 12 528 13 528 14 528 65 528 92 528 160 528 165 528 218 528 234 528 240 528 291 528 377 528 434 528 441 528 452 528 492 528 528 528 544 528 603 528 606 528 609 528 612 528 624 528 630 528 642 528 648 528 690 528 882 528 883 528 939 528 1026 528 1028 528 1075 528 1076 528 1159 528 1196 528 1225 528 1236 528 1265 528 1291 528 1461 529 81 529 99 529 106 529 151 529 185 529 188 529 347 529 419 529 430 529 480 529 510 529 529 529 546 529 550 529 585 529 665 529 674 529 682 529 721 529 760 529 820 529 821 529 842 529 949 529 986 529 996 529 1019 529 1022 529 1060 529 1063 529 1070 529 1197 529 1318 529 1440 529 1465 530 22 530 87 530 156 530 266 530 292 530 336 530 378 530 396 530 403 530 449 530 530 530 543 530 558 530 583 530 604 530 621 530 669 530 707 530 727 530 739 530 763 530 764 530 791 530 873 530 900 530 903 530 920 530 948 530 960 530 994 530 1005 530 1037 530 1038 530 1090 530 1176 530 1224 530 1267 530 1287 530 1289 530 1324 530 1326 530 1386 530 1436 530 1444 530 1464 530 1493 531 17 531 124 531 129 531 192 531 255 531 313 531 395 531 413 531 531 531 577 531 590 531 634 531 700 531 711 531 786 531 851 531 852 531 881 531 991 531 1092 531 1123 531 1125 531 1155 531 1173 531 1193 531 1292 532 43 532 46 532 62 532 104 532 105 532 118 532 176 532 208 532 287 532 309 532 456 532 500 532 532 532 557 532 565 532 651 532 710 532 747 532 826 532 878 532 899 532 902 532 927 532 957 532 1030 532 1114 532 1182 532 1220 532 1243 532 1264 532 1270 532 1350 532 1366 532 1368 532 1380 532 1383 532 1489 533 53 533 58 533 78 533 82 533 90 533 102 533 191 533 211 533 229 533 257 533 351 533 405 533 428 533 451 533 511 533 533 533 534 533 549 533 610 533 619 533 626 533 658 533 702 533 785 533 808 533 812 533 863 533 901 533 923 533 1003 533 1024 533 1054 533 1084 533 1135 533 1183 533 1334 533 1340 533 1360 533 1459 534 30 534 38 534 53 534 58 534 78 534 86 534 191 534 212 534 216 534 229 534 257 534 262 534 349 534 351 534 405 534 428 534 431 534 451 534 464 534 533 534 534 534 579 534 610 534 618 534 619 534 626 534 637 534 720 534 792 534 808 534 812 534 863 534 874 534 923 534 959 534 1017 534 1024 534 1057 534 1065 534 1084 534 1131 534 1137 534 1219 534 1234 534 1238 534 1249 534 1309 534 1334 534 1336 534 1351 534 1360 534 1418 534 1475 535 21 535 80 535 127 535 228 535 245 535 251 535 276 535 318 535 329 535 337 535 347 535 392 535 412 535 437 535 496 535 501 535 502 535 513 535 535 535 678 535 713 535 775 535 790 535 817 535 834 535 912 535 925 535 938 535 946 535 950 535 952 535 979 535 986 535 1009 535 1016 535 1033 535 1045 535 1048 535 1070 535 1201 535 1215 535 1241 535 1286 535 1288 535 1392 535 1408 535 1425 535 1445 535 1449 535 1471 536 9 536 15 536 54 536 90 536 102 536 121 536 191 536 205 536 222 536 262 536 285 536 312 536 323 536 351 536 485 536 490 536 536 536 579 536 610 536 618 536 619 536 658 536 685 536 698 536 701 536 734 536 778 536 802 536 808 536 815 536 823 536 827 536 863 536 864 536 905 536 959 536 1024 536 1035 536 1044 536 1054 536 1102 536 1118 536 1124 536 1153 536 1183 536 1212 536 1221 536 1258 536 1334 536 1340 536 1343 536 1360 536 1382 536 1452 536 1486 537 30 537 53 537 78 537 82 537 90 537 102 537 174 537 175 537 180 537 191 537 212 537 270 537 304 537 332 537 348 537 349 537 451 537 460 537 511 537 522 537 537 537 549 537 610 537 658 537 761 537 776 537 812 537 829 537 863 537 884 537 897 537 923 537 967 537 980 537 1003 537 1057 537 1124 537 1135 537 1137 537 1141 537 1204 537 1334 537 1390 537 1459 537 1481 538 20 538 50 538 68 538 75 538 141 538 203 538 294 538 300 538 314 538 333 538 336 538 357 538 368 538 402 538 433 538 514 538 519 538 538 538 551 538 571 538 671 538 673 538 697 538 916 538 930 538 1088 538 1100 538 1188 538 1203 538 1300 538 1364 538 1404 538 1460 538 1462 538 1490 539 24 539 66 539 116 539 137 539 145 539 174 539 175 539 206 539 235 539 261 539 322 539 323 539 325 539 356 539 425 539 429 539 444 539 479 539 502 539 539 539 552 539 568 539 576 539 646 539 678 539 705 539 714 539 753 539 755 539 767 539 771 539 776 539 885 539 944 539 985 539 995 539 1064 539 1072 539 1165 539 1173 539 1178 539 1204 539 1244 539 1261 539 1339 539 1353 539 1372 539 1401 539 1403 540 35 540 45 540 89 540 124 540 138 540 140 540 151 540 188 540 245 540 281 540 284 540 313 540 321 540 363 540 374 540 382 540 406 540 470 540 498 540 505 540 540 540 577 540 681 540 682 540 686 540 695 540 753 540 772 540 781 540 782 540 831 540 832 540 852 540 865 540 896 540 929 540 950 540 961 540 995 540 1032 540 1060 540 1158 540 1160 540 1201 540 1223 540 1251 540 1304 540 1425 541 43 541 46 541 60 541 77 541 118 541 154 541 176 541 208 541 280 541 287 541 369 541 385 541 410 541 456 541 541 541 557 541 565 541 633 541 724 541 747 541 779 541 861 541 891 541 902 541 927 541 957 541 976 541 1013 541 1025 541 1030 541 1128 541 1150 541 1210 541 1243 541 1279 541 1295 541 1310 541 1366 541 1380 541 1439 541 1489 542 10 542 23 542 103 542 184 542 198 542 210 542 341 542 376 542 503 542 542 542 578 542 582 542 601 542 643 542 666 542 687 542 693 542 704 542 725 542 750 542 811 542 898 542 913 542 915 542 943 542 1008 542 1095 542 1109 542 1168 542 1240 542 1246 542 1275 542 1297 542 1300 542 1312 542 1323 542 1338 542 1352 542 1374 542 1421 542 1429 542 1457 542 1492 542 1495 543 22 543 156 543 159 543 196 543 266 543 345 543 378 543 396 543 403 543 448 543 449 543 507 543 530 543 543 543 570 543 583 543 605 543 621 543 707 543 739 543 763 543 764 543 791 543 854 543 862 543 873 543 900 543 903 543 920 543 947 543 948 543 960 543 994 543 1005 543 1037 543 1038 543 1090 543 1126 543 1162 543 1174 543 1176 543 1224 543 1252 543 1267 543 1287 543 1324 543 1325 543 1386 543 1434 543 1436 543 1444 543 1493 544 13 544 83 544 187 544 217 544 234 544 371 544 377 544 452 544 478 544 497 544 528 544 544 544 562 544 567 544 584 544 603 544 640 544 648 544 807 544 875 544 883 544 972 544 1078 544 1099 544 1142 544 1159 544 1225 544 1236 544 1250 544 1313 544 1348 544 1356 544 1361 544 1373 544 1375 544 1496 545 0 545 11 545 21 545 29 545 51 545 151 545 186 545 199 545 276 545 278 545 339 545 347 545 412 545 419 545 437 545 496 545 509 545 513 545 545 545 597 545 661 545 665 545 676 545 699 545 713 545 729 545 787 545 817 545 821 545 828 545 872 545 880 545 912 545 949 545 950 545 952 545 996 545 1011 545 1033 545 1063 545 1086 545 1152 545 1163 545 1208 545 1215 545 1239 545 1362 545 1398 545 1417 545 1487 546 98 546 185 546 264 546 288 546 301 546 358 546 359 546 398 546 436 546 475 546 480 546 529 546 546 546 597 546 598 546 650 546 663 546 665 546 674 546 721 546 758 546 760 546 771 546 842 546 986 546 996 546 1009 546 1019 546 1079 546 1085 546 1197 546 1218 546 1266 546 1305 546 1318 546 1412 546 1440 546 1465 547 36 547 55 547 56 547 83 547 101 547 164 547 187 547 217 547 218 547 291 547 343 547 371 547 377 547 391 547 408 547 497 547 524 547 547 547 562 547 592 547 606 547 608 547 620 547 638 547 667 547 680 547 730 547 867 547 870 547 906 547 908 547 972 547 1034 547 1091 547 1098 547 1180 547 1198 547 1225 547 1299 547 1348 547 1361 547 1373 547 1474 547 1496 548 136 548 148 548 159 548 297 548 336 548 390 548 423 548 432 548 469 548 519 548 548 548 641 548 706 548 707 548 763 548 764 548 960 548 964 548 977 548 1005 548 1037 548 1130 548 1184 548 1224 548 1252 548 1255 548 1274 548 1287 548 1324 548 1328 548 1367 548 1404 548 1416 548 1422 548 1423 548 1436 548 1464 548 1480 548 1493 549 30 549 38 549 53 549 73 549 78 549 82 549 102 549 130 549 180 549 191 549 211 549 212 549 270 549 286 549 308 549 338 549 428 549 431 549 451 549 460 549 506 549 511 549 533 549 537 549 549 549 610 549 631 549 637 549 655 549 658 549 702 549 752 549 761 549 769 549 778 549 812 549 829 549 863 549 884 549 905 549 923 549 983 549 1003 549 1057 549 1065 549 1084 549 1135 549 1219 549 1249 549 1336 549 1359 549 1390 549 1418 549 1459 549 1481 550 81 550 99 550 106 550 188 550 249 550 265 550 329 550 430 550 487 550 510 550 529 550 550 550 585 550 602 550 656 550 717 550 820 550 855 550 922 550 949 550 1019 550 1022 550 1063 550 1070 550 1190 550 1223 550 1317 550 1408 550 1428 550 1465 551 10 551 37 551 49 551 68 551 75 551 128 551 198 551 203 551 210 551 290 551 357 551 360 551 368 551 376 551 402 551 433 551 443 551 457 551 503 551 538 551 551 551 555 551 559 551 571 551 573 551 582 551 622 551 627 551 657 551 673 551 697 551 703 551 725 551 750 551 756 551 766 551 805 551 811 551 898 551 916 551 930 551 1020 551 1088 551 1100 551 1107 551 1166 551 1203 551 1257 551 1323 551 1352 551 1374 551 1433 551 1457 551 1460 551 1490 551 1492 551 1495 552 27 552 28 552 116 552 124 552 138 552 172 552 206 552 235 552 267 552 321 552 322 552 325 552 354 552 356 552 444 552 470 552 479 552 539 552 552 552 561 552 568 552 580 552 646 552 652 552 678 552 705 552 714 552 753 552 797 552 830 552 832 552 885 552 909 552 931 552 942 552 985 552 991 552 995 552 1064 552 1072 552 1111 552 1120 552 1244 552 1292 552 1316 552 1339 552 1403 552 1414 552 1446 552 1494 553 88 553 166 553 306 553 334 553 420 553 461 553 471 553 472 553 474 553 525 553 553 553 572 553 659 553 668 553 696 553 723 553 728 553 737 553 748 553 804 553 818 553 924 553 1062 553 1080 553 1096 553 1104 553 1143 553 1149 553 1192 553 1254 553 1272 553 1285 553 1293 553 1303 553 1319 553 1391 553 1405 553 1427 553 1469 554 2 554 74 554 84 554 95 554 111 554 113 554 132 554 173 554 201 554 209 554 227 554 239 554 241 554 247 554 275 554 293 554 306 554 315 554 334 554 353 554 362 554 384 554 386 554 420 554 471 554 472 554 474 554 488 554 515 554 554 554 566 554 675 554 723 554 858 554 924 554 970 554 971 554 1105 554 1122 554 1143 554 1157 554 1186 554 1192 554 1232 554 1248 554 1254 554 1256 554 1285 554 1303 554 1329 554 1391 555 23 555 37 555 49 555 75 555 123 555 128 555 167 555 178 555 184 555 198 555 219 555 290 555 319 555 326 555 350 555 360 555 376 555 402 555 416 555 418 555 422 555 443 555 457 555 503 555 508 555 517 555 551 555 555 555 559 555 573 555 574 555 582 555 589 555 593 555 622 555 639 555 644 555 657 555 673 555 703 555 725 555 732 555 756 555 766 555 770 555 777 555 800 555 805 555 886 555 916 555 933 555 955 555 1010 555 1015 555 1020 555 1087 555 1101 555 1107 555 1112 555 1166 555 1167 555 1185 555 1200 555 1203 555 1205 555 1211 555 1257 555 1268 555 1273 555 1311 555 1346 555 1388 555 1431 555 1433 555 1457 555 1479 555 1483 555 1492 556 72 556 79 556 135 556 147 556 149 556 189 556 253 556 272 556 344 556 373 556 387 556 397 556 401 556 404 556 455 556 484 556 491 556 520 556 556 556 591 556 600 556 611 556 640 556 684 556 733 556 743 556 784 556 807 556 844 556 875 556 910 556 911 556 978 556 990 556 993 556 999 556 1014 556 1069 556 1082 556 1180 556 1196 556 1206 556 1217 556 1230 556 1235 556 1277 556 1290 556 1355 556 1358 556 1370 556 1375 556 1393 556 1441 556 1456 556 1474 556 1484 557 43 557 46 557 104 557 118 557 154 557 176 557 287 557 309 557 369 557 385 557 456 557 500 557 532 557 541 557 557 557 565 557 651 557 724 557 747 557 779 557 878 557 902 557 927 557 957 557 1013 557 1128 557 1150 557 1182 557 1210 557 1243 557 1264 557 1270 557 1279 557 1295 557 1366 557 1380 557 1439 557 1489 558 22 558 107 558 156 558 170 558 266 558 378 558 449 558 507 558 530 558 558 558 570 558 607 558 613 558 621 558 763 558 791 558 862 558 873 558 900 558 937 558 1071 558 1127 558 1146 558 1156 558 1161 558 1162 558 1176 558 1184 558 1224 558 1402 558 1404 558 1444 558 1450 558 1464 559 10 559 37 559 49 559 68 559 128 559 170 559 184 559 198 559 210 559 290 559 299 559 300 559 350 559 357 559 376 559 402 559 433 559 503 559 551 559 555 559 559 559 578 559 593 559 601 559 622 559 627 559 657 559 703 559 704 559 725 559 756 559 766 559 770 559 886 559 898 559 916 559 933 559 1008 559 1020 559 1029 559 1088 559 1100 559 1166 559 1169 559 1189 559 1203 559 1257 559 1300 559 1338 559 1388 559 1433 559 1457 559 1460 559 1462 559 1483 559 1490 559 1492 560 0 560 73 560 130 560 152 560 200 560 205 560 222 560 259 560 288 560 312 560 338 560 442 560 465 560 518 560 560 560 587 560 655 560 702 560 734 560 752 560 778 560 815 560 872 560 892 560 983 560 1084 560 1135 560 1214 560 1271 560 1327 560 1330 560 1371 560 1382 560 1398 560 1400 560 1413 560 1481 561 27 561 38 561 96 561 255 561 277 561 322 561 354 561 395 561 399 561 440 561 479 561 552 561 561 561 590 561 652 561 711 561 714 561 881 561 887 561 909 561 942 561 992 561 1092 561 1140 561 1209 561 1283 561 1414 562 13 562 55 562 83 562 85 562 101 562 187 562 218 562 291 562 377 562 452 562 492 562 497 562 524 562 544 562 547 562 562 562 608 562 620 562 667 562 730 562 867 562 870 562 883 562 908 562 1091 562 1098 562 1225 562 1291 562 1313 562 1348 562 1361 562 1373 562 1496 563 26 563 30 563 53 563 58 563 82 563 86 563 90 563 102 563 175 563 191 563 211 563 212 563 233 563 250 563 270 563 277 563 332 563 349 563 405 563 440 563 444 563 451 563 511 563 563 563 579 563 623 563 626 563 658 563 701 563 720 563 785 563 846 563 863 563 901 563 934 563 959 563 1024 563 1035 563 1054 563 1057 563 1102 563 1113 563 1131 563 1137 563 1212 563 1283 563 1309 563 1340 563 1341 563 1390 563 1459 563 1475 564 2 564 74 564 84 564 93 564 95 564 120 564 126 564 132 564 194 564 201 564 227 564 231 564 239 564 241 564 271 564 275 564 282 564 296 564 311 564 315 564 362 564 450 564 454 564 463 564 515 564 516 564 564 564 670 564 719 564 796 564 801 564 838 564 858 564 971 564 975 564 1001 564 1023 564 1036 564 1050 564 1056 564 1058 564 1116 564 1119 564 1122 564 1157 564 1194 564 1248 564 1253 564 1280 564 1282 564 1354 564 1377 564 1384 564 1394 564 1395 564 1396 564 1435 564 1478 565 43 565 46 565 60 565 104 565 118 565 176 565 208 565 287 565 309 565 369 565 385 565 456 565 500 565 532 565 541 565 557 565 565 565 651 565 724 565 747 565 779 565 878 565 902 565 927 565 957 565 1013 565 1025 565 1030 565 1150 565 1182 565 1210 565 1220 565 1243 565 1264 565 1270 565 1279 565 1295 565 1366 565 1380 565 1489 566 113 566 132 566 201 566 227 566 241 566 247 566 293 566 306 566 353 566 362 566 384 566 386 566 471 566 474 566 481 566 488 566 515 566 554 566 566 566 675 566 696 566 798 566 818 566 924 566 1122 566 1186 566 1232 566 1254 566 1259 566 1272 566 1285 566 1302 566 1329 566 1391 567 79 567 217 567 223 567 253 567 279 567 408 567 452 567 478 567 484 567 526 567 544 567 567 567 584 567 591 567 606 567 608 567 624 567 640 567 684 567 690 567 807 567 822 567 839 567 875 567 883 567 908 567 972 567 1034 567 1078 567 1082 567 1206 567 1216 567 1229 567 1236 567 1250 567 1290 567 1313 567 1348 567 1356 567 1361 567 1370 567 1375 567 1498 568 116 568 138 568 174 568 206 568 235 568 325 568 356 568 470 568 479 568 539 568 552 568 568 568 646 568 678 568 705 568 714 568 753 568 755 568 797 568 832 568 885 568 909 568 925 568 942 568 979 568 985 568 995 568 1072 568 1120 568 1204 568 1261 568 1286 568 1339 568 1372 568 1401 568 1411 569 5 569 14 569 36 569 92 569 160 569 202 569 230 569 240 569 272 569 365 569 373 569 387 569 434 569 441 569 569 569 606 569 612 569 624 569 630 569 730 569 809 569 867 569 882 569 999 569 1018 569 1075 569 1076 569 1108 569 1196 569 1277 569 1331 569 1369 569 1461 569 1472 569 1476 569 1484 570 22 570 107 570 143 570 156 570 266 570 378 570 449 570 507 570 543 570 558 570 570 570 604 570 607 570 613 570 621 570 739 570 791 570 854 570 862 570 900 570 920 570 937 570 994 570 1071 570 1090 570 1127 570 1146 570 1156 570 1162 570 1176 570 1386 570 1444 571 50 571 68 571 75 571 141 571 195 571 210 571 294 571 299 571 300 571 314 571 333 571 342 571 357 571 368 571 379 571 433 571 504 571 514 571 538 571 551 571 571 571 657 571 697 571 704 571 811 571 836 571 904 571 916 571 930 571 1088 571 1109 571 1188 571 1189 571 1203 571 1269 571 1275 571 1300 571 1338 571 1352 571 1364 571 1374 571 1420 571 1437 571 1460 571 1495 572 62 572 88 572 173 572 209 572 334 572 420 572 426 572 472 572 477 572 488 572 489 572 553 572 572 572 581 572 659 572 710 572 723 572 728 572 737 572 788 572 818 572 899 572 917 572 1006 572 1062 572 1080 572 1093 572 1096 572 1104 572 1114 572 1115 572 1143 572 1149 572 1192 572 1233 572 1293 572 1469 573 37 573 49 573 122 573 178 573 184 573 203 573 376 573 443 573 468 573 503 573 517 573 551 573 555 573 573 573 589 573 639 573 657 573 693 573 697 573 725 573 750 573 756 573 766 573 805 573 836 573 1087 573 1107 573 1185 573 1200 573 1246 573 1323 573 1364 573 1483 573 1492 574 37 574 49 574 128 574 290 574 443 574 555 574 574 574 582 574 589 574 639 574 770 574 800 574 805 574 933 574 955 574 1020 574 1167 574 1169 574 1246 574 1273 574 1364 574 1379 574 1429 574 1431 574 1433 574 1483 575 6 575 17 575 42 575 172 575 263 575 268 575 283 575 303 575 304 575 352 575 380 575 394 575 399 575 464 575 575 575 576 575 580 575 623 575 625 575 634 575 681 575 695 575 708 575 745 575 767 575 810 575 830 575 896 575 921 575 931 575 961 575 969 575 1007 575 1039 575 1059 575 1067 575 1160 575 1199 575 1316 575 1333 575 1378 575 1468 575 1499 576 6 576 42 576 66 576 124 576 129 576 131 576 145 576 162 576 172 576 261 576 263 576 322 576 325 576 328 576 392 576 394 576 395 576 486 576 498 576 539 576 575 576 576 576 634 576 649 576 678 576 757 576 767 576 786 576 810 576 887 576 921 576 942 576 944 576 946 576 961 576 969 576 992 576 1007 576 1072 576 1125 576 1155 576 1160 576 1173 576 1178 576 1209 576 1244 576 1333 576 1353 577 35 577 140 577 162 577 172 577 188 577 284 577 313 577 321 577 363 577 374 577 382 577 406 577 411 577 498 577 531 577 540 577 577 577 718 577 741 577 781 577 782 577 789 577 831 577 852 577 881 577 918 577 929 577 961 577 991 577 1049 577 1092 577 1094 577 1123 577 1213 577 1223 577 1251 577 1292 578 10 578 50 578 61 578 103 578 110 578 198 578 210 578 299 578 341 578 342 578 357 578 364 578 379 578 447 578 493 578 504 578 514 578 542 578 559 578 578 578 586 578 601 578 643 578 666 578 687 578 704 578 811 578 898 578 913 578 915 578 1008 578 1095 578 1109 578 1168 578 1189 578 1297 578 1312 578 1338 578 1420 578 1437 579 26 579 53 579 78 579 82 579 86 579 102 579 191 579 200 579 211 579 277 579 308 579 312 579 332 579 348 579 349 579 405 579 428 579 444 579 451 579 534 579 536 579 563 579 579 579 610 579 626 579 658 579 846 579 863 579 901 579 959 579 1024 579 1035 579 1066 579 1084 579 1102 579 1113 579 1131 579 1135 579 1137 579 1183 579 1212 579 1221 579 1309 579 1327 579 1340 579 1459 579 1475 579 1481 579 1486 579 1494 580 53 580 66 580 206 580 211 580 212 580 216 580 263 580 277 580 283 580 286 580 322 580 325 580 328 580 348 580 349 580 354 580 394 580 399 580 405 580 431 580 440 580 444 580 451 580 464 580 552 580 575 580 580 580 623 580 625 580 631 580 652 580 681 580 720 580 776 580 792 580 795 580 829 580 874 580 923 580 980 580 1024 580 1046 580 1059 580 1064 580 1131 580 1137 580 1140 580 1141 580 1199 580 1238 580 1316 580 1336 580 1351 580 1378 580 1390 580 1403 580 1481 580 1494 581 88 581 132 581 209 581 227 581 324 581 386 581 420 581 474 581 515 581 525 581 572 581 581 581 659 581 723 581 728 581 737 581 788 581 798 581 818 581 1006 581 1062 581 1093 581 1104 581 1115 581 1149 581 1192 581 1232 581 1259 581 1293 581 1391 582 10 582 23 582 49 582 68 582 75 582 184 582 198 582 290 582 360 582 368 582 376 582 443 582 503 582 517 582 542 582 551 582 555 582 574 582 582 582 643 582 657 582 673 582 693 582 697 582 756 582 770 582 805 582 811 582 898 582 955 582 1008 582 1020 582 1101 582 1107 582 1166 582 1168 582 1203 582 1240 582 1246 582 1323 582 1344 582 1352 582 1364 582 1374 582 1429 582 1433 582 1457 582 1483 583 7 583 20 583 22 583 37 583 87 583 156 583 167 583 204 583 242 583 266 583 292 583 350 583 396 583 403 583 446 583 449 583 508 583 530 583 543 583 583 583 604 583 621 583 703 583 777 583 791 583 873 583 900 583 903 583 928 583 935 583 948 583 958 583 987 583 994 583 1005 583 1029 583 1038 583 1071 583 1106 583 1211 583 1257 583 1268 583 1273 583 1287 583 1289 583 1324 583 1326 583 1450 583 1458 584 72 584 83 584 135 584 144 584 187 584 217 584 224 584 232 584 253 584 343 584 370 584 389 584 397 584 424 584 455 584 478 584 497 584 520 584 544 584 567 584 584 584 591 584 638 584 733 584 860 584 875 584 906 584 908 584 972 584 1034 584 1078 584 1136 584 1142 584 1179 584 1198 584 1216 584 1229 584 1250 584 1348 584 1356 584 1361 584 1375 584 1496 585 81 585 99 585 106 585 329 585 337 585 393 585 430 585 487 585 505 585 510 585 529 585 550 585 585 585 665 585 717 585 754 585 820 585 890 585 918 585 965 585 968 585 988 585 1000 585 1019 585 1060 585 1070 585 1226 585 1241 585 1286 585 1408 585 1428 585 1445 585 1465 585 1471 586 33 586 61 586 110 586 155 586 169 586 341 586 342 586 364 586 379 586 447 586 458 586 493 586 504 586 578 586 586 586 749 586 773 586 843 586 904 586 913 586 941 586 943 586 956 586 1109 586 1269 586 1312 586 1345 586 1421 586 1437 587 19 587 152 587 185 587 259 587 288 587 338 587 359 587 398 587 560 587 587 587 598 587 650 587 765 587 778 587 802 587 871 587 892 587 1214 587 1218 587 1242 587 1330 587 1343 587 1382 587 1412 587 1413 587 1419 587 1440 587 1442 588 16 588 34 588 40 588 136 588 150 588 159 588 171 588 207 588 213 588 252 588 274 588 297 588 317 588 390 588 423 588 432 588 439 588 495 588 588 588 615 588 641 588 706 588 738 588 744 588 764 588 813 588 848 588 853 588 868 588 889 588 936 588 964 588 1005 588 1073 588 1110 588 1130 588 1174 588 1252 588 1255 588 1274 588 1284 588 1322 588 1328 588 1381 588 1416 588 1422 588 1434 588 1436 589 49 589 122 589 184 589 319 589 350 589 360 589 376 589 416 589 443 589 503 589 555 589 573 589 574 589 589 589 622 589 639 589 657 589 725 589 750 589 766 589 770 589 777 589 800 589 805 589 886 589 1020 589 1087 589 1107 589 1166 589 1167 589 1185 589 1200 589 1205 589 1257 589 1273 589 1311 589 1364 589 1388 589 1479 589 1483 589 1492 590 17 590 129 590 133 590 145 590 172 590 180 590 192 590 255 590 261 590 304 590 322 590 325 590 328 590 340 590 352 590 394 590 395 590 399 590 522 590 531 590 561 590 590 590 634 590 681 590 695 590 711 590 745 590 776 590 786 590 969 590 980 590 992 590 1092 590 1125 590 1140 590 1155 590 1199 590 1209 590 1359 590 1415 591 57 591 76 591 135 591 144 591 149 591 189 591 217 591 232 591 253 591 305 591 344 591 370 591 397 591 401 591 424 591 455 591 478 591 484 591 520 591 556 591 567 591 584 591 591 591 611 591 684 591 733 591 807 591 822 591 860 591 875 591 893 591 911 591 978 591 990 591 993 591 1014 591 1082 591 1136 591 1142 591 1216 591 1217 591 1235 591 1250 591 1290 591 1348 591 1355 591 1356 591 1358 591 1370 591 1375 591 1393 591 1498 592 56 592 72 592 83 592 101 592 164 592 187 592 217 592 223 592 224 592 232 592 279 592 343 592 371 592 377 592 389 592 391 592 408 592 478 592 497 592 524 592 547 592 592 592 600 592 638 592 680 592 784 592 814 592 844 592 867 592 906 592 908 592 972 592 1034 592 1068 592 1078 592 1099 592 1142 592 1179 592 1180 592 1198 592 1217 592 1230 592 1299 592 1361 592 1373 592 1407 592 1441 592 1474 592 1496 593 20 593 31 593 37 593 75 593 123 593 128 593 167 593 170 593 178 593 198 593 219 593 319 593 350 593 360 593 402 593 416 593 418 593 422 593 457 593 555 593 559 593 593 593 622 593 627 593 644 593 673 593 703 593 725 593 736 593 756 593 766 593 770 593 777 593 800 593 805 593 886 593 900 593 916 593 928 593 933 593 997 593 1015 593 1020 593 1087 593 1100 593 1101 593 1106 593 1112 593 1154 593 1161 593 1166 593 1171 593 1185 593 1205 593 1211 593 1257 593 1268 593 1289 593 1294 593 1311 593 1346 593 1388 593 1402 593 1426 593 1433 593 1479 593 1490 593 1492 594 29 594 35 594 41 594 45 594 51 594 124 594 199 594 235 594 281 594 284 594 304 594 321 594 358 594 363 594 374 594 380 594 501 594 522 594 594 594 661 594 695 594 726 594 729 594 782 594 872 594 885 594 921 594 929 594 1007 594 1086 594 1164 594 1339 594 1417 594 1468 594 1487 595 214 595 236 595 476 595 595 595 742 595 973 595 981 595 984 595 1117 595 1182 595 1264 596 100 596 134 596 140 596 179 596 226 596 245 596 246 596 260 596 265 596 310 596 320 596 329 596 337 596 393 596 406 596 417 596 421 596 445 596 487 596 596 596 616 596 653 596 688 596 717 596 740 596 754 596 762 596 772 596 806 596 918 596 922 596 932 596 945 596 963 596 968 596 974 596 1000 596 1042 596 1045 596 1077 596 1094 596 1139 596 1158 596 1181 596 1226 596 1241 596 1251 596 1315 596 1387 596 1408 596 1428 596 1438 596 1445 596 1453 596 1470 597 0 597 51 597 98 597 151 597 185 597 186 597 238 597 256 597 264 597 278 597 301 597 358 597 359 597 367 597 419 597 436 597 437 597 480 597 496 597 545 597 546 597 597 597 645 597 646 597 650 597 661 597 663 597 665 597 676 597 682 597 699 597 729 597 758 597 771 597 817 597 821 597 828 597 895 597 996 597 1011 597 1060 597 1085 597 1197 597 1208 597 1215 597 1305 597 1398 597 1417 597 1440 597 1487 598 26 598 185 598 264 598 267 598 288 598 359 598 398 598 436 598 465 598 475 598 480 598 482 598 494 598 518 598 546 598 587 598 598 598 650 598 674 598 758 598 760 598 771 598 842 598 895 598 1009 598 1079 598 1147 598 1218 598 1242 598 1266 598 1314 598 1318 598 1321 598 1327 598 1412 598 1440 599 3 599 8 599 19 599 54 599 64 599 73 599 152 599 158 599 182 599 205 599 330 599 473 599 527 599 599 599 628 599 655 599 660 599 734 599 837 599 849 599 892 599 951 599 1132 599 1144 599 1382 599 1419 599 1448 599 1455 599 1463 600 79 600 92 600 125 600 135 600 160 600 189 600 223 600 230 600 272 600 279 600 295 600 371 600 373 600 387 600 391 600 441 600 483 600 484 600 491 600 520 600 556 600 592 600 600 600 611 600 624 600 638 600 640 600 690 600 694 600 784 600 807 600 809 600 814 600 844 600 888 600 910 600 911 600 978 600 999 600 1014 600 1068 600 1069 600 1075 600 1078 600 1082 600 1097 600 1099 600 1180 600 1196 600 1206 600 1217 600 1230 600 1236 600 1277 600 1281 600 1355 600 1361 600 1370 600 1407 600 1441 600 1474 600 1476 600 1484 601 10 601 23 601 103 601 184 601 198 601 210 601 341 601 357 601 376 601 503 601 542 601 559 601 578 601 601 601 627 601 666 601 687 601 704 601 725 601 736 601 750 601 766 601 898 601 915 601 1008 601 1095 601 1297 601 1300 601 1312 601 1338 601 1429 601 1457 601 1492 602 21 602 81 602 99 602 106 602 225 602 245 602 249 602 329 602 337 602 412 602 430 602 445 602 509 602 550 602 602 602 656 602 787 602 820 602 922 602 949 602 952 602 1022 602 1042 602 1070 602 1152 602 1175 602 1190 602 1241 602 1288 602 1317 602 1408 602 1428 603 5 603 13 603 14 603 47 603 52 603 63 603 65 603 85 603 92 603 160 603 165 603 218 603 230 603 234 603 240 603 291 603 371 603 377 603 434 603 441 603 492 603 528 603 544 603 603 603 609 603 612 603 620 603 624 603 630 603 642 603 648 603 690 603 730 603 882 603 883 603 939 603 1028 603 1075 603 1076 603 1108 603 1159 603 1196 603 1236 603 1265 603 1291 603 1369 603 1373 603 1472 604 22 604 91 604 143 604 156 604 266 604 378 604 396 604 446 604 449 604 507 604 508 604 530 604 570 604 583 604 604 604 613 604 621 604 636 604 644 604 669 604 691 604 727 604 739 604 841 604 854 604 873 604 903 604 920 604 948 604 962 604 987 604 994 604 1010 604 1038 604 1090 604 1151 604 1176 604 1324 604 1326 604 1431 604 1444 604 1450 605 156 605 159 605 196 605 266 605 345 605 383 605 400 605 448 605 543 605 605 605 615 605 707 605 739 605 862 605 920 605 947 605 960 605 1037 605 1090 605 1126 605 1127 605 1172 605 1267 605 1325 605 1386 605 1434 605 1436 606 13 606 14 606 79 606 92 606 101 606 279 606 373 606 408 606 434 606 452 606 484 606 526 606 528 606 547 606 567 606 569 606 606 606 608 606 624 606 690 606 730 606 822 606 867 606 882 606 883 606 910 606 1018 606 1076 606 1097 606 1098 606 1159 606 1196 606 1236 606 1291 606 1331 606 1348 606 1369 606 1476 606 1484 607 22 607 31 607 107 607 123 607 266 607 336 607 378 607 449 607 507 607 558 607 570 607 607 607 621 607 763 607 791 607 854 607 862 607 873 607 900 607 935 607 937 607 1071 607 1127 607 1146 607 1156 607 1161 607 1162 607 1176 607 1184 607 1224 607 1289 607 1294 607 1402 607 1404 607 1444 607 1464 608 13 608 36 608 55 608 56 608 85 608 101 608 187 608 218 608 291 608 434 608 452 608 497 608 524 608 547 608 562 608 567 608 606 608 608 608 620 608 667 608 730 608 822 608 867 608 870 608 883 608 908 608 1034 608 1091 608 1098 608 1225 608 1250 608 1290 608 1291 608 1313 608 1348 608 1498 609 5 609 12 609 13 609 52 609 55 609 65 609 85 609 165 609 218 609 230 609 234 609 240 609 291 609 377 609 441 609 492 609 528 609 603 609 609 609 620 609 630 609 642 609 648 609 730 609 742 609 870 609 882 609 883 609 939 609 1028 609 1076 609 1091 609 1108 609 1129 609 1159 609 1265 609 1369 609 1461 609 1472 610 15 610 30 610 53 610 54 610 78 610 82 610 90 610 102 610 121 610 130 610 191 610 211 610 229 610 257 610 262 610 270 610 308 610 348 610 351 610 428 610 451 610 506 610 511 610 533 610 534 610 536 610 537 610 549 610 579 610 610 610 619 610 637 610 658 610 685 610 701 610 702 610 752 610 761 610 812 610 827 610 829 610 863 610 884 610 901 610 923 610 1003 610 1057 610 1065 610 1066 610 1084 610 1135 610 1183 610 1219 610 1258 610 1336 610 1340 610 1360 610 1390 610 1459 610 1481 611 72 611 76 611 135 611 144 611 149 611 189 611 232 611 253 611 272 611 295 611 370 611 373 611 387 611 391 611 397 611 401 611 424 611 455 611 484 611 491 611 520 611 556 611 591 611 600 611 611 611 684 611 743 611 784 611 844 611 910 611 911 611 940 611 978 611 990 611 999 611 1014 611 1069 611 1179 611 1216 611 1230 611 1235 611 1277 611 1290 611 1355 611 1358 611 1370 611 1393 611 1441 611 1484 612 13 612 14 612 47 612 65 612 83 612 92 612 125 612 160 612 218 612 240 612 272 612 291 612 295 612 305 612 373 612 377 612 434 612 441 612 452 612 483 612 484 612 528 612 569 612 603 612 612 612 624 612 630 612 640 612 648 612 690 612 809 612 882 612 883 612 999 612 1014 612 1018 612 1075 612 1076 612 1082 612 1159 612 1196 612 1206 612 1229 612 1236 612 1265 612 1277 612 1331 612 1356 612 1369 612 1370 612 1375 612 1461 612 1472 612 1484 613 7 613 22 613 91 613 143 613 156 613 219 613 242 613 266 613 378 613 396 613 446 613 449 613 507 613 508 613 558 613 570 613 604 613 613 613 621 613 636 613 639 613 644 613 669 613 791 613 854 613 903 613 935 613 937 613 948 613 962 613 987 613 1038 613 1071 613 1151 613 1156 613 1161 613 1171 613 1176 613 1273 613 1326 613 1431 613 1444 613 1450 613 1464 614 3 614 8 614 19 614 64 614 97 614 183 614 197 614 296 614 407 614 473 614 499 614 614 614 628 614 654 614 660 614 662 614 670 614 709 614 765 614 796 614 816 614 849 614 892 614 951 614 1001 614 1036 614 1050 614 1132 614 1227 614 1242 614 1354 614 1419 615 136 615 159 615 196 615 252 615 345 615 383 615 400 615 448 615 588 615 605 615 615 615 641 615 707 615 739 615 764 615 783 615 813 615 847 615 947 615 1037 615 1090 615 1126 615 1172 615 1174 615 1252 615 1284 615 1325 615 1386 615 1434 615 1436 615 1493 616 1 616 100 616 226 616 246 616 260 616 265 616 310 616 320 616 417 616 421 616 445 616 487 616 596 616 616 616 653 616 656 616 672 616 688 616 712 616 717 616 740 616 754 616 762 616 806 616 855 616 856 616 880 616 922 616 945 616 1042 616 1045 616 1074 616 1077 616 1139 616 1158 616 1195 616 1226 616 1315 616 1317 616 1387 616 1397 616 1428 616 1438 616 1453 616 1470 616 1473 617 91 617 143 617 167 617 178 617 219 617 319 617 326 617 378 617 416 617 418 617 422 617 617 617 636 617 644 617 732 617 777 617 854 617 900 617 935 617 958 617 962 617 997 617 1010 617 1015 617 1146 617 1154 617 1176 617 1205 617 1289 617 1294 617 1311 617 1426 617 1431 617 1479 618 9 618 15 618 54 618 73 618 90 618 121 618 158 618 182 618 205 618 221 618 229 618 257 618 262 618 285 618 351 618 381 618 462 618 485 618 490 618 534 618 536 618 618 618 619 618 698 618 701 618 735 618 808 618 815 618 823 618 827 618 837 618 864 618 905 618 1044 618 1144 618 1153 618 1183 618 1221 618 1258 618 1343 618 1360 618 1389 618 1448 618 1452 618 1455 619 15 619 54 619 58 619 121 619 158 619 191 619 221 619 229 619 257 619 285 619 351 619 428 619 462 619 490 619 511 619 533 619 534 619 536 619 610 619 618 619 619 619 701 619 827 619 864 619 1044 619 1065 619 1153 619 1183 619 1258 619 1340 619 1360 619 1452 620 13 620 36 620 55 620 56 620 85 620 92 620 101 620 187 620 218 620 291 620 377 620 441 620 492 620 497 620 524 620 547 620 562 620 603 620 608 620 609 620 620 620 667 620 730 620 867 620 870 620 883 620 908 620 1076 620 1091 620 1098 620 1129 620 1225 620 1291 620 1299 620 1369 620 1373 620 1496 621 7 621 22 621 107 621 143 621 156 621 167 621 219 621 266 621 378 621 396 621 403 621 446 621 449 621 507 621 530 621 543 621 558 621 570 621 583 621 604 621 607 621 613 621 621 621 636 621 644 621 669 621 739 621 791 621 854 621 862 621 873 621 900 621 903 621 920 621 935 621 937 621 948 621 958 621 962 621 987 621 994 621 1005 621 1038 621 1071 621 1090 621 1154 621 1162 621 1176 621 1224 621 1289 621 1294 621 1324 621 1326 621 1386 621 1431 621 1444 621 1450 621 1464 622 31 622 37 622 75 622 122 622 123 622 167 622 170 622 178 622 198 622 219 622 319 622 326 622 350 622 360 622 376 622 402 622 416 622 418 622 422 622 457 622 551 622 555 622 559 622 589 622 593 622 622 622 673 622 703 622 725 622 756 622 766 622 770 622 777 622 800 622 886 622 916 622 928 622 933 622 935 622 958 622 997 622 1015 622 1020 622 1071 622 1087 622 1106 622 1112 622 1154 622 1166 622 1185 622 1200 622 1205 622 1211 622 1257 622 1268 622 1289 622 1294 622 1311 622 1388 622 1426 622 1433 622 1457 622 1479 622 1490 622 1492 623 82 623 191 623 212 623 233 623 244 623 286 623 349 623 464 623 563 623 575 623 580 623 623 623 625 623 767 623 795 623 934 623 959 623 967 623 1007 623 1035 623 1064 623 1113 623 1199 623 1316 623 1341 623 1378 623 1390 623 1467 624 14 624 47 624 79 624 92 624 125 624 160 624 165 624 230 624 234 624 240 624 272 624 279 624 295 624 373 624 387 624 404 624 434 624 441 624 483 624 484 624 528 624 567 624 569 624 600 624 603 624 606 624 612 624 624 624 630 624 640 624 648 624 690 624 694 624 743 624 807 624 809 624 882 624 910 624 999 624 1018 624 1075 624 1076 624 1082 624 1099 624 1159 624 1196 624 1236 624 1277 624 1355 624 1375 624 1472 624 1476 624 1484 625 28 625 66 625 86 625 193 625 200 625 206 625 211 625 233 625 244 625 263 625 283 625 348 625 349 625 355 625 394 625 399 625 405 625 425 625 444 625 464 625 575 625 580 625 623 625 625 625 652 625 708 625 720 625 767 625 829 625 830 625 896 625 921 625 931 625 969 625 1007 625 1059 625 1064 625 1140 625 1165 625 1238 625 1244 625 1309 625 1316 625 1341 625 1378 625 1390 625 1403 625 1467 625 1468 625 1494 626 26 626 53 626 58 626 78 626 82 626 86 626 102 626 191 626 193 626 200 626 211 626 250 626 257 626 277 626 308 626 332 626 348 626 349 626 405 626 428 626 431 626 440 626 444 626 451 626 533 626 534 626 563 626 579 626 626 626 658 626 846 626 863 626 901 626 959 626 1024 626 1035 626 1084 626 1102 626 1131 626 1135 626 1137 626 1249 626 1309 626 1340 626 1341 626 1459 626 1475 626 1481 626 1494 627 23 627 37 627 49 627 68 627 75 627 170 627 184 627 198 627 210 627 300 627 314 627 350 627 357 627 376 627 433 627 457 627 503 627 551 627 559 627 593 627 601 627 627 627 657 627 666 627 703 627 704 627 725 627 750 627 756 627 766 627 770 627 886 627 898 627 916 627 930 627 933 627 1008 627 1020 627 1029 627 1088 627 1100 627 1166 627 1185 627 1300 627 1338 627 1429 627 1457 627 1460 627 1483 627 1492 627 1495 628 3 628 8 628 19 628 64 628 97 628 183 628 296 628 330 628 407 628 427 628 473 628 499 628 599 628 614 628 628 628 660 628 662 628 709 628 765 628 802 628 816 628 849 628 892 628 951 628 1132 628 1227 628 1242 628 1419 629 24 629 222 629 244 629 283 629 327 629 348 629 355 629 429 629 475 629 482 629 522 629 629 629 708 629 755 629 824 629 866 629 884 629 1007 629 1204 629 1261 629 1314 629 1339 629 1400 629 1403 629 1468 629 1485 629 1494 630 5 630 13 630 14 630 47 630 52 630 63 630 65 630 92 630 160 630 165 630 202 630 218 630 230 630 234 630 240 630 272 630 291 630 365 630 373 630 377 630 387 630 434 630 441 630 483 630 528 630 569 630 603 630 609 630 612 630 624 630 630 630 642 630 648 630 690 630 742 630 809 630 882 630 883 630 939 630 1018 630 1028 630 1075 630 1076 630 1108 630 1159 630 1196 630 1206 630 1236 630 1265 630 1331 630 1369 630 1461 630 1472 630 1476 630 1484 631 53 631 78 631 180 631 212 631 283 631 286 631 308 631 322 631 328 631 348 631 349 631 354 631 394 631 399 631 440 631 460 631 511 631 549 631 580 631 631 631 652 631 720 631 752 631 761 631 795 631 812 631 829 631 923 631 980 631 1057 631 1059 631 1131 631 1137 631 1140 631 1238 631 1316 631 1336 631 1351 631 1378 631 1390 631 1418 631 1459 631 1481 632 4 632 16 632 71 632 155 632 177 632 248 632 297 632 331 632 432 632 469 632 519 632 632 632 706 632 716 632 738 632 977 632 1053 632 1073 632 1274 632 1328 632 1357 632 1367 632 1416 632 1423 632 1451 632 1480 633 39 633 60 633 77 633 104 633 105 633 109 633 112 633 154 633 176 633 208 633 254 633 280 633 287 633 302 633 369 633 385 633 410 633 456 633 500 633 541 633 633 633 651 633 724 633 747 633 779 633 826 633 861 633 878 633 891 633 902 633 927 633 957 633 976 633 989 633 1013 633 1025 633 1030 633 1128 633 1148 633 1207 633 1210 633 1243 633 1279 633 1295 633 1301 633 1310 633 1380 633 1383 633 1439 634 17 634 27 634 96 634 124 634 129 634 162 634 172 634 180 634 255 634 263 634 283 634 304 634 322 634 328 634 354 634 363 634 394 634 395 634 399 634 413 634 531 634 575 634 576 634 590 634 634 634 652 634 681 634 695 634 711 634 786 634 830 634 881 634 887 634 969 634 991 634 992 634 1059 634 1092 634 1123 634 1125 634 1140 634 1173 634 1209 634 1213 634 1332 634 1351 634 1414 634 1446 635 6 635 42 635 45 635 48 635 51 635 70 635 108 635 256 635 273 635 303 635 339 635 363 635 413 635 437 635 438 635 512 635 521 635 635 635 661 635 718 635 722 635 729 635 731 635 780 635 782 635 810 635 852 635 880 635 961 635 1033 635 1049 635 1052 635 1081 635 1086 635 1163 635 1201 635 1208 635 1239 635 1263 635 1362 635 1363 635 1399 635 1417 635 1466 635 1487 635 1488 636 91 636 143 636 167 636 178 636 219 636 326 636 378 636 422 636 446 636 508 636 604 636 613 636 617 636 621 636 636 636 644 636 669 636 732 636 854 636 903 636 935 636 958 636 962 636 987 636 997 636 1010 636 1038 636 1146 636 1151 636 1154 636 1167 636 1326 636 1431 637 30 637 38 637 53 637 78 637 130 637 212 637 216 637 262 637 270 637 428 637 431 637 460 637 464 637 506 637 511 637 534 637 549 637 610 637 637 637 808 637 812 637 874 637 923 637 1057 637 1065 637 1084 637 1187 637 1219 637 1234 637 1238 637 1249 637 1336 637 1360 637 1415 637 1418 638 56 638 72 638 79 638 164 638 223 638 279 638 343 638 373 638 389 638 391 638 408 638 478 638 483 638 484 638 497 638 520 638 524 638 547 638 584 638 592 638 600 638 638 638 680 638 784 638 814 638 822 638 839 638 844 638 867 638 906 638 908 638 911 638 940 638 972 638 1034 638 1068 638 1078 638 1097 638 1098 638 1099 638 1179 638 1180 638 1198 638 1206 638 1229 638 1230 638 1281 638 1299 638 1361 638 1373 638 1407 638 1441 638 1474 638 1496 639 37 639 49 639 91 639 128 639 219 639 242 639 350 639 360 639 443 639 446 639 508 639 555 639 573 639 574 639 589 639 613 639 639 639 644 639 770 639 777 639 800 639 805 639 903 639 933 639 955 639 1087 639 1161 639 1167 639 1185 639 1200 639 1205 639 1273 639 1379 639 1388 639 1431 639 1450 639 1479 639 1483 640 14 640 79 640 92 640 125 640 223 640 224 640 272 640 279 640 295 640 371 640 373 640 377 640 387 640 441 640 452 640 483 640 484 640 544 640 556 640 567 640 600 640 612 640 624 640 640 640 648 640 684 640 690 640 694 640 807 640 875 640 882 640 910 640 972 640 1068 640 1075 640 1078 640 1082 640 1099 640 1180 640 1196 640 1217 640 1236 640 1277 640 1355 640 1356 640 1361 640 1373 640 1375 640 1407 640 1441 640 1474 640 1476 640 1484 641 16 641 136 641 159 641 196 641 207 641 252 641 274 641 297 641 317 641 390 641 423 641 432 641 439 641 448 641 469 641 548 641 588 641 615 641 641 641 706 641 707 641 738 641 763 641 764 641 889 641 936 641 960 641 964 641 977 641 1005 641 1037 641 1126 641 1130 641 1172 641 1174 641 1252 641 1255 641 1274 641 1284 641 1287 641 1322 641 1324 641 1328 641 1386 641 1416 641 1422 641 1434 641 1436 641 1493 642 5 642 12 642 52 642 63 642 65 642 85 642 165 642 202 642 230 642 234 642 240 642 365 642 441 642 492 642 528 642 603 642 609 642 630 642 642 642 742 642 759 642 939 642 1026 642 1028 642 1108 642 1129 642 1159 642 1265 642 1461 642 1472 643 10 643 23 643 103 643 122 643 341 643 517 643 542 643 578 643 582 643 643 643 666 643 687 643 693 643 750 643 811 643 898 643 913 643 915 643 943 643 1008 643 1095 643 1109 643 1168 643 1240 643 1246 643 1275 643 1297 643 1323 643 1344 643 1352 643 1429 643 1495 644 91 644 143 644 167 644 178 644 219 644 242 644 319 644 326 644 350 644 360 644 378 644 416 644 418 644 422 644 446 644 508 644 555 644 593 644 604 644 613 644 617 644 621 644 636 644 639 644 644 644 732 644 777 644 800 644 854 644 886 644 900 644 903 644 928 644 935 644 958 644 962 644 997 644 1010 644 1015 644 1087 644 1146 644 1151 644 1154 644 1161 644 1167 644 1171 644 1200 644 1205 644 1211 644 1257 644 1268 644 1289 644 1294 644 1311 644 1326 644 1346 644 1388 644 1426 644 1431 644 1479 645 98 645 151 645 185 645 186 645 256 645 264 645 288 645 301 645 367 645 398 645 419 645 437 645 494 645 597 645 645 645 650 645 663 645 676 645 682 645 683 645 699 645 760 645 803 645 842 645 895 645 1011 645 1060 645 1083 645 1197 645 1263 645 1305 645 1371 645 1417 645 1440 645 1487 646 116 646 138 646 174 646 206 646 267 646 325 646 355 646 356 646 359 646 429 646 431 646 436 646 444 646 539 646 552 646 568 646 597 646 646 646 650 646 652 646 676 646 708 646 714 646 755 646 758 646 771 646 776 646 885 646 897 646 944 646 965 646 985 646 992 646 995 646 1007 646 1046 646 1204 646 1244 646 1316 646 1321 646 1339 647 120 647 132 647 201 647 214 647 239 647 275 647 293 647 311 647 353 647 361 647 372 647 415 647 488 647 647 647 677 647 719 647 793 647 858 647 971 647 1006 647 1023 647 1051 647 1058 647 1157 647 1192 647 1307 647 1377 647 1395 647 1424 647 1435 648 13 648 14 648 47 648 55 648 63 648 83 648 160 648 218 648 223 648 234 648 240 648 291 648 371 648 377 648 434 648 441 648 483 648 492 648 528 648 544 648 603 648 609 648 612 648 624 648 630 648 640 648 648 648 690 648 694 648 814 648 882 648 883 648 939 648 1068 648 1075 648 1076 648 1078 648 1099 648 1108 648 1159 648 1180 648 1196 648 1373 648 1407 648 1441 649 42 649 96 649 124 649 127 649 131 649 162 649 228 649 243 649 263 649 392 649 479 649 486 649 498 649 501 649 502 649 576 649 649 649 678 649 679 649 726 649 746 649 757 649 775 649 786 649 789 649 797 649 834 649 879 649 942 649 946 649 961 649 1016 649 1072 649 1160 649 1173 649 1213 649 1332 649 1353 649 1372 650 185 650 264 650 288 650 359 650 398 650 436 650 480 650 482 650 494 650 546 650 587 650 597 650 598 650 645 650 646 650 650 650 674 650 676 650 683 650 699 650 708 650 758 650 842 650 895 650 1079 650 1085 650 1197 650 1218 650 1266 650 1305 650 1314 650 1371 650 1412 650 1413 650 1440 651 43 651 104 651 105 651 109 651 118 651 176 651 208 651 254 651 287 651 309 651 410 651 456 651 500 651 532 651 557 651 565 651 633 651 651 651 747 651 779 651 826 651 878 651 899 651 902 651 927 651 957 651 989 651 1025 651 1030 651 1150 651 1182 651 1210 651 1220 651 1243 651 1264 651 1270 651 1279 651 1295 651 1310 651 1350 651 1366 651 1380 651 1383 651 1489 652 28 652 116 652 206 652 268 652 277 652 283 652 286 652 322 652 325 652 328 652 348 652 349 652 354 652 355 652 394 652 395 652 399 652 431 652 440 652 444 652 464 652 552 652 561 652 580 652 625 652 631 652 634 652 646 652 652 652 708 652 720 652 755 652 776 652 795 652 829 652 887 652 942 652 969 652 980 652 995 652 1007 652 1046 652 1059 652 1064 652 1125 652 1140 652 1199 652 1209 652 1238 652 1244 652 1316 652 1351 652 1403 652 1414 652 1446 652 1481 652 1494 652 1499 653 80 653 94 653 179 653 225 653 226 653 246 653 249 653 310 653 320 653 329 653 445 653 596 653 616 653 653 653 656 653 664 653 672 653 688 653 712 653 740 653 754 653 762 653 806 653 855 653 856 653 880 653 922 653 963 653 966 653 974 653 1022 653 1032 653 1042 653 1045 653 1063 653 1077 653 1139 653 1170 653 1175 653 1181 653 1195 653 1288 653 1317 653 1387 653 1428 653 1438 654 2 654 93 654 95 654 97 654 126 654 153 654 194 654 197 654 220 654 247 654 296 654 362 654 463 654 471 654 499 654 614 654 654 654 662 654 670 654 765 654 796 654 816 654 871 654 970 654 1001 654 1036 654 1040 654 1050 654 1105 654 1186 654 1191 654 1218 654 1242 654 1248 654 1329 654 1354 654 1384 654 1394 654 1478 655 19 655 73 655 130 655 152 655 205 655 259 655 270 655 285 655 330 655 338 655 549 655 560 655 599 655 655 655 698 655 701 655 734 655 752 655 761 655 778 655 802 655 815 655 866 655 871 655 892 655 905 655 983 655 1044 655 1084 655 1118 655 1145 655 1212 655 1214 655 1330 655 1343 655 1382 655 1400 655 1413 655 1442 655 1455 656 1 656 225 656 226 656 249 656 329 656 509 656 550 656 602 656 616 656 653 656 656 656 672 656 712 656 820 656 825 656 845 656 855 656 922 656 966 656 1063 656 1074 656 1170 656 1175 656 1288 656 1317 656 1335 656 1342 656 1428 657 10 657 37 657 49 657 68 657 75 657 128 657 141 657 184 657 198 657 203 657 204 657 290 657 294 657 300 657 350 657 357 657 360 657 368 657 376 657 402 657 433 657 443 657 503 657 551 657 555 657 559 657 571 657 573 657 582 657 589 657 627 657 657 657 671 657 673 657 697 657 703 657 725 657 756 657 770 657 805 657 836 657 886 657 898 657 916 657 930 657 1020 657 1029 657 1088 657 1100 657 1101 657 1107 657 1166 657 1185 657 1203 657 1257 657 1300 657 1311 657 1364 657 1374 657 1433 657 1457 657 1460 657 1483 657 1490 657 1492 658 26 658 53 658 78 658 82 658 86 658 90 658 102 658 191 658 193 658 200 658 211 658 233 658 277 658 308 658 332 658 405 658 428 658 451 658 465 658 511 658 533 658 536 658 537 658 549 658 563 658 579 658 610 658 626 658 658 658 685 658 701 658 702 658 752 658 761 658 812 658 846 658 863 658 884 658 901 658 934 658 959 658 1003 658 1024 658 1035 658 1054 658 1066 658 1084 658 1102 658 1113 658 1118 658 1124 658 1135 658 1137 658 1212 658 1221 658 1309 658 1327 658 1340 658 1341 658 1459 658 1467 658 1475 658 1481 658 1486 658 1494 659 62 659 74 659 88 659 173 659 209 659 306 659 324 659 334 659 420 659 461 659 525 659 553 659 572 659 581 659 659 659 668 659 696 659 723 659 728 659 737 659 748 659 788 659 798 659 804 659 818 659 917 659 924 659 1006 659 1062 659 1080 659 1093 659 1096 659 1104 659 1115 659 1143 659 1149 659 1192 659 1254 659 1259 659 1272 659 1285 659 1293 660 3 660 8 660 64 660 183 660 407 660 471 660 473 660 499 660 527 660 599 660 614 660 628 660 660 660 662 660 709 660 816 660 849 660 951 660 1040 660 1132 660 1191 660 1227 660 1272 661 51 661 133 661 151 661 186 661 188 661 199 661 278 661 281 661 367 661 380 661 419 661 430 661 437 661 498 661 545 661 594 661 597 661 635 661 661 661 665 661 676 661 682 661 729 661 872 661 949 661 1060 661 1086 661 1152 661 1190 661 1208 661 1223 661 1417 661 1440 661 1487 662 2 662 95 662 97 662 126 662 153 662 183 662 247 662 296 662 362 662 407 662 471 662 499 662 614 662 628 662 654 662 660 662 662 662 709 662 816 662 970 662 1001 662 1002 662 1040 662 1050 662 1105 662 1132 662 1191 662 1227 662 1272 662 1329 662 1354 662 1384 662 1394 663 0 663 98 663 114 663 181 663 185 663 220 663 298 663 301 663 358 663 398 663 412 663 419 663 480 663 546 663 597 663 645 663 663 663 665 663 670 663 692 663 699 663 721 663 758 663 760 663 765 663 768 663 821 663 825 663 842 663 996 663 1011 663 1012 663 1050 663 1055 663 1083 663 1085 663 1186 663 1197 663 1218 663 1222 663 1318 663 1384 663 1412 663 1440 663 1465 664 11 664 48 664 80 664 94 664 114 664 163 664 179 664 225 664 226 664 245 664 246 664 276 664 278 664 310 664 339 664 459 664 467 664 496 664 653 664 664 664 712 664 713 664 768 664 787 664 821 664 828 664 880 664 912 664 952 664 966 664 1012 664 1032 664 1033 664 1045 664 1063 664 1081 664 1158 664 1163 664 1170 664 1175 664 1181 664 1201 664 1208 664 1239 664 1251 664 1288 664 1308 664 1335 664 1362 664 1399 665 80 665 81 665 106 665 151 665 185 665 199 665 245 665 278 665 318 665 339 665 347 665 412 665 419 665 430 665 437 665 480 665 496 665 505 665 510 665 529 665 545 665 546 665 585 665 597 665 661 665 663 665 665 665 674 665 676 665 682 665 699 665 760 665 768 665 787 665 821 665 842 665 912 665 949 665 950 665 952 665 965 665 986 665 1019 665 1022 665 1060 665 1063 665 1070 665 1152 665 1175 665 1190 665 1215 665 1251 665 1304 665 1318 665 1408 665 1417 665 1440 665 1465 665 1471 665 1487 666 10 666 23 666 103 666 184 666 198 666 210 666 314 666 357 666 376 666 457 666 503 666 542 666 578 666 601 666 627 666 643 666 666 666 687 666 693 666 704 666 725 666 750 666 766 666 811 666 898 666 915 666 1008 666 1095 666 1168 666 1240 666 1246 666 1297 666 1300 666 1312 666 1338 666 1352 666 1429 666 1457 666 1492 666 1495 667 36 667 55 667 56 667 101 667 164 667 187 667 218 667 291 667 497 667 524 667 547 667 562 667 608 667 620 667 667 667 730 667 867 667 870 667 906 667 908 667 1091 667 1098 667 1225 667 1299 667 1373 668 74 668 84 668 88 668 173 668 201 668 306 668 420 668 461 668 471 668 525 668 553 668 659 668 668 668 696 668 723 668 728 668 748 668 788 668 798 668 804 668 818 668 858 668 924 668 1040 668 1062 668 1080 668 1096 668 1115 668 1191 668 1192 668 1248 668 1254 668 1272 668 1285 668 1293 668 1302 668 1303 669 22 669 91 669 143 669 156 669 266 669 378 669 396 669 446 669 449 669 508 669 530 669 604 669 613 669 621 669 636 669 669 669 691 669 727 669 739 669 841 669 854 669 873 669 903 669 919 669 920 669 948 669 962 669 994 669 1010 669 1038 669 1090 669 1151 669 1267 669 1324 669 1326 669 1431 669 1444 669 1450 670 2 670 93 670 95 670 111 670 114 670 194 670 220 670 247 670 362 670 384 670 450 670 463 670 481 670 516 670 564 670 614 670 654 670 663 670 670 670 675 670 721 670 796 670 825 670 970 670 975 670 1001 670 1012 670 1036 670 1050 670 1083 670 1105 670 1116 670 1122 670 1186 670 1194 670 1248 670 1256 670 1280 670 1302 670 1329 670 1354 670 1478 671 7 671 20 671 37 671 49 671 50 671 68 671 75 671 87 671 122 671 128 671 148 671 167 671 203 671 204 671 219 671 242 671 292 671 294 671 300 671 333 671 336 671 350 671 360 671 368 671 443 671 538 671 657 671 671 671 673 671 703 671 756 671 805 671 819 671 836 671 886 671 916 671 928 671 1088 671 1101 671 1106 671 1161 671 1166 671 1169 671 1171 671 1203 671 1211 671 1257 671 1273 671 1311 671 1326 671 1364 671 1404 671 1460 671 1464 671 1490 672 1 672 100 672 246 672 249 672 260 672 265 672 320 672 417 672 421 672 616 672 653 672 656 672 672 672 688 672 712 672 740 672 762 672 806 672 850 672 855 672 856 672 945 672 974 672 1074 672 1139 672 1195 672 1306 672 1317 672 1337 672 1342 672 1387 672 1397 672 1428 672 1438 672 1453 672 1473 673 20 673 31 673 37 673 49 673 68 673 75 673 123 673 128 673 198 673 203 673 242 673 290 673 333 673 357 673 360 673 368 673 402 673 433 673 443 673 457 673 503 673 538 673 551 673 555 673 582 673 593 673 622 673 657 673 671 673 673 673 703 673 756 673 770 673 800 673 805 673 836 673 886 673 916 673 933 673 955 673 1020 673 1100 673 1101 673 1106 673 1107 673 1166 673 1203 673 1211 673 1257 673 1311 673 1364 673 1433 673 1460 673 1490 674 151 674 185 674 186 674 238 674 264 674 267 674 281 674 301 674 318 674 358 674 398 674 430 674 475 674 480 674 494 674 510 674 518 674 529 674 546 674 598 674 650 674 665 674 674 674 758 674 760 674 803 674 824 674 842 674 896 674 986 674 996 674 1009 674 1011 674 1019 674 1060 674 1079 674 1085 674 1147 674 1218 674 1266 674 1271 674 1305 674 1318 674 1412 674 1449 674 1465 674 1471 675 2 675 84 675 113 675 173 675 194 675 241 675 247 675 275 675 315 675 334 675 362 675 372 675 384 675 420 675 471 675 472 675 488 675 554 675 566 675 670 675 675 675 788 675 796 675 825 675 966 675 1001 675 1036 675 1105 675 1122 675 1143 675 1157 675 1186 675 1192 675 1248 675 1302 675 1303 675 1308 675 1329 675 1469 676 0 676 29 676 45 676 51 676 138 676 151 676 185 676 186 676 199 676 318 676 359 676 380 676 398 676 419 676 436 676 437 676 470 676 494 676 505 676 545 676 597 676 645 676 646 676 650 676 661 676 665 676 676 676 683 676 699 676 708 676 729 676 895 676 931 676 950 676 965 676 979 676 1060 676 1079 676 1086 676 1197 676 1304 676 1305 676 1398 676 1417 676 1440 676 1471 676 1487 677 84 677 120 677 201 677 239 677 271 677 275 677 293 677 311 677 324 677 361 677 488 677 647 677 677 677 719 677 793 677 858 677 971 677 1006 677 1023 677 1051 677 1058 677 1157 677 1307 677 1377 677 1395 677 1424 677 1435 678 27 678 66 678 89 678 116 678 124 678 127 678 131 678 235 678 243 678 250 678 268 678 356 678 392 678 425 678 470 678 479 678 486 678 501 678 502 678 535 678 539 678 552 678 568 678 576 678 649 678 678 678 753 678 757 678 775 678 810 678 830 678 831 678 865 678 879 678 887 678 896 678 909 678 921 678 925 678 942 678 985 678 986 678 995 678 1007 678 1009 678 1016 678 1064 678 1072 678 1160 678 1165 678 1341 678 1349 678 1414 678 1425 678 1446 678 1449 679 94 679 127 679 131 679 134 679 228 679 243 679 289 679 392 679 393 679 459 679 467 679 486 679 501 679 502 679 649 679 679 679 726 679 741 679 746 679 772 679 775 679 789 679 797 679 879 679 909 679 918 679 925 679 946 679 968 679 1016 679 1072 679 1077 679 1111 679 1213 679 1315 679 1372 679 1392 679 1410 679 1470 680 14 680 47 680 56 680 83 680 101 680 164 680 217 680 223 680 279 680 295 680 389 680 391 680 408 680 478 680 520 680 524 680 526 680 547 680 592 680 638 680 680 680 784 680 814 680 822 680 839 680 844 680 867 680 906 680 908 680 911 680 940 680 978 680 1014 680 1018 680 1034 680 1097 680 1098 680 1142 680 1180 680 1198 680 1206 680 1216 680 1229 680 1230 680 1281 680 1290 680 1299 680 1370 680 1407 680 1441 680 1474 680 1498 681 17 681 133 681 244 681 283 681 304 681 349 681 382 681 394 681 395 681 399 681 505 681 540 681 575 681 580 681 590 681 634 681 681 681 695 681 776 681 786 681 795 681 865 681 969 681 980 681 992 681 1039 681 1059 681 1140 681 1160 681 1199 681 1271 681 1351 681 1378 681 1425 681 1446 681 1467 681 1499 682 98 682 99 682 106 682 151 682 179 682 186 682 188 682 199 682 225 682 245 682 278 682 339 682 347 682 367 682 419 682 430 682 437 682 509 682 529 682 540 682 597 682 645 682 661 682 665 682 682 682 686 682 760 682 768 682 821 682 845 682 949 682 950 682 1019 682 1022 682 1060 682 1063 682 1152 682 1190 682 1197 682 1263 682 1417 682 1440 682 1487 683 29 683 98 683 106 683 151 683 185 683 245 683 288 683 318 683 359 683 367 683 380 683 398 683 470 683 494 683 645 683 650 683 676 683 683 683 686 683 699 683 760 683 821 683 842 683 895 683 949 683 950 683 965 683 986 683 1060 683 1079 683 1197 683 1304 683 1417 683 1440 683 1465 683 1487 684 76 684 79 684 135 684 144 684 189 684 217 684 232 684 253 684 305 684 344 684 373 684 401 684 455 684 478 684 484 684 526 684 556 684 567 684 591 684 611 684 640 684 684 684 690 684 743 684 807 684 814 684 822 684 839 684 860 684 875 684 911 684 978 684 990 684 1014 684 1068 684 1082 684 1136 684 1142 684 1216 684 1217 684 1235 684 1236 684 1250 684 1277 684 1290 684 1348 684 1355 684 1356 684 1358 684 1370 684 1375 684 1407 684 1441 684 1498 685 9 685 15 685 53 685 54 685 78 685 102 685 121 685 130 685 158 685 191 685 205 685 229 685 270 685 285 685 308 685 312 685 451 685 462 685 485 685 490 685 511 685 536 685 610 685 658 685 685 685 698 685 752 685 761 685 812 685 823 685 827 685 837 685 863 685 864 685 884 685 959 685 1044 685 1066 685 1084 685 1102 685 1137 685 1144 685 1153 685 1183 685 1212 685 1221 685 1258 685 1340 685 1343 685 1382 685 1442 685 1452 685 1459 685 1475 686 6 686 41 686 45 686 89 686 99 686 106 686 151 686 188 686 199 686 245 686 278 686 318 686 382 686 470 686 505 686 510 686 540 686 682 686 683 686 686 686 722 686 865 686 890 686 896 686 921 686 949 686 950 686 965 686 968 686 986 686 1000 686 1048 686 1060 686 1063 686 1152 686 1160 686 1190 686 1251 686 1304 686 1349 686 1408 686 1417 686 1425 686 1445 686 1471 686 1487 687 10 687 61 687 103 687 110 687 341 687 342 687 364 687 379 687 447 687 493 687 504 687 542 687 578 687 601 687 643 687 666 687 687 687 704 687 749 687 811 687 843 687 913 687 915 687 943 687 956 687 1008 687 1095 687 1109 687 1168 687 1269 687 1297 687 1312 687 1374 687 1420 687 1421 687 1437 688 48 688 140 688 163 688 226 688 246 688 310 688 320 688 393 688 406 688 413 688 512 688 521 688 596 688 616 688 653 688 672 688 688 688 712 688 718 688 740 688 746 688 762 688 772 688 806 688 852 688 855 688 856 688 880 688 907 688 945 688 963 688 974 688 998 688 1004 688 1049 688 1094 688 1139 688 1158 688 1163 688 1177 688 1181 688 1306 688 1362 688 1387 688 1438 688 1453 688 1473 689 45 689 114 689 124 689 235 689 251 689 268 689 301 689 318 689 358 689 392 689 429 689 467 689 482 689 494 689 689 689 699 689 722 689 731 689 768 689 821 689 824 689 996 689 1007 689 1009 689 1055 689 1160 689 1228 689 1304 689 1349 689 1371 689 1403 689 1449 689 1468 690 13 690 14 690 47 690 79 690 92 690 125 690 160 690 165 690 230 690 240 690 272 690 279 690 295 690 305 690 371 690 373 690 387 690 441 690 452 690 483 690 484 690 528 690 567 690 600 690 603 690 606 690 612 690 624 690 630 690 640 690 648 690 684 690 690 690 694 690 807 690 809 690 882 690 883 690 910 690 939 690 999 690 1018 690 1075 690 1076 690 1082 690 1099 690 1180 690 1196 690 1206 690 1236 690 1277 690 1355 690 1356 690 1370 690 1375 690 1441 690 1484 691 156 691 190 691 396 691 414 691 508 691 604 691 669 691 691 691 727 691 739 691 841 691 854 691 903 691 919 691 920 691 994 691 1037 691 1038 691 1151 691 1267 691 1450 691 1454 691 1491 692 25 692 70 692 98 692 163 692 181 692 220 692 225 692 256 692 273 692 412 692 450 692 523 692 663 692 692 692 768 692 845 692 894 692 932 692 1012 692 1032 692 1055 692 1083 692 1175 692 1239 692 1385 692 1447 692 1488 693 23 693 122 693 195 693 517 693 542 693 573 693 582 693 643 693 666 693 693 693 697 693 811 693 898 693 915 693 943 693 1008 693 1095 693 1101 693 1107 693 1168 693 1240 693 1246 693 1275 693 1323 693 1344 693 1352 693 1374 693 1495 694 52 694 63 694 92 694 125 694 160 694 230 694 272 694 295 694 371 694 373 694 387 694 404 694 441 694 483 694 600 694 624 694 640 694 648 694 690 694 694 694 743 694 807 694 809 694 814 694 882 694 888 694 910 694 911 694 999 694 1014 694 1068 694 1069 694 1075 694 1082 694 1097 694 1099 694 1108 694 1180 694 1196 694 1277 694 1281 694 1355 694 1441 694 1456 694 1472 694 1476 694 1484 695 17 695 35 695 51 695 124 695 129 695 131 695 172 695 180 695 235 695 283 695 304 695 321 695 322 695 363 695 374 695 382 695 394 695 395 695 399 695 522 695 540 695 575 695 590 695 594 695 634 695 681 695 695 695 708 695 767 695 786 695 795 695 885 695 929 695 961 695 969 695 980 695 992 695 1007 695 1039 695 1052 695 1125 695 1140 695 1164 695 1199 695 1201 695 1209 695 1261 695 1316 695 1339 695 1359 695 1362 695 1468 696 166 696 306 696 334 696 386 696 420 696 461 696 471 696 472 696 474 696 525 696 553 696 566 696 659 696 668 696 696 696 723 696 748 696 804 696 924 696 1040 696 1096 696 1104 696 1143 696 1191 696 1254 696 1259 696 1272 696 1285 696 1302 696 1303 696 1319 696 1391 696 1405 696 1427 697 49 697 50 697 68 697 75 697 141 697 195 697 198 697 294 697 314 697 368 697 433 697 517 697 538 697 551 697 571 697 573 697 582 697 657 697 693 697 697 697 811 697 836 697 930 697 1008 697 1107 697 1168 697 1203 697 1240 697 1246 697 1275 697 1300 697 1323 697 1352 697 1364 697 1374 697 1460 698 9 698 15 698 54 698 73 698 121 698 130 698 152 698 158 698 205 698 259 698 262 698 285 698 351 698 485 698 490 698 536 698 618 698 655 698 685 698 698 698 701 698 752 698 761 698 778 698 815 698 823 698 827 698 837 698 864 698 905 698 1044 698 1118 698 1144 698 1153 698 1183 698 1212 698 1221 698 1258 698 1343 698 1360 698 1382 698 1448 698 1452 698 1455 699 0 699 29 699 51 699 80 699 114 699 186 699 251 699 264 699 278 699 301 699 318 699 347 699 358 699 367 699 412 699 419 699 437 699 467 699 494 699 545 699 597 699 645 699 650 699 663 699 665 699 676 699 683 699 689 699 699 699 721 699 729 699 760 699 768 699 787 699 821 699 828 699 895 699 912 699 950 699 986 699 996 699 1011 699 1055 699 1083 699 1197 699 1304 699 1305 699 1398 699 1417 699 1487 700 18 700 146 700 192 700 255 700 340 700 531 700 700 700 851 700 907 700 1004 700 1123 700 1155 700 1177 700 1193 700 1415 700 1466 701 15 701 54 701 73 701 90 701 121 701 152 701 191 701 205 701 259 701 262 701 285 701 323 701 327 701 351 701 485 701 490 701 536 701 563 701 610 701 618 701 619 701 655 701 658 701 698 701 701 701 734 701 752 701 778 701 802 701 808 701 815 701 823 701 864 701 905 701 934 701 959 701 1024 701 1035 701 1044 701 1054 701 1102 701 1113 701 1118 701 1124 701 1153 701 1183 701 1212 701 1258 701 1330 701 1334 701 1340 701 1360 701 1382 701 1452 701 1455 701 1486 702 53 702 58 702 78 702 82 702 102 702 193 702 206 702 211 702 222 702 262 702 270 702 308 702 323 702 348 702 405 702 431 702 451 702 506 702 511 702 533 702 549 702 560 702 610 702 658 702 702 702 752 702 761 702 769 702 808 702 863 702 897 702 901 702 923 702 983 702 1003 702 1024 702 1035 702 1046 702 1065 702 1084 702 1118 702 1124 702 1135 702 1219 702 1334 702 1336 702 1340 702 1459 702 1475 702 1481 702 1486 703 7 703 20 703 31 703 37 703 75 703 87 703 123 703 128 703 148 703 167 703 170 703 178 703 198 703 203 703 204 703 219 703 242 703 292 703 300 703 333 703 336 703 350 703 357 703 360 703 402 703 418 703 457 703 551 703 555 703 559 703 583 703 593 703 622 703 627 703 657 703 671 703 673 703 703 703 725 703 756 703 766 703 777 703 886 703 916 703 928 703 933 703 1020 703 1029 703 1071 703 1087 703 1100 703 1106 703 1112 703 1161 703 1166 703 1171 703 1185 703 1203 703 1205 703 1211 703 1224 703 1257 703 1268 703 1273 703 1311 703 1326 703 1388 703 1402 703 1433 703 1462 703 1490 704 10 704 50 704 61 704 68 704 103 704 141 704 195 704 210 704 299 704 314 704 341 704 342 704 364 704 376 704 379 704 447 704 493 704 504 704 542 704 559 704 571 704 578 704 601 704 627 704 666 704 687 704 704 704 749 704 811 704 898 704 904 704 913 704 915 704 1008 704 1088 704 1095 704 1109 704 1168 704 1189 704 1269 704 1297 704 1300 704 1312 704 1338 704 1374 704 1420 704 1421 704 1437 704 1457 704 1460 704 1495 705 28 705 89 705 138 705 162 705 174 705 261 705 470 705 539 705 552 705 568 705 705 705 753 705 797 705 831 705 832 705 931 705 944 705 995 705 1111 705 1120 705 1292 705 1372 706 71 706 136 706 150 706 177 706 213 706 248 706 252 706 297 706 317 706 390 706 423 706 432 706 439 706 469 706 548 706 588 706 632 706 641 706 706 706 738 706 835 706 868 706 889 706 936 706 964 706 977 706 1053 706 1073 706 1130 706 1247 706 1255 706 1274 706 1284 706 1322 706 1328 706 1381 706 1416 706 1422 706 1480 707 156 707 159 707 196 707 266 707 345 707 383 707 390 707 400 707 448 707 530 707 543 707 548 707 605 707 615 707 641 707 707 707 739 707 763 707 764 707 862 707 920 707 947 707 960 707 964 707 994 707 1005 707 1037 707 1090 707 1126 707 1172 707 1252 707 1267 707 1287 707 1324 707 1325 707 1386 707 1434 707 1436 707 1493 708 28 708 51 708 116 708 206 708 233 708 244 708 267 708 283 708 325 708 355 708 380 708 425 708 482 708 494 708 522 708 575 708 625 708 629 708 646 708 650 708 652 708 676 708 695 708 708 708 715 708 755 708 896 708 921 708 931 708 965 708 986 708 995 708 1007 708 1009 708 1064 708 1079 708 1113 708 1199 708 1204 708 1244 708 1261 708 1314 708 1316 708 1321 708 1378 708 1403 708 1449 708 1468 708 1485 708 1494 709 3 709 8 709 64 709 183 709 316 709 407 709 473 709 527 709 614 709 628 709 660 709 662 709 709 709 816 709 849 709 951 709 1040 709 1043 709 1132 709 1419 709 1463 710 62 710 104 710 105 710 166 710 173 710 209 710 254 710 302 710 309 710 334 710 409 710 426 710 472 710 477 710 489 710 532 710 572 710 710 710 723 710 826 710 899 710 917 710 1051 710 1080 710 1093 710 1114 710 1143 710 1149 710 1233 710 1270 710 1350 710 1380 710 1405 710 1469 711 27 711 96 711 162 711 255 711 322 711 328 711 354 711 394 711 531 711 561 711 590 711 634 711 711 711 786 711 830 711 874 711 887 711 942 711 969 711 1047 711 1092 711 1125 711 1140 711 1209 711 1414 711 1446 712 1 712 100 712 226 712 260 712 320 712 415 712 616 712 653 712 656 712 664 712 672 712 688 712 712 712 740 712 806 712 850 712 855 712 856 712 880 712 966 712 973 712 1077 712 1170 712 1175 712 1181 712 1195 712 1306 712 1317 712 1337 712 1342 712 1387 712 1397 712 1428 712 1438 712 1473 713 11 713 41 713 48 713 81 713 94 713 179 713 199 713 225 713 226 713 245 713 276 713 278 713 310 713 321 713 339 713 347 713 382 713 406 713 419 713 459 713 496 713 501 713 509 713 510 713 513 713 535 713 545 713 664 713 713 713 768 713 781 713 782 713 787 713 790 713 821 713 828 713 834 713 912 713 929 713 946 713 949 713 952 713 1033 713 1045 713 1048 713 1063 713 1081 713 1158 713 1163 713 1170 713 1181 713 1201 713 1208 713 1215 713 1241 713 1251 713 1288 713 1304 713 1335 713 1362 713 1425 713 1445 714 27 714 96 714 116 714 174 714 175 714 206 714 235 714 261 714 263 714 325 714 356 714 479 714 539 714 552 714 561 714 568 714 646 714 714 714 753 714 885 714 887 714 909 714 942 714 944 714 985 714 995 714 1047 714 1072 714 1120 714 1173 714 1244 714 1283 714 1339 714 1372 714 1401 714 1411 714 1414 715 0 715 29 715 222 715 263 715 380 715 459 715 482 715 486 715 494 715 708 715 715 715 879 715 895 715 931 715 973 715 996 715 1016 715 1215 715 1321 715 1398 715 1403 716 4 716 155 716 169 716 177 716 248 716 331 716 519 716 632 716 716 716 1053 716 1073 716 1357 716 1367 716 1423 716 1451 717 1 717 99 717 100 717 134 717 260 717 265 717 337 717 393 717 417 717 421 717 487 717 505 717 510 717 550 717 585 717 596 717 616 717 717 717 754 717 762 717 806 717 890 717 918 717 968 717 988 717 1000 717 1042 717 1074 717 1077 717 1139 717 1226 717 1315 717 1317 717 1397 717 1428 717 1445 717 1470 718 6 718 35 718 42 718 48 718 140 718 163 718 188 718 256 718 313 718 374 718 382 718 406 718 411 718 498 718 512 718 521 718 577 718 635 718 688 718 718 718 740 718 772 718 781 718 782 718 810 718 852 718 894 718 932 718 945 718 961 718 998 718 1022 718 1049 718 1052 718 1081 718 1094 718 1139 718 1158 718 1163 718 1181 718 1201 718 1208 718 1223 718 1362 718 1363 718 1399 719 84 719 120 719 239 719 271 719 275 719 293 719 311 719 315 719 361 719 372 719 515 719 564 719 647 719 677 719 719 719 793 719 858 719 971 719 975 719 1023 719 1056 719 1058 719 1157 719 1248 719 1253 719 1307 719 1377 719 1394 719 1395 719 1424 719 1435 720 38 720 58 720 66 720 86 720 175 720 193 720 211 720 212 720 216 720 250 720 277 720 322 720 328 720 349 720 354 720 394 720 399 720 405 720 428 720 440 720 444 720 464 720 534 720 563 720 580 720 625 720 631 720 652 720 720 720 785 720 792 720 829 720 874 720 923 720 1017 720 1046 720 1047 720 1131 720 1137 720 1234 720 1238 720 1249 720 1283 720 1309 720 1332 720 1336 720 1341 720 1351 720 1390 720 1418 721 0 721 114 721 181 721 197 721 220 721 251 721 264 721 298 721 301 721 358 721 480 721 529 721 546 721 663 721 670 721 699 721 721 721 758 721 765 721 771 721 825 721 996 721 1011 721 1050 721 1055 721 1079 721 1145 721 1186 721 1218 721 1222 721 1318 721 1384 721 1440 722 6 722 42 722 45 722 70 722 108 722 133 722 238 722 268 722 273 722 281 722 303 722 438 722 635 722 686 722 689 722 722 722 731 722 780 722 803 722 810 722 961 722 1031 722 1147 722 1160 722 1228 722 1263 722 1305 722 1333 722 1349 722 1363 722 1399 722 1466 722 1488 722 1499 723 62 723 88 723 166 723 209 723 306 723 334 723 420 723 426 723 472 723 553 723 554 723 572 723 581 723 659 723 668 723 696 723 710 723 723 723 728 723 737 723 748 723 788 723 798 723 804 723 818 723 899 723 917 723 924 723 1062 723 1093 723 1096 723 1104 723 1143 723 1149 723 1192 723 1254 723 1272 723 1285 723 1293 723 1303 723 1383 723 1391 723 1469 724 39 724 43 724 46 724 60 724 77 724 104 724 109 724 112 724 118 724 154 724 176 724 208 724 258 724 280 724 287 724 309 724 369 724 385 724 410 724 456 724 500 724 541 724 557 724 565 724 633 724 724 724 747 724 779 724 826 724 861 724 878 724 891 724 902 724 927 724 957 724 976 724 1013 724 1025 724 1030 724 1114 724 1128 724 1148 724 1150 724 1182 724 1207 724 1210 724 1243 724 1279 724 1295 724 1310 724 1366 724 1368 724 1380 724 1439 724 1489 725 10 725 23 725 37 725 49 725 122 725 184 725 198 725 210 725 319 725 350 725 357 725 376 725 457 725 503 725 542 725 551 725 555 725 559 725 573 725 589 725 593 725 601 725 622 725 627 725 657 725 666 725 703 725 725 725 750 725 756 725 766 725 770 725 800 725 805 725 886 725 898 725 933 725 1008 725 1020 725 1087 725 1088 725 1107 725 1166 725 1185 725 1200 725 1257 725 1429 725 1433 725 1457 725 1483 725 1492 726 29 726 48 726 96 726 124 726 131 726 134 726 199 726 243 726 263 726 284 726 289 726 380 726 392 726 393 726 459 726 486 726 501 726 513 726 594 726 649 726 679 726 726 726 741 726 746 726 757 726 772 726 775 726 786 726 789 726 797 726 810 726 830 726 879 726 921 726 929 726 931 726 942 726 946 726 1016 726 1072 726 1086 726 1164 726 1173 726 1213 726 1304 726 1349 726 1362 726 1372 727 156 727 190 727 396 727 414 727 508 727 530 727 604 727 669 727 691 727 727 727 739 727 841 727 854 727 903 727 919 727 920 727 994 727 1037 727 1038 727 1090 727 1151 727 1267 727 1450 727 1454 728 62 728 88 728 173 728 209 728 324 728 420 728 474 728 553 728 572 728 581 728 659 728 668 728 723 728 728 728 737 728 748 728 788 728 798 728 818 728 917 728 924 728 1062 728 1080 728 1093 728 1096 728 1104 728 1115 728 1143 728 1149 728 1192 728 1259 728 1293 728 1391 729 29 729 51 729 70 729 98 729 124 729 151 729 186 729 199 729 235 729 238 729 256 729 278 729 281 729 298 729 301 729 303 729 358 729 367 729 380 729 412 729 419 729 437 729 442 729 522 729 545 729 594 729 597 729 635 729 661 729 676 729 699 729 729 729 731 729 768 729 803 729 872 729 949 729 1011 729 1031 729 1052 729 1085 729 1086 729 1208 729 1239 729 1263 729 1305 729 1339 729 1362 729 1398 729 1399 729 1417 729 1468 729 1487 729 1488 730 5 730 12 730 13 730 14 730 36 730 85 730 92 730 101 730 202 730 218 730 230 730 240 730 291 730 365 730 434 730 441 730 492 730 547 730 562 730 569 730 603 730 606 730 608 730 609 730 620 730 667 730 730 730 867 730 870 730 883 730 1018 730 1028 730 1076 730 1091 730 1098 730 1129 730 1159 730 1225 730 1291 730 1331 730 1369 730 1373 730 1461 730 1472 731 24 731 51 731 70 731 98 731 108 731 151 731 256 731 273 731 281 731 298 731 303 731 358 731 367 731 437 731 438 731 522 731 635 731 689 731 722 731 729 731 731 731 780 731 794 731 803 731 824 731 1011 731 1031 731 1039 731 1052 731 1085 731 1086 731 1178 731 1208 731 1228 731 1239 731 1263 731 1363 731 1371 731 1399 731 1417 731 1466 731 1468 731 1487 731 1488 732 91 732 143 732 178 732 219 732 319 732 326 732 350 732 416 732 418 732 422 732 457 732 508 732 555 732 617 732 636 732 644 732 732 732 777 732 800 732 935 732 958 732 962 732 997 732 1010 732 1015 732 1087 732 1146 732 1154 732 1167 732 1200 732 1205 732 1268 732 1289 732 1294 732 1311 732 1346 732 1388 732 1426 732 1431 732 1479 733 44 733 57 733 72 733 76 733 135 733 144 733 149 733 232 733 344 733 370 733 375 733 388 733 397 733 401 733 424 733 455 733 478 733 491 733 556 733 584 733 591 733 733 733 799 733 860 733 893 733 993 733 1136 733 1142 733 1179 733 1235 733 1278 733 1290 733 1358 733 1393 733 1456 734 19 734 73 734 90 734 152 734 205 734 222 734 259 734 285 734 312 734 323 734 327 734 338 734 465 734 518 734 536 734 560 734 599 734 655 734 701 734 734 734 752 734 761 734 778 734 802 734 815 734 866 734 871 734 892 734 934 734 1035 734 1044 734 1113 734 1118 734 1124 734 1212 734 1214 734 1266 734 1327 734 1330 734 1334 734 1382 734 1400 734 1413 734 1419 734 1442 734 1486 735 9 735 15 735 54 735 158 735 182 735 205 735 221 735 229 735 285 735 381 735 462 735 473 735 485 735 490 735 618 735 735 735 823 735 837 735 849 735 864 735 1044 735 1144 735 1153 735 1258 735 1389 735 1448 735 1452 735 1463 736 31 736 123 736 170 736 402 736 457 736 593 736 601 736 736 736 1100 736 1112 736 1346 736 1402 736 1426 736 1462 737 62 737 88 737 209 737 324 737 420 737 477 737 553 737 572 737 581 737 659 737 723 737 728 737 737 737 788 737 798 737 818 737 917 737 1006 737 1062 737 1080 737 1093 737 1096 737 1104 737 1115 737 1149 737 1192 737 1293 737 1350 738 16 738 71 738 159 738 177 738 207 738 248 738 252 738 274 738 297 738 317 738 331 738 390 738 423 738 432 738 469 738 519 738 588 738 632 738 641 738 706 738 738 738 853 738 936 738 964 738 977 738 1053 738 1073 738 1130 738 1252 738 1274 738 1328 738 1357 738 1367 738 1416 738 1422 738 1423 738 1451 738 1480 739 22 739 91 739 143 739 156 739 159 739 196 739 266 739 345 739 378 739 383 739 396 739 400 739 448 739 449 739 507 739 530 739 543 739 570 739 604 739 605 739 615 739 621 739 669 739 691 739 707 739 727 739 739 739 791 739 847 739 854 739 873 739 903 739 920 739 947 739 994 739 1037 739 1090 739 1126 739 1172 739 1176 739 1267 739 1324 739 1325 739 1386 739 1434 739 1436 739 1444 740 48 740 140 740 163 740 226 740 246 740 310 740 320 740 413 740 512 740 523 740 596 740 616 740 653 740 672 740 688 740 712 740 718 740 740 740 751 740 762 740 772 740 806 740 852 740 855 740 856 740 880 740 932 740 945 740 963 740 974 740 998 740 1004 740 1049 740 1094 740 1139 740 1158 740 1163 740 1177 740 1181 740 1239 740 1306 740 1387 740 1438 740 1453 740 1473 741 27 741 35 741 134 741 140 741 162 741 289 741 393 741 411 741 413 741 498 741 501 741 521 741 577 741 679 741 726 741 741 741 746 741 772 741 775 741 781 741 789 741 797 741 832 741 890 741 918 741 946 741 1048 741 1049 741 1164 741 1173 741 1213 741 1292 741 1362 741 1410 742 5 742 12 742 52 742 63 742 65 742 85 742 165 742 202 742 234 742 236 742 240 742 365 742 595 742 609 742 630 742 642 742 742 742 759 742 939 742 984 742 1026 742 1028 742 1129 742 1159 742 1265 742 1461 742 1472 743 47 743 79 743 92 743 125 743 147 743 160 743 189 743 253 743 272 743 305 743 344 743 404 743 466 743 484 743 491 743 556 743 611 743 624 743 684 743 694 743 743 743 809 743 882 743 888 743 990 743 999 743 1014 743 1027 743 1069 743 1075 743 1082 743 1277 743 1355 743 1370 743 1375 743 1456 743 1484 744 16 744 32 744 34 744 40 744 150 744 171 744 177 744 207 744 213 744 237 744 274 744 297 744 307 744 317 744 439 744 453 744 495 744 588 744 744 744 813 744 835 744 848 744 853 744 859 744 869 744 936 744 1041 744 1061 744 1110 744 1138 744 1237 744 1247 744 1262 744 1276 744 1284 744 1296 744 1322 744 1347 744 1381 745 129 745 131 745 172 745 180 745 192 745 255 745 269 745 340 745 352 745 394 745 395 745 575 745 590 745 745 745 767 745 769 745 851 745 969 745 983 745 1067 745 1089 745 1125 745 1155 745 1178 745 1209 745 1332 745 1333 745 1353 745 1359 745 1415 745 1468 746 48 746 96 746 124 746 127 746 131 746 134 746 140 746 162 746 243 746 263 746 392 746 393 746 413 746 486 746 501 746 649 746 679 746 688 746 726 746 741 746 746 746 757 746 772 746 775 746 786 746 797 746 830 746 879 746 942 746 946 746 961 746 1016 746 1049 746 1072 746 1173 746 1181 746 1201 746 1213 746 1362 746 1372 747 43 747 46 747 60 747 77 747 109 747 118 747 154 747 176 747 208 747 254 747 280 747 287 747 369 747 385 747 410 747 456 747 500 747 532 747 541 747 557 747 565 747 633 747 651 747 724 747 747 747 779 747 861 747 878 747 891 747 902 747 927 747 957 747 976 747 989 747 1013 747 1025 747 1030 747 1114 747 1128 747 1148 747 1150 747 1182 747 1207 747 1210 747 1243 747 1279 747 1295 747 1310 747 1366 747 1368 747 1380 747 1439 747 1489 748 88 748 166 748 173 748 306 748 420 748 461 748 471 748 525 748 553 748 659 748 668 748 696 748 723 748 728 748 748 748 804 748 924 748 1040 748 1062 748 1080 748 1096 748 1143 748 1191 748 1254 748 1272 748 1285 748 1293 748 1303 748 1319 748 1391 748 1405 748 1427 748 1469 749 33 749 61 749 110 749 141 749 169 749 195 749 299 749 341 749 342 749 364 749 379 749 447 749 458 749 493 749 504 749 586 749 687 749 704 749 749 749 773 749 811 749 843 749 904 749 913 749 915 749 941 749 943 749 956 749 1109 749 1168 749 1189 749 1269 749 1275 749 1312 749 1338 749 1345 749 1374 749 1420 749 1421 749 1437 750 10 750 23 750 122 750 184 750 210 750 319 750 376 750 457 750 503 750 517 750 542 750 551 750 573 750 589 750 601 750 627 750 643 750 666 750 725 750 750 750 766 750 898 750 1008 750 1087 750 1095 750 1185 750 1240 750 1246 750 1344 750 1429 750 1457 750 1492 751 12 751 165 751 740 751 751 751 759 751 1292 751 1411 751 1438 751 1497 752 15 752 53 752 54 752 73 752 78 752 82 752 102 752 121 752 130 752 152 752 200 752 205 752 259 752 270 752 286 752 308 752 338 752 451 752 511 752 549 752 560 752 610 752 631 752 655 752 658 752 685 752 698 752 701 752 702 752 734 752 752 752 761 752 778 752 812 752 815 752 827 752 829 752 846 752 863 752 901 752 905 752 923 752 959 752 967 752 1003 752 1066 752 1084 752 1102 752 1113 752 1118 752 1124 752 1131 752 1135 752 1183 752 1212 752 1221 752 1330 752 1336 752 1340 752 1343 752 1382 752 1400 752 1413 752 1455 752 1459 752 1475 752 1481 753 27 753 28 753 89 753 124 753 127 753 138 753 235 753 267 753 321 753 356 753 392 753 470 753 479 753 502 753 539 753 540 753 552 753 568 753 678 753 705 753 714 753 753 753 775 753 797 753 831 753 832 753 921 753 925 753 931 753 979 753 985 753 995 753 1072 753 1111 753 1120 753 1160 753 1201 753 1292 753 1349 753 1372 754 99 754 100 754 179 754 226 754 246 754 249 754 260 754 265 754 310 754 320 754 329 754 337 754 393 754 406 754 417 754 421 754 445 754 487 754 585 754 596 754 616 754 653 754 717 754 754 754 762 754 790 754 806 754 820 754 912 754 918 754 922 754 945 754 1000 754 1022 754 1042 754 1045 754 1063 754 1070 754 1077 754 1094 754 1139 754 1158 754 1170 754 1181 754 1226 754 1241 754 1251 754 1288 754 1315 754 1317 754 1387 754 1408 754 1428 754 1438 754 1445 754 1453 754 1470 755 26 755 116 755 206 755 233 755 267 755 332 755 355 755 436 755 470 755 482 755 539 755 568 755 629 755 646 755 652 755 708 755 755 755 895 755 931 755 965 755 985 755 995 755 1009 755 1204 755 1314 755 1316 755 1321 755 1403 755 1485 755 1494 756 20 756 37 756 49 756 75 756 122 756 123 756 128 756 167 756 178 756 198 756 203 756 219 756 242 756 290 756 333 756 350 756 357 756 360 756 368 756 376 756 402 756 443 756 503 756 517 756 551 756 555 756 559 756 573 756 582 756 593 756 622 756 627 756 657 756 671 756 673 756 703 756 725 756 756 756 766 756 770 756 800 756 805 756 836 756 886 756 898 756 916 756 928 756 933 756 955 756 1020 756 1087 756 1088 756 1100 756 1101 756 1107 756 1166 756 1171 756 1185 756 1203 756 1211 756 1257 756 1311 756 1433 756 1457 756 1460 756 1483 756 1490 756 1492 757 6 757 42 757 48 757 124 757 131 757 162 757 228 757 243 757 263 757 392 757 479 757 486 757 498 757 501 757 521 757 576 757 649 757 678 757 726 757 746 757 757 757 775 757 786 757 789 757 810 757 834 757 879 757 946 757 961 757 1016 757 1052 757 1072 757 1160 757 1163 757 1173 757 1201 757 1213 757 1349 757 1353 757 1362 758 26 758 185 758 264 758 288 758 312 758 327 758 359 758 398 758 436 758 475 758 480 758 546 758 597 758 598 758 646 758 650 758 663 758 674 758 721 758 758 758 771 758 817 758 934 758 1054 758 1079 758 1113 758 1124 758 1204 758 1218 758 1266 758 1305 758 1318 758 1327 758 1330 758 1412 758 1413 759 12 759 52 759 63 759 65 759 165 759 234 759 642 759 742 759 751 759 759 759 939 759 1026 759 1028 759 1042 759 1077 759 1265 759 1315 759 1337 759 1438 759 1470 760 98 760 106 760 151 760 185 760 225 760 251 760 318 760 339 760 347 760 358 760 367 760 419 760 430 760 470 760 480 760 510 760 529 760 546 760 598 760 645 760 663 760 665 760 674 760 682 760 683 760 699 760 760 760 768 760 787 760 821 760 842 760 949 760 986 760 996 760 1009 760 1019 760 1060 760 1063 760 1079 760 1152 760 1190 760 1197 760 1218 760 1304 760 1318 760 1412 760 1417 760 1440 760 1465 760 1471 761 30 761 53 761 73 761 78 761 82 761 102 761 121 761 130 761 152 761 191 761 205 761 212 761 259 761 270 761 308 761 338 761 451 761 460 761 511 761 537 761 549 761 610 761 631 761 655 761 658 761 685 761 698 761 702 761 734 761 752 761 761 761 778 761 802 761 812 761 815 761 829 761 863 761 884 761 905 761 923 761 967 761 1003 761 1057 761 1065 761 1084 761 1124 761 1135 761 1183 761 1212 761 1330 761 1334 761 1336 761 1382 761 1390 761 1413 761 1418 761 1455 761 1459 761 1481 762 100 762 134 762 140 762 179 762 226 762 246 762 260 762 265 762 310 762 320 762 329 762 337 762 393 762 406 762 417 762 421 762 445 762 487 762 596 762 616 762 653 762 672 762 688 762 717 762 740 762 754 762 762 762 772 762 790 762 806 762 880 762 918 762 922 762 945 762 963 762 974 762 1042 762 1045 762 1049 762 1077 762 1094 762 1139 762 1158 762 1181 762 1223 762 1226 762 1241 762 1315 762 1387 762 1438 762 1445 762 1453 762 1470 763 7 763 20 763 31 763 148 763 156 763 336 763 403 763 449 763 530 763 543 763 548 763 558 763 607 763 641 763 707 763 763 763 764 763 862 763 873 763 948 763 960 763 994 763 1005 763 1037 763 1126 763 1156 763 1184 763 1188 763 1224 763 1255 763 1267 763 1287 763 1324 763 1386 763 1402 763 1404 763 1436 763 1444 763 1464 763 1493 764 22 764 156 764 159 764 196 764 252 764 345 764 390 764 403 764 448 764 530 764 543 764 548 764 588 764 615 764 641 764 707 764 763 764 764 764 847 764 920 764 948 764 960 764 964 764 994 764 1005 764 1037 764 1126 764 1172 764 1174 764 1252 764 1267 764 1287 764 1324 764 1325 764 1386 764 1434 764 1436 764 1493 765 19 765 64 765 97 765 119 765 197 765 220 765 288 765 298 765 330 765 338 765 407 765 427 765 442 765 499 765 518 765 587 765 614 765 628 765 654 765 663 765 721 765 765 765 802 765 816 765 866 765 871 765 892 765 951 765 1050 765 1085 765 1132 765 1133 765 1145 765 1147 765 1214 765 1222 765 1242 765 1260 765 1371 765 1400 765 1412 765 1419 766 23 766 37 766 170 766 184 766 198 766 210 766 319 766 350 766 376 766 457 766 503 766 551 766 555 766 559 766 573 766 589 766 593 766 601 766 622 766 627 766 666 766 703 766 725 766 750 766 756 766 766 766 800 766 886 766 898 766 916 766 933 766 1008 766 1020 766 1029 766 1087 766 1088 766 1100 766 1107 766 1112 766 1166 766 1185 766 1257 766 1300 766 1338 766 1388 766 1457 766 1492 767 66 767 129 767 131 767 145 767 174 767 180 767 261 767 283 767 304 767 322 767 328 767 340 767 349 767 352 767 394 767 395 767 431 767 464 767 486 767 539 767 575 767 576 767 623 767 625 767 695 767 745 767 767 767 769 767 792 767 885 767 887 767 944 767 969 767 980 767 1007 767 1046 767 1067 767 1072 767 1125 767 1141 767 1155 767 1178 767 1209 767 1244 767 1261 767 1333 767 1353 767 1468 768 51 768 70 768 80 768 98 768 106 768 151 768 179 768 181 768 225 768 226 768 245 768 246 768 251 768 276 768 281 768 310 768 339 768 358 768 412 768 419 768 430 768 437 768 509 768 663 768 664 768 665 768 682 768 689 768 692 768 699 768 713 768 729 768 760 768 768 768 787 768 821 768 845 768 912 768 932 768 949 768 950 768 952 768 963 768 974 768 1011 768 1022 768 1032 768 1045 768 1055 768 1063 768 1170 768 1190 768 1208 768 1251 768 1288 768 1398 768 1465 768 1487 769 24 769 129 769 145 769 180 769 192 769 255 769 268 769 286 769 323 769 325 769 328 769 340 769 348 769 352 769 395 769 506 769 522 769 549 769 702 769 745 769 767 769 769 769 969 769 983 769 1046 769 1064 769 1155 769 1178 769 1238 769 1336 769 1415 769 1459 769 1499 770 23 770 37 770 49 770 128 770 184 770 198 770 290 770 360 770 376 770 443 770 457 770 503 770 555 770 559 770 574 770 582 770 589 770 593 770 622 770 627 770 639 770 657 770 673 770 725 770 756 770 770 770 800 770 805 770 886 770 933 770 955 770 1020 770 1088 770 1101 770 1166 770 1268 770 1346 770 1364 770 1388 770 1429 770 1433 770 1457 770 1479 770 1483 770 1492 771 0 771 116 771 197 771 264 771 298 771 301 771 312 771 325 771 327 771 338 771 359 771 398 771 436 771 442 771 539 771 546 771 597 771 598 771 646 771 721 771 758 771 771 771 866 771 885 771 892 771 897 771 934 771 944 771 1011 771 1079 771 1085 771 1124 771 1145 771 1178 771 1244 771 1266 771 1305 771 1327 771 1330 771 1400 771 1413 772 35 772 48 772 94 772 131 772 134 772 140 772 246 772 284 772 313 772 320 772 321 772 363 772 374 772 382 772 393 772 406 772 411 772 413 772 417 772 486 772 501 772 521 772 540 772 596 772 679 772 688 772 718 772 726 772 740 772 741 772 746 772 762 772 772 772 775 772 781 772 782 772 797 772 806 772 852 772 880 772 918 772 945 772 946 772 961 772 963 772 974 772 998 772 1048 772 1049 772 1094 772 1139 772 1158 772 1164 772 1181 772 1213 772 1223 772 1292 772 1362 772 1387 772 1453 773 33 773 61 773 110 773 155 773 169 773 342 773 364 773 447 773 458 773 493 773 514 773 586 773 749 773 773 773 843 773 904 773 941 773 943 773 956 773 1269 773 1345 773 1421 773 1437 774 59 774 67 774 161 774 190 774 335 774 414 774 435 774 774 774 840 774 841 774 857 774 919 774 1021 774 1231 774 1320 774 1365 774 1409 774 1432 774 1443 774 1454 774 1477 774 1491 774 1497 775 27 775 127 775 131 775 134 775 138 775 228 775 243 775 289 775 337 775 392 775 393 775 459 775 479 775 486 775 501 775 502 775 513 775 535 775 649 775 678 775 679 775 726 775 741 775 746 775 753 775 757 775 772 775 775 775 789 775 797 775 830 775 831 775 834 775 879 775 890 775 909 775 918 775 921 775 925 775 946 775 968 775 1000 775 1016 775 1048 775 1072 775 1111 775 1120 775 1160 775 1213 775 1286 775 1349 775 1410 775 1414 775 1446 776 116 776 174 776 175 776 206 776 304 776 325 776 349 776 355 776 356 776 425 776 429 776 431 776 444 776 522 776 537 776 539 776 580 776 590 776 646 776 652 776 681 776 776 776 795 776 884 776 885 776 897 776 923 776 980 776 985 776 992 776 1039 776 1046 776 1131 776 1140 776 1141 776 1204 776 1261 776 1316 776 1339 776 1446 776 1499 777 123 777 143 777 167 777 178 777 219 777 242 777 319 777 326 777 350 777 360 777 378 777 416 777 418 777 422 777 457 777 508 777 555 777 583 777 589 777 593 777 617 777 622 777 639 777 644 777 703 777 732 777 777 777 800 777 886 777 900 777 928 777 935 777 958 777 997 777 1010 777 1015 777 1071 777 1087 777 1106 777 1146 777 1154 777 1161 777 1167 777 1171 777 1185 777 1200 777 1205 777 1211 777 1257 777 1268 777 1289 777 1294 777 1311 777 1326 777 1346 777 1388 777 1426 777 1431 777 1479 778 9 778 19 778 73 778 121 778 130 778 152 778 205 778 259 778 270 778 286 778 312 778 338 778 506 778 536 778 549 778 560 778 587 778 655 778 698 778 701 778 734 778 752 778 761 778 778 778 802 778 815 778 892 778 905 778 959 778 967 778 983 778 1084 778 1113 778 1118 778 1124 778 1145 778 1212 778 1214 778 1221 778 1330 778 1343 778 1382 778 1400 778 1413 778 1442 778 1455 778 1481 778 1486 779 43 779 46 779 60 779 77 779 104 779 118 779 154 779 176 779 208 779 254 779 280 779 287 779 309 779 369 779 385 779 410 779 456 779 500 779 541 779 557 779 565 779 633 779 651 779 724 779 747 779 779 779 826 779 861 779 891 779 902 779 927 779 957 779 976 779 989 779 1013 779 1025 779 1030 779 1128 779 1150 779 1182 779 1207 779 1210 779 1243 779 1279 779 1295 779 1310 779 1366 779 1380 779 1439 779 1489 780 25 780 69 780 108 780 119 780 146 780 273 780 427 780 438 780 454 780 635 780 722 780 731 780 780 780 794 780 872 780 970 780 982 780 1133 780 1186 780 1222 780 1228 780 1260 780 1263 780 1298 780 1384 780 1385 780 1466 780 1488 781 35 781 41 781 81 781 140 781 172 781 188 781 199 781 284 781 313 781 321 781 363 781 374 781 382 781 393 781 406 781 411 781 413 781 487 781 498 781 510 781 521 781 540 781 577 781 713 781 718 781 741 781 772 781 781 781 782 781 790 781 852 781 918 781 929 781 961 781 963 781 998 781 1048 781 1049 781 1094 781 1158 781 1164 781 1181 781 1223 781 1251 781 1425 781 1453 782 6 782 35 782 41 782 42 782 48 782 94 782 140 782 188 782 199 782 256 782 284 782 303 782 313 782 321 782 339 782 363 782 374 782 382 782 406 782 413 782 512 782 521 782 540 782 577 782 594 782 635 782 713 782 718 782 772 782 781 782 782 782 790 782 810 782 831 782 852 782 929 782 961 782 998 782 1052 782 1081 782 1094 782 1158 782 1163 782 1164 782 1201 782 1208 782 1223 782 1251 782 1362 782 1363 782 1399 782 1488 783 34 783 136 783 213 783 252 783 383 783 400 783 439 783 448 783 495 783 615 783 783 783 813 783 847 783 868 783 869 783 889 783 1110 783 1138 783 1174 783 1255 783 1284 783 1376 783 1434 784 14 784 47 784 56 784 79 784 135 784 144 784 164 784 223 784 230 784 279 784 295 784 371 784 387 784 389 784 391 784 401 784 408 784 478 784 483 784 520 784 526 784 556 784 592 784 600 784 611 784 638 784 680 784 784 784 809 784 814 784 822 784 839 784 844 784 888 784 906 784 910 784 911 784 940 784 978 784 1014 784 1034 784 1068 784 1097 784 1099 784 1142 784 1180 784 1206 784 1216 784 1229 784 1230 784 1277 784 1281 784 1299 784 1370 784 1373 784 1407 784 1441 784 1474 784 1484 784 1498 785 30 785 58 785 90 785 137 785 175 785 212 785 216 785 270 785 323 785 440 785 464 785 511 785 533 785 563 785 720 785 785 785 808 785 887 785 1047 785 1057 785 1089 785 1141 785 1187 785 1219 785 1234 785 1238 785 1283 785 1332 785 1334 785 1390 785 1459 786 6 786 17 786 27 786 89 786 96 786 124 786 162 786 172 786 255 786 263 786 268 786 283 786 304 786 313 786 322 786 328 786 354 786 363 786 374 786 382 786 392 786 394 786 399 786 413 786 486 786 501 786 531 786 576 786 590 786 634 786 649 786 681 786 695 786 711 786 726 786 746 786 757 786 786 786 789 786 810 786 830 786 865 786 881 786 887 786 921 786 942 786 946 786 961 786 969 786 991 786 992 786 1039 786 1059 786 1092 786 1125 786 1140 786 1160 786 1173 786 1201 786 1209 786 1213 786 1351 786 1410 786 1414 786 1446 787 11 787 29 787 41 787 94 787 106 787 151 787 179 787 199 787 225 787 245 787 249 787 251 787 318 787 339 787 347 787 459 787 509 787 510 787 545 787 602 787 664 787 665 787 699 787 713 787 760 787 768 787 787 787 820 787 821 787 828 787 845 787 912 787 949 787 950 787 952 787 986 787 1019 787 1026 787 1033 787 1063 787 1152 787 1170 787 1190 787 1304 787 1335 787 1408 787 1465 787 1471 788 84 788 88 788 173 788 209 788 324 788 420 788 472 788 477 788 488 788 489 788 525 788 572 788 581 788 659 788 668 788 675 788 723 788 728 788 737 788 788 788 798 788 818 788 1006 788 1062 788 1080 788 1093 788 1096 788 1104 788 1115 788 1143 788 1149 788 1192 788 1259 788 1293 788 1303 788 1469 789 27 789 89 789 96 789 127 789 162 789 228 789 243 789 289 789 328 789 479 789 486 789 501 789 577 789 649 789 679 789 726 789 741 789 757 789 775 789 786 789 789 789 797 789 830 789 831 789 881 789 890 789 909 789 918 789 921 789 942 789 946 789 968 789 988 789 991 789 1000 789 1092 789 1111 789 1120 789 1213 789 1410 789 1414 789 1446 790 11 790 35 790 41 790 81 790 94 790 179 790 188 790 199 790 245 790 276 790 284 790 339 790 374 790 380 790 382 790 393 790 406 790 487 790 496 790 510 790 513 790 535 790 713 790 754 790 762 790 781 790 782 790 790 790 828 790 834 790 912 790 929 790 946 790 949 790 963 790 1033 790 1045 790 1048 790 1070 790 1081 790 1094 790 1152 790 1158 790 1164 790 1190 790 1201 790 1215 790 1223 790 1241 790 1251 790 1304 790 1335 790 1408 790 1425 790 1445 791 22 791 107 791 143 791 156 791 266 791 378 791 446 791 449 791 507 791 530 791 543 791 558 791 570 791 583 791 607 791 613 791 621 791 739 791 791 791 854 791 862 791 873 791 900 791 903 791 935 791 937 791 948 791 962 791 994 791 1071 791 1090 791 1127 791 1146 791 1156 791 1162 791 1176 791 1184 791 1224 791 1289 791 1294 791 1324 791 1326 791 1386 791 1444 791 1464 792 38 792 66 792 96 792 174 792 212 792 216 792 261 792 322 792 328 792 349 792 354 792 394 792 431 792 464 792 479 792 534 792 580 792 720 792 767 792 792 792 808 792 874 792 887 792 942 792 969 792 980 792 1017 792 1046 792 1047 792 1067 792 1089 792 1125 792 1140 792 1141 792 1209 792 1219 792 1234 792 1238 792 1244 792 1249 792 1283 792 1332 792 1359 792 1418 793 120 793 214 793 275 793 293 793 353 793 361 793 372 793 415 793 476 793 523 793 647 793 677 793 719 793 793 793 850 793 932 793 1051 793 1056 793 1117 793 1195 793 1306 793 1307 793 1342 793 1377 793 1424 794 25 794 69 794 70 794 98 794 111 794 119 794 197 794 220 794 256 794 298 794 303 794 330 794 353 794 427 794 450 794 454 794 731 794 780 794 794 794 796 794 982 794 1012 794 1031 794 1052 794 1055 794 1083 794 1186 794 1222 794 1228 794 1256 794 1260 794 1263 794 1298 794 1371 794 1385 794 1396 794 1447 794 1466 794 1488 795 28 795 89 795 233 795 244 795 268 795 283 795 286 795 304 795 349 795 355 795 394 795 399 795 440 795 444 795 505 795 580 795 623 795 631 795 652 795 681 795 695 795 776 795 795 795 829 795 865 795 992 795 1007 795 1059 795 1131 795 1140 795 1199 795 1316 795 1351 795 1378 795 1425 795 1446 795 1467 796 2 796 93 796 95 796 111 796 126 796 132 796 194 796 227 796 231 796 241 796 247 796 282 796 353 796 362 796 384 796 450 796 463 796 481 796 516 796 564 796 614 796 654 796 670 796 675 796 794 796 796 796 970 796 975 796 1001 796 1012 796 1036 796 1050 796 1105 796 1116 796 1119 796 1122 796 1186 796 1194 796 1248 796 1256 796 1280 796 1298 796 1302 796 1329 796 1354 796 1384 796 1396 796 1478 797 127 797 134 797 140 797 228 797 243 797 289 797 321 797 337 797 392 797 393 797 486 797 501 797 521 797 552 797 568 797 649 797 679 797 705 797 726 797 741 797 746 797 753 797 772 797 775 797 789 797 797 797 879 797 890 797 918 797 946 797 968 797 991 797 1000 797 1042 797 1048 797 1072 797 1111 797 1120 797 1139 797 1173 797 1213 797 1292 797 1372 797 1414 798 74 798 88 798 113 798 132 798 201 798 209 798 227 798 306 798 324 798 386 798 420 798 474 798 481 798 515 798 525 798 566 798 581 798 659 798 668 798 723 798 728 798 737 798 788 798 798 798 804 798 818 798 1002 798 1093 798 1104 798 1192 798 1232 798 1259 798 1293 798 1391 799 44 799 57 799 147 799 344 799 375 799 388 799 491 799 733 799 799 799 893 799 990 799 993 799 1027 799 1202 799 1278 799 1355 799 1358 799 1456 800 37 800 49 800 122 800 128 800 170 800 184 800 290 800 319 800 326 800 350 800 360 800 376 800 416 800 418 800 443 800 457 800 508 800 555 800 574 800 589 800 593 800 622 800 639 800 644 800 673 800 725 800 732 800 756 800 766 800 770 800 777 800 800 800 886 800 933 800 955 800 1010 800 1015 800 1020 800 1087 800 1101 800 1146 800 1166 800 1167 800 1185 800 1200 800 1205 800 1257 800 1268 800 1273 800 1311 800 1346 800 1388 800 1429 800 1431 800 1433 800 1457 800 1479 801 2 801 93 801 95 801 126 801 153 801 227 801 231 801 271 801 282 801 296 801 315 801 450 801 454 801 463 801 516 801 564 801 801 801 838 801 858 801 975 801 1001 801 1002 801 1036 801 1116 801 1119 801 1122 801 1194 801 1227 801 1280 801 1282 801 1298 801 1354 801 1394 801 1396 801 1478 802 19 802 64 802 73 802 205 802 259 802 285 802 288 802 312 802 338 802 465 802 536 802 587 802 628 802 655 802 701 802 734 802 761 802 765 802 778 802 802 802 871 802 892 802 1044 802 1113 802 1118 802 1124 802 1212 802 1214 802 1242 802 1327 802 1330 802 1343 802 1382 802 1419 802 1442 802 1455 802 1463 802 1486 803 70 803 98 803 108 803 133 803 151 803 186 803 238 803 256 803 264 803 273 803 281 803 298 803 301 803 303 803 358 803 438 803 442 803 518 803 645 803 674 803 722 803 729 803 731 803 803 803 824 803 1011 803 1031 803 1032 803 1085 803 1147 803 1228 803 1263 803 1271 803 1305 803 1363 803 1371 803 1412 803 1488 803 1499 804 74 804 201 804 227 804 231 804 306 804 420 804 461 804 515 804 525 804 553 804 659 804 668 804 696 804 723 804 748 804 798 804 804 804 858 804 924 804 1002 804 1040 804 1096 804 1119 804 1254 804 1259 804 1272 804 1285 804 1302 804 1303 804 1391 805 37 805 49 805 75 805 122 805 128 805 178 805 198 805 203 805 290 805 350 805 360 805 368 805 376 805 443 805 468 805 503 805 517 805 551 805 555 805 573 805 574 805 582 805 589 805 593 805 639 805 657 805 671 805 673 805 725 805 756 805 770 805 805 805 819 805 836 805 886 805 955 805 1020 805 1101 805 1107 805 1166 805 1171 805 1185 805 1200 805 1203 805 1205 805 1273 805 1311 805 1364 805 1433 805 1460 805 1483 806 1 806 100 806 140 806 226 806 246 806 260 806 265 806 320 806 393 806 406 806 417 806 421 806 445 806 487 806 596 806 616 806 653 806 672 806 688 806 712 806 717 806 740 806 754 806 762 806 772 806 806 806 855 806 856 806 922 806 945 806 974 806 1042 806 1045 806 1074 806 1077 806 1094 806 1139 806 1158 806 1181 806 1195 806 1315 806 1317 806 1342 806 1387 806 1397 806 1428 806 1438 806 1453 806 1470 806 1473 807 79 807 125 807 135 807 189 807 217 807 223 807 224 807 232 807 253 807 305 807 344 807 371 807 373 807 387 807 404 807 478 807 483 807 484 807 491 807 544 807 556 807 567 807 591 807 600 807 624 807 640 807 684 807 690 807 694 807 807 807 860 807 875 807 910 807 911 807 990 807 1068 807 1078 807 1082 807 1099 807 1142 807 1196 807 1206 807 1217 807 1235 807 1236 807 1250 807 1277 807 1355 807 1356 807 1361 807 1375 807 1441 807 1456 807 1474 808 38 808 58 808 90 808 182 808 216 808 221 808 222 808 257 808 262 808 351 808 431 808 490 808 506 808 533 808 534 808 536 808 618 808 637 808 701 808 702 808 785 808 792 808 808 808 827 808 1044 808 1065 808 1118 808 1187 808 1219 808 1249 808 1258 808 1334 808 1360 808 1415 808 1448 808 1486 809 14 809 47 809 52 809 63 809 92 809 125 809 160 809 230 809 240 809 272 809 279 809 373 809 387 809 404 809 434 809 441 809 569 809 600 809 612 809 624 809 630 809 690 809 694 809 743 809 784 809 809 809 882 809 888 809 910 809 999 809 1026 809 1069 809 1075 809 1097 809 1108 809 1196 809 1206 809 1277 809 1461 809 1472 809 1476 809 1484 810 6 810 42 810 45 810 48 810 51 810 70 810 94 810 124 810 127 810 172 810 256 810 263 810 268 810 283 810 303 810 321 810 339 810 382 810 392 810 406 810 501 810 512 810 575 810 576 810 635 810 678 810 718 810 722 810 726 810 757 810 782 810 786 810 810 810 896 810 921 810 961 810 1007 810 1033 810 1039 810 1052 810 1081 810 1086 810 1160 810 1163 810 1181 810 1201 810 1208 810 1349 810 1362 810 1363 810 1399 810 1468 810 1488 811 10 811 103 811 141 811 195 811 210 811 299 811 314 811 341 811 342 811 364 811 379 811 504 811 542 811 551 811 571 811 578 811 582 811 643 811 666 811 687 811 693 811 697 811 704 811 749 811 811 811 898 811 904 811 913 811 915 811 943 811 1008 811 1095 811 1109 811 1168 811 1240 811 1246 811 1269 811 1275 811 1297 811 1312 811 1323 811 1338 811 1352 811 1374 811 1420 811 1437 811 1457 811 1495 812 30 812 53 812 78 812 82 812 90 812 102 812 130 812 191 812 211 812 212 812 270 812 308 812 332 812 428 812 451 812 460 812 511 812 533 812 534 812 537 812 549 812 610 812 631 812 637 812 658 812 685 812 752 812 761 812 812 812 827 812 829 812 863 812 884 812 905 812 923 812 967 812 1003 812 1057 812 1065 812 1084 812 1135 812 1137 812 1141 812 1183 812 1219 812 1249 812 1334 812 1336 812 1390 812 1418 812 1459 812 1481 813 34 813 40 813 136 813 171 813 207 813 213 813 237 813 274 813 307 813 423 813 439 813 495 813 588 813 615 813 744 813 783 813 813 813 847 813 848 813 853 813 859 813 868 813 869 813 889 813 936 813 1041 813 1110 813 1130 813 1138 813 1174 813 1237 813 1255 813 1284 813 1322 813 1347 813 1376 813 1422 813 1434 814 47 814 76 814 144 814 223 814 224 814 232 814 253 814 279 814 295 814 305 814 343 814 371 814 389 814 408 814 478 814 483 814 592 814 600 814 638 814 648 814 680 814 684 814 694 814 784 814 814 814 822 814 839 814 860 814 940 814 978 814 1014 814 1068 814 1078 814 1097 814 1099 814 1142 814 1180 814 1216 814 1217 814 1229 814 1277 814 1281 814 1299 814 1355 814 1356 814 1361 814 1370 814 1375 814 1407 814 1441 814 1474 814 1498 815 9 815 30 815 54 815 73 815 90 815 121 815 130 815 152 815 205 815 259 815 270 815 286 815 312 815 338 815 485 815 536 815 560 815 618 815 655 815 698 815 701 815 734 815 752 815 761 815 778 815 815 815 823 815 884 815 905 815 967 815 1221 815 1330 815 1343 815 1382 815 1400 815 1413 815 1415 815 1455 815 1481 815 1486 816 3 816 8 816 19 816 64 816 97 816 183 816 407 816 473 816 499 816 614 816 628 816 654 816 660 816 662 816 709 816 765 816 816 816 849 816 951 816 1132 816 1227 816 1242 816 1419 816 1463 817 138 817 264 817 267 817 318 817 475 817 496 817 513 817 535 817 545 817 597 817 758 817 817 817 824 817 828 817 834 817 979 817 1009 817 1011 817 1033 817 1204 817 1215 817 1318 817 1321 817 1425 817 1449 818 62 818 74 818 84 818 88 818 173 818 201 818 209 818 293 818 306 818 324 818 334 818 420 818 461 818 488 818 525 818 553 818 566 818 572 818 581 818 659 818 668 818 723 818 728 818 737 818 788 818 798 818 818 818 924 818 1006 818 1062 818 1080 818 1093 818 1096 818 1104 818 1115 818 1143 818 1149 818 1192 818 1293 818 1391 818 1469 819 122 819 142 819 157 819 203 819 316 819 443 819 468 819 517 819 671 819 805 819 819 819 836 819 877 819 914 819 1043 819 1101 819 1121 819 1169 819 1171 819 1430 820 81 820 99 820 106 820 188 820 249 820 329 820 337 820 347 820 430 820 487 820 510 820 529 820 550 820 585 820 602 820 656 820 754 820 787 820 820 820 922 820 949 820 1019 820 1022 820 1063 820 1070 820 1152 820 1175 820 1190 820 1241 820 1317 820 1408 820 1428 820 1445 821 0 821 11 821 29 821 106 821 151 821 220 821 225 821 251 821 276 821 278 821 339 821 347 821 358 821 367 821 412 821 419 821 430 821 437 821 467 821 480 821 496 821 509 821 529 821 545 821 597 821 663 821 664 821 665 821 682 821 683 821 689 821 699 821 713 821 760 821 768 821 787 821 821 821 828 821 845 821 912 821 986 821 996 821 1011 821 1019 821 1033 821 1055 821 1063 821 1170 821 1197 821 1208 821 1215 821 1304 821 1335 821 1398 821 1465 822 14 822 47 822 79 822 101 822 223 822 279 822 295 822 305 822 391 822 401 822 408 822 452 822 478 822 484 822 526 822 567 822 591 822 606 822 608 822 638 822 680 822 684 822 784 822 814 822 822 822 839 822 867 822 908 822 940 822 978 822 1014 822 1018 822 1076 822 1097 822 1098 822 1142 822 1206 822 1216 822 1229 822 1236 822 1250 822 1281 822 1290 822 1313 822 1348 822 1356 822 1370 822 1375 822 1407 822 1441 822 1498 823 9 823 15 823 54 823 121 823 130 823 158 823 182 823 205 823 221 823 262 823 285 823 351 823 381 823 462 823 485 823 490 823 536 823 618 823 685 823 698 823 701 823 735 823 815 823 823 823 827 823 837 823 864 823 905 823 1044 823 1144 823 1153 823 1183 823 1221 823 1258 823 1340 823 1343 823 1360 823 1389 823 1448 823 1452 823 1455 823 1463 824 0 824 24 824 220 824 238 824 264 824 281 824 298 824 301 824 303 824 327 824 338 824 358 824 398 824 442 824 475 824 480 824 482 824 518 824 629 824 674 824 689 824 731 824 803 824 817 824 824 824 866 824 996 824 1007 824 1011 824 1031 824 1085 824 1145 824 1147 824 1204 824 1228 824 1266 824 1271 824 1305 824 1371 824 1400 824 1403 824 1412 824 1468 824 1488 825 2 825 80 825 114 825 181 825 220 825 225 825 656 825 663 825 670 825 675 825 721 825 825 825 966 825 1012 825 1050 825 1055 825 1170 825 1175 825 1186 825 1308 825 1329 825 1384 825 1395 826 62 826 104 826 105 826 109 826 176 826 208 826 254 826 309 826 346 826 410 826 426 826 456 826 489 826 500 826 532 826 633 826 651 826 710 826 724 826 779 826 826 826 878 826 899 826 917 826 927 826 957 826 976 826 1025 826 1030 826 1114 826 1149 826 1207 826 1220 826 1243 826 1270 826 1310 826 1350 826 1380 826 1383 827 9 827 15 827 54 827 121 827 130 827 158 827 182 827 205 827 221 827 229 827 257 827 262 827 285 827 351 827 381 827 462 827 485 827 490 827 536 827 610 827 618 827 619 827 685 827 698 827 752 827 808 827 812 827 823 827 827 827 837 827 864 827 905 827 1044 827 1065 827 1144 827 1153 827 1183 827 1221 827 1258 827 1343 827 1360 827 1448 827 1452 828 0 828 11 828 21 828 41 828 151 828 186 828 225 828 256 828 276 828 278 828 339 828 347 828 358 828 412 828 419 828 437 828 459 828 496 828 509 828 513 828 545 828 597 828 664 828 699 828 713 828 787 828 790 828 817 828 821 828 828 828 912 828 996 828 1011 828 1033 828 1045 828 1052 828 1055 828 1063 828 1081 828 1201 828 1208 828 1215 828 1304 828 1335 828 1398 828 1417 828 1465 828 1488 829 30 829 53 829 78 829 90 829 102 829 191 829 211 829 212 829 270 829 286 829 308 829 348 829 349 829 354 829 394 829 399 829 428 829 440 829 451 829 460 829 464 829 511 829 537 829 549 829 580 829 610 829 625 829 631 829 652 829 720 829 752 829 761 829 795 829 812 829 829 829 863 829 923 829 980 829 1003 829 1057 829 1059 829 1065 829 1084 829 1131 829 1137 829 1140 829 1141 829 1199 829 1238 829 1249 829 1316 829 1336 829 1351 829 1390 829 1418 829 1459 829 1481 830 27 830 66 830 89 830 96 830 127 830 131 830 162 830 263 830 283 830 289 830 392 830 479 830 486 830 501 830 552 830 575 830 625 830 634 830 678 830 711 830 726 830 746 830 775 830 786 830 789 830 830 830 865 830 879 830 887 830 896 830 909 830 921 830 929 830 942 830 946 830 1016 830 1047 830 1059 830 1111 830 1160 830 1165 830 1213 830 1316 830 1410 830 1414 830 1425 830 1446 831 27 831 89 831 127 831 162 831 228 831 382 831 392 831 406 831 470 831 479 831 501 831 540 831 577 831 678 831 705 831 753 831 775 831 782 831 789 831 831 831 865 831 896 831 991 831 995 831 1009 831 1016 831 1120 831 1160 831 1201 831 1372 831 1410 831 1414 831 1425 831 1449 832 28 832 70 832 138 832 267 832 321 832 467 832 470 832 498 832 521 832 540 832 552 832 568 832 705 832 741 832 753 832 832 832 931 832 995 832 1086 832 1111 832 1120 832 1208 832 1292 832 1339 832 1417 833 32 833 40 833 115 833 139 833 157 833 177 833 237 833 307 833 366 833 453 833 833 833 835 833 848 833 859 833 869 833 914 833 926 833 1041 833 1061 833 1103 833 1138 833 1245 833 1247 833 1262 833 1276 833 1296 833 1347 833 1376 833 1406 833 1482 834 81 834 127 834 134 834 138 834 228 834 243 834 318 834 337 834 393 834 496 834 513 834 535 834 649 834 713 834 757 834 775 834 790 834 817 834 834 834 909 834 912 834 918 834 925 834 946 834 968 834 979 834 1000 834 1016 834 1033 834 1048 834 1070 834 1215 834 1241 834 1286 834 1392 834 1408 834 1425 834 1445 834 1449 834 1471 835 32 835 34 835 40 835 139 835 150 835 171 835 177 835 207 835 213 835 237 835 248 835 307 835 317 835 366 835 439 835 453 835 495 835 706 835 744 835 833 835 835 835 848 835 853 835 859 835 868 835 869 835 889 835 926 835 936 835 1041 835 1061 835 1103 835 1110 835 1138 835 1237 835 1247 835 1262 835 1276 835 1296 835 1322 835 1347 835 1376 835 1381 835 1406 835 1482 836 37 836 49 836 50 836 68 836 75 836 128 836 141 836 195 836 203 836 204 836 242 836 294 836 368 836 443 836 571 836 573 836 657 836 671 836 673 836 697 836 756 836 805 836 819 836 836 836 916 836 930 836 953 836 1029 836 1107 836 1169 836 1203 836 1273 836 1364 836 1379 836 1460 836 1483 837 9 837 15 837 54 837 121 837 158 837 182 837 205 837 221 837 229 837 285 837 351 837 381 837 462 837 473 837 485 837 490 837 599 837 618 837 685 837 698 837 735 837 823 837 827 837 837 837 849 837 864 837 1044 837 1144 837 1153 837 1183 837 1221 837 1258 837 1343 837 1360 837 1382 837 1389 837 1448 837 1452 837 1455 837 1463 838 2 838 93 838 95 838 113 838 126 838 153 838 227 838 231 838 282 838 296 838 315 838 450 838 454 838 463 838 481 838 515 838 516 838 564 838 801 838 838 838 975 838 982 838 1001 838 1002 838 1116 838 1119 838 1122 838 1194 838 1227 838 1253 838 1280 838 1282 838 1298 838 1354 838 1394 838 1396 838 1478 839 14 839 47 839 79 839 144 839 217 839 223 839 279 839 295 839 305 839 371 839 387 839 389 839 391 839 401 839 408 839 452 839 478 839 483 839 526 839 567 839 638 839 680 839 684 839 784 839 814 839 822 839 839 839 844 839 911 839 940 839 978 839 1014 839 1068 839 1097 839 1098 839 1142 839 1206 839 1216 839 1229 839 1236 839 1250 839 1281 839 1290 839 1313 839 1355 839 1356 839 1370 839 1375 839 1407 839 1441 839 1498 840 59 840 67 840 161 840 190 840 335 840 414 840 435 840 774 840 840 840 841 840 857 840 919 840 953 840 1021 840 1231 840 1320 840 1365 840 1409 840 1432 840 1443 840 1454 840 1477 840 1491 840 1497 841 59 841 190 841 396 841 414 841 435 841 604 841 669 841 691 841 727 841 774 841 840 841 841 841 919 841 953 841 987 841 1021 841 1038 841 1151 841 1267 841 1320 841 1379 841 1432 841 1450 841 1454 841 1477 841 1491 842 106 842 185 842 244 842 288 842 359 842 398 842 419 842 430 842 480 842 494 842 529 842 546 842 598 842 645 842 650 842 663 842 665 842 674 842 683 842 760 842 842 842 996 842 1019 842 1060 842 1070 842 1079 842 1197 842 1218 842 1318 842 1412 842 1440 842 1465 843 33 843 61 843 110 843 155 843 169 843 342 843 364 843 447 843 458 843 493 843 586 843 687 843 749 843 773 843 843 843 904 843 913 843 941 843 943 843 956 843 1109 843 1269 843 1345 843 1421 843 1437 844 56 844 72 844 79 844 101 844 135 844 164 844 223 844 224 844 230 844 279 844 343 844 373 844 387 844 389 844 391 844 408 844 484 844 497 844 520 844 524 844 556 844 592 844 600 844 611 844 638 844 680 844 784 844 839 844 844 844 867 844 906 844 911 844 940 844 972 844 1034 844 1068 844 1078 844 1097 844 1099 844 1180 844 1196 844 1198 844 1206 844 1230 844 1277 844 1299 844 1361 844 1370 844 1373 844 1393 844 1407 844 1441 844 1474 844 1484 844 1496 845 11 845 29 845 179 845 225 845 249 845 273 845 278 845 339 845 367 845 372 845 459 845 509 845 523 845 656 845 682 845 692 845 768 845 787 845 821 845 845 845 855 845 872 845 880 845 973 845 1026 845 1063 845 1152 845 1170 845 1175 845 1197 845 1335 845 1399 846 53 846 86 846 206 846 211 846 277 846 308 846 332 846 348 846 405 846 451 846 563 846 579 846 626 846 658 846 752 846 846 846 863 846 901 846 1024 846 1066 846 1084 846 1131 846 1137 846 1309 846 1475 846 1494 847 159 847 196 847 252 847 345 847 383 847 400 847 448 847 615 847 739 847 764 847 783 847 813 847 847 847 920 847 1037 847 1090 847 1126 847 1172 847 1174 847 1267 847 1287 847 1325 847 1386 847 1434 847 1436 847 1493 848 16 848 32 848 34 848 40 848 115 848 139 848 150 848 171 848 177 848 207 848 213 848 237 848 274 848 297 848 307 848 317 848 366 848 439 848 453 848 495 848 588 848 744 848 813 848 833 848 835 848 848 848 853 848 859 848 869 848 926 848 936 848 1041 848 1103 848 1110 848 1138 848 1237 848 1247 848 1262 848 1276 848 1284 848 1296 848 1322 848 1347 848 1376 848 1381 848 1482 849 3 849 8 849 19 849 64 849 182 849 183 849 381 849 407 849 473 849 527 849 599 849 614 849 628 849 660 849 709 849 735 849 816 849 837 849 849 849 1132 849 1144 849 1227 849 1389 849 1419 849 1452 849 1455 849 1463 850 1 850 214 850 265 850 415 850 476 850 523 850 672 850 712 850 793 850 850 850 855 850 856 850 876 850 932 850 945 850 974 850 1051 850 1074 850 1117 850 1195 850 1317 850 1337 850 1342 850 1397 850 1473 851 18 851 129 851 146 851 192 851 255 851 269 851 340 851 352 851 395 851 531 851 700 851 745 851 851 851 907 851 1089 851 1123 851 1155 851 1177 851 1193 851 1415 852 35 852 94 852 108 852 124 852 140 852 172 852 255 852 284 852 313 852 321 852 363 852 374 852 382 852 413 852 512 852 531 852 540 852 577 852 635 852 688 852 718 852 740 852 772 852 781 852 782 852 852 852 907 852 961 852 998 852 1049 852 1086 852 1123 852 1163 852 1177 852 1223 852 1292 852 1362 853 16 853 32 853 34 853 40 853 136 853 171 853 177 853 207 853 213 853 237 853 274 853 307 853 317 853 439 853 453 853 495 853 588 853 738 853 744 853 813 853 835 853 848 853 853 853 859 853 868 853 869 853 926 853 936 853 1041 853 1110 853 1138 853 1237 853 1247 853 1262 853 1276 853 1284 853 1296 853 1322 853 1347 853 1381 854 22 854 91 854 107 854 143 854 156 854 266 854 378 854 396 854 400 854 446 854 449 854 507 854 508 854 543 854 570 854 604 854 607 854 613 854 617 854 621 854 636 854 644 854 669 854 691 854 727 854 739 854 791 854 854 854 873 854 900 854 903 854 920 854 935 854 937 854 962 854 994 854 1010 854 1038 854 1090 854 1146 854 1151 854 1162 854 1176 854 1294 854 1324 854 1386 854 1444 855 1 855 226 855 246 855 249 855 265 855 278 855 310 855 320 855 550 855 616 855 653 855 656 855 672 855 688 855 712 855 740 855 806 855 845 855 850 855 855 855 856 855 880 855 932 855 945 855 963 855 974 855 1042 855 1074 855 1094 855 1139 855 1317 855 1335 855 1337 855 1342 855 1387 855 1399 855 1428 855 1438 855 1453 855 1473 856 1 856 100 856 214 856 246 856 260 856 265 856 320 856 417 856 476 856 616 856 653 856 672 856 688 856 712 856 740 856 806 856 850 856 855 856 856 856 876 856 945 856 974 856 1074 856 1117 856 1139 856 1177 856 1195 856 1306 856 1337 856 1342 856 1387 856 1397 856 1438 856 1453 856 1473 857 59 857 67 857 161 857 190 857 335 857 414 857 435 857 774 857 840 857 857 857 1021 857 1231 857 1320 857 1365 857 1409 857 1432 857 1443 857 1477 857 1491 857 1497 858 74 858 84 858 93 858 95 858 120 858 126 858 132 858 201 858 231 858 239 858 241 858 271 858 275 858 282 858 293 858 306 858 311 858 315 858 361 858 488 858 515 858 554 858 564 858 647 858 668 858 677 858 719 858 801 858 804 858 858 858 971 858 975 858 1002 858 1023 858 1058 858 1116 858 1157 858 1248 858 1282 858 1307 858 1354 858 1394 858 1395 858 1424 858 1435 859 32 859 34 859 40 859 136 859 171 859 207 859 213 859 237 859 307 859 366 859 439 859 453 859 495 859 744 859 813 859 833 859 835 859 848 859 853 859 859 859 868 859 869 859 889 859 926 859 936 859 1041 859 1061 859 1103 859 1110 859 1138 859 1237 859 1247 859 1262 859 1276 859 1284 859 1296 859 1322 859 1347 859 1376 859 1381 859 1482 860 44 860 57 860 72 860 76 860 135 860 144 860 149 860 189 860 217 860 224 860 232 860 253 860 305 860 343 860 344 860 370 860 388 860 389 860 397 860 424 860 455 860 478 860 491 860 584 860 591 860 684 860 733 860 807 860 814 860 860 860 893 860 978 860 990 860 993 860 1078 860 1136 860 1142 860 1179 860 1235 860 1250 860 1278 860 1355 860 1356 860 1358 860 1375 860 1393 860 1456 861 39 861 43 861 60 861 77 861 112 861 154 861 176 861 208 861 215 861 280 861 287 861 369 861 385 861 410 861 456 861 541 861 633 861 724 861 747 861 779 861 861 861 891 861 902 861 927 861 954 861 957 861 976 861 989 861 1013 861 1025 861 1030 861 1128 861 1148 861 1150 861 1207 861 1210 861 1243 861 1279 861 1295 861 1310 861 1380 861 1439 861 1489 862 22 862 107 862 156 862 196 862 266 862 345 862 378 862 449 862 507 862 543 862 558 862 570 862 605 862 607 862 621 862 707 862 763 862 791 862 862 862 900 862 937 862 947 862 960 862 1071 862 1090 862 1126 862 1127 862 1156 862 1162 862 1176 862 1184 862 1224 862 1267 862 1386 862 1404 862 1444 862 1464 863 26 863 53 863 58 863 78 863 82 863 86 863 102 863 191 863 193 863 200 863 211 863 270 863 277 863 308 863 332 863 405 863 428 863 444 863 451 863 511 863 533 863 534 863 536 863 537 863 549 863 563 863 579 863 610 863 626 863 658 863 685 863 702 863 752 863 761 863 812 863 829 863 846 863 863 863 901 863 923 863 959 863 1003 863 1024 863 1035 863 1054 863 1066 863 1084 863 1102 863 1113 863 1131 863 1135 863 1137 863 1183 863 1212 863 1221 863 1249 863 1309 863 1327 863 1336 863 1340 863 1341 863 1459 863 1475 863 1481 863 1494 864 9 864 15 864 54 864 121 864 158 864 182 864 205 864 221 864 229 864 257 864 262 864 285 864 351 864 381 864 462 864 485 864 490 864 536 864 618 864 619 864 685 864 698 864 701 864 735 864 823 864 827 864 837 864 864 864 1044 864 1144 864 1153 864 1183 864 1258 864 1360 864 1389 864 1448 864 1452 865 28 865 89 865 233 865 244 865 268 865 283 865 382 865 399 865 470 865 505 865 540 865 678 865 681 865 686 865 786 865 795 865 830 865 831 865 865 865 896 865 921 865 965 865 995 865 1007 865 1009 865 1059 865 1060 865 1140 865 1160 865 1199 865 1314 865 1351 865 1378 865 1425 865 1446 865 1467 866 0 866 19 866 197 866 222 866 298 866 312 866 327 866 330 866 398 866 442 866 518 866 629 866 655 866 734 866 765 866 771 866 824 866 866 866 892 866 934 866 938 866 951 866 983 866 1085 866 1145 866 1147 866 1214 866 1222 866 1327 866 1330 866 1371 866 1400 866 1412 867 36 867 56 867 92 867 101 867 164 867 187 867 218 867 279 867 291 867 373 867 408 867 484 867 497 867 520 867 524 867 526 867 547 867 562 867 569 867 592 867 606 867 608 867 620 867 638 867 667 867 680 867 730 867 822 867 844 867 867 867 870 867 906 867 908 867 972 867 1018 867 1034 867 1098 867 1198 867 1225 867 1236 867 1291 867 1299 867 1331 867 1348 867 1369 867 1373 868 32 868 34 868 136 868 150 868 171 868 207 868 213 868 237 868 307 868 317 868 423 868 439 868 495 868 588 868 706 868 783 868 813 868 835 868 853 868 859 868 868 868 869 868 889 868 936 868 1041 868 1103 868 1110 868 1138 868 1174 868 1237 868 1247 868 1255 868 1262 868 1276 868 1284 868 1296 868 1322 868 1347 868 1376 868 1381 868 1422 869 16 869 32 869 34 869 40 869 115 869 139 869 150 869 171 869 177 869 207 869 213 869 237 869 274 869 307 869 366 869 439 869 453 869 495 869 744 869 783 869 813 869 833 869 835 869 848 869 853 869 859 869 868 869 869 869 926 869 936 869 1041 869 1061 869 1103 869 1110 869 1138 869 1237 869 1247 869 1262 869 1276 869 1296 869 1347 869 1376 869 1381 869 1406 869 1482 870 36 870 55 870 56 870 85 870 101 870 164 870 202 870 218 870 230 870 291 870 441 870 492 870 524 870 547 870 562 870 608 870 609 870 620 870 667 870 730 870 867 870 870 870 1091 870 1098 870 1108 870 1129 870 1225 870 1299 870 1369 870 1373 870 1496 871 19 871 73 871 97 871 197 871 259 871 288 871 312 871 338 871 465 871 499 871 587 871 654 871 655 871 734 871 765 871 802 871 871 871 892 871 1214 871 1218 871 1242 871 1330 871 1343 871 1382 871 1412 871 1419 871 1442 871 1463 872 0 872 29 872 51 872 108 872 273 872 367 872 437 872 438 872 545 872 560 872 594 872 661 872 729 872 780 872 845 872 872 872 895 872 973 872 1083 872 1086 872 1239 872 1371 872 1398 872 1417 872 1466 872 1487 873 7 873 20 873 22 873 87 873 148 873 156 873 266 873 292 873 336 873 378 873 396 873 403 873 446 873 449 873 507 873 530 873 543 873 558 873 583 873 604 873 607 873 621 873 669 873 739 873 763 873 791 873 854 873 873 873 900 873 903 873 920 873 935 873 948 873 960 873 994 873 1005 873 1037 873 1038 873 1071 873 1090 873 1106 873 1162 873 1176 873 1184 873 1224 873 1267 873 1287 873 1289 873 1324 873 1326 873 1386 873 1436 873 1444 873 1464 874 38 874 58 874 137 874 211 874 212 874 216 874 257 874 277 874 349 874 354 874 394 874 428 874 440 874 464 874 534 874 580 874 637 874 711 874 720 874 792 874 874 874 1017 874 1047 874 1234 874 1238 874 1249 874 1283 874 1332 874 1336 874 1351 874 1418 875 79 875 144 875 217 875 223 875 224 875 253 875 371 875 404 875 452 875 484 875 526 875 544 875 556 875 567 875 584 875 591 875 640 875 684 875 807 875 875 875 893 875 910 875 972 875 993 875 1078 875 1082 875 1099 875 1216 875 1217 875 1235 875 1236 875 1250 875 1290 875 1313 875 1348 875 1356 875 1361 875 1375 875 1498 876 18 876 214 876 476 876 850 876 856 876 876 876 907 876 945 876 1074 876 1117 876 1177 876 1193 876 1195 876 1306 876 1337 876 1342 876 1397 876 1473 877 142 877 157 877 316 877 819 877 877 877 914 877 1043 877 1121 877 1430 878 43 878 60 878 77 878 104 878 109 878 112 878 118 878 154 878 176 878 208 878 254 878 280 878 346 878 410 878 456 878 500 878 532 878 557 878 565 878 633 878 651 878 724 878 747 878 826 878 878 878 891 878 902 878 957 878 976 878 989 878 1013 878 1025 878 1030 878 1128 878 1148 878 1207 878 1210 878 1220 878 1270 878 1301 878 1310 878 1350 878 1366 878 1368 878 1383 878 1439 878 1489 879 66 879 96 879 127 879 131 879 228 879 243 879 263 879 289 879 392 879 486 879 501 879 502 879 649 879 678 879 679 879 715 879 726 879 746 879 757 879 775 879 797 879 830 879 879 879 909 879 925 879 942 879 946 879 968 879 1016 879 1072 879 1111 879 1165 879 1213 879 1372 879 1414 880 48 880 94 880 163 880 179 880 246 880 278 880 310 880 320 880 339 880 509 880 512 880 521 880 523 880 545 880 616 880 635 880 653 880 664 880 688 880 712 880 740 880 762 880 772 880 845 880 855 880 880 880 963 880 1086 880 1094 880 1139 880 1158 880 1163 880 1181 880 1208 880 1239 880 1306 880 1335 880 1362 880 1387 880 1399 880 1438 881 17 881 96 881 129 881 131 881 145 881 162 881 174 881 255 881 261 881 313 881 322 881 394 881 486 881 531 881 561 881 577 881 634 881 786 881 789 881 881 881 887 881 942 881 969 881 991 881 1089 881 1092 881 1123 881 1125 881 1173 881 1209 881 1213 881 1244 881 1292 881 1372 882 14 882 47 882 52 882 63 882 92 882 125 882 160 882 165 882 218 882 230 882 234 882 240 882 272 882 291 882 371 882 373 882 377 882 404 882 434 882 441 882 483 882 528 882 569 882 603 882 606 882 609 882 612 882 624 882 630 882 640 882 648 882 690 882 694 882 743 882 809 882 882 882 883 882 888 882 910 882 939 882 1026 882 1075 882 1076 882 1097 882 1108 882 1159 882 1196 882 1236 882 1277 882 1461 882 1472 882 1476 882 1484 883 5 883 13 883 14 883 47 883 65 883 92 883 160 883 218 883 234 883 240 883 291 883 377 883 434 883 441 883 452 883 492 883 528 883 544 883 562 883 567 883 603 883 606 883 608 883 609 883 612 883 620 883 630 883 648 883 690 883 730 883 882 883 883 883 939 883 1018 883 1076 883 1159 883 1206 883 1225 883 1236 883 1265 883 1291 883 1313 883 1369 884 30 884 53 884 78 884 82 884 90 884 102 884 152 884 175 884 180 884 191 884 270 884 304 884 308 884 332 884 338 884 348 884 451 884 511 884 522 884 537 884 549 884 610 884 629 884 658 884 685 884 761 884 776 884 812 884 815 884 884 884 897 884 905 884 923 884 967 884 980 884 1003 884 1035 884 1057 884 1084 884 1124 884 1137 884 1141 884 1204 884 1271 884 1334 884 1390 884 1459 885 24 885 116 885 124 885 137 885 145 885 174 885 175 885 206 885 235 885 261 885 321 885 323 885 325 885 356 885 425 885 429 885 522 885 539 885 552 885 568 885 594 885 646 885 695 885 714 885 767 885 771 885 776 885 885 885 944 885 985 885 992 885 1064 885 1072 885 1178 885 1204 885 1244 885 1261 885 1333 885 1339 885 1353 885 1372 885 1401 885 1468 886 7 886 20 886 37 886 49 886 122 886 170 886 178 886 184 886 198 886 203 886 219 886 242 886 319 886 350 886 360 886 376 886 402 886 416 886 418 886 443 886 457 886 508 886 555 886 559 886 589 886 593 886 622 886 627 886 644 886 657 886 671 886 673 886 703 886 725 886 756 886 766 886 770 886 777 886 800 886 805 886 886 886 916 886 928 886 933 886 1015 886 1020 886 1029 886 1087 886 1100 886 1106 886 1112 886 1161 886 1166 886 1167 886 1171 886 1185 886 1200 886 1205 886 1211 886 1257 886 1268 886 1273 886 1311 886 1346 886 1388 886 1426 886 1431 886 1433 886 1479 886 1490 886 1492 887 17 887 27 887 66 887 96 887 131 887 162 887 174 887 175 887 216 887 261 887 263 887 322 887 328 887 354 887 356 887 394 887 444 887 464 887 479 887 486 887 561 887 576 887 634 887 652 887 678 887 711 887 714 887 767 887 785 887 786 887 792 887 830 887 881 887 887 887 909 887 942 887 969 887 1017 887 1047 887 1067 887 1089 887 1092 887 1125 887 1140 887 1165 887 1209 887 1213 887 1244 887 1283 887 1332 887 1414 887 1446 888 63 888 125 888 147 888 160 888 189 888 272 888 279 888 295 888 387 888 404 888 466 888 600 888 694 888 743 888 784 888 809 888 882 888 888 888 910 888 978 888 990 888 999 888 1069 888 1075 888 1082 888 1097 888 1108 888 1277 888 1281 888 1355 888 1407 888 1456 888 1476 888 1484 889 32 889 34 889 136 889 150 889 171 889 207 889 213 889 237 889 248 889 252 889 297 889 317 889 423 889 432 889 439 889 495 889 588 889 641 889 706 889 783 889 813 889 835 889 859 889 868 889 889 889 936 889 964 889 1073 889 1110 889 1130 889 1138 889 1247 889 1255 889 1274 889 1284 889 1322 889 1328 889 1376 889 1381 889 1422 890 27 890 28 890 99 890 134 890 138 890 228 890 337 890 411 890 487 890 505 890 510 890 585 890 686 890 717 890 741 890 775 890 789 890 797 890 890 890 918 890 968 890 988 890 1000 890 1060 890 1120 890 1226 890 1286 890 1414 890 1445 890 1446 891 39 891 43 891 60 891 77 891 112 891 154 891 176 891 208 891 254 891 280 891 287 891 385 891 410 891 456 891 500 891 541 891 633 891 724 891 747 891 779 891 861 891 878 891 891 891 902 891 927 891 957 891 976 891 989 891 1013 891 1025 891 1030 891 1128 891 1148 891 1150 891 1207 891 1210 891 1279 891 1295 891 1301 891 1310 891 1439 892 0 892 19 892 64 892 73 892 97 892 197 892 259 892 288 892 298 892 312 892 330 892 338 892 442 892 465 892 499 892 560 892 587 892 599 892 614 892 628 892 655 892 734 892 765 892 771 892 778 892 802 892 866 892 871 892 892 892 951 892 983 892 1085 892 1145 892 1147 892 1214 892 1222 892 1242 892 1305 892 1327 892 1330 892 1371 892 1382 892 1400 892 1412 892 1419 892 1442 892 1455 893 44 893 57 893 76 893 144 893 147 893 149 893 232 893 344 893 370 893 375 893 388 893 397 893 424 893 491 893 591 893 733 893 799 893 860 893 875 893 893 893 993 893 1027 893 1136 893 1179 893 1202 893 1235 893 1278 893 1358 893 1393 893 1456 894 25 894 70 894 163 894 179 894 181 894 246 894 265 894 273 894 310 894 415 894 523 894 692 894 718 894 894 894 932 894 945 894 963 894 974 894 982 894 1004 894 1022 894 1032 894 1055 894 1094 894 1158 894 1239 894 1335 894 1363 894 1385 894 1447 894 1488 895 0 895 26 895 29 895 185 895 264 895 267 895 288 895 359 895 380 895 398 895 436 895 482 895 494 895 597 895 598 895 645 895 650 895 676 895 683 895 699 895 715 895 755 895 872 895 895 895 931 895 1009 895 1079 895 1218 895 1314 895 1321 895 1398 895 1417 895 1485 896 89 896 124 896 127 896 233 896 267 896 268 896 283 896 380 896 382 896 392 896 425 896 470 896 494 896 501 896 505 896 540 896 575 896 625 896 674 896 678 896 686 896 708 896 810 896 830 896 831 896 865 896 896 896 921 896 965 896 986 896 995 896 1007 896 1009 896 1059 896 1064 896 1160 896 1304 896 1314 896 1316 896 1321 896 1341 896 1349 896 1425 896 1446 896 1449 896 1468 897 30 897 116 897 174 897 175 897 180 897 222 897 312 897 325 897 359 897 431 897 522 897 537 897 646 897 702 897 771 897 776 897 884 897 897 897 980 897 1046 897 1057 897 1113 897 1124 897 1135 897 1141 897 1204 897 1212 897 1330 897 1413 897 1486 898 10 898 23 898 103 898 184 898 198 898 210 898 357 898 376 898 457 898 503 898 517 898 542 898 551 898 559 898 578 898 582 898 601 898 627 898 643 898 657 898 666 898 693 898 704 898 725 898 750 898 756 898 766 898 811 898 898 898 915 898 1008 898 1095 898 1166 898 1168 898 1185 898 1240 898 1246 898 1297 898 1300 898 1323 898 1338 898 1429 898 1457 898 1492 898 1495 899 62 899 104 899 105 899 109 899 166 899 168 899 173 899 254 899 258 899 302 899 309 899 334 899 346 899 409 899 426 899 472 899 477 899 489 899 532 899 572 899 651 899 710 899 723 899 826 899 899 899 917 899 954 899 1080 899 1104 899 1114 899 1143 899 1149 899 1207 899 1220 899 1233 899 1270 899 1310 899 1350 899 1368 899 1383 899 1405 899 1469 900 7 900 20 900 22 900 31 900 107 900 123 900 143 900 148 900 156 900 167 900 178 900 219 900 242 900 266 900 336 900 350 900 378 900 418 900 449 900 507 900 530 900 543 900 558 900 570 900 583 900 593 900 607 900 617 900 621 900 644 900 777 900 791 900 854 900 862 900 873 900 900 900 903 900 928 900 935 900 937 900 958 900 962 900 1015 900 1071 900 1106 900 1154 900 1156 900 1161 900 1162 900 1171 900 1176 900 1184 900 1205 900 1211 900 1224 900 1268 900 1289 900 1294 900 1311 900 1326 900 1431 900 1444 900 1464 901 53 901 78 901 82 901 86 901 102 901 193 901 200 901 211 901 257 901 277 901 308 901 332 901 405 901 428 901 451 901 533 901 563 901 579 901 610 901 626 901 658 901 702 901 752 901 846 901 863 901 901 901 959 901 1003 901 1024 901 1035 901 1066 901 1084 901 1131 901 1135 901 1183 901 1309 901 1327 901 1340 901 1459 901 1475 901 1481 901 1494 902 43 902 60 902 77 902 118 902 154 902 176 902 208 902 280 902 287 902 369 902 385 902 456 902 500 902 532 902 541 902 557 902 565 902 633 902 651 902 724 902 747 902 779 902 861 902 878 902 891 902 902 902 927 902 957 902 976 902 1013 902 1025 902 1030 902 1148 902 1150 902 1182 902 1210 902 1243 902 1279 902 1295 902 1310 902 1366 902 1439 902 1489 903 7 903 20 903 22 903 87 903 148 903 156 903 219 903 242 903 266 903 292 903 378 903 396 903 446 903 449 903 508 903 530 903 543 903 583 903 604 903 613 903 621 903 636 903 639 903 644 903 669 903 691 903 727 903 739 903 791 903 854 903 873 903 900 903 903 903 920 903 928 903 935 903 948 903 987 903 994 903 1005 903 1038 903 1071 903 1106 903 1151 903 1176 903 1211 903 1268 903 1273 903 1289 903 1324 903 1326 903 1431 903 1444 903 1450 903 1458 903 1464 904 33 904 61 904 110 904 141 904 155 904 169 904 195 904 299 904 314 904 341 904 342 904 364 904 379 904 447 904 458 904 493 904 504 904 514 904 571 904 586 904 704 904 749 904 773 904 811 904 843 904 904 904 913 904 915 904 941 904 943 904 956 904 1109 904 1189 904 1269 904 1312 904 1338 904 1345 904 1374 904 1420 904 1421 904 1437 905 9 905 30 905 54 905 73 905 90 905 102 905 121 905 130 905 152 905 191 905 205 905 259 905 270 905 286 905 338 905 485 905 511 905 536 905 549 905 618 905 655 905 698 905 701 905 752 905 761 905 778 905 812 905 815 905 823 905 827 905 884 905 905 905 967 905 1044 905 1183 905 1221 905 1258 905 1343 905 1382 905 1390 905 1413 905 1452 905 1455 906 36 906 56 906 72 906 101 906 164 906 187 906 217 906 343 906 389 906 391 906 408 906 497 906 520 906 524 906 547 906 584 906 592 906 638 906 667 906 680 906 784 906 844 906 867 906 906 906 908 906 972 906 1034 906 1068 906 1078 906 1098 906 1179 906 1180 906 1198 906 1230 906 1299 906 1361 906 1373 906 1407 906 1441 906 1474 906 1496 907 18 907 146 907 688 907 700 907 851 907 852 907 876 907 907 907 998 907 1004 907 1123 907 1177 907 1193 907 1306 907 1397 907 1453 907 1473 908 55 908 83 908 101 908 164 908 187 908 217 908 224 908 343 908 408 908 497 908 524 908 547 908 562 908 567 908 584 908 592 908 608 908 620 908 638 908 667 908 680 908 822 908 867 908 906 908 908 908 972 908 1034 908 1098 908 1198 908 1217 908 1225 908 1250 908 1299 908 1348 908 1356 908 1361 908 1474 908 1496 909 27 909 96 909 138 909 162 909 228 909 243 909 250 909 289 909 356 909 479 909 552 909 561 909 568 909 678 909 679 909 714 909 775 909 789 909 830 909 834 909 879 909 887 909 909 909 925 909 942 909 946 909 988 909 1016 909 1072 909 1111 909 1120 909 1283 909 1286 909 1410 909 1414 909 1446 910 14 910 79 910 92 910 125 910 160 910 189 910 223 910 230 910 253 910 272 910 279 910 295 910 371 910 373 910 387 910 404 910 483 910 484 910 491 910 556 910 600 910 606 910 611 910 624 910 640 910 690 910 694 910 784 910 807 910 809 910 875 910 882 910 888 910 910 910 911 910 999 910 1014 910 1069 910 1075 910 1078 910 1082 910 1099 910 1180 910 1196 910 1217 910 1230 910 1236 910 1277 910 1355 910 1407 910 1441 910 1474 910 1476 910 1484 911 72 911 79 911 92 911 135 911 144 911 189 911 223 911 272 911 295 911 373 911 387 911 389 911 391 911 401 911 455 911 478 911 483 911 484 911 491 911 520 911 556 911 591 911 600 911 611 911 638 911 680 911 684 911 694 911 784 911 807 911 839 911 844 911 910 911 911 911 940 911 978 911 990 911 999 911 1014 911 1018 911 1068 911 1069 911 1082 911 1099 911 1142 911 1180 911 1196 911 1206 911 1217 911 1230 911 1277 911 1281 911 1290 911 1355 911 1370 911 1393 911 1407 911 1441 911 1474 911 1484 912 11 912 21 912 41 912 80 912 94 912 151 912 179 912 225 912 245 912 276 912 278 912 339 912 347 912 358 912 412 912 419 912 437 912 459 912 496 912 509 912 513 912 535 912 545 912 664 912 665 912 699 912 713 912 754 912 768 912 787 912 790 912 821 912 828 912 834 912 912 912 922 912 949 912 952 912 996 912 1022 912 1033 912 1045 912 1048 912 1063 912 1070 912 1081 912 1170 912 1215 912 1241 912 1251 912 1288 912 1335 912 1445 912 1465 913 10 913 33 913 50 913 61 913 103 913 110 913 141 913 195 913 299 913 341 913 342 913 364 913 379 913 447 913 458 913 493 913 504 913 514 913 542 913 578 913 586 913 643 913 687 913 704 913 749 913 811 913 843 913 904 913 913 913 915 913 943 913 956 913 1095 913 1109 913 1168 913 1189 913 1269 913 1297 913 1312 913 1338 913 1374 913 1420 913 1421 913 1437 913 1495 914 142 914 157 914 316 914 819 914 833 914 877 914 914 914 1043 914 1121 914 1430 915 10 915 61 915 103 915 110 915 299 915 341 915 342 915 364 915 379 915 447 915 493 915 504 915 542 915 578 915 601 915 643 915 666 915 687 915 693 915 704 915 749 915 811 915 898 915 904 915 913 915 915 915 943 915 1008 915 1095 915 1109 915 1168 915 1189 915 1240 915 1269 915 1275 915 1297 915 1312 915 1352 915 1374 915 1420 915 1421 915 1437 915 1457 915 1495 916 7 916 20 916 31 916 37 916 49 916 50 916 68 916 75 916 123 916 128 916 141 916 170 916 198 916 203 916 210 916 290 916 294 916 300 916 314 916 333 916 350 916 357 916 360 916 368 916 402 916 433 916 457 916 538 916 551 916 555 916 559 916 571 916 593 916 622 916 627 916 657 916 671 916 673 916 703 916 756 916 766 916 836 916 886 916 916 916 930 916 933 916 1020 916 1029 916 1088 916 1100 916 1106 916 1107 916 1112 916 1166 916 1171 916 1188 916 1203 916 1211 916 1257 916 1300 916 1364 916 1402 916 1433 916 1457 916 1460 916 1462 916 1490 917 62 917 88 917 104 917 105 917 109 917 166 917 173 917 254 917 258 917 309 917 334 917 346 917 409 917 426 917 477 917 489 917 572 917 659 917 710 917 723 917 728 917 737 917 826 917 899 917 917 917 1080 917 1093 917 1104 917 1114 917 1115 917 1134 917 1143 917 1149 917 1207 917 1220 917 1233 917 1270 917 1293 917 1350 917 1383 917 1469 918 35 918 134 918 140 918 228 918 243 918 321 918 337 918 393 918 406 918 411 918 417 918 487 918 501 918 513 918 521 918 577 918 585 918 596 918 679 918 717 918 741 918 754 918 762 918 772 918 775 918 781 918 789 918 797 918 834 918 890 918 918 918 946 918 968 918 991 918 1000 918 1042 918 1049 918 1077 918 1120 918 1139 918 1226 918 1241 918 1286 918 1445 918 1453 918 1470 919 59 919 190 919 396 919 414 919 435 919 669 919 691 919 727 919 774 919 840 919 841 919 919 919 953 919 987 919 1038 919 1151 919 1267 919 1320 919 1379 919 1450 919 1454 919 1477 919 1491 920 22 920 156 920 159 920 196 920 266 920 345 920 383 920 396 920 400 920 448 920 449 920 507 920 530 920 543 920 570 920 604 920 605 920 621 920 669 920 691 920 707 920 727 920 739 920 764 920 847 920 854 920 873 920 903 920 920 920 947 920 948 920 960 920 994 920 1005 920 1037 920 1038 920 1090 920 1126 920 1172 920 1176 920 1267 920 1287 920 1324 920 1325 920 1386 920 1434 920 1436 920 1444 920 1493 921 27 921 28 921 45 921 51 921 89 921 124 921 127 921 263 921 267 921 268 921 283 921 355 921 380 921 392 921 459 921 470 921 482 921 486 921 501 921 505 921 575 921 576 921 594 921 625 921 678 921 686 921 708 921 726 921 753 921 775 921 786 921 789 921 810 921 830 921 865 921 896 921 921 921 929 921 931 921 950 921 965 921 968 921 986 921 995 921 1007 921 1009 921 1111 921 1160 921 1304 921 1314 921 1316 921 1321 921 1349 921 1378 921 1410 921 1414 921 1417 921 1425 921 1446 921 1449 921 1468 922 21 922 100 922 225 922 249 922 260 922 329 922 337 922 393 922 417 922 445 922 509 922 550 922 596 922 602 922 616 922 653 922 656 922 754 922 762 922 806 922 820 922 912 922 922 922 1022 922 1042 922 1045 922 1070 922 1077 922 1139 922 1190 922 1241 922 1288 922 1315 922 1317 922 1387 922 1408 922 1428 922 1438 922 1445 922 1470 923 30 923 38 923 53 923 78 923 102 923 191 923 212 923 270 923 286 923 308 923 428 923 431 923 451 923 460 923 464 923 506 923 511 923 533 923 534 923 537 923 549 923 580 923 610 923 631 923 637 923 702 923 720 923 752 923 761 923 776 923 812 923 829 923 863 923 884 923 923 923 1003 923 1024 923 1046 923 1057 923 1065 923 1084 923 1131 923 1135 923 1219 923 1238 923 1249 923 1336 923 1351 923 1390 923 1418 923 1459 923 1481 924 166 924 306 924 334 924 386 924 420 924 461 924 471 924 472 924 474 924 553 924 554 924 566 924 659 924 668 924 696 924 723 924 728 924 748 924 804 924 818 924 924 924 1096 924 1104 924 1143 924 1192 924 1254 924 1259 924 1272 924 1285 924 1303 924 1391 924 1427 924 1469 925 127 925 228 925 243 925 251 925 289 925 318 925 501 925 502 925 535 925 568 925 678 925 679 925 753 925 775 925 834 925 879 925 909 925 925 925 979 925 988 925 1009 925 1016 925 1072 925 1111 925 1286 925 1392 925 1410 925 1449 925 1471 926 32 926 40 926 115 926 139 926 150 926 171 926 177 926 213 926 237 926 307 926 317 926 366 926 453 926 495 926 833 926 835 926 848 926 853 926 859 926 869 926 926 926 936 926 1041 926 1061 926 1103 926 1138 926 1237 926 1245 926 1247 926 1262 926 1276 926 1296 926 1322 926 1347 926 1376 926 1381 926 1406 926 1482 927 43 927 46 927 60 927 104 927 118 927 154 927 176 927 208 927 280 927 287 927 309 927 369 927 385 927 410 927 456 927 500 927 532 927 541 927 557 927 565 927 633 927 651 927 724 927 747 927 779 927 826 927 861 927 891 927 902 927 927 927 957 927 976 927 989 927 1013 927 1025 927 1030 927 1150 927 1182 927 1210 927 1243 927 1264 927 1279 927 1295 927 1310 927 1366 927 1380 927 1439 927 1489 928 7 928 20 928 31 928 37 928 87 928 123 928 167 928 170 928 178 928 204 928 219 928 242 928 326 928 350 928 360 928 416 928 418 928 443 928 446 928 508 928 583 928 593 928 622 928 644 928 671 928 703 928 756 928 777 928 886 928 900 928 903 928 928 928 935 928 958 928 987 928 1015 928 1029 928 1071 928 1087 928 1106 928 1154 928 1161 928 1166 928 1167 928 1171 928 1200 928 1205 928 1211 928 1257 928 1268 928 1273 928 1289 928 1294 928 1311 928 1326 928 1431 928 1458 928 1490 929 35 929 41 929 81 929 94 929 99 929 199 929 245 929 276 929 284 929 321 929 339 929 374 929 380 929 382 929 392 929 406 929 459 929 486 929 487 929 501 929 510 929 513 929 540 929 577 929 594 929 695 929 713 929 726 929 781 929 782 929 790 929 830 929 921 929 929 929 946 929 949 929 965 929 1045 929 1048 929 1081 929 1094 929 1152 929 1158 929 1164 929 1190 929 1201 929 1215 929 1223 929 1226 929 1251 929 1304 929 1408 929 1410 929 1417 929 1425 929 1445 929 1471 930 50 930 68 930 75 930 141 930 195 930 203 930 204 930 210 930 294 930 299 930 300 930 314 930 357 930 368 930 433 930 514 930 538 930 551 930 571 930 627 930 657 930 697 930 836 930 916 930 930 930 1029 930 1088 930 1100 930 1107 930 1169 930 1203 930 1275 930 1300 930 1338 930 1352 930 1364 930 1374 930 1379 930 1460 930 1490 930 1495 931 28 931 29 931 45 931 51 931 89 931 138 931 267 931 355 931 380 931 459 931 470 931 482 931 486 931 552 931 575 931 625 931 676 931 705 931 708 931 715 931 726 931 753 931 755 931 832 931 895 931 921 931 931 931 965 931 986 931 995 931 1007 931 1086 931 1111 931 1160 931 1261 931 1304 931 1316 931 1349 931 1403 931 1417 931 1485 931 1494 932 163 932 179 932 181 932 226 932 246 932 249 932 265 932 310 932 320 932 415 932 523 932 596 932 692 932 718 932 740 932 768 932 793 932 850 932 855 932 894 932 932 932 945 932 952 932 963 932 974 932 1004 932 1022 932 1032 932 1045 932 1094 932 1158 932 1239 932 1335 932 1453 933 23 933 37 933 49 933 75 933 91 933 128 933 170 933 184 933 198 933 219 933 290 933 319 933 326 933 350 933 360 933 376 933 402 933 416 933 418 933 422 933 457 933 503 933 555 933 559 933 574 933 593 933 622 933 627 933 639 933 673 933 703 933 725 933 756 933 766 933 770 933 800 933 886 933 916 933 933 933 955 933 1015 933 1020 933 1087 933 1100 933 1101 933 1106 933 1112 933 1166 933 1167 933 1200 933 1205 933 1211 933 1257 933 1268 933 1311 933 1346 933 1388 933 1426 933 1429 933 1431 933 1433 933 1457 933 1479 933 1492 934 26 934 82 934 90 934 191 934 222 934 233 934 312 934 327 934 332 934 425 934 436 934 465 934 475 934 563 934 623 934 658 934 701 934 734 934 758 934 771 934 866 934 934 934 959 934 1024 934 1035 934 1054 934 1102 934 1113 934 1118 934 1124 934 1212 934 1266 934 1318 934 1327 934 1330 934 1442 934 1485 934 1486 935 22 935 107 935 123 935 143 935 148 935 167 935 178 935 219 935 242 935 266 935 326 935 350 935 360 935 378 935 416 935 418 935 446 935 449 935 507 935 583 935 607 935 613 935 617 935 621 935 622 935 636 935 644 935 732 935 777 935 791 935 854 935 873 935 900 935 903 935 928 935 935 935 937 935 948 935 958 935 962 935 997 935 1010 935 1015 935 1071 935 1106 935 1154 935 1162 935 1176 935 1211 935 1257 935 1289 935 1294 935 1311 935 1326 935 1426 935 1431 935 1444 935 1464 936 32 936 34 936 40 936 136 936 150 936 171 936 207 936 213 936 237 936 248 936 252 936 274 936 297 936 317 936 423 936 432 936 439 936 453 936 495 936 588 936 641 936 706 936 738 936 744 936 813 936 835 936 848 936 853 936 859 936 868 936 869 936 889 936 926 936 936 936 1041 936 1073 936 1103 936 1110 936 1130 936 1138 936 1237 936 1247 936 1255 936 1262 936 1284 936 1296 936 1322 936 1347 936 1376 936 1381 937 107 937 143 937 266 937 378 937 446 937 449 937 507 937 508 937 558 937 570 937 607 937 613 937 621 937 791 937 854 937 862 937 900 937 935 937 937 937 962 937 1010 937 1071 937 1127 937 1146 937 1151 937 1156 937 1162 937 1176 937 1294 937 1444 937 1450 938 21 938 251 938 412 938 425 938 502 938 535 938 866 938 938 938 1054 938 1165 938 1401 938 1411 939 5 939 12 939 13 939 14 939 52 939 63 939 65 939 85 939 160 939 165 939 218 939 234 939 240 939 291 939 377 939 434 939 492 939 528 939 603 939 609 939 630 939 642 939 648 939 690 939 742 939 759 939 882 939 883 939 939 939 1026 939 1028 939 1129 939 1159 939 1265 939 1461 940 56 940 72 940 76 940 135 940 144 940 164 940 217 940 223 940 232 940 279 940 295 940 305 940 371 940 387 940 389 940 391 940 401 940 408 940 424 940 455 940 478 940 483 940 520 940 526 940 611 940 638 940 680 940 784 940 814 940 822 940 839 940 844 940 911 940 940 940 978 940 990 940 1014 940 1068 940 1078 940 1097 940 1099 940 1142 940 1179 940 1180 940 1216 940 1229 940 1281 940 1290 940 1299 940 1313 940 1356 940 1370 940 1373 940 1375 940 1407 940 1441 940 1498 941 33 941 61 941 110 941 155 941 169 941 342 941 364 941 447 941 458 941 493 941 586 941 749 941 773 941 843 941 904 941 941 941 943 941 956 941 1269 941 1345 941 1421 941 1437 942 27 942 66 942 96 942 131 942 162 942 174 942 261 942 263 942 322 942 354 942 356 942 394 942 479 942 486 942 501 942 552 942 561 942 568 942 576 942 649 942 652 942 678 942 711 942 714 942 726 942 746 942 786 942 789 942 792 942 830 942 879 942 881 942 887 942 909 942 942 942 946 942 1017 942 1047 942 1072 942 1089 942 1092 942 1125 942 1165 942 1173 942 1213 942 1244 942 1283 942 1372 942 1414 943 33 943 61 943 110 943 169 943 341 943 342 943 364 943 379 943 447 943 458 943 493 943 504 943 542 943 586 943 643 943 687 943 693 943 749 943 773 943 811 943 843 943 904 943 913 943 915 943 941 943 943 943 956 943 1095 943 1109 943 1168 943 1269 943 1275 943 1312 943 1345 943 1374 943 1421 943 1437 944 24 944 66 944 116 944 131 944 137 944 145 944 174 944 206 944 235 944 261 944 322 944 323 944 325 944 356 944 429 944 431 944 522 944 539 944 576 944 646 944 705 944 714 944 767 944 771 944 885 944 944 944 985 944 992 944 1064 944 1072 944 1173 944 1178 944 1209 944 1244 944 1339 944 1353 944 1372 944 1401 944 1403 945 1 945 100 945 140 945 246 945 265 945 310 945 320 945 393 945 406 945 417 945 421 945 596 945 616 945 672 945 688 945 718 945 740 945 754 945 762 945 772 945 806 945 850 945 855 945 856 945 876 945 894 945 932 945 945 945 963 945 974 945 998 945 1049 945 1074 945 1094 945 1139 945 1158 945 1177 945 1342 945 1387 945 1397 945 1438 945 1453 945 1473 946 94 946 127 946 131 946 134 946 138 946 162 946 228 946 243 946 289 946 337 946 392 946 393 946 459 946 479 946 486 946 501 946 513 946 535 946 576 946 649 946 679 946 713 946 726 946 741 946 746 946 757 946 772 946 775 946 786 946 789 946 790 946 797 946 830 946 834 946 879 946 909 946 918 946 929 946 942 946 946 946 968 946 1000 946 1016 946 1048 946 1072 946 1173 946 1213 946 1241 946 1286 946 1372 946 1392 946 1410 946 1445 947 159 947 196 947 266 947 345 947 383 947 400 947 448 947 543 947 605 947 615 947 707 947 739 947 862 947 920 947 947 947 960 947 1037 947 1090 947 1126 947 1127 947 1172 947 1174 947 1267 947 1325 947 1386 947 1434 947 1436 947 1493 948 7 948 20 948 22 948 87 948 148 948 156 948 204 948 242 948 266 948 292 948 336 948 378 948 396 948 403 948 446 948 449 948 530 948 543 948 583 948 604 948 613 948 621 948 669 948 763 948 764 948 791 948 873 948 903 948 920 948 935 948 948 948 960 948 987 948 994 948 1005 948 1037 948 1038 948 1176 948 1224 948 1287 948 1289 948 1324 948 1326 948 1386 948 1404 948 1436 948 1444 948 1450 948 1458 948 1464 948 1493 949 21 949 41 949 80 949 81 949 99 949 106 949 151 949 179 949 186 949 188 949 199 949 245 949 276 949 278 949 281 949 318 949 339 949 347 949 412 949 419 949 430 949 437 949 487 949 496 949 509 949 510 949 529 949 545 949 550 949 602 949 661 949 665 949 682 949 683 949 686 949 713 949 729 949 760 949 768 949 787 949 790 949 820 949 912 949 929 949 949 949 950 949 952 949 1011 949 1019 949 1022 949 1032 949 1033 949 1045 949 1060 949 1063 949 1086 949 1152 949 1170 949 1190 949 1208 949 1223 949 1251 949 1288 949 1304 949 1408 949 1417 949 1465 949 1487 950 45 950 89 950 106 950 151 950 186 950 245 950 268 950 278 950 318 950 337 950 339 950 347 950 380 950 437 950 470 950 494 950 496 950 505 950 510 950 535 950 540 950 545 950 665 950 676 950 682 950 683 950 686 950 699 950 768 950 787 950 921 950 949 950 950 950 952 950 965 950 968 950 986 950 1033 950 1048 950 1060 950 1160 950 1190 950 1251 950 1304 950 1349 950 1408 950 1417 950 1425 950 1445 950 1471 951 3 951 8 951 19 951 64 951 69 951 97 951 119 951 183 951 197 951 296 951 330 951 407 951 427 951 442 951 454 951 499 951 599 951 614 951 628 951 660 951 709 951 765 951 816 951 866 951 892 951 951 951 1132 951 1133 951 1186 951 1222 951 1227 951 1242 951 1260 951 1419 952 21 952 80 952 94 952 151 952 179 952 181 952 199 952 225 952 226 952 245 952 246 952 249 952 251 952 276 952 278 952 310 952 339 952 412 952 419 952 430 952 437 952 445 952 496 952 509 952 535 952 545 952 602 952 664 952 665 952 713 952 768 952 787 952 912 952 932 952 949 952 950 952 952 952 963 952 966 952 974 952 1022 952 1032 952 1033 952 1045 952 1063 952 1152 952 1158 952 1170 952 1181 952 1190 952 1215 952 1223 952 1251 952 1288 953 59 953 87 953 190 953 204 953 414 953 836 953 840 953 841 953 919 953 953 953 987 953 1029 953 1038 953 1151 953 1167 953 1169 953 1273 953 1320 953 1379 953 1454 953 1458 953 1491 954 39 954 104 954 109 954 112 954 168 954 215 954 258 954 280 954 302 954 309 954 346 954 409 954 410 954 426 954 489 954 861 954 899 954 954 954 989 954 1025 954 1114 954 1128 954 1134 954 1148 954 1207 954 1233 954 1301 954 1319 954 1368 954 1380 954 1405 955 49 955 122 955 128 955 290 955 360 955 443 955 468 955 517 955 555 955 574 955 582 955 639 955 673 955 756 955 770 955 800 955 805 955 933 955 955 955 1020 955 1101 955 1311 955 1364 955 1388 955 1433 956 33 956 61 956 110 956 155 956 169 956 299 956 341 956 342 956 364 956 379 956 447 956 458 956 493 956 504 956 586 956 687 956 749 956 773 956 843 956 904 956 913 956 941 956 943 956 956 956 1109 956 1269 956 1312 956 1345 956 1421 956 1437 957 43 957 46 957 60 957 77 957 104 957 118 957 154 957 176 957 208 957 287 957 309 957 369 957 385 957 410 957 456 957 500 957 532 957 541 957 557 957 565 957 633 957 651 957 724 957 747 957 779 957 826 957 861 957 878 957 891 957 902 957 927 957 957 957 976 957 1013 957 1025 957 1030 957 1150 957 1182 957 1210 957 1243 957 1264 957 1270 957 1279 957 1295 957 1310 957 1366 957 1380 957 1439 957 1489 958 91 958 123 958 143 958 167 958 178 958 219 958 326 958 350 958 360 958 378 958 416 958 418 958 422 958 446 958 583 958 617 958 621 958 622 958 636 958 644 958 732 958 777 958 900 958 928 958 935 958 958 958 962 958 997 958 1010 958 1015 958 1146 958 1154 958 1167 958 1200 958 1205 958 1211 958 1257 958 1268 958 1289 958 1294 958 1311 958 1326 958 1426 958 1431 959 26 959 58 959 78 959 82 959 86 959 102 959 191 959 193 959 200 959 211 959 312 959 332 959 405 959 451 959 534 959 536 959 563 959 579 959 623 959 626 959 658 959 685 959 701 959 752 959 778 959 863 959 901 959 934 959 959 959 1024 959 1035 959 1054 959 1066 959 1102 959 1113 959 1124 959 1131 959 1135 959 1212 959 1221 959 1309 959 1327 959 1330 959 1340 959 1341 959 1413 959 1467 959 1481 959 1486 960 156 960 159 960 196 960 345 960 383 960 390 960 396 960 400 960 448 960 449 960 530 960 543 960 548 960 605 960 641 960 707 960 763 960 764 960 862 960 873 960 920 960 947 960 948 960 960 960 994 960 1005 960 1037 960 1090 960 1126 960 1127 960 1172 960 1184 960 1224 960 1267 960 1287 960 1324 960 1325 960 1386 960 1404 960 1434 960 1436 960 1493 961 6 961 35 961 42 961 48 961 94 961 124 961 162 961 172 961 263 961 303 961 313 961 363 961 374 961 382 961 392 961 406 961 413 961 498 961 512 961 540 961 575 961 576 961 577 961 635 961 649 961 695 961 718 961 722 961 746 961 757 961 772 961 781 961 782 961 786 961 810 961 852 961 961 961 1049 961 1052 961 1163 961 1181 961 1201 961 1208 961 1223 961 1333 961 1362 961 1363 961 1399 962 91 962 143 962 178 962 326 962 378 962 422 962 446 962 449 962 507 962 604 962 613 962 617 962 621 962 636 962 644 962 669 962 732 962 791 962 854 962 900 962 935 962 937 962 958 962 962 962 997 962 1010 962 1015 962 1146 962 1151 962 1154 962 1176 962 1289 962 1294 962 1326 962 1426 963 35 963 163 963 179 963 181 963 226 963 245 963 246 963 265 963 284 963 310 963 320 963 406 963 415 963 523 963 596 963 653 963 688 963 740 963 762 963 768 963 772 963 781 963 790 963 855 963 880 963 894 963 932 963 945 963 952 963 963 963 974 963 1004 963 1022 963 1032 963 1045 963 1094 963 1139 963 1158 963 1181 963 1223 963 1239 963 1335 963 1453 964 16 964 71 964 136 964 150 964 159 964 177 964 207 964 252 964 274 964 297 964 317 964 390 964 423 964 432 964 469 964 548 964 588 964 641 964 706 964 707 964 738 964 764 964 889 964 964 964 977 964 1005 964 1053 964 1073 964 1130 964 1252 964 1255 964 1274 964 1287 964 1322 964 1328 964 1416 964 1422 964 1436 964 1480 964 1493 965 28 965 41 965 81 965 89 965 138 965 151 965 199 965 267 965 318 965 380 965 459 965 470 965 494 965 505 965 510 965 585 965 646 965 665 965 676 965 683 965 686 965 708 965 755 965 865 965 896 965 921 965 929 965 931 965 950 965 965 965 979 965 986 965 995 965 1009 965 1019 965 1060 965 1152 965 1160 965 1215 965 1286 965 1304 965 1314 965 1321 965 1392 965 1408 965 1417 965 1425 965 1445 965 1446 965 1449 965 1471 966 21 966 80 966 114 966 225 966 226 966 412 966 467 966 509 966 653 966 656 966 664 966 675 966 712 966 825 966 952 966 966 966 1012 966 1170 966 1175 966 1288 966 1308 966 1427 967 30 967 73 967 90 967 102 967 130 967 152 967 270 967 286 967 338 967 537 967 623 967 752 967 761 967 778 967 812 967 815 967 884 967 905 967 967 967 980 967 1003 967 1057 967 1124 967 1141 967 1204 967 1271 967 1334 967 1390 967 1413 967 1415 968 6 968 45 968 99 968 127 968 134 968 228 968 243 968 268 968 329 968 337 968 392 968 393 968 459 968 487 968 501 968 505 968 513 968 585 968 596 968 679 968 686 968 717 968 775 968 789 968 797 968 834 968 879 968 890 968 918 968 921 968 946 968 950 968 968 968 1000 968 1048 968 1160 968 1241 968 1286 968 1349 968 1408 968 1414 968 1428 968 1445 968 1446 969 17 969 42 969 129 969 133 969 172 969 174 969 180 969 255 969 261 969 263 969 268 969 283 969 304 969 322 969 328 969 340 969 352 969 354 969 394 969 395 969 399 969 464 969 575 969 576 969 590 969 625 969 634 969 652 969 681 969 695 969 711 969 745 969 767 969 769 969 786 969 792 969 881 969 887 969 969 969 980 969 992 969 1039 969 1067 969 1125 969 1140 969 1155 969 1173 969 1209 969 1244 969 1332 969 1333 969 1499 970 2 970 25 970 93 970 95 970 97 970 111 970 126 970 153 970 194 970 197 970 247 970 282 970 296 970 362 970 384 970 450 970 454 970 463 970 471 970 499 970 516 970 554 970 654 970 662 970 670 970 780 970 796 970 970 970 982 970 1001 970 1012 970 1036 970 1050 970 1083 970 1105 970 1122 970 1186 970 1194 970 1256 970 1329 970 1354 970 1384 970 1385 970 1394 970 1396 970 1447 970 1478 971 74 971 95 971 113 971 117 971 120 971 132 971 201 971 239 971 241 971 271 971 275 971 293 971 311 971 315 971 361 971 372 971 488 971 515 971 554 971 564 971 647 971 677 971 719 971 858 971 971 971 1006 971 1023 971 1056 971 1058 971 1157 971 1192 971 1232 971 1248 971 1253 971 1282 971 1307 971 1377 971 1394 971 1424 971 1435 972 56 972 72 972 83 972 101 972 164 972 187 972 217 972 223 972 224 972 279 972 343 972 371 972 389 972 391 972 408 972 452 972 497 972 520 972 524 972 544 972 547 972 567 972 584 972 592 972 638 972 640 972 844 972 867 972 875 972 906 972 908 972 972 972 1034 972 1068 972 1078 972 1098 972 1099 972 1142 972 1179 972 1180 972 1198 972 1216 972 1225 972 1250 972 1299 972 1313 972 1348 972 1356 972 1361 972 1373 972 1407 972 1441 972 1474 972 1496 973 0 973 29 973 194 973 236 973 372 973 459 973 595 973 712 973 715 973 845 973 872 973 973 973 981 973 984 973 996 973 1398 974 100 974 140 974 163 974 179 974 181 974 226 974 245 974 246 974 265 974 284 974 310 974 313 974 320 974 406 974 415 974 523 974 596 974 653 974 672 974 688 974 740 974 762 974 768 974 772 974 806 974 850 974 855 974 856 974 894 974 932 974 945 974 952 974 963 974 974 974 998 974 1004 974 1022 974 1032 974 1045 974 1094 974 1139 974 1158 974 1177 974 1181 974 1335 974 1387 974 1438 974 1453 974 1473 975 74 975 93 975 95 975 126 975 132 975 194 975 201 975 227 975 231 975 239 975 247 975 271 975 275 975 282 975 296 975 306 975 311 975 315 975 463 975 481 975 515 975 516 975 564 975 670 975 719 975 796 975 801 975 838 975 858 975 975 975 1001 975 1002 975 1023 975 1036 975 1058 975 1116 975 1119 975 1122 975 1157 975 1194 975 1232 975 1248 975 1280 975 1282 975 1354 975 1394 975 1435 975 1478 976 39 976 43 976 60 976 77 976 112 976 154 976 176 976 208 976 254 976 280 976 287 976 302 976 385 976 410 976 456 976 500 976 541 976 633 976 724 976 747 976 779 976 826 976 861 976 878 976 891 976 902 976 927 976 957 976 976 976 989 976 1013 976 1025 976 1030 976 1128 976 1148 976 1150 976 1207 976 1210 976 1279 976 1295 976 1301 976 1310 976 1439 977 4 977 71 977 248 977 297 977 331 977 390 977 423 977 432 977 469 977 519 977 548 977 632 977 641 977 706 977 738 977 964 977 977 977 1053 977 1073 977 1130 977 1188 977 1255 977 1274 977 1328 977 1357 977 1367 977 1416 977 1422 977 1423 977 1451 977 1480 978 72 978 76 978 135 978 144 978 189 978 223 978 232 978 253 978 279 978 295 978 305 978 371 978 373 978 389 978 401 978 408 978 455 978 478 978 483 978 520 978 526 978 556 978 591 978 600 978 611 978 680 978 684 978 784 978 814 978 822 978 839 978 860 978 888 978 911 978 940 978 978 978 990 978 999 978 1014 978 1068 978 1078 978 1097 978 1099 978 1142 978 1180 978 1206 978 1216 978 1229 978 1230 978 1235 978 1277 978 1281 978 1290 978 1355 978 1370 978 1375 978 1407 978 1441 978 1498 979 138 979 228 979 251 979 267 979 318 979 329 979 470 979 502 979 513 979 535 979 568 979 676 979 753 979 817 979 834 979 925 979 965 979 979 979 986 979 988 979 995 979 1009 979 1016 979 1111 979 1286 979 1304 979 1321 979 1392 979 1449 979 1471 980 30 980 38 980 129 980 174 980 175 980 180 980 261 980 283 980 304 980 322 980 325 980 348 980 349 980 394 980 395 980 399 980 431 980 444 980 522 980 537 980 580 980 590 980 631 980 652 980 681 980 695 980 767 980 776 980 792 980 829 980 884 980 897 980 967 980 969 980 980 980 992 980 1057 980 1125 980 1137 980 1140 980 1141 980 1199 980 1204 980 1209 980 1219 980 1244 980 1249 980 1261 980 1271 980 1351 980 1359 980 1378 981 214 981 236 981 476 981 595 981 973 981 981 981 984 981 1117 981 1182 981 1264 982 2 982 25 982 93 982 111 982 117 982 153 982 241 982 275 982 282 982 353 982 362 982 450 982 454 982 463 982 516 982 523 982 780 982 794 982 838 982 894 982 970 982 982 982 1056 982 1105 982 1122 982 1186 982 1194 982 1253 982 1256 982 1260 982 1280 982 1282 982 1298 982 1377 982 1384 982 1385 982 1396 982 1447 983 0 983 73 983 119 983 129 983 180 983 197 983 269 983 298 983 338 983 442 983 506 983 522 983 549 983 560 983 655 983 702 983 745 983 769 983 778 983 866 983 892 983 983 983 1084 983 1085 983 1145 983 1178 983 1260 983 1330 983 1333 983 1371 983 1400 983 1455 984 214 984 236 984 476 984 595 984 742 984 973 984 981 984 984 984 1117 984 1182 984 1264 985 24 985 66 985 116 985 137 985 174 985 206 985 235 985 250 985 261 985 325 985 348 985 356 985 425 985 429 985 479 985 502 985 539 985 552 985 568 985 646 985 678 985 714 985 753 985 755 985 776 985 885 985 944 985 985 985 995 985 1064 985 1072 985 1165 985 1178 985 1244 985 1261 985 1339 985 1401 985 1403 986 89 986 106 986 151 986 244 986 251 986 267 986 318 986 347 986 355 986 380 986 430 986 470 986 480 986 482 986 494 986 505 986 510 986 529 986 535 986 546 986 665 986 674 986 678 986 683 986 686 986 699 986 708 986 760 986 787 986 821 986 896 986 921 986 931 986 950 986 965 986 979 986 986 986 996 986 1007 986 1009 986 1019 986 1060 986 1063 986 1079 986 1160 986 1215 986 1304 986 1318 986 1408 986 1417 986 1425 986 1449 986 1465 986 1471 986 1485 987 7 987 20 987 37 987 87 987 148 987 167 987 204 987 219 987 242 987 292 987 350 987 396 987 446 987 508 987 583 987 604 987 613 987 621 987 636 987 841 987 903 987 919 987 928 987 948 987 953 987 987 987 1038 987 1106 987 1151 987 1161 987 1167 987 1169 987 1171 987 1211 987 1257 987 1268 987 1273 987 1326 987 1379 987 1431 987 1450 987 1454 987 1458 988 81 988 99 988 228 988 289 988 487 988 505 988 510 988 585 988 717 988 789 988 890 988 909 988 925 988 979 988 988 988 1000 988 1226 988 1286 988 1392 988 1410 988 1414 988 1445 988 1471 989 39 989 112 989 168 989 176 989 208 989 215 989 254 989 280 989 302 989 409 989 410 989 456 989 633 989 651 989 747 989 779 989 861 989 878 989 891 989 927 989 954 989 976 989 989 989 1025 989 1030 989 1128 989 1134 989 1148 989 1207 989 1233 989 1295 989 1301 989 1310 989 1319 989 1368 989 1383 990 57 990 76 990 135 990 144 990 147 990 189 990 232 990 253 990 295 990 305 990 344 990 370 990 373 990 397 990 401 990 404 990 455 990 478 990 484 990 491 990 520 990 556 990 591 990 611 990 684 990 743 990 799 990 807 990 860 990 888 990 911 990 940 990 978 990 990 990 993 990 999 990 1014 990 1069 990 1082 990 1202 990 1216 990 1217 990 1235 990 1250 990 1277 990 1290 990 1355 990 1356 990 1358 990 1370 990 1375 990 1456 991 17 991 27 991 124 991 162 991 243 991 321 991 413 991 479 991 531 991 552 991 577 991 634 991 786 991 789 991 797 991 831 991 881 991 918 991 991 991 1092 991 1120 991 1123 991 1173 991 1213 991 1292 991 1372 991 1410 991 1414 991 1446 992 17 992 124 992 129 992 133 992 145 992 172 992 174 992 180 992 255 992 261 992 304 992 322 992 325 992 328 992 394 992 395 992 399 992 429 992 498 992 522 992 561 992 576 992 590 992 634 992 646 992 681 992 695 992 776 992 786 992 795 992 885 992 944 992 969 992 980 992 992 992 1039 992 1046 992 1125 992 1140 992 1160 992 1173 992 1199 992 1209 992 1244 992 1353 993 44 993 57 993 76 993 147 993 149 993 189 993 253 993 344 993 370 993 375 993 388 993 397 993 455 993 491 993 556 993 591 993 733 993 799 993 860 993 875 993 893 993 990 993 993 993 1027 993 1069 993 1082 993 1136 993 1202 993 1235 993 1278 993 1355 993 1358 993 1456 994 7 994 22 994 156 994 196 994 266 994 345 994 378 994 396 994 403 994 449 994 530 994 543 994 570 994 583 994 604 994 621 994 669 994 691 994 707 994 727 994 739 994 763 994 764 994 791 994 854 994 873 994 903 994 920 994 948 994 960 994 994 994 1005 994 1037 994 1038 994 1090 994 1126 994 1176 994 1224 994 1267 994 1287 994 1324 994 1325 994 1326 994 1386 994 1436 994 1444 994 1450 994 1493 995 27 995 28 995 89 995 116 995 138 995 267 995 301 995 355 995 444 995 470 995 482 995 539 995 540 995 552 995 568 995 646 995 652 995 678 995 705 995 708 995 714 995 753 995 755 995 831 995 832 995 865 995 896 995 921 995 931 995 965 995 979 995 985 995 995 995 1007 995 1009 995 1064 995 1111 995 1120 995 1160 995 1199 995 1292 995 1316 995 1321 995 1339 995 1403 995 1414 995 1425 995 1446 995 1494 996 0 996 11 996 114 996 185 996 220 996 238 996 264 996 298 996 301 996 303 996 347 996 358 996 367 996 419 996 480 996 529 996 545 996 546 996 597 996 663 996 674 996 689 996 699 996 715 996 721 996 760 996 821 996 824 996 828 996 842 996 912 996 973 996 986 996 996 996 1011 996 1033 996 1085 996 1147 996 1197 996 1215 996 1218 996 1305 996 1398 996 1412 996 1440 996 1465 996 1488 997 31 997 91 997 123 997 143 997 167 997 178 997 219 997 319 997 326 997 402 997 416 997 418 997 422 997 457 997 593 997 617 997 622 997 636 997 644 997 732 997 777 997 935 997 958 997 962 997 997 997 1010 997 1015 997 1112 997 1146 997 1154 997 1200 997 1205 997 1257 997 1294 997 1311 997 1346 997 1388 997 1426 997 1479 998 18 998 108 998 140 998 146 998 246 998 313 998 320 998 363 998 393 998 406 998 411 998 413 998 512 998 521 998 688 998 718 998 740 998 772 998 781 998 782 998 852 998 907 998 945 998 974 998 998 998 1004 998 1049 998 1094 998 1123 998 1139 998 1158 998 1177 998 1387 998 1397 998 1453 998 1466 998 1473 999 92 999 125 999 189 999 202 999 230 999 240 999 272 999 295 999 373 999 387 999 484 999 491 999 520 999 556 999 569 999 600 999 611 999 612 999 624 999 690 999 694 999 743 999 809 999 888 999 910 999 911 999 978 999 990 999 999 999 1014 999 1018 999 1069 999 1075 999 1196 999 1277 999 1331 999 1355 999 1369 999 1461 999 1472 999 1476 999 1484 1000 81 1000 99 1000 127 1000 134 1000 138 1000 228 1000 329 1000 337 1000 393 1000 487 1000 505 1000 510 1000 513 1000 585 1000 596 1000 686 1000 717 1000 754 1000 775 1000 789 1000 797 1000 834 1000 890 1000 918 1000 946 1000 968 1000 988 1000 1000 1000 1048 1000 1226 1000 1241 1000 1251 1000 1286 1000 1408 1000 1414 1000 1428 1000 1445 1000 1471 1001 2 1001 93 1001 95 1001 97 1001 111 1001 126 1001 153 1001 194 1001 197 1001 227 1001 231 1001 247 1001 282 1001 296 1001 315 1001 362 1001 384 1001 450 1001 454 1001 463 1001 481 1001 499 1001 516 1001 564 1001 614 1001 654 1001 662 1001 670 1001 675 1001 796 1001 801 1001 838 1001 970 1001 975 1001 1001 1001 1002 1001 1036 1001 1050 1001 1105 1001 1116 1001 1119 1001 1122 1001 1157 1001 1186 1001 1194 1001 1248 1001 1256 1001 1280 1001 1282 1001 1302 1001 1329 1001 1354 1001 1384 1001 1394 1001 1396 1001 1478 1002 2 1002 74 1002 93 1002 95 1002 113 1002 126 1002 201 1002 227 1002 231 1002 282 1002 296 1002 306 1002 386 1002 407 1002 481 1002 515 1002 516 1002 525 1002 662 1002 798 1002 801 1002 804 1002 838 1002 858 1002 975 1002 1001 1002 1002 1002 1116 1002 1119 1002 1122 1002 1227 1002 1259 1002 1272 1002 1280 1002 1282 1002 1354 1002 1391 1002 1396 1002 1478 1003 30 1003 53 1003 78 1003 82 1003 90 1003 102 1003 130 1003 191 1003 193 1003 200 1003 211 1003 212 1003 262 1003 270 1003 308 1003 323 1003 332 1003 348 1003 405 1003 428 1003 451 1003 465 1003 511 1003 533 1003 537 1003 549 1003 610 1003 658 1003 702 1003 752 1003 761 1003 812 1003 829 1003 863 1003 884 1003 901 1003 923 1003 967 1003 1003 1003 1024 1003 1035 1003 1046 1003 1057 1003 1084 1003 1118 1003 1124 1003 1135 1003 1137 1003 1141 1003 1183 1003 1327 1003 1334 1003 1336 1003 1340 1003 1390 1003 1459 1003 1481 1004 18 1004 25 1004 108 1004 146 1004 163 1004 246 1004 273 1004 320 1004 415 1004 512 1004 523 1004 688 1004 700 1004 740 1004 894 1004 907 1004 932 1004 963 1004 974 1004 998 1004 1004 1004 1094 1004 1123 1004 1177 1004 1193 1004 1239 1004 1306 1004 1453 1004 1466 1004 1473 1005 22 1005 156 1005 159 1005 266 1005 274 1005 336 1005 390 1005 396 1005 403 1005 449 1005 530 1005 543 1005 548 1005 583 1005 588 1005 621 1005 641 1005 707 1005 763 1005 764 1005 873 1005 903 1005 920 1005 948 1005 960 1005 964 1005 994 1005 1005 1005 1037 1005 1038 1005 1126 1005 1224 1005 1252 1005 1267 1005 1287 1005 1324 1005 1386 1005 1436 1005 1444 1005 1493 1006 120 1006 209 1006 214 1006 293 1006 324 1006 361 1006 488 1006 572 1006 581 1006 647 1006 659 1006 677 1006 737 1006 788 1006 818 1006 971 1006 1006 1006 1051 1006 1062 1006 1093 1006 1115 1006 1149 1006 1192 1006 1293 1006 1307 1006 1424 1007 51 1007 116 1007 206 1007 235 1007 244 1007 263 1007 268 1007 283 1007 325 1007 355 1007 380 1007 399 1007 425 1007 470 1007 482 1007 522 1007 575 1007 576 1007 594 1007 623 1007 625 1007 629 1007 646 1007 652 1007 678 1007 689 1007 695 1007 708 1007 767 1007 795 1007 810 1007 824 1007 865 1007 896 1007 921 1007 931 1007 986 1007 995 1007 1007 1007 1039 1007 1059 1007 1064 1007 1160 1007 1199 1007 1204 1007 1244 1007 1261 1007 1316 1007 1321 1007 1339 1007 1349 1007 1378 1007 1403 1007 1449 1007 1468 1007 1494 1008 10 1008 23 1008 103 1008 184 1008 198 1008 210 1008 314 1008 342 1008 357 1008 376 1008 503 1008 517 1008 542 1008 559 1008 578 1008 582 1008 601 1008 627 1008 643 1008 666 1008 687 1008 693 1008 697 1008 704 1008 725 1008 750 1008 766 1008 811 1008 898 1008 915 1008 1008 1008 1095 1008 1168 1008 1240 1008 1246 1008 1297 1008 1300 1008 1312 1008 1338 1008 1352 1008 1374 1008 1429 1008 1457 1008 1492 1008 1495 1009 26 1009 89 1009 127 1009 244 1009 251 1009 264 1009 267 1009 318 1009 470 1009 482 1009 494 1009 535 1009 546 1009 598 1009 674 1009 678 1009 689 1009 708 1009 755 1009 760 1009 817 1009 831 1009 865 1009 895 1009 896 1009 921 1009 925 1009 965 1009 979 1009 986 1009 995 1009 1009 1009 1079 1009 1160 1009 1215 1009 1314 1009 1318 1009 1321 1009 1341 1009 1425 1009 1449 1009 1465 1009 1467 1009 1471 1010 91 1010 143 1010 219 1010 319 1010 326 1010 350 1010 378 1010 416 1010 418 1010 422 1010 446 1010 508 1010 555 1010 604 1010 617 1010 636 1010 644 1010 669 1010 732 1010 777 1010 800 1010 854 1010 935 1010 937 1010 958 1010 962 1010 997 1010 1010 1010 1015 1010 1087 1010 1146 1010 1151 1010 1154 1010 1167 1010 1200 1010 1205 1010 1268 1010 1289 1010 1294 1010 1311 1010 1346 1010 1388 1010 1431 1010 1479 1011 0 1011 51 1011 70 1011 80 1011 98 1011 114 1011 151 1011 185 1011 186 1011 238 1011 251 1011 256 1011 264 1011 276 1011 278 1011 281 1011 298 1011 301 1011 303 1011 358 1011 367 1011 412 1011 419 1011 437 1011 442 1011 475 1011 480 1011 496 1011 518 1011 545 1011 597 1011 645 1011 663 1011 674 1011 699 1011 721 1011 729 1011 731 1011 768 1011 771 1011 803 1011 817 1011 821 1011 824 1011 828 1011 949 1011 996 1011 1011 1011 1031 1011 1032 1011 1033 1011 1052 1011 1055 1011 1060 1011 1085 1011 1145 1011 1147 1011 1208 1011 1215 1011 1263 1011 1271 1011 1305 1011 1318 1011 1363 1011 1412 1011 1417 1011 1465 1011 1488 1012 2 1012 25 1012 70 1012 98 1012 111 1012 114 1012 163 1012 181 1012 194 1012 220 1012 353 1012 362 1012 384 1012 412 1012 450 1012 467 1012 663 1012 664 1012 670 1012 692 1012 794 1012 796 1012 825 1012 966 1012 970 1012 1012 1012 1032 1012 1055 1012 1083 1012 1105 1012 1170 1012 1186 1012 1228 1012 1239 1012 1256 1012 1298 1012 1302 1012 1308 1012 1385 1012 1396 1012 1466 1012 1478 1013 43 1013 46 1013 60 1013 77 1013 112 1013 118 1013 154 1013 176 1013 208 1013 280 1013 287 1013 369 1013 385 1013 410 1013 456 1013 541 1013 557 1013 565 1013 633 1013 724 1013 747 1013 779 1013 861 1013 878 1013 891 1013 902 1013 927 1013 957 1013 976 1013 1013 1013 1025 1013 1030 1013 1128 1013 1148 1013 1150 1013 1210 1013 1243 1013 1279 1013 1295 1013 1310 1013 1366 1013 1380 1013 1439 1013 1489 1014 47 1014 76 1014 135 1014 144 1014 189 1014 217 1014 253 1014 272 1014 295 1014 305 1014 373 1014 387 1014 401 1014 455 1014 478 1014 483 1014 520 1014 526 1014 556 1014 591 1014 600 1014 611 1014 612 1014 680 1014 684 1014 694 1014 743 1014 784 1014 814 1014 822 1014 839 1014 910 1014 911 1014 940 1014 978 1014 990 1014 999 1014 1014 1014 1018 1014 1069 1014 1075 1014 1082 1014 1099 1014 1142 1014 1180 1014 1206 1014 1216 1014 1217 1014 1229 1014 1230 1014 1250 1014 1277 1014 1281 1014 1290 1014 1355 1014 1370 1014 1375 1014 1407 1014 1441 1014 1474 1014 1484 1014 1498 1015 31 1015 123 1015 143 1015 167 1015 178 1015 219 1015 319 1015 326 1015 350 1015 360 1015 416 1015 418 1015 422 1015 457 1015 508 1015 555 1015 593 1015 617 1015 622 1015 644 1015 732 1015 777 1015 800 1015 886 1015 900 1015 928 1015 933 1015 935 1015 958 1015 962 1015 997 1015 1010 1015 1015 1015 1071 1015 1087 1015 1106 1015 1112 1015 1146 1015 1154 1015 1161 1015 1171 1015 1200 1015 1205 1015 1211 1015 1257 1015 1268 1015 1289 1015 1294 1015 1311 1015 1346 1015 1388 1015 1426 1015 1431 1015 1479 1016 127 1016 131 1016 138 1016 228 1016 243 1016 250 1016 263 1016 392 1016 479 1016 486 1016 501 1016 502 1016 513 1016 535 1016 649 1016 678 1016 679 1016 715 1016 726 1016 746 1016 757 1016 775 1016 830 1016 831 1016 834 1016 879 1016 909 1016 925 1016 946 1016 979 1016 1016 1016 1072 1016 1213 1016 1215 1016 1286 1016 1392 1017 38 1017 66 1017 96 1017 131 1017 137 1017 216 1017 261 1017 269 1017 356 1017 428 1017 464 1017 534 1017 720 1017 792 1017 874 1017 887 1017 942 1017 1017 1017 1047 1017 1067 1017 1089 1017 1219 1017 1234 1017 1238 1017 1244 1017 1336 1017 1359 1018 5 1018 13 1018 14 1018 47 1018 92 1018 101 1018 189 1018 202 1018 230 1018 240 1018 279 1018 291 1018 295 1018 305 1018 365 1018 373 1018 387 1018 408 1018 434 1018 441 1018 483 1018 526 1018 569 1018 606 1018 612 1018 624 1018 630 1018 680 1018 690 1018 730 1018 822 1018 867 1018 883 1018 911 1018 999 1018 1014 1018 1018 1018 1075 1018 1076 1018 1196 1018 1206 1018 1229 1018 1236 1018 1277 1018 1281 1018 1290 1018 1331 1018 1369 1018 1370 1018 1461 1018 1472 1018 1476 1018 1484 1018 1498 1019 11 1019 41 1019 81 1019 99 1019 106 1019 151 1019 188 1019 347 1019 419 1019 430 1019 480 1019 487 1019 505 1019 510 1019 529 1019 546 1019 550 1019 585 1019 665 1019 674 1019 682 1019 760 1019 787 1019 820 1019 821 1019 842 1019 949 1019 965 1019 986 1019 1019 1019 1022 1019 1060 1019 1063 1019 1070 1019 1175 1019 1190 1019 1304 1019 1318 1019 1408 1019 1440 1019 1465 1019 1471 1020 23 1020 37 1020 49 1020 75 1020 128 1020 170 1020 184 1020 198 1020 290 1020 357 1020 360 1020 376 1020 402 1020 443 1020 457 1020 503 1020 517 1020 551 1020 555 1020 559 1020 574 1020 582 1020 589 1020 593 1020 622 1020 627 1020 657 1020 673 1020 703 1020 725 1020 756 1020 766 1020 770 1020 800 1020 805 1020 886 1020 916 1020 933 1020 955 1020 1020 1020 1087 1020 1088 1020 1101 1020 1107 1020 1166 1020 1203 1020 1257 1020 1268 1020 1346 1020 1364 1020 1388 1020 1429 1020 1433 1020 1457 1020 1483 1020 1492 1021 59 1021 67 1021 161 1021 190 1021 335 1021 414 1021 435 1021 774 1021 840 1021 841 1021 857 1021 1021 1021 1231 1021 1320 1021 1365 1021 1409 1021 1432 1021 1443 1021 1454 1021 1477 1021 1491 1021 1497 1022 80 1022 81 1022 99 1022 106 1022 151 1022 179 1022 181 1022 188 1022 199 1022 225 1022 226 1022 245 1022 246 1022 249 1022 278 1022 310 1022 419 1022 430 1022 487 1022 509 1022 529 1022 550 1022 602 1022 653 1022 665 1022 682 1022 718 1022 754 1022 768 1022 820 1022 894 1022 912 1022 922 1022 932 1022 949 1022 952 1022 963 1022 974 1022 1019 1022 1022 1022 1032 1022 1045 1022 1063 1022 1070 1022 1152 1022 1158 1022 1170 1022 1190 1022 1223 1022 1251 1022 1288 1022 1465 1023 84 1023 93 1023 95 1023 120 1023 239 1023 241 1023 271 1023 293 1023 311 1023 315 1023 361 1023 450 1023 515 1023 564 1023 647 1023 677 1023 719 1023 858 1023 971 1023 975 1023 1023 1023 1058 1023 1157 1023 1248 1023 1307 1023 1377 1023 1394 1023 1395 1023 1424 1023 1435 1024 26 1024 53 1024 58 1024 78 1024 82 1024 86 1024 102 1024 137 1024 191 1024 193 1024 200 1024 206 1024 211 1024 222 1024 250 1024 257 1024 277 1024 332 1024 348 1024 405 1024 428 1024 431 1024 444 1024 451 1024 533 1024 534 1024 536 1024 563 1024 579 1024 580 1024 626 1024 658 1024 701 1024 702 1024 846 1024 863 1024 901 1024 923 1024 934 1024 959 1024 1003 1024 1024 1024 1035 1024 1046 1024 1054 1024 1084 1024 1102 1024 1113 1024 1131 1024 1135 1024 1137 1024 1309 1024 1327 1024 1334 1024 1340 1024 1341 1024 1459 1024 1475 1024 1481 1024 1486 1024 1494 1025 39 1025 46 1025 60 1025 77 1025 104 1025 109 1025 112 1025 154 1025 176 1025 208 1025 254 1025 258 1025 280 1025 346 1025 410 1025 456 1025 500 1025 541 1025 565 1025 633 1025 651 1025 724 1025 747 1025 779 1025 826 1025 861 1025 878 1025 891 1025 902 1025 927 1025 954 1025 957 1025 976 1025 989 1025 1013 1025 1025 1025 1030 1025 1114 1025 1128 1025 1134 1025 1148 1025 1207 1025 1210 1025 1243 1025 1270 1025 1301 1025 1310 1025 1350 1025 1368 1025 1380 1025 1439 1026 12 1026 29 1026 52 1026 63 1026 65 1026 125 1026 165 1026 234 1026 240 1026 528 1026 642 1026 742 1026 759 1026 787 1026 809 1026 845 1026 882 1026 939 1026 1026 1026 1028 1026 1075 1026 1265 1026 1461 1027 44 1027 57 1027 147 1027 344 1027 375 1027 388 1027 491 1027 743 1027 799 1027 893 1027 993 1027 1027 1027 1069 1027 1202 1027 1278 1027 1456 1028 5 1028 12 1028 13 1028 52 1028 65 1028 85 1028 165 1028 202 1028 234 1028 240 1028 365 1028 434 1028 441 1028 492 1028 528 1028 603 1028 609 1028 630 1028 642 1028 730 1028 742 1028 759 1028 939 1028 1026 1028 1028 1028 1108 1028 1129 1028 1159 1028 1265 1028 1369 1028 1461 1028 1472 1029 7 1029 20 1029 37 1029 68 1029 87 1029 170 1029 203 1029 204 1029 210 1029 294 1029 300 1029 314 1029 350 1029 433 1029 559 1029 583 1029 627 1029 657 1029 703 1029 766 1029 836 1029 886 1029 916 1029 928 1029 930 1029 953 1029 1029 1029 1088 1029 1100 1029 1106 1029 1169 1029 1171 1029 1211 1029 1300 1029 1338 1029 1458 1029 1460 1029 1462 1029 1490 1030 77 1030 104 1030 105 1030 154 1030 176 1030 208 1030 254 1030 280 1030 287 1030 302 1030 309 1030 385 1030 410 1030 456 1030 500 1030 532 1030 541 1030 565 1030 633 1030 651 1030 724 1030 747 1030 779 1030 826 1030 861 1030 878 1030 891 1030 902 1030 927 1030 957 1030 976 1030 989 1030 1013 1030 1025 1030 1030 1030 1148 1030 1207 1030 1210 1030 1279 1030 1295 1030 1310 1030 1366 1030 1380 1030 1383 1030 1489 1031 25 1031 70 1031 98 1031 108 1031 119 1031 133 1031 238 1031 256 1031 273 1031 281 1031 298 1031 301 1031 303 1031 358 1031 438 1031 442 1031 512 1031 722 1031 729 1031 731 1031 794 1031 803 1031 824 1031 1011 1031 1031 1031 1032 1031 1052 1031 1055 1031 1085 1031 1133 1031 1147 1031 1228 1031 1263 1031 1271 1031 1363 1031 1371 1031 1412 1031 1468 1031 1488 1032 70 1032 80 1032 98 1032 151 1032 163 1032 179 1032 181 1032 226 1032 245 1032 246 1032 256 1032 276 1032 281 1032 310 1032 339 1032 358 1032 412 1032 430 1032 540 1032 653 1032 664 1032 692 1032 768 1032 803 1032 894 1032 932 1032 949 1032 952 1032 963 1032 974 1032 1011 1032 1012 1032 1022 1032 1031 1032 1032 1032 1045 1032 1055 1032 1063 1032 1158 1032 1170 1032 1190 1032 1208 1032 1251 1032 1263 1032 1288 1032 1363 1032 1488 1033 11 1033 21 1033 41 1033 48 1033 70 1033 94 1033 151 1033 179 1033 245 1033 256 1033 276 1033 278 1033 339 1033 347 1033 358 1033 412 1033 419 1033 437 1033 459 1033 496 1033 513 1033 535 1033 545 1033 635 1033 664 1033 713 1033 787 1033 790 1033 810 1033 817 1033 821 1033 828 1033 834 1033 912 1033 949 1033 950 1033 952 1033 996 1033 1011 1033 1033 1033 1045 1033 1048 1033 1052 1033 1063 1033 1081 1033 1163 1033 1170 1033 1181 1033 1201 1033 1208 1033 1215 1033 1239 1033 1241 1033 1251 1033 1288 1033 1362 1033 1399 1033 1465 1033 1488 1034 36 1034 56 1034 72 1034 83 1034 101 1034 164 1034 187 1034 217 1034 223 1034 224 1034 343 1034 389 1034 391 1034 408 1034 497 1034 520 1034 524 1034 547 1034 567 1034 584 1034 592 1034 608 1034 638 1034 680 1034 784 1034 844 1034 867 1034 906 1034 908 1034 972 1034 1034 1034 1068 1034 1078 1034 1098 1034 1099 1034 1142 1034 1180 1034 1198 1034 1225 1034 1230 1034 1299 1034 1348 1034 1361 1034 1373 1034 1474 1034 1496 1034 1498 1035 26 1035 53 1035 58 1035 78 1035 82 1035 86 1035 90 1035 102 1035 191 1035 193 1035 200 1035 222 1035 233 1035 312 1035 323 1035 327 1035 332 1035 405 1035 451 1035 465 1035 536 1035 563 1035 579 1035 623 1035 626 1035 658 1035 701 1035 702 1035 734 1035 863 1035 884 1035 901 1035 934 1035 959 1035 1003 1035 1024 1035 1035 1035 1054 1035 1102 1035 1113 1035 1118 1035 1124 1035 1135 1035 1212 1035 1266 1035 1309 1035 1327 1035 1330 1035 1334 1035 1340 1035 1341 1035 1390 1035 1481 1035 1486 1036 2 1036 93 1036 95 1036 97 1036 111 1036 126 1036 153 1036 194 1036 197 1036 231 1036 247 1036 275 1036 282 1036 296 1036 311 1036 315 1036 362 1036 372 1036 384 1036 450 1036 454 1036 463 1036 481 1036 499 1036 516 1036 564 1036 614 1036 654 1036 670 1036 675 1036 796 1036 801 1036 970 1036 975 1036 1001 1036 1036 1036 1050 1036 1083 1036 1105 1036 1116 1036 1119 1036 1122 1036 1186 1036 1194 1036 1248 1036 1256 1036 1280 1036 1302 1036 1329 1036 1354 1036 1384 1036 1394 1036 1478 1037 22 1037 156 1037 159 1037 196 1037 266 1037 345 1037 390 1037 396 1037 400 1037 403 1037 448 1037 449 1037 530 1037 543 1037 548 1037 605 1037 615 1037 641 1037 691 1037 707 1037 727 1037 739 1037 763 1037 764 1037 847 1037 873 1037 920 1037 947 1037 948 1037 960 1037 994 1037 1005 1037 1037 1037 1090 1037 1126 1037 1172 1037 1252 1037 1267 1037 1287 1037 1324 1037 1325 1037 1386 1037 1436 1037 1493 1038 22 1038 156 1038 292 1038 396 1038 446 1038 508 1038 530 1038 543 1038 583 1038 604 1038 613 1038 621 1038 636 1038 669 1038 691 1038 727 1038 841 1038 854 1038 873 1038 903 1038 919 1038 920 1038 948 1038 953 1038 987 1038 994 1038 1005 1038 1038 1038 1151 1038 1267 1038 1273 1038 1287 1038 1324 1038 1326 1038 1450 1038 1454 1038 1458 1039 17 1039 24 1039 42 1039 70 1039 124 1039 268 1039 283 1039 304 1039 392 1039 395 1039 429 1039 575 1039 681 1039 695 1039 731 1039 776 1039 786 1039 810 1039 969 1039 992 1039 1007 1039 1039 1039 1155 1039 1160 1039 1201 1039 1339 1039 1468 1040 3 1040 166 1040 183 1040 461 1040 471 1040 473 1040 525 1040 527 1040 654 1040 660 1040 662 1040 668 1040 696 1040 709 1040 748 1040 804 1040 1040 1040 1143 1040 1191 1040 1254 1040 1272 1040 1285 1040 1302 1040 1303 1040 1329 1040 1405 1040 1427 1040 1469 1041 16 1041 32 1041 34 1041 40 1041 139 1041 150 1041 171 1041 177 1041 207 1041 213 1041 237 1041 248 1041 274 1041 297 1041 307 1041 317 1041 366 1041 423 1041 439 1041 453 1041 495 1041 744 1041 813 1041 833 1041 835 1041 848 1041 853 1041 859 1041 868 1041 869 1041 926 1041 936 1041 1041 1041 1053 1041 1103 1041 1110 1041 1138 1041 1237 1041 1247 1041 1262 1041 1284 1041 1296 1041 1322 1041 1347 1041 1376 1041 1381 1041 1422 1041 1482 1042 21 1042 99 1042 245 1042 246 1042 260 1042 320 1042 329 1042 337 1042 393 1042 417 1042 421 1042 445 1042 596 1042 602 1042 616 1042 653 1042 717 1042 754 1042 759 1042 762 1042 797 1042 806 1042 855 1042 918 1042 922 1042 1042 1042 1048 1042 1077 1042 1139 1042 1190 1042 1241 1042 1315 1042 1317 1042 1387 1042 1408 1042 1428 1042 1438 1042 1445 1042 1453 1042 1470 1043 142 1043 157 1043 316 1043 709 1043 819 1043 877 1043 914 1043 1043 1043 1121 1043 1430 1044 9 1044 15 1044 54 1044 73 1044 121 1044 158 1044 182 1044 205 1044 221 1044 229 1044 257 1044 262 1044 285 1044 351 1044 381 1044 462 1044 485 1044 490 1044 536 1044 618 1044 619 1044 655 1044 685 1044 698 1044 701 1044 734 1044 735 1044 802 1044 808 1044 823 1044 827 1044 837 1044 864 1044 905 1044 1044 1044 1118 1044 1144 1044 1153 1044 1183 1044 1221 1044 1258 1044 1340 1044 1343 1044 1360 1044 1382 1044 1448 1044 1452 1044 1455 1045 11 1045 21 1045 41 1045 80 1045 94 1045 163 1045 179 1045 225 1045 226 1045 245 1045 246 1045 276 1045 278 1045 310 1045 320 1045 329 1045 339 1045 406 1045 412 1045 417 1045 445 1045 459 1045 487 1045 496 1045 509 1045 535 1045 596 1045 616 1045 653 1045 664 1045 713 1045 754 1045 762 1045 768 1045 790 1045 806 1045 828 1045 912 1045 922 1045 929 1045 932 1045 949 1045 952 1045 963 1045 974 1045 1022 1045 1032 1045 1033 1045 1045 1045 1063 1045 1077 1045 1139 1045 1158 1045 1163 1045 1170 1045 1181 1045 1201 1045 1208 1045 1239 1045 1241 1045 1251 1045 1288 1045 1315 1045 1335 1045 1445 1045 1470 1046 38 1046 53 1046 58 1046 86 1046 130 1046 193 1046 206 1046 211 1046 212 1046 216 1046 286 1046 325 1046 348 1046 349 1046 405 1046 429 1046 431 1046 444 1046 451 1046 464 1046 522 1046 580 1046 646 1046 652 1046 702 1046 720 1046 767 1046 769 1046 776 1046 792 1046 897 1046 923 1046 992 1046 1003 1046 1024 1046 1046 1046 1084 1046 1135 1046 1137 1046 1219 1046 1238 1046 1249 1046 1309 1046 1316 1046 1336 1046 1459 1046 1481 1047 66 1047 96 1047 174 1047 216 1047 250 1047 261 1047 322 1047 354 1047 356 1047 394 1047 444 1047 479 1047 486 1047 711 1047 714 1047 720 1047 785 1047 792 1047 830 1047 874 1047 887 1047 942 1047 1017 1047 1047 1047 1089 1047 1165 1047 1283 1047 1332 1047 1359 1047 1414 1048 41 1048 81 1048 99 1048 127 1048 138 1048 151 1048 199 1048 245 1048 284 1048 318 1048 337 1048 382 1048 393 1048 406 1048 496 1048 501 1048 510 1048 513 1048 521 1048 535 1048 686 1048 713 1048 741 1048 772 1048 775 1048 781 1048 790 1048 797 1048 834 1048 912 1048 929 1048 946 1048 950 1048 968 1048 1000 1048 1033 1048 1042 1048 1048 1048 1070 1048 1164 1048 1190 1048 1223 1048 1226 1048 1241 1048 1251 1048 1286 1048 1304 1048 1408 1048 1410 1048 1425 1048 1445 1048 1470 1049 35 1049 48 1049 100 1049 134 1049 140 1049 313 1049 320 1049 374 1049 382 1049 393 1049 406 1049 411 1049 413 1049 498 1049 512 1049 521 1049 577 1049 635 1049 688 1049 718 1049 740 1049 741 1049 746 1049 762 1049 772 1049 781 1049 852 1049 918 1049 945 1049 961 1049 998 1049 1049 1049 1094 1049 1139 1049 1158 1049 1163 1049 1181 1049 1362 1049 1387 1049 1453 1050 2 1050 93 1050 95 1050 97 1050 114 1050 126 1050 153 1050 194 1050 197 1050 220 1050 231 1050 247 1050 282 1050 296 1050 315 1050 362 1050 407 1050 450 1050 454 1050 463 1050 499 1050 516 1050 564 1050 614 1050 654 1050 662 1050 663 1050 670 1050 721 1050 765 1050 796 1050 825 1050 970 1050 1001 1050 1036 1050 1050 1050 1083 1050 1105 1050 1122 1050 1186 1050 1194 1050 1222 1050 1242 1050 1248 1050 1256 1050 1280 1050 1329 1050 1354 1050 1384 1050 1394 1050 1395 1050 1396 1051 209 1051 214 1051 334 1051 353 1051 472 1051 476 1051 477 1051 488 1051 647 1051 677 1051 710 1051 793 1051 850 1051 1006 1051 1051 1051 1115 1051 1192 1051 1195 1052 6 1052 21 1052 25 1052 42 1052 48 1052 51 1052 70 1052 124 1052 163 1052 172 1052 256 1052 276 1052 298 1052 303 1052 339 1052 406 1052 512 1052 635 1052 695 1052 718 1052 729 1052 731 1052 757 1052 782 1052 794 1052 810 1052 828 1052 961 1052 1011 1052 1031 1052 1033 1052 1052 1052 1086 1052 1163 1052 1178 1052 1181 1052 1201 1052 1208 1052 1228 1052 1239 1052 1263 1052 1362 1052 1363 1052 1399 1052 1488 1053 4 1053 16 1053 32 1053 71 1053 177 1053 248 1053 274 1053 297 1053 331 1053 423 1053 432 1053 469 1053 519 1053 632 1053 706 1053 716 1053 738 1053 964 1053 977 1053 1041 1053 1053 1053 1073 1053 1130 1053 1274 1053 1322 1053 1328 1053 1357 1053 1367 1053 1416 1053 1423 1053 1451 1053 1480 1054 26 1054 58 1054 86 1054 191 1054 193 1054 222 1054 250 1054 312 1054 332 1054 405 1054 465 1054 533 1054 536 1054 563 1054 658 1054 701 1054 758 1054 863 1054 934 1054 938 1054 959 1054 1024 1054 1035 1054 1054 1054 1102 1054 1118 1054 1135 1054 1212 1054 1327 1054 1334 1054 1340 1054 1341 1054 1485 1054 1486 1055 25 1055 70 1055 98 1055 114 1055 151 1055 181 1055 220 1055 251 1055 256 1055 276 1055 358 1055 412 1055 663 1055 689 1055 692 1055 699 1055 721 1055 768 1055 794 1055 821 1055 825 1055 828 1055 894 1055 1011 1055 1012 1055 1031 1055 1032 1055 1055 1055 1083 1055 1263 1055 1363 1055 1385 1055 1447 1055 1488 1056 2 1056 117 1056 153 1056 201 1056 239 1056 241 1056 275 1056 282 1056 293 1056 353 1056 361 1056 372 1056 450 1056 516 1056 564 1056 719 1056 793 1056 971 1056 982 1056 1056 1056 1105 1056 1253 1056 1256 1056 1280 1056 1282 1056 1307 1056 1377 1056 1385 1056 1394 1056 1395 1056 1396 1056 1424 1056 1447 1057 30 1057 53 1057 78 1057 90 1057 102 1057 175 1057 191 1057 211 1057 212 1057 270 1057 286 1057 308 1057 349 1057 440 1057 451 1057 460 1057 511 1057 534 1057 537 1057 549 1057 563 1057 610 1057 631 1057 637 1057 761 1057 785 1057 812 1057 829 1057 884 1057 897 1057 923 1057 967 1057 980 1057 1003 1057 1057 1057 1065 1057 1084 1057 1137 1057 1141 1057 1204 1057 1219 1057 1249 1057 1334 1057 1336 1057 1390 1057 1418 1057 1459 1057 1481 1058 84 1058 95 1058 120 1058 239 1058 271 1058 293 1058 311 1058 315 1058 361 1058 515 1058 564 1058 647 1058 677 1058 719 1058 858 1058 971 1058 975 1058 1023 1058 1058 1058 1116 1058 1157 1058 1248 1058 1307 1058 1377 1058 1394 1058 1395 1058 1424 1058 1435 1059 28 1059 233 1059 268 1059 283 1059 286 1059 328 1059 348 1059 349 1059 394 1059 399 1059 440 1059 575 1059 580 1059 625 1059 631 1059 634 1059 652 1059 681 1059 786 1059 795 1059 829 1059 830 1059 865 1059 896 1059 1007 1059 1059 1059 1064 1059 1140 1059 1199 1059 1316 1059 1351 1059 1378 1059 1403 1059 1481 1059 1494 1059 1499 1060 106 1060 138 1060 151 1060 185 1060 186 1060 188 1060 199 1060 281 1060 380 1060 419 1060 430 1060 470 1060 480 1060 505 1060 510 1060 529 1060 540 1060 585 1060 597 1060 645 1060 661 1060 665 1060 674 1060 676 1060 682 1060 683 1060 686 1060 760 1060 842 1060 865 1060 890 1060 949 1060 950 1060 965 1060 986 1060 1011 1060 1019 1060 1060 1060 1152 1060 1160 1060 1197 1060 1304 1060 1305 1060 1417 1060 1425 1060 1440 1060 1465 1060 1471 1060 1487 1061 32 1061 40 1061 115 1061 139 1061 171 1061 177 1061 237 1061 307 1061 366 1061 453 1061 744 1061 833 1061 835 1061 859 1061 869 1061 926 1061 1061 1061 1103 1061 1138 1061 1237 1061 1245 1061 1247 1061 1262 1061 1276 1061 1296 1061 1322 1061 1347 1061 1376 1061 1381 1061 1406 1061 1482 1062 84 1062 88 1062 173 1062 209 1062 334 1062 420 1062 461 1062 477 1062 488 1062 489 1062 553 1062 572 1062 581 1062 659 1062 668 1062 723 1062 728 1062 737 1062 748 1062 788 1062 818 1062 1006 1062 1062 1062 1080 1062 1093 1062 1096 1062 1104 1062 1115 1062 1143 1062 1149 1062 1192 1062 1293 1062 1469 1063 11 1063 80 1063 99 1063 106 1063 151 1063 179 1063 186 1063 188 1063 225 1063 226 1063 245 1063 249 1063 276 1063 278 1063 310 1063 339 1063 347 1063 358 1063 419 1063 430 1063 437 1063 496 1063 509 1063 529 1063 545 1063 550 1063 653 1063 656 1063 664 1063 665 1063 682 1063 686 1063 713 1063 754 1063 760 1063 768 1063 787 1063 820 1063 821 1063 828 1063 845 1063 912 1063 949 1063 952 1063 986 1063 1019 1063 1022 1063 1032 1063 1033 1063 1045 1063 1063 1063 1070 1063 1152 1063 1170 1063 1175 1063 1190 1063 1197 1063 1208 1063 1251 1063 1288 1063 1304 1063 1335 1063 1465 1064 24 1064 66 1064 116 1064 137 1064 193 1064 206 1064 211 1064 212 1064 323 1064 348 1064 405 1064 425 1064 502 1064 539 1064 552 1064 580 1064 623 1064 625 1064 652 1064 678 1064 708 1064 769 1064 885 1064 896 1064 944 1064 985 1064 995 1064 1007 1064 1059 1064 1064 1064 1165 1064 1178 1064 1204 1064 1238 1064 1244 1064 1316 1064 1341 1064 1378 1064 1403 1064 1494 1065 30 1065 38 1065 53 1065 78 1065 130 1065 191 1065 212 1065 257 1065 262 1065 270 1065 308 1065 351 1065 428 1065 431 1065 451 1065 460 1065 511 1065 534 1065 549 1065 610 1065 619 1065 637 1065 702 1065 761 1065 808 1065 812 1065 827 1065 829 1065 923 1065 1057 1065 1065 1065 1084 1065 1137 1065 1219 1065 1249 1065 1336 1065 1359 1065 1415 1065 1418 1065 1459 1066 53 1066 54 1066 78 1066 82 1066 102 1066 191 1066 200 1066 205 1066 308 1066 312 1066 332 1066 451 1066 490 1066 579 1066 610 1066 658 1066 685 1066 752 1066 846 1066 863 1066 901 1066 959 1066 1066 1066 1102 1066 1113 1066 1135 1066 1183 1066 1212 1066 1221 1066 1327 1066 1340 1066 1442 1066 1463 1066 1475 1066 1486 1067 129 1067 131 1067 180 1067 192 1067 216 1067 261 1067 269 1067 340 1067 352 1067 394 1067 464 1067 575 1067 745 1067 767 1067 792 1067 887 1067 969 1067 1017 1067 1067 1067 1089 1067 1125 1067 1155 1067 1173 1067 1209 1067 1332 1067 1333 1067 1353 1067 1359 1068 72 1068 83 1068 144 1068 217 1068 223 1068 224 1068 232 1068 279 1068 295 1068 343 1068 371 1068 389 1068 391 1068 408 1068 478 1068 483 1068 592 1068 600 1068 638 1068 640 1068 648 1068 684 1068 694 1068 784 1068 807 1068 814 1068 839 1068 844 1068 906 1068 911 1068 940 1068 972 1068 978 1068 1034 1068 1068 1068 1078 1068 1099 1068 1142 1068 1180 1068 1198 1068 1216 1068 1217 1068 1229 1068 1230 1068 1277 1068 1281 1068 1299 1068 1361 1068 1373 1068 1407 1068 1441 1068 1474 1069 79 1069 147 1069 189 1069 272 1069 295 1069 344 1069 387 1069 404 1069 484 1069 491 1069 556 1069 600 1069 611 1069 694 1069 743 1069 809 1069 888 1069 910 1069 911 1069 990 1069 993 1069 999 1069 1014 1069 1027 1069 1069 1069 1075 1069 1082 1069 1277 1069 1281 1069 1355 1069 1456 1069 1484 1070 21 1070 81 1070 99 1070 106 1070 249 1070 318 1070 329 1070 337 1070 347 1070 430 1070 445 1070 480 1070 496 1070 513 1070 529 1070 535 1070 550 1070 585 1070 602 1070 665 1070 754 1070 790 1070 820 1070 834 1070 842 1070 912 1070 922 1070 1019 1070 1022 1070 1048 1070 1063 1070 1070 1070 1190 1070 1241 1070 1288 1070 1315 1070 1318 1070 1408 1070 1428 1070 1445 1070 1465 1070 1471 1071 7 1071 20 1071 31 1071 107 1071 123 1071 167 1071 170 1071 219 1071 242 1071 266 1071 292 1071 350 1071 378 1071 418 1071 446 1071 449 1071 507 1071 558 1071 570 1071 583 1071 607 1071 613 1071 621 1071 622 1071 703 1071 777 1071 791 1071 862 1071 873 1071 900 1071 903 1071 928 1071 935 1071 937 1071 1015 1071 1071 1071 1106 1071 1112 1071 1156 1071 1161 1071 1162 1071 1176 1071 1184 1071 1200 1071 1205 1071 1211 1071 1224 1071 1257 1071 1268 1071 1289 1071 1311 1071 1326 1071 1388 1071 1402 1071 1444 1071 1450 1071 1479 1071 1490 1072 27 1072 66 1072 96 1072 116 1072 127 1072 131 1072 137 1072 174 1072 228 1072 235 1072 243 1072 261 1072 263 1072 356 1072 392 1072 479 1072 486 1072 501 1072 502 1072 539 1072 552 1072 568 1072 576 1072 649 1072 678 1072 679 1072 714 1072 726 1072 746 1072 753 1072 757 1072 767 1072 775 1072 797 1072 879 1072 885 1072 909 1072 925 1072 942 1072 944 1072 946 1072 985 1072 1016 1072 1072 1072 1173 1072 1178 1072 1213 1072 1244 1072 1349 1072 1353 1072 1372 1072 1414 1073 4 1073 16 1073 71 1073 150 1073 155 1073 207 1073 248 1073 274 1073 297 1073 317 1073 331 1073 432 1073 469 1073 519 1073 588 1073 632 1073 706 1073 716 1073 738 1073 889 1073 936 1073 964 1073 977 1073 1053 1073 1073 1073 1274 1073 1322 1073 1328 1073 1357 1073 1367 1073 1416 1073 1423 1073 1451 1073 1480 1074 1 1074 100 1074 249 1074 260 1074 265 1074 417 1074 421 1074 616 1074 656 1074 672 1074 717 1074 806 1074 850 1074 855 1074 856 1074 876 1074 945 1074 1074 1074 1195 1074 1226 1074 1317 1074 1337 1074 1342 1074 1397 1074 1453 1074 1473 1075 14 1075 47 1075 52 1075 63 1075 79 1075 92 1075 125 1075 160 1075 230 1075 234 1075 240 1075 272 1075 279 1075 295 1075 373 1075 387 1075 404 1075 434 1075 441 1075 483 1075 484 1075 528 1075 569 1075 600 1075 603 1075 612 1075 624 1075 630 1075 640 1075 648 1075 690 1075 694 1075 743 1075 809 1075 882 1075 888 1075 910 1075 999 1075 1014 1075 1018 1075 1026 1075 1069 1075 1075 1075 1076 1075 1082 1075 1097 1075 1196 1075 1206 1075 1229 1075 1236 1075 1277 1075 1331 1075 1355 1075 1375 1075 1472 1075 1476 1075 1484 1076 5 1076 13 1076 14 1076 47 1076 65 1076 92 1076 160 1076 202 1076 218 1076 230 1076 234 1076 240 1076 291 1076 365 1076 373 1076 377 1076 408 1076 434 1076 441 1076 452 1076 483 1076 528 1076 569 1076 603 1076 606 1076 609 1076 612 1076 620 1076 624 1076 630 1076 648 1076 690 1076 730 1076 822 1076 882 1076 883 1076 1018 1076 1075 1076 1076 1076 1097 1076 1159 1076 1196 1076 1206 1076 1229 1076 1236 1076 1291 1076 1331 1076 1369 1076 1461 1076 1472 1076 1476 1076 1484 1077 100 1077 134 1077 260 1077 284 1077 289 1077 329 1077 337 1077 393 1077 417 1077 421 1077 445 1077 459 1077 487 1077 596 1077 616 1077 653 1077 679 1077 712 1077 717 1077 754 1077 759 1077 762 1077 806 1077 918 1077 922 1077 1042 1077 1045 1077 1077 1077 1139 1077 1226 1077 1241 1077 1315 1077 1428 1077 1438 1077 1445 1077 1470 1078 72 1078 83 1078 135 1078 217 1078 223 1078 224 1078 232 1078 253 1078 279 1078 343 1078 371 1078 377 1078 389 1078 478 1078 483 1078 497 1078 544 1078 567 1078 584 1078 592 1078 600 1078 638 1078 640 1078 648 1078 807 1078 814 1078 844 1078 860 1078 875 1078 906 1078 910 1078 940 1078 972 1078 978 1078 1034 1078 1068 1078 1078 1078 1099 1078 1142 1078 1180 1078 1198 1078 1217 1078 1356 1078 1361 1078 1373 1078 1407 1078 1441 1078 1474 1078 1496 1079 26 1079 185 1079 244 1079 251 1079 264 1079 267 1079 288 1079 355 1079 358 1079 359 1079 398 1079 436 1079 475 1079 480 1079 494 1079 546 1079 598 1079 650 1079 674 1079 676 1079 683 1079 708 1079 721 1079 758 1079 760 1079 771 1079 842 1079 895 1079 986 1079 1009 1079 1079 1079 1113 1079 1204 1079 1218 1079 1266 1079 1314 1079 1318 1079 1321 1079 1327 1079 1412 1079 1413 1079 1440 1079 1465 1079 1467 1079 1485 1080 88 1080 166 1080 168 1080 173 1080 334 1080 346 1080 409 1080 420 1080 461 1080 477 1080 489 1080 525 1080 553 1080 572 1080 659 1080 668 1080 710 1080 728 1080 737 1080 748 1080 788 1080 818 1080 899 1080 917 1080 1062 1080 1080 1080 1093 1080 1096 1080 1104 1080 1115 1080 1134 1080 1143 1080 1149 1080 1233 1080 1254 1080 1293 1080 1303 1080 1319 1080 1469 1081 6 1081 11 1081 41 1081 48 1081 94 1081 199 1081 310 1081 339 1081 382 1081 406 1081 413 1081 459 1081 510 1081 513 1081 635 1081 664 1081 713 1081 718 1081 782 1081 790 1081 810 1081 828 1081 912 1081 929 1081 1033 1081 1081 1081 1163 1081 1164 1081 1201 1081 1241 1081 1251 1081 1304 1081 1335 1081 1362 1081 1399 1082 79 1082 92 1082 125 1082 189 1082 253 1082 272 1082 279 1082 295 1082 344 1082 373 1082 387 1082 404 1082 478 1082 483 1082 484 1082 491 1082 556 1082 567 1082 591 1082 600 1082 612 1082 624 1082 640 1082 684 1082 690 1082 694 1082 743 1082 807 1082 875 1082 888 1082 910 1082 911 1082 990 1082 993 1082 1014 1082 1069 1082 1075 1082 1082 1082 1099 1082 1196 1082 1217 1082 1235 1082 1236 1082 1277 1082 1355 1082 1356 1082 1375 1082 1441 1082 1456 1082 1484 1083 0 1083 2 1083 25 1083 93 1083 98 1083 111 1083 220 1083 247 1083 362 1083 367 1083 412 1083 427 1083 450 1083 454 1083 463 1083 645 1083 663 1083 670 1083 692 1083 699 1083 794 1083 872 1083 970 1083 1012 1083 1036 1083 1050 1083 1055 1083 1083 1083 1105 1083 1133 1083 1194 1083 1197 1083 1222 1083 1253 1083 1256 1083 1260 1083 1371 1083 1385 1083 1396 1083 1398 1083 1447 1084 30 1084 38 1084 53 1084 78 1084 82 1084 102 1084 130 1084 191 1084 211 1084 212 1084 262 1084 270 1084 286 1084 308 1084 348 1084 428 1084 431 1084 451 1084 511 1084 533 1084 534 1084 549 1084 560 1084 579 1084 610 1084 626 1084 637 1084 655 1084 658 1084 685 1084 702 1084 752 1084 761 1084 778 1084 812 1084 829 1084 846 1084 863 1084 884 1084 901 1084 923 1084 983 1084 1003 1084 1024 1084 1046 1084 1057 1084 1065 1084 1084 1084 1124 1084 1131 1084 1135 1084 1137 1084 1219 1084 1249 1084 1309 1084 1336 1084 1418 1084 1459 1084 1475 1084 1481 1085 0 1085 98 1085 151 1085 185 1085 186 1085 197 1085 220 1085 238 1085 264 1085 281 1085 298 1085 301 1085 303 1085 327 1085 330 1085 338 1085 358 1085 367 1085 398 1085 442 1085 475 1085 480 1085 518 1085 546 1085 597 1085 650 1085 663 1085 674 1085 729 1085 731 1085 765 1085 771 1085 803 1085 824 1085 866 1085 892 1085 983 1085 996 1085 1011 1085 1031 1085 1085 1085 1124 1085 1145 1085 1147 1085 1263 1085 1266 1085 1271 1085 1305 1085 1330 1085 1371 1085 1400 1085 1412 1085 1413 1085 1468 1085 1488 1086 6 1086 29 1086 45 1086 51 1086 70 1086 108 1086 124 1086 186 1086 199 1086 278 1086 281 1086 303 1086 339 1086 380 1086 437 1086 438 1086 459 1086 512 1086 521 1086 545 1086 594 1086 635 1086 661 1086 676 1086 726 1086 729 1086 731 1086 810 1086 832 1086 852 1086 872 1086 880 1086 931 1086 949 1086 1052 1086 1086 1086 1163 1086 1208 1086 1239 1086 1362 1086 1399 1086 1417 1086 1468 1086 1487 1087 37 1087 122 1087 167 1087 178 1087 184 1087 319 1087 326 1087 350 1087 360 1087 376 1087 416 1087 418 1087 457 1087 503 1087 555 1087 573 1087 589 1087 593 1087 622 1087 639 1087 644 1087 703 1087 725 1087 732 1087 750 1087 756 1087 766 1087 777 1087 800 1087 886 1087 928 1087 933 1087 1010 1087 1015 1087 1020 1087 1087 1087 1107 1087 1112 1087 1166 1087 1167 1087 1185 1087 1200 1087 1205 1087 1257 1087 1268 1087 1289 1087 1311 1087 1388 1087 1457 1087 1479 1087 1483 1087 1492 1088 37 1088 49 1088 50 1088 68 1088 75 1088 141 1088 184 1088 198 1088 210 1088 294 1088 299 1088 300 1088 314 1088 333 1088 357 1088 368 1088 376 1088 433 1088 503 1088 538 1088 551 1088 559 1088 571 1088 627 1088 657 1088 671 1088 704 1088 725 1088 756 1088 766 1088 770 1088 916 1088 930 1088 1020 1088 1029 1088 1088 1088 1100 1088 1166 1088 1169 1088 1203 1088 1300 1088 1338 1088 1364 1088 1374 1088 1457 1088 1460 1088 1490 1088 1492 1088 1495 1089 38 1089 66 1089 96 1089 131 1089 137 1089 174 1089 192 1089 216 1089 261 1089 269 1089 322 1089 340 1089 356 1089 745 1089 785 1089 792 1089 851 1089 881 1089 887 1089 942 1089 1017 1089 1047 1089 1067 1089 1089 1089 1155 1089 1173 1089 1234 1089 1244 1089 1283 1089 1332 1089 1359 1089 1372 1090 22 1090 156 1090 159 1090 196 1090 266 1090 345 1090 378 1090 383 1090 396 1090 400 1090 448 1090 449 1090 507 1090 530 1090 543 1090 570 1090 604 1090 605 1090 615 1090 621 1090 669 1090 707 1090 727 1090 739 1090 791 1090 847 1090 854 1090 862 1090 873 1090 920 1090 947 1090 960 1090 994 1090 1037 1090 1090 1090 1126 1090 1172 1090 1176 1090 1267 1090 1324 1090 1325 1090 1386 1090 1434 1090 1436 1090 1444 1091 13 1091 36 1091 55 1091 83 1091 85 1091 101 1091 187 1091 218 1091 291 1091 377 1091 492 1091 497 1091 524 1091 547 1091 562 1091 608 1091 609 1091 620 1091 667 1091 730 1091 870 1091 1091 1091 1098 1091 1129 1091 1225 1091 1291 1091 1373 1091 1496 1092 17 1092 145 1092 162 1092 255 1092 322 1092 354 1092 394 1092 531 1092 561 1092 577 1092 590 1092 634 1092 711 1092 786 1092 789 1092 881 1092 887 1092 942 1092 991 1092 1092 1092 1123 1092 1125 1092 1173 1092 1213 1092 1292 1092 1414 1092 1446 1093 62 1093 88 1093 173 1093 209 1093 324 1093 420 1093 477 1093 489 1093 572 1093 581 1093 659 1093 710 1093 723 1093 728 1093 737 1093 788 1093 798 1093 818 1093 917 1093 1006 1093 1062 1093 1080 1093 1093 1093 1096 1093 1104 1093 1115 1093 1149 1093 1192 1093 1293 1093 1350 1093 1469 1094 35 1094 41 1094 100 1094 140 1094 179 1094 188 1094 199 1094 246 1094 265 1094 284 1094 310 1094 313 1094 320 1094 374 1094 382 1094 393 1094 406 1094 413 1094 487 1094 521 1094 577 1094 596 1094 688 1094 718 1094 740 1094 754 1094 762 1094 772 1094 781 1094 782 1094 790 1094 806 1094 855 1094 880 1094 894 1094 929 1094 932 1094 945 1094 963 1094 974 1094 998 1094 1004 1094 1049 1094 1094 1094 1139 1094 1158 1094 1164 1094 1223 1094 1226 1094 1251 1094 1387 1094 1438 1094 1453 1094 1473 1095 10 1095 103 1095 184 1095 210 1095 341 1095 364 1095 376 1095 542 1095 578 1095 601 1095 643 1095 666 1095 687 1095 693 1095 704 1095 750 1095 811 1095 898 1095 913 1095 915 1095 943 1095 1008 1095 1095 1095 1109 1095 1168 1095 1240 1095 1297 1095 1312 1095 1338 1095 1352 1095 1374 1095 1421 1095 1429 1095 1437 1095 1457 1095 1495 1096 88 1096 173 1096 306 1096 334 1096 420 1096 461 1096 472 1096 477 1096 489 1096 525 1096 553 1096 572 1096 659 1096 668 1096 696 1096 723 1096 728 1096 737 1096 748 1096 788 1096 804 1096 818 1096 924 1096 1062 1096 1080 1096 1093 1096 1096 1096 1104 1096 1115 1096 1143 1096 1192 1096 1254 1096 1272 1096 1285 1096 1293 1096 1303 1096 1391 1096 1405 1096 1427 1096 1469 1097 14 1097 47 1097 79 1097 160 1097 223 1097 272 1097 279 1097 295 1097 387 1097 391 1097 404 1097 408 1097 434 1097 478 1097 526 1097 600 1097 606 1097 638 1097 680 1097 694 1097 784 1097 809 1097 814 1097 822 1097 839 1097 844 1097 882 1097 888 1097 940 1097 978 1097 1075 1097 1076 1097 1097 1097 1098 1097 1142 1097 1206 1097 1216 1097 1229 1097 1236 1097 1281 1097 1370 1097 1407 1097 1441 1097 1484 1097 1498 1098 14 1098 36 1098 55 1098 56 1098 83 1098 101 1098 187 1098 218 1098 279 1098 291 1098 408 1098 441 1098 492 1098 497 1098 524 1098 526 1098 547 1098 562 1098 606 1098 608 1098 620 1098 638 1098 667 1098 680 1098 730 1098 822 1098 839 1098 867 1098 870 1098 906 1098 908 1098 972 1098 1034 1098 1091 1098 1097 1098 1098 1098 1225 1098 1299 1098 1313 1098 1348 1098 1361 1098 1373 1098 1496 1099 72 1099 83 1099 125 1099 223 1099 224 1099 272 1099 279 1099 295 1099 343 1099 371 1099 373 1099 377 1099 387 1099 389 1099 391 1099 478 1099 483 1099 544 1099 592 1099 600 1099 624 1099 638 1099 640 1099 648 1099 690 1099 694 1099 784 1099 807 1099 814 1099 844 1099 875 1099 910 1099 911 1099 940 1099 972 1099 978 1099 1014 1099 1034 1099 1068 1099 1078 1099 1082 1099 1099 1099 1142 1099 1180 1099 1196 1099 1198 1099 1217 1099 1277 1099 1299 1099 1361 1099 1373 1099 1407 1099 1441 1099 1474 1099 1484 1099 1496 1100 20 1100 31 1100 37 1100 68 1100 87 1100 170 1100 198 1100 203 1100 210 1100 294 1100 300 1100 314 1100 350 1100 357 1100 368 1100 402 1100 433 1100 538 1100 551 1100 559 1100 593 1100 627 1100 657 1100 673 1100 703 1100 736 1100 756 1100 766 1100 886 1100 916 1100 930 1100 933 1100 1029 1100 1088 1100 1100 1100 1166 1100 1169 1100 1171 1100 1188 1100 1203 1100 1211 1100 1300 1100 1402 1100 1433 1100 1460 1100 1462 1100 1490 1101 23 1101 37 1101 49 1101 75 1101 122 1101 128 1101 167 1101 178 1101 184 1101 198 1101 203 1101 219 1101 290 1101 319 1101 350 1101 360 1101 422 1101 443 1101 468 1101 503 1101 517 1101 555 1101 582 1101 593 1101 657 1101 671 1101 673 1101 693 1101 756 1101 770 1101 800 1101 805 1101 819 1101 933 1101 955 1101 1020 1101 1101 1101 1107 1101 1166 1101 1203 1101 1240 1101 1257 1101 1311 1101 1323 1101 1344 1101 1364 1101 1433 1101 1483 1102 15 1102 53 1102 54 1102 82 1102 102 1102 121 1102 191 1102 205 1102 222 1102 257 1102 312 1102 451 1102 490 1102 536 1102 563 1102 579 1102 626 1102 658 1102 685 1102 701 1102 752 1102 863 1102 934 1102 959 1102 1024 1102 1035 1102 1054 1102 1066 1102 1102 1102 1113 1102 1118 1102 1135 1102 1183 1102 1212 1102 1214 1102 1221 1102 1327 1102 1330 1102 1340 1102 1343 1102 1413 1102 1442 1102 1463 1102 1486 1103 32 1103 40 1103 115 1103 139 1103 150 1103 171 1103 177 1103 237 1103 307 1103 366 1103 453 1103 495 1103 833 1103 835 1103 848 1103 859 1103 868 1103 869 1103 926 1103 936 1103 1041 1103 1061 1103 1103 1103 1138 1103 1237 1103 1245 1103 1247 1103 1262 1103 1276 1103 1296 1103 1347 1103 1376 1103 1381 1103 1406 1103 1482 1104 62 1104 88 1104 166 1104 209 1104 324 1104 334 1104 346 1104 420 1104 426 1104 472 1104 477 1104 489 1104 553 1104 572 1104 581 1104 659 1104 696 1104 723 1104 728 1104 737 1104 788 1104 798 1104 818 1104 899 1104 917 1104 924 1104 1062 1104 1080 1104 1093 1104 1096 1104 1104 1104 1115 1104 1143 1104 1149 1104 1192 1104 1254 1104 1285 1104 1293 1104 1350 1104 1383 1104 1391 1104 1469 1105 2 1105 25 1105 97 1105 111 1105 117 1105 153 1105 194 1105 197 1105 247 1105 275 1105 282 1105 296 1105 353 1105 362 1105 372 1105 384 1105 450 1105 463 1105 499 1105 516 1105 554 1105 654 1105 662 1105 670 1105 675 1105 796 1105 970 1105 982 1105 1001 1105 1012 1105 1036 1105 1050 1105 1056 1105 1083 1105 1105 1105 1122 1105 1186 1105 1194 1105 1253 1105 1256 1105 1282 1105 1329 1105 1354 1105 1377 1105 1384 1105 1385 1105 1396 1105 1447 1105 1478 1106 7 1106 20 1106 31 1106 37 1106 75 1106 87 1106 123 1106 148 1106 167 1106 170 1106 178 1106 204 1106 219 1106 242 1106 292 1106 300 1106 333 1106 336 1106 350 1106 360 1106 378 1106 402 1106 418 1106 449 1106 583 1106 593 1106 622 1106 671 1106 673 1106 703 1106 777 1106 873 1106 886 1106 900 1106 903 1106 916 1106 928 1106 933 1106 935 1106 987 1106 1015 1106 1029 1106 1071 1106 1106 1106 1112 1106 1161 1106 1166 1106 1171 1106 1205 1106 1211 1106 1224 1106 1257 1106 1268 1106 1289 1106 1311 1106 1326 1106 1402 1106 1433 1106 1458 1106 1464 1106 1490 1107 37 1107 49 1107 68 1107 75 1107 122 1107 198 1107 203 1107 360 1107 368 1107 376 1107 443 1107 503 1107 517 1107 551 1107 555 1107 573 1107 582 1107 589 1107 657 1107 673 1107 693 1107 697 1107 725 1107 756 1107 766 1107 805 1107 836 1107 916 1107 930 1107 1020 1107 1087 1107 1101 1107 1107 1107 1166 1107 1185 1107 1203 1107 1240 1107 1246 1107 1323 1107 1352 1107 1364 1107 1374 1107 1483 1107 1492 1107 1495 1108 52 1108 63 1108 92 1108 160 1108 202 1108 230 1108 387 1108 441 1108 492 1108 569 1108 603 1108 609 1108 630 1108 642 1108 648 1108 694 1108 809 1108 870 1108 882 1108 888 1108 1028 1108 1108 1108 1265 1108 1369 1108 1472 1108 1476 1109 33 1109 61 1109 103 1109 110 1109 141 1109 169 1109 195 1109 299 1109 314 1109 341 1109 342 1109 364 1109 379 1109 447 1109 458 1109 493 1109 504 1109 542 1109 571 1109 578 1109 586 1109 643 1109 687 1109 704 1109 749 1109 811 1109 843 1109 904 1109 913 1109 915 1109 943 1109 956 1109 1095 1109 1109 1109 1168 1109 1189 1109 1269 1109 1275 1109 1297 1109 1312 1109 1338 1109 1345 1109 1352 1109 1374 1109 1420 1109 1421 1109 1437 1109 1495 1110 32 1110 34 1110 40 1110 136 1110 171 1110 207 1110 237 1110 274 1110 307 1110 423 1110 439 1110 495 1110 588 1110 744 1110 783 1110 813 1110 835 1110 848 1110 853 1110 859 1110 868 1110 869 1110 889 1110 936 1110 1041 1110 1110 1110 1138 1110 1174 1110 1237 1110 1247 1110 1255 1110 1262 1110 1276 1110 1284 1110 1296 1110 1322 1110 1347 1110 1376 1110 1422 1111 27 1111 28 1111 89 1111 127 1111 228 1111 243 1111 289 1111 470 1111 501 1111 502 1111 552 1111 679 1111 705 1111 753 1111 775 1111 789 1111 797 1111 830 1111 832 1111 879 1111 909 1111 921 1111 925 1111 931 1111 979 1111 995 1111 1111 1111 1120 1111 1286 1111 1372 1111 1392 1111 1410 1111 1414 1111 1471 1112 20 1112 31 1112 123 1112 167 1112 170 1112 178 1112 319 1112 333 1112 402 1112 416 1112 418 1112 422 1112 457 1112 555 1112 593 1112 622 1112 703 1112 736 1112 766 1112 886 1112 916 1112 933 1112 997 1112 1015 1112 1071 1112 1087 1112 1106 1112 1112 1112 1166 1112 1185 1112 1211 1112 1224 1112 1257 1112 1294 1112 1346 1112 1388 1112 1402 1112 1426 1112 1433 1112 1462 1112 1490 1112 1492 1113 26 1113 82 1113 102 1113 191 1113 200 1113 222 1113 233 1113 259 1113 312 1113 359 1113 405 1113 436 1113 465 1113 563 1113 579 1113 623 1113 658 1113 701 1113 708 1113 734 1113 752 1113 758 1113 778 1113 802 1113 863 1113 897 1113 934 1113 959 1113 1024 1113 1035 1113 1066 1113 1079 1113 1102 1113 1113 1113 1118 1113 1124 1113 1135 1113 1145 1113 1212 1113 1214 1113 1221 1113 1327 1113 1330 1113 1340 1113 1378 1113 1400 1113 1413 1113 1442 1113 1467 1113 1486 1114 39 1114 46 1114 62 1114 104 1114 105 1114 109 1114 118 1114 258 1114 309 1114 346 1114 409 1114 426 1114 489 1114 500 1114 532 1114 572 1114 710 1114 724 1114 747 1114 826 1114 899 1114 917 1114 954 1114 1025 1114 1114 1114 1128 1114 1134 1114 1149 1114 1207 1114 1233 1114 1243 1114 1270 1114 1350 1114 1368 1114 1380 1115 62 1115 88 1115 173 1115 209 1115 334 1115 420 1115 477 1115 488 1115 489 1115 572 1115 581 1115 659 1115 668 1115 728 1115 737 1115 788 1115 818 1115 917 1115 1006 1115 1051 1115 1062 1115 1080 1115 1093 1115 1096 1115 1104 1115 1115 1115 1149 1115 1192 1115 1293 1115 1469 1116 74 1116 93 1116 95 1116 111 1116 113 1116 126 1116 132 1116 194 1116 201 1116 227 1116 231 1116 241 1116 271 1116 275 1116 282 1116 306 1116 311 1116 315 1116 324 1116 362 1116 386 1116 481 1116 515 1116 516 1116 564 1116 670 1116 796 1116 801 1116 838 1116 858 1116 975 1116 1001 1116 1002 1116 1036 1116 1058 1116 1116 1116 1119 1116 1122 1116 1157 1116 1194 1116 1232 1116 1248 1116 1280 1116 1282 1116 1394 1116 1478 1117 1 1117 214 1117 236 1117 415 1117 476 1117 595 1117 793 1117 850 1117 856 1117 876 1117 981 1117 984 1117 1117 1117 1195 1117 1306 1117 1337 1117 1342 1117 1397 1118 15 1118 82 1118 90 1118 102 1118 121 1118 152 1118 222 1118 285 1118 312 1118 323 1118 327 1118 465 1118 490 1118 536 1118 655 1118 658 1118 698 1118 701 1118 702 1118 734 1118 752 1118 778 1118 802 1118 808 1118 934 1118 1003 1118 1035 1118 1044 1118 1054 1118 1102 1118 1113 1118 1118 1118 1124 1118 1135 1118 1153 1118 1212 1118 1327 1118 1330 1118 1334 1118 1340 1118 1382 1118 1442 1118 1486 1119 2 1119 74 1119 93 1119 95 1119 111 1119 113 1119 126 1119 132 1119 194 1119 201 1119 227 1119 231 1119 247 1119 282 1119 296 1119 315 1119 362 1119 384 1119 386 1119 450 1119 454 1119 463 1119 481 1119 515 1119 516 1119 564 1119 796 1119 801 1119 804 1119 838 1119 975 1119 1001 1119 1002 1119 1036 1119 1116 1119 1119 1119 1122 1119 1194 1119 1232 1119 1248 1119 1280 1119 1282 1119 1298 1119 1302 1119 1394 1119 1396 1119 1478 1120 27 1120 28 1120 89 1120 138 1120 162 1120 228 1120 321 1120 356 1120 470 1120 479 1120 498 1120 552 1120 568 1120 705 1120 714 1120 753 1120 775 1120 789 1120 797 1120 831 1120 832 1120 890 1120 909 1120 918 1120 991 1120 995 1120 1111 1120 1120 1120 1213 1120 1292 1120 1414 1120 1446 1121 142 1121 157 1121 316 1121 819 1121 877 1121 914 1121 1043 1121 1121 1121 1430 1122 2 1122 74 1122 93 1122 95 1122 111 1122 113 1122 126 1122 153 1122 194 1122 227 1122 231 1122 241 1122 247 1122 282 1122 296 1122 306 1122 315 1122 362 1122 384 1122 386 1122 450 1122 454 1122 463 1122 481 1122 515 1122 516 1122 554 1122 564 1122 566 1122 670 1122 675 1122 796 1122 801 1122 838 1122 970 1122 975 1122 982 1122 1001 1122 1002 1122 1036 1122 1050 1122 1105 1122 1116 1122 1119 1122 1122 1122 1194 1122 1248 1122 1256 1122 1280 1122 1282 1122 1298 1122 1302 1122 1394 1122 1396 1122 1478 1123 18 1123 35 1123 145 1123 146 1123 255 1123 313 1123 363 1123 411 1123 413 1123 531 1123 577 1123 634 1123 700 1123 851 1123 852 1123 881 1123 907 1123 991 1123 998 1123 1004 1123 1092 1123 1123 1123 1177 1123 1193 1123 1292 1124 0 1124 26 1124 73 1124 78 1124 82 1124 90 1124 102 1124 152 1124 200 1124 222 1124 298 1124 312 1124 327 1124 338 1124 425 1124 442 1124 451 1124 465 1124 475 1124 518 1124 536 1124 537 1124 658 1124 701 1124 702 1124 734 1124 752 1124 758 1124 761 1124 771 1124 778 1124 802 1124 884 1124 897 1124 934 1124 959 1124 967 1124 1003 1124 1035 1124 1084 1124 1085 1124 1113 1124 1118 1124 1124 1124 1135 1124 1145 1124 1212 1124 1266 1124 1271 1124 1327 1124 1330 1124 1334 1124 1382 1124 1390 1124 1400 1124 1413 1124 1442 1124 1459 1124 1481 1124 1486 1125 17 1125 96 1125 129 1125 131 1125 162 1125 172 1125 174 1125 180 1125 192 1125 255 1125 261 1125 263 1125 283 1125 304 1125 322 1125 328 1125 340 1125 352 1125 354 1125 394 1125 395 1125 399 1125 479 1125 531 1125 576 1125 590 1125 634 1125 652 1125 695 1125 711 1125 745 1125 767 1125 786 1125 792 1125 881 1125 887 1125 942 1125 969 1125 980 1125 992 1125 1067 1125 1092 1125 1125 1125 1140 1125 1155 1125 1173 1125 1209 1125 1213 1125 1244 1125 1332 1125 1351 1125 1359 1126 156 1126 159 1126 196 1126 266 1126 345 1126 383 1126 390 1126 400 1126 448 1126 543 1126 605 1126 615 1126 641 1126 707 1126 739 1126 763 1126 764 1126 847 1126 862 1126 920 1126 947 1126 960 1126 994 1126 1005 1126 1037 1126 1090 1126 1126 1126 1172 1126 1174 1126 1267 1126 1287 1126 1324 1126 1325 1126 1386 1126 1434 1126 1436 1126 1493 1127 107 1127 345 1127 507 1127 558 1127 570 1127 605 1127 607 1127 791 1127 862 1127 937 1127 947 1127 960 1127 1127 1127 1146 1127 1156 1127 1162 1127 1184 1127 1386 1127 1402 1127 1404 1128 39 1128 43 1128 46 1128 60 1128 77 1128 104 1128 109 1128 112 1128 154 1128 208 1128 258 1128 280 1128 309 1128 346 1128 369 1128 385 1128 409 1128 410 1128 500 1128 541 1128 557 1128 633 1128 724 1128 747 1128 779 1128 861 1128 878 1128 891 1128 954 1128 976 1128 989 1128 1013 1128 1025 1128 1114 1128 1128 1128 1134 1128 1148 1128 1207 1128 1210 1128 1243 1128 1279 1128 1301 1128 1310 1128 1368 1128 1380 1128 1439 1129 5 1129 12 1129 13 1129 65 1129 85 1129 165 1129 218 1129 234 1129 291 1129 365 1129 492 1129 609 1129 620 1129 642 1129 730 1129 742 1129 870 1129 939 1129 1028 1129 1091 1129 1129 1129 1159 1129 1265 1129 1291 1129 1369 1129 1461 1130 71 1130 136 1130 150 1130 207 1130 248 1130 252 1130 274 1130 297 1130 317 1130 390 1130 423 1130 432 1130 439 1130 469 1130 548 1130 588 1130 641 1130 706 1130 738 1130 813 1130 889 1130 936 1130 964 1130 977 1130 1053 1130 1130 1130 1252 1130 1255 1130 1274 1130 1284 1130 1322 1130 1328 1130 1367 1130 1416 1130 1422 1130 1480 1131 53 1131 78 1131 86 1131 191 1131 277 1131 286 1131 308 1131 349 1131 399 1131 405 1131 440 1131 444 1131 451 1131 534 1131 563 1131 579 1131 580 1131 626 1131 631 1131 720 1131 752 1131 776 1131 795 1131 829 1131 846 1131 863 1131 901 1131 923 1131 959 1131 1024 1131 1084 1131 1131 1131 1137 1131 1309 1131 1475 1131 1481 1132 3 1132 8 1132 19 1132 64 1132 97 1132 183 1132 296 1132 407 1132 473 1132 499 1132 527 1132 599 1132 614 1132 628 1132 660 1132 662 1132 709 1132 765 1132 816 1132 849 1132 951 1132 1132 1132 1227 1132 1419 1133 69 1133 119 1133 153 1133 330 1133 407 1133 427 1133 450 1133 454 1133 463 1133 516 1133 765 1133 780 1133 951 1133 1031 1133 1083 1133 1133 1133 1194 1133 1222 1133 1260 1133 1298 1133 1385 1133 1396 1134 39 1134 77 1134 104 1134 109 1134 112 1134 168 1134 215 1134 258 1134 302 1134 346 1134 409 1134 410 1134 489 1134 500 1134 917 1134 954 1134 989 1134 1025 1134 1080 1134 1114 1134 1128 1134 1134 1134 1148 1134 1207 1134 1233 1134 1301 1134 1319 1134 1350 1134 1368 1134 1405 1134 1439 1135 26 1135 53 1135 58 1135 78 1135 82 1135 86 1135 90 1135 102 1135 191 1135 193 1135 200 1135 206 1135 211 1135 222 1135 277 1135 308 1135 312 1135 323 1135 332 1135 348 1135 405 1135 425 1135 428 1135 431 1135 451 1135 465 1135 511 1135 533 1135 537 1135 549 1135 560 1135 579 1135 610 1135 626 1135 658 1135 702 1135 752 1135 761 1135 812 1135 863 1135 897 1135 901 1135 923 1135 959 1135 1003 1135 1024 1135 1035 1135 1046 1135 1054 1135 1066 1135 1084 1135 1102 1135 1113 1135 1118 1135 1124 1135 1135 1135 1212 1135 1309 1135 1327 1135 1334 1135 1336 1135 1340 1135 1459 1135 1475 1135 1481 1135 1486 1135 1494 1136 44 1136 57 1136 72 1136 76 1136 135 1136 144 1136 149 1136 224 1136 232 1136 253 1136 344 1136 370 1136 375 1136 388 1136 397 1136 424 1136 455 1136 478 1136 584 1136 591 1136 684 1136 733 1136 860 1136 893 1136 993 1136 1136 1136 1142 1136 1179 1136 1235 1136 1278 1136 1358 1136 1393 1136 1456 1137 30 1137 53 1137 86 1137 102 1137 175 1137 191 1137 193 1137 211 1137 233 1137 277 1137 308 1137 332 1137 348 1137 349 1137 399 1137 405 1137 431 1137 440 1137 444 1137 451 1137 534 1137 537 1137 563 1137 579 1137 580 1137 626 1137 631 1137 658 1137 685 1137 720 1137 812 1137 829 1137 846 1137 863 1137 884 1137 980 1137 1003 1137 1024 1137 1046 1137 1057 1137 1065 1137 1084 1137 1131 1137 1137 1137 1141 1137 1249 1137 1309 1137 1351 1137 1459 1137 1475 1137 1494 1138 32 1138 34 1138 40 1138 136 1138 139 1138 150 1138 171 1138 177 1138 207 1138 213 1138 237 1138 307 1138 317 1138 366 1138 423 1138 439 1138 453 1138 495 1138 744 1138 783 1138 813 1138 833 1138 835 1138 848 1138 853 1138 859 1138 868 1138 869 1138 889 1138 926 1138 936 1138 1041 1138 1061 1138 1103 1138 1110 1138 1138 1138 1237 1138 1247 1138 1262 1138 1276 1138 1284 1138 1296 1138 1322 1138 1347 1138 1376 1138 1381 1138 1406 1139 100 1139 134 1139 140 1139 246 1139 260 1139 310 1139 320 1139 337 1139 393 1139 406 1139 413 1139 417 1139 421 1139 445 1139 487 1139 521 1139 596 1139 616 1139 653 1139 672 1139 688 1139 717 1139 718 1139 740 1139 754 1139 762 1139 772 1139 797 1139 806 1139 855 1139 856 1139 880 1139 918 1139 922 1139 945 1139 963 1139 974 1139 998 1139 1042 1139 1045 1139 1049 1139 1077 1139 1094 1139 1139 1139 1158 1139 1181 1139 1315 1139 1387 1139 1438 1139 1445 1139 1453 1139 1470 1139 1473 1140 17 1140 129 1140 133 1140 162 1140 172 1140 180 1140 255 1140 263 1140 268 1140 283 1140 286 1140 304 1140 322 1140 328 1140 349 1140 352 1140 354 1140 394 1140 395 1140 399 1140 440 1140 464 1140 561 1140 580 1140 590 1140 625 1140 631 1140 634 1140 652 1140 681 1140 695 1140 711 1140 776 1140 786 1140 792 1140 795 1140 829 1140 865 1140 887 1140 969 1140 980 1140 992 1140 1059 1140 1125 1140 1140 1140 1199 1140 1209 1140 1316 1140 1351 1140 1446 1141 30 1141 90 1141 116 1141 174 1141 175 1141 180 1141 261 1141 270 1141 304 1141 322 1141 348 1141 349 1141 394 1141 399 1141 440 1141 444 1141 511 1141 522 1141 537 1141 580 1141 767 1141 776 1141 785 1141 792 1141 812 1141 829 1141 884 1141 897 1141 967 1141 980 1141 1003 1141 1057 1141 1137 1141 1141 1141 1199 1141 1204 1141 1209 1141 1244 1141 1261 1141 1334 1141 1359 1141 1390 1142 47 1142 72 1142 83 1142 135 1142 144 1142 149 1142 217 1142 223 1142 224 1142 232 1142 253 1142 279 1142 295 1142 305 1142 343 1142 371 1142 389 1142 397 1142 401 1142 408 1142 424 1142 455 1142 478 1142 544 1142 584 1142 591 1142 592 1142 680 1142 684 1142 733 1142 784 1142 807 1142 814 1142 822 1142 839 1142 860 1142 911 1142 940 1142 972 1142 978 1142 1014 1142 1034 1142 1068 1142 1078 1142 1097 1142 1099 1142 1136 1142 1142 1142 1180 1142 1206 1142 1216 1142 1229 1142 1235 1142 1250 1142 1281 1142 1290 1142 1356 1142 1361 1142 1370 1142 1375 1142 1407 1142 1441 1142 1474 1142 1498 1143 88 1143 166 1143 173 1143 209 1143 334 1143 420 1143 426 1143 461 1143 471 1143 472 1143 477 1143 488 1143 489 1143 553 1143 554 1143 572 1143 659 1143 675 1143 696 1143 710 1143 723 1143 728 1143 748 1143 788 1143 818 1143 899 1143 917 1143 924 1143 1040 1143 1062 1143 1080 1143 1096 1143 1104 1143 1143 1143 1191 1143 1192 1143 1254 1143 1272 1143 1285 1143 1293 1143 1303 1143 1319 1143 1391 1143 1405 1143 1427 1143 1469 1144 9 1144 15 1144 54 1144 121 1144 158 1144 182 1144 205 1144 221 1144 229 1144 262 1144 285 1144 351 1144 381 1144 462 1144 473 1144 485 1144 490 1144 599 1144 618 1144 685 1144 698 1144 735 1144 823 1144 827 1144 837 1144 849 1144 864 1144 1044 1144 1144 1144 1153 1144 1183 1144 1221 1144 1258 1144 1343 1144 1360 1144 1389 1144 1448 1144 1452 1144 1455 1144 1463 1145 0 1145 73 1145 197 1145 238 1145 264 1145 298 1145 301 1145 327 1145 330 1145 338 1145 358 1145 442 1145 475 1145 518 1145 655 1145 721 1145 765 1145 771 1145 778 1145 824 1145 866 1145 892 1145 983 1145 1011 1145 1085 1145 1113 1145 1124 1145 1145 1145 1147 1145 1212 1145 1214 1145 1222 1145 1266 1145 1271 1145 1305 1145 1330 1145 1371 1145 1400 1145 1412 1145 1413 1146 91 1146 107 1146 143 1146 326 1146 378 1146 416 1146 418 1146 507 1146 508 1146 558 1146 570 1146 607 1146 617 1146 636 1146 644 1146 732 1146 777 1146 791 1146 800 1146 854 1146 937 1146 958 1146 962 1146 997 1146 1010 1146 1015 1146 1127 1146 1146 1146 1154 1146 1162 1146 1167 1146 1200 1146 1205 1146 1268 1146 1294 1146 1346 1146 1431 1146 1444 1146 1479 1147 114 1147 197 1147 220 1147 238 1147 264 1147 281 1147 298 1147 301 1147 303 1147 327 1147 330 1147 338 1147 358 1147 442 1147 465 1147 480 1147 518 1147 598 1147 674 1147 722 1147 765 1147 803 1147 824 1147 866 1147 892 1147 996 1147 1011 1147 1031 1147 1085 1147 1145 1147 1147 1147 1218 1147 1228 1147 1263 1147 1266 1147 1271 1147 1305 1147 1371 1147 1400 1147 1412 1148 39 1148 60 1148 77 1148 109 1148 112 1148 154 1148 208 1148 215 1148 254 1148 258 1148 280 1148 346 1148 409 1148 410 1148 633 1148 724 1148 747 1148 861 1148 878 1148 891 1148 902 1148 954 1148 976 1148 989 1148 1013 1148 1025 1148 1030 1148 1128 1148 1134 1148 1148 1148 1207 1148 1210 1148 1233 1148 1301 1148 1310 1148 1319 1148 1368 1148 1439 1149 62 1149 105 1149 209 1149 254 1149 346 1149 426 1149 477 1149 489 1149 553 1149 572 1149 581 1149 659 1149 710 1149 723 1149 728 1149 737 1149 788 1149 818 1149 826 1149 899 1149 917 1149 1006 1149 1062 1149 1080 1149 1093 1149 1104 1149 1114 1149 1115 1149 1149 1149 1220 1149 1270 1149 1293 1149 1350 1149 1383 1150 43 1150 46 1150 60 1150 118 1150 154 1150 176 1150 280 1150 287 1150 369 1150 385 1150 456 1150 541 1150 557 1150 565 1150 651 1150 724 1150 747 1150 779 1150 861 1150 891 1150 902 1150 927 1150 957 1150 976 1150 1013 1150 1150 1150 1182 1150 1210 1150 1243 1150 1264 1150 1279 1150 1295 1150 1366 1150 1489 1151 91 1151 143 1151 396 1151 446 1151 508 1151 604 1151 613 1151 636 1151 644 1151 669 1151 691 1151 727 1151 841 1151 854 1151 903 1151 919 1151 937 1151 953 1151 962 1151 987 1151 1010 1151 1038 1151 1151 1151 1273 1151 1431 1151 1450 1151 1454 1152 41 1152 45 1152 106 1152 151 1152 179 1152 186 1152 188 1152 199 1152 225 1152 245 1152 249 1152 278 1152 284 1152 339 1152 380 1152 419 1152 430 1152 437 1152 459 1152 496 1152 509 1152 510 1152 545 1152 602 1152 661 1152 665 1152 682 1152 686 1152 760 1152 787 1152 790 1152 820 1152 845 1152 929 1152 949 1152 952 1152 965 1152 1022 1152 1060 1152 1063 1152 1152 1152 1190 1152 1223 1152 1251 1152 1304 1152 1408 1152 1417 1152 1487 1153 9 1153 15 1153 54 1153 73 1153 121 1153 158 1153 182 1153 205 1153 221 1153 229 1153 285 1153 351 1153 381 1153 462 1153 485 1153 490 1153 536 1153 618 1153 619 1153 685 1153 698 1153 701 1153 735 1153 823 1153 827 1153 837 1153 864 1153 1044 1153 1118 1153 1144 1153 1153 1153 1183 1153 1221 1153 1258 1153 1343 1153 1382 1153 1389 1153 1442 1153 1448 1153 1452 1153 1463 1154 91 1154 123 1154 143 1154 167 1154 178 1154 219 1154 326 1154 350 1154 378 1154 416 1154 418 1154 422 1154 508 1154 593 1154 617 1154 621 1154 622 1154 636 1154 644 1154 732 1154 777 1154 900 1154 928 1154 935 1154 958 1154 962 1154 997 1154 1010 1154 1015 1154 1146 1154 1154 1154 1176 1154 1200 1154 1205 1154 1211 1154 1257 1154 1268 1154 1289 1154 1294 1154 1311 1154 1326 1154 1388 1154 1426 1154 1431 1154 1479 1155 42 1155 129 1155 131 1155 145 1155 172 1155 180 1155 192 1155 255 1155 261 1155 269 1155 340 1155 352 1155 394 1155 395 1155 531 1155 576 1155 590 1155 700 1155 745 1155 767 1155 769 1155 851 1155 969 1155 1039 1155 1067 1155 1089 1155 1125 1155 1155 1155 1173 1155 1178 1155 1193 1155 1209 1155 1353 1155 1466 1155 1499 1156 7 1156 107 1156 148 1156 170 1156 242 1156 292 1156 446 1156 449 1156 507 1156 558 1156 570 1156 607 1156 613 1156 763 1156 791 1156 862 1156 900 1156 937 1156 1071 1156 1127 1156 1156 1156 1161 1156 1162 1156 1176 1156 1184 1156 1224 1156 1402 1156 1404 1156 1431 1156 1444 1156 1450 1156 1464 1157 74 1157 84 1157 93 1157 95 1157 120 1157 194 1157 201 1157 239 1157 241 1157 271 1157 293 1157 306 1157 311 1157 315 1157 488 1157 515 1157 554 1157 564 1157 647 1157 675 1157 677 1157 719 1157 858 1157 971 1157 975 1157 1001 1157 1023 1157 1058 1157 1116 1157 1157 1157 1192 1157 1248 1157 1307 1157 1329 1157 1354 1157 1377 1157 1394 1157 1424 1157 1435 1158 35 1158 81 1158 94 1158 100 1158 140 1158 179 1158 226 1158 245 1158 246 1158 265 1158 276 1158 284 1158 310 1158 313 1158 320 1158 321 1158 374 1158 382 1158 393 1158 406 1158 417 1158 445 1158 487 1158 540 1158 596 1158 616 1158 664 1158 688 1158 713 1158 718 1158 740 1158 754 1158 762 1158 772 1158 781 1158 782 1158 790 1158 806 1158 880 1158 894 1158 929 1158 932 1158 945 1158 952 1158 963 1158 974 1158 998 1158 1022 1158 1032 1158 1045 1158 1049 1158 1094 1158 1139 1158 1158 1158 1181 1158 1201 1158 1223 1158 1251 1158 1335 1158 1387 1158 1453 1159 5 1159 12 1159 13 1159 14 1159 65 1159 85 1159 92 1159 160 1159 165 1159 218 1159 234 1159 240 1159 291 1159 365 1159 377 1159 434 1159 441 1159 452 1159 492 1159 528 1159 544 1159 603 1159 606 1159 609 1159 612 1159 624 1159 630 1159 642 1159 648 1159 730 1159 742 1159 882 1159 883 1159 939 1159 1028 1159 1076 1159 1129 1159 1159 1159 1196 1159 1236 1159 1265 1159 1291 1159 1369 1159 1461 1160 6 1160 28 1160 42 1160 45 1160 89 1160 124 1160 127 1160 263 1160 268 1160 380 1160 392 1160 470 1160 501 1160 502 1160 505 1160 540 1160 575 1160 576 1160 649 1160 678 1160 681 1160 686 1160 689 1160 722 1160 753 1160 757 1160 775 1160 786 1160 810 1160 830 1160 831 1160 865 1160 896 1160 921 1160 931 1160 950 1160 965 1160 968 1160 986 1160 992 1160 995 1160 1007 1160 1009 1160 1039 1160 1060 1160 1160 1160 1201 1160 1349 1160 1425 1160 1446 1160 1449 1161 7 1161 20 1161 31 1161 37 1161 148 1161 167 1161 170 1161 204 1161 219 1161 242 1161 292 1161 336 1161 350 1161 360 1161 416 1161 418 1161 446 1161 558 1161 593 1161 607 1161 613 1161 639 1161 644 1161 671 1161 703 1161 777 1161 886 1161 900 1161 928 1161 987 1161 1015 1161 1071 1161 1106 1161 1156 1161 1161 1161 1171 1161 1184 1161 1200 1161 1205 1161 1211 1161 1224 1161 1257 1161 1268 1161 1273 1161 1289 1161 1311 1161 1326 1161 1346 1161 1388 1161 1402 1161 1404 1161 1426 1161 1431 1161 1450 1161 1464 1161 1479 1161 1490 1162 22 1162 107 1162 143 1162 266 1162 378 1162 449 1162 507 1162 543 1162 558 1162 570 1162 607 1162 621 1162 791 1162 854 1162 862 1162 873 1162 900 1162 935 1162 937 1162 1071 1162 1127 1162 1146 1162 1156 1162 1162 1162 1176 1162 1184 1162 1224 1162 1289 1162 1294 1162 1386 1162 1444 1162 1464 1163 6 1163 42 1163 48 1163 94 1163 108 1163 163 1163 256 1163 278 1163 303 1163 310 1163 320 1163 339 1163 437 1163 512 1163 521 1163 523 1163 545 1163 635 1163 664 1163 688 1163 713 1163 718 1163 740 1163 757 1163 782 1163 810 1163 852 1163 880 1163 961 1163 1033 1163 1045 1163 1049 1163 1052 1163 1081 1163 1086 1163 1163 1163 1181 1163 1201 1163 1208 1163 1239 1163 1335 1163 1362 1163 1399 1164 35 1164 41 1164 45 1164 199 1164 284 1164 313 1164 363 1164 374 1164 380 1164 382 1164 411 1164 413 1164 521 1164 594 1164 695 1164 726 1164 741 1164 772 1164 781 1164 782 1164 790 1164 929 1164 1048 1164 1081 1164 1094 1164 1164 1164 1223 1164 1399 1165 66 1165 86 1165 96 1165 116 1165 193 1165 206 1165 211 1165 250 1165 323 1165 356 1165 425 1165 444 1165 502 1165 539 1165 625 1165 678 1165 830 1165 879 1165 887 1165 938 1165 942 1165 985 1165 1047 1165 1064 1165 1165 1165 1204 1165 1244 1165 1283 1165 1332 1165 1341 1166 20 1166 23 1166 31 1166 37 1166 49 1166 75 1166 123 1166 128 1166 167 1166 170 1166 178 1166 184 1166 198 1166 203 1166 219 1166 290 1166 319 1166 350 1166 357 1166 360 1166 376 1166 402 1166 416 1166 422 1166 443 1166 457 1166 503 1166 517 1166 551 1166 555 1166 559 1166 582 1166 589 1166 593 1166 622 1166 627 1166 657 1166 671 1166 673 1166 703 1166 725 1166 756 1166 766 1166 770 1166 800 1166 805 1166 886 1166 898 1166 916 1166 928 1166 933 1166 1020 1166 1087 1166 1088 1166 1100 1166 1101 1166 1106 1166 1107 1166 1112 1166 1166 1166 1171 1166 1185 1166 1200 1166 1203 1166 1205 1166 1211 1166 1257 1166 1311 1166 1388 1166 1429 1166 1433 1166 1457 1166 1483 1166 1490 1166 1492 1167 91 1167 143 1167 167 1167 219 1167 326 1167 350 1167 360 1167 416 1167 418 1167 446 1167 508 1167 555 1167 574 1167 589 1167 636 1167 639 1167 644 1167 732 1167 777 1167 800 1167 886 1167 928 1167 933 1167 953 1167 958 1167 987 1167 1010 1167 1087 1167 1146 1167 1167 1167 1185 1167 1200 1167 1205 1167 1211 1167 1257 1167 1268 1167 1273 1167 1311 1167 1346 1167 1388 1167 1431 1167 1479 1168 10 1168 103 1168 141 1168 195 1168 299 1168 341 1168 342 1168 364 1168 379 1168 447 1168 504 1168 542 1168 578 1168 582 1168 643 1168 666 1168 687 1168 693 1168 697 1168 704 1168 749 1168 811 1168 898 1168 913 1168 915 1168 943 1168 1008 1168 1095 1168 1109 1168 1168 1168 1240 1168 1246 1168 1269 1168 1275 1168 1297 1168 1312 1168 1352 1168 1374 1168 1420 1168 1421 1168 1437 1168 1495 1169 37 1169 87 1169 203 1169 204 1169 292 1169 294 1169 300 1169 403 1169 559 1169 574 1169 671 1169 819 1169 836 1169 930 1169 953 1169 987 1169 1029 1169 1088 1169 1100 1169 1169 1169 1171 1169 1188 1169 1203 1169 1273 1169 1300 1169 1379 1169 1458 1169 1460 1169 1490 1170 11 1170 21 1170 80 1170 94 1170 114 1170 163 1170 179 1170 225 1170 226 1170 245 1170 249 1170 276 1170 310 1170 339 1170 347 1170 412 1170 445 1170 467 1170 509 1170 653 1170 656 1170 664 1170 712 1170 713 1170 754 1170 768 1170 787 1170 821 1170 825 1170 845 1170 912 1170 949 1170 952 1170 966 1170 1012 1170 1022 1170 1032 1170 1033 1170 1045 1170 1063 1170 1170 1170 1175 1170 1190 1170 1288 1170 1308 1170 1335 1171 7 1171 20 1171 31 1171 37 1171 87 1171 148 1171 167 1171 170 1171 178 1171 203 1171 204 1171 219 1171 242 1171 292 1171 300 1171 333 1171 336 1171 350 1171 360 1171 416 1171 418 1171 443 1171 593 1171 613 1171 644 1171 671 1171 703 1171 756 1171 777 1171 805 1171 819 1171 886 1171 900 1171 916 1171 928 1171 987 1171 1015 1171 1029 1171 1100 1171 1106 1171 1161 1171 1166 1171 1169 1171 1171 1171 1205 1171 1211 1171 1257 1171 1268 1171 1273 1171 1289 1171 1294 1171 1311 1171 1326 1171 1402 1171 1426 1171 1431 1171 1464 1171 1490 1172 159 1172 196 1172 252 1172 345 1172 383 1172 390 1172 400 1172 448 1172 605 1172 615 1172 641 1172 707 1172 739 1172 764 1172 847 1172 920 1172 947 1172 960 1172 1037 1172 1090 1172 1126 1172 1172 1172 1174 1172 1252 1172 1267 1172 1325 1172 1386 1172 1434 1172 1436 1173 66 1173 96 1173 124 1173 129 1173 131 1173 145 1173 180 1173 261 1173 263 1173 322 1173 356 1173 392 1173 394 1173 479 1173 486 1173 531 1173 539 1173 576 1173 634 1173 649 1173 714 1173 726 1173 741 1173 746 1173 757 1173 786 1173 797 1173 881 1173 942 1173 944 1173 946 1173 969 1173 991 1173 992 1173 1067 1173 1072 1173 1089 1173 1092 1173 1125 1173 1155 1173 1173 1173 1178 1173 1209 1173 1213 1173 1244 1173 1292 1173 1353 1173 1372 1174 34 1174 136 1174 159 1174 196 1174 252 1174 383 1174 390 1174 400 1174 439 1174 448 1174 495 1174 543 1174 588 1174 615 1174 641 1174 764 1174 783 1174 813 1174 847 1174 868 1174 947 1174 1110 1174 1126 1174 1172 1174 1174 1174 1252 1174 1255 1174 1284 1174 1287 1174 1325 1174 1386 1174 1422 1174 1434 1174 1436 1174 1493 1175 80 1175 114 1175 181 1175 225 1175 226 1175 249 1175 329 1175 347 1175 430 1175 467 1175 509 1175 602 1175 653 1175 656 1175 664 1175 665 1175 692 1175 712 1175 820 1175 825 1175 845 1175 966 1175 1019 1175 1063 1175 1170 1175 1175 1175 1288 1175 1308 1175 1317 1175 1428 1176 22 1176 107 1176 143 1176 156 1176 266 1176 378 1176 446 1176 449 1176 507 1176 530 1176 543 1176 558 1176 570 1176 604 1176 607 1176 613 1176 617 1176 621 1176 739 1176 791 1176 854 1176 862 1176 873 1176 900 1176 903 1176 920 1176 935 1176 937 1176 948 1176 962 1176 994 1176 1071 1176 1090 1176 1154 1176 1156 1176 1162 1176 1176 1176 1184 1176 1224 1176 1289 1176 1294 1176 1324 1176 1326 1176 1386 1176 1444 1176 1464 1177 18 1177 146 1177 246 1177 313 1177 320 1177 363 1177 512 1177 688 1177 700 1177 740 1177 851 1177 852 1177 856 1177 876 1177 907 1177 945 1177 974 1177 998 1177 1004 1177 1123 1177 1177 1177 1193 1177 1306 1177 1387 1177 1453 1177 1466 1177 1473 1178 24 1178 116 1178 124 1178 129 1178 131 1178 137 1178 145 1178 172 1178 180 1178 235 1178 261 1178 269 1178 323 1178 325 1178 340 1178 356 1178 486 1178 522 1178 539 1178 576 1178 731 1178 745 1178 767 1178 769 1178 771 1178 885 1178 944 1178 983 1178 985 1178 1052 1178 1064 1178 1072 1178 1155 1178 1173 1178 1178 1178 1244 1178 1261 1178 1333 1178 1339 1178 1353 1178 1403 1178 1468 1179 56 1179 57 1179 72 1179 76 1179 135 1179 144 1179 149 1179 164 1179 232 1179 343 1179 370 1179 388 1179 397 1179 401 1179 424 1179 455 1179 520 1179 584 1179 592 1179 611 1179 638 1179 733 1179 860 1179 893 1179 906 1179 940 1179 972 1179 1136 1179 1179 1179 1198 1179 1230 1179 1235 1179 1358 1179 1393 1180 55 1180 72 1180 83 1180 135 1180 164 1180 223 1180 224 1180 279 1180 305 1180 343 1180 371 1180 387 1180 389 1180 391 1180 408 1180 441 1180 478 1180 483 1180 520 1180 547 1180 556 1180 592 1180 600 1180 638 1180 640 1180 648 1180 680 1180 690 1180 694 1180 784 1180 814 1180 844 1180 906 1180 910 1180 911 1180 940 1180 972 1180 978 1180 1014 1180 1034 1180 1068 1180 1078 1180 1099 1180 1142 1180 1180 1180 1198 1180 1206 1180 1217 1180 1230 1180 1277 1180 1299 1180 1361 1180 1370 1180 1407 1180 1441 1180 1474 1180 1496 1181 21 1181 48 1181 94 1181 100 1181 140 1181 163 1181 179 1181 226 1181 246 1181 276 1181 310 1181 320 1181 339 1181 393 1181 406 1181 413 1181 417 1181 496 1181 521 1181 596 1181 653 1181 664 1181 688 1181 712 1181 713 1181 718 1181 740 1181 746 1181 754 1181 762 1181 772 1181 781 1181 806 1181 810 1181 880 1181 952 1181 961 1181 963 1181 974 1181 1033 1181 1045 1181 1049 1181 1052 1181 1139 1181 1158 1181 1163 1181 1181 1181 1201 1181 1208 1181 1239 1181 1251 1181 1335 1181 1362 1181 1363 1181 1387 1181 1453 1182 43 1182 46 1182 118 1182 176 1182 236 1182 258 1182 309 1182 369 1182 500 1182 532 1182 557 1182 565 1182 595 1182 651 1182 724 1182 747 1182 779 1182 902 1182 927 1182 957 1182 981 1182 984 1182 1150 1182 1182 1182 1220 1182 1243 1182 1264 1182 1270 1182 1279 1182 1366 1182 1368 1182 1380 1182 1489 1183 9 1183 15 1183 53 1183 54 1183 78 1183 82 1183 102 1183 121 1183 130 1183 158 1183 182 1183 191 1183 205 1183 221 1183 229 1183 257 1183 262 1183 285 1183 308 1183 351 1183 428 1183 451 1183 462 1183 485 1183 490 1183 511 1183 533 1183 536 1183 579 1183 610 1183 618 1183 619 1183 685 1183 698 1183 701 1183 752 1183 761 1183 812 1183 823 1183 827 1183 837 1183 863 1183 864 1183 901 1183 905 1183 1003 1183 1044 1183 1066 1183 1102 1183 1144 1183 1153 1183 1183 1183 1212 1183 1221 1183 1258 1183 1340 1183 1343 1183 1360 1183 1448 1183 1452 1183 1459 1184 7 1184 20 1184 31 1184 87 1184 107 1184 148 1184 170 1184 242 1184 292 1184 333 1184 336 1184 378 1184 403 1184 449 1184 507 1184 548 1184 558 1184 607 1184 763 1184 791 1184 862 1184 873 1184 900 1184 960 1184 1071 1184 1127 1184 1156 1184 1161 1184 1162 1184 1176 1184 1184 1184 1224 1184 1402 1184 1404 1184 1444 1184 1450 1184 1464 1185 23 1185 37 1185 122 1185 167 1185 178 1185 184 1185 319 1185 350 1185 360 1185 376 1185 422 1185 443 1185 457 1185 503 1185 555 1185 573 1185 589 1185 593 1185 622 1185 627 1185 639 1185 657 1185 703 1185 725 1185 750 1185 756 1185 766 1185 777 1185 800 1185 805 1185 886 1185 898 1185 1087 1185 1107 1185 1112 1185 1166 1185 1167 1185 1185 1185 1200 1185 1205 1185 1211 1185 1257 1185 1300 1185 1311 1185 1457 1185 1479 1185 1483 1185 1492 1186 2 1186 25 1186 97 1186 111 1186 114 1186 117 1186 153 1186 194 1186 197 1186 220 1186 241 1186 247 1186 362 1186 384 1186 407 1186 450 1186 454 1186 463 1186 499 1186 516 1186 554 1186 566 1186 654 1186 663 1186 670 1186 675 1186 721 1186 780 1186 794 1186 796 1186 825 1186 951 1186 970 1186 982 1186 1001 1186 1012 1186 1036 1186 1050 1186 1105 1186 1186 1186 1222 1186 1256 1186 1260 1186 1298 1186 1302 1186 1329 1186 1384 1186 1385 1186 1396 1186 1447 1187 58 1187 90 1187 192 1187 262 1187 269 1187 323 1187 340 1187 506 1187 637 1187 785 1187 808 1187 1187 1187 1219 1187 1234 1187 1249 1187 1334 1187 1360 1187 1401 1187 1415 1188 20 1188 50 1188 71 1188 87 1188 141 1188 148 1188 203 1188 204 1188 292 1188 294 1188 300 1188 333 1188 336 1188 357 1188 403 1188 433 1188 514 1188 519 1188 538 1188 571 1188 763 1188 916 1188 977 1188 1100 1188 1169 1188 1188 1188 1224 1188 1357 1188 1367 1188 1402 1188 1404 1188 1423 1188 1458 1188 1462 1188 1490 1189 10 1189 33 1189 50 1189 61 1189 68 1189 141 1189 195 1189 210 1189 290 1189 299 1189 341 1189 342 1189 364 1189 379 1189 447 1189 493 1189 504 1189 514 1189 559 1189 571 1189 578 1189 704 1189 749 1189 904 1189 913 1189 915 1189 1109 1189 1189 1189 1269 1189 1300 1189 1312 1189 1338 1189 1374 1189 1420 1189 1437 1189 1460 1189 1495 1190 41 1190 81 1190 99 1190 106 1190 151 1190 179 1190 188 1190 199 1190 225 1190 245 1190 249 1190 278 1190 318 1190 329 1190 337 1190 339 1190 419 1190 430 1190 509 1190 510 1190 550 1190 602 1190 661 1190 665 1190 682 1190 686 1190 760 1190 768 1190 787 1190 790 1190 820 1190 922 1190 929 1190 949 1190 950 1190 952 1190 1019 1190 1022 1190 1032 1190 1042 1190 1048 1190 1063 1190 1070 1190 1152 1190 1170 1190 1190 1190 1223 1190 1241 1190 1251 1190 1288 1190 1304 1190 1408 1190 1428 1190 1445 1190 1471 1190 1487 1191 166 1191 334 1191 461 1191 471 1191 654 1191 660 1191 662 1191 668 1191 696 1191 748 1191 1040 1191 1143 1191 1191 1191 1254 1191 1272 1191 1285 1191 1302 1191 1303 1191 1308 1191 1319 1191 1329 1191 1405 1191 1427 1191 1469 1192 74 1192 84 1192 88 1192 173 1192 201 1192 209 1192 293 1192 306 1192 334 1192 420 1192 461 1192 472 1192 477 1192 488 1192 525 1192 553 1192 554 1192 572 1192 581 1192 647 1192 659 1192 668 1192 675 1192 723 1192 728 1192 737 1192 788 1192 798 1192 818 1192 924 1192 971 1192 1006 1192 1051 1192 1062 1192 1093 1192 1096 1192 1104 1192 1115 1192 1143 1192 1157 1192 1192 1192 1285 1192 1293 1192 1303 1192 1469 1193 18 1193 146 1193 192 1193 255 1193 531 1193 700 1193 851 1193 876 1193 907 1193 1004 1193 1123 1193 1155 1193 1177 1193 1193 1193 1306 1193 1466 1194 2 1194 93 1194 95 1194 111 1194 117 1194 126 1194 153 1194 194 1194 231 1194 247 1194 282 1194 296 1194 362 1194 384 1194 427 1194 450 1194 454 1194 463 1194 516 1194 564 1194 670 1194 796 1194 801 1194 838 1194 970 1194 975 1194 982 1194 1001 1194 1036 1194 1050 1194 1083 1194 1105 1194 1116 1194 1119 1194 1122 1194 1133 1194 1194 1194 1222 1194 1248 1194 1253 1194 1256 1194 1260 1194 1280 1194 1282 1194 1298 1194 1384 1194 1385 1194 1394 1194 1396 1194 1478 1195 1 1195 100 1195 214 1195 260 1195 265 1195 417 1195 421 1195 476 1195 616 1195 653 1195 672 1195 712 1195 793 1195 806 1195 850 1195 856 1195 876 1195 1051 1195 1074 1195 1117 1195 1195 1195 1306 1195 1317 1195 1337 1195 1342 1195 1387 1195 1397 1195 1438 1195 1473 1196 14 1196 47 1196 79 1196 92 1196 125 1196 160 1196 165 1196 230 1196 240 1196 272 1196 279 1196 295 1196 373 1196 387 1196 404 1196 441 1196 483 1196 484 1196 528 1196 556 1196 569 1196 600 1196 603 1196 606 1196 612 1196 624 1196 630 1196 640 1196 648 1196 690 1196 694 1196 807 1196 809 1196 844 1196 882 1196 910 1196 911 1196 999 1196 1018 1196 1075 1196 1076 1196 1082 1196 1099 1196 1159 1196 1196 1196 1236 1196 1277 1196 1375 1196 1441 1196 1472 1196 1476 1196 1484 1197 98 1197 185 1197 186 1197 278 1197 288 1197 367 1197 398 1197 419 1197 437 1197 480 1197 529 1197 546 1197 597 1197 645 1197 650 1197 663 1197 676 1197 682 1197 683 1197 699 1197 760 1197 821 1197 842 1197 845 1197 996 1197 1060 1197 1063 1197 1083 1197 1197 1197 1263 1197 1398 1197 1417 1197 1440 1197 1465 1198 56 1198 72 1198 101 1198 164 1198 217 1198 223 1198 343 1198 389 1198 391 1198 408 1198 497 1198 520 1198 524 1198 547 1198 584 1198 592 1198 638 1198 680 1198 844 1198 867 1198 906 1198 908 1198 972 1198 1034 1198 1068 1198 1078 1198 1099 1198 1179 1198 1180 1198 1198 1198 1230 1198 1299 1198 1361 1198 1441 1198 1474 1198 1496 1199 116 1199 133 1199 138 1199 244 1199 283 1199 304 1199 349 1199 355 1199 394 1199 399 1199 522 1199 575 1199 580 1199 590 1199 623 1199 652 1199 681 1199 695 1199 708 1199 795 1199 829 1199 865 1199 980 1199 992 1199 995 1199 1007 1199 1059 1199 1140 1199 1141 1199 1199 1199 1204 1199 1271 1199 1316 1199 1378 1199 1425 1199 1467 1200 49 1200 122 1200 167 1200 219 1200 319 1200 326 1200 350 1200 360 1200 416 1200 418 1200 443 1200 457 1200 508 1200 555 1200 573 1200 589 1200 622 1200 639 1200 644 1200 725 1200 732 1200 777 1200 800 1200 805 1200 886 1200 928 1200 933 1200 958 1200 997 1200 1010 1200 1015 1200 1071 1200 1087 1200 1146 1200 1154 1200 1161 1200 1166 1200 1167 1200 1185 1200 1200 1200 1205 1200 1257 1200 1268 1200 1273 1200 1311 1200 1346 1200 1388 1200 1431 1200 1479 1200 1483 1201 6 1201 21 1201 42 1201 48 1201 94 1201 124 1201 127 1201 140 1201 256 1201 276 1201 303 1201 310 1201 339 1201 374 1201 382 1201 392 1201 406 1201 413 1201 496 1201 501 1201 535 1201 540 1201 635 1201 664 1201 695 1201 713 1201 718 1201 746 1201 753 1201 757 1201 782 1201 786 1201 790 1201 810 1201 828 1201 831 1201 929 1201 961 1201 1033 1201 1039 1201 1045 1201 1052 1201 1081 1201 1158 1201 1160 1201 1163 1201 1181 1201 1201 1201 1208 1201 1241 1201 1251 1201 1349 1201 1362 1201 1363 1201 1372 1201 1399 1202 44 1202 57 1202 147 1202 344 1202 375 1202 388 1202 491 1202 799 1202 893 1202 990 1202 993 1202 1027 1202 1202 1202 1278 1202 1355 1202 1358 1202 1456 1203 20 1203 37 1203 49 1203 50 1203 68 1203 75 1203 128 1203 141 1203 198 1203 203 1203 204 1203 290 1203 294 1203 300 1203 314 1203 333 1203 357 1203 360 1203 368 1203 402 1203 433 1203 443 1203 538 1203 551 1203 555 1203 559 1203 571 1203 582 1203 657 1203 671 1203 673 1203 697 1203 703 1203 756 1203 805 1203 836 1203 916 1203 930 1203 1020 1203 1088 1203 1100 1203 1101 1203 1107 1203 1166 1203 1169 1203 1203 1203 1257 1203 1273 1203 1300 1203 1364 1203 1379 1203 1433 1203 1460 1203 1483 1203 1490 1204 26 1204 30 1204 116 1204 174 1204 175 1204 206 1204 233 1204 264 1204 267 1204 325 1204 327 1204 332 1204 355 1204 356 1204 425 1204 429 1204 444 1204 475 1204 522 1204 537 1204 539 1204 568 1204 629 1204 646 1204 708 1204 755 1204 758 1204 776 1204 817 1204 824 1204 884 1204 885 1204 897 1204 967 1204 980 1204 1007 1204 1057 1204 1064 1204 1079 1204 1141 1204 1165 1204 1199 1204 1204 1204 1244 1204 1266 1204 1316 1204 1318 1204 1339 1204 1403 1204 1468 1205 37 1205 91 1205 167 1205 178 1205 219 1205 242 1205 319 1205 326 1205 350 1205 360 1205 416 1205 418 1205 457 1205 508 1205 555 1205 589 1205 593 1205 617 1205 622 1205 639 1205 644 1205 703 1205 732 1205 777 1205 800 1205 805 1205 886 1205 900 1205 928 1205 933 1205 958 1205 997 1205 1010 1205 1015 1205 1071 1205 1087 1205 1106 1205 1146 1205 1154 1205 1161 1205 1166 1205 1167 1205 1171 1205 1185 1205 1200 1205 1205 1205 1211 1205 1257 1205 1268 1205 1273 1205 1289 1205 1311 1205 1346 1205 1388 1205 1426 1205 1431 1205 1479 1206 14 1206 47 1206 79 1206 92 1206 160 1206 223 1206 279 1206 305 1206 373 1206 387 1206 391 1206 408 1206 434 1206 441 1206 478 1206 483 1206 556 1206 567 1206 600 1206 612 1206 630 1206 638 1206 680 1206 690 1206 784 1206 807 1206 809 1206 822 1206 839 1206 844 1206 883 1206 911 1206 978 1206 1014 1206 1018 1206 1075 1206 1076 1206 1097 1206 1142 1206 1180 1206 1206 1206 1217 1206 1229 1206 1230 1206 1236 1206 1277 1206 1281 1206 1290 1206 1369 1206 1370 1206 1441 1206 1474 1206 1484 1206 1498 1207 39 1207 62 1207 77 1207 105 1207 109 1207 112 1207 208 1207 215 1207 254 1207 258 1207 280 1207 302 1207 346 1207 409 1207 410 1207 426 1207 456 1207 633 1207 724 1207 747 1207 779 1207 826 1207 861 1207 878 1207 891 1207 899 1207 917 1207 954 1207 976 1207 989 1207 1025 1207 1030 1207 1114 1207 1128 1207 1134 1207 1148 1207 1207 1207 1233 1207 1301 1207 1310 1207 1350 1207 1368 1207 1383 1207 1439 1208 6 1208 21 1208 29 1208 42 1208 48 1208 51 1208 70 1208 94 1208 98 1208 151 1208 179 1208 186 1208 245 1208 256 1208 276 1208 278 1208 281 1208 303 1208 321 1208 339 1208 358 1208 412 1208 419 1208 437 1208 496 1208 512 1208 545 1208 597 1208 635 1208 661 1208 664 1208 713 1208 718 1208 729 1208 731 1208 768 1208 782 1208 810 1208 821 1208 828 1208 832 1208 880 1208 949 1208 961 1208 1011 1208 1032 1208 1033 1208 1045 1208 1052 1208 1063 1208 1086 1208 1163 1208 1181 1208 1201 1208 1208 1208 1239 1208 1251 1208 1362 1208 1363 1208 1399 1208 1417 1208 1487 1208 1488 1209 17 1209 38 1209 96 1209 129 1209 131 1209 133 1209 162 1209 172 1209 174 1209 180 1209 192 1209 255 1209 261 1209 263 1209 304 1209 322 1209 328 1209 349 1209 352 1209 354 1209 394 1209 395 1209 399 1209 464 1209 522 1209 561 1209 576 1209 590 1209 634 1209 652 1209 695 1209 711 1209 745 1209 767 1209 786 1209 792 1209 881 1209 887 1209 944 1209 969 1209 980 1209 992 1209 1067 1209 1125 1209 1140 1209 1141 1209 1155 1209 1173 1209 1209 1209 1244 1209 1351 1209 1353 1209 1359 1210 43 1210 60 1210 77 1210 118 1210 154 1210 176 1210 208 1210 280 1210 287 1210 369 1210 385 1210 410 1210 456 1210 541 1210 557 1210 565 1210 633 1210 651 1210 724 1210 747 1210 779 1210 861 1210 878 1210 891 1210 902 1210 927 1210 957 1210 976 1210 1013 1210 1025 1210 1030 1210 1128 1210 1148 1210 1150 1210 1210 1210 1279 1210 1295 1210 1310 1210 1366 1210 1380 1210 1439 1210 1489 1211 7 1211 20 1211 31 1211 37 1211 87 1211 123 1211 148 1211 167 1211 170 1211 178 1211 204 1211 219 1211 242 1211 292 1211 326 1211 350 1211 360 1211 416 1211 418 1211 443 1211 446 1211 508 1211 555 1211 583 1211 593 1211 622 1211 644 1211 671 1211 673 1211 703 1211 756 1211 777 1211 886 1211 900 1211 903 1211 916 1211 928 1211 933 1211 935 1211 958 1211 987 1211 1015 1211 1029 1211 1071 1211 1100 1211 1106 1211 1112 1211 1154 1211 1161 1211 1166 1211 1167 1211 1171 1211 1185 1211 1205 1211 1211 1211 1257 1211 1268 1211 1273 1211 1289 1211 1311 1211 1326 1211 1402 1211 1426 1211 1431 1211 1433 1211 1458 1211 1464 1211 1490 1212 54 1212 78 1212 82 1212 102 1212 121 1212 152 1212 191 1212 200 1212 205 1212 222 1212 259 1212 312 1212 338 1212 490 1212 536 1212 563 1212 579 1212 655 1212 658 1212 685 1212 698 1212 701 1212 734 1212 752 1212 761 1212 778 1212 802 1212 863 1212 897 1212 934 1212 959 1212 1035 1212 1054 1212 1066 1212 1102 1212 1113 1212 1118 1212 1124 1212 1135 1212 1145 1212 1183 1212 1212 1212 1214 1212 1221 1212 1327 1212 1330 1212 1340 1212 1343 1212 1382 1212 1400 1212 1413 1212 1442 1212 1481 1212 1486 1213 17 1213 27 1213 66 1213 96 1213 124 1213 127 1213 131 1213 162 1213 243 1213 263 1213 289 1213 392 1213 394 1213 413 1213 479 1213 486 1213 501 1213 577 1213 634 1213 649 1213 679 1213 726 1213 741 1213 746 1213 757 1213 772 1213 775 1213 786 1213 789 1213 797 1213 830 1213 879 1213 881 1213 887 1213 942 1213 946 1213 991 1213 1016 1213 1072 1213 1092 1213 1120 1213 1125 1213 1173 1213 1213 1213 1292 1213 1332 1213 1372 1213 1410 1213 1414 1213 1446 1214 19 1214 73 1214 152 1214 205 1214 222 1214 259 1214 288 1214 312 1214 330 1214 338 1214 442 1214 465 1214 560 1214 587 1214 655 1214 734 1214 765 1214 778 1214 802 1214 866 1214 871 1214 892 1214 1102 1214 1113 1214 1145 1214 1212 1214 1214 1214 1242 1214 1327 1214 1330 1214 1340 1214 1371 1214 1382 1214 1400 1214 1413 1214 1419 1214 1442 1214 1486 1215 81 1215 151 1215 199 1215 251 1215 276 1215 318 1215 347 1215 419 1215 437 1215 470 1215 496 1215 513 1215 535 1215 545 1215 597 1215 665 1215 713 1215 715 1215 790 1215 817 1215 821 1215 828 1215 834 1215 912 1215 929 1215 952 1215 965 1215 986 1215 996 1215 1009 1215 1011 1215 1016 1215 1033 1215 1215 1215 1241 1215 1304 1215 1318 1215 1392 1215 1449 1215 1465 1215 1471 1216 76 1216 135 1216 144 1216 189 1216 217 1216 223 1216 232 1216 279 1216 295 1216 305 1216 401 1216 408 1216 452 1216 455 1216 478 1216 520 1216 526 1216 567 1216 584 1216 591 1216 611 1216 680 1216 684 1216 784 1216 814 1216 822 1216 839 1216 875 1216 940 1216 972 1216 978 1216 990 1216 1014 1216 1068 1216 1097 1216 1142 1216 1216 1216 1229 1216 1250 1216 1281 1216 1290 1216 1313 1216 1348 1216 1356 1216 1361 1216 1370 1216 1375 1216 1407 1216 1498 1217 79 1217 125 1217 189 1217 217 1217 223 1217 224 1217 253 1217 305 1217 344 1217 389 1217 483 1217 491 1217 556 1217 591 1217 592 1217 600 1217 640 1217 684 1217 807 1217 814 1217 875 1217 908 1217 910 1217 911 1217 990 1217 1014 1217 1068 1217 1078 1217 1082 1217 1099 1217 1180 1217 1206 1217 1217 1217 1230 1217 1250 1217 1277 1217 1290 1217 1355 1217 1356 1217 1370 1217 1375 1217 1441 1217 1474 1217 1484 1218 185 1218 264 1218 288 1218 359 1218 398 1218 436 1218 480 1218 546 1218 587 1218 598 1218 650 1218 654 1218 663 1218 674 1218 721 1218 758 1218 760 1218 842 1218 871 1218 895 1218 996 1218 1079 1218 1147 1218 1218 1218 1242 1218 1318 1218 1412 1218 1440 1219 30 1219 38 1219 53 1219 58 1219 90 1219 212 1219 216 1219 257 1219 262 1219 270 1219 323 1219 351 1219 428 1219 431 1219 460 1219 464 1219 506 1219 511 1219 534 1219 549 1219 610 1219 637 1219 702 1219 785 1219 792 1219 808 1219 812 1219 923 1219 980 1219 1017 1219 1046 1219 1057 1219 1065 1219 1084 1219 1187 1219 1219 1219 1234 1219 1249 1219 1334 1219 1336 1219 1359 1219 1360 1219 1415 1219 1418 1220 62 1220 105 1220 176 1220 254 1220 456 1220 500 1220 532 1220 565 1220 651 1220 826 1220 878 1220 899 1220 917 1220 1149 1220 1182 1220 1220 1220 1264 1220 1270 1220 1310 1220 1350 1220 1366 1220 1383 1220 1489 1221 9 1221 15 1221 53 1221 54 1221 73 1221 78 1221 102 1221 121 1221 130 1221 152 1221 191 1221 205 1221 259 1221 285 1221 312 1221 451 1221 485 1221 490 1221 536 1221 579 1221 618 1221 658 1221 685 1221 698 1221 752 1221 778 1221 815 1221 823 1221 827 1221 837 1221 863 1221 905 1221 959 1221 1044 1221 1066 1221 1102 1221 1113 1221 1144 1221 1153 1221 1183 1221 1212 1221 1221 1221 1258 1221 1327 1221 1330 1221 1340 1221 1343 1221 1382 1221 1442 1221 1448 1221 1452 1221 1463 1221 1486 1222 69 1222 97 1222 111 1222 119 1222 197 1222 220 1222 298 1222 330 1222 427 1222 442 1222 450 1222 454 1222 463 1222 499 1222 663 1222 721 1222 765 1222 780 1222 794 1222 866 1222 892 1222 951 1222 1050 1222 1083 1222 1133 1222 1145 1222 1186 1222 1194 1222 1222 1222 1242 1222 1256 1222 1260 1222 1371 1222 1396 1222 1412 1223 35 1223 41 1223 81 1223 99 1223 106 1223 140 1223 179 1223 188 1223 199 1223 245 1223 284 1223 313 1223 321 1223 363 1223 374 1223 382 1223 393 1223 406 1223 430 1223 487 1223 498 1223 510 1223 521 1223 540 1223 550 1223 577 1223 661 1223 718 1223 762 1223 772 1223 781 1223 782 1223 790 1223 852 1223 929 1223 949 1223 952 1223 961 1223 963 1223 1022 1223 1048 1223 1094 1223 1152 1223 1158 1223 1164 1223 1190 1223 1223 1223 1251 1223 1335 1224 7 1224 20 1224 22 1224 31 1224 87 1224 148 1224 156 1224 204 1224 266 1224 292 1224 333 1224 336 1224 378 1224 403 1224 449 1224 530 1224 543 1224 548 1224 558 1224 607 1224 621 1224 703 1224 763 1224 791 1224 862 1224 873 1224 900 1224 948 1224 960 1224 994 1224 1005 1224 1071 1224 1106 1224 1112 1224 1156 1224 1161 1224 1162 1224 1176 1224 1184 1224 1188 1224 1224 1224 1289 1224 1324 1224 1326 1224 1402 1224 1404 1224 1444 1224 1458 1224 1464 1224 1490 1225 13 1225 36 1225 55 1225 83 1225 101 1225 187 1225 218 1225 291 1225 377 1225 452 1225 492 1225 497 1225 524 1225 528 1225 544 1225 547 1225 562 1225 608 1225 620 1225 667 1225 730 1225 867 1225 870 1225 883 1225 908 1225 972 1225 1034 1225 1091 1225 1098 1225 1225 1225 1291 1225 1299 1225 1313 1225 1348 1225 1361 1225 1373 1225 1496 1226 1 1226 41 1226 81 1226 99 1226 100 1226 134 1226 199 1226 260 1226 265 1226 284 1226 337 1226 393 1226 417 1226 421 1226 487 1226 505 1226 510 1226 585 1226 596 1226 616 1226 717 1226 754 1226 762 1226 890 1226 918 1226 929 1226 988 1226 1000 1226 1048 1226 1074 1226 1077 1226 1094 1226 1226 1226 1251 1226 1317 1226 1397 1226 1445 1226 1470 1227 3 1227 8 1227 64 1227 97 1227 126 1227 153 1227 183 1227 296 1227 407 1227 454 1227 499 1227 614 1227 628 1227 660 1227 662 1227 801 1227 816 1227 838 1227 849 1227 951 1227 1002 1227 1132 1227 1227 1227 1354 1228 6 1228 25 1228 70 1228 108 1228 114 1228 119 1228 220 1228 238 1228 273 1228 298 1228 303 1228 438 1228 442 1228 518 1228 689 1228 722 1228 731 1228 780 1228 794 1228 803 1228 824 1228 1012 1228 1031 1228 1052 1228 1147 1228 1228 1228 1260 1228 1263 1228 1363 1228 1371 1228 1399 1228 1466 1228 1488 1229 14 1229 47 1229 79 1229 135 1229 160 1229 232 1229 253 1229 279 1229 295 1229 343 1229 389 1229 408 1229 434 1229 478 1229 526 1229 567 1229 584 1229 612 1229 638 1229 680 1229 784 1229 814 1229 822 1229 839 1229 940 1229 978 1229 1014 1229 1018 1229 1068 1229 1075 1229 1076 1229 1097 1229 1142 1229 1206 1229 1216 1229 1229 1229 1236 1229 1250 1229 1281 1229 1290 1229 1356 1229 1370 1229 1375 1229 1407 1229 1441 1229 1498 1230 72 1230 79 1230 135 1230 144 1230 149 1230 164 1230 189 1230 223 1230 224 1230 232 1230 343 1230 387 1230 389 1230 391 1230 397 1230 401 1230 424 1230 455 1230 484 1230 491 1230 520 1230 556 1230 592 1230 600 1230 611 1230 638 1230 680 1230 784 1230 844 1230 906 1230 910 1230 911 1230 978 1230 1014 1230 1034 1230 1068 1230 1179 1230 1180 1230 1198 1230 1206 1230 1217 1230 1230 1230 1235 1230 1277 1230 1370 1230 1393 1230 1441 1230 1474 1230 1484 1231 59 1231 67 1231 161 1231 190 1231 335 1231 414 1231 435 1231 774 1231 840 1231 857 1231 1021 1231 1231 1231 1320 1231 1365 1231 1409 1231 1432 1231 1443 1231 1454 1231 1477 1231 1491 1231 1497 1232 74 1232 95 1232 113 1232 132 1232 194 1232 201 1232 227 1232 231 1232 241 1232 275 1232 293 1232 306 1232 324 1232 353 1232 386 1232 466 1232 474 1232 481 1232 515 1232 554 1232 566 1232 581 1232 798 1232 971 1232 975 1232 1116 1232 1119 1232 1232 1232 1259 1232 1280 1232 1391 1233 39 1233 112 1233 166 1233 168 1233 215 1233 258 1233 302 1233 346 1233 409 1233 426 1233 477 1233 489 1233 572 1233 710 1233 899 1233 917 1233 954 1233 989 1233 1080 1233 1114 1233 1134 1233 1148 1233 1207 1233 1233 1233 1301 1233 1319 1233 1368 1233 1405 1233 1469 1234 38 1234 58 1234 137 1234 193 1234 212 1234 216 1234 269 1234 323 1234 428 1234 464 1234 534 1234 637 1234 720 1234 785 1234 792 1234 874 1234 1017 1234 1089 1234 1187 1234 1219 1234 1234 1234 1238 1234 1249 1234 1336 1234 1359 1234 1459 1235 44 1235 57 1235 72 1235 76 1235 135 1235 144 1235 147 1235 149 1235 189 1235 217 1235 232 1235 253 1235 305 1235 344 1235 370 1235 388 1235 397 1235 401 1235 424 1235 455 1235 478 1235 491 1235 556 1235 591 1235 611 1235 684 1235 733 1235 807 1235 860 1235 875 1235 893 1235 978 1235 990 1235 993 1235 1082 1235 1136 1235 1142 1235 1179 1235 1230 1235 1235 1235 1250 1235 1278 1235 1290 1235 1358 1235 1375 1235 1393 1235 1456 1236 13 1236 14 1236 79 1236 92 1236 160 1236 279 1236 295 1236 371 1236 373 1236 408 1236 434 1236 441 1236 452 1236 483 1236 484 1236 526 1236 528 1236 544 1236 567 1236 600 1236 603 1236 606 1236 612 1236 624 1236 630 1236 640 1236 684 1236 690 1236 807 1236 822 1236 839 1236 867 1236 875 1236 882 1236 883 1236 910 1236 1018 1236 1075 1236 1076 1236 1082 1236 1097 1236 1159 1236 1196 1236 1206 1236 1229 1236 1236 1236 1250 1236 1277 1236 1291 1236 1313 1236 1348 1236 1355 1236 1356 1236 1361 1236 1369 1236 1375 1237 32 1237 34 1237 40 1237 139 1237 150 1237 171 1237 177 1237 207 1237 213 1237 237 1237 248 1237 274 1237 307 1237 317 1237 366 1237 423 1237 439 1237 453 1237 495 1237 744 1237 813 1237 835 1237 848 1237 853 1237 859 1237 868 1237 869 1237 926 1237 936 1237 1041 1237 1061 1237 1103 1237 1110 1237 1138 1237 1237 1237 1245 1237 1247 1237 1262 1237 1276 1237 1284 1237 1296 1237 1322 1237 1347 1237 1376 1237 1381 1237 1482 1238 24 1238 38 1238 58 1238 66 1238 78 1238 137 1238 193 1238 206 1238 211 1238 212 1238 216 1238 286 1238 322 1238 323 1238 328 1238 348 1238 349 1238 354 1238 394 1238 399 1238 428 1238 431 1238 440 1238 444 1238 451 1238 464 1238 534 1238 580 1238 625 1238 631 1238 637 1238 652 1238 720 1238 769 1238 785 1238 792 1238 829 1238 874 1238 923 1238 1017 1238 1046 1238 1064 1238 1234 1238 1238 1238 1249 1238 1332 1238 1336 1238 1351 1238 1390 1238 1418 1238 1459 1238 1481 1239 21 1239 25 1239 29 1239 48 1239 51 1239 70 1239 94 1239 163 1239 179 1239 246 1239 256 1239 278 1239 303 1239 310 1239 320 1239 339 1239 437 1239 512 1239 521 1239 523 1239 545 1239 635 1239 664 1239 692 1239 729 1239 731 1239 740 1239 872 1239 880 1239 894 1239 932 1239 963 1239 1004 1239 1012 1239 1033 1239 1045 1239 1052 1239 1086 1239 1163 1239 1181 1239 1208 1239 1239 1239 1362 1239 1363 1239 1399 1239 1417 1239 1487 1240 10 1240 23 1240 122 1240 195 1240 468 1240 517 1240 542 1240 582 1240 643 1240 666 1240 693 1240 697 1240 750 1240 811 1240 898 1240 915 1240 1008 1240 1095 1240 1101 1240 1107 1240 1168 1240 1240 1240 1246 1240 1275 1240 1323 1240 1344 1240 1352 1240 1374 1240 1495 1241 81 1241 94 1241 106 1241 127 1241 134 1241 228 1241 245 1241 249 1241 276 1241 329 1241 337 1241 339 1241 347 1241 393 1241 417 1241 445 1241 459 1241 487 1241 496 1241 510 1241 513 1241 535 1241 585 1241 596 1241 602 1241 713 1241 754 1241 762 1241 790 1241 820 1241 834 1241 912 1241 918 1241 922 1241 946 1241 968 1241 1000 1241 1033 1241 1042 1241 1045 1241 1048 1241 1070 1241 1077 1241 1081 1241 1190 1241 1201 1241 1215 1241 1241 1241 1251 1241 1286 1241 1315 1241 1392 1241 1408 1241 1428 1241 1445 1241 1470 1241 1471 1242 19 1242 97 1242 197 1242 288 1242 407 1242 499 1242 587 1242 598 1242 614 1242 628 1242 654 1242 765 1242 802 1242 816 1242 871 1242 892 1242 951 1242 1050 1242 1214 1242 1218 1242 1222 1242 1242 1242 1384 1242 1412 1242 1419 1242 1442 1243 43 1243 46 1243 104 1243 105 1243 109 1243 118 1243 176 1243 287 1243 309 1243 369 1243 385 1243 456 1243 500 1243 532 1243 541 1243 557 1243 565 1243 633 1243 651 1243 724 1243 747 1243 779 1243 826 1243 861 1243 902 1243 927 1243 957 1243 1013 1243 1025 1243 1114 1243 1128 1243 1150 1243 1182 1243 1243 1243 1270 1243 1279 1243 1366 1243 1368 1243 1380 1243 1489 1244 24 1244 66 1244 96 1244 116 1244 129 1244 131 1244 137 1244 145 1244 174 1244 206 1244 235 1244 261 1244 322 1244 323 1244 325 1244 356 1244 394 1244 425 1244 486 1244 522 1244 539 1244 552 1244 576 1244 625 1244 646 1244 652 1244 708 1244 714 1244 767 1244 771 1244 792 1244 881 1244 885 1244 887 1244 942 1244 944 1244 969 1244 980 1244 985 1244 992 1244 1007 1244 1017 1244 1064 1244 1072 1244 1089 1244 1125 1244 1141 1244 1165 1244 1173 1244 1178 1244 1204 1244 1209 1244 1244 1244 1261 1244 1316 1244 1339 1244 1353 1244 1372 1244 1403 1244 1468 1245 40 1245 115 1245 139 1245 177 1245 307 1245 366 1245 453 1245 833 1245 926 1245 1061 1245 1103 1245 1237 1245 1245 1245 1262 1245 1276 1245 1296 1245 1347 1245 1406 1245 1482 1246 10 1246 23 1246 122 1246 195 1246 468 1246 503 1246 517 1246 542 1246 573 1246 574 1246 582 1246 643 1246 666 1246 693 1246 697 1246 750 1246 811 1246 898 1246 1008 1246 1107 1246 1168 1246 1240 1246 1246 1246 1275 1246 1323 1246 1344 1246 1352 1246 1374 1246 1429 1246 1483 1246 1495 1247 16 1247 32 1247 40 1247 115 1247 139 1247 150 1247 171 1247 177 1247 207 1247 213 1247 237 1247 248 1247 307 1247 317 1247 366 1247 439 1247 453 1247 495 1247 706 1247 744 1247 833 1247 835 1247 848 1247 853 1247 859 1247 868 1247 869 1247 889 1247 926 1247 936 1247 1041 1247 1061 1247 1103 1247 1110 1247 1138 1247 1237 1247 1247 1247 1262 1247 1276 1247 1296 1247 1322 1247 1347 1247 1376 1247 1381 1247 1406 1247 1482 1248 2 1248 74 1248 84 1248 93 1248 95 1248 120 1248 126 1248 132 1248 194 1248 201 1248 231 1248 239 1248 241 1248 247 1248 271 1248 275 1248 282 1248 306 1248 311 1248 315 1248 362 1248 372 1248 384 1248 463 1248 481 1248 488 1248 515 1248 516 1248 554 1248 564 1248 654 1248 668 1248 670 1248 675 1248 719 1248 796 1248 858 1248 971 1248 975 1248 1001 1248 1023 1248 1036 1248 1050 1248 1058 1248 1116 1248 1119 1248 1122 1248 1157 1248 1194 1248 1248 1248 1280 1248 1282 1248 1302 1248 1329 1248 1354 1248 1384 1248 1394 1248 1435 1248 1478 1249 30 1249 38 1249 53 1249 58 1249 78 1249 211 1249 212 1249 216 1249 257 1249 262 1249 286 1249 349 1249 428 1249 431 1249 451 1249 460 1249 464 1249 534 1249 549 1249 626 1249 637 1249 720 1249 792 1249 808 1249 812 1249 829 1249 863 1249 874 1249 923 1249 980 1249 1046 1249 1057 1249 1065 1249 1084 1249 1137 1249 1187 1249 1219 1249 1234 1249 1238 1249 1249 1249 1334 1249 1336 1249 1390 1249 1415 1249 1418 1249 1459 1249 1481 1250 189 1250 217 1250 232 1250 253 1250 305 1250 344 1250 452 1250 455 1250 478 1250 526 1250 544 1250 567 1250 584 1250 591 1250 608 1250 684 1250 807 1250 822 1250 839 1250 860 1250 875 1250 908 1250 972 1250 990 1250 1014 1250 1142 1250 1216 1250 1217 1250 1229 1250 1235 1250 1236 1250 1250 1250 1290 1250 1313 1250 1348 1250 1355 1250 1356 1250 1358 1250 1361 1250 1370 1250 1375 1250 1498 1251 35 1251 41 1251 81 1251 94 1251 99 1251 140 1251 151 1251 179 1251 188 1251 199 1251 245 1251 246 1251 276 1251 284 1251 313 1251 321 1251 337 1251 339 1251 374 1251 382 1251 406 1251 430 1251 487 1251 496 1251 501 1251 505 1251 510 1251 513 1251 540 1251 577 1251 596 1251 664 1251 665 1251 686 1251 713 1251 754 1251 768 1251 781 1251 782 1251 790 1251 912 1251 929 1251 949 1251 950 1251 952 1251 1000 1251 1022 1251 1032 1251 1033 1251 1045 1251 1048 1251 1063 1251 1081 1251 1094 1251 1152 1251 1158 1251 1181 1251 1190 1251 1201 1251 1208 1251 1223 1251 1226 1251 1241 1251 1251 1251 1288 1251 1304 1251 1408 1251 1425 1251 1445 1251 1471 1252 16 1252 71 1252 159 1252 207 1252 252 1252 274 1252 297 1252 390 1252 432 1252 448 1252 469 1252 543 1252 548 1252 588 1252 615 1252 641 1252 707 1252 738 1252 764 1252 964 1252 1005 1252 1037 1252 1130 1252 1172 1252 1174 1252 1252 1252 1255 1252 1274 1252 1287 1252 1324 1252 1386 1252 1416 1252 1422 1252 1436 1252 1493 1253 93 1253 111 1253 117 1253 153 1253 239 1253 241 1253 247 1253 275 1253 282 1253 293 1253 311 1253 315 1253 353 1253 361 1253 372 1253 384 1253 450 1253 454 1253 463 1253 516 1253 564 1253 719 1253 838 1253 971 1253 982 1253 1056 1253 1083 1253 1105 1253 1194 1253 1253 1253 1256 1253 1280 1253 1282 1253 1307 1253 1377 1253 1385 1253 1394 1253 1395 1253 1396 1253 1447 1254 166 1254 306 1254 334 1254 420 1254 461 1254 471 1254 472 1254 553 1254 554 1254 566 1254 659 1254 668 1254 696 1254 723 1254 748 1254 804 1254 924 1254 1040 1254 1080 1254 1096 1254 1104 1254 1143 1254 1191 1254 1254 1254 1272 1254 1285 1254 1303 1254 1308 1254 1329 1254 1391 1254 1405 1254 1427 1254 1469 1255 34 1255 136 1255 297 1255 317 1255 423 1255 432 1255 439 1255 469 1255 548 1255 588 1255 641 1255 706 1255 763 1255 783 1255 813 1255 868 1255 889 1255 936 1255 964 1255 977 1255 1110 1255 1130 1255 1174 1255 1252 1255 1255 1255 1274 1255 1284 1255 1328 1255 1367 1255 1416 1255 1422 1255 1434 1255 1480 1256 2 1256 25 1256 69 1256 93 1256 97 1256 111 1256 117 1256 153 1256 194 1256 197 1256 220 1256 247 1256 282 1256 353 1256 362 1256 384 1256 450 1256 454 1256 463 1256 516 1256 554 1256 670 1256 794 1256 796 1256 970 1256 982 1256 1001 1256 1012 1256 1036 1256 1050 1256 1056 1256 1083 1256 1105 1256 1122 1256 1186 1256 1194 1256 1222 1256 1253 1256 1256 1256 1260 1256 1280 1256 1298 1256 1329 1256 1384 1256 1385 1256 1396 1256 1447 1256 1478 1257 7 1257 20 1257 31 1257 37 1257 75 1257 123 1257 167 1257 170 1257 178 1257 198 1257 219 1257 242 1257 319 1257 326 1257 350 1257 360 1257 402 1257 416 1257 418 1257 422 1257 457 1257 508 1257 551 1257 555 1257 559 1257 583 1257 589 1257 593 1257 622 1257 644 1257 657 1257 671 1257 673 1257 703 1257 725 1257 756 1257 766 1257 777 1257 800 1257 886 1257 916 1257 928 1257 933 1257 935 1257 958 1257 987 1257 997 1257 1015 1257 1020 1257 1071 1257 1087 1257 1101 1257 1106 1257 1112 1257 1154 1257 1161 1257 1166 1257 1167 1257 1171 1257 1185 1257 1200 1257 1203 1257 1205 1257 1211 1257 1257 1257 1268 1257 1273 1257 1289 1257 1311 1257 1326 1257 1388 1257 1433 1257 1479 1257 1490 1258 9 1258 15 1258 54 1258 121 1258 158 1258 182 1258 205 1258 221 1258 229 1258 257 1258 262 1258 285 1258 351 1258 381 1258 462 1258 485 1258 490 1258 536 1258 610 1258 618 1258 619 1258 685 1258 698 1258 701 1258 735 1258 808 1258 823 1258 827 1258 837 1258 864 1258 905 1258 1044 1258 1144 1258 1153 1258 1183 1258 1221 1258 1258 1258 1360 1258 1389 1258 1448 1258 1452 1258 1455 1259 74 1259 113 1259 132 1259 201 1259 227 1259 231 1259 241 1259 306 1259 324 1259 386 1259 474 1259 481 1259 515 1259 566 1259 581 1259 659 1259 696 1259 728 1259 788 1259 798 1259 804 1259 924 1259 1002 1259 1232 1259 1259 1259 1285 1259 1391 1260 25 1260 69 1260 111 1260 119 1260 146 1260 197 1260 220 1260 298 1260 330 1260 407 1260 427 1260 442 1260 454 1260 463 1260 516 1260 765 1260 780 1260 794 1260 951 1260 982 1260 983 1260 1083 1260 1133 1260 1186 1260 1194 1260 1222 1260 1228 1260 1256 1260 1260 1260 1298 1260 1371 1260 1385 1260 1396 1260 1466 1261 24 1261 51 1261 116 1261 129 1261 145 1261 174 1261 180 1261 206 1261 235 1261 261 1261 304 1261 322 1261 325 1261 348 1261 355 1261 356 1261 522 1261 539 1261 568 1261 629 1261 695 1261 708 1261 767 1261 776 1261 885 1261 931 1261 980 1261 985 1261 1007 1261 1141 1261 1178 1261 1244 1261 1261 1261 1316 1261 1339 1261 1403 1261 1468 1262 16 1262 32 1262 34 1262 40 1262 115 1262 139 1262 150 1262 171 1262 177 1262 207 1262 213 1262 237 1262 274 1262 307 1262 317 1262 366 1262 439 1262 453 1262 495 1262 744 1262 833 1262 835 1262 848 1262 853 1262 859 1262 868 1262 869 1262 926 1262 936 1262 1041 1262 1061 1262 1103 1262 1110 1262 1138 1262 1237 1262 1245 1262 1247 1262 1262 1262 1276 1262 1296 1262 1322 1262 1347 1262 1376 1262 1381 1262 1406 1262 1482 1263 6 1263 45 1263 70 1263 98 1263 108 1263 151 1263 186 1263 238 1263 256 1263 273 1263 281 1263 303 1263 367 1263 438 1263 512 1263 635 1263 645 1263 682 1263 722 1263 729 1263 731 1263 780 1263 794 1263 803 1263 1011 1263 1031 1263 1032 1263 1052 1263 1055 1263 1085 1263 1147 1263 1197 1263 1228 1263 1263 1263 1305 1263 1363 1263 1371 1263 1399 1263 1466 1263 1488 1264 118 1264 176 1264 236 1264 309 1264 532 1264 557 1264 565 1264 595 1264 651 1264 927 1264 957 1264 981 1264 984 1264 1150 1264 1182 1264 1220 1264 1264 1264 1270 1264 1295 1264 1366 1264 1489 1265 5 1265 12 1265 13 1265 52 1265 63 1265 65 1265 85 1265 165 1265 202 1265 234 1265 240 1265 365 1265 434 1265 441 1265 492 1265 528 1265 603 1265 609 1265 612 1265 630 1265 642 1265 742 1265 759 1265 883 1265 939 1265 1026 1265 1028 1265 1108 1265 1129 1265 1159 1265 1265 1265 1461 1265 1472 1266 26 1266 264 1266 281 1266 298 1266 301 1266 327 1266 338 1266 355 1266 398 1266 425 1266 436 1266 442 1266 465 1266 475 1266 480 1266 518 1266 546 1266 598 1266 650 1266 674 1266 734 1266 758 1266 771 1266 824 1266 934 1266 1035 1266 1079 1266 1085 1266 1124 1266 1145 1266 1147 1266 1204 1266 1266 1266 1271 1266 1305 1266 1400 1266 1412 1266 1413 1267 156 1267 196 1267 266 1267 345 1267 396 1267 400 1267 448 1267 449 1267 530 1267 543 1267 605 1267 669 1267 691 1267 707 1267 727 1267 739 1267 763 1267 764 1267 841 1267 847 1267 862 1267 873 1267 919 1267 920 1267 947 1267 960 1267 994 1267 1005 1267 1037 1267 1038 1267 1090 1267 1126 1267 1172 1267 1267 1267 1287 1267 1324 1267 1325 1267 1436 1267 1493 1268 7 1268 20 1268 37 1268 91 1268 167 1268 178 1268 219 1268 242 1268 319 1268 326 1268 350 1268 360 1268 416 1268 418 1268 508 1268 555 1268 583 1268 593 1268 622 1268 644 1268 703 1268 732 1268 770 1268 777 1268 800 1268 886 1268 900 1268 903 1268 928 1268 933 1268 958 1268 987 1268 1010 1268 1015 1268 1020 1268 1071 1268 1087 1268 1106 1268 1146 1268 1154 1268 1161 1268 1167 1268 1171 1268 1200 1268 1205 1268 1211 1268 1257 1268 1268 1268 1273 1268 1289 1268 1311 1268 1326 1268 1346 1268 1388 1268 1426 1268 1431 1268 1433 1268 1458 1268 1479 1269 33 1269 61 1269 110 1269 141 1269 155 1269 169 1269 195 1269 299 1269 314 1269 341 1269 342 1269 364 1269 379 1269 447 1269 458 1269 493 1269 504 1269 514 1269 571 1269 586 1269 687 1269 704 1269 749 1269 773 1269 811 1269 843 1269 904 1269 913 1269 915 1269 941 1269 943 1269 956 1269 1109 1269 1168 1269 1189 1269 1269 1269 1275 1269 1312 1269 1338 1269 1345 1269 1374 1269 1420 1269 1421 1269 1437 1270 46 1270 62 1270 104 1270 105 1270 109 1270 118 1270 254 1270 258 1270 346 1270 456 1270 500 1270 532 1270 557 1270 565 1270 651 1270 710 1270 826 1270 878 1270 899 1270 917 1270 957 1270 1025 1270 1114 1270 1149 1270 1182 1270 1220 1270 1243 1270 1264 1270 1270 1270 1310 1270 1350 1270 1366 1270 1380 1270 1383 1270 1489 1271 133 1271 152 1271 186 1271 238 1271 244 1271 264 1271 281 1271 298 1271 301 1271 338 1271 398 1271 442 1271 475 1271 518 1271 560 1271 674 1271 681 1271 803 1271 824 1271 884 1271 967 1271 980 1271 1011 1271 1031 1271 1085 1271 1124 1271 1145 1271 1147 1271 1199 1271 1266 1271 1271 1271 1305 1271 1330 1271 1371 1271 1378 1271 1400 1271 1412 1271 1413 1271 1468 1271 1499 1272 74 1272 247 1272 306 1272 386 1272 420 1272 461 1272 471 1272 525 1272 553 1272 566 1272 659 1272 660 1272 662 1272 668 1272 696 1272 723 1272 748 1272 804 1272 924 1272 1002 1272 1040 1272 1096 1272 1143 1272 1191 1272 1254 1272 1272 1272 1285 1272 1302 1272 1303 1272 1391 1273 7 1273 20 1273 37 1273 49 1273 87 1273 128 1273 204 1273 242 1273 350 1273 443 1273 446 1273 508 1273 555 1273 574 1273 583 1273 589 1273 613 1273 639 1273 671 1273 703 1273 800 1273 805 1273 836 1273 886 1273 903 1273 928 1273 953 1273 987 1273 1038 1273 1151 1273 1161 1273 1167 1273 1169 1273 1171 1273 1200 1273 1203 1273 1205 1273 1211 1273 1257 1273 1268 1273 1273 1273 1326 1273 1379 1273 1431 1273 1450 1273 1454 1273 1458 1273 1483 1274 16 1274 71 1274 136 1274 150 1274 177 1274 213 1274 248 1274 252 1274 274 1274 297 1274 317 1274 390 1274 423 1274 432 1274 469 1274 548 1274 588 1274 632 1274 641 1274 706 1274 738 1274 889 1274 964 1274 977 1274 1053 1274 1073 1274 1130 1274 1252 1274 1255 1274 1274 1274 1284 1274 1322 1274 1328 1274 1416 1274 1422 1274 1480 1275 141 1275 169 1275 195 1275 299 1275 342 1275 379 1275 504 1275 542 1275 571 1275 643 1275 693 1275 697 1275 749 1275 811 1275 915 1275 930 1275 943 1275 1109 1275 1168 1275 1240 1275 1246 1275 1269 1275 1275 1275 1323 1275 1344 1275 1352 1275 1374 1275 1420 1275 1437 1275 1495 1276 16 1276 32 1276 40 1276 115 1276 139 1276 207 1276 237 1276 307 1276 366 1276 439 1276 453 1276 744 1276 833 1276 835 1276 848 1276 853 1276 859 1276 868 1276 869 1276 926 1276 1061 1276 1103 1276 1110 1276 1138 1276 1237 1276 1245 1276 1247 1276 1262 1276 1276 1276 1296 1276 1322 1276 1347 1276 1376 1276 1381 1276 1406 1276 1482 1277 47 1277 79 1277 92 1277 125 1277 160 1277 189 1277 230 1277 272 1277 279 1277 295 1277 371 1277 373 1277 387 1277 391 1277 441 1277 483 1277 484 1277 491 1277 520 1277 556 1277 569 1277 600 1277 611 1277 612 1277 624 1277 640 1277 684 1277 690 1277 694 1277 743 1277 784 1277 807 1277 809 1277 814 1277 844 1277 882 1277 888 1277 910 1277 911 1277 978 1277 990 1277 999 1277 1014 1277 1018 1277 1068 1277 1069 1277 1075 1277 1082 1277 1099 1277 1180 1277 1196 1277 1206 1277 1217 1277 1230 1277 1236 1277 1277 1277 1281 1277 1355 1277 1370 1277 1441 1277 1472 1277 1474 1277 1476 1277 1484 1278 44 1278 57 1278 72 1278 76 1278 147 1278 149 1278 232 1278 344 1278 375 1278 388 1278 397 1278 491 1278 733 1278 799 1278 860 1278 893 1278 993 1278 1027 1278 1136 1278 1202 1278 1235 1278 1278 1278 1355 1278 1358 1278 1456 1279 43 1279 46 1279 60 1279 77 1279 104 1279 118 1279 154 1279 176 1279 280 1279 287 1279 309 1279 369 1279 385 1279 456 1279 500 1279 541 1279 557 1279 565 1279 633 1279 651 1279 724 1279 747 1279 779 1279 861 1279 891 1279 902 1279 927 1279 957 1279 976 1279 1013 1279 1030 1279 1128 1279 1150 1279 1182 1279 1210 1279 1243 1279 1279 1279 1295 1279 1366 1279 1380 1279 1439 1279 1489 1280 2 1280 74 1280 93 1280 95 1280 111 1280 113 1280 117 1280 126 1280 132 1280 153 1280 194 1280 201 1280 227 1280 231 1280 239 1280 241 1280 247 1280 271 1280 282 1280 296 1280 306 1280 311 1280 315 1280 362 1280 386 1280 450 1280 454 1280 463 1280 481 1280 515 1280 516 1280 564 1280 670 1280 796 1280 801 1280 838 1280 975 1280 982 1280 1001 1280 1002 1280 1036 1280 1050 1280 1056 1280 1116 1280 1119 1280 1122 1280 1194 1280 1232 1280 1248 1280 1253 1280 1256 1280 1280 1280 1282 1280 1298 1280 1302 1280 1394 1280 1396 1280 1478 1281 14 1281 47 1281 144 1281 223 1281 279 1281 295 1281 371 1281 387 1281 389 1281 391 1281 401 1281 408 1281 478 1281 483 1281 526 1281 600 1281 638 1281 680 1281 694 1281 784 1281 814 1281 822 1281 839 1281 888 1281 911 1281 940 1281 978 1281 1014 1281 1018 1281 1068 1281 1069 1281 1097 1281 1142 1281 1206 1281 1216 1281 1229 1281 1277 1281 1281 1281 1299 1281 1355 1281 1370 1281 1375 1281 1407 1281 1441 1281 1498 1282 2 1282 93 1282 95 1282 111 1282 113 1282 117 1282 126 1282 153 1282 201 1282 227 1282 231 1282 239 1282 241 1282 271 1282 275 1282 282 1282 293 1282 311 1282 450 1282 454 1282 463 1282 515 1282 516 1282 564 1282 801 1282 838 1282 858 1282 971 1282 975 1282 982 1282 1001 1282 1002 1282 1056 1282 1105 1282 1116 1282 1119 1282 1122 1282 1194 1282 1248 1282 1253 1282 1280 1282 1282 1282 1298 1282 1377 1282 1394 1282 1396 1282 1447 1283 58 1283 66 1283 86 1283 96 1283 162 1283 175 1283 193 1283 250 1283 277 1283 322 1283 354 1283 356 1283 394 1283 440 1283 444 1283 479 1283 561 1283 563 1283 714 1283 720 1283 785 1283 792 1283 874 1283 887 1283 909 1283 942 1283 1047 1283 1089 1283 1165 1283 1283 1283 1332 1283 1341 1284 34 1284 136 1284 150 1284 171 1284 207 1284 213 1284 237 1284 252 1284 297 1284 317 1284 383 1284 423 1284 432 1284 439 1284 495 1284 588 1284 615 1284 641 1284 706 1284 744 1284 783 1284 813 1284 848 1284 853 1284 859 1284 868 1284 889 1284 936 1284 1041 1284 1110 1284 1130 1284 1138 1284 1174 1284 1237 1284 1255 1284 1274 1284 1284 1284 1322 1284 1328 1284 1376 1284 1422 1285 74 1285 113 1285 166 1285 173 1285 201 1285 227 1285 306 1285 334 1285 386 1285 420 1285 461 1285 471 1285 472 1285 474 1285 515 1285 553 1285 554 1285 566 1285 659 1285 668 1285 696 1285 723 1285 748 1285 804 1285 924 1285 1040 1285 1096 1285 1104 1285 1143 1285 1191 1285 1192 1285 1254 1285 1259 1285 1272 1285 1285 1285 1303 1285 1329 1285 1391 1285 1405 1285 1427 1285 1469 1286 27 1286 127 1286 138 1286 228 1286 318 1286 329 1286 337 1286 393 1286 510 1286 513 1286 535 1286 568 1286 585 1286 775 1286 834 1286 890 1286 909 1286 918 1286 925 1286 946 1286 965 1286 968 1286 979 1286 988 1286 1000 1286 1016 1286 1048 1286 1111 1286 1241 1286 1286 1286 1314 1286 1321 1286 1392 1286 1408 1286 1445 1286 1471 1287 22 1287 156 1287 159 1287 292 1287 390 1287 396 1287 403 1287 449 1287 530 1287 543 1287 548 1287 583 1287 641 1287 707 1287 763 1287 764 1287 847 1287 873 1287 920 1287 948 1287 960 1287 964 1287 994 1287 1005 1287 1037 1287 1038 1287 1126 1287 1174 1287 1252 1287 1267 1287 1287 1287 1324 1287 1325 1287 1386 1287 1436 1287 1493 1288 21 1288 80 1288 94 1288 179 1288 225 1288 226 1288 245 1288 249 1288 276 1288 278 1288 310 1288 329 1288 339 1288 412 1288 437 1288 445 1288 496 1288 509 1288 535 1288 602 1288 653 1288 656 1288 664 1288 713 1288 754 1288 768 1288 912 1288 922 1288 949 1288 952 1288 966 1288 1022 1288 1032 1288 1033 1288 1045 1288 1063 1288 1070 1288 1170 1288 1175 1288 1190 1288 1251 1288 1288 1289 7 1289 22 1289 143 1289 167 1289 178 1289 219 1289 242 1289 266 1289 326 1289 336 1289 350 1289 360 1289 378 1289 416 1289 418 1289 446 1289 449 1289 508 1289 530 1289 583 1289 593 1289 607 1289 617 1289 621 1289 622 1289 644 1289 732 1289 777 1289 791 1289 873 1289 900 1289 903 1289 928 1289 935 1289 948 1289 958 1289 962 1289 1010 1289 1015 1289 1071 1289 1087 1289 1106 1289 1154 1289 1161 1289 1162 1289 1171 1289 1176 1289 1205 1289 1211 1289 1224 1289 1257 1289 1268 1289 1289 1289 1294 1289 1311 1289 1326 1289 1431 1289 1444 1289 1464 1290 76 1290 135 1290 144 1290 189 1290 217 1290 232 1290 253 1290 295 1290 305 1290 397 1290 401 1290 452 1290 455 1290 478 1290 484 1290 520 1290 526 1290 556 1290 567 1290 591 1290 608 1290 611 1290 680 1290 684 1290 733 1290 822 1290 839 1290 875 1290 911 1290 940 1290 978 1290 990 1290 1014 1290 1018 1290 1142 1290 1206 1290 1216 1290 1217 1290 1229 1290 1235 1290 1250 1290 1290 1290 1313 1290 1348 1290 1355 1290 1356 1290 1358 1290 1370 1290 1375 1290 1498 1291 13 1291 55 1291 65 1291 85 1291 187 1291 218 1291 291 1291 434 1291 441 1291 452 1291 492 1291 497 1291 526 1291 528 1291 562 1291 603 1291 606 1291 608 1291 620 1291 730 1291 867 1291 883 1291 1076 1291 1091 1291 1129 1291 1159 1291 1225 1291 1236 1291 1291 1291 1313 1291 1348 1292 35 1292 140 1292 145 1292 313 1292 321 1292 411 1292 531 1292 552 1292 577 1292 705 1292 741 1292 751 1292 753 1292 772 1292 797 1292 832 1292 852 1292 881 1292 991 1292 995 1292 1092 1292 1120 1292 1123 1292 1173 1292 1213 1292 1292 1292 1372 1293 84 1293 88 1293 173 1293 209 1293 324 1293 334 1293 420 1293 461 1293 472 1293 477 1293 488 1293 489 1293 553 1293 572 1293 581 1293 659 1293 668 1293 723 1293 728 1293 737 1293 748 1293 788 1293 798 1293 818 1293 917 1293 1006 1293 1062 1293 1080 1293 1093 1293 1096 1293 1104 1293 1115 1293 1143 1293 1149 1293 1192 1293 1293 1293 1469 1294 31 1294 107 1294 123 1294 143 1294 167 1294 178 1294 219 1294 326 1294 350 1294 378 1294 416 1294 418 1294 422 1294 449 1294 507 1294 593 1294 607 1294 617 1294 621 1294 622 1294 644 1294 732 1294 777 1294 791 1294 854 1294 900 1294 928 1294 935 1294 937 1294 958 1294 962 1294 997 1294 1010 1294 1015 1294 1112 1294 1146 1294 1154 1294 1162 1294 1171 1294 1176 1294 1289 1294 1294 1294 1311 1294 1326 1294 1426 1294 1444 1294 1464 1295 43 1295 60 1295 118 1295 154 1295 176 1295 208 1295 254 1295 280 1295 287 1295 369 1295 385 1295 410 1295 456 1295 541 1295 557 1295 565 1295 633 1295 651 1295 724 1295 747 1295 779 1295 861 1295 891 1295 902 1295 927 1295 957 1295 976 1295 989 1295 1013 1295 1030 1295 1150 1295 1210 1295 1264 1295 1279 1295 1295 1295 1310 1295 1366 1295 1380 1295 1489 1296 16 1296 32 1296 34 1296 40 1296 115 1296 139 1296 150 1296 171 1296 177 1296 207 1296 213 1296 237 1296 274 1296 307 1296 317 1296 366 1296 439 1296 453 1296 495 1296 744 1296 833 1296 835 1296 848 1296 853 1296 859 1296 868 1296 869 1296 926 1296 936 1296 1041 1296 1061 1296 1103 1296 1110 1296 1138 1296 1237 1296 1245 1296 1247 1296 1262 1296 1276 1296 1296 1296 1322 1296 1347 1296 1376 1296 1381 1296 1406 1296 1482 1297 10 1297 103 1297 210 1297 341 1297 364 1297 542 1297 578 1297 601 1297 643 1297 666 1297 687 1297 704 1297 811 1297 898 1297 913 1297 915 1297 1008 1297 1095 1297 1109 1297 1168 1297 1297 1297 1312 1297 1338 1297 1421 1297 1457 1298 2 1298 25 1298 69 1298 93 1298 111 1298 119 1298 126 1298 146 1298 153 1298 282 1298 353 1298 427 1298 450 1298 454 1298 463 1298 466 1298 481 1298 516 1298 780 1298 794 1298 796 1298 801 1298 838 1298 982 1298 1012 1298 1119 1298 1122 1298 1133 1298 1186 1298 1194 1298 1256 1298 1260 1298 1280 1298 1282 1298 1298 1298 1385 1298 1396 1298 1447 1298 1466 1298 1478 1299 36 1299 55 1299 56 1299 83 1299 101 1299 164 1299 187 1299 217 1299 343 1299 391 1299 408 1299 497 1299 524 1299 547 1299 592 1299 620 1299 638 1299 667 1299 680 1299 784 1299 814 1299 844 1299 867 1299 870 1299 906 1299 908 1299 940 1299 972 1299 1034 1299 1068 1299 1098 1299 1099 1299 1180 1299 1198 1299 1225 1299 1281 1299 1299 1299 1361 1299 1373 1299 1407 1299 1441 1299 1474 1299 1496 1299 1498 1300 10 1300 50 1300 68 1300 75 1300 141 1300 184 1300 198 1300 203 1300 210 1300 294 1300 299 1300 300 1300 314 1300 333 1300 357 1300 368 1300 376 1300 433 1300 538 1300 542 1300 559 1300 571 1300 601 1300 627 1300 657 1300 666 1300 697 1300 704 1300 766 1300 898 1300 916 1300 930 1300 1008 1300 1029 1300 1088 1300 1100 1300 1169 1300 1185 1300 1189 1300 1203 1300 1300 1300 1338 1300 1364 1300 1374 1300 1460 1300 1490 1300 1495 1301 39 1301 77 1301 104 1301 109 1301 112 1301 168 1301 215 1301 258 1301 280 1301 302 1301 346 1301 409 1301 410 1301 633 1301 878 1301 891 1301 954 1301 976 1301 989 1301 1025 1301 1128 1301 1134 1301 1148 1301 1207 1301 1233 1301 1301 1301 1319 1301 1350 1301 1439 1302 2 1302 111 1302 113 1302 194 1302 227 1302 247 1302 275 1302 362 1302 372 1302 384 1302 461 1302 471 1302 481 1302 525 1302 566 1302 668 1302 670 1302 675 1302 696 1302 796 1302 804 1302 1001 1302 1012 1302 1036 1302 1040 1302 1119 1302 1122 1302 1186 1302 1191 1302 1248 1302 1272 1302 1280 1302 1302 1302 1303 1302 1329 1302 1391 1302 1478 1303 84 1303 166 1303 173 1303 306 1303 334 1303 420 1303 461 1303 471 1303 472 1303 488 1303 553 1303 554 1303 668 1303 675 1303 696 1303 723 1303 748 1303 788 1303 804 1303 924 1303 1040 1303 1080 1303 1096 1303 1143 1303 1191 1303 1192 1303 1254 1303 1272 1303 1285 1303 1302 1303 1303 1303 1308 1303 1319 1303 1329 1303 1391 1303 1405 1303 1427 1303 1469 1304 11 1304 29 1304 41 1304 45 1304 106 1304 151 1304 199 1304 245 1304 251 1304 284 1304 318 1304 339 1304 347 1304 374 1304 380 1304 430 1304 459 1304 470 1304 494 1304 505 1304 510 1304 540 1304 665 1304 676 1304 683 1304 686 1304 689 1304 699 1304 713 1304 726 1304 760 1304 787 1304 790 1304 821 1304 828 1304 896 1304 921 1304 929 1304 931 1304 949 1304 950 1304 965 1304 979 1304 986 1304 1019 1304 1048 1304 1060 1304 1063 1304 1081 1304 1152 1304 1190 1304 1215 1304 1251 1304 1304 1304 1349 1304 1408 1304 1417 1304 1425 1304 1445 1304 1449 1304 1465 1304 1471 1305 0 1305 98 1305 133 1305 185 1305 186 1305 238 1305 264 1305 281 1305 298 1305 301 1305 303 1305 338 1305 358 1305 367 1305 398 1305 438 1305 442 1305 475 1305 480 1305 518 1305 546 1305 597 1305 645 1305 650 1305 674 1305 676 1305 699 1305 722 1305 729 1305 758 1305 771 1305 803 1305 824 1305 892 1305 996 1305 1011 1305 1060 1305 1085 1305 1145 1305 1147 1305 1263 1305 1266 1305 1271 1305 1305 1305 1371 1305 1400 1305 1412 1305 1413 1305 1488 1305 1499 1306 18 1306 146 1306 214 1306 320 1306 415 1306 476 1306 672 1306 688 1306 712 1306 740 1306 793 1306 856 1306 876 1306 880 1306 907 1306 1004 1306 1117 1306 1177 1306 1193 1306 1195 1306 1306 1306 1337 1306 1387 1306 1397 1306 1438 1306 1473 1307 84 1307 117 1307 120 1307 201 1307 239 1307 271 1307 275 1307 293 1307 311 1307 315 1307 361 1307 372 1307 415 1307 488 1307 647 1307 677 1307 719 1307 793 1307 858 1307 971 1307 1006 1307 1023 1307 1056 1307 1058 1307 1157 1307 1253 1307 1307 1307 1377 1307 1394 1307 1395 1307 1424 1307 1435 1307 1447 1308 80 1308 114 1308 166 1308 235 1308 467 1308 471 1308 664 1308 675 1308 825 1308 966 1308 1012 1308 1170 1308 1175 1308 1191 1308 1254 1308 1303 1308 1308 1308 1329 1308 1427 1309 53 1309 58 1309 78 1309 86 1309 193 1309 211 1309 250 1309 277 1309 332 1309 348 1309 349 1309 405 1309 431 1309 440 1309 444 1309 451 1309 534 1309 563 1309 579 1309 625 1309 626 1309 658 1309 720 1309 846 1309 863 1309 901 1309 959 1309 1024 1309 1035 1309 1046 1309 1084 1309 1131 1309 1135 1309 1137 1309 1309 1309 1341 1309 1351 1309 1475 1309 1494 1310 39 1310 60 1310 62 1310 77 1310 104 1310 105 1310 109 1310 112 1310 154 1310 176 1310 208 1310 254 1310 280 1310 302 1310 346 1310 410 1310 456 1310 500 1310 541 1310 633 1310 651 1310 724 1310 747 1310 779 1310 826 1310 861 1310 878 1310 891 1310 899 1310 902 1310 927 1310 957 1310 976 1310 989 1310 1013 1310 1025 1310 1030 1310 1128 1310 1148 1310 1207 1310 1210 1310 1220 1310 1270 1310 1295 1310 1310 1310 1350 1310 1380 1310 1383 1310 1439 1311 37 1311 122 1311 123 1311 143 1311 167 1311 178 1311 203 1311 219 1311 242 1311 319 1311 326 1311 350 1311 360 1311 378 1311 402 1311 416 1311 418 1311 422 1311 443 1311 468 1311 555 1311 589 1311 593 1311 617 1311 622 1311 644 1311 657 1311 671 1311 673 1311 703 1311 732 1311 756 1311 777 1311 800 1311 805 1311 886 1311 900 1311 928 1311 933 1311 935 1311 955 1311 958 1311 997 1311 1010 1311 1015 1311 1071 1311 1087 1311 1101 1311 1106 1311 1154 1311 1161 1311 1166 1311 1167 1311 1171 1311 1185 1311 1200 1311 1205 1311 1211 1311 1257 1311 1268 1311 1289 1311 1294 1311 1311 1311 1326 1311 1346 1311 1388 1311 1426 1311 1431 1311 1433 1311 1479 1312 33 1312 50 1312 61 1312 103 1312 110 1312 210 1312 299 1312 314 1312 341 1312 342 1312 364 1312 379 1312 447 1312 458 1312 493 1312 504 1312 514 1312 542 1312 578 1312 586 1312 601 1312 666 1312 687 1312 704 1312 749 1312 811 1312 904 1312 913 1312 915 1312 943 1312 956 1312 1008 1312 1095 1312 1109 1312 1168 1312 1189 1312 1269 1312 1297 1312 1312 1312 1338 1312 1420 1312 1421 1312 1437 1313 83 1313 144 1313 187 1313 217 1313 223 1313 452 1313 497 1313 526 1313 544 1313 562 1313 567 1313 608 1313 822 1313 839 1313 875 1313 883 1313 940 1313 972 1313 1098 1313 1216 1313 1225 1313 1236 1313 1250 1313 1290 1313 1291 1313 1313 1313 1348 1313 1356 1313 1361 1313 1375 1313 1498 1314 26 1314 89 1314 233 1314 267 1314 332 1314 355 1314 436 1314 482 1314 494 1314 598 1314 629 1314 650 1314 708 1314 755 1314 865 1314 895 1314 896 1314 921 1314 965 1314 1009 1314 1079 1314 1286 1314 1314 1314 1321 1314 1341 1314 1349 1314 1403 1314 1467 1314 1485 1314 1494 1315 100 1315 260 1315 329 1315 337 1315 393 1315 417 1315 421 1315 445 1315 459 1315 596 1315 616 1315 679 1315 717 1315 754 1315 759 1315 762 1315 806 1315 922 1315 1042 1315 1045 1315 1070 1315 1077 1315 1139 1315 1241 1315 1315 1315 1317 1315 1387 1315 1428 1315 1438 1315 1445 1315 1470 1316 28 1316 66 1316 116 1316 206 1316 233 1316 244 1316 263 1316 267 1316 283 1316 325 1316 348 1316 349 1316 355 1316 394 1316 399 1316 425 1316 431 1316 444 1316 464 1316 522 1316 552 1316 575 1316 580 1316 623 1316 625 1316 631 1316 646 1316 652 1316 695 1316 708 1316 755 1316 776 1316 795 1316 829 1316 830 1316 896 1316 921 1316 931 1316 995 1316 1007 1316 1046 1316 1059 1316 1064 1316 1140 1316 1199 1316 1204 1316 1244 1316 1261 1316 1316 1316 1378 1316 1403 1316 1446 1316 1467 1316 1468 1316 1481 1316 1494 1317 1 1317 99 1317 100 1317 249 1317 260 1317 265 1317 329 1317 421 1317 445 1317 487 1317 550 1317 602 1317 616 1317 653 1317 656 1317 672 1317 712 1317 717 1317 754 1317 806 1317 820 1317 850 1317 855 1317 922 1317 1042 1317 1074 1317 1175 1317 1195 1317 1226 1317 1315 1317 1317 1317 1337 1317 1342 1317 1397 1317 1428 1317 1438 1318 151 1318 185 1318 244 1318 251 1318 264 1318 398 1318 430 1318 475 1318 480 1318 529 1318 546 1318 598 1318 663 1318 665 1318 674 1318 721 1318 758 1318 760 1318 817 1318 842 1318 934 1318 986 1318 1009 1318 1011 1318 1019 1318 1070 1318 1079 1318 1204 1318 1215 1318 1218 1318 1318 1318 1449 1318 1465 1319 39 1319 112 1319 168 1319 215 1319 258 1319 302 1319 346 1319 409 1319 426 1319 461 1319 553 1319 696 1319 748 1319 954 1319 989 1319 1080 1319 1134 1319 1143 1319 1148 1319 1191 1319 1233 1319 1301 1319 1303 1319 1319 1319 1405 1319 1427 1320 59 1320 67 1320 161 1320 190 1320 335 1320 414 1320 435 1320 774 1320 840 1320 841 1320 857 1320 919 1320 953 1320 1021 1320 1231 1320 1320 1320 1365 1320 1409 1320 1432 1320 1443 1320 1454 1320 1477 1320 1491 1320 1497 1321 26 1321 89 1321 138 1321 267 1321 355 1321 470 1321 475 1321 482 1321 494 1321 598 1321 646 1321 708 1321 715 1321 755 1321 817 1321 895 1321 896 1321 921 1321 965 1321 979 1321 995 1321 1007 1321 1009 1321 1079 1321 1286 1321 1314 1321 1321 1321 1392 1321 1449 1321 1467 1321 1485 1322 16 1322 32 1322 34 1322 40 1322 136 1322 150 1322 171 1322 177 1322 207 1322 213 1322 237 1322 248 1322 252 1322 274 1322 297 1322 317 1322 423 1322 432 1322 439 1322 453 1322 495 1322 588 1322 641 1322 706 1322 744 1322 813 1322 835 1322 848 1322 853 1322 859 1322 868 1322 889 1322 926 1322 936 1322 964 1322 1041 1322 1053 1322 1061 1322 1073 1322 1110 1322 1130 1322 1138 1322 1237 1322 1247 1322 1262 1322 1274 1322 1276 1322 1284 1322 1296 1322 1322 1322 1328 1322 1347 1322 1376 1322 1381 1322 1422 1323 23 1323 122 1323 368 1323 468 1323 503 1323 517 1323 542 1323 551 1323 573 1323 582 1323 643 1323 693 1323 697 1323 811 1323 898 1323 1101 1323 1107 1323 1240 1323 1246 1323 1275 1323 1323 1323 1344 1323 1352 1323 1374 1323 1429 1323 1495 1324 22 1324 148 1324 156 1324 159 1324 196 1324 266 1324 345 1324 378 1324 390 1324 396 1324 403 1324 446 1324 448 1324 449 1324 530 1324 543 1324 548 1324 583 1324 604 1324 621 1324 641 1324 669 1324 707 1324 739 1324 763 1324 764 1324 791 1324 854 1324 873 1324 903 1324 920 1324 948 1324 960 1324 994 1324 1005 1324 1037 1324 1038 1324 1090 1324 1126 1324 1176 1324 1224 1324 1252 1324 1267 1324 1287 1324 1324 1324 1325 1324 1326 1324 1386 1324 1434 1324 1436 1324 1444 1324 1493 1325 156 1325 159 1325 196 1325 252 1325 266 1325 345 1325 383 1325 396 1325 400 1325 448 1325 543 1325 605 1325 615 1325 707 1325 739 1325 764 1325 847 1325 920 1325 947 1325 960 1325 994 1325 1037 1325 1090 1325 1126 1325 1172 1325 1174 1325 1267 1325 1287 1325 1324 1325 1325 1325 1386 1325 1434 1325 1436 1325 1493 1326 7 1326 20 1326 22 1326 31 1326 37 1326 87 1326 123 1326 143 1326 148 1326 156 1326 167 1326 204 1326 219 1326 242 1326 266 1326 292 1326 326 1326 336 1326 350 1326 378 1326 403 1326 446 1326 449 1326 530 1326 583 1326 604 1326 613 1326 621 1326 636 1326 644 1326 669 1326 671 1326 703 1326 777 1326 791 1326 873 1326 900 1326 903 1326 928 1326 935 1326 948 1326 958 1326 962 1326 987 1326 994 1326 1038 1326 1071 1326 1106 1326 1154 1326 1161 1326 1171 1326 1176 1326 1211 1326 1224 1326 1257 1326 1268 1326 1273 1326 1289 1326 1294 1326 1311 1326 1324 1326 1326 1326 1431 1326 1444 1326 1450 1326 1458 1326 1464 1326 1490 1327 26 1327 78 1327 82 1327 102 1327 191 1327 193 1327 200 1327 222 1327 233 1327 312 1327 327 1327 332 1327 405 1327 436 1327 451 1327 465 1327 560 1327 579 1327 598 1327 658 1327 734 1327 758 1327 771 1327 802 1327 863 1327 866 1327 892 1327 901 1327 934 1327 959 1327 1003 1327 1024 1327 1035 1327 1054 1327 1066 1327 1079 1327 1102 1327 1113 1327 1118 1327 1124 1327 1135 1327 1212 1327 1214 1327 1221 1327 1327 1327 1330 1327 1340 1327 1413 1327 1442 1327 1485 1327 1486 1327 1494 1328 16 1328 71 1328 136 1328 150 1328 177 1328 248 1328 297 1328 317 1328 390 1328 423 1328 432 1328 469 1328 519 1328 548 1328 588 1328 632 1328 641 1328 706 1328 738 1328 889 1328 964 1328 977 1328 1053 1328 1073 1328 1130 1328 1255 1328 1274 1328 1284 1328 1322 1328 1328 1328 1367 1328 1416 1328 1422 1328 1480 1329 2 1329 84 1329 97 1329 153 1329 166 1329 194 1329 197 1329 241 1329 247 1329 296 1329 306 1329 362 1329 384 1329 471 1329 488 1329 499 1329 554 1329 566 1329 654 1329 662 1329 670 1329 675 1329 796 1329 825 1329 970 1329 1001 1329 1036 1329 1040 1329 1050 1329 1105 1329 1157 1329 1186 1329 1191 1329 1248 1329 1254 1329 1256 1329 1285 1329 1302 1329 1303 1329 1308 1329 1329 1329 1354 1329 1384 1329 1427 1330 0 1330 26 1330 73 1330 102 1330 130 1330 152 1330 200 1330 205 1330 222 1330 259 1330 312 1330 338 1330 436 1330 442 1330 465 1330 518 1330 560 1330 587 1330 655 1330 701 1330 734 1330 752 1330 758 1330 761 1330 771 1330 778 1330 802 1330 815 1330 866 1330 871 1330 892 1330 897 1330 934 1330 959 1330 983 1330 1035 1330 1085 1330 1102 1330 1113 1330 1118 1330 1124 1330 1145 1330 1212 1330 1214 1330 1221 1330 1271 1330 1327 1330 1330 1330 1340 1330 1382 1330 1400 1330 1413 1330 1442 1330 1486 1331 5 1331 36 1331 92 1331 101 1331 202 1331 230 1331 240 1331 291 1331 365 1331 434 1331 441 1331 526 1331 569 1331 606 1331 612 1331 630 1331 730 1331 867 1331 999 1331 1018 1331 1075 1331 1076 1331 1331 1331 1369 1331 1461 1331 1472 1331 1476 1331 1484 1332 17 1332 66 1332 162 1332 322 1332 354 1332 394 1332 440 1332 464 1332 634 1332 649 1332 720 1332 745 1332 785 1332 792 1332 874 1332 887 1332 969 1332 1047 1332 1067 1332 1089 1332 1125 1332 1165 1332 1213 1332 1238 1332 1283 1332 1332 1332 1372 1333 42 1333 129 1333 172 1333 180 1333 192 1333 340 1333 352 1333 395 1333 575 1333 576 1333 722 1333 745 1333 767 1333 885 1333 961 1333 969 1333 983 1333 1067 1333 1178 1333 1333 1333 1415 1333 1499 1334 30 1334 53 1334 58 1334 90 1334 191 1334 212 1334 222 1334 257 1334 262 1334 270 1334 323 1334 506 1334 533 1334 534 1334 536 1334 537 1334 701 1334 702 1334 734 1334 761 1334 785 1334 808 1334 812 1334 884 1334 967 1334 1003 1334 1024 1334 1035 1334 1054 1334 1057 1334 1118 1334 1124 1334 1135 1334 1141 1334 1187 1334 1219 1334 1249 1334 1334 1334 1390 1334 1459 1334 1486 1335 11 1335 41 1335 94 1335 179 1335 225 1335 249 1335 265 1335 310 1335 339 1335 459 1335 509 1335 523 1335 656 1335 664 1335 713 1335 787 1335 790 1335 821 1335 828 1335 845 1335 855 1335 880 1335 894 1335 912 1335 932 1335 963 1335 974 1335 1045 1335 1063 1335 1081 1335 1158 1335 1163 1335 1170 1335 1181 1335 1223 1335 1335 1336 24 1336 30 1336 38 1336 53 1336 78 1336 102 1336 193 1336 212 1336 216 1336 270 1336 286 1336 348 1336 428 1336 431 1336 451 1336 460 1336 464 1336 506 1336 511 1336 534 1336 549 1336 580 1336 610 1336 631 1336 637 1336 702 1336 720 1336 752 1336 761 1336 769 1336 812 1336 829 1336 863 1336 874 1336 923 1336 1003 1336 1017 1336 1046 1336 1057 1336 1065 1336 1084 1336 1135 1336 1219 1336 1234 1336 1238 1336 1249 1336 1336 1336 1351 1336 1390 1336 1415 1336 1418 1336 1459 1336 1481 1337 1 1337 100 1337 214 1337 260 1337 265 1337 421 1337 476 1337 672 1337 712 1337 759 1337 850 1337 855 1337 856 1337 876 1337 1074 1337 1117 1337 1195 1337 1306 1337 1317 1337 1337 1337 1342 1337 1397 1337 1438 1338 10 1338 33 1338 50 1338 61 1338 68 1338 141 1338 195 1338 210 1338 299 1338 314 1338 341 1338 342 1338 357 1338 364 1338 379 1338 433 1338 493 1338 504 1338 514 1338 542 1338 559 1338 571 1338 578 1338 601 1338 627 1338 666 1338 704 1338 749 1338 766 1338 811 1338 898 1338 904 1338 913 1338 930 1338 1008 1338 1029 1338 1088 1338 1095 1338 1109 1338 1189 1338 1269 1338 1297 1338 1300 1338 1312 1338 1338 1338 1374 1338 1420 1338 1421 1338 1437 1338 1460 1338 1495 1339 24 1339 51 1339 116 1339 124 1339 145 1339 174 1339 235 1339 321 1339 325 1339 355 1339 356 1339 425 1339 429 1339 522 1339 539 1339 552 1339 568 1339 594 1339 629 1339 646 1339 695 1339 714 1339 729 1339 776 1339 832 1339 885 1339 944 1339 985 1339 995 1339 1007 1339 1039 1339 1178 1339 1204 1339 1244 1339 1261 1339 1339 1339 1468 1340 15 1340 53 1340 54 1340 78 1340 82 1340 102 1340 121 1340 191 1340 205 1340 222 1340 257 1340 285 1340 312 1340 351 1340 405 1340 451 1340 490 1340 533 1340 536 1340 563 1340 579 1340 610 1340 619 1340 626 1340 658 1340 685 1340 701 1340 702 1340 752 1340 823 1340 863 1340 901 1340 959 1340 1003 1340 1024 1340 1035 1340 1044 1340 1054 1340 1066 1340 1102 1340 1113 1340 1118 1340 1135 1340 1183 1340 1212 1340 1214 1340 1221 1340 1327 1340 1330 1340 1340 1340 1442 1340 1463 1340 1481 1340 1486 1341 26 1341 58 1341 66 1341 82 1341 86 1341 193 1341 211 1341 250 1341 277 1341 323 1341 332 1341 405 1341 425 1341 440 1341 444 1341 502 1341 563 1341 623 1341 625 1341 626 1341 658 1341 678 1341 720 1341 863 1341 896 1341 959 1341 1009 1341 1024 1341 1035 1341 1054 1341 1064 1341 1165 1341 1283 1341 1309 1341 1314 1341 1341 1341 1390 1341 1449 1342 1 1342 100 1342 214 1342 260 1342 265 1342 415 1342 417 1342 421 1342 476 1342 656 1342 672 1342 712 1342 793 1342 806 1342 850 1342 855 1342 856 1342 876 1342 945 1342 1074 1342 1117 1342 1195 1342 1317 1342 1337 1342 1342 1342 1387 1342 1397 1343 9 1343 15 1343 19 1343 54 1343 73 1343 121 1343 130 1343 152 1343 205 1343 259 1343 285 1343 312 1343 338 1343 485 1343 490 1343 536 1343 587 1343 618 1343 655 1343 685 1343 698 1343 752 1343 778 1343 802 1343 815 1343 823 1343 827 1343 837 1343 871 1343 905 1343 1044 1343 1102 1343 1144 1343 1153 1343 1183 1343 1212 1343 1221 1343 1343 1343 1382 1343 1442 1343 1452 1343 1455 1343 1463 1344 23 1344 122 1344 468 1344 503 1344 517 1344 582 1344 643 1344 693 1344 750 1344 1101 1344 1240 1344 1246 1344 1275 1344 1323 1344 1344 1344 1352 1344 1429 1345 33 1345 61 1345 110 1345 155 1345 169 1345 342 1345 364 1345 447 1345 458 1345 493 1345 586 1345 749 1345 773 1345 843 1345 904 1345 941 1345 943 1345 956 1345 1109 1345 1269 1345 1345 1345 1421 1345 1437 1346 170 1346 219 1346 319 1346 326 1346 416 1346 418 1346 422 1346 457 1346 508 1346 555 1346 593 1346 644 1346 732 1346 736 1346 770 1346 777 1346 800 1346 886 1346 933 1346 997 1346 1010 1346 1015 1346 1020 1346 1112 1346 1146 1346 1161 1346 1167 1346 1200 1346 1205 1346 1268 1346 1311 1346 1346 1346 1388 1346 1402 1346 1426 1346 1431 1346 1433 1346 1462 1346 1479 1347 32 1347 34 1347 40 1347 115 1347 171 1347 177 1347 207 1347 213 1347 237 1347 274 1347 307 1347 439 1347 453 1347 495 1347 744 1347 813 1347 833 1347 835 1347 848 1347 853 1347 859 1347 868 1347 869 1347 926 1347 936 1347 1041 1347 1061 1347 1103 1347 1110 1347 1138 1347 1237 1347 1245 1347 1247 1347 1262 1347 1276 1347 1296 1347 1322 1347 1347 1347 1376 1347 1381 1347 1482 1348 101 1348 187 1348 217 1348 452 1348 497 1348 524 1348 526 1348 544 1348 547 1348 562 1348 567 1348 584 1348 591 1348 606 1348 608 1348 684 1348 822 1348 867 1348 875 1348 908 1348 972 1348 1034 1348 1098 1348 1216 1348 1225 1348 1236 1348 1250 1348 1290 1348 1291 1348 1313 1348 1348 1348 1356 1348 1375 1348 1498 1349 6 1349 42 1349 45 1349 89 1349 124 1349 127 1349 268 1349 392 1349 429 1349 470 1349 482 1349 486 1349 494 1349 501 1349 502 1349 678 1349 686 1349 689 1349 722 1349 726 1349 753 1349 757 1349 775 1349 810 1349 896 1349 921 1349 931 1349 950 1349 968 1349 1007 1349 1072 1349 1160 1349 1201 1349 1304 1349 1314 1349 1349 1349 1399 1349 1403 1350 62 1350 104 1350 105 1350 109 1350 254 1350 346 1350 489 1350 500 1350 532 1350 651 1350 710 1350 737 1350 826 1350 878 1350 899 1350 917 1350 1025 1350 1093 1350 1104 1350 1114 1350 1134 1350 1149 1350 1207 1350 1220 1350 1270 1350 1301 1350 1310 1350 1350 1350 1383 1351 38 1351 78 1351 180 1351 212 1351 216 1351 277 1351 283 1351 286 1351 304 1351 322 1351 328 1351 348 1351 349 1351 354 1351 394 1351 395 1351 399 1351 428 1351 460 1351 464 1351 534 1351 580 1351 631 1351 634 1351 652 1351 681 1351 720 1351 786 1351 795 1351 829 1351 865 1351 874 1351 923 1351 980 1351 1059 1351 1125 1351 1137 1351 1140 1351 1209 1351 1238 1351 1309 1351 1336 1351 1351 1351 1378 1351 1418 1352 195 1352 314 1352 504 1352 517 1352 542 1352 551 1352 571 1352 582 1352 643 1352 666 1352 693 1352 697 1352 811 1352 915 1352 930 1352 1008 1352 1095 1352 1107 1352 1109 1352 1168 1352 1240 1352 1246 1352 1275 1352 1323 1352 1344 1352 1352 1352 1374 1352 1437 1352 1495 1353 66 1353 116 1353 124 1353 129 1353 131 1353 137 1353 145 1353 174 1353 261 1353 322 1353 323 1353 356 1353 392 1353 486 1353 502 1353 539 1353 576 1353 649 1353 745 1353 757 1353 767 1353 885 1353 944 1353 992 1353 1067 1353 1072 1353 1155 1353 1173 1353 1178 1353 1209 1353 1244 1353 1353 1353 1372 1353 1401 1354 2 1354 74 1354 84 1354 93 1354 95 1354 97 1354 126 1354 153 1354 194 1354 239 1354 247 1354 271 1354 282 1354 296 1354 315 1354 362 1354 407 1354 499 1354 564 1354 614 1354 654 1354 662 1354 670 1354 796 1354 801 1354 838 1354 858 1354 970 1354 975 1354 1001 1354 1002 1354 1036 1354 1050 1354 1105 1354 1157 1354 1227 1354 1248 1354 1329 1354 1354 1354 1384 1354 1394 1354 1395 1354 1478 1355 79 1355 125 1355 147 1355 189 1355 253 1355 272 1355 295 1355 305 1355 344 1355 373 1355 404 1355 478 1355 483 1355 484 1355 491 1355 556 1355 591 1355 600 1355 611 1355 624 1355 640 1355 684 1355 690 1355 694 1355 743 1355 799 1355 807 1355 814 1355 839 1355 860 1355 888 1355 910 1355 911 1355 978 1355 990 1355 993 1355 999 1355 1014 1355 1069 1355 1075 1355 1082 1355 1202 1355 1217 1355 1236 1355 1250 1355 1277 1355 1278 1355 1281 1355 1290 1355 1355 1355 1356 1355 1370 1355 1375 1355 1407 1355 1456 1355 1484 1356 79 1356 83 1356 144 1356 187 1356 217 1356 232 1356 253 1356 279 1356 305 1356 452 1356 478 1356 484 1356 526 1356 544 1356 567 1356 584 1356 591 1356 612 1356 640 1356 684 1356 690 1356 807 1356 814 1356 822 1356 839 1356 860 1356 875 1356 908 1356 940 1356 972 1356 990 1356 1078 1356 1082 1356 1142 1356 1216 1356 1217 1356 1229 1356 1236 1356 1250 1356 1290 1356 1313 1356 1348 1356 1355 1356 1356 1356 1361 1356 1370 1356 1375 1356 1498 1357 4 1357 71 1357 155 1357 248 1357 331 1357 469 1357 519 1357 632 1357 716 1357 738 1357 977 1357 1053 1357 1073 1357 1188 1357 1357 1357 1367 1357 1416 1357 1423 1357 1451 1357 1480 1358 44 1358 57 1358 72 1358 76 1358 135 1358 144 1358 147 1358 149 1358 189 1358 232 1358 253 1358 305 1358 344 1358 370 1358 375 1358 388 1358 397 1358 424 1358 455 1358 491 1358 556 1358 591 1358 611 1358 684 1358 733 1358 799 1358 860 1358 893 1358 990 1358 993 1358 1136 1358 1179 1358 1202 1358 1235 1358 1250 1358 1278 1358 1290 1358 1358 1358 1393 1358 1456 1359 38 1359 137 1359 174 1359 180 1359 216 1359 261 1359 269 1359 304 1359 322 1359 431 1359 506 1359 549 1359 590 1359 695 1359 745 1359 792 1359 980 1359 1017 1359 1047 1359 1065 1359 1067 1359 1089 1359 1125 1359 1141 1359 1209 1359 1219 1359 1234 1359 1359 1360 9 1360 15 1360 54 1360 121 1360 130 1360 158 1360 182 1360 205 1360 221 1360 229 1360 257 1360 262 1360 285 1360 351 1360 428 1360 462 1360 485 1360 490 1360 511 1360 533 1360 534 1360 536 1360 610 1360 618 1360 619 1360 637 1360 698 1360 701 1360 808 1360 823 1360 827 1360 837 1360 864 1360 1044 1360 1144 1360 1183 1360 1187 1360 1219 1360 1258 1360 1360 1360 1448 1361 72 1361 83 1361 187 1361 217 1361 223 1361 224 1361 279 1361 343 1361 371 1361 377 1361 389 1361 408 1361 452 1361 478 1361 483 1361 497 1361 524 1361 544 1361 547 1361 562 1361 567 1361 584 1361 592 1361 600 1361 638 1361 640 1361 807 1361 814 1361 844 1361 875 1361 906 1361 908 1361 972 1361 1034 1361 1068 1361 1078 1361 1098 1361 1099 1361 1142 1361 1180 1361 1198 1361 1216 1361 1225 1361 1236 1361 1250 1361 1299 1361 1313 1361 1356 1361 1361 1361 1373 1361 1407 1361 1474 1361 1496 1362 6 1362 29 1362 42 1362 48 1362 51 1362 94 1362 124 1362 131 1362 140 1362 172 1362 256 1362 303 1362 310 1362 313 1362 321 1362 339 1362 413 1362 459 1362 486 1362 512 1362 521 1362 545 1362 635 1362 664 1362 688 1362 695 1362 713 1362 718 1362 726 1362 729 1362 741 1362 746 1362 757 1362 772 1362 782 1362 810 1362 852 1362 880 1362 961 1362 1033 1362 1049 1362 1052 1362 1081 1362 1086 1362 1163 1362 1181 1362 1201 1362 1208 1362 1239 1362 1362 1362 1363 1362 1399 1363 6 1363 25 1363 42 1363 48 1363 70 1363 94 1363 108 1363 163 1363 172 1363 256 1363 273 1363 276 1363 303 1363 313 1363 374 1363 382 1363 406 1363 438 1363 498 1363 512 1363 635 1363 718 1363 722 1363 731 1363 782 1363 803 1363 810 1363 894 1363 961 1363 1011 1363 1031 1363 1032 1363 1052 1363 1055 1363 1181 1363 1201 1363 1208 1363 1228 1363 1239 1363 1263 1363 1362 1363 1363 1363 1399 1363 1488 1364 10 1364 23 1364 49 1364 50 1364 68 1364 75 1364 128 1364 141 1364 184 1364 203 1364 290 1364 294 1364 368 1364 376 1364 433 1364 443 1364 517 1364 538 1364 571 1364 573 1364 574 1364 582 1364 589 1364 657 1364 671 1364 673 1364 697 1364 770 1364 805 1364 836 1364 916 1364 930 1364 955 1364 1020 1364 1088 1364 1101 1364 1107 1364 1203 1364 1300 1364 1364 1364 1429 1364 1460 1364 1483 1365 59 1365 67 1365 161 1365 190 1365 335 1365 414 1365 435 1365 774 1365 840 1365 857 1365 1021 1365 1231 1365 1320 1365 1365 1365 1409 1365 1432 1365 1443 1365 1477 1365 1491 1365 1497 1366 43 1366 46 1366 104 1366 118 1366 176 1366 208 1366 287 1366 309 1366 369 1366 385 1366 456 1366 500 1366 532 1366 541 1366 557 1366 565 1366 651 1366 724 1366 747 1366 779 1366 878 1366 902 1366 927 1366 957 1366 1013 1366 1030 1366 1150 1366 1182 1366 1210 1366 1220 1366 1243 1366 1264 1366 1270 1366 1279 1366 1295 1366 1366 1366 1380 1366 1489 1367 4 1367 71 1367 148 1367 155 1367 248 1367 331 1367 469 1367 519 1367 548 1367 632 1367 716 1367 738 1367 977 1367 1053 1367 1073 1367 1130 1367 1188 1367 1255 1367 1328 1367 1357 1367 1367 1367 1416 1367 1423 1367 1451 1367 1480 1368 39 1368 46 1368 104 1368 109 1368 112 1368 118 1368 208 1368 258 1368 309 1368 346 1368 409 1368 500 1368 532 1368 724 1368 747 1368 878 1368 899 1368 954 1368 989 1368 1025 1368 1114 1368 1128 1368 1134 1368 1148 1368 1182 1368 1207 1368 1233 1368 1243 1368 1368 1368 1380 1369 5 1369 13 1369 14 1369 47 1369 85 1369 92 1369 101 1369 202 1369 218 1369 230 1369 240 1369 291 1369 365 1369 434 1369 441 1369 569 1369 603 1369 606 1369 609 1369 612 1369 620 1369 630 1369 730 1369 867 1369 870 1369 883 1369 999 1369 1018 1369 1028 1369 1076 1369 1108 1369 1129 1369 1159 1369 1206 1369 1236 1369 1331 1369 1369 1369 1461 1369 1472 1369 1476 1370 47 1370 76 1370 83 1370 135 1370 189 1370 217 1370 253 1370 295 1370 305 1370 373 1370 387 1370 408 1370 478 1370 483 1370 556 1370 567 1370 591 1370 600 1370 611 1370 612 1370 680 1370 684 1370 690 1370 743 1370 784 1370 814 1370 822 1370 839 1370 844 1370 911 1370 940 1370 978 1370 990 1370 1014 1370 1018 1370 1097 1370 1142 1370 1180 1370 1206 1370 1216 1370 1217 1370 1229 1370 1230 1370 1250 1370 1277 1370 1281 1370 1290 1370 1355 1370 1356 1370 1370 1370 1375 1370 1407 1370 1441 1370 1474 1370 1484 1370 1498 1371 0 1371 119 1371 197 1371 220 1371 238 1371 264 1371 298 1371 301 1371 330 1371 367 1371 398 1371 442 1371 482 1371 518 1371 560 1371 645 1371 650 1371 689 1371 731 1371 765 1371 794 1371 803 1371 824 1371 866 1371 872 1371 892 1371 983 1371 1031 1371 1083 1371 1085 1371 1145 1371 1147 1371 1214 1371 1222 1371 1228 1371 1260 1371 1263 1371 1271 1371 1305 1371 1371 1371 1398 1371 1400 1371 1468 1371 1488 1372 66 1372 96 1372 124 1372 127 1372 131 1372 162 1372 243 1372 261 1372 289 1372 356 1372 392 1372 479 1372 486 1372 501 1372 502 1372 539 1372 568 1372 649 1372 679 1372 705 1372 714 1372 726 1372 746 1372 753 1372 797 1372 831 1372 879 1372 881 1372 885 1372 942 1372 944 1372 946 1372 991 1372 1072 1372 1089 1372 1111 1372 1173 1372 1201 1372 1213 1372 1244 1372 1292 1372 1332 1372 1353 1372 1372 1373 14 1373 36 1373 55 1373 56 1373 83 1373 101 1373 164 1373 187 1373 218 1373 223 1373 224 1373 279 1373 291 1373 343 1373 371 1373 377 1373 389 1373 391 1373 408 1373 492 1373 497 1373 524 1373 544 1373 547 1373 562 1373 592 1373 603 1373 620 1373 638 1373 640 1373 648 1373 667 1373 730 1373 784 1373 844 1373 867 1373 870 1373 906 1373 940 1373 972 1373 1034 1373 1068 1373 1078 1373 1091 1373 1098 1373 1099 1373 1225 1373 1299 1373 1361 1373 1373 1373 1407 1373 1441 1373 1474 1373 1496 1374 10 1374 68 1374 141 1374 195 1374 299 1374 314 1374 342 1374 357 1374 368 1374 379 1374 504 1374 542 1374 551 1374 571 1374 582 1374 657 1374 687 1374 693 1374 697 1374 704 1374 749 1374 811 1374 904 1374 913 1374 915 1374 930 1374 943 1374 1008 1374 1088 1374 1095 1374 1107 1374 1109 1374 1168 1374 1189 1374 1240 1374 1246 1374 1269 1374 1275 1374 1300 1374 1323 1374 1338 1374 1352 1374 1374 1374 1420 1374 1437 1374 1460 1374 1495 1375 79 1375 189 1375 217 1375 232 1375 253 1375 279 1375 295 1375 305 1375 344 1375 373 1375 401 1375 404 1375 408 1375 452 1375 478 1375 484 1375 526 1375 544 1375 556 1375 567 1375 584 1375 591 1375 612 1375 624 1375 640 1375 684 1375 690 1375 743 1375 807 1375 814 1375 822 1375 839 1375 860 1375 875 1375 940 1375 978 1375 990 1375 1014 1375 1075 1375 1082 1375 1142 1375 1196 1375 1216 1375 1217 1375 1229 1375 1235 1375 1236 1375 1250 1375 1281 1375 1290 1375 1313 1375 1348 1375 1355 1375 1356 1375 1370 1375 1375 1375 1498 1376 32 1376 34 1376 40 1376 139 1376 150 1376 171 1376 213 1376 237 1376 307 1376 366 1376 423 1376 439 1376 453 1376 495 1376 783 1376 813 1376 833 1376 835 1376 848 1376 859 1376 868 1376 869 1376 889 1376 926 1376 936 1376 1041 1376 1061 1376 1103 1376 1110 1376 1138 1376 1237 1376 1247 1376 1262 1376 1276 1376 1284 1376 1296 1376 1322 1376 1347 1376 1376 1376 1381 1376 1406 1377 117 1377 120 1377 239 1377 271 1377 275 1377 293 1377 311 1377 353 1377 361 1377 372 1377 415 1377 450 1377 564 1377 647 1377 677 1377 719 1377 793 1377 971 1377 982 1377 1023 1377 1056 1377 1058 1377 1105 1377 1157 1377 1253 1377 1282 1377 1307 1377 1377 1377 1394 1377 1395 1377 1424 1377 1435 1377 1447 1378 82 1378 200 1378 233 1378 244 1378 283 1378 348 1378 355 1378 399 1378 575 1378 580 1378 623 1378 625 1378 631 1378 681 1378 708 1378 795 1378 865 1378 921 1378 980 1378 1007 1378 1059 1378 1064 1378 1113 1378 1199 1378 1271 1378 1316 1378 1351 1378 1378 1378 1403 1378 1467 1378 1485 1378 1494 1379 190 1379 195 1379 204 1379 294 1379 574 1379 639 1379 836 1379 841 1379 919 1379 930 1379 953 1379 987 1379 1169 1379 1203 1379 1273 1379 1379 1379 1454 1379 1458 1379 1460 1380 43 1380 46 1380 77 1380 104 1380 105 1380 109 1380 112 1380 118 1380 154 1380 176 1380 208 1380 258 1380 287 1380 309 1380 369 1380 385 1380 409 1380 456 1380 500 1380 532 1380 541 1380 557 1380 565 1380 633 1380 651 1380 710 1380 724 1380 747 1380 779 1380 826 1380 861 1380 927 1380 954 1380 957 1380 1013 1380 1025 1380 1030 1380 1114 1380 1128 1380 1182 1380 1210 1380 1243 1380 1270 1380 1279 1380 1295 1380 1310 1380 1366 1380 1368 1380 1380 1380 1439 1380 1489 1381 32 1381 40 1381 115 1381 139 1381 150 1381 171 1381 177 1381 207 1381 213 1381 237 1381 248 1381 307 1381 317 1381 366 1381 432 1381 439 1381 453 1381 495 1381 588 1381 706 1381 744 1381 835 1381 848 1381 853 1381 859 1381 868 1381 869 1381 889 1381 926 1381 936 1381 1041 1381 1061 1381 1103 1381 1138 1381 1237 1381 1247 1381 1262 1381 1276 1381 1296 1381 1322 1381 1347 1381 1376 1381 1381 1381 1406 1381 1482 1382 15 1382 19 1382 54 1382 73 1382 121 1382 130 1382 152 1382 205 1382 259 1382 285 1382 312 1382 338 1382 465 1382 536 1382 560 1382 587 1382 599 1382 655 1382 685 1382 698 1382 701 1382 734 1382 752 1382 761 1382 778 1382 802 1382 815 1382 837 1382 871 1382 892 1382 905 1382 1044 1382 1118 1382 1124 1382 1153 1382 1212 1382 1214 1382 1221 1382 1330 1382 1343 1382 1382 1382 1400 1382 1413 1382 1419 1382 1442 1382 1455 1382 1463 1382 1486 1383 62 1383 104 1383 105 1383 109 1383 208 1383 254 1383 346 1383 410 1383 426 1383 456 1383 532 1383 633 1383 651 1383 723 1383 826 1383 878 1383 899 1383 917 1383 989 1383 1030 1383 1104 1383 1149 1383 1207 1383 1220 1383 1270 1383 1310 1383 1350 1383 1383 1384 2 1384 93 1384 95 1384 97 1384 114 1384 153 1384 197 1384 220 1384 247 1384 296 1384 362 1384 384 1384 407 1384 463 1384 499 1384 564 1384 654 1384 662 1384 663 1384 721 1384 780 1384 796 1384 825 1384 970 1384 982 1384 1001 1384 1036 1384 1050 1384 1105 1384 1186 1384 1194 1384 1242 1384 1248 1384 1256 1384 1329 1384 1354 1384 1384 1384 1385 1384 1394 1385 2 1385 25 1385 69 1385 111 1385 117 1385 146 1385 153 1385 181 1385 220 1385 353 1385 362 1385 450 1385 454 1385 463 1385 516 1385 523 1385 692 1385 780 1385 794 1385 894 1385 970 1385 982 1385 1012 1385 1055 1385 1056 1385 1083 1385 1105 1385 1133 1385 1186 1385 1194 1385 1253 1385 1256 1385 1260 1385 1298 1385 1384 1385 1385 1385 1396 1385 1447 1385 1488 1386 22 1386 156 1386 159 1386 196 1386 266 1386 345 1386 378 1386 383 1386 390 1386 400 1386 403 1386 448 1386 449 1386 507 1386 530 1386 543 1386 570 1386 605 1386 615 1386 621 1386 641 1386 707 1386 739 1386 763 1386 764 1386 791 1386 847 1386 854 1386 862 1386 873 1386 920 1386 947 1386 948 1386 960 1386 994 1386 1005 1386 1037 1386 1090 1386 1126 1386 1127 1386 1162 1386 1172 1386 1174 1386 1176 1386 1252 1386 1287 1386 1324 1386 1325 1386 1386 1386 1434 1386 1436 1386 1444 1386 1493 1387 1 1387 100 1387 140 1387 246 1387 260 1387 320 1387 393 1387 417 1387 445 1387 596 1387 616 1387 653 1387 672 1387 688 1387 712 1387 740 1387 754 1387 762 1387 772 1387 806 1387 855 1387 856 1387 880 1387 922 1387 945 1387 974 1387 998 1387 1042 1387 1049 1387 1094 1387 1139 1387 1158 1387 1177 1387 1181 1387 1195 1387 1306 1387 1315 1387 1342 1387 1387 1387 1397 1387 1438 1387 1453 1387 1470 1387 1473 1388 37 1388 170 1388 219 1388 242 1388 319 1388 326 1388 350 1388 360 1388 416 1388 418 1388 457 1388 508 1388 555 1388 559 1388 589 1388 593 1388 622 1388 639 1388 644 1388 703 1388 732 1388 766 1388 770 1388 777 1388 800 1388 886 1388 933 1388 955 1388 997 1388 1010 1388 1015 1388 1020 1388 1071 1388 1087 1388 1112 1388 1154 1388 1161 1388 1166 1388 1167 1388 1200 1388 1205 1388 1257 1388 1268 1388 1311 1388 1346 1388 1388 1388 1426 1388 1431 1388 1479 1389 9 1389 15 1389 54 1389 158 1389 182 1389 205 1389 221 1389 229 1389 381 1389 462 1389 473 1389 485 1389 490 1389 618 1389 735 1389 823 1389 837 1389 849 1389 864 1389 1144 1389 1153 1389 1258 1389 1389 1389 1448 1389 1452 1389 1463 1390 30 1390 53 1390 58 1390 78 1390 86 1390 90 1390 102 1390 175 1390 191 1390 212 1390 216 1390 270 1390 286 1390 323 1390 349 1390 440 1390 444 1390 460 1390 464 1390 511 1390 537 1390 549 1390 563 1390 580 1390 610 1390 623 1390 625 1390 631 1390 720 1390 761 1390 785 1390 812 1390 829 1390 884 1390 905 1390 923 1390 967 1390 1003 1390 1035 1390 1057 1390 1124 1390 1141 1390 1238 1390 1249 1390 1334 1390 1336 1390 1341 1390 1390 1390 1418 1390 1459 1390 1481 1391 74 1391 113 1391 132 1391 166 1391 201 1391 227 1391 231 1391 241 1391 306 1391 324 1391 384 1391 386 1391 420 1391 472 1391 474 1391 481 1391 515 1391 553 1391 554 1391 566 1391 581 1391 696 1391 723 1391 728 1391 748 1391 798 1391 804 1391 818 1391 924 1391 1002 1391 1096 1391 1104 1391 1143 1391 1232 1391 1254 1391 1259 1391 1272 1391 1285 1391 1302 1391 1303 1391 1391 1392 127 1392 228 1392 267 1392 289 1392 318 1392 513 1392 535 1392 679 1392 834 1392 925 1392 946 1392 965 1392 979 1392 988 1392 1016 1392 1111 1392 1215 1392 1241 1392 1286 1392 1321 1392 1392 1392 1408 1392 1449 1392 1471 1393 44 1393 57 1393 72 1393 76 1393 135 1393 144 1393 149 1393 224 1393 232 1393 370 1393 388 1393 391 1393 397 1393 401 1393 424 1393 455 1393 491 1393 520 1393 556 1393 591 1393 611 1393 733 1393 844 1393 860 1393 893 1393 911 1393 1136 1393 1179 1393 1230 1393 1235 1393 1358 1393 1393 1394 2 1394 74 1394 84 1394 93 1394 95 1394 120 1394 126 1394 153 1394 194 1394 201 1394 231 1394 239 1394 241 1394 271 1394 282 1394 296 1394 311 1394 315 1394 361 1394 450 1394 463 1394 515 1394 516 1394 564 1394 654 1394 662 1394 719 1394 801 1394 838 1394 858 1394 970 1394 971 1394 975 1394 1001 1394 1023 1394 1036 1394 1050 1394 1056 1394 1058 1394 1116 1394 1119 1394 1122 1394 1157 1394 1194 1394 1248 1394 1253 1394 1280 1394 1282 1394 1307 1394 1354 1394 1377 1394 1384 1394 1394 1394 1395 1394 1424 1394 1435 1394 1478 1395 93 1395 120 1395 239 1395 271 1395 311 1395 315 1395 361 1395 450 1395 463 1395 564 1395 647 1395 677 1395 719 1395 825 1395 858 1395 1023 1395 1050 1395 1056 1395 1058 1395 1253 1395 1307 1395 1354 1395 1377 1395 1394 1395 1395 1395 1424 1395 1435 1396 2 1396 25 1396 69 1396 93 1396 95 1396 111 1396 117 1396 119 1396 126 1396 153 1396 227 1396 231 1396 247 1396 282 1396 296 1396 353 1396 362 1396 384 1396 427 1396 450 1396 454 1396 463 1396 516 1396 564 1396 794 1396 796 1396 801 1396 838 1396 970 1396 982 1396 1001 1396 1002 1396 1012 1396 1050 1396 1056 1396 1083 1396 1105 1396 1119 1396 1122 1396 1133 1396 1186 1396 1194 1396 1222 1396 1253 1396 1256 1396 1260 1396 1280 1396 1282 1396 1298 1396 1385 1396 1396 1396 1478 1397 1 1397 18 1397 100 1397 260 1397 265 1397 417 1397 421 1397 616 1397 672 1397 712 1397 717 1397 806 1397 850 1397 856 1397 876 1397 907 1397 945 1397 998 1397 1074 1397 1117 1397 1195 1397 1226 1397 1306 1397 1317 1397 1337 1397 1342 1397 1387 1397 1397 1397 1438 1397 1453 1397 1473 1398 0 1398 29 1398 51 1398 186 1398 220 1398 358 1398 367 1398 419 1398 437 1398 545 1398 560 1398 597 1398 676 1398 699 1398 715 1398 729 1398 768 1398 821 1398 828 1398 872 1398 895 1398 973 1398 996 1398 1083 1398 1197 1398 1371 1398 1398 1399 6 1399 29 1399 42 1399 45 1399 48 1399 51 1399 70 1399 108 1399 256 1399 273 1399 278 1399 303 1399 339 1399 363 1399 437 1399 438 1399 467 1399 512 1399 521 1399 635 1399 664 1399 718 1399 722 1399 729 1399 731 1399 782 1399 810 1399 845 1399 855 1399 880 1399 961 1399 1033 1399 1052 1399 1081 1399 1086 1399 1163 1399 1164 1399 1201 1399 1208 1399 1228 1399 1239 1399 1263 1399 1349 1399 1362 1399 1363 1399 1399 1399 1466 1399 1487 1399 1488 1400 0 1400 24 1400 73 1400 152 1400 197 1400 200 1400 238 1400 259 1400 270 1400 298 1400 301 1400 312 1400 327 1400 330 1400 338 1400 442 1400 475 1400 518 1400 560 1400 629 1400 655 1400 734 1400 752 1400 765 1400 771 1400 778 1400 815 1400 824 1400 866 1400 892 1400 983 1400 1085 1400 1113 1400 1124 1400 1145 1400 1147 1400 1212 1400 1214 1400 1266 1400 1271 1400 1305 1400 1330 1400 1371 1400 1382 1400 1400 1400 1412 1400 1413 1400 1468 1400 1486 1401 116 1401 137 1401 145 1401 174 1401 192 1401 261 1401 323 1401 356 1401 539 1401 568 1401 714 1401 885 1401 938 1401 944 1401 985 1401 1187 1401 1353 1401 1401 1401 1411 1402 7 1402 20 1402 31 1402 123 1402 170 1402 242 1402 300 1402 333 1402 336 1402 558 1402 593 1402 607 1402 703 1402 736 1402 763 1402 916 1402 1071 1402 1100 1402 1106 1402 1112 1402 1127 1402 1156 1402 1161 1402 1171 1402 1184 1402 1188 1402 1211 1402 1224 1402 1346 1402 1402 1402 1404 1402 1462 1402 1490 1403 24 1403 28 1403 116 1403 206 1403 238 1403 267 1403 325 1403 355 1403 425 1403 429 1403 482 1403 502 1403 539 1403 552 1403 580 1403 625 1403 629 1403 652 1403 689 1403 708 1403 715 1403 755 1403 824 1403 931 1403 944 1403 985 1403 995 1403 1007 1403 1059 1403 1064 1403 1178 1403 1204 1403 1244 1403 1261 1403 1314 1403 1316 1403 1349 1403 1378 1403 1403 1403 1499 1404 20 1404 31 1404 87 1404 148 1404 170 1404 204 1404 292 1404 294 1404 300 1404 333 1404 336 1404 403 1404 519 1404 538 1404 548 1404 558 1404 607 1404 671 1404 763 1404 862 1404 948 1404 960 1404 1127 1404 1156 1404 1161 1404 1184 1404 1188 1404 1224 1404 1402 1404 1404 1404 1458 1404 1462 1404 1490 1405 39 1405 166 1405 168 1405 215 1405 302 1405 334 1405 409 1405 426 1405 461 1405 471 1405 472 1405 489 1405 553 1405 696 1405 710 1405 748 1405 899 1405 954 1405 1040 1405 1096 1405 1134 1405 1143 1405 1191 1405 1233 1405 1254 1405 1285 1405 1303 1405 1319 1405 1405 1405 1427 1405 1469 1406 32 1406 40 1406 115 1406 139 1406 150 1406 171 1406 177 1406 237 1406 307 1406 366 1406 453 1406 833 1406 835 1406 869 1406 926 1406 1061 1406 1103 1406 1138 1406 1245 1406 1247 1406 1262 1406 1276 1406 1296 1406 1376 1406 1381 1406 1406 1406 1482 1407 47 1407 72 1407 144 1407 223 1407 224 1407 232 1407 279 1407 295 1407 343 1407 371 1407 389 1407 391 1407 408 1407 478 1407 483 1407 526 1407 592 1407 600 1407 638 1407 640 1407 648 1407 680 1407 684 1407 784 1407 814 1407 822 1407 839 1407 844 1407 888 1407 906 1407 910 1407 911 1407 940 1407 972 1407 978 1407 1014 1407 1068 1407 1078 1407 1097 1407 1099 1407 1142 1407 1180 1407 1216 1407 1229 1407 1281 1407 1299 1407 1355 1407 1361 1407 1370 1407 1373 1407 1407 1407 1441 1407 1474 1407 1498 1408 41 1408 81 1408 99 1408 106 1408 151 1408 199 1408 245 1408 318 1408 329 1408 337 1408 347 1408 393 1408 430 1408 487 1408 496 1408 505 1408 510 1408 513 1408 535 1408 550 1408 585 1408 596 1408 602 1408 665 1408 686 1408 754 1408 787 1408 790 1408 820 1408 834 1408 922 1408 929 1408 949 1408 950 1408 965 1408 968 1408 986 1408 1000 1408 1019 1408 1042 1408 1048 1408 1070 1408 1152 1408 1190 1408 1241 1408 1251 1408 1286 1408 1304 1408 1392 1408 1408 1408 1425 1408 1428 1408 1445 1408 1449 1408 1465 1408 1471 1409 59 1409 67 1409 161 1409 190 1409 335 1409 414 1409 435 1409 774 1409 840 1409 857 1409 1021 1409 1231 1409 1320 1409 1365 1409 1409 1409 1432 1409 1443 1409 1477 1409 1491 1409 1497 1410 27 1410 89 1410 127 1410 162 1410 228 1410 243 1410 289 1410 486 1410 501 1410 679 1410 741 1410 775 1410 786 1410 789 1410 830 1410 831 1410 909 1410 921 1410 925 1410 929 1410 946 1410 988 1410 991 1410 1048 1410 1111 1410 1213 1410 1410 1410 1414 1410 1425 1410 1446 1411 145 1411 261 1411 356 1411 568 1411 714 1411 751 1411 938 1411 1401 1411 1411 1411 1497 1412 185 1412 197 1412 238 1412 264 1412 281 1412 288 1412 298 1412 330 1412 338 1412 398 1412 442 1412 480 1412 518 1412 546 1412 587 1412 598 1412 650 1412 663 1412 674 1412 758 1412 760 1412 765 1412 803 1412 824 1412 842 1412 866 1412 871 1412 892 1412 996 1412 1011 1412 1031 1412 1079 1412 1085 1412 1145 1412 1147 1412 1218 1412 1222 1412 1242 1412 1266 1412 1271 1412 1305 1412 1400 1412 1412 1412 1413 1412 1440 1413 73 1413 130 1413 152 1413 185 1413 200 1413 259 1413 264 1413 270 1413 312 1413 338 1413 359 1413 398 1413 436 1413 442 1413 475 1413 518 1413 560 1413 587 1413 650 1413 655 1413 734 1413 752 1413 758 1413 761 1413 771 1413 778 1413 815 1413 897 1413 905 1413 959 1413 967 1413 1079 1413 1085 1413 1102 1413 1113 1413 1124 1413 1145 1413 1212 1413 1214 1413 1266 1413 1271 1413 1305 1413 1327 1413 1330 1413 1382 1413 1400 1413 1412 1413 1413 1413 1486 1414 27 1414 28 1414 89 1414 96 1414 127 1414 162 1414 228 1414 243 1414 289 1414 328 1414 354 1414 479 1414 501 1414 552 1414 561 1414 634 1414 652 1414 678 1414 711 1414 714 1414 775 1414 786 1414 789 1414 797 1414 830 1414 831 1414 879 1414 887 1414 890 1414 909 1414 921 1414 942 1414 968 1414 988 1414 991 1414 995 1414 1000 1414 1047 1414 1072 1414 1092 1414 1111 1414 1120 1414 1213 1414 1410 1414 1414 1414 1446 1415 129 1415 180 1415 192 1415 262 1415 269 1415 286 1415 340 1415 352 1415 395 1415 460 1415 506 1415 590 1415 637 1415 700 1415 745 1415 769 1415 808 1415 815 1415 851 1415 967 1415 1065 1415 1187 1415 1219 1415 1249 1415 1333 1415 1336 1415 1415 1415 1418 1416 16 1416 71 1416 136 1416 177 1416 207 1416 248 1416 274 1416 297 1416 331 1416 390 1416 423 1416 432 1416 469 1416 519 1416 548 1416 588 1416 632 1416 641 1416 706 1416 738 1416 964 1416 977 1416 1053 1416 1073 1416 1130 1416 1252 1416 1255 1416 1274 1416 1328 1416 1357 1416 1367 1416 1416 1416 1422 1416 1423 1416 1451 1416 1480 1417 29 1417 41 1417 45 1417 51 1417 70 1417 98 1417 151 1417 185 1417 186 1417 199 1417 256 1417 278 1417 281 1417 339 1417 359 1417 367 1417 380 1417 419 1417 437 1417 470 1417 496 1417 545 1417 594 1417 597 1417 635 1417 645 1417 661 1417 665 1417 676 1417 682 1417 683 1417 686 1417 699 1417 729 1417 731 1417 760 1417 828 1417 832 1417 872 1417 895 1417 921 1417 929 1417 931 1417 949 1417 950 1417 965 1417 986 1417 1011 1417 1060 1417 1086 1417 1152 1417 1197 1417 1208 1417 1239 1417 1304 1417 1417 1417 1440 1417 1487 1418 30 1418 38 1418 53 1418 78 1418 212 1418 216 1418 270 1418 286 1418 308 1418 349 1418 431 1418 460 1418 464 1418 511 1418 534 1418 549 1418 631 1418 637 1418 720 1418 761 1418 792 1418 812 1418 829 1418 874 1418 923 1418 1057 1418 1065 1418 1084 1418 1219 1418 1238 1418 1249 1418 1336 1418 1351 1418 1390 1418 1415 1418 1418 1418 1459 1418 1481 1419 3 1419 8 1419 19 1419 64 1419 259 1419 288 1419 312 1419 330 1419 473 1419 499 1419 527 1419 587 1419 599 1419 614 1419 628 1419 709 1419 734 1419 765 1419 802 1419 816 1419 849 1419 871 1419 892 1419 951 1419 1132 1419 1214 1419 1242 1419 1382 1419 1419 1419 1442 1419 1463 1420 33 1420 61 1420 110 1420 141 1420 169 1420 195 1420 299 1420 314 1420 341 1420 342 1420 364 1420 379 1420 447 1420 458 1420 493 1420 504 1420 514 1420 571 1420 578 1420 687 1420 704 1420 749 1420 811 1420 904 1420 913 1420 915 1420 1109 1420 1168 1420 1189 1420 1269 1420 1275 1420 1312 1420 1338 1420 1374 1420 1420 1420 1421 1420 1437 1420 1495 1421 33 1421 61 1421 103 1421 110 1421 169 1421 341 1421 342 1421 364 1421 447 1421 458 1421 493 1421 504 1421 542 1421 586 1421 687 1421 704 1421 749 1421 773 1421 843 1421 904 1421 913 1421 915 1421 941 1421 943 1421 956 1421 1095 1421 1109 1421 1168 1421 1269 1421 1297 1421 1312 1421 1338 1421 1345 1421 1420 1421 1421 1421 1437 1422 34 1422 136 1422 207 1422 274 1422 297 1422 390 1422 423 1422 432 1422 439 1422 469 1422 495 1422 548 1422 588 1422 641 1422 706 1422 738 1422 813 1422 868 1422 889 1422 964 1422 977 1422 1041 1422 1110 1422 1130 1422 1174 1422 1252 1422 1255 1422 1274 1422 1284 1422 1322 1422 1328 1422 1416 1422 1422 1422 1480 1422 1493 1423 4 1423 71 1423 155 1423 248 1423 331 1423 469 1423 519 1423 548 1423 632 1423 716 1423 738 1423 977 1423 1053 1423 1073 1423 1188 1423 1357 1423 1367 1423 1416 1423 1423 1423 1451 1423 1480 1424 84 1424 120 1424 239 1424 271 1424 275 1424 293 1424 311 1424 315 1424 361 1424 647 1424 677 1424 719 1424 793 1424 858 1424 971 1424 1006 1424 1023 1424 1056 1424 1058 1424 1157 1424 1307 1424 1377 1424 1394 1424 1395 1424 1424 1424 1435 1425 28 1425 41 1425 81 1425 89 1425 124 1425 138 1425 151 1425 268 1425 318 1425 382 1425 406 1425 470 1425 496 1425 501 1425 505 1425 510 1425 513 1425 535 1425 540 1425 678 1425 681 1425 686 1425 713 1425 781 1425 790 1425 795 1425 817 1425 830 1425 831 1425 834 1425 865 1425 896 1425 921 1425 929 1425 950 1425 965 1425 986 1425 995 1425 1009 1425 1048 1425 1060 1425 1160 1425 1199 1425 1251 1425 1304 1425 1408 1425 1410 1425 1425 1425 1445 1425 1446 1425 1449 1426 31 1426 123 1426 178 1426 219 1426 319 1426 350 1426 360 1426 402 1426 416 1426 418 1426 422 1426 457 1426 593 1426 617 1426 622 1426 644 1426 732 1426 736 1426 777 1426 886 1426 933 1426 935 1426 958 1426 962 1426 997 1426 1015 1426 1112 1426 1154 1426 1161 1426 1171 1426 1205 1426 1211 1426 1268 1426 1294 1426 1311 1426 1346 1426 1388 1426 1426 1426 1431 1426 1433 1426 1479 1427 166 1427 168 1427 173 1427 334 1427 426 1427 461 1427 467 1427 471 1427 472 1427 553 1427 696 1427 748 1427 924 1427 966 1427 1040 1427 1096 1427 1143 1427 1191 1427 1254 1427 1285 1427 1303 1427 1308 1427 1319 1427 1329 1427 1405 1427 1427 1427 1469 1428 99 1428 106 1428 249 1428 260 1428 329 1428 337 1428 393 1428 417 1428 421 1428 445 1428 487 1428 550 1428 585 1428 596 1428 602 1428 616 1428 653 1428 656 1428 672 1428 712 1428 717 1428 754 1428 806 1428 820 1428 855 1428 922 1428 968 1428 1000 1428 1042 1428 1070 1428 1077 1428 1175 1428 1190 1428 1241 1428 1315 1428 1317 1428 1408 1428 1428 1428 1438 1428 1445 1428 1470 1429 10 1429 23 1429 49 1429 184 1429 198 1429 290 1429 376 1429 457 1429 503 1429 517 1429 542 1429 574 1429 582 1429 601 1429 627 1429 643 1429 666 1429 725 1429 750 1429 770 1429 800 1429 898 1429 933 1429 1008 1429 1020 1429 1095 1429 1166 1429 1246 1429 1323 1429 1344 1429 1364 1429 1429 1429 1433 1429 1457 1429 1492 1430 142 1430 157 1430 316 1430 819 1430 877 1430 914 1430 1043 1430 1121 1430 1430 1431 7 1431 37 1431 91 1431 143 1431 148 1431 167 1431 219 1431 242 1431 326 1431 350 1431 360 1431 378 1431 416 1431 418 1431 443 1431 446 1431 508 1431 555 1431 574 1431 604 1431 613 1431 617 1431 621 1431 636 1431 639 1431 644 1431 669 1431 732 1431 777 1431 800 1431 886 1431 900 1431 903 1431 928 1431 933 1431 935 1431 958 1431 987 1431 1010 1431 1015 1431 1146 1431 1151 1431 1154 1431 1156 1431 1161 1431 1167 1431 1171 1431 1200 1431 1205 1431 1211 1431 1268 1431 1273 1431 1289 1431 1311 1431 1326 1431 1346 1431 1388 1431 1426 1431 1431 1431 1450 1431 1464 1431 1479 1432 59 1432 67 1432 161 1432 190 1432 335 1432 414 1432 435 1432 774 1432 840 1432 841 1432 857 1432 1021 1432 1231 1432 1320 1432 1365 1432 1409 1432 1432 1432 1443 1432 1454 1432 1477 1432 1491 1432 1497 1433 10 1433 20 1433 23 1433 31 1433 37 1433 49 1433 75 1433 123 1433 128 1433 170 1433 178 1433 198 1433 290 1433 357 1433 360 1433 376 1433 402 1433 422 1433 433 1433 443 1433 457 1433 503 1433 517 1433 551 1433 555 1433 559 1433 574 1433 582 1433 593 1433 622 1433 657 1433 673 1433 703 1433 725 1433 756 1433 770 1433 800 1433 805 1433 886 1433 916 1433 933 1433 955 1433 1020 1433 1100 1433 1101 1433 1106 1433 1112 1433 1166 1433 1203 1433 1211 1433 1257 1433 1268 1433 1311 1433 1346 1433 1426 1433 1429 1433 1433 1433 1457 1433 1462 1433 1490 1434 136 1434 159 1434 196 1434 252 1434 345 1434 383 1434 390 1434 400 1434 448 1434 543 1434 588 1434 605 1434 615 1434 641 1434 707 1434 739 1434 764 1434 783 1434 813 1434 847 1434 920 1434 947 1434 960 1434 1090 1434 1126 1434 1172 1434 1174 1434 1255 1434 1324 1434 1325 1434 1386 1434 1434 1434 1436 1434 1493 1435 84 1435 93 1435 120 1435 239 1435 271 1435 293 1435 311 1435 315 1435 361 1435 515 1435 564 1435 647 1435 677 1435 719 1435 858 1435 971 1435 975 1435 1023 1435 1058 1435 1157 1435 1248 1435 1307 1435 1377 1435 1394 1435 1395 1435 1424 1435 1435 1436 22 1436 156 1436 159 1436 196 1436 252 1436 345 1436 383 1436 390 1436 396 1436 400 1436 448 1436 449 1436 530 1436 543 1436 548 1436 588 1436 605 1436 615 1436 641 1436 707 1436 739 1436 763 1436 764 1436 847 1436 873 1436 920 1436 947 1436 948 1436 960 1436 964 1436 994 1436 1005 1436 1037 1436 1090 1436 1126 1436 1172 1436 1174 1436 1252 1436 1267 1436 1287 1436 1324 1436 1325 1436 1386 1436 1434 1436 1436 1436 1493 1437 10 1437 33 1437 50 1437 61 1437 110 1437 141 1437 169 1437 195 1437 299 1437 314 1437 341 1437 342 1437 364 1437 379 1437 447 1437 458 1437 493 1437 504 1437 514 1437 571 1437 578 1437 586 1437 687 1437 704 1437 749 1437 773 1437 811 1437 843 1437 904 1437 913 1437 915 1437 941 1437 943 1437 956 1437 1095 1437 1109 1437 1168 1437 1189 1437 1269 1437 1275 1437 1312 1437 1338 1437 1345 1437 1352 1437 1374 1437 1420 1437 1421 1437 1437 1437 1495 1438 100 1438 246 1438 260 1438 320 1438 393 1438 417 1438 445 1438 596 1438 616 1438 653 1438 672 1438 688 1438 712 1438 740 1438 751 1438 754 1438 759 1438 762 1438 806 1438 855 1438 856 1438 880 1438 922 1438 945 1438 974 1438 1042 1438 1077 1438 1094 1438 1139 1438 1195 1438 1306 1438 1315 1438 1317 1438 1337 1438 1387 1438 1397 1438 1428 1438 1438 1438 1453 1438 1470 1438 1473 1439 39 1439 43 1439 46 1439 60 1439 77 1439 104 1439 109 1439 112 1439 154 1439 208 1439 280 1439 369 1439 385 1439 410 1439 500 1439 541 1439 557 1439 633 1439 724 1439 747 1439 779 1439 861 1439 878 1439 891 1439 902 1439 927 1439 957 1439 976 1439 1013 1439 1025 1439 1128 1439 1134 1439 1148 1439 1207 1439 1210 1439 1279 1439 1301 1439 1310 1439 1380 1439 1439 1440 98 1440 185 1440 186 1440 288 1440 359 1440 367 1440 398 1440 419 1440 437 1440 480 1440 529 1440 546 1440 587 1440 597 1440 598 1440 645 1440 650 1440 661 1440 663 1440 665 1440 676 1440 682 1440 683 1440 721 1440 760 1440 842 1440 996 1440 1019 1440 1060 1440 1079 1440 1197 1440 1218 1440 1412 1440 1417 1440 1440 1440 1465 1441 14 1441 72 1441 79 1441 135 1441 189 1441 223 1441 232 1441 279 1441 295 1441 343 1441 371 1441 373 1441 387 1441 389 1441 391 1441 408 1441 478 1441 483 1441 526 1441 556 1441 592 1441 600 1441 611 1441 638 1441 640 1441 648 1441 680 1441 684 1441 690 1441 694 1441 784 1441 807 1441 814 1441 822 1441 839 1441 844 1441 906 1441 910 1441 911 1441 940 1441 972 1441 978 1441 1014 1441 1068 1441 1078 1441 1082 1441 1097 1441 1099 1441 1142 1441 1180 1441 1196 1441 1198 1441 1206 1441 1217 1441 1229 1441 1230 1441 1277 1441 1281 1441 1299 1441 1370 1441 1373 1441 1407 1441 1441 1441 1474 1441 1484 1442 19 1442 205 1442 222 1442 259 1442 285 1442 288 1442 312 1442 436 1442 465 1442 587 1442 655 1442 685 1442 734 1442 778 1442 802 1442 871 1442 892 1442 934 1442 1066 1442 1102 1442 1113 1442 1118 1442 1124 1442 1153 1442 1212 1442 1214 1442 1221 1442 1242 1442 1327 1442 1330 1442 1340 1442 1343 1442 1382 1442 1419 1442 1442 1442 1452 1442 1463 1442 1486 1443 59 1443 67 1443 161 1443 190 1443 335 1443 414 1443 435 1443 774 1443 840 1443 857 1443 1021 1443 1231 1443 1320 1443 1365 1443 1409 1443 1432 1443 1443 1443 1477 1443 1491 1443 1497 1444 7 1444 22 1444 107 1444 148 1444 156 1444 266 1444 378 1444 396 1444 446 1444 449 1444 507 1444 530 1444 543 1444 558 1444 570 1444 604 1444 607 1444 613 1444 621 1444 669 1444 739 1444 763 1444 791 1444 854 1444 862 1444 873 1444 900 1444 903 1444 920 1444 935 1444 937 1444 948 1444 994 1444 1005 1444 1071 1444 1090 1444 1146 1444 1156 1444 1162 1444 1176 1444 1184 1444 1224 1444 1289 1444 1294 1444 1324 1444 1326 1444 1386 1444 1444 1444 1450 1444 1464 1445 41 1445 81 1445 94 1445 99 1445 134 1445 245 1445 318 1445 329 1445 337 1445 393 1445 417 1445 445 1445 459 1445 487 1445 496 1445 501 1445 505 1445 510 1445 513 1445 535 1445 585 1445 596 1445 686 1445 713 1445 717 1445 754 1445 762 1445 790 1445 820 1445 834 1445 890 1445 912 1445 918 1445 922 1445 929 1445 946 1445 950 1445 965 1445 968 1445 988 1445 1000 1445 1042 1445 1045 1445 1048 1445 1070 1445 1077 1445 1139 1445 1190 1445 1226 1445 1241 1445 1251 1445 1286 1445 1304 1445 1315 1445 1408 1445 1425 1445 1428 1445 1445 1445 1470 1445 1471 1446 27 1446 28 1446 89 1446 162 1446 268 1446 289 1446 328 1446 444 1446 470 1446 479 1446 505 1446 552 1446 634 1446 652 1446 678 1446 681 1446 711 1446 775 1446 776 1446 786 1446 789 1446 795 1446 830 1446 865 1446 887 1446 890 1446 896 1446 909 1446 921 1446 965 1446 968 1446 991 1446 995 1446 1092 1446 1120 1446 1140 1446 1160 1446 1213 1446 1316 1446 1410 1446 1414 1446 1425 1446 1446 1447 2 1447 25 1447 117 1447 181 1447 220 1447 247 1447 273 1447 353 1447 362 1447 372 1447 384 1447 450 1447 454 1447 463 1447 523 1447 692 1447 794 1447 894 1447 970 1447 982 1447 1055 1447 1056 1447 1083 1447 1105 1447 1186 1447 1253 1447 1256 1447 1282 1447 1298 1447 1307 1447 1377 1447 1385 1447 1447 1447 1488 1448 9 1448 15 1448 54 1448 73 1448 158 1448 182 1448 205 1448 221 1448 229 1448 262 1448 285 1448 351 1448 381 1448 462 1448 473 1448 485 1448 490 1448 599 1448 618 1448 698 1448 735 1448 808 1448 823 1448 827 1448 837 1448 864 1448 1044 1448 1144 1448 1153 1448 1183 1448 1221 1448 1258 1448 1360 1448 1389 1448 1448 1448 1452 1448 1455 1449 89 1449 127 1449 251 1449 267 1449 318 1449 329 1449 347 1449 392 1449 470 1449 482 1449 494 1449 501 1449 502 1449 510 1449 513 1449 535 1449 674 1449 678 1449 689 1449 708 1449 817 1449 831 1449 834 1449 896 1449 921 1449 925 1449 965 1449 979 1449 986 1449 1007 1449 1009 1449 1160 1449 1215 1449 1304 1449 1318 1449 1321 1449 1341 1449 1392 1449 1408 1449 1425 1449 1449 1449 1471 1450 7 1450 87 1450 148 1450 156 1450 204 1450 242 1450 292 1450 396 1450 446 1450 508 1450 558 1450 583 1450 604 1450 613 1450 621 1450 639 1450 669 1450 691 1450 727 1450 841 1450 903 1450 919 1450 937 1450 948 1450 987 1450 994 1450 1038 1450 1071 1450 1151 1450 1156 1450 1161 1450 1184 1450 1273 1450 1326 1450 1431 1450 1444 1450 1450 1450 1458 1450 1464 1451 4 1451 71 1451 155 1451 169 1451 248 1451 331 1451 469 1451 519 1451 632 1451 716 1451 738 1451 977 1451 1053 1451 1073 1451 1357 1451 1367 1451 1416 1451 1423 1451 1451 1451 1480 1452 9 1452 15 1452 54 1452 73 1452 121 1452 158 1452 182 1452 205 1452 221 1452 229 1452 285 1452 351 1452 381 1452 462 1452 485 1452 490 1452 536 1452 618 1452 619 1452 685 1452 698 1452 701 1452 735 1452 823 1452 827 1452 837 1452 849 1452 864 1452 905 1452 1044 1452 1144 1452 1153 1452 1183 1452 1221 1452 1258 1452 1343 1452 1389 1452 1442 1452 1448 1452 1452 1452 1455 1452 1463 1453 100 1453 134 1453 140 1453 246 1453 260 1453 265 1453 310 1453 320 1453 337 1453 393 1453 406 1453 413 1453 417 1453 421 1453 521 1453 596 1453 616 1453 672 1453 688 1453 740 1453 754 1453 762 1453 772 1453 781 1453 806 1453 855 1453 856 1453 907 1453 918 1453 932 1453 945 1453 963 1453 974 1453 998 1453 1004 1453 1042 1453 1049 1453 1074 1453 1094 1453 1139 1453 1158 1453 1177 1453 1181 1453 1387 1453 1397 1453 1438 1453 1453 1453 1470 1453 1473 1454 59 1454 67 1454 190 1454 335 1454 414 1454 435 1454 691 1454 727 1454 774 1454 840 1454 841 1454 919 1454 953 1454 987 1454 1021 1454 1038 1454 1151 1454 1231 1454 1273 1454 1320 1454 1379 1454 1432 1454 1454 1454 1477 1454 1491 1454 1497 1455 9 1455 19 1455 54 1455 73 1455 121 1455 130 1455 152 1455 158 1455 182 1455 205 1455 259 1455 285 1455 330 1455 473 1455 485 1455 599 1455 618 1455 655 1455 698 1455 701 1455 752 1455 761 1455 778 1455 802 1455 815 1455 823 1455 837 1455 849 1455 892 1455 905 1455 983 1455 1044 1455 1144 1455 1258 1455 1343 1455 1382 1455 1448 1455 1452 1455 1455 1456 44 1456 57 1456 147 1456 149 1456 232 1456 253 1456 344 1456 375 1456 388 1456 397 1456 478 1456 491 1456 556 1456 694 1456 733 1456 743 1456 799 1456 807 1456 860 1456 888 1456 893 1456 990 1456 993 1456 1027 1456 1069 1456 1082 1456 1136 1456 1202 1456 1235 1456 1278 1456 1355 1456 1358 1456 1456 1457 10 1457 23 1457 49 1457 103 1457 184 1457 198 1457 210 1457 357 1457 376 1457 402 1457 457 1457 503 1457 517 1457 542 1457 551 1457 555 1457 559 1457 582 1457 601 1457 622 1457 627 1457 657 1457 666 1457 704 1457 725 1457 750 1457 756 1457 766 1457 770 1457 800 1457 811 1457 898 1457 915 1457 916 1457 933 1457 1008 1457 1020 1457 1087 1457 1088 1457 1095 1457 1166 1457 1185 1457 1297 1457 1429 1457 1433 1457 1457 1457 1492 1457 1495 1458 7 1458 20 1458 37 1458 87 1458 203 1458 204 1458 242 1458 292 1458 294 1458 300 1458 336 1458 403 1458 446 1458 583 1458 903 1458 928 1458 948 1458 953 1458 987 1458 1029 1458 1038 1458 1106 1458 1169 1458 1188 1458 1211 1458 1224 1458 1268 1458 1273 1458 1326 1458 1379 1458 1404 1458 1450 1458 1458 1458 1460 1459 30 1459 53 1459 58 1459 78 1459 82 1459 90 1459 102 1459 130 1459 191 1459 193 1459 206 1459 211 1459 212 1459 270 1459 286 1459 308 1459 323 1459 332 1459 348 1459 428 1459 451 1459 460 1459 464 1459 511 1459 533 1459 537 1459 549 1459 563 1459 579 1459 610 1459 626 1459 631 1459 658 1459 685 1459 702 1459 752 1459 761 1459 769 1459 785 1459 812 1459 829 1459 863 1459 884 1459 901 1459 923 1459 1003 1459 1024 1459 1046 1459 1057 1459 1065 1459 1084 1459 1124 1459 1135 1459 1137 1459 1183 1459 1234 1459 1238 1459 1249 1459 1334 1459 1336 1459 1390 1459 1418 1459 1459 1459 1481 1460 37 1460 49 1460 50 1460 68 1460 75 1460 87 1460 141 1460 203 1460 204 1460 210 1460 290 1460 294 1460 299 1460 300 1460 314 1460 357 1460 368 1460 433 1460 443 1460 538 1460 551 1460 559 1460 571 1460 627 1460 657 1460 671 1460 673 1460 697 1460 704 1460 756 1460 805 1460 836 1460 916 1460 930 1460 1029 1460 1088 1460 1100 1460 1169 1460 1189 1460 1203 1460 1300 1460 1338 1460 1364 1460 1374 1460 1379 1460 1458 1460 1460 1460 1462 1460 1490 1461 5 1461 12 1461 13 1461 52 1461 63 1461 65 1461 92 1461 165 1461 202 1461 230 1461 234 1461 240 1461 272 1461 365 1461 434 1461 441 1461 528 1461 569 1461 609 1461 612 1461 630 1461 642 1461 730 1461 742 1461 809 1461 882 1461 939 1461 999 1461 1018 1461 1026 1461 1028 1461 1076 1461 1129 1461 1159 1461 1265 1461 1331 1461 1369 1461 1461 1461 1472 1461 1476 1462 20 1462 31 1462 123 1462 170 1462 300 1462 333 1462 357 1462 402 1462 433 1462 538 1462 559 1462 703 1462 736 1462 916 1462 1029 1462 1100 1462 1112 1462 1188 1462 1346 1462 1402 1462 1404 1462 1433 1462 1460 1462 1462 1462 1490 1463 15 1463 19 1463 54 1463 158 1463 182 1463 205 1463 259 1463 285 1463 312 1463 381 1463 462 1463 473 1463 599 1463 709 1463 735 1463 802 1463 816 1463 823 1463 837 1463 849 1463 871 1463 1066 1463 1102 1463 1144 1463 1153 1463 1221 1463 1340 1463 1343 1463 1382 1463 1389 1463 1419 1463 1442 1463 1452 1463 1463 1463 1486 1464 7 1464 20 1464 31 1464 87 1464 123 1464 128 1464 148 1464 156 1464 167 1464 204 1464 219 1464 242 1464 266 1464 292 1464 336 1464 378 1464 449 1464 530 1464 548 1464 558 1464 607 1464 613 1464 621 1464 671 1464 763 1464 791 1464 862 1464 873 1464 900 1464 903 1464 935 1464 948 1464 1106 1464 1156 1464 1161 1464 1162 1464 1171 1464 1176 1464 1184 1464 1211 1464 1224 1464 1289 1464 1294 1464 1326 1464 1431 1464 1444 1464 1450 1464 1464 1465 11 1465 81 1465 106 1465 151 1465 185 1465 225 1465 251 1465 318 1465 339 1465 347 1465 358 1465 419 1465 430 1465 470 1465 480 1465 510 1465 529 1465 546 1465 550 1465 585 1465 663 1465 665 1465 674 1465 683 1465 760 1465 768 1465 787 1465 821 1465 828 1465 842 1465 912 1465 949 1465 986 1465 996 1465 1009 1465 1011 1465 1019 1465 1022 1465 1033 1465 1060 1465 1063 1465 1070 1465 1079 1465 1197 1465 1215 1465 1304 1465 1318 1465 1408 1465 1440 1465 1465 1465 1471 1466 69 1466 70 1466 108 1466 146 1466 273 1466 363 1466 438 1466 466 1466 512 1466 523 1466 635 1466 700 1466 722 1466 731 1466 780 1466 794 1466 872 1466 998 1466 1004 1466 1012 1466 1155 1466 1177 1466 1193 1466 1228 1466 1260 1466 1263 1466 1298 1466 1399 1466 1466 1467 26 1467 82 1467 200 1467 233 1467 244 1467 267 1467 332 1467 355 1467 359 1467 399 1467 623 1467 625 1467 658 1467 681 1467 795 1467 865 1467 959 1467 1009 1467 1079 1467 1113 1467 1199 1467 1314 1467 1316 1467 1321 1467 1378 1467 1467 1467 1485 1467 1494 1468 24 1468 51 1468 129 1468 283 1468 304 1468 327 1468 358 1468 429 1468 522 1468 575 1468 594 1468 625 1468 629 1468 689 1468 695 1468 708 1468 729 1468 731 1468 745 1468 767 1468 810 1468 824 1468 885 1468 896 1468 921 1468 1007 1468 1031 1468 1039 1468 1085 1468 1086 1468 1178 1468 1204 1468 1244 1468 1261 1468 1271 1468 1316 1468 1339 1468 1371 1468 1400 1468 1468 1469 84 1469 88 1469 166 1469 168 1469 173 1469 334 1469 409 1469 420 1469 426 1469 461 1469 471 1469 472 1469 477 1469 488 1469 489 1469 553 1469 572 1469 675 1469 710 1469 723 1469 748 1469 788 1469 818 1469 899 1469 917 1469 924 1469 1040 1469 1062 1469 1080 1469 1093 1469 1096 1469 1104 1469 1115 1469 1143 1469 1191 1469 1192 1469 1233 1469 1254 1469 1285 1469 1293 1469 1303 1469 1405 1469 1427 1469 1469 1470 100 1470 134 1470 140 1470 260 1470 289 1470 320 1470 329 1470 337 1470 393 1470 417 1470 421 1470 445 1470 459 1470 487 1470 596 1470 616 1470 679 1470 717 1470 754 1470 759 1470 762 1470 806 1470 918 1470 922 1470 1042 1470 1045 1470 1048 1470 1077 1470 1139 1470 1226 1470 1241 1470 1315 1470 1387 1470 1428 1470 1438 1470 1445 1470 1453 1470 1470 1471 41 1471 81 1471 151 1471 251 1471 267 1471 318 1471 329 1471 337 1471 347 1471 380 1471 470 1471 505 1471 510 1471 535 1471 585 1471 665 1471 674 1471 676 1471 686 1471 760 1471 787 1471 834 1471 925 1471 929 1471 950 1471 965 1471 979 1471 986 1471 988 1471 1000 1471 1009 1471 1019 1471 1060 1471 1070 1471 1111 1471 1190 1471 1215 1471 1241 1471 1251 1471 1286 1471 1304 1471 1392 1471 1408 1471 1445 1471 1449 1471 1465 1471 1471 1472 5 1472 47 1472 52 1472 63 1472 65 1472 92 1472 160 1472 202 1472 230 1472 240 1472 272 1472 291 1472 365 1472 387 1472 441 1472 569 1472 603 1472 609 1472 612 1472 624 1472 630 1472 642 1472 694 1472 730 1472 742 1472 809 1472 882 1472 999 1472 1018 1472 1028 1472 1075 1472 1076 1472 1108 1472 1196 1472 1265 1472 1277 1472 1331 1472 1369 1472 1461 1472 1472 1472 1476 1472 1484 1473 1 1473 18 1473 100 1473 246 1473 265 1473 320 1473 421 1473 616 1473 672 1473 688 1473 712 1473 740 1473 806 1473 850 1473 855 1473 856 1473 876 1473 907 1473 945 1473 974 1473 998 1473 1004 1473 1074 1473 1094 1473 1139 1473 1177 1473 1195 1473 1306 1473 1387 1473 1397 1473 1438 1473 1453 1473 1473 1474 83 1474 135 1474 217 1474 223 1474 224 1474 343 1474 371 1474 377 1474 387 1474 389 1474 391 1474 408 1474 441 1474 478 1474 483 1474 497 1474 524 1474 547 1474 556 1474 592 1474 600 1474 638 1474 640 1474 680 1474 784 1474 807 1474 814 1474 844 1474 906 1474 908 1474 910 1474 911 1474 972 1474 1014 1474 1034 1474 1068 1474 1078 1474 1099 1474 1142 1474 1180 1474 1198 1474 1206 1474 1217 1474 1230 1474 1277 1474 1299 1474 1361 1474 1370 1474 1373 1474 1407 1474 1441 1474 1474 1474 1496 1475 53 1475 86 1475 102 1475 206 1475 211 1475 277 1475 308 1475 332 1475 348 1475 349 1475 405 1475 451 1475 534 1475 563 1475 579 1475 626 1475 658 1475 685 1475 702 1475 752 1475 846 1475 863 1475 901 1475 1024 1475 1066 1475 1084 1475 1131 1475 1135 1475 1137 1475 1309 1475 1475 1475 1494 1476 14 1476 36 1476 63 1476 92 1476 125 1476 160 1476 202 1476 230 1476 240 1476 272 1476 365 1476 373 1476 387 1476 441 1476 569 1476 600 1476 606 1476 624 1476 630 1476 640 1476 694 1476 809 1476 882 1476 888 1476 910 1476 999 1476 1018 1476 1075 1476 1076 1476 1108 1476 1196 1476 1277 1476 1331 1476 1369 1476 1461 1476 1472 1476 1476 1476 1484 1477 59 1477 67 1477 161 1477 190 1477 335 1477 414 1477 435 1477 774 1477 840 1477 841 1477 857 1477 919 1477 1021 1477 1231 1477 1320 1477 1365 1477 1409 1477 1432 1477 1443 1477 1454 1477 1477 1477 1491 1477 1497 1478 2 1478 3 1478 93 1478 95 1478 111 1478 126 1478 153 1478 194 1478 227 1478 231 1478 247 1478 282 1478 296 1478 362 1478 384 1478 386 1478 454 1478 463 1478 466 1478 481 1478 515 1478 516 1478 564 1478 654 1478 670 1478 796 1478 801 1478 838 1478 970 1478 975 1478 1001 1478 1002 1478 1012 1478 1036 1478 1105 1478 1116 1478 1119 1478 1122 1478 1194 1478 1248 1478 1256 1478 1280 1478 1298 1478 1302 1478 1354 1478 1394 1478 1396 1478 1478 1479 91 1479 122 1479 219 1479 319 1479 326 1479 350 1479 360 1479 416 1479 418 1479 422 1479 457 1479 508 1479 555 1479 589 1479 593 1479 617 1479 622 1479 639 1479 644 1479 732 1479 770 1479 777 1479 800 1479 886 1479 933 1479 997 1479 1010 1479 1015 1479 1071 1479 1087 1479 1146 1479 1154 1479 1161 1479 1167 1479 1185 1479 1200 1479 1205 1479 1257 1479 1268 1479 1311 1479 1346 1479 1388 1479 1426 1479 1431 1479 1479 1480 4 1480 16 1480 71 1480 248 1480 274 1480 297 1480 331 1480 432 1480 469 1480 519 1480 548 1480 632 1480 706 1480 738 1480 964 1480 977 1480 1053 1480 1073 1480 1130 1480 1255 1480 1274 1480 1328 1480 1357 1480 1367 1480 1416 1480 1422 1480 1423 1480 1451 1480 1480 1481 30 1481 53 1481 78 1481 82 1481 90 1481 102 1481 130 1481 152 1481 193 1481 200 1481 211 1481 212 1481 270 1481 286 1481 308 1481 348 1481 349 1481 399 1481 405 1481 428 1481 431 1481 451 1481 464 1481 511 1481 537 1481 549 1481 560 1481 579 1481 580 1481 610 1481 626 1481 631 1481 652 1481 658 1481 702 1481 752 1481 761 1481 778 1481 812 1481 815 1481 829 1481 863 1481 901 1481 923 1481 959 1481 1003 1481 1024 1481 1035 1481 1046 1481 1057 1481 1059 1481 1084 1481 1124 1481 1131 1481 1135 1481 1212 1481 1238 1481 1249 1481 1316 1481 1336 1481 1340 1481 1390 1481 1418 1481 1459 1481 1481 1482 32 1482 40 1482 115 1482 139 1482 171 1482 177 1482 237 1482 307 1482 366 1482 453 1482 833 1482 835 1482 848 1482 859 1482 869 1482 926 1482 1041 1482 1061 1482 1103 1482 1237 1482 1245 1482 1247 1482 1262 1482 1276 1482 1296 1482 1347 1482 1381 1482 1406 1482 1482 1483 37 1483 49 1483 184 1483 198 1483 290 1483 368 1483 376 1483 443 1483 503 1483 555 1483 559 1483 573 1483 574 1483 582 1483 589 1483 627 1483 639 1483 657 1483 725 1483 756 1483 770 1483 805 1483 836 1483 1020 1483 1087 1483 1101 1483 1107 1483 1166 1483 1185 1483 1200 1483 1203 1483 1246 1483 1273 1483 1364 1483 1483 1483 1492 1484 14 1484 47 1484 79 1484 92 1484 125 1484 160 1484 189 1484 223 1484 230 1484 240 1484 272 1484 279 1484 295 1484 373 1484 387 1484 434 1484 441 1484 483 1484 484 1484 491 1484 520 1484 556 1484 569 1484 600 1484 606 1484 611 1484 612 1484 624 1484 630 1484 640 1484 690 1484 694 1484 743 1484 784 1484 809 1484 844 1484 882 1484 888 1484 910 1484 911 1484 999 1484 1014 1484 1018 1484 1069 1484 1075 1484 1076 1484 1082 1484 1097 1484 1099 1484 1196 1484 1206 1484 1217 1484 1230 1484 1277 1484 1331 1484 1355 1484 1370 1484 1441 1484 1472 1484 1476 1484 1484 1485 26 1485 233 1485 244 1485 267 1485 332 1485 355 1485 482 1485 629 1485 708 1485 755 1485 895 1485 931 1485 934 1485 986 1485 1054 1485 1079 1485 1314 1485 1321 1485 1327 1485 1378 1485 1467 1485 1485 1485 1494 1486 54 1486 90 1486 121 1486 191 1486 205 1486 222 1486 259 1486 312 1486 323 1486 465 1486 506 1486 536 1486 579 1486 658 1486 701 1486 702 1486 734 1486 778 1486 802 1486 808 1486 815 1486 897 1486 934 1486 959 1486 1024 1486 1035 1486 1054 1486 1066 1486 1102 1486 1113 1486 1118 1486 1124 1486 1135 1486 1212 1486 1214 1486 1221 1486 1327 1486 1330 1486 1334 1486 1340 1486 1382 1486 1400 1486 1413 1486 1442 1486 1463 1486 1486 1487 45 1487 51 1487 70 1487 151 1487 185 1487 186 1487 199 1487 245 1487 278 1487 281 1487 358 1487 359 1487 367 1487 380 1487 419 1487 437 1487 545 1487 594 1487 597 1487 635 1487 645 1487 661 1487 665 1487 676 1487 682 1487 683 1487 686 1487 699 1487 729 1487 731 1487 768 1487 872 1487 949 1487 1060 1487 1086 1487 1152 1487 1190 1487 1208 1487 1239 1487 1399 1487 1417 1487 1487 1488 25 1488 70 1488 98 1488 108 1488 151 1488 186 1488 220 1488 238 1488 256 1488 273 1488 281 1488 298 1488 303 1488 358 1488 438 1488 512 1488 635 1488 692 1488 722 1488 729 1488 731 1488 780 1488 782 1488 794 1488 803 1488 810 1488 824 1488 828 1488 894 1488 996 1488 1011 1488 1031 1488 1032 1488 1033 1488 1052 1488 1055 1488 1085 1488 1208 1488 1228 1488 1263 1488 1305 1488 1363 1488 1371 1488 1385 1488 1399 1488 1447 1488 1488 1489 43 1489 46 1489 60 1489 118 1489 176 1489 208 1489 287 1489 369 1489 385 1489 456 1489 500 1489 532 1489 541 1489 557 1489 565 1489 651 1489 724 1489 747 1489 779 1489 861 1489 878 1489 902 1489 927 1489 957 1489 1013 1489 1030 1489 1150 1489 1182 1489 1210 1489 1220 1489 1243 1489 1264 1489 1270 1489 1279 1489 1295 1489 1366 1489 1380 1489 1489 1490 7 1490 20 1490 31 1490 37 1490 68 1490 75 1490 87 1490 123 1490 148 1490 167 1490 170 1490 203 1490 204 1490 242 1490 292 1490 294 1490 300 1490 333 1490 336 1490 350 1490 357 1490 368 1490 402 1490 433 1490 538 1490 551 1490 559 1490 593 1490 622 1490 657 1490 671 1490 673 1490 703 1490 756 1490 886 1490 916 1490 928 1490 930 1490 1029 1490 1071 1490 1088 1490 1100 1490 1106 1490 1112 1490 1161 1490 1166 1490 1169 1490 1171 1490 1188 1490 1203 1490 1211 1490 1224 1490 1257 1490 1300 1490 1326 1490 1402 1490 1404 1490 1433 1490 1460 1490 1462 1490 1490 1491 59 1491 67 1491 161 1491 190 1491 335 1491 414 1491 435 1491 691 1491 774 1491 840 1491 841 1491 857 1491 919 1491 953 1491 1021 1491 1231 1491 1320 1491 1365 1491 1409 1491 1432 1491 1443 1491 1454 1491 1477 1491 1491 1491 1497 1492 10 1492 23 1492 49 1492 184 1492 198 1492 210 1492 319 1492 357 1492 376 1492 457 1492 503 1492 542 1492 551 1492 555 1492 559 1492 573 1492 589 1492 593 1492 601 1492 622 1492 627 1492 657 1492 666 1492 725 1492 750 1492 756 1492 766 1492 770 1492 886 1492 898 1492 933 1492 1008 1492 1020 1492 1087 1492 1088 1492 1107 1492 1112 1492 1166 1492 1185 1492 1429 1492 1457 1492 1483 1492 1492 1493 22 1493 156 1493 159 1493 196 1493 252 1493 274 1493 345 1493 390 1493 403 1493 448 1493 530 1493 543 1493 548 1493 615 1493 641 1493 707 1493 763 1493 764 1493 847 1493 920 1493 947 1493 948 1493 960 1493 964 1493 994 1493 1005 1493 1037 1493 1126 1493 1174 1493 1252 1493 1267 1493 1287 1493 1324 1493 1325 1493 1386 1493 1422 1493 1434 1493 1436 1493 1493 1494 53 1494 78 1494 82 1494 86 1494 200 1494 206 1494 211 1494 233 1494 244 1494 277 1494 332 1494 348 1494 355 1494 405 1494 444 1494 451 1494 552 1494 579 1494 580 1494 625 1494 626 1494 629 1494 652 1494 658 1494 708 1494 755 1494 846 1494 863 1494 901 1494 931 1494 995 1494 1007 1494 1024 1494 1059 1494 1064 1494 1135 1494 1137 1494 1309 1494 1314 1494 1316 1494 1327 1494 1378 1494 1467 1494 1475 1494 1485 1494 1494 1495 10 1495 50 1495 141 1495 195 1495 210 1495 314 1495 341 1495 342 1495 364 1495 379 1495 433 1495 503 1495 504 1495 542 1495 551 1495 571 1495 627 1495 643 1495 666 1495 693 1495 704 1495 811 1495 898 1495 913 1495 915 1495 930 1495 1008 1495 1088 1495 1095 1495 1107 1495 1109 1495 1168 1495 1189 1495 1240 1495 1246 1495 1275 1495 1300 1495 1323 1495 1338 1495 1352 1495 1374 1495 1420 1495 1437 1495 1457 1495 1495 1496 55 1496 56 1496 83 1496 164 1496 187 1496 217 1496 218 1496 223 1496 224 1496 291 1496 343 1496 371 1496 377 1496 389 1496 492 1496 497 1496 524 1496 544 1496 547 1496 562 1496 584 1496 592 1496 620 1496 638 1496 844 1496 870 1496 906 1496 908 1496 972 1496 1034 1496 1078 1496 1091 1496 1098 1496 1099 1496 1180 1496 1198 1496 1225 1496 1299 1496 1361 1496 1373 1496 1474 1496 1496 1497 59 1497 67 1497 161 1497 190 1497 335 1497 414 1497 435 1497 751 1497 774 1497 840 1497 857 1497 1021 1497 1231 1497 1320 1497 1365 1497 1409 1497 1411 1497 1432 1497 1443 1497 1454 1497 1477 1497 1491 1497 1497 1498 47 1498 135 1498 144 1498 217 1498 223 1498 253 1498 279 1498 295 1498 305 1498 401 1498 408 1498 452 1498 455 1498 478 1498 526 1498 567 1498 591 1498 608 1498 680 1498 684 1498 784 1498 814 1498 822 1498 839 1498 875 1498 940 1498 978 1498 1014 1498 1018 1498 1034 1498 1097 1498 1142 1498 1206 1498 1216 1498 1229 1498 1250 1498 1281 1498 1290 1498 1299 1498 1313 1498 1348 1498 1356 1498 1370 1498 1375 1498 1407 1498 1498 1499 42 1499 133 1499 180 1499 238 1499 268 1499 283 1499 286 1499 303 1499 328 1499 340 1499 395 1499 429 1499 438 1499 575 1499 652 1499 681 1499 722 1499 769 1499 776 1499 803 1499 969 1499 1059 1499 1155 1499 1271 1499 1305 1499 1333 1499 1403 1499 1499 leidenbase/tests/cpp_tests/leiden.cpp0000644000176200001440000001401614444624071017467 0ustar liggesusers/** leiden.cpp **/ #define FULL_TEST #include #include #include #include #include #include #include #include #include #include int leidenFindPartition( igraph_t *pigraph, std::string const partitionType, std::vector < size_t > const *pinitialMembership, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, size_t seed, double resolutionParameter, int32_t numIter, std::vector < size_t > *pmembership, std::vector < double > *pweightInCommunity, std::vector < double > *pweightFromCommunity, std::vector < double > *pweightToCommunity, double *pweightTotal, double *pquality, double *pmodularity, double *psignificance, int *pstatus ); int main( int argc, char **argv ) { int n_iter; int status; int version_major; int version_minor; int version_subminor; size_t i, j, mxcomm; char string[1024]; char fn[8192]; const char *igraphVersion; double resolution_parameter; double weightTotal; double quality; double modularity; double significance; igraph_t i_graph; igraph_integer_t numVertex; igraph_integer_t numEdge; FILE *fp; igraph_version( NULL, &version_major, &version_minor, &version_subminor ); fprintf( stderr, "igraph version %d.%d.%d\n", version_major, version_minor, version_subminor ); strcpy( fn, "edgelist.edg" ); fp = fopen( fn, "r" ); if( fp == NULL ) { fprintf( stderr, "Error: unable to open file %s\n", fn ); return( -1 ); } /* ** From igraph documentation: ** int igraph_read_graph_edgelist(igraph_t *graph, FILE *instream, ** igraph_integer_t n, ** igraph_bool_t directed); ** ** Arguments: ** graph: Pointer to an uninitialized graph object. ** instream: Pointer to a stream, it should be readable. ** n: The number of vertices in the graph. If smaller ** than the largest integer in the file it will be ** ignored. It is thus safe to supply zero here. ** directed: Logical, if true the graph is directed, if ** false it will be undirected. */ status = igraph_read_graph_edgelist( &i_graph, fp, 0, false ); if( status != 0 ) { fprintf( stderr, "Error: bad status: igraph_read_graph_edgelist\n" ); return( -1 ); } numVertex = igraph_vcount( &i_graph ); numEdge = igraph_ecount( &i_graph ); #ifdef FULL_TEST std::vector initial_membership; initial_membership.resize( numVertex ); for( i = 0; i < numVertex; ++i ) { initial_membership[i] = 1; } std::vector weights; weights.resize( numEdge ); for( i = 0; i < numEdge; ++i ) { weights[i] = 1.0; } std::vector node_sizes; node_sizes.resize( numVertex ); for( i = 0; i < numVertex; ++i ) { node_sizes[i] = 1; } #endif /* ** Partition types: ** CPMVertexPartition ** ModularityVertexPartition ** RBConfigurationVertexPartition ** RBERVertexPartition ** SignificanceVertexPartition ** SurpriseVertexPartition */ resolution_parameter = 0.5; n_iter = 2; std::vector membership; std::vector weightInCommunity; std::vector weightFromCommunity; std::vector weightToCommunity; leidenFindPartition( &i_graph, "CPMVertexPartition", NULL, NULL, NULL, 2016, resolution_parameter, n_iter, &membership, &weightInCommunity, &weightFromCommunity, &weightToCommunity, &weightTotal, &quality, &modularity, &significance, &status ); if( status != 0 ) { fprintf( stderr, "Error: bad status: leiden_find_partition\n" ); return( -1 ); } #ifdef FULL_TEST mxcomm = 0; for( i = 0; i < numVertex; ++i ) { if( membership[i] > mxcomm ) mxcomm = membership[i]; } for( j = 0; j <= mxcomm; ++j ) { fprintf( stdout, "[%d]", j ); for( i = 0; i < numVertex; ++i ) { if( membership[i] == j ) fprintf( stdout, " %d", i ); } fprintf( stdout, "\n\n" ); } /* ** The weightTotal value returned by leidenFindPartition ** appears to be the number of graph edges (or the number ** of edges * 2 for undirected graphs). ** ** The total weight in all communities is the sum of ** the weights in each community. This value is not ** give here. */ fprintf( stdout, "\n" ); fprintf( stdout, "Quality: %f\n", quality ); fprintf( stdout, "Total weight: %f\n", weightTotal ); fprintf( stdout, "Modularity: %f\n", modularity ); fprintf( stdout, "Significance: %f\n", significance ); fprintf( stdout, "\n\n" ); fprintf( stdout, "Edge weight within community\n" ); for( j = 0; j <= mxcomm; ++j ) { fprintf( stdout, " %.0f", weightInCommunity[j] ); } fprintf( stdout, "\n\n" ); fprintf( stdout, "Edge weight from community\n" ); for( j = 0; j <= mxcomm; ++j ) { fprintf( stdout, " %.0f", weightFromCommunity[j] ); } fprintf( stdout, "\n\n" ); fprintf( stdout, "Edge weight to community\n" ); for( j = 0; j <= mxcomm; ++j ) { fprintf( stdout, " %.0f", weightToCommunity[j] ); } fprintf( stdout, "\n\n" ); #endif igraph_destroy( &i_graph ); return( 0 ); } leidenbase/tests/cpp_tests/leidenalg_test.py0000755000176200001440000000517714446670026021076 0ustar liggesusers#!/usr/bin/env python3 import sys import platform import leidenalg import igraph as ig def read_edge_weights(): fp = open('edge_weights.txt', 'r') w = fp.read().splitlines() fp.close() v = [0] * len(w) for i in range(len(w)): v[i] = float(w[i]) return(v) def read_initial_memberships(): fp = open('initial_memberships.txt', 'r') w = fp.read().splitlines() fp.close() m = [0] * len(w) for i in range(len(w)): m[i] = int(w[i]) return(m) edge_wghts = read_edge_weights() init_members = read_initial_memberships() print('python version info: %s' % ( platform.python_version() ) ) print('leidenalg version: %s' % ( leidenalg.version ) ) print('igraph version: %s' % ( ig.__version__ ) ) g = ig.read( filename='edgelist.edg', format='edgelist', directed=False) # leidenalg.find_partition(graph, partition_type, initial_membership=None, weights=None, n_iterations=2, max_comm_size=0, seed=None, **kwargs)¶ # part = leidenalg.find_partition(g, partition_type=leidenalg.RBConfigurationVertexPartition, initial_membership=init_members, weights=edge_wghts, n_iterations=2, resolution_parameter=0.5, seed=2016) # part = leidenalg.find_partition(g, partition_type=leidenalg.CPMVertexPartition, n_iterations=2, resolution_parameter=0.5, seed=2016) part = leidenalg.find_partition(g, partition_type=leidenalg.RBConfigurationVertexPartition, n_iterations=2, resolution_parameter=0.5, seed=2016) # part = leidenalg.find_partition(g, partition_type=leidenalg.RBERVertexPartition, n_iterations=2, resolution_parameter=0.5, seed=2016) # part = leidenalg.find_partition(g, partition_type=leidenalg.SignificanceVertexPartition, n_iterations=2, seed=2016) # part = leidenalg.find_partition(g, partition_type=leidenalg.SurpriseVertexPartition, n_iterations=2, seed=2016) # part = leidenalg.find_partition(g, partition_type=leidenalg.ModularityVertexPartition, n_iterations=2, seed=2016) print(part) ncomm = len(part) print() print('Quality: %.0f ' % (part.quality())) print('Significance: %.0f ' % (leidenalg.SignificanceVertexPartition.FromPartition(part).quality())) print('Total weight in all communities: %.0f' % (part.total_weight_in_all_comms())) print('Apparently the total weight in all communities is the sum of the edge') print('weights in communities.') print() print('Edge weight within community') for i in range(ncomm): print('%.0f' % part.total_weight_in_comm(i), end=' ') print() print() print('Edge weight from community') for i in range(ncomm): print('%.0f' % part.total_weight_from_comm(i), end=' ') print() print() print('Edge weight to community') for i in range(ncomm): print('%.0f' % part.total_weight_to_comm(i), end=' ') print() leidenbase/tests/testthat/0000755000176200001440000000000014532326115015351 5ustar liggesusersleidenbase/tests/testthat/test-leidenbase.R0000644000176200001440000002351714444624115020557 0ustar liggesusers# Updating # 1. compare leidenbase output using the code in leidenbase/tests/cpp_tests # o check the NOTES file in leidenbase/tests/cpp_tests # o compare leidenbase C++ to python leidenalg # o compare leidenbase R to python leidenalg # 2. rebuild the expected values for devtools::test() by setting run_setup # below to TRUE and running # cd leidenbase # R # devtools::test() # This should update the files in leidenbase/inst/testdata. # Remember to reset run_setup to FALSE. run_setup <- FALSE dst_dir <- paste0(system.file(package='leidenbase'), '/testdata') evf <- paste0(dst_dir, '/expected_values.txt') # # Get igraph object # fname <- 'igraph_n1500_edgelist.txt.gz' fpath <- system.file( 'testdata', fname, package = 'leidenbase' ) if( length( fpath ) > 0 ) { zfp <- gzfile( fpath ) igraph <- igraph::read_graph( file = zfp, format='edgelist', n=1500 ) } else { stop( 'Error: unable to find file ', fname, '\n' ) } if(run_setup) { system(paste0('rm ', evf)) } else { source(evf) } # # Test partition types. # testthat::test_that( 'CPMVertexPartition membership and quality', { res <- leidenbase::leiden_find_partition( igraph, partition_type = 'CPMVertexPartition', seed = 123456, resolution_parameter = 0.5 ) t01_f01 <- 'test01_file01.txt' t01_v01 <- res$membership t01_v02 <- res$quality fpath <- paste0(dst_dir, '/', t01_f01) if(run_setup) { write.table(t01_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t01_v02_expect <- %.2f\n", t01_v02), file=evf, append=TRUE) } else { t01_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t01_v01, t01_v01_expect))) expect_equal(t01_v02, t01_v02_expect, tolerance = 1.0e-2) } }) testthat::test_that( 'ModularityVertexPartition membership and quality', { res <- leidenbase::leiden_find_partition( igraph, partition_type = 'ModularityVertexPartition', seed = 123456, resolution_parameter = 0.5 ) t02_f01 <- 'test02_file01.txt' t02_v01 <- res$membership t02_v02 <- res$quality fpath <- paste0(dst_dir, '/', t02_f01) if(run_setup) { write.table(t02_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t02_v02_expect <- %.4f\n", t02_v02), file=evf, append=TRUE) } else { t02_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t02_v01, t02_v01_expect))) expect_equal(t02_v02, t02_v02_expect, tolerance = 1.0e-2) } }) testthat::test_that( 'RBERVertexPartition membership and quality', { res <- leidenbase::leiden_find_partition( igraph, partition_type = 'RBERVertexPartition', seed = 123456, resolution_parameter = 0.5 ) t03_f01 <- 'test03_file01.txt' t03_v01 <- res$membership t03_v02 <- res$quality fpath <- paste0(dst_dir, '/', t03_f01) if(run_setup) { write.table(t03_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t03_v02_expect <- %.2f\n", t03_v02), file=evf, append=TRUE) } else { t03_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t03_v01, t03_v01_expect))) expect_equal(t03_v02, t03_v02_expect, tolerance = 1.0e-0) } }) testthat::test_that( 'SignificanceVertexPartition membership and quality', { res <- leidenbase::leiden_find_partition( igraph, partition_type = 'SignificanceVertexPartition', seed = 123456, resolution_parameter = 0.5 ) t04_f01 <- 'test04_file01.txt' t04_v01 <- res$membership t04_v02 <- res$quality fpath <- paste0(dst_dir, '/', t04_f01) if(run_setup) { write.table(t04_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t04_v02_expect <- %.2f\n", t04_v02), file=evf, append=TRUE) } else { t04_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t04_v01, t04_v01_expect))) expect_equal(t04_v02, t04_v02_expect, tolerance = 1.0e-2) } }) testthat::test_that( 'SurpriseVertexPartition membership and quality', { res <- leidenbase::leiden_find_partition( igraph, partition_type = 'SurpriseVertexPartition', seed = 123456, resolution_parameter = 0.5 ) t05_f01 <- 'test05_file01.txt' t05_v01 <- res$membership t05_v02 <- res$quality fpath <- paste0(dst_dir, '/', t05_f01) if(run_setup) { write.table(t05_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t05_v02_expect <- %.2f\n", t05_v02), file=evf, append=TRUE) } else { t05_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t05_v01, t05_v01_expect))) expect_equal(t05_v02, t05_v02_expect, tolerance = 1.0e-0) } }) # # Test resolution_parameter and num_iter. # testthat::test_that( 'resolution_parameter parameter', { res <- leidenbase::leiden_find_partition( igraph, partition_type = 'RBConfigurationVertexPartition', resolution_parameter = 1, seed = 123456 ) t06_f01 <- 'test06_file01.txt' t06_v01 <- res$membership t06_v02 <- res$quality fpath <- paste0(dst_dir, '/', t06_f01) if(run_setup) { write.table(t06_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t06_v02_expect <- %.2f\n", t06_v02), file=evf, append=TRUE) } else { t06_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t06_v01, t06_v01_expect))) expect_equal(t06_v02, t06_v02_expect, tolerance = 1.0e-0) } }) testthat::test_that( 'num_iter parameter', { res <- leidenbase::leiden_find_partition( igraph, partition_type = 'RBConfigurationVertexPartition', num_iter = 5, seed = 123456, resolution_parameter = 0.5 ) t07_f01 <- 'test07_file01.txt' t07_v01 <- res$membership t07_v02 <- res$quality fpath <- paste0(dst_dir, '/', t07_f01) if(run_setup) { write.table(t07_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t07_v02_expect <- %.2f\n", t07_v02), file=evf, append=TRUE) } else { t07_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t07_v01, t07_v01_expect))) expect_equal(t07_v02, t07_v02_expect, tolerance = 1.0e-0) } }) # # Test initial_membership # testthat::test_that( 'initial_membership parameter', { inimem <- as.integer( seq( 1, 1500 ) ) res <- leidenbase::leiden_find_partition( igraph, partition_type = 'RBConfigurationVertexPartition', initial_membership = inimem, seed = 123456, resolution_parameter = 0.5 ) t08_f01 <- 'test08_file01.txt' t08_v01 <- res$membership t08_v02 <- res$quality fpath <- paste0(dst_dir, '/', t08_f01) if(run_setup) { write.table(t08_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t08_v02_expect <- %.2f\n", t08_v02), file=evf, append=TRUE) } else { t08_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t08_v01, t08_v01_expect))) expect_equal(t08_v02, t08_v02_expect, tolerance = 1.0e-0) } }) # # Test edge_weights # testthat::test_that( 'edge_weights parameter', { edgwgt <- as.double( rep( 1.0, 61636 ) ) res <- leidenbase::leiden_find_partition( igraph, partition_type = 'RBConfigurationVertexPartition', edge_weights = edgwgt, seed = 123456, resolution_parameter = 0.5 ) t09_f01 <- 'test09_file01.txt' t09_v01 <- res$membership t09_v02 <- res$quality fpath <- paste0(dst_dir, '/', t09_f01) if(run_setup) { write.table(t09_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t09_v02_expect <- %.2f\n", t09_v02), file=evf, append=TRUE) } else { t09_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t09_v01, t09_v01_expect))) expect_equal(t09_v02, t09_v02_expect, tolerance = 1.0e-0) } }) # # Test node_sizes # testthat::test_that( 'node_sizes parameter', { nodsiz <- as.integer( rep( 1, 1500 ) ) res <- leidenbase::leiden_find_partition( igraph, partition_type = 'RBConfigurationVertexPartition', node_sizes = nodsiz, seed = 123456, resolution_parameter = 0.5 ) t10_f01 <- 'test10_file01.txt' t10_v01 <- res$membership t10_v02 <- res$quality fpath <- paste0(dst_dir, '/', t10_f01) if(run_setup) { write.table(t10_v01, file=fpath, row.names=FALSE, col.names=FALSE) cat(sprintf("t10_v02_expect <- %.2f\n", t10_v02), file=evf, append=TRUE) } else { t10_v01_expect <- read.table(fpath)[['V1']] expect_true(isTRUE(all.equal(t10_v01, t10_v01_expect))) expect_equal(t10_v02, t10_v02_expect, tolerance = 1.0e-0) } }) # # Test modularity and significance return values. # testthat::test_that( 'modularity and significance return values', { res <- leidenbase::leiden_find_partition( igraph, partition_type = 'CPMVertexPartition', seed = 123456, resolution_parameter = 0.1 ) t11_v01 <- res$modularity t11_v02 <- res$significance if(run_setup) { cat(sprintf("t11_v01_expect <- %.4f\n", t11_v01), file=evf, append=TRUE) cat(sprintf("t11_v02_expect <- %.2f\n", t11_v02), file=evf, append=TRUE) } else { expect_equal(t11_v01, t11_v01_expect, tolerance = 1.0e-2) expect_equal(t11_v02, t11_v02_expect, tolerance = 1.0e-2) } }) # # Test parameter errors # egraph <- '' testthat::test_that( 'igraph parameter error', { expect_error( leidenbase::leiden_find_partition( egraph ) ) }) inimem <- inimem <- as.integer( seq( 1, 1400 ) ) testthat::test_that( 'initial_membership parameter error', { expect_error( leidenbase::leiden_find_partition( igraph, initial_membership = inimem, resolution_parameter = 0.5 ) ) }) edgwgt <- as.double( rep( 1.0, 61630 ) ) testthat::test_that( 'edge_weights parameter error', { expect_error( leidenbase::leiden_find_partition( igraph, edge_weights = edgwgt, resolution_parameter = 0.5 ) ) }) nodsiz <- inimem <- as.integer( seq( 1, 1400 ) ) testthat::test_that( 'node_sizes parameter error', { expect_error( leidenbase::leiden_find_partition( igraph, node_sizes = nodsiz, resolution_parameter = 0.5 ) ) }) testthat::test_that( 'resolution_parameter parameter error', { expect_error( leidenbase::leiden_find_partition( igraph, resolution_parameter = 0.0 ) ) }) testthat::test_that( 'num_iter parameter error', { expect_error( leidenbase::leiden_find_partition( igraph, num_iter = 0, resolution_parameter = 0.5 ) ) }) leidenbase/tests/testthat.R0000644000176200001440000000004314444624071015475 0ustar liggesuserstestthat::test_check("leidenbase") leidenbase/configure.ac0000644000176200001440000001135214447673547014662 0ustar liggesusersAC_INIT(igraph) AC_CONFIG_SRCDIR(src/f2c.h) AC_CONFIG_HEADERS(src/config.h) : ${R_HOME=`R RHOME`} if test -z "${R_HOME}"; then echo "could not determine R_HOME" exit 1 fi CC=`"${R_HOME}/bin/R" CMD config CC` CXX=`"${R_HOME}/bin/R" CMD config CXX11` if test -z "$CXX"; then AC_MSG_ERROR([No C++11 compiler is available]) fi CXX11STD=`"${R_HOME}/bin/R" CMD config CXX11STD` CXX="${CXX} ${CXX11STD}" FC=`"${R_HOME}/bin/R" CMD config FC` CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS` CXXFLAGS=`"${R_HOME}/bin/R" CMD config CXX11FLAGS` CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS` FCFLAGS=`"${R_HOME}/bin/R" CMD config FCFLAGS` FLIBS=`"${R_HOME}/bin/R" CMD config FLIBS` LDFLAGS=`"${R_HOME}/bin/R" CMD config LDFLAGS` AC_LANG(C) AC_PROG_CC AC_LANG(C++) AC_PROG_CXX # Fortran compiler, we need to check if it is the GNU compiler AC_PROG_FC if test "x$ac_cv_fc_compiler_gnu" = xyes; then AC_DEFINE([HAVE_GFORTRAN], [1], [Define to 1 if using the GNU Fortran compiler]) fi LIBS_SAVE=$LIBS LIBS="$LIBS -lm" AC_CHECK_FUNCS([expm1 fmin finite log2 log1p rint rintf round stpcpy strcasecmp _stricmp strdup]) AC_CHECK_FUNCS(isfinite, [AC_DEFINE(HAVE_ISFINITE, 1)], [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[double f = 0.0; isfinite(f)]])], [AC_DEFINE(HAVE_ISFINITE, 1)], [AC_MSG_FAILURE([isfinite() not available])] )] ) LIBS=$LIBS_SAVE AC_CHECK_HEADER([sys/times.h], [AC_DEFINE([HAVE_TIMES_H], [1], [Define to 1 if you have the sys/times.h header])]) AC_CHECK_HEADERS([ \ net/if.h \ netinet/in.h \ net/if_dl.h \ sys/sockio.h \ sys/un.h \ sys/socket.h \ sys/ioctl.h \ sys/time.h \ sys/file.h \ ]) AC_CHECK_MEMBER([struct sockaddr.sa_len], AC_DEFINE_UNQUOTED([HAVE_SA_LEN], [1], [Define if struct sockaddr contains sa_len]), [], [#include #include ]) graphml_support=yes AC_ARG_ENABLE(graphml, AS_HELP_STRING([--disable-graphml], [Disable support for GraphML format]), [graphml_support=$enableval], [graphml_support=yes]) HAVE_LIBXML=0 if test $graphml_support = yes; then AC_PATH_PROG([XML2CONFIG], [xml2-config], [none]) if test "$XML2CONFIG" = "none"; then graphml_support=no else # xml2-config puts only preprocessor flags in --cflags (i.e. -D and -I) so # we can put them in XML2_CPPFLAGS. This might not be true for other # libraries, though. XML2_CPPFLAGS=`$XML2CONFIG --cflags` XML2_LIBS=`$XML2CONFIG --libs` OLDLIBS=${LIBS} LIBS=${XML2_LIBS} AC_CHECK_LIB([xml2], [xmlSAXUserParseFile], [ OLDCPPFLAGS=${CPPFLAGS} CPPFLAGS=${XML2_CPPFLAGS} AC_CHECK_HEADER([libxml/parser.h], [ HAVE_LIBXML=1 AC_DEFINE([HAVE_LIBXML], [1], [Define to 1 if you have the libxml2 libraries installed]) ], [ graphml_support=no ]) CPPFLAGS=${OLDCPPFLAGS} ], [ graphml_support=no ]) LIBS=${OLDLIBS} fi fi AC_SUBST(HAVE_LIBXML) AC_SUBST(XML2_LIBS) AC_SUBST(XML2_CPPFLAGS) AC_DEFINE([INTERNAL_GMP], [1], [Define to 1 if you use the vendored mini-GMP library]) AC_LANG_PUSH([C++]) HAVE_GMP=0 INTERNAL_GMP=1 GMP_LIBS="" gmp_support=no AC_CHECK_LIB([gmp], [__gmpz_add], [ AC_CHECK_HEADER([gmp.h], [ HAVE_GMP=1 INTERNAL_GMP=0 AC_DEFINE([HAVE_GMP], [1], [Define to 1 if you have the GMP library]) gmp_support=yes GMP_LIBS="-lgmp" ]) ]) AC_SUBST(HAVE_GMP) AC_SUBST(INTERNAL_GMP) AC_SUBST(GMP_LIBS) AC_LANG_POP([C++]) HAVE_GLPK=0 GLPK_LIBS="" glpk_support=no AC_ARG_ENABLE(glpk, AS_HELP_STRING([--disable-glpk], [Compile without the GLPK library])) if test "x$enable_glpk" != "xno"; then AC_CHECK_LIB([glpk], [glp_read_mps], [ AC_CHECK_HEADER([glpk.h], [ AC_EGREP_CPP(yes, [ #include #if GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION >= 57) yes #endif ], [ HAVE_GLPK=1 AC_DEFINE([HAVE_GLPK], [1], [Define to 1 if you have the GLPK library]) glpk_support=yes GLPK_LIBS="-lglpk" ]) ]) ]) fi AC_SUBST(HAVE_GLPK) AC_SUBST(GLPK_LIBS) AC_DEFINE(IGRAPH_THREAD_LOCAL, [], [We don't care about thread-local storage in R]) AC_CONFIG_FILES([src/Makevars.tmp:src/Makevars.in], [ if test -f src/Makevars && cmp -s src/Makevars.tmp src/Makevars; then AC_MSG_NOTICE([creating src/Makevars]) AC_MSG_NOTICE([src/Makevars is unchanged]) rm src/Makevars.tmp else AC_MSG_NOTICE([creating src/Makevars]) mv src/Makevars.tmp src/Makevars fi ] ) AC_OUTPUT echo "" echo "*** Compiler settings used:" echo " CC=${CC}" echo " LD=${LD}" echo " CFLAGS=${CFLAGS}" echo " CPPFLAGS=${CPPFLAGS}" echo " CXX=${CXX}" echo " CXXFLAGS=${CXXFLAGS}" echo " LDFLAGS=${LDFLAGS}" echo " LIBS=${LIBS}" leidenbase/src/0000755000176200001440000000000014532173045013140 5ustar liggesusersleidenbase/src/config.h0000644000176200001440000000000014532173045014544 0ustar liggesusersleidenbase/src/leidenbase/0000755000176200001440000000000014532173045015233 5ustar liggesusersleidenbase/src/leidenbase/leidenFindPartition.h0000644000176200001440000000362314444670622021350 0ustar liggesusers/* leidenFindPartition.h */ /* * Leidenalg find partition R-C interface. * Copyright (C) 2019 Cole Trapnell * University of Washington, Genome Sciences Department, Seattle, WA * * This file is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see http://www.gnu.org/licenses/. */ #ifndef LEIDENFINDPARTITION_H_ #define LEIDENFINDPARTITION_H_ int leidenFindPartition( igraph_t *pigraph, std::string const partitionType, std::vector < size_t > const *pinitialMembership, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, size_t seed, double resolutionParameter, std::int32_t numIter, std::vector < size_t > *pmembership, std::vector < double > *pweightInCommunity, std::vector < double > *pweightFromCommunity, std::vector < double > *pweightToCommunity, double *pweightTotal, double *pquality, double *pmodularity, double *psignificance, int *pstatus ); #endif /* LEIDENFINDPARTITION_H_ */ leidenbase/src/leidenbase/leidenFindPartitionR2C.cpp0000644000176200001440000004502314532172610022202 0ustar liggesusers/* leidenFindPartitionR2C.cpp */ /* * Leidenalg find partition R-C interface. * Copyright (C) 2019 Cole Trapnell * University of Washington, Genome Sciences Department, Seattle, WA * * This file is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see http://www.gnu.org/licenses/. */ /*! @file leidenFindPartitionR2C.cpp * @brief R to C wrapper that runs the Leidenalg algorithm find_partition function. * The Leiden algorithm is described in * From Louvain to Leiden: guaranteeing well-connected communities. * V. A. Traag and L. Waltman and N. J. van Eck * Scientific Reports (2019) * DOI: 10.1038/s41598-019-41695-z * * @param[in] igraph_edgelist a numeric edgelist vector * @param[in] igraph_directed an integer logical indicating whether or not the graph is directed * @param[in] partition_type partition type * @param[in] initial_membership Numeric vector of initial membership assignments of nodes (NULL for default of one community per node) * @param[in] edge_weights Numeric vector of edge weights (NULL for default of 1.0 for all edges) * @param[in] node_sizes Numeric vector of node sizes (NULL for default of 1 for all vertices) * @param[in] seed Numeric random number generator seed (NULL for random seed or numeric value > 0) * @param[in] resolution_parameter Numeric resolution parameter (numeric value > 0.0) * @param[in] num_iter Numeric number of iterations (numeric value >= 0) * @return A named list consisting of a numeric vector of the node community memberships (1-based indices), * a numeric quality value, a numeric modularity, a numeric significance, * a numeric vector of edge weights within each community, * a numeric vector of edge weights from each community, a numeric vector of edge weights to * each community, and total edge weight. * * @note Find additional information in the Leidenalg distribution source files. * * | description subject | description source | * | :---- | :---- | * | introductory information | leiden/doc/source/intro.rst | * | partitions and their parameters | leiden/src/VertexPartitions.py | * | initial membership/edge weights/node sizes | leiden/src/MutableVertexPartition.cpp | * * @note The Leiden algorithm paper has a description of the resolution parameter. * * @note This function does not support community detection in multiplex graphs. */ #include #include #include #include #include #include #include #include #include #include "leidenFindPartition.h" #define DEBUG 0 int xcheckParametersRValues( SEXP initial_membership, SEXP edge_weights, SEXP node_sizes, int *fstatus ); int xcheckParametersCValues( char *ppartitionType, double resolutionParameter, std::int32_t numIter, int *fstatus ); std::vector < size_t >* xsetInitialMembership( SEXP initial_membership, size_t numVertex, int *fstatus ); std::vector < double >* xsetEdgeWeights( SEXP edge_weights, size_t numEdge, int *fstatus ); std::vector < size_t >* xsetNodeSizes( SEXP node_sizes, size_t numVertex, int *fstatus ); #define LEN_ERROR_STRING 1024 void R_leidenbase_error_handler(const char *reason, const char *file, int line, int igraph_errno) { char error_string[LEN_ERROR_STRING]; snprintf(error_string, LEN_ERROR_STRING, "Error at %s:%i : %s - %s.\n", file, line, reason, igraph_strerror(igraph_errno)); IGRAPH_FINALLY_FREE(); error("%s\n", error_string); } extern "C" { SEXP _leiden_find_partition( SEXP sedgelist, SEXP snvertex, SEXP snedge, SEXP sdirected, SEXP partition_type, SEXP initial_membership, SEXP edge_weights, SEXP node_sizes, SEXP seed, SEXP resolution_parameter, SEXP num_iter ) { int status; int cdirected; std::int32_t cnumIter; size_t cseed; size_t i; size_t ir, ic; size_t numVertex, numEdge; size_t max_size; double cresolutionParameter; double cweightTotal; double cquality; double cmodularity; double csignificance; char *pcpartitionType; igraph_vector_t cedgelist; std::vector < size_t > *pcinitialMembership; std::vector < double > *pcedgeWeights; std::vector < size_t > *pcnodeSizes; std::vector < size_t > cmembership; std::vector < double > cweightInCommunity; std::vector < double > cweightFromCommunity; std::vector < double > cweightToCommunity; igraph_t cigraph; max_size = (size_t)-1; xcheckParametersRValues( initial_membership, edge_weights, node_sizes, &status ); /* * Enable attribute handling as instructed in leiden/src/Optimiser.cpp. */ igraph_set_attribute_table( &igraph_cattribute_table ); /* * Print error message and return on igraph error. (Default is to * abort on error.) */ igraph_set_error_handler( R_leidenbase_error_handler ); /* * Some graph characteristics. */ cdirected = (int)REAL(sdirected)[0]; if(REAL(snvertex)[0] > (double)max_size) { error("_leiden_find_partition: too many vertices.\n"); return( R_NilValue ); } numVertex = (size_t)REAL(snvertex)[0]; if(REAL(snedge)[0] > (double)max_size) { error("_leiden_find_partition: too many edges.\n"); return( R_NilValue ); } numEdge = (size_t)REAL(snedge)[0]; /* * Convert R igraph object to an C igraph graph using an edgelist. */ status = igraph_vector_init(&cedgelist, (int long)(2 * numEdge)); if(status == IGRAPH_ENOMEM) { error("_leiden_find_partition: unable to allocate memory\n"); return( R_NilValue ); } for( ic = 0; ic < 2; ++ic ) { for(ir = 0; ir < numEdge; ++ir) { VECTOR(cedgelist)[2*ir+ic] = (igraph_real_t)REAL(sedgelist)[ir+numEdge*ic] - 1; } } status = igraph_create(&cigraph, &cedgelist, (igraph_integer_t)numVertex, (igraph_bool_t)cdirected); if(status != IGRAPH_SUCCESS) { error("_leiden_find_partition: unable to convert graph\n"); return( R_NilValue ); } igraph_vector_destroy( &cedgelist ); /* * Extract partition type string. */ pcpartitionType = (char *)CHAR( STRING_ELT( partition_type, 0 ) ); /* * Convert additional parameters. */ cresolutionParameter = asReal( resolution_parameter ); cnumIter = asInteger( num_iter ); if( seed == R_NilValue ) { cseed = (size_t)0; } else { cseed = asInteger( seed ) >= 0 ? asInteger( seed ) : 0; } xcheckParametersCValues( pcpartitionType, cresolutionParameter, cnumIter, &status ); if( status != 0 ) { return( R_NilValue ); } pcinitialMembership = xsetInitialMembership( initial_membership, numVertex, &status ); if( status != 0 ) { return ( R_NilValue ); } pcedgeWeights = xsetEdgeWeights( edge_weights, numEdge, &status ); if( status != 0 ) { if( pcinitialMembership != NULL ) delete pcinitialMembership; return ( R_NilValue ); } pcnodeSizes = xsetNodeSizes( node_sizes, numVertex, &status ); if( status != 0 ) { if( pcinitialMembership != NULL ) delete pcinitialMembership; if( pcedgeWeights != NULL ) delete pcedgeWeights; return ( R_NilValue ); } /* * Partition nodes into communities. */ std::string partitionType( pcpartitionType ); leidenFindPartition( &cigraph, partitionType, pcinitialMembership, pcedgeWeights, pcnodeSizes, (size_t)cseed, cresolutionParameter, cnumIter, &cmembership, &cweightInCommunity, &cweightFromCommunity, &cweightToCommunity, &cweightTotal, &cquality, &cmodularity, &csignificance, &status ); if( status != 0 ) { if( pcinitialMembership != NULL ) delete pcinitialMembership; if( pcedgeWeights != NULL ) delete pcedgeWeights; if( pcnodeSizes != NULL ) delete pcnodeSizes; error( "_leiden_find_partition: bad status: leiden_find_partition" ); igraph_destroy(&cigraph); return ( R_NilValue ); } if( pcinitialMembership != NULL ) delete pcinitialMembership; if( pcedgeWeights != NULL ) delete pcedgeWeights; if( pcnodeSizes != NULL ) delete pcnodeSizes; igraph_destroy(&cigraph); /* * Set up to return community membership vector and community quality and * return them in an R list. * Notes: * o C-based leiden has 0-based vectors whereas R has 1-based. * Return membership in a 1-based vector. * o return named list of (1) membership, (2) quality, (3) significance, * (4) within community edge weight, (5) from community edge weight, * (6) to community edge weight, and (7) total weight * o rmembership: return integer vector if length <= MAX32_INT * else return real. */ SEXP rmembership; if( numVertex <= INT32_MAX ) { #if ( DEBUG ) std::cout << "Debug: _leiden_find_partition: return membership as integer vector\n"; #endif rmembership = PROTECT( allocVector( INTSXP, numVertex ) ); std::int32_t *pival; pival = INTEGER( rmembership ); for( i = 0; i < numVertex; ++i ) { pival[i] = (std::int32_t)( cmembership[i] + 1 ); } } else { #if ( DEBUG ) std::cout << "Debug: _leiden_find_partition: return membership as real vector\n"; #endif rmembership = PROTECT( allocVector( REALSXP, numVertex ) ); double *pdval; pdval = REAL( rmembership ); for( i = 0; i < numVertex; ++i ) { pdval[i] = (double)( cmembership[i] + 1 ); } } size_t numCommunity; numCommunity = cweightInCommunity.size(); double *pdval; SEXP rweightInCommunity = PROTECT( allocVector( REALSXP, numCommunity ) ); pdval = REAL( rweightInCommunity ); for( i = 0; i < numCommunity; ++i ) { pdval[i] = cweightInCommunity[i]; } SEXP rweightFromCommunity = PROTECT( allocVector( REALSXP, numCommunity ) ); pdval = REAL( rweightFromCommunity ); for( i = 0; i < numCommunity; ++i ) { pdval[i] = cweightFromCommunity[i]; } SEXP rweightToCommunity = PROTECT( allocVector( REALSXP, numCommunity ) ); pdval = REAL( rweightToCommunity ); for( i = 0; i < numCommunity; ++i ) { pdval[i] = cweightToCommunity[i]; } /* * Notes: * o notice the terminating empty string in lstNames. */ const char *lstNames[] = { "membership", "quality", "modularity", "significance", "edge_weight_within_community", "edge_weight_from_community", "edge_weight_to_community", "total_edge_weight", "" }; SEXP rresult = PROTECT( mkNamed( VECSXP, lstNames ) ); SET_VECTOR_ELT( rresult, 0, rmembership ); SET_VECTOR_ELT( rresult, 1, ScalarReal( cquality ) ); SET_VECTOR_ELT( rresult, 2, ScalarReal( cmodularity ) ); SET_VECTOR_ELT( rresult, 3, ScalarReal( csignificance ) ); SET_VECTOR_ELT( rresult, 4, rweightInCommunity ); SET_VECTOR_ELT( rresult, 5, rweightFromCommunity ); SET_VECTOR_ELT( rresult, 6, rweightToCommunity ); SET_VECTOR_ELT( rresult, 7, ScalarReal( cweightTotal ) ); UNPROTECT( 5 ); return ( rresult ); } } /* end of extern "C" block */ int xcheckParametersRValues( SEXP initial_membership, SEXP edge_weights, SEXP node_sizes, int *fstatus ) { if( initial_membership != R_NilValue && ( !isVectorAtomic( initial_membership ) || xlength( initial_membership ) < 1 ) ) { error( "_leiden_find_partition: initial_membership is not a vector" ); } if( edge_weights != R_NilValue && ( !isVectorAtomic( edge_weights ) || xlength( edge_weights ) < 1 ) ) { error( "_leiden_find_partition: edge_weights is not a vector" ); } if( node_sizes != R_NilValue && ( !isVectorAtomic( node_sizes ) || xlength( node_sizes ) < 1 ) ) { error( "_leiden_find_partition: node_sizes is not a vector" ); } *fstatus = -1; return( 0 ); } typedef struct { char *name; int flagResolutionParameter; } VertexPartitionTypes; static const VertexPartitionTypes vertexPartitionTypes[]= { { (char *)"CPMVertexPartition", 1 }, { (char *)"ModularityVertexPartition", 0 }, { (char *)"RBConfigurationVertexPartition", 1 }, { (char *)"RBERVertexPartition", 1 }, { (char *)"SignificanceVertexPartition", 0 }, { (char *)"SurpriseVertexPartition", 0 } }; /* * Check input parameters. */ int xcheckParametersCValues( char *ppartitionType, double resolutionParameter, std::int32_t numIter, int *fstatus ) { int i; int numPartitionType; int flagValidVertexPartition; int flagResolutionParameter; numPartitionType = sizeof( vertexPartitionTypes ) / sizeof( VertexPartitionTypes ); flagValidVertexPartition = 0; for( i = 0; i < numPartitionType; ++i ) { if( strcmp( vertexPartitionTypes[i].name, ppartitionType ) == 0 ) { flagValidVertexPartition = 1; flagResolutionParameter = vertexPartitionTypes[i].flagResolutionParameter; } } if( flagValidVertexPartition == 0 ) { error( "_leiden_find_partition: invalid partition_type" ); *fstatus = -1; return ( 0 ); } if( numIter <= 0 ) { error( "_leiden_find_partition: invalid num_iter: value must be > 0" ); *fstatus = -1; return ( 0 ); } if( flagResolutionParameter && resolutionParameter < 0.0 ) { error( "_leiden_find_partition: invalid resolution_parameter: value must be > 0.0" ); *fstatus = -1; return ( 0 ); } *fstatus = 0; return ( 0 ); } std::vector < size_t >* xsetInitialMembership( SEXP initial_membership, size_t numVertex, int *fstatus ) { std::vector < size_t > *pinitialMembership; if( initial_membership == R_NilValue ) { pinitialMembership = NULL; } else { size_t i, n; n = (size_t)xlength( initial_membership ); if( n != numVertex ) { error( "_leiden_find_partition: initial_membership and matrix dimension mismatch" ); *fstatus = -1; return ( NULL ); } if( TYPEOF( initial_membership ) == INTSXP ) { #if ( DEBUG ) std::cout << "Debug: _leiden_find_partition: initial_membership is an atomic vector of integers\n"; #endif int32_t *pval; pval = INTEGER( initial_membership ); pinitialMembership = new std::vector < size_t >( n ); for( i = 0; i < n; ++i ) { /* * Note: C-based leiden has 0-based vectors whereas R has 1-based */ ( *pinitialMembership )[i] = (size_t)pval[i] - 1; } } else if( TYPEOF( initial_membership ) == REALSXP ) { #if ( DEBUG ) std::cout << "Debug: _leiden_find_partition: initial_membership is an atomic vector of reals\n"; #endif double *pval; pval = REAL( initial_membership ); pinitialMembership = new std::vector < size_t >( n ); for( i = 0; i < n; ++i ) { /* * Note: C-based leiden has 0-based vectors whereas R has 1-based */ ( *pinitialMembership )[i] = (size_t)pval[i] - 1; } } else { error( "_leiden_find_partition: invalid initial_membership type" ); *fstatus = -1; return( NULL ); } } *fstatus = 0; return ( pinitialMembership ); } std::vector < double >* xsetEdgeWeights( SEXP edge_weights, size_t numEdge,int *fstatus ) { std::vector < double > *pedgeWeights; if( edge_weights == R_NilValue ) { pedgeWeights = NULL; } else { size_t i, n; n = (size_t)xlength( edge_weights ); if( n != numEdge ) { error( "_leiden_find_partition: edge_weights and matrix dimension mismatch" ); *fstatus = -1; return ( NULL ); } if( TYPEOF( edge_weights ) == INTSXP ) { #if ( DEBUG ) std::cout << "Debug: _leiden_find_partition: edge_weights is an atomic vector of integers\n"; #endif int32_t *pval; pval = INTEGER( edge_weights ); pedgeWeights = new std::vector < double >( n ); for( i = 0; i < n; ++i ) { ( *pedgeWeights )[i] = (double)pval[i]; } } else if( TYPEOF( edge_weights ) == REALSXP ) { #if ( DEBUG ) std::cout << "Debug: _leiden_find_partition: edge_weights is an atomic vector of reals\n"; #endif double *pval; pval = REAL( edge_weights ); pedgeWeights = new std::vector < double >( n ); for( i = 0; i < n; ++i ) { ( *pedgeWeights )[i] = (double)pval[i]; } } else { error( "_leiden_find_partition: invalid edge_weights type" ); *fstatus = -1; return( NULL ); } } *fstatus = 0; return ( pedgeWeights ); } std::vector < size_t >* xsetNodeSizes( SEXP node_sizes, size_t numVertex, int *fstatus ) { std::vector < size_t > *pnodeSizes; if( node_sizes == R_NilValue ) { pnodeSizes = NULL; } else { size_t i, n; n = (size_t)xlength( node_sizes ); if( n != numVertex ) { error( "_leiden_find_partition: node_sizes and matrix dimension mismatch" ); *fstatus = -1; return ( NULL ); } if( TYPEOF( node_sizes ) == INTSXP ) { #if ( DEBUG ) std::cout << "Debug: _leiden_find_partition: node_sizes is an atomic vector of integers\n"; #endif int32_t *pval; pval = INTEGER( node_sizes ); pnodeSizes = new std::vector < size_t >( n ); for( i = 0; i < n; ++i ) { ( *pnodeSizes )[i] = (size_t)pval[i]; } } else if( TYPEOF( node_sizes ) == REALSXP ) { #if ( DEBUG ) std::cout << "Debug: _leiden_find_partition: node_sizes is an atomic vector of reals\n"; #endif double *pval; pval = REAL( node_sizes ); pnodeSizes = new std::vector < size_t >( n ); for( i = 0; i < n; ++i ) { ( *pnodeSizes )[i] = (size_t)pval[i]; } } else { error( "_leiden_find_partition: invalid node_sizes type" ); *fstatus = -1; return( NULL ); } } *fstatus = 0; return ( pnodeSizes ); } static const R_CallMethodDef CallMethods[] = { {"_leiden_find_partition", (DL_FUNC) &_leiden_find_partition, 11}, {NULL, NULL, 0} }; extern "C" attribute_visible void R_init_leidenbase(DllInfo *info) { R_registerRoutines(info, NULL, CallMethods, NULL, NULL); R_useDynamicSymbols(info, FALSE); } leidenbase/src/leidenbase/leidenFindPartition.cpp0000644000176200001440000005227114531240532021674 0ustar liggesusers/* leidenFindPartition.cpp */ /* * Leidenalg find partition R-C interface. * Copyright (C) 2019 Cole Trapnell * University of Washington, Genome Sciences Department, Seattle, WA * * This file is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see http://www.gnu.org/licenses/. */ /*! @file leidenFindPartition.cpp * @brief C++ wrapper that runs the Leiden community detection algorithm * find_partition function, which is given in the Leidenalg * distribution file 'leiden/src/functions.py'. * The Leiden algorithm is described in * From Louvain to Leiden: guaranteeing well-connected communities. * V. A. Traag, L. Waltman, and N. J. van Eck * Scientific Reports (2019) * DOI: 10.1038/s41598-019-41695-z * * @param[in] igraph pointer to igraph_t graph * @param[in] partitionType partition type used for optimization * @param[in] initialMembership vector of initial membership assignments of nodes (NULL for default of one community per node) * @param[in] edgeWeights vector of weights of edges (NULL for default of 1.0) * @param[in] nodeSizes vector of node sizes (NULL for default of 1) * @param[in] seed random number generator seed (0=random seed) * @param[in] resolutionParameter resolution parameter * @param[in] numIter number of iterations * @param[out] pmembership vector of node community membership assignments * @param[out] pweightInCommunity vector of edge weights within community * @param[out] pweightFromCommunity vector of edge weights from community * @param[out] pweightToCommunity vector of edge weights to community * @param[out] pweightTotal total edge weights * @param[out] pquality partition quality * @param[out] pmodularity partition modularity * @param[out] psignificance partition significance * @param[out] pstatus function status (0=success; -1=failure) * * @note Find additional information in the Leidenalg distribution source files. * * | description subject | description source | * | :---- | :---- | * | introductory information | leiden/doc/source/intro.rst | * | partitions and their parameters | leiden/src/VertexPartitions.py | * | initial membership/edge weights/node sizes | leiden/src/MutableVertexPartition.cpp | * * @note The Leiden algorithm paper has a description of the resolution parameter. * * @note This function does not support community detection in multiplex graphs. * */ #include #include #include #include #include #include #include #include "GraphHelper.h" #include "CPMVertexPartition.h" #include "ModularityVertexPartition.h" #include "RBConfigurationVertexPartition.h" #include "RBERVertexPartition.h" #include "SignificanceVertexPartition.h" #include "SurpriseVertexPartition.h" #include "Optimiser.h" #include "leidenFindPartition.h" #ifdef USING_R #include #endif #define DEBUG 0 int xdumpParameters( igraph_t *pigraph, std::string const partitionType, std::vector < size_t > const *pinitialMembership, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, size_t seed, double resolutionParameter, std::int32_t numIter, int *pstatus ); int xcheckParameters( std::string const partitionType, std::vector < size_t > const *pinitialMembership, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, size_t numVertex, size_t numEdge, double resolutionParameter, std::int32_t numIter, int *pstatus ); Graph* xmakeGraph( igraph_t *pigraph, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, int correctSelfLoops, int *pstatus ); MutableVertexPartition* xmakePartition( Graph *pGraph, std::string const partitionType, std::vector < size_t > const *pinitialMembership, double resolutionParameter, int *pstatus ); int xgetQuality( MutableVertexPartition *ppartition, std::string const partitionType, double resolutionParameter, double *pquality, int *pstatus ); int xgetCommunityValues( MutableVertexPartition *ppartition, Graph *pGraph, std::vector < double > *pweightInCommunity, std::vector < double > *pweightFromCommunity, std::vector < double > *pweightToCommunity, double *pweightTotal, double *pmodularity, int *pstatus ); int xgetSignificance( MutableVertexPartition *ppartition, double *psignificance, int *pstatus ); int leidenFindPartition( igraph_t *pigraph, std::string const partitionType, std::vector < size_t > const *pinitialMembership, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, size_t seed, double resolutionParameter, std::int32_t numIter, std::vector < size_t > *pmembership, std::vector < double > *pweightInCommunity, std::vector < double > *pweightFromCommunity, std::vector < double > *pweightToCommunity, double *pweightTotal, double *pquality, double *pmodularity, double *psignificance, int *pstatus ) { int correctSelfLoops; int status; std::int32_t iiter; size_t numVertex; size_t numEdge; Graph *pGraph; MutableVertexPartition *ppartition; #if ( DEBUG ) xdumpParameters( pigraph, partitionType, pinitialMembership, pedgeWeights, pnodeSizes, seed, resolutionParameter, numIter, &status ); if( status != 0 ) { *pstatus = -1; return ( 0 ); } #endif numVertex = igraph_vcount( pigraph ); numEdge = igraph_ecount( pigraph ); /* * Check input parameters. */ xcheckParameters( partitionType, pinitialMembership, pedgeWeights, pnodeSizes, numVertex, numEdge, resolutionParameter, numIter, &status ); if( status != 0 ) { *pstatus = -1; return ( 0 ); } /* ** Make Graph (defined in GraphHelper.h) */ correctSelfLoops = 0; pGraph = xmakeGraph( pigraph, pedgeWeights, pnodeSizes, correctSelfLoops, &status ); if( status != 0 ) { *pstatus = -1; return ( 0 ); } /* ** Make specified partition. */ ppartition = xmakePartition( pGraph, partitionType, pinitialMembership, resolutionParameter, &status ); if( status != 0 ) { delete pGraph; *pstatus = -1; return ( 0 ); } /* * Make optimiser object. */ Optimiser optimiser; /* * Set random number generator seed if seed > 0. */ if( seed > 0 ) { optimiser.set_rng_seed( seed ); } /* * Run optimiser. */ for( iiter = 0; iiter < numIter; ++iiter ) { optimiser.optimise_partition( ppartition ); } /* * Prepare to return membership assignments. */ ( *pmembership ).resize( numVertex ); size_t i; for( i = 0; i < numVertex; ++i ) { ( *pmembership )[i] = ppartition->membership( i ); } /* * Get final quality. * Notes: * o the Leiden code notes that this quality is not normalized by * the number of edges. */ xgetQuality( ppartition, partitionType, resolutionParameter, pquality, &status ); if( status != 0 ) { delete pGraph; delete ppartition; *pstatus = -1; return ( 0 ); } #if ( DEBUG ) std::cout << "Debug: leidenFindPartition: quality: " << *pquality << "\n"; #endif #if ( DEBUG ) std::cout << "Debug: leidenFindPartition: done\n"; #endif /* * Get community values. */ xgetCommunityValues( ppartition, pGraph, pweightInCommunity, pweightFromCommunity, pweightToCommunity, pweightTotal, pmodularity, &status ); if( status != 0 ) { delete pGraph; delete ppartition; *pstatus = -1; return ( 0 ); } /* * Get partition significance if psignificance is not NULL. */ if( psignificance != NULL ) { xgetSignificance( ppartition, psignificance, &status ); if( status != 0 ) { delete pGraph; delete ppartition; *pstatus = -1; return ( 0 ); } } delete pGraph; delete ppartition; *pstatus = 0; return ( 0 ); } #ifndef USING_R int xdumpParameters( igraph_t *pigraph, std::string const partitionType, std::vector < size_t > const *pinitialMembership, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, size_t seed, double resolutionParameter, std::int32_t numIter, int *pstatus ) { std::cout << "Debug: leidenFindPartition: start\n"; std::cout << "Debug: leidenFindPartition: partitionType: " + partitionType + "\n"; if( pinitialMembership == NULL ) { std::cout << "Debug: leidenFindPartition: initialMembership is NULL\n"; } else { std::cout << "Debug: leidenFindPartition: initialMembership is not NULL\n"; } if( pedgeWeights == NULL ) { std::cout << "Debug: leidenFindPartition: edgeWeights is NULL\n"; } else { std::cout << "Debug: leidenFindPartition: edgeWeights is not NULL\n"; } if( pnodeSizes == NULL ) { std::cout << "Debug: leidenFindPartition: nodeSizes is NULL\n"; } else { std::cout << "Debug: leidenFindPartition: nodeSizes is not NULL\n"; } std::cout << "Debug: leidenFindPartition: resolutionParameter is " << resolutionParameter << "\n"; std::cout << "Debug: leidenFindPartition: seed: " << seed << "\n"; std::cout << "Debug: leidenFindPartition: numIter: " << numIter << "\n"; std::cout << "Debug: leidenFindPartition: numVertex: " << igraph_vcount( pigraph ) << "\n"; std::cout << "Debug: leidenFindPartition: numEdges: " << igraph_ecount( pigraph ) << "\n"; *pstatus = 0; return( 0 ); } #endif typedef struct { char *name; int flagResolutionParameter; } VertexPartitionTypes; static const VertexPartitionTypes vertexPartitionTypes[]= { { (char *)"CPMVertexPartition", 1 }, { (char *)"ModularityVertexPartition", 0 }, { (char *)"RBConfigurationVertexPartition", 1 }, { (char *)"RBERVertexPartition", 1 }, { (char *)"SignificanceVertexPartition", 0 }, { (char *)"SurpriseVertexPartition", 0 } }; /* * Check input parameter reasonableness. */ int xcheckParameters( std::string const partitionType, std::vector < size_t > const *pinitialMembership, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, size_t numVertex, size_t numEdge, double resolutionParameter, std::int32_t numIter, int *pstatus ) { int numPartitionType; int i; int flagValidVertexPartition; int flagResolutionParameter; numPartitionType = sizeof( vertexPartitionTypes ) / sizeof( VertexPartitionTypes ); flagValidVertexPartition = 0; for( i = 0; i < numPartitionType; ++i ) { if( partitionType.compare( vertexPartitionTypes[i].name ) == 0 ) { flagValidVertexPartition = 1; flagResolutionParameter = vertexPartitionTypes[i].flagResolutionParameter; } } if( flagValidVertexPartition == 0 ) { #ifdef USING_R Rprintf( "Error: leidenFindPartition: invalid partitionType.\n" ); #else std::cout << "Error: leidenFindPartition: invalid partitionType.\n"; #endif *pstatus = -1; return ( 0 ); } if( pinitialMembership != NULL && pinitialMembership->size() != numVertex ) { #ifdef USING_R Rprintf( "Error: leidenFindPartition: Initial membership vector inconsistent length with the vertex count of the graph.\n"); #else std::cout << "Error: leidenFindPartition: Initial membership vector inconsistent length with the vertex count of the graph.\n"; #endif *pstatus = -1; return ( 0 ); } if( pedgeWeights != NULL && pedgeWeights->size() != numEdge ) { #ifdef USING_R Rprintf( "Error: leidenFindPartition: Edge weight vector inconsistent length with the edge count of the graph.\n"); #else std::cout << "Error: leidenFindPartition: Edge weight vector inconsistent length with the edge count of the graph.\n"; #endif *pstatus = -1; return ( 0 ); } if( pnodeSizes != NULL && pnodeSizes->size() != numVertex ) { #ifdef USING_R Rprintf( "Error: leidenFindPartition: Node size vector inconsistent length with the vertex count of the graph.\n"); #else std::cout << "Error: leidenFindPartition: Node size vector inconsistent length with the vertex count of the graph.\n"; #endif *pstatus = -1; return ( 0 ); } if( flagResolutionParameter && resolutionParameter <= 0.0 ) { #ifdef USING_R Rprintf( "Error: leidenFindPartition: resolution parameter <= 0.0\n"); #else std::cout << "Error: leidenFindPartition: resolution parameter <= 0.0\n"; #endif *pstatus = -1; return ( 0 ); } if( numIter <= 0 ) { #ifdef USING_R Rprintf( "Error: leidenFindPartition: Number of iterations <= 0.\n"); #else std::cout << "Error: leidenFindPartition: Number of iterations <= 0.\n"; #endif *pstatus = -1; return ( 0 ); } *pstatus = 0; return ( 0 ); } /* * Make Leiden Graph object from igraph graph object. */ Graph* xmakeGraph( igraph_t *pigraph, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, int correctSelfLoops, int *pstatus ) { Graph *pGraph; if( pedgeWeights != NULL && pnodeSizes != NULL ) { pGraph = new Graph( pigraph, *pedgeWeights, *pnodeSizes, correctSelfLoops ); } else if( pedgeWeights != NULL && pnodeSizes == NULL ) { pGraph = new Graph( pigraph, *pedgeWeights, correctSelfLoops ); } else if( pedgeWeights == NULL && pnodeSizes != NULL ) { pGraph = new Graph( pigraph, *pnodeSizes, correctSelfLoops ); } else { pGraph = new Graph( pigraph, correctSelfLoops ); } *pstatus = 0; return ( pGraph ); } /* * Make requested partition object. */ MutableVertexPartition* xmakePartition( Graph *pGraph, std::string const partitionType, std::vector < size_t > const *pinitialMembership, double resolutionParameter, int *pstatus ) { MutableVertexPartition *ppartition; if( partitionType.compare( "CPMVertexPartition" ) == 0 ) { if( pinitialMembership != NULL ) { ppartition = new CPMVertexPartition( pGraph, *pinitialMembership, resolutionParameter ); } else { ppartition = new CPMVertexPartition( pGraph, resolutionParameter ); } } else if( partitionType.compare( "ModularityVertexPartition" ) == 0 ) { if( pinitialMembership != NULL ) { ppartition = new ModularityVertexPartition( pGraph, *pinitialMembership ); } else { ppartition = new ModularityVertexPartition( pGraph ); } } else if( partitionType.compare( "RBConfigurationVertexPartition" ) == 0 ) { if( pinitialMembership != NULL ) { ppartition = new RBConfigurationVertexPartition( pGraph, *pinitialMembership, resolutionParameter ); } else { ppartition = new RBConfigurationVertexPartition( pGraph, resolutionParameter ); } } else if( partitionType.compare( "RBERVertexPartition" ) == 0 ) { if( pinitialMembership != NULL ) { ppartition = new RBERVertexPartition( pGraph, *pinitialMembership, resolutionParameter ); } else { ppartition = new RBERVertexPartition( pGraph, resolutionParameter ); } } else if( partitionType.compare( "SignificanceVertexPartition" ) == 0 ) { if( pinitialMembership != NULL ) { ppartition = new SignificanceVertexPartition( pGraph, *pinitialMembership ); } else { ppartition = new SignificanceVertexPartition( pGraph ); } } else if( partitionType.compare( "SurpriseVertexPartition" ) == 0 ) { if( pinitialMembership != NULL ) { ppartition = new SurpriseVertexPartition( pGraph, *pinitialMembership ); } else { ppartition = new SurpriseVertexPartition( pGraph ); } } else { #ifdef USING_R Rprintf( "Error: leidenFindPartition: Unrecognized vertex partition type.\n"); #else std::cout << "Error: leidenFindPartition: Unrecognized vertex partition type.\n"; #endif *pstatus = -1; return ( NULL ); } *pstatus = 0; return ( ppartition ); } /* * Get quality of partition. */ int xgetQuality( MutableVertexPartition *ppartition, std::string const partitionType, double resolutionParameter, double *pquality, int *pstatus ) { *pquality = 0.0; if( partitionType.compare( "CPMVertexPartition" ) == 0 ) { *pquality = dynamic_cast< CPMVertexPartition * > (ppartition)->quality( resolutionParameter ); } else if( partitionType.compare( "ModularityVertexPartition" ) == 0 ) { *pquality = dynamic_cast< ModularityVertexPartition * > (ppartition)->quality(); } else if( partitionType.compare( "RBConfigurationVertexPartition" ) == 0 ) { *pquality = dynamic_cast< RBConfigurationVertexPartition * > (ppartition)->quality( resolutionParameter ); } else if( partitionType.compare( "RBERVertexPartition" ) == 0 ) { *pquality = dynamic_cast< RBERVertexPartition * > (ppartition)->quality( resolutionParameter ); } else if( partitionType.compare( "SignificanceVertexPartition" ) == 0 ) { *pquality = dynamic_cast< SignificanceVertexPartition * > (ppartition)->quality(); } else if( partitionType.compare( "SurpriseVertexPartition" ) == 0 ) { *pquality = dynamic_cast< SurpriseVertexPartition * > (ppartition)->quality(); } else { #ifdef USING_R Rprintf( "Error: leidenFindPartition: Unrecognized vertex partition type\n"); #else std::cout << "leidenFindPartition: Unrecognized vertex partition type\n"; #endif *pstatus = -1; return ( 0 ); } *pstatus = 0; return ( 0 ); } /* * Get some community values. */ int xgetCommunityValues( MutableVertexPartition *ppartition, Graph *pGraph, std::vector < double > *pweightInCommunity, std::vector < double > *pweightFromCommunity, std::vector < double > *pweightToCommunity, double *pweightTotal, double *pmodularity, int *pstatus ) { int is_directed; double mod; double modularity; double m; double w; double w_in; double w_out; double fac; double q; size_t icomm, numCommunity; is_directed = pGraph->is_directed(); numCommunity = ppartition->n_communities(); if( is_directed ) { m = pGraph->total_weight(); } else { m = 2 * pGraph->total_weight(); } *pweightTotal = m; if( m == 0 ) { *pstatus = -1; return( 0 ); } pweightInCommunity->resize( numCommunity ); pweightFromCommunity->resize( numCommunity ); pweightToCommunity->resize( numCommunity ); fac = ( ( is_directed ? 1.0 : 4.0 ) * pGraph->total_weight() ); mod = 0.0; for( icomm = 0; icomm < numCommunity; ++icomm ) { w = ppartition->total_weight_in_comm( icomm ); w_out = ppartition->total_weight_from_comm( icomm ); w_in = ppartition->total_weight_to_comm( icomm ); ( *pweightInCommunity )[icomm] = w; ( *pweightFromCommunity )[icomm] = w_out; ( *pweightToCommunity )[icomm] = w_in; mod += w - w_out * w_in / fac; } q = ( 2.0 - is_directed ) * mod; modularity = q / m; *pmodularity = modularity; *pstatus = 0; return( 0 ); } /* * Get the significance value of the given partition. * Significance is described in * Significant Scales in Community Structure * V. A. Traag, G. Krings, and P. Van Dooren * Scientific Reports, 3, 2930 (2013) * DOI: 10.1038/srep02930 */ int xgetSignificance( MutableVertexPartition *ppartition, double *psignificance, int *pstatus ) { double significance; SignificanceVertexPartition *psignificanceVertexPartition; psignificanceVertexPartition = new SignificanceVertexPartition( ppartition->get_graph() ); psignificanceVertexPartition->from_partition( ppartition ); significance = psignificanceVertexPartition->quality(); delete psignificanceVertexPartition; *psignificance = significance; *pstatus = 0; return( 0 ); } leidenbase/src/doc/0000755000176200001440000000000014457510633013711 5ustar liggesusersleidenbase/src/doc/issue_report_install.md0000644000176200001440000000600614457510633020506 0ustar liggesusers# Reporting Issues with Installing leidenbase Please report issues with installing leidenbase using the [leidenbase issues](https://github.com/cole-trapnell-lab/leidenbase/issues/) page on github.com.and please include the following information, which may help us to understand the problem * [computer system](#computer-system) * [R installation](#r-installation) * [R sessionInfo()](#r-sessioninfo) * [describe the error](#describe-the-error) ## Computer system I need to know the type, name, and version of your computer system. Is it MacOS, Linux, Windows, or some other system? Examples are ``` Windows 10 Pro MacOS version 10.14 Ubuntu Linux 18.04.3 ``` In order to install leidenbase, you must have C, C++, and FORTRAN compilers installed on your system. Please check for them and report the names, locations, and versions of them, if possible. Examples are ``` language some compiler commands -------- ---------------------- C cc, gcc, clang C++ c++, g++, clang++ FORTRAN f77, f95, gfortran, flang ``` If you installed any of the compilers manually or using a package manager, please include that information. ## R installation Please report your R version and how you installed it on your system. Did you build R manually from source code, install a package from CRAN, or build or install from another repository or package manager, for example, Homebrew? If possible, please include information from the file called 'Makeconf', which is part of the R installation. This file is found usually either in the directory or a subdirectory of R_HOME/etc, where R_HOME is a directory path that you can find using the R command *R.home()*. The helpful lines in this file start with the strings ``` CC = CFLAGS = CPICFLAGS = CPPFLAGS = CXX = CXXCPP = CXXFLAGS = CXXPICFLAGS = CXX98 = CXX98FLAGS = CXX98PICFLAGS = CXX98STD = CXX11 = CXX11FLAGS = CXX11PICFLAGS = CXX11STD = CXX14 = CXX14FLAGS = CXX14PICFLAGS = CXX14STD = CXX17 = CXX17FLAGS = CXX17PICFLAGS = CXX17STD = CXX_VISIBILITY = DYLIB_EXT = DYLIB_LD = DYLIB_LDFLAGS = DYLIB_LINK = FC = FCFLAGS = FCLIBS_XTRA = FFLAGS = FLIBS = ``` ## R sessionInfo Please report the information from the R command 'sessionInfo()'. ## Describe the error Please report the error and post relevant output. If possible, please include the full output of the install command, which you can get by * download the leidenbase release as a *.tar.gz* file, which you can get from [https://github.com/cole-trapnell-lab/leidenbase/releases](https://github.com/cole-trapnell-lab/leidenbase/releases) * in a terminal running the bash shell, go to the directory where you have the leidenbase release file * run the following command (the release file at the time of writing is *leidenbase-0.1.0.tar.gz*, you may need to change this name if there is a more recent release) ``` R CMD INSTALL leidenbase-0.1.0.tar.gz > install.out 2>&1 ``` * attach the resulting *install.out* file to your issue report ## Thank you I appreciate your feedback and patience. leidenbase/src/doc/issue_report_run.md0000644000176200001440000000142214457510633017641 0ustar liggesusers# Reporting Issues with Running leidenbase Please report issues with running leidenbase using the [leidenbase issues](https://github.com/cole-trapnell-lab/leidenbase/issues/) page on github and please include the following information, which may help us to understand the problem ### Describe the bug A clear and concise description of what the bug is. ### To Reproduce The code that produced the bug: ### traceback() After the error, run traceback() in R and post the output: ### Expected behavior A clear and concise description of what you expected to happen. ### Screenshots If applicable, add screenshots to help explain your problem. ### sessionInfo(): Run sessionInfo() in R and post the output ### Additional context Add any other context about the problem here. leidenbase/src/dummy.cpp0000644000176200001440000000055214455576660015017 0ustar liggesusers/* ** A source code file placed in leidenbase/src to mollify CRAN checks. ** ** This file serves two purposes: ** o it precludes complaints about missing source code files in the ** src directory ** o it causes the CRAN checker to link with the C++ standard ** libraries */ #include int a_dummy_function_cpp(void) { return(1); } leidenbase/src/include/0000755000176200001440000000000014455354651014573 5ustar liggesusersleidenbase/src/include/igraph_stack_pmt.h0000644000176200001440000000364014447675375020300 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include /** * Stack data type. * \ingroup internal */ typedef struct TYPE(igraph_stack) { BASE* stor_begin; BASE* stor_end; BASE* end; } TYPE(igraph_stack); IGRAPH_EXPORT int FUNCTION(igraph_stack, init)(TYPE(igraph_stack)* s, long int size); IGRAPH_EXPORT void FUNCTION(igraph_stack, destroy)(TYPE(igraph_stack)* s); IGRAPH_EXPORT int FUNCTION(igraph_stack, reserve)(TYPE(igraph_stack)* s, long int size); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_stack, empty)(TYPE(igraph_stack)* s); IGRAPH_EXPORT long int FUNCTION(igraph_stack, size)(const TYPE(igraph_stack)* s); IGRAPH_EXPORT void FUNCTION(igraph_stack, clear)(TYPE(igraph_stack)* s); IGRAPH_EXPORT int FUNCTION(igraph_stack, push)(TYPE(igraph_stack)* s, BASE elem); IGRAPH_EXPORT BASE FUNCTION(igraph_stack, pop)(TYPE(igraph_stack)* s); IGRAPH_EXPORT BASE FUNCTION(igraph_stack, top)(const TYPE(igraph_stack)* s); IGRAPH_EXPORT int FUNCTION(igraph_stack, print)(const TYPE(igraph_stack)* s); IGRAPH_EXPORT int FUNCTION(igraph_stack, fprint)(const TYPE(igraph_stack)* s, FILE *file); leidenbase/src/include/igraph_threading.h0000644000176200001440000000267214447675376020265 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_THREADING_H #define IGRAPH_THREADING_H #include "igraph_decls.h" __BEGIN_DECLS /** * \define IGRAPH_THREAD_SAFE * * Specifies whether igraph was built in thread-safe mode. * * This macro is defined to 1 if the current build of the igraph library is * built in thread-safe mode, and 0 if it is not. A thread-safe igraph library * attempts to use thread-local data structures instead of global ones, but * note that this is not (and can not) be guaranteed for third-party libraries * that igraph links to. */ #define IGRAPH_THREAD_SAFE 0 __END_DECLS #endif leidenbase/src/include/igraph_scan.h0000644000176200001440000000603414447675375017237 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_SCAN_H #define IGRAPH_SCAN_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_arpack.h" #include "igraph_constants.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_local_scan_0(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_local_scan_0_them(const igraph_t *us, const igraph_t *them, igraph_vector_t *res, const igraph_vector_t *weigths_them, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_local_scan_1_ecount(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_local_scan_1_ecount_them(const igraph_t *us, const igraph_t *them, igraph_vector_t *res, const igraph_vector_t *weights, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_local_scan_k_ecount(const igraph_t *graph, int k, igraph_vector_t *res, const igraph_vector_t *weights, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_local_scan_k_ecount_them(const igraph_t *us, const igraph_t *them, int k, igraph_vector_t *res, const igraph_vector_t *weights_them, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_local_scan_neighborhood_ecount(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights, const igraph_vector_ptr_t *neighborhoods); __END_DECLS #endif leidenbase/src/include/igraph_decls.h0000644000176200001440000000106714447675375017406 0ustar liggesusers#undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS /* empty */ #define __END_DECLS /* empty */ #endif /* This is to eliminate gcc warnings about unused parameters */ #define IGRAPH_UNUSED(x) (void)(x) /* Include the definition of macros controlling symbol visibility */ #include "igraph_export.h" /* Used instead of IGRAPH_EXPORT with functions that need to be tested, * but are not part of the public API. */ #define IGRAPH_PRIVATE_EXPORT IGRAPH_EXPORT leidenbase/src/include/igraph_lsap.h0000644000176200001440000000047014447675375017250 0ustar liggesusers #ifndef IGRAPH_LSAP_H #define IGRAPH_LSAP_H #include "igraph_decls.h" #include "igraph_matrix.h" #include "igraph_vector.h" #include "igraph_types.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_solve_lsap(igraph_matrix_t *c, igraph_integer_t n, igraph_vector_int_t *p); __END_DECLS #endif leidenbase/src/include/igraph_separators.h0000644000176200001440000000354014447675375020475 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_SEPARATORS_H #define IGRAPH_SEPARATORS_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" #include "igraph_datatype.h" #include "igraph_iterators.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_is_separator(const igraph_t *graph, const igraph_vs_t candidate, igraph_bool_t *res); IGRAPH_EXPORT int igraph_all_minimal_st_separators(const igraph_t *graph, igraph_vector_ptr_t *separators); IGRAPH_EXPORT int igraph_is_minimal_separator(const igraph_t *graph, const igraph_vs_t candidate, igraph_bool_t *res); IGRAPH_EXPORT int igraph_minimum_size_separators(const igraph_t *graph, igraph_vector_ptr_t *separators); __END_DECLS #endif leidenbase/src/include/igraph_pmt_off.h0000644000176200001440000000436014447675375017745 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef ATOMIC #undef ATOMIC #endif #ifdef ATOMIC_IO #undef ATOMIC_IO #endif #ifdef BASE #undef BASE #endif #ifdef BASE_EPSILON #undef BASE_EPSILON #endif #ifdef CONCAT2 #undef CONCAT2 #endif #ifdef CONCAT2x #undef CONCAT2x #endif #ifdef CONCAT3 #undef CONCAT3 #endif #ifdef CONCAT3x #undef CONCAT3x #endif #ifdef CONCAT4 #undef CONCAT4 #endif #ifdef CONCAT4x #undef CONCAT4x #endif #ifdef FP #undef FP #endif #ifdef FUNCTION #undef FUNCTION #endif #ifdef IN_FORMAT #undef IN_FORMAT #endif #ifdef MULTIPLICITY #undef MULTIPLICITY #endif #ifdef ONE #undef ONE #endif #ifdef OUT_FORMAT #undef OUT_FORMAT #endif #ifdef SHORT #undef SHORT #endif #ifdef TYPE #undef TYPE #endif #ifdef ZERO #undef ZERO #endif #ifdef HEAPMORE #undef HEAPMORE #endif #ifdef HEAPLESS #undef HEAPLESS #endif #ifdef HEAPMOREEQ #undef HEAPMOREEQ #endif #ifdef HEAPLESSEQ #undef HEAPLESSEQ #endif #ifdef SUM #undef SUM #endif #ifdef SQ #undef SQ #endif #ifdef PROD #undef PROD #endif #ifdef NOTORDERED #undef NOTORDERED #endif #ifdef EQ #undef EQ #endif #ifdef DIFF #undef DIFF #endif #ifdef DIV #undef DIV #endif #ifdef NOABS #undef NOABS #endif #ifdef PRINTFUNC #undef PRINTFUNC #endif #ifdef FPRINTFUNC #undef PRINTFUNC #endif #ifdef UNSIGNED #undef UNSIGNED #endif leidenbase/src/include/igraph_array_pmt.h0000644000176200001440000000451314447675375020311 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ typedef struct TYPE(igraph_array3) { TYPE(igraph_vector) data; long int n1, n2, n3, n1n2; } TYPE(igraph_array3); #ifndef IGRAPH_ARRAY3_INIT_FINALLY #define IGRAPH_ARRAY3_INIT_FINALLY(a, n1, n2, n3) \ do { IGRAPH_CHECK(igraph_array3_init(a, n1, n2, n3)); \ IGRAPH_FINALLY(igraph_array3_destroy, a); } while (0) #endif #ifndef ARRAY3 #define ARRAY3(m,i,j,k) ((m).data.stor_begin[(m).n1n2*(k)+(m).n1*(j)+(i)]) #endif IGRAPH_EXPORT int FUNCTION(igraph_array3, init)(TYPE(igraph_array3) *a, long int n1, long int n2, long int n3); IGRAPH_EXPORT void FUNCTION(igraph_array3, destroy)(TYPE(igraph_array3) *a); IGRAPH_EXPORT long int FUNCTION(igraph_array3, size)(const TYPE(igraph_array3) *a); IGRAPH_EXPORT long int FUNCTION(igraph_array3, n)(const TYPE(igraph_array3) *a, long int idx); IGRAPH_EXPORT int FUNCTION(igraph_array3, resize)(TYPE(igraph_array3) *a, long int n1, long int n2, long int n3); IGRAPH_EXPORT void FUNCTION(igraph_array3, null)(TYPE(igraph_array3) *a); IGRAPH_EXPORT BASE FUNCTION(igraph_array3, sum)(const TYPE(igraph_array3) *a); IGRAPH_EXPORT void FUNCTION(igraph_array3, scale)(TYPE(igraph_array3) *a, BASE by); IGRAPH_EXPORT void FUNCTION(igraph_array3, fill)(TYPE(igraph_array3) *a, BASE e); IGRAPH_EXPORT int FUNCTION(igraph_array3, update)(TYPE(igraph_array3) *to, const TYPE(igraph_array3) *from); leidenbase/src/include/igraph_embedding.h0000644000176200001440000000564714447675375020242 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_EMBEDDING_H #define IGRAPH_EMBEDDING_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_arpack.h" #include "igraph_eigen.h" #include "igraph_constants.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_adjacency_spectral_embedding(const igraph_t *graph, igraph_integer_t no, const igraph_vector_t *weights, igraph_eigen_which_position_t which, igraph_bool_t scaled, igraph_matrix_t *X, igraph_matrix_t *Y, igraph_vector_t *D, const igraph_vector_t *cvec, igraph_arpack_options_t *options); typedef enum { IGRAPH_EMBEDDING_D_A = 0, IGRAPH_EMBEDDING_I_DAD, IGRAPH_EMBEDDING_DAD, IGRAPH_EMBEDDING_OAP } igraph_laplacian_spectral_embedding_type_t; IGRAPH_EXPORT int igraph_laplacian_spectral_embedding(const igraph_t *graph, igraph_integer_t no, const igraph_vector_t *weights, igraph_eigen_which_position_t which, igraph_laplacian_spectral_embedding_type_t type, igraph_bool_t scaled, igraph_matrix_t *X, igraph_matrix_t *Y, igraph_vector_t *D, igraph_arpack_options_t *options); IGRAPH_EXPORT int igraph_dim_select(const igraph_vector_t *sv, igraph_integer_t *dim); __END_DECLS #endif leidenbase/src/include/igraph_neighborhood.h0000644000176200001440000000362014447675375020760 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_NEIGHBORHOOD_H #define IGRAPH_NEIGHBORHOOD_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_iterators.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_neighborhood_size(const igraph_t *graph, igraph_vector_t *res, igraph_vs_t vids, igraph_integer_t order, igraph_neimode_t mode, igraph_integer_t mindist); IGRAPH_EXPORT int igraph_neighborhood(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_vs_t vids, igraph_integer_t order, igraph_neimode_t mode, igraph_integer_t mindist); IGRAPH_EXPORT int igraph_neighborhood_graphs(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_vs_t vids, igraph_integer_t order, igraph_neimode_t mode, igraph_integer_t mindist); __END_DECLS #endif leidenbase/src/include/igraph_heap.h0000644000176200001440000000407614447675375017234 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_HEAP_H #define IGRAPH_HEAP_H #include "igraph_decls.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Heap */ /* -------------------------------------------------- */ /** * Heap data type. * \ingroup internal */ #define BASE_IGRAPH_REAL #define HEAP_TYPE_MAX #include "igraph_pmt.h" #include "igraph_heap_pmt.h" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MAX #define HEAP_TYPE_MIN #include "igraph_pmt.h" #include "igraph_heap_pmt.h" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MIN #undef BASE_IGRAPH_REAL #define BASE_LONG #define HEAP_TYPE_MAX #include "igraph_pmt.h" #include "igraph_heap_pmt.h" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MAX #define HEAP_TYPE_MIN #include "igraph_pmt.h" #include "igraph_heap_pmt.h" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MIN #undef BASE_LONG #define BASE_CHAR #define HEAP_TYPE_MAX #include "igraph_pmt.h" #include "igraph_heap_pmt.h" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MAX #define HEAP_TYPE_MIN #include "igraph_pmt.h" #include "igraph_heap_pmt.h" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MIN #undef BASE_CHAR #define IGRAPH_HEAP_NULL { 0,0,0 } __END_DECLS #endif leidenbase/src/include/igraph_vector.h0000644000176200001440000001330614447675375017615 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_VECTOR_H #define IGRAPH_VECTOR_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_complex.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Flexible vector */ /* -------------------------------------------------- */ #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "igraph_vector_type.h" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_FLOAT #include "igraph_pmt.h" #include "igraph_vector_type.h" #include "igraph_pmt_off.h" #undef BASE_FLOAT #define BASE_LONG #include "igraph_pmt.h" #include "igraph_vector_type.h" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_CHAR #include "igraph_pmt.h" #include "igraph_vector_type.h" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "igraph_vector_type.h" #include "igraph_pmt_off.h" #undef BASE_BOOL #define BASE_INT #include "igraph_pmt.h" #include "igraph_vector_type.h" #include "igraph_pmt_off.h" #undef BASE_INT #define BASE_COMPLEX #include "igraph_pmt.h" #include "igraph_vector_type.h" #include "igraph_pmt_off.h" #undef BASE_COMPLEX #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "igraph_vector_pmt.h" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_FLOAT #include "igraph_pmt.h" #include "igraph_vector_pmt.h" #include "igraph_pmt_off.h" #undef BASE_FLOAT #define BASE_LONG #include "igraph_pmt.h" #include "igraph_vector_pmt.h" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_CHAR #include "igraph_pmt.h" #include "igraph_vector_pmt.h" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "igraph_vector_pmt.h" #include "igraph_pmt_off.h" #undef BASE_BOOL #define BASE_INT #include "igraph_pmt.h" #include "igraph_vector_pmt.h" #include "igraph_pmt_off.h" #undef BASE_INT #define BASE_COMPLEX #include "igraph_pmt.h" #include "igraph_vector_pmt.h" #include "igraph_pmt_off.h" #undef BASE_COMPLEX /* -------------------------------------------------- */ /* Helper macros */ /* -------------------------------------------------- */ #ifndef IGRAPH_VECTOR_NULL #define IGRAPH_VECTOR_NULL { 0,0,0 } #endif #ifndef IGRAPH_VECTOR_INIT_FINALLY #define IGRAPH_VECTOR_INIT_FINALLY(v, size) \ do { IGRAPH_CHECK(igraph_vector_init(v, size)); \ IGRAPH_FINALLY(igraph_vector_destroy, v); } while (0) #endif #ifndef IGRAPH_VECTOR_BOOL_INIT_FINALLY #define IGRAPH_VECTOR_BOOL_INIT_FINALLY(v, size) \ do { IGRAPH_CHECK(igraph_vector_bool_init(v, size)); \ IGRAPH_FINALLY(igraph_vector_bool_destroy, v); } while (0) #endif #ifndef IGRAPH_VECTOR_CHAR_INIT_FINALLY #define IGRAPH_VECTOR_CHAR_INIT_FINALLY(v, size) \ do { IGRAPH_CHECK(igraph_vector_char_init(v, size)); \ IGRAPH_FINALLY(igraph_vector_char_destroy, v); } while (0) #endif #ifndef IGRAPH_VECTOR_INT_INIT_FINALLY #define IGRAPH_VECTOR_INT_INIT_FINALLY(v, size) \ do { IGRAPH_CHECK(igraph_vector_int_init(v, size)); \ IGRAPH_FINALLY(igraph_vector_int_destroy, v); } while (0) #endif #ifndef IGRAPH_VECTOR_LONG_INIT_FINALLY #define IGRAPH_VECTOR_LONG_INIT_FINALLY(v, size) \ do { IGRAPH_CHECK(igraph_vector_long_init(v, size)); \ IGRAPH_FINALLY(igraph_vector_long_destroy, v); } while (0) #endif /* -------------------------------------------------- */ /* Type-specific vector functions */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_vector_floor(const igraph_vector_t *from, igraph_vector_long_t *to); IGRAPH_EXPORT int igraph_vector_round(const igraph_vector_t *from, igraph_vector_long_t *to); IGRAPH_EXPORT igraph_bool_t igraph_vector_e_tol(const igraph_vector_t *lhs, const igraph_vector_t *rhs, igraph_real_t tol); IGRAPH_EXPORT int igraph_vector_zapsmall(igraph_vector_t *v, igraph_real_t tol); IGRAPH_EXPORT int igraph_vector_order(const igraph_vector_t* v, const igraph_vector_t *v2, igraph_vector_t* res, igraph_real_t maxval); IGRAPH_EXPORT int igraph_vector_order1(const igraph_vector_t* v, igraph_vector_t* res, igraph_real_t maxval); IGRAPH_EXPORT int igraph_vector_order1_int(const igraph_vector_t* v, igraph_vector_int_t* res, igraph_real_t maxval); IGRAPH_EXPORT int igraph_vector_order2(igraph_vector_t *v); IGRAPH_EXPORT int igraph_vector_rank(const igraph_vector_t *v, igraph_vector_t *res, long int nodes); IGRAPH_EXPORT int igraph_vector_is_nan(const igraph_vector_t *v, igraph_vector_bool_t *is_nan); IGRAPH_EXPORT igraph_bool_t igraph_vector_is_any_nan(const igraph_vector_t *v); __END_DECLS #endif leidenbase/src/include/igraph_vector_type.h0000644000176200001440000000204714447675375020656 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Vector, dealing with arrays efficiently. * \ingroup types */ typedef struct TYPE(igraph_vector) { BASE* stor_begin; BASE* stor_end; BASE* end; } TYPE(igraph_vector); leidenbase/src/include/igraph_centrality.h0000644000176200001440000002674314447675375020502 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CENTRALITY_H #define IGRAPH_CENTRALITY_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_datatype.h" #include "igraph_iterators.h" #include "igraph_arpack.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Centrality */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_closeness(const igraph_t *graph, igraph_vector_t *res, igraph_vector_t *reachable_count, igraph_bool_t *all_reachable, const igraph_vs_t vids, igraph_neimode_t mode, const igraph_vector_t *weights, igraph_bool_t normalized); IGRAPH_EXPORT int igraph_closeness_cutoff(const igraph_t *graph, igraph_vector_t *res, igraph_vector_t *reachable_count, igraph_bool_t *all_reachable, const igraph_vs_t vids, igraph_neimode_t mode, const igraph_vector_t *weights, igraph_bool_t normalized, igraph_real_t cutoff); IGRAPH_EXPORT int igraph_harmonic_centrality(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, const igraph_vector_t *weights, igraph_bool_t normalized); IGRAPH_EXPORT int igraph_harmonic_centrality_cutoff(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, const igraph_vector_t *weights, igraph_bool_t normalized, igraph_real_t cutoff); IGRAPH_EXPORT int igraph_betweenness(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_bool_t directed, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_betweenness_cutoff(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_bool_t directed, const igraph_vector_t *weights, igraph_real_t cutoff); IGRAPH_EXPORT int igraph_edge_betweenness(const igraph_t *graph, igraph_vector_t *result, igraph_bool_t directed, const igraph_vector_t *weigths); IGRAPH_EXPORT int igraph_edge_betweenness_cutoff(const igraph_t *graph, igraph_vector_t *result, igraph_bool_t directed, const igraph_vector_t *weights, igraph_real_t cutoff); /** * \typedef igraph_pagerank_algo_t * \brief PageRank algorithm implementation * * Algorithms to calculate PageRank. * \enumval IGRAPH_PAGERANK_ALGO_ARPACK Use the ARPACK library, this * was the PageRank implementation in igraph from version 0.5, until * version 0.7. * \enumval IGRAPH_PAGERANK_ALGO_PRPACK Use the PRPACK * library. Currently this implementation is recommended. */ typedef enum { IGRAPH_PAGERANK_ALGO_ARPACK = 1, IGRAPH_PAGERANK_ALGO_PRPACK = 2 } igraph_pagerank_algo_t; IGRAPH_EXPORT int igraph_pagerank(const igraph_t *graph, igraph_pagerank_algo_t algo, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *weights, igraph_arpack_options_t *options); IGRAPH_EXPORT int igraph_personalized_pagerank(const igraph_t *graph, igraph_pagerank_algo_t algo, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *reset, const igraph_vector_t *weights, igraph_arpack_options_t *options); IGRAPH_EXPORT int igraph_personalized_pagerank_vs(const igraph_t *graph, igraph_pagerank_algo_t algo, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, igraph_vs_t reset_vids, const igraph_vector_t *weights, igraph_arpack_options_t *options); IGRAPH_EXPORT int igraph_eigenvector_centrality(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t directed, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options); IGRAPH_EXPORT int igraph_hub_score(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options); IGRAPH_EXPORT int igraph_authority_score(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options); IGRAPH_EXPORT int igraph_constraint(const igraph_t *graph, igraph_vector_t *res, igraph_vs_t vids, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_convergence_degree(const igraph_t *graph, igraph_vector_t *result, igraph_vector_t *ins, igraph_vector_t *outs); IGRAPH_EXPORT igraph_real_t igraph_centralization(const igraph_vector_t *scores, igraph_real_t theoretical_max, igraph_bool_t normalized); IGRAPH_EXPORT int igraph_centralization_degree(const igraph_t *graph, igraph_vector_t *res, igraph_neimode_t mode, igraph_bool_t loops, igraph_real_t *centralization, igraph_real_t *theoretical_max, igraph_bool_t normalized); IGRAPH_EXPORT int igraph_centralization_degree_tmax(const igraph_t *graph, igraph_integer_t nodes, igraph_neimode_t mode, igraph_bool_t loops, igraph_real_t *res); IGRAPH_EXPORT int igraph_centralization_betweenness(const igraph_t *graph, igraph_vector_t *res, igraph_bool_t directed, igraph_real_t *centralization, igraph_real_t *theoretical_max, igraph_bool_t normalized); IGRAPH_EXPORT int igraph_centralization_betweenness_tmax(const igraph_t *graph, igraph_integer_t nodes, igraph_bool_t directed, igraph_real_t *res); IGRAPH_EXPORT int igraph_centralization_closeness(const igraph_t *graph, igraph_vector_t *res, igraph_neimode_t mode, igraph_real_t *centralization, igraph_real_t *theoretical_max, igraph_bool_t normalized); IGRAPH_EXPORT int igraph_centralization_closeness_tmax(const igraph_t *graph, igraph_integer_t nodes, igraph_neimode_t mode, igraph_real_t *res); IGRAPH_EXPORT int igraph_centralization_eigenvector_centrality( const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t directed, igraph_bool_t scale, igraph_arpack_options_t *options, igraph_real_t *centralization, igraph_real_t *theoretical_max, igraph_bool_t normalized); IGRAPH_EXPORT int igraph_centralization_eigenvector_centrality_tmax( const igraph_t *graph, igraph_integer_t nodes, igraph_bool_t directed, igraph_bool_t scale, igraph_real_t *res); /* Deprecated functions: */ IGRAPH_EXPORT IGRAPH_DEPRECATED int igraph_closeness_estimate(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_real_t cutoff, const igraph_vector_t *weights, igraph_bool_t normalized); IGRAPH_EXPORT IGRAPH_DEPRECATED int igraph_betweenness_estimate(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t cutoff, const igraph_vector_t *weights); IGRAPH_EXPORT IGRAPH_DEPRECATED int igraph_edge_betweenness_estimate(const igraph_t *graph, igraph_vector_t *result, igraph_bool_t directed, igraph_real_t cutoff, const igraph_vector_t *weights); __END_DECLS #endif leidenbase/src/include/igraph_mixing.h0000644000176200001440000000354514447675375017612 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_MIXING_H #define IGRAPH_MIXING_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_datatype.h" #include "igraph_vector.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_assortativity_nominal(const igraph_t *graph, const igraph_vector_t *types, igraph_real_t *res, igraph_bool_t directed); IGRAPH_EXPORT int igraph_assortativity(const igraph_t *graph, const igraph_vector_t *types1, const igraph_vector_t *types2, igraph_real_t *res, igraph_bool_t directed); IGRAPH_EXPORT int igraph_assortativity_degree(const igraph_t *graph, igraph_real_t *res, igraph_bool_t directed); __END_DECLS #endif leidenbase/src/include/igraph_bipartite.h0000644000176200001440000001112514447675375020273 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_BIPARTITE_H #define IGRAPH_BIPARTITE_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_matrix.h" #include "igraph_datatype.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Bipartite networks */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_full_bipartite(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_bool_t directed, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_create_bipartite(igraph_t *g, const igraph_vector_bool_t *types, const igraph_vector_t *edges, igraph_bool_t directed); IGRAPH_EXPORT int igraph_bipartite_projection_size(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_integer_t *vcount1, igraph_integer_t *ecount1, igraph_integer_t *vcount2, igraph_integer_t *ecount2); IGRAPH_EXPORT int igraph_bipartite_projection(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_t *proj1, igraph_t *proj2, igraph_vector_t *multiplicity1, igraph_vector_t *multiplicity2, igraph_integer_t probe1); IGRAPH_EXPORT int igraph_incidence(igraph_t *graph, igraph_vector_bool_t *types, const igraph_matrix_t *incidence, igraph_bool_t directed, igraph_neimode_t mode, igraph_bool_t multiple); IGRAPH_EXPORT int igraph_get_incidence(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_matrix_t *res, igraph_vector_t *row_ids, igraph_vector_t *col_ids); IGRAPH_EXPORT int igraph_is_bipartite(const igraph_t *graph, igraph_bool_t *res, igraph_vector_bool_t *types); IGRAPH_EXPORT int igraph_bipartite_game(igraph_t *graph, igraph_vector_bool_t *types, igraph_erdos_renyi_t type, igraph_integer_t n1, igraph_integer_t n2, igraph_real_t p, igraph_integer_t m, igraph_bool_t directed, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_bipartite_game_gnp(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_real_t p, igraph_bool_t directed, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_bipartite_game_gnm(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_integer_t m, igraph_bool_t directed, igraph_neimode_t mode); __END_DECLS #endif leidenbase/src/include/igraph_transitivity.h0000644000176200001440000000612614447675375021066 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_TRANSITIVITY_H #define IGRAPH_TRANSITIVITY_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_constants.h" #include "igraph_iterators.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_transitivity_undirected(const igraph_t *graph, igraph_real_t *res, igraph_transitivity_mode_t mode); IGRAPH_EXPORT int igraph_transitivity_local_undirected(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_transitivity_mode_t mode); IGRAPH_EXPORT int igraph_transitivity_local_undirected1(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_transitivity_mode_t mode); IGRAPH_EXPORT int igraph_transitivity_local_undirected2(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_transitivity_mode_t mode); IGRAPH_EXPORT int igraph_transitivity_local_undirected4(const igraph_t *graph, igraph_vector_t *res, igraph_transitivity_mode_t mode); IGRAPH_EXPORT int igraph_transitivity_avglocal_undirected(const igraph_t *graph, igraph_real_t *res, igraph_transitivity_mode_t mode); IGRAPH_EXPORT int igraph_transitivity_barrat(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, const igraph_vector_t *weights, const igraph_transitivity_mode_t mode); __END_DECLS #endif leidenbase/src/include/igraph_scg.h0000644000176200001440000001604014447675375017065 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_SCG_H #define IGRAPH_SCG_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_matrix.h" #include "igraph_sparsemat.h" __BEGIN_DECLS typedef enum { IGRAPH_SCG_SYMMETRIC = 1, IGRAPH_SCG_LAPLACIAN = 2, IGRAPH_SCG_STOCHASTIC = 3 } igraph_scg_matrix_t; typedef enum { IGRAPH_SCG_OPTIMUM = 1, IGRAPH_SCG_INTERV_KM = 2, IGRAPH_SCG_INTERV = 3, IGRAPH_SCG_EXACT = 4 } igraph_scg_algorithm_t; typedef enum { IGRAPH_SCG_NORM_ROW = 1, IGRAPH_SCG_NORM_COL = 2 } igraph_scg_norm_t; typedef enum { IGRAPH_SCG_DIRECTION_DEFAULT = 1, IGRAPH_SCG_DIRECTION_LEFT = 2, IGRAPH_SCG_DIRECTION_RIGHT = 3 } igraph_scg_direction_t; IGRAPH_EXPORT int igraph_scg_grouping(const igraph_matrix_t *V, igraph_vector_t *groups, igraph_integer_t nt, const igraph_vector_t *nt_vec, igraph_scg_matrix_t mtype, igraph_scg_algorithm_t algo, const igraph_vector_t *p, igraph_integer_t maxiter); IGRAPH_EXPORT int igraph_scg_semiprojectors(const igraph_vector_t *groups, igraph_scg_matrix_t mtype, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse, const igraph_vector_t *p, igraph_scg_norm_t norm); IGRAPH_EXPORT int igraph_scg_norm_eps(const igraph_matrix_t *V, const igraph_vector_t *groups, igraph_vector_t *eps, igraph_scg_matrix_t mtype, const igraph_vector_t *p, igraph_scg_norm_t norm); IGRAPH_EXPORT int igraph_scg_adjacency(const igraph_t *graph, const igraph_matrix_t *matrix, const igraph_sparsemat_t *sparsemat, const igraph_vector_t *ev, igraph_integer_t nt, const igraph_vector_t *nt_vec, igraph_scg_algorithm_t algo, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_t *groups, igraph_bool_t use_arpack, igraph_integer_t maxiter, igraph_t *scg_graph, igraph_matrix_t *scg_matrix, igraph_sparsemat_t *scg_sparsemat, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse); IGRAPH_EXPORT int igraph_scg_stochastic(const igraph_t *graph, const igraph_matrix_t *matrix, const igraph_sparsemat_t *sparsemat, const igraph_vector_t *ev, igraph_integer_t nt, const igraph_vector_t *nt_vec, igraph_scg_algorithm_t algo, igraph_scg_norm_t norm, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors, igraph_vector_t *groups, igraph_vector_t *p, igraph_bool_t use_arpack, igraph_integer_t maxiter, igraph_t *scg_graph, igraph_matrix_t *scg_matrix, igraph_sparsemat_t *scg_sparsemat, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse); IGRAPH_EXPORT int igraph_scg_laplacian(const igraph_t *graph, const igraph_matrix_t *matrix, const igraph_sparsemat_t *sparsemat, const igraph_vector_t *ev, igraph_integer_t nt, const igraph_vector_t *nt_vec, igraph_scg_algorithm_t algo, igraph_scg_norm_t norm, igraph_scg_direction_t direction, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors, igraph_vector_t *groups, igraph_bool_t use_arpack, igraph_integer_t maxiter, igraph_t *scg_graph, igraph_matrix_t *scg_matrix, igraph_sparsemat_t *scg_sparsemat, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse); __END_DECLS #endif leidenbase/src/include/igraph_eulerian.h0000644000176200001440000000254014447675375020115 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_EULERIAN_H #define IGRAPH_EULERIAN_H #include "igraph_decls.h" #include "igraph_datatype.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_is_eulerian(const igraph_t *graph, igraph_bool_t *has_path, igraph_bool_t *has_cycle); IGRAPH_EXPORT int igraph_eulerian_path(const igraph_t *graph, igraph_vector_t *edge_res, igraph_vector_t *vertex_res); IGRAPH_EXPORT int igraph_eulerian_cycle(const igraph_t *graph, igraph_vector_t *edge_res, igraph_vector_t *vertex_res); __END_DECLS #endif leidenbase/src/include/igraph_constants.h0000644000176200001440000001567414447675375020341 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CONSTANTS_H #define IGRAPH_CONSTANTS_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_datatype.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Constants */ /* -------------------------------------------------- */ typedef enum { IGRAPH_UNDIRECTED = 0, IGRAPH_DIRECTED = 1 } igraph_i_directed_t; /* Note for the enum below: yes, IGRAPH_LOOPS_TWICE is 1, and IGRAPH_LOOPS_ONCE * is 2. This is intentional, for the sake of backwards compatibility with * earlier versions where we only had IGRAPH_LOOPS and it meant * IGRAPH_LOOPS_TWICE */ typedef enum { IGRAPH_NO_LOOPS = 0, IGRAPH_LOOPS = 1, IGRAPH_LOOPS_TWICE = 1, IGRAPH_LOOPS_ONCE = 2 } igraph_loops_t; typedef enum { IGRAPH_NO_MULTIPLE = 0, IGRAPH_MULTIPLE = 1 } igraph_multiple_t; typedef enum { IGRAPH_ASCENDING = 0, IGRAPH_DESCENDING = 1 } igraph_order_t; typedef enum { IGRAPH_MINIMUM = 0, IGRAPH_MAXIMUM = 1 } igraph_optimal_t; typedef enum { IGRAPH_OUT = 1, IGRAPH_IN = 2, IGRAPH_ALL = 3, IGRAPH_TOTAL = 3 } igraph_neimode_t; /* Reverse IGRAPH_OUT to IGRAPH_IN and vice versa. Leave other values alone. */ #define IGRAPH_REVERSE_MODE(mode) \ ((mode) == IGRAPH_IN ? IGRAPH_OUT : ((mode) == IGRAPH_OUT ? IGRAPH_IN : (mode))) typedef enum { IGRAPH_WEAK = 1, IGRAPH_STRONG = 2 } igraph_connectedness_t; typedef enum { IGRAPH_RECIPROCITY_DEFAULT = 0, IGRAPH_RECIPROCITY_RATIO = 1 } igraph_reciprocity_t; typedef enum { IGRAPH_ADJ_DIRECTED = 0, IGRAPH_ADJ_UNDIRECTED = 1, IGRAPH_ADJ_MAX = 1, IGRAPH_ADJ_UPPER, IGRAPH_ADJ_LOWER, IGRAPH_ADJ_MIN, IGRAPH_ADJ_PLUS } igraph_adjacency_t; typedef enum { IGRAPH_STAR_OUT = 0, IGRAPH_STAR_IN, IGRAPH_STAR_UNDIRECTED, IGRAPH_STAR_MUTUAL } igraph_star_mode_t; typedef enum { IGRAPH_TREE_OUT = 0, IGRAPH_TREE_IN, IGRAPH_TREE_UNDIRECTED } igraph_tree_mode_t; typedef enum { IGRAPH_ERDOS_RENYI_GNP = 0, IGRAPH_ERDOS_RENYI_GNM } igraph_erdos_renyi_t; typedef enum { IGRAPH_GET_ADJACENCY_UPPER = 0, IGRAPH_GET_ADJACENCY_LOWER, IGRAPH_GET_ADJACENCY_BOTH } igraph_get_adjacency_t; typedef enum { IGRAPH_DEGSEQ_SIMPLE = 0, IGRAPH_DEGSEQ_VL, IGRAPH_DEGSEQ_SIMPLE_NO_MULTIPLE, IGRAPH_DEGSEQ_SIMPLE_NO_MULTIPLE_UNIFORM } igraph_degseq_t; typedef enum { IGRAPH_REALIZE_DEGSEQ_SMALLEST = 0, IGRAPH_REALIZE_DEGSEQ_LARGEST, IGRAPH_REALIZE_DEGSEQ_INDEX } igraph_realize_degseq_t; typedef enum { IGRAPH_RANDOM_TREE_PRUFER = 0, IGRAPH_RANDOM_TREE_LERW } igraph_random_tree_t; typedef enum { IGRAPH_FILEFORMAT_EDGELIST = 0, IGRAPH_FILEFORMAT_NCOL, IGRAPH_FILEFORMAT_PAJEK, IGRAPH_FILEFORMAT_LGL, IGRAPH_FILEFORMAT_GRAPHML } igraph_fileformat_type_t; typedef enum { IGRAPH_REWIRING_SIMPLE = 0, IGRAPH_REWIRING_SIMPLE_LOOPS } igraph_rewiring_t; typedef enum { IGRAPH_EDGEORDER_ID = 0, IGRAPH_EDGEORDER_FROM, IGRAPH_EDGEORDER_TO } igraph_edgeorder_type_t; typedef enum { IGRAPH_TO_DIRECTED_ARBITRARY = 0, IGRAPH_TO_DIRECTED_MUTUAL, IGRAPH_TO_DIRECTED_RANDOM, IGRAPH_TO_DIRECTED_ACYCLIC } igraph_to_directed_t; typedef enum { IGRAPH_TO_UNDIRECTED_EACH = 0, IGRAPH_TO_UNDIRECTED_COLLAPSE, IGRAPH_TO_UNDIRECTED_MUTUAL } igraph_to_undirected_t; typedef enum { IGRAPH_VCONN_NEI_ERROR = 0, IGRAPH_VCONN_NEI_NUMBER_OF_NODES, IGRAPH_VCONN_NEI_IGNORE, IGRAPH_VCONN_NEI_NEGATIVE } igraph_vconn_nei_t; typedef enum { IGRAPH_SPINCOMM_UPDATE_SIMPLE = 0, IGRAPH_SPINCOMM_UPDATE_CONFIG } igraph_spincomm_update_t; typedef enum { IGRAPH_DONT_SIMPLIFY = 0, IGRAPH_SIMPLIFY } igraph_lazy_adlist_simplify_t; typedef enum { IGRAPH_TRANSITIVITY_NAN = 0, IGRAPH_TRANSITIVITY_ZERO } igraph_transitivity_mode_t; typedef enum { IGRAPH_SPINCOMM_IMP_ORIG = 0, IGRAPH_SPINCOMM_IMP_NEG } igraph_spinglass_implementation_t; typedef enum { IGRAPH_COMMCMP_VI = 0, IGRAPH_COMMCMP_NMI, IGRAPH_COMMCMP_SPLIT_JOIN, IGRAPH_COMMCMP_RAND, IGRAPH_COMMCMP_ADJUSTED_RAND } igraph_community_comparison_t; typedef enum { IGRAPH_ADD_WEIGHTS_NO = 0, IGRAPH_ADD_WEIGHTS_YES, IGRAPH_ADD_WEIGHTS_IF_PRESENT } igraph_add_weights_t; typedef enum { IGRAPH_BARABASI_BAG = 0, IGRAPH_BARABASI_PSUMTREE, IGRAPH_BARABASI_PSUMTREE_MULTIPLE } igraph_barabasi_algorithm_t; typedef enum { IGRAPH_FAS_EXACT_IP = 0, IGRAPH_FAS_APPROX_EADES } igraph_fas_algorithm_t; typedef enum { IGRAPH_SUBGRAPH_AUTO = 0, IGRAPH_SUBGRAPH_COPY_AND_DELETE, IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH } igraph_subgraph_implementation_t; typedef enum { IGRAPH_IMITATE_AUGMENTED = 0, IGRAPH_IMITATE_BLIND, IGRAPH_IMITATE_CONTRACTED } igraph_imitate_algorithm_t; typedef igraph_real_t igraph_scalar_function_t(const igraph_vector_t *var, const igraph_vector_t *par, void* extra); typedef void igraph_vector_function_t(const igraph_vector_t *var, const igraph_vector_t *par, igraph_vector_t* res, void* extra); typedef enum { IGRAPH_LAYOUT_GRID = 0, IGRAPH_LAYOUT_NOGRID, IGRAPH_LAYOUT_AUTOGRID } igraph_layout_grid_t; typedef enum { IGRAPH_RANDOM_WALK_STUCK_ERROR = 0, IGRAPH_RANDOM_WALK_STUCK_RETURN } igraph_random_walk_stuck_t; __END_DECLS #endif leidenbase/src/include/igraph_motifs.h0000644000176200001440000001027714447675375017620 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_MOTIFS_H #define IGRAPH_MOTIFS_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_datatype.h" #include "igraph_iterators.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Graph motifs */ /* -------------------------------------------------- */ /** * \typedef igraph_motifs_handler_t * Callback type for \c igraph_motifs_randesu_callback * * \ref igraph_motifs_randesu_callback() calls a specified callback * function whenever a new motif is found during a motif search. This * callback function must be of type \c igraph_motifs_handler_t. It has * the following arguments: * \param graph The graph that that algorithm is working on. Of course * this must not be modified. * \param vids The IDs of the vertices in the motif that has just been * found. This vector is owned by the motif search algorithm, so do not * modify or destroy it; make a copy of it if you need it later. * \param isoclass The isomorphism class of the motif that has just been * found. Use \ref igraph_isoclass or \ref igraph_isoclass_subgraph to find * out which isomorphism class belongs to a given motif. * \param extra The extra argument that was passed to \ref * igraph_motifs_randesu_callback(). * \return A logical value, if TRUE (=non-zero), that is interpreted * as a request to stop the motif search and return to the caller. * * \sa \ref igraph_motifs_randesu_callback() */ typedef igraph_bool_t igraph_motifs_handler_t(const igraph_t *graph, igraph_vector_t *vids, int isoclass, void* extra); IGRAPH_EXPORT int igraph_motifs_randesu(const igraph_t *graph, igraph_vector_t *hist, int size, const igraph_vector_t *cut_prob); IGRAPH_EXPORT int igraph_motifs_randesu_callback(const igraph_t *graph, int size, const igraph_vector_t *cut_prob, igraph_motifs_handler_t *callback, void* extra); IGRAPH_EXPORT int igraph_motifs_randesu_estimate(const igraph_t *graph, igraph_integer_t *est, int size, const igraph_vector_t *cut_prob, igraph_integer_t sample_size, const igraph_vector_t *sample); IGRAPH_EXPORT int igraph_motifs_randesu_no(const igraph_t *graph, igraph_integer_t *no, int size, const igraph_vector_t *cut_prob); IGRAPH_EXPORT int igraph_dyad_census(const igraph_t *graph, igraph_integer_t *mut, igraph_integer_t *asym, igraph_integer_t *null); IGRAPH_EXPORT int igraph_triad_census(const igraph_t *igraph, igraph_vector_t *res); IGRAPH_EXPORT int igraph_triad_census_24(const igraph_t *graph, igraph_real_t *res2, igraph_real_t *res4); IGRAPH_EXPORT int igraph_adjacent_triangles(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids); IGRAPH_EXPORT int igraph_list_triangles(const igraph_t *graph, igraph_vector_int_t *res); __END_DECLS #endif leidenbase/src/include/igraph_lapack.h0000644000176200001440000001113414447675375017543 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_LAPACK_H #define IGRAPH_LAPACK_H #include "igraph_decls.h" #include "igraph_vector.h" #include "igraph_matrix.h" __BEGIN_DECLS /** * \section about_lapack LAPACK interface in igraph * * * LAPACK is written in Fortran90 and provides routines for solving * systems of simultaneous linear equations, least-squares solutions * of linear systems of equations, eigenvalue problems, and singular * value problems. The associated matrix factorizations (LU, Cholesky, * QR, SVD, Schur, generalized Schur) are also provided, as are * related computations such as reordering of the Schur factorizations * and estimating condition numbers. Dense and banded matrices are * handled, but not general sparse matrices. In all areas, similar * functionality is provided for real and complex matrices, in both * single and double precision. * * * * igraph provides an interface to a very limited set of LAPACK * functions, using the regular igraph data structures. * * * * See more about LAPACK at http://www.netlib.org/lapack/ * */ IGRAPH_EXPORT int igraph_lapack_dgetrf(igraph_matrix_t *a, igraph_vector_int_t *ipiv, int *info); IGRAPH_EXPORT int igraph_lapack_dgetrs(igraph_bool_t transpose, const igraph_matrix_t *a, const igraph_vector_int_t *ipiv, igraph_matrix_t *b); IGRAPH_EXPORT int igraph_lapack_dgesv(igraph_matrix_t *a, igraph_vector_int_t *ipiv, igraph_matrix_t *b, int *info); typedef enum { IGRAPH_LAPACK_DSYEV_ALL, IGRAPH_LAPACK_DSYEV_INTERVAL, IGRAPH_LAPACK_DSYEV_SELECT } igraph_lapack_dsyev_which_t; IGRAPH_EXPORT int igraph_lapack_dsyevr(const igraph_matrix_t *A, igraph_lapack_dsyev_which_t which, igraph_real_t vl, igraph_real_t vu, int vestimate, int il, int iu, igraph_real_t abstol, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_int_t *support); /* TODO: should we use complex vectors/matrices? */ IGRAPH_EXPORT int igraph_lapack_dgeev(const igraph_matrix_t *A, igraph_vector_t *valuesreal, igraph_vector_t *valuesimag, igraph_matrix_t *vectorsleft, igraph_matrix_t *vectorsright, int *info); typedef enum { IGRAPH_LAPACK_DGEEVX_BALANCE_NONE = 0, IGRAPH_LAPACK_DGEEVX_BALANCE_PERM, IGRAPH_LAPACK_DGEEVX_BALANCE_SCALE, IGRAPH_LAPACK_DGEEVX_BALANCE_BOTH } igraph_lapack_dgeevx_balance_t; IGRAPH_EXPORT int igraph_lapack_dgeevx(igraph_lapack_dgeevx_balance_t balance, const igraph_matrix_t *A, igraph_vector_t *valuesreal, igraph_vector_t *valuesimag, igraph_matrix_t *vectorsleft, igraph_matrix_t *vectorsright, int *ilo, int *ihi, igraph_vector_t *scale, igraph_real_t *abnrm, igraph_vector_t *rconde, igraph_vector_t *rcondv, int *info); IGRAPH_EXPORT int igraph_lapack_dgehrd(const igraph_matrix_t *A, int ilo, int ihi, igraph_matrix_t *result); __END_DECLS #endif leidenbase/src/include/igraph_statusbar.h0000644000176200001440000001027514447675375020325 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_STATUSBAR_H #define IGRAPH_STATUSBAR_H #include "igraph_decls.h" __BEGIN_DECLS /** * \section about_status_handlers Status reporting * * * In addition to the possibility of reporting the progress of an * igraph computation via \ref igraph_progress(), it is also possible * to report simple status messages from within igraph functions, * without having to judge how much of the computation was performed * already. For this one needs to install a status handler function. * * * * Status handler functions must be of type \ref igraph_status_handler_t * and they can be install by a call to \ref igraph_set_status_handler(). * Currently there is a simple predefined status handler function, * called \ref igraph_status_handler_stderr(), but the user can define * new ones. * * * * igraph functions report their status via a call to the * \ref IGRAPH_STATUS() or the \ref IGRAPH_STATUSF() macro. * */ /** * \typedef igraph_status_handler_t * * The type of the igraph status handler functions * \param message The status message. * \param data Additional context, with user-defined semantics. * Existing igraph functions pass a null pointer here. */ typedef int igraph_status_handler_t(const char *message, void *data); IGRAPH_EXPORT extern igraph_status_handler_t igraph_status_handler_stderr; IGRAPH_EXPORT igraph_status_handler_t * igraph_set_status_handler(igraph_status_handler_t new_handler); IGRAPH_EXPORT int igraph_status(const char *message, void *data); /** * \define IGRAPH_STATUS * Report the status of an igraph function. * * Typically this function is called only a handful of times from * an igraph function. E.g. if an algorithm has three major * steps, then it is logical to call it three times, to * signal the three major steps. * \param message The status message. * \param data Additional context, with user-defined semantics. * Existing igraph functions pass a null pointer here. * \return If the status handler returns with a value other than * \c IGRAPH_SUCCESS, then the function that called this * macro returns as well, with error code * \c IGRAPH_INTERRUPTED. */ #define IGRAPH_STATUS(message, data) \ do { \ if (igraph_status((message), (data)) != IGRAPH_SUCCESS) { \ IGRAPH_FINALLY_FREE(); \ return IGRAPH_INTERRUPTED; \ } \ } while (0) IGRAPH_EXPORT int igraph_statusf(const char *message, void *data, ...); /** * \define IGRAPH_STATUSF * Report the status from an igraph function * * This is the more flexible version of \ref IGRAPH_STATUS(), * having a printf-like syntax. As this macro takes variable * number of arguments, they must be all supplied as a single * argument, enclosed in parentheses. Then \ref igraph_statusf() * is called with the given arguments. * \param args The arguments to pass to \ref igraph_statusf(). * \return If the status handler returns with a value other than * \c IGRAPH_SUCCESS, then the function that called this * macro returns as well, with error code * \c IGRAPH_INTERRUPTED. */ #define IGRAPH_STATUSF(args) \ do { \ if (igraph_statusf args != IGRAPH_SUCCESS) { \ IGRAPH_FINALLY_FREE(); \ return IGRAPH_INTERRUPTED; \ } \ } while (0) __END_DECLS #endif leidenbase/src/include/igraph_graphicality.h0000644000176200001440000000473114447675375020775 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2009-2020 Gabor Csardi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IGRAPH_GRAPHICALITY_H #define IGRAPH_GRAPHICALITY_H #include "igraph_decls.h" #include "igraph_datatype.h" __BEGIN_DECLS typedef unsigned char igraph_edge_type_sw_t; /* * bit 0: self-loops alowed? * bit 1: more than one edge allowed between distinct vertices? * bit 2: more than one self-loop allowed (assuming bit 0 is set)? */ enum { IGRAPH_SIMPLE_SW = 0x00, /* 000 */ IGRAPH_LOOPS_SW = 0x01, /* 001 */ IGRAPH_MULTI_SW = 0x06 /* 110 */ }; IGRAPH_EXPORT int igraph_is_graphical(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, const igraph_edge_type_sw_t allowed_edge_types, igraph_bool_t *res); IGRAPH_EXPORT int igraph_is_bigraphical(const igraph_vector_t *degrees1, const igraph_vector_t *degrees2, const igraph_edge_type_sw_t allowed_edge_types, igraph_bool_t *res); /* Legacy functions (deprecated): */ IGRAPH_EXPORT IGRAPH_DEPRECATED int igraph_is_degree_sequence(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res); IGRAPH_EXPORT IGRAPH_DEPRECATED int igraph_is_graphical_degree_sequence(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res); __END_DECLS #endif // IGRAPH_GRAPHICALITY_H leidenbase/src/include/igraph_interface.h0000644000176200001440000001313114447675375020247 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_INTERFACE_H #define IGRAPH_INTERFACE_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_datatype.h" #include "igraph_iterators.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Interface */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_empty(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed); IGRAPH_EXPORT int igraph_empty_attrs(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, void *attr); IGRAPH_EXPORT void igraph_destroy(igraph_t *graph); IGRAPH_EXPORT int igraph_copy(igraph_t *to, const igraph_t *from); IGRAPH_EXPORT int igraph_add_edges(igraph_t *graph, const igraph_vector_t *edges, void *attr); IGRAPH_EXPORT int igraph_add_vertices(igraph_t *graph, igraph_integer_t nv, void *attr); IGRAPH_EXPORT int igraph_delete_edges(igraph_t *graph, igraph_es_t edges); IGRAPH_EXPORT int igraph_delete_vertices(igraph_t *graph, const igraph_vs_t vertices); IGRAPH_EXPORT int igraph_delete_vertices_idx(igraph_t *graph, const igraph_vs_t vertices, igraph_vector_t *idx, igraph_vector_t *invidx); IGRAPH_EXPORT igraph_integer_t igraph_vcount(const igraph_t *graph); IGRAPH_EXPORT igraph_integer_t igraph_ecount(const igraph_t *graph); IGRAPH_EXPORT int igraph_neighbors(const igraph_t *graph, igraph_vector_t *neis, igraph_integer_t vid, igraph_neimode_t mode); IGRAPH_EXPORT igraph_bool_t igraph_is_directed(const igraph_t *graph); IGRAPH_EXPORT int igraph_degree(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT int igraph_edge(const igraph_t *graph, igraph_integer_t eid, igraph_integer_t *from, igraph_integer_t *to); IGRAPH_EXPORT int igraph_edges(const igraph_t *graph, igraph_es_t eids, igraph_vector_t *edges); IGRAPH_EXPORT int igraph_get_eid(const igraph_t *graph, igraph_integer_t *eid, igraph_integer_t from, igraph_integer_t to, igraph_bool_t directed, igraph_bool_t error); IGRAPH_EXPORT int igraph_get_eids(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *pairs, const igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t error); IGRAPH_EXPORT int igraph_get_eids_multi(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *pairs, const igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t error); IGRAPH_EXPORT int igraph_incident(const igraph_t *graph, igraph_vector_t *eids, igraph_integer_t vid, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_is_same_graph(const igraph_t *graph1, const igraph_t *igraph2, igraph_bool_t *res); /** * \define IGRAPH_FROM * \brief The source vertex of an edge. * * Faster than \ref igraph_edge(), but no error checking is done: \p eid is assumed to be valid. * * \param graph The graph. * \param eid The edge ID. * \return The source vertex of the edge. * \sa \ref igraph_edge() if error checking is desired. */ #define IGRAPH_FROM(graph,eid) ((igraph_integer_t)(VECTOR((graph)->from)[(long int)(eid)])) /** * \define IGRAPH_TO * \brief The target vertex of an edge. * * Faster than \ref igraph_edge(), but no error checking is done: \p eid is assumed to be valid. * * \param graph The graph object. * \param eid The edge ID. * \return The target vertex of the edge. * \sa \ref igraph_edge() if error checking is desired. */ #define IGRAPH_TO(graph,eid) ((igraph_integer_t)(VECTOR((graph)->to) [(long int)(eid)])) /** * \define IGRAPH_OTHER * \brief The other endpoint of an edge. * * Typically used with undirected edges when one endpoint of the edge is known, * and the other endpoint is needed. No error checking is done: * \p eid and \p vid are assumed to be valid. * * \param graph The graph object. * \param eid The edge ID. * \param vid The vertex ID of one endpoint of an edge. * \return The other endpoint of the edge. * \sa \ref IGRAPH_TO() and \ref IGRAPH_FROM() to get the source and target * of directed edges. */ #define IGRAPH_OTHER(graph,eid,vid) \ ((igraph_integer_t)(IGRAPH_TO(graph,(eid))==(vid) ? IGRAPH_FROM((graph),(eid)) : IGRAPH_TO((graph),(eid)))) __END_DECLS #endif leidenbase/src/include/igraph_matrix.h0000644000176200001440000000553114447675375017620 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_MATRIX_H #define IGRAPH_MATRIX_H #include "igraph_decls.h" #include "igraph_vector.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Matrix, very similar to vector */ /* -------------------------------------------------- */ #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "igraph_matrix_pmt.h" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_INT #include "igraph_pmt.h" #include "igraph_matrix_pmt.h" #include "igraph_pmt_off.h" #undef BASE_INT #define BASE_LONG #include "igraph_pmt.h" #include "igraph_matrix_pmt.h" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_CHAR #include "igraph_pmt.h" #include "igraph_matrix_pmt.h" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "igraph_matrix_pmt.h" #include "igraph_pmt_off.h" #undef BASE_BOOL #define BASE_COMPLEX #include "igraph_pmt.h" #include "igraph_matrix_pmt.h" #include "igraph_pmt_off.h" #undef BASE_COMPLEX #define IGRAPH_MATRIX_NULL { IGRAPH_VECTOR_NULL, 0, 0 } #define IGRAPH_MATRIX_INIT_FINALLY(m, nr, nc) \ do { IGRAPH_CHECK(igraph_matrix_init(m, nr, nc)); \ IGRAPH_FINALLY(igraph_matrix_destroy, m); } while (0) /** * \ingroup matrix * \define MATRIX * \brief Accessing an element of a matrix. * * Note that there are no range checks right now. * This functionality might be redefined as a proper function later. * \param m The matrix object. * \param i The index of the row, starting with zero. * \param j The index of the column, starting with zero. * * Time complexity: O(1). */ #define MATRIX(m,i,j) ((m).data.stor_begin[(m).nrow*(j)+(i)]) IGRAPH_EXPORT igraph_bool_t igraph_matrix_all_e_tol(const igraph_matrix_t *lhs, const igraph_matrix_t *rhs, igraph_real_t tol); IGRAPH_EXPORT int igraph_matrix_zapsmall(igraph_matrix_t *m, igraph_real_t tol); __END_DECLS #endif leidenbase/src/include/igraph_cliques.h0000644000176200001440000001347114447675375017763 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CLIQUES_H #define IGRAPH_CLIQUES_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_datatype.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Cliques, maximal independent vertex sets */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_maximal_cliques(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size); IGRAPH_EXPORT int igraph_maximal_cliques_file(const igraph_t *graph, FILE *outfile, igraph_integer_t min_size, igraph_integer_t max_size); IGRAPH_EXPORT int igraph_maximal_cliques_count(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t min_size, igraph_integer_t max_size); IGRAPH_EXPORT int igraph_maximal_cliques_subset(const igraph_t *graph, igraph_vector_int_t *subset, igraph_vector_ptr_t *res, igraph_integer_t *no, FILE *outfile, igraph_integer_t min_size, igraph_integer_t max_size); IGRAPH_EXPORT int igraph_maximal_cliques_hist(const igraph_t *graph, igraph_vector_t *hist, igraph_integer_t min_size, igraph_integer_t max_size); IGRAPH_EXPORT int igraph_cliques(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size); IGRAPH_EXPORT int igraph_clique_size_hist(const igraph_t *graph, igraph_vector_t *hist, igraph_integer_t min_size, igraph_integer_t max_size); IGRAPH_EXPORT int igraph_largest_cliques(const igraph_t *graph, igraph_vector_ptr_t *cliques); IGRAPH_EXPORT int igraph_clique_number(const igraph_t *graph, igraph_integer_t *no); IGRAPH_EXPORT int igraph_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res, igraph_real_t min_weight, igraph_real_t max_weight, igraph_bool_t maximal); IGRAPH_EXPORT int igraph_largest_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res); IGRAPH_EXPORT int igraph_weighted_clique_number(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_real_t *res); IGRAPH_EXPORT int igraph_independent_vertex_sets(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size); IGRAPH_EXPORT int igraph_largest_independent_vertex_sets(const igraph_t *graph, igraph_vector_ptr_t *res); IGRAPH_EXPORT int igraph_maximal_independent_vertex_sets(const igraph_t *graph, igraph_vector_ptr_t *res); IGRAPH_EXPORT int igraph_independence_number(const igraph_t *graph, igraph_integer_t *no); /** * \typedef igraph_clique_handler_t * \brief Type of clique handler functions. * * Callback type, called when a clique was found. * * See the details at the documentation of \ref * igraph_cliques_callback(). * * \param clique The current clique. Destroying and freeing * this vector is left to the user. * Use \ref igraph_vector_destroy() and \ref igraph_free() * to do this. * \param arg This extra argument was passed to \ref * igraph_cliques_callback() when it was called. * \return Boolean, whether to continue with the clique search. */ typedef igraph_bool_t igraph_clique_handler_t(igraph_vector_t *clique, void *arg); IGRAPH_EXPORT int igraph_cliques_callback(const igraph_t *graph, igraph_integer_t min_size, igraph_integer_t max_size, igraph_clique_handler_t *cliquehandler_fn, void *arg); IGRAPH_EXPORT int igraph_maximal_cliques_callback(const igraph_t *graph, igraph_clique_handler_t *cliquehandler_fn, void *arg, igraph_integer_t min_size, igraph_integer_t max_size); __END_DECLS #endif leidenbase/src/include/igraph_nongraph.h0000644000176200001440000001001514447675375020121 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_NONGRAPH_H #define IGRAPH_NONGRAPH_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_matrix.h" #include "igraph_types.h" #include "igraph_vector.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Other, not graph related */ /* -------------------------------------------------- */ /** * \struct igraph_plfit_result_t * \brief Result of fitting a power-law distribution to a vector * * This data structure contains the result of \ref igraph_power_law_fit(), * which tries to fit a power-law distribution to a vector of numbers. The * structure contains the following members: * * \member continuous Whether the fitted power-law distribution was continuous * or discrete. * \member alpha The exponent of the fitted power-law distribution. * \member xmin The minimum value from which the power-law distribution was * fitted. In other words, only the values larger than \c xmin * were used from the input vector. * \member L The log-likelihood of the fitted parameters; in other words, * the probability of observing the input vector given the * parameters. * \member D The test statistic of a Kolmogorov-Smirnov test that compares * the fitted distribution with the input vector. Smaller scores * denote better fit. * \member p The p-value of the Kolmogorov-Smirnov test. Small p-values * (less than 0.05) indicate that the test rejected the hypothesis * that the original data could have been drawn from the fitted * power-law distribution. */ typedef struct igraph_plfit_result_t { igraph_bool_t continuous; double alpha; double xmin; double L; double D; double p; } igraph_plfit_result_t; IGRAPH_EXPORT int igraph_running_mean(const igraph_vector_t *data, igraph_vector_t *res, igraph_integer_t binwidth); IGRAPH_EXPORT int igraph_random_sample(igraph_vector_t *res, igraph_real_t l, igraph_real_t h, igraph_integer_t length); IGRAPH_EXPORT int igraph_convex_hull(const igraph_matrix_t *data, igraph_vector_t *resverts, igraph_matrix_t *rescoords); IGRAPH_EXPORT int igraph_zeroin(igraph_real_t *ax, igraph_real_t *bx, igraph_real_t (*f)(igraph_real_t x, void *info), void *info, igraph_real_t *Tol, int *Maxit, igraph_real_t *res); IGRAPH_EXPORT int igraph_bfgs(igraph_vector_t *b, igraph_real_t *Fmin, igraph_scalar_function_t fminfn, igraph_vector_function_t fmingr, int maxit, int trace, igraph_real_t abstol, igraph_real_t reltol, int nREPORT, void *ex, igraph_integer_t *fncount, igraph_integer_t *grcount); IGRAPH_EXPORT int igraph_power_law_fit(const igraph_vector_t* vector, igraph_plfit_result_t* result, igraph_real_t xmin, igraph_bool_t force_continuous); __END_DECLS #endif leidenbase/src/include/igraph_components.h0000644000176200001440000000521214447675375020475 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_COMPONENTS_H #define IGRAPH_COMPONENTS_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" #include "igraph_datatype.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Components */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_clusters(const igraph_t *graph, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t *no, igraph_connectedness_t mode); IGRAPH_EXPORT int igraph_is_connected(const igraph_t *graph, igraph_bool_t *res, igraph_connectedness_t mode); IGRAPH_EXPORT void igraph_decompose_destroy(igraph_vector_ptr_t *complist); IGRAPH_EXPORT int igraph_decompose(const igraph_t *graph, igraph_vector_ptr_t *components, igraph_connectedness_t mode, long int maxcompno, long int minelements); IGRAPH_EXPORT int igraph_articulation_points(const igraph_t *graph, igraph_vector_t *res); IGRAPH_EXPORT int igraph_biconnected_components(const igraph_t *graph, igraph_integer_t *no, igraph_vector_ptr_t *tree_edges, igraph_vector_ptr_t *component_edges, igraph_vector_ptr_t *components, igraph_vector_t *articulation_points); IGRAPH_EXPORT int igraph_bridges(const igraph_t *graph, igraph_vector_t *bridges); __END_DECLS #endif leidenbase/src/include/igraph_graphlets.h0000644000176200001440000000374714447675375020314 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_GRAPHLETS_H #define IGRAPH_GRAPHLETS_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_vector_ptr.h" #include "igraph_interface.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_graphlets_candidate_basis(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_ptr_t *cliques, igraph_vector_t *thresholds); IGRAPH_EXPORT int igraph_graphlets_project(const igraph_t *graph, const igraph_vector_t *weights, const igraph_vector_ptr_t *cliques, igraph_vector_t *Mu, igraph_bool_t startMu, int niter); IGRAPH_EXPORT int igraph_graphlets(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_ptr_t *cliques, igraph_vector_t *Mu, int niter); __END_DECLS #endif leidenbase/src/include/igraph_pmt.h0000644000176200001440000001004214447675375017105 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define CONCAT2x(a,b) a ## _ ## b #define CONCAT2(a,b) CONCAT2x(a,b) #define CONCAT3x(a,b,c) a ## _ ## b ## _ ## c #define CONCAT3(a,b,c) CONCAT3x(a,b,c) #define CONCAT4x(a,b,c,d) a ## _ ## b ## _ ## c ## _ ## d #define CONCAT4(a,b,c,d) CONCAT4x(a,b,c,d) #if defined(BASE_IGRAPH_REAL) #define BASE igraph_real_t #define SHORT #define OUT_FORMAT "%G" #define PRINTFUNC(val) igraph_real_printf(val) #define FPRINTFUNC(file, val) igraph_real_fprintf(file, val) #define ZERO 0.0 #define ONE 1.0 #define MULTIPLICITY 1 #elif defined(BASE_FLOAT) #define BASE float #define SHORT float #define OUT_FORMAT "%f" #define ZERO 0.0F #define ONE 1.0F #define MULTIPLICITY 1 #elif defined(BASE_LONG) #define BASE long #define SHORT long #define OUT_FORMAT "%ld" #define ZERO 0L #define ONE 1L #define MULTIPLICITY 1 #elif defined(BASE_CHAR) #define BASE char #define SHORT char #define OUT_FORMAT "%d" #define ZERO 0 #define ONE 1 #define MULTIPLICITY 1 #elif defined(BASE_BOOL) #define BASE igraph_bool_t #define SHORT bool #define OUT_FORMAT "%d" #define ZERO 0 #define ONE 1 #define MULTIPLICITY 1 #define NOTORDERED 1 #define NOABS 1 #define EQ(a,b) ((a && b) || (!a && !b)) #elif defined(BASE_INT) #define BASE igraph_integer_t #define SHORT int #define OUT_FORMAT "%" IGRAPH_PRId #define ZERO 0 #define ONE 1 #define MULTIPLICITY 1 #elif defined(BASE_PTR) #define BASE void* #define SHORT ptr #define ZERO 0 #define MULTIPLICITY 1 #elif defined(BASE_COMPLEX) #undef complex #define BASE igraph_complex_t #define SHORT complex #define ZERO igraph_complex(0,0) #define ONE {{1.0,0.0}} #define MULTIPLICITY 2 #define NOTORDERED 1 #define NOABS 1 #define SUM(a,b,c) ((a) = igraph_complex_add((b),(c))) #define DIFF(a,b,c) ((a) = igraph_complex_sub((b),(c))) #define PROD(a,b,c) ((a) = igraph_complex_mul((b),(c))) #define DIV(a,b,c) ((a) = igraph_complex_div((b),(c))) #define EQ(a,b) IGRAPH_COMPLEX_EQ((a),(b)) #define SQ(a) IGRAPH_REAL(igraph_complex_mul((a),(a))) #else #error unknown BASE_ directive #endif #if defined(BASE_IGRAPH_REAL) #define FUNCTION(dir,name) CONCAT2(dir,name) #define TYPE(dir) CONCAT2(dir,t) #elif defined(BASE_BOOL) /* Special case because stdbool.h defines bool as a macro to _Bool which would * screw things up */ #define FUNCTION(a,c) CONCAT3x(a,bool,c) #define TYPE(dir) CONCAT3x(dir,bool,t) #else #define FUNCTION(a,c) CONCAT3(a,SHORT,c) #define TYPE(dir) CONCAT3(dir,SHORT,t) #endif #if defined(HEAP_TYPE_MIN) #define HEAPMORE < #define HEAPMOREEQ <= #define HEAPLESS > #define HEAPLESSEQ >= #undef FUNCTION #undef TYPE #if defined(BASE_IGRAPH_REAL) #define FUNCTION(dir,name) CONCAT3(dir,min,name) #define TYPE(dir) CONCAT3(dir,min,t) #else #define FUNCTION(a,c) CONCAT4(a,min,SHORT,c) #define TYPE(dir) CONCAT4(dir,min,SHORT,t) #endif #endif #if defined(HEAP_TYPE_MAX) #define HEAPMORE > #define HEAPMOREEQ >= #define HEAPLESS < #define HEAPLESSEQ <= #endif leidenbase/src/include/igraph_sparsemat.h0000644000176200001440000003553614447675375020323 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_SPARSEMAT_H #define IGRAPH_SPARSEMAT_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_datatype.h" #include "igraph_arpack.h" #include __BEGIN_DECLS struct cs_di_sparse; struct cs_di_symbolic; struct cs_di_numeric; typedef struct { struct cs_di_sparse *cs; } igraph_sparsemat_t; typedef struct { struct cs_di_symbolic *symbolic; } igraph_sparsemat_symbolic_t; typedef struct { struct cs_di_numeric *numeric; } igraph_sparsemat_numeric_t; typedef enum { IGRAPH_SPARSEMAT_TRIPLET, IGRAPH_SPARSEMAT_CC } igraph_sparsemat_type_t; typedef struct { igraph_sparsemat_t *mat; int pos; int col; } igraph_sparsemat_iterator_t; IGRAPH_EXPORT int igraph_sparsemat_init(igraph_sparsemat_t *A, int rows, int cols, int nzmax); IGRAPH_EXPORT int igraph_sparsemat_copy(igraph_sparsemat_t *to, const igraph_sparsemat_t *from); IGRAPH_EXPORT void igraph_sparsemat_destroy(igraph_sparsemat_t *A); IGRAPH_EXPORT int igraph_sparsemat_realloc(igraph_sparsemat_t *A, int nzmax); IGRAPH_EXPORT long int igraph_sparsemat_nrow(const igraph_sparsemat_t *A); IGRAPH_EXPORT long int igraph_sparsemat_ncol(const igraph_sparsemat_t *B); IGRAPH_EXPORT igraph_sparsemat_type_t igraph_sparsemat_type(const igraph_sparsemat_t *A); IGRAPH_EXPORT igraph_bool_t igraph_sparsemat_is_triplet(const igraph_sparsemat_t *A); IGRAPH_EXPORT igraph_bool_t igraph_sparsemat_is_cc(const igraph_sparsemat_t *A); IGRAPH_EXPORT int igraph_sparsemat_permute(const igraph_sparsemat_t *A, const igraph_vector_int_t *p, const igraph_vector_int_t *q, igraph_sparsemat_t *res); IGRAPH_EXPORT int igraph_sparsemat_index(const igraph_sparsemat_t *A, const igraph_vector_int_t *p, const igraph_vector_int_t *q, igraph_sparsemat_t *res, igraph_real_t *constres); IGRAPH_EXPORT int igraph_sparsemat_entry(igraph_sparsemat_t *A, int row, int col, igraph_real_t elem); IGRAPH_EXPORT int igraph_sparsemat_compress(const igraph_sparsemat_t *A, igraph_sparsemat_t *res); IGRAPH_EXPORT int igraph_sparsemat_transpose(const igraph_sparsemat_t *A, igraph_sparsemat_t *res, int values); IGRAPH_EXPORT igraph_bool_t igraph_sparsemat_is_symmetric(const igraph_sparsemat_t *A); IGRAPH_EXPORT int igraph_sparsemat_dupl(igraph_sparsemat_t *A); IGRAPH_EXPORT int igraph_sparsemat_fkeep(igraph_sparsemat_t *A, igraph_integer_t (*fkeep)(igraph_integer_t, igraph_integer_t, igraph_real_t, void*), void *other); IGRAPH_EXPORT int igraph_sparsemat_dropzeros(igraph_sparsemat_t *A); IGRAPH_EXPORT int igraph_sparsemat_droptol(igraph_sparsemat_t *A, igraph_real_t tol); IGRAPH_EXPORT int igraph_sparsemat_multiply(const igraph_sparsemat_t *A, const igraph_sparsemat_t *B, igraph_sparsemat_t *res); IGRAPH_EXPORT int igraph_sparsemat_add(const igraph_sparsemat_t *A, const igraph_sparsemat_t *B, igraph_real_t alpha, igraph_real_t beta, igraph_sparsemat_t *res); IGRAPH_EXPORT int igraph_sparsemat_gaxpy(const igraph_sparsemat_t *A, const igraph_vector_t *x, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_lsolve(const igraph_sparsemat_t *A, const igraph_vector_t *b, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_ltsolve(const igraph_sparsemat_t *A, const igraph_vector_t *b, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_usolve(const igraph_sparsemat_t *A, const igraph_vector_t *b, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_utsolve(const igraph_sparsemat_t *A, const igraph_vector_t *b, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_cholsol(const igraph_sparsemat_t *A, const igraph_vector_t *b, igraph_vector_t *res, int order); IGRAPH_EXPORT int igraph_sparsemat_lusol(const igraph_sparsemat_t *A, const igraph_vector_t *b, igraph_vector_t *res, int order, igraph_real_t tol); IGRAPH_EXPORT int igraph_sparsemat_print(const igraph_sparsemat_t *A, FILE *outstream); IGRAPH_EXPORT int igraph_sparsemat_eye(igraph_sparsemat_t *A, int n, int nzmax, igraph_real_t value, igraph_bool_t compress); IGRAPH_EXPORT int igraph_sparsemat_diag(igraph_sparsemat_t *A, int nzmax, const igraph_vector_t *values, igraph_bool_t compress); IGRAPH_EXPORT int igraph_sparsemat(igraph_t *graph, const igraph_sparsemat_t *A, igraph_bool_t directed); IGRAPH_EXPORT int igraph_weighted_sparsemat(igraph_t *graph, const igraph_sparsemat_t *A, igraph_bool_t directed, const char *attr, igraph_bool_t loops); IGRAPH_EXPORT int igraph_get_sparsemat(const igraph_t *graph, igraph_sparsemat_t *res); IGRAPH_EXPORT int igraph_matrix_as_sparsemat(igraph_sparsemat_t *res, const igraph_matrix_t *mat, igraph_real_t tol); IGRAPH_EXPORT int igraph_sparsemat_as_matrix(igraph_matrix_t *res, const igraph_sparsemat_t *spmat); typedef enum { IGRAPH_SPARSEMAT_SOLVE_LU, IGRAPH_SPARSEMAT_SOLVE_QR } igraph_sparsemat_solve_t; IGRAPH_EXPORT int igraph_sparsemat_arpack_rssolve(const igraph_sparsemat_t *A, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_sparsemat_solve_t solvemethod); IGRAPH_EXPORT int igraph_sparsemat_arpack_rnsolve(const igraph_sparsemat_t *A, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_matrix_t *values, igraph_matrix_t *vectors); IGRAPH_EXPORT int igraph_sparsemat_lu(const igraph_sparsemat_t *A, const igraph_sparsemat_symbolic_t *dis, igraph_sparsemat_numeric_t *din, double tol); IGRAPH_EXPORT int igraph_sparsemat_qr(const igraph_sparsemat_t *A, const igraph_sparsemat_symbolic_t *dis, igraph_sparsemat_numeric_t *din); IGRAPH_EXPORT int igraph_sparsemat_luresol(const igraph_sparsemat_symbolic_t *dis, const igraph_sparsemat_numeric_t *din, const igraph_vector_t *b, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_qrresol(const igraph_sparsemat_symbolic_t *dis, const igraph_sparsemat_numeric_t *din, const igraph_vector_t *b, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_symbqr(long int order, const igraph_sparsemat_t *A, igraph_sparsemat_symbolic_t *dis); IGRAPH_EXPORT int igraph_sparsemat_symblu(long int order, const igraph_sparsemat_t *A, igraph_sparsemat_symbolic_t *dis); IGRAPH_EXPORT void igraph_sparsemat_symbolic_destroy(igraph_sparsemat_symbolic_t *dis); IGRAPH_EXPORT void igraph_sparsemat_numeric_destroy(igraph_sparsemat_numeric_t *din); IGRAPH_EXPORT igraph_real_t igraph_sparsemat_max(igraph_sparsemat_t *A); IGRAPH_EXPORT igraph_real_t igraph_sparsemat_min(igraph_sparsemat_t *A); IGRAPH_EXPORT int igraph_sparsemat_minmax(igraph_sparsemat_t *A, igraph_real_t *min, igraph_real_t *max); IGRAPH_EXPORT long int igraph_sparsemat_count_nonzero(igraph_sparsemat_t *A); IGRAPH_EXPORT long int igraph_sparsemat_count_nonzerotol(igraph_sparsemat_t *A, igraph_real_t tol); IGRAPH_EXPORT int igraph_sparsemat_rowsums(const igraph_sparsemat_t *A, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_colsums(const igraph_sparsemat_t *A, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_rowmins(igraph_sparsemat_t *A, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_colmins(igraph_sparsemat_t *A, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_rowmaxs(igraph_sparsemat_t *A, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_colmaxs(igraph_sparsemat_t *A, igraph_vector_t *res); IGRAPH_EXPORT int igraph_sparsemat_which_min_rows(igraph_sparsemat_t *A, igraph_vector_t *res, igraph_vector_int_t *pos); IGRAPH_EXPORT int igraph_sparsemat_which_min_cols(igraph_sparsemat_t *A, igraph_vector_t *res, igraph_vector_int_t *pos); IGRAPH_EXPORT int igraph_sparsemat_scale(igraph_sparsemat_t *A, igraph_real_t by); IGRAPH_EXPORT int igraph_sparsemat_add_rows(igraph_sparsemat_t *A, long int n); IGRAPH_EXPORT int igraph_sparsemat_add_cols(igraph_sparsemat_t *A, long int n); IGRAPH_EXPORT int igraph_sparsemat_resize(igraph_sparsemat_t *A, long int nrow, long int ncol, int nzmax); IGRAPH_EXPORT int igraph_sparsemat_nonzero_storage(const igraph_sparsemat_t *A); IGRAPH_EXPORT int igraph_sparsemat_getelements(const igraph_sparsemat_t *A, igraph_vector_int_t *i, igraph_vector_int_t *j, igraph_vector_t *x); IGRAPH_EXPORT int igraph_sparsemat_getelements_sorted(const igraph_sparsemat_t *A, igraph_vector_int_t *i, igraph_vector_int_t *j, igraph_vector_t *x); IGRAPH_EXPORT int igraph_sparsemat_scale_rows(igraph_sparsemat_t *A, const igraph_vector_t *fact); IGRAPH_EXPORT int igraph_sparsemat_scale_cols(igraph_sparsemat_t *A, const igraph_vector_t *fact); IGRAPH_EXPORT int igraph_sparsemat_multiply_by_dense(const igraph_sparsemat_t *A, const igraph_matrix_t *B, igraph_matrix_t *res); IGRAPH_EXPORT int igraph_sparsemat_dense_multiply(const igraph_matrix_t *A, const igraph_sparsemat_t *B, igraph_matrix_t *res); IGRAPH_EXPORT int igraph_sparsemat_view(igraph_sparsemat_t *A, int nzmax, int m, int n, int *p, int *i, double *x, int nz); IGRAPH_EXPORT IGRAPH_DEPRECATED int igraph_i_sparsemat_view(igraph_sparsemat_t *A, int nzmax, int m, int n, int *p, int *i, double *x, int nz); IGRAPH_EXPORT int igraph_sparsemat_sort(const igraph_sparsemat_t *A, igraph_sparsemat_t *sorted); IGRAPH_EXPORT int igraph_sparsemat_nzmax(const igraph_sparsemat_t *A); IGRAPH_EXPORT int igraph_sparsemat_neg(igraph_sparsemat_t *A); IGRAPH_EXPORT int igraph_sparsemat_iterator_init(igraph_sparsemat_iterator_t *it, igraph_sparsemat_t *sparsemat); IGRAPH_EXPORT int igraph_sparsemat_iterator_reset(igraph_sparsemat_iterator_t *it); IGRAPH_EXPORT igraph_bool_t igraph_sparsemat_iterator_end(const igraph_sparsemat_iterator_t *it); IGRAPH_EXPORT int igraph_sparsemat_iterator_row(const igraph_sparsemat_iterator_t *it); IGRAPH_EXPORT int igraph_sparsemat_iterator_col(const igraph_sparsemat_iterator_t *it); IGRAPH_EXPORT int igraph_sparsemat_iterator_idx(const igraph_sparsemat_iterator_t *it); IGRAPH_EXPORT igraph_real_t igraph_sparsemat_iterator_get(const igraph_sparsemat_iterator_t *it); IGRAPH_EXPORT int igraph_sparsemat_iterator_next(igraph_sparsemat_iterator_t *it); __END_DECLS #endif leidenbase/src/include/igraph_topology.h0000644000176200001440000003577314447675375020203 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_TOPOLOGY_H #define IGRAPH_TOPOLOGY_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_datatype.h" #include "igraph_types.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Directed acyclic graphs */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_topological_sorting(const igraph_t *graph, igraph_vector_t *res, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_is_dag(const igraph_t *graph, igraph_bool_t *res); IGRAPH_EXPORT int igraph_transitive_closure_dag(const igraph_t *graph, igraph_t *closure); /* -------------------------------------------------- */ /* Graph isomorphisms */ /* -------------------------------------------------- */ /* Common functions */ IGRAPH_EXPORT int igraph_simplify_and_colorize( const igraph_t *graph, igraph_t *res, igraph_vector_int_t *vertex_color, igraph_vector_int_t *edge_color); /* Generic interface */ IGRAPH_EXPORT int igraph_isomorphic(const igraph_t *graph1, const igraph_t *graph2, igraph_bool_t *iso); IGRAPH_EXPORT int igraph_subisomorphic(const igraph_t *graph1, const igraph_t *graph2, igraph_bool_t *iso); /* LAD */ IGRAPH_EXPORT int igraph_subisomorphic_lad(const igraph_t *pattern, const igraph_t *target, const igraph_vector_ptr_t *domains, igraph_bool_t *iso, igraph_vector_t *map, igraph_vector_ptr_t *maps, igraph_bool_t induced, int time_limit); /* VF2 family*/ /** * \typedef igraph_isohandler_t * Callback type, called when an isomorphism was found * * See the details at the documentation of \ref * igraph_isomorphic_function_vf2(). * \param map12 The mapping from the first graph to the second. * \param map21 The mapping from the second graph to the first, the * inverse of \p map12 basically. * \param arg This extra argument was passed to \ref * igraph_isomorphic_function_vf2() when it was called. * \return Boolean, whether to continue with the isomorphism search. */ typedef igraph_bool_t igraph_isohandler_t(const igraph_vector_t *map12, const igraph_vector_t *map21, void *arg); /** * \typedef igraph_isocompat_t * Callback type, called to check whether two vertices or edges are compatible * * VF2 (subgraph) isomorphism functions can be restricted by defining * relations on the vertices and/or edges of the graphs, and then checking * whether the vertices (edges) match according to these relations. * * This feature is implemented by two callbacks, one for * vertices, one for edges. Every time igraph tries to match a vertex (edge) * of the first (sub)graph to a vertex of the second graph, the vertex * (edge) compatibility callback is called. The callback returns a * logical value, giving whether the two vertices match. * * Both callback functions are of type \c igraph_isocompat_t. * \param graph1 The first graph. * \param graph2 The second graph. * \param g1_num The id of a vertex or edge in the first graph. * \param g2_num The id of a vertex or edge in the second graph. * \param arg Extra argument to pass to the callback functions. * \return Logical scalar, whether vertex (or edge) \p g1_num in \p graph1 * is compatible with vertex (or edge) \p g2_num in \p graph2. */ typedef igraph_bool_t igraph_isocompat_t(const igraph_t *graph1, const igraph_t *graph2, const igraph_integer_t g1_num, const igraph_integer_t g2_num, void *arg); IGRAPH_EXPORT int igraph_isomorphic_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_bool_t *iso, igraph_vector_t *map12, igraph_vector_t *map21, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg); IGRAPH_EXPORT int igraph_isomorphic_function_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_vector_t *map12, igraph_vector_t *map21, igraph_isohandler_t *isohandler_fn, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg); IGRAPH_EXPORT int igraph_count_isomorphisms_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_integer_t *count, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg); IGRAPH_EXPORT int igraph_get_isomorphisms_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_vector_ptr_t *maps, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg); IGRAPH_EXPORT int igraph_subisomorphic_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_bool_t *iso, igraph_vector_t *map12, igraph_vector_t *map21, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg); IGRAPH_EXPORT int igraph_subisomorphic_function_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_vector_t *map12, igraph_vector_t *map21, igraph_isohandler_t *isohandler_fn, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg); IGRAPH_EXPORT int igraph_count_subisomorphisms_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_integer_t *count, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg); IGRAPH_EXPORT int igraph_get_subisomorphisms_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_vector_ptr_t *maps, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg); /* BLISS family */ /** * \struct igraph_bliss_info_t * Information about a BLISS run * * Some secondary information found by the BLISS algorithm is stored * here. It is useful if you wany to study the internal working of the * algorithm. * \member nof_nodes The number of nodes in the search tree. * \member nof_leaf_nodes The number of leaf nodes in the search tree. * \member nof_bad_nodes Number of bad nodes. * \member nof_canupdates Number of canrep updates. * \member nof_generators Number of generators of the automorphism group. * \member max_level Maximum level. * \member group_size The size of the automorphism group of the graph, * given as a string. It should be deallocated via * \ref igraph_free() if not needed any more. * * See http://www.tcs.hut.fi/Software/bliss/index.html * for details about the algorithm and these parameters. */ typedef struct igraph_bliss_info_t { unsigned long nof_nodes; unsigned long nof_leaf_nodes; unsigned long nof_bad_nodes; unsigned long nof_canupdates; unsigned long nof_generators; unsigned long max_level; char *group_size; } igraph_bliss_info_t; /** * \typedef igraph_bliss_sh_t * \brief Splitting heuristics for Bliss. * * \c IGRAPH_BLISS_FL provides good performance for many graphs, and is a reasonable * default choice. \c IGRAPH_BLISS_FSM is recommended for graphs that have some * combinatorial structure, and is the default of the Bliss library's command * line tool. * * \enumval IGRAPH_BLISS_F First non-singleton cell. * \enumval IGRAPH_BLISS_FL First largest non-singleton cell. * \enumval IGRAPH_BLISS_FS First smallest non-singleton cell. * \enumval IGRAPH_BLISS_FM First maximally non-trivially connected * non-singleton cell. * \enumval IGRAPH_BLISS_FLM Largest maximally non-trivially connected * non-singleton cell. * \enumval IGRAPH_BLISS_FSM Smallest maximally non-trivially * connected non-singletion cell. */ typedef enum { IGRAPH_BLISS_F = 0, IGRAPH_BLISS_FL, IGRAPH_BLISS_FS, IGRAPH_BLISS_FM, IGRAPH_BLISS_FLM, IGRAPH_BLISS_FSM } igraph_bliss_sh_t; IGRAPH_EXPORT int igraph_canonical_permutation(const igraph_t *graph, const igraph_vector_int_t *colors, igraph_vector_t *labeling, igraph_bliss_sh_t sh, igraph_bliss_info_t *info); IGRAPH_EXPORT int igraph_isomorphic_bliss(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *colors1, const igraph_vector_int_t *colors2, igraph_bool_t *iso, igraph_vector_t *map12, igraph_vector_t *map21, igraph_bliss_sh_t sh, igraph_bliss_info_t *info1, igraph_bliss_info_t *info2); IGRAPH_EXPORT int igraph_automorphisms(const igraph_t *graph, const igraph_vector_int_t *colors, igraph_bliss_sh_t sh, igraph_bliss_info_t *info); IGRAPH_EXPORT int igraph_automorphism_group(const igraph_t *graph, const igraph_vector_int_t *colors, igraph_vector_ptr_t *generators, igraph_bliss_sh_t sh, igraph_bliss_info_t *info); /* Functions for 3-4 graphs */ IGRAPH_EXPORT int igraph_isomorphic_34(const igraph_t *graph1, const igraph_t *graph2, igraph_bool_t *iso); IGRAPH_EXPORT int igraph_isoclass(const igraph_t *graph, igraph_integer_t *isoclass); IGRAPH_EXPORT int igraph_isoclass_subgraph(const igraph_t *graph, const igraph_vector_t *vids, igraph_integer_t *isoclass); IGRAPH_EXPORT int igraph_isoclass_create(igraph_t *graph, igraph_integer_t size, igraph_integer_t number, igraph_bool_t directed); __END_DECLS #endif leidenbase/src/include/igraph_stack.h0000644000176200001440000000404414447675375017417 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_STACK_H #define IGRAPH_STACK_H #include "igraph_decls.h" #include "igraph_types.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Plain stack */ /* -------------------------------------------------- */ #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "igraph_stack_pmt.h" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_LONG #include "igraph_pmt.h" #include "igraph_stack_pmt.h" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_INT #include "igraph_pmt.h" #include "igraph_stack_pmt.h" #include "igraph_pmt_off.h" #undef BASE_INT #define BASE_CHAR #include "igraph_pmt.h" #include "igraph_stack_pmt.h" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "igraph_stack_pmt.h" #include "igraph_pmt_off.h" #undef BASE_BOOL #define BASE_PTR #include "igraph_pmt.h" #include "igraph_stack_pmt.h" #include "igraph_pmt_off.h" #undef BASE_PTR #define IGRAPH_STACK_NULL { 0,0,0 } IGRAPH_EXPORT void igraph_stack_ptr_free_all(igraph_stack_ptr_t* s); IGRAPH_EXPORT void igraph_stack_ptr_destroy_all(igraph_stack_ptr_t* s); __END_DECLS #endif leidenbase/src/include/igraph_adjlist.h0000644000176200001440000002022514447675375017743 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_ADJLIST_H #define IGRAPH_ADJLIST_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_datatype.h" __BEGIN_DECLS typedef struct igraph_adjlist_t { igraph_integer_t length; igraph_vector_int_t *adjs; } igraph_adjlist_t; IGRAPH_EXPORT int igraph_adjlist_init(const igraph_t *graph, igraph_adjlist_t *al, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple); IGRAPH_EXPORT int igraph_adjlist_init_empty(igraph_adjlist_t *al, igraph_integer_t no_of_nodes); IGRAPH_EXPORT igraph_integer_t igraph_adjlist_size(const igraph_adjlist_t *al); IGRAPH_EXPORT int igraph_adjlist_init_complementer(const igraph_t *graph, igraph_adjlist_t *al, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT void igraph_adjlist_destroy(igraph_adjlist_t *al); IGRAPH_EXPORT void igraph_adjlist_clear(igraph_adjlist_t *al); IGRAPH_EXPORT void igraph_adjlist_sort(igraph_adjlist_t *al); IGRAPH_EXPORT int igraph_adjlist_simplify(igraph_adjlist_t *al); IGRAPH_DEPRECATED IGRAPH_EXPORT int igraph_adjlist_remove_duplicate(const igraph_t *graph, igraph_adjlist_t *al); IGRAPH_EXPORT int igraph_adjlist_print(const igraph_adjlist_t *al); IGRAPH_EXPORT int igraph_adjlist_fprint(const igraph_adjlist_t *al, FILE *outfile); IGRAPH_EXPORT igraph_bool_t igraph_adjlist_has_edge(igraph_adjlist_t* al, igraph_integer_t from, igraph_integer_t to, igraph_bool_t directed); IGRAPH_EXPORT int igraph_adjlist_replace_edge(igraph_adjlist_t* al, igraph_integer_t from, igraph_integer_t oldto, igraph_integer_t newto, igraph_bool_t directed); /** * \define igraph_adjlist_get * \brief Query a vector in an adjacency list. * * Returns a pointer to an igraph_vector_int_t object from an * adjacency list. The vector can be modified as desired. * \param al The adjacency list object. * \param no The vertex whose adjacent vertices will be returned. * \return Pointer to the igraph_vector_int_t object. * * Time complexity: O(1). */ #define igraph_adjlist_get(al,no) (&(al)->adjs[(long int)(no)]) IGRAPH_EXPORT int igraph_adjlist(igraph_t *graph, const igraph_adjlist_t *adjlist, igraph_neimode_t mode, igraph_bool_t duplicate); typedef struct igraph_inclist_t { igraph_integer_t length; igraph_vector_int_t *incs; } igraph_inclist_t; IGRAPH_EXPORT int igraph_inclist_init(const igraph_t *graph, igraph_inclist_t *il, igraph_neimode_t mode, igraph_loops_t loops); IGRAPH_EXPORT int igraph_inclist_init_empty(igraph_inclist_t *il, igraph_integer_t n); IGRAPH_EXPORT igraph_integer_t igraph_inclist_size(const igraph_inclist_t *al); IGRAPH_EXPORT void igraph_inclist_destroy(igraph_inclist_t *il); IGRAPH_EXPORT void igraph_inclist_clear(igraph_inclist_t *il); IGRAPH_DEPRECATED IGRAPH_EXPORT int igraph_inclist_remove_duplicate(const igraph_t *graph, igraph_inclist_t *il); IGRAPH_EXPORT int igraph_inclist_print(const igraph_inclist_t *il); IGRAPH_EXPORT int igraph_inclist_fprint(const igraph_inclist_t *il, FILE *outfile); /** * \define igraph_inclist_get * \brief Query a vector in an incidence list. * * Returns a pointer to an igraph_vector_int_t object from an * incidence list containing edge ids. The vector can be modified, * resized, etc. as desired. * \param il Pointer to the incidence list. * \param no The vertex for which the incident edges are returned. * \return Pointer to an igraph_vector_int_t object. * * Time complexity: O(1). */ #define igraph_inclist_get(il,no) (&(il)->incs[(long int)(no)]) typedef struct igraph_lazy_adjlist_t { const igraph_t *graph; igraph_integer_t length; igraph_vector_int_t **adjs; igraph_neimode_t mode; igraph_loops_t loops; igraph_multiple_t multiple; igraph_vector_t dummy; } igraph_lazy_adjlist_t; IGRAPH_EXPORT int igraph_lazy_adjlist_init(const igraph_t *graph, igraph_lazy_adjlist_t *al, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple); IGRAPH_EXPORT void igraph_lazy_adjlist_destroy(igraph_lazy_adjlist_t *al); IGRAPH_EXPORT void igraph_lazy_adjlist_clear(igraph_lazy_adjlist_t *al); IGRAPH_EXPORT igraph_integer_t igraph_lazy_adjlist_size(const igraph_lazy_adjlist_t *al); /** * \define igraph_lazy_adjlist_get * \brief Query neighbor vertices. * * If the function is called for the first time for a vertex then the * result is stored in the adjacency list and no further query * operations are needed when the neighbors of the same vertex are * queried again. * \param al The lazy adjacency list. * \param no The vertex ID to query. * \return Pointer to a vector. It is allowed to modify it and * modification does not affect the original graph. * * Time complexity: O(d), the number of neighbor vertices for the * first time, O(1) for subsequent calls. */ #define igraph_lazy_adjlist_get(al,no) \ ((al)->adjs[(long int)(no)] != 0 ? ((al)->adjs[(long int)(no)]) : \ (igraph_i_lazy_adjlist_get_real(al, no))) IGRAPH_EXPORT igraph_vector_int_t *igraph_i_lazy_adjlist_get_real(igraph_lazy_adjlist_t *al, igraph_integer_t no); typedef struct igraph_lazy_inclist_t { const igraph_t *graph; igraph_integer_t length; igraph_vector_int_t **incs; igraph_neimode_t mode; igraph_vector_t dummy; igraph_loops_t loops; } igraph_lazy_inclist_t; IGRAPH_EXPORT int igraph_lazy_inclist_init(const igraph_t *graph, igraph_lazy_inclist_t *il, igraph_neimode_t mode, igraph_loops_t loops); IGRAPH_EXPORT void igraph_lazy_inclist_destroy(igraph_lazy_inclist_t *il); IGRAPH_EXPORT void igraph_lazy_inclist_clear(igraph_lazy_inclist_t *il); IGRAPH_EXPORT igraph_integer_t igraph_lazy_inclist_size(const igraph_lazy_inclist_t *il); /** * \define igraph_lazy_inclist_get * \brief Query incident edges. * * If the function is called for the first time for a vertex, then the * result is stored in the incidence list and no further query * operations are needed when the incident edges of the same vertex are * queried again. * \param al The lazy incidence list object. * \param no The vertex id to query. * \return Pointer to a vector. It is allowed to modify it and * modification does not affect the original graph. * * Time complexity: O(d), the number of incident edges for the first * time, O(1) for subsequent calls with the same \p no argument. */ #define igraph_lazy_inclist_get(al,no) \ ((al)->incs[(long int)(no)] != 0 ? ((al)->incs[(long int)(no)]) : \ (igraph_i_lazy_inclist_get_real(al, no))) IGRAPH_EXPORT igraph_vector_int_t *igraph_i_lazy_inclist_get_real(igraph_lazy_inclist_t *al, igraph_integer_t no); __END_DECLS #endif leidenbase/src/include/igraph_constructors.h0000644000176200001440000001017614447675375021065 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CONSTRUCTORS_H #define IGRAPH_CONSTRUCTORS_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_matrix.h" #include "igraph_datatype.h" #include "igraph_graphicality.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Constructors, deterministic */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_create(igraph_t *graph, const igraph_vector_t *edges, igraph_integer_t n, igraph_bool_t directed); IGRAPH_EXPORT int igraph_small(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, ...); IGRAPH_EXPORT int igraph_adjacency(igraph_t *graph, const igraph_matrix_t *adjmatrix, igraph_adjacency_t mode); IGRAPH_EXPORT int igraph_weighted_adjacency(igraph_t *graph, const igraph_matrix_t *adjmatrix, igraph_adjacency_t mode, const char* attr, igraph_bool_t loops); IGRAPH_EXPORT int igraph_star(igraph_t *graph, igraph_integer_t n, igraph_star_mode_t mode, igraph_integer_t center); IGRAPH_EXPORT int igraph_lattice(igraph_t *graph, const igraph_vector_t *dimvector, igraph_integer_t nei, igraph_bool_t directed, igraph_bool_t mutual, igraph_bool_t circular); IGRAPH_EXPORT int igraph_ring(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, igraph_bool_t mutual, igraph_bool_t circular); IGRAPH_EXPORT int igraph_tree(igraph_t *graph, igraph_integer_t n, igraph_integer_t children, igraph_tree_mode_t type); IGRAPH_EXPORT int igraph_from_prufer(igraph_t *graph, const igraph_vector_int_t *prufer); IGRAPH_EXPORT int igraph_full(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, igraph_bool_t loops); IGRAPH_EXPORT int igraph_full_citation(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed); IGRAPH_EXPORT int igraph_atlas(igraph_t *graph, int number); IGRAPH_EXPORT int igraph_extended_chordal_ring(igraph_t *graph, igraph_integer_t nodes, const igraph_matrix_t *W, igraph_bool_t directed); IGRAPH_EXPORT int igraph_linegraph(const igraph_t *graph, igraph_t *linegraph); IGRAPH_EXPORT int igraph_de_bruijn(igraph_t *graph, igraph_integer_t m, igraph_integer_t n); IGRAPH_EXPORT int igraph_kautz(igraph_t *graph, igraph_integer_t m, igraph_integer_t n); IGRAPH_EXPORT int igraph_famous(igraph_t *graph, const char *name); IGRAPH_EXPORT int igraph_lcf_vector(igraph_t *graph, igraph_integer_t n, const igraph_vector_t *shifts, igraph_integer_t repeats); IGRAPH_EXPORT int igraph_lcf(igraph_t *graph, igraph_integer_t n, ...); IGRAPH_EXPORT int igraph_realize_degree_sequence(igraph_t *graph, const igraph_vector_t *outdeg, const igraph_vector_t *indeg, igraph_edge_type_sw_t allowed_edge_types, igraph_realize_degseq_t method); __END_DECLS #endif leidenbase/src/include/igraph_version.h.in0000644000176200001440000000266714447675375020415 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_VERSION_H #define IGRAPH_VERSION_H #include "igraph_decls.h" __BEGIN_DECLS #define IGRAPH_VERSION "@PACKAGE_VERSION@" #define IGRAPH_VERSION_MAJOR @PACKAGE_VERSION_MAJOR@ #define IGRAPH_VERSION_MINOR @PACKAGE_VERSION_MINOR@ #define IGRAPH_VERSION_PATCH @PACKAGE_VERSION_PATCH@ #define IGRAPH_VERSION_PRERELEASE "@PACKAGE_VERSION_PRERELEASE@" IGRAPH_EXPORT int igraph_version(const char **version_string, int *major, int *minor, int *subminor); __END_DECLS #endif leidenbase/src/include/igraph_memory.h0000644000176200001440000000266614447675375017632 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_MEMORY_H #define IGRAPH_MEMORY_H #include #include "igraph_decls.h" __BEGIN_DECLS #define IGRAPH_CALLOC(n,t) (t*) calloc( (n) > 0 ? (size_t)(n) : (size_t)1, sizeof(t) ) #define IGRAPH_REALLOC(p,n,t) (t*) realloc((void*)(p), (n) > 0 ? (size_t)((n)*sizeof(t)) : (size_t)1) #define IGRAPH_FREE(p) (free( (void *)(p) ), (p) = NULL) #define igraph_Calloc IGRAPH_CALLOC #define igraph_Realloc IGRAPH_REALLOC #define igraph_Free IGRAPH_FREE IGRAPH_EXPORT void igraph_free(void *p); IGRAPH_EXPORT void *igraph_malloc(size_t n); __END_DECLS #endif leidenbase/src/include/igraph_layout.h0000644000176200001440000003422214447675375017630 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_LAYOUT_H #define IGRAPH_LAYOUT_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" #include "igraph_matrix.h" #include "igraph_datatype.h" #include "igraph_arpack.h" #include "igraph_iterators.h" __BEGIN_DECLS /** * \section about_layouts * * Layout generator functions (or at least most of them) try to place the * vertices and edges of a graph on a 2D plane or in 3D space in a way * which visually pleases the human eye. * * They take a graph object and a number of parameters as arguments * and return an \type igraph_matrix_t, in which each row gives the * coordinates of a vertex. */ /* -------------------------------------------------- */ /* Layouts */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_layout_random(const igraph_t *graph, igraph_matrix_t *res); IGRAPH_EXPORT int igraph_layout_circle(const igraph_t *graph, igraph_matrix_t *res, igraph_vs_t order); IGRAPH_EXPORT int igraph_layout_star(const igraph_t *graph, igraph_matrix_t *res, igraph_integer_t center, const igraph_vector_t *order); IGRAPH_EXPORT int igraph_layout_grid(const igraph_t *graph, igraph_matrix_t *res, long int width); IGRAPH_EXPORT int igraph_layout_fruchterman_reingold(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t niter, igraph_real_t start_temp, igraph_layout_grid_t grid, const igraph_vector_t *weight, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy); IGRAPH_EXPORT int igraph_layout_kamada_kawai(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t epsilon, igraph_real_t kkconst, const igraph_vector_t *weights, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy); IGRAPH_EXPORT int igraph_layout_lgl(const igraph_t *graph, igraph_matrix_t *res, igraph_integer_t maxiter, igraph_real_t maxdelta, igraph_real_t area, igraph_real_t coolexp, igraph_real_t repulserad, igraph_real_t cellsize, igraph_integer_t root); IGRAPH_EXPORT int igraph_layout_reingold_tilford(const igraph_t *graph, igraph_matrix_t *res, igraph_neimode_t mode, const igraph_vector_t *roots, const igraph_vector_t *rootlevel); IGRAPH_EXPORT int igraph_layout_reingold_tilford_circular(const igraph_t *graph, igraph_matrix_t *res, igraph_neimode_t mode, const igraph_vector_t *roots, const igraph_vector_t *rootlevel); IGRAPH_EXPORT int igraph_layout_sugiyama(const igraph_t *graph, igraph_matrix_t *res, igraph_t *extd_graph, igraph_vector_t *extd_to_orig_eids, const igraph_vector_t* layers, igraph_real_t hgap, igraph_real_t vgap, long int maxiter, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_layout_random_3d(const igraph_t *graph, igraph_matrix_t *res); IGRAPH_EXPORT int igraph_layout_sphere(const igraph_t *graph, igraph_matrix_t *res); IGRAPH_EXPORT int igraph_layout_grid_3d(const igraph_t *graph, igraph_matrix_t *res, long int width, long int height); IGRAPH_EXPORT int igraph_layout_fruchterman_reingold_3d(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t niter, igraph_real_t start_temp, const igraph_vector_t *weight, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy, const igraph_vector_t *minz, const igraph_vector_t *maxz); IGRAPH_EXPORT int igraph_layout_kamada_kawai_3d(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t epsilon, igraph_real_t kkconst, const igraph_vector_t *weights, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy, const igraph_vector_t *minz, const igraph_vector_t *maxz); IGRAPH_EXPORT int igraph_layout_graphopt(const igraph_t *graph, igraph_matrix_t *res, igraph_integer_t niter, igraph_real_t node_charge, igraph_real_t node_mass, igraph_real_t spring_length, igraph_real_t spring_constant, igraph_real_t max_sa_movement, igraph_bool_t use_seed); IGRAPH_EXPORT int igraph_layout_mds(const igraph_t *graph, igraph_matrix_t *res, const igraph_matrix_t *dist, long int dim); IGRAPH_EXPORT int igraph_layout_bipartite(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_matrix_t *res, igraph_real_t hgap, igraph_real_t vgap, long int maxiter); /** * \struct igraph_layout_drl_options_t * Parameters for the DrL layout generator * * \member edge_cut The edge cutting parameter. * Edge cutting is done in the late stages of the * algorithm in order to achieve less dense layouts. Edges are cut * if there is a lot of stress on them (a large value in the * objective function sum). The edge cutting parameter is a value * between 0 and 1 with 0 representing no edge cutting and 1 * representing maximal edge cutting. The default value is 32/40. * \member init_iterations Number of iterations, initial phase. * \member init_temperature Start temperature, initial phase. * \member init_attraction Attraction, initial phase. * \member init_damping_mult Damping factor, initial phase. * \member liquid_iterations Number of iterations in the liquid phase. * \member liquid_temperature Start temperature in the liquid phase. * \member liquid_attraction Attraction in the liquid phase. * \member liquid_damping_mult Multiplicatie damping factor, liquid phase. * \member expansion_iterations Number of iterations in the expansion phase. * \member expansion_temperature Start temperature in the expansion phase. * \member expansion_attraction Attraction, expansion phase. * \member expansion_damping_mult Damping factor, expansion phase. * \member cooldown_iterations Number of iterations in the cooldown phase. * \member cooldown_temperature Start temperature in the cooldown phase. * \member cooldown_attraction Attraction in the cooldown phase. * \member cooldown_damping_mult Damping fact int the cooldown phase. * \member crunch_iterations Number of iterations in the crunch phase. * \member crunch_temperature Start temperature in the crunch phase. * \member crunch_attraction Attraction in the crunch phase. * \member crunch_damping_mult Damping factor in the crunch phase. * \member simmer_iterations Number of iterations in the simmer phase. * \member simmer_temperature Start temperature in te simmer phase. * \member simmer_attraction Attraction in the simmer phase. * \member simmer_damping_mult Multiplicative damping factor in the simmer phase. */ typedef struct igraph_layout_drl_options_t { igraph_real_t edge_cut; igraph_integer_t init_iterations; igraph_real_t init_temperature; igraph_real_t init_attraction; igraph_real_t init_damping_mult; igraph_integer_t liquid_iterations; igraph_real_t liquid_temperature; igraph_real_t liquid_attraction; igraph_real_t liquid_damping_mult; igraph_integer_t expansion_iterations; igraph_real_t expansion_temperature; igraph_real_t expansion_attraction; igraph_real_t expansion_damping_mult; igraph_integer_t cooldown_iterations; igraph_real_t cooldown_temperature; igraph_real_t cooldown_attraction; igraph_real_t cooldown_damping_mult; igraph_integer_t crunch_iterations; igraph_real_t crunch_temperature; igraph_real_t crunch_attraction; igraph_real_t crunch_damping_mult; igraph_integer_t simmer_iterations; igraph_real_t simmer_temperature; igraph_real_t simmer_attraction; igraph_real_t simmer_damping_mult; } igraph_layout_drl_options_t; /** * \typedef igraph_layout_drl_default_t * Predefined parameter templates for the DrL layout generator * * These constants can be used to initialize a set of DrL parameters. * These can then be modified according to the user's needs. * \enumval IGRAPH_LAYOUT_DRL_DEFAULT The deafult parameters. * \enumval IGRAPH_LAYOUT_DRL_COARSEN Slightly modified parameters to * get a coarser layout. * \enumval IGRAPH_LAYOUT_DRL_COARSEST An even coarser layout. * \enumval IGRAPH_LAYOUT_DRL_REFINE Refine an already calculated layout. * \enumval IGRAPH_LAYOUT_DRL_FINAL Finalize an already refined layout. */ typedef enum { IGRAPH_LAYOUT_DRL_DEFAULT = 0, IGRAPH_LAYOUT_DRL_COARSEN, IGRAPH_LAYOUT_DRL_COARSEST, IGRAPH_LAYOUT_DRL_REFINE, IGRAPH_LAYOUT_DRL_FINAL } igraph_layout_drl_default_t; IGRAPH_EXPORT int igraph_layout_drl_options_init(igraph_layout_drl_options_t *options, igraph_layout_drl_default_t templ); IGRAPH_EXPORT int igraph_layout_drl(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, const igraph_layout_drl_options_t *options, const igraph_vector_t *weights, const igraph_vector_bool_t *fixed); IGRAPH_EXPORT int igraph_layout_drl_3d(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, const igraph_layout_drl_options_t *options, const igraph_vector_t *weights, const igraph_vector_bool_t *fixed); IGRAPH_EXPORT int igraph_layout_merge_dla(const igraph_vector_ptr_t *graphs, const igraph_vector_ptr_t *coords, igraph_matrix_t *res); IGRAPH_EXPORT int igraph_layout_gem(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t temp_max, igraph_real_t temp_min, igraph_real_t temp_init); IGRAPH_EXPORT int igraph_layout_davidson_harel(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_integer_t fineiter, igraph_real_t cool_fact, igraph_real_t weight_node_dist, igraph_real_t weight_border, igraph_real_t weight_edge_lengths, igraph_real_t weight_edge_crossings, igraph_real_t weight_node_edge_dist); __END_DECLS #endif leidenbase/src/include/igraph_random.h0000644000176200001440000001215214447675375017571 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_RANDOM_H #define IGRAPH_RANDOM_H #include "igraph_decls.h" __BEGIN_DECLS #include #include #include "igraph_types.h" #include "igraph_vector.h" /* The new RNG interface is (somewhat) modelled based on the GSL */ typedef struct igraph_rng_type_t { const char *name; unsigned long int min; /* 'min' must always be set to 0 */ unsigned long int max; int (*init)(void **state); void (*destroy)(void *state); int (*seed)(void *state, unsigned long int seed); unsigned long int (*get)(void *state); igraph_real_t (*get_real)(void *state); igraph_real_t (*get_norm)(void *state); igraph_real_t (*get_geom)(void *state, igraph_real_t p); igraph_real_t (*get_binom)(void *state, long int n, igraph_real_t p); igraph_real_t (*get_exp)(void *state, igraph_real_t rate); igraph_real_t (*get_gamma)(void *state, igraph_real_t shape, igraph_real_t scale); } igraph_rng_type_t; typedef struct igraph_rng_t { const igraph_rng_type_t *type; void *state; int def; } igraph_rng_t; /* --------------------------------- */ IGRAPH_EXPORT int igraph_rng_init(igraph_rng_t *rng, const igraph_rng_type_t *type); IGRAPH_EXPORT void igraph_rng_destroy(igraph_rng_t *rng); IGRAPH_EXPORT int igraph_rng_seed(igraph_rng_t *rng, unsigned long int seed); IGRAPH_EXPORT unsigned long int igraph_rng_max(igraph_rng_t *rng); IGRAPH_EXPORT IGRAPH_DEPRECATED unsigned long int igraph_rng_min(igraph_rng_t *rng); IGRAPH_EXPORT const char *igraph_rng_name(igraph_rng_t *rng); IGRAPH_EXPORT long int igraph_rng_get_integer(igraph_rng_t *rng, long int l, long int h); IGRAPH_EXPORT igraph_real_t igraph_rng_get_normal(igraph_rng_t *rng, igraph_real_t m, igraph_real_t s); IGRAPH_EXPORT igraph_real_t igraph_rng_get_unif(igraph_rng_t *rng, igraph_real_t l, igraph_real_t h); IGRAPH_EXPORT igraph_real_t igraph_rng_get_unif01(igraph_rng_t *rng); IGRAPH_EXPORT igraph_real_t igraph_rng_get_geom(igraph_rng_t *rng, igraph_real_t p); IGRAPH_EXPORT igraph_real_t igraph_rng_get_binom(igraph_rng_t *rng, long int n, igraph_real_t p); IGRAPH_EXPORT igraph_real_t igraph_rng_get_exp(igraph_rng_t *rng, igraph_real_t rate); IGRAPH_EXPORT unsigned long int igraph_rng_get_int31(igraph_rng_t *rng); IGRAPH_EXPORT igraph_real_t igraph_rng_get_gamma(igraph_rng_t *rng, igraph_real_t shape, igraph_real_t scale); IGRAPH_EXPORT int igraph_rng_get_dirichlet(igraph_rng_t *rng, const igraph_vector_t *alpha, igraph_vector_t *result); /* --------------------------------- */ IGRAPH_EXPORT extern const igraph_rng_type_t igraph_rngtype_glibc2; IGRAPH_EXPORT extern const igraph_rng_type_t igraph_rngtype_rand; IGRAPH_EXPORT extern const igraph_rng_type_t igraph_rngtype_mt19937; IGRAPH_EXPORT igraph_rng_t *igraph_rng_default(void); IGRAPH_EXPORT void igraph_rng_set_default(igraph_rng_t *rng); /* --------------------------------- */ #ifdef USING_R void GetRNGstate(void); void PutRNGstate(void); #define RNG_BEGIN() GetRNGstate() #define RNG_END() PutRNGstate() double Rf_dnorm4(double x, double mu, double sigma, int give_log); #define igraph_dnorm Rf_dnorm4 #else #define RNG_BEGIN() \ if (igraph_rng_default()->def == 1) { \ igraph_rng_seed(igraph_rng_default(), time(0)); \ igraph_rng_default()->def=2; \ } #define RNG_END() /* do nothing */ IGRAPH_EXPORT double igraph_dnorm(double x, double mu, double sigma, int give_log); #endif #define RNG_INTEGER(l,h) (igraph_rng_get_integer(igraph_rng_default(),(l),(h))) #define RNG_NORMAL(m,s) (igraph_rng_get_normal(igraph_rng_default(),(m),(s))) #define RNG_UNIF(l,h) (igraph_rng_get_unif(igraph_rng_default(),(l),(h))) #define RNG_UNIF01() (igraph_rng_get_unif01(igraph_rng_default())) #define RNG_GEOM(p) (igraph_rng_get_geom(igraph_rng_default(),(p))) #define RNG_BINOM(n,p) (igraph_rng_get_binom(igraph_rng_default(),(n),(p))) #define RNG_INT31() (igraph_rng_get_int31(igraph_rng_default())) __END_DECLS #endif leidenbase/src/include/igraph_interrupt.h0000644000176200001440000001144514447675375020351 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_INTERRUPT_H #define IGRAPH_INTERRUPT_H #include "igraph_decls.h" #include "igraph_error.h" __BEGIN_DECLS /* This file contains the igraph interruption handling. */ /** * \section interrupthandlers Interruption handlers * * * \a igraph is designed to be embeddable into several higher level * languages (R and Python interfaces are included in the original * package). Since most higher level languages consider internal \a igraph * calls as atomic, interruption requests (like Ctrl-C in Python) must * be handled differently depending on the environment \a igraph embeds * into. * * An \emb interruption handler \eme is a function which is called regularly * by \a igraph during long calculations. A typical usage of the interruption * handler is to check whether the user tried to interrupt the calculation * and return an appropriate value to signal this condition. For example, * in R, one must call an internal R function regularly to check for * interruption requests, and the \a igraph interruption handler is the * perfect place to do that. * * If you are using the plain C interface of \a igraph or if you are * allowed to replace the operating system's interruption handler (like * SIGINT in Un*x systems), these calls are not of much use to you. * * The default interruption handler is empty. * The \ref igraph_set_interruption_handler() function can be used to set a * new interruption handler function of type * \ref igraph_interruption_handler_t, see the * documentation of this type for details. * */ /** * \section writing_interruption_handlers Writing interruption handlers * * * You can write and install interruption handlers simply by defining a * function of type \ref igraph_interruption_handler_t and calling * \ref igraph_set_interruption_handler(). This feature is useful for * interface writers, because usually this is the only way to allow handling * of Ctrl-C and similar keypresses properly. * * * Your interruption handler will be called regularly during long operations * (so it is not guaranteed to be called during operations which tend to be * short, like adding single edges). An interruption handler accepts no * parameters and must return \c IGRAPH_SUCCESS if the calculation should go on. All * other return values are considered to be a request for interruption, * and the caller function would return a special error code, \c IGRAPH_INTERRUPTED. * It is up to your error handler function to handle this error properly. * */ /** * \section writing_functions_interruption_handling Writing \a igraph functions with * proper interruption handling * * * There is practically a simple rule that should be obeyed when writing * \a igraph functions. If the calculation is expected to take a long time * in large graphs (a simple rule of thumb is to assume this for every * function with a time complexity of at least O(n^2)), call * \ref IGRAPH_ALLOW_INTERRUPTION in regular intervals like every 10th * iteration or so. * */ /** * \typedef igraph_interruption_handler_t * * This is the type of the interruption handler functions. * * \param data reserved for possible future use * \return \c IGRAPH_SUCCESS if the calculation should go on, anything else otherwise. */ typedef int igraph_interruption_handler_t (void* data); /** * \function igraph_allow_interruption * * This is the function which is called (usually via the * \ref IGRAPH_ALLOW_INTERRUPTION macro) if \a igraph is checking for interruption * requests. * * \param data reserved for possible future use, now it is always \c NULL * \return \c IGRAPH_SUCCESS if the calculation should go on, anything else otherwise. */ IGRAPH_EXPORT int igraph_allow_interruption(void* data); IGRAPH_EXPORT igraph_interruption_handler_t * igraph_set_interruption_handler (igraph_interruption_handler_t * new_handler); __END_DECLS #endif leidenbase/src/include/igraph_vector_pmt.h0000644000176200001440000003463314447675375020503 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /*--------------------*/ /* Allocation */ /*--------------------*/ IGRAPH_EXPORT int FUNCTION(igraph_vector, init)(TYPE(igraph_vector)* v, long int size); IGRAPH_EXPORT int FUNCTION(igraph_vector, init_copy)(TYPE(igraph_vector)* v, const BASE* data, long int length); #ifndef NOTORDERED IGRAPH_EXPORT int FUNCTION(igraph_vector, init_seq)(TYPE(igraph_vector)*v, BASE from, BASE to); #endif IGRAPH_EXPORT int FUNCTION(igraph_vector, copy)(TYPE(igraph_vector) *to, const TYPE(igraph_vector) *from); IGRAPH_EXPORT void FUNCTION(igraph_vector, destroy)(TYPE(igraph_vector)* v); IGRAPH_EXPORT long int FUNCTION(igraph_vector, capacity)(const TYPE(igraph_vector)*v); /*--------------------*/ /* Accessing elements */ /*--------------------*/ #ifndef VECTOR /** * \ingroup vector * \define VECTOR * \brief Accessing an element of a vector. * * Usage: * \verbatim VECTOR(v)[0] \endverbatim * to access the first element of the vector, you can also use this in * assignments, like: * \verbatim VECTOR(v)[10]=5; \endverbatim * * Note that there are no range checks right now. * This functionality might be redefined later as a real function * instead of a #define. * \param v The vector object. * * Time complexity: O(1). */ #define VECTOR(v) ((v).stor_begin) #endif IGRAPH_EXPORT BASE FUNCTION(igraph_vector, e)(const TYPE(igraph_vector)* v, long int pos); IGRAPH_EXPORT BASE* FUNCTION(igraph_vector, e_ptr)(const TYPE(igraph_vector)* v, long int pos); IGRAPH_EXPORT void FUNCTION(igraph_vector, set)(TYPE(igraph_vector)* v, long int pos, BASE value); IGRAPH_EXPORT BASE FUNCTION(igraph_vector, tail)(const TYPE(igraph_vector) *v); /*-----------------------*/ /* Initializing elements */ /*-----------------------*/ IGRAPH_EXPORT void FUNCTION(igraph_vector, null)(TYPE(igraph_vector)* v); IGRAPH_EXPORT void FUNCTION(igraph_vector, fill)(TYPE(igraph_vector)* v, BASE e); /*-----------------------*/ /* Vector views */ /*-----------------------*/ IGRAPH_EXPORT const TYPE(igraph_vector) *FUNCTION(igraph_vector, view)(const TYPE(igraph_vector) *v, const BASE *data, long int length); /*-----------------------*/ /* Copying vectors */ /*-----------------------*/ IGRAPH_EXPORT void FUNCTION(igraph_vector, copy_to)(const TYPE(igraph_vector) *v, BASE* to); IGRAPH_EXPORT int FUNCTION(igraph_vector, update)(TYPE(igraph_vector) *to, const TYPE(igraph_vector) *from); IGRAPH_EXPORT int FUNCTION(igraph_vector, append)(TYPE(igraph_vector) *to, const TYPE(igraph_vector) *from); IGRAPH_EXPORT int FUNCTION(igraph_vector, swap)(TYPE(igraph_vector) *v1, TYPE(igraph_vector) *v2); /*-----------------------*/ /* Exchanging elements */ /*-----------------------*/ IGRAPH_EXPORT int FUNCTION(igraph_vector, swap_elements)(TYPE(igraph_vector) *v, long int i, long int j); IGRAPH_EXPORT int FUNCTION(igraph_vector, reverse)(TYPE(igraph_vector) *v); IGRAPH_EXPORT int FUNCTION(igraph_vector, shuffle)(TYPE(igraph_vector) *v); /*-----------------------*/ /* Vector operations */ /*-----------------------*/ IGRAPH_EXPORT void FUNCTION(igraph_vector, add_constant)(TYPE(igraph_vector) *v, BASE plus); IGRAPH_EXPORT void FUNCTION(igraph_vector, scale)(TYPE(igraph_vector) *v, BASE by); IGRAPH_EXPORT int FUNCTION(igraph_vector, add)(TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2); IGRAPH_EXPORT int FUNCTION(igraph_vector, sub)(TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2); IGRAPH_EXPORT int FUNCTION(igraph_vector, mul)(TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2); IGRAPH_EXPORT int FUNCTION(igraph_vector, div)(TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2); IGRAPH_EXPORT int FUNCTION(igraph_vector, cumsum)(TYPE(igraph_vector) *to, const TYPE(igraph_vector) *from); #ifndef NOABS IGRAPH_EXPORT int FUNCTION(igraph_vector, abs)(TYPE(igraph_vector) *v); #endif /*------------------------------*/ /* Comparison */ /*------------------------------*/ IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, all_e)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs); #ifndef NOTORDERED IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, all_l)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, all_g)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, all_le)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, all_ge)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs); IGRAPH_EXPORT int FUNCTION(igraph_vector, lex_cmp)(const void *lhs, const void *rhs); IGRAPH_EXPORT int FUNCTION(igraph_vector, colex_cmp)(const void *lhs, const void *rhs); #endif /*------------------------------*/ /* Finding minimum and maximum */ /*------------------------------*/ #ifndef NOTORDERED IGRAPH_EXPORT BASE FUNCTION(igraph_vector, min)(const TYPE(igraph_vector)* v); IGRAPH_EXPORT BASE FUNCTION(igraph_vector, max)(const TYPE(igraph_vector)* v); IGRAPH_EXPORT long int FUNCTION(igraph_vector, which_min)(const TYPE(igraph_vector)* v); IGRAPH_EXPORT long int FUNCTION(igraph_vector, which_max)(const TYPE(igraph_vector)* v); IGRAPH_EXPORT int FUNCTION(igraph_vector, minmax)(const TYPE(igraph_vector) *v, BASE *min, BASE *max); IGRAPH_EXPORT int FUNCTION(igraph_vector, which_minmax)(const TYPE(igraph_vector) *v, long int *which_min, long int *which_max); #endif /*-------------------*/ /* Vector properties */ /*-------------------*/ IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, empty) (const TYPE(igraph_vector)* v); IGRAPH_EXPORT long int FUNCTION(igraph_vector, size) (const TYPE(igraph_vector)* v); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, isnull)(const TYPE(igraph_vector) *v); IGRAPH_EXPORT BASE FUNCTION(igraph_vector, sum)(const TYPE(igraph_vector) *v); IGRAPH_EXPORT igraph_real_t FUNCTION(igraph_vector, sumsq)(const TYPE(igraph_vector) *v); IGRAPH_EXPORT BASE FUNCTION(igraph_vector, prod)(const TYPE(igraph_vector) *v); #ifndef NOTORDERED IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, isininterval)(const TYPE(igraph_vector) *v, BASE low, BASE high); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, any_smaller)(const TYPE(igraph_vector) *v, BASE limit); #endif IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, is_equal)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs); #ifndef NOTORDERED IGRAPH_EXPORT igraph_real_t FUNCTION(igraph_vector, maxdifference)(const TYPE(igraph_vector) *m1, const TYPE(igraph_vector) *m2); #endif /*------------------------*/ /* Searching for elements */ /*------------------------*/ IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, contains)(const TYPE(igraph_vector) *v, BASE e); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, search)(const TYPE(igraph_vector) *v, long int from, BASE what, long int *pos); #ifndef NOTORDERED IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, binsearch_slice)(const TYPE(igraph_vector) *v, BASE what, long int *pos, long int start, long int end); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, binsearch)(const TYPE(igraph_vector) *v, BASE what, long int *pos); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_vector, binsearch2)(const TYPE(igraph_vector) *v, BASE what); #endif /*------------------------*/ /* Resizing operations */ /*------------------------*/ IGRAPH_EXPORT void FUNCTION(igraph_vector, clear)(TYPE(igraph_vector)* v); IGRAPH_EXPORT int FUNCTION(igraph_vector, resize)(TYPE(igraph_vector)* v, long int newsize); IGRAPH_EXPORT int FUNCTION(igraph_vector, resize_min)(TYPE(igraph_vector)*v); IGRAPH_EXPORT int FUNCTION(igraph_vector, reserve)(TYPE(igraph_vector)* v, long int size); IGRAPH_EXPORT int FUNCTION(igraph_vector, push_back)(TYPE(igraph_vector)* v, BASE e); IGRAPH_EXPORT BASE FUNCTION(igraph_vector, pop_back)(TYPE(igraph_vector)* v); IGRAPH_EXPORT int FUNCTION(igraph_vector, insert)(TYPE(igraph_vector) *v, long int pos, BASE value); IGRAPH_EXPORT void FUNCTION(igraph_vector, remove)(TYPE(igraph_vector) *v, long int elem); IGRAPH_EXPORT void FUNCTION(igraph_vector, remove_section)(TYPE(igraph_vector) *v, long int from, long int to); /*-----------*/ /* Sorting */ /*-----------*/ #ifndef NOTORDERED IGRAPH_EXPORT void FUNCTION(igraph_vector, sort)(TYPE(igraph_vector) *v); IGRAPH_EXPORT void FUNCTION(igraph_vector, reverse_sort)(TYPE(igraph_vector) *v); IGRAPH_EXPORT long int FUNCTION(igraph_vector, qsort_ind)(TYPE(igraph_vector) *v, igraph_vector_t *inds, igraph_bool_t descending); #endif /*-----------*/ /* Printing */ /*-----------*/ IGRAPH_EXPORT int FUNCTION(igraph_vector, print)(const TYPE(igraph_vector) *v); IGRAPH_EXPORT int FUNCTION(igraph_vector, printf)(const TYPE(igraph_vector) *v, const char *format); IGRAPH_EXPORT int FUNCTION(igraph_vector, fprint)(const TYPE(igraph_vector) *v, FILE *file); #ifdef BASE_COMPLEX IGRAPH_EXPORT int igraph_vector_complex_real(const igraph_vector_complex_t *v, igraph_vector_t *real); IGRAPH_EXPORT int igraph_vector_complex_imag(const igraph_vector_complex_t *v, igraph_vector_t *imag); IGRAPH_EXPORT int igraph_vector_complex_realimag(const igraph_vector_complex_t *v, igraph_vector_t *real, igraph_vector_t *imag); IGRAPH_EXPORT int igraph_vector_complex_create(igraph_vector_complex_t *v, const igraph_vector_t *real, const igraph_vector_t *imag); IGRAPH_EXPORT int igraph_vector_complex_create_polar(igraph_vector_complex_t *v, const igraph_vector_t *r, const igraph_vector_t *theta); #endif IGRAPH_EXPORT int FUNCTION(igraph_vector, init_real)(TYPE(igraph_vector)*v, int no, ...); IGRAPH_EXPORT int FUNCTION(igraph_vector, init_int)(TYPE(igraph_vector)*v, int no, ...); IGRAPH_EXPORT int FUNCTION(igraph_vector, init_real_end)(TYPE(igraph_vector)*v, double endmark, ...); IGRAPH_EXPORT int FUNCTION(igraph_vector, init_int_end)(TYPE(igraph_vector)*v, int endmark, ...); IGRAPH_EXPORT int FUNCTION(igraph_vector, move_interval)(TYPE(igraph_vector) *v, long int begin, long int end, long int to); IGRAPH_EXPORT int FUNCTION(igraph_vector, move_interval2)(TYPE(igraph_vector) *v, long int begin, long int end, long int to); IGRAPH_EXPORT void FUNCTION(igraph_vector, permdelete)(TYPE(igraph_vector) *v, const igraph_vector_t *index, long int nremove); #ifndef NOTORDERED IGRAPH_EXPORT int FUNCTION(igraph_vector, filter_smaller)(TYPE(igraph_vector) *v, BASE elem); #endif IGRAPH_EXPORT int FUNCTION(igraph_vector, get_interval)(const TYPE(igraph_vector) *v, TYPE(igraph_vector) *res, long int from, long int to); #ifndef NOTORDERED IGRAPH_EXPORT int FUNCTION(igraph_vector, difference_sorted)(const TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2, TYPE(igraph_vector) *result); IGRAPH_EXPORT int FUNCTION(igraph_vector, intersect_sorted)(const TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2, TYPE(igraph_vector) *result); #endif IGRAPH_EXPORT int FUNCTION(igraph_vector, index)(const TYPE(igraph_vector) *v, TYPE(igraph_vector) *newv, const igraph_vector_t *idx); IGRAPH_EXPORT int FUNCTION(igraph_vector, index_int)(TYPE(igraph_vector) *v, const igraph_vector_int_t *idx); leidenbase/src/include/igraph_dqueue.h0000644000176200001440000000371614447675375017607 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_DQUEUE_H #define IGRAPH_DQUEUE_H #include "igraph_decls.h" #include "igraph_types.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* double ended queue, very useful */ /* -------------------------------------------------- */ #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "igraph_dqueue_pmt.h" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_LONG #include "igraph_pmt.h" #include "igraph_dqueue_pmt.h" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_CHAR #include "igraph_pmt.h" #include "igraph_dqueue_pmt.h" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "igraph_dqueue_pmt.h" #include "igraph_pmt_off.h" #undef BASE_BOOL #define BASE_INT #include "igraph_pmt.h" #include "igraph_dqueue_pmt.h" #include "igraph_pmt_off.h" #undef BASE_INT #define IGRAPH_DQUEUE_NULL { 0,0,0,0 } #define IGRAPH_DQUEUE_INIT_FINALLY(v, size) \ do { IGRAPH_CHECK(igraph_dqueue_init(v, size)); \ IGRAPH_FINALLY(igraph_dqueue_destroy, v); } while (0) __END_DECLS #endif leidenbase/src/include/igraph_vector_ptr.h0000644000176200001440000001136214447675375020502 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_VECTOR_PTR_H #define IGRAPH_VECTOR_PTR_H #include "igraph_decls.h" #include "igraph_vector.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Flexible vector, storing pointers */ /* -------------------------------------------------- */ /** * Vector, storing pointers efficiently * \ingroup internal * */ typedef struct s_vector_ptr { void** stor_begin; void** stor_end; void** end; igraph_finally_func_t* item_destructor; } igraph_vector_ptr_t; #define IGRAPH_VECTOR_PTR_NULL { 0,0,0,0 } #define IGRAPH_VECTOR_PTR_INIT_FINALLY(v, size) \ do { IGRAPH_CHECK(igraph_vector_ptr_init(v, size)); \ IGRAPH_FINALLY(igraph_vector_ptr_destroy, v); } while (0) IGRAPH_EXPORT int igraph_vector_ptr_init (igraph_vector_ptr_t* v, long int size); IGRAPH_EXPORT int igraph_vector_ptr_init_copy (igraph_vector_ptr_t* v, void** data, long int length); IGRAPH_EXPORT const igraph_vector_ptr_t *igraph_vector_ptr_view (const igraph_vector_ptr_t *v, void *const *data, long int length); IGRAPH_EXPORT void igraph_vector_ptr_destroy (igraph_vector_ptr_t* v); IGRAPH_EXPORT void igraph_vector_ptr_free_all (igraph_vector_ptr_t* v); IGRAPH_EXPORT void igraph_vector_ptr_destroy_all (igraph_vector_ptr_t* v); IGRAPH_EXPORT int igraph_vector_ptr_reserve (igraph_vector_ptr_t* v, long int size); IGRAPH_EXPORT igraph_bool_t igraph_vector_ptr_empty (const igraph_vector_ptr_t* v); IGRAPH_EXPORT long int igraph_vector_ptr_size (const igraph_vector_ptr_t* v); IGRAPH_EXPORT void igraph_vector_ptr_clear (igraph_vector_ptr_t* v); IGRAPH_EXPORT void igraph_vector_ptr_null (igraph_vector_ptr_t* v); IGRAPH_EXPORT int igraph_vector_ptr_push_back (igraph_vector_ptr_t* v, void* e); IGRAPH_EXPORT int igraph_vector_ptr_append (igraph_vector_ptr_t *to, const igraph_vector_ptr_t *from); IGRAPH_EXPORT void *igraph_vector_ptr_pop_back (igraph_vector_ptr_t *v); IGRAPH_EXPORT int igraph_vector_ptr_insert(igraph_vector_ptr_t *v, long int pos, void* e); IGRAPH_EXPORT void* igraph_vector_ptr_e (const igraph_vector_ptr_t* v, long int pos); IGRAPH_EXPORT void igraph_vector_ptr_set (igraph_vector_ptr_t* v, long int pos, void* value); IGRAPH_EXPORT int igraph_vector_ptr_resize(igraph_vector_ptr_t* v, long int newsize); IGRAPH_EXPORT void igraph_vector_ptr_copy_to(const igraph_vector_ptr_t *v, void** to); IGRAPH_EXPORT int igraph_vector_ptr_copy(igraph_vector_ptr_t *to, const igraph_vector_ptr_t *from); IGRAPH_EXPORT void igraph_vector_ptr_remove(igraph_vector_ptr_t *v, long int pos); IGRAPH_EXPORT void igraph_vector_ptr_sort(igraph_vector_ptr_t *v, int(*compar)(const void*, const void*)); IGRAPH_EXPORT int igraph_vector_ptr_index_int(igraph_vector_ptr_t *v, const igraph_vector_int_t *idx); IGRAPH_EXPORT igraph_finally_func_t* igraph_vector_ptr_get_item_destructor(const igraph_vector_ptr_t *v); IGRAPH_EXPORT igraph_finally_func_t* igraph_vector_ptr_set_item_destructor(igraph_vector_ptr_t *v, igraph_finally_func_t *func); /** * \define IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR * \brief Sets the item destructor for this pointer vector (macro version). * * This macro is expanded to \ref igraph_vector_ptr_set_item_destructor(), the * only difference is that the second argument is automatically cast to an * \c igraph_finally_func_t*. The cast is necessary in most cases as the * destructor functions we use (such as \ref igraph_vector_destroy()) take a * pointer to some concrete igraph data type, while \c igraph_finally_func_t * expects \c void* */ #define IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(v, func) \ igraph_vector_ptr_set_item_destructor((v), (igraph_finally_func_t*)(func)) __END_DECLS #endif leidenbase/src/include/igraph_complex.h0000644000176200001440000001177314447675375017770 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_COMPLEX_H #define IGRAPH_COMPLEX_H #include "igraph_decls.h" #include "igraph_types.h" __BEGIN_DECLS typedef struct igraph_complex_t { igraph_real_t dat[2]; } igraph_complex_t; #define IGRAPH_REAL(x) ((x).dat[0]) #define IGRAPH_IMAG(x) ((x).dat[1]) #define IGRAPH_COMPLEX_EQ(x,y) ((x).dat[0]==(y).dat[0] && (x).dat[1]==(y).dat[1]) IGRAPH_EXPORT igraph_complex_t igraph_complex(igraph_real_t x, igraph_real_t y); IGRAPH_EXPORT igraph_complex_t igraph_complex_polar(igraph_real_t r, igraph_real_t theta); IGRAPH_EXPORT igraph_bool_t igraph_complex_eq_tol(igraph_complex_t z1, igraph_complex_t z2, igraph_real_t tol); IGRAPH_EXPORT igraph_real_t igraph_complex_mod(igraph_complex_t z); IGRAPH_EXPORT igraph_real_t igraph_complex_arg(igraph_complex_t z); IGRAPH_EXPORT igraph_real_t igraph_complex_abs(igraph_complex_t z); IGRAPH_EXPORT igraph_real_t igraph_complex_logabs(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_add(igraph_complex_t z1, igraph_complex_t z2); IGRAPH_EXPORT igraph_complex_t igraph_complex_sub(igraph_complex_t z1, igraph_complex_t z2); IGRAPH_EXPORT igraph_complex_t igraph_complex_mul(igraph_complex_t z1, igraph_complex_t z2); IGRAPH_EXPORT igraph_complex_t igraph_complex_div(igraph_complex_t z1, igraph_complex_t z2); IGRAPH_EXPORT igraph_complex_t igraph_complex_add_real(igraph_complex_t z, igraph_real_t x); IGRAPH_EXPORT igraph_complex_t igraph_complex_add_imag(igraph_complex_t z, igraph_real_t y); IGRAPH_EXPORT igraph_complex_t igraph_complex_sub_real(igraph_complex_t z, igraph_real_t x); IGRAPH_EXPORT igraph_complex_t igraph_complex_sub_imag(igraph_complex_t z, igraph_real_t y); IGRAPH_EXPORT igraph_complex_t igraph_complex_mul_real(igraph_complex_t z, igraph_real_t x); IGRAPH_EXPORT igraph_complex_t igraph_complex_mul_imag(igraph_complex_t z, igraph_real_t y); IGRAPH_EXPORT igraph_complex_t igraph_complex_div_real(igraph_complex_t z, igraph_real_t x); IGRAPH_EXPORT igraph_complex_t igraph_complex_div_imag(igraph_complex_t z, igraph_real_t y); IGRAPH_EXPORT igraph_complex_t igraph_complex_conj(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_neg(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_inv(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_sqrt(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_sqrt_real(igraph_real_t x); IGRAPH_EXPORT igraph_complex_t igraph_complex_exp(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_pow(igraph_complex_t z1, igraph_complex_t z2); IGRAPH_EXPORT igraph_complex_t igraph_complex_pow_real(igraph_complex_t z, igraph_real_t x); IGRAPH_EXPORT igraph_complex_t igraph_complex_log(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_log10(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_log_b(igraph_complex_t z, igraph_complex_t b); IGRAPH_EXPORT igraph_complex_t igraph_complex_sin(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_cos(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_tan(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_sec(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_csc(igraph_complex_t z); IGRAPH_EXPORT igraph_complex_t igraph_complex_cot(igraph_complex_t z); __END_DECLS #endif leidenbase/src/include/igraph_iterators.h0000644000176200001440000003166114447675375020333 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_ITERATORS_H #define IGRAPH_ITERATORS_H #include "igraph_decls.h" #include "igraph_constants.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Vertex selectors */ /* -------------------------------------------------- */ #define IGRAPH_VS_ALL 0 #define IGRAPH_VS_ADJ 1 #define IGRAPH_VS_NONE 2 #define IGRAPH_VS_1 3 #define IGRAPH_VS_VECTORPTR 4 #define IGRAPH_VS_VECTOR 5 #define IGRAPH_VS_SEQ 6 #define IGRAPH_VS_NONADJ 7 typedef struct igraph_vs_t { int type; union { igraph_integer_t vid; /* single vertex */ const igraph_vector_t *vecptr; /* vector of vertices */ struct { igraph_integer_t vid; igraph_neimode_t mode; } adj; /* adjacent vertices */ struct { igraph_integer_t from; igraph_integer_t to; } seq; /* sequence of vertices from:to */ } data; } igraph_vs_t; IGRAPH_EXPORT int igraph_vs_all(igraph_vs_t *vs); IGRAPH_EXPORT igraph_vs_t igraph_vss_all(void); IGRAPH_EXPORT int igraph_vs_adj(igraph_vs_t *vs, igraph_integer_t vid, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_vs_nonadj(igraph_vs_t *vs, igraph_integer_t vid, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_vs_none(igraph_vs_t *vs); IGRAPH_EXPORT igraph_vs_t igraph_vss_none(void); IGRAPH_EXPORT int igraph_vs_1(igraph_vs_t *vs, igraph_integer_t vid); IGRAPH_EXPORT igraph_vs_t igraph_vss_1(igraph_integer_t vid); IGRAPH_EXPORT int igraph_vs_vector(igraph_vs_t *vs, const igraph_vector_t *v); IGRAPH_EXPORT igraph_vs_t igraph_vss_vector(const igraph_vector_t *v); IGRAPH_EXPORT int igraph_vs_vector_small(igraph_vs_t *vs, ...); IGRAPH_EXPORT int igraph_vs_vector_copy(igraph_vs_t *vs, const igraph_vector_t *v); IGRAPH_EXPORT int igraph_vs_seq(igraph_vs_t *vs, igraph_integer_t from, igraph_integer_t to); IGRAPH_EXPORT igraph_vs_t igraph_vss_seq(igraph_integer_t from, igraph_integer_t to); IGRAPH_EXPORT void igraph_vs_destroy(igraph_vs_t *vs); IGRAPH_EXPORT igraph_bool_t igraph_vs_is_all(const igraph_vs_t *vs); IGRAPH_EXPORT int igraph_vs_copy(igraph_vs_t* dest, const igraph_vs_t* src); IGRAPH_EXPORT int igraph_vs_as_vector(const igraph_t *graph, igraph_vs_t vs, igraph_vector_t *v); IGRAPH_EXPORT int igraph_vs_size(const igraph_t *graph, const igraph_vs_t *vs, igraph_integer_t *result); IGRAPH_EXPORT int igraph_vs_type(const igraph_vs_t *vs); /* -------------------------------------------------- */ /* Vertex iterators */ /* -------------------------------------------------- */ #define IGRAPH_VIT_SEQ 0 #define IGRAPH_VIT_VECTOR 1 #define IGRAPH_VIT_VECTORPTR 2 typedef struct igraph_vit_t { int type; long int pos; long int start; long int end; const igraph_vector_t *vec; } igraph_vit_t; /** * \section IGRAPH_VIT Stepping over the vertices * * After creating an iterator with \ref igraph_vit_create(), it * points to the first vertex in the vertex determined by the vertex * selector (if there is any). The \ref IGRAPH_VIT_NEXT() macro steps * to the next vertex, \ref IGRAPH_VIT_END() checks whether there are * more vertices to visit, \ref IGRAPH_VIT_SIZE() gives the total size * of the vertices visited so far and to be visited. \ref * IGRAPH_VIT_RESET() resets the iterator, it will point to the first * vertex again. Finally \ref IGRAPH_VIT_GET() gives the current vertex * pointed to by the iterator (call this only if \ref IGRAPH_VIT_END() * is false). * * * Here is an example on how to step over the neighbors of vertex 0: * * igraph_vs_t vs; * igraph_vit_t vit; * ... * igraph_vs_adj(&vs, 0, IGRAPH_ALL); * igraph_vit_create(&graph, vs, &vit); * while (!IGRAPH_VIT_END(vit)) { * printf(" %li", (long int) IGRAPH_VIT_GET(vit)); * IGRAPH_VIT_NEXT(vit); * } * printf("\n"); * ... * igraph_vit_destroy(&vit); * igraph_vs_destroy(&vs); * * */ /** * \define IGRAPH_VIT_NEXT * \brief Next vertex. * * Steps the iterator to the next vertex. Only call this function if * \ref IGRAPH_VIT_END() returns false. * \param vit The vertex iterator to step. * * Time complexity: O(1). */ #define IGRAPH_VIT_NEXT(vit) (++((vit).pos)) /** * \define IGRAPH_VIT_END * \brief Are we at the end? * * Checks whether there are more vertices to step to. * \param vit The vertex iterator to check. * \return Logical value, if true there are no more vertices to step * to. * * Time complexity: O(1). */ #define IGRAPH_VIT_END(vit) ((vit).pos >= (vit).end) /** * \define IGRAPH_VIT_SIZE * \brief Size of a vertex iterator. * * Gives the number of vertices in a vertex iterator. * \param vit The vertex iterator. * \return The number of vertices. * * Time complexity: O(1). */ #define IGRAPH_VIT_SIZE(vit) ((vit).end - (vit).start) /** * \define IGRAPH_VIT_RESET * \brief Reset a vertex iterator. * * Resets a vertex iterator. After calling this macro the iterator * will point to the first vertex. * \param vit The vertex iterator. * * Time complexity: O(1). */ #define IGRAPH_VIT_RESET(vit) ((vit).pos = (vit).start) /** * \define IGRAPH_VIT_GET * \brief Query the current position. * * Gives the vertex id of the current vertex pointed to by the * iterator. * \param vit The vertex iterator. * \return The vertex id of the current vertex. * * Time complexity: O(1). */ #define IGRAPH_VIT_GET(vit) \ ((igraph_integer_t)(((vit).type == IGRAPH_VIT_SEQ) ? (vit).pos : \ VECTOR(*(vit).vec)[(vit).pos])) IGRAPH_EXPORT int igraph_vit_create(const igraph_t *graph, igraph_vs_t vs, igraph_vit_t *vit); IGRAPH_EXPORT void igraph_vit_destroy(const igraph_vit_t *vit); IGRAPH_EXPORT int igraph_vit_as_vector(const igraph_vit_t *vit, igraph_vector_t *v); /* -------------------------------------------------- */ /* Edge Selectors */ /* -------------------------------------------------- */ #define IGRAPH_ES_ALL 0 #define IGRAPH_ES_ALLFROM 1 #define IGRAPH_ES_ALLTO 2 #define IGRAPH_ES_INCIDENT 3 #define IGRAPH_ES_NONE 4 #define IGRAPH_ES_1 5 #define IGRAPH_ES_VECTORPTR 6 #define IGRAPH_ES_VECTOR 7 #define IGRAPH_ES_SEQ 8 #define IGRAPH_ES_PAIRS 9 #define IGRAPH_ES_PATH 10 #define IGRAPH_ES_MULTIPAIRS 11 typedef struct igraph_es_t { int type; union { igraph_integer_t vid; igraph_integer_t eid; const igraph_vector_t *vecptr; struct { igraph_integer_t vid; igraph_neimode_t mode; } incident; struct { igraph_integer_t from; igraph_integer_t to; } seq; struct { const igraph_vector_t *ptr; igraph_bool_t mode; } path; } data; } igraph_es_t; IGRAPH_EXPORT int igraph_es_all(igraph_es_t *es, igraph_edgeorder_type_t order); IGRAPH_EXPORT igraph_es_t igraph_ess_all(igraph_edgeorder_type_t order); IGRAPH_EXPORT int igraph_es_incident(igraph_es_t *es, igraph_integer_t vid, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_es_none(igraph_es_t *es); IGRAPH_EXPORT igraph_es_t igraph_ess_none(void); IGRAPH_EXPORT int igraph_es_1(igraph_es_t *es, igraph_integer_t eid); IGRAPH_EXPORT igraph_es_t igraph_ess_1(igraph_integer_t eid); IGRAPH_EXPORT int igraph_es_vector(igraph_es_t *es, const igraph_vector_t *v); IGRAPH_EXPORT igraph_es_t igraph_ess_vector(const igraph_vector_t *v); IGRAPH_EXPORT int igraph_es_fromto(igraph_es_t *es, igraph_vs_t from, igraph_vs_t to); IGRAPH_EXPORT int igraph_es_seq(igraph_es_t *es, igraph_integer_t from, igraph_integer_t to); IGRAPH_EXPORT igraph_es_t igraph_ess_seq(igraph_integer_t from, igraph_integer_t to); IGRAPH_EXPORT int igraph_es_vector_copy(igraph_es_t *es, const igraph_vector_t *v); IGRAPH_EXPORT int igraph_es_pairs(igraph_es_t *es, const igraph_vector_t *v, igraph_bool_t directed); IGRAPH_EXPORT int igraph_es_pairs_small(igraph_es_t *es, igraph_bool_t directed, ...); IGRAPH_EXPORT int igraph_es_multipairs(igraph_es_t *es, const igraph_vector_t *v, igraph_bool_t directed); IGRAPH_EXPORT int igraph_es_path(igraph_es_t *es, const igraph_vector_t *v, igraph_bool_t directed); IGRAPH_EXPORT int igraph_es_path_small(igraph_es_t *es, igraph_bool_t directed, ...); IGRAPH_EXPORT void igraph_es_destroy(igraph_es_t *es); IGRAPH_EXPORT igraph_bool_t igraph_es_is_all(const igraph_es_t *es); IGRAPH_EXPORT int igraph_es_copy(igraph_es_t* dest, const igraph_es_t* src); IGRAPH_EXPORT int igraph_es_as_vector(const igraph_t *graph, igraph_es_t es, igraph_vector_t *v); IGRAPH_EXPORT int igraph_es_size(const igraph_t *graph, const igraph_es_t *es, igraph_integer_t *result); IGRAPH_EXPORT int igraph_es_type(const igraph_es_t *es); /* -------------------------------------------------- */ /* Edge Iterators */ /* -------------------------------------------------- */ #define IGRAPH_EIT_SEQ 0 #define IGRAPH_EIT_VECTOR 1 #define IGRAPH_EIT_VECTORPTR 2 typedef struct igraph_eit_t { int type; long int pos; long int start; long int end; const igraph_vector_t *vec; } igraph_eit_t; /** * \section IGRAPH_EIT Stepping over the edges * * Just like for vertex iterators, macros are provided for * stepping over a sequence of edges: \ref IGRAPH_EIT_NEXT() goes to * the next edge, \ref IGRAPH_EIT_END() checks whether there are more * edges to visit, \ref IGRAPH_EIT_SIZE() gives the number of edges in * the edge sequence, \ref IGRAPH_EIT_RESET() resets the iterator to * the first edge and \ref IGRAPH_EIT_GET() returns the id of the * current edge. */ /** * \define IGRAPH_EIT_NEXT * \brief Next edge. * * Steps the iterator to the next edge. Call this function only if * \ref IGRAPH_EIT_END() returns false. * \param eit The edge iterator to step. * * Time complexity: O(1). */ #define IGRAPH_EIT_NEXT(eit) (++((eit).pos)) /** * \define IGRAPH_EIT_END * \brief Are we at the end? * * Checks whether there are more edges to step to. * \param wit The edge iterator to check. * \return Logical value, if true there are no more edges * to step to. * * Time complexity: O(1). */ #define IGRAPH_EIT_END(eit) ((eit).pos >= (eit).end) /** * \define IGRAPH_EIT_SIZE * \brief Number of edges in the iterator. * * Gives the number of edges in an edge iterator. * \param eit The edge iterator. * \return The number of edges. * * Time complexity: O(1). */ #define IGRAPH_EIT_SIZE(eit) ((eit).end - (eit).start) /** * \define IGRAPH_EIT_RESET * \brief Reset an edge iterator. * * Resets an edge iterator. After calling this macro the iterator will * point to the first edge. * \param eit The edge iterator. * * Time complexity: O(1). */ #define IGRAPH_EIT_RESET(eit) ((eit).pos = (eit).start) /** * \define IGRAPH_EIT_GET * \brief Query an edge iterator. * * Gives the edge id of the current edge pointed to by an iterator. * \param eit The edge iterator. * \return The id of the current edge. * * Time complexity: O(1). */ #define IGRAPH_EIT_GET(eit) \ (igraph_integer_t)((((eit).type == IGRAPH_EIT_SEQ) ? (eit).pos : \ VECTOR(*(eit).vec)[(eit).pos])) IGRAPH_EXPORT int igraph_eit_create(const igraph_t *graph, igraph_es_t es, igraph_eit_t *eit); IGRAPH_EXPORT void igraph_eit_destroy(const igraph_eit_t *eit); IGRAPH_EXPORT int igraph_eit_as_vector(const igraph_eit_t *eit, igraph_vector_t *v); __END_DECLS #endif leidenbase/src/include/igraph_types.h0000644000176200001440000000454714447675375017466 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_TYPES_H #define IGRAPH_TYPES_H #include "igraph_decls.h" __BEGIN_DECLS #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #include "igraph_error.h" #include #include #include typedef int igraph_integer_t; typedef double igraph_real_t; typedef int igraph_bool_t; /* printf format specifier for igraph_integer_t */ #define IGRAPH_PRId "d" /* Replacements for printf that print doubles in the same way on all platforms * (even for NaN and infinities) */ IGRAPH_EXPORT int igraph_real_printf(igraph_real_t val); IGRAPH_EXPORT int igraph_real_fprintf(FILE *file, igraph_real_t val); IGRAPH_EXPORT int igraph_real_snprintf(char* str, size_t size, igraph_real_t val); /* Replacements for printf that print doubles in the same way on all platforms * (even for NaN and infinities) with the largest possible precision */ IGRAPH_EXPORT int igraph_real_printf_precise(igraph_real_t val); IGRAPH_EXPORT int igraph_real_fprintf_precise(FILE *file, igraph_real_t val); IGRAPH_EXPORT int igraph_real_snprintf_precise(char* str, size_t size, igraph_real_t val); #define IGRAPH_INFINITY INFINITY #define IGRAPH_POSINFINITY INFINITY #define IGRAPH_NEGINFINITY (-INFINITY) IGRAPH_EXPORT int igraph_finite(double x); #define IGRAPH_FINITE(x) igraph_finite(x) IGRAPH_EXPORT int igraph_is_nan(double x); IGRAPH_EXPORT int igraph_is_inf(double x); IGRAPH_EXPORT int igraph_is_posinf(double x); IGRAPH_EXPORT int igraph_is_neginf(double x); #define IGRAPH_NAN NAN __END_DECLS #endif leidenbase/src/include/igraph_hrg.h0000644000176200001440000001106214447675375017070 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_HRG_H #define IGRAPH_HRG_H #include "igraph_decls.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" #include "igraph_datatype.h" __BEGIN_DECLS /** * \struct igraph_hrg_t * Data structure to store a hierarchical random graph * * A hierarchical random graph (HRG) can be given as a binary tree, * where the internal vertices are labeled with real numbers. * * Note that you don't necessarily have to know this * internal representation for using the HRG functions, just pass the * HRG objects created by one igraph function, to another igraph * function. * * * It has the following members: * \member left Vector that contains the left children of the internal * tree vertices. The first vertex is always the root vertex, so * the first element of the vector is the left child of the root * vertex. Internal vertices are denoted with negative numbers, * starting from -1 and going down, i.e. the root vertex is * -1. Leaf vertices are denoted by non-negative number, starting * from zero and up. * \member right Vector that contains the right children of the * vertices, with the same encoding as the \c left vector. * \member prob The connection probabilities attached to the internal * vertices, the first number belongs to the root vertex * (i.e. internal vertex -1), the second to internal vertex -2, * etc. * \member edges The number of edges in the subtree below the given * internal vertex. * \member vertices The number of vertices in the subtree below the * given internal vertex, including itself. */ typedef struct igraph_hrg_t { igraph_vector_t left, right, prob, edges, vertices; } igraph_hrg_t; IGRAPH_EXPORT int igraph_hrg_init(igraph_hrg_t *hrg, int n); IGRAPH_EXPORT void igraph_hrg_destroy(igraph_hrg_t *hrg); IGRAPH_EXPORT int igraph_hrg_size(const igraph_hrg_t *hrg); IGRAPH_EXPORT int igraph_hrg_resize(igraph_hrg_t *hrg, int newsize); IGRAPH_EXPORT int igraph_hrg_fit(const igraph_t *graph, igraph_hrg_t *hrg, igraph_bool_t start, int steps); IGRAPH_EXPORT int igraph_hrg_sample(const igraph_t *graph, igraph_t *sample, igraph_vector_ptr_t *samples, igraph_integer_t no_samples, igraph_hrg_t *hrg, igraph_bool_t start); IGRAPH_EXPORT int igraph_hrg_game(igraph_t *graph, const igraph_hrg_t *hrg); IGRAPH_EXPORT int igraph_hrg_dendrogram(igraph_t *graph, const igraph_hrg_t *hrg); IGRAPH_EXPORT int igraph_hrg_consensus(const igraph_t *graph, igraph_vector_t *parents, igraph_vector_t *weights, igraph_hrg_t *hrg, igraph_bool_t start, int num_samples); IGRAPH_EXPORT int igraph_hrg_predict(const igraph_t *graph, igraph_vector_t *edges, igraph_vector_t *prob, igraph_hrg_t *hrg, igraph_bool_t start, int num_samples, int num_bins); IGRAPH_EXPORT int igraph_hrg_create(igraph_hrg_t *hrg, const igraph_t *graph, const igraph_vector_t *prob); __END_DECLS #endif /* IGRAPH_HRG_H */ leidenbase/src/include/igraph_array.h0000644000176200001440000000315714447675375017434 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_ARRAY_H #define IGRAPH_ARRAY_H #include "igraph_decls.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* 3D array */ /* -------------------------------------------------- */ #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "igraph_array_pmt.h" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_LONG #include "igraph_pmt.h" #include "igraph_array_pmt.h" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_CHAR #include "igraph_pmt.h" #include "igraph_array_pmt.h" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "igraph_array_pmt.h" #include "igraph_pmt_off.h" #undef BASE_BOOL __END_DECLS #endif leidenbase/src/include/igraph.h0000644000176200001440000000556614447675375016244 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_H #define IGRAPH_H #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #include "igraph_version.h" #include "igraph_memory.h" #include "igraph_error.h" #include "igraph_random.h" #include "igraph_progress.h" #include "igraph_statusbar.h" #include "igraph_types.h" #include "igraph_complex.h" #include "igraph_vector.h" #include "igraph_matrix.h" #include "igraph_array.h" #include "igraph_dqueue.h" #include "igraph_stack.h" #include "igraph_heap.h" #include "igraph_psumtree.h" #include "igraph_strvector.h" #include "igraph_vector_ptr.h" #include "igraph_spmatrix.h" #include "igraph_sparsemat.h" #include "igraph_qsort.h" #include "igraph_constants.h" #include "igraph_datatype.h" #include "igraph_iterators.h" #include "igraph_interface.h" #include "igraph_constructors.h" #include "igraph_games.h" #include "igraph_microscopic_update.h" #include "igraph_centrality.h" #include "igraph_paths.h" #include "igraph_components.h" #include "igraph_structural.h" #include "igraph_transitivity.h" #include "igraph_neighborhood.h" #include "igraph_topology.h" #include "igraph_bipartite.h" #include "igraph_cliques.h" #include "igraph_layout.h" #include "igraph_visitor.h" #include "igraph_community.h" #include "igraph_conversion.h" #include "igraph_foreign.h" #include "igraph_motifs.h" #include "igraph_operators.h" #include "igraph_flow.h" #include "igraph_nongraph.h" #include "igraph_cocitation.h" #include "igraph_adjlist.h" #include "igraph_attributes.h" #include "igraph_blas.h" #include "igraph_lapack.h" #include "igraph_arpack.h" #include "igraph_mixing.h" #include "igraph_separators.h" #include "igraph_cohesive_blocks.h" #include "igraph_eigen.h" #include "igraph_hrg.h" #include "igraph_threading.h" #include "igraph_interrupt.h" #include "igraph_scg.h" #include "igraph_matching.h" #include "igraph_embedding.h" #include "igraph_scan.h" #include "igraph_graphlets.h" #include "igraph_epidemics.h" #include "igraph_lsap.h" #include "igraph_coloring.h" #include "igraph_eulerian.h" #include "igraph_graphicality.h" #endif leidenbase/src/include/igraph_qsort.h0000644000176200001440000000245414447675375017465 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard st, Cambridge, MA 02139, USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_QSORT_H #define IGRAPH_QSORT_H #include "igraph_decls.h" #include __BEGIN_DECLS IGRAPH_EXPORT void igraph_qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)); IGRAPH_EXPORT void igraph_qsort_r(void *base, size_t nel, size_t width, void *thunk, int (*compar)(void *, const void *, const void *)); __END_DECLS #endif leidenbase/src/include/igraph_arpack.h0000644000176200001440000003414214447675375017555 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_ARPACK_H #define IGRAPH_ARPACK_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_matrix.h" __BEGIN_DECLS /** * \section about_arpack ARPACK interface in igraph * * * ARPACK is a library for solving large scale eigenvalue problems. * The package is designed to compute a few eigenvalues and corresponding * eigenvectors of a general \c n by \c n matrix \c A. It is * most appropriate for large sparse or structured matrices \c A where * structured means that a matrix-vector product w <- Av requires * order \c n rather than the usual order n^2 floating point * operations. Please see * http://www.caam.rice.edu/software/ARPACK/ for details. * * * * The eigenvalue calculation in ARPACK (in the simplest * case) involves the calculation of the \c Av product where \c A * is the matrix we work with and \c v is an arbitrary vector. A * user-defined function of type \ref igraph_arpack_function_t * is expected to perform this product. If the product can be done * efficiently, e.g. if the matrix is sparse, then ARPACK is usually * able to calculate the eigenvalues very quickly. * * * In igraph, eigenvalue/eigenvector calculations usually * involve the following steps: * \olist * \oli Initialization of an \ref igraph_arpack_options_t data * structure using \ref igraph_arpack_options_init. * \oli Setting some options in the initialized \ref * igraph_arpack_options_t object. * \oli Defining a function of type \ref igraph_arpack_function_t. * The input of this function is a vector, and the output * should be the output matrix multiplied by the input vector. * \oli Calling \ref igraph_arpack_rssolve() (is the matrix is * symmetric), or \ref igraph_arpack_rnsolve(). * \endolist * The \ref igraph_arpack_options_t object can be used multiple * times. * * * * If we have many eigenvalue problems to solve, then it might worth * to create an \ref igraph_arpack_storage_t object, and initialize it * via \ref igraph_arpack_storage_init(). This structure contains all * memory needed for ARPACK (with the given upper limit regerding to * the size of the eigenvalue problem). Then many problems can be * solved using the same \ref igraph_arpack_storage_t object, without * always reallocating the required memory. * The \ref igraph_arpack_storage_t object needs to be destroyed by * calling \ref igraph_arpack_storage_destroy() on it, when it is not * needed any more. * * * * igraph does not contain all * ARPACK routines, only the ones dealing with symmetric and * non-symmetric eigenvalue problems using double precision real * numbers. * * */ /** * \struct igraph_arpack_options_t * \brief Options for ARPACK * * This data structure contains the options of thee ARPACK eigenvalue * solver routines. It must be initialized by calling \ref * igraph_arpack_options_init() on it. Then it can be used for * multiple ARPACK calls, as the ARPACK solvers do not modify it. * * Input options: * \member bmat Character. Whether to solve a standard ('I') ot a * generalized problem ('B'). * \member n Dimension of the eigenproblem. * \member which Specifies which eigenvalues/vectors to * compute. Possible values for symmetric matrices: * \clist \cli LA * Compute \c nev largest (algebraic) eigenvalues. * \cli SA * Compute \c nev smallest (algebraic) eigenvalues. * \cli LM * Compute \c nev largest (in magnitude) eigenvalues. * \cli SM * Compute \c nev smallest (in magnitude) eigenvalues. * \cli BE * Compute \c nev eigenvalues, half from each end of * the spectrum. When \c nev is odd, compute one * more from the high en than from the low * end. \endclist * Possible values for non-symmetric matrices: * \clist \cli LM * Compute \c nev largest (in magnitude) eigenvalues. * \cli SM * Compute \c nev smallest (in magnitude) eigenvalues. * \cli LR * Compute \c nev eigenvalues of largest real part. * \cli SR * Compute \c nev eigenvalues of smallest real part. * \cli LI * Compute \c nev eigenvalues of largest imaginary part. * \cli SI * Compute \c nev eigenvalues of smallest imaginary * part. \endclist * \member nev The number of eigenvalues to be computed. * \member tol Stopping criterion: the relative accuracy * of the Ritz value is considered acceptable if its error is less * than \c tol times its estimated value. If this is set to zero * then machine precision is used. * \member ncv Number of Lanczos vectors to be generated. Setting this * to zero means that \ref igraph_arpack_rssolve and \ref igraph_arpack_rnsolve * will determine a suitable value for \c ncv automatically. * \member ldv Numberic scalar. It should be set to * zero in the current igraph implementation. * \member ishift Either zero or one. If zero then the shifts are * provided by the user via reverse communication. If one then exact * shifts with respect to the reduced tridiagonal matrix \c T. * Please always set this to one. * \member mxiter Maximum number of Arnoldi update iterations allowed. * \member nb Blocksize to be used in the recurrence. Please always * leave this on the default value, one. * \member mode The type of the eigenproblem to be solved. * Possible values if the input matrix is symmetric: * \olist * \oli A*x=lambda*x, A is symmetric. * \oli A*x=lambda*M*x, A is * symmetric, M is symmetric positive definite. * \oli K*x=lambda*M*x, K is * symmetric, M is symmetric positive semi-definite. * \oli K*x=lambda*KG*x, K is * symmetric positive semi-definite, KG is symmetric * indefinite. * \oli A*x=lambda*M*x, A is * symmetric, M is symmetric positive * semi-definite. (Cayley transformed mode.) \endolist * Please note that only \c mode ==1 was tested and other values * might not work properly. * Possible values if the input matrix is not symmetric: * \olist * \oli A*x=lambda*x. * \oli A*x=lambda*M*x, M is * symmetric positive definite. * \oli A*x=lambda*M*x, M is * symmetric semi-definite. * \oli A*x=lambda*M*x, M is * symmetric semi-definite. \endolist * Please note that only \c mode == 1 was tested and other values * might not work properly. * \member start Whether to use the supplied starting vector (1), or * use a random starting vector (0). The starting vector must be * supplied in the first column of the \c vectors argument of the * \ref igraph_arpack_rssolve() of \ref igraph_arpack_rnsolve() call. * * Output options: * \member info Error flag of ARPACK. Possible values: * \clist \cli 0 * Normal exit. * \cli 1 * Maximum number of iterations taken. * \cli 3 * No shifts could be applied during a cycle of the * Implicitly restarted Arnoldi iteration. One possibility * is to increase the size of \c ncv relative to \c * nev. \endclist * ARPACK can return other error flags as well, but these are * converted to igraph errors, see \ref igraph_error_type_t. * \member ierr Error flag of the second ARPACK call (one eigenvalue * computation usually involves two calls to ARPACK). This is * always zero, as other error codes are converted to igraph errors. * \member noiter Number of Arnoldi iterations taken. * \member nconv Number of converged Ritz values. This * represents the number of Ritz values that satisfy the * convergence critetion. * \member numop Total number of matrix-vector multiplications. * \member numopb Not used currently. * \member numreo Total number of steps of re-orthogonalization. * * Internal options: * \member lworkl Do not modify this option. * \member sigma The shift for the shift-invert mode. * \member sigmai The imaginary part of the shift, for the * non-symmetric or complex shift-invert mode. * \member iparam Do not modify this option. * \member ipntr Do not modify this option. * */ typedef struct igraph_arpack_options_t { /* INPUT */ char bmat[1]; /* I-standard problem, G-generalized */ int n; /* Dimension of the eigenproblem */ char which[2]; /* LA, SA, LM, SM, BE */ int nev; /* Number of eigenvalues to be computed */ igraph_real_t tol; /* Stopping criterion */ int ncv; /* Number of columns in V */ int ldv; /* Leading dimension of V */ int ishift; /* 0-reverse comm., 1-exact with tridiagonal */ int mxiter; /* Maximum number of update iterations to take */ int nb; /* Block size on the recurrence, only 1 works */ int mode; /* The kind of problem to be solved (1-5) 1: A*x=l*x, A symmetric 2: A*x=l*M*x, A symm. M pos. def. 3: K*x = l*M*x, K symm., M pos. semidef. 4: K*x = l*KG*x, K s. pos. semidef. KG s. indef. 5: A*x = l*M*x, A symm., M symm. pos. semidef. */ int start; /* 0: random, 1: use the supplied vector */ int lworkl; /* Size of temporary storage, default is fine */ igraph_real_t sigma; /* The shift for modes 3,4,5 */ igraph_real_t sigmai; /* The imaginary part of shift for rnsolve */ /* OUTPUT */ int info; /* What happened, see docs */ int ierr; /* What happened in the dseupd call */ int noiter; /* The number of iterations taken */ int nconv; int numop; /* Number of OP*x operations */ int numopb; /* Number of B*x operations if BMAT='G' */ int numreo; /* Number of steps of re-orthogonalizations */ /* INTERNAL */ int iparam[11]; int ipntr[14]; } igraph_arpack_options_t; /** * \struct igraph_arpack_storage_t * \brief Storage for ARPACK * * Public members, do not modify them directly, these are considered * to be read-only. * \member maxn Maximum rank of matrix. * \member maxncv Maximum NCV. * \member maxldv Maximum LDV. * * These members are considered to be private: * \member workl Working memory. * \member workd Working memory. * \member d Memory for eigenvalues. * \member resid Memory for residuals. * \member ax Working memory. * \member select Working memory. * \member di Memory for eigenvalues, non-symmetric case only. * \member workev Working memory, non-symmetric case only. */ typedef struct igraph_arpack_storage_t { int maxn, maxncv, maxldv; igraph_real_t *v; igraph_real_t *workl; igraph_real_t *workd; igraph_real_t *d; igraph_real_t *resid; igraph_real_t *ax; int *select; igraph_real_t *di; /* These two only for non-symmetric problems */ igraph_real_t *workev; } igraph_arpack_storage_t; IGRAPH_EXPORT void igraph_arpack_options_init(igraph_arpack_options_t *o); IGRAPH_EXPORT int igraph_arpack_storage_init(igraph_arpack_storage_t *s, long int maxn, long int maxncv, long int maxldv, igraph_bool_t symm); IGRAPH_EXPORT void igraph_arpack_storage_destroy(igraph_arpack_storage_t *s); /** * \typedef igraph_arpack_function_t * Type of the ARPACK callback function * * \param to Pointer to an \c igraph_real_t, the result of the * matrix-vector product is expected to be stored here. * \param from Pointer to an \c igraph_real_t, the input matrix should * be multiplied by the vector stored here. * \param n The length of the vector (which is the same as the order * of the input matrix). * \param extra Extra argument to the matrix-vector calculation * function. This is coming from the \ref igraph_arpack_rssolve() * or \ref igraph_arpack_rnsolve() function. * \return Error code, if not zero, then the ARPACK solver considers * this as an error, stops and calls the igraph error handler. */ typedef int igraph_arpack_function_t(igraph_real_t *to, const igraph_real_t *from, int n, void *extra); IGRAPH_EXPORT int igraph_arpack_rssolve(igraph_arpack_function_t *fun, void *extra, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors); IGRAPH_EXPORT int igraph_arpack_rnsolve(igraph_arpack_function_t *fun, void *extra, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_matrix_t *values, igraph_matrix_t *vectors); IGRAPH_EXPORT int igraph_arpack_unpack_complex(igraph_matrix_t *vectors, igraph_matrix_t *values, long int nev); __END_DECLS #endif leidenbase/src/include/igraph_epidemics.h0000644000176200001440000000432314447675375020254 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2014 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_EPIDEMICS_H #define IGRAPH_EPIDEMICS_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS /** * \struct igraph_sir_t * \brief The result of one SIR model simulation. * * Data structure to store the results of one simulation * of the SIR (susceptible-infected-recovered) model on a graph. * * It has the following members. They are all (real or integer) * vectors, and they are of the same length. * * \member times A vector, the times of the events are stored here. * \member no_s An integer vector, the number of susceptibles in * each time step is stored here. * \member no_i An integer vector, the number of infected individuals * at each time step, is stored here. * \member no_r An integer vector, the number of recovered individuals * is stored here at each time step. */ typedef struct igraph_sir_t { igraph_vector_t times; igraph_vector_int_t no_s, no_i, no_r; } igraph_sir_t; IGRAPH_EXPORT int igraph_sir_init(igraph_sir_t *sir); IGRAPH_EXPORT void igraph_sir_destroy(igraph_sir_t *sir); IGRAPH_EXPORT int igraph_sir(const igraph_t *graph, igraph_real_t beta, igraph_real_t gamma, igraph_integer_t no_sim, igraph_vector_ptr_t *result); __END_DECLS #endif leidenbase/src/include/igraph_games.h0000644000176200001440000003221714447675375017411 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_GAMES_H #define IGRAPH_GAMES_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_matrix.h" #include "igraph_vector.h" #include "igraph_datatype.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Constructors, games (=stochastic) */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_barabasi_game(igraph_t *graph, igraph_integer_t n, igraph_real_t power, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t A, igraph_bool_t directed, igraph_barabasi_algorithm_t algo, const igraph_t *start_from); IGRAPH_EXPORT int igraph_erdos_renyi_game(igraph_t *graph, igraph_erdos_renyi_t type, igraph_integer_t n, igraph_real_t p_or_m, igraph_bool_t directed, igraph_bool_t loops); IGRAPH_EXPORT int igraph_erdos_renyi_game_gnp(igraph_t *graph, igraph_integer_t n, igraph_real_t p, igraph_bool_t directed, igraph_bool_t loops); IGRAPH_EXPORT int igraph_erdos_renyi_game_gnm(igraph_t *graph, igraph_integer_t n, igraph_real_t m, igraph_bool_t directed, igraph_bool_t loops); IGRAPH_EXPORT int igraph_degree_sequence_game(igraph_t *graph, const igraph_vector_t *out_deg, const igraph_vector_t *in_deg, igraph_degseq_t method); IGRAPH_EXPORT int igraph_growing_random_game(igraph_t *graph, igraph_integer_t n, igraph_integer_t m, igraph_bool_t directed, igraph_bool_t citation); IGRAPH_EXPORT int igraph_barabasi_aging_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t pa_exp, igraph_real_t aging_exp, igraph_integer_t aging_bin, igraph_real_t zero_deg_appeal, igraph_real_t zero_age_appeal, igraph_real_t deg_coef, igraph_real_t age_coef, igraph_bool_t directed); IGRAPH_EXPORT int igraph_recent_degree_game(igraph_t *graph, igraph_integer_t n, igraph_real_t power, igraph_integer_t window, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t zero_appeal, igraph_bool_t directed); IGRAPH_EXPORT int igraph_recent_degree_aging_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t pa_exp, igraph_real_t aging_exp, igraph_integer_t aging_bin, igraph_integer_t window, igraph_real_t zero_appeal, igraph_bool_t directed); IGRAPH_EXPORT int igraph_callaway_traits_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t types, igraph_integer_t edges_per_step, const igraph_vector_t *type_dist, const igraph_matrix_t *pref_matrix, igraph_bool_t directed, igraph_vector_t *node_type_vec); IGRAPH_EXPORT int igraph_establishment_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t types, igraph_integer_t k, const igraph_vector_t *type_dist, const igraph_matrix_t *pref_matrix, igraph_bool_t directed, igraph_vector_t *node_type_vec); IGRAPH_EXPORT int igraph_grg_game(igraph_t *graph, igraph_integer_t nodes, igraph_real_t radius, igraph_bool_t torus, igraph_vector_t *x, igraph_vector_t *y); IGRAPH_EXPORT int igraph_preference_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t types, const igraph_vector_t *type_dist, igraph_bool_t fixed_sizes, const igraph_matrix_t *pref_matrix, igraph_vector_t *node_type_vec, igraph_bool_t directed, igraph_bool_t loops); IGRAPH_EXPORT int igraph_asymmetric_preference_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t out_types, igraph_integer_t in_types, const igraph_matrix_t *type_dist_matrix, const igraph_matrix_t *pref_matrix, igraph_vector_t *node_type_out_vec, igraph_vector_t *node_type_in_vec, igraph_bool_t loops); IGRAPH_EXPORT int igraph_rewire_edges(igraph_t *graph, igraph_real_t prob, igraph_bool_t loops, igraph_bool_t multiple); IGRAPH_EXPORT int igraph_rewire_directed_edges(igraph_t *graph, igraph_real_t prob, igraph_bool_t loops, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_watts_strogatz_game(igraph_t *graph, igraph_integer_t dim, igraph_integer_t size, igraph_integer_t nei, igraph_real_t p, igraph_bool_t loops, igraph_bool_t multiple); IGRAPH_EXPORT int igraph_lastcit_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t edges_per_node, igraph_integer_t agebins, const igraph_vector_t *preference, igraph_bool_t directed); IGRAPH_EXPORT int igraph_cited_type_game(igraph_t *graph, igraph_integer_t nodes, const igraph_vector_t *types, const igraph_vector_t *pref, igraph_integer_t edges_per_step, igraph_bool_t directed); IGRAPH_EXPORT int igraph_citing_cited_type_game(igraph_t *graph, igraph_integer_t nodes, const igraph_vector_t *types, const igraph_matrix_t *pref, igraph_integer_t edges_per_step, igraph_bool_t directed); IGRAPH_EXPORT int igraph_forest_fire_game(igraph_t *graph, igraph_integer_t nodes, igraph_real_t fw_prob, igraph_real_t bw_factor, igraph_integer_t ambs, igraph_bool_t directed); IGRAPH_EXPORT int igraph_simple_interconnected_islands_game( igraph_t *graph, igraph_integer_t islands_n, igraph_integer_t islands_size, igraph_real_t islands_pin, igraph_integer_t n_inter); IGRAPH_EXPORT int igraph_static_fitness_game(igraph_t *graph, igraph_integer_t no_of_edges, const igraph_vector_t *fitness_out, const igraph_vector_t *fitness_in, igraph_bool_t loops, igraph_bool_t multiple); IGRAPH_EXPORT int igraph_static_power_law_game(igraph_t *graph, igraph_integer_t no_of_nodes, igraph_integer_t no_of_edges, igraph_real_t exponent_out, igraph_real_t exponent_in, igraph_bool_t loops, igraph_bool_t multiple, igraph_bool_t finite_size_correction); IGRAPH_EXPORT int igraph_k_regular_game(igraph_t *graph, igraph_integer_t no_of_nodes, igraph_integer_t k, igraph_bool_t directed, igraph_bool_t multiple); IGRAPH_EXPORT int igraph_sbm_game(igraph_t *graph, igraph_integer_t n, const igraph_matrix_t *pref_matrix, const igraph_vector_int_t *block_sizes, igraph_bool_t directed, igraph_bool_t loops); IGRAPH_EXPORT int igraph_hsbm_game(igraph_t *graph, igraph_integer_t n, igraph_integer_t m, const igraph_vector_t *rho, const igraph_matrix_t *C, igraph_real_t p); IGRAPH_EXPORT int igraph_hsbm_list_game(igraph_t *graph, igraph_integer_t n, const igraph_vector_int_t *mlist, const igraph_vector_ptr_t *rholist, const igraph_vector_ptr_t *Clist, igraph_real_t p); IGRAPH_EXPORT int igraph_correlated_game(const igraph_t *old_graph, igraph_t *new_graph, igraph_real_t corr, igraph_real_t p, const igraph_vector_t *permutation); IGRAPH_EXPORT int igraph_correlated_pair_game(igraph_t *graph1, igraph_t *graph2, igraph_integer_t n, igraph_real_t corr, igraph_real_t p, igraph_bool_t directed, const igraph_vector_t *permutation); IGRAPH_EXPORT int igraph_tree_game(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, igraph_random_tree_t method); IGRAPH_EXPORT int igraph_dot_product_game(igraph_t *graph, const igraph_matrix_t *vecs, igraph_bool_t directed); IGRAPH_EXPORT int igraph_sample_sphere_surface(igraph_integer_t dim, igraph_integer_t n, igraph_real_t radius, igraph_bool_t positive, igraph_matrix_t *res); IGRAPH_EXPORT int igraph_sample_sphere_volume(igraph_integer_t dim, igraph_integer_t n, igraph_real_t radius, igraph_bool_t positive, igraph_matrix_t *res); IGRAPH_EXPORT int igraph_sample_dirichlet(igraph_integer_t n, const igraph_vector_t *alpha, igraph_matrix_t *res); __END_DECLS #endif leidenbase/src/include/igraph_matching.h0000644000176200001440000000454414447675375020111 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2012 Tamas Nepusz This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_MATCHING_H #define IGRAPH_MATCHING_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_datatype.h" #include "igraph_types.h" #include "igraph_vector.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Matchings in graphs */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_is_matching(const igraph_t* graph, const igraph_vector_bool_t* types, const igraph_vector_long_t* matching, igraph_bool_t* result); IGRAPH_EXPORT int igraph_is_maximal_matching(const igraph_t* graph, const igraph_vector_bool_t* types, const igraph_vector_long_t* matching, igraph_bool_t* result); IGRAPH_EXPORT int igraph_maximum_bipartite_matching(const igraph_t* graph, const igraph_vector_bool_t* types, igraph_integer_t* matching_size, igraph_real_t* matching_weight, igraph_vector_long_t* matching, const igraph_vector_t* weights, igraph_real_t eps); IGRAPH_EXPORT int igraph_maximum_matching(const igraph_t* graph, igraph_integer_t* matching_size, igraph_real_t* matching_weight, igraph_vector_long_t* matching, const igraph_vector_t* weights); __END_DECLS #endif leidenbase/src/include/igraph_attributes.h0000644000176200001440000010506214447675375020502 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_ATTRIBUTES_H #define IGRAPH_ATTRIBUTES_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_strvector.h" #include "igraph_vector_ptr.h" #include "igraph_iterators.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Attributes */ /* -------------------------------------------------- */ /** * \section about_attributes * * Attributes are numbers or strings (or basically any kind * of data) associated with the vertices or edges of a graph, or * with the graph itself. Eg. you may label vertices with symbolic names * or attach numeric weights to the edges of a graph. * * igraph attributes are designed to be flexible and extensible. * In igraph attributes are implemented via an interface abstraction: * any type implementing the functions in the interface, can be used * for storing vertex, edge and graph attributes. This means that * different attribute implementations can be used together with * igraph. This is reasonable: if igraph is used from Python attributes can be * of any Python type, from GNU R all R types are allowed. There is an * experimental attribute implementation to be used when programming * in C, but by default it is currently turned off. * * First we briefly look over how attribute handlers can be * implemented. This is not something a user does every day. It is * rather typically the job of the high level interface writers. (But * it is possible to write an interface without implementing * attributes.) Then we show the experimental C attribute handler. */ /** * \section about_attribute_table * It is possible to attach an attribute handling * interface to \a igraph. This is simply a table of functions, of * type \ref igraph_attribute_table_t. These functions are invoked to * notify the attribute handling code about the structural changes in * a graph. See the documentation of this type for details. * * By default there is no attribute interface attached to \a igraph, * to attach one, call \ref igraph_set_attribute_table with your new * table. * */ /** * \section about_attribute_combination * * Several graph operations may collapse multiple vertices or edges into * a single one. Attribute combination lists are used to indicate to the attribute * handler how to combine the attributes of the original vertices or edges and * how to derive the final attribute value that is to be assigned to the collapsed * vertex or edge. For example, \ref igraph_simplify() removes loops and combines * multiple edges into a single one; in case of a graph with an edge attribute * named \c weight the attribute combination list can tell the attribute handler * whether the weight of a collapsed edge should be the sum, the mean or some other * function of the weights of the original edges that were collapsed into one. * * One attribute combination list may contain several attribute combination * records, one for each vertex or edge attribute that is to be handled during the * operation. */ /** * \typedef igraph_attribute_type_t * The possible types of the attributes. * * Note that this is only the * type communicated by the attribute interface towards igraph * functions. Eg. in the GNU R attribute handler, it is safe to say * that all complex R object attributes are strings, as long as this * interface is able to serialize them into strings. See also \ref * igraph_attribute_table_t. * \enumval IGRAPH_ATTRIBUTE_DEFAULT Currently not used for anything. * \enumval IGRAPH_ATTRIBUTE_NUMERIC Numeric attribute. * \enumval IGRAPH_ATTRIBUTE_BOOLEAN Logical values, true or false. * \enumval IGRAPH_ATTRIBUTE_STRING Attribute that can be converted to * a string. * \enumval IGRAPH_ATTRIBUTE_R_OBJECT An R object. This is usually * ignored by the igraph functions. * \enumval IGRAPH_ATTRIBUTE_PY_OBJECT A Python object. Usually * ignored by the igraph functions. * */ typedef enum { IGRAPH_ATTRIBUTE_DEFAULT = 0, IGRAPH_ATTRIBUTE_NUMERIC = 1, IGRAPH_ATTRIBUTE_BOOLEAN = 5, IGRAPH_ATTRIBUTE_STRING = 2, IGRAPH_ATTRIBUTE_R_OBJECT = 3, IGRAPH_ATTRIBUTE_PY_OBJECT = 4 } igraph_attribute_type_t; typedef struct igraph_attribute_record_t { const char *name; igraph_attribute_type_t type; const void *value; } igraph_attribute_record_t; typedef enum { IGRAPH_ATTRIBUTE_GRAPH = 0, IGRAPH_ATTRIBUTE_VERTEX, IGRAPH_ATTRIBUTE_EDGE } igraph_attribute_elemtype_t; /** * \typedef igraph_attribute_combination_type_t * The possible types of attribute combinations. * * \enumval IGRAPH_ATTRIBUTE_COMBINE_IGNORE Ignore old attributes, use an empty value. * \enumval IGRAPH_ATTRIBUTE_COMBINE_DEFAULT Use the default way to combine attributes (decided by the attribute handler implementation). * \enumval IGRAPH_ATTRIBUTE_COMBINE_FUNCTION Supply your own function to combine * attributes. * \enumval IGRAPH_ATTRIBUTE_COMBINE_SUM Take the sum of the attributes. * \enumval IGRAPH_ATTRIBUTE_COMBINE_PROD Take the product of the attributes. * \enumval IGRAPH_ATTRIBUTE_COMBINE_MIN Take the minimum attribute. * \enumval IGRAPH_ATTRIBUTE_COMBINE_MAX Take the maximum attribute. * \enumval IGRAPH_ATTRIBUTE_COMBINE_RANDOM Take a random attribute. * \enumval IGRAPH_ATTRIBUTE_COMBINE_FIRST Take the first attribute. * \enumval IGRAPH_ATTRIBUTE_COMBINE_LAST Take the last attribute. * \enumval IGRAPH_ATTRIBUTE_COMBINE_MEAN Take the mean of the attributes. * \enumval IGRAPH_ATTRIBUTE_COMBINE_MEDIAN Take the median of the attributes. * \enumval IGRAPH_ATTRIBUTE_COMBINE_CONCAT Concatenate the attributes. */ typedef enum { IGRAPH_ATTRIBUTE_COMBINE_IGNORE = 0, IGRAPH_ATTRIBUTE_COMBINE_DEFAULT = 1, IGRAPH_ATTRIBUTE_COMBINE_FUNCTION = 2, IGRAPH_ATTRIBUTE_COMBINE_SUM = 3, IGRAPH_ATTRIBUTE_COMBINE_PROD = 4, IGRAPH_ATTRIBUTE_COMBINE_MIN = 5, IGRAPH_ATTRIBUTE_COMBINE_MAX = 6, IGRAPH_ATTRIBUTE_COMBINE_RANDOM = 7, IGRAPH_ATTRIBUTE_COMBINE_FIRST = 8, IGRAPH_ATTRIBUTE_COMBINE_LAST = 9, IGRAPH_ATTRIBUTE_COMBINE_MEAN = 10, IGRAPH_ATTRIBUTE_COMBINE_MEDIAN = 11, IGRAPH_ATTRIBUTE_COMBINE_CONCAT = 12 } igraph_attribute_combination_type_t; typedef void (*igraph_function_pointer_t)(void); typedef struct igraph_attribute_combination_record_t { const char *name; /* can be NULL, meaning: the rest */ igraph_attribute_combination_type_t type; igraph_function_pointer_t func; } igraph_attribute_combination_record_t; typedef struct igraph_attribute_combination_t { igraph_vector_ptr_t list; } igraph_attribute_combination_t; #define IGRAPH_NO_MORE_ATTRIBUTES ((const char*)0) IGRAPH_EXPORT int igraph_attribute_combination_init(igraph_attribute_combination_t *comb); IGRAPH_EXPORT int igraph_attribute_combination(igraph_attribute_combination_t *comb, ...); IGRAPH_EXPORT void igraph_attribute_combination_destroy(igraph_attribute_combination_t *comb); IGRAPH_EXPORT int igraph_attribute_combination_add(igraph_attribute_combination_t *comb, const char *name, igraph_attribute_combination_type_t type, igraph_function_pointer_t func); IGRAPH_EXPORT int igraph_attribute_combination_remove(igraph_attribute_combination_t *comb, const char *name); IGRAPH_EXPORT int igraph_attribute_combination_query(const igraph_attribute_combination_t *comb, const char *name, igraph_attribute_combination_type_t *type, igraph_function_pointer_t *func); /** * \struct igraph_attribute_table_t * \brief Table of functions to perform operations on attributes * * This type collects the functions defining an attribute handler. * It has the following members: * \member init This function is called whenever a new graph object is * created, right after it is created but before any vertices or * edges are added. It is supposed to set the \c attr member of the \c * igraph_t object. It is expected to return an error code. * \member destroy This function is called whenever the graph object * is destroyed, right before freeing the allocated memory. * \member copy This function is called when copying a graph with \ref * igraph_copy, after the structure of the graph has been already * copied. It is expected to return an error code. * \member add_vertices Called when vertices are added to a * graph, before adding the vertices themselves. * The number of vertices to add is supplied as an * argument. Expected to return an error code. * \member permute_vertices Typically called when a new graph is * created based on an existing one, e.g. if vertices are removed * from a graph. The supplied index vector defines which old vertex * a new vertex corresponds to. Its length must be the same as the * number of vertices in the new graph. * \member combine_vertices This function is called when the creation * of a new graph involves a merge (contraction, etc.) of vertices * from another graph. The function is after the new graph was created. * An argument specifies how several vertices from the old graph map to a * single vertex in the new graph. * \member add_edges Called when new edges have been added. The number * of new edges are supplied as well. It is expected to return an * error code. * \member permute_edges Typically called when a new graph is created and * some of the new edges should carry the attributes of some of the * old edges. The idx vector shows the mapping between the old edges and * the new ones. Its length is the same as the number of edges in the new * graph, and for each edge it gives the id of the old edge (the edge in * the old graph). * \member combine_edges This function is called when the creation * of a new graph involves a merge (contraction, etc.) of edges * from another graph. The function is after the new graph was created. * An argument specifies how several edges from the old graph map to a * single edge in the new graph. * \member get_info Query the attributes of a graph, the names and * types should be returned. * \member has_attr Check whether a graph has the named * graph/vertex/edge attribute. * \member gettype Query the type of a graph/vertex/edge attribute. * \member get_numeric_graph_attr Query a numeric graph attribute. The * value should be placed as the first element of the \p value * vector. * \member get_string_graph_attr Query a string graph attribute. The * value should be placed as the first element of the \p value * string vector. * \member get_bool_graph_attr Query a boolean graph attribute. The * value should be placed as the first element of the \p value * boolean vector. * \member get_numeric_vertex_attr Query a numeric vertex attribute, * for the vertices included in \p vs. * \member get_string_vertex_attr Query a string vertex attribute, * for the vertices included in \p vs. * \member get_bool_vertex_attr Query a boolean vertex attribute, * for the vertices included in \p vs. * \member get_numeric_edge_attr Query a numeric edge attribute, for * the edges included in \p es. * \member get_string_edge_attr Query a string edge attribute, for the * edges included in \p es. * \member get_bool_edge_attr Query a boolean edge attribute, for the * edges included in \p es. * * Note that the get_*_*_attr are allowed to * convert the attributes to numeric or string. E.g. if a vertex attribute * is a GNU R complex data type, then * get_string_vertex_attribute may serialize it * into a string, but this probably makes sense only if * add_vertices is able to deserialize it. */ typedef struct igraph_attribute_table_t { int (*init)(igraph_t *graph, igraph_vector_ptr_t *attr); void (*destroy)(igraph_t *graph); int (*copy)(igraph_t *to, const igraph_t *from, igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea); int (*add_vertices)(igraph_t *graph, long int nv, igraph_vector_ptr_t *attr); int (*permute_vertices)(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_t *idx); int (*combine_vertices)(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_ptr_t *merges, const igraph_attribute_combination_t *comb); int (*add_edges)(igraph_t *graph, const igraph_vector_t *edges, igraph_vector_ptr_t *attr); int (*permute_edges)(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_t *idx); int (*combine_edges)(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_ptr_t *merges, const igraph_attribute_combination_t *comb); int (*get_info)(const igraph_t *graph, igraph_strvector_t *gnames, igraph_vector_t *gtypes, igraph_strvector_t *vnames, igraph_vector_t *vtypes, igraph_strvector_t *enames, igraph_vector_t *etypes); igraph_bool_t (*has_attr)(const igraph_t *graph, igraph_attribute_elemtype_t type, const char *name); int (*gettype)(const igraph_t *graph, igraph_attribute_type_t *type, igraph_attribute_elemtype_t elemtype, const char *name); int (*get_numeric_graph_attr)(const igraph_t *graph, const char *name, igraph_vector_t *value); int (*get_string_graph_attr)(const igraph_t *graph, const char *name, igraph_strvector_t *value); int (*get_bool_graph_attr)(const igraph_t *igraph, const char *name, igraph_vector_bool_t *value); int (*get_numeric_vertex_attr)(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_vector_t *value); int (*get_string_vertex_attr)(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_strvector_t *value); int (*get_bool_vertex_attr)(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_vector_bool_t *value); int (*get_numeric_edge_attr)(const igraph_t *graph, const char *name, igraph_es_t es, igraph_vector_t *value); int (*get_string_edge_attr)(const igraph_t *graph, const char *name, igraph_es_t es, igraph_strvector_t *value); int (*get_bool_edge_attr)(const igraph_t *graph, const char *name, igraph_es_t es, igraph_vector_bool_t *value); } igraph_attribute_table_t; IGRAPH_EXPORT IGRAPH_DEPRECATED igraph_attribute_table_t * igraph_i_set_attribute_table(const igraph_attribute_table_t * table); IGRAPH_EXPORT igraph_attribute_table_t * igraph_set_attribute_table(const igraph_attribute_table_t * table); IGRAPH_EXPORT igraph_bool_t igraph_has_attribute_table(void); /* Experimental attribute handler in C */ IGRAPH_EXPORT extern const igraph_attribute_table_t igraph_cattribute_table; IGRAPH_EXPORT igraph_real_t igraph_cattribute_GAN(const igraph_t *graph, const char *name); IGRAPH_EXPORT igraph_bool_t igraph_cattribute_GAB(const igraph_t *graph, const char *name); IGRAPH_EXPORT const char* igraph_cattribute_GAS(const igraph_t *graph, const char *name); IGRAPH_EXPORT igraph_real_t igraph_cattribute_VAN(const igraph_t *graph, const char *name, igraph_integer_t vid); IGRAPH_EXPORT igraph_bool_t igraph_cattribute_VAB(const igraph_t *graph, const char *name, igraph_integer_t vid); IGRAPH_EXPORT const char* igraph_cattribute_VAS(const igraph_t *graph, const char *name, igraph_integer_t vid); IGRAPH_EXPORT igraph_real_t igraph_cattribute_EAN(const igraph_t *graph, const char *name, igraph_integer_t eid); IGRAPH_EXPORT igraph_bool_t igraph_cattribute_EAB(const igraph_t *graph, const char *name, igraph_integer_t eid); IGRAPH_EXPORT const char* igraph_cattribute_EAS(const igraph_t *graph, const char *name, igraph_integer_t eid); IGRAPH_EXPORT int igraph_cattribute_VANV(const igraph_t *graph, const char *name, igraph_vs_t vids, igraph_vector_t *result); IGRAPH_EXPORT int igraph_cattribute_EANV(const igraph_t *graph, const char *name, igraph_es_t eids, igraph_vector_t *result); IGRAPH_EXPORT int igraph_cattribute_VASV(const igraph_t *graph, const char *name, igraph_vs_t vids, igraph_strvector_t *result); IGRAPH_EXPORT int igraph_cattribute_EASV(const igraph_t *graph, const char *name, igraph_es_t eids, igraph_strvector_t *result); IGRAPH_EXPORT int igraph_cattribute_VABV(const igraph_t *graph, const char *name, igraph_vs_t vids, igraph_vector_bool_t *result); IGRAPH_EXPORT int igraph_cattribute_EABV(const igraph_t *graph, const char *name, igraph_es_t eids, igraph_vector_bool_t *result); IGRAPH_EXPORT int igraph_cattribute_list(const igraph_t *graph, igraph_strvector_t *gnames, igraph_vector_t *gtypes, igraph_strvector_t *vnames, igraph_vector_t *vtypes, igraph_strvector_t *enames, igraph_vector_t *etypes); IGRAPH_EXPORT igraph_bool_t igraph_cattribute_has_attr(const igraph_t *graph, igraph_attribute_elemtype_t type, const char *name); IGRAPH_EXPORT int igraph_cattribute_GAN_set(igraph_t *graph, const char *name, igraph_real_t value); IGRAPH_EXPORT int igraph_cattribute_GAB_set(igraph_t *graph, const char *name, igraph_bool_t value); IGRAPH_EXPORT int igraph_cattribute_GAS_set(igraph_t *graph, const char *name, const char *value); IGRAPH_EXPORT int igraph_cattribute_VAN_set(igraph_t *graph, const char *name, igraph_integer_t vid, igraph_real_t value); IGRAPH_EXPORT int igraph_cattribute_VAB_set(igraph_t *graph, const char *name, igraph_integer_t vid, igraph_bool_t value); IGRAPH_EXPORT int igraph_cattribute_VAS_set(igraph_t *graph, const char *name, igraph_integer_t vid, const char *value); IGRAPH_EXPORT int igraph_cattribute_EAN_set(igraph_t *graph, const char *name, igraph_integer_t eid, igraph_real_t value); IGRAPH_EXPORT int igraph_cattribute_EAB_set(igraph_t *graph, const char *name, igraph_integer_t eid, igraph_bool_t value); IGRAPH_EXPORT int igraph_cattribute_EAS_set(igraph_t *graph, const char *name, igraph_integer_t eid, const char *value); IGRAPH_EXPORT int igraph_cattribute_VAN_setv(igraph_t *graph, const char *name, const igraph_vector_t *v); IGRAPH_EXPORT int igraph_cattribute_VAB_setv(igraph_t *graph, const char *name, const igraph_vector_bool_t *v); IGRAPH_EXPORT int igraph_cattribute_VAS_setv(igraph_t *graph, const char *name, const igraph_strvector_t *sv); IGRAPH_EXPORT int igraph_cattribute_EAN_setv(igraph_t *graph, const char *name, const igraph_vector_t *v); IGRAPH_EXPORT int igraph_cattribute_EAB_setv(igraph_t *graph, const char *name, const igraph_vector_bool_t *v); IGRAPH_EXPORT int igraph_cattribute_EAS_setv(igraph_t *graph, const char *name, const igraph_strvector_t *sv); IGRAPH_EXPORT void igraph_cattribute_remove_g(igraph_t *graph, const char *name); IGRAPH_EXPORT void igraph_cattribute_remove_v(igraph_t *graph, const char *name); IGRAPH_EXPORT void igraph_cattribute_remove_e(igraph_t *graph, const char *name); IGRAPH_EXPORT void igraph_cattribute_remove_all(igraph_t *graph, igraph_bool_t g, igraph_bool_t v, igraph_bool_t e); /** * \define GAN * Query a numeric graph attribute. * * This is shorthand for \ref igraph_cattribute_GAN(). * \param graph The graph. * \param n The name of the attribute. * \return The value of the attribute. */ #define GAN(graph,n) (igraph_cattribute_GAN((graph), (n))) /** * \define GAB * Query a boolean graph attribute. * * This is shorthand for \ref igraph_cattribute_GAB(). * \param graph The graph. * \param n The name of the attribute. * \return The value of the attribute. */ #define GAB(graph,n) (igraph_cattribute_GAB((graph), (n))) /** * \define GAS * Query a string graph attribute. * * This is shorthand for \ref igraph_cattribute_GAS(). * \param graph The graph. * \param n The name of the attribute. * \return The value of the attribute. */ #define GAS(graph,n) (igraph_cattribute_GAS((graph), (n))) /** * \define VAN * Query a numeric vertex attribute. * * This is shorthand for \ref igraph_cattribute_VAN(). * \param graph The graph. * \param n The name of the attribute. * \param v The id of the vertex. * \return The value of the attribute. */ #define VAN(graph,n,v) (igraph_cattribute_VAN((graph), (n), (v))) /** * \define VAB * Query a boolean vertex attribute. * * This is shorthand for \ref igraph_cattribute_VAB(). * \param graph The graph. * \param n The name of the attribute. * \param v The id of the vertex. * \return The value of the attribute. */ #define VAB(graph,n,v) (igraph_cattribute_VAB((graph), (n), (v))) /** * \define VAS * Query a string vertex attribute. * * This is shorthand for \ref igraph_cattribute_VAS(). * \param graph The graph. * \param n The name of the attribute. * \param v The id of the vertex. * \return The value of the attribute. */ #define VAS(graph,n,v) (igraph_cattribute_VAS((graph), (n), (v))) /** * \define VANV * Query a numeric vertex attribute for all vertices. * * This is a shorthand for \ref igraph_cattribute_VANV(). * \param graph The graph. * \param n The name of the attribute. * \param vec Pointer to an initialized vector, the result is * stored here. It will be resized, if needed. * \return Error code. */ #define VANV(graph,n,vec) (igraph_cattribute_VANV((graph),(n), \ igraph_vss_all(), (vec))) /** * \define VABV * Query a boolean vertex attribute for all vertices. * * This is a shorthand for \ref igraph_cattribute_VABV(). * \param graph The graph. * \param n The name of the attribute. * \param vec Pointer to an initialized boolean vector, the result is * stored here. It will be resized, if needed. * \return Error code. */ #define VABV(graph,n,vec) (igraph_cattribute_VABV((graph),(n), \ igraph_vss_all(), (vec))) /** * \define VASV * Query a string vertex attribute for all vertices. * * This is a shorthand for \ref igraph_cattribute_VASV(). * \param graph The graph. * \param n The name of the attribute. * \param vec Pointer to an initialized string vector, the result is * stored here. It will be resized, if needed. * \return Error code. */ #define VASV(graph,n,vec) (igraph_cattribute_VASV((graph),(n), \ igraph_vss_all(), (vec))) /** * \define EAN * Query a numeric edge attribute. * * This is shorthand for \ref igraph_cattribute_EAN(). * \param graph The graph. * \param n The name of the attribute. * \param e The id of the edge. * \return The value of the attribute. */ #define EAN(graph,n,e) (igraph_cattribute_EAN((graph), (n), (e))) /** * \define EAB * Query a boolean edge attribute. * * This is shorthand for \ref igraph_cattribute_EAB(). * \param graph The graph. * \param n The name of the attribute. * \param e The id of the edge. * \return The value of the attribute. */ #define EAB(graph,n,e) (igraph_cattribute_EAB((graph), (n), (e))) /** * \define EAS * Query a string edge attribute. * * This is shorthand for \ref igraph_cattribute_EAS(). * \param graph The graph. * \param n The name of the attribute. * \param e The id of the edge. * \return The value of the attribute. */ #define EAS(graph,n,e) (igraph_cattribute_EAS((graph), (n), (e))) /** * \define EANV * Query a numeric edge attribute for all edges. * * This is a shorthand for \ref igraph_cattribute_EANV(). * \param graph The graph. * \param n The name of the attribute. * \param vec Pointer to an initialized vector, the result is * stored here. It will be resized, if needed. * \return Error code. */ #define EANV(graph,n,vec) (igraph_cattribute_EANV((graph),(n), \ igraph_ess_all(IGRAPH_EDGEORDER_ID), (vec))) /** * \define EABV * Query a boolean edge attribute for all edges. * * This is a shorthand for \ref igraph_cattribute_EABV(). * \param graph The graph. * \param n The name of the attribute. * \param vec Pointer to an initialized vector, the result is * stored here. It will be resized, if needed. * \return Error code. */ #define EABV(graph,n,vec) (igraph_cattribute_EABV((graph),(n), \ igraph_ess_all(IGRAPH_EDGEORDER_ID), (vec))) /** * \define EASV * Query a string edge attribute for all edges. * * This is a shorthand for \ref igraph_cattribute_EASV(). * \param graph The graph. * \param n The name of the attribute. * \param vec Pointer to an initialized string vector, the result is * stored here. It will be resized, if needed. * \return Error code. */ #define EASV(graph,n,vec) (igraph_cattribute_EASV((graph),(n), \ igraph_ess_all(IGRAPH_EDGEORDER_ID), (vec))) /** * \define SETGAN * Set a numeric graph attribute * * This is a shorthand for \ref igraph_cattribute_GAN_set(). * \param graph The graph. * \param n The name of the attribute. * \param value The new value of the attribute. * \return Error code. */ #define SETGAN(graph,n,value) (igraph_cattribute_GAN_set((graph),(n),(value))) /** * \define SETGAB * Set a boolean graph attribute * * This is a shorthand for \ref igraph_cattribute_GAB_set(). * \param graph The graph. * \param n The name of the attribute. * \param value The new value of the attribute. * \return Error code. */ #define SETGAB(graph,n,value) (igraph_cattribute_GAB_set((graph),(n),(value))) /** * \define SETGAS * Set a string graph attribute * * This is a shorthand for \ref igraph_cattribute_GAS_set(). * \param graph The graph. * \param n The name of the attribute. * \param value The new value of the attribute. * \return Error code. */ #define SETGAS(graph,n,value) (igraph_cattribute_GAS_set((graph),(n),(value))) /** * \define SETVAN * Set a numeric vertex attribute * * This is a shorthand for \ref igraph_cattribute_VAN_set(). * \param graph The graph. * \param n The name of the attribute. * \param vid Ids of the vertices to set. * \param value The new value of the attribute. * \return Error code. */ #define SETVAN(graph,n,vid,value) (igraph_cattribute_VAN_set((graph),(n),(vid),(value))) /** * \define SETVAB * Set a boolean vertex attribute * * This is a shorthand for \ref igraph_cattribute_VAB_set(). * \param graph The graph. * \param n The name of the attribute. * \param vid Ids of the vertices to set. * \param value The new value of the attribute. * \return Error code. */ #define SETVAB(graph,n,vid,value) (igraph_cattribute_VAB_set((graph),(n),(vid),(value))) /** * \define SETVAS * Set a string vertex attribute * * This is a shorthand for \ref igraph_cattribute_VAS_set(). * \param graph The graph. * \param n The name of the attribute. * \param vid Ids of the vertices to set. * \param value The new value of the attribute. * \return Error code. */ #define SETVAS(graph,n,vid,value) (igraph_cattribute_VAS_set((graph),(n),(vid),(value))) /** * \define SETEAN * Set a numeric edge attribute * * This is a shorthand for \ref igraph_cattribute_EAN_set(). * \param graph The graph. * \param n The name of the attribute. * \param eid Ids of the edges to set. * \param value The new value of the attribute. * \return Error code. */ #define SETEAN(graph,n,eid,value) (igraph_cattribute_EAN_set((graph),(n),(eid),(value))) /** * \define SETEAB * Set a boolean edge attribute * * This is a shorthand for \ref igraph_cattribute_EAB_set(). * \param graph The graph. * \param n The name of the attribute. * \param eid Ids of the edges to set. * \param value The new value of the attribute. * \return Error code. */ #define SETEAB(graph,n,eid,value) (igraph_cattribute_EAB_set((graph),(n),(eid),(value))) /** * \define SETEAS * Set a string edge attribute * * This is a shorthand for \ref igraph_cattribute_EAS_set(). * \param graph The graph. * \param n The name of the attribute. * \param eid Ids of the edges to set. * \param value The new value of the attribute. * \return Error code. */ #define SETEAS(graph,n,eid,value) (igraph_cattribute_EAS_set((graph),(n),(eid),(value))) /** * \define SETVANV * Set a numeric vertex attribute for all vertices * * This is a shorthand for \ref igraph_cattribute_VAN_setv(). * \param graph The graph. * \param n The name of the attribute. * \param v Vector containing the new values of the attributes. * \return Error code. */ #define SETVANV(graph,n,v) (igraph_cattribute_VAN_setv((graph),(n),(v))) /** * \define SETVABV * Set a boolean vertex attribute for all vertices * * This is a shorthand for \ref igraph_cattribute_VAB_setv(). * \param graph The graph. * \param n The name of the attribute. * \param v Vector containing the new values of the attributes. * \return Error code. */ #define SETVABV(graph,n,v) (igraph_cattribute_VAB_setv((graph),(n),(v))) /** * \define SETVASV * Set a string vertex attribute for all vertices * * This is a shorthand for \ref igraph_cattribute_VAS_setv(). * \param graph The graph. * \param n The name of the attribute. * \param v Vector containing the new values of the attributes. * \return Error code. */ #define SETVASV(graph,n,v) (igraph_cattribute_VAS_setv((graph),(n),(v))) /** * \define SETEANV * Set a numeric edge attribute for all edges * * This is a shorthand for \ref igraph_cattribute_EAN_setv(). * \param graph The graph. * \param n The name of the attribute. * \param v Vector containing the new values of the attributes. */ #define SETEANV(graph,n,v) (igraph_cattribute_EAN_setv((graph),(n),(v))) /** * \define SETEABV * Set a boolean edge attribute for all edges * * This is a shorthand for \ref igraph_cattribute_EAB_setv(). * \param graph The graph. * \param n The name of the attribute. * \param v Vector containing the new values of the attributes. */ #define SETEABV(graph,n,v) (igraph_cattribute_EAB_setv((graph),(n),(v))) /** * \define SETEASV * Set a string edge attribute for all edges * * This is a shorthand for \ref igraph_cattribute_EAS_setv(). * \param graph The graph. * \param n The name of the attribute. * \param v Vector containing the new values of the attributes. */ #define SETEASV(graph,n,v) (igraph_cattribute_EAS_setv((graph),(n),(v))) /** * \define DELGA * Remove a graph attribute. * * A shorthand for \ref igraph_cattribute_remove_g(). * \param graph The graph. * \param n The name of the attribute to remove. */ #define DELGA(graph,n) (igraph_cattribute_remove_g((graph),(n))) /** * \define DELVA * Remove a vertex attribute. * * A shorthand for \ref igraph_cattribute_remove_v(). * \param graph The graph. * \param n The name of the attribute to remove. */ #define DELVA(graph,n) (igraph_cattribute_remove_v((graph),(n))) /** * \define DELEA * Remove an edge attribute. * * A shorthand for \ref igraph_cattribute_remove_e(). * \param graph The graph. * \param n The name of the attribute to remove. */ #define DELEA(graph,n) (igraph_cattribute_remove_e((graph),(n))) /** * \define DELGAS * Remove all graph attributes. * * Calls \ref igraph_cattribute_remove_all(). * \param graph The graph. */ #define DELGAS(graph) (igraph_cattribute_remove_all((graph),1,0,0)) /** * \define DELVAS * Remove all vertex attributes. * * Calls \ref igraph_cattribute_remove_all(). * \param graph The graph. */ #define DELVAS(graph) (igraph_cattribute_remove_all((graph),0,1,0)) /** * \define DELEAS * Remove all edge attributes. * * Calls \ref igraph_cattribute_remove_all(). * \param graph The graph. */ #define DELEAS(graph) (igraph_cattribute_remove_all((graph),0,0,1)) /** * \define DELALL * Remove all attributes. * * All graph, vertex and edges attributes will be removed. * Calls \ref igraph_cattribute_remove_all(). * \param graph The graph. */ #define DELALL(graph) (igraph_cattribute_remove_all((graph),1,1,1)) __END_DECLS #endif leidenbase/src/include/igraph_structural.h0000644000176200001440000001556614447675375020535 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_STRUCTURAL_H #define IGRAPH_STRUCTURAL_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_matrix.h" #include "igraph_datatype.h" #include "igraph_iterators.h" #include "igraph_attributes.h" #include "igraph_sparsemat.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Basic query functions */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_are_connected(const igraph_t *graph, igraph_integer_t v1, igraph_integer_t v2, igraph_bool_t *res); IGRAPH_EXPORT int igraph_count_multiple(const igraph_t *graph, igraph_vector_t *res, igraph_es_t es); IGRAPH_EXPORT int igraph_density(const igraph_t *graph, igraph_real_t *res, igraph_bool_t loops); IGRAPH_EXPORT int igraph_diversity(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_t *res, const igraph_vs_t vs); IGRAPH_EXPORT int igraph_girth(const igraph_t *graph, igraph_integer_t *girth, igraph_vector_t *circle); IGRAPH_EXPORT int igraph_has_loop(const igraph_t *graph, igraph_bool_t *res); IGRAPH_EXPORT int igraph_has_multiple(const igraph_t *graph, igraph_bool_t *res); IGRAPH_EXPORT int igraph_is_loop(const igraph_t *graph, igraph_vector_bool_t *res, igraph_es_t es); IGRAPH_EXPORT int igraph_is_multiple(const igraph_t *graph, igraph_vector_bool_t *res, igraph_es_t es); IGRAPH_EXPORT int igraph_is_mutual(const igraph_t *graph, igraph_vector_bool_t *res, igraph_es_t es); IGRAPH_EXPORT int igraph_is_simple(const igraph_t *graph, igraph_bool_t *res); IGRAPH_EXPORT int igraph_is_tree(const igraph_t *graph, igraph_bool_t *res, igraph_integer_t *root, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_maxdegree(const igraph_t *graph, igraph_integer_t *res, igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT int igraph_reciprocity(const igraph_t *graph, igraph_real_t *res, igraph_bool_t ignore_loops, igraph_reciprocity_t mode); IGRAPH_EXPORT int igraph_strength(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_sort_vertex_ids_by_degree(const igraph_t *graph, igraph_vector_t *outvids, igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops, igraph_order_t order, igraph_bool_t only_indices); /* -------------------------------------------------- */ /* Structural properties */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_minimum_spanning_tree(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_minimum_spanning_tree_unweighted(const igraph_t *graph, igraph_t *mst); IGRAPH_EXPORT int igraph_minimum_spanning_tree_prim(const igraph_t *graph, igraph_t *mst, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_random_spanning_tree(const igraph_t *graph, igraph_vector_t *res, igraph_integer_t vid); IGRAPH_EXPORT int igraph_subcomponent(const igraph_t *graph, igraph_vector_t *res, igraph_real_t vid, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_unfold_tree(const igraph_t *graph, igraph_t *tree, igraph_neimode_t mode, const igraph_vector_t *roots, igraph_vector_t *vertex_index); IGRAPH_EXPORT int igraph_maximum_cardinality_search(const igraph_t *graph, igraph_vector_t *alpha, igraph_vector_t *alpham1); IGRAPH_EXPORT int igraph_is_chordal(const igraph_t *graph, const igraph_vector_t *alpha, const igraph_vector_t *alpham1, igraph_bool_t *chordal, igraph_vector_t *fill_in, igraph_t *newgraph); IGRAPH_EXPORT int igraph_avg_nearest_neighbor_degree(const igraph_t *graph, igraph_vs_t vids, igraph_neimode_t mode, igraph_neimode_t neighbor_degree_mode, igraph_vector_t *knn, igraph_vector_t *knnk, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_feedback_arc_set(const igraph_t *graph, igraph_vector_t *result, const igraph_vector_t *weights, igraph_fas_algorithm_t algo); /* -------------------------------------------------- */ /* Spectral Properties */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_laplacian(const igraph_t *graph, igraph_matrix_t *res, igraph_sparsemat_t *sparseres, igraph_bool_t normalized, const igraph_vector_t *weights); __END_DECLS #endif leidenbase/src/include/igraph_threading.h.in0000644000176200001440000000267714447675375020676 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_THREADING_H #define IGRAPH_THREADING_H #include "igraph_decls.h" __BEGIN_DECLS /** * \define IGRAPH_THREAD_SAFE * * Specifies whether igraph was built in thread-safe mode. * * This macro is defined to 1 if the current build of the igraph library is * built in thread-safe mode, and 0 if it is not. A thread-safe igraph library * attempts to use thread-local data structures instead of global ones, but * note that this is not (and can not) be guaranteed for third-party libraries * that igraph links to. */ #cmakedefine01 IGRAPH_THREAD_SAFE __END_DECLS #endif leidenbase/src/include/igraph_coloring.h0000644000176200001440000000273514447675375020133 0ustar liggesusers/* Heuristic graph coloring algorithms. Copyright (C) 2017 Szabolcs Horvat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_COLORING_H #define IGRAPH_COLORING_H #include "igraph_decls.h" #include "igraph_datatype.h" __BEGIN_DECLS /** * \typedef igraph_coloring_greedy_t * \brief Ordering heuristics for greedy graph coloring. * * Ordering heuristics for \ref igraph_vertex_coloring_greedy(). * * \enumval IGRAPH_COLORING_GREEDY_COLORED_NEIGHBORS Choose vertex with largest number of already colored neighbors. * */ typedef enum { IGRAPH_COLORING_GREEDY_COLORED_NEIGHBORS = 0 } igraph_coloring_greedy_t; IGRAPH_EXPORT int igraph_vertex_coloring_greedy(const igraph_t *graph, igraph_vector_int_t *colors, igraph_coloring_greedy_t heuristic); __END_DECLS #endif /* IGRAPH_COLORING_H */ leidenbase/src/include/igraph_operators.h0000644000176200001440000001100714447675375020325 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_OPERATORS_H #define IGRAPH_OPERATORS_H #include "igraph_decls.h" #include "igraph_attributes.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_datatype.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Graph operators */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_add_edge(igraph_t *graph, igraph_integer_t from, igraph_integer_t to); IGRAPH_EXPORT int igraph_disjoint_union(igraph_t *res, const igraph_t *left, const igraph_t *right); IGRAPH_EXPORT int igraph_disjoint_union_many(igraph_t *res, const igraph_vector_ptr_t *graphs); IGRAPH_EXPORT int igraph_union(igraph_t *res, const igraph_t *left, const igraph_t *right, igraph_vector_t *edge_map1, igraph_vector_t *edge_map2); IGRAPH_EXPORT int igraph_union_many(igraph_t *res, const igraph_vector_ptr_t *graphs, igraph_vector_ptr_t *edgemaps); IGRAPH_EXPORT int igraph_intersection(igraph_t *res, const igraph_t *left, const igraph_t *right, igraph_vector_t *edge_map1, igraph_vector_t *edge_map2); IGRAPH_EXPORT int igraph_intersection_many(igraph_t *res, const igraph_vector_ptr_t *graphs, igraph_vector_ptr_t *edgemaps); IGRAPH_EXPORT int igraph_difference(igraph_t *res, const igraph_t *orig, const igraph_t *sub); IGRAPH_EXPORT int igraph_complementer(igraph_t *res, const igraph_t *graph, igraph_bool_t loops); IGRAPH_EXPORT int igraph_compose(igraph_t *res, const igraph_t *g1, const igraph_t *g2, igraph_vector_t *edge_map1, igraph_vector_t *edge_map2); IGRAPH_EXPORT int igraph_contract_vertices(igraph_t *graph, const igraph_vector_t *mapping, const igraph_attribute_combination_t *vertex_comb); IGRAPH_EXPORT int igraph_permute_vertices(const igraph_t *graph, igraph_t *res, const igraph_vector_t *permutation); IGRAPH_EXPORT int igraph_connect_neighborhood(igraph_t *graph, igraph_integer_t order, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_rewire(igraph_t *graph, igraph_integer_t n, igraph_rewiring_t mode); IGRAPH_EXPORT int igraph_simplify(igraph_t *graph, igraph_bool_t multiple, igraph_bool_t loops, const igraph_attribute_combination_t *edge_comb); IGRAPH_EXPORT int igraph_induced_subgraph_map(const igraph_t *graph, igraph_t *res, const igraph_vs_t vids, igraph_subgraph_implementation_t impl, igraph_vector_t *map, igraph_vector_t *invmap); IGRAPH_EXPORT int igraph_induced_subgraph(const igraph_t *graph, igraph_t *res, const igraph_vs_t vids, igraph_subgraph_implementation_t impl); IGRAPH_EXPORT int igraph_subgraph_edges(const igraph_t *graph, igraph_t *res, const igraph_es_t eids, igraph_bool_t delete_vertices); __END_DECLS #endif leidenbase/src/include/igraph_dqueue_pmt.h0000644000176200001440000000433614447675375020466 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Double ended queue data type. * \ingroup internal */ typedef struct TYPE(igraph_dqueue) { BASE *begin; BASE *end; BASE *stor_begin; BASE *stor_end; } TYPE(igraph_dqueue); IGRAPH_EXPORT int FUNCTION(igraph_dqueue, init) (TYPE(igraph_dqueue)* q, long int size); IGRAPH_EXPORT void FUNCTION(igraph_dqueue, destroy) (TYPE(igraph_dqueue)* q); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_dqueue, empty) (const TYPE(igraph_dqueue)* q); IGRAPH_EXPORT void FUNCTION(igraph_dqueue, clear) (TYPE(igraph_dqueue)* q); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_dqueue, full) (TYPE(igraph_dqueue)* q); IGRAPH_EXPORT long int FUNCTION(igraph_dqueue, size) (const TYPE(igraph_dqueue)* q); IGRAPH_EXPORT BASE FUNCTION(igraph_dqueue, pop) (TYPE(igraph_dqueue)* q); IGRAPH_EXPORT BASE FUNCTION(igraph_dqueue, pop_back)(TYPE(igraph_dqueue)* q); IGRAPH_EXPORT BASE FUNCTION(igraph_dqueue, head) (const TYPE(igraph_dqueue)* q); IGRAPH_EXPORT BASE FUNCTION(igraph_dqueue, back) (const TYPE(igraph_dqueue)* q); IGRAPH_EXPORT int FUNCTION(igraph_dqueue, push) (TYPE(igraph_dqueue)* q, BASE elem); IGRAPH_EXPORT int FUNCTION(igraph_dqueue, print)(const TYPE(igraph_dqueue)* q); IGRAPH_EXPORT int FUNCTION(igraph_dqueue, fprint)(const TYPE(igraph_dqueue)* q, FILE *file); IGRAPH_EXPORT BASE FUNCTION(igraph_dqueue, e)(const TYPE(igraph_dqueue) *q, long int idx); leidenbase/src/include/igraph_cocitation.h0000644000176200001440000000613014447675375020444 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_COCITATION_H #define IGRAPH_COCITATION_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_matrix.h" #include "igraph_datatype.h" #include "igraph_iterators.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Cocitation and other similarity measures */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_cocitation(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids); IGRAPH_EXPORT int igraph_bibcoupling(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids); IGRAPH_EXPORT int igraph_similarity_jaccard(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT int igraph_similarity_jaccard_pairs(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *pairs, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT int igraph_similarity_jaccard_es(const igraph_t *graph, igraph_vector_t *res, const igraph_es_t es, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT int igraph_similarity_dice(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT int igraph_similarity_dice_pairs(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *pairs, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT int igraph_similarity_dice_es(const igraph_t *graph, igraph_vector_t *res, const igraph_es_t es, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT int igraph_similarity_inverse_log_weighted(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids, igraph_neimode_t mode); __END_DECLS #endif leidenbase/src/include/igraph_psumtree.h0000644000176200001440000000350714447675375020161 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_PSUMTREE_H #define IGRAPH_PSUMTREE_H #include "igraph_decls.h" #include "igraph_vector.h" __BEGIN_DECLS typedef struct { igraph_vector_t v; long int size; long int offset; } igraph_psumtree_t; IGRAPH_EXPORT int igraph_psumtree_init(igraph_psumtree_t *t, long int size); IGRAPH_EXPORT void igraph_psumtree_reset(igraph_psumtree_t *t); IGRAPH_EXPORT void igraph_psumtree_destroy(igraph_psumtree_t *t); IGRAPH_EXPORT igraph_real_t igraph_psumtree_get(const igraph_psumtree_t *t, long int idx); IGRAPH_EXPORT long int igraph_psumtree_size(const igraph_psumtree_t *t); IGRAPH_EXPORT int igraph_psumtree_search(const igraph_psumtree_t *t, long int *idx, igraph_real_t elem); IGRAPH_EXPORT int igraph_psumtree_update(igraph_psumtree_t *t, long int idx, igraph_real_t new_value); IGRAPH_EXPORT igraph_real_t igraph_psumtree_sum(const igraph_psumtree_t *t); __END_DECLS #endif leidenbase/src/include/igraph_paths.h0000644000176200001440000002536614447675375017443 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_PATHS_H #define IGRAPH_PATHS_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" #include "igraph_matrix.h" #include "igraph_iterators.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_diameter(const igraph_t *graph, igraph_real_t *res, igraph_integer_t *from, igraph_integer_t *to, igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t unconn); IGRAPH_EXPORT int igraph_diameter_dijkstra(const igraph_t *graph, const igraph_vector_t *weights, igraph_real_t *pres, igraph_integer_t *pfrom, igraph_integer_t *pto, igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t unconn); IGRAPH_EXPORT int igraph_shortest_paths(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_get_shortest_paths(const igraph_t *graph, igraph_vector_ptr_t *vertices, igraph_vector_ptr_t *edges, igraph_integer_t from, const igraph_vs_t to, igraph_neimode_t mode, igraph_vector_long_t *predecessors, igraph_vector_long_t *inbound_edges); IGRAPH_EXPORT int igraph_get_shortest_path(const igraph_t *graph, igraph_vector_t *vertices, igraph_vector_t *edges, igraph_integer_t from, igraph_integer_t to, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_get_all_shortest_paths(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_vector_t *nrgeo, igraph_integer_t from, const igraph_vs_t to, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_shortest_paths_dijkstra(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_shortest_paths_bellman_ford(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_get_shortest_path_bellman_ford(const igraph_t *graph, igraph_vector_t *vertices, igraph_vector_t *edges, igraph_integer_t from, igraph_integer_t to, const igraph_vector_t *weights, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_get_shortest_paths_dijkstra(const igraph_t *graph, igraph_vector_ptr_t *vertices, igraph_vector_ptr_t *edges, igraph_integer_t from, igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode, igraph_vector_long_t *predecessors, igraph_vector_long_t *inbound_edges); IGRAPH_EXPORT int igraph_get_shortest_paths_bellman_ford(const igraph_t *graph, igraph_vector_ptr_t *vertices, igraph_vector_ptr_t *edges, igraph_integer_t from, igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode, igraph_vector_long_t *predecessors, igraph_vector_long_t *inbound_edges); IGRAPH_EXPORT int igraph_get_shortest_path_dijkstra(const igraph_t *graph, igraph_vector_t *vertices, igraph_vector_t *edges, igraph_integer_t from, igraph_integer_t to, const igraph_vector_t *weights, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_get_all_shortest_paths_dijkstra(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_vector_t *nrgeo, igraph_integer_t from, igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_shortest_paths_johnson(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_average_path_length(const igraph_t *graph, igraph_real_t *res, igraph_real_t *unconn_pairs, igraph_bool_t directed, igraph_bool_t unconn); IGRAPH_EXPORT int igraph_average_path_length_dijkstra(const igraph_t *graph, igraph_real_t *res, igraph_real_t *unconn_pairs, const igraph_vector_t *weights, igraph_bool_t directed, igraph_bool_t unconn); IGRAPH_EXPORT int igraph_path_length_hist(const igraph_t *graph, igraph_vector_t *res, igraph_real_t *unconnected, igraph_bool_t directed); IGRAPH_EXPORT int igraph_global_efficiency(const igraph_t *graph, igraph_real_t *res, const igraph_vector_t *weights, igraph_bool_t directed); IGRAPH_EXPORT int igraph_local_efficiency(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, const igraph_vector_t *weights, igraph_bool_t directed, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_average_local_efficiency(const igraph_t *graph, igraph_real_t *res, const igraph_vector_t *weights, igraph_bool_t directed, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_eccentricity(const igraph_t *graph, igraph_vector_t *res, igraph_vs_t vids, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_radius(const igraph_t *graph, igraph_real_t *radius, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_get_all_simple_paths(const igraph_t *graph, igraph_vector_int_t *res, igraph_integer_t from, const igraph_vs_t to, igraph_integer_t cutoff, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_random_walk(const igraph_t *graph, igraph_vector_t *walk, igraph_integer_t start, igraph_neimode_t mode, igraph_integer_t steps, igraph_random_walk_stuck_t stuck); IGRAPH_EXPORT int igraph_random_edge_walk(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_t *edgewalk, igraph_integer_t start, igraph_neimode_t mode, igraph_integer_t steps, igraph_random_walk_stuck_t stuck); __END_DECLS #endif leidenbase/src/include/igraph_progress.h0000644000176200001440000001541614447675375020163 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_PROGRESS_H #define IGRAPH_PROGRESS_H #include "igraph_decls.h" #include "igraph_types.h" __BEGIN_DECLS /** * \section about_progress_handlers About progress handlers * * It is often useful to report the progress of some long * calculation, to allow the user to follow the computation and * guess the total running time. A couple of igraph functions * support this at the time of writing, hopefully more will support it * in the future. * * * * To see the progress of a computation, the user has to install a * progress handler, as there is none installed by default. * If an igraph function supports progress reporting, then it * calls the installed progress handler periodically, and passes a * percentage value to it, the percentage of computation already * performed. To install a progress handler, you need to call * \ref igraph_set_progress_handler(). Currently there is a single * pre-defined progress handler, called \ref * igraph_progress_handler_stderr(). * */ /** * \section writing_progress_handlers Writing progress handlers * * * To write a new progress handler, one needs to create a function of * type \ref igraph_progress_handler_t. The new progress handler * can then be installed with the \ref igraph_set_progress_handler() * function. * * * * One can assume that the first progress handler call from a * calculation will be call with zero as the \p percentage argument, * and the last call from a function will have 100 as the \p * percentage argument. Note, however, that if an error happens in the * middle of a computation, then the 100 percent call might be * omitted. * */ /** * \section igraph_functions_with_progress Writing igraph functions with progress reporting * * * If you want to write a function that uses igraph and supports * progress reporting, you need to include \ref igraph_progress() * calls in your function, usually via the \ref IGRAPH_PROGRESS() * macro. * * * * It is good practice to always include a call to \ref * igraph_progress() with a zero \p percentage argument, before the * computation; and another call with 100 \p percentage value * after the computation is completed. * * * * It is also good practice \em not to call \ref igraph_progress() too * often, as this would slow down the computation. It might not be * worth to support progress reporting in functions with linear or * log-linear time complexity, as these are fast, even with a large * amount of data. For functions with quadratic or higher time * complexity make sure that the time complexity of the progress * reporting is constant or at least linear. In practice this means * having at most O(n) progress checks and at most 100 * \ref igraph_progress() calls. * */ /** * \section progress_and_threads Multi-threaded programs * * * In multi-threaded programs, each thread has its own progress * handler, if thread-local storage is supported and igraph is * thread-safe. See the \ref IGRAPH_THREAD_SAFE macro for checking * whether an igraph build is thread-safe. * */ /* -------------------------------------------------- */ /* Progress handlers */ /* -------------------------------------------------- */ /** * \typedef igraph_progress_handler_t * \brief Type of progress handler functions * * This is the type of the igraph progress handler functions. * There is currently one such predefined function, * \ref igraph_progress_handler_stderr(), but the user can * write and set up more sophisticated ones. * \param message A string describing the function or algorithm * that is reporting the progress. Current igraph functions * always use the name \p message argument if reporting from the * same function. * \param percent Numeric, the percentage that was completed by the * algorithm or function. * \param data User-defined data. Current igraph functions that * report progress pass a null pointer here. Users can * write their own progress handlers and functions with progress * reporting, and then pass some meaningfull context here. * \return If the return value of the progress handler is not * \c IGRAPH_SUCCESS, then \ref igraph_progress() returns the * error code \c IGRAPH_INTERRUPTED. The \ref IGRAPH_PROGRESS() * macro frees all memory and finishes the igraph function with * error code \c IGRAPH_INTERRUPTED in this case. */ typedef int igraph_progress_handler_t(const char *message, igraph_real_t percent, void *data); IGRAPH_EXPORT extern igraph_progress_handler_t igraph_progress_handler_stderr; IGRAPH_EXPORT igraph_progress_handler_t * igraph_set_progress_handler(igraph_progress_handler_t new_handler); IGRAPH_EXPORT int igraph_progress(const char *message, igraph_real_t percent, void *data); IGRAPH_EXPORT int igraph_progressf(const char *message, igraph_real_t percent, void *data, ...); /** * \define IGRAPH_PROGRESS * \brief Report progress. * * The standard way to report progress from an igraph function * \param message A string, a textual message that references the * calculation under progress. * \param percent Numeric scalar, the percentage that is complete. * \param data User-defined data, this can be used in user-defined * progress handler functions, from user-written igraph functions. * \return If the progress handler returns with \c IGRAPH_INTERRUPTED, * then this macro frees up the igraph allocated memory for * temporary data and returns to the caller with \c * IGRAPH_INTERRUPTED. */ #define IGRAPH_PROGRESS(message, percent, data) \ do { \ if (igraph_progress((message), (percent), (data)) != IGRAPH_SUCCESS) { \ IGRAPH_FINALLY_FREE(); \ return IGRAPH_INTERRUPTED; \ } \ } while (0) __END_DECLS #endif leidenbase/src/include/igraph_export.h0000644000176200001440000000050214447675376017627 0ustar liggesusers #ifndef IGRAPH_EXPORT_H #define IGRAPH_EXPORT_H #define IGRAPH_EXPORT #define IGRAPH_NO_EXPORT #define IGRAPH_DEPRECATED __attribute__ ((__deprecated__)) #define IGRAPH_DEPRECATED_EXPORT IGRAPH_EXPORT IGRAPH_DEPRECATED #define IGRAPH_DEPRECATED_NO_EXPORT IGRAPH_NO_EXPORT IGRAPH_DEPRECATED #endif /* IGRAPH_EXPORT_H */ leidenbase/src/include/igraph_cohesive_blocks.h0000644000176200001440000000262414447675375021456 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_COHESIVE_BLOCKS_H #define IGRAPH_COHESIVE_BLOCKS_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_cohesive_blocks(const igraph_t *graph, igraph_vector_ptr_t *blocks, igraph_vector_t *cohesion, igraph_vector_t *parent, igraph_t *block_tree); __END_DECLS #endif leidenbase/src/include/igraph_eigen.h0000644000176200001440000001144514447675375017404 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_EIGEN_H #define IGRAPH_EIGEN_H #include "igraph_decls.h" #include "igraph_arpack.h" #include "igraph_lapack.h" #include "igraph_sparsemat.h" __BEGIN_DECLS typedef enum { IGRAPH_EIGEN_AUTO = 0, IGRAPH_EIGEN_LAPACK, IGRAPH_EIGEN_ARPACK, IGRAPH_EIGEN_COMP_AUTO, IGRAPH_EIGEN_COMP_LAPACK, IGRAPH_EIGEN_COMP_ARPACK } igraph_eigen_algorithm_t; typedef enum { IGRAPH_EIGEN_LM = 0, IGRAPH_EIGEN_SM, /* 1 */ IGRAPH_EIGEN_LA, /* 2 */ IGRAPH_EIGEN_SA, /* 3 */ IGRAPH_EIGEN_BE, /* 4 */ IGRAPH_EIGEN_LR, /* 5 */ IGRAPH_EIGEN_SR, /* 6 */ IGRAPH_EIGEN_LI, /* 7 */ IGRAPH_EIGEN_SI, /* 8 */ IGRAPH_EIGEN_ALL, /* 9 */ IGRAPH_EIGEN_INTERVAL, /* 10 */ IGRAPH_EIGEN_SELECT } /* 11 */ igraph_eigen_which_position_t; typedef struct igraph_eigen_which_t { igraph_eigen_which_position_t pos; int howmany; int il, iu; igraph_real_t vl, vu; int vestimate; igraph_lapack_dgeevx_balance_t balance; } igraph_eigen_which_t; IGRAPH_EXPORT int igraph_eigen_matrix_symmetric(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n, void *extra, igraph_eigen_algorithm_t algorithm, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors); IGRAPH_EXPORT int igraph_eigen_matrix(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n, void *extra, igraph_eigen_algorithm_t algorithm, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors); IGRAPH_EXPORT int igraph_eigen_adjacency(const igraph_t *graph, igraph_eigen_algorithm_t algorithm, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_complex_t *cmplxvalues, igraph_matrix_complex_t *cmplxvectors); IGRAPH_EXPORT int igraph_eigen_laplacian(const igraph_t *graph, igraph_eigen_algorithm_t algorithm, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_complex_t *cmplxvalues, igraph_matrix_complex_t *cmplxvectors); __END_DECLS #endif leidenbase/src/include/igraph_blas.h0000644000176200001440000000530714447675375017236 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_BLAS_H #define IGRAPH_BLAS_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_matrix.h" __BEGIN_DECLS /** * \section about_blas BLAS interface in igraph * * * BLAS is a highly optimized library for basic linear algebra operations * such as vector-vector, matrix-vector and matrix-matrix product. * Please see http://www.netlib.org/blas/ for details and a reference * implementation in Fortran. igraph contains some wrapper functions * that can be used to call BLAS routines in a somewhat more * user-friendly way. Not all BLAS routines are included in igraph, * and even those which are included might not have wrappers; * the extension of the set of wrapped functions will probably be driven * by igraph's internal requirements. The wrapper functions usually * substitute double-precision floating point arrays used by BLAS with * \type igraph_vector_t and \type igraph_matrix_t instances and also * remove those parameters (such as the number of rows/columns) that * can be inferred from the passed arguments directly. * */ IGRAPH_EXPORT void igraph_blas_dgemv(igraph_bool_t transpose, igraph_real_t alpha, const igraph_matrix_t* a, const igraph_vector_t* x, igraph_real_t beta, igraph_vector_t* y); IGRAPH_EXPORT void igraph_blas_dgemv_array(igraph_bool_t transpose, igraph_real_t alpha, const igraph_matrix_t* a, const igraph_real_t* x, igraph_real_t beta, igraph_real_t* y); IGRAPH_EXPORT igraph_real_t igraph_blas_dnrm2(const igraph_vector_t *v); IGRAPH_EXPORT int igraph_blas_ddot(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_real_t *res); __END_DECLS #endif leidenbase/src/include/igraph_datatype.h0000644000176200001440000000627314447675375020133 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_DATATYPE_H #define IGRAPH_DATATYPE_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_vector.h" __BEGIN_DECLS /** * \ingroup internal * \struct igraph_t * \brief The internal data structure for storing graphs. * * It is simple and efficient. It has the following members: * - n The number of vertices, redundant. * - directed Whether the graph is directed. * - from The first column of the edge list. * - to The second column of the edge list. * - oi The index of the edge list by the first column. Thus * the first edge according to this order goes from * \c from[oi[0]] to \c to[oi[0]]. The length of * this vector is the same as the number of edges in the graph. * - ii The index of the edge list by the second column. * The length of this vector is the same as the number of edges. * - os Contains pointers to the edgelist (\c from * and \c to for every vertex. The first edge \em from * vertex \c v is edge no. \c from[oi[os[v]]] if * \c os[v]is This is basically the same as os, but this time * for the incoming edges. * * For undirected graphs, the same edge list is stored, i.e. an * undirected edge is stored only once. Currently, undirected edges * are canonicalized so that the index of the 'from' vertex is not greater * than the index of the 'to' vertex. Thus, if v1 <= v2, only the edge (v1, v2) * needs to be searched for, not (v2, v1), to determine if v1 and v2 are connected. * However, this fact is NOT guaranteed by the documented public API, * and should not be relied upon by the implementation of any functions, * except those belonging to the minimal API in type_indexededgelist.c. * * The storage requirements for a graph with \c |V| vertices * and \c |E| edges is \c O(|E|+|V|). */ typedef struct igraph_s { igraph_integer_t n; igraph_bool_t directed; igraph_vector_t from; igraph_vector_t to; igraph_vector_t oi; igraph_vector_t ii; igraph_vector_t os; igraph_vector_t is; void *attr; } igraph_t; __END_DECLS #endif leidenbase/src/include/igraph_strvector.h0000644000176200001440000000777714447675375020365 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_STRVECTOR_H #define IGRAPH_STRVECTOR_H #include "igraph_decls.h" #include "igraph_vector.h" __BEGIN_DECLS /** * Vector of strings * \ingroup internal */ typedef struct s_igraph_strvector { char **data; long int len; } igraph_strvector_t; /** * \define STR * Indexing string vectors * * This is a macro which allows to query the elements of a string vector in * simpler way than \ref igraph_strvector_get(). Note this macro cannot be * used to set an element, for that use \ref igraph_strvector_set(). * \param sv The string vector * \param i The the index of the element. * \return The element at position \p i. * * Time complexity: O(1). */ #define STR(sv,i) ((const char *)((sv).data[(i)])) #define IGRAPH_STRVECTOR_NULL { 0,0 } #define IGRAPH_STRVECTOR_INIT_FINALLY(v, size) \ do { IGRAPH_CHECK(igraph_strvector_init(v, size)); \ IGRAPH_FINALLY( igraph_strvector_destroy, v); } while (0) IGRAPH_EXPORT int igraph_strvector_init(igraph_strvector_t *sv, long int len); IGRAPH_EXPORT void igraph_strvector_destroy(igraph_strvector_t *sv); IGRAPH_EXPORT long int igraph_strvector_size(const igraph_strvector_t *sv); IGRAPH_EXPORT void igraph_strvector_get(const igraph_strvector_t *sv, long int idx, char **value); IGRAPH_EXPORT int igraph_strvector_set(igraph_strvector_t *sv, long int idx, const char *value); IGRAPH_EXPORT int igraph_strvector_set2(igraph_strvector_t *sv, long int idx, const char *value, int len); IGRAPH_EXPORT void igraph_strvector_clear(igraph_strvector_t *sv); IGRAPH_EXPORT void igraph_strvector_remove_section(igraph_strvector_t *v, long int from, long int to); IGRAPH_EXPORT void igraph_strvector_remove(igraph_strvector_t *v, long int elem); IGRAPH_EXPORT void igraph_strvector_move_interval(igraph_strvector_t *v, long int begin, long int end, long int to); IGRAPH_EXPORT int igraph_strvector_copy(igraph_strvector_t *to, const igraph_strvector_t *from); IGRAPH_EXPORT int igraph_strvector_append(igraph_strvector_t *to, const igraph_strvector_t *from); IGRAPH_EXPORT int igraph_strvector_resize(igraph_strvector_t* v, long int newsize); IGRAPH_EXPORT int igraph_strvector_add(igraph_strvector_t *v, const char *value); IGRAPH_EXPORT void igraph_strvector_permdelete(igraph_strvector_t *v, const igraph_vector_t *index, long int nremove); IGRAPH_EXPORT void igraph_strvector_remove_negidx(igraph_strvector_t *v, const igraph_vector_t *neg, long int nremove); IGRAPH_EXPORT int igraph_strvector_print(const igraph_strvector_t *v, FILE *file, const char *sep); IGRAPH_EXPORT int igraph_strvector_index(const igraph_strvector_t *v, igraph_strvector_t *newv, const igraph_vector_t *idx); __END_DECLS #endif leidenbase/src/include/igraph_microscopic_update.h0000644000176200001440000000550314447675375022167 0ustar liggesusers/* -*- mode: C -*- */ /* Microscopic update rules for dealing with agent-level strategy revision. Copyright (C) 2011 Minh Van Nguyen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_MICROSCOPIC_UPDATE_H #define IGRAPH_MICROSCOPIC_UPDATE_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_datatype.h" #include "igraph_iterators.h" #include "igraph_types.h" #include "igraph_vector.h" __BEGIN_DECLS IGRAPH_EXPORT int igraph_deterministic_optimal_imitation(const igraph_t *graph, igraph_integer_t vid, igraph_optimal_t optimality, const igraph_vector_t *quantities, igraph_vector_t *strategies, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_moran_process(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_t *quantities, igraph_vector_t *strategies, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_roulette_wheel_imitation(const igraph_t *graph, igraph_integer_t vid, igraph_bool_t islocal, const igraph_vector_t *quantities, igraph_vector_t *strategies, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_stochastic_imitation(const igraph_t *graph, igraph_integer_t vid, igraph_imitate_algorithm_t algo, const igraph_vector_t *quantities, igraph_vector_t *strategies, igraph_neimode_t mode); __END_DECLS #endif leidenbase/src/include/igraph_version.h0000644000176200001440000000266714447675376020011 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_VERSION_H #define IGRAPH_VERSION_H #include "igraph_decls.h" __BEGIN_DECLS #define IGRAPH_VERSION "@PACKAGE_VERSION@" #define IGRAPH_VERSION_MAJOR @PACKAGE_VERSION_MAJOR@ #define IGRAPH_VERSION_MINOR @PACKAGE_VERSION_MINOR@ #define IGRAPH_VERSION_PATCH @PACKAGE_VERSION_PATCH@ #define IGRAPH_VERSION_PRERELEASE "@PACKAGE_VERSION_PRERELEASE@" IGRAPH_EXPORT int igraph_version(const char **version_string, int *major, int *minor, int *subminor); __END_DECLS #endif leidenbase/src/include/igraph_community.h0000644000176200001440000003361214447675375020341 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_COMMUNITY_H #define IGRAPH_COMMUNITY_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_datatype.h" #include "igraph_types.h" #include "igraph_arpack.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* K-Cores */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_coreness(const igraph_t *graph, igraph_vector_t *cores, igraph_neimode_t mode); /* -------------------------------------------------- */ /* Community Structure */ /* -------------------------------------------------- */ /* TODO: cut.community */ /* TODO: edge.type.matrix */ /* TODO: */ IGRAPH_EXPORT int igraph_community_optimal_modularity(const igraph_t *graph, igraph_real_t *modularity, igraph_vector_t *membership, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_community_spinglass(const igraph_t *graph, const igraph_vector_t *weights, igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t spins, igraph_bool_t parupdate, igraph_real_t starttemp, igraph_real_t stoptemp, igraph_real_t coolfact, igraph_spincomm_update_t update_rule, igraph_real_t gamma, /* the rest is for the NegSpin implementation */ igraph_spinglass_implementation_t implementation, /* igraph_matrix_t *adhesion, */ /* igraph_matrix_t *normalised_adhesion, */ /* igraph_real_t *polarization, */ igraph_real_t lambda); IGRAPH_EXPORT int igraph_community_spinglass_single(const igraph_t *graph, const igraph_vector_t *weights, igraph_integer_t vertex, igraph_vector_t *community, igraph_real_t *cohesion, igraph_real_t *adhesion, igraph_integer_t *inner_links, igraph_integer_t *outer_links, igraph_integer_t spins, igraph_spincomm_update_t update_rule, igraph_real_t gamma); IGRAPH_EXPORT int igraph_community_walktrap(const igraph_t *graph, const igraph_vector_t *weights, int steps, igraph_matrix_t *merges, igraph_vector_t *modularity, igraph_vector_t *membership); IGRAPH_EXPORT int igraph_community_infomap(const igraph_t * graph, const igraph_vector_t *e_weights, const igraph_vector_t *v_weights, int nb_trials, igraph_vector_t *membership, igraph_real_t *codelength); IGRAPH_EXPORT int igraph_community_edge_betweenness(const igraph_t *graph, igraph_vector_t *result, igraph_vector_t *edge_betweenness, igraph_matrix_t *merges, igraph_vector_t *bridges, igraph_vector_t *modularity, igraph_vector_t *membership, igraph_bool_t directed, const igraph_vector_t *weights); IGRAPH_EXPORT int igraph_community_eb_get_merges(const igraph_t *graph, const igraph_bool_t directed, const igraph_vector_t *edges, const igraph_vector_t *weights, igraph_matrix_t *merges, igraph_vector_t *bridges, igraph_vector_t *modularity, igraph_vector_t *membership); IGRAPH_EXPORT int igraph_community_fastgreedy(const igraph_t *graph, const igraph_vector_t *weights, igraph_matrix_t *merges, igraph_vector_t *modularity, igraph_vector_t *membership); IGRAPH_EXPORT int igraph_community_to_membership(const igraph_matrix_t *merges, igraph_integer_t nodes, igraph_integer_t steps, igraph_vector_t *membership, igraph_vector_t *csize); IGRAPH_EXPORT int igraph_le_community_to_membership(const igraph_matrix_t *merges, igraph_integer_t steps, igraph_vector_t *membership, igraph_vector_t *csize); IGRAPH_EXPORT int igraph_modularity(const igraph_t *graph, const igraph_vector_t *membership, const igraph_vector_t *weights, const igraph_real_t resolution, const igraph_bool_t directed, igraph_real_t *modularity); IGRAPH_EXPORT int igraph_modularity_matrix(const igraph_t *graph, const igraph_vector_t *weights, const igraph_real_t resolution, igraph_matrix_t *modmat, igraph_bool_t directed); IGRAPH_EXPORT int igraph_reindex_membership(igraph_vector_t *membership, igraph_vector_t *new_to_old, igraph_integer_t *nb_clusters); typedef enum { IGRAPH_LEVC_HIST_SPLIT = 1, IGRAPH_LEVC_HIST_FAILED, IGRAPH_LEVC_HIST_START_FULL, IGRAPH_LEVC_HIST_START_GIVEN } igraph_leading_eigenvector_community_history_t; /** * \typedef igraph_community_leading_eigenvector_callback_t * Callback for the leading eigenvector community finding method. * * The leading eigenvector community finding implementation in igraph * is able to call a callback function, after each eigenvalue * calculation. This callback function must be of \c * igraph_community_leading_eigenvector_callback_t type. * The following arguments are passed to the callback: * \param membership The actual membership vector, before recording * the potential change implied by the newly found eigenvalue. * \param comm The id of the community that the algorithm tried to * split in the last iteration. The community ids are indexed from * zero here! * \param eigenvalue The eigenvalue the algorithm has just found. * \param eigenvector The eigenvector corresponding to the eigenvalue * the algorithm just found. * \param arpack_multiplier A function that was passed to \ref * igraph_arpack_rssolve() to solve the last eigenproblem. * \param arpack_extra The extra argument that was passed to the * ARPACK solver. * \param extra Extra argument that as passed to \ref * igraph_community_leading_eigenvector(). * * \sa \ref igraph_community_leading_eigenvector(), \ref * igraph_arpack_function_t, \ref igraph_arpack_rssolve(). */ typedef int igraph_community_leading_eigenvector_callback_t( const igraph_vector_t *membership, long int comm, igraph_real_t eigenvalue, const igraph_vector_t *eigenvector, igraph_arpack_function_t *arpack_multiplier, void *arpack_extra, void *extra); IGRAPH_EXPORT int igraph_community_leading_eigenvector(const igraph_t *graph, const igraph_vector_t *weights, igraph_matrix_t *merges, igraph_vector_t *membership, igraph_integer_t steps, igraph_arpack_options_t *options, igraph_real_t *modularity, igraph_bool_t start, igraph_vector_t *eigenvalues, igraph_vector_ptr_t *eigenvectors, igraph_vector_t *history, igraph_community_leading_eigenvector_callback_t *callback, void *callback_extra); IGRAPH_EXPORT int igraph_community_fluid_communities(const igraph_t *graph, igraph_integer_t no_of_communities, igraph_vector_t *membership, igraph_real_t *modularity); IGRAPH_EXPORT int igraph_community_label_propagation(const igraph_t *graph, igraph_vector_t *membership, const igraph_vector_t *weights, const igraph_vector_t *initial, const igraph_vector_bool_t *fixed, igraph_real_t *modularity); IGRAPH_EXPORT int igraph_community_multilevel(const igraph_t *graph, const igraph_vector_t *weights, const igraph_real_t resolution, igraph_vector_t *membership, igraph_matrix_t *memberships, igraph_vector_t *modularity); IGRAPH_EXPORT int igraph_community_leiden(const igraph_t *graph, const igraph_vector_t *edge_weights, const igraph_vector_t *node_weights, const igraph_real_t resolution_parameter, const igraph_real_t beta, const igraph_bool_t start, igraph_vector_t *membership, igraph_integer_t *nb_clusters, igraph_real_t *quality); /* -------------------------------------------------- */ /* Community Structure Comparison */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_compare_communities(const igraph_vector_t *comm1, const igraph_vector_t *comm2, igraph_real_t* result, igraph_community_comparison_t method); IGRAPH_EXPORT int igraph_split_join_distance(const igraph_vector_t *comm1, const igraph_vector_t *comm2, igraph_integer_t* distance12, igraph_integer_t* distance21); __END_DECLS #endif leidenbase/src/include/igraph_conversion.h0000644000176200001440000000516214447675375020501 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CONVERSION_H #define IGRAPH_CONVERSION_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_datatype.h" #include "igraph_spmatrix.h" #include "igraph_matrix.h" #include "igraph_sparsemat.h" #include "igraph_attributes.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Conversion */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_get_adjacency(const igraph_t *graph, igraph_matrix_t *res, igraph_get_adjacency_t type, igraph_bool_t eids); IGRAPH_EXPORT int igraph_get_adjacency_sparse(const igraph_t *graph, igraph_spmatrix_t *res, igraph_get_adjacency_t type); IGRAPH_EXPORT int igraph_get_stochastic(const igraph_t *graph, igraph_matrix_t *matrix, igraph_bool_t column_wise); IGRAPH_EXPORT int igraph_get_stochastic_sparsemat(const igraph_t *graph, igraph_sparsemat_t *sparsemat, igraph_bool_t column_wise); IGRAPH_EXPORT int igraph_get_edgelist(const igraph_t *graph, igraph_vector_t *res, igraph_bool_t bycol); IGRAPH_EXPORT int igraph_to_directed(igraph_t *graph, igraph_to_directed_t flags); IGRAPH_EXPORT int igraph_to_undirected(igraph_t *graph, igraph_to_undirected_t mode, const igraph_attribute_combination_t *edge_comb); IGRAPH_EXPORT int igraph_to_prufer(const igraph_t *graph, igraph_vector_int_t *prufer); __END_DECLS #endif leidenbase/src/include/igraph_visitor.h0000644000176200001440000001243414447675375020013 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_VISITOR_H #define IGRAPH_VISITOR_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_datatype.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Visitor-like functions */ /* -------------------------------------------------- */ /** * \typedef igraph_bfshandler_t * Callback type for BFS function * * \ref igraph_bfs() is able to call a callback function, whenever a * new vertex is found, while doing the breadth-first search. This * callback function must be of type \c igraph_bfshandler_t. It has * the following arguments: * \param graph The graph that that algorithm is working on. Of course * this must not be modified. * \param vid The id of the vertex just found by the breadth-first * search. * \param pred The id of the previous vertex visited. It is -1 if * there is no previous vertex, because the current vertex is the root * is a search tree. * \param succ The id of the next vertex that will be visited. It is * -1 if there is no next vertex, because the current vertex is the * last one in a search tree. * \param rank The rank of the current vertex, it starts with zero. * \param dist The distance (number of hops) of the current vertex * from the root of the current search tree. * \param extra The extra argument that was passed to \ref * igraph_bfs(). * \return A logical value, if TRUE (=non-zero), that is interpreted * as a request to stop the BFS and return to the caller. If a BFS * is terminated like this, then all elements of the result vectors * that were not yet calculated at the point of the termination * contain NaN. * * \sa \ref igraph_bfs() */ typedef igraph_bool_t igraph_bfshandler_t(const igraph_t *graph, igraph_integer_t vid, igraph_integer_t pred, igraph_integer_t succ, igraph_integer_t rank, igraph_integer_t dist, void *extra); IGRAPH_EXPORT int igraph_bfs(const igraph_t *graph, igraph_integer_t root, const igraph_vector_t *roots, igraph_neimode_t mode, igraph_bool_t unreachable, const igraph_vector_t *restricted, igraph_vector_t *order, igraph_vector_t *rank, igraph_vector_t *father, igraph_vector_t *pred, igraph_vector_t *succ, igraph_vector_t *dist, igraph_bfshandler_t *callback, void *extra); IGRAPH_EXPORT int igraph_bfs_simple(igraph_t *graph, igraph_integer_t vid, igraph_neimode_t mode, igraph_vector_t *vids, igraph_vector_t *layers, igraph_vector_t *parents); /** * \function igraph_dfshandler_t * Callback type for the DFS function * * \ref igraph_dfs() is able to call a callback function, whenever a * new vertex is discovered, and/or whenever a subtree is * completed. These callbacks must be of type \c * igraph_dfshandler_t. They have the following arguments: * \param graph The graph that that algorithm is working on. Of course * this must not be modified. * \param vid The id of the vertex just found by the depth-first * search. * \param dist The distance (number of hops) of the current vertex * from the root of the current search tree. * \param extra The extra argument that was passed to \ref * igraph_dfs(). * \return A logical value, if TRUE (=non-zero), that is interpreted * as a request to stop the DFS and return to the caller. If a DFS * is terminated like this, then all elements of the result vectors * that were not yet calculated at the point of the termination * contain NaN. * * \sa \ref igraph_dfs() */ typedef igraph_bool_t igraph_dfshandler_t(const igraph_t *graph, igraph_integer_t vid, igraph_integer_t dist, void *extra); IGRAPH_EXPORT int igraph_dfs(const igraph_t *graph, igraph_integer_t root, igraph_neimode_t mode, igraph_bool_t unreachable, igraph_vector_t *order, igraph_vector_t *order_out, igraph_vector_t *father, igraph_vector_t *dist, igraph_dfshandler_t *in_callback, igraph_dfshandler_t *out_callback, void *extra); __END_DECLS #endif leidenbase/src/include/igraph_error.h0000644000176200001440000011277514447675375017456 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_ERROR_H #define IGRAPH_ERROR_H #include "igraph_decls.h" #include __BEGIN_DECLS /* This file contains the igraph error handling. * Most bits are taken literally from the GSL library (with the GSL_ * prefix renamed to IGRAPH_), as I couldn't find a better way to do * them. */ /* IGRAPH_NORETURN indicates to the compiler that a function does not return. * There are standard facilities for this, namely _Noreturn in C11 and [[noreturn]] in C++11. * However, since igraph is currently compiled with older standards, and since * the standard 'noreturn' specification would need to be diferent between C and C++, * we do not use these facilities. */ #if defined(__GNUC__) /* Compilers that support the GNU C syntax. Use __noreturn__ instead of 'noreturn' as the latter is a macro in C11. */ #define IGRAPH_NORETURN __attribute__((__noreturn__)) #elif defined(_MSC_VER) /* Compilers that support the MSVC syntax. */ #define IGRAPH_NORETURN __declspec(noreturn) #else #define IGRAPH_NORETURN #endif /** * \section error_handling_basics Error handling basics * * \a igraph functions can run into various problems preventing them * from normal operation. The user might have supplied invalid arguments, * e.g. a non-square matrix when a square-matrix was expected, or the program * has run out of memory while some more memory allocation is required, etc. * * * By default \a igraph aborts the program when it runs into an * error. While this behavior might be good enough for smaller programs, * it is without doubt avoidable in larger projects. Please read further * if your project requires more sophisticated error handling. You can * safely skip the rest of this chapter otherwise. * */ /** * \section error_handlers Error handlers * * * If \a igraph runs into an error - an invalid argument was supplied * to a function, or we've ran out of memory - the control is * transferred to the \emb error handler \eme function. * * The default error handler is \ref igraph_error_handler_abort which * prints an error message and aborts the program. * * * The \ref igraph_set_error_handler() function can be used to set a new * error handler function of type \ref igraph_error_handler_t; see the * documentation of this type for details. * * * There are two other predefined error handler functions, * \ref igraph_error_handler_ignore and \ref igraph_error_handler_printignore. * These deallocate the temporarily allocated memory (more about this * later) and return with the error code. The latter also prints an * error message. If you use these error handlers you need to take * care about possible errors yourself by checking the return value of * (almost) every non-void \a igraph function. * * Independently of the error handler installed, all functions in the * library do their best to leave their arguments * \em semantically unchanged if an error * happens. By semantically we mean that the implementation of an * object supplied as an argument might change, but its * \quote meaning \endquote in most cases does not. The rare occasions * when this rule is violated are documented in this manual. * */ /** * \section error_codes Error codes * * Every \a igraph function which can fail return a * single integer error code. Some functions are very simple and * cannot run into any error, these may return other types, or * \type void as well. The error codes are defined by the * \ref igraph_error_type_t enumeration. * */ /** * \section writing_error_handlers Writing error handlers * * * The contents of the rest of this chapter might be useful only * for those who want to create an interface to \a igraph from another * language. Most readers can safely skip to the next chapter. * * * * You can write and install error handlers simply by defining a * function of type \ref igraph_error_handler_t and calling * \ref igraph_set_error_handler(). This feature is useful for interface * writers, as \a igraph will have the chance to * signal errors the appropriate way, e.g. the R interface defines an * error handler which calls the error() * function, as required by R, while the Python interface has an error * handler which raises an exception according to the Python way. * * * If you want to write an error handler, your error handler should * call \ref IGRAPH_FINALLY_FREE() to deallocate all temporary memory to * prevent memory leaks. Note that this may invalidate the error message * buffer \p reason passed to the error handler. Do not access it after * having called \ref IGRAPH_FINALLY_FREE(). * */ /** * \section error_handling_internals Error handling internals * * * If an error happens, the functions in the library call the * \ref IGRAPH_ERROR() macro with a textual description of the error and an * \a igraph error code. This macro calls (through the \ref * igraph_error() function) the installed error handler. Another useful * macro is \ref IGRAPH_CHECK(). This checks the return value of its * argument, which is normally a function call, and calls \ref * IGRAPH_ERROR() if it is not \c IGRAPH_SUCCESS. * */ /** * \section deallocating_memory Deallocating memory * * * If a function runs into an error (and the program is not aborted) * the error handler should deallocate all temporary memory. This is * done by storing the address and the destroy function of all temporary * objects in a stack. The \ref IGRAPH_FINALLY function declares an object as * temporary by placing its address in the stack. If an \a igraph function returns * with success it calls \ref IGRAPH_FINALLY_CLEAN() with the * number of objects to remove from the stack. If an error happens * however, the error handler should call \ref IGRAPH_FINALLY_FREE() to * deallocate each object added to the stack. This means that the * temporary objects allocated in the calling function (and etc.) will * be freed as well. * */ /** * \section writing_functions_error_handling Writing \a igraph functions with * proper error handling * * * There are some simple rules to keep in order to have functions * behaving well in erroneous situations. First, check the arguments * of the functions and call \ref IGRAPH_ERROR() if they are invalid. Second, * call \ref IGRAPH_FINALLY on each dynamically allocated object and call * \ref IGRAPH_FINALLY_CLEAN() with the proper argument before returning. Third, use * \ref IGRAPH_CHECK on all \a igraph function calls which can generate errors. * * * The size of the stack used for this bookkeeping is fixed, and * small. If you want to allocate several objects, write a destroy * function which can deallocate all of these. See the * adjlist.c file in the * \a igraph source for an example. * * * For some functions these mechanisms are simply not flexible * enough. These functions should define their own error handlers and * restore the error handler before they return. * */ /** * \section error_handling_threads Error handling and threads * * * It is likely that the \a igraph error handling * method is \em not thread-safe, mainly because of * the static global stack which is used to store the address of the * temporarily allocated objects. This issue might be addressed in a * later version of \a igraph. * */ /** * \typedef igraph_error_handler_t * \brief The type of error handler functions. * * This is the type of the error handler functions. * \param reason Textual description of the error. * \param file The source file in which the error is noticed. * \param line The number of the line in the source file which triggered * the error * \param igraph_errno The \a igraph error code. */ typedef void igraph_error_handler_t (const char *reason, const char *file, int line, int igraph_errno); /** * \var igraph_error_handler_abort * \brief Abort program in case of error. * * The default error handler, prints an error message and aborts the * program. */ IGRAPH_EXPORT igraph_error_handler_t igraph_error_handler_abort; /** * \var igraph_error_handler_ignore * \brief Ignore errors. * * This error handler frees the temporarily allocated memory and returns * with the error code. */ IGRAPH_EXPORT igraph_error_handler_t igraph_error_handler_ignore; /** * \var igraph_error_handler_printignore * \brief Print and ignore errors. * * Frees temporarily allocated memory, prints an error message to the * standard error and returns with the error code. */ IGRAPH_EXPORT igraph_error_handler_t igraph_error_handler_printignore; /** * \function igraph_set_error_handler * \brief Sets a new error handler. * * Installs a new error handler. If called with 0, it installs the * default error handler (which is currently * \ref igraph_error_handler_abort). * \param new_handler The error handler function to install. * \return The old error handler function. This should be saved and * restored if \p new_handler is not needed any * more. */ IGRAPH_EXPORT igraph_error_handler_t* igraph_set_error_handler(igraph_error_handler_t* new_handler); /** * \typedef igraph_error_type_t * \brief Error code type. * These are the possible values returned by \a igraph functions. * Note that these are interesting only if you defined an error handler * with \ref igraph_set_error_handler(). Otherwise the program is aborted * and the function causing the error never returns. * * \enumval IGRAPH_SUCCESS The function successfully completed its task. * \enumval IGRAPH_FAILURE Something went wrong. You'll almost never * meet this error as normally more specific error codes are used. * \enumval IGRAPH_ENOMEM There wasn't enough memory to allocate * on the heap. * \enumval IGRAPH_PARSEERROR A parse error was found in a file. * \enumval IGRAPH_EINVAL A parameter's value is invalid. E.g. negative * number was specified as the number of vertices. * \enumval IGRAPH_EXISTS A graph/vertex/edge attribute is already * installed with the given name. * \enumval IGRAPH_EINVEVECTOR Invalid vector of vertex ids. A vertex id * is either negative or bigger than the number of vertices minus one. * \enumval IGRAPH_EINVVID Invalid vertex id, negative or too big. * \enumval IGRAPH_NONSQUARE A non-square matrix was received while a * square matrix was expected. * \enumval IGRAPH_EINVMODE Invalid mode parameter. * \enumval IGRAPH_EFILE A file operation failed. E.g. a file doesn't exist, * or the user has no rights to open it. * \enumval IGRAPH_UNIMPLEMENTED Attempted to call an unimplemented or * disabled (at compile-time) function. * \enumval IGRAPH_DIVERGED A numeric algorithm failed to converge. * \enumval IGRAPH_ARPACK_PROD Matrix-vector product failed. * \enumval IGRAPH_ARPACK_NPOS N must be positive. * \enumval IGRAPH_ARPACK_NEVNPOS NEV must be positive. * \enumval IGRAPH_ARPACK_NCVSMALL NCV must be bigger. * \enumval IGRAPH_ARPACK_NONPOSI Maximum number of iterations should be positive. * \enumval IGRAPH_ARPACK_WHICHINV Invalid WHICH parameter. * \enumval IGRAPH_ARPACK_BMATINV Invalid BMAT parameter. * \enumval IGRAPH_ARPACK_WORKLSMALL WORKL is too small. * \enumval IGRAPH_ARPACK_TRIDERR LAPACK error in tridiagonal eigenvalue calculation. * \enumval IGRAPH_ARPACK_ZEROSTART Starting vector is zero. * \enumval IGRAPH_ARPACK_MODEINV MODE is invalid. * \enumval IGRAPH_ARPACK_MODEBMAT MODE and BMAT are not compatible. * \enumval IGRAPH_ARPACK_ISHIFT ISHIFT must be 0 or 1. * \enumval IGRAPH_ARPACK_NEVBE NEV and WHICH='BE' are incompatible. * \enumval IGRAPH_ARPACK_NOFACT Could not build an Arnoldi factorization. * \enumval IGRAPH_ARPACK_FAILED No eigenvalues to sufficient accuracy. * \enumval IGRAPH_ARPACK_HOWMNY HOWMNY is invalid. * \enumval IGRAPH_ARPACK_HOWMNYS HOWMNY='S' is not implemented. * \enumval IGRAPH_ARPACK_EVDIFF Different number of converged Ritz values. * \enumval IGRAPH_ARPACK_SHUR Error from calculation of a real Schur form. * \enumval IGRAPH_ARPACK_LAPACK LAPACK (dtrevc) error for calculating eigenvectors. * \enumval IGRAPH_ARPACK_UNKNOWN Unknown ARPACK error. * \enumval IGRAPH_ENEGLOOP Negative loop detected while calculating shortest paths. * \enumval IGRAPH_EINTERNAL Internal error, likely a bug in igraph. * \enumval IGRAPH_EDIVZERO Big integer division by zero. * \enumval IGRAPH_GLP_EBOUND GLPK error (GLP_EBOUND). * \enumval IGRAPH_GLP_EROOT GLPK error (GLP_EROOT). * \enumval IGRAPH_GLP_ENOPFS GLPK error (GLP_ENOPFS). * \enumval IGRAPH_GLP_ENODFS GLPK error (GLP_ENODFS). * \enumval IGRAPH_GLP_EFAIL GLPK error (GLP_EFAIL). * \enumval IGRAPH_GLP_EMIPGAP GLPK error (GLP_EMIPGAP). * \enumval IGRAPH_GLP_ETMLIM GLPK error (GLP_ETMLIM). * \enumval IGRAPH_GLP_ESTOP GLPK error (GLP_ESTOP). * \enumval IGRAPH_EATTRIBUTES Attribute handler error. The user is not * expected to find this; it is signalled if some igraph function is * not using the attribute handler interface properly. * \enumval IGRAPH_EATTRCOMBINE Unimplemented attribute combination * method for the given attribute type. * \enumval IGRAPH_ELAPACK A LAPACK call resulted in an error. * \enumval IGRAPH_EDRL Internal error in the DrL layout generator. * \enumval IGRAPH_EOVERFLOW Integer or double overflow. * \enumval IGRAPH_EGLP Internal GLPK error. * \enumval IGRAPH_CPUTIME CPU time exceeded. * \enumval IGRAPH_EUNDERFLOW Integer or double underflow. * \enumval IGRAPH_ERWSTUCK Random walk got stuck. */ typedef enum { IGRAPH_SUCCESS = 0, IGRAPH_FAILURE = 1, IGRAPH_ENOMEM = 2, IGRAPH_PARSEERROR = 3, IGRAPH_EINVAL = 4, IGRAPH_EXISTS = 5, IGRAPH_EINVEVECTOR = 6, IGRAPH_EINVVID = 7, IGRAPH_NONSQUARE = 8, IGRAPH_EINVMODE = 9, IGRAPH_EFILE = 10, IGRAPH_UNIMPLEMENTED = 12, IGRAPH_INTERRUPTED = 13, IGRAPH_DIVERGED = 14, IGRAPH_ARPACK_PROD = 15, IGRAPH_ARPACK_NPOS = 16, IGRAPH_ARPACK_NEVNPOS = 17, IGRAPH_ARPACK_NCVSMALL = 18, IGRAPH_ARPACK_NONPOSI = 19, IGRAPH_ARPACK_WHICHINV = 20, IGRAPH_ARPACK_BMATINV = 21, IGRAPH_ARPACK_WORKLSMALL = 22, IGRAPH_ARPACK_TRIDERR = 23, IGRAPH_ARPACK_ZEROSTART = 24, IGRAPH_ARPACK_MODEINV = 25, IGRAPH_ARPACK_MODEBMAT = 26, IGRAPH_ARPACK_ISHIFT = 27, IGRAPH_ARPACK_NEVBE = 28, IGRAPH_ARPACK_NOFACT = 29, IGRAPH_ARPACK_FAILED = 30, IGRAPH_ARPACK_HOWMNY = 31, IGRAPH_ARPACK_HOWMNYS = 32, IGRAPH_ARPACK_EVDIFF = 33, IGRAPH_ARPACK_SHUR = 34, IGRAPH_ARPACK_LAPACK = 35, IGRAPH_ARPACK_UNKNOWN = 36, IGRAPH_ENEGLOOP = 37, IGRAPH_EINTERNAL = 38, IGRAPH_ARPACK_MAXIT = 39, IGRAPH_ARPACK_NOSHIFT = 40, IGRAPH_ARPACK_REORDER = 41, IGRAPH_EDIVZERO = 42, IGRAPH_GLP_EBOUND = 43, IGRAPH_GLP_EROOT = 44, IGRAPH_GLP_ENOPFS = 45, IGRAPH_GLP_ENODFS = 46, IGRAPH_GLP_EFAIL = 47, IGRAPH_GLP_EMIPGAP = 48, IGRAPH_GLP_ETMLIM = 49, IGRAPH_GLP_ESTOP = 50, IGRAPH_EATTRIBUTES = 51, IGRAPH_EATTRCOMBINE = 52, IGRAPH_ELAPACK = 53, IGRAPH_EDRL = 54, IGRAPH_EOVERFLOW = 55, IGRAPH_EGLP = 56, IGRAPH_CPUTIME = 57, IGRAPH_EUNDERFLOW = 58, IGRAPH_ERWSTUCK = 59, IGRAPH_STOP = 60 /* undocumented, used internally */ } igraph_error_type_t; /* Each enum value above must have a corresponding error string in * igraph_i_error_strings[] in igraph_error.c * * Information on undocumented codes: * - IGRAPH_STOP signals a request to stop in functions like igraph_i_maximal_cliques_bk() */ /* We use IGRAPH_FILE_BASENAME instead of __FILE__ to ensure that full * paths don't leak into the library code. IGRAPH_FILE_BASENAME is set up * by the build system when compiling the individual files. However, when * including igraph_error.h in user code, this macro is not defined so we * fall back to __FILE__ here */ #ifndef IGRAPH_FILE_BASENAME # define IGRAPH_FILE_BASENAME __FILE__ #endif /** * \define IGRAPH_ERROR * \brief Trigger an error. * * \a igraph functions usually use this macro when they notice an error. * It calls * \ref igraph_error() with the proper parameters and if that returns * the macro returns the "calling" function as well, with the error * code. If for some (suspicious) reason you want to call the error * handler without returning from the current function, call * \ref igraph_error() directly. * \param reason Textual description of the error. This should be * something more descriptive than the text associated with the error * code. E.g. if the error code is \c IGRAPH_EINVAL, * its associated text (see \ref igraph_strerror()) is "Invalid * value" and this string should explain which parameter was invalid * and maybe why. * \param igraph_errno The \a igraph error code. */ #define IGRAPH_ERROR(reason, igraph_errno) \ do { \ igraph_error (reason, IGRAPH_FILE_BASENAME, __LINE__, igraph_errno) ; \ return igraph_errno ; \ } while (0) #define IGRAPH_ERROR_NO_RETURN(reason, igraph_errno) \ do { \ igraph_error (reason, IGRAPH_FILE_BASENAME, __LINE__, igraph_errno) ; \ } while (0) /** * \function igraph_error * \brief Triggers an error. * * \a igraph functions usually call this function (most often via the * \ref IGRAPH_ERROR macro) if they notice an error. * It calls the currently installed error handler function with the * supplied arguments. * * \param reason Textual description of the error. * \param file The source file in which the error was noticed. * \param line The number of line in the source file which triggered the * error. * \param igraph_errno The \a igraph error code. * \return the error code (if it returns) * * \sa igraph_errorf(). */ IGRAPH_EXPORT int igraph_error(const char *reason, const char *file, int line, int igraph_errno); /** * \define IGRAPH_ERRORF * \brief Triggers an error, with printf-like syntax. * * \a igraph functions can use this macro when they notice an error and * want to pass on extra information to the user about what went wrong. * It calls \ref igraph_errorf() with the proper parameters and if that * returns the macro returns the "calling" function as well, with the * error code. If for some (suspicious) reason you want to call the * error handler without returning from the current function, call * \ref igraph_errorf() directly. * \param reason Textual description of the error, a template string * with the same syntax as the standard printf C library function. * This should be something more descriptive than the text associated * with the error code. E.g. if the error code is \c IGRAPH_EINVAL, * its associated text (see \ref igraph_strerror()) is "Invalid * value" and this string should explain which parameter was invalid * and maybe what was expected and what was recieved. * \param igraph_errno The \a igraph error code. * \param ... The additional arguments to be substituted into the * template string. */ #define IGRAPH_ERRORF(reason, igraph_errno, ...) \ do { \ igraph_errorf(reason, IGRAPH_FILE_BASENAME, __LINE__, \ igraph_errno, __VA_ARGS__) ; \ return igraph_errno; \ } while (0) /** * \function igraph_errorf * \brief Triggers an error, printf-like version. * * \param reason Textual description of the error, interpreted as * a \c printf format string. * \param file The source file in which the error was noticed. * \param line The line in the source file which triggered the error. * \param igraph_errno The \a igraph error code. * \param ... Additional parameters, the values to substitute into the * format string. * * \sa igraph_error(). */ IGRAPH_EXPORT int igraph_errorf(const char *reason, const char *file, int line, int igraph_errno, ...); IGRAPH_EXPORT int igraph_errorvf(const char *reason, const char *file, int line, int igraph_errno, va_list ap); /** * \function igraph_strerror * \brief Textual description of an error. * * This is a simple utility function, it gives a short general textual * description for an \a igraph error code. * * \param igraph_errno The \a igraph error code. * \return pointer to the textual description of the error code. */ IGRAPH_EXPORT const char* igraph_strerror(const int igraph_errno); #define IGRAPH_ERROR_SELECT_2(a,b) ((a) != IGRAPH_SUCCESS ? (a) : ((b) != IGRAPH_SUCCESS ? (b) : IGRAPH_SUCCESS)) #define IGRAPH_ERROR_SELECT_3(a,b,c) ((a) != IGRAPH_SUCCESS ? (a) : IGRAPH_ERROR_SELECT_2(b,c)) #define IGRAPH_ERROR_SELECT_4(a,b,c,d) ((a) != IGRAPH_SUCCESS ? (a) : IGRAPH_ERROR_SELECT_3(b,c,d)) #define IGRAPH_ERROR_SELECT_5(a,b,c,d,e) ((a) != IGRAPH_SUCCESS ? (a) : IGRAPH_ERROR_SELECT_4(b,c,d,e)) /* Now comes the more convenient error handling macro arsenal. * Ideas taken from exception.{h,c} by Laurent Deniau see * http://cern.ch/Laurent.Deniau/html/oopc/oopc.html#Exceptions for more * information. We don't use the exception handling code though. */ struct igraph_i_protectedPtr { int all; void *ptr; void (*func)(void*); }; typedef void igraph_finally_func_t (void*); IGRAPH_EXPORT void IGRAPH_FINALLY_REAL(void (*func)(void*), void* ptr); /** * \function IGRAPH_FINALLY_CLEAN * \brief Signals clean deallocation of objects. * * Removes the specified number of objects from the stack of * temporarily allocated objects. Most often this is called just * before returning from a function. * \param num The number of objects to remove from the bookkeeping * stack. */ IGRAPH_EXPORT void IGRAPH_FINALLY_CLEAN(int num); /** * \function IGRAPH_FINALLY_FREE * \brief Deallocates all registered objects. * * Calls the destroy function for all objects in the stack of * temporarily allocated objects. This is usually called only from an * error handler. It is \em not appropriate to use it * instead of destroying each unneeded object of a function, as it * destroys the temporary objects of the caller function (and so on) * as well. */ IGRAPH_EXPORT void IGRAPH_FINALLY_FREE(void); /** * \function IGRAPH_FINALLY_STACK_SIZE * \brief The number of registered objects. * * Returns the number of objects in the stack of temporarily allocated * objects. This function is handy if you write an own igraph routine and * you want to make sure it handles errors properly. A properly written * igraph routine should not leave pointers to temporarily allocated objects * in the finally stack, because otherwise an \ref IGRAPH_FINALLY_FREE call * in another igraph function would result in freeing these objects as well * (and this is really hard to debug, since the error will be not in that * function that shows erroneous behaviour). Therefore, it is advised to * write your own test cases and examine \ref IGRAPH_FINALLY_STACK_SIZE * before and after your test cases - the numbers should be equal. */ IGRAPH_EXPORT int IGRAPH_FINALLY_STACK_SIZE(void); /** * \define IGRAPH_FINALLY_STACK_EMPTY * \brief Returns true if there are no registered objects, false otherwise. * * This is just a shorthand notation for checking that * \ref IGRAPH_FINALLY_STACK_SIZE() is zero. */ #define IGRAPH_FINALLY_STACK_EMPTY (IGRAPH_FINALLY_STACK_SIZE() == 0) /** * \define IGRAPH_FINALLY * \brief Registers an object for deallocation. * \param func The address of the function which is normally called to * destroy the object. * \param ptr Pointer to the object itself. * * This macro places the address of an object, together with the * address of its destructor in a stack. This stack is used if an * error happens to deallocate temporarily allocated objects to * prevent memory leaks. */ #define IGRAPH_FINALLY(func, ptr) \ do { \ /* the following branch makes the compiler check the compatibility of \ * func and ptr to detect cases when we are accidentally invoking an \ * incorrect destructor function with the pointer */ \ if (0) { func(ptr); } \ IGRAPH_FINALLY_REAL((igraph_finally_func_t*)(func), (ptr)); \ } while (0) #if !defined(GCC_VERSION_MAJOR) && defined(__GNUC__) #define GCC_VERSION_MAJOR __GNUC__ #endif #if defined(GCC_VERSION_MAJOR) && (GCC_VERSION_MAJOR >= 3) #define IGRAPH_UNLIKELY(a) __builtin_expect((a), 0) #define IGRAPH_LIKELY(a) __builtin_expect((a), 1) #else #define IGRAPH_UNLIKELY(a) a #define IGRAPH_LIKELY(a) a #endif #if IGRAPH_VERIFY_FINALLY_STACK == 1 #define IGRAPH_CHECK(a) \ do { \ int enter_stack_size = IGRAPH_FINALLY_STACK_SIZE(); \ int igraph_i_ret=(a); \ if (IGRAPH_UNLIKELY(igraph_i_ret != 0)) {\ IGRAPH_ERROR("", igraph_i_ret); \ } \ if (IGRAPH_UNLIKELY(enter_stack_size != IGRAPH_FINALLY_STACK_SIZE())) { \ IGRAPH_ERROR("Non-matching number of IGRAPH_FINALLY and IGRAPH_FINALLY_CLEAN", IGRAPH_FAILURE); \ } \ } while (0) #else /** * \define IGRAPH_CHECK * \brief Checks the return value of a function call. * * \param a An expression, usually a function call. * * Executes the expression and checks its value. If this is not * \c IGRAPH_SUCCESS, it calls \ref IGRAPH_ERROR with * the value as the error code. Here is an example usage: * \verbatim IGRAPH_CHECK(vector_push_back(&v, 100)); \endverbatim * * There is only one reason to use this macro when writing * \a igraph functions. If the user installs an error handler which * returns to the auxiliary calling code (like \ref * igraph_error_handler_ignore and \ref * igraph_error_handler_printignore), and the \a igraph function * signalling the error is called from another \a igraph function * then we need to make sure that the error is propagated back to * the auxiliary (i.e. non-igraph) calling function. This is achieved * by using IGRAPH_CHECK on every \a igraph * call which can return an error code. */ #define IGRAPH_CHECK(a) do { \ int igraph_i_ret=(a); \ if (IGRAPH_UNLIKELY(igraph_i_ret != 0)) {\ IGRAPH_ERROR("", igraph_i_ret); \ } } while (0) #endif /** * \section about_igraph_warnings Warning messages * * * \a igraph also supports warning messages in addition to error * messages. Warning messages typically do not terminate the * program, but they are usually crucial to the user. * * * * \a igraph warnings are handled similarly to errors. There is a * separate warning handler function that is called whenever * an \a igraph function triggers a warning. This handler can be * set by the \ref igraph_set_warning_handler() function. There are * two predefined simple warning handlers, * \ref igraph_warning_handler_ignore() and * \ref igraph_warning_handler_print(), the latter being the default. * * * * To trigger a warning, \a igraph functions typically use the * \ref IGRAPH_WARNING() macro, the \ref igraph_warning() function, * or if more flexibility is needed, \ref igraph_warningf(). * */ /** * \typedef igraph_warning_handler_t * \brief The type of igraph warning handler functions. * * Currently it is defined to have the same type as * \ref igraph_error_handler_t, although the last (error code) * argument is not used. */ typedef igraph_error_handler_t igraph_warning_handler_t; /** * \function igraph_set_warning_handler * \brief Installs a warning handler. * * Install the supplied warning handler function. * \param new_handler The new warning handler function to install. * Supply a null pointer here to uninstall the current * warning handler, without installing a new one. * \return The current warning handler function. */ IGRAPH_EXPORT igraph_warning_handler_t* igraph_set_warning_handler(igraph_warning_handler_t* new_handler); IGRAPH_EXPORT extern igraph_warning_handler_t igraph_warning_handler_ignore; IGRAPH_EXPORT extern igraph_warning_handler_t igraph_warning_handler_print; /** * \function igraph_warning * \brief Triggers a warning. * * Call this function if you want to trigger a warning from within * a function that uses \a igraph. * \param reason Textual description of the warning. * \param file The source file in which the warning was noticed. * \param line The number of line in the source file which triggered the * warning. * \param igraph_errno Warnings could have potentially error codes as well, * but this is currently not used in igraph. * \return The supplied error code. */ IGRAPH_EXPORT int igraph_warning(const char *reason, const char *file, int line, int igraph_errno); /** * \define IGRAPH_WARNINGF * \brief Triggers a warning, with printf-like syntax. * * \a igraph functions can use this macro when they notice a warning and * want to pass on extra information to the user about what went wrong. * It calls \ref igraph_warningf() with the proper parameters and no * error code. * \param reason Textual description of the warning, a template string * with the same syntax as the standard printf C library function. * \param ... The additional arguments to be substituted into the * template string. */ #define IGRAPH_WARNINGF(reason, ...) \ do { \ igraph_warningf(reason, IGRAPH_FILE_BASENAME, __LINE__, \ -1, __VA_ARGS__); \ } while (0) /** * \function igraph_warningf * \brief Triggers a warning, printf-like version. * * This function is similar to \ref igraph_warning(), but * uses a printf-like syntax. It substitutes the additional arguments * into the \p reason template string and calls \ref igraph_warning(). * \param reason Textual description of the warning, a template string * with the same syntax as the standard printf C library function. * \param file The source file in which the warning was noticed. * \param line The number of line in the source file which triggered the * warning. * \param igraph_errno Warnings could have potentially error codes as well, * but this is currently not used in igraph. * \param ... The additional arguments to be substituted into the * template string. * \return The supplied error code. */ IGRAPH_EXPORT int igraph_warningf(const char *reason, const char *file, int line, int igraph_errno, ...); /** * \define IGRAPH_WARNING * \brief Triggers a warning. * * This is the usual way of triggering a warning from an igraph * function. It calls \ref igraph_warning(). * \param reason The warning message. */ #define IGRAPH_WARNING(reason) \ do { \ igraph_warning(reason, IGRAPH_FILE_BASENAME, __LINE__, -1); \ } while (0) /** * \section fatal_error_handlers Fatal errors * * * In some rare situations, \a igraph may encounter an internal error * that cannot be fully handled. In this case, it will call the * current fatal error handler. The default fatal error handler * simply prints the error and aborts the program. * * * * Fatal error handlers do not return. Typically, they might abort the * the program immediately, or in the case of the high-level \a igraph * interfaces, they might return to the top level using a * longjmp(). The fatal error handler is only called when * a serious error has occurred, and as a result igraph may be in an * inconsistent state. The purpose of returning to the top level is to * give the user a chance to save their work instead of aborting immediately. * However, the program session should be restarted as soon as possible. * * * * Most projects that use \a igraph will use the default fatal error * handler. * */ /** * \typedef igraph_fatal_handler_t * \brief The type of igraph fatal error handler functions. * * Functions of this type \em must not return. Typically they * call abort() or do a longjmp(). * * \param reason Textual description of the error. * \param file The source file in which the error is noticed. * \param line The number of the line in the source file which triggered the error */ typedef void igraph_fatal_handler_t (const char *reason, const char *file, int line); /** * \function igraph_set_fatal_handler * \brief Installs a fatal error handler. * * Installs the supplied fatal error handler function. * * * Fatal error handler functions \em must not return. Typically, the fatal * error handler would either call abort() or longjmp(). * * \param new_handler The new fatal error handler function to install. * Supply a null pointer here to uninstall the current * fatal error handler, without installing a new one. * \return The current fatal error handler function. */ IGRAPH_EXPORT igraph_fatal_handler_t* igraph_set_fatal_handler(igraph_fatal_handler_t* new_handler); /** * \var igraph_fatal_handler_abort * \brief Abort program in case of fatal error. * * The default fatal error handler, prints an error message and aborts the program. */ IGRAPH_EXPORT igraph_fatal_handler_t igraph_fatal_handler_abort; /** * \function igraph_fatal * \brief Triggers a fatal error. * * This function triggers a fatal error. Typically it is called indirectly through * \ref IGRAPH_FATAL() or \ref IGRAPH_ASSERT(). * * \param reason Textual description of the error. * \param file The source file in which the error was noticed. * \param line The number of line in the source file which triggered the error. */ IGRAPH_EXPORT IGRAPH_NORETURN void igraph_fatal(const char *reason, const char *file, int line); /** * \function igraph_fatalf * \brief Triggers a fatal error, printf-like syntax. * * This function is similar to \ref igraph_fatal(), but * uses a printf-like syntax. It substitutes the additional arguments * into the \p reason template string and calls \ref igraph_fatal(). * * \param reason Textual description of the error. * \param file The source file in which the error was noticed. * \param line The number of line in the source file which triggered the error. * \param ... The additional arguments to be substituted into the template string. */ IGRAPH_EXPORT IGRAPH_NORETURN void igraph_fatalf(const char *reason, const char *file, int line, ...); /** * \define IGRAPH_FATALF * \brief Triggers a fatal error, with printf-like syntax. * * \a igraph functions can use this macro when a fatal error occurs and * want to pass on extra information to the user about what went wrong. * It calls \ref igraph_fatalf() with the proper parameters. * \param reason Textual description of the error, a template string * with the same syntax as the standard printf C library function. * \param ... The additional arguments to be substituted into the * template string. */ #define IGRAPH_FATALF(reason, ...) \ do { \ igraph_fatalf(reason, IGRAPH_FILE_BASENAME, __LINE__, \ __VA_ARGS__); \ } while (0) /** * \define IGRAPH_FATAL * \brief Triggers a fatal error. * * This is the usual way of triggering a fatal error from an igraph * function. It calls \ref igraph_fatal(). * * * Use this macro only in situations where the error cannot be handled. * The normal way to handle errors is \ref IGRAPH_ERROR(). * * \param reason The error message. */ #define IGRAPH_FATAL(reason) \ do { \ igraph_fatal(reason, IGRAPH_FILE_BASENAME, __LINE__); \ } while (0) /** * \define IGRAPH_ASSERT * \brief igraph-specific replacement for assert(). * * This macro is like the standard assert(), but instead of * calling abort(), it calls \ref igraph_fatal(). This allows for returning * the control to the calling program, e.g. returning to the top level in a high-level * \a igraph interface. * * * Unlike assert(), IGRAPH_ASSERT() is not disabled * when the \c NDEBUG macro is defined. * * * This macro is meant for internal use by \a igraph. * * * Since a typial fatal error handler does a longjmp(), avoid using this * macro in C++ code. With most compilers, destructor will not be called when * longjmp() leaves the current scope. * * \param condition The condition to be checked. */ #define IGRAPH_ASSERT(condition) \ do { \ if (!(condition)) { \ igraph_fatal("Assertion failed: " #condition, IGRAPH_FILE_BASENAME, __LINE__); \ } \ } while (0) __END_DECLS #endif leidenbase/src/include/igraph_flow.h0000644000176200001440000001731014447675375017261 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_FLOW_H #define IGRAPH_FLOW_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_types.h" #include "igraph_datatype.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Maximum flows, minimum cuts & such */ /* -------------------------------------------------- */ /** * \typedef igraph_maxflow_stats_t * A simple data type to return some statistics from the * push-relabel maximum flow solver. * * \param nopush The number of push operations performed. * \param norelabel The number of relabel operarions performed. * \param nogap The number of times the gap heuristics was used. * \param nogapnodes The total number of vertices that were * omitted form further calculations because of the gap * heuristics. * \param nobfs The number of times the reverse BFS was run to * assign good values to the height function. This includes * an initial run before the whole algorithm, so it is always * at least one. */ typedef struct { int nopush, norelabel, nogap, nogapnodes, nobfs; } igraph_maxflow_stats_t; IGRAPH_EXPORT int igraph_maxflow(const igraph_t *graph, igraph_real_t *value, igraph_vector_t *flow, igraph_vector_t *cut, igraph_vector_t *partition, igraph_vector_t *partition2, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity, igraph_maxflow_stats_t *stats); IGRAPH_EXPORT int igraph_maxflow_value(const igraph_t *graph, igraph_real_t *value, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity, igraph_maxflow_stats_t *stats); IGRAPH_EXPORT int igraph_st_mincut(const igraph_t *graph, igraph_real_t *value, igraph_vector_t *cut, igraph_vector_t *partition, igraph_vector_t *partition2, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity); IGRAPH_EXPORT int igraph_st_mincut_value(const igraph_t *graph, igraph_real_t *res, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity); IGRAPH_EXPORT int igraph_mincut_value(const igraph_t *graph, igraph_real_t *res, const igraph_vector_t *capacity); IGRAPH_EXPORT int igraph_mincut(const igraph_t *graph, igraph_real_t *value, igraph_vector_t *partition, igraph_vector_t *partition2, igraph_vector_t *cut, const igraph_vector_t *capacity); IGRAPH_EXPORT int igraph_st_vertex_connectivity(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target, igraph_vconn_nei_t neighbors); IGRAPH_EXPORT int igraph_vertex_connectivity(const igraph_t *graph, igraph_integer_t *res, igraph_bool_t checks); IGRAPH_EXPORT int igraph_st_edge_connectivity(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target); IGRAPH_EXPORT int igraph_edge_connectivity(const igraph_t *graph, igraph_integer_t *res, igraph_bool_t checks); IGRAPH_EXPORT int igraph_edge_disjoint_paths(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target); IGRAPH_EXPORT int igraph_vertex_disjoint_paths(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target); IGRAPH_EXPORT int igraph_adhesion(const igraph_t *graph, igraph_integer_t *res, igraph_bool_t checks); IGRAPH_EXPORT int igraph_cohesion(const igraph_t *graph, igraph_integer_t *res, igraph_bool_t checks); /* s-t cut listing related stuff */ IGRAPH_EXPORT int igraph_even_tarjan_reduction(const igraph_t *graph, igraph_t *graphbar, igraph_vector_t *capacity); IGRAPH_EXPORT int igraph_residual_graph(const igraph_t *graph, const igraph_vector_t *capacity, igraph_t *residual, igraph_vector_t *residual_capacity, const igraph_vector_t *flow); IGRAPH_EXPORT int igraph_reverse_residual_graph(const igraph_t *graph, const igraph_vector_t *capacity, igraph_t *residual, const igraph_vector_t *flow); IGRAPH_EXPORT int igraph_dominator_tree(const igraph_t *graph, igraph_integer_t root, igraph_vector_t *dom, igraph_t *domtree, igraph_vector_t *leftout, igraph_neimode_t mode); IGRAPH_EXPORT int igraph_all_st_cuts(const igraph_t *graph, igraph_vector_ptr_t *cuts, igraph_vector_ptr_t *partition1s, igraph_integer_t source, igraph_integer_t target); IGRAPH_EXPORT int igraph_all_st_mincuts(const igraph_t *graph, igraph_real_t *value, igraph_vector_ptr_t *cuts, igraph_vector_ptr_t *partition1s, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity); IGRAPH_EXPORT int igraph_gomory_hu_tree(const igraph_t *graph, igraph_t *tree, igraph_vector_t *flows, const igraph_vector_t *capacity); __END_DECLS #endif leidenbase/src/include/igraph_foreign.h0000644000176200001440000001050714447675375017744 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_FOREIGN_H #define IGRAPH_FOREIGN_H #include "igraph_decls.h" #include "igraph_constants.h" #include "igraph_datatype.h" #include "igraph_types.h" #include "igraph_strvector.h" #include __BEGIN_DECLS /* -------------------------------------------------- */ /* Read and write foreign formats */ /* -------------------------------------------------- */ IGRAPH_EXPORT int igraph_read_graph_edgelist(igraph_t *graph, FILE *instream, igraph_integer_t n, igraph_bool_t directed); IGRAPH_EXPORT int igraph_read_graph_ncol(igraph_t *graph, FILE *instream, const igraph_strvector_t *predefnames, igraph_bool_t names, igraph_add_weights_t weights, igraph_bool_t directed); IGRAPH_EXPORT int igraph_read_graph_lgl(igraph_t *graph, FILE *instream, igraph_bool_t names, igraph_add_weights_t weights, igraph_bool_t directed); IGRAPH_EXPORT int igraph_read_graph_pajek(igraph_t *graph, FILE *instream); IGRAPH_EXPORT int igraph_read_graph_graphml(igraph_t *graph, FILE *instream, int index); IGRAPH_EXPORT int igraph_read_graph_dimacs(igraph_t *graph, FILE *instream, igraph_strvector_t *problem, igraph_vector_t *label, igraph_integer_t *source, igraph_integer_t *target, igraph_vector_t *capacity, igraph_bool_t directed); IGRAPH_EXPORT int igraph_read_graph_graphdb(igraph_t *graph, FILE *instream, igraph_bool_t directed); IGRAPH_EXPORT int igraph_read_graph_gml(igraph_t *graph, FILE *instream); IGRAPH_EXPORT int igraph_read_graph_dl(igraph_t *graph, FILE *instream, igraph_bool_t directed); IGRAPH_EXPORT int igraph_write_graph_edgelist(const igraph_t *graph, FILE *outstream); IGRAPH_EXPORT int igraph_write_graph_ncol(const igraph_t *graph, FILE *outstream, const char *names, const char *weights); IGRAPH_EXPORT int igraph_write_graph_lgl(const igraph_t *graph, FILE *outstream, const char *names, const char *weights, igraph_bool_t isolates); IGRAPH_EXPORT int igraph_write_graph_graphml(const igraph_t *graph, FILE *outstream, igraph_bool_t prefixattr); IGRAPH_EXPORT int igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream); IGRAPH_EXPORT int igraph_write_graph_dimacs(const igraph_t *graph, FILE *outstream, long int source, long int target, const igraph_vector_t *capacity); IGRAPH_EXPORT int igraph_write_graph_gml(const igraph_t *graph, FILE *outstream, const igraph_vector_t *id, const char *creator); IGRAPH_EXPORT int igraph_write_graph_dot(const igraph_t *graph, FILE *outstream); IGRAPH_EXPORT int igraph_write_graph_leda(const igraph_t *graph, FILE *outstream, const char* vertex_attr_name, const char* edge_attr_name); __END_DECLS #endif leidenbase/src/include/igraph_heap_pmt.h0000644000176200001440000000330714447675375020110 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ typedef struct TYPE(igraph_heap) { BASE* stor_begin; BASE* stor_end; BASE* end; int destroy; } TYPE(igraph_heap); IGRAPH_EXPORT int FUNCTION(igraph_heap, init)(TYPE(igraph_heap)* h, long int size); IGRAPH_EXPORT int FUNCTION(igraph_heap, init_array)(TYPE(igraph_heap) *t, BASE* data, long int len); IGRAPH_EXPORT void FUNCTION(igraph_heap, destroy)(TYPE(igraph_heap)* h); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_heap, empty)(TYPE(igraph_heap)* h); IGRAPH_EXPORT int FUNCTION(igraph_heap, push)(TYPE(igraph_heap)* h, BASE elem); IGRAPH_EXPORT BASE FUNCTION(igraph_heap, top)(TYPE(igraph_heap)* h); IGRAPH_EXPORT BASE FUNCTION(igraph_heap, delete_top)(TYPE(igraph_heap)* h); IGRAPH_EXPORT long int FUNCTION(igraph_heap, size)(TYPE(igraph_heap)* h); IGRAPH_EXPORT int FUNCTION(igraph_heap, reserve)(TYPE(igraph_heap)* h, long int size); leidenbase/src/include/igraph_matrix_pmt.h0000644000176200001440000003216714447675375020505 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ typedef struct TYPE(igraph_matrix) { TYPE(igraph_vector) data; long int nrow, ncol; } TYPE(igraph_matrix); /*---------------*/ /* Allocation */ /*---------------*/ IGRAPH_EXPORT int FUNCTION(igraph_matrix, init)(TYPE(igraph_matrix) *m, long int nrow, long int ncol); IGRAPH_EXPORT int FUNCTION(igraph_matrix, copy)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from); IGRAPH_EXPORT void FUNCTION(igraph_matrix, destroy)(TYPE(igraph_matrix) *m); IGRAPH_EXPORT long int FUNCTION(igraph_matrix, capacity)(const TYPE(igraph_matrix) *m); /*--------------------*/ /* Accessing elements */ /*--------------------*/ /* MATRIX */ IGRAPH_EXPORT BASE FUNCTION(igraph_matrix, e)(const TYPE(igraph_matrix) *m, long int row, long int col); IGRAPH_EXPORT BASE* FUNCTION(igraph_matrix, e_ptr)(const TYPE(igraph_matrix) *m, long int row, long int col); IGRAPH_EXPORT void FUNCTION(igraph_matrix, set)(TYPE(igraph_matrix)* m, long int row, long int col, BASE value); /*------------------------------*/ /* Initializing matrix elements */ /*------------------------------*/ IGRAPH_EXPORT void FUNCTION(igraph_matrix, null)(TYPE(igraph_matrix) *m); IGRAPH_EXPORT void FUNCTION(igraph_matrix, fill)(TYPE(igraph_matrix) *m, BASE e); /*-----------------------*/ /* Matrix views */ /*-----------------------*/ IGRAPH_EXPORT const TYPE(igraph_matrix) *FUNCTION(igraph_matrix, view)(const TYPE(igraph_matrix) *m, const BASE *data, long int nrow, long int ncol); /*------------------*/ /* Copying matrices */ /*------------------*/ IGRAPH_EXPORT void FUNCTION(igraph_matrix, copy_to)(const TYPE(igraph_matrix) *m, BASE *to); IGRAPH_EXPORT int FUNCTION(igraph_matrix, update)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from); IGRAPH_EXPORT int FUNCTION(igraph_matrix, rbind)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from); IGRAPH_EXPORT int FUNCTION(igraph_matrix, cbind)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from); IGRAPH_EXPORT int FUNCTION(igraph_matrix, swap)(TYPE(igraph_matrix) *m1, TYPE(igraph_matrix) *m2); /*--------------------------*/ /* Copying rows and columns */ /*--------------------------*/ IGRAPH_EXPORT int FUNCTION(igraph_matrix, get_row)(const TYPE(igraph_matrix) *m, TYPE(igraph_vector) *res, long int index); IGRAPH_EXPORT int FUNCTION(igraph_matrix, get_col)(const TYPE(igraph_matrix) *m, TYPE(igraph_vector) *res, long int index); IGRAPH_EXPORT int FUNCTION(igraph_matrix, set_row)(TYPE(igraph_matrix) *m, const TYPE(igraph_vector) *v, long int index); IGRAPH_EXPORT int FUNCTION(igraph_matrix, set_col)(TYPE(igraph_matrix) *m, const TYPE(igraph_vector) *v, long int index); IGRAPH_EXPORT int FUNCTION(igraph_matrix, select_rows)(const TYPE(igraph_matrix) *m, TYPE(igraph_matrix) *res, const igraph_vector_t *rows); IGRAPH_EXPORT int FUNCTION(igraph_matrix, select_cols)(const TYPE(igraph_matrix) *m, TYPE(igraph_matrix) *res, const igraph_vector_t *cols); IGRAPH_EXPORT int FUNCTION(igraph_matrix, select_rows_cols)(const TYPE(igraph_matrix) *m, TYPE(igraph_matrix) *res, const igraph_vector_t *rows, const igraph_vector_t *cols); /*-----------------------------*/ /* Exchanging rows and columns */ /*-----------------------------*/ IGRAPH_EXPORT int FUNCTION(igraph_matrix, swap_rows)(TYPE(igraph_matrix) *m, long int i, long int j); IGRAPH_EXPORT int FUNCTION(igraph_matrix, swap_cols)(TYPE(igraph_matrix) *m, long int i, long int j); IGRAPH_EXPORT int FUNCTION(igraph_matrix, swap_rowcol)(TYPE(igraph_matrix) *m, long int i, long int j); IGRAPH_EXPORT int FUNCTION(igraph_matrix, transpose)(TYPE(igraph_matrix) *m); /*-----------------------------*/ /* Matrix operations */ /*-----------------------------*/ IGRAPH_EXPORT int FUNCTION(igraph_matrix, add)(TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2); IGRAPH_EXPORT int FUNCTION(igraph_matrix, sub)(TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2); IGRAPH_EXPORT int FUNCTION(igraph_matrix, mul_elements)(TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2); IGRAPH_EXPORT int FUNCTION(igraph_matrix, div_elements)(TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2); IGRAPH_EXPORT void FUNCTION(igraph_matrix, scale)(TYPE(igraph_matrix) *m, BASE by); IGRAPH_EXPORT void FUNCTION(igraph_matrix, add_constant)(TYPE(igraph_matrix) *m, BASE plus); /*-----------------------------*/ /* Finding minimum and maximum */ /*-----------------------------*/ #ifndef NOTORDERED IGRAPH_EXPORT igraph_real_t FUNCTION(igraph_matrix, min)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT igraph_real_t FUNCTION(igraph_matrix, max)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT int FUNCTION(igraph_matrix, which_min)(const TYPE(igraph_matrix) *m, long int *i, long int *j); IGRAPH_EXPORT int FUNCTION(igraph_matrix, which_max)(const TYPE(igraph_matrix) *m, long int *i, long int *j); IGRAPH_EXPORT int FUNCTION(igraph_matrix, minmax)(const TYPE(igraph_matrix) *m, BASE *min, BASE *max); IGRAPH_EXPORT int FUNCTION(igraph_matrix, which_minmax)(const TYPE(igraph_matrix) *m, long int *imin, long int *jmin, long int *imax, long int *jmax); #endif /*------------------------------*/ /* Comparison */ /*------------------------------*/ IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, all_e)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs); #ifndef NOTORDERED IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, all_l)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, all_g)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, all_le)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, all_ge)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs); #endif /*-------------------*/ /* Matrix properties */ /*-------------------*/ IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, isnull)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, empty)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT long int FUNCTION(igraph_matrix, size)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT long int FUNCTION(igraph_matrix, nrow)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT long int FUNCTION(igraph_matrix, ncol)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, is_symmetric)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT BASE FUNCTION(igraph_matrix, sum)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT BASE FUNCTION(igraph_matrix, prod)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT int FUNCTION(igraph_matrix, rowsum)(const TYPE(igraph_matrix) *m, TYPE(igraph_vector) *res); IGRAPH_EXPORT int FUNCTION(igraph_matrix, colsum)(const TYPE(igraph_matrix) *m, TYPE(igraph_vector) *res); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, is_equal)(const TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2); #ifndef NOTORDERED IGRAPH_EXPORT igraph_real_t FUNCTION(igraph_matrix, maxdifference)(const TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2); #endif /*------------------------*/ /* Searching for elements */ /*------------------------*/ IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, contains)(const TYPE(igraph_matrix) *m, BASE e); IGRAPH_EXPORT igraph_bool_t FUNCTION(igraph_matrix, search)(const TYPE(igraph_matrix) *m, long int from, BASE what, long int *pos, long int *row, long int *col); /*------------------------*/ /* Resizing operations */ /*------------------------*/ IGRAPH_EXPORT int FUNCTION(igraph_matrix, resize)(TYPE(igraph_matrix) *m, long int nrow, long int ncol); IGRAPH_EXPORT int FUNCTION(igraph_matrix, resize_min)(TYPE(igraph_matrix) *m); IGRAPH_EXPORT int FUNCTION(igraph_matrix, add_cols)(TYPE(igraph_matrix) *m, long int n); IGRAPH_EXPORT int FUNCTION(igraph_matrix, add_rows)(TYPE(igraph_matrix) *m, long int n); IGRAPH_EXPORT int FUNCTION(igraph_matrix, remove_col)(TYPE(igraph_matrix) *m, long int col); IGRAPH_EXPORT int FUNCTION(igraph_matrix, remove_row)(TYPE(igraph_matrix) *m, long int row); /*------------------------*/ /* Print as text */ /*------------------------*/ IGRAPH_EXPORT int FUNCTION(igraph_matrix, print)(const TYPE(igraph_matrix) *m); IGRAPH_EXPORT int FUNCTION(igraph_matrix, printf)(const TYPE(igraph_matrix) *m, const char *format); IGRAPH_EXPORT int FUNCTION(igraph_matrix, fprint)(const TYPE(igraph_matrix) *m, FILE *file); #ifdef BASE_COMPLEX IGRAPH_EXPORT int igraph_matrix_complex_real(const igraph_matrix_complex_t *v, igraph_matrix_t *real); IGRAPH_EXPORT int igraph_matrix_complex_imag(const igraph_matrix_complex_t *v, igraph_matrix_t *imag); IGRAPH_EXPORT int igraph_matrix_complex_realimag(const igraph_matrix_complex_t *v, igraph_matrix_t *real, igraph_matrix_t *imag); IGRAPH_EXPORT int igraph_matrix_complex_create(igraph_matrix_complex_t *v, const igraph_matrix_t *real, const igraph_matrix_t *imag); IGRAPH_EXPORT int igraph_matrix_complex_create_polar(igraph_matrix_complex_t *v, const igraph_matrix_t *r, const igraph_matrix_t *theta); #endif IGRAPH_EXPORT int FUNCTION(igraph_matrix, permdelete_rows)(TYPE(igraph_matrix) *m, long int *index, long int nremove); IGRAPH_EXPORT int FUNCTION(igraph_matrix, delete_rows_neg)(TYPE(igraph_matrix) *m, const igraph_vector_t *neg, long int nremove); leidenbase/src/include/igraph_spmatrix.h0000644000176200001440000001260514447675375020163 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_SPMATRIX_H #define IGRAPH_SPMATRIX_H #include "igraph_decls.h" #include "igraph_vector.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Sparse matrix */ /* -------------------------------------------------- */ /** * \section about_igraph_spmatrix_t_objects About \type igraph_spmatrix_t objects * * The \type igraph_spmatrix_t type stores a sparse matrix with the * assumption that the number of nonzero elements in the matrix scales * linearly with the row or column count of the matrix (so most of the * elements are zero). Of course it can store an arbitrary real matrix, * but if most of the elements are nonzero, one should use \type igraph_matrix_t * instead. * * The elements are stored in column compressed format, so the elements * in the same column are stored adjacent in the computer's memory. The storage * requirement for a sparse matrix is O(n) where n is the number of nonzero * elements. Actually it can be a bit larger, see the documentation of * the vector type for an explanation. */ typedef struct s_spmatrix { igraph_vector_t ridx, cidx, data; long int nrow, ncol; } igraph_spmatrix_t; #define IGRAPH_SPMATRIX_INIT_FINALLY(m, nr, nc) \ do { IGRAPH_CHECK(igraph_spmatrix_init(m, nr, nc)); \ IGRAPH_FINALLY(igraph_spmatrix_destroy, m); } while (0) IGRAPH_EXPORT int igraph_spmatrix_init(igraph_spmatrix_t *m, long int nrow, long int ncol); IGRAPH_EXPORT void igraph_spmatrix_destroy(igraph_spmatrix_t *m); IGRAPH_EXPORT int igraph_spmatrix_resize(igraph_spmatrix_t *m, long int nrow, long int ncol); IGRAPH_EXPORT igraph_real_t igraph_spmatrix_e(const igraph_spmatrix_t *m, long int row, long int col); IGRAPH_EXPORT int igraph_spmatrix_set(igraph_spmatrix_t *m, long int row, long int col, igraph_real_t value); IGRAPH_EXPORT int igraph_spmatrix_add_e(igraph_spmatrix_t *m, long int row, long int col, igraph_real_t value); IGRAPH_EXPORT int igraph_spmatrix_add_col_values(igraph_spmatrix_t *m, long int to, long int from); IGRAPH_EXPORT long int igraph_spmatrix_count_nonzero(const igraph_spmatrix_t *m); IGRAPH_EXPORT long int igraph_spmatrix_size(const igraph_spmatrix_t *m); IGRAPH_EXPORT long int igraph_spmatrix_nrow(const igraph_spmatrix_t *m); IGRAPH_EXPORT long int igraph_spmatrix_ncol(const igraph_spmatrix_t *m); IGRAPH_EXPORT int igraph_spmatrix_copy_to(const igraph_spmatrix_t *m, igraph_real_t *to); IGRAPH_EXPORT int igraph_spmatrix_null(igraph_spmatrix_t *m); IGRAPH_EXPORT int igraph_spmatrix_add_cols(igraph_spmatrix_t *m, long int n); IGRAPH_EXPORT int igraph_spmatrix_add_rows(igraph_spmatrix_t *m, long int n); IGRAPH_EXPORT int igraph_spmatrix_clear_col(igraph_spmatrix_t *m, long int col); IGRAPH_EXPORT int igraph_spmatrix_clear_row(igraph_spmatrix_t *m, long int row); IGRAPH_EXPORT int igraph_spmatrix_copy(igraph_spmatrix_t *to, const igraph_spmatrix_t *from); IGRAPH_EXPORT igraph_real_t igraph_spmatrix_max_nonzero(const igraph_spmatrix_t *m, igraph_real_t *ridx, igraph_real_t *cidx); IGRAPH_EXPORT igraph_real_t igraph_spmatrix_max(const igraph_spmatrix_t *m, igraph_real_t *ridx, igraph_real_t *cidx); IGRAPH_EXPORT void igraph_spmatrix_scale(igraph_spmatrix_t *m, igraph_real_t by); IGRAPH_EXPORT int igraph_spmatrix_colsums(const igraph_spmatrix_t *m, igraph_vector_t *res); IGRAPH_EXPORT int igraph_spmatrix_rowsums(const igraph_spmatrix_t *m, igraph_vector_t *res); IGRAPH_EXPORT int igraph_spmatrix_print(const igraph_spmatrix_t *matrix); IGRAPH_EXPORT int igraph_spmatrix_fprint(const igraph_spmatrix_t *matrix, FILE* file); typedef struct s_spmatrix_iter { const igraph_spmatrix_t *m; /* pointer to the matrix we are iterating over */ long int pos; /* internal index into the data vector */ long int ri; /* row index */ long int ci; /* column index */ igraph_real_t value; /* value at the given cell */ } igraph_spmatrix_iter_t; IGRAPH_EXPORT int igraph_spmatrix_iter_create(igraph_spmatrix_iter_t *mit, const igraph_spmatrix_t *m); IGRAPH_EXPORT int igraph_spmatrix_iter_reset(igraph_spmatrix_iter_t *mit); IGRAPH_EXPORT int igraph_spmatrix_iter_next(igraph_spmatrix_iter_t *mit); IGRAPH_EXPORT igraph_bool_t igraph_spmatrix_iter_end(igraph_spmatrix_iter_t *mit); IGRAPH_EXPORT void igraph_spmatrix_iter_destroy(igraph_spmatrix_iter_t *mit); __END_DECLS #endif leidenbase/src/vendor/0000755000176200001440000000000014447675376014460 5ustar liggesusersleidenbase/src/vendor/simpleraytracer/0000755000176200001440000000000014532173045017643 5ustar liggesusersleidenbase/src/vendor/simpleraytracer/Color.cpp0000644000176200001440000000320514447675376021450 0ustar liggesusers#include "Color.h" #include "unit_limiter.h" namespace igraph { Color::Color() { } Color::Color(double vRed, double vGreen, double vBlue, double vTransparent) { Red(vRed); Green(vGreen); Blue(vBlue); Transparent(vTransparent); } Color::~Color() { } // returns multiplication of a scalar with this vector Color Color::operator* (double vRhs) const { return Color(mRed*vRhs, mGreen*vRhs, mBlue*vRhs, mTransparent); } // returns the addition of this color with another color Color Color::operator+ (const Color& vRhs) const { double trans=Transparent() > vRhs.Transparent() ? Transparent() : vRhs.Transparent(); return Color(Red()+vRhs.Red(),Green()+vRhs.Green(),Blue()+vRhs.Blue(), trans); } void Color::Red(double vRed) { mRed = unit_limiter(vRed); } double Color::Red() const { return mRed; } void Color::Green(double vGreen) { mGreen = unit_limiter(vGreen); } double Color::Green() const { return mGreen; } void Color::Blue(double vBlue) { mBlue = unit_limiter(vBlue); } double Color::Blue() const { return mBlue; } void Color::Transparent(double vTransparent) { mTransparent = unit_limiter(vTransparent); } double Color::Transparent() const { return mTransparent; } unsigned char Color::RedByte() const { return ByteValue(mRed); } unsigned char Color::GreenByte() const { return ByteValue(mGreen); } unsigned char Color::BlueByte() const { return ByteValue(mBlue); } unsigned char Color::TransparentByte() const { return ByteValue(mTransparent); } unsigned char Color::ByteValue(double vZeroToOne) const { return (unsigned char)(vZeroToOne*255.0); } } // namespace igraph leidenbase/src/vendor/simpleraytracer/RayVector.cpp0000644000176200001440000000433414447675376022314 0ustar liggesusers#include "RayVector.h" #include namespace igraph { Vector::Vector() { mI = mJ = mK = 0.0; } Vector::Vector(const Point& vStartPoint, const Point& vEndPoint) { mI = vEndPoint.X() - vStartPoint.X(); mJ = vEndPoint.Y() - vStartPoint.Y(); mK = vEndPoint.Z() - vStartPoint.Z(); } Vector::Vector(double vI, double vJ, double vK) { mI = vI; mJ = vJ; mK = vK; } Vector::~Vector() {} // returns a unit vector of this vector Vector Vector::Normalize() const { double magnitude = Magnitude(); return Vector(mI/magnitude, mJ/magnitude, mK/magnitude); } void Vector::NormalizeThis() { *this = Normalize(); } void Vector::ReverseDirection() { *this = *this * -1.0; } bool Vector::IsSameDirection(const Vector& rVector) const { return ( this->Normalize().Dot(rVector.Normalize()) > 0.0 ); } void Vector::I(double vI) { mI = vI; } double Vector::I() const { return mI; } void Vector::J(double vJ) { mJ = vJ; } double Vector::J() const { return mJ; } void Vector::K(double vK) { mK = vK; } double Vector::K() const { return mK; } // returns the dot product of this and rVector double Vector::Dot(const Vector& rVector) const { return mI*rVector.I() + mJ*rVector.J() + mK*rVector.K(); } // returns the cross product of this and vVector Vector Vector::Cross(const Vector& rVector) const { return Vector(mJ*rVector.K() - rVector.J()*mK, -1.0*(mI*rVector.K() - rVector.I()*mK), mI*rVector.J() - rVector.I()*mJ); } // returns the sum of this vector with another vector Vector Vector::operator+ (Vector vRhs) const { return Vector(mI + vRhs.I(), mJ + vRhs.J(), mK + vRhs.K()); } // returns the sume of a vector and a Point Point Vector::operator+ (Point vRhs) const { return Point(mI + vRhs.X(), mJ + vRhs.Y(), mK + vRhs.Z()); } // returns the difference of two vectors Vector Vector::operator- (Vector vRhs) const { return Vector(mI-vRhs.I(), mJ-vRhs.J(), mK-vRhs.K()); } // returns multiplication of a scalar with this vector Vector Vector::operator* (double vRhs) const { return Vector(mI*vRhs, mJ*vRhs, mK*vRhs); } // converts this vector to a point Point Vector::ToPoint() const { return Point(mI,mJ,mK); } // returns the magnitude double Vector::Magnitude() const { return sqrt(mI*mI + mJ*mJ + mK*mK); } } // namespace igraph leidenbase/src/vendor/simpleraytracer/unit_limiter.cpp0000644000176200001440000000035314447675376023077 0ustar liggesusers#include "unit_limiter.h" namespace igraph { double unit_limiter(double vUnitDouble) { double result = vUnitDouble; if (result < 0.0) result = 0.0; else if (result > 1.0) result = 1.0; return result; } } // namespace igraph leidenbase/src/vendor/simpleraytracer/Ray.cpp0000644000176200001440000000105614447675376021127 0ustar liggesusers#include "Ray.h" namespace igraph { Ray::Ray() {} Ray::~Ray() {} Ray::Ray(const Point& rOrigin, const Vector& rDirection) { Direction(rDirection); Origin(rOrigin); } Ray::Ray(const Point& rOrigin, const Point& rEndPoint) { Direction(Vector(rOrigin,rEndPoint)); Origin(rOrigin); } const Point& Ray::Origin() const { return mOrigin; } void Ray::Origin(Point vOrigin) { mOrigin = vOrigin; } const Vector& Ray::Direction() const { return mDirection; } void Ray::Direction(Vector vDirection) { mDirection = vDirection; } } // namespace igraph leidenbase/src/vendor/simpleraytracer/Light.cpp0000644000176200001440000000126414447675376021444 0ustar liggesusers#include "Light.h" #include "unit_limiter.h" namespace igraph { Light::Light() : mLightPoint(0,0,0) { mIntensity = 0.1; } Light::Light(const Point& rLightPoint) : mLightPoint(rLightPoint) { mIntensity = 0.1; } Light::~Light() {} const Point& Light::LightPoint() const { return mLightPoint; } void Light::LightPoint(const Point& rLightPoint) { mLightPoint = rLightPoint; } double Light::Intensity() const { return mIntensity; } void Light::Intensity(double vIntensity) { mIntensity = unit_limiter(vIntensity); } const Color& Light::LightColor() const { return mLightColor; } void Light::LightColor(const Color& rLightColor) { mLightColor = rLightColor; } } // namespace igraph leidenbase/src/vendor/simpleraytracer/Light.h0000644000176200001440000000122314447675376021104 0ustar liggesusers#ifndef LIGHT_H #define LIGHT_H #include "Point.h" #include "Color.h" #include using namespace std; namespace igraph { class Light { public: Light(); // creates a light at the origin Light(const Point& rLightPoint); ~Light(); const Point& LightPoint() const; void LightPoint(const Point& rLightPoint); double Intensity() const; void Intensity(double vIntensity); const Color& LightColor() const; void LightColor(const Color& rLightColor); private: Point mLightPoint; double mIntensity; // 0 to 1 Color mLightColor; }; typedef list LightList; typedef list::iterator LightListIterator; } // namespace igraph #endif leidenbase/src/vendor/simpleraytracer/RayVector.h0000644000176200001440000000224214447675376021755 0ustar liggesusers/** Vector.h */ #ifndef VECTOR_H #define VECTOR_H #include "Point.h" namespace igraph { class Vector { public: Vector(); Vector(const Point& vStartPoint, const Point& vEndPoint); Vector(double vI, double vJ, double vK); ~Vector(); Vector Normalize() const; // returns a unit vector of this vector void NormalizeThis(); void ReverseDirection(); bool IsSameDirection(const Vector& rVector) const; void I(double vI); double I() const; void J(double vJ); double J() const; void K(double vK); double K() const; double Dot(const Vector& rVector) const; // returns the dot product of this and rVector Vector Cross(const Vector& rVector) const; // returns the cross product of this and rVector Vector operator+ (Vector vRhs) const; // returns the sum of two vectors Vector operator- (Vector vRhs) const; // returns the difference of two vectors Point operator+ (Point vRhs) const; // returns the sum of a vector and a Point Vector operator* (double vRhs) const; // returns multiplication of a scalar with a vector Point ToPoint() const; // converts a vector to a point double Magnitude() const; private: double mI, mJ, mK; }; } // namespace igraph #endif leidenbase/src/vendor/simpleraytracer/Color.h0000644000176200001440000000156014447675376021117 0ustar liggesusers/** Color.h */ #ifndef COLOR_H #define COLOR_H namespace igraph { class Color { public: Color(); Color(double vRed, double vGreen, double vBlue, double vTransparent=1.0); ~Color(); Color operator* (double vRhs) const; // returns multiplication of a scalar with a vector Color operator+ (const Color& vRhs) const; // returns the addition of this color with another color void Red(double vRed); double Red() const; void Green(double vGreen); double Green() const; void Blue(double vBlue); double Blue() const; void Transparent(double vTransparent); double Transparent() const; unsigned char RedByte() const; unsigned char GreenByte() const; unsigned char BlueByte() const; unsigned char TransparentByte() const; private: unsigned char ByteValue(double vZeroToOne) const; double mRed, mGreen, mBlue, mTransparent; }; } // namespace igraph #endif leidenbase/src/vendor/simpleraytracer/Point.cpp0000644000176200001440000000253314447675376021466 0ustar liggesusers#include "Point.h" #include namespace igraph { Point::Point() { X(0.0); Y(0.0); Z(0.0); Name(0); } Point::Point(double vX, double vY, double vZ, int vName) { X(vX); Y(vY); Z(vZ); Name(vName); } Point::Point(double vX, double vY, double vZ) { X(vX); Y(vY); Z(vZ); Name(0); } Point::~Point() {} double Point::X() const { return mX; } void Point::X(double vX) { mX = vX; } double Point::Y() const { return mY; } void Point::Y(double vY) { mY = vY; } double Point::Z() const { return mZ; } void Point::Z(double vZ) { mZ = vZ; } int Point::Name() const { return mName; } void Point::Name(int vName) { mName = vName; } double Point::Distance(const Point& rPoint) const { return sqrt( (rPoint.X() - mX)*(rPoint.X() - mX) + (rPoint.Y() - mY)*(rPoint.Y() - mY) + (rPoint.Z() - mZ)*(rPoint.Z() - mZ) ); } bool Point::operator==(const Point& vRhs) const { bool result = true; /* if ( mX + .001 <= vRhs.X() ) result = false; if ( mX - .001 >= vRhs.X() ) result = false; if ( mY + .001 <= vRhs.Y() ) result = false; if ( mY - .001 >= vRhs.Y() ) result = false; if ( mZ + .001 <= vRhs.Z() ) result = false; if ( mZ - .001 >= vRhs.Z() ) result = false; */ if ( mX != vRhs.X() ) result = false; if ( mY != vRhs.Y() ) result = false; if ( mZ != vRhs.Z() ) result = false; return result; } } // namespace igraph leidenbase/src/vendor/simpleraytracer/Triangle.cpp0000644000176200001440000000515114447675376022141 0ustar liggesusers#include "Triangle.h" #include namespace igraph { Triangle::Triangle() {} Triangle::Triangle(const Point& rPoint1, const Point& rPoint2, const Point& rPoint3) { Type("Triangle"); mPoint1 = rPoint1; mPoint2 = rPoint2; mPoint3 = rPoint3; } Triangle::~Triangle() { } bool Triangle::Intersect(const Ray& vRay, Point& rIntersectPoint) const { Vector pointb_minus_pointa (mPoint1, mPoint2); Vector pointb_minus_pointc (mPoint1, mPoint3); /* Vector plane_normal = pointb_minus_pointa.Cross(pointb_minus_pointc); // get the plane normal facing the right way: Vector plane_normal_normalized = plane_normal.Normalize(); Vector triangle_to_ray_origin = Vector(mPoint1, vRay.Origin() ); triangle_to_ray_origin.NormalizeThis(); if ( plane_normal_normalized.Dot(triangle_to_ray_origin) < 0.0 ) { plane_normal = plane_normal * -1.0; plane_normal_normalized = plane_normal_normalized * -1.0; } // check that the ray is actually facing the triangle Vector ray_direction_normalized = vRay.Direction().Normalize(); if ( plane_normal_normalized.Dot(ray_direction_normalized) > 0.0 ) return false; */ Vector plane_normal = this->Normal(mPoint1, vRay.Origin()); Vector ray_direction_normalized = vRay.Direction().Normalize(); if ( plane_normal.IsSameDirection(ray_direction_normalized) ) return false; Vector b_minus_u (vRay.Origin(), mPoint2); double t = plane_normal.Dot(b_minus_u) / plane_normal.Dot(vRay.Direction()); Point p = (vRay.Direction() * t) + vRay.Origin(); Vector p_minus_a (mPoint1, p); Vector p_minus_b (mPoint2, p); Vector p_minus_c (mPoint3, p); Vector pointc_minus_pointb (mPoint2, mPoint3); Vector pointa_minus_pointc (mPoint3, mPoint1); double test1 = (pointb_minus_pointa.Cross(p_minus_a)).Dot(plane_normal); double test2 = (pointc_minus_pointb.Cross(p_minus_b)).Dot(plane_normal); double test3 = (pointa_minus_pointc.Cross(p_minus_c)).Dot(plane_normal); if ((test1 > 0 && test2 > 0 && test3 > 0) || (test1 < 0 && test2 < 0 && test3 < 0)) { rIntersectPoint = p; return true; } else return false; } Vector Triangle::Normal(const Point& rSurfacePoint, const Point& rOffSurface) const { Vector pointb_minus_pointa (mPoint1, mPoint2); Vector pointb_minus_pointc (mPoint1, mPoint3); Vector plane_normal = pointb_minus_pointa.Cross(pointb_minus_pointc).Normalize(); // get the plane normal facing the right way: Vector triangle_to_off_surface_point = Vector(mPoint1, rOffSurface ); triangle_to_off_surface_point.NormalizeThis(); if ( !plane_normal.IsSameDirection(triangle_to_off_surface_point) ) { plane_normal.ReverseDirection(); } return plane_normal; } } // namespace igraph leidenbase/src/vendor/simpleraytracer/RayTracer.h0000644000176200001440000000255614447675376021743 0ustar liggesusers/** RayTraceCanvas.h */ #ifndef RAY_TRACER_H #define RAY_TRACER_H #include #include "Point.h" #include "Shape.h" #include "Color.h" #include "Light.h" namespace igraph { class Image { public: int width, height; double *red, *green, *blue, *trans; }; class RayTracer { public: RayTracer(); ~RayTracer(); void RayTrace(Image &result); void AddShape(Shape* pShape); void AddLight(Light* pLight); void BackgroundColor(const Color& rBackgroundColor); void EyePoint(const Point& rEyePoint); void AmbientColor(const Color& rAmbient); void AmbientIntensity(double vAmbientIntensity); private: Color Render(const Ray& rRay, bool vIsReflecting = false, const Shape* pReflectingFrom = 0 ); // vEyeRay should be true if the ray we are tracing is a ray from the eye, otherwise it should be false Shape* QueryScene(const Ray& rRay, Point& rIntersectionPoint, bool vIsReflecting = false, const Shape* pReflectingFrom = 0); double Shade(const Shape* pShapeToShade, const Point& rPointOnShapeToShade); double Specular(const Shape* pShapeToShade, const Point& rPointOnShapeToShade, const Light* pLight); Color mBackgroundColor; Color mAmbientColor; Point mEyePoint; Color mSpecularColor; double mAmbientIntensity; ShapeList* mpShapes; LightList* mpLights; int mRecursions; int mRecursionLimit; int mAntiAliasDetail; }; } // namespace igraph #endif leidenbase/src/vendor/simpleraytracer/Shape.cpp0000644000176200001440000000402314447675376021431 0ustar liggesusers#include "Shape.h" #include "unit_limiter.h" namespace igraph { Shape::Shape() { mName = 0; mAmbientReflectivity = .6; mSpecularReflectivity = 0; mDiffuseReflectivity = 0; mSpecularSize = 64; } Shape::~Shape() {} int Shape::Name() const { return mName; } void Shape::Name(int vName) { mName = vName; } const Color& Shape::ShapeColor() const { return mShapeColor; } void Shape::ShapeColor(const Color& rColor) { mShapeColor = rColor; } double Shape::AmbientReflectivity() const { return mAmbientReflectivity; } double Shape::SpecularReflectivity() const { return mSpecularReflectivity; } double Shape::DiffuseReflectivity() const { return mDiffuseReflectivity; } void Shape::AmbientReflectivity(double rReflectivity) { mAmbientReflectivity = unit_limiter(rReflectivity); } void Shape::SpecularReflectivity(double rReflectivity) { mSpecularReflectivity = unit_limiter(rReflectivity); } void Shape::DiffuseReflectivity(double rReflectivity) { mDiffuseReflectivity = unit_limiter(rReflectivity); } Ray Shape::Reflect(const Point& rReflectFrom, const Ray& rIncidentRay) const { Ray result; // the reflected ray Vector result_direction; // the reflected direction vector Vector incident_unit = rIncidentRay.Direction().Normalize(); Vector normal = this->Normal(rReflectFrom, rIncidentRay.Origin() ); if ( !normal.IsSameDirection(incident_unit) ) normal.ReverseDirection(); // we want the normal in the same direction of the incident ray. result.Origin(rReflectFrom); result.Direction( normal*2.0*normal.Dot(incident_unit) - incident_unit ); /* if ( normal.Dot(rIncidentRay.Direction().Normalize()) < 0.0 ) normal.ReverseDirection(); result.Origin(rReflectFrom); result.Direction((normal*2.0) - rIncidentRay.Direction().Normalize()); */ return result; } const string& Shape::Type() const { return mType; } void Shape::Type(const string& rType) { mType = rType; } int Shape::SpecularSize() const { return mSpecularSize; } void Shape::SpecularSize(int vSpecularSize) { mSpecularSize = vSpecularSize; } } // namespace igraph leidenbase/src/vendor/simpleraytracer/Triangle.h0000644000176200001440000000073514447675376021611 0ustar liggesusers/** Triangle.h */ #ifndef TRIANGLE_H #define TRIANGLE_H #include "Shape.h" namespace igraph { class Triangle : public Shape { public: Triangle(); Triangle(const Point& rPoint1, const Point& rPoint2, const Point& rPoint3); ~Triangle(); virtual bool Intersect(const Ray& vRay, Point& vIntersectPoint) const; virtual Vector Normal(const Point& rSurfacePoint, const Point& rOffSurface) const; private: Point mPoint1, mPoint2, mPoint3; }; } // namespace igraph #endif leidenbase/src/vendor/simpleraytracer/RIgraphRay.cpp0000644000176200001440000000510214447675376022400 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library R interface. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph.h" #include "igraph_error.h" #include "RayTracer.h" #include "Sphere.h" #include "config.h" #include #include #include using namespace igraph; extern "C" { SEXP R_igraph_getsphere(SEXP pos, SEXP radius, SEXP color, SEXP bgcolor, SEXP lightpos, SEXP lightcolor, SEXP width, SEXP height) { /* All error checking is done at the R level */ int i; double *spos=REAL(pos); double *scolor=REAL(color); int no_lights=GET_LENGTH(lightpos); RayTracer* p_ray_tracer; Sphere * sphere; int swidth=INTEGER(width)[0]; int sheight=INTEGER(height)[0]; int nopixels=swidth * sheight; SEXP result, dim; Image image; p_ray_tracer = new RayTracer(); p_ray_tracer->EyePoint(Point(0,0,0)); for (i=0; iIntensity(1); light->LightColor(Color(lcol[0], lcol[1], lcol[2])); p_ray_tracer->AddLight(light); } sphere = new Sphere(Point(spos[0], spos[1], spos[2]), REAL(radius)[0]); sphere->ShapeColor(Color(scolor[0], scolor[1], scolor[2])); p_ray_tracer->AddShape(sphere); PROTECT(result=NEW_NUMERIC(nopixels * 4)); PROTECT(dim=NEW_INTEGER(3)); INTEGER(dim)[0]=swidth; INTEGER(dim)[1]=sheight; INTEGER(dim)[2]=4; SET_DIM(result, dim); image.width=swidth; image.height=sheight; image.red=REAL(result); image.green=image.red + nopixels; image.blue=image.green + nopixels; image.trans=image.blue + nopixels; p_ray_tracer->RayTrace(image); delete p_ray_tracer; UNPROTECT(2); return result; } } // extern C leidenbase/src/vendor/simpleraytracer/Ray.h0000644000176200001440000000071414447675376020574 0ustar liggesusers/** Ray.h */ #ifndef RAY_H #define RAY_H #include "RayVector.h" #include "Point.h" namespace igraph { class Ray { public: Ray(); Ray(const Point& rOrigin, const Vector& rDirection); Ray(const Point& rOrigin, const Point& rEndPoint); ~Ray(); void Origin(Point vPoint); const Point& Origin() const; const Vector& Direction() const; void Direction(Vector vDirection); private: Vector mDirection; Point mOrigin; }; } // namespace igraph #endif leidenbase/src/vendor/simpleraytracer/RayTracer.cpp0000644000176200001440000002016514447675376022272 0ustar liggesusers#include "RayTracer.h" #include "unit_limiter.h" #include #include namespace igraph { RayTracer::RayTracer() : mBackgroundColor(0,0,0,0), mAmbientColor(0,0,0), mEyePoint(0,0,0), mSpecularColor(1,1,1) { // begin settings mAmbientIntensity = .7; mRecursionLimit = 700; mAntiAliasDetail = 1; // end settings mRecursions = 0; mpShapes = new ShapeList; mpLights = new LightList; } RayTracer::~RayTracer() { ShapeListIterator iter1 = mpShapes->begin(); while ( iter1 != mpShapes->end() ) { delete *iter1; iter1++; } delete mpShapes; LightListIterator iter2 = mpLights->begin(); while ( iter2 != mpLights->end() ) { delete *iter2; iter2++; } delete mpLights; } void RayTracer::RayTrace(Image &result) { int mWidth=result.width; int mHeight=result.height; Ray eye_ray(mEyePoint,Vector(0,0,1)); Color draw_color; double i_inc, j_inc, anti_alias_i_inc, anti_alias_j_inc; // amount to increment the ray in each direction double i, j, anti_alias_i, anti_alias_j; // the i and j values of the ray int pixel_x, pixel_y, anti_alias_pixel_x, anti_alias_pixel_y; // the pixels being drawn double average_red_byte, average_green_byte, average_blue_byte, average_trans_byte; int anti_alias_count; // the number of anti aliases (used in averaging) int idx=0; i_inc = 2.0/(double)mWidth; j_inc = 2.0/(double)mHeight; anti_alias_i_inc = 1.0/(double)mAntiAliasDetail; anti_alias_j_inc = 1.0/(double)mAntiAliasDetail; pixel_y = 0; j = 1.0; for (; pixel_y < mHeight; j -= j_inc, pixel_y++) { pixel_x = 0; i = -1.0; for (; pixel_x < mWidth; i += i_inc, pixel_x++) { anti_alias_pixel_y = 0; anti_alias_j = 0.0; average_red_byte = 0; average_green_byte = 0; average_blue_byte = 0; average_trans_byte = 0; anti_alias_count = 0; for (; anti_alias_pixel_y < mAntiAliasDetail; anti_alias_j += anti_alias_j_inc, anti_alias_pixel_y++) { anti_alias_pixel_x = 0; anti_alias_i = 0.0; for (; anti_alias_pixel_x < mAntiAliasDetail; anti_alias_i += anti_alias_i_inc, anti_alias_pixel_x++) { anti_alias_count++; eye_ray.Direction( Vector(i+(anti_alias_i*i_inc),j+(anti_alias_j*j_inc),1.0) ); draw_color = Render(eye_ray); average_red_byte = average_red_byte + ((double)draw_color.RedByte() - average_red_byte)/(double)anti_alias_count; average_green_byte = average_green_byte + ((double)draw_color.GreenByte() - average_green_byte)/(double)anti_alias_count; average_blue_byte = average_blue_byte + ((double)draw_color.BlueByte() - average_blue_byte)/(double)anti_alias_count; average_trans_byte = average_trans_byte + ((double)draw_color.TransparentByte() - average_trans_byte)/(double)anti_alias_count; } } result.red [idx] = average_red_byte/255; result.green[idx] = average_green_byte/255; result.blue [idx] = average_blue_byte/255; result.trans[idx] = average_trans_byte/255; idx++; } } } Color RayTracer::Render(const Ray& rRay, bool vIsReflecting, const Shape* pReflectingFrom ) { mRecursions++; Shape* closest_shape; Point intersect_point; Color result; if (vIsReflecting) closest_shape = QueryScene(rRay, intersect_point, vIsReflecting, pReflectingFrom); else closest_shape = QueryScene(rRay, intersect_point); if (closest_shape == NULL && !vIsReflecting) { mRecursions = 0; return mBackgroundColor; } if (closest_shape == NULL && vIsReflecting) { mRecursions = 0; return mAmbientColor*mAmbientIntensity; } if ( mRecursions > mRecursionLimit ) { mRecursions = 0; return Color(0,0,0); // mAmbientColor*mAmbientIntensity; } result = closest_shape->ShapeColor()*Shade(closest_shape, intersect_point); Ray backwards_ray(intersect_point,rRay.Direction()*-1); if ( closest_shape->DiffuseReflectivity() > 0.0 ) result = result + (Render( closest_shape->Reflect(intersect_point,backwards_ray), true, closest_shape )*closest_shape->DiffuseReflectivity()); return (result + mSpecularColor); } double RayTracer::Shade(const Shape* pShapeToShade, const Point& rPointOnShapeToShade) { double intensity = mAmbientIntensity * pShapeToShade->AmbientReflectivity(); // the ambient intensity of the scene Ray light_ray; // the ray that goes from the intersection point to the light sources double dot_product; Shape* closest_shape; // the shape closest from the intersection point to the light source Point light_intersect; // the intersection point of the ray that goes from the intersection point to the light source light_ray.Origin(rPointOnShapeToShade); // lightRay. org= object. intersect; Ray light_ray_from_light; LightListIterator iter = mpLights->begin(); mSpecularColor.Red(0); mSpecularColor.Green(0); mSpecularColor.Blue(0); while ( iter != mpLights->end() ) // foreach light in LightList do { light_ray.Direction(Vector(rPointOnShapeToShade,(*iter)->LightPoint())); // lightRay. dir= light. dir light_ray_from_light.Origin((*iter)->LightPoint()); light_ray_from_light.Direction(Vector((*iter)->LightPoint(),rPointOnShapeToShade)); closest_shape = QueryScene(light_ray_from_light, light_intersect); if ( closest_shape == NULL || (closest_shape == pShapeToShade && light_ray.Direction().Dot(pShapeToShade->Normal(rPointOnShapeToShade, light_ray_from_light.Origin() )) >= 0.0 ) ) //if (QueryScene( lightRay)= NIL) { Vector normal_vector = pShapeToShade->Normal(rPointOnShapeToShade, Point() ); dot_product = normal_vector.Dot(light_ray.Direction().Normalize()); dot_product *= (*iter)->Intensity(); if (dot_product < 0.0) { if (pShapeToShade->Type() == "Triangle") dot_product = dot_product*-1.0; else dot_product = 0.0; } intensity = unit_limiter( intensity + dot_product ); if ( light_ray.Direction().Dot(pShapeToShade->Normal(rPointOnShapeToShade, light_ray_from_light.Origin() )) >= 0.0 ) { double specular = Specular(pShapeToShade, rPointOnShapeToShade, *iter); mSpecularColor = mSpecularColor + Color(specular,specular,specular); } } iter++; } return intensity; } double RayTracer::Specular(const Shape* pShapeToShade, const Point& rPointOnShapeToShade, const Light* pLight) { Ray reflected = pShapeToShade->Reflect(rPointOnShapeToShade,Ray(rPointOnShapeToShade, pLight->LightPoint())); Vector eye_vector(rPointOnShapeToShade, mEyePoint); Vector reflected_vector = reflected.Direction().Normalize(); eye_vector.NormalizeThis(); double dot_product = eye_vector.Dot(reflected_vector); int n = pShapeToShade->SpecularSize(); double specular_intensity = dot_product/(n - n*dot_product+ dot_product); return unit_limiter(specular_intensity*pLight->Intensity()); } Shape* RayTracer::QueryScene(const Ray& rRay, Point& rIntersectionPoint, bool vIsReflecting, const Shape* pReflectingFrom) { Shape* closest_shape = NULL; Point intersect_point; double closest_distance; double intersect_distance; bool found_intersection = false; ShapeListIterator iter = mpShapes->begin(); while ( iter != mpShapes->end() ) { if ( (*iter)->Intersect( rRay, intersect_point ) ) { intersect_distance = intersect_point.Distance(rRay.Origin()); if ( !found_intersection && (*iter) != pReflectingFrom) { found_intersection = true; rIntersectionPoint = intersect_point; closest_shape = *iter; closest_distance = intersect_distance; } else if ( intersect_distance < closest_distance && (*iter) != pReflectingFrom ) { rIntersectionPoint = intersect_point; closest_shape = *iter; closest_distance = intersect_distance; } } iter++; } return closest_shape; } void RayTracer::AddShape(Shape* pShape) { // should check if a shape with the same name already exists mpShapes->push_back(pShape); } void RayTracer::AddLight(Light* pLight) { // should check if a shape with the same name already exists mpLights->push_back(pLight); } void RayTracer::BackgroundColor(const Color& rBackgroundColor) { mBackgroundColor = rBackgroundColor; } void RayTracer::EyePoint(const Point& rEyePoint) { mEyePoint = rEyePoint; } void RayTracer::AmbientColor(const Color& rAmbientColor) { mAmbientColor = rAmbientColor; } void RayTracer::AmbientIntensity(double vAmbientIntensity) { mAmbientIntensity = unit_limiter(vAmbientIntensity); } } // namespace igraph leidenbase/src/vendor/simpleraytracer/Sphere.cpp0000644000176200001440000000246214447675376021624 0ustar liggesusers#include "Sphere.h" #include namespace igraph { Sphere::Sphere() {} Sphere::Sphere(Point vCenter, double vRadius) { Type("Sphere"); mCenter = vCenter; mRadius = vRadius; } Sphere::~Sphere() { } bool Sphere::Intersect(const Ray& vRay, Point& vIntersectPoint) const { Vector V; Vector EO(vRay.Origin(), mCenter); double v; double disc; double d; Vector E(Point(0,0,0), vRay.Origin()); // E = vector from origin to ray origin Vector P; mCenter.Distance(vRay.Origin()); //c = distance from eye to center of sphere V = vRay.Direction(); V.NormalizeThis(); v = EO.Dot(V); double v2 = V.Dot(EO.Normalize()); if (v2 >= 0.0) { disc = mRadius*mRadius - (EO.Dot(EO) - v*v); if (disc <= 0) return false; else { d = sqrt(disc); P = E + V*(v-d); vIntersectPoint = P.ToPoint(); return true; } } else return false; } Vector Sphere::Normal(const Point& rSurfacePoint, const Point& rOffSurface) const { // currently does not take rOffSurface point into account, // it should check if this point is inside the sphere, if it is // return a normal facing the center. Vector radius_vector (mCenter, rSurfacePoint); return (radius_vector.Normalize()); } double Sphere::Radius() const { return mRadius; } const Point& Sphere::Center() const { return mCenter; } } // namespace igraph leidenbase/src/vendor/simpleraytracer/unit_limiter.h0000644000176200001440000000021114447675376022535 0ustar liggesusers#ifndef ZERO_TO_ONE_H #define ZERO_TO_ONE_H namespace igraph { double unit_limiter(double vUnitDouble); } // namespace igraph #endif leidenbase/src/vendor/simpleraytracer/Shape.h0000644000176200001440000000302714447675376021101 0ustar liggesusers/** Shape.h */ #ifndef SHAPE_H #define SHAPE_H #include #include "Color.h" #include "Ray.h" #include "Point.h" #include using namespace std; namespace igraph { class Shape { public: Shape(); virtual ~Shape(); virtual bool Intersect(const Ray& rRay, Point& rIntersectPoint) const = 0; virtual Vector Normal(const Point& rSurfacePoint, const Point& rOffSurface) const = 0; // returns a normalized vector that is the normal of this shape from the surface point // it also takes the rOffSurface point into account, for example: // if rSurfacePoint is on top of a triangle, then the normal returned will be going up. Ray Reflect(const Point& rReflectFrom, const Ray& rRay) const; void Name(int vName); int Name() const; const Color& ShapeColor() const; void ShapeColor(const Color& rColor); double SpecularReflectivity() const; void SpecularReflectivity(double rReflectivity); double DiffuseReflectivity() const; void DiffuseReflectivity(double rReflectivity); double AmbientReflectivity() const; void AmbientReflectivity(double rReflectivity); int SpecularSize() const; void SpecularSize(int vSpecularSize); const string& Type() const; void Type(const string& rType); private: int mName; string mType; Color mShapeColor; double mSpecularReflectivity; // from 0 to 1 int mSpecularSize; // 1 to 64 double mDiffuseReflectivity; // from 0 to 1 double mAmbientReflectivity; // from 0 to 1 }; typedef list ShapeList; typedef list::iterator ShapeListIterator; } // namespace igraph #endif leidenbase/src/vendor/simpleraytracer/Sphere.h0000644000176200001440000000074214447675376021270 0ustar liggesusers/** Sphere.h */ #ifndef SPHERE_H #define SPHERE_H #include "Shape.h" namespace igraph { class Sphere : public Shape { public: Sphere(); Sphere(Point vCenter, double vRadius); ~Sphere(); virtual bool Intersect(const Ray& vRay, Point& vIntersectPoint) const; virtual Vector Normal(const Point& rSurfacePoint, const Point& rOffSurface) const; double Radius() const; const Point& Center() const; private: Point mCenter; double mRadius; }; } // namespace igraph #endif leidenbase/src/vendor/simpleraytracer/Point.h0000644000176200001440000000147314447675376021135 0ustar liggesusers/** this is a simple generic class representing a 3d point with a name. it also defines the PointList type, which is a linked list of Points */ #ifndef POINT_H #define POINT_H #include using namespace std; namespace igraph { class Point { public: Point(); // creates a point at the origin with name 0 Point(double vX, double vY, double vZ, int vName); Point(double vX, double vY, double vZ); ~Point(); double X() const; void X(double vX); double Y() const; void Y(double vY); double Z() const; void Z(double vZ); int Name() const; void Name(int vName); double Distance(const Point& rPoint) const; bool operator==(const Point& vRhs) const; private: double mX, mY, mZ; int mName; }; typedef list PointList; typedef list::iterator PointListIterator; } // namespace igraph #endif leidenbase/src/vendor/plfit/0000755000176200001440000000000014532173045015553 5ustar liggesusersleidenbase/src/vendor/plfit/lbfgs.h0000644000176200001440000007627614447675375017065 0ustar liggesusers/* * C library of Limited memory BFGS (L-BFGS). * * Copyright (c) 1990, Jorge Nocedal * Copyright (c) 2007-2010 Naoaki Okazaki * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* $Id: lbfgs.h 65 2010-01-29 12:19:16Z naoaki $ */ #ifndef __LBFGS_H__ #define __LBFGS_H__ #ifdef __cplusplus extern "C" { #endif/*__cplusplus*/ /* * The default precision of floating point values is 64bit (double). */ #ifndef LBFGS_FLOAT #define LBFGS_FLOAT 64 #endif/*LBFGS_FLOAT*/ /* * Activate optimization routines for IEEE754 floating point values. */ #ifndef LBFGS_IEEE_FLOAT #define LBFGS_IEEE_FLOAT 1 #endif/*LBFGS_IEEE_FLOAT*/ #if LBFGS_FLOAT == 32 typedef float lbfgsfloatval_t; #elif LBFGS_FLOAT == 64 typedef double lbfgsfloatval_t; #else #error "libLBFGS supports single (float; LBFGS_FLOAT = 32) or double (double; LBFGS_FLOAT=64) precision only." #endif /** * \addtogroup liblbfgs_api libLBFGS API * @{ * * The libLBFGS API. */ /** * Return values of lbfgs(). * * Roughly speaking, a negative value indicates an error. */ enum { /** L-BFGS reaches convergence. */ LBFGS_SUCCESS = 0, LBFGS_CONVERGENCE = 0, LBFGS_STOP, /** The initial variables already minimize the objective function. */ LBFGS_ALREADY_MINIMIZED, /** Unknown error. */ LBFGSERR_UNKNOWNERROR = -1024, /** Logic error. */ LBFGSERR_LOGICERROR, /** Insufficient memory. */ LBFGSERR_OUTOFMEMORY, /** The minimization process has been canceled. */ LBFGSERR_CANCELED, /** Invalid number of variables specified. */ LBFGSERR_INVALID_N, /** Invalid number of variables (for SSE) specified. */ LBFGSERR_INVALID_N_SSE, /** The array x must be aligned to 16 (for SSE). */ LBFGSERR_INVALID_X_SSE, /** Invalid parameter lbfgs_parameter_t::epsilon specified. */ LBFGSERR_INVALID_EPSILON, /** Invalid parameter lbfgs_parameter_t::past specified. */ LBFGSERR_INVALID_TESTPERIOD, /** Invalid parameter lbfgs_parameter_t::delta specified. */ LBFGSERR_INVALID_DELTA, /** Invalid parameter lbfgs_parameter_t::linesearch specified. */ LBFGSERR_INVALID_LINESEARCH, /** Invalid parameter lbfgs_parameter_t::max_step specified. */ LBFGSERR_INVALID_MINSTEP, /** Invalid parameter lbfgs_parameter_t::max_step specified. */ LBFGSERR_INVALID_MAXSTEP, /** Invalid parameter lbfgs_parameter_t::ftol specified. */ LBFGSERR_INVALID_FTOL, /** Invalid parameter lbfgs_parameter_t::wolfe specified. */ LBFGSERR_INVALID_WOLFE, /** Invalid parameter lbfgs_parameter_t::gtol specified. */ LBFGSERR_INVALID_GTOL, /** Invalid parameter lbfgs_parameter_t::xtol specified. */ LBFGSERR_INVALID_XTOL, /** Invalid parameter lbfgs_parameter_t::max_linesearch specified. */ LBFGSERR_INVALID_MAXLINESEARCH, /** Invalid parameter lbfgs_parameter_t::orthantwise_c specified. */ LBFGSERR_INVALID_ORTHANTWISE, /** Invalid parameter lbfgs_parameter_t::orthantwise_start specified. */ LBFGSERR_INVALID_ORTHANTWISE_START, /** Invalid parameter lbfgs_parameter_t::orthantwise_end specified. */ LBFGSERR_INVALID_ORTHANTWISE_END, /** The line-search step went out of the interval of uncertainty. */ LBFGSERR_OUTOFINTERVAL, /** A logic error occurred; alternatively, the interval of uncertainty became too small. */ LBFGSERR_INCORRECT_TMINMAX, /** A rounding error occurred; alternatively, no line-search step satisfies the sufficient decrease and curvature conditions. */ LBFGSERR_ROUNDING_ERROR, /** The line-search step became smaller than lbfgs_parameter_t::min_step. */ LBFGSERR_MINIMUMSTEP, /** The line-search step became larger than lbfgs_parameter_t::max_step. */ LBFGSERR_MAXIMUMSTEP, /** The line-search routine reaches the maximum number of evaluations. */ LBFGSERR_MAXIMUMLINESEARCH, /** The algorithm routine reaches the maximum number of iterations. */ LBFGSERR_MAXIMUMITERATION, /** Relative width of the interval of uncertainty is at most lbfgs_parameter_t::xtol. */ LBFGSERR_WIDTHTOOSMALL, /** A logic error (negative line-search step) occurred. */ LBFGSERR_INVALIDPARAMETERS, /** The current search direction increases the objective function value. */ LBFGSERR_INCREASEGRADIENT, }; /** * Line search algorithms. */ enum { /** The default algorithm (MoreThuente method). */ LBFGS_LINESEARCH_DEFAULT = 0, /** MoreThuente method proposd by More and Thuente. */ LBFGS_LINESEARCH_MORETHUENTE = 0, /** * Backtracking method with the Armijo condition. * The backtracking method finds the step length such that it satisfies * the sufficient decrease (Armijo) condition, * - f(x + a * d) <= f(x) + lbfgs_parameter_t::ftol * a * g(x)^T d, * * where x is the current point, d is the current search direction, and * a is the step length. */ LBFGS_LINESEARCH_BACKTRACKING_ARMIJO = 1, /** The backtracking method with the defualt (regular Wolfe) condition. */ LBFGS_LINESEARCH_BACKTRACKING = 2, /** * Backtracking method with regular Wolfe condition. * The backtracking method finds the step length such that it satisfies * both the Armijo condition (LBFGS_LINESEARCH_BACKTRACKING_ARMIJO) * and the curvature condition, * - g(x + a * d)^T d >= lbfgs_parameter_t::wolfe * g(x)^T d, * * where x is the current point, d is the current search direction, and * a is the step length. */ LBFGS_LINESEARCH_BACKTRACKING_WOLFE = 2, /** * Backtracking method with strong Wolfe condition. * The backtracking method finds the step length such that it satisfies * both the Armijo condition (LBFGS_LINESEARCH_BACKTRACKING_ARMIJO) * and the following condition, * - |g(x + a * d)^T d| <= lbfgs_parameter_t::wolfe * |g(x)^T d|, * * where x is the current point, d is the current search direction, and * a is the step length. */ LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE = 3, }; /** * L-BFGS optimization parameters. * Call lbfgs_parameter_init() function to initialize parameters to the * default values. */ typedef struct { /** * The number of corrections to approximate the inverse hessian matrix. * The L-BFGS routine stores the computation results of previous \ref m * iterations to approximate the inverse hessian matrix of the current * iteration. This parameter controls the size of the limited memories * (corrections). The default value is \c 6. Values less than \c 3 are * not recommended. Large values will result in excessive computing time. */ int m; /** * Epsilon for convergence test. * This parameter determines the accuracy with which the solution is to * be found. A minimization terminates when * ||g|| < \ref epsilon * max(1, ||x||), * where ||.|| denotes the Euclidean (L2) norm. The default value is * \c 1e-5. */ lbfgsfloatval_t epsilon; /** * Distance for delta-based convergence test. * This parameter determines the distance, in iterations, to compute * the rate of decrease of the objective function. If the value of this * parameter is zero, the library does not perform the delta-based * convergence test. The default value is \c 0. */ int past; /** * Delta for convergence test. * This parameter determines the minimum rate of decrease of the * objective function. The library stops iterations when the * following condition is met: * (f' - f) / f < \ref delta, * where f' is the objective value of \ref past iterations ago, and f is * the objective value of the current iteration. * The default value is \c 0. */ lbfgsfloatval_t delta; /** * The maximum number of iterations. * The lbfgs() function terminates an optimization process with * ::LBFGSERR_MAXIMUMITERATION status code when the iteration count * exceedes this parameter. Setting this parameter to zero continues an * optimization process until a convergence or error. The default value * is \c 0. */ int max_iterations; /** * The line search algorithm. * This parameter specifies a line search algorithm to be used by the * L-BFGS routine. */ int linesearch; /** * The maximum number of trials for the line search. * This parameter controls the number of function and gradients evaluations * per iteration for the line search routine. The default value is \c 20. */ int max_linesearch; /** * The minimum step of the line search routine. * The default value is \c 1e-20. This value need not be modified unless * the exponents are too large for the machine being used, or unless the * problem is extremely badly scaled (in which case the exponents should * be increased). */ lbfgsfloatval_t min_step; /** * The maximum step of the line search. * The default value is \c 1e+20. This value need not be modified unless * the exponents are too large for the machine being used, or unless the * problem is extremely badly scaled (in which case the exponents should * be increased). */ lbfgsfloatval_t max_step; /** * A parameter to control the accuracy of the line search routine. * The default value is \c 1e-4. This parameter should be greater * than zero and smaller than \c 0.5. */ lbfgsfloatval_t ftol; /** * A coefficient for the Wolfe condition. * This parameter is valid only when the backtracking line-search * algorithm is used with the Wolfe condition, * ::LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE or * ::LBFGS_LINESEARCH_BACKTRACKING_WOLFE . * The default value is \c 0.9. This parameter should be greater * the \ref ftol parameter and smaller than \c 1.0. */ lbfgsfloatval_t wolfe; /** * A parameter to control the accuracy of the line search routine. * The default value is \c 0.9. If the function and gradient * evaluations are inexpensive with respect to the cost of the * iteration (which is sometimes the case when solving very large * problems) it may be advantageous to set this parameter to a small * value. A typical small value is \c 0.1. This parameter shuold be * greater than the \ref ftol parameter (\c 1e-4) and smaller than * \c 1.0. */ lbfgsfloatval_t gtol; /** * The machine precision for floating-point values. * This parameter must be a positive value set by a client program to * estimate the machine precision. The line search routine will terminate * with the status code (::LBFGSERR_ROUNDING_ERROR) if the relative width * of the interval of uncertainty is less than this parameter. */ lbfgsfloatval_t xtol; /** * Coeefficient for the L1 norm of variables. * This parameter should be set to zero for standard minimization * problems. Setting this parameter to a positive value activates * Orthant-Wise Limited-memory Quasi-Newton (OWL-QN) method, which * minimizes the objective function F(x) combined with the L1 norm |x| * of the variables, {F(x) + C |x|}. This parameter is the coeefficient * for the |x|, i.e., C. As the L1 norm |x| is not differentiable at * zero, the library modifies function and gradient evaluations from * a client program suitably; a client program thus have only to return * the function value F(x) and gradients G(x) as usual. The default value * is zero. */ lbfgsfloatval_t orthantwise_c; /** * Start index for computing L1 norm of the variables. * This parameter is valid only for OWL-QN method * (i.e., \ref orthantwise_c != 0). This parameter b (0 <= b < N) * specifies the index number from which the library computes the * L1 norm of the variables x, * |x| := |x_{b}| + |x_{b+1}| + ... + |x_{N}| . * In other words, variables x_1, ..., x_{b-1} are not used for * computing the L1 norm. Setting b (0 < b < N), one can protect * variables, x_1, ..., x_{b-1} (e.g., a bias term of logistic * regression) from being regularized. The default value is zero. */ int orthantwise_start; /** * End index for computing L1 norm of the variables. * This parameter is valid only for OWL-QN method * (i.e., \ref orthantwise_c != 0). This parameter e (0 < e <= N) * specifies the index number at which the library stops computing the * L1 norm of the variables x, */ int orthantwise_end; } lbfgs_parameter_t; /** * Callback interface to provide objective function and gradient evaluations. * * The lbfgs() function call this function to obtain the values of objective * function and its gradients when needed. A client program must implement * this function to evaluate the values of the objective function and its * gradients, given current values of variables. * * @param instance The user data sent for lbfgs() function by the client. * @param x The current values of variables. * @param g The gradient vector. The callback function must compute * the gradient values for the current variables. * @param n The number of variables. * @param step The current step of the line search routine. * @retval lbfgsfloatval_t The value of the objective function for the current * variables. */ typedef lbfgsfloatval_t (*lbfgs_evaluate_t)( void *instance, const lbfgsfloatval_t *x, lbfgsfloatval_t *g, const int n, const lbfgsfloatval_t step ); /** * Callback interface to receive the progress of the optimization process. * * The lbfgs() function call this function for each iteration. Implementing * this function, a client program can store or display the current progress * of the optimization process. * * @param instance The user data sent for lbfgs() function by the client. * @param x The current values of variables. * @param g The current gradient values of variables. * @param fx The current value of the objective function. * @param xnorm The Euclidean norm of the variables. * @param gnorm The Euclidean norm of the gradients. * @param step The line-search step used for this iteration. * @param n The number of variables. * @param k The iteration count. * @param ls The number of evaluations called for this iteration. * @retval int Zero to continue the optimization process. Returning a * non-zero value will cancel the optimization process. */ typedef int (*lbfgs_progress_t)( void *instance, const lbfgsfloatval_t *x, const lbfgsfloatval_t *g, const lbfgsfloatval_t fx, const lbfgsfloatval_t xnorm, const lbfgsfloatval_t gnorm, const lbfgsfloatval_t step, int n, int k, int ls ); /* A user must implement a function compatible with ::lbfgs_evaluate_t (evaluation callback) and pass the pointer to the callback function to lbfgs() arguments. Similarly, a user can implement a function compatible with ::lbfgs_progress_t (progress callback) to obtain the current progress (e.g., variables, function value, ||G||, etc) and to cancel the iteration process if necessary. Implementation of a progress callback is optional: a user can pass \c NULL if progress notification is not necessary. In addition, a user must preserve two requirements: - The number of variables must be multiples of 16 (this is not 4). - The memory block of variable array ::x must be aligned to 16. This algorithm terminates an optimization when: ||G|| < \epsilon \cdot \max(1, ||x||) . In this formula, ||.|| denotes the Euclidean norm. */ /** * Start a L-BFGS optimization. * * @param n The number of variables. * @param x The array of variables. A client program can set * default values for the optimization and receive the * optimization result through this array. This array * must be allocated by ::lbfgs_malloc function * for libLBFGS built with SSE/SSE2 optimization routine * enabled. The library built without SSE/SSE2 * optimization does not have such a requirement. * @param ptr_fx The pointer to the variable that receives the final * value of the objective function for the variables. * This argument can be set to \c NULL if the final * value of the objective function is unnecessary. * @param proc_evaluate The callback function to provide function and * gradient evaluations given a current values of * variables. A client program must implement a * callback function compatible with \ref * lbfgs_evaluate_t and pass the pointer to the * callback function. * @param proc_progress The callback function to receive the progress * (the number of iterations, the current value of * the objective function) of the minimization * process. This argument can be set to \c NULL if * a progress report is unnecessary. * @param instance A user data for the client program. The callback * functions will receive the value of this argument. * @param param The pointer to a structure representing parameters for * L-BFGS optimization. A client program can set this * parameter to \c NULL to use the default parameters. * Call lbfgs_parameter_init() function to fill a * structure with the default values. * @retval int The status code. This function returns zero if the * minimization process terminates without an error. A * non-zero value indicates an error. */ int lbfgs( int n, lbfgsfloatval_t *x, lbfgsfloatval_t *ptr_fx, lbfgs_evaluate_t proc_evaluate, lbfgs_progress_t proc_progress, void *instance, lbfgs_parameter_t *param ); /** * Initialize L-BFGS parameters to the default values. * * Call this function to fill a parameter structure with the default values * and overwrite parameter values if necessary. * * @param param The pointer to the parameter structure. */ void lbfgs_parameter_init(lbfgs_parameter_t *param); /** * Allocate an array for variables. * * This function allocates an array of variables for the convenience of * ::lbfgs function; the function has a requreiemt for a variable array * when libLBFGS is built with SSE/SSE2 optimization routines. A user does * not have to use this function for libLBFGS built without SSE/SSE2 * optimization. * * @param n The number of variables. */ lbfgsfloatval_t* lbfgs_malloc(int n); /** * Free an array of variables. * * @param x The array of variables allocated by ::lbfgs_malloc * function. */ void lbfgs_free(lbfgsfloatval_t *x); /** @} */ #ifdef __cplusplus } #endif/*__cplusplus*/ /** @mainpage libLBFGS: a library of Limited-memory Broyden-Fletcher-Goldfarb-Shanno (L-BFGS) @section intro Introduction This library is a C port of the implementation of Limited-memory Broyden-Fletcher-Goldfarb-Shanno (L-BFGS) method written by Jorge Nocedal. The original FORTRAN source code is available at: http://www.ece.northwestern.edu/~nocedal/lbfgs.html The L-BFGS method solves the unconstrainted minimization problem,

    minimize F(x), x = (x1, x2, ..., xN),
only if the objective function F(x) and its gradient G(x) are computable. The well-known Newton's method requires computation of the inverse of the hessian matrix of the objective function. However, the computational cost for the inverse hessian matrix is expensive especially when the objective function takes a large number of variables. The L-BFGS method iteratively finds a minimizer by approximating the inverse hessian matrix by information from last m iterations. This innovation saves the memory storage and computational time drastically for large-scaled problems. Among the various ports of L-BFGS, this library provides several features: - Optimization with L1-norm (Orthant-Wise Limited-memory Quasi-Newton (OWL-QN) method): In addition to standard minimization problems, the library can minimize a function F(x) combined with L1-norm |x| of the variables, {F(x) + C |x|}, where C is a constant scalar parameter. This feature is useful for estimating parameters of sparse log-linear models (e.g., logistic regression and maximum entropy) with L1-regularization (or Laplacian prior). - Clean C code: Unlike C codes generated automatically by f2c (Fortran 77 into C converter), this port includes changes based on my interpretations, improvements, optimizations, and clean-ups so that the ported code would be well-suited for a C code. In addition to comments inherited from the original code, a number of comments were added through my interpretations. - Callback interface: The library receives function and gradient values via a callback interface. The library also notifies the progress of the optimization by invoking a callback function. In the original implementation, a user had to set function and gradient values every time the function returns for obtaining updated values. - Thread safe: The library is thread-safe, which is the secondary gain from the callback interface. - Cross platform. The source code can be compiled on Microsoft Visual Studio 2005, GNU C Compiler (gcc), etc. - Configurable precision: A user can choose single-precision (float) or double-precision (double) accuracy by changing ::LBFGS_FLOAT macro. - SSE/SSE2 optimization: This library includes SSE/SSE2 optimization (written in compiler intrinsics) for vector arithmetic operations on Intel/AMD processors. The library uses SSE for float values and SSE2 for double values. The SSE/SSE2 optimization routine is disabled by default. This library is used by: - CRFsuite: A fast implementation of Conditional Random Fields (CRFs) - Classias: A collection of machine-learning algorithms for classification - mlegp: an R package for maximum likelihood estimates for Gaussian processes - imaging2: the imaging2 class library - Algorithm::LBFGS - Perl extension for L-BFGS - YAP-LBFGS (an interface to call libLBFGS from YAP Prolog) @section download Download - Source code libLBFGS is distributed under the term of the MIT license. @section changelog History - Version 1.9 (2010-01-29): - Fixed a mistake in checking the validity of the parameters "ftol" and "wolfe"; this was discovered by Kevin S. Van Horn. - Version 1.8 (2009-07-13): - Accepted the patch submitted by Takashi Imamichi; the backtracking method now has three criteria for choosing the step length: - ::LBFGS_LINESEARCH_BACKTRACKING_ARMIJO: sufficient decrease (Armijo) condition only - ::LBFGS_LINESEARCH_BACKTRACKING_WOLFE: regular Wolfe condition (sufficient decrease condition + curvature condition) - ::LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE: strong Wolfe condition - Updated the documentation to explain the above three criteria. - Version 1.7 (2009-02-28): - Improved OWL-QN routines for stability. - Removed the support of OWL-QN method in MoreThuente algorithm because it accidentally fails in early stages of iterations for some objectives. Because of this change, the OW-LQN method must be used with the backtracking algorithm (::LBFGS_LINESEARCH_BACKTRACKING), or the library returns ::LBFGSERR_INVALID_LINESEARCH. - Renamed line search algorithms as follows: - ::LBFGS_LINESEARCH_BACKTRACKING: regular Wolfe condition. - ::LBFGS_LINESEARCH_BACKTRACKING_LOOSE: regular Wolfe condition. - ::LBFGS_LINESEARCH_BACKTRACKING_STRONG: strong Wolfe condition. - Source code clean-up. - Version 1.6 (2008-11-02): - Improved line-search algorithm with strong Wolfe condition, which was contributed by Takashi Imamichi. This routine is now default for ::LBFGS_LINESEARCH_BACKTRACKING. The previous line search algorithm with regular Wolfe condition is still available as ::LBFGS_LINESEARCH_BACKTRACKING_LOOSE. - Configurable stop index for L1-norm computation. A member variable ::lbfgs_parameter_t::orthantwise_end was added to specify the index number at which the library stops computing the L1 norm of the variables. This is useful to prevent some variables from being regularized by the OW-LQN method. - A sample program written in C++ (sample/sample.cpp). - Version 1.5 (2008-07-10): - Configurable starting index for L1-norm computation. A member variable ::lbfgs_parameter_t::orthantwise_start was added to specify the index number from which the library computes the L1 norm of the variables. This is useful to prevent some variables from being regularized by the OWL-QN method. - Fixed a zero-division error when the initial variables have already been a minimizer (reported by Takashi Imamichi). In this case, the library returns ::LBFGS_ALREADY_MINIMIZED status code. - Defined ::LBFGS_SUCCESS status code as zero; removed unused constants, LBFGSFALSE and LBFGSTRUE. - Fixed a compile error in an implicit down-cast. - Version 1.4 (2008-04-25): - Configurable line search algorithms. A member variable ::lbfgs_parameter_t::linesearch was added to choose either MoreThuente method (::LBFGS_LINESEARCH_MORETHUENTE) or backtracking algorithm (::LBFGS_LINESEARCH_BACKTRACKING). - Fixed a bug: the previous version did not compute psuedo-gradients properly in the line search routines for OWL-QN. This bug might quit an iteration process too early when the OWL-QN routine was activated (0 < ::lbfgs_parameter_t::orthantwise_c). - Configure script for POSIX environments. - SSE/SSE2 optimizations with GCC. - New functions ::lbfgs_malloc and ::lbfgs_free to use SSE/SSE2 routines transparently. It is uncessary to use these functions for libLBFGS built without SSE/SSE2 routines; you can still use any memory allocators if SSE/SSE2 routines are disabled in libLBFGS. - Version 1.3 (2007-12-16): - An API change. An argument was added to lbfgs() function to receive the final value of the objective function. This argument can be set to \c NULL if the final value is unnecessary. - Fixed a null-pointer bug in the sample code (reported by Takashi Imamichi). - Added build scripts for Microsoft Visual Studio 2005 and GCC. - Added README file. - Version 1.2 (2007-12-13): - Fixed a serious bug in orthant-wise L-BFGS. An important variable was used without initialization. - Version 1.1 (2007-12-01): - Implemented orthant-wise L-BFGS. - Implemented lbfgs_parameter_init() function. - Fixed several bugs. - API documentation. - Version 1.0 (2007-09-20): - Initial release. @section api Documentation - @ref liblbfgs_api "libLBFGS API" @section sample Sample code @include sample.c @section ack Acknowledgements The L-BFGS algorithm is described in: - Jorge Nocedal. Updating Quasi-Newton Matrices with Limited Storage. Mathematics of Computation, Vol. 35, No. 151, pp. 773--782, 1980. - Dong C. Liu and Jorge Nocedal. On the limited memory BFGS method for large scale optimization. Mathematical Programming B, Vol. 45, No. 3, pp. 503-528, 1989. The line search algorithms used in this implementation are described in: - John E. Dennis and Robert B. Schnabel. Numerical Methods for Unconstrained Optimization and Nonlinear Equations, Englewood Cliffs, 1983. - Jorge J. More and David J. Thuente. Line search algorithm with guaranteed sufficient decrease. ACM Transactions on Mathematical Software (TOMS), Vol. 20, No. 3, pp. 286-307, 1994. This library also implements Orthant-Wise Limited-memory Quasi-Newton (OWL-QN) method presented in: - Galen Andrew and Jianfeng Gao. Scalable training of L1-regularized log-linear models. In Proceedings of the 24th International Conference on Machine Learning (ICML 2007), pp. 33-40, 2007. Special thanks go to: - Yoshimasa Tsuruoka and Daisuke Okanohara for technical information about OWL-QN - Takashi Imamichi for the useful enhancements of the backtracking method Finally I would like to thank the original author, Jorge Nocedal, who has been distributing the effieicnt and explanatory implementation in an open source licence. @section reference Reference - L-BFGS by Jorge Nocedal. - Orthant-Wise Limited-memory Quasi-Newton Optimizer for L1-regularized Objectives by Galen Andrew. - C port (via f2c) by Taku Kudo. - C#/C++/Delphi/VisualBasic6 port in ALGLIB. - Computational Crystallography Toolbox includes scitbx::lbfgs. */ #endif/*__LBFGS_H__*/ leidenbase/src/vendor/plfit/rbinom.c0000644000176200001440000001305414447675375017232 0ustar liggesusers/* * Mathlib : A C Library of Special Functions * Copyright (C) 1998 Ross Ihaka * Copyright (C) 2000-2002 The R Core Team * Copyright (C) 2007 The R Foundation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ * * SYNOPSIS * * #include * double rbinom(double nin, double pp) * * DESCRIPTION * * Random variates from the binomial distribution. * * REFERENCE * * Kachitvichyanukul, V. and Schmeiser, B. W. (1988). * Binomial random variate generation. * Communications of the ACM 31, 216-222. * (Algorithm BTPEC). */ /* * Modifications for this file were performed by Tamas Nepusz to make it fit * better with plfit. The license of the original file applies to the * modifications as well. */ #include #include #include #include "plfit_sampling.h" #include "platform.h" #define repeat for(;;) double plfit_rbinom(double nin, double pp, plfit_mt_rng_t* rng) { /* FIXME: These should become THREAD_specific globals : */ static double c, fm, npq, p1, p2, p3, p4, qn; static double xl, xll, xlr, xm, xr; static double psave = -1.0; static int nsave = -1; static int m; double f, f1, f2, u, v, w, w2, x, x1, x2, z, z2; double p, q, np, g, r, al, alv, amaxp, ffm, ynorm; int i, ix, k, n; if (!isfinite(nin)) return NAN; r = floor(nin + 0.5); if (r != nin) return NAN; if (!isfinite(pp) || /* n=0, p=0, p=1 are not errors */ r < 0 || pp < 0. || pp > 1.) return NAN; if (r == 0 || pp == 0.) return 0; if (pp == 1.) return r; n = (int) r; p = fmin(pp, 1. - pp); q = 1. - p; np = n * p; r = p / q; g = r * (n + 1); /* Setup, perform only when parameters change [using static (globals): */ /* FIXING: Want this thread safe -- use as little (thread globals) as possible */ if (pp != psave || n != nsave) { psave = pp; nsave = n; if (np < 30.0) { /* inverse cdf logic for mean less than 30 */ qn = pow(q, (double) n); goto L_np_small; } else { ffm = np + p; m = (int) ffm; fm = m; npq = np * q; p1 = (int)(2.195 * sqrt(npq) - 4.6 * q) + 0.5; xm = fm + 0.5; xl = xm - p1; xr = xm + p1; c = 0.134 + 20.5 / (15.3 + fm); al = (ffm - xl) / (ffm - xl * p); xll = al * (1.0 + 0.5 * al); al = (xr - ffm) / (xr * q); xlr = al * (1.0 + 0.5 * al); p2 = p1 * (1.0 + c + c); p3 = p2 + c / xll; p4 = p3 + c / xlr; } } else if (n == nsave) { if (np < 30.0) goto L_np_small; } /*-------------------------- np = n*p >= 30 : ------------------- */ repeat { u = plfit_runif_01(rng) * p4; v = plfit_runif_01(rng); /* triangular region */ if (u <= p1) { ix = (int)(xm - p1 * v + u); goto finis; } /* parallelogram region */ if (u <= p2) { x = xl + (u - p1) / c; v = v * c + 1.0 - fabs(xm - x) / p1; if (v > 1.0 || v <= 0.) continue; ix = (int) x; } else { if (u > p3) { /* right tail */ ix = (int)(xr - log(v) / xlr); if (ix > n) continue; v = v * (u - p3) * xlr; } else {/* left tail */ ix = (int)(xl + log(v) / xll); if (ix < 0) continue; v = v * (u - p2) * xll; } } /* determine appropriate way to perform accept/reject test */ k = abs(ix - m); if (k <= 20 || k >= npq / 2 - 1) { /* explicit evaluation */ f = 1.0; if (m < ix) { for (i = m + 1; i <= ix; i++) f *= (g / i - r); } else if (m != ix) { for (i = ix + 1; i <= m; i++) f /= (g / i - r); } if (v <= f) goto finis; } else { /* squeezing using upper and lower bounds on log(f(x)) */ amaxp = (k / npq) * ((k * (k / 3. + 0.625) + 0.1666666666666) / npq + 0.5); ynorm = -k * k / (2.0 * npq); alv = log(v); if (alv < ynorm - amaxp) goto finis; if (alv <= ynorm + amaxp) { /* stirling's formula to machine accuracy */ /* for the final acceptance/rejection test */ x1 = ix + 1; f1 = fm + 1.0; z = n + 1 - fm; w = n - ix + 1.0; z2 = z * z; x2 = x1 * x1; f2 = f1 * f1; w2 = w * w; if (alv <= xm * log(f1 / x1) + (n - m + 0.5) * log(z / w) + (ix - m) * log(w * p / (x1 * q)) + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / f2) / f2) / f2) / f2) / f1 / 166320.0 + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / z2) / z2) / z2) / z2) / z / 166320.0 + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / x2) / x2) / x2) / x2) / x1 / 166320.0 + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / w2) / w2) / w2) / w2) / w / 166320.) goto finis; } } } L_np_small: /*---------------------- np = n*p < 30 : ------------------------- */ repeat { ix = 0; f = qn; u = plfit_runif_01(rng); repeat { if (u < f) goto finis; if (ix > 110) break; u -= f; ix++; f *= (g / ix - r); } } finis: if (psave > 0.5) ix = n - ix; return (double)ix; } leidenbase/src/vendor/plfit/gss.c0000644000176200001440000000662614453276447016541 0ustar liggesusers/* gss.c * * Copyright (C) 2012 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "plfit_error.h" #include "gss.h" #include "platform.h" /** * \def PHI * * The golden ratio, i.e. 1+sqrt(5)/2 */ #define PHI 1.618033988749895 /** * \def RESPHI * * Constant defined as 2 - \c PHI */ #define RESPHI 0.3819660112501051 /** * \const _defparam * * Default parameters for the GSS algorithm. */ static const gss_parameter_t _defparam = { /* .epsilon = */ DBL_MIN, /* .on_error = */ GSS_ERROR_STOP }; /** * Stores whether the last optimization run triggered a warning or not. */ static unsigned short int gss_i_warning_flag = 0; void gss_parameter_init(gss_parameter_t *param) { memcpy(param, &_defparam, sizeof(*param)); } unsigned short int gss_get_warning_flag(void) { return gss_i_warning_flag; } #define TERMINATE { \ if (_min) { \ *(_min) = min; \ } \ if (_fmin) { \ *(_fmin) = fmin; \ } \ } #define EVALUATE(x, fx) { \ fx = proc_evaluate(instance, x); \ if (fmin > fx) { \ min = x; \ fmin = fx; \ } \ if (proc_progress) { \ retval = proc_progress(instance, x, fx, min, fmin, \ (a < b) ? a : b, (a < b) ? b : a, k); \ if (retval) { \ TERMINATE; \ return PLFIT_SUCCESS; \ } \ } \ } int gss(double a, double b, double *_min, double *_fmin, gss_evaluate_t proc_evaluate, gss_progress_t proc_progress, void* instance, const gss_parameter_t *_param) { double c, d, min; double fa, fb, fc, fd, fmin; int k = 0; int retval; unsigned short int successful = 1; gss_parameter_t param = _param ? (*_param) : _defparam; gss_i_warning_flag = 0; if (a > b) { c = a; a = b; b = c; } min = a; fmin = proc_evaluate(instance, a); c = a + RESPHI*(b-a); EVALUATE(a, fa); EVALUATE(b, fb); EVALUATE(c, fc); if (fc >= fa || fc >= fb) { if (param.on_error == GSS_ERROR_STOP) { return PLFIT_FAILURE; } else { gss_i_warning_flag = 1; } } while (fabs(a-b) > param.epsilon) { k++; d = c + RESPHI*(b-c); EVALUATE(d, fd); if (fd >= fa || fd >= fb) { if (param.on_error == GSS_ERROR_STOP) { successful = 0; break; } else { gss_i_warning_flag = 1; } } if (fc <= fd) { b = a; a = d; } else { a = c; c = d; fc = fd; } } if (successful) { c = (a+b) / 2.0; k++; EVALUATE(c, fc); TERMINATE; } return successful ? PLFIT_SUCCESS : PLFIT_FAILURE; } leidenbase/src/vendor/plfit/sampling.c0000644000176200001440000002251614447675375017561 0ustar liggesusers/* sampling.c * * Copyright (C) 2012 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "igraph_random.h" #include "plfit_error.h" #include "plfit_sampling.h" #include "platform.h" inline double plfit_runif(double lo, double hi, plfit_mt_rng_t* rng) { if (rng == 0) { return RNG_UNIF(lo, hi); } return lo + plfit_mt_uniform_01(rng) * (hi-lo); } inline double plfit_runif_01(plfit_mt_rng_t* rng) { if (rng == 0) { return RNG_UNIF01(); } return plfit_mt_uniform_01(rng); } inline double plfit_rpareto(double xmin, double alpha, plfit_mt_rng_t* rng) { if (alpha <= 0 || xmin <= 0) return NAN; /* 1-u is used in the base here because we want to avoid the case of * sampling zero */ return pow(1-plfit_runif_01(rng), -1.0 / alpha) * xmin; } int plfit_rpareto_array(double xmin, double alpha, size_t n, plfit_mt_rng_t* rng, double* result) { double gamma; if (alpha <= 0 || xmin <= 0) return PLFIT_EINVAL; if (result == 0 || n == 0) return PLFIT_SUCCESS; gamma = -1.0 / alpha; while (n > 0) { /* 1-u is used in the base here because we want to avoid the case of * sampling zero */ *result = pow(1-plfit_runif_01(rng), gamma) * xmin; result++; n--; } return PLFIT_SUCCESS; } inline double plfit_rzeta(long int xmin, double alpha, plfit_mt_rng_t* rng) { double u, v, t; long int x; double alpha_minus_1 = alpha-1; double minus_1_over_alpha_minus_1 = -1.0 / (alpha-1); double b; double one_over_b_minus_1; if (alpha <= 0 || xmin < 1) return NAN; xmin = (long int) round(xmin); /* Rejection sampling for the win. We use Y=floor(U^{-1/alpha} * xmin) as the * envelope distribution, similarly to Chapter X.6 of Luc Devroye's book * (where xmin is assumed to be 1): http://luc.devroye.org/chapter_ten.pdf * * Some notes that should help me recover what I was doing: * * p_i = 1/zeta(alpha, xmin) * i^-alpha * q_i = (xmin/i)^{alpha-1} - (xmin/(i+1))^{alpha-1} * = (i/xmin)^{1-alpha} - ((i+1)/xmin)^{1-alpha} * = [i^{1-alpha} - (i+1)^{1-alpha}] / xmin^{1-alpha} * * p_i / q_i attains its maximum at xmin=i, so the rejection constant is: * * c = p_xmin / q_xmin * * We have to accept the sample if V <= (p_i / q_i) * (q_xmin / p_xmin) = * (i/xmin)^-alpha * [xmin^{1-alpha} - (xmin+1)^{1-alpha}] / [i^{1-alpha} - (i+1)^{1-alpha}] = * [xmin - xmin^alpha / (xmin+1)^{alpha-1}] / [i - i^alpha / (i+1)^{alpha-1}] = * xmin/i * [1-(xmin/(xmin+1))^{alpha-1}]/[1-(i/(i+1))^{alpha-1}] * * In other words (and substituting i with X, which is the same), * * V * (X/xmin) <= [1 - (1+1/xmin)^{1-alpha}] / [1 - (1+1/i)^{1-alpha}] * * Let b := (1+1/xmin)^{alpha-1} and let T := (1+1/i)^{alpha-1}. Then: * * V * (X/xmin) <= [(b-1)/b] / [(T-1)/T] * V * (X/xmin) * (T-1) / (b-1) <= T / b * * which is the same as in Devroye's book, except for the X/xmin term, and * the definition of b. */ b = pow(1 + 1.0/xmin, alpha_minus_1); one_over_b_minus_1 = 1.0/(b-1); do { do { u = plfit_runif_01(rng); v = plfit_runif_01(rng); /* 1-u is used in the base here because we want to avoid the case of * having zero in x */ x = (long int) floor(pow(1-u, minus_1_over_alpha_minus_1) * xmin); } while (x < xmin); t = pow((x+1.0)/x, alpha_minus_1); } while (v*x*(t-1)*one_over_b_minus_1*b > t*xmin); return x; } int plfit_rzeta_array(long int xmin, double alpha, size_t n, plfit_mt_rng_t* rng, double* result) { double u, v, t; long int x; double alpha_minus_1 = alpha-1; double minus_1_over_alpha_minus_1 = -1.0 / (alpha-1); double b, one_over_b_minus_1; if (alpha <= 0 || xmin < 1) return PLFIT_EINVAL; if (result == 0 || n == 0) return PLFIT_SUCCESS; /* See the comments in plfit_rzeta for an explanation of the algorithm * below. */ xmin = (long int) round(xmin); b = pow(1 + 1.0/xmin, alpha_minus_1); one_over_b_minus_1 = 1.0/(b-1); while (n > 0) { do { do { u = plfit_runif_01(rng); v = plfit_runif_01(rng); /* 1-u is used in the base here because we want to avoid the case of * having zero in x */ x = (long int) floor(pow(1-u, minus_1_over_alpha_minus_1) * xmin); } while (x < xmin); /* handles overflow as well */ t = pow((x+1.0)/x, alpha_minus_1); } while (v*x*(t-1)*one_over_b_minus_1*b > t*xmin); *result = x; if (x < 0) return PLFIT_EINVAL; result++; n--; } return PLFIT_SUCCESS; } int plfit_walker_alias_sampler_init(plfit_walker_alias_sampler_t* sampler, double* ps, size_t n) { double *p, *p2, *ps_end; double sum; long int *short_sticks, *long_sticks; long int num_short_sticks, num_long_sticks; long int i; if (n > LONG_MAX) { return PLFIT_EINVAL; } sampler->num_bins = (long int) n; ps_end = ps + n; /* Initialize indexes and probs */ sampler->indexes = (long int*)calloc(n, sizeof(long int)); if (sampler->indexes == 0) { return PLFIT_ENOMEM; } sampler->probs = (double*)calloc(n, sizeof(double)); if (sampler->probs == 0) { free(sampler->indexes); return PLFIT_ENOMEM; } /* Normalize the probability vector; count how many short and long sticks * are there initially */ for (sum = 0.0, p = ps; p != ps_end; p++) { sum += *p; } sum = n / sum; num_short_sticks = num_long_sticks = 0; for (p = ps, p2 = sampler->probs; p != ps_end; p++, p2++) { *p2 = *p * sum; if (*p2 < 1) { num_short_sticks++; } else if (*p2 > 1) { num_long_sticks++; } } /* Allocate space for short & long stick indexes */ long_sticks = (long int*)calloc(num_long_sticks, sizeof(long int)); if (long_sticks == 0) { free(sampler->probs); free(sampler->indexes); return PLFIT_ENOMEM; } short_sticks = (long int*)calloc(num_long_sticks, sizeof(long int)); if (short_sticks == 0) { free(sampler->probs); free(sampler->indexes); free(long_sticks); return PLFIT_ENOMEM; } /* Initialize short_sticks and long_sticks */ num_short_sticks = num_long_sticks = 0; for (i = 0, p = sampler->probs; i < n; i++, p++) { if (*p < 1) { short_sticks[num_short_sticks++] = i; } else if (*p > 1) { long_sticks[num_long_sticks++] = i; } } /* Prepare the index table */ while (num_short_sticks && num_long_sticks) { long int short_index, long_index; short_index = short_sticks[--num_short_sticks]; long_index = long_sticks[num_long_sticks-1]; sampler->indexes[short_index] = long_index; sampler->probs[long_index] = /* numerical stability */ (sampler->probs[long_index] + sampler->probs[short_index]) - 1; if (sampler->probs[long_index] < 1) { short_sticks[num_short_sticks++] = long_index; num_long_sticks--; } } /* Fix numerical stability issues */ while (num_long_sticks) { i = long_sticks[--num_long_sticks]; sampler->probs[i] = 1; } while (num_short_sticks) { i = short_sticks[--num_short_sticks]; sampler->probs[i] = 1; } free(short_sticks); free(long_sticks); return PLFIT_SUCCESS; } void plfit_walker_alias_sampler_destroy(plfit_walker_alias_sampler_t* sampler) { if (sampler->indexes) { free(sampler->indexes); sampler->indexes = 0; } if (sampler->probs) { free(sampler->probs); sampler->probs = 0; } } int plfit_walker_alias_sampler_sample(const plfit_walker_alias_sampler_t* sampler, long int *xs, size_t n, plfit_mt_rng_t* rng) { double u; long int j; long int *x; x = xs; if (rng == 0) { /* Using built-in RNG */ while (n > 0) { u = RNG_UNIF01(); j = RNG_INTEGER(0, sampler->num_bins - 1); *x = (u < sampler->probs[j]) ? j : sampler->indexes[j]; n--; x++; } } else { /* Using Mersenne Twister */ while (n > 0) { u = plfit_mt_uniform_01(rng); j = plfit_mt_random(rng) % sampler->num_bins; *x = (u < sampler->probs[j]) ? j : sampler->indexes[j]; n--; x++; } } return PLFIT_SUCCESS; } leidenbase/src/vendor/plfit/kolmogorov.c0000644000176200001440000000356114447675375020144 0ustar liggesusers/* kolmogorov.c * * Copyright (C) 2010-2011 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "kolmogorov.h" double plfit_kolmogorov(double z) { const double fj[4] = { -2, -8, -18, -32 }; const double w = 2.50662827; const double c1 = -1.2337005501361697; /* -pi^2 / 8 */ const double c2 = -11.103304951225528; /* 9*c1 */ const double c3 = -30.842513753404244; /* 25*c1 */ double u = fabs(z); double v; if (u < 0.2) return 1; if (u < 0.755) { v = 1.0 / (u*u); return 1 - w * (exp(c1*v) + exp(c2*v) + exp(c3*v)) / u; } if (u < 6.8116) { double r[4] = { 0, 0, 0, 0 }; long int maxj = (long int)(3.0 / u + 0.5); long int j; if (maxj < 1) maxj = 1; v = u*u; for (j = 0; j < maxj; j++) { r[j] = exp(fj[j] * v); } return 2*(r[0] - r[1] + r[2] - r[3]); } return 0; } double plfit_ks_test_one_sample_p(double d, size_t n) { return plfit_kolmogorov(d * sqrt((double) n)); } double plfit_ks_test_two_sample_p(double d, size_t n1, size_t n2) { return plfit_kolmogorov(d * sqrt(n1*n2 / ((double)(n1+n2)))); } leidenbase/src/vendor/plfit/plfit_sampling.h0000644000176200001440000001415714447675375020766 0ustar liggesusers/* plfit_sampling.h * * Copyright (C) 2012 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SAMPLING_H__ #define __SAMPLING_H__ #include #include "plfit_mt.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /** * Draws a sample from a binomial distribution with the given count and * probability values. * * This function is borrowed from R; see the corresponding license in * \c rbinom.c. The return value is always an integer. * * The function is \em not thread-safe. * * \param n the number of trials * \param p the success probability of each trial * \param rng the Mersenne Twister random number generator to use * \return the value drawn from the given binomial distribution. */ double plfit_rbinom(double n, double p, plfit_mt_rng_t* rng); /** * Draws a sample from a Pareto distribution with the given minimum value and * power-law exponent. * * \param xmin the minimum value of the distribution. Must be positive. * \param alpha the exponent. Must be positive * \param rng the Mersenne Twister random number generator to use * * \return the sample or NaN if one of the parameters is invalid */ extern double plfit_rpareto(double xmin, double alpha, plfit_mt_rng_t* rng); /** * Draws a given number of samples from a Pareto distribution with the given * minimum value and power-law exponent. * * \param xmin the minimum value of the distribution. Must be positive. * \param alpha the exponent. Must be positive * \param n the number of samples to draw * \param rng the Mersenne Twister random number generator to use * \param result the array where the result should be written. It must * have enough space to store n items * * \return \c PLFIT_EINVAL if one of the parameters is invalid, zero otherwise */ int plfit_rpareto_array(double xmin, double alpha, size_t n, plfit_mt_rng_t* rng, double* result); /** * Draws a sample from a zeta distribution with the given minimum value and * power-law exponent. * * \param xmin the minimum value of the distribution. Must be positive. * \param alpha the exponent. Must be positive * \param rng the Mersenne Twister random number generator to use * * \return the sample or NaN if one of the parameters is invalid */ extern double plfit_rzeta(long int xmin, double alpha, plfit_mt_rng_t* rng); /** * Draws a given number of samples from a zeta distribution with the given * minimum value and power-law exponent. * * \param xmin the minimum value of the distribution. Must be positive. * \param alpha the exponent. Must be positive * \param n the number of samples to draw * \param rng the Mersenne Twister random number generator to use * \param result the array where the result should be written. It must * have enough space to store n items * * \return \c PLFIT_EINVAL if one of the parameters is invalid, zero otherwise */ int plfit_rzeta_array(long int xmin, double alpha, size_t n, plfit_mt_rng_t* rng, double* result); /** * Draws a sample from a uniform distribution with the given lower and * upper bounds. * * The lower bound is inclusive, the uppoer bound is not. * * \param lo the lower bound * \param hi the upper bound * \param rng the Mersenne Twister random number generator to use * \return the value drawn from the given uniform distribution. */ extern double plfit_runif(double lo, double hi, plfit_mt_rng_t* rng); /** * Draws a sample from a uniform distribution over the [0; 1) interval. * * The interval is closed from the left and open from the right. * * \param rng the Mersenne Twister random number generator to use * \return the value drawn from the given uniform distribution. */ extern double plfit_runif_01(plfit_mt_rng_t* rng); /** * Random sampler using Walker's alias method. */ typedef struct { long int num_bins; /**< Number of bins */ long int* indexes; /**< Index of the "other" element in each bin */ double* probs; /**< Probability of drawing the "own" element from a bin */ } plfit_walker_alias_sampler_t; /** * \brief Initializes the sampler with item probabilities. * * \param sampler the sampler to initialize * \param ps pointer to an array containing a value proportional to the * sampling probability of each item in the set being sampled. * \param n the number of items in the array * \return error code */ int plfit_walker_alias_sampler_init(plfit_walker_alias_sampler_t* sampler, double* ps, size_t n); /** * \brief Destroys an initialized sampler and frees the allocated memory. * * \param sampler the sampler to destroy */ void plfit_walker_alias_sampler_destroy(plfit_walker_alias_sampler_t* sampler); /** * \brief Draws a given number of samples from the sampler and writes them * to a given array. * * \param sampler the sampler to use * \param xs pointer to an array where the sampled items should be * written * \param n the number of samples to draw * \param rng the Mersenne Twister random number generator to use * \return error code */ int plfit_walker_alias_sampler_sample(const plfit_walker_alias_sampler_t* sampler, long int* xs, size_t n, plfit_mt_rng_t* rng); __END_DECLS #endif leidenbase/src/vendor/plfit/plfit_error.c0000644000176200001440000000402314447675375020267 0ustar liggesusers/* error.c * * Copyright (C) 2010-2011 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "plfit_error.h" #include "platform.h" static char *plfit_i_error_strings[] = { "No error", "Failed", "Invalid value", "Underflow", "Overflow", "Not enough memory" }; #ifndef USING_R static plfit_error_handler_t* plfit_error_handler = plfit_error_handler_printignore; #else /* This is overwritten, anyway */ static plfit_error_handler_t* plfit_error_handler = plfit_error_handler_ignore; #endif const char* plfit_strerror(const int plfit_errno) { return plfit_i_error_strings[plfit_errno]; } plfit_error_handler_t* plfit_set_error_handler(plfit_error_handler_t* new_handler) { plfit_error_handler_t* old_handler = plfit_error_handler; plfit_error_handler = new_handler; return old_handler; } void plfit_error(const char *reason, const char *file, int line, int plfit_errno) { plfit_error_handler(reason, file, line, plfit_errno); } #ifndef USING_R void plfit_error_handler_printignore(const char *reason, const char *file, int line, int plfit_errno) { fprintf(stderr, "Error at %s:%i : %s, %s\n", file, line, reason, plfit_strerror(plfit_errno)); } #endif void plfit_error_handler_ignore(const char* reason, const char* file, int line, int plfit_errno) { } leidenbase/src/vendor/plfit/plfit_mt.h0000644000176200001440000000547214447675375017574 0ustar liggesusers/* plfit_mt.h * * Mersenne Twister random number generator, based on the implementation of * Michael Brundage (which has been placed in the public domain). * * Author: Tamas Nepusz (original by Michael Brundage) * * See the following URL for the original implementation: * http://www.qbrundage.com/michaelb/pubs/essays/random_number_generation.html * * This file has been placed in the public domain. */ #ifndef __PLFIT_MT_H__ #define __PLFIT_MT_H__ /* VS 2010, i.e. _MSC_VER == 1600, already has stdint.h */ #if defined(_MSC_VER) && _MSC_VER < 1600 # define uint32_t unsigned __int32 #else # include #endif #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS #define PLFIT_MT_LEN 624 /** * \def PLFIT_MT_RAND_MAX * * The maximum random number that \c plfit_mt_random() can generate. */ #define PLFIT_MT_RAND_MAX 0xFFFFFFFF /** * Struct that stores the internal state of a Mersenne Twister random number * generator. */ typedef struct { int mt_index; uint32_t mt_buffer[PLFIT_MT_LEN]; } plfit_mt_rng_t; /** * \brief Initializes a Mersenne Twister random number generator. * * The random number generator is seeded with random 32-bit numbers obtained * from the \em built-in random number generator using consecutive calls to * \c rand(). * * \param rng the random number generator to initialize */ void plfit_mt_init(plfit_mt_rng_t* rng); /** * \brief Initializes a Mersenne Twister random number generator, seeding it * from another one. * * The random number generator is seeded with random 32-bit numbers obtained * from another, initialized Mersenne Twister random number generator. * * \param rng the random number generator to initialize * \param seeder the random number generator that will seed the one being * initialized. When null, the random number generator will * be initialized from the built-in RNG as if \ref plfit_mt_init() * was called. */ void plfit_mt_init_from_rng(plfit_mt_rng_t* rng, plfit_mt_rng_t* seeder); /** * \brief Returns the next 32-bit random number from the given Mersenne Twister * random number generator. * * \param rng the random number generator to use * \return the next 32-bit random number from the generator */ uint32_t plfit_mt_random(plfit_mt_rng_t* rng); /** * \brief Returns a uniformly distributed double from the interval [0;1) * based on the next value of the given Mersenne Twister random number * generator. * * \param rng the random number generator to use * \return a uniformly distributed random number from the interval [0;1) */ double plfit_mt_uniform_01(plfit_mt_rng_t* rng); __END_DECLS #endif leidenbase/src/vendor/plfit/options.c0000644000176200001440000000336014447675375017436 0ustar liggesusers/* options.c * * Copyright (C) 2012 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "plfit_error.h" #include "plfit.h" const plfit_continuous_options_t plfit_continuous_default_options = { /* .finite_size_correction = */ 0, /* .xmin_method = */ PLFIT_DEFAULT_CONTINUOUS_METHOD, /* .p_value_method = */ PLFIT_DEFAULT_P_VALUE_METHOD, /* .p_value_precision = */ 0.01, /* .rng = */ 0 }; const plfit_discrete_options_t plfit_discrete_default_options = { /* .finite_size_correction = */ 0, /* .alpha_method = */ PLFIT_DEFAULT_DISCRETE_METHOD, /* .alpha = */ { /* .min = */ 1.01, /* .max = */ 5, /* .step = */ 0.01 }, /* .p_value_method = */ PLFIT_DEFAULT_P_VALUE_METHOD, /* .p_value_precision = */ 0.01, /* .rng = */ 0 }; int plfit_continuous_options_init(plfit_continuous_options_t* options) { *options = plfit_continuous_default_options; return PLFIT_SUCCESS; } int plfit_discrete_options_init(plfit_discrete_options_t* options) { *options = plfit_discrete_default_options; return PLFIT_SUCCESS; } leidenbase/src/vendor/plfit/arithmetic_ansi.h0000644000176200001440000000654714447675375021125 0ustar liggesusers/* * ANSI C implementation of vector operations. * * Copyright (c) 2007-2010 Naoaki Okazaki * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* $Id: arithmetic_ansi.h 65 2010-01-29 12:19:16Z naoaki $ */ #include #include #if LBFGS_FLOAT == 32 && LBFGS_IEEE_FLOAT #define fsigndiff(x, y) (((*(uint32_t*)(x)) ^ (*(uint32_t*)(y))) & 0x80000000U) #else #define fsigndiff(x, y) (*(x) * (*(y) / fabs(*(y))) < 0.) #endif/*LBFGS_IEEE_FLOAT*/ inline static void* vecalloc(size_t size) { void *memblock = malloc(size); if (memblock) { memset(memblock, 0, size); } return memblock; } inline static void vecfree(void *memblock) { free(memblock); } inline static void vecset(lbfgsfloatval_t *x, const lbfgsfloatval_t c, const int n) { int i; for (i = 0;i < n;++i) { x[i] = c; } } inline static void veccpy(lbfgsfloatval_t *y, const lbfgsfloatval_t *x, const int n) { int i; for (i = 0;i < n;++i) { y[i] = x[i]; } } inline static void vecncpy(lbfgsfloatval_t *y, const lbfgsfloatval_t *x, const int n) { int i; for (i = 0;i < n;++i) { y[i] = -x[i]; } } inline static void vecadd(lbfgsfloatval_t *y, const lbfgsfloatval_t *x, const lbfgsfloatval_t c, const int n) { int i; for (i = 0;i < n;++i) { y[i] += c * x[i]; } } inline static void vecdiff(lbfgsfloatval_t *z, const lbfgsfloatval_t *x, const lbfgsfloatval_t *y, const int n) { int i; for (i = 0;i < n;++i) { z[i] = x[i] - y[i]; } } inline static void vecscale(lbfgsfloatval_t *y, const lbfgsfloatval_t c, const int n) { int i; for (i = 0;i < n;++i) { y[i] *= c; } } inline static void vecmul(lbfgsfloatval_t *y, const lbfgsfloatval_t *x, const int n) { int i; for (i = 0;i < n;++i) { y[i] *= x[i]; } } inline static void vecdot(lbfgsfloatval_t* s, const lbfgsfloatval_t *x, const lbfgsfloatval_t *y, const int n) { int i; *s = 0.; for (i = 0;i < n;++i) { *s += x[i] * y[i]; } } inline static void vec2norm(lbfgsfloatval_t* s, const lbfgsfloatval_t *x, const int n) { vecdot(s, x, x, n); *s = (lbfgsfloatval_t)sqrt(*s); } inline static void vec2norminv(lbfgsfloatval_t* s, const lbfgsfloatval_t *x, const int n) { vec2norm(s, x, n); *s = (lbfgsfloatval_t)(1.0 / *s); } leidenbase/src/vendor/plfit/plfit_error.h0000644000176200001440000000473414447675375020305 0ustar liggesusers/* plfit_error.h * * Copyright (C) 2010-2011 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __ERROR_H__ #define __ERROR_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS enum { PLFIT_SUCCESS = 0, PLFIT_FAILURE = 1, PLFIT_EINVAL = 2, PLFIT_UNDRFLOW = 3, PLFIT_OVERFLOW = 4, PLFIT_ENOMEM = 5 }; #if (defined(__GNUC__) && GCC_VERSION_MAJOR >= 3) # define PLFIT_UNLIKELY(a) __builtin_expect((a), 0) # define PLFIT_LIKELY(a) __builtin_expect((a), 1) #else # define PLFIT_UNLIKELY(a) a # define PLFIT_LIKELY(a) a #endif #define PLFIT_CHECK(a) \ do {\ int plfit_i_ret=(a); \ if (PLFIT_UNLIKELY(plfit_i_ret != PLFIT_SUCCESS)) {\ return plfit_i_ret; \ } \ } while(0) #define PLFIT_ERROR(reason,plfit_errno) \ do {\ plfit_error (reason, __FILE__, __LINE__, plfit_errno) ; \ return plfit_errno ; \ } while (0) typedef void plfit_error_handler_t(const char*, const char*, int, int); extern plfit_error_handler_t plfit_error_handler_abort; extern plfit_error_handler_t plfit_error_handler_ignore; extern plfit_error_handler_t plfit_error_handler_printignore; plfit_error_handler_t* plfit_set_error_handler(plfit_error_handler_t* new_handler); void plfit_error(const char *reason, const char *file, int line, int plfit_errno); const char* plfit_strerror(const int plfit_errno); void plfit_error_handler_abort(const char *reason, const char *file, int line, int plfit_errno); void plfit_error_handler_ignore(const char *reason, const char *file, int line, int plfit_errno); void plfit_error_handler_printignore(const char *reason, const char *file, int line, int plfit_errno); __END_DECLS #endif /* __ERROR_H__ */ leidenbase/src/vendor/plfit/mt.c0000644000176200001440000000513714453276476016363 0ustar liggesusers/* mt.c * * Mersenne Twister random number generator, based on the implementation of * Michael Brundage (which has been placed in the public domain). * * Author: Tamas Nepusz (original by Michael Brundage) * * See the following URL for the original implementation: * http://www.qbrundage.com/michaelb/pubs/essays/random_number_generation.html * * This file has been placed in the public domain. */ #include #include "igraph_random.h" #include "plfit_mt.h" static uint16_t get_random_uint16(void) { return RNG_INT31() & 0xFFFF; } void plfit_mt_init(plfit_mt_rng_t* rng) { plfit_mt_init_from_rng(rng, 0); } void plfit_mt_init_from_rng(plfit_mt_rng_t* rng, plfit_mt_rng_t* seeder) { int i; if (seeder == 0) { for (i = 0; i < PLFIT_MT_LEN; i++) { /* RAND_MAX is guaranteed to be at least 32767, so we can use two * calls to rand() to produce a random 32-bit number */ rng->mt_buffer[i] = (get_random_uint16() << 16) + get_random_uint16(); } } else { for (i = 0; i < PLFIT_MT_LEN; i++) { rng->mt_buffer[i] = plfit_mt_random(seeder); } } rng->mt_index = 0; } #define MT_IA 397 #define MT_IB (PLFIT_MT_LEN - MT_IA) #define UPPER_MASK 0x80000000 #define LOWER_MASK 0x7FFFFFFF #define MATRIX_A 0x9908B0DF #define TWIST(b,i,j) ((b)[i] & UPPER_MASK) | ((b)[j] & LOWER_MASK) #define MAGIC(s) (((s)&1)*MATRIX_A) uint32_t plfit_mt_random(plfit_mt_rng_t* rng) { uint32_t * b = rng->mt_buffer; int idx = rng->mt_index; uint32_t s; int i; if (idx == PLFIT_MT_LEN * sizeof(uint32_t)) { idx = 0; i = 0; for (; i < MT_IB; i++) { s = TWIST(b, i, i+1); b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s); } for (; i < PLFIT_MT_LEN-1; i++) { s = TWIST(b, i, i+1); b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s); } s = TWIST(b, PLFIT_MT_LEN-1, 0); b[PLFIT_MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s); } rng->mt_index = idx + sizeof(uint32_t); return *(uint32_t *)((unsigned char *)b + idx); /* Matsumoto and Nishimura additionally confound the bits returned to the caller but this doesn't increase the randomness, and slows down the generator by as much as 25%. So I omit these operations here. r ^= (r >> 11); r ^= (r << 7) & 0x9D2C5680; r ^= (r << 15) & 0xEFC60000; r ^= (r >> 18); */ } double plfit_mt_uniform_01(plfit_mt_rng_t* rng) { return ((double)plfit_mt_random(rng)) / PLFIT_MT_RAND_MAX; } leidenbase/src/vendor/plfit/platform.h0000644000176200001440000000306414447675375017575 0ustar liggesusers/* platform.h * * Copyright (C) 2010-2011 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __PLATFORM_H__ #define __PLATFORM_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif #include __BEGIN_DECLS #ifdef _MSC_VER #include #define snprintf _snprintf #define inline __inline #ifndef isfinite # define isfinite(x) _finite(x) #endif extern double _plfit_fmin(double a, double b); extern double _plfit_round(double x); #define fmin _plfit_fmin #define round _plfit_round #endif /* _MSC_VER */ #ifndef isnan # define isnan(x) ((x) != (x)) #endif #ifndef INFINITY # define INFINITY (1.0/0.0) #endif #ifndef NAN # define NAN ((double)0.0 / (double)DBL_MIN) #endif __END_DECLS #endif /* __PLATFORM_H__ */ leidenbase/src/vendor/plfit/arithmetic_sse_double.h0000644000176200001440000002113614447675375022306 0ustar liggesusers/* * SSE2 implementation of vector oprations (64bit double). * * Copyright (c) 2007-2010 Naoaki Okazaki * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* $Id: arithmetic_sse_double.h 65 2010-01-29 12:19:16Z naoaki $ */ #include #if !defined(__APPLE__) #include #endif #include #if 1400 <= _MSC_VER #include #endif/*1400 <= _MSC_VER*/ #if HAVE_EMMINTRIN_H #include #endif/*HAVE_EMMINTRIN_H*/ inline static void* vecalloc(size_t size) { #ifdef _MSC_VER void *memblock = _aligned_malloc(size, 16); #elif defined(__APPLE__) /* Memory on Mac OS X is already aligned to 16 bytes */ void *memblock = malloc(size); #else void *memblock = memalign(16, size); #endif if (memblock != NULL) { memset(memblock, 0, size); } return memblock; } inline static void vecfree(void *memblock) { #ifdef _MSC_VER _aligned_free(memblock); #else free(memblock); #endif } #define fsigndiff(x, y) \ ((_mm_movemask_pd(_mm_set_pd(*(x), *(y))) + 1) & 0x002) #define vecset(x, c, n) \ { \ int i; \ __m128d XMM0 = _mm_set1_pd(c); \ for (i = 0;i < (n);i += 8) { \ _mm_store_pd((x)+i , XMM0); \ _mm_store_pd((x)+i+2, XMM0); \ _mm_store_pd((x)+i+4, XMM0); \ _mm_store_pd((x)+i+6, XMM0); \ } \ } #define veccpy(y, x, n) \ { \ int i; \ for (i = 0;i < (n);i += 8) { \ __m128d XMM0 = _mm_load_pd((x)+i ); \ __m128d XMM1 = _mm_load_pd((x)+i+2); \ __m128d XMM2 = _mm_load_pd((x)+i+4); \ __m128d XMM3 = _mm_load_pd((x)+i+6); \ _mm_store_pd((y)+i , XMM0); \ _mm_store_pd((y)+i+2, XMM1); \ _mm_store_pd((y)+i+4, XMM2); \ _mm_store_pd((y)+i+6, XMM3); \ } \ } #define vecncpy(y, x, n) \ { \ int i; \ for (i = 0;i < (n);i += 8) { \ __m128d XMM0 = _mm_setzero_pd(); \ __m128d XMM1 = _mm_setzero_pd(); \ __m128d XMM2 = _mm_setzero_pd(); \ __m128d XMM3 = _mm_setzero_pd(); \ __m128d XMM4 = _mm_load_pd((x)+i ); \ __m128d XMM5 = _mm_load_pd((x)+i+2); \ __m128d XMM6 = _mm_load_pd((x)+i+4); \ __m128d XMM7 = _mm_load_pd((x)+i+6); \ XMM0 = _mm_sub_pd(XMM0, XMM4); \ XMM1 = _mm_sub_pd(XMM1, XMM5); \ XMM2 = _mm_sub_pd(XMM2, XMM6); \ XMM3 = _mm_sub_pd(XMM3, XMM7); \ _mm_store_pd((y)+i , XMM0); \ _mm_store_pd((y)+i+2, XMM1); \ _mm_store_pd((y)+i+4, XMM2); \ _mm_store_pd((y)+i+6, XMM3); \ } \ } #define vecadd(y, x, c, n) \ { \ int i; \ __m128d XMM7 = _mm_set1_pd(c); \ for (i = 0;i < (n);i += 4) { \ __m128d XMM0 = _mm_load_pd((x)+i ); \ __m128d XMM1 = _mm_load_pd((x)+i+2); \ __m128d XMM2 = _mm_load_pd((y)+i ); \ __m128d XMM3 = _mm_load_pd((y)+i+2); \ XMM0 = _mm_mul_pd(XMM0, XMM7); \ XMM1 = _mm_mul_pd(XMM1, XMM7); \ XMM2 = _mm_add_pd(XMM2, XMM0); \ XMM3 = _mm_add_pd(XMM3, XMM1); \ _mm_store_pd((y)+i , XMM2); \ _mm_store_pd((y)+i+2, XMM3); \ } \ } #define vecdiff(z, x, y, n) \ { \ int i; \ for (i = 0;i < (n);i += 8) { \ __m128d XMM0 = _mm_load_pd((x)+i ); \ __m128d XMM1 = _mm_load_pd((x)+i+2); \ __m128d XMM2 = _mm_load_pd((x)+i+4); \ __m128d XMM3 = _mm_load_pd((x)+i+6); \ __m128d XMM4 = _mm_load_pd((y)+i ); \ __m128d XMM5 = _mm_load_pd((y)+i+2); \ __m128d XMM6 = _mm_load_pd((y)+i+4); \ __m128d XMM7 = _mm_load_pd((y)+i+6); \ XMM0 = _mm_sub_pd(XMM0, XMM4); \ XMM1 = _mm_sub_pd(XMM1, XMM5); \ XMM2 = _mm_sub_pd(XMM2, XMM6); \ XMM3 = _mm_sub_pd(XMM3, XMM7); \ _mm_store_pd((z)+i , XMM0); \ _mm_store_pd((z)+i+2, XMM1); \ _mm_store_pd((z)+i+4, XMM2); \ _mm_store_pd((z)+i+6, XMM3); \ } \ } #define vecscale(y, c, n) \ { \ int i; \ __m128d XMM7 = _mm_set1_pd(c); \ for (i = 0;i < (n);i += 4) { \ __m128d XMM0 = _mm_load_pd((y)+i ); \ __m128d XMM1 = _mm_load_pd((y)+i+2); \ XMM0 = _mm_mul_pd(XMM0, XMM7); \ XMM1 = _mm_mul_pd(XMM1, XMM7); \ _mm_store_pd((y)+i , XMM0); \ _mm_store_pd((y)+i+2, XMM1); \ } \ } #define vecmul(y, x, n) \ { \ int i; \ for (i = 0;i < (n);i += 8) { \ __m128d XMM0 = _mm_load_pd((x)+i ); \ __m128d XMM1 = _mm_load_pd((x)+i+2); \ __m128d XMM2 = _mm_load_pd((x)+i+4); \ __m128d XMM3 = _mm_load_pd((x)+i+6); \ __m128d XMM4 = _mm_load_pd((y)+i ); \ __m128d XMM5 = _mm_load_pd((y)+i+2); \ __m128d XMM6 = _mm_load_pd((y)+i+4); \ __m128d XMM7 = _mm_load_pd((y)+i+6); \ XMM4 = _mm_mul_pd(XMM4, XMM0); \ XMM5 = _mm_mul_pd(XMM5, XMM1); \ XMM6 = _mm_mul_pd(XMM6, XMM2); \ XMM7 = _mm_mul_pd(XMM7, XMM3); \ _mm_store_pd((y)+i , XMM4); \ _mm_store_pd((y)+i+2, XMM5); \ _mm_store_pd((y)+i+4, XMM6); \ _mm_store_pd((y)+i+6, XMM7); \ } \ } #if 3 <= __SSE__ /* Horizontal add with haddps SSE3 instruction. The work register (rw) is unused. */ #define __horizontal_sum(r, rw) \ r = _mm_hadd_ps(r, r); \ r = _mm_hadd_ps(r, r); #else /* Horizontal add with SSE instruction. The work register (rw) is used. */ #define __horizontal_sum(r, rw) \ rw = r; \ r = _mm_shuffle_ps(r, rw, _MM_SHUFFLE(1, 0, 3, 2)); \ r = _mm_add_ps(r, rw); \ rw = r; \ r = _mm_shuffle_ps(r, rw, _MM_SHUFFLE(2, 3, 0, 1)); \ r = _mm_add_ps(r, rw); #endif #define vecdot(s, x, y, n) \ { \ int i; \ __m128d XMM0 = _mm_setzero_pd(); \ __m128d XMM1 = _mm_setzero_pd(); \ __m128d XMM2, XMM3, XMM4, XMM5; \ for (i = 0;i < (n);i += 4) { \ XMM2 = _mm_load_pd((x)+i ); \ XMM3 = _mm_load_pd((x)+i+2); \ XMM4 = _mm_load_pd((y)+i ); \ XMM5 = _mm_load_pd((y)+i+2); \ XMM2 = _mm_mul_pd(XMM2, XMM4); \ XMM3 = _mm_mul_pd(XMM3, XMM5); \ XMM0 = _mm_add_pd(XMM0, XMM2); \ XMM1 = _mm_add_pd(XMM1, XMM3); \ } \ XMM0 = _mm_add_pd(XMM0, XMM1); \ XMM1 = _mm_shuffle_pd(XMM0, XMM0, _MM_SHUFFLE2(1, 1)); \ XMM0 = _mm_add_pd(XMM0, XMM1); \ _mm_store_sd((s), XMM0); \ } #define vec2norm(s, x, n) \ { \ int i; \ __m128d XMM0 = _mm_setzero_pd(); \ __m128d XMM1 = _mm_setzero_pd(); \ __m128d XMM2, XMM3, XMM4, XMM5; \ for (i = 0;i < (n);i += 4) { \ XMM2 = _mm_load_pd((x)+i ); \ XMM3 = _mm_load_pd((x)+i+2); \ XMM4 = XMM2; \ XMM5 = XMM3; \ XMM2 = _mm_mul_pd(XMM2, XMM4); \ XMM3 = _mm_mul_pd(XMM3, XMM5); \ XMM0 = _mm_add_pd(XMM0, XMM2); \ XMM1 = _mm_add_pd(XMM1, XMM3); \ } \ XMM0 = _mm_add_pd(XMM0, XMM1); \ XMM1 = _mm_shuffle_pd(XMM0, XMM0, _MM_SHUFFLE2(1, 1)); \ XMM0 = _mm_add_pd(XMM0, XMM1); \ XMM0 = _mm_sqrt_pd(XMM0); \ _mm_store_sd((s), XMM0); \ } #define vec2norminv(s, x, n) \ { \ int i; \ __m128d XMM0 = _mm_setzero_pd(); \ __m128d XMM1 = _mm_setzero_pd(); \ __m128d XMM2, XMM3, XMM4, XMM5; \ for (i = 0;i < (n);i += 4) { \ XMM2 = _mm_load_pd((x)+i ); \ XMM3 = _mm_load_pd((x)+i+2); \ XMM4 = XMM2; \ XMM5 = XMM3; \ XMM2 = _mm_mul_pd(XMM2, XMM4); \ XMM3 = _mm_mul_pd(XMM3, XMM5); \ XMM0 = _mm_add_pd(XMM0, XMM2); \ XMM1 = _mm_add_pd(XMM1, XMM3); \ } \ XMM2 = _mm_set1_pd(1.0); \ XMM0 = _mm_add_pd(XMM0, XMM1); \ XMM1 = _mm_shuffle_pd(XMM0, XMM0, _MM_SHUFFLE2(1, 1)); \ XMM0 = _mm_add_pd(XMM0, XMM1); \ XMM0 = _mm_sqrt_pd(XMM0); \ XMM2 = _mm_div_pd(XMM2, XMM0); \ _mm_store_sd((s), XMM2); \ } leidenbase/src/vendor/plfit/plfit.h0000644000176200001440000001136314447675375017070 0ustar liggesusers/* vim:set ts=4 sw=4 sts=4 et: */ /* plfit.h * * Copyright (C) 2010-2011 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __PLFIT_H__ #define __PLFIT_H__ #include #include "plfit_mt.h" #include "plfit_version.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef unsigned short int plfit_bool_t; typedef enum { PLFIT_LINEAR_ONLY, PLFIT_STRATIFIED_SAMPLING, PLFIT_GSS_OR_LINEAR, PLFIT_DEFAULT_CONTINUOUS_METHOD = PLFIT_STRATIFIED_SAMPLING } plfit_continuous_method_t; typedef enum { PLFIT_LBFGS, PLFIT_LINEAR_SCAN, PLFIT_PRETEND_CONTINUOUS, PLFIT_DEFAULT_DISCRETE_METHOD = PLFIT_LBFGS } plfit_discrete_method_t; typedef enum { PLFIT_P_VALUE_SKIP, PLFIT_P_VALUE_APPROXIMATE, PLFIT_P_VALUE_EXACT, PLFIT_DEFAULT_P_VALUE_METHOD = PLFIT_P_VALUE_EXACT } plfit_p_value_method_t; typedef struct _plfit_result_t { double alpha; /* fitted power-law exponent */ double xmin; /* cutoff where the power-law behaviour kicks in */ double L; /* log-likelihood of the sample */ double D; /* test statistic for the KS test */ double p; /* p-value of the KS test */ } plfit_result_t; /********** structure that holds the options of plfit **********/ typedef struct _plfit_continuous_options_t { plfit_bool_t finite_size_correction; plfit_continuous_method_t xmin_method; plfit_p_value_method_t p_value_method; double p_value_precision; plfit_mt_rng_t* rng; } plfit_continuous_options_t; typedef struct _plfit_discrete_options_t { plfit_bool_t finite_size_correction; plfit_discrete_method_t alpha_method; struct { double min; double max; double step; } alpha; plfit_p_value_method_t p_value_method; double p_value_precision; plfit_mt_rng_t* rng; } plfit_discrete_options_t; int plfit_continuous_options_init(plfit_continuous_options_t* options); int plfit_discrete_options_init(plfit_discrete_options_t* options); extern const plfit_continuous_options_t plfit_continuous_default_options; extern const plfit_discrete_options_t plfit_discrete_default_options; /********** continuous power law distribution fitting **********/ int plfit_log_likelihood_continuous(double* xs, size_t n, double alpha, double xmin, double* l); int plfit_estimate_alpha_continuous(double* xs, size_t n, double xmin, const plfit_continuous_options_t* options, plfit_result_t* result); int plfit_continuous(double* xs, size_t n, const plfit_continuous_options_t* options, plfit_result_t* result); /*********** discrete power law distribution fitting ***********/ int plfit_estimate_alpha_discrete(double* xs, size_t n, double xmin, const plfit_discrete_options_t* options, plfit_result_t *result); int plfit_log_likelihood_discrete(double* xs, size_t n, double alpha, double xmin, double* l); int plfit_discrete(double* xs, size_t n, const plfit_discrete_options_t* options, plfit_result_t* result); /***** resampling routines to generate synthetic replicates ****/ int plfit_resample_continuous(double* xs, size_t n, double alpha, double xmin, size_t num_samples, plfit_mt_rng_t* rng, double* result); int plfit_resample_discrete(double* xs, size_t n, double alpha, double xmin, size_t num_samples, plfit_mt_rng_t* rng, double* result); /******** calculating the p-value of a fitted model only *******/ int plfit_calculate_p_value_continuous(double* xs, size_t n, const plfit_continuous_options_t* options, plfit_bool_t xmin_fixed, plfit_result_t *result); int plfit_calculate_p_value_discrete(double* xs, size_t n, const plfit_discrete_options_t* options, plfit_bool_t xmin_fixed, plfit_result_t *result); /************* calculating descriptive statistics **************/ int plfit_moments(double* data, size_t n, double* mean, double* variance, double* skewness, double* kurtosis); __END_DECLS #endif /* __PLFIT_H__ */ leidenbase/src/vendor/plfit/hzeta.h0000644000176200001440000000567714447675375017100 0ustar liggesusers/* This file was imported from a private scientific library * based on GSL coined Home Scientific Libray (HSL) by its author * Jerome Benoit; this very material is itself inspired from the * material written by G. Jungan and distributed by GSL. * Ultimately, some modifications were done in order to render the * imported material independent from the rest of GSL. */ /* `hsl/hsl_sf_zeta.h' C header file // HSL - Home Scientific Library // Copyright (C) 2005-2018 Jerome Benoit // // HSL is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* For futher details, see its source conterpart src/hzeta.c */ /* Author: Jerome G. Benoit < jgmbenoit _at_ rezozer _dot_ net > */ #ifndef __HZETA_H__ #define __HZETA_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Hurwitz Zeta Function * zeta(s,q) = Sum[ (k+q)^(-s), {k,0,Infinity} ] * * s > 1.0, q > 0.0 */ double hsl_sf_hzeta(const double s, const double q); /* First Derivative of Hurwitz Zeta Function * zeta'(s,q) = - Sum[ Ln(k+q)/(k+q)^(s), {k,0,Infinity} ] * * s > 1.0, q > 0.0 */ double hsl_sf_hzeta_deriv(const double s, const double q); /* Second Derivative of Hurwitz Zeta Function * zeta''(s,q) = + Sum[ Ln(k+q)^2/(k+q)^(s), {k,0,Infinity} ] * * s > 1.0, q > 0.0 */ double hsl_sf_hzeta_deriv2(const double s, const double q); /* Logarithm of Hurwitz Zeta Function * lnzeta(s,q) = ln(zeta(s,q)) * * s > 1.0, q > 0.0 (and q >> 1) */ double hsl_sf_lnhzeta(const double s, const double q); /* Logarithmic Derivative of Hurwitz Zeta Function * lnzeta'(s,q) = zeta'(s,q)/zeta(s,q) * * s > 1.0, q > 0.0 (and q >> 1) */ double hsl_sf_lnhzeta_deriv(const double s, const double q); /* Logarithm and Logarithmic Derivative of Hurwitz Zeta Function: * nonredundant computation version: * - lnzeta(s,q) and lnzeta'(s,q) are stored in *deriv0 and *deriv1, respectively; * - the return value and the value stored in *deriv0 are the same; * - deriv0 and deriv1 must be effective pointers, that is, not the NULL pointer. * * s > 1.0, q > 0.0 (and q >> 1) */ double hsl_sf_lnhzeta_deriv_tuple(const double s, const double q, double * deriv0, double * deriv1); __END_DECLS #endif // __HZETA_H__ leidenbase/src/vendor/plfit/gss.h0000644000176200001440000001366014453276435016537 0ustar liggesusers/* gss.h * * Copyright (C) 2012 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSS_H__ #define __GSS_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /** * Enum specifying what the search should do when the function is not U-shaped. */ typedef enum { GSS_ERROR_STOP, /**< Stop and return an error code */ GSS_ERROR_WARN /**< Continue and set the warning flag */ } gss_error_handling_t; /** * Parameter settings for a golden section search. */ typedef struct { double epsilon; gss_error_handling_t on_error; } gss_parameter_t; /** * Callback interface to provide objective function evaluations for the golden * section search. * * The gss() function calls this function to obtain the values of the objective * function when needed. A client program must implement this function to evaluate * the value of the objective function, given the location. * * @param instance The user data sent for the gss() function by the client. * @param x The current value of the variable. * @retval double The value of the objective function for the current * variable. */ typedef double (*gss_evaluate_t)(void *instance, double x); /** * Callback interface to receive the progress of the optimization process for * the golden section search. * * The gss() function calls this function for each iteration. Implementing * this function, a client program can store or display the current progress * of the optimization process. * * @param instance The user data sent for the gss() function by the client. * @param x The current value of the variable. * @param fx The value of the objective function at x. * @param min The location of the minimum value of the objective * function found so far. * @param fmin The minimum value of the objective function found so far. * @param left The left side of the current bracket. * @param right The right side of the current bracket. * @param k The index of the current iteration. * @retval int Zero to continue the optimization process. Returning a * non-zero value will cancel the optimization process. */ typedef int (*gss_progress_t)(void *instance, double x, double fx, double min, double fmin, double left, double right, int k); /** * Start a golden section search optimization. * * @param a The left side of the bracket to start from * @param b The right side of the bracket to start from * @param min The pointer to the variable that receives the location of the * final value of the objective function. This argument can be set to * \c NULL if the location of the final value of the objective * function is unnecessary. * @param fmin The pointer to the variable that receives the final value of * the objective function. This argument can be st to \c NULL if the * final value of the objective function is unnecessary. * @param proc_evaluate The callback function to evaluate the objective * function at a given location. * @param proc_progress The callback function to receive the progress (the * last evaluated location, the value of the objective * function at that location, the width of the current * bracket, the minimum found so far and the step * count). This argument can be set to \c NULL if * a progress report is unnecessary. * @param instance A user data for the client program. The callback * functions will receive the value of this argument. * @param param The pointer to a structure representing parameters for * GSS algorithm. A client program can set this parameter * to \c NULL to use the default parameters. * Call the \ref gss_parameter_init() function to fill a * structure with the default values. * @retval int The status code. This function returns zero if the * minimization process terminates without an error. A * non-zero value indicates an error; in particular, * \c PLFIT_FAILURE means that the function is not * U-shaped. */ int gss(double a, double b, double *min, double *fmin, gss_evaluate_t proc_evaluate, gss_progress_t proc_progress, void* instance, const gss_parameter_t *_param); /** * Return the state of the warning flag. * * The warning flag is 1 if the last optimization was run on a function that * was not U-shaped. */ unsigned short int gss_get_warning_flag(void); /** * Initialize GSS parameters to the default values. * * Call this function to fill a parameter structure with the default values * and overwrite parameter values if necessary. * * @param param The pointer to the parameter structure. */ void gss_parameter_init(gss_parameter_t *param); __END_DECLS #endif /* __GSS_H__ */ leidenbase/src/vendor/plfit/arithmetic_sse_float.h0000644000176200001440000002122514447675375022140 0ustar liggesusers/* * SSE/SSE3 implementation of vector oprations (32bit float). * * Copyright (c) 2007-2010 Naoaki Okazaki * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* $Id: arithmetic_sse_float.h 65 2010-01-29 12:19:16Z naoaki $ */ #include #if !defined(__APPLE__) #include #endif #include #if 1400 <= _MSC_VER #include #endif/*_MSC_VER*/ #if HAVE_XMMINTRIN_H #include #endif/*HAVE_XMMINTRIN_H*/ #if LBFGS_FLOAT == 32 && LBFGS_IEEE_FLOAT #define fsigndiff(x, y) (((*(uint32_t*)(x)) ^ (*(uint32_t*)(y))) & 0x80000000U) #else #define fsigndiff(x, y) (*(x) * (*(y) / fabs(*(y))) < 0.) #endif/*LBFGS_IEEE_FLOAT*/ inline static void* vecalloc(size_t size) { void *memblock = _aligned_malloc(size, 16); if (memblock != NULL) { memset(memblock, 0, size); } return memblock; } inline static void vecfree(void *memblock) { _aligned_free(memblock); } #define vecset(x, c, n) \ { \ int i; \ __m128 XMM0 = _mm_set_ps1(c); \ for (i = 0;i < (n);i += 16) { \ _mm_store_ps((x)+i , XMM0); \ _mm_store_ps((x)+i+ 4, XMM0); \ _mm_store_ps((x)+i+ 8, XMM0); \ _mm_store_ps((x)+i+12, XMM0); \ } \ } #define veccpy(y, x, n) \ { \ int i; \ for (i = 0;i < (n);i += 16) { \ __m128 XMM0 = _mm_load_ps((x)+i ); \ __m128 XMM1 = _mm_load_ps((x)+i+ 4); \ __m128 XMM2 = _mm_load_ps((x)+i+ 8); \ __m128 XMM3 = _mm_load_ps((x)+i+12); \ _mm_store_ps((y)+i , XMM0); \ _mm_store_ps((y)+i+ 4, XMM1); \ _mm_store_ps((y)+i+ 8, XMM2); \ _mm_store_ps((y)+i+12, XMM3); \ } \ } #define vecncpy(y, x, n) \ { \ int i; \ const uint32_t mask = 0x80000000; \ __m128 XMM4 = _mm_load_ps1((float*)&mask); \ for (i = 0;i < (n);i += 16) { \ __m128 XMM0 = _mm_load_ps((x)+i ); \ __m128 XMM1 = _mm_load_ps((x)+i+ 4); \ __m128 XMM2 = _mm_load_ps((x)+i+ 8); \ __m128 XMM3 = _mm_load_ps((x)+i+12); \ XMM0 = _mm_xor_ps(XMM0, XMM4); \ XMM1 = _mm_xor_ps(XMM1, XMM4); \ XMM2 = _mm_xor_ps(XMM2, XMM4); \ XMM3 = _mm_xor_ps(XMM3, XMM4); \ _mm_store_ps((y)+i , XMM0); \ _mm_store_ps((y)+i+ 4, XMM1); \ _mm_store_ps((y)+i+ 8, XMM2); \ _mm_store_ps((y)+i+12, XMM3); \ } \ } #define vecadd(y, x, c, n) \ { \ int i; \ __m128 XMM7 = _mm_set_ps1(c); \ for (i = 0;i < (n);i += 8) { \ __m128 XMM0 = _mm_load_ps((x)+i ); \ __m128 XMM1 = _mm_load_ps((x)+i+4); \ __m128 XMM2 = _mm_load_ps((y)+i ); \ __m128 XMM3 = _mm_load_ps((y)+i+4); \ XMM0 = _mm_mul_ps(XMM0, XMM7); \ XMM1 = _mm_mul_ps(XMM1, XMM7); \ XMM2 = _mm_add_ps(XMM2, XMM0); \ XMM3 = _mm_add_ps(XMM3, XMM1); \ _mm_store_ps((y)+i , XMM2); \ _mm_store_ps((y)+i+4, XMM3); \ } \ } #define vecdiff(z, x, y, n) \ { \ int i; \ for (i = 0;i < (n);i += 16) { \ __m128 XMM0 = _mm_load_ps((x)+i ); \ __m128 XMM1 = _mm_load_ps((x)+i+ 4); \ __m128 XMM2 = _mm_load_ps((x)+i+ 8); \ __m128 XMM3 = _mm_load_ps((x)+i+12); \ __m128 XMM4 = _mm_load_ps((y)+i ); \ __m128 XMM5 = _mm_load_ps((y)+i+ 4); \ __m128 XMM6 = _mm_load_ps((y)+i+ 8); \ __m128 XMM7 = _mm_load_ps((y)+i+12); \ XMM0 = _mm_sub_ps(XMM0, XMM4); \ XMM1 = _mm_sub_ps(XMM1, XMM5); \ XMM2 = _mm_sub_ps(XMM2, XMM6); \ XMM3 = _mm_sub_ps(XMM3, XMM7); \ _mm_store_ps((z)+i , XMM0); \ _mm_store_ps((z)+i+ 4, XMM1); \ _mm_store_ps((z)+i+ 8, XMM2); \ _mm_store_ps((z)+i+12, XMM3); \ } \ } #define vecscale(y, c, n) \ { \ int i; \ __m128 XMM7 = _mm_set_ps1(c); \ for (i = 0;i < (n);i += 8) { \ __m128 XMM0 = _mm_load_ps((y)+i ); \ __m128 XMM1 = _mm_load_ps((y)+i+4); \ XMM0 = _mm_mul_ps(XMM0, XMM7); \ XMM1 = _mm_mul_ps(XMM1, XMM7); \ _mm_store_ps((y)+i , XMM0); \ _mm_store_ps((y)+i+4, XMM1); \ } \ } #define vecmul(y, x, n) \ { \ int i; \ for (i = 0;i < (n);i += 16) { \ __m128 XMM0 = _mm_load_ps((x)+i ); \ __m128 XMM1 = _mm_load_ps((x)+i+ 4); \ __m128 XMM2 = _mm_load_ps((x)+i+ 8); \ __m128 XMM3 = _mm_load_ps((x)+i+12); \ __m128 XMM4 = _mm_load_ps((y)+i ); \ __m128 XMM5 = _mm_load_ps((y)+i+ 4); \ __m128 XMM6 = _mm_load_ps((y)+i+ 8); \ __m128 XMM7 = _mm_load_ps((y)+i+12); \ XMM4 = _mm_mul_ps(XMM4, XMM0); \ XMM5 = _mm_mul_ps(XMM5, XMM1); \ XMM6 = _mm_mul_ps(XMM6, XMM2); \ XMM7 = _mm_mul_ps(XMM7, XMM3); \ _mm_store_ps((y)+i , XMM4); \ _mm_store_ps((y)+i+ 4, XMM5); \ _mm_store_ps((y)+i+ 8, XMM6); \ _mm_store_ps((y)+i+12, XMM7); \ } \ } #if 3 <= __SSE__ /* Horizontal add with haddps SSE3 instruction. The work register (rw) is unused. */ #define __horizontal_sum(r, rw) \ r = _mm_hadd_ps(r, r); \ r = _mm_hadd_ps(r, r); #else /* Horizontal add with SSE instruction. The work register (rw) is used. */ #define __horizontal_sum(r, rw) \ rw = r; \ r = _mm_shuffle_ps(r, rw, _MM_SHUFFLE(1, 0, 3, 2)); \ r = _mm_add_ps(r, rw); \ rw = r; \ r = _mm_shuffle_ps(r, rw, _MM_SHUFFLE(2, 3, 0, 1)); \ r = _mm_add_ps(r, rw); #endif #define vecdot(s, x, y, n) \ { \ int i; \ __m128 XMM0 = _mm_setzero_ps(); \ __m128 XMM1 = _mm_setzero_ps(); \ __m128 XMM2, XMM3, XMM4, XMM5; \ for (i = 0;i < (n);i += 8) { \ XMM2 = _mm_load_ps((x)+i ); \ XMM3 = _mm_load_ps((x)+i+4); \ XMM4 = _mm_load_ps((y)+i ); \ XMM5 = _mm_load_ps((y)+i+4); \ XMM2 = _mm_mul_ps(XMM2, XMM4); \ XMM3 = _mm_mul_ps(XMM3, XMM5); \ XMM0 = _mm_add_ps(XMM0, XMM2); \ XMM1 = _mm_add_ps(XMM1, XMM3); \ } \ XMM0 = _mm_add_ps(XMM0, XMM1); \ __horizontal_sum(XMM0, XMM1); \ _mm_store_ss((s), XMM0); \ } #define vec2norm(s, x, n) \ { \ int i; \ __m128 XMM0 = _mm_setzero_ps(); \ __m128 XMM1 = _mm_setzero_ps(); \ __m128 XMM2, XMM3; \ for (i = 0;i < (n);i += 8) { \ XMM2 = _mm_load_ps((x)+i ); \ XMM3 = _mm_load_ps((x)+i+4); \ XMM2 = _mm_mul_ps(XMM2, XMM2); \ XMM3 = _mm_mul_ps(XMM3, XMM3); \ XMM0 = _mm_add_ps(XMM0, XMM2); \ XMM1 = _mm_add_ps(XMM1, XMM3); \ } \ XMM0 = _mm_add_ps(XMM0, XMM1); \ __horizontal_sum(XMM0, XMM1); \ XMM2 = XMM0; \ XMM1 = _mm_rsqrt_ss(XMM0); \ XMM3 = XMM1; \ XMM1 = _mm_mul_ss(XMM1, XMM1); \ XMM1 = _mm_mul_ss(XMM1, XMM3); \ XMM1 = _mm_mul_ss(XMM1, XMM0); \ XMM1 = _mm_mul_ss(XMM1, _mm_set_ss(-0.5f)); \ XMM3 = _mm_mul_ss(XMM3, _mm_set_ss(1.5f)); \ XMM3 = _mm_add_ss(XMM3, XMM1); \ XMM3 = _mm_mul_ss(XMM3, XMM2); \ _mm_store_ss((s), XMM3); \ } #define vec2norminv(s, x, n) \ { \ int i; \ __m128 XMM0 = _mm_setzero_ps(); \ __m128 XMM1 = _mm_setzero_ps(); \ __m128 XMM2, XMM3; \ for (i = 0;i < (n);i += 16) { \ XMM2 = _mm_load_ps((x)+i ); \ XMM3 = _mm_load_ps((x)+i+4); \ XMM2 = _mm_mul_ps(XMM2, XMM2); \ XMM3 = _mm_mul_ps(XMM3, XMM3); \ XMM0 = _mm_add_ps(XMM0, XMM2); \ XMM1 = _mm_add_ps(XMM1, XMM3); \ } \ XMM0 = _mm_add_ps(XMM0, XMM1); \ __horizontal_sum(XMM0, XMM1); \ XMM2 = XMM0; \ XMM1 = _mm_rsqrt_ss(XMM0); \ XMM3 = XMM1; \ XMM1 = _mm_mul_ss(XMM1, XMM1); \ XMM1 = _mm_mul_ss(XMM1, XMM3); \ XMM1 = _mm_mul_ss(XMM1, XMM0); \ XMM1 = _mm_mul_ss(XMM1, _mm_set_ss(-0.5f)); \ XMM3 = _mm_mul_ss(XMM3, _mm_set_ss(1.5f)); \ XMM3 = _mm_add_ss(XMM3, XMM1); \ _mm_store_ss((s), XMM3); \ } leidenbase/src/vendor/plfit/plfit.c0000644000176200001440000012442114447675375017063 0ustar liggesusers/* vim:set ts=4 sw=4 sts=4 et: */ /* plfit.c * * Copyright (C) 2010-2011 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include "plfit_error.h" #include "gss.h" #include "lbfgs.h" #include "platform.h" #include "plfit.h" #include "kolmogorov.h" #include "plfit_sampling.h" #include "hzeta.h" /* #define PLFIT_DEBUG */ #define DATA_POINTS_CHECK \ if (n <= 0) { \ PLFIT_ERROR("no data points", PLFIT_EINVAL); \ } #define XMIN_CHECK_ZERO \ if (xmin <= 0) { \ PLFIT_ERROR("xmin must be greater than zero", PLFIT_EINVAL); \ } #define XMIN_CHECK_ONE \ if (xmin < 1) { \ PLFIT_ERROR("xmin must be at least 1", PLFIT_EINVAL); \ } static int plfit_i_resample_continuous(double* xs_head, size_t num_smaller, size_t n, double alpha, double xmin, size_t num_samples, plfit_mt_rng_t* rng, double* result); static int plfit_i_resample_discrete(double* xs_head, size_t num_smaller, size_t n, double alpha, double xmin, size_t num_samples, plfit_mt_rng_t* rng, double* result); static int double_comparator(const void *a, const void *b) { const double *da = (const double*)a; const double *db = (const double*)b; return (*da > *db) - (*da < *db); } static int plfit_i_copy_and_sort(double* xs, size_t n, double** result) { *result = (double*)malloc(sizeof(double) * n); if (*result == 0) { PLFIT_ERROR("cannot create sorted copy of input data", PLFIT_ENOMEM); } memcpy(*result, xs, sizeof(double) * n); qsort(*result, n, sizeof(double), double_comparator); return PLFIT_SUCCESS; } /** * Given an unsorted array of doubles, counts how many elements there are that * are smaller than a given value. * * \param begin pointer to the beginning of the array * \param end pointer to the first element after the end of the array * \param xmin the threshold value * * \return the nubmer of elements in the array that are smaller than the given * value. */ static size_t count_smaller(double* begin, double* end, double xmin) { double* p; size_t counter = 0; for (p = begin; p < end; p++) { if (*p < xmin) { counter++; } } return counter; } /** * Given an unsorted array of doubles, return another array that contains the * elements that are smaller than a given value * * \param begin pointer to the beginning of the array * \param end pointer to the first element after the end of the array * \param xmin the threshold value * \param result_length if not \c NULL, the number of unique elements in the * given array is returned here * * \return pointer to the head of the new array or 0 if there is not enough * memory */ static double* extract_smaller(double* begin, double* end, double xmin, size_t* result_length) { size_t counter = count_smaller(begin, end, xmin); double *p, *result; result = calloc(counter, sizeof(double)); if (result == 0) return 0; for (p = result; begin < end; begin++) { if (*begin < xmin) { *p = *begin; p++; } } if (result_length) { *result_length = counter; } return result; } /** * Given a sorted array of doubles, return another array that contains pointers * into the array for the start of each block of identical elements. * * \param begin pointer to the beginning of the array * \param end pointer to the first element after the end of the array * \param result_length if not \c NULL, the number of unique elements in the * given array is returned here. It is left unchanged if * the function returns with an error. * * \return pointer to the head of the new array or 0 if there is not enough * memory */ static double** unique_element_pointers(double* begin, double* end, size_t* result_length) { double* ptr = begin; double** result; double prev_x; size_t num_elts = 15; size_t used_elts = 0; /* Special case: empty array */ if (begin == end) { result = calloc(1, sizeof(double*)); if (result != 0) { result[0] = 0; if (result_length != 0) { *result_length = 0; } } return result; } /* Allocate initial result array, including the guard element */ result = calloc(num_elts+1, sizeof(double*)); if (result == 0) return 0; prev_x = *begin; result[used_elts++] = begin; /* Process the input array */ for (ptr = begin+1; ptr < end; ptr++) { if (*ptr == prev_x) continue; /* New block found */ if (used_elts >= num_elts) { /* Array full; allocate a new chunk */ num_elts = num_elts*2 + 1; result = realloc(result, sizeof(double*) * (num_elts+1)); if (result == 0) return 0; } /* Store the new element */ result[used_elts++] = ptr; prev_x = *ptr; } /* Calculate the result length */ if (result_length != 0) { *result_length = used_elts; } /* Add the guard entry to the end of the result */ result[used_elts++] = 0; return result; } static void plfit_i_perform_finite_size_correction(plfit_result_t* result, size_t n) { result->alpha = result->alpha * (n-1) / n + 1.0 / n; } /********** Continuous power law distribution fitting **********/ static void plfit_i_logsum_less_than_continuous(double* begin, double* end, double xmin, double* result, size_t* m) { double logsum = 0.0; size_t count = 0; for (; begin != end; begin++) { if (*begin >= xmin) { count++; logsum += log(*begin / xmin); } } *m = count; *result = logsum; } static double plfit_i_logsum_continuous(double* begin, double* end, double xmin) { double logsum = 0.0; for (; begin != end; begin++) logsum += log(*begin / xmin); return logsum; } static int plfit_i_estimate_alpha_continuous(double* xs, size_t n, double xmin, double* alpha) { double result; size_t m; XMIN_CHECK_ZERO; plfit_i_logsum_less_than_continuous(xs, xs+n, xmin, &result, &m); if (m == 0) { PLFIT_ERROR("no data point was larger than xmin", PLFIT_EINVAL); } *alpha = 1 + m / result; return PLFIT_SUCCESS; } static int plfit_i_estimate_alpha_continuous_sorted(double* xs, size_t n, double xmin, double* alpha) { double* end = xs+n; XMIN_CHECK_ZERO; for (; xs != end && *xs < xmin; xs++); if (xs == end) { PLFIT_ERROR("no data point was larger than xmin", PLFIT_EINVAL); } *alpha = 1 + (end-xs) / plfit_i_logsum_continuous(xs, end, xmin); return PLFIT_SUCCESS; } static int plfit_i_ks_test_continuous(double* xs, double* xs_end, const double alpha, const double xmin, double* D) { /* Assumption: xs is sorted and cut off at xmin so the first element is * always larger than or equal to xmin. */ double result = 0, n; int m = 0; n = xs_end - xs; while (xs < xs_end) { double d = fabs(1-pow(xmin / *xs, alpha-1) - m / n); if (d > result) result = d; xs++; m++; } *D = result; return PLFIT_SUCCESS; } static int plfit_i_calculate_p_value_continuous(double* xs, size_t n, const plfit_continuous_options_t *options, plfit_bool_t xmin_fixed, plfit_result_t *result) { long int num_trials; long int successes = 0; double *xs_head; size_t num_smaller; plfit_continuous_options_t options_no_p_value = *options; int retval = PLFIT_SUCCESS; if (options->p_value_method == PLFIT_P_VALUE_SKIP) { result->p = NAN; return PLFIT_SUCCESS; } if (options->p_value_method == PLFIT_P_VALUE_APPROXIMATE) { num_smaller = count_smaller(xs, xs + n, result->xmin); result->p = plfit_ks_test_one_sample_p(result->D, n - num_smaller); return PLFIT_SUCCESS; } options_no_p_value.p_value_method = PLFIT_P_VALUE_SKIP; num_trials = (long int)(0.25 / options->p_value_precision / options->p_value_precision); if (num_trials <= 0) { PLFIT_ERROR("invalid p-value precision", PLFIT_EINVAL); } /* Extract the head of xs that contains elements smaller than xmin */ xs_head = extract_smaller(xs, xs+n, result->xmin, &num_smaller); if (xs_head == 0) PLFIT_ERROR("cannot calculate exact p-value", PLFIT_ENOMEM); #ifdef _OPENMP #pragma omp parallel #endif { /* Parallel section starts here. If we are compiling using OpenMP, each * thread will use its own RNG that is seeded from the master RNG. If * we are compiling without OpenMP, there is only one thread and it uses * the master RNG. This section must be critical to ensure that only one * thread is using the master RNG at the same time. */ #ifdef _OPENMP plfit_mt_rng_t private_rng; #endif plfit_mt_rng_t *p_rng; double *ys; long int i; plfit_result_t result_synthetic; #ifdef _OPENMP #pragma omp critical { p_rng = &private_rng; plfit_mt_init_from_rng(p_rng, options->rng); } #else p_rng = options->rng; #endif /* Allocate memory to sample into */ ys = calloc(n, sizeof(double)); if (ys == 0) { retval = PLFIT_ENOMEM; } else { /* The main for loop starts here. */ #ifdef _OPENMP #pragma omp for reduction(+:successes) #endif for (i = 0; i < num_trials; i++) { plfit_i_resample_continuous(xs_head, num_smaller, n, result->alpha, result->xmin, n, p_rng, ys); if (xmin_fixed) { plfit_estimate_alpha_continuous(ys, n, result->xmin, &options_no_p_value, &result_synthetic); } else { plfit_continuous(ys, n, &options_no_p_value, &result_synthetic); } if (result_synthetic.D > result->D) successes++; } free(ys); } /* End of parallelized part */ } free(xs_head); if (retval == PLFIT_SUCCESS) { result->p = successes / ((double)num_trials); } else { PLFIT_ERROR("cannot calculate exact p-value", retval); } return retval; } int plfit_log_likelihood_continuous(double* xs, size_t n, double alpha, double xmin, double* L) { double logsum, c; size_t m; if (alpha <= 1) { PLFIT_ERROR("alpha must be greater than one", PLFIT_EINVAL); } XMIN_CHECK_ZERO; c = (alpha - 1) / xmin; plfit_i_logsum_less_than_continuous(xs, xs+n, xmin, &logsum, &m); *L = -alpha * logsum + log(c) * m; return PLFIT_SUCCESS; } int plfit_estimate_alpha_continuous_sorted(double* xs, size_t n, double xmin, const plfit_continuous_options_t* options, plfit_result_t *result) { double *begin, *end; if (!options) options = &plfit_continuous_default_options; begin = xs; end = xs + n; while (begin < end && *begin < xmin) begin++; PLFIT_CHECK(plfit_i_estimate_alpha_continuous_sorted(begin, end-begin, xmin, &result->alpha)); PLFIT_CHECK(plfit_i_ks_test_continuous(begin, end, result->alpha, xmin, &result->D)); if (options->finite_size_correction) plfit_i_perform_finite_size_correction(result, end-begin); result->xmin = xmin; PLFIT_CHECK(plfit_log_likelihood_continuous(begin, end-begin, result->alpha, result->xmin, &result->L)); PLFIT_CHECK(plfit_i_calculate_p_value_continuous(xs, n, options, 1, result)); return PLFIT_SUCCESS; } int plfit_estimate_alpha_continuous(double* xs, size_t n, double xmin, const plfit_continuous_options_t* options, plfit_result_t *result) { double *xs_copy; if (!options) options = &plfit_continuous_default_options; PLFIT_CHECK(plfit_i_copy_and_sort(xs, n, &xs_copy)); PLFIT_CHECK(plfit_estimate_alpha_continuous_sorted(xs_copy, n, xmin, options, result)); free(xs_copy); return PLFIT_SUCCESS; } typedef struct { double *begin; /**< Pointer to the beginning of the array holding the data */ double *end; /**< Pointer to after the end of the array holding the data */ double **probes; /**< Pointers to the elements of the array that will be probed */ size_t num_probes; /**< Number of probes */ plfit_result_t last; /**< Result of the last evaluation */ } plfit_continuous_xmin_opt_data_t; static double plfit_i_continuous_xmin_opt_evaluate(void* instance, double x) { plfit_continuous_xmin_opt_data_t* data = (plfit_continuous_xmin_opt_data_t*)instance; double* begin = data->probes[(long int)x]; data->last.xmin = *begin; #ifdef PLFIT_DEBUG printf("Trying with probes[%ld] = %.4f\n", (long int)x, *begin); #endif plfit_i_estimate_alpha_continuous_sorted(begin, data->end-begin, *begin, &data->last.alpha); plfit_i_ks_test_continuous(begin, data->end, data->last.alpha, *begin, &data->last.D); return data->last.D; } static int plfit_i_continuous_xmin_opt_progress(void* instance, double x, double fx, double min, double fmin, double left, double right, int k) { #ifdef PLFIT_DEBUG printf("Iteration #%d: [%.4f; %.4f), x=%.4f, fx=%.4f, min=%.4f, fmin=%.4f\n", k, left, right, x, fx, min, fmin); #endif /* Continue only if `left' and `right' point to different integers */ return (int)left == (int)right; } static int plfit_i_continuous_xmin_opt_linear_scan( plfit_continuous_xmin_opt_data_t* opt_data, plfit_result_t* best_result, size_t* best_n) { /* this must be signed because OpenMP with Windows MSVC needs signed for * loop index variables. ssize_t will not work because that is a POSIX * extension */ ptrdiff_t i = 0; /* initialize to work around incorrect warning issued by Clang 9.0 */ plfit_result_t global_best_result; size_t global_best_n; /* Prepare some variables */ global_best_n = 0; global_best_result.D = DBL_MAX; global_best_result.xmin = 0; global_best_result.alpha = 0; /* Due to the OpenMP parallelization, we do things as follows. Each * OpenMP thread will search for the best D-score on its own and store * the result in a private local_best_result variable. The end of the * parallel block contains a critical section that threads will enter * one by one and compare their private local_best_result with a * global_best that is shared among the threads. */ #ifdef _OPENMP #pragma omp parallel shared(global_best_result, global_best_n) private(i) firstprivate(opt_data) #endif { /* These variables are private since they are declared within the * parallel block */ plfit_result_t local_best_result; plfit_continuous_xmin_opt_data_t local_opt_data = *opt_data; size_t local_best_n; /* Initialize the local_best_result and local_best_n variables */ local_best_n = 0; local_best_result.D = DBL_MAX; local_best_result.xmin = 0; local_best_result.alpha = 0; local_best_result.p = NAN; local_best_result.L = NAN; /* The range of the for loop below is divided among the threads. * nowait means that there will be no implicit barrier at the end * of the loop so threads that get there earlier can enter the * critical section without waiting for the others */ #ifdef _OPENMP #pragma omp for nowait schedule(dynamic,10) #endif for (i = 0; i < local_opt_data.num_probes-1; i++) { plfit_i_continuous_xmin_opt_evaluate(&local_opt_data, i); if (local_opt_data.last.D < local_best_result.D) { #ifdef PLFIT_DEBUG printf("Found new local best at %g with D=%g\n", local_opt_data.last.xmin, local_opt_data.last.D); #endif local_best_result = local_opt_data.last; local_best_n = local_opt_data.end - local_opt_data.probes[i] + 1; } } /* Critical section that finds the global best result from the * local ones collected by each thread */ #ifdef _OPENMP #pragma omp critical #endif if (local_best_result.D < global_best_result.D) { global_best_result = local_best_result; global_best_n = local_best_n; #ifdef PLFIT_DEBUG printf("Found new global best at %g with D=%g\n", global_best_result.xmin, global_best_result.D); #endif } } *best_result = global_best_result; *best_n = global_best_n; #ifdef PLFIT_DEBUG printf("Returning global best: %g\n", best_result->xmin); #endif return PLFIT_SUCCESS; } int plfit_continuous(double* xs, size_t n, const plfit_continuous_options_t* options, plfit_result_t* result) { gss_parameter_t gss_param; plfit_continuous_xmin_opt_data_t opt_data; plfit_result_t best_result = { /* alpha = */ NAN, /* xmin = */ NAN, /* L = */ NAN, /* D = */ NAN, /* p = */ NAN }; int success; size_t i, best_n, num_uniques = 0; double x, *px, **uniques; DATA_POINTS_CHECK; /* Sane defaults */ best_n = n; if (!options) options = &plfit_continuous_default_options; /* Make a copy of xs and sort it */ PLFIT_CHECK(plfit_i_copy_and_sort(xs, n, &opt_data.begin)); opt_data.end = opt_data.begin + n; /* Create an array containing pointers to the unique elements of the input. From * each block of unique elements, we add the pointer to the first one. */ uniques = unique_element_pointers(opt_data.begin, opt_data.end, &num_uniques); if (uniques == 0) PLFIT_ERROR("cannot fit continuous power-law", PLFIT_ENOMEM); /* We will now determine the best xmin that yields the lowest D-score. The * 'success' variable will denote whether the search procedure we tried was * successful. If it is false after having exhausted all options, we fall * back to a linear search. */ success = 0; switch (options->xmin_method) { case PLFIT_GSS_OR_LINEAR: /* Try golden section search first. */ if (num_uniques > 5) { opt_data.probes = uniques; opt_data.num_probes = num_uniques; gss_parameter_init(&gss_param); success = (gss(0, opt_data.num_probes-5, &x, 0, plfit_i_continuous_xmin_opt_evaluate, plfit_i_continuous_xmin_opt_progress, &opt_data, &gss_param) == 0); if (success) { px = opt_data.probes[(int)x]; best_n = opt_data.end-px+1; best_result = opt_data.last; } } break; case PLFIT_STRATIFIED_SAMPLING: if (num_uniques >= 50) { /* Try stratified sampling to narrow down the interval where the minimum * is likely to reside. We check 10% of the unique items, distributed * evenly, find the one with the lowest D-score, and then check the * area around it more thoroughly. */ const size_t subdivision_length = 10; size_t num_strata = num_uniques / subdivision_length; double **strata = calloc(num_strata, sizeof(double*)); int error_code; for (i = 0; i < num_strata; i++) { strata[i] = uniques[i * subdivision_length]; } opt_data.probes = strata; opt_data.num_probes = num_strata; error_code = plfit_i_continuous_xmin_opt_linear_scan(&opt_data, &best_result, &best_n); if (error_code != PLFIT_SUCCESS) { free(strata); return error_code; } opt_data.num_probes = 0; for (i = 0; i < num_strata; i++) { if (*strata[i] == best_result.xmin) { /* Okay, scan more thoroughly from strata[i-1] to strata[i+1], * which is from uniques[(i-1)*subdivision_length] to * uniques[(i+1)*subdivision_length */ opt_data.probes = uniques + (i > 0 ? (i-1)*subdivision_length : 0); opt_data.num_probes = 0; if (i != 0) opt_data.num_probes += subdivision_length; if (i != num_strata-1) opt_data.num_probes += subdivision_length; break; } } free(strata); if (opt_data.num_probes > 0) { /* Do a strict linear scan in the subrange determined above */ PLFIT_CHECK( plfit_i_continuous_xmin_opt_linear_scan( &opt_data, &best_result, &best_n ) ); success = 1; } else { /* This should not happen, but we handle it anyway */ success = 0; } } break; default: /* Just use the linear search */ break; } if (!success) { /* More advanced search methods failed or were skipped; try linear search */ opt_data.probes = uniques; opt_data.num_probes = num_uniques; PLFIT_CHECK(plfit_i_continuous_xmin_opt_linear_scan(&opt_data, &best_result, &best_n)); success = 1; } /* Get rid of the uniques array, we don't need it any more */ free(uniques); /* Sort out the result */ *result = best_result; if (options->finite_size_correction) plfit_i_perform_finite_size_correction(result, best_n); PLFIT_CHECK(plfit_log_likelihood_continuous(opt_data.begin + n - best_n, best_n, result->alpha, result->xmin, &result->L)); PLFIT_CHECK(plfit_i_calculate_p_value_continuous(opt_data.begin, n, options, 0, result)); /* Get rid of the copied data as well */ free(opt_data.begin); return PLFIT_SUCCESS; } /********** Discrete power law distribution fitting **********/ typedef struct { size_t m; double logsum; double xmin; } plfit_i_estimate_alpha_discrete_data_t; static double plfit_i_logsum_discrete(double* begin, double* end, double xmin) { double logsum = 0.0; for (; begin != end; begin++) logsum += log(*begin); return logsum; } static void plfit_i_logsum_less_than_discrete(double* begin, double* end, double xmin, double* logsum, size_t* m) { double result = 0.0; size_t count = 0; for (; begin != end; begin++) { if (*begin < xmin) continue; result += log(*begin); count++; } *logsum = result; *m = count; } static lbfgsfloatval_t plfit_i_estimate_alpha_discrete_lbfgs_evaluate( void* instance, const lbfgsfloatval_t* x, lbfgsfloatval_t* g, const int n, const lbfgsfloatval_t step) { plfit_i_estimate_alpha_discrete_data_t* data; lbfgsfloatval_t result; double dx = step; double huge = 1e10; /* pseudo-infinity; apparently DBL_MAX does not work */ double lnhzeta_x=NAN; double lnhzeta_deriv_x=NAN; data = (plfit_i_estimate_alpha_discrete_data_t*)instance; #ifdef PLFIT_DEBUG printf("- Evaluating at %.4f (step = %.4f, xmin = %.4f)\n", *x, step, data->xmin); #endif if (isnan(*x)) { g[0] = huge; return huge; } /* Find the delta X value to estimate the gradient */ if (dx > 0.001 || dx == 0) dx = 0.001; else if (dx < -0.001) dx = -0.001; /* Is x[0] in its valid range? */ if (x[0] <= 1.0) { /* The Hurwitz zeta function is infinite in this case */ g[0] = (dx > 0) ? -huge : huge; return huge; } if (x[0] + dx <= 1.0) { g[0] = huge; result = x[0] * data->logsum + data->m * hsl_sf_lnhzeta(x[0], data->xmin); } else { hsl_sf_lnhzeta_deriv_tuple(x[0], data->xmin, &lnhzeta_x, &lnhzeta_deriv_x); g[0] = data->logsum + data->m * lnhzeta_deriv_x; result = x[0] * data->logsum + data->m * lnhzeta_x; } #ifdef PLFIT_DEBUG printf(" - Gradient: %.4f\n", g[0]); printf(" - Result: %.4f\n", result); #endif return result; } static int plfit_i_estimate_alpha_discrete_lbfgs_progress(void* instance, const lbfgsfloatval_t* x, const lbfgsfloatval_t* g, const lbfgsfloatval_t fx, const lbfgsfloatval_t xnorm, const lbfgsfloatval_t gnorm, const lbfgsfloatval_t step, int n, int k, int ls) { return 0; } static int plfit_i_estimate_alpha_discrete_linear_scan(double* xs, size_t n, double xmin, double* alpha, const plfit_discrete_options_t* options, plfit_bool_t sorted) { double curr_alpha, best_alpha, L, L_max; double logsum; size_t m; XMIN_CHECK_ONE; if (options->alpha.min <= 1.0) { PLFIT_ERROR("alpha.min must be greater than 1.0", PLFIT_EINVAL); } if (options->alpha.max < options->alpha.min) { PLFIT_ERROR("alpha.max must be greater than alpha.min", PLFIT_EINVAL); } if (options->alpha.step <= 0) { PLFIT_ERROR("alpha.step must be positive", PLFIT_EINVAL); } if (sorted) { logsum = plfit_i_logsum_discrete(xs, xs+n, xmin); m = n; } else { plfit_i_logsum_less_than_discrete(xs, xs+n, xmin, &logsum, &m); } best_alpha = options->alpha.min; L_max = -DBL_MAX; for (curr_alpha = options->alpha.min; curr_alpha <= options->alpha.max; curr_alpha += options->alpha.step) { L = -curr_alpha * logsum - m * hsl_sf_lnhzeta(curr_alpha, xmin); if (L > L_max) { L_max = L; best_alpha = curr_alpha; } } *alpha = best_alpha; return PLFIT_SUCCESS; } static int plfit_i_estimate_alpha_discrete_lbfgs(double* xs, size_t n, double xmin, double* alpha, const plfit_discrete_options_t* options, plfit_bool_t sorted) { lbfgs_parameter_t param; lbfgsfloatval_t* variables; plfit_i_estimate_alpha_discrete_data_t data; int ret; XMIN_CHECK_ONE; /* Initialize algorithm parameters */ lbfgs_parameter_init(¶m); param.max_iterations = 0; /* proceed until infinity */ /* Set up context for optimization */ data.xmin = xmin; if (sorted) { data.logsum = plfit_i_logsum_discrete(xs, xs+n, xmin); data.m = n; } else { plfit_i_logsum_less_than_discrete(xs, xs+n, xmin, &data.logsum, &data.m); } /* Allocate space for the single alpha variable */ variables = lbfgs_malloc(1); variables[0] = 3.0; /* initial guess */ /* Optimization */ ret = lbfgs(1, variables, /* ptr_fx = */ 0, plfit_i_estimate_alpha_discrete_lbfgs_evaluate, plfit_i_estimate_alpha_discrete_lbfgs_progress, &data, ¶m); if (ret < 0 && ret != LBFGSERR_ROUNDING_ERROR && ret != LBFGSERR_MAXIMUMLINESEARCH && ret != LBFGSERR_MINIMUMSTEP && ret != LBFGSERR_CANCELED) { char buf[4096]; snprintf(buf, 4096, "L-BFGS optimization signaled an error (error code = %d)", ret); lbfgs_free(variables); PLFIT_ERROR(buf, PLFIT_FAILURE); } *alpha = variables[0]; /* Deallocate the variable array */ lbfgs_free(variables); return PLFIT_SUCCESS; } static int plfit_i_estimate_alpha_discrete_fast(double* xs, size_t n, double xmin, double* alpha, const plfit_discrete_options_t* options, plfit_bool_t sorted) { plfit_continuous_options_t cont_options; if (!options) options = &plfit_discrete_default_options; plfit_continuous_options_init(&cont_options); cont_options.finite_size_correction = options->finite_size_correction; XMIN_CHECK_ONE; if (sorted) { return plfit_i_estimate_alpha_continuous_sorted(xs, n, xmin-0.5, alpha); } else { return plfit_i_estimate_alpha_continuous(xs, n, xmin-0.5, alpha); } } static int plfit_i_estimate_alpha_discrete(double* xs, size_t n, double xmin, double* alpha, const plfit_discrete_options_t* options, plfit_bool_t sorted) { switch (options->alpha_method) { case PLFIT_LBFGS: PLFIT_CHECK(plfit_i_estimate_alpha_discrete_lbfgs(xs, n, xmin, alpha, options, sorted)); break; case PLFIT_LINEAR_SCAN: PLFIT_CHECK(plfit_i_estimate_alpha_discrete_linear_scan(xs, n, xmin, alpha, options, sorted)); break; case PLFIT_PRETEND_CONTINUOUS: PLFIT_CHECK(plfit_i_estimate_alpha_discrete_fast(xs, n, xmin, alpha, options, sorted)); break; default: PLFIT_ERROR("unknown optimization method specified", PLFIT_EINVAL); } return PLFIT_SUCCESS; } static int plfit_i_ks_test_discrete(double* xs, double* xs_end, const double alpha, const double xmin, double* D) { /* Assumption: xs is sorted and cut off at xmin so the first element is * always larger than or equal to xmin. */ double result = 0, n, lnhzeta, x; int m = 0; n = xs_end - xs; lnhzeta = hsl_sf_lnhzeta(alpha, xmin); while (xs < xs_end) { double d; x = *xs; /* Re the next line: this used to be the following: * * fabs( 1 - hzeta(alpha, x) / hzeta(alpha, xmin) - m / n) * * However, using the Hurwitz zeta directly sometimes yields * underflows (see Github pull request #17 and related issues). * hzeta(alpha, x) / hzeta(alpha, xmin) can be replaced with * exp(lnhzeta(alpha, x) - lnhzeta(alpha, xmin)), but then * we have 1 - exp(something), which is better to calculate * with a dedicated expm1() function. */ d = fabs( expm1( hsl_sf_lnhzeta(alpha, x) - lnhzeta ) + m / n); if (d > result) result = d; do { xs++; m++; } while (xs < xs_end && *xs == x); } *D = result; return PLFIT_SUCCESS; } static int plfit_i_calculate_p_value_discrete(double* xs, size_t n, const plfit_discrete_options_t* options, plfit_bool_t xmin_fixed, plfit_result_t *result) { long int num_trials; long int successes = 0; double *xs_head; size_t num_smaller; plfit_discrete_options_t options_no_p_value = *options; int retval = PLFIT_SUCCESS; if (options->p_value_method == PLFIT_P_VALUE_SKIP) { /* skipping p-value calculation */ result->p = NAN; return PLFIT_SUCCESS; } if (options->p_value_method == PLFIT_P_VALUE_APPROXIMATE) { /* p-value approximation; most likely an upper bound */ num_smaller = count_smaller(xs, xs + n, result->xmin); result->p = plfit_ks_test_one_sample_p(result->D, n - num_smaller); return PLFIT_SUCCESS; } options_no_p_value.p_value_method = PLFIT_P_VALUE_SKIP; num_trials = (long int)(0.25 / options->p_value_precision / options->p_value_precision); if (num_trials <= 0) { PLFIT_ERROR("invalid p-value precision", PLFIT_EINVAL); } /* Extract the head of xs that contains elements smaller than xmin */ xs_head = extract_smaller(xs, xs+n, result->xmin, &num_smaller); if (xs_head == 0) PLFIT_ERROR("cannot calculate exact p-value", PLFIT_ENOMEM); #ifdef _OPENMP #pragma omp parallel #endif { /* Parallel section starts here. If we are compiling using OpenMP, each * thread will use its own RNG that is seeded from the master RNG. If * we are compiling without OpenMP, there is only one thread and it uses * the master RNG. This section must be critical to ensure that only one * thread is using the master RNG at the same time. */ #ifdef _OPENMP plfit_mt_rng_t private_rng; #endif plfit_mt_rng_t *p_rng; double *ys; long int i; plfit_result_t result_synthetic; #ifdef _OPENMP #pragma omp critical { p_rng = &private_rng; plfit_mt_init_from_rng(p_rng, options->rng); } #else p_rng = options->rng; #endif /* Allocate memory to sample into */ ys = calloc(n, sizeof(double)); if (ys == 0) { retval = PLFIT_ENOMEM; } else { /* The main for loop starts here. */ #ifdef _OPENMP #pragma omp for reduction(+:successes) #endif for (i = 0; i < num_trials; i++) { plfit_i_resample_discrete(xs_head, num_smaller, n, result->alpha, result->xmin, n, p_rng, ys); if (xmin_fixed) { plfit_estimate_alpha_discrete(ys, n, result->xmin, &options_no_p_value, &result_synthetic); } else { plfit_discrete(ys, n, &options_no_p_value, &result_synthetic); } if (result_synthetic.D > result->D) successes++; } free(ys); } /* End of parallelized part */ } free(xs_head); if (retval == PLFIT_SUCCESS) { result->p = successes / ((double)num_trials); } else { PLFIT_ERROR("cannot calculate exact p-value", retval); } return retval; } int plfit_log_likelihood_discrete(double* xs, size_t n, double alpha, double xmin, double* L) { double result; size_t m; if (alpha <= 1) { PLFIT_ERROR("alpha must be greater than one", PLFIT_EINVAL); } XMIN_CHECK_ONE; plfit_i_logsum_less_than_discrete(xs, xs+n, xmin, &result, &m); result = - alpha * result - m * hsl_sf_lnhzeta(alpha, xmin); *L = result; return PLFIT_SUCCESS; } int plfit_estimate_alpha_discrete(double* xs, size_t n, double xmin, const plfit_discrete_options_t* options, plfit_result_t *result) { double *xs_copy, *begin, *end; if (!options) options = &plfit_discrete_default_options; /* Check the validity of the input parameters */ DATA_POINTS_CHECK; if (options->alpha_method == PLFIT_LINEAR_SCAN) { if (options->alpha.min <= 1.0) { PLFIT_ERROR("alpha.min must be greater than 1.0", PLFIT_EINVAL); } if (options->alpha.max < options->alpha.min) { PLFIT_ERROR("alpha.max must be greater than alpha.min", PLFIT_EINVAL); } if (options->alpha.step <= 0) { PLFIT_ERROR("alpha.step must be positive", PLFIT_EINVAL); } } PLFIT_CHECK(plfit_i_copy_and_sort(xs, n, &xs_copy)); begin = xs_copy; end = xs_copy + n; while (begin < end && *begin < xmin) begin++; PLFIT_CHECK(plfit_i_estimate_alpha_discrete(begin, end-begin, xmin, &result->alpha, options, /* sorted = */ 1)); PLFIT_CHECK(plfit_i_ks_test_discrete(begin, end, result->alpha, xmin, &result->D)); result->xmin = xmin; if (options->finite_size_correction) plfit_i_perform_finite_size_correction(result, end-begin); PLFIT_CHECK(plfit_log_likelihood_discrete(begin, end-begin, result->alpha, result->xmin, &result->L)); PLFIT_CHECK(plfit_i_calculate_p_value_discrete(xs, n, options, 1, result)); free(xs_copy); return PLFIT_SUCCESS; } int plfit_discrete(double* xs, size_t n, const plfit_discrete_options_t* options, plfit_result_t* result) { double curr_D, curr_alpha; plfit_result_t best_result; double *xs_copy, *px, *end, *end_xmin, prev_x; size_t best_n; int m; if (!options) options = &plfit_discrete_default_options; /* Check the validity of the input parameters */ DATA_POINTS_CHECK; if (options->alpha_method == PLFIT_LINEAR_SCAN) { if (options->alpha.min <= 1.0) { PLFIT_ERROR("alpha.min must be greater than 1.0", PLFIT_EINVAL); } if (options->alpha.max < options->alpha.min) { PLFIT_ERROR("alpha.max must be greater than alpha.min", PLFIT_EINVAL); } if (options->alpha.step <= 0) { PLFIT_ERROR("alpha.step must be positive", PLFIT_EINVAL); } } PLFIT_CHECK(plfit_i_copy_and_sort(xs, n, &xs_copy)); best_result.D = DBL_MAX; best_result.xmin = 1; best_result.alpha = 1; best_n = 0; /* Skip initial values from xs_copy until we get to a positive element or * until we reach the end of the array */ px = xs_copy; end = px + n; end_xmin = end - 1; while (px < end && *px < 1) { px++; } /* Make sure there are at least three distinct values if possible */ m = px - xs_copy; prev_x = *end_xmin; while (end_xmin > px && *end_xmin == prev_x) { end_xmin--; } prev_x = *end_xmin; while (end_xmin > px && *end_xmin == prev_x) { end_xmin--; } prev_x = 0; end_xmin++; while (px < end_xmin) { while (px < end_xmin && *px == prev_x) { px++; m++; } PLFIT_CHECK( plfit_i_estimate_alpha_discrete( px, n-m, *px, &curr_alpha, options, /* sorted = */ 1 ) ); PLFIT_CHECK( plfit_i_ks_test_discrete(px, end, curr_alpha, *px, &curr_D) ); if (curr_D < best_result.D) { best_result.alpha = curr_alpha; best_result.xmin = *px; best_result.D = curr_D; best_n = n-m; } prev_x = *px; px++; m++; } *result = best_result; if (options->finite_size_correction) plfit_i_perform_finite_size_correction(result, best_n); PLFIT_CHECK(plfit_log_likelihood_discrete(xs_copy+(n-best_n), best_n, result->alpha, result->xmin, &result->L)); PLFIT_CHECK(plfit_i_calculate_p_value_discrete(xs_copy, n, options, 0, result)); free(xs_copy); return PLFIT_SUCCESS; } /***** resampling routines to generate synthetic replicates ****/ static int plfit_i_resample_continuous(double* xs_head, size_t num_smaller, size_t n, double alpha, double xmin, size_t num_samples, plfit_mt_rng_t* rng, double* result) { size_t num_orig_samples, i; /* Calculate how many samples have to be drawn from xs_head */ num_orig_samples = (size_t) plfit_rbinom(num_samples, num_smaller / (double)n, rng); /* Draw the samples from xs_head */ for (i = 0; i < num_orig_samples; i++, result++) { *result = xs_head[(size_t)plfit_runif(0, num_smaller, rng)]; } /* Draw the remaining samples from the fitted distribution */ PLFIT_CHECK(plfit_rpareto_array(xmin, alpha-1, num_samples-num_orig_samples, rng, result)); return PLFIT_SUCCESS; } int plfit_resample_continuous(double* xs, size_t n, double alpha, double xmin, size_t num_samples, plfit_mt_rng_t* rng, double* result) { double *xs_head; size_t num_smaller = 0; int retval; /* Extract the head of xs that contains elements smaller than xmin */ xs_head = extract_smaller(xs, xs+n, xmin, &num_smaller); if (xs_head == 0) PLFIT_ERROR("cannot resample continuous dataset", PLFIT_ENOMEM); retval = plfit_i_resample_continuous(xs_head, num_smaller, n, alpha, xmin, num_samples, rng, result); /* Free xs_head; we don't need it any more */ free(xs_head); return retval; } static int plfit_i_resample_discrete(double* xs_head, size_t num_smaller, size_t n, double alpha, double xmin, size_t num_samples, plfit_mt_rng_t* rng, double* result) { size_t num_orig_samples, i; /* Calculate how many samples have to be drawn from xs_head */ num_orig_samples = (size_t) plfit_rbinom(num_samples, num_smaller / (double)n, rng); /* Draw the samples from xs_head */ for (i = 0; i < num_orig_samples; i++, result++) { *result = xs_head[(size_t)plfit_runif(0, num_smaller, rng)]; } /* Draw the remaining samples from the fitted distribution */ PLFIT_CHECK(plfit_rzeta_array((long int)xmin, alpha, num_samples-num_orig_samples, rng, result)); return PLFIT_SUCCESS; } int plfit_resample_discrete(double* xs, size_t n, double alpha, double xmin, size_t num_samples, plfit_mt_rng_t* rng, double* result) { double *xs_head; size_t num_smaller = 0; int retval; /* Extract the head of xs that contains elements smaller than xmin */ xs_head = extract_smaller(xs, xs+n, xmin, &num_smaller); if (xs_head == 0) PLFIT_ERROR("cannot resample discrete dataset", PLFIT_ENOMEM); retval = plfit_i_resample_discrete(xs_head, num_smaller, n, alpha, xmin, num_samples, rng, result); /* Free xs_head; we don't need it any more */ free(xs_head); return retval; } /******** calculating the p-value of a fitted model only *******/ int plfit_calculate_p_value_continuous(double* xs, size_t n, const plfit_continuous_options_t* options, plfit_bool_t xmin_fixed, plfit_result_t *result) { double* xs_copy; PLFIT_CHECK(plfit_i_copy_and_sort(xs, n, &xs_copy)); PLFIT_CHECK(plfit_i_calculate_p_value_continuous(xs_copy, n, options, xmin_fixed, result)); free(xs_copy); return PLFIT_SUCCESS; } int plfit_calculate_p_value_discrete(double* xs, size_t n, const plfit_discrete_options_t* options, plfit_bool_t xmin_fixed, plfit_result_t *result) { double* xs_copy; PLFIT_CHECK(plfit_i_copy_and_sort(xs, n, &xs_copy)); PLFIT_CHECK(plfit_i_calculate_p_value_discrete(xs_copy, n, options, xmin_fixed, result)); free(xs_copy); return PLFIT_SUCCESS; } leidenbase/src/vendor/plfit/hzeta.c0000644000176200001440000005215614447675375017065 0ustar liggesusers/* vim:set ts=4 sw=2 sts=2 et: */ /* This file was imported from a private scientific library * based on GSL coined Home Scientific Libray (HSL) by its author * Jerome Benoit; this very material is itself inspired from the * material written by G. Jungan and distributed by GSL. * Ultimately, some modifications were done in order to render the * imported material independent from the rest of GSL. */ /* `hsl/specfunc/hzeta.c' C source file // HSL - Home Scientific Library // Copyright (C) 2017-2018 Jerome Benoit // // HSL is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* // The material in this file is mainly inspired by the material written by // G. Jungan and distributed under GPLv2 by the GNU Scientific Library (GSL) // ( https://www.gnu.org/software/gsl/ [specfunc/zeta.c]), itself inspired by // the material written by Moshier and distributed in the Cephes Mathematical // Library ( http://www.moshier.net/ [zeta.c]). // // More specifically, hsl_sf_hzeta_e is a slightly modifed clone of // gsl_sf_hzeta_e as found in GSL 2.4; the remaining is `inspired by'. // [Sooner or later a _Working_Note_ may be deposited at ResearchGate // ( https://www.researchgate.net/profile/Jerome_Benoit )] */ /* Author: Jerome G. Benoit < jgmbenoit _at_ rezozer _dot_ net > */ #ifdef _MSC_VER #define _USE_MATH_DEFINES #endif #include #include #include "hzeta.h" #include "plfit_error.h" #include "platform.h" /* because of NAN */ /* imported from gsl_machine.h */ #define GSL_LOG_DBL_MIN (-7.0839641853226408e+02) #define GSL_LOG_DBL_MAX 7.0978271289338397e+02 #define GSL_DBL_EPSILON 2.2204460492503131e-16 /* imported from gsl_math.h */ #ifndef M_LOG2E #define M_LOG2E 1.44269504088896340735992468100 /* log_2 (e) */ #endif /* imported from gsl_sf_result.h */ struct gsl_sf_result_struct { double val; double err; }; typedef struct gsl_sf_result_struct gsl_sf_result; /* imported and adapted from hsl/specfunc/specfunc_def.h */ #define HSL_SF_EVAL_RESULT(FnE) \ gsl_sf_result result; \ FnE ; \ return (result.val); #define HSL_SF_EVAL_TUPLE_RESULT(FnET) \ gsl_sf_result result0; \ gsl_sf_result result1; \ FnET ; \ *tuple1=result1.val; \ *tuple0=result0.val; \ return (result0.val); /* */ #define HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT 10 #define HSL_SF_HZETA_EULERMACLAURIN_SERIES_ORDER 32 #define HSL_SF_LNHZETA_EULERMACLAURIN_SERIES_SHIFT_MAX 256 // B_{2j}/(2j) static double hsl_sf_hzeta_eulermaclaurin_series_coeffs[HSL_SF_HZETA_EULERMACLAURIN_SERIES_ORDER+1]={ +1.0, +1.0/12.0, -1.0/720.0, +1.0/30240.0, -1.0/1209600.0, +1.0/47900160.0, -691.0/1307674368000.0, +1.0/74724249600.0, -3.38968029632258286683019539125e-13, +8.58606205627784456413590545043e-15, -2.17486869855806187304151642387e-16, +5.50900282836022951520265260890e-18, -1.39544646858125233407076862641e-19, +3.53470703962946747169322997780e-21, -8.95351742703754685040261131811e-23, +2.26795245233768306031095073887e-24, -5.74479066887220244526388198761e-26, +1.45517247561486490186626486727e-27, -3.68599494066531017818178247991e-29, +9.33673425709504467203255515279e-31, -2.36502241570062993455963519637e-32, +5.99067176248213430465991239682e-34, -1.51745488446829026171081313586e-35, +3.84375812545418823222944529099e-37, -9.73635307264669103526762127925e-39, +2.46624704420068095710640028029e-40, -6.24707674182074369314875679472e-42, +1.58240302446449142975108170683e-43, -4.00827368594893596853001219052e-45, +1.01530758555695563116307139454e-46, -2.57180415824187174992481940976e-48, +6.51445603523381493155843485864e-50, -1.65013099068965245550609878048e-51 }; // hsl_sf_hzeta_eulermaclaurin_series_coeffs // 4\zeta(2j)/(2\pi)^(2j) static double hsl_sf_hzeta_eulermaclaurin_series_majorantratios[HSL_SF_HZETA_EULERMACLAURIN_SERIES_ORDER+1]={ -2.0, +1.0/6.0, +1.0/360.0, +1.0/15120.0, +1.0/604800.0, +1.0/23950080.0, +691.0/653837184000.0, +1.0/37362124800.0, +3617.0/5335311421440000.0, +1.71721241125556891282718109009e-14, +4.34973739711612374608303284773e-16, +1.10180056567204590304053052178e-17, +2.79089293716250466814153725281e-19, +7.06941407925893494338645995561e-21, +1.79070348540750937008052226362e-22, +4.53590490467536612062190147774e-24, +1.14895813377444048905277639752e-25, +2.91034495122972980373252973454e-27, +7.37198988133062035636356495982e-29, +1.86734685141900893440651103056e-30, +4.73004483140125986911927039274e-32, +1.19813435249642686093198247936e-33, +3.03490976893658052342162627173e-35, +7.68751625090837646445889058198e-37, +1.94727061452933820705352425585e-38, +4.93249408840136191421280056051e-40, +1.24941534836414873862975135893e-41, +3.16480604892898285950216341362e-43, +8.01654737189787193706002438098e-45, +2.03061517111391126232614278906e-46, +5.14360831648374349984963881946e-48, +1.30289120704676298631168697172e-49, +3.30026198137930491101219756091e-51 }; // hsl_sf_hzeta_eulermaclaurin_series_majorantratios extern int hsl_sf_hzeta_e(const double s, const double q, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if ((s <= 1.0) || (q <= 0.0)) { PLFIT_ERROR("s must be larger than 1.0 and q must be larger than zero", PLFIT_EINVAL); } else { const double max_bits=54.0; // max_bits=\lceil{s}\rceil with \zeta(s,2)=\zeta(s)-1=GSL_DBL_EPSILON const double ln_term0=-s*log(q); if (ln_term0 < GSL_LOG_DBL_MIN+1.0) { PLFIT_ERROR("underflow", PLFIT_UNDRFLOW); } else if (GSL_LOG_DBL_MAX-1.0 < ln_term0) { PLFIT_ERROR("overflow", PLFIT_OVERFLOW); } #if 1 else if (((max_bits < s) && (q < 1.0)) || ((0.5*max_bits < s) && (q < 0.25))) { result->val=pow(q,-s); result->err=2.0*GSL_DBL_EPSILON*fabs(result->val); return (PLFIT_SUCCESS); } else if ((0.5*max_bits < s) && (q < 1.0)) { const double a0=pow(q,-s); const double p1=pow(q/(1.0+q),s); const double p2=pow(q/(2.0+q),s); const double ans=a0*(1.0+p1+p2); result->val=ans; result->err=GSL_DBL_EPSILON*(2.0+0.5*s)*fabs(result->val); return (PLFIT_SUCCESS); } #endif else { // Euler-Maclaurin summation formula const double qshift=HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT+q; const double inv_qshift=1.0/qshift; const double sqr_inv_qshift=inv_qshift*inv_qshift; const double inv_sm1=1.0/(s-1.0); const double pmax=pow(qshift,-s); double terms[HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT+HSL_SF_HZETA_EULERMACLAURIN_SERIES_ORDER+1]={NAN}; double delta=NAN; double tscp=s; double scp=tscp; double pcp=pmax*inv_qshift; double ratio=scp*pcp; size_t n=0; size_t j=0; double ans=0.0; double mjr=NAN; for(j=0;jval=+ans; result->err=2.0*((HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT+1.0)*GSL_DBL_EPSILON*fabs(ans)+mjr); return (PLFIT_SUCCESS); } } } extern double hsl_sf_hzeta(const double s, const double q) { HSL_SF_EVAL_RESULT(hsl_sf_hzeta_e(s,q,&result)); } extern int hsl_sf_hzeta_deriv_e(const double s, const double q, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if ((s <= 1.0) || (q <= 0.0)) { PLFIT_ERROR("s must be larger than 1.0 and q must be larger than zero", PLFIT_EINVAL); } else { const double ln_hz_term0=-s*log(q); if (ln_hz_term0 < GSL_LOG_DBL_MIN+1.0) { PLFIT_ERROR("underflow", PLFIT_UNDRFLOW); } else if (GSL_LOG_DBL_MAX-1.0 < ln_hz_term0) { PLFIT_ERROR("overflow", PLFIT_OVERFLOW); } else { // Euler-Maclaurin summation formula const double qshift=HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT+q; const double inv_qshift=1.0/qshift; const double sqr_inv_qshift=inv_qshift*inv_qshift; const double inv_sm1=1.0/(s-1.0); const double pmax=pow(qshift,-s); const double lmax=log(qshift); double terms[HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT+HSL_SF_HZETA_EULERMACLAURIN_SERIES_ORDER+1]={NAN}; double delta=NAN; double tscp=s; double scp=tscp; double pcp=pmax*inv_qshift; double lcp=lmax-1.0/s; double ratio=scp*pcp*lcp; double qs=NAN; size_t n=0; size_t j=0; double ans=0.0; double mjr=NAN; for(j=0,qs=q;jval=-ans; result->err=2.0*((HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT+1.0)*GSL_DBL_EPSILON*fabs(ans)+mjr); return (PLFIT_SUCCESS); } } } extern double hsl_sf_hzeta_deriv(const double s, const double q) { HSL_SF_EVAL_RESULT(hsl_sf_hzeta_deriv_e(s,q,&result)); } extern int hsl_sf_hzeta_deriv2_e(const double s, const double q, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if ((s <= 1.0) || (q <= 0.0)) { PLFIT_ERROR("s must be larger than 1.0 and q must be larger than zero", PLFIT_EINVAL); } else { const double ln_hz_term0=-s*log(q); if (ln_hz_term0 < GSL_LOG_DBL_MIN+1.0) { PLFIT_ERROR("underflow", PLFIT_UNDRFLOW); } else if (GSL_LOG_DBL_MAX-1.0 < ln_hz_term0) { PLFIT_ERROR("overflow", PLFIT_OVERFLOW); } else { // Euler-Maclaurin summation formula const double qshift=HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT+q; const double inv_qshift=1.0/qshift; const double sqr_inv_qshift=inv_qshift*inv_qshift; const double inv_sm1=1.0/(s-1.0); const double pmax=pow(qshift,-s); const double lmax=log(qshift); const double lmax_p_inv_sm1=lmax+inv_sm1; const double sqr_inv_sm1=inv_sm1*inv_sm1; const double sqr_lmax=lmax*lmax; const double sqr_lmax_p_inv_sm1=lmax_p_inv_sm1*lmax_p_inv_sm1; double terms[HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT+HSL_SF_HZETA_EULERMACLAURIN_SERIES_ORDER+1]={NAN}; double delta=NAN; double tscp=s; double slcp=NAN; double plcp=NAN; double scp=tscp; double pcp=pmax*inv_qshift; double lcp=1.0/s-lmax; double sqr_lcp=lmax*(lmax-2.0/s); double ratio=scp*pcp*sqr_lcp; double qs=NAN; double lqs=NAN; size_t n=0; size_t j=0; double ans=0.0; double mjr=NAN; for(j=0,qs=q;jval=+ans; result->err=2.0*((HSL_SF_HZETA_EULERMACLAURIN_SERIES_SHIFT+1.0)*GSL_DBL_EPSILON*fabs(ans)+mjr); return (PLFIT_SUCCESS); } } } extern double hsl_sf_hzeta_deriv2(const double s, const double q) { HSL_SF_EVAL_RESULT(hsl_sf_hzeta_deriv2_e(s,q,&result)); } static inline double hsl_sf_hZeta0_zed(const double s, const double q) { #if 1 const long double ld_q=(long double)(q); const long double ld_s=(long double)(s); const long double ld_log1prq=log1pl(1.0L/ld_q); const long double ld_epsilon=expm1l(-ld_s*ld_log1prq); const long double ld_z=ld_s+(ld_q+0.5L*ld_s+0.5L)*ld_epsilon; const double z=(double)(ld_z); #else double z=s+(q+0.5*s+0.5)*expm1(-s*log1p(1.0/q)); #endif return (z); } // Z_{0}(s,a) = a^s \left(\frac{1}{2}+\frac{a}{s-1}\right)^{-1} \zeta(s,a) - 1 // Z_{0}(s,a) = O\left(\frac{(s-1)s}{6a^{2}}\right) static int hsl_sf_hZeta0(const double s, const double q, double * value, double * abserror) { const double criterion=ceil(10.0*s-q); const size_t shift=(criterion<0.0)?0: (criterionval=log1p(ln_hZeta0_value); result->err=(2.0*GSL_DBL_EPSILON*ln_hz_coeff+hZeta0_abserror)/(1.0+ln_hZeta0_value); } if (result_deriv) { const double ld_hz_coeff2=1.0+inv_sm1*M_LOG2E; const double ld_hz_coeff1=1.0+inv_qsm1*ld_hz_coeff2; double hZeta1_value=NAN; double hZeta1_abserror=NAN; hsl_sf_hZeta1(s,2.0,M_LN2,&hZeta1_value,&hZeta1_abserror,NULL); hZeta0_value*=hz_coeff1; hZeta0_value+=hz_coeff0; hZeta1_value+=1.0; hZeta1_value*=-M_LN2*ld_hz_coeff1; result_deriv->val=hZeta1_value/hZeta0_value; result_deriv->err=2.0*GSL_DBL_EPSILON*fabs(result_deriv->val)+(hZeta0_abserror+hZeta1_abserror); } } else { const double ln_q=log(q); double hZeta0_value=NAN; double hZeta0_abserror=NAN; hsl_sf_hZeta0(s,q,&hZeta0_value,&hZeta0_abserror); if (result) { const double ln_hz_term0=-s*ln_q; const double ln_hz_term1=log(0.5+q/(s-1.0)); result->val=ln_hz_term0+ln_hz_term1+log1p(hZeta0_value); result->err=2.0*GSL_DBL_EPSILON*(fabs(ln_hz_term0)+fabs(ln_hz_term1))+hZeta0_abserror/(1.0+hZeta0_value); } if (result_deriv) { double hZeta1_value=NAN; double hZeta1_abserror=NAN; double ld_hz_coeff1=NAN; hsl_sf_hZeta1(s,q,ln_q,&hZeta1_value,&hZeta1_abserror,&ld_hz_coeff1); result_deriv->val=-ln_q*ld_hz_coeff1*(1.0+hZeta1_value)/(1.0+hZeta0_value); result_deriv->err=2.0*GSL_DBL_EPSILON*fabs(result_deriv->val)+(hZeta0_abserror+hZeta1_abserror); } } return (PLFIT_SUCCESS); } extern double hsl_sf_lnhzeta_deriv_tuple(const double s, const double q, double * tuple0, double * tuple1) { HSL_SF_EVAL_TUPLE_RESULT(hsl_sf_lnhzeta_deriv_tuple_e(s,q,&result0,&result1)); } extern int hsl_sf_lnhzeta_e(const double s, const double q, gsl_sf_result * result) { return (hsl_sf_lnhzeta_deriv_tuple_e(s,q,result,NULL)); } extern double hsl_sf_lnhzeta(const double s, const double q) { HSL_SF_EVAL_RESULT(hsl_sf_lnhzeta_e(s,q,&result)); } extern int hsl_sf_lnhzeta_deriv_e(const double s, const double q, gsl_sf_result * result) { return (hsl_sf_lnhzeta_deriv_tuple_e(s,q,NULL,result)); } extern double hsl_sf_lnhzeta_deriv(const double s, const double q) { HSL_SF_EVAL_RESULT(hsl_sf_lnhzeta_deriv_e(s,q,&result)); } // // End of file `hsl/specfunc/hzeta.c'. leidenbase/src/vendor/plfit/platform.c0000644000176200001440000000211714453300632017540 0ustar liggesusers/* platform.c * * Copyright (C) 2014 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "platform.h" #ifdef _MSC_VER inline double _plfit_fmin(double a, double b) { return (a < b) ? a : b; } inline double _plfit_round(double x) { return floor(x+0.5); } #endif /* Dummy function to prevent a warning when compiling with Clang - the file * would contain no symbols */ void _plfit_i_unused(void) {} leidenbase/src/vendor/plfit/kolmogorov.h0000644000176200001440000000234214447675375020145 0ustar liggesusers/* kolmogorov.h * * Copyright (C) 2010-2011 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __KOLMOGOROV_H__ #define __KOLMOGOROV_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif #include __BEGIN_DECLS double plfit_kolmogorov(double z); double plfit_ks_test_one_sample_p(double d, size_t n); double plfit_ks_test_two_sample_p(double d, size_t n1, size_t n2); __END_DECLS #endif leidenbase/src/vendor/plfit/lbfgs.c0000644000176200001440000012036414447675375017044 0ustar liggesusers/* * Limited memory BFGS (L-BFGS). * * Copyright (c) 1990, Jorge Nocedal * Copyright (c) 2007-2010 Naoaki Okazaki * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* $Id: lbfgs.c 65 2010-01-29 12:19:16Z naoaki $ */ /* This library is a C port of the FORTRAN implementation of Limited-memory Broyden-Fletcher-Goldfarb-Shanno (L-BFGS) method written by Jorge Nocedal. The original FORTRAN source code is available at: http://www.ece.northwestern.edu/~nocedal/lbfgs.html The L-BFGS algorithm is described in: - Jorge Nocedal. Updating Quasi-Newton Matrices with Limited Storage. Mathematics of Computation, Vol. 35, No. 151, pp. 773--782, 1980. - Dong C. Liu and Jorge Nocedal. On the limited memory BFGS method for large scale optimization. Mathematical Programming B, Vol. 45, No. 3, pp. 503-528, 1989. The line search algorithms used in this implementation are described in: - John E. Dennis and Robert B. Schnabel. Numerical Methods for Unconstrained Optimization and Nonlinear Equations, Englewood Cliffs, 1983. - Jorge J. More and David J. Thuente. Line search algorithm with guaranteed sufficient decrease. ACM Transactions on Mathematical Software (TOMS), Vol. 20, No. 3, pp. 286-307, 1994. This library also implements Orthant-Wise Limited-memory Quasi-Newton (OWL-QN) method presented in: - Galen Andrew and Jianfeng Gao. Scalable training of L1-regularized log-linear models. In Proceedings of the 24th International Conference on Machine Learning (ICML 2007), pp. 33-40, 2007. I would like to thank the original author, Jorge Nocedal, who has been distributing the effieicnt and explanatory implementation in an open source licence. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif/*HAVE_CONFIG_H*/ #ifndef _MSC_VER #include #endif #include #include #include #include "lbfgs.h" #include "platform.h" #ifdef _MSC_VER #define inline __inline typedef unsigned int uint32_t; #endif/*_MSC_VER*/ #if defined(USE_SSE) && defined(__SSE2__) && LBFGS_FLOAT == 64 /* Use SSE2 optimization for 64bit double precision. */ #include "arithmetic_sse_double.h" #elif defined(USE_SSE) && defined(__SSE__) && LBFGS_FLOAT == 32 /* Use SSE optimization for 32bit float precision. */ #include "arithmetic_sse_float.h" #else /* No CPU specific optimization. */ #include "arithmetic_ansi.h" #endif #define min2(a, b) ((a) <= (b) ? (a) : (b)) #define max2(a, b) ((a) >= (b) ? (a) : (b)) #define max3(a, b, c) max2(max2((a), (b)), (c)); #define is_aligned(p, bytes) \ (((uintptr_t)(const void*)(p)) % (bytes) == 0) struct tag_callback_data { int n; void *instance; lbfgs_evaluate_t proc_evaluate; lbfgs_progress_t proc_progress; }; typedef struct tag_callback_data callback_data_t; struct tag_iteration_data { lbfgsfloatval_t alpha; lbfgsfloatval_t *s; /* [n] */ lbfgsfloatval_t *y; /* [n] */ lbfgsfloatval_t ys; /* vecdot(y, s) */ }; typedef struct tag_iteration_data iteration_data_t; static const lbfgs_parameter_t _defparam = { 6, 1e-5, 0, 1e-5, 0, LBFGS_LINESEARCH_DEFAULT, 40, 1e-20, 1e20, 1e-4, 0.9, 0.9, 1.0e-16, 0.0, 0, -1, }; /* Forward function declarations. */ typedef int (*line_search_proc)( int n, lbfgsfloatval_t *x, lbfgsfloatval_t *f, lbfgsfloatval_t *g, lbfgsfloatval_t *s, lbfgsfloatval_t *stp, const lbfgsfloatval_t* xp, const lbfgsfloatval_t* gp, lbfgsfloatval_t *wa, callback_data_t *cd, const lbfgs_parameter_t *param ); static int line_search_backtracking( int n, lbfgsfloatval_t *x, lbfgsfloatval_t *f, lbfgsfloatval_t *g, lbfgsfloatval_t *s, lbfgsfloatval_t *stp, const lbfgsfloatval_t* xp, const lbfgsfloatval_t* gp, lbfgsfloatval_t *wa, callback_data_t *cd, const lbfgs_parameter_t *param ); static int line_search_backtracking_owlqn( int n, lbfgsfloatval_t *x, lbfgsfloatval_t *f, lbfgsfloatval_t *g, lbfgsfloatval_t *s, lbfgsfloatval_t *stp, const lbfgsfloatval_t* xp, const lbfgsfloatval_t* gp, lbfgsfloatval_t *wp, callback_data_t *cd, const lbfgs_parameter_t *param ); static int line_search_morethuente( int n, lbfgsfloatval_t *x, lbfgsfloatval_t *f, lbfgsfloatval_t *g, lbfgsfloatval_t *s, lbfgsfloatval_t *stp, const lbfgsfloatval_t* xp, const lbfgsfloatval_t* gp, lbfgsfloatval_t *wa, callback_data_t *cd, const lbfgs_parameter_t *param ); static int update_trial_interval( lbfgsfloatval_t *x, lbfgsfloatval_t *fx, lbfgsfloatval_t *dx, lbfgsfloatval_t *y, lbfgsfloatval_t *fy, lbfgsfloatval_t *dy, lbfgsfloatval_t *t, lbfgsfloatval_t *ft, lbfgsfloatval_t *dt, const lbfgsfloatval_t tmin, const lbfgsfloatval_t tmax, int *brackt ); static lbfgsfloatval_t owlqn_x1norm( const lbfgsfloatval_t* x, const int start, const int n ); static void owlqn_pseudo_gradient( lbfgsfloatval_t* pg, const lbfgsfloatval_t* x, const lbfgsfloatval_t* g, const int n, const lbfgsfloatval_t c, const int start, const int end ); static void owlqn_project( lbfgsfloatval_t* d, const lbfgsfloatval_t* sign, const int start, const int end ); #if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__)) static int round_out_variables(int n) { n += 7; n /= 8; n *= 8; return n; } #endif/*defined(USE_SSE)*/ lbfgsfloatval_t* lbfgs_malloc(int n) { #if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__)) n = round_out_variables(n); #endif/*defined(USE_SSE)*/ return (lbfgsfloatval_t*)vecalloc(sizeof(lbfgsfloatval_t) * (size_t) n); } void lbfgs_free(lbfgsfloatval_t *x) { vecfree(x); } void lbfgs_parameter_init(lbfgs_parameter_t *param) { memcpy(param, &_defparam, sizeof(*param)); } int lbfgs( int n, lbfgsfloatval_t *x, lbfgsfloatval_t *ptr_fx, lbfgs_evaluate_t proc_evaluate, lbfgs_progress_t proc_progress, void *instance, lbfgs_parameter_t *_param ) { int ret; int i, j, k, ls, end, bound; lbfgsfloatval_t step; /* Constant parameters and their default values. */ lbfgs_parameter_t param = (_param != NULL) ? (*_param) : _defparam; const int m = param.m; lbfgsfloatval_t *xp = NULL; lbfgsfloatval_t *g = NULL, *gp = NULL, *pg = NULL; lbfgsfloatval_t *d = NULL, *w = NULL, *pf = NULL; iteration_data_t *lm = NULL, *it = NULL; lbfgsfloatval_t ys, yy; lbfgsfloatval_t xnorm, gnorm, beta; lbfgsfloatval_t fx = 0.; lbfgsfloatval_t rate = 0.; line_search_proc linesearch = line_search_morethuente; /* Construct a callback data. */ callback_data_t cd; cd.n = n; cd.instance = instance; cd.proc_evaluate = proc_evaluate; cd.proc_progress = proc_progress; #if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__)) /* Round out the number of variables. */ n = round_out_variables(n); #endif/*defined(USE_SSE)*/ /* Check the input parameters for errors. */ if (n <= 0) { return LBFGSERR_INVALID_N; } #if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__)) if (n % 8 != 0) { return LBFGSERR_INVALID_N_SSE; } if (!is_aligned(x, 16)) { return LBFGSERR_INVALID_X_SSE; } #endif/*defined(USE_SSE)*/ if (param.epsilon < 0.) { return LBFGSERR_INVALID_EPSILON; } if (param.past < 0) { return LBFGSERR_INVALID_TESTPERIOD; } if (param.delta < 0.) { return LBFGSERR_INVALID_DELTA; } if (param.min_step < 0.) { return LBFGSERR_INVALID_MINSTEP; } if (param.max_step < param.min_step) { return LBFGSERR_INVALID_MAXSTEP; } if (param.ftol < 0.) { return LBFGSERR_INVALID_FTOL; } if (param.linesearch == LBFGS_LINESEARCH_BACKTRACKING_WOLFE || param.linesearch == LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE) { if (param.wolfe <= param.ftol || 1. <= param.wolfe) { return LBFGSERR_INVALID_WOLFE; } } if (param.gtol < 0.) { return LBFGSERR_INVALID_GTOL; } if (param.xtol < 0.) { return LBFGSERR_INVALID_XTOL; } if (param.max_linesearch <= 0) { return LBFGSERR_INVALID_MAXLINESEARCH; } if (param.orthantwise_c < 0.) { return LBFGSERR_INVALID_ORTHANTWISE; } if (param.orthantwise_start < 0 || n < param.orthantwise_start) { return LBFGSERR_INVALID_ORTHANTWISE_START; } if (param.orthantwise_end < 0) { param.orthantwise_end = n; } if (n < param.orthantwise_end) { return LBFGSERR_INVALID_ORTHANTWISE_END; } if (param.orthantwise_c != 0.) { switch (param.linesearch) { case LBFGS_LINESEARCH_BACKTRACKING: linesearch = line_search_backtracking_owlqn; break; default: /* Only the backtracking method is available. */ return LBFGSERR_INVALID_LINESEARCH; } } else { switch (param.linesearch) { case LBFGS_LINESEARCH_MORETHUENTE: linesearch = line_search_morethuente; break; case LBFGS_LINESEARCH_BACKTRACKING_ARMIJO: case LBFGS_LINESEARCH_BACKTRACKING_WOLFE: case LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE: linesearch = line_search_backtracking; break; default: return LBFGSERR_INVALID_LINESEARCH; } } /* Allocate working space. */ xp = (lbfgsfloatval_t*)vecalloc((size_t) n * sizeof(lbfgsfloatval_t)); g = (lbfgsfloatval_t*)vecalloc((size_t) n * sizeof(lbfgsfloatval_t)); gp = (lbfgsfloatval_t*)vecalloc((size_t) n * sizeof(lbfgsfloatval_t)); d = (lbfgsfloatval_t*)vecalloc((size_t) n * sizeof(lbfgsfloatval_t)); w = (lbfgsfloatval_t*)vecalloc((size_t) n * sizeof(lbfgsfloatval_t)); if (xp == NULL || g == NULL || gp == NULL || d == NULL || w == NULL) { ret = LBFGSERR_OUTOFMEMORY; goto lbfgs_exit; } if (param.orthantwise_c != 0.) { /* Allocate working space for OW-LQN. */ pg = (lbfgsfloatval_t*)vecalloc((size_t) n * sizeof(lbfgsfloatval_t)); if (pg == NULL) { ret = LBFGSERR_OUTOFMEMORY; goto lbfgs_exit; } } /* Allocate limited memory storage. */ lm = (iteration_data_t*)vecalloc((size_t) m * sizeof(iteration_data_t)); if (lm == NULL) { ret = LBFGSERR_OUTOFMEMORY; goto lbfgs_exit; } /* Initialize the limited memory. */ for (i = 0;i < m;++i) { it = &lm[i]; it->alpha = 0; it->ys = 0; it->s = (lbfgsfloatval_t*)vecalloc((size_t) n * sizeof(lbfgsfloatval_t)); it->y = (lbfgsfloatval_t*)vecalloc((size_t) n * sizeof(lbfgsfloatval_t)); if (it->s == NULL || it->y == NULL) { ret = LBFGSERR_OUTOFMEMORY; goto lbfgs_exit; } } /* Allocate an array for storing previous values of the objective function. */ if (0 < param.past) { pf = (lbfgsfloatval_t*)vecalloc((size_t) param.past * sizeof(lbfgsfloatval_t)); } /* Evaluate the function value and its gradient. */ fx = cd.proc_evaluate(cd.instance, x, g, cd.n, 0); if (0. != param.orthantwise_c) { /* Compute the L1 norm of the variable and add it to the object value. */ xnorm = owlqn_x1norm(x, param.orthantwise_start, param.orthantwise_end); fx += xnorm * param.orthantwise_c; owlqn_pseudo_gradient( pg, x, g, n, param.orthantwise_c, param.orthantwise_start, param.orthantwise_end ); } /* Store the initial value of the objective function. */ if (pf != NULL) { pf[0] = fx; } /* Compute the direction; we assume the initial hessian matrix H_0 as the identity matrix. */ if (param.orthantwise_c == 0.) { vecncpy(d, g, n); } else { vecncpy(d, pg, n); } /* Make sure that the initial variables are not a minimizer. */ vec2norm(&xnorm, x, n); if (param.orthantwise_c == 0.) { vec2norm(&gnorm, g, n); } else { vec2norm(&gnorm, pg, n); } if (xnorm < 1.0) xnorm = 1.0; if (gnorm / xnorm <= param.epsilon) { ret = LBFGS_ALREADY_MINIMIZED; goto lbfgs_exit; } /* Compute the initial step: step = 1.0 / sqrt(vecdot(d, d, n)) */ vec2norminv(&step, d, n); k = 1; end = 0; for (;;) { /* Store the current position and gradient vectors. */ veccpy(xp, x, n); veccpy(gp, g, n); /* Search for an optimal step. */ if (param.orthantwise_c == 0.) { ls = linesearch(n, x, &fx, g, d, &step, xp, gp, w, &cd, ¶m); } else { ls = linesearch(n, x, &fx, g, d, &step, xp, pg, w, &cd, ¶m); owlqn_pseudo_gradient( pg, x, g, n, param.orthantwise_c, param.orthantwise_start, param.orthantwise_end ); } if (ls < 0) { /* Revert to the previous point. */ veccpy(x, xp, n); veccpy(g, gp, n); ret = ls; goto lbfgs_exit; } /* Compute x and g norms. */ vec2norm(&xnorm, x, n); if (param.orthantwise_c == 0.) { vec2norm(&gnorm, g, n); } else { vec2norm(&gnorm, pg, n); } /* Report the progress. */ if (cd.proc_progress) { ret = cd.proc_progress(cd.instance, x, g, fx, xnorm, gnorm, step, cd.n, k, ls); if (ret) { goto lbfgs_exit; } } /* Convergence test. The criterion is given by the following formula: |g(x)| / \max(1, |x|) < \epsilon */ if (xnorm < 1.0) xnorm = 1.0; if (gnorm / xnorm <= param.epsilon) { /* Convergence. */ ret = LBFGS_SUCCESS; break; } /* Test for stopping criterion. The criterion is given by the following formula: (f(past_x) - f(x)) / f(x) < \delta */ if (pf != NULL) { /* We don't test the stopping criterion while k < past. */ if (param.past <= k) { /* Compute the relative improvement from the past. */ rate = (pf[k % param.past] - fx) / fx; /* The stopping criterion. */ if (rate < param.delta) { ret = LBFGS_STOP; break; } } /* Store the current value of the objective function. */ pf[k % param.past] = fx; } if (param.max_iterations != 0 && param.max_iterations < k+1) { /* Maximum number of iterations. */ ret = LBFGSERR_MAXIMUMITERATION; break; } /* Update vectors s and y: s_{k+1} = x_{k+1} - x_{k} = \step * d_{k}. y_{k+1} = g_{k+1} - g_{k}. */ it = &lm[end]; vecdiff(it->s, x, xp, n); vecdiff(it->y, g, gp, n); /* Compute scalars ys and yy: ys = y^t \cdot s = 1 / \rho. yy = y^t \cdot y. Notice that yy is used for scaling the hessian matrix H_0 (Cholesky factor). */ vecdot(&ys, it->y, it->s, n); vecdot(&yy, it->y, it->y, n); it->ys = ys; /* Recursive formula to compute dir = -(H \cdot g). This is described in page 779 of: Jorge Nocedal. Updating Quasi-Newton Matrices with Limited Storage. Mathematics of Computation, Vol. 35, No. 151, pp. 773--782, 1980. */ bound = (m <= k) ? m : k; ++k; end = (end + 1) % m; /* Compute the steepest direction. */ if (param.orthantwise_c == 0.) { /* Compute the negative of gradients. */ vecncpy(d, g, n); } else { vecncpy(d, pg, n); } j = end; for (i = 0;i < bound;++i) { j = (j + m - 1) % m; /* if (--j == -1) j = m-1; */ it = &lm[j]; /* \alpha_{j} = \rho_{j} s^{t}_{j} \cdot q_{k+1}. */ vecdot(&it->alpha, it->s, d, n); it->alpha /= it->ys; /* q_{i} = q_{i+1} - \alpha_{i} y_{i}. */ vecadd(d, it->y, -it->alpha, n); } vecscale(d, ys / yy, n); for (i = 0;i < bound;++i) { it = &lm[j]; /* \beta_{j} = \rho_{j} y^t_{j} \cdot \gamma_{i}. */ vecdot(&beta, it->y, d, n); beta /= it->ys; /* \gamma_{i+1} = \gamma_{i} + (\alpha_{j} - \beta_{j}) s_{j}. */ vecadd(d, it->s, it->alpha - beta, n); j = (j + 1) % m; /* if (++j == m) j = 0; */ } /* Constrain the search direction for orthant-wise updates. */ if (param.orthantwise_c != 0.) { for (i = param.orthantwise_start;i < param.orthantwise_end;++i) { if (d[i] * pg[i] >= 0) { d[i] = 0; } } } /* Now the search direction d is ready. We try step = 1 first. */ step = 1.0; } lbfgs_exit: /* Return the final value of the objective function. */ if (ptr_fx != NULL) { *ptr_fx = fx; } vecfree(pf); /* Free memory blocks used by this function. */ if (lm != NULL) { for (i = 0;i < m;++i) { vecfree(lm[i].s); vecfree(lm[i].y); } vecfree(lm); } vecfree(pg); vecfree(w); vecfree(d); vecfree(gp); vecfree(g); vecfree(xp); return ret; } static int line_search_backtracking( int n, lbfgsfloatval_t *x, lbfgsfloatval_t *f, lbfgsfloatval_t *g, lbfgsfloatval_t *s, lbfgsfloatval_t *stp, const lbfgsfloatval_t* xp, const lbfgsfloatval_t* gp, lbfgsfloatval_t *wp, callback_data_t *cd, const lbfgs_parameter_t *param ) { int count = 0; lbfgsfloatval_t width, dg; lbfgsfloatval_t finit, dginit = 0., dgtest; const lbfgsfloatval_t dec = 0.5, inc = 2.1; /* Check the input parameters for errors. */ if (*stp <= 0.) { return LBFGSERR_INVALIDPARAMETERS; } /* Compute the initial gradient in the search direction. */ vecdot(&dginit, g, s, n); /* Make sure that s points to a descent direction. */ if (0 < dginit) { return LBFGSERR_INCREASEGRADIENT; } /* The initial value of the objective function. */ finit = *f; dgtest = param->ftol * dginit; for (;;) { veccpy(x, xp, n); vecadd(x, s, *stp, n); /* Evaluate the function and gradient values. */ *f = cd->proc_evaluate(cd->instance, x, g, cd->n, *stp); ++count; if (*f > finit + *stp * dgtest) { width = dec; } else { /* The sufficient decrease condition (Armijo condition). */ if (param->linesearch == LBFGS_LINESEARCH_BACKTRACKING_ARMIJO) { /* Exit with the Armijo condition. */ return count; } /* Check the Wolfe condition. */ vecdot(&dg, g, s, n); if (dg < param->wolfe * dginit) { width = inc; } else { if(param->linesearch == LBFGS_LINESEARCH_BACKTRACKING_WOLFE) { /* Exit with the regular Wolfe condition. */ return count; } /* Check the strong Wolfe condition. */ if(dg > -param->wolfe * dginit) { width = dec; } else { /* Exit with the strong Wolfe condition. */ return count; } } } if (*stp < param->min_step) { /* The step is the minimum value. */ return LBFGSERR_MINIMUMSTEP; } if (*stp > param->max_step) { /* The step is the maximum value. */ return LBFGSERR_MAXIMUMSTEP; } if (param->max_linesearch <= count) { /* Maximum number of iteration. */ return LBFGSERR_MAXIMUMLINESEARCH; } (*stp) *= width; } } static int line_search_backtracking_owlqn( int n, lbfgsfloatval_t *x, lbfgsfloatval_t *f, lbfgsfloatval_t *g, lbfgsfloatval_t *s, lbfgsfloatval_t *stp, const lbfgsfloatval_t* xp, const lbfgsfloatval_t* gp, lbfgsfloatval_t *wp, callback_data_t *cd, const lbfgs_parameter_t *param ) { int i, count = 0; lbfgsfloatval_t width = 0.5, norm = 0.; lbfgsfloatval_t finit = *f, dgtest; /* Check the input parameters for errors. */ if (*stp <= 0.) { return LBFGSERR_INVALIDPARAMETERS; } /* Choose the orthant for the new point. */ for (i = 0;i < n;++i) { wp[i] = (xp[i] == 0.) ? -gp[i] : xp[i]; } for (;;) { /* Update the current point. */ veccpy(x, xp, n); vecadd(x, s, *stp, n); /* The current point is projected onto the orthant. */ owlqn_project(x, wp, param->orthantwise_start, param->orthantwise_end); /* Evaluate the function and gradient values. */ *f = cd->proc_evaluate(cd->instance, x, g, cd->n, *stp); /* Compute the L1 norm of the variables and add it to the object value. */ norm = owlqn_x1norm(x, param->orthantwise_start, param->orthantwise_end); *f += norm * param->orthantwise_c; ++count; dgtest = 0.; for (i = 0;i < n;++i) { dgtest += (x[i] - xp[i]) * gp[i]; } if (*f <= finit + param->ftol * dgtest) { /* The sufficient decrease condition. */ return count; } if (*stp < param->min_step) { /* The step is the minimum value. */ return LBFGSERR_MINIMUMSTEP; } if (*stp > param->max_step) { /* The step is the maximum value. */ return LBFGSERR_MAXIMUMSTEP; } if (param->max_linesearch <= count) { /* Maximum number of iteration. */ return LBFGSERR_MAXIMUMLINESEARCH; } (*stp) *= width; } } static int line_search_morethuente( int n, lbfgsfloatval_t *x, lbfgsfloatval_t *f, lbfgsfloatval_t *g, lbfgsfloatval_t *s, lbfgsfloatval_t *stp, const lbfgsfloatval_t* xp, const lbfgsfloatval_t* gp, lbfgsfloatval_t *wa, callback_data_t *cd, const lbfgs_parameter_t *param ) { int count = 0; int brackt, stage1, uinfo = 0; lbfgsfloatval_t dg; lbfgsfloatval_t stx, fx, dgx; lbfgsfloatval_t sty, fy, dgy; lbfgsfloatval_t fxm, dgxm, fym, dgym, fm, dgm; lbfgsfloatval_t finit, ftest1, dginit, dgtest; lbfgsfloatval_t width, prev_width; lbfgsfloatval_t stmin, stmax; /* Check the input parameters for errors. */ if (*stp <= 0.) { return LBFGSERR_INVALIDPARAMETERS; } /* Compute the initial gradient in the search direction. */ vecdot(&dginit, g, s, n); /* Make sure that s points to a descent direction. */ if (0 < dginit) { return LBFGSERR_INCREASEGRADIENT; } /* Initialize local variables. */ brackt = 0; stage1 = 1; finit = *f; dgtest = param->ftol * dginit; width = param->max_step - param->min_step; prev_width = 2.0 * width; /* The variables stx, fx, dgx contain the values of the step, function, and directional derivative at the best step. The variables sty, fy, dgy contain the value of the step, function, and derivative at the other endpoint of the interval of uncertainty. The variables stp, f, dg contain the values of the step, function, and derivative at the current step. */ stx = sty = 0.; fx = fy = finit; dgx = dgy = dginit; for (;;) { /* Set the minimum and maximum steps to correspond to the present interval of uncertainty. */ if (brackt) { stmin = min2(stx, sty); stmax = max2(stx, sty); } else { stmin = stx; stmax = *stp + 4.0 * (*stp - stx); } /* Clip the step in the range of [stpmin, stpmax]. */ if (*stp < param->min_step) *stp = param->min_step; if (param->max_step < *stp) *stp = param->max_step; /* If an unusual termination is to occur then let stp be the lowest point obtained so far. */ if ((brackt && ((*stp <= stmin || stmax <= *stp) || param->max_linesearch <= count + 1 || uinfo != 0)) || (brackt && (stmax - stmin <= param->xtol * stmax))) { *stp = stx; } /* Compute the current value of x: x <- x + (*stp) * s. */ veccpy(x, xp, n); vecadd(x, s, *stp, n); /* Evaluate the function and gradient values. */ *f = cd->proc_evaluate(cd->instance, x, g, cd->n, *stp); vecdot(&dg, g, s, n); ftest1 = finit + *stp * dgtest; ++count; /* Test for errors and convergence. */ if (brackt && ((*stp <= stmin || stmax <= *stp) || uinfo != 0)) { /* Rounding errors prevent further progress. */ return LBFGSERR_ROUNDING_ERROR; } if (*stp == param->max_step && *f <= ftest1 && dg <= dgtest) { /* The step is the maximum value. */ return LBFGSERR_MAXIMUMSTEP; } if (*stp == param->min_step && (ftest1 < *f || dgtest <= dg)) { /* The step is the minimum value. */ return LBFGSERR_MINIMUMSTEP; } if (brackt && (stmax - stmin) <= param->xtol * stmax) { /* Relative width of the interval of uncertainty is at most xtol. */ return LBFGSERR_WIDTHTOOSMALL; } if (param->max_linesearch <= count) { /* Maximum number of iteration. */ return LBFGSERR_MAXIMUMLINESEARCH; } if (*f <= ftest1 && fabs(dg) <= param->gtol * (-dginit)) { /* The sufficient decrease condition and the directional derivative condition hold. */ return count; } /* In the first stage we seek a step for which the modified function has a nonpositive value and nonnegative derivative. */ if (stage1 && *f <= ftest1 && min2(param->ftol, param->gtol) * dginit <= dg) { stage1 = 0; } /* A modified function is used to predict the step only if we have not obtained a step for which the modified function has a nonpositive function value and nonnegative derivative, and if a lower function value has been obtained but the decrease is not sufficient. */ if (stage1 && ftest1 < *f && *f <= fx) { /* Define the modified function and derivative values. */ fm = *f - *stp * dgtest; fxm = fx - stx * dgtest; fym = fy - sty * dgtest; dgm = dg - dgtest; dgxm = dgx - dgtest; dgym = dgy - dgtest; /* Call update_trial_interval() to update the interval of uncertainty and to compute the new step. */ uinfo = update_trial_interval( &stx, &fxm, &dgxm, &sty, &fym, &dgym, stp, &fm, &dgm, stmin, stmax, &brackt ); /* Reset the function and gradient values for f. */ fx = fxm + stx * dgtest; fy = fym + sty * dgtest; dgx = dgxm + dgtest; dgy = dgym + dgtest; } else { /* Call update_trial_interval() to update the interval of uncertainty and to compute the new step. */ uinfo = update_trial_interval( &stx, &fx, &dgx, &sty, &fy, &dgy, stp, f, &dg, stmin, stmax, &brackt ); } /* Force a sufficient decrease in the interval of uncertainty. */ if (brackt) { if (0.66 * prev_width <= fabs(sty - stx)) { *stp = stx + 0.5 * (sty - stx); } prev_width = width; width = fabs(sty - stx); } } } /** * Define the local variables for computing minimizers. */ #define USES_MINIMIZER \ lbfgsfloatval_t a, d, gamma, theta, p, q, r, s; /** * Find a minimizer of an interpolated cubic function. * @param cm The minimizer of the interpolated cubic. * @param u The value of one point, u. * @param fu The value of f(u). * @param du The value of f'(u). * @param v The value of another point, v. * @param fv The value of f(v). * @param du The value of f'(v). */ #define CUBIC_MINIMIZER(cm, u, fu, du, v, fv, dv) \ d = (v) - (u); \ theta = ((fu) - (fv)) * 3 / d + (du) + (dv); \ p = fabs(theta); \ q = fabs(du); \ r = fabs(dv); \ s = max3(p, q, r); \ /* gamma = s*sqrt((theta/s)**2 - (du/s) * (dv/s)) */ \ a = theta / s; \ gamma = s * sqrt(a * a - ((du) / s) * ((dv) / s)); \ if ((v) < (u)) gamma = -gamma; \ p = gamma - (du) + theta; \ q = gamma - (du) + gamma + (dv); \ r = p / q; \ (cm) = (u) + r * d; /** * Find a minimizer of an interpolated cubic function. * @param cm The minimizer of the interpolated cubic. * @param u The value of one point, u. * @param fu The value of f(u). * @param du The value of f'(u). * @param v The value of another point, v. * @param fv The value of f(v). * @param du The value of f'(v). * @param xmin The maximum value. * @param xmin The minimum value. */ #define CUBIC_MINIMIZER2(cm, u, fu, du, v, fv, dv, xmin, xmax) \ d = (v) - (u); \ theta = ((fu) - (fv)) * 3 / d + (du) + (dv); \ p = fabs(theta); \ q = fabs(du); \ r = fabs(dv); \ s = max3(p, q, r); \ /* gamma = s*sqrt((theta/s)**2 - (du/s) * (dv/s)) */ \ a = theta / s; \ gamma = s * sqrt(max2(0, a * a - ((du) / s) * ((dv) / s))); \ if ((u) < (v)) gamma = -gamma; \ p = gamma - (dv) + theta; \ q = gamma - (dv) + gamma + (du); \ r = p / q; \ if (r < 0. && gamma != 0.) { \ (cm) = (v) - r * d; \ } else if (a < 0) { \ (cm) = (xmax); \ } else { \ (cm) = (xmin); \ } /** * Find a minimizer of an interpolated quadratic function. * @param qm The minimizer of the interpolated quadratic. * @param u The value of one point, u. * @param fu The value of f(u). * @param du The value of f'(u). * @param v The value of another point, v. * @param fv The value of f(v). */ #define QUARD_MINIMIZER(qm, u, fu, du, v, fv) \ a = (v) - (u); \ (qm) = (u) + (du) / (((fu) - (fv)) / a + (du)) / 2 * a; /** * Find a minimizer of an interpolated quadratic function. * @param qm The minimizer of the interpolated quadratic. * @param u The value of one point, u. * @param du The value of f'(u). * @param v The value of another point, v. * @param dv The value of f'(v). */ #define QUARD_MINIMIZER2(qm, u, du, v, dv) \ a = (u) - (v); \ (qm) = (v) + (dv) / ((dv) - (du)) * a; /** * Update a safeguarded trial value and interval for line search. * * The parameter x represents the step with the least function value. * The parameter t represents the current step. This function assumes * that the derivative at the point of x in the direction of the step. * If the bracket is set to true, the minimizer has been bracketed in * an interval of uncertainty with endpoints between x and y. * * @param x The pointer to the value of one endpoint. * @param fx The pointer to the value of f(x). * @param dx The pointer to the value of f'(x). * @param y The pointer to the value of another endpoint. * @param fy The pointer to the value of f(y). * @param dy The pointer to the value of f'(y). * @param t The pointer to the value of the trial value, t. * @param ft The pointer to the value of f(t). * @param dt The pointer to the value of f'(t). * @param tmin The minimum value for the trial value, t. * @param tmax The maximum value for the trial value, t. * @param brackt The pointer to the predicate if the trial value is * bracketed. * @retval int Status value. Zero indicates a normal termination. * * @see * Jorge J. More and David J. Thuente. Line search algorithm with * guaranteed sufficient decrease. ACM Transactions on Mathematical * Software (TOMS), Vol 20, No 3, pp. 286-307, 1994. */ static int update_trial_interval( lbfgsfloatval_t *x, lbfgsfloatval_t *fx, lbfgsfloatval_t *dx, lbfgsfloatval_t *y, lbfgsfloatval_t *fy, lbfgsfloatval_t *dy, lbfgsfloatval_t *t, lbfgsfloatval_t *ft, lbfgsfloatval_t *dt, const lbfgsfloatval_t tmin, const lbfgsfloatval_t tmax, int *brackt ) { int bound; int dsign = fsigndiff(dt, dx); lbfgsfloatval_t mc; /* minimizer of an interpolated cubic. */ lbfgsfloatval_t mq; /* minimizer of an interpolated quadratic. */ lbfgsfloatval_t newt; /* new trial value. */ USES_MINIMIZER; /* for CUBIC_MINIMIZER and QUARD_MINIMIZER. */ /* Check the input parameters for errors. */ if (*brackt) { if (*t <= min2(*x, *y) || max2(*x, *y) <= *t) { /* The trival value t is out of the interval. */ return LBFGSERR_OUTOFINTERVAL; } if (0. <= *dx * (*t - *x)) { /* The function must decrease from x. */ return LBFGSERR_INCREASEGRADIENT; } if (tmax < tmin) { /* Incorrect tmin and tmax specified. */ return LBFGSERR_INCORRECT_TMINMAX; } } /* Trial value selection. */ if (*fx < *ft) { /* Case 1: a higher function value. The minimum is brackt. If the cubic minimizer is closer to x than the quadratic one, the cubic one is taken, else the average of the minimizers is taken. */ *brackt = 1; bound = 1; CUBIC_MINIMIZER(mc, *x, *fx, *dx, *t, *ft, *dt); QUARD_MINIMIZER(mq, *x, *fx, *dx, *t, *ft); if (fabs(mc - *x) < fabs(mq - *x)) { newt = mc; } else { newt = mc + 0.5 * (mq - mc); } } else if (dsign) { /* Case 2: a lower function value and derivatives of opposite sign. The minimum is brackt. If the cubic minimizer is closer to x than the quadratic (secant) one, the cubic one is taken, else the quadratic one is taken. */ *brackt = 1; bound = 0; CUBIC_MINIMIZER(mc, *x, *fx, *dx, *t, *ft, *dt); QUARD_MINIMIZER2(mq, *x, *dx, *t, *dt); if (fabs(mc - *t) > fabs(mq - *t)) { newt = mc; } else { newt = mq; } } else if (fabs(*dt) < fabs(*dx)) { /* Case 3: a lower function value, derivatives of the same sign, and the magnitude of the derivative decreases. The cubic minimizer is only used if the cubic tends to infinity in the direction of the minimizer or if the minimum of the cubic is beyond t. Otherwise the cubic minimizer is defined to be either tmin or tmax. The quadratic (secant) minimizer is also computed and if the minimum is brackt then the the minimizer closest to x is taken, else the one farthest away is taken. */ bound = 1; CUBIC_MINIMIZER2(mc, *x, *fx, *dx, *t, *ft, *dt, tmin, tmax); QUARD_MINIMIZER2(mq, *x, *dx, *t, *dt); if (*brackt) { if (fabs(*t - mc) < fabs(*t - mq)) { newt = mc; } else { newt = mq; } } else { if (fabs(*t - mc) > fabs(*t - mq)) { newt = mc; } else { newt = mq; } } } else { /* Case 4: a lower function value, derivatives of the same sign, and the magnitude of the derivative does not decrease. If the minimum is not brackt, the step is either tmin or tmax, else the cubic minimizer is taken. */ bound = 0; if (*brackt) { CUBIC_MINIMIZER(newt, *t, *ft, *dt, *y, *fy, *dy); } else if (*x < *t) { newt = tmax; } else { newt = tmin; } } /* Update the interval of uncertainty. This update does not depend on the new step or the case analysis above. - Case a: if f(x) < f(t), x <- x, y <- t. - Case b: if f(t) <= f(x) && f'(t)*f'(x) > 0, x <- t, y <- y. - Case c: if f(t) <= f(x) && f'(t)*f'(x) < 0, x <- t, y <- x. */ if (*fx < *ft) { /* Case a */ *y = *t; *fy = *ft; *dy = *dt; } else { /* Case c */ if (dsign) { *y = *x; *fy = *fx; *dy = *dx; } /* Cases b and c */ *x = *t; *fx = *ft; *dx = *dt; } /* Clip the new trial value in [tmin, tmax]. */ if (tmax < newt) newt = tmax; if (newt < tmin) newt = tmin; /* Redefine the new trial value if it is close to the upper bound of the interval. */ if (*brackt && bound) { mq = *x + 0.66 * (*y - *x); if (*x < *y) { if (mq < newt) newt = mq; } else { if (newt < mq) newt = mq; } } /* Return the new trial value. */ *t = newt; return 0; } static lbfgsfloatval_t owlqn_x1norm( const lbfgsfloatval_t* x, const int start, const int n ) { int i; lbfgsfloatval_t norm = 0.; for (i = start;i < n;++i) { norm += fabs(x[i]); } return norm; } static void owlqn_pseudo_gradient( lbfgsfloatval_t* pg, const lbfgsfloatval_t* x, const lbfgsfloatval_t* g, const int n, const lbfgsfloatval_t c, const int start, const int end ) { int i; /* Compute the negative of gradients. */ for (i = 0;i < start;++i) { pg[i] = g[i]; } /* Compute the psuedo-gradients. */ for (i = start;i < end;++i) { if (x[i] < 0.) { /* Differentiable. */ pg[i] = g[i] - c; } else if (0. < x[i]) { /* Differentiable. */ pg[i] = g[i] + c; } else { if (g[i] < -c) { /* Take the right partial derivative. */ pg[i] = g[i] + c; } else if (c < g[i]) { /* Take the left partial derivative. */ pg[i] = g[i] - c; } else { pg[i] = 0.; } } } for (i = end;i < n;++i) { pg[i] = g[i]; } } static void owlqn_project( lbfgsfloatval_t* d, const lbfgsfloatval_t* sign, const int start, const int end ) { int i; for (i = start;i < end;++i) { if (d[i] * sign[i] <= 0) { d[i] = 0; } } } leidenbase/src/vendor/plfit/plfit_version.h0000644000176200001440000000170714447675375020636 0ustar liggesusers/* plfit_version.h * * Copyright (C) 2021 Tamas Nepusz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PLFIT_VERSION_H #define PLFIT_VERSION_H #define PLFIT_VERSION_MAJOR 0 #define PLFIT_VERSION_MINOR 9 #define PLFIT_VERSION_PATCH 3 #define PLFIT_VERSION_STRING "0.9.3" #endif leidenbase/src/vendor/mini-gmp/0000755000176200001440000000000014532173045016152 5ustar liggesusersleidenbase/src/vendor/mini-gmp/mini-gmp.h0000644000176200001440000002643414447675375020073 0ustar liggesusers/* mini-gmp, a minimalistic implementation of a GNU GMP subset. Copyright 2011-2015, 2017, 2019-2020 Free Software Foundation, Inc. This file is part of the GNU MP Library. The GNU MP Library is free software; you can redistribute it and/or modify it under the terms of either: * the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. or * the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. or both in parallel, as here. The GNU MP Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received copies of the GNU General Public License and the GNU Lesser General Public License along with the GNU MP Library. If not, see https://www.gnu.org/licenses/. */ /* About mini-gmp: This is a minimal implementation of a subset of the GMP interface. It is intended for inclusion into applications which have modest bignums needs, as a fallback when the real GMP library is not installed. This file defines the public interface. */ #ifndef __MINI_GMP_H__ #define __MINI_GMP_H__ /* For size_t */ #include #if defined (__cplusplus) extern "C" { #endif void mp_set_memory_functions (void *(*) (size_t), void *(*) (void *, size_t, size_t), void (*) (void *, size_t)); void mp_get_memory_functions (void *(**) (size_t), void *(**) (void *, size_t, size_t), void (**) (void *, size_t)); #ifndef MINI_GMP_LIMB_TYPE #define MINI_GMP_LIMB_TYPE long #endif typedef unsigned MINI_GMP_LIMB_TYPE mp_limb_t; typedef long mp_size_t; typedef unsigned long mp_bitcnt_t; typedef mp_limb_t *mp_ptr; typedef const mp_limb_t *mp_srcptr; typedef struct { int _mp_alloc; /* Number of *limbs* allocated and pointed to by the _mp_d field. */ int _mp_size; /* abs(_mp_size) is the number of limbs the last field points to. If _mp_size is negative this is a negative number. */ mp_limb_t *_mp_d; /* Pointer to the limbs. */ } __mpz_struct; typedef __mpz_struct mpz_t[1]; typedef __mpz_struct *mpz_ptr; typedef const __mpz_struct *mpz_srcptr; extern const int mp_bits_per_limb; void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t); void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t); void mpn_zero (mp_ptr, mp_size_t); int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t); int mpn_zero_p (mp_srcptr, mp_size_t); mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); mp_limb_t mpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); mp_limb_t mpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t); int mpn_perfect_square_p (mp_srcptr, mp_size_t); mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t); mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); mp_bitcnt_t mpn_scan0 (mp_srcptr, mp_bitcnt_t); mp_bitcnt_t mpn_scan1 (mp_srcptr, mp_bitcnt_t); void mpn_com (mp_ptr, mp_srcptr, mp_size_t); mp_limb_t mpn_neg (mp_ptr, mp_srcptr, mp_size_t); mp_bitcnt_t mpn_popcount (mp_srcptr, mp_size_t); mp_limb_t mpn_invert_3by2 (mp_limb_t, mp_limb_t); #define mpn_invert_limb(x) mpn_invert_3by2 ((x), 0) size_t mpn_get_str (unsigned char *, int, mp_ptr, mp_size_t); mp_size_t mpn_set_str (mp_ptr, const unsigned char *, size_t, int); void mpz_init (mpz_t); void mpz_init2 (mpz_t, mp_bitcnt_t); void mpz_clear (mpz_t); #define mpz_odd_p(z) (((z)->_mp_size != 0) & (int) (z)->_mp_d[0]) #define mpz_even_p(z) (! mpz_odd_p (z)) int mpz_sgn (const mpz_t); int mpz_cmp_si (const mpz_t, long); int mpz_cmp_ui (const mpz_t, unsigned long); int mpz_cmp (const mpz_t, const mpz_t); int mpz_cmpabs_ui (const mpz_t, unsigned long); int mpz_cmpabs (const mpz_t, const mpz_t); int mpz_cmp_d (const mpz_t, double); int mpz_cmpabs_d (const mpz_t, double); void mpz_abs (mpz_t, const mpz_t); void mpz_neg (mpz_t, const mpz_t); void mpz_swap (mpz_t, mpz_t); void mpz_add_ui (mpz_t, const mpz_t, unsigned long); void mpz_add (mpz_t, const mpz_t, const mpz_t); void mpz_sub_ui (mpz_t, const mpz_t, unsigned long); void mpz_ui_sub (mpz_t, unsigned long, const mpz_t); void mpz_sub (mpz_t, const mpz_t, const mpz_t); void mpz_mul_si (mpz_t, const mpz_t, long int); void mpz_mul_ui (mpz_t, const mpz_t, unsigned long int); void mpz_mul (mpz_t, const mpz_t, const mpz_t); void mpz_mul_2exp (mpz_t, const mpz_t, mp_bitcnt_t); void mpz_addmul_ui (mpz_t, const mpz_t, unsigned long int); void mpz_addmul (mpz_t, const mpz_t, const mpz_t); void mpz_submul_ui (mpz_t, const mpz_t, unsigned long int); void mpz_submul (mpz_t, const mpz_t, const mpz_t); void mpz_cdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); void mpz_fdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); void mpz_tdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); void mpz_cdiv_q (mpz_t, const mpz_t, const mpz_t); void mpz_fdiv_q (mpz_t, const mpz_t, const mpz_t); void mpz_tdiv_q (mpz_t, const mpz_t, const mpz_t); void mpz_cdiv_r (mpz_t, const mpz_t, const mpz_t); void mpz_fdiv_r (mpz_t, const mpz_t, const mpz_t); void mpz_tdiv_r (mpz_t, const mpz_t, const mpz_t); void mpz_cdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t); void mpz_fdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t); void mpz_tdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t); void mpz_cdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t); void mpz_fdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t); void mpz_tdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t); void mpz_mod (mpz_t, const mpz_t, const mpz_t); void mpz_divexact (mpz_t, const mpz_t, const mpz_t); int mpz_divisible_p (const mpz_t, const mpz_t); int mpz_congruent_p (const mpz_t, const mpz_t, const mpz_t); unsigned long mpz_cdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); unsigned long mpz_fdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); unsigned long mpz_tdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); unsigned long mpz_cdiv_q_ui (mpz_t, const mpz_t, unsigned long); unsigned long mpz_fdiv_q_ui (mpz_t, const mpz_t, unsigned long); unsigned long mpz_tdiv_q_ui (mpz_t, const mpz_t, unsigned long); unsigned long mpz_cdiv_r_ui (mpz_t, const mpz_t, unsigned long); unsigned long mpz_fdiv_r_ui (mpz_t, const mpz_t, unsigned long); unsigned long mpz_tdiv_r_ui (mpz_t, const mpz_t, unsigned long); unsigned long mpz_cdiv_ui (const mpz_t, unsigned long); unsigned long mpz_fdiv_ui (const mpz_t, unsigned long); unsigned long mpz_tdiv_ui (const mpz_t, unsigned long); unsigned long mpz_mod_ui (mpz_t, const mpz_t, unsigned long); void mpz_divexact_ui (mpz_t, const mpz_t, unsigned long); int mpz_divisible_ui_p (const mpz_t, unsigned long); unsigned long mpz_gcd_ui (mpz_t, const mpz_t, unsigned long); void mpz_gcd (mpz_t, const mpz_t, const mpz_t); void mpz_gcdext (mpz_t, mpz_t, mpz_t, const mpz_t, const mpz_t); void mpz_lcm_ui (mpz_t, const mpz_t, unsigned long); void mpz_lcm (mpz_t, const mpz_t, const mpz_t); int mpz_invert (mpz_t, const mpz_t, const mpz_t); void mpz_sqrtrem (mpz_t, mpz_t, const mpz_t); void mpz_sqrt (mpz_t, const mpz_t); int mpz_perfect_square_p (const mpz_t); void mpz_pow_ui (mpz_t, const mpz_t, unsigned long); void mpz_ui_pow_ui (mpz_t, unsigned long, unsigned long); void mpz_powm (mpz_t, const mpz_t, const mpz_t, const mpz_t); void mpz_powm_ui (mpz_t, const mpz_t, unsigned long, const mpz_t); void mpz_rootrem (mpz_t, mpz_t, const mpz_t, unsigned long); int mpz_root (mpz_t, const mpz_t, unsigned long); void mpz_fac_ui (mpz_t, unsigned long); void mpz_2fac_ui (mpz_t, unsigned long); void mpz_mfac_uiui (mpz_t, unsigned long, unsigned long); void mpz_bin_uiui (mpz_t, unsigned long, unsigned long); int mpz_probab_prime_p (const mpz_t, int); int mpz_tstbit (const mpz_t, mp_bitcnt_t); void mpz_setbit (mpz_t, mp_bitcnt_t); void mpz_clrbit (mpz_t, mp_bitcnt_t); void mpz_combit (mpz_t, mp_bitcnt_t); void mpz_com (mpz_t, const mpz_t); void mpz_and (mpz_t, const mpz_t, const mpz_t); void mpz_ior (mpz_t, const mpz_t, const mpz_t); void mpz_xor (mpz_t, const mpz_t, const mpz_t); mp_bitcnt_t mpz_popcount (const mpz_t); mp_bitcnt_t mpz_hamdist (const mpz_t, const mpz_t); mp_bitcnt_t mpz_scan0 (const mpz_t, mp_bitcnt_t); mp_bitcnt_t mpz_scan1 (const mpz_t, mp_bitcnt_t); int mpz_fits_slong_p (const mpz_t); int mpz_fits_ulong_p (const mpz_t); long int mpz_get_si (const mpz_t); unsigned long int mpz_get_ui (const mpz_t); double mpz_get_d (const mpz_t); size_t mpz_size (const mpz_t); mp_limb_t mpz_getlimbn (const mpz_t, mp_size_t); void mpz_realloc2 (mpz_t, mp_bitcnt_t); mp_srcptr mpz_limbs_read (mpz_srcptr); mp_ptr mpz_limbs_modify (mpz_t, mp_size_t); mp_ptr mpz_limbs_write (mpz_t, mp_size_t); void mpz_limbs_finish (mpz_t, mp_size_t); mpz_srcptr mpz_roinit_n (mpz_t, mp_srcptr, mp_size_t); #define MPZ_ROINIT_N(xp, xs) {{0, (xs),(xp) }} void mpz_set_si (mpz_t, signed long int); void mpz_set_ui (mpz_t, unsigned long int); void mpz_set (mpz_t, const mpz_t); void mpz_set_d (mpz_t, double); void mpz_init_set_si (mpz_t, signed long int); void mpz_init_set_ui (mpz_t, unsigned long int); void mpz_init_set (mpz_t, const mpz_t); void mpz_init_set_d (mpz_t, double); size_t mpz_sizeinbase (const mpz_t, int); char *mpz_get_str (char *, int, const mpz_t); int mpz_set_str (mpz_t, const char *, int); int mpz_init_set_str (mpz_t, const char *, int); /* This long list taken from gmp.h. */ /* For reference, "defined(EOF)" cannot be used here. In g++ 2.95.4, defines EOF but not FILE. */ #if defined (FILE) \ || defined (H_STDIO) \ || defined (_H_STDIO) /* AIX */ \ || defined (_STDIO_H) /* glibc, Sun, SCO */ \ || defined (_STDIO_H_) /* BSD, OSF */ \ || defined (__STDIO_H) /* Borland */ \ || defined (__STDIO_H__) /* IRIX */ \ || defined (_STDIO_INCLUDED) /* HPUX */ \ || defined (__dj_include_stdio_h_) /* DJGPP */ \ || defined (_FILE_DEFINED) /* Microsoft */ \ || defined (__STDIO__) /* Apple MPW MrC */ \ || defined (_MSL_STDIO_H) /* Metrowerks */ \ || defined (_STDIO_H_INCLUDED) /* QNX4 */ \ || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \ || defined (__STDIO_LOADED) /* VMS */ \ || defined (__DEFINED_FILE) /* musl */ size_t mpz_out_str (FILE *, int, const mpz_t); #endif void mpz_import (mpz_t, size_t, int, size_t, int, size_t, const void *); void *mpz_export (void *, size_t *, int, size_t, int, size_t, const mpz_t); #if defined (__cplusplus) } #endif #endif /* __MINI_GMP_H__ */ leidenbase/src/vendor/mini-gmp/mini-gmp.c0000644000176200001440000025722214447675375020067 0ustar liggesusers/* mini-gmp, a minimalistic implementation of a GNU GMP subset. Contributed to the GNU project by Niels Möller Copyright 1991-1997, 1999-2019 Free Software Foundation, Inc. This file is part of the GNU MP Library. The GNU MP Library is free software; you can redistribute it and/or modify it under the terms of either: * the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. or * the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. or both in parallel, as here. The GNU MP Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received copies of the GNU General Public License and the GNU Lesser General Public License along with the GNU MP Library. If not, see https://www.gnu.org/licenses/. */ /* NOTE: All functions in this file which are not declared in mini-gmp.h are internal, and are not intended to be compatible with GMP or with future versions of mini-gmp. */ /* Much of the material copied from GMP files, including: gmp-impl.h, longlong.h, mpn/generic/add_n.c, mpn/generic/addmul_1.c, mpn/generic/lshift.c, mpn/generic/mul_1.c, mpn/generic/mul_basecase.c, mpn/generic/rshift.c, mpn/generic/sbpi1_div_qr.c, mpn/generic/sub_n.c, mpn/generic/submul_1.c. */ #include #include #include #include #include #include #include "mini-gmp.h" #if !defined(MINI_GMP_DONT_USE_FLOAT_H) #include #endif #include "igraph_error.h" /* Macros */ #define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT) #define GMP_LIMB_MAX ((mp_limb_t) ~ (mp_limb_t) 0) #define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1)) #define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2)) #define GMP_LLIMB_MASK (GMP_HLIMB_BIT - 1) #define GMP_ULONG_BITS (sizeof(unsigned long) * CHAR_BIT) #define GMP_ULONG_HIGHBIT ((unsigned long) 1 << (GMP_ULONG_BITS - 1)) #define GMP_ABS(x) ((x) >= 0 ? (x) : -(x)) #define GMP_NEG_CAST(T,x) (-((T)((x) + 1) - 1)) #define GMP_MIN(a, b) ((a) < (b) ? (a) : (b)) #define GMP_MAX(a, b) ((a) > (b) ? (a) : (b)) #define GMP_CMP(a,b) (((a) > (b)) - ((a) < (b))) #if defined(DBL_MANT_DIG) && FLT_RADIX == 2 #define GMP_DBL_MANT_BITS DBL_MANT_DIG #else #define GMP_DBL_MANT_BITS (53) #endif /* Return non-zero if xp,xsize and yp,ysize overlap. If xp+xsize<=yp there's no overlap, or if yp+ysize<=xp there's no overlap. If both these are false, there's an overlap. */ #define GMP_MPN_OVERLAP_P(xp, xsize, yp, ysize) \ ((xp) + (xsize) > (yp) && (yp) + (ysize) > (xp)) #define gmp_assert_nocarry(x) do { \ mp_limb_t __cy = (x); \ assert (__cy == 0); \ } while (0) #define gmp_clz(count, x) do { \ mp_limb_t __clz_x = (x); \ unsigned __clz_c = 0; \ int LOCAL_SHIFT_BITS = 8; \ if (GMP_LIMB_BITS > LOCAL_SHIFT_BITS) \ for (; \ (__clz_x & ((mp_limb_t) 0xff << (GMP_LIMB_BITS - 8))) == 0; \ __clz_c += 8) \ { __clz_x <<= LOCAL_SHIFT_BITS; } \ for (; (__clz_x & GMP_LIMB_HIGHBIT) == 0; __clz_c++) \ __clz_x <<= 1; \ (count) = __clz_c; \ } while (0) #define gmp_ctz(count, x) do { \ mp_limb_t __ctz_x = (x); \ unsigned __ctz_c = 0; \ gmp_clz (__ctz_c, __ctz_x & - __ctz_x); \ (count) = GMP_LIMB_BITS - 1 - __ctz_c; \ } while (0) #define gmp_add_ssaaaa(sh, sl, ah, al, bh, bl) \ do { \ mp_limb_t __x; \ __x = (al) + (bl); \ (sh) = (ah) + (bh) + (__x < (al)); \ (sl) = __x; \ } while (0) #define gmp_sub_ddmmss(sh, sl, ah, al, bh, bl) \ do { \ mp_limb_t __x; \ __x = (al) - (bl); \ (sh) = (ah) - (bh) - ((al) < (bl)); \ (sl) = __x; \ } while (0) #define gmp_umul_ppmm(w1, w0, u, v) \ do { \ int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; \ if (sizeof(unsigned int) * CHAR_BIT >= 2 * GMP_LIMB_BITS) \ { \ unsigned int __ww = (unsigned int) (u) * (v); \ w0 = (mp_limb_t) __ww; \ w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \ } \ else if (GMP_ULONG_BITS >= 2 * GMP_LIMB_BITS) \ { \ unsigned long int __ww = (unsigned long int) (u) * (v); \ w0 = (mp_limb_t) __ww; \ w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \ } \ else { \ mp_limb_t __x0, __x1, __x2, __x3; \ unsigned __ul, __vl, __uh, __vh; \ mp_limb_t __u = (u), __v = (v); \ \ __ul = __u & GMP_LLIMB_MASK; \ __uh = __u >> (GMP_LIMB_BITS / 2); \ __vl = __v & GMP_LLIMB_MASK; \ __vh = __v >> (GMP_LIMB_BITS / 2); \ \ __x0 = (mp_limb_t) __ul * __vl; \ __x1 = (mp_limb_t) __ul * __vh; \ __x2 = (mp_limb_t) __uh * __vl; \ __x3 = (mp_limb_t) __uh * __vh; \ \ __x1 += __x0 >> (GMP_LIMB_BITS / 2);/* this can't give carry */ \ __x1 += __x2; /* but this indeed can */ \ if (__x1 < __x2) /* did we get it? */ \ __x3 += GMP_HLIMB_BIT; /* yes, add it in the proper pos. */ \ \ (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \ (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \ } \ } while (0) #define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \ do { \ mp_limb_t _qh, _ql, _r, _mask; \ gmp_umul_ppmm (_qh, _ql, (nh), (di)); \ gmp_add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \ _r = (nl) - _qh * (d); \ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \ _qh += _mask; \ _r += _mask & (d); \ if (_r >= (d)) \ { \ _r -= (d); \ _qh++; \ } \ \ (r) = _r; \ (q) = _qh; \ } while (0) #define gmp_udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \ do { \ mp_limb_t _q0, _t1, _t0, _mask; \ gmp_umul_ppmm ((q), _q0, (n2), (dinv)); \ gmp_add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \ \ /* Compute the two most significant limbs of n - q'd */ \ (r1) = (n1) - (d1) * (q); \ gmp_sub_ddmmss ((r1), (r0), (r1), (n0), (d1), (d0)); \ gmp_umul_ppmm (_t1, _t0, (d0), (q)); \ gmp_sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \ (q)++; \ \ /* Conditionally adjust q and the remainders */ \ _mask = - (mp_limb_t) ((r1) >= _q0); \ (q) += _mask; \ gmp_add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \ if ((r1) >= (d1)) \ { \ if ((r1) > (d1) || (r0) >= (d0)) \ { \ (q)++; \ gmp_sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \ } \ } \ } while (0) /* Swap macros. */ #define MP_LIMB_T_SWAP(x, y) \ do { \ mp_limb_t __mp_limb_t_swap__tmp = (x); \ (x) = (y); \ (y) = __mp_limb_t_swap__tmp; \ } while (0) #define MP_SIZE_T_SWAP(x, y) \ do { \ mp_size_t __mp_size_t_swap__tmp = (x); \ (x) = (y); \ (y) = __mp_size_t_swap__tmp; \ } while (0) #define MP_BITCNT_T_SWAP(x,y) \ do { \ mp_bitcnt_t __mp_bitcnt_t_swap__tmp = (x); \ (x) = (y); \ (y) = __mp_bitcnt_t_swap__tmp; \ } while (0) #define MP_PTR_SWAP(x, y) \ do { \ mp_ptr __mp_ptr_swap__tmp = (x); \ (x) = (y); \ (y) = __mp_ptr_swap__tmp; \ } while (0) #define MP_SRCPTR_SWAP(x, y) \ do { \ mp_srcptr __mp_srcptr_swap__tmp = (x); \ (x) = (y); \ (y) = __mp_srcptr_swap__tmp; \ } while (0) #define MPN_PTR_SWAP(xp,xs, yp,ys) \ do { \ MP_PTR_SWAP (xp, yp); \ MP_SIZE_T_SWAP (xs, ys); \ } while(0) #define MPN_SRCPTR_SWAP(xp,xs, yp,ys) \ do { \ MP_SRCPTR_SWAP (xp, yp); \ MP_SIZE_T_SWAP (xs, ys); \ } while(0) #define MPZ_PTR_SWAP(x, y) \ do { \ mpz_ptr __mpz_ptr_swap__tmp = (x); \ (x) = (y); \ (y) = __mpz_ptr_swap__tmp; \ } while (0) #define MPZ_SRCPTR_SWAP(x, y) \ do { \ mpz_srcptr __mpz_srcptr_swap__tmp = (x); \ (x) = (y); \ (y) = __mpz_srcptr_swap__tmp; \ } while (0) const int mp_bits_per_limb = GMP_LIMB_BITS; /* Memory allocation and other helper functions. */ static void gmp_die (const char *msg) { /* fprintf (stderr, "%s\n", msg); abort(); */ IGRAPH_FATAL(msg); } static void * gmp_default_alloc (size_t size) { void *p; assert (size > 0); p = malloc (size); if (!p) gmp_die("gmp_default_alloc: Virtual memory exhausted."); return p; } static void * gmp_default_realloc (void *old, size_t unused_old_size, size_t new_size) { void * p; p = realloc (old, new_size); if (!p) gmp_die("gmp_default_realloc: Virtual memory exhausted."); return p; } static void gmp_default_free (void *p, size_t unused_size) { free (p); } static void * (*gmp_allocate_func) (size_t) = gmp_default_alloc; static void * (*gmp_reallocate_func) (void *, size_t, size_t) = gmp_default_realloc; static void (*gmp_free_func) (void *, size_t) = gmp_default_free; void mp_get_memory_functions (void *(**alloc_func) (size_t), void *(**realloc_func) (void *, size_t, size_t), void (**free_func) (void *, size_t)) { if (alloc_func) *alloc_func = gmp_allocate_func; if (realloc_func) *realloc_func = gmp_reallocate_func; if (free_func) *free_func = gmp_free_func; } void mp_set_memory_functions (void *(*alloc_func) (size_t), void *(*realloc_func) (void *, size_t, size_t), void (*free_func) (void *, size_t)) { if (!alloc_func) alloc_func = gmp_default_alloc; if (!realloc_func) realloc_func = gmp_default_realloc; if (!free_func) free_func = gmp_default_free; gmp_allocate_func = alloc_func; gmp_reallocate_func = realloc_func; gmp_free_func = free_func; } #define gmp_xalloc(size) ((*gmp_allocate_func)((size))) #define gmp_free(p) ((*gmp_free_func) ((p), 0)) static mp_ptr gmp_xalloc_limbs (mp_size_t size) { return (mp_ptr) gmp_xalloc (size * sizeof (mp_limb_t)); } static mp_ptr gmp_xrealloc_limbs (mp_ptr old, mp_size_t size) { assert (size > 0); return (mp_ptr) (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t)); } /* MPN interface */ void mpn_copyi (mp_ptr d, mp_srcptr s, mp_size_t n) { mp_size_t i; for (i = 0; i < n; i++) d[i] = s[i]; } void mpn_copyd (mp_ptr d, mp_srcptr s, mp_size_t n) { while (--n >= 0) d[n] = s[n]; } int mpn_cmp (mp_srcptr ap, mp_srcptr bp, mp_size_t n) { while (--n >= 0) { if (ap[n] != bp[n]) return ap[n] > bp[n] ? 1 : -1; } return 0; } static int mpn_cmp4 (mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn) { if (an != bn) return an < bn ? -1 : 1; else return mpn_cmp (ap, bp, an); } static mp_size_t mpn_normalized_size (mp_srcptr xp, mp_size_t n) { while (n > 0 && xp[n-1] == 0) --n; return n; } int mpn_zero_p(mp_srcptr rp, mp_size_t n) { return mpn_normalized_size (rp, n) == 0; } void mpn_zero (mp_ptr rp, mp_size_t n) { while (--n >= 0) rp[n] = 0; } mp_limb_t mpn_add_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b) { mp_size_t i; assert (n > 0); i = 0; do { mp_limb_t r = ap[i] + b; /* Carry out */ b = (r < b); rp[i] = r; } while (++i < n); return b; } mp_limb_t mpn_add_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n) { mp_size_t i; mp_limb_t cy; for (i = 0, cy = 0; i < n; i++) { mp_limb_t a, b, r; a = ap[i]; b = bp[i]; r = a + cy; cy = (r < cy); r += b; cy += (r < b); rp[i] = r; } return cy; } mp_limb_t mpn_add (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn) { mp_limb_t cy; assert (an >= bn); cy = mpn_add_n (rp, ap, bp, bn); if (an > bn) cy = mpn_add_1 (rp + bn, ap + bn, an - bn, cy); return cy; } mp_limb_t mpn_sub_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b) { mp_size_t i; assert (n > 0); i = 0; do { mp_limb_t a = ap[i]; /* Carry out */ mp_limb_t cy = a < b; rp[i] = a - b; b = cy; } while (++i < n); return b; } mp_limb_t mpn_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n) { mp_size_t i; mp_limb_t cy; for (i = 0, cy = 0; i < n; i++) { mp_limb_t a, b; a = ap[i]; b = bp[i]; b += cy; cy = (b < cy); cy += (a < b); rp[i] = a - b; } return cy; } mp_limb_t mpn_sub (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn) { mp_limb_t cy; assert (an >= bn); cy = mpn_sub_n (rp, ap, bp, bn); if (an > bn) cy = mpn_sub_1 (rp + bn, ap + bn, an - bn, cy); return cy; } mp_limb_t mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) { mp_limb_t ul, cl, hpl, lpl; assert (n >= 1); cl = 0; do { ul = *up++; gmp_umul_ppmm (hpl, lpl, ul, vl); lpl += cl; cl = (lpl < cl) + hpl; *rp++ = lpl; } while (--n != 0); return cl; } mp_limb_t mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) { mp_limb_t ul, cl, hpl, lpl, rl; assert (n >= 1); cl = 0; do { ul = *up++; gmp_umul_ppmm (hpl, lpl, ul, vl); lpl += cl; cl = (lpl < cl) + hpl; rl = *rp; lpl = rl + lpl; cl += lpl < rl; *rp++ = lpl; } while (--n != 0); return cl; } mp_limb_t mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) { mp_limb_t ul, cl, hpl, lpl, rl; assert (n >= 1); cl = 0; do { ul = *up++; gmp_umul_ppmm (hpl, lpl, ul, vl); lpl += cl; cl = (lpl < cl) + hpl; rl = *rp; lpl = rl - lpl; cl += lpl > rl; *rp++ = lpl; } while (--n != 0); return cl; } mp_limb_t mpn_mul (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn) { assert (un >= vn); assert (vn >= 1); assert (!GMP_MPN_OVERLAP_P(rp, un + vn, up, un)); assert (!GMP_MPN_OVERLAP_P(rp, un + vn, vp, vn)); /* We first multiply by the low order limb. This result can be stored, not added, to rp. We also avoid a loop for zeroing this way. */ rp[un] = mpn_mul_1 (rp, up, un, vp[0]); /* Now accumulate the product of up[] and the next higher limb from vp[]. */ while (--vn >= 1) { rp += 1, vp += 1; rp[un] = mpn_addmul_1 (rp, up, un, vp[0]); } return rp[un]; } void mpn_mul_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n) { mpn_mul (rp, ap, n, bp, n); } void mpn_sqr (mp_ptr rp, mp_srcptr ap, mp_size_t n) { mpn_mul (rp, ap, n, ap, n); } mp_limb_t mpn_lshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt) { mp_limb_t high_limb, low_limb; unsigned int tnc; mp_limb_t retval; assert (n >= 1); assert (cnt >= 1); assert (cnt < GMP_LIMB_BITS); up += n; rp += n; tnc = GMP_LIMB_BITS - cnt; low_limb = *--up; retval = low_limb >> tnc; high_limb = (low_limb << cnt); while (--n != 0) { low_limb = *--up; *--rp = high_limb | (low_limb >> tnc); high_limb = (low_limb << cnt); } *--rp = high_limb; return retval; } mp_limb_t mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt) { mp_limb_t high_limb, low_limb; unsigned int tnc; mp_limb_t retval; assert (n >= 1); assert (cnt >= 1); assert (cnt < GMP_LIMB_BITS); tnc = GMP_LIMB_BITS - cnt; high_limb = *up++; retval = (high_limb << tnc); low_limb = high_limb >> cnt; while (--n != 0) { high_limb = *up++; *rp++ = low_limb | (high_limb << tnc); low_limb = high_limb >> cnt; } *rp = low_limb; return retval; } static mp_bitcnt_t mpn_common_scan (mp_limb_t limb, mp_size_t i, mp_srcptr up, mp_size_t un, mp_limb_t ux) { unsigned cnt; assert (ux == 0 || ux == GMP_LIMB_MAX); assert (0 <= i && i <= un ); while (limb == 0) { i++; if (i == un) return (ux == 0 ? ~(mp_bitcnt_t) 0 : un * GMP_LIMB_BITS); limb = ux ^ up[i]; } gmp_ctz (cnt, limb); return (mp_bitcnt_t) i * GMP_LIMB_BITS + cnt; } mp_bitcnt_t mpn_scan1 (mp_srcptr ptr, mp_bitcnt_t bit) { mp_size_t i; i = bit / GMP_LIMB_BITS; return mpn_common_scan ( ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)), i, ptr, i, 0); } mp_bitcnt_t mpn_scan0 (mp_srcptr ptr, mp_bitcnt_t bit) { mp_size_t i; i = bit / GMP_LIMB_BITS; return mpn_common_scan (~ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)), i, ptr, i, GMP_LIMB_MAX); } void mpn_com (mp_ptr rp, mp_srcptr up, mp_size_t n) { while (--n >= 0) *rp++ = ~ *up++; } mp_limb_t mpn_neg (mp_ptr rp, mp_srcptr up, mp_size_t n) { while (*up == 0) { *rp = 0; if (!--n) return 0; ++up; ++rp; } *rp = - *up; mpn_com (++rp, ++up, --n); return 1; } /* MPN division interface. */ /* The 3/2 inverse is defined as m = floor( (B^3-1) / (B u1 + u0)) - B */ mp_limb_t mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) { mp_limb_t r, m; { mp_limb_t p, ql; unsigned ul, uh, qh; /* For notation, let b denote the half-limb base, so that B = b^2. Split u1 = b uh + ul. */ ul = u1 & GMP_LLIMB_MASK; uh = u1 >> (GMP_LIMB_BITS / 2); /* Approximation of the high half of quotient. Differs from the 2/1 inverse of the half limb uh, since we have already subtracted u0. */ qh = (u1 ^ GMP_LIMB_MAX) / uh; /* Adjust to get a half-limb 3/2 inverse, i.e., we want qh' = floor( (b^3 - 1) / u) - b = floor ((b^3 - b u - 1) / u = floor( (b (~u) + b-1) / u), and the remainder r = b (~u) + b-1 - qh (b uh + ul) = b (~u - qh uh) + b-1 - qh ul Subtraction of qh ul may underflow, which implies adjustments. But by normalization, 2 u >= B > qh ul, so we need to adjust by at most 2. */ r = ((~u1 - (mp_limb_t) qh * uh) << (GMP_LIMB_BITS / 2)) | GMP_LLIMB_MASK; p = (mp_limb_t) qh * ul; /* Adjustment steps taken from udiv_qrnnd_c */ if (r < p) { qh--; r += u1; if (r >= u1) /* i.e. we didn't get carry when adding to r */ if (r < p) { qh--; r += u1; } } r -= p; /* Low half of the quotient is ql = floor ( (b r + b-1) / u1). This is a 3/2 division (on half-limbs), for which qh is a suitable inverse. */ p = (r >> (GMP_LIMB_BITS / 2)) * qh + r; /* Unlike full-limb 3/2, we can add 1 without overflow. For this to work, it is essential that ql is a full mp_limb_t. */ ql = (p >> (GMP_LIMB_BITS / 2)) + 1; /* By the 3/2 trick, we don't need the high half limb. */ r = (r << (GMP_LIMB_BITS / 2)) + GMP_LLIMB_MASK - ql * u1; if (r >= (GMP_LIMB_MAX & (p << (GMP_LIMB_BITS / 2)))) { ql--; r += u1; } m = ((mp_limb_t) qh << (GMP_LIMB_BITS / 2)) + ql; if (r >= u1) { m++; r -= u1; } } /* Now m is the 2/1 inverse of u1. If u0 > 0, adjust it to become a 3/2 inverse. */ if (u0 > 0) { mp_limb_t th, tl; r = ~r; r += u0; if (r < u0) { m--; if (r >= u1) { m--; r -= u1; } r -= u1; } gmp_umul_ppmm (th, tl, u0, m); r += th; if (r < th) { m--; m -= ((r > u1) | ((r == u1) & (tl > u0))); } } return m; } struct gmp_div_inverse { /* Normalization shift count. */ unsigned shift; /* Normalized divisor (d0 unused for mpn_div_qr_1) */ mp_limb_t d1, d0; /* Inverse, for 2/1 or 3/2. */ mp_limb_t di; }; static void mpn_div_qr_1_invert (struct gmp_div_inverse *inv, mp_limb_t d) { unsigned shift; assert (d > 0); gmp_clz (shift, d); inv->shift = shift; inv->d1 = d << shift; inv->di = mpn_invert_limb (inv->d1); } static void mpn_div_qr_2_invert (struct gmp_div_inverse *inv, mp_limb_t d1, mp_limb_t d0) { unsigned shift; assert (d1 > 0); gmp_clz (shift, d1); inv->shift = shift; if (shift > 0) { d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift)); d0 <<= shift; } inv->d1 = d1; inv->d0 = d0; inv->di = mpn_invert_3by2 (d1, d0); } static void mpn_div_qr_invert (struct gmp_div_inverse *inv, mp_srcptr dp, mp_size_t dn) { assert (dn > 0); if (dn == 1) mpn_div_qr_1_invert (inv, dp[0]); else if (dn == 2) mpn_div_qr_2_invert (inv, dp[1], dp[0]); else { unsigned shift; mp_limb_t d1, d0; d1 = dp[dn-1]; d0 = dp[dn-2]; assert (d1 > 0); gmp_clz (shift, d1); inv->shift = shift; if (shift > 0) { d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift)); d0 = (d0 << shift) | (dp[dn-3] >> (GMP_LIMB_BITS - shift)); } inv->d1 = d1; inv->d0 = d0; inv->di = mpn_invert_3by2 (d1, d0); } } /* Not matching current public gmp interface, rather corresponding to the sbpi1_div_* functions. */ static mp_limb_t mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn, const struct gmp_div_inverse *inv) { mp_limb_t d, di; mp_limb_t r; mp_ptr tp = NULL; if (inv->shift > 0) { /* Shift, reusing qp area if possible. In-place shift if qp == np. */ tp = qp ? qp : gmp_xalloc_limbs (nn); r = mpn_lshift (tp, np, nn, inv->shift); np = tp; } else r = 0; d = inv->d1; di = inv->di; while (--nn >= 0) { mp_limb_t q; gmp_udiv_qrnnd_preinv (q, r, r, np[nn], d, di); if (qp) qp[nn] = q; } if ((inv->shift > 0) && (tp != qp)) gmp_free (tp); return r >> inv->shift; } static void mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn, const struct gmp_div_inverse *inv) { unsigned shift; mp_size_t i; mp_limb_t d1, d0, di, r1, r0; assert (nn >= 2); shift = inv->shift; d1 = inv->d1; d0 = inv->d0; di = inv->di; if (shift > 0) r1 = mpn_lshift (np, np, nn, shift); else r1 = 0; r0 = np[nn - 1]; i = nn - 2; do { mp_limb_t n0, q; n0 = np[i]; gmp_udiv_qr_3by2 (q, r1, r0, r1, r0, n0, d1, d0, di); if (qp) qp[i] = q; } while (--i >= 0); if (shift > 0) { assert ((r0 & (GMP_LIMB_MAX >> (GMP_LIMB_BITS - shift))) == 0); r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift)); r1 >>= shift; } np[1] = r1; np[0] = r0; } static void mpn_div_qr_pi1 (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_limb_t n1, mp_srcptr dp, mp_size_t dn, mp_limb_t dinv) { mp_size_t i; mp_limb_t d1, d0; mp_limb_t cy, cy1; mp_limb_t q; assert (dn > 2); assert (nn >= dn); d1 = dp[dn - 1]; d0 = dp[dn - 2]; assert ((d1 & GMP_LIMB_HIGHBIT) != 0); /* Iteration variable is the index of the q limb. * * We divide * by */ i = nn - dn; do { mp_limb_t n0 = np[dn-1+i]; if (n1 == d1 && n0 == d0) { q = GMP_LIMB_MAX; mpn_submul_1 (np+i, dp, dn, q); n1 = np[dn-1+i]; /* update n1, last loop's value will now be invalid */ } else { gmp_udiv_qr_3by2 (q, n1, n0, n1, n0, np[dn-2+i], d1, d0, dinv); cy = mpn_submul_1 (np + i, dp, dn-2, q); cy1 = n0 < cy; n0 = n0 - cy; cy = n1 < cy1; n1 = n1 - cy1; np[dn-2+i] = n0; if (cy != 0) { n1 += d1 + mpn_add_n (np + i, np + i, dp, dn - 1); q--; } } if (qp) qp[i] = q; } while (--i >= 0); np[dn - 1] = n1; } static void mpn_div_qr_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn, const struct gmp_div_inverse *inv) { assert (dn > 0); assert (nn >= dn); if (dn == 1) np[0] = mpn_div_qr_1_preinv (qp, np, nn, inv); else if (dn == 2) mpn_div_qr_2_preinv (qp, np, nn, inv); else { mp_limb_t nh; unsigned shift; assert (inv->d1 == dp[dn-1]); assert (inv->d0 == dp[dn-2]); assert ((inv->d1 & GMP_LIMB_HIGHBIT) != 0); shift = inv->shift; if (shift > 0) nh = mpn_lshift (np, np, nn, shift); else nh = 0; mpn_div_qr_pi1 (qp, np, nn, nh, dp, dn, inv->di); if (shift > 0) gmp_assert_nocarry (mpn_rshift (np, np, dn, shift)); } } static void mpn_div_qr (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn) { struct gmp_div_inverse inv; mp_ptr tp = NULL; assert (dn > 0); assert (nn >= dn); mpn_div_qr_invert (&inv, dp, dn); if (dn > 2 && inv.shift > 0) { tp = gmp_xalloc_limbs (dn); gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift)); dp = tp; } mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv); if (tp) gmp_free (tp); } /* MPN base conversion. */ static unsigned mpn_base_power_of_two_p (unsigned b) { switch (b) { case 2: return 1; case 4: return 2; case 8: return 3; case 16: return 4; case 32: return 5; case 64: return 6; case 128: return 7; case 256: return 8; default: return 0; } } struct mpn_base_info { /* bb is the largest power of the base which fits in one limb, and exp is the corresponding exponent. */ unsigned exp; mp_limb_t bb; }; static void mpn_get_base_info (struct mpn_base_info *info, mp_limb_t b) { mp_limb_t m; mp_limb_t p; unsigned exp; m = GMP_LIMB_MAX / b; for (exp = 1, p = b; p <= m; exp++) p *= b; info->exp = exp; info->bb = p; } static mp_bitcnt_t mpn_limb_size_in_base_2 (mp_limb_t u) { unsigned shift; assert (u > 0); gmp_clz (shift, u); return GMP_LIMB_BITS - shift; } static size_t mpn_get_str_bits (unsigned char *sp, unsigned bits, mp_srcptr up, mp_size_t un) { unsigned char mask; size_t sn, j; mp_size_t i; unsigned shift; sn = ((un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]) + bits - 1) / bits; mask = (1U << bits) - 1; for (i = 0, j = sn, shift = 0; j-- > 0;) { unsigned char digit = up[i] >> shift; shift += bits; if (shift >= GMP_LIMB_BITS && ++i < un) { shift -= GMP_LIMB_BITS; digit |= up[i] << (bits - shift); } sp[j] = digit & mask; } return sn; } /* We generate digits from the least significant end, and reverse at the end. */ static size_t mpn_limb_get_str (unsigned char *sp, mp_limb_t w, const struct gmp_div_inverse *binv) { mp_size_t i; for (i = 0; w > 0; i++) { mp_limb_t h, l, r; h = w >> (GMP_LIMB_BITS - binv->shift); l = w << binv->shift; gmp_udiv_qrnnd_preinv (w, r, h, l, binv->d1, binv->di); assert ((r & (GMP_LIMB_MAX >> (GMP_LIMB_BITS - binv->shift))) == 0); r >>= binv->shift; sp[i] = r; } return i; } static size_t mpn_get_str_other (unsigned char *sp, int base, const struct mpn_base_info *info, mp_ptr up, mp_size_t un) { struct gmp_div_inverse binv; size_t sn; size_t i; mpn_div_qr_1_invert (&binv, base); sn = 0; if (un > 1) { struct gmp_div_inverse bbinv; mpn_div_qr_1_invert (&bbinv, info->bb); do { mp_limb_t w; size_t done; w = mpn_div_qr_1_preinv (up, up, un, &bbinv); un -= (up[un-1] == 0); done = mpn_limb_get_str (sp + sn, w, &binv); for (sn += done; done < info->exp; done++) sp[sn++] = 0; } while (un > 1); } sn += mpn_limb_get_str (sp + sn, up[0], &binv); /* Reverse order */ for (i = 0; 2*i + 1 < sn; i++) { unsigned char t = sp[i]; sp[i] = sp[sn - i - 1]; sp[sn - i - 1] = t; } return sn; } size_t mpn_get_str (unsigned char *sp, int base, mp_ptr up, mp_size_t un) { unsigned bits; assert (un > 0); assert (up[un-1] > 0); bits = mpn_base_power_of_two_p (base); if (bits) return mpn_get_str_bits (sp, bits, up, un); else { struct mpn_base_info info; mpn_get_base_info (&info, base); return mpn_get_str_other (sp, base, &info, up, un); } } static mp_size_t mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, size_t sn, unsigned bits) { mp_size_t rn; size_t j; unsigned shift; for (j = sn, rn = 0, shift = 0; j-- > 0; ) { if (shift == 0) { rp[rn++] = sp[j]; shift += bits; } else { rp[rn-1] |= (mp_limb_t) sp[j] << shift; shift += bits; if (shift >= GMP_LIMB_BITS) { shift -= GMP_LIMB_BITS; if (shift > 0) rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift); } } } rn = mpn_normalized_size (rp, rn); return rn; } /* Result is usually normalized, except for all-zero input, in which case a single zero limb is written at *RP, and 1 is returned. */ static mp_size_t mpn_set_str_other (mp_ptr rp, const unsigned char *sp, size_t sn, mp_limb_t b, const struct mpn_base_info *info) { mp_size_t rn; mp_limb_t w; unsigned k; size_t j; assert (sn > 0); k = 1 + (sn - 1) % info->exp; j = 0; w = sp[j++]; while (--k != 0) w = w * b + sp[j++]; rp[0] = w; for (rn = 1; j < sn;) { mp_limb_t cy; w = sp[j++]; for (k = 1; k < info->exp; k++) w = w * b + sp[j++]; cy = mpn_mul_1 (rp, rp, rn, info->bb); cy += mpn_add_1 (rp, rp, rn, w); if (cy > 0) rp[rn++] = cy; } assert (j == sn); return rn; } mp_size_t mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base) { unsigned bits; if (sn == 0) return 0; bits = mpn_base_power_of_two_p (base); if (bits) return mpn_set_str_bits (rp, sp, sn, bits); else { struct mpn_base_info info; mpn_get_base_info (&info, base); return mpn_set_str_other (rp, sp, sn, base, &info); } } /* MPZ interface */ void mpz_init (mpz_t r) { static const mp_limb_t dummy_limb = GMP_LIMB_MAX & 0xc1a0; r->_mp_alloc = 0; r->_mp_size = 0; r->_mp_d = (mp_ptr) &dummy_limb; } /* The utility of this function is a bit limited, since many functions assigns the result variable using mpz_swap. */ void mpz_init2 (mpz_t r, mp_bitcnt_t bits) { mp_size_t rn; bits -= (bits != 0); /* Round down, except if 0 */ rn = 1 + bits / GMP_LIMB_BITS; r->_mp_alloc = rn; r->_mp_size = 0; r->_mp_d = gmp_xalloc_limbs (rn); } void mpz_clear (mpz_t r) { if (r->_mp_alloc) gmp_free (r->_mp_d); } static mp_ptr mpz_realloc (mpz_t r, mp_size_t size) { size = GMP_MAX (size, 1); if (r->_mp_alloc) r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size); else r->_mp_d = gmp_xalloc_limbs (size); r->_mp_alloc = size; if (GMP_ABS (r->_mp_size) > size) r->_mp_size = 0; return r->_mp_d; } /* Realloc for an mpz_t WHAT if it has less than NEEDED limbs. */ #define MPZ_REALLOC(z,n) ((n) > (z)->_mp_alloc \ ? mpz_realloc(z,n) \ : (z)->_mp_d) /* MPZ assignment and basic conversions. */ void mpz_set_si (mpz_t r, signed long int x) { if (x >= 0) mpz_set_ui (r, x); else /* (x < 0) */ if (GMP_LIMB_BITS < GMP_ULONG_BITS) { mpz_set_ui (r, GMP_NEG_CAST (unsigned long int, x)); mpz_neg (r, r); } else { r->_mp_size = -1; MPZ_REALLOC (r, 1)[0] = GMP_NEG_CAST (unsigned long int, x); } } void mpz_set_ui (mpz_t r, unsigned long int x) { if (x > 0) { r->_mp_size = 1; MPZ_REALLOC (r, 1)[0] = x; if (GMP_LIMB_BITS < GMP_ULONG_BITS) { int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; while (x >>= LOCAL_GMP_LIMB_BITS) { ++ r->_mp_size; MPZ_REALLOC (r, r->_mp_size)[r->_mp_size - 1] = x; } } } else r->_mp_size = 0; } void mpz_set (mpz_t r, const mpz_t x) { /* Allow the NOP r == x */ if (r != x) { mp_size_t n; mp_ptr rp; n = GMP_ABS (x->_mp_size); rp = MPZ_REALLOC (r, n); mpn_copyi (rp, x->_mp_d, n); r->_mp_size = x->_mp_size; } } void mpz_init_set_si (mpz_t r, signed long int x) { mpz_init (r); mpz_set_si (r, x); } void mpz_init_set_ui (mpz_t r, unsigned long int x) { mpz_init (r); mpz_set_ui (r, x); } void mpz_init_set (mpz_t r, const mpz_t x) { mpz_init (r); mpz_set (r, x); } int mpz_fits_slong_p (const mpz_t u) { return (LONG_MAX + LONG_MIN == 0 || mpz_cmp_ui (u, LONG_MAX) <= 0) && mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, LONG_MIN)) <= 0; } static int mpn_absfits_ulong_p (mp_srcptr up, mp_size_t un) { int ulongsize = GMP_ULONG_BITS / GMP_LIMB_BITS; mp_limb_t ulongrem = 0; if (GMP_ULONG_BITS % GMP_LIMB_BITS != 0) ulongrem = (mp_limb_t) (ULONG_MAX >> GMP_LIMB_BITS * ulongsize) + 1; return un <= ulongsize || (up[ulongsize] < ulongrem && un == ulongsize + 1); } int mpz_fits_ulong_p (const mpz_t u) { mp_size_t us = u->_mp_size; return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us); } long int mpz_get_si (const mpz_t u) { unsigned long r = mpz_get_ui (u); unsigned long c = -LONG_MAX - LONG_MIN; if (u->_mp_size < 0) /* This expression is necessary to properly handle -LONG_MIN */ return -(long) c - (long) ((r - c) & LONG_MAX); else return (long) (r & LONG_MAX); } unsigned long int mpz_get_ui (const mpz_t u) { if (GMP_LIMB_BITS < GMP_ULONG_BITS) { int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; unsigned long r = 0; mp_size_t n = GMP_ABS (u->_mp_size); n = GMP_MIN (n, 1 + (mp_size_t) (GMP_ULONG_BITS - 1) / GMP_LIMB_BITS); while (--n >= 0) r = (r << LOCAL_GMP_LIMB_BITS) + u->_mp_d[n]; return r; } return u->_mp_size == 0 ? 0 : u->_mp_d[0]; } size_t mpz_size (const mpz_t u) { return GMP_ABS (u->_mp_size); } mp_limb_t mpz_getlimbn (const mpz_t u, mp_size_t n) { if (n >= 0 && n < GMP_ABS (u->_mp_size)) return u->_mp_d[n]; else return 0; } void mpz_realloc2 (mpz_t x, mp_bitcnt_t n) { mpz_realloc (x, 1 + (n - (n != 0)) / GMP_LIMB_BITS); } mp_srcptr mpz_limbs_read (mpz_srcptr x) { return x->_mp_d; } mp_ptr mpz_limbs_modify (mpz_t x, mp_size_t n) { assert (n > 0); return MPZ_REALLOC (x, n); } mp_ptr mpz_limbs_write (mpz_t x, mp_size_t n) { return mpz_limbs_modify (x, n); } void mpz_limbs_finish (mpz_t x, mp_size_t xs) { mp_size_t xn; xn = mpn_normalized_size (x->_mp_d, GMP_ABS (xs)); x->_mp_size = xs < 0 ? -xn : xn; } static mpz_srcptr mpz_roinit_normal_n (mpz_t x, mp_srcptr xp, mp_size_t xs) { x->_mp_alloc = 0; x->_mp_d = (mp_ptr) xp; x->_mp_size = xs; return x; } mpz_srcptr mpz_roinit_n (mpz_t x, mp_srcptr xp, mp_size_t xs) { mpz_roinit_normal_n (x, xp, xs); mpz_limbs_finish (x, xs); return x; } /* Conversions and comparison to double. */ void mpz_set_d (mpz_t r, double x) { int sign; mp_ptr rp; mp_size_t rn, i; double B; double Bi; mp_limb_t f; /* x != x is true when x is a NaN, and x == x * 0.5 is true when x is zero or infinity. */ if (x != x || x == x * 0.5) { r->_mp_size = 0; return; } sign = x < 0.0 ; if (sign) x = - x; if (x < 1.0) { r->_mp_size = 0; return; } B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1); Bi = 1.0 / B; for (rn = 1; x >= B; rn++) x *= Bi; rp = MPZ_REALLOC (r, rn); f = (mp_limb_t) x; x -= f; assert (x < 1.0); i = rn-1; rp[i] = f; while (--i >= 0) { x = B * x; f = (mp_limb_t) x; x -= f; assert (x < 1.0); rp[i] = f; } r->_mp_size = sign ? - rn : rn; } void mpz_init_set_d (mpz_t r, double x) { mpz_init (r); mpz_set_d (r, x); } double mpz_get_d (const mpz_t u) { int m; mp_limb_t l; mp_size_t un; double x; double B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1); un = GMP_ABS (u->_mp_size); if (un == 0) return 0.0; l = u->_mp_d[--un]; gmp_clz (m, l); m = m + GMP_DBL_MANT_BITS - GMP_LIMB_BITS; if (m < 0) l &= GMP_LIMB_MAX << -m; for (x = l; --un >= 0;) { x = B*x; if (m > 0) { l = u->_mp_d[un]; m -= GMP_LIMB_BITS; if (m < 0) l &= GMP_LIMB_MAX << -m; x += l; } } if (u->_mp_size < 0) x = -x; return x; } int mpz_cmpabs_d (const mpz_t x, double d) { mp_size_t xn; double B, Bi; mp_size_t i; xn = x->_mp_size; d = GMP_ABS (d); if (xn != 0) { xn = GMP_ABS (xn); B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1); Bi = 1.0 / B; /* Scale d so it can be compared with the top limb. */ for (i = 1; i < xn; i++) d *= Bi; if (d >= B) return -1; /* Compare floor(d) to top limb, subtract and cancel when equal. */ for (i = xn; i-- > 0;) { mp_limb_t f, xl; f = (mp_limb_t) d; xl = x->_mp_d[i]; if (xl > f) return 1; else if (xl < f) return -1; d = B * (d - f); } } return - (d > 0.0); } int mpz_cmp_d (const mpz_t x, double d) { if (x->_mp_size < 0) { if (d >= 0.0) return -1; else return -mpz_cmpabs_d (x, d); } else { if (d < 0.0) return 1; else return mpz_cmpabs_d (x, d); } } /* MPZ comparisons and the like. */ int mpz_sgn (const mpz_t u) { return GMP_CMP (u->_mp_size, 0); } int mpz_cmp_si (const mpz_t u, long v) { mp_size_t usize = u->_mp_size; if (v >= 0) return mpz_cmp_ui (u, v); else if (usize >= 0) return 1; else return - mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, v)); } int mpz_cmp_ui (const mpz_t u, unsigned long v) { mp_size_t usize = u->_mp_size; if (usize < 0) return -1; else return mpz_cmpabs_ui (u, v); } int mpz_cmp (const mpz_t a, const mpz_t b) { mp_size_t asize = a->_mp_size; mp_size_t bsize = b->_mp_size; if (asize != bsize) return (asize < bsize) ? -1 : 1; else if (asize >= 0) return mpn_cmp (a->_mp_d, b->_mp_d, asize); else return mpn_cmp (b->_mp_d, a->_mp_d, -asize); } int mpz_cmpabs_ui (const mpz_t u, unsigned long v) { mp_size_t un = GMP_ABS (u->_mp_size); if (! mpn_absfits_ulong_p (u->_mp_d, un)) return 1; else { unsigned long uu = mpz_get_ui (u); return GMP_CMP(uu, v); } } int mpz_cmpabs (const mpz_t u, const mpz_t v) { return mpn_cmp4 (u->_mp_d, GMP_ABS (u->_mp_size), v->_mp_d, GMP_ABS (v->_mp_size)); } void mpz_abs (mpz_t r, const mpz_t u) { mpz_set (r, u); r->_mp_size = GMP_ABS (r->_mp_size); } void mpz_neg (mpz_t r, const mpz_t u) { mpz_set (r, u); r->_mp_size = -r->_mp_size; } void mpz_swap (mpz_t u, mpz_t v) { MP_SIZE_T_SWAP (u->_mp_size, v->_mp_size); MP_SIZE_T_SWAP (u->_mp_alloc, v->_mp_alloc); MP_PTR_SWAP (u->_mp_d, v->_mp_d); } /* MPZ addition and subtraction */ void mpz_add_ui (mpz_t r, const mpz_t a, unsigned long b) { mpz_t bb; mpz_init_set_ui (bb, b); mpz_add (r, a, bb); mpz_clear (bb); } void mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b) { mpz_ui_sub (r, b, a); mpz_neg (r, r); } void mpz_ui_sub (mpz_t r, unsigned long a, const mpz_t b) { mpz_neg (r, b); mpz_add_ui (r, r, a); } static mp_size_t mpz_abs_add (mpz_t r, const mpz_t a, const mpz_t b) { mp_size_t an = GMP_ABS (a->_mp_size); mp_size_t bn = GMP_ABS (b->_mp_size); mp_ptr rp; mp_limb_t cy; if (an < bn) { MPZ_SRCPTR_SWAP (a, b); MP_SIZE_T_SWAP (an, bn); } rp = MPZ_REALLOC (r, an + 1); cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn); rp[an] = cy; return an + cy; } static mp_size_t mpz_abs_sub (mpz_t r, const mpz_t a, const mpz_t b) { mp_size_t an = GMP_ABS (a->_mp_size); mp_size_t bn = GMP_ABS (b->_mp_size); int cmp; mp_ptr rp; cmp = mpn_cmp4 (a->_mp_d, an, b->_mp_d, bn); if (cmp > 0) { rp = MPZ_REALLOC (r, an); gmp_assert_nocarry (mpn_sub (rp, a->_mp_d, an, b->_mp_d, bn)); return mpn_normalized_size (rp, an); } else if (cmp < 0) { rp = MPZ_REALLOC (r, bn); gmp_assert_nocarry (mpn_sub (rp, b->_mp_d, bn, a->_mp_d, an)); return -mpn_normalized_size (rp, bn); } else return 0; } void mpz_add (mpz_t r, const mpz_t a, const mpz_t b) { mp_size_t rn; if ( (a->_mp_size ^ b->_mp_size) >= 0) rn = mpz_abs_add (r, a, b); else rn = mpz_abs_sub (r, a, b); r->_mp_size = a->_mp_size >= 0 ? rn : - rn; } void mpz_sub (mpz_t r, const mpz_t a, const mpz_t b) { mp_size_t rn; if ( (a->_mp_size ^ b->_mp_size) >= 0) rn = mpz_abs_sub (r, a, b); else rn = mpz_abs_add (r, a, b); r->_mp_size = a->_mp_size >= 0 ? rn : - rn; } /* MPZ multiplication */ void mpz_mul_si (mpz_t r, const mpz_t u, long int v) { if (v < 0) { mpz_mul_ui (r, u, GMP_NEG_CAST (unsigned long int, v)); mpz_neg (r, r); } else mpz_mul_ui (r, u, v); } void mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v) { mpz_t vv; mpz_init_set_ui (vv, v); mpz_mul (r, u, vv); mpz_clear (vv); return; } void mpz_mul (mpz_t r, const mpz_t u, const mpz_t v) { int sign; mp_size_t un, vn, rn; mpz_t t; mp_ptr tp; un = u->_mp_size; vn = v->_mp_size; if (un == 0 || vn == 0) { r->_mp_size = 0; return; } sign = (un ^ vn) < 0; un = GMP_ABS (un); vn = GMP_ABS (vn); mpz_init2 (t, (un + vn) * GMP_LIMB_BITS); tp = t->_mp_d; if (un >= vn) mpn_mul (tp, u->_mp_d, un, v->_mp_d, vn); else mpn_mul (tp, v->_mp_d, vn, u->_mp_d, un); rn = un + vn; rn -= tp[rn-1] == 0; t->_mp_size = sign ? - rn : rn; mpz_swap (r, t); mpz_clear (t); } void mpz_mul_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bits) { mp_size_t un, rn; mp_size_t limbs; unsigned shift; mp_ptr rp; un = GMP_ABS (u->_mp_size); if (un == 0) { r->_mp_size = 0; return; } limbs = bits / GMP_LIMB_BITS; shift = bits % GMP_LIMB_BITS; rn = un + limbs + (shift > 0); rp = MPZ_REALLOC (r, rn); if (shift > 0) { mp_limb_t cy = mpn_lshift (rp + limbs, u->_mp_d, un, shift); rp[rn-1] = cy; rn -= (cy == 0); } else mpn_copyd (rp + limbs, u->_mp_d, un); mpn_zero (rp, limbs); r->_mp_size = (u->_mp_size < 0) ? - rn : rn; } void mpz_addmul_ui (mpz_t r, const mpz_t u, unsigned long int v) { mpz_t t; mpz_init_set_ui (t, v); mpz_mul (t, u, t); mpz_add (r, r, t); mpz_clear (t); } void mpz_submul_ui (mpz_t r, const mpz_t u, unsigned long int v) { mpz_t t; mpz_init_set_ui (t, v); mpz_mul (t, u, t); mpz_sub (r, r, t); mpz_clear (t); } void mpz_addmul (mpz_t r, const mpz_t u, const mpz_t v) { mpz_t t; mpz_init (t); mpz_mul (t, u, v); mpz_add (r, r, t); mpz_clear (t); } void mpz_submul (mpz_t r, const mpz_t u, const mpz_t v) { mpz_t t; mpz_init (t); mpz_mul (t, u, v); mpz_sub (r, r, t); mpz_clear (t); } /* MPZ division */ enum mpz_div_round_mode { GMP_DIV_FLOOR, GMP_DIV_CEIL, GMP_DIV_TRUNC }; /* Allows q or r to be zero. Returns 1 iff remainder is non-zero. */ static int mpz_div_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d, enum mpz_div_round_mode mode) { mp_size_t ns, ds, nn, dn, qs; ns = n->_mp_size; ds = d->_mp_size; if (ds == 0) gmp_die("mpz_div_qr: Divide by zero."); if (ns == 0) { if (q) q->_mp_size = 0; if (r) r->_mp_size = 0; return 0; } nn = GMP_ABS (ns); dn = GMP_ABS (ds); qs = ds ^ ns; if (nn < dn) { if (mode == GMP_DIV_CEIL && qs >= 0) { /* q = 1, r = n - d */ if (r) mpz_sub (r, n, d); if (q) mpz_set_ui (q, 1); } else if (mode == GMP_DIV_FLOOR && qs < 0) { /* q = -1, r = n + d */ if (r) mpz_add (r, n, d); if (q) mpz_set_si (q, -1); } else { /* q = 0, r = d */ if (r) mpz_set (r, n); if (q) q->_mp_size = 0; } return 1; } else { mp_ptr np, qp; mp_size_t qn, rn; mpz_t tq, tr; mpz_init_set (tr, n); np = tr->_mp_d; qn = nn - dn + 1; if (q) { mpz_init2 (tq, qn * GMP_LIMB_BITS); qp = tq->_mp_d; } else qp = NULL; mpn_div_qr (qp, np, nn, d->_mp_d, dn); if (qp) { qn -= (qp[qn-1] == 0); tq->_mp_size = qs < 0 ? -qn : qn; } rn = mpn_normalized_size (np, dn); tr->_mp_size = ns < 0 ? - rn : rn; if (mode == GMP_DIV_FLOOR && qs < 0 && rn != 0) { if (q) mpz_sub_ui (tq, tq, 1); if (r) mpz_add (tr, tr, d); } else if (mode == GMP_DIV_CEIL && qs >= 0 && rn != 0) { if (q) mpz_add_ui (tq, tq, 1); if (r) mpz_sub (tr, tr, d); } if (q) { mpz_swap (tq, q); mpz_clear (tq); } if (r) mpz_swap (tr, r); mpz_clear (tr); return rn != 0; } } void mpz_cdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) { mpz_div_qr (q, r, n, d, GMP_DIV_CEIL); } void mpz_fdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) { mpz_div_qr (q, r, n, d, GMP_DIV_FLOOR); } void mpz_tdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) { mpz_div_qr (q, r, n, d, GMP_DIV_TRUNC); } void mpz_cdiv_q (mpz_t q, const mpz_t n, const mpz_t d) { mpz_div_qr (q, NULL, n, d, GMP_DIV_CEIL); } void mpz_fdiv_q (mpz_t q, const mpz_t n, const mpz_t d) { mpz_div_qr (q, NULL, n, d, GMP_DIV_FLOOR); } void mpz_tdiv_q (mpz_t q, const mpz_t n, const mpz_t d) { mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC); } void mpz_cdiv_r (mpz_t r, const mpz_t n, const mpz_t d) { mpz_div_qr (NULL, r, n, d, GMP_DIV_CEIL); } void mpz_fdiv_r (mpz_t r, const mpz_t n, const mpz_t d) { mpz_div_qr (NULL, r, n, d, GMP_DIV_FLOOR); } void mpz_tdiv_r (mpz_t r, const mpz_t n, const mpz_t d) { mpz_div_qr (NULL, r, n, d, GMP_DIV_TRUNC); } void mpz_mod (mpz_t r, const mpz_t n, const mpz_t d) { mpz_div_qr (NULL, r, n, d, d->_mp_size >= 0 ? GMP_DIV_FLOOR : GMP_DIV_CEIL); } static void mpz_div_q_2exp (mpz_t q, const mpz_t u, mp_bitcnt_t bit_index, enum mpz_div_round_mode mode) { mp_size_t un, qn; mp_size_t limb_cnt; mp_ptr qp; int adjust; un = u->_mp_size; if (un == 0) { q->_mp_size = 0; return; } limb_cnt = bit_index / GMP_LIMB_BITS; qn = GMP_ABS (un) - limb_cnt; bit_index %= GMP_LIMB_BITS; if (mode == ((un > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* un != 0 here. */ /* Note: Below, the final indexing at limb_cnt is valid because at that point we have qn > 0. */ adjust = (qn <= 0 || !mpn_zero_p (u->_mp_d, limb_cnt) || (u->_mp_d[limb_cnt] & (((mp_limb_t) 1 << bit_index) - 1))); else adjust = 0; if (qn <= 0) qn = 0; else { qp = MPZ_REALLOC (q, qn); if (bit_index != 0) { mpn_rshift (qp, u->_mp_d + limb_cnt, qn, bit_index); qn -= qp[qn - 1] == 0; } else { mpn_copyi (qp, u->_mp_d + limb_cnt, qn); } } q->_mp_size = qn; if (adjust) mpz_add_ui (q, q, 1); if (un < 0) mpz_neg (q, q); } static void mpz_div_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bit_index, enum mpz_div_round_mode mode) { mp_size_t us, un, rn; mp_ptr rp; mp_limb_t mask; us = u->_mp_size; if (us == 0 || bit_index == 0) { r->_mp_size = 0; return; } rn = (bit_index + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; assert (rn > 0); rp = MPZ_REALLOC (r, rn); un = GMP_ABS (us); mask = GMP_LIMB_MAX >> (rn * GMP_LIMB_BITS - bit_index); if (rn > un) { /* Quotient (with truncation) is zero, and remainder is non-zero */ if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */ { /* Have to negate and sign extend. */ mp_size_t i; gmp_assert_nocarry (! mpn_neg (rp, u->_mp_d, un)); for (i = un; i < rn - 1; i++) rp[i] = GMP_LIMB_MAX; rp[rn-1] = mask; us = -us; } else { /* Just copy */ if (r != u) mpn_copyi (rp, u->_mp_d, un); rn = un; } } else { if (r != u) mpn_copyi (rp, u->_mp_d, rn - 1); rp[rn-1] = u->_mp_d[rn-1] & mask; if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */ { /* If r != 0, compute 2^{bit_count} - r. */ mpn_neg (rp, rp, rn); rp[rn-1] &= mask; /* us is not used for anything else, so we can modify it here to indicate flipped sign. */ us = -us; } } rn = mpn_normalized_size (rp, rn); r->_mp_size = us < 0 ? -rn : rn; } void mpz_cdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) { mpz_div_q_2exp (r, u, cnt, GMP_DIV_CEIL); } void mpz_fdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) { mpz_div_q_2exp (r, u, cnt, GMP_DIV_FLOOR); } void mpz_tdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) { mpz_div_q_2exp (r, u, cnt, GMP_DIV_TRUNC); } void mpz_cdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) { mpz_div_r_2exp (r, u, cnt, GMP_DIV_CEIL); } void mpz_fdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) { mpz_div_r_2exp (r, u, cnt, GMP_DIV_FLOOR); } void mpz_tdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) { mpz_div_r_2exp (r, u, cnt, GMP_DIV_TRUNC); } void mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d) { gmp_assert_nocarry (mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC)); } int mpz_divisible_p (const mpz_t n, const mpz_t d) { return mpz_div_qr (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0; } int mpz_congruent_p (const mpz_t a, const mpz_t b, const mpz_t m) { mpz_t t; int res; /* a == b (mod 0) iff a == b */ if (mpz_sgn (m) == 0) return (mpz_cmp (a, b) == 0); mpz_init (t); mpz_sub (t, a, b); res = mpz_divisible_p (t, m); mpz_clear (t); return res; } static unsigned long mpz_div_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d, enum mpz_div_round_mode mode) { unsigned long ret; mpz_t rr, dd; mpz_init (rr); mpz_init_set_ui (dd, d); mpz_div_qr (q, rr, n, dd, mode); mpz_clear (dd); ret = mpz_get_ui (rr); if (r) mpz_swap (r, rr); mpz_clear (rr); return ret; } unsigned long mpz_cdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (q, r, n, d, GMP_DIV_CEIL); } unsigned long mpz_fdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (q, r, n, d, GMP_DIV_FLOOR); } unsigned long mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (q, r, n, d, GMP_DIV_TRUNC); } unsigned long mpz_cdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_CEIL); } unsigned long mpz_fdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_FLOOR); } unsigned long mpz_tdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC); } unsigned long mpz_cdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_CEIL); } unsigned long mpz_fdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR); } unsigned long mpz_tdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_TRUNC); } unsigned long mpz_cdiv_ui (const mpz_t n, unsigned long d) { return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_CEIL); } unsigned long mpz_fdiv_ui (const mpz_t n, unsigned long d) { return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_FLOOR); } unsigned long mpz_tdiv_ui (const mpz_t n, unsigned long d) { return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC); } unsigned long mpz_mod_ui (mpz_t r, const mpz_t n, unsigned long d) { return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR); } void mpz_divexact_ui (mpz_t q, const mpz_t n, unsigned long d) { gmp_assert_nocarry (mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC)); } int mpz_divisible_ui_p (const mpz_t n, unsigned long d) { return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0; } /* GCD */ static mp_limb_t mpn_gcd_11 (mp_limb_t u, mp_limb_t v) { unsigned shift; assert ( (u | v) > 0); if (u == 0) return v; else if (v == 0) return u; gmp_ctz (shift, u | v); u >>= shift; v >>= shift; if ( (u & 1) == 0) MP_LIMB_T_SWAP (u, v); while ( (v & 1) == 0) v >>= 1; while (u != v) { if (u > v) { u -= v; do u >>= 1; while ( (u & 1) == 0); } else { v -= u; do v >>= 1; while ( (v & 1) == 0); } } return u << shift; } unsigned long mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v) { mpz_t t; mpz_init_set_ui(t, v); mpz_gcd (t, u, t); if (v > 0) v = mpz_get_ui (t); if (g) mpz_swap (t, g); mpz_clear (t); return v; } static mp_bitcnt_t mpz_make_odd (mpz_t r) { mp_bitcnt_t shift; assert (r->_mp_size > 0); /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */ shift = mpn_common_scan (r->_mp_d[0], 0, r->_mp_d, 0, 0); mpz_tdiv_q_2exp (r, r, shift); return shift; } void mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v) { mpz_t tu, tv; mp_bitcnt_t uz, vz, gz; if (u->_mp_size == 0) { mpz_abs (g, v); return; } if (v->_mp_size == 0) { mpz_abs (g, u); return; } mpz_init (tu); mpz_init (tv); mpz_abs (tu, u); uz = mpz_make_odd (tu); mpz_abs (tv, v); vz = mpz_make_odd (tv); gz = GMP_MIN (uz, vz); if (tu->_mp_size < tv->_mp_size) mpz_swap (tu, tv); mpz_tdiv_r (tu, tu, tv); if (tu->_mp_size == 0) { mpz_swap (g, tv); } else for (;;) { int c; mpz_make_odd (tu); c = mpz_cmp (tu, tv); if (c == 0) { mpz_swap (g, tu); break; } if (c < 0) mpz_swap (tu, tv); if (tv->_mp_size == 1) { mp_limb_t vl = tv->_mp_d[0]; mp_limb_t ul = mpz_tdiv_ui (tu, vl); mpz_set_ui (g, mpn_gcd_11 (ul, vl)); break; } mpz_sub (tu, tu, tv); } mpz_clear (tu); mpz_clear (tv); mpz_mul_2exp (g, g, gz); } void mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) { mpz_t tu, tv, s0, s1, t0, t1; mp_bitcnt_t uz, vz, gz; mp_bitcnt_t power; if (u->_mp_size == 0) { /* g = 0 u + sgn(v) v */ signed long sign = mpz_sgn (v); mpz_abs (g, v); if (s) s->_mp_size = 0; if (t) mpz_set_si (t, sign); return; } if (v->_mp_size == 0) { /* g = sgn(u) u + 0 v */ signed long sign = mpz_sgn (u); mpz_abs (g, u); if (s) mpz_set_si (s, sign); if (t) t->_mp_size = 0; return; } mpz_init (tu); mpz_init (tv); mpz_init (s0); mpz_init (s1); mpz_init (t0); mpz_init (t1); mpz_abs (tu, u); uz = mpz_make_odd (tu); mpz_abs (tv, v); vz = mpz_make_odd (tv); gz = GMP_MIN (uz, vz); uz -= gz; vz -= gz; /* Cofactors corresponding to odd gcd. gz handled later. */ if (tu->_mp_size < tv->_mp_size) { mpz_swap (tu, tv); MPZ_SRCPTR_SWAP (u, v); MPZ_PTR_SWAP (s, t); MP_BITCNT_T_SWAP (uz, vz); } /* Maintain * * u = t0 tu + t1 tv * v = s0 tu + s1 tv * * where u and v denote the inputs with common factors of two * eliminated, and det (s0, t0; s1, t1) = 2^p. Then * * 2^p tu = s1 u - t1 v * 2^p tv = -s0 u + t0 v */ /* After initial division, tu = q tv + tu', we have * * u = 2^uz (tu' + q tv) * v = 2^vz tv * * or * * t0 = 2^uz, t1 = 2^uz q * s0 = 0, s1 = 2^vz */ mpz_setbit (t0, uz); mpz_tdiv_qr (t1, tu, tu, tv); mpz_mul_2exp (t1, t1, uz); mpz_setbit (s1, vz); power = uz + vz; if (tu->_mp_size > 0) { mp_bitcnt_t shift; shift = mpz_make_odd (tu); mpz_mul_2exp (t0, t0, shift); mpz_mul_2exp (s0, s0, shift); power += shift; for (;;) { int c; c = mpz_cmp (tu, tv); if (c == 0) break; if (c < 0) { /* tv = tv' + tu * * u = t0 tu + t1 (tv' + tu) = (t0 + t1) tu + t1 tv' * v = s0 tu + s1 (tv' + tu) = (s0 + s1) tu + s1 tv' */ mpz_sub (tv, tv, tu); mpz_add (t0, t0, t1); mpz_add (s0, s0, s1); shift = mpz_make_odd (tv); mpz_mul_2exp (t1, t1, shift); mpz_mul_2exp (s1, s1, shift); } else { mpz_sub (tu, tu, tv); mpz_add (t1, t0, t1); mpz_add (s1, s0, s1); shift = mpz_make_odd (tu); mpz_mul_2exp (t0, t0, shift); mpz_mul_2exp (s0, s0, shift); } power += shift; } } /* Now tv = odd part of gcd, and -s0 and t0 are corresponding cofactors. */ mpz_mul_2exp (tv, tv, gz); mpz_neg (s0, s0); /* 2^p g = s0 u + t0 v. Eliminate one factor of two at a time. To adjust cofactors, we need u / g and v / g */ mpz_divexact (s1, v, tv); mpz_abs (s1, s1); mpz_divexact (t1, u, tv); mpz_abs (t1, t1); while (power-- > 0) { /* s0 u + t0 v = (s0 - v/g) u - (t0 + u/g) v */ if (mpz_odd_p (s0) || mpz_odd_p (t0)) { mpz_sub (s0, s0, s1); mpz_add (t0, t0, t1); } assert (mpz_even_p (t0) && mpz_even_p (s0)); mpz_tdiv_q_2exp (s0, s0, 1); mpz_tdiv_q_2exp (t0, t0, 1); } /* Arrange so that |s| < |u| / 2g */ mpz_add (s1, s0, s1); if (mpz_cmpabs (s0, s1) > 0) { mpz_swap (s0, s1); mpz_sub (t0, t0, t1); } if (u->_mp_size < 0) mpz_neg (s0, s0); if (v->_mp_size < 0) mpz_neg (t0, t0); mpz_swap (g, tv); if (s) mpz_swap (s, s0); if (t) mpz_swap (t, t0); mpz_clear (tu); mpz_clear (tv); mpz_clear (s0); mpz_clear (s1); mpz_clear (t0); mpz_clear (t1); } void mpz_lcm (mpz_t r, const mpz_t u, const mpz_t v) { mpz_t g; if (u->_mp_size == 0 || v->_mp_size == 0) { r->_mp_size = 0; return; } mpz_init (g); mpz_gcd (g, u, v); mpz_divexact (g, u, g); mpz_mul (r, g, v); mpz_clear (g); mpz_abs (r, r); } void mpz_lcm_ui (mpz_t r, const mpz_t u, unsigned long v) { if (v == 0 || u->_mp_size == 0) { r->_mp_size = 0; return; } v /= mpz_gcd_ui (NULL, u, v); mpz_mul_ui (r, u, v); mpz_abs (r, r); } int mpz_invert (mpz_t r, const mpz_t u, const mpz_t m) { mpz_t g, tr; int invertible; if (u->_mp_size == 0 || mpz_cmpabs_ui (m, 1) <= 0) return 0; mpz_init (g); mpz_init (tr); mpz_gcdext (g, tr, NULL, u, m); invertible = (mpz_cmp_ui (g, 1) == 0); if (invertible) { if (tr->_mp_size < 0) { if (m->_mp_size >= 0) mpz_add (tr, tr, m); else mpz_sub (tr, tr, m); } mpz_swap (r, tr); } mpz_clear (g); mpz_clear (tr); return invertible; } /* Higher level operations (sqrt, pow and root) */ void mpz_pow_ui (mpz_t r, const mpz_t b, unsigned long e) { unsigned long bit; mpz_t tr; mpz_init_set_ui (tr, 1); bit = GMP_ULONG_HIGHBIT; do { mpz_mul (tr, tr, tr); if (e & bit) mpz_mul (tr, tr, b); bit >>= 1; } while (bit > 0); mpz_swap (r, tr); mpz_clear (tr); } void mpz_ui_pow_ui (mpz_t r, unsigned long blimb, unsigned long e) { mpz_t b; mpz_init_set_ui (b, blimb); mpz_pow_ui (r, b, e); mpz_clear (b); } void mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m) { mpz_t tr; mpz_t base; mp_size_t en, mn; mp_srcptr mp; struct gmp_div_inverse minv; unsigned shift; mp_ptr tp = NULL; en = GMP_ABS (e->_mp_size); mn = GMP_ABS (m->_mp_size); if (mn == 0) gmp_die ("mpz_powm: Zero modulo."); if (en == 0) { mpz_set_ui (r, 1); return; } mp = m->_mp_d; mpn_div_qr_invert (&minv, mp, mn); shift = minv.shift; if (shift > 0) { /* To avoid shifts, we do all our reductions, except the final one, using a *normalized* m. */ minv.shift = 0; tp = gmp_xalloc_limbs (mn); gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift)); mp = tp; } mpz_init (base); if (e->_mp_size < 0) { if (!mpz_invert (base, b, m)) gmp_die ("mpz_powm: Negative exponent and non-invertible base."); } else { mp_size_t bn; mpz_abs (base, b); bn = base->_mp_size; if (bn >= mn) { mpn_div_qr_preinv (NULL, base->_mp_d, base->_mp_size, mp, mn, &minv); bn = mn; } /* We have reduced the absolute value. Now take care of the sign. Note that we get zero represented non-canonically as m. */ if (b->_mp_size < 0) { mp_ptr bp = MPZ_REALLOC (base, mn); gmp_assert_nocarry (mpn_sub (bp, mp, mn, bp, bn)); bn = mn; } base->_mp_size = mpn_normalized_size (base->_mp_d, bn); } mpz_init_set_ui (tr, 1); while (--en >= 0) { mp_limb_t w = e->_mp_d[en]; mp_limb_t bit; bit = GMP_LIMB_HIGHBIT; do { mpz_mul (tr, tr, tr); if (w & bit) mpz_mul (tr, tr, base); if (tr->_mp_size > mn) { mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv); tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn); } bit >>= 1; } while (bit > 0); } /* Final reduction */ if (tr->_mp_size >= mn) { minv.shift = shift; mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv); tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn); } if (tp) gmp_free (tp); mpz_swap (r, tr); mpz_clear (tr); mpz_clear (base); } void mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m) { mpz_t e; mpz_init_set_ui (e, elimb); mpz_powm (r, b, e, m); mpz_clear (e); } /* x=trunc(y^(1/z)), r=y-x^z */ void mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z) { int sgn; mpz_t t, u; sgn = y->_mp_size < 0; if ((~z & sgn) != 0) gmp_die ("mpz_rootrem: Negative argument, with even root."); if (z == 0) gmp_die ("mpz_rootrem: Zeroth root."); if (mpz_cmpabs_ui (y, 1) <= 0) { if (x) mpz_set (x, y); if (r) r->_mp_size = 0; return; } mpz_init (u); mpz_init (t); mpz_setbit (t, mpz_sizeinbase (y, 2) / z + 1); if (z == 2) /* simplify sqrt loop: z-1 == 1 */ do { mpz_swap (u, t); /* u = x */ mpz_tdiv_q (t, y, u); /* t = y/x */ mpz_add (t, t, u); /* t = y/x + x */ mpz_tdiv_q_2exp (t, t, 1); /* x'= (y/x + x)/2 */ } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */ else /* z != 2 */ { mpz_t v; mpz_init (v); if (sgn) mpz_neg (t, t); do { mpz_swap (u, t); /* u = x */ mpz_pow_ui (t, u, z - 1); /* t = x^(z-1) */ mpz_tdiv_q (t, y, t); /* t = y/x^(z-1) */ mpz_mul_ui (v, u, z - 1); /* v = x*(z-1) */ mpz_add (t, t, v); /* t = y/x^(z-1) + x*(z-1) */ mpz_tdiv_q_ui (t, t, z); /* x'=(y/x^(z-1) + x*(z-1))/z */ } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */ mpz_clear (v); } if (r) { mpz_pow_ui (t, u, z); mpz_sub (r, y, t); } if (x) mpz_swap (x, u); mpz_clear (u); mpz_clear (t); } int mpz_root (mpz_t x, const mpz_t y, unsigned long z) { int res; mpz_t r; mpz_init (r); mpz_rootrem (x, r, y, z); res = r->_mp_size == 0; mpz_clear (r); return res; } /* Compute s = floor(sqrt(u)) and r = u - s^2. Allows r == NULL */ void mpz_sqrtrem (mpz_t s, mpz_t r, const mpz_t u) { mpz_rootrem (s, r, u, 2); } void mpz_sqrt (mpz_t s, const mpz_t u) { mpz_rootrem (s, NULL, u, 2); } int mpz_perfect_square_p (const mpz_t u) { if (u->_mp_size <= 0) return (u->_mp_size == 0); else return mpz_root (NULL, u, 2); } int mpn_perfect_square_p (mp_srcptr p, mp_size_t n) { mpz_t t; assert (n > 0); assert (p [n-1] != 0); return mpz_root (NULL, mpz_roinit_normal_n (t, p, n), 2); } mp_size_t mpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr p, mp_size_t n) { mpz_t s, r, u; mp_size_t res; assert (n > 0); assert (p [n-1] != 0); mpz_init (r); mpz_init (s); mpz_rootrem (s, r, mpz_roinit_normal_n (u, p, n), 2); assert (s->_mp_size == (n+1)/2); mpn_copyd (sp, s->_mp_d, s->_mp_size); mpz_clear (s); res = r->_mp_size; if (rp) mpn_copyd (rp, r->_mp_d, res); mpz_clear (r); return res; } /* Combinatorics */ void mpz_mfac_uiui (mpz_t x, unsigned long n, unsigned long m) { mpz_set_ui (x, n + (n == 0)); if (m + 1 < 2) return; while (n > m + 1) mpz_mul_ui (x, x, n -= m); } void mpz_2fac_ui (mpz_t x, unsigned long n) { mpz_mfac_uiui (x, n, 2); } void mpz_fac_ui (mpz_t x, unsigned long n) { mpz_mfac_uiui (x, n, 1); } void mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k) { mpz_t t; mpz_set_ui (r, k <= n); if (k > (n >> 1)) k = (k <= n) ? n - k : 0; mpz_init (t); mpz_fac_ui (t, k); for (; k > 0; --k) mpz_mul_ui (r, r, n--); mpz_divexact (r, r, t); mpz_clear (t); } /* Primality testing */ /* Computes Kronecker (a/b) with odd b, a!=0 and GCD(a,b) = 1 */ /* Adapted from JACOBI_BASE_METHOD==4 in mpn/generic/jacbase.c */ static int gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b) { int c, bit = 0; assert (b & 1); assert (a != 0); /* assert (mpn_gcd_11 (a, b) == 1); */ /* Below, we represent a and b shifted right so that the least significant one bit is implicit. */ b >>= 1; gmp_ctz(c, a); a >>= 1; do { a >>= c; /* (2/b) = -1 if b = 3 or 5 mod 8 */ bit ^= c & (b ^ (b >> 1)); if (a < b) { bit ^= a & b; a = b - a; b -= a; } else { a -= b; assert (a != 0); } gmp_ctz(c, a); ++c; } while (b > 0); return bit & 1 ? -1 : 1; } static void gmp_lucas_step_k_2k (mpz_t V, mpz_t Qk, const mpz_t n) { mpz_mod (Qk, Qk, n); /* V_{2k} <- V_k ^ 2 - 2Q^k */ mpz_mul (V, V, V); mpz_submul_ui (V, Qk, 2); mpz_tdiv_r (V, V, n); /* Q^{2k} = (Q^k)^2 */ mpz_mul (Qk, Qk, Qk); } /* Computes V_k, Q^k (mod n) for the Lucas' sequence */ /* with P=1, Q=Q; k = (n>>b0)|1. */ /* Requires an odd n > 4; b0 > 0; -2*Q must not overflow a long */ /* Returns (U_k == 0) and sets V=V_k and Qk=Q^k. */ static int gmp_lucas_mod (mpz_t V, mpz_t Qk, long Q, mp_bitcnt_t b0, const mpz_t n) { mp_bitcnt_t bs; mpz_t U; int res; assert (b0 > 0); assert (Q <= - (LONG_MIN / 2)); assert (Q >= - (LONG_MAX / 2)); assert (mpz_cmp_ui (n, 4) > 0); assert (mpz_odd_p (n)); mpz_init_set_ui (U, 1); /* U1 = 1 */ mpz_set_ui (V, 1); /* V1 = 1 */ mpz_set_si (Qk, Q); for (bs = mpz_sizeinbase (n, 2) - 1; --bs >= b0;) { /* U_{2k} <- U_k * V_k */ mpz_mul (U, U, V); /* V_{2k} <- V_k ^ 2 - 2Q^k */ /* Q^{2k} = (Q^k)^2 */ gmp_lucas_step_k_2k (V, Qk, n); /* A step k->k+1 is performed if the bit in $n$ is 1 */ /* mpz_tstbit(n,bs) or the bit is 0 in $n$ but */ /* should be 1 in $n+1$ (bs == b0) */ if (b0 == bs || mpz_tstbit (n, bs)) { /* Q^{k+1} <- Q^k * Q */ mpz_mul_si (Qk, Qk, Q); /* U_{k+1} <- (U_k + V_k) / 2 */ mpz_swap (U, V); /* Keep in V the old value of U_k */ mpz_add (U, U, V); /* We have to compute U/2, so we need an even value, */ /* equivalent (mod n) */ if (mpz_odd_p (U)) mpz_add (U, U, n); mpz_tdiv_q_2exp (U, U, 1); /* V_{k+1} <-(D*U_k + V_k) / 2 = U_{k+1} + (D-1)/2*U_k = U_{k+1} - 2Q*U_k */ mpz_mul_si (V, V, -2*Q); mpz_add (V, U, V); mpz_tdiv_r (V, V, n); } mpz_tdiv_r (U, U, n); } res = U->_mp_size == 0; mpz_clear (U); return res; } /* Performs strong Lucas' test on x, with parameters suggested */ /* for the BPSW test. Qk is only passed to recycle a variable. */ /* Requires GCD (x,6) = 1.*/ static int gmp_stronglucas (const mpz_t x, mpz_t Qk) { mp_bitcnt_t b0; mpz_t V, n; mp_limb_t maxD, D; /* The absolute value is stored. */ long Q; mp_limb_t tl; /* Test on the absolute value. */ mpz_roinit_normal_n (n, x->_mp_d, GMP_ABS (x->_mp_size)); assert (mpz_odd_p (n)); /* assert (mpz_gcd_ui (NULL, n, 6) == 1); */ if (mpz_root (Qk, n, 2)) return 0; /* A square is composite. */ /* Check Ds up to square root (in case, n is prime) or avoid overflows */ maxD = (Qk->_mp_size == 1) ? Qk->_mp_d [0] - 1 : GMP_LIMB_MAX; D = 3; /* Search a D such that (D/n) = -1 in the sequence 5,-7,9,-11,.. */ /* For those Ds we have (D/n) = (n/|D|) */ do { if (D >= maxD) return 1 + (D != GMP_LIMB_MAX); /* (1 + ! ~ D) */ D += 2; tl = mpz_tdiv_ui (n, D); if (tl == 0) return 0; } while (gmp_jacobi_coprime (tl, D) == 1); mpz_init (V); /* n-(D/n) = n+1 = d*2^{b0}, with d = (n>>b0) | 1 */ b0 = mpz_scan0 (n, 0); /* D= P^2 - 4Q; P = 1; Q = (1-D)/4 */ Q = (D & 2) ? (long) (D >> 2) + 1 : -(long) (D >> 2); if (! gmp_lucas_mod (V, Qk, Q, b0, n)) /* If Ud != 0 */ while (V->_mp_size != 0 && --b0 != 0) /* while Vk != 0 */ /* V <- V ^ 2 - 2Q^k */ /* Q^{2k} = (Q^k)^2 */ gmp_lucas_step_k_2k (V, Qk, n); mpz_clear (V); return (b0 != 0); } static int gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y, const mpz_t q, mp_bitcnt_t k) { assert (k > 0); /* Caller must initialize y to the base. */ mpz_powm (y, y, q, n); if (mpz_cmp_ui (y, 1) == 0 || mpz_cmp (y, nm1) == 0) return 1; while (--k > 0) { mpz_powm_ui (y, y, 2, n); if (mpz_cmp (y, nm1) == 0) return 1; /* y == 1 means that the previous y was a non-trivial square root of 1 (mod n). y == 0 means that n is a power of the base. In either case, n is not prime. */ if (mpz_cmp_ui (y, 1) <= 0) return 0; } return 0; } /* This product is 0xc0cfd797, and fits in 32 bits. */ #define GMP_PRIME_PRODUCT \ (3UL*5UL*7UL*11UL*13UL*17UL*19UL*23UL*29UL) /* Bit (p+1)/2 is set, for each odd prime <= 61 */ #define GMP_PRIME_MASK 0xc96996dcUL int mpz_probab_prime_p (const mpz_t n, int reps) { mpz_t nm1; mpz_t q; mpz_t y; mp_bitcnt_t k; int is_prime; int j; /* Note that we use the absolute value of n only, for compatibility with the real GMP. */ if (mpz_even_p (n)) return (mpz_cmpabs_ui (n, 2) == 0) ? 2 : 0; /* Above test excludes n == 0 */ assert (n->_mp_size != 0); if (mpz_cmpabs_ui (n, 64) < 0) return (GMP_PRIME_MASK >> (n->_mp_d[0] >> 1)) & 2; if (mpz_gcd_ui (NULL, n, GMP_PRIME_PRODUCT) != 1) return 0; /* All prime factors are >= 31. */ if (mpz_cmpabs_ui (n, 31*31) < 0) return 2; mpz_init (nm1); mpz_init (q); /* Find q and k, where q is odd and n = 1 + 2**k * q. */ mpz_abs (nm1, n); nm1->_mp_d[0] -= 1; k = mpz_scan1 (nm1, 0); mpz_tdiv_q_2exp (q, nm1, k); /* BPSW test */ mpz_init_set_ui (y, 2); is_prime = gmp_millerrabin (n, nm1, y, q, k) && gmp_stronglucas (n, y); reps -= 24; /* skip the first 24 repetitions */ /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] = j^2 + j + 41 using Euler's polynomial. We potentially stop early, if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps > 30 (a[30] == 971 > 31*31 == 961). */ for (j = 0; is_prime & (j < reps); j++) { mpz_set_ui (y, (unsigned long) j*j+j+41); if (mpz_cmp (y, nm1) >= 0) { /* Don't try any further bases. This "early" break does not affect the result for any reasonable reps value (<=5000 was tested) */ assert (j >= 30); break; } is_prime = gmp_millerrabin (n, nm1, y, q, k); } mpz_clear (nm1); mpz_clear (q); mpz_clear (y); return is_prime; } /* Logical operations and bit manipulation. */ /* Numbers are treated as if represented in two's complement (and infinitely sign extended). For a negative values we get the two's complement from -x = ~x + 1, where ~ is bitwise complement. Negation transforms xxxx10...0 into yyyy10...0 where yyyy is the bitwise complement of xxxx. So least significant bits, up to and including the first one bit, are unchanged, and the more significant bits are all complemented. To change a bit from zero to one in a negative number, subtract the corresponding power of two from the absolute value. This can never underflow. To change a bit from one to zero, add the corresponding power of two, and this might overflow. E.g., if x = -001111, the two's complement is 110001. Clearing the least significant bit, we get two's complement 110000, and -010000. */ int mpz_tstbit (const mpz_t d, mp_bitcnt_t bit_index) { mp_size_t limb_index; unsigned shift; mp_size_t ds; mp_size_t dn; mp_limb_t w; int bit; ds = d->_mp_size; dn = GMP_ABS (ds); limb_index = bit_index / GMP_LIMB_BITS; if (limb_index >= dn) return ds < 0; shift = bit_index % GMP_LIMB_BITS; w = d->_mp_d[limb_index]; bit = (w >> shift) & 1; if (ds < 0) { /* d < 0. Check if any of the bits below is set: If so, our bit must be complemented. */ if (shift > 0 && (mp_limb_t) (w << (GMP_LIMB_BITS - shift)) > 0) return bit ^ 1; while (--limb_index >= 0) if (d->_mp_d[limb_index] > 0) return bit ^ 1; } return bit; } static void mpz_abs_add_bit (mpz_t d, mp_bitcnt_t bit_index) { mp_size_t dn, limb_index; mp_limb_t bit; mp_ptr dp; dn = GMP_ABS (d->_mp_size); limb_index = bit_index / GMP_LIMB_BITS; bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS); if (limb_index >= dn) { mp_size_t i; /* The bit should be set outside of the end of the number. We have to increase the size of the number. */ dp = MPZ_REALLOC (d, limb_index + 1); dp[limb_index] = bit; for (i = dn; i < limb_index; i++) dp[i] = 0; dn = limb_index + 1; } else { mp_limb_t cy; dp = d->_mp_d; cy = mpn_add_1 (dp + limb_index, dp + limb_index, dn - limb_index, bit); if (cy > 0) { dp = MPZ_REALLOC (d, dn + 1); dp[dn++] = cy; } } d->_mp_size = (d->_mp_size < 0) ? - dn : dn; } static void mpz_abs_sub_bit (mpz_t d, mp_bitcnt_t bit_index) { mp_size_t dn, limb_index; mp_ptr dp; mp_limb_t bit; dn = GMP_ABS (d->_mp_size); dp = d->_mp_d; limb_index = bit_index / GMP_LIMB_BITS; bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS); assert (limb_index < dn); gmp_assert_nocarry (mpn_sub_1 (dp + limb_index, dp + limb_index, dn - limb_index, bit)); dn = mpn_normalized_size (dp, dn); d->_mp_size = (d->_mp_size < 0) ? - dn : dn; } void mpz_setbit (mpz_t d, mp_bitcnt_t bit_index) { if (!mpz_tstbit (d, bit_index)) { if (d->_mp_size >= 0) mpz_abs_add_bit (d, bit_index); else mpz_abs_sub_bit (d, bit_index); } } void mpz_clrbit (mpz_t d, mp_bitcnt_t bit_index) { if (mpz_tstbit (d, bit_index)) { if (d->_mp_size >= 0) mpz_abs_sub_bit (d, bit_index); else mpz_abs_add_bit (d, bit_index); } } void mpz_combit (mpz_t d, mp_bitcnt_t bit_index) { if (mpz_tstbit (d, bit_index) ^ (d->_mp_size < 0)) mpz_abs_sub_bit (d, bit_index); else mpz_abs_add_bit (d, bit_index); } void mpz_com (mpz_t r, const mpz_t u) { mpz_add_ui (r, u, 1); mpz_neg (r, r); } void mpz_and (mpz_t r, const mpz_t u, const mpz_t v) { mp_size_t un, vn, rn, i; mp_ptr up, vp, rp; mp_limb_t ux, vx, rx; mp_limb_t uc, vc, rc; mp_limb_t ul, vl, rl; un = GMP_ABS (u->_mp_size); vn = GMP_ABS (v->_mp_size); if (un < vn) { MPZ_SRCPTR_SWAP (u, v); MP_SIZE_T_SWAP (un, vn); } if (vn == 0) { r->_mp_size = 0; return; } uc = u->_mp_size < 0; vc = v->_mp_size < 0; rc = uc & vc; ux = -uc; vx = -vc; rx = -rc; /* If the smaller input is positive, higher limbs don't matter. */ rn = vx ? un : vn; rp = MPZ_REALLOC (r, rn + (mp_size_t) rc); up = u->_mp_d; vp = v->_mp_d; i = 0; do { ul = (up[i] ^ ux) + uc; uc = ul < uc; vl = (vp[i] ^ vx) + vc; vc = vl < vc; rl = ( (ul & vl) ^ rx) + rc; rc = rl < rc; rp[i] = rl; } while (++i < vn); assert (vc == 0); for (; i < rn; i++) { ul = (up[i] ^ ux) + uc; uc = ul < uc; rl = ( (ul & vx) ^ rx) + rc; rc = rl < rc; rp[i] = rl; } if (rc) rp[rn++] = rc; else rn = mpn_normalized_size (rp, rn); r->_mp_size = rx ? -rn : rn; } void mpz_ior (mpz_t r, const mpz_t u, const mpz_t v) { mp_size_t un, vn, rn, i; mp_ptr up, vp, rp; mp_limb_t ux, vx, rx; mp_limb_t uc, vc, rc; mp_limb_t ul, vl, rl; un = GMP_ABS (u->_mp_size); vn = GMP_ABS (v->_mp_size); if (un < vn) { MPZ_SRCPTR_SWAP (u, v); MP_SIZE_T_SWAP (un, vn); } if (vn == 0) { mpz_set (r, u); return; } uc = u->_mp_size < 0; vc = v->_mp_size < 0; rc = uc | vc; ux = -uc; vx = -vc; rx = -rc; /* If the smaller input is negative, by sign extension higher limbs don't matter. */ rn = vx ? vn : un; rp = MPZ_REALLOC (r, rn + (mp_size_t) rc); up = u->_mp_d; vp = v->_mp_d; i = 0; do { ul = (up[i] ^ ux) + uc; uc = ul < uc; vl = (vp[i] ^ vx) + vc; vc = vl < vc; rl = ( (ul | vl) ^ rx) + rc; rc = rl < rc; rp[i] = rl; } while (++i < vn); assert (vc == 0); for (; i < rn; i++) { ul = (up[i] ^ ux) + uc; uc = ul < uc; rl = ( (ul | vx) ^ rx) + rc; rc = rl < rc; rp[i] = rl; } if (rc) rp[rn++] = rc; else rn = mpn_normalized_size (rp, rn); r->_mp_size = rx ? -rn : rn; } void mpz_xor (mpz_t r, const mpz_t u, const mpz_t v) { mp_size_t un, vn, i; mp_ptr up, vp, rp; mp_limb_t ux, vx, rx; mp_limb_t uc, vc, rc; mp_limb_t ul, vl, rl; un = GMP_ABS (u->_mp_size); vn = GMP_ABS (v->_mp_size); if (un < vn) { MPZ_SRCPTR_SWAP (u, v); MP_SIZE_T_SWAP (un, vn); } if (vn == 0) { mpz_set (r, u); return; } uc = u->_mp_size < 0; vc = v->_mp_size < 0; rc = uc ^ vc; ux = -uc; vx = -vc; rx = -rc; rp = MPZ_REALLOC (r, un + (mp_size_t) rc); up = u->_mp_d; vp = v->_mp_d; i = 0; do { ul = (up[i] ^ ux) + uc; uc = ul < uc; vl = (vp[i] ^ vx) + vc; vc = vl < vc; rl = (ul ^ vl ^ rx) + rc; rc = rl < rc; rp[i] = rl; } while (++i < vn); assert (vc == 0); for (; i < un; i++) { ul = (up[i] ^ ux) + uc; uc = ul < uc; rl = (ul ^ ux) + rc; rc = rl < rc; rp[i] = rl; } if (rc) rp[un++] = rc; else un = mpn_normalized_size (rp, un); r->_mp_size = rx ? -un : un; } static unsigned gmp_popcount_limb (mp_limb_t x) { unsigned c; /* Do 16 bits at a time, to avoid limb-sized constants. */ int LOCAL_SHIFT_BITS = 16; for (c = 0; x > 0;) { unsigned w = x - ((x >> 1) & 0x5555); w = ((w >> 2) & 0x3333) + (w & 0x3333); w = (w >> 4) + w; w = ((w >> 8) & 0x000f) + (w & 0x000f); c += w; if (GMP_LIMB_BITS > LOCAL_SHIFT_BITS) x >>= LOCAL_SHIFT_BITS; else x = 0; } return c; } mp_bitcnt_t mpn_popcount (mp_srcptr p, mp_size_t n) { mp_size_t i; mp_bitcnt_t c; for (c = 0, i = 0; i < n; i++) c += gmp_popcount_limb (p[i]); return c; } mp_bitcnt_t mpz_popcount (const mpz_t u) { mp_size_t un; un = u->_mp_size; if (un < 0) return ~(mp_bitcnt_t) 0; return mpn_popcount (u->_mp_d, un); } mp_bitcnt_t mpz_hamdist (const mpz_t u, const mpz_t v) { mp_size_t un, vn, i; mp_limb_t uc, vc, ul, vl, comp; mp_srcptr up, vp; mp_bitcnt_t c; un = u->_mp_size; vn = v->_mp_size; if ( (un ^ vn) < 0) return ~(mp_bitcnt_t) 0; comp = - (uc = vc = (un < 0)); if (uc) { assert (vn < 0); un = -un; vn = -vn; } up = u->_mp_d; vp = v->_mp_d; if (un < vn) MPN_SRCPTR_SWAP (up, un, vp, vn); for (i = 0, c = 0; i < vn; i++) { ul = (up[i] ^ comp) + uc; uc = ul < uc; vl = (vp[i] ^ comp) + vc; vc = vl < vc; c += gmp_popcount_limb (ul ^ vl); } assert (vc == 0); for (; i < un; i++) { ul = (up[i] ^ comp) + uc; uc = ul < uc; c += gmp_popcount_limb (ul ^ comp); } return c; } mp_bitcnt_t mpz_scan1 (const mpz_t u, mp_bitcnt_t starting_bit) { mp_ptr up; mp_size_t us, un, i; mp_limb_t limb, ux; us = u->_mp_size; un = GMP_ABS (us); i = starting_bit / GMP_LIMB_BITS; /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit for u<0. Notice this test picks up any u==0 too. */ if (i >= un) return (us >= 0 ? ~(mp_bitcnt_t) 0 : starting_bit); up = u->_mp_d; ux = 0; limb = up[i]; if (starting_bit != 0) { if (us < 0) { ux = mpn_zero_p (up, i); limb = ~ limb + ux; ux = - (mp_limb_t) (limb >= ux); } /* Mask to 0 all bits before starting_bit, thus ignoring them. */ limb &= GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS); } return mpn_common_scan (limb, i, up, un, ux); } mp_bitcnt_t mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit) { mp_ptr up; mp_size_t us, un, i; mp_limb_t limb, ux; us = u->_mp_size; ux = - (mp_limb_t) (us >= 0); un = GMP_ABS (us); i = starting_bit / GMP_LIMB_BITS; /* When past end, there's an immediate 0 bit for u>=0, or no 0 bits for u<0. Notice this test picks up all cases of u==0 too. */ if (i >= un) return (ux ? starting_bit : ~(mp_bitcnt_t) 0); up = u->_mp_d; limb = up[i] ^ ux; if (ux == 0) limb -= mpn_zero_p (up, i); /* limb = ~(~limb + zero_p) */ /* Mask all bits before starting_bit, thus ignoring them. */ limb &= GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS); return mpn_common_scan (limb, i, up, un, ux); } /* MPZ base conversion. */ size_t mpz_sizeinbase (const mpz_t u, int base) { mp_size_t un; mp_srcptr up; mp_ptr tp; mp_bitcnt_t bits; struct gmp_div_inverse bi; size_t ndigits; assert (base >= 2); assert (base <= 62); un = GMP_ABS (u->_mp_size); if (un == 0) return 1; up = u->_mp_d; bits = (un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]); switch (base) { case 2: return bits; case 4: return (bits + 1) / 2; case 8: return (bits + 2) / 3; case 16: return (bits + 3) / 4; case 32: return (bits + 4) / 5; /* FIXME: Do something more clever for the common case of base 10. */ } tp = gmp_xalloc_limbs (un); mpn_copyi (tp, up, un); mpn_div_qr_1_invert (&bi, base); ndigits = 0; do { ndigits++; mpn_div_qr_1_preinv (tp, tp, un, &bi); un -= (tp[un-1] == 0); } while (un > 0); gmp_free (tp); return ndigits; } char * mpz_get_str (char *sp, int base, const mpz_t u) { unsigned bits; const char *digits; mp_size_t un; size_t i, sn; digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; if (base > 1) { if (base <= 36) digits = "0123456789abcdefghijklmnopqrstuvwxyz"; else if (base > 62) return NULL; } else if (base >= -1) base = 10; else { base = -base; if (base > 36) return NULL; } sn = 1 + mpz_sizeinbase (u, base); if (!sp) sp = (char *) gmp_xalloc (1 + sn); un = GMP_ABS (u->_mp_size); if (un == 0) { sp[0] = '0'; sp[1] = '\0'; return sp; } i = 0; if (u->_mp_size < 0) sp[i++] = '-'; bits = mpn_base_power_of_two_p (base); if (bits) /* Not modified in this case. */ sn = i + mpn_get_str_bits ((unsigned char *) sp + i, bits, u->_mp_d, un); else { struct mpn_base_info info; mp_ptr tp; mpn_get_base_info (&info, base); tp = gmp_xalloc_limbs (un); mpn_copyi (tp, u->_mp_d, un); sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un); gmp_free (tp); } for (; i < sn; i++) sp[i] = digits[(unsigned char) sp[i]]; sp[sn] = '\0'; return sp; } int mpz_set_str (mpz_t r, const char *sp, int base) { unsigned bits, value_of_a; mp_size_t rn, alloc; mp_ptr rp; size_t dn; int sign; unsigned char *dp; assert (base == 0 || (base >= 2 && base <= 62)); while (isspace( (unsigned char) *sp)) sp++; sign = (*sp == '-'); sp += sign; if (base == 0) { if (sp[0] == '0') { if (sp[1] == 'x' || sp[1] == 'X') { base = 16; sp += 2; } else if (sp[1] == 'b' || sp[1] == 'B') { base = 2; sp += 2; } else base = 8; } else base = 10; } if (!*sp) { r->_mp_size = 0; return -1; } dp = (unsigned char *) gmp_xalloc (strlen (sp)); value_of_a = (base > 36) ? 36 : 10; for (dn = 0; *sp; sp++) { unsigned digit; if (isspace ((unsigned char) *sp)) continue; else if (*sp >= '0' && *sp <= '9') digit = *sp - '0'; else if (*sp >= 'a' && *sp <= 'z') digit = *sp - 'a' + value_of_a; else if (*sp >= 'A' && *sp <= 'Z') digit = *sp - 'A' + 10; else digit = base; /* fail */ if (digit >= (unsigned) base) { gmp_free (dp); r->_mp_size = 0; return -1; } dp[dn++] = digit; } if (!dn) { gmp_free (dp); r->_mp_size = 0; return -1; } bits = mpn_base_power_of_two_p (base); if (bits > 0) { alloc = (dn * bits + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; rp = MPZ_REALLOC (r, alloc); rn = mpn_set_str_bits (rp, dp, dn, bits); } else { struct mpn_base_info info; mpn_get_base_info (&info, base); alloc = (dn + info.exp - 1) / info.exp; rp = MPZ_REALLOC (r, alloc); rn = mpn_set_str_other (rp, dp, dn, base, &info); /* Normalization, needed for all-zero input. */ assert (rn > 0); rn -= rp[rn-1] == 0; } assert (rn <= alloc); gmp_free (dp); r->_mp_size = sign ? - rn : rn; return 0; } int mpz_init_set_str (mpz_t r, const char *sp, int base) { mpz_init (r); return mpz_set_str (r, sp, base); } size_t mpz_out_str (FILE *stream, int base, const mpz_t x) { char *str; size_t len; str = mpz_get_str (NULL, base, x); if (!str) return 0; len = strlen (str); len = fwrite (str, 1, len, stream); gmp_free (str); return len; } static int gmp_detect_endian (void) { static const int i = 2; const unsigned char *p = (const unsigned char *) &i; return 1 - *p; } /* Import and export. Does not support nails. */ void mpz_import (mpz_t r, size_t count, int order, size_t size, int endian, size_t nails, const void *src) { const unsigned char *p; ptrdiff_t word_step; mp_ptr rp; mp_size_t rn; /* The current (partial) limb. */ mp_limb_t limb; /* The number of bytes already copied to this limb (starting from the low end). */ size_t bytes; /* The index where the limb should be stored, when completed. */ mp_size_t i; if (nails != 0) gmp_die ("mpz_import: Nails not supported."); assert (order == 1 || order == -1); assert (endian >= -1 && endian <= 1); if (endian == 0) endian = gmp_detect_endian (); p = (unsigned char *) src; word_step = (order != endian) ? 2 * size : 0; /* Process bytes from the least significant end, so point p at the least significant word. */ if (order == 1) { p += size * (count - 1); word_step = - word_step; } /* And at least significant byte of that word. */ if (endian == 1) p += (size - 1); rn = (size * count + sizeof(mp_limb_t) - 1) / sizeof(mp_limb_t); rp = MPZ_REALLOC (r, rn); for (limb = 0, bytes = 0, i = 0; count > 0; count--, p += word_step) { size_t j; for (j = 0; j < size; j++, p -= (ptrdiff_t) endian) { limb |= (mp_limb_t) *p << (bytes++ * CHAR_BIT); if (bytes == sizeof(mp_limb_t)) { rp[i++] = limb; bytes = 0; limb = 0; } } } assert (i + (bytes > 0) == rn); if (limb != 0) rp[i++] = limb; else i = mpn_normalized_size (rp, i); r->_mp_size = i; } void * mpz_export (void *r, size_t *countp, int order, size_t size, int endian, size_t nails, const mpz_t u) { size_t count; mp_size_t un; if (nails != 0) gmp_die ("mpz_import: Nails not supported."); assert (order == 1 || order == -1); assert (endian >= -1 && endian <= 1); assert (size > 0 || u->_mp_size == 0); un = u->_mp_size; count = 0; if (un != 0) { size_t k; unsigned char *p; ptrdiff_t word_step; /* The current (partial) limb. */ mp_limb_t limb; /* The number of bytes left to do in this limb. */ size_t bytes; /* The index where the limb was read. */ mp_size_t i; un = GMP_ABS (un); /* Count bytes in top limb. */ limb = u->_mp_d[un-1]; assert (limb != 0); k = (GMP_LIMB_BITS <= CHAR_BIT); if (!k) { do { int LOCAL_CHAR_BIT = CHAR_BIT; k++; limb >>= LOCAL_CHAR_BIT; } while (limb != 0); } /* else limb = 0; */ count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size; if (!r) r = gmp_xalloc (count * size); if (endian == 0) endian = gmp_detect_endian (); p = (unsigned char *) r; word_step = (order != endian) ? 2 * size : 0; /* Process bytes from the least significant end, so point p at the least significant word. */ if (order == 1) { p += size * (count - 1); word_step = - word_step; } /* And at least significant byte of that word. */ if (endian == 1) p += (size - 1); for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step) { size_t j; for (j = 0; j < size; ++j, p -= (ptrdiff_t) endian) { if (sizeof (mp_limb_t) == 1) { if (i < un) *p = u->_mp_d[i++]; else *p = 0; } else { int LOCAL_CHAR_BIT = CHAR_BIT; if (bytes == 0) { if (i < un) limb = u->_mp_d[i++]; bytes = sizeof (mp_limb_t); } *p = limb; limb >>= LOCAL_CHAR_BIT; bytes--; } } } assert (i == un); assert (k == count); } if (countp) *countp = count; return r; } leidenbase/src/vendor/uuid/0000755000176200001440000000000014532173045015403 5ustar liggesusersleidenbase/src/vendor/uuid/unparse.c0000644000176200001440000000474314447675376017257 0ustar liggesusers/* * unparse.c -- convert a UUID to string * * Copyright (C) 1996, 1997 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #include #include "uuidP.h" static const char *fmt_lower = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"; static const char *fmt_upper = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"; #ifdef UUID_UNPARSE_DEFAULT_UPPER #define FMT_DEFAULT fmt_upper #else #define FMT_DEFAULT fmt_lower #endif static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt) { struct uuid uuid; uuid_unpack(uu, &uuid); snprintf(out, 37, fmt, uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, uuid.node[0], uuid.node[1], uuid.node[2], uuid.node[3], uuid.node[4], uuid.node[5]); } void uuid_unparse_lower(const uuid_t uu, char *out) { uuid_unparse_x(uu, out, fmt_lower); } void uuid_unparse_upper(const uuid_t uu, char *out) { uuid_unparse_x(uu, out, fmt_upper); } void uuid_unparse(const uuid_t uu, char *out) { uuid_unparse_x(uu, out, FMT_DEFAULT); } leidenbase/src/vendor/uuid/uuidP.h0000644000176200001440000000410614447675376016666 0ustar liggesusers/* * uuid.h -- private header file for uuids * * Copyright (C) 1996, 1997 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #include #include #include "config.h" #include "uuid.h" #define LIBUUID_CLOCK_FILE "/var/lib/libuuid/clock.txt" /* * Offset between 15-Oct-1582 and 1-Jan-70 */ #define TIME_OFFSET_HIGH 0x01B21DD2 #define TIME_OFFSET_LOW 0x13814000 struct uuid { uint32_t time_low; uint16_t time_mid; uint16_t time_hi_and_version; uint16_t clock_seq; uint8_t node[6]; }; /* * prototypes */ void uuid_pack(const struct uuid *uu, uuid_t ptr); void uuid_unpack(const uuid_t in, struct uuid *uu); leidenbase/src/vendor/uuid/gen_uuid.c0000644000176200001440000003105614447675376017376 0ustar liggesusers/* * gen_uuid.c --- generate a DCE-compatible uuid * * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ /* * Force inclusion of SVID stuff since we need it if we're compiling in * gcc-wall wall mode */ #define _DEFAULT_SOURCE #include "config.h" #ifdef _WIN32 #define _WIN32_WINNT 0x0500 #include #define UUID MYUUID #endif #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #include #ifdef HAVE_SYS_FILE_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_UN_H #include #endif #ifdef HAVE_SYS_SOCKIO_H #include #endif #ifdef HAVE_NET_IF_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NET_IF_DL_H #include #endif #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) #include #endif #include "uuidP.h" #include "uuidd.h" #ifdef USING_R #include "igraph_random.h" #define srand(x) ; #define rand() RNG_INTEGER(0, RAND_MAX) #endif #ifdef HAVE_TLS #define THREAD_LOCAL static __thread #else #define THREAD_LOCAL static #endif #ifdef _WIN32 #if 0 /* MinGW has gettimeofday so we don't need this */ static int gettimeofday (struct timeval *tv, void *dummy) { FILETIME ftime; uint64_t n; GetSystemTimeAsFileTime (&ftime); n = (((uint64_t) ftime.dwHighDateTime << 32) + (uint64_t) ftime.dwLowDateTime); if (n) { n /= 10; n -= ((369 * 365 + 89) * (uint64_t) 86400) * 1000000; } tv->tv_sec = n / 1000000; tv->tv_usec = n % 1000000; } #endif #ifdef __MINGW32__ int gettimeofday (struct timeval *tv, void *dummy); #endif #ifdef __MINGW64__ int gettimeofday (struct timeval *tv, void *dummy); #endif static int getuid (void) { return 1; } #endif /* * Get the ethernet hardware address, if we can find it... * * XXX for a windows version, probably should use GetAdaptersInfo: * http://www.codeguru.com/cpp/i-n/network/networkinformation/article.php/c5451 * commenting out get_node_id just to get gen_uuid to compile under windows * is not the right way to go! */ static int get_node_id(unsigned char *node_id) { #ifdef HAVE_NET_IF_H int sd; struct ifreq ifr, *ifrp; struct ifconf ifc; char buf[1024]; int n, i; unsigned char *a; #ifdef HAVE_NET_IF_DL_H struct sockaddr_dl *sdlp; #endif /* * BSD 4.4 defines the size of an ifreq to be * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len * However, under earlier systems, sa_len isn't present, so the size is * just sizeof(struct ifreq) */ #ifdef HAVE_SA_LEN #define max(x, y) (((x) > (y)) ? (x) : (y)) #define ifreq_size(i) max(sizeof(struct ifreq),\ sizeof((i).ifr_name)+(i).ifr_addr.sa_len) #else #define ifreq_size(i) sizeof(struct ifreq) #endif /* HAVE_SA_LEN */ sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sd < 0) { return -1; } memset(buf, 0, sizeof(buf)); ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) { close(sd); return -1; } n = ifc.ifc_len; for (i = 0; i < n; i+= ifreq_size(*ifrp) ) { ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i); strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ); #if defined(SIOCGIFHWADDR) && (!defined(__sun__)) if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) continue; a = (unsigned char *) &ifr.ifr_hwaddr.sa_data; #else #ifdef SIOCGENADDR if (ioctl(sd, SIOCGENADDR, &ifr) < 0) continue; a = (unsigned char *) ifr.ifr_enaddr; #else #ifdef HAVE_NET_IF_DL_H sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr; if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6)) continue; a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen]; #else /* * XXX we don't have a way of getting the hardware * address */ close(sd); return 0; #endif /* HAVE_NET_IF_DL_H */ #endif /* SIOCGENADDR */ #endif /* SIOCGIFHWADDR */ if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) continue; if (node_id) { memcpy(node_id, a, 6); close(sd); return 1; } } close(sd); #endif return 0; } #if defined(__linux__) && defined(__NR_gettid) && defined(HAVE_JRAND48) #define DO_JRAND_MIX static unsigned short ul_jrand_seed[3]; #endif static int random_get_fd(void) { int i, fd = -1; struct timeval tv; gettimeofday(&tv, NULL); #ifndef _WIN32 fd = open("/dev/urandom", O_RDONLY); if (fd == -1) fd = open("/dev/random", O_RDONLY | O_NONBLOCK); if (fd >= 0) { i = fcntl(fd, F_GETFD); if (i >= 0) fcntl(fd, F_SETFD, i | FD_CLOEXEC); } #endif srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec); #ifdef DO_JRAND_MIX ul_jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF); ul_jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF); ul_jrand_seed[2] = (tv.tv_sec ^ tv.tv_usec) >> 16; #endif /* Crank the random number generator a few times */ gettimeofday(&tv, NULL); for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) rand(); return fd; } /* * Generate a stream of random nbytes into buf. * Use /dev/urandom if possible, and if not, * use glibc pseudo-random functions. */ static void random_get_bytes(void *buf, size_t nbytes) { size_t i, n = nbytes; int fd = random_get_fd(); int lose_counter = 0; unsigned char *cp = (unsigned char *) buf; if (fd >= 0) { while (n > 0) { ssize_t x = read(fd, cp, n); if (x <= 0) { if (lose_counter++ > 16) break; continue; } n -= x; cp += x; lose_counter = 0; } close(fd); } /* * We do this all the time, but this is the only source of * randomness if /dev/random/urandom is out to lunch. */ for (cp = buf, i = 0; i < nbytes; i++) *cp++ ^= (rand() >> 7) & 0xFF; #ifdef DO_JRAND_MIX { unsigned short tmp_seed[3]; memcpy(tmp_seed, ul_jrand_seed, sizeof(tmp_seed)); ul_jrand_seed[2] = ul_jrand_seed[2] ^ syscall(__NR_gettid); for (cp = buf, i = 0; i < nbytes; i++) *cp++ ^= (jrand48(tmp_seed) >> 7) & 0xFF; memcpy(ul_jrand_seed, tmp_seed, sizeof(ul_jrand_seed)-sizeof(unsigned short)); } #endif return; } /* Assume that the gettimeofday() has microsecond granularity */ #define MAX_ADJUSTMENT 10 /* * Get clock from global sequence clock counter. * * Return -1 if the clock counter could not be opened/locked (in this case * pseudorandom value is returned in @ret_clock_seq), otherwise return 0. */ static int get_clock(uint32_t *clock_high, uint32_t *clock_low, uint16_t *ret_clock_seq, int *num) { THREAD_LOCAL int adjustment = 0; THREAD_LOCAL struct timeval last = {0, 0}; THREAD_LOCAL int state_fd = -2; THREAD_LOCAL FILE *state_f; THREAD_LOCAL uint16_t clock_seq; struct timeval tv; uint64_t clock_reg; mode_t save_umask; int len; int ret = 0; if (state_fd == -2) { save_umask = umask(0); state_fd = open(LIBUUID_CLOCK_FILE, O_RDWR|O_CREAT, 0660); (void) umask(save_umask); if (state_fd != -1) { state_f = fdopen(state_fd, "r+"); if (!state_f) { close(state_fd); state_fd = -1; ret = -1; } } else ret = -1; } if (state_fd >= 0) { rewind(state_f); } if (state_fd >= 0) { unsigned int cl; unsigned long tv1, tv2; int a; if (fscanf(state_f, "clock: %04x tv: %lu %lu adj: %d\n", &cl, &tv1, &tv2, &a) == 4) { clock_seq = cl & 0x3FFF; last.tv_sec = tv1; last.tv_usec = tv2; adjustment = a; } } if ((last.tv_sec == 0) && (last.tv_usec == 0)) { random_get_bytes(&clock_seq, sizeof(clock_seq)); clock_seq &= 0x3FFF; gettimeofday(&last, NULL); last.tv_sec--; } try_again: gettimeofday(&tv, NULL); if ((tv.tv_sec < last.tv_sec) || ((tv.tv_sec == last.tv_sec) && (tv.tv_usec < last.tv_usec))) { clock_seq = (clock_seq+1) & 0x3FFF; adjustment = 0; last = tv; } else if ((tv.tv_sec == last.tv_sec) && (tv.tv_usec == last.tv_usec)) { if (adjustment >= MAX_ADJUSTMENT) goto try_again; adjustment++; } else { adjustment = 0; last = tv; } clock_reg = tv.tv_usec*10 + adjustment; clock_reg += ((uint64_t) tv.tv_sec)*10000000; clock_reg += (((uint64_t) 0x01B21DD2) << 32) + 0x13814000; if (num && (*num > 1)) { adjustment += *num - 1; last.tv_usec += adjustment / 10; adjustment = adjustment % 10; last.tv_sec += last.tv_usec / 1000000; last.tv_usec = last.tv_usec % 1000000; } if (state_fd >= 0) { rewind(state_f); len = fprintf(state_f, "clock: %04x tv: %016lu %08lu adj: %08d\n", clock_seq, (unsigned long) last.tv_sec, (unsigned long) last.tv_usec, adjustment); fflush(state_f); if (ftruncate(state_fd, len) < 0) { fprintf(state_f, " \n"); fflush(state_f); } rewind(state_f); } *clock_high = clock_reg >> 32; *clock_low = clock_reg; *ret_clock_seq = clock_seq; return ret; } int __uuid_generate_time(uuid_t out, int *num) { static unsigned char node_id[6]; static int has_init = 0; struct uuid uu; uint32_t clock_mid; int ret; if (!has_init) { if (get_node_id(node_id) <= 0) { random_get_bytes(node_id, 6); /* * Set multicast bit, to prevent conflicts * with IEEE 802 addresses obtained from * network cards */ node_id[0] |= 0x01; } has_init = 1; } ret = get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num); uu.clock_seq |= 0x8000; uu.time_mid = (uint16_t) clock_mid; uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000; memcpy(uu.node, node_id, 6); uuid_pack(&uu, out); return ret; } /* * Generate time-based UUID and store it to @out * * Since there is no daemon here, use fall-back right away */ static int uuid_generate_time_generic(uuid_t out) { return __uuid_generate_time(out, 0); } /* * Generate time-based UUID and store it to @out. * * Discards return value from uuid_generate_time_generic() */ void uuid_generate_time(uuid_t out) { (void)uuid_generate_time_generic(out); } int uuid_generate_time_safe(uuid_t out) { return uuid_generate_time_generic(out); } void __uuid_generate_random(uuid_t out, int *num) { uuid_t buf; struct uuid uu; int i, n; if (!num || !*num) n = 1; else n = *num; for (i = 0; i < n; i++) { random_get_bytes(buf, sizeof(buf)); uuid_unpack(buf, &uu); uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000; uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000; uuid_pack(&uu, out); out += sizeof(uuid_t); } } void uuid_generate_random(uuid_t out) { int num = 1; /* No real reason to use the daemon for random uuid's -- yet */ __uuid_generate_random(out, &num); } /* * Check whether good random source (/dev/random or /dev/urandom) * is available. */ static int have_random_source(void) { struct stat s; return (!stat("/dev/random", &s) || !stat("/dev/urandom", &s)); } /* * This is the generic front-end to uuid_generate_random and * uuid_generate_time. It uses uuid_generate_random only if * /dev/urandom is available, since otherwise we won't have * high-quality randomness. */ void uuid_generate(uuid_t out) { if (have_random_source()) uuid_generate_random(out); else uuid_generate_time(out); } leidenbase/src/vendor/uuid/clear.c0000644000176200001440000000321414447675376016660 0ustar liggesusers/* * clear.c -- Clear a UUID * * Copyright (C) 1996, 1997 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #include #include "uuidP.h" void uuid_clear(uuid_t uu) { memset(uu, 0, 16); } leidenbase/src/vendor/uuid/parse.c0000644000176200001440000000456514447675376016716 0ustar liggesusers/* * parse.c --- UUID parsing * * Copyright (C) 1996, 1997 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #include #include #include #include #include "uuidP.h" int uuid_parse(const char *in, uuid_t uu) { struct uuid uuid; int i; const char *cp; char buf[3]; if (strlen(in) != 36) return -1; for (i=0, cp = in; i <= 36; i++,cp++) { if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { if (*cp == '-') continue; else return -1; } if (i== 36) if (*cp == 0) continue; if (!isxdigit(*cp)) return -1; } uuid.time_low = strtoul(in, NULL, 16); uuid.time_mid = strtoul(in+9, NULL, 16); uuid.time_hi_and_version = strtoul(in+14, NULL, 16); uuid.clock_seq = strtoul(in+19, NULL, 16); cp = in+24; buf[2] = 0; for (i=0; i < 6; i++) { buf[0] = *cp++; buf[1] = *cp++; uuid.node[i] = strtoul(buf, NULL, 16); } uuid_pack(&uuid, uu); return 0; } leidenbase/src/vendor/uuid/uuidd.h0000644000176200001440000000423014447675376016710 0ustar liggesusers/* * Definitions used by the uuidd daemon * * Copyright (C) 2007 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #ifndef _UUID_UUIDD_H #define _UUID_UUIDD_H #define UUIDD_DIR _PATH_LOCALSTATEDIR "/uuidd" #define UUIDD_SOCKET_PATH UUIDD_DIR "/request" #define UUIDD_PIDFILE_PATH UUIDD_DIR "/uuidd.pid" #define UUIDD_PATH "/usr/sbin/uuidd" #define UUIDD_OP_GETPID 0 #define UUIDD_OP_GET_MAXOP 1 #define UUIDD_OP_TIME_UUID 2 #define UUIDD_OP_RANDOM_UUID 3 #define UUIDD_OP_BULK_TIME_UUID 4 #define UUIDD_OP_BULK_RANDOM_UUID 5 #define UUIDD_MAX_OP UUIDD_OP_BULK_RANDOM_UUID extern int __uuid_generate_time(uuid_t out, int *num); extern void __uuid_generate_random(uuid_t out, int *num); #endif /* _UUID_UUID_H */ leidenbase/src/vendor/uuid/compare.c0000644000176200001440000000416714447675376017230 0ustar liggesusers/* * compare.c --- compare whether or not two UUIDs are the same * * Returns 0 if the two UUIDs are different, and 1 if they are the same. * * Copyright (C) 1996, 1997 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #include "uuidP.h" #include #define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1); int uuid_compare(const uuid_t uu1, const uuid_t uu2) { struct uuid uuid1, uuid2; uuid_unpack(uu1, &uuid1); uuid_unpack(uu2, &uuid2); UUCMP(uuid1.time_low, uuid2.time_low); UUCMP(uuid1.time_mid, uuid2.time_mid); UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version); UUCMP(uuid1.clock_seq, uuid2.clock_seq); return memcmp(uuid1.node, uuid2.node, 6); } leidenbase/src/vendor/uuid/win32/0000755000176200001440000000000014447675376016370 5ustar liggesusersleidenbase/src/vendor/uuid/win32/config.h0000644000176200001440000000476014447675376020015 0ustar liggesusers/* src/config.h. Generated from config.h.in by configure. */ /* src/config.h.in. Generated from configure.ac by autoheader. */ /* -- reflects MinGW + Win32 -- */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `jrand48' function. */ /* #undef HAVE_JRAND48 */ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_NETINET_IN_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_NET_IF_DL_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_NET_IF_H */ /* Define if struct sockaddr contains sa_len */ /* #undef HAVE_SA_LEN */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_FILE_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_IOCTL_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_SOCKET_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_SOCKIO_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_SYSCALL_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_UN_H */ /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "Simon.Urbanek@r-project.org" /* Define to the full name of this package. */ #define PACKAGE_NAME "uuid" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "uuid 0.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "uuid" /* Define to the version of this package. */ #define PACKAGE_VERSION "0.1" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 leidenbase/src/vendor/uuid/R.c0000644000176200001440000000061314447675376015773 0ustar liggesusers#include "uuid.h" #include #include "igraph_random.h" SEXP UUID_gen(SEXP sTime) { RNG_BEGIN(); uuid_t u; char c[40]; int use_time = asInteger(sTime); if (use_time == TRUE) uuid_generate_time(u); else if (use_time == FALSE) uuid_generate_random(u); else uuid_generate(u); uuid_unparse_lower(u, c); RNG_END(); return mkString(c); } leidenbase/src/vendor/uuid/copy.c0000644000176200001440000000335714447675376016554 0ustar liggesusers/* * copy.c --- copy UUIDs * * Copyright (C) 1996, 1997 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #include "uuidP.h" void uuid_copy(uuid_t dst, const uuid_t src) { unsigned char *cp1; const unsigned char *cp2; int i; for (i=0, cp1 = dst, cp2 = src; i < 16; i++) *cp1++ = *cp2++; } leidenbase/src/vendor/uuid/unpack.c0000644000176200001440000000405114447675376017053 0ustar liggesusers/* * Internal routine for unpacking UUID * * Copyright (C) 1996, 1997 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #include #include "uuidP.h" void uuid_unpack(const uuid_t in, struct uuid *uu) { const uint8_t *ptr = in; uint32_t tmp; tmp = *ptr++; tmp = (tmp << 8) | *ptr++; tmp = (tmp << 8) | *ptr++; tmp = (tmp << 8) | *ptr++; uu->time_low = tmp; tmp = *ptr++; tmp = (tmp << 8) | *ptr++; uu->time_mid = tmp; tmp = *ptr++; tmp = (tmp << 8) | *ptr++; uu->time_hi_and_version = tmp; tmp = *ptr++; tmp = (tmp << 8) | *ptr++; uu->clock_seq = tmp; memcpy(uu->node, ptr, 6); } leidenbase/src/vendor/uuid/pack.c0000644000176200001440000000430414447675376016511 0ustar liggesusers/* * Internal routine for packing UUIDs * * Copyright (C) 1996, 1997 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #include #include "uuidP.h" void uuid_pack(const struct uuid *uu, uuid_t ptr) { uint32_t tmp; unsigned char *out = ptr; tmp = uu->time_low; out[3] = (unsigned char) tmp; tmp >>= 8; out[2] = (unsigned char) tmp; tmp >>= 8; out[1] = (unsigned char) tmp; tmp >>= 8; out[0] = (unsigned char) tmp; tmp = uu->time_mid; out[5] = (unsigned char) tmp; tmp >>= 8; out[4] = (unsigned char) tmp; tmp = uu->time_hi_and_version; out[7] = (unsigned char) tmp; tmp >>= 8; out[6] = (unsigned char) tmp; tmp = uu->clock_seq; out[9] = (unsigned char) tmp; tmp >>= 8; out[8] = (unsigned char) tmp; memcpy(out+10, uu->node, 6); } leidenbase/src/vendor/uuid/Makevars.win0000644000176200001440000000002514447675376017713 0ustar liggesusersPKG_CPPFLAGS=-Iwin32 leidenbase/src/vendor/uuid/COPYING0000644000176200001440000000274514447675376016471 0ustar liggesusersThis library is free software; you can redistribute it and/or modify it under the terms of the Modified BSD License: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, and the entire permission notice in its entirety, including the disclaimer of warranties. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. leidenbase/src/vendor/uuid/isnull.c0000644000176200001440000000343614447675376017106 0ustar liggesusers/* * isnull.c --- Check whether or not the UUID is null * * Copyright (C) 1996, 1997 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #include "uuidP.h" /* Returns 1 if the uuid is the NULL uuid */ int uuid_is_null(const uuid_t uu) { const unsigned char *cp; int i; for (i=0, cp = uu; i < 16; i++) if (*cp++) return 0; return 1; } leidenbase/src/vendor/uuid/config.h.in0000644000176200001440000000435414447675376017457 0ustar liggesusers/* src/config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `jrand48' function. */ #undef HAVE_JRAND48 /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_DL_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H /* Define if struct sockaddr contains sa_len */ #undef HAVE_SA_LEN /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSCALL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UN_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS leidenbase/src/vendor/uuid/uuid.h0000644000176200001440000000634114447675376016551 0ustar liggesusers/* * Public include file for the UUID library * * Copyright (C) 1996, 1997, 1998 Theodore Ts'o. * * %Begin-Header% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * %End-Header% */ #ifndef _UUID_UUID_H #define _UUID_UUID_H #include #ifndef _WIN32 #include #endif #include typedef unsigned char uuid_t[16]; /* UUID Variant definitions */ #define UUID_VARIANT_NCS 0 #define UUID_VARIANT_DCE 1 #define UUID_VARIANT_MICROSOFT 2 #define UUID_VARIANT_OTHER 3 /* UUID Type definitions */ #define UUID_TYPE_DCE_TIME 1 #define UUID_TYPE_DCE_RANDOM 4 /* Allow UUID constants to be defined */ #ifdef __GNUC__ #define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \ static const uuid_t name __attribute__ ((unused)) = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15} #else #define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \ static const uuid_t name = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15} #endif #ifdef __cplusplus extern "C" { #endif /* clear.c */ void uuid_clear(uuid_t uu); /* compare.c */ int uuid_compare(const uuid_t uu1, const uuid_t uu2); /* copy.c */ void uuid_copy(uuid_t dst, const uuid_t src); /* gen_uuid.c */ void uuid_generate(uuid_t out); void uuid_generate_random(uuid_t out); void uuid_generate_time(uuid_t out); int uuid_generate_time_safe(uuid_t out); /* isnull.c */ int uuid_is_null(const uuid_t uu); /* parse.c */ int uuid_parse(const char *in, uuid_t uu); /* unparse.c */ void uuid_unparse(const uuid_t uu, char *out); void uuid_unparse_lower(const uuid_t uu, char *out); void uuid_unparse_upper(const uuid_t uu, char *out); /* uuid_time.c */ time_t uuid_time(const uuid_t uu, struct timeval *ret_tv); int uuid_type(const uuid_t uu); int uuid_variant(const uuid_t uu); #ifdef __cplusplus } #endif #endif /* _UUID_UUID_H */ leidenbase/src/vendor/uuid/Makevars.in0000644000176200001440000000005014447675376017522 0ustar liggesusersPKG_CPPFLAGS=@CPPFLAGS@ PKG_LIBS=@LIBS@ leidenbase/src/vendor/arpack/0000755000176200001440000000000014532173045015676 5ustar liggesusersleidenbase/src/vendor/arpack/dlaqrb.f0000644000176200001440000004405014447675376017340 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdlaqrb c c\Description: c Compute the eigenvalues and the Schur decomposition of an upper c Hessenberg submatrix in rows and columns ILO to IHI. Only the c last component of the Schur vectors are computed. c c This is mostly a modification of the LAPACK routine dlahqr. c c\Usage: c call igraphdlaqrb c ( WANTT, N, ILO, IHI, H, LDH, WR, WI, Z, INFO ) c c\Arguments c WANTT Logical variable. (INPUT) c = .TRUE. : the full Schur form T is required; c = .FALSE.: only eigenvalues are required. c c N Integer. (INPUT) c The order of the matrix H. N >= 0. c c ILO Integer. (INPUT) c IHI Integer. (INPUT) c It is assumed that H is already upper quasi-triangular in c rows and columns IHI+1:N, and that H(ILO,ILO-1) = 0 (unless c ILO = 1). SLAQRB works primarily with the Hessenberg c submatrix in rows and columns ILO to IHI, but applies c transformations to all of H if WANTT is .TRUE.. c 1 <= ILO <= max(1,IHI); IHI <= N. c c H Double precision array, dimension (LDH,N). (INPUT/OUTPUT) c On entry, the upper Hessenberg matrix H. c On exit, if WANTT is .TRUE., H is upper quasi-triangular in c rows and columns ILO:IHI, with any 2-by-2 diagonal blocks in c standard form. If WANTT is .FALSE., the contents of H are c unspecified on exit. c c LDH Integer. (INPUT) c The leading dimension of the array H. LDH >= max(1,N). c c WR Double precision array, dimension (N). (OUTPUT) c WI Double precision array, dimension (N). (OUTPUT) c The real and imaginary parts, respectively, of the computed c eigenvalues ILO to IHI are stored in the corresponding c elements of WR and WI. If two eigenvalues are computed as a c complex conjugate pair, they are stored in consecutive c elements of WR and WI, say the i-th and (i+1)th, with c WI(i) > 0 and WI(i+1) < 0. If WANTT is .TRUE., the c eigenvalues are stored in the same order as on the diagonal c of the Schur form returned in H, with WR(i) = H(i,i), and, if c H(i:i+1,i:i+1) is a 2-by-2 diagonal block, c WI(i) = sqrt(H(i+1,i)*H(i,i+1)) and WI(i+1) = -WI(i). c c Z Double precision array, dimension (N). (OUTPUT) c On exit Z contains the last components of the Schur vectors. c c INFO Integer. (OUPUT) c = 0: successful exit c > 0: SLAQRB failed to compute all the eigenvalues ILO to IHI c in a total of 30*(IHI-ILO+1) iterations; if INFO = i, c elements i+1:ihi of WR and WI contain those eigenvalues c which have been successfully computed. c c\Remarks c 1. None. c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\Routines called: c dlabad LAPACK routine that computes machine constants. c dlamch LAPACK routine that determines machine constants. c dlanhs LAPACK routine that computes various norms of a matrix. c dlanv2 LAPACK routine that computes the Schur factorization of c 2 by 2 nonsymmetric matrix in standard form. c dlarfg LAPACK Householder reflection construction routine. c dcopy Level 1 BLAS that copies one vector to another. c drot Level 1 BLAS that applies a rotation to a 2 by 2 matrix. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/92: Version ' 2.4' c Modified from the LAPACK routine dlahqr so that only the c last component of the Schur vectors are computed. c c\SCCS Information: @(#) c FILE: laqrb.F SID: 2.2 DATE OF SID: 8/27/96 RELEASE: 2 c c\Remarks c 1. None c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdlaqrb ( wantt, n, ilo, ihi, h, ldh, wr, wi, & z, info ) c c %------------------% c | Scalar Arguments | c %------------------% c logical wantt integer ihi, ilo, info, ldh, n c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & h( ldh, * ), wi( * ), wr( * ), z( * ) c c %------------% c | Parameters | c %------------% c Double precision & zero, one, dat1, dat2 parameter (zero = 0.0D+0, one = 1.0D+0, dat1 = 7.5D-1, & dat2 = -4.375D-1) c c %------------------------% c | Local Scalars & Arrays | c %------------------------% c integer i, i1, i2, itn, its, j, k, l, m, nh, nr Double precision & cs, h00, h10, h11, h12, h21, h22, h33, h33s, & h43h34, h44, h44s, ovfl, s, smlnum, sn, sum, & t1, t2, t3, tst1, ulp, unfl, v1, v2, v3 Double precision & v( 3 ), work( 1 ) c c %--------------------% c | External Functions | c %--------------------% c Double precision & dlamch, dlanhs external dlamch, dlanhs c c %----------------------% c | External Subroutines | c %----------------------% c external dcopy, dlabad, dlanv2, dlarfg, drot c c %-----------------------% c | Executable Statements | c %-----------------------% c info = 0 c c %--------------------------% c | Quick return if possible | c %--------------------------% c if( n.eq.0 ) & return if( ilo.eq.ihi ) then wr( ilo ) = h( ilo, ilo ) wi( ilo ) = zero return end if c c %---------------------------------------------% c | Initialize the vector of last components of | c | the Schur vectors for accumulation. | c %---------------------------------------------% c do 5 j = 1, n-1 z(j) = zero 5 continue z(n) = one c nh = ihi - ilo + 1 c c %-------------------------------------------------------------% c | Set machine-dependent constants for the stopping criterion. | c | If norm(H) <= sqrt(OVFL), overflow should not occur. | c %-------------------------------------------------------------% c unfl = dlamch( 'safe minimum' ) ovfl = one / unfl call dlabad( unfl, ovfl ) ulp = dlamch( 'precision' ) smlnum = unfl*( nh / ulp ) c c %---------------------------------------------------------------% c | I1 and I2 are the indices of the first row and last column | c | of H to which transformations must be applied. If eigenvalues | c | only are computed, I1 and I2 are set inside the main loop. | c | Zero out H(J+2,J) = ZERO for J=1:N if WANTT = .TRUE. | c | else H(J+2,J) for J=ILO:IHI-ILO-1 if WANTT = .FALSE. | c %---------------------------------------------------------------% c if( wantt ) then i1 = 1 i2 = n do 8 i=1,i2-2 h(i1+i+1,i) = zero 8 continue else do 9 i=1, ihi-ilo-1 h(ilo+i+1,ilo+i-1) = zero 9 continue end if c c %---------------------------------------------------% c | ITN is the total number of QR iterations allowed. | c %---------------------------------------------------% c itn = 30*nh c c ------------------------------------------------------------------ c The main loop begins here. I is the loop index and decreases from c IHI to ILO in steps of 1 or 2. Each iteration of the loop works c with the active submatrix in rows and columns L to I. c Eigenvalues I+1 to IHI have already converged. Either L = ILO or c H(L,L-1) is negligible so that the matrix splits. c ------------------------------------------------------------------ c i = ihi 10 continue l = ilo if( i.lt.ilo ) & go to 150 c %--------------------------------------------------------------% c | Perform QR iterations on rows and columns ILO to I until a | c | submatrix of order 1 or 2 splits off at the bottom because a | c | subdiagonal element has become negligible. | c %--------------------------------------------------------------% do 130 its = 0, itn c c %----------------------------------------------% c | Look for a single small subdiagonal element. | c %----------------------------------------------% c do 20 k = i, l + 1, -1 tst1 = abs( h( k-1, k-1 ) ) + abs( h( k, k ) ) if( tst1.eq.zero ) & tst1 = dlanhs( '1', i-l+1, h( l, l ), ldh, work ) if( abs( h( k, k-1 ) ).le.max( ulp*tst1, smlnum ) ) & go to 30 20 continue 30 continue l = k if( l.gt.ilo ) then c c %------------------------% c | H(L,L-1) is negligible | c %------------------------% c h( l, l-1 ) = zero end if c c %-------------------------------------------------------------% c | Exit from loop if a submatrix of order 1 or 2 has split off | c %-------------------------------------------------------------% c if( l.ge.i-1 ) & go to 140 c c %---------------------------------------------------------% c | Now the active submatrix is in rows and columns L to I. | c | If eigenvalues only are being computed, only the active | c | submatrix need be transformed. | c %---------------------------------------------------------% c if( .not.wantt ) then i1 = l i2 = i end if c if( its.eq.10 .or. its.eq.20 ) then c c %-------------------% c | Exceptional shift | c %-------------------% c s = abs( h( i, i-1 ) ) + abs( h( i-1, i-2 ) ) h44 = dat1*s h33 = h44 h43h34 = dat2*s*s c else c c %-----------------------------------------% c | Prepare to use Wilkinson's double shift | c %-----------------------------------------% c h44 = h( i, i ) h33 = h( i-1, i-1 ) h43h34 = h( i, i-1 )*h( i-1, i ) end if c c %-----------------------------------------------------% c | Look for two consecutive small subdiagonal elements | c %-----------------------------------------------------% c do 40 m = i - 2, l, -1 c c %---------------------------------------------------------% c | Determine the effect of starting the double-shift QR | c | iteration at row M, and see if this would make H(M,M-1) | c | negligible. | c %---------------------------------------------------------% c h11 = h( m, m ) h22 = h( m+1, m+1 ) h21 = h( m+1, m ) h12 = h( m, m+1 ) h44s = h44 - h11 h33s = h33 - h11 v1 = ( h33s*h44s-h43h34 ) / h21 + h12 v2 = h22 - h11 - h33s - h44s v3 = h( m+2, m+1 ) s = abs( v1 ) + abs( v2 ) + abs( v3 ) v1 = v1 / s v2 = v2 / s v3 = v3 / s v( 1 ) = v1 v( 2 ) = v2 v( 3 ) = v3 if( m.eq.l ) & go to 50 h00 = h( m-1, m-1 ) h10 = h( m, m-1 ) tst1 = abs( v1 )*( abs( h00 )+abs( h11 )+abs( h22 ) ) if( abs( h10 )*( abs( v2 )+abs( v3 ) ).le.ulp*tst1 ) & go to 50 40 continue 50 continue c c %----------------------% c | Double-shift QR step | c %----------------------% c do 120 k = m, i - 1 c c ------------------------------------------------------------ c The first iteration of this loop determines a reflection G c from the vector V and applies it from left and right to H, c thus creating a nonzero bulge below the subdiagonal. c c Each subsequent iteration determines a reflection G to c restore the Hessenberg form in the (K-1)th column, and thus c chases the bulge one step toward the bottom of the active c submatrix. NR is the order of G. c ------------------------------------------------------------ c nr = min( 3, i-k+1 ) if( k.gt.m ) & call dcopy( nr, h( k, k-1 ), 1, v, 1 ) call dlarfg( nr, v( 1 ), v( 2 ), 1, t1 ) if( k.gt.m ) then h( k, k-1 ) = v( 1 ) h( k+1, k-1 ) = zero if( k.lt.i-1 ) & h( k+2, k-1 ) = zero else if( m.gt.l ) then h( k, k-1 ) = -h( k, k-1 ) end if v2 = v( 2 ) t2 = t1*v2 if( nr.eq.3 ) then v3 = v( 3 ) t3 = t1*v3 c c %------------------------------------------------% c | Apply G from the left to transform the rows of | c | the matrix in columns K to I2. | c %------------------------------------------------% c do 60 j = k, i2 sum = h( k, j ) + v2*h( k+1, j ) + v3*h( k+2, j ) h( k, j ) = h( k, j ) - sum*t1 h( k+1, j ) = h( k+1, j ) - sum*t2 h( k+2, j ) = h( k+2, j ) - sum*t3 60 continue c c %----------------------------------------------------% c | Apply G from the right to transform the columns of | c | the matrix in rows I1 to min(K+3,I). | c %----------------------------------------------------% c do 70 j = i1, min( k+3, i ) sum = h( j, k ) + v2*h( j, k+1 ) + v3*h( j, k+2 ) h( j, k ) = h( j, k ) - sum*t1 h( j, k+1 ) = h( j, k+1 ) - sum*t2 h( j, k+2 ) = h( j, k+2 ) - sum*t3 70 continue c c %----------------------------------% c | Accumulate transformations for Z | c %----------------------------------% c sum = z( k ) + v2*z( k+1 ) + v3*z( k+2 ) z( k ) = z( k ) - sum*t1 z( k+1 ) = z( k+1 ) - sum*t2 z( k+2 ) = z( k+2 ) - sum*t3 else if( nr.eq.2 ) then c c %------------------------------------------------% c | Apply G from the left to transform the rows of | c | the matrix in columns K to I2. | c %------------------------------------------------% c do 90 j = k, i2 sum = h( k, j ) + v2*h( k+1, j ) h( k, j ) = h( k, j ) - sum*t1 h( k+1, j ) = h( k+1, j ) - sum*t2 90 continue c c %----------------------------------------------------% c | Apply G from the right to transform the columns of | c | the matrix in rows I1 to min(K+3,I). | c %----------------------------------------------------% c do 100 j = i1, i sum = h( j, k ) + v2*h( j, k+1 ) h( j, k ) = h( j, k ) - sum*t1 h( j, k+1 ) = h( j, k+1 ) - sum*t2 100 continue c c %----------------------------------% c | Accumulate transformations for Z | c %----------------------------------% c sum = z( k ) + v2*z( k+1 ) z( k ) = z( k ) - sum*t1 z( k+1 ) = z( k+1 ) - sum*t2 end if 120 continue 130 continue c c %-------------------------------------------------------% c | Failure to converge in remaining number of iterations | c %-------------------------------------------------------% c info = i return 140 continue if( l.eq.i ) then c c %------------------------------------------------------% c | H(I,I-1) is negligible: one eigenvalue has converged | c %------------------------------------------------------% c wr( i ) = h( i, i ) wi( i ) = zero else if( l.eq.i-1 ) then c c %--------------------------------------------------------% c | H(I-1,I-2) is negligible; | c | a pair of eigenvalues have converged. | c | | c | Transform the 2-by-2 submatrix to standard Schur form, | c | and compute and store the eigenvalues. | c %--------------------------------------------------------% c call dlanv2( h( i-1, i-1 ), h( i-1, i ), h( i, i-1 ), & h( i, i ), wr( i-1 ), wi( i-1 ), wr( i ), wi( i ), & cs, sn ) if( wantt ) then c c %-----------------------------------------------------% c | Apply the transformation to the rest of H and to Z, | c | as required. | c %-----------------------------------------------------% c if( i2.gt.i ) & call drot( i2-i, h( i-1, i+1 ), ldh, h( i, i+1 ), ldh, & cs, sn ) call drot( i-i1-1, h( i1, i-1 ), 1, h( i1, i ), 1, cs, sn ) sum = cs*z( i-1 ) + sn*z( i ) z( i ) = cs*z( i ) - sn*z( i-1 ) z( i-1 ) = sum end if end if c c %---------------------------------------------------------% c | Decrement number of remaining iterations, and return to | c | start of the main loop with new value of I. | c %---------------------------------------------------------% c itn = itn - its i = l - 1 go to 10 150 continue return c c %---------------% c | End of igraphdlaqrb | c %---------------% c end leidenbase/src/vendor/arpack/dneigh.f0000644000176200001440000002444614447675376017340 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdneigh c c\Description: c Compute the eigenvalues of the current upper Hessenberg matrix c and the corresponding Ritz estimates given the current residual norm. c c\Usage: c call igraphdneigh c ( RNORM, N, H, LDH, RITZR, RITZI, BOUNDS, Q, LDQ, WORKL, IERR ) c c\Arguments c RNORM Double precision scalar. (INPUT) c Residual norm corresponding to the current upper Hessenberg c matrix H. c c N Integer. (INPUT) c Size of the matrix H. c c H Double precision N by N array. (INPUT) c H contains the current upper Hessenberg matrix. c c LDH Integer. (INPUT) c Leading dimension of H exactly as declared in the calling c program. c c RITZR, Double precision arrays of length N. (OUTPUT) c RITZI On output, RITZR(1:N) (resp. RITZI(1:N)) contains the real c (respectively imaginary) parts of the eigenvalues of H. c c BOUNDS Double precision array of length N. (OUTPUT) c On output, BOUNDS contains the Ritz estimates associated with c the eigenvalues RITZR and RITZI. This is equal to RNORM c times the last components of the eigenvectors corresponding c to the eigenvalues in RITZR and RITZI. c c Q Double precision N by N array. (WORKSPACE) c Workspace needed to store the eigenvectors of H. c c LDQ Integer. (INPUT) c Leading dimension of Q exactly as declared in the calling c program. c c WORKL Double precision work array of length N**2 + 3*N. (WORKSPACE) c Private (replicated) array on each PE or array allocated on c the front end. This is needed to keep the full Schur form c of H and also in the calculation of the eigenvectors of H. c c IERR Integer. (OUTPUT) c Error exit flag from igraphdlaqrb or dtrevc. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\Routines called: c igraphdlaqrb ARPACK routine to compute the real Schur form of an c upper Hessenberg matrix and last row of the Schur vectors. c igraphsecond ARPACK utility routine for timing. c igraphdmout ARPACK utility routine that prints matrices c igraphdvout ARPACK utility routine that prints vectors. c dlacpy LAPACK matrix copy routine. c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully. c dtrevc LAPACK routine to compute the eigenvectors of a matrix c in upper quasi-triangular form c dgemv Level 2 BLAS routine for matrix vector multiplication. c dcopy Level 1 BLAS that copies one vector to another . c dnrm2 Level 1 BLAS that computes the norm of a vector. c dscal Level 1 BLAS that scales a vector. c c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/92: Version ' 2.1' c c\SCCS Information: @(#) c FILE: neigh.F SID: 2.3 DATE OF SID: 4/20/96 RELEASE: 2 c c\Remarks c None c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdneigh (rnorm, n, h, ldh, ritzr, ritzi, bounds, & q, ldq, workl, ierr) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c integer ierr, n, ldh, ldq Double precision & rnorm c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & bounds(n), h(ldh,n), q(ldq,n), ritzi(n), ritzr(n), & workl(n*(n+3)) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %------------------------% c | Local Scalars & Arrays | c %------------------------% c logical select(1) integer i, iconj, msglvl Double precision & temp, vl(1) c c %----------------------% c | External Subroutines | c %----------------------% c external dcopy, dlacpy, igraphdlaqrb, dtrevc, igraphdvout, & igraphsecond c c %--------------------% c | External Functions | c %--------------------% c Double precision & dlapy2, dnrm2 external dlapy2, dnrm2 c c %---------------------% c | Intrinsic Functions | c %---------------------% c intrinsic abs c c %-----------------------% c | Executable Statements | c %-----------------------% c c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = mneigh c if (msglvl .gt. 2) then call igraphdmout (logfil, n, n, h, ldh, ndigit, & '_neigh: Entering upper Hessenberg matrix H ') end if c c %-----------------------------------------------------------% c | 1. Compute the eigenvalues, the last components of the | c | corresponding Schur vectors and the full Schur form T | c | of the current upper Hessenberg matrix H. | c | igraphdlaqrb returns the full Schur form of H in WORKL(1:N**2) | c | and the last components of the Schur vectors in BOUNDS. | c %-----------------------------------------------------------% c call dlacpy ('All', n, n, h, ldh, workl, n) call igraphdlaqrb (.true., n, 1, n, workl, n, ritzr, ritzi, & bounds, ierr) if (ierr .ne. 0) go to 9000 c if (msglvl .gt. 1) then call igraphdvout (logfil, n, bounds, ndigit, & '_neigh: last row of the Schur matrix for H') end if c c %-----------------------------------------------------------% c | 2. Compute the eigenvectors of the full Schur form T and | c | apply the last components of the Schur vectors to get | c | the last components of the corresponding eigenvectors. | c | Remember that if the i-th and (i+1)-st eigenvalues are | c | complex conjugate pairs, then the real & imaginary part | c | of the eigenvector components are split across adjacent | c | columns of Q. | c %-----------------------------------------------------------% c call dtrevc ('R', 'A', select, n, workl, n, vl, n, q, ldq, & n, n, workl(n*n+1), ierr) c if (ierr .ne. 0) go to 9000 c c %------------------------------------------------% c | Scale the returning eigenvectors so that their | c | euclidean norms are all one. LAPACK subroutine | c | dtrevc returns each eigenvector normalized so | c | that the element of largest magnitude has | c | magnitude 1; here the magnitude of a complex | c | number (x,y) is taken to be |x| + |y|. | c %------------------------------------------------% c iconj = 0 do 10 i=1, n if ( abs( ritzi(i) ) .le. zero ) then c c %----------------------% c | Real eigenvalue case | c %----------------------% c temp = dnrm2( n, q(1,i), 1 ) call dscal ( n, one / temp, q(1,i), 1 ) else c c %-------------------------------------------% c | Complex conjugate pair case. Note that | c | since the real and imaginary part of | c | the eigenvector are stored in consecutive | c | columns, we further normalize by the | c | square root of two. | c %-------------------------------------------% c if (iconj .eq. 0) then temp = dlapy2( dnrm2( n, q(1,i), 1 ), & dnrm2( n, q(1,i+1), 1 ) ) call dscal ( n, one / temp, q(1,i), 1 ) call dscal ( n, one / temp, q(1,i+1), 1 ) iconj = 1 else iconj = 0 end if end if 10 continue c call dgemv ('T', n, n, one, q, ldq, bounds, 1, zero, workl, 1) c if (msglvl .gt. 1) then call igraphdvout (logfil, n, workl, ndigit, & '_neigh: Last row of the eigenvector matrix for H') end if c c %----------------------------% c | Compute the Ritz estimates | c %----------------------------% c iconj = 0 do 20 i = 1, n if ( abs( ritzi(i) ) .le. zero ) then c c %----------------------% c | Real eigenvalue case | c %----------------------% c bounds(i) = rnorm * abs( workl(i) ) else c c %-------------------------------------------% c | Complex conjugate pair case. Note that | c | since the real and imaginary part of | c | the eigenvector are stored in consecutive | c | columns, we need to take the magnitude | c | of the last components of the two vectors | c %-------------------------------------------% c if (iconj .eq. 0) then bounds(i) = rnorm * dlapy2( workl(i), workl(i+1) ) bounds(i+1) = bounds(i) iconj = 1 else iconj = 0 end if end if 20 continue c if (msglvl .gt. 2) then call igraphdvout (logfil, n, ritzr, ndigit, & '_neigh: Real part of the eigenvalues of H') call igraphdvout (logfil, n, ritzi, ndigit, & '_neigh: Imaginary part of the eigenvalues of H') call igraphdvout (logfil, n, bounds, ndigit, & '_neigh: Ritz estimates for the eigenvalues of H') end if c call igraphsecond (t1) tneigh = tneigh + (t1 - t0) c 9000 continue return c c %---------------% c | End of igraphdneigh | c %---------------% c end leidenbase/src/vendor/arpack/dnaup2.f0000644000176200001440000007610314447675376017270 0ustar liggesusersc\BeginDoc c c\Name: igraphdnaup2 c c\Description: c Intermediate level interface called by igraphdnaupd. c c\Usage: c call igraphdnaup2 c ( IDO, BMAT, N, WHICH, NEV, NP, TOL, RESID, MODE, IUPD, c ISHIFT, MXITER, V, LDV, H, LDH, RITZR, RITZI, BOUNDS, c Q, LDQ, WORKL, IPNTR, WORKD, INFO ) c c\Arguments c c IDO, BMAT, N, WHICH, NEV, TOL, RESID: same as defined in igraphdnaupd. c MODE, ISHIFT, MXITER: see the definition of IPARAM in igraphdnaupd. c c NP Integer. (INPUT/OUTPUT) c Contains the number of implicit shifts to apply during c each Arnoldi iteration. c If ISHIFT=1, NP is adjusted dynamically at each iteration c to accelerate convergence and prevent stagnation. c This is also roughly equal to the number of matrix-vector c products (involving the operator OP) per Arnoldi iteration. c The logic for adjusting is contained within the current c subroutine. c If ISHIFT=0, NP is the number of shifts the user needs c to provide via reverse comunication. 0 < NP < NCV-NEV. c NP may be less than NCV-NEV for two reasons. The first, is c to keep complex conjugate pairs of "wanted" Ritz values c together. The igraphsecond, is that a leading block of the current c upper Hessenberg matrix has split off and contains "unwanted" c Ritz values. c Upon termination of the IRA iteration, NP contains the number c of "converged" wanted Ritz values. c c IUPD Integer. (INPUT) c IUPD .EQ. 0: use explicit restart instead implicit update. c IUPD .NE. 0: use implicit update. c c V Double precision N by (NEV+NP) array. (INPUT/OUTPUT) c The Arnoldi basis vectors are returned in the first NEV c columns of V. c c LDV Integer. (INPUT) c Leading dimension of V exactly as declared in the calling c program. c c H Double precision (NEV+NP) by (NEV+NP) array. (OUTPUT) c H is used to store the generated upper Hessenberg matrix c c LDH Integer. (INPUT) c Leading dimension of H exactly as declared in the calling c program. c c RITZR, Double precision arrays of length NEV+NP. (OUTPUT) c RITZI RITZR(1:NEV) (resp. RITZI(1:NEV)) contains the real (resp. c imaginary) part of the computed Ritz values of OP. c c BOUNDS Double precision array of length NEV+NP. (OUTPUT) c BOUNDS(1:NEV) contain the error bounds corresponding to c the computed Ritz values. c c Q Double precision (NEV+NP) by (NEV+NP) array. (WORKSPACE) c Private (replicated) work array used to accumulate the c rotation in the shift application step. c c LDQ Integer. (INPUT) c Leading dimension of Q exactly as declared in the calling c program. c c WORKL Double precision work array of length at least c (NEV+NP)**2 + 3*(NEV+NP). (INPUT/WORKSPACE) c Private (replicated) array on each PE or array allocated on c the front end. It is used in shifts calculation, shifts c application and convergence checking. c c On exit, the last 3*(NEV+NP) locations of WORKL contain c the Ritz values (real,imaginary) and associated Ritz c estimates of the current Hessenberg matrix. They are c listed in the same order as returned from igraphdneigh. c c If ISHIFT .EQ. O and IDO .EQ. 3, the first 2*NP locations c of WORKL are used in reverse communication to hold the user c supplied shifts. c c IPNTR Integer array of length 3. (OUTPUT) c Pointer to mark the starting locations in the WORKD for c vectors used by the Arnoldi iteration. c ------------------------------------------------------------- c IPNTR(1): pointer to the current operand vector X. c IPNTR(2): pointer to the current result vector Y. c IPNTR(3): pointer to the vector B * X when used in the c shift-and-invert mode. X is the current operand. c ------------------------------------------------------------- c c WORKD Double precision work array of length 3*N. (WORKSPACE) c Distributed array to be used in the basic Arnoldi iteration c for reverse communication. The user should not use WORKD c as temporary workspace during the iteration !!!!!!!!!! c See Data Distribution Note in DNAUPD. c c INFO Integer. (INPUT/OUTPUT) c If INFO .EQ. 0, a randomly initial residual vector is used. c If INFO .NE. 0, RESID contains the initial residual vector, c possibly from a previous run. c Error flag on output. c = 0: Normal return. c = 1: Maximum number of iterations taken. c All possible eigenvalues of OP has been found. c NP returns the number of converged Ritz values. c = 2: No shifts could be applied. c = -8: Error return from LAPACK eigenvalue calculation; c This should never happen. c = -9: Starting vector is zero. c = -9999: Could not build an Arnoldi factorization. c Size that was built in returned in NP. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly c Restarted Arnoldi Iteration", Rice University Technical Report c TR95-13, Department of Computational and Applied Mathematics. c c\Routines called: c igraphdgetv0 ARPACK initial vector generation routine. c igraphdnaitr ARPACK Arnoldi factorization routine. c igraphdnapps ARPACK application of implicit shifts routine. c igraphdnconv ARPACK convergence of Ritz values routine. c igraphdneigh ARPACK compute Ritz values and error bounds routine. c igraphdngets ARPACK reorder Ritz values and error bounds routine. c igraphdsortc ARPACK sorting routine. c igraphivout ARPACK utility routine that prints integers. c igraphsecond ARPACK utility routine for timing. c igraphdmout ARPACK utility routine that prints matrices c igraphdvout ARPACK utility routine that prints vectors. c dlamch LAPACK routine that determines machine constants. c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully. c dcopy Level 1 BLAS that copies one vector to another . c ddot Level 1 BLAS that computes the scalar product of two vectors. c dnrm2 Level 1 BLAS that computes the norm of a vector. c dswap Level 1 BLAS that swaps two vectors. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\SCCS Information: @(#) c FILE: naup2.F SID: 2.4 DATE OF SID: 7/30/96 RELEASE: 2 c c\Remarks c 1. None c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdnaup2 & ( ido, bmat, n, which, nev, np, tol, resid, mode, iupd, & ishift, mxiter, v, ldv, h, ldh, ritzr, ritzi, bounds, & q, ldq, workl, ipntr, workd, info ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character bmat*1, which*2 integer ido, info, ishift, iupd, mode, ldh, ldq, ldv, mxiter, & n, nev, np Double precision & tol c c %-----------------% c | Array Arguments | c %-----------------% c integer ipntr(13) Double precision & bounds(nev+np), h(ldh,nev+np), q(ldq,nev+np), resid(n), & ritzi(nev+np), ritzr(nev+np), v(ldv,nev+np), & workd(3*n), workl( (nev+np)*(nev+np+3) ) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c character wprime*2 logical cnorm, getv0, initv, update, ushift integer ierr, iter, j, kplusp, msglvl, nconv, nevbef, nev0, & np0, nptemp, numcnv Double precision & rnorm, temp, eps23 c c %-----------------------% c | Local array arguments | c %-----------------------% c integer kp(4) save c c %----------------------% c | External Subroutines | c %----------------------% c external dcopy, igraphdgetv0, igraphdnaitr, igraphdnconv, & igraphdneigh, igraphdngets, igraphdnapps, & igraphdvout, igraphivout, igraphsecond c c %--------------------% c | External Functions | c %--------------------% c Double precision & ddot, dnrm2, dlapy2, dlamch external ddot, dnrm2, dlapy2, dlamch c c %---------------------% c | Intrinsic Functions | c %---------------------% c intrinsic min, max, abs, sqrt c c %-----------------------% c | Executable Statements | c %-----------------------% c if (ido .eq. 0) then c call igraphsecond (t0) c msglvl = mnaup2 c c %-------------------------------------% c | Get the machine dependent constant. | c %-------------------------------------% c eps23 = dlamch('Epsilon-Machine') eps23 = eps23**(2.0D+0 / 3.0D+0) c nev0 = nev np0 = np c c %-------------------------------------% c | kplusp is the bound on the largest | c | Lanczos factorization built. | c | nconv is the current number of | c | "converged" eigenvlues. | c | iter is the counter on the current | c | iteration step. | c %-------------------------------------% c kplusp = nev + np nconv = 0 iter = 0 c c %---------------------------------------% c | Set flags for computing the first NEV | c | steps of the Arnoldi factorization. | c %---------------------------------------% c getv0 = .true. update = .false. ushift = .false. cnorm = .false. c if (info .ne. 0) then c c %--------------------------------------------% c | User provides the initial residual vector. | c %--------------------------------------------% c initv = .true. info = 0 else initv = .false. end if end if c c %---------------------------------------------% c | Get a possibly random starting vector and | c | force it into the range of the operator OP. | c %---------------------------------------------% c 10 continue c if (getv0) then call igraphdgetv0 (ido, bmat, 1, initv, n, 1, v, ldv, resid, & rnorm, ipntr, workd, info) c if (ido .ne. 99) go to 9000 c if (rnorm .eq. zero) then c c %-----------------------------------------% c | The initial vector is zero. Error exit. | c %-----------------------------------------% c info = -9 go to 1100 end if getv0 = .false. ido = 0 end if c c %-----------------------------------% c | Back from reverse communication : | c | continue with update step | c %-----------------------------------% c if (update) go to 20 c c %-------------------------------------------% c | Back from computing user specified shifts | c %-------------------------------------------% c if (ushift) go to 50 c c %-------------------------------------% c | Back from computing residual norm | c | at the end of the current iteration | c %-------------------------------------% c if (cnorm) go to 100 c c %----------------------------------------------------------% c | Compute the first NEV steps of the Arnoldi factorization | c %----------------------------------------------------------% c call igraphdnaitr (ido, bmat, n, 0, nev, mode, resid, rnorm, v, & ldv, h, ldh, ipntr, workd, info) c c %---------------------------------------------------% c | ido .ne. 99 implies use of reverse communication | c | to compute operations involving OP and possibly B | c %---------------------------------------------------% c if (ido .ne. 99) go to 9000 c if (info .gt. 0) then np = info mxiter = iter info = -9999 go to 1200 end if c c %--------------------------------------------------------------% c | | c | M A I N ARNOLDI I T E R A T I O N L O O P | c | Each iteration implicitly restarts the Arnoldi | c | factorization in place. | c | | c %--------------------------------------------------------------% c 1000 continue c iter = iter + 1 c if (msglvl .gt. 0) then call igraphivout (logfil, 1, [iter], ndigit, & '_naup2: **** Start of major iteration number ****') end if c c %-----------------------------------------------------------% c | Compute NP additional steps of the Arnoldi factorization. | c | Adjust NP since NEV might have been updated by last call | c | to the shift application routine igraphdnapps. | c %-----------------------------------------------------------% c np = kplusp - nev c if (msglvl .gt. 1) then call igraphivout (logfil, 1, [nev], ndigit, & '_naup2: The length of the current Arnoldi factorization') call igraphivout (logfil, 1, [np], ndigit, & '_naup2: Extend the Arnoldi factorization by') end if c c %-----------------------------------------------------------% c | Compute NP additional steps of the Arnoldi factorization. | c %-----------------------------------------------------------% c ido = 0 20 continue update = .true. c call igraphdnaitr (ido, bmat, n, nev, np, mode, resid, rnorm, & v, ldv, h, ldh, ipntr, workd, info) c c %---------------------------------------------------% c | ido .ne. 99 implies use of reverse communication | c | to compute operations involving OP and possibly B | c %---------------------------------------------------% c if (ido .ne. 99) go to 9000 c if (info .gt. 0) then np = info mxiter = iter info = -9999 go to 1200 end if update = .false. c if (msglvl .gt. 1) then call igraphdvout (logfil, 1, [rnorm], ndigit, & '_naup2: Corresponding B-norm of the residual') end if c c %--------------------------------------------------------% c | Compute the eigenvalues and corresponding error bounds | c | of the current upper Hessenberg matrix. | c %--------------------------------------------------------% c call igraphdneigh (rnorm, kplusp, h, ldh, ritzr, ritzi, bounds, & q, ldq, workl, ierr) c if (ierr .ne. 0) then info = -8 go to 1200 end if c c %----------------------------------------------------% c | Make a copy of eigenvalues and corresponding error | c | bounds obtained from igraphdneigh. | c %----------------------------------------------------% c call dcopy(kplusp, ritzr, 1, workl(kplusp**2+1), 1) call dcopy(kplusp, ritzi, 1, workl(kplusp**2+kplusp+1), 1) call dcopy(kplusp, bounds, 1, workl(kplusp**2+2*kplusp+1), 1) c c %---------------------------------------------------% c | Select the wanted Ritz values and their bounds | c | to be used in the convergence test. | c | The wanted part of the spectrum and corresponding | c | error bounds are in the last NEV loc. of RITZR, | c | RITZI and BOUNDS respectively. The variables NEV | c | and NP may be updated if the NEV-th wanted Ritz | c | value has a non zero imaginary part. In this case | c | NEV is increased by one and NP decreased by one. | c | NOTE: The last two arguments of igraphdngets are no | c | longer used as of version 2.1. | c %---------------------------------------------------% c nev = nev0 np = np0 numcnv = nev call igraphdngets (ishift, which, nev, np, ritzr, ritzi, & bounds, workl, workl(np+1)) if (nev .eq. nev0+1) numcnv = nev0+1 c c %-------------------% c | Convergence test. | c %-------------------% c call dcopy (nev, bounds(np+1), 1, workl(2*np+1), 1) call igraphdnconv (nev, ritzr(np+1), ritzi(np+1), & workl(2*np+1), tol, nconv) c if (msglvl .gt. 2) then kp(1) = nev kp(2) = np kp(3) = numcnv kp(4) = nconv call igraphivout (logfil, 4, kp, ndigit, & '_naup2: NEV, NP, NUMCNV, NCONV are') call igraphdvout (logfil, kplusp, ritzr, ndigit, & '_naup2: Real part of the eigenvalues of H') call igraphdvout (logfil, kplusp, ritzi, ndigit, & '_naup2: Imaginary part of the eigenvalues of H') call igraphdvout (logfil, kplusp, bounds, ndigit, & '_naup2: Ritz estimates of the current NCV Ritz values') end if c c %---------------------------------------------------------% c | Count the number of unwanted Ritz values that have zero | c | Ritz estimates. If any Ritz estimates are equal to zero | c | then a leading block of H of order equal to at least | c | the number of Ritz values with zero Ritz estimates has | c | split off. None of these Ritz values may be removed by | c | shifting. Decrease NP the number of shifts to apply. If | c | no shifts may be applied, then prepare to exit | c %---------------------------------------------------------% c nptemp = np do 30 j=1, nptemp if (bounds(j) .eq. zero) then np = np - 1 nev = nev + 1 end if 30 continue c if ( (nconv .ge. numcnv) .or. & (iter .gt. mxiter) .or. & (np .eq. 0) ) then c if (msglvl .gt. 4) then call igraphdvout(logfil, kplusp, workl(kplusp**2+1), & ndigit, & '_naup2: Real part of the eig computed by _neigh:') call igraphdvout(logfil, kplusp, & workl(kplusp**2+kplusp+1), ndigit, & '_naup2: Imag part of the eig computed by _neigh:') call igraphdvout(logfil, kplusp, & workl(kplusp**2+kplusp*2+1), ndigit, & '_naup2: Ritz eistmates computed by _neigh:') end if c c %------------------------------------------------% c | Prepare to exit. Put the converged Ritz values | c | and corresponding bounds in RITZ(1:NCONV) and | c | BOUNDS(1:NCONV) respectively. Then sort. Be | c | careful when NCONV > NP | c %------------------------------------------------% c c %------------------------------------------% c | Use h( 3,1 ) as storage to communicate | c | rnorm to _neupd if needed | c %------------------------------------------% h(3,1) = rnorm c c %----------------------------------------------% c | To be consistent with igraphdngets, we first do a | c | pre-processing sort in order to keep complex | c | conjugate pairs together. This is similar | c | to the pre-processing sort used in igraphdngets | c | except that the sort is done in the opposite | c | order. | c %----------------------------------------------% c if (which .eq. 'LM') wprime = 'SR' if (which .eq. 'SM') wprime = 'LR' if (which .eq. 'LR') wprime = 'SM' if (which .eq. 'SR') wprime = 'LM' if (which .eq. 'LI') wprime = 'SM' if (which .eq. 'SI') wprime = 'LM' c call igraphdsortc (wprime, .true., kplusp, ritzr, ritzi, & bounds) c c %----------------------------------------------% c | Now sort Ritz values so that converged Ritz | c | values appear within the first NEV locations | c | of ritzr, ritzi and bounds, and the most | c | desired one appears at the front. | c %----------------------------------------------% c if (which .eq. 'LM') wprime = 'SM' if (which .eq. 'SM') wprime = 'LM' if (which .eq. 'LR') wprime = 'SR' if (which .eq. 'SR') wprime = 'LR' if (which .eq. 'LI') wprime = 'SI' if (which .eq. 'SI') wprime = 'LI' c call igraphdsortc(wprime, .true., kplusp, ritzr, ritzi, & bounds) c c %--------------------------------------------------% c | Scale the Ritz estimate of each Ritz value | c | by 1 / max(eps23,magnitude of the Ritz value). | c %--------------------------------------------------% c do 35 j = 1, nev0 temp = max(eps23,dlapy2(ritzr(j), & ritzi(j))) bounds(j) = bounds(j)/temp 35 continue c c %----------------------------------------------------% c | Sort the Ritz values according to the scaled Ritz | c | esitmates. This will push all the converged ones | c | towards the front of ritzr, ritzi, bounds | c | (in the case when NCONV < NEV.) | c %----------------------------------------------------% c wprime = 'LR' call igraphdsortc(wprime, .true., nev0, bounds, ritzr, & ritzi) c c %----------------------------------------------% c | Scale the Ritz estimate back to its original | c | value. | c %----------------------------------------------% c do 40 j = 1, nev0 temp = max(eps23, dlapy2(ritzr(j), & ritzi(j))) bounds(j) = bounds(j)*temp 40 continue c c %------------------------------------------------% c | Sort the converged Ritz values again so that | c | the "threshold" value appears at the front of | c | ritzr, ritzi and bound. | c %------------------------------------------------% c call igraphdsortc(which, .true., nconv, ritzr, ritzi, & bounds) c if (msglvl .gt. 1) then call igraphdvout (logfil, kplusp, ritzr, ndigit, & '_naup2: Sorted real part of the eigenvalues') call igraphdvout (logfil, kplusp, ritzi, ndigit, & '_naup2: Sorted imaginary part of the eigenvalues') call igraphdvout (logfil, kplusp, bounds, ndigit, & '_naup2: Sorted ritz estimates.') end if c c %------------------------------------% c | Max iterations have been exceeded. | c %------------------------------------% c if (iter .gt. mxiter .and. nconv .lt. numcnv) info = 1 c c %---------------------% c | No shifts to apply. | c %---------------------% c if (np .eq. 0 .and. nconv .lt. numcnv) info = 2 c np = nconv go to 1100 c else if ( (nconv .lt. numcnv) .and. (ishift .eq. 1) ) then c c %-------------------------------------------------% c | Do not have all the requested eigenvalues yet. | c | To prevent possible stagnation, adjust the size | c | of NEV. | c %-------------------------------------------------% c nevbef = nev nev = nev + min(nconv, np/2) if (nev .eq. 1 .and. kplusp .ge. 6) then nev = kplusp / 2 else if (nev .eq. 1 .and. kplusp .gt. 3) then nev = 2 end if np = kplusp - nev c c %---------------------------------------% c | If the size of NEV was just increased | c | resort the eigenvalues. | c %---------------------------------------% c if (nevbef .lt. nev) & call igraphdngets (ishift, which, nev, np, ritzr, ritzi, & bounds, workl, workl(np+1)) c end if c if (msglvl .gt. 0) then call igraphivout (logfil, 1, [nconv], ndigit, & '_naup2: no. of "converged" Ritz values at this iter.') if (msglvl .gt. 1) then kp(1) = nev kp(2) = np call igraphivout (logfil, 2, kp, ndigit, & '_naup2: NEV and NP are') call igraphdvout (logfil, nev, ritzr(np+1), ndigit, & '_naup2: "wanted" Ritz values -- real part') call igraphdvout (logfil, nev, ritzi(np+1), ndigit, & '_naup2: "wanted" Ritz values -- imag part') call igraphdvout (logfil, nev, bounds(np+1), ndigit, & '_naup2: Ritz estimates of the "wanted" values ') end if end if c if (ishift .eq. 0) then c c %-------------------------------------------------------% c | User specified shifts: reverse comminucation to | c | compute the shifts. They are returned in the first | c | 2*NP locations of WORKL. | c %-------------------------------------------------------% c ushift = .true. ido = 3 go to 9000 end if c 50 continue c c %------------------------------------% c | Back from reverse communication; | c | User specified shifts are returned | c | in WORKL(1:2*NP) | c %------------------------------------% c ushift = .false. c if ( ishift .eq. 0 ) then c c %----------------------------------% c | Move the NP shifts from WORKL to | c | RITZR, RITZI to free up WORKL | c | for non-exact shift case. | c %----------------------------------% c call dcopy (np, workl, 1, ritzr, 1) call dcopy (np, workl(np+1), 1, ritzi, 1) end if c if (msglvl .gt. 2) then call igraphivout (logfil, 1, [np], ndigit, & '_naup2: The number of shifts to apply ') call igraphdvout (logfil, np, ritzr, ndigit, & '_naup2: Real part of the shifts') call igraphdvout (logfil, np, ritzi, ndigit, & '_naup2: Imaginary part of the shifts') if ( ishift .eq. 1 ) & call igraphdvout (logfil, np, bounds, ndigit, & '_naup2: Ritz estimates of the shifts') end if c c %---------------------------------------------------------% c | Apply the NP implicit shifts by QR bulge chasing. | c | Each shift is applied to the whole upper Hessenberg | c | matrix H. | c | The first 2*N locations of WORKD are used as workspace. | c %---------------------------------------------------------% c call igraphdnapps (n, nev, np, ritzr, ritzi, v, ldv, & h, ldh, resid, q, ldq, workl, workd) c c %---------------------------------------------% c | Compute the B-norm of the updated residual. | c | Keep B*RESID in WORKD(1:N) to be used in | c | the first step of the next call to igraphdnaitr. | c %---------------------------------------------% c cnorm = .true. call igraphsecond (t2) if (bmat .eq. 'G') then nbx = nbx + 1 call dcopy (n, resid, 1, workd(n+1), 1) ipntr(1) = n + 1 ipntr(2) = 1 ido = 2 c c %----------------------------------% c | Exit in order to compute B*RESID | c %----------------------------------% c go to 9000 else if (bmat .eq. 'I') then call dcopy (n, resid, 1, workd, 1) end if c 100 continue c c %----------------------------------% c | Back from reverse communication; | c | WORKD(1:N) := B*RESID | c %----------------------------------% c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c if (bmat .eq. 'G') then rnorm = ddot (n, resid, 1, workd, 1) rnorm = sqrt(abs(rnorm)) else if (bmat .eq. 'I') then rnorm = dnrm2(n, resid, 1) end if cnorm = .false. c if (msglvl .gt. 2) then call igraphdvout (logfil, 1, [rnorm], ndigit, & '_naup2: B-norm of residual for compressed factorization') call igraphdmout (logfil, nev, nev, h, ldh, ndigit, & '_naup2: Compressed upper Hessenberg matrix H') end if c go to 1000 c c %---------------------------------------------------------------% c | | c | E N D O F M A I N I T E R A T I O N L O O P | c | | c %---------------------------------------------------------------% c 1100 continue c mxiter = iter nev = numcnv c 1200 continue ido = 99 c c %------------% c | Error Exit | c %------------% c call igraphsecond (t1) tnaup2 = t1 - t0 c 9000 continue c c %---------------% c | End of igraphdnaup2 | c %---------------% c return end leidenbase/src/vendor/arpack/dmout.f0000644000176200001440000001357514447675376017233 0ustar liggesusers*----------------------------------------------------------------------- * Routine: DMOUT * * Purpose: Real matrix output routine. * * Usage: CALL DMOUT (LOUT, M, N, A, LDA, IDIGIT, IFMT) * * Arguments * M - Number of rows of A. (Input) * N - Number of columns of A. (Input) * A - Real M by N matrix to be printed. (Input) * LDA - Leading dimension of A exactly as specified in the * dimension statement of the calling program. (Input) * IFMT - Format to be used in printing matrix A. (Input) * IDIGIT - Print up to IABS(IDIGIT) decimal digits per number. (In) * If IDIGIT .LT. 0, printing is done with 72 columns. * If IDIGIT .GT. 0, printing is done with 132 columns. * *----------------------------------------------------------------------- * SUBROUTINE IGRAPHDMOUT( LOUT, M, N, A, LDA, IDIGIT, IFMT ) * ... * ... SPECIFICATIONS FOR ARGUMENTS * ... * ... SPECIFICATIONS FOR LOCAL VARIABLES * .. Scalar Arguments .. CHARACTER*( * ) IFMT INTEGER IDIGIT, LDA, LOUT, M, N * .. * .. Array Arguments .. DOUBLE PRECISION A( LDA, * ) * .. * .. Local Scalars .. CHARACTER*80 LINE INTEGER I, J, K1, K2, LLL, NDIGIT * .. * .. Local Arrays .. CHARACTER ICOL( 3 ) * .. * .. Intrinsic Functions .. INTRINSIC LEN, MIN, MIN0 * .. * .. Data statements .. DATA ICOL( 1 ), ICOL( 2 ), ICOL( 3 ) / 'C', 'o', $ 'l' / * .. * .. Executable Statements .. * ... * ... FIRST EXECUTABLE STATEMENT * c$$$ LLL = MIN( LEN( IFMT ), 80 ) c$$$ DO 10 I = 1, LLL c$$$ LINE( I: I ) = '-' c$$$ 10 CONTINUE c$$$* c$$$ DO 20 I = LLL + 1, 80 c$$$ LINE( I: I ) = ' ' c$$$ 20 CONTINUE c$$$* c$$$ WRITE( LOUT, FMT = 9999 )IFMT, LINE( 1: LLL ) c$$$ 9999 FORMAT( / 1X, A, / 1X, A ) c$$$* c$$$ IF( M.LE.0 .OR. N.LE.0 .OR. LDA.LE.0 ) c$$$ $ RETURN c$$$ NDIGIT = IDIGIT c$$$ IF( IDIGIT.EQ.0 ) c$$$ $ NDIGIT = 4 c$$$* c$$$*======================================================================= c$$$* CODE FOR OUTPUT USING 72 COLUMNS FORMAT c$$$*======================================================================= c$$$* c$$$ IF( IDIGIT.LT.0 ) THEN c$$$ NDIGIT = -IDIGIT c$$$ IF( NDIGIT.LE.4 ) THEN c$$$ DO 40 K1 = 1, N, 5 c$$$ K2 = MIN0( N, K1+4 ) c$$$ WRITE( LOUT, FMT = 9998 )( ICOL, I, I = K1, K2 ) c$$$ DO 30 I = 1, M c$$$ WRITE( LOUT, FMT = 9994 )I, ( A( I, J ), J = K1, K2 ) c$$$ 30 CONTINUE c$$$ 40 CONTINUE c$$$* c$$$ ELSE IF( NDIGIT.LE.6 ) THEN c$$$ DO 60 K1 = 1, N, 4 c$$$ K2 = MIN0( N, K1+3 ) c$$$ WRITE( LOUT, FMT = 9997 )( ICOL, I, I = K1, K2 ) c$$$ DO 50 I = 1, M c$$$ WRITE( LOUT, FMT = 9993 )I, ( A( I, J ), J = K1, K2 ) c$$$ 50 CONTINUE c$$$ 60 CONTINUE c$$$* c$$$ ELSE IF( NDIGIT.LE.10 ) THEN c$$$ DO 80 K1 = 1, N, 3 c$$$ K2 = MIN0( N, K1+2 ) c$$$ WRITE( LOUT, FMT = 9996 )( ICOL, I, I = K1, K2 ) c$$$ DO 70 I = 1, M c$$$ WRITE( LOUT, FMT = 9992 )I, ( A( I, J ), J = K1, K2 ) c$$$ 70 CONTINUE c$$$ 80 CONTINUE c$$$* c$$$ ELSE c$$$ DO 100 K1 = 1, N, 2 c$$$ K2 = MIN0( N, K1+1 ) c$$$ WRITE( LOUT, FMT = 9995 )( ICOL, I, I = K1, K2 ) c$$$ DO 90 I = 1, M c$$$ WRITE( LOUT, FMT = 9991 )I, ( A( I, J ), J = K1, K2 ) c$$$ 90 CONTINUE c$$$ 100 CONTINUE c$$$ END IF c$$$* c$$$*======================================================================= c$$$* CODE FOR OUTPUT USING 132 COLUMNS FORMAT c$$$*======================================================================= c$$$* c$$$ ELSE c$$$ IF( NDIGIT.LE.4 ) THEN c$$$ DO 120 K1 = 1, N, 10 c$$$ K2 = MIN0( N, K1+9 ) c$$$ WRITE( LOUT, FMT = 9998 )( ICOL, I, I = K1, K2 ) c$$$ DO 110 I = 1, M c$$$ WRITE( LOUT, FMT = 9994 )I, ( A( I, J ), J = K1, K2 ) c$$$ 110 CONTINUE c$$$ 120 CONTINUE c$$$* c$$$ ELSE IF( NDIGIT.LE.6 ) THEN c$$$ DO 140 K1 = 1, N, 8 c$$$ K2 = MIN0( N, K1+7 ) c$$$ WRITE( LOUT, FMT = 9997 )( ICOL, I, I = K1, K2 ) c$$$ DO 130 I = 1, M c$$$ WRITE( LOUT, FMT = 9993 )I, ( A( I, J ), J = K1, K2 ) c$$$ 130 CONTINUE c$$$ 140 CONTINUE c$$$* c$$$ ELSE IF( NDIGIT.LE.10 ) THEN c$$$ DO 160 K1 = 1, N, 6 c$$$ K2 = MIN0( N, K1+5 ) c$$$ WRITE( LOUT, FMT = 9996 )( ICOL, I, I = K1, K2 ) c$$$ DO 150 I = 1, M c$$$ WRITE( LOUT, FMT = 9992 )I, ( A( I, J ), J = K1, K2 ) c$$$ 150 CONTINUE c$$$ 160 CONTINUE c$$$* c$$$ ELSE c$$$ DO 180 K1 = 1, N, 5 c$$$ K2 = MIN0( N, K1+4 ) c$$$ WRITE( LOUT, FMT = 9995 )( ICOL, I, I = K1, K2 ) c$$$ DO 170 I = 1, M c$$$ WRITE( LOUT, FMT = 9991 )I, ( A( I, J ), J = K1, K2 ) c$$$ 170 CONTINUE c$$$ 180 CONTINUE c$$$ END IF c$$$ END IF c$$$ WRITE( LOUT, FMT = 9990 ) c$$$* c$$$ 9998 FORMAT( 10X, 10( 4X, 3A1, I4, 1X ) ) c$$$ 9997 FORMAT( 10X, 8( 5X, 3A1, I4, 2X ) ) c$$$ 9996 FORMAT( 10X, 6( 7X, 3A1, I4, 4X ) ) c$$$ 9995 FORMAT( 10X, 5( 9X, 3A1, I4, 6X ) ) c$$$ 9994 FORMAT( 1X, ' Row', I4, ':', 1X, 1P, 10D12.3 ) c$$$ 9993 FORMAT( 1X, ' Row', I4, ':', 1X, 1P, 8D14.5 ) c$$$ 9992 FORMAT( 1X, ' Row', I4, ':', 1X, 1P, 6D18.9 ) c$$$ 9991 FORMAT( 1X, ' Row', I4, ':', 1X, 1P, 5D22.13 ) c$$$ 9990 FORMAT( 1X, ' ' ) * RETURN END leidenbase/src/vendor/arpack/second.f0000644000176200001440000000113714447675376017345 0ustar liggesusers SUBROUTINE IGRAPHSECOND( T ) * REAL T * * -- LAPACK auxiliary routine (preliminary version) -- * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., * Courant Institute, Argonne National Lab, and Rice University * July 26, 1991 * * Purpose * ======= * * SECOND returns the user time for a process in igraphseconds. * This version was changed in igraph to always return zero, since * we do not need the timings. The original version used the * non-standard ETIME, which is unsupported by flang. * T = 0.0e+0 RETURN * * End of SECOND * END leidenbase/src/vendor/arpack/dstqrb.f0000644000176200001440000004065414447675376017400 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdstqrb c c\Description: c Computes all eigenvalues and the last component of the eigenvectors c of a symmetric tridiagonal matrix using the implicit QL or QR method. c c This is mostly a modification of the LAPACK routine dsteqr. c See Remarks. c c\Usage: c call igraphdstqrb c ( N, D, E, Z, WORK, INFO ) c c\Arguments c N Integer. (INPUT) c The number of rows and columns in the matrix. N >= 0. c c D Double precision array, dimension (N). (INPUT/OUTPUT) c On entry, D contains the diagonal elements of the c tridiagonal matrix. c On exit, D contains the eigenvalues, in ascending order. c If an error exit is made, the eigenvalues are correct c for indices 1,2,...,INFO-1, but they are unordered and c may not be the smallest eigenvalues of the matrix. c c E Double precision array, dimension (N-1). (INPUT/OUTPUT) c On entry, E contains the subdiagonal elements of the c tridiagonal matrix in positions 1 through N-1. c On exit, E has been destroyed. c c Z Double precision array, dimension (N). (OUTPUT) c On exit, Z contains the last row of the orthonormal c eigenvector matrix of the symmetric tridiagonal matrix. c If an error exit is made, Z contains the last row of the c eigenvector matrix associated with the stored eigenvalues. c c WORK Double precision array, dimension (max(1,2*N-2)). (WORKSPACE) c Workspace used in accumulating the transformation for c computing the last components of the eigenvectors. c c INFO Integer. (OUTPUT) c = 0: normal return. c < 0: if INFO = -i, the i-th argument had an illegal value. c > 0: if INFO = +i, the i-th eigenvalue has not converged c after a total of 30*N iterations. c c\Remarks c 1. None. c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\Routines called: c daxpy Level 1 BLAS that computes a vector triad. c dcopy Level 1 BLAS that copies one vector to another. c dswap Level 1 BLAS that swaps the contents of two vectors. c lsame LAPACK character comparison routine. c dlae2 LAPACK routine that computes the eigenvalues of a 2-by-2 c symmetric matrix. c dlaev2 LAPACK routine that eigendecomposition of a 2-by-2 symmetric c matrix. c dlamch LAPACK routine that determines machine constants. c dlanst LAPACK routine that computes the norm of a matrix. c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully. c dlartg LAPACK Givens rotation construction routine. c dlascl LAPACK routine for careful scaling of a matrix. c dlaset LAPACK matrix initialization routine. c dlasr LAPACK routine that applies an orthogonal transformation to c a matrix. c dlasrt LAPACK sorting routine. c dsteqr LAPACK routine that computes eigenvalues and eigenvectors c of a symmetric tridiagonal matrix. c xerbla LAPACK error handler routine. c c\Authors c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\SCCS Information: @(#) c FILE: stqrb.F SID: 2.5 DATE OF SID: 8/27/96 RELEASE: 2 c c\Remarks c 1. Starting with version 2.5, this routine is a modified version c of LAPACK version 2.0 subroutine SSTEQR. No lines are deleted, c only commeted out and new lines inserted. c All lines commented out have "c$$$" at the beginning. c Note that the LAPACK version 1.0 subroutine SSTEQR contained c bugs. c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdstqrb ( n, d, e, z, work, info ) c c %------------------% c | Scalar Arguments | c %------------------% c integer info, n c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & d( n ), e( n-1 ), z( n ), work( 2*n-2 ) c c .. parameters .. Double precision & zero, one, two, three parameter ( zero = 0.0D+0, one = 1.0D+0, & two = 2.0D+0, three = 3.0D+0 ) integer maxit parameter ( maxit = 30 ) c .. c .. local scalars .. integer i, icompz, ii, iscale, j, jtot, k, l, l1, lend, & lendm1, lendp1, lendsv, lm1, lsv, m, mm, mm1, & nm1, nmaxit Double precision & anorm, b, c, eps, eps2, f, g, p, r, rt1, rt2, & s, safmax, safmin, ssfmax, ssfmin, tst c .. c .. external functions .. logical lsame Double precision & dlamch, dlanst, dlapy2 external lsame, dlamch, dlanst, dlapy2 c .. c .. external subroutines .. external dlae2, dlaev2, dlartg, dlascl, dlaset, dlasr, & dlasrt, dswap, xerbla c .. c .. intrinsic functions .. intrinsic abs, max, sign, sqrt c .. c .. executable statements .. c c test the input parameters. c info = 0 c c$$$ IF( LSAME( COMPZ, 'N' ) ) THEN c$$$ ICOMPZ = 0 c$$$ ELSE IF( LSAME( COMPZ, 'V' ) ) THEN c$$$ ICOMPZ = 1 c$$$ ELSE IF( LSAME( COMPZ, 'I' ) ) THEN c$$$ ICOMPZ = 2 c$$$ ELSE c$$$ ICOMPZ = -1 c$$$ END IF c$$$ IF( ICOMPZ.LT.0 ) THEN c$$$ INFO = -1 c$$$ ELSE IF( N.LT.0 ) THEN c$$$ INFO = -2 c$$$ ELSE IF( ( LDZ.LT.1 ) .OR. ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1, c$$$ $ N ) ) ) THEN c$$$ INFO = -6 c$$$ END IF c$$$ IF( INFO.NE.0 ) THEN c$$$ CALL XERBLA( 'SSTEQR', -INFO ) c$$$ RETURN c$$$ END IF c c *** New starting with version 2.5 *** c icompz = 2 c ************************************* c c quick return if possible c if( n.eq.0 ) $ return c if( n.eq.1 ) then if( icompz.eq.2 ) z( 1 ) = one return end if c c determine the unit roundoff and over/underflow thresholds. c eps = dlamch( 'e' ) eps2 = eps**2 safmin = dlamch( 's' ) safmax = one / safmin ssfmax = sqrt( safmax ) / three ssfmin = sqrt( safmin ) / eps2 c c compute the eigenvalues and eigenvectors of the tridiagonal c matrix. c c$$ if( icompz.eq.2 ) c$$$ $ call dlaset( 'full', n, n, zero, one, z, ldz ) c c *** New starting with version 2.5 *** c if ( icompz .eq. 2 ) then do 5 j = 1, n-1 z(j) = zero 5 continue z( n ) = one end if c ************************************* c nmaxit = n*maxit jtot = 0 c c determine where the matrix splits and choose ql or qr iteration c for each block, according to whether top or bottom diagonal c element is smaller. c l1 = 1 nm1 = n - 1 c 10 continue if( l1.gt.n ) $ go to 160 if( l1.gt.1 ) $ e( l1-1 ) = zero if( l1.le.nm1 ) then do 20 m = l1, nm1 tst = abs( e( m ) ) if( tst.eq.zero ) $ go to 30 if( tst.le.( sqrt( abs( d( m ) ) )*sqrt( abs( d( m+ $ 1 ) ) ) )*eps ) then e( m ) = zero go to 30 end if 20 continue end if m = n c 30 continue l = l1 lsv = l lend = m lendsv = lend l1 = m + 1 if( lend.eq.l ) $ go to 10 c c scale submatrix in rows and columns l to lend c anorm = dlanst( 'i', lend-l+1, d( l ), e( l ) ) iscale = 0 if( anorm.eq.zero ) $ go to 10 if( anorm.gt.ssfmax ) then iscale = 1 call dlascl( 'g', 0, 0, anorm, ssfmax, lend-l+1, 1, d( l ), n, $ info ) call dlascl( 'g', 0, 0, anorm, ssfmax, lend-l, 1, e( l ), n, $ info ) else if( anorm.lt.ssfmin ) then iscale = 2 call dlascl( 'g', 0, 0, anorm, ssfmin, lend-l+1, 1, d( l ), n, $ info ) call dlascl( 'g', 0, 0, anorm, ssfmin, lend-l, 1, e( l ), n, $ info ) end if c c choose between ql and qr iteration c if( abs( d( lend ) ).lt.abs( d( l ) ) ) then lend = lsv l = lendsv end if c if( lend.gt.l ) then c c ql iteration c c look for small subdiagonal element. c 40 continue if( l.ne.lend ) then lendm1 = lend - 1 do 50 m = l, lendm1 tst = abs( e( m ) )**2 if( tst.le.( eps2*abs( d( m ) ) )*abs( d( m+1 ) )+ $ safmin )go to 60 50 continue end if c m = lend c 60 continue if( m.lt.lend ) $ e( m ) = zero p = d( l ) if( m.eq.l ) $ go to 80 c c if remaining matrix is 2-by-2, use dlae2 or dlaev2 c to compute its eigensystem. c if( m.eq.l+1 ) then if( icompz.gt.0 ) then call dlaev2( d( l ), e( l ), d( l+1 ), rt1, rt2, c, s ) work( l ) = c work( n-1+l ) = s c$$$ call dlasr( 'r', 'v', 'b', n, 2, work( l ), c$$$ $ work( n-1+l ), z( 1, l ), ldz ) c c *** New starting with version 2.5 *** c tst = z(l+1) z(l+1) = c*tst - s*z(l) z(l) = s*tst + c*z(l) c ************************************* else call dlae2( d( l ), e( l ), d( l+1 ), rt1, rt2 ) end if d( l ) = rt1 d( l+1 ) = rt2 e( l ) = zero l = l + 2 if( l.le.lend ) $ go to 40 go to 140 end if c if( jtot.eq.nmaxit ) $ go to 140 jtot = jtot + 1 c c form shift. c g = ( d( l+1 )-p ) / ( two*e( l ) ) r = dlapy2( g, one ) g = d( m ) - p + ( e( l ) / ( g+sign( r, g ) ) ) c s = one c = one p = zero c c inner loop c mm1 = m - 1 do 70 i = mm1, l, -1 f = s*e( i ) b = c*e( i ) call dlartg( g, f, c, s, r ) if( i.ne.m-1 ) $ e( i+1 ) = r g = d( i+1 ) - p r = ( d( i )-g )*s + two*c*b p = s*r d( i+1 ) = g + p g = c*r - b c c if eigenvectors are desired, then save rotations. c if( icompz.gt.0 ) then work( i ) = c work( n-1+i ) = -s end if c 70 continue c c if eigenvectors are desired, then apply saved rotations. c if( icompz.gt.0 ) then mm = m - l + 1 c$$$ call dlasr( 'r', 'v', 'b', n, mm, work( l ), work( n-1+l ), c$$$ $ z( 1, l ), ldz ) c c *** New starting with version 2.5 *** c call dlasr( 'r', 'v', 'b', 1, mm, work( l ), & work( n-1+l ), z( l ), 1 ) c ************************************* end if c d( l ) = d( l ) - p e( l ) = g go to 40 c c eigenvalue found. c 80 continue d( l ) = p c l = l + 1 if( l.le.lend ) $ go to 40 go to 140 c else c c qr iteration c c look for small superdiagonal element. c 90 continue if( l.ne.lend ) then lendp1 = lend + 1 do 100 m = l, lendp1, -1 tst = abs( e( m-1 ) )**2 if( tst.le.( eps2*abs( d( m ) ) )*abs( d( m-1 ) )+ $ safmin )go to 110 100 continue end if c m = lend c 110 continue if( m.gt.lend ) $ e( m-1 ) = zero p = d( l ) if( m.eq.l ) $ go to 130 c c if remaining matrix is 2-by-2, use dlae2 or dlaev2 c to compute its eigensystem. c if( m.eq.l-1 ) then if( icompz.gt.0 ) then call dlaev2( d( l-1 ), e( l-1 ), d( l ), rt1, rt2, c, s ) c$$$ work( m ) = c c$$$ work( n-1+m ) = s c$$$ call dlasr( 'r', 'v', 'f', n, 2, work( m ), c$$$ $ work( n-1+m ), z( 1, l-1 ), ldz ) c c *** New starting with version 2.5 *** c tst = z(l) z(l) = c*tst - s*z(l-1) z(l-1) = s*tst + c*z(l-1) c ************************************* else call dlae2( d( l-1 ), e( l-1 ), d( l ), rt1, rt2 ) end if d( l-1 ) = rt1 d( l ) = rt2 e( l-1 ) = zero l = l - 2 if( l.ge.lend ) $ go to 90 go to 140 end if c if( jtot.eq.nmaxit ) $ go to 140 jtot = jtot + 1 c c form shift. c g = ( d( l-1 )-p ) / ( two*e( l-1 ) ) r = dlapy2( g, one ) g = d( m ) - p + ( e( l-1 ) / ( g+sign( r, g ) ) ) c s = one c = one p = zero c c inner loop c lm1 = l - 1 do 120 i = m, lm1 f = s*e( i ) b = c*e( i ) call dlartg( g, f, c, s, r ) if( i.ne.m ) $ e( i-1 ) = r g = d( i ) - p r = ( d( i+1 )-g )*s + two*c*b p = s*r d( i ) = g + p g = c*r - b c c if eigenvectors are desired, then save rotations. c if( icompz.gt.0 ) then work( i ) = c work( n-1+i ) = s end if c 120 continue c c if eigenvectors are desired, then apply saved rotations. c if( icompz.gt.0 ) then mm = l - m + 1 c$$$ call dlasr( 'r', 'v', 'f', n, mm, work( m ), work( n-1+m ), c$$$ $ z( 1, m ), ldz ) c c *** New starting with version 2.5 *** c call dlasr( 'r', 'v', 'f', 1, mm, work( m ), work( n-1+m ), & z( m ), 1 ) c ************************************* end if c d( l ) = d( l ) - p e( lm1 ) = g go to 90 c c eigenvalue found. c 130 continue d( l ) = p c l = l - 1 if( l.ge.lend ) $ go to 90 go to 140 c end if c c undo scaling if necessary c 140 continue if( iscale.eq.1 ) then call dlascl( 'g', 0, 0, ssfmax, anorm, lendsv-lsv+1, 1, $ d( lsv ), n, info ) call dlascl( 'g', 0, 0, ssfmax, anorm, lendsv-lsv, 1, e( lsv ), $ n, info ) else if( iscale.eq.2 ) then call dlascl( 'g', 0, 0, ssfmin, anorm, lendsv-lsv+1, 1, $ d( lsv ), n, info ) call dlascl( 'g', 0, 0, ssfmin, anorm, lendsv-lsv, 1, e( lsv ), $ n, info ) end if c c check for no convergence to an eigenvalue after a total c of n*maxit iterations. c if( jtot.lt.nmaxit ) $ go to 10 do 150 i = 1, n - 1 if( e( i ).ne.zero ) $ info = info + 1 150 continue go to 190 c c order eigenvalues and eigenvectors. c 160 continue if( icompz.eq.0 ) then c c use quick sort c call dlasrt( 'i', n, d, info ) c else c c use selection sort to minimize swaps of eigenvectors c do 180 ii = 2, n i = ii - 1 k = i p = d( i ) do 170 j = ii, n if( d( j ).lt.p ) then k = j p = d( j ) end if 170 continue if( k.ne.i ) then d( k ) = d( i ) d( i ) = p c$$$ call dswap( n, z( 1, i ), 1, z( 1, k ), 1 ) c *** New starting with version 2.5 *** c p = z(k) z(k) = z(i) z(i) = p c ************************************* end if 180 continue end if c 190 continue return c c %---------------% c | End of igraphdstqrb | c %---------------% c end leidenbase/src/vendor/arpack/dseigt.f0000644000176200001440000001227114447675376017352 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdseigt c c\Description: c Compute the eigenvalues of the current symmetric tridiagonal matrix c and the corresponding error bounds given the current residual norm. c c\Usage: c call igraphdseigt c ( RNORM, N, H, LDH, EIG, BOUNDS, WORKL, IERR ) c c\Arguments c RNORM Double precision scalar. (INPUT) c RNORM contains the residual norm corresponding to the current c symmetric tridiagonal matrix H. c c N Integer. (INPUT) c Size of the symmetric tridiagonal matrix H. c c H Double precision N by 2 array. (INPUT) c H contains the symmetric tridiagonal matrix with the c subdiagonal in the first column starting at H(2,1) and the c main diagonal in igraphsecond column. c c LDH Integer. (INPUT) c Leading dimension of H exactly as declared in the calling c program. c c EIG Double precision array of length N. (OUTPUT) c On output, EIG contains the N eigenvalues of H possibly c unsorted. The BOUNDS arrays are returned in the c same sorted order as EIG. c c BOUNDS Double precision array of length N. (OUTPUT) c On output, BOUNDS contains the error estimates corresponding c to the eigenvalues EIG. This is equal to RNORM times the c last components of the eigenvectors corresponding to the c eigenvalues in EIG. c c WORKL Double precision work array of length 3*N. (WORKSPACE) c Private (replicated) array on each PE or array allocated on c the front end. c c IERR Integer. (OUTPUT) c Error exit flag from igraphdstqrb. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\Routines called: c igraphdstqrb ARPACK routine that computes the eigenvalues and the c last components of the eigenvectors of a symmetric c and tridiagonal matrix. c igraphsecond ARPACK utility routine for timing. c igraphdvout ARPACK utility routine that prints vectors. c dcopy Level 1 BLAS that copies one vector to another. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/92: Version ' 2.4' c c\SCCS Information: @(#) c FILE: seigt.F SID: 2.4 DATE OF SID: 8/27/96 RELEASE: 2 c c\Remarks c None c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdseigt & ( rnorm, n, h, ldh, eig, bounds, workl, ierr ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c integer ierr, ldh, n Double precision & rnorm c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & eig(n), bounds(n), h(ldh,2), workl(3*n) c c %------------% c | Parameters | c %------------% c Double precision & zero parameter (zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c integer i, k, msglvl c c %----------------------% c | External Subroutines | c %----------------------% c external dcopy, igraphdstqrb, igraphdvout, igraphsecond c c %-----------------------% c | Executable Statements | c %-----------------------% c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = mseigt c if (msglvl .gt. 0) then call igraphdvout (logfil, n, h(1,2), ndigit, & '_seigt: main diagonal of matrix H') if (n .gt. 1) then call igraphdvout (logfil, n-1, h(2,1), ndigit, & '_seigt: sub diagonal of matrix H') end if end if c call dcopy (n, h(1,2), 1, eig, 1) call dcopy (n-1, h(2,1), 1, workl, 1) call igraphdstqrb (n, eig, workl, bounds, workl(n+1), ierr) if (ierr .ne. 0) go to 9000 if (msglvl .gt. 1) then call igraphdvout (logfil, n, bounds, ndigit, & '_seigt: last row of the eigenvector matrix for H') end if c c %-----------------------------------------------% c | Finally determine the error bounds associated | c | with the n Ritz values of H. | c %-----------------------------------------------% c do 30 k = 1, n bounds(k) = rnorm*abs(bounds(k)) 30 continue c call igraphsecond (t1) tseigt = tseigt + (t1 - t0) c 9000 continue return c c %---------------% c | End of igraphdseigt | c %---------------% c end leidenbase/src/vendor/arpack/wrap.f0000644000176200001440000000735114447675376017047 0ustar liggesusersc----------------------------------------------------------------------- c Wrapper functions, so we don't need to pass logicals from c C to Fortran, because that generates LTO warnings, as the compiler c apparently cannot match a Fortran logical to a C type. c----------------------------------------------------------------------- c subroutine igraphxdsortr (which, apply, n, x1, x2) c character*2 which integer apply integer n Double precision & x1(0:n-1), x2(0:n-1) c logical applyx c if (apply .eq. 1) then applyx = .true. else applyx = .false. end if c call igraphdsortr(which, applyx, n, x1, x2) c return c end c c----------------------------------------------------------------------- c subroutine igraphxdsortc (which, apply, n, xreal, ximag, y) c character*2 which integer apply integer n c Double precision & xreal(0:n-1), ximag(0:n-1), y(0:n-1) c logical applyx c if (apply .eq. 1) then applyx = .true. else applyx = .false. end if c call igraphdsortc(which, applyx, n, xreal, ximag, y) c return c end c c----------------------------------------------------------------------- c subroutine igraphxdneupd (rvec, howmny, select, dr, di, z, ldz, & sigmar, sigmai, workev, bmat, n, which, nev, tol, & resid, ncv, v, ldv, iparam, ipntr, workd, & workl, lworkl, info) c character bmat, howmny, which*2 integer rvec integer info, ldz, ldv, lworkl, n, ncv, nev Double precision & sigmar, sigmai, tol c integer iparam(11), ipntr(14) integer select(ncv) Double precision & dr(nev+1), di(nev+1), resid(n), v(ldv,ncv), z(ldz,*), & workd(3*n), workl(lworkl), workev(3*ncv) c logical rvecx integer i logical selectx(ncv) c if (rvec .eq. 1) then rvecx = .true. else rvecx = .false. end if c i = 1 100 if (i .gt. ncv) then go to 110 end if if (select(i) .eq. 1) then selectx(i) = .true. else selectx(i) = .false. end if i = i + 1 go to 100 110 continue c call igraphdneupd(rvecx, howmny, selectx, dr, di, z, ldz, & sigmar, sigmai, workev, bmat, n, which, nev, tol, & resid, ncv, v, ldv, iparam, ipntr, workd, & workl, lworkl, info) c return c end c c----------------------------------------------------------------------- c subroutine igraphxdseupd (rvec, howmny, select, d, z, ldz, & sigma, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, & ipntr, workd, workl, lworkl, info ) c character bmat, howmny, which*2 integer rvec, select(ncv) integer info, ldz, ldv, lworkl, n, ncv, nev Double precision & sigma, tol c integer iparam(7), ipntr(11) Double precision & d(nev), resid(n), v(ldv,ncv), z(ldz, nev), & workd(2*n), workl(lworkl) c logical rvecx integer i logical selectx(ncv) c if (rvec .eq. 1) then rvecx = .true. else rvecx = .false. end if c i = 1 100 if (i .gt. ncv) then go to 110 end if if (select(i) .eq. 1) then selectx(i) = .true. else selectx(i) = .false. end if i = i + 1 go to 100 110 continue c call igraphdseupd(rvecx, howmny, selectx, d, z, ldz, & sigma, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, & ipntr, workd, workl, lworkl, info ) c return c end leidenbase/src/vendor/arpack/dsgets.f0000644000176200001440000001664114447675376017371 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdsgets c c\Description: c Given the eigenvalues of the symmetric tridiagonal matrix H, c computes the NP shifts AMU that are zeros of the polynomial of c degree NP which filters out components of the unwanted eigenvectors c corresponding to the AMU's based on some given criteria. c c NOTE: This is called even in the case of user specified shifts in c order to sort the eigenvalues, and error bounds of H for later use. c c\Usage: c call igraphdsgets c ( ISHIFT, WHICH, KEV, NP, RITZ, BOUNDS, SHIFTS ) c c\Arguments c ISHIFT Integer. (INPUT) c Method for selecting the implicit shifts at each iteration. c ISHIFT = 0: user specified shifts c ISHIFT = 1: exact shift with respect to the matrix H. c c WHICH Character*2. (INPUT) c Shift selection criteria. c 'LM' -> KEV eigenvalues of largest magnitude are retained. c 'SM' -> KEV eigenvalues of smallest magnitude are retained. c 'LA' -> KEV eigenvalues of largest value are retained. c 'SA' -> KEV eigenvalues of smallest value are retained. c 'BE' -> KEV eigenvalues, half from each end of the spectrum. c If KEV is odd, compute one more from the high end. c c KEV Integer. (INPUT) c KEV+NP is the size of the matrix H. c c NP Integer. (INPUT) c Number of implicit shifts to be computed. c c RITZ Double precision array of length KEV+NP. (INPUT/OUTPUT) c On INPUT, RITZ contains the eigenvalues of H. c On OUTPUT, RITZ are sorted so that the unwanted eigenvalues c are in the first NP locations and the wanted part is in c the last KEV locations. When exact shifts are selected, the c unwanted part corresponds to the shifts to be applied. c c BOUNDS Double precision array of length KEV+NP. (INPUT/OUTPUT) c Error bounds corresponding to the ordering in RITZ. c c SHIFTS Double precision array of length NP. (INPUT/OUTPUT) c On INPUT: contains the user specified shifts if ISHIFT = 0. c On OUTPUT: contains the shifts sorted into decreasing order c of magnitude with respect to the Ritz estimates contained in c BOUNDS. If ISHIFT = 0, SHIFTS is not modified on exit. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\Routines called: c igraphdsortr ARPACK utility sorting routine. c igraphivout ARPACK utility routine that prints integers. c igraphsecond ARPACK utility routine for timing. c igraphdvout ARPACK utility routine that prints vectors. c dcopy Level 1 BLAS that copies one vector to another. c dswap Level 1 BLAS that swaps the contents of two vectors. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/93: Version ' 2.1' c c\SCCS Information: @(#) c FILE: sgets.F SID: 2.4 DATE OF SID: 4/19/96 RELEASE: 2 c c\Remarks c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdsgets ( ishift, which, kev, np, ritz, bounds, & shifts ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character*2 which integer ishift, kev, np c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & bounds(kev+np), ritz(kev+np), shifts(np) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c integer kevd2, msglvl c c %----------------------% c | External Subroutines | c %----------------------% c external dswap, dcopy, igraphdsortr, igraphsecond c c %---------------------% c | Intrinsic Functions | c %---------------------% c intrinsic max, min c c %-----------------------% c | Executable Statements | c %-----------------------% c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = msgets c if (which .eq. 'BE') then c c %-----------------------------------------------------% c | Both ends of the spectrum are requested. | c | Sort the eigenvalues into algebraically increasing | c | order first then swap high end of the spectrum next | c | to low end in appropriate locations. | c | NOTE: when np < floor(kev/2) be careful not to swap | c | overlapping locations. | c %-----------------------------------------------------% c call igraphdsortr ('LA', .true., kev+np, ritz, bounds) kevd2 = kev / 2 if ( kev .gt. 1 ) then call dswap ( min(kevd2,np), ritz, 1, & ritz( max(kevd2,np)+1 ), 1) call dswap ( min(kevd2,np), bounds, 1, & bounds( max(kevd2,np)+1 ), 1) end if c else c c %----------------------------------------------------% c | LM, SM, LA, SA case. | c | Sort the eigenvalues of H into the desired order | c | and apply the resulting order to BOUNDS. | c | The eigenvalues are sorted so that the wanted part | c | are always in the last KEV locations. | c %----------------------------------------------------% c call igraphdsortr (which, .true., kev+np, ritz, bounds) end if c if (ishift .eq. 1 .and. np .gt. 0) then c c %-------------------------------------------------------% c | Sort the unwanted Ritz values used as shifts so that | c | the ones with largest Ritz estimates are first. | c | This will tend to minimize the effects of the | c | forward instability of the iteration when the shifts | c | are applied in subroutine igraphdsapps. | c %-------------------------------------------------------% c call igraphdsortr ('SM', .true., np, bounds, ritz) call dcopy (np, ritz, 1, shifts, 1) end if c call igraphsecond (t1) tsgets = tsgets + (t1 - t0) c if (msglvl .gt. 0) then call igraphivout (logfil, 1, kev, ndigit, '_sgets: KEV is') call igraphivout (logfil, 1, np, ndigit, '_sgets: NP is') call igraphdvout (logfil, kev+np, ritz, ndigit, & '_sgets: Eigenvalues of current H matrix') call igraphdvout (logfil, kev+np, bounds, ndigit, & '_sgets: Associated Ritz estimates') end if c return c c %---------------% c | End of igraphdsgets | c %---------------% c end leidenbase/src/vendor/arpack/dsortc.f0000644000176200001440000002207614447675376017375 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdsortc c c\Description: c Sorts the complex array in XREAL and XIMAG into the order c specified by WHICH and optionally applies the permutation to the c real array Y. It is assumed that if an element of XIMAG is c nonzero, then its negative is also an element. In other words, c both members of a complex conjugate pair are to be sorted and the c pairs are kept adjacent to each other. c c\Usage: c call igraphdsortc c ( WHICH, APPLY, N, XREAL, XIMAG, Y ) c c\Arguments c WHICH Character*2. (Input) c 'LM' -> sort XREAL,XIMAG into increasing order of magnitude. c 'SM' -> sort XREAL,XIMAG into decreasing order of magnitude. c 'LR' -> sort XREAL into increasing order of algebraic. c 'SR' -> sort XREAL into decreasing order of algebraic. c 'LI' -> sort XIMAG into increasing order of magnitude. c 'SI' -> sort XIMAG into decreasing order of magnitude. c NOTE: If an element of XIMAG is non-zero, then its negative c is also an element. c c APPLY Logical. (Input) c APPLY = .TRUE. -> apply the sorted order to array Y. c APPLY = .FALSE. -> do not apply the sorted order to array Y. c c N Integer. (INPUT) c Size of the arrays. c c XREAL, Double precision array of length N. (INPUT/OUTPUT) c XIMAG Real and imaginary part of the array to be sorted. c c Y Double precision array of length N. (INPUT/OUTPUT) c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/92: Version ' 2.1' c Adapted from the sort routine in LANSO. c c\SCCS Information: @(#) c FILE: sortc.F SID: 2.3 DATE OF SID: 4/20/96 RELEASE: 2 c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdsortc (which, apply, n, xreal, ximag, y) c c %------------------% c | Scalar Arguments | c %------------------% c character*2 which logical apply integer n c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & xreal(0:n-1), ximag(0:n-1), y(0:n-1) c c %---------------% c | Local Scalars | c %---------------% c integer i, igap, j Double precision & temp, temp1, temp2 c c %--------------------% c | External Functions | c %--------------------% c Double precision & dlapy2 external dlapy2 c c %-----------------------% c | Executable Statements | c %-----------------------% c igap = n / 2 c if (which .eq. 'LM') then c c %------------------------------------------------------% c | Sort XREAL,XIMAG into increasing order of magnitude. | c %------------------------------------------------------% c 10 continue if (igap .eq. 0) go to 9000 c do 30 i = igap, n-1 j = i-igap 20 continue c if (j.lt.0) go to 30 c temp1 = dlapy2(xreal(j),ximag(j)) temp2 = dlapy2(xreal(j+igap),ximag(j+igap)) c if (temp1.gt.temp2) then temp = xreal(j) xreal(j) = xreal(j+igap) xreal(j+igap) = temp c temp = ximag(j) ximag(j) = ximag(j+igap) ximag(j+igap) = temp c if (apply) then temp = y(j) y(j) = y(j+igap) y(j+igap) = temp end if else go to 30 end if j = j-igap go to 20 30 continue igap = igap / 2 go to 10 c else if (which .eq. 'SM') then c c %------------------------------------------------------% c | Sort XREAL,XIMAG into decreasing order of magnitude. | c %------------------------------------------------------% c 40 continue if (igap .eq. 0) go to 9000 c do 60 i = igap, n-1 j = i-igap 50 continue c if (j .lt. 0) go to 60 c temp1 = dlapy2(xreal(j),ximag(j)) temp2 = dlapy2(xreal(j+igap),ximag(j+igap)) c if (temp1.lt.temp2) then temp = xreal(j) xreal(j) = xreal(j+igap) xreal(j+igap) = temp c temp = ximag(j) ximag(j) = ximag(j+igap) ximag(j+igap) = temp c if (apply) then temp = y(j) y(j) = y(j+igap) y(j+igap) = temp end if else go to 60 endif j = j-igap go to 50 60 continue igap = igap / 2 go to 40 c else if (which .eq. 'LR') then c c %------------------------------------------------% c | Sort XREAL into increasing order of algebraic. | c %------------------------------------------------% c 70 continue if (igap .eq. 0) go to 9000 c do 90 i = igap, n-1 j = i-igap 80 continue c if (j.lt.0) go to 90 c if (xreal(j).gt.xreal(j+igap)) then temp = xreal(j) xreal(j) = xreal(j+igap) xreal(j+igap) = temp c temp = ximag(j) ximag(j) = ximag(j+igap) ximag(j+igap) = temp c if (apply) then temp = y(j) y(j) = y(j+igap) y(j+igap) = temp end if else go to 90 endif j = j-igap go to 80 90 continue igap = igap / 2 go to 70 c else if (which .eq. 'SR') then c c %------------------------------------------------% c | Sort XREAL into decreasing order of algebraic. | c %------------------------------------------------% c 100 continue if (igap .eq. 0) go to 9000 do 120 i = igap, n-1 j = i-igap 110 continue c if (j.lt.0) go to 120 c if (xreal(j).lt.xreal(j+igap)) then temp = xreal(j) xreal(j) = xreal(j+igap) xreal(j+igap) = temp c temp = ximag(j) ximag(j) = ximag(j+igap) ximag(j+igap) = temp c if (apply) then temp = y(j) y(j) = y(j+igap) y(j+igap) = temp end if else go to 120 endif j = j-igap go to 110 120 continue igap = igap / 2 go to 100 c else if (which .eq. 'LI') then c c %------------------------------------------------% c | Sort XIMAG into increasing order of magnitude. | c %------------------------------------------------% c 130 continue if (igap .eq. 0) go to 9000 do 150 i = igap, n-1 j = i-igap 140 continue c if (j.lt.0) go to 150 c if (abs(ximag(j)).gt.abs(ximag(j+igap))) then temp = xreal(j) xreal(j) = xreal(j+igap) xreal(j+igap) = temp c temp = ximag(j) ximag(j) = ximag(j+igap) ximag(j+igap) = temp c if (apply) then temp = y(j) y(j) = y(j+igap) y(j+igap) = temp end if else go to 150 endif j = j-igap go to 140 150 continue igap = igap / 2 go to 130 c else if (which .eq. 'SI') then c c %------------------------------------------------% c | Sort XIMAG into decreasing order of magnitude. | c %------------------------------------------------% c 160 continue if (igap .eq. 0) go to 9000 do 180 i = igap, n-1 j = i-igap 170 continue c if (j.lt.0) go to 180 c if (abs(ximag(j)).lt.abs(ximag(j+igap))) then temp = xreal(j) xreal(j) = xreal(j+igap) xreal(j+igap) = temp c temp = ximag(j) ximag(j) = ximag(j+igap) ximag(j+igap) = temp c if (apply) then temp = y(j) y(j) = y(j+igap) y(j+igap) = temp end if else go to 180 endif j = j-igap go to 170 180 continue igap = igap / 2 go to 160 end if c 9000 continue return c c %---------------% c | End of igraphdsortc | c %---------------% c end leidenbase/src/vendor/arpack/dsconv.f0000644000176200001440000000665414447675376017377 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdsconv c c\Description: c Convergence testing for the symmetric Arnoldi eigenvalue routine. c c\Usage: c call igraphdsconv c ( N, RITZ, BOUNDS, TOL, NCONV ) c c\Arguments c N Integer. (INPUT) c Number of Ritz values to check for convergence. c c RITZ Double precision array of length N. (INPUT) c The Ritz values to be checked for convergence. c c BOUNDS Double precision array of length N. (INPUT) c Ritz estimates associated with the Ritz values in RITZ. c c TOL Double precision scalar. (INPUT) c Desired relative accuracy for a Ritz value to be considered c "converged". c c NCONV Integer scalar. (OUTPUT) c Number of "converged" Ritz values. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Routines called: c igraphsecond ARPACK utility routine for timing. c dlamch LAPACK routine that determines machine constants. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\SCCS Information: @(#) c FILE: sconv.F SID: 2.4 DATE OF SID: 4/19/96 RELEASE: 2 c c\Remarks c 1. Starting with version 2.4, this routine no longer uses the c Parlett strategy using the gap conditions. c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdsconv (n, ritz, bounds, tol, nconv) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c integer n, nconv Double precision & tol c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & ritz(n), bounds(n) c c %---------------% c | Local Scalars | c %---------------% c integer i Double precision & temp, eps23 c c %-------------------% c | External routines | c %-------------------% c Double precision & dlamch external dlamch c %---------------------% c | Intrinsic Functions | c %---------------------% c intrinsic abs c c %-----------------------% c | Executable Statements | c %-----------------------% c call igraphsecond (t0) c eps23 = dlamch('Epsilon-Machine') eps23 = eps23**(2.0D+0 / 3.0D+0) c nconv = 0 do 10 i = 1, n c c %-----------------------------------------------------% c | The i-th Ritz value is considered "converged" | c | when: bounds(i) .le. TOL*max(eps23, abs(ritz(i))) | c %-----------------------------------------------------% c temp = max( eps23, abs(ritz(i)) ) if ( bounds(i) .le. tol*temp ) then nconv = nconv + 1 end if c 10 continue c call igraphsecond (t1) tsconv = tsconv + (t1 - t0) c return c c %---------------% c | End of igraphdsconv | c %---------------% c end leidenbase/src/vendor/arpack/ivout.f0000644000176200001440000000722114447675376017240 0ustar liggesusersC----------------------------------------------------------------------- C Routine: IVOUT C C Purpose: Integer vector output routine. C C Usage: CALL IVOUT (LOUT, N, IX, IDIGIT, IFMT) C C Arguments C N - Length of array IX. (Input) C IX - Integer array to be printed. (Input) C IFMT - Format to be used in printing array IX. (Input) C IDIGIT - Print up to ABS(IDIGIT) decimal digits / number. (Input) C If IDIGIT .LT. 0, printing is done with 72 columns. C If IDIGIT .GT. 0, printing is done with 132 columns. C C----------------------------------------------------------------------- C SUBROUTINE IGRAPHIVOUT (LOUT, N, IX, IDIGIT, IFMT) C ... C ... SPECIFICATIONS FOR ARGUMENTS INTEGER IX(*), N, IDIGIT, LOUT CHARACTER IFMT*(*) C ... C ... SPECIFICATIONS FOR LOCAL VARIABLES INTEGER I, NDIGIT, K1, K2, LLL CHARACTER*80 LINE * ... * ... SPECIFICATIONS INTRINSICS INTRINSIC MIN * C c$$$ LLL = MIN ( LEN ( IFMT ), 80 ) c$$$ DO 1 I = 1, LLL c$$$ LINE(I:I) = '-' c$$$ 1 CONTINUE c$$$C c$$$ DO 2 I = LLL+1, 80 c$$$ LINE(I:I) = ' ' c$$$ 2 CONTINUE c$$$C c$$$ WRITE ( LOUT, 2000 ) IFMT, LINE(1:LLL) c$$$ 2000 FORMAT ( /1X, A /1X, A ) c$$$C c$$$ IF (N .LE. 0) RETURN c$$$ NDIGIT = IDIGIT c$$$ IF (IDIGIT .EQ. 0) NDIGIT = 4 c$$$C c$$$C======================================================================= c$$$C CODE FOR OUTPUT USING 72 COLUMNS FORMAT c$$$C======================================================================= c$$$C c$$$ IF (IDIGIT .LT. 0) THEN c$$$C c$$$ NDIGIT = -IDIGIT c$$$ IF (NDIGIT .LE. 4) THEN c$$$ DO 10 K1 = 1, N, 10 c$$$ K2 = MIN0(N,K1+9) c$$$ WRITE(LOUT,1000) K1,K2,(IX(I),I=K1,K2) c$$$ 10 CONTINUE c$$$C c$$$ ELSE IF (NDIGIT .LE. 6) THEN c$$$ DO 30 K1 = 1, N, 7 c$$$ K2 = MIN0(N,K1+6) c$$$ WRITE(LOUT,1001) K1,K2,(IX(I),I=K1,K2) c$$$ 30 CONTINUE c$$$C c$$$ ELSE IF (NDIGIT .LE. 10) THEN c$$$ DO 50 K1 = 1, N, 5 c$$$ K2 = MIN0(N,K1+4) c$$$ WRITE(LOUT,1002) K1,K2,(IX(I),I=K1,K2) c$$$ 50 CONTINUE c$$$C c$$$ ELSE c$$$ DO 70 K1 = 1, N, 3 c$$$ K2 = MIN0(N,K1+2) c$$$ WRITE(LOUT,1003) K1,K2,(IX(I),I=K1,K2) c$$$ 70 CONTINUE c$$$ END IF c$$$C c$$$C======================================================================= c$$$C CODE FOR OUTPUT USING 132 COLUMNS FORMAT c$$$C======================================================================= c$$$C c$$$ ELSE c$$$C c$$$ IF (NDIGIT .LE. 4) THEN c$$$ DO 90 K1 = 1, N, 20 c$$$ K2 = MIN0(N,K1+19) c$$$ WRITE(LOUT,1000) K1,K2,(IX(I),I=K1,K2) c$$$ 90 CONTINUE c$$$C c$$$ ELSE IF (NDIGIT .LE. 6) THEN c$$$ DO 110 K1 = 1, N, 15 c$$$ K2 = MIN0(N,K1+14) c$$$ WRITE(LOUT,1001) K1,K2,(IX(I),I=K1,K2) c$$$ 110 CONTINUE c$$$C c$$$ ELSE IF (NDIGIT .LE. 10) THEN c$$$ DO 130 K1 = 1, N, 10 c$$$ K2 = MIN0(N,K1+9) c$$$ WRITE(LOUT,1002) K1,K2,(IX(I),I=K1,K2) c$$$ 130 CONTINUE c$$$C c$$$ ELSE c$$$ DO 150 K1 = 1, N, 7 c$$$ K2 = MIN0(N,K1+6) c$$$ WRITE(LOUT,1003) K1,K2,(IX(I),I=K1,K2) c$$$ 150 CONTINUE c$$$ END IF c$$$ END IF c$$$ WRITE (LOUT,1004) c$$$C c$$$ 1000 FORMAT(1X,I4,' - ',I4,':',20(1X,I5)) c$$$ 1001 FORMAT(1X,I4,' - ',I4,':',15(1X,I7)) c$$$ 1002 FORMAT(1X,I4,' - ',I4,':',10(1X,I11)) c$$$ 1003 FORMAT(1X,I4,' - ',I4,':',7(1X,I15)) c$$$ 1004 FORMAT(1X,' ') c$$$C RETURN END leidenbase/src/vendor/arpack/dseupd.f0000644000176200001440000011031414447675376017354 0ustar liggesusersc\BeginDoc c c\Name: igraphdseupd c c\Description: c c This subroutine returns the converged approximations to eigenvalues c of A*z = lambda*B*z and (optionally): c c (1) the corresponding approximate eigenvectors, c c (2) an orthonormal (Lanczos) basis for the associated approximate c invariant subspace, c c (3) Both. c c There is negligible additional cost to obtain eigenvectors. An orthonormal c (Lanczos) basis is always computed. There is an additional storage cost c of n*nev if both are requested (in this case a separate array Z must be c supplied). c c These quantities are obtained from the Lanczos factorization computed c by DSAUPD for the linear operator OP prescribed by the MODE selection c (see IPARAM(7) in DSAUPD documentation.) DSAUPD must be called before c this routine is called. These approximate eigenvalues and vectors are c commonly called Ritz values and Ritz vectors respectively. They are c referred to as such in the comments that follow. The computed orthonormal c basis for the invariant subspace corresponding to these Ritz values is c referred to as a Lanczos basis. c c See documentation in the header of the subroutine DSAUPD for a definition c of OP as well as other terms and the relation of computed Ritz values c and vectors of OP with respect to the given problem A*z = lambda*B*z. c c The approximate eigenvalues of the original problem are returned in c ascending algebraic order. The user may elect to call this routine c once for each desired Ritz vector and store it peripherally if desired. c There is also the option of computing a selected set of these vectors c with a single call. c c\Usage: c call igraphdseupd c ( RVEC, HOWMNY, SELECT, D, Z, LDZ, SIGMA, BMAT, N, WHICH, NEV, TOL, c RESID, NCV, V, LDV, IPARAM, IPNTR, WORKD, WORKL, LWORKL, INFO ) c c RVEC LOGICAL (INPUT) c Specifies whether Ritz vectors corresponding to the Ritz value c approximations to the eigenproblem A*z = lambda*B*z are computed. c c RVEC = .FALSE. Compute Ritz values only. c c RVEC = .TRUE. Compute Ritz vectors. c c HOWMNY Character*1 (INPUT) c Specifies how many Ritz vectors are wanted and the form of Z c the matrix of Ritz vectors. See remark 1 below. c = 'A': compute NEV Ritz vectors; c = 'S': compute some of the Ritz vectors, specified c by the logical array SELECT. c c SELECT Logical array of dimension NEV. (INPUT) c If HOWMNY = 'S', SELECT specifies the Ritz vectors to be c computed. To select the Ritz vector corresponding to a c Ritz value D(j), SELECT(j) must be set to .TRUE.. c If HOWMNY = 'A' , SELECT is not referenced. c c D Double precision array of dimension NEV. (OUTPUT) c On exit, D contains the Ritz value approximations to the c eigenvalues of A*z = lambda*B*z. The values are returned c in ascending order. If IPARAM(7) = 3,4,5 then D represents c the Ritz values of OP computed by igraphdsaupd transformed to c those of the original eigensystem A*z = lambda*B*z. If c IPARAM(7) = 1,2 then the Ritz values of OP are the same c as the those of A*z = lambda*B*z. c c Z Double precision N by NEV array if HOWMNY = 'A'. (OUTPUT) c On exit, Z contains the B-orthonormal Ritz vectors of the c eigensystem A*z = lambda*B*z corresponding to the Ritz c value approximations. c If RVEC = .FALSE. then Z is not referenced. c NOTE: The array Z may be set equal to first NEV columns of the c Arnoldi/Lanczos basis array V computed by DSAUPD. c c LDZ Integer. (INPUT) c The leading dimension of the array Z. If Ritz vectors are c desired, then LDZ .ge. max( 1, N ). In any case, LDZ .ge. 1. c c SIGMA Double precision (INPUT) c If IPARAM(7) = 3,4,5 represents the shift. Not referenced if c IPARAM(7) = 1 or 2. c c c **** The remaining arguments MUST be the same as for the **** c **** call to DNAUPD that was just completed. **** c c NOTE: The remaining arguments c c BMAT, N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, IPNTR, c WORKD, WORKL, LWORKL, INFO c c must be passed directly to DSEUPD following the last call c to DSAUPD. These arguments MUST NOT BE MODIFIED between c the the last call to DSAUPD and the call to DSEUPD. c c Two of these parameters (WORKL, INFO) are also output parameters: c c WORKL Double precision work array of length LWORKL. (OUTPUT/WORKSPACE) c WORKL(1:4*ncv) contains information obtained in c igraphdsaupd. They are not changed by igraphdseupd. c WORKL(4*ncv+1:ncv*ncv+8*ncv) holds the c untransformed Ritz values, the computed error estimates, c and the associated eigenvector matrix of H. c c Note: IPNTR(8:10) contains the pointer into WORKL for addresses c of the above information computed by igraphdseupd. c ------------------------------------------------------------- c IPNTR(8): pointer to the NCV RITZ values of the original system. c IPNTR(9): pointer to the NCV corresponding error bounds. c IPNTR(10): pointer to the NCV by NCV matrix of eigenvectors c of the tridiagonal matrix T. Only referenced by c igraphdseupd if RVEC = .TRUE. See Remarks. c ------------------------------------------------------------- c c INFO Integer. (OUTPUT) c Error flag on output. c = 0: Normal exit. c = -1: N must be positive. c = -2: NEV must be positive. c = -3: NCV must be greater than NEV and less than or equal to N. c = -5: WHICH must be one of 'LM', 'SM', 'LA', 'SA' or 'BE'. c = -6: BMAT must be one of 'I' or 'G'. c = -7: Length of private work WORKL array is not sufficient. c = -8: Error return from trid. eigenvalue calculation; c Information error from LAPACK routine dsteqr. c = -9: Starting vector is zero. c = -10: IPARAM(7) must be 1,2,3,4,5. c = -11: IPARAM(7) = 1 and BMAT = 'G' are incompatible. c = -12: NEV and WHICH = 'BE' are incompatible. c = -14: DSAUPD did not find any eigenvalues to sufficient c accuracy. c = -15: HOWMNY must be one of 'A' or 'S' if RVEC = .true. c = -16: HOWMNY = 'S' not yet implemented c c\BeginLib c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly c Restarted Arnoldi Iteration", Rice University Technical Report c TR95-13, Department of Computational and Applied Mathematics. c 3. B.N. Parlett, "The Symmetric Eigenvalue Problem". Prentice-Hall, c 1980. c 4. B.N. Parlett, B. Nour-Omid, "Towards a Black Box Lanczos Program", c Computer Physics Communications, 53 (1989), pp 169-179. c 5. B. Nour-Omid, B.N. Parlett, T. Ericson, P.S. Jensen, "How to c Implement the Spectral Transformation", Math. Comp., 48 (1987), c pp 663-673. c 6. R.G. Grimes, J.G. Lewis and H.D. Simon, "A Shifted Block Lanczos c Algorithm for Solving Sparse Symmetric Generalized Eigenproblems", c SIAM J. Matr. Anal. Apps., January (1993). c 7. L. Reichel, W.B. Gragg, "Algorithm 686: FORTRAN Subroutines c for Updating the QR decomposition", ACM TOMS, December 1990, c Volume 16 Number 4, pp 369-377. c c\Remarks c 1. The converged Ritz values are always returned in increasing c (algebraic) order. c c 2. Currently only HOWMNY = 'A' is implemented. It is included at this c stage for the user who wants to incorporate it. c c\Routines called: c igraphdsesrt ARPACK routine that sorts an array X, and applies the c corresponding permutation to a matrix A. c igraphdsortr igraphdsortr ARPACK sorting routine. c igraphivout ARPACK utility routine that prints integers. c igraphdvout ARPACK utility routine that prints vectors. c dgeqr2 LAPACK routine that computes the QR factorization of c a matrix. c dlacpy LAPACK matrix copy routine. c dlamch LAPACK routine that determines machine constants. c dorm2r LAPACK routine that applies an orthogonal matrix in c factored form. c dsteqr LAPACK routine that computes eigenvalues and eigenvectors c of a tridiagonal matrix. c dger Level 2 BLAS rank one update to a matrix. c dcopy Level 1 BLAS that copies one vector to another . c dnrm2 Level 1 BLAS that computes the norm of a vector. c dscal Level 1 BLAS that scales a vector. c dswap Level 1 BLAS that swaps the contents of two vectors. c\Authors c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Chao Yang Houston, Texas c Dept. of Computational & c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c 12/15/93: Version ' 2.1' c c\SCCS Information: @(#) c FILE: seupd.F SID: 2.7 DATE OF SID: 8/27/96 RELEASE: 2 c c\EndLib c c----------------------------------------------------------------------- subroutine igraphdseupd (rvec, howmny, select, d, z, ldz, & sigma, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, & ipntr, workd, workl, lworkl, info ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character bmat, howmny, which*2 logical rvec, select(ncv) integer info, ldz, ldv, lworkl, n, ncv, nev Double precision & sigma, tol c c %-----------------% c | Array Arguments | c %-----------------% c integer iparam(7), ipntr(11) Double precision & d(nev), resid(n), v(ldv,ncv), z(ldz, nev), & workd(2*n), workl(lworkl) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c character type*6 integer bounds, ierr, ih, ihb, ihd, iq, iw, j, k, & ldh, ldq, mode, msglvl, nconv, next, ritz, & irz, ibd, ktrord, leftptr, rghtptr, ism, ilg Double precision & bnorm2, rnorm, temp, thres1, thres2, tempbnd, eps23 logical reord c c %--------------% c | Local Arrays | c %--------------% c Double precision & kv(2) c c %----------------------% c | External Subroutines | c %----------------------% c external dcopy, dger, dgeqr2, dlacpy, dorm2r, dscal, & igraphdsesrt, dsteqr, dswap, igraphdvout, & igraphivout, igraphdsortr c c %--------------------% c | External Functions | c %--------------------% c Double precision & dnrm2, dlamch external dnrm2, dlamch c c %---------------------% c | Intrinsic Functions | c %---------------------% c intrinsic min c c %-----------------------% c | Executable Statements | c %-----------------------% c c %------------------------% c | Set default parameters | c %------------------------% c msglvl = mseupd mode = iparam(7) nconv = iparam(5) info = 0 c c %--------------% c | Quick return | c %--------------% c if (nconv .eq. 0) go to 9000 ierr = 0 c if (nconv .le. 0) ierr = -14 if (n .le. 0) ierr = -1 if (nev .le. 0) ierr = -2 if (ncv .le. nev .or. ncv .gt. n) ierr = -3 if (which .ne. 'LM' .and. & which .ne. 'SM' .and. & which .ne. 'LA' .and. & which .ne. 'SA' .and. & which .ne. 'BE') ierr = -5 if (bmat .ne. 'I' .and. bmat .ne. 'G') ierr = -6 if ( (howmny .ne. 'A' .and. & howmny .ne. 'P' .and. & howmny .ne. 'S') .and. rvec ) & ierr = -15 if (rvec .and. howmny .eq. 'S') ierr = -16 c if (rvec .and. lworkl .lt. ncv**2+8*ncv) ierr = -7 c if (mode .eq. 1 .or. mode .eq. 2) then type = 'REGULR' else if (mode .eq. 3 ) then type = 'SHIFTI' else if (mode .eq. 4 ) then type = 'BUCKLE' else if (mode .eq. 5 ) then type = 'CAYLEY' else ierr = -10 end if if (mode .eq. 1 .and. bmat .eq. 'G') ierr = -11 if (nev .eq. 1 .and. which .eq. 'BE') ierr = -12 c c %------------% c | Error Exit | c %------------% c if (ierr .ne. 0) then info = ierr go to 9000 end if c c %-------------------------------------------------------% c | Pointer into WORKL for address of H, RITZ, BOUNDS, Q | c | etc... and the remaining workspace. | c | Also update pointer to be used on output. | c | Memory is laid out as follows: | c | workl(1:2*ncv) := generated tridiagonal matrix H | c | The subdiagonal is stored in workl(2:ncv). | c | The dead spot is workl(1) but upon exiting | c | igraphdsaupd stores the B-norm of the last residual | c | vector in workl(1). We use this !!! | c | workl(2*ncv+1:2*ncv+ncv) := ritz values | c | The wanted values are in the first NCONV spots. | c | workl(3*ncv+1:3*ncv+ncv) := computed Ritz estimates | c | The wanted values are in the first NCONV spots. | c | NOTE: workl(1:4*ncv) is set by igraphdsaupd and is not | c | modified by igraphdseupd. | c %-------------------------------------------------------% c c %-------------------------------------------------------% c | The following is used and set by igraphdseupd. | c | workl(4*ncv+1:4*ncv+ncv) := used as workspace during | c | computation of the eigenvectors of H. Stores | c | the diagonal of H. Upon EXIT contains the NCV | c | Ritz values of the original system. The first | c | NCONV spots have the wanted values. If MODE = | c | 1 or 2 then will equal workl(2*ncv+1:3*ncv). | c | workl(5*ncv+1:5*ncv+ncv) := used as workspace during | c | computation of the eigenvectors of H. Stores | c | the subdiagonal of H. Upon EXIT contains the | c | NCV corresponding Ritz estimates of the | c | original system. The first NCONV spots have the | c | wanted values. If MODE = 1,2 then will equal | c | workl(3*ncv+1:4*ncv). | c | workl(6*ncv+1:6*ncv+ncv*ncv) := orthogonal Q that is | c | the eigenvector matrix for H as returned by | c | dsteqr. Not referenced if RVEC = .False. | c | Ordering follows that of workl(4*ncv+1:5*ncv) | c | workl(6*ncv+ncv*ncv+1:6*ncv+ncv*ncv+2*ncv) := | c | Workspace. Needed by dsteqr and by igraphdseupd. | c | GRAND total of NCV*(NCV+8) locations. | c %-------------------------------------------------------% c c ih = ipntr(5) ritz = ipntr(6) bounds = ipntr(7) ldh = ncv ldq = ncv ihd = bounds + ldh ihb = ihd + ldh iq = ihb + ldh iw = iq + ldh*ncv next = iw + 2*ncv ipntr(4) = next ipntr(8) = ihd ipntr(9) = ihb ipntr(10) = iq c c %----------------------------------------% c | irz points to the Ritz values computed | c | by _seigt before exiting _saup2. | c | ibd points to the Ritz estimates | c | computed by _seigt before exiting | c | _saup2. | c %----------------------------------------% c irz = ipntr(11)+ncv ibd = irz+ncv c c c %---------------------------------% c | Set machine dependent constant. | c %---------------------------------% c eps23 = dlamch('Epsilon-Machine') eps23 = eps23**(2.0D+0 / 3.0D+0) c c %---------------------------------------% c | RNORM is B-norm of the RESID(1:N). | c | BNORM2 is the 2 norm of B*RESID(1:N). | c | Upon exit of igraphdsaupd WORKD(1:N) has | c | B*RESID(1:N). | c %---------------------------------------% c rnorm = workl(ih) if (bmat .eq. 'I') then bnorm2 = rnorm else if (bmat .eq. 'G') then bnorm2 = dnrm2(n, workd, 1) end if c if (rvec) then c c %------------------------------------------------% c | Get the converged Ritz value on the boundary. | c | This value will be used to dermine whether we | c | need to reorder the eigenvalues and | c | eigenvectors comupted by _steqr, and is | c | referred to as the "threshold" value. | c | | c | A Ritz value gamma is said to be a wanted | c | one, if | c | abs(gamma) .ge. threshold, when WHICH = 'LM'; | c | abs(gamma) .le. threshold, when WHICH = 'SM'; | c | gamma .ge. threshold, when WHICH = 'LA'; | c | gamma .le. threshold, when WHICH = 'SA'; | c | gamma .le. thres1 .or. gamma .ge. thres2 | c | when WHICH = 'BE'; | c | | c | Note: converged Ritz values and associated | c | Ritz estimates have been placed in the first | c | NCONV locations in workl(ritz) and | c | workl(bounds) respectively. They have been | c | sorted (in _saup2) according to the WHICH | c | selection criterion. (Except in the case | c | WHICH = 'BE', they are sorted in an increasing | c | order.) | c %------------------------------------------------% c if (which .eq. 'LM' .or. which .eq. 'SM' & .or. which .eq. 'LA' .or. which .eq. 'SA' ) then c thres1 = workl(ritz) c if (msglvl .gt. 2) then call igraphdvout(logfil, 1, [thres1], ndigit, & '_seupd: Threshold eigenvalue used for re-ordering') end if c else if (which .eq. 'BE') then c c %------------------------------------------------% c | Ritz values returned from _saup2 have been | c | sorted in increasing order. Thus two | c | "threshold" values (one for the small end, one | c | for the large end) are in the middle. | c %------------------------------------------------% c ism = max(nev,nconv) / 2 ilg = ism + 1 thres1 = workl(ism) thres2 = workl(ilg) c if (msglvl .gt. 2) then kv(1) = thres1 kv(2) = thres2 call igraphdvout(logfil, 2, kv, ndigit, & '_seupd: Threshold eigenvalues used for re-ordering') end if c end if c c %----------------------------------------------------------% c | Check to see if all converged Ritz values appear within | c | the first NCONV diagonal elements returned from _seigt. | c | This is done in the following way: | c | | c | 1) For each Ritz value obtained from _seigt, compare it | c | with the threshold Ritz value computed above to | c | determine whether it is a wanted one. | c | | c | 2) If it is wanted, then check the corresponding Ritz | c | estimate to see if it has converged. If it has, set | c | correponding entry in the logical array SELECT to | c | .TRUE.. | c | | c | If SELECT(j) = .TRUE. and j > NCONV, then there is a | c | converged Ritz value that does not appear at the top of | c | the diagonal matrix computed by _seigt in _saup2. | c | Reordering is needed. | c %----------------------------------------------------------% c reord = .false. ktrord = 0 do 10 j = 0, ncv-1 select(j+1) = .false. if (which .eq. 'LM') then if (abs(workl(irz+j)) .ge. abs(thres1)) then tempbnd = max( eps23, abs(workl(irz+j)) ) if (workl(ibd+j) .le. tol*tempbnd) then select(j+1) = .true. end if end if else if (which .eq. 'SM') then if (abs(workl(irz+j)) .le. abs(thres1)) then tempbnd = max( eps23, abs(workl(irz+j)) ) if (workl(ibd+j) .le. tol*tempbnd) then select(j+1) = .true. end if end if else if (which .eq. 'LA') then if (workl(irz+j) .ge. thres1) then tempbnd = max( eps23, abs(workl(irz+j)) ) if (workl(ibd+j) .le. tol*tempbnd) then select(j+1) = .true. end if end if else if (which .eq. 'SA') then if (workl(irz+j) .le. thres1) then tempbnd = max( eps23, abs(workl(irz+j)) ) if (workl(ibd+j) .le. tol*tempbnd) then select(j+1) = .true. end if end if else if (which .eq. 'BE') then if ( workl(irz+j) .le. thres1 .or. & workl(irz+j) .ge. thres2 ) then tempbnd = max( eps23, abs(workl(irz+j)) ) if (workl(ibd+j) .le. tol*tempbnd) then select(j+1) = .true. end if end if end if if (j+1 .gt. nconv ) reord = select(j+1) .or. reord if (select(j+1)) ktrord = ktrord + 1 10 continue c %-------------------------------------------% c | If KTRORD .ne. NCONV, something is wrong. | c %-------------------------------------------% c if (msglvl .gt. 2) then call igraphivout(logfil, 1, [ktrord], ndigit, & '_seupd: Number of specified eigenvalues') call igraphivout(logfil, 1, [nconv], ndigit, & '_seupd: Number of "converged" eigenvalues') end if c c %-----------------------------------------------------------% c | Call LAPACK routine _steqr to compute the eigenvalues and | c | eigenvectors of the final symmetric tridiagonal matrix H. | c | Initialize the eigenvector matrix Q to the identity. | c %-----------------------------------------------------------% c call dcopy (ncv-1, workl(ih+1), 1, workl(ihb), 1) call dcopy (ncv, workl(ih+ldh), 1, workl(ihd), 1) c call dsteqr ('Identity', ncv, workl(ihd), workl(ihb), & workl(iq), ldq, workl(iw), ierr) c if (ierr .ne. 0) then info = -8 go to 9000 end if c if (msglvl .gt. 1) then call dcopy (ncv, workl(iq+ncv-1), ldq, workl(iw), 1) call igraphdvout (logfil, ncv, workl(ihd), ndigit, & '_seupd: NCV Ritz values of the final H matrix') call igraphdvout (logfil, ncv, workl(iw), ndigit, & '_seupd: last row of the eigenvector matrix for H') end if c if (reord) then c c %---------------------------------------------% c | Reordered the eigenvalues and eigenvectors | c | computed by _steqr so that the "converged" | c | eigenvalues appear in the first NCONV | c | positions of workl(ihd), and the associated | c | eigenvectors appear in the first NCONV | c | columns. | c %---------------------------------------------% c leftptr = 1 rghtptr = ncv c if (ncv .eq. 1) go to 30 c 20 if (select(leftptr)) then c c %-------------------------------------------% c | Search, from the left, for the first Ritz | c | value that has not converged. | c %-------------------------------------------% c leftptr = leftptr + 1 c else if ( .not. select(rghtptr)) then c c %----------------------------------------------% c | Search, from the right, the first Ritz value | c | that has converged. | c %----------------------------------------------% c rghtptr = rghtptr - 1 c else c c %----------------------------------------------% c | Swap the Ritz value on the left that has not | c | converged with the Ritz value on the right | c | that has converged. Swap the associated | c | eigenvector of the tridiagonal matrix H as | c | well. | c %----------------------------------------------% c temp = workl(ihd+leftptr-1) workl(ihd+leftptr-1) = workl(ihd+rghtptr-1) workl(ihd+rghtptr-1) = temp call dcopy(ncv, workl(iq+ncv*(leftptr-1)), 1, & workl(iw), 1) call dcopy(ncv, workl(iq+ncv*(rghtptr-1)), 1, & workl(iq+ncv*(leftptr-1)), 1) call dcopy(ncv, workl(iw), 1, & workl(iq+ncv*(rghtptr-1)), 1) leftptr = leftptr + 1 rghtptr = rghtptr - 1 c end if c if (leftptr .lt. rghtptr) go to 20 c 30 end if c if (msglvl .gt. 2) then call igraphdvout (logfil, ncv, workl(ihd), ndigit, & '_seupd: The eigenvalues of H--reordered') end if c c %----------------------------------------% c | Load the converged Ritz values into D. | c %----------------------------------------% c call dcopy(nconv, workl(ihd), 1, d, 1) c else c c %-----------------------------------------------------% c | Ritz vectors not required. Load Ritz values into D. | c %-----------------------------------------------------% c call dcopy (nconv, workl(ritz), 1, d, 1) call dcopy (ncv, workl(ritz), 1, workl(ihd), 1) c end if c c %------------------------------------------------------------------% c | Transform the Ritz values and possibly vectors and corresponding | c | Ritz estimates of OP to those of A*x=lambda*B*x. The Ritz values | c | (and corresponding data) are returned in ascending order. | c %------------------------------------------------------------------% c if (type .eq. 'REGULR') then c c %---------------------------------------------------------% c | Ascending sort of wanted Ritz values, vectors and error | c | bounds. Not necessary if only Ritz values are desired. | c %---------------------------------------------------------% c if (rvec) then call igraphdsesrt ('LA', rvec , nconv, d, ncv, workl(iq), & ldq) else call dcopy (ncv, workl(bounds), 1, workl(ihb), 1) end if c else c c %-------------------------------------------------------------% c | * Make a copy of all the Ritz values. | c | * Transform the Ritz values back to the original system. | c | For TYPE = 'SHIFTI' the transformation is | c | lambda = 1/theta + sigma | c | For TYPE = 'BUCKLE' the transformation is | c | lambda = sigma * theta / ( theta - 1 ) | c | For TYPE = 'CAYLEY' the transformation is | c | lambda = sigma * (theta + 1) / (theta - 1 ) | c | where the theta are the Ritz values returned by igraphdsaupd. | c | NOTES: | c | *The Ritz vectors are not affected by the transformation. | c | They are only reordered. | c %-------------------------------------------------------------% c call dcopy (ncv, workl(ihd), 1, workl(iw), 1) if (type .eq. 'SHIFTI') then do 40 k=1, ncv workl(ihd+k-1) = one / workl(ihd+k-1) + sigma 40 continue else if (type .eq. 'BUCKLE') then do 50 k=1, ncv workl(ihd+k-1) = sigma * workl(ihd+k-1) / & (workl(ihd+k-1) - one) 50 continue else if (type .eq. 'CAYLEY') then do 60 k=1, ncv workl(ihd+k-1) = sigma * (workl(ihd+k-1) + one) / & (workl(ihd+k-1) - one) 60 continue end if c c %-------------------------------------------------------------% c | * Store the wanted NCONV lambda values into D. | c | * Sort the NCONV wanted lambda in WORKL(IHD:IHD+NCONV-1) | c | into ascending order and apply sort to the NCONV theta | c | values in the transformed system. We'll need this to | c | compute Ritz estimates in the original system. | c | * Finally sort the lambda's into ascending order and apply | c | to Ritz vectors if wanted. Else just sort lambda's into | c | ascending order. | c | NOTES: | c | *workl(iw:iw+ncv-1) contain the theta ordered so that they | c | match the ordering of the lambda. We'll use them again for | c | Ritz vector purification. | c %-------------------------------------------------------------% c call dcopy (nconv, workl(ihd), 1, d, 1) call igraphdsortr ('LA', .true., nconv, workl(ihd), workl(iw)) if (rvec) then call igraphdsesrt ('LA', rvec , nconv, d, ncv, workl(iq), & ldq) else call dcopy (ncv, workl(bounds), 1, workl(ihb), 1) call dscal (ncv, bnorm2/rnorm, workl(ihb), 1) call igraphdsortr ('LA', .true., nconv, d, workl(ihb)) end if c end if c c %------------------------------------------------% c | Compute the Ritz vectors. Transform the wanted | c | eigenvectors of the symmetric tridiagonal H by | c | the Lanczos basis matrix V. | c %------------------------------------------------% c if (rvec .and. howmny .eq. 'A') then c c %----------------------------------------------------------% c | Compute the QR factorization of the matrix representing | c | the wanted invariant subspace located in the first NCONV | c | columns of workl(iq,ldq). | c %----------------------------------------------------------% c call dgeqr2 (ncv, nconv, workl(iq), ldq, workl(iw+ncv), & workl(ihb), ierr) c c c %--------------------------------------------------------% c | * Postmultiply V by Q. | c | * Copy the first NCONV columns of VQ into Z. | c | The N by NCONV matrix Z is now a matrix representation | c | of the approximate invariant subspace associated with | c | the Ritz values in workl(ihd). | c %--------------------------------------------------------% c call dorm2r ('Right', 'Notranspose', n, ncv, nconv, workl(iq), & ldq, workl(iw+ncv), v, ldv, workd(n+1), ierr) call dlacpy ('All', n, nconv, v, ldv, z, ldz) c c %-----------------------------------------------------% c | In order to compute the Ritz estimates for the Ritz | c | values in both systems, need the last row of the | c | eigenvector matrix. Remember, it's in factored form | c %-----------------------------------------------------% c do 65 j = 1, ncv-1 workl(ihb+j-1) = zero 65 continue workl(ihb+ncv-1) = one call dorm2r ('Left', 'Transpose', ncv, 1, nconv, workl(iq), & ldq, workl(iw+ncv), workl(ihb), ncv, temp, ierr) c else if (rvec .and. howmny .eq. 'S') then c c Not yet implemented. See remark 2 above. c end if c if (type .eq. 'REGULR' .and. rvec) then c do 70 j=1, ncv workl(ihb+j-1) = rnorm * abs( workl(ihb+j-1) ) 70 continue c else if (type .ne. 'REGULR' .and. rvec) then c c %-------------------------------------------------% c | * Determine Ritz estimates of the theta. | c | If RVEC = .true. then compute Ritz estimates | c | of the theta. | c | If RVEC = .false. then copy Ritz estimates | c | as computed by igraphdsaupd. | c | * Determine Ritz estimates of the lambda. | c %-------------------------------------------------% c call dscal (ncv, bnorm2, workl(ihb), 1) if (type .eq. 'SHIFTI') then c do 80 k=1, ncv workl(ihb+k-1) = abs( workl(ihb+k-1) ) / workl(iw+k-1)**2 80 continue c else if (type .eq. 'BUCKLE') then c do 90 k=1, ncv workl(ihb+k-1) = sigma * abs( workl(ihb+k-1) ) / & ( workl(iw+k-1)-one )**2 90 continue c else if (type .eq. 'CAYLEY') then c do 100 k=1, ncv workl(ihb+k-1) = abs( workl(ihb+k-1) / & workl(iw+k-1)*(workl(iw+k-1)-one) ) 100 continue c end if c end if c if (type .ne. 'REGULR' .and. msglvl .gt. 1) then call igraphdvout (logfil, nconv, d, ndigit, & '_seupd: Untransformed converged Ritz values') call igraphdvout (logfil, nconv, workl(ihb), ndigit, & '_seupd: Ritz estimates of the untransformed Ritz values') else if (msglvl .gt. 1) then call igraphdvout (logfil, nconv, d, ndigit, & '_seupd: Converged Ritz values') call igraphdvout (logfil, nconv, workl(ihb), ndigit, & '_seupd: Associated Ritz estimates') end if c c %-------------------------------------------------% c | Ritz vector purification step. Formally perform | c | one of inverse subspace iteration. Only used | c | for MODE = 3,4,5. See reference 7 | c %-------------------------------------------------% c if (rvec .and. (type .eq. 'SHIFTI' .or. type .eq. 'CAYLEY')) then c do 110 k=0, nconv-1 workl(iw+k) = workl(iq+k*ldq+ncv-1) / workl(iw+k) 110 continue c else if (rvec .and. type .eq. 'BUCKLE') then c do 120 k=0, nconv-1 workl(iw+k) = workl(iq+k*ldq+ncv-1) / (workl(iw+k)-one) 120 continue c end if c if (type .ne. 'REGULR') & call dger (n, nconv, one, resid, 1, workl(iw), 1, z, ldz) c 9000 continue c return c c %---------------% c | End of igraphdseupd | c %---------------% c end leidenbase/src/vendor/arpack/dstats.f0000644000176200001440000000223214447675376017371 0ustar liggesusersc c\SCCS Information: @(#) c FILE: stats.F SID: 2.1 DATE OF SID: 4/19/96 RELEASE: 2 c %---------------------------------------------% c | Initialize statistic and timing information | c | for symmetric Arnoldi code. | c %---------------------------------------------% subroutine igraphdstats c %--------------------------------% c | See stat.doc for documentation | c %--------------------------------% include 'stat.h' c %-----------------------% c | Executable Statements | c %-----------------------% nopx = 0 nbx = 0 nrorth = 0 nitref = 0 nrstrt = 0 tsaupd = 0.0D+0 tsaup2 = 0.0D+0 tsaitr = 0.0D+0 tseigt = 0.0D+0 tsgets = 0.0D+0 tsapps = 0.0D+0 tsconv = 0.0D+0 titref = 0.0D+0 tgetv0 = 0.0D+0 trvec = 0.0D+0 c %----------------------------------------------------% c | User time including reverse communication overhead | c %----------------------------------------------------% tmvopx = 0.0D+0 tmvbx = 0.0D+0 return c c End of igraphdstats c end leidenbase/src/vendor/arpack/dneupd.f0000644000176200001440000012570514447675376017361 0ustar liggesusersc\BeginDoc c c\Name: igraphdneupd c c\Description: c c This subroutine returns the converged approximations to eigenvalues c of A*z = lambda*B*z and (optionally): c c (1) The corresponding approximate eigenvectors; c c (2) An orthonormal basis for the associated approximate c invariant subspace; c c (3) Both. c c There is negligible additional cost to obtain eigenvectors. An orthonormal c basis is always computed. There is an additional storage cost of n*nev c if both are requested (in this case a separate array Z must be supplied). c c The approximate eigenvalues and eigenvectors of A*z = lambda*B*z c are derived from approximate eigenvalues and eigenvectors of c of the linear operator OP prescribed by the MODE selection in the c call to DNAUPD. DNAUPD must be called before this routine is called. c These approximate eigenvalues and vectors are commonly called Ritz c values and Ritz vectors respectively. They are referred to as such c in the comments that follow. The computed orthonormal basis for the c invariant subspace corresponding to these Ritz values is referred to as a c Schur basis. c c See documentation in the header of the subroutine DNAUPD for c definition of OP as well as other terms and the relation of computed c Ritz values and Ritz vectors of OP with respect to the given problem c A*z = lambda*B*z. For a brief description, see definitions of c IPARAM(7), MODE and WHICH in the documentation of DNAUPD. c c\Usage: c call igraphdneupd c ( RVEC, HOWMNY, SELECT, DR, DI, Z, LDZ, SIGMAR, SIGMAI, WORKEV, BMAT, c N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, IPNTR, WORKD, WORKL, c LWORKL, INFO ) c c\Arguments: c RVEC LOGICAL (INPUT) c Specifies whether a basis for the invariant subspace corresponding c to the converged Ritz value approximations for the eigenproblem c A*z = lambda*B*z is computed. c c RVEC = .FALSE. Compute Ritz values only. c c RVEC = .TRUE. Compute the Ritz vectors or Schur vectors. c See Remarks below. c c HOWMNY Character*1 (INPUT) c Specifies the form of the basis for the invariant subspace c corresponding to the converged Ritz values that is to be computed. c c = 'A': Compute NEV Ritz vectors; c = 'P': Compute NEV Schur vectors; c = 'S': compute some of the Ritz vectors, specified c by the logical array SELECT. c c SELECT Logical array of dimension NCV. (INPUT) c If HOWMNY = 'S', SELECT specifies the Ritz vectors to be c computed. To select the Ritz vector corresponding to a c Ritz value (DR(j), DI(j)), SELECT(j) must be set to .TRUE.. c If HOWMNY = 'A' or 'P', SELECT is used as internal workspace. c c DR Double precision array of dimension NEV+1. (OUTPUT) c If IPARAM(7) = 1,2 or 3 and SIGMAI=0.0 then on exit: DR contains c the real part of the Ritz approximations to the eigenvalues of c A*z = lambda*B*z. c If IPARAM(7) = 3, 4 and SIGMAI is not equal to zero, then on exit: c DR contains the real part of the Ritz values of OP computed by c DNAUPD. A further computation must be performed by the user c to transform the Ritz values computed for OP by DNAUPD to those c of the original system A*z = lambda*B*z. See remark 3 below. c c DI Double precision array of dimension NEV+1. (OUTPUT) c On exit, DI contains the imaginary part of the Ritz value c approximations to the eigenvalues of A*z = lambda*B*z associated c with DR. c c NOTE: When Ritz values are complex, they will come in complex c conjugate pairs. If eigenvectors are requested, the c corresponding Ritz vectors will also come in conjugate c pairs and the real and imaginary parts of these are c represented in two consecutive columns of the array Z c (see below). c c Z Double precision N by NEV+1 array if RVEC = .TRUE. and HOWMNY = 'A'. (OUTPUT) c On exit, if RVEC = .TRUE. and HOWMNY = 'A', then the columns of c Z represent approximate eigenvectors (Ritz vectors) corresponding c to the NCONV=IPARAM(5) Ritz values for eigensystem c A*z = lambda*B*z. c c The complex Ritz vector associated with the Ritz value c with positive imaginary part is stored in two consecutive c columns. The first column holds the real part of the Ritz c vector and the igraphsecond column holds the imaginary part. The c Ritz vector associated with the Ritz value with negative c imaginary part is simply the complex conjugate of the Ritz vector c associated with the positive imaginary part. c c If RVEC = .FALSE. or HOWMNY = 'P', then Z is not referenced. c c NOTE: If if RVEC = .TRUE. and a Schur basis is not required, c the array Z may be set equal to first NEV+1 columns of the Arnoldi c basis array V computed by DNAUPD. In this case the Arnoldi basis c will be destroyed and overwritten with the eigenvector basis. c c LDZ Integer. (INPUT) c The leading dimension of the array Z. If Ritz vectors are c desired, then LDZ >= max( 1, N ). In any case, LDZ >= 1. c c SIGMAR Double precision (INPUT) c If IPARAM(7) = 3 or 4, represents the real part of the shift. c Not referenced if IPARAM(7) = 1 or 2. c c SIGMAI Double precision (INPUT) c If IPARAM(7) = 3 or 4, represents the imaginary part of the shift. c Not referenced if IPARAM(7) = 1 or 2. See remark 3 below. c c WORKEV Double precision work array of dimension 3*NCV. (WORKSPACE) c c **** The remaining arguments MUST be the same as for the **** c **** call to DNAUPD that was just completed. **** c c NOTE: The remaining arguments c c BMAT, N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, IPNTR, c WORKD, WORKL, LWORKL, INFO c c must be passed directly to DNEUPD following the last call c to DNAUPD. These arguments MUST NOT BE MODIFIED between c the the last call to DNAUPD and the call to DNEUPD. c c Three of these parameters (V, WORKL, INFO) are also output parameters: c c V Double precision N by NCV array. (INPUT/OUTPUT) c c Upon INPUT: the NCV columns of V contain the Arnoldi basis c vectors for OP as constructed by DNAUPD . c c Upon OUTPUT: If RVEC = .TRUE. the first NCONV=IPARAM(5) columns c contain approximate Schur vectors that span the c desired invariant subspace. See Remark 2 below. c c NOTE: If the array Z has been set equal to first NEV+1 columns c of the array V and RVEC=.TRUE. and HOWMNY= 'A', then the c Arnoldi basis held by V has been overwritten by the desired c Ritz vectors. If a separate array Z has been passed then c the first NCONV=IPARAM(5) columns of V will contain approximate c Schur vectors that span the desired invariant subspace. c c WORKL Double precision work array of length LWORKL. (OUTPUT/WORKSPACE) c WORKL(1:ncv*ncv+3*ncv) contains information obtained in c igraphdnaupd. They are not changed by igraphdneupd. c WORKL(ncv*ncv+3*ncv+1:3*ncv*ncv+6*ncv) holds the c real and imaginary part of the untransformed Ritz values, c the upper quasi-triangular matrix for H, and the c associated matrix representation of the invariant subspace for H. c c Note: IPNTR(9:13) contains the pointer into WORKL for addresses c of the above information computed by igraphdneupd. c ------------------------------------------------------------- c IPNTR(9): pointer to the real part of the NCV RITZ values of the c original system. c IPNTR(10): pointer to the imaginary part of the NCV RITZ values of c the original system. c IPNTR(11): pointer to the NCV corresponding error bounds. c IPNTR(12): pointer to the NCV by NCV upper quasi-triangular c Schur matrix for H. c IPNTR(13): pointer to the NCV by NCV matrix of eigenvectors c of the upper Hessenberg matrix H. Only referenced by c igraphdneupd if RVEC = .TRUE. See Remark 2 below. c ------------------------------------------------------------- c c INFO Integer. (OUTPUT) c Error flag on output. c c = 0: Normal exit. c c = 1: The Schur form computed by LAPACK routine dlahqr c could not be reordered by LAPACK routine dtrsen. c Re-enter subroutine igraphdneupd with IPARAM(5)=NCV and c increase the size of the arrays DR and DI to have c dimension at least dimension NCV and allocate at least NCV c columns for Z. NOTE: Not necessary if Z and V share c the same space. Please notify the authors if this error c occurs. c c = -1: N must be positive. c = -2: NEV must be positive. c = -3: NCV-NEV >= 2 and less than or equal to N. c = -5: WHICH must be one of 'LM', 'SM', 'LR', 'SR', 'LI', 'SI' c = -6: BMAT must be one of 'I' or 'G'. c = -7: Length of private work WORKL array is not sufficient. c = -8: Error return from calculation of a real Schur form. c Informational error from LAPACK routine dlahqr. c = -9: Error return from calculation of eigenvectors. c Informational error from LAPACK routine dtrevc. c = -10: IPARAM(7) must be 1,2,3,4. c = -11: IPARAM(7) = 1 and BMAT = 'G' are incompatible. c = -12: HOWMNY = 'S' not yet implemented c = -13: HOWMNY must be one of 'A' or 'P' if RVEC = .true. c = -14: DNAUPD did not find any eigenvalues to sufficient c accuracy. c c\BeginLib c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly c Restarted Arnoldi Iteration", Rice University Technical Report c TR95-13, Department of Computational and Applied Mathematics. c 3. B.N. Parlett & Y. Saad, "Complex Shift and Invert Strategies for c Real Matrices", Linear Algebra and its Applications, vol 88/89, c pp 575-595, (1987). c c\Routines called: c igraphivout ARPACK utility routine that prints integers. c igraphdmout ARPACK utility routine that prints matrices c igraphdvout ARPACK utility routine that prints vectors. c dgeqr2 LAPACK routine that computes the QR factorization of c a matrix. c dlacpy LAPACK matrix copy routine. c dlahqr LAPACK routine to compute the real Schur form of an c upper Hessenberg matrix. c dlamch LAPACK routine that determines machine constants. c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully. c dlaset LAPACK matrix initialization routine. c dorm2r LAPACK routine that applies an orthogonal matrix in c factored form. c dtrevc LAPACK routine to compute the eigenvectors of a matrix c in upper quasi-triangular form. c dtrsen LAPACK routine that re-orders the Schur form. c dtrmm Level 3 BLAS matrix times an upper triangular matrix. c dger Level 2 BLAS rank one update to a matrix. c dcopy Level 1 BLAS that copies one vector to another . c ddot Level 1 BLAS that computes the scalar product of two vectors. c dnrm2 Level 1 BLAS that computes the norm of a vector. c dscal Level 1 BLAS that scales a vector. c c\Remarks c c 1. Currently only HOWMNY = 'A' and 'P' are implemented. c c Let X' denote the transpose of X. c c 2. Schur vectors are an orthogonal representation for the basis of c Ritz vectors. Thus, their numerical properties are often superior. c If RVEC = .TRUE. then the relationship c A * V(:,1:IPARAM(5)) = V(:,1:IPARAM(5)) * T, and c V(:,1:IPARAM(5))' * V(:,1:IPARAM(5)) = I are approximately satisfied. c Here T is the leading submatrix of order IPARAM(5) of the real c upper quasi-triangular matrix stored workl(ipntr(12)). That is, c T is block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; c each 2-by-2 diagonal block has its diagonal elements equal and its c off-diagonal elements of opposite sign. Corresponding to each 2-by-2 c diagonal block is a complex conjugate pair of Ritz values. The real c Ritz values are stored on the diagonal of T. c c 3. If IPARAM(7) = 3 or 4 and SIGMAI is not equal zero, then the user must c form the IPARAM(5) Rayleigh quotients in order to transform the Ritz c values computed by DNAUPD for OP to those of A*z = lambda*B*z. c Set RVEC = .true. and HOWMNY = 'A', and c compute c Z(:,I)' * A * Z(:,I) if DI(I) = 0. c If DI(I) is not equal to zero and DI(I+1) = - D(I), c then the desired real and imaginary parts of the Ritz value are c Z(:,I)' * A * Z(:,I) + Z(:,I+1)' * A * Z(:,I+1), c Z(:,I)' * A * Z(:,I+1) - Z(:,I+1)' * A * Z(:,I), respectively. c Another possibility is to set RVEC = .true. and HOWMNY = 'P' and c compute V(:,1:IPARAM(5))' * A * V(:,1:IPARAM(5)) and then an upper c quasi-triangular matrix of order IPARAM(5) is computed. See remark c 2 above. c c\Authors c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Chao Yang Houston, Texas c Dept. of Computational & c Applied Mathematics c Rice University c Houston, Texas c c\SCCS Information: @(#) c FILE: neupd.F SID: 2.5 DATE OF SID: 7/31/96 RELEASE: 2 c c\EndLib c c----------------------------------------------------------------------- subroutine igraphdneupd (rvec, howmny, select, dr, di, z, ldz, & sigmar, sigmai, workev, bmat, n, which, nev, tol, & resid, ncv, v, ldv, iparam, ipntr, workd, & workl, lworkl, info) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character bmat, howmny, which*2 logical rvec integer info, ldz, ldv, lworkl, n, ncv, nev Double precision & sigmar, sigmai, tol c c %-----------------% c | Array Arguments | c %-----------------% c integer iparam(11), ipntr(14) logical select(ncv) Double precision & dr(nev+1), di(nev+1), resid(n), v(ldv,ncv), z(ldz,*), & workd(3*n), workl(lworkl), workev(3*ncv) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c character type*6 integer bounds, ierr, ih, ihbds, iheigr, iheigi, iconj, nconv, & invsub, iuptri, iwev, iwork(1), j, k, ktrord, & ldh, ldq, mode, msglvl, outncv, ritzr, ritzi, wri, wrr, & irr, iri, ibd logical reord Double precision & conds, rnorm, sep, temp, thres, vl(1,1), temp1, eps23 c c %----------------------% c | External Subroutines | c %----------------------% c external dcopy, dger, dgeqr2, dlacpy, dlahqr, dlaset, & igraphdmout, dorm2r, dtrevc, dtrmm, dtrsen, dscal, & igraphdvout, igraphivout c c %--------------------% c | External Functions | c %--------------------% c Double precision & dlapy2, dnrm2, dlamch, ddot external dlapy2, dnrm2, dlamch, ddot c c %---------------------% c | Intrinsic Functions | c %---------------------% c intrinsic abs, min, sqrt c c %-----------------------% c | Executable Statements | c %-----------------------% c c %------------------------% c | Set default parameters | c %------------------------% c msglvl = mneupd mode = iparam(7) nconv = iparam(5) info = 0 c c %---------------------------------% c | Get machine dependent constant. | c %---------------------------------% c eps23 = dlamch('Epsilon-Machine') eps23 = eps23**(2.0D+0 / 3.0D+0) c c %--------------% c | Quick return | c %--------------% c ierr = 0 c if (nconv .le. 0) then ierr = -14 else if (n .le. 0) then ierr = -1 else if (nev .le. 0) then ierr = -2 else if (ncv .le. nev+1 .or. ncv .gt. n) then ierr = -3 else if (which .ne. 'LM' .and. & which .ne. 'SM' .and. & which .ne. 'LR' .and. & which .ne. 'SR' .and. & which .ne. 'LI' .and. & which .ne. 'SI') then ierr = -5 else if (bmat .ne. 'I' .and. bmat .ne. 'G') then ierr = -6 else if (lworkl .lt. 3*ncv**2 + 6*ncv) then ierr = -7 else if ( (howmny .ne. 'A' .and. & howmny .ne. 'P' .and. & howmny .ne. 'S') .and. rvec ) then ierr = -13 else if (howmny .eq. 'S' ) then ierr = -12 end if c if (mode .eq. 1 .or. mode .eq. 2) then type = 'REGULR' else if (mode .eq. 3 .and. sigmai .eq. zero) then type = 'SHIFTI' else if (mode .eq. 3 ) then type = 'REALPT' else if (mode .eq. 4 ) then type = 'IMAGPT' else ierr = -10 end if if (mode .eq. 1 .and. bmat .eq. 'G') ierr = -11 c c %------------% c | Error Exit | c %------------% c if (ierr .ne. 0) then info = ierr go to 9000 end if c c %--------------------------------------------------------% c | Pointer into WORKL for address of H, RITZ, BOUNDS, Q | c | etc... and the remaining workspace. | c | Also update pointer to be used on output. | c | Memory is laid out as follows: | c | workl(1:ncv*ncv) := generated Hessenberg matrix | c | workl(ncv*ncv+1:ncv*ncv+2*ncv) := real and imaginary | c | parts of ritz values | c | workl(ncv*ncv+2*ncv+1:ncv*ncv+3*ncv) := error bounds | c %--------------------------------------------------------% c c %-----------------------------------------------------------% c | The following is used and set by DNEUPD. | c | workl(ncv*ncv+3*ncv+1:ncv*ncv+4*ncv) := The untransformed | c | real part of the Ritz values. | c | workl(ncv*ncv+4*ncv+1:ncv*ncv+5*ncv) := The untransformed | c | imaginary part of the Ritz values. | c | workl(ncv*ncv+5*ncv+1:ncv*ncv+6*ncv) := The untransformed | c | error bounds of the Ritz values | c | workl(ncv*ncv+6*ncv+1:2*ncv*ncv+6*ncv) := Holds the upper | c | quasi-triangular matrix for H | c | workl(2*ncv*ncv+6*ncv+1: 3*ncv*ncv+6*ncv) := Holds the | c | associated matrix representation of the invariant | c | subspace for H. | c | GRAND total of NCV * ( 3 * NCV + 6 ) locations. | c %-----------------------------------------------------------% c ih = ipntr(5) ritzr = ipntr(6) ritzi = ipntr(7) bounds = ipntr(8) ldh = ncv ldq = ncv iheigr = bounds + ldh iheigi = iheigr + ldh ihbds = iheigi + ldh iuptri = ihbds + ldh invsub = iuptri + ldh*ncv ipntr(9) = iheigr ipntr(10) = iheigi ipntr(11) = ihbds ipntr(12) = iuptri ipntr(13) = invsub wrr = 1 wri = ncv + 1 iwev = wri + ncv c c %-----------------------------------------% c | irr points to the REAL part of the Ritz | c | values computed by _neigh before | c | exiting _naup2. | c | iri points to the IMAGINARY part of the | c | Ritz values computed by _neigh | c | before exiting _naup2. | c | ibd points to the Ritz estimates | c | computed by _neigh before exiting | c | _naup2. | c %-----------------------------------------% c irr = ipntr(14)+ncv*ncv iri = irr+ncv ibd = iri+ncv c c %------------------------------------% c | RNORM is B-norm of the RESID(1:N). | c %------------------------------------% c rnorm = workl(ih+2) workl(ih+2) = zero c if (rvec) then c c %-------------------------------------------% c | Get converged Ritz value on the boundary. | c | Note: converged Ritz values have been | c | placed in the first NCONV locations in | c | workl(ritzr) and workl(ritzi). They have | c | been sorted (in _naup2) according to the | c | WHICH selection criterion. | c %-------------------------------------------% c if (which .eq. 'LM' .or. which .eq. 'SM') then thres = dlapy2( workl(ritzr), workl(ritzi) ) else if (which .eq. 'LR' .or. which .eq. 'SR') then thres = workl(ritzr) else if (which .eq. 'LI' .or. which .eq. 'SI') then thres = abs( workl(ritzi) ) end if c if (msglvl .gt. 2) then call igraphdvout(logfil, 1, [thres], ndigit, & '_neupd: Threshold eigenvalue used for re-ordering') end if c c %----------------------------------------------------------% c | Check to see if all converged Ritz values appear at the | c | top of the upper quasi-triangular matrix computed by | c | _neigh in _naup2. This is done in the following way: | c | | c | 1) For each Ritz value obtained from _neigh, compare it | c | with the threshold Ritz value computed above to | c | determine whether it is a wanted one. | c | | c | 2) If it is wanted, then check the corresponding Ritz | c | estimate to see if it has converged. If it has, set | c | correponding entry in the logical array SELECT to | c | .TRUE.. | c | | c | If SELECT(j) = .TRUE. and j > NCONV, then there is a | c | converged Ritz value that does not appear at the top of | c | the upper quasi-triangular matrix computed by _neigh in | c | _naup2. Reordering is needed. | c %----------------------------------------------------------% c reord = .false. ktrord = 0 do 10 j = 0, ncv-1 select(j+1) = .false. if (which .eq. 'LM') then if (dlapy2(workl(irr+j), workl(iri+j)) & .ge. thres) then temp1 = max( eps23, & dlapy2( workl(irr+j), workl(iri+j) ) ) if (workl(ibd+j) .le. tol*temp1) & select(j+1) = .true. end if else if (which .eq. 'SM') then if (dlapy2(workl(irr+j), workl(iri+j)) & .le. thres) then temp1 = max( eps23, & dlapy2( workl(irr+j), workl(iri+j) ) ) if (workl(ibd+j) .le. tol*temp1) & select(j+1) = .true. end if else if (which .eq. 'LR') then if (workl(irr+j) .ge. thres) then temp1 = max( eps23, & dlapy2( workl(irr+j), workl(iri+j) ) ) if (workl(ibd+j) .le. tol*temp1) & select(j+1) = .true. end if else if (which .eq. 'SR') then if (workl(irr+j) .le. thres) then temp1 = max( eps23, & dlapy2( workl(irr+j), workl(iri+j) ) ) if (workl(ibd+j) .le. tol*temp1) & select(j+1) = .true. end if else if (which .eq. 'LI') then if (abs(workl(iri+j)) .ge. thres) then temp1 = max( eps23, & dlapy2( workl(irr+j), workl(iri+j) ) ) if (workl(ibd+j) .le. tol*temp1) & select(j+1) = .true. end if else if (which .eq. 'SI') then if (abs(workl(iri+j)) .le. thres) then temp1 = max( eps23, & dlapy2( workl(irr+j), workl(iri+j) ) ) if (workl(ibd+j) .le. tol*temp1) & select(j+1) = .true. end if end if if (j+1 .gt. nconv ) reord = ( select(j+1) .or. reord ) if (select(j+1)) ktrord = ktrord + 1 10 continue c if (msglvl .gt. 2) then call igraphivout(logfil, 1, [ktrord], ndigit, & '_neupd: Number of specified eigenvalues') call igraphivout(logfil, 1, [nconv], ndigit, & '_neupd: Number of "converged" eigenvalues') end if c c %-----------------------------------------------------------% c | Call LAPACK routine dlahqr to compute the real Schur form | c | of the upper Hessenberg matrix returned by DNAUPD. | c | Make a copy of the upper Hessenberg matrix. | c | Initialize the Schur vector matrix Q to the identity. | c %-----------------------------------------------------------% c call dcopy (ldh*ncv, workl(ih), 1, workl(iuptri), 1) call dlaset ('All', ncv, ncv, zero, one, workl(invsub), ldq) call dlahqr (.true., .true., ncv, 1, ncv, workl(iuptri), ldh, & workl(iheigr), workl(iheigi), 1, ncv, & workl(invsub), ldq, ierr) call dcopy (ncv, workl(invsub+ncv-1), ldq, workl(ihbds), 1) c if (ierr .ne. 0) then info = -8 go to 9000 end if c if (msglvl .gt. 1) then call igraphdvout (logfil, ncv, workl(iheigr), ndigit, & '_neupd: Real part of the eigenvalues of H') call igraphdvout (logfil, ncv, workl(iheigi), ndigit, & '_neupd: Imaginary part of the Eigenvalues of H') call igraphdvout (logfil, ncv, workl(ihbds), ndigit, & '_neupd: Last row of the Schur vector matrix') if (msglvl .gt. 3) then call igraphdmout (logfil, ncv, ncv, workl(iuptri), ldh, & ndigit, & '_neupd: The upper quasi-triangular matrix ') end if end if c if (reord) then c c %-----------------------------------------------------% c | Reorder the computed upper quasi-triangular matrix. | c %-----------------------------------------------------% c call dtrsen ('None', 'V', select, ncv, workl(iuptri), ldh, & workl(invsub), ldq, workl(iheigr), workl(iheigi), & nconv, conds, sep, workl(ihbds), ncv, iwork, 1, ierr) c if (ierr .eq. 1) then info = 1 go to 9000 end if c if (msglvl .gt. 2) then call igraphdvout (logfil, ncv, workl(iheigr), ndigit, & '_neupd: Real part of the eigenvalues of H--reordered') call igraphdvout (logfil, ncv, workl(iheigi), ndigit, & '_neupd: Imag part of the eigenvalues of H--reordered') if (msglvl .gt. 3) then call igraphdmout (logfil, ncv, ncv, workl(iuptri), & ldq, ndigit, & '_neupd: Quasi-triangular matrix after re-ordering') end if end if c end if c c %---------------------------------------% c | Copy the last row of the Schur vector | c | into workl(ihbds). This will be used | c | to compute the Ritz estimates of | c | converged Ritz values. | c %---------------------------------------% c call dcopy(ncv, workl(invsub+ncv-1), ldq, workl(ihbds), 1) c c %----------------------------------------------------% c | Place the computed eigenvalues of H into DR and DI | c | if a spectral transformation was not used. | c %----------------------------------------------------% c if (type .eq. 'REGULR') then call dcopy (nconv, workl(iheigr), 1, dr, 1) call dcopy (nconv, workl(iheigi), 1, di, 1) end if c c %----------------------------------------------------------% c | Compute the QR factorization of the matrix representing | c | the wanted invariant subspace located in the first NCONV | c | columns of workl(invsub,ldq). | c %----------------------------------------------------------% c call dgeqr2 (ncv, nconv, workl(invsub), ldq, workev, & workev(ncv+1), ierr) c c %---------------------------------------------------------% c | * Postmultiply V by Q using dorm2r. | c | * Copy the first NCONV columns of VQ into Z. | c | * Postmultiply Z by R. | c | The N by NCONV matrix Z is now a matrix representation | c | of the approximate invariant subspace associated with | c | the Ritz values in workl(iheigr) and workl(iheigi) | c | The first NCONV columns of V are now approximate Schur | c | vectors associated with the real upper quasi-triangular | c | matrix of order NCONV in workl(iuptri) | c %---------------------------------------------------------% c call dorm2r ('Right', 'Notranspose', n, ncv, nconv, & workl(invsub), ldq, workev, v, ldv, workd(n+1), ierr) call dlacpy ('All', n, nconv, v, ldv, z, ldz) c do 20 j=1, nconv c c %---------------------------------------------------% c | Perform both a column and row scaling if the | c | diagonal element of workl(invsub,ldq) is negative | c | I'm lazy and don't take advantage of the upper | c | quasi-triangular form of workl(iuptri,ldq) | c | Note that since Q is orthogonal, R is a diagonal | c | matrix consisting of plus or minus ones | c %---------------------------------------------------% c if (workl(invsub+(j-1)*ldq+j-1) .lt. zero) then call dscal (nconv, -one, workl(iuptri+j-1), ldq) call dscal (nconv, -one, workl(iuptri+(j-1)*ldq), 1) end if c 20 continue c if (howmny .eq. 'A') then c c %--------------------------------------------% c | Compute the NCONV wanted eigenvectors of T | c | located in workl(iuptri,ldq). | c %--------------------------------------------% c do 30 j=1, ncv if (j .le. nconv) then select(j) = .true. else select(j) = .false. end if 30 continue c call dtrevc ('Right', 'Select', select, ncv, workl(iuptri), & ldq, vl, 1, workl(invsub), ldq, ncv, outncv, workev, & ierr) c if (ierr .ne. 0) then info = -9 go to 9000 end if c c %------------------------------------------------% c | Scale the returning eigenvectors so that their | c | Euclidean norms are all one. LAPACK subroutine | c | dtrevc returns each eigenvector normalized so | c | that the element of largest magnitude has | c | magnitude 1; | c %------------------------------------------------% c iconj = 0 do 40 j=1, nconv c if ( workl(iheigi+j-1) .eq. zero ) then c c %----------------------% c | real eigenvalue case | c %----------------------% c temp = dnrm2( ncv, workl(invsub+(j-1)*ldq), 1 ) call dscal ( ncv, one / temp, & workl(invsub+(j-1)*ldq), 1 ) c else c c %-------------------------------------------% c | Complex conjugate pair case. Note that | c | since the real and imaginary part of | c | the eigenvector are stored in consecutive | c | columns, we further normalize by the | c | square root of two. | c %-------------------------------------------% c if (iconj .eq. 0) then temp = dlapy2( dnrm2( ncv, workl(invsub+(j-1)*ldq), & 1 ), dnrm2( ncv, workl(invsub+j*ldq), 1) ) call dscal ( ncv, one / temp, & workl(invsub+(j-1)*ldq), 1 ) call dscal ( ncv, one / temp, & workl(invsub+j*ldq), 1 ) iconj = 1 else iconj = 0 end if c end if c 40 continue c call dgemv('T', ncv, nconv, one, workl(invsub), & ldq, workl(ihbds), 1, zero, workev, 1) c iconj = 0 do 45 j=1, nconv if (workl(iheigi+j-1) .ne. zero) then c c %-------------------------------------------% c | Complex conjugate pair case. Note that | c | since the real and imaginary part of | c | the eigenvector are stored in consecutive | c %-------------------------------------------% c if (iconj .eq. 0) then workev(j) = dlapy2(workev(j), workev(j+1)) workev(j+1) = workev(j) iconj = 1 else iconj = 0 end if end if 45 continue c if (msglvl .gt. 2) then call dcopy(ncv, workl(invsub+ncv-1), ldq, & workl(ihbds), 1) call igraphdvout (logfil, ncv, workl(ihbds), ndigit, & '_neupd: Last row of the eigenvector matrix for T') if (msglvl .gt. 3) then call igraphdmout (logfil, ncv, ncv, workl(invsub), & ldq, ndigit, & '_neupd: The eigenvector matrix for T') end if end if c c %---------------------------------------% c | Copy Ritz estimates into workl(ihbds) | c %---------------------------------------% c call dcopy(nconv, workev, 1, workl(ihbds), 1) c c %---------------------------------------------------------% c | Compute the QR factorization of the eigenvector matrix | c | associated with leading portion of T in the first NCONV | c | columns of workl(invsub,ldq). | c %---------------------------------------------------------% c call dgeqr2 (ncv, nconv, workl(invsub), ldq, workev, & workev(ncv+1), ierr) c c %----------------------------------------------% c | * Postmultiply Z by Q. | c | * Postmultiply Z by R. | c | The N by NCONV matrix Z is now contains the | c | Ritz vectors associated with the Ritz values | c | in workl(iheigr) and workl(iheigi). | c %----------------------------------------------% c call dorm2r ('Right', 'Notranspose', n, ncv, nconv, & workl(invsub), ldq, workev, z, ldz, workd(n+1), ierr) c call dtrmm ('Right', 'Upper', 'No transpose', 'Non-unit', & n, nconv, one, workl(invsub), ldq, z, ldz) c end if c else c c %------------------------------------------------------% c | An approximate invariant subspace is not needed. | c | Place the Ritz values computed DNAUPD into DR and DI | c %------------------------------------------------------% c call dcopy (nconv, workl(ritzr), 1, dr, 1) call dcopy (nconv, workl(ritzi), 1, di, 1) call dcopy (nconv, workl(ritzr), 1, workl(iheigr), 1) call dcopy (nconv, workl(ritzi), 1, workl(iheigi), 1) call dcopy (nconv, workl(bounds), 1, workl(ihbds), 1) end if c c %------------------------------------------------% c | Transform the Ritz values and possibly vectors | c | and corresponding error bounds of OP to those | c | of A*x = lambda*B*x. | c %------------------------------------------------% c if (type .eq. 'REGULR') then c if (rvec) & call dscal (ncv, rnorm, workl(ihbds), 1) c else c c %---------------------------------------% c | A spectral transformation was used. | c | * Determine the Ritz estimates of the | c | Ritz values in the original system. | c %---------------------------------------% c if (type .eq. 'SHIFTI') then c if (rvec) & call dscal (ncv, rnorm, workl(ihbds), 1) c do 50 k=1, ncv temp = dlapy2( workl(iheigr+k-1), & workl(iheigi+k-1) ) workl(ihbds+k-1) = abs( workl(ihbds+k-1) ) & / temp / temp 50 continue c else if (type .eq. 'REALPT') then c do 60 k=1, ncv 60 continue c else if (type .eq. 'IMAGPT') then c do 70 k=1, ncv 70 continue c end if c c %-----------------------------------------------------------% c | * Transform the Ritz values back to the original system. | c | For TYPE = 'SHIFTI' the transformation is | c | lambda = 1/theta + sigma | c | For TYPE = 'REALPT' or 'IMAGPT' the user must from | c | Rayleigh quotients or a projection. See remark 3 above.| c | NOTES: | c | *The Ritz vectors are not affected by the transformation. | c %-----------------------------------------------------------% c if (type .eq. 'SHIFTI') then c do 80 k=1, ncv temp = dlapy2( workl(iheigr+k-1), & workl(iheigi+k-1) ) workl(iheigr+k-1) = workl(iheigr+k-1) / temp / temp & + sigmar workl(iheigi+k-1) = -workl(iheigi+k-1) / temp / temp & + sigmai 80 continue c call dcopy (nconv, workl(iheigr), 1, dr, 1) call dcopy (nconv, workl(iheigi), 1, di, 1) c else if (type .eq. 'REALPT' .or. type .eq. 'IMAGPT') then c call dcopy (nconv, workl(iheigr), 1, dr, 1) call dcopy (nconv, workl(iheigi), 1, di, 1) c end if c end if c if (type .eq. 'SHIFTI' .and. msglvl .gt. 1) then call igraphdvout (logfil, nconv, dr, ndigit, & '_neupd: Untransformed real part of the Ritz valuess.') call igraphdvout (logfil, nconv, di, ndigit, & '_neupd: Untransformed imag part of the Ritz valuess.') call igraphdvout (logfil, nconv, workl(ihbds), ndigit, & '_neupd: Ritz estimates of untransformed Ritz values.') else if (type .eq. 'REGULR' .and. msglvl .gt. 1) then call igraphdvout (logfil, nconv, dr, ndigit, & '_neupd: Real parts of converged Ritz values.') call igraphdvout (logfil, nconv, di, ndigit, & '_neupd: Imag parts of converged Ritz values.') call igraphdvout (logfil, nconv, workl(ihbds), ndigit, & '_neupd: Associated Ritz estimates.') end if c c %-------------------------------------------------% c | Eigenvector Purification step. Formally perform | c | one of inverse subspace iteration. Only used | c | for MODE = 2. | c %-------------------------------------------------% c if (rvec .and. howmny .eq. 'A' .and. type .eq. 'SHIFTI') then c c %------------------------------------------------% c | Purify the computed Ritz vectors by adding a | c | little bit of the residual vector: | c | T | c | resid(:)*( e s ) / theta | c | NCV | c | where H s = s theta. Remember that when theta | c | has nonzero imaginary part, the corresponding | c | Ritz vector is stored across two columns of Z. | c %------------------------------------------------% c iconj = 0 do 110 j=1, nconv if (workl(iheigi+j-1) .eq. zero) then workev(j) = workl(invsub+(j-1)*ldq+ncv-1) / & workl(iheigr+j-1) else if (iconj .eq. 0) then temp = dlapy2( workl(iheigr+j-1), workl(iheigi+j-1) ) workev(j) = ( workl(invsub+(j-1)*ldq+ncv-1) * & workl(iheigr+j-1) + & workl(invsub+j*ldq+ncv-1) * & workl(iheigi+j-1) ) / temp / temp workev(j+1) = ( workl(invsub+j*ldq+ncv-1) * & workl(iheigr+j-1) - & workl(invsub+(j-1)*ldq+ncv-1) * & workl(iheigi+j-1) ) / temp / temp iconj = 1 else iconj = 0 end if 110 continue c c %---------------------------------------% c | Perform a rank one update to Z and | c | purify all the Ritz vectors together. | c %---------------------------------------% c call dger (n, nconv, one, resid, 1, workev, 1, z, ldz) c end if c 9000 continue c return c c %---------------% c | End of DNEUPD | c %---------------% c end leidenbase/src/vendor/arpack/dnapps.f0000644000176200001440000005616114447675376017366 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdnapps c c\Description: c Given the Arnoldi factorization c c A*V_{k} - V_{k}*H_{k} = r_{k+p}*e_{k+p}^T, c c apply NP implicit shifts resulting in c c A*(V_{k}*Q) - (V_{k}*Q)*(Q^T* H_{k}*Q) = r_{k+p}*e_{k+p}^T * Q c c where Q is an orthogonal matrix which is the product of rotations c and reflections resulting from the NP bulge chage sweeps. c The updated Arnoldi factorization becomes: c c A*VNEW_{k} - VNEW_{k}*HNEW_{k} = rnew_{k}*e_{k}^T. c c\Usage: c call igraphdnapps c ( N, KEV, NP, SHIFTR, SHIFTI, V, LDV, H, LDH, RESID, Q, LDQ, c WORKL, WORKD ) c c\Arguments c N Integer. (INPUT) c Problem size, i.e. size of matrix A. c c KEV Integer. (INPUT/OUTPUT) c KEV+NP is the size of the input matrix H. c KEV is the size of the updated matrix HNEW. KEV is only c updated on ouput when fewer than NP shifts are applied in c order to keep the conjugate pair together. c c NP Integer. (INPUT) c Number of implicit shifts to be applied. c c SHIFTR, Double precision array of length NP. (INPUT) c SHIFTI Real and imaginary part of the shifts to be applied. c Upon, entry to igraphdnapps, the shifts must be sorted so that the c conjugate pairs are in consecutive locations. c c V Double precision N by (KEV+NP) array. (INPUT/OUTPUT) c On INPUT, V contains the current KEV+NP Arnoldi vectors. c On OUTPUT, V contains the updated KEV Arnoldi vectors c in the first KEV columns of V. c c LDV Integer. (INPUT) c Leading dimension of V exactly as declared in the calling c program. c c H Double precision (KEV+NP) by (KEV+NP) array. (INPUT/OUTPUT) c On INPUT, H contains the current KEV+NP by KEV+NP upper c Hessenber matrix of the Arnoldi factorization. c On OUTPUT, H contains the updated KEV by KEV upper Hessenberg c matrix in the KEV leading submatrix. c c LDH Integer. (INPUT) c Leading dimension of H exactly as declared in the calling c program. c c RESID Double precision array of length N. (INPUT/OUTPUT) c On INPUT, RESID contains the the residual vector r_{k+p}. c On OUTPUT, RESID is the update residual vector rnew_{k} c in the first KEV locations. c c Q Double precision KEV+NP by KEV+NP work array. (WORKSPACE) c Work array used to accumulate the rotations and reflections c during the bulge chase sweep. c c LDQ Integer. (INPUT) c Leading dimension of Q exactly as declared in the calling c program. c c WORKL Double precision work array of length (KEV+NP). (WORKSPACE) c Private (replicated) array on each PE or array allocated on c the front end. c c WORKD Double precision work array of length 2*N. (WORKSPACE) c Distributed array used in the application of the accumulated c orthogonal matrix Q. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c c\Routines called: c igraphivout ARPACK utility routine that prints integers. c igraphsecond ARPACK utility routine for timing. c igraphdmout ARPACK utility routine that prints matrices. c igraphdvout ARPACK utility routine that prints vectors. c dlabad LAPACK routine that computes machine constants. c dlacpy LAPACK matrix copy routine. c dlamch LAPACK routine that determines machine constants. c dlanhs LAPACK routine that computes various norms of a matrix. c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully. c dlarf LAPACK routine that applies Householder reflection to c a matrix. c dlarfg LAPACK Householder reflection construction routine. c dlartg LAPACK Givens rotation construction routine. c dlaset LAPACK matrix initialization routine. c dgemv Level 2 BLAS routine for matrix vector multiplication. c daxpy Level 1 BLAS that computes a vector triad. c dcopy Level 1 BLAS that copies one vector to another . c dscal Level 1 BLAS that scales a vector. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/92: Version ' 2.1' c c\SCCS Information: @(#) c FILE: napps.F SID: 2.3 DATE OF SID: 4/20/96 RELEASE: 2 c c\Remarks c 1. In this version, each shift is applied to all the sublocks of c the Hessenberg matrix H and not just to the submatrix that it c comes from. Deflation as in LAPACK routine dlahqr (QR algorithm c for upper Hessenberg matrices ) is used. c The subdiagonals of H are enforced to be non-negative. c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdnapps & ( n, kev, np, shiftr, shifti, v, ldv, h, ldh, resid, q, ldq, & workl, workd ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c integer kev, ldh, ldq, ldv, n, np c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & h(ldh,kev+np), resid(n), shifti(np), shiftr(np), & v(ldv,kev+np), q(ldq,kev+np), workd(2*n), workl(kev+np) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %------------------------% c | Local Scalars & Arrays | c %------------------------% c integer i, iend, ir, istart, j, jj, kplusp, msglvl, nr logical cconj, first Double precision & c, f, g, h11, h12, h21, h22, h32, ovfl, r, s, sigmai, & sigmar, smlnum, ulp, unfl, u(3), t, tau, tst1 save first, ovfl, smlnum, ulp, unfl c c %----------------------% c | External Subroutines | c %----------------------% c external daxpy, dcopy, dscal, dlacpy, dlarfg, dlarf, & dlaset, dlabad, igraphsecond, dlartg c c %--------------------% c | External Functions | c %--------------------% c Double precision & dlamch, dlanhs, dlapy2 external dlamch, dlanhs, dlapy2 c c %----------------------% c | Intrinsics Functions | c %----------------------% c intrinsic abs, max, min c c %----------------% c | Data statments | c %----------------% c data first / .true. / c c %-----------------------% c | Executable Statements | c %-----------------------% c if (first) then c c %-----------------------------------------------% c | Set machine-dependent constants for the | c | stopping criterion. If norm(H) <= sqrt(OVFL), | c | overflow should not occur. | c | REFERENCE: LAPACK subroutine dlahqr | c %-----------------------------------------------% c unfl = dlamch( 'safe minimum' ) ovfl = one / unfl call dlabad( unfl, ovfl ) ulp = dlamch( 'precision' ) smlnum = unfl*( n / ulp ) first = .false. end if c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = mnapps kplusp = kev + np c c %--------------------------------------------% c | Initialize Q to the identity to accumulate | c | the rotations and reflections | c %--------------------------------------------% c call dlaset ('All', kplusp, kplusp, zero, one, q, ldq) c c %----------------------------------------------% c | Quick return if there are no shifts to apply | c %----------------------------------------------% c if (np .eq. 0) go to 9000 c c %----------------------------------------------% c | Chase the bulge with the application of each | c | implicit shift. Each shift is applied to the | c | whole matrix including each block. | c %----------------------------------------------% c cconj = .false. do 110 jj = 1, np sigmar = shiftr(jj) sigmai = shifti(jj) c if (msglvl .gt. 2 ) then call igraphivout (logfil, 1, [jj], ndigit, & '_napps: shift number.') call igraphdvout (logfil, 1, [sigmar], ndigit, & '_napps: The real part of the shift ') call igraphdvout (logfil, 1, [sigmai], ndigit, & '_napps: The imaginary part of the shift ') end if c c %-------------------------------------------------% c | The following set of conditionals is necessary | c | in order that complex conjugate pairs of shifts | c | are applied together or not at all. | c %-------------------------------------------------% c if ( cconj ) then c c %-----------------------------------------% c | cconj = .true. means the previous shift | c | had non-zero imaginary part. | c %-----------------------------------------% c cconj = .false. go to 110 else if ( jj .lt. np .and. abs( sigmai ) .gt. zero ) then c c %------------------------------------% c | Start of a complex conjugate pair. | c %------------------------------------% c cconj = .true. else if ( jj .eq. np .and. abs( sigmai ) .gt. zero ) then c c %----------------------------------------------% c | The last shift has a nonzero imaginary part. | c | Don't apply it; thus the order of the | c | compressed H is order KEV+1 since only np-1 | c | were applied. | c %----------------------------------------------% c kev = kev + 1 go to 110 end if istart = 1 20 continue c c %--------------------------------------------------% c | if sigmai = 0 then | c | Apply the jj-th shift ... | c | else | c | Apply the jj-th and (jj+1)-th together ... | c | (Note that jj < np at this point in the code) | c | end | c | to the current block of H. The next do loop | c | determines the current block ; | c %--------------------------------------------------% c do 30 i = istart, kplusp-1 c c %----------------------------------------% c | Check for splitting and deflation. Use | c | a standard test as in the QR algorithm | c | REFERENCE: LAPACK subroutine dlahqr | c %----------------------------------------% c tst1 = abs( h( i, i ) ) + abs( h( i+1, i+1 ) ) if( tst1.eq.zero ) & tst1 = dlanhs( '1', kplusp-jj+1, h, ldh, workl ) if( abs( h( i+1,i ) ).le.max( ulp*tst1, smlnum ) ) then if (msglvl .gt. 0) then call igraphivout (logfil, 1, [i], ndigit, & '_napps: matrix splitting at row/column no.') call igraphivout (logfil, 1, [jj], ndigit, & '_napps: matrix splitting with shift number.') call igraphdvout (logfil, 1, h(i+1,i), ndigit, & '_napps: off diagonal element.') end if iend = i h(i+1,i) = zero go to 40 end if 30 continue iend = kplusp 40 continue c if (msglvl .gt. 2) then call igraphivout (logfil, 1, [istart], ndigit, & '_napps: Start of current block ') call igraphivout (logfil, 1, [iend], ndigit, & '_napps: End of current block ') end if c c %------------------------------------------------% c | No reason to apply a shift to block of order 1 | c %------------------------------------------------% c if ( istart .eq. iend ) go to 100 c c %------------------------------------------------------% c | If istart + 1 = iend then no reason to apply a | c | complex conjugate pair of shifts on a 2 by 2 matrix. | c %------------------------------------------------------% c if ( istart + 1 .eq. iend .and. abs( sigmai ) .gt. zero ) & go to 100 c h11 = h(istart,istart) h21 = h(istart+1,istart) if ( abs( sigmai ) .le. zero ) then c c %---------------------------------------------% c | Real-valued shift ==> apply single shift QR | c %---------------------------------------------% c f = h11 - sigmar g = h21 c do 80 i = istart, iend-1 c c %-----------------------------------------------------% c | Contruct the plane rotation G to zero out the bulge | c %-----------------------------------------------------% c call dlartg (f, g, c, s, r) if (i .gt. istart) then c c %-------------------------------------------% c | The following ensures that h(1:iend-1,1), | c | the first iend-2 off diagonal of elements | c | H, remain non negative. | c %-------------------------------------------% c if (r .lt. zero) then r = -r c = -c s = -s end if h(i,i-1) = r h(i+1,i-1) = zero end if c c %---------------------------------------------% c | Apply rotation to the left of H; H <- G'*H | c %---------------------------------------------% c do 50 j = i, kplusp t = c*h(i,j) + s*h(i+1,j) h(i+1,j) = -s*h(i,j) + c*h(i+1,j) h(i,j) = t 50 continue c c %---------------------------------------------% c | Apply rotation to the right of H; H <- H*G | c %---------------------------------------------% c do 60 j = 1, min(i+2,iend) t = c*h(j,i) + s*h(j,i+1) h(j,i+1) = -s*h(j,i) + c*h(j,i+1) h(j,i) = t 60 continue c c %----------------------------------------------------% c | Accumulate the rotation in the matrix Q; Q <- Q*G | c %----------------------------------------------------% c do 70 j = 1, min( j+jj, kplusp ) t = c*q(j,i) + s*q(j,i+1) q(j,i+1) = - s*q(j,i) + c*q(j,i+1) q(j,i) = t 70 continue c c %---------------------------% c | Prepare for next rotation | c %---------------------------% c if (i .lt. iend-1) then f = h(i+1,i) g = h(i+2,i) end if 80 continue c c %-----------------------------------% c | Finished applying the real shift. | c %-----------------------------------% c else c c %----------------------------------------------------% c | Complex conjugate shifts ==> apply double shift QR | c %----------------------------------------------------% c h12 = h(istart,istart+1) h22 = h(istart+1,istart+1) h32 = h(istart+2,istart+1) c c %---------------------------------------------------------% c | Compute 1st column of (H - shift*I)*(H - conj(shift)*I) | c %---------------------------------------------------------% c s = 2.0*sigmar t = dlapy2 ( sigmar, sigmai ) u(1) = ( h11 * (h11 - s) + t * t ) / h21 + h12 u(2) = h11 + h22 - s u(3) = h32 c do 90 i = istart, iend-1 c nr = min ( 3, iend-i+1 ) c c %-----------------------------------------------------% c | Construct Householder reflector G to zero out u(1). | c | G is of the form I - tau*( 1 u )' * ( 1 u' ). | c %-----------------------------------------------------% c call dlarfg ( nr, u(1), u(2), 1, tau ) c if (i .gt. istart) then h(i,i-1) = u(1) h(i+1,i-1) = zero if (i .lt. iend-1) h(i+2,i-1) = zero end if u(1) = one c c %--------------------------------------% c | Apply the reflector to the left of H | c %--------------------------------------% c call dlarf ('Left', nr, kplusp-i+1, u, 1, tau, & h(i,i), ldh, workl) c c %---------------------------------------% c | Apply the reflector to the right of H | c %---------------------------------------% c ir = min ( i+3, iend ) call dlarf ('Right', ir, nr, u, 1, tau, & h(1,i), ldh, workl) c c %-----------------------------------------------------% c | Accumulate the reflector in the matrix Q; Q <- Q*G | c %-----------------------------------------------------% c call dlarf ('Right', kplusp, nr, u, 1, tau, & q(1,i), ldq, workl) c c %----------------------------% c | Prepare for next reflector | c %----------------------------% c if (i .lt. iend-1) then u(1) = h(i+1,i) u(2) = h(i+2,i) if (i .lt. iend-2) u(3) = h(i+3,i) end if c 90 continue c c %--------------------------------------------% c | Finished applying a complex pair of shifts | c | to the current block | c %--------------------------------------------% c end if c 100 continue c c %---------------------------------------------------------% c | Apply the same shift to the next block if there is any. | c %---------------------------------------------------------% c istart = iend + 1 if (iend .lt. kplusp) go to 20 c c %---------------------------------------------% c | Loop back to the top to get the next shift. | c %---------------------------------------------% c 110 continue c c %--------------------------------------------------% c | Perform a similarity transformation that makes | c | sure that H will have non negative sub diagonals | c %--------------------------------------------------% c do 120 j=1,kev if ( h(j+1,j) .lt. zero ) then call dscal( kplusp-j+1, -one, h(j+1,j), ldh ) call dscal( min(j+2, kplusp), -one, h(1,j+1), 1 ) call dscal( min(j+np+1,kplusp), -one, q(1,j+1), 1 ) end if 120 continue c do 130 i = 1, kev c c %--------------------------------------------% c | Final check for splitting and deflation. | c | Use a standard test as in the QR algorithm | c | REFERENCE: LAPACK subroutine dlahqr | c %--------------------------------------------% c tst1 = abs( h( i, i ) ) + abs( h( i+1, i+1 ) ) if( tst1.eq.zero ) & tst1 = dlanhs( '1', kev, h, ldh, workl ) if( h( i+1,i ) .le. max( ulp*tst1, smlnum ) ) & h(i+1,i) = zero 130 continue c c %-------------------------------------------------% c | Compute the (kev+1)-st column of (V*Q) and | c | temporarily store the result in WORKD(N+1:2*N). | c | This is needed in the residual update since we | c | cannot GUARANTEE that the corresponding entry | c | of H would be zero as in exact arithmetic. | c %-------------------------------------------------% c if (h(kev+1,kev) .gt. zero) & call dgemv ('N', n, kplusp, one, v, ldv, q(1,kev+1), 1, zero, & workd(n+1), 1) c c %----------------------------------------------------------% c | Compute column 1 to kev of (V*Q) in backward order | c | taking advantage of the upper Hessenberg structure of Q. | c %----------------------------------------------------------% c do 140 i = 1, kev call dgemv ('N', n, kplusp-i+1, one, v, ldv, & q(1,kev-i+1), 1, zero, workd, 1) call dcopy (n, workd, 1, v(1,kplusp-i+1), 1) 140 continue c c %-------------------------------------------------% c | Move v(:,kplusp-kev+1:kplusp) into v(:,1:kev). | c %-------------------------------------------------% c call dlacpy ('A', n, kev, v(1,kplusp-kev+1), ldv, v, ldv) c c %--------------------------------------------------------------% c | Copy the (kev+1)-st column of (V*Q) in the appropriate place | c %--------------------------------------------------------------% c if (h(kev+1,kev) .gt. zero) & call dcopy (n, workd(n+1), 1, v(1,kev+1), 1) c c %-------------------------------------% c | Update the residual vector: | c | r <- sigmak*r + betak*v(:,kev+1) | c | where | c | sigmak = (e_{kplusp}'*Q)*e_{kev} | c | betak = e_{kev+1}'*H*e_{kev} | c %-------------------------------------% c call dscal (n, q(kplusp,kev), resid, 1) if (h(kev+1,kev) .gt. zero) & call daxpy (n, h(kev+1,kev), v(1,kev+1), 1, resid, 1) c if (msglvl .gt. 1) then call igraphdvout (logfil, 1, q(kplusp,kev), ndigit, & '_napps: sigmak = (e_{kev+p}^T*Q)*e_{kev}') call igraphdvout (logfil, 1, h(kev+1,kev), ndigit, & '_napps: betak = e_{kev+1}^T*H*e_{kev}') call igraphivout (logfil, 1, [kev], ndigit, & '_napps: Order of the final Hessenberg matrix ') if (msglvl .gt. 2) then call igraphdmout (logfil, kev, kev, h, ldh, ndigit, & '_napps: updated Hessenberg matrix H for next iteration') end if c end if c 9000 continue call igraphsecond (t1) tnapps = tnapps + (t1 - t0) c return c c %---------------% c | End of igraphdnapps | c %---------------% c end leidenbase/src/vendor/arpack/dsesrt.f0000644000176200001440000001242614447675376017401 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdsesrt c c\Description: c Sort the array X in the order specified by WHICH and optionally c apply the permutation to the columns of the matrix A. c c\Usage: c call igraphdsesrt c ( WHICH, APPLY, N, X, NA, A, LDA) c c\Arguments c WHICH Character*2. (Input) c 'LM' -> X is sorted into increasing order of magnitude. c 'SM' -> X is sorted into decreasing order of magnitude. c 'LA' -> X is sorted into increasing order of algebraic. c 'SA' -> X is sorted into decreasing order of algebraic. c c APPLY Logical. (Input) c APPLY = .TRUE. -> apply the sorted order to A. c APPLY = .FALSE. -> do not apply the sorted order to A. c c N Integer. (INPUT) c Dimension of the array X. c c X Double precision array of length N. (INPUT/OUTPUT) c The array to be sorted. c c NA Integer. (INPUT) c Number of rows of the matrix A. c c A Double precision array of length NA by N. (INPUT/OUTPUT) c c LDA Integer. (INPUT) c Leading dimension of A. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Routines c dswap Level 1 BLAS that swaps the contents of two vectors. c c\Authors c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c 12/15/93: Version ' 2.1'. c Adapted from the sort routine in LANSO and c the ARPACK code igraphdsortr c c\SCCS Information: @(#) c FILE: sesrt.F SID: 2.3 DATE OF SID: 4/19/96 RELEASE: 2 c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdsesrt (which, apply, n, x, na, a, lda) c c %------------------% c | Scalar Arguments | c %------------------% c character*2 which logical apply integer lda, n, na c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & x(0:n-1), a(lda, 0:n-1) c c %---------------% c | Local Scalars | c %---------------% c integer i, igap, j Double precision & temp c c %----------------------% c | External Subroutines | c %----------------------% c external dswap c c %-----------------------% c | Executable Statements | c %-----------------------% c igap = n / 2 c if (which .eq. 'SA') then c c X is sorted into decreasing order of algebraic. c 10 continue if (igap .eq. 0) go to 9000 do 30 i = igap, n-1 j = i-igap 20 continue c if (j.lt.0) go to 30 c if (x(j).lt.x(j+igap)) then temp = x(j) x(j) = x(j+igap) x(j+igap) = temp if (apply) call dswap( na, a(1, j), 1, a(1,j+igap), 1) else go to 30 endif j = j-igap go to 20 30 continue igap = igap / 2 go to 10 c else if (which .eq. 'SM') then c c X is sorted into decreasing order of magnitude. c 40 continue if (igap .eq. 0) go to 9000 do 60 i = igap, n-1 j = i-igap 50 continue c if (j.lt.0) go to 60 c if (abs(x(j)).lt.abs(x(j+igap))) then temp = x(j) x(j) = x(j+igap) x(j+igap) = temp if (apply) call dswap( na, a(1, j), 1, a(1,j+igap), 1) else go to 60 endif j = j-igap go to 50 60 continue igap = igap / 2 go to 40 c else if (which .eq. 'LA') then c c X is sorted into increasing order of algebraic. c 70 continue if (igap .eq. 0) go to 9000 do 90 i = igap, n-1 j = i-igap 80 continue c if (j.lt.0) go to 90 c if (x(j).gt.x(j+igap)) then temp = x(j) x(j) = x(j+igap) x(j+igap) = temp if (apply) call dswap( na, a(1, j), 1, a(1,j+igap), 1) else go to 90 endif j = j-igap go to 80 90 continue igap = igap / 2 go to 70 c else if (which .eq. 'LM') then c c X is sorted into increasing order of magnitude. c 100 continue if (igap .eq. 0) go to 9000 do 120 i = igap, n-1 j = i-igap 110 continue c if (j.lt.0) go to 120 c if (abs(x(j)).gt.abs(x(j+igap))) then temp = x(j) x(j) = x(j+igap) x(j+igap) = temp if (apply) call dswap( na, a(1, j), 1, a(1,j+igap), 1) else go to 120 endif j = j-igap go to 110 120 continue igap = igap / 2 go to 100 end if c 9000 continue return c c %---------------% c | End of igraphdsesrt | c %---------------% c end leidenbase/src/vendor/arpack/dsaup2.f0000644000176200001440000010003014447675376017260 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdsaup2 c c\Description: c Intermediate level interface called by igraphdsaupd. c c\Usage: c call igraphdsaup2 c ( IDO, BMAT, N, WHICH, NEV, NP, TOL, RESID, MODE, IUPD, c ISHIFT, MXITER, V, LDV, H, LDH, RITZ, BOUNDS, Q, LDQ, WORKL, c IPNTR, WORKD, INFO ) c c\Arguments c c IDO, BMAT, N, WHICH, NEV, TOL, RESID: same as defined in igraphdsaupd. c MODE, ISHIFT, MXITER: see the definition of IPARAM in igraphdsaupd. c c NP Integer. (INPUT/OUTPUT) c Contains the number of implicit shifts to apply during c each Arnoldi/Lanczos iteration. c If ISHIFT=1, NP is adjusted dynamically at each iteration c to accelerate convergence and prevent stagnation. c This is also roughly equal to the number of matrix-vector c products (involving the operator OP) per Arnoldi iteration. c The logic for adjusting is contained within the current c subroutine. c If ISHIFT=0, NP is the number of shifts the user needs c to provide via reverse comunication. 0 < NP < NCV-NEV. c NP may be less than NCV-NEV since a leading block of the current c upper Tridiagonal matrix has split off and contains "unwanted" c Ritz values. c Upon termination of the IRA iteration, NP contains the number c of "converged" wanted Ritz values. c c IUPD Integer. (INPUT) c IUPD .EQ. 0: use explicit restart instead implicit update. c IUPD .NE. 0: use implicit update. c c V Double precision N by (NEV+NP) array. (INPUT/OUTPUT) c The Lanczos basis vectors. c c LDV Integer. (INPUT) c Leading dimension of V exactly as declared in the calling c program. c c H Double precision (NEV+NP) by 2 array. (OUTPUT) c H is used to store the generated symmetric tridiagonal matrix c The subdiagonal is stored in the first column of H starting c at H(2,1). The main diagonal is stored in the igraphsecond column c of H starting at H(1,2). If igraphdsaup2 converges store the c B-norm of the final residual vector in H(1,1). c c LDH Integer. (INPUT) c Leading dimension of H exactly as declared in the calling c program. c c RITZ Double precision array of length NEV+NP. (OUTPUT) c RITZ(1:NEV) contains the computed Ritz values of OP. c c BOUNDS Double precision array of length NEV+NP. (OUTPUT) c BOUNDS(1:NEV) contain the error bounds corresponding to RITZ. c c Q Double precision (NEV+NP) by (NEV+NP) array. (WORKSPACE) c Private (replicated) work array used to accumulate the c rotation in the shift application step. c c LDQ Integer. (INPUT) c Leading dimension of Q exactly as declared in the calling c program. c c WORKL Double precision array of length at least 3*(NEV+NP). (INPUT/WORKSPACE) c Private (replicated) array on each PE or array allocated on c the front end. It is used in the computation of the c tridiagonal eigenvalue problem, the calculation and c application of the shifts and convergence checking. c If ISHIFT .EQ. O and IDO .EQ. 3, the first NP locations c of WORKL are used in reverse communication to hold the user c supplied shifts. c c IPNTR Integer array of length 3. (OUTPUT) c Pointer to mark the starting locations in the WORKD for c vectors used by the Lanczos iteration. c ------------------------------------------------------------- c IPNTR(1): pointer to the current operand vector X. c IPNTR(2): pointer to the current result vector Y. c IPNTR(3): pointer to the vector B * X when used in one of c the spectral transformation modes. X is the current c operand. c ------------------------------------------------------------- c c WORKD Double precision work array of length 3*N. (REVERSE COMMUNICATION) c Distributed array to be used in the basic Lanczos iteration c for reverse communication. The user should not use WORKD c as temporary workspace during the iteration !!!!!!!!!! c See Data Distribution Note in igraphdsaupd. c c INFO Integer. (INPUT/OUTPUT) c If INFO .EQ. 0, a randomly initial residual vector is used. c If INFO .NE. 0, RESID contains the initial residual vector, c possibly from a previous run. c Error flag on output. c = 0: Normal return. c = 1: All possible eigenvalues of OP has been found. c NP returns the size of the invariant subspace c spanning the operator OP. c = 2: No shifts could be applied. c = -8: Error return from trid. eigenvalue calculation; c This should never happen. c = -9: Starting vector is zero. c = -9999: Could not build an Lanczos factorization. c Size that was built in returned in NP. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly c Restarted Arnoldi Iteration", Rice University Technical Report c TR95-13, Department of Computational and Applied Mathematics. c 3. B.N. Parlett, "The Symmetric Eigenvalue Problem". Prentice-Hall, c 1980. c 4. B.N. Parlett, B. Nour-Omid, "Towards a Black Box Lanczos Program", c Computer Physics Communications, 53 (1989), pp 169-179. c 5. B. Nour-Omid, B.N. Parlett, T. Ericson, P.S. Jensen, "How to c Implement the Spectral Transformation", Math. Comp., 48 (1987), c pp 663-673. c 6. R.G. Grimes, J.G. Lewis and H.D. Simon, "A Shifted Block Lanczos c Algorithm for Solving Sparse Symmetric Generalized Eigenproblems", c SIAM J. Matr. Anal. Apps., January (1993). c 7. L. Reichel, W.B. Gragg, "Algorithm 686: FORTRAN Subroutines c for Updating the QR decomposition", ACM TOMS, December 1990, c Volume 16 Number 4, pp 369-377. c c\Routines called: c igraphdgetv0 ARPACK initial vector generation routine. c igraphdsaitr ARPACK Lanczos factorization routine. c igraphdsapps ARPACK application of implicit shifts routine. c igraphdsconv ARPACK convergence of Ritz values routine. c igraphdseigt ARPACK compute Ritz values and error bounds routine. c igraphdsgets ARPACK reorder Ritz values and error bounds routine. c igraphdsortr ARPACK sorting routine. c igraphivout ARPACK utility routine that prints integers. c igraphsecond ARPACK utility routine for timing. c igraphdvout ARPACK utility routine that prints vectors. c dlamch LAPACK routine that determines machine constants. c dcopy Level 1 BLAS that copies one vector to another. c ddot Level 1 BLAS that computes the scalar product of two vectors. c dnrm2 Level 1 BLAS that computes the norm of a vector. c dscal Level 1 BLAS that scales a vector. c dswap Level 1 BLAS that swaps two vectors. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c 12/15/93: Version ' 2.4' c xx/xx/95: Version ' 2.4'. (R.B. Lehoucq) c c\SCCS Information: @(#) c FILE: saup2.F SID: 2.6 DATE OF SID: 8/16/96 RELEASE: 2 c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdsaup2 & ( ido, bmat, n, which, nev, np, tol, resid, mode, iupd, & ishift, mxiter, v, ldv, h, ldh, ritz, bounds, & q, ldq, workl, ipntr, workd, info ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character bmat*1, which*2 integer ido, info, ishift, iupd, ldh, ldq, ldv, mxiter, & n, mode, nev, np Double precision & tol c c %-----------------% c | Array Arguments | c %-----------------% c integer ipntr(3) Double precision & bounds(nev+np), h(ldh,2), q(ldq,nev+np), resid(n), & ritz(nev+np), v(ldv,nev+np), workd(3*n), & workl(3*(nev+np)) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c character wprime*2 logical cnorm, getv0, initv, update, ushift integer ierr, iter, j, kplusp, msglvl, nconv, nevbef, nev0, & np0, nptemp, nevd2, nevm2, kp(3) Double precision & rnorm, temp, eps23 save cnorm, getv0, initv, update, ushift, & iter, kplusp, msglvl, nconv, nev0, np0, & rnorm, eps23 c c %----------------------% c | External Subroutines | c %----------------------% c external dcopy, igraphdgetv0, igraphdsaitr, dscal, & igraphdsconv, igraphdseigt, igraphdsgets, & igraphdsapps, igraphdsortr, igraphdvout, igraphivout, & igraphsecond, dswap c c %--------------------% c | External Functions | c %--------------------% c Double precision & ddot, dnrm2, dlamch external ddot, dnrm2, dlamch c c %---------------------% c | Intrinsic Functions | c %---------------------% c intrinsic min c c %-----------------------% c | Executable Statements | c %-----------------------% c if (ido .eq. 0) then c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = msaup2 c c %---------------------------------% c | Set machine dependent constant. | c %---------------------------------% c eps23 = dlamch('Epsilon-Machine') eps23 = eps23**(2.0D+0/3.0D+0) c c %-------------------------------------% c | nev0 and np0 are integer variables | c | hold the initial values of NEV & NP | c %-------------------------------------% c nev0 = nev np0 = np c c %-------------------------------------% c | kplusp is the bound on the largest | c | Lanczos factorization built. | c | nconv is the current number of | c | "converged" eigenvlues. | c | iter is the counter on the current | c | iteration step. | c %-------------------------------------% c kplusp = nev0 + np0 nconv = 0 iter = 0 c c %--------------------------------------------% c | Set flags for computing the first NEV steps | c | of the Lanczos factorization. | c %--------------------------------------------% c getv0 = .true. update = .false. ushift = .false. cnorm = .false. c if (info .ne. 0) then c c %--------------------------------------------% c | User provides the initial residual vector. | c %--------------------------------------------% c initv = .true. info = 0 else initv = .false. end if end if c c %---------------------------------------------% c | Get a possibly random starting vector and | c | force it into the range of the operator OP. | c %---------------------------------------------% c 10 continue c if (getv0) then call igraphdgetv0 (ido, bmat, 1, initv, n, 1, v, ldv, resid, & rnorm, ipntr, workd, info) c if (ido .ne. 99) go to 9000 c if (rnorm .eq. zero) then c c %-----------------------------------------% c | The initial vector is zero. Error exit. | c %-----------------------------------------% c info = -9 go to 1200 end if getv0 = .false. ido = 0 end if c c %------------------------------------------------------------% c | Back from reverse communication: continue with update step | c %------------------------------------------------------------% c if (update) go to 20 c c %-------------------------------------------% c | Back from computing user specified shifts | c %-------------------------------------------% c if (ushift) go to 50 c c %-------------------------------------% c | Back from computing residual norm | c | at the end of the current iteration | c %-------------------------------------% c if (cnorm) go to 100 c c %----------------------------------------------------------% c | Compute the first NEV steps of the Lanczos factorization | c %----------------------------------------------------------% c call igraphdsaitr (ido, bmat, n, 0, nev0, mode, resid, rnorm, v, & ldv, h, ldh, ipntr, workd, info) c c %---------------------------------------------------% c | ido .ne. 99 implies use of reverse communication | c | to compute operations involving OP and possibly B | c %---------------------------------------------------% c if (ido .ne. 99) go to 9000 c if (info .gt. 0) then c c %-----------------------------------------------------% c | igraphdsaitr was unable to build an Lanczos factorization | c | of length NEV0. INFO is returned with the size of | c | the factorization built. Exit main loop. | c %-----------------------------------------------------% c np = info mxiter = iter info = -9999 go to 1200 end if c c %--------------------------------------------------------------% c | | c | M A I N LANCZOS I T E R A T I O N L O O P | c | Each iteration implicitly restarts the Lanczos | c | factorization in place. | c | | c %--------------------------------------------------------------% c 1000 continue c iter = iter + 1 c if (msglvl .gt. 0) then call igraphivout (logfil, 1, [iter], ndigit, & '_saup2: **** Start of major iteration number ****') end if if (msglvl .gt. 1) then call igraphivout (logfil, 1, [nev], ndigit, & '_saup2: The length of the current Lanczos factorization') call igraphivout (logfil, 1, [np], ndigit, & '_saup2: Extend the Lanczos factorization by') end if c c %------------------------------------------------------------% c | Compute NP additional steps of the Lanczos factorization. | c %------------------------------------------------------------% c ido = 0 20 continue update = .true. c call igraphdsaitr (ido, bmat, n, nev, np, mode, resid, rnorm, & v, ldv, h, ldh, ipntr, workd, info) c c %---------------------------------------------------% c | ido .ne. 99 implies use of reverse communication | c | to compute operations involving OP and possibly B | c %---------------------------------------------------% c if (ido .ne. 99) go to 9000 c if (info .gt. 0) then c c %-----------------------------------------------------% c | igraphdsaitr was unable to build an Lanczos factorization | c | of length NEV0+NP0. INFO is returned with the size | c | of the factorization built. Exit main loop. | c %-----------------------------------------------------% c np = info mxiter = iter info = -9999 go to 1200 end if update = .false. c if (msglvl .gt. 1) then call igraphdvout (logfil, 1, [rnorm], ndigit, & '_saup2: Current B-norm of residual for factorization') end if c c %--------------------------------------------------------% c | Compute the eigenvalues and corresponding error bounds | c | of the current symmetric tridiagonal matrix. | c %--------------------------------------------------------% c call igraphdseigt (rnorm, kplusp, h, ldh, ritz, bounds, workl, & ierr) c if (ierr .ne. 0) then info = -8 go to 1200 end if c c %----------------------------------------------------% c | Make a copy of eigenvalues and corresponding error | c | bounds obtained from _seigt. | c %----------------------------------------------------% c call dcopy(kplusp, ritz, 1, workl(kplusp+1), 1) call dcopy(kplusp, bounds, 1, workl(2*kplusp+1), 1) c c %---------------------------------------------------% c | Select the wanted Ritz values and their bounds | c | to be used in the convergence test. | c | The selection is based on the requested number of | c | eigenvalues instead of the current NEV and NP to | c | prevent possible misconvergence. | c | * Wanted Ritz values := RITZ(NP+1:NEV+NP) | c | * Shifts := RITZ(1:NP) := WORKL(1:NP) | c %---------------------------------------------------% c nev = nev0 np = np0 call igraphdsgets (ishift, which, nev, np, ritz, bounds, workl) c c %-------------------% c | Convergence test. | c %-------------------% c call dcopy (nev, bounds(np+1), 1, workl(np+1), 1) call igraphdsconv (nev, ritz(np+1), workl(np+1), tol, nconv) c if (msglvl .gt. 2) then kp(1) = nev kp(2) = np kp(3) = nconv call igraphivout (logfil, 3, kp, ndigit, & '_saup2: NEV, NP, NCONV are') call igraphdvout (logfil, kplusp, ritz, ndigit, & '_saup2: The eigenvalues of H') call igraphdvout (logfil, kplusp, bounds, ndigit, & '_saup2: Ritz estimates of the current NCV Ritz values') end if c c %---------------------------------------------------------% c | Count the number of unwanted Ritz values that have zero | c | Ritz estimates. If any Ritz estimates are equal to zero | c | then a leading block of H of order equal to at least | c | the number of Ritz values with zero Ritz estimates has | c | split off. None of these Ritz values may be removed by | c | shifting. Decrease NP the number of shifts to apply. If | c | no shifts may be applied, then prepare to exit | c %---------------------------------------------------------% c nptemp = np do 30 j=1, nptemp if (bounds(j) .eq. zero) then np = np - 1 nev = nev + 1 end if 30 continue c if ( (nconv .ge. nev0) .or. & (iter .gt. mxiter) .or. & (np .eq. 0) ) then c c %------------------------------------------------% c | Prepare to exit. Put the converged Ritz values | c | and corresponding bounds in RITZ(1:NCONV) and | c | BOUNDS(1:NCONV) respectively. Then sort. Be | c | careful when NCONV > NP since we don't want to | c | swap overlapping locations. | c %------------------------------------------------% c if (which .eq. 'BE') then c c %-----------------------------------------------------% c | Both ends of the spectrum are requested. | c | Sort the eigenvalues into algebraically decreasing | c | order first then swap low end of the spectrum next | c | to high end in appropriate locations. | c | NOTE: when np < floor(nev/2) be careful not to swap | c | overlapping locations. | c %-----------------------------------------------------% c wprime = 'SA' call igraphdsortr (wprime, .true., kplusp, ritz, bounds) nevd2 = nev / 2 nevm2 = nev - nevd2 if ( nev .gt. 1 ) then call dswap ( min(nevd2,np), ritz(nevm2+1), 1, & ritz( max(kplusp-nevd2+1,kplusp-np+1) ), 1) call dswap ( min(nevd2,np), bounds(nevm2+1), 1, & bounds( max(kplusp-nevd2+1,kplusp-np)+1 ), 1) end if c else c c %--------------------------------------------------% c | LM, SM, LA, SA case. | c | Sort the eigenvalues of H into the an order that | c | is opposite to WHICH, and apply the resulting | c | order to BOUNDS. The eigenvalues are sorted so | c | that the wanted part are always within the first | c | NEV locations. | c %--------------------------------------------------% c if (which .eq. 'LM') wprime = 'SM' if (which .eq. 'SM') wprime = 'LM' if (which .eq. 'LA') wprime = 'SA' if (which .eq. 'SA') wprime = 'LA' c call igraphdsortr (wprime, .true., kplusp, ritz, bounds) c end if c c %--------------------------------------------------% c | Scale the Ritz estimate of each Ritz value | c | by 1 / max(eps23,magnitude of the Ritz value). | c %--------------------------------------------------% c do 35 j = 1, nev0 temp = max( eps23, abs(ritz(j)) ) bounds(j) = bounds(j)/temp 35 continue c c %----------------------------------------------------% c | Sort the Ritz values according to the scaled Ritz | c | esitmates. This will push all the converged ones | c | towards the front of ritzr, ritzi, bounds | c | (in the case when NCONV < NEV.) | c %----------------------------------------------------% c wprime = 'LA' call igraphdsortr(wprime, .true., nev0, bounds, ritz) c c %----------------------------------------------% c | Scale the Ritz estimate back to its original | c | value. | c %----------------------------------------------% c do 40 j = 1, nev0 temp = max( eps23, abs(ritz(j)) ) bounds(j) = bounds(j)*temp 40 continue c c %--------------------------------------------------% c | Sort the "converged" Ritz values again so that | c | the "threshold" values and their associated Ritz | c | estimates appear at the appropriate position in | c | ritz and bound. | c %--------------------------------------------------% c if (which .eq. 'BE') then c c %------------------------------------------------% c | Sort the "converged" Ritz values in increasing | c | order. The "threshold" values are in the | c | middle. | c %------------------------------------------------% c wprime = 'LA' call igraphdsortr(wprime, .true., nconv, ritz, bounds) c else c c %----------------------------------------------% c | In LM, SM, LA, SA case, sort the "converged" | c | Ritz values according to WHICH so that the | c | "threshold" value appears at the front of | c | ritz. | c %----------------------------------------------% call igraphdsortr(which, .true., nconv, ritz, bounds) c end if c c %------------------------------------------% c | Use h( 1,1 ) as storage to communicate | c | rnorm to _seupd if needed | c %------------------------------------------% c h(1,1) = rnorm c if (msglvl .gt. 1) then call igraphdvout (logfil, kplusp, ritz, ndigit, & '_saup2: Sorted Ritz values.') call igraphdvout (logfil, kplusp, bounds, ndigit, & '_saup2: Sorted ritz estimates.') end if c c %------------------------------------% c | Max iterations have been exceeded. | c %------------------------------------% c if (iter .gt. mxiter .and. nconv .lt. nev) info = 1 c c %---------------------% c | No shifts to apply. | c %---------------------% c if (np .eq. 0 .and. nconv .lt. nev0) info = 2 c np = nconv go to 1100 c else if (nconv .lt. nev .and. ishift .eq. 1) then c c %---------------------------------------------------% c | Do not have all the requested eigenvalues yet. | c | To prevent possible stagnation, adjust the number | c | of Ritz values and the shifts. | c %---------------------------------------------------% c nevbef = nev nev = nev + min (nconv, np/2) if (nev .eq. 1 .and. kplusp .ge. 6) then nev = kplusp / 2 else if (nev .eq. 1 .and. kplusp .gt. 2) then nev = 2 end if np = kplusp - nev c c %---------------------------------------% c | If the size of NEV was just increased | c | resort the eigenvalues. | c %---------------------------------------% c if (nevbef .lt. nev) & call igraphdsgets (ishift, which, nev, np, ritz, bounds, & workl) c end if c if (msglvl .gt. 0) then call igraphivout (logfil, 1, [nconv], ndigit, & '_saup2: no. of "converged" Ritz values at this iter.') if (msglvl .gt. 1) then kp(1) = nev kp(2) = np call igraphivout (logfil, 2, kp, ndigit, & '_saup2: NEV and NP are') call igraphdvout (logfil, nev, ritz(np+1), ndigit, & '_saup2: "wanted" Ritz values.') call igraphdvout (logfil, nev, bounds(np+1), ndigit, & '_saup2: Ritz estimates of the "wanted" values ') end if end if c if (ishift .eq. 0) then c c %-----------------------------------------------------% c | User specified shifts: reverse communication to | c | compute the shifts. They are returned in the first | c | NP locations of WORKL. | c %-----------------------------------------------------% c ushift = .true. ido = 3 go to 9000 end if c 50 continue c c %------------------------------------% c | Back from reverse communication; | c | User specified shifts are returned | c | in WORKL(1:*NP) | c %------------------------------------% c ushift = .false. c c c %---------------------------------------------------------% c | Move the NP shifts to the first NP locations of RITZ to | c | free up WORKL. This is for the non-exact shift case; | c | in the exact shift case, igraphdsgets already handles this. | c %---------------------------------------------------------% c if (ishift .eq. 0) call dcopy (np, workl, 1, ritz, 1) c if (msglvl .gt. 2) then call igraphivout (logfil, 1, [np], ndigit, & '_saup2: The number of shifts to apply ') call igraphdvout (logfil, np, workl, ndigit, & '_saup2: shifts selected') if (ishift .eq. 1) then call igraphdvout (logfil, np, bounds, ndigit, & '_saup2: corresponding Ritz estimates') end if end if c c %---------------------------------------------------------% c | Apply the NP0 implicit shifts by QR bulge chasing. | c | Each shift is applied to the entire tridiagonal matrix. | c | The first 2*N locations of WORKD are used as workspace. | c | After igraphdsapps is done, we have a Lanczos | c | factorization of length NEV. | c %---------------------------------------------------------% c call igraphdsapps (n, nev, np, ritz, v, ldv, h, ldh, resid, & q, ldq, workd) c c %---------------------------------------------% c | Compute the B-norm of the updated residual. | c | Keep B*RESID in WORKD(1:N) to be used in | c | the first step of the next call to igraphdsaitr. | c %---------------------------------------------% c cnorm = .true. call igraphsecond (t2) if (bmat .eq. 'G') then nbx = nbx + 1 call dcopy (n, resid, 1, workd(n+1), 1) ipntr(1) = n + 1 ipntr(2) = 1 ido = 2 c c %----------------------------------% c | Exit in order to compute B*RESID | c %----------------------------------% c go to 9000 else if (bmat .eq. 'I') then call dcopy (n, resid, 1, workd, 1) end if c 100 continue c c %----------------------------------% c | Back from reverse communication; | c | WORKD(1:N) := B*RESID | c %----------------------------------% c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c if (bmat .eq. 'G') then rnorm = ddot (n, resid, 1, workd, 1) rnorm = sqrt(abs(rnorm)) else if (bmat .eq. 'I') then rnorm = dnrm2(n, resid, 1) end if cnorm = .false. 130 continue c if (msglvl .gt. 2) then call igraphdvout (logfil, 1, [rnorm], ndigit, & '_saup2: B-norm of residual for NEV factorization') call igraphdvout (logfil, nev, h(1,2), ndigit, & '_saup2: main diagonal of compressed H matrix') call igraphdvout (logfil, nev-1, h(2,1), ndigit, & '_saup2: subdiagonal of compressed H matrix') end if c go to 1000 c c %---------------------------------------------------------------% c | | c | E N D O F M A I N I T E R A T I O N L O O P | c | | c %---------------------------------------------------------------% c 1100 continue c mxiter = iter nev = nconv c 1200 continue ido = 99 c c %------------% c | Error exit | c %------------% c call igraphsecond (t1) tsaup2 = t1 - t0 c 9000 continue return c c %---------------% c | End of igraphdsaup2 | c %---------------% c end leidenbase/src/vendor/arpack/dsaupd.f0000644000176200001440000006463514447675376017366 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdsaupd c c\Description: c c Reverse communication interface for the Implicitly Restarted Arnoldi c Iteration. For symmetric problems this reduces to a variant of the Lanczos c method. This method has been designed to compute approximations to a c few eigenpairs of a linear operator OP that is real and symmetric c with respect to a real positive semi-definite symmetric matrix B, c i.e. c c B*OP = (OP')*B. c c Another way to express this condition is c c < x,OPy > = < OPx,y > where < z,w > = z'Bw . c c In the standard eigenproblem B is the identity matrix. c ( A' denotes transpose of A) c c The computed approximate eigenvalues are called Ritz values and c the corresponding approximate eigenvectors are called Ritz vectors. c c igraphdsaupd is usually called iteratively to solve one of the c following problems: c c Mode 1: A*x = lambda*x, A symmetric c ===> OP = A and B = I. c c Mode 2: A*x = lambda*M*x, A symmetric, M symmetric positive definite c ===> OP = inv[M]*A and B = M. c ===> (If M can be factored see remark 3 below) c c Mode 3: K*x = lambda*M*x, K symmetric, M symmetric positive semi-definite c ===> OP = (inv[K - sigma*M])*M and B = M. c ===> Shift-and-Invert mode c c Mode 4: K*x = lambda*KG*x, K symmetric positive semi-definite, c KG symmetric indefinite c ===> OP = (inv[K - sigma*KG])*K and B = K. c ===> Buckling mode c c Mode 5: A*x = lambda*M*x, A symmetric, M symmetric positive semi-definite c ===> OP = inv[A - sigma*M]*[A + sigma*M] and B = M. c ===> Cayley transformed mode c c NOTE: The action of w <- inv[A - sigma*M]*v or w <- inv[M]*v c should be accomplished either by a direct method c using a sparse matrix factorization and solving c c [A - sigma*M]*w = v or M*w = v, c c or through an iterative method for solving these c systems. If an iterative method is used, the c convergence test must be more stringent than c the accuracy requirements for the eigenvalue c approximations. c c\Usage: c call igraphdsaupd c ( IDO, BMAT, N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, c IPNTR, WORKD, WORKL, LWORKL, INFO ) c c\Arguments c IDO Integer. (INPUT/OUTPUT) c Reverse communication flag. IDO must be zero on the first c call to igraphdsaupd. IDO will be set internally to c indicate the type of operation to be performed. Control is c then given back to the calling routine which has the c responsibility to carry out the requested operation and call c igraphdsaupd with the result. The operand is given in c WORKD(IPNTR(1)), the result must be put in WORKD(IPNTR(2)). c (If Mode = 2 see remark 5 below) c ------------------------------------------------------------- c IDO = 0: first call to the reverse communication interface c IDO = -1: compute Y = OP * X where c IPNTR(1) is the pointer into WORKD for X, c IPNTR(2) is the pointer into WORKD for Y. c This is for the initialization phase to force the c starting vector into the range of OP. c IDO = 1: compute Y = OP * X where c IPNTR(1) is the pointer into WORKD for X, c IPNTR(2) is the pointer into WORKD for Y. c In mode 3,4 and 5, the vector B * X is already c available in WORKD(ipntr(3)). It does not c need to be recomputed in forming OP * X. c IDO = 2: compute Y = B * X where c IPNTR(1) is the pointer into WORKD for X, c IPNTR(2) is the pointer into WORKD for Y. c IDO = 3: compute the IPARAM(8) shifts where c IPNTR(11) is the pointer into WORKL for c placing the shifts. See remark 6 below. c IDO = 99: done c ------------------------------------------------------------- c c BMAT Character*1. (INPUT) c BMAT specifies the type of the matrix B that defines the c semi-inner product for the operator OP. c B = 'I' -> standard eigenvalue problem A*x = lambda*x c B = 'G' -> generalized eigenvalue problem A*x = lambda*B*x c c N Integer. (INPUT) c Dimension of the eigenproblem. c c WHICH Character*2. (INPUT) c Specify which of the Ritz values of OP to compute. c c 'LA' - compute the NEV largest (algebraic) eigenvalues. c 'SA' - compute the NEV smallest (algebraic) eigenvalues. c 'LM' - compute the NEV largest (in magnitude) eigenvalues. c 'SM' - compute the NEV smallest (in magnitude) eigenvalues. c 'BE' - compute NEV eigenvalues, half from each end of the c spectrum. When NEV is odd, compute one more from the c high end than from the low end. c (see remark 1 below) c c NEV Integer. (INPUT) c Number of eigenvalues of OP to be computed. 0 < NEV < N. c c TOL Double precision scalar. (INPUT) c Stopping criterion: the relative accuracy of the Ritz value c is considered acceptable if BOUNDS(I) .LE. TOL*ABS(RITZ(I)). c If TOL .LE. 0. is passed a default is set: c DEFAULT = DLAMCH('EPS') (machine precision as computed c by the LAPACK auxiliary subroutine DLAMCH). c c RESID Double precision array of length N. (INPUT/OUTPUT) c On INPUT: c If INFO .EQ. 0, a random initial residual vector is used. c If INFO .NE. 0, RESID contains the initial residual vector, c possibly from a previous run. c On OUTPUT: c RESID contains the final residual vector. c c NCV Integer. (INPUT) c Number of columns of the matrix V (less than or equal to N). c This will indicate how many Lanczos vectors are generated c at each iteration. After the startup phase in which NEV c Lanczos vectors are generated, the algorithm generates c NCV-NEV Lanczos vectors at each subsequent update iteration. c Most of the cost in generating each Lanczos vector is in the c matrix-vector product OP*x. (See remark 4 below). c c V Double precision N by NCV array. (OUTPUT) c The NCV columns of V contain the Lanczos basis vectors. c c LDV Integer. (INPUT) c Leading dimension of V exactly as declared in the calling c program. c c IPARAM Integer array of length 11. (INPUT/OUTPUT) c IPARAM(1) = ISHIFT: method for selecting the implicit shifts. c The shifts selected at each iteration are used to restart c the Arnoldi iteration in an implicit fashion. c ------------------------------------------------------------- c ISHIFT = 0: the shifts are provided by the user via c reverse communication. The NCV eigenvalues of c the current tridiagonal matrix T are returned in c the part of WORKL array corresponding to RITZ. c See remark 6 below. c ISHIFT = 1: exact shifts with respect to the reduced c tridiagonal matrix T. This is equivalent to c restarting the iteration with a starting vector c that is a linear combination of Ritz vectors c associated with the "wanted" Ritz values. c ------------------------------------------------------------- c c IPARAM(2) = LEVEC c No longer referenced. See remark 2 below. c c IPARAM(3) = MXITER c On INPUT: maximum number of Arnoldi update iterations allowed. c On OUTPUT: actual number of Arnoldi update iterations taken. c c IPARAM(4) = NB: blocksize to be used in the recurrence. c The code currently works only for NB = 1. c c IPARAM(5) = NCONV: number of "converged" Ritz values. c This represents the number of Ritz values that satisfy c the convergence criterion. c c IPARAM(6) = IUPD c No longer referenced. Implicit restarting is ALWAYS used. c c IPARAM(7) = MODE c On INPUT determines what type of eigenproblem is being solved. c Must be 1,2,3,4,5; See under \Description of igraphdsaupd for the c five modes available. c c IPARAM(8) = NP c When ido = 3 and the user provides shifts through reverse c communication (IPARAM(1)=0), igraphdsaupd returns NP, the number c of shifts the user is to provide. 0 < NP <=NCV-NEV. See Remark c 6 below. c c IPARAM(9) = NUMOP, IPARAM(10) = NUMOPB, IPARAM(11) = NUMREO, c OUTPUT: NUMOP = total number of OP*x operations, c NUMOPB = total number of B*x operations if BMAT='G', c NUMREO = total number of steps of re-orthogonalization. c c IPNTR Integer array of length 11. (OUTPUT) c Pointer to mark the starting locations in the WORKD and WORKL c arrays for matrices/vectors used by the Lanczos iteration. c ------------------------------------------------------------- c IPNTR(1): pointer to the current operand vector X in WORKD. c IPNTR(2): pointer to the current result vector Y in WORKD. c IPNTR(3): pointer to the vector B * X in WORKD when used in c the shift-and-invert mode. c IPNTR(4): pointer to the next available location in WORKL c that is untouched by the program. c IPNTR(5): pointer to the NCV by 2 tridiagonal matrix T in WORKL. c IPNTR(6): pointer to the NCV RITZ values array in WORKL. c IPNTR(7): pointer to the Ritz estimates in array WORKL associated c with the Ritz values located in RITZ in WORKL. c IPNTR(11): pointer to the NP shifts in WORKL. See Remark 6 below. c c Note: IPNTR(8:10) is only referenced by igraphdseupd. See Remark 2. c IPNTR(8): pointer to the NCV RITZ values of the original system. c IPNTR(9): pointer to the NCV corresponding error bounds. c IPNTR(10): pointer to the NCV by NCV matrix of eigenvectors c of the tridiagonal matrix T. Only referenced by c igraphdseupd if RVEC = .TRUE. See Remarks. c ------------------------------------------------------------- c c WORKD Double precision work array of length 3*N. (REVERSE COMMUNICATION) c Distributed array to be used in the basic Arnoldi iteration c for reverse communication. The user should not use WORKD c as temporary workspace during the iteration. Upon termination c WORKD(1:N) contains B*RESID(1:N). If the Ritz vectors are desired c subroutine igraphdseupd uses this output. c See Data Distribution Note below. c c WORKL Double precision work array of length LWORKL. (OUTPUT/WORKSPACE) c Private (replicated) array on each PE or array allocated on c the front end. See Data Distribution Note below. c c LWORKL Integer. (INPUT) c LWORKL must be at least NCV**2 + 8*NCV . c c INFO Integer. (INPUT/OUTPUT) c If INFO .EQ. 0, a randomly initial residual vector is used. c If INFO .NE. 0, RESID contains the initial residual vector, c possibly from a previous run. c Error flag on output. c = 0: Normal exit. c = 1: Maximum number of iterations taken. c All possible eigenvalues of OP has been found. IPARAM(5) c returns the number of wanted converged Ritz values. c = 2: No longer an informational error. Deprecated starting c with release 2 of ARPACK. c = 3: No shifts could be applied during a cycle of the c Implicitly restarted Arnoldi iteration. One possibility c is to increase the size of NCV relative to NEV. c See remark 4 below. c = -1: N must be positive. c = -2: NEV must be positive. c = -3: NCV must be greater than NEV and less than or equal to N. c = -4: The maximum number of Arnoldi update iterations allowed c must be greater than zero. c = -5: WHICH must be one of 'LM', 'SM', 'LA', 'SA' or 'BE'. c = -6: BMAT must be one of 'I' or 'G'. c = -7: Length of private work array WORKL is not sufficient. c = -8: Error return from trid. eigenvalue calculation; c Informatinal error from LAPACK routine dsteqr. c = -9: Starting vector is zero. c = -10: IPARAM(7) must be 1,2,3,4,5. c = -11: IPARAM(7) = 1 and BMAT = 'G' are incompatable. c = -12: IPARAM(1) must be equal to 0 or 1. c = -13: NEV and WHICH = 'BE' are incompatable. c = -9999: Could not build an Arnoldi factorization. c IPARAM(5) returns the size of the current Arnoldi c factorization. The user is advised to check that c enough workspace and array storage has been allocated. c c c\Remarks c 1. The converged Ritz values are always returned in ascending c algebraic order. The computed Ritz values are approximate c eigenvalues of OP. The selection of WHICH should be made c with this in mind when Mode = 3,4,5. After convergence, c approximate eigenvalues of the original problem may be obtained c with the ARPACK subroutine igraphdseupd. c c 2. If the Ritz vectors corresponding to the converged Ritz values c are needed, the user must call igraphdseupd immediately following completion c of igraphdsaupd. This is new starting with version 2.1 of ARPACK. c c 3. If M can be factored into a Cholesky factorization M = LL' c then Mode = 2 should not be selected. Instead one should use c Mode = 1 with OP = inv(L)*A*inv(L'). Appropriate triangular c linear systems should be solved with L and L' rather c than computing inverses. After convergence, an approximate c eigenvector z of the original problem is recovered by solving c L'z = x where x is a Ritz vector of OP. c c 4. At present there is no a-priori analysis to guide the selection c of NCV relative to NEV. The only formal requrement is that NCV > NEV. c However, it is recommended that NCV .ge. 2*NEV. If many problems of c the same type are to be solved, one should experiment with increasing c NCV while keeping NEV fixed for a given test problem. This will c usually decrease the required number of OP*x operations but it c also increases the work and storage required to maintain the orthogonal c basis vectors. The optimal "cross-over" with respect to CPU time c is problem dependent and must be determined empirically. c c 5. If IPARAM(7) = 2 then in the Reverse commuication interface the user c must do the following. When IDO = 1, Y = OP * X is to be computed. c When IPARAM(7) = 2 OP = inv(B)*A. After computing A*X the user c must overwrite X with A*X. Y is then the solution to the linear set c of equations B*Y = A*X. c c 6. When IPARAM(1) = 0, and IDO = 3, the user needs to provide the c NP = IPARAM(8) shifts in locations: c 1 WORKL(IPNTR(11)) c 2 WORKL(IPNTR(11)+1) c . c . c . c NP WORKL(IPNTR(11)+NP-1). c c The eigenvalues of the current tridiagonal matrix are located in c WORKL(IPNTR(6)) through WORKL(IPNTR(6)+NCV-1). They are in the c order defined by WHICH. The associated Ritz estimates are located in c WORKL(IPNTR(8)), WORKL(IPNTR(8)+1), ... , WORKL(IPNTR(8)+NCV-1). c c----------------------------------------------------------------------- c c\Data Distribution Note: c c Fortran-D syntax: c ================ c REAL RESID(N), V(LDV,NCV), WORKD(3*N), WORKL(LWORKL) c DECOMPOSE D1(N), D2(N,NCV) c ALIGN RESID(I) with D1(I) c ALIGN V(I,J) with D2(I,J) c ALIGN WORKD(I) with D1(I) range (1:N) c ALIGN WORKD(I) with D1(I-N) range (N+1:2*N) c ALIGN WORKD(I) with D1(I-2*N) range (2*N+1:3*N) c DISTRIBUTE D1(BLOCK), D2(BLOCK,:) c REPLICATED WORKL(LWORKL) c c Cray MPP syntax: c =============== c REAL RESID(N), V(LDV,NCV), WORKD(N,3), WORKL(LWORKL) c SHARED RESID(BLOCK), V(BLOCK,:), WORKD(BLOCK,:) c REPLICATED WORKL(LWORKL) c c c\BeginLib c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly c Restarted Arnoldi Iteration", Rice University Technical Report c TR95-13, Department of Computational and Applied Mathematics. c 3. B.N. Parlett, "The Symmetric Eigenvalue Problem". Prentice-Hall, c 1980. c 4. B.N. Parlett, B. Nour-Omid, "Towards a Black Box Lanczos Program", c Computer Physics Communications, 53 (1989), pp 169-179. c 5. B. Nour-Omid, B.N. Parlett, T. Ericson, P.S. Jensen, "How to c Implement the Spectral Transformation", Math. Comp., 48 (1987), c pp 663-673. c 6. R.G. Grimes, J.G. Lewis and H.D. Simon, "A Shifted Block Lanczos c Algorithm for Solving Sparse Symmetric Generalized Eigenproblems", c SIAM J. Matr. Anal. Apps., January (1993). c 7. L. Reichel, W.B. Gragg, "Algorithm 686: FORTRAN Subroutines c for Updating the QR decomposition", ACM TOMS, December 1990, c Volume 16 Number 4, pp 369-377. c 8. R.B. Lehoucq, D.C. Sorensen, "Implementation of Some Spectral c Transformations in a k-Step Arnoldi Method". In Preparation. c c\Routines called: c igraphdsaup2 ARPACK routine that implements the Implicitly Restarted c Arnoldi Iteration. c igraphdstats ARPACK routine that initialize timing and other statistics c variables. c igraphivout ARPACK utility routine that prints integers. c igraphsecond ARPACK utility routine for timing. c igraphdvout ARPACK utility routine that prints vectors. c dlamch LAPACK routine that determines machine constants. c c\Authors c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c 12/15/93: Version ' 2.4' c c\SCCS Information: @(#) c FILE: saupd.F SID: 2.7 DATE OF SID: 8/27/96 RELEASE: 2 c c\Remarks c 1. None c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdsaupd & ( ido, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, & ipntr, workd, workl, lworkl, info ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character bmat*1, which*2 integer ido, info, ldv, lworkl, n, ncv, nev Double precision & tol c c %-----------------% c | Array Arguments | c %-----------------% c integer iparam(11), ipntr(11) Double precision & resid(n), v(ldv,ncv), workd(3*n), workl(lworkl) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c integer bounds, ierr, ih, iq, ishift, iupd, iw, & ldh, ldq, msglvl, mxiter, mode, nb, & nev0, next, np, ritz, j save bounds, ierr, ih, iq, ishift, iupd, iw, & ldh, ldq, msglvl, mxiter, mode, nb, & nev0, next, np, ritz c c %----------------------% c | External Subroutines | c %----------------------% c external igraphdsaup2, igraphdvout, igraphivout, & igraphsecond, igraphdstats c c %--------------------% c | External Functions | c %--------------------% c Double precision & dlamch external dlamch c c %-----------------------% c | Executable Statements | c %-----------------------% c if (ido .eq. 0) then c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphdstats call igraphsecond (t0) msglvl = msaupd c ierr = 0 ishift = iparam(1) mxiter = iparam(3) nb = iparam(4) c c %--------------------------------------------% c | Revision 2 performs only implicit restart. | c %--------------------------------------------% c iupd = 1 mode = iparam(7) c c %----------------% c | Error checking | c %----------------% c if (n .le. 0) then ierr = -1 else if (nev .le. 0) then ierr = -2 else if (ncv .le. nev .or. ncv .gt. n) then ierr = -3 end if c c %----------------------------------------------% c | NP is the number of additional steps to | c | extend the length NEV Lanczos factorization. | c %----------------------------------------------% c np = ncv - nev c if (mxiter .le. 0) ierr = -4 if (which .ne. 'LM' .and. & which .ne. 'SM' .and. & which .ne. 'LA' .and. & which .ne. 'SA' .and. & which .ne. 'BE') ierr = -5 if (bmat .ne. 'I' .and. bmat .ne. 'G') ierr = -6 c if (lworkl .lt. ncv**2 + 8*ncv) ierr = -7 if (mode .lt. 1 .or. mode .gt. 5) then ierr = -10 else if (mode .eq. 1 .and. bmat .eq. 'G') then ierr = -11 else if (ishift .lt. 0 .or. ishift .gt. 1) then ierr = -12 else if (nev .eq. 1 .and. which .eq. 'BE') then ierr = -13 end if c c %------------% c | Error Exit | c %------------% c if (ierr .ne. 0) then info = ierr ido = 99 go to 9000 end if c c %------------------------% c | Set default parameters | c %------------------------% c if (nb .le. 0) nb = 1 if (tol .le. zero) tol = dlamch('EpsMach') c c %----------------------------------------------% c | NP is the number of additional steps to | c | extend the length NEV Lanczos factorization. | c | NEV0 is the local variable designating the | c | size of the invariant subspace desired. | c %----------------------------------------------% c np = ncv - nev nev0 = nev c c %-----------------------------% c | Zero out internal workspace | c %-----------------------------% c do 10 j = 1, ncv**2 + 8*ncv workl(j) = zero 10 continue c c %-------------------------------------------------------% c | Pointer into WORKL for address of H, RITZ, BOUNDS, Q | c | etc... and the remaining workspace. | c | Also update pointer to be used on output. | c | Memory is laid out as follows: | c | workl(1:2*ncv) := generated tridiagonal matrix | c | workl(2*ncv+1:2*ncv+ncv) := ritz values | c | workl(3*ncv+1:3*ncv+ncv) := computed error bounds | c | workl(4*ncv+1:4*ncv+ncv*ncv) := rotation matrix Q | c | workl(4*ncv+ncv*ncv+1:7*ncv+ncv*ncv) := workspace | c %-------------------------------------------------------% c ldh = ncv ldq = ncv ih = 1 ritz = ih + 2*ldh bounds = ritz + ncv iq = bounds + ncv iw = iq + ncv**2 next = iw + 3*ncv c ipntr(4) = next ipntr(5) = ih ipntr(6) = ritz ipntr(7) = bounds ipntr(11) = iw end if c c %-------------------------------------------------------% c | Carry out the Implicitly restarted Lanczos Iteration. | c %-------------------------------------------------------% c call igraphdsaup2 & ( ido, bmat, n, which, nev0, np, tol, resid, mode, iupd, & ishift, mxiter, v, ldv, workl(ih), ldh, workl(ritz), & workl(bounds), workl(iq), ldq, workl(iw), ipntr, workd, & info ) c c %--------------------------------------------------% c | ido .ne. 99 implies use of reverse communication | c | to compute operations involving OP or shifts. | c %--------------------------------------------------% c if (ido .eq. 3) iparam(8) = np if (ido .ne. 99) go to 9000 c iparam(3) = mxiter iparam(5) = np iparam(9) = nopx iparam(10) = nbx iparam(11) = nrorth c c %------------------------------------% c | Exit if there was an informational | c | error within igraphdsaup2. | c %------------------------------------% c if (info .lt. 0) go to 9000 if (info .eq. 2) info = 3 c if (msglvl .gt. 0) then call igraphivout (logfil, 1, mxiter, ndigit, & '_saupd: number of update iterations taken') call igraphivout (logfil, 1, np, ndigit, & '_saupd: number of "converged" Ritz values') call igraphdvout (logfil, np, workl(Ritz), ndigit, & '_saupd: final Ritz values') call igraphdvout (logfil, np, workl(Bounds), ndigit, & '_saupd: corresponding error bounds') end if c call igraphsecond (t1) tsaupd = t1 - t0 c c 9000 continue c return c c %---------------% c | End of igraphdsaupd | c %---------------% c end leidenbase/src/vendor/arpack/dngets.f0000644000176200001440000001773314447675376017367 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdngets c c\Description: c Given the eigenvalues of the upper Hessenberg matrix H, c computes the NP shifts AMU that are zeros of the polynomial of c degree NP which filters out components of the unwanted eigenvectors c corresponding to the AMU's based on some given criteria. c c NOTE: call this even in the case of user specified shifts in order c to sort the eigenvalues, and error bounds of H for later use. c c\Usage: c call igraphdngets c ( ISHIFT, WHICH, KEV, NP, RITZR, RITZI, BOUNDS, SHIFTR, SHIFTI ) c c\Arguments c ISHIFT Integer. (INPUT) c Method for selecting the implicit shifts at each iteration. c ISHIFT = 0: user specified shifts c ISHIFT = 1: exact shift with respect to the matrix H. c c WHICH Character*2. (INPUT) c Shift selection criteria. c 'LM' -> want the KEV eigenvalues of largest magnitude. c 'SM' -> want the KEV eigenvalues of smallest magnitude. c 'LR' -> want the KEV eigenvalues of largest real part. c 'SR' -> want the KEV eigenvalues of smallest real part. c 'LI' -> want the KEV eigenvalues of largest imaginary part. c 'SI' -> want the KEV eigenvalues of smallest imaginary part. c c KEV Integer. (INPUT/OUTPUT) c INPUT: KEV+NP is the size of the matrix H. c OUTPUT: Possibly increases KEV by one to keep complex conjugate c pairs together. c c NP Integer. (INPUT/OUTPUT) c Number of implicit shifts to be computed. c OUTPUT: Possibly decreases NP by one to keep complex conjugate c pairs together. c c RITZR, Double precision array of length KEV+NP. (INPUT/OUTPUT) c RITZI On INPUT, RITZR and RITZI contain the real and imaginary c parts of the eigenvalues of H. c On OUTPUT, RITZR and RITZI are sorted so that the unwanted c eigenvalues are in the first NP locations and the wanted c portion is in the last KEV locations. When exact shifts are c selected, the unwanted part corresponds to the shifts to c be applied. Also, if ISHIFT .eq. 1, the unwanted eigenvalues c are further sorted so that the ones with largest Ritz values c are first. c c BOUNDS Double precision array of length KEV+NP. (INPUT/OUTPUT) c Error bounds corresponding to the ordering in RITZ. c c SHIFTR, SHIFTI *** USE deprecated as of version 2.1. *** c c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\Routines called: c igraphdsortc ARPACK sorting routine. c dcopy Level 1 BLAS that copies one vector to another . c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/92: Version ' 2.1' c c\SCCS Information: @(#) c FILE: ngets.F SID: 2.3 DATE OF SID: 4/20/96 RELEASE: 2 c c\Remarks c 1. xxxx c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdngets ( ishift, which, kev, np, ritzr, ritzi, & bounds, shiftr, shifti ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character*2 which integer ishift, kev, np c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & bounds(kev+np), ritzr(kev+np), ritzi(kev+np), & shiftr(1), shifti(1) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0, zero = 0.0) c c %---------------% c | Local Scalars | c %---------------% c integer msglvl c c %----------------------% c | External Subroutines | c %----------------------% c external dcopy, igraphdsortc, igraphsecond c c %----------------------% c | Intrinsics Functions | c %----------------------% c intrinsic abs c c %-----------------------% c | Executable Statements | c %-----------------------% c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = mngets c c %----------------------------------------------------% c | LM, SM, LR, SR, LI, SI case. | c | Sort the eigenvalues of H into the desired order | c | and apply the resulting order to BOUNDS. | c | The eigenvalues are sorted so that the wanted part | c | are always in the last KEV locations. | c | We first do a pre-processing sort in order to keep | c | complex conjugate pairs together | c %----------------------------------------------------% c if (which .eq. 'LM') then call igraphdsortc ('LR', .true., kev+np, ritzr, ritzi, bounds) else if (which .eq. 'SM') then call igraphdsortc ('SR', .true., kev+np, ritzr, ritzi, bounds) else if (which .eq. 'LR') then call igraphdsortc ('LM', .true., kev+np, ritzr, ritzi, bounds) else if (which .eq. 'SR') then call igraphdsortc ('SM', .true., kev+np, ritzr, ritzi, bounds) else if (which .eq. 'LI') then call igraphdsortc ('LM', .true., kev+np, ritzr, ritzi, bounds) else if (which .eq. 'SI') then call igraphdsortc ('SM', .true., kev+np, ritzr, ritzi, bounds) end if c call igraphdsortc (which, .true., kev+np, ritzr, ritzi, bounds) c c %-------------------------------------------------------% c | Increase KEV by one if the ( ritzr(np),ritzi(np) ) | c | = ( ritzr(np+1),-ritzi(np+1) ) and ritz(np) .ne. zero | c | Accordingly decrease NP by one. In other words keep | c | complex conjugate pairs together. | c %-------------------------------------------------------% c if ( ( ritzr(np+1) - ritzr(np) ) .eq. zero & .and. ( ritzi(np+1) + ritzi(np) ) .eq. zero ) then np = np - 1 kev = kev + 1 end if c if ( ishift .eq. 1 ) then c c %-------------------------------------------------------% c | Sort the unwanted Ritz values used as shifts so that | c | the ones with largest Ritz estimates are first | c | This will tend to minimize the effects of the | c | forward instability of the iteration when they shifts | c | are applied in subroutine igraphdnapps. | c | Be careful and use 'SR' since we want to sort BOUNDS! | c %-------------------------------------------------------% c call igraphdsortc ( 'SR', .true., np, bounds, ritzr, ritzi ) end if c call igraphsecond (t1) tngets = tngets + (t1 - t0) c if (msglvl .gt. 0) then call igraphivout (logfil, 1, [kev], ndigit, '_ngets: KEV is') call igraphivout (logfil, 1, [np], ndigit, '_ngets: NP is') call igraphdvout (logfil, kev+np, ritzr, ndigit, & '_ngets: Eigenvalues of current H matrix -- real part') call igraphdvout (logfil, kev+np, ritzi, ndigit, & '_ngets: Eigenvalues of current H matrix -- imag part') call igraphdvout (logfil, kev+np, bounds, ndigit, & '_ngets: Ritz estimates of the current KEV+NP Ritz values') end if c return c c %---------------% c | End of igraphdngets | c %---------------% c end leidenbase/src/vendor/arpack/debug.h0000644000176200001440000000135114447675376017160 0ustar liggesusersc c\SCCS Information: @(#) c FILE: debug.h SID: 2.3 DATE OF SID: 11/16/95 RELEASE: 2 c c %---------------------------------% c | See debug.doc for documentation | c %---------------------------------% integer logfil, ndigit, mgetv0, & msaupd, msaup2, msaitr, mseigt, msapps, msgets, mseupd, & mnaupd, mnaup2, mnaitr, mneigh, mnapps, mngets, mneupd, & mcaupd, mcaup2, mcaitr, mceigh, mcapps, mcgets, mceupd common /debug/ & logfil, ndigit, mgetv0, & msaupd, msaup2, msaitr, mseigt, msapps, msgets, mseupd, & mnaupd, mnaup2, mnaitr, mneigh, mnapps, mngets, mneupd, & mcaupd, mcaup2, mcaitr, mceigh, mcapps, mcgets, mceupd leidenbase/src/vendor/arpack/dgetv0.f0000644000176200001440000003206114447675376017263 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdgetv0 c c\Description: c Generate a random initial residual vector for the Arnoldi process. c Force the residual vector to be in the range of the operator OP. c c\Usage: c call igraphdgetv0 c ( IDO, BMAT, ITRY, INITV, N, J, V, LDV, RESID, RNORM, c IPNTR, WORKD, IERR ) c c\Arguments c IDO Integer. (INPUT/OUTPUT) c Reverse communication flag. IDO must be zero on the first c call to igraphdgetv0. c ------------------------------------------------------------- c IDO = 0: first call to the reverse communication interface c IDO = -1: compute Y = OP * X where c IPNTR(1) is the pointer into WORKD for X, c IPNTR(2) is the pointer into WORKD for Y. c This is for the initialization phase to force the c starting vector into the range of OP. c IDO = 2: compute Y = B * X where c IPNTR(1) is the pointer into WORKD for X, c IPNTR(2) is the pointer into WORKD for Y. c IDO = 99: done c ------------------------------------------------------------- c c BMAT Character*1. (INPUT) c BMAT specifies the type of the matrix B in the (generalized) c eigenvalue problem A*x = lambda*B*x. c B = 'I' -> standard eigenvalue problem A*x = lambda*x c B = 'G' -> generalized eigenvalue problem A*x = lambda*B*x c c ITRY Integer. (INPUT) c ITRY counts the number of times that igraphdgetv0 is called. c It should be set to 1 on the initial call to igraphdgetv0. c c INITV Logical variable. (INPUT) c .TRUE. => the initial residual vector is given in RESID. c .FALSE. => generate a random initial residual vector. c c N Integer. (INPUT) c Dimension of the problem. c c J Integer. (INPUT) c Index of the residual vector to be generated, with respect to c the Arnoldi process. J > 1 in case of a "restart". c c V Double precision N by J array. (INPUT) c The first J-1 columns of V contain the current Arnoldi basis c if this is a "restart". c c LDV Integer. (INPUT) c Leading dimension of V exactly as declared in the calling c program. c c RESID Double precision array of length N. (INPUT/OUTPUT) c Initial residual vector to be generated. If RESID is c provided, force RESID into the range of the operator OP. c c RNORM Double precision scalar. (OUTPUT) c B-norm of the generated residual. c c IPNTR Integer array of length 3. (OUTPUT) c c WORKD Double precision work array of length 2*N. (REVERSE COMMUNICATION). c On exit, WORK(1:N) = B*RESID to be used in SSAITR. c c IERR Integer. (OUTPUT) c = 0: Normal exit. c = -1: Cannot generate a nontrivial restarted residual vector c in the range of the operator OP. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly c Restarted Arnoldi Iteration", Rice University Technical Report c TR95-13, Department of Computational and Applied Mathematics. c c\Routines called: c igraphsecond ARPACK utility routine for timing. c igraphdvout ARPACK utility routine for vector output. c dlarnv LAPACK routine for generating a random vector. c dgemv Level 2 BLAS routine for matrix vector multiplication. c dcopy Level 1 BLAS that copies one vector to another. c ddot Level 1 BLAS that computes the scalar product of two vectors. c dnrm2 Level 1 BLAS that computes the norm of a vector. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\SCCS Information: @(#) c FILE: getv0.F SID: 2.6 DATE OF SID: 8/27/96 RELEASE: 2 c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdgetv0 & ( ido, bmat, itry, initv, n, j, v, ldv, resid, rnorm, & ipntr, workd, ierr ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character bmat*1 logical initv integer ido, ierr, itry, j, ldv, n Double precision & rnorm c c %-----------------% c | Array Arguments | c %-----------------% c integer ipntr(3) Double precision & resid(n), v(ldv,j), workd(2*n) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %------------------------% c | Local Scalars & Arrays | c %------------------------% c logical first, inits, orth integer idist, iseed(4), iter, msglvl, jj Double precision & rnorm0 save first, iseed, inits, iter, msglvl, orth, rnorm0 c c %----------------------% c | External Subroutines | c %----------------------% c external dlarnv, igraphdvout, dcopy, dgemv, igraphsecond c c %--------------------% c | External Functions | c %--------------------% c Double precision & ddot, dnrm2 external ddot, dnrm2 c c %---------------------% c | Intrinsic Functions | c %---------------------% c intrinsic abs, sqrt c c %-----------------% c | Data Statements | c %-----------------% c data inits /.true./ c c %-----------------------% c | Executable Statements | c %-----------------------% c c c %-----------------------------------% c | Initialize the seed of the LAPACK | c | random number generator | c %-----------------------------------% c if (inits) then iseed(1) = 1 iseed(2) = 3 iseed(3) = 5 iseed(4) = 7 inits = .false. end if c if (ido .eq. 0) then c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = mgetv0 c ierr = 0 iter = 0 first = .FALSE. orth = .FALSE. c c %-----------------------------------------------------% c | Possibly generate a random starting vector in RESID | c | Use a LAPACK random number generator used by the | c | matrix generation routines. | c | idist = 1: uniform (0,1) distribution; | c | idist = 2: uniform (-1,1) distribution; | c | idist = 3: normal (0,1) distribution; | c %-----------------------------------------------------% c if (.not.initv) then idist = 2 call dlarnv (idist, iseed, n, resid) end if c c %----------------------------------------------------------% c | Force the starting vector into the range of OP to handle | c | the generalized problem when B is possibly (singular). | c %----------------------------------------------------------% c call igraphsecond (t2) if (bmat .eq. 'G') then nopx = nopx + 1 ipntr(1) = 1 ipntr(2) = n + 1 call dcopy (n, resid, 1, workd, 1) ido = -1 go to 9000 end if end if c c %-----------------------------------------% c | Back from computing OP*(initial-vector) | c %-----------------------------------------% c if (first) go to 20 c c %-----------------------------------------------% c | Back from computing B*(orthogonalized-vector) | c %-----------------------------------------------% c if (orth) go to 40 c if (bmat .eq. 'G') then call igraphsecond (t3) tmvopx = tmvopx + (t3 - t2) end if c c %------------------------------------------------------% c | Starting vector is now in the range of OP; r = OP*r; | c | Compute B-norm of starting vector. | c %------------------------------------------------------% c call igraphsecond (t2) first = .TRUE. if (bmat .eq. 'G') then nbx = nbx + 1 call dcopy (n, workd(n+1), 1, resid, 1) ipntr(1) = n + 1 ipntr(2) = 1 ido = 2 go to 9000 else if (bmat .eq. 'I') then call dcopy (n, resid, 1, workd, 1) end if c 20 continue c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c first = .FALSE. if (bmat .eq. 'G') then rnorm0 = ddot (n, resid, 1, workd, 1) rnorm0 = sqrt(abs(rnorm0)) else if (bmat .eq. 'I') then rnorm0 = dnrm2(n, resid, 1) end if rnorm = rnorm0 c c %---------------------------------------------% c | Exit if this is the very first Arnoldi step | c %---------------------------------------------% c if (j .eq. 1) go to 50 c c %---------------------------------------------------------------- c | Otherwise need to B-orthogonalize the starting vector against | c | the current Arnoldi basis using Gram-Schmidt with iter. ref. | c | This is the case where an invariant subspace is encountered | c | in the middle of the Arnoldi factorization. | c | | c | s = V^{T}*B*r; r = r - V*s; | c | | c | Stopping criteria used for iter. ref. is discussed in | c | Parlett's book, page 107 and in Gragg & Reichel TOMS paper. | c %---------------------------------------------------------------% c orth = .TRUE. 30 continue c call dgemv ('T', n, j-1, one, v, ldv, workd, 1, & zero, workd(n+1), 1) call dgemv ('N', n, j-1, -one, v, ldv, workd(n+1), 1, & one, resid, 1) c c %----------------------------------------------------------% c | Compute the B-norm of the orthogonalized starting vector | c %----------------------------------------------------------% c call igraphsecond (t2) if (bmat .eq. 'G') then nbx = nbx + 1 call dcopy (n, resid, 1, workd(n+1), 1) ipntr(1) = n + 1 ipntr(2) = 1 ido = 2 go to 9000 else if (bmat .eq. 'I') then call dcopy (n, resid, 1, workd, 1) end if c 40 continue c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c if (bmat .eq. 'G') then rnorm = ddot (n, resid, 1, workd, 1) rnorm = sqrt(abs(rnorm)) else if (bmat .eq. 'I') then rnorm = dnrm2(n, resid, 1) end if c c %--------------------------------------% c | Check for further orthogonalization. | c %--------------------------------------% c if (msglvl .gt. 2) then call igraphdvout (logfil, 1, [rnorm0], ndigit, & '_getv0: re-orthonalization ; rnorm0 is') call igraphdvout (logfil, 1, [rnorm], ndigit, & '_getv0: re-orthonalization ; rnorm is') end if c if (rnorm .gt. 0.717*rnorm0) go to 50 c iter = iter + 1 if (iter .le. 1) then c c %-----------------------------------% c | Perform iterative refinement step | c %-----------------------------------% c rnorm0 = rnorm go to 30 else c c %------------------------------------% c | Iterative refinement step "failed" | c %------------------------------------% c do 45 jj = 1, n resid(jj) = zero 45 continue rnorm = zero ierr = -1 end if c 50 continue c if (msglvl .gt. 0) then call igraphdvout (logfil, 1, [rnorm], ndigit, & '_getv0: B-norm of initial / restarted starting vector') end if if (msglvl .gt. 2) then call igraphdvout (logfil, n, resid, ndigit, & '_getv0: initial / restarted starting vector') end if ido = 99 c call igraphsecond (t1) tgetv0 = tgetv0 + (t1 - t0) c 9000 continue return c c %---------------% c | End of igraphdgetv0 | c %---------------% c end leidenbase/src/vendor/arpack/dnaupd.f0000644000176200001440000006615114447675376017354 0ustar liggesusersc\BeginDoc c c\Name: igraphdnaupd c c\Description: c Reverse communication interface for the Implicitly Restarted Arnoldi c iteration. This subroutine computes approximations to a few eigenpairs c of a linear operator "OP" with respect to a semi-inner product defined by c a symmetric positive semi-definite real matrix B. B may be the identity c matrix. NOTE: If the linear operator "OP" is real and symmetric c with respect to the real positive semi-definite symmetric matrix B, c i.e. B*OP = (OP')*B, then subroutine ssaupd should be used instead. c c The computed approximate eigenvalues are called Ritz values and c the corresponding approximate eigenvectors are called Ritz vectors. c c igraphdnaupd is usually called iteratively to solve one of the c following problems: c c Mode 1: A*x = lambda*x. c ===> OP = A and B = I. c c Mode 2: A*x = lambda*M*x, M symmetric positive definite c ===> OP = inv[M]*A and B = M. c ===> (If M can be factored see remark 3 below) c c Mode 3: A*x = lambda*M*x, M symmetric semi-definite c ===> OP = Real_Part{ inv[A - sigma*M]*M } and B = M. c ===> shift-and-invert mode (in real arithmetic) c If OP*x = amu*x, then c amu = 1/2 * [ 1/(lambda-sigma) + 1/(lambda-conjg(sigma)) ]. c Note: If sigma is real, i.e. imaginary part of sigma is zero; c Real_Part{ inv[A - sigma*M]*M } == inv[A - sigma*M]*M c amu == 1/(lambda-sigma). c c Mode 4: A*x = lambda*M*x, M symmetric semi-definite c ===> OP = Imaginary_Part{ inv[A - sigma*M]*M } and B = M. c ===> shift-and-invert mode (in real arithmetic) c If OP*x = amu*x, then c amu = 1/2i * [ 1/(lambda-sigma) - 1/(lambda-conjg(sigma)) ]. c c Both mode 3 and 4 give the same enhancement to eigenvalues close to c the (complex) shift sigma. However, as lambda goes to infinity, c the operator OP in mode 4 dampens the eigenvalues more strongly than c does OP defined in mode 3. c c NOTE: The action of w <- inv[A - sigma*M]*v or w <- inv[M]*v c should be accomplished either by a direct method c using a sparse matrix factorization and solving c c [A - sigma*M]*w = v or M*w = v, c c or through an iterative method for solving these c systems. If an iterative method is used, the c convergence test must be more stringent than c the accuracy requirements for the eigenvalue c approximations. c c\Usage: c call igraphdnaupd c ( IDO, BMAT, N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, c IPNTR, WORKD, WORKL, LWORKL, INFO ) c c\Arguments c IDO Integer. (INPUT/OUTPUT) c Reverse communication flag. IDO must be zero on the first c call to igraphdnaupd. IDO will be set internally to c indicate the type of operation to be performed. Control is c then given back to the calling routine which has the c responsibility to carry out the requested operation and call c igraphdnaupd with the result. The operand is given in c WORKD(IPNTR(1)), the result must be put in WORKD(IPNTR(2)). c ------------------------------------------------------------- c IDO = 0: first call to the reverse communication interface c IDO = -1: compute Y = OP * X where c IPNTR(1) is the pointer into WORKD for X, c IPNTR(2) is the pointer into WORKD for Y. c This is for the initialization phase to force the c starting vector into the range of OP. c IDO = 1: compute Y = OP * X where c IPNTR(1) is the pointer into WORKD for X, c IPNTR(2) is the pointer into WORKD for Y. c In mode 3 and 4, the vector B * X is already c available in WORKD(ipntr(3)). It does not c need to be recomputed in forming OP * X. c IDO = 2: compute Y = B * X where c IPNTR(1) is the pointer into WORKD for X, c IPNTR(2) is the pointer into WORKD for Y. c IDO = 3: compute the IPARAM(8) real and imaginary parts c of the shifts where INPTR(14) is the pointer c into WORKL for placing the shifts. See Remark c 5 below. c IDO = 99: done c ------------------------------------------------------------- c c BMAT Character*1. (INPUT) c BMAT specifies the type of the matrix B that defines the c semi-inner product for the operator OP. c BMAT = 'I' -> standard eigenvalue problem A*x = lambda*x c BMAT = 'G' -> generalized eigenvalue problem A*x = lambda*B*x c c N Integer. (INPUT) c Dimension of the eigenproblem. c c WHICH Character*2. (INPUT) c 'LM' -> want the NEV eigenvalues of largest magnitude. c 'SM' -> want the NEV eigenvalues of smallest magnitude. c 'LR' -> want the NEV eigenvalues of largest real part. c 'SR' -> want the NEV eigenvalues of smallest real part. c 'LI' -> want the NEV eigenvalues of largest imaginary part. c 'SI' -> want the NEV eigenvalues of smallest imaginary part. c c NEV Integer. (INPUT) c Number of eigenvalues of OP to be computed. 0 < NEV < N-1. c c TOL Double precision scalar. (INPUT) c Stopping criterion: the relative accuracy of the Ritz value c is considered acceptable if BOUNDS(I) .LE. TOL*ABS(RITZ(I)) c where ABS(RITZ(I)) is the magnitude when RITZ(I) is complex. c DEFAULT = DLAMCH('EPS') (machine precision as computed c by the LAPACK auxiliary subroutine DLAMCH). c c RESID Double precision array of length N. (INPUT/OUTPUT) c On INPUT: c If INFO .EQ. 0, a random initial residual vector is used. c If INFO .NE. 0, RESID contains the initial residual vector, c possibly from a previous run. c On OUTPUT: c RESID contains the final residual vector. c c NCV Integer. (INPUT) c Number of columns of the matrix V. NCV must satisfy the two c inequalities 2 <= NCV-NEV and NCV <= N. c This will indicate how many Arnoldi vectors are generated c at each iteration. After the startup phase in which NEV c Arnoldi vectors are generated, the algorithm generates c approximately NCV-NEV Arnoldi vectors at each subsequent update c iteration. Most of the cost in generating each Arnoldi vector is c in the matrix-vector operation OP*x. c NOTE: 2 <= NCV-NEV in order that complex conjugate pairs of Ritz c values are kept together. (See remark 4 below) c c V Double precision array N by NCV. (OUTPUT) c Contains the final set of Arnoldi basis vectors. c c LDV Integer. (INPUT) c Leading dimension of V exactly as declared in the calling program. c c IPARAM Integer array of length 11. (INPUT/OUTPUT) c IPARAM(1) = ISHIFT: method for selecting the implicit shifts. c The shifts selected at each iteration are used to restart c the Arnoldi iteration in an implicit fashion. c ------------------------------------------------------------- c ISHIFT = 0: the shifts are provided by the user via c reverse communication. The real and imaginary c parts of the NCV eigenvalues of the Hessenberg c matrix H are returned in the part of the WORKL c array corresponding to RITZR and RITZI. See remark c 5 below. c ISHIFT = 1: exact shifts with respect to the current c Hessenberg matrix H. This is equivalent to c restarting the iteration with a starting vector c that is a linear combination of approximate Schur c vectors associated with the "wanted" Ritz values. c ------------------------------------------------------------- c c IPARAM(2) = No longer referenced. c c IPARAM(3) = MXITER c On INPUT: maximum number of Arnoldi update iterations allowed. c On OUTPUT: actual number of Arnoldi update iterations taken. c c IPARAM(4) = NB: blocksize to be used in the recurrence. c The code currently works only for NB = 1. c c IPARAM(5) = NCONV: number of "converged" Ritz values. c This represents the number of Ritz values that satisfy c the convergence criterion. c c IPARAM(6) = IUPD c No longer referenced. Implicit restarting is ALWAYS used. c c IPARAM(7) = MODE c On INPUT determines what type of eigenproblem is being solved. c Must be 1,2,3,4; See under \Description of igraphdnaupd for the c four modes available. c c IPARAM(8) = NP c When ido = 3 and the user provides shifts through reverse c communication (IPARAM(1)=0), igraphdnaupd returns NP, the number c of shifts the user is to provide. 0 < NP <=NCV-NEV. See Remark c 5 below. c c IPARAM(9) = NUMOP, IPARAM(10) = NUMOPB, IPARAM(11) = NUMREO, c OUTPUT: NUMOP = total number of OP*x operations, c NUMOPB = total number of B*x operations if BMAT='G', c NUMREO = total number of steps of re-orthogonalization. c c IPNTR Integer array of length 14. (OUTPUT) c Pointer to mark the starting locations in the WORKD and WORKL c arrays for matrices/vectors used by the Arnoldi iteration. c ------------------------------------------------------------- c IPNTR(1): pointer to the current operand vector X in WORKD. c IPNTR(2): pointer to the current result vector Y in WORKD. c IPNTR(3): pointer to the vector B * X in WORKD when used in c the shift-and-invert mode. c IPNTR(4): pointer to the next available location in WORKL c that is untouched by the program. c IPNTR(5): pointer to the NCV by NCV upper Hessenberg matrix c H in WORKL. c IPNTR(6): pointer to the real part of the ritz value array c RITZR in WORKL. c IPNTR(7): pointer to the imaginary part of the ritz value array c RITZI in WORKL. c IPNTR(8): pointer to the Ritz estimates in array WORKL associated c with the Ritz values located in RITZR and RITZI in WORKL. c c IPNTR(14): pointer to the NP shifts in WORKL. See Remark 5 below. c c Note: IPNTR(9:13) is only referenced by igraphdneupd. See Remark 2 below. c c IPNTR(9): pointer to the real part of the NCV RITZ values of the c original system. c IPNTR(10): pointer to the imaginary part of the NCV RITZ values of c the original system. c IPNTR(11): pointer to the NCV corresponding error bounds. c IPNTR(12): pointer to the NCV by NCV upper quasi-triangular c Schur matrix for H. c IPNTR(13): pointer to the NCV by NCV matrix of eigenvectors c of the upper Hessenberg matrix H. Only referenced by c igraphdneupd if RVEC = .TRUE. See Remark 2 below. c ------------------------------------------------------------- c c WORKD Double precision work array of length 3*N. (REVERSE COMMUNICATION) c Distributed array to be used in the basic Arnoldi iteration c for reverse communication. The user should not use WORKD c as temporary workspace during the iteration. Upon termination c WORKD(1:N) contains B*RESID(1:N). If an invariant subspace c associated with the converged Ritz values is desired, see remark c 2 below, subroutine igraphdneupd uses this output. c See Data Distribution Note below. c c WORKL Double precision work array of length LWORKL. (OUTPUT/WORKSPACE) c Private (replicated) array on each PE or array allocated on c the front end. See Data Distribution Note below. c c LWORKL Integer. (INPUT) c LWORKL must be at least 3*NCV**2 + 6*NCV. c c INFO Integer. (INPUT/OUTPUT) c If INFO .EQ. 0, a randomly initial residual vector is used. c If INFO .NE. 0, RESID contains the initial residual vector, c possibly from a previous run. c Error flag on output. c = 0: Normal exit. c = 1: Maximum number of iterations taken. c All possible eigenvalues of OP has been found. IPARAM(5) c returns the number of wanted converged Ritz values. c = 2: No longer an informational error. Deprecated starting c with release 2 of ARPACK. c = 3: No shifts could be applied during a cycle of the c Implicitly restarted Arnoldi iteration. One possibility c is to increase the size of NCV relative to NEV. c See remark 4 below. c = -1: N must be positive. c = -2: NEV must be positive. c = -3: NCV-NEV >= 2 and less than or equal to N. c = -4: The maximum number of Arnoldi update iteration c must be greater than zero. c = -5: WHICH must be one of 'LM', 'SM', 'LR', 'SR', 'LI', 'SI' c = -6: BMAT must be one of 'I' or 'G'. c = -7: Length of private work array is not sufficient. c = -8: Error return from LAPACK eigenvalue calculation; c = -9: Starting vector is zero. c = -10: IPARAM(7) must be 1,2,3,4. c = -11: IPARAM(7) = 1 and BMAT = 'G' are incompatable. c = -12: IPARAM(1) must be equal to 0 or 1. c = -9999: Could not build an Arnoldi factorization. c IPARAM(5) returns the size of the current Arnoldi c factorization. c c\Remarks c 1. The computed Ritz values are approximate eigenvalues of OP. The c selection of WHICH should be made with this in mind when c Mode = 3 and 4. After convergence, approximate eigenvalues of the c original problem may be obtained with the ARPACK subroutine igraphdneupd. c c 2. If a basis for the invariant subspace corresponding to the converged Ritz c values is needed, the user must call igraphdneupd immediately following c completion of igraphdnaupd. This is new starting with release 2 of ARPACK. c c 3. If M can be factored into a Cholesky factorization M = LL' c then Mode = 2 should not be selected. Instead one should use c Mode = 1 with OP = inv(L)*A*inv(L'). Appropriate triangular c linear systems should be solved with L and L' rather c than computing inverses. After convergence, an approximate c eigenvector z of the original problem is recovered by solving c L'z = x where x is a Ritz vector of OP. c c 4. At present there is no a-priori analysis to guide the selection c of NCV relative to NEV. The only formal requrement is that NCV > NEV + 2. c However, it is recommended that NCV .ge. 2*NEV+1. If many problems of c the same type are to be solved, one should experiment with increasing c NCV while keeping NEV fixed for a given test problem. This will c usually decrease the required number of OP*x operations but it c also increases the work and storage required to maintain the orthogonal c basis vectors. The optimal "cross-over" with respect to CPU time c is problem dependent and must be determined empirically. c See Chapter 8 of Reference 2 for further information. c c 5. When IPARAM(1) = 0, and IDO = 3, the user needs to provide the c NP = IPARAM(8) real and imaginary parts of the shifts in locations c real part imaginary part c ----------------------- -------------- c 1 WORKL(IPNTR(14)) WORKL(IPNTR(14)+NP) c 2 WORKL(IPNTR(14)+1) WORKL(IPNTR(14)+NP+1) c . . c . . c . . c NP WORKL(IPNTR(14)+NP-1) WORKL(IPNTR(14)+2*NP-1). c c Only complex conjugate pairs of shifts may be applied and the pairs c must be placed in consecutive locations. The real part of the c eigenvalues of the current upper Hessenberg matrix are located in c WORKL(IPNTR(6)) through WORKL(IPNTR(6)+NCV-1) and the imaginary part c in WORKL(IPNTR(7)) through WORKL(IPNTR(7)+NCV-1). They are ordered c according to the order defined by WHICH. The complex conjugate c pairs are kept together and the associated Ritz estimates are located in c WORKL(IPNTR(8)), WORKL(IPNTR(8)+1), ... , WORKL(IPNTR(8)+NCV-1). c c----------------------------------------------------------------------- c c\Data Distribution Note: c c Fortran-D syntax: c ================ c Double precision resid(n), v(ldv,ncv), workd(3*n), workl(lworkl) c decompose d1(n), d2(n,ncv) c align resid(i) with d1(i) c align v(i,j) with d2(i,j) c align workd(i) with d1(i) range (1:n) c align workd(i) with d1(i-n) range (n+1:2*n) c align workd(i) with d1(i-2*n) range (2*n+1:3*n) c distribute d1(block), d2(block,:) c replicated workl(lworkl) c c Cray MPP syntax: c =============== c Double precision resid(n), v(ldv,ncv), workd(n,3), workl(lworkl) c shared resid(block), v(block,:), workd(block,:) c replicated workl(lworkl) c c CM2/CM5 syntax: c ============== c c----------------------------------------------------------------------- c c include 'ex-nonsym.doc' c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly c Restarted Arnoldi Iteration", Rice University Technical Report c TR95-13, Department of Computational and Applied Mathematics. c 3. B.N. Parlett & Y. Saad, "Complex Shift and Invert Strategies for c Real Matrices", Linear Algebra and its Applications, vol 88/89, c pp 575-595, (1987). c c\Routines called: c igraphdnaup2 ARPACK routine that implements the Implicitly Restarted c Arnoldi Iteration. c igraphivout ARPACK utility routine that prints integers. c igraphsecond ARPACK utility routine for timing. c igraphdvout ARPACK utility routine that prints vectors. c dlamch LAPACK routine that determines machine constants. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c 12/16/93: Version '1.1' c c\SCCS Information: @(#) c FILE: naupd.F SID: 2.5 DATE OF SID: 8/27/96 RELEASE: 2 c c\Remarks c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdnaupd & ( ido, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, & ipntr, workd, workl, lworkl, info ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character bmat*1, which*2 integer ido, info, ldv, lworkl, n, ncv, nev Double precision & tol c c %-----------------% c | Array Arguments | c %-----------------% c integer iparam(11), ipntr(14) Double precision & resid(n), v(ldv,ncv), workd(3*n), workl(lworkl) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c integer bounds, ierr, ih, iq, ishift, iupd, iw, & ldh, ldq, levec, mode, msglvl, mxiter, nb, & nev0, next, np, ritzi, ritzr, j save bounds, ih, iq, ishift, iupd, iw, ldh, ldq, & levec, mode, msglvl, mxiter, nb, nev0, next, & np, ritzi, ritzr c c %----------------------% c | External Subroutines | c %----------------------% c external igraphdnaup2, igraphdvout, igraphivout, & igraphsecond, igraphdstatn c c %--------------------% c | External Functions | c %--------------------% c Double precision & dlamch external dlamch c c %-----------------------% c | Executable Statements | c %-----------------------% c if (ido .eq. 0) then c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphdstatn call igraphsecond (t0) msglvl = mnaupd c c %----------------% c | Error checking | c %----------------% c ierr = 0 ishift = iparam(1) levec = iparam(2) mxiter = iparam(3) nb = iparam(4) c c %--------------------------------------------% c | Revision 2 performs only implicit restart. | c %--------------------------------------------% c iupd = 1 mode = iparam(7) c if (n .le. 0) then ierr = -1 else if (nev .le. 0) then ierr = -2 else if (ncv .le. nev+1 .or. ncv .gt. n) then ierr = -3 else if (mxiter .le. 0) then ierr = -4 else if (which .ne. 'LM' .and. & which .ne. 'SM' .and. & which .ne. 'LR' .and. & which .ne. 'SR' .and. & which .ne. 'LI' .and. & which .ne. 'SI') then ierr = -5 else if (bmat .ne. 'I' .and. bmat .ne. 'G') then ierr = -6 else if (lworkl .lt. 3*ncv**2 + 6*ncv) then ierr = -7 else if (mode .lt. 1 .or. mode .gt. 5) then ierr = -10 else if (mode .eq. 1 .and. bmat .eq. 'G') then ierr = -11 else if (ishift .lt. 0 .or. ishift .gt. 1) then ierr = -12 end if c c %------------% c | Error Exit | c %------------% c if (ierr .ne. 0) then info = ierr ido = 99 go to 9000 end if c c %------------------------% c | Set default parameters | c %------------------------% c if (nb .le. 0) nb = 1 if (tol .le. zero) tol = dlamch('EpsMach') c c %----------------------------------------------% c | NP is the number of additional steps to | c | extend the length NEV Lanczos factorization. | c | NEV0 is the local variable designating the | c | size of the invariant subspace desired. | c %----------------------------------------------% c np = ncv - nev nev0 = nev c c %-----------------------------% c | Zero out internal workspace | c %-----------------------------% c do 10 j = 1, 3*ncv**2 + 6*ncv workl(j) = zero 10 continue c c %-------------------------------------------------------------% c | Pointer into WORKL for address of H, RITZ, BOUNDS, Q | c | etc... and the remaining workspace. | c | Also update pointer to be used on output. | c | Memory is laid out as follows: | c | workl(1:ncv*ncv) := generated Hessenberg matrix | c | workl(ncv*ncv+1:ncv*ncv+2*ncv) := real and imaginary | c | parts of ritz values | c | workl(ncv*ncv+2*ncv+1:ncv*ncv+3*ncv) := error bounds | c | workl(ncv*ncv+3*ncv+1:2*ncv*ncv+3*ncv) := rotation matrix Q | c | workl(2*ncv*ncv+3*ncv+1:3*ncv*ncv+6*ncv) := workspace | c | The final workspace is needed by subroutine igraphdneigh called | c | by igraphdnaup2. Subroutine igraphdneigh calls LAPACK routines for | c | calculating eigenvalues and the last row of the eigenvector | c | matrix. | c %-------------------------------------------------------------% c ldh = ncv ldq = ncv ih = 1 ritzr = ih + ldh*ncv ritzi = ritzr + ncv bounds = ritzi + ncv iq = bounds + ncv iw = iq + ldq*ncv next = iw + ncv**2 + 3*ncv c ipntr(4) = next ipntr(5) = ih ipntr(6) = ritzr ipntr(7) = ritzi ipntr(8) = bounds ipntr(14) = iw c end if c c %-------------------------------------------------------% c | Carry out the Implicitly restarted Arnoldi Iteration. | c %-------------------------------------------------------% c call igraphdnaup2 & ( ido, bmat, n, which, nev0, np, tol, resid, mode, iupd, & ishift, mxiter, v, ldv, workl(ih), ldh, workl(ritzr), & workl(ritzi), workl(bounds), workl(iq), ldq, workl(iw), & ipntr, workd, info ) c c %--------------------------------------------------% c | ido .ne. 99 implies use of reverse communication | c | to compute operations involving OP or shifts. | c %--------------------------------------------------% c if (ido .eq. 3) iparam(8) = np if (ido .ne. 99) go to 9000 c iparam(3) = mxiter iparam(5) = np iparam(9) = nopx iparam(10) = nbx iparam(11) = nrorth c c %------------------------------------% c | Exit if there was an informational | c | error within igraphdnaup2. | c %------------------------------------% c if (info .lt. 0) go to 9000 if (info .eq. 2) info = 3 c if (msglvl .gt. 0) then call igraphivout (logfil, 1, [mxiter], ndigit, & '_naupd: Number of update iterations taken') call igraphivout (logfil, 1, [np], ndigit, & '_naupd: Number of wanted "converged" Ritz values') call igraphdvout (logfil, np, workl(ritzr), ndigit, & '_naupd: Real part of the final Ritz values') call igraphdvout (logfil, np, workl(ritzi), ndigit, & '_naupd: Imaginary part of the final Ritz values') call igraphdvout (logfil, np, workl(bounds), ndigit, & '_naupd: Associated Ritz estimates') end if c call igraphsecond (t1) tnaupd = t1 - t0 c c 9000 continue c return c c %---------------% c | End of igraphdnaupd | c %---------------% c end leidenbase/src/vendor/arpack/dsaitr.f0000644000176200001440000007453114447675376017370 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdsaitr c c\Description: c Reverse communication interface for applying NP additional steps to c a K step symmetric Arnoldi factorization. c c Input: OP*V_{k} - V_{k}*H = r_{k}*e_{k}^T c c with (V_{k}^T)*B*V_{k} = I, (V_{k}^T)*B*r_{k} = 0. c c Output: OP*V_{k+p} - V_{k+p}*H = r_{k+p}*e_{k+p}^T c c with (V_{k+p}^T)*B*V_{k+p} = I, (V_{k+p}^T)*B*r_{k+p} = 0. c c where OP and B are as in igraphdsaupd. The B-norm of r_{k+p} is also c computed and returned. c c\Usage: c call igraphdsaitr c ( IDO, BMAT, N, K, NP, MODE, RESID, RNORM, V, LDV, H, LDH, c IPNTR, WORKD, INFO ) c c\Arguments c IDO Integer. (INPUT/OUTPUT) c Reverse communication flag. c ------------------------------------------------------------- c IDO = 0: first call to the reverse communication interface c IDO = -1: compute Y = OP * X where c IPNTR(1) is the pointer into WORK for X, c IPNTR(2) is the pointer into WORK for Y. c This is for the restart phase to force the new c starting vector into the range of OP. c IDO = 1: compute Y = OP * X where c IPNTR(1) is the pointer into WORK for X, c IPNTR(2) is the pointer into WORK for Y, c IPNTR(3) is the pointer into WORK for B * X. c IDO = 2: compute Y = B * X where c IPNTR(1) is the pointer into WORK for X, c IPNTR(2) is the pointer into WORK for Y. c IDO = 99: done c ------------------------------------------------------------- c When the routine is used in the "shift-and-invert" mode, the c vector B * Q is already available and does not need to be c recomputed in forming OP * Q. c c BMAT Character*1. (INPUT) c BMAT specifies the type of matrix B that defines the c semi-inner product for the operator OP. See igraphdsaupd. c B = 'I' -> standard eigenvalue problem A*x = lambda*x c B = 'G' -> generalized eigenvalue problem A*x = lambda*M*x c c N Integer. (INPUT) c Dimension of the eigenproblem. c c K Integer. (INPUT) c Current order of H and the number of columns of V. c c NP Integer. (INPUT) c Number of additional Arnoldi steps to take. c c MODE Integer. (INPUT) c Signifies which form for "OP". If MODE=2 then c a reduction in the number of B matrix vector multiplies c is possible since the B-norm of OP*x is equivalent to c the inv(B)-norm of A*x. c c RESID Double precision array of length N. (INPUT/OUTPUT) c On INPUT: RESID contains the residual vector r_{k}. c On OUTPUT: RESID contains the residual vector r_{k+p}. c c RNORM Double precision scalar. (INPUT/OUTPUT) c On INPUT the B-norm of r_{k}. c On OUTPUT the B-norm of the updated residual r_{k+p}. c c V Double precision N by K+NP array. (INPUT/OUTPUT) c On INPUT: V contains the Arnoldi vectors in the first K c columns. c On OUTPUT: V contains the new NP Arnoldi vectors in the next c NP columns. The first K columns are unchanged. c c LDV Integer. (INPUT) c Leading dimension of V exactly as declared in the calling c program. c c H Double precision (K+NP) by 2 array. (INPUT/OUTPUT) c H is used to store the generated symmetric tridiagonal matrix c with the subdiagonal in the first column starting at H(2,1) c and the main diagonal in the igraphsecond column. c c LDH Integer. (INPUT) c Leading dimension of H exactly as declared in the calling c program. c c IPNTR Integer array of length 3. (OUTPUT) c Pointer to mark the starting locations in the WORK for c vectors used by the Arnoldi iteration. c ------------------------------------------------------------- c IPNTR(1): pointer to the current operand vector X. c IPNTR(2): pointer to the current result vector Y. c IPNTR(3): pointer to the vector B * X when used in the c shift-and-invert mode. X is the current operand. c ------------------------------------------------------------- c c WORKD Double precision work array of length 3*N. (REVERSE COMMUNICATION) c Distributed array to be used in the basic Arnoldi iteration c for reverse communication. The calling program should not c use WORKD as temporary workspace during the iteration !!!!!! c On INPUT, WORKD(1:N) = B*RESID where RESID is associated c with the K step Arnoldi factorization. Used to save some c computation at the first step. c On OUTPUT, WORKD(1:N) = B*RESID where RESID is associated c with the K+NP step Arnoldi factorization. c c INFO Integer. (OUTPUT) c = 0: Normal exit. c > 0: Size of an invariant subspace of OP is found that is c less than K + NP. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\Routines called: c igraphdgetv0 ARPACK routine to generate the initial vector. c igraphivout ARPACK utility routine that prints integers. c igraphdmout ARPACK utility routine that prints matrices. c igraphdvout ARPACK utility routine that prints vectors. c dlamch LAPACK routine that determines machine constants. c dlascl LAPACK routine for careful scaling of a matrix. c dgemv Level 2 BLAS routine for matrix vector multiplication. c daxpy Level 1 BLAS that computes a vector triad. c dscal Level 1 BLAS that scales a vector. c dcopy Level 1 BLAS that copies one vector to another . c ddot Level 1 BLAS that computes the scalar product of two vectors. c dnrm2 Level 1 BLAS that computes the norm of a vector. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/93: Version ' 2.4' c c\SCCS Information: @(#) c FILE: saitr.F SID: 2.6 DATE OF SID: 8/28/96 RELEASE: 2 c c\Remarks c The algorithm implemented is: c c restart = .false. c Given V_{k} = [v_{1}, ..., v_{k}], r_{k}; c r_{k} contains the initial residual vector even for k = 0; c Also assume that rnorm = || B*r_{k} || and B*r_{k} are already c computed by the calling program. c c betaj = rnorm ; p_{k+1} = B*r_{k} ; c For j = k+1, ..., k+np Do c 1) if ( betaj < tol ) stop or restart depending on j. c if ( restart ) generate a new starting vector. c 2) v_{j} = r(j-1)/betaj; V_{j} = [V_{j-1}, v_{j}]; c p_{j} = p_{j}/betaj c 3) r_{j} = OP*v_{j} where OP is defined as in igraphdsaupd c For shift-invert mode p_{j} = B*v_{j} is already available. c wnorm = || OP*v_{j} || c 4) Compute the j-th step residual vector. c w_{j} = V_{j}^T * B * OP * v_{j} c r_{j} = OP*v_{j} - V_{j} * w_{j} c alphaj <- j-th component of w_{j} c rnorm = || r_{j} || c betaj+1 = rnorm c If (rnorm > 0.717*wnorm) accept step and go back to 1) c 5) Re-orthogonalization step: c s = V_{j}'*B*r_{j} c r_{j} = r_{j} - V_{j}*s; rnorm1 = || r_{j} || c alphaj = alphaj + s_{j}; c 6) Iterative refinement step: c If (rnorm1 > 0.717*rnorm) then c rnorm = rnorm1 c accept step and go back to 1) c Else c rnorm = rnorm1 c If this is the first time in step 6), go to 5) c Else r_{j} lies in the span of V_{j} numerically. c Set r_{j} = 0 and rnorm = 0; go to 1) c EndIf c End Do c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdsaitr & (ido, bmat, n, k, np, mode, resid, rnorm, v, ldv, h, ldh, & ipntr, workd, info) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character bmat*1 integer ido, info, k, ldh, ldv, n, mode, np Double precision & rnorm c c %-----------------% c | Array Arguments | c %-----------------% c integer ipntr(3) Double precision & h(ldh,2), resid(n), v(ldv,k+np), workd(3*n) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c logical first, orth1, orth2, rstart, step3, step4 integer i, ierr, ipj, irj, ivj, iter, itry, j, msglvl, & infol, jj Double precision & rnorm1, wnorm, safmin, temp1 save orth1, orth2, rstart, step3, step4, & ierr, ipj, irj, ivj, iter, itry, j, msglvl, & rnorm1, safmin, wnorm c c %-----------------------% c | Local Array Arguments | c %-----------------------% c Double precision & xtemp(2) c c %----------------------% c | External Subroutines | c %----------------------% c external daxpy, dcopy, dscal, dgemv, igraphdgetv0, & igraphdvout, igraphdmout, & dlascl, igraphivout, igraphsecond c c %--------------------% c | External Functions | c %--------------------% c Double precision & ddot, dnrm2, dlamch external ddot, dnrm2, dlamch c c %-----------------% c | Data statements | c %-----------------% c data first / .true. / c c %-----------------------% c | Executable Statements | c %-----------------------% c if (first) then first = .false. c c %--------------------------------% c | safmin = safe minimum is such | c | that 1/sfmin does not overflow | c %--------------------------------% c safmin = dlamch('safmin') end if c if (ido .eq. 0) then c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = msaitr c c %------------------------------% c | Initial call to this routine | c %------------------------------% c info = 0 step3 = .false. step4 = .false. rstart = .false. orth1 = .false. orth2 = .false. c c %--------------------------------% c | Pointer to the current step of | c | the factorization to build | c %--------------------------------% c j = k + 1 c c %------------------------------------------% c | Pointers used for reverse communication | c | when using WORKD. | c %------------------------------------------% c ipj = 1 irj = ipj + n ivj = irj + n end if c c %-------------------------------------------------% c | When in reverse communication mode one of: | c | STEP3, STEP4, ORTH1, ORTH2, RSTART | c | will be .true. | c | STEP3: return from computing OP*v_{j}. | c | STEP4: return from computing B-norm of OP*v_{j} | c | ORTH1: return from computing B-norm of r_{j+1} | c | ORTH2: return from computing B-norm of | c | correction to the residual vector. | c | RSTART: return from OP computations needed by | c | igraphdgetv0. | c %-------------------------------------------------% c if (step3) go to 50 if (step4) go to 60 if (orth1) go to 70 if (orth2) go to 90 if (rstart) go to 30 c c %------------------------------% c | Else this is the first step. | c %------------------------------% c c %--------------------------------------------------------------% c | | c | A R N O L D I I T E R A T I O N L O O P | c | | c | Note: B*r_{j-1} is already in WORKD(1:N)=WORKD(IPJ:IPJ+N-1) | c %--------------------------------------------------------------% c 1000 continue c if (msglvl .gt. 2) then call igraphivout (logfil, 1, [j], ndigit, & '_saitr: generating Arnoldi vector no.') call igraphdvout (logfil, 1, [rnorm], ndigit, & '_saitr: B-norm of the current residual =') end if c c %---------------------------------------------------------% c | Check for exact zero. Equivalent to determing whether a | c | j-step Arnoldi factorization is present. | c %---------------------------------------------------------% c if (rnorm .gt. zero) go to 40 c c %---------------------------------------------------% c | Invariant subspace found, generate a new starting | c | vector which is orthogonal to the current Arnoldi | c | basis and continue the iteration. | c %---------------------------------------------------% c if (msglvl .gt. 0) then call igraphivout (logfil, 1, [j], ndigit, & '_saitr: ****** restart at step ******') end if c c %---------------------------------------------% c | ITRY is the loop variable that controls the | c | maximum amount of times that a restart is | c | attempted. NRSTRT is used by stat.h | c %---------------------------------------------% c nrstrt = nrstrt + 1 itry = 1 20 continue rstart = .true. ido = 0 30 continue c c %--------------------------------------% c | If in reverse communication mode and | c | RSTART = .true. flow returns here. | c %--------------------------------------% c call igraphdgetv0 (ido, bmat, itry, .false., n, j, v, ldv, & resid, rnorm, ipntr, workd, ierr) if (ido .ne. 99) go to 9000 if (ierr .lt. 0) then itry = itry + 1 if (itry .le. 3) go to 20 c c %------------------------------------------------% c | Give up after several restart attempts. | c | Set INFO to the size of the invariant subspace | c | which spans OP and exit. | c %------------------------------------------------% c info = j - 1 call igraphsecond (t1) tsaitr = tsaitr + (t1 - t0) ido = 99 go to 9000 end if c 40 continue c c %---------------------------------------------------------% c | STEP 2: v_{j} = r_{j-1}/rnorm and p_{j} = p_{j}/rnorm | c | Note that p_{j} = B*r_{j-1}. In order to avoid overflow | c | when reciprocating a small RNORM, test against lower | c | machine bound. | c %---------------------------------------------------------% c call dcopy (n, resid, 1, v(1,j), 1) if (rnorm .ge. safmin) then temp1 = one / rnorm call dscal (n, temp1, v(1,j), 1) call dscal (n, temp1, workd(ipj), 1) else c c %-----------------------------------------% c | To scale both v_{j} and p_{j} carefully | c | use LAPACK routine SLASCL | c %-----------------------------------------% c call dlascl ('General', i, i, rnorm, one, n, 1, & v(1,j), n, infol) call dlascl ('General', i, i, rnorm, one, n, 1, & workd(ipj), n, infol) end if c c %------------------------------------------------------% c | STEP 3: r_{j} = OP*v_{j}; Note that p_{j} = B*v_{j} | c | Note that this is not quite yet r_{j}. See STEP 4 | c %------------------------------------------------------% c step3 = .true. nopx = nopx + 1 call igraphsecond (t2) call dcopy (n, v(1,j), 1, workd(ivj), 1) ipntr(1) = ivj ipntr(2) = irj ipntr(3) = ipj ido = 1 c c %-----------------------------------% c | Exit in order to compute OP*v_{j} | c %-----------------------------------% c go to 9000 50 continue c c %-----------------------------------% c | Back from reverse communication; | c | WORKD(IRJ:IRJ+N-1) := OP*v_{j}. | c %-----------------------------------% c call igraphsecond (t3) tmvopx = tmvopx + (t3 - t2) c step3 = .false. c c %------------------------------------------% c | Put another copy of OP*v_{j} into RESID. | c %------------------------------------------% c call dcopy (n, workd(irj), 1, resid, 1) c c %-------------------------------------------% c | STEP 4: Finish extending the symmetric | c | Arnoldi to length j. If MODE = 2 | c | then B*OP = B*inv(B)*A = A and | c | we don't need to compute B*OP. | c | NOTE: If MODE = 2 WORKD(IVJ:IVJ+N-1) is | c | assumed to have A*v_{j}. | c %-------------------------------------------% c if (mode .eq. 2) go to 65 call igraphsecond (t2) if (bmat .eq. 'G') then nbx = nbx + 1 step4 = .true. ipntr(1) = irj ipntr(2) = ipj ido = 2 c c %-------------------------------------% c | Exit in order to compute B*OP*v_{j} | c %-------------------------------------% c go to 9000 else if (bmat .eq. 'I') then call dcopy(n, resid, 1 , workd(ipj), 1) end if 60 continue c c %-----------------------------------% c | Back from reverse communication; | c | WORKD(IPJ:IPJ+N-1) := B*OP*v_{j}. | c %-----------------------------------% c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c step4 = .false. c c %-------------------------------------% c | The following is needed for STEP 5. | c | Compute the B-norm of OP*v_{j}. | c %-------------------------------------% c 65 continue if (mode .eq. 2) then c c %----------------------------------% c | Note that the B-norm of OP*v_{j} | c | is the inv(B)-norm of A*v_{j}. | c %----------------------------------% c wnorm = ddot (n, resid, 1, workd(ivj), 1) wnorm = sqrt(abs(wnorm)) else if (bmat .eq. 'G') then wnorm = ddot (n, resid, 1, workd(ipj), 1) wnorm = sqrt(abs(wnorm)) else if (bmat .eq. 'I') then wnorm = dnrm2(n, resid, 1) end if c c %-----------------------------------------% c | Compute the j-th residual corresponding | c | to the j step factorization. | c | Use Classical Gram Schmidt and compute: | c | w_{j} <- V_{j}^T * B * OP * v_{j} | c | r_{j} <- OP*v_{j} - V_{j} * w_{j} | c %-----------------------------------------% c c c %------------------------------------------% c | Compute the j Fourier coefficients w_{j} | c | WORKD(IPJ:IPJ+N-1) contains B*OP*v_{j}. | c %------------------------------------------% c if (mode .ne. 2 ) then call dgemv('T', n, j, one, v, ldv, workd(ipj), 1, zero, & workd(irj), 1) else if (mode .eq. 2) then call dgemv('T', n, j, one, v, ldv, workd(ivj), 1, zero, & workd(irj), 1) end if c c %--------------------------------------% c | Orthgonalize r_{j} against V_{j}. | c | RESID contains OP*v_{j}. See STEP 3. | c %--------------------------------------% c call dgemv('N', n, j, -one, v, ldv, workd(irj), 1, one, & resid, 1) c c %--------------------------------------% c | Extend H to have j rows and columns. | c %--------------------------------------% c h(j,2) = workd(irj + j - 1) if (j .eq. 1 .or. rstart) then h(j,1) = zero else h(j,1) = rnorm end if call igraphsecond (t4) c orth1 = .true. iter = 0 c call igraphsecond (t2) if (bmat .eq. 'G') then nbx = nbx + 1 call dcopy (n, resid, 1, workd(irj), 1) ipntr(1) = irj ipntr(2) = ipj ido = 2 c c %----------------------------------% c | Exit in order to compute B*r_{j} | c %----------------------------------% c go to 9000 else if (bmat .eq. 'I') then call dcopy (n, resid, 1, workd(ipj), 1) end if 70 continue c c %---------------------------------------------------% c | Back from reverse communication if ORTH1 = .true. | c | WORKD(IPJ:IPJ+N-1) := B*r_{j}. | c %---------------------------------------------------% c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c orth1 = .false. c c %------------------------------% c | Compute the B-norm of r_{j}. | c %------------------------------% c if (bmat .eq. 'G') then rnorm = ddot (n, resid, 1, workd(ipj), 1) rnorm = sqrt(abs(rnorm)) else if (bmat .eq. 'I') then rnorm = dnrm2(n, resid, 1) end if c c %-----------------------------------------------------------% c | STEP 5: Re-orthogonalization / Iterative refinement phase | c | Maximum NITER_ITREF tries. | c | | c | s = V_{j}^T * B * r_{j} | c | r_{j} = r_{j} - V_{j}*s | c | alphaj = alphaj + s_{j} | c | | c | The stopping criteria used for iterative refinement is | c | discussed in Parlett's book SEP, page 107 and in Gragg & | c | Reichel ACM TOMS paper; Algorithm 686, Dec. 1990. | c | Determine if we need to correct the residual. The goal is | c | to enforce ||v(:,1:j)^T * r_{j}|| .le. eps * || r_{j} || | c %-----------------------------------------------------------% c if (rnorm .gt. 0.717*wnorm) go to 100 nrorth = nrorth + 1 c c %---------------------------------------------------% c | Enter the Iterative refinement phase. If further | c | refinement is necessary, loop back here. The loop | c | variable is ITER. Perform a step of Classical | c | Gram-Schmidt using all the Arnoldi vectors V_{j} | c %---------------------------------------------------% c 80 continue c if (msglvl .gt. 2) then xtemp(1) = wnorm xtemp(2) = rnorm call igraphdvout (logfil, 2, xtemp, ndigit, & '_saitr: re-orthonalization ; wnorm and rnorm are') end if c c %----------------------------------------------------% c | Compute V_{j}^T * B * r_{j}. | c | WORKD(IRJ:IRJ+J-1) = v(:,1:J)'*WORKD(IPJ:IPJ+N-1). | c %----------------------------------------------------% c call dgemv ('T', n, j, one, v, ldv, workd(ipj), 1, & zero, workd(irj), 1) c c %----------------------------------------------% c | Compute the correction to the residual: | c | r_{j} = r_{j} - V_{j} * WORKD(IRJ:IRJ+J-1). | c | The correction to H is v(:,1:J)*H(1:J,1:J) + | c | v(:,1:J)*WORKD(IRJ:IRJ+J-1)*e'_j, but only | c | H(j,j) is updated. | c %----------------------------------------------% c call dgemv ('N', n, j, -one, v, ldv, workd(irj), 1, & one, resid, 1) c if (j .eq. 1 .or. rstart) h(j,1) = zero h(j,2) = h(j,2) + workd(irj + j - 1) c orth2 = .true. call igraphsecond (t2) if (bmat .eq. 'G') then nbx = nbx + 1 call dcopy (n, resid, 1, workd(irj), 1) ipntr(1) = irj ipntr(2) = ipj ido = 2 c c %-----------------------------------% c | Exit in order to compute B*r_{j}. | c | r_{j} is the corrected residual. | c %-----------------------------------% c go to 9000 else if (bmat .eq. 'I') then call dcopy (n, resid, 1, workd(ipj), 1) end if 90 continue c c %---------------------------------------------------% c | Back from reverse communication if ORTH2 = .true. | c %---------------------------------------------------% c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c c %-----------------------------------------------------% c | Compute the B-norm of the corrected residual r_{j}. | c %-----------------------------------------------------% c if (bmat .eq. 'G') then rnorm1 = ddot (n, resid, 1, workd(ipj), 1) rnorm1 = sqrt(abs(rnorm1)) else if (bmat .eq. 'I') then rnorm1 = dnrm2(n, resid, 1) end if c if (msglvl .gt. 0 .and. iter .gt. 0) then call igraphivout (logfil, 1, [j], ndigit, & '_saitr: Iterative refinement for Arnoldi residual') if (msglvl .gt. 2) then xtemp(1) = rnorm xtemp(2) = rnorm1 call igraphdvout (logfil, 2, xtemp, ndigit, & '_saitr: iterative refinement ; rnorm and rnorm1 are') end if end if c c %-----------------------------------------% c | Determine if we need to perform another | c | step of re-orthogonalization. | c %-----------------------------------------% c if (rnorm1 .gt. 0.717*rnorm) then c c %--------------------------------% c | No need for further refinement | c %--------------------------------% c rnorm = rnorm1 c else c c %-------------------------------------------% c | Another step of iterative refinement step | c | is required. NITREF is used by stat.h | c %-------------------------------------------% c nitref = nitref + 1 rnorm = rnorm1 iter = iter + 1 if (iter .le. 1) go to 80 c c %-------------------------------------------------% c | Otherwise RESID is numerically in the span of V | c %-------------------------------------------------% c do 95 jj = 1, n resid(jj) = zero 95 continue rnorm = zero end if c c %----------------------------------------------% c | Branch here directly if iterative refinement | c | wasn't necessary or after at most NITER_REF | c | steps of iterative refinement. | c %----------------------------------------------% c 100 continue c rstart = .false. orth2 = .false. c call igraphsecond (t5) titref = titref + (t5 - t4) c c %----------------------------------------------------------% c | Make sure the last off-diagonal element is non negative | c | If not perform a similarity transformation on H(1:j,1:j) | c | and scale v(:,j) by -1. | c %----------------------------------------------------------% c if (h(j,1) .lt. zero) then h(j,1) = -h(j,1) if ( j .lt. k+np) then call dscal(n, -one, v(1,j+1), 1) else call dscal(n, -one, resid, 1) end if end if c c %------------------------------------% c | STEP 6: Update j = j+1; Continue | c %------------------------------------% c j = j + 1 if (j .gt. k+np) then call igraphsecond (t1) tsaitr = tsaitr + (t1 - t0) ido = 99 c if (msglvl .gt. 1) then call igraphdvout (logfil, k+np, h(1,2), ndigit, & '_saitr: main diagonal of matrix H of step K+NP.') if (k+np .gt. 1) then call igraphdvout (logfil, k+np-1, h(2,1), ndigit, & '_saitr: sub diagonal of matrix H of step K+NP.') end if end if c go to 9000 end if c c %--------------------------------------------------------% c | Loop back to extend the factorization by another step. | c %--------------------------------------------------------% c go to 1000 c c %---------------------------------------------------------------% c | | c | E N D O F M A I N I T E R A T I O N L O O P | c | | c %---------------------------------------------------------------% c 9000 continue return c c %---------------% c | End of igraphdsaitr | c %---------------% c end leidenbase/src/vendor/arpack/dnaitr.f0000644000176200001440000007426314447675376017365 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdnaitr c c\Description: c Reverse communication interface for applying NP additional steps to c a K step nonsymmetric Arnoldi factorization. c c Input: OP*V_{k} - V_{k}*H = r_{k}*e_{k}^T c c with (V_{k}^T)*B*V_{k} = I, (V_{k}^T)*B*r_{k} = 0. c c Output: OP*V_{k+p} - V_{k+p}*H = r_{k+p}*e_{k+p}^T c c with (V_{k+p}^T)*B*V_{k+p} = I, (V_{k+p}^T)*B*r_{k+p} = 0. c c where OP and B are as in igraphdnaupd. The B-norm of r_{k+p} is also c computed and returned. c c\Usage: c call igraphdnaitr c ( IDO, BMAT, N, K, NP, NB, RESID, RNORM, V, LDV, H, LDH, c IPNTR, WORKD, INFO ) c c\Arguments c IDO Integer. (INPUT/OUTPUT) c Reverse communication flag. c ------------------------------------------------------------- c IDO = 0: first call to the reverse communication interface c IDO = -1: compute Y = OP * X where c IPNTR(1) is the pointer into WORK for X, c IPNTR(2) is the pointer into WORK for Y. c This is for the restart phase to force the new c starting vector into the range of OP. c IDO = 1: compute Y = OP * X where c IPNTR(1) is the pointer into WORK for X, c IPNTR(2) is the pointer into WORK for Y, c IPNTR(3) is the pointer into WORK for B * X. c IDO = 2: compute Y = B * X where c IPNTR(1) is the pointer into WORK for X, c IPNTR(2) is the pointer into WORK for Y. c IDO = 99: done c ------------------------------------------------------------- c When the routine is used in the "shift-and-invert" mode, the c vector B * Q is already available and do not need to be c recompute in forming OP * Q. c c BMAT Character*1. (INPUT) c BMAT specifies the type of the matrix B that defines the c semi-inner product for the operator OP. See igraphdnaupd. c B = 'I' -> standard eigenvalue problem A*x = lambda*x c B = 'G' -> generalized eigenvalue problem A*x = lambda*M**x c c N Integer. (INPUT) c Dimension of the eigenproblem. c c K Integer. (INPUT) c Current size of V and H. c c NP Integer. (INPUT) c Number of additional Arnoldi steps to take. c c NB Integer. (INPUT) c Blocksize to be used in the recurrence. c Only work for NB = 1 right now. The goal is to have a c program that implement both the block and non-block method. c c RESID Double precision array of length N. (INPUT/OUTPUT) c On INPUT: RESID contains the residual vector r_{k}. c On OUTPUT: RESID contains the residual vector r_{k+p}. c c RNORM Double precision scalar. (INPUT/OUTPUT) c B-norm of the starting residual on input. c B-norm of the updated residual r_{k+p} on output. c c V Double precision N by K+NP array. (INPUT/OUTPUT) c On INPUT: V contains the Arnoldi vectors in the first K c columns. c On OUTPUT: V contains the new NP Arnoldi vectors in the next c NP columns. The first K columns are unchanged. c c LDV Integer. (INPUT) c Leading dimension of V exactly as declared in the calling c program. c c H Double precision (K+NP) by (K+NP) array. (INPUT/OUTPUT) c H is used to store the generated upper Hessenberg matrix. c c LDH Integer. (INPUT) c Leading dimension of H exactly as declared in the calling c program. c c IPNTR Integer array of length 3. (OUTPUT) c Pointer to mark the starting locations in the WORK for c vectors used by the Arnoldi iteration. c ------------------------------------------------------------- c IPNTR(1): pointer to the current operand vector X. c IPNTR(2): pointer to the current result vector Y. c IPNTR(3): pointer to the vector B * X when used in the c shift-and-invert mode. X is the current operand. c ------------------------------------------------------------- c c WORKD Double precision work array of length 3*N. (REVERSE COMMUNICATION) c Distributed array to be used in the basic Arnoldi iteration c for reverse communication. The calling program should not c use WORKD as temporary workspace during the iteration !!!!!! c On input, WORKD(1:N) = B*RESID and is used to save some c computation at the first step. c c INFO Integer. (OUTPUT) c = 0: Normal exit. c > 0: Size of the spanning invariant subspace of OP found. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly c Restarted Arnoldi Iteration", Rice University Technical Report c TR95-13, Department of Computational and Applied Mathematics. c c\Routines called: c igraphdgetv0 ARPACK routine to generate the initial vector. c igraphivout ARPACK utility routine that prints integers. c igraphsecond ARPACK utility routine for timing. c igraphdmout ARPACK utility routine that prints matrices c igraphdvout ARPACK utility routine that prints vectors. c dlabad LAPACK routine that computes machine constants. c dlamch LAPACK routine that determines machine constants. c dlascl LAPACK routine for careful scaling of a matrix. c dlanhs LAPACK routine that computes various norms of a matrix. c dgemv Level 2 BLAS routine for matrix vector multiplication. c daxpy Level 1 BLAS that computes a vector triad. c dscal Level 1 BLAS that scales a vector. c dcopy Level 1 BLAS that copies one vector to another . c ddot Level 1 BLAS that computes the scalar product of two vectors. c dnrm2 Level 1 BLAS that computes the norm of a vector. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/92: Version ' 2.4' c c\SCCS Information: @(#) c FILE: naitr.F SID: 2.4 DATE OF SID: 8/27/96 RELEASE: 2 c c\Remarks c The algorithm implemented is: c c restart = .false. c Given V_{k} = [v_{1}, ..., v_{k}], r_{k}; c r_{k} contains the initial residual vector even for k = 0; c Also assume that rnorm = || B*r_{k} || and B*r_{k} are already c computed by the calling program. c c betaj = rnorm ; p_{k+1} = B*r_{k} ; c For j = k+1, ..., k+np Do c 1) if ( betaj < tol ) stop or restart depending on j. c ( At present tol is zero ) c if ( restart ) generate a new starting vector. c 2) v_{j} = r(j-1)/betaj; V_{j} = [V_{j-1}, v_{j}]; c p_{j} = p_{j}/betaj c 3) r_{j} = OP*v_{j} where OP is defined as in igraphdnaupd c For shift-invert mode p_{j} = B*v_{j} is already available. c wnorm = || OP*v_{j} || c 4) Compute the j-th step residual vector. c w_{j} = V_{j}^T * B * OP * v_{j} c r_{j} = OP*v_{j} - V_{j} * w_{j} c H(:,j) = w_{j}; c H(j,j-1) = rnorm c rnorm = || r_(j) || c If (rnorm > 0.717*wnorm) accept step and go back to 1) c 5) Re-orthogonalization step: c s = V_{j}'*B*r_{j} c r_{j} = r_{j} - V_{j}*s; rnorm1 = || r_{j} || c alphaj = alphaj + s_{j}; c 6) Iterative refinement step: c If (rnorm1 > 0.717*rnorm) then c rnorm = rnorm1 c accept step and go back to 1) c Else c rnorm = rnorm1 c If this is the first time in step 6), go to 5) c Else r_{j} lies in the span of V_{j} numerically. c Set r_{j} = 0 and rnorm = 0; go to 1) c EndIf c End Do c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdnaitr & (ido, bmat, n, k, np, nb, resid, rnorm, v, ldv, h, ldh, & ipntr, workd, info) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c character bmat*1 integer ido, info, k, ldh, ldv, n, nb, np Double precision & rnorm c c %-----------------% c | Array Arguments | c %-----------------% c integer ipntr(3) Double precision & h(ldh,k+np), resid(n), v(ldv,k+np), workd(3*n) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c logical first, orth1, orth2, rstart, step3, step4 integer ierr, i, infol, ipj, irj, ivj, iter, itry, j, msglvl, & jj Double precision & betaj, ovfl, temp1, rnorm1, smlnum, tst1, ulp, unfl, & wnorm save first, orth1, orth2, rstart, step3, step4, & ierr, ipj, irj, ivj, iter, itry, j, msglvl, ovfl, & betaj, rnorm1, smlnum, ulp, unfl, wnorm c c %-----------------------% c | Local Array Arguments | c %-----------------------% c Double precision & xtemp(2) c c %----------------------% c | External Subroutines | c %----------------------% c external daxpy, dcopy, dscal, dgemv, igraphdgetv0, dlabad, & igraphdvout, igraphdmout, igraphivout, igraphsecond c c %--------------------% c | External Functions | c %--------------------% c Double precision & ddot, dnrm2, dlanhs, dlamch external ddot, dnrm2, dlanhs, dlamch c c %---------------------% c | Intrinsic Functions | c %---------------------% c intrinsic abs, sqrt c c %-----------------% c | Data statements | c %-----------------% c data first / .true. / c c %-----------------------% c | Executable Statements | c %-----------------------% c if (first) then c c %-----------------------------------------% c | Set machine-dependent constants for the | c | the splitting and deflation criterion. | c | If norm(H) <= sqrt(OVFL), | c | overflow should not occur. | c | REFERENCE: LAPACK subroutine dlahqr | c %-----------------------------------------% c unfl = dlamch( 'safe minimum' ) ovfl = one / unfl call dlabad( unfl, ovfl ) ulp = dlamch( 'precision' ) smlnum = unfl*( n / ulp ) first = .false. end if c if (ido .eq. 0) then c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = mnaitr c c %------------------------------% c | Initial call to this routine | c %------------------------------% c info = 0 step3 = .false. step4 = .false. rstart = .false. orth1 = .false. orth2 = .false. j = k + 1 ipj = 1 irj = ipj + n ivj = irj + n end if c c %-------------------------------------------------% c | When in reverse communication mode one of: | c | STEP3, STEP4, ORTH1, ORTH2, RSTART | c | will be .true. when .... | c | STEP3: return from computing OP*v_{j}. | c | STEP4: return from computing B-norm of OP*v_{j} | c | ORTH1: return from computing B-norm of r_{j+1} | c | ORTH2: return from computing B-norm of | c | correction to the residual vector. | c | RSTART: return from OP computations needed by | c | igraphdgetv0. | c %-------------------------------------------------% c if (step3) go to 50 if (step4) go to 60 if (orth1) go to 70 if (orth2) go to 90 if (rstart) go to 30 c c %-----------------------------% c | Else this is the first step | c %-----------------------------% c c %--------------------------------------------------------------% c | | c | A R N O L D I I T E R A T I O N L O O P | c | | c | Note: B*r_{j-1} is already in WORKD(1:N)=WORKD(IPJ:IPJ+N-1) | c %--------------------------------------------------------------% 1000 continue c if (msglvl .gt. 1) then call igraphivout (logfil, 1, [j], ndigit, & '_naitr: generating Arnoldi vector number') call igraphdvout (logfil, 1, [rnorm], ndigit, & '_naitr: B-norm of the current residual is') end if c c %---------------------------------------------------% c | STEP 1: Check if the B norm of j-th residual | c | vector is zero. Equivalent to determing whether | c | an exact j-step Arnoldi factorization is present. | c %---------------------------------------------------% c betaj = rnorm if (rnorm .gt. zero) go to 40 c c %---------------------------------------------------% c | Invariant subspace found, generate a new starting | c | vector which is orthogonal to the current Arnoldi | c | basis and continue the iteration. | c %---------------------------------------------------% c if (msglvl .gt. 0) then call igraphivout (logfil, 1, [j], ndigit, & '_naitr: ****** RESTART AT STEP ******') end if c c %---------------------------------------------% c | ITRY is the loop variable that controls the | c | maximum amount of times that a restart is | c | attempted. NRSTRT is used by stat.h | c %---------------------------------------------% c betaj = zero nrstrt = nrstrt + 1 itry = 1 20 continue rstart = .true. ido = 0 30 continue c c %--------------------------------------% c | If in reverse communication mode and | c | RSTART = .true. flow returns here. | c %--------------------------------------% c call igraphdgetv0 (ido, bmat, itry, .false., n, j, v, ldv, & resid, rnorm, ipntr, workd, ierr) if (ido .ne. 99) go to 9000 if (ierr .lt. 0) then itry = itry + 1 if (itry .le. 3) go to 20 c c %------------------------------------------------% c | Give up after several restart attempts. | c | Set INFO to the size of the invariant subspace | c | which spans OP and exit. | c %------------------------------------------------% c info = j - 1 call igraphsecond (t1) tnaitr = tnaitr + (t1 - t0) ido = 99 go to 9000 end if c 40 continue c c %---------------------------------------------------------% c | STEP 2: v_{j} = r_{j-1}/rnorm and p_{j} = p_{j}/rnorm | c | Note that p_{j} = B*r_{j-1}. In order to avoid overflow | c | when reciprocating a small RNORM, test against lower | c | machine bound. | c %---------------------------------------------------------% c call dcopy (n, resid, 1, v(1,j), 1) if (rnorm .ge. unfl) then temp1 = one / rnorm call dscal (n, temp1, v(1,j), 1) call dscal (n, temp1, workd(ipj), 1) else c c %-----------------------------------------% c | To scale both v_{j} and p_{j} carefully | c | use LAPACK routine SLASCL | c %-----------------------------------------% c call dlascl ('General', i, i, rnorm, one, n, 1, & v(1,j), n, infol) call dlascl ('General', i, i, rnorm, one, n, 1, & workd(ipj), n, infol) end if c c %------------------------------------------------------% c | STEP 3: r_{j} = OP*v_{j}; Note that p_{j} = B*v_{j} | c | Note that this is not quite yet r_{j}. See STEP 4 | c %------------------------------------------------------% c step3 = .true. nopx = nopx + 1 call igraphsecond (t2) call dcopy (n, v(1,j), 1, workd(ivj), 1) ipntr(1) = ivj ipntr(2) = irj ipntr(3) = ipj ido = 1 c c %-----------------------------------% c | Exit in order to compute OP*v_{j} | c %-----------------------------------% c go to 9000 50 continue c c %----------------------------------% c | Back from reverse communication; | c | WORKD(IRJ:IRJ+N-1) := OP*v_{j} | c | if step3 = .true. | c %----------------------------------% c call igraphsecond (t3) tmvopx = tmvopx + (t3 - t2) step3 = .false. c c %------------------------------------------% c | Put another copy of OP*v_{j} into RESID. | c %------------------------------------------% c call dcopy (n, workd(irj), 1, resid, 1) c c %---------------------------------------% c | STEP 4: Finish extending the Arnoldi | c | factorization to length j. | c %---------------------------------------% c call igraphsecond (t2) if (bmat .eq. 'G') then nbx = nbx + 1 step4 = .true. ipntr(1) = irj ipntr(2) = ipj ido = 2 c c %-------------------------------------% c | Exit in order to compute B*OP*v_{j} | c %-------------------------------------% c go to 9000 else if (bmat .eq. 'I') then call dcopy (n, resid, 1, workd(ipj), 1) end if 60 continue c c %----------------------------------% c | Back from reverse communication; | c | WORKD(IPJ:IPJ+N-1) := B*OP*v_{j} | c | if step4 = .true. | c %----------------------------------% c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c step4 = .false. c c %-------------------------------------% c | The following is needed for STEP 5. | c | Compute the B-norm of OP*v_{j}. | c %-------------------------------------% c if (bmat .eq. 'G') then wnorm = ddot (n, resid, 1, workd(ipj), 1) wnorm = sqrt(abs(wnorm)) else if (bmat .eq. 'I') then wnorm = dnrm2(n, resid, 1) end if c c %-----------------------------------------% c | Compute the j-th residual corresponding | c | to the j step factorization. | c | Use Classical Gram Schmidt and compute: | c | w_{j} <- V_{j}^T * B * OP * v_{j} | c | r_{j} <- OP*v_{j} - V_{j} * w_{j} | c %-----------------------------------------% c c c %------------------------------------------% c | Compute the j Fourier coefficients w_{j} | c | WORKD(IPJ:IPJ+N-1) contains B*OP*v_{j}. | c %------------------------------------------% c call dgemv ('T', n, j, one, v, ldv, workd(ipj), 1, & zero, h(1,j), 1) c c %--------------------------------------% c | Orthogonalize r_{j} against V_{j}. | c | RESID contains OP*v_{j}. See STEP 3. | c %--------------------------------------% c call dgemv ('N', n, j, -one, v, ldv, h(1,j), 1, & one, resid, 1) c if (j .gt. 1) h(j,j-1) = betaj c call igraphsecond (t4) c orth1 = .true. c call igraphsecond (t2) if (bmat .eq. 'G') then nbx = nbx + 1 call dcopy (n, resid, 1, workd(irj), 1) ipntr(1) = irj ipntr(2) = ipj ido = 2 c c %----------------------------------% c | Exit in order to compute B*r_{j} | c %----------------------------------% c go to 9000 else if (bmat .eq. 'I') then call dcopy (n, resid, 1, workd(ipj), 1) end if 70 continue c c %---------------------------------------------------% c | Back from reverse communication if ORTH1 = .true. | c | WORKD(IPJ:IPJ+N-1) := B*r_{j}. | c %---------------------------------------------------% c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c orth1 = .false. c c %------------------------------% c | Compute the B-norm of r_{j}. | c %------------------------------% c if (bmat .eq. 'G') then rnorm = ddot (n, resid, 1, workd(ipj), 1) rnorm = sqrt(abs(rnorm)) else if (bmat .eq. 'I') then rnorm = dnrm2(n, resid, 1) end if c c %-----------------------------------------------------------% c | STEP 5: Re-orthogonalization / Iterative refinement phase | c | Maximum NITER_ITREF tries. | c | | c | s = V_{j}^T * B * r_{j} | c | r_{j} = r_{j} - V_{j}*s | c | alphaj = alphaj + s_{j} | c | | c | The stopping criteria used for iterative refinement is | c | discussed in Parlett's book SEP, page 107 and in Gragg & | c | Reichel ACM TOMS paper; Algorithm 686, Dec. 1990. | c | Determine if we need to correct the residual. The goal is | c | to enforce ||v(:,1:j)^T * r_{j}|| .le. eps * || r_{j} || | c | The following test determines whether the sine of the | c | angle between OP*x and the computed residual is less | c | than or equal to 0.717. | c %-----------------------------------------------------------% c if (rnorm .gt. 0.717*wnorm) go to 100 iter = 0 nrorth = nrorth + 1 c c %---------------------------------------------------% c | Enter the Iterative refinement phase. If further | c | refinement is necessary, loop back here. The loop | c | variable is ITER. Perform a step of Classical | c | Gram-Schmidt using all the Arnoldi vectors V_{j} | c %---------------------------------------------------% c 80 continue c if (msglvl .gt. 2) then xtemp(1) = wnorm xtemp(2) = rnorm call igraphdvout (logfil, 2, xtemp, ndigit, & '_naitr: re-orthonalization; wnorm and rnorm are') call igraphdvout (logfil, j, h(1,j), ndigit, & '_naitr: j-th column of H') end if c c %----------------------------------------------------% c | Compute V_{j}^T * B * r_{j}. | c | WORKD(IRJ:IRJ+J-1) = v(:,1:J)'*WORKD(IPJ:IPJ+N-1). | c %----------------------------------------------------% c call dgemv ('T', n, j, one, v, ldv, workd(ipj), 1, & zero, workd(irj), 1) c c %---------------------------------------------% c | Compute the correction to the residual: | c | r_{j} = r_{j} - V_{j} * WORKD(IRJ:IRJ+J-1). | c | The correction to H is v(:,1:J)*H(1:J,1:J) | c | + v(:,1:J)*WORKD(IRJ:IRJ+J-1)*e'_j. | c %---------------------------------------------% c call dgemv ('N', n, j, -one, v, ldv, workd(irj), 1, & one, resid, 1) call daxpy (j, one, workd(irj), 1, h(1,j), 1) c orth2 = .true. call igraphsecond (t2) if (bmat .eq. 'G') then nbx = nbx + 1 call dcopy (n, resid, 1, workd(irj), 1) ipntr(1) = irj ipntr(2) = ipj ido = 2 c c %-----------------------------------% c | Exit in order to compute B*r_{j}. | c | r_{j} is the corrected residual. | c %-----------------------------------% c go to 9000 else if (bmat .eq. 'I') then call dcopy (n, resid, 1, workd(ipj), 1) end if 90 continue c c %---------------------------------------------------% c | Back from reverse communication if ORTH2 = .true. | c %---------------------------------------------------% c if (bmat .eq. 'G') then call igraphsecond (t3) tmvbx = tmvbx + (t3 - t2) end if c c %-----------------------------------------------------% c | Compute the B-norm of the corrected residual r_{j}. | c %-----------------------------------------------------% c if (bmat .eq. 'G') then rnorm1 = ddot (n, resid, 1, workd(ipj), 1) rnorm1 = sqrt(abs(rnorm1)) else if (bmat .eq. 'I') then rnorm1 = dnrm2(n, resid, 1) end if c if (msglvl .gt. 0 .and. iter .gt. 0) then call igraphivout (logfil, 1, [j], ndigit, & '_naitr: Iterative refinement for Arnoldi residual') if (msglvl .gt. 2) then xtemp(1) = rnorm xtemp(2) = rnorm1 call igraphdvout (logfil, 2, xtemp, ndigit, & '_naitr: iterative refinement ; rnorm and rnorm1 are') end if end if c c %-----------------------------------------% c | Determine if we need to perform another | c | step of re-orthogonalization. | c %-----------------------------------------% c if (rnorm1 .gt. 0.717*rnorm) then c c %---------------------------------------% c | No need for further refinement. | c | The cosine of the angle between the | c | corrected residual vector and the old | c | residual vector is greater than 0.717 | c | In other words the corrected residual | c | and the old residual vector share an | c | angle of less than arcCOS(0.717) | c %---------------------------------------% c rnorm = rnorm1 c else c c %-------------------------------------------% c | Another step of iterative refinement step | c | is required. NITREF is used by stat.h | c %-------------------------------------------% c nitref = nitref + 1 rnorm = rnorm1 iter = iter + 1 if (iter .le. 1) go to 80 c c %-------------------------------------------------% c | Otherwise RESID is numerically in the span of V | c %-------------------------------------------------% c do 95 jj = 1, n resid(jj) = zero 95 continue rnorm = zero end if c c %----------------------------------------------% c | Branch here directly if iterative refinement | c | wasn't necessary or after at most NITER_REF | c | steps of iterative refinement. | c %----------------------------------------------% c 100 continue c rstart = .false. orth2 = .false. c call igraphsecond (t5) titref = titref + (t5 - t4) c c %------------------------------------% c | STEP 6: Update j = j+1; Continue | c %------------------------------------% c j = j + 1 if (j .gt. k+np) then call igraphsecond (t1) tnaitr = tnaitr + (t1 - t0) ido = 99 do 110 i = max(1,k), k+np-1 c c %--------------------------------------------% c | Check for splitting and deflation. | c | Use a standard test as in the QR algorithm | c | REFERENCE: LAPACK subroutine dlahqr | c %--------------------------------------------% c tst1 = abs( h( i, i ) ) + abs( h( i+1, i+1 ) ) if( tst1.eq.zero ) & tst1 = dlanhs( '1', k+np, h, ldh, workd(n+1) ) if( abs( h( i+1,i ) ).le.max( ulp*tst1, smlnum ) ) & h(i+1,i) = zero 110 continue c if (msglvl .gt. 2) then call igraphdmout (logfil, k+np, k+np, h, ldh, ndigit, & '_naitr: Final upper Hessenberg matrix H of order K+NP') end if c go to 9000 end if c c %--------------------------------------------------------% c | Loop back to extend the factorization by another step. | c %--------------------------------------------------------% c go to 1000 c c %---------------------------------------------------------------% c | | c | E N D O F M A I N I T E R A T I O N L O O P | c | | c %---------------------------------------------------------------% c 9000 continue return c c %---------------% c | End of igraphdnaitr | c %---------------% c end leidenbase/src/vendor/arpack/dstatn.f0000644000176200001440000000272414447675376017372 0ustar liggesusersc c %---------------------------------------------% c | Initialize statistic and timing information | c | for nonsymmetric Arnoldi code. | c %---------------------------------------------% c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\SCCS Information: @(#) c FILE: statn.F SID: 2.4 DATE OF SID: 4/20/96 RELEASE: 2 c subroutine igraphdstatn c c %--------------------------------% c | See stat.doc for documentation | c %--------------------------------% c include 'stat.h' c c %-----------------------% c | Executable Statements | c %-----------------------% c nopx = 0 nbx = 0 nrorth = 0 nitref = 0 nrstrt = 0 c tnaupd = 0.0D+0 tnaup2 = 0.0D+0 tnaitr = 0.0D+0 tneigh = 0.0D+0 tngets = 0.0D+0 tnapps = 0.0D+0 tnconv = 0.0D+0 titref = 0.0D+0 tgetv0 = 0.0D+0 trvec = 0.0D+0 c c %----------------------------------------------------% c | User time including reverse communication overhead | c %----------------------------------------------------% c tmvopx = 0.0D+0 tmvbx = 0.0D+0 c return c c c %---------------% c | End of igraphdstatn | c %---------------% c end leidenbase/src/vendor/arpack/stat.h0000644000176200001440000000171314447675376017047 0ustar liggesusersc %--------------------------------% c | See stat.doc for documentation | c %--------------------------------% c c\SCCS Information: @(#) c FILE: stat.h SID: 2.2 DATE OF SID: 11/16/95 RELEASE: 2 c real t0, t1, t2, t3, t4, t5 c save t0, t1, t2, t3, t4, t5 c integer nopx, nbx, nrorth, nitref, nrstrt real tsaupd, tsaup2, tsaitr, tseigt, tsgets, tsapps, tsconv, & tnaupd, tnaup2, tnaitr, tneigh, tngets, tnapps, tnconv, & tcaupd, tcaup2, tcaitr, tceigh, tcgets, tcapps, tcconv, & tmvopx, tmvbx, tgetv0, titref, trvec common /timing/ & nopx, nbx, nrorth, nitref, nrstrt, & tsaupd, tsaup2, tsaitr, tseigt, tsgets, tsapps, tsconv, & tnaupd, tnaup2, tnaitr, tneigh, tngets, tnapps, tnconv, & tcaupd, tcaup2, tcaitr, tceigh, tcgets, tcapps, tcconv, & tmvopx, tmvbx, tgetv0, titref, trvec leidenbase/src/vendor/arpack/dvout.f0000644000176200001440000001031214447675376017226 0ustar liggesusers*----------------------------------------------------------------------- * Routine: DVOUT * * Purpose: Real vector output routine. * * Usage: CALL DVOUT (LOUT, N, SX, IDIGIT, IFMT) * * Arguments * N - Length of array SX. (Input) * SX - Real array to be printed. (Input) * IFMT - Format to be used in printing array SX. (Input) * IDIGIT - Print up to IABS(IDIGIT) decimal digits per number. (In) * If IDIGIT .LT. 0, printing is done with 72 columns. * If IDIGIT .GT. 0, printing is done with 132 columns. * *----------------------------------------------------------------------- * SUBROUTINE IGRAPHDVOUT( LOUT, N, SX, IDIGIT, IFMT ) * ... * ... SPECIFICATIONS FOR ARGUMENTS * ... * ... SPECIFICATIONS FOR LOCAL VARIABLES * .. Scalar Arguments .. CHARACTER*( * ) IFMT INTEGER IDIGIT, LOUT, N * .. * .. Array Arguments .. DOUBLE PRECISION SX( * ) * .. * .. Local Scalars .. CHARACTER*80 LINE INTEGER I, K1, K2, LLL, NDIGIT * .. * .. Intrinsic Functions .. INTRINSIC LEN, MIN, MIN0 * .. * .. Executable Statements .. * ... * ... FIRST EXECUTABLE STATEMENT * * c$$$ LLL = MIN( LEN( IFMT ), 80 ) c$$$ DO 10 I = 1, LLL c$$$ LINE( I: I ) = '-' c$$$ 10 CONTINUE c$$$* c$$$ DO 20 I = LLL + 1, 80 c$$$ LINE( I: I ) = ' ' c$$$ 20 CONTINUE c$$$* c$$$ WRITE( LOUT, FMT = 9999 )IFMT, LINE( 1: LLL ) c$$$ 9999 FORMAT( / 1X, A, / 1X, A ) c$$$* c$$$ IF( N.LE.0 ) c$$$ $ RETURN c$$$ NDIGIT = IDIGIT c$$$ IF( IDIGIT.EQ.0 ) c$$$ $ NDIGIT = 4 c$$$* c$$$*======================================================================= c$$$* CODE FOR OUTPUT USING 72 COLUMNS FORMAT c$$$*======================================================================= c$$$* c$$$ IF( IDIGIT.LT.0 ) THEN c$$$ NDIGIT = -IDIGIT c$$$ IF( NDIGIT.LE.4 ) THEN c$$$ DO 30 K1 = 1, N, 5 c$$$ K2 = MIN0( N, K1+4 ) c$$$ WRITE( LOUT, FMT = 9998 )K1, K2, ( SX( I ), I = K1, K2 ) c$$$ 30 CONTINUE c$$$ ELSE IF( NDIGIT.LE.6 ) THEN c$$$ DO 40 K1 = 1, N, 4 c$$$ K2 = MIN0( N, K1+3 ) c$$$ WRITE( LOUT, FMT = 9997 )K1, K2, ( SX( I ), I = K1, K2 ) c$$$ 40 CONTINUE c$$$ ELSE IF( NDIGIT.LE.10 ) THEN c$$$ DO 50 K1 = 1, N, 3 c$$$ K2 = MIN0( N, K1+2 ) c$$$ WRITE( LOUT, FMT = 9996 )K1, K2, ( SX( I ), I = K1, K2 ) c$$$ 50 CONTINUE c$$$ ELSE c$$$ DO 60 K1 = 1, N, 2 c$$$ K2 = MIN0( N, K1+1 ) c$$$ WRITE( LOUT, FMT = 9995 )K1, K2, ( SX( I ), I = K1, K2 ) c$$$ 60 CONTINUE c$$$ END IF c$$$* c$$$*======================================================================= c$$$* CODE FOR OUTPUT USING 132 COLUMNS FORMAT c$$$*======================================================================= c$$$* c$$$ ELSE c$$$ IF( NDIGIT.LE.4 ) THEN c$$$ DO 70 K1 = 1, N, 10 c$$$ K2 = MIN0( N, K1+9 ) c$$$ WRITE( LOUT, FMT = 9998 )K1, K2, ( SX( I ), I = K1, K2 ) c$$$ 70 CONTINUE c$$$ ELSE IF( NDIGIT.LE.6 ) THEN c$$$ DO 80 K1 = 1, N, 8 c$$$ K2 = MIN0( N, K1+7 ) c$$$ WRITE( LOUT, FMT = 9997 )K1, K2, ( SX( I ), I = K1, K2 ) c$$$ 80 CONTINUE c$$$ ELSE IF( NDIGIT.LE.10 ) THEN c$$$ DO 90 K1 = 1, N, 6 c$$$ K2 = MIN0( N, K1+5 ) c$$$ WRITE( LOUT, FMT = 9996 )K1, K2, ( SX( I ), I = K1, K2 ) c$$$ 90 CONTINUE c$$$ ELSE c$$$ DO 100 K1 = 1, N, 5 c$$$ K2 = MIN0( N, K1+4 ) c$$$ WRITE( LOUT, FMT = 9995 )K1, K2, ( SX( I ), I = K1, K2 ) c$$$ 100 CONTINUE c$$$ END IF c$$$ END IF c$$$ WRITE( LOUT, FMT = 9994 ) c$$$ RETURN c$$$ 9998 FORMAT( 1X, I4, ' - ', I4, ':', 1P, 10D12.3 ) c$$$ 9997 FORMAT( 1X, I4, ' - ', I4, ':', 1X, 1P, 8D14.5 ) c$$$ 9996 FORMAT( 1X, I4, ' - ', I4, ':', 1X, 1P, 6D18.9 ) c$$$ 9995 FORMAT( 1X, I4, ' - ', I4, ':', 1X, 1P, 5D24.13 ) c$$$ 9994 FORMAT( 1X, ' ' ) END leidenbase/src/vendor/arpack/dsortr.f0000644000176200001440000001240414447675376017406 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdsortr c c\Description: c Sort the array X1 in the order specified by WHICH and optionally c applies the permutation to the array X2. c c\Usage: c call igraphdsortr c ( WHICH, APPLY, N, X1, X2 ) c c\Arguments c WHICH Character*2. (Input) c 'LM' -> X1 is sorted into increasing order of magnitude. c 'SM' -> X1 is sorted into decreasing order of magnitude. c 'LA' -> X1 is sorted into increasing order of algebraic. c 'SA' -> X1 is sorted into decreasing order of algebraic. c c APPLY Logical. (Input) c APPLY = .TRUE. -> apply the sorted order to X2. c APPLY = .FALSE. -> do not apply the sorted order to X2. c c N Integer. (INPUT) c Size of the arrays. c c X1 Double precision array of length N. (INPUT/OUTPUT) c The array to be sorted. c c X2 Double precision array of length N. (INPUT/OUTPUT) c Only referenced if APPLY = .TRUE. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c 12/16/93: Version ' 2.1'. c Adapted from the sort routine in LANSO. c c\SCCS Information: @(#) c FILE: sortr.F SID: 2.3 DATE OF SID: 4/19/96 RELEASE: 2 c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdsortr (which, apply, n, x1, x2) c c %------------------% c | Scalar Arguments | c %------------------% c character*2 which logical apply integer n c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & x1(0:n-1), x2(0:n-1) c c %---------------% c | Local Scalars | c %---------------% c integer i, igap, j Double precision & temp c c %-----------------------% c | Executable Statements | c %-----------------------% c igap = n / 2 c if (which .eq. 'SA') then c c X1 is sorted into decreasing order of algebraic. c 10 continue if (igap .eq. 0) go to 9000 do 30 i = igap, n-1 j = i-igap 20 continue c if (j.lt.0) go to 30 c if (x1(j).lt.x1(j+igap)) then temp = x1(j) x1(j) = x1(j+igap) x1(j+igap) = temp if (apply) then temp = x2(j) x2(j) = x2(j+igap) x2(j+igap) = temp end if else go to 30 endif j = j-igap go to 20 30 continue igap = igap / 2 go to 10 c else if (which .eq. 'SM') then c c X1 is sorted into decreasing order of magnitude. c 40 continue if (igap .eq. 0) go to 9000 do 60 i = igap, n-1 j = i-igap 50 continue c if (j.lt.0) go to 60 c if (abs(x1(j)).lt.abs(x1(j+igap))) then temp = x1(j) x1(j) = x1(j+igap) x1(j+igap) = temp if (apply) then temp = x2(j) x2(j) = x2(j+igap) x2(j+igap) = temp end if else go to 60 endif j = j-igap go to 50 60 continue igap = igap / 2 go to 40 c else if (which .eq. 'LA') then c c X1 is sorted into increasing order of algebraic. c 70 continue if (igap .eq. 0) go to 9000 do 90 i = igap, n-1 j = i-igap 80 continue c if (j.lt.0) go to 90 c if (x1(j).gt.x1(j+igap)) then temp = x1(j) x1(j) = x1(j+igap) x1(j+igap) = temp if (apply) then temp = x2(j) x2(j) = x2(j+igap) x2(j+igap) = temp end if else go to 90 endif j = j-igap go to 80 90 continue igap = igap / 2 go to 70 c else if (which .eq. 'LM') then c c X1 is sorted into increasing order of magnitude. c 100 continue if (igap .eq. 0) go to 9000 do 120 i = igap, n-1 j = i-igap 110 continue c if (j.lt.0) go to 120 c if (abs(x1(j)).gt.abs(x1(j+igap))) then temp = x1(j) x1(j) = x1(j+igap) x1(j+igap) = temp if (apply) then temp = x2(j) x2(j) = x2(j+igap) x2(j+igap) = temp end if else go to 120 endif j = j-igap go to 110 120 continue igap = igap / 2 go to 100 end if c 9000 continue return c c %---------------% c | End of igraphdsortr | c %---------------% c end leidenbase/src/vendor/arpack/dnconv.f0000644000176200001440000001003714447675376017360 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdnconv c c\Description: c Convergence testing for the nonsymmetric Arnoldi eigenvalue routine. c c\Usage: c call igraphdnconv c ( N, RITZR, RITZI, BOUNDS, TOL, NCONV ) c c\Arguments c N Integer. (INPUT) c Number of Ritz values to check for convergence. c c RITZR, Double precision arrays of length N. (INPUT) c RITZI Real and imaginary parts of the Ritz values to be checked c for convergence. c BOUNDS Double precision array of length N. (INPUT) c Ritz estimates for the Ritz values in RITZR and RITZI. c c TOL Double precision scalar. (INPUT) c Desired backward error for a Ritz value to be considered c "converged". c c NCONV Integer scalar. (OUTPUT) c Number of "converged" Ritz values. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\Routines called: c igraphsecond ARPACK utility routine for timing. c dlamch LAPACK routine that determines machine constants. c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c xx/xx/92: Version ' 2.1' c c\SCCS Information: @(#) c FILE: nconv.F SID: 2.3 DATE OF SID: 4/20/96 RELEASE: 2 c c\Remarks c 1. xxxx c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdnconv (n, ritzr, ritzi, bounds, tol, nconv) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c integer n, nconv Double precision & tol c c %-----------------% c | Array Arguments | c %-----------------% Double precision & ritzr(n), ritzi(n), bounds(n) c c %---------------% c | Local Scalars | c %---------------% c integer i Double precision & temp, eps23 c c %--------------------% c | External Functions | c %--------------------% c Double precision & dlapy2, dlamch external dlapy2, dlamch c %-----------------------% c | Executable Statements | c %-----------------------% c c %-------------------------------------------------------------% c | Convergence test: unlike in the symmetric code, I am not | c | using things like refined error bounds and gap condition | c | because I don't know the exact equivalent concept. | c | | c | Instead the i-th Ritz value is considered "converged" when: | c | | c | bounds(i) .le. ( TOL * | ritz | ) | c | | c | for some appropriate choice of norm. | c %-------------------------------------------------------------% c call igraphsecond (t0) c c %---------------------------------% c | Get machine dependent constant. | c %---------------------------------% c eps23 = dlamch('Epsilon-Machine') eps23 = eps23**(2.0D+0 / 3.0D+0) c nconv = 0 do 20 i = 1, n temp = max( eps23, dlapy2( ritzr(i), ritzi(i) ) ) if (bounds(i) .le. tol*temp) nconv = nconv + 1 20 continue c call igraphsecond (t1) tnconv = tnconv + (t1 - t0) c return c c %---------------% c | End of igraphdnconv | c %---------------% c end leidenbase/src/vendor/arpack/dsapps.f0000644000176200001440000004431214447675376017366 0ustar liggesusersc----------------------------------------------------------------------- c\BeginDoc c c\Name: igraphdsapps c c\Description: c Given the Arnoldi factorization c c A*V_{k} - V_{k}*H_{k} = r_{k+p}*e_{k+p}^T, c c apply NP shifts implicitly resulting in c c A*(V_{k}*Q) - (V_{k}*Q)*(Q^T* H_{k}*Q) = r_{k+p}*e_{k+p}^T * Q c c where Q is an orthogonal matrix of order KEV+NP. Q is the product of c rotations resulting from the NP bulge chasing sweeps. The updated Arnoldi c factorization becomes: c c A*VNEW_{k} - VNEW_{k}*HNEW_{k} = rnew_{k}*e_{k}^T. c c\Usage: c call igraphdsapps c ( N, KEV, NP, SHIFT, V, LDV, H, LDH, RESID, Q, LDQ, WORKD ) c c\Arguments c N Integer. (INPUT) c Problem size, i.e. dimension of matrix A. c c KEV Integer. (INPUT) c INPUT: KEV+NP is the size of the input matrix H. c OUTPUT: KEV is the size of the updated matrix HNEW. c c NP Integer. (INPUT) c Number of implicit shifts to be applied. c c SHIFT Double precision array of length NP. (INPUT) c The shifts to be applied. c c V Double precision N by (KEV+NP) array. (INPUT/OUTPUT) c INPUT: V contains the current KEV+NP Arnoldi vectors. c OUTPUT: VNEW = V(1:n,1:KEV); the updated Arnoldi vectors c are in the first KEV columns of V. c c LDV Integer. (INPUT) c Leading dimension of V exactly as declared in the calling c program. c c H Double precision (KEV+NP) by 2 array. (INPUT/OUTPUT) c INPUT: H contains the symmetric tridiagonal matrix of the c Arnoldi factorization with the subdiagonal in the 1st column c starting at H(2,1) and the main diagonal in the 2nd column. c OUTPUT: H contains the updated tridiagonal matrix in the c KEV leading submatrix. c c LDH Integer. (INPUT) c Leading dimension of H exactly as declared in the calling c program. c c RESID Double precision array of length (N). (INPUT/OUTPUT) c INPUT: RESID contains the the residual vector r_{k+p}. c OUTPUT: RESID is the updated residual vector rnew_{k}. c c Q Double precision KEV+NP by KEV+NP work array. (WORKSPACE) c Work array used to accumulate the rotations during the bulge c chase sweep. c c LDQ Integer. (INPUT) c Leading dimension of Q exactly as declared in the calling c program. c c WORKD Double precision work array of length 2*N. (WORKSPACE) c Distributed array used in the application of the accumulated c orthogonal matrix Q. c c\EndDoc c c----------------------------------------------------------------------- c c\BeginLib c c\Local variables: c xxxxxx real c c\References: c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), c pp 357-385. c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly c Restarted Arnoldi Iteration", Rice University Technical Report c TR95-13, Department of Computational and Applied Mathematics. c c\Routines called: c igraphivout ARPACK utility routine that prints integers. c igraphsecond ARPACK utility routine for timing. c igraphdvout ARPACK utility routine that prints vectors. c dlamch LAPACK routine that determines machine constants. c dlartg LAPACK Givens rotation construction routine. c dlacpy LAPACK matrix copy routine. c dlaset LAPACK matrix initialization routine. c dgemv Level 2 BLAS routine for matrix vector multiplication. c daxpy Level 1 BLAS that computes a vector triad. c dcopy Level 1 BLAS that copies one vector to another. c dscal Level 1 BLAS that scales a vector. c c\Author c Danny Sorensen Phuong Vu c Richard Lehoucq CRPC / Rice University c Dept. of Computational & Houston, Texas c Applied Mathematics c Rice University c Houston, Texas c c\Revision history: c 12/16/93: Version ' 2.1' c c\SCCS Information: @(#) c FILE: sapps.F SID: 2.5 DATE OF SID: 4/19/96 RELEASE: 2 c c\Remarks c 1. In this version, each shift is applied to all the subblocks of c the tridiagonal matrix H and not just to the submatrix that it c comes from. This routine assumes that the subdiagonal elements c of H that are stored in h(1:kev+np,1) are nonegative upon input c and enforce this condition upon output. This version incorporates c deflation. See code for documentation. c c\EndLib c c----------------------------------------------------------------------- c subroutine igraphdsapps & ( n, kev, np, shift, v, ldv, h, ldh, resid, q, ldq, workd ) c c %----------------------------------------------------% c | Include files for debugging and timing information | c %----------------------------------------------------% c include 'debug.h' include 'stat.h' c c %------------------% c | Scalar Arguments | c %------------------% c integer kev, ldh, ldq, ldv, n, np c c %-----------------% c | Array Arguments | c %-----------------% c Double precision & h(ldh,2), q(ldq,kev+np), resid(n), shift(np), & v(ldv,kev+np), workd(2*n) c c %------------% c | Parameters | c %------------% c Double precision & one, zero parameter (one = 1.0D+0, zero = 0.0D+0) c c %---------------% c | Local Scalars | c %---------------% c integer i, iend, istart, itop, j, jj, kplusp, msglvl logical first Double precision & a1, a2, a3, a4, big, c, epsmch, f, g, r, s save epsmch, first c c c %----------------------% c | External Subroutines | c %----------------------% c external daxpy, dcopy, dscal, dlacpy, dlartg, dlaset, & igraphdvout, igraphivout, igraphsecond, dgemv c c %--------------------% c | External Functions | c %--------------------% c Double precision & dlamch external dlamch c c %----------------------% c | Intrinsics Functions | c %----------------------% c intrinsic abs c c %----------------% c | Data statments | c %----------------% c data first / .true. / c c %-----------------------% c | Executable Statements | c %-----------------------% c if (first) then epsmch = dlamch('Epsilon-Machine') first = .false. end if itop = 1 c c %-------------------------------% c | Initialize timing statistics | c | & message level for debugging | c %-------------------------------% c call igraphsecond (t0) msglvl = msapps c kplusp = kev + np c c %----------------------------------------------% c | Initialize Q to the identity matrix of order | c | kplusp used to accumulate the rotations. | c %----------------------------------------------% c call dlaset ('All', kplusp, kplusp, zero, one, q, ldq) c c %----------------------------------------------% c | Quick return if there are no shifts to apply | c %----------------------------------------------% c if (np .eq. 0) go to 9000 c c %----------------------------------------------------------% c | Apply the np shifts implicitly. Apply each shift to the | c | whole matrix and not just to the submatrix from which it | c | comes. | c %----------------------------------------------------------% c do 90 jj = 1, np c istart = itop c c %----------------------------------------------------------% c | Check for splitting and deflation. Currently we consider | c | an off-diagonal element h(i+1,1) negligible if | c | h(i+1,1) .le. epsmch*( |h(i,2)| + |h(i+1,2)| ) | c | for i=1:KEV+NP-1. | c | If above condition tests true then we set h(i+1,1) = 0. | c | Note that h(1:KEV+NP,1) are assumed to be non negative. | c %----------------------------------------------------------% c 20 continue c c %------------------------------------------------% c | The following loop exits early if we encounter | c | a negligible off diagonal element. | c %------------------------------------------------% c do 30 i = istart, kplusp-1 big = abs(h(i,2)) + abs(h(i+1,2)) if (h(i+1,1) .le. epsmch*big) then if (msglvl .gt. 0) then call igraphivout (logfil, 1, i, ndigit, & '_sapps: deflation at row/column no.') call igraphivout (logfil, 1, jj, ndigit, & '_sapps: occured before shift number.') call igraphdvout (logfil, 1, h(i+1,1), ndigit, & '_sapps: the corresponding off diagonal element') end if h(i+1,1) = zero iend = i go to 40 end if 30 continue iend = kplusp 40 continue c if (istart .lt. iend) then c c %--------------------------------------------------------% c | Construct the plane rotation G'(istart,istart+1,theta) | c | that attempts to drive h(istart+1,1) to zero. | c %--------------------------------------------------------% c f = h(istart,2) - shift(jj) g = h(istart+1,1) call dlartg (f, g, c, s, r) c c %-------------------------------------------------------% c | Apply rotation to the left and right of H; | c | H <- G' * H * G, where G = G(istart,istart+1,theta). | c | This will create a "bulge". | c %-------------------------------------------------------% c a1 = c*h(istart,2) + s*h(istart+1,1) a2 = c*h(istart+1,1) + s*h(istart+1,2) a4 = c*h(istart+1,2) - s*h(istart+1,1) a3 = c*h(istart+1,1) - s*h(istart,2) h(istart,2) = c*a1 + s*a2 h(istart+1,2) = c*a4 - s*a3 h(istart+1,1) = c*a3 + s*a4 c c %----------------------------------------------------% c | Accumulate the rotation in the matrix Q; Q <- Q*G | c %----------------------------------------------------% c do 60 j = 1, min(istart+jj,kplusp) a1 = c*q(j,istart) + s*q(j,istart+1) q(j,istart+1) = - s*q(j,istart) + c*q(j,istart+1) q(j,istart) = a1 60 continue c c c %----------------------------------------------% c | The following loop chases the bulge created. | c | Note that the previous rotation may also be | c | done within the following loop. But it is | c | kept separate to make the distinction among | c | the bulge chasing sweeps and the first plane | c | rotation designed to drive h(istart+1,1) to | c | zero. | c %----------------------------------------------% c do 70 i = istart+1, iend-1 c c %----------------------------------------------% c | Construct the plane rotation G'(i,i+1,theta) | c | that zeros the i-th bulge that was created | c | by G(i-1,i,theta). g represents the bulge. | c %----------------------------------------------% c f = h(i,1) g = s*h(i+1,1) c c %----------------------------------% c | Final update with G(i-1,i,theta) | c %----------------------------------% c h(i+1,1) = c*h(i+1,1) call dlartg (f, g, c, s, r) c c %-------------------------------------------% c | The following ensures that h(1:iend-1,1), | c | the first iend-2 off diagonal of elements | c | H, remain non negative. | c %-------------------------------------------% c if (r .lt. zero) then r = -r c = -c s = -s end if c c %--------------------------------------------% c | Apply rotation to the left and right of H; | c | H <- G * H * G', where G = G(i,i+1,theta) | c %--------------------------------------------% c h(i,1) = r c a1 = c*h(i,2) + s*h(i+1,1) a2 = c*h(i+1,1) + s*h(i+1,2) a3 = c*h(i+1,1) - s*h(i,2) a4 = c*h(i+1,2) - s*h(i+1,1) c h(i,2) = c*a1 + s*a2 h(i+1,2) = c*a4 - s*a3 h(i+1,1) = c*a3 + s*a4 c c %----------------------------------------------------% c | Accumulate the rotation in the matrix Q; Q <- Q*G | c %----------------------------------------------------% c do 50 j = 1, min( j+jj, kplusp ) a1 = c*q(j,i) + s*q(j,i+1) q(j,i+1) = - s*q(j,i) + c*q(j,i+1) q(j,i) = a1 50 continue c 70 continue c end if c c %--------------------------% c | Update the block pointer | c %--------------------------% c istart = iend + 1 c c %------------------------------------------% c | Make sure that h(iend,1) is non-negative | c | If not then set h(iend,1) <-- -h(iend,1) | c | and negate the last column of Q. | c | We have effectively carried out a | c | similarity on transformation H | c %------------------------------------------% c if (h(iend,1) .lt. zero) then h(iend,1) = -h(iend,1) call dscal(kplusp, -one, q(1,iend), 1) end if c c %--------------------------------------------------------% c | Apply the same shift to the next block if there is any | c %--------------------------------------------------------% c if (iend .lt. kplusp) go to 20 c c %-----------------------------------------------------% c | Check if we can increase the the start of the block | c %-----------------------------------------------------% c do 80 i = itop, kplusp-1 if (h(i+1,1) .gt. zero) go to 90 itop = itop + 1 80 continue c c %-----------------------------------% c | Finished applying the jj-th shift | c %-----------------------------------% c 90 continue c c %------------------------------------------% c | All shifts have been applied. Check for | c | more possible deflation that might occur | c | after the last shift is applied. | c %------------------------------------------% c do 100 i = itop, kplusp-1 big = abs(h(i,2)) + abs(h(i+1,2)) if (h(i+1,1) .le. epsmch*big) then if (msglvl .gt. 0) then call igraphivout (logfil, 1, i, ndigit, & '_sapps: deflation at row/column no.') call igraphdvout (logfil, 1, h(i+1,1), ndigit, & '_sapps: the corresponding off diagonal element') end if h(i+1,1) = zero end if 100 continue c c %-------------------------------------------------% c | Compute the (kev+1)-st column of (V*Q) and | c | temporarily store the result in WORKD(N+1:2*N). | c | This is not necessary if h(kev+1,1) = 0. | c %-------------------------------------------------% c if ( h(kev+1,1) .gt. zero ) & call dgemv ('N', n, kplusp, one, v, ldv, & q(1,kev+1), 1, zero, workd(n+1), 1) c c %-------------------------------------------------------% c | Compute column 1 to kev of (V*Q) in backward order | c | taking advantage that Q is an upper triangular matrix | c | with lower bandwidth np. | c | Place results in v(:,kplusp-kev:kplusp) temporarily. | c %-------------------------------------------------------% c do 130 i = 1, kev call dgemv ('N', n, kplusp-i+1, one, v, ldv, & q(1,kev-i+1), 1, zero, workd, 1) call dcopy (n, workd, 1, v(1,kplusp-i+1), 1) 130 continue c c %-------------------------------------------------% c | Move v(:,kplusp-kev+1:kplusp) into v(:,1:kev). | c %-------------------------------------------------% c call dlacpy ('All', n, kev, v(1,np+1), ldv, v, ldv) c c %--------------------------------------------% c | Copy the (kev+1)-st column of (V*Q) in the | c | appropriate place if h(kev+1,1) .ne. zero. | c %--------------------------------------------% c if ( h(kev+1,1) .gt. zero ) & call dcopy (n, workd(n+1), 1, v(1,kev+1), 1) c c %-------------------------------------% c | Update the residual vector: | c | r <- sigmak*r + betak*v(:,kev+1) | c | where | c | sigmak = (e_{kev+p}'*Q)*e_{kev} | c | betak = e_{kev+1}'*H*e_{kev} | c %-------------------------------------% c call dscal (n, q(kplusp,kev), resid, 1) if (h(kev+1,1) .gt. zero) & call daxpy (n, h(kev+1,1), v(1,kev+1), 1, resid, 1) c if (msglvl .gt. 1) then call igraphdvout (logfil, 1, q(kplusp,kev), ndigit, & '_sapps: sigmak of the updated residual vector') call igraphdvout (logfil, 1, h(kev+1,1), ndigit, & '_sapps: betak of the updated residual vector') call igraphdvout (logfil, kev, h(1,2), ndigit, & '_sapps: updated main diagonal of H for next iteration') if (kev .gt. 1) then call igraphdvout (logfil, kev-1, h(2,1), ndigit, & '_sapps: updated sub diagonal of H for next iteration') end if end if c call igraphsecond (t1) tsapps = tsapps + (t1 - t0) c 9000 continue return c c %---------------% c | End of igraphdsapps | c %---------------% c end leidenbase/src/vendor/cs/0000755000176200001440000000000014532173045015042 5ustar liggesusersleidenbase/src/vendor/cs/cs_usolve.c0000644000176200001440000000102114447675375017224 0ustar liggesusers#include "cs.h" /* solve Ux=b where x and b are dense. x=b on input, solution on output. */ CS_INT cs_usolve (const cs *U, CS_ENTRY *x) { CS_INT p, j, n, *Up, *Ui ; CS_ENTRY *Ux ; if (!CS_CSC (U) || !x) return (0) ; /* check inputs */ n = U->n ; Up = U->p ; Ui = U->i ; Ux = U->x ; for (j = n-1 ; j >= 0 ; j--) { x [j] /= Ux [Up [j+1]-1] ; for (p = Up [j] ; p < Up [j+1]-1 ; p++) { x [Ui [p]] -= Ux [p] * x [j] ; } } return (1) ; } leidenbase/src/vendor/cs/cs_schol.c0000644000176200001440000000221714447675375017027 0ustar liggesusers#include "cs.h" /* ordering and symbolic analysis for a Cholesky factorization */ css *cs_schol (CS_INT order, const cs *A) { CS_INT n, *c, *post, *P ; cs *C ; css *S ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; S = cs_calloc (1, sizeof (css)) ; /* allocate result S */ if (!S) return (NULL) ; /* out of memory */ P = cs_amd (order, A) ; /* P = amd(A+A'), or natural */ S->pinv = cs_pinv (P, n) ; /* find inverse permutation */ cs_free (P) ; if (order && !S->pinv) return (cs_sfree (S)) ; C = cs_symperm (A, S->pinv, 0) ; /* C = spones(triu(A(P,P))) */ S->parent = cs_etree (C, 0) ; /* find etree of C */ post = cs_post (S->parent, n) ; /* postorder the etree */ c = cs_counts (C, S->parent, post, 0) ; /* find column counts of chol(C) */ cs_free (post) ; cs_spfree (C) ; S->cp = cs_malloc (n+1, sizeof (CS_INT)) ; /* allocate result S->cp */ S->unz = S->lnz = cs_cumsum (S->cp, c, n) ; /* find column pointers for L */ cs_free (c) ; return ((S->lnz >= 0) ? S : cs_sfree (S)) ; } leidenbase/src/vendor/cs/cs_dmperm.c0000644000176200001440000001442614447675375017210 0ustar liggesusers#include "cs.h" /* breadth-first search for coarse decomposition (C0,C1,R1 or R0,R3,C3) */ static CS_INT cs_bfs (const cs *A, CS_INT n, CS_INT *wi, CS_INT *wj, CS_INT *queue, const CS_INT *imatch, const CS_INT *jmatch, CS_INT mark) { CS_INT *Ap, *Ai, head = 0, tail = 0, j, i, p, j2 ; cs *C ; for (j = 0 ; j < n ; j++) /* place all unmatched nodes in queue */ { if (imatch [j] >= 0) continue ; /* skip j if matched */ wj [j] = 0 ; /* j in set C0 (R0 if transpose) */ queue [tail++] = j ; /* place unmatched col j in queue */ } if (tail == 0) return (1) ; /* quick return if no unmatched nodes */ C = (mark == 1) ? ((cs *) A) : cs_transpose (A, 0) ; if (!C) return (0) ; /* bfs of C=A' to find R3,C3 from R0 */ Ap = C->p ; Ai = C->i ; while (head < tail) /* while queue is not empty */ { j = queue [head++] ; /* get the head of the queue */ for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; if (wi [i] >= 0) continue ; /* skip if i is marked */ wi [i] = mark ; /* i in set R1 (C3 if transpose) */ j2 = jmatch [i] ; /* traverse alternating path to j2 */ if (wj [j2] >= 0) continue ;/* skip j2 if it is marked */ wj [j2] = mark ; /* j2 in set C1 (R3 if transpose) */ queue [tail++] = j2 ; /* add j2 to queue */ } } if (mark != 1) cs_spfree (C) ; /* free A' if it was created */ return (1) ; } /* collect matched rows and columns into p and q */ static void cs_matched (CS_INT n, const CS_INT *wj, const CS_INT *imatch, CS_INT *p, CS_INT *q, CS_INT *cc, CS_INT *rr, CS_INT set, CS_INT mark) { CS_INT kc = cc [set], j ; CS_INT kr = rr [set-1] ; for (j = 0 ; j < n ; j++) { if (wj [j] != mark) continue ; /* skip if j is not in C set */ p [kr++] = imatch [j] ; q [kc++] = j ; } cc [set+1] = kc ; rr [set] = kr ; } /* collect unmatched rows into the permutation vector p */ static void cs_unmatched (CS_INT m, const CS_INT *wi, CS_INT *p, CS_INT *rr, CS_INT set) { CS_INT i, kr = rr [set] ; for (i = 0 ; i < m ; i++) if (wi [i] == 0) p [kr++] = i ; rr [set+1] = kr ; } /* return 1 if row i is in R2 */ static CS_INT cs_rprune (CS_INT i, CS_INT j, CS_ENTRY aij, void *other) { CS_INT *rr = (CS_INT *) other ; return (i >= rr [1] && i < rr [2]) ; } /* Given A, compute coarse and then fine dmperm */ csd *cs_dmperm (const cs *A, CS_INT seed) { CS_INT m, n, i, j, k, cnz, nc, *jmatch, *imatch, *wi, *wj, *pinv, *Cp, *Ci, *ps, *rs, nb1, nb2, *p, *q, *cc, *rr, *r, *s, ok ; cs *C ; csd *D, *scc ; /* --- Maximum matching ------------------------------------------------- */ if (!CS_CSC (A)) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; D = cs_dalloc (m, n) ; /* allocate result */ if (!D) return (NULL) ; p = D->p ; q = D->q ; r = D->r ; s = D->s ; cc = D->cc ; rr = D->rr ; jmatch = cs_maxtrans (A, seed) ; /* max transversal */ imatch = jmatch + m ; /* imatch = inverse of jmatch */ if (!jmatch) return (cs_ddone (D, NULL, jmatch, 0)) ; /* --- Coarse decomposition --------------------------------------------- */ wi = r ; wj = s ; /* use r and s as workspace */ for (j = 0 ; j < n ; j++) wj [j] = -1 ; /* unmark all cols for bfs */ for (i = 0 ; i < m ; i++) wi [i] = -1 ; /* unmark all rows for bfs */ cs_bfs (A, n, wi, wj, q, imatch, jmatch, 1) ; /* find C1, R1 from C0*/ ok = cs_bfs (A, m, wj, wi, p, jmatch, imatch, 3) ; /* find R3, C3 from R0*/ if (!ok) return (cs_ddone (D, NULL, jmatch, 0)) ; cs_unmatched (n, wj, q, cc, 0) ; /* unmatched set C0 */ cs_matched (n, wj, imatch, p, q, cc, rr, 1, 1) ; /* set R1 and C1 */ cs_matched (n, wj, imatch, p, q, cc, rr, 2, -1) ; /* set R2 and C2 */ cs_matched (n, wj, imatch, p, q, cc, rr, 3, 3) ; /* set R3 and C3 */ cs_unmatched (m, wi, p, rr, 3) ; /* unmatched set R0 */ cs_free (jmatch) ; /* --- Fine decomposition ----------------------------------------------- */ pinv = cs_pinv (p, m) ; /* pinv=p' */ if (!pinv) return (cs_ddone (D, NULL, NULL, 0)) ; C = cs_permute (A, pinv, q, 0) ;/* C=A(p,q) (it will hold A(R2,C2)) */ cs_free (pinv) ; if (!C) return (cs_ddone (D, NULL, NULL, 0)) ; Cp = C->p ; nc = cc [3] - cc [2] ; /* delete cols C0, C1, and C3 from C */ if (cc [2] > 0) for (j = cc [2] ; j <= cc [3] ; j++) Cp [j-cc[2]] = Cp [j] ; C->n = nc ; if (rr [2] - rr [1] < m) /* delete rows R0, R1, and R3 from C */ { cs_fkeep (C, cs_rprune, rr) ; cnz = Cp [nc] ; Ci = C->i ; if (rr [1] > 0) for (k = 0 ; k < cnz ; k++) Ci [k] -= rr [1] ; } C->m = nc ; scc = cs_scc (C) ; /* find strongly connected components of C*/ if (!scc) return (cs_ddone (D, C, NULL, 0)) ; /* --- Combine coarse and fine decompositions --------------------------- */ ps = scc->p ; /* C(ps,ps) is the permuted matrix */ rs = scc->r ; /* kth block is rs[k]..rs[k+1]-1 */ nb1 = scc->nb ; /* # of blocks of A(R2,C2) */ for (k = 0 ; k < nc ; k++) wj [k] = q [ps [k] + cc [2]] ; for (k = 0 ; k < nc ; k++) q [k + cc [2]] = wj [k] ; for (k = 0 ; k < nc ; k++) wi [k] = p [ps [k] + rr [1]] ; for (k = 0 ; k < nc ; k++) p [k + rr [1]] = wi [k] ; nb2 = 0 ; /* create the fine block partitions */ r [0] = s [0] = 0 ; if (cc [2] > 0) nb2++ ; /* leading coarse block A (R1, [C0 C1]) */ for (k = 0 ; k < nb1 ; k++) /* coarse block A (R2,C2) */ { r [nb2] = rs [k] + rr [1] ; /* A (R2,C2) splits into nb1 fine blocks */ s [nb2] = rs [k] + cc [2] ; nb2++ ; } if (rr [2] < m) { r [nb2] = rr [2] ; /* trailing coarse block A ([R3 R0], C3) */ s [nb2] = cc [3] ; nb2++ ; } r [nb2] = m ; s [nb2] = n ; D->nb = nb2 ; cs_dfree (scc) ; return (cs_ddone (D, C, NULL, 1)) ; } leidenbase/src/vendor/cs/cs_lusol.c0000644000176200001440000000155114447675375017055 0ustar liggesusers#include "cs.h" /* x=A\b where A is unsymmetric; b overwritten with solution */ CS_INT cs_lusol (CS_INT order, const cs *A, CS_ENTRY *b, double tol) { CS_ENTRY *x ; css *S ; csn *N ; CS_INT n, ok ; if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ n = A->n ; S = cs_sqr (order, A, 0) ; /* ordering and symbolic analysis */ N = cs_lu (A, S, tol) ; /* numeric LU factorization */ x = cs_malloc (n, sizeof (CS_ENTRY)) ; /* get workspace */ ok = (S && N && x) ; if (ok) { cs_ipvec (N->pinv, b, x, n) ; /* x = b(p) */ cs_lsolve (N->L, x) ; /* x = L\x */ cs_usolve (N->U, x) ; /* x = U\x */ cs_ipvec (S->q, x, b, n) ; /* b(q) = x */ } cs_free (x) ; cs_sfree (S) ; cs_nfree (N) ; return (ok) ; } leidenbase/src/vendor/cs/cs_entry.c0000644000176200001440000000071314447675375017057 0ustar liggesusers#include "cs.h" /* add an entry to a triplet matrix; return 1 if ok, 0 otherwise */ CS_INT cs_entry (cs *T, CS_INT i, CS_INT j, CS_ENTRY x) { if (!CS_TRIPLET (T) || i < 0 || j < 0) return (0) ; /* check inputs */ if (T->nz >= T->nzmax && !cs_sprealloc (T,2*(T->nzmax))) return (0) ; if (T->x) T->x [T->nz] = x ; T->i [T->nz] = i ; T->p [T->nz++] = j ; T->m = CS_MAX (T->m, i+1) ; T->n = CS_MAX (T->n, j+1) ; return (1) ; } leidenbase/src/vendor/cs/cs_cholsol.c0000644000176200001440000000154514447675375017365 0ustar liggesusers#include "cs.h" /* x=A\b where A is symmetric positive definite; b overwritten with solution */ CS_INT cs_cholsol (CS_INT order, const cs *A, CS_ENTRY *b) { CS_ENTRY *x ; css *S ; csn *N ; CS_INT n, ok ; if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ n = A->n ; S = cs_schol (order, A) ; /* ordering and symbolic analysis */ N = cs_chol (A, S) ; /* numeric Cholesky factorization */ x = cs_malloc (n, sizeof (CS_ENTRY)) ; /* get workspace */ ok = (S && N && x) ; if (ok) { cs_ipvec (S->pinv, b, x, n) ; /* x = P*b */ cs_lsolve (N->L, x) ; /* x = L\x */ cs_ltsolve (N->L, x) ; /* x = L'\x */ cs_pvec (S->pinv, x, b, n) ; /* b = P'*x */ } cs_free (x) ; cs_sfree (S) ; cs_nfree (N) ; return (ok) ; } leidenbase/src/vendor/cs/cs_counts.c0000644000176200001440000000550314447675375017233 0ustar liggesusers#include "cs.h" /* column counts of LL'=A or LL'=A'A, given parent & post ordering */ #define HEAD(k,j) (ata ? head [k] : j) #define NEXT(J) (ata ? next [J] : -1) static void init_ata (cs *AT, const CS_INT *post, CS_INT *w, CS_INT **head, CS_INT **next) { CS_INT i, k, p, m = AT->n, n = AT->m, *ATp = AT->p, *ATi = AT->i ; *head = w+4*n, *next = w+5*n+1 ; for (k = 0 ; k < n ; k++) w [post [k]] = k ; /* invert post */ for (i = 0 ; i < m ; i++) { for (k = n, p = ATp[i] ; p < ATp[i+1] ; p++) k = CS_MIN (k, w [ATi[p]]); (*next) [i] = (*head) [k] ; /* place row i in linked list k */ (*head) [k] = i ; } } CS_INT *cs_counts (const cs *A, const CS_INT *parent, const CS_INT *post, CS_INT ata) { CS_INT i, j, k, n, m, J, s, p, q, jleaf, *ATp, *ATi, *maxfirst, *prevleaf, *ancestor, *head = NULL, *next = NULL, *colcount, *w, *first, *delta ; cs *AT ; if (!CS_CSC (A) || !parent || !post) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; s = 4*n + (ata ? (n+m+1) : 0) ; delta = colcount = cs_malloc (n, sizeof (CS_INT)) ; /* allocate result */ w = cs_malloc (s, sizeof (CS_INT)) ; /* get workspace */ AT = cs_transpose (A, 0) ; /* AT = A' */ if (!AT || !colcount || !w) return (cs_idone (colcount, AT, w, 0)) ; ancestor = w ; maxfirst = w+n ; prevleaf = w+2*n ; first = w+3*n ; for (k = 0 ; k < s ; k++) w [k] = -1 ; /* clear workspace w [0..s-1] */ for (k = 0 ; k < n ; k++) /* find first [j] */ { j = post [k] ; delta [j] = (first [j] == -1) ? 1 : 0 ; /* delta[j]=1 if j is a leaf */ for ( ; j != -1 && first [j] == -1 ; j = parent [j]) first [j] = k ; } ATp = AT->p ; ATi = AT->i ; if (ata) init_ata (AT, post, w, &head, &next) ; for (i = 0 ; i < n ; i++) ancestor [i] = i ; /* each node in its own set */ for (k = 0 ; k < n ; k++) { j = post [k] ; /* j is the kth node in postordered etree */ if (parent [j] != -1) delta [parent [j]]-- ; /* j is not a root */ for (J = HEAD (k,j) ; J != -1 ; J = NEXT (J)) /* J=j for LL'=A case */ { for (p = ATp [J] ; p < ATp [J+1] ; p++) { i = ATi [p] ; q = cs_leaf (i, j, first, maxfirst, prevleaf, ancestor, &jleaf); if (jleaf >= 1) delta [j]++ ; /* A(i,j) is in skeleton */ if (jleaf == 2) delta [q]-- ; /* account for overlap in q */ } } if (parent [j] != -1) ancestor [j] = parent [j] ; } for (j = 0 ; j < n ; j++) /* sum up delta's of each child */ { if (parent [j] != -1) colcount [parent [j]] += colcount [j] ; } return (cs_idone (colcount, AT, w, 1)) ; /* success: free workspace */ } leidenbase/src/vendor/cs/cs_transpose.c0000644000176200001440000000203514447675375017733 0ustar liggesusers#include "cs.h" /* C = A' */ cs *cs_transpose (const cs *A, CS_INT values) { CS_INT p, q, j, *Cp, *Ci, n, m, *Ap, *Ai, *w ; CS_ENTRY *Cx, *Ax ; cs *C ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; C = cs_spalloc (n, m, Ap [n], values && Ax, 0) ; /* allocate result */ w = cs_calloc (m, sizeof (CS_INT)) ; /* get workspace */ if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ Cp = C->p ; Ci = C->i ; Cx = C->x ; for (p = 0 ; p < Ap [n] ; p++) w [Ai [p]]++ ; /* row counts */ cs_cumsum (Cp, w, m) ; /* row pointers */ for (j = 0 ; j < n ; j++) { for (p = Ap [j] ; p < Ap [j+1] ; p++) { Ci [q = w [Ai [p]]++] = j ; /* place A(i,j) as entry C(j,i) */ if (Cx) Cx [q] = (values > 0) ? CS_CONJ (Ax [p]) : Ax [p] ; } } return (cs_done (C, w, NULL, 1)) ; /* success; free w and return C */ } leidenbase/src/vendor/cs/cs_multiply.c0000644000176200001440000000305114447675375017573 0ustar liggesusers#include "cs.h" /* C = A*B */ cs *cs_multiply (const cs *A, const cs *B) { CS_INT p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values, *Bi ; CS_ENTRY *x, *Bx, *Cx ; cs *C ; if (!CS_CSC (A) || !CS_CSC (B)) return (NULL) ; /* check inputs */ if (A->n != B->m) return (NULL) ; m = A->m ; anz = A->p [A->n] ; n = B->n ; Bp = B->p ; Bi = B->i ; Bx = B->x ; bnz = Bp [n] ; w = cs_calloc (m, sizeof (CS_INT)) ; /* get workspace */ values = (A->x != NULL) && (Bx != NULL) ; x = values ? cs_malloc (m, sizeof (CS_ENTRY)) : NULL ; /* get workspace */ C = cs_spalloc (m, n, anz + bnz, values, 0) ; /* allocate result */ if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ; Cp = C->p ; for (j = 0 ; j < n ; j++) { if (nz + m > C->nzmax && !cs_sprealloc (C, 2*(C->nzmax)+m)) { return (cs_done (C, w, x, 0)) ; /* out of memory */ } Ci = C->i ; Cx = C->x ; /* C->i and C->x may be reallocated */ Cp [j] = nz ; /* column j of C starts here */ for (p = Bp [j] ; p < Bp [j+1] ; p++) { nz = cs_scatter (A, Bi [p], Bx ? Bx [p] : 1, w, x, j+1, C, nz) ; } if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ; } Cp [n] = nz ; /* finalize the last column of C */ cs_sprealloc (C, 0) ; /* remove extra space from C */ return (cs_done (C, w, x, 1)) ; /* success; free workspace, return C */ } leidenbase/src/vendor/cs/cs_post.c0000644000176200001440000000210314447675375016676 0ustar liggesusers#include "cs.h" /* post order a forest */ CS_INT *cs_post (const CS_INT *parent, CS_INT n) { CS_INT j, k = 0, *post, *w, *head, *next, *stack ; if (!parent) return (NULL) ; /* check inputs */ post = cs_malloc (n, sizeof (CS_INT)) ; /* allocate result */ w = cs_malloc (3*n, sizeof (CS_INT)) ; /* get workspace */ if (!w || !post) return (cs_idone (post, NULL, w, 0)) ; head = w ; next = w + n ; stack = w + 2*n ; for (j = 0 ; j < n ; j++) head [j] = -1 ; /* empty linked lists */ for (j = n-1 ; j >= 0 ; j--) /* traverse nodes in reverse order*/ { if (parent [j] == -1) continue ; /* j is a root */ next [j] = head [parent [j]] ; /* add j to list of its parent */ head [parent [j]] = j ; } for (j = 0 ; j < n ; j++) { if (parent [j] != -1) continue ; /* skip j if it is not a root */ k = cs_tdfs (j, k, head, next, post, stack) ; } return (cs_idone (post, NULL, w, 1)) ; /* success; free w, return post */ } leidenbase/src/vendor/cs/cs_fkeep.c0000644000176200001440000000170114447675375017006 0ustar liggesusers#include "cs.h" /* drop entries for which fkeep(A(i,j)) is false; return nz if OK, else -1 */ CS_INT cs_fkeep (cs *A, CS_INT (*fkeep) (CS_INT, CS_INT, CS_ENTRY, void *), void *other) { CS_INT j, p, nz = 0, n, *Ap, *Ai ; CS_ENTRY *Ax ; if (!CS_CSC (A) || !fkeep) return (-1) ; /* check inputs */ n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; for (j = 0 ; j < n ; j++) { p = Ap [j] ; /* get current location of col j */ Ap [j] = nz ; /* record new location of col j */ for ( ; p < Ap [j+1] ; p++) { if (fkeep (Ai [p], j, Ax ? Ax [p] : 1, other)) { if (Ax) Ax [nz] = Ax [p] ; /* keep A(i,j) */ Ai [nz++] = Ai [p] ; } } } Ap [n] = nz ; /* finalize A */ cs_sprealloc (A, 0) ; /* remove extra space from A */ return (nz) ; } leidenbase/src/vendor/cs/cs_print.c0000644000176200001440000000347614447675375017063 0ustar liggesusers#include "cs.h" /* print a sparse matrix; use %g for integers to avoid differences with CS_INT */ /* Disabled for igraph as it prints to stdio */ #if 0 CS_INT cs_print (const cs *A, CS_INT brief) { CS_INT p, j, m, n, nzmax, nz, *Ap, *Ai ; CS_ENTRY *Ax ; if (!A) { printf ("(null)\n") ; return (0) ; } m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; nzmax = A->nzmax ; nz = A->nz ; printf ("CXSparse Version %d.%d.%d, %s. %s\n", CS_VER, CS_SUBVER, CS_SUBSUB, CS_DATE, CS_COPYRIGHT) ; if (nz < 0) { printf ("%g-by-%g, nzmax: %g nnz: %g, 1-norm: %g\n", (double) m, (double) n, (double) nzmax, (double) (Ap [n]), cs_norm (A)) ; for (j = 0 ; j < n ; j++) { printf (" col %g : locations %g to %g\n", (double) j, (double) (Ap [j]), (double) (Ap [j+1]-1)) ; for (p = Ap [j] ; p < Ap [j+1] ; p++) { printf (" %g : ", (double) (Ai [p])) ; #ifdef CS_COMPLEX printf ("(%g, %g)\n", Ax ? CS_REAL (Ax [p]) : 1, Ax ? CS_IMAG (Ax [p]) : 0) ; #else printf ("%g\n", Ax ? Ax [p] : 1) ; #endif if (brief && p > 20) { printf (" ...\n") ; return (1) ; } } } } else { printf ("triplet: %g-by-%g, nzmax: %g nnz: %g\n", (double) m, (double) n, (double) nzmax, (double) nz) ; for (p = 0 ; p < nz ; p++) { printf (" %g %g : ", (double) (Ai [p]), (double) (Ap [p])) ; #ifdef CS_COMPLEX printf ("(%g, %g)\n", Ax ? CS_REAL (Ax [p]) : 1, Ax ? CS_IMAG (Ax [p]) : 0) ; #else printf ("%g\n", Ax ? Ax [p] : 1) ; #endif if (brief && p > 20) { printf (" ...\n") ; return (1) ; } } } return (1) ; } #endif leidenbase/src/vendor/cs/SuiteSparse_config.h0000644000176200001440000001714714447675375021043 0ustar liggesusers/* ========================================================================== */ /* === SuiteSparse_config =================================================== */ /* ========================================================================== */ /* Configuration file for SuiteSparse: a Suite of Sparse matrix packages * (AMD, COLAMD, CCOLAMD, CAMD, CHOLMOD, UMFPACK, CXSparse, and others). * * SuiteSparse_config.h provides the definition of the long integer. On most * systems, a C program can be compiled in LP64 mode, in which long's and * pointers are both 64-bits, and int's are 32-bits. Windows 64, however, uses * the LLP64 model, in which int's and long's are 32-bits, and long long's and * pointers are 64-bits. * * SuiteSparse packages that include long integer versions are * intended for the LP64 mode. However, as a workaround for Windows 64 * (and perhaps other systems), the long integer can be redefined. * * If _WIN64 is defined, then the __int64 type is used instead of long. * * The long integer can also be defined at compile time. For example, this * could be added to SuiteSparse_config.mk: * * CFLAGS = -O -D'SuiteSparse_long=long long' \ * -D'SuiteSparse_long_max=9223372036854775801' -D'SuiteSparse_long_idd="lld"' * * This file defines SuiteSparse_long as either long (on all but _WIN64) or * __int64 on Windows 64. The intent is that a SuiteSparse_long is always a * 64-bit integer in a 64-bit code. ptrdiff_t might be a better choice than * long; it is always the same size as a pointer. * * This file also defines the SUITESPARSE_VERSION and related definitions. * * Copyright (c) 2012, Timothy A. Davis. No licensing restrictions apply * to this file or to the SuiteSparse_config directory. * Author: Timothy A. Davis. */ #ifndef SUITESPARSE_CONFIG_H #define SUITESPARSE_CONFIG_H #ifdef __cplusplus extern "C" { #endif #include #include /* ========================================================================== */ /* === SuiteSparse_long ===================================================== */ /* ========================================================================== */ #ifndef SuiteSparse_long #ifdef _WIN64 #define SuiteSparse_long __int64 #define SuiteSparse_long_max _I64_MAX #define SuiteSparse_long_idd "I64d" #else #define SuiteSparse_long long #define SuiteSparse_long_max LONG_MAX #define SuiteSparse_long_idd "ld" #endif #define SuiteSparse_long_id "%" SuiteSparse_long_idd #endif /* Disable unneeded parts for igraph */ #if 0 /* start comment */ /* ========================================================================== */ /* === SuiteSparse_config parameters and functions ========================== */ /* ========================================================================== */ /* SuiteSparse-wide parameters are placed in this struct. It is meant to be an extern, globally-accessible struct. It is not meant to be updated frequently by multiple threads. Rather, if an application needs to modify SuiteSparse_config, it should do it once at the beginning of the application, before multiple threads are launched. The intent of these function pointers is that they not be used in your application directly, except to assign them to the desired user-provided functions. Rather, you should use the */ struct SuiteSparse_config_struct { void *(*malloc_func) (size_t) ; /* pointer to malloc */ void *(*calloc_func) (size_t, size_t) ; /* pointer to calloc */ void *(*realloc_func) (void *, size_t) ; /* pointer to realloc */ void (*free_func) (void *) ; /* pointer to free */ int (*printf_func) (const char *, ...) ; /* pointer to printf */ double (*hypot_func) (double, double) ; /* pointer to hypot */ int (*divcomplex_func) (double, double, double, double, double *, double *); } ; extern struct SuiteSparse_config_struct SuiteSparse_config ; void SuiteSparse_start ( void ) ; /* called to start SuiteSparse */ void SuiteSparse_finish ( void ) ; /* called to finish SuiteSparse */ void *SuiteSparse_malloc /* pointer to allocated block of memory */ ( size_t nitems, /* number of items to malloc (>=1 is enforced) */ size_t size_of_item /* sizeof each item */ ) ; void *SuiteSparse_calloc /* pointer to allocated block of memory */ ( size_t nitems, /* number of items to calloc (>=1 is enforced) */ size_t size_of_item /* sizeof each item */ ) ; void *SuiteSparse_realloc /* pointer to reallocated block of memory, or to original block if the realloc failed. */ ( size_t nitems_new, /* new number of items in the object */ size_t nitems_old, /* old number of items in the object */ size_t size_of_item, /* sizeof each item */ void *p, /* old object to reallocate */ int *ok /* 1 if successful, 0 otherwise */ ) ; void *SuiteSparse_free /* always returns NULL */ ( void *p /* block to free */ ) ; void SuiteSparse_tic /* start the timer */ ( double tic [2] /* output, contents undefined on input */ ) ; double SuiteSparse_toc /* return time in seconds since last tic */ ( double tic [2] /* input: from last call to SuiteSparse_tic */ ) ; double SuiteSparse_time /* returns current wall clock time in seconds */ ( void ) ; /* returns sqrt (x^2 + y^2), computed reliably */ double SuiteSparse_hypot (double x, double y) ; /* complex division of c = a/b */ int SuiteSparse_divcomplex ( double ar, double ai, /* real and imaginary parts of a */ double br, double bi, /* real and imaginary parts of b */ double *cr, double *ci /* real and imaginary parts of c */ ) ; /* determine which timer to use, if any */ #ifndef NTIMER #ifdef _POSIX_C_SOURCE #if _POSIX_C_SOURCE >= 199309L #define SUITESPARSE_TIMER_ENABLED #endif #endif #endif /* SuiteSparse printf macro */ #define SUITESPARSE_PRINTF(params) \ { \ if (SuiteSparse_config.printf_func != NULL) \ { \ (void) (SuiteSparse_config.printf_func) params ; \ } \ } /* ========================================================================== */ /* === SuiteSparse version ================================================== */ /* ========================================================================== */ /* SuiteSparse is not a package itself, but a collection of packages, some of * which must be used together (UMFPACK requires AMD, CHOLMOD requires AMD, * COLAMD, CAMD, and CCOLAMD, etc). A version number is provided here for the * collection itself, which is also the version number of SuiteSparse_config. */ int SuiteSparse_version /* returns SUITESPARSE_VERSION */ ( /* output, not defined on input. Not used if NULL. Returns the three version codes in version [0..2]: version [0] is SUITESPARSE_MAIN_VERSION version [1] is SUITESPARSE_SUB_VERSION version [2] is SUITESPARSE_SUBSUB_VERSION */ int version [3] ) ; /* Versions prior to 4.2.0 do not have the above function. The following code fragment will work with any version of SuiteSparse: #ifdef SUITESPARSE_HAS_VERSION_FUNCTION v = SuiteSparse_version (NULL) ; #else v = SUITESPARSE_VERSION ; #endif */ #define SUITESPARSE_HAS_VERSION_FUNCTION #endif /* end comment */ #define SUITESPARSE_DATE "Mar 3, 2021" #define SUITESPARSE_VER_CODE(main,sub) ((main) * 1000 + (sub)) #define SUITESPARSE_MAIN_VERSION 5 #define SUITESPARSE_SUB_VERSION 9 #define SUITESPARSE_SUBSUB_VERSION 0 #define SUITESPARSE_VERSION \ SUITESPARSE_VER_CODE(SUITESPARSE_MAIN_VERSION,SUITESPARSE_SUB_VERSION) #ifdef __cplusplus } #endif #endif leidenbase/src/vendor/cs/cs.h0000644000176200001440000010012614447675375015642 0ustar liggesusers/* ========================================================================== */ /* CXSparse/Include/cs.h file */ /* ========================================================================== */ /* This is the CXSparse/Include/cs.h file. It has the same name (cs.h) as the CSparse/Include/cs.h file. The 'make install' for SuiteSparse installs CXSparse, and this file, instead of CSparse. The two packages have the same cs.h include filename, because CXSparse is a superset of CSparse. Any user program that uses CSparse can rely on CXSparse instead, with no change to the user code. The #include "cs.h" line will work for both versions, in user code, and the function names and user-visible typedefs from CSparse all appear in CXSparse. For experimenting and changing the package itself, I recommend using CSparse since it's simpler and easier to modify. For using the package in production codes, I recommend CXSparse since it has more features (support for complex matrices, and both int and long versions). */ /* ========================================================================== */ #ifndef _CXS_H #define _CXS_H #include #include #include #include #ifdef MATLAB_MEX_FILE #include "mex.h" #endif #ifdef __cplusplus #ifndef NCOMPLEX #include typedef std::complex cs_complex_t ; #endif extern "C" { #else #ifndef NCOMPLEX #include #define cs_complex_t double _Complex #endif #endif #define CS_VER 3 /* CXSparse Version */ #define CS_SUBVER 2 #define CS_SUBSUB 0 #define CS_DATE "Sept 12, 2017" /* CSparse release date */ #define CS_COPYRIGHT "Copyright (c) Timothy A. Davis, 2006-2016" #define CXSPARSE #include "SuiteSparse_config.h" #define cs_long_t SuiteSparse_long #define cs_long_t_id SuiteSparse_long_id #define cs_long_t_max SuiteSparse_long_max /* -------------------------------------------------------------------------- */ /* double/int version of CXSparse */ /* -------------------------------------------------------------------------- */ /* --- primary CSparse routines and data structures ------------------------- */ typedef struct cs_di_sparse /* matrix in compressed-column or triplet form */ { int nzmax ; /* maximum number of entries */ int m ; /* number of rows */ int n ; /* number of columns */ int *p ; /* column pointers (size n+1) or col indices (size nzmax) */ int *i ; /* row indices, size nzmax */ double *x ; /* numerical values, size nzmax */ int nz ; /* # of entries in triplet matrix, -1 for compressed-col */ } cs_di ; cs_di *cs_di_add (const cs_di *A, const cs_di *B, double alpha, double beta) ; int cs_di_cholsol (int order, const cs_di *A, double *b) ; int cs_di_dupl (cs_di *A) ; int cs_di_entry (cs_di *T, int i, int j, double x) ; int cs_di_lusol (int order, const cs_di *A, double *b, double tol) ; int cs_di_gaxpy (const cs_di *A, const double *x, double *y) ; cs_di *cs_di_multiply (const cs_di *A, const cs_di *B) ; int cs_di_qrsol (int order, const cs_di *A, double *b) ; cs_di *cs_di_transpose (const cs_di *A, int values) ; cs_di *cs_di_compress (const cs_di *T) ; double cs_di_norm (const cs_di *A) ; /*int cs_di_print (const cs_di *A, int brief) ;*/ cs_di *cs_di_load (FILE *f) ; /* utilities */ void *cs_di_calloc (int n, size_t size) ; void *cs_di_free (void *p) ; void *cs_di_realloc (void *p, int n, size_t size, int *ok) ; cs_di *cs_di_spalloc (int m, int n, int nzmax, int values, int t) ; cs_di *cs_di_spfree (cs_di *A) ; int cs_di_sprealloc (cs_di *A, int nzmax) ; void *cs_di_malloc (int n, size_t size) ; /* --- secondary CSparse routines and data structures ----------------------- */ typedef struct cs_di_symbolic /* symbolic Cholesky, LU, or QR analysis */ { int *pinv ; /* inverse row perm. for QR, fill red. perm for Chol */ int *q ; /* fill-reducing column permutation for LU and QR */ int *parent ; /* elimination tree for Cholesky and QR */ int *cp ; /* column pointers for Cholesky, row counts for QR */ int *leftmost ; /* leftmost[i] = min(find(A(i,:))), for QR */ int m2 ; /* # of rows for QR, after adding fictitious rows */ double lnz ; /* # entries in L for LU or Cholesky; in V for QR */ double unz ; /* # entries in U for LU; in R for QR */ } cs_dis ; typedef struct cs_di_numeric /* numeric Cholesky, LU, or QR factorization */ { cs_di *L ; /* L for LU and Cholesky, V for QR */ cs_di *U ; /* U for LU, r for QR, not used for Cholesky */ int *pinv ; /* partial pivoting for LU */ double *B ; /* beta [0..n-1] for QR */ } cs_din ; typedef struct cs_di_dmperm_results /* cs_di_dmperm or cs_di_scc output */ { int *p ; /* size m, row permutation */ int *q ; /* size n, column permutation */ int *r ; /* size nb+1, block k is rows r[k] to r[k+1]-1 in A(p,q) */ int *s ; /* size nb+1, block k is cols s[k] to s[k+1]-1 in A(p,q) */ int nb ; /* # of blocks in fine dmperm decomposition */ int rr [5] ; /* coarse row decomposition */ int cc [5] ; /* coarse column decomposition */ } cs_did ; int *cs_di_amd (int order, const cs_di *A) ; cs_din *cs_di_chol (const cs_di *A, const cs_dis *S) ; cs_did *cs_di_dmperm (const cs_di *A, int seed) ; int cs_di_droptol (cs_di *A, double tol) ; int cs_di_dropzeros (cs_di *A) ; int cs_di_happly (const cs_di *V, int i, double beta, double *x) ; int cs_di_ipvec (const int *p, const double *b, double *x, int n) ; int cs_di_lsolve (const cs_di *L, double *x) ; int cs_di_ltsolve (const cs_di *L, double *x) ; cs_din *cs_di_lu (const cs_di *A, const cs_dis *S, double tol) ; cs_di *cs_di_permute (const cs_di *A, const int *pinv, const int *q, int values) ; int *cs_di_pinv (const int *p, int n) ; int cs_di_pvec (const int *p, const double *b, double *x, int n) ; cs_din *cs_di_qr (const cs_di *A, const cs_dis *S) ; cs_dis *cs_di_schol (int order, const cs_di *A) ; cs_dis *cs_di_sqr (int order, const cs_di *A, int qr) ; cs_di *cs_di_symperm (const cs_di *A, const int *pinv, int values) ; int cs_di_usolve (const cs_di *U, double *x) ; int cs_di_utsolve (const cs_di *U, double *x) ; int cs_di_updown (cs_di *L, int sigma, const cs_di *C, const int *parent) ; /* utilities */ cs_dis *cs_di_sfree (cs_dis *S) ; cs_din *cs_di_nfree (cs_din *N) ; cs_did *cs_di_dfree (cs_did *D) ; /* --- tertiary CSparse routines -------------------------------------------- */ int *cs_di_counts (const cs_di *A, const int *parent, const int *post, int ata) ; double cs_di_cumsum (int *p, int *c, int n) ; int cs_di_dfs (int j, cs_di *G, int top, int *xi, int *pstack, const int *pinv) ; int *cs_di_etree (const cs_di *A, int ata) ; int cs_di_fkeep (cs_di *A, int (*fkeep) (int, int, double, void *), void *other) ; double cs_di_house (double *x, double *beta, int n) ; int *cs_di_maxtrans (const cs_di *A, int seed) ; int *cs_di_post (const int *parent, int n) ; cs_did *cs_di_scc (cs_di *A) ; int cs_di_scatter (const cs_di *A, int j, double beta, int *w, double *x, int mark, cs_di *C, int nz) ; int cs_di_tdfs (int j, int k, int *head, const int *next, int *post, int *stack) ; int cs_di_leaf (int i, int j, const int *first, int *maxfirst, int *prevleaf, int *ancestor, int *jleaf) ; int cs_di_reach (cs_di *G, const cs_di *B, int k, int *xi, const int *pinv) ; int cs_di_spsolve (cs_di *L, const cs_di *B, int k, int *xi, double *x, const int *pinv, int lo) ; int cs_di_ereach (const cs_di *A, int k, const int *parent, int *s, int *w) ; int *cs_di_randperm (int n, int seed) ; /* utilities */ cs_did *cs_di_dalloc (int m, int n) ; cs_di *cs_di_done (cs_di *C, void *w, void *x, int ok) ; int *cs_di_idone (int *p, cs_di *C, void *w, int ok) ; cs_din *cs_di_ndone (cs_din *N, cs_di *C, void *w, void *x, int ok) ; cs_did *cs_di_ddone (cs_did *D, cs_di *C, void *w, int ok) ; /* -------------------------------------------------------------------------- */ /* double/cs_long_t version of CXSparse */ /* -------------------------------------------------------------------------- */ /* --- primary CSparse routines and data structures ------------------------- */ typedef struct cs_dl_sparse /* matrix in compressed-column or triplet form */ { cs_long_t nzmax ; /* maximum number of entries */ cs_long_t m ; /* number of rows */ cs_long_t n ; /* number of columns */ cs_long_t *p ; /* column pointers (size n+1) or col indlces (size nzmax) */ cs_long_t *i ; /* row indices, size nzmax */ double *x ; /* numerical values, size nzmax */ cs_long_t nz ; /* # of entries in triplet matrix, -1 for compressed-col */ } cs_dl ; cs_dl *cs_dl_add (const cs_dl *A, const cs_dl *B, double alpha, double beta) ; cs_long_t cs_dl_cholsol (cs_long_t order, const cs_dl *A, double *b) ; cs_long_t cs_dl_dupl (cs_dl *A) ; cs_long_t cs_dl_entry (cs_dl *T, cs_long_t i, cs_long_t j, double x) ; cs_long_t cs_dl_lusol (cs_long_t order, const cs_dl *A, double *b, double tol) ; cs_long_t cs_dl_gaxpy (const cs_dl *A, const double *x, double *y) ; cs_dl *cs_dl_multiply (const cs_dl *A, const cs_dl *B) ; cs_long_t cs_dl_qrsol (cs_long_t order, const cs_dl *A, double *b) ; cs_dl *cs_dl_transpose (const cs_dl *A, cs_long_t values) ; cs_dl *cs_dl_compress (const cs_dl *T) ; double cs_dl_norm (const cs_dl *A) ; /*cs_long_t cs_dl_print (const cs_dl *A, cs_long_t brief) ;*/ cs_dl *cs_dl_load (FILE *f) ; /* utilities */ void *cs_dl_calloc (cs_long_t n, size_t size) ; void *cs_dl_free (void *p) ; void *cs_dl_realloc (void *p, cs_long_t n, size_t size, cs_long_t *ok) ; cs_dl *cs_dl_spalloc (cs_long_t m, cs_long_t n, cs_long_t nzmax, cs_long_t values, cs_long_t t) ; cs_dl *cs_dl_spfree (cs_dl *A) ; cs_long_t cs_dl_sprealloc (cs_dl *A, cs_long_t nzmax) ; void *cs_dl_malloc (cs_long_t n, size_t size) ; /* --- secondary CSparse routines and data structures ----------------------- */ typedef struct cs_dl_symbolic /* symbolic Cholesky, LU, or QR analysis */ { cs_long_t *pinv ; /* inverse row perm. for QR, fill red. perm for Chol */ cs_long_t *q ; /* fill-reducing column permutation for LU and QR */ cs_long_t *parent ; /* elimination tree for Cholesky and QR */ cs_long_t *cp ; /* column pointers for Cholesky, row counts for QR */ cs_long_t *leftmost ; /* leftmost[i] = min(find(A(i,:))), for QR */ cs_long_t m2 ; /* # of rows for QR, after adding fictitious rows */ double lnz ; /* # entries in L for LU or Cholesky; in V for QR */ double unz ; /* # entries in U for LU; in R for QR */ } cs_dls ; typedef struct cs_dl_numeric /* numeric Cholesky, LU, or QR factorization */ { cs_dl *L ; /* L for LU and Cholesky, V for QR */ cs_dl *U ; /* U for LU, r for QR, not used for Cholesky */ cs_long_t *pinv ; /* partial pivoting for LU */ double *B ; /* beta [0..n-1] for QR */ } cs_dln ; typedef struct cs_dl_dmperm_results /* cs_dl_dmperm or cs_dl_scc output */ { cs_long_t *p ; /* size m, row permutation */ cs_long_t *q ; /* size n, column permutation */ cs_long_t *r ; /* size nb+1, block k is rows r[k] to r[k+1]-1 in A(p,q) */ cs_long_t *s ; /* size nb+1, block k is cols s[k] to s[k+1]-1 in A(p,q) */ cs_long_t nb ; /* # of blocks in fine dmperm decomposition */ cs_long_t rr [5] ; /* coarse row decomposition */ cs_long_t cc [5] ; /* coarse column decomposition */ } cs_dld ; cs_long_t *cs_dl_amd (cs_long_t order, const cs_dl *A) ; cs_dln *cs_dl_chol (const cs_dl *A, const cs_dls *S) ; cs_dld *cs_dl_dmperm (const cs_dl *A, cs_long_t seed) ; cs_long_t cs_dl_droptol (cs_dl *A, double tol) ; cs_long_t cs_dl_dropzeros (cs_dl *A) ; cs_long_t cs_dl_happly (const cs_dl *V, cs_long_t i, double beta, double *x) ; cs_long_t cs_dl_ipvec (const cs_long_t *p, const double *b, double *x, cs_long_t n) ; cs_long_t cs_dl_lsolve (const cs_dl *L, double *x) ; cs_long_t cs_dl_ltsolve (const cs_dl *L, double *x) ; cs_dln *cs_dl_lu (const cs_dl *A, const cs_dls *S, double tol) ; cs_dl *cs_dl_permute (const cs_dl *A, const cs_long_t *pinv, const cs_long_t *q, cs_long_t values) ; cs_long_t *cs_dl_pinv (const cs_long_t *p, cs_long_t n) ; cs_long_t cs_dl_pvec (const cs_long_t *p, const double *b, double *x, cs_long_t n) ; cs_dln *cs_dl_qr (const cs_dl *A, const cs_dls *S) ; cs_dls *cs_dl_schol (cs_long_t order, const cs_dl *A) ; cs_dls *cs_dl_sqr (cs_long_t order, const cs_dl *A, cs_long_t qr) ; cs_dl *cs_dl_symperm (const cs_dl *A, const cs_long_t *pinv, cs_long_t values) ; cs_long_t cs_dl_usolve (const cs_dl *U, double *x) ; cs_long_t cs_dl_utsolve (const cs_dl *U, double *x) ; cs_long_t cs_dl_updown (cs_dl *L, cs_long_t sigma, const cs_dl *C, const cs_long_t *parent) ; /* utilities */ cs_dls *cs_dl_sfree (cs_dls *S) ; cs_dln *cs_dl_nfree (cs_dln *N) ; cs_dld *cs_dl_dfree (cs_dld *D) ; /* --- tertiary CSparse routines -------------------------------------------- */ cs_long_t *cs_dl_counts (const cs_dl *A, const cs_long_t *parent, const cs_long_t *post, cs_long_t ata) ; double cs_dl_cumsum (cs_long_t *p, cs_long_t *c, cs_long_t n) ; cs_long_t cs_dl_dfs (cs_long_t j, cs_dl *G, cs_long_t top, cs_long_t *xi, cs_long_t *pstack, const cs_long_t *pinv) ; cs_long_t *cs_dl_etree (const cs_dl *A, cs_long_t ata) ; cs_long_t cs_dl_fkeep (cs_dl *A, cs_long_t (*fkeep) (cs_long_t, cs_long_t, double, void *), void *other) ; double cs_dl_house (double *x, double *beta, cs_long_t n) ; cs_long_t *cs_dl_maxtrans (const cs_dl *A, cs_long_t seed) ; cs_long_t *cs_dl_post (const cs_long_t *parent, cs_long_t n) ; cs_dld *cs_dl_scc (cs_dl *A) ; cs_long_t cs_dl_scatter (const cs_dl *A, cs_long_t j, double beta, cs_long_t *w, double *x, cs_long_t mark,cs_dl *C, cs_long_t nz) ; cs_long_t cs_dl_tdfs (cs_long_t j, cs_long_t k, cs_long_t *head, const cs_long_t *next, cs_long_t *post, cs_long_t *stack) ; cs_long_t cs_dl_leaf (cs_long_t i, cs_long_t j, const cs_long_t *first, cs_long_t *maxfirst, cs_long_t *prevleaf, cs_long_t *ancestor, cs_long_t *jleaf) ; cs_long_t cs_dl_reach (cs_dl *G, const cs_dl *B, cs_long_t k, cs_long_t *xi, const cs_long_t *pinv) ; cs_long_t cs_dl_spsolve (cs_dl *L, const cs_dl *B, cs_long_t k, cs_long_t *xi, double *x, const cs_long_t *pinv, cs_long_t lo) ; cs_long_t cs_dl_ereach (const cs_dl *A, cs_long_t k, const cs_long_t *parent, cs_long_t *s, cs_long_t *w) ; cs_long_t *cs_dl_randperm (cs_long_t n, cs_long_t seed) ; /* utilities */ cs_dld *cs_dl_dalloc (cs_long_t m, cs_long_t n) ; cs_dl *cs_dl_done (cs_dl *C, void *w, void *x, cs_long_t ok) ; cs_long_t *cs_dl_idone (cs_long_t *p, cs_dl *C, void *w, cs_long_t ok) ; cs_dln *cs_dl_ndone (cs_dln *N, cs_dl *C, void *w, void *x, cs_long_t ok) ; cs_dld *cs_dl_ddone (cs_dld *D, cs_dl *C, void *w, cs_long_t ok) ; /* -------------------------------------------------------------------------- */ /* complex/int version of CXSparse */ /* -------------------------------------------------------------------------- */ #ifndef NCOMPLEX /* --- primary CSparse routines and data structures ------------------------- */ typedef struct cs_ci_sparse /* matrix in compressed-column or triplet form */ { int nzmax ; /* maximum number of entries */ int m ; /* number of rows */ int n ; /* number of columns */ int *p ; /* column pointers (size n+1) or col indices (size nzmax) */ int *i ; /* row indices, size nzmax */ cs_complex_t *x ; /* numerical values, size nzmax */ int nz ; /* # of entries in triplet matrix, -1 for compressed-col */ } cs_ci ; cs_ci *cs_ci_add (const cs_ci *A, const cs_ci *B, cs_complex_t alpha, cs_complex_t beta) ; int cs_ci_cholsol (int order, const cs_ci *A, cs_complex_t *b) ; int cs_ci_dupl (cs_ci *A) ; int cs_ci_entry (cs_ci *T, int i, int j, cs_complex_t x) ; int cs_ci_lusol (int order, const cs_ci *A, cs_complex_t *b, double tol) ; int cs_ci_gaxpy (const cs_ci *A, const cs_complex_t *x, cs_complex_t *y) ; cs_ci *cs_ci_multiply (const cs_ci *A, const cs_ci *B) ; int cs_ci_qrsol (int order, const cs_ci *A, cs_complex_t *b) ; cs_ci *cs_ci_transpose (const cs_ci *A, int values) ; cs_ci *cs_ci_compress (const cs_ci *T) ; double cs_ci_norm (const cs_ci *A) ; /*int cs_ci_print (const cs_ci *A, int brief) ;*/ cs_ci *cs_ci_load (FILE *f) ; /* utilities */ void *cs_ci_calloc (int n, size_t size) ; void *cs_ci_free (void *p) ; void *cs_ci_realloc (void *p, int n, size_t size, int *ok) ; cs_ci *cs_ci_spalloc (int m, int n, int nzmax, int values, int t) ; cs_ci *cs_ci_spfree (cs_ci *A) ; int cs_ci_sprealloc (cs_ci *A, int nzmax) ; void *cs_ci_malloc (int n, size_t size) ; /* --- secondary CSparse routines and data structures ----------------------- */ typedef struct cs_ci_symbolic /* symbolic Cholesky, LU, or QR analysis */ { int *pinv ; /* inverse row perm. for QR, fill red. perm for Chol */ int *q ; /* fill-reducing column permutation for LU and QR */ int *parent ; /* elimination tree for Cholesky and QR */ int *cp ; /* column pointers for Cholesky, row counts for QR */ int *leftmost ; /* leftmost[i] = min(find(A(i,:))), for QR */ int m2 ; /* # of rows for QR, after adding fictitious rows */ double lnz ; /* # entries in L for LU or Cholesky; in V for QR */ double unz ; /* # entries in U for LU; in R for QR */ } cs_cis ; typedef struct cs_ci_numeric /* numeric Cholesky, LU, or QR factorization */ { cs_ci *L ; /* L for LU and Cholesky, V for QR */ cs_ci *U ; /* U for LU, r for QR, not used for Cholesky */ int *pinv ; /* partial pivoting for LU */ double *B ; /* beta [0..n-1] for QR */ } cs_cin ; typedef struct cs_ci_dmperm_results /* cs_ci_dmperm or cs_ci_scc output */ { int *p ; /* size m, row permutation */ int *q ; /* size n, column permutation */ int *r ; /* size nb+1, block k is rows r[k] to r[k+1]-1 in A(p,q) */ int *s ; /* size nb+1, block k is cols s[k] to s[k+1]-1 in A(p,q) */ int nb ; /* # of blocks in fine dmperm decomposition */ int rr [5] ; /* coarse row decomposition */ int cc [5] ; /* coarse column decomposition */ } cs_cid ; int *cs_ci_amd (int order, const cs_ci *A) ; cs_cin *cs_ci_chol (const cs_ci *A, const cs_cis *S) ; cs_cid *cs_ci_dmperm (const cs_ci *A, int seed) ; int cs_ci_droptol (cs_ci *A, double tol) ; int cs_ci_dropzeros (cs_ci *A) ; int cs_ci_happly (const cs_ci *V, int i, double beta, cs_complex_t *x) ; int cs_ci_ipvec (const int *p, const cs_complex_t *b, cs_complex_t *x, int n) ; int cs_ci_lsolve (const cs_ci *L, cs_complex_t *x) ; int cs_ci_ltsolve (const cs_ci *L, cs_complex_t *x) ; cs_cin *cs_ci_lu (const cs_ci *A, const cs_cis *S, double tol) ; cs_ci *cs_ci_permute (const cs_ci *A, const int *pinv, const int *q, int values) ; int *cs_ci_pinv (const int *p, int n) ; int cs_ci_pvec (const int *p, const cs_complex_t *b, cs_complex_t *x, int n) ; cs_cin *cs_ci_qr (const cs_ci *A, const cs_cis *S) ; cs_cis *cs_ci_schol (int order, const cs_ci *A) ; cs_cis *cs_ci_sqr (int order, const cs_ci *A, int qr) ; cs_ci *cs_ci_symperm (const cs_ci *A, const int *pinv, int values) ; int cs_ci_usolve (const cs_ci *U, cs_complex_t *x) ; int cs_ci_utsolve (const cs_ci *U, cs_complex_t *x) ; int cs_ci_updown (cs_ci *L, int sigma, const cs_ci *C, const int *parent) ; /* utilities */ cs_cis *cs_ci_sfree (cs_cis *S) ; cs_cin *cs_ci_nfree (cs_cin *N) ; cs_cid *cs_ci_dfree (cs_cid *D) ; /* --- tertiary CSparse routines -------------------------------------------- */ int *cs_ci_counts (const cs_ci *A, const int *parent, const int *post, int ata) ; double cs_ci_cumsum (int *p, int *c, int n) ; int cs_ci_dfs (int j, cs_ci *G, int top, int *xi, int *pstack, const int *pinv) ; int *cs_ci_etree (const cs_ci *A, int ata) ; int cs_ci_fkeep (cs_ci *A, int (*fkeep) (int, int, cs_complex_t, void *), void *other) ; cs_complex_t cs_ci_house (cs_complex_t *x, double *beta, int n) ; int *cs_ci_maxtrans (const cs_ci *A, int seed) ; int *cs_ci_post (const int *parent, int n) ; cs_cid *cs_ci_scc (cs_ci *A) ; int cs_ci_scatter (const cs_ci *A, int j, cs_complex_t beta, int *w, cs_complex_t *x, int mark,cs_ci *C, int nz) ; int cs_ci_tdfs (int j, int k, int *head, const int *next, int *post, int *stack) ; int cs_ci_leaf (int i, int j, const int *first, int *maxfirst, int *prevleaf, int *ancestor, int *jleaf) ; int cs_ci_reach (cs_ci *G, const cs_ci *B, int k, int *xi, const int *pinv) ; int cs_ci_spsolve (cs_ci *L, const cs_ci *B, int k, int *xi, cs_complex_t *x, const int *pinv, int lo) ; int cs_ci_ereach (const cs_ci *A, int k, const int *parent, int *s, int *w) ; int *cs_ci_randperm (int n, int seed) ; /* utilities */ cs_cid *cs_ci_dalloc (int m, int n) ; cs_ci *cs_ci_done (cs_ci *C, void *w, void *x, int ok) ; int *cs_ci_idone (int *p, cs_ci *C, void *w, int ok) ; cs_cin *cs_ci_ndone (cs_cin *N, cs_ci *C, void *w, void *x, int ok) ; cs_cid *cs_ci_ddone (cs_cid *D, cs_ci *C, void *w, int ok) ; /* -------------------------------------------------------------------------- */ /* complex/cs_long_t version of CXSparse */ /* -------------------------------------------------------------------------- */ /* --- primary CSparse routines and data structures ------------------------- */ typedef struct cs_cl_sparse /* matrix in compressed-column or triplet form */ { cs_long_t nzmax ; /* maximum number of entries */ cs_long_t m ; /* number of rows */ cs_long_t n ; /* number of columns */ cs_long_t *p ; /* column pointers (size n+1) or col indlces (size nzmax) */ cs_long_t *i ; /* row indices, size nzmax */ cs_complex_t *x ; /* numerical values, size nzmax */ cs_long_t nz ; /* # of entries in triplet matrix, -1 for compressed-col */ } cs_cl ; cs_cl *cs_cl_add (const cs_cl *A, const cs_cl *B, cs_complex_t alpha, cs_complex_t beta) ; cs_long_t cs_cl_cholsol (cs_long_t order, const cs_cl *A, cs_complex_t *b) ; cs_long_t cs_cl_dupl (cs_cl *A) ; cs_long_t cs_cl_entry (cs_cl *T, cs_long_t i, cs_long_t j, cs_complex_t x) ; cs_long_t cs_cl_lusol (cs_long_t order, const cs_cl *A, cs_complex_t *b, double tol) ; cs_long_t cs_cl_gaxpy (const cs_cl *A, const cs_complex_t *x, cs_complex_t *y) ; cs_cl *cs_cl_multiply (const cs_cl *A, const cs_cl *B) ; cs_long_t cs_cl_qrsol (cs_long_t order, const cs_cl *A, cs_complex_t *b) ; cs_cl *cs_cl_transpose (const cs_cl *A, cs_long_t values) ; cs_cl *cs_cl_compress (const cs_cl *T) ; double cs_cl_norm (const cs_cl *A) ; /*cs_long_t cs_cl_print (const cs_cl *A, cs_long_t brief) ;*/ cs_cl *cs_cl_load (FILE *f) ; /* utilities */ void *cs_cl_calloc (cs_long_t n, size_t size) ; void *cs_cl_free (void *p) ; void *cs_cl_realloc (void *p, cs_long_t n, size_t size, cs_long_t *ok) ; cs_cl *cs_cl_spalloc (cs_long_t m, cs_long_t n, cs_long_t nzmax, cs_long_t values, cs_long_t t) ; cs_cl *cs_cl_spfree (cs_cl *A) ; cs_long_t cs_cl_sprealloc (cs_cl *A, cs_long_t nzmax) ; void *cs_cl_malloc (cs_long_t n, size_t size) ; /* --- secondary CSparse routines and data structures ----------------------- */ typedef struct cs_cl_symbolic /* symbolic Cholesky, LU, or QR analysis */ { cs_long_t *pinv ; /* inverse row perm. for QR, fill red. perm for Chol */ cs_long_t *q ; /* fill-reducing column permutation for LU and QR */ cs_long_t *parent ; /* elimination tree for Cholesky and QR */ cs_long_t *cp ; /* column pointers for Cholesky, row counts for QR */ cs_long_t *leftmost ; /* leftmost[i] = min(find(A(i,:))), for QR */ cs_long_t m2 ; /* # of rows for QR, after adding fictitious rows */ double lnz ; /* # entries in L for LU or Cholesky; in V for QR */ double unz ; /* # entries in U for LU; in R for QR */ } cs_cls ; typedef struct cs_cl_numeric /* numeric Cholesky, LU, or QR factorization */ { cs_cl *L ; /* L for LU and Cholesky, V for QR */ cs_cl *U ; /* U for LU, r for QR, not used for Cholesky */ cs_long_t *pinv ; /* partial pivoting for LU */ double *B ; /* beta [0..n-1] for QR */ } cs_cln ; typedef struct cs_cl_dmperm_results /* cs_cl_dmperm or cs_cl_scc output */ { cs_long_t *p ; /* size m, row permutation */ cs_long_t *q ; /* size n, column permutation */ cs_long_t *r ; /* size nb+1, block k is rows r[k] to r[k+1]-1 in A(p,q) */ cs_long_t *s ; /* size nb+1, block k is cols s[k] to s[k+1]-1 in A(p,q) */ cs_long_t nb ; /* # of blocks in fine dmperm decomposition */ cs_long_t rr [5] ; /* coarse row decomposition */ cs_long_t cc [5] ; /* coarse column decomposition */ } cs_cld ; cs_long_t *cs_cl_amd (cs_long_t order, const cs_cl *A) ; cs_cln *cs_cl_chol (const cs_cl *A, const cs_cls *S) ; cs_cld *cs_cl_dmperm (const cs_cl *A, cs_long_t seed) ; cs_long_t cs_cl_droptol (cs_cl *A, double tol) ; cs_long_t cs_cl_dropzeros (cs_cl *A) ; cs_long_t cs_cl_happly (const cs_cl *V, cs_long_t i, double beta, cs_complex_t *x) ; cs_long_t cs_cl_ipvec (const cs_long_t *p, const cs_complex_t *b, cs_complex_t *x, cs_long_t n) ; cs_long_t cs_cl_lsolve (const cs_cl *L, cs_complex_t *x) ; cs_long_t cs_cl_ltsolve (const cs_cl *L, cs_complex_t *x) ; cs_cln *cs_cl_lu (const cs_cl *A, const cs_cls *S, double tol) ; cs_cl *cs_cl_permute (const cs_cl *A, const cs_long_t *pinv, const cs_long_t *q, cs_long_t values) ; cs_long_t *cs_cl_pinv (const cs_long_t *p, cs_long_t n) ; cs_long_t cs_cl_pvec (const cs_long_t *p, const cs_complex_t *b, cs_complex_t *x, cs_long_t n) ; cs_cln *cs_cl_qr (const cs_cl *A, const cs_cls *S) ; cs_cls *cs_cl_schol (cs_long_t order, const cs_cl *A) ; cs_cls *cs_cl_sqr (cs_long_t order, const cs_cl *A, cs_long_t qr) ; cs_cl *cs_cl_symperm (const cs_cl *A, const cs_long_t *pinv, cs_long_t values) ; cs_long_t cs_cl_usolve (const cs_cl *U, cs_complex_t *x) ; cs_long_t cs_cl_utsolve (const cs_cl *U, cs_complex_t *x) ; cs_long_t cs_cl_updown (cs_cl *L, cs_long_t sigma, const cs_cl *C, const cs_long_t *parent) ; /* utilities */ cs_cls *cs_cl_sfree (cs_cls *S) ; cs_cln *cs_cl_nfree (cs_cln *N) ; cs_cld *cs_cl_dfree (cs_cld *D) ; /* --- tertiary CSparse routines -------------------------------------------- */ cs_long_t *cs_cl_counts (const cs_cl *A, const cs_long_t *parent, const cs_long_t *post, cs_long_t ata) ; double cs_cl_cumsum (cs_long_t *p, cs_long_t *c, cs_long_t n) ; cs_long_t cs_cl_dfs (cs_long_t j, cs_cl *G, cs_long_t top, cs_long_t *xi, cs_long_t *pstack, const cs_long_t *pinv) ; cs_long_t *cs_cl_etree (const cs_cl *A, cs_long_t ata) ; cs_long_t cs_cl_fkeep (cs_cl *A, cs_long_t (*fkeep) (cs_long_t, cs_long_t, cs_complex_t, void *), void *other) ; cs_complex_t cs_cl_house (cs_complex_t *x, double *beta, cs_long_t n) ; cs_long_t *cs_cl_maxtrans (const cs_cl *A, cs_long_t seed) ; cs_long_t *cs_cl_post (const cs_long_t *parent, cs_long_t n) ; cs_cld *cs_cl_scc (cs_cl *A) ; cs_long_t cs_cl_scatter (const cs_cl *A, cs_long_t j, cs_complex_t beta, cs_long_t *w, cs_complex_t *x, cs_long_t mark,cs_cl *C, cs_long_t nz) ; cs_long_t cs_cl_tdfs (cs_long_t j, cs_long_t k, cs_long_t *head, const cs_long_t *next, cs_long_t *post, cs_long_t *stack) ; cs_long_t cs_cl_leaf (cs_long_t i, cs_long_t j, const cs_long_t *first, cs_long_t *maxfirst, cs_long_t *prevleaf, cs_long_t *ancestor, cs_long_t *jleaf) ; cs_long_t cs_cl_reach (cs_cl *G, const cs_cl *B, cs_long_t k, cs_long_t *xi, const cs_long_t *pinv) ; cs_long_t cs_cl_spsolve (cs_cl *L, const cs_cl *B, cs_long_t k, cs_long_t *xi, cs_complex_t *x, const cs_long_t *pinv, cs_long_t lo) ; cs_long_t cs_cl_ereach (const cs_cl *A, cs_long_t k, const cs_long_t *parent, cs_long_t *s, cs_long_t *w) ; cs_long_t *cs_cl_randperm (cs_long_t n, cs_long_t seed) ; /* utilities */ cs_cld *cs_cl_dalloc (cs_long_t m, cs_long_t n) ; cs_cl *cs_cl_done (cs_cl *C, void *w, void *x, cs_long_t ok) ; cs_long_t *cs_cl_idone (cs_long_t *p, cs_cl *C, void *w, cs_long_t ok) ; cs_cln *cs_cl_ndone (cs_cln *N, cs_cl *C, void *w, void *x, cs_long_t ok) ; cs_cld *cs_cl_ddone (cs_cld *D, cs_cl *C, void *w, cs_long_t ok) ; #endif /* -------------------------------------------------------------------------- */ /* Macros for constructing each version of CSparse */ /* -------------------------------------------------------------------------- */ #ifdef CS_LONG #define CS_INT cs_long_t #define CS_INT_MAX cs_long_t_max #define CS_ID cs_long_t_id #ifdef CS_COMPLEX #define CS_ENTRY cs_complex_t #define CS_NAME(nm) cs_cl ## nm #define cs cs_cl #else #define CS_ENTRY double #define CS_NAME(nm) cs_dl ## nm #define cs cs_dl #endif #else #define CS_INT int #define CS_INT_MAX INT_MAX #define CS_ID "%d" #ifdef CS_COMPLEX #define CS_ENTRY cs_complex_t #define CS_NAME(nm) cs_ci ## nm #define cs cs_ci #else #define CS_ENTRY double #define CS_NAME(nm) cs_di ## nm #define cs cs_di #endif #endif #ifdef CS_COMPLEX #define CS_REAL(x) creal(x) #define CS_IMAG(x) cimag(x) #define CS_CONJ(x) conj(x) #define CS_ABS(x) cabs(x) #else #define CS_REAL(x) (x) #define CS_IMAG(x) (0.) #define CS_CONJ(x) (x) #define CS_ABS(x) fabs(x) #endif #define CS_MAX(a,b) (((a) > (b)) ? (a) : (b)) #define CS_MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CS_FLIP(i) (-(i)-2) #define CS_UNFLIP(i) (((i) < 0) ? CS_FLIP(i) : (i)) #define CS_MARKED(w,j) (w [j] < 0) #define CS_MARK(w,j) { w [j] = CS_FLIP (w [j]) ; } #define CS_CSC(A) (A && (A->nz == -1)) #define CS_TRIPLET(A) (A && (A->nz >= 0)) /* --- primary CSparse routines and data structures ------------------------- */ #define cs_add CS_NAME (_add) #define cs_cholsol CS_NAME (_cholsol) #define cs_dupl CS_NAME (_dupl) #define cs_entry CS_NAME (_entry) #define cs_lusol CS_NAME (_lusol) #define cs_gaxpy CS_NAME (_gaxpy) #define cs_multiply CS_NAME (_multiply) #define cs_qrsol CS_NAME (_qrsol) #define cs_transpose CS_NAME (_transpose) #define cs_compress CS_NAME (_compress) #define cs_norm CS_NAME (_norm) /*#define cs_print CS_NAME (_print)*/ #define cs_load CS_NAME (_load) /* utilities */ #define cs_calloc CS_NAME (_calloc) #define cs_free CS_NAME (_free) #define cs_realloc CS_NAME (_realloc) #define cs_spalloc CS_NAME (_spalloc) #define cs_spfree CS_NAME (_spfree) #define cs_sprealloc CS_NAME (_sprealloc) #define cs_malloc CS_NAME (_malloc) /* --- secondary CSparse routines and data structures ----------------------- */ #define css CS_NAME (s) #define csn CS_NAME (n) #define csd CS_NAME (d) #define cs_amd CS_NAME (_amd) #define cs_chol CS_NAME (_chol) #define cs_dmperm CS_NAME (_dmperm) #define cs_droptol CS_NAME (_droptol) #define cs_dropzeros CS_NAME (_dropzeros) #define cs_happly CS_NAME (_happly) #define cs_ipvec CS_NAME (_ipvec) #define cs_lsolve CS_NAME (_lsolve) #define cs_ltsolve CS_NAME (_ltsolve) #define cs_lu CS_NAME (_lu) #define cs_permute CS_NAME (_permute) #define cs_pinv CS_NAME (_pinv) #define cs_pvec CS_NAME (_pvec) #define cs_qr CS_NAME (_qr) #define cs_schol CS_NAME (_schol) #define cs_sqr CS_NAME (_sqr) #define cs_symperm CS_NAME (_symperm) #define cs_usolve CS_NAME (_usolve) #define cs_utsolve CS_NAME (_utsolve) #define cs_updown CS_NAME (_updown) /* utilities */ #define cs_sfree CS_NAME (_sfree) #define cs_nfree CS_NAME (_nfree) #define cs_dfree CS_NAME (_dfree) /* --- tertiary CSparse routines -------------------------------------------- */ #define cs_counts CS_NAME (_counts) #define cs_cumsum CS_NAME (_cumsum) #define cs_dfs CS_NAME (_dfs) #define cs_etree CS_NAME (_etree) #define cs_fkeep CS_NAME (_fkeep) #define cs_house CS_NAME (_house) #define cs_invmatch CS_NAME (_invmatch) #define cs_maxtrans CS_NAME (_maxtrans) #define cs_post CS_NAME (_post) #define cs_scc CS_NAME (_scc) #define cs_scatter CS_NAME (_scatter) #define cs_tdfs CS_NAME (_tdfs) #define cs_reach CS_NAME (_reach) #define cs_spsolve CS_NAME (_spsolve) #define cs_ereach CS_NAME (_ereach) #define cs_randperm CS_NAME (_randperm) #define cs_leaf CS_NAME (_leaf) /* utilities */ #define cs_dalloc CS_NAME (_dalloc) #define cs_done CS_NAME (_done) #define cs_idone CS_NAME (_idone) #define cs_ndone CS_NAME (_ndone) #define cs_ddone CS_NAME (_ddone) /* -------------------------------------------------------------------------- */ /* Conversion routines */ /* -------------------------------------------------------------------------- */ #ifndef NCOMPLEX cs_di *cs_i_real (cs_ci *A, int real) ; cs_ci *cs_i_complex (cs_di *A, int real) ; cs_dl *cs_l_real (cs_cl *A, cs_long_t real) ; cs_cl *cs_l_complex (cs_dl *A, cs_long_t real) ; #endif #ifdef __cplusplus } #endif #endif leidenbase/src/vendor/cs/cs_pvec.c0000644000176200001440000000051314447675375016651 0ustar liggesusers#include "cs.h" /* x = b(p), for dense vectors x and b; p=NULL denotes identity */ CS_INT cs_pvec (const CS_INT *p, const CS_ENTRY *b, CS_ENTRY *x, CS_INT n) { CS_INT k ; if (!x || !b) return (0) ; /* check inputs */ for (k = 0 ; k < n ; k++) x [k] = b [p ? p [k] : k] ; return (1) ; } leidenbase/src/vendor/cs/cs_load.c0000644000176200001440000000136314447675375016637 0ustar liggesusers#include "cs.h" /* load a triplet matrix from a file */ cs *cs_load (FILE *f) { double i, j ; /* use double for integers to avoid csi conflicts */ double x ; #ifdef CS_COMPLEX double xi ; #endif cs *T ; if (!f) return (NULL) ; /* check inputs */ T = cs_spalloc (0, 0, 1, 1, 1) ; /* allocate result */ #ifdef CS_COMPLEX while (fscanf (f, "%lg %lg %lg %lg\n", &i, &j, &x, &xi) == 4) #else while (fscanf (f, "%lg %lg %lg\n", &i, &j, &x) == 3) #endif { #ifdef CS_COMPLEX if (!cs_entry (T, (CS_INT) i, (CS_INT) j, x + xi*I)) return (cs_spfree (T)) ; #else if (!cs_entry (T, (CS_INT) i, (CS_INT) j, x)) return (cs_spfree (T)) ; #endif } return (T) ; } leidenbase/src/vendor/cs/cs_etree.c0000644000176200001440000000253714447675375017030 0ustar liggesusers#include "cs.h" /* compute the etree of A (using triu(A), or A'A without forming A'A */ CS_INT *cs_etree (const cs *A, CS_INT ata) { CS_INT i, k, p, m, n, inext, *Ap, *Ai, *w, *parent, *ancestor, *prev ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; parent = cs_malloc (n, sizeof (CS_INT)) ; /* allocate result */ w = cs_malloc (n + (ata ? m : 0), sizeof (CS_INT)) ; /* get workspace */ if (!w || !parent) return (cs_idone (parent, NULL, w, 0)) ; ancestor = w ; prev = w + n ; if (ata) for (i = 0 ; i < m ; i++) prev [i] = -1 ; for (k = 0 ; k < n ; k++) { parent [k] = -1 ; /* node k has no parent yet */ ancestor [k] = -1 ; /* nor does k have an ancestor */ for (p = Ap [k] ; p < Ap [k+1] ; p++) { i = ata ? (prev [Ai [p]]) : (Ai [p]) ; for ( ; i != -1 && i < k ; i = inext) /* traverse from i to k */ { inext = ancestor [i] ; /* inext = ancestor of i */ ancestor [i] = k ; /* path compression */ if (inext == -1) parent [i] = k ; /* no anc., parent is k */ } if (ata) prev [Ai [p]] = k ; } } return (cs_idone (parent, NULL, w, 1)) ; } leidenbase/src/vendor/cs/cs_norm.c0000644000176200001440000000073714447675375016677 0ustar liggesusers#include "cs.h" /* 1-norm of a sparse matrix = max (sum (abs (A))), largest column sum */ double cs_norm (const cs *A) { CS_INT p, j, n, *Ap ; CS_ENTRY *Ax ; double norm = 0, s ; if (!CS_CSC (A) || !A->x) return (-1) ; /* check inputs */ n = A->n ; Ap = A->p ; Ax = A->x ; for (j = 0 ; j < n ; j++) { for (s = 0, p = Ap [j] ; p < Ap [j+1] ; p++) s += CS_ABS (Ax [p]) ; norm = CS_MAX (norm, s) ; } return (norm) ; } leidenbase/src/vendor/cs/cs_dropzeros.c0000644000176200001440000000034514447675375017746 0ustar liggesusers#include "cs.h" static CS_INT cs_nonzero (CS_INT i, CS_INT j, CS_ENTRY aij, void *other) { return (aij != 0) ; } CS_INT cs_dropzeros (cs *A) { return (cs_fkeep (A, &cs_nonzero, NULL)) ; /* keep all nonzero entries */ } leidenbase/src/vendor/cs/cs_ltsolve.c0000644000176200001440000000104314447675375017403 0ustar liggesusers#include "cs.h" /* solve L'x=b where x and b are dense. x=b on input, solution on output. */ CS_INT cs_ltsolve (const cs *L, CS_ENTRY *x) { CS_INT p, j, n, *Lp, *Li ; CS_ENTRY *Lx ; if (!CS_CSC (L) || !x) return (0) ; /* check inputs */ n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; for (j = n-1 ; j >= 0 ; j--) { for (p = Lp [j]+1 ; p < Lp [j+1] ; p++) { x [j] -= CS_CONJ (Lx [p]) * x [Li [p]] ; } x [j] /= CS_CONJ (Lx [Lp [j]]) ; } return (1) ; } leidenbase/src/vendor/cs/cs_lsolve.c0000644000176200001440000000101214447675375017213 0ustar liggesusers#include "cs.h" /* solve Lx=b where x and b are dense. x=b on input, solution on output. */ CS_INT cs_lsolve (const cs *L, CS_ENTRY *x) { CS_INT p, j, n, *Lp, *Li ; CS_ENTRY *Lx ; if (!CS_CSC (L) || !x) return (0) ; /* check inputs */ n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; for (j = 0 ; j < n ; j++) { x [j] /= Lx [Lp [j]] ; for (p = Lp [j]+1 ; p < Lp [j+1] ; p++) { x [Li [p]] -= Lx [p] * x [j] ; } } return (1) ; } leidenbase/src/vendor/cs/cs_compress.c0000644000176200001440000000175514447675375017560 0ustar liggesusers#include "cs.h" /* C = compressed-column form of a triplet matrix T */ cs *cs_compress (const cs *T) { CS_INT m, n, nz, p, k, *Cp, *Ci, *w, *Ti, *Tj ; CS_ENTRY *Cx, *Tx ; cs *C ; if (!CS_TRIPLET (T)) return (NULL) ; /* check inputs */ m = T->m ; n = T->n ; Ti = T->i ; Tj = T->p ; Tx = T->x ; nz = T->nz ; C = cs_spalloc (m, n, nz, Tx != NULL, 0) ; /* allocate result */ w = cs_calloc (n, sizeof (CS_INT)) ; /* get workspace */ if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ Cp = C->p ; Ci = C->i ; Cx = C->x ; for (k = 0 ; k < nz ; k++) w [Tj [k]]++ ; /* column counts */ cs_cumsum (Cp, w, n) ; /* column pointers */ for (k = 0 ; k < nz ; k++) { Ci [p = w [Tj [k]]++] = Ti [k] ; /* A(i,j) is the pth entry in C */ if (Cx) Cx [p] = Tx [k] ; } return (cs_done (C, w, NULL, 1)) ; /* success; free w and return C */ } leidenbase/src/vendor/cs/cs_amd.c0000644000176200001440000004020214447675375016454 0ustar liggesusers#include "cs.h" /* clear w */ static CS_INT cs_wclear (CS_INT mark, CS_INT lemax, CS_INT *w, CS_INT n) { CS_INT k ; if (mark < 2 || (mark + lemax < 0)) { for (k = 0 ; k < n ; k++) if (w [k] != 0) w [k] = 1 ; mark = 2 ; } return (mark) ; /* at this point, w [0..n-1] < mark holds */ } /* keep off-diagonal entries; drop diagonal entries */ static CS_INT cs_diag (CS_INT i, CS_INT j, CS_ENTRY aij, void *other) { return (i != j) ; } /* p = amd(A+A') if symmetric is true, or amd(A'A) otherwise */ CS_INT *cs_amd (CS_INT order, const cs *A) /* order 0:natural, 1:Chol, 2:LU, 3:QR */ { cs *C, *A2, *AT ; CS_INT *Cp, *Ci, *last, *W, *len, *nv, *next, *P, *head, *elen, *degree, *w, *hhead, *ATp, *ATi, d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1, k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi, ok, cnz, nel = 0, p, p1, p2, p3, p4, pj, pk, pk1, pk2, pn, q, n, m, t ; CS_INT h ; /* --- Construct matrix C ----------------------------------------------- */ if (!CS_CSC (A) || order <= 0 || order > 3) return (NULL) ; /* check */ AT = cs_transpose (A, 0) ; /* compute A' */ if (!AT) return (NULL) ; m = A->m ; n = A->n ; dense = CS_MAX (16, 10 * sqrt ((double) n)) ; /* find dense threshold */ dense = CS_MIN (n-2, dense) ; if (order == 1 && n == m) { C = cs_add (A, AT, 0, 0) ; /* C = A+A' */ } else if (order == 2) { ATp = AT->p ; /* drop dense columns from AT */ ATi = AT->i ; for (p2 = 0, j = 0 ; j < m ; j++) { p = ATp [j] ; /* column j of AT starts here */ ATp [j] = p2 ; /* new column j starts here */ if (ATp [j+1] - p > dense) continue ; /* skip dense col j */ for ( ; p < ATp [j+1] ; p++) ATi [p2++] = ATi [p] ; } ATp [m] = p2 ; /* finalize AT */ A2 = cs_transpose (AT, 0) ; /* A2 = AT' */ C = A2 ? cs_multiply (AT, A2) : NULL ; /* C=A'*A with no dense rows */ cs_spfree (A2) ; } else { C = cs_multiply (AT, A) ; /* C=A'*A */ } cs_spfree (AT) ; if (!C) return (NULL) ; cs_fkeep (C, &cs_diag, NULL) ; /* drop diagonal entries */ Cp = C->p ; cnz = Cp [n] ; P = cs_malloc (n+1, sizeof (CS_INT)) ; /* allocate result */ W = cs_malloc (8*(n+1), sizeof (CS_INT)) ; /* get workspace */ t = cnz + cnz/5 + 2*n ; /* add elbow room to C */ if (!P || !W || !cs_sprealloc (C, t)) return (cs_idone (P, C, W, 0)) ; len = W ; nv = W + (n+1) ; next = W + 2*(n+1) ; head = W + 3*(n+1) ; elen = W + 4*(n+1) ; degree = W + 5*(n+1) ; w = W + 6*(n+1) ; hhead = W + 7*(n+1) ; last = P ; /* use P as workspace for last */ /* --- Initialize quotient graph ---------------------------------------- */ for (k = 0 ; k < n ; k++) len [k] = Cp [k+1] - Cp [k] ; len [n] = 0 ; nzmax = C->nzmax ; Ci = C->i ; for (i = 0 ; i <= n ; i++) { head [i] = -1 ; /* degree list i is empty */ last [i] = -1 ; next [i] = -1 ; hhead [i] = -1 ; /* hash list i is empty */ nv [i] = 1 ; /* node i is just one node */ w [i] = 1 ; /* node i is alive */ elen [i] = 0 ; /* Ek of node i is empty */ degree [i] = len [i] ; /* degree of node i */ } mark = cs_wclear (0, 0, w, n) ; /* clear w */ elen [n] = -2 ; /* n is a dead element */ Cp [n] = -1 ; /* n is a root of assembly tree */ w [n] = 0 ; /* n is a dead element */ /* --- Initialize degree lists ------------------------------------------ */ for (i = 0 ; i < n ; i++) { d = degree [i] ; if (d == 0) /* node i is empty */ { elen [i] = -2 ; /* element i is dead */ nel++ ; Cp [i] = -1 ; /* i is a root of assembly tree */ w [i] = 0 ; } else if (d > dense) /* node i is dense */ { nv [i] = 0 ; /* absorb i into element n */ elen [i] = -1 ; /* node i is dead */ nel++ ; Cp [i] = CS_FLIP (n) ; nv [n]++ ; } else { if (head [d] != -1) last [head [d]] = i ; next [i] = head [d] ; /* put node i in degree list d */ head [d] = i ; } } while (nel < n) /* while (selecting pivots) do */ { /* --- Select node of minimum approximate degree -------------------- */ for (k = -1 ; mindeg < n && (k = head [mindeg]) == -1 ; mindeg++) ; if (next [k] != -1) last [next [k]] = -1 ; head [mindeg] = next [k] ; /* remove k from degree list */ elenk = elen [k] ; /* elenk = |Ek| */ nvk = nv [k] ; /* # of nodes k represents */ nel += nvk ; /* nv[k] nodes of A eliminated */ /* --- Garbage collection ------------------------------------------- */ if (elenk > 0 && cnz + mindeg >= nzmax) { for (j = 0 ; j < n ; j++) { if ((p = Cp [j]) >= 0) /* j is a live node or element */ { Cp [j] = Ci [p] ; /* save first entry of object */ Ci [p] = CS_FLIP (j) ; /* first entry is now CS_FLIP(j) */ } } for (q = 0, p = 0 ; p < cnz ; ) /* scan all of memory */ { if ((j = CS_FLIP (Ci [p++])) >= 0) /* found object j */ { Ci [q] = Cp [j] ; /* restore first entry of object */ Cp [j] = q++ ; /* new pointer to object j */ for (k3 = 0 ; k3 < len [j]-1 ; k3++) Ci [q++] = Ci [p++] ; } } cnz = q ; /* Ci [cnz...nzmax-1] now free */ } /* --- Construct new element ---------------------------------------- */ dk = 0 ; nv [k] = -nvk ; /* flag k as in Lk */ p = Cp [k] ; pk1 = (elenk == 0) ? p : cnz ; /* do in place if elen[k] == 0 */ pk2 = pk1 ; for (k1 = 1 ; k1 <= elenk + 1 ; k1++) { if (k1 > elenk) { e = k ; /* search the nodes in k */ pj = p ; /* list of nodes starts at Ci[pj]*/ ln = len [k] - elenk ; /* length of list of nodes in k */ } else { e = Ci [p++] ; /* search the nodes in e */ pj = Cp [e] ; ln = len [e] ; /* length of list of nodes in e */ } for (k2 = 1 ; k2 <= ln ; k2++) { i = Ci [pj++] ; if ((nvi = nv [i]) <= 0) continue ; /* node i dead, or seen */ dk += nvi ; /* degree[Lk] += size of node i */ nv [i] = -nvi ; /* negate nv[i] to denote i in Lk*/ Ci [pk2++] = i ; /* place i in Lk */ if (next [i] != -1) last [next [i]] = last [i] ; if (last [i] != -1) /* remove i from degree list */ { next [last [i]] = next [i] ; } else { head [degree [i]] = next [i] ; } } if (e != k) { Cp [e] = CS_FLIP (k) ; /* absorb e into k */ w [e] = 0 ; /* e is now a dead element */ } } if (elenk != 0) cnz = pk2 ; /* Ci [cnz...nzmax] is free */ degree [k] = dk ; /* external degree of k - |Lk\i| */ Cp [k] = pk1 ; /* element k is in Ci[pk1..pk2-1] */ len [k] = pk2 - pk1 ; elen [k] = -2 ; /* k is now an element */ /* --- Find set differences ----------------------------------------- */ mark = cs_wclear (mark, lemax, w, n) ; /* clear w if necessary */ for (pk = pk1 ; pk < pk2 ; pk++) /* scan 1: find |Le\Lk| */ { i = Ci [pk] ; if ((eln = elen [i]) <= 0) continue ;/* skip if elen[i] empty */ nvi = -nv [i] ; /* nv [i] was negated */ wnvi = mark - nvi ; for (p = Cp [i] ; p <= Cp [i] + eln - 1 ; p++) /* scan Ei */ { e = Ci [p] ; if (w [e] >= mark) { w [e] -= nvi ; /* decrement |Le\Lk| */ } else if (w [e] != 0) /* ensure e is a live element */ { w [e] = degree [e] + wnvi ; /* 1st time e seen in scan 1 */ } } } /* --- Degree update ------------------------------------------------ */ for (pk = pk1 ; pk < pk2 ; pk++) /* scan2: degree update */ { i = Ci [pk] ; /* consider node i in Lk */ p1 = Cp [i] ; p2 = p1 + elen [i] - 1 ; pn = p1 ; for (h = 0, d = 0, p = p1 ; p <= p2 ; p++) /* scan Ei */ { e = Ci [p] ; if (w [e] != 0) /* e is an unabsorbed element */ { dext = w [e] - mark ; /* dext = |Le\Lk| */ if (dext > 0) { d += dext ; /* sum up the set differences */ Ci [pn++] = e ; /* keep e in Ei */ h += e ; /* compute the hash of node i */ } else { Cp [e] = CS_FLIP (k) ; /* aggressive absorb. e->k */ w [e] = 0 ; /* e is a dead element */ } } } elen [i] = pn - p1 + 1 ; /* elen[i] = |Ei| */ p3 = pn ; p4 = p1 + len [i] ; for (p = p2 + 1 ; p < p4 ; p++) /* prune edges in Ai */ { j = Ci [p] ; if ((nvj = nv [j]) <= 0) continue ; /* node j dead or in Lk */ d += nvj ; /* degree(i) += |j| */ Ci [pn++] = j ; /* place j in node list of i */ h += j ; /* compute hash for node i */ } if (d == 0) /* check for mass elimination */ { Cp [i] = CS_FLIP (k) ; /* absorb i into k */ nvi = -nv [i] ; dk -= nvi ; /* |Lk| -= |i| */ nvk += nvi ; /* |k| += nv[i] */ nel += nvi ; nv [i] = 0 ; elen [i] = -1 ; /* node i is dead */ } else { degree [i] = CS_MIN (degree [i], d) ; /* update degree(i) */ Ci [pn] = Ci [p3] ; /* move first node to end */ Ci [p3] = Ci [p1] ; /* move 1st el. to end of Ei */ Ci [p1] = k ; /* add k as 1st element in of Ei */ len [i] = pn - p1 + 1 ; /* new len of adj. list of node i */ h = ((h<0) ? (-h):h) % n ; /* finalize hash of i */ next [i] = hhead [h] ; /* place i in hash bucket */ hhead [h] = i ; last [i] = h ; /* save hash of i in last[i] */ } } /* scan2 is done */ degree [k] = dk ; /* finalize |Lk| */ lemax = CS_MAX (lemax, dk) ; mark = cs_wclear (mark+lemax, lemax, w, n) ; /* clear w */ /* --- Supernode detection ------------------------------------------ */ for (pk = pk1 ; pk < pk2 ; pk++) { i = Ci [pk] ; if (nv [i] >= 0) continue ; /* skip if i is dead */ h = last [i] ; /* scan hash bucket of node i */ i = hhead [h] ; hhead [h] = -1 ; /* hash bucket will be empty */ for ( ; i != -1 && next [i] != -1 ; i = next [i], mark++) { ln = len [i] ; eln = elen [i] ; for (p = Cp [i]+1 ; p <= Cp [i] + ln-1 ; p++) w [Ci [p]] = mark; jlast = i ; for (j = next [i] ; j != -1 ; ) /* compare i with all j */ { ok = (len [j] == ln) && (elen [j] == eln) ; for (p = Cp [j] + 1 ; ok && p <= Cp [j] + ln - 1 ; p++) { if (w [Ci [p]] != mark) ok = 0 ; /* compare i and j*/ } if (ok) /* i and j are identical */ { Cp [j] = CS_FLIP (i) ; /* absorb j into i */ nv [i] += nv [j] ; nv [j] = 0 ; elen [j] = -1 ; /* node j is dead */ j = next [j] ; /* delete j from hash bucket */ next [jlast] = j ; } else { jlast = j ; /* j and i are different */ j = next [j] ; } } } } /* --- Finalize new element------------------------------------------ */ for (p = pk1, pk = pk1 ; pk < pk2 ; pk++) /* finalize Lk */ { i = Ci [pk] ; if ((nvi = -nv [i]) <= 0) continue ;/* skip if i is dead */ nv [i] = nvi ; /* restore nv[i] */ d = degree [i] + dk - nvi ; /* compute external degree(i) */ d = CS_MIN (d, n - nel - nvi) ; if (head [d] != -1) last [head [d]] = i ; next [i] = head [d] ; /* put i back in degree list */ last [i] = -1 ; head [d] = i ; mindeg = CS_MIN (mindeg, d) ; /* find new minimum degree */ degree [i] = d ; Ci [p++] = i ; /* place i in Lk */ } nv [k] = nvk ; /* # nodes absorbed into k */ if ((len [k] = p-pk1) == 0) /* length of adj list of element k*/ { Cp [k] = -1 ; /* k is a root of the tree */ w [k] = 0 ; /* k is now a dead element */ } if (elenk != 0) cnz = p ; /* free unused space in Lk */ } /* --- Postordering ----------------------------------------------------- */ for (i = 0 ; i < n ; i++) Cp [i] = CS_FLIP (Cp [i]) ;/* fix assembly tree */ for (j = 0 ; j <= n ; j++) head [j] = -1 ; for (j = n ; j >= 0 ; j--) /* place unordered nodes in lists */ { if (nv [j] > 0) continue ; /* skip if j is an element */ next [j] = head [Cp [j]] ; /* place j in list of its parent */ head [Cp [j]] = j ; } for (e = n ; e >= 0 ; e--) /* place elements in lists */ { if (nv [e] <= 0) continue ; /* skip unless e is an element */ if (Cp [e] != -1) { next [e] = head [Cp [e]] ; /* place e in list of its parent */ head [Cp [e]] = e ; } } for (k = 0, i = 0 ; i <= n ; i++) /* postorder the assembly tree */ { if (Cp [i] == -1) k = cs_tdfs (i, k, head, next, P, w) ; } return (cs_idone (P, C, W, 1)) ; } leidenbase/src/vendor/cs/cs_randperm.c0000644000176200001440000000177214447675375017534 0ustar liggesusers#include "cs.h" #include "igraph_random.h" /* return a random permutation vector, the identity perm, or p = n-1:-1:0. * seed = -1 means p = n-1:-1:0. seed = 0 means p = identity. otherwise * p = random permutation. */ CS_INT *cs_randperm (CS_INT n, CS_INT seed) { CS_INT *p, k, j, t ; if (seed == 0) return (NULL) ; /* return p = NULL (identity) */ p = cs_malloc (n, sizeof (CS_INT)) ; /* allocate result */ if (!p) return (NULL) ; /* out of memory */ for (k = 0 ; k < n ; k++) p [k] = n-k-1 ; if (seed == -1) return (p) ; /* return reverse permutation */ /* srand (seed) ; /\* get new random number seed *\/ */ RNG_BEGIN(); for (k = 0 ; k < n ; k++) { /* j = k + (rand ( ) % (n-k)) ; /\* j = rand CS_INT in range k to n-1 *\/ */ j = RNG_INTEGER(k, n-1) ; t = p [j] ; /* swap p[k] and p[j] */ p [j] = p [k] ; p [k] = t ; } RNG_END(); return (p) ; } leidenbase/src/vendor/cs/cs_cumsum.c0000644000176200001440000000110314447675375017221 0ustar liggesusers#include "cs.h" /* p [0..n] = cumulative sum of c [0..n-1], and then copy p [0..n-1] into c */ double cs_cumsum (CS_INT *p, CS_INT *c, CS_INT n) { CS_INT i, nz = 0 ; double nz2 = 0 ; if (!p || !c) return (-1) ; /* check inputs */ for (i = 0 ; i < n ; i++) { p [i] = nz ; nz += c [i] ; nz2 += c [i] ; /* also in double to avoid CS_INT overflow */ c [i] = p [i] ; /* also copy p[0..n-1] back into c[0..n-1]*/ } p [n] = nz ; return (nz2) ; /* return sum (c [0..n-1]) */ } leidenbase/src/vendor/cs/cs_tdfs.c0000644000176200001440000000165514447675375016664 0ustar liggesusers#include "cs.h" /* depth-first search and postorder of a tree rooted at node j */ CS_INT cs_tdfs (CS_INT j, CS_INT k, CS_INT *head, const CS_INT *next, CS_INT *post, CS_INT *stack) { CS_INT i, p, top = 0 ; if (!head || !next || !post || !stack) return (-1) ; /* check inputs */ stack [0] = j ; /* place j on the stack */ while (top >= 0) /* while (stack is not empty) */ { p = stack [top] ; /* p = top of stack */ i = head [p] ; /* i = youngest child of p */ if (i == -1) { top-- ; /* p has no unordered children left */ post [k++] = p ; /* node p is the kth postordered node */ } else { head [p] = next [i] ; /* remove i from children of p */ stack [++top] = i ; /* start dfs on child node i */ } } return (k) ; } leidenbase/src/vendor/cs/cs_util.c0000644000176200001440000001014414447675375016672 0ustar liggesusers#include "cs.h" /* allocate a sparse matrix (triplet form or compressed-column form) */ cs *cs_spalloc (CS_INT m, CS_INT n, CS_INT nzmax, CS_INT values, CS_INT triplet) { cs *A = cs_calloc (1, sizeof (cs)) ; /* allocate the cs struct */ if (!A) return (NULL) ; /* out of memory */ A->m = m ; /* define dimensions and nzmax */ A->n = n ; A->nzmax = nzmax = CS_MAX (nzmax, 1) ; A->nz = triplet ? 0 : -1 ; /* allocate triplet or comp.col */ A->p = cs_malloc (triplet ? nzmax : n+1, sizeof (CS_INT)) ; A->i = cs_malloc (nzmax, sizeof (CS_INT)) ; A->x = values ? cs_malloc (nzmax, sizeof (CS_ENTRY)) : NULL ; return ((!A->p || !A->i || (values && !A->x)) ? cs_spfree (A) : A) ; } /* change the max # of entries sparse matrix */ CS_INT cs_sprealloc (cs *A, CS_INT nzmax) { CS_INT ok, oki, okj = 1, okx = 1 ; if (!A) return (0) ; if (nzmax <= 0) nzmax = (CS_CSC (A)) ? (A->p [A->n]) : A->nz ; nzmax = CS_MAX (nzmax, 1) ; A->i = cs_realloc (A->i, nzmax, sizeof (CS_INT), &oki) ; if (CS_TRIPLET (A)) A->p = cs_realloc (A->p, nzmax, sizeof (CS_INT), &okj) ; if (A->x) A->x = cs_realloc (A->x, nzmax, sizeof (CS_ENTRY), &okx) ; ok = (oki && okj && okx) ; if (ok) A->nzmax = nzmax ; return (ok) ; } /* free a sparse matrix */ cs *cs_spfree (cs *A) { if (!A) return (NULL) ; /* do nothing if A already NULL */ cs_free (A->p) ; cs_free (A->i) ; cs_free (A->x) ; return ((cs *) cs_free (A)) ; /* free the cs struct and return NULL */ } /* free a numeric factorization */ csn *cs_nfree (csn *N) { if (!N) return (NULL) ; /* do nothing if N already NULL */ cs_spfree (N->L) ; cs_spfree (N->U) ; cs_free (N->pinv) ; cs_free (N->B) ; return ((csn *) cs_free (N)) ; /* free the csn struct and return NULL */ } /* free a symbolic factorization */ css *cs_sfree (css *S) { if (!S) return (NULL) ; /* do nothing if S already NULL */ cs_free (S->pinv) ; cs_free (S->q) ; cs_free (S->parent) ; cs_free (S->cp) ; cs_free (S->leftmost) ; return ((css *) cs_free (S)) ; /* free the css struct and return NULL */ } /* allocate a cs_dmperm or cs_scc result */ csd *cs_dalloc (CS_INT m, CS_INT n) { csd *D ; D = cs_calloc (1, sizeof (csd)) ; if (!D) return (NULL) ; D->p = cs_malloc (m, sizeof (CS_INT)) ; D->r = cs_malloc (m+6, sizeof (CS_INT)) ; D->q = cs_malloc (n, sizeof (CS_INT)) ; D->s = cs_malloc (n+6, sizeof (CS_INT)) ; return ((!D->p || !D->r || !D->q || !D->s) ? cs_dfree (D) : D) ; } /* free a cs_dmperm or cs_scc result */ csd *cs_dfree (csd *D) { if (!D) return (NULL) ; /* do nothing if D already NULL */ cs_free (D->p) ; cs_free (D->q) ; cs_free (D->r) ; cs_free (D->s) ; return ((csd *) cs_free (D)) ; /* free the csd struct and return NULL */ } /* free workspace and return a sparse matrix result */ cs *cs_done (cs *C, void *w, void *x, CS_INT ok) { cs_free (w) ; /* free workspace */ cs_free (x) ; return (ok ? C : cs_spfree (C)) ; /* return result if OK, else free it */ } /* free workspace and return CS_INT array result */ CS_INT *cs_idone (CS_INT *p, cs *C, void *w, CS_INT ok) { cs_spfree (C) ; /* free temporary matrix */ cs_free (w) ; /* free workspace */ return (ok ? p : (CS_INT *) cs_free (p)) ; /* return result, or free it */ } /* free workspace and return a numeric factorization (Cholesky, LU, or QR) */ csn *cs_ndone (csn *N, cs *C, void *w, void *x, CS_INT ok) { cs_spfree (C) ; /* free temporary matrix */ cs_free (w) ; /* free workspace */ cs_free (x) ; return (ok ? N : cs_nfree (N)) ; /* return result if OK, else free it */ } /* free workspace and return a csd result */ csd *cs_ddone (csd *D, cs *C, void *w, CS_INT ok) { cs_spfree (C) ; /* free temporary matrix */ cs_free (w) ; /* free workspace */ return (ok ? D : cs_dfree (D)) ; /* return result if OK, else free it */ } leidenbase/src/vendor/cs/cs_dfs.c0000644000176200001440000000315514447675375016475 0ustar liggesusers#include "cs.h" /* depth-first-search of the graph of a matrix, starting at node j */ CS_INT cs_dfs (CS_INT j, cs *G, CS_INT top, CS_INT *xi, CS_INT *pstack, const CS_INT *pinv) { CS_INT i, p, p2, done, jnew, head = 0, *Gp, *Gi ; if (!CS_CSC (G) || !xi || !pstack) return (-1) ; /* check inputs */ Gp = G->p ; Gi = G->i ; xi [0] = j ; /* initialize the recursion stack */ while (head >= 0) { j = xi [head] ; /* get j from the top of the recursion stack */ jnew = pinv ? (pinv [j]) : j ; if (!CS_MARKED (Gp, j)) { CS_MARK (Gp, j) ; /* mark node j as visited */ pstack [head] = (jnew < 0) ? 0 : CS_UNFLIP (Gp [jnew]) ; } done = 1 ; /* node j done if no unvisited neighbors */ p2 = (jnew < 0) ? 0 : CS_UNFLIP (Gp [jnew+1]) ; for (p = pstack [head] ; p < p2 ; p++) /* examine all neighbors of j */ { i = Gi [p] ; /* consider neighbor node i */ if (CS_MARKED (Gp, i)) continue ; /* skip visited node i */ pstack [head] = p ; /* pause depth-first search of node j */ xi [++head] = i ; /* start dfs at node i */ done = 0 ; /* node j is not done */ break ; /* break, to start dfs (i) */ } if (done) /* depth-first search at node j is done */ { head-- ; /* remove j from the recursion stack */ xi [--top] = j ; /* and place in the output stack */ } } return (top) ; } leidenbase/src/vendor/cs/cs_ipvec.c0000644000176200001440000000051414447675375017023 0ustar liggesusers#include "cs.h" /* x(p) = b, for dense vectors x and b; p=NULL denotes identity */ CS_INT cs_ipvec (const CS_INT *p, const CS_ENTRY *b, CS_ENTRY *x, CS_INT n) { CS_INT k ; if (!x || !b) return (0) ; /* check inputs */ for (k = 0 ; k < n ; k++) x [p ? p [k] : k] = b [k] ; return (1) ; } leidenbase/src/vendor/cs/cs_chol.c0000644000176200001440000000547514447675375016655 0ustar liggesusers#include "cs.h" /* L = chol (A, [pinv parent cp]), pinv is optional */ csn *cs_chol (const cs *A, const css *S) { CS_ENTRY d, lki, *Lx, *x, *Cx ; CS_INT top, i, p, k, n, *Li, *Lp, *cp, *pinv, *s, *c, *parent, *Cp, *Ci ; cs *L, *C, *E ; csn *N ; if (!CS_CSC (A) || !S || !S->cp || !S->parent) return (NULL) ; n = A->n ; N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ c = cs_malloc (2*n, sizeof (CS_INT)) ; /* get CS_INT workspace */ x = cs_malloc (n, sizeof (CS_ENTRY)) ; /* get CS_ENTRY workspace */ cp = S->cp ; pinv = S->pinv ; parent = S->parent ; C = pinv ? cs_symperm (A, pinv, 1) : ((cs *) A) ; E = pinv ? C : NULL ; /* E is alias for A, or a copy E=A(p,p) */ if (!N || !c || !x || !C) return (cs_ndone (N, E, c, x, 0)) ; s = c + n ; Cp = C->p ; Ci = C->i ; Cx = C->x ; N->L = L = cs_spalloc (n, n, cp [n], 1, 0) ; /* allocate result */ if (!L) return (cs_ndone (N, E, c, x, 0)) ; Lp = L->p ; Li = L->i ; Lx = L->x ; for (k = 0 ; k < n ; k++) Lp [k] = c [k] = cp [k] ; for (k = 0 ; k < n ; k++) /* compute L(k,:) for L*L' = C */ { /* --- Nonzero pattern of L(k,:) ------------------------------------ */ top = cs_ereach (C, k, parent, s, c) ; /* find pattern of L(k,:) */ x [k] = 0 ; /* x (0:k) is now zero */ for (p = Cp [k] ; p < Cp [k+1] ; p++) /* x = full(triu(C(:,k))) */ { if (Ci [p] <= k) x [Ci [p]] = Cx [p] ; } d = x [k] ; /* d = C(k,k) */ x [k] = 0 ; /* clear x for k+1st iteration */ /* --- Triangular solve --------------------------------------------- */ for ( ; top < n ; top++) /* solve L(0:k-1,0:k-1) * x = C(:,k) */ { i = s [top] ; /* s [top..n-1] is pattern of L(k,:) */ lki = x [i] / Lx [Lp [i]] ; /* L(k,i) = x (i) / L(i,i) */ x [i] = 0 ; /* clear x for k+1st iteration */ for (p = Lp [i] + 1 ; p < c [i] ; p++) { x [Li [p]] -= Lx [p] * lki ; } d -= lki * CS_CONJ (lki) ; /* d = d - L(k,i)*L(k,i) */ p = c [i]++ ; Li [p] = k ; /* store L(k,i) in column i */ Lx [p] = CS_CONJ (lki) ; } /* --- Compute L(k,k) ----------------------------------------------- */ if (CS_REAL (d) <= 0 || CS_IMAG (d) != 0) return (cs_ndone (N, E, c, x, 0)) ; /* not pos def */ p = c [k]++ ; Li [p] = k ; /* store L(k,k) = sqrt (d) in column k */ Lx [p] = sqrt (d) ; } Lp [n] = cp [n] ; /* finalize L */ return (cs_ndone (N, E, c, x, 1)) ; /* success: free E,s,x; return N */ } leidenbase/src/vendor/cs/cs_qr.c0000644000176200001440000000670714447675375016351 0ustar liggesusers#include "cs.h" /* sparse QR factorization [V,beta,pinv,R] = qr (A) */ csn *cs_qr (const cs *A, const css *S) { CS_ENTRY *Rx, *Vx, *Ax, *x ; double *Beta ; CS_INT i, k, p, n, vnz, p1, top, m2, len, col, rnz, *s, *leftmost, *Ap, *Ai, *parent, *Rp, *Ri, *Vp, *Vi, *w, *pinv, *q ; cs *R, *V ; csn *N ; if (!CS_CSC (A) || !S) return (NULL) ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; q = S->q ; parent = S->parent ; pinv = S->pinv ; m2 = S->m2 ; vnz = S->lnz ; rnz = S->unz ; leftmost = S->leftmost ; w = cs_malloc (m2+n, sizeof (CS_INT)) ; /* get CS_INT workspace */ x = cs_malloc (m2, sizeof (CS_ENTRY)) ; /* get CS_ENTRY workspace */ N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ if (!w || !x || !N) return (cs_ndone (N, NULL, w, x, 0)) ; s = w + m2 ; /* s is size n */ for (k = 0 ; k < m2 ; k++) x [k] = 0 ; /* clear workspace x */ N->L = V = cs_spalloc (m2, n, vnz, 1, 0) ; /* allocate result V */ N->U = R = cs_spalloc (m2, n, rnz, 1, 0) ; /* allocate result R */ N->B = Beta = cs_malloc (n, sizeof (double)) ; /* allocate result Beta */ if (!R || !V || !Beta) return (cs_ndone (N, NULL, w, x, 0)) ; Rp = R->p ; Ri = R->i ; Rx = R->x ; Vp = V->p ; Vi = V->i ; Vx = V->x ; for (i = 0 ; i < m2 ; i++) w [i] = -1 ; /* clear w, to mark nodes */ rnz = 0 ; vnz = 0 ; for (k = 0 ; k < n ; k++) /* compute V and R */ { Rp [k] = rnz ; /* R(:,k) starts here */ Vp [k] = p1 = vnz ; /* V(:,k) starts here */ w [k] = k ; /* add V(k,k) to pattern of V */ Vi [vnz++] = k ; top = n ; col = q ? q [k] : k ; for (p = Ap [col] ; p < Ap [col+1] ; p++) /* find R(:,k) pattern */ { i = leftmost [Ai [p]] ; /* i = min(find(A(i,q))) */ for (len = 0 ; w [i] != k ; i = parent [i]) /* traverse up to k */ { s [len++] = i ; w [i] = k ; } while (len > 0) s [--top] = s [--len] ; /* push path on stack */ i = pinv [Ai [p]] ; /* i = permuted row of A(:,col) */ x [i] = Ax [p] ; /* x (i) = A(:,col) */ if (i > k && w [i] < k) /* pattern of V(:,k) = x (k+1:m) */ { Vi [vnz++] = i ; /* add i to pattern of V(:,k) */ w [i] = k ; } } for (p = top ; p < n ; p++) /* for each i in pattern of R(:,k) */ { i = s [p] ; /* R(i,k) is nonzero */ cs_happly (V, i, Beta [i], x) ; /* apply (V(i),Beta(i)) to x */ Ri [rnz] = i ; /* R(i,k) = x(i) */ Rx [rnz++] = x [i] ; x [i] = 0 ; if (parent [i] == k) vnz = cs_scatter (V, i, 0, w, NULL, k, V, vnz); } for (p = p1 ; p < vnz ; p++) /* gather V(:,k) = x */ { Vx [p] = x [Vi [p]] ; x [Vi [p]] = 0 ; } Ri [rnz] = k ; /* R(k,k) = norm (x) */ Rx [rnz++] = cs_house (Vx+p1, Beta+k, vnz-p1) ; /* [v,beta]=house(x) */ } Rp [n] = rnz ; /* finalize R */ Vp [n] = vnz ; /* finalize V */ return (cs_ndone (N, NULL, w, x, 1)) ; /* success */ } leidenbase/src/vendor/cs/cs_happly.c0000644000176200001440000000113514447675375017212 0ustar liggesusers#include "cs.h" /* apply the ith Householder vector to x */ CS_INT cs_happly (const cs *V, CS_INT i, double beta, CS_ENTRY *x) { CS_INT p, *Vp, *Vi ; CS_ENTRY *Vx, tau = 0 ; if (!CS_CSC (V) || !x) return (0) ; /* check inputs */ Vp = V->p ; Vi = V->i ; Vx = V->x ; for (p = Vp [i] ; p < Vp [i+1] ; p++) /* tau = v'*x */ { tau += CS_CONJ (Vx [p]) * x [Vi [p]] ; } tau *= beta ; /* tau = beta*(v'*x) */ for (p = Vp [i] ; p < Vp [i+1] ; p++) /* x = x - v*tau */ { x [Vi [p]] -= Vx [p] * tau ; } return (1) ; } leidenbase/src/vendor/cs/cs_lu.c0000644000176200001440000001004114447675375016331 0ustar liggesusers#include "cs.h" /* [L,U,pinv]=lu(A, [q lnz unz]). lnz and unz can be guess */ csn *cs_lu (const cs *A, const css *S, double tol) { cs *L, *U ; csn *N ; CS_ENTRY pivot, *Lx, *Ux, *x ; double a, t ; CS_INT *Lp, *Li, *Up, *Ui, *pinv, *xi, *q, n, ipiv, k, top, p, i, col, lnz,unz; if (!CS_CSC (A) || !S) return (NULL) ; /* check inputs */ n = A->n ; q = S->q ; lnz = S->lnz ; unz = S->unz ; x = cs_malloc (n, sizeof (CS_ENTRY)) ; /* get CS_ENTRY workspace */ xi = cs_malloc (2*n, sizeof (CS_INT)) ; /* get CS_INT workspace */ N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ if (!x || !xi || !N) return (cs_ndone (N, NULL, xi, x, 0)) ; N->L = L = cs_spalloc (n, n, lnz, 1, 0) ; /* allocate result L */ N->U = U = cs_spalloc (n, n, unz, 1, 0) ; /* allocate result U */ N->pinv = pinv = cs_malloc (n, sizeof (CS_INT)) ; /* allocate result pinv */ if (!L || !U || !pinv) return (cs_ndone (N, NULL, xi, x, 0)) ; Lp = L->p ; Up = U->p ; for (i = 0 ; i < n ; i++) x [i] = 0 ; /* clear workspace */ for (i = 0 ; i < n ; i++) pinv [i] = -1 ; /* no rows pivotal yet */ for (k = 0 ; k <= n ; k++) Lp [k] = 0 ; /* no cols of L yet */ lnz = unz = 0 ; for (k = 0 ; k < n ; k++) /* compute L(:,k) and U(:,k) */ { /* --- Triangular solve --------------------------------------------- */ Lp [k] = lnz ; /* L(:,k) starts here */ Up [k] = unz ; /* U(:,k) starts here */ if ((lnz + n > L->nzmax && !cs_sprealloc (L, 2*L->nzmax + n)) || (unz + n > U->nzmax && !cs_sprealloc (U, 2*U->nzmax + n))) { return (cs_ndone (N, NULL, xi, x, 0)) ; } Li = L->i ; Lx = L->x ; Ui = U->i ; Ux = U->x ; col = q ? (q [k]) : k ; top = cs_spsolve (L, A, col, xi, x, pinv, 1) ; /* x = L\A(:,col) */ /* --- Find pivot --------------------------------------------------- */ ipiv = -1 ; a = -1 ; for (p = top ; p < n ; p++) { i = xi [p] ; /* x(i) is nonzero */ if (pinv [i] < 0) /* row i is not yet pivotal */ { if ((t = CS_ABS (x [i])) > a) { a = t ; /* largest pivot candidate so far */ ipiv = i ; } } else /* x(i) is the entry U(pinv[i],k) */ { Ui [unz] = pinv [i] ; Ux [unz++] = x [i] ; } } if (ipiv == -1 || a <= 0) return (cs_ndone (N, NULL, xi, x, 0)) ; /* tol=1 for partial pivoting; tol<1 gives preference to diagonal */ if (pinv [col] < 0 && CS_ABS (x [col]) >= a*tol) ipiv = col ; /* --- Divide by pivot ---------------------------------------------- */ pivot = x [ipiv] ; /* the chosen pivot */ Ui [unz] = k ; /* last entry in U(:,k) is U(k,k) */ Ux [unz++] = pivot ; pinv [ipiv] = k ; /* ipiv is the kth pivot row */ Li [lnz] = ipiv ; /* first entry in L(:,k) is L(k,k) = 1 */ Lx [lnz++] = 1 ; for (p = top ; p < n ; p++) /* L(k+1:n,k) = x / pivot */ { i = xi [p] ; if (pinv [i] < 0) /* x(i) is an entry in L(:,k) */ { Li [lnz] = i ; /* save unpermuted row in L */ Lx [lnz++] = x [i] / pivot ; /* scale pivot column */ } x [i] = 0 ; /* x [0..n-1] = 0 for next k */ } } /* --- Finalize L and U ------------------------------------------------- */ Lp [n] = lnz ; Up [n] = unz ; Li = L->i ; /* fix row indices of L for final pinv */ for (p = 0 ; p < lnz ; p++) Li [p] = pinv [Li [p]] ; cs_sprealloc (L, 0) ; /* remove extra space from L and U */ cs_sprealloc (U, 0) ; return (cs_ndone (N, NULL, xi, x, 1)) ; /* success */ } leidenbase/src/vendor/cs/cs_spsolve.c0000644000176200001440000000255214447675375017414 0ustar liggesusers#include "cs.h" /* solve Gx=b(:,k), where G is either upper (lo=0) or lower (lo=1) triangular */ CS_INT cs_spsolve (cs *G, const cs *B, CS_INT k, CS_INT *xi, CS_ENTRY *x, const CS_INT *pinv, CS_INT lo) { CS_INT j, J, p, q, px, top, n, *Gp, *Gi, *Bp, *Bi ; CS_ENTRY *Gx, *Bx ; if (!CS_CSC (G) || !CS_CSC (B) || !xi || !x) return (-1) ; Gp = G->p ; Gi = G->i ; Gx = G->x ; n = G->n ; Bp = B->p ; Bi = B->i ; Bx = B->x ; top = cs_reach (G, B, k, xi, pinv) ; /* xi[top..n-1]=Reach(B(:,k)) */ for (p = top ; p < n ; p++) x [xi [p]] = 0 ; /* clear x */ for (p = Bp [k] ; p < Bp [k+1] ; p++) x [Bi [p]] = Bx [p] ; /* scatter B */ for (px = top ; px < n ; px++) { j = xi [px] ; /* x(j) is nonzero */ J = pinv ? (pinv [j]) : j ; /* j maps to col J of G */ if (J < 0) continue ; /* column J is empty */ x [j] /= Gx [lo ? (Gp [J]) : (Gp [J+1]-1)] ;/* x(j) /= G(j,j) */ p = lo ? (Gp [J]+1) : (Gp [J]) ; /* lo: L(j,j) 1st entry */ q = lo ? (Gp [J+1]) : (Gp [J+1]-1) ; /* up: U(j,j) last entry */ for ( ; p < q ; p++) { x [Gi [p]] -= Gx [p] * x [j] ; /* x(i) -= G(i,j) * x(j) */ } } return (top) ; /* return top of stack */ } leidenbase/src/vendor/cs/cs_add.c0000644000176200001440000000261314447675375016447 0ustar liggesusers#include "cs.h" /* C = alpha*A + beta*B */ cs *cs_add (const cs *A, const cs *B, CS_ENTRY alpha, CS_ENTRY beta) { CS_INT p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values ; CS_ENTRY *x, *Bx, *Cx ; cs *C ; if (!CS_CSC (A) || !CS_CSC (B)) return (NULL) ; /* check inputs */ if (A->m != B->m || A->n != B->n) return (NULL) ; m = A->m ; anz = A->p [A->n] ; n = B->n ; Bp = B->p ; Bx = B->x ; bnz = Bp [n] ; w = cs_calloc (m, sizeof (CS_INT)) ; /* get workspace */ values = (A->x != NULL) && (Bx != NULL) ; x = values ? cs_malloc (m, sizeof (CS_ENTRY)) : NULL ; /* get workspace */ C = cs_spalloc (m, n, anz + bnz, values, 0) ; /* allocate result*/ if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ; Cp = C->p ; Ci = C->i ; Cx = C->x ; for (j = 0 ; j < n ; j++) { Cp [j] = nz ; /* column j of C starts here */ nz = cs_scatter (A, j, alpha, w, x, j+1, C, nz) ; /* alpha*A(:,j)*/ nz = cs_scatter (B, j, beta, w, x, j+1, C, nz) ; /* beta*B(:,j) */ if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ; } Cp [n] = nz ; /* finalize the last column of C */ cs_sprealloc (C, 0) ; /* remove extra space from C */ return (cs_done (C, w, x, 1)) ; /* success; free workspace, return C */ } leidenbase/src/vendor/cs/cs_scc.c0000644000176200001440000000354414447675375016473 0ustar liggesusers#include "cs.h" /* find the strongly connected components of a square matrix */ csd *cs_scc (cs *A) /* matrix A temporarily modified, then restored */ { CS_INT n, i, k, b, nb = 0, top, *xi, *pstack, *p, *r, *Ap, *ATp, *rcopy, *Blk ; cs *AT ; csd *D ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; Ap = A->p ; D = cs_dalloc (n, 0) ; /* allocate result */ AT = cs_transpose (A, 0) ; /* AT = A' */ xi = cs_malloc (2*n+1, sizeof (CS_INT)) ; /* get workspace */ if (!D || !AT || !xi) return (cs_ddone (D, AT, xi, 0)) ; Blk = xi ; rcopy = pstack = xi + n ; p = D->p ; r = D->r ; ATp = AT->p ; top = n ; for (i = 0 ; i < n ; i++) /* first dfs(A) to find finish times (xi) */ { if (!CS_MARKED (Ap, i)) top = cs_dfs (i, A, top, xi, pstack, NULL) ; } for (i = 0 ; i < n ; i++) CS_MARK (Ap, i) ; /* restore A; unmark all nodes*/ top = n ; nb = n ; for (k = 0 ; k < n ; k++) /* dfs(A') to find strongly connnected comp */ { i = xi [k] ; /* get i in reverse order of finish times */ if (CS_MARKED (ATp, i)) continue ; /* skip node i if already ordered */ r [nb--] = top ; /* node i is the start of a component in p */ top = cs_dfs (i, AT, top, p, pstack, NULL) ; } r [nb] = 0 ; /* first block starts at zero; shift r up */ for (k = nb ; k <= n ; k++) r [k-nb] = r [k] ; D->nb = nb = n-nb ; /* nb = # of strongly connected components */ for (b = 0 ; b < nb ; b++) /* sort each block in natural order */ { for (k = r [b] ; k < r [b+1] ; k++) Blk [p [k]] = b ; } for (b = 0 ; b <= nb ; b++) rcopy [b] = r [b] ; for (i = 0 ; i < n ; i++) p [rcopy [Blk [i]]++] = i ; return (cs_ddone (D, AT, xi, 1)) ; } leidenbase/src/vendor/cs/cs_ereach.c0000644000176200001440000000213614447675375017146 0ustar liggesusers#include "cs.h" /* find nonzero pattern of Cholesky L(k,1:k-1) using etree and triu(A(:,k)) */ CS_INT cs_ereach (const cs *A, CS_INT k, const CS_INT *parent, CS_INT *s, CS_INT *w) { CS_INT i, p, n, len, top, *Ap, *Ai ; if (!CS_CSC (A) || !parent || !s || !w) return (-1) ; /* check inputs */ top = n = A->n ; Ap = A->p ; Ai = A->i ; CS_MARK (w, k) ; /* mark node k as visited */ for (p = Ap [k] ; p < Ap [k+1] ; p++) { i = Ai [p] ; /* A(i,k) is nonzero */ if (i > k) continue ; /* only use upper triangular part of A */ for (len = 0 ; !CS_MARKED (w,i) ; i = parent [i]) /* traverse up etree*/ { s [len++] = i ; /* L(k,i) is nonzero */ CS_MARK (w, i) ; /* mark i as visited */ } while (len > 0) s [--top] = s [--len] ; /* push path onto stack */ } for (p = top ; p < n ; p++) CS_MARK (w, s [p]) ; /* unmark all nodes */ CS_MARK (w, k) ; /* unmark node k */ return (top) ; /* s [top..n-1] contains pattern of L(k,:)*/ } leidenbase/src/vendor/cs/cs_sqr.c0000644000176200001440000000737214447675375016533 0ustar liggesusers#include "cs.h" /* compute nnz(V) = S->lnz, S->pinv, S->leftmost, S->m2 from A and S->parent */ static CS_INT cs_vcount (const cs *A, css *S) { CS_INT i, k, p, pa, n = A->n, m = A->m, *Ap = A->p, *Ai = A->i, *next, *head, *tail, *nque, *pinv, *leftmost, *w, *parent = S->parent ; S->pinv = pinv = cs_malloc (m+n, sizeof (CS_INT)) ; /* allocate pinv, */ S->leftmost = leftmost = cs_malloc (m, sizeof (CS_INT)) ; /* and leftmost */ w = cs_malloc (m+3*n, sizeof (CS_INT)) ; /* get workspace */ if (!pinv || !w || !leftmost) { cs_free (w) ; /* pinv and leftmost freed later */ return (0) ; /* out of memory */ } next = w ; head = w + m ; tail = w + m + n ; nque = w + m + 2*n ; for (k = 0 ; k < n ; k++) head [k] = -1 ; /* queue k is empty */ for (k = 0 ; k < n ; k++) tail [k] = -1 ; for (k = 0 ; k < n ; k++) nque [k] = 0 ; for (i = 0 ; i < m ; i++) leftmost [i] = -1 ; for (k = n-1 ; k >= 0 ; k--) { for (p = Ap [k] ; p < Ap [k+1] ; p++) { leftmost [Ai [p]] = k ; /* leftmost[i] = min(find(A(i,:)))*/ } } for (i = m-1 ; i >= 0 ; i--) /* scan rows in reverse order */ { pinv [i] = -1 ; /* row i is not yet ordered */ k = leftmost [i] ; if (k == -1) continue ; /* row i is empty */ if (nque [k]++ == 0) tail [k] = i ; /* first row in queue k */ next [i] = head [k] ; /* put i at head of queue k */ head [k] = i ; } S->lnz = 0 ; S->m2 = m ; for (k = 0 ; k < n ; k++) /* find row permutation and nnz(V)*/ { i = head [k] ; /* remove row i from queue k */ S->lnz++ ; /* count V(k,k) as nonzero */ if (i < 0) i = S->m2++ ; /* add a fictitious row */ pinv [i] = k ; /* associate row i with V(:,k) */ if (--nque [k] <= 0) continue ; /* skip if V(k+1:m,k) is empty */ S->lnz += nque [k] ; /* nque [k] is nnz (V(k+1:m,k)) */ if ((pa = parent [k]) != -1) /* move all rows to parent of k */ { if (nque [pa] == 0) tail [pa] = tail [k] ; next [tail [k]] = head [pa] ; head [pa] = next [i] ; nque [pa] += nque [k] ; } } for (i = 0 ; i < m ; i++) if (pinv [i] < 0) pinv [i] = k++ ; cs_free (w) ; return (1) ; } /* symbolic ordering and analysis for QR or LU */ css *cs_sqr (CS_INT order, const cs *A, CS_INT qr) { CS_INT n, k, ok = 1, *post ; css *S ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; S = cs_calloc (1, sizeof (css)) ; /* allocate result S */ if (!S) return (NULL) ; /* out of memory */ S->q = cs_amd (order, A) ; /* fill-reducing ordering */ if (order && !S->q) return (cs_sfree (S)) ; if (qr) /* QR symbolic analysis */ { cs *C = order ? cs_permute (A, NULL, S->q, 0) : ((cs *) A) ; S->parent = cs_etree (C, 1) ; /* etree of C'*C, where C=A(:,q) */ post = cs_post (S->parent, n) ; S->cp = cs_counts (C, S->parent, post, 1) ; /* col counts chol(C'*C) */ cs_free (post) ; ok = C && S->parent && S->cp && cs_vcount (C, S) ; if (ok) for (S->unz = 0, k = 0 ; k < n ; k++) S->unz += S->cp [k] ; if (order) cs_spfree (C) ; } else { S->unz = 4*(A->p [n]) + n ; /* for LU factorization only, */ S->lnz = S->unz ; /* guess nnz(L) and nnz(U) */ } return (ok ? S : cs_sfree (S)) ; /* return result S */ } leidenbase/src/vendor/cs/cs_permute.c0000644000176200001440000000202714447675375017377 0ustar liggesusers#include "cs.h" /* C = A(p,q) where p and q are permutations of 0..m-1 and 0..n-1. */ cs *cs_permute (const cs *A, const CS_INT *pinv, const CS_INT *q, CS_INT values) { CS_INT t, j, k, nz = 0, m, n, *Ap, *Ai, *Cp, *Ci ; CS_ENTRY *Cx, *Ax ; cs *C ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; C = cs_spalloc (m, n, Ap [n], values && Ax != NULL, 0) ; /* alloc result */ if (!C) return (cs_done (C, NULL, NULL, 0)) ; /* out of memory */ Cp = C->p ; Ci = C->i ; Cx = C->x ; for (k = 0 ; k < n ; k++) { Cp [k] = nz ; /* column k of C is column q[k] of A */ j = q ? (q [k]) : k ; for (t = Ap [j] ; t < Ap [j+1] ; t++) { if (Cx) Cx [nz] = Ax [t] ; /* row i of A is row pinv[i] of C */ Ci [nz++] = pinv ? (pinv [Ai [t]]) : Ai [t] ; } } Cp [n] = nz ; /* finalize the last column of C */ return (cs_done (C, NULL, NULL, 1)) ; } leidenbase/src/vendor/cs/cs_utsolve.c0000644000176200001440000000104414447675375017415 0ustar liggesusers#include "cs.h" /* solve U'x=b where x and b are dense. x=b on input, solution on output. */ CS_INT cs_utsolve (const cs *U, CS_ENTRY *x) { CS_INT p, j, n, *Up, *Ui ; CS_ENTRY *Ux ; if (!CS_CSC (U) || !x) return (0) ; /* check inputs */ n = U->n ; Up = U->p ; Ui = U->i ; Ux = U->x ; for (j = 0 ; j < n ; j++) { for (p = Up [j] ; p < Up [j+1]-1 ; p++) { x [j] -= CS_CONJ (Ux [p]) * x [Ui [p]] ; } x [j] /= CS_CONJ (Ux [Up [j+1]-1]) ; } return (1) ; } leidenbase/src/vendor/cs/cs_maxtrans.c0000644000176200001440000001063314447675375017555 0ustar liggesusers#include "cs.h" /* find an augmenting path starting at column k and extend the match if found */ static void cs_augment (CS_INT k, const cs *A, CS_INT *jmatch, CS_INT *cheap, CS_INT *w, CS_INT *js, CS_INT *is, CS_INT *ps) { CS_INT found = 0, p, i = -1, *Ap = A->p, *Ai = A->i, head = 0, j ; js [0] = k ; /* start with just node k in jstack */ while (head >= 0) { /* --- Start (or continue) depth-first-search at node j ------------- */ j = js [head] ; /* get j from top of jstack */ if (w [j] != k) /* 1st time j visited for kth path */ { w [j] = k ; /* mark j as visited for kth path */ for (p = cheap [j] ; p < Ap [j+1] && !found ; p++) { i = Ai [p] ; /* try a cheap assignment (i,j) */ found = (jmatch [i] == -1) ; } cheap [j] = p ; /* start here next time j is traversed*/ if (found) { is [head] = i ; /* column j matched with row i */ break ; /* end of augmenting path */ } ps [head] = Ap [j] ; /* no cheap match: start dfs for j */ } /* --- Depth-first-search of neighbors of j ------------------------- */ for (p = ps [head] ; p < Ap [j+1] ; p++) { i = Ai [p] ; /* consider row i */ if (w [jmatch [i]] == k) continue ; /* skip jmatch [i] if marked */ ps [head] = p + 1 ; /* pause dfs of node j */ is [head] = i ; /* i will be matched with j if found */ js [++head] = jmatch [i] ; /* start dfs at column jmatch [i] */ break ; } if (p == Ap [j+1]) head-- ; /* node j is done; pop from stack */ } /* augment the match if path found: */ if (found) for (p = head ; p >= 0 ; p--) jmatch [is [p]] = js [p] ; } /* find a maximum transveral */ CS_INT *cs_maxtrans (const cs *A, CS_INT seed) /*[jmatch [0..m-1]; imatch [0..n-1]]*/ { CS_INT i, j, k, n, m, p, n2 = 0, m2 = 0, *Ap, *jimatch, *w, *cheap, *js, *is, *ps, *Ai, *Cp, *jmatch, *imatch, *q ; cs *C ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; m = A->m ; Ap = A->p ; Ai = A->i ; w = jimatch = cs_calloc (m+n, sizeof (CS_INT)) ; /* allocate result */ if (!jimatch) return (NULL) ; for (k = 0, j = 0 ; j < n ; j++) /* count nonempty rows and columns */ { n2 += (Ap [j] < Ap [j+1]) ; for (p = Ap [j] ; p < Ap [j+1] ; p++) { w [Ai [p]] = 1 ; k += (j == Ai [p]) ; /* count entries already on diagonal */ } } if (k == CS_MIN (m,n)) /* quick return if diagonal zero-free */ { jmatch = jimatch ; imatch = jimatch + m ; for (i = 0 ; i < k ; i++) jmatch [i] = i ; for ( ; i < m ; i++) jmatch [i] = -1 ; for (j = 0 ; j < k ; j++) imatch [j] = j ; for ( ; j < n ; j++) imatch [j] = -1 ; return (cs_idone (jimatch, NULL, NULL, 1)) ; } for (i = 0 ; i < m ; i++) m2 += w [i] ; C = (m2 < n2) ? cs_transpose (A,0) : ((cs *) A) ; /* transpose if needed */ if (!C) return (cs_idone (jimatch, (m2 < n2) ? C : NULL, NULL, 0)) ; n = C->n ; m = C->m ; Cp = C->p ; jmatch = (m2 < n2) ? jimatch + n : jimatch ; imatch = (m2 < n2) ? jimatch : jimatch + m ; w = cs_malloc (5*n, sizeof (CS_INT)) ; /* get workspace */ if (!w) return (cs_idone (jimatch, (m2 < n2) ? C : NULL, w, 0)) ; cheap = w + n ; js = w + 2*n ; is = w + 3*n ; ps = w + 4*n ; for (j = 0 ; j < n ; j++) cheap [j] = Cp [j] ; /* for cheap assignment */ for (j = 0 ; j < n ; j++) w [j] = -1 ; /* all columns unflagged */ for (i = 0 ; i < m ; i++) jmatch [i] = -1 ; /* nothing matched yet */ q = cs_randperm (n, seed) ; /* q = random permutation */ for (k = 0 ; k < n ; k++) /* augment, starting at column q[k] */ { cs_augment (q ? q [k]: k, C, jmatch, cheap, w, js, is, ps) ; } cs_free (q) ; for (j = 0 ; j < n ; j++) imatch [j] = -1 ; /* find row match */ for (i = 0 ; i < m ; i++) if (jmatch [i] >= 0) imatch [jmatch [i]] = i ; return (cs_idone (jimatch, (m2 < n2) ? C : NULL, w, 1)) ; } leidenbase/src/vendor/cs/cs_malloc.c0000644000176200001440000000160614447675375017167 0ustar liggesusers#include "cs.h" #ifdef MATLAB_MEX_FILE #define malloc mxMalloc #define free mxFree #define realloc mxRealloc #define calloc mxCalloc #endif /* wrapper for malloc */ void *cs_malloc (CS_INT n, size_t size) { return (malloc (CS_MAX (n,1) * size)) ; } /* wrapper for calloc */ void *cs_calloc (CS_INT n, size_t size) { return (calloc (CS_MAX (n,1), size)) ; } /* wrapper for free */ void *cs_free (void *p) { if (p) free (p) ; /* free p if it is not already NULL */ return (NULL) ; /* return NULL to simplify the use of cs_free */ } /* wrapper for realloc */ void *cs_realloc (void *p, CS_INT n, size_t size, CS_INT *ok) { void *pnew ; pnew = realloc (p, CS_MAX (n,1) * size) ; /* realloc the block */ *ok = (pnew != NULL) ; /* realloc fails if pnew is NULL */ return ((*ok) ? pnew : p) ; /* return original p if failure */ } leidenbase/src/vendor/cs/cs_house.c0000644000176200001440000000154214447675375017042 0ustar liggesusers#include "cs.h" /* create a Householder reflection [v,beta,s]=house(x), overwrite x with v, * where (I-beta*v*v')*x = s*e1 and e1 = [1 0 ... 0]'. * Note that this CXSparse version is different than CSparse. See Higham, * Accuracy & Stability of Num Algorithms, 2nd ed, 2002, page 357. */ CS_ENTRY cs_house (CS_ENTRY *x, double *beta, CS_INT n) { CS_ENTRY s = 0 ; CS_INT i ; if (!x || !beta) return (-1) ; /* check inputs */ /* s = norm(x) */ for (i = 0 ; i < n ; i++) s += x [i] * CS_CONJ (x [i]) ; s = sqrt (s) ; if (s == 0) { (*beta) = 0 ; x [0] = 1 ; } else { /* s = sign(x[0]) * norm (x) ; */ if (x [0] != 0) { s *= x [0] / CS_ABS (x [0]) ; } x [0] += s ; (*beta) = 1. / CS_REAL (CS_CONJ (s) * x [0]) ; } return (-s) ; } leidenbase/src/vendor/cs/cs_leaf.c0000644000176200001440000000201714447675375016624 0ustar liggesusers#include "cs.h" /* consider A(i,j), node j in ith row subtree and return lca(jprev,j) */ CS_INT cs_leaf (CS_INT i, CS_INT j, const CS_INT *first, CS_INT *maxfirst, CS_INT *prevleaf, CS_INT *ancestor, CS_INT *jleaf) { CS_INT q, s, sparent, jprev ; if (!first || !maxfirst || !prevleaf || !ancestor || !jleaf) return (-1) ; *jleaf = 0 ; if (i <= j || first [j] <= maxfirst [i]) return (-1) ; /* j not a leaf */ maxfirst [i] = first [j] ; /* update max first[j] seen so far */ jprev = prevleaf [i] ; /* jprev = previous leaf of ith subtree */ prevleaf [i] = j ; *jleaf = (jprev == -1) ? 1: 2 ; /* j is first or subsequent leaf */ if (*jleaf == 1) return (i) ; /* if 1st leaf, q = root of ith subtree */ for (q = jprev ; q != ancestor [q] ; q = ancestor [q]) ; for (s = jprev ; s != q ; s = sparent) { sparent = ancestor [s] ; /* path compression */ ancestor [s] = q ; } return (q) ; /* q = least common ancester (jprev,j) */ } leidenbase/src/vendor/cs/cs_dupl.c0000644000176200001440000000257514447675375016672 0ustar liggesusers#include "cs.h" /* remove duplicate entries from A */ CS_INT cs_dupl (cs *A) { CS_INT i, j, p, q, nz = 0, n, m, *Ap, *Ai, *w ; CS_ENTRY *Ax ; if (!CS_CSC (A)) return (0) ; /* check inputs */ m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; w = cs_malloc (m, sizeof (CS_INT)) ; /* get workspace */ if (!w) return (0) ; /* out of memory */ for (i = 0 ; i < m ; i++) w [i] = -1 ; /* row i not yet seen */ for (j = 0 ; j < n ; j++) { q = nz ; /* column j will start at q */ for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; /* A(i,j) is nonzero */ if (w [i] >= q) { Ax [w [i]] += Ax [p] ; /* A(i,j) is a duplicate */ } else { w [i] = nz ; /* record where row i occurs */ Ai [nz] = i ; /* keep A(i,j) */ Ax [nz++] = Ax [p] ; } } Ap [j] = q ; /* record start of column j */ } Ap [n] = nz ; /* finalize A */ cs_free (w) ; /* free workspace */ return (cs_sprealloc (A, 0)) ; /* remove extra space from A */ } leidenbase/src/vendor/cs/cs_gaxpy.c0000644000176200001440000000066614447675375017055 0ustar liggesusers#include "cs.h" /* y = A*x+y */ CS_INT cs_gaxpy (const cs *A, const CS_ENTRY *x, CS_ENTRY *y) { CS_INT p, j, n, *Ap, *Ai ; CS_ENTRY *Ax ; if (!CS_CSC (A) || !x || !y) return (0) ; /* check inputs */ n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; for (j = 0 ; j < n ; j++) { for (p = Ap [j] ; p < Ap [j+1] ; p++) { y [Ai [p]] += Ax [p] * x [j] ; } } return (1) ; } leidenbase/src/vendor/cs/cs_droptol.c0000644000176200001440000000037414447675375017404 0ustar liggesusers#include "cs.h" static CS_INT cs_tol (CS_INT i, CS_INT j, CS_ENTRY aij, void *tol) { return (CS_ABS (aij) > *((double *) tol)) ; } CS_INT cs_droptol (cs *A, double tol) { return (cs_fkeep (A, &cs_tol, &tol)) ; /* keep all large entries */ } leidenbase/src/vendor/cs/cs_pinv.c0000644000176200001440000000074214447675375016674 0ustar liggesusers#include "cs.h" /* pinv = p', or p = pinv' */ CS_INT *cs_pinv (CS_INT const *p, CS_INT n) { CS_INT k, *pinv ; if (!p) return (NULL) ; /* p = NULL denotes identity */ pinv = cs_malloc (n, sizeof (CS_INT)) ; /* allocate result */ if (!pinv) return (NULL) ; /* out of memory */ for (k = 0 ; k < n ; k++) pinv [p [k]] = k ;/* invert the permutation */ return (pinv) ; /* return result */ } leidenbase/src/vendor/cs/cs_qrsol.c0000644000176200001440000000353314447675375017061 0ustar liggesusers#include "cs.h" /* x=A\b where A can be rectangular; b overwritten with solution */ CS_INT cs_qrsol (CS_INT order, const cs *A, CS_ENTRY *b) { CS_ENTRY *x ; css *S ; csn *N ; cs *AT = NULL ; CS_INT k, m, n, ok ; if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ n = A->n ; m = A->m ; if (m >= n) { S = cs_sqr (order, A, 1) ; /* ordering and symbolic analysis */ N = cs_qr (A, S) ; /* numeric QR factorization */ x = cs_calloc (S ? S->m2 : 1, sizeof (CS_ENTRY)) ; /* get workspace */ ok = (S && N && x) ; if (ok) { cs_ipvec (S->pinv, b, x, m) ; /* x(0:m-1) = b(p(0:m-1) */ for (k = 0 ; k < n ; k++) /* apply Householder refl. to x */ { cs_happly (N->L, k, N->B [k], x) ; } cs_usolve (N->U, x) ; /* x = R\x */ cs_ipvec (S->q, x, b, n) ; /* b(q(0:n-1)) = x(0:n-1) */ } } else { AT = cs_transpose (A, 1) ; /* Ax=b is underdetermined */ S = cs_sqr (order, AT, 1) ; /* ordering and symbolic analysis */ N = cs_qr (AT, S) ; /* numeric QR factorization of A' */ x = cs_calloc (S ? S->m2 : 1, sizeof (CS_ENTRY)) ; /* get workspace */ ok = (AT && S && N && x) ; if (ok) { cs_pvec (S->q, b, x, m) ; /* x(q(0:m-1)) = b(0:m-1) */ cs_utsolve (N->U, x) ; /* x = R'\x */ for (k = m-1 ; k >= 0 ; k--) /* apply Householder refl. to x */ { cs_happly (N->L, k, N->B [k], x) ; } cs_pvec (S->pinv, x, b, n) ; /* b(0:n-1) = x(p(0:n-1)) */ } } cs_free (x) ; cs_sfree (S) ; cs_nfree (N) ; cs_spfree (AT) ; return (ok) ; } leidenbase/src/vendor/cs/cs_scatter.c0000644000176200001440000000160514447675375017364 0ustar liggesusers#include "cs.h" /* x = x + beta * A(:,j), where x is a dense vector and A(:,j) is sparse */ CS_INT cs_scatter (const cs *A, CS_INT j, CS_ENTRY beta, CS_INT *w, CS_ENTRY *x, CS_INT mark, cs *C, CS_INT nz) { CS_INT i, p, *Ap, *Ai, *Ci ; CS_ENTRY *Ax ; if (!CS_CSC (A) || !w || !CS_CSC (C)) return (-1) ; /* check inputs */ Ap = A->p ; Ai = A->i ; Ax = A->x ; Ci = C->i ; for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; /* A(i,j) is nonzero */ if (w [i] < mark) { w [i] = mark ; /* i is new entry in column j */ Ci [nz++] = i ; /* add i to pattern of C(:,j) */ if (x) x [i] = beta * Ax [p] ; /* x(i) = beta*A(i,j) */ } else if (x) x [i] += beta * Ax [p] ; /* i exists in C(:,j) already */ } return (nz) ; } leidenbase/src/vendor/cs/cs_symperm.c0000644000176200001440000000336714447675375017422 0ustar liggesusers#include "cs.h" /* C = A(p,p) where A and C are symmetric the upper part stored; pinv not p */ cs *cs_symperm (const cs *A, const CS_INT *pinv, CS_INT values) { CS_INT i, j, p, q, i2, j2, n, *Ap, *Ai, *Cp, *Ci, *w ; CS_ENTRY *Cx, *Ax ; cs *C ; if (!CS_CSC (A)) return (NULL) ; /* check inputs */ n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; C = cs_spalloc (n, n, Ap [n], values && (Ax != NULL), 0) ; /* alloc result*/ w = cs_calloc (n, sizeof (CS_INT)) ; /* get workspace */ if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ Cp = C->p ; Ci = C->i ; Cx = C->x ; for (j = 0 ; j < n ; j++) /* count entries in each column of C */ { j2 = pinv ? pinv [j] : j ; /* column j of A is column j2 of C */ for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; if (i > j) continue ; /* skip lower triangular part of A */ i2 = pinv ? pinv [i] : i ; /* row i of A is row i2 of C */ w [CS_MAX (i2, j2)]++ ; /* column count of C */ } } cs_cumsum (Cp, w, n) ; /* compute column pointers of C */ for (j = 0 ; j < n ; j++) { j2 = pinv ? pinv [j] : j ; /* column j of A is column j2 of C */ for (p = Ap [j] ; p < Ap [j+1] ; p++) { i = Ai [p] ; if (i > j) continue ; /* skip lower triangular part of A*/ i2 = pinv ? pinv [i] : i ; /* row i of A is row i2 of C */ Ci [q = w [CS_MAX (i2, j2)]++] = CS_MIN (i2, j2) ; if (Cx) Cx [q] = (i2 <= j2) ? Ax [p] : CS_CONJ (Ax [p]) ; } } return (cs_done (C, w, NULL, 1)) ; /* success; free workspace, return C */ } leidenbase/src/vendor/cs/cs_reach.c0000644000176200001440000000127114447675375017000 0ustar liggesusers#include "cs.h" /* xi [top...n-1] = nodes reachable from graph of G*P' via nodes in B(:,k). * xi [n...2n-1] used as workspace */ CS_INT cs_reach (cs *G, const cs *B, CS_INT k, CS_INT *xi, const CS_INT *pinv) { CS_INT p, n, top, *Bp, *Bi, *Gp ; if (!CS_CSC (G) || !CS_CSC (B) || !xi) return (-1) ; /* check inputs */ n = G->n ; Bp = B->p ; Bi = B->i ; Gp = G->p ; top = n ; for (p = Bp [k] ; p < Bp [k+1] ; p++) { if (!CS_MARKED (Gp, Bi [p])) /* start a dfs at unmarked node i */ { top = cs_dfs (Bi [p], G, top, xi, xi+n, pinv) ; } } for (p = top ; p < n ; p++) CS_MARK (Gp, xi [p]) ; /* restore G */ return (top) ; } leidenbase/src/vendor/cs/cs_updown.c0000644000176200001440000000407214447675375017234 0ustar liggesusers#include "cs.h" /* sparse Cholesky update/downdate, L*L' + sigma*w*w' (sigma = +1 or -1) */ CS_INT cs_updown (cs *L, CS_INT sigma, const cs *C, const CS_INT *parent) { CS_INT n, p, f, j, *Lp, *Li, *Cp, *Ci ; CS_ENTRY *Lx, *Cx, alpha, gamma, w1, w2, *w ; double beta = 1, beta2 = 1, delta ; #ifdef CS_COMPLEX cs_complex_t phase ; #endif if (!CS_CSC (L) || !CS_CSC (C) || !parent) return (0) ; /* check inputs */ Lp = L->p ; Li = L->i ; Lx = L->x ; n = L->n ; Cp = C->p ; Ci = C->i ; Cx = C->x ; if ((p = Cp [0]) >= Cp [1]) return (1) ; /* return if C empty */ w = cs_malloc (n, sizeof (CS_ENTRY)) ; /* get workspace */ if (!w) return (0) ; /* out of memory */ f = Ci [p] ; for ( ; p < Cp [1] ; p++) f = CS_MIN (f, Ci [p]) ; /* f = min (find (C)) */ for (j = f ; j != -1 ; j = parent [j]) w [j] = 0 ; /* clear workspace w */ for (p = Cp [0] ; p < Cp [1] ; p++) w [Ci [p]] = Cx [p] ; /* w = C */ for (j = f ; j != -1 ; j = parent [j]) /* walk path f up to root */ { p = Lp [j] ; alpha = w [j] / Lx [p] ; /* alpha = w(j) / L(j,j) */ beta2 = beta*beta + sigma*alpha*CS_CONJ(alpha) ; if (beta2 <= 0) break ; /* not positive definite */ beta2 = sqrt (beta2) ; delta = (sigma > 0) ? (beta / beta2) : (beta2 / beta) ; gamma = sigma * CS_CONJ(alpha) / (beta2 * beta) ; Lx [p] = delta * Lx [p] + ((sigma > 0) ? (gamma * w [j]) : 0) ; beta = beta2 ; #ifdef CS_COMPLEX phase = CS_ABS (Lx [p]) / Lx [p] ; /* phase = abs(L(j,j))/L(j,j)*/ Lx [p] *= phase ; /* L(j,j) = L(j,j) * phase */ #endif for (p++ ; p < Lp [j+1] ; p++) { w1 = w [Li [p]] ; w [Li [p]] = w2 = w1 - alpha * Lx [p] ; Lx [p] = delta * Lx [p] + gamma * ((sigma > 0) ? w1 : w2) ; #ifdef CS_COMPLEX Lx [p] *= phase ; /* L(i,j) = L(i,j) * phase */ #endif } } cs_free (w) ; return (beta2 > 0) ; } leidenbase/src/Makevars.win0000644000176200001440000002502614457511147015442 0ustar liggesusersLIB_XML ?= $(MINGW_PREFIX) GLPK_HOME ?= $(MINGW_PREFIX) LIB_GMP ?= $(MINGW_PREFIX) PKG_CPPFLAGS = -I${LIB_XML}/include/libxml2 -I${LIB_XML}/include -DLIBXML_STATIC -DUSING_R \ -DHAVE_FMEMOPEN=0 -DHAVE_OPEN_MEMSTREAM=0 -DHAVE_RINTF -DHAVE_STRCASECMP -DWin32 \ -DHAVE_LIBXML=1 -DHAVE_UNISTD_H -Wall -DHAVE_FMIN=1 -DHAVE_LOG2=1 -DHAVE_GFORTRAN \ -DINTERNAL_ARPACK -I${GLPK_HOME}/include -DHAVE_GLPK=1 -DIGRAPH_THREAD_LOCAL= \ -DPRPACK_IGRAPH_SUPPORT -I. -Icore -Iinclude -Ivendor -DNDEBUG -DNTIMER -DNPRINT \ -I${LIB_GMP}/include -Ileidenalg -Ileidenbase PKG_LIBS = -L${LIB_XML}/lib -lxml2 -liconv -lz -lws2_32 -lstdc++ -L${GLPK_HOME}/lib \ -lglpk -lgmp -lgfortran -L$(LIB_GMP)/lib $(BLAS_LIBS) $(LAPACK_LIBS) # # Debian i386 fix. # # ifneq (,$(filter $(DEB_HOST_ARCH),i386)) # PKG_CPPFLAGS += -ffloat-store # endif OBJECTS=core/centrality/betweenness.o core/centrality/centrality_other.o core/centrality/centralization.o core/centrality/closeness.o core/centrality/coreness.o core/centrality/prpack.o core/centrality/prpack/prpack_base_graph.o core/centrality/prpack/prpack_igraph_graph.o core/centrality/prpack/prpack_preprocessed_ge_graph.o core/centrality/prpack/prpack_preprocessed_gs_graph.o core/centrality/prpack/prpack_preprocessed_scc_graph.o core/centrality/prpack/prpack_preprocessed_schur_graph.o core/centrality/prpack/prpack_result.o core/centrality/prpack/prpack_solver.o core/centrality/prpack/prpack_utils.o core/cliques/cliquer/cliquer.o core/cliques/cliquer/cliquer_graph.o core/cliques/cliquer/reorder.o core/cliques/cliquer_wrapper.o core/cliques/cliques.o core/cliques/glet.o core/cliques/maximal_cliques.o core/community/community_misc.o core/community/edge_betweenness.o core/community/fast_modularity.o core/community/fluid.o core/community/infomap/infomap.o core/community/infomap/infomap_FlowGraph.o core/community/infomap/infomap_Greedy.o core/community/infomap/infomap_Node.o core/community/label_propagation.o core/community/leading_eigenvector.o core/community/leiden.o core/community/louvain.o core/community/modularity.o core/community/optimal_modularity.o core/community/spinglass/NetDataTypes.o core/community/spinglass/NetRoutines.o core/community/spinglass/clustertool.o core/community/spinglass/pottsmodel_2.o core/community/walktrap/walktrap.o core/community/walktrap/walktrap_communities.o core/community/walktrap/walktrap_graph.o core/community/walktrap/walktrap_heap.o core/connectivity/cohesive_blocks.o core/connectivity/components.o core/connectivity/separators.o core/constructors/adjacency.o core/constructors/atlas.o core/constructors/basic_constructors.o core/constructors/de_bruijn.o core/constructors/famous.o core/constructors/full.o core/constructors/kautz.o core/constructors/lcf.o core/constructors/linegraph.o core/constructors/prufer.o core/constructors/regular.o core/core/array.o core/core/buckets.o core/core/cutheap.o core/core/dqueue.o core/core/error.o core/core/estack.o core/core/fixed_vectorlist.o core/core/grid.o core/core/heap.o core/core/indheap.o core/core/interruption.o core/core/marked_queue.o core/core/matrix.o core/core/memory.o core/core/printing.o core/core/progress.o core/core/psumtree.o core/core/set.o core/core/sparsemat.o core/core/spmatrix.o core/core/stack.o core/core/statusbar.o core/core/strvector.o core/core/trie.o core/core/vector.o core/core/vector_ptr.o core/flow/flow.o core/flow/st-cuts.o core/games/barabasi.o core/games/callaway_traits.o core/games/citations.o core/games/correlated.o core/games/degree_sequence.o core/games/degree_sequence_vl/gengraph_box_list.o core/games/degree_sequence_vl/gengraph_degree_sequence.o core/games/degree_sequence_vl/gengraph_graph_molloy_hash.o core/games/degree_sequence_vl/gengraph_graph_molloy_optimized.o core/games/degree_sequence_vl/gengraph_mr-connected.o core/games/degree_sequence_vl/gengraph_powerlaw.o core/games/degree_sequence_vl/gengraph_random.o core/games/dotproduct.o core/games/erdos_renyi.o core/games/establishment.o core/games/forestfire.o core/games/grg.o core/games/growing_random.o core/games/islands.o core/games/k_regular.o core/games/preference.o core/games/recent_degree.o core/games/sbm.o core/games/static_fitness.o core/games/tree.o core/games/watts_strogatz.o core/graph/adjlist.o core/graph/attributes.o core/graph/basic_query.o core/graph/cattributes.o core/graph/iterators.o core/graph/type_indexededgelist.o core/graph/visitors.o core/hrg/hrg.o core/hrg/hrg_types.o core/internal/glpk_support.o core/internal/hacks.o core/internal/lsap.o core/internal/qsort.o core/internal/qsort_r.o core/internal/zeroin.o core/io/dimacs.o core/io/dl-lexer.o core/io/dl-parser.o core/io/dl.o core/io/dot.o core/io/edgelist.o core/io/gml-lexer.o core/io/gml-parser.o core/io/gml-tree.o core/io/gml.o core/io/graphdb.o core/io/graphml.o core/io/leda.o core/io/lgl-lexer.o core/io/lgl-parser.o core/io/lgl.o core/io/ncol-lexer.o core/io/ncol-parser.o core/io/ncol.o core/io/pajek-lexer.o core/io/pajek-parser.o core/io/pajek.o core/isomorphism/bliss.o core/isomorphism/bliss/defs.o core/isomorphism/bliss/graph.o core/isomorphism/bliss/heap.o core/isomorphism/bliss/orbit.o core/isomorphism/bliss/partition.o core/isomorphism/bliss/uintseqhash.o core/isomorphism/bliss/utils.o core/isomorphism/isoclasses.o core/isomorphism/isomorphism_misc.o core/isomorphism/lad.o core/isomorphism/queries.o core/isomorphism/vf2.o core/layout/circular.o core/layout/davidson_harel.o core/layout/drl/DensityGrid.o core/layout/drl/DensityGrid_3d.o core/layout/drl/drl_graph.o core/layout/drl/drl_graph_3d.o core/layout/drl/drl_layout.o core/layout/drl/drl_layout_3d.o core/layout/drl/drl_parse.o core/layout/fruchterman_reingold.o core/layout/gem.o core/layout/graphopt.o core/layout/kamada_kawai.o core/layout/large_graph.o core/layout/layout_bipartite.o core/layout/layout_grid.o core/layout/layout_random.o core/layout/mds.o core/layout/merge_dla.o core/layout/merge_grid.o core/layout/reingold_tilford.o core/layout/sugiyama.o core/linalg/arpack.o core/linalg/blas.o core/linalg/eigen.o core/linalg/lapack.o core/math/bfgs.o core/math/complex.o core/math/utils.o core/misc/bipartite.o core/misc/chordality.o core/misc/cocitation.o core/misc/coloring.o core/misc/conversion.o core/misc/degree_sequence.o core/misc/embedding.o core/misc/feedback_arc_set.o core/misc/graphicality.o core/misc/matching.o core/misc/microscopic_update.o core/misc/mixing.o core/misc/motifs.o core/misc/other.o core/misc/scan.o core/misc/sir.o core/misc/spanning_trees.o core/operators/add_edge.o core/operators/complementer.o core/operators/compose.o core/operators/connect_neighborhood.o core/operators/contract.o core/operators/difference.o core/operators/disjoint_union.o core/operators/intersection.o core/operators/misc_internal.o core/operators/permute.o core/operators/rewire.o core/operators/rewire_edges.o core/operators/simplify.o core/operators/subgraph.o core/operators/union.o core/paths/all_shortest_paths.o core/paths/bellman_ford.o core/paths/dijkstra.o core/paths/distances.o core/paths/eulerian.o core/paths/histogram.o core/paths/johnson.o core/paths/random_walk.o core/paths/shortest_paths.o core/paths/simple_paths.o core/paths/unweighted.o core/properties/basic_properties.o core/properties/constraint.o core/properties/convergence_degree.o core/properties/dag.o core/properties/degrees.o core/properties/girth.o core/properties/loops.o core/properties/multiplicity.o core/properties/neighborhood.o core/properties/spectral.o core/properties/trees.o core/properties/triangles.o core/random/random.o core/scg/scg.o core/scg/scg_approximate_methods.o core/scg/scg_exact_scg.o core/scg/scg_kmeans.o core/scg/scg_optimal_method.o core/scg/scg_utils.o core/version.o vendor/cs/cs_add.o vendor/cs/cs_amd.o vendor/cs/cs_chol.o vendor/cs/cs_cholsol.o vendor/cs/cs_compress.o vendor/cs/cs_counts.o vendor/cs/cs_cumsum.o vendor/cs/cs_dfs.o vendor/cs/cs_dmperm.o vendor/cs/cs_droptol.o vendor/cs/cs_dropzeros.o vendor/cs/cs_dupl.o vendor/cs/cs_entry.o vendor/cs/cs_ereach.o vendor/cs/cs_etree.o vendor/cs/cs_fkeep.o vendor/cs/cs_gaxpy.o vendor/cs/cs_happly.o vendor/cs/cs_house.o vendor/cs/cs_ipvec.o vendor/cs/cs_leaf.o vendor/cs/cs_load.o vendor/cs/cs_lsolve.o vendor/cs/cs_ltsolve.o vendor/cs/cs_lu.o vendor/cs/cs_lusol.o vendor/cs/cs_malloc.o vendor/cs/cs_maxtrans.o vendor/cs/cs_multiply.o vendor/cs/cs_norm.o vendor/cs/cs_permute.o vendor/cs/cs_pinv.o vendor/cs/cs_post.o vendor/cs/cs_print.o vendor/cs/cs_pvec.o vendor/cs/cs_qr.o vendor/cs/cs_qrsol.o vendor/cs/cs_randperm.o vendor/cs/cs_reach.o vendor/cs/cs_scatter.o vendor/cs/cs_scc.o vendor/cs/cs_schol.o vendor/cs/cs_spsolve.o vendor/cs/cs_sqr.o vendor/cs/cs_symperm.o vendor/cs/cs_tdfs.o vendor/cs/cs_transpose.o vendor/cs/cs_updown.o vendor/cs/cs_usolve.o vendor/cs/cs_util.o vendor/cs/cs_utsolve.o vendor/mini-gmp/mini-gmp.o vendor/plfit/gss.o vendor/plfit/hzeta.o vendor/plfit/kolmogorov.o vendor/plfit/lbfgs.o vendor/plfit/mt.o vendor/plfit/options.o vendor/plfit/platform.o vendor/plfit/plfit.o vendor/plfit/plfit_error.o vendor/plfit/rbinom.o vendor/plfit/sampling.o vendor/arpack/dgetv0.o vendor/arpack/dlaqrb.o vendor/arpack/dmout.o vendor/arpack/dnaitr.o vendor/arpack/dnapps.o vendor/arpack/dnaup2.o vendor/arpack/dnaupd.o vendor/arpack/dnconv.o vendor/arpack/dneigh.o vendor/arpack/dneupd.o vendor/arpack/dngets.o vendor/arpack/dsaitr.o vendor/arpack/dsapps.o vendor/arpack/dsaup2.o vendor/arpack/dsaupd.o vendor/arpack/dsconv.o vendor/arpack/dseigt.o vendor/arpack/dsesrt.o vendor/arpack/dseupd.o vendor/arpack/dsgets.o vendor/arpack/dsortc.o vendor/arpack/dsortr.o vendor/arpack/dstatn.o vendor/arpack/dstats.o vendor/arpack/dstqrb.o vendor/arpack/dvout.o vendor/arpack/ivout.o vendor/arpack/second.o vendor/arpack/wrap.o vendor/simpleraytracer/Color.o vendor/simpleraytracer/Light.o vendor/simpleraytracer/Point.o vendor/simpleraytracer/RIgraphRay.o vendor/simpleraytracer/Ray.o vendor/simpleraytracer/RayTracer.o vendor/simpleraytracer/RayVector.o vendor/simpleraytracer/Shape.o vendor/simpleraytracer/Sphere.o vendor/simpleraytracer/Triangle.o vendor/simpleraytracer/unit_limiter.o vendor/uuid/R.o vendor/uuid/clear.o vendor/uuid/compare.o vendor/uuid/copy.o vendor/uuid/gen_uuid.o vendor/uuid/isnull.o vendor/uuid/pack.o vendor/uuid/parse.o vendor/uuid/unpack.o vendor/uuid/unparse.o leidenalg/CPMVertexPartition.o leidenalg/GraphHelper.o leidenalg/LinearResolutionParameterVertexPartition.o leidenalg/ModularityVertexPartition.o leidenalg/MutableVertexPartition.o leidenalg/Optimiser.o leidenalg/RBConfigurationVertexPartition.o leidenalg/RBERVertexPartition.o leidenalg/ResolutionParameterVertexPartition.o leidenalg/SignificanceVertexPartition.o leidenalg/SurpriseVertexPartition.o leidenbase/leidenFindPartition.o leidenbase/leidenFindPartitionR2C.o leidenbase/src/f2c.h0000644000176200001440000001227414447604640013776 0ustar liggesusers/* f2c.h -- Standard Fortran to C header file */ /** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ #ifndef F2C_INCLUDE #define F2C_INCLUDE #include "linalg/blas_internal.h" #include "linalg/lapack_internal.h" #include "linalg/arpack_internal.h" typedef int integer; typedef unsigned int uinteger; typedef char *address; typedef short int shortint; typedef float real; typedef double doublereal; typedef struct { real r, i; } f2c_complex; typedef struct { doublereal r, i; } doublecomplex; typedef int logical; typedef short int shortlogical; typedef char logical1; typedef char integer1; #ifdef INTEGER_STAR_8 /* Adjust for integer*8. */ typedef long longint; /* system-dependent */ typedef unsigned long ulongint; /* system-dependent */ #define qbit_clear(a,b) ((a) & ~((ulongint)1 << (b))) #define qbit_set(a,b) ((a) | ((ulongint)1 << (b))) #endif #define TRUE_ (1) #define FALSE_ (0) /* Extern is for use with -E */ #ifndef Extern #define Extern extern #endif /* I/O stuff */ #ifdef f2c_i2 /* for -i2 */ typedef short flag; typedef short ftnlen; typedef short ftnint; #else typedef int flag; typedef int ftnlen; typedef int ftnint; #endif /*external read, write*/ typedef struct { flag cierr; ftnint ciunit; flag ciend; char *cifmt; ftnint cirec; } cilist; /*internal read, write*/ typedef struct { flag icierr; char *iciunit; flag iciend; char *icifmt; ftnint icirlen; ftnint icirnum; } icilist; /*open*/ typedef struct { flag oerr; ftnint ounit; char *ofnm; ftnlen ofnmlen; char *osta; char *oacc; char *ofm; ftnint orl; char *oblnk; } olist; /*close*/ typedef struct { flag cerr; ftnint cunit; char *csta; } cllist; /*rewind, backspace, endfile*/ typedef struct { flag aerr; ftnint aunit; } alist; /* inquire */ typedef struct { flag inerr; ftnint inunit; char *infile; ftnlen infilen; ftnint *inex; /*parameters in standard's order*/ ftnint *inopen; ftnint *innum; ftnint *innamed; char *inname; ftnlen innamlen; char *inacc; ftnlen inacclen; char *inseq; ftnlen inseqlen; char *indir; ftnlen indirlen; char *infmt; ftnlen infmtlen; char *inform; ftnint informlen; char *inunf; ftnlen inunflen; ftnint *inrecl; ftnint *innrec; char *inblank; ftnlen inblanklen; } inlist; #define VOID void union Multitype { /* for multiple entry points */ integer1 g; shortint h; integer i; /* longint j; */ real r; doublereal d; f2c_complex c; doublecomplex z; }; typedef union Multitype Multitype; /*typedef long int Long;*/ /* No longer used; formerly in Namelist */ struct Vardesc { /* for Namelist */ char *name; char *addr; ftnlen *dims; int type; }; typedef struct Vardesc Vardesc; struct Namelist { char *name; Vardesc **vars; int nvars; }; typedef struct Namelist Namelist; #define abs(x) ((x) >= 0 ? (x) : -(x)) #define dabs(x) (doublereal)abs(x) #ifndef min #define min(a,b) ((a) <= (b) ? (a) : (b)) #endif #ifndef max #define max(a,b) ((a) >= (b) ? (a) : (b)) #endif #define dmin(a,b) (doublereal)min(a,b) #define dmax(a,b) (doublereal)max(a,b) #define bit_test(a,b) ((a) >> (b) & 1) #define bit_clear(a,b) ((a) & ~((uinteger)1 << (b))) #define bit_set(a,b) ((a) | ((uinteger)1 << (b))) /* procedure parameter types for -A and -C++ */ #define F2C_proc_par_types 1 #ifdef __cplusplus typedef int /* Unknown procedure type */ (*U_fp)(...); typedef shortint (*J_fp)(...); typedef integer (*I_fp)(...); typedef real (*R_fp)(...); typedef doublereal (*D_fp)(...), (*E_fp)(...); typedef /* Complex */ VOID (*C_fp)(...); typedef /* Double Complex */ VOID (*Z_fp)(...); typedef logical (*L_fp)(...); typedef shortlogical (*K_fp)(...); typedef /* Character */ VOID (*H_fp)(...); typedef /* Subroutine */ int (*S_fp)(...); #else typedef int /* Unknown procedure type */ (*U_fp)(); typedef shortint (*J_fp)(); typedef integer (*I_fp)(); typedef real (*R_fp)(); typedef doublereal (*D_fp)(), (*E_fp)(); typedef /* Complex */ VOID (*C_fp)(); typedef /* Double Complex */ VOID (*Z_fp)(); typedef logical (*L_fp)(); typedef shortlogical (*K_fp)(); typedef /* Character */ VOID (*H_fp)(); typedef /* Subroutine */ int (*S_fp)(); #endif /* E_fp is for real functions when -R is not specified */ typedef VOID C_f; /* complex function */ typedef VOID H_f; /* character function */ typedef VOID Z_f; /* double complex function */ typedef doublereal E_f; /* real function with -R not specified */ /* undef any lower-case symbols that your C compiler predefines, e.g.: */ #ifndef Skip_f2c_Undefs #undef cray #undef gcos #undef mc68010 #undef mc68020 #undef mips #undef pdp11 #undef sgi #undef sparc #undef sun #undef sun2 #undef sun3 #undef sun4 #undef u370 #undef u3b #undef u3b2 #undef u3b5 #undef unix #undef vax #endif #include "config.h" #endif leidenbase/src/core/0000755000176200001440000000000014532173045014070 5ustar liggesusersleidenbase/src/core/community/0000755000176200001440000000000014532173045016114 5ustar liggesusersleidenbase/src/core/community/walktrap/0000755000176200001440000000000014532173045017741 5ustar liggesusersleidenbase/src/core/community/walktrap/walktrap_communities.h0000644000176200001440000001561014447675374024377 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Pascal Pons The original copyright notice follows here. The FSF address was fixed by Tamas Nepusz */ // File: communities.h //----------------------------------------------------------------------------- // Walktrap v0.2 -- Finds community structure of networks using random walks // Copyright (C) 2004-2005 Pascal Pons // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301 USA //----------------------------------------------------------------------------- // Author : Pascal Pons // Email : pascal.pons@gmail.com // Web page : http://www-rp.lip6.fr/~latapy/PP/walktrap.html // Location : Paris, France // Time : June 2005 //----------------------------------------------------------------------------- // see readme.txt for more details #ifndef WALKTRAP_COMMUNITIES_H #define WALKTRAP_COMMUNITIES_H #include "walktrap_graph.h" #include "walktrap_heap.h" #include "igraph_community.h" #include "config.h" namespace igraph { namespace walktrap { class Communities; class Probabilities { public: static IGRAPH_THREAD_LOCAL float* tmp_vector1; // static IGRAPH_THREAD_LOCAL float* tmp_vector2; // static IGRAPH_THREAD_LOCAL int* id; // static IGRAPH_THREAD_LOCAL int* vertices1; // static IGRAPH_THREAD_LOCAL int* vertices2; // static IGRAPH_THREAD_LOCAL int current_id; // static IGRAPH_THREAD_LOCAL Communities* C; // pointer to all the communities static IGRAPH_THREAD_LOCAL int length; // length of the random walks int size; // number of probabilities stored int* vertices; // the vertices corresponding to the stored probabilities, 0 if all the probabilities are stored float* P; // the probabilities long memory(); // the memory (in Bytes) used by the object double compute_distance(const Probabilities* P2) const; // compute the squared distance r^2 between this probability vector and P2 Probabilities(int community); // compute the probability vector of a community Probabilities(int community1, int community2); // merge the probability vectors of two communities in a new one // the two communities must have their probability vectors stored ~Probabilities(); // destructor }; class Community { public: Neighbor* first_neighbor; // first item of the list of adjacent communities Neighbor* last_neighbor; // last item of the list of adjacent communities int this_community; // number of this community int first_member; // number of the first vertex of the community int last_member; // number of the last vertex of the community int size; // number of members of the community Probabilities* P; // the probability vector, 0 if not stored. float sigma; // sigma(C) of the community float internal_weight; // sum of the weight of the internal edges float total_weight; // sum of the weight of all the edges of the community (an edge between two communities is a half-edge for each community) int sub_communities[2]; // the two sub sommunities, -1 if no sub communities; int sub_community_of; // number of the community in which this community has been merged // 0 if the community is active // -1 if the community is not used void merge(Community &C1, Community &C2); // create a new community by merging C1 an C2 void add_neighbor(Neighbor* N); void remove_neighbor(Neighbor* N); float min_delta_sigma(); // compute the minimal delta sigma among all the neighbors of this community Community(); // create an empty community ~Community(); // destructor }; class Communities { private: long max_memory; // size in Byte of maximal memory usage, -1 for no limit igraph_matrix_t *merges; long int mergeidx; igraph_vector_t *modularity; public: long memory_used; // in bytes Min_delta_sigma_heap* min_delta_sigma; // the min delta_sigma of the community with a saved probability vector (for memory management) Graph* G; // the graph int* members; // the members of each community represented as a chained list. // a community points to the first_member the array which contains // the next member (-1 = end of the community) Neighbor_heap* H; // the distances between adjacent communities. Community* communities; // array of the communities int nb_communities; // number of valid communities int nb_active_communities; // number of active communities Communities(Graph* G, int random_walks_length = 3, long max_memory = -1, igraph_matrix_t *merges = 0, igraph_vector_t *modularity = 0); // Constructor ~Communities(); // Destructor void merge_communities(Neighbor* N); // create a community by merging two existing communities double merge_nearest_communities(); double compute_delta_sigma(int c1, int c2); // compute delta_sigma(c1,c2) void remove_neighbor(Neighbor* N); void add_neighbor(Neighbor* N); void update_neighbor(Neighbor* N, float new_delta_sigma); void manage_memory(); }; } } /* end of namespaces */ #endif // WALKTRAP_COMMUNITIES_H leidenbase/src/core/community/walktrap/walktrap_graph.cpp0000644000176200001440000001521614447675374023501 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Pascal Pons The original copyright notice follows here. The FSF address was fixed by Tamas Nepusz */ // File: graph.cpp //----------------------------------------------------------------------------- // Walktrap v0.2 -- Finds community structure of networks using random walks // Copyright (C) 2004-2005 Pascal Pons // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301 USA //----------------------------------------------------------------------------- // Author : Pascal Pons // Email : pascal.pons@gmail.com // Web page : http://www-rp.lip6.fr/~latapy/PP/walktrap.html // Location : Paris, France // Time : June 2005 //----------------------------------------------------------------------------- // see readme.txt for more details #include "walktrap_graph.h" #include "igraph_interface.h" #include #include // strlen using namespace std; namespace igraph { namespace walktrap { bool operator<(const Edge& E1, const Edge& E2) { return (E1.neighbor < E2.neighbor); } Vertex::Vertex() { degree = 0; edges = 0; total_weight = 0.; } Vertex::~Vertex() { if (edges) { delete[] edges; } } Graph::Graph() { nb_vertices = 0; nb_edges = 0; vertices = 0; index = 0; total_weight = 0.; } Graph::~Graph () { if (vertices) { delete[] vertices; } } class Edge_list { public: int* V1; int* V2; float* W; int size; int size_max; void add(int v1, int v2, float w); Edge_list() { size = 0; size_max = 1024; V1 = new int[1024]; V2 = new int[1024]; W = new float[1024]; } ~Edge_list() { if (V1) { delete[] V1; } if (V2) { delete[] V2; } if (W) { delete[] W; } } }; void Edge_list::add(int v1, int v2, float w) { if (size == size_max) { int* tmp1 = new int[2 * size_max]; int* tmp2 = new int[2 * size_max]; float* tmp3 = new float[2 * size_max]; for (int i = 0; i < size_max; i++) { tmp1[i] = V1[i]; tmp2[i] = V2[i]; tmp3[i] = W[i]; } delete[] V1; delete[] V2; delete[] W; V1 = tmp1; V2 = tmp2; W = tmp3; size_max *= 2; } V1[size] = v1; V2[size] = v2; W[size] = w; size++; } int Graph::convert_from_igraph(const igraph_t *graph, const igraph_vector_t *weights) { Graph &G = *this; int max_vertex = (int)igraph_vcount(graph) - 1; long int no_of_edges = (long int)igraph_ecount(graph); long int i; long int deg; double w; Edge_list EL; for (i = 0; i < no_of_edges; i++) { igraph_integer_t from, to; int v1, v2; w = weights ? VECTOR(*weights)[i] : 1.0; igraph_edge(graph, i, &from, &to); v1 = (int)from; v2 = (int)to; EL.add(v1, v2, w); } G.nb_vertices = max_vertex + 1; G.vertices = new Vertex[G.nb_vertices]; G.nb_edges = 0; G.total_weight = 0.0; for (int i = 0; i < EL.size; i++) { G.vertices[EL.V1[i]].degree++; G.vertices[EL.V2[i]].degree++; G.vertices[EL.V1[i]].total_weight += EL.W[i]; G.vertices[EL.V2[i]].total_weight += EL.W[i]; G.nb_edges++; G.total_weight += EL.W[i]; } for (int i = 0; i < G.nb_vertices; i++) { deg = G.vertices[i].degree; w = (deg == 0) ? 1.0 : (G.vertices[i].total_weight / double(deg)); G.vertices[i].edges = new Edge[deg + 1]; G.vertices[i].edges[0].neighbor = i; G.vertices[i].edges[0].weight = w; G.vertices[i].total_weight += w; G.vertices[i].degree = 1; } for (int i = 0; i < EL.size; i++) { G.vertices[EL.V1[i]].edges[G.vertices[EL.V1[i]].degree].neighbor = EL.V2[i]; G.vertices[EL.V1[i]].edges[G.vertices[EL.V1[i]].degree].weight = EL.W[i]; G.vertices[EL.V1[i]].degree++; G.vertices[EL.V2[i]].edges[G.vertices[EL.V2[i]].degree].neighbor = EL.V1[i]; G.vertices[EL.V2[i]].edges[G.vertices[EL.V2[i]].degree].weight = EL.W[i]; G.vertices[EL.V2[i]].degree++; } for (int i = 0; i < G.nb_vertices; i++) { sort(G.vertices[i].edges, G.vertices[i].edges + G.vertices[i].degree); } for (int i = 0; i < G.nb_vertices; i++) { // merge multi edges int a = 0; for (int b = 1; b < G.vertices[i].degree; b++) { if (G.vertices[i].edges[b].neighbor == G.vertices[i].edges[a].neighbor) { G.vertices[i].edges[a].weight += G.vertices[i].edges[b].weight; } else { G.vertices[i].edges[++a] = G.vertices[i].edges[b]; } } G.vertices[i].degree = a + 1; } return 0; } long Graph::memory() { size_t m = 0; m += size_t(nb_vertices) * sizeof(Vertex); m += 2 * size_t(nb_edges) * sizeof(Edge); m += sizeof(Graph); if (index != 0) { m += size_t(nb_vertices) * sizeof(char*); for (int i = 0; i < nb_vertices; i++) { m += strlen(index[i]) + 1; } } return m; } } } leidenbase/src/core/community/walktrap/walktrap.cpp0000644000176200001440000001606014447675374022316 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Pascal Pons The original copyright notice follows here. The FSF address was fixed by Tamas Nepusz */ // File: walktrap.cpp //----------------------------------------------------------------------------- // Walktrap v0.2 -- Finds community structure of networks using random walks // Copyright (C) 2004-2005 Pascal Pons // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301 USA //----------------------------------------------------------------------------- // Author : Pascal Pons // Email : pascal.pons@gmail.com // Web page : http://www-rp.lip6.fr/~latapy/PP/walktrap.html // Location : Paris, France // Time : June 2005 //----------------------------------------------------------------------------- // see readme.txt for more details #include "walktrap_graph.h" #include "walktrap_communities.h" #include "igraph_community.h" #include "igraph_components.h" #include "igraph_interface.h" #include "core/exceptions.h" #include "core/interruption.h" using namespace igraph::walktrap; /** * \function igraph_community_walktrap * * This function is the implementation of the Walktrap community * finding algorithm, see Pascal Pons, Matthieu Latapy: Computing * communities in large networks using random walks, * https://arxiv.org/abs/physics/0512106 * * * Currently the original C++ implementation is used in igraph, * see https://www-complexnetworks.lip6.fr/~latapy/PP/walktrap.html * We are grateful to Matthieu Latapy and Pascal Pons for providing this * source code. * * * In contrast to the original implementation, isolated vertices are allowed * in the graph and they are assumed to have a single incident loop edge with * weight 1. * * \param graph The input graph, edge directions are ignored. * \param weights Numeric vector giving the weights of the edges. * If it is a NULL pointer then all edges will have equal * weights. The weights are expected to be positive. * \param steps Integer constant, the length of the random walks. * Typically, good results are obtained with values between * 3-8 with 4-5 being a reasonable default. * \param merges Pointer to a matrix, the merges performed by the * algorithm will be stored here (if not NULL). Each merge is a * row in a two-column matrix and contains the ids of the merged * clusters. Clusters are numbered from zero and cluster numbers * smaller than the number of nodes in the network belong to the * individual vertices as singleton clusters. In each step a new * cluster is created from two other clusters and its id will be * one larger than the largest cluster id so far. This means that * before the first merge we have \c n clusters (the number of * vertices in the graph) numbered from zero to \c n-1. The first * merge creates cluster \c n, the second cluster \c n+1, etc. * \param modularity Pointer to a vector. If not NULL then the * modularity score of the current clustering is stored here after * each merge operation. * \param membership Pointer to a vector. If not a NULL pointer, then * the membership vector corresponding to the maximal modularity * score is stored here. If it is not a NULL pointer, then neither * \p modularity nor \p merges may be NULL. * \return Error code. * * \sa \ref igraph_community_spinglass(), \ref * igraph_community_edge_betweenness(). * * Time complexity: O(|E||V|^2) in the worst case, O(|V|^2 log|V|) typically, * |V| is the number of vertices, |E| is the number of edges. * * \example examples/simple/walktrap.c */ int igraph_community_walktrap(const igraph_t *graph, const igraph_vector_t *weights, int steps, igraph_matrix_t *merges, igraph_vector_t *modularity, igraph_vector_t *membership) { IGRAPH_HANDLE_EXCEPTIONS( long int no_of_nodes = (long int)igraph_vcount(graph); int length = steps; long max_memory = -1; if (steps <= 0) { IGRAPH_ERROR("Length of random walks must be positive for walktrap community detection.", IGRAPH_EINVAL); } if (membership && !(modularity && merges)) { IGRAPH_ERROR("Cannot calculate membership without modularity or merges", IGRAPH_EINVAL); } Graph G; if (G.convert_from_igraph(graph, weights)) { IGRAPH_ERROR("Cannot convert igraph graph into walktrap format", IGRAPH_EINVAL); } if (merges) { igraph_integer_t no; IGRAPH_CHECK(igraph_clusters(graph, /*membership=*/ 0, /*csize=*/ 0, &no, IGRAPH_WEAK)); IGRAPH_CHECK(igraph_matrix_resize(merges, no_of_nodes - no, 2)); } if (modularity) { IGRAPH_CHECK(igraph_vector_resize(modularity, no_of_nodes)); igraph_vector_null(modularity); } Communities C(&G, length, max_memory, merges, modularity); while (!C.H->is_empty()) { IGRAPH_ALLOW_INTERRUPTION(); C.merge_nearest_communities(); } if (membership) { long int m; m = no_of_nodes > 0 ? igraph_vector_which_max(modularity) : 0; IGRAPH_CHECK(igraph_community_to_membership(merges, no_of_nodes, /*steps=*/ m, membership, /*csize=*/ NULL)); } return IGRAPH_SUCCESS; ) } leidenbase/src/core/community/walktrap/walktrap_communities.cpp0000644000176200001440000010204114447675374024725 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Pascal Pons The original copyright notice follows here. The FSF address was fixed by Tamas Nepusz */ // File: communities.cpp //----------------------------------------------------------------------------- // Walktrap v0.2 -- Finds community structure of networks using random walks // Copyright (C) 2004-2005 Pascal Pons // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301 USA //----------------------------------------------------------------------------- // Author : Pascal Pons // Email : pascal.pons@gmail.com // Web page : http://www-rp.lip6.fr/~latapy/PP/walktrap.html // Location : Paris, France // Time : June 2005 //----------------------------------------------------------------------------- // see readme.txt for more details #include "walktrap_communities.h" #include "config.h" #include #include using namespace std; namespace igraph { namespace walktrap { IGRAPH_THREAD_LOCAL int Probabilities::length = 0; IGRAPH_THREAD_LOCAL Communities* Probabilities::C = 0; IGRAPH_THREAD_LOCAL float* Probabilities::tmp_vector1 = 0; IGRAPH_THREAD_LOCAL float* Probabilities::tmp_vector2 = 0; IGRAPH_THREAD_LOCAL int* Probabilities::id = 0; IGRAPH_THREAD_LOCAL int* Probabilities::vertices1 = 0; IGRAPH_THREAD_LOCAL int* Probabilities::vertices2 = 0; IGRAPH_THREAD_LOCAL int Probabilities::current_id = 0; Neighbor::Neighbor() { next_community1 = 0; previous_community1 = 0; next_community2 = 0; previous_community2 = 0; heap_index = -1; } Probabilities::~Probabilities() { C->memory_used -= memory(); if (P) { delete[] P; } if (vertices) { delete[] vertices; } } Probabilities::Probabilities(int community) { Graph* G = C->G; int nb_vertices1 = 0; int nb_vertices2 = 0; float initial_proba = 1. / float(C->communities[community].size); int last = C->members[C->communities[community].last_member]; for (int m = C->communities[community].first_member; m != last; m = C->members[m]) { tmp_vector1[m] = initial_proba; vertices1[nb_vertices1++] = m; } for (int t = 0; t < length; t++) { current_id++; if (nb_vertices1 > (G->nb_vertices / 2)) { nb_vertices2 = G->nb_vertices; for (int i = 0; i < G->nb_vertices; i++) { tmp_vector2[i] = 0.; } if (nb_vertices1 == G->nb_vertices) { for (int i = 0; i < G->nb_vertices; i++) { float proba = tmp_vector1[i] / G->vertices[i].total_weight; for (int j = 0; j < G->vertices[i].degree; j++) { tmp_vector2[G->vertices[i].edges[j].neighbor] += proba * G->vertices[i].edges[j].weight; } } } else { for (int i = 0; i < nb_vertices1; i++) { int v1 = vertices1[i]; float proba = tmp_vector1[v1] / G->vertices[v1].total_weight; for (int j = 0; j < G->vertices[v1].degree; j++) { tmp_vector2[G->vertices[v1].edges[j].neighbor] += proba * G->vertices[v1].edges[j].weight; } } } } else { nb_vertices2 = 0; for (int i = 0; i < nb_vertices1; i++) { int v1 = vertices1[i]; float proba = tmp_vector1[v1] / G->vertices[v1].total_weight; for (int j = 0; j < G->vertices[v1].degree; j++) { int v2 = G->vertices[v1].edges[j].neighbor; if (id[v2] == current_id) { tmp_vector2[v2] += proba * G->vertices[v1].edges[j].weight; } else { tmp_vector2[v2] = proba * G->vertices[v1].edges[j].weight; id[v2] = current_id; vertices2[nb_vertices2++] = v2; } } } } float* tmp = tmp_vector2; tmp_vector2 = tmp_vector1; tmp_vector1 = tmp; int* tmp2 = vertices2; vertices2 = vertices1; vertices1 = tmp2; nb_vertices1 = nb_vertices2; } if (nb_vertices1 > (G->nb_vertices / 2)) { P = new float[G->nb_vertices]; size = G->nb_vertices; vertices = 0; if (nb_vertices1 == G->nb_vertices) { for (int i = 0; i < G->nb_vertices; i++) { P[i] = tmp_vector1[i] / sqrt(G->vertices[i].total_weight); } } else { for (int i = 0; i < G->nb_vertices; i++) { P[i] = 0.; } for (int i = 0; i < nb_vertices1; i++) { P[vertices1[i]] = tmp_vector1[vertices1[i]] / sqrt(G->vertices[vertices1[i]].total_weight); } } } else { P = new float[nb_vertices1]; size = nb_vertices1; vertices = new int[nb_vertices1]; int j = 0; for (int i = 0; i < G->nb_vertices; i++) { if (id[i] == current_id) { P[j] = tmp_vector1[i] / sqrt(G->vertices[i].total_weight); vertices[j] = i; j++; } } } C->memory_used += memory(); } Probabilities::Probabilities(int community1, int community2) { // The two following probability vectors must exist. // Do not call this function if it is not the case. Probabilities* P1 = C->communities[community1].P; Probabilities* P2 = C->communities[community2].P; float w1 = float(C->communities[community1].size) / float(C->communities[community1].size + C->communities[community2].size); float w2 = float(C->communities[community2].size) / float(C->communities[community1].size + C->communities[community2].size); if (P1->size == C->G->nb_vertices) { P = new float[C->G->nb_vertices]; size = C->G->nb_vertices; vertices = 0; if (P2->size == C->G->nb_vertices) { // two full vectors for (int i = 0; i < C->G->nb_vertices; i++) { P[i] = P1->P[i] * w1 + P2->P[i] * w2; } } else { // P1 full vector, P2 partial vector int j = 0; for (int i = 0; i < P2->size; i++) { for (; j < P2->vertices[i]; j++) { P[j] = P1->P[j] * w1; } P[j] = P1->P[j] * w1 + P2->P[i] * w2; j++; } for (; j < C->G->nb_vertices; j++) { P[j] = P1->P[j] * w1; } } } else { if (P2->size == C->G->nb_vertices) { // P1 partial vector, P2 full vector P = new float[C->G->nb_vertices]; size = C->G->nb_vertices; vertices = 0; int j = 0; for (int i = 0; i < P1->size; i++) { for (; j < P1->vertices[i]; j++) { P[j] = P2->P[j] * w2; } P[j] = P1->P[i] * w1 + P2->P[j] * w2; j++; } for (; j < C->G->nb_vertices; j++) { P[j] = P2->P[j] * w2; } } else { // two partial vectors int i = 0; int j = 0; int nb_vertices1 = 0; while ((i < P1->size) && (j < P2->size)) { if (P1->vertices[i] < P2->vertices[j]) { tmp_vector1[P1->vertices[i]] = P1->P[i] * w1; vertices1[nb_vertices1++] = P1->vertices[i]; i++; continue; } if (P1->vertices[i] > P2->vertices[j]) { tmp_vector1[P2->vertices[j]] = P2->P[j] * w2; vertices1[nb_vertices1++] = P2->vertices[j]; j++; continue; } tmp_vector1[P1->vertices[i]] = P1->P[i] * w1 + P2->P[j] * w2; vertices1[nb_vertices1++] = P1->vertices[i]; i++; j++; } if (i == P1->size) { for (; j < P2->size; j++) { tmp_vector1[P2->vertices[j]] = P2->P[j] * w2; vertices1[nb_vertices1++] = P2->vertices[j]; } } else { for (; i < P1->size; i++) { tmp_vector1[P1->vertices[i]] = P1->P[i] * w1; vertices1[nb_vertices1++] = P1->vertices[i]; } } if (nb_vertices1 > (C->G->nb_vertices / 2)) { P = new float[C->G->nb_vertices]; size = C->G->nb_vertices; vertices = 0; for (int i = 0; i < C->G->nb_vertices; i++) { P[i] = 0.; } for (int i = 0; i < nb_vertices1; i++) { P[vertices1[i]] = tmp_vector1[vertices1[i]]; } } else { P = new float[nb_vertices1]; size = nb_vertices1; vertices = new int[nb_vertices1]; for (int i = 0; i < nb_vertices1; i++) { vertices[i] = vertices1[i]; P[i] = tmp_vector1[vertices1[i]]; } } } } C->memory_used += memory(); } double Probabilities::compute_distance(const Probabilities* P2) const { double r = 0.; if (vertices) { if (P2->vertices) { // two partial vectors int i = 0; int j = 0; while ((i < size) && (j < P2->size)) { if (vertices[i] < P2->vertices[j]) { r += P[i] * P[i]; i++; continue; } if (vertices[i] > P2->vertices[j]) { r += P2->P[j] * P2->P[j]; j++; continue; } r += (P[i] - P2->P[j]) * (P[i] - P2->P[j]); i++; j++; } if (i == size) { for (; j < P2->size; j++) { r += P2->P[j] * P2->P[j]; } } else { for (; i < size; i++) { r += P[i] * P[i]; } } } else { // P1 partial vector, P2 full vector int i = 0; for (int j = 0; j < size; j++) { for (; i < vertices[j]; i++) { r += P2->P[i] * P2->P[i]; } r += (P[j] - P2->P[i]) * (P[j] - P2->P[i]); i++; } for (; i < P2->size; i++) { r += P2->P[i] * P2->P[i]; } } } else { if (P2->vertices) { // P1 full vector, P2 partial vector int i = 0; for (int j = 0; j < P2->size; j++) { for (; i < P2->vertices[j]; i++) { r += P[i] * P[i]; } r += (P[i] - P2->P[j]) * (P[i] - P2->P[j]); i++; } for (; i < size; i++) { r += P[i] * P[i]; } } else { // two full vectors for (int i = 0; i < size; i++) { r += (P[i] - P2->P[i]) * (P[i] - P2->P[i]); } } } return r; } long Probabilities::memory() { if (vertices) { return (sizeof(Probabilities) + long(size) * (sizeof(float) + sizeof(int))); } else { return (sizeof(Probabilities) + long(size) * sizeof(float)); } } Community::Community() { P = 0; first_neighbor = 0; last_neighbor = 0; sub_community_of = -1; sub_communities[0] = -1; sub_communities[1] = -1; sigma = 0.; internal_weight = 0.; total_weight = 0.; } Community::~Community() { if (P) { delete P; } } Communities::Communities(Graph* graph, int random_walks_length, long m, igraph_matrix_t *pmerges, igraph_vector_t *pmodularity) { max_memory = m; memory_used = 0; G = graph; merges = pmerges; mergeidx = 0; modularity = pmodularity; Probabilities::C = this; Probabilities::length = random_walks_length; Probabilities::tmp_vector1 = new float[G->nb_vertices]; Probabilities::tmp_vector2 = new float[G->nb_vertices]; Probabilities::id = new int[G->nb_vertices]; for (int i = 0; i < G->nb_vertices; i++) { Probabilities::id[i] = 0; } Probabilities::vertices1 = new int[G->nb_vertices]; Probabilities::vertices2 = new int[G->nb_vertices]; Probabilities::current_id = 0; members = new int[G->nb_vertices]; for (int i = 0; i < G->nb_vertices; i++) { members[i] = -1; } H = new Neighbor_heap(G->nb_edges); communities = new Community[2 * G->nb_vertices]; // init the n single vertex communities if (max_memory != -1) { min_delta_sigma = new Min_delta_sigma_heap(G->nb_vertices * 2); } else { min_delta_sigma = 0; } for (int i = 0; i < G->nb_vertices; i++) { communities[i].this_community = i; communities[i].first_member = i; communities[i].last_member = i; communities[i].size = 1; communities[i].sub_community_of = 0; } nb_communities = G->nb_vertices; nb_active_communities = G->nb_vertices; for (int i = 0; i < G->nb_vertices; i++) for (int j = 0; j < G->vertices[i].degree; j++) if (i < G->vertices[i].edges[j].neighbor) { communities[i].total_weight += G->vertices[i].edges[j].weight / 2.; communities[G->vertices[i].edges[j].neighbor].total_weight += G->vertices[i].edges[j].weight / 2.; Neighbor* N = new Neighbor; N->community1 = i; N->community2 = G->vertices[i].edges[j].neighbor; N->delta_sigma = -1. / double(min(G->vertices[i].degree, G->vertices[G->vertices[i].edges[j].neighbor].degree)); N->weight = G->vertices[i].edges[j].weight; N->exact = false; add_neighbor(N); } if (max_memory != -1) { memory_used += min_delta_sigma->memory(); memory_used += 2 * long(G->nb_vertices) * sizeof(Community); memory_used += long(G->nb_vertices) * (2 * sizeof(float) + 3 * sizeof(int)); // the static data of Probabilities class memory_used += H->memory() + long(G->nb_edges) * sizeof(Neighbor); memory_used += G->memory(); } /* int c = 0; */ Neighbor* N = H->get_first(); if (N == 0) { return; /* this can happen if there are no edges */ } while (!N->exact) { update_neighbor(N, compute_delta_sigma(N->community1, N->community2)); N->exact = true; N = H->get_first(); if (max_memory != -1) { manage_memory(); } /* TODO: this could use igraph_progress */ /* if(!silent) { */ /* c++; */ /* for(int k = (500*(c-1))/G->nb_edges + 1; k <= (500*c)/G->nb_edges; k++) { */ /* if(k % 50 == 1) {cerr.width(2); cerr << endl << k/ 5 << "% ";} */ /* cerr << "."; */ /* } */ /* } */ } double Q = 0.; for (int i = 0; i < nb_communities; i++) { if (communities[i].sub_community_of == 0) { Q += (communities[i].internal_weight - communities[i].total_weight * communities[i].total_weight / G->total_weight) / G->total_weight; } } if (modularity) { VECTOR(*modularity)[mergeidx] = Q; } } Communities::~Communities() { delete[] members; delete[] communities; delete H; if (min_delta_sigma) { delete min_delta_sigma; } delete[] Probabilities::tmp_vector1; delete[] Probabilities::tmp_vector2; delete[] Probabilities::id; delete[] Probabilities::vertices1; delete[] Probabilities::vertices2; } float Community::min_delta_sigma() { float r = 1.; for (Neighbor* N = first_neighbor; N != 0;) { if (N->delta_sigma < r) { r = N->delta_sigma; } if (N->community1 == this_community) { N = N->next_community1; } else { N = N->next_community2; } } return r; } void Community::add_neighbor(Neighbor* N) { // add a new neighbor at the end of the list if (last_neighbor) { if (last_neighbor->community1 == this_community) { last_neighbor->next_community1 = N; } else { last_neighbor->next_community2 = N; } if (N->community1 == this_community) { N->previous_community1 = last_neighbor; } else { N->previous_community2 = last_neighbor; } } else { first_neighbor = N; if (N->community1 == this_community) { N->previous_community1 = 0; } else { N->previous_community2 = 0; } } last_neighbor = N; } void Community::remove_neighbor(Neighbor* N) { // remove a neighbor from the list if (N->community1 == this_community) { if (N->next_community1) { // if (N->next_community1->community1 == this_community) N->next_community1->previous_community1 = N->previous_community1; // else // N->next_community1->previous_community2 = N->previous_community1; } else { last_neighbor = N->previous_community1; } if (N->previous_community1) { if (N->previous_community1->community1 == this_community) { N->previous_community1->next_community1 = N->next_community1; } else { N->previous_community1->next_community2 = N->next_community1; } } else { first_neighbor = N->next_community1; } } else { if (N->next_community2) { if (N->next_community2->community1 == this_community) { N->next_community2->previous_community1 = N->previous_community2; } else { N->next_community2->previous_community2 = N->previous_community2; } } else { last_neighbor = N->previous_community2; } if (N->previous_community2) { // if (N->previous_community2->community1 == this_community) // N->previous_community2->next_community1 = N->next_community2; // else N->previous_community2->next_community2 = N->next_community2; } else { first_neighbor = N->next_community2; } } } void Communities::remove_neighbor(Neighbor* N) { communities[N->community1].remove_neighbor(N); communities[N->community2].remove_neighbor(N); H->remove(N); if (max_memory != -1) { if (N->delta_sigma == min_delta_sigma->delta_sigma[N->community1]) { min_delta_sigma->delta_sigma[N->community1] = communities[N->community1].min_delta_sigma(); if (communities[N->community1].P) { min_delta_sigma->update(N->community1); } } if (N->delta_sigma == min_delta_sigma->delta_sigma[N->community2]) { min_delta_sigma->delta_sigma[N->community2] = communities[N->community2].min_delta_sigma(); if (communities[N->community2].P) { min_delta_sigma->update(N->community2); } } } } void Communities::add_neighbor(Neighbor* N) { communities[N->community1].add_neighbor(N); communities[N->community2].add_neighbor(N); H->add(N); if (max_memory != -1) { if (N->delta_sigma < min_delta_sigma->delta_sigma[N->community1]) { min_delta_sigma->delta_sigma[N->community1] = N->delta_sigma; if (communities[N->community1].P) { min_delta_sigma->update(N->community1); } } if (N->delta_sigma < min_delta_sigma->delta_sigma[N->community2]) { min_delta_sigma->delta_sigma[N->community2] = N->delta_sigma; if (communities[N->community2].P) { min_delta_sigma->update(N->community2); } } } } void Communities::update_neighbor(Neighbor* N, float new_delta_sigma) { if (max_memory != -1) { if (new_delta_sigma < min_delta_sigma->delta_sigma[N->community1]) { min_delta_sigma->delta_sigma[N->community1] = new_delta_sigma; if (communities[N->community1].P) { min_delta_sigma->update(N->community1); } } if (new_delta_sigma < min_delta_sigma->delta_sigma[N->community2]) { min_delta_sigma->delta_sigma[N->community2] = new_delta_sigma; if (communities[N->community2].P) { min_delta_sigma->update(N->community2); } } float old_delta_sigma = N->delta_sigma; N->delta_sigma = new_delta_sigma; H->update(N); if (old_delta_sigma == min_delta_sigma->delta_sigma[N->community1]) { min_delta_sigma->delta_sigma[N->community1] = communities[N->community1].min_delta_sigma(); if (communities[N->community1].P) { min_delta_sigma->update(N->community1); } } if (old_delta_sigma == min_delta_sigma->delta_sigma[N->community2]) { min_delta_sigma->delta_sigma[N->community2] = communities[N->community2].min_delta_sigma(); if (communities[N->community2].P) { min_delta_sigma->update(N->community2); } } } else { N->delta_sigma = new_delta_sigma; H->update(N); } } void Communities::manage_memory() { while ((memory_used > max_memory) && !min_delta_sigma->is_empty()) { int c = min_delta_sigma->get_max_community(); delete communities[c].P; communities[c].P = 0; min_delta_sigma->remove_community(c); } } void Communities::merge_communities(Neighbor* merge_N) { int c1 = merge_N->community1; int c2 = merge_N->community2; communities[nb_communities].first_member = communities[c1].first_member; // merge the communities[nb_communities].last_member = communities[c2].last_member; // two lists members[communities[c1].last_member] = communities[c2].first_member; // of members communities[nb_communities].size = communities[c1].size + communities[c2].size; communities[nb_communities].this_community = nb_communities; communities[nb_communities].sub_community_of = 0; communities[nb_communities].sub_communities[0] = c1; communities[nb_communities].sub_communities[1] = c2; communities[nb_communities].total_weight = communities[c1].total_weight + communities[c2].total_weight; communities[nb_communities].internal_weight = communities[c1].internal_weight + communities[c2].internal_weight + merge_N->weight; communities[nb_communities].sigma = communities[c1].sigma + communities[c2].sigma + merge_N->delta_sigma; communities[c1].sub_community_of = nb_communities; communities[c2].sub_community_of = nb_communities; // update the new probability vector... if (communities[c1].P && communities[c2].P) { communities[nb_communities].P = new Probabilities(c1, c2); } if (communities[c1].P) { delete communities[c1].P; communities[c1].P = 0; if (max_memory != -1) { min_delta_sigma->remove_community(c1); } } if (communities[c2].P) { delete communities[c2].P; communities[c2].P = 0; if (max_memory != -1) { min_delta_sigma->remove_community(c2); } } if (max_memory != -1) { min_delta_sigma->delta_sigma[c1] = -1.; // to avoid to update the min_delta_sigma for these communities min_delta_sigma->delta_sigma[c2] = -1.; // min_delta_sigma->delta_sigma[nb_communities] = -1.; } // update the new neighbors // by enumerating all the neighbors of c1 and c2 Neighbor* N1 = communities[c1].first_neighbor; Neighbor* N2 = communities[c2].first_neighbor; while (N1 && N2) { int neighbor_community1; int neighbor_community2; if (N1->community1 == c1) { neighbor_community1 = N1->community2; } else { neighbor_community1 = N1->community1; } if (N2->community1 == c2) { neighbor_community2 = N2->community2; } else { neighbor_community2 = N2->community1; } if (neighbor_community1 < neighbor_community2) { Neighbor* tmp = N1; if (N1->community1 == c1) { N1 = N1->next_community1; } else { N1 = N1->next_community2; } remove_neighbor(tmp); Neighbor* N = new Neighbor; N->weight = tmp->weight; N->community1 = neighbor_community1; N->community2 = nb_communities; N->delta_sigma = (double(communities[c1].size + communities[neighbor_community1].size) * tmp->delta_sigma + double(communities[c2].size) * merge_N->delta_sigma) / (double(communities[c1].size + communities[c2].size + communities[neighbor_community1].size)); //compute_delta_sigma(neighbor_community1, nb_communities); N->exact = false; delete tmp; add_neighbor(N); } if (neighbor_community2 < neighbor_community1) { Neighbor* tmp = N2; if (N2->community1 == c2) { N2 = N2->next_community1; } else { N2 = N2->next_community2; } remove_neighbor(tmp); Neighbor* N = new Neighbor; N->weight = tmp->weight; N->community1 = neighbor_community2; N->community2 = nb_communities; N->delta_sigma = (double(communities[c1].size) * merge_N->delta_sigma + double(communities[c2].size + communities[neighbor_community2].size) * tmp->delta_sigma) / (double(communities[c1].size + communities[c2].size + communities[neighbor_community2].size)); //compute_delta_sigma(neighbor_community2, nb_communities); N->exact = false; delete tmp; add_neighbor(N); } if (neighbor_community1 == neighbor_community2) { Neighbor* tmp1 = N1; Neighbor* tmp2 = N2; bool exact = N1->exact && N2->exact; if (N1->community1 == c1) { N1 = N1->next_community1; } else { N1 = N1->next_community2; } if (N2->community1 == c2) { N2 = N2->next_community1; } else { N2 = N2->next_community2; } remove_neighbor(tmp1); remove_neighbor(tmp2); Neighbor* N = new Neighbor; N->weight = tmp1->weight + tmp2->weight; N->community1 = neighbor_community1; N->community2 = nb_communities; N->delta_sigma = (double(communities[c1].size + communities[neighbor_community1].size) * tmp1->delta_sigma + double(communities[c2].size + communities[neighbor_community1].size) * tmp2->delta_sigma - double(communities[neighbor_community1].size) * merge_N->delta_sigma) / (double(communities[c1].size + communities[c2].size + communities[neighbor_community1].size)); N->exact = exact; delete tmp1; delete tmp2; add_neighbor(N); } } if (!N1) { while (N2) { // double delta_sigma2 = N2->delta_sigma; int neighbor_community; if (N2->community1 == c2) { neighbor_community = N2->community2; } else { neighbor_community = N2->community1; } Neighbor* tmp = N2; if (N2->community1 == c2) { N2 = N2->next_community1; } else { N2 = N2->next_community2; } remove_neighbor(tmp); Neighbor* N = new Neighbor; N->weight = tmp->weight; N->community1 = neighbor_community; N->community2 = nb_communities; N->delta_sigma = (double(communities[c1].size) * merge_N->delta_sigma + double(communities[c2].size + communities[neighbor_community].size) * tmp->delta_sigma) / (double(communities[c1].size + communities[c2].size + communities[neighbor_community].size)); //compute_delta_sigma(neighbor_community, nb_communities); N->exact = false; delete tmp; add_neighbor(N); } } if (!N2) { while (N1) { // double delta_sigma1 = N1->delta_sigma; int neighbor_community; if (N1->community1 == c1) { neighbor_community = N1->community2; } else { neighbor_community = N1->community1; } Neighbor* tmp = N1; if (N1->community1 == c1) { N1 = N1->next_community1; } else { N1 = N1->next_community2; } remove_neighbor(tmp); Neighbor* N = new Neighbor; N->weight = tmp->weight; N->community1 = neighbor_community; N->community2 = nb_communities; N->delta_sigma = (double(communities[c1].size + communities[neighbor_community].size) * tmp->delta_sigma + double(communities[c2].size) * merge_N->delta_sigma) / (double(communities[c1].size + communities[c2].size + communities[neighbor_community].size)); //compute_delta_sigma(neighbor_community, nb_communities); N->exact = false; delete tmp; add_neighbor(N); } } if (max_memory != -1) { min_delta_sigma->delta_sigma[nb_communities] = communities[nb_communities].min_delta_sigma(); min_delta_sigma->update(nb_communities); } nb_communities++; nb_active_communities--; } double Communities::merge_nearest_communities() { Neighbor* N = H->get_first(); while (!N->exact) { update_neighbor(N, compute_delta_sigma(N->community1, N->community2)); N->exact = true; N = H->get_first(); if (max_memory != -1) { manage_memory(); } } double d = N->delta_sigma; remove_neighbor(N); merge_communities(N); if (max_memory != -1) { manage_memory(); } if (merges) { MATRIX(*merges, mergeidx, 0) = N->community1; MATRIX(*merges, mergeidx, 1) = N->community2; mergeidx++; } if (modularity) { float Q = 0.; for (int i = 0; i < nb_communities; i++) { if (communities[i].sub_community_of == 0) { Q += (communities[i].internal_weight - communities[i].total_weight * communities[i].total_weight / G->total_weight) / G->total_weight; } } VECTOR(*modularity)[mergeidx] = Q; } delete N; /* This could use igraph_progress */ /* if(!silent) { */ /* for(int k = (500*(G->nb_vertices - nb_active_communities - 1))/(G->nb_vertices-1) + 1; k <= (500*(G->nb_vertices - nb_active_communities))/(G->nb_vertices-1); k++) { */ /* if(k % 50 == 1) {cerr.width(2); cerr << endl << k/ 5 << "% ";} */ /* cerr << "."; */ /* } */ /* } */ return d; } double Communities::compute_delta_sigma(int community1, int community2) { if (!communities[community1].P) { communities[community1].P = new Probabilities(community1); if (max_memory != -1) { min_delta_sigma->update(community1); } } if (!communities[community2].P) { communities[community2].P = new Probabilities(community2); if (max_memory != -1) { min_delta_sigma->update(community2); } } return communities[community1].P->compute_distance(communities[community2].P) * double(communities[community1].size) * double(communities[community2].size) / double(communities[community1].size + communities[community2].size); } } } /* end of namespaces */ leidenbase/src/core/community/walktrap/walktrap_heap.cpp0000644000176200001440000001512514447675374023314 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Pascal Pons The original copyright notice follows here. The FSF address was fixed by Tamas Nepusz */ // File: heap.cpp //----------------------------------------------------------------------------- // Walktrap v0.2 -- Finds community structure of networks using random walks // Copyright (C) 2004-2005 Pascal Pons // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301 USA //----------------------------------------------------------------------------- // Author : Pascal Pons // Email : pascal.pons@gmail.com // Web page : http://www-rp.lip6.fr/~latapy/PP/walktrap.html // Location : Paris, France // Time : June 2005 //----------------------------------------------------------------------------- // see readme.txt for more details #include "walktrap_heap.h" using namespace igraph::walktrap; void Neighbor_heap::move_up(int index) { while (H[index / 2]->delta_sigma > H[index]->delta_sigma) { Neighbor* tmp = H[index / 2]; H[index]->heap_index = index / 2; H[index / 2] = H[index]; tmp->heap_index = index; H[index] = tmp; index = index / 2; } } void Neighbor_heap::move_down(int index) { while (true) { int min = index; if ((2 * index < size) && (H[2 * index]->delta_sigma < H[min]->delta_sigma)) { min = 2 * index; } if (2 * index + 1 < size && H[2 * index + 1]->delta_sigma < H[min]->delta_sigma) { min = 2 * index + 1; } if (min != index) { Neighbor* tmp = H[min]; H[index]->heap_index = min; H[min] = H[index]; tmp->heap_index = index; H[index] = tmp; index = min; } else { break; } } } Neighbor* Neighbor_heap::get_first() { if (size == 0) { return 0; } else { return H[0]; } } void Neighbor_heap::remove(Neighbor* N) { if (N->heap_index == -1 || size == 0) { return; } Neighbor* last_N = H[--size]; H[N->heap_index] = last_N; last_N->heap_index = N->heap_index; move_up(last_N->heap_index); move_down(last_N->heap_index); N->heap_index = -1; } void Neighbor_heap::add(Neighbor* N) { if (size >= max_size) { return; } N->heap_index = size++; H[N->heap_index] = N; move_up(N->heap_index); } void Neighbor_heap::update(Neighbor* N) { if (N->heap_index == -1) { return; } move_up(N->heap_index); move_down(N->heap_index); } long Neighbor_heap::memory() { return (sizeof(Neighbor_heap) + long(max_size) * sizeof(Neighbor*)); } Neighbor_heap::Neighbor_heap(int max_s) { max_size = max_s; size = 0; H = new Neighbor*[max_s]; } Neighbor_heap::~Neighbor_heap() { delete[] H; } bool Neighbor_heap::is_empty() { return (size == 0); } //################################################################# void Min_delta_sigma_heap::move_up(int index) { while (delta_sigma[H[index / 2]] < delta_sigma[H[index]]) { int tmp = H[index / 2]; I[H[index]] = index / 2; H[index / 2] = H[index]; I[tmp] = index; H[index] = tmp; index = index / 2; } } void Min_delta_sigma_heap::move_down(int index) { while (true) { int max = index; if (2 * index < size && delta_sigma[H[2 * index]] > delta_sigma[H[max]]) { max = 2 * index; } if (2 * index + 1 < size && delta_sigma[H[2 * index + 1]] > delta_sigma[H[max]]) { max = 2 * index + 1; } if (max != index) { int tmp = H[max]; I[H[index]] = max; H[max] = H[index]; I[tmp] = index; H[index] = tmp; index = max; } else { break; } } } int Min_delta_sigma_heap::get_max_community() { if (size == 0) { return -1; } else { return H[0]; } } void Min_delta_sigma_heap::remove_community(int community) { if (I[community] == -1 || size == 0) { return; } int last_community = H[--size]; H[I[community]] = last_community; I[last_community] = I[community]; move_up(I[last_community]); move_down(I[last_community]); I[community] = -1; } void Min_delta_sigma_heap::update(int community) { if (community < 0 || community >= max_size) { return; } if (I[community] == -1) { I[community] = size++; H[I[community]] = community; } move_up(I[community]); move_down(I[community]); } long Min_delta_sigma_heap::memory() { return (sizeof(Min_delta_sigma_heap) + long(max_size) * (2 * sizeof(int) + sizeof(float))); } Min_delta_sigma_heap::Min_delta_sigma_heap(int max_s) { max_size = max_s; size = 0; H = new int[max_s]; I = new int[max_s]; delta_sigma = new float[max_s]; for (int i = 0; i < max_size; i++) { I[i] = -1; delta_sigma[i] = 1.; } } Min_delta_sigma_heap::~Min_delta_sigma_heap() { delete[] H; delete[] I; delete[] delta_sigma; } bool Min_delta_sigma_heap::is_empty() { return (size == 0); } leidenbase/src/core/community/walktrap/walktrap_graph.h0000644000176200001440000000703014447675374023141 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Pascal Pons The original copyright notice follows here */ // File: graph.h //----------------------------------------------------------------------------- // Walktrap v0.2 -- Finds community structure of networks using random walks // Copyright (C) 2004-2005 Pascal Pons // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301 USA //----------------------------------------------------------------------------- // Author : Pascal Pons // Email : pascal.pons@gmail.com // Web page : http://www-rp.lip6.fr/~latapy/PP/walktrap.html // Location : Paris, France // Time : June 2005 //----------------------------------------------------------------------------- // see readme.txt for more details /* FSF address above was fixed by Tamas Nepusz */ #ifndef WALKTRAP_GRAPH_H #define WALKTRAP_GRAPH_H #include "igraph_community.h" namespace igraph { namespace walktrap { class Edge { // code an edge of a given vertex public: int neighbor; // the number of the neighbor vertex float weight; // the weight of the edge }; bool operator<(const Edge& E1, const Edge& E2); class Vertex { public: Edge* edges; // the edges of the vertex int degree; // number of neighbors float total_weight; // the total weight of the vertex Vertex(); // creates empty vertex ~Vertex(); // destructor }; class Graph { public: int nb_vertices; // number of vertices int nb_edges; // number of edges float total_weight; // total weight of the edges Vertex* vertices; // array of the vertices long memory(); // the total memory used in Bytes Graph(); // create an empty graph ~Graph(); // destructor char** index; // to keep the real name of the vertices int convert_from_igraph(const igraph_t * igraph, const igraph_vector_t *weights); }; } } /* end of namespaces */ #endif // WALKTRAP_GRAPH_H leidenbase/src/core/community/walktrap/walktrap_heap.h0000644000176200001440000001062314447675374022757 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Pascal Pons The original copyright notice follows here. The FSF address was fixed by Tamas Nepusz */ // File: heap.h //----------------------------------------------------------------------------- // Walktrap v0.2 -- Finds community structure of networks using random walks // Copyright (C) 2004-2005 Pascal Pons // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301 USA //----------------------------------------------------------------------------- // Author : Pascal Pons // Email : pons@liafa.jussieu.fr // Web page : http://www.liafa.jussieu.fr/~pons/ // Location : Paris, France // Time : June 2005 //----------------------------------------------------------------------------- // see readme.txt for more details #ifndef WALKTRAP_HEAP_H #define WALKTRAP_HEAP_H namespace igraph { namespace walktrap { class Neighbor { public: int community1; // the two adjacent communities int community2; // community1 < community2 float delta_sigma; // the delta sigma between the two communities float weight; // the total weight of the edges between the two communities bool exact; // true if delta_sigma is exact, false if it is only a lower bound Neighbor* next_community1; // pointers of two double Neighbor* previous_community1; // chained lists containing Neighbor* next_community2; // all the neighbors of Neighbor* previous_community2; // each communities. int heap_index; // Neighbor(); }; class Neighbor_heap { private: int size; int max_size; Neighbor** H; // the heap that contains a pointer to each Neighbor object stored void move_up(int index); void move_down(int index); public: void add(Neighbor* N); // add a new distance void update(Neighbor* N); // update a distance void remove(Neighbor* N); // remove a distance Neighbor* get_first(); // get the first item long memory(); bool is_empty(); Neighbor_heap(int max_size); ~Neighbor_heap(); }; class Min_delta_sigma_heap { private: int size; int max_size; int* H; // the heap that contains the number of each community int* I; // the index of each community in the heap (-1 = not stored) void move_up(int index); void move_down(int index); public: int get_max_community(); // return the community with the maximal delta_sigma void remove_community(int community); // remove a community; void update(int community); // update (or insert if necessary) the community long memory(); // the memory used in Bytes. bool is_empty(); float* delta_sigma; // the delta_sigma of the stored communities Min_delta_sigma_heap(int max_size); ~Min_delta_sigma_heap(); }; } } /* end of namespaces */ #endif // WALKTRAP_HEAP_H leidenbase/src/core/community/louvain.c0000644000176200001440000006721514447675374017771 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_qsort.h" #include "igraph_random.h" #include "core/interruption.h" /* Structure storing a community */ typedef struct { igraph_integer_t size; /* Size of the community */ igraph_real_t weight_inside; /* Sum of edge weights inside community */ igraph_real_t weight_all; /* Sum of edge weights starting/ending in the community */ } igraph_i_multilevel_community; /* Global community list structure */ typedef struct { long int communities_no, vertices_no; /* Number of communities, number of vertices */ igraph_real_t weight_sum; /* Sum of edges weight in the whole graph */ igraph_i_multilevel_community *item; /* List of communities */ igraph_vector_t *membership; /* Community IDs */ igraph_vector_t *weights; /* Graph edge weights */ } igraph_i_multilevel_community_list; /* Computes the modularity of a community partitioning */ static igraph_real_t igraph_i_multilevel_community_modularity( const igraph_i_multilevel_community_list *communities, const igraph_real_t resolution) { igraph_real_t result = 0; long int i; igraph_real_t m = communities->weight_sum; for (i = 0; i < communities->vertices_no; i++) { if (communities->item[i].size > 0) { result += (communities->item[i].weight_inside - resolution * communities->item[i].weight_all * communities->item[i].weight_all / m) / m; } } return result; } typedef struct { long int from; long int to; long int id; } igraph_i_multilevel_link; static int igraph_i_multilevel_link_cmp(const void *a, const void *b) { long int r = (((igraph_i_multilevel_link*)a)->from - ((igraph_i_multilevel_link*)b)->from); if (r != 0) { return (int) r; } return (int) (((igraph_i_multilevel_link*)a)->to - ((igraph_i_multilevel_link*)b)->to); } /* removes multiple edges and returns new edge id's for each edge in |E|log|E| */ static int igraph_i_multilevel_simplify_multiple(igraph_t *graph, igraph_vector_t *eids) { long int ecount = igraph_ecount(graph); long int i, l = -1, last_from = -1, last_to = -1; igraph_bool_t directed = igraph_is_directed(graph); igraph_vector_t edges; igraph_i_multilevel_link *links; /* Make sure there's enough space in eids to store the new edge IDs */ IGRAPH_CHECK(igraph_vector_resize(eids, ecount)); links = IGRAPH_CALLOC(ecount, igraph_i_multilevel_link); if (links == 0) { IGRAPH_ERROR("multi-level community structure detection failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, links); for (i = 0; i < ecount; i++) { igraph_integer_t from, to; igraph_edge(graph, (igraph_integer_t) i, &from, &to); links[i].from = from; links[i].to = to; links[i].id = i; } igraph_qsort((void*)links, (size_t) ecount, sizeof(igraph_i_multilevel_link), igraph_i_multilevel_link_cmp); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); for (i = 0; i < ecount; i++) { if (links[i].from == last_from && links[i].to == last_to) { VECTOR(*eids)[links[i].id] = l; continue; } last_from = links[i].from; last_to = links[i].to; igraph_vector_push_back(&edges, last_from); igraph_vector_push_back(&edges, last_to); l++; VECTOR(*eids)[links[i].id] = l; } IGRAPH_FREE(links); IGRAPH_FINALLY_CLEAN(1); igraph_destroy(graph); IGRAPH_CHECK(igraph_create(graph, &edges, igraph_vcount(graph), directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } typedef struct { long int community; igraph_real_t weight; } igraph_i_multilevel_community_link; static int igraph_i_multilevel_community_link_cmp(const void *a, const void *b) { return (int) (((igraph_i_multilevel_community_link*)a)->community - ((igraph_i_multilevel_community_link*)b)->community); } /** * Given a graph, a community structure and a vertex ID, this method * calculates: * * - edges: the list of edge IDs that are incident on the vertex * - weight_all: the total weight of these edges * - weight_inside: the total weight of edges that stay within the same * community where the given vertex is right now, excluding loop edges * - weight_loop: the total weight of loop edges * - links_community and links_weight: together these two vectors list the * communities incident on this vertex and the total weight of edges * pointing to these communities */ static int igraph_i_multilevel_community_links( const igraph_t *graph, const igraph_i_multilevel_community_list *communities, igraph_integer_t vertex, igraph_vector_t *edges, igraph_real_t *weight_all, igraph_real_t *weight_inside, igraph_real_t *weight_loop, igraph_vector_t *links_community, igraph_vector_t *links_weight) { long int i, n, last = -1, c = -1; igraph_real_t weight = 1; long int to, to_community; long int community = (long int) VECTOR(*(communities->membership))[(long int)vertex]; igraph_i_multilevel_community_link *links; *weight_all = *weight_inside = *weight_loop = 0; igraph_vector_clear(links_community); igraph_vector_clear(links_weight); /* Get the list of incident edges */ igraph_incident(graph, edges, vertex, IGRAPH_ALL); n = igraph_vector_size(edges); links = IGRAPH_CALLOC(n, igraph_i_multilevel_community_link); if (links == 0) { IGRAPH_ERROR("multi-level community structure detection failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, links); for (i = 0; i < n; i++) { long int eidx = (long int) VECTOR(*edges)[i]; weight = VECTOR(*communities->weights)[eidx]; to = IGRAPH_OTHER(graph, eidx, vertex); *weight_all += weight; if (to == vertex) { *weight_loop += weight; links[i].community = community; links[i].weight = 0; continue; } to_community = (long int)VECTOR(*(communities->membership))[to]; if (community == to_community) { *weight_inside += weight; } /* debug("Link %ld (C: %ld) <-> %ld (C: %ld)\n", vertex, community, to, to_community); */ links[i].community = to_community; links[i].weight = weight; } /* Sort links by community ID and merge the same */ igraph_qsort((void*)links, (size_t) n, sizeof(igraph_i_multilevel_community_link), igraph_i_multilevel_community_link_cmp); for (i = 0; i < n; i++) { to_community = links[i].community; if (to_community != last) { igraph_vector_push_back(links_community, to_community); igraph_vector_push_back(links_weight, links[i].weight); last = to_community; c++; } else { VECTOR(*links_weight)[c] += links[i].weight; } } igraph_free(links); IGRAPH_FINALLY_CLEAN(1); return 0; } static igraph_real_t igraph_i_multilevel_community_modularity_gain( const igraph_i_multilevel_community_list *communities, igraph_integer_t community, igraph_integer_t vertex, igraph_real_t weight_all, igraph_real_t weight_inside, const igraph_real_t resolution) { IGRAPH_UNUSED(vertex); return weight_inside - resolution * communities->item[(long int)community].weight_all * weight_all / communities->weight_sum; } /* Shrinks communities into single vertices, keeping all the edges. * This method is internal because it destroys the graph in-place and * creates a new one -- this is fine for the multilevel community * detection where a copy of the original graph is used anyway. * The membership vector will also be rewritten by the underlying * igraph_membership_reindex call */ static int igraph_i_multilevel_shrink(igraph_t *graph, igraph_vector_t *membership) { igraph_vector_t edges; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_bool_t directed = igraph_is_directed(graph); long int i; igraph_eit_t eit; if (no_of_nodes == 0) { return 0; } if (igraph_vector_size(membership) < no_of_nodes) { IGRAPH_ERROR("cannot shrink graph, membership vector too short", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); IGRAPH_CHECK(igraph_reindex_membership(membership, 0, NULL)); /* Create the new edgelist */ igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID), &eit); IGRAPH_FINALLY(igraph_eit_destroy, &eit); i = 0; while (!IGRAPH_EIT_END(eit)) { igraph_integer_t from, to; IGRAPH_CHECK(igraph_edge(graph, IGRAPH_EIT_GET(eit), &from, &to)); VECTOR(edges)[i++] = VECTOR(*membership)[(long int) from]; VECTOR(edges)[i++] = VECTOR(*membership)[(long int) to]; IGRAPH_EIT_NEXT(eit); } igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(1); /* Create the new graph */ igraph_destroy(graph); no_of_nodes = (long int) igraph_vector_max(membership) + 1; IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup communities * \function igraph_i_community_multilevel_step * \brief Performs a single step of the multi-level modularity optimization method * * This function implements a single step of the multi-level modularity optimization * algorithm for finding community structure, see VD Blondel, J-L Guillaume, * R Lambiotte and E Lefebvre: Fast unfolding of community hierarchies in large * networks, http://arxiv.org/abs/0803.0476 for the details. * * This function was contributed by Tom Gregorovic. * * \param graph The input graph. It must be an undirected graph. * \param weights Numeric vector containing edge weights. If \c NULL, * every edge has equal weight. The weights are expected * to be non-negative. * \param membership The membership vector, the result is returned here. * For each vertex it gives the ID of its community. * \param modularity The modularity of the partition is returned here. * \c NULL means that the modularity is not needed. * \param resolution Resolution parameter. Must be greater than or equal to 0. * Default is 1. Lower values favor fewer, larger communities; * higher values favor more, smaller communities. * \return Error code. * * Time complexity: in average near linear on sparse graphs. */ static int igraph_i_community_multilevel_step( igraph_t *graph, igraph_vector_t *weights, igraph_vector_t *membership, igraph_real_t *modularity, const igraph_real_t resolution) { long int i, j; long int vcount = igraph_vcount(graph); long int ecount = igraph_ecount(graph); igraph_real_t q, pass_q; int pass; igraph_bool_t changed = 0; igraph_vector_t links_community; igraph_vector_t links_weight; igraph_vector_t edges; igraph_vector_t temp_membership; igraph_i_multilevel_community_list communities; igraph_vector_t node_order; /* Initial sanity checks on the input parameters */ if (igraph_is_directed(graph)) { IGRAPH_ERROR("multi-level community detection works for undirected graphs only", IGRAPH_UNIMPLEMENTED); } if (igraph_vector_size(weights) < igraph_ecount(graph)) { IGRAPH_ERROR("multi-level community detection: weight vector too short", IGRAPH_EINVAL); } if (igraph_vector_any_smaller(weights, 0)) { IGRAPH_ERROR("weights must be positive", IGRAPH_EINVAL); } if (resolution < 0.0) { IGRAPH_ERROR("The resolution parameter must be non-negative", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_init_seq(&node_order, 0, vcount - 1)); IGRAPH_FINALLY(igraph_vector_destroy, &node_order); IGRAPH_CHECK(igraph_vector_shuffle(&node_order)); /* Initialize data structures */ IGRAPH_VECTOR_INIT_FINALLY(&links_community, 0); IGRAPH_VECTOR_INIT_FINALLY(&links_weight, 0); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&temp_membership, vcount); IGRAPH_CHECK(igraph_vector_resize(membership, vcount)); /* Initialize list of communities from graph vertices */ communities.vertices_no = vcount; communities.communities_no = vcount; communities.weights = weights; communities.weight_sum = 2 * igraph_vector_sum(weights); communities.membership = membership; communities.item = IGRAPH_CALLOC(vcount, igraph_i_multilevel_community); if (communities.item == 0) { IGRAPH_ERROR("multi-level community structure detection failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, communities.item); /* Still initializing the communities data structure */ for (i = 0; i < vcount; i++) { VECTOR(*communities.membership)[i] = i; communities.item[i].size = 1; communities.item[i].weight_inside = 0; communities.item[i].weight_all = 0; } /* Some more initialization :) */ for (i = 0; i < ecount; i++) { igraph_integer_t ffrom, fto; igraph_real_t weight = 1; igraph_edge(graph, (igraph_integer_t) i, &ffrom, &fto); weight = VECTOR(*weights)[i]; communities.item[(long int) ffrom].weight_all += weight; communities.item[(long int) fto].weight_all += weight; if (ffrom == fto) { communities.item[(long int) ffrom].weight_inside += 2 * weight; } } q = igraph_i_multilevel_community_modularity(&communities, resolution); pass = 1; do { /* Pass begin */ long int temp_communities_no = communities.communities_no; pass_q = q; changed = 0; /* Save the current membership, it will be restored in case of worse result */ IGRAPH_CHECK(igraph_vector_update(&temp_membership, communities.membership)); for (i = 0; i < vcount; i++) { /* Exclude vertex from its current community */ igraph_real_t weight_all = 0; igraph_real_t weight_inside = 0; igraph_real_t weight_loop = 0; igraph_real_t max_q_gain = 0; igraph_real_t max_weight; long int old_id, new_id, n, ni; ni = VECTOR(node_order)[i]; igraph_i_multilevel_community_links(graph, &communities, (igraph_integer_t) ni, &edges, &weight_all, &weight_inside, &weight_loop, &links_community, &links_weight); old_id = (long int)VECTOR(*(communities.membership))[ni]; new_id = old_id; /* Update old community */ igraph_vector_set(communities.membership, ni, -1); communities.item[old_id].size--; if (communities.item[old_id].size == 0) { communities.communities_no--; } communities.item[old_id].weight_all -= weight_all; communities.item[old_id].weight_inside -= 2 * weight_inside + weight_loop; /* debug("Remove %ld all: %lf Inside: %lf\n", ni, -weight_all, -2*weight_inside + weight_loop); */ /* Find new community to join with the best modification gain */ max_q_gain = 0; max_weight = weight_inside; n = igraph_vector_size(&links_community); for (j = 0; j < n; j++) { long int c = (long int) VECTOR(links_community)[j]; igraph_real_t w = VECTOR(links_weight)[j]; igraph_real_t q_gain = igraph_i_multilevel_community_modularity_gain(&communities, (igraph_integer_t) c, (igraph_integer_t) ni, weight_all, w, resolution); /* debug("Link %ld -> %ld weight: %lf gain: %lf\n", ni, c, (double) w, (double) q_gain); */ if (q_gain > max_q_gain) { new_id = c; max_q_gain = q_gain; max_weight = w; } } /* debug("Added vertex %ld to community %ld (gain %lf).\n", ni, new_id, (double) max_q_gain); */ /* Add vertex to "new" community and update it */ igraph_vector_set(communities.membership, ni, new_id); if (communities.item[new_id].size == 0) { communities.communities_no++; } communities.item[new_id].size++; communities.item[new_id].weight_all += weight_all; communities.item[new_id].weight_inside += 2 * max_weight + weight_loop; if (new_id != old_id) { changed++; } } q = igraph_i_multilevel_community_modularity(&communities, resolution); if (changed && (q > pass_q)) { /* debug("Pass %d (changed: %d) Communities: %ld Modularity from %lf to %lf\n", pass, changed, communities.communities_no, (double) pass_q, (double) q); */ pass++; } else { /* No changes or the modularity became worse, restore last membership */ IGRAPH_CHECK(igraph_vector_update(communities.membership, &temp_membership)); communities.communities_no = temp_communities_no; break; } IGRAPH_ALLOW_INTERRUPTION(); } while (changed && (q > pass_q)); /* Pass end */ if (modularity) { *modularity = q; } /* debug("Result Communities: %ld Modularity: %lf\n", communities.communities_no, (double) q); */ IGRAPH_CHECK(igraph_reindex_membership(membership, 0, NULL)); /* Shrink the nodes of the graph according to the present community structure * and simplify the resulting graph */ /* TODO: check if we really need to copy temp_membership */ IGRAPH_CHECK(igraph_vector_update(&temp_membership, membership)); IGRAPH_CHECK(igraph_i_multilevel_shrink(graph, &temp_membership)); igraph_vector_destroy(&temp_membership); IGRAPH_FINALLY_CLEAN(1); /* Update edge weights after shrinking and simplification */ /* Here we reuse the edges vector as we don't need the previous contents anymore */ /* TODO: can we use igraph_simplify here? */ IGRAPH_CHECK(igraph_i_multilevel_simplify_multiple(graph, &edges)); /* We reuse the links_weight vector to store the old edge weights */ IGRAPH_CHECK(igraph_vector_update(&links_weight, weights)); igraph_vector_fill(weights, 0); for (i = 0; i < ecount; i++) { VECTOR(*weights)[(long int)VECTOR(edges)[i]] += VECTOR(links_weight)[i]; } igraph_free(communities.item); igraph_vector_destroy(&links_community); igraph_vector_destroy(&links_weight); igraph_vector_destroy(&edges); igraph_vector_destroy(&node_order); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \ingroup communities * \function igraph_community_multilevel * \brief Finding community structure by multi-level optimization of modularity. * * This function implements the multi-level modularity optimization * algorithm for finding community structure, see * Blondel, V. D., Guillaume, J.-L., Lambiotte, R., & Lefebvre, E. (2008). Fast * unfolding of communities in large networks. Journal of Statistical Mechanics: * Theory and Experiment, 10008(10), 6. * https://doi.org/10.1088/1742-5468/2008/10/P10008 for the details (preprint: * http://arxiv.org/abs/0803.0476). The algorithm is sometimes known as the * "Louvain" algorithm. * * * The algorithm is based on the modularity measure and a hierarchical approach. * Initially, each vertex is assigned to a community on its own. In every step, * vertices are re-assigned to communities in a local, greedy way: in a random * order, each vertex is moved to the community with which it achieves the highest * contribution to modularity. When no vertices can be reassigned, each community * is considered a vertex on its own, and the process starts again with the merged * communities. The process stops when there is only a single vertex left or when * the modularity cannot be increased any more in a step. * * * The resolution parameter \c gamma allows finding communities at different * resolutions. Higher values of the resolution parameter typically result in * more, smaller communities. Lower values typically result in fewer, larger * communities. The original definition of modularity is retrieved when setting * gamma=1. Note that the returned modularity value is calculated using * the indicated resolution parameter. See \ref igraph_modularity() for more details. * * This function was contributed by Tom Gregorovic. * * \param graph The input graph. It must be an undirected graph. * \param weights Numeric vector containing edge weights. If \c NULL, every edge * has equal weight. The weights are expected to be non-negative. * \param resolution Resolution parameter. Must be greater than or equal to 0. * Lower values favor fewer, larger communities; * higher values favor more, smaller communities. * Set it to 1 to use the classical definition of modularity. * \param membership The membership vector, the result is returned here. * For each vertex it gives the ID of its community. The vector * must be initialized and it will be resized accordingly. * \param memberships Numeric matrix that will contain the membership vector after * each level, if not \c NULL. It must be initialized and * it will be resized accordingly. * \param modularity Numeric vector that will contain the modularity score * after each level, if not \c NULL. It must be initialized * and it will be resized accordingly. * \return Error code. * * Time complexity: in average near linear on sparse graphs. * * \example examples/simple/igraph_community_multilevel.c */ int igraph_community_multilevel(const igraph_t *graph, const igraph_vector_t *weights, const igraph_real_t resolution, igraph_vector_t *membership, igraph_matrix_t *memberships, igraph_vector_t *modularity) { igraph_t g; igraph_vector_t w, m, level_membership; igraph_real_t prev_q = -1, q = -1; int i, level = 1; long int vcount = igraph_vcount(graph); /* Make a copy of the original graph, we will do the merges on the copy */ IGRAPH_CHECK(igraph_copy(&g, graph)); IGRAPH_FINALLY(igraph_destroy, &g); if (weights) { IGRAPH_CHECK(igraph_vector_copy(&w, weights)); IGRAPH_FINALLY(igraph_vector_destroy, &w); } else { IGRAPH_VECTOR_INIT_FINALLY(&w, igraph_ecount(&g)); igraph_vector_fill(&w, 1); } IGRAPH_VECTOR_INIT_FINALLY(&m, vcount); IGRAPH_VECTOR_INIT_FINALLY(&level_membership, vcount); if (memberships || membership) { /* Put each vertex in its own community */ for (i = 0; i < vcount; i++) { VECTOR(level_membership)[i] = i; } } if (memberships) { /* Resize the membership matrix to have vcount columns and no rows */ IGRAPH_CHECK(igraph_matrix_resize(memberships, 0, vcount)); } if (modularity) { /* Clear the modularity vector */ igraph_vector_clear(modularity); } while (1) { /* Remember the previous modularity and vertex count, do a single step */ igraph_integer_t step_vcount = igraph_vcount(&g); prev_q = q; IGRAPH_CHECK(igraph_i_community_multilevel_step(&g, &w, &m, &q, resolution)); /* Were there any merges? If not, we have to stop the process */ if (igraph_vcount(&g) == step_vcount || q < prev_q) { break; } if (memberships || membership) { for (i = 0; i < vcount; i++) { /* Readjust the membership vector */ VECTOR(level_membership)[i] = VECTOR(m)[(long int) VECTOR(level_membership)[i]]; } } if (modularity) { /* If we have to return the modularity scores, add it to the modularity vector */ IGRAPH_CHECK(igraph_vector_push_back(modularity, q)); } if (memberships) { /* If we have to return the membership vectors at each level, store the new * membership vector */ IGRAPH_CHECK(igraph_matrix_add_rows(memberships, 1)); IGRAPH_CHECK(igraph_matrix_set_row(memberships, &level_membership, level - 1)); } /* debug("Level: %d Communities: %ld Modularity: %f\n", level, (long int) igraph_vcount(&g), (double) q); */ /* Increase the level counter */ level++; } /* It might happen that there are no merges, so every vertex is in its own community. We still might want the modularity score for that. */ if (modularity && igraph_vector_size(modularity) == 0) { igraph_vector_t tmp; igraph_real_t mod; int i; IGRAPH_VECTOR_INIT_FINALLY(&tmp, vcount); for (i = 0; i < vcount; i++) { VECTOR(tmp)[i] = i; } IGRAPH_CHECK(igraph_modularity(graph, &tmp, weights, resolution, /* only undirected */ 0, &mod)); igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_vector_resize(modularity, 1)); VECTOR(*modularity)[0] = mod; } /* If we need the final membership vector, copy it to the output */ if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, vcount)); for (i = 0; i < vcount; i++) { VECTOR(*membership)[i] = VECTOR(level_membership)[i]; } } /* Destroy the copy of the graph */ igraph_destroy(&g); /* Destroy the temporary vectors */ igraph_vector_destroy(&m); igraph_vector_destroy(&w); igraph_vector_destroy(&level_membership); IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; } leidenbase/src/core/community/fluid.c0000644000176200001440000002644714447675374017421 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_adjlist.h" #include "igraph_components.h" #include "igraph_interface.h" #include "igraph_random.h" #include "igraph_structural.h" /** * \ingroup communities * \function igraph_community_fluid_communities * \brief Community detection based on fluids interacting on the graph. * * The algorithm is based on the simple idea of * several fluids interacting in a non-homogeneous environment * (the graph topology), expanding and contracting based on their * interaction and density. * * This function implements the community detection method described in: * Parés F, Gasulla DG, et. al. (2018) Fluid Communities: A Competitive, * Scalable and Diverse Community Detection Algorithm. In: Complex Networks * & Their Applications VI: Proceedings of Complex Networks 2017 (The Sixth * International Conference on Complex Networks and Their Applications), * Springer, vol 689, p 229. * * \param graph The input graph. The graph must be simple and connected. * Empty graphs are not supported as well as single vertex graphs. * Edge directions are ignored. Weights are not considered. * \param no_of_communities The number of communities to be found. Must be * greater than 0 and fewer than number of vertices in the graph. * \param membership The result vector mapping vertices to the communities * they are assigned to. * \param modularity If not a null pointer, then it must be a pointer * to a real number. The modularity score of the detected community * structure is stored here. * \return Error code. * * Time complexity: O(|E|) */ int igraph_community_fluid_communities(const igraph_t *graph, igraph_integer_t no_of_communities, igraph_vector_t *membership, igraph_real_t *modularity) { /* Declaration of variables */ long int no_of_nodes, i, j, k, kv1; igraph_adjlist_t al; double max_density; igraph_bool_t res, running; igraph_vector_t node_order, density, label_counters, dominant_labels, nonzero_labels; igraph_vector_int_t com_to_numvertices; /* Initialization of variables needed for initial checking */ no_of_nodes = igraph_vcount(graph); /* Checking input values */ if (no_of_nodes < 2) { if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); igraph_vector_fill(membership, 0); } if (modularity) { IGRAPH_CHECK(igraph_modularity(graph, membership, 0, 1, igraph_is_directed(graph), modularity)); } return IGRAPH_SUCCESS; } if ((long int) no_of_communities < 1) { IGRAPH_ERROR("Number of requested communities must be greater than zero.", IGRAPH_EINVAL); } if ((long int) no_of_communities > no_of_nodes) { IGRAPH_ERROR("Number of requested communities must not be greater than the number of nodes.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_is_simple(graph, &res)); if (!res) { IGRAPH_ERROR("Fluid community detection supports only simple graphs.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_is_connected(graph, &res, IGRAPH_WEAK)); if (!res) { IGRAPH_ERROR("Fluid community detection supports only connected graphs.", IGRAPH_EINVAL); } if (igraph_is_directed(graph)) { IGRAPH_WARNING("Edge directions are ignored by fluid community detection."); } /* Internal variables initialization */ max_density = 1.0; /* Resize membership vector (number of nodes) */ IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); /* Initialize density and com_to_numvertices vectors */ IGRAPH_CHECK(igraph_vector_init(&density, (long int) no_of_communities)); IGRAPH_FINALLY(igraph_vector_destroy, &density); IGRAPH_CHECK(igraph_vector_int_init(&com_to_numvertices, (long int) no_of_communities)); IGRAPH_FINALLY(igraph_vector_int_destroy, &com_to_numvertices); /* Initialize node ordering vector */ IGRAPH_CHECK(igraph_vector_init_seq(&node_order, 0, no_of_nodes - 1)); IGRAPH_FINALLY(igraph_vector_destroy, &node_order); /* Initialize the membership vector with 0 values */ igraph_vector_null(membership); /* Initialize densities to max_density */ igraph_vector_fill(&density, max_density); /* Initialize com_to_numvertices and initialize communities into membership vector */ IGRAPH_CHECK(igraph_vector_shuffle(&node_order)); for (i = 0; i < no_of_communities; i++) { /* Initialize membership at initial nodes for each community * where 0 refers to have no label*/ VECTOR(*membership)[(long int)VECTOR(node_order)[i]] = i + 1.0; /* Initialize com_to_numvertices list: Number of vertices for each community */ VECTOR(com_to_numvertices)[i] = 1; } /* Create an adjacency list representation for efficiency. */ IGRAPH_CHECK(igraph_adjlist_init(graph, &al, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &al); /* Create storage space for counting distinct labels and dominant ones */ IGRAPH_VECTOR_INIT_FINALLY(&dominant_labels, (long int) no_of_communities); IGRAPH_VECTOR_INIT_FINALLY(&nonzero_labels, (long int) no_of_communities); IGRAPH_CHECK(igraph_vector_init(&label_counters, (long int) no_of_communities)); IGRAPH_FINALLY(igraph_vector_destroy, &label_counters); /* running is the convergence boolean variable */ running = 1; while (running) { /* Declarations of varibales used inside main loop */ long int v1, size, rand_idx; igraph_real_t max_count, label_counter_diff; igraph_vector_int_t *neis; igraph_bool_t same_label_in_dominant; running = 0; /* Shuffle the node ordering vector */ IGRAPH_CHECK(igraph_vector_shuffle(&node_order)); /* In the prescribed order, loop over the vertices and reassign labels */ for (i = 0; i < no_of_nodes; i++) { /* Clear dominant_labels and nonzero_labels vectors */ igraph_vector_clear(&dominant_labels); igraph_vector_null(&label_counters); /* Obtain actual node index */ v1 = (long int) VECTOR(node_order)[i]; /* Take into account same label in updating rule */ kv1 = (long int) VECTOR(*membership)[v1]; max_count = 0.0; if (kv1 != 0) { VECTOR(label_counters)[kv1 - 1] += VECTOR(density)[kv1 - 1]; /* Set up max_count */ max_count = VECTOR(density)[kv1 - 1]; /* Initialize dominant_labels */ IGRAPH_CHECK(igraph_vector_resize(&dominant_labels, 1)); VECTOR(dominant_labels)[0] = kv1; } /* Count the weights corresponding to different labels */ neis = igraph_adjlist_get(&al, v1); size = igraph_vector_int_size(neis); for (j = 0; j < size; j++) { k = (long int) VECTOR(*membership)[(long)VECTOR(*neis)[j]]; /* skip if it has no label yet */ if (k == 0) { continue; } /* Update label counter and evaluate diff against max_count*/ VECTOR(label_counters)[k - 1] += VECTOR(density)[k - 1]; label_counter_diff = VECTOR(label_counters)[k - 1] - max_count; /* Check if this label must be included in dominant_labels vector */ if (label_counter_diff > 0.0001) { max_count = VECTOR(label_counters)[k - 1]; IGRAPH_CHECK(igraph_vector_resize(&dominant_labels, 1)); VECTOR(dominant_labels)[0] = k; } else if (-0.0001 < label_counter_diff && label_counter_diff < 0.0001) { IGRAPH_CHECK(igraph_vector_push_back(&dominant_labels, k)); } } RNG_BEGIN(); if (!igraph_vector_empty(&dominant_labels)) { /* Maintain same label if it exists in dominant_labels */ same_label_in_dominant = igraph_vector_contains(&dominant_labels, kv1); if (!same_label_in_dominant) { /* We need at least one more iteration */ running = 1; /* Select randomly from the dominant labels */ rand_idx = RNG_INTEGER(0, igraph_vector_size(&dominant_labels) - 1); k = (long int) VECTOR(dominant_labels)[rand_idx]; if (kv1 != 0) { /* Subtract 1 vertex from corresponding community in com_to_numvertices */ VECTOR(com_to_numvertices)[kv1 - 1] -= 1; /* Re-calculate density for community kv1 */ VECTOR(density)[kv1 - 1] = max_density / VECTOR(com_to_numvertices)[kv1 - 1]; } /* Update vertex new label */ VECTOR(*membership)[v1] = k; /* Add 1 vertex to corresponding new community in com_to_numvertices */ VECTOR(com_to_numvertices)[k - 1] += 1; /* Re-calculate density for new community k */ VECTOR(density)[k - 1] = max_density / VECTOR(com_to_numvertices)[k - 1]; } } RNG_END(); } } /* Shift back the membership vector */ /* There must be no 0 labels in membership vector at this point */ for (i = 0; i < no_of_nodes; i++) { VECTOR(*membership)[i] -= 1; /* Something went wrong: At least one vertex has no community assigned */ if (VECTOR(*membership)[i] < 0) { IGRAPH_ERROR("Something went wrong during execution. One or more vertices got " "no community assigned at algorithm convergence.", IGRAPH_EINTERNAL); } } igraph_adjlist_destroy(&al); IGRAPH_FINALLY_CLEAN(1); if (modularity) { IGRAPH_CHECK(igraph_modularity(graph, membership, NULL, /* resolution */ 1, /* only undirected */ 0, modularity)); } igraph_vector_destroy(&node_order); igraph_vector_destroy(&density); igraph_vector_int_destroy(&com_to_numvertices); igraph_vector_destroy(&label_counters); igraph_vector_destroy(&dominant_labels); igraph_vector_destroy(&nonzero_labels); IGRAPH_FINALLY_CLEAN(6); return IGRAPH_SUCCESS; } leidenbase/src/core/community/infomap/0000755000176200001440000000000014532173045017545 5ustar liggesusersleidenbase/src/core/community/infomap/infomap_Node.cc0000644000176200001440000000430314447675374022473 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "infomap_Node.h" using namespace std; Node::Node() { exit = 0.0; size = 0.0; selfLink = 0.0; } Node::Node(int nodenr, double tpweight) { teleportWeight = tpweight; exit = 0.0; size = 0.0; selfLink = 0.0; members.push_back(nodenr); // members = [nodenr] } void cpyNode(Node *newNode, Node *oldNode) { newNode->exit = oldNode->exit; newNode->size = oldNode->size; newNode->teleportWeight = oldNode->teleportWeight; newNode->danglingSize = oldNode->danglingSize; int Nmembers = oldNode->members.size(); newNode->members = vector(Nmembers); for (int i = 0; i < Nmembers; i++) { newNode->members[i] = oldNode->members[i]; } newNode->selfLink = oldNode->selfLink; int NoutLinks = oldNode->outLinks.size(); newNode->outLinks = vector >(NoutLinks); for (int i = 0; i < NoutLinks; i++) { newNode->outLinks[i].first = oldNode->outLinks[i].first; newNode->outLinks[i].second = oldNode->outLinks[i].second; } int NinLinks = oldNode->inLinks.size(); newNode->inLinks = vector >(NinLinks); for (int i = 0; i < NinLinks; i++) { newNode->inLinks[i].first = oldNode->inLinks[i].first; newNode->inLinks[i].second = oldNode->inLinks[i].second; } } leidenbase/src/core/community/infomap/infomap_FlowGraph.h0000644000176200001440000000407714447675374023351 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FLOWGRAPH_H #define FLOWGRAPH_H #include #include #include "igraph_interface.h" #include "infomap_Node.h" class FlowGraph { private: void init(int n, const igraph_vector_t *nodeWeights); public: FlowGraph(int n); FlowGraph(int n, const igraph_vector_t *nodeWeights); FlowGraph(FlowGraph * fgraph); FlowGraph(FlowGraph * fgraph, int sub_Nnode, int * sub_members); FlowGraph(const igraph_t * graph, const igraph_vector_t *e_weights, const igraph_vector_t *v_weights); ~FlowGraph(); void swap(FlowGraph * fgraph); void initiate(); void eigenvector(); void calibrate(); void back_to(FlowGraph * fgraph); /*************************************************************************/ Node **node; int Nnode; double alpha, beta; int Ndanglings; std::vector danglings; // id of dangling nodes double exit; // double exitFlow; // double exit_log_exit; // double size_log_size; // double nodeSize_log_nodeSize; // \sum_{v in V} p log(p) double codeLength; }; void delete_FlowGraph(FlowGraph *fgraph); #endif leidenbase/src/core/community/infomap/infomap_Node.h0000644000176200001440000000255214447675374022341 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef NODE_H #define NODE_H #include #include #include "igraph_interface.h" class Node { public: Node(); Node(int modulenr, double tpweight); std::vector members; std::vector< std::pair > inLinks; std::vector< std::pair > outLinks; double selfLink; double teleportWeight; double danglingSize; double exit; double size; }; void cpyNode(Node *newNode, Node *oldNode); #endif leidenbase/src/core/community/infomap/infomap_Greedy.cc0000644000176200001440000005442714447675374023041 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "infomap_Greedy.h" #include #define plogp( x ) ( (x) > 0.0 ? (x)*log(x) : 0.0 ) using namespace std; Greedy::Greedy(FlowGraph * fgraph) { graph = fgraph; Nnode = graph->Nnode; alpha = graph->alpha;// teleportation probability beta = 1.0 - alpha; // probability to take normal step Nempty = 0; vector(Nnode).swap(mod_empty); vector(Nnode).swap(node_index); vector(Nnode).swap(mod_exit); vector(Nnode).swap(mod_size); vector(Nnode).swap(mod_danglingSize); vector(Nnode).swap(mod_teleportWeight); vector(Nnode).swap(mod_members); nodeSize_log_nodeSize = graph->nodeSize_log_nodeSize; exit_log_exit = graph->exit_log_exit; size_log_size = graph->size_log_size; exitFlow = graph->exitFlow; Node ** node = graph->node; for (int i = 0; i < Nnode; i++) { // For each module node_index[i] = i; mod_exit[i] = node[i]->exit; mod_size[i] = node[i]->size; mod_danglingSize[i] = node[i]->danglingSize; mod_teleportWeight[i] = node[i]->teleportWeight; mod_members[i] = node[i]->members.size(); } exit = plogp(exitFlow); codeLength = exit - 2.0 * exit_log_exit + size_log_size - nodeSize_log_nodeSize; } Greedy::~Greedy() { } void delete_Greedy(Greedy *greedy) { delete greedy; } /** Greedy optimizing (as in Blodel and Al.) : * for each vertex (selected in a random order) compute the best possible move within neighborhood */ bool Greedy::optimize() { bool moved = false; Node ** node = graph->node; RNG_BEGIN(); // Generate random enumeration of nodes vector randomOrder(Nnode); for (int i = 0; i < Nnode; i++) { randomOrder[i] = i; } for (int i = 0; i < Nnode - 1; i++) { //int randPos = i ; //XXX int randPos = RNG_INTEGER(i, Nnode - 1); // swap i & randPos int tmp = randomOrder[i]; randomOrder[i] = randomOrder[randPos]; randomOrder[randPos] = tmp; } unsigned int offset = 1; vector redirect(Nnode, 0); vector > > flowNtoM(Nnode); for (int k = 0; k < Nnode; k++) { // Pick nodes in random order int flip = randomOrder[k]; int oldM = node_index[flip]; // Reset offset when int overflows if (offset > INT_MAX) { for (int j = 0; j < Nnode; j++) { redirect[j] = 0; } offset = 1; } // Size of vector with module links int NmodLinks = 0; // For all outLinks int NoutLinks = node[flip]->outLinks.size(); if (NoutLinks == 0) { //dangling node, add node to calculate flow below redirect[oldM] = offset + NmodLinks; flowNtoM[NmodLinks].first = oldM; flowNtoM[NmodLinks].second.first = 0.0; flowNtoM[NmodLinks].second.second = 0.0; NmodLinks++; } else { for (int j = 0; j < NoutLinks; j++) { int nb_M = node_index[node[flip]->outLinks[j].first]; // index destination du lien double nb_flow = node[flip]->outLinks[j].second; // wgt du lien if (redirect[nb_M] >= offset) { flowNtoM[redirect[nb_M] - offset].second.first += nb_flow; } else { redirect[nb_M] = offset + NmodLinks; flowNtoM[NmodLinks].first = nb_M; flowNtoM[NmodLinks].second.first = nb_flow; flowNtoM[NmodLinks].second.second = 0.0; NmodLinks++; } } } // For all inLinks int NinLinks = node[flip]->inLinks.size(); for (int j = 0; j < NinLinks; j++) { int nb_M = node_index[node[flip]->inLinks[j].first]; double nb_flow = node[flip]->inLinks[j].second; if (redirect[nb_M] >= offset) { flowNtoM[redirect[nb_M] - offset].second.second += nb_flow; } else { redirect[nb_M] = offset + NmodLinks; flowNtoM[NmodLinks].first = nb_M; flowNtoM[NmodLinks].second.first = 0.0; flowNtoM[NmodLinks].second.second = nb_flow; NmodLinks++; } } // For teleportation and dangling nodes for (int j = 0; j < NmodLinks; j++) { int newM = flowNtoM[j].first; if (newM == oldM) { flowNtoM[j].second.first += (alpha * node[flip]->size + beta * node[flip]->danglingSize) * (mod_teleportWeight[oldM] - node[flip]->teleportWeight); flowNtoM[j].second.second += (alpha * (mod_size[oldM] - node[flip]->size) + beta * (mod_danglingSize[oldM] - node[flip]->danglingSize)) * node[flip]->teleportWeight; } else { flowNtoM[j].second.first += (alpha * node[flip]->size + beta * node[flip]->danglingSize) * mod_teleportWeight[newM]; flowNtoM[j].second.second += (alpha * mod_size[newM] + beta * mod_danglingSize[newM] ) * node[flip]->teleportWeight; } } // Calculate flow to/from own module (default value if no link to // own module) double outFlowOldM = (alpha * node[flip]->size + beta * node[flip]->danglingSize) * (mod_teleportWeight[oldM] - node[flip]->teleportWeight) ; double inFlowOldM = (alpha * (mod_size[oldM] - node[flip]->size) + beta * (mod_danglingSize[oldM] - node[flip]->danglingSize)) * node[flip]->teleportWeight; if (redirect[oldM] >= offset) { outFlowOldM = flowNtoM[redirect[oldM] - offset].second.first; inFlowOldM = flowNtoM[redirect[oldM] - offset].second.second; } // Option to move to empty module (if node not already alone) if (mod_members[oldM] > static_cast(node[flip]->members.size())) { if (Nempty > 0) { flowNtoM[NmodLinks].first = mod_empty[Nempty - 1]; flowNtoM[NmodLinks].second.first = 0.0; flowNtoM[NmodLinks].second.second = 0.0; NmodLinks++; } } // Randomize link order for optimized search for (int j = 0; j < NmodLinks - 1; j++) { //int randPos = j ; // XXX int randPos = RNG_INTEGER(j, NmodLinks - 1); int tmp_M = flowNtoM[j].first; double tmp_outFlow = flowNtoM[j].second.first; double tmp_inFlow = flowNtoM[j].second.second; flowNtoM[j].first = flowNtoM[randPos].first; flowNtoM[j].second.first = flowNtoM[randPos].second.first; flowNtoM[j].second.second = flowNtoM[randPos].second.second; flowNtoM[randPos].first = tmp_M; flowNtoM[randPos].second.first = tmp_outFlow; flowNtoM[randPos].second.second = tmp_inFlow; } int bestM = oldM; double best_outFlow = 0.0; double best_inFlow = 0.0; double best_delta = 0.0; // Find the move that minimizes the description length for (int j = 0; j < NmodLinks; j++) { int newM = flowNtoM[j].first; double outFlowNewM = flowNtoM[j].second.first; double inFlowNewM = flowNtoM[j].second.second; if (newM != oldM) { double delta_exit = plogp(exitFlow + outFlowOldM + inFlowOldM - outFlowNewM - inFlowNewM) - exit; double delta_exit_log_exit = - plogp(mod_exit[oldM]) - plogp(mod_exit[newM]) + plogp(mod_exit[oldM] - node[flip]->exit + outFlowOldM + inFlowOldM) + plogp(mod_exit[newM] + node[flip]->exit - outFlowNewM - inFlowNewM); double delta_size_log_size = - plogp(mod_exit[oldM] + mod_size[oldM]) - plogp(mod_exit[newM] + mod_size[newM]) + plogp(mod_exit[oldM] + mod_size[oldM] - node[flip]->exit - node[flip]->size + outFlowOldM + inFlowOldM) + plogp(mod_exit[newM] + mod_size[newM] + node[flip]->exit + node[flip]->size - outFlowNewM - inFlowNewM); double deltaL = delta_exit - 2.0 * delta_exit_log_exit + delta_size_log_size; if (deltaL - best_delta < -1e-10) { bestM = newM; best_outFlow = outFlowNewM; best_inFlow = inFlowNewM; best_delta = deltaL; } } } // Make best possible move if (bestM != oldM) { //Update empty module vector if (mod_members[bestM] == 0) { Nempty--; } if (mod_members[oldM] == static_cast(node[flip]->members.size())) { mod_empty[Nempty] = oldM; Nempty++; } exitFlow -= mod_exit[oldM] + mod_exit[bestM]; exit_log_exit -= plogp(mod_exit[oldM]) + plogp(mod_exit[bestM]); size_log_size -= plogp(mod_exit[oldM] + mod_size[oldM]) + plogp(mod_exit[bestM] + mod_size[bestM]); mod_exit[oldM] -= node[flip]->exit - outFlowOldM - inFlowOldM; mod_size[oldM] -= node[flip]->size; mod_danglingSize[oldM] -= node[flip]->danglingSize; mod_teleportWeight[oldM] -= node[flip]->teleportWeight; mod_members[oldM] -= node[flip]->members.size(); mod_exit[bestM] += node[flip]->exit - best_outFlow - best_inFlow; mod_size[bestM] += node[flip]->size; mod_danglingSize[bestM] += node[flip]->danglingSize; mod_teleportWeight[bestM] += node[flip]->teleportWeight; mod_members[bestM] += node[flip]->members.size(); exitFlow += mod_exit[oldM] + mod_exit[bestM]; // Update terms in map equation exit_log_exit += plogp(mod_exit[oldM]) + plogp(mod_exit[bestM]); size_log_size += plogp(mod_exit[oldM] + mod_size[oldM]) + plogp(mod_exit[bestM] + mod_size[bestM]); exit = plogp(exitFlow); // Update code length codeLength = exit - 2.0 * exit_log_exit + size_log_size - nodeSize_log_nodeSize; node_index[flip] = bestM; moved = true; } offset += Nnode; } RNG_END(); return moved; } /** Apply the move to the given network */ void Greedy::apply(bool sort) { //void Greedy::level(Node ***node_tmp, bool sort) { //old fct prepare(sort) vector modSnode; // will give ids of no-empty modules (nodes) int Nmod = 0; if (sort) { multimap Msize; for (int i = 0; i < Nnode; i++) { if (mod_members[i] > 0) { Nmod++; Msize.insert(pair(mod_size[i], i)); } } for (multimap::reverse_iterator it = Msize.rbegin(); it != Msize.rend(); it++) { modSnode.push_back(it->second); } } else { for (int i = 0; i < Nnode; i++) { if (mod_members[i] > 0) { Nmod++; modSnode.push_back(i); } } } //modSnode[id_when_no_empty_node] = id_in_mod_tbl // Create the new graph FlowGraph * tmp_fgraph = new FlowGraph(Nmod); IGRAPH_FINALLY(delete_FlowGraph, tmp_fgraph); Node ** node_tmp = tmp_fgraph->node ; Node ** node = graph->node; vector nodeInMod = vector(Nnode); // creation of new nodes for (int i = 0; i < Nmod; i++) { //node_tmp[i] = new Node(); vector().swap(node_tmp[i]->members); // clear membership node_tmp[i]->exit = mod_exit[modSnode[i]]; node_tmp[i]->size = mod_size[modSnode[i]]; node_tmp[i]->danglingSize = mod_danglingSize[modSnode[i]]; node_tmp[i]->teleportWeight = mod_teleportWeight[modSnode[i]]; nodeInMod[modSnode[i]] = i; } //nodeInMode[id_in_mod_tbl] = id_when_no_empty_node // Calculate outflow of links to different modules vector > outFlowNtoM(Nmod); map::iterator it_M; for (int i = 0; i < Nnode; i++) { int i_M = nodeInMod[node_index[i]]; //final id of the module of the node i // add node members to the module copy( node[i]->members.begin(), node[i]->members.end(), back_inserter( node_tmp[i_M]->members ) ); int NoutLinks = node[i]->outLinks.size(); for (int j = 0; j < NoutLinks; j++) { int nb = node[i]->outLinks[j].first; int nb_M = nodeInMod[node_index[nb]]; double nb_flow = node[i]->outLinks[j].second; if (nb != i) { it_M = outFlowNtoM[i_M].find(nb_M); if (it_M != outFlowNtoM[i_M].end()) { it_M->second += nb_flow; } else { outFlowNtoM[i_M].insert(make_pair(nb_M, nb_flow)); } } } } // Create outLinks at new level for (int i = 0; i < Nmod; i++) { for (it_M = outFlowNtoM[i].begin(); it_M != outFlowNtoM[i].end(); it_M++) { if (it_M->first != i) { node_tmp[i]->outLinks.push_back(make_pair(it_M->first, it_M->second)); } } } // Calculate inflow of links from different modules vector > inFlowNtoM(Nmod); for (int i = 0; i < Nnode; i++) { int i_M = nodeInMod[node_index[i]]; int NinLinks = node[i]->inLinks.size(); for (int j = 0; j < NinLinks; j++) { int nb = node[i]->inLinks[j].first; int nb_M = nodeInMod[node_index[nb]]; double nb_flow = node[i]->inLinks[j].second; if (nb != i) { it_M = inFlowNtoM[i_M].find(nb_M); if (it_M != inFlowNtoM[i_M].end()) { it_M->second += nb_flow; } else { inFlowNtoM[i_M].insert(make_pair(nb_M, nb_flow)); } } } } // Create inLinks at new level for (int i = 0; i < Nmod; i++) { for (it_M = inFlowNtoM[i].begin(); it_M != inFlowNtoM[i].end(); it_M++) { if (it_M->first != i) { node_tmp[i]->inLinks.push_back(make_pair(it_M->first, it_M->second)); } } } // Option to move to empty module vector().swap(mod_empty); Nempty = 0; //swap node between tmp_graph and graph, then destroy tmp_fgraph graph->swap(tmp_fgraph); Nnode = Nmod; delete tmp_fgraph; IGRAPH_FINALLY_CLEAN(1); } /** * RAZ et recalcul : * - mod_exit * - mod_size * - mod_danglingSize * - mod_teleportWeight * - mod_members * and * - exit_log_exit * - size_log_size * - exitFlow * - exit * - codeLength * according to **node / node[i]->index */ void Greedy::tune(void) { exit_log_exit = 0.0; size_log_size = 0.0; exitFlow = 0.0; for (int i = 0; i < Nnode; i++) { mod_exit[i] = 0.0; mod_size[i] = 0.0; mod_danglingSize[i] = 0.0; mod_teleportWeight[i] = 0.0; mod_members[i] = 0; } Node ** node = graph->node; // Update all values except contribution from teleportation for (int i = 0; i < Nnode; i++) { int i_M = node_index[i]; // module id of node i int Nlinks = node[i]->outLinks.size(); mod_size[i_M] += node[i]->size; mod_danglingSize[i_M] += node[i]->danglingSize; mod_teleportWeight[i_M] += node[i]->teleportWeight; mod_members[i_M]++; for (int j = 0; j < Nlinks; j++) { int neighbor = node[i]->outLinks[j].first; double neighbor_w = node[i]->outLinks[j].second; int neighbor_M = node_index[neighbor]; if (i_M != neighbor_M) { // neighbor in an other module mod_exit[i_M] += neighbor_w; } } } // Update contribution from teleportation for (int i = 0; i < Nnode; i++) { mod_exit[i] += (alpha * mod_size[i] + beta * mod_danglingSize[i]) * (1.0 - mod_teleportWeight[i]); } for (int i = 0; i < Nnode; i++) { exit_log_exit += plogp(mod_exit[i]); size_log_size += plogp(mod_exit[i] + mod_size[i]); exitFlow += mod_exit[i]; } exit = plogp(exitFlow); codeLength = exit - 2.0 * exit_log_exit + size_log_size - nodeSize_log_nodeSize; } /* Compute the new CodeSize if modules are merged as indicated by moveTo */ void Greedy::setMove(int *moveTo) { //void Greedy::determMove(int *moveTo) { Node ** node = graph->node; //printf("setMove nNode:%d \n", Nnode); for (int i = 0 ; i < Nnode ; i++) { // pour chaque module int oldM = i; int newM = moveTo[i]; //printf("old -> new : %d -> %d \n", oldM, newM); if (newM != oldM) { // Si je comprend bien : // outFlow... : c'est le "flow" de i-> autre sommet du meme module // inFlow... : c'est le "flow" depuis un autre sommet du meme module --> i double outFlowOldM = (alpha * node[i]->size + beta * node[i]->danglingSize) * (mod_teleportWeight[oldM] - node[i]->teleportWeight); double inFlowOldM = (alpha * (mod_size[oldM] - node[i]->size) + beta * (mod_danglingSize[oldM] - node[i]->danglingSize)) * node[i]->teleportWeight; double outFlowNewM = (alpha * node[i]->size + beta * node[i]->danglingSize) * mod_teleportWeight[newM]; double inFlowNewM = (alpha * mod_size[newM] + beta * mod_danglingSize[newM]) * node[i]->teleportWeight; // For all outLinks int NoutLinks = node[i]->outLinks.size(); for (int j = 0; j < NoutLinks; j++) { int nb_M = node_index[node[i]->outLinks[j].first]; double nb_flow = node[i]->outLinks[j].second; if (nb_M == oldM) { outFlowOldM += nb_flow; } else if (nb_M == newM) { outFlowNewM += nb_flow; } } // For all inLinks int NinLinks = node[i]->inLinks.size(); for (int j = 0; j < NinLinks; j++) { int nb_M = node_index[node[i]->inLinks[j].first]; double nb_flow = node[i]->inLinks[j].second; if (nb_M == oldM) { inFlowOldM += nb_flow; } else if (nb_M == newM) { inFlowNewM += nb_flow; } } // Update empty module vector // RAZ de mod_empty et Nempty ds calibrate() if (mod_members[newM] == 0) { // si le nouveau etait vide, on a un vide de moins... Nempty--; } if (mod_members[oldM] == static_cast(node[i]->members.size())) { // si l'ancien avait la taille de celui qui bouge, un vide de plus mod_empty[Nempty] = oldM; Nempty++; } exitFlow -= mod_exit[oldM] + mod_exit[newM]; exit_log_exit -= plogp(mod_exit[oldM]) + plogp(mod_exit[newM]); size_log_size -= plogp(mod_exit[oldM] + mod_size[oldM]) + plogp(mod_exit[newM] + mod_size[newM]); mod_exit[oldM] -= node[i]->exit - outFlowOldM - inFlowOldM; mod_size[oldM] -= node[i]->size; mod_danglingSize[oldM] -= node[i]->danglingSize; mod_teleportWeight[oldM] -= node[i]->teleportWeight; mod_members[oldM] -= node[i]->members.size(); mod_exit[newM] += node[i]->exit - outFlowNewM - inFlowNewM; mod_size[newM] += node[i]->size; mod_danglingSize[newM] += node[i]->danglingSize; mod_teleportWeight[newM] += node[i]->teleportWeight; mod_members[newM] += node[i]->members.size(); exitFlow += mod_exit[oldM] + mod_exit[newM]; exit_log_exit += plogp(mod_exit[oldM]) + plogp(mod_exit[newM]); size_log_size += plogp(mod_exit[oldM] + mod_size[oldM]) + plogp(mod_exit[newM] + mod_size[newM]); exit = plogp(exitFlow); codeLength = exit - 2.0 * exit_log_exit + size_log_size - nodeSize_log_nodeSize; node_index[i] = newM; } } } leidenbase/src/core/community/infomap/infomap_Greedy.h0000644000176200001440000000423714447675374022675 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef GREEDY_H #define GREEDY_H #include #include #include #include #include "igraph_random.h" #include "infomap_Node.h" #include "infomap_FlowGraph.h" class Greedy { public: Greedy(FlowGraph * fgraph); // initialise les attributs par rapport au graph ~Greedy(); void setMove(int *moveTo); //virtual void determMove(int *moveTo); bool optimize(); //virtual void move(bool &moved); void apply(bool sort); //virtual void level(Node ***, bool sort); void tune(void); /**************************************************************************/ FlowGraph * graph; int Nnode; double exit; double exitFlow; double exit_log_exit; double size_log_size; double nodeSize_log_nodeSize; double codeLength; double alpha, beta; // local copy of fgraph alpha, beta (=alpha - Nnode = graph->Nnode;1) std::vector node_index; // module number of each node int Nempty; std::vector mod_empty; std::vector mod_exit; // version tmp de node std::vector mod_size; std::vector mod_danglingSize; std::vector mod_teleportWeight; std::vector mod_members; }; void delete_Greedy(Greedy *greedy); #endif leidenbase/src/core/community/infomap/infomap.cc0000644000176200001440000002743414447675374021540 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ---- The original version of this file was written by Martin Rosvall email: martin.rosvall@physics.umu.se homePage: http://www.tp.umu.se/~rosvall/ It was integrated in igraph by Emmanuel Navarro email: navarro@irit.fr homePage: http://www.irit.fr/~Emmanuel.Navarro/ */ #include #include "igraph_interface.h" #include "igraph_community.h" #include "core/interruption.h" #include "infomap_Node.h" #include "infomap_Greedy.h" /****************************************************************************/ int infomap_partition(FlowGraph * fgraph, bool rcall) { Greedy * greedy; // save the original graph FlowGraph * cpy_fgraph = new FlowGraph(fgraph); IGRAPH_FINALLY(delete_FlowGraph, cpy_fgraph); int Nnode = cpy_fgraph->Nnode; // "real" number of vertex, ie. number of vertex of the graph int iteration = 0; double outer_oldCodeLength, newCodeLength; int *initial_move = NULL; bool initial_move_done = true; do { // Main loop outer_oldCodeLength = fgraph->codeLength; if (iteration > 0) { /**********************************************************************/ // FIRST PART: re-split the network (if need) // =========================================== // intial_move indicate current clustering initial_move = new int[Nnode]; // new_cluster_id --> old_cluster_id (save curent clustering state) IGRAPH_FINALLY(operator delete [], initial_move); initial_move_done = false; int *subMoveTo = NULL; // enventual new partitionment of original graph if ((iteration % 2 == 0) && (fgraph->Nnode > 1)) { // 0/ Submodule movements : partition each module of the // current partition (rec. call) subMoveTo = new int[Nnode]; // vid_cpy_fgraph --> new_cluster_id (new partition) IGRAPH_FINALLY(operator delete [], subMoveTo); int subModIndex = 0; for (int i = 0 ; i < fgraph->Nnode ; i++) { // partition each non trivial module int sub_Nnode = fgraph->node[i]->members.size(); if (sub_Nnode > 1) { // If the module is not trivial int *sub_members = new int[sub_Nnode]; // id_sub --> id IGRAPH_FINALLY(operator delete [], sub_members); for (int j = 0 ; j < sub_Nnode ; j++) { sub_members[j] = fgraph->node[i]->members[j]; } // extraction of the subgraph FlowGraph *sub_fgraph = new FlowGraph(cpy_fgraph, sub_Nnode, sub_members); IGRAPH_FINALLY(delete_FlowGraph, sub_fgraph); sub_fgraph->initiate(); // recursif call of partitionment on the subgraph infomap_partition(sub_fgraph, true); // Record membership changes for (int j = 0; j < sub_fgraph->Nnode; j++) { int Nmembers = sub_fgraph->node[j]->members.size(); for (int k = 0; k < Nmembers; k++) { subMoveTo[sub_members[sub_fgraph->node[j]->members[k]]] = subModIndex; } initial_move[subModIndex] = i; subModIndex++; } delete sub_fgraph; IGRAPH_FINALLY_CLEAN(1); delete [] sub_members; IGRAPH_FINALLY_CLEAN(1); } else { subMoveTo[fgraph->node[i]->members[0]] = subModIndex; initial_move[subModIndex] = i; subModIndex++; } } } else { // 1/ Single-node movements : allows each node to move (again) // save current modules for (int i = 0; i < fgraph->Nnode; i++) { // for each module int Nmembers = fgraph->node[i]->members.size(); // Module size for (int j = 0; j < Nmembers; j++) { // for each vertex (of the module) initial_move[fgraph->node[i]->members[j]] = i; } } } fgraph->back_to(cpy_fgraph); if (subMoveTo) { Greedy *cpy_greedy = new Greedy(fgraph); IGRAPH_FINALLY(delete_Greedy, cpy_greedy); cpy_greedy->setMove(subMoveTo); cpy_greedy->apply(false); delete_Greedy(cpy_greedy); IGRAPH_FINALLY_CLEAN(1); delete [] subMoveTo; IGRAPH_FINALLY_CLEAN(1); } } /**********************************************************************/ // SECOND PART: greedy optimizing it self // =========================================== double oldCodeLength; do { // greedy optimizing object creation greedy = new Greedy(fgraph); IGRAPH_FINALLY(delete_Greedy, greedy); // Initial move to apply ? if (!initial_move_done && initial_move) { initial_move_done = true; greedy->setMove(initial_move); } oldCodeLength = greedy->codeLength; bool moved = true; int Nloops = 0; //int count = 0; double inner_oldCodeLength = 1000; while (moved) { // main greedy optimizing loop inner_oldCodeLength = greedy->codeLength; moved = greedy->optimize(); Nloops++; //count++; if (fabs(greedy->codeLength - inner_oldCodeLength) < 1.0e-10) // if the move does'n reduce the codelenght -> exit ! { moved = false; } //if (count == 10) { // greedy->tune(); // count = 0; //} } // transform the network to network of modules: greedy->apply(true); newCodeLength = greedy->codeLength; // destroy greedy object delete greedy; IGRAPH_FINALLY_CLEAN(1); } while (oldCodeLength - newCodeLength > 1.0e-10); // while there is some improvement if (iteration > 0) { delete [] initial_move; IGRAPH_FINALLY_CLEAN(1); } iteration++; if (!rcall) { IGRAPH_ALLOW_INTERRUPTION(); } } while (outer_oldCodeLength - newCodeLength > 1.0e-10); delete cpy_fgraph; IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \function igraph_community_infomap * \brief Find community structure that minimizes the expected * description length of a random walker trajectory. * * Implementation of the InfoMap community detection algorithm.of * Martin Rosvall and Carl T. Bergstrom. * * See : * Visualization of the math and the map generator: www.mapequation.org * [2] The original paper: M. Rosvall and C. T. Bergstrom, Maps of * information flow reveal community structure in complex networks, PNAS * 105, 1118 (2008) [http://dx.doi.org/10.1073/pnas.0706851105 , * http://arxiv.org/abs/0707.0609 ] * [3] A more detailed paper: M. Rosvall, D. Axelsson, and C. T. Bergstrom, * The map equation, Eur. Phys. J. Special Topics 178, 13 (2009). * [http://dx.doi.org/10.1140/epjst/e2010-01179-1 , * http://arxiv.org/abs/0906.1405 ] * * The original C++ implementation of Martin Rosvall is used, * see http://www.tp.umu.se/~rosvall/downloads/infomap_undir.tgz . * Intergation in igraph has be done by Emmanuel Navarro (who is grateful to * Martin Rosvall and Carl T. Bergstrom for providing this source code.) * * * Note that the graph must not contain isolated vertices. * * * If you want to specify a random seed (as in original * implementation) you can use \ref igraph_rng_seed(). * * \param graph The input graph. * \param e_weights Numeric vector giving the weights of the edges. * If it is a NULL pointer then all edges will have equal * weights. The weights are expected to be positive. * \param v_weights Numeric vector giving the weights of the vertices. * If it is a NULL pointer then all vertices will have equal * weights. The weights are expected to be positive. * \param nb_trials The number of attempts to partition the network * (can be any integer value equal or larger than 1). * \param membership Pointer to a vector. The membership vector is * stored here. * \param codelength Pointer to a real. If not NULL the code length of the * partition is stored here. * \return Error code. * * \sa \ref igraph_community_spinglass(), \ref * igraph_community_edge_betweenness(), \ref igraph_community_walktrap(). * * Time complexity: TODO. */ int igraph_community_infomap(const igraph_t * graph, const igraph_vector_t *e_weights, const igraph_vector_t *v_weights, int nb_trials, igraph_vector_t *membership, igraph_real_t *codelength) { FlowGraph * fgraph = new FlowGraph(graph, e_weights, v_weights); IGRAPH_FINALLY(delete_FlowGraph, fgraph); // compute stationary distribution fgraph->initiate(); FlowGraph * cpy_fgraph ; double shortestCodeLength = 1000.0; // create membership vector int Nnode = fgraph->Nnode; IGRAPH_CHECK(igraph_vector_resize(membership, Nnode)); for (int trial = 0; trial < nb_trials; trial++) { cpy_fgraph = new FlowGraph(fgraph); IGRAPH_FINALLY(delete_FlowGraph, cpy_fgraph); //partition the network IGRAPH_CHECK(infomap_partition(cpy_fgraph, false)); // if better than the better... if (cpy_fgraph->codeLength < shortestCodeLength) { shortestCodeLength = cpy_fgraph->codeLength; // ... store the partition for (int i = 0 ; i < cpy_fgraph->Nnode ; i++) { int Nmembers = cpy_fgraph->node[i]->members.size(); for (int k = 0; k < Nmembers; k++) { //cluster[ cpy_fgraph->node[i]->members[k] ] = i; VECTOR(*membership)[cpy_fgraph->node[i]->members[k]] = i; } } } delete_FlowGraph(cpy_fgraph); IGRAPH_FINALLY_CLEAN(1); } *codelength = (igraph_real_t) shortestCodeLength / log(2.0); delete fgraph; IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_reindex_membership(membership, 0, 0)); return IGRAPH_SUCCESS; } leidenbase/src/core/community/infomap/infomap_FlowGraph.cc0000644000176200001440000003122714447675374023504 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "infomap_FlowGraph.h" #define plogp( x ) ( (x) > 0.0 ? (x)*log(x) : 0.0 ) using namespace std; void FlowGraph::init(int n, const igraph_vector_t *v_weights) { alpha = 0.15; beta = 1.0 - alpha; Nnode = n; node = new Node*[Nnode]; if (v_weights) { for (int i = 0; i < Nnode; i++) { node[i] = new Node(i, (double)VECTOR(*v_weights)[i]); } } else { for (int i = 0; i < Nnode; i++) { node[i] = new Node(i, 1.0); } } } FlowGraph::FlowGraph(int n) { init(n, NULL); } FlowGraph::FlowGraph(int n, const igraph_vector_t *v_weights) { init(n, v_weights); } /* Build the graph from igraph_t object */ FlowGraph::FlowGraph(const igraph_t * graph, const igraph_vector_t *e_weights, const igraph_vector_t *v_weights) { int n = (int)igraph_vcount(graph); init(n, v_weights); int directed = (int) igraph_is_directed(graph); double linkWeight = 1.0; igraph_integer_t from, to; long int Nlinks = (long int) igraph_ecount(graph); if (!directed) { Nlinks = Nlinks * 2 ; } for (int i = 0; i < Nlinks; i++) { if (!directed) { // not directed if (i % 2 == 0) { linkWeight = e_weights ? (double)VECTOR(*e_weights)[i / 2] : 1.0; igraph_edge(graph, i / 2, &from, &to); } else { igraph_edge(graph, (i - 1) / 2, &to, &from); } } else { // directed linkWeight = e_weights ? (double)VECTOR(*e_weights)[i] : 1.0; igraph_edge(graph, i, &from, &to); } // Populate node from igraph_graph if (linkWeight > 0.0) { if (from != to) { node[(int) from]->outLinks.push_back(make_pair((int)to, linkWeight)); node[(int) to]->inLinks.push_back(make_pair((int) from, linkWeight)); } } } } FlowGraph::FlowGraph(FlowGraph * fgraph) { int n = fgraph->Nnode; init(n, NULL); for (int i = 0; i < n; i++) { cpyNode(node[i], fgraph->node[i]); } //XXX: quid de danglings et Ndanglings? alpha = fgraph->alpha ; beta = fgraph->beta ; exit = fgraph->exit; exitFlow = fgraph->exitFlow; exit_log_exit = fgraph->exit_log_exit; size_log_size = fgraph->size_log_size ; nodeSize_log_nodeSize = fgraph->nodeSize_log_nodeSize; codeLength = fgraph->codeLength; } /** construct a graph by extracting a subgraph from the given graph */ FlowGraph::FlowGraph(FlowGraph * fgraph, int sub_Nnode, int * sub_members) { init(sub_Nnode, NULL); //XXX: use set of integer to ensure that elements are sorted set sub_mem; for (int j = 0 ; j < sub_Nnode ; j++) { sub_mem.insert(sub_members[j]); } set::iterator it_mem = sub_mem.begin(); vector sub_renumber = vector(fgraph->Nnode); // id --> sub_id for (int j = 0; j < fgraph->Nnode; j++) { sub_renumber[j] = -1; } for (int j = 0; j < sub_Nnode; j++) { //int orig_nr = sub_members[j]; int orig_nr = (*it_mem); node[j]->teleportWeight = fgraph->node[orig_nr]->teleportWeight; node[j]->selfLink = fgraph->node[orig_nr]->selfLink; // Take care of self-link int orig_NoutLinks = fgraph->node[orig_nr]->outLinks.size(); int orig_NinLinks = fgraph->node[orig_nr]->inLinks.size(); sub_renumber[orig_nr] = j; for (int k = 0; k < orig_NoutLinks; k++) { int to = fgraph->node[orig_nr]->outLinks[k].first; int to_newnr = sub_renumber[to]; double link_weight = fgraph->node[orig_nr]->outLinks[k].second; if (to < orig_nr) { // we add links if the destination (to) has already be seen // (ie. smaller than current id) => orig if (sub_mem.find(to) != sub_mem.end()) { // printf("%2d | %4d to %4d\n", j, orig_nr, to); // printf("from %4d (%4d:%1.5f) to %4d (%4d)\n", j, orig_nr, // node[j]->selfLink, to_newnr, to); node[j]->outLinks.push_back(make_pair(to_newnr, link_weight)); node[to_newnr]->inLinks.push_back(make_pair(j, link_weight)); } } } for (int k = 0; k < orig_NinLinks; k++) { int to = fgraph->node[orig_nr]->inLinks[k].first; int to_newnr = sub_renumber[to]; double link_weight = fgraph->node[orig_nr]->inLinks[k].second; if (to < orig_nr) { if (sub_mem.find(to) != sub_mem.end()) { node[j]->inLinks.push_back(make_pair(to_newnr, link_weight)); node[to_newnr]->outLinks.push_back(make_pair(j, link_weight)); } } } it_mem++; } } FlowGraph::~FlowGraph() { //printf("delete FlowGraph !\n"); for (int i = 0; i < Nnode; i++) { delete node[i]; } delete [] node; } void delete_FlowGraph(FlowGraph *fgraph) { delete fgraph; } /** Swap the graph with the one given the graph is "re" calibrate but NOT the given one. */ void FlowGraph::swap(FlowGraph * fgraph) { Node ** node_tmp = fgraph->node; int Nnode_tmp = fgraph->Nnode; fgraph->node = node; fgraph->Nnode = Nnode; node = node_tmp; Nnode = Nnode_tmp; calibrate(); } /** Initialisation of the graph, compute the flow inside the graph * - count danglings nodes * - normalized edge weights * - Call eigenvector() to compute steady state distribution * - call calibrate to compute codelenght */ void FlowGraph::initiate() { // Take care of dangling nodes, normalize outLinks, and calculate // total teleport weight Ndanglings = 0; double totTeleportWeight = 0.0; for (int i = 0; i < Nnode; i++) { totTeleportWeight += node[i]->teleportWeight; } for (int i = 0; i < Nnode; i++) { node[i]->teleportWeight /= totTeleportWeight; // normalize teleportation weight if (node[i]->outLinks.empty() && (node[i]->selfLink <= 0.0)) { danglings.push_back(i); Ndanglings++; } else { // Normalize the weights int NoutLinks = node[i]->outLinks.size(); double sum = node[i]->selfLink; // Take care of self-links for (int j = 0; j < NoutLinks; j++) { sum += node[i]->outLinks[j].second; } node[i]->selfLink /= sum; for (int j = 0; j < NoutLinks; j++) { node[i]->outLinks[j].second /= sum; } } } // Calculate steady state matrix eigenvector(); // Update links to represent flow for (int i = 0; i < Nnode; i++) { node[i]->selfLink = beta * node[i]->size * node[i]->selfLink; // (1 - \tau) * \pi_i * P_{ii} if (!node[i]->outLinks.empty()) { int NoutLinks = node[i]->outLinks.size(); for (int j = 0; j < NoutLinks; j++) { node[i]->outLinks[j].second = beta * node[i]->size * node[i]->outLinks[j].second; // (1 - \tau) * \pi_i * P_{ij} } // Update values for corresponding inlink for (int j = 0; j < NoutLinks; j++) { int NinLinks = node[node[i]->outLinks[j].first]->inLinks.size(); for (int k = 0; k < NinLinks; k++) { if (node[node[i]->outLinks[j].first]->inLinks[k].first == i) { node[node[i]->outLinks[j].first]->inLinks[k].second = node[i]->outLinks[j].second; k = NinLinks; } } } } } // To be able to handle dangling nodes efficiently for (int i = 0; i < Nnode; i++) if (node[i]->outLinks.empty() && (node[i]->selfLink <= 0.0)) { node[i]->danglingSize = node[i]->size; } else { node[i]->danglingSize = 0.0; } nodeSize_log_nodeSize = 0.0 ; // The exit flow from each node at initiation for (int i = 0; i < Nnode; i++) { node[i]->exit = node[i]->size // Proba to be on i - (alpha * node[i]->size + beta * node[i]->danglingSize) * node[i]->teleportWeight // Proba teleport back to i - node[i]->selfLink; // Proba stay on i // node[i]->exit == q_{i\exit} nodeSize_log_nodeSize += plogp(node[i]->size); } calibrate(); } /* Compute steady state distribution (ie. PageRank) over the network * (for all i update node[i]->size) */ void FlowGraph::eigenvector() { vector size_tmp = vector(Nnode, 1.0 / Nnode); int Niterations = 0; double danglingSize; double sqdiff = 1.0; double sqdiff_old; double sum; do { // Calculate dangling size danglingSize = 0.0; for (int i = 0; i < Ndanglings; i++) { danglingSize += size_tmp[danglings[i]]; } // Flow from teleportation for (int i = 0; i < Nnode; i++) { node[i]->size = (alpha + beta * danglingSize) * node[i]->teleportWeight; } // Flow from network steps for (int i = 0; i < Nnode; i++) { node[i]->size += beta * node[i]->selfLink * size_tmp[i]; int Nlinks = node[i]->outLinks.size(); for (int j = 0; j < Nlinks; j++) node[node[i]->outLinks[j].first]->size += beta * node[i]->outLinks[j].second * size_tmp[i]; } // Normalize sum = 0.0; for (int i = 0; i < Nnode; i++) { sum += node[i]->size; } sqdiff_old = sqdiff; sqdiff = 0.0; for (int i = 0; i < Nnode; i++) { node[i]->size /= sum; sqdiff += fabs(node[i]->size - size_tmp[i]); size_tmp[i] = node[i]->size; } Niterations++; if (sqdiff == sqdiff_old) { alpha += 1.0e-10; beta = 1.0 - alpha; } } while ((Niterations < 200) && (sqdiff > 1.0e-15 || Niterations < 50)); danglingSize = 0.0; for (int i = 0; i < Ndanglings; i++) { danglingSize += size_tmp[danglings[i]]; } // cout << "done! (the error is " << sqdiff << " after " << Niterations // << " iterations)" << endl; } /* Compute the codeLength of the given network * note: (in **node, one node == one module) */ void FlowGraph::calibrate() { exit_log_exit = 0.0; exitFlow = 0.0; size_log_size = 0.0; for (int i = 0; i < Nnode; i++) { // For each module // own node/module codebook size_log_size += plogp(node[i]->exit + node[i]->size); // use of index codebook exitFlow += node[i]->exit; exit_log_exit += plogp(node[i]->exit); } exit = plogp(exitFlow); codeLength = exit - 2.0 * exit_log_exit + size_log_size - nodeSize_log_nodeSize; } /* Restore the data from the given FlowGraph object */ void FlowGraph::back_to(FlowGraph * fgraph) { // delete current nodes for (int i = 0 ; i < Nnode ; i++) { delete node[i]; } delete [] node; Nnode = fgraph->Nnode; // copy original ones node = new Node*[Nnode]; for (int i = 0; i < Nnode; i++) { node[i] = new Node(); cpyNode(node[i], fgraph->node[i]); } // restore atributs alpha = fgraph->alpha ; beta = fgraph->beta ; exit = fgraph->exit; exitFlow = fgraph->exitFlow; exit_log_exit = fgraph->exit_log_exit; size_log_size = fgraph->size_log_size ; nodeSize_log_nodeSize = fgraph->nodeSize_log_nodeSize; codeLength = fgraph->codeLength; } leidenbase/src/core/community/leiden.c0000644000176200001440000013226614447675374017553 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_adjlist.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_random.h" #include "igraph_stack.h" #include "igraph_vector.h" #include "igraph_constructors.h" #include "core/interruption.h" /* Move nodes in order to improve the quality of a partition. * * This function considers each node and greedily moves it to a neighboring * community that maximizes the improvement in the quality of a partition. * * The nodes are examined in a queue, and initially all nodes are put in the * queue in a random order. Nodes are popped from the queue when they are * examined, and only neighbors of nodes that are moved (which are not part of * the cluster the node was moved to) are pushed to the queue again. * * The \c membership vector is used as the starting point to move around nodes, * and is updated in-place. * */ static int igraph_i_community_leiden_fastmovenodes( const igraph_t *graph, const igraph_inclist_t *edges_per_node, const igraph_vector_t *edge_weights, const igraph_vector_t *node_weights, const igraph_real_t resolution_parameter, igraph_integer_t *nb_clusters, igraph_vector_t *membership) { igraph_dqueue_t unstable_nodes; igraph_real_t max_diff = 0.0, diff = 0.0; igraph_integer_t n = igraph_vcount(graph); igraph_vector_bool_t neighbor_cluster_added, node_is_stable; igraph_vector_t node_order, cluster_weights, edge_weights_per_cluster, neighbor_clusters; igraph_vector_int_t nb_nodes_per_cluster; igraph_stack_t empty_clusters; long int i, j, c, nb_neigh_clusters; /* Initialize queue of unstable nodes and whether node is stable. Only * unstable nodes are in the queue. */ IGRAPH_CHECK(igraph_vector_bool_init(&node_is_stable, n)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &node_is_stable); IGRAPH_CHECK(igraph_dqueue_init(&unstable_nodes, n)); IGRAPH_FINALLY(igraph_dqueue_destroy, &unstable_nodes); /* Shuffle nodes */ IGRAPH_CHECK(igraph_vector_init_seq(&node_order, 0, n - 1)); IGRAPH_FINALLY(igraph_vector_destroy, &node_order); IGRAPH_CHECK(igraph_vector_shuffle(&node_order)); /* Add to the queue */ for (i = 0; i < n; i++) { igraph_dqueue_push(&unstable_nodes, (long int)VECTOR(node_order)[i]); } /* Initialize cluster weights and nb nodes */ IGRAPH_CHECK(igraph_vector_init(&cluster_weights, n)); IGRAPH_FINALLY(igraph_vector_destroy, &cluster_weights); IGRAPH_CHECK(igraph_vector_int_init(&nb_nodes_per_cluster, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &nb_nodes_per_cluster); for (i = 0; i < n; i++) { c = (long int)VECTOR(*membership)[i]; VECTOR(cluster_weights)[c] += VECTOR(*node_weights)[i]; VECTOR(nb_nodes_per_cluster)[c] += 1; } /* Initialize empty clusters */ IGRAPH_CHECK(igraph_stack_init(&empty_clusters, n)); IGRAPH_FINALLY(igraph_stack_destroy, &empty_clusters); for (c = 0; c < n; c++) if (VECTOR(nb_nodes_per_cluster)[c] == 0) { igraph_stack_push(&empty_clusters, c); } /* Initialize vectors to be used in calculating differences */ IGRAPH_CHECK(igraph_vector_init(&edge_weights_per_cluster, n)); IGRAPH_FINALLY(igraph_vector_destroy, &edge_weights_per_cluster); /* Initialize neighboring cluster */ IGRAPH_CHECK(igraph_vector_bool_init(&neighbor_cluster_added, n)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &neighbor_cluster_added); IGRAPH_CHECK(igraph_vector_init(&neighbor_clusters, n)); IGRAPH_FINALLY(igraph_vector_destroy, &neighbor_clusters); /* Iterate while the queue is not empty */ j = 0; while (!igraph_dqueue_empty(&unstable_nodes)) { long int v = (long int) igraph_dqueue_pop(&unstable_nodes); long int best_cluster, current_cluster = VECTOR(*membership)[v]; long int degree, i; igraph_vector_int_t *edges; /* Remove node from current cluster */ VECTOR(cluster_weights)[current_cluster] -= VECTOR(*node_weights)[v]; VECTOR(nb_nodes_per_cluster)[current_cluster]--; if (VECTOR(nb_nodes_per_cluster)[current_cluster] == 0) { IGRAPH_CHECK(igraph_stack_push(&empty_clusters, current_cluster)); } /* Find out neighboring clusters */ c = (long int) igraph_stack_top(&empty_clusters); VECTOR(neighbor_clusters)[0] = c; VECTOR(neighbor_cluster_added)[c] = 1; nb_neigh_clusters = 1; /* Determine the edge weight to each neighboring cluster */ edges = igraph_inclist_get(edges_per_node, v); degree = igraph_vector_int_size(edges); for (i = 0; i < degree; i++) { long int e = VECTOR(*edges)[i]; long int u = (long int)IGRAPH_OTHER(graph, e, v); if (u != v) { c = VECTOR(*membership)[u]; if (!VECTOR(neighbor_cluster_added)[c]) { VECTOR(neighbor_cluster_added)[c] = 1; VECTOR(neighbor_clusters)[nb_neigh_clusters++] = c; } VECTOR(edge_weights_per_cluster)[c] += VECTOR(*edge_weights)[e]; } } /* Calculate maximum diff */ best_cluster = current_cluster; max_diff = VECTOR(edge_weights_per_cluster)[current_cluster] - VECTOR(*node_weights)[v] * VECTOR(cluster_weights)[current_cluster] * resolution_parameter; for (i = 0; i < nb_neigh_clusters; i++) { c = VECTOR(neighbor_clusters)[i]; diff = VECTOR(edge_weights_per_cluster)[c] - VECTOR(*node_weights)[v] * VECTOR(cluster_weights)[c] * resolution_parameter; if (diff > max_diff) { best_cluster = c; max_diff = diff; } VECTOR(edge_weights_per_cluster)[c] = 0.0; VECTOR(neighbor_cluster_added)[c] = 0; } /* Move node to best cluster */ VECTOR(cluster_weights)[best_cluster] += VECTOR(*node_weights)[v]; VECTOR(nb_nodes_per_cluster)[best_cluster]++; if (best_cluster == igraph_stack_top(&empty_clusters)) { igraph_stack_pop(&empty_clusters); } /* Mark node as stable */ VECTOR(node_is_stable)[v] = 1; /* Add stable neighbours that are not part of the new cluster to the queue */ if (best_cluster != current_cluster) { VECTOR(*membership)[v] = best_cluster; for (i = 0; i < degree; i++) { long int e = VECTOR(*edges)[i]; long int u = (long int) IGRAPH_OTHER(graph, e, v); if (VECTOR(node_is_stable)[u] && VECTOR(*membership)[u] != best_cluster) { IGRAPH_CHECK(igraph_dqueue_push(&unstable_nodes, u)); VECTOR(node_is_stable)[u] = 0; } } } j++; if (j > 10000) { IGRAPH_ALLOW_INTERRUPTION(); j = 0; } } IGRAPH_CHECK(igraph_reindex_membership(membership, NULL, nb_clusters)); igraph_vector_destroy(&neighbor_clusters); igraph_vector_bool_destroy(&neighbor_cluster_added); igraph_vector_destroy(&edge_weights_per_cluster); igraph_stack_destroy(&empty_clusters); igraph_vector_int_destroy(&nb_nodes_per_cluster); igraph_vector_destroy(&cluster_weights); igraph_vector_destroy(&node_order); igraph_dqueue_destroy(&unstable_nodes); igraph_vector_bool_destroy(&node_is_stable); IGRAPH_FINALLY_CLEAN(9); return IGRAPH_SUCCESS; } /* Clean a refined membership vector. * * This function examines all nodes in \c node_subset and updates \c * refined_membership to ensure that the clusters are numbered consecutively, * starting from \c nb_refined_clusters. The \c nb_refined_clusters is also * updated itself. If C is the initial \c nb_refined_clusters and C' the * resulting \c nb_refined_clusters, then nodes in \c node_subset are numbered * C, C + 1, ..., C' - 1. */ static int igraph_i_community_leiden_clean_refined_membership( const igraph_vector_t* node_subset, igraph_vector_t *refined_membership, igraph_integer_t* nb_refined_clusters) { long int i, n = igraph_vector_size(node_subset); igraph_vector_t new_cluster; IGRAPH_CHECK(igraph_vector_init(&new_cluster, n)); IGRAPH_FINALLY(igraph_vector_destroy, &new_cluster); /* Clean clusters. We will store the new cluster + 1 so that cluster == 0 * indicates that no membership was assigned yet. */ *nb_refined_clusters += 1; for (i = 0; i < n; i++) { long int v = (long int) VECTOR(*node_subset)[i]; long int c = (long int) VECTOR(*refined_membership)[v]; if (VECTOR(new_cluster)[c] == 0) { VECTOR(new_cluster)[c] = (igraph_real_t)(*nb_refined_clusters); *nb_refined_clusters += 1; } } /* Assign new cluster */ for (i = 0; i < n; i++) { long int v = (long int) VECTOR(*node_subset)[i]; long int c = (long int) VECTOR(*refined_membership)[v]; VECTOR(*refined_membership)[v] = VECTOR(new_cluster)[c] - 1; } /* We used the cluster + 1, so correct */ *nb_refined_clusters -= 1; igraph_vector_destroy(&new_cluster); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Merge nodes for a subset of the nodes. This is used to refine a partition. * * The nodes included in \c node_subset are assumed to be the nodes i for which * membership[i] = cluster_subset. * * All nodes in \c node_subset are initialized to a singleton partition in \c * refined_membership. Only singleton clusters can be merged if they are * sufficiently well connected to the current subgraph induced by \c * node_subset. * * We only examine each node once. Instead of greedily choosing the maximum * possible cluster to merge with, the cluster is chosen randomly among all * possibilities that do not decrease the quality of the partition. The * probability of choosing a certain cluster is proportional to exp(diff/beta). * For beta to 0 this converges to selecting a cluster with the maximum * improvement. For beta to infinity this converges to a uniform distribution * among all eligible clusters. * * The \c refined_membership is updated for node in \c node_subset. The number * of refined clusters, \c nb_refined_clusters is used to set the actual refined * cluster membership and is updated after this routine. Within each cluster * (i.e. for a given \c node_subset), the refined membership is initially simply * set to 0, ..., n - 1 (for n nodes in \c node_subset). However, for each \c * node_subset the refined membership should of course be unique. Hence, after * merging, the refined membership starts with \c nb_refined_clusters, which is * also updated to ensure that the resulting \c nb_refined_clusters counts all * refined clusters that have already been processed. See * igraph_i_community_leiden_clean_refined_membership for more information about * this aspect. */ static int igraph_i_community_leiden_mergenodes( const igraph_t *graph, const igraph_inclist_t *edges_per_node, const igraph_vector_t *edge_weights, const igraph_vector_t *node_weights, const igraph_vector_t *node_subset, const igraph_vector_t *membership, const igraph_integer_t cluster_subset, const igraph_real_t resolution_parameter, const igraph_real_t beta, igraph_integer_t *nb_refined_clusters, igraph_vector_t *refined_membership) { igraph_vector_t node_order; igraph_vector_bool_t non_singleton_cluster, neighbor_cluster_added; igraph_real_t max_diff, total_cum_trans_diff, diff = 0.0, total_node_weight = 0.0; igraph_integer_t n = igraph_vector_size(node_subset); igraph_vector_t cluster_weights, cum_trans_diff, edge_weights_per_cluster, external_edge_weight_per_cluster_in_subset, neighbor_clusters; igraph_vector_int_t *edges, nb_nodes_per_cluster; long int i, j, degree, nb_neigh_clusters; /* Initialize cluster weights */ IGRAPH_CHECK(igraph_vector_init(&cluster_weights, n)); IGRAPH_FINALLY(igraph_vector_destroy, &cluster_weights); /* Initialize number of nodes per cluster */ IGRAPH_CHECK(igraph_vector_int_init(&nb_nodes_per_cluster, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &nb_nodes_per_cluster); /* Initialize external edge weight per cluster in subset */ IGRAPH_CHECK(igraph_vector_init(&external_edge_weight_per_cluster_in_subset, n)); IGRAPH_FINALLY(igraph_vector_destroy, &external_edge_weight_per_cluster_in_subset); /* Initialize administration for a singleton partition */ for (i = 0; i < n; i++) { long int v = (long int) VECTOR(*node_subset)[i]; VECTOR(*refined_membership)[v] = i; VECTOR(cluster_weights)[i] += VECTOR(*node_weights)[v]; VECTOR(nb_nodes_per_cluster)[i] += 1; total_node_weight += VECTOR(*node_weights)[v]; /* Find out neighboring clusters */ edges = igraph_inclist_get(edges_per_node, v); degree = igraph_vector_int_size(edges); for (j = 0; j < degree; j++) { long int e = VECTOR(*edges)[j]; long int u = (long int)IGRAPH_OTHER(graph, e, v); if (u != v && VECTOR(*membership)[u] == cluster_subset) { VECTOR(external_edge_weight_per_cluster_in_subset)[i] += VECTOR(*edge_weights)[e]; } } } /* Shuffle nodes */ IGRAPH_CHECK(igraph_vector_copy(&node_order, node_subset)); IGRAPH_FINALLY(igraph_vector_destroy, &node_order); IGRAPH_CHECK(igraph_vector_shuffle(&node_order)); /* Initialize non singleton clusters */ IGRAPH_CHECK(igraph_vector_bool_init(&non_singleton_cluster, n)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &non_singleton_cluster); /* Initialize vectors to be used in calculating differences */ IGRAPH_CHECK(igraph_vector_init(&edge_weights_per_cluster, n)); IGRAPH_FINALLY(igraph_vector_destroy, &edge_weights_per_cluster); /* Initialize neighboring cluster */ IGRAPH_CHECK(igraph_vector_bool_init(&neighbor_cluster_added, n)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &neighbor_cluster_added); IGRAPH_CHECK(igraph_vector_init(&neighbor_clusters, n)); IGRAPH_FINALLY(igraph_vector_destroy, &neighbor_clusters); /* Initialize cumulative transformed difference */ IGRAPH_CHECK(igraph_vector_init(&cum_trans_diff, n)); IGRAPH_FINALLY(igraph_vector_destroy, &cum_trans_diff); RNG_BEGIN(); for (i = 0; i < n; i++) { long int v = (long int) VECTOR(node_order)[i]; long int chosen_cluster, best_cluster, current_cluster = (long int) VECTOR(*refined_membership)[v]; if (!VECTOR(non_singleton_cluster)[current_cluster] && (VECTOR(external_edge_weight_per_cluster_in_subset)[current_cluster] >= VECTOR(cluster_weights)[current_cluster] * (total_node_weight - VECTOR(cluster_weights)[current_cluster]) * resolution_parameter)) { /* Remove node from current cluster, which is then a singleton by * definition. */ VECTOR(cluster_weights)[current_cluster] = 0.0; VECTOR(nb_nodes_per_cluster)[current_cluster] = 0; /* Find out neighboring clusters */ edges = igraph_inclist_get(edges_per_node, v); degree = igraph_vector_int_size(edges); /* Also add current cluster to ensure it can be chosen. */ VECTOR(neighbor_clusters)[0] = current_cluster; VECTOR(neighbor_cluster_added)[current_cluster] = 1; nb_neigh_clusters = 1; for (j = 0; j < degree; j++) { long int e = (long int)VECTOR(*edges)[j]; long int u = (long int)IGRAPH_OTHER(graph, e, v); if (u != v && VECTOR(*membership)[u] == cluster_subset) { long int c = VECTOR(*refined_membership)[u]; if (!VECTOR(neighbor_cluster_added)[c]) { VECTOR(neighbor_cluster_added)[c] = 1; VECTOR(neighbor_clusters)[nb_neigh_clusters++] = c; } VECTOR(edge_weights_per_cluster)[c] += VECTOR(*edge_weights)[e]; } } /* Calculate diffs */ best_cluster = current_cluster; max_diff = 0.0; total_cum_trans_diff = 0.0; for (j = 0; j < nb_neigh_clusters; j++) { long int c = (long int) VECTOR(neighbor_clusters)[j]; if (VECTOR(external_edge_weight_per_cluster_in_subset)[c] >= VECTOR(cluster_weights)[c] * (total_node_weight - VECTOR(cluster_weights)[c]) * resolution_parameter) { diff = VECTOR(edge_weights_per_cluster)[c] - VECTOR(*node_weights)[v] * VECTOR(cluster_weights)[c] * resolution_parameter; if (diff > max_diff) { best_cluster = c; max_diff = diff; } /* Calculate the transformed difference for sampling */ if (diff >= 0) { total_cum_trans_diff += exp(diff / beta); } } VECTOR(cum_trans_diff)[j] = total_cum_trans_diff; VECTOR(edge_weights_per_cluster)[c] = 0.0; VECTOR(neighbor_cluster_added)[c] = 0; } /* Determine the neighboring cluster to which the currently selected node * will be moved. */ if (total_cum_trans_diff < IGRAPH_INFINITY) { igraph_real_t r = RNG_UNIF(0, total_cum_trans_diff); long int chosen_idx; igraph_vector_binsearch_slice(&cum_trans_diff, r, &chosen_idx, 0, nb_neigh_clusters); chosen_cluster = VECTOR(neighbor_clusters)[chosen_idx]; } else { chosen_cluster = best_cluster; } /* Move node to randomly chosen cluster */ VECTOR(cluster_weights)[chosen_cluster] += VECTOR(*node_weights)[v]; VECTOR(nb_nodes_per_cluster)[chosen_cluster]++; for (j = 0; j < degree; j++) { long int e = (long int) VECTOR(*edges)[j]; long int u = (long int) IGRAPH_OTHER(graph, e, v); if (VECTOR(*membership)[u] == cluster_subset) { if (VECTOR(*refined_membership)[u] == chosen_cluster) { VECTOR(external_edge_weight_per_cluster_in_subset)[chosen_cluster] -= VECTOR(*edge_weights)[e]; } else { VECTOR(external_edge_weight_per_cluster_in_subset)[chosen_cluster] += VECTOR(*edge_weights)[e]; } } } /* Set cluster */ if (chosen_cluster != current_cluster) { VECTOR(*refined_membership)[v] = chosen_cluster; VECTOR(non_singleton_cluster)[chosen_cluster] = 1; } } /* end if singleton and may be merged */ } RNG_END(); IGRAPH_CHECK(igraph_i_community_leiden_clean_refined_membership(node_subset, refined_membership, nb_refined_clusters)); igraph_vector_destroy(&cum_trans_diff); igraph_vector_destroy(&neighbor_clusters); igraph_vector_bool_destroy(&neighbor_cluster_added); igraph_vector_destroy(&edge_weights_per_cluster); igraph_vector_bool_destroy(&non_singleton_cluster); igraph_vector_destroy(&node_order); igraph_vector_destroy(&external_edge_weight_per_cluster_in_subset); igraph_vector_int_destroy(&nb_nodes_per_cluster); igraph_vector_destroy(&cluster_weights); IGRAPH_FINALLY_CLEAN(9); return IGRAPH_SUCCESS; } /* Create clusters out of a membership vector. * * The cluster pointer vector should be initialized for all entries of the * membership vector, no range checking is performed. If a vector for a cluster * does not yet exist it will be created and initialized. If a vector for a * cluster already does exist it will not be emptied on first use. Hence, it * should be ensured that all clusters are always properly empty (or * non-existing) before calling this function. */ static int igraph_i_community_get_clusters(const igraph_vector_t *membership, igraph_vector_ptr_t *clusters) { long int i, c, n = igraph_vector_size(membership); igraph_vector_t *cluster; for (i = 0; i < n; i++) { /* Get cluster for node i */ c = VECTOR(*membership)[i]; cluster = (igraph_vector_t*)VECTOR(*clusters)[c]; /* No cluster vector exists yet, so we create a new one */ if (!cluster) { cluster = IGRAPH_CALLOC(1, igraph_vector_t); if (cluster == 0) { IGRAPH_ERROR("Cannot allocate memory for assigning cluster", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(cluster, 0)); VECTOR(*clusters)[c] = cluster; } /* Add node i to cluster vector */ IGRAPH_CHECK(igraph_vector_push_back(cluster, i)); } return IGRAPH_SUCCESS; } /* Aggregate the graph based on the \c refined membership while setting the * membership of each aggregated node according to the \c membership. * * Technically speaking we have that * aggregated_membership[refined_membership[v]] = membership[v] for each node v. * * The new aggregated graph is returned in \c aggregated_graph. This graph * object should not yet be initialized, `igraph_create` is called on it, and * responsibility for destroying the object lies with the calling method * * The remaining results, aggregated_edge_weights, aggregate_node_weights and * aggregated_membership are all expected to be initialized. * */ static int igraph_i_community_leiden_aggregate( const igraph_t *graph, const igraph_inclist_t *edges_per_node, const igraph_vector_t *edge_weights, const igraph_vector_t *node_weights, const igraph_vector_t *membership, const igraph_vector_t *refined_membership, const igraph_integer_t nb_refined_clusters, igraph_t *aggregated_graph, igraph_vector_t *aggregated_edge_weights, igraph_vector_t *aggregated_node_weights, igraph_vector_t *aggregated_membership) { igraph_vector_t aggregated_edges, edge_weight_to_cluster; igraph_vector_ptr_t refined_clusters; igraph_vector_int_t *incident_edges; igraph_vector_t neighbor_clusters; igraph_vector_bool_t neighbor_cluster_added; long int i, j, c, degree, nb_neigh_clusters; /* Get refined clusters */ IGRAPH_CHECK(igraph_vector_ptr_init(&refined_clusters, nb_refined_clusters)); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&refined_clusters, igraph_vector_destroy); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &refined_clusters); IGRAPH_CHECK(igraph_i_community_get_clusters(refined_membership, &refined_clusters)); /* Initialize new edges */ IGRAPH_CHECK(igraph_vector_init(&aggregated_edges, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &aggregated_edges); /* We clear the aggregated edge weights, we will push each new edge weight */ igraph_vector_clear(aggregated_edge_weights); /* Simply resize the aggregated node weights and membership, they can be set * directly */ IGRAPH_CHECK(igraph_vector_resize(aggregated_node_weights, nb_refined_clusters)); IGRAPH_CHECK(igraph_vector_resize(aggregated_membership, nb_refined_clusters)); IGRAPH_CHECK(igraph_vector_init(&edge_weight_to_cluster, nb_refined_clusters)); IGRAPH_FINALLY(igraph_vector_destroy, &edge_weight_to_cluster); /* Initialize neighboring cluster */ IGRAPH_CHECK(igraph_vector_bool_init(&neighbor_cluster_added, nb_refined_clusters)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &neighbor_cluster_added); IGRAPH_CHECK(igraph_vector_init(&neighbor_clusters, nb_refined_clusters)); IGRAPH_FINALLY(igraph_vector_destroy, &neighbor_clusters); /* Check per cluster */ for (c = 0; c < nb_refined_clusters; c++) { igraph_vector_t* refined_cluster = (igraph_vector_t*)VECTOR(refined_clusters)[c]; long int n_c = igraph_vector_size(refined_cluster); long int v = -1; /* Calculate the total edge weight to other clusters */ VECTOR(*aggregated_node_weights)[c] = 0.0; nb_neigh_clusters = 0; for (i = 0; i < n_c; i++) { v = (long int) VECTOR(*refined_cluster)[i]; incident_edges = igraph_inclist_get(edges_per_node, v); degree = igraph_vector_int_size(incident_edges); for (j = 0; j < degree; j++) { long int e = VECTOR(*incident_edges)[j]; long int u = (long int) IGRAPH_OTHER(graph, e, v); long int c2 = VECTOR(*refined_membership)[u]; if (c2 > c) { if (!VECTOR(neighbor_cluster_added)[c2]) { VECTOR(neighbor_cluster_added)[c2] = 1; VECTOR(neighbor_clusters)[nb_neigh_clusters++] = c2; } VECTOR(edge_weight_to_cluster)[c2] += VECTOR(*edge_weights)[e]; } } VECTOR(*aggregated_node_weights)[c] += VECTOR(*node_weights)[v]; } /* Add actual edges from this cluster to the other clusters */ for (i = 0; i < nb_neigh_clusters; i++) { long int c2 = VECTOR(neighbor_clusters)[i]; /* Add edge */ IGRAPH_CHECK(igraph_vector_push_back(&aggregated_edges, c)); IGRAPH_CHECK(igraph_vector_push_back(&aggregated_edges, c2)); /* Add edge weight */ IGRAPH_CHECK(igraph_vector_push_back(aggregated_edge_weights, VECTOR(edge_weight_to_cluster)[c2])); VECTOR(edge_weight_to_cluster)[c2] = 0.0; VECTOR(neighbor_cluster_added)[c2] = 0; } VECTOR(*aggregated_membership)[c] = VECTOR(*membership)[v]; } igraph_vector_destroy(&neighbor_clusters); igraph_vector_bool_destroy(&neighbor_cluster_added); igraph_vector_destroy(&edge_weight_to_cluster); igraph_vector_ptr_destroy_all(&refined_clusters); IGRAPH_FINALLY_CLEAN(4); igraph_destroy(aggregated_graph); IGRAPH_CHECK(igraph_create(aggregated_graph, &aggregated_edges, nb_refined_clusters, IGRAPH_UNDIRECTED)); igraph_vector_destroy(&aggregated_edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Calculate the quality of the partition. * * The quality is defined as * * 1 / 2m sum_ij (A_ij - gamma n_i n_j)d(s_i, s_j) * * where m is the total edge weight, A_ij is the weight of edge (i, j), gamma is * the so-called resolution parameter, n_i is the node weight of node i, s_i is * the cluster of node i and d(x, y) = 1 if and only if x = y and 0 otherwise. * * Note that by setting n_i = k_i the degree of node i and dividing gamma by 2m, * we effectively optimize modularity. By setting n_i = 1 we optimize the * Constant Potts Model. * * This can be represented as a sum over clusters as * * 1 / 2m sum_c (e_c - gamma N_c^2) * * where e_c = sum_ij A_ij d(s_i, c)d(s_j, c) is (twice) the internal edge * weight in cluster c and N_c = sum_i n_i d(s_i, c) is the sum of the node * weights inside cluster c. This is how the quality is calculated in practice. * */ static int igraph_i_community_leiden_quality( const igraph_t *graph, const igraph_vector_t *edge_weights, const igraph_vector_t *node_weights, const igraph_vector_t *membership, const igraph_integer_t nb_comms, const igraph_real_t resolution_parameter, igraph_real_t *quality) { igraph_vector_t cluster_weights; igraph_real_t total_edge_weight = 0.0; igraph_eit_t eit; long int i, c, n = igraph_vcount(graph);; *quality = 0.0; /* Create the edgelist */ IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID), &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); while (!IGRAPH_EIT_END(eit)) { igraph_integer_t e = IGRAPH_EIT_GET(eit), from, to; IGRAPH_CHECK(igraph_edge(graph, e, &from, &to)); total_edge_weight += VECTOR(*edge_weights)[e]; /* We add the internal edge weights */ if (VECTOR(*membership)[(long int) from] == VECTOR(*membership)[(long int) to]) { *quality += 2 * VECTOR(*edge_weights)[e]; } IGRAPH_EIT_NEXT(eit); } igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(1); /* Initialize cluster weights and nb nodes */ IGRAPH_CHECK(igraph_vector_init(&cluster_weights, n)); IGRAPH_FINALLY(igraph_vector_destroy, &cluster_weights); for (i = 0; i < n; i++) { c = VECTOR(*membership)[i]; VECTOR(cluster_weights)[c] += VECTOR(*node_weights)[i]; } /* We subtract gamma * N_c^2 */ for (c = 0; c < nb_comms; c++) { *quality -= resolution_parameter * VECTOR(cluster_weights)[c] * VECTOR(cluster_weights)[c]; } igraph_vector_destroy(&cluster_weights); IGRAPH_FINALLY_CLEAN(1); /* We normalise by 2m */ *quality /= (2.0 * total_edge_weight); return IGRAPH_SUCCESS; } /* This is the core of the Leiden algorithm and relies on subroutines to * perform the three different phases: (1) local moving of nodes, (2) * refinement of the partition and (3) aggregation of the network based on the * refined partition, using the non-refined partition to create an initial * partition for the aggregate network. */ static int igraph_i_community_leiden( const igraph_t *graph, igraph_vector_t *edge_weights, igraph_vector_t *node_weights, const igraph_real_t resolution_parameter, const igraph_real_t beta, igraph_vector_t *membership, igraph_integer_t *nb_clusters, igraph_real_t *quality) { igraph_integer_t nb_refined_clusters; long int i, c, n = igraph_vcount(graph); igraph_t aggregated_graph, *i_graph; igraph_vector_t aggregated_edge_weights, aggregated_node_weights, aggregated_membership; igraph_vector_t *i_edge_weights, *i_node_weights, *i_membership; igraph_vector_t tmp_edge_weights, tmp_node_weights, tmp_membership; igraph_vector_t refined_membership; igraph_vector_int_t aggregate_node; igraph_vector_ptr_t clusters; igraph_inclist_t edges_per_node; igraph_bool_t continue_clustering; igraph_integer_t level = 0; /* Initialize temporary weights and membership to be used in aggregation */ IGRAPH_CHECK(igraph_vector_init(&tmp_edge_weights, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &tmp_edge_weights); IGRAPH_CHECK(igraph_vector_init(&tmp_node_weights, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &tmp_node_weights); IGRAPH_CHECK(igraph_vector_init(&tmp_membership, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &tmp_membership); /* Initialize clusters */ IGRAPH_CHECK(igraph_vector_ptr_init(&clusters, n)); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&clusters, igraph_vector_destroy); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &clusters); /* Initialize aggregate nodes, which initially is identical to simply the * nodes in the graph. */ IGRAPH_CHECK(igraph_vector_int_init(&aggregate_node, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &aggregate_node); for (i = 0; i < n; i++) { VECTOR(aggregate_node)[i] = i; } /* Initialize refined membership */ IGRAPH_CHECK(igraph_vector_init(&refined_membership, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &refined_membership); /* Initialize aggregated graph */ IGRAPH_CHECK(igraph_empty(&aggregated_graph, 0, IGRAPH_UNDIRECTED)); IGRAPH_FINALLY(igraph_destroy, &aggregated_graph); /* Initialize aggregated edge weights */ IGRAPH_CHECK(igraph_vector_init(&aggregated_edge_weights, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &aggregated_edge_weights); /* Initialize aggregated node weights */ IGRAPH_CHECK(igraph_vector_init(&aggregated_node_weights, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &aggregated_node_weights); /* Initialize aggregated membership */ IGRAPH_CHECK(igraph_vector_init(&aggregated_membership, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &aggregated_membership); /* Set actual graph, weights and membership to be used. */ i_graph = (igraph_t*)graph; i_edge_weights = edge_weights; i_node_weights = node_weights; i_membership = membership; /* Clean membership and count number of *clusters */ IGRAPH_CHECK(igraph_reindex_membership(i_membership, NULL, nb_clusters)); if (*nb_clusters > n) { IGRAPH_ERROR("Too many communities in membership vector", IGRAPH_EINVAL); } do { /* Get incidence list for fast iteration */ IGRAPH_CHECK(igraph_inclist_init( i_graph, &edges_per_node, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &edges_per_node); /* Move around the nodes in order to increase the quality */ IGRAPH_CHECK(igraph_i_community_leiden_fastmovenodes(i_graph, &edges_per_node, i_edge_weights, i_node_weights, resolution_parameter, nb_clusters, i_membership)); /* We only continue clustering if not all clusters are represented by a * single node yet */ continue_clustering = (*nb_clusters < igraph_vcount(i_graph)); if (continue_clustering) { /* Set original membership */ if (level > 0) { for (i = 0; i < n; i++) { long int v_aggregate = VECTOR(aggregate_node)[i]; VECTOR(*membership)[i] = VECTOR(*i_membership)[v_aggregate]; } } /* Get node sets for each cluster. */ IGRAPH_CHECK(igraph_i_community_get_clusters(i_membership, &clusters)); /* Ensure refined membership is correct size */ IGRAPH_CHECK(igraph_vector_resize(&refined_membership, igraph_vcount(i_graph))); /* Refine each cluster */ nb_refined_clusters = 0; for (c = 0; c < *nb_clusters; c++) { igraph_vector_t* cluster = (igraph_vector_t*)VECTOR(clusters)[c]; IGRAPH_CHECK(igraph_i_community_leiden_mergenodes(i_graph, &edges_per_node, i_edge_weights, i_node_weights, cluster, i_membership, c, resolution_parameter, beta, &nb_refined_clusters, &refined_membership)); /* Empty cluster */ igraph_vector_clear(cluster); } /* If refinement didn't aggregate anything, we aggregate on the basis of * the actual clustering */ if (nb_refined_clusters >= igraph_vcount(i_graph)) { igraph_vector_update(&refined_membership, i_membership); nb_refined_clusters = *nb_clusters; } /* Keep track of aggregate node. */ for (i = 0; i < n; i++) { /* Current aggregate node */ igraph_integer_t v_aggregate = VECTOR(aggregate_node)[i]; /* New aggregate node */ VECTOR(aggregate_node)[i] = (igraph_integer_t)VECTOR(refined_membership)[v_aggregate]; } IGRAPH_CHECK(igraph_i_community_leiden_aggregate( i_graph, &edges_per_node, i_edge_weights, i_node_weights, i_membership, &refined_membership, nb_refined_clusters, &aggregated_graph, &tmp_edge_weights, &tmp_node_weights, &tmp_membership)); /* On the lowest level, the actual graph and node and edge weights and * membership are used. On higher levels, we will use the aggregated graph * and associated vectors. */ if (level == 0) { /* Set actual graph, weights and membership to be used. */ i_graph = &aggregated_graph; i_edge_weights = &aggregated_edge_weights; i_node_weights = &aggregated_node_weights; i_membership = &aggregated_membership; } /* Update the aggregated administration. */ IGRAPH_CHECK(igraph_vector_update(i_edge_weights, &tmp_edge_weights)); IGRAPH_CHECK(igraph_vector_update(i_node_weights, &tmp_node_weights)); IGRAPH_CHECK(igraph_vector_update(i_membership, &tmp_membership)); level += 1; } /* We are done iterating, so we destroy the incidence list */ igraph_inclist_destroy(&edges_per_node); IGRAPH_FINALLY_CLEAN(1); } while (continue_clustering); /* Free aggregated graph and associated vectors */ igraph_vector_destroy(&aggregated_membership); igraph_vector_destroy(&aggregated_node_weights); igraph_vector_destroy(&aggregated_edge_weights); igraph_destroy(&aggregated_graph); IGRAPH_FINALLY_CLEAN(4); /* Free remaining memory */ igraph_vector_destroy(&refined_membership); igraph_vector_int_destroy(&aggregate_node); igraph_vector_ptr_destroy_all(&clusters); igraph_vector_destroy(&tmp_membership); igraph_vector_destroy(&tmp_node_weights); igraph_vector_destroy(&tmp_edge_weights); IGRAPH_FINALLY_CLEAN(6); /* Calculate quality */ if (quality) { IGRAPH_CHECK(igraph_i_community_leiden_quality(graph, edge_weights, node_weights, membership, *nb_clusters, resolution_parameter, quality)); } return IGRAPH_SUCCESS; } /** * \ingroup communities * \function igraph_community_leiden * \brief Finding community structure using the Leiden algorithm. * * This function implements the Leiden algorithm for finding community * structure, see Traag, V. A., Waltman, L., & van Eck, N. J. (2019). From * Louvain to Leiden: guaranteeing well-connected communities. Scientific * reports, 9(1), 5233. http://dx.doi.org/10.1038/s41598-019-41695-z * * * It is similar to the multilevel algorithm, often called the Louvain * algorithm, but it is faster and yields higher quality solutions. It can * optimize both modularity and the Constant Potts Model, which does not suffer * from the resolution-limit (see preprint http://arxiv.org/abs/1104.3083). * * * The Leiden algorithm consists of three phases: (1) local moving of nodes, * (2) refinement of the partition and (3) aggregation of the network based on * the refined partition, using the non-refined partition to create an initial * partition for the aggregate network. In the local move procedure in the * Leiden algorithm, only nodes whose neighborhood has changed are visited. The * refinement is done by restarting from a singleton partition within each * cluster and gradually merging the subclusters. When aggregating, a single * cluster may then be represented by several nodes (which are the subclusters * identified in the refinement). * * * The Leiden algorithm provides several guarantees. The Leiden algorithm is * typically iterated: the output of one iteration is used as the input for the * next iteration. At each iteration all clusters are guaranteed to be * connected and well-separated. After an iteration in which nothing has * changed, all nodes and some parts are guaranteed to be locally optimally * assigned. Finally, asymptotically, all subsets of all clusters are * guaranteed to be locally optimally assigned. For more details, please see * Traag, Waltman & van Eck (2019). * * * The objective function being optimized is * * * 1 / 2m sum_ij (A_ij - gamma n_i n_j)d(s_i, s_j) * * * where m is the total edge weight, A_ij is the weight of edge (i, j), gamma is * the so-called resolution parameter, n_i is the node weight of node i, s_i is * the cluster of node i and d(x, y) = 1 if and only if x = y and 0 otherwise. * By setting n_i = k_i, the degree of node i, and dividing gamma by 2m, you * effectively obtain an expression for modularity. Hence, the standard * modularity will be optimized when you supply the degrees as \c node_weights * and by supplying as a resolution parameter 1.0/(2*m), with m the number of * edges. * * \param graph The input graph. It must be an undirected graph. * \param edge_weights Numeric vector containing edge weights. If \c NULL, every edge * has equal weight of 1. The weights need not be non-negative. * \param node_weights Numeric vector containing node weights. * \param resolution_parameter The resolution parameter used, which is * represented by gamma in the objective function mentioned in the * documentation. * \param beta The randomness used in the refinement step when merging. A small * amount of randomness (\c beta = 0.01) typically works well. * \param start Start from membership vector. If this is true, the optimization * will start from the provided membership vector. If this is false, the * optimization will start from a singleton partition. * \param membership The membership vector. This is both used as the initial * membership from which optimisation starts and is updated in place. It * must hence be properly initialized. When finding clusters from scratch it * is typically started using a singleton clustering. This can be achieved * using \c igraph_vector_init_seq. * \param nb_clusters The number of clusters contained in \c membership. Must * not be a \c NULL pointer. * \param quality The quality of the partition, in terms of the objective * function as included in the documentation. If \c NULL the quality will * not be calculated. * \return Error code. * * Time complexity: near linear on sparse graphs. * * \example examples/simple/igraph_community_leiden.c */ int igraph_community_leiden(const igraph_t *graph, const igraph_vector_t *edge_weights, const igraph_vector_t *node_weights, const igraph_real_t resolution_parameter, const igraph_real_t beta, const igraph_bool_t start, igraph_vector_t *membership, igraph_integer_t *nb_clusters, igraph_real_t *quality) { igraph_vector_t *i_edge_weights, *i_node_weights; igraph_integer_t n = igraph_vcount(graph); if (start) { if (!membership) { IGRAPH_ERROR("Cannot start optimization if membership is missing", IGRAPH_EINVAL); } if (igraph_vector_size(membership) != n) { IGRAPH_ERROR("Initial membership length does not equal the number of vertices", IGRAPH_EINVAL); } } else { int i; if (!membership) IGRAPH_ERROR("Membership vector should be supplied and initialized, " "even when not starting optimization from it", IGRAPH_EINVAL); igraph_vector_resize(membership, n); for (i = 0; i < n; i++) { VECTOR(*membership)[i] = i; } } if (igraph_is_directed(graph)) { IGRAPH_ERROR("Leiden algorithm is only implemented for undirected graphs", IGRAPH_EINVAL); } /* Check edge weights to possibly use default */ if (!edge_weights) { i_edge_weights = IGRAPH_CALLOC(1, igraph_vector_t); if (i_edge_weights == 0) { IGRAPH_ERROR("Leiden algorithm failed, could not allocate memory for edge weights", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, i_edge_weights); IGRAPH_CHECK(igraph_vector_init(i_edge_weights, igraph_ecount(graph))); IGRAPH_FINALLY(igraph_vector_destroy, i_edge_weights); igraph_vector_fill(i_edge_weights, 1); } else { i_edge_weights = (igraph_vector_t*)edge_weights; } /* Check edge weights to possibly use default */ if (!node_weights) { i_node_weights = IGRAPH_CALLOC(1, igraph_vector_t); if (i_node_weights == 0) { IGRAPH_ERROR("Leiden algorithm failed, could not allocate memory for node weights", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, i_node_weights); IGRAPH_CHECK(igraph_vector_init(i_node_weights, n)); IGRAPH_FINALLY(igraph_vector_destroy, i_node_weights); igraph_vector_fill(i_node_weights, 1); } else { i_node_weights = (igraph_vector_t*)node_weights; } /* Perform actual Leiden algorithm */ IGRAPH_CHECK(igraph_i_community_leiden(graph, i_edge_weights, i_node_weights, resolution_parameter, beta, membership, nb_clusters, quality)); if (!edge_weights) { igraph_vector_destroy(i_edge_weights); IGRAPH_FREE(i_edge_weights); IGRAPH_FINALLY_CLEAN(2); } if (!node_weights) { igraph_vector_destroy(i_node_weights); IGRAPH_FREE(i_node_weights); IGRAPH_FINALLY_CLEAN(2); } return IGRAPH_SUCCESS; } leidenbase/src/core/community/spinglass/0000755000176200001440000000000014532173045020117 5ustar liggesusersleidenbase/src/core/community/spinglass/pottsmodel_2.h0000644000176200001440000001704314447675374022731 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Jörg Reichardt This file was modified by Vincent Traag The original copyright notice follows here */ /*************************************************************************** pottsmodel.h - description ------------------- begin : Fri May 28 2004 copyright : (C) 2004 by email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef POTTSMODEL_H #define POTTSMODEL_H #include "NetDataTypes.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_matrix.h" // Simple matrix class with heap allocation, allowing mat[i][j] indexing. class SimpleMatrix { double *data; size_t n; public: explicit SimpleMatrix(size_t n_) : n(n_) { data = new double[n*n]; } ~SimpleMatrix() { delete [] data; } // Return a pointer to the i'th column, which can be indexed into using a second [] operator. // We assume column-major storage. double *operator [] (size_t i) { return &(data[n*i]); } }; class PottsModel { private: // HugeArray neg_gammalookup; // HugeArray pos_gammalookup; DL_Indexed_List *new_spins; DL_Indexed_List *previous_spins; HugeArray*> correlation; network *net; unsigned int q; unsigned int operation_mode; // FILE *Qfile, *Magfile; SimpleMatrix Qmatrix; double* Qa; double* weights; double total_degree_sum; unsigned long num_of_nodes; unsigned long num_of_links; unsigned long k_max; double energy; double acceptance; double *neighbours; public: PottsModel(network *net, unsigned int q, int norm_by_degree); ~PottsModel(); double* color_field; unsigned long assign_initial_conf(int spin); unsigned long initialize_lookup(double kT, double gamma); double initialize_Qmatrix(); double calculate_Q(); double calculate_genQ(double gamma); double FindStartTemp(double gamma, double prob, double ts); long HeatBathParallelLookupZeroTemp(double gamma, double prob, unsigned int max_sweeps); double HeatBathLookupZeroTemp(double gamma, double prob, unsigned int max_sweeps); long HeatBathParallelLookup(double gamma, double prob, double kT, unsigned int max_sweeps); double HeatBathLookup(double gamma, double prob, double kT, unsigned int max_sweeps); double GammaSweep(double gamma_start, double gamma_stop, double prob, unsigned int steps, bool non_parallel = true, int repetitions = 1); double GammaSweepZeroTemp(double gamma_start, double gamma_stop, double prob, unsigned int steps, bool non_parallel = true, int repetitions = 1); // long WriteCorrelationMatrix(char *filename); double calculate_energy(double gamma); long WriteClusters(igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *csize, igraph_vector_t *membership, double kT, double gamma); // long WriteSoftClusters(char *filename, double threshold); double Get_Energy() const { return energy; } double FindCommunityFromStart(double gamma, double prob, char *nodename, igraph_vector_t *result, igraph_real_t *cohesion, igraph_real_t *adhesion, igraph_integer_t *inner_links, igraph_integer_t *outer_links); }; class PottsModelN { private: // HugeArray neg_gammalookup; // HugeArray pos_gammalookup; // DL_Indexed_List *new_spins; // DL_Indexed_List *previous_spins; HugeArray*> correlation; network *net; unsigned int q; //number of communities double m_p; //number of positive ties (or sum of degrees), this equals the number of edges only if it is undirected and each edge has a weight of 1 double m_n; //number of negative ties (or sum of degrees) unsigned int num_nodes; //number of nodes bool is_directed; bool is_init; double *degree_pos_in; //Postive indegree of the nodes (or sum of weights) double *degree_neg_in; //Negative indegree of the nodes (or sum of weights) double *degree_pos_out; //Postive outdegree of the nodes (or sum of weights) double *degree_neg_out; //Negative outdegree of the nodes (or sum of weights) double *degree_community_pos_in; //Positive sum of indegree for communities double *degree_community_neg_in; //Negative sum of indegree for communities double *degree_community_pos_out; //Positive sum of outegree for communities double *degree_community_neg_out; //Negative sum of outdegree for communities unsigned int *csize; //The number of nodes in each community unsigned int *spin; //The membership of each node double *neighbours; //Array of neighbours of a vertex in each community double *weights; //Weights of all possible transitions to another community public: PottsModelN(network *n, unsigned int num_communities, bool directed); ~PottsModelN(); void assign_initial_conf(bool init_spins); double FindStartTemp(double gamma, double lambda, double ts); double HeatBathLookup(double gamma, double lambda, double t, unsigned int max_sweeps); // double HeatBathJoin(double gamma, double lambda); // double HeatBathLookupZeroTemp(double gamma, double lambda, unsigned int max_sweeps); long WriteClusters(igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *community_size, igraph_vector_t *membership, igraph_matrix_t *adhesion, igraph_matrix_t *normalised_adhesion, igraph_real_t *polarization, double t, double d_p, double d_n, double gamma, double lambda); }; #endif leidenbase/src/core/community/spinglass/pottsmodel_2.cpp0000644000176200001440000024740314447675374023271 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Jörg Reichardt This file was modified by Vincent Traag The original copyright notice follows here */ /*************************************************************************** pottsmodel.cpp - description ------------------- begin : Fri May 28 2004 copyright : (C) 2004 by email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "pottsmodel_2.h" #include "NetRoutines.h" #include "igraph_random.h" #include "core/interruption.h" #include #include using namespace std; //################################################################################################# PottsModel::PottsModel(network *n, unsigned int qvalue, int m) : Qmatrix(qvalue+1), acceptance(0) { DLList_Iter iter; NNode *n_cur; unsigned int *i_ptr; net = n; q = qvalue; operation_mode = m; k_max = 0; //needed in calculating modularity Qa = new double[q + 1]; //weights for each spin state needed in Monte Carlo process weights = new double[q + 1]; //bookkeeping of occupation numbers of spin states or the number of links in community color_field = new double[q + 1]; neighbours = new double[q + 1]; num_of_nodes = net->node_list->Size(); num_of_links = net->link_list->Size(); n_cur = iter.First(net->node_list); //these lists are needed to keep track of spin states for parallel update mode new_spins = new DL_Indexed_List(); previous_spins = new DL_Indexed_List(); while (!iter.End()) { if (k_max < n_cur->Get_Degree()) { k_max = n_cur->Get_Degree(); } i_ptr = new unsigned int; *i_ptr = 0; new_spins->Push(i_ptr); i_ptr = new unsigned int; *i_ptr = 0; previous_spins->Push(i_ptr); n_cur = iter.Next(); } } //####################################################### //Destructor of PottsModel //######################################################## PottsModel::~PottsModel() { /* The DLItem destructor does not delete its item currently, because of some bad design. As a workaround, we delete them here by hand */ new_spins->delete_items(); previous_spins->delete_items(); delete new_spins; delete previous_spins; delete [] Qa; delete [] weights; delete [] color_field; delete [] neighbours; } //##################################################### //Assing an initial random configuration of spins to nodes //if called with negative argument or the spin used as argument //when called with positve one. //This may be handy, if you want to warm up the network. //#################################################### unsigned long PottsModel::assign_initial_conf(int spin) { int s; DLList_Iter iter; DLList_Iter l_iter; NNode *n_cur; NLink *l_cur; double sum_weight; double av_k_squared = 0.0; double av_k = 0.0; IGRAPH_UNUSED(av_k_squared); /* We mark it as unused to prevent warnings about unused-but-set-variables. */ IGRAPH_UNUSED(av_k); /* We mark it as unused to prevent warnings about unused-but-set-variables. */ // printf("Assigning initial configuration...\n"); // initialize colorfield for (unsigned int i = 0; i <= q; i++) { color_field[i] = 0.0; } // total_degree_sum = 0.0; n_cur = iter.First(net->node_list); while (!iter.End()) { if (spin < 0) { s = RNG_INTEGER(1, q); } else { s = spin; } n_cur->Set_ClusterIndex(s); l_cur = l_iter.First(n_cur->Get_Links()); sum_weight = 0; while (!l_iter.End()) { sum_weight += l_cur->Get_Weight(); //weight should be one, in case we are not using it. l_cur = l_iter.Next(); } // we set the sum of the weights or the degree as the weight of the node, this way // we do not have to calculate it again. n_cur->Set_Weight(sum_weight); av_k_squared += sum_weight * sum_weight; av_k += sum_weight; // in case we want all links to be contribute equally - parameter gamm=fixed if (operation_mode == 0) { color_field[s]++; } else { color_field[s] += sum_weight; } // or in case we want to use a weight of each link that is proportional to k_i\times k_j total_degree_sum += sum_weight; n_cur = iter.Next(); } av_k_squared /= double(net->node_list->Size()); av_k /= double(net->node_list->Size()); // total_degree_sum-=av_k_squared/av_k; // printf("Total Degree Sum=2M=%f\n",total_degree_sum); return net->node_list->Size(); } //##################################################################### //If I ever manage to write a decent LookUp function, it will be here //##################################################################### unsigned long PottsModel::initialize_lookup(double kT, double gamma) { IGRAPH_UNUSED(kT); IGRAPH_UNUSED(gamma); /* double beta; // the look-up table contains all entries of exp(-beta(-neighbours+gamma*h)) // as needed in the HeatBath algorithm beta=1.0/kT; for (long w=0; w<=k_max+num_of_nodes; w++) { neg_lookup[w]=exp(-beta*-w } delta_ij[0]=1.0; for (long w=-num_of_nodes-k_max; w<=k_max+num_of_nodes; w++) { } // wenn wir spaeter exp(-1/kT*gamma*(nk+1-nj) fuer eine spin-flip von j nach k benoetigen schauen wir nur noch hier nach for (unsigned long n=1; n<=num_of_nodes; n++) { gamma_term[n]=exp(-double(n)/kT*gamma); } gamma_term[0]=1.0; */ return 1; } //##################################################################### // Q denotes the modularity of the network // This function calculates it initially // In the event of a spin changing its state, it only needs updating // Note that Qmatrix and Qa are only counting! The normalization // by num_of_links is done later //#################################################################### double PottsModel::initialize_Qmatrix() { DLList_Iter l_iter; NLink *l_cur; unsigned int i, j; //initialize with zeros num_of_links = net->link_list->Size(); for (i = 0; i <= q; i++) { Qa[i] = 0.0; for (j = i; j <= q; j++) { Qmatrix[i][j] = 0.0; Qmatrix[j][i] = 0.0; } } //go over all links and make corresponding entries in Q matrix //An edge connecting state i wiht state j will get an entry in Qij and Qji l_cur = l_iter.First(net->link_list); while (!l_iter.End()) { i = l_cur->Get_Start()->Get_ClusterIndex(); j = l_cur->Get_End()->Get_ClusterIndex(); //printf("%d %d\n",i,j); Qmatrix[i][j] += l_cur->Get_Weight(); Qmatrix[j][i] += l_cur->Get_Weight(); l_cur = l_iter.Next(); } //Finally, calculate sum over rows and keep in Qa for (i = 0; i <= q; i++) { for (j = 0; j <= q; j++) { Qa[i] += Qmatrix[i][j]; } } return calculate_Q(); } //#################################################################### // This function does the actual calculation of Q from the matrix // The normalization by num_of_links is done here //#################################################################### double PottsModel::calculate_Q() { double Q = 0.0; for (unsigned int i = 0; i <= q; i++) { Q += Qmatrix[i][i] - Qa[i] * Qa[i] / double(2.0 * net->sum_weights); if ((Qa[i] < 0.0) || Qmatrix[i][i] < 0.0) { // printf("Negatives Qa oder Qii\n\n\n"); //printf("Press any key to continue\n\n"); //cin >> Q; } } Q /= double(2.0 * net->sum_weights); return Q; } double PottsModel::calculate_genQ(double gamma) { double Q = 0.0; for (unsigned int i = 0; i <= q; i++) { Q += Qmatrix[i][i] - gamma * Qa[i] * Qa[i] / double(2.0 * net->sum_weights); if ((Qa[i] < 0.0) || Qmatrix[i][i] < 0.0) { // printf("Negatives Qa oder Qii\n\n\n"); //printf("Press any key to continue\n\n"); //cin >> Q; } } Q /= double(2.0 * net->sum_weights); return Q; } //####################################################################### // This function calculates the Energy for the standard Hamiltonian // given a particular value of gamma and the current spin states // ##################################################################### double PottsModel::calculate_energy(double gamma) { double e = 0.0; DLList_Iter l_iter; NLink *l_cur; l_cur = l_iter.First(net->link_list); //every in-cluster edge contributes -1 while (!l_iter.End()) { if (l_cur->Get_Start()->Get_ClusterIndex() == l_cur->Get_End()->Get_ClusterIndex()) { e--; } l_cur = l_iter.Next(); } //and the penalty term contributes according to cluster sizes for (unsigned int i = 1; i <= q; i++) { e += gamma * 0.5 * double(color_field[i]) * double((color_field[i] - 1)); } energy = e; return e; } //########################################################################## // We would like to start from a temperature with at least 95 of all proposed // spin changes accepted in 50 sweeps over the network // The function returns the Temperature found //######################################################################### double PottsModel::FindStartTemp(double gamma, double prob, double ts) { double kT; kT = ts; //assing random initial condition assign_initial_conf(-1); //initialize Modularity matrix, from now on, it will be updated at every spin change initialize_Qmatrix(); // the factor 1-1/q is important, since even, at infinite temperature, // only 1-1/q of all spins do change their state, since a randomly chooses new // state is with prob. 1/q the old state. while (acceptance < (1.0 - 1.0 / double(q)) * 0.95) { //want 95% acceptance kT = kT * 1.1; // if I ever have a lookup table, it will need initialization for every kT //initialize_lookup(kT,k_max,net->node_list->Size()); HeatBathParallelLookup(gamma, prob, kT, 50); // printf("kT=%f acceptance=%f\n", kT, acceptance); } kT *= 1.1; // just to be sure... // printf("Starting with acceptance ratio: %1.6f bei kT=%2.4f\n",acceptance,kT); return kT; } //############################################################## //This function does a parallel update at zero T //Hence, it is really fast on easy problems //max sweeps is the maximum number of sweeps it should perform, //if it does not converge earlier //############################################################## long PottsModel::HeatBathParallelLookupZeroTemp(double gamma, double prob, unsigned int max_sweeps) { DLList_Iter iter, net_iter; DLList_Iter l_iter; DLList_Iter i_iter, i_iter2; NNode *node, *n_cur; NLink *l_cur; unsigned int *SPIN, *P_SPIN, new_spin, spin_opt, old_spin, spin, sweep; // long h; // degree; unsigned long changes; double h, delta = 0, deltaE, deltaEmin, w, degree; //HugeArray neighbours; bool cyclic = false; sweep = 0; changes = 1; while (sweep < max_sweeps && changes) { cyclic = true; sweep++; changes = 0; //Loop over all nodes node = net_iter.First(net->node_list); SPIN = i_iter.First(new_spins); while (!net_iter.End()) { // How many neigbors of each type? // set them all zero for (unsigned int i = 0; i <= q; i++) { neighbours[i] = 0; } degree = node->Get_Weight(); //Loop over all links (=neighbours) l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { //printf("%s %s\n",node->Get_Name(),n_cur->Get_Name()); w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } neighbours[n_cur->Get_ClusterIndex()] += w; l_cur = l_iter.Next(); } //Search optimal Spin old_spin = node->Get_ClusterIndex(); //degree=node->Get_Degree(); switch (operation_mode) { case 0: { delta = 1.0; break; } case 1: { //newman modularity prob = degree / total_degree_sum; delta = degree; break; } } spin_opt = old_spin; deltaEmin = 0.0; for (spin = 1; spin <= q; spin++) { // all possible spin states if (spin != old_spin) { h = color_field[spin] + delta - color_field[old_spin]; deltaE = double(neighbours[old_spin] - neighbours[spin]) + gamma * prob * double(h); if (deltaE < deltaEmin) { spin_opt = spin; deltaEmin = deltaE; } } } // for spin //Put optimal spin on list for later update *SPIN = spin_opt; node = net_iter.Next(); SPIN = i_iter.Next(); } // while !net_iter.End() //------------------------------- //Now set all spins to new values node = net_iter.First(net->node_list); SPIN = i_iter.First(new_spins); P_SPIN = i_iter2.First(previous_spins); while (!net_iter.End()) { old_spin = node->Get_ClusterIndex(); new_spin = *SPIN; if (new_spin != old_spin) { // Do we really have a change?? changes++; node->Set_ClusterIndex(new_spin); //this is important!! //In Parallel update, there occur cyclic attractors of size two //which then make the program run for ever if (new_spin != *P_SPIN) { cyclic = false; } *P_SPIN = old_spin; color_field[old_spin]--; color_field[new_spin]++; //Qmatrix update //iteration over all neighbours l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } Qmatrix[old_spin][n_cur->Get_ClusterIndex()] -= w; Qmatrix[new_spin][n_cur->Get_ClusterIndex()] += w; Qmatrix[n_cur->Get_ClusterIndex()][old_spin] -= w; Qmatrix[n_cur->Get_ClusterIndex()][new_spin] += w; Qa[old_spin] -= w; Qa[new_spin] += w; l_cur = l_iter.Next(); } // while l_iter } node = net_iter.Next(); SPIN = i_iter.Next(); P_SPIN = i_iter2.Next(); } // while (!net_iter.End()) } // while markov // In case of a cyclic attractor, we want to interrupt if (cyclic) { // printf("Cyclic attractor!\n"); acceptance = 0.0; return 0; } else { acceptance = double(changes) / double(num_of_nodes); return changes; } } //################################################################################### //The same function as before, but rather than parallel update, it pics the nodes to update //randomly //################################################################################### double PottsModel::HeatBathLookupZeroTemp(double gamma, double prob, unsigned int max_sweeps) { DLList_Iter iter; DLList_Iter l_iter; DLList_Iter i_iter, i_iter2; NNode *node, *n_cur; NLink *l_cur; unsigned int new_spin, spin_opt, old_spin, spin, sweep; long r;// degree; unsigned long changes; double delta = 0, h, deltaE, deltaEmin, w, degree; //HugeArray neighbours; sweep = 0; changes = 0; while (sweep < max_sweeps) { sweep++; //ueber alle Knoten im Netz for (unsigned long n = 0; n < num_of_nodes; n++) { r = -1; while ((r < 0) || (r > (long)num_of_nodes - 1)) { r = RNG_INTEGER(0, num_of_nodes - 1); } /* r=long(double(num_of_nodes*double(rand())/double(RAND_MAX+1.0)));*/ node = net->node_list->Get(r); // Wir zaehlen, wieviele Nachbarn von jedem spin vorhanden sind // erst mal alles Null setzen for (unsigned int i = 0; i <= q; i++) { neighbours[i] = 0; } degree = node->Get_Weight(); //Loop over all links (=neighbours) l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { //printf("%s %s\n",node->Get_Name(),n_cur->Get_Name()); w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } neighbours[n_cur->Get_ClusterIndex()] += w; l_cur = l_iter.Next(); } //Search optimal Spin old_spin = node->Get_ClusterIndex(); //degree=node->Get_Degree(); switch (operation_mode) { case 0: { delta = 1.0; break; } case 1: { //newman modularity prob = degree / total_degree_sum; delta = degree; break; } } spin_opt = old_spin; deltaEmin = 0.0; for (spin = 1; spin <= q; spin++) { // alle moeglichen Spins if (spin != old_spin) { h = color_field[spin] + delta - color_field[old_spin]; deltaE = double(neighbours[old_spin] - neighbours[spin]) + gamma * prob * double(h); if (deltaE < deltaEmin) { spin_opt = spin; deltaEmin = deltaE; } } } // for spin //------------------------------- //Now update the spins new_spin = spin_opt; if (new_spin != old_spin) { // Did we really change something?? changes++; node->Set_ClusterIndex(new_spin); color_field[old_spin] -= delta; color_field[new_spin] += delta; //Qmatrix update //iteration over all neighbours l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } Qmatrix[old_spin][n_cur->Get_ClusterIndex()] -= w; Qmatrix[new_spin][n_cur->Get_ClusterIndex()] += w; Qmatrix[n_cur->Get_ClusterIndex()][old_spin] -= w; Qmatrix[n_cur->Get_ClusterIndex()][new_spin] += w; Qa[old_spin] -= w; Qa[new_spin] += w; l_cur = l_iter.Next(); } // while l_iter } } // for n } // while markov acceptance = double(changes) / double(num_of_nodes) / double(sweep); return acceptance; } //##################################################################################### //This function performs a parallel update at Terperature T //##################################################################################### long PottsModel::HeatBathParallelLookup(double gamma, double prob, double kT, unsigned int max_sweeps) { DLList_Iter iter, net_iter; DLList_Iter l_iter; DLList_Iter i_iter, i_iter2; NNode *node, *n_cur; NLink *l_cur; unsigned int new_spin, spin_opt, old_spin; unsigned int *SPIN, *P_SPIN; unsigned int sweep; long max_q; unsigned long changes, /*degree,*/ problemcount; //HugeArray neighbours; double h, delta = 0, norm, r, beta, minweight, prefac = 0, w, degree; bool cyclic = false, found; unsigned long number_of_nodes; sweep = 0; changes = 1; number_of_nodes = net->node_list->Size(); while (sweep < max_sweeps && changes) { cyclic = true; sweep++; changes = 0; //Loop over all nodes node = net_iter.First(net->node_list); SPIN = i_iter.First(new_spins); while (!net_iter.End()) { // Initialize neighbours and weights problemcount = 0; for (unsigned int i = 0; i <= q; i++) { neighbours[i] = 0; weights[i] = 0; } norm = 0.0; degree = node->Get_Weight(); //Loop over all links (=neighbours) l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { //printf("%s %s\n",node->Get_Name(),n_cur->Get_Name()); w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } neighbours[n_cur->Get_ClusterIndex()] += w; l_cur = l_iter.Next(); } //Search optimal Spin old_spin = node->Get_ClusterIndex(); //degree=node->Get_Degree(); switch (operation_mode) { case 0: { prefac = 1.0; delta = 1.0; break; } case 1: { //newman modularity prefac = 1.0; prob = degree / total_degree_sum; delta = degree; break; } } spin_opt = old_spin; beta = 1.0 / kT * prefac; minweight = 0.0; weights[old_spin] = 0.0; for (unsigned spin = 1; spin <= q; spin++) { // loop over all possible new spins if (spin != old_spin) { // only if we have a different than old spin! h = color_field[spin] + delta - color_field[old_spin]; weights[spin] = double(neighbours[old_spin] - neighbours[spin]) + gamma * prob * double(h); if (weights[spin] < minweight) { minweight = weights[spin]; } } } // for spin for (unsigned spin = 1; spin <= q; spin++) { // loop over all possibe spins weights[spin] -= minweight; // subtract minweight // to avoid numerical problems with large exponents weights[spin] = exp(-beta * weights[spin]); norm += weights[spin]; } // for spin //now choose a new spin r = RNG_UNIF(0, norm); /* norm*double(rand())/double(RAND_MAX + 1.0); */ new_spin = 1; found = false; while (!found && new_spin <= q) { if (r <= weights[new_spin]) { spin_opt = new_spin; found = true; break; } else { r -= weights[new_spin]; } new_spin++; } if (!found) { // printf("."); problemcount++; } //Put new spin on list *SPIN = spin_opt; node = net_iter.Next(); SPIN = i_iter.Next(); } // while !net_iter.End() //------------------------------- //now update all spins node = net_iter.First(net->node_list); SPIN = i_iter.First(new_spins); P_SPIN = i_iter2.First(previous_spins); while (!net_iter.End()) { old_spin = node->Get_ClusterIndex(); new_spin = *SPIN; if (new_spin != old_spin) { // Did we really change something?? changes++; node->Set_ClusterIndex(new_spin); if (new_spin != *P_SPIN) { cyclic = false; } *P_SPIN = old_spin; color_field[old_spin] -= delta; color_field[new_spin] += delta; //Qmatrix update //iteration over all neighbours l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } Qmatrix[old_spin][n_cur->Get_ClusterIndex()] -= w; Qmatrix[new_spin][n_cur->Get_ClusterIndex()] += w; Qmatrix[n_cur->Get_ClusterIndex()][old_spin] -= w; Qmatrix[n_cur->Get_ClusterIndex()][new_spin] += w; Qa[old_spin] -= w; Qa[new_spin] += w; l_cur = l_iter.Next(); } // while l_iter } node = net_iter.Next(); SPIN = i_iter.Next(); P_SPIN = i_iter2.Next(); } // while (!net_iter.End()) } // while markov max_q = 0; for (unsigned int i = 1; i <= q; i++) if (color_field[i] > max_q) { max_q = long(color_field[i]); } //again, we would not like to end up in cyclic attractors if (cyclic && changes) { // printf("Cyclic attractor!\n"); acceptance = double(changes) / double(number_of_nodes); return 0; } else { acceptance = double(changes) / double(number_of_nodes); return changes; } } //############################################################## // This is the function generally used for optimisation, // as the parallel update has its flaws, due to the cyclic attractors //############################################################## double PottsModel::HeatBathLookup(double gamma, double prob, double kT, unsigned int max_sweeps) { DLList_Iter iter; DLList_Iter l_iter; DLList_Iter i_iter, i_iter2; NNode *node, *n_cur; NLink *l_cur; unsigned int new_spin, spin_opt, old_spin; unsigned int sweep; long max_q, rn; unsigned long changes, /*degree,*/ problemcount; double degree, w, delta = 0, h; //HugeArray neighbours; double norm, r, beta, minweight, prefac = 0; bool found; long int number_of_nodes; sweep = 0; changes = 0; number_of_nodes = net->node_list->Size(); while (sweep < max_sweeps) { sweep++; //loop over all nodes in network for (int n = 0; n < number_of_nodes; n++) { rn = -1; while ((rn < 0) || (rn > number_of_nodes - 1)) { rn = RNG_INTEGER(0, number_of_nodes - 1); } /* rn=long(double(number_of_nodes*double(rand())/double(RAND_MAX+1.0))); */ node = net->node_list->Get(rn); // initialize the neighbours and the weights problemcount = 0; for (unsigned int i = 0; i <= q; i++) { neighbours[i] = 0.0; weights[i] = 0.0; } norm = 0.0; degree = node->Get_Weight(); //Loop over all links (=neighbours) l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { //printf("%s %s\n",node->Get_Name(),n_cur->Get_Name()); w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } neighbours[n_cur->Get_ClusterIndex()] += w; l_cur = l_iter.Next(); } //Look for optimal spin old_spin = node->Get_ClusterIndex(); //degree=node->Get_Degree(); switch (operation_mode) { case 0: { prefac = 1.0; delta = 1.0; break; } case 1: {//newman modularity prefac = 1.0; prob = degree / total_degree_sum; delta = degree; break; } } spin_opt = old_spin; beta = 1.0 / kT * prefac; minweight = 0.0; weights[old_spin] = 0.0; for (unsigned spin = 1; spin <= q; spin++) { // all possible new spins if (spin != old_spin) { // except the old one! h = color_field[spin] - (color_field[old_spin] - delta); weights[spin] = neighbours[old_spin] - neighbours[spin] + gamma * prob * h; if (weights[spin] < minweight) { minweight = weights[spin]; } } } // for spin for (unsigned spin = 1; spin <= q; spin++) { // all possible new spins weights[spin] -= minweight; // subtract minweigt // for numerical stability weights[spin] = exp(-beta * weights[spin]); norm += weights[spin]; } // for spin //choose a new spin /* r = norm*double(rand())/double(RAND_MAX + 1.0); */ r = RNG_UNIF(0, norm); new_spin = 1; found = false; while (!found && new_spin <= q) { if (r <= weights[new_spin]) { spin_opt = new_spin; found = true; break; } else { r -= weights[new_spin]; } new_spin++; } if (!found) { // printf("."); problemcount++; } //------------------------------- //now set the new spin new_spin = spin_opt; if (new_spin != old_spin) { // Did we really change something?? changes++; node->Set_ClusterIndex(new_spin); color_field[old_spin] -= delta; color_field[new_spin] += delta; //Qmatrix update //iteration over all neighbours l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } Qmatrix[old_spin][n_cur->Get_ClusterIndex()] -= w; Qmatrix[new_spin][n_cur->Get_ClusterIndex()] += w; Qmatrix[n_cur->Get_ClusterIndex()][old_spin] -= w; Qmatrix[n_cur->Get_ClusterIndex()][new_spin] += w; Qa[old_spin] -= w; Qa[new_spin] += w; l_cur = l_iter.Next(); } // while l_iter } } // for n } // while markov max_q = 0; for (unsigned int i = 1; i <= q; i++) if (color_field[i] > max_q) { max_q = long(color_field[i] + 0.5); } acceptance = double(changes) / double(number_of_nodes) / double(sweep); return acceptance; } //############################################################################################### //# Here we try to minimize the affinity to the rest of the network //############################################################################################### double PottsModel::FindCommunityFromStart(double gamma, double prob, char *nodename, igraph_vector_t *result, igraph_real_t *cohesion, igraph_real_t *adhesion, igraph_integer_t *my_inner_links, igraph_integer_t *my_outer_links) { DLList_Iter iter, iter2; DLList_Iter l_iter; DLList* to_do; DLList* community; NNode *start_node = NULL, *n_cur, *neighbor, *max_aff_node, *node; NLink *l_cur; bool found = false, add = false, remove = false; double degree, delta_aff_add, delta_aff_rem, max_delta_aff, Ks = 0.0, Kr = 0, kis, kir, w; long community_marker = 5; long to_do_marker = 10; double inner_links = 0, outer_links = 0, aff_r, aff_s; IGRAPH_UNUSED(prob); to_do = new DLList; community = new DLList; // find the node in the network n_cur = iter.First(net->node_list); while (!found && !iter.End()) { if (0 == strcmp(n_cur->Get_Name(), nodename)) { start_node = n_cur; found = true; start_node->Set_Affinity(0.0); community->Push(start_node); start_node->Set_Marker(community_marker); Ks = start_node->Get_Weight(); Kr = total_degree_sum - start_node->Get_Weight(); } n_cur = iter.Next(); } if (!found) { // printf("%s not found found. Aborting.\n",nodename); // fprintf(file,"%s not found found. Aborting.\n",nodename); delete to_do; delete community; return -1; } //############################# // initialize the to_do list and community with the neighbours of start node //############################# neighbor = iter.First(start_node->Get_Neighbours()); while (!iter.End()) { // printf("Adding node %s to comunity.\n",neighbor->Get_Name()); community->Push(neighbor); neighbor->Set_Marker(community_marker); Ks += neighbor->Get_Weight(); Kr -= neighbor->Get_Weight(); neighbor = iter.Next(); } node = iter.First(community); while (!iter.End()) { //now add at the second neighbors to the to_do list neighbor = iter2.First(node->Get_Neighbours()); while (!iter2.End()) { if ((long)neighbor->Get_Marker() != community_marker && (long)neighbor->Get_Marker() != to_do_marker) { to_do->Push(neighbor); neighbor->Set_Marker(to_do_marker); // printf("Adding node %s to to_do list.\n",neighbor->Get_Name()); } neighbor = iter2.Next(); } node = iter.Next(); } //############# //repeat, as long as we are still adding nodes to the communtiy //############# add = true; remove = true; while (add || remove) { //############################# //calculate the affinity changes of all nodes for adding every node in the to_do list to the community //############################## IGRAPH_ALLOW_INTERRUPTION(); /* This is not clean.... */ max_delta_aff = 0.0; max_aff_node = NULL; add = false; node = iter.First(to_do); while (!iter.End()) { //printf("Checking Links of %s\n",node->Get_Name()); degree = node->Get_Weight(); kis = 0.0; kir = 0.0; // For every of the neighbors, check, count the links to the community l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } if ((long)n_cur->Get_Marker() == community_marker) { kis += w; //the weight/number of links to the community } else { kir += w; //the weight/number of links to the rest of the network } l_cur = l_iter.Next(); } aff_r = kir - gamma / total_degree_sum * (Kr - degree) * degree; aff_s = kis - gamma / total_degree_sum * Ks * degree; delta_aff_add = aff_r - aff_s; // if (aff_s>=aff_r && delta_aff_add<=max_delta_aff) { if (delta_aff_add <= max_delta_aff) { node->Set_Affinity(aff_s); max_delta_aff = delta_aff_add; max_aff_node = node; add = true; } //printf("%s in to_do list with affinity %f\n",node->Get_Name(),node->Get_Affinity()); node = iter.Next(); } //################ //calculate the affinity changes for removing every single node from the community //################ inner_links = 0; outer_links = 0; remove = false; node = iter.First(community); while (!iter.End()) { //printf("Checking Links of %s\n",node->Get_Name()); degree = node->Get_Weight(); kis = 0.0; kir = 0.0; // For every of the neighbors, check, count the links to the community l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } if ((long)n_cur->Get_Marker() == community_marker) { kis += w; inner_links += w; //summing all w gives twice the number of inner links(weights) } else { kir += w; outer_links += w; } l_cur = l_iter.Next(); } // if (kir+kis!=degree) { printf("error kir=%f\tkis=%f\tk=%f\n",kir,kis,degree); } aff_r = kir - gamma / total_degree_sum * Kr * degree; aff_s = kis - gamma / total_degree_sum * (Ks - degree) * degree; delta_aff_rem = aff_s - aff_r; node->Set_Affinity(aff_s); // we should not remove the nodes, we have just added if (delta_aff_rem < max_delta_aff) { max_delta_aff = delta_aff_rem ; max_aff_node = node; remove = true; add = false; } //printf("%s in to_do list with affinity %f\n",node->Get_Name(),node->Get_Affinity()); node = iter.Next(); } inner_links = inner_links * 0.5; //################ // Now check, whether we want to remove or add a node //################ if (add) { //################ //add the node of maximum affinity to the community //############### community->Push(max_aff_node); max_aff_node->Set_Marker(community_marker); //delete node from to_do to_do->fDelete(max_aff_node); //update the sum of degrees in the community Ks += max_aff_node->Get_Weight(); Kr -= max_aff_node->Get_Weight(); // printf("Adding node %s to community with affinity of %f delta_aff: %f.\n",max_aff_node->Get_Name(), max_aff_node->Get_Affinity(),max_delta_aff); //now add all neighbors of this node, that are not already //in the to_do list or in the community neighbor = iter.First(max_aff_node->Get_Neighbours()); while (!iter.End()) { if ((long)neighbor->Get_Marker() != community_marker && (long)neighbor->Get_Marker() != to_do_marker) { to_do->Push(neighbor); neighbor->Set_Marker(to_do_marker); //printf("Adding node %s to to_do list.\n",neighbor->Get_Name()); } neighbor = iter.Next(); } } if (remove) { //################ //remove those with negative affinities //################ community->fDelete(max_aff_node); max_aff_node->Set_Marker(to_do_marker); //update the sum of degrees in the community Ks -= max_aff_node->Get_Weight(); Kr += max_aff_node->Get_Weight(); //add the node to to_do again to_do->Push(max_aff_node); // printf("Removing node %s from community with affinity of %f delta_aff: %f.\n",max_aff_node->Get_Name(), max_aff_node->Get_Affinity(),max_delta_aff); } IGRAPH_ALLOW_INTERRUPTION(); /* This is not clean.... */ } //################### //write the node in the community to a file //################### // TODO return this instead of writing it // fprintf(file,"Number_of_nodes:\t%d\n",community->Size()); // fprintf(file,"Inner_Links:\t%f\n",inner_links); // fprintf(file,"Outer_Links:\t%f\n",Ks-2*inner_links); // fprintf(file,"Cohesion:\t%f\n",inner_links-gamma/total_degree_sum*Ks*Ks*0.5); // fprintf(file,"Adhesion:\t%f\n",outer_links-gamma/total_degree_sum*Ks*Kr); // fprintf(file,"\n"); if (cohesion) { *cohesion = inner_links - gamma / total_degree_sum * Ks * Ks * 0.5; } if (adhesion) { *adhesion = outer_links - gamma / total_degree_sum * Ks * Kr; } if (my_inner_links) { *my_inner_links = inner_links; } if (my_outer_links) { *my_outer_links = outer_links; } if (result) { node = iter.First(community); igraph_vector_resize(result, 0); while (!iter.End()) { // printf("%s in community.\n",node->Get_Name()); // fprintf(file,"%s\t%f\n",node->Get_Name(),node->Get_Affinity()); IGRAPH_CHECK(igraph_vector_push_back(result, node->Get_Index())); node = iter.Next(); } } // printf("%d nodes in community around %s\n",community->Size(),start_node->Get_Name()); // fclose(file); unsigned int size = community->Size(); delete to_do; delete community; return size; } //################################################################################################ // this Function writes the clusters to disk //################################################################################################ long PottsModel::WriteClusters(igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *csize, igraph_vector_t *membership, double kT, double gamma) { NNode *n_cur, *n_cur2; /* double a1,a2,a3,p,p1,p2; long n,N,lin,lout; */ DLList_Iter iter, iter2; HugeArray inner_links; HugeArray outer_links; HugeArray nodes; //den Header schreiben // p=2.0*double(num_of_links)/double(num_of_nodes)/double(num_of_nodes-1); // fprintf(file," Nodes=\t%lu\n",num_of_nodes); // fprintf(file," Links=\t%lu\n",num_of_links); // fprintf(file," q=\t%d\n",q); // fprintf(file," p=\t%f\n",p); // fprintf(file," Modularity=\t%f\n",calculate_Q()); // fprintf(file,"Temperature=\t%f\n", kT); // fprintf(file,"Cluster\tNodes\tInnerLinks\tOuterLinks\tp_in\tp_out\t\n"); if (temperature) { *temperature = kT; } if (csize || membership || modularity) { // TODO: count the number of clusters for (unsigned int spin = 1; spin <= q; spin++) { inner_links[spin] = 0; outer_links[spin] = 0; nodes[spin] = 0; n_cur = iter.First(net->node_list); while (!iter.End()) { if (n_cur->Get_ClusterIndex() == spin) { nodes[spin]++; n_cur2 = iter2.First(n_cur->Get_Neighbours()); while (!iter2.End()) { if (n_cur2->Get_ClusterIndex() == spin) { inner_links[spin]++; } else { outer_links[spin]++; } n_cur2 = iter2.Next(); } } n_cur = iter.Next(); } } } if (modularity) { *modularity = 0.0; for (unsigned int spin = 1; spin <= q; spin++) { if (nodes[spin] > 0) { double t1 = inner_links[spin] / net->sum_weights / 2.0; double t2 = (inner_links[spin] + outer_links[spin]) / net->sum_weights / 2.0; *modularity += t1; *modularity -= gamma * t2 * t2; } } } if (csize) { igraph_vector_resize(csize, 0); for (unsigned int spin = 1; spin <= q; spin++) { if (nodes[spin] > 0) { inner_links[spin] /= 2; // fprintf(file,"Cluster\tNodes\tInnerLinks\tOuterLinks\tp_in\tp_out\n"); /* N=num_of_nodes; n=nodes[spin]; lin=inner_links[spin]; lout=outer_links[spin]; a1=N*log((double)N)-n*log((double)n)*(N-n)*log((double)N-n); if ((lin==long(n*(n-1)*0.5+0.5)) || (n==1)) a2=0.0; else a2=(n*(n-1)*0.5 )*log((double)n*(n-1)*0.5 )-(n*(n-1)*0.5 )- (n*(n-1)*0.5-lin)*log((double)n*(n-1)*0.5-lin)+(n*(n-1)*0.5-lin)- lin*log((double)lin )+lin; */ /* if ((lout==n*(N-n)) || n==N) a3=0.0; else a3=(n*(N-n) )*log((double)n*(N-n) )-(n*(N-n))- (n*(N-n)-lout)*log((double)n*(N-n)-lout)+(n*(N-n)-lout)- lout*log((double)lout )+lout; */ /* p1=(lin+lout)*log((double)p); p2=(0.5*n*(n-1)-lin + n*(N-n)-lout)*log((double)1.0-p); */ // fprintf(file,"%d\t%d\t%d\t%d\t%f\t%f\t%f\n",spin,nodes[spin], inner_links[spin], outer_links[spin], p_in, p_out,log_num_exp); IGRAPH_CHECK(igraph_vector_push_back(csize, nodes[spin])); } } // fprintf(file,"\n"); } //die Elemente der Cluster if (membership) { long int no = -1; IGRAPH_CHECK(igraph_vector_resize(membership, num_of_nodes)); for (unsigned int spin = 1; spin <= q; spin++) { if (nodes[spin] > 0) { no++; } n_cur = iter.First(net->node_list); while (!iter.End()) { if (n_cur->Get_ClusterIndex() == spin) { // fprintf(file,"%d\t%s\n",spin,n_cur->Get_Name()); VECTOR(*membership)[ n_cur->Get_Index() ] = no; } n_cur = iter.Next(); } } } return num_of_nodes; } //################################################################################################ //This function writes the soft clusters after a gamma sweep //that is, it groups every node together that was found in // more than threshold percent together with the other node // in the same cluster //################################################################################################ // Does not work at the moment !!! //################################################################################################ // long PottsModel::WriteSoftClusters(char *filename, double threshold) // { // FILE *file; // NNode *n_cur, *n_cur2; // DLList_Iter iter, iter2; // DL_Indexed_List*> *cl_list, *old_clusterlist; // ClusterList *cl_cur; // double max; // file=fopen(filename,"w"); // if (!file) { // printf("Could not open %s for writing.\n",filename); // return -1; // } // max=correlation[0]->Get(0); // //printf("max=%f\n",max); // cl_list=new DL_Indexed_List*>(); // n_cur=iter.First(net->node_list); // while (!iter.End()) // { // cl_cur=new ClusterList(); // cl_list->Push(cl_cur); // n_cur2=iter2.First(net->node_list); // while (!iter2.End()) // { // if (double(correlation[n_cur->Get_Index()]->Get(n_cur2->Get_Index()))/max>threshold) // cl_cur->Push(n_cur2); // n_cur2=iter2.Next(); // } // n_cur=iter.Next(); // } // old_clusterlist=net->cluster_list; // net->cluster_list=cl_list; // clear_all_markers(net); // //printf("Es gibt %d Cluster\n",cl_list->Size()); // reduce_cliques2(net, false, 15); // //printf("Davon bleiben %d Cluster uebrig\n",cl_list->Size()); // clear_all_markers(net); // while (net->cluster_list->Size()){ // cl_cur=net->cluster_list->Pop(); // while (cl_cur->Size()) // { // n_cur=cl_cur->Pop(); // fprintf(file,"%s\n",n_cur->Get_Name()); // //printf("%s\n",n_cur->Get_Name()); // } // fprintf(file,"\n"); // } // net->cluster_list=old_clusterlist; // fclose(file); // return 1; // } //############################################################################# // Performs a gamma sweep //############################################################################# double PottsModel::GammaSweep(double gamma_start, double gamma_stop, double prob, unsigned int steps, bool non_parallel, int repetitions) { double stepsize; double kT = 0.5, kT_start; long changes; double gamma, acc; NNode *n_cur, *n_cur2; DLList_Iter iter, iter2; stepsize = (gamma_stop - gamma_start) / double(steps); n_cur = iter.First(net->node_list); while (!iter.End()) { correlation[n_cur->Get_Index()] = new HugeArray(); n_cur2 = iter2.First(net->node_list); while (!iter2.End()) { correlation[n_cur->Get_Index()]->Set(n_cur->Get_Index()) = 0.0; n_cur2 = iter2.Next(); } n_cur = iter.Next(); } for (unsigned int n = 0; n <= steps; n++) { assign_initial_conf(-1); initialize_Qmatrix(); gamma = gamma_start + stepsize * n; kT = 0.5; acceptance = 0.5; while (acceptance < (1.0 - 1.0 / double(q)) * 0.95) { //wollen 95% Acceptance kT *= 1.1; //initialize_lookup(kT,kmax,net->node_list->Size()); if (!non_parallel) { HeatBathParallelLookup(gamma, prob, kT, 25); } else { HeatBathLookup(gamma, prob, kT, 25); } // printf("kT=%f acceptance=%f\n", kT, acceptance); } // printf("Starting with gamma=%f\n", gamma); kT_start = kT; for (int i = 0; i < repetitions; i++) { changes = 1; kT = kT_start; assign_initial_conf(-1); initialize_Qmatrix(); while ((changes > 0) && (kT > 0.01)) { kT = kT * 0.99; //initialize_lookup(kT,kmax,net->node_list->Size()); if (!non_parallel) { changes = HeatBathParallelLookup(gamma, prob, kT, 50); // printf("kT: %f \t Changes %li\n",kT, changes); } else { acc = HeatBathLookup(gamma, prob, kT, 50); if (acc > (1.0 - 1.0 / double(q)) * 0.01) { changes = 1; } else { changes = 0; } // printf("kT: %f Acceptance: %f\n",kT, acc); } } // printf("Finisched with acceptance: %1.6f bei kT=%2.4f und gamma=%2.4f\n",acceptance,kT, gamma); // fprintf(file,"%f\t%f\n",gamma_,acceptance); // fprintf(file2,"%f\t%f\n",gamma_,kT); // fprintf(file3,"%f\t%d\n",gamma_,count_clusters(5)); //Die Correlation berechnen n_cur = iter.First(net->node_list); while (!iter.End()) { n_cur2 = iter2.First(net->node_list); while (!iter2.End()) { if (n_cur->Get_ClusterIndex() == n_cur2->Get_ClusterIndex()) { correlation[n_cur->Get_Index()]->Set(n_cur2->Get_Index()) += 0.5; } n_cur2 = iter2.Next(); } n_cur = iter.Next(); } } // for i } //for n return kT; } //############################################################################# //Performs a Gamma sweep at zero T //############################################################################# double PottsModel::GammaSweepZeroTemp(double gamma_start, double gamma_stop, double prob, unsigned int steps, bool non_parallel, int repetitions) { double stepsize; long changes; double gamma = gamma_start, acc; long runs; NNode *n_cur, *n_cur2; DLList_Iter iter, iter2; stepsize = (gamma_stop - gamma_start) / double(steps); n_cur = iter.First(net->node_list); while (!iter.End()) { correlation[n_cur->Get_Index()] = new HugeArray(); n_cur2 = iter2.First(net->node_list); while (!iter2.End()) { correlation[n_cur->Get_Index()]->Set(n_cur->Get_Index()) = 0.0; n_cur2 = iter2.Next(); } n_cur = iter.Next(); } for (unsigned int n = 0; n <= steps; n++) { assign_initial_conf(-1); initialize_Qmatrix(); gamma = gamma_start + stepsize * n; // printf("Starting with gamma=%f\n", gamma); for (int i = 0; i < repetitions; i++) { changes = 1; assign_initial_conf(-1); initialize_Qmatrix(); runs = 0; while (changes > 0 && runs < 250) { //initialize_lookup(kT,kmax,net->node_list->Size()); if (!non_parallel) { changes = HeatBathParallelLookupZeroTemp(gamma, prob, 1); // printf("Changes %li\n", changes); } else { acc = HeatBathLookupZeroTemp(gamma, prob, 1); if (acc > (1.0 - 1.0 / double(q)) * 0.01) { changes = 1; } else { changes = 0; } // printf("Acceptance: %f\n", acc); } runs++; } // printf("Finisched with Modularity: %1.6f bei Gamma=%1.6f\n",calculate_Q(), gamma); // fprintf(file,"%f\t%f\n",gamma_,acceptance); // fprintf(file2,"%f\t%f\n",gamma_,kT); // fprintf(file3,"%f\t%d\n",gamma_,count_clusters(5)); //Die Correlation berechnen n_cur = iter.First(net->node_list); while (!iter.End()) { n_cur2 = iter2.First(net->node_list); while (!iter2.End()) { if (n_cur->Get_ClusterIndex() == n_cur2->Get_ClusterIndex()) { correlation[n_cur->Get_Index()]->Set(n_cur2->Get_Index()) += 0.5; correlation[n_cur2->Get_Index()]->Set(n_cur->Get_Index()) += 0.5; } n_cur2 = iter2.Next(); } n_cur = iter.Next(); } } // for i } //for n return gamma; } //####################################################################### //----------------------------------------------------------------------- //####################################################################### // This function writes the Correlation Matrix that results from a // Gamma-Sweep, this matrix is used to make ps files of it. // ###################################################################### // long PottsModel::WriteCorrelationMatrix(char *filename) // { // FILE *file, *file2; // char filename2[255]; // NNode *n_cur, *n_cur2; // DLList_Iter iter, iter2; // sprintf(filename2,"%s.mat",filename); // file=fopen(filename,"w"); // if (!file) { // printf("Could not open %s for writing.\n",filename); // return -1; // } // file2=fopen(filename2,"w"); // if (!file2) { // printf("Could not open %s for writing.\n",filename2); // return -1; // } // //write the header in one line // n_cur=iter.First(net->node_list); // while (!iter.End()) // { // fprintf(file, "\t%s",n_cur->Get_Name()); // n_cur=iter.Next(); // } // fprintf(file, "\n"); // //fprintf(file, "%d\t%d\n",net->node_list->Size(),net->node_list->Size()); // long r=0,c=0; // n_cur=iter.First(net->node_list); // while (!iter.End()) // { // fprintf(file, "%s",n_cur->Get_Name()); // r++; // n_cur2=iter2.First(net->node_list); // while (!iter2.End()) // { // c++; // fprintf(file,"\t%f",correlation[n_cur->Get_Index()]->Get(n_cur2->Get_Index())); // fprintf(file2,"%li\t%li\t%f\n",r,c,correlation[n_cur->Get_Index()]->Get(n_cur2->Get_Index())); // n_cur2=iter2.Next(); // } // fprintf(file,"\n"); // n_cur=iter.Next(); // } // fclose(file); // fclose(file2); // return 1; // } //############################################################################## //################################################################################################# PottsModelN::PottsModelN(network *n, unsigned int num_communities, bool directed) : degree_pos_in(NULL), degree_neg_in(NULL), degree_pos_out(NULL), degree_neg_out(NULL), degree_community_pos_in(NULL), degree_community_neg_in(NULL), degree_community_pos_out(NULL), degree_community_neg_out(NULL), csize(NULL), spin(NULL), neighbours(NULL), weights(NULL) { //Set internal variable net = n; q = num_communities; is_directed = directed; is_init = false; num_nodes = net->node_list->Size(); } //####################################################### //Destructor of PottsModel //######################################################## PottsModelN::~PottsModelN() { delete [] degree_pos_in; delete [] degree_neg_in; delete [] degree_pos_out; delete [] degree_neg_out; delete [] degree_community_pos_in; delete [] degree_community_neg_in; delete [] degree_community_pos_out; delete [] degree_community_neg_out; delete [] weights; delete [] neighbours; delete [] csize; delete [] spin; } void PottsModelN::assign_initial_conf(bool init_spins) { #ifdef SPINGLASS_DEBUG printf("Start assigning.\n"); #endif unsigned int s; DLList_Iter iter; DLList_Iter l_iter; NNode *n_cur; NLink *l_cur; if (init_spins) { #ifdef SPINGLASS_DEBUG printf("Initializing spin.\n"); #endif // Free the arrays before (re-)allocating them // These arrays are initialized to NULL, so it is safe to delete even before allocation delete [] degree_pos_in; delete [] degree_neg_in; delete [] degree_pos_out; delete [] degree_neg_out; delete [] spin; //Bookkeeping of the various degrees (positive/negative) and (in/out) degree_pos_in = new double[num_nodes]; //Postive indegree of the nodes (or sum of weights) degree_neg_in = new double[num_nodes]; //Negative indegree of the nodes (or sum of weights) degree_pos_out = new double[num_nodes]; //Postive outdegree of the nodes (or sum of weights) degree_neg_out = new double[num_nodes]; //Negative outdegree of the nodes (or sum of weights) spin = new unsigned int[num_nodes]; //The spin state of each node } if (is_init) { delete [] degree_community_pos_in; delete [] degree_community_neg_in; delete [] degree_community_pos_out; delete [] degree_community_neg_out; delete [] weights; delete [] neighbours; delete [] csize; } is_init = true; //Bookkeep of occupation numbers of spin states or the number of links in community... degree_community_pos_in = new double[q + 1]; //Positive sum of indegree for communities degree_community_neg_in = new double[q + 1]; //Negative sum of indegree for communities degree_community_pos_out = new double[q + 1]; //Positive sum of outegree for communities degree_community_neg_out = new double[q + 1]; //Negative sum of outdegree for communities //...and of weights and neighbours for in the HeathBathLookup weights = new double[q + 1]; //The weights for changing to another spin state neighbours = new double[q + 1]; //The number of neighbours (or weights) in different spin states csize = new unsigned int[q + 1]; //The number of nodes in each community //Initialize communities for (unsigned int i = 0; i <= q; i++) { degree_community_pos_in[i] = 0.0; degree_community_neg_in[i] = 0.0; degree_community_pos_out[i] = 0.0; degree_community_neg_out[i] = 0.0; csize[i] = 0; } //Initialize vectors if (init_spins) { for (unsigned int i = 0; i < num_nodes; i++) { degree_pos_in[i] = 0.0; degree_neg_in[i] = 0.0; degree_pos_out[i] = 0.0; degree_neg_out[i] = 0.0; #ifdef SPINGLASS_DEBUG printf("Initializing spin %d", i); #endif spin[i] = 0; } } m_p = 0.0; m_n = 0.0; //Set community for each node, and //correctly store it in the bookkeeping double sum_weight_pos_in, sum_weight_pos_out, sum_weight_neg_in, sum_weight_neg_out; //double av_w = 0.0, av_k=0.0; //int l = 0; #ifdef SPINGLASS_DEBUG printf("Visiting each node.\n"); #endif for (unsigned int v = 0; v < num_nodes; v++) { if (init_spins) { s = RNG_INTEGER(1, q); //The new spin s spin[v] = (unsigned int)s; } else { s = spin[v]; } #ifdef SPINGLASS_DEBUG printf("Spin %d assigned to node %d.\n", s, v); #endif n_cur = net->node_list->Get(v); l_cur = l_iter.First(n_cur->Get_Links()); sum_weight_pos_in = 0.0; sum_weight_pos_out = 0.0; sum_weight_neg_in = 0.0; sum_weight_neg_out = 0.0; while (!l_iter.End()) { double w = l_cur->Get_Weight(); //av_w = (av_w*l + w)/(l+1); //Average weight //l++; if (l_cur->Get_Start() == n_cur) //From this to other, so outgoing link if (w > 0) { sum_weight_pos_out += w; //Increase positive outgoing weight } else { sum_weight_neg_out -= w; //Increase negative outgoing weight } else if (w > 0) { sum_weight_pos_in += w; //Increase positive incoming weight } else { sum_weight_neg_in -= w; //Increase negative incoming weight } l_cur = l_iter.Next(); } if (!is_directed) { double sum_weight_pos = sum_weight_pos_out + sum_weight_pos_in; sum_weight_pos_out = sum_weight_pos; sum_weight_pos_in = sum_weight_pos; double sum_weight_neg = sum_weight_neg_out + sum_weight_neg_in; sum_weight_neg_out = sum_weight_neg; sum_weight_neg_in = sum_weight_neg; } //av_k = (av_k*l + sum_weight_pos_in)/(l+1); //Average k if (init_spins) { //Set the degrees correctly degree_pos_in[v] = sum_weight_pos_in; degree_neg_in[v] = sum_weight_neg_in; degree_pos_out[v] = sum_weight_pos_out; degree_neg_out[v] = sum_weight_neg_out; } //Correct the community bookkeeping degree_community_pos_in[s] += sum_weight_pos_in; degree_community_neg_in[s] += sum_weight_neg_in; degree_community_pos_out[s] += sum_weight_pos_out; degree_community_neg_out[s] += sum_weight_neg_out; //Community just increased csize[s]++; //Sum the weights (notice that sum of indegrees equals sum of outdegrees) m_p += sum_weight_pos_in; m_n += sum_weight_neg_in; } #ifdef SPINGLASS_DEBUG printf("Done assigning.\n"); #endif } //############################################################## // This is the function generally used for optimisation, // as the parallel update has its flaws, due to the cyclic attractors //############################################################## double PottsModelN::HeatBathLookup(double gamma, double lambda, double t, unsigned int max_sweeps) { #ifdef SPINGLASS_DEBUG printf("Starting sweep at temperature %f.\n", t); #endif DLList_Iter iter; DLList_Iter l_iter; DLList_Iter i_iter, i_iter2; NNode *node, *n_cur; NLink *l_cur; /* The new_spin contains the spin to which we will update, * the spin_opt is the optional spin we will consider and * the old_spin is the spin of the node we are currently * changing. */ unsigned int new_spin, spin_opt, old_spin; unsigned int sweep; //current sweep unsigned long changes, problemcount; //Number of changes and number of problems encountered double exp_old_spin; //The expectation value for the old spin double exp_spin; //The expectation value for the other spin(s) int v; //The node we will be investigating //The variables required for the calculations double delta_pos_out, delta_pos_in, delta_neg_out, delta_neg_in; double k_v_pos_out, k_v_pos_in, k_v_neg_out, k_v_neg_in; //weight of edge double w; double beta = 1 / t; //Weight for probabilities double r = 0.0; //random number used for assigning new spin double maxweight = 0.0; double sum_weights = 0.0; //sum_weights for normalizing the probabilities sweep = 0; changes = 0; double m_pt = m_p; double m_nt = m_n; if (m_pt < 0.001) { m_pt = 1; } if (m_nt < 0.001) { m_nt = 1; } while (sweep < max_sweeps) { sweep++; //loop over all nodes in network for (unsigned int n = 0; n < num_nodes; n++) { //Look for a random node v = RNG_INTEGER(0, num_nodes - 1); //We will be investigating node v node = net->node_list->Get(v); /*******************************************/ // initialize the neighbours and the weights problemcount = 0; for (unsigned int i = 0; i <= q; i++) { neighbours[i] = 0.0; weights[i] = 0.0; } //Loop over all links (=neighbours) l_cur = l_iter.First(node->Get_Links()); while (!l_iter.End()) { w = l_cur->Get_Weight(); if (node == l_cur->Get_Start()) { n_cur = l_cur->Get_End(); } else { n_cur = l_cur->Get_Start(); } //Add the link to the correct cluster neighbours[spin[n_cur->Get_Index()]] += w; l_cur = l_iter.Next(); } //We now have the weight of the (in and out) neighbours //in each cluster available to us. /*******************************************/ old_spin = spin[v]; //Look for optimal spin //Set the appropriate variable delta_pos_out = degree_pos_out[v]; delta_pos_in = degree_pos_in[v]; delta_neg_out = degree_neg_out[v]; delta_neg_in = degree_neg_in[v]; k_v_pos_out = gamma * delta_pos_out / m_pt; k_v_pos_in = gamma * delta_pos_in / m_pt; k_v_neg_out = lambda * delta_neg_out / m_nt; k_v_neg_in = lambda * delta_neg_in / m_nt; //The expectation value for the old spin if (is_directed) exp_old_spin = (k_v_pos_out * (degree_community_pos_in[old_spin] - delta_pos_in) - k_v_neg_out * (degree_community_neg_in[old_spin] - delta_neg_in)) + (k_v_pos_in * (degree_community_pos_out[old_spin] - delta_pos_out) - k_v_neg_in * (degree_community_neg_out[old_spin] - delta_neg_out)); else exp_old_spin = (k_v_pos_out * (degree_community_pos_in[old_spin] - delta_pos_in) - k_v_neg_out * (degree_community_neg_in[old_spin] - delta_neg_in)); /*******************************************/ //Calculating probabilities for each transition to another //community. maxweight = 0.0; weights[old_spin] = 0.0; for (spin_opt = 1; spin_opt <= q; spin_opt++) { // all possible new spins if (spin_opt != old_spin) { // except the old one! if (is_directed) exp_spin = (k_v_pos_out * degree_community_pos_in[spin_opt] - k_v_neg_out * degree_community_neg_in[spin_opt]) + (k_v_pos_in * degree_community_pos_out[spin_opt] - k_v_neg_in * degree_community_neg_out[spin_opt]); else { exp_spin = (k_v_pos_out * degree_community_pos_in[spin_opt] - k_v_neg_out * degree_community_neg_in[spin_opt]); } weights[spin_opt] = (neighbours[spin_opt] - exp_spin) - (neighbours[old_spin] - exp_old_spin); if (weights[spin_opt] > maxweight) { maxweight = weights[spin_opt]; } } } // for spin //Calculate exp. prob. an sum_weights = 0.0; for (spin_opt = 1; spin_opt <= q; spin_opt++) { // all possible new spins weights[spin_opt] -= maxweight; //subtract maxweight for numerical stability (otherwise overflow). weights[spin_opt] = exp((double)(beta * weights[spin_opt])); sum_weights += weights[spin_opt]; } // for spin /*******************************************/ /*******************************************/ //Choose a new spin dependent on the calculated probabilities r = RNG_UNIF(0, sum_weights); new_spin = 1; bool found = false; while (!found && new_spin <= q) { if (r <= weights[new_spin]) { spin_opt = new_spin; //We have found are new spin found = true; break; } else { r -= weights[new_spin]; //Perhaps the next spin is the one we want } new_spin++; } //Some weird thing happened. We haven't found a new spin //while that shouldn't be the case. Numerical problems? if (!found) { problemcount++; } new_spin = spin_opt; //If there wasn't a problem we should have found //our new spin. /*******************************************/ /*******************************************/ //The new spin is available to us, so change //all the appropriate counters. if (new_spin != old_spin) { // Did we really change something?? changes++; spin[v] = new_spin; //The new spin increase by one, and the old spin decreases by one csize[new_spin]++; csize[old_spin]--; //Change the sums of degree for the old spin... degree_community_pos_in[old_spin] -= delta_pos_in; degree_community_neg_in[old_spin] -= delta_neg_in; degree_community_pos_out[old_spin] -= delta_pos_out; degree_community_neg_out[old_spin] -= delta_neg_out; //...and for the new spin degree_community_pos_in[new_spin] += delta_pos_in; degree_community_neg_in[new_spin] += delta_neg_in; degree_community_pos_out[new_spin] += delta_pos_out; degree_community_neg_out[new_spin] += delta_neg_out; } //We have no change a node from old_spin to new_spin /*******************************************/ } // for n } // while sweep #ifdef SPINGLASS_DEBUG printf("Done %d sweeps.\n", max_sweeps); printf("%ld changes made for %d nodes.\n", changes, num_nodes); printf("Last node is %d and last random number is %f with sum of weights %f with spin %d.\n", v, r, sum_weights, old_spin); #endif return (double(changes) / double(num_nodes) / double(sweep)); } //We need to begin at a suitable temperature. That is, a temperature at which //enough nodes may change their initially assigned communties double PottsModelN::FindStartTemp(double gamma, double lambda, double ts) { double kT; kT = ts; //assing random initial condition assign_initial_conf(true); // the factor 1-1/q is important, since even, at infinite temperature, // only 1-1/q of all spins do change their state, since a randomly chooses new // state is with prob. 1/q the old state. double acceptance = 0.0; while (acceptance < (1.0 - 1.0 / double(q)) * 0.95) { //want 95% acceptance kT = kT * 1.1; acceptance = HeatBathLookup(gamma, lambda, kT, 50); } kT *= 1.1; // just to be sure... return kT; } long PottsModelN::WriteClusters(igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *community_size, igraph_vector_t *membership, igraph_matrix_t *adhesion, igraph_matrix_t *normalised_adhesion, igraph_real_t *polarization, double t, double d_p, double d_n, double gamma, double lambda) { IGRAPH_UNUSED(gamma); IGRAPH_UNUSED(lambda); #ifdef SPINGLASS_DEBUG printf("Start writing clusters.\n"); #endif //Reassign each community so that we retrieve a community assignment 1 through num_communities unsigned int *cluster_assign = new unsigned int[q + 1]; for (unsigned int i = 0; i <= q; i++) { cluster_assign[i] = 0; } int num_clusters = 0; //Find out what the new communities will be for (unsigned int i = 0; i < num_nodes; i++) { unsigned int s = spin[i]; if (cluster_assign[s] == 0) { num_clusters++; cluster_assign[s] = num_clusters; #ifdef SPINGLASS_DEBUG printf("Setting cluster %d to %d.\n", s, num_clusters); #endif } } /* DLList_Iter iter; NNode *n_cur=iter.First(net->node_list); n_cur = iter.First(net->node_list); */ //And now assign each node to its new community q = num_clusters; for (unsigned int i = 0; i < num_nodes; i++) { #ifdef SPINGLASS_DEBUG printf("Setting node %d to %d.\n", i, cluster_assign[spin[i]]); #endif unsigned int s = cluster_assign[spin[i]]; spin[i] = s; #ifdef SPINGLASS_DEBUG printf("Have set node %d to %d.\n", i, s); #endif } assign_initial_conf(false); delete[] cluster_assign; if (temperature) { *temperature = t; } if (community_size) { //Initialize the vector IGRAPH_CHECK(igraph_vector_resize(community_size, q)); for (unsigned int spin_opt = 1; spin_opt <= q; spin_opt++) { //Set the community size VECTOR(*community_size)[spin_opt - 1] = csize[spin_opt]; } } //Set the membership if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, num_nodes)); for (unsigned int i = 0; i < num_nodes; i++) { VECTOR(*membership)[ i ] = spin[i] - 1; } } double Q = 0.0; //Modularity if (adhesion) { IGRAPH_CHECK(igraph_matrix_resize(adhesion, q, q)); IGRAPH_CHECK(igraph_matrix_resize(normalised_adhesion, q, q)); double **num_links_pos = NULL; double **num_links_neg = NULL; //memory allocated for elements of rows. num_links_pos = new double *[q + 1] ; num_links_neg = new double *[q + 1] ; //memory allocated for elements of each column. for ( unsigned int i = 0 ; i < q + 1 ; i++) { num_links_pos[i] = new double[q + 1]; num_links_neg[i] = new double[q + 1]; } //Init num_links for (unsigned int i = 0; i <= q; i++) { for (unsigned int j = 0; j <= q; j++) { num_links_pos[i][j] = 0.0; num_links_neg[i][j] = 0.0; } } DLList_Iter iter_l; NLink *l_cur = iter_l.First(net->link_list); double w = 0.0; while (!iter_l.End()) { w = l_cur->Get_Weight(); unsigned int a = spin[l_cur->Get_Start()->Get_Index()]; unsigned int b = spin[l_cur->Get_End()->Get_Index()]; if (w > 0) { num_links_pos[a][b] += w; if (!is_directed && a != b) { //Only one edge is defined in case it is undirected num_links_pos[b][a] += w; } } else { num_links_neg[a][b] -= w; if (!is_directed && a != b) { //Only one edge is defined in case it is undirected num_links_neg[b][a] -= w; } } l_cur = iter_l.Next(); } //while links #ifdef SPINGLASS_DEBUG printf("d_p: %f\n", d_p); printf("d_n: %f\n", d_n); #endif double expected = 0.0; double a = 0.0; double normal_a = 0.0; double delta, u_p, u_n; double max_expected, max_a; //We don't take into account the lambda or gamma for //computing the modularity and adhesion, since they //are then incomparable to other definitions. for (unsigned int i = 1; i <= q; i++) { for (unsigned int j = 1; j <= q; j++) { if (!is_directed && i == j) expected = degree_community_pos_out[i] * degree_community_pos_in[j] / (m_p == 0 ? 1 : 2 * m_p) - degree_community_neg_out[i] * degree_community_neg_in[j] / (m_n == 0 ? 1 : 2 * m_n); else expected = degree_community_pos_out[i] * degree_community_pos_in[j] / (m_p == 0 ? 1 : m_p) - degree_community_neg_out[i] * degree_community_neg_in[j] / (m_n == 0 ? 1 : m_n); a = (num_links_pos[i][j] - num_links_neg[i][j]) - expected; if (i == j) { //cohesion if (is_directed) { delta = d_p * csize[i] * (csize[i] - 1); //Maximum amount } else { delta = d_p * csize[i] * (csize[i] - 1) / 2; //Maximum amount } u_p = delta - num_links_pos[i][i]; //Add as many positive links we can u_n = -num_links_neg[i][i]; //Delete as many negative links we can Q += a; } else { //adhesion if (is_directed) { delta = d_n * csize[i] * csize[j] * 2; //Maximum amount } else { delta = d_n * csize[i] * csize[j]; //Maximum amount } u_p = -num_links_pos[i][j]; //Delete as many positive links we can u_n = delta - num_links_neg[i][j]; //Add as many negative links we can } if (!is_directed && i == j) max_expected = (degree_community_pos_out[i] + u_p) * (degree_community_pos_in[j] + u_p) / ((m_p + u_p) == 0 ? 1 : 2 * (m_p + u_p)) - (degree_community_neg_out[i] - u_n) * (degree_community_neg_in[j] + u_n) / ((m_n + u_n) == 0 ? 1 : 2 * (m_n + u_n)); else max_expected = (degree_community_pos_out[i] + u_p) * (degree_community_pos_in[j] + u_p) / ((m_p + u_p) == 0 ? 1 : m_p + u_p) - (degree_community_neg_out[i] - u_n) * (degree_community_neg_in[j] + u_n) / ((m_n + u_n) == 0 ? 1 : m_n + u_n); //printf("%f/%f %d/%d\t", num_links_pos[i][j], num_links_neg[i][j], csize[i], csize[j]); //printf("%f/%f - %f(%f)\t", u_p, u_n, expected, max_expected); max_a = ((num_links_pos[i][j] + u_p) - (num_links_neg[i][j] + u_n)) - max_expected; //In cases where we haven't actually found a ground state //the adhesion/cohesion *might* not be negative/positive, //hence the maximum adhesion and cohesion might behave quite //strangely. In order to prevent that, we limit them to 1 in //absolute value, and prevent from dividing by zero (even if //chuck norris would). if (i == j) { normal_a = a / (max_a == 0 ? a : max_a); } else { normal_a = -a / (max_a == 0 ? a : max_a); } if (normal_a > 1) { normal_a = 1; } else if (normal_a < -1) { normal_a = -1; } MATRIX(*adhesion, i - 1, j - 1) = a; MATRIX(*normalised_adhesion, i - 1, j - 1) = normal_a; } //for j //printf("\n"); } //for i //free the allocated memory for ( unsigned int i = 0 ; i < q + 1 ; i++ ) { delete [] num_links_pos[i] ; delete [] num_links_neg[i]; } delete [] num_links_pos ; delete [] num_links_neg ; } //adhesion if (modularity) { if (is_directed) { *modularity = Q / (m_p + m_n); } else { *modularity = 2 * Q / (m_p + m_n); //Correction for the way m_p and m_n are counted. Modularity is 1/m, not 1/2m } } if (polarization) { double sum_ad = 0.0; for (unsigned int i = 0; i < q; i++) { for (unsigned int j = 0; j < q; j++) { if (i != j) { sum_ad -= MATRIX(*normalised_adhesion, i, j); } } } *polarization = sum_ad / (q * q - q); } #ifdef SPINGLASS_DEBUG printf("Finished writing cluster.\n"); #endif return num_nodes; } leidenbase/src/core/community/spinglass/NetDataTypes.h0000644000176200001440000006057514447675374022673 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Jörg Reichardt The original copyright notice follows here */ /*************************************************************************** NetDataTypes.h - description ------------------- begin : Mon Oct 6 2003 copyright : (C) 2003 by Joerg Reichardt email : reichardt@mitte ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef NETDATATYPES_H #define NETDATATYPES_H #include //########################################################################################### struct HUGE_INDEX { unsigned int field_index; unsigned long in_field_index; }; template class HugeArray { private: unsigned long int size; unsigned int highest_field_index; unsigned long max_bit_left; unsigned long max_index; DATA *data; DATA *fields[32]; public: HUGE_INDEX get_huge_index(unsigned long); DATA &Set(unsigned long); DATA Get(unsigned long); HugeArray(); ~HugeArray(); DATA &operator[](unsigned long); unsigned long Size() { return max_index; } } ; //############################################################################################### template class DLList; template class DL_Indexed_List; template class ClusterList; template class DLList_Iter; template class DLItem { friend class DLList ; friend class DL_Indexed_List; friend class DLList_Iter; private: L_DATA item; unsigned long index; DLItem *previous; DLItem *next; DLItem(L_DATA i, unsigned long ind); DLItem(L_DATA i, unsigned long ind, DLItem *p, DLItem *n); ~DLItem(); public: void del() { delete item; } }; template class DLList { friend class DLList_Iter; protected: DLItem *head; DLItem *tail; unsigned long number_of_items; DLItem *pInsert(L_DATA, DLItem*); L_DATA pDelete(DLItem*); public: DLList(); ~DLList(); unsigned long Size() { return number_of_items; } int Insert(L_DATA, unsigned long); int Delete(unsigned long); int fDelete(L_DATA); L_DATA Push(L_DATA); L_DATA Pop(); L_DATA Get(unsigned long); int Enqueue(L_DATA); L_DATA Dequeue(); unsigned long Is_In_List(L_DATA); void delete_items(); }; template class DL_Indexed_List : virtual public DLList { friend class DLList_Iter; private: DLItem *pInsert(L_DATA, DLItem*); L_DATA pDelete(DLItem*); HugeArray*> array; unsigned long last_index; public: DL_Indexed_List(); ~DL_Indexed_List(); L_DATA Push(L_DATA); L_DATA Pop(); L_DATA Get(unsigned long); }; //##################################################################################################### template class DLList_Iter { private: DLList *list; DLItem *current; bool end_reached; public: DLList_Iter(); ~DLList_Iter() { end_reached = true; }; L_DATA Next(); L_DATA Previous(); L_DATA First(DLList *l); L_DATA Last(DLList *l); bool End() { return end_reached; } DLItem *Get_Current() { return current; } L_DATA Get_Current_Item() { return current->item; } void Set_Current(DLItem *c) { current = c; } void Set_Status(bool s) { end_reached = s; } bool Swap(DLList_Iter); //swapt die beiden Elemente, wenn sie in der gleichen Liste stehen!! }; //##################################################################################################### struct RGBcolor { unsigned int red; unsigned int green; unsigned int blue; char pajek_c[20]; }; //------------------------------------------------------------------------------- class NLink; class NNode { friend class NLink; private : unsigned long index; unsigned long cluster_index; unsigned long marker, affiliations; unsigned long *state_history; unsigned int max_states; long distance; double clustering; double weight; double affinity; // double old_weight; DLList *neighbours; //list with pointers to neighbours DLList *n_links; DLList *global_link_list; char name[255]; RGBcolor color; public : NNode(unsigned long, unsigned long, DLList*, const char*, int); ~NNode(); unsigned long Get_Index() { return (index); } unsigned long Get_ClusterIndex() { return (cluster_index); } unsigned long Get_Marker() { return marker; } void Set_Marker(unsigned long m) { marker = m; } unsigned long Get_Affiliations() { return affiliations; } void Set_Affiliations(unsigned long m) { affiliations = m; } void Set_ClusterIndex(unsigned long ci) { cluster_index = ci; } void Set_Index(unsigned long i) { index = i; } unsigned long Get_Degree() { return (neighbours->Size()); } char *Get_Name() { return name; } void Set_Name(char* n) { strcpy(name, n); } double Get_Links_Among_Neigbours(); double Get_Clustering(); double Get_Weight() { return weight; } double Get_Affinity() { return affinity; } unsigned long *Get_StateHistory() { return state_history; } void Add_StateHistory(unsigned int q); // double Get_OldWeight() {return old_weight;} void Set_Weight(double w) { weight = w; } void Set_Affinity(double w) { affinity = w; } // void Set_OldWeight(double w) {old_weight=w;} long Get_Distance() { return distance; } void Set_Distance(long d) { distance = d; } int Connect_To(NNode*, double); DLList *Get_Neighbours() { return neighbours; } DLList *Get_Links() { return n_links; } int Disconnect_From(NNode*); int Disconnect_From_All(); bool Is_Linked_To(NNode*); RGBcolor Get_Color() { return color; } void Set_Color(RGBcolor c); NLink *Get_LinkToNeighbour(NNode *neighbour); }; //##################################################################################################### class NLink { friend class NNode; private : NNode *start; NNode *end; double weight; double old_weight; unsigned long index; unsigned long marker; public : NLink( NNode*, NNode*, double); ~NLink(); unsigned long Get_Start_Index() { return (start->Get_Index()); } unsigned long Get_End_Index() { return (end->Get_Index()); } NNode *Get_Start() { return (start); } NNode *Get_End() { return (end); } double Get_Weight() { return weight; } void Set_Weight(double w) { weight = w; } double Get_OldWeight() { return old_weight; } void Set_OldWeight(double w) { old_weight = w; } unsigned long Get_Marker() { return marker; } void Set_Marker(unsigned long m) { marker = m; } unsigned long Get_Index() { return index; } void Set_Index(unsigned long i) { index = i; } }; //##################################################################################################### template class ClusterList : public DLList { friend class DLList_Iter; private: long links_out_of_cluster; unsigned long links_inside_cluster; unsigned long frequency; double cluster_energy; DLList *candidates; long marker; public: ClusterList(); ~ClusterList(); long Get_Links_OOC() { return (links_out_of_cluster); } void Set_Links_OOC(long looc) { links_out_of_cluster = looc; } unsigned long Get_Links_IC() { return (links_inside_cluster); } unsigned long Get_Frequency() { return (frequency); } void IncreaseFrequency() { frequency++; } void Set_Links_IC(unsigned long lic) { links_inside_cluster = lic; } double Get_Energy() { return (cluster_energy); } void Set_Energy(double e) { cluster_energy = e; } DLList *Get_Candidates() { return candidates; } bool operator<(ClusterList &b); bool operator==(ClusterList &b); long Get_Marker() { return marker; } void Set_Marker(long m) { marker = m; } }; //##################################################################################################### template class DL_Node_List : virtual public DL_Indexed_List { friend class DLList_Iter; private: DLItem *pInsert(NNode*, DLItem*); NNode* pDelete(DLItem*); HugeArray*> array; unsigned long last_index; public: DL_Node_List(); ~DL_Node_List(); NNode* Push(NNode*); NNode* Pop(); NNode* Get(unsigned long); int Delete(unsigned long); }; //##################################################################################################### struct cluster_join_move { ClusterList *c1; ClusterList *c2; double joint_energy; long joint_looc; unsigned long joint_lic; } ; struct network { DL_Indexed_List *node_list; DL_Indexed_List *link_list; DL_Indexed_List*> *cluster_list; // DL_Indexed_List *moveset; unsigned long max_k; unsigned long min_k; unsigned long diameter; double av_weight; double max_weight; double min_weight; double sum_weights; double av_k; double av_bids; unsigned long max_bids; unsigned long min_bids; unsigned long sum_bids; network() { node_list = new DL_Indexed_List(); link_list = new DL_Indexed_List(); cluster_list = new DL_Indexed_List*>(); } ~network() { ClusterList *cl_cur; while (link_list->Size()) { delete link_list->Pop(); } while (node_list->Size()) { delete node_list->Pop(); } while (cluster_list->Size()) { cl_cur = cluster_list->Pop(); while (cl_cur->Size()) { cl_cur->Pop(); } delete cl_cur; } delete link_list; delete node_list; delete cluster_list; } }; /* struct network { DLList *node_list; DLList *link_list; DLList*> *cluster_list; DLList *moveset; } ; */ template HugeArray::HugeArray() { max_bit_left = 1UL << 31; //wir setzen das 31. Bit auf 1 size = 2; max_index = 0; highest_field_index = 0; data = new DATA[2]; //ein extra Platz fuer das Nullelement data[0] = 0; data[1] = 0; for (int i = 0; i < 32; i++) { fields[i] = NULL; } fields[highest_field_index] = data; } template HugeArray::~HugeArray() { for (unsigned int i = 0; i <= highest_field_index; i++) { data = fields[i]; delete [] data; } } template HUGE_INDEX HugeArray::get_huge_index(unsigned long index) { HUGE_INDEX h_index; unsigned int shift_index = 0; unsigned long help_index; help_index = index; if (index < 2) { h_index.field_index = 0; h_index.in_field_index = index; return h_index; } // wie oft muessen wir help_index nach links shiften, damit das 31. Bit gesetzt ist?? while (!(max_bit_left & help_index)) { help_index <<= 1; shift_index++; } h_index.field_index = 31 - shift_index; // das hoechste besetzte Bit im Index help_index = 1UL << h_index.field_index; // in help_index wird das hoechste besetzte Bit von Index gesetzt h_index.in_field_index = (index ^ help_index); // index XOR help_index, womit alle bits unter dem hoechsten erhalten bleiben return h_index; } template DATA &HugeArray::Set(unsigned long int index) { HUGE_INDEX h_index; unsigned long data_size; while (size < index + 1) { highest_field_index++; data_size = 1UL << highest_field_index; data = new DATA[data_size]; for (unsigned long i = 0; i < data_size; i++) { data[i] = 0; } size = size + data_size; //overflow noch abfangen //printf("Vergroesserung auf: %u bei index %u\n",size,index); fields[highest_field_index] = data; } h_index = get_huge_index(index); //printf("index %lu = %lu . %lu\n",index,h_index.field_index,h_index.in_field_index); data = fields[h_index.field_index]; if (max_index < index) { max_index = index; } return (data[h_index.in_field_index]); } template DATA HugeArray::Get(unsigned long index) { return (Set(index)); } template DATA &HugeArray::operator[](unsigned long index) { return (Set(index)); } //############################################################################### template DLItem::DLItem(L_DATA i, unsigned long ind) : item(i), index(ind), previous(0), next(0) { } template DLItem::DLItem(L_DATA i, unsigned long ind, DLItem *p, DLItem *n) : item(i), index(ind), previous(p), next(n) { } template DLItem::~DLItem() { //delete item; //eigentlich muessten wir pruefen, ob item ueberhaupt ein Pointer ist... //previous=NULL; //next=NULL; } //###################################################################################################################### template DLList::DLList() { head = tail = NULL; number_of_items = 0; head = new DLItem(NULL, 0); //fuer head und Tail gibt es das gleiche Array-Element!! Vorsicht!! tail = new DLItem(NULL, 0); if ( !head || !tail ) { if (head) { delete (head); } if (tail) { delete (tail); } return; } else { head->next = tail; tail->previous = head; } } template DLList::~DLList() { DLItem *cur = head, *next; while (cur) { next = cur->next; delete (cur); cur = next; } number_of_items = 0; // printf("Liste Zerstoert!\n"); } template void DLList::delete_items() { DLItem *cur, *next; cur = this->head; while (cur) { next = cur->next; cur->del(); cur = next; } this->number_of_items = 0; } //privates Insert template DLItem *DLList::pInsert(L_DATA data, DLItem *pos) { DLItem *i = new DLItem(data, number_of_items + 1, pos->previous, pos); if (i) { pos->previous->next = i; pos->previous = i; number_of_items++; return (i); } else { return (0); } } //privates delete template L_DATA DLList::pDelete(DLItem *i) { L_DATA data = i->item; i->previous->next = i->next; i->next->previous = i->previous; // array[i->index]=0; delete (i); number_of_items--; return (data); } //oeffentliches Insert template int DLList::Insert(L_DATA data, unsigned long pos) { if ((pos < 0) || (pos > (number_of_items))) { return (0); } DLItem *cur = head; while (pos--) { cur = cur->next; } return (pInsert(data, cur) != 0); } //oeffentliche Delete template int DLList::Delete(unsigned long pos) { if ((pos < 0) || (pos > (number_of_items))) { return (0); } DLItem *cur = head; while (pos--) { cur = cur->next; } return (pDelete(cur) != 0); } //oeffentliche Delete template int DLList::fDelete(L_DATA data) { if ((number_of_items == 0) || (!data)) { return (0); } DLItem *cur; cur = head->next; while ((cur != tail) && (cur->item != data)) { cur = cur->next; } if (cur != tail) { return (pDelete(cur) != 0); } return (0); } template L_DATA DLList::Push(L_DATA data) { DLItem *tmp; tmp = pInsert(data, tail); if (tmp) { return (tmp->item); } return (0); } template L_DATA DLList::Pop() { return (pDelete(tail->previous)); } template L_DATA DLList::Get(unsigned long pos) { if ((pos < 1) || (pos > (number_of_items + 1))) { return (0); } // return(array[pos]->item); DLItem *cur = head; while (pos--) { cur = cur->next; } return (cur->item); } template int DLList::Enqueue(L_DATA data) { return (pInsert(data, tail) != 0); } template L_DATA DLList::Dequeue() { return (pDelete(head->next)); } //gibt Index des gesuchte Listenelement zurueck, besser waere eigentlich zeiger template unsigned long DLList::Is_In_List(L_DATA data) { DLItem *cur = head, *next; unsigned long pos = 0; while (cur) { next = cur->next; if (cur->item == data) { return (pos) ; } cur = next; pos++; } return (0); } //###################################################################################################################### template DL_Indexed_List::DL_Indexed_List() : DLList() { last_index = 0; } template DL_Indexed_List::~DL_Indexed_List() { /* This is already done by the DLList destructor */ /* DLItem *cur, *next; */ /* cur=this->head; */ /* while (cur) */ /* { */ /* next=cur->next; */ /* delete(cur); */ /* cur=next; */ /* } */ /* this->number_of_items=0; */ // printf("Liste Zerstoert!\n"); } //privates Insert template DLItem *DL_Indexed_List::pInsert(L_DATA data, DLItem *pos) { DLItem *i = new DLItem(data, last_index, pos->previous, pos); if (i) { pos->previous->next = i; pos->previous = i; this->number_of_items++; array[last_index] = i; last_index++; return (i); } else { return (0); } } //privates delete template L_DATA DL_Indexed_List::pDelete(DLItem *i) { L_DATA data = i->item; i->previous->next = i->next; i->next->previous = i->previous; array[i->index] = 0; last_index = i->index; delete (i); this->number_of_items--; return (data); } template L_DATA DL_Indexed_List::Push(L_DATA data) { DLItem *tmp; tmp = pInsert(data, this->tail); if (tmp) { return (tmp->item); } return (0); } template L_DATA DL_Indexed_List::Pop() { return (pDelete(this->tail->previous)); } template L_DATA DL_Indexed_List::Get(unsigned long pos) { if (pos > this->number_of_items - 1) { return (0); } return (array[pos]->item); } //####################################################################################### //************************************************************************************************************ template ClusterList::ClusterList() : DLList() { links_out_of_cluster = 0; links_inside_cluster = 0; frequency = 1; cluster_energy = 1e30; candidates = new DLList(); marker = 0; } template ClusterList::~ClusterList() { while (candidates->Size()) { candidates->Pop(); } delete candidates; } template bool ClusterList::operator==(ClusterList &b) { bool found = false; L_DATA n_cur, n_cur_b; DLList_Iter a_iter, b_iter; if (this->Size() != b.Size()) { return false; } n_cur = a_iter.First(this); while (!(a_iter.End())) { found = false; n_cur_b = b_iter.First(&b); while (!(b_iter.End()) && !found) { if (n_cur == n_cur_b) { found = true; } n_cur_b = b_iter.Next(); } if (!found) { return false; } n_cur = a_iter.Next(); } return (found); } //A bool ClusterList::operator<(ClusterList &b) { bool found = false; L_DATA n_cur, n_cur_b; DLList_Iter a_iter, b_iter; if (this->Size() >= b.Size()) { return false; } n_cur = a_iter.First(this); while (!(a_iter.End())) { found = false; n_cur_b = b_iter.First(&b); while (!(b_iter.End()) && !found) { if (n_cur == n_cur_b) { found = true; } n_cur_b = b_iter.Next(); } if (!found) { return false; } n_cur = a_iter.Next(); } return (found); } //##################################################################################### template DLList_Iter::DLList_Iter() { list = NULL; current = NULL; end_reached = true; } template L_DATA DLList_Iter::Next() { current = current->next; if (current == (list->tail)) { end_reached = true; } return (current->item); } template L_DATA DLList_Iter::Previous() { current = current->previous; if (current == (list->head)) { end_reached = true; } return (current->item); } template L_DATA DLList_Iter::First(DLList *l) { list = l; current = list->head->next; if (current == (list->tail)) { end_reached = true; } else { end_reached = false; } return (current->item); } template L_DATA DLList_Iter::Last(DLList *l) { list = l; current = list->tail->previous; if (current == (list->head)) { end_reached = true; // falls die List leer ist } else { end_reached = false; } return (current->item); } template bool DLList_Iter::Swap(DLList_Iter b) { L_DATA h; if (list != b.list) { return false; //elemeten muessen aus der gleichen List stammen } if (end_reached || b.end_reached) { return false; } h = current->item; current->item = b.current->item; b.current->item = h; return true; } #endif leidenbase/src/core/community/spinglass/clustertool.cpp0000644000176200001440000006257014447675374023235 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Joerg Reichardt The original copyright notice follows here */ /*************************************************************************** main.cpp - description ------------------- begin : Tue Jul 13 11:26:47 CEST 2004 copyright : (C) 2004 by email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "NetDataTypes.h" #include "NetRoutines.h" #include "pottsmodel_2.h" #include "igraph_community.h" #include "igraph_error.h" #include "igraph_random.h" #include "core/math.h" #include "igraph_interface.h" #include "igraph_components.h" #include "core/interruption.h" #include "core/exceptions.h" static int igraph_i_community_spinglass_orig( const igraph_t *graph, const igraph_vector_t *weights, igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t spins, igraph_bool_t parupdate, igraph_real_t starttemp, igraph_real_t stoptemp, igraph_real_t coolfact, igraph_spincomm_update_t update_rule, igraph_real_t gamma); static int igraph_i_community_spinglass_negative( const igraph_t *graph, const igraph_vector_t *weights, igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t spins, igraph_bool_t parupdate, igraph_real_t starttemp, igraph_real_t stoptemp, igraph_real_t coolfact, igraph_spincomm_update_t update_rule, igraph_real_t gamma, /* igraph_matrix_t *adhesion, */ /* igraph_matrix_t *normalised_adhesion, */ /* igraph_real_t *polarization, */ igraph_real_t gamma_minus); /** * \function igraph_community_spinglass * \brief Community detection based on statistical mechanics * * This function implements the community structure detection * algorithm proposed by Joerg Reichardt and Stefan Bornholdt. * The algorithm is described in their paper: Statistical Mechanics of * Community Detection, http://arxiv.org/abs/cond-mat/0603718 . * * * From version 0.6, igraph also supports an extension to * the algorithm that allows negative edge weights. This is described * in V. A. Traag and Jeroen Bruggeman: Community detection in networks * with positive and negative links, http://arxiv.org/abs/0811.2329 . * * \param graph The input graph, it may be directed but the direction * of the edges is not used in the algorithm. * \param weights The vector giving the edge weights, it may be \c NULL, * in which case all edges are weighted equally. The edge weights * must be positive unless using the \c IGRAPH_SPINCOMM_IMP_NEG * implementation. This condition is not verified by the function. * \param modularity Pointer to a real number, if not \c NULL then the * modularity score of the solution will be stored here. This is the * gereralized modularity that simplifies to the one defined in * M. E. J. Newman and M. Girvan, Phys. Rev. E 69, 026113 (2004), * if the gamma parameter is one. * \param temperature Pointer to a real number, if not \c NULL then * the temperature at the end of the algorithm will be stored * here. * \param membership Pointer to an initialized vector or \c NULL. If * not \c NULL then the result of the clustering will be stored * here. For each vertex, the number of its cluster is given, with the * first cluster numbered zero. The vector will be resized as * needed. * \param csize Pointer to an initialized vector or \c NULL. If not \c * NULL then the sizes of the clusters will stored here in cluster * number order. The vector will be resized as needed. * \param spins Integer giving the number of spins, i.e. the maximum * number of clusters. Usually it is not a program to give a high * number here, the default was 25 in the original code. Even if * the number of spins is high the number of clusters in the * result might be small. * \param parupdate A logical constant, whether to update all spins in * parallel. The default for this argument was \c FALSE (i.e. 0) in * the original code. It is not implemented in the \c * IGRAPH_SPINCOMM_INP_NEG implementation. * \param starttemp Real number, the temperature at the start. The * value of this argument was 1.0 in the original code. * \param stoptemp Real number, the algorithm stops at this * temperature. The default was 0.01 in the original code. * \param coolfact Real number, the cooling factor for the simulated * annealing. The default was 0.99 in the original code. * \param update_rule The type of the update rule. Possible values: \c * IGRAPH_SPINCOMM_UPDATE_SIMPLE and \c * IGRAPH_SPINCOMM_UPDATE_CONFIG. Basically this parameter defines * the null model based on which the actual clustering is done. If * this is \c IGRAPH_SPINCOMM_UPDATE_SIMPLE then the random graph * (i.e. G(n,p)), if it is \c IGRAPH_SPINCOMM_UPDATE then the * configuration model is used. The configuration means that the * baseline for the clustering is a random graph with the same * degree distribution as the input graph. * \param gamma Real number. The gamma parameter of the * algorithm. This defines the weight of the missing and existing * links in the quality function for the clustering. The default * value in the original code was 1.0, which is equal weight to * missing and existing edges. Smaller values make the existing * links contibute more to the energy function which is minimized * in the algorithm. Bigger values make the missing links more * important. (If my understanding is correct.) * \param implementation Constant, chooses between the two * implementations of the spin-glass algorithm that are included * in igraph. \c IGRAPH_SPINCOMM_IMP_ORIG selects the original * implementation, this is faster, \c IGRAPH_SPINCOMM_INP_NEG selects * a new implementation by Vincent Traag that allows negative edge * weights. * \param gamma_minus Real number. Parameter for the \c * IGRAPH_SPINCOMM_IMP_NEG implementation. This * specifies the balance between the importance of present and * non-present negative weighted edges in a community. Smaller values of * \p gamma_minus lead to communities with lesser * negative intra-connectivity. * If this argument is set to zero, the algorithm reduces to a graph * coloring algorithm, using the number of spins as the number of * colors. * \return Error code. * * \sa igraph_community_spinglass_single() for calculating the community * of a single vertex. * * Time complexity: TODO. * */ int igraph_community_spinglass(const igraph_t *graph, const igraph_vector_t *weights, igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t spins, igraph_bool_t parupdate, igraph_real_t starttemp, igraph_real_t stoptemp, igraph_real_t coolfact, igraph_spincomm_update_t update_rule, igraph_real_t gamma, /* the rest is for the NegSpin implementation */ igraph_spinglass_implementation_t implementation, /* igraph_matrix_t *adhesion, */ /* igraph_matrix_t *normalised_adhesion, */ /* igraph_real_t *polarization, */ igraph_real_t gamma_minus) { IGRAPH_HANDLE_EXCEPTIONS( switch (implementation) { case IGRAPH_SPINCOMM_IMP_ORIG: return igraph_i_community_spinglass_orig(graph, weights, modularity, temperature, membership, csize, spins, parupdate, starttemp, stoptemp, coolfact, update_rule, gamma); break; case IGRAPH_SPINCOMM_IMP_NEG: return igraph_i_community_spinglass_negative(graph, weights, modularity, temperature, membership, csize, spins, parupdate, starttemp, stoptemp, coolfact, update_rule, gamma, /* adhesion, normalised_adhesion, */ /* polarization, */ gamma_minus); break; default: IGRAPH_ERROR("Unknown `implementation' in spinglass community finding", IGRAPH_EINVAL); } ); } static int igraph_i_community_spinglass_orig( const igraph_t *graph, const igraph_vector_t *weights, igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t spins, igraph_bool_t parupdate, igraph_real_t starttemp, igraph_real_t stoptemp, igraph_real_t coolfact, igraph_spincomm_update_t update_rule, igraph_real_t gamma) { long int no_of_nodes = igraph_vcount(graph); unsigned long changes, runs; igraph_bool_t use_weights = 0; bool zeroT; double kT, acc, prob; /* Check arguments */ if (spins < 2) { IGRAPH_ERROR("Number of spins must be at least 2", IGRAPH_EINVAL); } if (update_rule != IGRAPH_SPINCOMM_UPDATE_SIMPLE && update_rule != IGRAPH_SPINCOMM_UPDATE_CONFIG) { IGRAPH_ERROR("Invalid update rule", IGRAPH_EINVAL); } if (weights) { if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } use_weights = 1; } if (coolfact < 0 || coolfact >= 1.0) { IGRAPH_ERROR("Invalid cooling factor", IGRAPH_EINVAL); } if (gamma < 0.0) { IGRAPH_ERROR("Invalid gamma value", IGRAPH_EINVAL); } if (starttemp / stoptemp < 1.0) { IGRAPH_ERROR("starttemp should be larger in absolute value than stoptemp", IGRAPH_EINVAL); } /* The spinglass algorithm does not handle the trivial cases of the null and singleton graphs, so we catch them here. */ if (no_of_nodes < 2) { if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); igraph_vector_fill(membership, 0); } if (modularity) { IGRAPH_CHECK(igraph_modularity(graph, membership, 0, 1, igraph_is_directed(graph), modularity)); } if (temperature) { *temperature = stoptemp; } if (csize) { /* 0 clusters for 0 nodes, 1 cluster for 1 node */ IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); igraph_vector_fill(membership, 1); } return IGRAPH_SUCCESS; } /* Check whether we have a single component */ igraph_bool_t conn; IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK)); if (!conn) { IGRAPH_ERROR("Cannot work with unconnected graph", IGRAPH_EINVAL); } network net; /* Transform the igraph_t */ IGRAPH_CHECK(igraph_i_read_network(graph, weights, &net, use_weights, 0)); prob = 2.0 * net.sum_weights / double(net.node_list->Size()) / double(net.node_list->Size() - 1); PottsModel pm(&net, (unsigned int)spins, update_rule); /* initialize the random number generator */ RNG_BEGIN(); if ((stoptemp == 0.0) && (starttemp == 0.0)) { zeroT = true; } else { zeroT = false; } if (!zeroT) { kT = pm.FindStartTemp(gamma, prob, starttemp); } else { kT = stoptemp; } /* assign random initial configuration */ pm.assign_initial_conf(-1); runs = 0; changes = 1; while (changes > 0 && (kT / stoptemp > 1.0 || (zeroT && runs < 150))) { IGRAPH_ALLOW_INTERRUPTION(); runs++; if (!zeroT) { kT *= coolfact; if (parupdate) { changes = pm.HeatBathParallelLookup(gamma, prob, kT, 50); } else { acc = pm.HeatBathLookup(gamma, prob, kT, 50); if (acc < (1.0 - 1.0 / double(spins)) * 0.01) { changes = 0; } else { changes = 1; } } } else { if (parupdate) { changes = pm.HeatBathParallelLookupZeroTemp(gamma, prob, 50); } else { acc = pm.HeatBathLookupZeroTemp(gamma, prob, 50); /* less than 1 percent acceptance ratio */ if (acc < (1.0 - 1.0 / double(spins)) * 0.01) { changes = 0; } else { changes = 1; } } } } /* while loop */ pm.WriteClusters(modularity, temperature, csize, membership, kT, gamma); RNG_END(); return 0; } /** * \function igraph_community_spinglass_single * \brief Community of a single node based on statistical mechanics * * This function implements the community structure detection * algorithm proposed by Joerg Reichardt and Stefan Bornholdt. It is * described in their paper: Statistical Mechanics of * Community Detection, http://arxiv.org/abs/cond-mat/0603718 . * * * This function calculates the community of a single vertex without * calculating all the communities in the graph. * * \param graph The input graph, it may be directed but the direction * of the edges is not used in the algorithm. * \param weights Pointer to a vector with the weights of the edges. * Alternatively \c NULL can be supplied to have the same weight * for every edge. * \param vertex The vertex id of the vertex of which ths community is * calculated. * \param community Pointer to an initialized vector, the result, the * ids of the vertices in the community of the input vertex will be * stored here. The vector will be resized as needed. * \param cohesion Pointer to a real variable, if not \c NULL the * cohesion index of the community will be stored here. * \param adhesion Pointer to a real variable, if not \c NULL the * adhesion index of the community will be stored here. * \param inner_links Pointer to an integer, if not \c NULL the * number of edges within the community is stored here. * \param outer_links Pointer to an integer, if not \c NULL the * number of edges between the community and the rest of the graph * will be stored here. * \param spins The number of spins to use, this can be higher than * the actual number of clusters in the network, in which case some * clusters will contain zero vertices. * \param update_rule The type of the update rule. Possible values: \c * IGRAPH_SPINCOMM_UPDATE_SIMPLE and \c * IGRAPH_SPINCOMM_UPDATE_CONFIG. Basically this parameter defined * the null model based on which the actual clustering is done. If * this is \c IGRAPH_SPINCOMM_UPDATE_SIMPLE then the random graph * (ie. G(n,p)), if it is \c IGRAPH_SPINCOMM_UPDATE then the * configuration model is used. The configuration means that the * baseline for the clustering is a random graph with the same * degree distribution as the input graph. * \param gamma Real number. The gamma parameter of the * algorithm. This defined the weight of the missing and existing * links in the quality function for the clustering. The default * value in the original code was 1.0, which is equal weight to * missing and existing edges. Smaller values make the existing * links contibute more to the energy function which is minimized * in the algorithm. Bigger values make the missing links more * important. (If my understanding is correct.) * \return Error code. * * \sa igraph_community_spinglass() for the traditional version of the * algorithm. * * Time complexity: TODO. */ int igraph_community_spinglass_single(const igraph_t *graph, const igraph_vector_t *weights, igraph_integer_t vertex, igraph_vector_t *community, igraph_real_t *cohesion, igraph_real_t *adhesion, igraph_integer_t *inner_links, igraph_integer_t *outer_links, igraph_integer_t spins, igraph_spincomm_update_t update_rule, igraph_real_t gamma) { IGRAPH_HANDLE_EXCEPTIONS( igraph_bool_t use_weights = 0; double prob; char startnode[255]; /* Check arguments */ if (spins < 2) { IGRAPH_ERROR("Number of spins must be at least 2", IGRAPH_EINVAL); } if (update_rule != IGRAPH_SPINCOMM_UPDATE_SIMPLE && update_rule != IGRAPH_SPINCOMM_UPDATE_CONFIG) { IGRAPH_ERROR("Invalid update rule", IGRAPH_EINVAL); } if (weights) { if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } use_weights = 1; } if (gamma < 0.0) { IGRAPH_ERROR("Invalid gamme value", IGRAPH_EINVAL); } if (vertex < 0 || vertex > igraph_vcount(graph)) { IGRAPH_ERROR("Invalid vertex id", IGRAPH_EINVAL); } /* Check whether we have a single component */ igraph_bool_t conn; IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK)); if (!conn) { IGRAPH_ERROR("Cannot work with unconnected graph", IGRAPH_EINVAL); } network net; /* Transform the igraph_t */ IGRAPH_CHECK(igraph_i_read_network(graph, weights, &net, use_weights, 0)); prob = 2.0 * net.sum_weights / double(net.node_list->Size()) / double(net.node_list->Size() - 1); PottsModel pm(&net, (unsigned int)spins, update_rule); /* initialize the random number generator */ RNG_BEGIN(); /* to be exected, if we want to find the community around a particular node*/ /* the initial conf is needed, because otherwise, the degree of the nodes is not in the weight property, stupid!!! */ pm.assign_initial_conf(-1); snprintf(startnode, 255, "%li", (long int)vertex + 1); pm.FindCommunityFromStart(gamma, prob, startnode, community, cohesion, adhesion, inner_links, outer_links); RNG_END(); ); return 0; } static int igraph_i_community_spinglass_negative( const igraph_t *graph, const igraph_vector_t *weights, igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t spins, igraph_bool_t parupdate, igraph_real_t starttemp, igraph_real_t stoptemp, igraph_real_t coolfact, igraph_spincomm_update_t update_rule, igraph_real_t gamma, /* igraph_matrix_t *adhesion, */ /* igraph_matrix_t *normalised_adhesion, */ /* igraph_real_t *polarization, */ igraph_real_t gamma_minus) { long int no_of_nodes = igraph_vcount(graph); unsigned long changes, runs; igraph_bool_t use_weights = 0; bool zeroT; double kT, acc; igraph_real_t d_n; igraph_real_t d_p; /* Check arguments */ if (parupdate) { IGRAPH_ERROR("Parallel spin update not implemented with " "negative gamma", IGRAPH_UNIMPLEMENTED); } if (spins < 2) { IGRAPH_ERROR("Number of spins must be at least 2", IGRAPH_EINVAL); } if (update_rule != IGRAPH_SPINCOMM_UPDATE_SIMPLE && update_rule != IGRAPH_SPINCOMM_UPDATE_CONFIG) { IGRAPH_ERROR("Invalid update rule", IGRAPH_EINVAL); } if (weights) { if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } use_weights = 1; } if (coolfact < 0 || coolfact >= 1.0) { IGRAPH_ERROR("Invalid cooling factor", IGRAPH_EINVAL); } if (gamma < 0.0) { IGRAPH_ERROR("Invalid gamma value", IGRAPH_EINVAL); } if (starttemp / stoptemp < 1.0) { IGRAPH_ERROR("starttemp should be larger in absolute value than stoptemp", IGRAPH_EINVAL); } /* The spinglass algorithm does not handle the trivial cases of the null and singleton graphs, so we catch them here. */ if (no_of_nodes < 2) { if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); igraph_vector_fill(membership, 0); } if (modularity) { IGRAPH_CHECK(igraph_modularity(graph, membership, 0, 1, igraph_is_directed(graph), modularity)); } if (temperature) { *temperature = stoptemp; } if (csize) { /* 0 clusters for 0 nodes, 1 cluster for 1 node */ IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); igraph_vector_fill(membership, 1); } return IGRAPH_SUCCESS; } /* Check whether we have a single component */ igraph_bool_t conn; IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK)); if (!conn) { IGRAPH_ERROR("Cannot work with unconnected graph", IGRAPH_EINVAL); } if (weights) { igraph_vector_minmax(weights, &d_n, &d_p); } else { d_n = d_p = 1; } if (d_n > 0) { d_n = 0; } if (d_p < 0) { d_p = 0; } d_n = -d_n; network net; /* Transform the igraph_t */ IGRAPH_CHECK(igraph_i_read_network(graph, weights, &net, use_weights, 0)); bool directed = igraph_is_directed(graph); PottsModelN pm(&net, (unsigned int)spins, directed); /* initialize the random number generator */ RNG_BEGIN(); if ((stoptemp == 0.0) && (starttemp == 0.0)) { zeroT = true; } else { zeroT = false; } //Begin at a high enough temperature kT = pm.FindStartTemp(gamma, gamma_minus, starttemp); /* assign random initial configuration */ pm.assign_initial_conf(true); runs = 0; changes = 1; acc = 0; while (changes > 0 && (kT / stoptemp > 1.0 || (zeroT && runs < 150))) { IGRAPH_ALLOW_INTERRUPTION(); runs++; kT = kT * coolfact; acc = pm.HeatBathLookup(gamma, gamma_minus, kT, 50); if (acc < (1.0 - 1.0 / double(spins)) * 0.001) { changes = 0; } else { changes = 1; } } /* while loop */ /* These are needed, otherwise 'modularity' is not calculated */ igraph_matrix_t adhesion, normalized_adhesion; igraph_real_t polarization; IGRAPH_MATRIX_INIT_FINALLY(&adhesion, 0, 0); IGRAPH_MATRIX_INIT_FINALLY(&normalized_adhesion, 0, 0); pm.WriteClusters(modularity, temperature, csize, membership, &adhesion, &normalized_adhesion, &polarization, kT, d_p, d_n, gamma, gamma_minus); igraph_matrix_destroy(&normalized_adhesion); igraph_matrix_destroy(&adhesion); IGRAPH_FINALLY_CLEAN(2); RNG_END(); return 0; } leidenbase/src/core/community/spinglass/NetRoutines.h0000644000176200001440000000473314447675374022577 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Jörg Reichardt The original copyright notice follows here */ /*************************************************************************** NetRoutines.h - description ------------------- begin : Tue Oct 28 2003 copyright : (C) 2003 by Joerg Reichardt email : reichardt@mitte ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef NETROUTINES_H #define NETROUTINES_H #include "NetDataTypes.h" #include "igraph_types.h" #include "igraph_datatype.h" int igraph_i_read_network(const igraph_t *graph, const igraph_vector_t *weights, network *net, igraph_bool_t use_weights, unsigned int states); void reduce_cliques(DLList*>*, FILE *file); void reduce_cliques2(network*, bool, long ); void clear_all_markers(network *net); #endif leidenbase/src/core/community/spinglass/NetDataTypes.cpp0000644000176200001440000001545514447675374023223 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Jörg Reichardt The original copyright notice follows here */ /*************************************************************************** NetDataTypes.cpp - description ------------------- begin : Mon Oct 6 2003 copyright : (C) 2003 by Joerg Reichardt email : reichardt@mitte ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "NetDataTypes.h" #include //################################################################################# //############################################################################### //Constructor NNode::NNode(unsigned long ind, unsigned long c_ind, DLList *ll, const char *n, int states) { index = ind; cluster_index = c_ind; neighbours = new DLList(); n_links = new DLList(); global_link_list = ll; strcpy(name, n); color.red = 0; color.green = 0; color.blue = 0; strcpy(color.pajek_c, "Green"); clustering = 0.0; marker = 0; affiliations = 0; weight = 0.0; affinity = 0.0; distance = 0; max_states = states; state_history = new unsigned long[states + 1]; } //Destructor NNode::~NNode() { Disconnect_From_All(); delete neighbours; delete n_links; delete [] state_history; neighbours = NULL; n_links = NULL; state_history = NULL; } void NNode::Add_StateHistory(unsigned int state) { if (max_states >= state) { state_history[state]++; } } void NNode::Set_Color(RGBcolor c) { color.red = c.red; color.blue = c.blue; color.green = c.green; strcpy(color.pajek_c, c.pajek_c); } int NNode::Connect_To(NNode* neighbour, double weight_) { NLink *link; //sollen doppelte Links erlaubt sein?? NEIN if (!neighbour) { return 0; } if (!(neighbours->Is_In_List(neighbour)) && (neighbour != this)) { neighbours->Push(neighbour); // nachbar hier eintragen neighbour->neighbours->Push(this); // diesen knoten beim nachbarn eintragen link = new NLink(this, neighbour, weight_); //link erzeugen global_link_list->Push(link); // in globaler liste eintragen n_links->Push(link); // bei diesem Knoten eintragen neighbour->n_links->Push(link); // beim nachbarn eintragen return (1); } return (0); } NLink *NNode::Get_LinkToNeighbour(NNode* neighbour) { DLList_Iter iter; NLink *l_cur, *link = NULL; bool found = false; // finde einen bestimmten Link aus der Liste der links eines Knotens l_cur = iter.First(n_links); while (!iter.End() && !found) { if (((l_cur->Get_Start() == this) && (l_cur->Get_End() == neighbour)) || ((l_cur->Get_End() == this) && (l_cur->Get_Start() == neighbour))) { found = true; link = l_cur; } l_cur = iter.Next(); } if (found) { return link; } else { return NULL; } } int NNode::Disconnect_From(NNode* neighbour) { //sollen doppelte Links erlaubt sein?? s.o. if (!neighbours) { return 0; } neighbours->fDelete(neighbour); n_links->fDelete(Get_LinkToNeighbour(neighbour)); neighbour->n_links->fDelete(neighbour->Get_LinkToNeighbour(this)); neighbour->neighbours->fDelete(this); return 1; } int NNode::Disconnect_From_All() { int number_of_neighbours = 0; while (neighbours->Size()) { Disconnect_From(neighbours->Pop()); number_of_neighbours++; } return (number_of_neighbours) ; } /* int NNode::Disconnect_From_All_Grandchildren() { int n_l=links->Size(); unsigned long pos=0; while ((n_l--)>1) { //alle bis auf das erste loeschen pos=(links->Get(n_l+1))->links->Is_In_List(this); // printf("%d %d\n",n_l,pos); (links->Get(n_l+1))->links->Delete(pos); } return(pos) ; } */ double NNode::Get_Links_Among_Neigbours() { // long neighbours1, neighbours2; double lam = 0; DLList_Iter iter1, iter2; // neighbours1=neighbours->Size(); //so viele Nachbarn hat die Betrachtete Node NNode *step1, *step2; step1 = iter1.First(neighbours); while (!iter1.End()) { // for (int n1=1;n1<=neighbours1; n1++) //step1=neighbours->Get(n1); //neighbours2=step1->neighbours->Size(); //so viele Nachbarn hat der n1-ste Nachbar step2 = iter2.First(step1->Get_Neighbours()); while (!iter2.End()) { //for (int n2=1;n2<=neighbours2; n2++) //step2=step1->neighbours->Get(n2); if (step2->Get_Neighbours()->Is_In_List(this)) { lam++; } step2 = iter2.Next(); } step1 = iter1.Next(); } return (lam / 2.0); } double NNode::Get_Clustering() { double c; unsigned long k; k = neighbours->Size(); if (k <= 1) { return (0); } c = 2.0 * Get_Links_Among_Neigbours() / double(k * k - k); return (c); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Constructor NLink::NLink(NNode *s, NNode *e, double w) { start = s; end = e; weight = w; old_weight = 0; marker = 0; } //Destructor NLink::~NLink() { if (start && end) { start->Disconnect_From(end); } } leidenbase/src/core/community/spinglass/NetRoutines.cpp0000644000176200001440000002327514451322564023115 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The original version of this file was written by Jörg Reichardt The original copyright notice follows here */ /*************************************************************************** NetRoutines.cpp - description ------------------- begin : Tue Oct 28 2003 copyright : (C) 2003 by Joerg Reichardt email : reichardt@mitte ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "NetRoutines.h" #include "NetDataTypes.h" #include "igraph_types.h" #include "igraph_interface.h" #include "igraph_conversion.h" int igraph_i_read_network(const igraph_t *graph, const igraph_vector_t *weights, network *net, igraph_bool_t use_weights, unsigned int states) { double av_k = 0.0, sum_weight = 0.0, min_weight = 1e60, max_weight = -1e60; unsigned long min_k = 999999999, max_k = 0; char name[255]; NNode *node1, *node2; DLList_Iter iter; igraph_vector_t edgelist; long int no_of_nodes = (long int) igraph_vcount(graph); long int no_of_edges = (long int) igraph_ecount(graph); long int ii; const char *empty = ""; IGRAPH_VECTOR_INIT_FINALLY(&edgelist, no_of_edges * 2); IGRAPH_CHECK(igraph_get_edgelist(graph, &edgelist, 0 /* rowwise */)); for (ii = 0; ii < no_of_nodes; ii++) { net->node_list->Push(new NNode(ii, 0, net->link_list, empty, states)); } for (ii = 0; ii < no_of_edges; ii++) { long int i1 = (long int)VECTOR(edgelist)[2 * ii]; long int i2 = (long int)VECTOR(edgelist)[2 * ii + 1]; igraph_real_t Links; if (use_weights) { Links = VECTOR(*weights)[ii]; } else { Links = 1.0; } node1 = net->node_list->Get(i1); snprintf(name, (size_t)255, "%li", i1+1); node1->Set_Name(name); node2 = net->node_list->Get(i2); snprintf(name, (size_t)255, "%li", i2+1); node2->Set_Name(name); node1->Connect_To(node2, Links); if (Links < min_weight) { min_weight = Links; } if (Links > max_weight) { max_weight = Links; } sum_weight += Links; } IGRAPH_FINALLY_CLEAN(1); igraph_vector_destroy(&edgelist); node1 = iter.First(net->node_list); while (!iter.End()) { if (node1->Get_Degree() > max_k) { max_k = node1->Get_Degree(); } if (node1->Get_Degree() < min_k) { min_k = node1->Get_Degree(); } av_k += node1->Get_Degree(); node1 = iter.Next(); } net->av_k = av_k / double(net->node_list->Size()); net->sum_weights = sum_weight; net->av_weight = sum_weight / double(net->link_list->Size()); net->min_k = min_k; net->max_k = max_k; net->min_weight = min_weight; net->max_weight = max_weight; net->sum_bids = 0; net->min_bids = 0; net->max_bids = 0; return IGRAPH_SUCCESS; } //############################################################################################################### void reduce_cliques(DLList*> *global_cluster_list, FILE *file) { unsigned long size; ClusterList *c_cur, *largest_c = NULL; DLList*> *subsets; DLList_Iter*> c_iter, sub_iter; DLList_Iter iter; NNode *n_cur; if (!(global_cluster_list->Size())) { return; } //wir suchen den groessten Cluster c_cur = c_iter.First(global_cluster_list); size = 0; while (!(c_iter.End())) { if (c_cur->Size() > size) { size = c_cur->Size(); largest_c = c_cur; } c_cur = c_iter.Next(); } // printf("Groesster Cluster hat %u Elemente.\n",largest_c->Size()); //Schauen, ob es Teilmengen gibt, die ebenfalls gefunden wurden subsets = new DLList*>(); c_cur = c_iter.First(global_cluster_list); while (!(c_iter.End())) { if ((*c_cur < *largest_c || *c_cur == *largest_c) && c_cur != largest_c) { //alle echten Teilcluster von largest_c und die doppelten subsets->Push(c_cur); } c_cur = c_iter.Next(); } // die gefundenen Subsets werden aus der cluster_liste geloescht while (subsets->Size()) { global_cluster_list->fDelete(subsets->Pop()); } delete subsets; // Dann schreiben wir den groessten Cluster in das File fprintf(file, "Energie: %1.12f Nodes:%3lu - ", largest_c->Get_Energy(), largest_c->Size()); n_cur = iter.First(largest_c); while (!(iter.End())) { fprintf(file, "%s", n_cur->Get_Name()); n_cur = iter.Next(); if (n_cur) { fprintf(file, ", "); } } fprintf(file, "\n"); //Schliesslich schmeissen wir noch den eben gefundenen groessten Cluster raus global_cluster_list->fDelete(largest_c); //und dann geht es von vorn mit der Reduzierten ClusterListe los reduce_cliques(global_cluster_list, file); } //################################################################################## void reduce_cliques2(network *net, bool only_double, long marker) { unsigned long size; ClusterList *c_cur, *largest_c = NULL; DLList_Iter*> c_iter; do { //wir suchen den groessten, nicht markierten Cluster size = 0; c_cur = c_iter.First(net->cluster_list); while (!(c_iter.End())) { if ((c_cur->Size() > size) && (c_cur->Get_Marker() != marker)) { size = c_cur->Size(); largest_c = c_cur; } c_cur = c_iter.Next(); } // printf("Groesster Cluster hat %u Elemente.\n",largest_c->Size()); //Schauen, ob es Teilmengen gibt, die ebenfalls gefunden wurden c_cur = c_iter.First(net->cluster_list); while (!(c_iter.End())) { if (((!only_double && (*c_cur < *largest_c)) || (*c_cur == *largest_c)) && (c_cur != largest_c)) { //alle echten Teilcluster von largest_c und die doppelten net->cluster_list->fDelete(c_cur); while (c_cur->Get_Candidates()->Size()) { c_cur->Get_Candidates()->Pop(); } while (c_cur->Size()) { c_cur->Pop(); // die knoten aber nicht loeschen!! } delete c_cur; // nicht vergessen, die global geloeschte Clusterliste zu loeschen } c_cur = c_iter.Next(); } //Schliesslich markieren wir noch den eben gefundenen groessten Cluster largest_c->Set_Marker(marker); } while (size); } //################################################################################################## unsigned long iterate_nsf_hierarchy(NNode *parent, unsigned long depth, FILE *file) { NNode* next_node; unsigned long newdepth, maxdepth; bool first = true; DLList_Iter *iter; maxdepth = newdepth = depth; iter = new DLList_Iter; next_node = iter->First(parent->Get_Neighbours()); while (!(iter->End())) { if (next_node->Get_Marker() > parent->Get_Marker()) { // wir gehen nach unten if (first) { fprintf(file, ",("); // eine Neue Klammer auf } if (first) { fprintf(file, "%s", next_node->Get_Name()); // nur vor dem ersten kein Komma } else { fprintf(file, ",%s", next_node->Get_Name()); // sonst immer mit Komma } first = false; newdepth = iterate_nsf_hierarchy(next_node, depth + 1, file); if (maxdepth < newdepth) { maxdepth = newdepth; } } next_node = iter->Next(); } if (!first) { fprintf(file, ")"); //hat es ueberhaupt einen gegeben? } //dann klamer zu! delete iter; return maxdepth; } //################################################################ void clear_all_markers(network *net) { DLList_Iter iter; NNode *n_cur; n_cur = iter.First(net->node_list); while (!iter.End()) { n_cur->Set_Marker(0); n_cur = iter.Next(); } } leidenbase/src/core/community/fast_modularity.c0000644000176200001440000012762414447675374021523 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_memory.h" #include "igraph_iterators.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "igraph_structural.h" #include "igraph_vector_ptr.h" #include "core/interruption.h" /* #define IGRAPH_FASTCOMM_DEBUG */ #ifdef _MSC_VER /* MSVC does not support variadic macros */ #include void debug(const char* fmt, ...) { va_list args; va_start(args, fmt); #ifdef IGRAPH_FASTCOMM_DEBUG vfprintf(stderr, fmt, args); #endif va_end(args); } #else #ifdef IGRAPH_FASTCOMM_DEBUG #define debug(...) fprintf(stderr, __VA_ARGS__) #else #define debug(...) #endif #endif /* * Implementation of the community structure algorithm originally published * by Clauset et al in: * * A. Clauset, M.E.J. Newman and C. Moore, "Finding community structure in * very large networks.". Phys. Rev. E 70, 066111 (2004). * * The data structures being used are slightly different and they are described * most closely in: * * K. Wakita, T. Tsurumi, "Finding community structure in mega-scale social * networks.". arXiv:cs/0702048v1. * * We maintain a vector of communities, each of which containing a list of * pointers to their neighboring communities along with the increase in the * modularity score that could be achieved by joining the two communities. * Each community has a pointer to one of its neighbors - the one which would * result in the highest increase in modularity after a join. The local * (community-level) maximums are also stored in an indexed max-heap. The * max-heap itself stores its elements in an array which satisfies the heap * property, but to allow us to access any of the elements in the array based * on the community index (and not based on the array index - which depends on * the element's actual position in the heap), we also maintain an index * vector in the heap: the ith element of the index vector contains the * position of community i in the array of the max-heap. When we perform * sifting operations on the heap to restore the heap property, we also maintain * the index vector. */ /* Structure storing a pair of communities along with their dQ values */ typedef struct s_igraph_i_fastgreedy_commpair { long int first; /* first member of the community pair */ long int second; /* second member of the community pair */ igraph_real_t *dq; /* pointer to a member of the dq vector storing the */ /* increase in modularity achieved when joining */ struct s_igraph_i_fastgreedy_commpair *opposite; } igraph_i_fastgreedy_commpair; /* Structure storing a community */ typedef struct { igraph_integer_t id; /* Identifier of the community (for merges matrix) */ igraph_integer_t size; /* Size of the community */ igraph_vector_ptr_t neis; /* references to neighboring communities */ igraph_i_fastgreedy_commpair* maxdq; /* community pair with maximal dq */ } igraph_i_fastgreedy_community; /* Global community list structure */ typedef struct { long int no_of_communities, n; /* number of communities, number of vertices */ igraph_i_fastgreedy_community* e; /* list of communities */ igraph_i_fastgreedy_community** heap; /* heap of communities */ igraph_integer_t *heapindex; /* heap index to speed up lookup by community idx */ } igraph_i_fastgreedy_community_list; /* Scans the community neighborhood list for the new maximal dq value. * Returns 1 if the maximum is different from the previous one, * 0 otherwise. */ static int igraph_i_fastgreedy_community_rescan_max( igraph_i_fastgreedy_community* comm) { long int i, n; igraph_i_fastgreedy_commpair *p, *best; igraph_real_t bestdq, currdq; n = igraph_vector_ptr_size(&comm->neis); if (n == 0) { comm->maxdq = 0; return 1; } best = (igraph_i_fastgreedy_commpair*)VECTOR(comm->neis)[0]; bestdq = *best->dq; for (i = 1; i < n; i++) { p = (igraph_i_fastgreedy_commpair*)VECTOR(comm->neis)[i]; currdq = *p->dq; if (currdq > bestdq) { best = p; bestdq = currdq; } } if (best != comm->maxdq) { comm->maxdq = best; return 1; } else { return 0; } } /* Destroys the global community list object */ static void igraph_i_fastgreedy_community_list_destroy( igraph_i_fastgreedy_community_list* list) { long int i; for (i = 0; i < list->n; i++) { igraph_vector_ptr_destroy(&list->e[i].neis); } IGRAPH_FREE(list->e); if (list->heapindex != 0) { IGRAPH_FREE(list->heapindex); } if (list->heap != 0) { IGRAPH_FREE(list->heap); } } /* Community list heap maintenance: sift down */ static void igraph_i_fastgreedy_community_list_sift_down( igraph_i_fastgreedy_community_list* list, long int idx) { long int root, child, c1, c2; igraph_i_fastgreedy_community* dummy; igraph_integer_t dummy2; igraph_i_fastgreedy_community** heap = list->heap; igraph_integer_t* heapindex = list->heapindex; root = idx; while (root * 2 + 1 < list->no_of_communities) { child = root * 2 + 1; if (child + 1 < list->no_of_communities && *heap[child]->maxdq->dq < *heap[child + 1]->maxdq->dq) { child++; } if (*heap[root]->maxdq->dq < *heap[child]->maxdq->dq) { c1 = heap[root]->maxdq->first; c2 = heap[child]->maxdq->first; dummy = heap[root]; heap[root] = heap[child]; heap[child] = dummy; dummy2 = heapindex[c1]; heapindex[c1] = heapindex[c2]; heapindex[c2] = dummy2; root = child; } else { break; } } } /* Community list heap maintenance: sift up */ static void igraph_i_fastgreedy_community_list_sift_up( igraph_i_fastgreedy_community_list* list, long int idx) { long int root, parent, c1, c2; igraph_i_fastgreedy_community* dummy; igraph_integer_t dummy2; igraph_i_fastgreedy_community** heap = list->heap; igraph_integer_t* heapindex = list->heapindex; root = idx; while (root > 0) { parent = (root - 1) / 2; if (*heap[parent]->maxdq->dq < *heap[root]->maxdq->dq) { c1 = heap[root]->maxdq->first; c2 = heap[parent]->maxdq->first; dummy = heap[parent]; heap[parent] = heap[root]; heap[root] = dummy; dummy2 = heapindex[c1]; heapindex[c1] = heapindex[c2]; heapindex[c2] = dummy2; root = parent; } else { break; } } } /* Builds the community heap for the first time */ static void igraph_i_fastgreedy_community_list_build_heap( igraph_i_fastgreedy_community_list* list) { long int i; for (i = list->no_of_communities / 2 - 1; i >= 0; i--) { igraph_i_fastgreedy_community_list_sift_down(list, i); } } /* Finds the element belonging to a given community in the heap and return its * index in the heap array */ #define igraph_i_fastgreedy_community_list_find_in_heap(list, idx) (list)->heapindex[idx] /* Dumps the heap - for debugging purposes */ /* static void igraph_i_fastgreedy_community_list_dump_heap( igraph_i_fastgreedy_community_list* list) { long int i; debug("Heap:\n"); for (i = 0; i < list->no_of_communities; i++) { debug("(%ld, %p, %p)", i, list->heap[i], list->heap[i]->maxdq); if (list->heap[i]->maxdq) { debug(" (%ld, %ld, %.7f)", list->heap[i]->maxdq->first, list->heap[i]->maxdq->second, *list->heap[i]->maxdq->dq); } debug("\n"); } debug("Heap index:\n"); for (i = 0; i < list->no_of_communities; i++) { debug("%ld ", (long)list->heapindex[i]); } debug("\nEND\n"); } */ /* Checks if the community heap satisfies the heap property. * Only useful for debugging. */ /* static void igraph_i_fastgreedy_community_list_check_heap( igraph_i_fastgreedy_community_list* list) { long int i; for (i = 0; i < list->no_of_communities / 2; i++) { if ((2 * i + 1 < list->no_of_communities && *list->heap[i]->maxdq->dq < *list->heap[2 * i + 1]->maxdq->dq) || (2 * i + 2 < list->no_of_communities && *list->heap[i]->maxdq->dq < *list->heap[2 * i + 2]->maxdq->dq)) { IGRAPH_WARNING("Heap property violated"); debug("Position: %ld, %ld and %ld\n", i, 2 * i + 1, 2 * i + 2); igraph_i_fastgreedy_community_list_dump_heap(list); } } } */ /* Removes a given element from the heap */ static void igraph_i_fastgreedy_community_list_remove( igraph_i_fastgreedy_community_list* list, long int idx) { igraph_real_t old; long int commidx; /* First adjust the index */ commidx = list->heap[list->no_of_communities - 1]->maxdq->first; list->heapindex[commidx] = (igraph_integer_t) idx; commidx = list->heap[idx]->maxdq->first; list->heapindex[commidx] = -1; /* Now remove the element */ old = *list->heap[idx]->maxdq->dq; list->heap[idx] = list->heap[list->no_of_communities - 1]; list->no_of_communities--; /* Recover heap property */ if (old > *list->heap[idx]->maxdq->dq) { igraph_i_fastgreedy_community_list_sift_down(list, idx); } else { igraph_i_fastgreedy_community_list_sift_up(list, idx); } } /* Removes a given element from the heap when there are no more neighbors * for it (comm->maxdq is NULL) */ static void igraph_i_fastgreedy_community_list_remove2( igraph_i_fastgreedy_community_list* list, long int idx, long int comm) { long int i; if (idx == list->no_of_communities - 1) { /* We removed the rightmost element on the bottom level, no problem, * there's nothing to be done */ list->heapindex[comm] = -1; list->no_of_communities--; return; } /* First adjust the index */ i = list->heap[list->no_of_communities - 1]->maxdq->first; list->heapindex[i] = (igraph_integer_t) idx; list->heapindex[comm] = -1; /* Now remove the element */ list->heap[idx] = list->heap[list->no_of_communities - 1]; list->no_of_communities--; /* Recover heap property */ for (i = list->no_of_communities / 2 - 1; i >= 0; i--) { igraph_i_fastgreedy_community_list_sift_down(list, i); } } /* Removes the pair belonging to community k from the neighborhood list * of community c (that is, clist[c]) and recalculates maxdq */ static void igraph_i_fastgreedy_community_remove_nei( igraph_i_fastgreedy_community_list* list, long int c, long int k) { long int i, n; igraph_bool_t rescan = 0; igraph_i_fastgreedy_commpair *p; igraph_i_fastgreedy_community *comm; igraph_real_t olddq; comm = &list->e[c]; n = igraph_vector_ptr_size(&comm->neis); for (i = 0; i < n; i++) { p = (igraph_i_fastgreedy_commpair*)VECTOR(comm->neis)[i]; if (p->second == k) { /* Check current maxdq */ if (comm->maxdq == p) { rescan = 1; } break; } } if (i < n) { olddq = *comm->maxdq->dq; igraph_vector_ptr_remove(&comm->neis, i); if (rescan) { igraph_i_fastgreedy_community_rescan_max(comm); i = igraph_i_fastgreedy_community_list_find_in_heap(list, c); if (comm->maxdq) { if (*comm->maxdq->dq > olddq) { igraph_i_fastgreedy_community_list_sift_up(list, i); } else { igraph_i_fastgreedy_community_list_sift_down(list, i); } } else { /* no more neighbors for this community. we should remove this * community from the heap and restore the heap property */ debug("REMOVING (NO MORE NEIS): %ld\n", i); igraph_i_fastgreedy_community_list_remove2(list, i, c); } } } } /* Auxiliary function to sort a community pair list with respect to the * `second` field */ static int igraph_i_fastgreedy_commpair_cmp(const void* p1, const void* p2) { igraph_i_fastgreedy_commpair *cp1, *cp2; cp1 = *(igraph_i_fastgreedy_commpair**)p1; cp2 = *(igraph_i_fastgreedy_commpair**)p2; return (int) (cp1->second - cp2->second); } /* Sorts the neighbor list of the community with the given index, optionally * optimizing the process if we know that the list is nearly sorted and only * a given pair is in the wrong place. */ static void igraph_i_fastgreedy_community_sort_neighbors_of( igraph_i_fastgreedy_community_list* list, long int index, igraph_i_fastgreedy_commpair* changed_pair) { igraph_vector_ptr_t* vec; long int i, n; igraph_bool_t can_skip_sort = 0; igraph_i_fastgreedy_commpair *other_pair; vec = &list->e[index].neis; if (changed_pair != 0) { /* Optimized sorting */ /* First we look for changed_pair in vec */ n = igraph_vector_ptr_size(vec); for (i = 0; i < n; i++) { if (VECTOR(*vec)[i] == changed_pair) { break; } } /* Did we find it? We should have -- otherwise it's a bug */ if (i >= n) { IGRAPH_WARNING("changed_pair not found in neighbor vector while re-sorting " "the neighbors of a community; this is probably a bug. Falling back to " "full sort instead." ); } else { /* Okay, the pair that changed is at index i. We need to figure out where * its new place should be. We can simply try moving the item all the way * to the left as long as the comparison function tells so (since the * rest of the vector is sorted), and then move all the way to the right * as long as the comparison function tells so, and we will be okay. */ /* Shifting to the left */ while (i > 0) { other_pair = VECTOR(*vec)[i - 1]; if (other_pair->second > changed_pair->second) { VECTOR(*vec)[i] = other_pair; i--; } else { break; } } VECTOR(*vec)[i] = changed_pair; /* Shifting to the right */ while (i < n - 1) { other_pair = VECTOR(*vec)[i + 1]; if (other_pair->second < changed_pair->second) { VECTOR(*vec)[i] = other_pair; i++; } else { break; } } VECTOR(*vec)[i] = changed_pair; /* Mark that we don't need a full sort */ can_skip_sort = 1; } } if (!can_skip_sort) { /* Fallback to full sorting */ igraph_vector_ptr_sort(vec, igraph_i_fastgreedy_commpair_cmp); } } /* Updates the dq value of community pair p in the community with index p->first * of the community list clist to newdq and restores the heap property * in community c if necessary. Returns 1 if the maximum in the row had * to be updated, zero otherwise */ static int igraph_i_fastgreedy_community_update_dq( igraph_i_fastgreedy_community_list* list, igraph_i_fastgreedy_commpair* p, igraph_real_t newdq) { long int i, j, to, from; igraph_real_t olddq; igraph_i_fastgreedy_community *comm_to, *comm_from; to = p->first; from = p->second; comm_to = &list->e[to]; comm_from = &list->e[from]; if (comm_to->maxdq == p && newdq >= *p->dq) { /* If we are adjusting the current maximum and it is increased, we don't * have to re-scan for the new maximum */ *p->dq = newdq; /* The maximum was increased, so perform a sift-up in the heap */ i = igraph_i_fastgreedy_community_list_find_in_heap(list, to); igraph_i_fastgreedy_community_list_sift_up(list, i); /* Let's check the opposite side. If the pair was not the maximal in * the opposite side (the other community list)... */ if (comm_from->maxdq != p->opposite) { if (*comm_from->maxdq->dq < newdq) { /* ...and it will become the maximal, we need to adjust and sift up */ comm_from->maxdq = p->opposite; j = igraph_i_fastgreedy_community_list_find_in_heap(list, from); igraph_i_fastgreedy_community_list_sift_up(list, j); } else { /* The pair was not the maximal in the opposite side and it will * NOT become the maximal, there's nothing to do there */ } } else { /* The pair was maximal in the opposite side, so we need to sift it up * with the new value */ j = igraph_i_fastgreedy_community_list_find_in_heap(list, from); igraph_i_fastgreedy_community_list_sift_up(list, j); } return 1; } else if (comm_to->maxdq != p && (newdq <= *comm_to->maxdq->dq)) { /* If we are modifying an item which is not the current maximum, and the * new value is less than the current maximum, we don't * have to re-scan for the new maximum */ olddq = *p->dq; *p->dq = newdq; /* However, if the item was the maximum on the opposite side, we'd better * re-scan it */ if (comm_from->maxdq == p->opposite) { if (olddq > newdq) { /* Decreased the maximum on the other side, we have to re-scan for the * new maximum */ igraph_i_fastgreedy_community_rescan_max(comm_from); j = igraph_i_fastgreedy_community_list_find_in_heap(list, from); igraph_i_fastgreedy_community_list_sift_down(list, j); } else { /* Increased the maximum on the other side, we don't have to re-scan * but we might have to sift up */ j = igraph_i_fastgreedy_community_list_find_in_heap(list, from); igraph_i_fastgreedy_community_list_sift_up(list, j); } } return 0; } else { /* We got here in two cases: (1) the pair we are modifying right now is the maximum in the given community and we are decreasing it (2) the pair we are modifying right now is NOT the maximum in the given community, but we increase it so much that it will become the new maximum */ *p->dq = newdq; if (comm_to->maxdq != p) { /* case (2) */ comm_to->maxdq = p; /* The maximum was increased, so perform a sift-up in the heap */ i = igraph_i_fastgreedy_community_list_find_in_heap(list, to); igraph_i_fastgreedy_community_list_sift_up(list, i); /* Opposite side. Chances are that the new value became the maximum * in the opposite side, but check it first */ if (comm_from->maxdq != p->opposite) { if (*comm_from->maxdq->dq < newdq) { /* Yes, it will become the new maximum */ comm_from->maxdq = p->opposite; j = igraph_i_fastgreedy_community_list_find_in_heap(list, from); igraph_i_fastgreedy_community_list_sift_up(list, j); } else { /* No, nothing to do there */ } } else { /* Already increased the maximum on the opposite side, so sift it up */ j = igraph_i_fastgreedy_community_list_find_in_heap(list, from); igraph_i_fastgreedy_community_list_sift_up(list, j); } } else { /* case (1) */ /* This is the worst, we have to re-scan the whole community to find * the new maximum and update the global maximum as well if necessary */ igraph_i_fastgreedy_community_rescan_max(comm_to); /* The maximum was decreased, so perform a sift-down in the heap */ i = igraph_i_fastgreedy_community_list_find_in_heap(list, to); igraph_i_fastgreedy_community_list_sift_down(list, i); if (comm_from->maxdq != p->opposite) { /* The one that we decreased on the opposite side is not the * maximal one. Nothing to do. */ } else { /* We decreased the maximal on the opposite side as well. Re-scan * and sift down */ igraph_i_fastgreedy_community_rescan_max(comm_from); j = igraph_i_fastgreedy_community_list_find_in_heap(list, from); igraph_i_fastgreedy_community_list_sift_down(list, j); } } } return 1; } /** * \function igraph_community_fastgreedy * \brief Finding community structure by greedy optimization of modularity. * * This function implements the fast greedy modularity optimization * algorithm for finding community structure, see * A Clauset, MEJ Newman, C Moore: Finding community structure in very * large networks, http://www.arxiv.org/abs/cond-mat/0408187 for the * details. * * * Some improvements proposed in K Wakita, T Tsurumi: Finding community * structure in mega-scale social networks, * http://www.arxiv.org/abs/cs.CY/0702048v1 have also been implemented. * * \param graph The input graph. It must be a graph without multiple edges. * This is checked and an error message is given for graphs with multiple * edges. * \param weights Potentially a numeric vector containing edge * weights. Supply a null pointer here for unweighted graphs. The * weights are expected to be non-negative. * \param merges Pointer to an initialized matrix or \c NULL, the result of the * computation is stored here. The matrix has two columns and each * merge corresponds to one merge, the ids of the two merged * components are stored. The component ids are numbered from zero and * the first \c n components are the individual vertices, \c n is * the number of vertices in the graph. Component \c n is created * in the first merge, component n+1 in the second merge, etc. * The matrix will be resized as needed. If this argument is \c NULL * then it is ignored completely. * \param modularity Pointer to an initialized vector or \c NULL pointer, * in the former case the modularity scores along the stages of the * computation are recorded here. The vector will be resized as * needed. * \param membership Pointer to a vector. If not a null pointer, then * the membership vector corresponding to the best split (in terms * of modularity) is stored here. * \return Error code. * * \sa \ref igraph_community_walktrap(), \ref * igraph_community_edge_betweenness() for other community detection * algorithms, \ref igraph_community_to_membership() to convert the * dendrogram to a membership vector. * * Time complexity: O(|E||V|log|V|) in the worst case, * O(|E|+|V|log^2|V|) typically, |V| is the number of vertices, |E| is * the number of edges. * * \example examples/simple/igraph_community_fastgreedy.c */ int igraph_community_fastgreedy(const igraph_t *graph, const igraph_vector_t *weights, igraph_matrix_t *merges, igraph_vector_t *modularity, igraph_vector_t *membership) { long int no_of_edges, no_of_nodes, no_of_joins, total_joins; long int i, j, k, n, m, from, to, dummy, best_no_of_joins; igraph_integer_t ffrom, fto; igraph_eit_t edgeit; igraph_i_fastgreedy_commpair *pairs, *p1, *p2; igraph_i_fastgreedy_community_list communities; igraph_vector_t a; igraph_real_t q, *dq, bestq, weight_sum, loop_weight_sum; igraph_bool_t has_multiple; igraph_matrix_t merges_local; /*long int join_order[] = { 16,5, 5,6, 6,0, 4,0, 10,0, 26,29, 29,33, 23,33, 27,33, 25,24, 24,31, 12,3, 21,1, 30,8, 8,32, 9,2, 17,1, 11,0, 7,3, 3,2, 13,2, 1,2, 28,31, 31,33, 22,32, 18,32, 20,32, 32,33, 15,33, 14,33, 0,19, 19,2, -1,-1 };*/ /*long int join_order[] = { 43,42, 42,41, 44,41, 41,36, 35,36, 37,36, 36,29, 38,29, 34,29, 39,29, 33,29, 40,29, 32,29, 14,29, 30,29, 31,29, 6,18, 18,4, 23,4, 21,4, 19,4, 27,4, 20,4, 22,4, 26,4, 25,4, 24,4, 17,4, 0,13, 13,2, 1,2, 11,2, 8,2, 5,2, 3,2, 10,2, 9,2, 7,2, 2,28, 28,15, 12,15, 29,16, 4,15, -1,-1 };*/ no_of_nodes = igraph_vcount(graph); no_of_edges = igraph_ecount(graph); if (igraph_is_directed(graph)) { IGRAPH_ERROR("Fast greedy community detection works on undirected graphs only.", IGRAPH_UNIMPLEMENTED); } total_joins = no_of_nodes > 0 ? no_of_nodes - 1 : 0; if (weights != 0) { if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Length of weight vector must agree with number of edges.", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t minweight = igraph_vector_min(weights); if (minweight < 0) { IGRAPH_ERROR("Weights must not be negative.", IGRAPH_EINVAL); } if (igraph_is_nan(minweight)) { IGRAPH_ERROR("Weights must not be NaN.", IGRAPH_EINVAL); } } weight_sum = igraph_vector_sum(weights); } else { weight_sum = no_of_edges; } IGRAPH_CHECK(igraph_has_multiple(graph, &has_multiple)); if (has_multiple) { IGRAPH_ERROR("Fast greedy community detection works only on graphs without multi-edges.", IGRAPH_EINVAL); } if (membership != 0 && merges == 0) { /* We need the merge matrix because the user wants the membership * vector, so we allocate one on our own */ IGRAPH_CHECK(igraph_matrix_init(&merges_local, total_joins, 2)); IGRAPH_FINALLY(igraph_matrix_destroy, &merges_local); merges = &merges_local; } if (merges != 0) { IGRAPH_CHECK(igraph_matrix_resize(merges, total_joins, 2)); igraph_matrix_null(merges); } if (modularity != 0) { IGRAPH_CHECK(igraph_vector_resize(modularity, total_joins + 1)); } /* Create degree vector */ IGRAPH_VECTOR_INIT_FINALLY(&a, no_of_nodes); if (weights) { debug("Calculating weighted degrees\n"); for (i = 0; i < no_of_edges; i++) { VECTOR(a)[(long int)IGRAPH_FROM(graph, i)] += VECTOR(*weights)[i]; VECTOR(a)[(long int)IGRAPH_TO(graph, i)] += VECTOR(*weights)[i]; } } else { debug("Calculating degrees\n"); IGRAPH_CHECK(igraph_degree(graph, &a, igraph_vss_all(), IGRAPH_ALL, 1)); } /* Create list of communities */ debug("Creating community list\n"); communities.n = no_of_nodes; communities.no_of_communities = no_of_nodes; communities.e = (igraph_i_fastgreedy_community*)calloc((size_t) no_of_nodes, sizeof(igraph_i_fastgreedy_community)); if (communities.e == 0) { IGRAPH_ERROR("Insufficient memory for fast greedy community detection.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, communities.e); communities.heap = (igraph_i_fastgreedy_community**)calloc((size_t) no_of_nodes, sizeof(igraph_i_fastgreedy_community*)); if (communities.heap == 0) { IGRAPH_ERROR("Insufficient memory for fast greedy community detection.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, communities.heap); communities.heapindex = (igraph_integer_t*)calloc((size_t)no_of_nodes, sizeof(igraph_integer_t)); if (communities.heapindex == 0) { IGRAPH_ERROR("Insufficient memory for fast greedy community detection.", IGRAPH_ENOMEM); } IGRAPH_FINALLY_CLEAN(2); IGRAPH_FINALLY(igraph_i_fastgreedy_community_list_destroy, &communities); for (i = 0; i < no_of_nodes; i++) { igraph_vector_ptr_init(&communities.e[i].neis, 0); communities.e[i].id = (igraph_integer_t) i; communities.e[i].size = 1; } /* Create list of community pairs from edges */ debug("Allocating dq vector\n"); dq = (igraph_real_t*)calloc((size_t) no_of_edges, sizeof(igraph_real_t)); if (dq == 0) { IGRAPH_ERROR("Insufficient memory for fast greedy community detection.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, dq); debug("Creating community pair list\n"); IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(0), &edgeit)); IGRAPH_FINALLY(igraph_eit_destroy, &edgeit); pairs = (igraph_i_fastgreedy_commpair*)calloc(2 * (size_t) no_of_edges, sizeof(igraph_i_fastgreedy_commpair)); if (pairs == 0) { IGRAPH_ERROR("Insufficient memory for fast greedy community detection.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, pairs); loop_weight_sum = 0; for (i = 0, j = 0; !IGRAPH_EIT_END(edgeit); i += 2, j++, IGRAPH_EIT_NEXT(edgeit)) { long int eidx = IGRAPH_EIT_GET(edgeit); igraph_edge(graph, (igraph_integer_t) eidx, &ffrom, &fto); /* Create the pairs themselves */ from = (long int)ffrom; to = (long int)fto; if (from == to) { loop_weight_sum += weights ? 2 * VECTOR(*weights)[eidx] : 2; continue; } if (from > to) { dummy = from; from = to; to = dummy; } if (weights) { dq[j] = 2 * (VECTOR(*weights)[eidx] / (weight_sum * 2.0) - VECTOR(a)[from] * VECTOR(a)[to] / (4.0 * weight_sum * weight_sum)); } else { dq[j] = 2 * (1.0 / (no_of_edges * 2.0) - VECTOR(a)[from] * VECTOR(a)[to] / (4.0 * no_of_edges * no_of_edges)); } pairs[i].first = from; pairs[i].second = to; pairs[i].dq = &dq[j]; pairs[i].opposite = &pairs[i + 1]; pairs[i + 1].first = to; pairs[i + 1].second = from; pairs[i + 1].dq = pairs[i].dq; pairs[i + 1].opposite = &pairs[i]; /* Link the pair to the communities */ igraph_vector_ptr_push_back(&communities.e[from].neis, &pairs[i]); igraph_vector_ptr_push_back(&communities.e[to].neis, &pairs[i + 1]); /* Update maximums */ if (communities.e[from].maxdq == 0 || *communities.e[from].maxdq->dq < *pairs[i].dq) { communities.e[from].maxdq = &pairs[i]; } if (communities.e[to].maxdq == 0 || *communities.e[to].maxdq->dq < *pairs[i + 1].dq) { communities.e[to].maxdq = &pairs[i + 1]; } } igraph_eit_destroy(&edgeit); IGRAPH_FINALLY_CLEAN(1); /* Sorting community neighbor lists by community IDs */ debug("Sorting community neighbor lists\n"); for (i = 0, j = 0; i < no_of_nodes; i++) { igraph_i_fastgreedy_community_sort_neighbors_of(&communities, i, 0); /* Isolated vertices and vertices with loop edges only won't be stored in * the heap (to avoid maxdq == 0) */ if (communities.e[i].maxdq != 0) { communities.heap[j] = &communities.e[i]; communities.heapindex[i] = (igraph_integer_t) j; j++; } else { communities.heapindex[i] = -1; } } communities.no_of_communities = j; /* Calculate proper vector a (see paper) and initial modularity */ q = 2.0 * (weights ? weight_sum : no_of_edges); if (q == 0) { /* All the weights are zero */ } else { igraph_vector_scale(&a, 1.0 / q); q = loop_weight_sum / q; for (i = 0; i < no_of_nodes; i++) { q -= VECTOR(a)[i] * VECTOR(a)[i]; } } /* Initialize "best modularity" value and best merge counter */ bestq = q; best_no_of_joins = 0; /* Initializing community heap */ debug("Initializing community heap\n"); igraph_i_fastgreedy_community_list_build_heap(&communities); debug("Initial modularity: %.4f\n", q); /* Let's rock ;) */ no_of_joins = 0; while (no_of_joins < total_joins) { IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_PROGRESS("Fast greedy community detection", no_of_joins * 100.0 / total_joins, 0); /* Store the modularity */ if (modularity) { VECTOR(*modularity)[no_of_joins] = q; } /* Update best modularity if needed */ if (q >= bestq) { bestq = q; best_no_of_joins = no_of_joins; } /* Some debug info if needed */ /* igraph_i_fastgreedy_community_list_check_heap(&communities); */ #ifdef IGRAPH_FASTCOMM_DEBUG debug("===========================================\n"); for (i = 0; i < communities.n; i++) { if (communities.e[i].maxdq == 0) { debug("Community #%ld: PASSIVE\n", i); continue; } debug("Community #%ld\n ", i); for (j = 0; j < igraph_vector_ptr_size(&communities.e[i].neis); j++) { p1 = (igraph_i_fastgreedy_commpair*)VECTOR(communities.e[i].neis)[j]; debug(" (%ld,%ld,%.4f)", p1->first, p1->second, *p1->dq); } p1 = communities.e[i].maxdq; debug("\n Maxdq: (%ld,%ld,%.4f)\n", p1->first, p1->second, *p1->dq); } debug("Global maxdq is: (%ld,%ld,%.4f)\n", communities.heap[0]->maxdq->first, communities.heap[0]->maxdq->second, *communities.heap[0]->maxdq->dq); for (i = 0; i < communities.no_of_communities; i++) { debug("(%ld,%ld,%.4f) ", communities.heap[i]->maxdq->first, communities.heap[i]->maxdq->second, *communities.heap[0]->maxdq->dq); } debug("\n"); #endif if (communities.heap[0] == 0) { break; /* no more communities */ } if (communities.heap[0]->maxdq == 0) { break; /* there are only isolated comms */ } to = communities.heap[0]->maxdq->second; from = communities.heap[0]->maxdq->first; debug("Q[%ld] = %.7f\tdQ = %.7f\t |H| = %ld\n", no_of_joins, q, *communities.heap[0]->maxdq->dq, no_of_nodes - no_of_joins - 1); /* IGRAPH_FASTCOMM_DEBUG */ /* from=join_order[no_of_joins*2]; to=join_order[no_of_joins*2+1]; if (to == -1) break; for (i=0; isecond == from) communities.maxdq = p1; } */ n = igraph_vector_ptr_size(&communities.e[to].neis); m = igraph_vector_ptr_size(&communities.e[from].neis); /*if (n>m) { dummy=n; n=m; m=dummy; dummy=to; to=from; from=dummy; }*/ debug(" joining: %ld <- %ld\n", to, from); q += *communities.heap[0]->maxdq->dq; /* Merge the second community into the first */ i = j = 0; while (i < n && j < m) { p1 = (igraph_i_fastgreedy_commpair*)VECTOR(communities.e[to].neis)[i]; p2 = (igraph_i_fastgreedy_commpair*)VECTOR(communities.e[from].neis)[j]; debug("Pairs: %ld-%ld and %ld-%ld\n", p1->first, p1->second, p2->first, p2->second); if (p1->second < p2->second) { /* Considering p1 from now on */ debug(" Considering: %ld-%ld\n", p1->first, p1->second); if (p1->second == from) { debug(" WILL REMOVE: %ld-%ld\n", to, from); } else { /* chain, case 1 */ debug(" CHAIN(1): %ld-%ld %ld, now=%.7f, adding=%.7f, newdq(%ld,%ld)=%.7f\n", to, p1->second, from, *p1->dq, -2 * VECTOR(a)[from]*VECTOR(a)[p1->second], p1->first, p1->second, *p1->dq - 2 * VECTOR(a)[from]*VECTOR(a)[p1->second]); igraph_i_fastgreedy_community_update_dq(&communities, p1, *p1->dq - 2 * VECTOR(a)[from]*VECTOR(a)[p1->second]); } i++; } else if (p1->second == p2->second) { /* p1->first, p1->second and p2->first form a triangle */ debug(" Considering: %ld-%ld and %ld-%ld\n", p1->first, p1->second, p2->first, p2->second); /* Update dq value */ debug(" TRIANGLE: %ld-%ld-%ld, now=%.7f, adding=%.7f, newdq(%ld,%ld)=%.7f\n", to, p1->second, from, *p1->dq, *p2->dq, p1->first, p1->second, *p1->dq + *p2->dq); igraph_i_fastgreedy_community_update_dq(&communities, p1, *p1->dq + *p2->dq); igraph_i_fastgreedy_community_remove_nei(&communities, p1->second, from); i++; j++; } else { debug(" Considering: %ld-%ld\n", p2->first, p2->second); if (p2->second == to) { debug(" WILL REMOVE: %ld-%ld\n", p2->second, p2->first); } else { /* chain, case 2 */ debug(" CHAIN(2): %ld %ld-%ld, newdq(%ld,%ld)=%.7f\n", to, p2->second, from, to, p2->second, *p2->dq - 2 * VECTOR(a)[to]*VECTOR(a)[p2->second]); p2->opposite->second = to; /* p2->opposite->second changed, so it means that * communities.e[p2->second].neis (which contains p2->opposite) is * not sorted any more. We have to find the index of p2->opposite in * this vector and move it to the correct place. Moving should be an * O(n) operation; re-sorting would be O(n*logn) or even worse, * depending on the pivoting strategy used by qsort() since the * vector is nearly sorted */ igraph_i_fastgreedy_community_sort_neighbors_of( &communities, p2->second, p2->opposite); /* link from.neis[j] to the current place in to.neis if * from.neis[j] != to */ p2->first = to; IGRAPH_CHECK(igraph_vector_ptr_insert(&communities.e[to].neis, i, p2)); n++; i++; if (*p2->dq > *communities.e[to].maxdq->dq) { communities.e[to].maxdq = p2; k = igraph_i_fastgreedy_community_list_find_in_heap(&communities, to); igraph_i_fastgreedy_community_list_sift_up(&communities, k); } igraph_i_fastgreedy_community_update_dq(&communities, p2, *p2->dq - 2 * VECTOR(a)[to]*VECTOR(a)[p2->second]); } j++; } } p1 = 0; while (i < n) { p1 = (igraph_i_fastgreedy_commpair*)VECTOR(communities.e[to].neis)[i]; if (p1->second == from) { debug(" WILL REMOVE: %ld-%ld\n", p1->first, from); } else { /* chain, case 1 */ debug(" CHAIN(1): %ld-%ld %ld, now=%.7f, adding=%.7f, newdq(%ld,%ld)=%.7f\n", to, p1->second, from, *p1->dq, -2 * VECTOR(a)[from]*VECTOR(a)[p1->second], p1->first, p1->second, *p1->dq - 2 * VECTOR(a)[from]*VECTOR(a)[p1->second]); igraph_i_fastgreedy_community_update_dq(&communities, p1, *p1->dq - 2 * VECTOR(a)[from]*VECTOR(a)[p1->second]); } i++; } while (j < m) { p2 = (igraph_i_fastgreedy_commpair*)VECTOR(communities.e[from].neis)[j]; if (to == p2->second) { j++; continue; } /* chain, case 2 */ debug(" CHAIN(2): %ld %ld-%ld, newdq(%ld,%ld)=%.7f\n", to, p2->second, from, p1 ? p1->first : -1, p2->second, *p2->dq - 2 * VECTOR(a)[to]*VECTOR(a)[p2->second]); p2->opposite->second = to; /* need to re-sort community nei list `p2->second` */ igraph_i_fastgreedy_community_sort_neighbors_of(&communities, p2->second, p2->opposite); /* link from.neis[j] to the current place in to.neis if * from.neis[j] != to */ p2->first = to; IGRAPH_CHECK(igraph_vector_ptr_push_back(&communities.e[to].neis, p2)); if (*p2->dq > *communities.e[to].maxdq->dq) { communities.e[to].maxdq = p2; k = igraph_i_fastgreedy_community_list_find_in_heap(&communities, to); igraph_i_fastgreedy_community_list_sift_up(&communities, k); } igraph_i_fastgreedy_community_update_dq(&communities, p2, *p2->dq - 2 * VECTOR(a)[to]*VECTOR(a)[p2->second]); j++; } /* Now, remove community `from` from the neighbors of community `to` */ if (communities.no_of_communities > 2) { debug(" REMOVING: %ld-%ld\n", to, from); igraph_i_fastgreedy_community_remove_nei(&communities, to, from); i = igraph_i_fastgreedy_community_list_find_in_heap(&communities, from); igraph_i_fastgreedy_community_list_remove(&communities, i); } communities.e[from].maxdq = 0; /* Update community sizes */ communities.e[to].size += communities.e[from].size; communities.e[from].size = 0; /* record what has been merged */ /* igraph_vector_ptr_clear is not enough here as it won't free * the memory consumed by communities.e[from].neis. Thanks * to Tom Gregorovic for pointing that out. */ igraph_vector_ptr_destroy(&communities.e[from].neis); if (merges) { MATRIX(*merges, no_of_joins, 0) = communities.e[to].id; MATRIX(*merges, no_of_joins, 1) = communities.e[from].id; communities.e[to].id = (igraph_integer_t) (no_of_nodes + no_of_joins); } /* Update vector a */ VECTOR(a)[to] += VECTOR(a)[from]; VECTOR(a)[from] = 0.0; no_of_joins++; } /* TODO: continue merging when some isolated communities remained. Always * joining the communities with the least number of nodes results in the * smallest decrease in modularity every step. Now we're simply deleting * the excess rows from the merge matrix */ if (no_of_joins < total_joins) { long int *ivec; long int merges_nrow = igraph_matrix_nrow(merges); ivec = IGRAPH_CALLOC(merges_nrow, long int); if (ivec == 0) { IGRAPH_ERROR("Insufficient memory for fast greedy community detection.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, ivec); for (i = 0; i < no_of_joins; i++) { ivec[i] = i + 1; } igraph_matrix_permdelete_rows(merges, ivec, total_joins - no_of_joins); IGRAPH_FREE(ivec); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_PROGRESS("Fast greedy community detection", 100.0, 0); if (modularity) { VECTOR(*modularity)[no_of_joins] = q; igraph_vector_resize(modularity, no_of_joins + 1); } debug("Freeing memory\n"); IGRAPH_FREE(pairs); IGRAPH_FREE(dq); igraph_i_fastgreedy_community_list_destroy(&communities); igraph_vector_destroy(&a); IGRAPH_FINALLY_CLEAN(4); if (membership) { IGRAPH_CHECK(igraph_community_to_membership(merges, (igraph_integer_t) no_of_nodes, /*steps=*/ (igraph_integer_t) best_no_of_joins, membership, /*csize=*/ 0)); } if (merges == &merges_local) { igraph_matrix_destroy(&merges_local); IGRAPH_FINALLY_CLEAN(1); } return 0; } #ifdef IGRAPH_FASTCOMM_DEBUG #undef IGRAPH_FASTCOMM_DEBUG #endif leidenbase/src/core/community/label_propagation.c0000644000176200001440000004413214447675374021767 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_adjlist.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_random.h" /** * \ingroup communities * \function igraph_community_label_propagation * \brief Community detection based on label propagation. * * This function implements the label propagation-based community detection * algorithm described by Raghavan, Albert and Kumara. This version extends * the original method by the ability to take edge weights into consideration * and also by allowing some labels to be fixed. * * * Weights are taken into account as follows: when the new label of node * \c i is determined, the algorithm iterates over all edges incident on * node \c i and calculate the total weight of edges leading to other * nodes with label 0, 1, 2, ..., \c k - 1 (where \c k is the number of possible * labels). The new label of node \c i will then be the label whose edges * (among the ones incident on node \c i) have the highest total weight. * * * Reference: * * * Raghavan, U.N. and Albert, R. and Kumara, S.: * Near linear time algorithm to detect community structures in large-scale networks. * Phys Rev E 76, 036106. (2007). * https://doi.org/10.1103/PhysRevE.76.036106 * * \param graph The input graph, should be undirected to make sense. * \param membership The membership vector, the result is returned here. * For each vertex it gives the ID of its community (label). * \param weights The weight vector, it should contain a positive * weight for all the edges. * \param initial The initial state. If \c NULL, every vertex will have * a different label at the beginning. Otherwise it must be a vector * with an entry for each vertex. Non-negative values denote different * labels, negative entries denote vertices without labels. Unlabeled * vertices which are not reachable from any labeled ones will remain * unlabeled at the end of the label propagation process, and will be * labeled in an additional step to avoid returning negative values in * \p membership. In undirected graphs, this happens when entire connected * components are unlabeled. Then, each unlabeled component will receive * its own separate label. In directed graphs, the outcome of the * additional labeling should be considered undefined and may change * in the future; please do not rely on it. * \param fixed Boolean vector denoting which labels are fixed. Of course * this makes sense only if you provided an initial state, otherwise * this element will be ignored. Also note that vertices without labels * cannot be fixed. If they are, this vector will be modified to * make it consistent with \p initial. * \param modularity If not a null pointer, then it must be a pointer * to a real number. The modularity score of the detected community * structure is stored here. * \return Error code. * * Time complexity: O(m+n) * * \example examples/simple/igraph_community_label_propagation.c */ int igraph_community_label_propagation(const igraph_t *graph, igraph_vector_t *membership, const igraph_vector_t *weights, const igraph_vector_t *initial, const igraph_vector_bool_t *fixed, igraph_real_t *modularity) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int no_of_not_fixed_nodes = no_of_nodes; long int i, j, k; igraph_adjlist_t al; igraph_inclist_t il; igraph_bool_t running, control_iteration; igraph_bool_t unlabelled_left; igraph_vector_t label_counters, dominant_labels, nonzero_labels, node_order; /* We make a copy of 'fixed' as a pointer into 'fixed_copy' after casting * away the constness, and promise ourselves that we will make a proper * copy of 'fixed' into 'fixed_copy' as soon as we start mutating it */ igraph_vector_bool_t* fixed_copy = (igraph_vector_bool_t*) fixed; /* The implementation uses a trick to avoid negative array indexing: * elements of the membership vector are increased by 1 at the start * of the algorithm; this to allow us to denote unlabeled vertices * (if any) by zeroes. The membership vector is shifted back in the end */ /* Do some initial checks */ if (fixed && igraph_vector_bool_size(fixed) != no_of_nodes) { IGRAPH_ERROR("Fixed labeling vector length must agree with number of nodes.", IGRAPH_EINVAL); } if (weights) { if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Length of weight vector must agree with number of edges.", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t minweight = igraph_vector_min(weights); if (minweight < 0) { IGRAPH_ERROR("Weights must not be negative.", IGRAPH_EINVAL); } if (igraph_is_nan(minweight)) { IGRAPH_ERROR("Weights must not be NaN.", IGRAPH_EINVAL); } } } if (fixed && !initial) { IGRAPH_WARNING("Ignoring fixed vertices as no initial labeling given."); } IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); if (initial) { if (igraph_vector_size(initial) != no_of_nodes) { IGRAPH_ERROR("Initial labeling vector length must agree with number of nodes.", IGRAPH_EINVAL); } /* Check if the labels used are valid, initialize membership vector */ for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*initial)[i] < 0) { VECTOR(*membership)[i] = 0; } else { VECTOR(*membership)[i] = floor(VECTOR(*initial)[i]) + 1; } } if (fixed) { for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*fixed)[i]) { if (VECTOR(*membership)[i] == 0) { IGRAPH_WARNING("Fixed nodes cannot be unlabeled, ignoring them."); /* We cannot modify 'fixed' because it is const, so we make a copy and * modify 'fixed_copy' instead */ if (fixed_copy == fixed) { fixed_copy = igraph_Calloc(1, igraph_vector_bool_t); if (fixed_copy == 0) { IGRAPH_ERROR("Failed to copy 'fixed' vector.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, fixed_copy); IGRAPH_CHECK(igraph_vector_bool_copy(fixed_copy, fixed)); IGRAPH_FINALLY(igraph_vector_bool_destroy, fixed_copy); } VECTOR(*fixed_copy)[i] = 0; } else { no_of_not_fixed_nodes--; } } } } i = (long int) igraph_vector_max(membership); if (i > no_of_nodes) { IGRAPH_ERROR("Elements of the initial labeling vector must be between 0 and |V|-1.", IGRAPH_EINVAL); } } else { for (i = 0; i < no_of_nodes; i++) { VECTOR(*membership)[i] = i + 1; } } /* From this point onwards we use 'fixed_copy' instead of 'fixed' */ /* Create an adjacency/incidence list representation for efficiency. * For the unweighted case, the adjacency list is enough. For the * weighted case, we need the incidence list */ if (weights) { IGRAPH_CHECK(igraph_inclist_init(graph, &il, IGRAPH_IN, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &il); } else { IGRAPH_CHECK(igraph_adjlist_init(graph, &al, IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &al); } /* Create storage space for counting distinct labels and dominant ones */ IGRAPH_VECTOR_INIT_FINALLY(&label_counters, no_of_nodes + 1); IGRAPH_VECTOR_INIT_FINALLY(&dominant_labels, 0); IGRAPH_VECTOR_INIT_FINALLY(&nonzero_labels, 0); IGRAPH_CHECK(igraph_vector_reserve(&dominant_labels, 2)); /* Initialize node ordering vector with only the not fixed nodes */ if (fixed_copy) { IGRAPH_VECTOR_INIT_FINALLY(&node_order, no_of_not_fixed_nodes); for (i = 0, j = 0; i < no_of_nodes; i++) { if (!VECTOR(*fixed_copy)[i]) { VECTOR(node_order)[j] = i; j++; } } } else { IGRAPH_CHECK(igraph_vector_init_seq(&node_order, 0, no_of_nodes - 1)); IGRAPH_FINALLY(igraph_vector_destroy, &node_order); } /* There are two alternating types of iterations, one for changing labels and the other one for checking the end condition - every vertex in the graph has a label to which the maximum number of its neighbors belongs. If control_iteration is true, we are just checking the end condition and not relabeling nodes. */ control_iteration = 1; running = 1; while (running) { long int v1, num_neis; igraph_real_t max_count; igraph_vector_int_t *neis; igraph_vector_int_t *ineis; igraph_bool_t was_zero; if (control_iteration) { /* If we are in the control iteration, we expect in the begining of the iterationthat all vertices meet the end condition, so running is false. If some of them does not, running is set to true later in the code. */ running = 0; } else { /* Shuffle the node ordering vector if we are in the label updating iteration */ IGRAPH_CHECK(igraph_vector_shuffle(&node_order)); } RNG_BEGIN(); /* In the prescribed order, loop over the vertices and reassign labels */ for (i = 0; i < no_of_not_fixed_nodes; i++) { v1 = (long int) VECTOR(node_order)[i]; /* Count the weights corresponding to different labels */ igraph_vector_clear(&dominant_labels); igraph_vector_clear(&nonzero_labels); max_count = 0.0; if (weights) { ineis = igraph_inclist_get(&il, v1); num_neis = igraph_vector_int_size(ineis); for (j = 0; j < num_neis; j++) { k = (long int) VECTOR(*membership)[ (long)IGRAPH_OTHER(graph, VECTOR(*ineis)[j], v1) ]; if (k == 0) { continue; /* skip if it has no label yet */ } was_zero = (VECTOR(label_counters)[k] == 0); VECTOR(label_counters)[k] += VECTOR(*weights)[(long)VECTOR(*ineis)[j]]; if (was_zero && VECTOR(label_counters)[k] != 0) { /* counter just became nonzero */ IGRAPH_CHECK(igraph_vector_push_back(&nonzero_labels, k)); } if (max_count < VECTOR(label_counters)[k]) { max_count = VECTOR(label_counters)[k]; IGRAPH_CHECK(igraph_vector_resize(&dominant_labels, 1)); VECTOR(dominant_labels)[0] = k; } else if (max_count == VECTOR(label_counters)[k]) { IGRAPH_CHECK(igraph_vector_push_back(&dominant_labels, k)); } } } else { neis = igraph_adjlist_get(&al, v1); num_neis = igraph_vector_int_size(neis); for (j = 0; j < num_neis; j++) { k = (long int) VECTOR(*membership)[(long)VECTOR(*neis)[j]]; if (k == 0) { continue; /* skip if it has no label yet */ } VECTOR(label_counters)[k]++; if (VECTOR(label_counters)[k] == 1) { /* counter just became nonzero */ IGRAPH_CHECK(igraph_vector_push_back(&nonzero_labels, k)); } if (max_count < VECTOR(label_counters)[k]) { max_count = VECTOR(label_counters)[k]; IGRAPH_CHECK(igraph_vector_resize(&dominant_labels, 1)); VECTOR(dominant_labels)[0] = k; } else if (max_count == VECTOR(label_counters)[k]) { IGRAPH_CHECK(igraph_vector_push_back(&dominant_labels, k)); } } } if (igraph_vector_size(&dominant_labels) > 0) { if (control_iteration) { /* Check if the _current_ label of the node is also dominant */ if (VECTOR(label_counters)[(long)VECTOR(*membership)[v1]] != max_count) { /* Nope, we need at least one more iteration */ running = 1; } } else { /* Select randomly from the dominant labels */ k = RNG_INTEGER(0, igraph_vector_size(&dominant_labels) - 1); VECTOR(*membership)[v1] = VECTOR(dominant_labels)[(long int)k]; } } /* Clear the nonzero elements in label_counters */ num_neis = igraph_vector_size(&nonzero_labels); for (j = 0; j < num_neis; j++) { VECTOR(label_counters)[(long int)VECTOR(nonzero_labels)[j]] = 0; } } RNG_END(); /* Alternating between control iterations and label updating iterations */ control_iteration = !control_iteration; } if (weights) { igraph_inclist_destroy(&il); } else { igraph_adjlist_destroy(&al); } IGRAPH_FINALLY_CLEAN(1); /* Shift back the membership vector, permute labels in increasing order */ /* We recycle label_counters here :) */ igraph_vector_fill(&label_counters, -1); j = 0; unlabelled_left = 0; for (i = 0; i < no_of_nodes; i++) { k = (long)VECTOR(*membership)[i] - 1; if (k >= 0) { if (VECTOR(label_counters)[k] == -1) { /* We have seen this label for the first time */ VECTOR(label_counters)[k] = j; k = j; j++; } else { k = (long int) VECTOR(label_counters)[k]; } } else { /* This is an unlabeled vertex */ unlabelled_left = 1; } VECTOR(*membership)[i] = k; } /* From this point on, unlabelled nodes are represented with -1 (no longer 0). */ #define IS_UNLABELLED(x) (VECTOR(*membership)[x] < 0) /* If any nodes are left unlabelled, we assign the remaining labels to them, * as well as to all unlabelled nodes reachable from them. * * Note that only those nodes could remain unlabelled which were unreachable * from any labelled ones. Thus, in the undirected case, fully unlabelled * connected components remain unlabelled. Here we label each such component * with the same label. */ if (unlabelled_left) { igraph_dqueue_t q; igraph_vector_t neis; /* In the directed case, the outcome depends on the node ordering, thus we * shuffle nodes one more time. */ IGRAPH_CHECK(igraph_vector_shuffle(&node_order)); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_dqueue_init(&q, 0)); IGRAPH_FINALLY(igraph_dqueue_destroy, &q); for (i=0; i < no_of_nodes; ++i) { long int v = VECTOR(node_order)[i]; /* Is this node unlabelled? */ if (IS_UNLABELLED(v)) { /* If yes, we label it, and do a BFS to apply the same label * to all other unlabelled nodes reachable from it */ igraph_dqueue_push(&q, v); VECTOR(*membership)[v] = j; while (!igraph_dqueue_empty(&q)) { long int ni, num_neis; long int actnode = igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_neighbors(graph, &neis, actnode, IGRAPH_OUT)); num_neis = igraph_vector_size(&neis); for (ni = 0; ni < num_neis; ++ni) { long int neighbor = VECTOR(neis)[ni]; if (IS_UNLABELLED(neighbor)) { VECTOR(*membership)[neighbor] = j; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); } } } j++; } } igraph_vector_destroy(&neis); igraph_dqueue_destroy(&q); IGRAPH_FINALLY_CLEAN(2); } if (modularity) { IGRAPH_CHECK(igraph_modularity(graph, membership, weights, /* resolution */ 1, /* directed */ 1, modularity)); } igraph_vector_destroy(&node_order); igraph_vector_destroy(&label_counters); igraph_vector_destroy(&dominant_labels); igraph_vector_destroy(&nonzero_labels); IGRAPH_FINALLY_CLEAN(4); if (fixed != fixed_copy) { igraph_vector_bool_destroy(fixed_copy); igraph_Free(fixed_copy); IGRAPH_FINALLY_CLEAN(2); } return IGRAPH_SUCCESS; } leidenbase/src/core/community/leading_eigenvector.c0000644000176200001440000011736514447675374022313 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_adjlist.h" #include "igraph_components.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_iterators.h" #include "igraph_memory.h" #include "igraph_statusbar.h" #include "igraph_structural.h" #include "core/interruption.h" /** * \section about_leading_eigenvector_methods * * * The function documented in these section implements the * leading eigenvector method developed by Mark Newman and * published in MEJ Newman: Finding community structure using the * eigenvectors of matrices, Phys Rev E 74:036104 (2006). * * * The heart of the method is the definition of the modularity matrix, * B, which is B=A-P, A being the adjacency matrix of the (undirected) * network, and P contains the probability that certain edges are * present according to the configuration model In * other words, a Pij element of P is the probability that there is an * edge between vertices i and j in a random network in which the * degrees of all vertices are the same as in the input graph. * * * The leading eigenvector method works by calculating the eigenvector * of the modularity matrix for the largest positive eigenvalue and * then separating vertices into two community based on the sign of * the corresponding element in the eigenvector. If all elements in * the eigenvector are of the same sign that means that the network * has no underlying community structure. * Check Newman's paper to understand why this is a good method for * detecting community structure. * * * The leading eigenvector community structure detection method is * implemented in \ref igraph_community_leading_eigenvector(). After * the initial split, the following splits are done in a way to * optimize modularity regarding to the original network. Note that * any further refinement, for example using Kernighan-Lin, as * proposed in Section V.A of Newman (2006), is not implemented here. * * * * \example examples/simple/igraph_community_leading_eigenvector.c * */ typedef struct igraph_i_community_leading_eigenvector_data_t { igraph_vector_t *idx; igraph_vector_t *idx2; igraph_adjlist_t *adjlist; igraph_inclist_t *inclist; igraph_vector_t *tmp; long int no_of_edges; igraph_vector_t *mymembership; long int comm; const igraph_vector_t *weights; const igraph_t *graph; igraph_vector_t *strength; igraph_real_t sumweights; } igraph_i_community_leading_eigenvector_data_t; static int igraph_i_community_leading_eigenvector(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_community_leading_eigenvector_data_t *data = extra; long int j, k, nlen, size = n; igraph_vector_t *idx = data->idx; igraph_vector_t *idx2 = data->idx2; igraph_vector_t *tmp = data->tmp; igraph_adjlist_t *adjlist = data->adjlist; igraph_real_t ktx, ktx2; long int no_of_edges = data->no_of_edges; igraph_vector_t *mymembership = data->mymembership; long int comm = data->comm; /* Ax */ for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_vector_int_t *neis = igraph_adjlist_get(adjlist, oldid); nlen = igraph_vector_int_size(neis); to[j] = 0.0; VECTOR(*tmp)[j] = 0.0; for (k = 0; k < nlen; k++) { long int nei = (long int) VECTOR(*neis)[k]; long int neimemb = (long int) VECTOR(*mymembership)[nei]; if (neimemb == comm) { to[j] += from[ (long int) VECTOR(*idx2)[nei] ]; VECTOR(*tmp)[j] += 1; } } } /* Now calculate k^Tx/2m */ ktx = 0.0; ktx2 = 0.0; for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_vector_int_t *neis = igraph_adjlist_get(adjlist, oldid); long int degree = igraph_vector_int_size(neis); ktx += from[j] * degree; ktx2 += degree; } ktx = ktx / no_of_edges / 2.0; ktx2 = ktx2 / no_of_edges / 2.0; /* Now calculate Bx */ for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_vector_int_t *neis = igraph_adjlist_get(adjlist, oldid); igraph_real_t degree = igraph_vector_int_size(neis); to[j] = to[j] - ktx * degree; VECTOR(*tmp)[j] = VECTOR(*tmp)[j] - ktx2 * degree; } /* -d_ij summa l in G B_il */ for (j = 0; j < size; j++) { to[j] -= VECTOR(*tmp)[j] * from[j]; } return 0; } static int igraph_i_community_leading_eigenvector2(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_community_leading_eigenvector_data_t *data = extra; long int j, k, nlen, size = n; igraph_vector_t *idx = data->idx; igraph_vector_t *idx2 = data->idx2; igraph_vector_t *tmp = data->tmp; igraph_adjlist_t *adjlist = data->adjlist; igraph_real_t ktx, ktx2; long int no_of_edges = data->no_of_edges; igraph_vector_t *mymembership = data->mymembership; long int comm = data->comm; /* Ax */ for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_vector_int_t *neis = igraph_adjlist_get(adjlist, oldid); nlen = igraph_vector_int_size(neis); to[j] = 0.0; VECTOR(*tmp)[j] = 0.0; for (k = 0; k < nlen; k++) { long int nei = (long int) VECTOR(*neis)[k]; long int neimemb = (long int) VECTOR(*mymembership)[nei]; if (neimemb == comm) { long int fi = (long int) VECTOR(*idx2)[nei]; if (fi < size) { to[j] += from[fi]; } VECTOR(*tmp)[j] += 1; } } } /* Now calculate k^Tx/2m */ ktx = 0.0; ktx2 = 0.0; for (j = 0; j < size + 1; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_vector_int_t *neis = igraph_adjlist_get(adjlist, oldid); long int degree = igraph_vector_int_size(neis); if (j < size) { ktx += from[j] * degree; } ktx2 += degree; } ktx = ktx / no_of_edges / 2.0; ktx2 = ktx2 / no_of_edges / 2.0; /* Now calculate Bx */ for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_vector_int_t *neis = igraph_adjlist_get(adjlist, oldid); igraph_real_t degree = igraph_vector_int_size(neis); to[j] = to[j] - ktx * degree; VECTOR(*tmp)[j] = VECTOR(*tmp)[j] - ktx2 * degree; } /* -d_ij summa l in G B_il */ for (j = 0; j < size; j++) { to[j] -= VECTOR(*tmp)[j] * from[j]; } return 0; } static int igraph_i_community_leading_eigenvector_weighted(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_community_leading_eigenvector_data_t *data = extra; long int j, k, nlen, size = n; igraph_vector_t *idx = data->idx; igraph_vector_t *idx2 = data->idx2; igraph_vector_t *tmp = data->tmp; igraph_inclist_t *inclist = data->inclist; igraph_real_t ktx, ktx2; igraph_vector_t *mymembership = data->mymembership; long int comm = data->comm; const igraph_vector_t *weights = data->weights; const igraph_t *graph = data->graph; igraph_vector_t *strength = data->strength; igraph_real_t sw = data->sumweights; /* Ax */ for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_vector_int_t *inc = igraph_inclist_get(inclist, oldid); nlen = igraph_vector_int_size(inc); to[j] = 0.0; VECTOR(*tmp)[j] = 0.0; for (k = 0; k < nlen; k++) { long int edge = (long int) VECTOR(*inc)[k]; igraph_real_t w = VECTOR(*weights)[edge]; long int nei = IGRAPH_OTHER(graph, edge, oldid); long int neimemb = (long int) VECTOR(*mymembership)[nei]; if (neimemb == comm) { to[j] += from[ (long int) VECTOR(*idx2)[nei] ] * w; VECTOR(*tmp)[j] += w; } } } /* k^Tx/2m */ ktx = 0.0; ktx2 = 0.0; for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_real_t str = VECTOR(*strength)[oldid]; ktx += from[j] * str; ktx2 += str; } ktx = ktx / sw / 2.0; ktx2 = ktx2 / sw / 2.0; /* Bx */ for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_real_t str = VECTOR(*strength)[oldid]; to[j] = to[j] - ktx * str; VECTOR(*tmp)[j] = VECTOR(*tmp)[j] - ktx2 * str; } /* -d_ij summa l in G B_il */ for (j = 0; j < size; j++) { to[j] -= VECTOR(*tmp)[j] * from[j]; } return 0; } static int igraph_i_community_leading_eigenvector2_weighted(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_community_leading_eigenvector_data_t *data = extra; long int j, k, nlen, size = n; igraph_vector_t *idx = data->idx; igraph_vector_t *idx2 = data->idx2; igraph_vector_t *tmp = data->tmp; igraph_inclist_t *inclist = data->inclist; igraph_real_t ktx, ktx2; igraph_vector_t *mymembership = data->mymembership; long int comm = data->comm; const igraph_vector_t *weights = data->weights; const igraph_t *graph = data->graph; igraph_vector_t *strength = data->strength; igraph_real_t sw = data->sumweights; /* Ax */ for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_vector_int_t *inc = igraph_inclist_get(inclist, oldid); nlen = igraph_vector_int_size(inc); to[j] = 0.0; VECTOR(*tmp)[j] = 0.0; for (k = 0; k < nlen; k++) { long int edge = (long int) VECTOR(*inc)[k]; igraph_real_t w = VECTOR(*weights)[edge]; long int nei = IGRAPH_OTHER(graph, edge, oldid); long int neimemb = (long int) VECTOR(*mymembership)[nei]; if (neimemb == comm) { long int fi = (long int) VECTOR(*idx2)[nei]; if (fi < size) { to[j] += from[fi] * w; } VECTOR(*tmp)[j] += w; } } } /* k^Tx/2m */ ktx = 0.0; ktx2 = 0.0; for (j = 0; j < size + 1; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_real_t str = VECTOR(*strength)[oldid]; if (j < size) { ktx += from[j] * str; } ktx2 += str; } ktx = ktx / sw / 2.0; ktx2 = ktx2 / sw / 2.0; /* Bx */ for (j = 0; j < size; j++) { long int oldid = (long int) VECTOR(*idx)[j]; igraph_real_t str = VECTOR(*strength)[oldid]; to[j] = to[j] - ktx * str; VECTOR(*tmp)[j] = VECTOR(*tmp)[j] - ktx2 * str; } /* -d_ij summa l in G B_il */ for (j = 0; j < size; j++) { to[j] -= VECTOR(*tmp)[j] * from[j]; } return 0; } static void igraph_i_levc_free(igraph_vector_ptr_t *ptr) { long int i, n = igraph_vector_ptr_size(ptr); for (i = 0; i < n; i++) { igraph_vector_t *v = VECTOR(*ptr)[i]; if (v) { igraph_vector_destroy(v); igraph_free(v); } } } static void igraph_i_error_handler_none(const char *reason, const char *file, int line, int igraph_errno) { IGRAPH_UNUSED(reason); IGRAPH_UNUSED(file); IGRAPH_UNUSED(line); IGRAPH_UNUSED(igraph_errno); /* do nothing */ } /** * \ingroup communities * \function igraph_community_leading_eigenvector * \brief Leading eigenvector community finding (proper version). * * Newman's leading eigenvector method for detecting community * structure. This is the proper implementation of the recursive, * divisive algorithm: each split is done by maximizing the modularity * regarding the original network, see MEJ Newman: Finding community * structure in networks using the eigenvectors of matrices, * Phys Rev E 74:036104 (2006). * * \param graph The undirected input graph. * \param weights The weights of the edges, or a null pointer for * unweighted graphs. * \param merges The result of the algorithm, a matrix containing the * information about the splits performed. The matrix is built in * the opposite way however, it is like the result of an * agglomerative algorithm. If at the end of the algorithm (after * \p steps steps was done) there are p communities, * then these are numbered from zero to p-1. The * first line of the matrix contains the first merge * (which is in reality the last split) of two communities into * community p, the merge in the second line forms * community p+1, etc. The matrix should be * initialized before calling and will be resized as needed. * This argument is ignored of it is \c NULL. * \param membership The membership of the vertices after all the * splits were performed will be stored here. The vector must be * initialized before calling and will be resized as needed. * This argument is ignored if it is \c NULL. This argument can * also be used to supply a starting configuration for the community * finding, in the format of a membership vector. In this case the * \p start argument must be set to 1. * \param steps The maximum number of steps to perform. It might * happen that some component (or the whole network) has no * underlying community structure and no further steps can be * done. If you want as many steps as possible then supply the * number of vertices in the network here. * \param options The options for ARPACK. \c n is always * overwritten. \c ncv is set to at least 4. * \param modularity If not a null pointer, then it must be a pointer * to a real number and the modularity score of the final division * is stored here. * \param start Boolean, whether to use the community structure given * in the \p membership argument as a starting point. * \param eigenvalues Pointer to an initialized vector or a null * pointer. If not a null pointer, then the eigenvalues calculated * along the community structure detection are stored here. The * non-positive eigenvalues, that do not result a split, are stored * as well. * \param eigenvectors If not a null pointer, then the eigenvectors * that are calculated in each step of the algorithm, are stored here, * in a pointer vector. Each eigenvector is stored in an * \ref igraph_vector_t object. The user is responsible of * deallocating the memory that belongs to the individual vectors, * by calling first \ref igraph_vector_destroy(), and then * \ref igraph_free() on them. * \param history Pointer to an initialized vector or a null pointer. * If not a null pointer, then a trace of the algorithm is stored * here, encoded numerically. The various operations: * \clist * \cli IGRAPH_LEVC_HIST_START_FULL * Start the algorithm from an initial state where each connected * component is a separate community. * \cli IGRAPH_LEVC_HIST_START_GIVEN * Start the algorithm from a given community structure. The next * value in the vector contains the initial number of * communities. * \cli IGRAPH_LEVC_HIST_SPLIT * Split a community into two communities. The id of the splitted * community is given in the next element of the history vector. * The id of the first new community is the same as the id of the * splitted community. The id of the second community equals to * the number of communities before the split. * \cli IGRAPH_LEVC_HIST_FAILED * Tried to split a community, but it was not worth it, as it * does not result in a bigger modularity value. The id of the * community is given in the next element of the vector. * \endclist * \param callback A null pointer or a function of type \ref * igraph_community_leading_eigenvector_callback_t. If given, this * callback function is called after each eigenvector/eigenvalue * calculation. If the callback returns a non-zero value, then the * community finding algorithm stops. See the arguments passed to * the callback at the documentation of \ref * igraph_community_leading_eigenvector_callback_t. * \param callback_extra Extra argument to pass to the callback * function. * \return Error code. * * \sa \ref igraph_community_walktrap() and \ref * igraph_community_spinglass() for other community structure * detection methods. * * Time complexity: O(|E|+|V|^2*steps), |V| is the number of vertices, * |E| the number of edges, steps the number of splits * performed. */ int igraph_community_leading_eigenvector(const igraph_t *graph, const igraph_vector_t *weights, igraph_matrix_t *merges, igraph_vector_t *membership, igraph_integer_t steps, igraph_arpack_options_t *options, igraph_real_t *modularity, igraph_bool_t start, igraph_vector_t *eigenvalues, igraph_vector_ptr_t *eigenvectors, igraph_vector_t *history, igraph_community_leading_eigenvector_callback_t *callback, void *callback_extra) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_dqueue_t tosplit; igraph_vector_t idx, idx2, mymerges; igraph_vector_t strength, tmp; long int staken = 0; igraph_adjlist_t adjlist; igraph_inclist_t inclist; long int i, j, k, l; long int communities; igraph_vector_t vmembership, *mymembership = membership; igraph_i_community_leading_eigenvector_data_t extra; igraph_arpack_storage_t storage; igraph_real_t mod = 0; igraph_arpack_function_t *arpcb1 = weights ? igraph_i_community_leading_eigenvector_weighted : igraph_i_community_leading_eigenvector; igraph_arpack_function_t *arpcb2 = weights ? igraph_i_community_leading_eigenvector2_weighted : igraph_i_community_leading_eigenvector2; igraph_real_t sumweights = 0.0; if (weights && no_of_edges != igraph_vector_size(weights)) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } if (start && !membership) { IGRAPH_ERROR("Cannot start from given configuration if memberships " "missing", IGRAPH_EINVAL); } if (start && membership && igraph_vector_size(membership) != no_of_nodes) { IGRAPH_ERROR("Wrong length for vector of predefined memberships", IGRAPH_EINVAL); } if (start && membership && igraph_vector_max(membership) >= no_of_nodes) { IGRAPH_WARNING("Too many communities in membership start vector"); } if (igraph_is_directed(graph)) { IGRAPH_WARNING("This method was developed for undirected graphs"); } if (steps < 0 || steps > no_of_nodes - 1) { steps = (igraph_integer_t) no_of_nodes - 1; } if (!membership) { mymembership = &vmembership; IGRAPH_VECTOR_INIT_FINALLY(mymembership, 0); } IGRAPH_VECTOR_INIT_FINALLY(&mymerges, 0); IGRAPH_CHECK(igraph_vector_reserve(&mymerges, steps * 2)); IGRAPH_VECTOR_INIT_FINALLY(&idx, 0); if (eigenvalues) { igraph_vector_clear(eigenvalues); } if (eigenvectors) { igraph_vector_ptr_clear(eigenvectors); IGRAPH_FINALLY(igraph_i_levc_free, eigenvectors); } IGRAPH_STATUS("Starting leading eigenvector method.\n", 0); if (!start) { /* Calculate the weakly connected components in the graph and use them as * an initial split */ IGRAPH_CHECK(igraph_clusters(graph, mymembership, &idx, 0, IGRAPH_WEAK)); communities = igraph_vector_size(&idx); IGRAPH_STATUSF(("Starting from %li component(s).\n", 0, communities)); if (history) { IGRAPH_CHECK(igraph_vector_push_back(history, IGRAPH_LEVC_HIST_START_FULL)); } } else { /* Just create the idx vector for the given membership vector */ communities = (long int) igraph_vector_max(mymembership) + 1; IGRAPH_STATUSF(("Starting from given membership vector with %li " "communities.\n", 0, communities)); if (history) { IGRAPH_CHECK(igraph_vector_push_back(history, IGRAPH_LEVC_HIST_START_GIVEN)); IGRAPH_CHECK(igraph_vector_push_back(history, communities)); } IGRAPH_CHECK(igraph_vector_resize(&idx, communities)); igraph_vector_null(&idx); for (i = 0; i < no_of_nodes; i++) { int t = (int) VECTOR(*mymembership)[i]; VECTOR(idx)[t] += 1; } } IGRAPH_DQUEUE_INIT_FINALLY(&tosplit, 100); for (i = 0; i < communities; i++) { if (VECTOR(idx)[i] > 2) { igraph_dqueue_push(&tosplit, i); } } for (i = 1; i < communities; i++) { /* Record merge */ IGRAPH_CHECK(igraph_vector_push_back(&mymerges, i - 1)); IGRAPH_CHECK(igraph_vector_push_back(&mymerges, i)); if (eigenvalues) { IGRAPH_CHECK(igraph_vector_push_back(eigenvalues, IGRAPH_NAN)); } if (eigenvectors) { igraph_vector_t *v = IGRAPH_CALLOC(1, igraph_vector_t); if (!v) { IGRAPH_ERROR("Cannot do leading eigenvector community detection", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, v); IGRAPH_VECTOR_INIT_FINALLY(v, 0); IGRAPH_CHECK(igraph_vector_ptr_push_back(eigenvectors, v)); IGRAPH_FINALLY_CLEAN(2); } if (history) { IGRAPH_CHECK(igraph_vector_push_back(history, IGRAPH_LEVC_HIST_SPLIT)); IGRAPH_CHECK(igraph_vector_push_back(history, i - 1)); } } staken = communities - 1; IGRAPH_VECTOR_INIT_FINALLY(&tmp, no_of_nodes); IGRAPH_CHECK(igraph_vector_resize(&idx, no_of_nodes)); igraph_vector_null(&idx); IGRAPH_VECTOR_INIT_FINALLY(&idx2, no_of_nodes); if (!weights) { IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); } else { IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); IGRAPH_VECTOR_INIT_FINALLY(&strength, no_of_nodes); IGRAPH_CHECK(igraph_strength(graph, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, weights)); sumweights = igraph_vector_sum(weights); } options->ncv = 0; /* 0 means "automatic" in igraph_arpack_rssolve */ options->start = 0; options->which[0] = 'L'; options->which[1] = 'A'; /* Memory for ARPACK */ /* We are allocating memory for 20 eigenvectors since options->ncv won't be * larger than 20 when using automatic mode in igraph_arpack_rssolve */ IGRAPH_CHECK(igraph_arpack_storage_init(&storage, (int) no_of_nodes, 20, (int) no_of_nodes, 1)); IGRAPH_FINALLY(igraph_arpack_storage_destroy, &storage); extra.idx = &idx; extra.idx2 = &idx2; extra.tmp = &tmp; extra.adjlist = &adjlist; extra.inclist = &inclist; extra.weights = weights; extra.sumweights = sumweights; extra.graph = graph; extra.strength = &strength; extra.no_of_edges = no_of_edges; extra.mymembership = mymembership; while (!igraph_dqueue_empty(&tosplit) && staken < steps) { long int comm = (long int) igraph_dqueue_pop_back(&tosplit); /* depth first search */ long int size = 0; igraph_real_t tmpev; IGRAPH_STATUSF(("Trying to split community %li... ", 0, comm)); IGRAPH_ALLOW_INTERRUPTION(); for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*mymembership)[i] == comm) { VECTOR(idx)[size] = i; VECTOR(idx2)[i] = size++; } } staken++; if (size <= 2) { continue; } /* We solve two eigenproblems, one for the original modularity matrix, and one for the modularity matrix after deleting the last row and last column from it. This is a trick to find multiple leading eigenvalues, because ARPACK is sometimes unstable when the first two eigenvalues are requested, but it does much better for the single principal eigenvalue. */ /* We start with the smaller eigenproblem. */ options->n = (int) size - 1; options->info = 0; options->nev = 1; options->ldv = 0; options->ncv = 0; /* 0 means "automatic" in igraph_arpack_rssolve */ options->nconv = 0; options->lworkl = 0; /* we surely have enough space */ extra.comm = comm; /* We try calling the solver twice, once from a random starting point, once from a fixed one. This is because for some hard cases it tends to fail. We need to suppress error handling for the first call. */ { int i; igraph_error_handler_t *errh = igraph_set_error_handler(igraph_i_error_handler_none); igraph_warning_handler_t *warnh = igraph_set_warning_handler(igraph_warning_handler_ignore); igraph_arpack_rssolve(arpcb2, &extra, options, &storage, /*values=*/ 0, /*vectors=*/ 0); igraph_set_error_handler(errh); igraph_set_warning_handler(warnh); if (options->nconv < 1) { /* Call again from a fixed starting point. Note that we cannot use a * fixed all-1 starting vector as sometimes ARPACK would return a * 'starting vector is zero' error -- this is of course not true but * it's a result of ARPACK >= 3.6.3 trying to force the starting vector * into the range of OP (i.e. the matrix being solved). The initial * vector we use here seems to work, but I have no theoretical argument * for its usage; it just happens to work. */ options->start = 1; options->info = 0; options->ncv = 0; options->lworkl = 0; /* we surely have enough space */ for (i = 0; i < options->n ; i++) { storage.resid[i] = i % 2 ? 1 : -1; } IGRAPH_CHECK(igraph_arpack_rssolve(arpcb2, &extra, options, &storage, /*values=*/ 0, /*vectors=*/ 0)); options->start = 0; } } if (options->nconv < 1) { IGRAPH_ERROR("ARPACK did not converge", IGRAPH_ARPACK_FAILED); } tmpev = storage.d[0]; /* Now we do the original eigenproblem, again, twice if needed */ options->n = (int) size; options->info = 0; options->nev = 1; options->ldv = 0; options->nconv = 0; options->lworkl = 0; /* we surely have enough space */ options->ncv = 0; /* 0 means "automatic" in igraph_arpack_rssolve */ { int i; igraph_error_handler_t *errh = igraph_set_error_handler(igraph_i_error_handler_none); igraph_arpack_rssolve(arpcb1, &extra, options, &storage, /*values=*/ 0, /*vectors=*/ 0); igraph_set_error_handler(errh); if (options->nconv < 1) { /* Call again from a fixed starting point. See the comment a few lines * above about the exact choice of this starting vector */ options->start = 1; options->info = 0; options->ncv = 0; options->lworkl = 0; /* we surely have enough space */ for (i = 0; i < options->n; i++) { storage.resid[i] = i % 2 ? 1 : -1; } IGRAPH_CHECK(igraph_arpack_rssolve(arpcb1, &extra, options, &storage, /*values=*/ 0, /*vectors=*/ 0)); options->start = 0; } } if (options->nconv < 1) { IGRAPH_ERROR("ARPACK did not converge", IGRAPH_ARPACK_FAILED); } /* Ok, we have the leading eigenvector of the modularity matrix*/ /* ---------------------------------------------------------------*/ /* To avoid numeric errors */ if (fabs(storage.d[0]) < 1e-8) { storage.d[0] = 0; } /* We replace very small (in absolute value) elements of the leading eigenvector with zero, to get the same result, consistently.*/ for (i = 0; i < size; i++) { if (fabs(storage.v[i]) < 1e-8) { storage.v[i] = 0; } } /* Just to have the always the same result, we multiply by -1 if the first (nonzero) element is not positive. */ for (i = 0; i < size; i++) { if (storage.v[i] != 0) { break; } } if (i < size && storage.v[i] < 0) { for (i = 0; i < size; i++) { storage.v[i] = - storage.v[i]; } } /* ---------------------------------------------------------------*/ if (callback) { igraph_vector_t vv; int ret; igraph_vector_view(&vv, storage.v, size); ret = callback(mymembership, comm, storage.d[0], &vv, arpcb1, &extra, callback_extra); if (ret) { break; } } if (eigenvalues) { IGRAPH_CHECK(igraph_vector_push_back(eigenvalues, storage.d[0])); } if (eigenvectors) { igraph_vector_t *v = IGRAPH_CALLOC(1, igraph_vector_t); if (!v) { IGRAPH_ERROR("Cannot do leading eigenvector community detection", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, v); IGRAPH_VECTOR_INIT_FINALLY(v, size); for (i = 0; i < size; i++) { VECTOR(*v)[i] = storage.v[i]; } IGRAPH_CHECK(igraph_vector_ptr_push_back(eigenvectors, v)); IGRAPH_FINALLY_CLEAN(2); } if (storage.d[0] <= 0) { IGRAPH_STATUS("no split.\n", 0); if (history) { IGRAPH_CHECK(igraph_vector_push_back(history, IGRAPH_LEVC_HIST_FAILED)); IGRAPH_CHECK(igraph_vector_push_back(history, comm)); } continue; } /* Check for multiple leading eigenvalues */ if (fabs(storage.d[0] - tmpev) < 1e-8) { IGRAPH_STATUS("multiple principal eigenvalue, no split.\n", 0); if (history) { IGRAPH_CHECK(igraph_vector_push_back(history, IGRAPH_LEVC_HIST_FAILED)); IGRAPH_CHECK(igraph_vector_push_back(history, comm)); } continue; } /* Count the number of vertices in each community after the split */ l = 0; for (j = 0; j < size; j++) { if (storage.v[j] < 0) { storage.v[j] = -1; l++; } else { storage.v[j] = 1; } } if (l == 0 || l == size) { IGRAPH_STATUS("no split.\n", 0); if (history) { IGRAPH_CHECK(igraph_vector_push_back(history, IGRAPH_LEVC_HIST_FAILED)); IGRAPH_CHECK(igraph_vector_push_back(history, comm)); } continue; } /* Check that Q increases with our choice of split */ arpcb1(storage.v + size, storage.v, (int) size, &extra); mod = 0; for (i = 0; i < size; i++) { mod += storage.v[size + i] * storage.v[i]; } if (mod <= 1e-8) { IGRAPH_STATUS("no modularity increase, no split.\n", 0); if (history) { IGRAPH_CHECK(igraph_vector_push_back(history, IGRAPH_LEVC_HIST_FAILED)); IGRAPH_CHECK(igraph_vector_push_back(history, comm)); } continue; } communities++; IGRAPH_STATUS("split.\n", 0); /* Rewrite the mymembership vector */ for (j = 0; j < size; j++) { if (storage.v[j] < 0) { long int oldid = (long int) VECTOR(idx)[j]; VECTOR(*mymembership)[oldid] = communities - 1; } } /* Record merge */ IGRAPH_CHECK(igraph_vector_push_back(&mymerges, comm)); IGRAPH_CHECK(igraph_vector_push_back(&mymerges, communities - 1)); if (history) { IGRAPH_CHECK(igraph_vector_push_back(history, IGRAPH_LEVC_HIST_SPLIT)); IGRAPH_CHECK(igraph_vector_push_back(history, comm)); } /* Store the resulting communities in the queue if needed */ if (l > 1) { IGRAPH_CHECK(igraph_dqueue_push(&tosplit, communities - 1)); } if (size - l > 1) { IGRAPH_CHECK(igraph_dqueue_push(&tosplit, comm)); } } igraph_arpack_storage_destroy(&storage); IGRAPH_FINALLY_CLEAN(1); if (!weights) { igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); } else { igraph_inclist_destroy(&inclist); igraph_vector_destroy(&strength); IGRAPH_FINALLY_CLEAN(2); } igraph_dqueue_destroy(&tosplit); igraph_vector_destroy(&tmp); igraph_vector_destroy(&idx2); IGRAPH_FINALLY_CLEAN(3); IGRAPH_STATUS("Done.\n", 0); /* reform the mymerges vector */ if (merges) { igraph_vector_null(&idx); l = igraph_vector_size(&mymerges); k = communities; j = 0; IGRAPH_CHECK(igraph_matrix_resize(merges, l / 2, 2)); for (i = l; i > 0; i -= 2) { long int from = (long int) VECTOR(mymerges)[i - 1]; long int to = (long int) VECTOR(mymerges)[i - 2]; MATRIX(*merges, j, 0) = VECTOR(mymerges)[i - 2]; MATRIX(*merges, j, 1) = VECTOR(mymerges)[i - 1]; if (VECTOR(idx)[from] != 0) { MATRIX(*merges, j, 1) = VECTOR(idx)[from] - 1; } if (VECTOR(idx)[to] != 0) { MATRIX(*merges, j, 0) = VECTOR(idx)[to] - 1; } VECTOR(idx)[to] = ++k; j++; } } if (eigenvectors) { IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&idx); igraph_vector_destroy(&mymerges); IGRAPH_FINALLY_CLEAN(2); if (modularity) { IGRAPH_CHECK(igraph_modularity(graph, mymembership, weights, /* resolution */ 1, /* only undirected */ 0, modularity)); } if (!membership) { igraph_vector_destroy(mymembership); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_le_community_to_membership * Vertex membership from the leading eigenvector community structure * * This function creates a membership vector from the * result of \ref igraph_community_leading_eigenvector(), * It takes \c membership * and performs \c steps merges, according to the supplied * \c merges matrix. * \param merges The two-column matrix containing the merge * operations. See \ref igraph_community_walktrap() for the * detailed syntax. This is usually from the output of the * leading eigenvector community structure detection routines. * \param steps The number of steps to make according to \c merges. * \param membership Initially the starting membership vector, * on output the resulting membership vector, after performing \c steps merges. * \param csize Optionally the sizes of the communities is stored here, * if this is not a null pointer, but an initialized vector. * \return Error code. * * Time complexity: O(|V|), the number of vertices. */ int igraph_le_community_to_membership(const igraph_matrix_t *merges, igraph_integer_t steps, igraph_vector_t *membership, igraph_vector_t *csize) { long int no_of_nodes = igraph_vector_size(membership); igraph_vector_t fake_memb; long int components, i; if (no_of_nodes > 0) { components = (long int) igraph_vector_max(membership) + 1; } else { components = 0; } if (components > no_of_nodes) { IGRAPH_ERRORF("Invalid membership vector: number of components (%ld) must " "not be greater than the number of nodes (%ld).", IGRAPH_EINVAL, components, no_of_nodes); } if (steps >= components) { IGRAPH_ERRORF("Number of steps (%" IGRAPH_PRId ") must be smaller than number of components (%ld).", IGRAPH_EINVAL, steps, components); } IGRAPH_VECTOR_INIT_FINALLY(&fake_memb, components); /* Check membership vector */ for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*membership)[i] < 0) { IGRAPH_ERRORF("Invalid membership vector, negative ID found: %g.", IGRAPH_EINVAL, VECTOR(*membership)[i]); } VECTOR(fake_memb)[ (long int) VECTOR(*membership)[i] ] += 1; } for (i = 0; i < components; i++) { if (VECTOR(fake_memb)[i] == 0) { /* Ideally the empty cluster's index would be reported. However, doing so would be confusing as some high-level interfaces use 1-based indexing, some 0-based. */ IGRAPH_ERROR("Invalid membership vector, empty cluster found.", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_community_to_membership(merges, (igraph_integer_t) components, steps, &fake_memb, 0)); /* Ok, now we have the membership of the initial components, rewrite the original membership vector. */ if (csize) { IGRAPH_CHECK(igraph_vector_resize(csize, components - steps)); igraph_vector_null(csize); } for (i = 0; i < no_of_nodes; i++) { VECTOR(*membership)[i] = VECTOR(fake_memb)[ (long int) VECTOR(*membership)[i] ]; if (csize) { VECTOR(*csize)[ (long int) VECTOR(*membership)[i] ] += 1; } } igraph_vector_destroy(&fake_memb); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/community/optimal_modularity.c0000644000176200001440000002262114447675374022222 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_error.h" #include "igraph_interface.h" #include "igraph_structural.h" #include "core/interruption.h" #include "internal/glpk_support.h" #include "config.h" #ifdef HAVE_GLPK #include #endif /** * \function igraph_community_optimal_modularity * Calculate the community structure with the highest modularity value * * This function calculates the optimal community structure for a * graph, in terms of maximal modularity score. * * * The calculation is done by transforming the modularity maximization * into an integer programming problem, and then calling the GLPK * library to solve that. Please see Ulrik Brandes et al.: On * Modularity Clustering, IEEE Transactions on Knowledge and Data * Engineering 20(2):172-188, 2008. * * * Note that modularity optimization is an NP-complete problem, and * all known algorithms for it have exponential time complexity. This * means that you probably don't want to run this function on larger * graphs. Graphs with up to fifty vertices should be fine, graphs * with a couple of hundred vertices might be possible. * * \param graph The input graph. It is always treated as undirected. * \param modularity Pointer to a real number, or a null pointer. * If it is not a null pointer, then a optimal modularity value * is returned here. * \param membership Pointer to a vector, or a null pointer. If not a * null pointer, then the membership vector of the optimal * community structure is stored here. * \param weights Vector giving the weights of the edges. If it is * \c NULL then each edge is supposed to have the same weight. * \return Error code. * * \sa \ref igraph_modularity(), \ref igraph_community_fastgreedy() * for an algorithm that finds a local optimum in a greedy way. * * Time complexity: exponential in the number of vertices. * * \example examples/simple/igraph_community_optimal_modularity.c */ int igraph_community_optimal_modularity(const igraph_t *graph, igraph_real_t *modularity, igraph_vector_t *membership, const igraph_vector_t *weights) { #ifndef HAVE_GLPK IGRAPH_ERROR("GLPK is not available", IGRAPH_UNIMPLEMENTED); #else igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph); igraph_integer_t no_of_edges = (igraph_integer_t) igraph_ecount(graph); igraph_bool_t directed = igraph_is_directed(graph); int no_of_variables = no_of_nodes * (no_of_nodes + 1) / 2; int i, j, k, l, st; int idx[] = { 0, 0, 0, 0 }; double coef[] = { 0.0, 1.0, 1.0, -2.0 }; igraph_real_t total_weight; igraph_vector_t indegree; igraph_vector_t outdegree; glp_prob *ip; glp_iocp parm; if (weights) { if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length must agree with number of edges.", IGRAPH_EINVAL); } if (no_of_edges > 0) { /* Must not call vector_min on empty vector */ igraph_real_t minweight = igraph_vector_min(weights); if (minweight < 0) { IGRAPH_ERROR("Negative weights are not allowed in weight vector.", IGRAPH_EINVAL); } if (igraph_is_nan(minweight)) { IGRAPH_ERROR("Weights must not be NaN.", IGRAPH_EINVAL); } } } /* Avoid problems with the null graph */ if (no_of_nodes < 2) { if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); igraph_vector_fill(membership, 0); } if (modularity) { IGRAPH_CHECK(igraph_modularity(graph, membership, 0, 1, igraph_is_directed(graph), modularity)); } return IGRAPH_SUCCESS; } if (weights) { total_weight = igraph_vector_sum(weights); } else { total_weight = no_of_edges; } if (!directed) { total_weight *= 2; } /* Special case */ if (no_of_edges == 0 || total_weight == 0) { if (modularity) { *modularity = IGRAPH_NAN; } if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); igraph_vector_null(membership); } } IGRAPH_VECTOR_INIT_FINALLY(&indegree, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&outdegree, no_of_nodes); IGRAPH_CHECK(igraph_strength(graph, &indegree, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS, weights)); IGRAPH_CHECK(igraph_strength(graph, &outdegree, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS, weights)); IGRAPH_GLPK_SETUP(); ip = glp_create_prob(); IGRAPH_FINALLY(igraph_i_glp_delete_prob, ip); glp_set_obj_dir(ip, GLP_MAX); st = glp_add_cols(ip, no_of_variables); /* variables are binary */ for (i = 0; i < no_of_variables; i++) { glp_set_col_kind(ip, (st + i), GLP_BV); } #define IDX(a,b) ((b)*((b)+1)/2+(a)) /* reflexivity */ for (i = 0; i < no_of_nodes; i++) { glp_set_col_bnds(ip, (st + IDX(i, i)), GLP_FX, 1.0, 1.0); } /* transitivity */ for (i = 0; i < no_of_nodes; i++) { for (j = i + 1; j < no_of_nodes; j++) { IGRAPH_ALLOW_INTERRUPTION(); for (k = j + 1; k < no_of_nodes; k++) { int newrow = glp_add_rows(ip, 3); glp_set_row_bnds(ip, newrow, GLP_UP, 0.0, 1.0); idx[1] = (st + IDX(i, j)); idx[2] = (st + IDX(j, k)); idx[3] = (st + IDX(i, k)); glp_set_mat_row(ip, newrow, 3, idx, coef); glp_set_row_bnds(ip, newrow + 1, GLP_UP, 0.0, 1.0); idx[1] = st + IDX(i, j); idx[2] = st + IDX(i, k); idx[3] = st + IDX(j, k); glp_set_mat_row(ip, newrow + 1, 3, idx, coef); glp_set_row_bnds(ip, newrow + 2, GLP_UP, 0.0, 1.0); idx[1] = st + IDX(i, k); idx[2] = st + IDX(j, k); idx[3] = st + IDX(i, j); glp_set_mat_row(ip, newrow + 2, 3, idx, coef); } } } /* objective function */ { igraph_real_t c; /* first part: -strength(i)*strength(j)/total_weight for every node pair */ for (i = 0; i < no_of_nodes; i++) { for (j = i + 1; j < no_of_nodes; j++) { c = -VECTOR(indegree)[i] * VECTOR(outdegree)[j] / total_weight \ -VECTOR(outdegree)[i] * VECTOR(indegree)[j] / total_weight; glp_set_obj_coef(ip, st + IDX(i, j), c); } /* special case for (i,i) */ c = -VECTOR(indegree)[i] * VECTOR(outdegree)[i] / total_weight; glp_set_obj_coef(ip, st + IDX(i, i), c); } /* second part: add the weighted adjacency matrix to the coefficient matrix */ for (k = 0; k < no_of_edges; k++) { i = IGRAPH_FROM(graph, k); j = IGRAPH_TO(graph, k); if (i > j) { l = i; i = j; j = l; } c = weights ? VECTOR(*weights)[k] : 1.0; if (!directed || i == j) { c *= 2.0; } glp_set_obj_coef(ip, st + IDX(i, j), c + glp_get_obj_coef(ip, st + IDX(i, j))); } } /* solve it */ glp_init_iocp(&parm); parm.br_tech = GLP_BR_DTH; parm.bt_tech = GLP_BT_BLB; parm.presolve = GLP_ON; parm.binarize = GLP_ON; parm.cb_func = igraph_i_glpk_interruption_hook; IGRAPH_GLPK_CHECK(glp_intopt(ip, &parm), "Modularity optimization failed"); /* store the results */ if (modularity) { *modularity = glp_mip_obj_val(ip) / total_weight; } if (membership) { long int comm = 0; /* id of the last community that was found */ IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { IGRAPH_ALLOW_INTERRUPTION(); for (j = 0; j < i; j++) { int val = (int) glp_mip_col_val(ip, st + IDX(j, i)); if (val == 1) { VECTOR(*membership)[i] = VECTOR(*membership)[j]; break; } } if (j == i) { /* new community */ VECTOR(*membership)[i] = comm++; } } } #undef IDX igraph_vector_destroy(&indegree); igraph_vector_destroy(&outdegree); glp_delete_prob(ip); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; #endif } leidenbase/src/core/community/edge_betweenness.c0000644000176200001440000007272614447675374021625 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_adjlist.h" #include "igraph_components.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_progress.h" #include "igraph_stack.h" #include "core/indheap.h" #include "core/interruption.h" #include static int igraph_i_rewrite_membership_vector(igraph_vector_t *membership) { long int no = (long int) igraph_vector_max(membership) + 1; igraph_vector_t idx; long int realno = 0; long int i; long int len = igraph_vector_size(membership); IGRAPH_VECTOR_INIT_FINALLY(&idx, no); for (i = 0; i < len; i++) { long int t = (long int) VECTOR(*membership)[i]; if (VECTOR(idx)[t]) { VECTOR(*membership)[i] = VECTOR(idx)[t] - 1; } else { VECTOR(idx)[t] = ++realno; VECTOR(*membership)[i] = VECTOR(idx)[t] - 1; } } igraph_vector_destroy(&idx); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_community_eb_get_merges2(const igraph_t *graph, const igraph_bool_t directed, const igraph_vector_t *edges, const igraph_vector_t *weights, igraph_matrix_t *res, igraph_vector_t *bridges, igraph_vector_t *modularity, igraph_vector_t *membership) { igraph_vector_t mymembership; long int no_of_nodes = igraph_vcount(graph); long int i; igraph_real_t maxmod = -1; long int midx = 0; igraph_integer_t no_comps; igraph_bool_t use_directed = directed && igraph_is_directed(graph); IGRAPH_VECTOR_INIT_FINALLY(&mymembership, no_of_nodes); if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); } if (modularity || res || bridges) { IGRAPH_CHECK(igraph_clusters(graph, 0, 0, &no_comps, IGRAPH_WEAK)); if (modularity) { IGRAPH_CHECK(igraph_vector_resize(modularity, no_of_nodes - no_comps + 1)); } if (res) { IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes - no_comps, 2)); } if (bridges) { IGRAPH_CHECK(igraph_vector_resize(bridges, no_of_nodes - no_comps)); } } for (i = 0; i < no_of_nodes; i++) { VECTOR(mymembership)[i] = i; } if (membership) { igraph_vector_update(membership, &mymembership); } IGRAPH_CHECK(igraph_modularity(graph, &mymembership, weights, /* resolution */ 1, use_directed, &maxmod)); if (modularity) { VECTOR(*modularity)[0] = maxmod; } for (i = igraph_vector_size(edges) - 1; i >= 0; i--) { long int edge = (long int) VECTOR(*edges)[i]; long int from = IGRAPH_FROM(graph, (igraph_integer_t) edge); long int to = IGRAPH_TO(graph, (igraph_integer_t) edge); long int c1 = (long int) VECTOR(mymembership)[from]; long int c2 = (long int) VECTOR(mymembership)[to]; igraph_real_t actmod; long int j; if (c1 != c2) { /* this is a merge */ if (res) { MATRIX(*res, midx, 0) = c1; MATRIX(*res, midx, 1) = c2; } if (bridges) { VECTOR(*bridges)[midx] = i + 1; } /* The new cluster has id no_of_nodes+midx+1 */ for (j = 0; j < no_of_nodes; j++) { if (VECTOR(mymembership)[j] == c1 || VECTOR(mymembership)[j] == c2) { VECTOR(mymembership)[j] = no_of_nodes + midx; } } IGRAPH_CHECK(igraph_modularity(graph, &mymembership, weights, /* resolution */ 1, use_directed, &actmod)); if (modularity) { VECTOR(*modularity)[midx + 1] = actmod; if (actmod > maxmod) { maxmod = actmod; if (membership) { igraph_vector_update(membership, &mymembership); } } } midx++; } } if (membership) { IGRAPH_CHECK(igraph_i_rewrite_membership_vector(membership)); } igraph_vector_destroy(&mymembership); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_community_eb_get_merges * \brief Calculating the merges, i.e. the dendrogram for an edge betweenness community structure. * * * This function is handy if you have a sequence of edges which are * gradually removed from the network and you would like to know how * the network falls apart into separate components. The edge sequence * may come from the \ref igraph_community_edge_betweenness() * function, but this is not necessary. Note that \ref * igraph_community_edge_betweenness() can also calculate the * dendrogram, via its \p merges argument. * * \param graph The input graph. * \param edges Vector containing the edges to be removed from the * network, all edges are expected to appear exactly once in the * vector. * \param directed Whether to use the directed or undirected version * of modularity. Will be ignored for undirected graphs. * \param weights An optional vector containing edge weights. If null, * the unweighted modularity scores will be calculated. If not null, * the weighted modularity scores will be calculated. Ignored if both * \p modularity and \p membership are \c NULL pointers. * \param res Pointer to an initialized matrix, if not \c NULL then the * dendrogram will be stored here, in the same form as for the \ref * igraph_community_walktrap() function: the matrix has two columns * and each line is a merge given by the ids of the merged * components. The component ids are numbered from zero and * component ids smaller than the number of vertices in the graph * belong to individual vertices. The non-trivial components * containing at least two vertices are numbered from \c n, where \c n is * the number of vertices in the graph. So if the first line * contains \c a and \c b that means that components \c a and \c b * are merged into component \c n, the second line creates * component \c n+1, etc. The matrix will be resized as needed. * \param bridges Pointer to an initialized vector or \c NULL. If not * null then the index of the edge removals which split the network * will be stored here. The vector will be resized as needed. * \param modularity If not a null pointer, then the modularity values * for the different divisions, corresponding to the merges matrix, * will be stored here. * \param membership If not a null pointer, then the membership vector * for the best division (in terms of modularity) will be stored * here. * \return Error code. * * \sa \ref igraph_community_edge_betweenness(). * * Time complexity: O(|E|+|V|log|V|), |V| is the number of vertices, * |E| is the number of edges. */ int igraph_community_eb_get_merges(const igraph_t *graph, const igraph_bool_t directed, const igraph_vector_t *edges, const igraph_vector_t *weights, igraph_matrix_t *res, igraph_vector_t *bridges, igraph_vector_t *modularity, igraph_vector_t *membership) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t ptr; long int i, midx = 0; igraph_integer_t no_comps; /* catch null graph early */ if (no_of_nodes == 0) { if (res) { igraph_matrix_resize(res, 0, 2); } if (bridges) { igraph_vector_clear(bridges); } if (modularity) { igraph_vector_clear(modularity); } if (membership) { igraph_vector_clear(membership); } return IGRAPH_SUCCESS; } if (membership || modularity) { return igraph_i_community_eb_get_merges2(graph, directed && igraph_is_directed(graph), edges, weights, res, bridges, modularity, membership); } IGRAPH_CHECK(igraph_clusters(graph, 0, 0, &no_comps, IGRAPH_WEAK)); IGRAPH_VECTOR_INIT_FINALLY(&ptr, no_of_nodes * 2 - 1); if (res) { IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes - no_comps, 2)); } if (bridges) { IGRAPH_CHECK(igraph_vector_resize(bridges, no_of_nodes - no_comps)); } for (i = igraph_vector_size(edges) - 1; i >= 0; i--) { igraph_integer_t edge = (igraph_integer_t) VECTOR(*edges)[i]; igraph_integer_t from, to, c1, c2, idx; igraph_edge(graph, edge, &from, &to); idx = from + 1; while (VECTOR(ptr)[idx - 1] != 0) { idx = (igraph_integer_t) VECTOR(ptr)[idx - 1]; } c1 = idx - 1; idx = to + 1; while (VECTOR(ptr)[idx - 1] != 0) { idx = (igraph_integer_t) VECTOR(ptr)[idx - 1]; } c2 = idx - 1; if (c1 != c2) { /* this is a merge */ if (res) { MATRIX(*res, midx, 0) = c1; MATRIX(*res, midx, 1) = c2; } if (bridges) { VECTOR(*bridges)[midx] = i + 1; } VECTOR(ptr)[c1] = no_of_nodes + midx + 1; VECTOR(ptr)[c2] = no_of_nodes + midx + 1; VECTOR(ptr)[from] = no_of_nodes + midx + 1; VECTOR(ptr)[to] = no_of_nodes + midx + 1; midx++; } } igraph_vector_destroy(&ptr); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Find the smallest active element in the vector */ static long int igraph_i_vector_which_max_not_null(const igraph_vector_t *v, const char *passive) { long int which, i = 0, size = igraph_vector_size(v); igraph_real_t max; while (passive[i]) { i++; } which = i; max = VECTOR(*v)[which]; for (i++; i < size; i++) { igraph_real_t elem = VECTOR(*v)[i]; if (!passive[i] && elem > max) { max = elem; which = i; } } return which; } /** * \function igraph_community_edge_betweenness * \brief Community finding based on edge betweenness. * * Community structure detection based on the betweenness of the edges * in the network. The algorithm was invented by M. Girvan and * M. Newman, see: M. Girvan and M. E. J. Newman: Community structure in * social and biological networks, Proc. Nat. Acad. Sci. USA 99, 7821-7826 * (2002). * * * The idea is that the betweenness of the edges connecting two * communities is typically high, as many of the shortest paths * between nodes in separate communities go through them. So we * gradually remove the edge with highest betweenness from the * network, and recalculate edge betweenness after every removal. * This way sooner or later the network falls off to two components, * then after a while one of these components falls off to two smaller * components, etc. until all edges are removed. This is a divisive * hierarchical approach, the result is a dendrogram. * \param graph The input graph. * \param result Pointer to an initialized vector, the result will be * stored here, the ids of the removed edges in the order of their * removal. It will be resized as needed. It may be \c NULL if * the edge IDs are not needed by the caller. * \param edge_betweenness Pointer to an initialized vector or * \c NULL. In the former case the edge betweenness of the removed * edge is stored here. The vector will be resized as needed. * \param merges Pointer to an initialized matrix or \c NULL. If not \c NULL * then merges performed by the algorithm are stored here. Even if * this is a divisive algorithm, we can replay it backwards and * note which two clusters were merged. Clusters are numbered from * zero, see the \p merges argument of \ref * igraph_community_walktrap() for details. The matrix will be * resized as needed. * \param bridges Pointer to an initialized vector of \c NULL. If not * NULL then all edge removals which separated the network into * more components are marked here. * \param modularity If not a null pointer, then the modularity values * of the different divisions are stored here, in the order * corresponding to the merge matrix. The modularity values will * take weights into account if \p weights is not null. * \param membership If not a null pointer, then the membership vector, * corresponding to the highest modularity value, is stored here. * \param directed Logical constant, whether to calculate directed * betweenness (i.e. directed paths) for directed graphs. It is * ignored for undirected graphs. * \param weights An optional vector containing edge weights. If null, * the unweighted edge betweenness scores will be calculated and * used. If not null, the weighted edge betweenness scores will be * calculated and used. * \return Error code. * * \sa \ref igraph_community_eb_get_merges(), \ref * igraph_community_spinglass(), \ref igraph_community_walktrap(). * * Time complexity: O(|V||E|^2), as the betweenness calculation requires * O(|V||E|) and we do it |E|-1 times. * * \example examples/simple/igraph_community_edge_betweenness.c */ int igraph_community_edge_betweenness(const igraph_t *graph, igraph_vector_t *result, igraph_vector_t *edge_betweenness, igraph_matrix_t *merges, igraph_vector_t *bridges, igraph_vector_t *modularity, igraph_vector_t *membership, igraph_bool_t directed, const igraph_vector_t *weights) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); double *distance, *tmpscore; double *nrgeo; long int source, i, e; igraph_inclist_t elist_out, elist_in, fathers; igraph_inclist_t *elist_out_p, *elist_in_p; igraph_vector_int_t *neip; long int neino; igraph_vector_t eb; long int maxedge, pos; igraph_integer_t from, to; igraph_bool_t result_owned = 0; igraph_stack_t stack = IGRAPH_STACK_NULL; igraph_real_t steps, steps_done; char *passive; /* Needed only for the unweighted case */ igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; /* Needed only for the weighted case */ igraph_2wheap_t heap; if (result == 0) { result = IGRAPH_CALLOC(1, igraph_vector_t); if (result == 0) { IGRAPH_ERROR("Edge betweenness community structure failed.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, result); IGRAPH_VECTOR_INIT_FINALLY(result, 0); result_owned = 1; } directed = directed && igraph_is_directed(graph); if (directed) { IGRAPH_CHECK(igraph_inclist_init(graph, &elist_out, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &elist_out); IGRAPH_CHECK(igraph_inclist_init(graph, &elist_in, IGRAPH_IN, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &elist_in); elist_out_p = &elist_out; elist_in_p = &elist_in; } else { IGRAPH_CHECK(igraph_inclist_init(graph, &elist_out, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &elist_out); elist_out_p = elist_in_p = &elist_out; } distance = IGRAPH_CALLOC(no_of_nodes, double); if (distance == 0) { IGRAPH_ERROR("Edge betweenness community structure failed.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, distance); nrgeo = IGRAPH_CALLOC(no_of_nodes, double); if (nrgeo == 0) { IGRAPH_ERROR("Edge betweenness community structure failed.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, nrgeo); tmpscore = IGRAPH_CALLOC(no_of_nodes, double); if (tmpscore == 0) { IGRAPH_ERROR("Edge betweenness community structure failed.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmpscore); if (weights == 0) { IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); } else { if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length must agree with number of edges.", IGRAPH_EINVAL); } if (no_of_edges > 0) { /* Must not call vector_min on empty vector */ igraph_real_t minweight = igraph_vector_min(weights); if (minweight <= 0) { IGRAPH_ERROR("Weights must be strictly positive.", IGRAPH_EINVAL); } if (igraph_is_nan(minweight)) { IGRAPH_ERROR("Weights must not be NaN.", IGRAPH_EINVAL); } } if (membership != 0) { IGRAPH_WARNING("Membership vector will be selected based on the lowest " "modularity score."); } if (modularity != 0 || membership != 0) { IGRAPH_WARNING("Modularity calculation with weighted edge betweenness " "community detection might not make sense -- modularity treats edge " "weights as similarities while edge betwenness treats them as " "distances."); } IGRAPH_CHECK(igraph_2wheap_init(&heap, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &heap); IGRAPH_CHECK(igraph_inclist_init_empty(&fathers, (igraph_integer_t) no_of_nodes)); IGRAPH_FINALLY(igraph_inclist_destroy, &fathers); } IGRAPH_CHECK(igraph_stack_init(&stack, no_of_nodes)); IGRAPH_FINALLY(igraph_stack_destroy, &stack); IGRAPH_CHECK(igraph_vector_resize(result, no_of_edges)); if (edge_betweenness) { IGRAPH_CHECK(igraph_vector_resize(edge_betweenness, no_of_edges)); if (no_of_edges > 0) { VECTOR(*edge_betweenness)[no_of_edges - 1] = 0; } } IGRAPH_VECTOR_INIT_FINALLY(&eb, no_of_edges); passive = IGRAPH_CALLOC(no_of_edges, char); if (!passive) { IGRAPH_ERROR("Edge betweenness community structure failed.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, passive); /* Estimate the number of steps to be taken. * It is assumed that one iteration is O(|E||V|), but |V| is constant * anyway, so we will have approximately |E|^2 / 2 steps, and one * iteration of the outer loop advances the step counter by the number * of remaining edges at that iteration. */ steps = no_of_edges / 2.0 * (no_of_edges + 1); steps_done = 0; for (e = 0; e < no_of_edges; steps_done += no_of_edges - e, e++) { IGRAPH_PROGRESS("Edge betweenness community detection: ", 100.0 * steps_done / steps, NULL); igraph_vector_null(&eb); if (weights == 0) { /* Unweighted variant follows */ /* The following for loop is copied almost intact from * igraph_edge_betweenness_cutoff */ for (source = 0; source < no_of_nodes; source++) { IGRAPH_ALLOW_INTERRUPTION(); memset(distance, 0, (size_t) no_of_nodes * sizeof(double)); memset(nrgeo, 0, (size_t) no_of_nodes * sizeof(double)); memset(tmpscore, 0, (size_t) no_of_nodes * sizeof(double)); igraph_stack_clear(&stack); /* it should be empty anyway... */ IGRAPH_CHECK(igraph_dqueue_push(&q, source)); nrgeo[source] = 1; distance[source] = 0; while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); neip = igraph_inclist_get(elist_out_p, actnode); neino = igraph_vector_int_size(neip); for (i = 0; i < neino; i++) { igraph_integer_t edge = (igraph_integer_t) VECTOR(*neip)[i]; long int neighbor= (long int) IGRAPH_OTHER(graph, edge, actnode); if (nrgeo[neighbor] != 0) { /* we've already seen this node, another shortest path? */ if (distance[neighbor] == distance[actnode] + 1) { nrgeo[neighbor] += nrgeo[actnode]; } } else { /* we haven't seen this node yet */ nrgeo[neighbor] += nrgeo[actnode]; distance[neighbor] = distance[actnode] + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_stack_push(&stack, neighbor)); } } } /* while !igraph_dqueue_empty */ /* Ok, we've the distance of each node and also the number of shortest paths to them. Now we do an inverse search, starting with the farthest nodes. */ while (!igraph_stack_empty(&stack)) { long int actnode = (long int) igraph_stack_pop(&stack); if (distance[actnode] < 1) { continue; /* skip source node */ } /* set the temporary score of the friends */ neip = igraph_inclist_get(elist_in_p, actnode); neino = igraph_vector_int_size(neip); for (i = 0; i < neino; i++) { long int edge = (long int) VECTOR(*neip)[i]; long int neighbor = IGRAPH_OTHER(graph, edge, actnode); if (distance[neighbor] == distance[actnode] - 1 && nrgeo[neighbor] != 0) { tmpscore[neighbor] += (tmpscore[actnode] + 1) * nrgeo[neighbor] / nrgeo[actnode]; VECTOR(eb)[edge] += (tmpscore[actnode] + 1) * nrgeo[neighbor] / nrgeo[actnode]; } } } /* Ok, we've the scores for this source */ } /* for source <= no_of_nodes */ } else { /* Weighted variant follows */ /* The following for loop is copied almost intact from * igraph_i_edge_betweenness_cutoff_weighted */ for (source = 0; source < no_of_nodes; source++) { /* This will contain the edge betweenness in the current step */ IGRAPH_ALLOW_INTERRUPTION(); memset(distance, 0, (size_t) no_of_nodes * sizeof(double)); memset(nrgeo, 0, (size_t) no_of_nodes * sizeof(double)); memset(tmpscore, 0, (size_t) no_of_nodes * sizeof(double)); igraph_2wheap_push_with_index(&heap, source, 0); distance[source] = 1.0; nrgeo[source] = 1; while (!igraph_2wheap_empty(&heap)) { long int minnei = igraph_2wheap_max_index(&heap); igraph_real_t mindist = -igraph_2wheap_delete_max(&heap); igraph_stack_push(&stack, minnei); neip = igraph_inclist_get(elist_out_p, minnei); neino = igraph_vector_int_size(neip); for (i = 0; i < neino; i++) { long int edge = VECTOR(*neip)[i]; long int to = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_real_t curdist = distance[to]; igraph_vector_int_t *v; if (curdist == 0) { /* This is the first finite distance to 'to' */ v = igraph_inclist_get(&fathers, to); igraph_vector_int_resize(v, 1); VECTOR(*v)[0] = edge; nrgeo[to] = nrgeo[minnei]; distance[to] = altdist + 1.0; IGRAPH_CHECK(igraph_2wheap_push_with_index(&heap, to, -altdist)); } else if (altdist < curdist - 1) { /* This is a shorter path */ v = igraph_inclist_get(&fathers, to); igraph_vector_int_resize(v, 1); VECTOR(*v)[0] = edge; nrgeo[to] = nrgeo[minnei]; distance[to] = altdist + 1.0; IGRAPH_CHECK(igraph_2wheap_modify(&heap, to, -altdist)); } else if (altdist == curdist - 1) { /* Another path with the same length */ v = igraph_inclist_get(&fathers, to); igraph_vector_int_push_back(v, edge); nrgeo[to] += nrgeo[minnei]; } } } /* igraph_2wheap_empty(&Q) */ while (!igraph_stack_empty(&stack)) { long int w = (long int) igraph_stack_pop(&stack); igraph_vector_int_t *fatv = igraph_inclist_get(&fathers, w); long int fatv_len = igraph_vector_int_size(fatv); for (i = 0; i < fatv_len; i++) { long int fedge = (long int) VECTOR(*fatv)[i]; long int neighbor = IGRAPH_OTHER(graph, fedge, w); tmpscore[neighbor] += (tmpscore[w] + 1) * nrgeo[neighbor] / nrgeo[w]; VECTOR(eb)[fedge] += (tmpscore[w] + 1) * nrgeo[neighbor] / nrgeo[w]; } tmpscore[w] = 0; distance[w] = 0; nrgeo[w] = 0; igraph_vector_int_clear(fatv); } } /* source < no_of_nodes */ } /* Now look for the smallest edge betweenness */ /* and eliminate that edge from the network */ maxedge = igraph_i_vector_which_max_not_null(&eb, passive); VECTOR(*result)[e] = maxedge; if (edge_betweenness) { VECTOR(*edge_betweenness)[e] = VECTOR(eb)[maxedge]; if (!directed) { VECTOR(*edge_betweenness)[e] /= 2.0; } } passive[maxedge] = 1; igraph_edge(graph, (igraph_integer_t) maxedge, &from, &to); neip = igraph_inclist_get(elist_in_p, to); neino = igraph_vector_int_size(neip); igraph_vector_int_search(neip, 0, maxedge, &pos); VECTOR(*neip)[pos] = VECTOR(*neip)[neino - 1]; igraph_vector_int_pop_back(neip); neip = igraph_inclist_get(elist_out_p, from); neino = igraph_vector_int_size(neip); igraph_vector_int_search(neip, 0, maxedge, &pos); VECTOR(*neip)[pos] = VECTOR(*neip)[neino - 1]; igraph_vector_int_pop_back(neip); } IGRAPH_PROGRESS("Edge betweenness community detection: ", 100.0, NULL); igraph_free(passive); igraph_vector_destroy(&eb); igraph_stack_destroy(&stack); IGRAPH_FINALLY_CLEAN(3); if (weights == 0) { igraph_dqueue_destroy(&q); IGRAPH_FINALLY_CLEAN(1); } else { igraph_2wheap_destroy(&heap); igraph_inclist_destroy(&fathers); IGRAPH_FINALLY_CLEAN(2); } igraph_free(tmpscore); igraph_free(nrgeo); igraph_free(distance); IGRAPH_FINALLY_CLEAN(3); if (directed) { igraph_inclist_destroy(&elist_out); igraph_inclist_destroy(&elist_in); IGRAPH_FINALLY_CLEAN(2); } else { igraph_inclist_destroy(&elist_out); IGRAPH_FINALLY_CLEAN(1); } if (merges || bridges || modularity || membership) { IGRAPH_CHECK(igraph_community_eb_get_merges(graph, directed, result, weights, merges, bridges, modularity, membership)); } if (result_owned) { igraph_vector_destroy(result); IGRAPH_FREE(result); IGRAPH_FINALLY_CLEAN(2); } return 0; } leidenbase/src/core/community/modularity.c0000644000176200001440000003521514447675374020500 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_conversion.h" #include "igraph_interface.h" #include "igraph_structural.h" /** * \function igraph_modularity * \brief Calculate the modularity of a graph with respect to some clusters or vertex types. * * The modularity of a graph with respect to some clustering of the vertices * (or assignment of vertex types) * measures how strongly separated the different clusters are from each * other compared to a random null model. It is defined as * * * Q = 1/(2m) sum_ij (A_ij - gamma * k_i * k_j / (2m)) * d(c_i,c_j), * * * where \c m is the number of edges, A_ij is the adjacency matrix, * \c k_i is the degree of vertex \c i, \c c_i is the cluster that vertex \c i belongs to * (or its vertex type), d(i,j)=1 if i=j and 0 otherwise, * and the sum goes over all i, j pairs of vertices. * * * The resolution parameter \c gamma allows weighting the random null model, which * might be useful when finding partitions with a high modularity. Maximizing modularity * with higher values of the resolution parameter typically results in more, smaller clusters * when finding partitions with a high modularity. Lower values typically results in * fewer, larger clusters. The original definition of modularity is retrieved * when setting gamma=1. * * * Modularity can also be calculated on directed graphs. This only requires a relatively * modest change * * * Q = 1/(m) sum_ij (A_ij - gamma * k^out_i * k^in_j / m) * d(c_i,c_j), * * * where \c k^out_i is the out-degree of node \c i and \c k^in_j is the in-degree of node \c j. * * * Modularity on weighted graphs is also meaningful. When taking * edge weights into account, \c A_ij equals the weight of the corresponding edge * (or 0 if there is no edge), \c k_i is the strength (i.e. the weighted degree) of * vertex \c i, with similar counterparts for a directed graph, and \c m is the total * weight of all edges. * * * Note that the modularity is not well-defined for graphs with no edges. * igraph returns \c NaN for graphs with no edges; see * https://github.com/igraph/igraph/issues/1539 for * a detailed discussion. * * * For the original definition of modularity, see Newman, M. E. J., and Girvan, M. * (2004). Finding and evaluating community structure in networks. * Physical Review E 69, 026113. https://doi.org/10.1103/PhysRevE.69.026113 * * * For the directed definition of modularity, see Leicht, E. A., and Newman, M. E. * J. (2008). Community Structure in Directed Networks. Physical Review Letters 100, * 118703. https://doi.org/10.1103/PhysRevLett.100.118703 * * * For the introduction of the resolution parameter, see Reichardt, J., and * Bornholdt, S. (2006). Statistical mechanics of community detection. Physical * Review E 74, 016110. https://doi.org/10.1103/PhysRevE.74.016110 * * \param graph The input graph. * \param membership Numeric vector of integer values which gives the type of each * vertex, i.e. the cluster to which it belongs. * It does not have to be consecutive, i.e. empty communities * are allowed. * \param weights Weight vector or \c NULL if no weights are specified. * \param resolution Resolution parameter. Must be greater than or equal to 0. * Set it to 1 to use the classical definition of modularity. * \param directed Whether to use the directed or undirected version of modularity. * Ignored for undirected graphs. * \param modularity Pointer to a real number, the result will be * stored here. * \return Error code. * * \sa \ref igraph_modularity_matrix() * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges. */ int igraph_modularity(const igraph_t *graph, const igraph_vector_t *membership, const igraph_vector_t *weights, const igraph_real_t resolution, const igraph_bool_t directed, igraph_real_t *modularity) { igraph_vector_t e, k_out, k_in; long int types; long int no_of_edges = igraph_ecount(graph); long int i; igraph_real_t m; long int c1, c2; /* Only consider the graph as directed if it actually is directed */ igraph_bool_t use_directed = directed && igraph_is_directed(graph); igraph_real_t directed_multiplier = (use_directed ? 1 : 2); if (igraph_vector_size(membership) != igraph_vcount(graph)) { IGRAPH_ERROR("Membership vector size differs from number of vertices.", IGRAPH_EINVAL); } if (resolution < 0.0) { IGRAPH_ERROR("The resolution parameter must be non-negative.", IGRAPH_EINVAL); } if (no_of_edges == 0) { /* Special case: the modularity of graphs with no edges is not * well-defined */ if (modularity) { *modularity = IGRAPH_NAN; } return IGRAPH_SUCCESS; } /* At this point, the 'membership' vector does not have length zero, thus it is safe to call igraph_vector_max() and min(). */ types = (long int) igraph_vector_max(membership) + 1; if (igraph_vector_min(membership) < 0) { IGRAPH_ERROR("Invalid membership vector: negative entry.", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&e, types); IGRAPH_VECTOR_INIT_FINALLY(&k_out, types); IGRAPH_VECTOR_INIT_FINALLY(&k_in, types); if (weights) { if (igraph_vector_size(weights) != no_of_edges) IGRAPH_ERROR("Vector size differs from number of edges.", IGRAPH_EINVAL); m = 0.0; for (i = 0; i < no_of_edges; i++) { igraph_real_t w = VECTOR(*weights)[i]; if (w < 0) { IGRAPH_ERROR("Negative weight in weight vector.", IGRAPH_EINVAL); } c1 = (long int) VECTOR(*membership)[ IGRAPH_FROM(graph, i) ]; c2 = (long int) VECTOR(*membership)[ IGRAPH_TO(graph, i) ]; if (c1 == c2) { VECTOR(e)[c1] += directed_multiplier * w; } VECTOR(k_out)[c1] += w; VECTOR(k_in)[c2] += w; m += w; } } else { m = no_of_edges; for (i = 0; i < no_of_edges; i++) { c1 = (long int) VECTOR(*membership)[ IGRAPH_FROM(graph, i) ]; c2 = (long int) VECTOR(*membership)[ IGRAPH_TO(graph, i) ]; if (c1 == c2) { VECTOR(e)[c1] += directed_multiplier; } VECTOR(k_out)[c1] += 1; VECTOR(k_in)[c2] += 1; } } if (!use_directed) { /* Graph is undirected, simply add vectors */ igraph_vector_add(&k_out, &k_in); igraph_vector_update(&k_in, &k_out); } /* Divide all vectors by total weight. */ igraph_vector_scale(&k_out, 1.0/( directed_multiplier * m ) ); igraph_vector_scale(&k_in, 1.0/( directed_multiplier * m ) ); igraph_vector_scale(&e, 1.0/( directed_multiplier * m ) ); *modularity = 0.0; if (m > 0) { for (i = 0; i < types; i++) { *modularity += VECTOR(e)[i]; *modularity -= resolution * VECTOR(k_out)[i] * VECTOR(k_in)[i]; } } igraph_vector_destroy(&e); igraph_vector_destroy(&k_out); igraph_vector_destroy(&k_in); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } static int igraph_i_modularity_matrix_get_adjacency( const igraph_t *graph, igraph_matrix_t *res, const igraph_vector_t *weights, igraph_bool_t directed) { /* Specifically used to handle weights and/or ignore direction */ igraph_eit_t edgeit; long int no_of_nodes = igraph_vcount(graph); igraph_integer_t from, to; IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, no_of_nodes)); igraph_matrix_null(res); IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID), &edgeit)); IGRAPH_FINALLY(igraph_eit_destroy, &edgeit); if (weights) { for (; !IGRAPH_EIT_END(edgeit); IGRAPH_EIT_NEXT(edgeit)) { igraph_integer_t edge = IGRAPH_EIT_GET(edgeit); from = IGRAPH_FROM(graph, edge); to = IGRAPH_TO(graph, edge); MATRIX(*res, from, to) += VECTOR(*weights)[edge]; if (!directed) { MATRIX(*res, to, from) += VECTOR(*weights)[edge]; } } } else { for (; !IGRAPH_EIT_END(edgeit); IGRAPH_EIT_NEXT(edgeit)) { igraph_integer_t edge = IGRAPH_EIT_GET(edgeit); igraph_edge(graph, edge, &from, &to); MATRIX(*res, from, to) += 1; if (!directed) { MATRIX(*res, to, from) += 1; } } } igraph_eit_destroy(&edgeit); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \function igraph_modularity_matrix * \brief Calculate the modularity matrix * * This function returns the modularity matrix defined as * * * B_ij = A_ij - gamma * k_i * k_j / (2m) * * * for undirected graphs, where \c A_ij is the adjacency matrix, \c gamma is the * resolution parameter, \c k_i is the degree of vertex \c i, and \c m is the * number of edges in the graph. When there are no edges, or the weights add up * to zero, the result is undefined. * * * For directed graphs the modularity matrix is changed to * * * B_ij = A_ij - gamma * k^out_i * k^in_j / m * where k^out_i is the out-degree of node \c i and k^in_j is the * in-degree of node \c j. * * * Note that self-loops in undirected graphs are multiplied by 2 in this * implementation. If weights are specified, the weighted counterparts are used. * * \param graph The input graph. * \param weights Edge weights, pointer to a vector. If this is a null pointer * then every edge is assumed to have a weight of 1. * \param resolution Resolution parameter. Must be greater than or equal to 0. * Default is 1. Lower values favor fewer, larger communities; * higher values favor more, smaller communities. * \param modmat Pointer to an initialized matrix in which the modularity * matrix is stored. * \param directed For directed graphs: if the edges should be treated as * undirected. * For undirected graphs this is ignored. * * \sa \ref igraph_modularity() */ int igraph_modularity_matrix(const igraph_t *graph, const igraph_vector_t *weights, const igraph_real_t resolution, igraph_matrix_t *modmat, igraph_bool_t directed) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_real_t sw = weights ? igraph_vector_sum(weights) : no_of_edges; igraph_vector_t deg, deg_unscaled, in_deg, out_deg; long int i, j; igraph_real_t scaling_factor; if (weights && igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Invalid weight vector length.", IGRAPH_EINVAL); } if (resolution < 0.0) { IGRAPH_ERROR("The resolution parameter must be non-negative.", IGRAPH_EINVAL); } if (!igraph_is_directed(graph)) { directed = 0; } IGRAPH_CHECK(igraph_i_modularity_matrix_get_adjacency(graph, modmat, weights, directed)); if (directed) { IGRAPH_VECTOR_INIT_FINALLY(&in_deg, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&out_deg, no_of_nodes); if (!weights) { IGRAPH_CHECK(igraph_degree(graph, &in_deg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_degree(graph, &out_deg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); } else { IGRAPH_CHECK(igraph_strength(graph, &in_deg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS, weights)); IGRAPH_CHECK(igraph_strength(graph, &out_deg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS, weights)); } /* Scaling one degree factor so every element gets scaled. */ scaling_factor = resolution / sw; igraph_vector_scale(&out_deg, scaling_factor); for (j = 0; j < no_of_nodes; j++) { for (i = 0; i < no_of_nodes; i++) { MATRIX(*modmat, i, j) -= VECTOR(out_deg)[i] * VECTOR(in_deg)[j]; } } igraph_vector_destroy(&in_deg); igraph_vector_destroy(&out_deg); IGRAPH_FINALLY_CLEAN(2); } else { IGRAPH_VECTOR_INIT_FINALLY(°, no_of_nodes); if (!weights) { IGRAPH_CHECK(igraph_degree(graph, °, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS)); } else { IGRAPH_CHECK(igraph_strength(graph, °, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, weights)); } /* Scaling one degree factor so every element gets scaled. */ igraph_vector_copy(°_unscaled, °); IGRAPH_FINALLY(igraph_vector_destroy, °_unscaled); scaling_factor = resolution / 2.0 / sw; igraph_vector_scale(°, scaling_factor); for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < no_of_nodes; j++) { MATRIX(*modmat, i, j) -= VECTOR(deg)[i] * VECTOR(deg_unscaled)[j]; } } igraph_vector_destroy(°); igraph_vector_destroy(°_unscaled); IGRAPH_FINALLY_CLEAN(2); } return IGRAPH_SUCCESS; } leidenbase/src/core/community/community_misc.c0000644000176200001440000007465014447675374021354 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_constructors.h" #include "igraph_memory.h" #include "igraph_random.h" #include "igraph_arpack.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_components.h" #include "igraph_dqueue.h" #include "igraph_progress.h" #include "igraph_stack.h" #include "igraph_spmatrix.h" #include "igraph_statusbar.h" #include "igraph_conversion.h" #include "igraph_centrality.h" #include "igraph_structural.h" #include "core/indheap.h" #include "core/interruption.h" #include "config.h" #include #include /** * \function igraph_community_to_membership * \brief Create membership vector from community structure dendrogram * * This function creates a membership vector from a community * structure dendrogram. A membership vector contains for each vertex * the id of its graph component, the graph components are numbered * from zero, see the same argument of \ref igraph_clusters() for an * example of a membership vector. * * * Many community detection algorithms return with a \em merges * matrix, \ref igraph_community_walktrap() and \ref * igraph_community_edge_betweenness() are two examples. The matrix * contains the merge operations performed while mapping the * hierarchical structure of a network. If the matrix has \c n-1 rows, * where \c n is the number of vertices in the graph, then it contains * the hierarchical structure of the whole network and it is called a * dendrogram. * * * This function performs \p steps merge operations as prescribed by * the \p merges matrix and returns the current state of the network. * * * If \p merges is not a complete dendrogram, it is possible to * take \p steps steps if \p steps is not bigger than the number * lines in \p merges. * \param merges The two-column matrix containing the merge * operations. See \ref igraph_community_walktrap() for the * detailed syntax. * \param nodes The number of leaf nodes in the dendrogram. * \param steps Integer constant, the number of steps to take. * \param membership Pointer to an initialized vector, the membership * results will be stored here, if not NULL. The vector will be * resized as needed. * \param csize Pointer to an initialized vector, or NULL. If not NULL * then the sizes of the components will be stored here, the vector * will be resized as needed. * * \sa \ref igraph_community_walktrap(), \ref * igraph_community_edge_betweenness(), \ref * igraph_community_fastgreedy() for community structure detection * algorithms. * * Time complexity: O(|V|), the number of vertices in the graph. */ int igraph_community_to_membership(const igraph_matrix_t *merges, igraph_integer_t nodes, igraph_integer_t steps, igraph_vector_t *membership, igraph_vector_t *csize) { long int no_of_nodes = nodes; long int components = no_of_nodes - steps; long int i, found = 0; igraph_vector_t tmp; igraph_vector_bool_t already_merged; igraph_vector_t own_membership; igraph_bool_t using_own_membership = 0; if (steps > igraph_matrix_nrow(merges)) { IGRAPH_ERRORF("Number of steps is greater than number of rows in merges matrix: found %" IGRAPH_PRId " steps, %ld rows.", IGRAPH_EINVAL, steps, igraph_matrix_nrow(merges)); } if (igraph_matrix_ncol(merges) != 2) { IGRAPH_ERRORF("The merges matrix should have two columns, but has %ld.", IGRAPH_EINVAL, igraph_matrix_ncol(merges)); } if (steps < 0) { IGRAPH_ERRORF("Number of steps should be non-negative, found %" IGRAPH_PRId ".", IGRAPH_EINVAL, steps); } if (csize != 0 && membership == 0) { /* we need a membership vector to calculate 'csize' but the user did * not provide one; let's allocate one ourselves */ IGRAPH_VECTOR_INIT_FINALLY(&own_membership, no_of_nodes); using_own_membership = 1; membership = &own_membership; } if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); igraph_vector_null(membership); } if (csize) { IGRAPH_CHECK(igraph_vector_resize(csize, components)); igraph_vector_null(csize); } IGRAPH_VECTOR_BOOL_INIT_FINALLY(&already_merged, steps + no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&tmp, steps); for (i = steps - 1; i >= 0; i--) { long int c1 = (long int) MATRIX(*merges, i, 0); long int c2 = (long int) MATRIX(*merges, i, 1); if (VECTOR(already_merged)[c1] == 0) { VECTOR(already_merged)[c1] = 1; } else { IGRAPH_ERRORF("Merges matrix contains multiple merges of cluster %ld.", IGRAPH_EINVAL, c1); } if (VECTOR(already_merged)[c2] == 0) { VECTOR(already_merged)[c2] = 1; } else { IGRAPH_ERRORF("Merges matrix contains multiple merges of cluster %ld.", IGRAPH_EINVAL, c2); } /* new component? */ if (VECTOR(tmp)[i] == 0) { found++; VECTOR(tmp)[i] = found; } if (c1 < no_of_nodes) { long int cid = (long int) VECTOR(tmp)[i] - 1; if (membership) { VECTOR(*membership)[c1] = cid + 1; } if (csize) { VECTOR(*csize)[cid] += 1; } } else { VECTOR(tmp)[c1 - no_of_nodes] = VECTOR(tmp)[i]; } if (c2 < no_of_nodes) { long int cid = (long int) VECTOR(tmp)[i] - 1; if (membership) { VECTOR(*membership)[c2] = cid + 1; } if (csize) { VECTOR(*csize)[cid] += 1; } } else { VECTOR(tmp)[c2 - no_of_nodes] = VECTOR(tmp)[i]; } } if (membership || csize) { /* it can never happen that csize != 0 and membership == 0; we have * handled that case above */ for (i = 0; i < no_of_nodes; i++) { long int tmp = (long int) VECTOR(*membership)[i]; if (tmp != 0) { if (membership) { VECTOR(*membership)[i] = tmp - 1; } } else { if (csize) { VECTOR(*csize)[found] += 1; } if (membership) { VECTOR(*membership)[i] = found; } found++; } } } igraph_vector_destroy(&tmp); igraph_vector_bool_destroy(&already_merged); IGRAPH_FINALLY_CLEAN(2); if (using_own_membership) { igraph_vector_destroy(&own_membership); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_reindex_membership * \brief Makes the IDs in a membership vector continuous * * This function reindexes component IDs in a membership vector * in a way that the new IDs start from zero and go up to C-1, * where C is the number of unique component IDs in the original * vector. The supplied membership is expected to fall in the * range 0, ..., n - 1. * * \param membership Numeric vector which gives the type of each * vertex, i.e. the component to which it belongs. * The vector will be altered in-place. * \param new_to_old Pointer to a vector which will contain the * old component ID for each new one, or NULL, * in which case it is not returned. The vector * will be resized as needed. * \param nb_clusters Pointer to an integer for the number of * distinct clusters. If not NULL, this will be * updated to reflect the number of distinct * clusters found in membership. * * Time complexity: should be O(n) for n elements. */ int igraph_reindex_membership(igraph_vector_t *membership, igraph_vector_t *new_to_old, igraph_integer_t *nb_clusters) { long int i, n = igraph_vector_size(membership); igraph_vector_t new_cluster; igraph_integer_t i_nb_clusters; /* We allow original cluster indices in the range 0, ..., n - 1 */ IGRAPH_CHECK(igraph_vector_init(&new_cluster, n)); IGRAPH_FINALLY(igraph_vector_destroy, &new_cluster); if (new_to_old) { igraph_vector_clear(new_to_old); } /* Clean clusters. We will store the new cluster + 1 so that membership == 0 * indicates that no cluster was assigned yet. */ i_nb_clusters = 1; for (i = 0; i < n; i++) { long int c = (long int)VECTOR(*membership)[i]; if (c < 0) { IGRAPH_ERRORF("Membership indices should be non-negative. " "Found member of cluster %ld.", IGRAPH_EINVAL, c); } if (c >= n) { IGRAPH_ERRORF("Membership indices should be less than total number of vertices. " "Found member of cluster %ld, but only %ld vertices.", IGRAPH_EINVAL, c, n); } if (VECTOR(new_cluster)[c] == 0) { VECTOR(new_cluster)[c] = (igraph_real_t)i_nb_clusters; i_nb_clusters += 1; if (new_to_old) { IGRAPH_CHECK(igraph_vector_push_back(new_to_old, c)); } } } /* Assign new membership */ for (i = 0; i < n; i++) { long int c = (long int)VECTOR(*membership)[i]; VECTOR(*membership)[i] = VECTOR(new_cluster)[c] - 1; } if (nb_clusters) { /* We used the cluster + 1, so correct */ *nb_clusters = i_nb_clusters - 1; } igraph_vector_destroy(&new_cluster); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } static int igraph_i_compare_communities_vi(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_real_t* result); static int igraph_i_compare_communities_nmi(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_real_t* result); static int igraph_i_compare_communities_rand(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_real_t* result, igraph_bool_t adjust); static int igraph_i_split_join_distance(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_integer_t* distance12, igraph_integer_t* distance21); /** * \ingroup communities * \function igraph_compare_communities * \brief Compares community structures using various metrics * * This function assesses the distance between two community structures * using the variation of information (VI) metric of Meila (2003), the * normalized mutual information (NMI) of Danon et al (2005), the * split-join distance of van Dongen (2000), the Rand index of Rand (1971) * or the adjusted Rand index of Hubert and Arabie (1985). * * * References: * * * Meila M: Comparing clusterings by the variation of information. * In: Schölkopf B, Warmuth MK (eds.). Learning Theory and Kernel Machines: * 16th Annual Conference on Computational Learning Theory and 7th Kernel * Workshop, COLT/Kernel 2003, Washington, DC, USA. Lecture Notes in Computer * Science, vol. 2777, Springer, 2003. ISBN: 978-3-540-40720-1. * * * Danon L, Diaz-Guilera A, Duch J, Arenas A: Comparing community structure * identification. J Stat Mech P09008, 2005. * * * van Dongen S: Performance criteria for graph clustering and Markov cluster * experiments. Technical Report INS-R0012, National Research Institute for * Mathematics and Computer Science in the Netherlands, Amsterdam, May 2000. * * * Rand WM: Objective criteria for the evaluation of clustering methods. * J Am Stat Assoc 66(336):846-850, 1971. * * * Hubert L and Arabie P: Comparing partitions. Journal of Classification * 2:193-218, 1985. * * \param comm1 the membership vector of the first community structure * \param comm2 the membership vector of the second community structure * \param result the result is stored here. * \param method the comparison method to use. \c IGRAPH_COMMCMP_VI * selects the variation of information (VI) metric of * Meila (2003), \c IGRAPH_COMMCMP_NMI selects the * normalized mutual information measure proposed by * Danon et al (2005), \c IGRAPH_COMMCMP_SPLIT_JOIN * selects the split-join distance of van Dongen (2000), * \c IGRAPH_COMMCMP_RAND selects the unadjusted Rand * index (1971) and \c IGRAPH_COMMCMP_ADJUSTED_RAND * selects the adjusted Rand index. * * \return Error code. * * Time complexity: O(n log(n)). */ int igraph_compare_communities(const igraph_vector_t *comm1, const igraph_vector_t *comm2, igraph_real_t* result, igraph_community_comparison_t method) { igraph_vector_t c1, c2; if (igraph_vector_size(comm1) != igraph_vector_size(comm2)) { IGRAPH_ERROR("community membership vectors have different lengths", IGRAPH_EINVAL); } /* Copy and reindex membership vectors to make sure they are continuous */ IGRAPH_CHECK(igraph_vector_copy(&c1, comm1)); IGRAPH_FINALLY(igraph_vector_destroy, &c1); IGRAPH_CHECK(igraph_vector_copy(&c2, comm2)); IGRAPH_FINALLY(igraph_vector_destroy, &c2); IGRAPH_CHECK(igraph_reindex_membership(&c1, 0, NULL)); IGRAPH_CHECK(igraph_reindex_membership(&c2, 0, NULL)); switch (method) { case IGRAPH_COMMCMP_VI: IGRAPH_CHECK(igraph_i_compare_communities_vi(&c1, &c2, result)); break; case IGRAPH_COMMCMP_NMI: IGRAPH_CHECK(igraph_i_compare_communities_nmi(&c1, &c2, result)); break; case IGRAPH_COMMCMP_SPLIT_JOIN: { igraph_integer_t d12, d21; IGRAPH_CHECK(igraph_i_split_join_distance(&c1, &c2, &d12, &d21)); *result = d12 + d21; } break; case IGRAPH_COMMCMP_RAND: case IGRAPH_COMMCMP_ADJUSTED_RAND: IGRAPH_CHECK(igraph_i_compare_communities_rand(&c1, &c2, result, method == IGRAPH_COMMCMP_ADJUSTED_RAND)); break; default: IGRAPH_ERROR("unknown community comparison method", IGRAPH_EINVAL); } /* Clean up everything */ igraph_vector_destroy(&c1); igraph_vector_destroy(&c2); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \ingroup communities * \function igraph_split_join_distance * \brief Calculates the split-join distance of two community structures * * The split-join distance between partitions A and B is the sum of the * projection distance of A from B and the projection distance of B from * A. The projection distance is an asymmetric measure and it is defined * as follows: * * * First, each set in partition A is evaluated against all sets in partition * B. For each set in partition A, the best matching set in partition B is * found and the overlap size is calculated. (Matching is quantified by the * size of the overlap between the two sets). Then, the maximal overlap sizes * for each set in A are summed together and subtracted from the number of * elements in A. * * * The split-join distance will be returned in two arguments, \c distance12 * will contain the projection distance of the first partition from the * second, while \c distance21 will be the projection distance of the second * partition from the first. This makes it easier to detect whether a * partition is a subpartition of the other, since in this case, the * corresponding distance will be zero. * * * Reference: * * * van Dongen S: Performance criteria for graph clustering and Markov cluster * experiments. Technical Report INS-R0012, National Research Institute for * Mathematics and Computer Science in the Netherlands, Amsterdam, May 2000. * * \param comm1 the membership vector of the first community structure * \param comm2 the membership vector of the second community structure * \param distance12 pointer to an \c igraph_integer_t, the projection distance * of the first community structure from the second one will be * returned here. * \param distance21 pointer to an \c igraph_integer_t, the projection distance * of the second community structure from the first one will be * returned here. * \return Error code. * * \see \ref igraph_compare_communities() with the \c IGRAPH_COMMCMP_SPLIT_JOIN * method if you are not interested in the individual distances but only the sum * of them. * * Time complexity: O(n log(n)). */ int igraph_split_join_distance(const igraph_vector_t *comm1, const igraph_vector_t *comm2, igraph_integer_t *distance12, igraph_integer_t *distance21) { igraph_vector_t c1, c2; if (igraph_vector_size(comm1) != igraph_vector_size(comm2)) { IGRAPH_ERRORF("Community membership vectors have different lengths: %ld and %ld.", IGRAPH_EINVAL, igraph_vector_size(comm1), igraph_vector_size(comm2)); } /* Copy and reindex membership vectors to make sure they are continuous */ IGRAPH_CHECK(igraph_vector_copy(&c1, comm1)); IGRAPH_FINALLY(igraph_vector_destroy, &c1); IGRAPH_CHECK(igraph_vector_copy(&c2, comm2)); IGRAPH_FINALLY(igraph_vector_destroy, &c2); IGRAPH_CHECK(igraph_reindex_membership(&c1, 0, NULL)); IGRAPH_CHECK(igraph_reindex_membership(&c2, 0, NULL)); IGRAPH_CHECK(igraph_i_split_join_distance(&c1, &c2, distance12, distance21)); /* Clean up everything */ igraph_vector_destroy(&c1); igraph_vector_destroy(&c2); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * Calculates the entropy and the mutual information for two reindexed community * membership vectors v1 and v2. This is needed by both Meila's and Danon's * community comparison measure. */ static int igraph_i_entropy_and_mutual_information(const igraph_vector_t* v1, const igraph_vector_t* v2, double* h1, double* h2, double* mut_inf) { long int i, n; long int k1; long int k2; double *p1, *p2; igraph_spmatrix_t m; igraph_spmatrix_iter_t mit; n = igraph_vector_size(v1); if (n == 0) { *h1 = 0; *h2 = 0; *mut_inf = 0; return IGRAPH_SUCCESS; } k1 = (long int)igraph_vector_max(v1) + 1; k2 = (long int)igraph_vector_max(v2) + 1; p1 = IGRAPH_CALLOC(k1, double); if (p1 == 0) { IGRAPH_ERROR("igraph_i_entropy_and_mutual_information failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, p1); p2 = IGRAPH_CALLOC(k2, double); if (p2 == 0) { IGRAPH_ERROR("igraph_i_entropy_and_mutual_information failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, p2); /* Calculate the entropy of v1 */ *h1 = 0.0; for (i = 0; i < n; i++) { p1[(long int)VECTOR(*v1)[i]]++; } for (i = 0; i < k1; i++) { p1[i] /= n; *h1 -= p1[i] * log(p1[i]); } /* Calculate the entropy of v2 */ *h2 = 0.0; for (i = 0; i < n; i++) { p2[(long int)VECTOR(*v2)[i]]++; } for (i = 0; i < k2; i++) { p2[i] /= n; *h2 -= p2[i] * log(p2[i]); } /* We will only need the logs of p1 and p2 from now on */ for (i = 0; i < k1; i++) { p1[i] = log(p1[i]); } for (i = 0; i < k2; i++) { p2[i] = log(p2[i]); } /* Calculate the mutual information of v1 and v2 */ *mut_inf = 0.0; IGRAPH_CHECK(igraph_spmatrix_init(&m, k1, k2)); IGRAPH_FINALLY(igraph_spmatrix_destroy, &m); for (i = 0; i < n; i++) { IGRAPH_CHECK(igraph_spmatrix_add_e(&m, (int)VECTOR(*v1)[i], (int)VECTOR(*v2)[i], 1)); } IGRAPH_CHECK(igraph_spmatrix_iter_create(&mit, &m)); IGRAPH_FINALLY(igraph_spmatrix_iter_destroy, &mit); while (!igraph_spmatrix_iter_end(&mit)) { double p = mit.value / n; *mut_inf += p * (log(p) - p1[mit.ri] - p2[mit.ci]); igraph_spmatrix_iter_next(&mit); } igraph_spmatrix_iter_destroy(&mit); igraph_spmatrix_destroy(&m); IGRAPH_FREE(p1); IGRAPH_FREE(p2); IGRAPH_FINALLY_CLEAN(4); return 0; } /** * Implementation of the normalized mutual information (NMI) measure of * Danon et al. This function assumes that the community membership * vectors have already been normalized using igraph_reindex_communities(). * * * Reference: Danon L, Diaz-Guilera A, Duch J, Arenas A: Comparing community * structure identification. J Stat Mech P09008, 2005. * * * Time complexity: O(n log(n)) */ static int igraph_i_compare_communities_nmi(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_real_t* result) { double h1, h2, mut_inf; IGRAPH_CHECK(igraph_i_entropy_and_mutual_information(v1, v2, &h1, &h2, &mut_inf)); if (h1 == 0 && h2 == 0) { *result = 1; } else { *result = 2 * mut_inf / (h1 + h2); } return IGRAPH_SUCCESS; } /** * Implementation of the variation of information metric (VI) of * Meila et al. This function assumes that the community membership * vectors have already been normalized using igraph_reindex_communities(). * * * Reference: Meila M: Comparing clusterings by the variation of information. * In: Schölkopf B, Warmuth MK (eds.). Learning Theory and Kernel Machines: * 16th Annual Conference on Computational Learning Theory and 7th Kernel * Workshop, COLT/Kernel 2003, Washington, DC, USA. Lecture Notes in Computer * Science, vol. 2777, Springer, 2003. ISBN: 978-3-540-40720-1. * * * Time complexity: O(n log(n)) */ static int igraph_i_compare_communities_vi(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_real_t* result) { double h1, h2, mut_inf; IGRAPH_CHECK(igraph_i_entropy_and_mutual_information(v1, v2, &h1, &h2, &mut_inf)); *result = h1 + h2 - 2 * mut_inf; return IGRAPH_SUCCESS; } /** * \brief Calculates the confusion matrix for two clusterings. * * * This function assumes that the community membership vectors have already * been normalized using igraph_reindex_communities(). * * * Time complexity: O(n log(max(k1, k2))), where n is the number of vertices, k1 * and k2 are the number of clusters in each of the clusterings. */ static int igraph_i_confusion_matrix(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_spmatrix_t *m) { long int k1; long int k2; long int i, n; n = igraph_vector_size(v1); if (n == 0 ) { IGRAPH_CHECK(igraph_spmatrix_resize(m, 0, 0)); return IGRAPH_SUCCESS; } k1 = (long int)igraph_vector_max(v1) + 1; k2 = (long int)igraph_vector_max(v2) + 1; IGRAPH_CHECK(igraph_spmatrix_resize(m, k1, k2)); for (i = 0; i < n; i++) { IGRAPH_CHECK(igraph_spmatrix_add_e(m, (int)VECTOR(*v1)[i], (int)VECTOR(*v2)[i], 1)); } return IGRAPH_SUCCESS; } /** * Implementation of the split-join distance of van Dongen. * * * This function assumes that the community membership vectors have already * been normalized using igraph_reindex_communities(). * * * Reference: van Dongen S: Performance criteria for graph clustering and Markov * cluster experiments. Technical Report INS-R0012, National Research Institute * for Mathematics and Computer Science in the Netherlands, Amsterdam, May 2000. * * * Time complexity: O(n log(max(k1, k2))), where n is the number of vertices, k1 * and k2 are the number of clusters in each of the clusterings. */ static int igraph_i_split_join_distance(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_integer_t* distance12, igraph_integer_t* distance21) { long int n = igraph_vector_size(v1); igraph_vector_t rowmax, colmax; igraph_spmatrix_t m; igraph_spmatrix_iter_t mit; if (n == 0) { *distance12 = 0; *distance21 = 0; return IGRAPH_SUCCESS; } /* Calculate the confusion matrix */ IGRAPH_CHECK(igraph_spmatrix_init(&m, 1, 1)); IGRAPH_FINALLY(igraph_spmatrix_destroy, &m); IGRAPH_CHECK(igraph_i_confusion_matrix(v1, v2, &m)); /* Initialize vectors that will store the row/columnwise maxima */ IGRAPH_VECTOR_INIT_FINALLY(&rowmax, igraph_spmatrix_nrow(&m)); IGRAPH_VECTOR_INIT_FINALLY(&colmax, igraph_spmatrix_ncol(&m)); /* Find the row/columnwise maxima */ IGRAPH_CHECK(igraph_spmatrix_iter_create(&mit, &m)); IGRAPH_FINALLY(igraph_spmatrix_iter_destroy, &mit); while (!igraph_spmatrix_iter_end(&mit)) { if (mit.value > VECTOR(rowmax)[mit.ri]) { VECTOR(rowmax)[mit.ri] = mit.value; } if (mit.value > VECTOR(colmax)[mit.ci]) { VECTOR(colmax)[mit.ci] = mit.value; } igraph_spmatrix_iter_next(&mit); } igraph_spmatrix_iter_destroy(&mit); IGRAPH_FINALLY_CLEAN(1); /* Calculate the distances */ *distance12 = (igraph_integer_t) (n - igraph_vector_sum(&rowmax)); *distance21 = (igraph_integer_t) (n - igraph_vector_sum(&colmax)); igraph_vector_destroy(&rowmax); igraph_vector_destroy(&colmax); igraph_spmatrix_destroy(&m); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /** * Implementation of the adjusted and unadjusted Rand indices. * * * This function assumes that the community membership vectors have already * been normalized using igraph_reindex_communities(). * * * References: * * * Rand WM: Objective criteria for the evaluation of clustering methods. J Am * Stat Assoc 66(336):846-850, 1971. * * * Hubert L and Arabie P: Comparing partitions. Journal of Classification * 2:193-218, 1985. * * * Time complexity: O(n log(max(k1, k2))), where n is the number of vertices, k1 * and k2 are the number of clusters in each of the clusterings. */ static int igraph_i_compare_communities_rand( const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_real_t *result, igraph_bool_t adjust) { igraph_spmatrix_t m; igraph_spmatrix_iter_t mit; igraph_vector_t rowsums, colsums; long int i, nrow, ncol; double rand, n; double frac_pairs_in_1, frac_pairs_in_2; if (igraph_vector_size(v1) <= 1) { IGRAPH_ERRORF("Rand indices not defined for only zero or one vertices. " "Found membership vector of size %ld", IGRAPH_EINVAL, igraph_vector_size(v1)); } /* Calculate the confusion matrix */ IGRAPH_CHECK(igraph_spmatrix_init(&m, 1, 1)); IGRAPH_FINALLY(igraph_spmatrix_destroy, &m); IGRAPH_CHECK(igraph_i_confusion_matrix(v1, v2, &m)); /* The unadjusted Rand index is defined as (a+d) / (a+b+c+d), where: * * - a is the number of pairs in the same cluster both in v1 and v2. This * equals the sum of n(i,j) choose 2 for all i and j. * * - b is the number of pairs in the same cluster in v1 and in different * clusters in v2. This is sum n(i,*) choose 2 for all i minus a. * n(i,*) is the number of elements in cluster i in v1. * * - c is the number of pairs in the same cluster in v2 and in different * clusters in v1. This is sum n(*,j) choose 2 for all j minus a. * n(*,j) is the number of elements in cluster j in v2. * * - d is (n choose 2) - a - b - c. * * Therefore, a+d = (n choose 2) - b - c * = (n choose 2) - sum (n(i,*) choose 2) * - sum (n(*,j) choose 2) * + 2 * sum (n(i,j) choose 2). * * Since a+b+c+d = (n choose 2) and this goes in the denominator, we can * just as well start dividing each term in a+d by (n choose 2), which * yields: * * 1 - sum( n(i,*)/n * (n(i,*)-1)/(n-1) ) * - sum( n(*,i)/n * (n(*,i)-1)/(n-1) ) * + sum( n(i,j)/n * (n(i,j)-1)/(n-1) ) * 2 */ /* Calculate row and column sums */ nrow = igraph_spmatrix_nrow(&m); ncol = igraph_spmatrix_ncol(&m); n = igraph_vector_size(v1) + 0.0; IGRAPH_VECTOR_INIT_FINALLY(&rowsums, nrow); IGRAPH_VECTOR_INIT_FINALLY(&colsums, ncol); IGRAPH_CHECK(igraph_spmatrix_rowsums(&m, &rowsums)); IGRAPH_CHECK(igraph_spmatrix_colsums(&m, &colsums)); /* Start calculating the unadjusted Rand index */ rand = 0.0; IGRAPH_CHECK(igraph_spmatrix_iter_create(&mit, &m)); IGRAPH_FINALLY(igraph_spmatrix_iter_destroy, &mit); while (!igraph_spmatrix_iter_end(&mit)) { rand += (mit.value / n) * (mit.value - 1) / (n - 1); igraph_spmatrix_iter_next(&mit); } igraph_spmatrix_iter_destroy(&mit); IGRAPH_FINALLY_CLEAN(1); frac_pairs_in_1 = frac_pairs_in_2 = 0.0; for (i = 0; i < nrow; i++) { frac_pairs_in_1 += (VECTOR(rowsums)[i] / n) * (VECTOR(rowsums)[i] - 1) / (n - 1); } for (i = 0; i < ncol; i++) { frac_pairs_in_2 += (VECTOR(colsums)[i] / n) * (VECTOR(colsums)[i] - 1) / (n - 1); } rand = 1.0 + 2 * rand - frac_pairs_in_1 - frac_pairs_in_2; if (adjust) { double expected = frac_pairs_in_1 * frac_pairs_in_2 + (1 - frac_pairs_in_1) * (1 - frac_pairs_in_2); rand = (rand - expected) / (1 - expected); } igraph_vector_destroy(&rowsums); igraph_vector_destroy(&colsums); igraph_spmatrix_destroy(&m); IGRAPH_FINALLY_CLEAN(3); *result = rand; return IGRAPH_SUCCESS; } leidenbase/src/core/linalg/0000755000176200001440000000000014532173045015336 5ustar liggesusersleidenbase/src/core/linalg/eigen.c0000644000176200001440000014415614447675375016626 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_eigen.h" #include "igraph_qsort.h" #include "igraph_blas.h" #include "igraph_interface.h" #include "igraph_adjlist.h" #include #include #include static int igraph_i_eigen_arpackfun_to_mat(igraph_arpack_function_t *fun, int n, void *extra, igraph_matrix_t *res) { int i; igraph_vector_t v; IGRAPH_CHECK(igraph_matrix_init(res, n, n)); IGRAPH_FINALLY(igraph_matrix_destroy, res); IGRAPH_VECTOR_INIT_FINALLY(&v, n); VECTOR(v)[0] = 1; IGRAPH_CHECK(fun(/*to=*/ &MATRIX(*res, 0, 0), /*from=*/ VECTOR(v), n, extra)); for (i = 1; i < n; i++) { VECTOR(v)[i - 1] = 0; VECTOR(v)[i ] = 1; IGRAPH_CHECK(fun(/*to=*/ &MATRIX(*res, 0, i), /*from=*/ VECTOR(v), n, extra)); } igraph_vector_destroy(&v); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_eigen_matrix_symmetric_lapack_lm(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_t *values, igraph_matrix_t *vectors) { igraph_matrix_t vec1, vec2; igraph_vector_t val1, val2; int n = (int) igraph_matrix_nrow(A); int p1 = 0, p2 = which->howmany - 1, pr = 0; IGRAPH_VECTOR_INIT_FINALLY(&val1, 0); IGRAPH_VECTOR_INIT_FINALLY(&val2, 0); if (vectors) { IGRAPH_CHECK(igraph_matrix_init(&vec1, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, &vec1); IGRAPH_CHECK(igraph_matrix_init(&vec2, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, &vec1); } IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_SELECT, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ 1, /*iu=*/ which->howmany, /*abstol=*/ 1e-14, &val1, vectors ? &vec1 : 0, /*support=*/ 0)); IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_SELECT, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ n - which->howmany + 1, /*iu=*/ n, /*abstol=*/ 1e-14, &val2, vectors ? &vec2 : 0, /*support=*/ 0)); if (values) { IGRAPH_CHECK(igraph_vector_resize(values, which->howmany)); } if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, which->howmany)); } while (pr < which->howmany) { if (p2 < 0 || fabs(VECTOR(val1)[p1]) > fabs(VECTOR(val2)[p2])) { if (values) { VECTOR(*values)[pr] = VECTOR(val1)[p1]; } if (vectors) { memcpy(&MATRIX(*vectors, 0, pr), &MATRIX(vec1, 0, p1), sizeof(igraph_real_t) * (size_t) n); } p1++; pr++; } else { if (values) { VECTOR(*values)[pr] = VECTOR(val2)[p2]; } if (vectors) { memcpy(&MATRIX(*vectors, 0, pr), &MATRIX(vec2, 0, p2), sizeof(igraph_real_t) * (size_t) n); } p2--; pr++; } } if (vectors) { igraph_matrix_destroy(&vec2); igraph_matrix_destroy(&vec1); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_destroy(&val2); igraph_vector_destroy(&val1); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_eigen_matrix_symmetric_lapack_sm(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_t *values, igraph_matrix_t *vectors) { igraph_vector_t val; igraph_matrix_t vec; int i, w = 0, n = (int) igraph_matrix_nrow(A); igraph_real_t small; int p1, p2, pr = 0; IGRAPH_VECTOR_INIT_FINALLY(&val, 0); if (vectors) { IGRAPH_MATRIX_INIT_FINALLY(&vec, 0, 0); } IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_ALL, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ 0, /*iu=*/ 0, /*abstol=*/ 1e-14, &val, vectors ? &vec : 0, /*support=*/ 0)); /* Look for smallest value */ small = fabs(VECTOR(val)[0]); for (i = 1; i < n; i++) { igraph_real_t v = fabs(VECTOR(val)[i]); if (v < small) { small = v; w = i; } } p1 = w - 1; p2 = w; if (values) { IGRAPH_CHECK(igraph_vector_resize(values, which->howmany)); } if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, which->howmany)); } while (pr < which->howmany) { if (p2 == n - 1 || fabs(VECTOR(val)[p1]) < fabs(VECTOR(val)[p2])) { if (values) { VECTOR(*values)[pr] = VECTOR(val)[p1]; } if (vectors) { memcpy(&MATRIX(*vectors, 0, pr), &MATRIX(vec, 0, p1), sizeof(igraph_real_t) * (size_t) n); } p1--; pr++; } else { if (values) { VECTOR(*values)[pr] = VECTOR(val)[p2]; } if (vectors) { memcpy(&MATRIX(*vectors, 0, pr), &MATRIX(vec, 0, p2), sizeof(igraph_real_t) * (size_t) n); } p2++; pr++; } } if (vectors) { igraph_matrix_destroy(&vec); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&val); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_eigen_matrix_symmetric_lapack_la(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_t *values, igraph_matrix_t *vectors) { /* TODO: ordering? */ int n = (int) igraph_matrix_nrow(A); int il = n - which->howmany + 1; IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_SELECT, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ il, /*iu=*/ n, /*abstol=*/ 1e-14, values, vectors, /*support=*/ 0)); return 0; } static int igraph_i_eigen_matrix_symmetric_lapack_sa(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_t *values, igraph_matrix_t *vectors) { /* TODO: ordering? */ IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_SELECT, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ 1, /*iu=*/ which->howmany, /*abstol=*/ 1e-14, values, vectors, /*support=*/ 0)); return 0; } static int igraph_i_eigen_matrix_symmetric_lapack_be(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_t *values, igraph_matrix_t *vectors) { /* TODO: ordering? */ igraph_matrix_t vec1, vec2; igraph_vector_t val1, val2; int n = (int) igraph_matrix_nrow(A); int p1 = 0, p2 = which->howmany / 2, pr = 0; IGRAPH_VECTOR_INIT_FINALLY(&val1, 0); IGRAPH_VECTOR_INIT_FINALLY(&val2, 0); if (vectors) { IGRAPH_CHECK(igraph_matrix_init(&vec1, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, &vec1); IGRAPH_CHECK(igraph_matrix_init(&vec2, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, &vec1); } IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_SELECT, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ 1, /*iu=*/ (which->howmany) / 2, /*abstol=*/ 1e-14, &val1, vectors ? &vec1 : 0, /*support=*/ 0)); IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_SELECT, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ n - (which->howmany) / 2, /*iu=*/ n, /*abstol=*/ 1e-14, &val2, vectors ? &vec2 : 0, /*support=*/ 0)); if (values) { IGRAPH_CHECK(igraph_vector_resize(values, which->howmany)); } if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, which->howmany)); } while (pr < which->howmany) { if (pr % 2) { if (values) { VECTOR(*values)[pr] = VECTOR(val1)[p1]; } if (vectors) { memcpy(&MATRIX(*vectors, 0, pr), &MATRIX(vec1, 0, p1), sizeof(igraph_real_t) * (size_t) n); } p1++; pr++; } else { if (values) { VECTOR(*values)[pr] = VECTOR(val2)[p2]; } if (vectors) { memcpy(&MATRIX(*vectors, 0, pr), &MATRIX(vec2, 0, p2), sizeof(igraph_real_t) * (size_t) n); } p2--; pr++; } } if (vectors) { igraph_matrix_destroy(&vec2); igraph_matrix_destroy(&vec1); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_destroy(&val2); igraph_vector_destroy(&val1); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_eigen_matrix_symmetric_lapack_all(const igraph_matrix_t *A, igraph_vector_t *values, igraph_matrix_t *vectors) { IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_ALL, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ 0, /*iu=*/ 0, /*abstol=*/ 1e-14, values, vectors, /*support=*/ 0)); return 0; } static int igraph_i_eigen_matrix_symmetric_lapack_iv(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_t *values, igraph_matrix_t *vectors) { IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_INTERVAL, /*vl=*/ which->vl, /*vu=*/ which->vu, /*vestimate=*/ which->vestimate, /*il=*/ 0, /*iu=*/ 0, /*abstol=*/ 1e-14, values, vectors, /*support=*/ 0)); return 0; } static int igraph_i_eigen_matrix_symmetric_lapack_sel(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_t *values, igraph_matrix_t *vectors) { IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_SELECT, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ which->il, /*iu=*/ which->iu, /*abstol=*/ 1e-14, values, vectors, /*support=*/ 0)); return 0; } static int igraph_i_eigen_matrix_symmetric_lapack(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n, void *extra, const igraph_eigen_which_t *which, igraph_vector_t *values, igraph_matrix_t *vectors) { const igraph_matrix_t *myA = A; igraph_matrix_t mA; /* First we need to create a dense square matrix */ if (A) { n = (int) igraph_matrix_nrow(A); } else if (sA) { n = (int) igraph_sparsemat_nrow(sA); IGRAPH_CHECK(igraph_matrix_init(&mA, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, &mA); IGRAPH_CHECK(igraph_sparsemat_as_matrix(&mA, sA)); myA = &mA; } else if (fun) { IGRAPH_CHECK(igraph_i_eigen_arpackfun_to_mat(fun, n, extra, &mA)); IGRAPH_FINALLY(igraph_matrix_destroy, &mA); myA = &mA; } switch (which->pos) { case IGRAPH_EIGEN_LM: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack_lm(myA, which, values, vectors)); break; case IGRAPH_EIGEN_SM: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack_sm(myA, which, values, vectors)); break; case IGRAPH_EIGEN_LA: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack_la(myA, which, values, vectors)); break; case IGRAPH_EIGEN_SA: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack_sa(myA, which, values, vectors)); break; case IGRAPH_EIGEN_BE: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack_be(myA, which, values, vectors)); break; case IGRAPH_EIGEN_ALL: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack_all(myA, values, vectors)); break; case IGRAPH_EIGEN_INTERVAL: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack_iv(myA, which, values, vectors)); break; case IGRAPH_EIGEN_SELECT: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack_sel(myA, which, values, vectors)); break; default: /* This cannot happen */ break; } if (!A) { igraph_matrix_destroy(&mA); IGRAPH_FINALLY_CLEAN(1); } return 0; } typedef struct igraph_i_eigen_matrix_sym_arpack_data_t { const igraph_matrix_t *A; const igraph_sparsemat_t *sA; } igraph_i_eigen_matrix_sym_arpack_data_t; static int igraph_i_eigen_matrix_sym_arpack_cb(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_eigen_matrix_sym_arpack_data_t *data = (igraph_i_eigen_matrix_sym_arpack_data_t *) extra; if (data->A) { igraph_blas_dgemv_array(/*transpose=*/ 0, /*alpha=*/ 1.0, data->A, from, /*beta=*/ 0.0, to); } else { /* data->sA */ igraph_vector_t vto, vfrom; igraph_vector_view(&vto, to, n); igraph_vector_view(&vfrom, from, n); igraph_vector_null(&vto); igraph_sparsemat_gaxpy(data->sA, &vfrom, &vto); } return 0; } static int igraph_i_eigen_matrix_symmetric_arpack_be(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n, void *extra, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors) { igraph_vector_t tmpvalues, tmpvalues2; igraph_matrix_t tmpvectors, tmpvectors2; int low = (int) floor(which->howmany / 2.0), high = (int) ceil(which->howmany / 2.0); int l1, l2, w; igraph_i_eigen_matrix_sym_arpack_data_t myextra; myextra.A = A; myextra.sA = sA; if (low + high >= n) { IGRAPH_ERROR("Requested too many eigenvalues/vectors", IGRAPH_EINVAL); } if (!fun) { fun = igraph_i_eigen_matrix_sym_arpack_cb; extra = (void*) &myextra; } IGRAPH_VECTOR_INIT_FINALLY(&tmpvalues, high); IGRAPH_MATRIX_INIT_FINALLY(&tmpvectors, n, high); IGRAPH_VECTOR_INIT_FINALLY(&tmpvalues2, low); IGRAPH_MATRIX_INIT_FINALLY(&tmpvectors2, n, low); options->n = n; options->nev = high; options->ncv = 2 * options->nev < n ? 2 * options->nev : n; options->which[0] = 'L'; options->which[1] = 'A'; IGRAPH_CHECK(igraph_arpack_rssolve(fun, extra, options, storage, &tmpvalues, &tmpvectors)); options->nev = low; options->ncv = 2 * options->nev < n ? 2 * options->nev : n; options->which[0] = 'S'; options->which[1] = 'A'; IGRAPH_CHECK(igraph_arpack_rssolve(fun, extra, options, storage, &tmpvalues2, &tmpvectors2)); IGRAPH_CHECK(igraph_vector_resize(values, low + high)); IGRAPH_CHECK(igraph_matrix_resize(vectors, n, low + high)); l1 = 0; l2 = 0; w = 0; while (w < which->howmany) { VECTOR(*values)[w] = VECTOR(tmpvalues)[l1]; memcpy(&MATRIX(*vectors, 0, w), &MATRIX(tmpvectors, 0, l1), (size_t) n * sizeof(igraph_real_t)); w++; l1++; if (w < which->howmany) { VECTOR(*values)[w] = VECTOR(tmpvalues2)[l2]; memcpy(&MATRIX(*vectors, 0, w), &MATRIX(tmpvectors2, 0, l2), (size_t) n * sizeof(igraph_real_t)); w++; l2++; } } igraph_matrix_destroy(&tmpvectors2); igraph_vector_destroy(&tmpvalues2); igraph_matrix_destroy(&tmpvectors); igraph_vector_destroy(&tmpvalues); IGRAPH_FINALLY_CLEAN(4); return 0; } static int igraph_i_eigen_matrix_symmetric_arpack(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n, void *extra, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors) { /* For ARPACK we need a matrix multiplication operation. This can be done in any format, so everything is fine, we don't have to convert. */ igraph_i_eigen_matrix_sym_arpack_data_t myextra; myextra.A = A; myextra.sA = sA; if (!options) { IGRAPH_ERROR("`options' must be given for ARPACK algorithm", IGRAPH_EINVAL); } if (which->pos == IGRAPH_EIGEN_BE) { return igraph_i_eigen_matrix_symmetric_arpack_be(A, sA, fun, n, extra, which, options, storage, values, vectors); } else { switch (which->pos) { case IGRAPH_EIGEN_LM: options->which[0] = 'L'; options->which[1] = 'M'; options->nev = which->howmany; break; case IGRAPH_EIGEN_SM: options->which[0] = 'S'; options->which[1] = 'M'; options->nev = which->howmany; break; case IGRAPH_EIGEN_LA: options->which[0] = 'L'; options->which[1] = 'A'; options->nev = which->howmany; break; case IGRAPH_EIGEN_SA: options->which[0] = 'S'; options->which[1] = 'A'; options->nev = which->howmany; break; case IGRAPH_EIGEN_ALL: options->which[0] = 'L'; options->which[1] = 'M'; options->nev = n; break; case IGRAPH_EIGEN_INTERVAL: IGRAPH_ERROR("Interval of eigenvectors with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_SELECT: IGRAPH_ERROR("Selected eigenvalues with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; default: /* This cannot happen */ break; } options->n = n; options->ncv = 2 * options->nev < n ? 2 * options->nev : n; if (!fun) { fun = igraph_i_eigen_matrix_sym_arpack_cb; extra = (void*) &myextra; } IGRAPH_CHECK(igraph_arpack_rssolve(fun, extra, options, storage, values, vectors)); return 0; } } /* Get the eigenvalues and the eigenvectors from the compressed form. Order them according to the ordering criteria. Comparison functions for the reordering first */ typedef int (*igraph_i_eigen_matrix_lapack_cmp_t)(void*, const void*, const void *); typedef struct igraph_i_eml_cmp_t { const igraph_vector_t *mag, *real, *imag; } igraph_i_eml_cmp_t; /* TODO: these should be defined in some header */ #define EPS (DBL_EPSILON*100) #define LESS(a,b) ((a) < (b)-EPS) #define MORE(a,b) ((a) > (b)+EPS) #define ZERO(a) ((a) > -EPS && (a) < EPS) #define NONZERO(a) ((a) < -EPS || (a) > EPS) /* Largest magnitude. Ordering is according to 1 Larger magnitude 2 Real eigenvalues before complex ones 3 Larger real part 4 Larger imaginary part */ static int igraph_i_eigen_matrix_lapack_cmp_lm(void *extra, const void *a, const void *b) { igraph_i_eml_cmp_t *myextra = (igraph_i_eml_cmp_t *) extra; int *aa = (int*) a, *bb = (int*) b; igraph_real_t a_m = VECTOR(*myextra->mag)[*aa]; igraph_real_t b_m = VECTOR(*myextra->mag)[*bb]; if (LESS(a_m, b_m)) { return 1; } else if (MORE(a_m, b_m)) { return -1; } else { igraph_real_t a_r = VECTOR(*myextra->real)[*aa]; igraph_real_t a_i = VECTOR(*myextra->imag)[*aa]; igraph_real_t b_r = VECTOR(*myextra->real)[*bb]; igraph_real_t b_i = VECTOR(*myextra->imag)[*bb]; if (ZERO(a_i) && NONZERO(b_i)) { return -1; } if (NONZERO(a_i) && ZERO(b_i)) { return 1; } if (MORE(a_r, b_r)) { return -1; } if (LESS(a_r, b_r)) { return 1; } if (MORE(a_i, b_i)) { return -1; } if (LESS(a_i, b_i)) { return 1; } } return 0; } /* Smallest marginude. Ordering is according to 1 Magnitude (smaller first) 2 Complex eigenvalues before real ones 3 Smaller real part 4 Smaller imaginary part This ensures that lm has exactly the opposite order to sm */ static int igraph_i_eigen_matrix_lapack_cmp_sm(void *extra, const void *a, const void *b) { igraph_i_eml_cmp_t *myextra = (igraph_i_eml_cmp_t *) extra; int *aa = (int*) a, *bb = (int*) b; igraph_real_t a_m = VECTOR(*myextra->mag)[*aa]; igraph_real_t b_m = VECTOR(*myextra->mag)[*bb]; if (MORE(a_m, b_m)) { return 1; } else if (LESS(a_m, b_m)) { return -1; } else { igraph_real_t a_r = VECTOR(*myextra->real)[*aa]; igraph_real_t a_i = VECTOR(*myextra->imag)[*aa]; igraph_real_t b_r = VECTOR(*myextra->real)[*bb]; igraph_real_t b_i = VECTOR(*myextra->imag)[*bb]; if (NONZERO(a_i) && ZERO(b_i)) { return -1; } if (ZERO(a_i) && NONZERO(b_i)) { return 1; } if (LESS(a_r, b_r)) { return -1; } if (MORE(a_r, b_r)) { return 1; } if (LESS(a_i, b_i)) { return -1; } if (MORE(a_i, b_i)) { return 1; } } return 0; } /* Largest real part. Ordering is according to 1 Larger real part 2 Real eigenvalues come before complex ones 3 Larger complex part */ static int igraph_i_eigen_matrix_lapack_cmp_lr(void *extra, const void *a, const void *b) { igraph_i_eml_cmp_t *myextra = (igraph_i_eml_cmp_t *) extra; int *aa = (int*) a, *bb = (int*) b; igraph_real_t a_r = VECTOR(*myextra->real)[*aa]; igraph_real_t b_r = VECTOR(*myextra->real)[*bb]; if (MORE(a_r, b_r)) { return -1; } else if (LESS(a_r, b_r)) { return 1; } else { igraph_real_t a_i = VECTOR(*myextra->imag)[*aa]; igraph_real_t b_i = VECTOR(*myextra->imag)[*bb]; if (ZERO(a_i) && NONZERO(b_i)) { return -1; } if (NONZERO(a_i) && ZERO(b_i)) { return 1; } if (MORE(a_i, b_i)) { return -1; } if (LESS(a_i, b_i)) { return 1; } } return 0; } /* Largest real part. Ordering is according to 1 Smaller real part 2 Complex eigenvalues come before real ones 3 Smaller complex part This is opposite to LR */ static int igraph_i_eigen_matrix_lapack_cmp_sr(void *extra, const void *a, const void *b) { igraph_i_eml_cmp_t *myextra = (igraph_i_eml_cmp_t *) extra; int *aa = (int*) a, *bb = (int*) b; igraph_real_t a_r = VECTOR(*myextra->real)[*aa]; igraph_real_t b_r = VECTOR(*myextra->real)[*bb]; if (LESS(a_r, b_r)) { return -1; } else if (MORE(a_r, b_r)) { return 1; } else { igraph_real_t a_i = VECTOR(*myextra->imag)[*aa]; igraph_real_t b_i = VECTOR(*myextra->imag)[*bb]; if (NONZERO(a_i) && ZERO(b_i)) { return -1; } if (ZERO(a_i) && NONZERO(b_i)) { return 1; } if (LESS(a_i, b_i)) { return -1; } if (MORE(a_i, b_i)) { return 1; } } return 0; } /* Order: 1 Larger imaginary part 2 Real eigenvalues before complex ones 3 Larger real part */ static int igraph_i_eigen_matrix_lapack_cmp_li(void *extra, const void *a, const void *b) { igraph_i_eml_cmp_t *myextra = (igraph_i_eml_cmp_t *) extra; int *aa = (int*) a, *bb = (int*) b; igraph_real_t a_i = VECTOR(*myextra->imag)[*aa]; igraph_real_t b_i = VECTOR(*myextra->imag)[*bb]; if (MORE(a_i, b_i)) { return -1; } else if (LESS(a_i, b_i)) { return 1; } else { igraph_real_t a_r = VECTOR(*myextra->real)[*aa]; igraph_real_t b_r = VECTOR(*myextra->real)[*bb]; if (ZERO(a_i) && NONZERO(b_i)) { return -1; } if (NONZERO(a_i) && ZERO(b_i)) { return 1; } if (MORE(a_r, b_r)) { return -1; } if (LESS(a_r, b_r)) { return 1; } } return 0; } /* Order: 1 Smaller imaginary part 2 Complex eigenvalues before real ones 3 Smaller real part Order is opposite to LI */ static int igraph_i_eigen_matrix_lapack_cmp_si(void *extra, const void *a, const void *b) { igraph_i_eml_cmp_t *myextra = (igraph_i_eml_cmp_t *) extra; int *aa = (int*) a, *bb = (int*) b; igraph_real_t a_i = VECTOR(*myextra->imag)[*aa]; igraph_real_t b_i = VECTOR(*myextra->imag)[*bb]; if (LESS(a_i, b_i)) { return -1; } else if (MORE(a_i, b_i)) { return 1; } else { igraph_real_t a_r = VECTOR(*myextra->real)[*aa]; igraph_real_t b_r = VECTOR(*myextra->real)[*bb]; if (NONZERO(a_i) && ZERO(b_i)) { return -1; } if (ZERO(a_i) && NONZERO(b_i)) { return 1; } if (LESS(a_r, b_r)) { return -1; } if (MORE(a_r, b_r)) { return 1; } } return 0; } #undef EPS #undef LESS #undef MORE #undef ZERO #undef NONZERO #define INITMAG() \ do { \ int i; \ IGRAPH_VECTOR_INIT_FINALLY(&mag, nev); \ hasmag=1; \ for (i=0; ipos) { case IGRAPH_EIGEN_LM: INITMAG(); cmpfunc = igraph_i_eigen_matrix_lapack_cmp_lm; howmany = which->howmany; break; case IGRAPH_EIGEN_ALL: INITMAG(); cmpfunc = igraph_i_eigen_matrix_lapack_cmp_sm; howmany = nev; break; case IGRAPH_EIGEN_SM: INITMAG(); cmpfunc = igraph_i_eigen_matrix_lapack_cmp_sm; howmany = which->howmany; break; case IGRAPH_EIGEN_LR: cmpfunc = igraph_i_eigen_matrix_lapack_cmp_lr; howmany = which->howmany; break; case IGRAPH_EIGEN_SR: cmpfunc = igraph_i_eigen_matrix_lapack_cmp_sr; howmany = which->howmany; break; case IGRAPH_EIGEN_SELECT: INITMAG(); cmpfunc = igraph_i_eigen_matrix_lapack_cmp_sm; start = which->il - 1; howmany = which->iu - which->il + 1; break; case IGRAPH_EIGEN_LI: cmpfunc = igraph_i_eigen_matrix_lapack_cmp_li; howmany = which->howmany; break; case IGRAPH_EIGEN_SI: cmpfunc = igraph_i_eigen_matrix_lapack_cmp_si; howmany = which->howmany; break; case IGRAPH_EIGEN_INTERVAL: case IGRAPH_EIGEN_BE: default: IGRAPH_ERROR("Unimplemented eigenvalue ordering", IGRAPH_UNIMPLEMENTED); break; } for (i = 0; i < nev; i++) { VECTOR(idx)[i] = i; } igraph_qsort_r(VECTOR(idx), (size_t) nev, sizeof(VECTOR(idx)[0]), extra, cmpfunc); if (hasmag) { igraph_vector_destroy(&mag); IGRAPH_FINALLY_CLEAN(1); } if (values) { IGRAPH_CHECK(igraph_vector_complex_resize(values, howmany)); for (i = 0; i < howmany; i++) { int x = VECTOR(idx)[start + i]; VECTOR(*values)[i] = igraph_complex(VECTOR(*real)[x], VECTOR(*imag)[x]); } } if (vectors) { int n = (int) igraph_matrix_nrow(compressed); IGRAPH_CHECK(igraph_matrix_complex_resize(vectors, n, howmany)); for (i = 0; i < howmany; i++) { int j, x = VECTOR(idx)[start + i]; if (VECTOR(*imag)[x] == 0) { /* real eigenvalue */ for (j = 0; j < n; j++) { MATRIX(*vectors, j, i) = igraph_complex(MATRIX(*compressed, j, x), 0.0); } } else { /* complex eigenvalue */ int neg = 1, co = 0; if (VECTOR(*imag)[x] < 0) { neg = -1; co = 1; } for (j = 0; j < n; j++) { MATRIX(*vectors, j, i) = igraph_complex(MATRIX(*compressed, j, x - co), neg * MATRIX(*compressed, j, x + 1 - co)); } } } } igraph_vector_int_destroy(&idx); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_eigen_matrix_lapack_common(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { igraph_vector_t valuesreal, valuesimag; igraph_matrix_t vectorsright, *myvectors = vectors ? &vectorsright : 0; int n = (int) igraph_matrix_nrow(A); int info = 1; IGRAPH_VECTOR_INIT_FINALLY(&valuesreal, n); IGRAPH_VECTOR_INIT_FINALLY(&valuesimag, n); if (vectors) { IGRAPH_MATRIX_INIT_FINALLY(&vectorsright, n, n); } IGRAPH_CHECK(igraph_lapack_dgeev(A, &valuesreal, &valuesimag, /*vectorsleft=*/ 0, myvectors, &info)); IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_reorder(&valuesreal, &valuesimag, myvectors, which, values, vectors)); if (vectors) { igraph_matrix_destroy(&vectorsright); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&valuesimag); igraph_vector_destroy(&valuesreal); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_eigen_matrix_lapack_lm(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { return igraph_i_eigen_matrix_lapack_common(A, which, values, vectors); } static int igraph_i_eigen_matrix_lapack_sm(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { return igraph_i_eigen_matrix_lapack_common(A, which, values, vectors); } static int igraph_i_eigen_matrix_lapack_lr(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { return igraph_i_eigen_matrix_lapack_common(A, which, values, vectors); } static int igraph_i_eigen_matrix_lapack_sr(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { return igraph_i_eigen_matrix_lapack_common(A, which, values, vectors); } static int igraph_i_eigen_matrix_lapack_li(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { return igraph_i_eigen_matrix_lapack_common(A, which, values, vectors); } static int igraph_i_eigen_matrix_lapack_si(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { return igraph_i_eigen_matrix_lapack_common(A, which, values, vectors); } static int igraph_i_eigen_matrix_lapack_select(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { return igraph_i_eigen_matrix_lapack_common(A, which, values, vectors); } static int igraph_i_eigen_matrix_lapack_all(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { return igraph_i_eigen_matrix_lapack_common(A, which, values, vectors); } static int igraph_i_eigen_matrix_lapack(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n, void *extra, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { const igraph_matrix_t *myA = A; igraph_matrix_t mA; /* We need to create a dense square matrix first */ if (A) { n = (int) igraph_matrix_nrow(A); } else if (sA) { n = (int) igraph_sparsemat_nrow(sA); IGRAPH_CHECK(igraph_matrix_init(&mA, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, &mA); IGRAPH_CHECK(igraph_sparsemat_as_matrix(&mA, sA)); myA = &mA; } else if (fun) { IGRAPH_CHECK(igraph_i_eigen_arpackfun_to_mat(fun, n, extra, &mA)); IGRAPH_FINALLY(igraph_matrix_destroy, &mA); } switch (which->pos) { case IGRAPH_EIGEN_LM: IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_lm(myA, which, values, vectors)); break; case IGRAPH_EIGEN_SM: IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_sm(myA, which, values, vectors)); break; case IGRAPH_EIGEN_LR: IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_lr(myA, which, values, vectors)); break; case IGRAPH_EIGEN_SR: IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_sr(myA, which, values, vectors)); break; case IGRAPH_EIGEN_LI: IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_li(myA, which, values, vectors)); break; case IGRAPH_EIGEN_SI: IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_si(myA, which, values, vectors)); break; case IGRAPH_EIGEN_SELECT: IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_select(myA, which, values, vectors)); break; case IGRAPH_EIGEN_ALL: IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_all(myA, which, values, vectors)); break; default: /* This cannot happen */ break; } if (!A) { igraph_matrix_destroy(&mA); IGRAPH_FINALLY_CLEAN(1); } return 0; } static int igraph_i_eigen_checks(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n) { if ( (A ? 1 : 0) + (sA ? 1 : 0) + (fun ? 1 : 0) != 1) { IGRAPH_ERROR("Exactly one of 'A', 'sA' and 'fun' must be given", IGRAPH_EINVAL); } if (A) { if (n != igraph_matrix_ncol(A) || n != igraph_matrix_nrow(A)) { IGRAPH_ERROR("Invalid matrix", IGRAPH_NONSQUARE); } } else if (sA) { if (n != igraph_sparsemat_ncol(sA) || n != igraph_sparsemat_nrow(sA)) { IGRAPH_ERROR("Invalid matrix", IGRAPH_NONSQUARE); } } return 0; } /** * \function igraph_eigen_matrix_symmetric * * \example examples/simple/igraph_eigen_matrix_symmetric.c */ int igraph_eigen_matrix_symmetric(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n, void *extra, igraph_eigen_algorithm_t algorithm, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors) { IGRAPH_CHECK(igraph_i_eigen_checks(A, sA, fun, n)); if (which->pos != IGRAPH_EIGEN_LM && which->pos != IGRAPH_EIGEN_SM && which->pos != IGRAPH_EIGEN_LA && which->pos != IGRAPH_EIGEN_SA && which->pos != IGRAPH_EIGEN_BE && which->pos != IGRAPH_EIGEN_ALL && which->pos != IGRAPH_EIGEN_INTERVAL && which->pos != IGRAPH_EIGEN_SELECT) { IGRAPH_ERROR("Invalid 'pos' position in 'which'", IGRAPH_EINVAL); } switch (algorithm) { case IGRAPH_EIGEN_AUTO: if (which->howmany == n || n < 100) { IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack(A, sA, fun, n, extra, which, values, vectors)); } else { IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_arpack(A, sA, fun, n, extra, which, options, storage, values, vectors)); } break; case IGRAPH_EIGEN_LAPACK: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack(A, sA, fun, n, extra, which, values, vectors)); break; case IGRAPH_EIGEN_ARPACK: IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_arpack(A, sA, fun, n, extra, which, options, storage, values, vectors)); break; default: IGRAPH_ERROR("Unknown 'algorithm'", IGRAPH_EINVAL); } return 0; } /** * \function igraph_eigen_matrix * */ int igraph_eigen_matrix(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n, void *extra, igraph_eigen_algorithm_t algorithm, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { IGRAPH_UNUSED(options); IGRAPH_UNUSED(storage); IGRAPH_CHECK(igraph_i_eigen_checks(A, sA, fun, n)); if (which->pos != IGRAPH_EIGEN_LM && which->pos != IGRAPH_EIGEN_SM && which->pos != IGRAPH_EIGEN_LR && which->pos != IGRAPH_EIGEN_SR && which->pos != IGRAPH_EIGEN_LI && which->pos != IGRAPH_EIGEN_SI && which->pos != IGRAPH_EIGEN_SELECT && which->pos != IGRAPH_EIGEN_ALL) { IGRAPH_ERROR("Invalid 'pos' position in 'which'", IGRAPH_EINVAL); } switch (algorithm) { case IGRAPH_EIGEN_AUTO: IGRAPH_ERROR("'AUTO' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_LAPACK: IGRAPH_CHECK(igraph_i_eigen_matrix_lapack(A, sA, fun, n, extra, which, values, vectors)); /* TODO */ break; case IGRAPH_EIGEN_ARPACK: IGRAPH_ERROR("'ARPACK' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_COMP_AUTO: IGRAPH_ERROR("'COMP_AUTO' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_COMP_LAPACK: IGRAPH_ERROR("'COMP_LAPACK' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_COMP_ARPACK: IGRAPH_ERROR("'COMP_ARPACK' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; default: IGRAPH_ERROR("Unknown `algorithm'", IGRAPH_EINVAL); } return 0; } static int igraph_i_eigen_adjacency_arpack_sym_cb(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_adjlist_t *adjlist = (igraph_adjlist_t *) extra; igraph_vector_int_t *neis; int i, j, nlen; for (i = 0; i < n; i++) { neis = igraph_adjlist_get(adjlist, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { int nei = VECTOR(*neis)[j]; to[i] += from[nei]; } } return 0; } static int igraph_i_eigen_adjacency_arpack(const igraph_t *graph, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t* storage, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_complex_t *cmplxvalues, igraph_matrix_complex_t *cmplxvectors) { IGRAPH_UNUSED(cmplxvalues); IGRAPH_UNUSED(cmplxvectors); igraph_adjlist_t adjlist; void *extra = (void*) &adjlist; int n = igraph_vcount(graph); if (!options) { IGRAPH_ERROR("`options' must be given for ARPACK algorithm", IGRAPH_EINVAL); } if (igraph_is_directed(graph)) { IGRAPH_ERROR("ARPACK adjacency eigensolver not implemented for " "directed graphs", IGRAPH_UNIMPLEMENTED); } if (which->pos == IGRAPH_EIGEN_INTERVAL) { IGRAPH_ERROR("ARPACK adjacency eigensolver does not implement " "`INTERNAL' eigenvalues", IGRAPH_UNIMPLEMENTED); } if (which->pos == IGRAPH_EIGEN_SELECT) { IGRAPH_ERROR("ARPACK adjacency eigensolver does not implement " "`SELECT' eigenvalues", IGRAPH_UNIMPLEMENTED); } if (which->pos == IGRAPH_EIGEN_ALL) { IGRAPH_ERROR("ARPACK adjacency eigensolver does not implement " "`ALL' eigenvalues", IGRAPH_UNIMPLEMENTED); } switch (which->pos) { case IGRAPH_EIGEN_LM: options->which[0] = 'L'; options->which[1] = 'M'; options->nev = which->howmany; break; case IGRAPH_EIGEN_SM: options->which[0] = 'S'; options->which[1] = 'M'; options->nev = which->howmany; break; case IGRAPH_EIGEN_LA: options->which[0] = 'L'; options->which[1] = 'A'; options->nev = which->howmany; break; case IGRAPH_EIGEN_SA: options->which[0] = 'S'; options->which[1] = 'A'; options->nev = which->howmany; break; case IGRAPH_EIGEN_ALL: options->which[0] = 'L'; options->which[1] = 'M'; options->nev = n; break; case IGRAPH_EIGEN_BE: IGRAPH_ERROR("Eigenvectors from both ends with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_INTERVAL: IGRAPH_ERROR("Interval of eigenvectors with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_SELECT: IGRAPH_ERROR("Selected eigenvalues with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; default: /* This cannot happen */ break; } options->n = n; options->ncv = 2 * options->nev < n ? 2 * options->nev : n; IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_eigen_adjacency_arpack_sym_cb, extra, options, storage, values, vectors)); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_eigen_adjacency * */ int igraph_eigen_adjacency(const igraph_t *graph, igraph_eigen_algorithm_t algorithm, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_complex_t *cmplxvalues, igraph_matrix_complex_t *cmplxvectors) { if (which->pos != IGRAPH_EIGEN_LM && which->pos != IGRAPH_EIGEN_SM && which->pos != IGRAPH_EIGEN_LA && which->pos != IGRAPH_EIGEN_SA && which->pos != IGRAPH_EIGEN_BE && which->pos != IGRAPH_EIGEN_SELECT && which->pos != IGRAPH_EIGEN_INTERVAL && which->pos != IGRAPH_EIGEN_ALL) { IGRAPH_ERROR("Invalid 'pos' position in 'which'", IGRAPH_EINVAL); } switch (algorithm) { case IGRAPH_EIGEN_AUTO: IGRAPH_ERROR("'AUTO' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_LAPACK: IGRAPH_ERROR("'LAPACK' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_ARPACK: IGRAPH_CHECK(igraph_i_eigen_adjacency_arpack(graph, which, options, storage, values, vectors, cmplxvalues, cmplxvectors)); break; case IGRAPH_EIGEN_COMP_AUTO: IGRAPH_ERROR("'COMP_AUTO' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_COMP_LAPACK: IGRAPH_ERROR("'COMP_LAPACK' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_COMP_ARPACK: IGRAPH_ERROR("'COMP_ARPACK' algorithm not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ break; default: IGRAPH_ERROR("Unknown `algorithm'", IGRAPH_EINVAL); } return 0; } /** * \function igraph_eigen_laplacian * */ int igraph_eigen_laplacian(const igraph_t *graph, igraph_eigen_algorithm_t algorithm, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_complex_t *cmplxvalues, igraph_matrix_complex_t *cmplxvectors) { IGRAPH_UNUSED(graph); IGRAPH_UNUSED(algorithm); IGRAPH_UNUSED(which); IGRAPH_UNUSED(options); IGRAPH_UNUSED(storage); IGRAPH_UNUSED(values); IGRAPH_UNUSED(vectors); IGRAPH_UNUSED(cmplxvalues); IGRAPH_UNUSED(cmplxvectors); /* TODO */ IGRAPH_ERROR("'igraph_eigen_laplacian'", IGRAPH_UNIMPLEMENTED); } leidenbase/src/core/linalg/blas_internal.h0000644000176200001440000000612014447675375020345 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef BLAS_INTERNAL_H #define BLAS_INTERNAL_H /* Note: only files calling the BLAS routines directly need to include this header. */ #include "igraph_types.h" #include "config.h" #ifndef INTERNAL_BLAS #define igraphdaxpy_ daxpy_ #define igraphdger_ dger_ #define igraphdcopy_ dcopy_ #define igraphdscal_ dscal_ #define igraphdswap_ dswap_ #define igraphdgemm_ dgemm_ #define igraphdgemv_ dgemv_ #define igraphddot_ ddot_ #define igraphdnrm2_ dnrm2_ #define igraphlsame_ lsame_ #define igraphdrot_ drot_ #define igraphidamax_ idamax_ #define igraphdtrmm_ dtrmm_ #define igraphdasum_ dasum_ #define igraphdtrsm_ dtrsm_ #define igraphdtrsv_ dtrsv_ #define igraphdnrm2_ dnrm2_ #define igraphdsymv_ dsymv_ #define igraphdsyr2_ dsyr2_ #define igraphdsyr2k_ dsyr2k_ #define igraphdtrmv_ dtrmv_ #define igraphdsyrk_ dsyrk_ #endif #ifdef HAVE_GFORTRAN /* GFortran-specific calling conventions, used when compiling the R interface. * Derived with "gfortran -fc-prototypes-external", applied on the original * Fortran sources of these functions. */ void igraphdgemv_(char *trans, int *m, int *n, igraph_real_t *alpha, igraph_real_t *a, int *lda, igraph_real_t *x, int *incx, igraph_real_t *beta, igraph_real_t *y, int *incy, long int trans_len); void igraphdgemm_(char *transa, char *transb, int *m, int *n, int *k, double *alpha, double *a, int *lda, double *b, int *ldb, double *beta, double *c__, int *ldc, long int transa_len, long int transb_len); #else int igraphdgemv_(char *trans, int *m, int *n, igraph_real_t *alpha, igraph_real_t *a, int *lda, igraph_real_t *x, int *incx, igraph_real_t *beta, igraph_real_t *y, int *incy); int igraphdgemm_(char *transa, char *transb, int *m, int *n, int *k, double *alpha, double *a, int *lda, double *b, int *ldb, double *beta, double *c__, int *ldc); #endif double igraphdnrm2_(int *n, double *x, int *incx); double igraphddot_(int *n, double *dx, int *incx, double *dy, int *incy); #endif leidenbase/src/core/linalg/blas.c0000644000176200001440000001217114447675375016447 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_error.h" #include "igraph_blas.h" #include "linalg/blas_internal.h" /** * \function igraph_blas_dgemv * \brief Matrix-vector multiplication using BLAS, vector version. * * This function is a somewhat more user-friendly interface to * the \c dgemv function in BLAS. \c dgemv performs the operation * y = alpha*A*x + beta*y, where x and y are vectors and A is an * appropriately sized matrix (symmetric or non-symmetric). * * \param transpose whether to transpose the matrix \p A * \param alpha the constant \p alpha * \param a the matrix \p A * \param x the vector \p x * \param beta the constant \p beta * \param y the vector \p y (which will be modified in-place) * * Time complexity: O(nk) if the matrix is of size n x k * * \sa \ref igraph_blas_dgemv_array if you have arrays instead of * vectors. * * \example examples/simple/blas.c */ void igraph_blas_dgemv(igraph_bool_t transpose, igraph_real_t alpha, const igraph_matrix_t* a, const igraph_vector_t* x, igraph_real_t beta, igraph_vector_t* y) { char trans = transpose ? 'T' : 'N'; int m, n; int inc = 1; m = (int) igraph_matrix_nrow(a); n = (int) igraph_matrix_ncol(a); IGRAPH_ASSERT(igraph_vector_size(x) == transpose ? m : n); IGRAPH_ASSERT(igraph_vector_size(y) == transpose ? n : m); #ifdef HAVE_GFORTRAN igraphdgemv_(&trans, &m, &n, &alpha, VECTOR(a->data), &m, VECTOR(*x), &inc, &beta, VECTOR(*y), &inc, /* trans_len = */ 1); #else igraphdgemv_(&trans, &m, &n, &alpha, VECTOR(a->data), &m, VECTOR(*x), &inc, &beta, VECTOR(*y), &inc); #endif } /** * \function igraph_blas_dgemv_array * \brief Matrix-vector multiplication using BLAS, array version. * * This function is a somewhat more user-friendly interface to * the \c dgemv function in BLAS. \c dgemv performs the operation * y = alpha*A*x + beta*y, where x and y are vectors and A is an * appropriately sized matrix (symmetric or non-symmetric). * * \param transpose whether to transpose the matrix \p A * \param alpha the constant \p alpha * \param a the matrix \p A * \param x the vector \p x as a regular C array * \param beta the constant \p beta * \param y the vector \p y as a regular C array * (which will be modified in-place) * * Time complexity: O(nk) if the matrix is of size n x k * * \sa \ref igraph_blas_dgemv if you have vectors instead of * arrays. */ void igraph_blas_dgemv_array(igraph_bool_t transpose, igraph_real_t alpha, const igraph_matrix_t* a, const igraph_real_t* x, igraph_real_t beta, igraph_real_t* y) { char trans = transpose ? 'T' : 'N'; int m, n; int inc = 1; m = (int) igraph_matrix_nrow(a); n = (int) igraph_matrix_ncol(a); #ifdef HAVE_GFORTRAN igraphdgemv_(&trans, &m, &n, &alpha, VECTOR(a->data), &m, (igraph_real_t*)x, &inc, &beta, y, &inc, /* trans_len = */ 1); #else igraphdgemv_(&trans, &m, &n, &alpha, VECTOR(a->data), &m, (igraph_real_t*)x, &inc, &beta, y, &inc); #endif } /** * \function igraph_blas_dnrm2 * \brief Euclidean norm of a vector. * * \param v The vector. * \return Real value, the norm of \p v. * * Time complexity: O(n) where n is the length of the vector. */ igraph_real_t igraph_blas_dnrm2(const igraph_vector_t *v) { int n = igraph_vector_size(v); int one = 1; return igraphdnrm2_(&n, VECTOR(*v), &one); } /** * \function igraph_blas_ddot * \brief Dot product of two vectors. * * \param v1 The first vector. * \param v2 The second vector. * \param res Pointer to a real, the result will be stored here. * * Time complexity: O(n) where n is the length of the vectors. * * \example examples/simple/blas.c */ int igraph_blas_ddot(const igraph_vector_t *v1, const igraph_vector_t *v2, igraph_real_t *res) { int n = igraph_vector_size(v1); int one = 1; if (igraph_vector_size(v2) != n) { IGRAPH_ERROR("Dot product of vectors with different dimensions.", IGRAPH_EINVAL); } *res = igraphddot_(&n, VECTOR(*v1), &one, VECTOR(*v2), &one); return 0; } leidenbase/src/core/linalg/lapack.c0000644000176200001440000010551514447675375016766 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_lapack.h" #include "linalg/lapack_internal.h" /** * \function igraph_lapack_dgetrf * \brief LU factorization of a general M-by-N matrix. * * The factorization has the form * A = P * L * U * where P is a permutation matrix, L is lower triangular with unit * diagonal elements (lower trapezoidal if m > n), and U is upper * triangular (upper trapezoidal if m < n). * \param a The input/output matrix. On entry, the M-by-N matrix to be * factored. On exit, the factors L and U from the factorization * A = P * L * U; the unit diagonal elements of L are not * stored. * \param ipiv An integer vector, the pivot indices are stored here, * unless it is a null pointer. Row \c i of the matrix was * interchanged with row ipiv[i]. * \param info LAPACK error code. Zero on successful exit. If its value is * a positive number i, it indicates that U(i,i) is exactly zero. * The factorization has been * completed, but the factor U is exactly singular, and division * by zero will occur if it is used to solve a system of * equations. If LAPACK returns an error, i.e. a negative info * value, then an igraph error is generated as well. * \return Error code. * * Time complexity: TODO. */ int igraph_lapack_dgetrf(igraph_matrix_t *a, igraph_vector_int_t *ipiv, int *info) { int m = (int) igraph_matrix_nrow(a); int n = (int) igraph_matrix_ncol(a); int lda = m > 0 ? m : 1; igraph_vector_int_t *myipiv = ipiv, vipiv; if (!ipiv) { IGRAPH_CHECK(igraph_vector_int_init(&vipiv, m < n ? m : n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vipiv); myipiv = &vipiv; } else { IGRAPH_CHECK(igraph_vector_int_resize(ipiv, m < n ? m : n)); } igraphdgetrf_(&m, &n, VECTOR(a->data), &lda, VECTOR(*myipiv), info); if (*info > 0) { IGRAPH_WARNING("LU: factor is exactly singular."); } else if (*info < 0) { switch (*info) { case -1: IGRAPH_ERROR("Invalid number of rows.", IGRAPH_ELAPACK); break; case -2: IGRAPH_ERROR("Invalid number of columns.", IGRAPH_ELAPACK); break; case -3: IGRAPH_ERROR("Invalid input matrix.", IGRAPH_ELAPACK); break; case -4: IGRAPH_ERROR("Invalid LDA parameter.", IGRAPH_ELAPACK); break; case -5: IGRAPH_ERROR("Invalid pivot vector.", IGRAPH_ELAPACK); break; case -6: IGRAPH_ERROR("Invalid info argument.", IGRAPH_ELAPACK); break; default: IGRAPH_ERROR("Unknown LAPACK error.", IGRAPH_ELAPACK); break; } } if (!ipiv) { igraph_vector_int_destroy(&vipiv); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_lapack_dgetrs * \brief Solve general system of linear equations using LU factorization. * * This function calls LAPACK to solve a system of linear equations * A * X = B or A' * X = B * with a general N-by-N matrix A using the LU factorization * computed by \ref igraph_lapack_dgetrf. * \param transpose Logical scalar, whether to transpose the input * matrix. * \param a A matrix containing the L and U factors from the * factorization A = P*L*U. L is expected to be unitriangular, * diagonal entries are those of U. If A is singular, no warning or * error wil be given and random output will be returned. * \param ipiv An integer vector, the pivot indices from \ref * igraph_lapack_dgetrf() must be given here. Row \c i of A was * interchanged with row ipiv[i]. * \param b The right hand side matrix must be given here. The solution will also be placed here. * \return Error code. * * Time complexity: TODO. */ int igraph_lapack_dgetrs(igraph_bool_t transpose, const igraph_matrix_t *a, const igraph_vector_int_t *ipiv, igraph_matrix_t *b) { char trans = transpose ? 'T' : 'N'; int n = (int) igraph_matrix_nrow(a); int nrhs = (int) igraph_matrix_ncol(b); int lda = n > 0 ? n : 1; int ldb = n > 0 ? n : 1; int info; if (n != igraph_matrix_ncol(a)) { IGRAPH_ERROR("Cannot LU solve matrix.", IGRAPH_NONSQUARE); } if (n != igraph_matrix_nrow(b)) { IGRAPH_ERROR("Cannot LU solve matrix, RHS of wrong size.", IGRAPH_EINVAL); } if (igraph_vector_int_size(ipiv) > 0) { igraph_integer_t min, max; igraph_vector_int_minmax(ipiv, &min, &max); if (max > n || min < 1) { IGRAPH_ERROR("Pivot index out of range.", IGRAPH_EINVAL); } } if (igraph_vector_int_size(ipiv) != n) { IGRAPH_ERROR("Pivot vector length must match number of matrix rows.", IGRAPH_EINVAL); } igraphdgetrs_(&trans, &n, &nrhs, VECTOR(a->data), &lda, VECTOR(*ipiv), VECTOR(b->data), &ldb, &info); if (info < 0) { switch (info) { case -1: IGRAPH_ERROR("Invalid transpose argument.", IGRAPH_ELAPACK); break; case -2: IGRAPH_ERROR("Invalid number of rows/columns.", IGRAPH_ELAPACK); break; case -3: IGRAPH_ERROR("Invalid number of RHS vectors.", IGRAPH_ELAPACK); break; case -4: IGRAPH_ERROR("Invalid LU matrix.", IGRAPH_ELAPACK); break; case -5: IGRAPH_ERROR("Invalid LDA parameter.", IGRAPH_ELAPACK); break; case -6: IGRAPH_ERROR("Invalid pivot vector.", IGRAPH_ELAPACK); break; case -7: IGRAPH_ERROR("Invalid RHS matrix.", IGRAPH_ELAPACK); break; case -8: IGRAPH_ERROR("Invalid LDB parameter.", IGRAPH_ELAPACK); break; case -9: IGRAPH_ERROR("Invalid info argument.", IGRAPH_ELAPACK); break; default: IGRAPH_ERROR("Unknown LAPACK error.", IGRAPH_ELAPACK); break; } } return 0; } /** * \function igraph_lapack_dgesv * Solve system of linear equations with LU factorization * * This function computes the solution to a real system of linear * equations A * X = B, where A is an N-by-N matrix and X and B are * N-by-NRHS matrices. * * The LU decomposition with partial pivoting and row * interchanges is used to factor A as * A = P * L * U, * where P is a permutation matrix, L is unit lower triangular, and U is * upper triangular. The factored form of A is then used to solve the * system of equations A * X = B. * \param a Matrix. On entry the N-by-N coefficient matrix, on exit, * the factors L and U from the factorization A=P*L*U; the unit * diagonal elements of L are not stored. * \param ipiv An integer vector or a null pointer. If not a null * pointer, then the pivot indices that define the permutation * matrix P, are stored here. Row i of the matrix was * interchanged with row IPIV(i). * \param b Matrix, on entry the right hand side matrix should be * stored here. On exit, if there was no error, and the info * argument is zero, then it contains the solution matrix X. * \param info The LAPACK info code. If it is positive, then * U(info,info) is exactly zero. In this case the factorization * has been completed, but the factor U is exactly * singular, so the solution could not be computed. * \return Error code. * * Time complexity: TODO. * * \example examples/simple/igraph_lapack_dgesv.c */ int igraph_lapack_dgesv(igraph_matrix_t *a, igraph_vector_int_t *ipiv, igraph_matrix_t *b, int *info) { int n = (int) igraph_matrix_nrow(a); int nrhs = (int) igraph_matrix_ncol(b); int lda = n > 0 ? n : 1; int ldb = n > 0 ? n : 1; igraph_vector_int_t *myipiv = ipiv, vipiv; if (n != igraph_matrix_ncol(a)) { IGRAPH_ERROR("Cannot LU solve matrix.", IGRAPH_NONSQUARE); } if (n != igraph_matrix_nrow(b)) { IGRAPH_ERROR("Cannot LU solve matrix, RHS of wrong size.", IGRAPH_EINVAL); } if (!ipiv) { IGRAPH_CHECK(igraph_vector_int_init(&vipiv, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vipiv); myipiv = &vipiv; } igraphdgesv_(&n, &nrhs, VECTOR(a->data), &lda, VECTOR(*myipiv), VECTOR(b->data), &ldb, info); if (*info > 0) { IGRAPH_WARNING("LU: factor is exactly singular."); } else if (*info < 0) { switch (*info) { case -1: IGRAPH_ERROR("Invalid number of rows/column.", IGRAPH_ELAPACK); break; case -2: IGRAPH_ERROR("Invalid number of RHS vectors.", IGRAPH_ELAPACK); break; case -3: IGRAPH_ERROR("Invalid input matrix.", IGRAPH_ELAPACK); break; case -4: IGRAPH_ERROR("Invalid LDA parameter.", IGRAPH_ELAPACK); break; case -5: IGRAPH_ERROR("Invalid pivot vector.", IGRAPH_ELAPACK); break; case -6: IGRAPH_ERROR("Invalid RHS matrix.", IGRAPH_ELAPACK); break; case -7: IGRAPH_ERROR("Invalid LDB parameter.", IGRAPH_ELAPACK); break; case -8: IGRAPH_ERROR("Invalid info argument.", IGRAPH_ELAPACK); break; default: IGRAPH_ERROR("Unknown LAPACK error.", IGRAPH_ELAPACK); break; } } if (!ipiv) { igraph_vector_int_destroy(&vipiv); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_lapack_dsyevr * Selected eigenvalues and optionally eigenvectors of a symmetric matrix * * Calls the DSYEVR LAPACK function to compute selected eigenvalues * and, optionally, eigenvectors of a real symmetric matrix A. * Eigenvalues and eigenvectors can be selected by specifying either * a range of values or a range of indices for the desired eigenvalues. * * See more in the LAPACK documentation. * \param A Matrix, on entry it contains the symmetric input * matrix. Only the leading N-by-N upper triangular part is * used for the computation. * \param which Constant that gives which eigenvalues (and possibly * the corresponding eigenvectors) to calculate. Possible * values are \c IGRAPH_LAPACK_DSYEV_ALL, all eigenvalues; * \c IGRAPH_LAPACK_DSYEV_INTERVAL, all eigenvalues in the * half-open interval (vl,vu]; * \c IGRAPH_LAPACK_DSYEV_SELECT, the il-th through iu-th * eigenvalues. * \param vl If \p which is \c IGRAPH_LAPACK_DSYEV_INTERVAL, then * this is the lower bound of the interval to be searched for * eigenvalues. See also the \p vestimate argument. * \param vu If \p which is \c IGRAPH_LAPACK_DSYEV_INTERVAL, then * this is the upper bound of the interval to be searched for * eigenvalues. See also the \p vestimate argument. * \param vestimate An upper bound for the number of eigenvalues in * the (vl,vu] interval, if \p which is \c * IGRAPH_LAPACK_DSYEV_INTERVAL. Memory is allocated only for * the given number of eigenvalues (and eigenvectors), so this * upper bound must be correct. * \param il The index of the smallest eigenvalue to return, if \p * which is \c IGRAPH_LAPACK_DSYEV_SELECT. * \param iu The index of the largets eigenvalue to return, if \p * which is \c IGRAPH_LAPACK_DSYEV_SELECT. * \param abstol The absolute error tolerance for the eigevalues. An * approximate eigenvalue is accepted as converged when it is * determined to lie in an interval [a,b] of width less than or * equal to abstol + EPS * max(|a|,|b|), where EPS is the * machine precision. * \param values An initialized vector, the eigenvalues are stored * here, unless it is a null pointer. It will be resized as * needed. * \param vectors An initialized matrix, the eigenvectors are stored * in its columns, unless it is a null pointer. It will be * resized as needed. * \param support An integer vector. If not a null pointer, then it * will be resized to (2*max(1,M)) (M is a the total number of * eigenvalues found). Then the support of the eigenvectors in * \p vectors is stored here, i.e., the indices * indicating the nonzero elements in \p vectors. * The i-th eigenvector is nonzero only in elements * support(2*i-1) through support(2*i). * \return Error code. * * Time complexity: TODO. * * \example examples/simple/igraph_lapack_dsyevr.c */ int igraph_lapack_dsyevr(const igraph_matrix_t *A, igraph_lapack_dsyev_which_t which, igraph_real_t vl, igraph_real_t vu, int vestimate, int il, int iu, igraph_real_t abstol, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_int_t *support) { igraph_matrix_t Acopy; char jobz = vectors ? 'V' : 'N', range, uplo = 'U'; int n = (int) igraph_matrix_nrow(A), lda = n, ldz = n; int m, info; igraph_vector_t *myvalues = values, vvalues; igraph_vector_int_t *mysupport = support, vsupport; igraph_vector_t work; igraph_vector_int_t iwork; int lwork = -1, liwork = -1; if (n != igraph_matrix_ncol(A)) { IGRAPH_ERROR("Cannot find eigenvalues/vectors.", IGRAPH_NONSQUARE); } if (which == IGRAPH_LAPACK_DSYEV_INTERVAL && (vestimate < 1 || vestimate > n)) { IGRAPH_ERROR("Estimated (upper bound) number of eigenvalues must be " "between 1 and n.", IGRAPH_EINVAL); } if (which == IGRAPH_LAPACK_DSYEV_SELECT && iu - il < 0) { IGRAPH_ERROR("Invalid 'il' and/or 'iu' values.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A)); IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy); IGRAPH_VECTOR_INIT_FINALLY(&work, 1); IGRAPH_CHECK(igraph_vector_int_init(&iwork, 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &iwork); if (!values) { IGRAPH_VECTOR_INIT_FINALLY(&vvalues, 0); myvalues = &vvalues; } if (!support) { IGRAPH_CHECK(igraph_vector_int_init(&vsupport, 0)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vsupport); mysupport = &vsupport; } IGRAPH_CHECK(igraph_vector_resize(myvalues, n)); switch (which) { case IGRAPH_LAPACK_DSYEV_ALL: range = 'A'; IGRAPH_CHECK(igraph_vector_int_resize(mysupport, 2 * n)); if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, n)); } break; case IGRAPH_LAPACK_DSYEV_INTERVAL: range = 'V'; IGRAPH_CHECK(igraph_vector_int_resize(mysupport, 2 * vestimate)); if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, vestimate)); } break; case IGRAPH_LAPACK_DSYEV_SELECT: range = 'I'; IGRAPH_CHECK(igraph_vector_int_resize(mysupport, 2 * (iu - il + 1))); if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, iu - il + 1)); } break; } igraphdsyevr_(&jobz, &range, &uplo, &n, &MATRIX(Acopy, 0, 0), &lda, &vl, &vu, &il, &iu, &abstol, &m, VECTOR(*myvalues), vectors ? &MATRIX(*vectors, 0, 0) : 0, &ldz, VECTOR(*mysupport), VECTOR(work), &lwork, VECTOR(iwork), &liwork, &info); if (info != 0) { IGRAPH_ERROR("Invalid argument to dsyevr in workspace query.", IGRAPH_EINVAL); } lwork = (int) VECTOR(work)[0]; liwork = VECTOR(iwork)[0]; IGRAPH_CHECK(igraph_vector_resize(&work, lwork)); IGRAPH_CHECK(igraph_vector_int_resize(&iwork, liwork)); igraphdsyevr_(&jobz, &range, &uplo, &n, &MATRIX(Acopy, 0, 0), &lda, &vl, &vu, &il, &iu, &abstol, &m, VECTOR(*myvalues), vectors ? &MATRIX(*vectors, 0, 0) : 0, &ldz, VECTOR(*mysupport), VECTOR(work), &lwork, VECTOR(iwork), &liwork, &info); if (info != 0) { IGRAPH_ERROR("Invalid argument to dsyevr in calculation.", IGRAPH_EINVAL); } if (values) { IGRAPH_CHECK(igraph_vector_resize(values, m)); } if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, m)); } if (support) { IGRAPH_CHECK(igraph_vector_int_resize(support, m)); } if (!support) { igraph_vector_int_destroy(&vsupport); IGRAPH_FINALLY_CLEAN(1); } if (!values) { igraph_vector_destroy(&vvalues); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_int_destroy(&iwork); igraph_vector_destroy(&work); igraph_matrix_destroy(&Acopy); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_lapack_dgeev * Eigenvalues and optionally eigenvectors of a non-symmetric matrix * * This function calls LAPACK to compute, for an N-by-N real * nonsymmetric matrix A, the eigenvalues and, optionally, the left * and/or right eigenvectors. * * * The right eigenvector v(j) of A satisfies * A * v(j) = lambda(j) * v(j) * where lambda(j) is its eigenvalue. * The left eigenvector u(j) of A satisfies * u(j)**H * A = lambda(j) * u(j)**H * where u(j)**H denotes the conjugate transpose of u(j). * * * The computed eigenvectors are normalized to have Euclidean norm * equal to 1 and largest component real. * * \param A matrix. On entry it contains the N-by-N input matrix. * \param valuesreal Pointer to an initialized vector, or a null * pointer. If not a null pointer, then the real parts of the * eigenvalues are stored here. The vector will be resized as * needed. * \param valuesimag Pointer to an initialized vector, or a null * pointer. If not a null pointer, then the imaginary parts of * the eigenvalues are stored here. The vector will be resized * as needed. * \param vectorsleft Pointer to an initialized matrix, or a null * pointer. If not a null pointer, then the left eigenvectors * are stored in the columns of the matrix. The matrix will be * resized as needed. * \param vectorsright Pointer to an initialized matrix, or a null * pointer. If not a null pointer, then the right eigenvectors * are stored in the columns of the matrix. The matrix will be * resized as needed. * \param info This argument is used for two purposes. As an input * argument it gives whether an igraph error should be * generated if the QR algorithm fails to compute all * eigenvalues. If \p info is non-zero, then an error is * generated, otherwise only a warning is given. * On exit it contains the LAPACK error code. * Zero means successful exit. * A negative values means that some of the arguments had an * illegal value, this always triggers an igraph error. An i * positive value means that the QR algorithm failed to * compute all the eigenvalues, and no eigenvectors have been * computed; element i+1:N of \p valuesreal and \p valuesimag * contain eigenvalues which have converged. This case only * generates an igraph error, if \p info was non-zero on entry. * \return Error code. * * Time complexity: TODO. * * \example examples/simple/igraph_lapack_dgeev.c */ int igraph_lapack_dgeev(const igraph_matrix_t *A, igraph_vector_t *valuesreal, igraph_vector_t *valuesimag, igraph_matrix_t *vectorsleft, igraph_matrix_t *vectorsright, int *info) { char jobvl = vectorsleft ? 'V' : 'N'; char jobvr = vectorsright ? 'V' : 'N'; int n = (int) igraph_matrix_nrow(A); int lda = n, ldvl = n, ldvr = n, lwork = -1; igraph_vector_t work; igraph_vector_t *myreal = valuesreal, *myimag = valuesimag, vreal, vimag; igraph_matrix_t Acopy; int error = *info; if (igraph_matrix_ncol(A) != n) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev).", IGRAPH_NONSQUARE); } IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A)); IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy); IGRAPH_VECTOR_INIT_FINALLY(&work, 1); if (!valuesreal) { IGRAPH_VECTOR_INIT_FINALLY(&vreal, n); myreal = &vreal; } else { IGRAPH_CHECK(igraph_vector_resize(myreal, n)); } if (!valuesimag) { IGRAPH_VECTOR_INIT_FINALLY(&vimag, n); myimag = &vimag; } else { IGRAPH_CHECK(igraph_vector_resize(myimag, n)); } if (vectorsleft) { IGRAPH_CHECK(igraph_matrix_resize(vectorsleft, n, n)); } if (vectorsright) { IGRAPH_CHECK(igraph_matrix_resize(vectorsright, n, n)); } igraphdgeev_(&jobvl, &jobvr, &n, &MATRIX(Acopy, 0, 0), &lda, VECTOR(*myreal), VECTOR(*myimag), vectorsleft ? &MATRIX(*vectorsleft, 0, 0) : 0, &ldvl, vectorsright ? &MATRIX(*vectorsright, 0, 0) : 0, &ldvr, VECTOR(work), &lwork, info); lwork = (int) VECTOR(work)[0]; IGRAPH_CHECK(igraph_vector_resize(&work, lwork)); igraphdgeev_(&jobvl, &jobvr, &n, &MATRIX(Acopy, 0, 0), &lda, VECTOR(*myreal), VECTOR(*myimag), vectorsleft ? &MATRIX(*vectorsleft, 0, 0) : 0, &ldvl, vectorsright ? &MATRIX(*vectorsright, 0, 0) : 0, &ldvr, VECTOR(work), &lwork, info); if (*info < 0) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev).", IGRAPH_ELAPACK); } else if (*info > 0) { if (error) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev).", IGRAPH_ELAPACK); } else { IGRAPH_WARNING("Cannot calculate eigenvalues (dgeev)."); } } if (!valuesimag) { igraph_vector_destroy(&vimag); IGRAPH_FINALLY_CLEAN(1); } if (!valuesreal) { igraph_vector_destroy(&vreal); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&work); igraph_matrix_destroy(&Acopy); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_lapack_dgeevx * Eigenvalues/vectors of nonsymmetric matrices, expert mode * * This function calculates the eigenvalues and optionally the left * and/or right eigenvectors of a nonsymmetric N-by-N real matrix. * * * Optionally also, it computes a balancing transformation to improve * the conditioning of the eigenvalues and eigenvectors (\p ilo, \p ihi, * \p scale, and \p abnrm), reciprocal condition numbers for the * eigenvalues (\p rconde), and reciprocal condition numbers for the * right eigenvectors (\p rcondv). * * * The right eigenvector v(j) of A satisfies * A * v(j) = lambda(j) * v(j) * where lambda(j) is its eigenvalue. * The left eigenvector u(j) of A satisfies * u(j)^H * A = lambda(j) * u(j)^H * where u(j)^H denotes the conjugate transpose of u(j). * * * The computed eigenvectors are normalized to have Euclidean norm * equal to 1 and largest component real. * * * Balancing a matrix means permuting the rows and columns to make it * more nearly upper triangular, and applying a diagonal similarity * transformation D * A * D^(-1), where D is a diagonal matrix, to * make its rows and columns closer in norm and the condition numbers * of its eigenvalues and eigenvectors smaller. The computed * reciprocal condition numbers correspond to the balanced matrix. * Permuting rows and columns will not change the condition numbers * (in exact arithmetic) but diagonal scaling will. For further * explanation of balancing, see section 4.10.2 of the LAPACK * Users' Guide. * * \param balance Scalar that indicated, whether the input matrix * should be balanced. Possible values: * \clist * \cli IGRAPH_LAPACK_DGEEVX_BALANCE_NONE * no not diagonally scale or permute. * \cli IGRAPH_LAPACK_DGEEVX_BALANCE_PERM * perform permutations to make the matrix more nearly upper * triangular. Do not diagonally scale. * \cli IGRAPH_LAPACK_DGEEVX_BALANCE_SCALE * diagonally scale the matrix, i.e. replace A by * D*A*D^(-1), where D is a diagonal matrix, chosen to make * the rows and columns of A more equal in norm. Do not * permute. * \cli IGRAPH_LAPACK_DGEEVX_BALANCE_BOTH * both diagonally scale and permute A. * \endclist * \param A The input matrix, must be square. * \param valuesreal An initialized vector, or a NULL pointer. If not * a NULL pointer, then the real parts of the eigenvalues are stored * here. The vector will be resized, as needed. * \param valuesimag An initialized vector, or a NULL pointer. If not * a NULL pointer, then the imaginary parts of the eigenvalues are stored * here. The vector will be resized, as needed. * \param vectorsleft An initialized matrix or a NULL pointer. If not * a null pointer, then the left eigenvectors are stored here. The * order corresponds to the eigenvalues and the eigenvectors are * stored in a compressed form. If the j-th eigenvalue is real then * column j contains the corresponding eigenvector. If the j-th and * (j+1)-th eigenvalues form a complex conjugate pair, then the j-th * and (j+1)-th columns contain their corresponding eigenvectors. * \param vectorsright An initialized matrix or a NULL pointer. If not * a null pointer, then the right eigenvectors are stored here. The * format is the same, as for the \p vectorsleft argument. * \param ilo * \param ihi \p ilo and \p ihi are integer values determined when A was * balanced. The balanced A(i,j) = 0 if I>J and * J=1,...,ilo-1 or I=ihi+1,...,N. * \param scale Pointer to an initialized vector or a NULL pointer. If * not a NULL pointer, then details of the permutations and scaling * factors applied when balancing \p A, are stored here. * If P(j) is the index of the row and column * interchanged with row and column j, and D(j) is the scaling * factor applied to row and column j, then * \clist * \cli scale(J) = P(J), for J = 1,...,ilo-1 * \cli scale(J) = D(J), for J = ilo,...,ihi * \cli scale(J) = P(J) for J = ihi+1,...,N. * \endclist * The order in which the interchanges are made is N to \p ihi+1, * then 1 to \p ilo-1. * \param abnrm Pointer to a real variable, the one-norm of the * balanced matrix is stored here. (The one-norm is the maximum of * the sum of absolute values of elements in any column.) * \param rconde An initialized vector or a NULL pointer. If not a * null pointer, then the reciprocal condition numbers of the * eigenvalues are stored here. * \param rcondv An initialized vector or a NULL pointer. If not a * null pointer, then the reciprocal condition numbers of the right * eigenvectors are stored here. * \param info This argument is used for two purposes. As an input * argument it gives whether an igraph error should be * generated if the QR algorithm fails to compute all * eigenvalues. If \p info is non-zero, then an error is * generated, otherwise only a warning is given. * On exit it contains the LAPACK error code. * Zero means successful exit. * A negative values means that some of the arguments had an * illegal value, this always triggers an igraph error. An i * positive value means that the QR algorithm failed to * compute all the eigenvalues, and no eigenvectors have been * computed; element i+1:N of \p valuesreal and \p valuesimag * contain eigenvalues which have converged. This case only * generated an igraph error, if \p info was non-zero on entry. * \return Error code. * * Time complexity: TODO * * \example examples/simple/igraph_lapack_dgeevx.c */ int igraph_lapack_dgeevx(igraph_lapack_dgeevx_balance_t balance, const igraph_matrix_t *A, igraph_vector_t *valuesreal, igraph_vector_t *valuesimag, igraph_matrix_t *vectorsleft, igraph_matrix_t *vectorsright, int *ilo, int *ihi, igraph_vector_t *scale, igraph_real_t *abnrm, igraph_vector_t *rconde, igraph_vector_t *rcondv, int *info) { char balanc; char jobvl = vectorsleft ? 'V' : 'N'; char jobvr = vectorsright ? 'V' : 'N'; char sense; int n = (int) igraph_matrix_nrow(A); int lda = n, ldvl = n, ldvr = n, lwork = -1; igraph_vector_t work; igraph_vector_int_t iwork; igraph_matrix_t Acopy; int error = *info; igraph_vector_t *myreal = valuesreal, *myimag = valuesimag, vreal, vimag; igraph_vector_t *myscale = scale, vscale; if (igraph_matrix_ncol(A) != n) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeevx).", IGRAPH_NONSQUARE); } switch (balance) { case IGRAPH_LAPACK_DGEEVX_BALANCE_NONE: balanc = 'N'; break; case IGRAPH_LAPACK_DGEEVX_BALANCE_PERM: balanc = 'P'; break; case IGRAPH_LAPACK_DGEEVX_BALANCE_SCALE: balanc = 'S'; break; case IGRAPH_LAPACK_DGEEVX_BALANCE_BOTH: balanc = 'B'; break; default: IGRAPH_ERROR("Invalid 'balance' argument.", IGRAPH_EINVAL); break; } if (!rconde && !rcondv) { sense = 'N'; } else if (rconde && !rcondv) { sense = 'E'; } else if (!rconde && rcondv) { sense = 'V'; } else { sense = 'B'; } IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A)); IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy); IGRAPH_VECTOR_INIT_FINALLY(&work, 1); IGRAPH_CHECK(igraph_vector_int_init(&iwork, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &iwork); if (!valuesreal) { IGRAPH_VECTOR_INIT_FINALLY(&vreal, n); myreal = &vreal; } else { IGRAPH_CHECK(igraph_vector_resize(myreal, n)); } if (!valuesimag) { IGRAPH_VECTOR_INIT_FINALLY(&vimag, n); myimag = &vimag; } else { IGRAPH_CHECK(igraph_vector_resize(myimag, n)); } if (!scale) { IGRAPH_VECTOR_INIT_FINALLY(&vscale, n); myscale = &vscale; } else { IGRAPH_CHECK(igraph_vector_resize(scale, n)); } if (vectorsleft) { IGRAPH_CHECK(igraph_matrix_resize(vectorsleft, n, n)); } if (vectorsright) { IGRAPH_CHECK(igraph_matrix_resize(vectorsright, n, n)); } igraphdgeevx_(&balanc, &jobvl, &jobvr, &sense, &n, &MATRIX(Acopy, 0, 0), &lda, VECTOR(*myreal), VECTOR(*myimag), vectorsleft ? &MATRIX(*vectorsleft, 0, 0) : 0, &ldvl, vectorsright ? &MATRIX(*vectorsright, 0, 0) : 0, &ldvr, ilo, ihi, VECTOR(*myscale), abnrm, rconde ? VECTOR(*rconde) : 0, rcondv ? VECTOR(*rcondv) : 0, VECTOR(work), &lwork, VECTOR(iwork), info); lwork = (int) VECTOR(work)[0]; IGRAPH_CHECK(igraph_vector_resize(&work, lwork)); igraphdgeevx_(&balanc, &jobvl, &jobvr, &sense, &n, &MATRIX(Acopy, 0, 0), &lda, VECTOR(*myreal), VECTOR(*myimag), vectorsleft ? &MATRIX(*vectorsleft, 0, 0) : 0, &ldvl, vectorsright ? &MATRIX(*vectorsright, 0, 0) : 0, &ldvr, ilo, ihi, VECTOR(*myscale), abnrm, rconde ? VECTOR(*rconde) : 0, rcondv ? VECTOR(*rcondv) : 0, VECTOR(work), &lwork, VECTOR(iwork), info); if (*info < 0) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev).", IGRAPH_ELAPACK); } else if (*info > 0) { if (error) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev).", IGRAPH_ELAPACK); } else { IGRAPH_WARNING("Cannot calculate eigenvalues (dgeev)."); } } if (!scale) { igraph_vector_destroy(&vscale); IGRAPH_FINALLY_CLEAN(1); } if (!valuesimag) { igraph_vector_destroy(&vimag); IGRAPH_FINALLY_CLEAN(1); } if (!valuesreal) { igraph_vector_destroy(&vreal); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_int_destroy(&iwork); igraph_vector_destroy(&work); igraph_matrix_destroy(&Acopy); IGRAPH_FINALLY_CLEAN(3); return 0; } int igraph_lapack_dgehrd(const igraph_matrix_t *A, int ilo, int ihi, igraph_matrix_t *result) { int n = (int) igraph_matrix_nrow(A); int lda = n; int lwork = -1; igraph_vector_t work; igraph_real_t optwork; igraph_vector_t tau; igraph_matrix_t Acopy; int info = 0; int i; if (igraph_matrix_ncol(A) != n) { IGRAPH_ERROR("Hessenberg reduction failed.", IGRAPH_NONSQUARE); } if (ilo < 1 || ihi > n || ilo > ihi) { IGRAPH_ERROR("Invalid `ilo' and/or `ihi'.", IGRAPH_EINVAL); } if (n <= 1) { IGRAPH_CHECK(igraph_matrix_update(result, A)); return 0; } IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A)); IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy); IGRAPH_VECTOR_INIT_FINALLY(&tau, n - 1); igraphdgehrd_(&n, &ilo, &ihi, &MATRIX(Acopy, 0, 0), &lda, VECTOR(tau), &optwork, &lwork, &info); if (info != 0) { IGRAPH_ERROR("Internal Hessenberg transformation error.", IGRAPH_EINTERNAL); } lwork = (int) optwork; IGRAPH_VECTOR_INIT_FINALLY(&work, lwork); igraphdgehrd_(&n, &ilo, &ihi, &MATRIX(Acopy, 0, 0), &lda, VECTOR(tau), VECTOR(work), &lwork, &info); if (info != 0) { IGRAPH_ERROR("Internal Hessenberg transformation error.", IGRAPH_EINTERNAL); } igraph_vector_destroy(&work); igraph_vector_destroy(&tau); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_matrix_update(result, &Acopy)); igraph_matrix_destroy(&Acopy); IGRAPH_FINALLY_CLEAN(1); for (i = 0; i < n - 2; i++) { int j; for (j = i + 2; j < n; j++) { MATRIX(*result, j, i) = 0.0; } } return 0; } leidenbase/src/core/linalg/arpack.c0000644000176200001440000014602214447675374016771 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 noet: */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_arpack.h" #include "igraph_memory.h" #include "linalg/arpack_internal.h" #include #include #include /* The ARPACK example file dssimp.f is used as a template */ static int igraph_i_arpack_err_dsaupd(int error) { switch (error) { case 1: return IGRAPH_ARPACK_MAXIT; case 3: return IGRAPH_ARPACK_NOSHIFT; case -1: return IGRAPH_ARPACK_NPOS; case -2: return IGRAPH_ARPACK_NEVNPOS; case -3: return IGRAPH_ARPACK_NCVSMALL; case -4: return IGRAPH_ARPACK_NONPOSI; case -5: return IGRAPH_ARPACK_WHICHINV; case -6: return IGRAPH_ARPACK_BMATINV; case -7: return IGRAPH_ARPACK_WORKLSMALL; case -8: return IGRAPH_ARPACK_TRIDERR; case -9: return IGRAPH_ARPACK_ZEROSTART; case -10: return IGRAPH_ARPACK_MODEINV; case -11: return IGRAPH_ARPACK_MODEBMAT; case -12: return IGRAPH_ARPACK_ISHIFT; case -13: return IGRAPH_ARPACK_NEVBE; case -9999: return IGRAPH_ARPACK_NOFACT; default: return IGRAPH_ARPACK_UNKNOWN; } } static int igraph_i_arpack_err_dseupd(int error) { switch (error) { case -1: return IGRAPH_ARPACK_NPOS; case -2: return IGRAPH_ARPACK_NEVNPOS; case -3: return IGRAPH_ARPACK_NCVSMALL; case -5: return IGRAPH_ARPACK_WHICHINV; case -6: return IGRAPH_ARPACK_BMATINV; case -7: return IGRAPH_ARPACK_WORKLSMALL; case -8: return IGRAPH_ARPACK_TRIDERR; case -9: return IGRAPH_ARPACK_ZEROSTART; case -10: return IGRAPH_ARPACK_MODEINV; case -11: return IGRAPH_ARPACK_MODEBMAT; case -12: return IGRAPH_ARPACK_NEVBE; case -14: return IGRAPH_ARPACK_FAILED; case -15: return IGRAPH_ARPACK_HOWMNY; case -16: return IGRAPH_ARPACK_HOWMNYS; case -17: return IGRAPH_ARPACK_EVDIFF; default: return IGRAPH_ARPACK_UNKNOWN; } } static int igraph_i_arpack_err_dnaupd(int error) { switch (error) { case 1: return IGRAPH_ARPACK_MAXIT; case 3: return IGRAPH_ARPACK_NOSHIFT; case -1: return IGRAPH_ARPACK_NPOS; case -2: return IGRAPH_ARPACK_NEVNPOS; case -3: return IGRAPH_ARPACK_NCVSMALL; case -4: return IGRAPH_ARPACK_NONPOSI; case -5: return IGRAPH_ARPACK_WHICHINV; case -6: return IGRAPH_ARPACK_BMATINV; case -7: return IGRAPH_ARPACK_WORKLSMALL; case -8: return IGRAPH_ARPACK_TRIDERR; case -9: return IGRAPH_ARPACK_ZEROSTART; case -10: return IGRAPH_ARPACK_MODEINV; case -11: return IGRAPH_ARPACK_MODEBMAT; case -12: return IGRAPH_ARPACK_ISHIFT; case -9999: return IGRAPH_ARPACK_NOFACT; default: return IGRAPH_ARPACK_UNKNOWN; } } static int igraph_i_arpack_err_dneupd(int error) { switch (error) { case 1: return IGRAPH_ARPACK_REORDER; case -1: return IGRAPH_ARPACK_NPOS; case -2: return IGRAPH_ARPACK_NEVNPOS; case -3: return IGRAPH_ARPACK_NCVSMALL; case -5: return IGRAPH_ARPACK_WHICHINV; case -6: return IGRAPH_ARPACK_BMATINV; case -7: return IGRAPH_ARPACK_WORKLSMALL; case -8: return IGRAPH_ARPACK_SHUR; case -9: return IGRAPH_ARPACK_LAPACK; case -10: return IGRAPH_ARPACK_MODEINV; case -11: return IGRAPH_ARPACK_MODEBMAT; case -12: return IGRAPH_ARPACK_HOWMNYS; case -13: return IGRAPH_ARPACK_HOWMNY; case -14: return IGRAPH_ARPACK_FAILED; case -15: return IGRAPH_ARPACK_EVDIFF; default: return IGRAPH_ARPACK_UNKNOWN; } } /** * \function igraph_arpack_options_init * Initialize ARPACK options * * Initializes ARPACK options, set them to default values. * You can always pass the initialized \ref igraph_arpack_options_t * object to built-in igraph functions without any modification. The * built-in igraph functions modify the options to perform their * calculation, e.g. \ref igraph_pagerank() always searches for the * eigenvalue with the largest magnitude, regardless of the supplied * value. * * If you want to implement your own function involving eigenvalue * calculation using ARPACK, however, you will likely need to set up * the fields for yourself. * \param o The \ref igraph_arpack_options_t object to initialize. * * Time complexity: O(1). */ void igraph_arpack_options_init(igraph_arpack_options_t *o) { o->bmat[0] = 'I'; o->n = 0; /* needs to be updated! */ o->which[0] = 'X'; o->which[1] = 'X'; o->nev = 1; o->tol = 0; o->ncv = 0; /* 0 means "automatic" */ o->ldv = o->n; /* will be updated to (real) n */ o->ishift = 1; o->mxiter = 3000; o->nb = 1; o->mode = 1; o->start = 0; o->lworkl = 0; o->sigma = 0; o->sigmai = 0; o->info = o->start; o->iparam[0] = o->ishift; o->iparam[1] = 0; o->iparam[2] = o->mxiter; o->iparam[3] = o->nb; o->iparam[4] = 0; o->iparam[5] = 0; o->iparam[6] = o->mode; o->iparam[7] = 0; o->iparam[8] = 0; o->iparam[9] = 0; o->iparam[10] = 0; } /** * \function igraph_arpack_storage_init * Initialize ARPACK storage * * You only need this function if you want to run multiple eigenvalue * calculations using ARPACK, and want to spare the memory * allocation/deallocation between each two runs. Otherwise it is safe * to supply a null pointer as the \c storage argument of both \ref * igraph_arpack_rssolve() and \ref igraph_arpack_rnsolve() to make * memory allocated and deallocated automatically. * * Don't forget to call the \ref * igraph_arpack_storage_destroy() function on the storage object if * you don't need it any more. * \param s The \ref igraph_arpack_storage_t object to initialize. * \param maxn The maximum order of the matrices. * \param maxncv The maximum NCV parameter intended to use. * \param maxldv The maximum LDV parameter intended to use. * \param symm Whether symmetric or non-symmetric problems will be * solved using this \ref igraph_arpack_storage_t. (You cannot use * the same storage both with symmetric and non-symmetric solvers.) * \return Error code. * * Time complexity: O(maxncv*(maxldv+maxn)). */ int igraph_arpack_storage_init(igraph_arpack_storage_t *s, long int maxn, long int maxncv, long int maxldv, igraph_bool_t symm) { /* TODO: check arguments */ s->maxn = (int) maxn; s->maxncv = (int) maxncv; s->maxldv = (int) maxldv; #define CHECKMEM(x) \ if (!x) { \ IGRAPH_ERROR("Cannot allocate memory for ARPACK", IGRAPH_ENOMEM); \ } \ IGRAPH_FINALLY(igraph_free, x); s->v = IGRAPH_CALLOC(maxldv * maxncv, igraph_real_t); CHECKMEM(s->v); s->workd = IGRAPH_CALLOC(3 * maxn, igraph_real_t); CHECKMEM(s->workd); s->d = IGRAPH_CALLOC(2 * maxncv, igraph_real_t); CHECKMEM(s->d); s->resid = IGRAPH_CALLOC(maxn, igraph_real_t); CHECKMEM(s->resid); s->ax = IGRAPH_CALLOC(maxn, igraph_real_t); CHECKMEM(s->ax); s->select = IGRAPH_CALLOC(maxncv, int); CHECKMEM(s->select); if (symm) { s->workl = IGRAPH_CALLOC(maxncv * (maxncv + 8), igraph_real_t); CHECKMEM(s->workl); s->di = 0; s->workev = 0; } else { s->workl = IGRAPH_CALLOC(3 * maxncv * (maxncv + 2), igraph_real_t); CHECKMEM(s->workl); s->di = IGRAPH_CALLOC(2 * maxncv, igraph_real_t); CHECKMEM(s->di); s->workev = IGRAPH_CALLOC(3 * maxncv, igraph_real_t); CHECKMEM(s->workev); IGRAPH_FINALLY_CLEAN(2); } #undef CHECKMEM IGRAPH_FINALLY_CLEAN(7); return 0; } /** * \function igraph_arpack_storage_destroy * Deallocate ARPACK storage * * \param s The \ref igraph_arpack_storage_t object for which the * memory will be deallocated. * * Time complexity: operating system dependent. */ void igraph_arpack_storage_destroy(igraph_arpack_storage_t *s) { if (s->di) { IGRAPH_FREE(s->di); } if (s->workev) { IGRAPH_FREE(s->workev); } IGRAPH_FREE(s->workl); IGRAPH_FREE(s->select); IGRAPH_FREE(s->ax); IGRAPH_FREE(s->resid); IGRAPH_FREE(s->d); IGRAPH_FREE(s->workd); IGRAPH_FREE(s->v); } /** * "Solver" for 1x1 eigenvalue problems since ARPACK sometimes blows up with * these. */ static int igraph_i_arpack_rssolve_1x1(igraph_arpack_function_t *fun, void *extra, igraph_arpack_options_t* options, igraph_vector_t* values, igraph_matrix_t* vectors) { igraph_real_t a, b; int nev = options->nev; if (nev <= 0) { IGRAPH_ERROR("ARPACK error", IGRAPH_ARPACK_NEVNPOS); } /* Probe the value in the matrix */ a = 1; if (fun(&b, &a, 1, extra)) { IGRAPH_ERROR("ARPACK error while evaluating matrix-vector product", IGRAPH_ARPACK_PROD); } options->nconv = nev; if (values != 0) { IGRAPH_CHECK(igraph_vector_resize(values, 1)); VECTOR(*values)[0] = b; } if (vectors != 0) { IGRAPH_CHECK(igraph_matrix_resize(vectors, 1, 1)); MATRIX(*vectors, 0, 0) = 1; } return IGRAPH_SUCCESS; } /** * "Solver" for 1x1 eigenvalue problems since ARPACK sometimes blows up with * these. */ static int igraph_i_arpack_rnsolve_1x1(igraph_arpack_function_t *fun, void *extra, igraph_arpack_options_t* options, igraph_matrix_t* values, igraph_matrix_t* vectors) { igraph_real_t a, b; int nev = options->nev; if (nev <= 0) { IGRAPH_ERROR("ARPACK error", IGRAPH_ARPACK_NEVNPOS); } /* Probe the value in the matrix */ a = 1; if (fun(&b, &a, 1, extra)) { IGRAPH_ERROR("ARPACK error while evaluating matrix-vector product", IGRAPH_ARPACK_PROD); } options->nconv = nev; if (values != 0) { IGRAPH_CHECK(igraph_matrix_resize(values, 1, 2)); MATRIX(*values, 0, 0) = b; MATRIX(*values, 0, 1) = 0; } if (vectors != 0) { IGRAPH_CHECK(igraph_matrix_resize(vectors, 1, 1)); MATRIX(*vectors, 0, 0) = 1; } return IGRAPH_SUCCESS; } /** * "Solver" for 2x2 nonsymmetric eigenvalue problems since ARPACK sometimes * blows up with these. */ static int igraph_i_arpack_rnsolve_2x2(igraph_arpack_function_t *fun, void *extra, igraph_arpack_options_t* options, igraph_matrix_t* values, igraph_matrix_t* vectors) { igraph_real_t vec[2], mat[4]; igraph_real_t a, b, c, d; igraph_real_t trace, det, tsq4_minus_d; igraph_complex_t eval1, eval2; igraph_complex_t evec1[2], evec2[2]; igraph_bool_t swap_evals = 0; igraph_bool_t complex_evals = 0; int nev = options->nev; if (nev <= 0) { IGRAPH_ERROR("ARPACK error", IGRAPH_ARPACK_NEVNPOS); } if (nev > 2) { nev = 2; } /* Probe the values in the matrix */ vec[0] = 1; vec[1] = 0; if (fun(mat, vec, 2, extra)) { IGRAPH_ERROR("ARPACK error while evaluating matrix-vector product", IGRAPH_ARPACK_PROD); } vec[0] = 0; vec[1] = 1; if (fun(mat + 2, vec, 2, extra)) { IGRAPH_ERROR("ARPACK error while evaluating matrix-vector product", IGRAPH_ARPACK_PROD); } a = mat[0]; b = mat[2]; c = mat[1]; d = mat[3]; /* Get the trace and the determinant */ trace = a + d; det = a * d - b * c; tsq4_minus_d = trace * trace / 4 - det; /* Calculate the eigenvalues */ complex_evals = tsq4_minus_d < 0; eval1 = igraph_complex_sqrt_real(tsq4_minus_d); if (complex_evals) { eval2 = igraph_complex_mul_real(eval1, -1); } else { /* to avoid having -0 in the imaginary part */ eval2 = igraph_complex(-IGRAPH_REAL(eval1), 0); } eval1 = igraph_complex_add_real(eval1, trace / 2); eval2 = igraph_complex_add_real(eval2, trace / 2); if (c != 0) { evec1[0] = igraph_complex_sub_real(eval1, d); evec1[1] = igraph_complex(c, 0); evec2[0] = igraph_complex_sub_real(eval2, d); evec2[1] = igraph_complex(c, 0); } else if (b != 0) { evec1[0] = igraph_complex(b, 0); evec1[1] = igraph_complex_sub_real(eval1, a); evec2[0] = igraph_complex(b, 0); evec2[1] = igraph_complex_sub_real(eval2, a); } else { evec1[0] = igraph_complex(1, 0); evec1[1] = igraph_complex(0, 0); evec2[0] = igraph_complex(0, 0); evec2[1] = igraph_complex(1, 0); } /* Sometimes we have to swap eval1 with eval2 and evec1 with eval2; * determine whether we have to do it now */ if (options->which[0] == 'S') { if (options->which[1] == 'M') { /* eval1 must be the one with the smallest magnitude */ swap_evals = (igraph_complex_mod(eval1) > igraph_complex_mod(eval2)); } else if (options->which[1] == 'R') { /* eval1 must be the one with the smallest real part */ swap_evals = (IGRAPH_REAL(eval1) > IGRAPH_REAL(eval2)); } else if (options->which[1] == 'I') { /* eval1 must be the one with the smallest imaginary part */ swap_evals = (IGRAPH_IMAG(eval1) > IGRAPH_IMAG(eval2)); } else { IGRAPH_ERROR("ARPACK error", IGRAPH_ARPACK_WHICHINV); } } else if (options->which[0] == 'L') { if (options->which[1] == 'M') { /* eval1 must be the one with the largest magnitude */ swap_evals = (igraph_complex_mod(eval1) < igraph_complex_mod(eval2)); } else if (options->which[1] == 'R') { /* eval1 must be the one with the largest real part */ swap_evals = (IGRAPH_REAL(eval1) < IGRAPH_REAL(eval2)); } else if (options->which[1] == 'I') { /* eval1 must be the one with the largest imaginary part */ swap_evals = (IGRAPH_IMAG(eval1) < IGRAPH_IMAG(eval2)); } else { IGRAPH_ERROR("ARPACK error", IGRAPH_ARPACK_WHICHINV); } } else if (options->which[0] == 'X' && options->which[1] == 'X') { /* No preference on the ordering of eigenvectors */ } else { /* fprintf(stderr, "%c%c\n", options->which[0], options->which[1]); */ IGRAPH_ERROR("ARPACK error", IGRAPH_ARPACK_WHICHINV); } options->nconv = nev; if (swap_evals) { igraph_complex_t dummy; dummy = eval1; eval1 = eval2; eval2 = dummy; dummy = evec1[0]; evec1[0] = evec2[0]; evec2[0] = dummy; dummy = evec1[1]; evec1[1] = evec2[1]; evec2[1] = dummy; } if (complex_evals) { /* The eigenvalues are conjugate pairs, so we store only the * one with positive imaginary part */ if (IGRAPH_IMAG(eval1) < 0) { eval1 = eval2; evec1[0] = evec2[0]; evec1[1] = evec2[1]; } } if (values != 0) { IGRAPH_CHECK(igraph_matrix_resize(values, nev, 2)); MATRIX(*values, 0, 0) = IGRAPH_REAL(eval1); MATRIX(*values, 0, 1) = IGRAPH_IMAG(eval1); if (nev > 1) { MATRIX(*values, 1, 0) = IGRAPH_REAL(eval2); MATRIX(*values, 1, 1) = IGRAPH_IMAG(eval2); } } if (vectors != 0) { if (complex_evals) { IGRAPH_CHECK(igraph_matrix_resize(vectors, 2, 2)); MATRIX(*vectors, 0, 0) = IGRAPH_REAL(evec1[0]); MATRIX(*vectors, 1, 0) = IGRAPH_REAL(evec1[1]); MATRIX(*vectors, 0, 1) = IGRAPH_IMAG(evec1[0]); MATRIX(*vectors, 1, 1) = IGRAPH_IMAG(evec1[1]); } else { IGRAPH_CHECK(igraph_matrix_resize(vectors, 2, nev)); MATRIX(*vectors, 0, 0) = IGRAPH_REAL(evec1[0]); MATRIX(*vectors, 1, 0) = IGRAPH_REAL(evec1[1]); if (nev > 1) { MATRIX(*vectors, 0, 1) = IGRAPH_REAL(evec2[0]); MATRIX(*vectors, 1, 1) = IGRAPH_REAL(evec2[1]); } } } return IGRAPH_SUCCESS; } /** * "Solver" for symmetric 2x2 eigenvalue problems since ARPACK sometimes blows * up with these. */ static int igraph_i_arpack_rssolve_2x2(igraph_arpack_function_t *fun, void *extra, igraph_arpack_options_t* options, igraph_vector_t* values, igraph_matrix_t* vectors) { igraph_real_t vec[2], mat[4]; igraph_real_t a, b, c, d; igraph_real_t trace, det, tsq4_minus_d; igraph_real_t eval1, eval2; int nev = options->nev; if (nev <= 0) { IGRAPH_ERROR("ARPACK error", IGRAPH_ARPACK_NEVNPOS); } if (nev > 2) { nev = 2; } /* Probe the values in the matrix */ vec[0] = 1; vec[1] = 0; if (fun(mat, vec, 2, extra)) { IGRAPH_ERROR("ARPACK error while evaluating matrix-vector product", IGRAPH_ARPACK_PROD); } vec[0] = 0; vec[1] = 1; if (fun(mat + 2, vec, 2, extra)) { IGRAPH_ERROR("ARPACK error while evaluating matrix-vector product", IGRAPH_ARPACK_PROD); } a = mat[0]; b = mat[2]; c = mat[1]; d = mat[3]; /* Get the trace and the determinant */ trace = a + d; det = a * d - b * c; tsq4_minus_d = trace * trace / 4 - det; if (tsq4_minus_d >= 0) { /* Both eigenvalues are real */ eval1 = trace / 2 + sqrt(tsq4_minus_d); eval2 = trace / 2 - sqrt(tsq4_minus_d); if (c != 0) { mat[0] = eval1 - d; mat[2] = eval2 - d; mat[1] = c; mat[3] = c; } else if (b != 0) { mat[0] = b; mat[2] = b; mat[1] = eval1 - a; mat[3] = eval2 - a; } else { mat[0] = 1; mat[2] = 0; mat[1] = 0; mat[3] = 1; } } else { /* Both eigenvalues are complex. Should not happen with symmetric * matrices. */ IGRAPH_ERROR("ARPACK error, 2x2 matrix is not symmetric", IGRAPH_EINVAL); } /* eval1 is always the larger eigenvalue. If we want the smaller * one, we have to swap eval1 with eval2 and also the columns of mat */ if (options->which[0] == 'S') { trace = eval1; eval1 = eval2; eval2 = trace; trace = mat[0]; mat[0] = mat[2]; mat[2] = trace; trace = mat[1]; mat[1] = mat[3]; mat[3] = trace; } else if (options->which[0] == 'L' || options->which[0] == 'B') { /* Nothing to do here */ } else if (options->which[0] == 'X' && options->which[1] == 'X') { /* No preference on the ordering of eigenvectors */ } else { IGRAPH_ERROR("ARPACK error", IGRAPH_ARPACK_WHICHINV); } options->nconv = nev; if (values != 0) { IGRAPH_CHECK(igraph_vector_resize(values, nev)); VECTOR(*values)[0] = eval1; if (nev > 1) { VECTOR(*values)[1] = eval2; } } if (vectors != 0) { IGRAPH_CHECK(igraph_matrix_resize(vectors, 2, nev)); MATRIX(*vectors, 0, 0) = mat[0]; MATRIX(*vectors, 1, 0) = mat[1]; if (nev > 1) { MATRIX(*vectors, 0, 1) = mat[2]; MATRIX(*vectors, 1, 1) = mat[3]; } } return IGRAPH_SUCCESS; } int igraph_arpack_rssort(igraph_vector_t *values, igraph_matrix_t *vectors, const igraph_arpack_options_t *options, igraph_real_t *d, const igraph_real_t *v) { igraph_vector_t order; char sort[2]; int apply = 1; unsigned int n = (unsigned int) options->n; int nconv = options->nconv; int nev = options->nev; unsigned int nans = (unsigned int) (nconv < nev ? nconv : nev); unsigned int i; #define which(a,b) (options->which[0]==a && options->which[1]==b) if (which('L', 'A')) { sort[0] = 'S'; sort[1] = 'A'; } else if (which('S', 'A')) { sort[0] = 'L'; sort[1] = 'A'; } else if (which('L', 'M')) { sort[0] = 'S'; sort[1] = 'M'; } else if (which('S', 'M')) { sort[0] = 'L'; sort[1] = 'M'; } else if (which('B', 'E')) { sort[0] = 'L'; sort[1] = 'A'; } IGRAPH_CHECK(igraph_vector_init_seq(&order, 0, nconv - 1)); IGRAPH_FINALLY(igraph_vector_destroy, &order); #ifdef HAVE_GFORTRAN igraphdsortr_(sort, &apply, &nconv, d, VECTOR(order), /*which_len=*/ 2); #else igraphdsortr_(sort, &apply, &nconv, d, VECTOR(order)); #endif /* BE is special */ if (which('B', 'E')) { int w = 0, l1 = 0, l2 = nev - 1; igraph_vector_t order2, d2; IGRAPH_VECTOR_INIT_FINALLY(&order2, nev); IGRAPH_VECTOR_INIT_FINALLY(&d2, nev); while (l1 <= l2) { VECTOR(order2)[w] = VECTOR(order)[l1]; VECTOR(d2)[w] = d[l1]; w++; l1++; if (l1 <= l2) { VECTOR(order2)[w] = VECTOR(order)[l2]; VECTOR(d2)[w] = d[l2]; w++; l2--; } } igraph_vector_update(&order, &order2); igraph_vector_copy_to(&d2, d); igraph_vector_destroy(&order2); igraph_vector_destroy(&d2); IGRAPH_FINALLY_CLEAN(2); } #undef which /* Copy values */ if (values) { IGRAPH_CHECK(igraph_vector_resize(values, nans)); memcpy(VECTOR(*values), d, sizeof(igraph_real_t) * nans); } /* Reorder vectors */ if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, nans)); for (i = 0; i < nans; i++) { unsigned int idx = (unsigned int) VECTOR(order)[i]; const igraph_real_t *ptr = v + n * idx; memcpy(&MATRIX(*vectors, 0, i), ptr, sizeof(igraph_real_t) * n); } } igraph_vector_destroy(&order); IGRAPH_FINALLY_CLEAN(1); return 0; } int igraph_arpack_rnsort(igraph_matrix_t *values, igraph_matrix_t *vectors, const igraph_arpack_options_t *options, igraph_real_t *dr, igraph_real_t *di, igraph_real_t *v) { igraph_vector_t order; char sort[2]; int apply = 1; unsigned int n = (unsigned int) options->n; int nconv = options->nconv; int nev = options->nev; unsigned int nans = (unsigned int) (nconv < nev ? nconv : nev); unsigned int i; #define which(a,b) (options->which[0]==a && options->which[1]==b) if (which('L', 'M')) { sort[0] = 'S'; sort[1] = 'M'; } else if (which('S', 'M')) { sort[0] = 'L'; sort[1] = 'M'; } else if (which('L', 'R')) { sort[0] = 'S'; sort[1] = 'R'; } else if (which('S', 'R')) { sort[0] = 'L'; sort[1] = 'R'; } else if (which('L', 'I')) { sort[0] = 'S'; sort[1] = 'I'; } else if (which('S', 'I')) { sort[0] = 'L'; sort[1] = 'I'; } #undef which IGRAPH_CHECK(igraph_vector_init_seq(&order, 0, nconv - 1)); IGRAPH_FINALLY(igraph_vector_destroy, &order); #ifdef HAVE_GFORTRAN igraphdsortc_(sort, &apply, &nconv, dr, di, VECTOR(order), /*which_len=*/ 2); #else igraphdsortc_(sort, &apply, &nconv, dr, di, VECTOR(order)); #endif if (values) { IGRAPH_CHECK(igraph_matrix_resize(values, nans, 2)); memcpy(&MATRIX(*values, 0, 0), dr, sizeof(igraph_real_t) * nans); memcpy(&MATRIX(*values, 0, 1), di, sizeof(igraph_real_t) * nans); } if (vectors) { int nc = 0, nr = 0, ncol, vx = 0; for (i = 0; i < nans; i++) { if (di[i] == 0) { nr++; } else { nc++; } } ncol = (nc / 2) * 2 + (nc % 2) * 2 + nr; IGRAPH_CHECK(igraph_matrix_resize(vectors, n, ncol)); for (i = 0; i < nans; i++) { unsigned int idx; idx = (unsigned int) VECTOR(order)[i]; if (di[i] == 0) { /* real eigenvalue, single eigenvector */ memcpy(&MATRIX(*vectors, 0, vx), v + n * idx, sizeof(igraph_real_t) * n); vx++; } else if (di[i] > 0) { /* complex eigenvalue, positive imaginary part encountered first. * ARPACK stores its eigenvector directly in two consecutive columns. * The complex conjugate pair of the eigenvalue (if any) will be in * the next column and we will skip it because we advance 'i' below */ memcpy(&MATRIX(*vectors, 0, vx), v + n * idx, sizeof(igraph_real_t) * 2 * n); vx += 2; i++; } else { /* complex eigenvalue, negative imaginary part encountered first. * The positive one will be the next one, but we need to copy the * eigenvector corresponding to the eigenvalue with the positive * imaginary part. */ idx = (unsigned int) VECTOR(order)[i + 1]; memcpy(&MATRIX(*vectors, 0, vx), v + n * idx, sizeof(igraph_real_t) * 2 * n); vx += 2; i++; } } } igraph_vector_destroy(&order); IGRAPH_FINALLY_CLEAN(1); if (values) { /* Strive to include complex conjugate eigenvalue pairs in a way that the * positive imaginary part comes first */ for (i = 0; i < nans; i++) { if (MATRIX(*values, i, 1) == 0) { /* Real eigenvalue, nothing to do */ } else if (MATRIX(*values, i, 1) < 0) { /* Negative imaginary part came first; negate the imaginary part for * this eigenvalue and the next one (which is the complex conjugate * pair), and skip it */ MATRIX(*values, i, 1) *= -1; i++; if (i < nans) { MATRIX(*values, i, 1) *= -1; } } else { /* Positive imaginary part; skip the next eigenvalue, which is the * complex conjugate pair */ i++; } } } return 0; } /** * \function igraph_i_arpack_auto_ncv * \brief Tries to set up the value of \c ncv in an \c igraph_arpack_options_t * automagically. */ static void igraph_i_arpack_auto_ncv(igraph_arpack_options_t* options) { /* This is similar to how Octave determines the value of ncv, with some * modifications. */ int min_ncv = options->nev * 2 + 1; /* Use twice the number of desired eigenvectors plus one by default */ options->ncv = min_ncv; /* ...but use at least 20 Lanczos vectors... */ if (options->ncv < 20) { options->ncv = 20; } /* ...but having ncv close to n leads to some problems with small graphs * (example: PageRank of "A <--> C, D <--> E, B"), so we don't let it * to be larger than n / 2... */ if (options->ncv > options->n / 2) { options->ncv = options->n / 2; } /* ...but we need at least min_ncv. */ if (options->ncv < min_ncv) { options->ncv = min_ncv; } /* ...but at most n */ if (options->ncv > options->n) { options->ncv = options->n; } } /** * \function igraph_i_arpack_report_no_convergence * \brief Prints a warning that informs the user that the ARPACK solver * did not converge. */ static void igraph_i_arpack_report_no_convergence(const igraph_arpack_options_t* options) { char buf[1024]; snprintf(buf, sizeof(buf), "ARPACK solver failed to converge (%d iterations, " "%d/%d eigenvectors converged)", options->iparam[2], options->iparam[4], options->nev); IGRAPH_WARNING(buf); } /** * \function igraph_arpack_rssolve * \brief ARPACK solver for symmetric matrices * * This is the ARPACK solver for symmetric matrices. Please use * \ref igraph_arpack_rnsolve() for non-symmetric matrices. * \param fun Pointer to an \ref igraph_arpack_function_t object, * the function that performs the matrix-vector multiplication. * \param extra An extra argument to be passed to \c fun. * \param options An \ref igraph_arpack_options_t object. * \param storage An \ref igraph_arpack_storage_t object, or a null * pointer. In the latter case memory allocation and deallocation * is performed automatically. Either this or the \p vectors argument * must be non-null if the ARPACK iteration is started from a * given starting vector. If both are given \p vectors take * precedence. * \param values If not a null pointer, then it should be a pointer to an * initialized vector. The eigenvalues will be stored here. The * vector will be resized as needed. * \param vectors If not a null pointer, then it must be a pointer to * an initialized matrix. The eigenvectors will be stored in the * columns of the matrix. The matrix will be resized as needed. * Either this or the \p vectors argument must be non-null if the * ARPACK iteration is started from a given starting vector. If * both are given \p vectors take precedence. * \return Error code. * * Time complexity: depends on the matrix-vector * multiplication. Usually a small number of iterations is enough, so * if the matrix is sparse and the matrix-vector multiplication can be * done in O(n) time (the number of vertices), then the eigenvalues * are found in O(n) time as well. */ int igraph_arpack_rssolve(igraph_arpack_function_t *fun, void *extra, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors) { igraph_real_t *v, *workl, *workd, *d, *resid, *ax; igraph_bool_t free_them = 0; int *select, i; int ido = 0; int rvec = vectors || storage ? 1 : 0; /* calculate eigenvectors? */ char *all = "All"; int origldv = options->ldv, origlworkl = options->lworkl, orignev = options->nev, origncv = options->ncv; igraph_real_t origtol = options->tol; char origwhich[2]; origwhich[0] = options->which[0]; origwhich[1] = options->which[1]; /* Special case for 1x1 and 2x2 matrices in mode 1 */ if (options->mode == 1 && options->n == 1) { return igraph_i_arpack_rssolve_1x1(fun, extra, options, values, vectors); } else if (options->mode == 1 && options->n == 2) { return igraph_i_arpack_rssolve_2x2(fun, extra, options, values, vectors); } /* Brush up options if needed */ if (options->ldv == 0) { options->ldv = options->n; } if (options->ncv == 0) { igraph_i_arpack_auto_ncv(options); } if (options->lworkl == 0) { options->lworkl = options->ncv * (options->ncv + 8); } if (options->which[0] == 'X') { options->which[0] = 'L'; options->which[1] = 'M'; } if (storage) { /* Storage provided */ if (storage->maxn < options->n) { IGRAPH_ERROR("Not enough storage for ARPACK (`n')", IGRAPH_EINVAL); } if (storage->maxncv < options->ncv) { IGRAPH_ERROR("Not enough storage for ARPACK (`ncv')", IGRAPH_EINVAL); } if (storage->maxldv < options->ldv) { IGRAPH_ERROR("Not enough storage for ARPACK (`ldv')", IGRAPH_EINVAL); } v = storage->v; workl = storage->workl; workd = storage->workd; d = storage->d; resid = storage->resid; ax = storage->ax; select = storage->select; } else { /* Storage not provided */ free_them = 1; #define CHECKMEM(x) \ if (!x) { \ IGRAPH_ERROR("Cannot allocate memory for ARPACK", IGRAPH_ENOMEM); \ } \ IGRAPH_FINALLY(igraph_free, x); v = IGRAPH_CALLOC(options->ldv * options->ncv, igraph_real_t); CHECKMEM(v); workl = IGRAPH_CALLOC(options->lworkl, igraph_real_t); CHECKMEM(workl); workd = IGRAPH_CALLOC(3 * options->n, igraph_real_t); CHECKMEM(workd); d = IGRAPH_CALLOC(2 * options->ncv, igraph_real_t); CHECKMEM(d); resid = IGRAPH_CALLOC(options->n, igraph_real_t); CHECKMEM(resid); ax = IGRAPH_CALLOC(options->n, igraph_real_t); CHECKMEM(ax); select = IGRAPH_CALLOC(options->ncv, int); CHECKMEM(select); #undef CHECKMEM } /* Set final bits */ options->bmat[0] = 'I'; options->iparam[0] = options->ishift; options->iparam[1] = 0; // not referenced options->iparam[2] = options->mxiter; options->iparam[3] = 1; // currently dsaupd() works only for nb=1 options->iparam[4] = 0; options->iparam[5] = 0; // not referenced options->iparam[6] = options->mode; options->iparam[7] = 0; // return value options->iparam[8] = 0; // return value options->iparam[9] = 0; // return value options->iparam[10] = 0; // return value options->info = options->start; if (options->start) { if (!storage && !vectors) { IGRAPH_ERROR("Starting vector not given", IGRAPH_EINVAL); } if (vectors && (igraph_matrix_nrow(vectors) != options->n || igraph_matrix_ncol(vectors) != 1)) { IGRAPH_ERROR("Invalid starting vector size", IGRAPH_EINVAL); } if (vectors) { for (i = 0; i < options->n; i++) { resid[i] = MATRIX(*vectors, i, 0); } } } /* Ok, we have everything */ while (1) { #ifdef HAVE_GFORTRAN igraphdsaupd_(&ido, options->bmat, &options->n, options->which, &options->nev, &options->tol, resid, &options->ncv, v, &options->ldv, options->iparam, options->ipntr, workd, workl, &options->lworkl, &options->info, /*bmat_len=*/ 1, /*which_len=*/ 2); #else igraphdsaupd_(&ido, options->bmat, &options->n, options->which, &options->nev, &options->tol, resid, &options->ncv, v, &options->ldv, options->iparam, options->ipntr, workd, workl, &options->lworkl, &options->info); #endif if (ido == -1 || ido == 1) { igraph_real_t *from = workd + options->ipntr[0] - 1; igraph_real_t *to = workd + options->ipntr[1] - 1; if (fun(to, from, options->n, extra) != 0) { IGRAPH_ERROR("ARPACK error while evaluating matrix-vector product", IGRAPH_ARPACK_PROD); } } else { break; } } if (options->info == 1) { igraph_i_arpack_report_no_convergence(options); } if (options->info != 0) { IGRAPH_ERROR("ARPACK error", igraph_i_arpack_err_dsaupd(options->info)); } options->ierr = 0; #ifdef HAVE_GFORTRAN igraphdseupd_(&rvec, all, select, d, v, &options->ldv, &options->sigma, options->bmat, &options->n, options->which, &options->nev, &options->tol, resid, &options->ncv, v, &options->ldv, options->iparam, options->ipntr, workd, workl, &options->lworkl, &options->ierr, /*howmny_len=*/ 1, /*bmat_len=*/ 1, /*which_len=*/ 2); #else igraphdseupd_(&rvec, all, select, d, v, &options->ldv, &options->sigma, options->bmat, &options->n, options->which, &options->nev, &options->tol, resid, &options->ncv, v, &options->ldv, options->iparam, options->ipntr, workd, workl, &options->lworkl, &options->ierr); #endif if (options->ierr != 0) { IGRAPH_ERROR("ARPACK error", igraph_i_arpack_err_dseupd(options->ierr)); } /* Save the result */ options->noiter = options->iparam[2]; options->nconv = options->iparam[4]; options->numop = options->iparam[8]; options->numopb = options->iparam[9]; options->numreo = options->iparam[10]; if (options->nconv < options->nev) { IGRAPH_WARNING("Not enough eigenvalues/vectors in symmetric ARPACK " "solver"); } if (values || vectors) { IGRAPH_CHECK(igraph_arpack_rssort(values, vectors, options, d, v)); } options->ldv = origldv; options->ncv = origncv; options->lworkl = origlworkl; options->which[0] = origwhich[0]; options->which[1] = origwhich[1]; options->tol = origtol; options->nev = orignev; /* Clean up if needed */ if (free_them) { IGRAPH_FREE(select); IGRAPH_FREE(ax); IGRAPH_FREE(resid); IGRAPH_FREE(d); IGRAPH_FREE(workd); IGRAPH_FREE(workl); IGRAPH_FREE(v); IGRAPH_FINALLY_CLEAN(7); } return 0; } /** * \function igraph_arpack_rnsolve * \brief ARPACK solver for non-symmetric matrices * * Please always consider calling \ref igraph_arpack_rssolve() if your * matrix is symmetric, it is much faster. * \ref igraph_arpack_rnsolve() for non-symmetric matrices. * * Note that ARPACK is not called for 2x2 matrices as an exact algebraic * solution exists in these cases. * * \param fun Pointer to an \ref igraph_arpack_function_t object, * the function that performs the matrix-vector multiplication. * \param extra An extra argument to be passed to \c fun. * \param options An \ref igraph_arpack_options_t object. * \param storage An \ref igraph_arpack_storage_t object, or a null * pointer. In the latter case memory allocation and deallocation * is performed automatically. * \param values If not a null pointer, then it should be a pointer to an * initialized matrix. The (possibly complex) eigenvalues will be * stored here. The matrix will have two columns, the first column * contains the real, the second the imaginary parts of the * eigenvalues. * The matrix will be resized as needed. * \param vectors If not a null pointer, then it must be a pointer to * an initialized matrix. The eigenvectors will be stored in the * columns of the matrix. The matrix will be resized as needed. * Note that real eigenvalues will have real eigenvectors in a single * column in this matrix; however, complex eigenvalues come in conjugate * pairs and the result matrix will store the eigenvector corresponding to * the eigenvalue with \em positive imaginary part only. Since in this case * the eigenvector is also complex, it will occupy \em two columns in the * eigenvector matrix (the real and the imaginary parts, in this order). * Caveat: if the eigenvalue vector returns only the eigenvalue with the * \em negative imaginary part for a complex conjugate eigenvalue pair, the * result vector will \em still store the eigenvector corresponding to the * eigenvalue with the positive imaginary part (since this is how ARPACK * works). * \return Error code. * * Time complexity: depends on the matrix-vector * multiplication. Usually a small number of iterations is enough, so * if the matrix is sparse and the matrix-vector multiplication can be * done in O(n) time (the number of vertices), then the eigenvalues * are found in O(n) time as well. */ int igraph_arpack_rnsolve(igraph_arpack_function_t *fun, void *extra, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_matrix_t *values, igraph_matrix_t *vectors) { igraph_real_t *v, *workl, *workd, *dr, *di, *resid, *workev; igraph_bool_t free_them = 0; int *select, i; int ido = 0; int rvec = vectors || storage ? 1 : 0; char *all = "All"; int origldv = options->ldv, origlworkl = options->lworkl, orignev = options->nev, origncv = options->ncv; igraph_real_t origtol = options->tol; int d_size; char origwhich[2]; origwhich[0] = options->which[0]; origwhich[1] = options->which[1]; /* Special case for 1x1 and 2x2 matrices in mode 1 */ if (options->mode == 1 && options->n == 1) { return igraph_i_arpack_rnsolve_1x1(fun, extra, options, values, vectors); } else if (options->mode == 1 && options->n == 2) { return igraph_i_arpack_rnsolve_2x2(fun, extra, options, values, vectors); } /* Brush up options if needed */ if (options->ldv == 0) { options->ldv = options->n; } if (options->ncv == 0) { igraph_i_arpack_auto_ncv(options); } if (options->lworkl == 0) { options->lworkl = 3 * options->ncv * (options->ncv + 2); } if (options->which[0] == 'X') { options->which[0] = 'L'; options->which[1] = 'M'; } if (storage) { /* Storage provided */ if (storage->maxn < options->n) { IGRAPH_ERROR("Not enough storage for ARPACK (`n')", IGRAPH_EINVAL); } if (storage->maxncv < options->ncv) { IGRAPH_ERROR("Not enough storage for ARPACK (`ncv')", IGRAPH_EINVAL); } if (storage->maxldv < options->ldv) { IGRAPH_ERROR("Not enough storage for ARPACK (`ldv')", IGRAPH_EINVAL); } v = storage->v; workl = storage->workl; workd = storage->workd; workev = storage->workev; dr = storage->d; di = storage->di; d_size = options->n; resid = storage->resid; select = storage->select; } else { /* Storage not provided */ free_them = 1; #define CHECKMEM(x) \ if (!x) { \ IGRAPH_ERROR("Cannot allocate memory for ARPACK", IGRAPH_ENOMEM); \ } \ IGRAPH_FINALLY(igraph_free, x); v = IGRAPH_CALLOC(options->n * options->ncv, igraph_real_t); CHECKMEM(v); workl = IGRAPH_CALLOC(options->lworkl, igraph_real_t); CHECKMEM(workl); workd = IGRAPH_CALLOC(3 * options->n, igraph_real_t); CHECKMEM(workd); d_size = 2 * options->nev + 1 > options->ncv ? 2 * options->nev + 1 : options->ncv; dr = IGRAPH_CALLOC(d_size, igraph_real_t); CHECKMEM(dr); di = IGRAPH_CALLOC(d_size, igraph_real_t); CHECKMEM(di); resid = IGRAPH_CALLOC(options->n, igraph_real_t); CHECKMEM(resid); select = IGRAPH_CALLOC(options->ncv, int); CHECKMEM(select); workev = IGRAPH_CALLOC(3 * options->ncv, igraph_real_t); CHECKMEM(workev); #undef CHECKMEM } /* Set final bits */ options->bmat[0] = 'I'; options->iparam[0] = options->ishift; options->iparam[1] = 0; // not referenced options->iparam[2] = options->mxiter; options->iparam[3] = 1; // currently dnaupd() works only for nb=1 options->iparam[4] = 0; options->iparam[5] = 0; // not referenced options->iparam[6] = options->mode; options->iparam[7] = 0; // return value options->iparam[8] = 0; // return value options->iparam[9] = 0; // return value options->iparam[10] = 0; // return value options->info = options->start; if (options->start) { if (!storage && !vectors) { IGRAPH_ERROR("Starting vector not given", IGRAPH_EINVAL); } if (vectors && (igraph_matrix_nrow(vectors) != options->n || igraph_matrix_ncol(vectors) != 1)) { IGRAPH_ERROR("Invalid starting vector size", IGRAPH_EINVAL); } if (vectors) { for (i = 0; i < options->n; i++) { resid[i] = MATRIX(*vectors, i, 0); } } } /* Ok, we have everything */ while (1) { #ifdef HAVE_GFORTRAN igraphdnaupd_(&ido, options->bmat, &options->n, options->which, &options->nev, &options->tol, resid, &options->ncv, v, &options->ldv, options->iparam, options->ipntr, workd, workl, &options->lworkl, &options->info, /*bmat_len=*/ 1, /*which_len=*/ 2); #else igraphdnaupd_(&ido, options->bmat, &options->n, options->which, &options->nev, &options->tol, resid, &options->ncv, v, &options->ldv, options->iparam, options->ipntr, workd, workl, &options->lworkl, &options->info); #endif if (ido == -1 || ido == 1) { igraph_real_t *from = workd + options->ipntr[0] - 1; igraph_real_t *to = workd + options->ipntr[1] - 1; if (fun(to, from, options->n, extra) != 0) { IGRAPH_ERROR("ARPACK error while evaluating matrix-vector product", IGRAPH_ARPACK_PROD); } } else { break; } } if (options->info == 1) { igraph_i_arpack_report_no_convergence(options); } if (options->info != 0 && options->info != -9999) { IGRAPH_ERROR("ARPACK error", igraph_i_arpack_err_dnaupd(options->info)); } options->ierr = 0; #ifdef HAVE_GFORTRAN igraphdneupd_(&rvec, all, select, dr, di, v, &options->ldv, &options->sigma, &options->sigmai, workev, options->bmat, &options->n, options->which, &options->nev, &options->tol, resid, &options->ncv, v, &options->ldv, options->iparam, options->ipntr, workd, workl, &options->lworkl, &options->ierr, /*howmny_len=*/ 1, /*bmat_len=*/ 1, /*which_len=*/ 2); #else igraphdneupd_(&rvec, all, select, dr, di, v, &options->ldv, &options->sigma, &options->sigmai, workev, options->bmat, &options->n, options->which, &options->nev, &options->tol, resid, &options->ncv, v, &options->ldv, options->iparam, options->ipntr, workd, workl, &options->lworkl, &options->ierr); #endif if (options->ierr != 0) { IGRAPH_ERROR("ARPACK error", igraph_i_arpack_err_dneupd(options->info)); } /* Save the result */ options->noiter = options->iparam[2]; options->nconv = options->iparam[4]; options->numop = options->iparam[8]; options->numopb = options->iparam[9]; options->numreo = options->iparam[10]; if (options->nconv < options->nev) { IGRAPH_WARNING("Not enough eigenvalues/vectors in ARPACK " "solver"); } /* ARPACK might modify stuff in 'options' so reset everything that could * potentially get modified */ options->ldv = origldv; options->ncv = origncv; options->lworkl = origlworkl; options->which[0] = origwhich[0]; options->which[1] = origwhich[1]; options->tol = origtol; options->nev = orignev; if (values || vectors) { IGRAPH_CHECK(igraph_arpack_rnsort(values, vectors, options, dr, di, v)); } /* Clean up if needed */ if (free_them) { IGRAPH_FREE(workev); IGRAPH_FREE(select); IGRAPH_FREE(resid); IGRAPH_FREE(di); IGRAPH_FREE(dr); IGRAPH_FREE(workd); IGRAPH_FREE(workl); IGRAPH_FREE(v); IGRAPH_FINALLY_CLEAN(8); } return 0; } /** * \function igraph_arpack_unpack_complex * \brief Make the result of the non-symmetric ARPACK solver more readable * * This function works on the output of \ref igraph_arpack_rnsolve and * brushes it up a bit: it only keeps \p nev eigenvalues/vectors and * every eigenvector is stored in two columns of the \p vectors * matrix. * * * The output of the non-symmetric ARPACK solver is somewhat hard to * parse, as real eigenvectors occupy only one column in the matrix, * and the complex conjugate eigenvectors are not stored at all * (usually). The other problem is that the solver might return more * eigenvalues than requested. The common use of this function is to * call it directly after \ref igraph_arpack_rnsolve with its \p * vectors and \p values argument and \c options->nev as \p nev. * This will add the vectors for eigenvalues with a negative imaginary * part and return all vectors as 2 columns, a real and imaginary part. * \param vectors The eigenvector matrix, as returned by \ref * igraph_arpack_rnsolve. It will be resized, typically it will be * larger. * \param values The eigenvalue matrix, as returned by \ref * igraph_arpack_rnsolve. It will be resized, typically extra, * unneeded rows (=eigenvalues) will be removed. * \param nev The number of eigenvalues/vectors to keep. Can be less * or equal than the number originally requested from ARPACK. * \return Error code. * * Time complexity: linear in the number of elements in the \p vectors * matrix. */ int igraph_arpack_unpack_complex(igraph_matrix_t *vectors, igraph_matrix_t *values, long int nev) { long int nodes = igraph_matrix_nrow(vectors); long int no_evs = igraph_matrix_nrow(values); long int i, j; long int new_vector_pos; long int vector_pos; igraph_matrix_t new_vectors; /* Error checks */ if (nev < 0) { IGRAPH_ERROR("`nev' cannot be negative", IGRAPH_EINVAL); } if (nev > no_evs) { IGRAPH_ERROR("`nev' too large, we don't have that many in `values'", IGRAPH_EINVAL); } for (i = no_evs -1; i >= nev; i--) { IGRAPH_CHECK(igraph_matrix_remove_row(values, i)); } IGRAPH_CHECK(igraph_matrix_init(&new_vectors, nodes, nev * 2)); IGRAPH_FINALLY(igraph_matrix_destroy, &new_vectors); new_vector_pos = 0; vector_pos = 0; for (i = 0; i < nev && vector_pos < igraph_matrix_ncol(vectors); i++) { if (MATRIX(*values, i, 1) == 0) { /* Real eigenvalue */ for (j = 0; j < nodes; j++) { MATRIX(new_vectors, j, new_vector_pos) = MATRIX(*vectors, j, vector_pos); } new_vector_pos += 2; vector_pos += 1; } else { /* complex eigenvalue */ for (j = 0; j < nodes; j++) { MATRIX(new_vectors, j, new_vector_pos) = MATRIX(*vectors, j, vector_pos); MATRIX(new_vectors, j, new_vector_pos + 1) = MATRIX(*vectors, j, vector_pos + 1); } /* handle the conjugate */ /* first check if the conjugate eigenvalue is there */ i++; if (i >= nev) { break; } if (MATRIX(*values, i, 1) != -MATRIX(*values, i-1, 1)) { IGRAPH_ERROR("Complex eigenvalue not followed by its conjugate.", IGRAPH_EINVAL); } /* then copy and negate */ for (j = 0; j < nodes; j++) { MATRIX(new_vectors, j, new_vector_pos + 2) = MATRIX(*vectors, j, vector_pos); MATRIX(new_vectors, j, new_vector_pos + 3) = -MATRIX(*vectors, j, vector_pos + 1); } new_vector_pos += 4; vector_pos += 2; } } igraph_matrix_destroy(vectors); IGRAPH_CHECK(igraph_matrix_copy(vectors, &new_vectors)); igraph_matrix_destroy(&new_vectors); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/linalg/arpack_internal.h0000644000176200001440000002134314447675374020670 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef ARPACK_INTERNAL_H #define ARPACK_INTERNAL_H /* Note: only files calling the arpack routines directly need to include this header. */ #include "igraph_types.h" #include "config.h" #ifndef INTERNAL_ARPACK #define igraphdsaupd_ dsaupd_ #define igraphdseupd_ dseupd_ #define igraphdsaup2_ dsaup2_ #define igraphdstats_ dstats_ #define igraphdsesrt_ dsesrt_ #define igraphdsortr_ dsortr_ #define igraphdsortc_ dsortc_ #define igraphdgetv0_ dgetv0_ #define igraphdsaitr_ dsaitr_ #define igraphdsapps_ dsapps_ #define igraphdsconv_ dsconv_ #define igraphdseigt_ dseigt_ #define igraphdsgets_ dsgets_ #define igraphdstqrb_ dstqrb_ #define igraphdmout_ dmout_ #define igraphivout_ ivout_ #define igraphsecond_ second_ #define igraphdvout_ dvout_ #define igraphdnaitr_ dnaitr_ #define igraphdnapps_ dnapps_ #define igraphdnaup2_ dnaup2_ #define igraphdnaupd_ dnaupd_ #define igraphdnconv_ dnconv_ #define igraphdlabad_ dlabad_ #define igraphdlanhs_ dlanhs_ #define igraphdsortc_ dsortc_ #define igraphdneigh_ dneigh_ #define igraphdngets_ dngets_ #define igraphdstatn_ dstatn_ #define igraphdlaqrb_ dlaqrb_ #define igraphdsaupd_ dsaupd_ #define igraphdseupd_ dseupd_ #define igraphdnaupd_ dnaupd_ #define igraphdneupd_ dneupd_ #endif #ifndef INTERNAL_LAPACK #define igraphdlarnv_ dlarnv_ #define igraphdlascl_ dlascl_ #define igraphdlartg_ dlartg_ #define igraphdlaset_ dlaset_ #define igraphdlae2_ dlae2_ #define igraphdlaev2_ dlaev2_ #define igraphdlasr_ dlasr_ #define igraphdlasrt_ dlasrt_ #define igraphdgeqr2_ dgeqr2_ #define igraphdlacpy_ dlacpy_ #define igraphdorm2r_ dorm2r_ #define igraphdsteqr_ dsteqr_ #define igraphdlanst_ dlanst_ #define igraphdlapy2_ dlapy2_ #define igraphdlamch_ dlamch_ #define igraphdlaruv_ dlaruv_ #define igraphdlarfg_ dlarfg_ #define igraphdlarf_ dlarf_ #define igraphdlassq_ dlassq_ #define igraphdlamc2_ dlamc2_ #define igraphdlamc1_ dlamc1_ #define igraphdlamc2_ dlamc2_ #define igraphdlamc3_ dlamc3_ #define igraphdlamc4_ dlamc4_ #define igraphdlamc5_ dlamc5_ #define igraphdlabad_ dlabad_ #define igraphdlanhs_ dlanhs_ #define igraphdtrevc_ dtrevc_ #define igraphdlanv2_ dlanv2_ #define igraphdlaln2_ dlaln2_ #define igraphdladiv_ dladiv_ #define igraphdtrsen_ dtrsen_ #define igraphdlahqr_ dlahqr_ #define igraphdtrsen_ dtrsen_ #define igraphdlacon_ dlacon_ #define igraphdtrsyl_ dtrsyl_ #define igraphdtrexc_ dtrexc_ #define igraphdlange_ dlange_ #define igraphdlaexc_ dlaexc_ #define igraphdlasy2_ dlasy2_ #define igraphdlarfx_ dlarfx_ #endif #if 0 /* internal f2c functions always used */ #define igraphd_sign d_sign #define igraphetime_ etime_ #define igraphpow_dd pow_dd #define igraphpow_di pow_di #define igraphs_cmp s_cmp #define igraphs_copy s_copy #define igraphd_lg10_ d_lg10_ #define igraphi_dnnt_ i_dnnt_ #endif #ifdef HAVE_GFORTRAN /* GFortran-specific calling conventions, used when compiling the R interface. * Derived with "gfortran -fc-prototypes-external", applied on the original * Fortran sources of these functions. * * Caveats: * * 1) gfortran prints size_t for the "_len" arguments, but in fact they must be * long int * 2) gofrtran maps Fortran LOGICAL types to int_least32_t, but in fact they * must be void* (anything else doesn't work, not even _Bool*) * */ void igraphdsaupd_(int *ido, char *bmat, int *n, char *which, int *nev, igraph_real_t *tol, igraph_real_t *resid, int *ncv, igraph_real_t *v, int *ldv, int *iparam, int *ipntr, igraph_real_t *workd, igraph_real_t *workl, int *lworkl, int *info, long int bmat_len, long int which_len); void igraphdseupd_(void *rvec, char *howmny, void *select, igraph_real_t *d, igraph_real_t *z, int *ldz, igraph_real_t *sigma, char *bmat, int *n, char *which, int *nev, igraph_real_t *tol, igraph_real_t *resid, int *ncv, igraph_real_t *v, int *ldv, int *iparam, int *ipntr, igraph_real_t *workd, igraph_real_t *workl, int *lworkl, int *info, long int howmny_len, long int bmat_len, long int which_len); void igraphdnaupd_(int *ido, char *bmat, int *n, char *which, int *nev, igraph_real_t *tol, igraph_real_t *resid, int *ncv, igraph_real_t *v, int *ldv, int *iparam, int *ipntr, igraph_real_t *workd, igraph_real_t *workl, int *lworkl, int *info, long int bmat_len, long int which_len); void igraphdneupd_(void *rvec, char *howmny, void *select, igraph_real_t *dr, igraph_real_t *di, igraph_real_t *z, int *ldz, igraph_real_t *sigmar, igraph_real_t *sigmai, igraph_real_t *workev, char *bmat, int *n, char *which, int *nev, igraph_real_t *tol, igraph_real_t *resid, int *ncv, igraph_real_t *v, int *ldv, int *iparam, int *ipntr, igraph_real_t *workd, igraph_real_t *workl, int *lworkl, int *info, long int howmny_len, long int bmat_len, long int which_len); void igraphdsortr_(char *which, void *apply, int* n, igraph_real_t *x1, igraph_real_t *x2, long int which_len); void igraphdsortc_(char *which, void *apply, int* n, igraph_real_t *xreal, igraph_real_t *ximag, igraph_real_t *y, long int which_len); #else int igraphdsaupd_(int *ido, char *bmat, int *n, char *which, int *nev, igraph_real_t *tol, igraph_real_t *resid, int *ncv, igraph_real_t *v, int *ldv, int *iparam, int *ipntr, igraph_real_t *workd, igraph_real_t *workl, int *lworkl, int *info); int igraphdseupd_(int *rvec, char *howmny, int *select, igraph_real_t *d, igraph_real_t *z, int *ldz, igraph_real_t *sigma, char *bmat, int *n, char *which, int *nev, igraph_real_t *tol, igraph_real_t *resid, int *ncv, igraph_real_t *v, int *ldv, int *iparam, int *ipntr, igraph_real_t *workd, igraph_real_t *workl, int *lworkl, int *info); int igraphdnaupd_(int *ido, char *bmat, int *n, char *which, int *nev, igraph_real_t *tol, igraph_real_t *resid, int *ncv, igraph_real_t *v, int *ldv, int *iparam, int *ipntr, igraph_real_t *workd, igraph_real_t *workl, int *lworkl, int *info); int igraphdneupd_(int *rvec, char *howmny, int *select, igraph_real_t *dr, igraph_real_t *di, igraph_real_t *z, int *ldz, igraph_real_t *sigmar, igraph_real_t *sigmai, igraph_real_t *workev, char *bmat, int *n, char *which, int *nev, igraph_real_t *tol, igraph_real_t *resid, int *ncv, igraph_real_t *v, int *ldv, int *iparam, int *ipntr, igraph_real_t *workd, igraph_real_t *workl, int *lworkl, int *info); int igraphdsortr_(char *which, int *apply, int* n, igraph_real_t *x1, igraph_real_t *x2); int igraphdsortc_(char *which, int *apply, int* n, igraph_real_t *xreal, igraph_real_t *ximag, igraph_real_t *y); #endif #endif /* ARPACK_INTERNAL_H */ leidenbase/src/core/linalg/lapack_internal.h0000644000176200001440000001542414447675375020666 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LAPACK_INTERNAL_H #define LAPACK_INTERNAL_H /* Note: only files calling the LAPACK routines directly need to include this header. */ #include "igraph_types.h" #include "config.h" #ifndef INTERNAL_LAPACK #define igraphdgeevx_ dgeevx_ #define igraphdgeev_ dgeev_ #define igraphdgebak_ dgebak_ #define igraphxerbla_ xerbla_ #define igraphdgebal_ dgebal_ #define igraphdisnan_ disnan_ #define igraphdlaisnan_ dlaisnan_ #define igraphdgehrd_ dgehrd_ #define igraphdgehd2_ dgehd2_ #define igraphdlarf_ dlarf_ #define igraphiladlc_ iladlc_ #define igraphiladlr_ iladlr_ #define igraphdlarfg_ dlarfg_ #define igraphdlapy2_ dlapy2_ #define igraphdlahr2_ dlahr2_ #define igraphdlacpy_ dlacpy_ #define igraphdlarfb_ dlarfb_ #define igraphilaenv_ ilaenv_ #define igraphieeeck_ ieeeck_ #define igraphiparmq_ iparmq_ #define igraphdhseqr_ dhseqr_ #define igraphdlahqr_ dlahqr_ #define igraphdlabad_ dlabad_ #define igraphdlanv2_ dlanv2_ #define igraphdlaqr0_ dlaqr0_ #define igraphdlaqr3_ dlaqr3_ #define igraphdlaqr4_ dlaqr4_ #define igraphdlaqr2_ dlaqr2_ #define igraphdlaset_ dlaset_ #define igraphdormhr_ dormhr_ #define igraphdormqr_ dormqr_ #define igraphdlarft_ dlarft_ #define igraphdorm2r_ dorm2r_ #define igraphdtrexc_ dtrexc_ #define igraphdlaexc_ dlaexc_ #define igraphdlange_ dlange_ #define igraphdlassq_ dlassq_ #define igraphdlarfx_ dlarfx_ #define igraphdlartg_ dlartg_ #define igraphdlasy2_ dlasy2_ #define igraphdlaqr5_ dlaqr5_ #define igraphdlaqr1_ dlaqr1_ #define igraphdlascl_ dlascl_ #define igraphdorghr_ dorghr_ #define igraphdorgqr_ dorgqr_ #define igraphdorg2r_ dorg2r_ #define igraphdtrevc_ dtrevc_ #define igraphdlaln2_ dlaln2_ #define igraphdladiv_ dladiv_ #define igraphdsyevr_ dsyevr_ #define igraphdsyrk_ dsyrk_ #define igraphdlansy_ dlansy_ #define igraphdormtr_ dormtr_ #define igraphdormql_ dormql_ #define igraphdorm2l_ dorm2l_ #define igraphdstebz_ dstebz_ #define igraphdlaebz_ dlaebz_ #define igraphdstein_ dstein_ #define igraphdlagtf_ dlagtf_ #define igraphdlagts_ dlagts_ #define igraphdlarnv_ dlarnv_ #define igraphdlaruv_ dlaruv_ #define igraphdstemr_ dstemr_ #define igraphdlae2_ dlae2_ #define igraphdlaev2_ dlaev2_ #define igraphdlanst_ dlanst_ #define igraphdlarrc_ dlarrc_ #define igraphdlarre_ dlarre_ #define igraphdlarra_ dlarra_ #define igraphdlarrb_ dlarrb_ #define igraphdlaneg_ dlaneg_ #define igraphdlarrd_ dlarrd_ #define igraphdlarrk_ dlarrk_ #define igraphdlasq2_ dlasq2_ #define igraphdlasq3_ dlasq3_ #define igraphdlasq4_ dlasq4_ #define igraphdlasq5_ dlasq5_ #define igraphdlasq6_ dlasq6_ #define igraphdlasrt_ dlasrt_ #define igraphdlarrj_ dlarrj_ #define igraphdlarrr_ dlarrr_ #define igraphdlarrv_ dlarrv_ #define igraphdlar1v_ dlar1v_ #define igraphdlarrf_ dlarrf_ #define igraphdpotrf_ dpotrf_ #define igraphdsterf_ dsterf_ #define igraphdsytrd_ dsytrd_ #define igraphdlatrd_ dlatrd_ #define igraphdsytd2_ dsytd2_ #define igraphdlanhs_ dlanhs_ #define igraphdgeqr2_ dgeqr2_ #define igraphdtrsen_ dtrsen_ #define igraphdlacn2_ dlacn2_ #define igraphdtrsyl_ dtrsyl_ #define igraphdlasr_ dlasr_ #define igraphdsteqr_ dsteqr_ #define igraphdgesv_ dgesv_ #define igraphdgetrf_ dgetrf_ #define igraphdgetf2_ dgetf2_ #define igraphdlaswp_ dlaswp_ #define igraphdgetrs_ dgetrs_ #define igraphlen_trim_ len_trim_ #define igraph_dlamc1_ dlamc1_ #define igraph_dlamc2_ dlamc2_ #define igraph_dlamc3_ dlamc3_ #define igraph_dlamc4_ dlamc4_ #define igraph_dlamc5_ dlamc5_ #endif int igraphdgetrf_(int *m, int *n, igraph_real_t *a, int *lda, int *ipiv, int *info); int igraphdgetrs_(char *trans, int *n, int *nrhs, igraph_real_t *a, int *lda, int *ipiv, igraph_real_t *b, int *ldb, int *info); int igraphdgesv_(int *n, int *nrhs, igraph_real_t *a, int *lda, int *ipiv, igraph_real_t *b, int *ldb, int *info); igraph_real_t igraphdlapy2_(igraph_real_t *x, igraph_real_t *y); int igraphdsyevr_(char *jobz, char *range, char *uplo, int *n, igraph_real_t *a, int *lda, igraph_real_t *vl, igraph_real_t *vu, int * il, int *iu, igraph_real_t *abstol, int *m, igraph_real_t *w, igraph_real_t *z, int *ldz, int *isuppz, igraph_real_t *work, int *lwork, int *iwork, int *liwork, int *info); int igraphdgeev_(char *jobvl, char *jobvr, int *n, igraph_real_t *a, int *lda, igraph_real_t *wr, igraph_real_t *wi, igraph_real_t *vl, int *ldvl, igraph_real_t *vr, int *ldvr, igraph_real_t *work, int *lwork, int *info); int igraphdgeevx_(char *balanc, char *jobvl, char *jobvr, char *sense, int *n, igraph_real_t *a, int *lda, igraph_real_t *wr, igraph_real_t *wi, igraph_real_t *vl, int *ldvl, igraph_real_t *vr, int *ldvr, int *ilo, int *ihi, igraph_real_t *scale, igraph_real_t *abnrm, igraph_real_t *rconde, igraph_real_t *rcondv, igraph_real_t *work, int *lwork, int *iwork, int *info); int igraphdgehrd_(int *n, int *ilo, int *ihi, igraph_real_t *A, int *lda, igraph_real_t *tau, igraph_real_t *work, int *lwork, int *info); igraph_real_t igraphddot_(int *n, igraph_real_t *dx, int *incx, igraph_real_t *dy, int *incy); #endif leidenbase/src/core/version.c0000644000176200001440000000423514447675375015747 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2008-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_version.h" #include static const char *igraph_version_string = IGRAPH_VERSION; /** * \function igraph_version * Return the version of the igraph C library * * \param version_string Pointer to a string pointer. If not null, it * is set to the igraph version string, e.g. "0.6" or "0.5.3". This * string should not be modified or deallocated. * \param major If not a null pointer, then it is set to the major * igraph version. E.g. for version "0.5.3" this is 0. * \param minor If not a null pointer, then it is set to the minor * igraph version. E.g. for version "0.5.3" this is 5. * \param subminor If not a null pointer, then it is set to the * subminor igraph version. E.g. for version "0.5.3" this is 3. * \return Error code. * * Time complexity: O(1). * * \example examples/simple/igraph_version.c */ int igraph_version(const char **version_string, int *major, int *minor, int *subminor) { int i1, i2, i3; int *p1 = major ? major : &i1, *p2 = minor ? minor : &i2, *p3 = subminor ? subminor : &i3; if (version_string) { *version_string = igraph_version_string; } *p1 = *p2 = *p3 = 0; sscanf(IGRAPH_VERSION, "%i.%i.%i", p1, p2, p3); return 0; } leidenbase/src/core/math/0000755000176200001440000000000014532173045015021 5ustar liggesusersleidenbase/src/core/math/utils.c0000644000176200001440000002417314447675375016356 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "core/math.h" #include "config.h" #include #include #ifdef _MSC_VER # ifndef isinf # define isinf(x) (!_finite(x) && !_isnan(x)) # endif #endif int igraph_finite(double x) { #if HAVE_ISFINITE return isfinite(x); #elif HAVE_FINITE return finite(x); #else return (!isnan(x) & (x != IGRAPH_POSINFINITY) & (x != IGRAPH_NEGINFINITY)); #endif } double igraph_log2(const double a) { return log(a) / log(2.0); } int igraph_chebyshev_init(const double *dos, int nos, double eta) { int i, ii; double err; if (nos < 1) { return 0; } err = 0.0; i = 0; /* just to avoid compiler warnings */ for (ii = 1; ii <= nos; ii++) { i = nos - ii; err += fabs(dos[i]); if (err > eta) { return i; } } return i; } double igraph_chebyshev_eval(double x, const double *a, const int n) { double b0, b1, b2, twox; int i; if (n < 1 || n > 1000) { IGRAPH_WARNING("chebyshev_eval: argument out of domain"); return IGRAPH_NAN; } if (x < -1.1 || x > 1.1) { IGRAPH_WARNING("chebyshev_eval: argument out of domain"); return IGRAPH_NAN; } twox = x * 2; b2 = b1 = 0; b0 = 0; for (i = 1; i <= n; i++) { b2 = b1; b1 = b0; b0 = twox * b1 - b2 + a[n - i]; } return (b0 - b2) * 0.5; } double igraph_log1p(double x) { /* series for log1p on the interval -.375 to .375 * with weighted error 6.35e-32 * log weighted error 31.20 * significant figures required 30.93 * decimal places required 32.01 */ static const double alnrcs[43] = { +.10378693562743769800686267719098e+1, -.13364301504908918098766041553133e+0, +.19408249135520563357926199374750e-1, -.30107551127535777690376537776592e-2, +.48694614797154850090456366509137e-3, -.81054881893175356066809943008622e-4, +.13778847799559524782938251496059e-4, -.23802210894358970251369992914935e-5, +.41640416213865183476391859901989e-6, -.73595828378075994984266837031998e-7, +.13117611876241674949152294345011e-7, -.23546709317742425136696092330175e-8, +.42522773276034997775638052962567e-9, -.77190894134840796826108107493300e-10, +.14075746481359069909215356472191e-10, -.25769072058024680627537078627584e-11, +.47342406666294421849154395005938e-12, -.87249012674742641745301263292675e-13, +.16124614902740551465739833119115e-13, -.29875652015665773006710792416815e-14, +.55480701209082887983041321697279e-15, -.10324619158271569595141333961932e-15, +.19250239203049851177878503244868e-16, -.35955073465265150011189707844266e-17, +.67264542537876857892194574226773e-18, -.12602624168735219252082425637546e-18, +.23644884408606210044916158955519e-19, -.44419377050807936898878389179733e-20, +.83546594464034259016241293994666e-21, -.15731559416479562574899253521066e-21, +.29653128740247422686154369706666e-22, -.55949583481815947292156013226666e-23, +.10566354268835681048187284138666e-23, -.19972483680670204548314999466666e-24, +.37782977818839361421049855999999e-25, -.71531586889081740345038165333333e-26, +.13552488463674213646502024533333e-26, -.25694673048487567430079829333333e-27, +.48747756066216949076459519999999e-28, -.92542112530849715321132373333333e-29, +.17578597841760239233269760000000e-29, -.33410026677731010351377066666666e-30, +.63533936180236187354180266666666e-31, }; static IGRAPH_THREAD_LOCAL int nlnrel = 0; static IGRAPH_THREAD_LOCAL double xmin = 0.0; if (xmin == 0.0) { xmin = -1 + sqrt(DBL_EPSILON); /*was sqrt(d1mach(4)); */ } if (nlnrel == 0) { /* initialize chebychev coefficients */ nlnrel = igraph_chebyshev_init(alnrcs, 43, DBL_EPSILON / 20); /*was .1*d1mach(3)*/ } if (x == 0.) { return 0.; /* speed */ } if (x == -1) { return (IGRAPH_NEGINFINITY); } if (x < -1) { return (IGRAPH_NAN); } if (fabs(x) <= .375) { /* Improve on speed (only); again give result accurate to IEEE double precision: */ if (fabs(x) < .5 * DBL_EPSILON) { return x; } if ( (0 < x && x < 1e-8) || (-1e-9 < x && x < 0)) { return x * (1 - .5 * x); } /* else */ return x * (1 - x * igraph_chebyshev_eval(x / .375, alnrcs, nlnrel)); } /* else */ /* if (x < xmin) { */ /* /\* answer less than half precision because x too near -1 *\/ */ /* ML_ERROR(ME_PRECISION, "log1p"); */ /* } */ return log(1 + x); } double igraph_fmin(double a, double b) { if (b < a) { return b; } else { return a; } } double igraph_i_round(double X) { /* NaN */ if (X != X) { return X; } if (X < 0.0) { return floor(X); } return ceil(X); } #ifdef _MSC_VER /** * Internal function, replacement for snprintf * Used only in case of the Microsoft Visual C compiler which does not * provide a proper sprintf implementation. * * This implementation differs from the standard in the value returned * when the number of characters needed by the output, excluding the * terminating '\0' is larger than count */ int igraph_i_snprintf(char *buffer, size_t count, const char *format, ...) { int n; va_list args; if (count > 0) { va_start(args, format); n = _vsnprintf(buffer, count, format, args); buffer[count - 1] = 0; va_end(args); } else { n = 0; } return n; } #endif int igraph_is_nan(double x) { return isnan(x); } int igraph_is_inf(double x) { return isinf(x) != 0; } int igraph_is_posinf(double x) { return isinf(x) && x > 0; } int igraph_is_neginf(double x) { return isinf(x) && x < 0; } /** * \function igraph_almost_equals * Compare two double-precision floats with a tolerance * * Determines whether two double-precision floats are "almost equal" * to each other with a given level of tolerance on the relative error. * * \param a the first float * \param b the second float * \param eps the level of tolerance on the relative error. The relative * error is defined as \c "abs(a-b) / (abs(a) + abs(b))". The * two numbers are considered equal if this is less than \c eps. * * \return nonzero if the two floats are nearly equal to each other within * the given level of tolerance, zero otherwise */ int igraph_almost_equals(double a, double b, double eps) { return igraph_cmp_epsilon(a, b, eps) == 0 ? 1 : 0; } /* Use value-safe floating point math for igraph_cmp_epsilon() with * the Intel compiler. * * The Intel compiler rewrites arithmetic expressions for faster * evaluation by default. In the below function, it will evaluate * (eps * fabs(a) + eps * fabs(b)) as eps*(fabs(a) + fabs(b)). * However, this code path is taken precisely when fabs(a) + fabs(b) * overflows, thus this rearrangement of the expression causes * the function to return incorrect results, and some test failures. * To avoid this, we switch the Intel compiler to "precise" mode. */ #ifdef __INTEL_COMPILER #pragma float_control(push) #pragma float_control (precise, on) #endif /** * \function igraph_cmp_epsilon * Compare two double-precision floats with a tolerance * * Determines whether two double-precision floats are "almost equal" * to each other with a given level of tolerance on the relative error. * * \param a the first float * \param b the second float * \param eps the level of tolerance on the relative error. The relative * error is defined as \c "abs(a-b) / (abs(a) + abs(b))". The * two numbers are considered equal if this is less than \c eps. * * \return zero if the two floats are nearly equal to each other within * the given level of tolerance, positive number if the first float is * larger, negative number if the second float is larger */ int igraph_cmp_epsilon(double a, double b, double eps) { double diff; double abs_diff; double sum; if (a == b) { /* shortcut, handles infinities */ return 0; } diff = a - b; abs_diff = fabs(diff); sum = fabs(a) + fabs(b); if (a == 0 || b == 0 || sum < DBL_MIN) { /* a or b is zero or both are extremely close to it; relative * error is less meaningful here so just compare it with * epsilon */ return abs_diff < (eps * DBL_MIN) ? 0 : (diff < 0 ? -1 : 1); } else if (!isfinite(sum)) { /* addition overflow, so presumably |a| and |b| are both large; use a * different formulation */ return (abs_diff < (eps * fabs(a) + eps * fabs(b))) ? 0 : (diff < 0 ? -1 : 1); } else { return (abs_diff / sum < eps) ? 0 : (diff < 0 ? -1 : 1); } } #ifdef __INTEL_COMPILER #pragma float_control(pop) #endif leidenbase/src/core/math/bfgs.c0000644000176200001440000001644614447675375016143 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_nongraph.h" #include "core/interruption.h" #include "igraph_statusbar.h" #include /* This is from GNU R's optim.c, slightly adapted to igraph */ #define stepredn 0.2 #define acctol 0.0001 #define reltest 10.0 #define FALSE 0 #define TRUE 1 /* BFGS variable-metric method, based on Pascal code in J.C. Nash, `Compact Numerical Methods for Computers', 2nd edition, converted by p2c then re-crafted by B.D. Ripley */ int igraph_bfgs(igraph_vector_t *b, igraph_real_t *Fmin, igraph_scalar_function_t fminfn, igraph_vector_function_t fmingr, int maxit, int trace, igraph_real_t abstol, igraph_real_t reltol, int nREPORT, void *ex, igraph_integer_t *fncount, igraph_integer_t *grcount) { int n = (int) igraph_vector_size(b); igraph_bool_t accpoint, enough; igraph_vector_t g, t, X, c; igraph_matrix_t B; /* Lmatrix really */ int count, funcount, gradcount; igraph_real_t f, gradproj; int i, j, ilast, iter = 0; igraph_real_t s, steplength; igraph_real_t D1, D2; if (maxit <= 0) { *Fmin = fminfn(b, 0, ex); *fncount = 1; *grcount = 0; return 0; } if (nREPORT <= 0) { IGRAPH_ERROR("REPORT must be > 0 (method = \"BFGS\")", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&g, n); IGRAPH_VECTOR_INIT_FINALLY(&t, n); IGRAPH_VECTOR_INIT_FINALLY(&X, n); IGRAPH_VECTOR_INIT_FINALLY(&c, n); IGRAPH_MATRIX_INIT_FINALLY(&B, n, n); f = fminfn(b, 0, ex); if (!IGRAPH_FINITE(f)) { IGRAPH_ERROR("initial value in 'BFGS' is not finite", IGRAPH_DIVERGED); } if (trace) { igraph_statusf("initial value %f ", 0, f); } *Fmin = f; funcount = gradcount = 1; fmingr(b, 0, &g, ex); iter++; ilast = gradcount; do { IGRAPH_ALLOW_INTERRUPTION(); if (ilast == gradcount) { for (i = 0; i < n; i++) { for (j = 0; j < i; j++) { MATRIX(B, i, j) = 0.0; } MATRIX(B, i, i) = 1.0; } } for (i = 0; i < n; i++) { VECTOR(X)[i] = VECTOR(*b)[i]; VECTOR(c)[i] = VECTOR(g)[i]; } gradproj = 0.0; for (i = 0; i < n; i++) { s = 0.0; for (j = 0; j <= i; j++) { s -= MATRIX(B, i, j) * VECTOR(g)[j]; } for (j = i + 1; j < n; j++) { s -= MATRIX(B, j, i) * VECTOR(g)[j]; } VECTOR(t)[i] = s; gradproj += s * VECTOR(g)[i]; } if (gradproj < 0.0) { /* search direction is downhill */ steplength = 1.0; accpoint = FALSE; do { count = 0; for (i = 0; i < n; i++) { VECTOR(*b)[i] = VECTOR(X)[i] + steplength * VECTOR(t)[i]; if (reltest + VECTOR(X)[i] == reltest + VECTOR(*b)[i]) { /* no change */ count++; } } if (count < n) { f = fminfn(b, 0, ex); funcount++; accpoint = IGRAPH_FINITE(f) && (f <= *Fmin + gradproj * steplength * acctol); if (!accpoint) { steplength *= stepredn; } } } while (!(count == n || accpoint)); enough = (f > abstol) && fabs(f - *Fmin) > reltol * (fabs(*Fmin) + reltol); /* stop if value if small or if relative change is low */ if (!enough) { count = n; *Fmin = f; } if (count < n) {/* making progress */ *Fmin = f; fmingr(b, 0, &g, ex); gradcount++; iter++; D1 = 0.0; for (i = 0; i < n; i++) { VECTOR(t)[i] = steplength * VECTOR(t)[i]; VECTOR(c)[i] = VECTOR(g)[i] - VECTOR(c)[i]; D1 += VECTOR(t)[i] * VECTOR(c)[i]; } if (D1 > 0) { D2 = 0.0; for (i = 0; i < n; i++) { s = 0.0; for (j = 0; j <= i; j++) { s += MATRIX(B, i, j) * VECTOR(c)[j]; } for (j = i + 1; j < n; j++) { s += MATRIX(B, j, i) * VECTOR(c)[j]; } VECTOR(X)[i] = s; D2 += s * VECTOR(c)[i]; } D2 = 1.0 + D2 / D1; for (i = 0; i < n; i++) { for (j = 0; j <= i; j++) MATRIX(B, i, j) += (D2 * VECTOR(t)[i] * VECTOR(t)[j] - VECTOR(X)[i] * VECTOR(t)[j] - VECTOR(t)[i] * VECTOR(X)[j]) / D1; } } else { /* D1 < 0 */ ilast = gradcount; } } else { /* no progress */ if (ilast < gradcount) { count = 0; ilast = gradcount; } } } else { /* uphill search */ count = 0; if (ilast == gradcount) { count = n; } else { ilast = gradcount; } /* Resets unless has just been reset */ } if (trace && (iter % nREPORT == 0)) { igraph_statusf("iter%4d value %f", 0, iter, f); } if (iter >= maxit) { break; } if (gradcount - ilast > 2 * n) { ilast = gradcount; /* periodic restart */ } } while (count != n || ilast != gradcount); if (trace) { igraph_statusf("final value %f ", 0, *Fmin); if (iter < maxit) { igraph_status("converged", 0); } else { igraph_statusf("stopped after %i iterations", 0, iter); } } *fncount = funcount; *grcount = gradcount; igraph_matrix_destroy(&B); igraph_vector_destroy(&c); igraph_vector_destroy(&X); igraph_vector_destroy(&t); igraph_vector_destroy(&g); IGRAPH_FINALLY_CLEAN(5); return (iter < maxit) ? 0 : IGRAPH_DIVERGED; } leidenbase/src/core/math/complex.c0000644000176200001440000002740514447675375016666 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_complex.h" #include "core/math.h" #include /** * \example igraph_complex.c */ igraph_complex_t igraph_complex(igraph_real_t x, igraph_real_t y) { igraph_complex_t res; IGRAPH_REAL(res) = x; IGRAPH_IMAG(res) = y; return res; } igraph_complex_t igraph_complex_polar(igraph_real_t r, igraph_real_t theta) { igraph_complex_t res; IGRAPH_REAL(res) = r * cos(theta); IGRAPH_IMAG(res) = r * sin(theta); return res; } igraph_bool_t igraph_complex_eq_tol(igraph_complex_t z1, igraph_complex_t z2, igraph_real_t tol) { if (fabs(IGRAPH_REAL(z1) - IGRAPH_REAL(z2)) > tol || fabs(IGRAPH_IMAG(z1) - IGRAPH_IMAG(z2)) > tol) { return 0; } return 1; } igraph_real_t igraph_complex_mod(igraph_complex_t z) { igraph_real_t x = IGRAPH_REAL(z); igraph_real_t y = IGRAPH_IMAG(z); return hypot(x, y); } igraph_real_t igraph_complex_arg(igraph_complex_t z) { igraph_real_t x = IGRAPH_REAL(z); igraph_real_t y = IGRAPH_IMAG(z); if (x == 0.0 && y == 0.0) { return 0.0; } return atan2(y, x); } igraph_complex_t igraph_complex_add(igraph_complex_t z1, igraph_complex_t z2) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z1) + IGRAPH_REAL(z2); IGRAPH_IMAG(res) = IGRAPH_IMAG(z1) + IGRAPH_IMAG(z2); return res; } igraph_complex_t igraph_complex_sub(igraph_complex_t z1, igraph_complex_t z2) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z1) - IGRAPH_REAL(z2); IGRAPH_IMAG(res) = IGRAPH_IMAG(z1) - IGRAPH_IMAG(z2); return res; } igraph_complex_t igraph_complex_mul(igraph_complex_t z1, igraph_complex_t z2) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z1) * IGRAPH_REAL(z2) - IGRAPH_IMAG(z1) * IGRAPH_IMAG(z2); IGRAPH_IMAG(res) = IGRAPH_REAL(z1) * IGRAPH_IMAG(z2) + IGRAPH_IMAG(z1) * IGRAPH_REAL(z2); return res; } igraph_complex_t igraph_complex_div(igraph_complex_t z1, igraph_complex_t z2) { igraph_complex_t res; igraph_real_t z1r = IGRAPH_REAL(z1), z1i = IGRAPH_IMAG(z1); igraph_real_t z2r = IGRAPH_REAL(z2), z2i = IGRAPH_IMAG(z2); igraph_real_t s = 1.0 / igraph_complex_abs(z2); igraph_real_t sz2r = s * z2r; igraph_real_t sz2i = s * z2i; IGRAPH_REAL(res) = (z1r * sz2r + z1i * sz2i) * s; IGRAPH_IMAG(res) = (z1i * sz2r - z1r * sz2i) * s; return res; } igraph_complex_t igraph_complex_add_real(igraph_complex_t z, igraph_real_t x) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z) + x; IGRAPH_IMAG(res) = IGRAPH_IMAG(z); return res; } igraph_complex_t igraph_complex_add_imag(igraph_complex_t z, igraph_real_t y) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z); IGRAPH_IMAG(res) = IGRAPH_IMAG(z) + y; return res; } igraph_complex_t igraph_complex_sub_real(igraph_complex_t z, igraph_real_t x) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z) - x; IGRAPH_IMAG(res) = IGRAPH_IMAG(z); return res; } igraph_complex_t igraph_complex_sub_imag(igraph_complex_t z, igraph_real_t y) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z); IGRAPH_IMAG(res) = IGRAPH_IMAG(z) - y; return res; } igraph_complex_t igraph_complex_mul_real(igraph_complex_t z, igraph_real_t x) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z) * x; IGRAPH_IMAG(res) = IGRAPH_IMAG(z) * x; return res; } igraph_complex_t igraph_complex_mul_imag(igraph_complex_t z, igraph_real_t y) { igraph_complex_t res; IGRAPH_REAL(res) = - IGRAPH_IMAG(z) * y; IGRAPH_IMAG(res) = IGRAPH_REAL(z) * y; return res; } igraph_complex_t igraph_complex_div_real(igraph_complex_t z, igraph_real_t x) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z) / x; IGRAPH_IMAG(res) = IGRAPH_IMAG(z) / x; return res; } igraph_complex_t igraph_complex_div_imag(igraph_complex_t z, igraph_real_t y) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_IMAG(z) / y; IGRAPH_IMAG(res) = - IGRAPH_REAL(z) / y; return res; } igraph_complex_t igraph_complex_conj(igraph_complex_t z) { igraph_complex_t res; IGRAPH_REAL(res) = IGRAPH_REAL(z); IGRAPH_IMAG(res) = - IGRAPH_IMAG(z); return res; } igraph_complex_t igraph_complex_neg(igraph_complex_t z) { igraph_complex_t res; IGRAPH_REAL(res) = - IGRAPH_REAL(z); IGRAPH_IMAG(res) = - IGRAPH_IMAG(z); return res; } igraph_complex_t igraph_complex_inv(igraph_complex_t z) { igraph_complex_t res; igraph_real_t s = 1.0 / igraph_complex_abs(z); IGRAPH_REAL(res) = (IGRAPH_REAL(z) * s) * s; IGRAPH_IMAG(res) = - (IGRAPH_IMAG(z) * s) * s; return res; } igraph_real_t igraph_complex_abs(igraph_complex_t z) { return hypot(IGRAPH_REAL(z), IGRAPH_IMAG(z)); } igraph_real_t igraph_complex_logabs(igraph_complex_t z) { igraph_real_t xabs = fabs(IGRAPH_REAL(z)); igraph_real_t yabs = fabs(IGRAPH_IMAG(z)); igraph_real_t max, u; if (xabs >= yabs) { max = xabs; u = yabs / xabs; } else { max = yabs; u = xabs / yabs; } return log (max) + 0.5 * log1p (u * u); } igraph_complex_t igraph_complex_sqrt(igraph_complex_t z) { igraph_complex_t res; if (IGRAPH_REAL(z) == 0.0 && IGRAPH_IMAG(z) == 0.0) { IGRAPH_REAL(res) = IGRAPH_IMAG(res) = 0.0; } else { igraph_real_t x = fabs (IGRAPH_REAL(z)); igraph_real_t y = fabs (IGRAPH_IMAG(z)); igraph_real_t w; if (x >= y) { igraph_real_t t = y / x; w = sqrt (x) * sqrt (0.5 * (1.0 + sqrt (1.0 + t * t))); } else { igraph_real_t t = x / y; w = sqrt (y) * sqrt (0.5 * (t + sqrt (1.0 + t * t))); } if (IGRAPH_REAL(z) >= 0.0) { igraph_real_t ai = IGRAPH_IMAG(z); IGRAPH_REAL(res) = w; IGRAPH_IMAG(res) = ai / (2.0 * w); } else { igraph_real_t ai = IGRAPH_IMAG(z); igraph_real_t vi = (ai >= 0) ? w : -w; IGRAPH_REAL(res) = ai / (2.0 * vi); IGRAPH_IMAG(res) = vi; } } return res; } igraph_complex_t igraph_complex_sqrt_real(igraph_real_t x) { igraph_complex_t res; if (x >= 0) { IGRAPH_REAL(res) = sqrt(x); IGRAPH_IMAG(res) = 0.0; } else { IGRAPH_REAL(res) = 0.0; IGRAPH_IMAG(res) = sqrt(-x); } return res; } igraph_complex_t igraph_complex_exp(igraph_complex_t z) { igraph_real_t rho = exp(IGRAPH_REAL(z)); igraph_real_t theta = IGRAPH_IMAG(z); igraph_complex_t res; IGRAPH_REAL(res) = rho * cos(theta); IGRAPH_IMAG(res) = rho * sin(theta); return res; } igraph_complex_t igraph_complex_pow(igraph_complex_t z1, igraph_complex_t z2) { igraph_complex_t res; if (IGRAPH_REAL(z1) == 0 && IGRAPH_IMAG(z1) == 0.0) { if (IGRAPH_REAL(z2) == 0 && IGRAPH_IMAG(z2) == 0.0) { IGRAPH_REAL(res) = 1.0; IGRAPH_IMAG(res) = 0.0; } else { IGRAPH_REAL(res) = IGRAPH_IMAG(res) = 0.0; } } else if (IGRAPH_REAL(z2) == 1.0 && IGRAPH_IMAG(z2) == 0.0) { IGRAPH_REAL(res) = IGRAPH_REAL(z1); IGRAPH_IMAG(res) = IGRAPH_IMAG(z1); } else if (IGRAPH_REAL(z2) == -1.0 && IGRAPH_IMAG(z2) == 0.0) { res = igraph_complex_inv(z1); } else { igraph_real_t logr = igraph_complex_logabs (z1); igraph_real_t theta = igraph_complex_arg (z1); igraph_real_t z2r = IGRAPH_REAL(z2), z2i = IGRAPH_IMAG(z2); igraph_real_t rho = exp (logr * z2r - z2i * theta); igraph_real_t beta = theta * z2r + z2i * logr; IGRAPH_REAL(res) = rho * cos(beta); IGRAPH_IMAG(res) = rho * sin(beta); } return res; } igraph_complex_t igraph_complex_pow_real(igraph_complex_t z, igraph_real_t x) { igraph_complex_t res; if (IGRAPH_REAL(z) == 0.0 && IGRAPH_IMAG(z) == 0.0) { if (x == 0) { IGRAPH_REAL(res) = 1.0; IGRAPH_IMAG(res) = 0.0; } else { IGRAPH_REAL(res) = IGRAPH_IMAG(res) = 0.0; } } else { igraph_real_t logr = igraph_complex_logabs(z); igraph_real_t theta = igraph_complex_arg(z); igraph_real_t rho = exp (logr * x); igraph_real_t beta = theta * x; IGRAPH_REAL(res) = rho * cos(beta); IGRAPH_IMAG(res) = rho * sin(beta); } return res; } igraph_complex_t igraph_complex_log(igraph_complex_t z) { igraph_complex_t res; IGRAPH_REAL(res) = igraph_complex_logabs(z); IGRAPH_IMAG(res) = igraph_complex_arg(z); return res; } igraph_complex_t igraph_complex_log10(igraph_complex_t z) { return igraph_complex_mul_real(igraph_complex_log(z), 1 / log(10.0)); } igraph_complex_t igraph_complex_log_b(igraph_complex_t z, igraph_complex_t b) { return igraph_complex_div (igraph_complex_log(z), igraph_complex_log(b)); } igraph_complex_t igraph_complex_sin(igraph_complex_t z) { igraph_real_t zr = IGRAPH_REAL(z); igraph_real_t zi = IGRAPH_IMAG(z); igraph_complex_t res; if (zi == 0.0) { IGRAPH_REAL(res) = sin(zr); IGRAPH_IMAG(res) = 0.0; } else { IGRAPH_REAL(res) = sin(zr) * cosh(zi); IGRAPH_IMAG(res) = cos(zr) * sinh(zi); } return res; } igraph_complex_t igraph_complex_cos(igraph_complex_t z) { igraph_real_t zr = IGRAPH_REAL(z); igraph_real_t zi = IGRAPH_IMAG(z); igraph_complex_t res; if (zi == 0.0) { IGRAPH_REAL(res) = cos(zr); IGRAPH_IMAG(res) = 0.0; } else { IGRAPH_REAL(res) = cos(zr) * cosh(zi); IGRAPH_IMAG(res) = sin(zr) * sinh(-zi); } return res; } igraph_complex_t igraph_complex_tan(igraph_complex_t z) { igraph_real_t zr = IGRAPH_REAL(z); igraph_real_t zi = IGRAPH_IMAG(z); igraph_complex_t res; if (fabs (zi) < 1) { igraph_real_t D = pow (cos (zr), 2.0) + pow (sinh (zi), 2.0); IGRAPH_REAL(res) = 0.5 * sin (2 * zr) / D; IGRAPH_IMAG(res) = 0.5 * sinh (2 * zi) / D; } else { igraph_real_t u = exp (-zi); igraph_real_t C = 2 * u / (1 - pow (u, 2.0)); igraph_real_t D = 1 + pow (cos (zr), 2.0) * pow (C, 2.0); igraph_real_t S = pow (C, 2.0); igraph_real_t T = 1.0 / tanh (zi); IGRAPH_REAL(res) = 0.5 * sin (2 * zr) * S / D; IGRAPH_IMAG(res) = T / D; } return res; } igraph_complex_t igraph_complex_sec(igraph_complex_t z) { return igraph_complex_inv(igraph_complex_cos(z)); } igraph_complex_t igraph_complex_csc(igraph_complex_t z) { return igraph_complex_inv(igraph_complex_sin(z)); } igraph_complex_t igraph_complex_cot(igraph_complex_t z) { return igraph_complex_inv(igraph_complex_tan(z)); } leidenbase/src/core/isomorphism/0000755000176200001440000000000014532173045016441 5ustar liggesusersleidenbase/src/core/isomorphism/bliss/0000755000176200001440000000000014532326115017553 5ustar liggesusersleidenbase/src/core/isomorphism/bliss/utils.cc0000644000176200001440000000273514447675374021254 0ustar liggesusers#include #include "utils.hh" /* Allow using 'and' instead of '&&' with MSVC */ #if _MSC_VER #include #endif /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { bool is_permutation(const unsigned int N, const unsigned int* perm) { if(N == 0) return true; std::vector m(N, false); for(unsigned int i = 0; i < N; i++) { if(perm[i] >= N) return false; if(m[perm[i]]) return false; m[perm[i]] = true; } return true; } bool is_permutation(const std::vector& perm) { const unsigned int N = perm.size(); if(N == 0) return true; std::vector m(N, false); for(unsigned int i = 0; i < N; i++) { if(perm[i] >= N) return false; if(m[perm[i]]) return false; m[perm[i]] = true; } return true; } } // namespace bliss leidenbase/src/core/isomorphism/bliss/heap.hh0000644000176200001440000000404714447675374021041 0ustar liggesusers#ifndef BLISS_HEAP_HH #define BLISS_HEAP_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { /** * \brief A capacity bounded heap data structure. */ class Heap { unsigned int N; unsigned int n; unsigned int *array; void upheap(unsigned int k); void downheap(unsigned int k); public: /** * Create a new heap. * init() must be called after this. */ Heap(); ~Heap(); /** * Initialize the heap to have the capacity to hold \e size elements. */ void init(const unsigned int size); /** * Is the heap empty? * Time complexity is O(1). */ bool is_empty() const {return n == 0; } /** * Remove all the elements in the heap. * Time complexity is O(1). */ void clear() {n = 0; } /** * Insert the element \a e in the heap. * Time complexity is O(log(N)), where N is the number of elements * currently in the heap. */ void insert(const unsigned int e); /** * Return the smallest element in the heap. * Time complexity is O(1). */ unsigned int smallest() const; /** * Remove and return the smallest element in the heap. * Time complexity is O(log(N)), where N is the number of elements * currently in the heap. */ unsigned int remove(); /** * Get the number of elements in the heap. */ unsigned int size() const {return n; } }; } // namespace bliss #endif // BLISS_HEAP_HH leidenbase/src/core/isomorphism/bliss/uintseqhash.hh0000644000176200001440000000371514447675374022461 0ustar liggesusers#ifndef BLISS_UINTSEQHASH_HH #define BLISS_UINTSEQHASH_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { /** * \brief A updatable hash for sequences of unsigned ints. */ class UintSeqHash { protected: unsigned int h; public: UintSeqHash() {h = 0; } UintSeqHash(const UintSeqHash &other) {h = other.h; } UintSeqHash& operator=(const UintSeqHash &other) {h = other.h; return *this; } /** Reset the hash value. */ void reset() {h = 0; } /** Add the unsigned int \a n to the sequence. */ void update(unsigned int n); /** Get the hash value of the sequence seen so far. */ unsigned int get_value() const {return h; } /** Compare the hash values of this and \a other. * Return -1/0/1 if the value of this is smaller/equal/greater than * that of \a other. */ int cmp(const UintSeqHash &other) const { return (h < other.h)?-1:((h == other.h)?0:1); } /** An abbreviation for cmp(other) < 0 */ bool is_lt(const UintSeqHash &other) const {return cmp(other) < 0; } /** An abbreviation for cmp(other) <= 0 */ bool is_le(const UintSeqHash &other) const {return cmp(other) <= 0; } /** An abbreviation for cmp(other) == 0 */ bool is_equal(const UintSeqHash &other) const {return cmp(other) == 0; } }; } // namespace bliss #endif // BLISS_UINTSEQHASH_HH leidenbase/src/core/isomorphism/bliss/kqueue.hh0000644000176200001440000000636514447675374021430 0ustar liggesusers#ifndef BLISS_KQUEUE_HH #define BLISS_KQUEUE_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ #include #include namespace bliss { /** * \brief A simple implementation of queues with fixed maximum capacity. */ template class KQueue { public: /** * Create a new queue with capacity zero. * The function init() should be called next. */ KQueue(); ~KQueue(); /** * Initialize the queue to have the capacity to hold at most \a N elements. */ void init(const unsigned int N); /** Is the queue empty? */ bool is_empty() const; /** Return the number of elements in the queue. */ unsigned int size() const; /** Remove all the elements in the queue. */ void clear(); /** Return (but don't remove) the first element in the queue. */ Type front() const; /** Remove and return the first element of the queue. */ Type pop_front(); /** Push the element \a e in the front of the queue. */ void push_front(Type e); /** Remove and return the last element of the queue. */ Type pop_back(); /** Push the element \a e in the back of the queue. */ void push_back(Type e); private: Type *entries, *end; Type *head, *tail; }; template KQueue::KQueue() { entries = nullptr; end = nullptr; head = nullptr; tail = nullptr; } template KQueue::~KQueue() { delete[] entries; entries = nullptr; end = nullptr; head = nullptr; tail = nullptr; } template void KQueue::init(const unsigned int k) { assert(k > 0); delete[] entries; entries = new Type[k+1]; end = entries + k + 1; head = entries; tail = head; } template void KQueue::clear() { head = entries; tail = head; } template bool KQueue::is_empty() const { return head == tail; } template unsigned int KQueue::size() const { if(tail >= head) return(tail - head); return (end - head) + (tail - entries); } template Type KQueue::front() const { assert(head != tail); return *head; } template Type KQueue::pop_front() { assert(head != tail); Type *old_head = head; head++; if(head == end) head = entries; return *old_head; } template void KQueue::push_front(Type e) { if(head == entries) head = end - 1; else head--; assert(head != tail); *head = e; } template void KQueue::push_back(Type e) { *tail = e; tail++; if(tail == end) tail = entries; assert(head != tail); } } // namespace bliss #endif // BLISS_KQUEUE_HH leidenbase/src/core/isomorphism/bliss/igraph-changes.md0000644000176200001440000000236314447675374023004 0ustar liggesusersThis file lists changes that were made to the original Bliss package (version 0.75) to integrate it into igraph. Exclude `CMakeLists.txt`, `Doxyfile`, `Makefile-manual`, `readme.txt`. Make sure not to accidentally overwrite igraph's own `bliss/CMakeLists.txt`. Removed `bliss.cc`, `bliss_C.cc`, `bliss_C.h`. Remove `timer.hh`. Remove references to `timer.hh` and `Timer` class in `graph.cc`. Replace `#pragma once` by traditional header guards in all headers. ### In `bignum.hh`: Replace `#include ` by `#include "internal/gmp_internal.h"`. At the beginning, add `#define BLISS_USE_GMP`. Verify that this macro is only used in this file. ### In `defs.cc` and `defs.hh`: Remove the `...` argument from `fatal_error` for simplicity, and make the function simply invoke `IGRAPH_FATAL`. ### In `graph.cc`: Define `_INTERNAL_ERROR` in terms of `IGRAPH_FATAL`. ### MSVC compatibility Bliss uses `and`, `or`, etc. instead of `&&`, `||`, etc. These are not supported by MSVC by default. Bliss 0.74 uses the `/permissive` option to enable support in MSVC, but this option is only supported wit VS2019. Instead, in igraph we add the following where relevant: ``` /* Allow using 'and' instead of '&&' with MSVC */ #if _MSC_VER #include #endif ``` leidenbase/src/core/isomorphism/bliss/graph.hh0000644000176200001440000007172414447675374021233 0ustar liggesusers#ifndef BLISS_GRAPH_HH #define BLISS_GRAPH_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ /** * \namespace bliss * The namespace bliss contains all the classes and functions of the bliss * tool except for the C programming language API. */ namespace bliss { class AbstractGraph; } // #include #include #include #include "stats.hh" #include "kstack.hh" #include "kqueue.hh" #include "heap.hh" #include "orbit.hh" #include "partition.hh" #include "uintseqhash.hh" namespace bliss { /** * \brief An abstract base class for different types of graphs. */ class AbstractGraph { friend class Partition; public: AbstractGraph(); virtual ~AbstractGraph(); #if 0 /** * Set the verbose output level for the algorithms. * \param level the level of verbose output, 0 means no verbose output */ void set_verbose_level(const unsigned int level); /** * Set the file stream for the verbose output. * \param fp the file stream; if null, no verbose output is written */ void set_verbose_file(FILE * const fp); #endif /** * Add a new vertex with color \a color in the graph and return its index. */ virtual unsigned int add_vertex(const unsigned int color = 0) = 0; /** * Add an edge between vertices \a source and \a target. * Duplicate edges between vertices are ignored but try to avoid introducing * them in the first place as they are not ignored immediately but will * consume memory and computation resources for a while. */ virtual void add_edge(const unsigned int source, const unsigned int target) = 0; /** * Change the color of the vertex \a vertex to \a color. */ virtual void change_color(const unsigned int vertex, const unsigned int color) = 0; /** * Check whether \a perm is an automorphism of this graph. * Unoptimized, mainly for debugging purposes. */ virtual bool is_automorphism(const std::vector& perm) const = 0; /** Activate/deactivate failure recording. * May not be called during the search, i.e. from an automorphism reporting * hook function. * \param active if true, activate failure recording, deactivate otherwise */ void set_failure_recording(const bool active) {assert(!in_search); opt_use_failure_recording = active;} /** Activate/deactivate component recursion. * The choice affects the computed canonical labelings; * therefore, if you want to compare whether two graphs are isomorphic by * computing and comparing (for equality) their canonical versions, * be sure to use the same choice for both graphs. * May not be called during the search, i.e. from an automorphism reporting * hook function. * \param active if true, activate component recursion, deactivate otherwise */ void set_component_recursion(const bool active) {assert(!in_search); opt_use_comprec = active;} /** * Return the number of vertices in the graph. */ virtual unsigned int get_nof_vertices() const = 0; /** * Return a new graph that is the result of applying the permutation \a perm * to this graph. This graph is not modified. * \a perm must contain N=this.get_nof_vertices() elements and be a bijection * on {0,1,...,N-1}, otherwise the result is undefined or a segfault. */ virtual AbstractGraph* permute(const unsigned int* const perm) const = 0; virtual AbstractGraph* permute(const std::vector& perm) const = 0; /** * Find a set of generators for the automorphism group of the graph. * The function \a report (if non-null) is called each time a new generator * for the automorphism group is found. * The first argument \a n for the function * is the length of the automorphism (equal to get_nof_vertices()), and * the second argument \a aut is the automorphism * (a bijection on {0,...,get_nof_vertices()-1}). * The memory for the automorphism \a aut will be invalidated immediately * after the return from the \a report function; * if you want to use the automorphism later, you have to take a copy of it. * Do not call any member functions from the \a report function. * * The search statistics are copied in \a stats. * * If the \a terminate function argument is given, * it is called in each search tree node: if the function returns true, * then the search is terminated and thus not all the automorphisms * may have been generated. * The \a terminate function may be used to limit the time spent in bliss * in case the graph is too difficult under the available time constraints. * If used, keep the function simple to evaluate so that * it does not consume too much time. */ void find_automorphisms(Stats& stats, const std::function& report = nullptr, const std::function& terminate = nullptr); /** * Otherwise the same as find_automorphisms() except that * a canonical labeling of the graph (a bijection on * {0,...,get_nof_vertices()-1}) is returned. * The memory allocated for the returned canonical labeling will remain * valid only until the next call to a member function with the exception * that constant member functions (for example, bliss::Graph::permute()) can * be called without invalidating the labeling. * To compute the canonical version of an undirected graph, call this * function and then bliss::Graph::permute() with the returned canonical * labeling. * Note that the computed canonical version may depend on the applied version * of bliss as well as on some other options (for instance, the splitting * heuristic selected with bliss::Graph::set_splitting_heuristic()). * * If the \a terminate function argument is given, * it is called in each search tree node: if the function returns true, * then the search is terminated and thus (i) not all the automorphisms * may have been generated and (ii) the returned labeling may not * be canonical. * The \a terminate function may be used to limit the time spent in bliss * in case the graph is too difficult under the available time constraints. * If used, keep the function simple to evaluate so that * it does not consume too much time. */ const unsigned int* canonical_form(Stats& stats, const std::function& report = nullptr, const std::function& terminate = nullptr); /** * Get a hash value for the graph. * \return the hash value */ virtual unsigned int get_hash() = 0; /** * Disable/enable the "long prune" method. * The choice affects the computed canonical labelings; * therefore, if you want to compare whether two graphs are isomorphic by * computing and comparing (for equality) their canonical versions, * be sure to use the same choice for both graphs. * May not be called during the search, i.e. from an automorphism reporting * hook function. * \param active if true, activate "long prune", deactivate otherwise */ void set_long_prune_activity(const bool active) { assert(!in_search); opt_use_long_prune = active; } protected: /** \internal * How much verbose output is produced (0 means none) */ /* unsigned int verbose_level; */ /** \internal * The output stream for verbose output. */ /* FILE *verbstr; */ protected: /** \internal * The ordered partition used in the search algorithm. */ Partition p; /** \internal * Whether the search for automorphisms and a canonical labeling is * in progress. */ bool in_search; /** \internal * Is failure recording in use? */ bool opt_use_failure_recording; /* The "tree-specific" invariant value for the point when current path * got different from the first path */ unsigned int failure_recording_fp_deviation; /** \internal * Is component recursion in use? */ bool opt_use_comprec; unsigned int refine_current_path_certificate_index; bool refine_compare_certificate = false; bool refine_equal_to_first = false; unsigned int refine_first_path_subcertificate_end; int refine_cmp_to_best; unsigned int refine_best_path_subcertificate_end; static const unsigned int CERT_SPLIT = 0; //UINT_MAX; static const unsigned int CERT_EDGE = 1; //UINT_MAX-1; /** \internal * Add a triple (v1,v2,v3) in the certificate. * May modify refine_equal_to_first and refine_cmp_to_best. * May also update eqref_hash and failure_recording_fp_deviation. */ void cert_add(const unsigned int v1, const unsigned int v2, const unsigned int v3); /** \internal * Add a redundant triple (v1,v2,v3) in the certificate. * Can also just dicard the triple. * May modify refine_equal_to_first and refine_cmp_to_best. * May also update eqref_hash and failure_recording_fp_deviation. */ void cert_add_redundant(const unsigned int x, const unsigned int y, const unsigned int z); /**\internal * Is the long prune method in use? */ bool opt_use_long_prune; /**\internal * Maximum amount of memory (in megabytes) available for * the long prune method */ static const unsigned int long_prune_options_max_mem = 50; /**\internal * Maximum amount of automorphisms stored for the long prune method; * less than this is stored if the memory limit above is reached first */ static const unsigned int long_prune_options_max_stored_auts = 100; unsigned int long_prune_max_stored_autss; std::vector *> long_prune_fixed; std::vector *> long_prune_mcrs; std::vector long_prune_temp; unsigned int long_prune_begin; unsigned int long_prune_end; /** \internal * Initialize the "long prune" data structures. */ void long_prune_init(); /** \internal * Release the memory allocated for "long prune" data structures. */ void long_prune_deallocate(); void long_prune_add_automorphism(const unsigned int *aut); std::vector& long_prune_get_fixed(const unsigned int index); std::vector& long_prune_allocget_fixed(const unsigned int index); std::vector& long_prune_get_mcrs(const unsigned int index); std::vector& long_prune_allocget_mcrs(const unsigned int index); /** \internal * Swap the i:th and j:th stored automorphism information; * i and j must be "in window, i.e. in [long_prune_begin,long_prune_end[ */ void long_prune_swap(const unsigned int i, const unsigned int j); /* * Data structures and routines for refining the partition p into equitable */ Heap neighbour_heap; virtual bool split_neighbourhood_of_unit_cell(Partition::Cell * const) = 0; virtual bool split_neighbourhood_of_cell(Partition::Cell * const) = 0; void refine_to_equitable(); void refine_to_equitable(Partition::Cell * const unit_cell); void refine_to_equitable(Partition::Cell * const unit_cell1, Partition::Cell * const unit_cell2); /** \internal * \return false if it was detected that the current certificate * is different from the first and/or best (whether this is checked * depends on in_search and refine_compare_certificate flags. */ bool do_refine_to_equitable(); unsigned int eqref_max_certificate_index; /** \internal * Whether eqref_hash is updated during equitable refinement process. */ bool compute_eqref_hash; UintSeqHash eqref_hash; /** \internal * Check whether the current partition p is equitable. * Performance: very slow, use only for debugging purposes. */ virtual bool is_equitable() const = 0; unsigned int *first_path_labeling; unsigned int *first_path_labeling_inv; Orbit first_path_orbits; unsigned int *first_path_automorphism; unsigned int *best_path_labeling; unsigned int *best_path_labeling_inv; Orbit best_path_orbits; unsigned int *best_path_automorphism; void update_labeling(unsigned int * const lab); void update_labeling_and_its_inverse(unsigned int * const lab, unsigned int * const lab_inv); void update_orbit_information(Orbit &o, const unsigned int *perm); void reset_permutation(unsigned int *perm); /* Mainly for debugging purposes */ virtual bool is_automorphism(unsigned int* const perm) const = 0; std::vector certificate_current_path; std::vector certificate_first_path; std::vector certificate_best_path; unsigned int certificate_index; virtual void initialize_certificate() = 0; virtual void remove_duplicate_edges() = 0; virtual void make_initial_equitable_partition() = 0; virtual Partition::Cell* find_next_cell_to_be_splitted(Partition::Cell *cell) = 0; /** \struct PathInfo * * A structure for holding first, current, and best path information. */ typedef struct { unsigned int splitting_element; unsigned int certificate_index; unsigned int subcertificate_length; UintSeqHash eqref_hash; } PathInfo; void search(const bool canonical, Stats &stats, const std::function& report_function = nullptr, const std::function& terminate = nullptr); void (*report_hook)(void *user_param, unsigned int n, const unsigned int *aut); void *report_user_param; /* * * Nonuniform component recursion (NUCR) * */ /* The currently traversed component */ unsigned int cr_level; /** @internal @class CR_CEP * The "Component End Point" data structure */ class CR_CEP { public: /** At which level in the search was this CEP created */ unsigned int creation_level; /** The current component has been fully traversed when the partition has * this many discrete cells left */ unsigned int discrete_cell_limit; /** The component to be traversed after the current one */ unsigned int next_cr_level; /** The next component end point */ unsigned int next_cep_index; bool first_checked; bool best_checked; }; /** \internal * A stack for storing Component End Points */ std::vector cr_cep_stack; /** \internal * Find the first non-uniformity component at the component recursion * level \a level. * The component is stored in \a cr_component. * If no component is found, \a cr_component is empty. * Returns false if all the cells in the component recursion level \a level * were discrete. * Modifies the max_ival and max_ival_count fields of Partition:Cell * (assumes that they are 0 when called and * quarantees that they are 0 when returned). */ virtual bool nucr_find_first_component(const unsigned int level) = 0; virtual bool nucr_find_first_component(const unsigned int level, std::vector& component, unsigned int& component_elements, Partition::Cell*& sh_return) = 0; /** \internal * The non-uniformity component found by nucr_find_first_component() * is stored here. */ std::vector cr_component; /** \internal * The number of vertices in the component \a cr_component */ unsigned int cr_component_elements; }; /** * \brief The class for undirected, vertex colored graphs. * * Multiple edges between vertices are not allowed (i.e., are ignored). */ class Graph : public AbstractGraph { public: /** * The possible splitting heuristics. * The selected splitting heuristics affects the computed canonical * labelings; therefore, if you want to compare whether two graphs * are isomorphic by computing and comparing (for equality) their * canonical versions, be sure to use the same splitting heuristics * for both graphs. */ typedef enum { /** First non-unit cell. * Very fast but may result in large search spaces on difficult graphs. * Use for large but easy graphs. */ shs_f = 0, /** First smallest non-unit cell. * Fast, should usually produce smaller search spaces than shs_f. */ shs_fs, /** First largest non-unit cell. * Fast, should usually produce smaller search spaces than shs_f. */ shs_fl, /** First maximally non-trivially connected non-unit cell. * Not so fast, should usually produce smaller search spaces than shs_f, * shs_fs, and shs_fl. */ shs_fm, /** First smallest maximally non-trivially connected non-unit cell. * Not so fast, should usually produce smaller search spaces than shs_f, * shs_fs, and shs_fl. */ shs_fsm, /** First largest maximally non-trivially connected non-unit cell. * Not so fast, should usually produce smaller search spaces than shs_f, * shs_fs, and shs_fl. */ shs_flm } SplittingHeuristic; protected: class Vertex { public: Vertex(); ~Vertex(); void add_edge(const unsigned int other_vertex); void remove_duplicate_edges(std::vector& tmp); void sort_edges(); unsigned int color; std::vector edges; unsigned int nof_edges() const {return edges.size(); } }; std::vector vertices; void sort_edges(); void remove_duplicate_edges(); /** \internal * Partition independent invariant. * Returns the color of the vertex. * Time complexity: O(1). */ static unsigned int vertex_color_invariant(const Graph* const g, const unsigned int v); /** \internal * Partition independent invariant. * Returns the degree of the vertex. * DUPLICATE EDGES MUST HAVE BEEN REMOVED BEFORE. * Time complexity: O(1). */ static unsigned int degree_invariant(const Graph* const g, const unsigned int v); /** \internal * Partition independent invariant. * Returns 1 if there is an edge from the vertex to itself, 0 if not. * Time complexity: O(k), where k is the number of edges leaving the vertex. */ static unsigned int selfloop_invariant(const Graph* const g, const unsigned int v); bool refine_according_to_invariant(unsigned int (*inv)(const Graph* const g, const unsigned int v)); /* * Routines needed when refining the partition p into equitable */ bool split_neighbourhood_of_unit_cell(Partition::Cell * const); bool split_neighbourhood_of_cell(Partition::Cell * const); /** \internal * \copydoc AbstractGraph::is_equitable() const */ bool is_equitable() const; /* Splitting heuristics, documented in more detail in graph.cc */ SplittingHeuristic sh; Partition::Cell* find_next_cell_to_be_splitted(Partition::Cell *cell); Partition::Cell* sh_first(); Partition::Cell* sh_first_smallest(); Partition::Cell* sh_first_largest(); Partition::Cell* sh_first_max_neighbours(); Partition::Cell* sh_first_smallest_max_neighbours(); Partition::Cell* sh_first_largest_max_neighbours(); void make_initial_equitable_partition(); void initialize_certificate(); bool is_automorphism(unsigned int* const perm) const; bool nucr_find_first_component(const unsigned int level); bool nucr_find_first_component(const unsigned int level, std::vector& component, unsigned int& component_elements, Partition::Cell*& sh_return); public: /** * Create a new graph with \a N vertices and no edges. */ Graph(const unsigned int N = 0); /** * Destroy the graph. */ ~Graph(); /** * \copydoc AbstractGraph::is_automorphism(const std::vector& perm) const */ bool is_automorphism(const std::vector& perm) const; /** * \copydoc AbstractGraph::get_hash() */ virtual unsigned int get_hash(); /** * Return the number of vertices in the graph. */ unsigned int get_nof_vertices() const {return vertices.size(); } /** * \copydoc AbstractGraph::permute(const unsigned int* const perm) const */ Graph* permute(const unsigned int* const perm) const; Graph* permute(const std::vector& perm) const; /** * Add a new vertex with color \a color in the graph and return its index. */ unsigned int add_vertex(const unsigned int color = 0); /** * Add an edge between vertices \a v1 and \a v2. * Duplicate edges between vertices are ignored but try to avoid introducing * them in the first place as they are not ignored immediately but will * consume memory and computation resources for a while. */ void add_edge(const unsigned int v1, const unsigned int v2); /** * Change the color of the vertex \a vertex to \a color. */ void change_color(const unsigned int vertex, const unsigned int color); /** * Compare this graph with the graph \a other. * Returns 0 if the graphs are equal, and a negative (positive) integer * if this graph is "smaller than" ("greater than", resp.) than \a other. */ int cmp(Graph& other); /** * Set the splitting heuristic used by the automorphism and canonical * labeling algorithm. * The selected splitting heuristics affects the computed canonical * labelings; therefore, if you want to compare whether two graphs * are isomorphic by computing and comparing (for equality) their * canonical versions, be sure to use the same splitting heuristics * for both graphs. */ void set_splitting_heuristic(const SplittingHeuristic shs) {sh = shs; } }; /** * \brief The class for directed, vertex colored graphs. * * Multiple edges between vertices are not allowed (i.e., are ignored). */ class Digraph : public AbstractGraph { public: /** * The possible splitting heuristics. * The selected splitting heuristics affects the computed canonical * labelings; therefore, if you want to compare whether two graphs * are isomorphic by computing and comparing (for equality) their * canonical versions, be sure to use the same splitting heuristics * for both graphs. */ typedef enum { /** First non-unit cell. * Very fast but may result in large search spaces on difficult graphs. * Use for large but easy graphs. */ shs_f = 0, /** First smallest non-unit cell. * Fast, should usually produce smaller search spaces than shs_f. */ shs_fs, /** First largest non-unit cell. * Fast, should usually produce smaller search spaces than shs_f. */ shs_fl, /** First maximally non-trivially connected non-unit cell. * Not so fast, should usually produce smaller search spaces than shs_f, * shs_fs, and shs_fl. */ shs_fm, /** First smallest maximally non-trivially connected non-unit cell. * Not so fast, should usually produce smaller search spaces than shs_f, * shs_fs, and shs_fl. */ shs_fsm, /** First largest maximally non-trivially connected non-unit cell. * Not so fast, should usually produce smaller search spaces than shs_f, * shs_fs, and shs_fl. */ shs_flm } SplittingHeuristic; protected: class Vertex { public: Vertex(); ~Vertex(); void add_edge_to(const unsigned int dest_vertex); void add_edge_from(const unsigned int source_vertex); void remove_duplicate_edges(std::vector& tmp); void sort_edges(); unsigned int color; std::vector edges_out; std::vector edges_in; unsigned int nof_edges_in() const {return edges_in.size(); } unsigned int nof_edges_out() const {return edges_out.size(); } }; std::vector vertices; void remove_duplicate_edges(); /** \internal * Partition independent invariant. * Returns the color of the vertex. * Time complexity: O(1). */ static unsigned int vertex_color_invariant(const Digraph* const g, const unsigned int v); /** \internal * Partition independent invariant. * Returns the indegree of the vertex. * DUPLICATE EDGES MUST HAVE BEEN REMOVED BEFORE. * Time complexity: O(1). */ static unsigned int indegree_invariant(const Digraph* const g, const unsigned int v); /** \internal * Partition independent invariant. * Returns the outdegree of the vertex. * DUPLICATE EDGES MUST HAVE BEEN REMOVED BEFORE. * Time complexity: O(1). */ static unsigned int outdegree_invariant(const Digraph* const g, const unsigned int v); /** \internal * Partition independent invariant. * Returns 1 if there is an edge from the vertex to itself, 0 if not. * Time complexity: O(k), where k is the number of edges leaving the vertex. */ static unsigned int selfloop_invariant(const Digraph* const g, const unsigned int v); /** \internal * Refine the partition \a p according to * the partition independent invariant \a inv. */ bool refine_according_to_invariant(unsigned int (*inv)(const Digraph* const g, const unsigned int v)); /* * Routines needed when refining the partition p into equitable */ bool split_neighbourhood_of_unit_cell(Partition::Cell* const); bool split_neighbourhood_of_cell(Partition::Cell* const); /** \internal * \copydoc AbstractGraph::is_equitable() const */ bool is_equitable() const; /* Splitting heuristics, documented in more detail in the cc-file. */ SplittingHeuristic sh; Partition::Cell* find_next_cell_to_be_splitted(Partition::Cell *cell); Partition::Cell* sh_first(); Partition::Cell* sh_first_smallest(); Partition::Cell* sh_first_largest(); Partition::Cell* sh_first_max_neighbours(); Partition::Cell* sh_first_smallest_max_neighbours(); Partition::Cell* sh_first_largest_max_neighbours(); void make_initial_equitable_partition(); void initialize_certificate(); bool is_automorphism(unsigned int* const perm) const; void sort_edges(); bool nucr_find_first_component(const unsigned int level); bool nucr_find_first_component(const unsigned int level, std::vector& component, unsigned int& component_elements, Partition::Cell*& sh_return); public: /** * Create a new directed graph with \a N vertices and no edges. */ Digraph(const unsigned int N = 0); /** * Destroy the graph. */ ~Digraph(); /** * \copydoc AbstractGraph::is_automorphism(const std::vector& perm) const */ bool is_automorphism(const std::vector& perm) const; /** * \copydoc AbstractGraph::get_hash() */ virtual unsigned int get_hash(); /** * Return the number of vertices in the graph. */ unsigned int get_nof_vertices() const {return vertices.size(); } /** * Add a new vertex with color 'color' in the graph and return its index. */ unsigned int add_vertex(const unsigned int color = 0); /** * Add an edge from the vertex \a source to the vertex \a target. * Duplicate edges are ignored but try to avoid introducing * them in the first place as they are not ignored immediately but will * consume memory and computation resources for a while. */ void add_edge(const unsigned int source, const unsigned int target); /** * Change the color of the vertex 'vertex' to 'color'. */ void change_color(const unsigned int vertex, const unsigned int color); /** * Compare this graph with the graph \a other. * Returns 0 if the graphs are equal, and a negative (positive) integer * if this graph is "smaller than" ("greater than", resp.) than \a other. */ int cmp(Digraph& other); /** * Set the splitting heuristic used by the automorphism and canonical * labeling algorithm. * The selected splitting heuristics affects the computed canonical * labelings; therefore, if you want to compare whether two graphs * are isomorphic by computing and comparing (for equality) their * canonical versions, be sure to use the same splitting heuristics * for both graphs. */ void set_splitting_heuristic(SplittingHeuristic shs) {sh = shs; } /** * \copydoc AbstractGraph::permute(const unsigned int* const perm) const */ Digraph* permute(const unsigned int* const perm) const; Digraph* permute(const std::vector& perm) const; }; } // namespace bliss #endif // BLISS_GRAPH_HH leidenbase/src/core/isomorphism/bliss/defs.hh0000644000176200001440000000472114447675374021044 0ustar liggesusers#ifndef BLISS_DEFS_HH #define BLISS_DEFS_HH #include #include /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ /** \file * \brief Some common definitions. */ namespace bliss { /** \brief The version number of bliss. */ static const char * const version = "0.75"; /** * If a fatal internal error is encountered, * this function is called. * There should no return from this function, but an exit or * a jump/throw to code that deallocates the AbstractGraph instance calling this. */ void fatal_error(const char* fmt); #if defined(BLISS_DEBUG) #define BLISS_CONSISTENCY_CHECKS #define BLISS_EXPENSIVE_CONSISTENCY_CHECKS #endif #if defined(BLISS_CONSISTENCY_CHECKS) /* Force a check that the found automorphisms are valid */ #define BLISS_VERIFY_AUTOMORPHISMS #endif #if defined(BLISS_CONSISTENCY_CHECKS) /* Force a check that the generated partitions are equitable */ #define BLISS_VERIFY_EQUITABLEDNESS #endif } // namespace bliss /*! \mainpage Outline * * This is the C++ API documentation of bliss, * produced by running doxygen in * the source directory. * * The algorithms and data structures used in bliss, * the graph file format, as well as the compilation process * can be found at the * bliss web site. * * The C++ language API is the main API to bliss. * It basically consists of the public methods in the classes * * bliss::Graph and * * bliss::Digraph. * * For an example of its use, * see the \ref executable "source of the bliss executable". * * \section capi_sec The C language API * * The C language API is given in the file bliss_C.h. * It is currently only a subset of the C++ API, * so consider using the C++ API whenever possible. */ #endif // BLISS_DEFS_HH leidenbase/src/core/isomorphism/bliss/kstack.hh0000644000176200001440000000571614447675374021410 0ustar liggesusers#ifndef BLISS_KSTACK_HH #define BLISS_KSTACK_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ #include #include namespace bliss { /** * \brief A simple implementation of a stack with fixed maximum capacity. */ template class KStack { public: /** * Create a new stack with zero capacity. * The function init() should be called next. */ KStack(); /** * Create a new stack with the capacity to hold at most \a N elements. */ KStack(int N); ~KStack(); /** * Initialize the stack to have the capacity to hold at most \a N elements. */ void init(int N); /** * Is the stack empty? */ bool is_empty() const {return cursor == entries; } /** * Return (but don't remove) the top element of the stack. */ Type top() const {assert(cursor > entries); return *cursor; } /** * Pop (remove) the top element of the stack. */ Type pop() { assert(cursor > entries); return *cursor--; } /** * Push the element \a e in the stack. */ void push(Type e) { assert(cursor < entries + kapacity); *(++cursor) = e; } /** Remove all the elements in the stack. */ void clean() {cursor = entries; } /** * Get the number of elements in the stack. */ unsigned int size() const {return cursor - entries; } /** * Return the i:th element in the stack, where \a i is in the range * 0,...,this.size()-1; the 0:th element is the bottom element * in the stack. */ Type element_at(unsigned int i) { assert(i < size()); return entries[i+1]; } /** Return the capacity (NOT the number of elements) of the stack. */ int capacity() const {return kapacity; } private: int kapacity; Type *entries; Type *cursor; }; template KStack::KStack() { kapacity = 0; entries = nullptr; cursor = nullptr; } template KStack::KStack(int k) { assert(k > 0); kapacity = k; entries = new Type[k+1]; cursor = entries; } template void KStack::init(int k) { assert(k > 0); delete[] entries; kapacity = k; entries = new Type[k+1]; cursor = entries; } template KStack::~KStack() { delete[] entries; kapacity = 0; entries = nullptr; cursor = nullptr; } } // namespace bliss #endif // BLISS_KSTACK_HH leidenbase/src/core/isomorphism/bliss/defs.cc0000644000176200001440000000154014447675374021026 0ustar liggesusers#include "igraph_error.h" #include "defs.hh" /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { void fatal_error(const char* reason) { IGRAPH_FATAL(reason); } } leidenbase/src/core/isomorphism/bliss/bignum.hh0000644000176200001440000000441314447675374021402 0ustar liggesusers#ifndef BLISS_BIGNUM_HH #define BLISS_BIGNUM_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ #define BLISS_USE_GMP #if defined(BLISS_USE_GMP) #include "internal/gmp_internal.h" #endif #include #include "defs.hh" namespace bliss { /** * \brief A simple wrapper class for big integers (or approximation of them). * * If the compile time flag BLISS_USE_GMP is set, * then the GNU Multiple Precision Arithmetic library (GMP) is used to * obtain arbitrary precision, otherwise "long double" is used to * approximate big integers. */ #if defined(BLISS_USE_GMP) class BigNum { mpz_t v; public: /** * \brief Create a new big number and set it to zero. */ BigNum() {mpz_init(v); } /** * \brief Destroy the number. */ ~BigNum() {mpz_clear(v); } /** * \brief Set the number to \a n. */ void assign(const int n) {mpz_set_si(v, n); } /** * \brief Multiply the number with \a n. */ void multiply(const int n) {mpz_mul_si(v, v, n); } /** * Get a copy of the internal GNU GMP integer. * The caller is responsible for calling mpz_init before, * and mpz_clear afterwards on the \a result variable. */ void get(mpz_t& result) const {mpz_set(result, v); } }; #else class BigNum { long double v; public: /** * \brief Create a new big number and set it to zero. */ BigNum(): v(0.0) {} /** * \brief Set the number to \a n. */ void assign(const int n) {v = (long double)n; } /** * \brief Multiply the number with \a n. */ void multiply(const int n) {v *= (long double)n; } }; #endif } //namespace bliss #endif // BLISS_BIGNUM_HH leidenbase/src/core/isomorphism/bliss/graph.cc0000644000176200001440000044255314447675374021223 0ustar liggesusers#include "igraph_error.h" #include #include #include #include #include // #include #include #include #include "defs.hh" #include "graph.hh" #include "partition.hh" #include "utils.hh" /* Allow using 'and' instead of '&&' with MSVC */ #if _MSC_VER #include #endif /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { #define _INTERNAL_ERROR() IGRAPH_FATAL("Bliss internal error") /*------------------------------------------------------------------------- * * Constructor and destructor routines for the abstract graph class * *-------------------------------------------------------------------------*/ AbstractGraph::AbstractGraph() { /* Initialize stuff */ first_path_labeling = nullptr; first_path_labeling_inv = nullptr; best_path_labeling = nullptr; best_path_labeling_inv = nullptr; first_path_automorphism = nullptr; best_path_automorphism = nullptr; in_search = false; /* Default value for using "long prune" */ opt_use_long_prune = true; /* Default value for using failure recording */ opt_use_failure_recording = true; /* Default value for using component recursion */ opt_use_comprec = true; /* verbose_level = 0; verbstr = stdout; */ } AbstractGraph::~AbstractGraph() { delete[] first_path_labeling; first_path_labeling = nullptr; delete[] first_path_labeling_inv; first_path_labeling_inv = nullptr; delete[] first_path_automorphism; first_path_automorphism = nullptr; delete[] best_path_labeling; best_path_labeling = nullptr; delete[] best_path_labeling_inv; best_path_labeling_inv = nullptr; delete[] best_path_automorphism; best_path_automorphism = nullptr; } /*------------------------------------------------------------------------- * * Verbose output management routines * *-------------------------------------------------------------------------*/ /* void AbstractGraph::set_verbose_level(const unsigned int level) { verbose_level = level; } void AbstractGraph::set_verbose_file(FILE* const fp) { verbstr = fp; } */ /*------------------------------------------------------------------------- * * Routines for refinement to equitable partition * *-------------------------------------------------------------------------*/ void AbstractGraph::refine_to_equitable() { /* Start refinement from all cells -> push 'em all in the splitting queue */ for(Partition::Cell* cell = p.first_cell; cell; cell = cell->next) p.splitting_queue_add(cell); do_refine_to_equitable(); } void AbstractGraph::refine_to_equitable(Partition::Cell* const unit_cell) { p.splitting_queue_add(unit_cell); do_refine_to_equitable(); } void AbstractGraph::refine_to_equitable(Partition::Cell* const unit_cell1, Partition::Cell* const unit_cell2) { p.splitting_queue_add(unit_cell1); p.splitting_queue_add(unit_cell2); do_refine_to_equitable(); } bool AbstractGraph::do_refine_to_equitable() { eqref_hash.reset(); while(!p.splitting_queue_is_empty()) { Partition::Cell* const cell = p.splitting_queue_pop(); if(cell->is_unit()) { if(in_search) { const unsigned int index = cell->first; if(first_path_automorphism) { /* Build the (potential) automorphism on-the-fly */ first_path_automorphism[first_path_labeling_inv[index]] = p.elements[index]; } if(best_path_automorphism) { /* Build the (potential) automorphism on-the-fly */ best_path_automorphism[best_path_labeling_inv[index]] = p.elements[index]; } } const bool worse = split_neighbourhood_of_unit_cell(cell); if(in_search and worse) goto worse_exit; } else { const bool worse = split_neighbourhood_of_cell(cell); if(in_search and worse) goto worse_exit; } } return true; worse_exit: /* Clear splitting_queue */ p.splitting_queue_clear(); return false; } /*------------------------------------------------------------------------- * * Routines for handling the canonical labeling * *-------------------------------------------------------------------------*/ /** \internal * Assign the labeling induced by the current partition 'this.p' to * \a labeling. * That is, if the partition is [[2,0],[1]], * then \a labeling will map 0 to 1, 1 to 2, and 2 to 0. */ void AbstractGraph::update_labeling(unsigned int* const labeling) { const unsigned int N = get_nof_vertices(); unsigned int* ep = p.elements; for(unsigned int i = 0; i < N; i++, ep++) labeling[*ep] = i; } /** \internal * The same as update_labeling() except that the inverse of the labeling * is also produced and assigned to \a labeling_inv. */ void AbstractGraph::update_labeling_and_its_inverse(unsigned int* const labeling, unsigned int* const labeling_inv) { const unsigned int N = get_nof_vertices(); unsigned int* ep = p.elements; unsigned int* clip = labeling_inv; for(unsigned int i = 0; i < N; ) { labeling[*ep] = i; i++; *clip = *ep; ep++; clip++; } } /*------------------------------------------------------------------------- * * Routines for handling automorphisms * *-------------------------------------------------------------------------*/ /** \internal * Reset the permutation \a perm to the identity permutation. */ void AbstractGraph::reset_permutation(unsigned int* perm) { const unsigned int N = get_nof_vertices(); for(unsigned int i = 0; i < N; i++, perm++) *perm = i; } /* bool AbstractGraph::is_automorphism(unsigned int* const perm) { _INTERNAL_ERROR(); return false; } */ /* bool AbstractGraph::is_automorphism(const std::vector& perm) const { _INTERNAL_ERROR(); return false; } */ /*------------------------------------------------------------------------- * * Certificate building * *-------------------------------------------------------------------------*/ void AbstractGraph::cert_add(const unsigned int v1, const unsigned int v2, const unsigned int v3) { if(refine_compare_certificate) { if(refine_equal_to_first) { /* So far equivalent to the first path... */ unsigned int index = certificate_current_path.size(); if(index >= refine_first_path_subcertificate_end) { refine_equal_to_first = false; } else if(certificate_first_path[index] != v1) { refine_equal_to_first = false; } else if(certificate_first_path[++index] != v2) { refine_equal_to_first = false; } else if(certificate_first_path[++index] != v3) { refine_equal_to_first = false; } if(opt_use_failure_recording and !refine_equal_to_first) { /* We just became different from the first path, * remember the deviation point tree-specific invariant * for the use of failure recording */ UintSeqHash h; h.update(v1); h.update(v2); h.update(v3); h.update(index); h.update(eqref_hash.get_value()); failure_recording_fp_deviation = h.get_value(); } } if(refine_cmp_to_best == 0) { /* So far equivalent to the current best path... */ unsigned int index = certificate_current_path.size(); if(index >= refine_best_path_subcertificate_end) { refine_cmp_to_best = 1; } else if(v1 > certificate_best_path[index]) { refine_cmp_to_best = 1; } else if(v1 < certificate_best_path[index]) { refine_cmp_to_best = -1; } else if(v2 > certificate_best_path[++index]) { refine_cmp_to_best = 1; } else if(v2 < certificate_best_path[index]) { refine_cmp_to_best = -1; } else if(v3 > certificate_best_path[++index]) { refine_cmp_to_best = 1; } else if(v3 < certificate_best_path[index]) { refine_cmp_to_best = -1; } } if((refine_equal_to_first == false) and (refine_cmp_to_best < 0)) return; } /* Update the current path certificate */ certificate_current_path.push_back(v1); certificate_current_path.push_back(v2); certificate_current_path.push_back(v3); } void AbstractGraph::cert_add_redundant(const unsigned int v1, const unsigned int v2, const unsigned int v3) { return cert_add(v1, v2, v3); } /*------------------------------------------------------------------------- * * Long prune code * *-------------------------------------------------------------------------*/ void AbstractGraph::long_prune_init() { const unsigned int N = get_nof_vertices(); long_prune_temp.clear(); long_prune_temp.resize(N); /* Of how many automorphisms we can store information in the predefined, fixed amount of memory? */ const unsigned int nof_fitting_in_max_mem = (long_prune_options_max_mem * 1024 * 1024) / (((N * 2) / 8)+1); long_prune_max_stored_autss = long_prune_options_max_stored_auts; /* Had some problems with g++ in using (a* tmp = long_prune_fixed[real_i]; long_prune_fixed[real_i] = long_prune_fixed[real_j]; long_prune_fixed[real_j] = tmp; tmp = long_prune_mcrs[real_i]; long_prune_mcrs[real_i] = long_prune_mcrs[real_j]; long_prune_mcrs[real_j] = tmp; } std::vector& AbstractGraph::long_prune_allocget_fixed(const unsigned int index) { const unsigned int i = index % long_prune_max_stored_autss; if(!long_prune_fixed[i]) long_prune_fixed[i] = new std::vector(get_nof_vertices()); return *long_prune_fixed[i]; } std::vector& AbstractGraph::long_prune_get_fixed(const unsigned int index) { return *long_prune_fixed[index % long_prune_max_stored_autss]; } std::vector& AbstractGraph::long_prune_allocget_mcrs(const unsigned int index) { const unsigned int i = index % long_prune_max_stored_autss; if(!long_prune_mcrs[i]) long_prune_mcrs[i] = new std::vector(get_nof_vertices()); return *long_prune_mcrs[i]; } std::vector& AbstractGraph::long_prune_get_mcrs(const unsigned int index) { return *long_prune_mcrs[index % long_prune_max_stored_autss]; } void AbstractGraph::long_prune_add_automorphism(const unsigned int* aut) { if(long_prune_max_stored_autss == 0) return; const unsigned int N = get_nof_vertices(); /* If the buffer of stored auts is full, remove the oldest aut */ if(long_prune_end - long_prune_begin == long_prune_max_stored_autss) { long_prune_begin++; } long_prune_end++; std::vector& fixed = long_prune_allocget_fixed(long_prune_end-1); std::vector& mcrs = long_prune_allocget_mcrs(long_prune_end-1); /* Mark nodes that are (i) fixed or (ii) minimal orbit representatives * under the automorphism 'aut' */ for(unsigned int i = 0; i < N; i++) { fixed[i] = (aut[i] == i); if(long_prune_temp[i] == false) { mcrs[i] = true; unsigned int j = aut[i]; while(j != i) { long_prune_temp[j] = true; j = aut[j]; } } else { mcrs[i] = false; } /* Clear the temp array on-the-fly... */ long_prune_temp[i] = false; } } /*------------------------------------------------------------------------- * * Routines for handling orbit information * *-------------------------------------------------------------------------*/ void AbstractGraph::update_orbit_information(Orbit& o, const unsigned int* perm) { const unsigned int N = get_nof_vertices(); for(unsigned int i = 0; i < N; i++) if(perm[i] != i) o.merge_orbits(i, perm[i]); } /*------------------------------------------------------------------------- * * The actual backtracking search * *-------------------------------------------------------------------------*/ /** \internal \brief Search tree node information. */ class TreeNode { //friend class AbstractGraph; public: unsigned int split_cell_first; int split_element; static const int SPLIT_START = -1; static const int SPLIT_END = -2; Partition::BacktrackPoint partition_bt_point; unsigned int certificate_index; static const char NO = -1; static const char MAYBE = 0; static const char YES = 1; /* First path stuff */ bool fp_on; bool fp_cert_equal; char fp_extendable; /* Best path stuff */ bool in_best_path; int cmp_to_best_path; unsigned int failure_recording_ival; /* Component recursion related data */ unsigned int cr_cep_stack_size; unsigned int cr_cep_index; unsigned int cr_level; bool needs_long_prune = false; /* igraph-specific patch: initialize to false to silence UBSan */ unsigned int long_prune_begin; std::set > long_prune_redundant; UintSeqHash eqref_hash; unsigned int subcertificate_length; }; void AbstractGraph::search(const bool canonical, Stats& stats, const std::function& report, const std::function& terminate) { const unsigned int N = get_nof_vertices(); unsigned int all_same_level = UINT_MAX; p.graph = this; /* * Must be done! */ remove_duplicate_edges(); /* * Reset search statistics */ stats.reset(); stats.nof_nodes = 1; stats.nof_leaf_nodes = 1; /* Free old first path data structures */ delete[] first_path_labeling; first_path_labeling = nullptr; delete[] first_path_labeling_inv; first_path_labeling_inv = nullptr; delete[] first_path_automorphism; first_path_automorphism = nullptr; /* Free old best path data structures */ delete[] best_path_labeling; best_path_labeling = nullptr; delete[] best_path_labeling_inv; best_path_labeling_inv = nullptr; delete[] best_path_automorphism; best_path_automorphism = nullptr; if(N == 0) { /* Nothing to do, return... */ return; } /* Initialize the partition ... */ p.init(N); /* ... and the component recursion data structures in the partition */ if(opt_use_comprec) p.cr_init(); neighbour_heap.init(N); in_search = false; /* Do not compute certificate when building the initial partition */ refine_compare_certificate = false; /* The 'eqref_hash' hash value is not computed when building * the initial partition as it is not used for anything at the moment. * This saves some cycles. */ compute_eqref_hash = false; make_initial_equitable_partition(); /* * Allocate space for the "first path" and "best path" labelings */ delete[] first_path_labeling; first_path_labeling = new unsigned int[N]; delete[] best_path_labeling; best_path_labeling = new unsigned int[N]; for(unsigned int i = 0; i < N; i++) best_path_labeling[i] = i; /* * Is the initial partition discrete? */ if(p.is_discrete()) { /* Make the best path labeling i.e. the canonical labeling */ update_labeling(best_path_labeling); /* Update statistics */ stats.nof_leaf_nodes = 1; /* Release component recursion data in partition */ if(opt_use_comprec) p.cr_free(); return; } /* * Allocate the inverses of the "first path" and "best path" labelings */ delete[] first_path_labeling_inv; first_path_labeling_inv = new unsigned int[N]; std::fill_n(first_path_labeling_inv, N, 0); delete[] best_path_labeling_inv; best_path_labeling_inv = new unsigned int[N]; std::fill_n(best_path_labeling_inv, N, 0); /* * Allocate space for the automorphisms */ delete[] first_path_automorphism; first_path_automorphism = new unsigned int[N]; delete[] best_path_automorphism; best_path_automorphism = new unsigned int[N]; /* * Initialize orbit information so that all vertices are in their own orbits */ first_path_orbits.init(N); best_path_orbits.init(N); /* * Initialize certificate memory */ initialize_certificate(); std::vector search_stack; std::vector first_path_info; std::vector best_path_info; search_stack.clear(); /* Initialize "long prune" data structures */ if(opt_use_long_prune) long_prune_init(); /* * Initialize failure recording data structures */ typedef std::set > FailureRecordingSet; std::vector failure_recording_hashes; /* * Initialize component recursion data structures */ cr_cep_stack.clear(); unsigned int cr_cep_index = 0; { /* Inset a sentinel "component end point" */ CR_CEP sentinel; sentinel.creation_level = 0; sentinel.discrete_cell_limit = get_nof_vertices(); sentinel.next_cr_level = 0; sentinel.next_cep_index = 0; sentinel.first_checked = false; sentinel.best_checked = false; cr_cep_index = 0; cr_cep_stack.push_back(sentinel); } cr_level = 0; if(opt_use_comprec and nucr_find_first_component(cr_level) == true and p.nof_discrete_cells() + cr_component_elements < cr_cep_stack[cr_cep_index].discrete_cell_limit) { cr_level = p.cr_split_level(0, cr_component); CR_CEP cep; cep.creation_level = 0; cep.discrete_cell_limit = p.nof_discrete_cells() + cr_component_elements; cep.next_cr_level = 0; cep.next_cep_index = cr_cep_index; cep.first_checked = false; cep.best_checked = false; cr_cep_index = cr_cep_stack.size(); cr_cep_stack.push_back(cep); } /* * Build the root node of the search tree */ { TreeNode root; Partition::Cell* split_cell = find_next_cell_to_be_splitted(p.first_cell); root.split_cell_first = split_cell->first; root.split_element = TreeNode::SPLIT_START; root.partition_bt_point = p.set_backtrack_point(); root.certificate_index = 0; root.fp_on = true; root.fp_cert_equal = true; root.fp_extendable = TreeNode::MAYBE; root.in_best_path = false; root.cmp_to_best_path = 0; root.long_prune_begin = 0; root.failure_recording_ival = 0; /* Save component recursion info for backtracking */ root.cr_level = cr_level; root.cr_cep_stack_size = cr_cep_stack.size(); root.cr_cep_index = cr_cep_index; search_stack.push_back(root); } /* * Set status and global flags for search related procedures */ in_search = true; /* Do not compare certificates during refinement until the first path has been traversed to the leaf */ refine_compare_certificate = false; /* * The actual backtracking search */ while(!search_stack.empty()) { if(terminate and terminate()) { break; } TreeNode& current_node = search_stack.back(); const unsigned int current_level = (unsigned int)search_stack.size()-1; if(opt_use_comprec) { CR_CEP& cep = cr_cep_stack[current_node.cr_cep_index]; if(cep.first_checked == true and current_node.fp_extendable == TreeNode::MAYBE and !search_stack[cep.creation_level].fp_on) { current_node.fp_extendable = TreeNode::NO; } } if(current_node.fp_on) { if(current_node.split_element == TreeNode::SPLIT_END) { search_stack.pop_back(); continue; } } else { if(current_node.fp_extendable == TreeNode::YES) { search_stack.pop_back(); continue; } if(current_node.split_element == TreeNode::SPLIT_END) { if(opt_use_failure_recording) { TreeNode& parent_node = search_stack[current_level-1]; if(parent_node.fp_on) failure_recording_hashes[current_level-1].insert(current_node.failure_recording_ival); } search_stack.pop_back(); continue; } if(current_node.fp_extendable == TreeNode::NO and (!canonical or current_node.cmp_to_best_path < 0)) { if(opt_use_failure_recording) { TreeNode& parent_node = search_stack[current_level-1]; if(parent_node.fp_on) failure_recording_hashes[current_level-1].insert(current_node.failure_recording_ival); } search_stack.pop_back(); continue; } } /* Restore partition ... */ p.goto_backtrack_point(current_node.partition_bt_point); /* ... and re-remember backtracking point */ current_node.partition_bt_point = p.set_backtrack_point(); /* Restore current path certificate */ certificate_index = current_node.certificate_index; refine_current_path_certificate_index = current_node.certificate_index; certificate_current_path.resize(certificate_index); /* Fetch split cell information */ Partition::Cell * const cell = p.get_cell(p.elements[current_node.split_cell_first]); /* Restore component recursion information */ cr_level = current_node.cr_level; cr_cep_stack.resize(current_node.cr_cep_stack_size); cr_cep_index = current_node.cr_cep_index; /* * Update long prune redundancy sets */ if(opt_use_long_prune and current_level >= 1 and !current_node.fp_on) { unsigned int begin = (current_node.long_prune_begin>long_prune_begin)?current_node.long_prune_begin:long_prune_begin; for(unsigned int i = begin; i < long_prune_end; i++) { const std::vector& fixed = long_prune_get_fixed(i); #if defined(BLISS_CONSISTENCY_CHECKS) for(unsigned int l = 0; l < search_stack.size()-2; l++) assert(fixed[search_stack[l].split_element]); #endif if(fixed[search_stack[search_stack.size()-1-1].split_element] == false) { long_prune_swap(begin, i); begin++; current_node.long_prune_begin = begin; continue; } } if(current_node.split_element == TreeNode::SPLIT_START) { current_node.needs_long_prune = true; } else if(current_node.needs_long_prune) { current_node.needs_long_prune = false; unsigned int begin = (current_node.long_prune_begin>long_prune_begin)?current_node.long_prune_begin:long_prune_begin; for(unsigned int i = begin; i < long_prune_end; i++) { const std::vector& fixed = long_prune_get_fixed(i); #if defined(BLISS_CONSISTENCY_CHECKS) for(unsigned int l = 0; l < search_stack.size()-2; l++) assert(fixed[search_stack[l].split_element]); #endif assert(fixed[search_stack[current_level-1].split_element] == true); if(fixed[search_stack[current_level-1].split_element] == false) { long_prune_swap(begin, i); begin++; current_node.long_prune_begin = begin; continue; } const std::vector& mcrs = long_prune_get_mcrs(i); unsigned int* ep = p.elements + cell->first; for(unsigned int j = cell->length; j > 0; j--, ep++) { if(mcrs[*ep] == false) current_node.long_prune_redundant.insert(*ep); } } } } /* * Find the next smallest, non-isomorphic element in the cell and * store it in current_node.split_element */ { unsigned int next_split_element = UINT_MAX; //unsigned int* next_split_element_pos = 0; unsigned int* ep = p.elements + cell->first; if(current_node.fp_on) { /* Find the next larger splitting element that is * a minimal orbit representative w.r.t. first_path_orbits */ for(unsigned int i = cell->length; i > 0; i--, ep++) { if((int)(*ep) > current_node.split_element and *ep < next_split_element and first_path_orbits.is_minimal_representative(*ep)) { next_split_element = *ep; //next_split_element_pos = ep; } } } else if(current_node.in_best_path) { /* Find the next larger splitting element that is * a minimal orbit representative w.r.t. best_path_orbits */ for(unsigned int i = cell->length; i > 0; i--, ep++) { if((int)(*ep) > current_node.split_element and *ep < next_split_element and best_path_orbits.is_minimal_representative(*ep) and (!opt_use_long_prune or current_node.long_prune_redundant.find(*ep) == current_node.long_prune_redundant.end())) { next_split_element = *ep; //next_split_element_pos = ep; } } } else { /* Find the next larger splitting element */ for(unsigned int i = cell->length; i > 0; i--, ep++) { if((int)(*ep) > current_node.split_element and *ep < next_split_element and (!opt_use_long_prune or current_node.long_prune_redundant.find(*ep) == current_node.long_prune_redundant.end())) { next_split_element = *ep; //next_split_element_pos = ep; } } } if(next_split_element == UINT_MAX) { /* No more (unexplored children) in the cell */ current_node.split_element = TreeNode::SPLIT_END; if(current_node.fp_on) { /* Update group size */ const unsigned int index = first_path_orbits.orbit_size(first_path_info[search_stack.size()-1].splitting_element); stats.group_size.multiply(index); stats.group_size_approx *= (long double)index; /* * Update all_same_level */ if(index == cell->length and all_same_level == current_level+1) all_same_level = current_level; /* if(verbstr and verbose_level >= 2) { fprintf(verbstr, "Level %u: orbits=%u, index=%u/%u, all_same_level=%u\n", current_level, first_path_orbits.nof_orbits(), index, cell->length, all_same_level); fflush(verbstr); } */ } continue; } /* Split on smallest */ current_node.split_element = next_split_element; } const unsigned int child_level = current_level+1; /* Update some statistics */ stats.nof_nodes++; if(search_stack.size() > stats.max_level) stats.max_level = search_stack.size(); /* Set flags and indices for the refiner certificate builder */ refine_equal_to_first = current_node.fp_cert_equal; refine_cmp_to_best = current_node.cmp_to_best_path; if(!first_path_info.empty()) { if(refine_equal_to_first) refine_first_path_subcertificate_end = first_path_info[search_stack.size()-1].certificate_index + first_path_info[search_stack.size()-1].subcertificate_length; if(canonical) { if(refine_cmp_to_best == 0) refine_best_path_subcertificate_end = best_path_info[search_stack.size()-1].certificate_index + best_path_info[search_stack.size()-1].subcertificate_length; } else refine_cmp_to_best = -1; } const bool was_fp_cert_equal = current_node.fp_cert_equal; /* Individualize, i.e. split the cell in two, the latter new cell * will be a unit one containing info.split_element */ Partition::Cell* const new_cell = p.individualize(cell, current_node.split_element); /* * Refine the new partition to equitable */ if(cell->is_unit()) refine_to_equitable(cell, new_cell); else refine_to_equitable(new_cell); /* Update statistics */ if(p.is_discrete()) stats.nof_leaf_nodes++; if(!first_path_info.empty()) { /* We are no longer on the first path */ const unsigned int subcertificate_length = certificate_current_path.size() - certificate_index; if(refine_equal_to_first) { /* Was equal to the first path so far */ PathInfo& first_pinfo = first_path_info[current_level]; assert(first_pinfo.certificate_index == certificate_index); if(subcertificate_length != first_pinfo.subcertificate_length) { refine_equal_to_first = false; if(opt_use_failure_recording) failure_recording_fp_deviation = subcertificate_length; } else if(first_pinfo.eqref_hash.cmp(eqref_hash) != 0) { refine_equal_to_first = false; if(opt_use_failure_recording) failure_recording_fp_deviation = eqref_hash.get_value(); } } if(canonical and (refine_cmp_to_best == 0)) { /* Was equal to the best path so far */ PathInfo& bestp_info = best_path_info[current_level]; assert(bestp_info.certificate_index == certificate_index); if(subcertificate_length < bestp_info.subcertificate_length) { refine_cmp_to_best = -1; } else if(subcertificate_length > bestp_info.subcertificate_length) { refine_cmp_to_best = 1; } else if(bestp_info.eqref_hash.cmp(eqref_hash) > 0) { refine_cmp_to_best = -1; } else if(bestp_info.eqref_hash.cmp(eqref_hash) < 0) { refine_cmp_to_best = 1; } } if(opt_use_failure_recording and was_fp_cert_equal and !refine_equal_to_first) { UintSeqHash k; k.update(failure_recording_fp_deviation); k.update(eqref_hash.get_value()); failure_recording_fp_deviation = k.get_value(); if(current_node.fp_on) failure_recording_hashes[current_level].insert(failure_recording_fp_deviation); else { for(unsigned int i = current_level; i > 0; i--) { if(search_stack[i].fp_on) break; const FailureRecordingSet& s = failure_recording_hashes[i]; if(i == current_level and s.find(failure_recording_fp_deviation) != s.end()) break; if(s.find(0) != s.end()) break; search_stack[i].fp_extendable = TreeNode::NO; } } } /* Check if no longer equal to the first path and, * if canonical labeling is desired, also worse than the * current best path */ if(refine_equal_to_first == false and (!canonical or (refine_cmp_to_best < 0))) { /* Yes, backtrack */ stats.nof_bad_nodes++; if(current_node.fp_cert_equal == true and current_level+1 > all_same_level) { assert(all_same_level >= 1); for(unsigned int i = all_same_level; i < search_stack.size(); i++) { search_stack[i].fp_extendable = TreeNode::NO; } } continue; } } #if defined(BLISS_VERIFY_EQUITABLEDNESS) /* The new partition should be equitable */ if(!is_equitable()) fatal_error("consistency check failed - partition after refinement is not equitable"); #endif /* * Next level search tree node info */ TreeNode child_node; /* No more in the first path */ child_node.fp_on = false; /* No more in the best path */ child_node.in_best_path = false; child_node.fp_cert_equal = refine_equal_to_first; if(current_node.fp_extendable == TreeNode::NO or (current_node.fp_extendable == TreeNode::MAYBE and child_node.fp_cert_equal == false)) child_node.fp_extendable = TreeNode::NO; else child_node.fp_extendable = TreeNode::MAYBE; child_node.cmp_to_best_path = refine_cmp_to_best; child_node.failure_recording_ival = 0; child_node.cr_cep_stack_size = current_node.cr_cep_stack_size; child_node.cr_cep_index = current_node.cr_cep_index; child_node.cr_level = current_node.cr_level; certificate_index = certificate_current_path.size(); current_node.eqref_hash = eqref_hash; current_node.subcertificate_length = certificate_index - current_node.certificate_index; /* * The first encountered leaf node at the end of the "first path"? */ if(p.is_discrete() and first_path_info.empty()) { //fprintf(stdout, "Level %u: FIRST\n", child_level); fflush(stdout); stats.nof_canupdates++; /* * Update labelings and their inverses */ update_labeling_and_its_inverse(first_path_labeling, first_path_labeling_inv); update_labeling_and_its_inverse(best_path_labeling, best_path_labeling_inv); /* * Reset automorphism array */ reset_permutation(first_path_automorphism); reset_permutation(best_path_automorphism); /* * Reset orbit information */ first_path_orbits.reset(); best_path_orbits.reset(); /* * Reset group size */ stats.group_size.assign(1); stats.group_size_approx = 1.0; /* * Reset all_same_level */ all_same_level = child_level; /* * Mark the current path to be the first and best one and save it */ const unsigned int base_size = search_stack.size(); best_path_info.clear(); //fprintf(stdout, " New base is: "); for(unsigned int i = 0; i < base_size; i++) { search_stack[i].fp_on = true; search_stack[i].fp_cert_equal = true; search_stack[i].fp_extendable = TreeNode::YES; search_stack[i].in_best_path = true; search_stack[i].cmp_to_best_path = 0; PathInfo path_info; path_info.splitting_element = search_stack[i].split_element; path_info.certificate_index = search_stack[i].certificate_index; path_info.eqref_hash = search_stack[i].eqref_hash; path_info.subcertificate_length = search_stack[i].subcertificate_length; first_path_info.push_back(path_info); best_path_info.push_back(path_info); //fprintf(stdout, "%u ", search_stack[i].split_element); } //fprintf(stdout, "\n"); fflush(stdout); /* Copy certificates */ certificate_first_path = certificate_current_path; certificate_best_path = certificate_current_path; /* From now on, compare certificates when refining */ refine_compare_certificate = true; if(opt_use_failure_recording) failure_recording_hashes.resize(base_size); /* for(unsigned int j = 0; j < search_stack.size(); j++) fprintf(stderr, "%u ", search_stack[j].split_element); fprintf(stderr, "\n"); p.print(stderr); fprintf(stderr, "\n"); */ /* * Backtrack to the previous level */ continue; } if(p.is_discrete() and child_node.fp_cert_equal) { /* * A leaf node that is equal to the first one. * An automorphism found: aut[i] = elements[first_path_labeling[i]] */ goto handle_first_path_automorphism; } if(!p.is_discrete()) { Partition::Cell* next_split_cell = 0; /* * An internal, non-leaf node */ if(opt_use_comprec) { assert(p.nof_discrete_cells() <= cr_cep_stack[cr_cep_index].discrete_cell_limit); assert(cr_level == child_node.cr_level); if(p.nof_discrete_cells() == cr_cep_stack[cr_cep_index].discrete_cell_limit) { /* We have reached the end of a component */ assert(cr_cep_index != 0); CR_CEP& cep = cr_cep_stack[cr_cep_index]; /* First, compare with respect to the first path */ if(first_path_info.empty() or child_node.fp_cert_equal) { if(cep.first_checked == false) { /* First time, go to the next component */ cep.first_checked = true; } else { assert(!first_path_info.empty()); assert(cep.creation_level < search_stack.size()); TreeNode& old_info = search_stack[cep.creation_level]; /* If the component was found when on the first path, * handle the found automorphism as the other * first path automorphisms */ if(old_info.fp_on) goto handle_first_path_automorphism; } } if(canonical and !first_path_info.empty() and child_node.cmp_to_best_path >= 0) { if(cep.best_checked == false) { /* First time, go to the next component */ cep.best_checked = true; } else { assert(cep.creation_level < search_stack.size()); TreeNode& old_info = search_stack[cep.creation_level]; if(child_node.cmp_to_best_path == 0) { /* If the component was found when on the best path, * handle the found automorphism as the other * best path automorphisms */ if(old_info.in_best_path) goto handle_best_path_automorphism; /* Otherwise, we do not remember the automorhism as * we didn't memorize the path that was invariant * equal to the best one and passed through the * component. * Thus we can only backtrack to the previous level */ child_node.cmp_to_best_path = -1; if(!child_node.fp_cert_equal) { continue; } } else { assert(child_node.cmp_to_best_path > 0); if(old_info.in_best_path) { stats.nof_canupdates++; /* * Update canonical labeling and its inverse */ for(unsigned int i = 0; i < N; i++) { if(p.get_cell(p.elements[i])->is_unit()) { best_path_labeling[p.elements[i]] = i; best_path_labeling_inv[i] = p.elements[i]; } } //update_labeling_and_its_inverse(best_path_labeling, best_path_labeling_inv); /* Reset best path automorphism */ reset_permutation(best_path_automorphism); /* Reset best path orbit structure */ best_path_orbits.reset(); /* Mark to be the best one and save prefix */ unsigned int postfix_start = cep.creation_level; assert(postfix_start < best_path_info.size()); while(p.get_cell(best_path_info[postfix_start].splitting_element)->is_unit()) { postfix_start++; assert(postfix_start < best_path_info.size()); } unsigned int postfix_start_cert = best_path_info[postfix_start].certificate_index; std::vector best_path_temp = best_path_info; best_path_info.clear(); for(unsigned int i = 0; i < search_stack.size(); i++) { TreeNode& ss_info = search_stack[i]; PathInfo bp_info; ss_info.cmp_to_best_path = 0; ss_info.in_best_path = true; bp_info.splitting_element = ss_info.split_element; bp_info.certificate_index = ss_info.certificate_index; bp_info.subcertificate_length = ss_info.subcertificate_length; bp_info.eqref_hash = ss_info.eqref_hash; best_path_info.push_back(bp_info); } /* Copy the postfix of the previous best path */ for(unsigned int i = postfix_start; i < best_path_temp.size(); i++) { best_path_info.push_back(best_path_temp[i]); best_path_info[best_path_info.size()-1].certificate_index = best_path_info[best_path_info.size()-2].certificate_index + best_path_info[best_path_info.size()-2].subcertificate_length; } std::vector certificate_best_path_old = certificate_best_path; certificate_best_path = certificate_current_path; for(unsigned int i = postfix_start_cert; i < certificate_best_path_old.size(); i++) certificate_best_path.push_back(certificate_best_path_old[i]); assert(certificate_best_path.size() == best_path_info.back().certificate_index + best_path_info.back().subcertificate_length); /* Backtrack to the previous level */ continue; } } } } /* No backtracking performed, go to next componenet */ cr_level = cep.next_cr_level; cr_cep_index = cep.next_cep_index; } /* Check if the current component has been split into * new non-uniformity subcomponents */ //if(nucr_find_first_component(cr_level) == true and // p.nof_discrete_cells() + cr_component_elements < // cr_cep_stack[cr_cep_index].discrete_cell_limit) if(nucr_find_first_component(cr_level, cr_component, cr_component_elements, next_split_cell) == true and p.nof_discrete_cells() + cr_component_elements < cr_cep_stack[cr_cep_index].discrete_cell_limit) { const unsigned int next_cr_level = p.cr_split_level(cr_level, cr_component); CR_CEP cep; cep.creation_level = search_stack.size(); cep.discrete_cell_limit = p.nof_discrete_cells() + cr_component_elements; cep.next_cr_level = cr_level; cep.next_cep_index = cr_cep_index; cep.first_checked = false; cep.best_checked = false; cr_cep_index = cr_cep_stack.size(); cr_cep_stack.push_back(cep); cr_level = next_cr_level; } } /* * Build the next node info */ /* Find the next cell to be splitted */ if(!next_split_cell) next_split_cell = find_next_cell_to_be_splitted(p.get_cell(p.elements[current_node.split_cell_first])); //Partition::Cell * const next_split_cell = find_next_cell_to_be_splitted(p.get_cell(p.elements[current_node.split_cell_first])); child_node.split_cell_first = next_split_cell->first; child_node.split_element = TreeNode::SPLIT_START; child_node.certificate_index = certificate_index; child_node.partition_bt_point = p.set_backtrack_point(); child_node.long_prune_redundant.clear(); child_node.long_prune_begin = current_node.long_prune_begin; /* Save component recursion info for backtracking */ child_node.cr_level = cr_level; child_node.cr_cep_stack_size = cr_cep_stack.size(); child_node.cr_cep_index = cr_cep_index; search_stack.push_back(child_node); continue; } /* * A leaf node not in the first path or equivalent to the first path */ if(child_node.cmp_to_best_path > 0) { /* * A new, better representative found */ //fprintf(stdout, "Level %u: NEW BEST\n", child_level); fflush(stdout); stats.nof_canupdates++; /* * Update canonical labeling and its inverse */ update_labeling_and_its_inverse(best_path_labeling, best_path_labeling_inv); /* Reset best path automorphism */ reset_permutation(best_path_automorphism); /* Reset best path orbit structure */ best_path_orbits.reset(); /* * Mark the current path to be the best one and save it */ const unsigned int base_size = search_stack.size(); assert(current_level+1 == base_size); best_path_info.clear(); for(unsigned int i = 0; i < base_size; i++) { search_stack[i].cmp_to_best_path = 0; search_stack[i].in_best_path = true; PathInfo path_info; path_info.splitting_element = search_stack[i].split_element; path_info.certificate_index = search_stack[i].certificate_index; path_info.subcertificate_length = search_stack[i].subcertificate_length; path_info.eqref_hash = search_stack[i].eqref_hash; best_path_info.push_back(path_info); } certificate_best_path = certificate_current_path; /* * Backtrack to the previous level */ continue; } handle_best_path_automorphism: /* * * Best path automorphism handling * */ { /* * Equal to the previous best path */ if(p.is_discrete()) { #if defined(BLISS_CONSISTENCY_CHECKS) /* Verify that the automorphism is correctly built */ for(unsigned int i = 0; i < N; i++) assert(best_path_automorphism[i] == p.elements[best_path_labeling[i]]); #endif } else { /* An automorphism that was found before the partition was discrete. * Set the image of all elements in non-disrete cells accordingly */ for(Partition::Cell* c = p.first_nonsingleton_cell; c; c = c->next_nonsingleton) { for(unsigned int i = c->first; i < c->first+c->length; i++) if(p.get_cell(p.elements[best_path_labeling[p.elements[i]]])->is_unit()) best_path_automorphism[p.elements[best_path_labeling[p.elements[i]]]] = p.elements[i]; else best_path_automorphism[p.elements[i]] = p.elements[i]; } } #if defined(BLISS_VERIFY_AUTOMORPHISMS) /* Verify that it really is an automorphism */ if(!is_automorphism(best_path_automorphism)) fatal_error("Best path automorhism validation check failed"); #endif unsigned int gca_level_with_first = 0; for(unsigned int i = search_stack.size(); i > 0; i--) { if((int)first_path_info[gca_level_with_first].splitting_element != search_stack[gca_level_with_first].split_element) break; gca_level_with_first++; } unsigned int gca_level_with_best = 0; for(unsigned int i = search_stack.size(); i > 0; i--) { if((int)best_path_info[gca_level_with_best].splitting_element != search_stack[gca_level_with_best].split_element) break; gca_level_with_best++; } if(opt_use_long_prune) { /* Record automorphism */ long_prune_add_automorphism(best_path_automorphism); } /* * Update orbit information */ update_orbit_information(best_path_orbits, best_path_automorphism); /* * Update orbit information */ const unsigned int nof_old_orbits = first_path_orbits.nof_orbits(); update_orbit_information(first_path_orbits, best_path_automorphism); if(nof_old_orbits != first_path_orbits.nof_orbits()) { /* Some orbits were merged */ /* Report automorphism */ if(report) report(get_nof_vertices(), best_path_automorphism); /* Update statistics */ stats.nof_generators++; } /* * Compute backjumping level */ unsigned int backjumping_level = current_level+1-1; if(!first_path_orbits.is_minimal_representative(search_stack[gca_level_with_first].split_element)) { backjumping_level = gca_level_with_first; } else { assert(!best_path_orbits.is_minimal_representative(search_stack[gca_level_with_best].split_element)); backjumping_level = gca_level_with_best; } /* Backtrack */ search_stack.resize(backjumping_level + 1); continue; } _INTERNAL_ERROR(); handle_first_path_automorphism: /* * * A first-path automorphism: aut[i] = elements[first_path_labeling[i]] * */ if(p.is_discrete()) { #if defined(BLISS_CONSISTENCY_CHECKS) /* Verify that the complete automorphism is correctly built */ for(unsigned int i = 0; i < N; i++) assert(first_path_automorphism[i] == p.elements[first_path_labeling[i]]); #endif } else { /* An automorphism that was found before the partition was discrete. * Set the image of all elements in non-disrete cells accordingly */ for(Partition::Cell* c = p.first_nonsingleton_cell; c; c = c->next_nonsingleton) { for(unsigned int i = c->first; i < c->first+c->length; i++) if(p.get_cell(p.elements[first_path_labeling[p.elements[i]]])->is_unit()) first_path_automorphism[p.elements[first_path_labeling[p.elements[i]]]] = p.elements[i]; else first_path_automorphism[p.elements[i]] = p.elements[i]; } } #if defined(BLISS_VERIFY_AUTOMORPHISMS) /* Verify that it really is an automorphism */ if(!is_automorphism(first_path_automorphism)) fatal_error("First path automorphism validation check failed"); #endif if(opt_use_long_prune) { long_prune_add_automorphism(first_path_automorphism); } /* * Update orbit information */ update_orbit_information(first_path_orbits, first_path_automorphism); /* * Compute backjumping level */ for(unsigned int i = 0; i < search_stack.size(); i++) { TreeNode& n = search_stack[i]; if(n.fp_on) { ; } else { n.fp_extendable = TreeNode::YES; } } /* Report automorphism by calling the user defined hook function */ if(report) report(get_nof_vertices(), first_path_automorphism); /* Update statistics */ stats.nof_generators++; continue; } /* while(!search_stack.empty()) */ /* Free "long prune" technique memory */ if(opt_use_long_prune) long_prune_deallocate(); /* Release component recursion data in partition */ if(opt_use_comprec) p.cr_free(); } void AbstractGraph::find_automorphisms(Stats& stats, const std::function& report, const std::function& terminate) { search(false, stats, report, terminate); delete[] first_path_labeling; first_path_labeling = nullptr; delete[] best_path_labeling; best_path_labeling = nullptr; } const unsigned int * AbstractGraph::canonical_form(Stats& stats, const std::function& report, const std::function& terminate) { search(true, stats, report, terminate); return best_path_labeling; } /*------------------------------------------------------------------------- * * Routines for directed graphs * *-------------------------------------------------------------------------*/ Digraph::Vertex::Vertex() { color = 0; } Digraph::Vertex::~Vertex() { ; } void Digraph::Vertex::add_edge_to(const unsigned int other_vertex) { edges_out.push_back(other_vertex); } void Digraph::Vertex::add_edge_from(const unsigned int other_vertex) { edges_in.push_back(other_vertex); } void Digraph::Vertex::remove_duplicate_edges(std::vector& tmp) { #if defined(BLISS_CONSISTENCY_CHECKS) /* Pre-conditions */ for(unsigned int i = 0; i < tmp.size(); i++) assert(tmp[i] == false); #endif for(std::vector::iterator iter = edges_out.begin(); iter != edges_out.end(); ) { const unsigned int dest_vertex = *iter; if(tmp[dest_vertex] == true) { /* A duplicate edge found! */ iter = edges_out.erase(iter); } else { /* Not seen earlier, mark as seen */ tmp[dest_vertex] = true; iter++; } } /* Clear tmp */ for(std::vector::iterator iter = edges_out.begin(); iter != edges_out.end(); iter++) { tmp[*iter] = false; } for(std::vector::iterator iter = edges_in.begin(); iter != edges_in.end(); ) { const unsigned int dest_vertex = *iter; if(tmp[dest_vertex] == true) { /* A duplicate edge found! */ iter = edges_in.erase(iter); } else { /* Not seen earlier, mark as seen */ tmp[dest_vertex] = true; iter++; } } /* Clear tmp */ for(std::vector::iterator iter = edges_in.begin(); iter != edges_in.end(); iter++) { tmp[*iter] = false; } #if defined(BLISS_CONSISTENCY_CHECKS) /* Post-conditions */ for(unsigned int i = 0; i < tmp.size(); i++) assert(tmp[i] == false); #endif } /** * Sort the edges entering and leaving the vertex according to * the vertex number of the other edge end. * Time complexity: O(e log(e)), where e is the number of edges * entering/leaving the vertex. */ void Digraph::Vertex::sort_edges() { std::sort(edges_in.begin(), edges_in.end()); std::sort(edges_out.begin(), edges_out.end()); } /*------------------------------------------------------------------------- * * Constructor and destructor for directed graphs * *-------------------------------------------------------------------------*/ Digraph::Digraph(const unsigned int nof_vertices) { vertices.resize(nof_vertices); sh = shs_flm; } Digraph::~Digraph() { ; } unsigned int Digraph::add_vertex(const unsigned int color) { const unsigned int new_vertex_num = vertices.size(); vertices.resize(new_vertex_num + 1); vertices.back().color = color; return new_vertex_num; } void Digraph::add_edge(const unsigned int vertex1, const unsigned int vertex2) { if(vertex1 >= vertices.size() or vertex2 >= vertices.size()) throw std::runtime_error("out of bounds vertex number"); //assert(vertex1 < get_nof_vertices()); //assert(vertex2 < get_nof_vertices()); vertices[vertex1].add_edge_to(vertex2); vertices[vertex2].add_edge_from(vertex1); } void Digraph::change_color(const unsigned int vertex, const unsigned int new_color) { assert(vertex < get_nof_vertices()); vertices[vertex].color = new_color; } void Digraph::sort_edges() { for(unsigned int i = 0; i < get_nof_vertices(); i++) vertices[i].sort_edges(); } int Digraph::cmp(Digraph& other) { /* Compare the numbers of vertices */ if(get_nof_vertices() < other.get_nof_vertices()) return -1; if(get_nof_vertices() > other.get_nof_vertices()) return 1; /* Compare vertex colors */ for(unsigned int i = 0; i < get_nof_vertices(); i++) { if(vertices[i].color < other.vertices[i].color) return -1; if(vertices[i].color > other.vertices[i].color) return 1; } /* Compare vertex degrees */ remove_duplicate_edges(); other.remove_duplicate_edges(); for(unsigned int i = 0; i < get_nof_vertices(); i++) { if(vertices[i].nof_edges_in() < other.vertices[i].nof_edges_in()) return -1; if(vertices[i].nof_edges_in() > other.vertices[i].nof_edges_in()) return 1; if(vertices[i].nof_edges_out() < other.vertices[i].nof_edges_out()) return -1; if(vertices[i].nof_edges_out() > other.vertices[i].nof_edges_out()) return 1; } /* Compare edges */ for(unsigned int i = 0; i < get_nof_vertices(); i++) { Vertex& v1 = vertices[i]; Vertex& v2 = other.vertices[i]; v1.sort_edges(); v2.sort_edges(); std::vector::const_iterator ei1 = v1.edges_in.begin(); std::vector::const_iterator ei2 = v2.edges_in.begin(); while(ei1 != v1.edges_in.end()) { if(*ei1 < *ei2) return -1; if(*ei1 > *ei2) return 1; ei1++; ei2++; } ei1 = v1.edges_out.begin(); ei2 = v2.edges_out.begin(); while(ei1 != v1.edges_out.end()) { if(*ei1 < *ei2) return -1; if(*ei1 > *ei2) return 1; ei1++; ei2++; } } return 0; } Digraph* Digraph::permute(const std::vector& perm) const { Digraph* const g = new Digraph(get_nof_vertices()); for(unsigned int i = 0; i < get_nof_vertices(); i++) { const Vertex& v = vertices[i]; g->change_color(perm[i], v.color); for(std::vector::const_iterator ei = v.edges_out.begin(); ei != v.edges_out.end(); ei++) { g->add_edge(perm[i], perm[*ei]); } } g->sort_edges(); return g; } Digraph* Digraph::permute(const unsigned int* const perm) const { Digraph* const g = new Digraph(get_nof_vertices()); for(unsigned int i = 0; i < get_nof_vertices(); i++) { const Vertex &v = vertices[i]; g->change_color(perm[i], v.color); for(std::vector::const_iterator ei = v.edges_out.begin(); ei != v.edges_out.end(); ei++) { g->add_edge(perm[i], perm[*ei]); } } g->sort_edges(); return g; } void Digraph::remove_duplicate_edges() { std::vector tmp(get_nof_vertices(), false); for(std::vector::iterator vi = vertices.begin(); vi != vertices.end(); vi++) { #if defined(BLISS_EXPENSIVE_CONSISTENCY_CHECKS) for(unsigned int i = 0; i < tmp.size(); i++) assert(tmp[i] == false); #endif (*vi).remove_duplicate_edges(tmp); } } /*------------------------------------------------------------------------- * * Get a hash value for the graph. * *-------------------------------------------------------------------------*/ unsigned int Digraph::get_hash() { remove_duplicate_edges(); sort_edges(); UintSeqHash h; h.update(get_nof_vertices()); /* Hash the color of each vertex */ for(unsigned int i = 0; i < get_nof_vertices(); i++) { h.update(vertices[i].color); } /* Hash the edges */ for(unsigned int i = 0; i < get_nof_vertices(); i++) { Vertex &v = vertices[i]; for(std::vector::const_iterator ei = v.edges_out.begin(); ei != v.edges_out.end(); ei++) { h.update(i); h.update(*ei); } } return h.get_value(); } /*------------------------------------------------------------------------- * * Partition independent invariants * *-------------------------------------------------------------------------*/ unsigned int Digraph::vertex_color_invariant(const Digraph* const g, const unsigned int vnum) { return g->vertices[vnum].color; } unsigned int Digraph::indegree_invariant(const Digraph* const g, const unsigned int vnum) { return g->vertices[vnum].nof_edges_in(); } unsigned int Digraph::outdegree_invariant(const Digraph* const g, const unsigned int vnum) { return g->vertices[vnum].nof_edges_out(); } unsigned int Digraph::selfloop_invariant(const Digraph* const g, const unsigned int vnum) { /* Quite inefficient but luckily not in the critical path */ const Vertex& v = g->vertices[vnum]; for(std::vector::const_iterator ei = v.edges_out.begin(); ei != v.edges_out.end(); ei++) { if(*ei == vnum) return 1; } return 0; } /*------------------------------------------------------------------------- * * Refine the partition p according to a partition independent invariant * *-------------------------------------------------------------------------*/ bool Digraph::refine_according_to_invariant(unsigned int (*inv)(const Digraph* const g, const unsigned int v)) { bool refined = false; for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; ) { Partition::Cell* const next_cell = cell->next_nonsingleton; const unsigned int* ep = p.elements + cell->first; for(unsigned int i = cell->length; i > 0; i--, ep++) { unsigned int ival = inv(this, *ep); p.invariant_values[*ep] = ival; if(ival > cell->max_ival) { cell->max_ival = ival; cell->max_ival_count = 1; } else if(ival == cell->max_ival) { cell->max_ival_count++; } } Partition::Cell* const last_new_cell = p.zplit_cell(cell, true); refined |= (last_new_cell != cell); cell = next_cell; } return refined; } /*------------------------------------------------------------------------- * * Split the neighbourhood of a cell according to the equitable invariant * *-------------------------------------------------------------------------*/ bool Digraph::split_neighbourhood_of_cell(Partition::Cell* const cell) { const bool was_equal_to_first = refine_equal_to_first; if(compute_eqref_hash) { eqref_hash.update(cell->first); eqref_hash.update(cell->length); } const unsigned int* ep = p.elements + cell->first; for(unsigned int i = cell->length; i > 0; i--) { const Vertex& v = vertices[*ep++]; std::vector::const_iterator ei = v.edges_out.begin(); for(unsigned int j = v.nof_edges_out(); j != 0; j--) { const unsigned int dest_vertex = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(dest_vertex); if(neighbour_cell->is_unit()) continue; const unsigned int ival = ++p.invariant_values[dest_vertex]; if(ival > neighbour_cell->max_ival) { neighbour_cell->max_ival = ival; neighbour_cell->max_ival_count = 1; if(ival == 1) neighbour_heap.insert(neighbour_cell->first); } else if(ival == neighbour_cell->max_ival) { neighbour_cell->max_ival_count++; } } } while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* const neighbour_cell = p.get_cell(p.elements[start]); if(compute_eqref_hash) { eqref_hash.update(neighbour_cell->first); eqref_hash.update(neighbour_cell->length); eqref_hash.update(neighbour_cell->max_ival); eqref_hash.update(neighbour_cell->max_ival_count); } Partition::Cell* const last_new_cell = p.zplit_cell(neighbour_cell, true); /* Update certificate and hash if needed */ const Partition::Cell* c = neighbour_cell; while(1) { if(in_search) { /* Build certificate */ cert_add_redundant(CERT_SPLIT, c->first, c->length); /* No need to continue? */ if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) goto worse_exit; } if(compute_eqref_hash) { eqref_hash.update(c->first); eqref_hash.update(c->length); } if(c == last_new_cell) break; c = c->next; } } if(cell->is_in_splitting_queue()) { return false; } ep = p.elements + cell->first; for(unsigned int i = cell->length; i > 0; i--) { const Vertex& v = vertices[*ep++]; std::vector::const_iterator ei = v.edges_in.begin(); for(unsigned int j = v.nof_edges_in(); j > 0; j--) { const unsigned int dest_vertex = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(dest_vertex); if(neighbour_cell->is_unit()) continue; const unsigned int ival = ++p.invariant_values[dest_vertex]; if(ival > neighbour_cell->max_ival) { neighbour_cell->max_ival = ival; neighbour_cell->max_ival_count = 1; if(ival == 1) neighbour_heap.insert(neighbour_cell->first); } else if(ival == neighbour_cell->max_ival) { neighbour_cell->max_ival_count++; } } } while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* const neighbour_cell = p.get_cell(p.elements[start]); if(compute_eqref_hash) { eqref_hash.update(neighbour_cell->first); eqref_hash.update(neighbour_cell->length); eqref_hash.update(neighbour_cell->max_ival); eqref_hash.update(neighbour_cell->max_ival_count); } Partition::Cell* const last_new_cell = p.zplit_cell(neighbour_cell, true); /* Update certificate and hash if needed */ const Partition::Cell* c = neighbour_cell; while(1) { if(in_search) { /* Build certificate */ cert_add_redundant(CERT_SPLIT, c->first, c->length); /* No need to continue? */ if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) goto worse_exit; } if(compute_eqref_hash) { eqref_hash.update(c->first); eqref_hash.update(c->length); } if(c == last_new_cell) break; c = c->next; } } if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) return true; return false; worse_exit: /* Clear neighbour heap */ UintSeqHash rest; while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* const neighbour_cell = p.get_cell(p.elements[start]); if(opt_use_failure_recording and was_equal_to_first) { rest.update(neighbour_cell->first); rest.update(neighbour_cell->length); rest.update(neighbour_cell->max_ival); rest.update(neighbour_cell->max_ival_count); } neighbour_cell->max_ival = 0; neighbour_cell->max_ival_count = 0; p.clear_ivs(neighbour_cell); } if(opt_use_failure_recording and was_equal_to_first) { for(unsigned int i = p.splitting_queue.size(); i > 0; i--) { Partition::Cell* const cell = p.splitting_queue.pop_front(); rest.update(cell->first); rest.update(cell->length); p.splitting_queue.push_back(cell); } rest.update(failure_recording_fp_deviation); failure_recording_fp_deviation = rest.get_value(); } return true; } bool Digraph::split_neighbourhood_of_unit_cell(Partition::Cell* const unit_cell) { const bool was_equal_to_first = refine_equal_to_first; if(compute_eqref_hash) { eqref_hash.update(0x87654321); eqref_hash.update(unit_cell->first); eqref_hash.update(1); } const Vertex& v = vertices[p.elements[unit_cell->first]]; /* * Phase 1 * Refine neighbours according to the edges that leave the vertex v */ std::vector::const_iterator ei = v.edges_out.begin(); for(unsigned int j = v.nof_edges_out(); j > 0; j--) { const unsigned int dest_vertex = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(dest_vertex); if(neighbour_cell->is_unit()) { if(in_search) { /* Remember neighbour in order to generate certificate */ neighbour_heap.insert(neighbour_cell->first); } continue; } if(neighbour_cell->max_ival_count == 0) { neighbour_heap.insert(neighbour_cell->first); } neighbour_cell->max_ival_count++; unsigned int* const swap_position = p.elements + neighbour_cell->first + neighbour_cell->length - neighbour_cell->max_ival_count; *p.in_pos[dest_vertex] = *swap_position; p.in_pos[*swap_position] = p.in_pos[dest_vertex]; *swap_position = dest_vertex; p.in_pos[dest_vertex] = swap_position; } while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* neighbour_cell = p.get_cell(p.elements[start]); #if defined(BLISS_CONSISTENCY_CHECKS) assert(neighbour_cell->first == start); if(neighbour_cell->is_unit()) { assert(neighbour_cell->max_ival_count == 0); } else { assert(neighbour_cell->max_ival_count > 0); assert(neighbour_cell->max_ival_count <= neighbour_cell->length); } #endif if(compute_eqref_hash) { eqref_hash.update(neighbour_cell->first); eqref_hash.update(neighbour_cell->length); eqref_hash.update(neighbour_cell->max_ival_count); } if(neighbour_cell->length > 1 and neighbour_cell->max_ival_count != neighbour_cell->length) { Partition::Cell* const new_cell = p.aux_split_in_two(neighbour_cell, neighbour_cell->length - neighbour_cell->max_ival_count); unsigned int* ep = p.elements + new_cell->first; unsigned int* const lp = p.elements+new_cell->first+new_cell->length; while(ep < lp) { p.element_to_cell_map[*ep] = new_cell; ep++; } neighbour_cell->max_ival_count = 0; if(compute_eqref_hash) { /* Update hash */ eqref_hash.update(neighbour_cell->first); eqref_hash.update(neighbour_cell->length); eqref_hash.update(0); eqref_hash.update(new_cell->first); eqref_hash.update(new_cell->length); eqref_hash.update(1); } /* Add cells in splitting_queue */ if(neighbour_cell->is_in_splitting_queue()) { /* Both cells must be included in splitting_queue in order to have refinement to equitable partition */ p.splitting_queue_add(new_cell); } else { Partition::Cell *min_cell, *max_cell; if(neighbour_cell->length <= new_cell->length) { min_cell = neighbour_cell; max_cell = new_cell; } else { min_cell = new_cell; max_cell = neighbour_cell; } /* Put the smaller cell in splitting_queue */ p.splitting_queue_add(min_cell); if(max_cell->is_unit()) { /* Put the "larger" cell also in splitting_queue */ p.splitting_queue_add(max_cell); } } /* Update pointer for certificate generation */ neighbour_cell = new_cell; } else { neighbour_cell->max_ival_count = 0; } /* * Build certificate if required */ if(in_search) { for(unsigned int i = neighbour_cell->first, j = neighbour_cell->length; j > 0; j--, i++) { /* Build certificate */ cert_add(CERT_EDGE, unit_cell->first, i); /* No need to continue? */ if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) goto worse_exit; } } /* if(in_search) */ } /* while(!neighbour_heap.is_empty()) */ /* * Phase 2 * Refine neighbours according to the edges that enter the vertex v */ ei = v.edges_in.begin(); for(unsigned int j = v.nof_edges_in(); j > 0; j--) { const unsigned int dest_vertex = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(dest_vertex); if(neighbour_cell->is_unit()) { if(in_search) { neighbour_heap.insert(neighbour_cell->first); } continue; } if(neighbour_cell->max_ival_count == 0) { neighbour_heap.insert(neighbour_cell->first); } neighbour_cell->max_ival_count++; unsigned int* const swap_position = p.elements + neighbour_cell->first + neighbour_cell->length - neighbour_cell->max_ival_count; *p.in_pos[dest_vertex] = *swap_position; p.in_pos[*swap_position] = p.in_pos[dest_vertex]; *swap_position = dest_vertex; p.in_pos[dest_vertex] = swap_position; } while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* neighbour_cell = p.get_cell(p.elements[start]); #if defined(BLISS_CONSISTENCY_CHECKS) assert(neighbour_cell->first == start); if(neighbour_cell->is_unit()) { assert(neighbour_cell->max_ival_count == 0); } else { assert(neighbour_cell->max_ival_count > 0); assert(neighbour_cell->max_ival_count <= neighbour_cell->length); } #endif if(compute_eqref_hash) { eqref_hash.update(neighbour_cell->first); eqref_hash.update(neighbour_cell->length); eqref_hash.update(neighbour_cell->max_ival_count); } if(neighbour_cell->length > 1 and neighbour_cell->max_ival_count != neighbour_cell->length) { Partition::Cell* const new_cell = p.aux_split_in_two(neighbour_cell, neighbour_cell->length - neighbour_cell->max_ival_count); unsigned int* ep = p.elements + new_cell->first; unsigned int* const lp = p.elements+new_cell->first+new_cell->length; while(ep < lp) { p.element_to_cell_map[*ep] = new_cell; ep++; } neighbour_cell->max_ival_count = 0; if(compute_eqref_hash) { eqref_hash.update(neighbour_cell->first); eqref_hash.update(neighbour_cell->length); eqref_hash.update(0); eqref_hash.update(new_cell->first); eqref_hash.update(new_cell->length); eqref_hash.update(1); } /* Add cells in splitting_queue */ if(neighbour_cell->is_in_splitting_queue()) { /* Both cells must be included in splitting_queue in order to have refinement to equitable partition */ p.splitting_queue_add(new_cell); } else { Partition::Cell *min_cell, *max_cell; if(neighbour_cell->length <= new_cell->length) { min_cell = neighbour_cell; max_cell = new_cell; } else { min_cell = new_cell; max_cell = neighbour_cell; } /* Put the smaller cell in splitting_queue */ p.splitting_queue_add(min_cell); if(max_cell->is_unit()) { /* Put the "larger" cell also in splitting_queue */ p.splitting_queue_add(max_cell); } } /* Update pointer for certificate generation */ neighbour_cell = new_cell; } else { neighbour_cell->max_ival_count = 0; } /* * Build certificate if required */ if(in_search) { for(unsigned int i = neighbour_cell->first, j = neighbour_cell->length; j > 0; j--, i++) { /* Build certificate */ cert_add(CERT_EDGE, i, unit_cell->first); /* No need to continue? */ if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) goto worse_exit; } } /* if(in_search) */ } /* while(!neighbour_heap.is_empty()) */ if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) return true; return false; worse_exit: /* Clear neighbour heap */ UintSeqHash rest; while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* const neighbour_cell = p.get_cell(p.elements[start]); if(opt_use_failure_recording and was_equal_to_first) { rest.update(neighbour_cell->first); rest.update(neighbour_cell->length); rest.update(neighbour_cell->max_ival_count); } neighbour_cell->max_ival_count = 0; } if(opt_use_failure_recording and was_equal_to_first) { rest.update(failure_recording_fp_deviation); failure_recording_fp_deviation = rest.get_value(); } return true; } /*------------------------------------------------------------------------- * * Check whether the current partition p is equitable. * Performance: very slow, use only for debugging purposes. * *-------------------------------------------------------------------------*/ bool Digraph::is_equitable() const { const unsigned int N = get_nof_vertices(); if(N == 0) return true; std::vector first_count = std::vector(N, 0); std::vector other_count = std::vector(N, 0); /* * Check equitabledness w.r.t. outgoing edges */ for(Partition::Cell* cell = p.first_cell; cell; cell = cell->next) { if(cell->is_unit()) continue; unsigned int* ep = p.elements + cell->first; const Vertex& first_vertex = vertices[*ep++]; /* Count outgoing edges of the first vertex for cells */ for(std::vector::const_iterator ei = first_vertex.edges_out.begin(); ei != first_vertex.edges_out.end(); ei++) { first_count[p.get_cell(*ei)->first]++; } /* Count and compare outgoing edges of the other vertices */ for(unsigned int i = cell->length; i > 1; i--) { const Vertex &vertex = vertices[*ep++]; for(std::vector::const_iterator ei = vertex.edges_out.begin(); ei != vertex.edges_out.end(); ei++) { other_count[p.get_cell(*ei)->first]++; } for(Partition::Cell *cell2 = p.first_cell; cell2; cell2 = cell2->next) { if(first_count[cell2->first] != other_count[cell2->first]) { /* Not equitable */ return false; } other_count[cell2->first] = 0; } } /* Reset first_count */ for(unsigned int i = 0; i < N; i++) first_count[i] = 0; } /* * Check equitabledness w.r.t. incoming edges */ for(Partition::Cell* cell = p.first_cell; cell; cell = cell->next) { if(cell->is_unit()) continue; unsigned int* ep = p.elements + cell->first; const Vertex& first_vertex = vertices[*ep++]; /* Count incoming edges of the first vertex for cells */ for(std::vector::const_iterator ei = first_vertex.edges_in.begin(); ei != first_vertex.edges_in.end(); ei++) { first_count[p.get_cell(*ei)->first]++; } /* Count and compare incoming edges of the other vertices */ for(unsigned int i = cell->length; i > 1; i--) { const Vertex &vertex = vertices[*ep++]; for(std::vector::const_iterator ei = vertex.edges_in.begin(); ei != vertex.edges_in.end(); ei++) { other_count[p.get_cell(*ei)->first]++; } for(Partition::Cell *cell2 = p.first_cell; cell2; cell2 = cell2->next) { if(first_count[cell2->first] != other_count[cell2->first]) { /* Not equitable */ return false; } other_count[cell2->first] = 0; } } /* Reset first_count */ for(unsigned int i = 0; i < N; i++) first_count[i] = 0; } return true; } /*------------------------------------------------------------------------- * * Build the initial equitable partition * *-------------------------------------------------------------------------*/ void Digraph::make_initial_equitable_partition() { refine_according_to_invariant(&vertex_color_invariant); p.splitting_queue_clear(); //p.print_signature(stderr); fprintf(stderr, "\n"); refine_according_to_invariant(&selfloop_invariant); p.splitting_queue_clear(); //p.print_signature(stderr); fprintf(stderr, "\n"); refine_according_to_invariant(&outdegree_invariant); p.splitting_queue_clear(); //p.print_signature(stderr); fprintf(stderr, "\n"); refine_according_to_invariant(&indegree_invariant); p.splitting_queue_clear(); //p.print_signature(stderr); fprintf(stderr, "\n"); refine_to_equitable(); //p.print_signature(stderr); fprintf(stderr, "\n"); } /*------------------------------------------------------------------------- * * Find the next cell to be splitted * *-------------------------------------------------------------------------*/ Partition::Cell* Digraph::find_next_cell_to_be_splitted(Partition::Cell* cell) { switch(sh) { case shs_f: return sh_first(); case shs_fs: return sh_first_smallest(); case shs_fl: return sh_first_largest(); case shs_fm: return sh_first_max_neighbours(); case shs_fsm: return sh_first_smallest_max_neighbours(); case shs_flm: return sh_first_largest_max_neighbours(); default: fatal_error("Internal error - unknown splitting heuristics"); return 0; } } /** \internal * A splitting heuristic. * Returns the first nonsingleton cell in the current partition. * The argument \a cell is ignored. */ Partition::Cell* Digraph::sh_first() { Partition::Cell* best_cell = 0; for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; best_cell = cell; break; } return best_cell; } /** \internal * A splitting heuristic. * Returns the first smallest nonsingleton cell in the current partition. * The argument \a cell is ignored. */ Partition::Cell* Digraph::sh_first_smallest() { Partition::Cell* best_cell = 0; unsigned int best_size = UINT_MAX; for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; if(cell->length < best_size) { best_size = cell->length; best_cell = cell; } } return best_cell; } /** \internal * A splitting heuristic. * Returns the first largest nonsingleton cell in the current partition. * The argument \a cell is ignored. */ Partition::Cell* Digraph::sh_first_largest() { Partition::Cell* best_cell = 0; unsigned int best_size = 0; for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; if(cell->length > best_size) { best_size = cell->length; best_cell = cell; } } return best_cell; } /** \internal * A splitting heuristic. * Returns the first nonsingleton cell with max number of neighbouring * nonsingleton cells. * Assumes that the partition p is equitable. * Assumes that the max_ival fields of the cells are all 0. */ Partition::Cell* Digraph::sh_first_max_neighbours() { Partition::Cell* best_cell = 0; int best_value = -1; KStack neighbour_cells_visited; neighbour_cells_visited.init(get_nof_vertices()); for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; int value = 0; const Vertex &v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei; ei = v.edges_in.begin(); for(unsigned int j = v.nof_edges_in(); j > 0; j--) { Partition::Cell * const neighbour_cell = p.get_cell(*ei++); if(neighbour_cell->is_unit()) continue; neighbour_cell->max_ival++; if(neighbour_cell->max_ival == 1) neighbour_cells_visited.push(neighbour_cell); } while(!neighbour_cells_visited.is_empty()) { Partition::Cell* const neighbour_cell = neighbour_cells_visited.pop(); if(neighbour_cell->max_ival != neighbour_cell->length) value++; neighbour_cell->max_ival = 0; } ei = v.edges_out.begin(); for(unsigned int j = v.nof_edges_out(); j > 0; j--) { Partition::Cell * const neighbour_cell = p.get_cell(*ei++); if(neighbour_cell->is_unit()) continue; neighbour_cell->max_ival++; if(neighbour_cell->max_ival == 1) neighbour_cells_visited.push(neighbour_cell); } while(!neighbour_cells_visited.is_empty()) { Partition::Cell* const neighbour_cell = neighbour_cells_visited.pop(); if(neighbour_cell->max_ival != neighbour_cell->length) value++; neighbour_cell->max_ival = 0; } if(value > best_value) { best_value = value; best_cell = cell; } } return best_cell; } /** \internal * A splitting heuristic. * Returns the first smallest nonsingleton cell with max number of neighbouring * nonsingleton cells. * Assumes that the partition p is equitable. * Assumes that the max_ival fields of the cells are all 0. */ Partition::Cell* Digraph::sh_first_smallest_max_neighbours() { Partition::Cell* best_cell = 0; int best_value = -1; unsigned int best_size = UINT_MAX; KStack neighbour_cells_visited; neighbour_cells_visited.init(get_nof_vertices()); for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; int value = 0; const Vertex& v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei; ei = v.edges_in.begin(); for(unsigned int j = v.nof_edges_in(); j > 0; j--) { Partition::Cell * const neighbour_cell = p.get_cell(*ei++); if(neighbour_cell->is_unit()) continue; neighbour_cell->max_ival++; if(neighbour_cell->max_ival == 1) neighbour_cells_visited.push(neighbour_cell); } while(!neighbour_cells_visited.is_empty()) { Partition::Cell * const neighbour_cell = neighbour_cells_visited.pop(); if(neighbour_cell->max_ival != neighbour_cell->length) value++; neighbour_cell->max_ival = 0; } ei = v.edges_out.begin(); for(unsigned int j = v.nof_edges_out(); j > 0; j--) { Partition::Cell * const neighbour_cell = p.get_cell(*ei++); if(neighbour_cell->is_unit()) continue; neighbour_cell->max_ival++; if(neighbour_cell->max_ival == 1) neighbour_cells_visited.push(neighbour_cell); } while(!neighbour_cells_visited.is_empty()) { Partition::Cell * const neighbour_cell = neighbour_cells_visited.pop(); if(neighbour_cell->max_ival != neighbour_cell->length) value++; neighbour_cell->max_ival = 0; } if((value > best_value) or (value == best_value and cell->length < best_size)) { best_value = value; best_size = cell->length; best_cell = cell; } } return best_cell; } /** \internal * A splitting heuristic. * Returns the first largest nonsingleton cell with max number of neighbouring * nonsingleton cells. * Assumes that the partition p is equitable. * Assumes that the max_ival fields of the cells are all 0. */ Partition::Cell* Digraph::sh_first_largest_max_neighbours() { Partition::Cell* best_cell = 0; int best_value = -1; unsigned int best_size = 0; KStack neighbour_cells_visited; neighbour_cells_visited.init(get_nof_vertices()); for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; int value = 0; const Vertex &v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei; ei = v.edges_in.begin(); for(unsigned int j = v.nof_edges_in(); j > 0; j--) { Partition::Cell* const neighbour_cell = p.get_cell(*ei++); if(neighbour_cell->is_unit()) continue; neighbour_cell->max_ival++; if(neighbour_cell->max_ival == 1) neighbour_cells_visited.push(neighbour_cell); } while(!neighbour_cells_visited.is_empty()) { Partition::Cell* const neighbour_cell = neighbour_cells_visited.pop(); if(neighbour_cell->max_ival != neighbour_cell->length) value++; neighbour_cell->max_ival = 0; } ei = v.edges_out.begin(); for(unsigned int j = v.nof_edges_out(); j > 0; j--) { Partition::Cell* const neighbour_cell = p.get_cell(*ei++); if(neighbour_cell->is_unit()) continue; neighbour_cell->max_ival++; if(neighbour_cell->max_ival == 1) neighbour_cells_visited.push(neighbour_cell); } while(!neighbour_cells_visited.is_empty()) { Partition::Cell* const neighbour_cell = neighbour_cells_visited.pop(); if(neighbour_cell->max_ival != neighbour_cell->length) value++; neighbour_cell->max_ival = 0; } if((value > best_value) || (value == best_value && cell->length > best_size)) { best_value = value; best_size = cell->length; best_cell = cell; } } return best_cell; } /*------------------------------------------------------------------------ * * Initialize the certificate size and memory * *-------------------------------------------------------------------------*/ void Digraph::initialize_certificate() { certificate_index = 0; certificate_current_path.clear(); certificate_first_path.clear(); certificate_best_path.clear(); } /* * Check whether perm is an automorphism. * Slow, mainly for debugging and validation purposes. */ bool Digraph::is_automorphism(unsigned int* const perm) const { std::set > edges1; std::set > edges2; #if defined(BLISS_CONSISTENCY_CHECKS) if(!is_permutation(get_nof_vertices(), perm)) _INTERNAL_ERROR(); #endif for(unsigned int i = 0; i < get_nof_vertices(); i++) { const Vertex& v1 = vertices[i]; const Vertex& v2 = vertices[perm[i]]; edges1.clear(); for(std::vector::const_iterator ei = v1.edges_in.cbegin(); ei != v1.edges_in.cend(); ei++) edges1.insert(perm[*ei]); edges2.clear(); for(std::vector::const_iterator ei = v2.edges_in.cbegin(); ei != v2.edges_in.cend(); ei++) edges2.insert(*ei); if(!(edges1 == edges2)) return false; edges1.clear(); for(std::vector::const_iterator ei = v1.edges_out.cbegin(); ei != v1.edges_out.cend(); ei++) edges1.insert(perm[*ei]); edges2.clear(); for(std::vector::const_iterator ei = v2.edges_out.cbegin(); ei != v2.edges_out.cend(); ei++) edges2.insert(*ei); if(!(edges1 == edges2)) return false; } return true; } bool Digraph::is_automorphism(const std::vector& perm) const { if(!(perm.size() == get_nof_vertices() and is_permutation(perm))) return false; std::set > edges1; std::set > edges2; for(unsigned int i = 0; i < get_nof_vertices(); i++) { const Vertex& v1 = vertices[i]; const Vertex& v2 = vertices[perm[i]]; edges1.clear(); for(std::vector::const_iterator ei = v1.edges_in.begin(); ei != v1.edges_in.end(); ei++) edges1.insert(perm[*ei]); edges2.clear(); for(std::vector::const_iterator ei = v2.edges_in.begin(); ei != v2.edges_in.end(); ei++) edges2.insert(*ei); if(!(edges1 == edges2)) return false; edges1.clear(); for(std::vector::const_iterator ei = v1.edges_out.begin(); ei != v1.edges_out.end(); ei++) edges1.insert(perm[*ei]); edges2.clear(); for(std::vector::const_iterator ei = v2.edges_out.begin(); ei != v2.edges_out.end(); ei++) edges2.insert(*ei); if(!(edges1 == edges2)) return false; } return true; } bool Digraph::nucr_find_first_component(const unsigned int level) { cr_component.clear(); cr_component_elements = 0; /* Find first non-discrete cell in the component level */ Partition::Cell* first_cell = p.first_nonsingleton_cell; while(first_cell) { if(p.cr_get_level(first_cell->first) == level) break; first_cell = first_cell->next_nonsingleton; } /* The component is discrete, return false */ if(!first_cell) return false; std::vector component; first_cell->max_ival = 1; component.push_back(first_cell); for(unsigned int i = 0; i < component.size(); i++) { Partition::Cell* const cell = component[i]; const Vertex& v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei; ei = v.edges_out.begin(); for(unsigned int j = v.nof_edges_out(); j > 0; j--) { const unsigned int neighbour = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(neighbour); /* Skip unit neighbours */ if(neighbour_cell->is_unit()) continue; /* Already marked to be in the same component? */ if(neighbour_cell->max_ival == 1) continue; /* Is the neighbour at the same component recursion level? */ if(p.cr_get_level(neighbour_cell->first) != level) continue; if(neighbour_cell->max_ival_count == 0) neighbour_heap.insert(neighbour_cell->first); neighbour_cell->max_ival_count++; } while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* const neighbour_cell = p.get_cell(p.elements[start]); /* Skip saturated neighbour cells */ if(neighbour_cell->max_ival_count == neighbour_cell->length) { neighbour_cell->max_ival_count = 0; continue; } neighbour_cell->max_ival_count = 0; neighbour_cell->max_ival = 1; component.push_back(neighbour_cell); } ei = v.edges_in.begin(); for(unsigned int j = v.nof_edges_in(); j > 0; j--) { const unsigned int neighbour = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(neighbour); /* Skip unit neighbours */ if(neighbour_cell->is_unit()) continue; /* Already marked to be in the same component? */ if(neighbour_cell->max_ival == 1) continue; /* Is the neighbour at the same component recursion level? */ if(p.cr_get_level(neighbour_cell->first) != level) continue; if(neighbour_cell->max_ival_count == 0) neighbour_heap.insert(neighbour_cell->first); neighbour_cell->max_ival_count++; } while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* const neighbour_cell = p.get_cell(p.elements[start]); /* Skip saturated neighbour cells */ if(neighbour_cell->max_ival_count == neighbour_cell->length) { neighbour_cell->max_ival_count = 0; continue; } neighbour_cell->max_ival_count = 0; neighbour_cell->max_ival = 1; component.push_back(neighbour_cell); } } for(unsigned int i = 0; i < component.size(); i++) { Partition::Cell* const cell = component[i]; cell->max_ival = 0; cr_component.push_back(cell->first); cr_component_elements += cell->length; } /* if(verbstr and verbose_level > 2) { fprintf(verbstr, "NU-component with %lu cells and %u vertices\n", (long unsigned)cr_component.size(), cr_component_elements); fflush(verbstr); } */ return true; } bool Digraph::nucr_find_first_component(const unsigned int level, std::vector& component, unsigned int& component_elements, Partition::Cell*& sh_return) { component.clear(); component_elements = 0; sh_return = 0; unsigned int sh_first = 0; unsigned int sh_size = 0; unsigned int sh_nuconn = 0; /* Find first non-discrete cell in the component level */ Partition::Cell* first_cell = p.first_nonsingleton_cell; while(first_cell) { if(p.cr_get_level(first_cell->first) == level) break; first_cell = first_cell->next_nonsingleton; } if(!first_cell) { /* The component is discrete, return false */ return false; } std::vector comp; KStack neighbours; neighbours.init(get_nof_vertices()); first_cell->max_ival = 1; comp.push_back(first_cell); for(unsigned int i = 0; i < comp.size(); i++) { Partition::Cell* const cell = comp[i]; unsigned int nuconn = 1; const Vertex& v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei; /*| Phase 1: outgoing edges */ ei = v.edges_out.begin(); for(unsigned int j = v.nof_edges_out(); j > 0; j--) { const unsigned int neighbour = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(neighbour); /* Skip unit neighbours */ if(neighbour_cell->is_unit()) continue; /* Is the neighbour at the same component recursion level? */ //if(p.cr_get_level(neighbour_cell->first) != level) // continue; if(neighbour_cell->max_ival_count == 0) neighbours.push(neighbour_cell); neighbour_cell->max_ival_count++; } while(!neighbours.is_empty()) { Partition::Cell* const neighbour_cell = neighbours.pop(); /* Skip saturated neighbour cells */ if(neighbour_cell->max_ival_count == neighbour_cell->length) { neighbour_cell->max_ival_count = 0; continue; } nuconn++; neighbour_cell->max_ival_count = 0; if(neighbour_cell->max_ival == 0) { comp.push_back(neighbour_cell); neighbour_cell->max_ival = 1; } } /*| Phase 2: incoming edges */ ei = v.edges_in.begin(); for(unsigned int j = v.nof_edges_in(); j > 0; j--) { const unsigned int neighbour = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(neighbour); /*| Skip unit neighbours */ if(neighbour_cell->is_unit()) continue; /* Is the neighbour at the same component recursion level? */ //if(p.cr_get_level(neighbour_cell->first) != level) // continue; if(neighbour_cell->max_ival_count == 0) neighbours.push(neighbour_cell); neighbour_cell->max_ival_count++; } while(!neighbours.is_empty()) { Partition::Cell* const neighbour_cell = neighbours.pop(); /* Skip saturated neighbour cells */ if(neighbour_cell->max_ival_count == neighbour_cell->length) { neighbour_cell->max_ival_count = 0; continue; } nuconn++; neighbour_cell->max_ival_count = 0; if(neighbour_cell->max_ival == 0) { comp.push_back(neighbour_cell); neighbour_cell->max_ival = 1; } } /*| Phase 3: splitting heuristics */ switch(sh) { case shs_f: if(sh_return == 0 or cell->first <= sh_first) { sh_return = cell; sh_first = cell->first; } break; case shs_fs: if(sh_return == 0 or cell->length < sh_size or (cell->length == sh_size and cell->first <= sh_first)) { sh_return = cell; sh_first = cell->first; sh_size = cell->length; } break; case shs_fl: if(sh_return == 0 or cell->length > sh_size or (cell->length == sh_size and cell->first <= sh_first)) { sh_return = cell; sh_first = cell->first; sh_size = cell->length; } break; case shs_fm: if(sh_return == 0 or nuconn > sh_nuconn or (nuconn == sh_nuconn and cell->first <= sh_first)) { sh_return = cell; sh_first = cell->first; sh_nuconn = nuconn; } break; case shs_fsm: if(sh_return == 0 or nuconn > sh_nuconn or (nuconn == sh_nuconn and (cell->length < sh_size or (cell->length == sh_size and cell->first <= sh_first)))) { sh_return = cell; sh_first = cell->first; sh_size = cell->length; sh_nuconn = nuconn; } break; case shs_flm: if(sh_return == 0 or nuconn > sh_nuconn or (nuconn == sh_nuconn and (cell->length > sh_size or (cell->length == sh_size and cell->first <= sh_first)))) { sh_return = cell; sh_first = cell->first; sh_size = cell->length; sh_nuconn = nuconn; } break; default: fatal_error("Internal error - unknown splitting heuristics"); return 0; } } assert(sh_return); for(unsigned int i = 0; i < comp.size(); i++) { Partition::Cell* const cell = comp[i]; cell->max_ival = 0; component.push_back(cell->first); component_elements += cell->length; } /* if(verbstr and verbose_level > 2) { fprintf(verbstr, "NU-component with %lu cells and %u vertices\n", (long unsigned)component.size(), component_elements); fflush(verbstr); } */ return true; } /*------------------------------------------------------------------------- * * Routines for undirected graphs * *-------------------------------------------------------------------------*/ Graph::Vertex::Vertex() { color = 0; } Graph::Vertex::~Vertex() { ; } void Graph::Vertex::add_edge(const unsigned int other_vertex) { edges.push_back(other_vertex); } void Graph::Vertex::remove_duplicate_edges(std::vector& tmp) { #if defined(BLISS_CONSISTENCY_CHECKS) /* Pre-conditions */ for(unsigned int i = 0; i < tmp.size(); i++) assert(tmp[i] == false); #endif for(std::vector::iterator iter = edges.begin(); iter != edges.end(); ) { const unsigned int dest_vertex = *iter; if(tmp[dest_vertex] == true) { /* A duplicate edge found! */ iter = edges.erase(iter); } else { /* Not seen earlier, mark as seen */ tmp[dest_vertex] = true; iter++; } } /* Clear tmp */ for(std::vector::iterator iter = edges.begin(); iter != edges.end(); iter++) { tmp[*iter] = false; } #if defined(BLISS_CONSISTENCY_CHECKS) /* Post-conditions */ for(unsigned int i = 0; i < tmp.size(); i++) assert(tmp[i] == false); #endif } /** * Sort the edges leaving the vertex according to * the vertex number of the other edge end. * Time complexity: O(e log(e)), where e is the number of edges * leaving the vertex. */ void Graph::Vertex::sort_edges() { std::sort(edges.begin(), edges.end()); } /*------------------------------------------------------------------------- * * Constructor and destructor for undirected graphs * *-------------------------------------------------------------------------*/ Graph::Graph(const unsigned int nof_vertices) { vertices.resize(nof_vertices); sh = shs_flm; } Graph::~Graph() { ; } unsigned int Graph::add_vertex(const unsigned int color) { const unsigned int vertex_num = vertices.size(); vertices.resize(vertex_num + 1); vertices.back().color = color; return vertex_num; } void Graph::add_edge(const unsigned int vertex1, const unsigned int vertex2) { //fprintf(stderr, "(%u,%u) ", vertex1, vertex2); if(vertex1 >= vertices.size() or vertex2 >= vertices.size()) throw std::runtime_error("out of bounds vertex number"); vertices[vertex1].add_edge(vertex2); vertices[vertex2].add_edge(vertex1); } void Graph::change_color(const unsigned int vertex, const unsigned int color) { vertices[vertex].color = color; } void Graph::sort_edges() { for(unsigned int i = 0; i < get_nof_vertices(); i++) vertices[i].sort_edges(); } int Graph::cmp(Graph& other) { /* Compare the numbers of vertices */ if(get_nof_vertices() < other.get_nof_vertices()) return -1; if(get_nof_vertices() > other.get_nof_vertices()) return 1; /* Compare vertex colors */ for(unsigned int i = 0; i < get_nof_vertices(); i++) { if(vertices[i].color < other.vertices[i].color) return -1; if(vertices[i].color > other.vertices[i].color) return 1; } /* Compare vertex degrees */ remove_duplicate_edges(); other.remove_duplicate_edges(); for(unsigned int i = 0; i < get_nof_vertices(); i++) { if(vertices[i].nof_edges() < other.vertices[i].nof_edges()) return -1; if(vertices[i].nof_edges() > other.vertices[i].nof_edges()) return 1; } /* Compare edges */ for(unsigned int i = 0; i < get_nof_vertices(); i++) { Vertex &v1 = vertices[i]; Vertex &v2 = other.vertices[i]; v1.sort_edges(); v2.sort_edges(); std::vector::const_iterator ei1 = v1.edges.begin(); std::vector::const_iterator ei2 = v2.edges.begin(); while(ei1 != v1.edges.end()) { if(*ei1 < *ei2) return -1; if(*ei1 > *ei2) return 1; ei1++; ei2++; } } return 0; } Graph* Graph::permute(const std::vector& perm) const { #if defined(BLISS_CONSISTENCY_CHECKS) #endif Graph* const g = new Graph(get_nof_vertices()); for(unsigned int i = 0; i < get_nof_vertices(); i++) { const Vertex& v = vertices[i]; Vertex& permuted_v = g->vertices[perm[i]]; permuted_v.color = v.color; for(std::vector::const_iterator ei = v.edges.begin(); ei != v.edges.end(); ei++) { const unsigned int dest_v = *ei; permuted_v.add_edge(perm[dest_v]); } permuted_v.sort_edges(); } return g; } Graph* Graph::permute(const unsigned int* perm) const { #if defined(BLISS_CONSISTENCY_CHECKS) if(!is_permutation(get_nof_vertices(), perm)) _INTERNAL_ERROR(); #endif Graph* const g = new Graph(get_nof_vertices()); for(unsigned int i = 0; i < get_nof_vertices(); i++) { const Vertex& v = vertices[i]; Vertex& permuted_v = g->vertices[perm[i]]; permuted_v.color = v.color; for(std::vector::const_iterator ei = v.edges.begin(); ei != v.edges.end(); ei++) { const unsigned int dest_v = *ei; permuted_v.add_edge(perm[dest_v]); } permuted_v.sort_edges(); } return g; } /*------------------------------------------------------------------------- * * Get a hash value for the graph. * *-------------------------------------------------------------------------*/ unsigned int Graph::get_hash() { remove_duplicate_edges(); sort_edges(); UintSeqHash h; h.update(get_nof_vertices()); /* Hash the color of each vertex */ for(unsigned int i = 0; i < get_nof_vertices(); i++) { h.update(vertices[i].color); } /* Hash the edges */ for(unsigned int i = 0; i < get_nof_vertices(); i++) { Vertex &v = vertices[i]; for(std::vector::const_iterator ei = v.edges.begin(); ei != v.edges.end(); ei++) { const unsigned int dest_i = *ei; if(dest_i < i) continue; h.update(i); h.update(dest_i); } } return h.get_value(); } void Graph::remove_duplicate_edges() { std::vector tmp(vertices.size(), false); for(std::vector::iterator vi = vertices.begin(); vi != vertices.end(); vi++) { #if defined(BLISS_EXPENSIVE_CONSISTENCY_CHECKS) for(unsigned int i = 0; i < tmp.size(); i++) assert(tmp[i] == false); #endif (*vi).remove_duplicate_edges(tmp); } } /*------------------------------------------------------------------------- * * Partition independent invariants * *-------------------------------------------------------------------------*/ /* * Return the color of the vertex. * Time complexity: O(1) */ unsigned int Graph::vertex_color_invariant(const Graph* const g, const unsigned int v) { return g->vertices[v].color; } /* * Return the degree of the vertex. * Time complexity: O(1) */ unsigned int Graph::degree_invariant(const Graph* const g, const unsigned int v) { return g->vertices[v].nof_edges(); } /* * Return 1 if the vertex v has a self-loop, 0 otherwise * Time complexity: O(E_v), where E_v is the number of edges leaving v */ unsigned int Graph::selfloop_invariant(const Graph* const g, const unsigned int v) { const Vertex& vertex = g->vertices[v]; for(std::vector::const_iterator ei = vertex.edges.begin(); ei != vertex.edges.end(); ei++) { if(*ei == v) return 1; } return 0; } /*------------------------------------------------------------------------- * * Refine the partition p according to a partition independent invariant * *-------------------------------------------------------------------------*/ bool Graph::refine_according_to_invariant(unsigned int (*inv)(const Graph* const g, const unsigned int v)) { bool refined = false; for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; ) { Partition::Cell* const next_cell = cell->next_nonsingleton; const unsigned int* ep = p.elements + cell->first; for(unsigned int i = cell->length; i > 0; i--, ep++) { const unsigned int ival = inv(this, *ep); p.invariant_values[*ep] = ival; if(ival > cell->max_ival) { cell->max_ival = ival; cell->max_ival_count = 1; } else if(ival == cell->max_ival) { cell->max_ival_count++; } } Partition::Cell* const last_new_cell = p.zplit_cell(cell, true); refined |= (last_new_cell != cell); cell = next_cell; } return refined; } /*------------------------------------------------------------------------- * * Split the neighbourhood of a cell according to the equitable invariant * *-------------------------------------------------------------------------*/ bool Graph::split_neighbourhood_of_cell(Partition::Cell* const cell) { const bool was_equal_to_first = refine_equal_to_first; if(compute_eqref_hash) { eqref_hash.update(cell->first); eqref_hash.update(cell->length); } const unsigned int* ep = p.elements + cell->first; for(unsigned int i = cell->length; i > 0; i--) { const Vertex& v = vertices[*ep++]; std::vector::const_iterator ei = v.edges.begin(); for(unsigned int j = v.nof_edges(); j != 0; j--) { const unsigned int dest_vertex = *ei++; Partition::Cell * const neighbour_cell = p.get_cell(dest_vertex); if(neighbour_cell->is_unit()) continue; const unsigned int ival = ++p.invariant_values[dest_vertex]; if(ival > neighbour_cell->max_ival) { neighbour_cell->max_ival = ival; neighbour_cell->max_ival_count = 1; if(ival == 1) { neighbour_heap.insert(neighbour_cell->first); } } else if(ival == neighbour_cell->max_ival) { neighbour_cell->max_ival_count++; } } } while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell * const neighbour_cell = p.get_cell(p.elements[start]); if(compute_eqref_hash) { eqref_hash.update(neighbour_cell->first); eqref_hash.update(neighbour_cell->length); eqref_hash.update(neighbour_cell->max_ival); eqref_hash.update(neighbour_cell->max_ival_count); } Partition::Cell* const last_new_cell = p.zplit_cell(neighbour_cell, true); /* Update certificate and hash if needed */ const Partition::Cell* c = neighbour_cell; while(1) { if(in_search) { /* Build certificate */ cert_add_redundant(CERT_SPLIT, c->first, c->length); /* No need to continue? */ if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) goto worse_exit; } if(compute_eqref_hash) { eqref_hash.update(c->first); eqref_hash.update(c->length); } if(c == last_new_cell) break; c = c->next; } } if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) return true; return false; worse_exit: /* Clear neighbour heap */ UintSeqHash rest; while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell * const neighbour_cell = p.get_cell(p.elements[start]); if(opt_use_failure_recording and was_equal_to_first) { rest.update(neighbour_cell->first); rest.update(neighbour_cell->length); rest.update(neighbour_cell->max_ival); rest.update(neighbour_cell->max_ival_count); } neighbour_cell->max_ival = 0; neighbour_cell->max_ival_count = 0; p.clear_ivs(neighbour_cell); } if(opt_use_failure_recording and was_equal_to_first) { for(unsigned int i = p.splitting_queue.size(); i > 0; i--) { Partition::Cell* const cell = p.splitting_queue.pop_front(); rest.update(cell->first); rest.update(cell->length); p.splitting_queue.push_back(cell); } rest.update(failure_recording_fp_deviation); failure_recording_fp_deviation = rest.get_value(); } return true; } bool Graph::split_neighbourhood_of_unit_cell(Partition::Cell* const unit_cell) { const bool was_equal_to_first = refine_equal_to_first; if(compute_eqref_hash) { eqref_hash.update(0x87654321); eqref_hash.update(unit_cell->first); eqref_hash.update(1); } const Vertex& v = vertices[p.elements[unit_cell->first]]; std::vector::const_iterator ei = v.edges.begin(); for(unsigned int j = v.nof_edges(); j > 0; j--) { const unsigned int dest_vertex = *ei++; Partition::Cell * const neighbour_cell = p.get_cell(dest_vertex); if(neighbour_cell->is_unit()) { if(in_search) { /* Remember neighbour in order to generate certificate */ neighbour_heap.insert(neighbour_cell->first); } continue; } if(neighbour_cell->max_ival_count == 0) { neighbour_heap.insert(neighbour_cell->first); } neighbour_cell->max_ival_count++; unsigned int * const swap_position = p.elements + neighbour_cell->first + neighbour_cell->length - neighbour_cell->max_ival_count; *p.in_pos[dest_vertex] = *swap_position; p.in_pos[*swap_position] = p.in_pos[dest_vertex]; *swap_position = dest_vertex; p.in_pos[dest_vertex] = swap_position; } while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* neighbour_cell = p.get_cell(p.elements[start]); #if defined(BLISS_CONSISTENCY_CHECKS) if(neighbour_cell->is_unit()) { } else { } #endif if(compute_eqref_hash) { eqref_hash.update(neighbour_cell->first); eqref_hash.update(neighbour_cell->length); eqref_hash.update(neighbour_cell->max_ival_count); } if(neighbour_cell->length > 1 and neighbour_cell->max_ival_count != neighbour_cell->length) { Partition::Cell * const new_cell = p.aux_split_in_two(neighbour_cell, neighbour_cell->length - neighbour_cell->max_ival_count); unsigned int *ep = p.elements + new_cell->first; unsigned int * const lp = p.elements+new_cell->first+new_cell->length; while(ep < lp) { p.element_to_cell_map[*ep] = new_cell; ep++; } neighbour_cell->max_ival_count = 0; if(compute_eqref_hash) { /* Update hash */ eqref_hash.update(neighbour_cell->first); eqref_hash.update(neighbour_cell->length); eqref_hash.update(0); eqref_hash.update(new_cell->first); eqref_hash.update(new_cell->length); eqref_hash.update(1); } /* Add cells in splitting_queue */ if(neighbour_cell->is_in_splitting_queue()) { /* Both cells must be included in splitting_queue in order to ensure refinement into equitable partition */ p.splitting_queue_add(new_cell); } else { Partition::Cell *min_cell, *max_cell; if(neighbour_cell->length <= new_cell->length) { min_cell = neighbour_cell; max_cell = new_cell; } else { min_cell = new_cell; max_cell = neighbour_cell; } /* Put the smaller cell in splitting_queue */ p.splitting_queue_add(min_cell); if(max_cell->is_unit()) { /* Put the "larger" cell also in splitting_queue */ p.splitting_queue_add(max_cell); } } /* Update pointer for certificate generation */ neighbour_cell = new_cell; } else { /* neighbour_cell->length == 1 || neighbour_cell->max_ival_count == neighbour_cell->length */ neighbour_cell->max_ival_count = 0; } /* * Build certificate if required */ if(in_search) { for(unsigned int i = neighbour_cell->first, j = neighbour_cell->length; j > 0; j--, i++) { /* Build certificate */ cert_add(CERT_EDGE, unit_cell->first, i); /* No need to continue? */ if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) goto worse_exit; } } /* if(in_search) */ } /* while(!neighbour_heap.is_empty()) */ if(refine_compare_certificate and (refine_equal_to_first == false) and (refine_cmp_to_best < 0)) return true; return false; worse_exit: /* Clear neighbour heap */ UintSeqHash rest; while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell * const neighbour_cell = p.get_cell(p.elements[start]); if(opt_use_failure_recording and was_equal_to_first) { rest.update(neighbour_cell->first); rest.update(neighbour_cell->length); rest.update(neighbour_cell->max_ival_count); } neighbour_cell->max_ival_count = 0; } if(opt_use_failure_recording and was_equal_to_first) { rest.update(failure_recording_fp_deviation); failure_recording_fp_deviation = rest.get_value(); } return true; } /*------------------------------------------------------------------------- * * Check whether the current partition p is equitable. * Performance: very slow, use only for debugging purposes. * *-------------------------------------------------------------------------*/ bool Graph::is_equitable() const { const unsigned int N = get_nof_vertices(); if(N == 0) return true; std::vector first_count = std::vector(N, 0); std::vector other_count = std::vector(N, 0); for(Partition::Cell *cell = p.first_cell; cell; cell = cell->next) { if(cell->is_unit()) continue; unsigned int *ep = p.elements + cell->first; const Vertex &first_vertex = vertices[*ep++]; /* Count how many edges lead from the first vertex to * the neighbouring cells */ for(std::vector::const_iterator ei = first_vertex.edges.begin(); ei != first_vertex.edges.end(); ei++) { first_count[p.get_cell(*ei)->first]++; } /* Count and compare to the edges of the other vertices */ for(unsigned int i = cell->length; i > 1; i--) { const Vertex &vertex = vertices[*ep++]; for(std::vector::const_iterator ei = vertex.edges.begin(); ei != vertex.edges.end(); ei++) { other_count[p.get_cell(*ei)->first]++; } for(Partition::Cell *cell2 = p.first_cell; cell2; cell2 = cell2->next) { if(first_count[cell2->first] != other_count[cell2->first]) { /* Not equitable */ return false; } other_count[cell2->first] = 0; } } /* Reset first_count */ for(unsigned int i = 0; i < N; i++) first_count[i] = 0; } return true; } /*------------------------------------------------------------------------- * * Build the initial equitable partition * *-------------------------------------------------------------------------*/ void Graph::make_initial_equitable_partition() { refine_according_to_invariant(&vertex_color_invariant); p.splitting_queue_clear(); //p.print_signature(stderr); fprintf(stderr, "\n"); refine_according_to_invariant(&selfloop_invariant); p.splitting_queue_clear(); //p.print_signature(stderr); fprintf(stderr, "\n"); refine_according_to_invariant(°ree_invariant); p.splitting_queue_clear(); //p.print_signature(stderr); fprintf(stderr, "\n"); refine_to_equitable(); //p.print_signature(stderr); fprintf(stderr, "\n"); } /*------------------------------------------------------------------------- * * Find the next cell to be splitted * *-------------------------------------------------------------------------*/ Partition::Cell* Graph::find_next_cell_to_be_splitted(Partition::Cell* cell) { switch(sh) { case shs_f: return sh_first(); case shs_fs: return sh_first_smallest(); case shs_fl: return sh_first_largest(); case shs_fm: return sh_first_max_neighbours(); case shs_fsm: return sh_first_smallest_max_neighbours(); case shs_flm: return sh_first_largest_max_neighbours(); default: fatal_error("Internal error - unknown splitting heuristics"); return 0; } } /** \internal * A splitting heuristic. * Returns the first nonsingleton cell in the current partition. */ Partition::Cell* Graph::sh_first() { Partition::Cell* best_cell = 0; for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; best_cell = cell; break; } return best_cell; } /** \internal * A splitting heuristic. * Returns the first smallest nonsingleton cell in the current partition. */ Partition::Cell* Graph::sh_first_smallest() { Partition::Cell* best_cell = 0; unsigned int best_size = UINT_MAX; for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; if(cell->length < best_size) { best_size = cell->length; best_cell = cell; } } return best_cell; } /** \internal * A splitting heuristic. * Returns the first largest nonsingleton cell in the current partition. */ Partition::Cell* Graph::sh_first_largest() { Partition::Cell* best_cell = 0; unsigned int best_size = 0; for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; if(cell->length > best_size) { best_size = cell->length; best_cell = cell; } } return best_cell; } /** \internal * A splitting heuristic. * Returns the first nonsingleton cell with max number of neighbouring * nonsingleton cells. * Assumes that the partition p is equitable. * Assumes that the max_ival fields of the cells are all 0. */ Partition::Cell* Graph::sh_first_max_neighbours() { Partition::Cell* best_cell = 0; int best_value = -1; KStack neighbour_cells_visited; neighbour_cells_visited.init(get_nof_vertices()); for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; const Vertex& v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei = v.edges.begin(); for(unsigned int j = v.nof_edges(); j > 0; j--) { Partition::Cell * const neighbour_cell = p.get_cell(*ei++); if(neighbour_cell->is_unit()) continue; neighbour_cell->max_ival++; if(neighbour_cell->max_ival == 1) neighbour_cells_visited.push(neighbour_cell); } int value = 0; while(!neighbour_cells_visited.is_empty()) { Partition::Cell* const neighbour_cell = neighbour_cells_visited.pop(); if(neighbour_cell->max_ival != neighbour_cell->length) value++; neighbour_cell->max_ival = 0; } if(value > best_value) { best_value = value; best_cell = cell; } } return best_cell; } /** \internal * A splitting heuristic. * Returns the first smallest nonsingleton cell with max number of neighbouring * nonsingleton cells. * Assumes that the partition p is equitable. * Assumes that the max_ival fields of the cells are all 0. */ Partition::Cell* Graph::sh_first_smallest_max_neighbours() { Partition::Cell* best_cell = 0; int best_value = -1; unsigned int best_size = UINT_MAX; KStack neighbour_cells_visited; neighbour_cells_visited.init(get_nof_vertices()); for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; const Vertex& v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei = v.edges.begin(); for(unsigned int j = v.nof_edges(); j > 0; j--) { Partition::Cell* const neighbour_cell = p.get_cell(*ei++); if(neighbour_cell->is_unit()) continue; neighbour_cell->max_ival++; if(neighbour_cell->max_ival == 1) neighbour_cells_visited.push(neighbour_cell); } int value = 0; while(!neighbour_cells_visited.is_empty()) { Partition::Cell* const neighbour_cell = neighbour_cells_visited.pop(); if(neighbour_cell->max_ival != neighbour_cell->length) value++; neighbour_cell->max_ival = 0; } if((value > best_value) or (value == best_value and cell->length < best_size)) { best_value = value; best_size = cell->length; best_cell = cell; } } return best_cell; } /** \internal * A splitting heuristic. * Returns the first largest nonsingleton cell with max number of neighbouring * nonsingleton cells. * Assumes that the partition p is equitable. * Assumes that the max_ival fields of the cells are all 0. */ Partition::Cell* Graph::sh_first_largest_max_neighbours() { Partition::Cell* best_cell = 0; int best_value = -1; unsigned int best_size = 0; KStack neighbour_cells_visited; neighbour_cells_visited.init(get_nof_vertices()); for(Partition::Cell* cell = p.first_nonsingleton_cell; cell; cell = cell->next_nonsingleton) { if(opt_use_comprec and p.cr_get_level(cell->first) != cr_level) continue; const Vertex& v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei = v.edges.begin(); for(unsigned int j = v.nof_edges(); j > 0; j--) { Partition::Cell* const neighbour_cell = p.get_cell(*ei++); if(neighbour_cell->is_unit()) continue; neighbour_cell->max_ival++; if(neighbour_cell->max_ival == 1) neighbour_cells_visited.push(neighbour_cell); } int value = 0; while(!neighbour_cells_visited.is_empty()) { Partition::Cell* const neighbour_cell = neighbour_cells_visited.pop(); if(neighbour_cell->max_ival != neighbour_cell->length) value++; neighbour_cell->max_ival = 0; } if((value > best_value) or (value == best_value and cell->length > best_size)) { best_value = value; best_size = cell->length; best_cell = cell; } } return best_cell; } /*------------------------------------------------------------------------- * * Initialize the certificate size and memory * *-------------------------------------------------------------------------*/ void Graph::initialize_certificate() { certificate_index = 0; certificate_current_path.clear(); certificate_first_path.clear(); certificate_best_path.clear(); } /*------------------------------------------------------------------------- * * Check whether perm is an automorphism. * Slow, mainly for debugging and validation purposes. * *-------------------------------------------------------------------------*/ bool Graph::is_automorphism(unsigned int* const perm) const { std::set > edges1; std::set > edges2; #if defined(BLISS_CONSISTENCY_CHECKS) if(!is_permutation(get_nof_vertices(), perm)) _INTERNAL_ERROR(); #endif for(unsigned int i = 0; i < get_nof_vertices(); i++) { const Vertex& v1 = vertices[i]; edges1.clear(); for(std::vector::const_iterator ei = v1.edges.cbegin(); ei != v1.edges.cend(); ei++) edges1.insert(perm[*ei]); const Vertex& v2 = vertices[perm[i]]; edges2.clear(); for(std::vector::const_iterator ei = v2.edges.cbegin(); ei != v2.edges.cend(); ei++) edges2.insert(*ei); if(!(edges1 == edges2)) return false; } return true; } bool Graph::is_automorphism(const std::vector& perm) const { if(!(perm.size() == get_nof_vertices() and is_permutation(perm))) return false; std::set > edges1; std::set > edges2; for(unsigned int i = 0; i < get_nof_vertices(); i++) { const Vertex& v1 = vertices[i]; edges1.clear(); for(std::vector::const_iterator ei = v1.edges.begin(); ei != v1.edges.end(); ei++) edges1.insert(perm[*ei]); const Vertex& v2 = vertices[perm[i]]; edges2.clear(); for(std::vector::const_iterator ei = v2.edges.begin(); ei != v2.edges.end(); ei++) edges2.insert(*ei); if(!(edges1 == edges2)) return false; } return true; } bool Graph::nucr_find_first_component(const unsigned int level) { cr_component.clear(); cr_component_elements = 0; /* Find first non-discrete cell in the component level */ Partition::Cell* first_cell = p.first_nonsingleton_cell; while(first_cell) { if(p.cr_get_level(first_cell->first) == level) break; first_cell = first_cell->next_nonsingleton; } /* The component is discrete, return false */ if(!first_cell) return false; std::vector component; first_cell->max_ival = 1; component.push_back(first_cell); for(unsigned int i = 0; i < component.size(); i++) { Partition::Cell* const cell = component[i]; const Vertex& v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei = v.edges.begin(); for(unsigned int j = v.nof_edges(); j > 0; j--) { const unsigned int neighbour = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(neighbour); /* Skip unit neighbours */ if(neighbour_cell->is_unit()) continue; /* Already marked to be in the same component? */ if(neighbour_cell->max_ival == 1) continue; /* Is the neighbour at the same component recursion level? */ if(p.cr_get_level(neighbour_cell->first) != level) continue; if(neighbour_cell->max_ival_count == 0) neighbour_heap.insert(neighbour_cell->first); neighbour_cell->max_ival_count++; } while(!neighbour_heap.is_empty()) { const unsigned int start = neighbour_heap.remove(); Partition::Cell* const neighbour_cell = p.get_cell(p.elements[start]); /* Skip saturated neighbour cells */ if(neighbour_cell->max_ival_count == neighbour_cell->length) { neighbour_cell->max_ival_count = 0; continue; } neighbour_cell->max_ival_count = 0; neighbour_cell->max_ival = 1; component.push_back(neighbour_cell); } } for(unsigned int i = 0; i < component.size(); i++) { Partition::Cell* const cell = component[i]; cell->max_ival = 0; cr_component.push_back(cell->first); cr_component_elements += cell->length; } /* if(verbstr and verbose_level > 2) { fprintf(verbstr, "NU-component with %lu cells and %u vertices\n", (long unsigned)cr_component.size(), cr_component_elements); fflush(verbstr); } */ return true; } bool Graph::nucr_find_first_component(const unsigned int level, std::vector& component, unsigned int& component_elements, Partition::Cell*& sh_return) { component.clear(); component_elements = 0; sh_return = 0; unsigned int sh_first = 0; unsigned int sh_size = 0; unsigned int sh_nuconn = 0; /* Find first non-discrete cell in the component level */ Partition::Cell* first_cell = p.first_nonsingleton_cell; while(first_cell) { if(p.cr_get_level(first_cell->first) == level) break; first_cell = first_cell->next_nonsingleton; } if(!first_cell) { /* The component is discrete, return false */ return false; } std::vector comp; KStack neighbours; neighbours.init(get_nof_vertices()); first_cell->max_ival = 1; comp.push_back(first_cell); for(unsigned int i = 0; i < comp.size(); i++) { Partition::Cell* const cell = comp[i]; const Vertex& v = vertices[p.elements[cell->first]]; std::vector::const_iterator ei = v.edges.begin(); for(unsigned int j = v.nof_edges(); j > 0; j--) { const unsigned int neighbour = *ei++; Partition::Cell* const neighbour_cell = p.get_cell(neighbour); /* Skip unit neighbours */ if(neighbour_cell->is_unit()) continue; /* Is the neighbour at the same component recursion level? */ //if(p.cr_get_level(neighbour_cell->first) != level) // continue; if(neighbour_cell->max_ival_count == 0) neighbours.push(neighbour_cell); neighbour_cell->max_ival_count++; } unsigned int nuconn = 1; while(!neighbours.is_empty()) { Partition::Cell* const neighbour_cell = neighbours.pop(); //neighbours.pop_back(); /* Skip saturated neighbour cells */ if(neighbour_cell->max_ival_count == neighbour_cell->length) { neighbour_cell->max_ival_count = 0; continue; } nuconn++; neighbour_cell->max_ival_count = 0; if(neighbour_cell->max_ival == 0) { comp.push_back(neighbour_cell); neighbour_cell->max_ival = 1; } } switch(sh) { case shs_f: if(sh_return == 0 or cell->first <= sh_first) { sh_return = cell; sh_first = cell->first; } break; case shs_fs: if(sh_return == 0 or cell->length < sh_size or (cell->length == sh_size and cell->first <= sh_first)) { sh_return = cell; sh_first = cell->first; sh_size = cell->length; } break; case shs_fl: if(sh_return == 0 or cell->length > sh_size or (cell->length == sh_size and cell->first <= sh_first)) { sh_return = cell; sh_first = cell->first; sh_size = cell->length; } break; case shs_fm: if(sh_return == 0 or nuconn > sh_nuconn or (nuconn == sh_nuconn and cell->first <= sh_first)) { sh_return = cell; sh_first = cell->first; sh_nuconn = nuconn; } break; case shs_fsm: if(sh_return == 0 or nuconn > sh_nuconn or (nuconn == sh_nuconn and (cell->length < sh_size or (cell->length == sh_size and cell->first <= sh_first)))) { sh_return = cell; sh_first = cell->first; sh_size = cell->length; sh_nuconn = nuconn; } break; case shs_flm: if(sh_return == 0 or nuconn > sh_nuconn or (nuconn == sh_nuconn and (cell->length > sh_size or (cell->length == sh_size and cell->first <= sh_first)))) { sh_return = cell; sh_first = cell->first; sh_size = cell->length; sh_nuconn = nuconn; } break; default: fatal_error("Internal error - unknown splitting heuristics"); return 0; } } assert(sh_return); for(unsigned int i = 0; i < comp.size(); i++) { Partition::Cell* const cell = comp[i]; cell->max_ival = 0; component.push_back(cell->first); component_elements += cell->length; } /* if(verbstr and verbose_level > 2) { fprintf(verbstr, "NU-component with %lu cells and %u vertices\n", (long unsigned)component.size(), component_elements); fflush(verbstr); } */ return true; } } leidenbase/src/core/isomorphism/bliss/utils.hh0000644000176200001440000000242114447675374021256 0ustar liggesusers#ifndef BLISS_UTILS_HH #define BLISS_UTILS_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ /** * \file * \brief Some small utilities. */ #include namespace bliss { /** * Check whether \a perm is a valid permutation on {0,...,N-1}. * Slow, mainly for debugging and validation purposes. */ bool is_permutation(const unsigned int N, const unsigned int* perm); /** * Check whether \a perm is a valid permutation on {0,...,N-1}. * Slow, mainly for debugging and validation purposes. */ bool is_permutation(const std::vector& perm); } // namespace bliss #endif // BLISS_UTILS_HH leidenbase/src/core/isomorphism/bliss/stats.hh0000644000176200001440000000601314447675374021255 0ustar liggesusers#ifndef BLISS_STATS_HH #define BLISS_STATS_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ #include "graph.hh" #include "bignum.hh" namespace bliss { /** * \brief Statistics returned by the bliss search algorithm. */ class Stats { friend class AbstractGraph; /** \internal The size of the automorphism group. */ BigNum group_size; /** \internal An approximation (due to possible overflows) of * the size of the automorphism group. */ long double group_size_approx; /** \internal The number of nodes in the search tree. */ long unsigned int nof_nodes; /** \internal The number of leaf nodes in the search tree. */ long unsigned int nof_leaf_nodes; /** \internal The number of bad nodes in the search tree. */ long unsigned int nof_bad_nodes; /** \internal The number of canonical representative updates. */ long unsigned int nof_canupdates; /** \internal The number of generator permutations. */ long unsigned int nof_generators; /** \internal The maximal depth of the search tree. */ unsigned long int max_level; /** \internal Reset the statistics. */ void reset() { group_size.assign(1); group_size_approx = 1.0; nof_nodes = 0; nof_leaf_nodes = 0; nof_bad_nodes = 0; nof_canupdates = 0; nof_generators = 0; max_level = 0; } public: Stats() { reset(); } /** The size of the automorphism group. */ const BigNum& get_group_size() const {return group_size;} /** An approximation (due to possible overflows/rounding errors) of * the size of the automorphism group. */ long double get_group_size_approx() const {return group_size_approx;} /** The number of nodes in the search tree. */ long unsigned int get_nof_nodes() const {return nof_nodes;} /** The number of leaf nodes in the search tree. */ long unsigned int get_nof_leaf_nodes() const {return nof_leaf_nodes;} /** The number of bad nodes in the search tree. */ long unsigned int get_nof_bad_nodes() const {return nof_bad_nodes;} /** The number of canonical representative updates. */ long unsigned int get_nof_canupdates() const {return nof_canupdates;} /** The number of generator permutations. */ long unsigned int get_nof_generators() const {return nof_generators;} /** The maximal depth of the search tree. */ unsigned long int get_max_level() const {return max_level;} }; } // namespace bliss #endif // BLISS_STATS_HH leidenbase/src/core/isomorphism/bliss/heap.cc0000644000176200001440000000431014447675374021020 0ustar liggesusers#include "heap.hh" #include #include /* Allow using 'and' instead of '&&' with MSVC */ #if _MSC_VER #include #endif /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { Heap::Heap() { array = nullptr; n = 0; N = 0; } Heap::~Heap() { delete[] array; array = nullptr; n = 0; N = 0; } void Heap::upheap(unsigned int index) { assert(n >= 1); assert(index >= 1 and index <= n); const unsigned int v = array[index]; array[0] = 0; while(array[index/2] > v) { array[index] = array[index/2]; index = index/2; } array[index] = v; } void Heap::downheap(unsigned int index) { const unsigned int v = array[index]; const unsigned int lim = n/2; while(index <= lim) { unsigned int new_index = index + index; if((new_index < n) and (array[new_index] > array[new_index+1])) new_index++; if(v <= array[new_index]) break; array[index] = array[new_index]; index = new_index; } array[index] = v; } void Heap::init(const unsigned int size) { assert(size > 0); if(size > N) { delete[] array; array = new unsigned int[size + 1]; N = size; } n = 0; } void Heap::insert(const unsigned int v) { assert(n < N); array[++n] = v; upheap(n); } unsigned int Heap::smallest() const { assert(n >= 1 and n <= N); return array[1]; } unsigned int Heap::remove() { assert(n >= 1 and n <= N); const unsigned int v = array[1]; array[1] = array[n--]; downheap(1); return v; } } // namespace bliss leidenbase/src/core/isomorphism/bliss/uintseqhash.cc0000644000176200001440000001052714447675374022446 0ustar liggesusers#include "uintseqhash.hh" /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { /* * Random bits generated by * http://www.fourmilab.ch/hotbits/ */ static unsigned int rtab[256] = { 0xAEAA35B8, 0x65632E16, 0x155EDBA9, 0x01349B39, 0x8EB8BD97, 0x8E4C5367, 0x8EA78B35, 0x2B1B4072, 0xC1163893, 0x269A8642, 0xC79D7F6D, 0x6A32DEA0, 0xD4D2DA56, 0xD96D4F47, 0x47B5F48A, 0x2587C6BF, 0x642B71D8, 0x5DBBAF58, 0x5C178169, 0xA16D9279, 0x75CDA063, 0x291BC48B, 0x01AC2F47, 0x5416DF7C, 0x45307514, 0xB3E1317B, 0xE1C7A8DE, 0x3ACDAC96, 0x11B96831, 0x32DE22DD, 0x6A1DA93B, 0x58B62381, 0x283810E2, 0xBC30E6A6, 0x8EE51705, 0xB06E8DFB, 0x729AB12A, 0xA9634922, 0x1A6E8525, 0x49DD4E19, 0xE5DB3D44, 0x8C5B3A02, 0xEBDE2864, 0xA9146D9F, 0x736D2CB4, 0xF5229F42, 0x712BA846, 0x20631593, 0x89C02603, 0xD5A5BF6A, 0x823F4E18, 0x5BE5DEFF, 0x1C4EBBFA, 0x5FAB8490, 0x6E559B0C, 0x1FE528D6, 0xB3198066, 0x4A965EB5, 0xFE8BB3D5, 0x4D2F6234, 0x5F125AA4, 0xBCC640FA, 0x4F8BC191, 0xA447E537, 0xAC474D3C, 0x703BFA2C, 0x617DC0E7, 0xF26299D7, 0xC90FD835, 0x33B71C7B, 0x6D83E138, 0xCBB1BB14, 0x029CF5FF, 0x7CBD093D, 0x4C9825EF, 0x845C4D6D, 0x124349A5, 0x53942D21, 0x800E60DA, 0x2BA6EB7F, 0xCEBF30D3, 0xEB18D449, 0xE281F724, 0x58B1CB09, 0xD469A13D, 0x9C7495C3, 0xE53A7810, 0xA866C08E, 0x832A038B, 0xDDDCA484, 0xD5FE0DDE, 0x0756002B, 0x2FF51342, 0x60FEC9C8, 0x061A53E3, 0x47B1884E, 0xDC17E461, 0xA17A6A37, 0x3158E7E2, 0xA40D873B, 0x45AE2140, 0xC8F36149, 0x63A4EE2D, 0xD7107447, 0x6F90994F, 0x5006770F, 0xC1F3CA9A, 0x91B317B2, 0xF61B4406, 0xA8C9EE8F, 0xC6939B75, 0xB28BBC3B, 0x36BF4AEF, 0x3B12118D, 0x4D536ECF, 0x9CF4B46B, 0xE8AB1E03, 0x8225A360, 0x7AE4A130, 0xC4EE8B50, 0x50651797, 0x5BB4C59F, 0xD120EE47, 0x24F3A386, 0xBE579B45, 0x3A378EFC, 0xC5AB007B, 0x3668942B, 0x2DBDCC3A, 0x6F37F64C, 0xC24F862A, 0xB6F97FCF, 0x9E4FA23D, 0x551AE769, 0x46A8A5A6, 0xDC1BCFDD, 0x8F684CF9, 0x501D811B, 0x84279F80, 0x2614E0AC, 0x86445276, 0xAEA0CE71, 0x0812250F, 0xB586D18A, 0xC68D721B, 0x44514E1D, 0x37CDB99A, 0x24731F89, 0xFA72E589, 0x81E6EBA2, 0x15452965, 0x55523D9D, 0x2DC47E14, 0x2E7FA107, 0xA7790F23, 0x40EBFDBB, 0x77E7906B, 0x6C1DB960, 0x1A8B9898, 0x65FA0D90, 0xED28B4D8, 0x34C3ED75, 0x768FD2EC, 0xFAB60BCB, 0x962C75F4, 0x304F0498, 0x0A41A36B, 0xF7DE2A4A, 0xF4770FE2, 0x73C93BBB, 0xD21C82C5, 0x6C387447, 0x8CDB4CB9, 0x2CC243E8, 0x41859E3D, 0xB667B9CB, 0x89681E8A, 0x61A0526C, 0x883EDDDC, 0x539DE9A4, 0xC29E1DEC, 0x97C71EC5, 0x4A560A66, 0xBD7ECACF, 0x576AE998, 0x31CE5616, 0x97172A6C, 0x83D047C4, 0x274EA9A8, 0xEB31A9DA, 0x327209B5, 0x14D1F2CB, 0x00FE1D96, 0x817DBE08, 0xD3E55AED, 0xF2D30AFC, 0xFB072660, 0x866687D6, 0x92552EB9, 0xEA8219CD, 0xF7927269, 0xF1948483, 0x694C1DF5, 0xB7D8B7BF, 0xFFBC5D2F, 0x2E88B849, 0x883FD32B, 0xA0331192, 0x8CB244DF, 0x41FAF895, 0x16902220, 0x97FB512A, 0x2BEA3CC4, 0xAF9CAE61, 0x41ACD0D5, 0xFD2F28FF, 0xE780ADFA, 0xB3A3A76E, 0x7112AD87, 0x7C3D6058, 0x69E64FFF, 0xE5F8617C, 0x8580727C, 0x41F54F04, 0xD72BE498, 0x653D1795, 0x1275A327, 0x14B499D4, 0x4E34D553, 0x4687AA39, 0x68B64292, 0x5C18ABC3, 0x41EABFCC, 0x92A85616, 0x82684CF8, 0x5B9F8A4E, 0x35382FFE, 0xFB936318, 0x52C08E15, 0x80918B2E, 0x199EDEE0, 0xA9470163, 0xEC44ACDD, 0x612D6735, 0x8F88EA7D, 0x759F5EA4, 0xE5CC7240, 0x68CFEB8B, 0x04725601, 0x0C22C23E, 0x5BC97174, 0x89965841, 0x5D939479, 0x690F338A, 0x3C2D4380, 0xDAE97F2B }; void UintSeqHash::update(unsigned int i) { i++; while(i > 0) { h ^= rtab[i & 0xff]; #if 1 const unsigned int b = (h & 0x80000000) >> 31; i = i >> 8; h = (h << 1) | b; #else const unsigned int b = h & 0x80000000; h = h << 1; if(b != 0) h++; i = i >> 8; #endif } } } // namespace bliss leidenbase/src/core/isomorphism/bliss/partition.cc0000644000176200001440000007222314447675374022124 0ustar liggesusers#include #include #include "graph.hh" #include "partition.hh" #include "igraph_decls.h" /* Allow using 'and' instead of '&&' with MSVC */ #if _MSC_VER #include #endif /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { Partition::Partition() { N = 0; elements = 0; in_pos = 0; invariant_values = 0; cells = 0; free_cells = 0; element_to_cell_map = 0; graph = 0; discrete_cell_count = 0; /* Initialize a distribution count sorting array. */ for(unsigned int i = 0; i < 256; i++) dcs_count[i] = 0; cr_enabled = false; cr_cells = 0; cr_levels = 0; } Partition::~Partition() { delete[] elements; elements = nullptr; delete[] cells; cells = nullptr; delete[] element_to_cell_map; element_to_cell_map = nullptr; delete[] in_pos; in_pos = nullptr; delete[] invariant_values; invariant_values = nullptr; N = 0; } void Partition::init(const unsigned int M) { assert(M > 0); N = M; delete[] elements; elements = new unsigned int[N]; for(unsigned int i = 0; i < N; i++) elements[i] = i; delete[] in_pos; in_pos = new unsigned int*[N]; for(unsigned int i = 0; i < N; i++) in_pos[i] = elements + i; delete[] invariant_values; invariant_values = new unsigned int[N]; for(unsigned int i = 0; i < N; i++) invariant_values[i] = 0; delete[] cells; cells = new Cell[N]; cells[0].first = 0; cells[0].length = N; cells[0].max_ival = 0; cells[0].max_ival_count = 0; cells[0].in_splitting_queue = false; cells[0].in_neighbour_heap = false; cells[0].prev = 0; cells[0].next = 0; cells[0].next_nonsingleton = 0; cells[0].prev_nonsingleton = 0; cells[0].split_level = 0; first_cell = &cells[0]; if(N == 1) { first_nonsingleton_cell = 0; discrete_cell_count = 1; } else { first_nonsingleton_cell = &cells[0]; discrete_cell_count = 0; } for(unsigned int i = 1; i < N; i++) { cells[i].first = 0; cells[i].length = 0; cells[i].max_ival = 0; cells[i].max_ival_count = 0; cells[i].in_splitting_queue = false; cells[i].in_neighbour_heap = false; cells[i].prev = 0; cells[i].next = (i < N-1)?&cells[i+1]:0; cells[i].next_nonsingleton = 0; cells[i].prev_nonsingleton = 0; } if(N > 1) free_cells = &cells[1]; else free_cells = 0; delete[] element_to_cell_map; element_to_cell_map = new Cell*[N]; for(unsigned int i = 0; i < N; i++) element_to_cell_map[i] = first_cell; splitting_queue.init(N); refinement_stack.init(N); /* Reset the main backtracking stack */ bt_stack.clear(); } Partition::BacktrackPoint Partition::set_backtrack_point() { BacktrackInfo info; info.refinement_stack_size = refinement_stack.size(); if(cr_enabled) info.cr_backtrack_point = cr_get_backtrack_point(); BacktrackPoint p = bt_stack.size(); bt_stack.push_back(info); return p; } void Partition::goto_backtrack_point(BacktrackPoint p) { assert(p < bt_stack.size()); BacktrackInfo info = bt_stack[p]; bt_stack.resize(p); if(cr_enabled) cr_goto_backtrack_point(info.cr_backtrack_point); const unsigned int dest_refinement_stack_size = info.refinement_stack_size; assert(refinement_stack.size() >= dest_refinement_stack_size); while(refinement_stack.size() > dest_refinement_stack_size) { RefInfo i = refinement_stack.pop(); const unsigned int first = i.split_cell_first; Cell* cell = get_cell(elements[first]); if(cell->first != first) { assert(cell->first < first); assert(cell->split_level <= dest_refinement_stack_size); goto done; } assert(cell->split_level > dest_refinement_stack_size); while(cell->split_level > dest_refinement_stack_size) { assert(cell->prev); cell = cell->prev; } while(cell->next and cell->next->split_level > dest_refinement_stack_size) { /* Merge next cell */ Cell* const next_cell = cell->next; if(cell->length == 1) discrete_cell_count--; if(next_cell->length == 1) discrete_cell_count--; /* Update element_to_cell_map values of elements added in cell */ unsigned int* ep = elements + next_cell->first; unsigned int* const lp = ep + next_cell->length; for( ; ep < lp; ep++) element_to_cell_map[*ep] = cell; /* Update cell parameters */ cell->length += next_cell->length; if(next_cell->next) next_cell->next->prev = cell; cell->next = next_cell->next; /* (Pseudo)free next_cell */ next_cell->first = 0; next_cell->length = 0; next_cell->prev = 0; next_cell->next = free_cells; free_cells = next_cell; } done: if(i.prev_nonsingleton_first >= 0) { Cell* const prev_cell = get_cell(elements[i.prev_nonsingleton_first]); assert(prev_cell->length > 1); cell->prev_nonsingleton = prev_cell; prev_cell->next_nonsingleton = cell; } else { //assert(cell->prev_nonsingleton == 0); cell->prev_nonsingleton = 0; first_nonsingleton_cell = cell; } if(i.next_nonsingleton_first >= 0) { Cell* const next_cell = get_cell(elements[i.next_nonsingleton_first]); assert(next_cell->length > 1); cell->next_nonsingleton = next_cell; next_cell->prev_nonsingleton = cell; } else { //assert(cell->next_nonsingleton == 0); cell->next_nonsingleton = 0; } } } Partition::Cell* Partition::individualize(Partition::Cell * const cell, const unsigned int element) { assert(!cell->is_unit()); unsigned int * const pos = in_pos[element]; assert((unsigned int)(pos - elements) >= cell->first); assert((unsigned int)(pos - elements) < cell->first + cell->length); assert(*pos == element); const unsigned int last = cell->first + cell->length - 1; *pos = elements[last]; in_pos[*pos] = pos; elements[last] = element; in_pos[element] = elements + last; Partition::Cell * const new_cell = aux_split_in_two(cell, cell->length-1); assert(elements[new_cell->first] == element); element_to_cell_map[element] = new_cell; return new_cell; } Partition::Cell* Partition::aux_split_in_two(Partition::Cell* const cell, const unsigned int first_half_size) { RefInfo i; assert(0 < first_half_size && first_half_size < cell->length); /* (Pseudo)allocate new cell */ Cell * const new_cell = free_cells; assert(new_cell != 0); free_cells = new_cell->next; /* Update new cell parameters */ new_cell->first = cell->first + first_half_size; new_cell->length = cell->length - first_half_size; new_cell->next = cell->next; if(new_cell->next) new_cell->next->prev = new_cell; new_cell->prev = cell; new_cell->split_level = refinement_stack.size()+1; /* Update old, splitted cell parameters */ cell->length = first_half_size; cell->next = new_cell; /* CR */ if(cr_enabled) cr_create_at_level_trailed(new_cell->first, cr_get_level(cell->first)); /* Add cell in refinement_stack for backtracking */ i.split_cell_first = new_cell->first; if(cell->prev_nonsingleton) i.prev_nonsingleton_first = cell->prev_nonsingleton->first; else i.prev_nonsingleton_first = -1; if(cell->next_nonsingleton) i.next_nonsingleton_first = cell->next_nonsingleton->first; else i.next_nonsingleton_first = -1; refinement_stack.push(i); /* Modify nonsingleton cell list */ if(new_cell->length > 1) { new_cell->prev_nonsingleton = cell; new_cell->next_nonsingleton = cell->next_nonsingleton; if(new_cell->next_nonsingleton) new_cell->next_nonsingleton->prev_nonsingleton = new_cell; cell->next_nonsingleton = new_cell; } else { new_cell->next_nonsingleton = 0; new_cell->prev_nonsingleton = 0; discrete_cell_count++; } if(cell->is_unit()) { if(cell->prev_nonsingleton) cell->prev_nonsingleton->next_nonsingleton = cell->next_nonsingleton; else first_nonsingleton_cell = cell->next_nonsingleton; if(cell->next_nonsingleton) cell->next_nonsingleton->prev_nonsingleton = cell->prev_nonsingleton; cell->next_nonsingleton = 0; cell->prev_nonsingleton = 0; discrete_cell_count++; } return new_cell; } void Partition::splitting_queue_add(Cell* const cell) { static const unsigned int smallish_cell_threshold = 1; assert(!cell->in_splitting_queue); cell->in_splitting_queue = true; if(cell->length <= smallish_cell_threshold) splitting_queue.push_front(cell); else splitting_queue.push_back(cell); } void Partition::splitting_queue_clear() { while(!splitting_queue_is_empty()) splitting_queue_pop(); } /* * Assumes that the invariant values are NOT the same * and that the cell contains more than one element */ Partition::Cell* Partition::sort_and_split_cell1(Partition::Cell* const cell) { #if defined(BLISS_EXPENSIVE_CONSISTENCY_CHECKS) assert(cell->length > 1); assert(cell->first + cell->length <= N); unsigned int nof_0_found = 0; unsigned int nof_1_found = 0; for(unsigned int i = cell->first; i < cell->first + cell->length; i++) { const unsigned int ival = invariant_values[elements[i]]; assert(ival == 0 or ival == 1); if(ival == 0) nof_0_found++; else nof_1_found++; } assert(nof_0_found > 0); assert(nof_1_found > 0); assert(nof_1_found == cell->max_ival_count); assert(nof_0_found + nof_1_found == cell->length); assert(cell->max_ival == 1); #endif /* (Pseudo)allocate new cell */ Cell* const new_cell = free_cells; assert(new_cell != 0); free_cells = new_cell->next; #define NEW_SORT1 #ifdef NEW_SORT1 unsigned int *ep0 = elements + cell->first; unsigned int *ep1 = ep0 + cell->length - cell->max_ival_count; if(cell->max_ival_count > cell->length / 2) { /* There are more ones than zeros, only move zeros */ unsigned int * const end = ep0 + cell->length; while(ep1 < end) { while(invariant_values[*ep1] == 0) { const unsigned int tmp = *ep1; *ep1 = *ep0; *ep0 = tmp; in_pos[tmp] = ep0; in_pos[*ep1] = ep1; ep0++; } element_to_cell_map[*ep1] = new_cell; invariant_values[*ep1] = 0; ep1++; } } else { /* There are more zeros than ones, only move ones */ unsigned int * const end = ep1; while(ep0 < end) { while(invariant_values[*ep0] != 0) { const unsigned int tmp = *ep0; *ep0 = *ep1; *ep1 = tmp; in_pos[tmp] = ep1; in_pos[*ep0] = ep0; ep1++; } ep0++; } ep1 = end; while(ep1 < elements + cell->first + cell->length) { element_to_cell_map[*ep1] = new_cell; invariant_values[*ep1] = 0; ep1++; } } /* Update new cell parameters */ new_cell->first = cell->first + cell->length - cell->max_ival_count; new_cell->length = cell->length - (new_cell->first - cell->first); new_cell->next = cell->next; if(new_cell->next) new_cell->next->prev = new_cell; new_cell->prev = cell; new_cell->split_level = refinement_stack.size()+1; /* Update old, splitted cell parameters */ cell->length = new_cell->first - cell->first; cell->next = new_cell; /* CR */ if(cr_enabled) cr_create_at_level_trailed(new_cell->first, cr_get_level(cell->first)); #else /* Sort vertices in the cell according to the invariant values */ unsigned int *ep0 = elements + cell->first; unsigned int *ep1 = ep0 + cell->length; while(ep1 > ep0) { const unsigned int element = *ep0; const unsigned int ival = invariant_values[element]; invariant_values[element] = 0; assert(ival <= 1); assert(element_to_cell_map[element] == cell); assert(in_pos[element] == ep0); if(ival == 0) { ep0++; } else { ep1--; *ep0 = *ep1; *ep1 = element; element_to_cell_map[element] = new_cell; in_pos[element] = ep1; in_pos[*ep0] = ep0; } } assert(ep1 != elements + cell->first); assert(ep0 != elements + cell->first + cell->length); /* Update new cell parameters */ new_cell->first = ep1 - elements; new_cell->length = cell->length - (new_cell->first - cell->first); new_cell->next = cell->next; if(new_cell->next) new_cell->next->prev = new_cell; new_cell->prev = cell; new_cell->split_level = cell->split_level; /* Update old, splitted cell parameters */ cell->length = new_cell->first - cell->first; cell->next = new_cell; cell->split_level = refinement_stack.size()+1; /* CR */ if(cr_enabled) cr_create_at_level_trailed(new_cell->first, cr_get_level(cell->first)); #endif /* ifdef NEW_SORT1*/ /* Add cell in refinement stack for backtracking */ { RefInfo i; i.split_cell_first = new_cell->first; if(cell->prev_nonsingleton) i.prev_nonsingleton_first = cell->prev_nonsingleton->first; else i.prev_nonsingleton_first = -1; if(cell->next_nonsingleton) i.next_nonsingleton_first = cell->next_nonsingleton->first; else i.next_nonsingleton_first = -1; /* Modify nonsingleton cell list */ if(new_cell->length > 1) { new_cell->prev_nonsingleton = cell; new_cell->next_nonsingleton = cell->next_nonsingleton; if(new_cell->next_nonsingleton) new_cell->next_nonsingleton->prev_nonsingleton = new_cell; cell->next_nonsingleton = new_cell; } else { new_cell->next_nonsingleton = 0; new_cell->prev_nonsingleton = 0; discrete_cell_count++; } if(cell->is_unit()) { if(cell->prev_nonsingleton) cell->prev_nonsingleton->next_nonsingleton = cell->next_nonsingleton; else first_nonsingleton_cell = cell->next_nonsingleton; if(cell->next_nonsingleton) cell->next_nonsingleton->prev_nonsingleton = cell->prev_nonsingleton; cell->next_nonsingleton = 0; cell->prev_nonsingleton = 0; discrete_cell_count++; } refinement_stack.push(i); } /* Add cells in splitting queue */ assert(!new_cell->in_splitting_queue); if(cell->in_splitting_queue) { /* Both cells must be included in splitting_queue in order to have refinement to equitable partition */ splitting_queue_add(new_cell); } else { Cell *min_cell, *max_cell; if(cell->length <= new_cell->length) { min_cell = cell; max_cell = new_cell; } else { min_cell = new_cell; max_cell = cell; } /* Put the smaller cell in splitting_queue */ splitting_queue_add(min_cell); if(max_cell->is_unit()) { /* Put the "larger" cell also in splitting_queue */ splitting_queue_add(max_cell); } } return new_cell; } /** * An auxiliary function for distribution count sorting. * Build start array so that * dcs_start[0] = 0 and dcs_start[i+1] = dcs_start[i] + dcs_count[i]. */ void Partition::dcs_cumulate_count(const unsigned int max) { assert(max <= 255); unsigned int* count_p = dcs_count; unsigned int* start_p = dcs_start; unsigned int sum = 0; for(unsigned int i = max+1; i > 0; i--) { *start_p = sum; start_p++; sum += *count_p; count_p++; } } /** * Distribution count sorting of cells with invariant values less than 256. */ Partition::Cell* Partition::sort_and_split_cell255(Partition::Cell* const cell, const unsigned int max_ival) { assert(max_ival <= 255); if(cell->is_unit()) { /* Reset invariant value */ invariant_values[elements[cell->first]] = 0; return cell; } #ifdef BLISS_CONSISTENCY_CHECKS for(unsigned int i = 0; i < 256; i++) assert(dcs_count[i] == 0); #endif /* * Compute the distribution of invariant values to the count array */ { const unsigned int *ep = elements + cell->first; assert(element_to_cell_map[*ep] == cell); const unsigned int ival = invariant_values[*ep]; assert(ival <= 255); dcs_count[ival]++; ep++; #if defined(BLISS_CONSISTENCY_CHECKS) bool equal_invariant_values = true; #endif for(unsigned int i = cell->length - 1; i != 0; i--) { assert(element_to_cell_map[*ep] == cell); const unsigned int ival2 = invariant_values[*ep]; assert(ival2 <= 255); assert(ival2 <= max_ival); dcs_count[ival2]++; #if defined(BLISS_CONSISTENCY_CHECKS) if(ival2 != ival) { equal_invariant_values = false; } #endif ep++; } #if defined(BLISS_CONSISTENCY_CHECKS) assert(!equal_invariant_values); if(equal_invariant_values) { assert(dcs_count[ival] == cell->length); dcs_count[ival] = 0; clear_ivs(cell); return cell; } #endif } /* Build start array */ dcs_cumulate_count(max_ival); //assert(dcs_start[255] + dcs_count[255] == cell->length); assert(dcs_start[max_ival] + dcs_count[max_ival] == cell->length); /* Do the sorting */ for(unsigned int i = 0; i <= max_ival; i++) { unsigned int *ep = elements + cell->first + dcs_start[i]; for(unsigned int j = dcs_count[i]; j > 0; j--) { while(true) { const unsigned int element = *ep; const unsigned int ival = invariant_values[element]; if(ival == i) break; assert(ival > i); assert(dcs_count[ival] > 0); *ep = elements[cell->first + dcs_start[ival]]; elements[cell->first + dcs_start[ival]] = element; dcs_start[ival]++; dcs_count[ival]--; } ep++; } dcs_count[i] = 0; } #if defined(BLISS_CONSISTENCY_CHECKS) for(unsigned int i = 0; i < 256; i++) assert(dcs_count[i] == 0); #endif /* split cell */ Cell* const new_cell = split_cell(cell); assert(new_cell != cell); return new_cell; } /* * Sort the elements in a cell according to their invariant values. * The invariant values are not cleared. * Warning: the in_pos array is left in incorrect state. */ bool Partition::shellsort_cell(Partition::Cell* const cell) { unsigned int h; unsigned int* ep; //assert(cell->first + cell->length <= N); if(cell->is_unit()) return false; /* Check whether all the elements have the same invariant value */ bool equal_invariant_values = true; { ep = elements + cell->first; const unsigned int ival = invariant_values[*ep]; assert(element_to_cell_map[*ep] == cell); ep++; for(unsigned int i = cell->length - 1; i > 0; i--) { assert(element_to_cell_map[*ep] == cell); if(invariant_values[*ep] != ival) { equal_invariant_values = false; break; } ep++; } } if(equal_invariant_values) return false; ep = elements + cell->first; for(h = 1; h <= cell->length/9; h = 3*h + 1) ; for( ; h > 0; h = h/3) { for(unsigned int i = h; i < cell->length; i++) { const unsigned int element = ep[i]; const unsigned int ival = invariant_values[element]; unsigned int j = i; while(j >= h and invariant_values[ep[j-h]] > ival) { ep[j] = ep[j-h]; j -= h; } ep[j] = element; } } return true; } void Partition::clear_ivs(Cell* const cell) { unsigned int* ep = elements + cell->first; for(unsigned int i = cell->length; i > 0; i--, ep++) invariant_values[*ep] = 0; } /* * Assumes that the elements in the cell are sorted according to their * invariant values. */ Partition::Cell* Partition::split_cell(Partition::Cell* const original_cell) { Cell* cell = original_cell; const bool original_cell_was_in_splitting_queue = original_cell->in_splitting_queue; Cell* largest_new_cell = 0; while(true) { unsigned int* ep = elements + cell->first; const unsigned int* const lp = ep + cell->length; const unsigned int ival = invariant_values[*ep]; invariant_values[*ep] = 0; element_to_cell_map[*ep] = cell; in_pos[*ep] = ep; ep++; while(ep < lp) { const unsigned int e = *ep; if(invariant_values[e] != ival) break; invariant_values[e] = 0; in_pos[e] = ep; ep++; element_to_cell_map[e] = cell; } if(ep == lp) break; Cell* const new_cell = aux_split_in_two(cell, (ep - elements) - cell->first); if(graph and graph->compute_eqref_hash) { graph->eqref_hash.update(new_cell->first); graph->eqref_hash.update(new_cell->length); graph->eqref_hash.update(ival); } /* Add cells in splitting_queue */ assert(!new_cell->is_in_splitting_queue()); if(original_cell_was_in_splitting_queue) { /* In this case, all new cells are inserted in splitting_queue */ assert(cell->is_in_splitting_queue()); splitting_queue_add(new_cell); } else { /* Otherwise, we can omit one new cell from splitting_queue */ assert(!cell->is_in_splitting_queue()); if(largest_new_cell == 0) { largest_new_cell = cell; } else { assert(!largest_new_cell->is_in_splitting_queue()); if(cell->length > largest_new_cell->length) { splitting_queue_add(largest_new_cell); largest_new_cell = cell; } else { splitting_queue_add(cell); } } } /* Process the rest of the cell */ cell = new_cell; } if(original_cell == cell) { /* All the elements in cell had the same invariant value */ return cell; } /* Add cells in splitting_queue */ if(!original_cell_was_in_splitting_queue) { /* Also consider the last new cell */ assert(largest_new_cell); if(cell->length > largest_new_cell->length) { splitting_queue_add(largest_new_cell); largest_new_cell = cell; } else { splitting_queue_add(cell); } if(largest_new_cell->is_unit()) { /* Needed in certificate computation */ splitting_queue_add(largest_new_cell); } } return cell; } Partition::Cell* Partition::zplit_cell(Partition::Cell* const cell, const bool max_ival_info_ok) { assert(cell != 0); Cell* last_new_cell = cell; if(!max_ival_info_ok) { /* Compute max_ival info */ assert(cell->max_ival == 0); assert(cell->max_ival_count == 0); unsigned int *ep = elements + cell->first; for(unsigned int i = cell->length; i > 0; i--, ep++) { const unsigned int ival = invariant_values[*ep]; if(ival > cell->max_ival) { cell->max_ival = ival; cell->max_ival_count = 1; } else if(ival == cell->max_ival) { cell->max_ival_count++; } } } #ifdef BLISS_CONSISTENCY_CHECKS /* Verify max_ival info */ { unsigned int nof_zeros = 0; unsigned int max_ival = 0; unsigned int max_ival_count = 0; unsigned int *ep = elements + cell->first; for(unsigned int i = cell->length; i > 0; i--, ep++) { const unsigned int ival = invariant_values[*ep]; if(ival == 0) nof_zeros++; if(ival > max_ival) { max_ival = ival; max_ival_count = 1; } else if(ival == max_ival) max_ival_count++; } assert(max_ival == cell->max_ival); assert(max_ival_count == cell->max_ival_count); } #endif /* max_ival info has been computed */ if(cell->max_ival_count == cell->length) { /* All invariant values are the same, clear 'em */ if(cell->max_ival > 0) clear_ivs(cell); } else { /* All invariant values are not the same */ if(cell->max_ival == 1) { /* Specialized splitting for cells with binary invariant values */ last_new_cell = sort_and_split_cell1(cell); } else if(cell->max_ival < 256) { /* Specialized splitting for cells with invariant values < 256 */ last_new_cell = sort_and_split_cell255(cell, cell->max_ival); } else { /* Generic sorting and splitting */ const bool sorted = shellsort_cell(cell); assert(sorted); IGRAPH_UNUSED(sorted); last_new_cell = split_cell(cell); } } cell->max_ival = 0; cell->max_ival_count = 0; return last_new_cell; } /* * * Component recursion specific code * */ void Partition::cr_init() { assert(bt_stack.empty()); cr_enabled = true; delete[] cr_cells; cr_cells = new CRCell[N]; delete[] cr_levels; cr_levels = new CRCell*[N]; for(unsigned int i = 0; i < N; i++) { cr_levels[i] = 0; cr_cells[i].level = UINT_MAX; cr_cells[i].next = 0; cr_cells[i].prev_next_ptr = 0; } for(const Cell *cell = first_cell; cell; cell = cell->next) cr_create_at_level_trailed(cell->first, 0); cr_max_level = 0; } void Partition::cr_free() { delete[] cr_cells; cr_cells = nullptr; delete[] cr_levels; cr_levels = nullptr; cr_created_trail.clear(); cr_splitted_level_trail.clear(); cr_bt_info.clear(); cr_max_level = 0; cr_enabled = false; } unsigned int Partition::cr_split_level(const unsigned int level, const std::vector& splitted_cells) { assert(cr_enabled); assert(level <= cr_max_level); cr_levels[++cr_max_level] = 0; cr_splitted_level_trail.push_back(level); for(unsigned int i = 0; i < splitted_cells.size(); i++) { const unsigned int cell_index = splitted_cells[i]; assert(cell_index < N); CRCell& cr_cell = cr_cells[cell_index]; assert(cr_cell.level == level); cr_cell.detach(); cr_create_at_level(cell_index, cr_max_level); } return cr_max_level; } unsigned int Partition::cr_get_backtrack_point() { assert(cr_enabled); CR_BTInfo info; info.created_trail_index = cr_created_trail.size(); info.splitted_level_trail_index = cr_splitted_level_trail.size(); cr_bt_info.push_back(info); return cr_bt_info.size()-1; } void Partition::cr_goto_backtrack_point(const unsigned int btpoint) { assert(cr_enabled); assert(btpoint < cr_bt_info.size()); while(cr_created_trail.size() > cr_bt_info[btpoint].created_trail_index) { const unsigned int cell_index = cr_created_trail.back(); cr_created_trail.pop_back(); CRCell& cr_cell = cr_cells[cell_index]; assert(cr_cell.level != UINT_MAX); assert(cr_cell.prev_next_ptr); cr_cell.detach(); } while(cr_splitted_level_trail.size() > cr_bt_info[btpoint].splitted_level_trail_index) { const unsigned int dest_level = cr_splitted_level_trail.back(); cr_splitted_level_trail.pop_back(); assert(cr_max_level > 0); assert(dest_level < cr_max_level); while(cr_levels[cr_max_level]) { CRCell *cr_cell = cr_levels[cr_max_level]; cr_cell->detach(); cr_create_at_level(cr_cell - cr_cells, dest_level); } cr_max_level--; } cr_bt_info.resize(btpoint); } void Partition::cr_create_at_level(const unsigned int cell_index, const unsigned int level) { assert(cr_enabled); assert(cell_index < N); assert(level < N); CRCell& cr_cell = cr_cells[cell_index]; assert(cr_cell.level == UINT_MAX); assert(cr_cell.next == 0); assert(cr_cell.prev_next_ptr == 0); if(cr_levels[level]) cr_levels[level]->prev_next_ptr = &(cr_cell.next); cr_cell.next = cr_levels[level]; cr_levels[level] = &cr_cell; cr_cell.prev_next_ptr = &cr_levels[level]; cr_cell.level = level; } void Partition::cr_create_at_level_trailed(const unsigned int cell_index, const unsigned int level) { assert(cr_enabled); cr_create_at_level(cell_index, level); cr_created_trail.push_back(cell_index); } } // namespace bliss leidenbase/src/core/isomorphism/bliss/orbit.hh0000644000176200001440000000602414447675374021240 0ustar liggesusers#ifndef BLISS_ORBIT_HH #define BLISS_ORBIT_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { /** * \brief A class for representing orbit information. * * Given a set {0,...,N-1} of N elements, represent equivalence * classes (that is, unordered partitions) of the elements. * Supports only equivalence class merging, not splitting. * Merging two classes requires time O(k), where k is the number of * the elements in the smaller of the merged classes. * Getting the smallest representative in a class * (and thus testing whether two elements belong to the same class) * is a constant time operation. */ class Orbit { class OrbitEntry { public: unsigned int element; OrbitEntry *next; unsigned int size; }; OrbitEntry *orbits; OrbitEntry **in_orbit; unsigned int nof_elements; unsigned int _nof_orbits; void merge_orbits(OrbitEntry *o1, OrbitEntry *o2); public: /** * Create a new orbit information object. * The init() function must be called next to actually initialize * the object. */ Orbit(); ~Orbit(); /** * Initialize the orbit information to consider sets of \a N elements. * It is required that \a N > 0. * The orbit information is reset so that each element forms * an orbit of its own. * Time complexity is O(N). * \sa reset() */ void init(const unsigned int N); /** * Reset the orbits so that each element forms an orbit of its own. * Time complexity is O(N). */ void reset(); /** * Merge the orbits of the elements \a e1 and \a e2. * Time complexity is O(k), where k is the number of elements in * the smaller of the merged orbits. */ void merge_orbits(unsigned int e1, unsigned int e2); /** * Is the element \a e the smallest element in its orbit? * Time complexity is O(1). */ bool is_minimal_representative(unsigned int e) const; /** * Get the smallest element in the orbit of the element \a e. * Time complexity is O(1). */ unsigned int get_minimal_representative(unsigned int e) const; /** * Get the number of elements in the orbit of the element \a e. * Time complexity is O(1). */ unsigned int orbit_size(unsigned int e) const; /** * Get the number of orbits. * Time complexity is O(1). */ unsigned int nof_orbits() const {return _nof_orbits; } }; } // namespace bliss #endif // BLISS_ORBIT_HH leidenbase/src/core/isomorphism/bliss/orbit.cc0000644000176200001440000000601314447675374021224 0ustar liggesusers#include #include "orbit.hh" /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { Orbit::Orbit() { orbits = 0; in_orbit = 0; nof_elements = 0; } Orbit::~Orbit() { delete[] orbits; orbits = 0; /* if(orbits) { free(orbits); orbits = 0; } */ delete[] in_orbit; in_orbit = 0; /* if(in_orbit) { free(in_orbit); in_orbit = 0; } */ nof_elements = 0; _nof_orbits = 0; } void Orbit::init(const unsigned int n) { assert(n > 0); if(orbits) delete[] orbits; orbits = new OrbitEntry[n]; delete[] in_orbit; in_orbit = new OrbitEntry*[n]; nof_elements = n; reset(); } void Orbit::reset() { assert(orbits); assert(in_orbit); for(unsigned int i = 0; i < nof_elements; i++) { orbits[i].element = i; orbits[i].next = 0; orbits[i].size = 1; in_orbit[i] = &orbits[i]; } _nof_orbits = nof_elements; } void Orbit::merge_orbits(OrbitEntry *orbit1, OrbitEntry *orbit2) { if(orbit1 != orbit2) { _nof_orbits--; /* Only update the elements in the smaller orbit */ if(orbit1->size > orbit2->size) { OrbitEntry * const temp = orbit2; orbit2 = orbit1; orbit1 = temp; } /* Link the elements of orbit1 to the almost beginning of orbit2 */ OrbitEntry *e = orbit1; while(e->next) { in_orbit[e->element] = orbit2; e = e->next; } in_orbit[e->element] = orbit2; e->next = orbit2->next; orbit2->next = orbit1; /* Keep the minimal orbit representative in the beginning */ if(orbit1->element < orbit2->element) { const unsigned int temp = orbit1->element; orbit1->element = orbit2->element; orbit2->element = temp; } orbit2->size += orbit1->size; } } void Orbit::merge_orbits(unsigned int e1, unsigned int e2) { merge_orbits(in_orbit[e1], in_orbit[e2]); } bool Orbit::is_minimal_representative(unsigned int element) const { return(get_minimal_representative(element) == element); } unsigned int Orbit::get_minimal_representative(unsigned int element) const { OrbitEntry * const orbit = in_orbit[element]; return(orbit->element); } unsigned int Orbit::orbit_size(unsigned int element) const { return(in_orbit[element]->size); } } // namespace bliss leidenbase/src/core/isomorphism/bliss/partition.hh0000644000176200001440000002020314447675374022125 0ustar liggesusers#ifndef BLISS_PARTITION_HH #define BLISS_PARTITION_HH /* Copyright (c) 2003-2021 Tommi Junttila Released under the GNU Lesser General Public License version 3. This file is part of bliss. bliss is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. bliss is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with bliss. If not, see . */ namespace bliss { class Partition; } #include #include #include "kstack.hh" #include "kqueue.hh" #include "graph.hh" namespace bliss { /** * \brief A class for refinable, backtrackable ordered partitions. * * This is rather a data structure with some helper functions than * a proper self-contained class. * That is, for efficiency reasons the fields of this class are directly * manipulated from bliss::AbstractGraph and its subclasses. * Conversely, some methods of this class modify the fields of * bliss::AbstractGraph, too. */ class Partition { public: /** * \brief Data structure for holding information about a cell in a Partition. */ class Cell { friend class Partition; public: unsigned int length; /* Index of the first element of the cell in the Partition::elements array */ unsigned int first; unsigned int max_ival; unsigned int max_ival_count; private: bool in_splitting_queue; public: bool in_neighbour_heap; /* Pointer to the next cell, null if this is the last one. */ Cell* next; Cell* prev; Cell* next_nonsingleton; Cell* prev_nonsingleton; unsigned int split_level; /** Is this a unit cell? */ bool is_unit() const {return(length == 1); } /** Is this cell in splitting queue? */ bool is_in_splitting_queue() const {return(in_splitting_queue); } }; private: /** \internal * Data structure for remembering information about splits in order to * perform efficient backtracking over the splits. */ class RefInfo { public: unsigned int split_cell_first; int prev_nonsingleton_first; int next_nonsingleton_first; }; /** \internal * A stack for remembering the splits, used for backtracking. */ KStack refinement_stack; class BacktrackInfo { public: unsigned int refinement_stack_size; unsigned int cr_backtrack_point; }; /** \internal * The main stack for enabling backtracking. */ std::vector bt_stack; public: AbstractGraph* graph; /* Used during equitable partition refinement */ KQueue splitting_queue; void splitting_queue_add(Cell* const cell); Cell* splitting_queue_pop(); bool splitting_queue_is_empty() const; void splitting_queue_clear(); /** Type for backtracking points. */ typedef unsigned int BacktrackPoint; /** * Get a new backtrack point for the current partition */ BacktrackPoint set_backtrack_point(); /** * Backtrack to the point \a p and remove it. */ void goto_backtrack_point(BacktrackPoint p); /** * Split the non-unit Cell \a cell = {\a element,e1,e2,...,en} containing * the element \a element in two: * \a cell = {e1,...,en} and \a newcell = {\a element}. * @param cell a non-unit Cell * @param element an element in \a cell * @return the new unit Cell \a newcell */ Cell* individualize(Cell* const cell, const unsigned int element); Cell* aux_split_in_two(Cell* const cell, const unsigned int first_half_size); private: unsigned int N; Cell* cells; Cell* free_cells; unsigned int discrete_cell_count; public: Cell* first_cell; Cell* first_nonsingleton_cell; unsigned int *elements; /* invariant_values[e] gives the invariant value of the element e */ unsigned int *invariant_values; /* element_to_cell_map[e] gives the cell of the element e */ Cell **element_to_cell_map; /** Get the cell of the element \a e */ Cell* get_cell(const unsigned int e) const { assert(e < N); return element_to_cell_map[e]; } /* in_pos[e] points to the elements array s.t. *in_pos[e] = e */ unsigned int **in_pos; Partition(); ~Partition(); /** * Initialize the partition to the unit partition (all elements in one cell) * over the \a N > 0 elements {0,...,\a N-1}. */ void init(const unsigned int N); /** * Returns true iff the partition is discrete, meaning that all * the elements are in their own cells. */ bool is_discrete() const {return(free_cells == 0); } unsigned int nof_discrete_cells() const {return(discrete_cell_count); } /* * Splits the Cell \a cell into [cell_1,...,cell_n] * according to the invariant_values of the elements in \a cell. * After splitting, cell_1 == \a cell. * Returns the pointer to the Cell cell_n; * cell_n != cell iff the Cell \a cell was actually splitted. * The flag \a max_ival_info_ok indicates whether the max_ival and * max_ival_count fields of the Cell \a cell have consistent values * when the method is called. * Clears the invariant values of elements in the Cell \a cell as well as * the max_ival and max_ival_count fields of the Cell \a cell. */ Cell *zplit_cell(Cell * const cell, const bool max_ival_info_ok); /* * Routines for component recursion */ void cr_init(); void cr_free(); unsigned int cr_get_level(const unsigned int cell_index) const; unsigned int cr_split_level(const unsigned int level, const std::vector& cells); /** Clear the invariant_values of the elements in the Cell \a cell. */ void clear_ivs(Cell* const cell); private: /* * Component recursion data structures */ /* Is component recursion support in use? */ bool cr_enabled; class CRCell { public: unsigned int level; CRCell* next; CRCell** prev_next_ptr; void detach() { if(next) next->prev_next_ptr = prev_next_ptr; *(prev_next_ptr) = next; level = UINT_MAX; next = 0; prev_next_ptr = 0; } }; CRCell* cr_cells; CRCell** cr_levels; class CR_BTInfo { public: unsigned int created_trail_index; unsigned int splitted_level_trail_index; }; std::vector cr_created_trail; std::vector cr_splitted_level_trail; std::vector cr_bt_info; unsigned int cr_max_level; void cr_create_at_level(const unsigned int cell_index, unsigned int level); void cr_create_at_level_trailed(const unsigned int cell_index, unsigned int level); unsigned int cr_get_backtrack_point(); void cr_goto_backtrack_point(const unsigned int btpoint); /* * * Auxiliary routines for sorting and splitting cells * */ Cell* sort_and_split_cell1(Cell* cell); Cell* sort_and_split_cell255(Cell* const cell, const unsigned int max_ival); bool shellsort_cell(Cell* cell); Cell* split_cell(Cell* const cell); /* * Some auxiliary stuff needed for distribution count sorting. * To make the code thread-safe (modulo the requirement that each graph is * only accessed in one thread at a time), the arrays are owned by * the partition instance, not statically defined. */ unsigned int dcs_count[256]; unsigned int dcs_start[256]; void dcs_cumulate_count(const unsigned int max); }; inline Partition::Cell* Partition::splitting_queue_pop() { assert(!splitting_queue.is_empty()); Cell* const cell = splitting_queue.pop_front(); assert(cell->in_splitting_queue); cell->in_splitting_queue = false; return cell; } inline bool Partition::splitting_queue_is_empty() const { return splitting_queue.is_empty(); } inline unsigned int Partition::cr_get_level(const unsigned int cell_index) const { assert(cr_enabled); assert(cell_index < N); assert(cr_cells[cell_index].level != UINT_MAX); return(cr_cells[cell_index].level); } } // namespace bliss #endif // BLISS_PARTITION_HH leidenbase/src/core/isomorphism/isoclasses.h0000644000176200001440000000312014447675374020777 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2008-2020 The igraph development team 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_ISOCLASSES_H #define IGRAPH_ISOCLASSES_H #include "igraph_decls.h" __BEGIN_DECLS extern const unsigned int igraph_i_isoclass2_3[]; extern const unsigned int igraph_i_isoclass2_4[]; extern const unsigned int igraph_i_isoclass2_3u[]; extern const unsigned int igraph_i_isoclass2_4u[]; extern const unsigned int igraph_i_isoclass2_5u[]; extern const unsigned int igraph_i_isoclass2_6u[]; extern const unsigned int igraph_i_isoclass_3_idx[]; extern const unsigned int igraph_i_isoclass_4_idx[]; extern const unsigned int igraph_i_isoclass_3u_idx[]; extern const unsigned int igraph_i_isoclass_4u_idx[]; extern const unsigned int igraph_i_isoclass_5u_idx[]; extern const unsigned int igraph_i_isoclass_6u_idx[]; __END_DECLS #endif leidenbase/src/core/isomorphism/bliss.cc0000644000176200001440000005265214447675374020117 0ustar liggesusers/* Copyright (C) 2003-2006 Tommi Junttila This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ /* FSF address fixed in the above notice on 1 Oct 2009 by Tamas Nepusz */ #include "bliss/graph.hh" #include "igraph_topology.h" #include "igraph_conversion.h" #include "igraph_interface.h" #include "igraph_interrupt.h" #include "igraph_memory.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" #include "core/exceptions.h" using namespace bliss; using namespace std; /** * \section about_bliss * * * Bliss is a successor of the famous NAUTY algorithm and * implementation. While using the same ideas in general, with better * heuristics and data structures Bliss outperforms NAUTY on most * graphs. * * * * Bliss was developed and implemented by Tommi Junttila and Petteri Kaski at * Helsinki University of Technology, Finland. For more information, * see the Bliss homepage at https://users.aalto.fi/~tjunttil/bliss/ and the following * publication: * * * * Tommi Junttila and Petteri Kaski: "Engineering an Efficient Canonical Labeling * Tool for Large and Sparse Graphs" In ALENEX 2007, pages 135–149, 2007 * https://doi.org/10.1137/1.9781611972870.13 * * * * Tommi Junttila and Petteri Kaski: "Conflict Propagation and Component Recursion * for Canonical Labeling" in TAPAS 2011, pages 151–162, 2011. * https://doi.org/10.1007/978-3-642-19754-3_16 * * * * Bliss works with both directed graphs and undirected graphs. It supports graphs with * self-loops, but not graphs with multi-edges. * * * * Bliss version 0.75 is included in igraph. * */ namespace { // unnamed namespace inline AbstractGraph *bliss_from_igraph(const igraph_t *graph) { unsigned int nof_vertices = (unsigned int)igraph_vcount(graph); unsigned int nof_edges = (unsigned int)igraph_ecount(graph); AbstractGraph *g; if (igraph_is_directed(graph)) { g = new Digraph(nof_vertices); } else { g = new Graph(nof_vertices); } /* g->set_verbose_level(0); */ for (unsigned int i = 0; i < nof_edges; i++) { g->add_edge((unsigned int)IGRAPH_FROM(graph, i), (unsigned int)IGRAPH_TO(graph, i)); } return g; } void bliss_free_graph(AbstractGraph *g) { delete g; } inline int bliss_set_sh(AbstractGraph *g, igraph_bliss_sh_t sh, bool directed) { if (directed) { Digraph::SplittingHeuristic gsh = Digraph::shs_fsm; switch (sh) { case IGRAPH_BLISS_F: gsh = Digraph::shs_f; break; case IGRAPH_BLISS_FL: gsh = Digraph::shs_fl; break; case IGRAPH_BLISS_FS: gsh = Digraph::shs_fs; break; case IGRAPH_BLISS_FM: gsh = Digraph::shs_fm; break; case IGRAPH_BLISS_FLM: gsh = Digraph::shs_flm; break; case IGRAPH_BLISS_FSM: gsh = Digraph::shs_fsm; break; default: IGRAPH_ERROR("Invalid splitting heuristic.", IGRAPH_EINVAL); } static_cast(g)->set_splitting_heuristic(gsh); } else { Graph::SplittingHeuristic gsh = Graph::shs_fsm; switch (sh) { case IGRAPH_BLISS_F: gsh = Graph::shs_f; break; case IGRAPH_BLISS_FL: gsh = Graph::shs_fl; break; case IGRAPH_BLISS_FS: gsh = Graph::shs_fs; break; case IGRAPH_BLISS_FM: gsh = Graph::shs_fm; break; case IGRAPH_BLISS_FLM: gsh = Graph::shs_flm; break; case IGRAPH_BLISS_FSM: gsh = Graph::shs_fsm; break; default: IGRAPH_ERROR("Invalid splitting heuristic.", IGRAPH_EINVAL); } static_cast(g)->set_splitting_heuristic(gsh); } return IGRAPH_SUCCESS; } inline int bliss_set_colors(AbstractGraph *g, const igraph_vector_int_t *colors) { if (colors == NULL) { return IGRAPH_SUCCESS; } const int n = g->get_nof_vertices(); if (n != igraph_vector_int_size(colors)) { IGRAPH_ERROR("Invalid vertex color vector length.", IGRAPH_EINVAL); } for (int i = 0; i < n; ++i) { g->change_color(i, VECTOR(*colors)[i]); } return IGRAPH_SUCCESS; } inline int bliss_info_to_igraph(igraph_bliss_info_t *info, const Stats &stats) { if (info) { size_t group_size_strlen; info->max_level = stats.get_max_level(); info->nof_nodes = stats.get_nof_nodes(); info->nof_leaf_nodes = stats.get_nof_leaf_nodes(); info->nof_bad_nodes = stats.get_nof_bad_nodes(); info->nof_canupdates = stats.get_nof_canupdates(); info->nof_generators = stats.get_nof_generators(); mpz_t group_size; mpz_init(group_size); stats.get_group_size().get(group_size); group_size_strlen = mpz_sizeinbase(group_size, /* base */ 10) + 2; info->group_size = IGRAPH_CALLOC(group_size_strlen, char); if (! info->group_size) { IGRAPH_ERROR("Insufficient memory to retrieve automotphism group size.", IGRAPH_ENOMEM); } mpz_get_str(info->group_size, /* base */ 10, group_size); mpz_clear(group_size); } return IGRAPH_SUCCESS; } // This is the callback function that can tell Bliss to terminate early. struct AbortChecker { bool aborted; AbortChecker() : aborted(false) { } bool operator()() { if (igraph_allow_interruption(NULL) != IGRAPH_SUCCESS) { aborted = true; return true; } return false; } }; // This is the callback function used with AbstractGraph::find_automorphisms(). // It collects the automorphism group generators into a pointer vector. class AutCollector { igraph_vector_ptr_t *generators; public: AutCollector(igraph_vector_ptr_t *generators_) : generators(generators_) { } void operator ()(unsigned int n, const unsigned int *aut) { int err; igraph_vector_t *newvector = IGRAPH_CALLOC(1, igraph_vector_t); if (! newvector) { throw bad_alloc(); } err = igraph_vector_init(newvector, n); if (err) { throw bad_alloc(); } copy(aut, aut + n, newvector->stor_begin); // takes care of unsigned int -> double conversion err = igraph_vector_ptr_push_back(generators, newvector); if (err) { throw bad_alloc(); } } }; } // end unnamed namespace /** * \function igraph_canonical_permutation * \brief Canonical permutation using Bliss. * * This function computes the vertex permutation which transforms * the graph into a canonical form, using the Bliss algorithm. * Two graphs have the same canonical form if and only if they * are isomorphic. Use \ref igraph_is_same_graph() to compare * two canonical forms. * * \param graph The input graph. Multiple edges between the same nodes * are not supported and will cause an incorrect result to be returned. * \param colors An optional vertex color vector for the graph. Supply a * null pointer is the graph is not colored. * \param labeling Pointer to a vector, the result is stored here. The * permutation takes vertex 0 to the first element of the vector, * vertex 1 to the second, etc. The vector will be resized as * needed. * \param sh The splitting heuristics to be used in Bliss. See \ref * igraph_bliss_sh_t. * \param info If not \c NULL then information on Bliss internals is * stored here. The memory used by this structure must to be freed * when no longer needed, see \ref igraph_bliss_info_t. * \return Error code. * * \sa igraph_is_same_graph() * * Time complexity: exponential, in practice it is fast for many graphs. */ int igraph_canonical_permutation(const igraph_t *graph, const igraph_vector_int_t *colors, igraph_vector_t *labeling, igraph_bliss_sh_t sh, igraph_bliss_info_t *info) { IGRAPH_HANDLE_EXCEPTIONS( AbstractGraph *g = bliss_from_igraph(graph); IGRAPH_FINALLY(bliss_free_graph, g); const unsigned int N = g->get_nof_vertices(); IGRAPH_CHECK(bliss_set_sh(g, sh, igraph_is_directed(graph))); IGRAPH_CHECK(bliss_set_colors(g, colors)); Stats stats; AbortChecker checker; const unsigned int *cl = g->canonical_form(stats, /* report */ nullptr, /* terminate */ checker); if (checker.aborted) { return IGRAPH_INTERRUPTED; } IGRAPH_CHECK(igraph_vector_resize(labeling, N)); for (unsigned int i = 0; i < N; i++) { VECTOR(*labeling)[i] = cl[i]; } IGRAPH_CHECK(bliss_info_to_igraph(info, stats)); delete g; IGRAPH_FINALLY_CLEAN(1); ); return IGRAPH_SUCCESS; } /** * \function igraph_automorphisms * \brief Number of automorphisms using Bliss. * * The number of automorphisms of a graph is computed using Bliss. The * result is returned as part of the \p info structure, in tag \c * group_size. It is returned as a string, as it can be very high even * for relatively small graphs. If the GNU MP library is used then * this number is exact, otherwise a long double is used * and it is only approximate. See also \ref igraph_bliss_info_t. * * \param graph The input graph. Multiple edges between the same nodes * are not supported and will cause an incorrect result to be returned. * \param colors An optional vertex color vector for the graph. Supply a * null pointer is the graph is not colored. * \param sh The splitting heuristics to be used in Bliss. See \ref * igraph_bliss_sh_t. * \param info The result is stored here, in particular in the \c * group_size tag of \p info. The memory used by this structure must be * released when no longer needed, see \ref igraph_bliss_info_t. * \return Error code. * * Time complexity: exponential, in practice it is fast for many graphs. */ int igraph_automorphisms(const igraph_t *graph, const igraph_vector_int_t *colors, igraph_bliss_sh_t sh, igraph_bliss_info_t *info) { IGRAPH_HANDLE_EXCEPTIONS( AbstractGraph *g = bliss_from_igraph(graph); IGRAPH_FINALLY(bliss_free_graph, g); IGRAPH_CHECK(bliss_set_sh(g, sh, igraph_is_directed(graph))); IGRAPH_CHECK(bliss_set_colors(g, colors)); Stats stats; AbortChecker checker; g->find_automorphisms(stats, /* report */ nullptr, /* terminate */ checker); if (checker.aborted) { return IGRAPH_INTERRUPTED; } IGRAPH_CHECK(bliss_info_to_igraph(info, stats)); delete g; IGRAPH_FINALLY_CLEAN(1); ); return IGRAPH_SUCCESS; } /** * \function igraph_automorphism_group * \brief Automorphism group generators using Bliss. * * The generators of the automorphism group of a graph are computed * using Bliss. The generator set may not be minimal and may depend on * the splitting heuristics. The generators are permutations represented * using zero-based indexing. * * \param graph The input graph. Multiple edges between the same nodes * are not supported and will cause an incorrect result to be returned. * \param colors An optional vertex color vector for the graph. Supply a * null pointer is the graph is not colored. * \param generators Must be an initialized pointer vector. It will * contain pointers to \ref igraph_vector_t objects * representing generators of the automorphism group. * \param sh The splitting heuristics to be used in Bliss. See \ref * igraph_bliss_sh_t. * \param info If not \c NULL then information on Bliss internals is * stored here. The memory used by this structure must to be freed * when no longer needed, see \ref igraph_bliss_info_t. * \return Error code. * * Time complexity: exponential, in practice it is fast for many graphs. */ int igraph_automorphism_group( const igraph_t *graph, const igraph_vector_int_t *colors, igraph_vector_ptr_t *generators, igraph_bliss_sh_t sh, igraph_bliss_info_t *info) { IGRAPH_HANDLE_EXCEPTIONS( AbstractGraph *g = bliss_from_igraph(graph); IGRAPH_FINALLY(bliss_free_graph, g); IGRAPH_CHECK(bliss_set_sh(g, sh, igraph_is_directed(graph))); IGRAPH_CHECK(bliss_set_colors(g, colors)); Stats stats; igraph_vector_ptr_resize(generators, 0); AutCollector collector(generators); AbortChecker checker; g->find_automorphisms(stats, collector, checker); if (checker.aborted) { return IGRAPH_INTERRUPTED; } IGRAPH_CHECK(bliss_info_to_igraph(info, stats)); delete g; IGRAPH_FINALLY_CLEAN(1); ); return IGRAPH_SUCCESS; } /* The following license notice applies to the rest of this file */ /* IGraph library. Copyright (C) 2006-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** * \function igraph_isomorphic_bliss * \brief Graph isomorphism via Bliss. * * This function uses the Bliss graph isomorphism algorithm, a * successor of the famous NAUTY algorithm and implementation. Bliss * is open source and licensed according to the GNU LGPL. See * https://users.aalto.fi/~tjunttil/bliss/ for * details. Currently the 0.75 version of Bliss is included in igraph. * * * Isomorphism testing is implemented by producing the canonical form * of both graphs using \ref igraph_canonical_permutation() and * comparing them. * * \param graph1 The first input graph. Multiple edges between the same nodes * are not supported and will cause an incorrect result to be returned. * \param graph2 The second input graph. Multiple edges between the same nodes * are not supported and will cause an incorrect result to be returned. * \param colors1 An optional vertex color vector for the first graph. Supply a * null pointer if your graph is not colored. * \param colors2 An optional vertex color vector for the second graph. Supply a * null pointer if your graph is not colored. * \param iso Pointer to a boolean, the result is stored here. * \param map12 A vector or \c NULL pointer. If not \c NULL then an * isomorphic mapping from \p graph1 to \p graph2 is stored here. * If the input graphs are not isomorphic then this vector is * cleared, i.e. it will have length zero. * \param map21 Similar to \p map12, but for the mapping from \p * graph2 to \p graph1. * \param sh Splitting heuristics to be used for the graphs. See * \ref igraph_bliss_sh_t. * \param info1 If not \c NULL, information about the canonization of * the first input graph is stored here. Note that if the two graphs * have different number of vertices or edges, then this is only * partially filled. The memory used by this structure should be * released when no longer needed, see \ref igraph_bliss_info_t * for details. * \param info2 Same as \p info1, but for the second graph. * \return Error code. * * Time complexity: exponential, but in practice it is quite fast. */ int igraph_isomorphic_bliss(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *colors1, const igraph_vector_int_t *colors2, igraph_bool_t *iso, igraph_vector_t *map12, igraph_vector_t *map21, igraph_bliss_sh_t sh, igraph_bliss_info_t *info1, igraph_bliss_info_t *info2) { long int no_of_nodes = igraph_vcount(graph1); long int no_of_edges = igraph_ecount(graph1); igraph_vector_t perm1, perm2; igraph_vector_t vmap12, *mymap12 = &vmap12; igraph_vector_t from, to, index; igraph_vector_t from2, to2, index2; igraph_bool_t directed; long int i, j; *iso = 0; if (info1) { info1->nof_nodes = info1->nof_leaf_nodes = info1->nof_bad_nodes = info1->nof_canupdates = info1->max_level = info1->nof_generators = 0; info1->group_size = 0; } if (info2) { info2->nof_nodes = info2->nof_leaf_nodes = info2->nof_bad_nodes = info2->nof_canupdates = info2->max_level = info2->nof_generators = 0; info2->group_size = 0; } directed = igraph_is_directed(graph1); if (igraph_is_directed(graph2) != directed) { IGRAPH_ERROR("Cannot compare directed and undirected graphs.", IGRAPH_EINVAL); } if ((colors1 == NULL || colors2 == NULL) && colors1 != colors2) { IGRAPH_WARNING("Only one of the graphs is vertex colored, colors will be ignored."); colors1 = NULL; colors2 = NULL; } if (no_of_nodes != igraph_vcount(graph2) || no_of_edges != igraph_ecount(graph2)) { if (map12) { igraph_vector_clear(map12); } if (map21) { igraph_vector_clear(map21); } return 0; } if (map12) { mymap12 = map12; } else { IGRAPH_VECTOR_INIT_FINALLY(mymap12, 0); } IGRAPH_VECTOR_INIT_FINALLY(&perm1, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&perm2, no_of_nodes); IGRAPH_CHECK(igraph_canonical_permutation(graph1, colors1, &perm1, sh, info1)); IGRAPH_CHECK(igraph_canonical_permutation(graph2, colors2, &perm2, sh, info2)); IGRAPH_CHECK(igraph_vector_resize(mymap12, no_of_nodes)); /* The inverse of perm2 is produced in mymap12 */ for (i = 0; i < no_of_nodes; i++) { VECTOR(*mymap12)[ (long int)VECTOR(perm2)[i] ] = i; } /* Now we produce perm2^{-1} o perm1 in perm2 */ for (i = 0; i < no_of_nodes; i++) { VECTOR(perm2)[i] = VECTOR(*mymap12)[ (long int) VECTOR(perm1)[i] ]; } /* Copy it to mymap12 */ igraph_vector_update(mymap12, &perm2); igraph_vector_destroy(&perm1); igraph_vector_destroy(&perm2); IGRAPH_FINALLY_CLEAN(2); /* Check isomorphism, we apply the permutation in mymap12 to graph1 and should get graph2 */ IGRAPH_VECTOR_INIT_FINALLY(&from, no_of_edges); IGRAPH_VECTOR_INIT_FINALLY(&to, no_of_edges); IGRAPH_VECTOR_INIT_FINALLY(&index, no_of_edges); IGRAPH_VECTOR_INIT_FINALLY(&from2, no_of_edges * 2); IGRAPH_VECTOR_INIT_FINALLY(&to2, no_of_edges); IGRAPH_VECTOR_INIT_FINALLY(&index2, no_of_edges); for (i = 0; i < no_of_edges; i++) { VECTOR(from)[i] = VECTOR(*mymap12)[ (long int) IGRAPH_FROM(graph1, i) ]; VECTOR(to)[i] = VECTOR(*mymap12)[ (long int) IGRAPH_TO (graph1, i) ]; if (! directed && VECTOR(from)[i] < VECTOR(to)[i]) { igraph_real_t tmp = VECTOR(from)[i]; VECTOR(from)[i] = VECTOR(to)[i]; VECTOR(to)[i] = tmp; } } igraph_vector_order(&from, &to, &index, no_of_nodes); igraph_get_edgelist(graph2, &from2, /*bycol=*/ 1); for (i = 0, j = no_of_edges; i < no_of_edges; i++, j++) { VECTOR(to2)[i] = VECTOR(from2)[j]; if (! directed && VECTOR(from2)[i] < VECTOR(to2)[i]) { igraph_real_t tmp = VECTOR(from2)[i]; VECTOR(from2)[i] = VECTOR(to2)[i]; VECTOR(to2)[i] = tmp; } } igraph_vector_resize(&from2, no_of_edges); igraph_vector_order(&from2, &to2, &index2, no_of_nodes); *iso = 1; for (i = 0; i < no_of_edges; i++) { long int i1 = (long int) VECTOR(index)[i]; long int i2 = (long int) VECTOR(index2)[i]; if (VECTOR(from)[i1] != VECTOR(from2)[i2] || VECTOR(to)[i1] != VECTOR(to2)[i2]) { *iso = 0; break; } } /* If the graphs are coloured, we also need to check that applying the permutation mymap12 to colors1 gives colors2. */ if (*iso && colors1 != NULL) { for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*colors1)[i] != VECTOR(*colors2)[(long int) VECTOR(*mymap12)[i] ]) { *iso = 0; break; } } } igraph_vector_destroy(&index2); igraph_vector_destroy(&to2); igraph_vector_destroy(&from2); igraph_vector_destroy(&index); igraph_vector_destroy(&to); igraph_vector_destroy(&from); IGRAPH_FINALLY_CLEAN(6); if (*iso) { /* The inverse of mymap12 */ if (map21) { IGRAPH_CHECK(igraph_vector_resize(map21, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { VECTOR(*map21)[ (long int) VECTOR(*mymap12)[i] ] = i; } } } else { if (map12) { igraph_vector_clear(map12); } if (map21) { igraph_vector_clear(map21); } } if (!map12) { igraph_vector_destroy(mymap12); IGRAPH_FINALLY_CLEAN(1); } return 0; } leidenbase/src/core/isomorphism/isoclasses.c0000644000176200001440000057162414447675374021015 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_topology.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "isomorphism/isoclasses.h" /* * Small labelled graphs are encoded into a compact representation, a "code", * that fits into a single integer value. Each non-loop edge corresponds to * a specific bit of the integer. The edge-to-bit mappings are stored in * the "isoclass_idx" arrays while the bit-to-edge mappings are in the "classedges" * arrays. * * The "isoclass2" array is a mapping from the code of each possible labelled * graph to its isomorphism class. A canonical representative of each isomorphism * class is stored in "isographs". * * In the names of arrays, the number refers to the vertex count, while "u" * indicates undirected graphs (the other arrays store directed ones). * * Description of each array for graphs of size n: * * isosclass_idx represents an n-by-n matrix stored in column-major order. * Element i,j of the matrix is an integer with a single bit set. This bit, * if set, represents edge i-j in the graph code. * * isoclass2[code] gives the isomorphism class of the graph represented by code. * Classes are labelled by integers starting at 0, after ordering them by the * graph code of their smallest-code representative. * * isographs[class] is the code of a graph belonging to the given class. For each * class, the representative with the smallest code is chosen. * * classedges[2*i] - classedges[2*i+1] are the endpoints of the edge represented * by bit i in the code. Bits are numbered from most to least significant, thus * the most significant one has index i=0. */ const unsigned int igraph_i_isoclass_3_idx[] = { 0, 4, 16, 1, 0, 32, 2, 8, 0 }; const unsigned int igraph_i_isoclass_4_idx[] = { 0, 8, 64, 512, 1, 0, 128, 1024, 2, 16, 0, 2048, 4, 32, 256, 0 }; const unsigned int igraph_i_isoclass_3u_idx[] = { 0, 1, 2, 1, 0, 4, 2, 4, 0 }; const unsigned int igraph_i_isoclass_4u_idx[] = { 0, 1, 2, 8, 1, 0, 4, 16, 2, 4, 0, 32, 8, 16, 32, 0 }; const unsigned int igraph_i_isoclass_5u_idx[] = { 0, 1, 2, 8, 64, 1, 0, 4, 16, 128, 2, 4, 0, 32, 256, 8, 16, 32, 0, 512, 64, 128, 256, 512, 0 }; const unsigned int igraph_i_isoclass_6u_idx[] = { 0, 1, 2, 8, 64, 1024, 1, 0, 4, 16, 128, 2048, 2, 4, 0, 32, 256, 4096, 8, 16, 32, 0, 512, 8192, 64, 128, 256, 512, 0, 16384, 1024, 2048, 4096, 8192, 16384, 0 }; const unsigned int igraph_i_isoclass2_3[] = { 0, 1, 1, 2, 1, 3, 4, 5, 1, 4, 6, 7, 2, 5, 7, 8, 1, 4, 3, 5, 6, 9, 9, 10, 4, 11, 9, 12, 7, 12, 13, 14, 1, 6, 4, 7, 4, 9, 11, 12, 3, 9, 9, 13, 5, 10, 12, 14, 2, 7, 5, 8, 7, 13, 12, 14, 5, 12, 10, 14, 8, 14, 14, 15 }; const unsigned int igraph_i_isoclass2_3u[] = { 0, 1, 1, 2, 1, 2, 2, 3 }; const unsigned int igraph_i_isoclass2_4u[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 4, 5, 6, 6, 7, 1, 2, 5, 6, 2, 4, 6, 7, 2, 3, 6, 7, 6, 7, 8, 9, 1, 5, 2, 6, 2, 6, 4, 7, 2, 6, 3, 7, 6, 8, 7, 9, 2, 6, 6, 8, 3, 7, 7, 9, 4, 7, 7, 9, 7, 9, 9, 10 }; const unsigned int igraph_i_isoclass2_4[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 4, 5, 6, 5, 6, 7, 8, 1, 5, 9, 10, 11, 12, 13, 14, 2, 6, 10, 15, 12, 16, 17, 18, 1, 5, 11, 12, 9, 10, 13, 14, 2, 6, 12, 16, 10, 15, 17, 18, 2, 7, 13, 17, 13, 17, 19, 20, 3, 8, 14, 18, 14, 18, 20, 21, 1, 5, 4, 6, 5, 7, 6, 8, 9, 22, 22, 23, 24, 25, 25, 26, 5, 27, 22, 28, 29, 30, 31, 32, 10, 28, 33, 34, 35, 36, 37, 38, 11, 29, 39, 40, 41, 42, 43, 44, 13, 31, 45, 46, 47, 48, 49, 50, 12, 30, 45, 51, 52, 53, 54, 55, 14, 32, 56, 57, 58, 59, 60, 61, 1, 9, 5, 10, 11, 13, 12, 14, 5, 22, 27, 28, 29, 31, 30, 32, 4, 22, 22, 33, 39, 45, 45, 56, 6, 23, 28, 34, 40, 46, 51, 57, 5, 24, 29, 35, 41, 47, 52, 58, 7, 25, 30, 36, 42, 48, 53, 59, 6, 25, 31, 37, 43, 49, 54, 60, 8, 26, 32, 38, 44, 50, 55, 61, 2, 10, 6, 15, 12, 17, 16, 18, 10, 33, 28, 34, 35, 37, 36, 38, 6, 28, 23, 34, 40, 51, 46, 57, 15, 34, 34, 62, 63, 64, 64, 65, 12, 35, 40, 63, 66, 67, 68, 69, 17, 37, 51, 64, 67, 70, 71, 72, 16, 36, 46, 64, 68, 71, 73, 74, 18, 38, 57, 65, 69, 72, 74, 75, 1, 11, 5, 12, 9, 13, 10, 14, 11, 39, 29, 40, 41, 43, 42, 44, 5, 29, 24, 35, 41, 52, 47, 58, 12, 40, 35, 63, 66, 68, 67, 69, 9, 41, 41, 66, 76, 77, 77, 78, 13, 43, 52, 68, 77, 79, 80, 81, 10, 42, 47, 67, 77, 80, 82, 83, 14, 44, 58, 69, 78, 81, 83, 84, 2, 12, 6, 16, 10, 17, 15, 18, 13, 45, 31, 46, 47, 49, 48, 50, 7, 30, 25, 36, 42, 53, 48, 59, 17, 51, 37, 64, 67, 71, 70, 72, 13, 52, 43, 68, 77, 80, 79, 81, 19, 54, 54, 73, 82, 85, 85, 86, 17, 53, 49, 71, 80, 87, 85, 88, 20, 55, 60, 74, 83, 88, 89, 90, 2, 13, 7, 17, 13, 19, 17, 20, 12, 45, 30, 51, 52, 54, 53, 55, 6, 31, 25, 37, 43, 54, 49, 60, 16, 46, 36, 64, 68, 73, 71, 74, 10, 47, 42, 67, 77, 82, 80, 83, 17, 49, 53, 71, 80, 85, 87, 88, 15, 48, 48, 70, 79, 85, 85, 89, 18, 50, 59, 72, 81, 86, 88, 90, 3, 14, 8, 18, 14, 20, 18, 21, 14, 56, 32, 57, 58, 60, 59, 61, 8, 32, 26, 38, 44, 55, 50, 61, 18, 57, 38, 65, 69, 74, 72, 75, 14, 58, 44, 69, 78, 83, 81, 84, 20, 60, 55, 74, 83, 89, 88, 90, 18, 59, 50, 72, 81, 88, 86, 90, 21, 61, 61, 75, 84, 90, 90, 91, 1, 5, 5, 7, 4, 6, 6, 8, 9, 22, 24, 25, 22, 23, 25, 26, 11, 29, 41, 42, 39, 40, 43, 44, 13, 31, 47, 48, 45, 46, 49, 50, 5, 27, 29, 30, 22, 28, 31, 32, 10, 28, 35, 36, 33, 34, 37, 38, 12, 30, 52, 53, 45, 51, 54, 55, 14, 32, 58, 59, 56, 57, 60, 61, 9, 24, 22, 25, 22, 25, 23, 26, 76, 92, 92, 93, 92, 93, 93, 94, 41, 95, 96, 97, 98, 99, 100, 101, 77, 102, 103, 104, 105, 106, 107, 108, 41, 95, 98, 99, 96, 97, 100, 101, 77, 102, 105, 106, 103, 104, 107, 108, 66, 109, 110, 111, 110, 111, 112, 113, 78, 114, 115, 116, 115, 116, 117, 118, 11, 41, 29, 42, 39, 43, 40, 44, 41, 96, 95, 97, 98, 100, 99, 101, 39, 98, 98, 119, 120, 121, 121, 122, 43, 100, 123, 124, 121, 125, 126, 127, 29, 95, 128, 129, 98, 123, 130, 131, 42, 97, 129, 132, 119, 124, 133, 134, 40, 99, 130, 133, 121, 126, 135, 136, 44, 101, 131, 134, 122, 127, 136, 137, 13, 47, 31, 48, 45, 49, 46, 50, 77, 103, 102, 104, 105, 107, 106, 108, 43, 123, 100, 124, 121, 126, 125, 127, 79, 138, 138, 139, 140, 141, 141, 142, 52, 143, 130, 144, 110, 145, 146, 147, 80, 148, 149, 150, 151, 152, 153, 154, 68, 155, 146, 156, 157, 158, 159, 160, 81, 161, 162, 163, 164, 165, 166, 167, 5, 29, 27, 30, 22, 31, 28, 32, 41, 98, 95, 99, 96, 100, 97, 101, 29, 128, 95, 129, 98, 130, 123, 131, 52, 130, 143, 144, 110, 146, 145, 147, 24, 95, 95, 109, 92, 102, 102, 114, 47, 123, 143, 155, 103, 138, 148, 161, 35, 129, 143, 168, 105, 149, 169, 170, 58, 131, 171, 172, 115, 162, 173, 174, 10, 35, 28, 36, 33, 37, 34, 38, 77, 105, 102, 106, 103, 107, 104, 108, 42, 129, 97, 132, 119, 133, 124, 134, 80, 149, 148, 150, 151, 153, 152, 154, 47, 143, 123, 155, 103, 148, 138, 161, 82, 169, 169, 175, 176, 177, 177, 178, 67, 168, 145, 179, 151, 180, 181, 182, 83, 170, 173, 183, 184, 185, 186, 187, 12, 52, 30, 53, 45, 54, 51, 55, 66, 110, 109, 111, 110, 112, 111, 113, 40, 130, 99, 133, 121, 135, 126, 136, 68, 146, 155, 156, 157, 159, 158, 160, 35, 143, 129, 168, 105, 169, 149, 170, 67, 145, 168, 179, 151, 181, 180, 182, 63, 144, 144, 188, 140, 189, 189, 190, 69, 147, 172, 191, 164, 192, 193, 194, 14, 58, 32, 59, 56, 60, 57, 61, 78, 115, 114, 116, 115, 117, 116, 118, 44, 131, 101, 134, 122, 136, 127, 137, 81, 162, 161, 163, 164, 166, 165, 167, 58, 171, 131, 172, 115, 173, 162, 174, 83, 173, 170, 183, 184, 186, 185, 187, 69, 172, 147, 191, 164, 193, 192, 194, 84, 174, 174, 195, 196, 197, 197, 198, 1, 9, 11, 13, 5, 10, 12, 14, 5, 22, 29, 31, 27, 28, 30, 32, 5, 24, 41, 47, 29, 35, 52, 58, 7, 25, 42, 48, 30, 36, 53, 59, 4, 22, 39, 45, 22, 33, 45, 56, 6, 23, 40, 46, 28, 34, 51, 57, 6, 25, 43, 49, 31, 37, 54, 60, 8, 26, 44, 50, 32, 38, 55, 61, 11, 41, 39, 43, 29, 42, 40, 44, 41, 96, 98, 100, 95, 97, 99, 101, 29, 95, 98, 123, 128, 129, 130, 131, 42, 97, 119, 124, 129, 132, 133, 134, 39, 98, 120, 121, 98, 119, 121, 122, 43, 100, 121, 125, 123, 124, 126, 127, 40, 99, 121, 126, 130, 133, 135, 136, 44, 101, 122, 127, 131, 134, 136, 137, 9, 76, 41, 77, 41, 77, 66, 78, 24, 92, 95, 102, 95, 102, 109, 114, 22, 92, 96, 103, 98, 105, 110, 115, 25, 93, 97, 104, 99, 106, 111, 116, 22, 92, 98, 105, 96, 103, 110, 115, 25, 93, 99, 106, 97, 104, 111, 116, 23, 93, 100, 107, 100, 107, 112, 117, 26, 94, 101, 108, 101, 108, 113, 118, 13, 77, 43, 79, 52, 80, 68, 81, 47, 103, 123, 138, 143, 148, 155, 161, 31, 102, 100, 138, 130, 149, 146, 162, 48, 104, 124, 139, 144, 150, 156, 163, 45, 105, 121, 140, 110, 151, 157, 164, 49, 107, 126, 141, 145, 152, 158, 165, 46, 106, 125, 141, 146, 153, 159, 166, 50, 108, 127, 142, 147, 154, 160, 167, 5, 41, 29, 52, 24, 47, 35, 58, 29, 98, 128, 130, 95, 123, 129, 131, 27, 95, 95, 143, 95, 143, 143, 171, 30, 99, 129, 144, 109, 155, 168, 172, 22, 96, 98, 110, 92, 103, 105, 115, 31, 100, 130, 146, 102, 138, 149, 162, 28, 97, 123, 145, 102, 148, 169, 173, 32, 101, 131, 147, 114, 161, 170, 174, 12, 66, 40, 68, 35, 67, 63, 69, 52, 110, 130, 146, 143, 145, 144, 147, 30, 109, 99, 155, 129, 168, 144, 172, 53, 111, 133, 156, 168, 179, 188, 191, 45, 110, 121, 157, 105, 151, 140, 164, 54, 112, 135, 159, 169, 181, 189, 192, 51, 111, 126, 158, 149, 180, 189, 193, 55, 113, 136, 160, 170, 182, 190, 194, 10, 77, 42, 80, 47, 82, 67, 83, 35, 105, 129, 149, 143, 169, 168, 170, 28, 102, 97, 148, 123, 169, 145, 173, 36, 106, 132, 150, 155, 175, 179, 183, 33, 103, 119, 151, 103, 176, 151, 184, 37, 107, 133, 153, 148, 177, 180, 185, 34, 104, 124, 152, 138, 177, 181, 186, 38, 108, 134, 154, 161, 178, 182, 187, 14, 78, 44, 81, 58, 83, 69, 84, 58, 115, 131, 162, 171, 173, 172, 174, 32, 114, 101, 161, 131, 170, 147, 174, 59, 116, 134, 163, 172, 183, 191, 195, 56, 115, 122, 164, 115, 184, 164, 196, 60, 117, 136, 166, 173, 186, 193, 197, 57, 116, 127, 165, 162, 185, 192, 197, 61, 118, 137, 167, 174, 187, 194, 198, 2, 10, 12, 17, 6, 15, 16, 18, 10, 33, 35, 37, 28, 34, 36, 38, 12, 35, 66, 67, 40, 63, 68, 69, 17, 37, 67, 70, 51, 64, 71, 72, 6, 28, 40, 51, 23, 34, 46, 57, 15, 34, 63, 64, 34, 62, 64, 65, 16, 36, 68, 71, 46, 64, 73, 74, 18, 38, 69, 72, 57, 65, 74, 75, 13, 47, 45, 49, 31, 48, 46, 50, 77, 103, 105, 107, 102, 104, 106, 108, 52, 143, 110, 145, 130, 144, 146, 147, 80, 148, 151, 152, 149, 150, 153, 154, 43, 123, 121, 126, 100, 124, 125, 127, 79, 138, 140, 141, 138, 139, 141, 142, 68, 155, 157, 158, 146, 156, 159, 160, 81, 161, 164, 165, 162, 163, 166, 167, 13, 77, 52, 80, 43, 79, 68, 81, 47, 103, 143, 148, 123, 138, 155, 161, 45, 105, 110, 151, 121, 140, 157, 164, 49, 107, 145, 152, 126, 141, 158, 165, 31, 102, 130, 149, 100, 138, 146, 162, 48, 104, 144, 150, 124, 139, 156, 163, 46, 106, 146, 153, 125, 141, 159, 166, 50, 108, 147, 154, 127, 142, 160, 167, 19, 82, 54, 85, 54, 85, 73, 86, 82, 176, 169, 177, 169, 177, 175, 178, 54, 169, 112, 181, 135, 189, 159, 192, 85, 177, 181, 199, 189, 200, 201, 202, 54, 169, 135, 189, 112, 181, 159, 192, 85, 177, 189, 200, 181, 199, 201, 202, 73, 175, 159, 201, 159, 201, 203, 204, 86, 178, 192, 202, 192, 202, 204, 205, 7, 42, 30, 53, 25, 48, 36, 59, 42, 119, 129, 133, 97, 124, 132, 134, 30, 129, 109, 168, 99, 144, 155, 172, 53, 133, 168, 188, 111, 156, 179, 191, 25, 97, 99, 111, 93, 104, 106, 116, 48, 124, 144, 156, 104, 139, 150, 163, 36, 132, 155, 179, 106, 150, 175, 183, 59, 134, 172, 191, 116, 163, 183, 195, 17, 67, 51, 71, 37, 70, 64, 72, 80, 151, 149, 153, 148, 152, 150, 154, 53, 168, 111, 179, 133, 188, 156, 191, 87, 180, 180, 206, 180, 206, 206, 207, 49, 145, 126, 158, 107, 152, 141, 165, 85, 181, 189, 201, 177, 199, 200, 202, 71, 179, 158, 208, 153, 206, 201, 209, 88, 182, 193, 209, 185, 210, 211, 212, 17, 80, 53, 87, 49, 85, 71, 88, 67, 151, 168, 180, 145, 181, 179, 182, 51, 149, 111, 180, 126, 189, 158, 193, 71, 153, 179, 206, 158, 201, 208, 209, 37, 148, 133, 180, 107, 177, 153, 185, 70, 152, 188, 206, 152, 199, 206, 210, 64, 150, 156, 206, 141, 200, 201, 211, 72, 154, 191, 207, 165, 202, 209, 212, 20, 83, 55, 88, 60, 89, 74, 90, 83, 184, 170, 185, 173, 186, 183, 187, 55, 170, 113, 182, 136, 190, 160, 194, 88, 185, 182, 210, 193, 211, 209, 212, 60, 173, 136, 193, 117, 186, 166, 197, 89, 186, 190, 211, 186, 213, 211, 214, 74, 183, 160, 209, 166, 211, 204, 215, 90, 187, 194, 212, 197, 214, 215, 216, 1, 11, 9, 13, 5, 12, 10, 14, 11, 39, 41, 43, 29, 40, 42, 44, 9, 41, 76, 77, 41, 66, 77, 78, 13, 43, 77, 79, 52, 68, 80, 81, 5, 29, 41, 52, 24, 35, 47, 58, 12, 40, 66, 68, 35, 63, 67, 69, 10, 42, 77, 80, 47, 67, 82, 83, 14, 44, 78, 81, 58, 69, 83, 84, 5, 29, 22, 31, 27, 30, 28, 32, 41, 98, 96, 100, 95, 99, 97, 101, 24, 95, 92, 102, 95, 109, 102, 114, 47, 123, 103, 138, 143, 155, 148, 161, 29, 128, 98, 130, 95, 129, 123, 131, 52, 130, 110, 146, 143, 144, 145, 147, 35, 129, 105, 149, 143, 168, 169, 170, 58, 131, 115, 162, 171, 172, 173, 174, 5, 41, 24, 47, 29, 52, 35, 58, 29, 98, 95, 123, 128, 130, 129, 131, 22, 96, 92, 103, 98, 110, 105, 115, 31, 100, 102, 138, 130, 146, 149, 162, 27, 95, 95, 143, 95, 143, 143, 171, 30, 99, 109, 155, 129, 144, 168, 172, 28, 97, 102, 148, 123, 145, 169, 173, 32, 101, 114, 161, 131, 147, 170, 174, 7, 42, 25, 48, 30, 53, 36, 59, 42, 119, 97, 124, 129, 133, 132, 134, 25, 97, 93, 104, 99, 111, 106, 116, 48, 124, 104, 139, 144, 156, 150, 163, 30, 129, 99, 144, 109, 168, 155, 172, 53, 133, 111, 156, 168, 188, 179, 191, 36, 132, 106, 150, 155, 179, 175, 183, 59, 134, 116, 163, 172, 191, 183, 195, 4, 39, 22, 45, 22, 45, 33, 56, 39, 120, 98, 121, 98, 121, 119, 122, 22, 98, 92, 105, 96, 110, 103, 115, 45, 121, 105, 140, 110, 157, 151, 164, 22, 98, 96, 110, 92, 105, 103, 115, 45, 121, 110, 157, 105, 140, 151, 164, 33, 119, 103, 151, 103, 151, 176, 184, 56, 122, 115, 164, 115, 164, 184, 196, 6, 40, 23, 46, 28, 51, 34, 57, 43, 121, 100, 125, 123, 126, 124, 127, 25, 99, 93, 106, 97, 111, 104, 116, 49, 126, 107, 141, 145, 158, 152, 165, 31, 130, 100, 146, 102, 149, 138, 162, 54, 135, 112, 159, 169, 189, 181, 192, 37, 133, 107, 153, 148, 180, 177, 185, 60, 136, 117, 166, 173, 193, 186, 197, 6, 43, 25, 49, 31, 54, 37, 60, 40, 121, 99, 126, 130, 135, 133, 136, 23, 100, 93, 107, 100, 112, 107, 117, 46, 125, 106, 141, 146, 159, 153, 166, 28, 123, 97, 145, 102, 169, 148, 173, 51, 126, 111, 158, 149, 189, 180, 193, 34, 124, 104, 152, 138, 181, 177, 186, 57, 127, 116, 165, 162, 192, 185, 197, 8, 44, 26, 50, 32, 55, 38, 61, 44, 122, 101, 127, 131, 136, 134, 137, 26, 101, 94, 108, 101, 113, 108, 118, 50, 127, 108, 142, 147, 160, 154, 167, 32, 131, 101, 147, 114, 170, 161, 174, 55, 136, 113, 160, 170, 190, 182, 194, 38, 134, 108, 154, 161, 182, 178, 187, 61, 137, 118, 167, 174, 194, 187, 198, 2, 12, 10, 17, 6, 16, 15, 18, 13, 45, 47, 49, 31, 46, 48, 50, 13, 52, 77, 80, 43, 68, 79, 81, 19, 54, 82, 85, 54, 73, 85, 86, 7, 30, 42, 53, 25, 36, 48, 59, 17, 51, 67, 71, 37, 64, 70, 72, 17, 53, 80, 87, 49, 71, 85, 88, 20, 55, 83, 88, 60, 74, 89, 90, 10, 35, 33, 37, 28, 36, 34, 38, 77, 105, 103, 107, 102, 106, 104, 108, 47, 143, 103, 148, 123, 155, 138, 161, 82, 169, 176, 177, 169, 175, 177, 178, 42, 129, 119, 133, 97, 132, 124, 134, 80, 149, 151, 153, 148, 150, 152, 154, 67, 168, 151, 180, 145, 179, 181, 182, 83, 170, 184, 185, 173, 183, 186, 187, 12, 66, 35, 67, 40, 68, 63, 69, 52, 110, 143, 145, 130, 146, 144, 147, 45, 110, 105, 151, 121, 157, 140, 164, 54, 112, 169, 181, 135, 159, 189, 192, 30, 109, 129, 168, 99, 155, 144, 172, 53, 111, 168, 179, 133, 156, 188, 191, 51, 111, 149, 180, 126, 158, 189, 193, 55, 113, 170, 182, 136, 160, 190, 194, 17, 67, 37, 70, 51, 71, 64, 72, 80, 151, 148, 152, 149, 153, 150, 154, 49, 145, 107, 152, 126, 158, 141, 165, 85, 181, 177, 199, 189, 201, 200, 202, 53, 168, 133, 188, 111, 179, 156, 191, 87, 180, 180, 206, 180, 206, 206, 207, 71, 179, 153, 206, 158, 208, 201, 209, 88, 182, 185, 210, 193, 209, 211, 212, 6, 40, 28, 51, 23, 46, 34, 57, 43, 121, 123, 126, 100, 125, 124, 127, 31, 130, 102, 149, 100, 146, 138, 162, 54, 135, 169, 189, 112, 159, 181, 192, 25, 99, 97, 111, 93, 106, 104, 116, 49, 126, 145, 158, 107, 141, 152, 165, 37, 133, 148, 180, 107, 153, 177, 185, 60, 136, 173, 193, 117, 166, 186, 197, 15, 63, 34, 64, 34, 64, 62, 65, 79, 140, 138, 141, 138, 141, 139, 142, 48, 144, 104, 150, 124, 156, 139, 163, 85, 189, 177, 200, 181, 201, 199, 202, 48, 144, 124, 156, 104, 150, 139, 163, 85, 189, 181, 201, 177, 200, 199, 202, 70, 188, 152, 206, 152, 206, 199, 210, 89, 190, 186, 211, 186, 211, 213, 214, 16, 68, 36, 71, 46, 73, 64, 74, 68, 157, 155, 158, 146, 159, 156, 160, 46, 146, 106, 153, 125, 159, 141, 166, 73, 159, 175, 201, 159, 203, 201, 204, 36, 155, 132, 179, 106, 175, 150, 183, 71, 158, 179, 208, 153, 201, 206, 209, 64, 156, 150, 206, 141, 201, 200, 211, 74, 160, 183, 209, 166, 204, 211, 215, 18, 69, 38, 72, 57, 74, 65, 75, 81, 164, 161, 165, 162, 166, 163, 167, 50, 147, 108, 154, 127, 160, 142, 167, 86, 192, 178, 202, 192, 204, 202, 205, 59, 172, 134, 191, 116, 183, 163, 195, 88, 193, 182, 209, 185, 211, 210, 212, 72, 191, 154, 207, 165, 209, 202, 212, 90, 194, 187, 212, 197, 215, 214, 216, 2, 13, 13, 19, 7, 17, 17, 20, 12, 45, 52, 54, 30, 51, 53, 55, 10, 47, 77, 82, 42, 67, 80, 83, 17, 49, 80, 85, 53, 71, 87, 88, 6, 31, 43, 54, 25, 37, 49, 60, 16, 46, 68, 73, 36, 64, 71, 74, 15, 48, 79, 85, 48, 70, 85, 89, 18, 50, 81, 86, 59, 72, 88, 90, 12, 52, 45, 54, 30, 53, 51, 55, 66, 110, 110, 112, 109, 111, 111, 113, 35, 143, 105, 169, 129, 168, 149, 170, 67, 145, 151, 181, 168, 179, 180, 182, 40, 130, 121, 135, 99, 133, 126, 136, 68, 146, 157, 159, 155, 156, 158, 160, 63, 144, 140, 189, 144, 188, 189, 190, 69, 147, 164, 192, 172, 191, 193, 194, 10, 77, 47, 82, 42, 80, 67, 83, 35, 105, 143, 169, 129, 149, 168, 170, 33, 103, 103, 176, 119, 151, 151, 184, 37, 107, 148, 177, 133, 153, 180, 185, 28, 102, 123, 169, 97, 148, 145, 173, 36, 106, 155, 175, 132, 150, 179, 183, 34, 104, 138, 177, 124, 152, 181, 186, 38, 108, 161, 178, 134, 154, 182, 187, 17, 80, 49, 85, 53, 87, 71, 88, 67, 151, 145, 181, 168, 180, 179, 182, 37, 148, 107, 177, 133, 180, 153, 185, 70, 152, 152, 199, 188, 206, 206, 210, 51, 149, 126, 189, 111, 180, 158, 193, 71, 153, 158, 201, 179, 206, 208, 209, 64, 150, 141, 200, 156, 206, 201, 211, 72, 154, 165, 202, 191, 207, 209, 212, 6, 43, 31, 54, 25, 49, 37, 60, 40, 121, 130, 135, 99, 126, 133, 136, 28, 123, 102, 169, 97, 145, 148, 173, 51, 126, 149, 189, 111, 158, 180, 193, 23, 100, 100, 112, 93, 107, 107, 117, 46, 125, 146, 159, 106, 141, 153, 166, 34, 124, 138, 181, 104, 152, 177, 186, 57, 127, 162, 192, 116, 165, 185, 197, 16, 68, 46, 73, 36, 71, 64, 74, 68, 157, 146, 159, 155, 158, 156, 160, 36, 155, 106, 175, 132, 179, 150, 183, 71, 158, 153, 201, 179, 208, 206, 209, 46, 146, 125, 159, 106, 153, 141, 166, 73, 159, 159, 203, 175, 201, 201, 204, 64, 156, 141, 201, 150, 206, 200, 211, 74, 160, 166, 204, 183, 209, 211, 215, 15, 79, 48, 85, 48, 85, 70, 89, 63, 140, 144, 189, 144, 189, 188, 190, 34, 138, 104, 177, 124, 181, 152, 186, 64, 141, 150, 200, 156, 201, 206, 211, 34, 138, 124, 181, 104, 177, 152, 186, 64, 141, 156, 201, 150, 200, 206, 211, 62, 139, 139, 199, 139, 199, 199, 213, 65, 142, 163, 202, 163, 202, 210, 214, 18, 81, 50, 86, 59, 88, 72, 90, 69, 164, 147, 192, 172, 193, 191, 194, 38, 161, 108, 178, 134, 182, 154, 187, 72, 165, 154, 202, 191, 209, 207, 212, 57, 162, 127, 192, 116, 185, 165, 197, 74, 166, 160, 204, 183, 211, 209, 215, 65, 163, 142, 202, 163, 210, 202, 214, 75, 167, 167, 205, 195, 212, 212, 216, 3, 14, 14, 20, 8, 18, 18, 21, 14, 56, 58, 60, 32, 57, 59, 61, 14, 58, 78, 83, 44, 69, 81, 84, 20, 60, 83, 89, 55, 74, 88, 90, 8, 32, 44, 55, 26, 38, 50, 61, 18, 57, 69, 74, 38, 65, 72, 75, 18, 59, 81, 88, 50, 72, 86, 90, 21, 61, 84, 90, 61, 75, 90, 91, 14, 58, 56, 60, 32, 59, 57, 61, 78, 115, 115, 117, 114, 116, 116, 118, 58, 171, 115, 173, 131, 172, 162, 174, 83, 173, 184, 186, 170, 183, 185, 187, 44, 131, 122, 136, 101, 134, 127, 137, 81, 162, 164, 166, 161, 163, 165, 167, 69, 172, 164, 193, 147, 191, 192, 194, 84, 174, 196, 197, 174, 195, 197, 198, 14, 78, 58, 83, 44, 81, 69, 84, 58, 115, 171, 173, 131, 162, 172, 174, 56, 115, 115, 184, 122, 164, 164, 196, 60, 117, 173, 186, 136, 166, 193, 197, 32, 114, 131, 170, 101, 161, 147, 174, 59, 116, 172, 183, 134, 163, 191, 195, 57, 116, 162, 185, 127, 165, 192, 197, 61, 118, 174, 187, 137, 167, 194, 198, 20, 83, 60, 89, 55, 88, 74, 90, 83, 184, 173, 186, 170, 185, 183, 187, 60, 173, 117, 186, 136, 193, 166, 197, 89, 186, 186, 213, 190, 211, 211, 214, 55, 170, 136, 190, 113, 182, 160, 194, 88, 185, 193, 211, 182, 210, 209, 212, 74, 183, 166, 211, 160, 209, 204, 215, 90, 187, 197, 214, 194, 212, 215, 216, 8, 44, 32, 55, 26, 50, 38, 61, 44, 122, 131, 136, 101, 127, 134, 137, 32, 131, 114, 170, 101, 147, 161, 174, 55, 136, 170, 190, 113, 160, 182, 194, 26, 101, 101, 113, 94, 108, 108, 118, 50, 127, 147, 160, 108, 142, 154, 167, 38, 134, 161, 182, 108, 154, 178, 187, 61, 137, 174, 194, 118, 167, 187, 198, 18, 69, 57, 74, 38, 72, 65, 75, 81, 164, 162, 166, 161, 165, 163, 167, 59, 172, 116, 183, 134, 191, 163, 195, 88, 193, 185, 211, 182, 209, 210, 212, 50, 147, 127, 160, 108, 154, 142, 167, 86, 192, 192, 204, 178, 202, 202, 205, 72, 191, 165, 209, 154, 207, 202, 212, 90, 194, 197, 215, 187, 212, 214, 216, 18, 81, 59, 88, 50, 86, 72, 90, 69, 164, 172, 193, 147, 192, 191, 194, 57, 162, 116, 185, 127, 192, 165, 197, 74, 166, 183, 211, 160, 204, 209, 215, 38, 161, 134, 182, 108, 178, 154, 187, 72, 165, 191, 209, 154, 202, 207, 212, 65, 163, 163, 210, 142, 202, 202, 214, 75, 167, 195, 212, 167, 205, 212, 216, 21, 84, 61, 90, 61, 90, 75, 91, 84, 196, 174, 197, 174, 197, 195, 198, 61, 174, 118, 187, 137, 194, 167, 198, 90, 197, 187, 214, 194, 215, 212, 216, 61, 174, 137, 194, 118, 187, 167, 198, 90, 197, 194, 215, 187, 214, 212, 216, 75, 195, 167, 212, 167, 212, 205, 216, 91, 198, 198, 216, 198, 216, 216, 217 }; const unsigned int igraph_i_isoclass2_5u[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 4, 5, 6, 6, 7, 1, 2, 5, 6, 2, 4, 6, 7, 2, 3, 6, 7, 6, 7, 8, 9, 1, 5, 2, 6, 2, 6, 4, 7, 2, 6, 3, 7, 6, 8, 7, 9, 2, 6, 6, 8, 3, 7, 7, 9, 4, 7, 7, 9, 7, 9, 9, 10, 1, 2, 2, 4, 5, 6, 6, 7, 2, 4, 4, 11, 12, 13, 13, 14, 5, 6, 12, 13, 12, 13, 15, 16, 6, 7, 13, 14, 15, 16, 17, 18, 5, 12, 6, 13, 12, 15, 13, 16, 6, 13, 7, 14, 15, 17, 16, 18, 12, 15, 15, 17, 19, 20, 20, 21, 13, 16, 16, 18, 20, 21, 21, 22, 1, 2, 5, 6, 2, 4, 6, 7, 5, 6, 12, 13, 12, 13, 15, 16, 2, 4, 12, 13, 4, 11, 13, 14, 6, 7, 15, 16, 13, 14, 17, 18, 5, 12, 12, 15, 6, 13, 13, 16, 12, 15, 19, 20, 15, 17, 20, 21, 6, 13, 15, 17, 7, 14, 16, 18, 13, 16, 20, 21, 16, 18, 21, 22, 2, 3, 6, 7, 6, 7, 8, 9, 6, 7, 13, 14, 15, 16, 17, 18, 6, 7, 15, 16, 13, 14, 17, 18, 8, 9, 17, 18, 17, 18, 23, 24, 12, 19, 15, 20, 15, 20, 17, 21, 15, 20, 20, 25, 26, 27, 27, 28, 15, 20, 26, 27, 20, 25, 27, 28, 17, 21, 27, 28, 27, 28, 29, 30, 1, 5, 2, 6, 2, 6, 4, 7, 5, 12, 6, 13, 12, 15, 13, 16, 5, 12, 12, 15, 6, 13, 13, 16, 12, 19, 15, 20, 15, 20, 17, 21, 2, 12, 4, 13, 4, 13, 11, 14, 6, 15, 7, 16, 13, 17, 14, 18, 6, 15, 13, 17, 7, 16, 14, 18, 13, 20, 16, 21, 16, 21, 18, 22, 2, 6, 3, 7, 6, 8, 7, 9, 6, 13, 7, 14, 15, 17, 16, 18, 12, 15, 19, 20, 15, 17, 20, 21, 15, 20, 20, 25, 26, 27, 27, 28, 6, 15, 7, 16, 13, 17, 14, 18, 8, 17, 9, 18, 17, 23, 18, 24, 15, 26, 20, 27, 20, 27, 25, 28, 17, 27, 21, 28, 27, 29, 28, 30, 2, 6, 6, 8, 3, 7, 7, 9, 12, 15, 15, 17, 19, 20, 20, 21, 6, 13, 15, 17, 7, 14, 16, 18, 15, 20, 26, 27, 20, 25, 27, 28, 6, 15, 13, 17, 7, 16, 14, 18, 15, 26, 20, 27, 20, 27, 25, 28, 8, 17, 17, 23, 9, 18, 18, 24, 17, 27, 27, 29, 21, 28, 28, 30, 4, 7, 7, 9, 7, 9, 9, 10, 13, 16, 16, 18, 20, 21, 21, 22, 13, 16, 20, 21, 16, 18, 21, 22, 17, 21, 27, 28, 27, 28, 29, 30, 13, 20, 16, 21, 16, 21, 18, 22, 17, 27, 21, 28, 27, 29, 28, 30, 17, 27, 27, 29, 21, 28, 28, 30, 23, 29, 29, 31, 29, 31, 31, 32, 1, 5, 5, 12, 5, 12, 12, 19, 2, 6, 6, 13, 12, 15, 15, 20, 2, 6, 12, 15, 6, 13, 15, 20, 4, 7, 13, 16, 13, 16, 17, 21, 2, 12, 6, 15, 6, 15, 13, 20, 4, 13, 7, 16, 13, 17, 16, 21, 4, 13, 13, 17, 7, 16, 16, 21, 11, 14, 14, 18, 14, 18, 18, 22, 2, 6, 6, 13, 12, 15, 15, 20, 3, 7, 7, 14, 19, 20, 20, 25, 6, 8, 15, 17, 15, 17, 26, 27, 7, 9, 16, 18, 20, 21, 27, 28, 6, 15, 8, 17, 15, 26, 17, 27, 7, 16, 9, 18, 20, 27, 21, 28, 13, 17, 17, 23, 20, 27, 27, 29, 14, 18, 18, 24, 25, 28, 28, 30, 2, 6, 12, 15, 6, 13, 15, 20, 6, 8, 15, 17, 15, 17, 26, 27, 3, 7, 19, 20, 7, 14, 20, 25, 7, 9, 20, 21, 16, 18, 27, 28, 6, 15, 15, 26, 8, 17, 17, 27, 13, 17, 20, 27, 17, 23, 27, 29, 7, 16, 20, 27, 9, 18, 21, 28, 14, 18, 25, 28, 18, 24, 28, 30, 4, 7, 13, 16, 13, 16, 17, 21, 7, 9, 16, 18, 20, 21, 27, 28, 7, 9, 20, 21, 16, 18, 27, 28, 9, 10, 21, 22, 21, 22, 29, 30, 13, 20, 17, 27, 17, 27, 23, 29, 16, 21, 21, 28, 27, 29, 29, 31, 16, 21, 27, 29, 21, 28, 29, 31, 18, 22, 28, 30, 28, 30, 31, 32, 2, 12, 6, 15, 6, 15, 13, 20, 6, 15, 8, 17, 15, 26, 17, 27, 6, 15, 15, 26, 8, 17, 17, 27, 13, 20, 17, 27, 17, 27, 23, 29, 3, 19, 7, 20, 7, 20, 14, 25, 7, 20, 9, 21, 16, 27, 18, 28, 7, 20, 16, 27, 9, 21, 18, 28, 14, 25, 18, 28, 18, 28, 24, 30, 4, 13, 7, 16, 13, 17, 16, 21, 7, 16, 9, 18, 20, 27, 21, 28, 13, 17, 20, 27, 17, 23, 27, 29, 16, 21, 21, 28, 27, 29, 29, 31, 7, 20, 9, 21, 16, 27, 18, 28, 9, 21, 10, 22, 21, 29, 22, 30, 16, 27, 21, 29, 21, 29, 28, 31, 18, 28, 22, 30, 28, 31, 30, 32, 4, 13, 13, 17, 7, 16, 16, 21, 13, 17, 17, 23, 20, 27, 27, 29, 7, 16, 20, 27, 9, 18, 21, 28, 16, 21, 27, 29, 21, 28, 29, 31, 7, 20, 16, 27, 9, 21, 18, 28, 16, 27, 21, 29, 21, 29, 28, 31, 9, 21, 21, 29, 10, 22, 22, 30, 18, 28, 28, 31, 22, 30, 30, 32, 11, 14, 14, 18, 14, 18, 18, 22, 14, 18, 18, 24, 25, 28, 28, 30, 14, 18, 25, 28, 18, 24, 28, 30, 18, 22, 28, 30, 28, 30, 31, 32, 14, 25, 18, 28, 18, 28, 24, 30, 18, 28, 22, 30, 28, 31, 30, 32, 18, 28, 28, 31, 22, 30, 30, 32, 24, 30, 30, 32, 30, 32, 32, 33 }; const unsigned int igraph_i_isoclass2_6u[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 4, 5, 6, 6, 7, 1, 2, 5, 6, 2, 4, 6, 7, 2, 3, 6, 7, 6, 7, 8, 9, 1, 5, 2, 6, 2, 6, 4, 7, 2, 6, 3, 7, 6, 8, 7, 9, 2, 6, 6, 8, 3, 7, 7, 9, 4, 7, 7, 9, 7, 9, 9, 10, 1, 2, 2, 4, 5, 6, 6, 7, 2, 4, 4, 11, 12, 13, 13, 14, 5, 6, 12, 13, 12, 13, 15, 16, 6, 7, 13, 14, 15, 16, 17, 18, 5, 12, 6, 13, 12, 15, 13, 16, 6, 13, 7, 14, 15, 17, 16, 18, 12, 15, 15, 17, 19, 20, 20, 21, 13, 16, 16, 18, 20, 21, 21, 22, 1, 2, 5, 6, 2, 4, 6, 7, 5, 6, 12, 13, 12, 13, 15, 16, 2, 4, 12, 13, 4, 11, 13, 14, 6, 7, 15, 16, 13, 14, 17, 18, 5, 12, 12, 15, 6, 13, 13, 16, 12, 15, 19, 20, 15, 17, 20, 21, 6, 13, 15, 17, 7, 14, 16, 18, 13, 16, 20, 21, 16, 18, 21, 22, 2, 3, 6, 7, 6, 7, 8, 9, 6, 7, 13, 14, 15, 16, 17, 18, 6, 7, 15, 16, 13, 14, 17, 18, 8, 9, 17, 18, 17, 18, 23, 24, 12, 19, 15, 20, 15, 20, 17, 21, 15, 20, 20, 25, 26, 27, 27, 28, 15, 20, 26, 27, 20, 25, 27, 28, 17, 21, 27, 28, 27, 28, 29, 30, 1, 5, 2, 6, 2, 6, 4, 7, 5, 12, 6, 13, 12, 15, 13, 16, 5, 12, 12, 15, 6, 13, 13, 16, 12, 19, 15, 20, 15, 20, 17, 21, 2, 12, 4, 13, 4, 13, 11, 14, 6, 15, 7, 16, 13, 17, 14, 18, 6, 15, 13, 17, 7, 16, 14, 18, 13, 20, 16, 21, 16, 21, 18, 22, 2, 6, 3, 7, 6, 8, 7, 9, 6, 13, 7, 14, 15, 17, 16, 18, 12, 15, 19, 20, 15, 17, 20, 21, 15, 20, 20, 25, 26, 27, 27, 28, 6, 15, 7, 16, 13, 17, 14, 18, 8, 17, 9, 18, 17, 23, 18, 24, 15, 26, 20, 27, 20, 27, 25, 28, 17, 27, 21, 28, 27, 29, 28, 30, 2, 6, 6, 8, 3, 7, 7, 9, 12, 15, 15, 17, 19, 20, 20, 21, 6, 13, 15, 17, 7, 14, 16, 18, 15, 20, 26, 27, 20, 25, 27, 28, 6, 15, 13, 17, 7, 16, 14, 18, 15, 26, 20, 27, 20, 27, 25, 28, 8, 17, 17, 23, 9, 18, 18, 24, 17, 27, 27, 29, 21, 28, 28, 30, 4, 7, 7, 9, 7, 9, 9, 10, 13, 16, 16, 18, 20, 21, 21, 22, 13, 16, 20, 21, 16, 18, 21, 22, 17, 21, 27, 28, 27, 28, 29, 30, 13, 20, 16, 21, 16, 21, 18, 22, 17, 27, 21, 28, 27, 29, 28, 30, 17, 27, 27, 29, 21, 28, 28, 30, 23, 29, 29, 31, 29, 31, 31, 32, 1, 5, 5, 12, 5, 12, 12, 19, 2, 6, 6, 13, 12, 15, 15, 20, 2, 6, 12, 15, 6, 13, 15, 20, 4, 7, 13, 16, 13, 16, 17, 21, 2, 12, 6, 15, 6, 15, 13, 20, 4, 13, 7, 16, 13, 17, 16, 21, 4, 13, 13, 17, 7, 16, 16, 21, 11, 14, 14, 18, 14, 18, 18, 22, 2, 6, 6, 13, 12, 15, 15, 20, 3, 7, 7, 14, 19, 20, 20, 25, 6, 8, 15, 17, 15, 17, 26, 27, 7, 9, 16, 18, 20, 21, 27, 28, 6, 15, 8, 17, 15, 26, 17, 27, 7, 16, 9, 18, 20, 27, 21, 28, 13, 17, 17, 23, 20, 27, 27, 29, 14, 18, 18, 24, 25, 28, 28, 30, 2, 6, 12, 15, 6, 13, 15, 20, 6, 8, 15, 17, 15, 17, 26, 27, 3, 7, 19, 20, 7, 14, 20, 25, 7, 9, 20, 21, 16, 18, 27, 28, 6, 15, 15, 26, 8, 17, 17, 27, 13, 17, 20, 27, 17, 23, 27, 29, 7, 16, 20, 27, 9, 18, 21, 28, 14, 18, 25, 28, 18, 24, 28, 30, 4, 7, 13, 16, 13, 16, 17, 21, 7, 9, 16, 18, 20, 21, 27, 28, 7, 9, 20, 21, 16, 18, 27, 28, 9, 10, 21, 22, 21, 22, 29, 30, 13, 20, 17, 27, 17, 27, 23, 29, 16, 21, 21, 28, 27, 29, 29, 31, 16, 21, 27, 29, 21, 28, 29, 31, 18, 22, 28, 30, 28, 30, 31, 32, 2, 12, 6, 15, 6, 15, 13, 20, 6, 15, 8, 17, 15, 26, 17, 27, 6, 15, 15, 26, 8, 17, 17, 27, 13, 20, 17, 27, 17, 27, 23, 29, 3, 19, 7, 20, 7, 20, 14, 25, 7, 20, 9, 21, 16, 27, 18, 28, 7, 20, 16, 27, 9, 21, 18, 28, 14, 25, 18, 28, 18, 28, 24, 30, 4, 13, 7, 16, 13, 17, 16, 21, 7, 16, 9, 18, 20, 27, 21, 28, 13, 17, 20, 27, 17, 23, 27, 29, 16, 21, 21, 28, 27, 29, 29, 31, 7, 20, 9, 21, 16, 27, 18, 28, 9, 21, 10, 22, 21, 29, 22, 30, 16, 27, 21, 29, 21, 29, 28, 31, 18, 28, 22, 30, 28, 31, 30, 32, 4, 13, 13, 17, 7, 16, 16, 21, 13, 17, 17, 23, 20, 27, 27, 29, 7, 16, 20, 27, 9, 18, 21, 28, 16, 21, 27, 29, 21, 28, 29, 31, 7, 20, 16, 27, 9, 21, 18, 28, 16, 27, 21, 29, 21, 29, 28, 31, 9, 21, 21, 29, 10, 22, 22, 30, 18, 28, 28, 31, 22, 30, 30, 32, 11, 14, 14, 18, 14, 18, 18, 22, 14, 18, 18, 24, 25, 28, 28, 30, 14, 18, 25, 28, 18, 24, 28, 30, 18, 22, 28, 30, 28, 30, 31, 32, 14, 25, 18, 28, 18, 28, 24, 30, 18, 28, 22, 30, 28, 31, 30, 32, 18, 28, 28, 31, 22, 30, 30, 32, 24, 30, 30, 32, 30, 32, 32, 33, 1, 2, 2, 4, 5, 6, 6, 7, 2, 4, 4, 11, 12, 13, 13, 14, 5, 6, 12, 13, 12, 13, 15, 16, 6, 7, 13, 14, 15, 16, 17, 18, 5, 12, 6, 13, 12, 15, 13, 16, 6, 13, 7, 14, 15, 17, 16, 18, 12, 15, 15, 17, 19, 20, 20, 21, 13, 16, 16, 18, 20, 21, 21, 22, 2, 4, 4, 11, 12, 13, 13, 14, 4, 11, 11, 34, 35, 36, 36, 37, 12, 13, 35, 36, 38, 39, 40, 41, 13, 14, 36, 37, 40, 41, 42, 43, 12, 35, 13, 36, 38, 40, 39, 41, 13, 36, 14, 37, 40, 42, 41, 43, 38, 40, 40, 42, 44, 45, 45, 46, 39, 41, 41, 43, 45, 46, 46, 47, 5, 6, 12, 13, 12, 13, 15, 16, 12, 13, 35, 36, 38, 39, 40, 41, 12, 13, 38, 39, 35, 36, 40, 41, 15, 16, 40, 41, 40, 41, 48, 49, 50, 51, 51, 52, 51, 52, 52, 53, 51, 52, 54, 55, 56, 57, 58, 59, 51, 52, 56, 57, 54, 55, 58, 59, 52, 53, 58, 59, 58, 59, 60, 61, 6, 7, 13, 14, 15, 16, 17, 18, 13, 14, 36, 37, 40, 41, 42, 43, 15, 16, 40, 41, 40, 41, 48, 49, 17, 18, 42, 43, 48, 49, 62, 63, 51, 54, 52, 55, 56, 58, 57, 59, 52, 55, 55, 64, 65, 66, 66, 67, 56, 58, 65, 66, 68, 69, 70, 71, 57, 59, 66, 67, 70, 71, 72, 73, 5, 12, 6, 13, 12, 15, 13, 16, 12, 35, 13, 36, 38, 40, 39, 41, 50, 51, 51, 52, 51, 52, 52, 53, 51, 54, 52, 55, 56, 58, 57, 59, 12, 38, 13, 39, 35, 40, 36, 41, 15, 40, 16, 41, 40, 48, 41, 49, 51, 56, 52, 57, 54, 58, 55, 59, 52, 58, 53, 59, 58, 60, 59, 61, 6, 13, 7, 14, 15, 17, 16, 18, 13, 36, 14, 37, 40, 42, 41, 43, 51, 52, 54, 55, 56, 57, 58, 59, 52, 55, 55, 64, 65, 66, 66, 67, 15, 40, 16, 41, 40, 48, 41, 49, 17, 42, 18, 43, 48, 62, 49, 63, 56, 65, 58, 66, 68, 70, 69, 71, 57, 66, 59, 67, 70, 72, 71, 73, 12, 15, 15, 17, 19, 20, 20, 21, 38, 40, 40, 42, 44, 45, 45, 46, 51, 52, 56, 57, 54, 55, 58, 59, 56, 58, 65, 66, 68, 69, 70, 71, 51, 56, 52, 57, 54, 58, 55, 59, 56, 65, 58, 66, 68, 70, 69, 71, 74, 75, 75, 76, 77, 78, 78, 79, 75, 80, 80, 81, 82, 83, 83, 84, 13, 16, 16, 18, 20, 21, 21, 22, 39, 41, 41, 43, 45, 46, 46, 47, 52, 53, 58, 59, 58, 59, 60, 61, 57, 59, 66, 67, 70, 71, 72, 73, 52, 58, 53, 59, 58, 60, 59, 61, 57, 66, 59, 67, 70, 72, 71, 73, 75, 80, 80, 81, 82, 83, 83, 84, 76, 81, 81, 85, 86, 87, 87, 88, 5, 12, 12, 35, 50, 51, 51, 54, 6, 13, 13, 36, 51, 52, 52, 55, 12, 15, 38, 40, 51, 52, 56, 58, 13, 16, 39, 41, 52, 53, 57, 59, 12, 38, 15, 40, 51, 56, 52, 58, 13, 39, 16, 41, 52, 57, 53, 59, 35, 40, 40, 48, 54, 58, 58, 60, 36, 41, 41, 49, 55, 59, 59, 61, 6, 13, 13, 36, 51, 52, 52, 55, 7, 14, 14, 37, 54, 55, 55, 64, 15, 17, 40, 42, 56, 57, 65, 66, 16, 18, 41, 43, 58, 59, 66, 67, 15, 40, 17, 42, 56, 65, 57, 66, 16, 41, 18, 43, 58, 66, 59, 67, 40, 48, 48, 62, 68, 70, 70, 72, 41, 49, 49, 63, 69, 71, 71, 73, 12, 15, 38, 40, 51, 52, 56, 58, 15, 17, 40, 42, 56, 57, 65, 66, 19, 20, 44, 45, 54, 55, 68, 69, 20, 21, 45, 46, 58, 59, 70, 71, 51, 56, 56, 65, 74, 75, 75, 80, 52, 57, 58, 66, 75, 76, 80, 81, 54, 58, 68, 70, 77, 78, 82, 83, 55, 59, 69, 71, 78, 79, 83, 84, 13, 16, 39, 41, 52, 53, 57, 59, 16, 18, 41, 43, 58, 59, 66, 67, 20, 21, 45, 46, 58, 59, 70, 71, 21, 22, 46, 47, 60, 61, 72, 73, 52, 58, 57, 66, 75, 80, 76, 81, 53, 59, 59, 67, 80, 81, 81, 85, 58, 60, 70, 72, 82, 83, 86, 87, 59, 61, 71, 73, 83, 84, 87, 88, 12, 38, 15, 40, 51, 56, 52, 58, 15, 40, 17, 42, 56, 65, 57, 66, 51, 56, 56, 65, 74, 75, 75, 80, 52, 58, 57, 66, 75, 80, 76, 81, 19, 44, 20, 45, 54, 68, 55, 69, 20, 45, 21, 46, 58, 70, 59, 71, 54, 68, 58, 70, 77, 82, 78, 83, 55, 69, 59, 71, 78, 83, 79, 84, 13, 39, 16, 41, 52, 57, 53, 59, 16, 41, 18, 43, 58, 66, 59, 67, 52, 57, 58, 66, 75, 76, 80, 81, 53, 59, 59, 67, 80, 81, 81, 85, 20, 45, 21, 46, 58, 70, 59, 71, 21, 46, 22, 47, 60, 72, 61, 73, 58, 70, 60, 72, 82, 86, 83, 87, 59, 71, 61, 73, 83, 87, 84, 88, 35, 40, 40, 48, 54, 58, 58, 60, 40, 48, 48, 62, 68, 70, 70, 72, 54, 58, 68, 70, 77, 78, 82, 83, 58, 60, 70, 72, 82, 83, 86, 87, 54, 68, 58, 70, 77, 82, 78, 83, 58, 70, 60, 72, 82, 86, 83, 87, 77, 82, 82, 86, 89, 90, 90, 91, 78, 83, 83, 87, 90, 91, 91, 92, 36, 41, 41, 49, 55, 59, 59, 61, 41, 49, 49, 63, 69, 71, 71, 73, 55, 59, 69, 71, 78, 79, 83, 84, 59, 61, 71, 73, 83, 84, 87, 88, 55, 69, 59, 71, 78, 83, 79, 84, 59, 71, 61, 73, 83, 87, 84, 88, 78, 83, 83, 87, 90, 91, 91, 92, 79, 84, 84, 88, 91, 92, 92, 93, 1, 2, 5, 6, 2, 4, 6, 7, 5, 6, 12, 13, 12, 13, 15, 16, 2, 4, 12, 13, 4, 11, 13, 14, 6, 7, 15, 16, 13, 14, 17, 18, 5, 12, 12, 15, 6, 13, 13, 16, 12, 15, 19, 20, 15, 17, 20, 21, 6, 13, 15, 17, 7, 14, 16, 18, 13, 16, 20, 21, 16, 18, 21, 22, 5, 6, 12, 13, 12, 13, 15, 16, 12, 13, 35, 36, 38, 39, 40, 41, 12, 13, 38, 39, 35, 36, 40, 41, 15, 16, 40, 41, 40, 41, 48, 49, 50, 51, 51, 52, 51, 52, 52, 53, 51, 52, 54, 55, 56, 57, 58, 59, 51, 52, 56, 57, 54, 55, 58, 59, 52, 53, 58, 59, 58, 59, 60, 61, 2, 4, 12, 13, 4, 11, 13, 14, 12, 13, 38, 39, 35, 36, 40, 41, 4, 11, 35, 36, 11, 34, 36, 37, 13, 14, 40, 41, 36, 37, 42, 43, 12, 35, 38, 40, 13, 36, 39, 41, 38, 40, 44, 45, 40, 42, 45, 46, 13, 36, 40, 42, 14, 37, 41, 43, 39, 41, 45, 46, 41, 43, 46, 47, 6, 7, 15, 16, 13, 14, 17, 18, 15, 16, 40, 41, 40, 41, 48, 49, 13, 14, 40, 41, 36, 37, 42, 43, 17, 18, 48, 49, 42, 43, 62, 63, 51, 54, 56, 58, 52, 55, 57, 59, 56, 58, 68, 69, 65, 66, 70, 71, 52, 55, 65, 66, 55, 64, 66, 67, 57, 59, 70, 71, 66, 67, 72, 73, 5, 12, 12, 15, 6, 13, 13, 16, 50, 51, 51, 52, 51, 52, 52, 53, 12, 35, 38, 40, 13, 36, 39, 41, 51, 54, 56, 58, 52, 55, 57, 59, 12, 38, 35, 40, 13, 39, 36, 41, 51, 56, 54, 58, 52, 57, 55, 59, 15, 40, 40, 48, 16, 41, 41, 49, 52, 58, 58, 60, 53, 59, 59, 61, 12, 15, 19, 20, 15, 17, 20, 21, 51, 52, 54, 55, 56, 57, 58, 59, 38, 40, 44, 45, 40, 42, 45, 46, 56, 58, 68, 69, 65, 66, 70, 71, 51, 56, 54, 58, 52, 57, 55, 59, 74, 75, 77, 78, 75, 76, 78, 79, 56, 65, 68, 70, 58, 66, 69, 71, 75, 80, 82, 83, 80, 81, 83, 84, 6, 13, 15, 17, 7, 14, 16, 18, 51, 52, 56, 57, 54, 55, 58, 59, 13, 36, 40, 42, 14, 37, 41, 43, 52, 55, 65, 66, 55, 64, 66, 67, 15, 40, 40, 48, 16, 41, 41, 49, 56, 65, 68, 70, 58, 66, 69, 71, 17, 42, 48, 62, 18, 43, 49, 63, 57, 66, 70, 72, 59, 67, 71, 73, 13, 16, 20, 21, 16, 18, 21, 22, 52, 53, 58, 59, 58, 59, 60, 61, 39, 41, 45, 46, 41, 43, 46, 47, 57, 59, 70, 71, 66, 67, 72, 73, 52, 58, 58, 60, 53, 59, 59, 61, 75, 80, 82, 83, 80, 81, 83, 84, 57, 66, 70, 72, 59, 67, 71, 73, 76, 81, 86, 87, 81, 85, 87, 88, 5, 12, 50, 51, 12, 35, 51, 54, 12, 15, 51, 52, 38, 40, 56, 58, 6, 13, 51, 52, 13, 36, 52, 55, 13, 16, 52, 53, 39, 41, 57, 59, 12, 38, 51, 56, 15, 40, 52, 58, 35, 40, 54, 58, 40, 48, 58, 60, 13, 39, 52, 57, 16, 41, 53, 59, 36, 41, 55, 59, 41, 49, 59, 61, 12, 15, 51, 52, 38, 40, 56, 58, 19, 20, 54, 55, 44, 45, 68, 69, 15, 17, 56, 57, 40, 42, 65, 66, 20, 21, 58, 59, 45, 46, 70, 71, 51, 56, 74, 75, 56, 65, 75, 80, 54, 58, 77, 78, 68, 70, 82, 83, 52, 57, 75, 76, 58, 66, 80, 81, 55, 59, 78, 79, 69, 71, 83, 84, 6, 13, 51, 52, 13, 36, 52, 55, 15, 17, 56, 57, 40, 42, 65, 66, 7, 14, 54, 55, 14, 37, 55, 64, 16, 18, 58, 59, 41, 43, 66, 67, 15, 40, 56, 65, 17, 42, 57, 66, 40, 48, 68, 70, 48, 62, 70, 72, 16, 41, 58, 66, 18, 43, 59, 67, 41, 49, 69, 71, 49, 63, 71, 73, 13, 16, 52, 53, 39, 41, 57, 59, 20, 21, 58, 59, 45, 46, 70, 71, 16, 18, 58, 59, 41, 43, 66, 67, 21, 22, 60, 61, 46, 47, 72, 73, 52, 58, 75, 80, 57, 66, 76, 81, 58, 60, 82, 83, 70, 72, 86, 87, 53, 59, 80, 81, 59, 67, 81, 85, 59, 61, 83, 84, 71, 73, 87, 88, 12, 38, 51, 56, 15, 40, 52, 58, 51, 56, 74, 75, 56, 65, 75, 80, 15, 40, 56, 65, 17, 42, 57, 66, 52, 58, 75, 80, 57, 66, 76, 81, 19, 44, 54, 68, 20, 45, 55, 69, 54, 68, 77, 82, 58, 70, 78, 83, 20, 45, 58, 70, 21, 46, 59, 71, 55, 69, 78, 83, 59, 71, 79, 84, 35, 40, 54, 58, 40, 48, 58, 60, 54, 58, 77, 78, 68, 70, 82, 83, 40, 48, 68, 70, 48, 62, 70, 72, 58, 60, 82, 83, 70, 72, 86, 87, 54, 68, 77, 82, 58, 70, 78, 83, 77, 82, 89, 90, 82, 86, 90, 91, 58, 70, 82, 86, 60, 72, 83, 87, 78, 83, 90, 91, 83, 87, 91, 92, 13, 39, 52, 57, 16, 41, 53, 59, 52, 57, 75, 76, 58, 66, 80, 81, 16, 41, 58, 66, 18, 43, 59, 67, 53, 59, 80, 81, 59, 67, 81, 85, 20, 45, 58, 70, 21, 46, 59, 71, 58, 70, 82, 86, 60, 72, 83, 87, 21, 46, 60, 72, 22, 47, 61, 73, 59, 71, 83, 87, 61, 73, 84, 88, 36, 41, 55, 59, 41, 49, 59, 61, 55, 59, 78, 79, 69, 71, 83, 84, 41, 49, 69, 71, 49, 63, 71, 73, 59, 61, 83, 84, 71, 73, 87, 88, 55, 69, 78, 83, 59, 71, 79, 84, 78, 83, 90, 91, 83, 87, 91, 92, 59, 71, 83, 87, 61, 73, 84, 88, 79, 84, 91, 92, 84, 88, 92, 93, 2, 3, 6, 7, 6, 7, 8, 9, 6, 7, 13, 14, 15, 16, 17, 18, 6, 7, 15, 16, 13, 14, 17, 18, 8, 9, 17, 18, 17, 18, 23, 24, 12, 19, 15, 20, 15, 20, 17, 21, 15, 20, 20, 25, 26, 27, 27, 28, 15, 20, 26, 27, 20, 25, 27, 28, 17, 21, 27, 28, 27, 28, 29, 30, 6, 7, 13, 14, 15, 16, 17, 18, 13, 14, 36, 37, 40, 41, 42, 43, 15, 16, 40, 41, 40, 41, 48, 49, 17, 18, 42, 43, 48, 49, 62, 63, 51, 54, 52, 55, 56, 58, 57, 59, 52, 55, 55, 64, 65, 66, 66, 67, 56, 58, 65, 66, 68, 69, 70, 71, 57, 59, 66, 67, 70, 71, 72, 73, 6, 7, 15, 16, 13, 14, 17, 18, 15, 16, 40, 41, 40, 41, 48, 49, 13, 14, 40, 41, 36, 37, 42, 43, 17, 18, 48, 49, 42, 43, 62, 63, 51, 54, 56, 58, 52, 55, 57, 59, 56, 58, 68, 69, 65, 66, 70, 71, 52, 55, 65, 66, 55, 64, 66, 67, 57, 59, 70, 71, 66, 67, 72, 73, 8, 9, 17, 18, 17, 18, 23, 24, 17, 18, 42, 43, 48, 49, 62, 63, 17, 18, 48, 49, 42, 43, 62, 63, 23, 24, 62, 63, 62, 63, 94, 95, 74, 77, 75, 78, 75, 78, 76, 79, 75, 78, 96, 97, 98, 99, 100, 101, 75, 78, 98, 99, 96, 97, 100, 101, 76, 79, 100, 101, 100, 101, 102, 103, 12, 19, 15, 20, 15, 20, 17, 21, 51, 54, 52, 55, 56, 58, 57, 59, 51, 54, 56, 58, 52, 55, 57, 59, 74, 77, 75, 78, 75, 78, 76, 79, 38, 44, 40, 45, 40, 45, 42, 46, 56, 68, 58, 69, 65, 70, 66, 71, 56, 68, 65, 70, 58, 69, 66, 71, 75, 82, 80, 83, 80, 83, 81, 84, 15, 20, 20, 25, 26, 27, 27, 28, 52, 55, 55, 64, 65, 66, 66, 67, 56, 58, 68, 69, 65, 66, 70, 71, 75, 78, 96, 97, 98, 99, 100, 101, 56, 68, 58, 69, 65, 70, 66, 71, 75, 96, 78, 97, 98, 100, 99, 101, 104, 105, 105, 106, 105, 106, 106, 107, 108, 109, 109, 110, 111, 112, 112, 113, 15, 20, 26, 27, 20, 25, 27, 28, 56, 58, 65, 66, 68, 69, 70, 71, 52, 55, 65, 66, 55, 64, 66, 67, 75, 78, 98, 99, 96, 97, 100, 101, 56, 68, 65, 70, 58, 69, 66, 71, 104, 105, 105, 106, 105, 106, 106, 107, 75, 96, 98, 100, 78, 97, 99, 101, 108, 109, 111, 112, 109, 110, 112, 113, 17, 21, 27, 28, 27, 28, 29, 30, 57, 59, 66, 67, 70, 71, 72, 73, 57, 59, 70, 71, 66, 67, 72, 73, 76, 79, 100, 101, 100, 101, 102, 103, 75, 82, 80, 83, 80, 83, 81, 84, 108, 109, 109, 110, 111, 112, 112, 113, 108, 109, 111, 112, 109, 110, 112, 113, 114, 115, 116, 117, 116, 117, 118, 119, 12, 19, 51, 54, 51, 54, 74, 77, 15, 20, 52, 55, 56, 58, 75, 78, 15, 20, 56, 58, 52, 55, 75, 78, 17, 21, 57, 59, 57, 59, 76, 79, 38, 44, 56, 68, 56, 68, 75, 82, 40, 45, 58, 69, 65, 70, 80, 83, 40, 45, 65, 70, 58, 69, 80, 83, 42, 46, 66, 71, 66, 71, 81, 84, 15, 20, 52, 55, 56, 58, 75, 78, 20, 25, 55, 64, 68, 69, 96, 97, 26, 27, 65, 66, 65, 66, 98, 99, 27, 28, 66, 67, 70, 71, 100, 101, 56, 68, 75, 96, 104, 105, 108, 109, 58, 69, 78, 97, 105, 106, 109, 110, 65, 70, 98, 100, 105, 106, 111, 112, 66, 71, 99, 101, 106, 107, 112, 113, 15, 20, 56, 58, 52, 55, 75, 78, 26, 27, 65, 66, 65, 66, 98, 99, 20, 25, 68, 69, 55, 64, 96, 97, 27, 28, 70, 71, 66, 67, 100, 101, 56, 68, 104, 105, 75, 96, 108, 109, 65, 70, 105, 106, 98, 100, 111, 112, 58, 69, 105, 106, 78, 97, 109, 110, 66, 71, 106, 107, 99, 101, 112, 113, 17, 21, 57, 59, 57, 59, 76, 79, 27, 28, 66, 67, 70, 71, 100, 101, 27, 28, 70, 71, 66, 67, 100, 101, 29, 30, 72, 73, 72, 73, 102, 103, 75, 82, 108, 109, 108, 109, 114, 115, 80, 83, 109, 110, 111, 112, 116, 117, 80, 83, 111, 112, 109, 110, 116, 117, 81, 84, 112, 113, 112, 113, 118, 119, 38, 44, 56, 68, 56, 68, 75, 82, 56, 68, 75, 96, 104, 105, 108, 109, 56, 68, 104, 105, 75, 96, 108, 109, 75, 82, 108, 109, 108, 109, 114, 115, 44, 120, 68, 121, 68, 121, 96, 122, 68, 121, 82, 122, 105, 123, 109, 124, 68, 121, 105, 123, 82, 122, 109, 124, 96, 122, 109, 124, 109, 124, 115, 125, 40, 45, 58, 69, 65, 70, 80, 83, 58, 69, 78, 97, 105, 106, 109, 110, 65, 70, 105, 106, 98, 100, 111, 112, 80, 83, 109, 110, 111, 112, 116, 117, 68, 121, 82, 122, 105, 123, 109, 124, 82, 122, 90, 126, 127, 128, 129, 130, 105, 123, 127, 128, 127, 128, 131, 132, 109, 124, 129, 130, 131, 132, 133, 134, 40, 45, 65, 70, 58, 69, 80, 83, 65, 70, 98, 100, 105, 106, 111, 112, 58, 69, 105, 106, 78, 97, 109, 110, 80, 83, 111, 112, 109, 110, 116, 117, 68, 121, 105, 123, 82, 122, 109, 124, 105, 123, 127, 128, 127, 128, 131, 132, 82, 122, 127, 128, 90, 126, 129, 130, 109, 124, 131, 132, 129, 130, 133, 134, 42, 46, 66, 71, 66, 71, 81, 84, 66, 71, 99, 101, 106, 107, 112, 113, 66, 71, 106, 107, 99, 101, 112, 113, 81, 84, 112, 113, 112, 113, 118, 119, 96, 122, 109, 124, 109, 124, 115, 125, 109, 124, 129, 130, 131, 132, 133, 134, 109, 124, 131, 132, 129, 130, 133, 134, 115, 125, 133, 134, 133, 134, 135, 136, 1, 5, 2, 6, 2, 6, 4, 7, 5, 12, 6, 13, 12, 15, 13, 16, 5, 12, 12, 15, 6, 13, 13, 16, 12, 19, 15, 20, 15, 20, 17, 21, 2, 12, 4, 13, 4, 13, 11, 14, 6, 15, 7, 16, 13, 17, 14, 18, 6, 15, 13, 17, 7, 16, 14, 18, 13, 20, 16, 21, 16, 21, 18, 22, 5, 12, 6, 13, 12, 15, 13, 16, 12, 35, 13, 36, 38, 40, 39, 41, 50, 51, 51, 52, 51, 52, 52, 53, 51, 54, 52, 55, 56, 58, 57, 59, 12, 38, 13, 39, 35, 40, 36, 41, 15, 40, 16, 41, 40, 48, 41, 49, 51, 56, 52, 57, 54, 58, 55, 59, 52, 58, 53, 59, 58, 60, 59, 61, 5, 12, 12, 15, 6, 13, 13, 16, 50, 51, 51, 52, 51, 52, 52, 53, 12, 35, 38, 40, 13, 36, 39, 41, 51, 54, 56, 58, 52, 55, 57, 59, 12, 38, 35, 40, 13, 39, 36, 41, 51, 56, 54, 58, 52, 57, 55, 59, 15, 40, 40, 48, 16, 41, 41, 49, 52, 58, 58, 60, 53, 59, 59, 61, 12, 19, 15, 20, 15, 20, 17, 21, 51, 54, 52, 55, 56, 58, 57, 59, 51, 54, 56, 58, 52, 55, 57, 59, 74, 77, 75, 78, 75, 78, 76, 79, 38, 44, 40, 45, 40, 45, 42, 46, 56, 68, 58, 69, 65, 70, 66, 71, 56, 68, 65, 70, 58, 69, 66, 71, 75, 82, 80, 83, 80, 83, 81, 84, 2, 12, 4, 13, 4, 13, 11, 14, 12, 38, 13, 39, 35, 40, 36, 41, 12, 38, 35, 40, 13, 39, 36, 41, 38, 44, 40, 45, 40, 45, 42, 46, 4, 35, 11, 36, 11, 36, 34, 37, 13, 40, 14, 41, 36, 42, 37, 43, 13, 40, 36, 42, 14, 41, 37, 43, 39, 45, 41, 46, 41, 46, 43, 47, 6, 15, 7, 16, 13, 17, 14, 18, 15, 40, 16, 41, 40, 48, 41, 49, 51, 56, 54, 58, 52, 57, 55, 59, 56, 68, 58, 69, 65, 70, 66, 71, 13, 40, 14, 41, 36, 42, 37, 43, 17, 48, 18, 49, 42, 62, 43, 63, 52, 65, 55, 66, 55, 66, 64, 67, 57, 70, 59, 71, 66, 72, 67, 73, 6, 15, 13, 17, 7, 16, 14, 18, 51, 56, 52, 57, 54, 58, 55, 59, 15, 40, 40, 48, 16, 41, 41, 49, 56, 68, 65, 70, 58, 69, 66, 71, 13, 40, 36, 42, 14, 41, 37, 43, 52, 65, 55, 66, 55, 66, 64, 67, 17, 48, 42, 62, 18, 49, 43, 63, 57, 70, 66, 72, 59, 71, 67, 73, 13, 20, 16, 21, 16, 21, 18, 22, 52, 58, 53, 59, 58, 60, 59, 61, 52, 58, 58, 60, 53, 59, 59, 61, 75, 82, 80, 83, 80, 83, 81, 84, 39, 45, 41, 46, 41, 46, 43, 47, 57, 70, 59, 71, 66, 72, 67, 73, 57, 70, 66, 72, 59, 71, 67, 73, 76, 86, 81, 87, 81, 87, 85, 88, 5, 50, 12, 51, 12, 51, 35, 54, 12, 51, 15, 52, 38, 56, 40, 58, 12, 51, 38, 56, 15, 52, 40, 58, 35, 54, 40, 58, 40, 58, 48, 60, 6, 51, 13, 52, 13, 52, 36, 55, 13, 52, 16, 53, 39, 57, 41, 59, 13, 52, 39, 57, 16, 53, 41, 59, 36, 55, 41, 59, 41, 59, 49, 61, 12, 51, 15, 52, 38, 56, 40, 58, 19, 54, 20, 55, 44, 68, 45, 69, 51, 74, 56, 75, 56, 75, 65, 80, 54, 77, 58, 78, 68, 82, 70, 83, 15, 56, 17, 57, 40, 65, 42, 66, 20, 58, 21, 59, 45, 70, 46, 71, 52, 75, 57, 76, 58, 80, 66, 81, 55, 78, 59, 79, 69, 83, 71, 84, 12, 51, 38, 56, 15, 52, 40, 58, 51, 74, 56, 75, 56, 75, 65, 80, 19, 54, 44, 68, 20, 55, 45, 69, 54, 77, 68, 82, 58, 78, 70, 83, 15, 56, 40, 65, 17, 57, 42, 66, 52, 75, 58, 80, 57, 76, 66, 81, 20, 58, 45, 70, 21, 59, 46, 71, 55, 78, 69, 83, 59, 79, 71, 84, 35, 54, 40, 58, 40, 58, 48, 60, 54, 77, 58, 78, 68, 82, 70, 83, 54, 77, 68, 82, 58, 78, 70, 83, 77, 89, 82, 90, 82, 90, 86, 91, 40, 68, 48, 70, 48, 70, 62, 72, 58, 82, 60, 83, 70, 86, 72, 87, 58, 82, 70, 86, 60, 83, 72, 87, 78, 90, 83, 91, 83, 91, 87, 92, 6, 51, 13, 52, 13, 52, 36, 55, 15, 56, 17, 57, 40, 65, 42, 66, 15, 56, 40, 65, 17, 57, 42, 66, 40, 68, 48, 70, 48, 70, 62, 72, 7, 54, 14, 55, 14, 55, 37, 64, 16, 58, 18, 59, 41, 66, 43, 67, 16, 58, 41, 66, 18, 59, 43, 67, 41, 69, 49, 71, 49, 71, 63, 73, 13, 52, 16, 53, 39, 57, 41, 59, 20, 58, 21, 59, 45, 70, 46, 71, 52, 75, 58, 80, 57, 76, 66, 81, 58, 82, 60, 83, 70, 86, 72, 87, 16, 58, 18, 59, 41, 66, 43, 67, 21, 60, 22, 61, 46, 72, 47, 73, 53, 80, 59, 81, 59, 81, 67, 85, 59, 83, 61, 84, 71, 87, 73, 88, 13, 52, 39, 57, 16, 53, 41, 59, 52, 75, 57, 76, 58, 80, 66, 81, 20, 58, 45, 70, 21, 59, 46, 71, 58, 82, 70, 86, 60, 83, 72, 87, 16, 58, 41, 66, 18, 59, 43, 67, 53, 80, 59, 81, 59, 81, 67, 85, 21, 60, 46, 72, 22, 61, 47, 73, 59, 83, 71, 87, 61, 84, 73, 88, 36, 55, 41, 59, 41, 59, 49, 61, 55, 78, 59, 79, 69, 83, 71, 84, 55, 78, 69, 83, 59, 79, 71, 84, 78, 90, 83, 91, 83, 91, 87, 92, 41, 69, 49, 71, 49, 71, 63, 73, 59, 83, 61, 84, 71, 87, 73, 88, 59, 83, 71, 87, 61, 84, 73, 88, 79, 91, 84, 92, 84, 92, 88, 93, 2, 6, 3, 7, 6, 8, 7, 9, 6, 13, 7, 14, 15, 17, 16, 18, 12, 15, 19, 20, 15, 17, 20, 21, 15, 20, 20, 25, 26, 27, 27, 28, 6, 15, 7, 16, 13, 17, 14, 18, 8, 17, 9, 18, 17, 23, 18, 24, 15, 26, 20, 27, 20, 27, 25, 28, 17, 27, 21, 28, 27, 29, 28, 30, 6, 13, 7, 14, 15, 17, 16, 18, 13, 36, 14, 37, 40, 42, 41, 43, 51, 52, 54, 55, 56, 57, 58, 59, 52, 55, 55, 64, 65, 66, 66, 67, 15, 40, 16, 41, 40, 48, 41, 49, 17, 42, 18, 43, 48, 62, 49, 63, 56, 65, 58, 66, 68, 70, 69, 71, 57, 66, 59, 67, 70, 72, 71, 73, 12, 15, 19, 20, 15, 17, 20, 21, 51, 52, 54, 55, 56, 57, 58, 59, 38, 40, 44, 45, 40, 42, 45, 46, 56, 58, 68, 69, 65, 66, 70, 71, 51, 56, 54, 58, 52, 57, 55, 59, 74, 75, 77, 78, 75, 76, 78, 79, 56, 65, 68, 70, 58, 66, 69, 71, 75, 80, 82, 83, 80, 81, 83, 84, 15, 20, 20, 25, 26, 27, 27, 28, 52, 55, 55, 64, 65, 66, 66, 67, 56, 58, 68, 69, 65, 66, 70, 71, 75, 78, 96, 97, 98, 99, 100, 101, 56, 68, 58, 69, 65, 70, 66, 71, 75, 96, 78, 97, 98, 100, 99, 101, 104, 105, 105, 106, 105, 106, 106, 107, 108, 109, 109, 110, 111, 112, 112, 113, 6, 15, 7, 16, 13, 17, 14, 18, 15, 40, 16, 41, 40, 48, 41, 49, 51, 56, 54, 58, 52, 57, 55, 59, 56, 68, 58, 69, 65, 70, 66, 71, 13, 40, 14, 41, 36, 42, 37, 43, 17, 48, 18, 49, 42, 62, 43, 63, 52, 65, 55, 66, 55, 66, 64, 67, 57, 70, 59, 71, 66, 72, 67, 73, 8, 17, 9, 18, 17, 23, 18, 24, 17, 42, 18, 43, 48, 62, 49, 63, 74, 75, 77, 78, 75, 76, 78, 79, 75, 96, 78, 97, 98, 100, 99, 101, 17, 48, 18, 49, 42, 62, 43, 63, 23, 62, 24, 63, 62, 94, 63, 95, 75, 98, 78, 99, 96, 100, 97, 101, 76, 100, 79, 101, 100, 102, 101, 103, 15, 26, 20, 27, 20, 27, 25, 28, 56, 65, 58, 66, 68, 70, 69, 71, 56, 65, 68, 70, 58, 66, 69, 71, 104, 105, 105, 106, 105, 106, 106, 107, 52, 65, 55, 66, 55, 66, 64, 67, 75, 98, 78, 99, 96, 100, 97, 101, 75, 98, 96, 100, 78, 99, 97, 101, 108, 111, 109, 112, 109, 112, 110, 113, 17, 27, 21, 28, 27, 29, 28, 30, 57, 66, 59, 67, 70, 72, 71, 73, 75, 80, 82, 83, 80, 81, 83, 84, 108, 109, 109, 110, 111, 112, 112, 113, 57, 70, 59, 71, 66, 72, 67, 73, 76, 100, 79, 101, 100, 102, 101, 103, 108, 111, 109, 112, 109, 112, 110, 113, 114, 116, 115, 117, 116, 118, 117, 119, 12, 51, 19, 54, 51, 74, 54, 77, 15, 52, 20, 55, 56, 75, 58, 78, 38, 56, 44, 68, 56, 75, 68, 82, 40, 58, 45, 69, 65, 80, 70, 83, 15, 56, 20, 58, 52, 75, 55, 78, 17, 57, 21, 59, 57, 76, 59, 79, 40, 65, 45, 70, 58, 80, 69, 83, 42, 66, 46, 71, 66, 81, 71, 84, 15, 52, 20, 55, 56, 75, 58, 78, 20, 55, 25, 64, 68, 96, 69, 97, 56, 75, 68, 96, 104, 108, 105, 109, 58, 78, 69, 97, 105, 109, 106, 110, 26, 65, 27, 66, 65, 98, 66, 99, 27, 66, 28, 67, 70, 100, 71, 101, 65, 98, 70, 100, 105, 111, 106, 112, 66, 99, 71, 101, 106, 112, 107, 113, 38, 56, 44, 68, 56, 75, 68, 82, 56, 75, 68, 96, 104, 108, 105, 109, 44, 68, 120, 121, 68, 96, 121, 122, 68, 82, 121, 122, 105, 109, 123, 124, 56, 104, 68, 105, 75, 108, 96, 109, 75, 108, 82, 109, 108, 114, 109, 115, 68, 105, 121, 123, 82, 109, 122, 124, 96, 109, 122, 124, 109, 115, 124, 125, 40, 58, 45, 69, 65, 80, 70, 83, 58, 78, 69, 97, 105, 109, 106, 110, 68, 82, 121, 122, 105, 109, 123, 124, 82, 90, 122, 126, 127, 129, 128, 130, 65, 105, 70, 106, 98, 111, 100, 112, 80, 109, 83, 110, 111, 116, 112, 117, 105, 127, 123, 128, 127, 131, 128, 132, 109, 129, 124, 130, 131, 133, 132, 134, 15, 56, 20, 58, 52, 75, 55, 78, 26, 65, 27, 66, 65, 98, 66, 99, 56, 104, 68, 105, 75, 108, 96, 109, 65, 105, 70, 106, 98, 111, 100, 112, 20, 68, 25, 69, 55, 96, 64, 97, 27, 70, 28, 71, 66, 100, 67, 101, 58, 105, 69, 106, 78, 109, 97, 110, 66, 106, 71, 107, 99, 112, 101, 113, 17, 57, 21, 59, 57, 76, 59, 79, 27, 66, 28, 67, 70, 100, 71, 101, 75, 108, 82, 109, 108, 114, 109, 115, 80, 109, 83, 110, 111, 116, 112, 117, 27, 70, 28, 71, 66, 100, 67, 101, 29, 72, 30, 73, 72, 102, 73, 103, 80, 111, 83, 112, 109, 116, 110, 117, 81, 112, 84, 113, 112, 118, 113, 119, 40, 65, 45, 70, 58, 80, 69, 83, 65, 98, 70, 100, 105, 111, 106, 112, 68, 105, 121, 123, 82, 109, 122, 124, 105, 127, 123, 128, 127, 131, 128, 132, 58, 105, 69, 106, 78, 109, 97, 110, 80, 111, 83, 112, 109, 116, 110, 117, 82, 127, 122, 128, 90, 129, 126, 130, 109, 131, 124, 132, 129, 133, 130, 134, 42, 66, 46, 71, 66, 81, 71, 84, 66, 99, 71, 101, 106, 112, 107, 113, 96, 109, 122, 124, 109, 115, 124, 125, 109, 129, 124, 130, 131, 133, 132, 134, 66, 106, 71, 107, 99, 112, 101, 113, 81, 112, 84, 113, 112, 118, 113, 119, 109, 131, 124, 132, 129, 133, 130, 134, 115, 133, 125, 134, 133, 135, 134, 136, 2, 6, 6, 8, 3, 7, 7, 9, 12, 15, 15, 17, 19, 20, 20, 21, 6, 13, 15, 17, 7, 14, 16, 18, 15, 20, 26, 27, 20, 25, 27, 28, 6, 15, 13, 17, 7, 16, 14, 18, 15, 26, 20, 27, 20, 27, 25, 28, 8, 17, 17, 23, 9, 18, 18, 24, 17, 27, 27, 29, 21, 28, 28, 30, 12, 15, 15, 17, 19, 20, 20, 21, 38, 40, 40, 42, 44, 45, 45, 46, 51, 52, 56, 57, 54, 55, 58, 59, 56, 58, 65, 66, 68, 69, 70, 71, 51, 56, 52, 57, 54, 58, 55, 59, 56, 65, 58, 66, 68, 70, 69, 71, 74, 75, 75, 76, 77, 78, 78, 79, 75, 80, 80, 81, 82, 83, 83, 84, 6, 13, 15, 17, 7, 14, 16, 18, 51, 52, 56, 57, 54, 55, 58, 59, 13, 36, 40, 42, 14, 37, 41, 43, 52, 55, 65, 66, 55, 64, 66, 67, 15, 40, 40, 48, 16, 41, 41, 49, 56, 65, 68, 70, 58, 66, 69, 71, 17, 42, 48, 62, 18, 43, 49, 63, 57, 66, 70, 72, 59, 67, 71, 73, 15, 20, 26, 27, 20, 25, 27, 28, 56, 58, 65, 66, 68, 69, 70, 71, 52, 55, 65, 66, 55, 64, 66, 67, 75, 78, 98, 99, 96, 97, 100, 101, 56, 68, 65, 70, 58, 69, 66, 71, 104, 105, 105, 106, 105, 106, 106, 107, 75, 96, 98, 100, 78, 97, 99, 101, 108, 109, 111, 112, 109, 110, 112, 113, 6, 15, 13, 17, 7, 16, 14, 18, 51, 56, 52, 57, 54, 58, 55, 59, 15, 40, 40, 48, 16, 41, 41, 49, 56, 68, 65, 70, 58, 69, 66, 71, 13, 40, 36, 42, 14, 41, 37, 43, 52, 65, 55, 66, 55, 66, 64, 67, 17, 48, 42, 62, 18, 49, 43, 63, 57, 70, 66, 72, 59, 71, 67, 73, 15, 26, 20, 27, 20, 27, 25, 28, 56, 65, 58, 66, 68, 70, 69, 71, 56, 65, 68, 70, 58, 66, 69, 71, 104, 105, 105, 106, 105, 106, 106, 107, 52, 65, 55, 66, 55, 66, 64, 67, 75, 98, 78, 99, 96, 100, 97, 101, 75, 98, 96, 100, 78, 99, 97, 101, 108, 111, 109, 112, 109, 112, 110, 113, 8, 17, 17, 23, 9, 18, 18, 24, 74, 75, 75, 76, 77, 78, 78, 79, 17, 42, 48, 62, 18, 43, 49, 63, 75, 96, 98, 100, 78, 97, 99, 101, 17, 48, 42, 62, 18, 49, 43, 63, 75, 98, 96, 100, 78, 99, 97, 101, 23, 62, 62, 94, 24, 63, 63, 95, 76, 100, 100, 102, 79, 101, 101, 103, 17, 27, 27, 29, 21, 28, 28, 30, 75, 80, 80, 81, 82, 83, 83, 84, 57, 66, 70, 72, 59, 67, 71, 73, 108, 109, 111, 112, 109, 110, 112, 113, 57, 70, 66, 72, 59, 71, 67, 73, 108, 111, 109, 112, 109, 112, 110, 113, 76, 100, 100, 102, 79, 101, 101, 103, 114, 116, 116, 118, 115, 117, 117, 119, 12, 51, 51, 74, 19, 54, 54, 77, 38, 56, 56, 75, 44, 68, 68, 82, 15, 52, 56, 75, 20, 55, 58, 78, 40, 58, 65, 80, 45, 69, 70, 83, 15, 56, 52, 75, 20, 58, 55, 78, 40, 65, 58, 80, 45, 70, 69, 83, 17, 57, 57, 76, 21, 59, 59, 79, 42, 66, 66, 81, 46, 71, 71, 84, 38, 56, 56, 75, 44, 68, 68, 82, 44, 68, 68, 96, 120, 121, 121, 122, 56, 75, 104, 108, 68, 96, 105, 109, 68, 82, 105, 109, 121, 122, 123, 124, 56, 104, 75, 108, 68, 105, 96, 109, 68, 105, 82, 109, 121, 123, 122, 124, 75, 108, 108, 114, 82, 109, 109, 115, 96, 109, 109, 115, 122, 124, 124, 125, 15, 52, 56, 75, 20, 55, 58, 78, 56, 75, 104, 108, 68, 96, 105, 109, 20, 55, 68, 96, 25, 64, 69, 97, 58, 78, 105, 109, 69, 97, 106, 110, 26, 65, 65, 98, 27, 66, 66, 99, 65, 98, 105, 111, 70, 100, 106, 112, 27, 66, 70, 100, 28, 67, 71, 101, 66, 99, 106, 112, 71, 101, 107, 113, 40, 58, 65, 80, 45, 69, 70, 83, 68, 82, 105, 109, 121, 122, 123, 124, 58, 78, 105, 109, 69, 97, 106, 110, 82, 90, 127, 129, 122, 126, 128, 130, 65, 105, 98, 111, 70, 106, 100, 112, 105, 127, 127, 131, 123, 128, 128, 132, 80, 109, 111, 116, 83, 110, 112, 117, 109, 129, 131, 133, 124, 130, 132, 134, 15, 56, 52, 75, 20, 58, 55, 78, 56, 104, 75, 108, 68, 105, 96, 109, 26, 65, 65, 98, 27, 66, 66, 99, 65, 105, 98, 111, 70, 106, 100, 112, 20, 68, 55, 96, 25, 69, 64, 97, 58, 105, 78, 109, 69, 106, 97, 110, 27, 70, 66, 100, 28, 71, 67, 101, 66, 106, 99, 112, 71, 107, 101, 113, 40, 65, 58, 80, 45, 70, 69, 83, 68, 105, 82, 109, 121, 123, 122, 124, 65, 98, 105, 111, 70, 100, 106, 112, 105, 127, 127, 131, 123, 128, 128, 132, 58, 105, 78, 109, 69, 106, 97, 110, 82, 127, 90, 129, 122, 128, 126, 130, 80, 111, 109, 116, 83, 112, 110, 117, 109, 131, 129, 133, 124, 132, 130, 134, 17, 57, 57, 76, 21, 59, 59, 79, 75, 108, 108, 114, 82, 109, 109, 115, 27, 66, 70, 100, 28, 67, 71, 101, 80, 109, 111, 116, 83, 110, 112, 117, 27, 70, 66, 100, 28, 71, 67, 101, 80, 111, 109, 116, 83, 112, 110, 117, 29, 72, 72, 102, 30, 73, 73, 103, 81, 112, 112, 118, 84, 113, 113, 119, 42, 66, 66, 81, 46, 71, 71, 84, 96, 109, 109, 115, 122, 124, 124, 125, 66, 99, 106, 112, 71, 101, 107, 113, 109, 129, 131, 133, 124, 130, 132, 134, 66, 106, 99, 112, 71, 107, 101, 113, 109, 131, 129, 133, 124, 132, 130, 134, 81, 112, 112, 118, 84, 113, 113, 119, 115, 133, 133, 135, 125, 134, 134, 136, 4, 7, 7, 9, 7, 9, 9, 10, 13, 16, 16, 18, 20, 21, 21, 22, 13, 16, 20, 21, 16, 18, 21, 22, 17, 21, 27, 28, 27, 28, 29, 30, 13, 20, 16, 21, 16, 21, 18, 22, 17, 27, 21, 28, 27, 29, 28, 30, 17, 27, 27, 29, 21, 28, 28, 30, 23, 29, 29, 31, 29, 31, 31, 32, 13, 16, 16, 18, 20, 21, 21, 22, 39, 41, 41, 43, 45, 46, 46, 47, 52, 53, 58, 59, 58, 59, 60, 61, 57, 59, 66, 67, 70, 71, 72, 73, 52, 58, 53, 59, 58, 60, 59, 61, 57, 66, 59, 67, 70, 72, 71, 73, 75, 80, 80, 81, 82, 83, 83, 84, 76, 81, 81, 85, 86, 87, 87, 88, 13, 16, 20, 21, 16, 18, 21, 22, 52, 53, 58, 59, 58, 59, 60, 61, 39, 41, 45, 46, 41, 43, 46, 47, 57, 59, 70, 71, 66, 67, 72, 73, 52, 58, 58, 60, 53, 59, 59, 61, 75, 80, 82, 83, 80, 81, 83, 84, 57, 66, 70, 72, 59, 67, 71, 73, 76, 81, 86, 87, 81, 85, 87, 88, 17, 21, 27, 28, 27, 28, 29, 30, 57, 59, 66, 67, 70, 71, 72, 73, 57, 59, 70, 71, 66, 67, 72, 73, 76, 79, 100, 101, 100, 101, 102, 103, 75, 82, 80, 83, 80, 83, 81, 84, 108, 109, 109, 110, 111, 112, 112, 113, 108, 109, 111, 112, 109, 110, 112, 113, 114, 115, 116, 117, 116, 117, 118, 119, 13, 20, 16, 21, 16, 21, 18, 22, 52, 58, 53, 59, 58, 60, 59, 61, 52, 58, 58, 60, 53, 59, 59, 61, 75, 82, 80, 83, 80, 83, 81, 84, 39, 45, 41, 46, 41, 46, 43, 47, 57, 70, 59, 71, 66, 72, 67, 73, 57, 70, 66, 72, 59, 71, 67, 73, 76, 86, 81, 87, 81, 87, 85, 88, 17, 27, 21, 28, 27, 29, 28, 30, 57, 66, 59, 67, 70, 72, 71, 73, 75, 80, 82, 83, 80, 81, 83, 84, 108, 109, 109, 110, 111, 112, 112, 113, 57, 70, 59, 71, 66, 72, 67, 73, 76, 100, 79, 101, 100, 102, 101, 103, 108, 111, 109, 112, 109, 112, 110, 113, 114, 116, 115, 117, 116, 118, 117, 119, 17, 27, 27, 29, 21, 28, 28, 30, 75, 80, 80, 81, 82, 83, 83, 84, 57, 66, 70, 72, 59, 67, 71, 73, 108, 109, 111, 112, 109, 110, 112, 113, 57, 70, 66, 72, 59, 71, 67, 73, 108, 111, 109, 112, 109, 112, 110, 113, 76, 100, 100, 102, 79, 101, 101, 103, 114, 116, 116, 118, 115, 117, 117, 119, 23, 29, 29, 31, 29, 31, 31, 32, 76, 81, 81, 85, 86, 87, 87, 88, 76, 81, 86, 87, 81, 85, 87, 88, 114, 115, 116, 117, 116, 117, 118, 119, 76, 86, 81, 87, 81, 87, 85, 88, 114, 116, 115, 117, 116, 118, 117, 119, 114, 116, 116, 118, 115, 117, 117, 119, 137, 138, 138, 139, 138, 139, 139, 140, 35, 54, 54, 77, 54, 77, 77, 89, 40, 58, 58, 78, 68, 82, 82, 90, 40, 58, 68, 82, 58, 78, 82, 90, 48, 60, 70, 83, 70, 83, 86, 91, 40, 68, 58, 82, 58, 82, 78, 90, 48, 70, 60, 83, 70, 86, 83, 91, 48, 70, 70, 86, 60, 83, 83, 91, 62, 72, 72, 87, 72, 87, 87, 92, 40, 58, 58, 78, 68, 82, 82, 90, 45, 69, 69, 97, 121, 122, 122, 126, 65, 80, 105, 109, 105, 109, 127, 129, 70, 83, 106, 110, 123, 124, 128, 130, 65, 105, 80, 109, 105, 127, 109, 129, 70, 106, 83, 110, 123, 128, 124, 130, 98, 111, 111, 116, 127, 131, 131, 133, 100, 112, 112, 117, 128, 132, 132, 134, 40, 58, 68, 82, 58, 78, 82, 90, 65, 80, 105, 109, 105, 109, 127, 129, 45, 69, 121, 122, 69, 97, 122, 126, 70, 83, 123, 124, 106, 110, 128, 130, 65, 105, 105, 127, 80, 109, 109, 129, 98, 111, 127, 131, 111, 116, 131, 133, 70, 106, 123, 128, 83, 110, 124, 130, 100, 112, 128, 132, 112, 117, 132, 134, 48, 60, 70, 83, 70, 83, 86, 91, 70, 83, 106, 110, 123, 124, 128, 130, 70, 83, 123, 124, 106, 110, 128, 130, 86, 91, 128, 130, 128, 130, 141, 142, 98, 127, 111, 131, 111, 131, 116, 133, 111, 131, 131, 143, 144, 145, 145, 146, 111, 131, 144, 145, 131, 143, 145, 146, 116, 133, 145, 146, 145, 146, 147, 148, 40, 68, 58, 82, 58, 82, 78, 90, 65, 105, 80, 109, 105, 127, 109, 129, 65, 105, 105, 127, 80, 109, 109, 129, 98, 127, 111, 131, 111, 131, 116, 133, 45, 121, 69, 122, 69, 122, 97, 126, 70, 123, 83, 124, 106, 128, 110, 130, 70, 123, 106, 128, 83, 124, 110, 130, 100, 128, 112, 132, 112, 132, 117, 134, 48, 70, 60, 83, 70, 86, 83, 91, 70, 106, 83, 110, 123, 128, 124, 130, 98, 111, 127, 131, 111, 116, 131, 133, 111, 131, 131, 143, 144, 145, 145, 146, 70, 123, 83, 124, 106, 128, 110, 130, 86, 128, 91, 130, 128, 141, 130, 142, 111, 144, 131, 145, 131, 145, 143, 146, 116, 145, 133, 146, 145, 147, 146, 148, 48, 70, 70, 86, 60, 83, 83, 91, 98, 111, 111, 116, 127, 131, 131, 133, 70, 106, 123, 128, 83, 110, 124, 130, 111, 131, 144, 145, 131, 143, 145, 146, 70, 123, 106, 128, 83, 124, 110, 130, 111, 144, 131, 145, 131, 145, 143, 146, 86, 128, 128, 141, 91, 130, 130, 142, 116, 145, 145, 147, 133, 146, 146, 148, 62, 72, 72, 87, 72, 87, 87, 92, 100, 112, 112, 117, 128, 132, 132, 134, 100, 112, 128, 132, 112, 117, 132, 134, 116, 133, 145, 146, 145, 146, 147, 148, 100, 128, 112, 132, 112, 132, 117, 134, 116, 145, 133, 146, 145, 147, 146, 148, 116, 145, 145, 147, 133, 146, 146, 148, 138, 149, 149, 150, 149, 150, 150, 151, 1, 5, 5, 12, 5, 12, 12, 19, 2, 6, 6, 13, 12, 15, 15, 20, 2, 6, 12, 15, 6, 13, 15, 20, 4, 7, 13, 16, 13, 16, 17, 21, 2, 12, 6, 15, 6, 15, 13, 20, 4, 13, 7, 16, 13, 17, 16, 21, 4, 13, 13, 17, 7, 16, 16, 21, 11, 14, 14, 18, 14, 18, 18, 22, 5, 12, 12, 35, 50, 51, 51, 54, 6, 13, 13, 36, 51, 52, 52, 55, 12, 15, 38, 40, 51, 52, 56, 58, 13, 16, 39, 41, 52, 53, 57, 59, 12, 38, 15, 40, 51, 56, 52, 58, 13, 39, 16, 41, 52, 57, 53, 59, 35, 40, 40, 48, 54, 58, 58, 60, 36, 41, 41, 49, 55, 59, 59, 61, 5, 12, 50, 51, 12, 35, 51, 54, 12, 15, 51, 52, 38, 40, 56, 58, 6, 13, 51, 52, 13, 36, 52, 55, 13, 16, 52, 53, 39, 41, 57, 59, 12, 38, 51, 56, 15, 40, 52, 58, 35, 40, 54, 58, 40, 48, 58, 60, 13, 39, 52, 57, 16, 41, 53, 59, 36, 41, 55, 59, 41, 49, 59, 61, 12, 19, 51, 54, 51, 54, 74, 77, 15, 20, 52, 55, 56, 58, 75, 78, 15, 20, 56, 58, 52, 55, 75, 78, 17, 21, 57, 59, 57, 59, 76, 79, 38, 44, 56, 68, 56, 68, 75, 82, 40, 45, 58, 69, 65, 70, 80, 83, 40, 45, 65, 70, 58, 69, 80, 83, 42, 46, 66, 71, 66, 71, 81, 84, 5, 50, 12, 51, 12, 51, 35, 54, 12, 51, 15, 52, 38, 56, 40, 58, 12, 51, 38, 56, 15, 52, 40, 58, 35, 54, 40, 58, 40, 58, 48, 60, 6, 51, 13, 52, 13, 52, 36, 55, 13, 52, 16, 53, 39, 57, 41, 59, 13, 52, 39, 57, 16, 53, 41, 59, 36, 55, 41, 59, 41, 59, 49, 61, 12, 51, 19, 54, 51, 74, 54, 77, 15, 52, 20, 55, 56, 75, 58, 78, 38, 56, 44, 68, 56, 75, 68, 82, 40, 58, 45, 69, 65, 80, 70, 83, 15, 56, 20, 58, 52, 75, 55, 78, 17, 57, 21, 59, 57, 76, 59, 79, 40, 65, 45, 70, 58, 80, 69, 83, 42, 66, 46, 71, 66, 81, 71, 84, 12, 51, 51, 74, 19, 54, 54, 77, 38, 56, 56, 75, 44, 68, 68, 82, 15, 52, 56, 75, 20, 55, 58, 78, 40, 58, 65, 80, 45, 69, 70, 83, 15, 56, 52, 75, 20, 58, 55, 78, 40, 65, 58, 80, 45, 70, 69, 83, 17, 57, 57, 76, 21, 59, 59, 79, 42, 66, 66, 81, 46, 71, 71, 84, 35, 54, 54, 77, 54, 77, 77, 89, 40, 58, 58, 78, 68, 82, 82, 90, 40, 58, 68, 82, 58, 78, 82, 90, 48, 60, 70, 83, 70, 83, 86, 91, 40, 68, 58, 82, 58, 82, 78, 90, 48, 70, 60, 83, 70, 86, 83, 91, 48, 70, 70, 86, 60, 83, 83, 91, 62, 72, 72, 87, 72, 87, 87, 92, 2, 12, 12, 38, 12, 38, 38, 44, 4, 13, 13, 39, 35, 40, 40, 45, 4, 13, 35, 40, 13, 39, 40, 45, 11, 14, 36, 41, 36, 41, 42, 46, 4, 35, 13, 40, 13, 40, 39, 45, 11, 36, 14, 41, 36, 42, 41, 46, 11, 36, 36, 42, 14, 41, 41, 46, 34, 37, 37, 43, 37, 43, 43, 47, 6, 15, 15, 40, 51, 56, 56, 68, 7, 16, 16, 41, 54, 58, 58, 69, 13, 17, 40, 48, 52, 57, 65, 70, 14, 18, 41, 49, 55, 59, 66, 71, 13, 40, 17, 48, 52, 65, 57, 70, 14, 41, 18, 49, 55, 66, 59, 71, 36, 42, 42, 62, 55, 66, 66, 72, 37, 43, 43, 63, 64, 67, 67, 73, 6, 15, 51, 56, 15, 40, 56, 68, 13, 17, 52, 57, 40, 48, 65, 70, 7, 16, 54, 58, 16, 41, 58, 69, 14, 18, 55, 59, 41, 49, 66, 71, 13, 40, 52, 65, 17, 48, 57, 70, 36, 42, 55, 66, 42, 62, 66, 72, 14, 41, 55, 66, 18, 49, 59, 71, 37, 43, 64, 67, 43, 63, 67, 73, 13, 20, 52, 58, 52, 58, 75, 82, 16, 21, 53, 59, 58, 60, 80, 83, 16, 21, 58, 60, 53, 59, 80, 83, 18, 22, 59, 61, 59, 61, 81, 84, 39, 45, 57, 70, 57, 70, 76, 86, 41, 46, 59, 71, 66, 72, 81, 87, 41, 46, 66, 72, 59, 71, 81, 87, 43, 47, 67, 73, 67, 73, 85, 88, 6, 51, 15, 56, 15, 56, 40, 68, 13, 52, 17, 57, 40, 65, 48, 70, 13, 52, 40, 65, 17, 57, 48, 70, 36, 55, 42, 66, 42, 66, 62, 72, 7, 54, 16, 58, 16, 58, 41, 69, 14, 55, 18, 59, 41, 66, 49, 71, 14, 55, 41, 66, 18, 59, 49, 71, 37, 64, 43, 67, 43, 67, 63, 73, 13, 52, 20, 58, 52, 75, 58, 82, 16, 53, 21, 59, 58, 80, 60, 83, 39, 57, 45, 70, 57, 76, 70, 86, 41, 59, 46, 71, 66, 81, 72, 87, 16, 58, 21, 60, 53, 80, 59, 83, 18, 59, 22, 61, 59, 81, 61, 84, 41, 66, 46, 72, 59, 81, 71, 87, 43, 67, 47, 73, 67, 85, 73, 88, 13, 52, 52, 75, 20, 58, 58, 82, 39, 57, 57, 76, 45, 70, 70, 86, 16, 53, 58, 80, 21, 59, 60, 83, 41, 59, 66, 81, 46, 71, 72, 87, 16, 58, 53, 80, 21, 60, 59, 83, 41, 66, 59, 81, 46, 72, 71, 87, 18, 59, 59, 81, 22, 61, 61, 84, 43, 67, 67, 85, 47, 73, 73, 88, 36, 55, 55, 78, 55, 78, 78, 90, 41, 59, 59, 79, 69, 83, 83, 91, 41, 59, 69, 83, 59, 79, 83, 91, 49, 61, 71, 84, 71, 84, 87, 92, 41, 69, 59, 83, 59, 83, 79, 91, 49, 71, 61, 84, 71, 87, 84, 92, 49, 71, 71, 87, 61, 84, 84, 92, 63, 73, 73, 88, 73, 88, 88, 93, 2, 6, 6, 13, 12, 15, 15, 20, 3, 7, 7, 14, 19, 20, 20, 25, 6, 8, 15, 17, 15, 17, 26, 27, 7, 9, 16, 18, 20, 21, 27, 28, 6, 15, 8, 17, 15, 26, 17, 27, 7, 16, 9, 18, 20, 27, 21, 28, 13, 17, 17, 23, 20, 27, 27, 29, 14, 18, 18, 24, 25, 28, 28, 30, 6, 13, 13, 36, 51, 52, 52, 55, 7, 14, 14, 37, 54, 55, 55, 64, 15, 17, 40, 42, 56, 57, 65, 66, 16, 18, 41, 43, 58, 59, 66, 67, 15, 40, 17, 42, 56, 65, 57, 66, 16, 41, 18, 43, 58, 66, 59, 67, 40, 48, 48, 62, 68, 70, 70, 72, 41, 49, 49, 63, 69, 71, 71, 73, 12, 15, 51, 52, 38, 40, 56, 58, 19, 20, 54, 55, 44, 45, 68, 69, 15, 17, 56, 57, 40, 42, 65, 66, 20, 21, 58, 59, 45, 46, 70, 71, 51, 56, 74, 75, 56, 65, 75, 80, 54, 58, 77, 78, 68, 70, 82, 83, 52, 57, 75, 76, 58, 66, 80, 81, 55, 59, 78, 79, 69, 71, 83, 84, 15, 20, 52, 55, 56, 58, 75, 78, 20, 25, 55, 64, 68, 69, 96, 97, 26, 27, 65, 66, 65, 66, 98, 99, 27, 28, 66, 67, 70, 71, 100, 101, 56, 68, 75, 96, 104, 105, 108, 109, 58, 69, 78, 97, 105, 106, 109, 110, 65, 70, 98, 100, 105, 106, 111, 112, 66, 71, 99, 101, 106, 107, 112, 113, 12, 51, 15, 52, 38, 56, 40, 58, 19, 54, 20, 55, 44, 68, 45, 69, 51, 74, 56, 75, 56, 75, 65, 80, 54, 77, 58, 78, 68, 82, 70, 83, 15, 56, 17, 57, 40, 65, 42, 66, 20, 58, 21, 59, 45, 70, 46, 71, 52, 75, 57, 76, 58, 80, 66, 81, 55, 78, 59, 79, 69, 83, 71, 84, 15, 52, 20, 55, 56, 75, 58, 78, 20, 55, 25, 64, 68, 96, 69, 97, 56, 75, 68, 96, 104, 108, 105, 109, 58, 78, 69, 97, 105, 109, 106, 110, 26, 65, 27, 66, 65, 98, 66, 99, 27, 66, 28, 67, 70, 100, 71, 101, 65, 98, 70, 100, 105, 111, 106, 112, 66, 99, 71, 101, 106, 112, 107, 113, 38, 56, 56, 75, 44, 68, 68, 82, 44, 68, 68, 96, 120, 121, 121, 122, 56, 75, 104, 108, 68, 96, 105, 109, 68, 82, 105, 109, 121, 122, 123, 124, 56, 104, 75, 108, 68, 105, 96, 109, 68, 105, 82, 109, 121, 123, 122, 124, 75, 108, 108, 114, 82, 109, 109, 115, 96, 109, 109, 115, 122, 124, 124, 125, 40, 58, 58, 78, 68, 82, 82, 90, 45, 69, 69, 97, 121, 122, 122, 126, 65, 80, 105, 109, 105, 109, 127, 129, 70, 83, 106, 110, 123, 124, 128, 130, 65, 105, 80, 109, 105, 127, 109, 129, 70, 106, 83, 110, 123, 128, 124, 130, 98, 111, 111, 116, 127, 131, 131, 133, 100, 112, 112, 117, 128, 132, 132, 134, 6, 15, 15, 40, 51, 56, 56, 68, 7, 16, 16, 41, 54, 58, 58, 69, 13, 17, 40, 48, 52, 57, 65, 70, 14, 18, 41, 49, 55, 59, 66, 71, 13, 40, 17, 48, 52, 65, 57, 70, 14, 41, 18, 49, 55, 66, 59, 71, 36, 42, 42, 62, 55, 66, 66, 72, 37, 43, 43, 63, 64, 67, 67, 73, 8, 17, 17, 42, 74, 75, 75, 96, 9, 18, 18, 43, 77, 78, 78, 97, 17, 23, 48, 62, 75, 76, 98, 100, 18, 24, 49, 63, 78, 79, 99, 101, 17, 48, 23, 62, 75, 98, 76, 100, 18, 49, 24, 63, 78, 99, 79, 101, 42, 62, 62, 94, 96, 100, 100, 102, 43, 63, 63, 95, 97, 101, 101, 103, 15, 26, 56, 65, 56, 65, 104, 105, 20, 27, 58, 66, 68, 70, 105, 106, 20, 27, 68, 70, 58, 66, 105, 106, 25, 28, 69, 71, 69, 71, 106, 107, 52, 65, 75, 98, 75, 98, 108, 111, 55, 66, 78, 99, 96, 100, 109, 112, 55, 66, 96, 100, 78, 99, 109, 112, 64, 67, 97, 101, 97, 101, 110, 113, 17, 27, 57, 66, 75, 80, 108, 109, 21, 28, 59, 67, 82, 83, 109, 110, 27, 29, 70, 72, 80, 81, 111, 112, 28, 30, 71, 73, 83, 84, 112, 113, 57, 70, 76, 100, 108, 111, 114, 116, 59, 71, 79, 101, 109, 112, 115, 117, 66, 72, 100, 102, 109, 112, 116, 118, 67, 73, 101, 103, 110, 113, 117, 119, 15, 56, 26, 65, 56, 104, 65, 105, 20, 58, 27, 66, 68, 105, 70, 106, 52, 75, 65, 98, 75, 108, 98, 111, 55, 78, 66, 99, 96, 109, 100, 112, 20, 68, 27, 70, 58, 105, 66, 106, 25, 69, 28, 71, 69, 106, 71, 107, 55, 96, 66, 100, 78, 109, 99, 112, 64, 97, 67, 101, 97, 110, 101, 113, 17, 57, 27, 66, 75, 108, 80, 109, 21, 59, 28, 67, 82, 109, 83, 110, 57, 76, 70, 100, 108, 114, 111, 116, 59, 79, 71, 101, 109, 115, 112, 117, 27, 70, 29, 72, 80, 111, 81, 112, 28, 71, 30, 73, 83, 112, 84, 113, 66, 100, 72, 102, 109, 116, 112, 118, 67, 101, 73, 103, 110, 117, 113, 119, 40, 65, 65, 98, 68, 105, 105, 127, 45, 70, 70, 100, 121, 123, 123, 128, 58, 80, 105, 111, 82, 109, 127, 131, 69, 83, 106, 112, 122, 124, 128, 132, 58, 105, 80, 111, 82, 127, 109, 131, 69, 106, 83, 112, 122, 128, 124, 132, 78, 109, 109, 116, 90, 129, 129, 133, 97, 110, 110, 117, 126, 130, 130, 134, 42, 66, 66, 99, 96, 109, 109, 129, 46, 71, 71, 101, 122, 124, 124, 130, 66, 81, 106, 112, 109, 115, 131, 133, 71, 84, 107, 113, 124, 125, 132, 134, 66, 106, 81, 112, 109, 131, 115, 133, 71, 107, 84, 113, 124, 132, 125, 134, 99, 112, 112, 118, 129, 133, 133, 135, 101, 113, 113, 119, 130, 134, 134, 136, 2, 6, 12, 15, 6, 13, 15, 20, 6, 8, 15, 17, 15, 17, 26, 27, 3, 7, 19, 20, 7, 14, 20, 25, 7, 9, 20, 21, 16, 18, 27, 28, 6, 15, 15, 26, 8, 17, 17, 27, 13, 17, 20, 27, 17, 23, 27, 29, 7, 16, 20, 27, 9, 18, 21, 28, 14, 18, 25, 28, 18, 24, 28, 30, 12, 15, 38, 40, 51, 52, 56, 58, 15, 17, 40, 42, 56, 57, 65, 66, 19, 20, 44, 45, 54, 55, 68, 69, 20, 21, 45, 46, 58, 59, 70, 71, 51, 56, 56, 65, 74, 75, 75, 80, 52, 57, 58, 66, 75, 76, 80, 81, 54, 58, 68, 70, 77, 78, 82, 83, 55, 59, 69, 71, 78, 79, 83, 84, 6, 13, 51, 52, 13, 36, 52, 55, 15, 17, 56, 57, 40, 42, 65, 66, 7, 14, 54, 55, 14, 37, 55, 64, 16, 18, 58, 59, 41, 43, 66, 67, 15, 40, 56, 65, 17, 42, 57, 66, 40, 48, 68, 70, 48, 62, 70, 72, 16, 41, 58, 66, 18, 43, 59, 67, 41, 49, 69, 71, 49, 63, 71, 73, 15, 20, 56, 58, 52, 55, 75, 78, 26, 27, 65, 66, 65, 66, 98, 99, 20, 25, 68, 69, 55, 64, 96, 97, 27, 28, 70, 71, 66, 67, 100, 101, 56, 68, 104, 105, 75, 96, 108, 109, 65, 70, 105, 106, 98, 100, 111, 112, 58, 69, 105, 106, 78, 97, 109, 110, 66, 71, 106, 107, 99, 101, 112, 113, 12, 51, 38, 56, 15, 52, 40, 58, 51, 74, 56, 75, 56, 75, 65, 80, 19, 54, 44, 68, 20, 55, 45, 69, 54, 77, 68, 82, 58, 78, 70, 83, 15, 56, 40, 65, 17, 57, 42, 66, 52, 75, 58, 80, 57, 76, 66, 81, 20, 58, 45, 70, 21, 59, 46, 71, 55, 78, 69, 83, 59, 79, 71, 84, 38, 56, 44, 68, 56, 75, 68, 82, 56, 75, 68, 96, 104, 108, 105, 109, 44, 68, 120, 121, 68, 96, 121, 122, 68, 82, 121, 122, 105, 109, 123, 124, 56, 104, 68, 105, 75, 108, 96, 109, 75, 108, 82, 109, 108, 114, 109, 115, 68, 105, 121, 123, 82, 109, 122, 124, 96, 109, 122, 124, 109, 115, 124, 125, 15, 52, 56, 75, 20, 55, 58, 78, 56, 75, 104, 108, 68, 96, 105, 109, 20, 55, 68, 96, 25, 64, 69, 97, 58, 78, 105, 109, 69, 97, 106, 110, 26, 65, 65, 98, 27, 66, 66, 99, 65, 98, 105, 111, 70, 100, 106, 112, 27, 66, 70, 100, 28, 67, 71, 101, 66, 99, 106, 112, 71, 101, 107, 113, 40, 58, 68, 82, 58, 78, 82, 90, 65, 80, 105, 109, 105, 109, 127, 129, 45, 69, 121, 122, 69, 97, 122, 126, 70, 83, 123, 124, 106, 110, 128, 130, 65, 105, 105, 127, 80, 109, 109, 129, 98, 111, 127, 131, 111, 116, 131, 133, 70, 106, 123, 128, 83, 110, 124, 130, 100, 112, 128, 132, 112, 117, 132, 134, 6, 15, 51, 56, 15, 40, 56, 68, 13, 17, 52, 57, 40, 48, 65, 70, 7, 16, 54, 58, 16, 41, 58, 69, 14, 18, 55, 59, 41, 49, 66, 71, 13, 40, 52, 65, 17, 48, 57, 70, 36, 42, 55, 66, 42, 62, 66, 72, 14, 41, 55, 66, 18, 49, 59, 71, 37, 43, 64, 67, 43, 63, 67, 73, 15, 26, 56, 65, 56, 65, 104, 105, 20, 27, 58, 66, 68, 70, 105, 106, 20, 27, 68, 70, 58, 66, 105, 106, 25, 28, 69, 71, 69, 71, 106, 107, 52, 65, 75, 98, 75, 98, 108, 111, 55, 66, 78, 99, 96, 100, 109, 112, 55, 66, 96, 100, 78, 99, 109, 112, 64, 67, 97, 101, 97, 101, 110, 113, 8, 17, 74, 75, 17, 42, 75, 96, 17, 23, 75, 76, 48, 62, 98, 100, 9, 18, 77, 78, 18, 43, 78, 97, 18, 24, 78, 79, 49, 63, 99, 101, 17, 48, 75, 98, 23, 62, 76, 100, 42, 62, 96, 100, 62, 94, 100, 102, 18, 49, 78, 99, 24, 63, 79, 101, 43, 63, 97, 101, 63, 95, 101, 103, 17, 27, 75, 80, 57, 66, 108, 109, 27, 29, 80, 81, 70, 72, 111, 112, 21, 28, 82, 83, 59, 67, 109, 110, 28, 30, 83, 84, 71, 73, 112, 113, 57, 70, 108, 111, 76, 100, 114, 116, 66, 72, 109, 112, 100, 102, 116, 118, 59, 71, 109, 112, 79, 101, 115, 117, 67, 73, 110, 113, 101, 103, 117, 119, 15, 56, 56, 104, 26, 65, 65, 105, 52, 75, 75, 108, 65, 98, 98, 111, 20, 58, 68, 105, 27, 66, 70, 106, 55, 78, 96, 109, 66, 99, 100, 112, 20, 68, 58, 105, 27, 70, 66, 106, 55, 96, 78, 109, 66, 100, 99, 112, 25, 69, 69, 106, 28, 71, 71, 107, 64, 97, 97, 110, 67, 101, 101, 113, 40, 65, 68, 105, 65, 98, 105, 127, 58, 80, 82, 109, 105, 111, 127, 131, 45, 70, 121, 123, 70, 100, 123, 128, 69, 83, 122, 124, 106, 112, 128, 132, 58, 105, 82, 127, 80, 111, 109, 131, 78, 109, 90, 129, 109, 116, 129, 133, 69, 106, 122, 128, 83, 112, 124, 132, 97, 110, 126, 130, 110, 117, 130, 134, 17, 57, 75, 108, 27, 66, 80, 109, 57, 76, 108, 114, 70, 100, 111, 116, 21, 59, 82, 109, 28, 67, 83, 110, 59, 79, 109, 115, 71, 101, 112, 117, 27, 70, 80, 111, 29, 72, 81, 112, 66, 100, 109, 116, 72, 102, 112, 118, 28, 71, 83, 112, 30, 73, 84, 113, 67, 101, 110, 117, 73, 103, 113, 119, 42, 66, 96, 109, 66, 99, 109, 129, 66, 81, 109, 115, 106, 112, 131, 133, 46, 71, 122, 124, 71, 101, 124, 130, 71, 84, 124, 125, 107, 113, 132, 134, 66, 106, 109, 131, 81, 112, 115, 133, 99, 112, 129, 133, 112, 118, 133, 135, 71, 107, 124, 132, 84, 113, 125, 134, 101, 113, 130, 134, 113, 119, 134, 136, 4, 7, 13, 16, 13, 16, 17, 21, 7, 9, 16, 18, 20, 21, 27, 28, 7, 9, 20, 21, 16, 18, 27, 28, 9, 10, 21, 22, 21, 22, 29, 30, 13, 20, 17, 27, 17, 27, 23, 29, 16, 21, 21, 28, 27, 29, 29, 31, 16, 21, 27, 29, 21, 28, 29, 31, 18, 22, 28, 30, 28, 30, 31, 32, 13, 16, 39, 41, 52, 53, 57, 59, 16, 18, 41, 43, 58, 59, 66, 67, 20, 21, 45, 46, 58, 59, 70, 71, 21, 22, 46, 47, 60, 61, 72, 73, 52, 58, 57, 66, 75, 80, 76, 81, 53, 59, 59, 67, 80, 81, 81, 85, 58, 60, 70, 72, 82, 83, 86, 87, 59, 61, 71, 73, 83, 84, 87, 88, 13, 16, 52, 53, 39, 41, 57, 59, 20, 21, 58, 59, 45, 46, 70, 71, 16, 18, 58, 59, 41, 43, 66, 67, 21, 22, 60, 61, 46, 47, 72, 73, 52, 58, 75, 80, 57, 66, 76, 81, 58, 60, 82, 83, 70, 72, 86, 87, 53, 59, 80, 81, 59, 67, 81, 85, 59, 61, 83, 84, 71, 73, 87, 88, 17, 21, 57, 59, 57, 59, 76, 79, 27, 28, 66, 67, 70, 71, 100, 101, 27, 28, 70, 71, 66, 67, 100, 101, 29, 30, 72, 73, 72, 73, 102, 103, 75, 82, 108, 109, 108, 109, 114, 115, 80, 83, 109, 110, 111, 112, 116, 117, 80, 83, 111, 112, 109, 110, 116, 117, 81, 84, 112, 113, 112, 113, 118, 119, 35, 54, 40, 58, 40, 58, 48, 60, 54, 77, 58, 78, 68, 82, 70, 83, 54, 77, 68, 82, 58, 78, 70, 83, 77, 89, 82, 90, 82, 90, 86, 91, 40, 68, 48, 70, 48, 70, 62, 72, 58, 82, 60, 83, 70, 86, 72, 87, 58, 82, 70, 86, 60, 83, 72, 87, 78, 90, 83, 91, 83, 91, 87, 92, 40, 58, 45, 69, 65, 80, 70, 83, 58, 78, 69, 97, 105, 109, 106, 110, 68, 82, 121, 122, 105, 109, 123, 124, 82, 90, 122, 126, 127, 129, 128, 130, 65, 105, 70, 106, 98, 111, 100, 112, 80, 109, 83, 110, 111, 116, 112, 117, 105, 127, 123, 128, 127, 131, 128, 132, 109, 129, 124, 130, 131, 133, 132, 134, 40, 58, 65, 80, 45, 69, 70, 83, 68, 82, 105, 109, 121, 122, 123, 124, 58, 78, 105, 109, 69, 97, 106, 110, 82, 90, 127, 129, 122, 126, 128, 130, 65, 105, 98, 111, 70, 106, 100, 112, 105, 127, 127, 131, 123, 128, 128, 132, 80, 109, 111, 116, 83, 110, 112, 117, 109, 129, 131, 133, 124, 130, 132, 134, 48, 60, 70, 83, 70, 83, 86, 91, 70, 83, 106, 110, 123, 124, 128, 130, 70, 83, 123, 124, 106, 110, 128, 130, 86, 91, 128, 130, 128, 130, 141, 142, 98, 127, 111, 131, 111, 131, 116, 133, 111, 131, 131, 143, 144, 145, 145, 146, 111, 131, 144, 145, 131, 143, 145, 146, 116, 133, 145, 146, 145, 146, 147, 148, 13, 20, 52, 58, 52, 58, 75, 82, 16, 21, 53, 59, 58, 60, 80, 83, 16, 21, 58, 60, 53, 59, 80, 83, 18, 22, 59, 61, 59, 61, 81, 84, 39, 45, 57, 70, 57, 70, 76, 86, 41, 46, 59, 71, 66, 72, 81, 87, 41, 46, 66, 72, 59, 71, 81, 87, 43, 47, 67, 73, 67, 73, 85, 88, 17, 27, 57, 66, 75, 80, 108, 109, 21, 28, 59, 67, 82, 83, 109, 110, 27, 29, 70, 72, 80, 81, 111, 112, 28, 30, 71, 73, 83, 84, 112, 113, 57, 70, 76, 100, 108, 111, 114, 116, 59, 71, 79, 101, 109, 112, 115, 117, 66, 72, 100, 102, 109, 112, 116, 118, 67, 73, 101, 103, 110, 113, 117, 119, 17, 27, 75, 80, 57, 66, 108, 109, 27, 29, 80, 81, 70, 72, 111, 112, 21, 28, 82, 83, 59, 67, 109, 110, 28, 30, 83, 84, 71, 73, 112, 113, 57, 70, 108, 111, 76, 100, 114, 116, 66, 72, 109, 112, 100, 102, 116, 118, 59, 71, 109, 112, 79, 101, 115, 117, 67, 73, 110, 113, 101, 103, 117, 119, 23, 29, 76, 81, 76, 81, 114, 115, 29, 31, 81, 85, 86, 87, 116, 117, 29, 31, 86, 87, 81, 85, 116, 117, 31, 32, 87, 88, 87, 88, 118, 119, 76, 86, 114, 116, 114, 116, 137, 138, 81, 87, 115, 117, 116, 118, 138, 139, 81, 87, 116, 118, 115, 117, 138, 139, 85, 88, 117, 119, 117, 119, 139, 140, 40, 68, 65, 105, 65, 105, 98, 127, 58, 82, 80, 109, 105, 127, 111, 131, 58, 82, 105, 127, 80, 109, 111, 131, 78, 90, 109, 129, 109, 129, 116, 133, 45, 121, 70, 123, 70, 123, 100, 128, 69, 122, 83, 124, 106, 128, 112, 132, 69, 122, 106, 128, 83, 124, 112, 132, 97, 126, 110, 130, 110, 130, 117, 134, 48, 70, 70, 106, 98, 111, 111, 131, 60, 83, 83, 110, 127, 131, 131, 143, 70, 86, 123, 128, 111, 116, 144, 145, 83, 91, 124, 130, 131, 133, 145, 146, 70, 123, 86, 128, 111, 144, 116, 145, 83, 124, 91, 130, 131, 145, 133, 146, 106, 128, 128, 141, 131, 145, 145, 147, 110, 130, 130, 142, 143, 146, 146, 148, 48, 70, 98, 111, 70, 106, 111, 131, 70, 86, 111, 116, 123, 128, 144, 145, 60, 83, 127, 131, 83, 110, 131, 143, 83, 91, 131, 133, 124, 130, 145, 146, 70, 123, 111, 144, 86, 128, 116, 145, 106, 128, 131, 145, 128, 141, 145, 147, 83, 124, 131, 145, 91, 130, 133, 146, 110, 130, 143, 146, 130, 142, 146, 148, 62, 72, 100, 112, 100, 112, 116, 133, 72, 87, 112, 117, 128, 132, 145, 146, 72, 87, 128, 132, 112, 117, 145, 146, 87, 92, 132, 134, 132, 134, 147, 148, 100, 128, 116, 145, 116, 145, 138, 149, 112, 132, 133, 146, 145, 147, 149, 150, 112, 132, 145, 147, 133, 146, 149, 150, 117, 134, 146, 148, 146, 148, 150, 151, 2, 12, 6, 15, 6, 15, 13, 20, 6, 15, 8, 17, 15, 26, 17, 27, 6, 15, 15, 26, 8, 17, 17, 27, 13, 20, 17, 27, 17, 27, 23, 29, 3, 19, 7, 20, 7, 20, 14, 25, 7, 20, 9, 21, 16, 27, 18, 28, 7, 20, 16, 27, 9, 21, 18, 28, 14, 25, 18, 28, 18, 28, 24, 30, 12, 38, 15, 40, 51, 56, 52, 58, 15, 40, 17, 42, 56, 65, 57, 66, 51, 56, 56, 65, 74, 75, 75, 80, 52, 58, 57, 66, 75, 80, 76, 81, 19, 44, 20, 45, 54, 68, 55, 69, 20, 45, 21, 46, 58, 70, 59, 71, 54, 68, 58, 70, 77, 82, 78, 83, 55, 69, 59, 71, 78, 83, 79, 84, 12, 38, 51, 56, 15, 40, 52, 58, 51, 56, 74, 75, 56, 65, 75, 80, 15, 40, 56, 65, 17, 42, 57, 66, 52, 58, 75, 80, 57, 66, 76, 81, 19, 44, 54, 68, 20, 45, 55, 69, 54, 68, 77, 82, 58, 70, 78, 83, 20, 45, 58, 70, 21, 46, 59, 71, 55, 69, 78, 83, 59, 71, 79, 84, 38, 44, 56, 68, 56, 68, 75, 82, 56, 68, 75, 96, 104, 105, 108, 109, 56, 68, 104, 105, 75, 96, 108, 109, 75, 82, 108, 109, 108, 109, 114, 115, 44, 120, 68, 121, 68, 121, 96, 122, 68, 121, 82, 122, 105, 123, 109, 124, 68, 121, 105, 123, 82, 122, 109, 124, 96, 122, 109, 124, 109, 124, 115, 125, 6, 51, 13, 52, 13, 52, 36, 55, 15, 56, 17, 57, 40, 65, 42, 66, 15, 56, 40, 65, 17, 57, 42, 66, 40, 68, 48, 70, 48, 70, 62, 72, 7, 54, 14, 55, 14, 55, 37, 64, 16, 58, 18, 59, 41, 66, 43, 67, 16, 58, 41, 66, 18, 59, 43, 67, 41, 69, 49, 71, 49, 71, 63, 73, 15, 56, 20, 58, 52, 75, 55, 78, 26, 65, 27, 66, 65, 98, 66, 99, 56, 104, 68, 105, 75, 108, 96, 109, 65, 105, 70, 106, 98, 111, 100, 112, 20, 68, 25, 69, 55, 96, 64, 97, 27, 70, 28, 71, 66, 100, 67, 101, 58, 105, 69, 106, 78, 109, 97, 110, 66, 106, 71, 107, 99, 112, 101, 113, 15, 56, 52, 75, 20, 58, 55, 78, 56, 104, 75, 108, 68, 105, 96, 109, 26, 65, 65, 98, 27, 66, 66, 99, 65, 105, 98, 111, 70, 106, 100, 112, 20, 68, 55, 96, 25, 69, 64, 97, 58, 105, 78, 109, 69, 106, 97, 110, 27, 70, 66, 100, 28, 71, 67, 101, 66, 106, 99, 112, 71, 107, 101, 113, 40, 68, 58, 82, 58, 82, 78, 90, 65, 105, 80, 109, 105, 127, 109, 129, 65, 105, 105, 127, 80, 109, 109, 129, 98, 127, 111, 131, 111, 131, 116, 133, 45, 121, 69, 122, 69, 122, 97, 126, 70, 123, 83, 124, 106, 128, 110, 130, 70, 123, 106, 128, 83, 124, 110, 130, 100, 128, 112, 132, 112, 132, 117, 134, 6, 51, 15, 56, 15, 56, 40, 68, 13, 52, 17, 57, 40, 65, 48, 70, 13, 52, 40, 65, 17, 57, 48, 70, 36, 55, 42, 66, 42, 66, 62, 72, 7, 54, 16, 58, 16, 58, 41, 69, 14, 55, 18, 59, 41, 66, 49, 71, 14, 55, 41, 66, 18, 59, 49, 71, 37, 64, 43, 67, 43, 67, 63, 73, 15, 56, 26, 65, 56, 104, 65, 105, 20, 58, 27, 66, 68, 105, 70, 106, 52, 75, 65, 98, 75, 108, 98, 111, 55, 78, 66, 99, 96, 109, 100, 112, 20, 68, 27, 70, 58, 105, 66, 106, 25, 69, 28, 71, 69, 106, 71, 107, 55, 96, 66, 100, 78, 109, 99, 112, 64, 97, 67, 101, 97, 110, 101, 113, 15, 56, 56, 104, 26, 65, 65, 105, 52, 75, 75, 108, 65, 98, 98, 111, 20, 58, 68, 105, 27, 66, 70, 106, 55, 78, 96, 109, 66, 99, 100, 112, 20, 68, 58, 105, 27, 70, 66, 106, 55, 96, 78, 109, 66, 100, 99, 112, 25, 69, 69, 106, 28, 71, 71, 107, 64, 97, 97, 110, 67, 101, 101, 113, 40, 68, 65, 105, 65, 105, 98, 127, 58, 82, 80, 109, 105, 127, 111, 131, 58, 82, 105, 127, 80, 109, 111, 131, 78, 90, 109, 129, 109, 129, 116, 133, 45, 121, 70, 123, 70, 123, 100, 128, 69, 122, 83, 124, 106, 128, 112, 132, 69, 122, 106, 128, 83, 124, 112, 132, 97, 126, 110, 130, 110, 130, 117, 134, 8, 74, 17, 75, 17, 75, 42, 96, 17, 75, 23, 76, 48, 98, 62, 100, 17, 75, 48, 98, 23, 76, 62, 100, 42, 96, 62, 100, 62, 100, 94, 102, 9, 77, 18, 78, 18, 78, 43, 97, 18, 78, 24, 79, 49, 99, 63, 101, 18, 78, 49, 99, 24, 79, 63, 101, 43, 97, 63, 101, 63, 101, 95, 103, 17, 75, 27, 80, 57, 108, 66, 109, 27, 80, 29, 81, 70, 111, 72, 112, 57, 108, 70, 111, 76, 114, 100, 116, 66, 109, 72, 112, 100, 116, 102, 118, 21, 82, 28, 83, 59, 109, 67, 110, 28, 83, 30, 84, 71, 112, 73, 113, 59, 109, 71, 112, 79, 115, 101, 117, 67, 110, 73, 113, 101, 117, 103, 119, 17, 75, 57, 108, 27, 80, 66, 109, 57, 108, 76, 114, 70, 111, 100, 116, 27, 80, 70, 111, 29, 81, 72, 112, 66, 109, 100, 116, 72, 112, 102, 118, 21, 82, 59, 109, 28, 83, 67, 110, 59, 109, 79, 115, 71, 112, 101, 117, 28, 83, 71, 112, 30, 84, 73, 113, 67, 110, 101, 117, 73, 113, 103, 119, 42, 96, 66, 109, 66, 109, 99, 129, 66, 109, 81, 115, 106, 131, 112, 133, 66, 109, 106, 131, 81, 115, 112, 133, 99, 129, 112, 133, 112, 133, 118, 135, 46, 122, 71, 124, 71, 124, 101, 130, 71, 124, 84, 125, 107, 132, 113, 134, 71, 124, 107, 132, 84, 125, 113, 134, 101, 130, 113, 134, 113, 134, 119, 136, 4, 13, 7, 16, 13, 17, 16, 21, 7, 16, 9, 18, 20, 27, 21, 28, 13, 17, 20, 27, 17, 23, 27, 29, 16, 21, 21, 28, 27, 29, 29, 31, 7, 20, 9, 21, 16, 27, 18, 28, 9, 21, 10, 22, 21, 29, 22, 30, 16, 27, 21, 29, 21, 29, 28, 31, 18, 28, 22, 30, 28, 31, 30, 32, 13, 39, 16, 41, 52, 57, 53, 59, 16, 41, 18, 43, 58, 66, 59, 67, 52, 57, 58, 66, 75, 76, 80, 81, 53, 59, 59, 67, 80, 81, 81, 85, 20, 45, 21, 46, 58, 70, 59, 71, 21, 46, 22, 47, 60, 72, 61, 73, 58, 70, 60, 72, 82, 86, 83, 87, 59, 71, 61, 73, 83, 87, 84, 88, 35, 40, 54, 58, 40, 48, 58, 60, 54, 58, 77, 78, 68, 70, 82, 83, 40, 48, 68, 70, 48, 62, 70, 72, 58, 60, 82, 83, 70, 72, 86, 87, 54, 68, 77, 82, 58, 70, 78, 83, 77, 82, 89, 90, 82, 86, 90, 91, 58, 70, 82, 86, 60, 72, 83, 87, 78, 83, 90, 91, 83, 87, 91, 92, 40, 45, 58, 69, 65, 70, 80, 83, 58, 69, 78, 97, 105, 106, 109, 110, 65, 70, 105, 106, 98, 100, 111, 112, 80, 83, 109, 110, 111, 112, 116, 117, 68, 121, 82, 122, 105, 123, 109, 124, 82, 122, 90, 126, 127, 128, 129, 130, 105, 123, 127, 128, 127, 128, 131, 132, 109, 124, 129, 130, 131, 132, 133, 134, 13, 52, 16, 53, 39, 57, 41, 59, 20, 58, 21, 59, 45, 70, 46, 71, 52, 75, 58, 80, 57, 76, 66, 81, 58, 82, 60, 83, 70, 86, 72, 87, 16, 58, 18, 59, 41, 66, 43, 67, 21, 60, 22, 61, 46, 72, 47, 73, 53, 80, 59, 81, 59, 81, 67, 85, 59, 83, 61, 84, 71, 87, 73, 88, 17, 57, 21, 59, 57, 76, 59, 79, 27, 66, 28, 67, 70, 100, 71, 101, 75, 108, 82, 109, 108, 114, 109, 115, 80, 109, 83, 110, 111, 116, 112, 117, 27, 70, 28, 71, 66, 100, 67, 101, 29, 72, 30, 73, 72, 102, 73, 103, 80, 111, 83, 112, 109, 116, 110, 117, 81, 112, 84, 113, 112, 118, 113, 119, 40, 65, 58, 80, 45, 70, 69, 83, 68, 105, 82, 109, 121, 123, 122, 124, 65, 98, 105, 111, 70, 100, 106, 112, 105, 127, 127, 131, 123, 128, 128, 132, 58, 105, 78, 109, 69, 106, 97, 110, 82, 127, 90, 129, 122, 128, 126, 130, 80, 111, 109, 116, 83, 112, 110, 117, 109, 131, 129, 133, 124, 132, 130, 134, 48, 70, 60, 83, 70, 86, 83, 91, 70, 106, 83, 110, 123, 128, 124, 130, 98, 111, 127, 131, 111, 116, 131, 133, 111, 131, 131, 143, 144, 145, 145, 146, 70, 123, 83, 124, 106, 128, 110, 130, 86, 128, 91, 130, 128, 141, 130, 142, 111, 144, 131, 145, 131, 145, 143, 146, 116, 145, 133, 146, 145, 147, 146, 148, 13, 52, 20, 58, 52, 75, 58, 82, 16, 53, 21, 59, 58, 80, 60, 83, 39, 57, 45, 70, 57, 76, 70, 86, 41, 59, 46, 71, 66, 81, 72, 87, 16, 58, 21, 60, 53, 80, 59, 83, 18, 59, 22, 61, 59, 81, 61, 84, 41, 66, 46, 72, 59, 81, 71, 87, 43, 67, 47, 73, 67, 85, 73, 88, 17, 57, 27, 66, 75, 108, 80, 109, 21, 59, 28, 67, 82, 109, 83, 110, 57, 76, 70, 100, 108, 114, 111, 116, 59, 79, 71, 101, 109, 115, 112, 117, 27, 70, 29, 72, 80, 111, 81, 112, 28, 71, 30, 73, 83, 112, 84, 113, 66, 100, 72, 102, 109, 116, 112, 118, 67, 101, 73, 103, 110, 117, 113, 119, 40, 65, 68, 105, 65, 98, 105, 127, 58, 80, 82, 109, 105, 111, 127, 131, 45, 70, 121, 123, 70, 100, 123, 128, 69, 83, 122, 124, 106, 112, 128, 132, 58, 105, 82, 127, 80, 111, 109, 131, 78, 109, 90, 129, 109, 116, 129, 133, 69, 106, 122, 128, 83, 112, 124, 132, 97, 110, 126, 130, 110, 117, 130, 134, 48, 70, 70, 106, 98, 111, 111, 131, 60, 83, 83, 110, 127, 131, 131, 143, 70, 86, 123, 128, 111, 116, 144, 145, 83, 91, 124, 130, 131, 133, 145, 146, 70, 123, 86, 128, 111, 144, 116, 145, 83, 124, 91, 130, 131, 145, 133, 146, 106, 128, 128, 141, 131, 145, 145, 147, 110, 130, 130, 142, 143, 146, 146, 148, 17, 75, 27, 80, 57, 108, 66, 109, 27, 80, 29, 81, 70, 111, 72, 112, 57, 108, 70, 111, 76, 114, 100, 116, 66, 109, 72, 112, 100, 116, 102, 118, 21, 82, 28, 83, 59, 109, 67, 110, 28, 83, 30, 84, 71, 112, 73, 113, 59, 109, 71, 112, 79, 115, 101, 117, 67, 110, 73, 113, 101, 117, 103, 119, 23, 76, 29, 81, 76, 114, 81, 115, 29, 81, 31, 85, 86, 116, 87, 117, 76, 114, 86, 116, 114, 137, 116, 138, 81, 115, 87, 117, 116, 138, 118, 139, 29, 86, 31, 87, 81, 116, 85, 117, 31, 87, 32, 88, 87, 118, 88, 119, 81, 116, 87, 118, 115, 138, 117, 139, 85, 117, 88, 119, 117, 139, 119, 140, 48, 98, 70, 111, 70, 111, 106, 131, 70, 111, 86, 116, 123, 144, 128, 145, 70, 111, 123, 144, 86, 116, 128, 145, 106, 131, 128, 145, 128, 145, 141, 147, 60, 127, 83, 131, 83, 131, 110, 143, 83, 131, 91, 133, 124, 145, 130, 146, 83, 131, 124, 145, 91, 133, 130, 146, 110, 143, 130, 146, 130, 146, 142, 148, 62, 100, 72, 112, 100, 116, 112, 133, 72, 112, 87, 117, 128, 145, 132, 146, 100, 116, 128, 145, 116, 138, 145, 149, 112, 133, 132, 146, 145, 149, 147, 150, 72, 128, 87, 132, 112, 145, 117, 146, 87, 132, 92, 134, 132, 147, 134, 148, 112, 145, 132, 147, 133, 149, 146, 150, 117, 146, 134, 148, 146, 150, 148, 151, 4, 13, 13, 17, 7, 16, 16, 21, 13, 17, 17, 23, 20, 27, 27, 29, 7, 16, 20, 27, 9, 18, 21, 28, 16, 21, 27, 29, 21, 28, 29, 31, 7, 20, 16, 27, 9, 21, 18, 28, 16, 27, 21, 29, 21, 29, 28, 31, 9, 21, 21, 29, 10, 22, 22, 30, 18, 28, 28, 31, 22, 30, 30, 32, 35, 40, 40, 48, 54, 58, 58, 60, 40, 48, 48, 62, 68, 70, 70, 72, 54, 58, 68, 70, 77, 78, 82, 83, 58, 60, 70, 72, 82, 83, 86, 87, 54, 68, 58, 70, 77, 82, 78, 83, 58, 70, 60, 72, 82, 86, 83, 87, 77, 82, 82, 86, 89, 90, 90, 91, 78, 83, 83, 87, 90, 91, 91, 92, 13, 39, 52, 57, 16, 41, 53, 59, 52, 57, 75, 76, 58, 66, 80, 81, 16, 41, 58, 66, 18, 43, 59, 67, 53, 59, 80, 81, 59, 67, 81, 85, 20, 45, 58, 70, 21, 46, 59, 71, 58, 70, 82, 86, 60, 72, 83, 87, 21, 46, 60, 72, 22, 47, 61, 73, 59, 71, 83, 87, 61, 73, 84, 88, 40, 45, 65, 70, 58, 69, 80, 83, 65, 70, 98, 100, 105, 106, 111, 112, 58, 69, 105, 106, 78, 97, 109, 110, 80, 83, 111, 112, 109, 110, 116, 117, 68, 121, 105, 123, 82, 122, 109, 124, 105, 123, 127, 128, 127, 128, 131, 132, 82, 122, 127, 128, 90, 126, 129, 130, 109, 124, 131, 132, 129, 130, 133, 134, 13, 52, 39, 57, 16, 53, 41, 59, 52, 75, 57, 76, 58, 80, 66, 81, 20, 58, 45, 70, 21, 59, 46, 71, 58, 82, 70, 86, 60, 83, 72, 87, 16, 58, 41, 66, 18, 59, 43, 67, 53, 80, 59, 81, 59, 81, 67, 85, 21, 60, 46, 72, 22, 61, 47, 73, 59, 83, 71, 87, 61, 84, 73, 88, 40, 65, 45, 70, 58, 80, 69, 83, 65, 98, 70, 100, 105, 111, 106, 112, 68, 105, 121, 123, 82, 109, 122, 124, 105, 127, 123, 128, 127, 131, 128, 132, 58, 105, 69, 106, 78, 109, 97, 110, 80, 111, 83, 112, 109, 116, 110, 117, 82, 127, 122, 128, 90, 129, 126, 130, 109, 131, 124, 132, 129, 133, 130, 134, 17, 57, 57, 76, 21, 59, 59, 79, 75, 108, 108, 114, 82, 109, 109, 115, 27, 66, 70, 100, 28, 67, 71, 101, 80, 109, 111, 116, 83, 110, 112, 117, 27, 70, 66, 100, 28, 71, 67, 101, 80, 111, 109, 116, 83, 112, 110, 117, 29, 72, 72, 102, 30, 73, 73, 103, 81, 112, 112, 118, 84, 113, 113, 119, 48, 70, 70, 86, 60, 83, 83, 91, 98, 111, 111, 116, 127, 131, 131, 133, 70, 106, 123, 128, 83, 110, 124, 130, 111, 131, 144, 145, 131, 143, 145, 146, 70, 123, 106, 128, 83, 124, 110, 130, 111, 144, 131, 145, 131, 145, 143, 146, 86, 128, 128, 141, 91, 130, 130, 142, 116, 145, 145, 147, 133, 146, 146, 148, 13, 52, 52, 75, 20, 58, 58, 82, 39, 57, 57, 76, 45, 70, 70, 86, 16, 53, 58, 80, 21, 59, 60, 83, 41, 59, 66, 81, 46, 71, 72, 87, 16, 58, 53, 80, 21, 60, 59, 83, 41, 66, 59, 81, 46, 72, 71, 87, 18, 59, 59, 81, 22, 61, 61, 84, 43, 67, 67, 85, 47, 73, 73, 88, 40, 65, 65, 98, 68, 105, 105, 127, 45, 70, 70, 100, 121, 123, 123, 128, 58, 80, 105, 111, 82, 109, 127, 131, 69, 83, 106, 112, 122, 124, 128, 132, 58, 105, 80, 111, 82, 127, 109, 131, 69, 106, 83, 112, 122, 128, 124, 132, 78, 109, 109, 116, 90, 129, 129, 133, 97, 110, 110, 117, 126, 130, 130, 134, 17, 57, 75, 108, 27, 66, 80, 109, 57, 76, 108, 114, 70, 100, 111, 116, 21, 59, 82, 109, 28, 67, 83, 110, 59, 79, 109, 115, 71, 101, 112, 117, 27, 70, 80, 111, 29, 72, 81, 112, 66, 100, 109, 116, 72, 102, 112, 118, 28, 71, 83, 112, 30, 73, 84, 113, 67, 101, 110, 117, 73, 103, 113, 119, 48, 70, 98, 111, 70, 106, 111, 131, 70, 86, 111, 116, 123, 128, 144, 145, 60, 83, 127, 131, 83, 110, 131, 143, 83, 91, 131, 133, 124, 130, 145, 146, 70, 123, 111, 144, 86, 128, 116, 145, 106, 128, 131, 145, 128, 141, 145, 147, 83, 124, 131, 145, 91, 130, 133, 146, 110, 130, 143, 146, 130, 142, 146, 148, 17, 75, 57, 108, 27, 80, 66, 109, 57, 108, 76, 114, 70, 111, 100, 116, 27, 80, 70, 111, 29, 81, 72, 112, 66, 109, 100, 116, 72, 112, 102, 118, 21, 82, 59, 109, 28, 83, 67, 110, 59, 109, 79, 115, 71, 112, 101, 117, 28, 83, 71, 112, 30, 84, 73, 113, 67, 110, 101, 117, 73, 113, 103, 119, 48, 98, 70, 111, 70, 111, 106, 131, 70, 111, 86, 116, 123, 144, 128, 145, 70, 111, 123, 144, 86, 116, 128, 145, 106, 131, 128, 145, 128, 145, 141, 147, 60, 127, 83, 131, 83, 131, 110, 143, 83, 131, 91, 133, 124, 145, 130, 146, 83, 131, 124, 145, 91, 133, 130, 146, 110, 143, 130, 146, 130, 146, 142, 148, 23, 76, 76, 114, 29, 81, 81, 115, 76, 114, 114, 137, 86, 116, 116, 138, 29, 81, 86, 116, 31, 85, 87, 117, 81, 115, 116, 138, 87, 117, 118, 139, 29, 86, 81, 116, 31, 87, 85, 117, 81, 116, 115, 138, 87, 118, 117, 139, 31, 87, 87, 118, 32, 88, 88, 119, 85, 117, 117, 139, 88, 119, 119, 140, 62, 100, 100, 116, 72, 112, 112, 133, 100, 116, 116, 138, 128, 145, 145, 149, 72, 112, 128, 145, 87, 117, 132, 146, 112, 133, 145, 149, 132, 146, 147, 150, 72, 128, 112, 145, 87, 132, 117, 146, 112, 145, 133, 149, 132, 147, 146, 150, 87, 132, 132, 147, 92, 134, 134, 148, 117, 146, 146, 150, 134, 148, 148, 151, 11, 14, 14, 18, 14, 18, 18, 22, 14, 18, 18, 24, 25, 28, 28, 30, 14, 18, 25, 28, 18, 24, 28, 30, 18, 22, 28, 30, 28, 30, 31, 32, 14, 25, 18, 28, 18, 28, 24, 30, 18, 28, 22, 30, 28, 31, 30, 32, 18, 28, 28, 31, 22, 30, 30, 32, 24, 30, 30, 32, 30, 32, 32, 33, 36, 41, 41, 49, 55, 59, 59, 61, 41, 49, 49, 63, 69, 71, 71, 73, 55, 59, 69, 71, 78, 79, 83, 84, 59, 61, 71, 73, 83, 84, 87, 88, 55, 69, 59, 71, 78, 83, 79, 84, 59, 71, 61, 73, 83, 87, 84, 88, 78, 83, 83, 87, 90, 91, 91, 92, 79, 84, 84, 88, 91, 92, 92, 93, 36, 41, 55, 59, 41, 49, 59, 61, 55, 59, 78, 79, 69, 71, 83, 84, 41, 49, 69, 71, 49, 63, 71, 73, 59, 61, 83, 84, 71, 73, 87, 88, 55, 69, 78, 83, 59, 71, 79, 84, 78, 83, 90, 91, 83, 87, 91, 92, 59, 71, 83, 87, 61, 73, 84, 88, 79, 84, 91, 92, 84, 88, 92, 93, 42, 46, 66, 71, 66, 71, 81, 84, 66, 71, 99, 101, 106, 107, 112, 113, 66, 71, 106, 107, 99, 101, 112, 113, 81, 84, 112, 113, 112, 113, 118, 119, 96, 122, 109, 124, 109, 124, 115, 125, 109, 124, 129, 130, 131, 132, 133, 134, 109, 124, 131, 132, 129, 130, 133, 134, 115, 125, 133, 134, 133, 134, 135, 136, 36, 55, 41, 59, 41, 59, 49, 61, 55, 78, 59, 79, 69, 83, 71, 84, 55, 78, 69, 83, 59, 79, 71, 84, 78, 90, 83, 91, 83, 91, 87, 92, 41, 69, 49, 71, 49, 71, 63, 73, 59, 83, 61, 84, 71, 87, 73, 88, 59, 83, 71, 87, 61, 84, 73, 88, 79, 91, 84, 92, 84, 92, 88, 93, 42, 66, 46, 71, 66, 81, 71, 84, 66, 99, 71, 101, 106, 112, 107, 113, 96, 109, 122, 124, 109, 115, 124, 125, 109, 129, 124, 130, 131, 133, 132, 134, 66, 106, 71, 107, 99, 112, 101, 113, 81, 112, 84, 113, 112, 118, 113, 119, 109, 131, 124, 132, 129, 133, 130, 134, 115, 133, 125, 134, 133, 135, 134, 136, 42, 66, 66, 81, 46, 71, 71, 84, 96, 109, 109, 115, 122, 124, 124, 125, 66, 99, 106, 112, 71, 101, 107, 113, 109, 129, 131, 133, 124, 130, 132, 134, 66, 106, 99, 112, 71, 107, 101, 113, 109, 131, 129, 133, 124, 132, 130, 134, 81, 112, 112, 118, 84, 113, 113, 119, 115, 133, 133, 135, 125, 134, 134, 136, 62, 72, 72, 87, 72, 87, 87, 92, 100, 112, 112, 117, 128, 132, 132, 134, 100, 112, 128, 132, 112, 117, 132, 134, 116, 133, 145, 146, 145, 146, 147, 148, 100, 128, 112, 132, 112, 132, 117, 134, 116, 145, 133, 146, 145, 147, 146, 148, 116, 145, 145, 147, 133, 146, 146, 148, 138, 149, 149, 150, 149, 150, 150, 151, 36, 55, 55, 78, 55, 78, 78, 90, 41, 59, 59, 79, 69, 83, 83, 91, 41, 59, 69, 83, 59, 79, 83, 91, 49, 61, 71, 84, 71, 84, 87, 92, 41, 69, 59, 83, 59, 83, 79, 91, 49, 71, 61, 84, 71, 87, 84, 92, 49, 71, 71, 87, 61, 84, 84, 92, 63, 73, 73, 88, 73, 88, 88, 93, 42, 66, 66, 99, 96, 109, 109, 129, 46, 71, 71, 101, 122, 124, 124, 130, 66, 81, 106, 112, 109, 115, 131, 133, 71, 84, 107, 113, 124, 125, 132, 134, 66, 106, 81, 112, 109, 131, 115, 133, 71, 107, 84, 113, 124, 132, 125, 134, 99, 112, 112, 118, 129, 133, 133, 135, 101, 113, 113, 119, 130, 134, 134, 136, 42, 66, 96, 109, 66, 99, 109, 129, 66, 81, 109, 115, 106, 112, 131, 133, 46, 71, 122, 124, 71, 101, 124, 130, 71, 84, 124, 125, 107, 113, 132, 134, 66, 106, 109, 131, 81, 112, 115, 133, 99, 112, 129, 133, 112, 118, 133, 135, 71, 107, 124, 132, 84, 113, 125, 134, 101, 113, 130, 134, 113, 119, 134, 136, 62, 72, 100, 112, 100, 112, 116, 133, 72, 87, 112, 117, 128, 132, 145, 146, 72, 87, 128, 132, 112, 117, 145, 146, 87, 92, 132, 134, 132, 134, 147, 148, 100, 128, 116, 145, 116, 145, 138, 149, 112, 132, 133, 146, 145, 147, 149, 150, 112, 132, 145, 147, 133, 146, 149, 150, 117, 134, 146, 148, 146, 148, 150, 151, 42, 96, 66, 109, 66, 109, 99, 129, 66, 109, 81, 115, 106, 131, 112, 133, 66, 109, 106, 131, 81, 115, 112, 133, 99, 129, 112, 133, 112, 133, 118, 135, 46, 122, 71, 124, 71, 124, 101, 130, 71, 124, 84, 125, 107, 132, 113, 134, 71, 124, 107, 132, 84, 125, 113, 134, 101, 130, 113, 134, 113, 134, 119, 136, 62, 100, 72, 112, 100, 116, 112, 133, 72, 112, 87, 117, 128, 145, 132, 146, 100, 116, 128, 145, 116, 138, 145, 149, 112, 133, 132, 146, 145, 149, 147, 150, 72, 128, 87, 132, 112, 145, 117, 146, 87, 132, 92, 134, 132, 147, 134, 148, 112, 145, 132, 147, 133, 149, 146, 150, 117, 146, 134, 148, 146, 150, 148, 151, 62, 100, 100, 116, 72, 112, 112, 133, 100, 116, 116, 138, 128, 145, 145, 149, 72, 112, 128, 145, 87, 117, 132, 146, 112, 133, 145, 149, 132, 146, 147, 150, 72, 128, 112, 145, 87, 132, 117, 146, 112, 145, 133, 149, 132, 147, 146, 150, 87, 132, 132, 147, 92, 134, 134, 148, 117, 146, 146, 150, 134, 148, 148, 151, 94, 102, 102, 118, 102, 118, 118, 135, 102, 118, 118, 139, 141, 147, 147, 150, 102, 118, 141, 147, 118, 139, 147, 150, 118, 135, 147, 150, 147, 150, 152, 153, 102, 141, 118, 147, 118, 147, 139, 150, 118, 147, 135, 150, 147, 152, 150, 153, 118, 147, 147, 152, 135, 150, 150, 153, 139, 150, 150, 153, 150, 153, 153, 154, 1, 5, 5, 12, 5, 12, 12, 19, 5, 12, 12, 35, 50, 51, 51, 54, 5, 12, 50, 51, 12, 35, 51, 54, 12, 19, 51, 54, 51, 54, 74, 77, 5, 50, 12, 51, 12, 51, 35, 54, 12, 51, 19, 54, 51, 74, 54, 77, 12, 51, 51, 74, 19, 54, 54, 77, 35, 54, 54, 77, 54, 77, 77, 89, 2, 6, 6, 13, 12, 15, 15, 20, 6, 13, 13, 36, 51, 52, 52, 55, 12, 15, 51, 52, 38, 40, 56, 58, 15, 20, 52, 55, 56, 58, 75, 78, 12, 51, 15, 52, 38, 56, 40, 58, 15, 52, 20, 55, 56, 75, 58, 78, 38, 56, 56, 75, 44, 68, 68, 82, 40, 58, 58, 78, 68, 82, 82, 90, 2, 6, 12, 15, 6, 13, 15, 20, 12, 15, 38, 40, 51, 52, 56, 58, 6, 13, 51, 52, 13, 36, 52, 55, 15, 20, 56, 58, 52, 55, 75, 78, 12, 51, 38, 56, 15, 52, 40, 58, 38, 56, 44, 68, 56, 75, 68, 82, 15, 52, 56, 75, 20, 55, 58, 78, 40, 58, 68, 82, 58, 78, 82, 90, 4, 7, 13, 16, 13, 16, 17, 21, 13, 16, 39, 41, 52, 53, 57, 59, 13, 16, 52, 53, 39, 41, 57, 59, 17, 21, 57, 59, 57, 59, 76, 79, 35, 54, 40, 58, 40, 58, 48, 60, 40, 58, 45, 69, 65, 80, 70, 83, 40, 58, 65, 80, 45, 69, 70, 83, 48, 60, 70, 83, 70, 83, 86, 91, 2, 12, 6, 15, 6, 15, 13, 20, 12, 38, 15, 40, 51, 56, 52, 58, 12, 38, 51, 56, 15, 40, 52, 58, 38, 44, 56, 68, 56, 68, 75, 82, 6, 51, 13, 52, 13, 52, 36, 55, 15, 56, 20, 58, 52, 75, 55, 78, 15, 56, 52, 75, 20, 58, 55, 78, 40, 68, 58, 82, 58, 82, 78, 90, 4, 13, 7, 16, 13, 17, 16, 21, 13, 39, 16, 41, 52, 57, 53, 59, 35, 40, 54, 58, 40, 48, 58, 60, 40, 45, 58, 69, 65, 70, 80, 83, 13, 52, 16, 53, 39, 57, 41, 59, 17, 57, 21, 59, 57, 76, 59, 79, 40, 65, 58, 80, 45, 70, 69, 83, 48, 70, 60, 83, 70, 86, 83, 91, 4, 13, 13, 17, 7, 16, 16, 21, 35, 40, 40, 48, 54, 58, 58, 60, 13, 39, 52, 57, 16, 41, 53, 59, 40, 45, 65, 70, 58, 69, 80, 83, 13, 52, 39, 57, 16, 53, 41, 59, 40, 65, 45, 70, 58, 80, 69, 83, 17, 57, 57, 76, 21, 59, 59, 79, 48, 70, 70, 86, 60, 83, 83, 91, 11, 14, 14, 18, 14, 18, 18, 22, 36, 41, 41, 49, 55, 59, 59, 61, 36, 41, 55, 59, 41, 49, 59, 61, 42, 46, 66, 71, 66, 71, 81, 84, 36, 55, 41, 59, 41, 59, 49, 61, 42, 66, 46, 71, 66, 81, 71, 84, 42, 66, 66, 81, 46, 71, 71, 84, 62, 72, 72, 87, 72, 87, 87, 92, 2, 12, 12, 38, 12, 38, 38, 44, 6, 15, 15, 40, 51, 56, 56, 68, 6, 15, 51, 56, 15, 40, 56, 68, 13, 20, 52, 58, 52, 58, 75, 82, 6, 51, 15, 56, 15, 56, 40, 68, 13, 52, 20, 58, 52, 75, 58, 82, 13, 52, 52, 75, 20, 58, 58, 82, 36, 55, 55, 78, 55, 78, 78, 90, 4, 13, 13, 39, 35, 40, 40, 45, 7, 16, 16, 41, 54, 58, 58, 69, 13, 17, 52, 57, 40, 48, 65, 70, 16, 21, 53, 59, 58, 60, 80, 83, 13, 52, 17, 57, 40, 65, 48, 70, 16, 53, 21, 59, 58, 80, 60, 83, 39, 57, 57, 76, 45, 70, 70, 86, 41, 59, 59, 79, 69, 83, 83, 91, 4, 13, 35, 40, 13, 39, 40, 45, 13, 17, 40, 48, 52, 57, 65, 70, 7, 16, 54, 58, 16, 41, 58, 69, 16, 21, 58, 60, 53, 59, 80, 83, 13, 52, 40, 65, 17, 57, 48, 70, 39, 57, 45, 70, 57, 76, 70, 86, 16, 53, 58, 80, 21, 59, 60, 83, 41, 59, 69, 83, 59, 79, 83, 91, 11, 14, 36, 41, 36, 41, 42, 46, 14, 18, 41, 49, 55, 59, 66, 71, 14, 18, 55, 59, 41, 49, 66, 71, 18, 22, 59, 61, 59, 61, 81, 84, 36, 55, 42, 66, 42, 66, 62, 72, 41, 59, 46, 71, 66, 81, 72, 87, 41, 59, 66, 81, 46, 71, 72, 87, 49, 61, 71, 84, 71, 84, 87, 92, 4, 35, 13, 40, 13, 40, 39, 45, 13, 40, 17, 48, 52, 65, 57, 70, 13, 40, 52, 65, 17, 48, 57, 70, 39, 45, 57, 70, 57, 70, 76, 86, 7, 54, 16, 58, 16, 58, 41, 69, 16, 58, 21, 60, 53, 80, 59, 83, 16, 58, 53, 80, 21, 60, 59, 83, 41, 69, 59, 83, 59, 83, 79, 91, 11, 36, 14, 41, 36, 42, 41, 46, 14, 41, 18, 49, 55, 66, 59, 71, 36, 42, 55, 66, 42, 62, 66, 72, 41, 46, 59, 71, 66, 72, 81, 87, 14, 55, 18, 59, 41, 66, 49, 71, 18, 59, 22, 61, 59, 81, 61, 84, 41, 66, 59, 81, 46, 72, 71, 87, 49, 71, 61, 84, 71, 87, 84, 92, 11, 36, 36, 42, 14, 41, 41, 46, 36, 42, 42, 62, 55, 66, 66, 72, 14, 41, 55, 66, 18, 49, 59, 71, 41, 46, 66, 72, 59, 71, 81, 87, 14, 55, 41, 66, 18, 59, 49, 71, 41, 66, 46, 72, 59, 81, 71, 87, 18, 59, 59, 81, 22, 61, 61, 84, 49, 71, 71, 87, 61, 84, 84, 92, 34, 37, 37, 43, 37, 43, 43, 47, 37, 43, 43, 63, 64, 67, 67, 73, 37, 43, 64, 67, 43, 63, 67, 73, 43, 47, 67, 73, 67, 73, 85, 88, 37, 64, 43, 67, 43, 67, 63, 73, 43, 67, 47, 73, 67, 85, 73, 88, 43, 67, 67, 85, 47, 73, 73, 88, 63, 73, 73, 88, 73, 88, 88, 93, 2, 6, 6, 13, 12, 15, 15, 20, 6, 13, 13, 36, 51, 52, 52, 55, 12, 15, 51, 52, 38, 40, 56, 58, 15, 20, 52, 55, 56, 58, 75, 78, 12, 51, 15, 52, 38, 56, 40, 58, 15, 52, 20, 55, 56, 75, 58, 78, 38, 56, 56, 75, 44, 68, 68, 82, 40, 58, 58, 78, 68, 82, 82, 90, 3, 7, 7, 14, 19, 20, 20, 25, 7, 14, 14, 37, 54, 55, 55, 64, 19, 20, 54, 55, 44, 45, 68, 69, 20, 25, 55, 64, 68, 69, 96, 97, 19, 54, 20, 55, 44, 68, 45, 69, 20, 55, 25, 64, 68, 96, 69, 97, 44, 68, 68, 96, 120, 121, 121, 122, 45, 69, 69, 97, 121, 122, 122, 126, 6, 8, 15, 17, 15, 17, 26, 27, 15, 17, 40, 42, 56, 57, 65, 66, 15, 17, 56, 57, 40, 42, 65, 66, 26, 27, 65, 66, 65, 66, 98, 99, 51, 74, 56, 75, 56, 75, 65, 80, 56, 75, 68, 96, 104, 108, 105, 109, 56, 75, 104, 108, 68, 96, 105, 109, 65, 80, 105, 109, 105, 109, 127, 129, 7, 9, 16, 18, 20, 21, 27, 28, 16, 18, 41, 43, 58, 59, 66, 67, 20, 21, 58, 59, 45, 46, 70, 71, 27, 28, 66, 67, 70, 71, 100, 101, 54, 77, 58, 78, 68, 82, 70, 83, 58, 78, 69, 97, 105, 109, 106, 110, 68, 82, 105, 109, 121, 122, 123, 124, 70, 83, 106, 110, 123, 124, 128, 130, 6, 15, 8, 17, 15, 26, 17, 27, 15, 40, 17, 42, 56, 65, 57, 66, 51, 56, 74, 75, 56, 65, 75, 80, 56, 68, 75, 96, 104, 105, 108, 109, 15, 56, 17, 57, 40, 65, 42, 66, 26, 65, 27, 66, 65, 98, 66, 99, 56, 104, 75, 108, 68, 105, 96, 109, 65, 105, 80, 109, 105, 127, 109, 129, 7, 16, 9, 18, 20, 27, 21, 28, 16, 41, 18, 43, 58, 66, 59, 67, 54, 58, 77, 78, 68, 70, 82, 83, 58, 69, 78, 97, 105, 106, 109, 110, 20, 58, 21, 59, 45, 70, 46, 71, 27, 66, 28, 67, 70, 100, 71, 101, 68, 105, 82, 109, 121, 123, 122, 124, 70, 106, 83, 110, 123, 128, 124, 130, 13, 17, 17, 23, 20, 27, 27, 29, 40, 48, 48, 62, 68, 70, 70, 72, 52, 57, 75, 76, 58, 66, 80, 81, 65, 70, 98, 100, 105, 106, 111, 112, 52, 75, 57, 76, 58, 80, 66, 81, 65, 98, 70, 100, 105, 111, 106, 112, 75, 108, 108, 114, 82, 109, 109, 115, 98, 111, 111, 116, 127, 131, 131, 133, 14, 18, 18, 24, 25, 28, 28, 30, 41, 49, 49, 63, 69, 71, 71, 73, 55, 59, 78, 79, 69, 71, 83, 84, 66, 71, 99, 101, 106, 107, 112, 113, 55, 78, 59, 79, 69, 83, 71, 84, 66, 99, 71, 101, 106, 112, 107, 113, 96, 109, 109, 115, 122, 124, 124, 125, 100, 112, 112, 117, 128, 132, 132, 134, 6, 15, 15, 40, 51, 56, 56, 68, 8, 17, 17, 42, 74, 75, 75, 96, 15, 26, 56, 65, 56, 65, 104, 105, 17, 27, 57, 66, 75, 80, 108, 109, 15, 56, 26, 65, 56, 104, 65, 105, 17, 57, 27, 66, 75, 108, 80, 109, 40, 65, 65, 98, 68, 105, 105, 127, 42, 66, 66, 99, 96, 109, 109, 129, 7, 16, 16, 41, 54, 58, 58, 69, 9, 18, 18, 43, 77, 78, 78, 97, 20, 27, 58, 66, 68, 70, 105, 106, 21, 28, 59, 67, 82, 83, 109, 110, 20, 58, 27, 66, 68, 105, 70, 106, 21, 59, 28, 67, 82, 109, 83, 110, 45, 70, 70, 100, 121, 123, 123, 128, 46, 71, 71, 101, 122, 124, 124, 130, 13, 17, 40, 48, 52, 57, 65, 70, 17, 23, 48, 62, 75, 76, 98, 100, 20, 27, 68, 70, 58, 66, 105, 106, 27, 29, 70, 72, 80, 81, 111, 112, 52, 75, 65, 98, 75, 108, 98, 111, 57, 76, 70, 100, 108, 114, 111, 116, 58, 80, 105, 111, 82, 109, 127, 131, 66, 81, 106, 112, 109, 115, 131, 133, 14, 18, 41, 49, 55, 59, 66, 71, 18, 24, 49, 63, 78, 79, 99, 101, 25, 28, 69, 71, 69, 71, 106, 107, 28, 30, 71, 73, 83, 84, 112, 113, 55, 78, 66, 99, 96, 109, 100, 112, 59, 79, 71, 101, 109, 115, 112, 117, 69, 83, 106, 112, 122, 124, 128, 132, 71, 84, 107, 113, 124, 125, 132, 134, 13, 40, 17, 48, 52, 65, 57, 70, 17, 48, 23, 62, 75, 98, 76, 100, 52, 65, 75, 98, 75, 98, 108, 111, 57, 70, 76, 100, 108, 111, 114, 116, 20, 68, 27, 70, 58, 105, 66, 106, 27, 70, 29, 72, 80, 111, 81, 112, 58, 105, 80, 111, 82, 127, 109, 131, 66, 106, 81, 112, 109, 131, 115, 133, 14, 41, 18, 49, 55, 66, 59, 71, 18, 49, 24, 63, 78, 99, 79, 101, 55, 66, 78, 99, 96, 100, 109, 112, 59, 71, 79, 101, 109, 112, 115, 117, 25, 69, 28, 71, 69, 106, 71, 107, 28, 71, 30, 73, 83, 112, 84, 113, 69, 106, 83, 112, 122, 128, 124, 132, 71, 107, 84, 113, 124, 132, 125, 134, 36, 42, 42, 62, 55, 66, 66, 72, 42, 62, 62, 94, 96, 100, 100, 102, 55, 66, 96, 100, 78, 99, 109, 112, 66, 72, 100, 102, 109, 112, 116, 118, 55, 96, 66, 100, 78, 109, 99, 112, 66, 100, 72, 102, 109, 116, 112, 118, 78, 109, 109, 116, 90, 129, 129, 133, 99, 112, 112, 118, 129, 133, 133, 135, 37, 43, 43, 63, 64, 67, 67, 73, 43, 63, 63, 95, 97, 101, 101, 103, 64, 67, 97, 101, 97, 101, 110, 113, 67, 73, 101, 103, 110, 113, 117, 119, 64, 97, 67, 101, 97, 110, 101, 113, 67, 101, 73, 103, 110, 117, 113, 119, 97, 110, 110, 117, 126, 130, 130, 134, 101, 113, 113, 119, 130, 134, 134, 136, 2, 6, 12, 15, 6, 13, 15, 20, 12, 15, 38, 40, 51, 52, 56, 58, 6, 13, 51, 52, 13, 36, 52, 55, 15, 20, 56, 58, 52, 55, 75, 78, 12, 51, 38, 56, 15, 52, 40, 58, 38, 56, 44, 68, 56, 75, 68, 82, 15, 52, 56, 75, 20, 55, 58, 78, 40, 58, 68, 82, 58, 78, 82, 90, 6, 8, 15, 17, 15, 17, 26, 27, 15, 17, 40, 42, 56, 57, 65, 66, 15, 17, 56, 57, 40, 42, 65, 66, 26, 27, 65, 66, 65, 66, 98, 99, 51, 74, 56, 75, 56, 75, 65, 80, 56, 75, 68, 96, 104, 108, 105, 109, 56, 75, 104, 108, 68, 96, 105, 109, 65, 80, 105, 109, 105, 109, 127, 129, 3, 7, 19, 20, 7, 14, 20, 25, 19, 20, 44, 45, 54, 55, 68, 69, 7, 14, 54, 55, 14, 37, 55, 64, 20, 25, 68, 69, 55, 64, 96, 97, 19, 54, 44, 68, 20, 55, 45, 69, 44, 68, 120, 121, 68, 96, 121, 122, 20, 55, 68, 96, 25, 64, 69, 97, 45, 69, 121, 122, 69, 97, 122, 126, 7, 9, 20, 21, 16, 18, 27, 28, 20, 21, 45, 46, 58, 59, 70, 71, 16, 18, 58, 59, 41, 43, 66, 67, 27, 28, 70, 71, 66, 67, 100, 101, 54, 77, 68, 82, 58, 78, 70, 83, 68, 82, 121, 122, 105, 109, 123, 124, 58, 78, 105, 109, 69, 97, 106, 110, 70, 83, 123, 124, 106, 110, 128, 130, 6, 15, 15, 26, 8, 17, 17, 27, 51, 56, 56, 65, 74, 75, 75, 80, 15, 40, 56, 65, 17, 42, 57, 66, 56, 68, 104, 105, 75, 96, 108, 109, 15, 56, 40, 65, 17, 57, 42, 66, 56, 104, 68, 105, 75, 108, 96, 109, 26, 65, 65, 98, 27, 66, 66, 99, 65, 105, 105, 127, 80, 109, 109, 129, 13, 17, 20, 27, 17, 23, 27, 29, 52, 57, 58, 66, 75, 76, 80, 81, 40, 48, 68, 70, 48, 62, 70, 72, 65, 70, 105, 106, 98, 100, 111, 112, 52, 75, 58, 80, 57, 76, 66, 81, 75, 108, 82, 109, 108, 114, 109, 115, 65, 98, 105, 111, 70, 100, 106, 112, 98, 111, 127, 131, 111, 116, 131, 133, 7, 16, 20, 27, 9, 18, 21, 28, 54, 58, 68, 70, 77, 78, 82, 83, 16, 41, 58, 66, 18, 43, 59, 67, 58, 69, 105, 106, 78, 97, 109, 110, 20, 58, 45, 70, 21, 59, 46, 71, 68, 105, 121, 123, 82, 109, 122, 124, 27, 66, 70, 100, 28, 67, 71, 101, 70, 106, 123, 128, 83, 110, 124, 130, 14, 18, 25, 28, 18, 24, 28, 30, 55, 59, 69, 71, 78, 79, 83, 84, 41, 49, 69, 71, 49, 63, 71, 73, 66, 71, 106, 107, 99, 101, 112, 113, 55, 78, 69, 83, 59, 79, 71, 84, 96, 109, 122, 124, 109, 115, 124, 125, 66, 99, 106, 112, 71, 101, 107, 113, 100, 112, 128, 132, 112, 117, 132, 134, 6, 15, 51, 56, 15, 40, 56, 68, 15, 26, 56, 65, 56, 65, 104, 105, 8, 17, 74, 75, 17, 42, 75, 96, 17, 27, 75, 80, 57, 66, 108, 109, 15, 56, 56, 104, 26, 65, 65, 105, 40, 65, 68, 105, 65, 98, 105, 127, 17, 57, 75, 108, 27, 66, 80, 109, 42, 66, 96, 109, 66, 99, 109, 129, 13, 17, 52, 57, 40, 48, 65, 70, 20, 27, 58, 66, 68, 70, 105, 106, 17, 23, 75, 76, 48, 62, 98, 100, 27, 29, 80, 81, 70, 72, 111, 112, 52, 75, 75, 108, 65, 98, 98, 111, 58, 80, 82, 109, 105, 111, 127, 131, 57, 76, 108, 114, 70, 100, 111, 116, 66, 81, 109, 115, 106, 112, 131, 133, 7, 16, 54, 58, 16, 41, 58, 69, 20, 27, 68, 70, 58, 66, 105, 106, 9, 18, 77, 78, 18, 43, 78, 97, 21, 28, 82, 83, 59, 67, 109, 110, 20, 58, 68, 105, 27, 66, 70, 106, 45, 70, 121, 123, 70, 100, 123, 128, 21, 59, 82, 109, 28, 67, 83, 110, 46, 71, 122, 124, 71, 101, 124, 130, 14, 18, 55, 59, 41, 49, 66, 71, 25, 28, 69, 71, 69, 71, 106, 107, 18, 24, 78, 79, 49, 63, 99, 101, 28, 30, 83, 84, 71, 73, 112, 113, 55, 78, 96, 109, 66, 99, 100, 112, 69, 83, 122, 124, 106, 112, 128, 132, 59, 79, 109, 115, 71, 101, 112, 117, 71, 84, 124, 125, 107, 113, 132, 134, 13, 40, 52, 65, 17, 48, 57, 70, 52, 65, 75, 98, 75, 98, 108, 111, 17, 48, 75, 98, 23, 62, 76, 100, 57, 70, 108, 111, 76, 100, 114, 116, 20, 68, 58, 105, 27, 70, 66, 106, 58, 105, 82, 127, 80, 111, 109, 131, 27, 70, 80, 111, 29, 72, 81, 112, 66, 106, 109, 131, 81, 112, 115, 133, 36, 42, 55, 66, 42, 62, 66, 72, 55, 66, 78, 99, 96, 100, 109, 112, 42, 62, 96, 100, 62, 94, 100, 102, 66, 72, 109, 112, 100, 102, 116, 118, 55, 96, 78, 109, 66, 100, 99, 112, 78, 109, 90, 129, 109, 116, 129, 133, 66, 100, 109, 116, 72, 102, 112, 118, 99, 112, 129, 133, 112, 118, 133, 135, 14, 41, 55, 66, 18, 49, 59, 71, 55, 66, 96, 100, 78, 99, 109, 112, 18, 49, 78, 99, 24, 63, 79, 101, 59, 71, 109, 112, 79, 101, 115, 117, 25, 69, 69, 106, 28, 71, 71, 107, 69, 106, 122, 128, 83, 112, 124, 132, 28, 71, 83, 112, 30, 73, 84, 113, 71, 107, 124, 132, 84, 113, 125, 134, 37, 43, 64, 67, 43, 63, 67, 73, 64, 67, 97, 101, 97, 101, 110, 113, 43, 63, 97, 101, 63, 95, 101, 103, 67, 73, 110, 113, 101, 103, 117, 119, 64, 97, 97, 110, 67, 101, 101, 113, 97, 110, 126, 130, 110, 117, 130, 134, 67, 101, 110, 117, 73, 103, 113, 119, 101, 113, 130, 134, 113, 119, 134, 136, 4, 7, 13, 16, 13, 16, 17, 21, 13, 16, 39, 41, 52, 53, 57, 59, 13, 16, 52, 53, 39, 41, 57, 59, 17, 21, 57, 59, 57, 59, 76, 79, 35, 54, 40, 58, 40, 58, 48, 60, 40, 58, 45, 69, 65, 80, 70, 83, 40, 58, 65, 80, 45, 69, 70, 83, 48, 60, 70, 83, 70, 83, 86, 91, 7, 9, 16, 18, 20, 21, 27, 28, 16, 18, 41, 43, 58, 59, 66, 67, 20, 21, 58, 59, 45, 46, 70, 71, 27, 28, 66, 67, 70, 71, 100, 101, 54, 77, 58, 78, 68, 82, 70, 83, 58, 78, 69, 97, 105, 109, 106, 110, 68, 82, 105, 109, 121, 122, 123, 124, 70, 83, 106, 110, 123, 124, 128, 130, 7, 9, 20, 21, 16, 18, 27, 28, 20, 21, 45, 46, 58, 59, 70, 71, 16, 18, 58, 59, 41, 43, 66, 67, 27, 28, 70, 71, 66, 67, 100, 101, 54, 77, 68, 82, 58, 78, 70, 83, 68, 82, 121, 122, 105, 109, 123, 124, 58, 78, 105, 109, 69, 97, 106, 110, 70, 83, 123, 124, 106, 110, 128, 130, 9, 10, 21, 22, 21, 22, 29, 30, 21, 22, 46, 47, 60, 61, 72, 73, 21, 22, 60, 61, 46, 47, 72, 73, 29, 30, 72, 73, 72, 73, 102, 103, 77, 89, 82, 90, 82, 90, 86, 91, 82, 90, 122, 126, 127, 129, 128, 130, 82, 90, 127, 129, 122, 126, 128, 130, 86, 91, 128, 130, 128, 130, 141, 142, 13, 20, 17, 27, 17, 27, 23, 29, 52, 58, 57, 66, 75, 80, 76, 81, 52, 58, 75, 80, 57, 66, 76, 81, 75, 82, 108, 109, 108, 109, 114, 115, 40, 68, 48, 70, 48, 70, 62, 72, 65, 105, 70, 106, 98, 111, 100, 112, 65, 105, 98, 111, 70, 106, 100, 112, 98, 127, 111, 131, 111, 131, 116, 133, 16, 21, 21, 28, 27, 29, 29, 31, 53, 59, 59, 67, 80, 81, 81, 85, 58, 60, 82, 83, 70, 72, 86, 87, 80, 83, 109, 110, 111, 112, 116, 117, 58, 82, 60, 83, 70, 86, 72, 87, 80, 109, 83, 110, 111, 116, 112, 117, 105, 127, 127, 131, 123, 128, 128, 132, 111, 131, 131, 143, 144, 145, 145, 146, 16, 21, 27, 29, 21, 28, 29, 31, 58, 60, 70, 72, 82, 83, 86, 87, 53, 59, 80, 81, 59, 67, 81, 85, 80, 83, 111, 112, 109, 110, 116, 117, 58, 82, 70, 86, 60, 83, 72, 87, 105, 127, 123, 128, 127, 131, 128, 132, 80, 109, 111, 116, 83, 110, 112, 117, 111, 131, 144, 145, 131, 143, 145, 146, 18, 22, 28, 30, 28, 30, 31, 32, 59, 61, 71, 73, 83, 84, 87, 88, 59, 61, 83, 84, 71, 73, 87, 88, 81, 84, 112, 113, 112, 113, 118, 119, 78, 90, 83, 91, 83, 91, 87, 92, 109, 129, 124, 130, 131, 133, 132, 134, 109, 129, 131, 133, 124, 130, 132, 134, 116, 133, 145, 146, 145, 146, 147, 148, 13, 20, 52, 58, 52, 58, 75, 82, 17, 27, 57, 66, 75, 80, 108, 109, 17, 27, 75, 80, 57, 66, 108, 109, 23, 29, 76, 81, 76, 81, 114, 115, 40, 68, 65, 105, 65, 105, 98, 127, 48, 70, 70, 106, 98, 111, 111, 131, 48, 70, 98, 111, 70, 106, 111, 131, 62, 72, 100, 112, 100, 112, 116, 133, 16, 21, 53, 59, 58, 60, 80, 83, 21, 28, 59, 67, 82, 83, 109, 110, 27, 29, 80, 81, 70, 72, 111, 112, 29, 31, 81, 85, 86, 87, 116, 117, 58, 82, 80, 109, 105, 127, 111, 131, 60, 83, 83, 110, 127, 131, 131, 143, 70, 86, 111, 116, 123, 128, 144, 145, 72, 87, 112, 117, 128, 132, 145, 146, 16, 21, 58, 60, 53, 59, 80, 83, 27, 29, 70, 72, 80, 81, 111, 112, 21, 28, 82, 83, 59, 67, 109, 110, 29, 31, 86, 87, 81, 85, 116, 117, 58, 82, 105, 127, 80, 109, 111, 131, 70, 86, 123, 128, 111, 116, 144, 145, 60, 83, 127, 131, 83, 110, 131, 143, 72, 87, 128, 132, 112, 117, 145, 146, 18, 22, 59, 61, 59, 61, 81, 84, 28, 30, 71, 73, 83, 84, 112, 113, 28, 30, 83, 84, 71, 73, 112, 113, 31, 32, 87, 88, 87, 88, 118, 119, 78, 90, 109, 129, 109, 129, 116, 133, 83, 91, 124, 130, 131, 133, 145, 146, 83, 91, 131, 133, 124, 130, 145, 146, 87, 92, 132, 134, 132, 134, 147, 148, 39, 45, 57, 70, 57, 70, 76, 86, 57, 70, 76, 100, 108, 111, 114, 116, 57, 70, 108, 111, 76, 100, 114, 116, 76, 86, 114, 116, 114, 116, 137, 138, 45, 121, 70, 123, 70, 123, 100, 128, 70, 123, 86, 128, 111, 144, 116, 145, 70, 123, 111, 144, 86, 128, 116, 145, 100, 128, 116, 145, 116, 145, 138, 149, 41, 46, 59, 71, 66, 72, 81, 87, 59, 71, 79, 101, 109, 112, 115, 117, 66, 72, 109, 112, 100, 102, 116, 118, 81, 87, 115, 117, 116, 118, 138, 139, 69, 122, 83, 124, 106, 128, 112, 132, 83, 124, 91, 130, 131, 145, 133, 146, 106, 128, 131, 145, 128, 141, 145, 147, 112, 132, 133, 146, 145, 147, 149, 150, 41, 46, 66, 72, 59, 71, 81, 87, 66, 72, 100, 102, 109, 112, 116, 118, 59, 71, 109, 112, 79, 101, 115, 117, 81, 87, 116, 118, 115, 117, 138, 139, 69, 122, 106, 128, 83, 124, 112, 132, 106, 128, 128, 141, 131, 145, 145, 147, 83, 124, 131, 145, 91, 130, 133, 146, 112, 132, 145, 147, 133, 146, 149, 150, 43, 47, 67, 73, 67, 73, 85, 88, 67, 73, 101, 103, 110, 113, 117, 119, 67, 73, 110, 113, 101, 103, 117, 119, 85, 88, 117, 119, 117, 119, 139, 140, 97, 126, 110, 130, 110, 130, 117, 134, 110, 130, 130, 142, 143, 146, 146, 148, 110, 130, 143, 146, 130, 142, 146, 148, 117, 134, 146, 148, 146, 148, 150, 151, 2, 12, 6, 15, 6, 15, 13, 20, 12, 38, 15, 40, 51, 56, 52, 58, 12, 38, 51, 56, 15, 40, 52, 58, 38, 44, 56, 68, 56, 68, 75, 82, 6, 51, 13, 52, 13, 52, 36, 55, 15, 56, 20, 58, 52, 75, 55, 78, 15, 56, 52, 75, 20, 58, 55, 78, 40, 68, 58, 82, 58, 82, 78, 90, 6, 15, 8, 17, 15, 26, 17, 27, 15, 40, 17, 42, 56, 65, 57, 66, 51, 56, 74, 75, 56, 65, 75, 80, 56, 68, 75, 96, 104, 105, 108, 109, 15, 56, 17, 57, 40, 65, 42, 66, 26, 65, 27, 66, 65, 98, 66, 99, 56, 104, 75, 108, 68, 105, 96, 109, 65, 105, 80, 109, 105, 127, 109, 129, 6, 15, 15, 26, 8, 17, 17, 27, 51, 56, 56, 65, 74, 75, 75, 80, 15, 40, 56, 65, 17, 42, 57, 66, 56, 68, 104, 105, 75, 96, 108, 109, 15, 56, 40, 65, 17, 57, 42, 66, 56, 104, 68, 105, 75, 108, 96, 109, 26, 65, 65, 98, 27, 66, 66, 99, 65, 105, 105, 127, 80, 109, 109, 129, 13, 20, 17, 27, 17, 27, 23, 29, 52, 58, 57, 66, 75, 80, 76, 81, 52, 58, 75, 80, 57, 66, 76, 81, 75, 82, 108, 109, 108, 109, 114, 115, 40, 68, 48, 70, 48, 70, 62, 72, 65, 105, 70, 106, 98, 111, 100, 112, 65, 105, 98, 111, 70, 106, 100, 112, 98, 127, 111, 131, 111, 131, 116, 133, 3, 19, 7, 20, 7, 20, 14, 25, 19, 44, 20, 45, 54, 68, 55, 69, 19, 44, 54, 68, 20, 45, 55, 69, 44, 120, 68, 121, 68, 121, 96, 122, 7, 54, 14, 55, 14, 55, 37, 64, 20, 68, 25, 69, 55, 96, 64, 97, 20, 68, 55, 96, 25, 69, 64, 97, 45, 121, 69, 122, 69, 122, 97, 126, 7, 20, 9, 21, 16, 27, 18, 28, 20, 45, 21, 46, 58, 70, 59, 71, 54, 68, 77, 82, 58, 70, 78, 83, 68, 121, 82, 122, 105, 123, 109, 124, 16, 58, 18, 59, 41, 66, 43, 67, 27, 70, 28, 71, 66, 100, 67, 101, 58, 105, 78, 109, 69, 106, 97, 110, 70, 123, 83, 124, 106, 128, 110, 130, 7, 20, 16, 27, 9, 21, 18, 28, 54, 68, 58, 70, 77, 82, 78, 83, 20, 45, 58, 70, 21, 46, 59, 71, 68, 121, 105, 123, 82, 122, 109, 124, 16, 58, 41, 66, 18, 59, 43, 67, 58, 105, 69, 106, 78, 109, 97, 110, 27, 70, 66, 100, 28, 71, 67, 101, 70, 123, 106, 128, 83, 124, 110, 130, 14, 25, 18, 28, 18, 28, 24, 30, 55, 69, 59, 71, 78, 83, 79, 84, 55, 69, 78, 83, 59, 71, 79, 84, 96, 122, 109, 124, 109, 124, 115, 125, 41, 69, 49, 71, 49, 71, 63, 73, 66, 106, 71, 107, 99, 112, 101, 113, 66, 106, 99, 112, 71, 107, 101, 113, 100, 128, 112, 132, 112, 132, 117, 134, 6, 51, 15, 56, 15, 56, 40, 68, 15, 56, 26, 65, 56, 104, 65, 105, 15, 56, 56, 104, 26, 65, 65, 105, 40, 68, 65, 105, 65, 105, 98, 127, 8, 74, 17, 75, 17, 75, 42, 96, 17, 75, 27, 80, 57, 108, 66, 109, 17, 75, 57, 108, 27, 80, 66, 109, 42, 96, 66, 109, 66, 109, 99, 129, 13, 52, 17, 57, 40, 65, 48, 70, 20, 58, 27, 66, 68, 105, 70, 106, 52, 75, 75, 108, 65, 98, 98, 111, 58, 82, 80, 109, 105, 127, 111, 131, 17, 75, 23, 76, 48, 98, 62, 100, 27, 80, 29, 81, 70, 111, 72, 112, 57, 108, 76, 114, 70, 111, 100, 116, 66, 109, 81, 115, 106, 131, 112, 133, 13, 52, 40, 65, 17, 57, 48, 70, 52, 75, 65, 98, 75, 108, 98, 111, 20, 58, 68, 105, 27, 66, 70, 106, 58, 82, 105, 127, 80, 109, 111, 131, 17, 75, 48, 98, 23, 76, 62, 100, 57, 108, 70, 111, 76, 114, 100, 116, 27, 80, 70, 111, 29, 81, 72, 112, 66, 109, 106, 131, 81, 115, 112, 133, 36, 55, 42, 66, 42, 66, 62, 72, 55, 78, 66, 99, 96, 109, 100, 112, 55, 78, 96, 109, 66, 99, 100, 112, 78, 90, 109, 129, 109, 129, 116, 133, 42, 96, 62, 100, 62, 100, 94, 102, 66, 109, 72, 112, 100, 116, 102, 118, 66, 109, 100, 116, 72, 112, 102, 118, 99, 129, 112, 133, 112, 133, 118, 135, 7, 54, 16, 58, 16, 58, 41, 69, 20, 68, 27, 70, 58, 105, 66, 106, 20, 68, 58, 105, 27, 70, 66, 106, 45, 121, 70, 123, 70, 123, 100, 128, 9, 77, 18, 78, 18, 78, 43, 97, 21, 82, 28, 83, 59, 109, 67, 110, 21, 82, 59, 109, 28, 83, 67, 110, 46, 122, 71, 124, 71, 124, 101, 130, 14, 55, 18, 59, 41, 66, 49, 71, 25, 69, 28, 71, 69, 106, 71, 107, 55, 96, 78, 109, 66, 100, 99, 112, 69, 122, 83, 124, 106, 128, 112, 132, 18, 78, 24, 79, 49, 99, 63, 101, 28, 83, 30, 84, 71, 112, 73, 113, 59, 109, 79, 115, 71, 112, 101, 117, 71, 124, 84, 125, 107, 132, 113, 134, 14, 55, 41, 66, 18, 59, 49, 71, 55, 96, 66, 100, 78, 109, 99, 112, 25, 69, 69, 106, 28, 71, 71, 107, 69, 122, 106, 128, 83, 124, 112, 132, 18, 78, 49, 99, 24, 79, 63, 101, 59, 109, 71, 112, 79, 115, 101, 117, 28, 83, 71, 112, 30, 84, 73, 113, 71, 124, 107, 132, 84, 125, 113, 134, 37, 64, 43, 67, 43, 67, 63, 73, 64, 97, 67, 101, 97, 110, 101, 113, 64, 97, 97, 110, 67, 101, 101, 113, 97, 126, 110, 130, 110, 130, 117, 134, 43, 97, 63, 101, 63, 101, 95, 103, 67, 110, 73, 113, 101, 117, 103, 119, 67, 110, 101, 117, 73, 113, 103, 119, 101, 130, 113, 134, 113, 134, 119, 136, 4, 13, 7, 16, 13, 17, 16, 21, 13, 39, 16, 41, 52, 57, 53, 59, 35, 40, 54, 58, 40, 48, 58, 60, 40, 45, 58, 69, 65, 70, 80, 83, 13, 52, 16, 53, 39, 57, 41, 59, 17, 57, 21, 59, 57, 76, 59, 79, 40, 65, 58, 80, 45, 70, 69, 83, 48, 70, 60, 83, 70, 86, 83, 91, 7, 16, 9, 18, 20, 27, 21, 28, 16, 41, 18, 43, 58, 66, 59, 67, 54, 58, 77, 78, 68, 70, 82, 83, 58, 69, 78, 97, 105, 106, 109, 110, 20, 58, 21, 59, 45, 70, 46, 71, 27, 66, 28, 67, 70, 100, 71, 101, 68, 105, 82, 109, 121, 123, 122, 124, 70, 106, 83, 110, 123, 128, 124, 130, 13, 17, 20, 27, 17, 23, 27, 29, 52, 57, 58, 66, 75, 76, 80, 81, 40, 48, 68, 70, 48, 62, 70, 72, 65, 70, 105, 106, 98, 100, 111, 112, 52, 75, 58, 80, 57, 76, 66, 81, 75, 108, 82, 109, 108, 114, 109, 115, 65, 98, 105, 111, 70, 100, 106, 112, 98, 111, 127, 131, 111, 116, 131, 133, 16, 21, 21, 28, 27, 29, 29, 31, 53, 59, 59, 67, 80, 81, 81, 85, 58, 60, 82, 83, 70, 72, 86, 87, 80, 83, 109, 110, 111, 112, 116, 117, 58, 82, 60, 83, 70, 86, 72, 87, 80, 109, 83, 110, 111, 116, 112, 117, 105, 127, 127, 131, 123, 128, 128, 132, 111, 131, 131, 143, 144, 145, 145, 146, 7, 20, 9, 21, 16, 27, 18, 28, 20, 45, 21, 46, 58, 70, 59, 71, 54, 68, 77, 82, 58, 70, 78, 83, 68, 121, 82, 122, 105, 123, 109, 124, 16, 58, 18, 59, 41, 66, 43, 67, 27, 70, 28, 71, 66, 100, 67, 101, 58, 105, 78, 109, 69, 106, 97, 110, 70, 123, 83, 124, 106, 128, 110, 130, 9, 21, 10, 22, 21, 29, 22, 30, 21, 46, 22, 47, 60, 72, 61, 73, 77, 82, 89, 90, 82, 86, 90, 91, 82, 122, 90, 126, 127, 128, 129, 130, 21, 60, 22, 61, 46, 72, 47, 73, 29, 72, 30, 73, 72, 102, 73, 103, 82, 127, 90, 129, 122, 128, 126, 130, 86, 128, 91, 130, 128, 141, 130, 142, 16, 27, 21, 29, 21, 29, 28, 31, 58, 70, 60, 72, 82, 86, 83, 87, 58, 70, 82, 86, 60, 72, 83, 87, 105, 123, 127, 128, 127, 128, 131, 132, 53, 80, 59, 81, 59, 81, 67, 85, 80, 111, 83, 112, 109, 116, 110, 117, 80, 111, 109, 116, 83, 112, 110, 117, 111, 144, 131, 145, 131, 145, 143, 146, 18, 28, 22, 30, 28, 31, 30, 32, 59, 71, 61, 73, 83, 87, 84, 88, 78, 83, 90, 91, 83, 87, 91, 92, 109, 124, 129, 130, 131, 132, 133, 134, 59, 83, 61, 84, 71, 87, 73, 88, 81, 112, 84, 113, 112, 118, 113, 119, 109, 131, 129, 133, 124, 132, 130, 134, 116, 145, 133, 146, 145, 147, 146, 148, 13, 52, 20, 58, 52, 75, 58, 82, 17, 57, 27, 66, 75, 108, 80, 109, 40, 65, 68, 105, 65, 98, 105, 127, 48, 70, 70, 106, 98, 111, 111, 131, 17, 75, 27, 80, 57, 108, 66, 109, 23, 76, 29, 81, 76, 114, 81, 115, 48, 98, 70, 111, 70, 111, 106, 131, 62, 100, 72, 112, 100, 116, 112, 133, 16, 53, 21, 59, 58, 80, 60, 83, 21, 59, 28, 67, 82, 109, 83, 110, 58, 80, 82, 109, 105, 111, 127, 131, 60, 83, 83, 110, 127, 131, 131, 143, 27, 80, 29, 81, 70, 111, 72, 112, 29, 81, 31, 85, 86, 116, 87, 117, 70, 111, 86, 116, 123, 144, 128, 145, 72, 112, 87, 117, 128, 145, 132, 146, 39, 57, 45, 70, 57, 76, 70, 86, 57, 76, 70, 100, 108, 114, 111, 116, 45, 70, 121, 123, 70, 100, 123, 128, 70, 86, 123, 128, 111, 116, 144, 145, 57, 108, 70, 111, 76, 114, 100, 116, 76, 114, 86, 116, 114, 137, 116, 138, 70, 111, 123, 144, 86, 116, 128, 145, 100, 116, 128, 145, 116, 138, 145, 149, 41, 59, 46, 71, 66, 81, 72, 87, 59, 79, 71, 101, 109, 115, 112, 117, 69, 83, 122, 124, 106, 112, 128, 132, 83, 91, 124, 130, 131, 133, 145, 146, 66, 109, 72, 112, 100, 116, 102, 118, 81, 115, 87, 117, 116, 138, 118, 139, 106, 131, 128, 145, 128, 145, 141, 147, 112, 133, 132, 146, 145, 149, 147, 150, 16, 58, 21, 60, 53, 80, 59, 83, 27, 70, 29, 72, 80, 111, 81, 112, 58, 105, 82, 127, 80, 111, 109, 131, 70, 123, 86, 128, 111, 144, 116, 145, 21, 82, 28, 83, 59, 109, 67, 110, 29, 86, 31, 87, 81, 116, 85, 117, 60, 127, 83, 131, 83, 131, 110, 143, 72, 128, 87, 132, 112, 145, 117, 146, 18, 59, 22, 61, 59, 81, 61, 84, 28, 71, 30, 73, 83, 112, 84, 113, 78, 109, 90, 129, 109, 116, 129, 133, 83, 124, 91, 130, 131, 145, 133, 146, 28, 83, 30, 84, 71, 112, 73, 113, 31, 87, 32, 88, 87, 118, 88, 119, 83, 131, 91, 133, 124, 145, 130, 146, 87, 132, 92, 134, 132, 147, 134, 148, 41, 66, 46, 72, 59, 81, 71, 87, 66, 100, 72, 102, 109, 116, 112, 118, 69, 106, 122, 128, 83, 112, 124, 132, 106, 128, 128, 141, 131, 145, 145, 147, 59, 109, 71, 112, 79, 115, 101, 117, 81, 116, 87, 118, 115, 138, 117, 139, 83, 131, 124, 145, 91, 133, 130, 146, 112, 145, 132, 147, 133, 149, 146, 150, 43, 67, 47, 73, 67, 85, 73, 88, 67, 101, 73, 103, 110, 117, 113, 119, 97, 110, 126, 130, 110, 117, 130, 134, 110, 130, 130, 142, 143, 146, 146, 148, 67, 110, 73, 113, 101, 117, 103, 119, 85, 117, 88, 119, 117, 139, 119, 140, 110, 143, 130, 146, 130, 146, 142, 148, 117, 146, 134, 148, 146, 150, 148, 151, 4, 13, 13, 17, 7, 16, 16, 21, 35, 40, 40, 48, 54, 58, 58, 60, 13, 39, 52, 57, 16, 41, 53, 59, 40, 45, 65, 70, 58, 69, 80, 83, 13, 52, 39, 57, 16, 53, 41, 59, 40, 65, 45, 70, 58, 80, 69, 83, 17, 57, 57, 76, 21, 59, 59, 79, 48, 70, 70, 86, 60, 83, 83, 91, 13, 17, 17, 23, 20, 27, 27, 29, 40, 48, 48, 62, 68, 70, 70, 72, 52, 57, 75, 76, 58, 66, 80, 81, 65, 70, 98, 100, 105, 106, 111, 112, 52, 75, 57, 76, 58, 80, 66, 81, 65, 98, 70, 100, 105, 111, 106, 112, 75, 108, 108, 114, 82, 109, 109, 115, 98, 111, 111, 116, 127, 131, 131, 133, 7, 16, 20, 27, 9, 18, 21, 28, 54, 58, 68, 70, 77, 78, 82, 83, 16, 41, 58, 66, 18, 43, 59, 67, 58, 69, 105, 106, 78, 97, 109, 110, 20, 58, 45, 70, 21, 59, 46, 71, 68, 105, 121, 123, 82, 109, 122, 124, 27, 66, 70, 100, 28, 67, 71, 101, 70, 106, 123, 128, 83, 110, 124, 130, 16, 21, 27, 29, 21, 28, 29, 31, 58, 60, 70, 72, 82, 83, 86, 87, 53, 59, 80, 81, 59, 67, 81, 85, 80, 83, 111, 112, 109, 110, 116, 117, 58, 82, 70, 86, 60, 83, 72, 87, 105, 127, 123, 128, 127, 131, 128, 132, 80, 109, 111, 116, 83, 110, 112, 117, 111, 131, 144, 145, 131, 143, 145, 146, 7, 20, 16, 27, 9, 21, 18, 28, 54, 68, 58, 70, 77, 82, 78, 83, 20, 45, 58, 70, 21, 46, 59, 71, 68, 121, 105, 123, 82, 122, 109, 124, 16, 58, 41, 66, 18, 59, 43, 67, 58, 105, 69, 106, 78, 109, 97, 110, 27, 70, 66, 100, 28, 71, 67, 101, 70, 123, 106, 128, 83, 124, 110, 130, 16, 27, 21, 29, 21, 29, 28, 31, 58, 70, 60, 72, 82, 86, 83, 87, 58, 70, 82, 86, 60, 72, 83, 87, 105, 123, 127, 128, 127, 128, 131, 132, 53, 80, 59, 81, 59, 81, 67, 85, 80, 111, 83, 112, 109, 116, 110, 117, 80, 111, 109, 116, 83, 112, 110, 117, 111, 144, 131, 145, 131, 145, 143, 146, 9, 21, 21, 29, 10, 22, 22, 30, 77, 82, 82, 86, 89, 90, 90, 91, 21, 46, 60, 72, 22, 47, 61, 73, 82, 122, 127, 128, 90, 126, 129, 130, 21, 60, 46, 72, 22, 61, 47, 73, 82, 127, 122, 128, 90, 129, 126, 130, 29, 72, 72, 102, 30, 73, 73, 103, 86, 128, 128, 141, 91, 130, 130, 142, 18, 28, 28, 31, 22, 30, 30, 32, 78, 83, 83, 87, 90, 91, 91, 92, 59, 71, 83, 87, 61, 73, 84, 88, 109, 124, 131, 132, 129, 130, 133, 134, 59, 83, 71, 87, 61, 84, 73, 88, 109, 131, 124, 132, 129, 133, 130, 134, 81, 112, 112, 118, 84, 113, 113, 119, 116, 145, 145, 147, 133, 146, 146, 148, 13, 52, 52, 75, 20, 58, 58, 82, 40, 65, 65, 98, 68, 105, 105, 127, 17, 57, 75, 108, 27, 66, 80, 109, 48, 70, 98, 111, 70, 106, 111, 131, 17, 75, 57, 108, 27, 80, 66, 109, 48, 98, 70, 111, 70, 111, 106, 131, 23, 76, 76, 114, 29, 81, 81, 115, 62, 100, 100, 116, 72, 112, 112, 133, 39, 57, 57, 76, 45, 70, 70, 86, 45, 70, 70, 100, 121, 123, 123, 128, 57, 76, 108, 114, 70, 100, 111, 116, 70, 86, 111, 116, 123, 128, 144, 145, 57, 108, 76, 114, 70, 111, 100, 116, 70, 111, 86, 116, 123, 144, 128, 145, 76, 114, 114, 137, 86, 116, 116, 138, 100, 116, 116, 138, 128, 145, 145, 149, 16, 53, 58, 80, 21, 59, 60, 83, 58, 80, 105, 111, 82, 109, 127, 131, 21, 59, 82, 109, 28, 67, 83, 110, 60, 83, 127, 131, 83, 110, 131, 143, 27, 80, 70, 111, 29, 81, 72, 112, 70, 111, 123, 144, 86, 116, 128, 145, 29, 81, 86, 116, 31, 85, 87, 117, 72, 112, 128, 145, 87, 117, 132, 146, 41, 59, 66, 81, 46, 71, 72, 87, 69, 83, 106, 112, 122, 124, 128, 132, 59, 79, 109, 115, 71, 101, 112, 117, 83, 91, 131, 133, 124, 130, 145, 146, 66, 109, 100, 116, 72, 112, 102, 118, 106, 131, 128, 145, 128, 145, 141, 147, 81, 115, 116, 138, 87, 117, 118, 139, 112, 133, 145, 149, 132, 146, 147, 150, 16, 58, 53, 80, 21, 60, 59, 83, 58, 105, 80, 111, 82, 127, 109, 131, 27, 70, 80, 111, 29, 72, 81, 112, 70, 123, 111, 144, 86, 128, 116, 145, 21, 82, 59, 109, 28, 83, 67, 110, 60, 127, 83, 131, 83, 131, 110, 143, 29, 86, 81, 116, 31, 87, 85, 117, 72, 128, 112, 145, 87, 132, 117, 146, 41, 66, 59, 81, 46, 72, 71, 87, 69, 106, 83, 112, 122, 128, 124, 132, 66, 100, 109, 116, 72, 102, 112, 118, 106, 128, 131, 145, 128, 141, 145, 147, 59, 109, 79, 115, 71, 112, 101, 117, 83, 131, 91, 133, 124, 145, 130, 146, 81, 116, 115, 138, 87, 118, 117, 139, 112, 145, 133, 149, 132, 147, 146, 150, 18, 59, 59, 81, 22, 61, 61, 84, 78, 109, 109, 116, 90, 129, 129, 133, 28, 71, 83, 112, 30, 73, 84, 113, 83, 124, 131, 145, 91, 130, 133, 146, 28, 83, 71, 112, 30, 84, 73, 113, 83, 131, 124, 145, 91, 133, 130, 146, 31, 87, 87, 118, 32, 88, 88, 119, 87, 132, 132, 147, 92, 134, 134, 148, 43, 67, 67, 85, 47, 73, 73, 88, 97, 110, 110, 117, 126, 130, 130, 134, 67, 101, 110, 117, 73, 103, 113, 119, 110, 130, 143, 146, 130, 142, 146, 148, 67, 110, 101, 117, 73, 113, 103, 119, 110, 143, 130, 146, 130, 146, 142, 148, 85, 117, 117, 139, 88, 119, 119, 140, 117, 146, 146, 150, 134, 148, 148, 151, 11, 14, 14, 18, 14, 18, 18, 22, 36, 41, 41, 49, 55, 59, 59, 61, 36, 41, 55, 59, 41, 49, 59, 61, 42, 46, 66, 71, 66, 71, 81, 84, 36, 55, 41, 59, 41, 59, 49, 61, 42, 66, 46, 71, 66, 81, 71, 84, 42, 66, 66, 81, 46, 71, 71, 84, 62, 72, 72, 87, 72, 87, 87, 92, 14, 18, 18, 24, 25, 28, 28, 30, 41, 49, 49, 63, 69, 71, 71, 73, 55, 59, 78, 79, 69, 71, 83, 84, 66, 71, 99, 101, 106, 107, 112, 113, 55, 78, 59, 79, 69, 83, 71, 84, 66, 99, 71, 101, 106, 112, 107, 113, 96, 109, 109, 115, 122, 124, 124, 125, 100, 112, 112, 117, 128, 132, 132, 134, 14, 18, 25, 28, 18, 24, 28, 30, 55, 59, 69, 71, 78, 79, 83, 84, 41, 49, 69, 71, 49, 63, 71, 73, 66, 71, 106, 107, 99, 101, 112, 113, 55, 78, 69, 83, 59, 79, 71, 84, 96, 109, 122, 124, 109, 115, 124, 125, 66, 99, 106, 112, 71, 101, 107, 113, 100, 112, 128, 132, 112, 117, 132, 134, 18, 22, 28, 30, 28, 30, 31, 32, 59, 61, 71, 73, 83, 84, 87, 88, 59, 61, 83, 84, 71, 73, 87, 88, 81, 84, 112, 113, 112, 113, 118, 119, 78, 90, 83, 91, 83, 91, 87, 92, 109, 129, 124, 130, 131, 133, 132, 134, 109, 129, 131, 133, 124, 130, 132, 134, 116, 133, 145, 146, 145, 146, 147, 148, 14, 25, 18, 28, 18, 28, 24, 30, 55, 69, 59, 71, 78, 83, 79, 84, 55, 69, 78, 83, 59, 71, 79, 84, 96, 122, 109, 124, 109, 124, 115, 125, 41, 69, 49, 71, 49, 71, 63, 73, 66, 106, 71, 107, 99, 112, 101, 113, 66, 106, 99, 112, 71, 107, 101, 113, 100, 128, 112, 132, 112, 132, 117, 134, 18, 28, 22, 30, 28, 31, 30, 32, 59, 71, 61, 73, 83, 87, 84, 88, 78, 83, 90, 91, 83, 87, 91, 92, 109, 124, 129, 130, 131, 132, 133, 134, 59, 83, 61, 84, 71, 87, 73, 88, 81, 112, 84, 113, 112, 118, 113, 119, 109, 131, 129, 133, 124, 132, 130, 134, 116, 145, 133, 146, 145, 147, 146, 148, 18, 28, 28, 31, 22, 30, 30, 32, 78, 83, 83, 87, 90, 91, 91, 92, 59, 71, 83, 87, 61, 73, 84, 88, 109, 124, 131, 132, 129, 130, 133, 134, 59, 83, 71, 87, 61, 84, 73, 88, 109, 131, 124, 132, 129, 133, 130, 134, 81, 112, 112, 118, 84, 113, 113, 119, 116, 145, 145, 147, 133, 146, 146, 148, 24, 30, 30, 32, 30, 32, 32, 33, 79, 84, 84, 88, 91, 92, 92, 93, 79, 84, 91, 92, 84, 88, 92, 93, 115, 125, 133, 134, 133, 134, 135, 136, 79, 91, 84, 92, 84, 92, 88, 93, 115, 133, 125, 134, 133, 135, 134, 136, 115, 133, 133, 135, 125, 134, 134, 136, 138, 149, 149, 150, 149, 150, 150, 151, 36, 55, 55, 78, 55, 78, 78, 90, 42, 66, 66, 99, 96, 109, 109, 129, 42, 66, 96, 109, 66, 99, 109, 129, 62, 72, 100, 112, 100, 112, 116, 133, 42, 96, 66, 109, 66, 109, 99, 129, 62, 100, 72, 112, 100, 116, 112, 133, 62, 100, 100, 116, 72, 112, 112, 133, 94, 102, 102, 118, 102, 118, 118, 135, 41, 59, 59, 79, 69, 83, 83, 91, 46, 71, 71, 101, 122, 124, 124, 130, 66, 81, 109, 115, 106, 112, 131, 133, 72, 87, 112, 117, 128, 132, 145, 146, 66, 109, 81, 115, 106, 131, 112, 133, 72, 112, 87, 117, 128, 145, 132, 146, 100, 116, 116, 138, 128, 145, 145, 149, 102, 118, 118, 139, 141, 147, 147, 150, 41, 59, 69, 83, 59, 79, 83, 91, 66, 81, 106, 112, 109, 115, 131, 133, 46, 71, 122, 124, 71, 101, 124, 130, 72, 87, 128, 132, 112, 117, 145, 146, 66, 109, 106, 131, 81, 115, 112, 133, 100, 116, 128, 145, 116, 138, 145, 149, 72, 112, 128, 145, 87, 117, 132, 146, 102, 118, 141, 147, 118, 139, 147, 150, 49, 61, 71, 84, 71, 84, 87, 92, 71, 84, 107, 113, 124, 125, 132, 134, 71, 84, 124, 125, 107, 113, 132, 134, 87, 92, 132, 134, 132, 134, 147, 148, 99, 129, 112, 133, 112, 133, 118, 135, 112, 133, 132, 146, 145, 149, 147, 150, 112, 133, 145, 149, 132, 146, 147, 150, 118, 135, 147, 150, 147, 150, 152, 153, 41, 69, 59, 83, 59, 83, 79, 91, 66, 106, 81, 112, 109, 131, 115, 133, 66, 106, 109, 131, 81, 112, 115, 133, 100, 128, 116, 145, 116, 145, 138, 149, 46, 122, 71, 124, 71, 124, 101, 130, 72, 128, 87, 132, 112, 145, 117, 146, 72, 128, 112, 145, 87, 132, 117, 146, 102, 141, 118, 147, 118, 147, 139, 150, 49, 71, 61, 84, 71, 87, 84, 92, 71, 107, 84, 113, 124, 132, 125, 134, 99, 112, 129, 133, 112, 118, 133, 135, 112, 132, 133, 146, 145, 147, 149, 150, 71, 124, 84, 125, 107, 132, 113, 134, 87, 132, 92, 134, 132, 147, 134, 148, 112, 145, 133, 149, 132, 147, 146, 150, 118, 147, 135, 150, 147, 152, 150, 153, 49, 71, 71, 87, 61, 84, 84, 92, 99, 112, 112, 118, 129, 133, 133, 135, 71, 107, 124, 132, 84, 113, 125, 134, 112, 132, 145, 147, 133, 146, 149, 150, 71, 124, 107, 132, 84, 125, 113, 134, 112, 145, 132, 147, 133, 149, 146, 150, 87, 132, 132, 147, 92, 134, 134, 148, 118, 147, 147, 152, 135, 150, 150, 153, 63, 73, 73, 88, 73, 88, 88, 93, 101, 113, 113, 119, 130, 134, 134, 136, 101, 113, 130, 134, 113, 119, 134, 136, 117, 134, 146, 148, 146, 148, 150, 151, 101, 130, 113, 134, 113, 134, 119, 136, 117, 146, 134, 148, 146, 150, 148, 151, 117, 146, 146, 150, 134, 148, 148, 151, 139, 150, 150, 153, 150, 153, 153, 154, 2, 12, 12, 38, 12, 38, 38, 44, 6, 15, 15, 40, 51, 56, 56, 68, 6, 15, 51, 56, 15, 40, 56, 68, 13, 20, 52, 58, 52, 58, 75, 82, 6, 51, 15, 56, 15, 56, 40, 68, 13, 52, 20, 58, 52, 75, 58, 82, 13, 52, 52, 75, 20, 58, 58, 82, 36, 55, 55, 78, 55, 78, 78, 90, 6, 15, 15, 40, 51, 56, 56, 68, 8, 17, 17, 42, 74, 75, 75, 96, 15, 26, 56, 65, 56, 65, 104, 105, 17, 27, 57, 66, 75, 80, 108, 109, 15, 56, 26, 65, 56, 104, 65, 105, 17, 57, 27, 66, 75, 108, 80, 109, 40, 65, 65, 98, 68, 105, 105, 127, 42, 66, 66, 99, 96, 109, 109, 129, 6, 15, 51, 56, 15, 40, 56, 68, 15, 26, 56, 65, 56, 65, 104, 105, 8, 17, 74, 75, 17, 42, 75, 96, 17, 27, 75, 80, 57, 66, 108, 109, 15, 56, 56, 104, 26, 65, 65, 105, 40, 65, 68, 105, 65, 98, 105, 127, 17, 57, 75, 108, 27, 66, 80, 109, 42, 66, 96, 109, 66, 99, 109, 129, 13, 20, 52, 58, 52, 58, 75, 82, 17, 27, 57, 66, 75, 80, 108, 109, 17, 27, 75, 80, 57, 66, 108, 109, 23, 29, 76, 81, 76, 81, 114, 115, 40, 68, 65, 105, 65, 105, 98, 127, 48, 70, 70, 106, 98, 111, 111, 131, 48, 70, 98, 111, 70, 106, 111, 131, 62, 72, 100, 112, 100, 112, 116, 133, 6, 51, 15, 56, 15, 56, 40, 68, 15, 56, 26, 65, 56, 104, 65, 105, 15, 56, 56, 104, 26, 65, 65, 105, 40, 68, 65, 105, 65, 105, 98, 127, 8, 74, 17, 75, 17, 75, 42, 96, 17, 75, 27, 80, 57, 108, 66, 109, 17, 75, 57, 108, 27, 80, 66, 109, 42, 96, 66, 109, 66, 109, 99, 129, 13, 52, 20, 58, 52, 75, 58, 82, 17, 57, 27, 66, 75, 108, 80, 109, 40, 65, 68, 105, 65, 98, 105, 127, 48, 70, 70, 106, 98, 111, 111, 131, 17, 75, 27, 80, 57, 108, 66, 109, 23, 76, 29, 81, 76, 114, 81, 115, 48, 98, 70, 111, 70, 111, 106, 131, 62, 100, 72, 112, 100, 116, 112, 133, 13, 52, 52, 75, 20, 58, 58, 82, 40, 65, 65, 98, 68, 105, 105, 127, 17, 57, 75, 108, 27, 66, 80, 109, 48, 70, 98, 111, 70, 106, 111, 131, 17, 75, 57, 108, 27, 80, 66, 109, 48, 98, 70, 111, 70, 111, 106, 131, 23, 76, 76, 114, 29, 81, 81, 115, 62, 100, 100, 116, 72, 112, 112, 133, 36, 55, 55, 78, 55, 78, 78, 90, 42, 66, 66, 99, 96, 109, 109, 129, 42, 66, 96, 109, 66, 99, 109, 129, 62, 72, 100, 112, 100, 112, 116, 133, 42, 96, 66, 109, 66, 109, 99, 129, 62, 100, 72, 112, 100, 116, 112, 133, 62, 100, 100, 116, 72, 112, 112, 133, 94, 102, 102, 118, 102, 118, 118, 135, 3, 19, 19, 44, 19, 44, 44, 120, 7, 20, 20, 45, 54, 68, 68, 121, 7, 20, 54, 68, 20, 45, 68, 121, 14, 25, 55, 69, 55, 69, 96, 122, 7, 54, 20, 68, 20, 68, 45, 121, 14, 55, 25, 69, 55, 96, 69, 122, 14, 55, 55, 96, 25, 69, 69, 122, 37, 64, 64, 97, 64, 97, 97, 126, 7, 20, 20, 45, 54, 68, 68, 121, 9, 21, 21, 46, 77, 82, 82, 122, 16, 27, 58, 70, 58, 70, 105, 123, 18, 28, 59, 71, 78, 83, 109, 124, 16, 58, 27, 70, 58, 105, 70, 123, 18, 59, 28, 71, 78, 109, 83, 124, 41, 66, 66, 100, 69, 106, 106, 128, 43, 67, 67, 101, 97, 110, 110, 130, 7, 20, 54, 68, 20, 45, 68, 121, 16, 27, 58, 70, 58, 70, 105, 123, 9, 21, 77, 82, 21, 46, 82, 122, 18, 28, 78, 83, 59, 71, 109, 124, 16, 58, 58, 105, 27, 70, 70, 123, 41, 66, 69, 106, 66, 100, 106, 128, 18, 59, 78, 109, 28, 71, 83, 124, 43, 67, 97, 110, 67, 101, 110, 130, 14, 25, 55, 69, 55, 69, 96, 122, 18, 28, 59, 71, 78, 83, 109, 124, 18, 28, 78, 83, 59, 71, 109, 124, 24, 30, 79, 84, 79, 84, 115, 125, 41, 69, 66, 106, 66, 106, 100, 128, 49, 71, 71, 107, 99, 112, 112, 132, 49, 71, 99, 112, 71, 107, 112, 132, 63, 73, 101, 113, 101, 113, 117, 134, 7, 54, 20, 68, 20, 68, 45, 121, 16, 58, 27, 70, 58, 105, 70, 123, 16, 58, 58, 105, 27, 70, 70, 123, 41, 69, 66, 106, 66, 106, 100, 128, 9, 77, 21, 82, 21, 82, 46, 122, 18, 78, 28, 83, 59, 109, 71, 124, 18, 78, 59, 109, 28, 83, 71, 124, 43, 97, 67, 110, 67, 110, 101, 130, 14, 55, 25, 69, 55, 96, 69, 122, 18, 59, 28, 71, 78, 109, 83, 124, 41, 66, 69, 106, 66, 100, 106, 128, 49, 71, 71, 107, 99, 112, 112, 132, 18, 78, 28, 83, 59, 109, 71, 124, 24, 79, 30, 84, 79, 115, 84, 125, 49, 99, 71, 112, 71, 112, 107, 132, 63, 101, 73, 113, 101, 117, 113, 134, 14, 55, 55, 96, 25, 69, 69, 122, 41, 66, 66, 100, 69, 106, 106, 128, 18, 59, 78, 109, 28, 71, 83, 124, 49, 71, 99, 112, 71, 107, 112, 132, 18, 78, 59, 109, 28, 83, 71, 124, 49, 99, 71, 112, 71, 112, 107, 132, 24, 79, 79, 115, 30, 84, 84, 125, 63, 101, 101, 117, 73, 113, 113, 134, 37, 64, 64, 97, 64, 97, 97, 126, 43, 67, 67, 101, 97, 110, 110, 130, 43, 67, 97, 110, 67, 101, 110, 130, 63, 73, 101, 113, 101, 113, 117, 134, 43, 97, 67, 110, 67, 110, 101, 130, 63, 101, 73, 113, 101, 117, 113, 134, 63, 101, 101, 117, 73, 113, 113, 134, 95, 103, 103, 119, 103, 119, 119, 136, 4, 13, 13, 39, 35, 40, 40, 45, 7, 16, 16, 41, 54, 58, 58, 69, 13, 17, 52, 57, 40, 48, 65, 70, 16, 21, 53, 59, 58, 60, 80, 83, 13, 52, 17, 57, 40, 65, 48, 70, 16, 53, 21, 59, 58, 80, 60, 83, 39, 57, 57, 76, 45, 70, 70, 86, 41, 59, 59, 79, 69, 83, 83, 91, 7, 16, 16, 41, 54, 58, 58, 69, 9, 18, 18, 43, 77, 78, 78, 97, 20, 27, 58, 66, 68, 70, 105, 106, 21, 28, 59, 67, 82, 83, 109, 110, 20, 58, 27, 66, 68, 105, 70, 106, 21, 59, 28, 67, 82, 109, 83, 110, 45, 70, 70, 100, 121, 123, 123, 128, 46, 71, 71, 101, 122, 124, 124, 130, 13, 17, 52, 57, 40, 48, 65, 70, 20, 27, 58, 66, 68, 70, 105, 106, 17, 23, 75, 76, 48, 62, 98, 100, 27, 29, 80, 81, 70, 72, 111, 112, 52, 75, 75, 108, 65, 98, 98, 111, 58, 80, 82, 109, 105, 111, 127, 131, 57, 76, 108, 114, 70, 100, 111, 116, 66, 81, 109, 115, 106, 112, 131, 133, 16, 21, 53, 59, 58, 60, 80, 83, 21, 28, 59, 67, 82, 83, 109, 110, 27, 29, 80, 81, 70, 72, 111, 112, 29, 31, 81, 85, 86, 87, 116, 117, 58, 82, 80, 109, 105, 127, 111, 131, 60, 83, 83, 110, 127, 131, 131, 143, 70, 86, 111, 116, 123, 128, 144, 145, 72, 87, 112, 117, 128, 132, 145, 146, 13, 52, 17, 57, 40, 65, 48, 70, 20, 58, 27, 66, 68, 105, 70, 106, 52, 75, 75, 108, 65, 98, 98, 111, 58, 82, 80, 109, 105, 127, 111, 131, 17, 75, 23, 76, 48, 98, 62, 100, 27, 80, 29, 81, 70, 111, 72, 112, 57, 108, 76, 114, 70, 111, 100, 116, 66, 109, 81, 115, 106, 131, 112, 133, 16, 53, 21, 59, 58, 80, 60, 83, 21, 59, 28, 67, 82, 109, 83, 110, 58, 80, 82, 109, 105, 111, 127, 131, 60, 83, 83, 110, 127, 131, 131, 143, 27, 80, 29, 81, 70, 111, 72, 112, 29, 81, 31, 85, 86, 116, 87, 117, 70, 111, 86, 116, 123, 144, 128, 145, 72, 112, 87, 117, 128, 145, 132, 146, 39, 57, 57, 76, 45, 70, 70, 86, 45, 70, 70, 100, 121, 123, 123, 128, 57, 76, 108, 114, 70, 100, 111, 116, 70, 86, 111, 116, 123, 128, 144, 145, 57, 108, 76, 114, 70, 111, 100, 116, 70, 111, 86, 116, 123, 144, 128, 145, 76, 114, 114, 137, 86, 116, 116, 138, 100, 116, 116, 138, 128, 145, 145, 149, 41, 59, 59, 79, 69, 83, 83, 91, 46, 71, 71, 101, 122, 124, 124, 130, 66, 81, 109, 115, 106, 112, 131, 133, 72, 87, 112, 117, 128, 132, 145, 146, 66, 109, 81, 115, 106, 131, 112, 133, 72, 112, 87, 117, 128, 145, 132, 146, 100, 116, 116, 138, 128, 145, 145, 149, 102, 118, 118, 139, 141, 147, 147, 150, 7, 20, 20, 45, 54, 68, 68, 121, 9, 21, 21, 46, 77, 82, 82, 122, 16, 27, 58, 70, 58, 70, 105, 123, 18, 28, 59, 71, 78, 83, 109, 124, 16, 58, 27, 70, 58, 105, 70, 123, 18, 59, 28, 71, 78, 109, 83, 124, 41, 66, 66, 100, 69, 106, 106, 128, 43, 67, 67, 101, 97, 110, 110, 130, 9, 21, 21, 46, 77, 82, 82, 122, 10, 22, 22, 47, 89, 90, 90, 126, 21, 29, 60, 72, 82, 86, 127, 128, 22, 30, 61, 73, 90, 91, 129, 130, 21, 60, 29, 72, 82, 127, 86, 128, 22, 61, 30, 73, 90, 129, 91, 130, 46, 72, 72, 102, 122, 128, 128, 141, 47, 73, 73, 103, 126, 130, 130, 142, 16, 27, 58, 70, 58, 70, 105, 123, 21, 29, 60, 72, 82, 86, 127, 128, 21, 29, 82, 86, 60, 72, 127, 128, 28, 31, 83, 87, 83, 87, 131, 132, 53, 80, 80, 111, 80, 111, 111, 144, 59, 81, 83, 112, 109, 116, 131, 145, 59, 81, 109, 116, 83, 112, 131, 145, 67, 85, 110, 117, 110, 117, 143, 146, 18, 28, 59, 71, 78, 83, 109, 124, 22, 30, 61, 73, 90, 91, 129, 130, 28, 31, 83, 87, 83, 87, 131, 132, 30, 32, 84, 88, 91, 92, 133, 134, 59, 83, 81, 112, 109, 131, 116, 145, 61, 84, 84, 113, 129, 133, 133, 146, 71, 87, 112, 118, 124, 132, 145, 147, 73, 88, 113, 119, 130, 134, 146, 148, 16, 58, 27, 70, 58, 105, 70, 123, 21, 60, 29, 72, 82, 127, 86, 128, 53, 80, 80, 111, 80, 111, 111, 144, 59, 83, 81, 112, 109, 131, 116, 145, 21, 82, 29, 86, 60, 127, 72, 128, 28, 83, 31, 87, 83, 131, 87, 132, 59, 109, 81, 116, 83, 131, 112, 145, 67, 110, 85, 117, 110, 143, 117, 146, 18, 59, 28, 71, 78, 109, 83, 124, 22, 61, 30, 73, 90, 129, 91, 130, 59, 81, 83, 112, 109, 116, 131, 145, 61, 84, 84, 113, 129, 133, 133, 146, 28, 83, 31, 87, 83, 131, 87, 132, 30, 84, 32, 88, 91, 133, 92, 134, 71, 112, 87, 118, 124, 145, 132, 147, 73, 113, 88, 119, 130, 146, 134, 148, 41, 66, 66, 100, 69, 106, 106, 128, 46, 72, 72, 102, 122, 128, 128, 141, 59, 81, 109, 116, 83, 112, 131, 145, 71, 87, 112, 118, 124, 132, 145, 147, 59, 109, 81, 116, 83, 131, 112, 145, 71, 112, 87, 118, 124, 145, 132, 147, 79, 115, 115, 138, 91, 133, 133, 149, 101, 117, 117, 139, 130, 146, 146, 150, 43, 67, 67, 101, 97, 110, 110, 130, 47, 73, 73, 103, 126, 130, 130, 142, 67, 85, 110, 117, 110, 117, 143, 146, 73, 88, 113, 119, 130, 134, 146, 148, 67, 110, 85, 117, 110, 143, 117, 146, 73, 113, 88, 119, 130, 146, 134, 148, 101, 117, 117, 139, 130, 146, 146, 150, 103, 119, 119, 140, 142, 148, 148, 151, 4, 13, 35, 40, 13, 39, 40, 45, 13, 17, 40, 48, 52, 57, 65, 70, 7, 16, 54, 58, 16, 41, 58, 69, 16, 21, 58, 60, 53, 59, 80, 83, 13, 52, 40, 65, 17, 57, 48, 70, 39, 57, 45, 70, 57, 76, 70, 86, 16, 53, 58, 80, 21, 59, 60, 83, 41, 59, 69, 83, 59, 79, 83, 91, 13, 17, 40, 48, 52, 57, 65, 70, 17, 23, 48, 62, 75, 76, 98, 100, 20, 27, 68, 70, 58, 66, 105, 106, 27, 29, 70, 72, 80, 81, 111, 112, 52, 75, 65, 98, 75, 108, 98, 111, 57, 76, 70, 100, 108, 114, 111, 116, 58, 80, 105, 111, 82, 109, 127, 131, 66, 81, 106, 112, 109, 115, 131, 133, 7, 16, 54, 58, 16, 41, 58, 69, 20, 27, 68, 70, 58, 66, 105, 106, 9, 18, 77, 78, 18, 43, 78, 97, 21, 28, 82, 83, 59, 67, 109, 110, 20, 58, 68, 105, 27, 66, 70, 106, 45, 70, 121, 123, 70, 100, 123, 128, 21, 59, 82, 109, 28, 67, 83, 110, 46, 71, 122, 124, 71, 101, 124, 130, 16, 21, 58, 60, 53, 59, 80, 83, 27, 29, 70, 72, 80, 81, 111, 112, 21, 28, 82, 83, 59, 67, 109, 110, 29, 31, 86, 87, 81, 85, 116, 117, 58, 82, 105, 127, 80, 109, 111, 131, 70, 86, 123, 128, 111, 116, 144, 145, 60, 83, 127, 131, 83, 110, 131, 143, 72, 87, 128, 132, 112, 117, 145, 146, 13, 52, 40, 65, 17, 57, 48, 70, 52, 75, 65, 98, 75, 108, 98, 111, 20, 58, 68, 105, 27, 66, 70, 106, 58, 82, 105, 127, 80, 109, 111, 131, 17, 75, 48, 98, 23, 76, 62, 100, 57, 108, 70, 111, 76, 114, 100, 116, 27, 80, 70, 111, 29, 81, 72, 112, 66, 109, 106, 131, 81, 115, 112, 133, 39, 57, 45, 70, 57, 76, 70, 86, 57, 76, 70, 100, 108, 114, 111, 116, 45, 70, 121, 123, 70, 100, 123, 128, 70, 86, 123, 128, 111, 116, 144, 145, 57, 108, 70, 111, 76, 114, 100, 116, 76, 114, 86, 116, 114, 137, 116, 138, 70, 111, 123, 144, 86, 116, 128, 145, 100, 116, 128, 145, 116, 138, 145, 149, 16, 53, 58, 80, 21, 59, 60, 83, 58, 80, 105, 111, 82, 109, 127, 131, 21, 59, 82, 109, 28, 67, 83, 110, 60, 83, 127, 131, 83, 110, 131, 143, 27, 80, 70, 111, 29, 81, 72, 112, 70, 111, 123, 144, 86, 116, 128, 145, 29, 81, 86, 116, 31, 85, 87, 117, 72, 112, 128, 145, 87, 117, 132, 146, 41, 59, 69, 83, 59, 79, 83, 91, 66, 81, 106, 112, 109, 115, 131, 133, 46, 71, 122, 124, 71, 101, 124, 130, 72, 87, 128, 132, 112, 117, 145, 146, 66, 109, 106, 131, 81, 115, 112, 133, 100, 116, 128, 145, 116, 138, 145, 149, 72, 112, 128, 145, 87, 117, 132, 146, 102, 118, 141, 147, 118, 139, 147, 150, 7, 20, 54, 68, 20, 45, 68, 121, 16, 27, 58, 70, 58, 70, 105, 123, 9, 21, 77, 82, 21, 46, 82, 122, 18, 28, 78, 83, 59, 71, 109, 124, 16, 58, 58, 105, 27, 70, 70, 123, 41, 66, 69, 106, 66, 100, 106, 128, 18, 59, 78, 109, 28, 71, 83, 124, 43, 67, 97, 110, 67, 101, 110, 130, 16, 27, 58, 70, 58, 70, 105, 123, 21, 29, 60, 72, 82, 86, 127, 128, 21, 29, 82, 86, 60, 72, 127, 128, 28, 31, 83, 87, 83, 87, 131, 132, 53, 80, 80, 111, 80, 111, 111, 144, 59, 81, 83, 112, 109, 116, 131, 145, 59, 81, 109, 116, 83, 112, 131, 145, 67, 85, 110, 117, 110, 117, 143, 146, 9, 21, 77, 82, 21, 46, 82, 122, 21, 29, 82, 86, 60, 72, 127, 128, 10, 22, 89, 90, 22, 47, 90, 126, 22, 30, 90, 91, 61, 73, 129, 130, 21, 60, 82, 127, 29, 72, 86, 128, 46, 72, 122, 128, 72, 102, 128, 141, 22, 61, 90, 129, 30, 73, 91, 130, 47, 73, 126, 130, 73, 103, 130, 142, 18, 28, 78, 83, 59, 71, 109, 124, 28, 31, 83, 87, 83, 87, 131, 132, 22, 30, 90, 91, 61, 73, 129, 130, 30, 32, 91, 92, 84, 88, 133, 134, 59, 83, 109, 131, 81, 112, 116, 145, 71, 87, 124, 132, 112, 118, 145, 147, 61, 84, 129, 133, 84, 113, 133, 146, 73, 88, 130, 134, 113, 119, 146, 148, 16, 58, 58, 105, 27, 70, 70, 123, 53, 80, 80, 111, 80, 111, 111, 144, 21, 60, 82, 127, 29, 72, 86, 128, 59, 83, 109, 131, 81, 112, 116, 145, 21, 82, 60, 127, 29, 86, 72, 128, 59, 109, 83, 131, 81, 116, 112, 145, 28, 83, 83, 131, 31, 87, 87, 132, 67, 110, 110, 143, 85, 117, 117, 146, 41, 66, 69, 106, 66, 100, 106, 128, 59, 81, 83, 112, 109, 116, 131, 145, 46, 72, 122, 128, 72, 102, 128, 141, 71, 87, 124, 132, 112, 118, 145, 147, 59, 109, 83, 131, 81, 116, 112, 145, 79, 115, 91, 133, 115, 138, 133, 149, 71, 112, 124, 145, 87, 118, 132, 147, 101, 117, 130, 146, 117, 139, 146, 150, 18, 59, 78, 109, 28, 71, 83, 124, 59, 81, 109, 116, 83, 112, 131, 145, 22, 61, 90, 129, 30, 73, 91, 130, 61, 84, 129, 133, 84, 113, 133, 146, 28, 83, 83, 131, 31, 87, 87, 132, 71, 112, 124, 145, 87, 118, 132, 147, 30, 84, 91, 133, 32, 88, 92, 134, 73, 113, 130, 146, 88, 119, 134, 148, 43, 67, 97, 110, 67, 101, 110, 130, 67, 85, 110, 117, 110, 117, 143, 146, 47, 73, 126, 130, 73, 103, 130, 142, 73, 88, 130, 134, 113, 119, 146, 148, 67, 110, 110, 143, 85, 117, 117, 146, 101, 117, 130, 146, 117, 139, 146, 150, 73, 113, 130, 146, 88, 119, 134, 148, 103, 119, 142, 148, 119, 140, 148, 151, 11, 14, 36, 41, 36, 41, 42, 46, 14, 18, 41, 49, 55, 59, 66, 71, 14, 18, 55, 59, 41, 49, 66, 71, 18, 22, 59, 61, 59, 61, 81, 84, 36, 55, 42, 66, 42, 66, 62, 72, 41, 59, 46, 71, 66, 81, 72, 87, 41, 59, 66, 81, 46, 71, 72, 87, 49, 61, 71, 84, 71, 84, 87, 92, 14, 18, 41, 49, 55, 59, 66, 71, 18, 24, 49, 63, 78, 79, 99, 101, 25, 28, 69, 71, 69, 71, 106, 107, 28, 30, 71, 73, 83, 84, 112, 113, 55, 78, 66, 99, 96, 109, 100, 112, 59, 79, 71, 101, 109, 115, 112, 117, 69, 83, 106, 112, 122, 124, 128, 132, 71, 84, 107, 113, 124, 125, 132, 134, 14, 18, 55, 59, 41, 49, 66, 71, 25, 28, 69, 71, 69, 71, 106, 107, 18, 24, 78, 79, 49, 63, 99, 101, 28, 30, 83, 84, 71, 73, 112, 113, 55, 78, 96, 109, 66, 99, 100, 112, 69, 83, 122, 124, 106, 112, 128, 132, 59, 79, 109, 115, 71, 101, 112, 117, 71, 84, 124, 125, 107, 113, 132, 134, 18, 22, 59, 61, 59, 61, 81, 84, 28, 30, 71, 73, 83, 84, 112, 113, 28, 30, 83, 84, 71, 73, 112, 113, 31, 32, 87, 88, 87, 88, 118, 119, 78, 90, 109, 129, 109, 129, 116, 133, 83, 91, 124, 130, 131, 133, 145, 146, 83, 91, 131, 133, 124, 130, 145, 146, 87, 92, 132, 134, 132, 134, 147, 148, 36, 55, 42, 66, 42, 66, 62, 72, 55, 78, 66, 99, 96, 109, 100, 112, 55, 78, 96, 109, 66, 99, 100, 112, 78, 90, 109, 129, 109, 129, 116, 133, 42, 96, 62, 100, 62, 100, 94, 102, 66, 109, 72, 112, 100, 116, 102, 118, 66, 109, 100, 116, 72, 112, 102, 118, 99, 129, 112, 133, 112, 133, 118, 135, 41, 59, 46, 71, 66, 81, 72, 87, 59, 79, 71, 101, 109, 115, 112, 117, 69, 83, 122, 124, 106, 112, 128, 132, 83, 91, 124, 130, 131, 133, 145, 146, 66, 109, 72, 112, 100, 116, 102, 118, 81, 115, 87, 117, 116, 138, 118, 139, 106, 131, 128, 145, 128, 145, 141, 147, 112, 133, 132, 146, 145, 149, 147, 150, 41, 59, 66, 81, 46, 71, 72, 87, 69, 83, 106, 112, 122, 124, 128, 132, 59, 79, 109, 115, 71, 101, 112, 117, 83, 91, 131, 133, 124, 130, 145, 146, 66, 109, 100, 116, 72, 112, 102, 118, 106, 131, 128, 145, 128, 145, 141, 147, 81, 115, 116, 138, 87, 117, 118, 139, 112, 133, 145, 149, 132, 146, 147, 150, 49, 61, 71, 84, 71, 84, 87, 92, 71, 84, 107, 113, 124, 125, 132, 134, 71, 84, 124, 125, 107, 113, 132, 134, 87, 92, 132, 134, 132, 134, 147, 148, 99, 129, 112, 133, 112, 133, 118, 135, 112, 133, 132, 146, 145, 149, 147, 150, 112, 133, 145, 149, 132, 146, 147, 150, 118, 135, 147, 150, 147, 150, 152, 153, 14, 25, 55, 69, 55, 69, 96, 122, 18, 28, 59, 71, 78, 83, 109, 124, 18, 28, 78, 83, 59, 71, 109, 124, 24, 30, 79, 84, 79, 84, 115, 125, 41, 69, 66, 106, 66, 106, 100, 128, 49, 71, 71, 107, 99, 112, 112, 132, 49, 71, 99, 112, 71, 107, 112, 132, 63, 73, 101, 113, 101, 113, 117, 134, 18, 28, 59, 71, 78, 83, 109, 124, 22, 30, 61, 73, 90, 91, 129, 130, 28, 31, 83, 87, 83, 87, 131, 132, 30, 32, 84, 88, 91, 92, 133, 134, 59, 83, 81, 112, 109, 131, 116, 145, 61, 84, 84, 113, 129, 133, 133, 146, 71, 87, 112, 118, 124, 132, 145, 147, 73, 88, 113, 119, 130, 134, 146, 148, 18, 28, 78, 83, 59, 71, 109, 124, 28, 31, 83, 87, 83, 87, 131, 132, 22, 30, 90, 91, 61, 73, 129, 130, 30, 32, 91, 92, 84, 88, 133, 134, 59, 83, 109, 131, 81, 112, 116, 145, 71, 87, 124, 132, 112, 118, 145, 147, 61, 84, 129, 133, 84, 113, 133, 146, 73, 88, 130, 134, 113, 119, 146, 148, 24, 30, 79, 84, 79, 84, 115, 125, 30, 32, 84, 88, 91, 92, 133, 134, 30, 32, 91, 92, 84, 88, 133, 134, 32, 33, 92, 93, 92, 93, 135, 136, 79, 91, 115, 133, 115, 133, 138, 149, 84, 92, 125, 134, 133, 135, 149, 150, 84, 92, 133, 135, 125, 134, 149, 150, 88, 93, 134, 136, 134, 136, 150, 151, 41, 69, 66, 106, 66, 106, 100, 128, 59, 83, 81, 112, 109, 131, 116, 145, 59, 83, 109, 131, 81, 112, 116, 145, 79, 91, 115, 133, 115, 133, 138, 149, 46, 122, 72, 128, 72, 128, 102, 141, 71, 124, 87, 132, 112, 145, 118, 147, 71, 124, 112, 145, 87, 132, 118, 147, 101, 130, 117, 146, 117, 146, 139, 150, 49, 71, 71, 107, 99, 112, 112, 132, 61, 84, 84, 113, 129, 133, 133, 146, 71, 87, 124, 132, 112, 118, 145, 147, 84, 92, 125, 134, 133, 135, 149, 150, 71, 124, 87, 132, 112, 145, 118, 147, 84, 125, 92, 134, 133, 149, 135, 150, 107, 132, 132, 147, 132, 147, 147, 152, 113, 134, 134, 148, 146, 150, 150, 153, 49, 71, 99, 112, 71, 107, 112, 132, 71, 87, 112, 118, 124, 132, 145, 147, 61, 84, 129, 133, 84, 113, 133, 146, 84, 92, 133, 135, 125, 134, 149, 150, 71, 124, 112, 145, 87, 132, 118, 147, 107, 132, 132, 147, 132, 147, 147, 152, 84, 125, 133, 149, 92, 134, 135, 150, 113, 134, 146, 150, 134, 148, 150, 153, 63, 73, 101, 113, 101, 113, 117, 134, 73, 88, 113, 119, 130, 134, 146, 148, 73, 88, 130, 134, 113, 119, 146, 148, 88, 93, 134, 136, 134, 136, 150, 151, 101, 130, 117, 146, 117, 146, 139, 150, 113, 134, 134, 148, 146, 150, 150, 153, 113, 134, 146, 150, 134, 148, 150, 153, 119, 136, 148, 151, 148, 151, 153, 154, 4, 35, 13, 40, 13, 40, 39, 45, 13, 40, 17, 48, 52, 65, 57, 70, 13, 40, 52, 65, 17, 48, 57, 70, 39, 45, 57, 70, 57, 70, 76, 86, 7, 54, 16, 58, 16, 58, 41, 69, 16, 58, 21, 60, 53, 80, 59, 83, 16, 58, 53, 80, 21, 60, 59, 83, 41, 69, 59, 83, 59, 83, 79, 91, 13, 40, 17, 48, 52, 65, 57, 70, 17, 48, 23, 62, 75, 98, 76, 100, 52, 65, 75, 98, 75, 98, 108, 111, 57, 70, 76, 100, 108, 111, 114, 116, 20, 68, 27, 70, 58, 105, 66, 106, 27, 70, 29, 72, 80, 111, 81, 112, 58, 105, 80, 111, 82, 127, 109, 131, 66, 106, 81, 112, 109, 131, 115, 133, 13, 40, 52, 65, 17, 48, 57, 70, 52, 65, 75, 98, 75, 98, 108, 111, 17, 48, 75, 98, 23, 62, 76, 100, 57, 70, 108, 111, 76, 100, 114, 116, 20, 68, 58, 105, 27, 70, 66, 106, 58, 105, 82, 127, 80, 111, 109, 131, 27, 70, 80, 111, 29, 72, 81, 112, 66, 106, 109, 131, 81, 112, 115, 133, 39, 45, 57, 70, 57, 70, 76, 86, 57, 70, 76, 100, 108, 111, 114, 116, 57, 70, 108, 111, 76, 100, 114, 116, 76, 86, 114, 116, 114, 116, 137, 138, 45, 121, 70, 123, 70, 123, 100, 128, 70, 123, 86, 128, 111, 144, 116, 145, 70, 123, 111, 144, 86, 128, 116, 145, 100, 128, 116, 145, 116, 145, 138, 149, 7, 54, 16, 58, 16, 58, 41, 69, 20, 68, 27, 70, 58, 105, 66, 106, 20, 68, 58, 105, 27, 70, 66, 106, 45, 121, 70, 123, 70, 123, 100, 128, 9, 77, 18, 78, 18, 78, 43, 97, 21, 82, 28, 83, 59, 109, 67, 110, 21, 82, 59, 109, 28, 83, 67, 110, 46, 122, 71, 124, 71, 124, 101, 130, 16, 58, 21, 60, 53, 80, 59, 83, 27, 70, 29, 72, 80, 111, 81, 112, 58, 105, 82, 127, 80, 111, 109, 131, 70, 123, 86, 128, 111, 144, 116, 145, 21, 82, 28, 83, 59, 109, 67, 110, 29, 86, 31, 87, 81, 116, 85, 117, 60, 127, 83, 131, 83, 131, 110, 143, 72, 128, 87, 132, 112, 145, 117, 146, 16, 58, 53, 80, 21, 60, 59, 83, 58, 105, 80, 111, 82, 127, 109, 131, 27, 70, 80, 111, 29, 72, 81, 112, 70, 123, 111, 144, 86, 128, 116, 145, 21, 82, 59, 109, 28, 83, 67, 110, 60, 127, 83, 131, 83, 131, 110, 143, 29, 86, 81, 116, 31, 87, 85, 117, 72, 128, 112, 145, 87, 132, 117, 146, 41, 69, 59, 83, 59, 83, 79, 91, 66, 106, 81, 112, 109, 131, 115, 133, 66, 106, 109, 131, 81, 112, 115, 133, 100, 128, 116, 145, 116, 145, 138, 149, 46, 122, 71, 124, 71, 124, 101, 130, 72, 128, 87, 132, 112, 145, 117, 146, 72, 128, 112, 145, 87, 132, 117, 146, 102, 141, 118, 147, 118, 147, 139, 150, 7, 54, 20, 68, 20, 68, 45, 121, 16, 58, 27, 70, 58, 105, 70, 123, 16, 58, 58, 105, 27, 70, 70, 123, 41, 69, 66, 106, 66, 106, 100, 128, 9, 77, 21, 82, 21, 82, 46, 122, 18, 78, 28, 83, 59, 109, 71, 124, 18, 78, 59, 109, 28, 83, 71, 124, 43, 97, 67, 110, 67, 110, 101, 130, 16, 58, 27, 70, 58, 105, 70, 123, 21, 60, 29, 72, 82, 127, 86, 128, 53, 80, 80, 111, 80, 111, 111, 144, 59, 83, 81, 112, 109, 131, 116, 145, 21, 82, 29, 86, 60, 127, 72, 128, 28, 83, 31, 87, 83, 131, 87, 132, 59, 109, 81, 116, 83, 131, 112, 145, 67, 110, 85, 117, 110, 143, 117, 146, 16, 58, 58, 105, 27, 70, 70, 123, 53, 80, 80, 111, 80, 111, 111, 144, 21, 60, 82, 127, 29, 72, 86, 128, 59, 83, 109, 131, 81, 112, 116, 145, 21, 82, 60, 127, 29, 86, 72, 128, 59, 109, 83, 131, 81, 116, 112, 145, 28, 83, 83, 131, 31, 87, 87, 132, 67, 110, 110, 143, 85, 117, 117, 146, 41, 69, 66, 106, 66, 106, 100, 128, 59, 83, 81, 112, 109, 131, 116, 145, 59, 83, 109, 131, 81, 112, 116, 145, 79, 91, 115, 133, 115, 133, 138, 149, 46, 122, 72, 128, 72, 128, 102, 141, 71, 124, 87, 132, 112, 145, 118, 147, 71, 124, 112, 145, 87, 132, 118, 147, 101, 130, 117, 146, 117, 146, 139, 150, 9, 77, 21, 82, 21, 82, 46, 122, 21, 82, 29, 86, 60, 127, 72, 128, 21, 82, 60, 127, 29, 86, 72, 128, 46, 122, 72, 128, 72, 128, 102, 141, 10, 89, 22, 90, 22, 90, 47, 126, 22, 90, 30, 91, 61, 129, 73, 130, 22, 90, 61, 129, 30, 91, 73, 130, 47, 126, 73, 130, 73, 130, 103, 142, 18, 78, 28, 83, 59, 109, 71, 124, 28, 83, 31, 87, 83, 131, 87, 132, 59, 109, 83, 131, 81, 116, 112, 145, 71, 124, 87, 132, 112, 145, 118, 147, 22, 90, 30, 91, 61, 129, 73, 130, 30, 91, 32, 92, 84, 133, 88, 134, 61, 129, 84, 133, 84, 133, 113, 146, 73, 130, 88, 134, 113, 146, 119, 148, 18, 78, 59, 109, 28, 83, 71, 124, 59, 109, 81, 116, 83, 131, 112, 145, 28, 83, 83, 131, 31, 87, 87, 132, 71, 124, 112, 145, 87, 132, 118, 147, 22, 90, 61, 129, 30, 91, 73, 130, 61, 129, 84, 133, 84, 133, 113, 146, 30, 91, 84, 133, 32, 92, 88, 134, 73, 130, 113, 146, 88, 134, 119, 148, 43, 97, 67, 110, 67, 110, 101, 130, 67, 110, 85, 117, 110, 143, 117, 146, 67, 110, 110, 143, 85, 117, 117, 146, 101, 130, 117, 146, 117, 146, 139, 150, 47, 126, 73, 130, 73, 130, 103, 142, 73, 130, 88, 134, 113, 146, 119, 148, 73, 130, 113, 146, 88, 134, 119, 148, 103, 142, 119, 148, 119, 148, 140, 151, 11, 36, 14, 41, 36, 42, 41, 46, 14, 41, 18, 49, 55, 66, 59, 71, 36, 42, 55, 66, 42, 62, 66, 72, 41, 46, 59, 71, 66, 72, 81, 87, 14, 55, 18, 59, 41, 66, 49, 71, 18, 59, 22, 61, 59, 81, 61, 84, 41, 66, 59, 81, 46, 72, 71, 87, 49, 71, 61, 84, 71, 87, 84, 92, 14, 41, 18, 49, 55, 66, 59, 71, 18, 49, 24, 63, 78, 99, 79, 101, 55, 66, 78, 99, 96, 100, 109, 112, 59, 71, 79, 101, 109, 112, 115, 117, 25, 69, 28, 71, 69, 106, 71, 107, 28, 71, 30, 73, 83, 112, 84, 113, 69, 106, 83, 112, 122, 128, 124, 132, 71, 107, 84, 113, 124, 132, 125, 134, 36, 42, 55, 66, 42, 62, 66, 72, 55, 66, 78, 99, 96, 100, 109, 112, 42, 62, 96, 100, 62, 94, 100, 102, 66, 72, 109, 112, 100, 102, 116, 118, 55, 96, 78, 109, 66, 100, 99, 112, 78, 109, 90, 129, 109, 116, 129, 133, 66, 100, 109, 116, 72, 102, 112, 118, 99, 112, 129, 133, 112, 118, 133, 135, 41, 46, 59, 71, 66, 72, 81, 87, 59, 71, 79, 101, 109, 112, 115, 117, 66, 72, 109, 112, 100, 102, 116, 118, 81, 87, 115, 117, 116, 118, 138, 139, 69, 122, 83, 124, 106, 128, 112, 132, 83, 124, 91, 130, 131, 145, 133, 146, 106, 128, 131, 145, 128, 141, 145, 147, 112, 132, 133, 146, 145, 147, 149, 150, 14, 55, 18, 59, 41, 66, 49, 71, 25, 69, 28, 71, 69, 106, 71, 107, 55, 96, 78, 109, 66, 100, 99, 112, 69, 122, 83, 124, 106, 128, 112, 132, 18, 78, 24, 79, 49, 99, 63, 101, 28, 83, 30, 84, 71, 112, 73, 113, 59, 109, 79, 115, 71, 112, 101, 117, 71, 124, 84, 125, 107, 132, 113, 134, 18, 59, 22, 61, 59, 81, 61, 84, 28, 71, 30, 73, 83, 112, 84, 113, 78, 109, 90, 129, 109, 116, 129, 133, 83, 124, 91, 130, 131, 145, 133, 146, 28, 83, 30, 84, 71, 112, 73, 113, 31, 87, 32, 88, 87, 118, 88, 119, 83, 131, 91, 133, 124, 145, 130, 146, 87, 132, 92, 134, 132, 147, 134, 148, 41, 66, 59, 81, 46, 72, 71, 87, 69, 106, 83, 112, 122, 128, 124, 132, 66, 100, 109, 116, 72, 102, 112, 118, 106, 128, 131, 145, 128, 141, 145, 147, 59, 109, 79, 115, 71, 112, 101, 117, 83, 131, 91, 133, 124, 145, 130, 146, 81, 116, 115, 138, 87, 118, 117, 139, 112, 145, 133, 149, 132, 147, 146, 150, 49, 71, 61, 84, 71, 87, 84, 92, 71, 107, 84, 113, 124, 132, 125, 134, 99, 112, 129, 133, 112, 118, 133, 135, 112, 132, 133, 146, 145, 147, 149, 150, 71, 124, 84, 125, 107, 132, 113, 134, 87, 132, 92, 134, 132, 147, 134, 148, 112, 145, 133, 149, 132, 147, 146, 150, 118, 147, 135, 150, 147, 152, 150, 153, 14, 55, 25, 69, 55, 96, 69, 122, 18, 59, 28, 71, 78, 109, 83, 124, 41, 66, 69, 106, 66, 100, 106, 128, 49, 71, 71, 107, 99, 112, 112, 132, 18, 78, 28, 83, 59, 109, 71, 124, 24, 79, 30, 84, 79, 115, 84, 125, 49, 99, 71, 112, 71, 112, 107, 132, 63, 101, 73, 113, 101, 117, 113, 134, 18, 59, 28, 71, 78, 109, 83, 124, 22, 61, 30, 73, 90, 129, 91, 130, 59, 81, 83, 112, 109, 116, 131, 145, 61, 84, 84, 113, 129, 133, 133, 146, 28, 83, 31, 87, 83, 131, 87, 132, 30, 84, 32, 88, 91, 133, 92, 134, 71, 112, 87, 118, 124, 145, 132, 147, 73, 113, 88, 119, 130, 146, 134, 148, 41, 66, 69, 106, 66, 100, 106, 128, 59, 81, 83, 112, 109, 116, 131, 145, 46, 72, 122, 128, 72, 102, 128, 141, 71, 87, 124, 132, 112, 118, 145, 147, 59, 109, 83, 131, 81, 116, 112, 145, 79, 115, 91, 133, 115, 138, 133, 149, 71, 112, 124, 145, 87, 118, 132, 147, 101, 117, 130, 146, 117, 139, 146, 150, 49, 71, 71, 107, 99, 112, 112, 132, 61, 84, 84, 113, 129, 133, 133, 146, 71, 87, 124, 132, 112, 118, 145, 147, 84, 92, 125, 134, 133, 135, 149, 150, 71, 124, 87, 132, 112, 145, 118, 147, 84, 125, 92, 134, 133, 149, 135, 150, 107, 132, 132, 147, 132, 147, 147, 152, 113, 134, 134, 148, 146, 150, 150, 153, 18, 78, 28, 83, 59, 109, 71, 124, 28, 83, 31, 87, 83, 131, 87, 132, 59, 109, 83, 131, 81, 116, 112, 145, 71, 124, 87, 132, 112, 145, 118, 147, 22, 90, 30, 91, 61, 129, 73, 130, 30, 91, 32, 92, 84, 133, 88, 134, 61, 129, 84, 133, 84, 133, 113, 146, 73, 130, 88, 134, 113, 146, 119, 148, 24, 79, 30, 84, 79, 115, 84, 125, 30, 84, 32, 88, 91, 133, 92, 134, 79, 115, 91, 133, 115, 138, 133, 149, 84, 125, 92, 134, 133, 149, 135, 150, 30, 91, 32, 92, 84, 133, 88, 134, 32, 92, 33, 93, 92, 135, 93, 136, 84, 133, 92, 135, 125, 149, 134, 150, 88, 134, 93, 136, 134, 150, 136, 151, 49, 99, 71, 112, 71, 112, 107, 132, 71, 112, 87, 118, 124, 145, 132, 147, 71, 112, 124, 145, 87, 118, 132, 147, 107, 132, 132, 147, 132, 147, 147, 152, 61, 129, 84, 133, 84, 133, 113, 146, 84, 133, 92, 135, 125, 149, 134, 150, 84, 133, 125, 149, 92, 135, 134, 150, 113, 146, 134, 150, 134, 150, 148, 153, 63, 101, 73, 113, 101, 117, 113, 134, 73, 113, 88, 119, 130, 146, 134, 148, 101, 117, 130, 146, 117, 139, 146, 150, 113, 134, 134, 148, 146, 150, 150, 153, 73, 130, 88, 134, 113, 146, 119, 148, 88, 134, 93, 136, 134, 150, 136, 151, 113, 146, 134, 150, 134, 150, 148, 153, 119, 148, 136, 151, 148, 153, 151, 154, 11, 36, 36, 42, 14, 41, 41, 46, 36, 42, 42, 62, 55, 66, 66, 72, 14, 41, 55, 66, 18, 49, 59, 71, 41, 46, 66, 72, 59, 71, 81, 87, 14, 55, 41, 66, 18, 59, 49, 71, 41, 66, 46, 72, 59, 81, 71, 87, 18, 59, 59, 81, 22, 61, 61, 84, 49, 71, 71, 87, 61, 84, 84, 92, 36, 42, 42, 62, 55, 66, 66, 72, 42, 62, 62, 94, 96, 100, 100, 102, 55, 66, 96, 100, 78, 99, 109, 112, 66, 72, 100, 102, 109, 112, 116, 118, 55, 96, 66, 100, 78, 109, 99, 112, 66, 100, 72, 102, 109, 116, 112, 118, 78, 109, 109, 116, 90, 129, 129, 133, 99, 112, 112, 118, 129, 133, 133, 135, 14, 41, 55, 66, 18, 49, 59, 71, 55, 66, 96, 100, 78, 99, 109, 112, 18, 49, 78, 99, 24, 63, 79, 101, 59, 71, 109, 112, 79, 101, 115, 117, 25, 69, 69, 106, 28, 71, 71, 107, 69, 106, 122, 128, 83, 112, 124, 132, 28, 71, 83, 112, 30, 73, 84, 113, 71, 107, 124, 132, 84, 113, 125, 134, 41, 46, 66, 72, 59, 71, 81, 87, 66, 72, 100, 102, 109, 112, 116, 118, 59, 71, 109, 112, 79, 101, 115, 117, 81, 87, 116, 118, 115, 117, 138, 139, 69, 122, 106, 128, 83, 124, 112, 132, 106, 128, 128, 141, 131, 145, 145, 147, 83, 124, 131, 145, 91, 130, 133, 146, 112, 132, 145, 147, 133, 146, 149, 150, 14, 55, 41, 66, 18, 59, 49, 71, 55, 96, 66, 100, 78, 109, 99, 112, 25, 69, 69, 106, 28, 71, 71, 107, 69, 122, 106, 128, 83, 124, 112, 132, 18, 78, 49, 99, 24, 79, 63, 101, 59, 109, 71, 112, 79, 115, 101, 117, 28, 83, 71, 112, 30, 84, 73, 113, 71, 124, 107, 132, 84, 125, 113, 134, 41, 66, 46, 72, 59, 81, 71, 87, 66, 100, 72, 102, 109, 116, 112, 118, 69, 106, 122, 128, 83, 112, 124, 132, 106, 128, 128, 141, 131, 145, 145, 147, 59, 109, 71, 112, 79, 115, 101, 117, 81, 116, 87, 118, 115, 138, 117, 139, 83, 131, 124, 145, 91, 133, 130, 146, 112, 145, 132, 147, 133, 149, 146, 150, 18, 59, 59, 81, 22, 61, 61, 84, 78, 109, 109, 116, 90, 129, 129, 133, 28, 71, 83, 112, 30, 73, 84, 113, 83, 124, 131, 145, 91, 130, 133, 146, 28, 83, 71, 112, 30, 84, 73, 113, 83, 131, 124, 145, 91, 133, 130, 146, 31, 87, 87, 118, 32, 88, 88, 119, 87, 132, 132, 147, 92, 134, 134, 148, 49, 71, 71, 87, 61, 84, 84, 92, 99, 112, 112, 118, 129, 133, 133, 135, 71, 107, 124, 132, 84, 113, 125, 134, 112, 132, 145, 147, 133, 146, 149, 150, 71, 124, 107, 132, 84, 125, 113, 134, 112, 145, 132, 147, 133, 149, 146, 150, 87, 132, 132, 147, 92, 134, 134, 148, 118, 147, 147, 152, 135, 150, 150, 153, 14, 55, 55, 96, 25, 69, 69, 122, 41, 66, 66, 100, 69, 106, 106, 128, 18, 59, 78, 109, 28, 71, 83, 124, 49, 71, 99, 112, 71, 107, 112, 132, 18, 78, 59, 109, 28, 83, 71, 124, 49, 99, 71, 112, 71, 112, 107, 132, 24, 79, 79, 115, 30, 84, 84, 125, 63, 101, 101, 117, 73, 113, 113, 134, 41, 66, 66, 100, 69, 106, 106, 128, 46, 72, 72, 102, 122, 128, 128, 141, 59, 81, 109, 116, 83, 112, 131, 145, 71, 87, 112, 118, 124, 132, 145, 147, 59, 109, 81, 116, 83, 131, 112, 145, 71, 112, 87, 118, 124, 145, 132, 147, 79, 115, 115, 138, 91, 133, 133, 149, 101, 117, 117, 139, 130, 146, 146, 150, 18, 59, 78, 109, 28, 71, 83, 124, 59, 81, 109, 116, 83, 112, 131, 145, 22, 61, 90, 129, 30, 73, 91, 130, 61, 84, 129, 133, 84, 113, 133, 146, 28, 83, 83, 131, 31, 87, 87, 132, 71, 112, 124, 145, 87, 118, 132, 147, 30, 84, 91, 133, 32, 88, 92, 134, 73, 113, 130, 146, 88, 119, 134, 148, 49, 71, 99, 112, 71, 107, 112, 132, 71, 87, 112, 118, 124, 132, 145, 147, 61, 84, 129, 133, 84, 113, 133, 146, 84, 92, 133, 135, 125, 134, 149, 150, 71, 124, 112, 145, 87, 132, 118, 147, 107, 132, 132, 147, 132, 147, 147, 152, 84, 125, 133, 149, 92, 134, 135, 150, 113, 134, 146, 150, 134, 148, 150, 153, 18, 78, 59, 109, 28, 83, 71, 124, 59, 109, 81, 116, 83, 131, 112, 145, 28, 83, 83, 131, 31, 87, 87, 132, 71, 124, 112, 145, 87, 132, 118, 147, 22, 90, 61, 129, 30, 91, 73, 130, 61, 129, 84, 133, 84, 133, 113, 146, 30, 91, 84, 133, 32, 92, 88, 134, 73, 130, 113, 146, 88, 134, 119, 148, 49, 99, 71, 112, 71, 112, 107, 132, 71, 112, 87, 118, 124, 145, 132, 147, 71, 112, 124, 145, 87, 118, 132, 147, 107, 132, 132, 147, 132, 147, 147, 152, 61, 129, 84, 133, 84, 133, 113, 146, 84, 133, 92, 135, 125, 149, 134, 150, 84, 133, 125, 149, 92, 135, 134, 150, 113, 146, 134, 150, 134, 150, 148, 153, 24, 79, 79, 115, 30, 84, 84, 125, 79, 115, 115, 138, 91, 133, 133, 149, 30, 84, 91, 133, 32, 88, 92, 134, 84, 125, 133, 149, 92, 134, 135, 150, 30, 91, 84, 133, 32, 92, 88, 134, 84, 133, 125, 149, 92, 135, 134, 150, 32, 92, 92, 135, 33, 93, 93, 136, 88, 134, 134, 150, 93, 136, 136, 151, 63, 101, 101, 117, 73, 113, 113, 134, 101, 117, 117, 139, 130, 146, 146, 150, 73, 113, 130, 146, 88, 119, 134, 148, 113, 134, 146, 150, 134, 148, 150, 153, 73, 130, 113, 146, 88, 134, 119, 148, 113, 146, 134, 150, 134, 150, 148, 153, 88, 134, 134, 150, 93, 136, 136, 151, 119, 148, 148, 153, 136, 151, 151, 154, 34, 37, 37, 43, 37, 43, 43, 47, 37, 43, 43, 63, 64, 67, 67, 73, 37, 43, 64, 67, 43, 63, 67, 73, 43, 47, 67, 73, 67, 73, 85, 88, 37, 64, 43, 67, 43, 67, 63, 73, 43, 67, 47, 73, 67, 85, 73, 88, 43, 67, 67, 85, 47, 73, 73, 88, 63, 73, 73, 88, 73, 88, 88, 93, 37, 43, 43, 63, 64, 67, 67, 73, 43, 63, 63, 95, 97, 101, 101, 103, 64, 67, 97, 101, 97, 101, 110, 113, 67, 73, 101, 103, 110, 113, 117, 119, 64, 97, 67, 101, 97, 110, 101, 113, 67, 101, 73, 103, 110, 117, 113, 119, 97, 110, 110, 117, 126, 130, 130, 134, 101, 113, 113, 119, 130, 134, 134, 136, 37, 43, 64, 67, 43, 63, 67, 73, 64, 67, 97, 101, 97, 101, 110, 113, 43, 63, 97, 101, 63, 95, 101, 103, 67, 73, 110, 113, 101, 103, 117, 119, 64, 97, 97, 110, 67, 101, 101, 113, 97, 110, 126, 130, 110, 117, 130, 134, 67, 101, 110, 117, 73, 103, 113, 119, 101, 113, 130, 134, 113, 119, 134, 136, 43, 47, 67, 73, 67, 73, 85, 88, 67, 73, 101, 103, 110, 113, 117, 119, 67, 73, 110, 113, 101, 103, 117, 119, 85, 88, 117, 119, 117, 119, 139, 140, 97, 126, 110, 130, 110, 130, 117, 134, 110, 130, 130, 142, 143, 146, 146, 148, 110, 130, 143, 146, 130, 142, 146, 148, 117, 134, 146, 148, 146, 148, 150, 151, 37, 64, 43, 67, 43, 67, 63, 73, 64, 97, 67, 101, 97, 110, 101, 113, 64, 97, 97, 110, 67, 101, 101, 113, 97, 126, 110, 130, 110, 130, 117, 134, 43, 97, 63, 101, 63, 101, 95, 103, 67, 110, 73, 113, 101, 117, 103, 119, 67, 110, 101, 117, 73, 113, 103, 119, 101, 130, 113, 134, 113, 134, 119, 136, 43, 67, 47, 73, 67, 85, 73, 88, 67, 101, 73, 103, 110, 117, 113, 119, 97, 110, 126, 130, 110, 117, 130, 134, 110, 130, 130, 142, 143, 146, 146, 148, 67, 110, 73, 113, 101, 117, 103, 119, 85, 117, 88, 119, 117, 139, 119, 140, 110, 143, 130, 146, 130, 146, 142, 148, 117, 146, 134, 148, 146, 150, 148, 151, 43, 67, 67, 85, 47, 73, 73, 88, 97, 110, 110, 117, 126, 130, 130, 134, 67, 101, 110, 117, 73, 103, 113, 119, 110, 130, 143, 146, 130, 142, 146, 148, 67, 110, 101, 117, 73, 113, 103, 119, 110, 143, 130, 146, 130, 146, 142, 148, 85, 117, 117, 139, 88, 119, 119, 140, 117, 146, 146, 150, 134, 148, 148, 151, 63, 73, 73, 88, 73, 88, 88, 93, 101, 113, 113, 119, 130, 134, 134, 136, 101, 113, 130, 134, 113, 119, 134, 136, 117, 134, 146, 148, 146, 148, 150, 151, 101, 130, 113, 134, 113, 134, 119, 136, 117, 146, 134, 148, 146, 150, 148, 151, 117, 146, 146, 150, 134, 148, 148, 151, 139, 150, 150, 153, 150, 153, 153, 154, 37, 64, 64, 97, 64, 97, 97, 126, 43, 67, 67, 101, 97, 110, 110, 130, 43, 67, 97, 110, 67, 101, 110, 130, 63, 73, 101, 113, 101, 113, 117, 134, 43, 97, 67, 110, 67, 110, 101, 130, 63, 101, 73, 113, 101, 117, 113, 134, 63, 101, 101, 117, 73, 113, 113, 134, 95, 103, 103, 119, 103, 119, 119, 136, 43, 67, 67, 101, 97, 110, 110, 130, 47, 73, 73, 103, 126, 130, 130, 142, 67, 85, 110, 117, 110, 117, 143, 146, 73, 88, 113, 119, 130, 134, 146, 148, 67, 110, 85, 117, 110, 143, 117, 146, 73, 113, 88, 119, 130, 146, 134, 148, 101, 117, 117, 139, 130, 146, 146, 150, 103, 119, 119, 140, 142, 148, 148, 151, 43, 67, 97, 110, 67, 101, 110, 130, 67, 85, 110, 117, 110, 117, 143, 146, 47, 73, 126, 130, 73, 103, 130, 142, 73, 88, 130, 134, 113, 119, 146, 148, 67, 110, 110, 143, 85, 117, 117, 146, 101, 117, 130, 146, 117, 139, 146, 150, 73, 113, 130, 146, 88, 119, 134, 148, 103, 119, 142, 148, 119, 140, 148, 151, 63, 73, 101, 113, 101, 113, 117, 134, 73, 88, 113, 119, 130, 134, 146, 148, 73, 88, 130, 134, 113, 119, 146, 148, 88, 93, 134, 136, 134, 136, 150, 151, 101, 130, 117, 146, 117, 146, 139, 150, 113, 134, 134, 148, 146, 150, 150, 153, 113, 134, 146, 150, 134, 148, 150, 153, 119, 136, 148, 151, 148, 151, 153, 154, 43, 97, 67, 110, 67, 110, 101, 130, 67, 110, 85, 117, 110, 143, 117, 146, 67, 110, 110, 143, 85, 117, 117, 146, 101, 130, 117, 146, 117, 146, 139, 150, 47, 126, 73, 130, 73, 130, 103, 142, 73, 130, 88, 134, 113, 146, 119, 148, 73, 130, 113, 146, 88, 134, 119, 148, 103, 142, 119, 148, 119, 148, 140, 151, 63, 101, 73, 113, 101, 117, 113, 134, 73, 113, 88, 119, 130, 146, 134, 148, 101, 117, 130, 146, 117, 139, 146, 150, 113, 134, 134, 148, 146, 150, 150, 153, 73, 130, 88, 134, 113, 146, 119, 148, 88, 134, 93, 136, 134, 150, 136, 151, 113, 146, 134, 150, 134, 150, 148, 153, 119, 148, 136, 151, 148, 153, 151, 154, 63, 101, 101, 117, 73, 113, 113, 134, 101, 117, 117, 139, 130, 146, 146, 150, 73, 113, 130, 146, 88, 119, 134, 148, 113, 134, 146, 150, 134, 148, 150, 153, 73, 130, 113, 146, 88, 134, 119, 148, 113, 146, 134, 150, 134, 150, 148, 153, 88, 134, 134, 150, 93, 136, 136, 151, 119, 148, 148, 153, 136, 151, 151, 154, 95, 103, 103, 119, 103, 119, 119, 136, 103, 119, 119, 140, 142, 148, 148, 151, 103, 119, 142, 148, 119, 140, 148, 151, 119, 136, 148, 151, 148, 151, 153, 154, 103, 142, 119, 148, 119, 148, 140, 151, 119, 148, 136, 151, 148, 153, 151, 154, 119, 148, 148, 153, 136, 151, 151, 154, 140, 151, 151, 154, 151, 154, 154, 155 }; const unsigned int igraph_i_isographs_3[] = { 0, 1, 3, 5, 6, 7, 10, 11, 15, 21, 23, 25, 27, 30, 31, 63 }; const unsigned int igraph_i_isographs_3u[] = { 0, 1, 3, 7 }; const unsigned int igraph_i_isographs_4[] = { 0, 1, 3, 7, 9, 10, 11, 14, 15, 18, 19, 20, 21, 22, 23, 27, 29, 30, 31, 54, 55, 63, 73, 75, 76, 77, 79, 81, 83, 84, 85, 86, 87, 90, 91, 92, 93, 94, 95, 98, 99, 100, 101, 102, 103, 106, 107, 108, 109, 110, 111, 115, 116, 117, 118, 119, 122, 123, 124, 125, 126, 127, 219, 220, 221, 223, 228, 229, 230, 231, 237, 238, 239, 246, 247, 255, 292, 293, 295, 301, 302, 303, 310, 311, 319, 365, 367, 373, 375, 382, 383, 511, 585, 587, 591, 593, 594, 595, 596, 597, 598, 599, 601, 602, 603, 604, 605, 606, 607, 625, 626, 627, 630, 631, 633, 634, 635, 638, 639, 659, 660, 661, 663, 666, 667, 669, 670, 671, 674, 675, 678, 679, 683, 686, 687, 694, 695, 703, 729, 731, 732, 733, 735, 737, 739, 741, 742, 743, 745, 746, 747, 748, 749, 750, 751, 753, 755, 756, 757, 758, 759, 761, 762, 763, 764, 765, 766, 767, 819, 822, 823, 826, 827, 830, 831, 875, 876, 877, 879, 883, 885, 886, 887, 891, 892, 893, 894, 895, 947, 949, 951, 955, 957, 958, 959, 1019, 1020, 1021, 1023, 1755, 1757, 1758, 1759, 1782, 1783, 1791, 1883, 1887, 1907, 1911, 1917, 1918, 1919, 2029, 2031, 2039, 2047, 4095 }; const unsigned int igraph_i_isographs_4u[] = { 0, 1, 3, 7, 11, 12, 13, 15, 30, 31, 63 }; const unsigned int igraph_i_isographs_5u[] = { 0, 1, 3, 7, 11, 12, 13, 15, 30, 31, 63, 75, 76, 77, 79, 86, 87, 94, 95, 116, 117, 119, 127, 222, 223, 235, 236, 237, 239, 254, 255, 507, 511, 1023 }; const unsigned int igraph_i_isographs_6u[] = { 0, 1, 3, 7, 11, 12, 13, 15, 30, 31, 63, 75, 76, 77, 79, 86, 87, 94, 95, 116, 117, 119, 127, 222, 223, 235, 236, 237, 239, 254, 255, 507, 511, 1023, 1099, 1100, 1101, 1103, 1108, 1109, 1110, 1111, 1118, 1119, 1140, 1141, 1143, 1151, 1182, 1183, 1184, 1185, 1187, 1191, 1194, 1195, 1196, 1197, 1198, 1199, 1214, 1215, 1246, 1247, 1259, 1260, 1261, 1263, 1268, 1269, 1270, 1271, 1278, 1279, 1456, 1457, 1459, 1460, 1461, 1463, 1465, 1467, 1468, 1469, 1471, 1531, 1532, 1533, 1535, 1972, 1973, 1975, 1983, 2047, 3294, 3295, 3306, 3307, 3308, 3309, 3310, 3311, 3326, 3327, 3440, 3441, 3443, 3447, 3448, 3449, 3451, 3452, 3453, 3455, 3576, 3577, 3578, 3579, 3582, 3583, 3873, 3875, 3879, 3885, 3887, 3903, 3947, 3948, 3949, 3950, 3951, 3958, 3959, 3966, 3967, 4094, 4095, 7672, 7673, 7675, 7679, 7902, 7903, 7915, 7916, 7917, 7919, 7934, 7935, 8185, 8187, 8191, 16350, 16351, 16383, 32767 }; const unsigned int igraph_i_classedges_3[] = { 1, 2, 0, 2, 2, 1, 0, 1, 2, 0, 1, 0 }; const unsigned int igraph_i_classedges_3u[] = { 1, 2, 0, 2, 0, 1 }; const unsigned int igraph_i_classedges_4[] = { 2, 3, 1, 3, 0, 3, 3, 2, 1, 2, 0, 2, 3, 1, 2, 1, 0, 1, 3, 0, 2, 0, 1, 0 }; const unsigned int igraph_i_classedges_4u[] = { 2, 3, 1, 3, 0, 3, 1, 2, 0, 2, 0, 1 }; const unsigned int igraph_i_classedges_5u[] = { 3, 4, 2, 4, 1, 4, 0, 4, 2, 3, 1, 3, 0, 3, 1, 2, 0, 2, 0, 1 }; const unsigned int igraph_i_classedges_6u[] = { 4, 5, 3, 5, 2, 5, 1, 5, 0, 5, 3, 4, 2, 4, 1, 4, 0, 4, 2, 3, 1, 3, 0, 3, 1, 2, 0, 2, 0, 1 }; /** * \function igraph_isoclass * \brief Determine the isomorphism class of small graphs. * * * All graphs with a given number of vertices belong to a number of * isomorphism classes, with every graph in a given class being * isomorphic to each other. * * * This function gives the isomorphism class (a number) of a * graph. Two graphs have the same isomorphism class if and only if * they are isomorphic. * * * The first isomorphism class is numbered zero and it contains the edgeless * graph. The last isomorphism class contains the full graph. The number of * isomorphism classes for directed graphs with three vertices is 16 * (between 0 and 15), for undirected graph it is only 4. For graphs * with four vertices it is 218 (directed) and 11 (undirected). * For 5 and 6 vertex undirected graphs, it is 34 and 156, respectively. * For more information, see https://oeis.org/A000273 and https://oeis.org/A000088. * * * At the moment, 3- and 4-vertex directed graphs and 3 to 6 vertex * undirected graphs are supported. * * * Multi-edges and self-loops are ignored by this function. * * \param graph The graph object. * \param isoclass Pointer to an integer, the isomorphism class will * be stored here. * \return Error code. * \sa \ref igraph_isomorphic(), \ref igraph_isoclass_subgraph(), * \ref igraph_isoclass_create(), \ref igraph_motifs_randesu(). * * Because of some limitations this function works only for graphs * with three of four vertices. * * * Time complexity: O(|E|), the number of edges in the graph. */ int igraph_isoclass(const igraph_t *graph, igraph_integer_t *isoclass) { long int e; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); unsigned int idx, mul; const unsigned int *arr_idx, *arr_code; unsigned int code; if (igraph_is_directed(graph)) { switch (no_of_nodes) { case 3: arr_idx = igraph_i_isoclass_3_idx; arr_code = igraph_i_isoclass2_3; mul = 3; break; case 4: arr_idx = igraph_i_isoclass_4_idx; arr_code = igraph_i_isoclass2_4; mul = 4; break; default: IGRAPH_ERROR("Directed isoclass is only implemented for graphs with 3 or 4 vertices.", IGRAPH_UNIMPLEMENTED); } } else { switch (no_of_nodes) { case 3: arr_idx = igraph_i_isoclass_3u_idx; arr_code = igraph_i_isoclass2_3u; mul = 3; break; case 4: arr_idx = igraph_i_isoclass_4u_idx; arr_code = igraph_i_isoclass2_4u; mul = 4; break; case 5: arr_idx = igraph_i_isoclass_5u_idx; arr_code = igraph_i_isoclass2_5u; mul = 5; break; case 6: arr_idx = igraph_i_isoclass_6u_idx; arr_code = igraph_i_isoclass2_6u; mul = 6; break; default: IGRAPH_ERROR("Undirected isoclass is only implemented for graphs with 3 to 6 vertices.", IGRAPH_UNIMPLEMENTED); } } code = 0; for (e = 0; e < no_of_edges; e++) { idx = mul * IGRAPH_FROM(graph, e) + IGRAPH_TO(graph, e); code |= arr_idx[idx]; } *isoclass = (igraph_integer_t) arr_code[code]; return IGRAPH_SUCCESS; } /** * \function igraph_isoclass_subgraph * \brief The isomorphism class of a subgraph of a graph. * * This function identifies the isomorphism class of the subgraph * induced the vertices specified in \p vids. * * * At the moment, 3- and 4-vertex directed graphs and 3 to 6 vertex * undirected graphs are supported. * * * Multi-edges and self-loops are ignored by this function. * * \param graph The graph object. * \param vids A vector containing the vertex ids to be considered as * a subgraph. Each vertex id should be included at most once. * \param isoclass Pointer to an integer, this will be set to the * isomorphism class. * \return Error code. * \sa \ref igraph_isoclass(), \ref igraph_isomorphic(), * \ref igraph_isoclass_create(). * * Time complexity: O((d+n)*n), d is the average degree in the network, * and n is the number of vertices in \c vids. */ int igraph_isoclass_subgraph(const igraph_t *graph, const igraph_vector_t *vids, igraph_integer_t *isoclass) { int subgraph_size = (int) igraph_vector_size(vids); igraph_vector_t neis; unsigned int mul, idx; const unsigned int *arr_idx, *arr_code; unsigned int code = 0; long int i, j, s; IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); if (igraph_is_directed(graph)) { switch (subgraph_size) { case 3: arr_idx = igraph_i_isoclass_3_idx; arr_code = igraph_i_isoclass2_3; mul = 3; break; case 4: arr_idx = igraph_i_isoclass_4_idx; arr_code = igraph_i_isoclass2_4; mul = 4; break; default: IGRAPH_ERROR("Directed isoclass is only implemented for graphs with 3 or 4 vertices.", IGRAPH_UNIMPLEMENTED); } } else { switch (subgraph_size) { case 3: arr_idx = igraph_i_isoclass_3u_idx; arr_code = igraph_i_isoclass2_3u; mul = 3; break; case 4: arr_idx = igraph_i_isoclass_4u_idx; arr_code = igraph_i_isoclass2_4u; mul = 4; break; case 5: arr_idx = igraph_i_isoclass_5u_idx; arr_code = igraph_i_isoclass2_5u; mul = 5; break; case 6: arr_idx = igraph_i_isoclass_6u_idx; arr_code = igraph_i_isoclass2_6u; mul = 6; break; default: IGRAPH_ERROR("Undirected isoclass is only implemented for graphs with 3 to 6 vertices.", IGRAPH_UNIMPLEMENTED); } } for (i = 0; i < subgraph_size; i++) { long int from = (long int) VECTOR(*vids)[i]; igraph_neighbors(graph, &neis, (igraph_integer_t) from, IGRAPH_OUT); s = igraph_vector_size(&neis); for (j = 0; j < s; j++) { long int nei = (long int) VECTOR(neis)[j], to; if (igraph_vector_search(vids, 0, nei, &to)) { idx = (mul * i + to); code |= arr_idx[idx]; } } } *isoclass = (igraph_integer_t) arr_code[code]; igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \function igraph_isoclass_create * \brief Creates a graph from the given isomorphism class. * * * This function creates the canonical representative graph of the * given isomorphism class. * * * The isomorphism class is an integer between 0 and the number of * unique unlabeled (i.e. non-isomorphic) graphs on the given number * of vertices and give directedness. See https://oeis.org/A000273 * and https://oeis.org/A000088 for the number of directed and * undirected graphs on \p size nodes. * * * At the moment, 3- and 4-vertex directed graphs and 3 to 6 vertex * undirected graphs are supported. * * \param graph Pointer to an uninitialized graph object. * \param size The number of vertices to add to the graph. * \param number The isomorphism class. * \param directed Logical constant, whether to create a directed * graph. * \return Error code. * \sa \ref igraph_isoclass(), * \ref igraph_isoclass_subgraph(), * \ref igraph_isomorphic(). * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges in the graph to create. */ int igraph_isoclass_create(igraph_t *graph, igraph_integer_t size, igraph_integer_t number, igraph_bool_t directed) { igraph_vector_t edges; const unsigned int *classedges; long int graphcount; long int power; long int pos; unsigned int code; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); #define CHECK_ISOCLASS(number, directed, size, graphcount) \ IGRAPH_ERRORF( \ "Isoclass %" IGRAPH_PRId " requested, but there are only %ld" \ " %s graphs of size %" IGRAPH_PRId ".", IGRAPH_EINVAL, \ (igraph_integer_t) number, graphcount, directed ? "directed" : "undirected", size) if (directed) { switch (size) { case 3: { classedges = igraph_i_classedges_3; graphcount = sizeof(igraph_i_isographs_3) / sizeof(igraph_i_isographs_3[0]); if (number < 0 || number >= graphcount) { CHECK_ISOCLASS(number, directed, size, graphcount); } code = igraph_i_isographs_3[ (long int) number]; power = 32; break; } case 4: { classedges = igraph_i_classedges_4; graphcount = sizeof(igraph_i_isographs_4) / sizeof(igraph_i_isographs_4[0]); if (number < 0 || number >= graphcount) { CHECK_ISOCLASS(number, directed, size, graphcount); } code = igraph_i_isographs_4[ (long int) number]; power = 2048; break; } default: IGRAPH_ERROR("Directed isoclasses are supported only for graphs with 3 or 4 vertices.", IGRAPH_UNIMPLEMENTED); } } else { switch (size) { case 3: { classedges = igraph_i_classedges_3u; graphcount = sizeof(igraph_i_isographs_3u) / sizeof(igraph_i_isographs_3u[0]); if (number < 0 || number >= graphcount) { CHECK_ISOCLASS(number, directed, size, graphcount); } code = igraph_i_isographs_3u[ (long int) number]; power = 4; break; } case 4: { classedges = igraph_i_classedges_4u; graphcount = sizeof(igraph_i_isographs_4u) / sizeof(igraph_i_isographs_4u[0]); if (number < 0 || number >= graphcount) { CHECK_ISOCLASS(number, directed, size, graphcount); } code = igraph_i_isographs_4u[ (long int) number]; power = 32; break; } case 5: { classedges = igraph_i_classedges_5u; graphcount = sizeof(igraph_i_isographs_5u) / sizeof(igraph_i_isographs_5u[0]); if (number < 0 || number >= graphcount) { CHECK_ISOCLASS(number, directed, size, graphcount); } code = igraph_i_isographs_5u[ (long int) number]; power = 512; break; } case 6: { classedges = igraph_i_classedges_6u; graphcount = sizeof(igraph_i_isographs_6u) / sizeof(igraph_i_isographs_6u[0]); if (number < 0 || number >= graphcount) { CHECK_ISOCLASS(number, directed, size, graphcount); } code = igraph_i_isographs_6u[ (long int) number]; power = 16384; break; } default: IGRAPH_ERROR("Undirected isoclasses are supported only for graphs with 3 to 6 vertices.", IGRAPH_UNIMPLEMENTED); } } #undef CHECK_ISOCLASS pos = 0; while (code > 0) { if (code >= power) { IGRAPH_CHECK(igraph_vector_push_back(&edges, classedges[2 * pos])); IGRAPH_CHECK(igraph_vector_push_back(&edges, classedges[2 * pos + 1])); code -= power; } power /= 2; pos++; } IGRAPH_CHECK(igraph_create(graph, &edges, size, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/isomorphism/queries.c0000644000176200001440000001600514447675374020305 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_topology.h" #include "igraph_interface.h" #include "igraph_structural.h" /** * \section about_graph_isomorphism * * igraph provides four set of functions to deal with graph * isomorphism problems. * * The \ref igraph_isomorphic() and \ref igraph_subisomorphic() * functions make up the first set (in addition with the \ref * igraph_permute_vertices() function). These functions choose the * algorithm which is best for the supplied input graph. (The choice is * not very sophisticated though, see their documentation for * details.) * * The VF2 graph (and subgraph) isomorphism algorithm is implemented in * igraph, these functions are the second set. See \ref * igraph_isomorphic_vf2() and \ref igraph_subisomorphic_vf2() for * starters. * * Functions for the Bliss algorithm constitute the third set, * see \ref igraph_isomorphic_bliss(). * * Finally, the isomorphism classes of all graphs with three and * four vertices are precomputed and stored in igraph, so for these * small graphs there is a very simple fast way to decide isomorphism. * See \ref igraph_isomorphic_34(). * */ /** * \function igraph_isomorphic * \brief Decides whether two graphs are isomorphic * * * In simple terms, two graphs are isomorphic if they become indistinguishable * from each other once their vertex labels are removed (rendering the vertices * within each graph indistiguishable). More precisely, two graphs are isomorphic * if there is a one-to-one mapping from the vertices of the first one * to the vertices of the second such that it transforms the edge set of the * first graph into the edge set of the second. This mapping is called * an \em isomorphism. * * Currently, this function supports simple graphs and graphs * with self-loops, but does not support multigraphs. * * This function decides which graph isomorphism algorithm to be * used based on the input graphs. Right now it does the following: * \olist * \oli If one graph is directed and the other undirected then an * error is triggered. * \oli If one of the graphs has multi-edges then an error is triggered. * \oli If the two graphs does not have the same number of vertices * and edges it returns with \c FALSE. * \oli Otherwise, if the graphs have three or four vertices then an O(1) * algorithm is used with precomputed data. * \oli Otherwise Bliss is used, see \ref igraph_isomorphic_bliss(). * \endolist * * Please call the VF2 and Bliss functions directly if you need * something more sophisticated, e.g. you need the isomorphic mapping. * * \param graph1 The first graph. * \param graph2 The second graph. * \param iso Pointer to a logical variable, will be set to TRUE (1) * if the two graphs are isomorphic, and FALSE (0) otherwise. * \return Error code. * \sa \ref igraph_isoclass(), \ref igraph_isoclass_subgraph(), * \ref igraph_isoclass_create(). * * Time complexity: exponential. */ int igraph_isomorphic(const igraph_t *graph1, const igraph_t *graph2, igraph_bool_t *iso) { long int nodes1 = igraph_vcount(graph1), nodes2 = igraph_vcount(graph2); long int edges1 = igraph_ecount(graph1), edges2 = igraph_ecount(graph2); igraph_bool_t dir1 = igraph_is_directed(graph1), dir2 = igraph_is_directed(graph2); igraph_bool_t loop1, loop2, multi1, multi2; IGRAPH_CHECK(igraph_has_multiple(graph1, &multi1)); IGRAPH_CHECK(igraph_has_multiple(graph2, &multi2)); if (multi1 || multi2) { IGRAPH_ERROR("Isomorphism testing is not implemented for multigraphs", IGRAPH_UNIMPLEMENTED); } if (dir1 != dir2) { IGRAPH_ERROR("Cannot compare directed and undirected graphs", IGRAPH_EINVAL); } else if (nodes1 != nodes2 || edges1 != edges2) { *iso = 0; } else if (nodes1 == 3 || nodes1 == 4) { IGRAPH_CHECK(igraph_has_loop(graph1, &loop1)); IGRAPH_CHECK(igraph_has_loop(graph2, &loop2)); if (!loop1 && !loop2) { IGRAPH_CHECK(igraph_isomorphic_34(graph1, graph2, iso)); } else { IGRAPH_CHECK(igraph_isomorphic_bliss(graph1, graph2, NULL, NULL, iso, 0, 0, /*sh=*/ IGRAPH_BLISS_FL, 0, 0)); } } else { IGRAPH_CHECK(igraph_isomorphic_bliss(graph1, graph2, NULL, NULL, iso, 0, 0, /*sh=*/ IGRAPH_BLISS_FL, 0, 0)); } return 0; } /** * \function igraph_isomorphic_34 * Graph isomorphism for 3-4 vertices * * This function uses precomputed indices to decide isomorphism * problems for graphs with only 3 or 4 vertices. Multi-edges * and self-loops are ignored by this function. * \param graph1 The first input graph. * \param graph2 The second input graph. Must have the same * directedness as \p graph1. * \param iso Pointer to a boolean, the result is stored here. * \return Error code. * * Time complexity: O(1). */ int igraph_isomorphic_34(const igraph_t *graph1, const igraph_t *graph2, igraph_bool_t *iso) { igraph_integer_t class1, class2; IGRAPH_CHECK(igraph_isoclass(graph1, &class1)); IGRAPH_CHECK(igraph_isoclass(graph2, &class2)); *iso = (class1 == class2); return 0; } /** * \function igraph_subisomorphic * \brief Decide subgraph isomorphism. * * Check whether \p graph2 is isomorphic to a subgraph of \p graph1. * Currently this function just calls \ref igraph_subisomorphic_vf2() * for all graphs. * * * Currently this function does not support non-simple graphs. * * \param graph1 The first input graph, may be directed or * undirected. This is supposed to be the bigger graph. * \param graph2 The second input graph, it must have the same * directedness as \p graph2, or an error is triggered. This is * supposed to be the smaller graph. * \param iso Pointer to a boolean, the result is stored here. * \return Error code. * * Time complexity: exponential. */ int igraph_subisomorphic(const igraph_t *graph1, const igraph_t *graph2, igraph_bool_t *iso) { return igraph_subisomorphic_vf2(graph1, graph2, NULL, NULL, NULL, NULL, iso, NULL, NULL, NULL, NULL, NULL); } leidenbase/src/core/isomorphism/isomorphism_misc.c0000644000176200001440000000762314447675374022222 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_topology.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_iterators.h" /** * \function igraph_simplify_and_colorize * \brief Simplify the graph and compute self-loop and edge multiplicities. * * * This function creates a vertex and edge colored simple graph from the input * graph. The vertex colors are computed as the number of incident self-loops * to each vertex in the input graph. The edge colors are computed as the number of * parallel edges in the input graph that were merged to create each edge * in the simple graph. * * * The resulting colored simple graph is suitable for use by isomorphism checking * algorithms such as VF2, which only support simple graphs, but can consider * vertex and edge colors. * * \param graph The graph object, typically having self-loops or multi-edges. * \param res An uninitialized graph object. The result will be stored here * \param vertex_color Computed vertex colors corresponding to self-loop multiplicities. * \param edge_color Computed edge colors corresponding to edge multiplicities * \return Error code. * * \sa \ref igraph_simplify(), \ref igraph_isomorphic_vf2(), \ref igraph_subisomorphic_vf2() * */ int igraph_simplify_and_colorize( const igraph_t *graph, igraph_t *res, igraph_vector_int_t *vertex_color, igraph_vector_int_t *edge_color) { igraph_es_t es; igraph_eit_t eit; igraph_vector_t edges; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int pto = -1, pfrom = -1; long int i; IGRAPH_CHECK(igraph_es_all(&es, IGRAPH_EDGEORDER_FROM)); IGRAPH_FINALLY(igraph_es_destroy, &es); IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); IGRAPH_CHECK(igraph_vector_int_resize(vertex_color, no_of_nodes)); igraph_vector_int_null(vertex_color); IGRAPH_CHECK(igraph_vector_int_resize(edge_color, no_of_edges)); igraph_vector_int_null(edge_color); i = -1; for (; !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { long int edge = IGRAPH_EIT_GET(eit); long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO(graph, edge); if (to == from) { VECTOR(*vertex_color)[to]++; continue; } if (to == pto && from == pfrom) { VECTOR(*edge_color)[i]++; } else { igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); i++; VECTOR(*edge_color)[i] = 1; } pfrom = from; pto = to; } igraph_vector_int_resize(edge_color, i + 1); igraph_eit_destroy(&eit); igraph_es_destroy(&es); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(res, &edges, no_of_nodes, igraph_is_directed(graph))); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/isomorphism/lad.c0000644000176200001440000017641114447675374017400 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* The contents of this file was originally taken from the LAD homepage: http://liris.cnrs.fr/csolnon/LAD.html and then modified to fit better into igraph. Unfortunately LAD seems to have no version numbers. The files were apparently last changed on the 29th of June, 2010. The original copyright message follows here. The CeCILL-B V1 license is GPL compatible, because instead of V1, one can freely choose to use V2, and V2 is explicitly GPL compatible. */ /* This software has been written by Christine Solnon. It is distributed under the CeCILL-B FREE SOFTWARE LICENSE see http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html for more details */ /* Several modifications had to be made to the original LAD implementation to make it compile with non-C99-compliant compilers such as MSVC. In particular, I had to remove all the variable-sized arrays. -- Tamas Nepusz, 11 July 2013 */ #include "igraph_topology.h" #include "igraph_interface.h" #include "igraph_adjlist.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" #include "igraph_memory.h" #include "igraph_matrix.h" #include "igraph_qsort.h" #include "core/interruption.h" #include #include #include #include /* define boolean type as char */ #define true 1 #define false 0 #define bool char /* helper to allocate an array of given size and free it using IGRAPH_FINALLY * when needed */ #define ALLOC_ARRAY(VAR, SIZE, TYPE) { \ VAR = IGRAPH_CALLOC(SIZE, TYPE); \ if (VAR == 0) { \ IGRAPH_ERROR("cannot allocate '" #VAR "' array in LAD isomorphism search", IGRAPH_ENOMEM); \ } \ IGRAPH_FINALLY(igraph_free, VAR); \ } /* helper to allocate an array of given size and store its address in a * pointer array */ #define ALLOC_ARRAY_IN_HISTORY(VAR, SIZE, TYPE, HISTORY) { \ VAR = IGRAPH_CALLOC(SIZE, TYPE); \ if (VAR == 0) { \ IGRAPH_ERROR("cannot allocate '" #VAR "' array in LAD isomorphism search", IGRAPH_ENOMEM); \ } \ IGRAPH_FINALLY(igraph_free, VAR); \ IGRAPH_CHECK(igraph_vector_ptr_push_back(HISTORY, VAR)); \ IGRAPH_FINALLY_CLEAN(1); \ } /* ---------------------------------------------------------*/ /* Coming from graph.c */ /* ---------------------------------------------------------*/ typedef struct { long int nbVertices; /* Number of vertices */ igraph_vector_t nbSucc; igraph_adjlist_t succ; igraph_matrix_char_t isEdge; } Tgraph; static int igraph_i_lad_createGraph(const igraph_t *igraph, Tgraph* graph) { long int i, j, n; long int no_of_nodes = igraph_vcount(igraph); igraph_vector_int_t *neis; graph->nbVertices = no_of_nodes; IGRAPH_CHECK(igraph_adjlist_init(igraph, &graph->succ, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &graph->succ); IGRAPH_VECTOR_INIT_FINALLY(&graph->nbSucc, no_of_nodes); for (i=0; i < no_of_nodes; ++i) { VECTOR(graph->nbSucc)[i] = igraph_vector_int_size(igraph_adjlist_get(&graph->succ, i)); } IGRAPH_CHECK(igraph_matrix_char_init(&graph->isEdge, no_of_nodes, no_of_nodes)); IGRAPH_FINALLY(igraph_matrix_char_destroy, &graph->isEdge); for (i = 0; i < no_of_nodes; i++) { neis = igraph_adjlist_get(&graph->succ, i); n = igraph_vector_int_size(neis); for (j = 0; j < n; j++) { int v = (int)VECTOR(*neis)[j]; if (MATRIX(graph->isEdge, i, v)) { IGRAPH_ERROR("LAD functions do not support graphs with multi-edges.", IGRAPH_EINVAL); } MATRIX(graph->isEdge, i, v) = 1; } } IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } static void igraph_i_lad_destroyGraph(Tgraph *graph) { igraph_matrix_char_destroy(&graph->isEdge); igraph_adjlist_destroy(&graph->succ); igraph_vector_destroy(&graph->nbSucc); } /* ---------------------------------------------------------*/ /* Coming from domains.c */ /* ---------------------------------------------------------*/ typedef struct { igraph_vector_int_t nbVal; /* nbVal[u] = number of values in D[u] */ igraph_vector_int_t firstVal; /* firstVal[u] = pos in val of the first value of D[u] */ igraph_vector_int_t val; /* val[firstVal[u]..firstVal[u]+nbVal[u]-1] = values of D[u] */ igraph_matrix_int_t posInVal; /* If v in D[u] then firstVal[u] <= posInVal[u][v] < firstVal[u]+nbVal[u] and val[posInVal[u][v]] = v otherwise posInVal[u][v] >= firstVal[u]+nbVal[u] */ int valSize; /* size of val */ igraph_matrix_int_t firstMatch; /* firstMatch[u][v] = pos in match of the first vertex of the covering matching of G_(u, v) */ igraph_vector_int_t matching; /* matching[firstMatch[u][v]..firstMatch[u][v]+nbSucc[u]-1] = covering matching of G_(u, v) */ int nextOutToFilter; /* position in toFilter of the next pattern node whose domain should be filtered (-1 if no domain to filter) */ int lastInToFilter; /* position in toFilter of the last pattern node whose domain should be filtered */ igraph_vector_int_t toFilter; /* contain all pattern nodes whose domain should be filtered */ igraph_vector_char_t markedToFilter; /* markedToFilter[u]=true if u is in toFilter; false otherwise */ igraph_vector_int_t globalMatchingP; /* globalMatchingP[u] = node of Gt matched to u in globalAllDiff(Np) */ igraph_vector_int_t globalMatchingT; /* globalMatchingT[v] = node of Gp matched to v in globalAllDiff(Np) or -1 if v is not matched */ } Tdomain; static bool igraph_i_lad_toFilterEmpty(Tdomain* D) { /* return true if there is no more nodes in toFilter */ return (D->nextOutToFilter < 0); } static void igraph_i_lad_resetToFilter(Tdomain *D) { /* empty to filter and unmark the vertices that are marked to be filtered */ igraph_vector_char_null(&D->markedToFilter); D->nextOutToFilter = -1; } static int igraph_i_lad_nextToFilter(Tdomain* D, int size) { /* precondition: emptyToFilter = false remove a node from toFilter (FIFO) unmark this node and return it */ int u = VECTOR(D->toFilter)[D->nextOutToFilter]; VECTOR(D->markedToFilter)[u] = false; if (D->nextOutToFilter == D->lastInToFilter) { /* u was the last node in tofilter */ D->nextOutToFilter = -1; } else if (D->nextOutToFilter == size - 1) { D->nextOutToFilter = 0; } else { D->nextOutToFilter++; } return u; } static void igraph_i_lad_addToFilter(int u, Tdomain* D, int size) { /* if u is not marked, then add it to toFilter and mark it */ if (VECTOR(D->markedToFilter)[u]) { return; } VECTOR(D->markedToFilter)[u] = true; if (D->nextOutToFilter < 0) { D->lastInToFilter = 0; D->nextOutToFilter = 0; } else if (D->lastInToFilter == size - 1) { D->lastInToFilter = 0; } else { D->lastInToFilter++; } VECTOR(D->toFilter)[D->lastInToFilter] = u; } static bool igraph_i_lad_isInD(int u, int v, Tdomain* D) { /* returns true if v belongs to D(u); false otherwise */ return (MATRIX(D->posInVal, u, v) < VECTOR(D->firstVal)[u] + VECTOR(D->nbVal)[u]); } static int igraph_i_lad_augmentingPath(int u, Tdomain* D, int nbV, bool* result) { /* return true if there exists an augmenting path starting from u and ending on a free vertex v in the bipartite directed graph G=(U, V, E) such that U=pattern nodes, V=target nodes, and E={(u, v), v in D(u)} U {(v, u), D->globalMatchingP[u]=v} update D-globalMatchingP and D->globalMatchingT consequently */ int *fifo, *pred; bool *marked; int nextIn = 0; int nextOut = 0; int i, v, v2, u2; *result = false; /* Allocate memory */ ALLOC_ARRAY(fifo, nbV, int); ALLOC_ARRAY(pred, nbV, int); ALLOC_ARRAY(marked, nbV, bool); for (i = 0; i < VECTOR(D->nbVal)[u]; i++) { v = VECTOR(D->val)[ VECTOR(D->firstVal)[u] + i ]; /* v in D(u) */ if (VECTOR(D->globalMatchingT)[v] < 0) { /* v is free => augmenting path found */ VECTOR(D->globalMatchingP)[u] = v; VECTOR(D->globalMatchingT)[v] = u; *result = true; goto cleanup; } /* v is not free => add it to fifo */ pred[v] = u; fifo[nextIn++] = v; marked[v] = true; } while (nextOut < nextIn) { u2 = VECTOR(D->globalMatchingT)[fifo[nextOut++]]; for (i = 0; i < VECTOR(D->nbVal)[u2]; i++) { v = VECTOR(D->val)[ VECTOR(D->firstVal)[u2] + i ]; /* v in D(u2) */ if (VECTOR(D->globalMatchingT)[v] < 0) { /* v is free => augmenting path found */ while (u2 != u) { /* update global matching wrt path */ v2 = VECTOR(D->globalMatchingP)[u2]; VECTOR(D->globalMatchingP)[u2] = v; VECTOR(D->globalMatchingT)[v] = u2; v = v2; u2 = pred[v]; } VECTOR(D->globalMatchingP)[u] = v; VECTOR(D->globalMatchingT)[v] = u; *result = true; goto cleanup; } if (!marked[v]) { /* v is not free and not marked => add it to fifo */ pred[v] = u2; fifo[nextIn++] = v; marked[v] = true; } } } cleanup: igraph_free(fifo); igraph_free(pred); igraph_free(marked); IGRAPH_FINALLY_CLEAN(3); return 0; } static int igraph_i_lad_removeAllValuesButOne(int u, int v, Tdomain* D, Tgraph* Gp, Tgraph* Gt, bool* result) { /* remove all values but v from D(u) and add all successors of u in toFilter return false if an inconsistency is detected wrt to global all diff */ int j, oldPos, newPos; igraph_vector_int_t *uneis = igraph_adjlist_get(&Gp->succ, u); int n = (int) igraph_vector_int_size(uneis); /* add all successors of u in toFilter */ for (j = 0; j < n; j++) { igraph_i_lad_addToFilter((int) VECTOR(*uneis)[j], D, (int) (Gp->nbVertices)); } /* remove all values but v from D[u] */ oldPos = MATRIX(D->posInVal, u, v); newPos = VECTOR(D->firstVal)[u]; VECTOR(D->val)[oldPos] = VECTOR(D->val)[newPos]; VECTOR(D->val)[newPos] = v; MATRIX(D->posInVal, u, VECTOR(D->val)[newPos]) = newPos; MATRIX(D->posInVal, u, VECTOR(D->val)[oldPos]) = oldPos; VECTOR(D->nbVal)[u] = 1; /* update global matchings that support the global all different constraint */ if (VECTOR(D->globalMatchingP)[u] != v) { VECTOR(D->globalMatchingT)[ VECTOR(D->globalMatchingP)[u] ] = -1; VECTOR(D->globalMatchingP)[u] = -1; IGRAPH_CHECK(igraph_i_lad_augmentingPath(u, D, (int) (Gt->nbVertices), result)); } else { *result = true; } return 0; } static int igraph_i_lad_removeValue(int u, int v, Tdomain* D, Tgraph* Gp, Tgraph* Gt, bool* result) { /* remove v from D(u) and add all successors of u in toFilter return false if an inconsistency is detected wrt global all diff */ int j; igraph_vector_int_t *uneis = igraph_adjlist_get(&Gp->succ, u); int n = (int) igraph_vector_int_size(uneis); int oldPos, newPos; /* add all successors of u in toFilter */ for (j = 0; j < n; j++) { igraph_i_lad_addToFilter((int) VECTOR(*uneis)[j], D, (int) (Gp->nbVertices)); } /* remove v from D[u] */ oldPos = MATRIX(D->posInVal, u, v); VECTOR(D->nbVal)[u]--; newPos = VECTOR(D->firstVal)[u] + VECTOR(D->nbVal)[u]; VECTOR(D->val)[oldPos] = VECTOR(D->val)[newPos]; VECTOR(D->val)[newPos] = v; MATRIX(D->posInVal, u, VECTOR(D->val)[oldPos]) = oldPos; MATRIX(D->posInVal, u, VECTOR(D->val)[newPos]) = newPos; /* update global matchings that support the global all different constraint */ if (VECTOR(D->globalMatchingP)[u] == v) { VECTOR(D->globalMatchingP)[u] = -1; VECTOR(D->globalMatchingT)[v] = -1; IGRAPH_CHECK(igraph_i_lad_augmentingPath(u, D, (int) (Gt->nbVertices), result)); } else { *result = true; } return 0; } static int igraph_i_lad_matchVertices(int nb, igraph_vector_int_t* toBeMatched, bool induced, Tdomain* D, Tgraph* Gp, Tgraph* Gt, int *invalid) { /* for each u in toBeMatched[0..nb-1], match u to D->val[D->firstVal[u] and filter domains of other non matched vertices wrt FC(Edges) and FC(diff) (this is not mandatory, as LAD is stronger than FC(Edges) and GAC(allDiff) is stronger than FC(diff), but this speeds up the solution process). return false if an inconsistency is detected by FC(Edges) or FC(diff); true otherwise; */ int j, u, v, u2, oldNbVal; igraph_vector_int_t *vneis; bool result = false; while (nb > 0) { u = VECTOR(*toBeMatched)[--nb]; v = VECTOR(D->val)[ VECTOR(D->firstVal)[u] ]; vneis = igraph_adjlist_get(&Gt->succ, v); /* match u to v */ for (u2 = 0; u2 < Gp->nbVertices; u2++) { if (u != u2) { oldNbVal = VECTOR(D->nbVal)[u2]; if (igraph_i_lad_isInD(u2, v, D)) { IGRAPH_CHECK(igraph_i_lad_removeValue(u2, v, D, Gp, Gt, &result)); if (!result) { *invalid = 1 ; return 0; } } if (MATRIX(Gp->isEdge, u, u2)) { /* remove from D[u2] vertices which are not adjacent to v */ j = VECTOR(D->firstVal)[u2]; while (j < VECTOR(D->firstVal)[u2] + VECTOR(D->nbVal)[u2]) { if (MATRIX(Gt->isEdge, v, VECTOR(D->val)[j])) { j++; } else { IGRAPH_CHECK(igraph_i_lad_removeValue(u2, VECTOR(D->val)[j], D, Gp, Gt, &result)); if (!result) { *invalid = 1; return 0; } } } } else if (induced) { /* (u, u2) is not an edge => remove neighbors of v from D[u2] */ if (VECTOR(D->nbVal)[u2] < VECTOR(Gt->nbSucc)[v]) { j = VECTOR(D->firstVal)[u2]; while (j < VECTOR(D->firstVal)[u2] + VECTOR(D->nbVal)[u2]) { if (!MATRIX(Gt->isEdge, v, VECTOR(D->val)[j])) { j++; } else { IGRAPH_CHECK(igraph_i_lad_removeValue(u2, VECTOR(D->val)[j], D, Gp, Gt, &result)); if (!result) { *invalid = 1; return 0; } } } } else { for (j = 0; j < VECTOR(Gt->nbSucc)[v]; j++) { if (igraph_i_lad_isInD(u2, (int) VECTOR(*vneis)[j], D)) { IGRAPH_CHECK(igraph_i_lad_removeValue(u2, (int) VECTOR(*vneis)[j], D, Gp, Gt, &result)); if (!result) { *invalid = 1; return 0; } } } } } if (VECTOR(D->nbVal)[u2] == 0) { *invalid = 1; /* D[u2] is empty */ return 0; } if ((VECTOR(D->nbVal)[u2] == 1) && (oldNbVal > 1)) { VECTOR(*toBeMatched)[nb++] = u2; } } } } *invalid = 0; return 0; } static bool igraph_i_lad_matchVertex(int u, bool induced, Tdomain* D, Tgraph* Gp, Tgraph *Gt) { int invalid; /* match u to D->val[D->firstVal[u]] and filter domains of other non matched vertices wrt FC(Edges) and FC(diff) (this is not mandatory, as LAD is stronger than FC(Edges) and GAC(allDiff) is stronger than FC(diff), but this speeds up the solution process). return false if an inconsistency is detected by FC(Edges) or FC(diff); true otherwise; */ igraph_vector_int_t toBeMatched; igraph_vector_int_init(&toBeMatched, Gp->nbVertices); IGRAPH_FINALLY(igraph_vector_int_destroy, &toBeMatched); VECTOR(toBeMatched)[0] = u; IGRAPH_CHECK(igraph_i_lad_matchVertices(1, &toBeMatched, induced, D, Gp, Gt, &invalid)); igraph_vector_int_destroy(&toBeMatched); IGRAPH_FINALLY_CLEAN(1); return invalid ? false : true; } static int igraph_i_lad_qcompare (void const *a, void const *b) { /* function used by the qsort function */ int pa = *((int*)a) - *((int*)b); return pa; } static bool igraph_i_lad_compare(int size_mu, int* mu, int size_mv, int* mv) { /* return true if for every element u of mu there exists a different element v of mv such that u <= v; return false otherwise */ int i, j; igraph_qsort(mu, (size_t) size_mu, sizeof(int), igraph_i_lad_qcompare); igraph_qsort(mv, (size_t) size_mv, sizeof(int), igraph_i_lad_qcompare); i = size_mv - 1; for (j = size_mu - 1; j >= 0; j--) { if (mu[j] > mv[i]) { return false; } i--; } return true; } static int igraph_i_lad_initDomains(bool initialDomains, const igraph_vector_ptr_t *domains, Tdomain *D, const Tgraph *Gp, const Tgraph *Gt, int *empty) { /* for every pattern node u, initialize D(u) with every vertex v such that for every neighbor u' of u there exists a different neighbor v' of v such that degree(u) <= degree(v) if initialDomains, then filter initial domains wrt compatibilities given in file return false if a domain is empty and true otherwise */ int *val; bool *dom; int *mu, *mv; int matchingSize, u, v, i, j; igraph_vector_t *vec; ALLOC_ARRAY(val, Gp->nbVertices * Gt->nbVertices, int); ALLOC_ARRAY(dom, Gt->nbVertices, bool); IGRAPH_VECTOR_INT_INIT_FINALLY(&D->globalMatchingP, Gp->nbVertices); igraph_vector_int_fill(&D->globalMatchingP, -1L); IGRAPH_VECTOR_INT_INIT_FINALLY(&D->globalMatchingT, Gt->nbVertices); igraph_vector_int_fill(&D->globalMatchingT, -1L); IGRAPH_VECTOR_INT_INIT_FINALLY(&D->nbVal, Gp->nbVertices); IGRAPH_CHECK(igraph_vector_int_init(&D->firstVal, Gp->nbVertices)); IGRAPH_FINALLY(igraph_vector_int_destroy, &D->firstVal); IGRAPH_CHECK(igraph_matrix_int_init(&D->posInVal, Gp->nbVertices, Gt->nbVertices)); IGRAPH_FINALLY(igraph_matrix_int_destroy, &D->posInVal); IGRAPH_CHECK(igraph_matrix_int_init(&D->firstMatch, Gp->nbVertices, Gt->nbVertices)); IGRAPH_FINALLY(igraph_matrix_int_destroy, &D->firstMatch); IGRAPH_CHECK(igraph_vector_char_init(&D->markedToFilter, Gp->nbVertices)); IGRAPH_FINALLY(igraph_vector_char_destroy, &D->markedToFilter); IGRAPH_VECTOR_INT_INIT_FINALLY(&D->toFilter, Gp->nbVertices); D->valSize = 0; matchingSize = 0; for (u = 0; u < Gp->nbVertices; u++) { igraph_vector_int_t *Gp_uneis = igraph_adjlist_get(&Gp->succ, u); if (initialDomains) { /* read the list of target vertices which are compatible with u */ vec = VECTOR(*domains)[u]; i = (int) igraph_vector_size(vec); memset(dom, false, sizeof(bool) * (size_t)(Gt->nbVertices)); for (j = 0; j < i; j++) { v = (int) VECTOR(*vec)[j]; dom[v] = true; } } VECTOR(D->markedToFilter)[u] = true; VECTOR(D->toFilter)[u] = u; VECTOR(D->nbVal)[u] = 0; VECTOR(D->firstVal)[u] = D->valSize; for (v = 0; v < Gt->nbVertices; v++) { igraph_vector_int_t *Gt_vneis = igraph_adjlist_get(&Gt->succ, v); if ((initialDomains) && (!dom[v])) { /* v not in D(u) */ MATRIX(D->posInVal, u, v) = (int) (VECTOR(D->firstVal)[u] + Gt->nbVertices); } else { MATRIX(D->firstMatch, u, v) = matchingSize; matchingSize += VECTOR(Gp->nbSucc)[u]; if (VECTOR(Gp->nbSucc)[u] <= VECTOR(Gt->nbSucc)[v]) { mu = IGRAPH_CALLOC((long int) VECTOR(Gp->nbSucc)[u], int); if (mu == 0) { igraph_free(val); igraph_free(dom); IGRAPH_ERROR("cannot allocate 'mu' array in igraph_i_lad_initDomains", IGRAPH_ENOMEM); } mv = IGRAPH_CALLOC((long int) VECTOR(Gt->nbSucc)[v], int); if (mv == 0) { igraph_free(mu); igraph_free(val); igraph_free(dom); IGRAPH_ERROR("cannot allocate 'mv' array in igraph_i_lad_initDomains", IGRAPH_ENOMEM); } for (i = 0; i < VECTOR(Gp->nbSucc)[u]; i++) { mu[i] = (int) VECTOR(Gp->nbSucc)[(long int) VECTOR(*Gp_uneis)[i]]; } for (i = 0; i < VECTOR(Gt->nbSucc)[v]; i++) { mv[i] = (int) VECTOR(Gt->nbSucc)[(long int) VECTOR(*Gt_vneis)[i]]; } if (igraph_i_lad_compare((int) VECTOR(Gp->nbSucc)[u], mu, (int) VECTOR(Gt->nbSucc)[v], mv) == 1) { val[D->valSize] = v; VECTOR(D->nbVal)[u]++; MATRIX(D->posInVal, u, v) = D->valSize++; } else { /* v not in D(u) */ MATRIX(D->posInVal, u, v) = (int)(VECTOR(D->firstVal)[u] + Gt->nbVertices); } igraph_free(mu); mu = 0; igraph_free(mv); mv = 0; } else { /* v not in D(u) */ MATRIX(D->posInVal, u, v) = (int) (VECTOR(D->firstVal)[u] + Gt->nbVertices); } } } if (VECTOR(D->nbVal)[u] == 0) { *empty = 1; /* empty domain */ igraph_free(val); igraph_free(dom); /* On this branch, 'val' and 'matching' are unused. * We init them anyway so that we can have a consistent destructor. */ IGRAPH_VECTOR_INT_INIT_FINALLY(&D->val, 0); IGRAPH_VECTOR_INT_INIT_FINALLY(&D->matching, 0); IGRAPH_FINALLY_CLEAN(12); return IGRAPH_SUCCESS; } } IGRAPH_VECTOR_INT_INIT_FINALLY(&D->val, D->valSize); for (i = 0; i < D->valSize; i++) { VECTOR(D->val)[i] = val[i]; } IGRAPH_VECTOR_INT_INIT_FINALLY(&D->matching, matchingSize); igraph_vector_int_fill(&D->matching, -1); D->nextOutToFilter = 0; D->lastInToFilter = (int) (Gp->nbVertices - 1); *empty = 0; igraph_free(val); igraph_free(dom); IGRAPH_FINALLY_CLEAN(12); return IGRAPH_SUCCESS; } static void igraph_i_lad_destroyDomains(Tdomain *D) { igraph_vector_int_destroy(&D->globalMatchingP); igraph_vector_int_destroy(&D->globalMatchingT); igraph_vector_int_destroy(&D->nbVal); igraph_vector_int_destroy(&D->firstVal); igraph_matrix_int_destroy(&D->posInVal); igraph_matrix_int_destroy(&D->firstMatch); igraph_vector_char_destroy(&D->markedToFilter); igraph_vector_int_destroy(&D->toFilter); igraph_vector_int_destroy(&D->val); igraph_vector_int_destroy(&D->matching); } /* ---------------------------------------------------------*/ /* Coming from allDiff.c */ /* ---------------------------------------------------------*/ #define white 0 #define grey 1 #define black 2 #define toBeDeleted 3 #define deleted 4 static void igraph_i_lad_addToDelete(int u, int* list, int* nb, int* marked) { if (marked[u] < toBeDeleted) { list[(*nb)++] = u; marked[u] = toBeDeleted; } } static int igraph_i_lad_updateMatching(int sizeOfU, int sizeOfV, igraph_vector_int_t *degree, igraph_vector_int_t *firstAdj, igraph_vector_int_t *adj, igraph_vector_int_t * matchedWithU, int *invalid) { /* input: sizeOfU = number of vertices in U sizeOfV = number of vertices in V degree[u] = number of vertices of V which are adjacent to u firstAdj[u] = pos in adj of the first vertex of V adjacent to u adj[firstAdj[u]..firstAdj[u]+sizeOfU[u]-1] = vertices of V adjacent to u input/output: matchedWithU[u] = vertex of V matched with u returns true if there exists a matching that covers U, i.e., if for every u in 0..nbU-1, there exists a different v in 0..nb-1 such that v is adjacent to u; returns false otherwise */ int *matchedWithV; /* matchedWithV[matchedWithU[u]]=u */ int *nbPred; /* nbPred[i] = nb of predecessors of the ith vertex of V in the DAG */ int *pred; /* pred[i][j] = jth predecessor the ith vertex of V in the DAG */ int *nbSucc; /* nbSucc[i] = nb of successors of the ith vertex of U in the DAG */ int *succ; /* succ[i][j] = jth successor of the ith vertex of U in the DAG */ int *listV, *listU, *listDV, *listDU; int nbV, nbU, nbDV, nbDU; int i, j, k, stop, u, v; int *markedV, *markedU; /* markedX[i]=white if X[i] is not in the DAG markedX[i]=grey if X[i] has been added to the DAG, but not its successors markedX[i]=black if X[i] and its successors have been added to the DAG markedX[i]=toBeDeleted if X[i] must be deleted from the DAG markedX[i]=deleted if X[i] has been deleted from the DAG */ int nbUnmatched = 0; /* number of vertices of U that are not matched */ int *unmatched; /* vertices of U that are not matched */ int *posInUnmatched; /* unmatched[posInUnmatched[u]]=u */ igraph_vector_int_t path; if (sizeOfU > sizeOfV) { *invalid = 1; /* trivial case of infeasibility */ return 0; } ALLOC_ARRAY(matchedWithV, sizeOfV, int); ALLOC_ARRAY(nbPred, sizeOfV, int); ALLOC_ARRAY(pred, sizeOfV * sizeOfU, int); ALLOC_ARRAY(nbSucc, sizeOfU, int); ALLOC_ARRAY(succ, sizeOfU * sizeOfV, int); ALLOC_ARRAY(listV, sizeOfV, int); ALLOC_ARRAY(listU, sizeOfU, int); ALLOC_ARRAY(listDV, sizeOfV, int); ALLOC_ARRAY(listDU, sizeOfU, int); ALLOC_ARRAY(markedV, sizeOfV, int); ALLOC_ARRAY(markedU, sizeOfU, int); ALLOC_ARRAY(unmatched, sizeOfU, int); ALLOC_ARRAY(posInUnmatched, sizeOfU, int); IGRAPH_CHECK(igraph_vector_int_init(&path, 0)); IGRAPH_FINALLY(igraph_vector_int_destroy, &path); /* initialize matchedWithV and unmatched */ memset(matchedWithV, -1, (size_t)sizeOfV * sizeof(int)); for (u = 0; u < sizeOfU; u++) { if (VECTOR(*matchedWithU)[u] >= 0) { matchedWithV[VECTOR(*matchedWithU)[u]] = u; } else { posInUnmatched[u] = nbUnmatched; unmatched[nbUnmatched++] = u; } } /* try to match unmatched vertices of U with free vertices of V */ j = 0; while (j < nbUnmatched) { u = unmatched[j]; for (i = VECTOR(*firstAdj)[u]; ((i < VECTOR(*firstAdj)[u] + VECTOR(*degree)[u]) && (matchedWithV[VECTOR(*adj)[i]] >= 0)); i++) { } if (i == VECTOR(*firstAdj)[u] + VECTOR(*degree)[u]) { j++; /* no free vertex for u */ } else { v = VECTOR(*adj)[i]; /* v is free => match u with v */ VECTOR(*matchedWithU)[u] = v; matchedWithV[v] = u; unmatched[j] = unmatched[--nbUnmatched]; posInUnmatched[unmatched[j]] = j; } } while (nbUnmatched > 0) { /* Try to increase the number of matched vertices */ /* step 1 : build the DAG */ memset(markedU, white, (size_t) sizeOfU * sizeof(int)); memset(nbSucc, 0, (size_t) sizeOfU * sizeof(int)); memset(markedV, white, (size_t) sizeOfV * sizeof(int)); memset(nbPred, 0, (size_t) sizeOfV * sizeof(int)); /* first layer of the DAG from the free nodes of U */ nbV = 0; for (j = 0; j < nbUnmatched; j++) { u = unmatched[j]; /* u is a free node of U */ markedU[u] = black; for (i = VECTOR(*firstAdj)[u]; i < VECTOR(*firstAdj)[u] + VECTOR(*degree)[u]; i++) { v = VECTOR(*adj)[i]; /* add edge (u, v) to the DAG */ pred[v * sizeOfU + (nbPred[v]++)] = u; succ[u * sizeOfV + (nbSucc[u]++)] = v; if (markedV[v] == white) { /* first time v is added to the DAG*/ markedV[v] = grey; listV[nbV++] = v; } } } stop = 0; while ((stop == 0) && (nbV > 0)) { /* build next layer from nodes of V to nodes of U */ nbU = 0; for (i = 0; i < nbV; i++) { v = listV[i]; markedV[v] = black; u = matchedWithV[v]; if (markedU[u] == white) { /* edge (v, u) belongs to the DAG */ markedU[u] = grey; listU[nbU++] = u; } } /* build next layer from nodes of U to nodes of V */ nbV = 0; for (j = 0; j < nbU; j++) { u = listU[j]; markedU[u] = black; for (i = VECTOR(*firstAdj)[u]; i < VECTOR(*firstAdj)[u] + VECTOR(*degree)[u]; i++) { v = VECTOR(*adj)[i]; if (markedV[v] != black) { /* add edge (u, v) to the DAG */ pred[v * sizeOfU + (nbPred[v]++)] = u; succ[u * sizeOfV + (nbSucc[u]++)] = v; if (markedV[v] == white) { /* first time v is added to the DAG */ markedV[v] = grey; listV[nbV++] = v; } if (matchedWithV[v] == -1) { /* we have found a free node ! */ stop = 1; } } } } } if (nbV == 0) { *invalid = 1; /* I know it's ugly. */ goto cleanup; } /* step 2: look for augmenting paths */ for (k = 0; k < nbV; k++) { v = listV[k]; if ((matchedWithV[v] == -1) && (nbPred[v] > 0)) { /* v is the final node of an augmenting path */ IGRAPH_CHECK(igraph_vector_int_resize(&path, 1)); VECTOR(path)[0] = v; nbDV = 0; nbDU = 0; igraph_i_lad_addToDelete(v, listDV, &nbDV, markedV); do { u = pred[v * sizeOfU + 0]; /* (u, v) belongs to the augmenting path */ IGRAPH_CHECK(igraph_vector_int_push_back(&path, u)); igraph_i_lad_addToDelete(u, listDU, &nbDU, markedU); if (VECTOR(*matchedWithU)[u] != -1) { /* u is not the initial node of the augmenting path */ v = VECTOR(*matchedWithU)[u]; /* (v, u) belongs to the augmenting path */ IGRAPH_CHECK(igraph_vector_int_push_back(&path, v)); igraph_i_lad_addToDelete(v, listDV, &nbDV, markedV); } } while (VECTOR(*matchedWithU)[u] != -1); /* delete nodes of listDV and listDU */ while ((nbDV > 0) || (nbDU > 0)) { while (nbDV > 0) { /* delete v */ v = listDV[--nbDV]; markedV[v] = deleted; u = matchedWithV[v]; if (u != -1) { igraph_i_lad_addToDelete(u, listDU, &nbDU, markedU); } for (i = 0; i < nbPred[v]; i++) { u = pred[v * sizeOfU + i]; /* delete edge (u, v) */ for (j = 0; ((j < nbSucc[u]) && (v != succ[u * sizeOfV + j])); j++) { } succ[u * sizeOfV + j] = succ[u * sizeOfV + (--nbSucc[u])]; if (nbSucc[u] == 0) { igraph_i_lad_addToDelete(u, listDU, &nbDU, markedU); } } } while (nbDU > 0) { /* delete u */ u = listDU[--nbDU]; markedU[u] = deleted; v = VECTOR(*matchedWithU)[u]; if (v != -1) { igraph_i_lad_addToDelete(v, listDV, &nbDV, markedV); } j = 0; for (i = 0; i < nbSucc[u]; i++) { /* delete edge (u, v) */ v = succ[u * sizeOfV + i]; for (j = 0; ((j < nbPred[v]) && (u != pred[v * sizeOfU + j])); j++) { } pred[v * sizeOfU + j] = pred[v * sizeOfU + (--nbPred[v])]; if (nbPred[v] == 0) { igraph_i_lad_addToDelete(v, listDV, &nbDV, markedV); } } } } /* Remove the last node of the augmenting path from the set of unmatched vertices */ u = VECTOR(path)[igraph_vector_int_size(&path) - 1]; i = posInUnmatched[u]; unmatched[i] = unmatched[--nbUnmatched]; posInUnmatched[unmatched[i]] = i; /* Update the matching wrt the augmenting path */ while (igraph_vector_int_size(&path) > 1) { u = igraph_vector_int_pop_back(&path); v = igraph_vector_int_pop_back(&path); VECTOR(*matchedWithU)[u] = v; matchedWithV[v] = u; } } } } *invalid = 0; cleanup: /* Free the allocated arrays */ igraph_vector_int_destroy(&path); igraph_free(posInUnmatched); igraph_free(unmatched); igraph_free(markedU); igraph_free(markedV); igraph_free(listDU); igraph_free(listDV); igraph_free(listU); igraph_free(listV); igraph_free(succ); igraph_free(nbSucc); igraph_free(pred); igraph_free(nbPred); igraph_free(matchedWithV); IGRAPH_FINALLY_CLEAN(14); return 0; } static void igraph_i_lad_DFS(int nbU, int nbV, int u, bool* marked, int* nbSucc, int* succ, igraph_vector_int_t * matchedWithU, int* order, int* nb) { /* perform a depth first search, starting from u, in the bipartite graph Go=(U, V, E) such that U = vertices of Gp V = vertices of Gt E = { (u, matchedWithU[u]) / u is a vertex of Gp } U { (v, u) / v is a vertex of D[u] which is not matched to v} Given a vertex v of Gt, nbSucc[v]=number of successors of v and succ[v]=list of successors of v. order[nb^out+1..nb^in] contains the vertices discovered by the DFS */ int i; int v = VECTOR(*matchedWithU)[u]; /* the only one predecessor of v is u */ marked[u] = true; if (v >= 0) { for (i = 0; i < nbSucc[v]; i++) { if (!marked[succ[v * nbU + i]]) { igraph_i_lad_DFS(nbU, nbV, succ[v * nbU + i], marked, nbSucc, succ, matchedWithU, order, nb); } } } /* we have finished with u => number it */ order[*nb] = u; (*nb)--; } static int igraph_i_lad_SCC(int nbU, int nbV, int* numV, int* numU, int* nbSucc, int* succ, int* nbPred, int* pred, igraph_vector_int_t * matchedWithU, igraph_vector_int_t * matchedWithV) { /* postrelation: numV[v]==numU[u] iff they belong to the same strongly connected component in the bipartite graph Go=(U, V, E) such that U = vertices of Gp V = vertices of Gt E = { (u, matchedWithU[u]) / u is a vertex of Gp } U { (v, u) / v is a vertex of D[u] which is not matched to v} Given a vertex v of Gt, nbSucc[v]=number of sucessors of v and succ[v]=list of successors of v */ int *order; bool *marked; int *fifo; int u, v, i, j, k, nbSCC, nb; /* Allocate memory */ ALLOC_ARRAY(order, nbU, int); ALLOC_ARRAY(marked, nbU, bool); ALLOC_ARRAY(fifo, nbV, int); /* Order vertices of Gp wrt DFS */ nb = nbU - 1; for (u = 0; u < nbU; u++) { if (!marked[u]) { igraph_i_lad_DFS(nbU, nbV, u, marked, nbSucc, succ, matchedWithU, order, &nb); } } /* traversal starting from order[0], then order[1], ... */ nbSCC = 0; memset(numU, -1, (size_t) nbU * sizeof(int)); memset(numV, -1, (size_t) nbV * sizeof(int)); for (i = 0; i < nbU; i++) { u = order[i]; v = VECTOR(*matchedWithU)[u]; if (v == -1) { continue; } if (numV[v] == -1) { /* v belongs to a new SCC */ nbSCC++; k = 1; fifo[0] = v; numV[v] = nbSCC; while (k > 0) { v = fifo[--k]; u = VECTOR(*matchedWithV)[v]; if (u != -1) { numU[u] = nbSCC; for (j = 0; j < nbPred[u]; j++) { v = pred[u * nbV + j]; if (numV[v] == -1) { numV[v] = nbSCC; fifo[k++] = v; } } } } } } /* Free memory */ igraph_free(fifo); igraph_free(marked); igraph_free(order); IGRAPH_FINALLY_CLEAN(3); return 0; } static int igraph_i_lad_ensureGACallDiff(bool induced, Tgraph* Gp, Tgraph* Gt, Tdomain* D, int *invalid) { /* precondition: D->globalMatchingP is an all different matching of the pattern vertices postcondition: filter domains wrt GAC(allDiff) return false if an inconsistency is detected; true otherwise Build the bipartite directed graph Go=(U, V, E) such that E = { (u, v) / u is a vertex of Gp which is matched to v (i.e., v=D->globalMatchingP[u])} U { (v, u) / v is a vertex of Gt which is in D(u) but is not matched to u} */ int *nbPred; /* nbPred[u] = nb of predecessors of u in Go */ int *pred; /* pred[u][i] = ith predecessor of u in Go */ int *nbSucc; /* nbSucc[v] = nb of successors of v in Go */ int *succ; /* succ[v][i] = ith successor of v in Go */ int u, v, i, w, oldNbVal, nbToMatch; int *numV, *numU; igraph_vector_int_t toMatch; bool *used; int *list; int nb = 0; bool result; /* Allocate memory */ ALLOC_ARRAY(nbPred, Gp->nbVertices, int); ALLOC_ARRAY(pred, Gp->nbVertices * Gt->nbVertices, int); ALLOC_ARRAY(nbSucc, Gt->nbVertices, int); ALLOC_ARRAY(succ, Gt->nbVertices * Gp->nbVertices, int); ALLOC_ARRAY(numV, Gt->nbVertices, int); ALLOC_ARRAY(numU, Gp->nbVertices, int); ALLOC_ARRAY(used, Gp->nbVertices * Gt->nbVertices, bool); ALLOC_ARRAY(list, Gt->nbVertices, int); IGRAPH_CHECK(igraph_vector_int_init(&toMatch, Gp->nbVertices)); IGRAPH_FINALLY(igraph_vector_int_destroy, &toMatch); for (u = 0; u < Gp->nbVertices; u++) { for (i = 0; i < VECTOR(D->nbVal)[u]; i++) { v = VECTOR(D->val)[ VECTOR(D->firstVal)[u] + i ]; /* v in D(u) */ used[u * Gt->nbVertices + v] = false; if (v != VECTOR(D->globalMatchingP)[u]) { pred[u * Gt->nbVertices + (nbPred[u]++)] = v; succ[v * Gp->nbVertices + (nbSucc[v]++)] = u; } } } /* mark as used all edges of paths starting from free vertices */ for (v = 0; v < Gt->nbVertices; v++) { if (VECTOR(D->globalMatchingT)[v] < 0) { /* v is free */ list[nb++] = v; numV[v] = true; } } while (nb > 0) { v = list[--nb]; for (i = 0; i < nbSucc[v]; i++) { u = succ[v * Gp->nbVertices + i]; used[u * Gt->nbVertices + v] = true; if (numU[u] == false) { numU[u] = true; w = VECTOR(D->globalMatchingP)[u]; used[u * Gt->nbVertices + w] = true; if (numV[w] == false) { list[nb++] = w; numV[w] = true; } } } } /* look for strongly connected components in Go */ IGRAPH_CHECK( igraph_i_lad_SCC((int)(Gp->nbVertices), (int)(Gt->nbVertices), numV, numU, nbSucc, succ, nbPred, pred, &D->globalMatchingP, &D->globalMatchingT)); /* remove v from D[u] if (u, v) is not marked as used and u and v are not in the same SCC and D->globalMatchingP[u] != v */ nbToMatch = 0; for (u = 0; u < Gp->nbVertices; u++) { oldNbVal = VECTOR(D->nbVal)[u]; for (i = 0; i < VECTOR(D->nbVal)[u]; i++) { v = VECTOR(D->val)[ VECTOR(D->firstVal)[u] + i ]; /* v in D(u) */ if ((!used[u * Gt->nbVertices + v]) && (numV[v] != numU[u]) && (VECTOR(D->globalMatchingP)[u] != v)) { IGRAPH_CHECK(igraph_i_lad_removeValue(u, v, D, Gp, Gt, &result)); if (!result) { *invalid = 1; /* Yes, this is ugly. */ goto cleanup; } } } if (VECTOR(D->nbVal)[u] == 0) { *invalid = 1; /* Yes, this is ugly. */ goto cleanup; } if ((oldNbVal > 1) && (VECTOR(D->nbVal)[u] == 1)) { VECTOR(toMatch)[nbToMatch++] = u; } } IGRAPH_CHECK(igraph_i_lad_matchVertices(nbToMatch, &toMatch, induced, D, Gp, Gt, invalid)); cleanup: igraph_vector_int_destroy(&toMatch); igraph_free(list); igraph_free(used); igraph_free(numU); igraph_free(numV); igraph_free(succ); igraph_free(nbSucc); igraph_free(pred); igraph_free(nbPred); IGRAPH_FINALLY_CLEAN(9); return 0; } /* ---------------------------------------------------------*/ /* Coming from lad.c */ /* ---------------------------------------------------------*/ static int igraph_i_lad_checkLAD(int u, int v, Tdomain* D, Tgraph* Gp, Tgraph* Gt, bool *result) { /* return true if G_(u, v) has a adj(u)-covering matching; false otherwise */ int u2, v2, i, j; int nbMatched = 0; igraph_vector_int_t *Gp_uneis = igraph_adjlist_get(&Gp->succ, u); int *num, *numInv; igraph_vector_int_t nbComp; igraph_vector_int_t firstComp; igraph_vector_int_t comp; int nbNum = 0; int posInComp = 0; igraph_vector_int_t matchedWithU; int invalid; /* special case when u has only 1 adjacent node => no need to call Hopcroft and Karp */ if (VECTOR(Gp->nbSucc)[u] == 1) { u2 = (int) VECTOR(*Gp_uneis)[0]; /* u2 is the only node adjacent to u */ v2 = VECTOR(D->matching)[ MATRIX(D->firstMatch, u, v) ]; if ((v2 != -1) && (igraph_i_lad_isInD(u2, v2, D))) { *result = true; return 0; } /* look for a support of edge (u, u2) for v */ for (i = VECTOR(D->firstVal)[u2]; i < VECTOR(D->firstVal)[u2] + VECTOR(D->nbVal)[u2]; i++) { if (MATRIX(Gt->isEdge, v, VECTOR(D->val)[i])) { VECTOR(D->matching)[ MATRIX(D->firstMatch, u, v) ] = VECTOR(D->val)[i]; *result = true; return 0; } } *result = false; return 0; } /* general case (when u has more than 1 adjacent node) */ for (i = 0; i < VECTOR(Gp->nbSucc)[u]; i++) { /* remove from the matching of G_(u, v) edges which no longer belong to G_(u, v) */ u2 = (int) VECTOR(*Gp_uneis)[i]; v2 = VECTOR(D->matching)[ MATRIX(D->firstMatch, u, v) + i]; if ((v2 != -1) && (igraph_i_lad_isInD(u2, v2, D))) { nbMatched++; } } if (nbMatched == VECTOR(Gp->nbSucc)[u]) { *result = true; return 0; } /* The matching still covers adj(u) */ /* Allocate memory */ ALLOC_ARRAY(num, Gt->nbVertices, int); ALLOC_ARRAY(numInv, Gt->nbVertices, int); /* Build the bipartite graph let U be the set of nodes adjacent to u let V be the set of nodes that are adjacent to v, and that belong to domains of nodes of U */ /* nbComp[u]=number of elements of V that are compatible with u */ IGRAPH_CHECK(igraph_vector_int_init(&nbComp, (long int) VECTOR(Gp->nbSucc)[u])); IGRAPH_FINALLY(igraph_vector_int_destroy, &nbComp); IGRAPH_CHECK(igraph_vector_int_init(&firstComp, (long int) VECTOR(Gp->nbSucc)[u])); IGRAPH_FINALLY(igraph_vector_int_destroy, &firstComp); /* comp[firstComp[u]..firstComp[u]+nbComp[u]-1] = nodes of Gt that are compatible with u */ IGRAPH_CHECK(igraph_vector_int_init(&comp, (long int) (VECTOR(Gp->nbSucc)[u] * Gt->nbVertices))); IGRAPH_FINALLY(igraph_vector_int_destroy, &comp); IGRAPH_CHECK(igraph_vector_int_init(&matchedWithU, (long int) VECTOR(Gp->nbSucc)[u])); IGRAPH_FINALLY(igraph_vector_int_destroy, &matchedWithU); memset(num, -1, (size_t) (Gt->nbVertices) * sizeof(int)); for (i = 0; i < VECTOR(Gp->nbSucc)[u]; i++) { u2 = (int) VECTOR(*Gp_uneis)[i]; /* u2 is adjacent to u */ /* search for all nodes v2 in D[u2] which are adjacent to v */ VECTOR(nbComp)[i] = 0; VECTOR(firstComp)[i] = posInComp; if (VECTOR(D->nbVal)[u2] > VECTOR(Gt->nbSucc)[v]) { for (j = VECTOR(D->firstVal)[u2]; j < VECTOR(D->firstVal)[u2] + VECTOR(D->nbVal)[u2]; j++) { v2 = VECTOR(D->val)[j]; /* v2 belongs to D[u2] */ if (MATRIX(Gt->isEdge, v, v2)) { /* v2 is a successor of v */ if (num[v2] < 0) { /* v2 has not yet been added to V */ num[v2] = nbNum; numInv[nbNum++] = v2; } VECTOR(comp)[posInComp++] = num[v2]; VECTOR(nbComp)[i]++; } } } else { igraph_vector_int_t *Gt_vneis = igraph_adjlist_get(&Gt->succ, v); for (j = 0; j < VECTOR(Gt->nbSucc)[v]; j++) { v2 = (int) VECTOR(*Gt_vneis)[j]; /* v2 is a successor of v */ if (igraph_i_lad_isInD(u2, v2, D)) { /* v2 belongs to D[u2] */ if (num[v2] < 0) { /* v2 has not yet been added to V */ num[v2] = nbNum; numInv[nbNum++] = v2; } VECTOR(comp)[posInComp++] = num[v2]; VECTOR(nbComp)[i]++; } } } if (VECTOR(nbComp)[i] == 0) { *result = false; /* u2 has no compatible vertex in succ[v] */ goto cleanup; } /* u2 is matched to v2 in the matching that supports (u, v) */ v2 = VECTOR(D->matching)[ MATRIX(D->firstMatch, u, v) + i]; if ((v2 != -1) && (igraph_i_lad_isInD(u2, v2, D))) { VECTOR(matchedWithU)[i] = num[v2]; } else { VECTOR(matchedWithU)[i] = -1; } } /* Call Hopcroft Karp to update the matching */ IGRAPH_CHECK( igraph_i_lad_updateMatching((int) VECTOR(Gp->nbSucc)[u], nbNum, &nbComp, &firstComp, &comp, &matchedWithU, &invalid) ); if (invalid) { *result = false; goto cleanup; } for (i = 0; i < VECTOR(Gp->nbSucc)[u]; i++) { VECTOR(D->matching)[ MATRIX(D->firstMatch, u, v) + i] = numInv[ VECTOR(matchedWithU)[i] ]; } *result = true; cleanup: igraph_free(numInv); igraph_free(num); igraph_vector_int_destroy(&matchedWithU); igraph_vector_int_destroy(&comp); igraph_vector_int_destroy(&firstComp); igraph_vector_int_destroy(&nbComp); IGRAPH_FINALLY_CLEAN(6); return 0; } /* ---------------------------------------------------------*/ /* Coming from main.c */ /* ---------------------------------------------------------*/ static int igraph_i_lad_filter(bool induced, Tdomain* D, Tgraph* Gp, Tgraph* Gt, bool *result) { /* filter domains of all vertices in D->toFilter wrt LAD and ensure GAC(allDiff) return false if some domain becomes empty; true otherwise */ int u, v, i, oldNbVal; int invalid; bool result2; while (!igraph_i_lad_toFilterEmpty(D)) { while (!igraph_i_lad_toFilterEmpty(D)) { u = igraph_i_lad_nextToFilter(D, (int) (Gp->nbVertices)); oldNbVal = VECTOR(D->nbVal)[u]; i = VECTOR(D->firstVal)[u]; while (i < VECTOR(D->firstVal)[u] + VECTOR(D->nbVal)[u]) { /* for every target node v in D(u), check if G_(u, v) has a covering matching */ v = VECTOR(D->val)[i]; IGRAPH_CHECK(igraph_i_lad_checkLAD(u, v, D, Gp, Gt, &result2)); if (result2) { i++; } else { IGRAPH_CHECK(igraph_i_lad_removeValue(u, v, D, Gp, Gt, &result2)); if (!result2) { *result = false; return 0; } } } if ((VECTOR(D->nbVal)[u] == 1) && (oldNbVal > 1) && (!igraph_i_lad_matchVertex(u, induced, D, Gp, Gt))) { *result = false; return 0; } if (VECTOR(D->nbVal)[u] == 0) { *result = false; return 0; } } igraph_i_lad_ensureGACallDiff(induced, Gp, Gt, D, &invalid); if (invalid) { *result = false; return 0; } } *result = true; return 0; } static int igraph_i_lad_solve(int timeLimit, bool firstSol, bool induced, Tdomain* D, Tgraph* Gp, Tgraph* Gt, int *invalid, igraph_bool_t *iso, igraph_vector_t *map, igraph_vector_ptr_t *maps, int *nbNodes, int *nbFail, int *nbSol, clock_t *begin, igraph_vector_ptr_t *alloc_history) { /* if firstSol then search for the first solution; otherwise search for all solutions if induced then search for induced subgraphs; otherwise search for partial subgraphs return false if CPU time limit exceeded before the search is completed, return true otherwise */ int u, v, minDom, i; int* nbVal; int* globalMatching; clock_t end = clock(); igraph_vector_t *vec; int* val; bool result; (*nbNodes)++; if ( (double)(end - *begin) / CLOCKS_PER_SEC >= timeLimit) { /* CPU time limit exceeded */ IGRAPH_ERROR("LAD CPU time exceeded", IGRAPH_CPUTIME); } /* Allocate memory */ ALLOC_ARRAY_IN_HISTORY(nbVal, Gp->nbVertices, int, alloc_history); ALLOC_ARRAY_IN_HISTORY(globalMatching, Gp->nbVertices, int, alloc_history); IGRAPH_CHECK(igraph_i_lad_filter(induced, D, Gp, Gt, &result)); if (!result) { /* filtering has detected an inconsistency */ (*nbFail)++; igraph_i_lad_resetToFilter(D); *invalid = 0; goto cleanup; } /* The current node of the search tree is consistent wrt to LAD and GAC(allDiff) Save domain sizes and global all different matching and search for the non matched vertex minDom with smallest domain */ minDom = -1; for (u = 0; u < Gp->nbVertices; u++) { nbVal[u] = VECTOR(D->nbVal)[u]; if ((nbVal[u] > 1) && ((minDom < 0) || (nbVal[u] < nbVal[minDom]))) { minDom = u; } globalMatching[u] = VECTOR(D->globalMatchingP)[u]; } if (minDom == -1) { /* All vertices are matched => Solution found */ if (iso) { *iso = 1; } (*nbSol)++; if (map && igraph_vector_size(map) == 0) { IGRAPH_CHECK(igraph_vector_resize(map, Gp->nbVertices)); for (u = 0; u < Gp->nbVertices; u++) { VECTOR(*map)[u] = VECTOR(D->val)[ VECTOR(D->firstVal)[u] ]; } } if (maps) { vec = IGRAPH_CALLOC(1, igraph_vector_t); if (!vec) { IGRAPH_ERROR("LAD failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, vec); IGRAPH_CHECK(igraph_vector_init(vec, Gp->nbVertices)); IGRAPH_FINALLY(igraph_vector_destroy, vec); for (u = 0; u < Gp->nbVertices; u++) { VECTOR(*vec)[u] = VECTOR(D->val)[ VECTOR(D->firstVal)[u] ]; } IGRAPH_CHECK(igraph_vector_ptr_push_back(maps, vec)); IGRAPH_FINALLY_CLEAN(2); } igraph_i_lad_resetToFilter(D); *invalid = 0; goto cleanup; } /* save the domain of minDom to iterate on its values */ ALLOC_ARRAY_IN_HISTORY(val, VECTOR(D->nbVal)[minDom], int, alloc_history); for (i = 0; i < VECTOR(D->nbVal)[minDom]; i++) { val[i] = VECTOR(D->val)[ VECTOR(D->firstVal)[minDom] + i ]; } /* branch on minDom=v, for every target node v in D(u) */ for (i = 0; ((i < nbVal[minDom]) && ((firstSol == 0) || (*nbSol == 0))); i++) { IGRAPH_ALLOW_INTERRUPTION(); v = val[i]; IGRAPH_CHECK(igraph_i_lad_removeAllValuesButOne(minDom, v, D, Gp, Gt, &result)); if (!result || (!igraph_i_lad_matchVertex(minDom, induced, D, Gp, Gt))) { (*nbFail)++; (*nbNodes)++; igraph_i_lad_resetToFilter(D); } else { IGRAPH_CHECK(igraph_i_lad_solve(timeLimit, firstSol, induced, D, Gp, Gt, invalid, iso, map, maps, nbNodes, nbFail, nbSol, begin, alloc_history)); } /* restore domain sizes and global all different matching */ igraph_vector_int_fill(&D->globalMatchingT, -1); for (u = 0; u < Gp->nbVertices; u++) { VECTOR(D->nbVal)[u] = nbVal[u]; VECTOR(D->globalMatchingP)[u] = globalMatching[u]; VECTOR(D->globalMatchingT)[globalMatching[u]] = u; } } *invalid = 0; igraph_free(val); igraph_vector_ptr_pop_back(alloc_history); cleanup: igraph_free(globalMatching); igraph_vector_ptr_pop_back(alloc_history); igraph_free(nbVal); igraph_vector_ptr_pop_back(alloc_history); return 0; } /** * \section about_lad * * * The LAD algorithm can search for a subgraph in a larger graph, or check * if two graphs are isomorphic. * See Christine Solnon: AllDifferent-based Filtering for Subgraph * Isomorphism. Artificial Intelligence, 174(12-13):850-864, 2010. * https://doi.org/10.1016/j.artint.2010.05.002 * as well as the homepage of the LAD library at http://liris.cnrs.fr/csolnon/LAD.html * The implementation in igraph is based on LADv1, but it is * modified to use igraph's own memory allocation and error handling. * * * * LAD uses the concept of domains to indicate vertex compatibility when matching the * pattern graph. Domains can be used to implement matching of colored vertices. * * * * LAD works with both directed and undirected graphs. Graphs with multi-edges are not supported. * */ /** * \function igraph_subisomorphic_lad * Check subgraph isomorphism with the LAD algorithm * * Check whether \p pattern is isomorphic to a subgraph os \p target. * The original LAD implementation by Christine Solnon was used as the * basis of this code. * * * See more about LAD at http://liris.cnrs.fr/csolnon/LAD.html and in * Christine Solnon: AllDifferent-based Filtering for Subgraph * Isomorphism. Artificial Intelligence, 174(12-13):850-864, 2010. * https://doi.org/10.1016/j.artint.2010.05.002 * * \param pattern The smaller graph, it can be directed or undirected. * \param target The bigger graph, it can be directed or undirected. * \param domains A pointer vector, or a null pointer. If a pointer * vector, then it must contain pointers to \c igraph_vector_t * objects and the length of the vector must match the number of * vertices in the \p pattern graph. For each vertex, the ids of * the compatible vertices in the target graph are listed. * \param iso Pointer to a boolean, or a null pointer. If not a null * pointer, then the boolean is set to TRUE (1) if a subgraph * isomorphism is found, and to FALSE (0) otherwise. * \param map Pointer to a vector or a null pointer. If not a null * pointer and a subgraph isomorphism is found, the matching * vertices from the target graph are listed here, for each vertex * (in vertex id order) from the pattern graph. * \param maps Pointer vector or a null pointer. If not a null * pointer, then all subgraph isomorphisms are stored in the * pointer vector, in \c igraph_vector_t objects. * \param induced Boolean, whether to search for induced matching * subgraphs. * \param time_limit Processor time limit in seconds. Supply zero * here for no limit. If the time limit is over, then the function * signals an error. * \return Error code * * \sa \ref igraph_subisomorphic_vf2() for the VF2 algorithm. * * Time complexity: exponential. * * \example examples/simple/igraph_subisomorphic_lad.c */ int igraph_subisomorphic_lad(const igraph_t *pattern, const igraph_t *target, const igraph_vector_ptr_t *domains, igraph_bool_t *iso, igraph_vector_t *map, igraph_vector_ptr_t *maps, igraph_bool_t induced, int time_limit) { bool firstSol = maps == 0; bool initialDomains = domains != 0; Tgraph Gp, Gt; Tdomain D; int invalidDomain; int u, nbToMatch = 0; igraph_vector_int_t toMatch; /* Number of nodes in the search tree */ int nbNodes = 0; /* number of failed nodes in the search tree */ int nbFail = 0; /* number of solutions found */ int nbSol = 0; /* reusable structure to get CPU time usage */ clock_t begin = clock(); /* Stack to store memory blocks that are allocated during igraph_i_lad_solve */ igraph_vector_ptr_t alloc_history; if (!iso && !map && !maps) { IGRAPH_ERROR("Please give least one of `iso', `map' or `maps'", IGRAPH_EINVAL); } if (igraph_is_directed(pattern) != igraph_is_directed(target)) { IGRAPH_ERROR("Cannot search for a directed pattern in an undirected target " "or vice versa", IGRAPH_EINVAL); } if (time_limit <= 0) { time_limit = INT_MAX; } if (iso) { *iso = (igraph_vcount(pattern) == 0); } if (map) { igraph_vector_clear(map); } if (maps) { igraph_vector_ptr_clear(maps); } if (igraph_vcount(pattern) == 0) { /* Special case for empty graphs */ return IGRAPH_SUCCESS; } IGRAPH_CHECK(igraph_i_lad_createGraph(pattern, &Gp)); IGRAPH_FINALLY(igraph_i_lad_destroyGraph, &Gp); IGRAPH_CHECK(igraph_i_lad_createGraph(target, &Gt)); IGRAPH_FINALLY(igraph_i_lad_destroyGraph, &Gt); if (Gp.nbVertices > Gt.nbVertices) { goto exit3; } IGRAPH_CHECK(igraph_i_lad_initDomains(initialDomains, domains, &D, &Gp, &Gt, &invalidDomain)); IGRAPH_FINALLY(igraph_i_lad_destroyDomains, &D); if (invalidDomain) { goto exit2; } IGRAPH_CHECK(igraph_i_lad_updateMatching((int) (Gp.nbVertices), (int) (Gt.nbVertices), &D.nbVal, &D.firstVal, &D.val, &D.globalMatchingP, &invalidDomain)); if (invalidDomain) { goto exit; } IGRAPH_CHECK(igraph_i_lad_ensureGACallDiff((char) induced, &Gp, &Gt, &D, &invalidDomain)); if (invalidDomain) { goto exit; } for (u = 0; u < Gp.nbVertices; u++) { VECTOR(D.globalMatchingT)[ VECTOR(D.globalMatchingP)[u] ] = u; } IGRAPH_CHECK(igraph_vector_int_init(&toMatch, Gp.nbVertices)); IGRAPH_FINALLY(igraph_vector_int_destroy, &toMatch); for (u = 0; u < Gp.nbVertices; u++) { if (VECTOR(D.nbVal)[u] == 1) { VECTOR(toMatch)[nbToMatch++] = u; } } IGRAPH_CHECK(igraph_i_lad_matchVertices(nbToMatch, &toMatch, (char) induced, &D, &Gp, &Gt, &invalidDomain)); igraph_vector_int_destroy(&toMatch); IGRAPH_FINALLY_CLEAN(1); if (invalidDomain) { goto exit; } IGRAPH_CHECK(igraph_vector_ptr_init(&alloc_history, 0)); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &alloc_history); IGRAPH_CHECK(igraph_i_lad_solve(time_limit, firstSol, (char) induced, &D, &Gp, &Gt, &invalidDomain, iso, map, maps, &nbNodes, &nbFail, &nbSol, &begin, &alloc_history)); igraph_vector_ptr_destroy_all(&alloc_history); IGRAPH_FINALLY_CLEAN(1); exit: exit2: igraph_i_lad_destroyDomains(&D); IGRAPH_FINALLY_CLEAN(1); exit3: igraph_i_lad_destroyGraph(&Gt); igraph_i_lad_destroyGraph(&Gp); IGRAPH_FINALLY_CLEAN(2); return 0; } leidenbase/src/core/isomorphism/vf2.c0000644000176200001440000022536114447675374017334 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_topology.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_stack.h" #include "core/interruption.h" /** * \section about_vf2 * * * The VF2 algorithm can search for a subgraph in a larger graph, or check if two * graphs are isomorphic. See P. Foggia, C. Sansone, M. Vento, An Improved algorithm for * matching large graphs, Proc. of the 3rd IAPR-TC-15 International * Workshop on Graph-based Representations, Italy, 2001. * * * * VF2 supports both vertex and edge-colored graphs, as well as custom vertex or edge * compatibility functions. * * * * VF2 works with both directed and undirected graphs. Only simple graphs are supported. * Self-loops or multi-edges must not be present in the graphs. Currently, the VF2 * functions do not check that the input graph is simple: it is the responsibility * of the user to pass in valid input. * */ /** * \function igraph_isomorphic_function_vf2 * The generic VF2 interface * * * This function is an implementation of the VF2 isomorphism algorithm, * see P. Foggia, C. Sansone, M. Vento, An Improved algorithm for * matching large graphs, Proc. of the 3rd IAPR-TC-15 International * Workshop on Graph-based Representations, Italy, 2001. * * For using it you need to define a callback function of type * \ref igraph_isohandler_t. This function will be called whenever VF2 * finds an isomorphism between the two graphs. The mapping between * the two graphs will be also provided to this function. If the * callback returns a nonzero value then the search is continued, * otherwise it stops. The callback function must not destroy the * mapping vectors that are passed to it. * \param graph1 The first input graph. * \param graph2 The second input graph. * \param vertex_color1 An optional color vector for the first graph. If * color vectors are given for both graphs, then the isomorphism is * calculated on the colored graphs; i.e. two vertices can match * only if their color also matches. Supply a null pointer here if * your graphs are not colored. * \param vertex_color2 An optional color vector for the second graph. See * the previous argument for explanation. * \param edge_color1 An optional edge color vector for the first * graph. The matching edges in the two graphs must have matching * colors as well. Supply a null pointer here if your graphs are not * edge-colored. * \param edge_color2 The edge color vector for the second graph. * \param map12 Pointer to an initialized vector or \c NULL. If not \c * NULL and the supplied graphs are isomorphic then the permutation * taking \p graph1 to \p graph is stored here. If not \c NULL and the * graphs are not isomorphic then a zero-length vector is returned. * \param map21 This is the same as \p map12, but for the permutation * taking \p graph2 to \p graph1. * \param isohandler_fn The callback function to be called if an * isomorphism is found. See also \ref igraph_isohandler_t. * \param node_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two nodes are compatible. * \param edge_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two edges are compatible. * \param arg Extra argument to supply to functions \p isohandler_fn, \p * node_compat_fn and \p edge_compat_fn. * \return Error code. * * Time complexity: exponential. */ int igraph_isomorphic_function_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_vector_t *map12, igraph_vector_t *map21, igraph_isohandler_t *isohandler_fn, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg) { long int no_of_nodes = igraph_vcount(graph1); long int no_of_edges = igraph_ecount(graph1); igraph_vector_t mycore_1, mycore_2, *core_1 = &mycore_1, *core_2 = &mycore_2; igraph_vector_t in_1, in_2, out_1, out_2; long int in_1_size = 0, in_2_size = 0, out_1_size = 0, out_2_size = 0; igraph_vector_int_t *inneis_1, *inneis_2, *outneis_1, *outneis_2; long int matched_nodes = 0; long int depth; long int cand1, cand2; long int last1, last2; igraph_stack_t path; igraph_lazy_adjlist_t inadj1, inadj2, outadj1, outadj2; igraph_vector_t indeg1, indeg2, outdeg1, outdeg2; long int vsize; if (igraph_is_directed(graph1) != igraph_is_directed(graph2)) { IGRAPH_ERROR("Cannot compare directed and undirected graphs", IGRAPH_EINVAL); } if ( (vertex_color1 && !vertex_color2) || (!vertex_color1 && vertex_color2) ) { IGRAPH_WARNING("Only one graph is vertex-colored, vertex colors will be ignored"); vertex_color1 = vertex_color2 = 0; } if ( (edge_color1 && !edge_color2) || (!edge_color1 && edge_color2)) { IGRAPH_WARNING("Only one graph is edge-colored, edge colors will be ignored"); edge_color1 = edge_color2 = 0; } if (no_of_nodes != igraph_vcount(graph2) || no_of_edges != igraph_ecount(graph2)) { return 0; } if (vertex_color1) { if (igraph_vector_int_size(vertex_color1) != no_of_nodes || igraph_vector_int_size(vertex_color2) != no_of_nodes) { IGRAPH_ERROR("Invalid vertex color vector length", IGRAPH_EINVAL); } } if (edge_color1) { if (igraph_vector_int_size(edge_color1) != no_of_edges || igraph_vector_int_size(edge_color2) != no_of_edges) { IGRAPH_ERROR("Invalid edge color vector length", IGRAPH_EINVAL); } } /* Check color distribution */ if (vertex_color1) { int ret = 0; igraph_vector_int_t tmp1, tmp2; IGRAPH_CHECK(igraph_vector_int_copy(&tmp1, vertex_color1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &tmp1); IGRAPH_CHECK(igraph_vector_int_copy(&tmp2, vertex_color2)); IGRAPH_FINALLY(igraph_vector_int_destroy, &tmp2); igraph_vector_int_sort(&tmp1); igraph_vector_int_sort(&tmp2); ret = !igraph_vector_int_all_e(&tmp1, &tmp2); igraph_vector_int_destroy(&tmp1); igraph_vector_int_destroy(&tmp2); IGRAPH_FINALLY_CLEAN(2); if (ret) { return 0; } } /* Check edge color distribution */ if (edge_color1) { int ret = 0; igraph_vector_int_t tmp1, tmp2; IGRAPH_CHECK(igraph_vector_int_copy(&tmp1, edge_color1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &tmp1); IGRAPH_CHECK(igraph_vector_int_copy(&tmp2, edge_color2)); IGRAPH_FINALLY(igraph_vector_int_destroy, &tmp2); igraph_vector_int_sort(&tmp1); igraph_vector_int_sort(&tmp2); ret = !igraph_vector_int_all_e(&tmp1, &tmp2); igraph_vector_int_destroy(&tmp1); igraph_vector_int_destroy(&tmp2); IGRAPH_FINALLY_CLEAN(2); if (ret) { return 0; } } if (map12) { core_1 = map12; IGRAPH_CHECK(igraph_vector_resize(core_1, no_of_nodes)); } else { IGRAPH_VECTOR_INIT_FINALLY(core_1, no_of_nodes); } igraph_vector_fill(core_1, -1); if (map21) { core_2 = map21; IGRAPH_CHECK(igraph_vector_resize(core_2, no_of_nodes)); igraph_vector_null(core_2); } else { IGRAPH_VECTOR_INIT_FINALLY(core_2, no_of_nodes); } igraph_vector_fill(core_2, -1); IGRAPH_VECTOR_INIT_FINALLY(&in_1, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&in_2, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&out_1, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&out_2, no_of_nodes); IGRAPH_CHECK(igraph_stack_init(&path, 0)); IGRAPH_FINALLY(igraph_stack_destroy, &path); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph1, &inadj1, IGRAPH_IN, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &inadj1); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph1, &outadj1, IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &outadj1); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph2, &inadj2, IGRAPH_IN, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &inadj2); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph2, &outadj2, IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &outadj2); IGRAPH_VECTOR_INIT_FINALLY(&indeg1, 0); IGRAPH_VECTOR_INIT_FINALLY(&indeg2, 0); IGRAPH_VECTOR_INIT_FINALLY(&outdeg1, 0); IGRAPH_VECTOR_INIT_FINALLY(&outdeg2, 0); IGRAPH_CHECK(igraph_stack_reserve(&path, no_of_nodes * 2)); IGRAPH_CHECK(igraph_degree(graph1, &indeg1, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_degree(graph2, &indeg2, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_degree(graph1, &outdeg1, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_degree(graph2, &outdeg2, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); depth = 0; last1 = -1; last2 = -1; while (depth >= 0) { long int i; IGRAPH_ALLOW_INTERRUPTION(); cand1 = -1; cand2 = -1; /* Search for the next pair to try */ if ((in_1_size != in_2_size) || (out_1_size != out_2_size)) { /* step back, nothing to do */ } else if (out_1_size > 0 && out_2_size > 0) { /**************************************************************/ /* cand2, search not always needed */ if (last2 >= 0) { cand2 = last2; } else { i = 0; while (cand2 < 0 && i < no_of_nodes) { if (VECTOR(out_2)[i] > 0 && VECTOR(*core_2)[i] < 0) { cand2 = i; } i++; } } /* search for cand1 now, it should be bigger than last1 */ i = last1 + 1; while (cand1 < 0 && i < no_of_nodes) { if (VECTOR(out_1)[i] > 0 && VECTOR(*core_1)[i] < 0) { cand1 = i; } i++; } } else if (in_1_size > 0 && in_2_size > 0) { /**************************************************************/ /* cand2, search not always needed */ if (last2 >= 0) { cand2 = last2; } else { i = 0; while (cand2 < 0 && i < no_of_nodes) { if (VECTOR(in_2)[i] > 0 && VECTOR(*core_2)[i] < 0) { cand2 = i; } i++; } } /* search for cand1 now, should be bigger than last1 */ i = last1 + 1; while (cand1 < 0 && i < no_of_nodes) { if (VECTOR(in_1)[i] > 0 && VECTOR(*core_1)[i] < 0) { cand1 = i; } i++; } } else { /**************************************************************/ /* cand2, search not always needed */ if (last2 >= 0) { cand2 = last2; } else { i = 0; while (cand2 < 0 && i < no_of_nodes) { if (VECTOR(*core_2)[i] < 0) { cand2 = i; } i++; } } /* search for cand1, should be bigger than last1 */ i = last1 + 1; while (cand1 < 0 && i < no_of_nodes) { if (VECTOR(*core_1)[i] < 0) { cand1 = i; } i++; } } /* Ok, we have cand1, cand2 as candidates. Or not? */ if (cand1 < 0 || cand2 < 0) { /**************************************************************/ /* dead end, step back, if possible. Otherwise we'll terminate */ if (depth >= 1) { last2 = (long int) igraph_stack_pop(&path); last1 = (long int) igraph_stack_pop(&path); matched_nodes -= 1; VECTOR(*core_1)[last1] = -1; VECTOR(*core_2)[last2] = -1; if (VECTOR(in_1)[last1] != 0) { in_1_size += 1; } if (VECTOR(out_1)[last1] != 0) { out_1_size += 1; } if (VECTOR(in_2)[last2] != 0) { in_2_size += 1; } if (VECTOR(out_2)[last2] != 0) { out_2_size += 1; } inneis_1 = igraph_lazy_adjlist_get(&inadj1, (igraph_integer_t) last1); vsize = igraph_vector_int_size(inneis_1); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*inneis_1)[i]; if (VECTOR(in_1)[node] == depth) { VECTOR(in_1)[node] = 0; in_1_size -= 1; } } outneis_1 = igraph_lazy_adjlist_get(&outadj1, (igraph_integer_t) last1); vsize = igraph_vector_int_size(outneis_1); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*outneis_1)[i]; if (VECTOR(out_1)[node] == depth) { VECTOR(out_1)[node] = 0; out_1_size -= 1; } } inneis_2 = igraph_lazy_adjlist_get(&inadj2, (igraph_integer_t) last2); vsize = igraph_vector_int_size(inneis_2); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*inneis_2)[i]; if (VECTOR(in_2)[node] == depth) { VECTOR(in_2)[node] = 0; in_2_size -= 1; } } outneis_2 = igraph_lazy_adjlist_get(&outadj2, (igraph_integer_t) last2); vsize = igraph_vector_int_size(outneis_2); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*outneis_2)[i]; if (VECTOR(out_2)[node] == depth) { VECTOR(out_2)[node] = 0; out_2_size -= 1; } } } /* end of stepping back */ depth -= 1; } else { /**************************************************************/ /* step forward if worth, check if worth first */ long int xin1 = 0, xin2 = 0, xout1 = 0, xout2 = 0; igraph_bool_t end = 0; inneis_1 = igraph_lazy_adjlist_get(&inadj1, (igraph_integer_t) cand1); outneis_1 = igraph_lazy_adjlist_get(&outadj1, (igraph_integer_t) cand1); inneis_2 = igraph_lazy_adjlist_get(&inadj2, (igraph_integer_t) cand2); outneis_2 = igraph_lazy_adjlist_get(&outadj2, (igraph_integer_t) cand2); if (VECTOR(indeg1)[cand1] != VECTOR(indeg2)[cand2] || VECTOR(outdeg1)[cand1] != VECTOR(outdeg2)[cand2]) { end = 1; } if (vertex_color1 && VECTOR(*vertex_color1)[cand1] != VECTOR(*vertex_color2)[cand2]) { end = 1; } if (node_compat_fn && !node_compat_fn(graph1, graph2, (igraph_integer_t) cand1, (igraph_integer_t) cand2, arg)) { end = 1; } vsize = igraph_vector_int_size(inneis_1); for (i = 0; !end && i < vsize; i++) { long int node = (long int) VECTOR(*inneis_1)[i]; if (VECTOR(*core_1)[node] >= 0) { long int node2 = (long int) VECTOR(*core_1)[node]; /* check if there is a node2->cand2 edge */ if (!igraph_vector_int_binsearch2(inneis_2, node2)) { end = 1; } else if (edge_color1 || edge_compat_fn) { igraph_integer_t eid1, eid2; igraph_get_eid(graph1, &eid1, (igraph_integer_t) node, (igraph_integer_t) cand1, /*directed=*/ 1, /*error=*/ 1); igraph_get_eid(graph2, &eid2, (igraph_integer_t) node2, (igraph_integer_t) cand2, /*directed=*/ 1, /*error=*/ 1); if (edge_color1 && VECTOR(*edge_color1)[(long int)eid1] != VECTOR(*edge_color2)[(long int)eid2]) { end = 1; } if (edge_compat_fn && !edge_compat_fn(graph1, graph2, eid1, eid2, arg)) { end = 1; } } } else { if (VECTOR(in_1)[node] != 0) { xin1++; } if (VECTOR(out_1)[node] != 0) { xout1++; } } } vsize = igraph_vector_int_size(outneis_1); for (i = 0; !end && i < vsize; i++) { long int node = (long int) VECTOR(*outneis_1)[i]; if (VECTOR(*core_1)[node] >= 0) { long int node2 = (long int) VECTOR(*core_1)[node]; /* check if there is a cand2->node2 edge */ if (!igraph_vector_int_binsearch2(outneis_2, node2)) { end = 1; } else if (edge_color1 || edge_compat_fn) { igraph_integer_t eid1, eid2; igraph_get_eid(graph1, &eid1, (igraph_integer_t) cand1, (igraph_integer_t) node, /*directed=*/ 1, /*error=*/ 1); igraph_get_eid(graph2, &eid2, (igraph_integer_t) cand2, (igraph_integer_t) node2, /*directed=*/ 1, /*error=*/ 1); if (edge_color1 && VECTOR(*edge_color1)[(long int)eid1] != VECTOR(*edge_color2)[(long int)eid2]) { end = 1; } if (edge_compat_fn && !edge_compat_fn(graph1, graph2, eid1, eid2, arg)) { end = 1; } } } else { if (VECTOR(in_1)[node] != 0) { xin1++; } if (VECTOR(out_1)[node] != 0) { xout1++; } } } vsize = igraph_vector_int_size(inneis_2); for (i = 0; !end && i < vsize; i++) { long int node = (long int) VECTOR(*inneis_2)[i]; if (VECTOR(*core_2)[node] >= 0) { long int node2 = (long int) VECTOR(*core_2)[node]; /* check if there is a node2->cand1 edge */ if (!igraph_vector_int_binsearch2(inneis_1, node2)) { end = 1; } else if (edge_color1 || edge_compat_fn) { igraph_integer_t eid1, eid2; igraph_get_eid(graph1, &eid1, (igraph_integer_t) node2, (igraph_integer_t) cand1, /*directed=*/ 1, /*error=*/ 1); igraph_get_eid(graph2, &eid2, (igraph_integer_t) node, (igraph_integer_t) cand2, /*directed=*/ 1, /*error=*/ 1); if (edge_color1 && VECTOR(*edge_color1)[(long int)eid1] != VECTOR(*edge_color2)[(long int)eid2]) { end = 1; } if (edge_compat_fn && !edge_compat_fn(graph1, graph2, eid1, eid2, arg)) { end = 1; } } } else { if (VECTOR(in_2)[node] != 0) { xin2++; } if (VECTOR(out_2)[node] != 0) { xout2++; } } } vsize = igraph_vector_int_size(outneis_2); for (i = 0; !end && i < vsize; i++) { long int node = (long int) VECTOR(*outneis_2)[i]; if (VECTOR(*core_2)[node] >= 0) { long int node2 = (long int) VECTOR(*core_2)[node]; /* check if there is a cand1->node2 edge */ if (!igraph_vector_int_binsearch2(outneis_1, node2)) { end = 1; } else if (edge_color1 || edge_compat_fn) { igraph_integer_t eid1, eid2; igraph_get_eid(graph1, &eid1, (igraph_integer_t) cand1, (igraph_integer_t) node2, /*directed=*/ 1, /*error=*/ 1); igraph_get_eid(graph2, &eid2, (igraph_integer_t) cand2, (igraph_integer_t) node, /*directed=*/ 1, /*error=*/ 1); if (edge_color1 && VECTOR(*edge_color1)[(long int)eid1] != VECTOR(*edge_color2)[(long int)eid2]) { end = 1; } if (edge_compat_fn && !edge_compat_fn(graph1, graph2, eid1, eid2, arg)) { end = 1; } } } else { if (VECTOR(in_2)[node] != 0) { xin2++; } if (VECTOR(out_2)[node] != 0) { xout2++; } } } if (!end && (xin1 == xin2 && xout1 == xout2)) { /* Ok, we add the (cand1, cand2) pair to the mapping */ depth += 1; IGRAPH_CHECK(igraph_stack_push(&path, cand1)); IGRAPH_CHECK(igraph_stack_push(&path, cand2)); matched_nodes += 1; VECTOR(*core_1)[cand1] = cand2; VECTOR(*core_2)[cand2] = cand1; /* update in_*, out_* */ if (VECTOR(in_1)[cand1] != 0) { in_1_size -= 1; } if (VECTOR(out_1)[cand1] != 0) { out_1_size -= 1; } if (VECTOR(in_2)[cand2] != 0) { in_2_size -= 1; } if (VECTOR(out_2)[cand2] != 0) { out_2_size -= 1; } inneis_1 = igraph_lazy_adjlist_get(&inadj1, (igraph_integer_t) cand1); vsize = igraph_vector_int_size(inneis_1); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*inneis_1)[i]; if (VECTOR(in_1)[node] == 0 && VECTOR(*core_1)[node] < 0) { VECTOR(in_1)[node] = depth; in_1_size += 1; } } outneis_1 = igraph_lazy_adjlist_get(&outadj1, (igraph_integer_t) cand1); vsize = igraph_vector_int_size(outneis_1); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*outneis_1)[i]; if (VECTOR(out_1)[node] == 0 && VECTOR(*core_1)[node] < 0) { VECTOR(out_1)[node] = depth; out_1_size += 1; } } inneis_2 = igraph_lazy_adjlist_get(&inadj2, (igraph_integer_t) cand2); vsize = igraph_vector_int_size(inneis_2); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*inneis_2)[i]; if (VECTOR(in_2)[node] == 0 && VECTOR(*core_2)[node] < 0) { VECTOR(in_2)[node] = depth; in_2_size += 1; } } outneis_2 = igraph_lazy_adjlist_get(&outadj2, (igraph_integer_t) cand2); vsize = igraph_vector_int_size(outneis_2); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*outneis_2)[i]; if (VECTOR(out_2)[node] == 0 && VECTOR(*core_2)[node] < 0) { VECTOR(out_2)[node] = depth; out_2_size += 1; } } last1 = -1; last2 = -1; /* this the first time here */ } else { last1 = cand1; last2 = cand2; } } if (matched_nodes == no_of_nodes && isohandler_fn) { if (!isohandler_fn(core_1, core_2, arg)) { break; } } } igraph_vector_destroy(&outdeg2); igraph_vector_destroy(&outdeg1); igraph_vector_destroy(&indeg2); igraph_vector_destroy(&indeg1); igraph_lazy_adjlist_destroy(&outadj2); igraph_lazy_adjlist_destroy(&inadj2); igraph_lazy_adjlist_destroy(&outadj1); igraph_lazy_adjlist_destroy(&inadj1); igraph_stack_destroy(&path); igraph_vector_destroy(&out_2); igraph_vector_destroy(&out_1); igraph_vector_destroy(&in_2); igraph_vector_destroy(&in_1); IGRAPH_FINALLY_CLEAN(13); if (!map21) { igraph_vector_destroy(core_2); IGRAPH_FINALLY_CLEAN(1); } if (!map12) { igraph_vector_destroy(core_1); IGRAPH_FINALLY_CLEAN(1); } return 0; } typedef struct { igraph_isocompat_t *node_compat_fn, *edge_compat_fn; void *arg, *carg; } igraph_i_iso_cb_data_t; static igraph_bool_t igraph_i_isocompat_node_cb( const igraph_t *graph1, const igraph_t *graph2, const igraph_integer_t g1_num, const igraph_integer_t g2_num, void *arg) { igraph_i_iso_cb_data_t *data = arg; return data->node_compat_fn(graph1, graph2, g1_num, g2_num, data->carg); } static igraph_bool_t igraph_i_isocompat_edge_cb( const igraph_t *graph1, const igraph_t *graph2, const igraph_integer_t g1_num, const igraph_integer_t g2_num, void *arg) { igraph_i_iso_cb_data_t *data = arg; return data->edge_compat_fn(graph1, graph2, g1_num, g2_num, data->carg); } static igraph_bool_t igraph_i_isomorphic_vf2(igraph_vector_t *map12, igraph_vector_t *map21, void *arg) { igraph_i_iso_cb_data_t *data = arg; igraph_bool_t *iso = data->arg; IGRAPH_UNUSED(map12); IGRAPH_UNUSED(map21); *iso = 1; return 0; /* don't need to continue */ } /** * \function igraph_isomorphic_vf2 * \brief Isomorphism via VF2 * * * This function performs the VF2 algorithm via calling \ref * igraph_isomorphic_function_vf2(). * * Note that this function cannot be used for * deciding subgraph isomorphism, use \ref igraph_subisomorphic_vf2() * for that. * \param graph1 The first graph, may be directed or undirected. * \param graph2 The second graph. It must have the same directedness * as \p graph1, otherwise an error is reported. * \param vertex_color1 An optional color vector for the first graph. If * color vectors are given for both graphs, then the isomorphism is * calculated on the colored graphs; i.e. two vertices can match * only if their color also matches. Supply a null pointer here if * your graphs are not colored. * \param vertex_color2 An optional color vector for the second graph. See * the previous argument for explanation. * \param edge_color1 An optional edge color vector for the first * graph. The matching edges in the two graphs must have matching * colors as well. Supply a null pointer here if your graphs are not * edge-colored. * \param edge_color2 The edge color vector for the second graph. * \param iso Pointer to a logical constant, the result of the * algorithm will be placed here. * \param map12 Pointer to an initialized vector or a NULL pointer. If not * a NULL pointer then the mapping from \p graph1 to \p graph2 is * stored here. If the graphs are not isomorphic then the vector is * cleared (i.e. has zero elements). * \param map21 Pointer to an initialized vector or a NULL pointer. If not * a NULL pointer then the mapping from \p graph2 to \p graph1 is * stored here. If the graphs are not isomorphic then the vector is * cleared (i.e. has zero elements). * \param node_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two nodes are compatible. * \param edge_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two edges are compatible. * \param arg Extra argument to supply to functions \p node_compat_fn * and \p edge_compat_fn. * \return Error code. * * \sa \ref igraph_subisomorphic_vf2(), * \ref igraph_count_isomorphisms_vf2(), * \ref igraph_get_isomorphisms_vf2(), * * Time complexity: exponential, what did you expect? * * \example examples/simple/igraph_isomorphic_vf2.c */ int igraph_isomorphic_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_bool_t *iso, igraph_vector_t *map12, igraph_vector_t *map21, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg) { igraph_i_iso_cb_data_t data = { node_compat_fn, edge_compat_fn, iso, arg }; igraph_isocompat_t *ncb = node_compat_fn ? igraph_i_isocompat_node_cb : 0; igraph_isocompat_t *ecb = edge_compat_fn ? igraph_i_isocompat_edge_cb : 0; *iso = 0; IGRAPH_CHECK(igraph_isomorphic_function_vf2(graph1, graph2, vertex_color1, vertex_color2, edge_color1, edge_color2, map12, map21, (igraph_isohandler_t*) igraph_i_isomorphic_vf2, ncb, ecb, &data)); if (! *iso) { if (map12) { igraph_vector_clear(map12); } if (map21) { igraph_vector_clear(map21); } } return 0; } static igraph_bool_t igraph_i_count_isomorphisms_vf2( const igraph_vector_t *map12, const igraph_vector_t *map21, void *arg) { igraph_i_iso_cb_data_t *data = arg; igraph_integer_t *count = data->arg; IGRAPH_UNUSED(map12); IGRAPH_UNUSED(map21); *count += 1; return 1; /* always continue */ } /** * \function igraph_count_isomorphisms_vf2 * Number of isomorphisms via VF2 * * This function counts the number of isomorphic mappings between two * graphs. It uses the generic \ref igraph_isomorphic_function_vf2() * function. * \param graph1 The first input graph, may be directed or undirected. * \param graph2 The second input graph, it must have the same * directedness as \p graph1, or an error will be reported. * \param vertex_color1 An optional color vector for the first graph. If * color vectors are given for both graphs, then the isomorphism is * calculated on the colored graphs; i.e. two vertices can match * only if their color also matches. Supply a null pointer here if * your graphs are not colored. * \param vertex_color2 An optional color vector for the second graph. See * the previous argument for explanation. * \param edge_color1 An optional edge color vector for the first * graph. The matching edges in the two graphs must have matching * colors as well. Supply a null pointer here if your graphs are not * edge-colored. * \param edge_color2 The edge color vector for the second graph. * \param count Point to an integer, the result will be stored here. * \param node_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two nodes are compatible. * \param edge_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two edges are compatible. * \param arg Extra argument to supply to functions \p node_compat_fn and * \p edge_compat_fn. * \return Error code. * * Time complexity: exponential. */ int igraph_count_isomorphisms_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_integer_t *count, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg) { igraph_i_iso_cb_data_t data = { node_compat_fn, edge_compat_fn, count, arg }; igraph_isocompat_t *ncb = node_compat_fn ? igraph_i_isocompat_node_cb : 0; igraph_isocompat_t *ecb = edge_compat_fn ? igraph_i_isocompat_edge_cb : 0; *count = 0; IGRAPH_CHECK(igraph_isomorphic_function_vf2(graph1, graph2, vertex_color1, vertex_color2, edge_color1, edge_color2, 0, 0, (igraph_isohandler_t*) igraph_i_count_isomorphisms_vf2, ncb, ecb, &data)); return 0; } static void igraph_i_get_isomorphisms_free(igraph_vector_ptr_t *data) { long int i, n = igraph_vector_ptr_size(data); for (i = 0; i < n; i++) { igraph_vector_t *vec = VECTOR(*data)[i]; igraph_vector_destroy(vec); igraph_free(vec); } } static int igraph_i_get_isomorphisms_vf2_inner( const igraph_vector_t *map12, const igraph_vector_t *map21, void *arg) { igraph_i_iso_cb_data_t *data = arg; igraph_vector_ptr_t *ptrvector = data->arg; igraph_vector_t *newvector = IGRAPH_CALLOC(1, igraph_vector_t); IGRAPH_UNUSED(map12); if (!newvector) { IGRAPH_ERROR("", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newvector); IGRAPH_CHECK(igraph_vector_copy(newvector, map21)); IGRAPH_FINALLY(igraph_vector_destroy, newvector); IGRAPH_CHECK(igraph_vector_ptr_push_back(ptrvector, newvector)); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } static igraph_bool_t igraph_i_get_isomorphisms_vf2( const igraph_vector_t *map12, const igraph_vector_t *map21, void *arg) { return igraph_i_get_isomorphisms_vf2_inner(map12, map21, arg) == IGRAPH_SUCCESS; } /** * \function igraph_get_isomorphisms_vf2 * \brief Collect all isomorphic mappings of two graphs. * * This function finds all the isomorphic mappings between two simple * graphs. It uses the \ref igraph_isomorphic_function_vf2() * function. Call the function with the same graph as \p graph1 and \p * graph2 to get automorphisms. * \param graph1 The first input graph, may be directed or undirected. * \param graph2 The second input graph, it must have the same * directedness as \p graph1, or an error will be reported. * \param vertex_color1 An optional color vector for the first graph. If * color vectors are given for both graphs, then the isomorphism is * calculated on the colored graphs; i.e. two vertices can match * only if their color also matches. Supply a null pointer here if * your graphs are not colored. * \param vertex_color2 An optional color vector for the second graph. See * the previous argument for explanation. * \param edge_color1 An optional edge color vector for the first * graph. The matching edges in the two graphs must have matching * colors as well. Supply a null pointer here if your graphs are not * edge-colored. * \param edge_color2 The edge color vector for the second graph. * \param maps Pointer vector. On return it is empty if the input graphs * are not isomorphic. Otherwise it contains pointers to * \ref igraph_vector_t objects, each vector is an * isomorphic mapping of \p graph2 to \p graph1. Please note that * you need to 1) Destroy the vectors via \ref * igraph_vector_destroy(), 2) free them via * \ref igraph_free() and then 3) call \ref * igraph_vector_ptr_destroy() on the pointer vector to deallocate all * memory when \p maps is no longer needed. * \param node_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two nodes are compatible. * \param edge_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two edges are compatible. * \param arg Extra argument to supply to functions \p node_compat_fn * and \p edge_compat_fn. * \return Error code. * * Time complexity: exponential. */ int igraph_get_isomorphisms_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_vector_ptr_t *maps, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg) { igraph_i_iso_cb_data_t data = { node_compat_fn, edge_compat_fn, maps, arg }; igraph_isocompat_t *ncb = node_compat_fn ? igraph_i_isocompat_node_cb : NULL; igraph_isocompat_t *ecb = edge_compat_fn ? igraph_i_isocompat_edge_cb : NULL; igraph_vector_ptr_clear(maps); IGRAPH_FINALLY(igraph_i_get_isomorphisms_free, maps); IGRAPH_CHECK(igraph_isomorphic_function_vf2(graph1, graph2, vertex_color1, vertex_color2, edge_color1, edge_color2, NULL, NULL, (igraph_isohandler_t*) igraph_i_get_isomorphisms_vf2, ncb, ecb, &data)); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \function igraph_subisomorphic_function_vf2 * Generic VF2 function for subgraph isomorphism problems * * This function is the pair of \ref igraph_isomorphic_function_vf2(), * for subgraph isomorphism problems. It searches for subgraphs of \p * graph1 which are isomorphic to \p graph2. When it founds an * isomorphic mapping it calls the supplied callback \p isohandler_fn. * The mapping (and its inverse) and the additional \p arg argument * are supplied to the callback. * \param graph1 The first input graph, may be directed or * undirected. This is supposed to be the larger graph. * \param graph2 The second input graph, it must have the same * directedness as \p graph1. This is supposed to be the smaller * graph. * \param vertex_color1 An optional color vector for the first graph. If * color vectors are given for both graphs, then the subgraph isomorphism is * calculated on the colored graphs; i.e. two vertices can match * only if their color also matches. Supply a null pointer here if * your graphs are not colored. * \param vertex_color2 An optional color vector for the second graph. See * the previous argument for explanation. * \param edge_color1 An optional edge color vector for the first * graph. The matching edges in the two graphs must have matching * colors as well. Supply a null pointer here if your graphs are not * edge-colored. * \param edge_color2 The edge color vector for the second graph. * \param map12 Pointer to a vector or \c NULL. If not \c NULL, then an * isomorphic mapping from \p graph1 to \p graph2 is stored here. * \param map21 Pointer to a vector ot \c NULL. If not \c NULL, then * an isomorphic mapping from \p graph2 to \p graph1 is stored * here. * \param isohandler_fn A pointer to a function of type \ref * igraph_isohandler_t. This will be called whenever a subgraph * isomorphism is found. If the function returns with a non-zero value * then the search is continued, otherwise it stops and the function * returns. * \param node_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two nodes are compatible. * \param edge_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two edges are compatible. * \param arg Extra argument to supply to functions \p isohandler_fn, \p * node_compat_fn and \p edge_compat_fn. * \return Error code. * * Time complexity: exponential. */ int igraph_subisomorphic_function_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_vector_t *map12, igraph_vector_t *map21, igraph_isohandler_t *isohandler_fn, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg) { long int no_of_nodes1 = igraph_vcount(graph1), no_of_nodes2 = igraph_vcount(graph2); long int no_of_edges1 = igraph_ecount(graph1), no_of_edges2 = igraph_ecount(graph2); igraph_vector_t mycore_1, mycore_2, *core_1 = &mycore_1, *core_2 = &mycore_2; igraph_vector_t in_1, in_2, out_1, out_2; long int in_1_size = 0, in_2_size = 0, out_1_size = 0, out_2_size = 0; igraph_vector_int_t *inneis_1, *inneis_2, *outneis_1, *outneis_2; long int matched_nodes = 0; long int depth; long int cand1, cand2; long int last1, last2; igraph_stack_t path; igraph_lazy_adjlist_t inadj1, inadj2, outadj1, outadj2; igraph_vector_t indeg1, indeg2, outdeg1, outdeg2; long int vsize; if (igraph_is_directed(graph1) != igraph_is_directed(graph2)) { IGRAPH_ERROR("Cannot compare directed and undirected graphs", IGRAPH_EINVAL); } if (no_of_nodes1 < no_of_nodes2 || no_of_edges1 < no_of_edges2) { return 0; } if ( (vertex_color1 && !vertex_color2) || (!vertex_color1 && vertex_color2) ) { IGRAPH_WARNING("Only one graph is vertex colored, colors will be ignored"); vertex_color1 = vertex_color2 = 0; } if ( (edge_color1 && !edge_color2) || (!edge_color1 && edge_color2) ) { IGRAPH_WARNING("Only one graph is edge colored, colors will be ignored"); edge_color1 = edge_color2 = 0; } if (vertex_color1) { if (igraph_vector_int_size(vertex_color1) != no_of_nodes1 || igraph_vector_int_size(vertex_color2) != no_of_nodes2) { IGRAPH_ERROR("Invalid vertex color vector length", IGRAPH_EINVAL); } } if (edge_color1) { if (igraph_vector_int_size(edge_color1) != no_of_edges1 || igraph_vector_int_size(edge_color2) != no_of_edges2) { IGRAPH_ERROR("Invalid edge color vector length", IGRAPH_EINVAL); } } /* Check color distribution */ if (vertex_color1) { /* TODO */ } /* Check edge color distribution */ if (edge_color1) { /* TODO */ } if (map12) { core_1 = map12; IGRAPH_CHECK(igraph_vector_resize(core_1, no_of_nodes1)); } else { IGRAPH_VECTOR_INIT_FINALLY(core_1, no_of_nodes1); } igraph_vector_fill(core_1, -1); if (map21) { core_2 = map21; IGRAPH_CHECK(igraph_vector_resize(core_2, no_of_nodes2)); } else { IGRAPH_VECTOR_INIT_FINALLY(core_2, no_of_nodes2); } igraph_vector_fill(core_2, -1); IGRAPH_VECTOR_INIT_FINALLY(&in_1, no_of_nodes1); IGRAPH_VECTOR_INIT_FINALLY(&in_2, no_of_nodes2); IGRAPH_VECTOR_INIT_FINALLY(&out_1, no_of_nodes1); IGRAPH_VECTOR_INIT_FINALLY(&out_2, no_of_nodes2); IGRAPH_CHECK(igraph_stack_init(&path, 0)); IGRAPH_FINALLY(igraph_stack_destroy, &path); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph1, &inadj1, IGRAPH_IN, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &inadj1); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph1, &outadj1, IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &outadj1); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph2, &inadj2, IGRAPH_IN, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &inadj2); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph2, &outadj2, IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &outadj2); IGRAPH_VECTOR_INIT_FINALLY(&indeg1, 0); IGRAPH_VECTOR_INIT_FINALLY(&indeg2, 0); IGRAPH_VECTOR_INIT_FINALLY(&outdeg1, 0); IGRAPH_VECTOR_INIT_FINALLY(&outdeg2, 0); IGRAPH_CHECK(igraph_stack_reserve(&path, no_of_nodes2 * 2)); IGRAPH_CHECK(igraph_degree(graph1, &indeg1, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_degree(graph2, &indeg2, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_degree(graph1, &outdeg1, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_degree(graph2, &outdeg2, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); depth = 0; last1 = -1; last2 = -1; while (depth >= 0) { long int i; IGRAPH_ALLOW_INTERRUPTION(); cand1 = -1; cand2 = -1; /* Search for the next pair to try */ if ((in_1_size < in_2_size) || (out_1_size < out_2_size)) { /* step back, nothing to do */ } else if (out_1_size > 0 && out_2_size > 0) { /**************************************************************/ /* cand2, search not always needed */ if (last2 >= 0) { cand2 = last2; } else { i = 0; while (cand2 < 0 && i < no_of_nodes2) { if (VECTOR(out_2)[i] > 0 && VECTOR(*core_2)[i] < 0) { cand2 = i; } i++; } } /* search for cand1 now, it should be bigger than last1 */ i = last1 + 1; while (cand1 < 0 && i < no_of_nodes1) { if (VECTOR(out_1)[i] > 0 && VECTOR(*core_1)[i] < 0) { cand1 = i; } i++; } } else if (in_1_size > 0 && in_2_size > 0) { /**************************************************************/ /* cand2, search not always needed */ if (last2 >= 0) { cand2 = last2; } else { i = 0; while (cand2 < 0 && i < no_of_nodes2) { if (VECTOR(in_2)[i] > 0 && VECTOR(*core_2)[i] < 0) { cand2 = i; } i++; } } /* search for cand1 now, should be bigger than last1 */ i = last1 + 1; while (cand1 < 0 && i < no_of_nodes1) { if (VECTOR(in_1)[i] > 0 && VECTOR(*core_1)[i] < 0) { cand1 = i; } i++; } } else { /**************************************************************/ /* cand2, search not always needed */ if (last2 >= 0) { cand2 = last2; } else { i = 0; while (cand2 < 0 && i < no_of_nodes2) { if (VECTOR(*core_2)[i] < 0) { cand2 = i; } i++; } } /* search for cand1, should be bigger than last1 */ i = last1 + 1; while (cand1 < 0 && i < no_of_nodes1) { if (VECTOR(*core_1)[i] < 0) { cand1 = i; } i++; } } /* Ok, we have cand1, cand2 as candidates. Or not? */ if (cand1 < 0 || cand2 < 0) { /**************************************************************/ /* dead end, step back, if possible. Otherwise we'll terminate */ if (depth >= 1) { last2 = (long int) igraph_stack_pop(&path); last1 = (long int) igraph_stack_pop(&path); matched_nodes -= 1; VECTOR(*core_1)[last1] = -1; VECTOR(*core_2)[last2] = -1; if (VECTOR(in_1)[last1] != 0) { in_1_size += 1; } if (VECTOR(out_1)[last1] != 0) { out_1_size += 1; } if (VECTOR(in_2)[last2] != 0) { in_2_size += 1; } if (VECTOR(out_2)[last2] != 0) { out_2_size += 1; } inneis_1 = igraph_lazy_adjlist_get(&inadj1, (igraph_integer_t) last1); vsize = igraph_vector_int_size(inneis_1); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*inneis_1)[i]; if (VECTOR(in_1)[node] == depth) { VECTOR(in_1)[node] = 0; in_1_size -= 1; } } outneis_1 = igraph_lazy_adjlist_get(&outadj1, (igraph_integer_t) last1); vsize = igraph_vector_int_size(outneis_1); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*outneis_1)[i]; if (VECTOR(out_1)[node] == depth) { VECTOR(out_1)[node] = 0; out_1_size -= 1; } } inneis_2 = igraph_lazy_adjlist_get(&inadj2, (igraph_integer_t) last2); vsize = igraph_vector_int_size(inneis_2); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*inneis_2)[i]; if (VECTOR(in_2)[node] == depth) { VECTOR(in_2)[node] = 0; in_2_size -= 1; } } outneis_2 = igraph_lazy_adjlist_get(&outadj2, (igraph_integer_t) last2); vsize = igraph_vector_int_size(outneis_2); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*outneis_2)[i]; if (VECTOR(out_2)[node] == depth) { VECTOR(out_2)[node] = 0; out_2_size -= 1; } } } /* end of stepping back */ depth -= 1; } else { /**************************************************************/ /* step forward if worth, check if worth first */ long int xin1 = 0, xin2 = 0, xout1 = 0, xout2 = 0; igraph_bool_t end = 0; inneis_1 = igraph_lazy_adjlist_get(&inadj1, (igraph_integer_t) cand1); outneis_1 = igraph_lazy_adjlist_get(&outadj1, (igraph_integer_t) cand1); inneis_2 = igraph_lazy_adjlist_get(&inadj2, (igraph_integer_t) cand2); outneis_2 = igraph_lazy_adjlist_get(&outadj2, (igraph_integer_t) cand2); if (VECTOR(indeg1)[cand1] < VECTOR(indeg2)[cand2] || VECTOR(outdeg1)[cand1] < VECTOR(outdeg2)[cand2]) { end = 1; } if (vertex_color1 && VECTOR(*vertex_color1)[cand1] != VECTOR(*vertex_color2)[cand2]) { end = 1; } if (node_compat_fn && !node_compat_fn(graph1, graph2, (igraph_integer_t) cand1, (igraph_integer_t) cand2, arg)) { end = 1; } vsize = igraph_vector_int_size(inneis_1); for (i = 0; !end && i < vsize; i++) { long int node = (long int) VECTOR(*inneis_1)[i]; if (VECTOR(*core_1)[node] < 0) { if (VECTOR(in_1)[node] != 0) { xin1++; } if (VECTOR(out_1)[node] != 0) { xout1++; } } } vsize = igraph_vector_int_size(outneis_1); for (i = 0; !end && i < vsize; i++) { long int node = (long int) VECTOR(*outneis_1)[i]; if (VECTOR(*core_1)[node] < 0) { if (VECTOR(in_1)[node] != 0) { xin1++; } if (VECTOR(out_1)[node] != 0) { xout1++; } } } vsize = igraph_vector_int_size(inneis_2); for (i = 0; !end && i < vsize; i++) { long int node = (long int) VECTOR(*inneis_2)[i]; if (VECTOR(*core_2)[node] >= 0) { long int node2 = (long int) VECTOR(*core_2)[node]; /* check if there is a node2->cand1 edge */ if (!igraph_vector_int_binsearch2(inneis_1, node2)) { end = 1; } else if (edge_color1 || edge_compat_fn) { igraph_integer_t eid1, eid2; igraph_get_eid(graph1, &eid1, (igraph_integer_t) node2, (igraph_integer_t) cand1, /*directed=*/ 1, /*error=*/ 1); igraph_get_eid(graph2, &eid2, (igraph_integer_t) node, (igraph_integer_t) cand2, /*directed=*/ 1, /*error=*/ 1); if (edge_color1 && VECTOR(*edge_color1)[(long int)eid1] != VECTOR(*edge_color2)[(long int)eid2]) { end = 1; } if (edge_compat_fn && !edge_compat_fn(graph1, graph2, eid1, eid2, arg)) { end = 1; } } } else { if (VECTOR(in_2)[node] != 0) { xin2++; } if (VECTOR(out_2)[node] != 0) { xout2++; } } } vsize = igraph_vector_int_size(outneis_2); for (i = 0; !end && i < vsize; i++) { long int node = (long int) VECTOR(*outneis_2)[i]; if (VECTOR(*core_2)[node] >= 0) { long int node2 = (long int) VECTOR(*core_2)[node]; /* check if there is a cand1->node2 edge */ if (!igraph_vector_int_binsearch2(outneis_1, node2)) { end = 1; } else if (edge_color1 || edge_compat_fn) { igraph_integer_t eid1, eid2; igraph_get_eid(graph1, &eid1, (igraph_integer_t) cand1, (igraph_integer_t) node2, /*directed=*/ 1, /*error=*/ 1); igraph_get_eid(graph2, &eid2, (igraph_integer_t) cand2, (igraph_integer_t) node, /*directed=*/ 1, /*error=*/ 1); if (edge_color1 && VECTOR(*edge_color1)[(long int)eid1] != VECTOR(*edge_color2)[(long int)eid2]) { end = 1; } if (edge_compat_fn && !edge_compat_fn(graph1, graph2, eid1, eid2, arg)) { end = 1; } } } else { if (VECTOR(in_2)[node] != 0) { xin2++; } if (VECTOR(out_2)[node] != 0) { xout2++; } } } if (!end && (xin1 >= xin2 && xout1 >= xout2)) { /* Ok, we add the (cand1, cand2) pair to the mapping */ depth += 1; IGRAPH_CHECK(igraph_stack_push(&path, cand1)); IGRAPH_CHECK(igraph_stack_push(&path, cand2)); matched_nodes += 1; VECTOR(*core_1)[cand1] = cand2; VECTOR(*core_2)[cand2] = cand1; /* update in_*, out_* */ if (VECTOR(in_1)[cand1] != 0) { in_1_size -= 1; } if (VECTOR(out_1)[cand1] != 0) { out_1_size -= 1; } if (VECTOR(in_2)[cand2] != 0) { in_2_size -= 1; } if (VECTOR(out_2)[cand2] != 0) { out_2_size -= 1; } inneis_1 = igraph_lazy_adjlist_get(&inadj1, (igraph_integer_t) cand1); vsize = igraph_vector_int_size(inneis_1); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*inneis_1)[i]; if (VECTOR(in_1)[node] == 0 && VECTOR(*core_1)[node] < 0) { VECTOR(in_1)[node] = depth; in_1_size += 1; } } outneis_1 = igraph_lazy_adjlist_get(&outadj1, (igraph_integer_t) cand1); vsize = igraph_vector_int_size(outneis_1); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*outneis_1)[i]; if (VECTOR(out_1)[node] == 0 && VECTOR(*core_1)[node] < 0) { VECTOR(out_1)[node] = depth; out_1_size += 1; } } inneis_2 = igraph_lazy_adjlist_get(&inadj2, (igraph_integer_t) cand2); vsize = igraph_vector_int_size(inneis_2); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*inneis_2)[i]; if (VECTOR(in_2)[node] == 0 && VECTOR(*core_2)[node] < 0) { VECTOR(in_2)[node] = depth; in_2_size += 1; } } outneis_2 = igraph_lazy_adjlist_get(&outadj2, (igraph_integer_t) cand2); vsize = igraph_vector_int_size(outneis_2); for (i = 0; i < vsize; i++) { long int node = (long int) VECTOR(*outneis_2)[i]; if (VECTOR(out_2)[node] == 0 && VECTOR(*core_2)[node] < 0) { VECTOR(out_2)[node] = depth; out_2_size += 1; } } last1 = -1; last2 = -1; /* this the first time here */ } else { last1 = cand1; last2 = cand2; } } if (matched_nodes == no_of_nodes2 && isohandler_fn) { if (!isohandler_fn(core_1, core_2, arg)) { break; } } } igraph_vector_destroy(&outdeg2); igraph_vector_destroy(&outdeg1); igraph_vector_destroy(&indeg2); igraph_vector_destroy(&indeg1); igraph_lazy_adjlist_destroy(&outadj2); igraph_lazy_adjlist_destroy(&inadj2); igraph_lazy_adjlist_destroy(&outadj1); igraph_lazy_adjlist_destroy(&inadj1); igraph_stack_destroy(&path); igraph_vector_destroy(&out_2); igraph_vector_destroy(&out_1); igraph_vector_destroy(&in_2); igraph_vector_destroy(&in_1); IGRAPH_FINALLY_CLEAN(13); if (!map21) { igraph_vector_destroy(core_2); IGRAPH_FINALLY_CLEAN(1); } if (!map12) { igraph_vector_destroy(core_1); IGRAPH_FINALLY_CLEAN(1); } return 0; } static igraph_bool_t igraph_i_subisomorphic_vf2( const igraph_vector_t *map12, const igraph_vector_t *map21, void *arg) { igraph_i_iso_cb_data_t *data = arg; igraph_bool_t *iso = data->arg; IGRAPH_UNUSED(map12); IGRAPH_UNUSED(map21); *iso = 1; return 0; /* stop */ } /** * \function igraph_subisomorphic_vf2 * Decide subgraph isomorphism using VF2 * * Decides whether a subgraph of \p graph1 is isomorphic to \p * graph2. It uses \ref igraph_subisomorphic_function_vf2(). * \param graph1 The first input graph, may be directed or * undirected. This is supposed to be the larger graph. * \param graph2 The second input graph, it must have the same * directedness as \p graph1. This is supposed to be the smaller * graph. * \param vertex_color1 An optional color vector for the first graph. If * color vectors are given for both graphs, then the subgraph isomorphism is * calculated on the colored graphs; i.e. two vertices can match * only if their color also matches. Supply a null pointer here if * your graphs are not colored. * \param vertex_color2 An optional color vector for the second graph. See * the previous argument for explanation. * \param edge_color1 An optional edge color vector for the first * graph. The matching edges in the two graphs must have matching * colors as well. Supply a null pointer here if your graphs are not * edge-colored. * \param edge_color2 The edge color vector for the second graph. * \param iso Pointer to a boolean. The result of the decision problem * is stored here. * \param map12 Pointer to a vector or \c NULL. If not \c NULL, then an * isomorphic mapping from \p graph1 to \p graph2 is stored here. * \param map21 Pointer to a vector ot \c NULL. If not \c NULL, then * an isomorphic mapping from \p graph2 to \p graph1 is stored * here. * \param node_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two nodes are compatible. * \param edge_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two edges are compatible. * \param arg Extra argument to supply to functions \p node_compat_fn * and \p edge_compat_fn. * \return Error code. * * Time complexity: exponential. */ int igraph_subisomorphic_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_bool_t *iso, igraph_vector_t *map12, igraph_vector_t *map21, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg) { igraph_i_iso_cb_data_t data = { node_compat_fn, edge_compat_fn, iso, arg }; igraph_isocompat_t *ncb = node_compat_fn ? igraph_i_isocompat_node_cb : 0; igraph_isocompat_t *ecb = edge_compat_fn ? igraph_i_isocompat_edge_cb : 0; *iso = 0; IGRAPH_CHECK(igraph_subisomorphic_function_vf2(graph1, graph2, vertex_color1, vertex_color2, edge_color1, edge_color2, map12, map21, (igraph_isohandler_t *) igraph_i_subisomorphic_vf2, ncb, ecb, &data)); if (! *iso) { if (map12) { igraph_vector_clear(map12); } if (map21) { igraph_vector_clear(map21); } } return 0; } static igraph_bool_t igraph_i_count_subisomorphisms_vf2( const igraph_vector_t *map12, const igraph_vector_t *map21, void *arg) { igraph_i_iso_cb_data_t *data = arg; igraph_integer_t *count = data->arg; IGRAPH_UNUSED(map12); IGRAPH_UNUSED(map21); *count += 1; return 1; /* always continue */ } /** * \function igraph_count_subisomorphisms_vf2 * Number of subgraph isomorphisms using VF2 * * Count the number of isomorphisms between subgraphs of \p graph1 and * \p graph2. This function uses \ref * igraph_subisomorphic_function_vf2(). * \param graph1 The first input graph, may be directed or * undirected. This is supposed to be the larger graph. * \param graph2 The second input graph, it must have the same * directedness as \p graph1. This is supposed to be the smaller * graph. * \param vertex_color1 An optional color vector for the first graph. If * color vectors are given for both graphs, then the subgraph isomorphism is * calculated on the colored graphs; i.e. two vertices can match * only if their color also matches. Supply a null pointer here if * your graphs are not colored. * \param vertex_color2 An optional color vector for the second graph. See * the previous argument for explanation. * \param edge_color1 An optional edge color vector for the first * graph. The matching edges in the two graphs must have matching * colors as well. Supply a null pointer here if your graphs are not * edge-colored. * \param edge_color2 The edge color vector for the second graph. * \param count Pointer to an integer. The number of subgraph * isomorphisms is stored here. * \param node_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two nodes are compatible. * \param edge_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two edges are compatible. * \param arg Extra argument to supply to functions \p node_compat_fn and * \p edge_compat_fn. * \return Error code. * * Time complexity: exponential. */ int igraph_count_subisomorphisms_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_integer_t *count, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg) { igraph_i_iso_cb_data_t data = { node_compat_fn, edge_compat_fn, count, arg }; igraph_isocompat_t *ncb = node_compat_fn ? igraph_i_isocompat_node_cb : 0; igraph_isocompat_t *ecb = edge_compat_fn ? igraph_i_isocompat_edge_cb : 0; *count = 0; IGRAPH_CHECK(igraph_subisomorphic_function_vf2(graph1, graph2, vertex_color1, vertex_color2, edge_color1, edge_color2, 0, 0, (igraph_isohandler_t*) igraph_i_count_subisomorphisms_vf2, ncb, ecb, &data)); return 0; } static void igraph_i_get_subisomorphisms_free(igraph_vector_ptr_t *data) { long int i, n = igraph_vector_ptr_size(data); for (i = 0; i < n; i++) { igraph_vector_t *vec = VECTOR(*data)[i]; igraph_vector_destroy(vec); igraph_free(vec); } } static int igraph_i_get_subisomorphisms_vf2_inner( const igraph_vector_t *map12, const igraph_vector_t *map21, void *arg) { igraph_i_iso_cb_data_t *data = arg; igraph_vector_ptr_t *vector = data->arg; igraph_vector_t *newvector = IGRAPH_CALLOC(1, igraph_vector_t); IGRAPH_UNUSED(map12); if (!newvector) { IGRAPH_ERROR("", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newvector); IGRAPH_CHECK(igraph_vector_copy(newvector, map21)); IGRAPH_FINALLY(igraph_vector_destroy, newvector); IGRAPH_CHECK(igraph_vector_ptr_push_back(vector, newvector)); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } static igraph_bool_t igraph_i_get_subisomorphisms_vf2( const igraph_vector_t *map12, const igraph_vector_t *map21, void *arg) { return igraph_i_get_subisomorphisms_vf2_inner(map12, map21, arg) == IGRAPH_SUCCESS; } /** * \function igraph_get_subisomorphisms_vf2 * \brief Return all subgraph isomorphic mappings. * * This function collects all isomorphic mappings of \p graph2 to a * subgraph of \p graph1. It uses the \ref * igraph_subisomorphic_function_vf2() function. The graphs should be simple. * \param graph1 The first input graph, may be directed or * undirected. This is supposed to be the larger graph. * \param graph2 The second input graph, it must have the same * directedness as \p graph1. This is supposed to be the smaller * graph. * \param vertex_color1 An optional color vector for the first graph. If * color vectors are given for both graphs, then the subgraph isomorphism is * calculated on the colored graphs; i.e. two vertices can match * only if their color also matches. Supply a null pointer here if * your graphs are not colored. * \param vertex_color2 An optional color vector for the second graph. See * the previous argument for explanation. * \param edge_color1 An optional edge color vector for the first * graph. The matching edges in the two graphs must have matching * colors as well. Supply a null pointer here if your graphs are not * edge-colored. * \param edge_color2 The edge color vector for the second graph. * \param maps Pointer vector. On return it contains pointers to * \ref igraph_vector_t objects, each vector is an * isomorphic mapping of \p graph2 to a subgraph of \p graph1. Please note that * you need to 1) Destroy the vectors via \ref * igraph_vector_destroy(), 2) free them via * \ref igraph_free() and then 3) call \ref * igraph_vector_ptr_destroy() on the pointer vector to deallocate all * memory when \p maps is no longer needed. * \param node_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two nodes are compatible. * \param edge_compat_fn A pointer to a function of type \ref * igraph_isocompat_t. This function will be called by the algorithm to * determine whether two edges are compatible. * \param arg Extra argument to supply to functions \p node_compat_fn * and \p edge_compat_fn. * \return Error code. * * Time complexity: exponential. */ int igraph_get_subisomorphisms_vf2(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *vertex_color1, const igraph_vector_int_t *vertex_color2, const igraph_vector_int_t *edge_color1, const igraph_vector_int_t *edge_color2, igraph_vector_ptr_t *maps, igraph_isocompat_t *node_compat_fn, igraph_isocompat_t *edge_compat_fn, void *arg) { igraph_i_iso_cb_data_t data = { node_compat_fn, edge_compat_fn, maps, arg }; igraph_isocompat_t *ncb = node_compat_fn ? igraph_i_isocompat_node_cb : NULL; igraph_isocompat_t *ecb = edge_compat_fn ? igraph_i_isocompat_edge_cb : NULL; igraph_vector_ptr_clear(maps); IGRAPH_FINALLY(igraph_i_get_subisomorphisms_free, maps); IGRAPH_CHECK(igraph_subisomorphic_function_vf2(graph1, graph2, vertex_color1, vertex_color2, edge_color1, edge_color2, NULL, NULL, (igraph_isohandler_t*) igraph_i_get_subisomorphisms_vf2, ncb, ecb, &data)); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/misc/0000755000176200001440000000000014532173045015023 5ustar liggesusersleidenbase/src/core/misc/other.c0000644000176200001440000004043114447675375016334 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_nongraph.h" #include "igraph_random.h" #include "igraph_types.h" #include "core/interruption.h" #include "plfit/plfit_error.h" #include "plfit/plfit.h" #include /** * \ingroup nongraph * \function igraph_running_mean * \brief Calculates the running mean of a vector. * * * The running mean is defined by the mean of the * previous \p binwidth values. * \param data The vector containing the data. * \param res The vector containing the result. This should be * initialized before calling this function and will be * resized. * \param binwidth Integer giving the width of the bin for the running * mean calculation. * \return Error code. * * Time complexity: O(n), * n is the length of * the data vector. */ int igraph_running_mean(const igraph_vector_t *data, igraph_vector_t *res, igraph_integer_t binwidth) { double sum = 0; long int i; /* Check */ if (igraph_vector_size(data) < binwidth) { IGRAPH_ERRORF("Data vector length (%ld) smaller than bin width (%" IGRAPH_PRId ").", IGRAPH_EINVAL, igraph_vector_size(data), binwidth); } if (binwidth < 1) { IGRAPH_ERRORF("Bin width for running mean should be at least 1, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, binwidth); } /* Memory for result */ IGRAPH_CHECK(igraph_vector_resize(res, (long int)(igraph_vector_size(data) - binwidth + 1))); /* Initial bin */ for (i = 0; i < binwidth; i++) { sum += VECTOR(*data)[i]; } VECTOR(*res)[0] = sum / binwidth; for (i = 1; i < igraph_vector_size(data) - binwidth + 1; i++) { IGRAPH_ALLOW_INTERRUPTION(); sum -= VECTOR(*data)[i - 1]; sum += VECTOR(*data)[ (long int)(i + binwidth - 1)]; VECTOR(*res)[i] = sum / binwidth; } return IGRAPH_SUCCESS; } /** * \ingroup nongraph * \function igraph_convex_hull * \brief Determines the convex hull of a given set of points in the 2D plane * * * The convex hull is determined by the Graham scan algorithm. * See the following reference for details: * * * Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford * Stein. Introduction to Algorithms, Second Edition. MIT Press and * McGraw-Hill, 2001. ISBN 0262032937. Pages 949-955 of section 33.3: * Finding the convex hull. * * \param data vector containing the coordinates. The length of the * vector must be even, since it contains X-Y coordinate pairs. * \param resverts the vector containing the result, e.g. the vector of * vertex indices used as the corners of the convex hull. Supply * \c NULL here if you are only interested in the coordinates of * the convex hull corners. * \param rescoords the matrix containing the coordinates of the selected * corner vertices. Supply \c NULL here if you are only interested in * the vertex indices. * \return Error code: * \c IGRAPH_ENOMEM: not enough memory * * Time complexity: O(n log(n)) where n is the number of vertices * * \example examples/simple/igraph_convex_hull.c */ int igraph_convex_hull(const igraph_matrix_t *data, igraph_vector_t *resverts, igraph_matrix_t *rescoords) { igraph_integer_t no_of_nodes; long int i, pivot_idx = 0, last_idx, before_last_idx, next_idx, j; igraph_vector_t angles, stack, order; igraph_real_t px, py, cp; no_of_nodes = (igraph_integer_t) igraph_matrix_nrow(data); if (igraph_matrix_ncol(data) != 2) { IGRAPH_ERROR("matrix must have 2 columns", IGRAPH_EINVAL); } if (no_of_nodes == 0) { if (resverts != 0) { IGRAPH_CHECK(igraph_vector_resize(resverts, 0)); } if (rescoords != 0) { IGRAPH_CHECK(igraph_matrix_resize(rescoords, 0, 2)); } /**************************** this is an exit here *********/ return 0; } IGRAPH_VECTOR_INIT_FINALLY(&angles, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&stack, 0); /* Search for the pivot vertex */ for (i = 1; i < no_of_nodes; i++) { if (MATRIX(*data, i, 1) < MATRIX(*data, pivot_idx, 1)) { pivot_idx = i; } else if (MATRIX(*data, i, 1) == MATRIX(*data, pivot_idx, 1) && MATRIX(*data, i, 0) < MATRIX(*data, pivot_idx, 0)) { pivot_idx = i; } } px = MATRIX(*data, pivot_idx, 0); py = MATRIX(*data, pivot_idx, 1); /* Create angle array */ for (i = 0; i < no_of_nodes; i++) { if (i == pivot_idx) { /* We can't calculate the angle of the pivot point with itself, * so we use 10 here. This way, after sorting the angle vector, * the pivot point will always be the first one, since the range * of atan2 is -3.14..3.14 */ VECTOR(angles)[i] = 10; } else { VECTOR(angles)[i] = atan2(MATRIX(*data, i, 1) - py, MATRIX(*data, i, 0) - px); } } /* Sort points by angles */ IGRAPH_VECTOR_INIT_FINALLY(&order, no_of_nodes); IGRAPH_CHECK(igraph_vector_qsort_ind(&angles, &order, 0)); /* Check if two points have the same angle. If so, keep only the point that * is farthest from the pivot */ j = 0; last_idx = (long int) VECTOR(order)[0]; pivot_idx = (long int) VECTOR(order)[no_of_nodes - 1]; for (i = 1; i < no_of_nodes; i++) { next_idx = (long int) VECTOR(order)[i]; if (VECTOR(angles)[last_idx] == VECTOR(angles)[next_idx]) { /* Keep the vertex that is farther from the pivot, drop the one that is * closer */ px = pow(MATRIX(*data, last_idx, 0) - MATRIX(*data, pivot_idx, 0), 2) + pow(MATRIX(*data, last_idx, 1) - MATRIX(*data, pivot_idx, 1), 2); py = pow(MATRIX(*data, next_idx, 0) - MATRIX(*data, pivot_idx, 0), 2) + pow(MATRIX(*data, next_idx, 1) - MATRIX(*data, pivot_idx, 1), 2); if (px > py) { VECTOR(order)[i] = -1; } else { VECTOR(order)[j] = -1; last_idx = next_idx; j = i; } } else { last_idx = next_idx; j = i; } } j = 0; last_idx = -1; before_last_idx = -1; while (!igraph_vector_empty(&order)) { next_idx = (long int)VECTOR(order)[igraph_vector_size(&order) - 1]; if (next_idx < 0) { /* This vertex should be skipped; was excluded in an earlier step */ igraph_vector_pop_back(&order); continue; } /* Determine whether we are at a left or right turn */ if (j < 2) { /* Pretend that we are turning into the right direction if we have less * than two items in the stack */ cp = -1; } else { cp = (MATRIX(*data, last_idx, 0) - MATRIX(*data, before_last_idx, 0)) * (MATRIX(*data, next_idx, 1) - MATRIX(*data, before_last_idx, 1)) - (MATRIX(*data, next_idx, 0) - MATRIX(*data, before_last_idx, 0)) * (MATRIX(*data, last_idx, 1) - MATRIX(*data, before_last_idx, 1)); } /* printf("B L N cp: %ld, %ld, %ld, %f [", before_last_idx, last_idx, next_idx, (float)cp); for (int k=0; k= 2) ? (long int) VECTOR(stack)[j - 2] : -1; } } /* Create result vector */ if (resverts != 0) { igraph_vector_clear(resverts); IGRAPH_CHECK(igraph_vector_append(resverts, &stack)); } if (rescoords != 0) { igraph_matrix_select_rows(data, rescoords, &stack); } /* Free everything */ igraph_vector_destroy(&order); igraph_vector_destroy(&stack); igraph_vector_destroy(&angles); IGRAPH_FINALLY_CLEAN(3); return 0; } static const char* igraph_i_plfit_error_message = 0; static void igraph_i_plfit_error_handler_store(const char *reason, const char *file, int line, int plfit_errno) { IGRAPH_UNUSED(file); IGRAPH_UNUSED(line); IGRAPH_UNUSED(plfit_errno); igraph_i_plfit_error_message = reason; } /** * \ingroup nongraph * \function igraph_power_law_fit * \brief Fits a power-law distribution to a vector of numbers * * This function fits a power-law distribution to a vector containing samples * from a distribution (that is assumed to follow a power-law of course). In * a power-law distribution, it is generally assumed that P(X=x) is * proportional to x-alpha, where x is a positive number and alpha * is greater than 1. In many real-world cases, the power-law behaviour kicks * in only above a threshold value \em xmin. The goal of this functions is to * determine \em alpha if \em xmin is given, or to determine \em xmin and the * corresponding value of \em alpha. * * * The function uses the maximum likelihood principle to determine \em alpha * for a given \em xmin; in other words, the function will return the \em alpha * value for which the probability of drawing the given sample is the highest. * When \em xmin is not given in advance, the algorithm will attempt to find * the optimal \em xmin value for which the p-value of a Kolmogorov-Smirnov * test between the fitted distribution and the original sample is the largest. * The function uses the method of Clauset, Shalizi and Newman to calculate the * parameters of the fitted distribution. See the following reference for * details: * * * Aaron Clauset, Cosma R .Shalizi and Mark E.J. Newman: Power-law * distributions in empirical data. SIAM Review 51(4):661-703, 2009. * * \param data vector containing the samples for which a power-law distribution * is to be fitted. Note that you have to provide the \em samples, * not the probability density function or the cumulative * distribution function. For example, if you wish to fit * a power-law to the degrees of a graph, you can use the output of * \ref igraph_degree directly as an input argument to * \ref igraph_power_law_fit * \param result the result of the fitting algorithm. See \ref igraph_plfit_result_t * for more details. * \param xmin the minimum value in the sample vector where the power-law * behaviour is expected to kick in. Samples smaller than \c xmin * will be ignored by the algorithm. Pass zero here if you want to * include all the samples. If \c xmin is negative, the algorithm * will attempt to determine its best value automatically. * \param force_continuous assume that the samples in the \c data argument come * from a continuous distribution even if the sample vector * contains integer values only (by chance). If this argument is * false, igraph will assume a continuous distribution if at least * one sample is non-integer and assume a discrete distribution * otherwise. * \return Error code: * \c IGRAPH_ENOMEM: not enough memory * \c IGRAPH_EINVAL: one of the arguments is invalid * \c IGRAPH_EOVERFLOW: overflow during the fitting process * \c IGRAPH_EUNDERFLOW: underflow during the fitting process * \c IGRAPH_FAILURE: the underlying algorithm signaled a failure * without returning a more specific error code * * Time complexity: in the continuous case, O(n log(n)) if \c xmin is given. * In the discrete case, the time complexity is dominated by the complexity of * the underlying L-BFGS algorithm that is used to optimize alpha. If \c xmin * is not given, the time complexity is multiplied by the number of unique * samples in the input vector (although it should be faster in practice). * * \example examples/simple/igraph_power_law_fit.c */ int igraph_power_law_fit(const igraph_vector_t* data, igraph_plfit_result_t* result, igraph_real_t xmin, igraph_bool_t force_continuous) { plfit_error_handler_t* plfit_stored_error_handler; plfit_result_t plfit_result; plfit_continuous_options_t cont_options; plfit_discrete_options_t disc_options; igraph_bool_t discrete = force_continuous ? 0 : 1; igraph_bool_t finite_size_correction; int retval; size_t i, n; n = (size_t) igraph_vector_size(data); finite_size_correction = (n < 50); if (discrete) { /* Does the vector contain discrete values only? */ for (i = 0; i < n; i++) { if ((long int)(VECTOR(*data)[i]) != VECTOR(*data)[i]) { discrete = 0; break; } } } RNG_BEGIN(); plfit_stored_error_handler = plfit_set_error_handler(igraph_i_plfit_error_handler_store); if (discrete) { plfit_discrete_options_init(&disc_options); /* TODO: approximation method should be switched to PLFIT_P_VALUE_EXACT in igraph 0.9 */ disc_options.p_value_method = PLFIT_P_VALUE_APPROXIMATE; disc_options.finite_size_correction = (plfit_bool_t) finite_size_correction; if (xmin >= 0) { retval = plfit_estimate_alpha_discrete(VECTOR(*data), n, xmin, &disc_options, &plfit_result); } else { retval = plfit_discrete(VECTOR(*data), n, &disc_options, &plfit_result); } } else { plfit_continuous_options_init(&cont_options); /* TODO: approximation method should be switched to PLFIT_P_VALUE_EXACT in igraph 0.9 */ cont_options.p_value_method = PLFIT_P_VALUE_APPROXIMATE; /* TODO: xmin method should be switched to PLFIT_STRATIFIED_SAMPLING in igraph 0.9 */ cont_options.xmin_method = PLFIT_GSS_OR_LINEAR; cont_options.finite_size_correction = (plfit_bool_t) finite_size_correction; if (xmin >= 0) { retval = plfit_estimate_alpha_continuous(VECTOR(*data), n, xmin, &cont_options, &plfit_result); } else { retval = plfit_continuous(VECTOR(*data), n, &cont_options, &plfit_result); } } plfit_set_error_handler(plfit_stored_error_handler); RNG_END(); switch (retval) { case PLFIT_FAILURE: IGRAPH_ERROR(igraph_i_plfit_error_message, IGRAPH_FAILURE); break; case PLFIT_EINVAL: IGRAPH_ERROR(igraph_i_plfit_error_message, IGRAPH_EINVAL); break; case PLFIT_UNDRFLOW: IGRAPH_ERROR(igraph_i_plfit_error_message, IGRAPH_EUNDERFLOW); break; case PLFIT_OVERFLOW: IGRAPH_ERROR(igraph_i_plfit_error_message, IGRAPH_EOVERFLOW); break; case PLFIT_ENOMEM: IGRAPH_ERROR(igraph_i_plfit_error_message, IGRAPH_ENOMEM); break; default: break; } if (result) { result->continuous = !discrete; result->alpha = plfit_result.alpha; result->xmin = plfit_result.xmin; result->L = plfit_result.L; result->D = plfit_result.D; result->p = plfit_result.p; } return 0; } leidenbase/src/core/misc/microscopic_update.c0000644000176200001440000016530214447675375021074 0ustar liggesusers/* -*- mode: C -*- */ /* Microscopic update rules for dealing with agent-level strategy revision. Copyright (C) 2011 Minh Van Nguyen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_microscopic_update.h" #include "igraph_iterators.h" #include "igraph_interface.h" #include "igraph_random.h" #include "igraph_error.h" /* * Internal use only. * Compute the cumulative proportionate values of a vector. The vector is * assumed to hold values associated with edges. * * \param graph The graph object representing the game network. No error * checks will be performed on this graph. You are responsible for * ensuring that this is a valid graph for the particular * microscopic update rule at hand. * \param U A vector of edge values for which we want to compute cumulative * proportionate values. So U[i] is the value of the edge with ID i. * With a local perspective, we would only compute cumulative * proportionate values for some combination of U. This vector could * be, for example, a vector of weights for edges in \p graph. It is * assumed that each value of U is nonnegative; it is your * responsibility to ensure this. Furthermore, this vector must have a * length the same as the number of edges in \p graph; you are * responsible for ensuring this condition holds. * \param V Pointer to an initialized vector. The cumulative proportionate * values will be computed and stored here. No error checks will be * performed on this parameter. * \param islocal Boolean; this flag controls which perspective to use. If * true then we use the local perspective; otherwise we use the global * perspective. In the context of this function, the local perspective * for a vertex v consists of all edges incident on v. In contrast, the * global perspective for v consists of all edges in \p graph. * \param vid The vertex to use if we are considering a local perspective, * i.e. if \p islocal is true. This vertex will be ignored if * \p islocal is false. That is, if \p islocal is false then it is safe * pass the value -1 here. On the other hand, if \p islocal is true then * it is assumed that this is indeed a vertex of \p graph. * \param mode Defines the sort of neighbourhood to consider for \p vid. This * is only relevant if we are considering the local perspective, i.e. if * \p islocal is true. If we are considering the global perspective, * then this parameter would be ignored. In other words, if \p islocal * is false then it is safe to pass the value \p IGRAPH_ALL here. If * \p graph is undirected, then we use all the immediate neighbours of * \p vid. Thus if you know that \p graph is undirected, then it is * safe to pass the value \p IGRAPH_ALL here. Supported values are: * \clist * \cli IGRAPH_OUT * Use the out-neighbours of \p vid. This option is only relevant * when \p graph is a digraph and we are considering the local * perspective. * \cli IGRAPH_IN * Use the in-neighbours of \p vid. Again this option is only relevant * when \p graph is a directed graph and we are considering the local * perspective. * \cli IGRAPH_ALL * Use both the in- and out-neighbours of \p vid. This option is only * relevant if \p graph is a digraph and we are considering a local * perspective. Also use this value if \p graph is undirected or we * are considering the global perspective. * \endclist * \return Codes: * \clist * \cli IGRAPH_EINVAL * This error code is returned in the following case: The vector * \p U, or some combination of its values, sums to zero. * \cli IGRAPH_SUCCESS * This signal is returned if the cumulative proportionate values * were successfully computed. * \endclist * * Time complexity: O(2n) where n is the number of edges in the perspective * of \p vid. */ static int igraph_i_ecumulative_proportionate_values(const igraph_t *graph, const igraph_vector_t *U, igraph_vector_t *V, igraph_bool_t islocal, igraph_integer_t vid, igraph_neimode_t mode) { igraph_eit_t A; /* all edges in v's perspective */ igraph_es_t es; igraph_integer_t e; igraph_real_t C; /* cumulative probability */ igraph_real_t P; /* probability */ igraph_real_t S; /* sum of values */ long int i; /* Set the perspective. Let v be the vertex under consideration. The local */ /* perspective for v consists of edges incident on it. In contrast, the */ /* global perspective for v are all edges in the given graph. Hence in the */ /* global perspective, we will ignore the given vertex and the given */ /* neighbourhood type, but instead consider all edges in the given graph. */ if (islocal) { IGRAPH_CHECK(igraph_es_incident(&es, vid, mode)); } else { IGRAPH_CHECK(igraph_es_all(&es, IGRAPH_EDGEORDER_ID)); } IGRAPH_FINALLY(igraph_es_destroy, &es); /* Sum up all the values of vector U in the perspective for v. This sum */ /* will be used in normalizing each value. */ /* NOTE: Here we assume that each value to be summed is nonnegative, */ /* and at least one of the values is nonzero. The behaviour resulting */ /* from all values being zero would be division by zero later on when */ /* we normalize each value. We check to see that the values sum to zero. */ /* NOTE: In this function, the order in which we iterate through the */ /* edges of interest should be the same as the order in which we do so */ /* in the caller function. If the caller function doesn't care about the */ /* order of values in the resulting vector V, then there's no need to take */ /* special notice of that order. But in some cases the order of values in */ /* V is taken into account, for example, in the Moran process. */ S = 0.0; IGRAPH_CHECK(igraph_eit_create(graph, es, &A)); IGRAPH_FINALLY(igraph_eit_destroy, &A); while (!IGRAPH_EIT_END(A)) { e = (igraph_integer_t)IGRAPH_EIT_GET(A); S += (igraph_real_t)VECTOR(*U)[e]; IGRAPH_EIT_NEXT(A); } /* avoid division by zero later on */ if (S == (igraph_real_t)0.0) { igraph_eit_destroy(&A); igraph_es_destroy(&es); IGRAPH_FINALLY_CLEAN(2); IGRAPH_ERROR("Vector of values sums to zero", IGRAPH_EINVAL); } /* Get cumulative probability and relative value for each edge in the */ /* perspective of v. The vector V holds the cumulative proportionate */ /* values of all edges in v's perspective. The value V[0] is the */ /* cumulative proportionate value of the first edge in the edge iterator */ /* A. The value V[1] is the cumulative proportionate value of the second */ /* edge in the iterator A. And so on. */ C = 0.0; i = 0; IGRAPH_EIT_RESET(A); IGRAPH_CHECK(igraph_vector_resize(V, IGRAPH_EIT_SIZE(A))); while (!IGRAPH_EIT_END(A)) { e = (igraph_integer_t)IGRAPH_EIT_GET(A); /* NOTE: Beware of division by zero here. This can happen if the vector */ /* of values, or the combination of interest, sums to zero. */ P = (igraph_real_t)VECTOR(*U)[e] / S; C += P; VECTOR(*V)[i] = C; i++; IGRAPH_EIT_NEXT(A); } igraph_eit_destroy(&A); igraph_es_destroy(&es); /* Pop A and es from the finally stack -- that's three items */ IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /* * Internal use only. * Compute the cumulative proportionate values of a vector. The vector is * assumed to hold values associated with vertices. * * \param graph The graph object representing the game network. No error * checks will be performed on this graph. You are responsible for * ensuring that this is a valid graph for the particular * microscopic update rule at hand. * \param U A vector of vertex values for which we want to compute cumulative * proportionate values. The vector could be, for example, a vector of * fitness for vertices of \p graph. It is assumed that each value of U * is nonnegative; it is your responsibility to ensure this. Also U, or * a combination of interest, is assumed to sum to a positive value; * this condition will be checked. * \param V Pointer to an initialized vector. The cumulative proportionate * values will be computed and stored here. No error checks will be * performed on this parameter. * \param islocal Boolean; this flag controls which perspective to use. If * true then we use the local perspective; otherwise we use the global * perspective. The local perspective for a vertex v is the set of all * immediate neighbours of v. In contrast, the global perspective * for v is the vertex set of \p graph. * \param vid The vertex to use if we are considering a local perspective, * i.e. if \p islocal is true. This vertex will be ignored if * \p islocal is false. That is, if \p islocal is false then it is safe * pass the value -1 here. On the other hand, if \p islocal is true then * it is assumed that this is indeed a vertex of \p graph. * \param mode Defines the sort of neighbourhood to consider for \p vid. This * is only relevant if we are considering the local perspective, i.e. if * \p islocal is true. If we are considering the global perspective, * then this parameter would be ignored. In other words, if \p islocal * is false then it is safe to pass the value \p IGRAPH_ALL here. If * \p graph is undirected, then we use all the immediate neighbours of * \p vid. Thus if you know that \p graph is undirected, then it is * safe to pass the value \p IGRAPH_ALL here. Supported values are: * \clist * \cli IGRAPH_OUT * Use the out-neighbours of \p vid. This option is only relevant * when \p graph is a digraph and we are considering the local * perspective. * \cli IGRAPH_IN * Use the in-neighbours of \p vid. Again this option is only relevant * when \p graph is a directed graph and we are considering the local * perspective. * \cli IGRAPH_ALL * Use both the in- and out-neighbours of \p vid. This option is only * relevant if \p graph is a digraph and we are considering a local * perspective. Also use this value if \p graph is undirected or we * are considering the global perspective. * \endclist * \return Codes: * \clist * \cli IGRAPH_EINVAL * This error code is returned in the following case: The vector * \p U, or some combination of its values, sums to zero. * \cli IGRAPH_SUCCESS * This signal is returned if the cumulative proportionate values * were successfully computed. * \endclist * * Time complexity: O(2n) where n is the number of vertices in the * perspective of vid. */ static int igraph_i_vcumulative_proportionate_values(const igraph_t *graph, const igraph_vector_t *U, igraph_vector_t *V, igraph_bool_t islocal, igraph_integer_t vid, igraph_neimode_t mode) { igraph_integer_t v; igraph_real_t C; /* cumulative probability */ igraph_real_t P; /* probability */ igraph_real_t S; /* sum of values */ igraph_vit_t A; /* all vertices in v's perspective */ igraph_vs_t vs; long int i; /* Set the perspective. Let v be the vertex under consideration; it might */ /* be that we want to update v's strategy. The local perspective for v */ /* consists of its immediate neighbours. In contrast, the global */ /* perspective for v are all the vertices in the given graph. Hence in the */ /* global perspective, we will ignore the given vertex and the given */ /* neighbourhood type, but instead consider all vertices in the given */ /* graph. */ if (islocal) { IGRAPH_CHECK(igraph_vs_adj(&vs, vid, mode)); } else { IGRAPH_CHECK(igraph_vs_all(&vs)); } IGRAPH_FINALLY(igraph_vs_destroy, &vs); /* Sum up all the values of vector U in the perspective for v. This */ /* sum will be used in normalizing each value. If we are using a local */ /* perspective, then we also need to consider the quantity of v in */ /* computing the sum. */ /* NOTE: Here we assume that each value to be summed is nonnegative, */ /* and at least one of the values is nonzero. The behaviour resulting */ /* from all values being zero would be division by zero later on when */ /* we normalize each value. We check to see that the values sum to zero. */ /* NOTE: In this function, the order in which we iterate through the */ /* vertices of interest should be the same as the order in which we do so */ /* in the caller function. If the caller function doesn't care about the */ /* order of values in the resulting vector V, then there's no need to take */ /* special notice of that order. But in some cases the order of values in */ /* V is taken into account, for example, in roulette wheel selection. */ S = 0.0; IGRAPH_CHECK(igraph_vit_create(graph, vs, &A)); IGRAPH_FINALLY(igraph_vit_destroy, &A); while (!IGRAPH_VIT_END(A)) { v = (igraph_integer_t)IGRAPH_VIT_GET(A); S += (igraph_real_t)VECTOR(*U)[v]; IGRAPH_VIT_NEXT(A); } if (islocal) { S += (igraph_real_t)VECTOR(*U)[vid]; } /* avoid division by zero later on */ if (S == (igraph_real_t)0.0) { igraph_vit_destroy(&A); igraph_vs_destroy(&vs); IGRAPH_FINALLY_CLEAN(2); IGRAPH_ERROR("Vector of values sums to zero", IGRAPH_EINVAL); } /* Get cumulative probability and relative value for each vertex in the */ /* perspective of v. The vector V holds the cumulative proportionate */ /* values of all vertices in v's perspective. The value V[0] is the */ /* cumulative proportionate value of the first vertex in the vertex */ /* iterator A. The value V[1] is the cumulative proportionate value of */ /* the second vertex in the iterator A. And so on. If we are using the */ /* local perspective, then we also need to consider the cumulative */ /* proportionate value of v. In the case of the local perspective, we */ /* don't need to compute and store v's cumulative proportionate value, */ /* but we pretend that such value is appended to the vector V. */ C = 0.0; i = 0; IGRAPH_VIT_RESET(A); IGRAPH_CHECK(igraph_vector_resize(V, IGRAPH_VIT_SIZE(A))); while (!IGRAPH_VIT_END(A)) { v = (igraph_integer_t)IGRAPH_VIT_GET(A); /* NOTE: Beware of division by zero here. This can happen if the vector */ /* of values, or a combination of interest, sums to zero. */ P = (igraph_real_t)VECTOR(*U)[v] / S; C += P; VECTOR(*V)[i] = C; i++; IGRAPH_VIT_NEXT(A); } igraph_vit_destroy(&A); igraph_vs_destroy(&vs); /* Pop A and vs from the finally stack -- that's two items */ IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /* * Internal use only. * A set of standard tests to be performed prior to strategy updates. The * tests contained in this function are common to many strategy revision * functions in this file. This function is meant to be invoked from within * a specific strategy update function in order to perform certain common * tests, including sanity checks and conditions under which no strategy * updates are necessary. * * \param graph The graph object representing the game network. This cannot * be the empty or trivial graph, but must have at least two vertices * and one edge. If \p graph has one vertex, then no strategy update * would take place. Furthermore, if \p graph has at least two vertices * but zero edges, then strategy update would also not take place. * \param vid The vertex whose strategy is to be updated. It is assumed that * \p vid represents a vertex in \p graph. No checking is performed and * it is your responsibility to ensure that \p vid is indeed a vertex * of \p graph. If an isolated vertex is provided, i.e. the input * vertex has degree 0, then no strategy update would take place and * \p vid would retain its current strategy. Strategy update would also * not take place if the local neighbourhood of \p vid are its * in-neighbours (respectively out-neighbours), but \p vid has zero * in-neighbours (respectively out-neighbours). Loops are ignored in * computing the degree (in, out, all) of \p vid. * \param quantities A vector of quantities providing the quantity of each * vertex in \p graph. Think of each entry of the vector as being * generated by a function such as the fitness function for the game. * So if the vector represents fitness quantities, then each vector * entry is the fitness of some vertex. The length of this vector must * be the same as the number of vertices in the vertex set of \p graph. * \param strategies A vector of the current strategies for the vertex * population. Each strategy is identified with a nonnegative integer, * whose interpretation depends on the payoff matrix of the game. * Generally we use the strategy ID as a row or column index of the * payoff matrix. The length of this vector must be the same as the * number of vertices in the vertex set of \p graph. * \param mode Defines the sort of neighbourhood to consider for \p vid. If * \p graph is undirected, then we use all the immediate neighbours of * \p vid. Thus if you know that \p graph is undirected, then it is safe * to pass the value \p IGRAPH_ALL here. Supported values are: * \clist * \cli IGRAPH_OUT * Use the out-neighbours of \p vid. This option is only relevant * when \p graph is a directed graph. * \cli IGRAPH_IN * Use the in-neighbours of \p vid. Again this option is only relevant * when \p graph is a directed graph. * \cli IGRAPH_ALL * Use both the in- and out-neighbours of \p vid. This option is only * relevant if \p graph is a digraph. Also use this value if * \p graph is undirected. * \endclist * \param updates Boolean; at the end of this test suite, this flag * indicates whether to proceed with strategy revision. If true then * strategy revision should proceed; otherwise there is no need to * continue with revising a vertex's strategy. A caller function that * invokes this function would use the value of \p updates to * determine whether to proceed with strategy revision. * \param islocal Boolean; this flag controls which perspective to use. If * true then we use the local perspective; otherwise we use the global * perspective. The local perspective for \p vid is the set of all * immediate neighbours of \p vid. In contrast, the global perspective * for \p vid is the vertex set of \p graph. * \return Codes: * \clist * \cli IGRAPH_EINVAL * This error code is returned in each of the following cases: * (1) Any of the parameters \p graph, \p quantities, or * \p strategies is a null pointer. (2) The vector \p quantities * or \p strategies has a length different from the number of * vertices in \p graph. (3) The parameter \p graph is the empty * or null graph, i.e. the graph with zero vertices and edges. * \cli IGRAPH_SUCCESS * This signal is returned if no errors were raised. You should use * the value of the boolean \p updates to decide whether to go * ahead with updating a vertex's strategy. * \endclist */ static int igraph_i_microscopic_standard_tests(const igraph_t *graph, igraph_integer_t vid, const igraph_vector_t *quantities, const igraph_vector_t *strategies, igraph_neimode_t mode, igraph_bool_t *updates, igraph_bool_t islocal) { igraph_integer_t nvert; igraph_vector_t degv; *updates = 1; /* sanity checks */ if (graph == NULL) { IGRAPH_ERROR("Graph is a null pointer", IGRAPH_EINVAL); } if (quantities == NULL) { IGRAPH_ERROR("Quantities vector is a null pointer", IGRAPH_EINVAL); } if (strategies == NULL) { IGRAPH_ERROR("Strategies vector is a null pointer", IGRAPH_EINVAL); } /* the empty graph */ nvert = igraph_vcount(graph); if (nvert < 1) { IGRAPH_ERROR("Graph cannot be the empty graph", IGRAPH_EINVAL); } /* invalid vector length */ if (nvert != (igraph_integer_t)igraph_vector_size(quantities)) { IGRAPH_ERROR("Size of quantities vector different from number of vertices", IGRAPH_EINVAL); } if (nvert != (igraph_integer_t)igraph_vector_size(strategies)) { IGRAPH_ERROR("Size of strategies vector different from number of vertices", IGRAPH_EINVAL); } /* Various conditions under which no strategy updates will take place. That * is, the vertex retains its current strategy. */ /* given graph has < 2 vertices */ if (nvert < 2) { *updates = 0; } /* graph has >= 2 vertices, but no edges */ if (igraph_ecount(graph) < 1) { *updates = 0; } /* Test for vertex isolation, depending on the perspective given. For * undirected graphs, a given vertex v is isolated if its degree is zero. * If we are considering in-neighbours (respectively out-neighbours), then * we say that v is isolated if its in-degree (respectively out-degree) is * zero. In general, this vertex isolation test is only relevant if we are * using a local perspective, i.e. if we only consider the immediate * neighbours (local perspective) of v as opposed to all vertices in the * vertex set of the graph (global perspective). */ if (islocal) { /* Moving on ahead with vertex isolation test, since local perspective */ /* is requested. */ IGRAPH_VECTOR_INIT_FINALLY(°v, 1); IGRAPH_CHECK(igraph_degree(graph, °v, igraph_vss_1(vid), mode, IGRAPH_NO_LOOPS)); if (VECTOR(degv)[0] < 1) { *updates = 0; } igraph_vector_destroy(°v); IGRAPH_FINALLY_CLEAN(1); } return IGRAPH_SUCCESS; } /** * \ingroup spatialgames * \function igraph_deterministic_optimal_imitation * \brief Adopt a strategy via deterministic optimal imitation. * * A simple deterministic imitation strategy where a vertex revises its * strategy to that which yields a local optimal. Here "local" is with * respect to the immediate neighbours of the vertex. The vertex retains its * current strategy where this strategy yields a locally optimal quantity. * The quantity in this case could be a measure such as fitness. * * \param graph The graph object representing the game network. This cannot * be the empty or trivial graph, but must have at least two vertices * and one edge. If \p graph has one vertex, then no strategy update * would take place. Furthermore, if \p graph has at least two vertices * but zero edges, then strategy update would also not take place. * \param vid The vertex whose strategy is to be updated. It is assumed that * \p vid represents a vertex in \p graph. No checking is performed and * it is your responsibility to ensure that \p vid is indeed a vertex * of \p graph. If an isolated vertex is provided, i.e. the input * vertex has degree 0, then no strategy update would take place and * \p vid would retain its current strategy. Strategy update would also * not take place if the local neighbourhood of \p vid are its * in-neighbours (respectively out-neighbours), but \p vid has zero * in-neighbours (respectively out-neighbours). Loops are ignored in * computing the degree (in, out, all) of \p vid. * \param optimality Logical; controls the type of optimality to be used. * Supported values are: * \clist * \cli IGRAPH_MAXIMUM * Use maximum deterministic imitation, where the strategy of the * vertex with maximum quantity (e.g. fitness) would be adopted. We * update the strategy of \p vid to that which yields a local * maximum. * \cli IGRAPH_MINIMUM * Use minimum deterministic imitation. That is, the strategy of the * vertex with minimum quantity would be imitated. In other words, * update to the strategy that yields a local minimum. * \endclist * \param quantities A vector of quantities providing the quantity of each * vertex in \p graph. Think of each entry of the vector as being * generated by a function such as the fitness function for the game. * So if the vector represents fitness quantities, then each vector * entry is the fitness of some vertex. The length of this vector must * be the same as the number of vertices in the vertex set of \p graph. * \param strategies A vector of the current strategies for the vertex * population. The updated strategy for \p vid would be stored here. * Each strategy is identified with a nonnegative integer, whose * interpretation depends on the payoff matrix of the game. Generally * we use the strategy ID as a row or column index of the payoff * matrix. The length of this vector must be the same as the number of * vertices in the vertex set of \p graph. * \param mode Defines the sort of neighbourhood to consider for \p vid. If * \p graph is undirected, then we use all the immediate neighbours of * \p vid. Thus if you know that \p graph is undirected, then it is safe * to pass the value \p IGRAPH_ALL here. Supported values are: * \clist * \cli IGRAPH_OUT * Use the out-neighbours of \p vid. This option is only relevant * when \p graph is a directed graph. * \cli IGRAPH_IN * Use the in-neighbours of \p vid. Again this option is only relevant * when \p graph is a directed graph. * \cli IGRAPH_ALL * Use both the in- and out-neighbours of \p vid. This option is only * relevant if \p graph is a digraph. Also use this value if * \p graph is undirected. * \endclist * \return The error code \p IGRAPH_EINVAL is returned in each of the * following cases: (1) Any of the parameters \p graph, \p quantities, * or \p strategies is a null pointer. (2) The vector \p quantities * or \p strategies has a length different from the number of vertices * in \p graph. (3) The parameter \p graph is the empty or null graph, * i.e. the graph with zero vertices and edges. * * Time complexity: O(2d), where d is the degree of the vertex \p vid. * * \example examples/simple/igraph_deterministic_optimal_imitation.c */ int igraph_deterministic_optimal_imitation(const igraph_t *graph, igraph_integer_t vid, igraph_optimal_t optimality, const igraph_vector_t *quantities, igraph_vector_t *strategies, igraph_neimode_t mode) { igraph_integer_t i, k, v; igraph_real_t q; igraph_vector_t adj; igraph_bool_t updates; IGRAPH_CHECK(igraph_i_microscopic_standard_tests(graph, vid, quantities, strategies, mode, &updates, /*is local?*/ 1)); if (!updates) { return IGRAPH_SUCCESS; /* Nothing to do */ } /* Choose a locally optimal strategy to imitate. This can be either maximum * or minimum deterministic imitation. By now we know that the given vertex v * has degree >= 1 and at least 1 edge. Then within its immediate * neighbourhood adj(v) and including v itself, there exists a vertex whose * strategy yields a local optimal quantity. */ /* Random permutation of adj(v). This ensures that if there are multiple */ /* candidates with an optimal strategy, then we choose one such candidate */ /* at random. */ IGRAPH_VECTOR_INIT_FINALLY(&adj, 0); IGRAPH_CHECK(igraph_neighbors(graph, &adj, vid, mode)); IGRAPH_CHECK(igraph_vector_shuffle(&adj)); /* maximum deterministic imitation */ i = vid; q = (igraph_real_t)VECTOR(*quantities)[vid]; if (optimality == IGRAPH_MAXIMUM) { for (k = 0; k < igraph_vector_size(&adj); k++) { v = (igraph_integer_t) VECTOR(adj)[k]; if ((igraph_real_t)VECTOR(*quantities)[v] > q) { i = v; q = (igraph_real_t)VECTOR(*quantities)[v]; } } } else { /* minimum deterministic imitation */ for (k = 0; k < igraph_vector_size(&adj); k++) { v = (igraph_integer_t) VECTOR(adj)[k]; if ((igraph_real_t)VECTOR(*quantities)[v] < q) { i = v; q = (igraph_real_t)VECTOR(*quantities)[v]; } } } /* Now i is a vertex with a locally optimal quantity, the value of which */ /* is q. Update the strategy of vid to that of i. */ VECTOR(*strategies)[vid] = VECTOR(*strategies)[i]; igraph_vector_destroy(&adj); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \ingroup spatialgames * \function igraph_moran_process * \brief The Moran process in a network setting. * * This is an extension of the classic Moran process to a network setting. * The Moran process is a model of haploid (asexual) reproduction within a * population having a fixed size. In the network setting, the Moran process * operates on a weighted graph. At each time step a vertex a is chosen for * reproduction and another vertex b is chosen for death. Vertex a gives birth * to an identical clone c, which replaces b. Vertex c is a clone of a in that * c inherits both the current quantity (e.g. fitness) and current strategy * of a. * * * The graph G representing the game network is assumed to be simple, * i.e. free of loops and without multiple edges. If, on the other hand, G has * a loop incident on some vertex v, then it is possible that when v is chosen * for reproduction it would forgo this opportunity. In particular, when v is * chosen for reproduction and v is also chosen for death, the clone of v * would be v itself with its current vertex ID. In effect v forgoes its * chance for reproduction. * * \param graph The graph object representing the game network. This cannot * be the empty or trivial graph, but must have at least two vertices * and one edge. The Moran process will not take place in each of the * following cases: (1) If \p graph has one vertex. (2) If \p graph has * at least two vertices but zero edges. * \param weights A vector of all edge weights for \p graph. Thus weights[i] * means the weight of the edge with edge ID i. For the purpose of the * Moran process, each weight is assumed to be positive; it is your * responsibility to ensure this condition holds. The length of this * vector must be the same as the number of edges in \p graph. * \param quantities A vector of quantities providing the quantity of each * vertex in \p graph. The quantity of the new clone will be stored * here. Think of each entry of the vector as being generated by a * function such as the fitness function for the game. So if the vector * represents fitness quantities, then each vector entry is the fitness * of some vertex. The length of this vector must be the same as the * number of vertices in the vertex set of \p graph. For the purpose of * the Moran process, each vector entry is assumed to be nonnegative; * no checks will be performed for this. It is your responsibility to * ensure that at least one entry is positive. Furthermore, this vector * cannot be a vector of zeros; this condition will be checked. * \param strategies A vector of the current strategies for the vertex * population. The strategy of the new clone will be stored here. Each * strategy is identified with a nonnegative integer, whose * interpretation depends on the payoff matrix of the game. Generally * we use the strategy ID as a row or column index of the payoff * matrix. The length of this vector must be the same as the number of * vertices in the vertex set of \p graph. * \param mode Defines the sort of neighbourhood to consider for the vertex a * chosen for reproduction. This is only relevant if \p graph is * directed. If \p graph is undirected, then it is safe to pass the * value \p IGRAPH_ALL here. Supported values are: * \clist * \cli IGRAPH_OUT * Use the out-neighbours of a. This option is only relevant when * \p graph is directed. * \cli IGRAPH_IN * Use the in-neighbours of a. Again this option is only relevant * when \p graph is directed. * \cli IGRAPH_ALL * Use both the in- and out-neighbours of a. This option is only * relevant if \p graph is directed. Also use this value if * \p graph is undirected. * \endclist * \return The error code \p IGRAPH_EINVAL is returned in each of the following * cases: (1) Any of the parameters \p graph, \p weights, * \p quantities or \p strategies is a null pointer. (2) The vector * \p quantities or \p strategies has a length different from the * number of vertices in \p graph. (3) The vector \p weights has a * length different from the number of edges in \p graph. (4) The * parameter \p graph is the empty or null graph, i.e. the graph with * zero vertices and edges. (5) The vector \p weights, or the * combination of interest, sums to zero. (6) The vector \p quantities, * or the combination of interest, sums to zero. * * Time complexity: depends on the random number generator, but is usually * O(n) where n is the number of vertices in \p graph. * * * References: * \clist * \cli (Lieberman et al. 2005) * E. Lieberman, C. Hauert, and M. A. Nowak. Evolutionary dynamics on * graphs. \emb Nature, \eme 433(7023):312--316, 2005. * \cli (Moran 1958) * P. A. P. Moran. Random processes in genetics. \emb Mathematical * Proceedings of the Cambridge Philosophical Society, \eme 54(1):60--71, * 1958. * \endclist */ int igraph_moran_process(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_t *quantities, igraph_vector_t *strategies, igraph_neimode_t mode) { igraph_bool_t updates; igraph_integer_t a = -1; /* vertex chosen for reproduction */ igraph_integer_t b = -1; /* vertex chosen for death */ igraph_integer_t e, nedge, u, v; igraph_real_t r; /* random number */ igraph_vector_t deg; igraph_vector_t V; /* vector of cumulative proportionate values */ igraph_vit_t vA; /* vertex list */ igraph_eit_t eA; /* edge list */ igraph_vs_t vs; igraph_es_t es; long int i; /* don't test for vertex isolation, hence vid = -1 and islocal = 0 */ IGRAPH_CHECK(igraph_i_microscopic_standard_tests(graph, /*vid*/ -1, quantities, strategies, mode, &updates, /*is local?*/ 0)); if (!updates) { return IGRAPH_SUCCESS; /* nothing more to do */ } if (weights == NULL) { IGRAPH_ERROR("Weights vector is a null pointer", IGRAPH_EINVAL); } nedge = igraph_ecount(graph); if (nedge != (igraph_integer_t)igraph_vector_size(weights)) { IGRAPH_ERROR("Size of weights vector different from number of edges", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&V, 0); /* Cumulative proportionate quantities. We are using the global */ /* perspective, hence islocal = 0, vid = -1 and mode = IGRAPH_ALL. */ IGRAPH_CHECK(igraph_i_vcumulative_proportionate_values(graph, quantities, &V, /*is local?*/ 0, /*vid*/ -1, /*mode*/ IGRAPH_ALL)); /* Choose a vertex for reproduction from among all vertices in the graph. */ /* The vertex is chosen proportionate to its quantity and such that its */ /* degree is >= 1. In case we are considering in-neighbours (respectively */ /* out-neighbours), the chosen vertex must have in-degree (respectively */ /* out-degree) >= 1. All loops will be ignored. At this point, we know */ /* that the graph has at least one edge, which may be directed or not. */ /* Furthermore the quantities of all vertices sum to a positive value. */ /* Hence at least one vertex will be chosen for reproduction. */ IGRAPH_CHECK(igraph_vs_all(&vs)); IGRAPH_FINALLY(igraph_vs_destroy, &vs); IGRAPH_CHECK(igraph_vit_create(graph, vs, &vA)); IGRAPH_FINALLY(igraph_vit_destroy, &vA); RNG_BEGIN(); r = RNG_UNIF01(); RNG_END(); i = 0; IGRAPH_VECTOR_INIT_FINALLY(°, 1); while (!IGRAPH_VIT_END(vA)) { u = (igraph_integer_t)IGRAPH_VIT_GET(vA); IGRAPH_CHECK(igraph_degree(graph, °, igraph_vss_1(u), mode, IGRAPH_NO_LOOPS)); if (VECTOR(deg)[0] < 1) { i++; IGRAPH_VIT_NEXT(vA); continue; } if (r <= VECTOR(V)[i]) { /* we have found our candidate vertex for reproduction */ a = u; break; } i++; IGRAPH_VIT_NEXT(vA); } /* By now we should have chosen a vertex for reproduction. Check this. */ IGRAPH_ASSERT(a >= 0); /* Cumulative proportionate weights. We are using the local perspective */ /* with respect to vertex a, which has been chosen for reproduction. */ /* The degree of a is deg(a) >= 1 with respect to the mode "mode", which */ /* can flag either the in-degree, out-degree or all degree of a. But it */ /* still might happen that the edge weights of interest would sum to zero. */ /* An error would be raised in that case. */ IGRAPH_CHECK(igraph_i_ecumulative_proportionate_values(graph, weights, &V, /*is local?*/ 1, /*vertex*/ a, mode)); /* Choose a vertex for death from among all vertices in a's perspective. */ /* Let E be all the edges in the perspective of a. If (u,v) \in E is any */ /* such edge, then we have a = u or a = v. That is, any edge in E has a */ /* for one of its endpoints. As G is assumed to be a simple graph, then */ /* exactly one of u or v is the vertex a. Without loss of generality, we */ /* assume that each edge in E has the form (a, v_i). Then the vertex v_j */ /* chosen for death is chosen proportionate to the weight of the edge */ /* (a, v_j). */ IGRAPH_CHECK(igraph_es_incident(&es, a, mode)); IGRAPH_FINALLY(igraph_es_destroy, &es); IGRAPH_CHECK(igraph_eit_create(graph, es, &eA)); IGRAPH_FINALLY(igraph_eit_destroy, &eA); RNG_BEGIN(); r = RNG_UNIF01(); RNG_END(); i = 0; while (!IGRAPH_EIT_END(eA)) { e = (igraph_integer_t)IGRAPH_EIT_GET(eA); if (r <= VECTOR(V)[i]) { /* We have found our candidate vertex for death; call this vertex b. */ /* As G is simple, then a =/= b. Check the latter condition. */ IGRAPH_CHECK(igraph_edge(graph, /*edge ID*/ e, /*tail vertex*/ &u, /*head vertex*/ &v)); if (a == u) { b = v; } else { b = u; } IGRAPH_ASSERT(a != b); /* always true if G is simple */ break; } i++; IGRAPH_EIT_NEXT(eA); } /* By now a vertex a is chosen for reproduction and a vertex b is chosen */ /* for death. Check that b has indeed been chosen. Clone vertex a and kill */ /* vertex b. Let the clone c have the vertex ID of b, and the strategy and */ /* quantity of a. */ IGRAPH_ASSERT(b >= 0); VECTOR(*quantities)[b] = VECTOR(*quantities)[a]; VECTOR(*strategies)[b] = VECTOR(*strategies)[a]; igraph_eit_destroy(&eA); igraph_es_destroy(&es); igraph_vector_destroy(°); igraph_vit_destroy(&vA); igraph_vs_destroy(&vs); igraph_vector_destroy(&V); IGRAPH_FINALLY_CLEAN(6); return IGRAPH_SUCCESS; } /** * \ingroup spatialgames * \function igraph_roulette_wheel_imitation * \brief Adopt a strategy via roulette wheel selection. * * A simple stochastic imitation strategy where a vertex revises its * strategy to that of a vertex u chosen proportionate to u's quantity * (e.g. fitness). This is a special case of stochastic imitation, where a * candidate is not chosen uniformly at random but proportionate to its * quantity. * * \param graph The graph object representing the game network. This cannot * be the empty or trivial graph, but must have at least two vertices * and one edge. If \p graph has one vertex, then no strategy update * would take place. Furthermore, if \p graph has at least two vertices * but zero edges, then strategy update would also not take place. * \param vid The vertex whose strategy is to be updated. It is assumed that * \p vid represents a vertex in \p graph. No checking is performed and * it is your responsibility to ensure that \p vid is indeed a vertex * of \p graph. If an isolated vertex is provided, i.e. the input * vertex has degree 0, then no strategy update would take place and * \p vid would retain its current strategy. Strategy update would also * not take place if the local neighbourhood of \p vid are its * in-neighbours (respectively out-neighbours), but \p vid has zero * in-neighbours (respectively out-neighbours). Loops are ignored in * computing the degree (in, out, all) of \p vid. * \param islocal Boolean; this flag controls which perspective to use in * computing the relative quantity. If true then we use the local * perspective; otherwise we use the global perspective. The local * perspective for \p vid is the set of all immediate neighbours of * \p vid. In contrast, the global perspective for \p vid is the * vertex set of \p graph. * \param quantities A vector of quantities providing the quantity of each * vertex in \p graph. Think of each entry of the vector as being * generated by a function such as the fitness function for the game. * So if the vector represents fitness quantities, then each vector * entry is the fitness of some vertex. The length of this vector must * be the same as the number of vertices in the vertex set of \p graph. * For the purpose of roulette wheel selection, each vector entry is * assumed to be nonnegative; no checks will be performed for this. It * is your responsibility to ensure that at least one entry is nonzero. * Furthermore, this vector cannot be a vector of zeros; this condition * will be checked. * \param strategies A vector of the current strategies for the vertex * population. The updated strategy for \p vid would be stored here. * Each strategy is identified with a nonnegative integer, whose * interpretation depends on the payoff matrix of the game. Generally * we use the strategy ID as a row or column index of the payoff * matrix. The length of this vector must be the same as the number of * vertices in the vertex set of \p graph. * \param mode Defines the sort of neighbourhood to consider for \p vid. This * is only relevant if we are considering the local perspective, i.e. if * \p islocal is true. If we are considering the global perspective, * then it is safe to pass the value \p IGRAPH_ALL here. If \p graph is * undirected, then we use all the immediate neighbours of \p vid. Thus * if you know that \p graph is undirected, then it is safe to pass the * value \p IGRAPH_ALL here. Supported values are: * \clist * \cli IGRAPH_OUT * Use the out-neighbours of \p vid. This option is only relevant * when \p graph is a digraph and we are considering the local * perspective. * \cli IGRAPH_IN * Use the in-neighbours of \p vid. Again this option is only relevant * when \p graph is a directed graph and we are considering the local * perspective. * \cli IGRAPH_ALL * Use both the in- and out-neighbours of \p vid. This option is only * relevant if \p graph is a digraph. Also use this value if * \p graph is undirected or we are considering the global * perspective. * \endclist * \return The error code \p IGRAPH_EINVAL is returned in each of the following * cases: (1) Any of the parameters \p graph, \p quantities, or * \p strategies is a null pointer. (2) The vector \p quantities or * \p strategies has a length different from the number of vertices * in \p graph. (3) The parameter \p graph is the empty or null graph, * i.e. the graph with zero vertices and edges. (4) The vector * \p quantities sums to zero. * * Time complexity: O(n) where n is the number of vertices in the perspective * to consider. If we consider the global perspective, then n is the number * of vertices in the vertex set of \p graph. On the other hand, for the local * perspective n is the degree of \p vid, excluding loops. * * * Reference: * \clist * \cli (Yu & Gen 2010) * X. Yu and M. Gen. \emb Introduction to Evolutionary Algorithms. \eme * Springer, 2010, pages 18--20. * \endclist * * \example examples/simple/igraph_roulette_wheel_imitation.c */ int igraph_roulette_wheel_imitation(const igraph_t *graph, igraph_integer_t vid, igraph_bool_t islocal, const igraph_vector_t *quantities, igraph_vector_t *strategies, igraph_neimode_t mode) { igraph_bool_t updates; igraph_integer_t u; igraph_real_t r; /* random number */ igraph_vector_t V; /* vector of cumulative proportionate quantities */ igraph_vit_t A; /* all vertices in v's perspective */ igraph_vs_t vs; long int i; IGRAPH_CHECK(igraph_i_microscopic_standard_tests(graph, vid, quantities, strategies, mode, &updates, islocal)); if (!updates) { return IGRAPH_SUCCESS; /* nothing further to do */ } /* set the perspective */ if (islocal) { IGRAPH_CHECK(igraph_vs_adj(&vs, vid, mode)); } else { IGRAPH_CHECK(igraph_vs_all(&vs)); } IGRAPH_FINALLY(igraph_vs_destroy, &vs); IGRAPH_CHECK(igraph_vit_create(graph, vs, &A)); IGRAPH_FINALLY(igraph_vit_destroy, &A); IGRAPH_VECTOR_INIT_FINALLY(&V, 0); IGRAPH_CHECK(igraph_i_vcumulative_proportionate_values(graph, quantities, &V, islocal, vid, mode)); /* Finally, choose a vertex u to imitate. The vertex u is chosen */ /* proportionate to its quantity. In the case of a local perspective, we */ /* pretend that v's cumulative proportionate quantity has been appended to */ /* the vector V. Let V be of length n so that V[n-1] is the last element */ /* of V, and let r be a real number chosen uniformly at random from the */ /* unit interval [0,1]. If r > V[i] for all i < n, then v defaults to */ /* retaining its current strategy. Similarly in the case of the global */ /* perspective, if r > V[i] for all i < n - 1 then v would adopt the */ /* strategy of the vertex whose cumulative proportionate quantity is */ /* V[n-1]. */ /* NOTE: Here we assume that the order in which we iterate through the */ /* vertices in A is the same as the order in which we do so in the */ /* invoked function igraph_vcumulative_proportionate_values(). */ /* Otherwise we would incorrectly associate each V[i] with a vertex in A. */ RNG_BEGIN(); r = RNG_UNIF01(); RNG_END(); i = 0; while (!IGRAPH_VIT_END(A)) { if (r <= VECTOR(V)[i]) { /* We have found our candidate vertex for imitation. Update strategy */ /* of v to that of u, and exit the selection loop. */ u = (igraph_integer_t)IGRAPH_VIT_GET(A); VECTOR(*strategies)[vid] = VECTOR(*strategies)[u]; break; } i++; IGRAPH_VIT_NEXT(A); } /* By now, vertex v should either retain its current strategy or it has */ /* adopted the strategy of a vertex in its perspective. Nothing else to */ /* do, but clean up. */ igraph_vector_destroy(&V); igraph_vit_destroy(&A); igraph_vs_destroy(&vs); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /** * \ingroup spatialgames * \function igraph_stochastic_imitation * \brief Adopt a strategy via stochastic imitation with uniform selection. * * A simple stochastic imitation strategy where a vertex revises its * strategy to that of a vertex chosen uniformly at random from its local * neighbourhood. This is called stochastic imitation via uniform selection, * where the strategy to imitate is chosen via some random process. For the * purposes of this function, we use uniform selection from a pool of * candidates. * * \param graph The graph object representing the game network. This cannot * be the empty or trivial graph, but must have at least two vertices * and one edge. If \p graph has one vertex, then no strategy update * would take place. Furthermore, if \p graph has at least two vertices * but zero edges, then strategy update would also not take place. * \param vid The vertex whose strategy is to be updated. It is assumed that * \p vid represents a vertex in \p graph. No checking is performed and * it is your responsibility to ensure that \p vid is indeed a vertex * of \p graph. If an isolated vertex is provided, i.e. the input * vertex has degree 0, then no strategy update would take place and * \p vid would retain its current strategy. Strategy update would also * not take place if the local neighbourhood of \p vid are its * in-neighbours (respectively out-neighbours), but \p vid has zero * in-neighbours (respectively out-neighbours). Loops are ignored in * computing the degree (in, out, all) of \p vid. * \param algo This flag controls which algorithm to use in stochastic * imitation. Supported values are: * \clist * \cli IGRAPH_IMITATE_AUGMENTED * Augmented imitation. Vertex \p vid imitates the strategy of the * chosen vertex u provided that doing so would increase the * quantity (e.g. fitness) of \p vid. Augmented imitation can be * thought of as "imitate if better". * \cli IGRAPH_IMITATE_BLIND * Blind imitation. Vertex \p vid blindly imitates the strategy of * the chosen vertex u, regardless of whether doing so would * increase or decrease the quantity of \p vid. * \cli IGRAPH_IMITATE_CONTRACTED * Contracted imitation. Here vertex \p vid imitates the strategy of * the chosen vertex u if doing so would decrease the quantity of * \p vid. Think of contracted imitation as "imitate if worse". * \endclist * \param quantities A vector of quantities providing the quantity of each * vertex in \p graph. Think of each entry of the vector as being * generated by a function such as the fitness function for the game. * So if the vector represents fitness quantities, then each vector * entry is the fitness of some vertex. The length of this vector must * be the same as the number of vertices in the vertex set of \p graph. * \param strategies A vector of the current strategies for the vertex * population. The updated strategy for \p vid would be stored here. * Each strategy is identified with a nonnegative integer, whose * interpretation depends on the payoff matrix of the game. Generally * we use the strategy ID as a row or column index of the payoff * matrix. The length of this vector must be the same as the number of * vertices in the vertex set of \p graph. * \param mode Defines the sort of neighbourhood to consider for \p vid. If * \p graph is undirected, then we use all the immediate neighbours of * \p vid. Thus if you know that \p graph is undirected, then it is safe * to pass the value \p IGRAPH_ALL here. Supported values are: * \clist * \cli IGRAPH_OUT * Use the out-neighbours of \p vid. This option is only relevant * when \p graph is a directed graph. * \cli IGRAPH_IN * Use the in-neighbours of \p vid. Again this option is only relevant * when \p graph is a directed graph. * \cli IGRAPH_ALL * Use both the in- and out-neighbours of \p vid. This option is only * relevant if \p graph is a digraph. Also use this value if * \p graph is undirected. * \endclist * \return The error code \p IGRAPH_EINVAL is returned in each of the following * cases: (1) Any of the parameters \p graph, \p quantities, or * \p strategies is a null pointer. (2) The vector \p quantities or * \p strategies has a length different from the number of vertices * in \p graph. (3) The parameter \p graph is the empty or null graph, * i.e. the graph with zero vertices and edges. (4) The parameter * \p algo refers to an unsupported stochastic imitation algorithm. * * Time complexity: depends on the uniform random number generator, but should * usually be O(1). * * \example examples/simple/igraph_stochastic_imitation.c */ int igraph_stochastic_imitation(const igraph_t *graph, igraph_integer_t vid, igraph_imitate_algorithm_t algo, const igraph_vector_t *quantities, igraph_vector_t *strategies, igraph_neimode_t mode) { igraph_bool_t updates; igraph_integer_t u; igraph_vector_t adj; int i; /* sanity checks */ if (algo != IGRAPH_IMITATE_AUGMENTED && algo != IGRAPH_IMITATE_BLIND && algo != IGRAPH_IMITATE_CONTRACTED) { IGRAPH_ERROR("Unsupported stochastic imitation algorithm", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_i_microscopic_standard_tests(graph, vid, quantities, strategies, mode, &updates, /*is local?*/ 1)); if (!updates) { return IGRAPH_SUCCESS; /* nothing more to do */ } /* immediate neighbours of v */ IGRAPH_VECTOR_INIT_FINALLY(&adj, 0); IGRAPH_CHECK(igraph_neighbors(graph, &adj, vid, mode)); /* Blind imitation. Let v be the vertex whose strategy we want to revise. */ /* Choose a vertex u uniformly at random from the immediate neighbours of */ /* v, including v itself. Then blindly update the strategy of v to that of */ /* u, irrespective of whether doing so would increase or decrease the */ /* quantity (e.g. fitness) of v. Here v retains its current strategy if */ /* the chosen vertex u is indeed v itself. */ if (algo == IGRAPH_IMITATE_BLIND) { IGRAPH_CHECK(igraph_vector_push_back(&adj, vid)); RNG_BEGIN(); i = (int) RNG_INTEGER(0, igraph_vector_size(&adj) - 1); RNG_END(); u = (igraph_integer_t) VECTOR(adj)[i]; VECTOR(*strategies)[vid] = VECTOR(*strategies)[u]; } /* Augmented imitation. Let v be the vertex whose strategy we want to */ /* revise. Let f be the quantity function for the game. Choose a vertex u */ /* uniformly at random from the immediate neighbours of v; do not include */ /* v. Then v imitates the strategy of u if f(u) > f(v). Otherwise v */ /* retains its current strategy. */ else if (algo == IGRAPH_IMITATE_AUGMENTED) { RNG_BEGIN(); i = (int) RNG_INTEGER(0, igraph_vector_size(&adj) - 1); RNG_END(); u = (igraph_integer_t) VECTOR(adj)[i]; if (VECTOR(*quantities)[u] > VECTOR(*quantities)[vid]) { VECTOR(*strategies)[vid] = VECTOR(*strategies)[u]; } } /* Contracted imitation. Let v be the vertex whose strategy we want to */ /* update and let f be the quantity function for the game. Choose a vertex */ /* u uniformly at random from the immediate neighbours of v, excluding v */ /* itself. Then v imitates the strategy of u provided that f(u) < f(v). */ /* Otherwise v retains its current strategy. */ else if (algo == IGRAPH_IMITATE_CONTRACTED) { RNG_BEGIN(); i = (int) RNG_INTEGER(0, igraph_vector_size(&adj) - 1); RNG_END(); u = (igraph_integer_t) VECTOR(adj)[i]; if (VECTOR(*quantities)[u] < VECTOR(*quantities)[vid]) { VECTOR(*strategies)[vid] = VECTOR(*strategies)[u]; } } /* clean up */ igraph_vector_destroy(&adj); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/misc/feedback_arc_set.c0000644000176200001440000006226414447675375020447 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_components.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_structural.h" #include "igraph_visitor.h" #include "internal/glpk_support.h" #include "misc/feedback_arc_set.h" int igraph_i_feedback_arc_set_ip(const igraph_t *graph, igraph_vector_t *result, const igraph_vector_t *weights); /** * \ingroup structural * \function igraph_feedback_arc_set * \brief Calculates a feedback arc set of the graph using different * algorithms. * * * A feedback arc set is a set of edges whose removal makes the graph acyclic. * We are usually interested in \em minimum feedback arc sets, i.e. sets of edges * whose total weight is minimal among all the feedback arc sets. * * * For undirected graphs, the problem is simple: one has to find a maximum weight * spanning tree and then remove all the edges not in the spanning tree. For directed * graphs, this is an NP-hard problem, and various heuristics are usually used to * find an approximate solution to the problem. This function implements a few of * these heuristics. * * \param graph The graph object. * \param result An initialized vector, the result will be returned here. * \param weights Weight vector or NULL if no weights are specified. * \param algo The algorithm to use to solve the problem if the graph is directed. * Possible values: * \clist * \cli IGRAPH_FAS_EXACT_IP * Finds a \em minimum feedback arc set using integer programming (IP). * The complexity of this algorithm is exponential of course. * \cli IGRAPH_FAS_APPROX_EADES * Finds a feedback arc set using the heuristic of Eades, Lin and * Smyth (1993). This is guaranteed to be smaller than |E|/2 - |V|/6, * and it is linear in the number of edges (i.e. O(|E|)). * For more details, see Eades P, Lin X and Smyth WF: A fast and effective * heuristic for the feedback arc set problem. In: Proc Inf Process Lett * 319-323, 1993. * \endclist * * \return Error code: * \c IGRAPH_EINVAL if an unknown method was specified or the weight vector * is invalid. * * \example examples/simple/igraph_feedback_arc_set.c * \example examples/simple/igraph_feedback_arc_set_ip.c * * Time complexity: depends on \p algo, see the time complexities there. */ int igraph_feedback_arc_set(const igraph_t *graph, igraph_vector_t *result, const igraph_vector_t *weights, igraph_fas_algorithm_t algo) { if (weights && igraph_vector_size(weights) < igraph_ecount(graph)) IGRAPH_ERROR("cannot calculate feedback arc set, weight vector too short", IGRAPH_EINVAL); if (!igraph_is_directed(graph)) { return igraph_i_feedback_arc_set_undirected(graph, result, weights, 0); } switch (algo) { case IGRAPH_FAS_EXACT_IP: return igraph_i_feedback_arc_set_ip(graph, result, weights); case IGRAPH_FAS_APPROX_EADES: return igraph_i_feedback_arc_set_eades(graph, result, weights, 0); default: IGRAPH_ERROR("Invalid algorithm", IGRAPH_EINVAL); } } /** * Solves the feedback arc set problem for undirected graphs. */ int igraph_i_feedback_arc_set_undirected(const igraph_t *graph, igraph_vector_t *result, const igraph_vector_t *weights, igraph_vector_t *layering) { igraph_vector_t edges; long int i, j, n, no_of_nodes = igraph_vcount(graph); IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_nodes > 0 ? no_of_nodes - 1 : 0); if (weights) { /* Find a maximum weight spanning tree. igraph has a routine for minimum * spanning trees, so we negate the weights */ igraph_vector_t vcopy; IGRAPH_CHECK(igraph_vector_copy(&vcopy, weights)); IGRAPH_FINALLY(igraph_vector_destroy, &vcopy); igraph_vector_scale(&vcopy, -1); IGRAPH_CHECK(igraph_minimum_spanning_tree(graph, &edges, &vcopy)); igraph_vector_destroy(&vcopy); IGRAPH_FINALLY_CLEAN(1); } else { /* Any spanning tree will do */ IGRAPH_CHECK(igraph_minimum_spanning_tree(graph, &edges, 0)); } /* Now we have a bunch of edges that constitute a spanning forest. We have * to come up with a layering, and return those edges that are not in the * spanning forest */ igraph_vector_sort(&edges); IGRAPH_CHECK(igraph_vector_push_back(&edges, -1)); /* guard element */ if (result != 0) { igraph_vector_clear(result); n = igraph_ecount(graph); for (i = 0, j = 0; i < n; i++) { if (i == VECTOR(edges)[j]) { j++; continue; } IGRAPH_CHECK(igraph_vector_push_back(result, i)); } } if (layering != 0) { igraph_vector_t degrees; igraph_vector_t roots; IGRAPH_VECTOR_INIT_FINALLY(°rees, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&roots, no_of_nodes); IGRAPH_CHECK(igraph_strength(graph, °rees, igraph_vss_all(), IGRAPH_ALL, 0, weights)); IGRAPH_CHECK((int) igraph_vector_qsort_ind(°rees, &roots, /* descending = */ 1)); IGRAPH_CHECK(igraph_bfs(graph, /* root = */ 0, /* roots = */ &roots, /* mode = */ IGRAPH_OUT, /* unreachable = */ 0, /* restricted = */ 0, /* order = */ 0, /* rank = */ 0, /* father = */ 0, /* pred = */ 0, /* succ = */ 0, /* dist = */ layering, /* callback = */ 0, /* extra = */ 0)); igraph_vector_destroy(°rees); igraph_vector_destroy(&roots); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * Solves the feedback arc set problem using the heuristics of Eades et al. */ int igraph_i_feedback_arc_set_eades(const igraph_t *graph, igraph_vector_t *result, const igraph_vector_t *weights, igraph_vector_t *layers) { long int i, j, k, v, eid, no_of_nodes = igraph_vcount(graph), nodes_left; igraph_dqueue_t sources, sinks; igraph_vector_t neis; igraph_vector_t indegrees, outdegrees; igraph_vector_t instrengths, outstrengths; long int* ordering; long int order_next_pos = 0, order_next_neg = -1; igraph_real_t diff, maxdiff; ordering = IGRAPH_CALLOC(no_of_nodes, long int); IGRAPH_FINALLY(igraph_free, ordering); IGRAPH_VECTOR_INIT_FINALLY(&indegrees, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&outdegrees, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&instrengths, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&outstrengths, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_dqueue_init(&sources, 0)); IGRAPH_FINALLY(igraph_dqueue_destroy, &sources); IGRAPH_CHECK(igraph_dqueue_init(&sinks, 0)); IGRAPH_FINALLY(igraph_dqueue_destroy, &sinks); IGRAPH_CHECK(igraph_degree(graph, &indegrees, igraph_vss_all(), IGRAPH_IN, 0)); IGRAPH_CHECK(igraph_degree(graph, &outdegrees, igraph_vss_all(), IGRAPH_OUT, 0)); if (weights) { IGRAPH_CHECK(igraph_strength(graph, &instrengths, igraph_vss_all(), IGRAPH_IN, 0, weights)); IGRAPH_CHECK(igraph_strength(graph, &outstrengths, igraph_vss_all(), IGRAPH_OUT, 0, weights)); } else { IGRAPH_CHECK(igraph_vector_update(&instrengths, &indegrees)); IGRAPH_CHECK(igraph_vector_update(&outstrengths, &outdegrees)); } /* Find initial sources and sinks */ nodes_left = no_of_nodes; for (i = 0; i < no_of_nodes; i++) { if (VECTOR(indegrees)[i] == 0) { if (VECTOR(outdegrees)[i] == 0) { /* Isolated vertex, we simply ignore it */ nodes_left--; ordering[i] = order_next_pos++; VECTOR(indegrees)[i] = VECTOR(outdegrees)[i] = -1; } else { /* This is a source */ igraph_dqueue_push(&sources, i); } } else if (VECTOR(outdegrees)[i] == 0) { /* This is a sink */ igraph_dqueue_push(&sinks, i); } } /* While we have any nodes left... */ while (nodes_left > 0) { /* (1) Remove the sources one by one */ while (!igraph_dqueue_empty(&sources)) { i = (long)igraph_dqueue_pop(&sources); /* Add the node to the ordering */ ordering[i] = order_next_pos++; /* Exclude the node from further searches */ VECTOR(indegrees)[i] = VECTOR(outdegrees)[i] = -1; /* Get the neighbors and decrease their degrees */ IGRAPH_CHECK(igraph_incident(graph, &neis, (igraph_integer_t) i, IGRAPH_OUT)); j = igraph_vector_size(&neis); for (i = 0; i < j; i++) { eid = (long int) VECTOR(neis)[i]; k = IGRAPH_TO(graph, eid); if (VECTOR(indegrees)[k] <= 0) { /* Already removed, continue */ continue; } VECTOR(indegrees)[k]--; VECTOR(instrengths)[k] -= (weights ? VECTOR(*weights)[eid] : 1.0); if (VECTOR(indegrees)[k] == 0) { IGRAPH_CHECK(igraph_dqueue_push(&sources, k)); } } nodes_left--; } /* (2) Remove the sinks one by one */ while (!igraph_dqueue_empty(&sinks)) { i = (long)igraph_dqueue_pop(&sinks); /* Maybe the vertex became sink and source at the same time, hence it * was already removed in the previous iteration. Check it. */ if (VECTOR(indegrees)[i] < 0) { continue; } /* Add the node to the ordering */ ordering[i] = order_next_neg--; /* Exclude the node from further searches */ VECTOR(indegrees)[i] = VECTOR(outdegrees)[i] = -1; /* Get the neighbors and decrease their degrees */ IGRAPH_CHECK(igraph_incident(graph, &neis, (igraph_integer_t) i, IGRAPH_IN)); j = igraph_vector_size(&neis); for (i = 0; i < j; i++) { eid = (long int) VECTOR(neis)[i]; k = IGRAPH_FROM(graph, eid); if (VECTOR(outdegrees)[k] <= 0) { /* Already removed, continue */ continue; } VECTOR(outdegrees)[k]--; VECTOR(outstrengths)[k] -= (weights ? VECTOR(*weights)[eid] : 1.0); if (VECTOR(outdegrees)[k] == 0) { IGRAPH_CHECK(igraph_dqueue_push(&sinks, k)); } } nodes_left--; } /* (3) No more sources or sinks. Find the node with the largest * difference between its out-strength and in-strength */ v = -1; maxdiff = -IGRAPH_INFINITY; for (i = 0; i < no_of_nodes; i++) { if (VECTOR(outdegrees)[i] < 0) { continue; } diff = VECTOR(outstrengths)[i] - VECTOR(instrengths)[i]; if (diff > maxdiff) { maxdiff = diff; v = i; } } if (v >= 0) { /* Remove vertex v */ ordering[v] = order_next_pos++; /* Remove outgoing edges */ IGRAPH_CHECK(igraph_incident(graph, &neis, (igraph_integer_t) v, IGRAPH_OUT)); j = igraph_vector_size(&neis); for (i = 0; i < j; i++) { eid = (long int) VECTOR(neis)[i]; k = IGRAPH_TO(graph, eid); if (VECTOR(indegrees)[k] <= 0) { /* Already removed, continue */ continue; } VECTOR(indegrees)[k]--; VECTOR(instrengths)[k] -= (weights ? VECTOR(*weights)[eid] : 1.0); if (VECTOR(indegrees)[k] == 0) { IGRAPH_CHECK(igraph_dqueue_push(&sources, k)); } } /* Remove incoming edges */ IGRAPH_CHECK(igraph_incident(graph, &neis, (igraph_integer_t) v, IGRAPH_IN)); j = igraph_vector_size(&neis); for (i = 0; i < j; i++) { eid = (long int) VECTOR(neis)[i]; k = IGRAPH_FROM(graph, eid); if (VECTOR(outdegrees)[k] <= 0) { /* Already removed, continue */ continue; } VECTOR(outdegrees)[k]--; VECTOR(outstrengths)[k] -= (weights ? VECTOR(*weights)[eid] : 1.0); if (VECTOR(outdegrees)[k] == 0 && VECTOR(indegrees)[k] > 0) { IGRAPH_CHECK(igraph_dqueue_push(&sinks, k)); } } VECTOR(outdegrees)[v] = -1; VECTOR(indegrees)[v] = -1; nodes_left--; } } igraph_dqueue_destroy(&sinks); igraph_dqueue_destroy(&sources); igraph_vector_destroy(&neis); igraph_vector_destroy(&outstrengths); igraph_vector_destroy(&instrengths); igraph_vector_destroy(&outdegrees); igraph_vector_destroy(&indegrees); IGRAPH_FINALLY_CLEAN(7); /* Tidy up the ordering */ for (i = 0; i < no_of_nodes; i++) { if (ordering[i] < 0) { ordering[i] += no_of_nodes; } } /* Find the feedback edges based on the ordering */ if (result != 0) { igraph_vector_clear(result); j = igraph_ecount(graph); for (i = 0; i < j; i++) { long int from = IGRAPH_FROM(graph, i), to = IGRAPH_TO(graph, i); if (from == to || ordering[from] > ordering[to]) { IGRAPH_CHECK(igraph_vector_push_back(result, i)); } } } /* If we have also requested a layering, return that as well */ if (layers != 0) { igraph_vector_t ranks; igraph_vector_long_t order_vec; IGRAPH_CHECK(igraph_vector_resize(layers, no_of_nodes)); igraph_vector_null(layers); igraph_vector_long_view(&order_vec, ordering, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_INIT_FINALLY(&ranks, 0); IGRAPH_CHECK((int) igraph_vector_long_qsort_ind(&order_vec, &ranks, 0)); for (i = 0; i < no_of_nodes; i++) { long int from = (long int) VECTOR(ranks)[i]; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) from, IGRAPH_OUT)); k = igraph_vector_size(&neis); for (j = 0; j < k; j++) { long int to = (long int) VECTOR(neis)[j]; if (from == to) { continue; } if (ordering[from] > ordering[to]) { continue; } if (VECTOR(*layers)[to] < VECTOR(*layers)[from] + 1) { VECTOR(*layers)[to] = VECTOR(*layers)[from] + 1; } } } igraph_vector_destroy(&neis); igraph_vector_destroy(&ranks); IGRAPH_FINALLY_CLEAN(2); } /* Free the ordering vector */ igraph_free(ordering); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * Solves the feedback arc set problem using integer programming. */ int igraph_i_feedback_arc_set_ip(const igraph_t *graph, igraph_vector_t *result, const igraph_vector_t *weights) { #ifndef HAVE_GLPK IGRAPH_ERROR("GLPK is not available", IGRAPH_UNIMPLEMENTED); #else igraph_integer_t no_of_components; igraph_integer_t no_of_vertices = igraph_vcount(graph); igraph_integer_t no_of_edges = igraph_ecount(graph); igraph_vector_t membership, ordering, vertex_remapping; igraph_vector_ptr_t vertices_by_components, edges_by_components; long int i, j, k, l, m, n, from, to; igraph_real_t weight; glp_prob *ip; glp_iocp parm; IGRAPH_VECTOR_INIT_FINALLY(&membership, 0); IGRAPH_VECTOR_INIT_FINALLY(&ordering, 0); IGRAPH_VECTOR_INIT_FINALLY(&vertex_remapping, no_of_vertices); igraph_vector_clear(result); /* Decompose the graph into connected components */ IGRAPH_CHECK(igraph_clusters(graph, &membership, 0, &no_of_components, IGRAPH_WEAK)); /* Construct vertex and edge lists for each of the components */ IGRAPH_CHECK(igraph_vector_ptr_init(&vertices_by_components, no_of_components)); IGRAPH_CHECK(igraph_vector_ptr_init(&edges_by_components, no_of_components)); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &vertices_by_components); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &edges_by_components); for (i = 0; i < no_of_components; i++) { igraph_vector_t* vptr; vptr = IGRAPH_CALLOC(1, igraph_vector_t); if (vptr == 0) { IGRAPH_ERROR("cannot calculate feedback arc set using IP", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, vptr); IGRAPH_CHECK(igraph_vector_init(vptr, 0)); IGRAPH_FINALLY_CLEAN(1); VECTOR(vertices_by_components)[i] = vptr; } IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&vertices_by_components, igraph_vector_destroy); for (i = 0; i < no_of_components; i++) { igraph_vector_t* vptr; vptr = IGRAPH_CALLOC(1, igraph_vector_t); if (vptr == 0) { IGRAPH_ERROR("cannot calculate feedback arc set using IP", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, vptr); IGRAPH_CHECK(igraph_vector_init(vptr, 0)); IGRAPH_FINALLY_CLEAN(1); VECTOR(edges_by_components)[i] = vptr; } IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&edges_by_components, igraph_vector_destroy); for (i = 0; i < no_of_vertices; i++) { j = (long int) VECTOR(membership)[i]; IGRAPH_CHECK(igraph_vector_push_back(VECTOR(vertices_by_components)[j], i)); } for (i = 0; i < no_of_edges; i++) { j = (long int) VECTOR(membership)[(long)IGRAPH_FROM(graph, i)]; IGRAPH_CHECK(igraph_vector_push_back(VECTOR(edges_by_components)[j], i)); } #define VAR2IDX(i, j) (i*(n-1)+j-(i+1)*i/2) /* Configure GLPK */ IGRAPH_GLPK_SETUP(); glp_init_iocp(&parm); parm.br_tech = GLP_BR_DTH; parm.bt_tech = GLP_BT_BLB; parm.pp_tech = GLP_PP_ALL; parm.presolve = GLP_ON; parm.binarize = GLP_OFF; parm.cb_func = igraph_i_glpk_interruption_hook; /* Solve an IP for feedback arc sets in each of the components */ for (i = 0; i < no_of_components; i++) { igraph_vector_t* vertices_in_comp = (igraph_vector_t*)VECTOR(vertices_by_components)[i]; igraph_vector_t* edges_in_comp = (igraph_vector_t*)VECTOR(edges_by_components)[i]; /* * Let x_ij denote whether layer(i) < layer(j). * * The standard formulation of the problem is as follows: * * max sum_{i,j} w_ij x_ij * * subject to * * (1) x_ij + x_ji = 1 (i.e. either layer(i) < layer(j) or layer(i) > layer(j)) * for all i < j * (2) x_ij + x_jk + x_ki <= 2 for all i < j, i < k, j != k * * Note that x_ij = 1 implies that x_ji = 0 and vice versa; in other words, * x_ij = 1 - x_ji. Thus, we can get rid of the (1) constraints and half of the * x_ij variables (where j < i) if we rewrite constraints of type (2) as follows: * * (2a) x_ij + x_jk - x_ik <= 1 for all i < j, i < k, j < k * (2b) x_ij - x_kj - x_ik <= 0 for all i < j, i < k, j > k * * The goal function then becomes: * * max sum_{i 0) { glp_add_cols(ip, (int) k); for (j = 1; j <= k; j++) { glp_set_col_kind(ip, (int) j, GLP_BV); } } /* Set up coefficients in the goal function */ k = igraph_vector_size(edges_in_comp); for (j = 0; j < k; j++) { l = (long int) VECTOR(*edges_in_comp)[j]; from = (long int) VECTOR(vertex_remapping)[(long)IGRAPH_FROM(graph, l)]; to = (long int) VECTOR(vertex_remapping)[(long)IGRAPH_TO(graph, l)]; if (from == to) { continue; } weight = weights ? VECTOR(*weights)[l] : 1; if (from < to) { l = VAR2IDX(from, to); glp_set_obj_coef(ip, (int) l, glp_get_obj_coef(ip, (int) l) + weight); } else { l = VAR2IDX(to, from); glp_set_obj_coef(ip, (int) l, glp_get_obj_coef(ip, (int) l) - weight); } } /* Add constraints */ if (n > 1) { glp_add_rows(ip, (int)(n * (n - 1) / 2 + n * (n - 1) * (n - 2) / 3)); m = 1; for (j = 0; j < n; j++) { int ind[4]; double val[4] = {0, 1, 1, -1}; for (k = j + 1; k < n; k++) { ind[1] = (int) VAR2IDX(j, k); /* Type (2a) */ val[2] = 1; for (l = k + 1; l < n; l++, m++) { ind[2] = (int) VAR2IDX(k, l); ind[3] = (int) VAR2IDX(j, l); glp_set_row_bnds(ip, (int) m, GLP_UP, 1, 1); glp_set_mat_row(ip, (int) m, 3, ind, val); } /* Type (2b) */ val[2] = -1; for (l = j + 1; l < k; l++, m++) { ind[2] = (int) VAR2IDX(l, k); ind[3] = (int) VAR2IDX(j, l); glp_set_row_bnds(ip, (int) m, GLP_UP, 0, 0); glp_set_mat_row(ip, (int) m, 3, ind, val); } } } } /* Solve the problem */ IGRAPH_GLPK_CHECK(glp_intopt(ip, &parm), "Feedback arc set using IP failed"); /* Find the ordering of the vertices */ IGRAPH_CHECK(igraph_vector_resize(&ordering, n)); igraph_vector_null(&ordering); m = n * (n - 1) / 2; j = 0; k = 1; for (l = 1; l <= m; l++) { /* variable l always corresponds to the (j, k) vertex pair */ /* printf("(%ld, %ld) = %g\n", i, j, glp_mip_col_val(ip, l)); */ if (glp_mip_col_val(ip, (int) l) > 0) { /* j comes earlier in the ordering than k */ VECTOR(ordering)[j]++; } else { /* k comes earlier in the ordering than j */ VECTOR(ordering)[k]++; } k++; if (k == n) { j++; k = j + 1; } } /* Find the feedback edges */ k = igraph_vector_size(edges_in_comp); for (j = 0; j < k; j++) { l = (long int) VECTOR(*edges_in_comp)[j]; from = (long int) VECTOR(vertex_remapping)[(long)IGRAPH_FROM(graph, l)]; to = (long int) VECTOR(vertex_remapping)[(long)IGRAPH_TO(graph, l)]; if (from == to || VECTOR(ordering)[from] < VECTOR(ordering)[to]) { IGRAPH_CHECK(igraph_vector_push_back(result, l)); } } /* Clean up */ glp_delete_prob(ip); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_ptr_destroy_all(&vertices_by_components); igraph_vector_ptr_destroy_all(&edges_by_components); igraph_vector_destroy(&vertex_remapping); igraph_vector_destroy(&ordering); igraph_vector_destroy(&membership); IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; #endif } leidenbase/src/core/misc/degree_sequence.cpp0000644000176200001440000006700514447675375020704 0ustar liggesusers/* IGraph library. Constructing realizations of degree sequences and bi-degree sequences. Copyright (C) 2018-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_constructors.h" #include "igraph_interface.h" #include #include #include #include #define IGRAPH_I_MULTI_EDGES_SW 0x02 /* 010, more than one edge allowed between distinct vertices */ #define IGRAPH_I_MULTI_LOOPS_SW 0x04 /* 100, more than one self-loop allowed on the same vertex */ /******************************/ /***** Helper constructs ******/ /******************************/ // (vertex, degree) pair struct vd_pair { long vertex; igraph_integer_t degree; vd_pair(long vertex, igraph_integer_t degree) : vertex(vertex), degree(degree) {} }; // (indegree, outdegree) typedef std::pair bidegree; // (vertex, bidegree) pair struct vbd_pair { long vertex; bidegree degree; vbd_pair(long vertex, bidegree degree) : vertex(vertex), degree(degree) {} }; // Comparison function for vertex-degree pairs. // Also used for lexicographic sorting of bi-degrees. template inline bool degree_greater(const T &a, const T &b) { return a.degree > b.degree; } template inline bool degree_less(const T &a, const T &b) { return a.degree < b.degree; } /*************************************/ /***** Undirected simple graphs ******/ /*************************************/ // Generate simple undirected realization as edge-list. // If largest=true, always choose the vertex with the largest remaining degree to connect up next. // Otherwise, always choose the one with the smallest remaining degree. static int igraph_i_havel_hakimi(const igraph_vector_t *deg, igraph_vector_t *edges, bool largest) { long n = igraph_vector_size(deg); long ec = 0; // number of edges added so far std::vector vertices; vertices.reserve(n); for (int i = 0; i < n; ++i) { vertices.push_back(vd_pair(i, VECTOR(*deg)[i])); } while (! vertices.empty()) { if (largest) { std::stable_sort(vertices.begin(), vertices.end(), degree_less); } else { std::stable_sort(vertices.begin(), vertices.end(), degree_greater); } // take the next vertex to be connected up vd_pair vd = vertices.back(); vertices.pop_back(); if (vd.degree == 0) { continue; } if (vertices.size() < size_t(vd.degree)) { goto fail; } if (largest) { for (int i = 0; i < vd.degree; ++i) { if (--(vertices[vertices.size() - 1 - i].degree) < 0) { goto fail; } VECTOR(*edges)[2 * (ec + i)] = vd.vertex; VECTOR(*edges)[2 * (ec + i) + 1] = vertices[vertices.size() - 1 - i].vertex; } } else { // this loop can only be reached if all zero-degree nodes have already been removed // therefore decrementing remaining degrees is safe for (int i = 0; i < vd.degree; ++i) { vertices[i].degree--; VECTOR(*edges)[2 * (ec + i)] = vd.vertex; VECTOR(*edges)[2 * (ec + i) + 1] = vertices[i].vertex; } } ec += vd.degree; } return IGRAPH_SUCCESS; fail: IGRAPH_ERROR("The given degree sequence cannot be realized as a simple graph.", IGRAPH_EINVAL); } // Choose vertices in the order of their IDs. static int igraph_i_havel_hakimi_index(const igraph_vector_t *deg, igraph_vector_t *edges) { long n = igraph_vector_size(deg); long ec = 0; // number of edges added so far typedef std::list vlist; vlist vertices; for (int i = 0; i < n; ++i) { vertices.push_back(vd_pair(i, VECTOR(*deg)[i])); } std::vector pointers; pointers.reserve(n); for (vlist::iterator it = vertices.begin(); it != vertices.end(); ++it) { pointers.push_back(it); } for (std::vector::iterator pt = pointers.begin(); pt != pointers.end(); ++pt) { vertices.sort(degree_greater); vd_pair vd = **pt; vertices.erase(*pt); if (vd.degree == 0) { continue; } int k; vlist::iterator it; for (it = vertices.begin(), k = 0; k != vd.degree && it != vertices.end(); ++it, ++k) { if (--(it->degree) < 0) { goto fail; } VECTOR(*edges)[2 * (ec + k)] = vd.vertex; VECTOR(*edges)[2 * (ec + k) + 1] = it->vertex; } if (it == vertices.end() && k < vd.degree) { goto fail; } ec += vd.degree; } return IGRAPH_SUCCESS; fail: IGRAPH_ERROR("The given degree sequence cannot be realized as a simple graph.", IGRAPH_EINVAL); } /***********************************/ /***** Undirected multigraphs ******/ /***********************************/ // Given a sequence that is sorted, except for its first element, // move the first element to the correct position fully sort the sequence. template static void bubble_up(It first, It last, Compare comp) { if (first == last) return; It it = first; it++; while (it != last) { if (comp(*first, *it)) { break; } else { std::swap(*first, *it); } first = it; it++; } } // In each step, choose a vertex (the largest degree one if largest=true, // the smallest degree one otherwise) and connect it to the largest remaining degree vertex. // This will create a connected loopless multigraph, if one exists. // If loops=true, and a loopless multigraph does not exist, complete the procedure // by adding loops on the last vertex. // If largest=false, and the degree sequence was potentially connected, the resulting // graph will be connected. static int igraph_i_realize_undirected_multi(const igraph_vector_t *deg, igraph_vector_t *edges, bool loops, bool largest) { long vcount = igraph_vector_size(deg); if (vcount == 0) return IGRAPH_SUCCESS; std::vector vertices; vertices.reserve(vcount); for (int i = 0; i < vcount; ++i) { long d = VECTOR(*deg)[i]; vertices.push_back(vd_pair(i, d)); } // Initial sort in non-increasing order. std::stable_sort(vertices.begin(), vertices.end(), degree_greater); long ec = 0; while (! vertices.empty()) { // Remove any zero degrees, and error on negative ones. vd_pair &w = vertices.back(); if (w.degree == 0) { vertices.pop_back(); continue; } // If only one vertex remains, then the degree sequence cannot be realized as // a loopless multigraph. We either complete the graph by adding loops on this vertex // or throw an error, depending on the 'loops' setting. if (vertices.size() == 1) { if (loops) { for (long i=0; i < w.degree/2; ++i) { VECTOR(*edges)[2*ec] = w.vertex; VECTOR(*edges)[2*ec+1] = w.vertex; ec++; } break; } else { IGRAPH_ERROR("The given degree sequence cannot be realized as a loopless multigraph.", IGRAPH_EINVAL); } } // At this point we are guaranteed to have at least two remaining vertices. vd_pair *u, *v; if (largest) { u = &vertices[0]; v = &vertices[1]; } else { u = &vertices.front(); v = &vertices.back(); } u->degree -= 1; v->degree -= 1; VECTOR(*edges)[2*ec] = u->vertex; VECTOR(*edges)[2*ec+1] = v->vertex; ec++; // Now the first element may be out of order. // If largest=true, the first two elements may be out of order. // Restore the sorted order using a single step of bubble sort. if (largest) { bubble_up(vertices.begin()+1, vertices.end(), degree_greater); } bubble_up(vertices.begin(), vertices.end(), degree_greater); } return IGRAPH_SUCCESS; } static int igraph_i_realize_undirected_multi_index(const igraph_vector_t *deg, igraph_vector_t *edges, bool loops) { long vcount = igraph_vector_size(deg); if (vcount == 0) return IGRAPH_SUCCESS; typedef std::list vlist; vlist vertices; for (int i = 0; i < vcount; ++i) { vertices.push_back(vd_pair(i, VECTOR(*deg)[i])); } std::vector pointers; pointers.reserve(vcount); for (vlist::iterator it = vertices.begin(); it != vertices.end(); ++it) { pointers.push_back(it); } // Initial sort vertices.sort(degree_greater); long ec = 0; for (std::vector::iterator pt = pointers.begin(); pt != pointers.end(); ++pt) { vd_pair vd = **pt; vertices.erase(*pt); while (vd.degree > 0) { vlist::iterator uit = vertices.begin(); if (vertices.empty() || uit->degree == 0) { // We are out of non-zero degree vertices to connect to. if (loops) { for (long i=0; i < vd.degree/2; ++i) { VECTOR(*edges)[2*ec] = vd.vertex; VECTOR(*edges)[2*ec+1] = vd.vertex; ec++; } return IGRAPH_SUCCESS; } else { IGRAPH_ERROR("The given degree sequence cannot be realized as a loopless multigraph.", IGRAPH_EINVAL); } } vd.degree -= 1; uit->degree -= 1; VECTOR(*edges)[2*ec] = vd.vertex; VECTOR(*edges)[2*ec+1] = uit->vertex; ec++; // If there are at least two elements, and the first two are not in order, // re-sort the list. A possible optimization would be a version of // bubble_up() that can exchange list nodes instead of swapping their values. if (vertices.size() > 1) { vlist::iterator wit = uit; ++wit; if (wit->degree > uit->degree) { vertices.sort(degree_greater); } } } } return IGRAPH_SUCCESS; } /***********************************/ /***** Directed simple graphs ******/ /***********************************/ inline bool is_nonzero_outdeg(const vbd_pair &vd) { return (vd.degree.second != 0); } // The below implementations of the Kleitman-Wang algorithm follow the description in https://arxiv.org/abs/0905.4913 // Realize bi-degree sequence as edge list // If smallest=true, always choose the vertex with "smallest" bi-degree for connecting up next, // otherwise choose the "largest" (based on lexicographic bi-degree ordering). static int igraph_i_kleitman_wang(const igraph_vector_t *outdeg, const igraph_vector_t *indeg, igraph_vector_t *edges, bool smallest) { long n = igraph_vector_size(indeg); // number of vertices long ec = 0; // number of edges added so far std::vector vertices; vertices.reserve(n); for (int i = 0; i < n; ++i) { vertices.push_back(vbd_pair(i, bidegree(VECTOR(*indeg)[i], VECTOR(*outdeg)[i]))); } while (true) { // sort vertices by (in, out) degree pairs in decreasing order std::stable_sort(vertices.begin(), vertices.end(), degree_greater); // remove (0,0)-degree vertices while (!vertices.empty() && vertices.back().degree == bidegree(0, 0)) { vertices.pop_back(); } // if no vertices remain, stop if (vertices.empty()) { break; } // choose a vertex the out-stubs of which will be connected // note: a vertex with non-zero out-degree is guaranteed to exist // because there are _some_ non-zero degrees and the sum of in- and out-degrees // is the same vbd_pair *vdp; if (smallest) { vdp = &*std::find_if(vertices.rbegin(), vertices.rend(), is_nonzero_outdeg); } else { vdp = &*std::find_if(vertices.begin(), vertices.end(), is_nonzero_outdeg); } // are there a sufficient number of other vertices to connect to? if (static_cast(vertices.size()) - 1 < vdp->degree.second) { goto fail; } // create the connections int k = 0; for (std::vector::iterator it = vertices.begin(); k < vdp->degree.second; ++it) { if (it->vertex == vdp->vertex) { continue; // do not create a self-loop } if (--(it->degree.first) < 0) { goto fail; } VECTOR(*edges)[2 * (ec + k)] = vdp->vertex; VECTOR(*edges)[2 * (ec + k) + 1] = it->vertex; k++; } ec += vdp->degree.second; vdp->degree.second = 0; } return IGRAPH_SUCCESS; fail: IGRAPH_ERROR("The given directed degree sequences cannot be realized as a simple graph.", IGRAPH_EINVAL); } // Choose vertices in the order of their IDs. static int igraph_i_kleitman_wang_index(const igraph_vector_t *outdeg, const igraph_vector_t *indeg, igraph_vector_t *edges) { long n = igraph_vector_size(indeg); // number of vertices long ec = 0; // number of edges added so far typedef std::list vlist; vlist vertices; for (int i = 0; i < n; ++i) { vertices.push_back(vbd_pair(i, bidegree(VECTOR(*indeg)[i], VECTOR(*outdeg)[i]))); } std::vector pointers; pointers.reserve(n); for (vlist::iterator it = vertices.begin(); it != vertices.end(); ++it) { pointers.push_back(it); } for (std::vector::iterator pt = pointers.begin(); pt != pointers.end(); ++pt) { // sort vertices by (in, out) degree pairs in decreasing order // note: std::list::sort does a stable sort vertices.sort(degree_greater); // choose a vertex the out-stubs of which will be connected vbd_pair &vd = **pt; if (vd.degree.second == 0) { continue; } int k = 0; vlist::iterator it; for (it = vertices.begin(); k != vd.degree.second && it != vertices.end(); ++it) { if (it->vertex == vd.vertex) { continue; } if (--(it->degree.first) < 0) { goto fail; } VECTOR(*edges)[2 * (ec + k)] = vd.vertex; VECTOR(*edges)[2 * (ec + k) + 1] = it->vertex; ++k; } if (it == vertices.end() && k < vd.degree.second) { goto fail; } ec += vd.degree.second; vd.degree.second = 0; } return IGRAPH_SUCCESS; fail: IGRAPH_ERROR("The given directed degree sequences cannot be realized as a simple graph.", IGRAPH_EINVAL); } /**************************/ /***** Main functions *****/ /**************************/ static int igraph_i_realize_undirected_degree_sequence( igraph_t *graph, const igraph_vector_t *deg, igraph_edge_type_sw_t allowed_edge_types, igraph_realize_degseq_t method) { long node_count = igraph_vector_size(deg); long deg_sum = long(igraph_vector_sum(deg)); if (deg_sum % 2 != 0) { IGRAPH_ERROR("The sum of degrees must be even for an undirected graph.", IGRAPH_EINVAL); } if (node_count > 0 && igraph_vector_min(deg) < 0) { IGRAPH_ERROR("Vertex degrees must be non-negative.", IGRAPH_EINVAL); } igraph_vector_t edges; IGRAPH_CHECK(igraph_vector_init(&edges, deg_sum)); IGRAPH_FINALLY(igraph_vector_destroy, &edges); if ( (allowed_edge_types & IGRAPH_LOOPS_SW) && (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) && (allowed_edge_types & IGRAPH_I_MULTI_LOOPS_SW ) ) { switch (method) { case IGRAPH_REALIZE_DEGSEQ_SMALLEST: IGRAPH_CHECK(igraph_i_realize_undirected_multi(deg, &edges, true, false)); break; case IGRAPH_REALIZE_DEGSEQ_LARGEST: IGRAPH_CHECK(igraph_i_realize_undirected_multi(deg, &edges, true, true)); break; case IGRAPH_REALIZE_DEGSEQ_INDEX: IGRAPH_CHECK(igraph_i_realize_undirected_multi_index(deg, &edges, true)); break; default: IGRAPH_ERROR("Invalid degree sequence realization method.", IGRAPH_EINVAL); } } else if ( ! (allowed_edge_types & IGRAPH_LOOPS_SW) && (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) ) { switch (method) { case IGRAPH_REALIZE_DEGSEQ_SMALLEST: IGRAPH_CHECK(igraph_i_realize_undirected_multi(deg, &edges, false, false)); break; case IGRAPH_REALIZE_DEGSEQ_LARGEST: IGRAPH_CHECK(igraph_i_realize_undirected_multi(deg, &edges, false, true)); break; case IGRAPH_REALIZE_DEGSEQ_INDEX: IGRAPH_CHECK(igraph_i_realize_undirected_multi_index(deg, &edges, false)); break; default: IGRAPH_ERROR("Invalid degree sequence realization method.", IGRAPH_EINVAL); } } else if ( (allowed_edge_types & IGRAPH_LOOPS_SW) && ! (allowed_edge_types & IGRAPH_I_MULTI_LOOPS_SW) && ! (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) ) { IGRAPH_ERROR("Graph realization with at most one self-loop per vertex is not implemented.", IGRAPH_UNIMPLEMENTED); } else if ( ! (allowed_edge_types & IGRAPH_LOOPS_SW) && ! (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) ) { switch (method) { case IGRAPH_REALIZE_DEGSEQ_SMALLEST: IGRAPH_CHECK(igraph_i_havel_hakimi(deg, &edges, false)); break; case IGRAPH_REALIZE_DEGSEQ_LARGEST: IGRAPH_CHECK(igraph_i_havel_hakimi(deg, &edges, true)); break; case IGRAPH_REALIZE_DEGSEQ_INDEX: IGRAPH_CHECK(igraph_i_havel_hakimi_index(deg, &edges)); break; default: IGRAPH_ERROR("Invalid degree sequence realization method.", IGRAPH_EINVAL); } } else { /* Remainig cases: * - At most one self-loop per vertex but multi-edges between distinct vertices allowed. * - At most one edge between distinct vertices but multi-self-loops allowed. * These cases cannot currently be requested through the documented API, * so no explanatory error message for now. */ return IGRAPH_UNIMPLEMENTED; } igraph_create(graph, &edges, igraph_integer_t(node_count), false); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } static int igraph_i_realize_directed_degree_sequence( igraph_t *graph, const igraph_vector_t *outdeg, const igraph_vector_t *indeg, igraph_edge_type_sw_t allowed_edge_types, igraph_realize_degseq_t method) { long node_count = igraph_vector_size(outdeg); long edge_count = long(igraph_vector_sum(outdeg)); if (igraph_vector_size(indeg) != node_count) { IGRAPH_ERROR("In- and out-degree sequences must have the same length.", IGRAPH_EINVAL); } if (igraph_vector_sum(indeg) != edge_count) { IGRAPH_ERROR("In- and out-degree sequences do not sum to the same value.", IGRAPH_EINVAL); } if (node_count > 0 && (igraph_vector_min(outdeg) < 0 || igraph_vector_min(indeg) < 0)) { IGRAPH_ERROR("Vertex degrees must be non-negative.", IGRAPH_EINVAL); } /* TODO implement loopless and loopy multigraph case */ if (allowed_edge_types != IGRAPH_SIMPLE_SW) { IGRAPH_ERROR("Realizing directed degree sequences as non-simple graphs is not implemented.", IGRAPH_UNIMPLEMENTED); } igraph_vector_t edges; IGRAPH_CHECK(igraph_vector_init(&edges, 2 * edge_count)); IGRAPH_FINALLY(igraph_vector_destroy, &edges); switch (method) { case IGRAPH_REALIZE_DEGSEQ_SMALLEST: IGRAPH_CHECK(igraph_i_kleitman_wang(outdeg, indeg, &edges, true)); break; case IGRAPH_REALIZE_DEGSEQ_LARGEST: IGRAPH_CHECK(igraph_i_kleitman_wang(outdeg, indeg, &edges, false)); break; case IGRAPH_REALIZE_DEGSEQ_INDEX: IGRAPH_CHECK(igraph_i_kleitman_wang_index(outdeg, indeg, &edges)); break; default: IGRAPH_ERROR("Invalid directed degree sequence realization method.", IGRAPH_EINVAL); } igraph_create(graph, &edges, igraph_integer_t(node_count), true); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \ingroup generators * \function igraph_realize_degree_sequence * \brief Generates a graph with the given degree sequence. * * This function generates an undirected graph that realizes a given degree sequence, * or a directed graph that realized a given pair of out- and in-degree sequences. * * * Simple undirected graphs are constructed using the Havel-Hakimi algorithm * (undirected case), or the analogous Kleitman-Wang algorithm (directed case). * These algorithms work by choosing an arbitrary vertex and connecting all its stubs * to other vertices of highest degree. In the directed case, the "highest" (in, out) degree * pairs are determined based on lexicographic ordering. This step is repeated until all degrees * have been connected up. * * * Loopless multigraphs are generated using an analogous algorithm: an arbitrary vertex is chosen, * and it is connected with a single connection to a highest remaining degee vertex. If self-loops * are also allowed, the same algorithm is used, but if a non-zero vertex remains at the end of the * procedure, the graph is completed by adding self-loops to it. Thus, the result will contain at most * one vertex with self-loops. * * * The \c method parameter controls the order in which the vertices to be connected are chosen. * * * References: * * * V. Havel, * Poznámka o existenci konečných grafů (A remark on the existence of finite graphs), * Časopis pro pěstování matematiky 80, 477-480 (1955). * http://eudml.org/doc/19050 * * * S. L. Hakimi, * On Realizability of a Set of Integers as Degrees of the Vertices of a Linear Graph, * Journal of the SIAM 10, 3 (1962). * https://www.jstor.org/stable/2098746 * * * D. J. Kleitman and D. L. Wang, * Algorithms for Constructing Graphs and Digraphs with Given Valences and Factors, * Discrete Mathematics 6, 1 (1973). * https://doi.org/10.1016/0012-365X%2873%2990037-X * * * Sz. Horvát and C. D. Modes, * Connectivity matters: Construction and exact random sampling of connected graphs (2020). * https://arxiv.org/abs/2009.03747 * * \param graph Pointer to an uninitialized graph object. * \param outdeg The degree sequence of an undirected graph * (if \p indeg is NULL), or the out-degree sequence of * a directed graph (if \p indeg is given). * \param indeg The in-degree sequence of a directed graph. * Pass \c NULL to generate an undirected graph. * \param allowed_edge_types The types of edges to allow in the graph. For directed graphs, * only \c IGRAPH_SIMPLE_SW is implemented at this moment. For undirected * graphs, the following values are valid: * \clist * \cli IGRAPH_SIMPLE_SW * simple graphs (i.e. no self-loops or multi-edges allowed). * \cli IGRAPH_LOOPS_SW * single self-loops are allowed, but not multi-edges; currently not implemented. * \cli IGRAPH_MULTI_SW * multi-edges are allowed, but not self-loops. * \cli IGRAPH_LOOPS_SW | IGRAPH_MULTI_SW * both self-loops and multi-edges are allowed. * \endclist * \param method The method to generate the graph. Possible values: * \clist * \cli IGRAPH_REALIZE_DEGSEQ_SMALLEST * The vertex with smallest remaining degree is selected first. The result is usually * a graph with high negative degree assortativity. In the undirected case, this method * is guaranteed to generate a connected graph, regardless of whether multi-edges are allowed, * provided that a connected realization exists (see Horvát and Modes, 2020, as well as * http://szhorvat.net/pelican/hh-connected-graphs.html). * In the directed case it tends to generate weakly connected graphs, but this is not * guaranteed. * \cli IGRAPH_REALIZE_DEGSEQ_LARGEST * The vertex with the largest remaining degree is selected first. The result * is usually a graph with high positive degree assortativity, and is often disconnected. * \cli IGRAPH_REALIZE_DEGSEQ_INDEX * The vertices are selected in order of their index (i.e. their position in the degree vector). * Note that sorting the degree vector and using the \c INDEX method is not equivalent * to the \c SMALLEST method above, as \c SMALLEST uses the smallest \em remaining * degree for selecting vertices, not the smallest \em initial degree. * \endclist * \return Error code: * \clist * \cli IGRAPH_UNIMPLEMENTED * The requested method is not implemented. * \cli IGRAPH_ENOMEM * There is not enough memory to perform the operation. * \cli IGRAPH_EINVAL * Invalid method parameter, or invalid in- and/or out-degree vectors. * The degree vectors should be non-negative, the length * and sum of \p outdeg and \p indeg should match for directed graphs. * \endclist * * \sa \ref igraph_is_graphical() to test graphicality without generating a graph; * \ref igraph_degree_sequence_game() to generate random graphs with a given degree sequence; * \ref igraph_k_regular_game() to generate random regular graphs; * \ref igraph_rewire() to randomly rewire the edges of a graph while preserving its degree sequence. * */ int igraph_realize_degree_sequence( igraph_t *graph, const igraph_vector_t *outdeg, const igraph_vector_t *indeg, igraph_edge_type_sw_t allowed_edge_types, igraph_realize_degseq_t method) { long n = igraph_vector_size(outdeg); if (n != igraph_integer_t(n)) { // does the vector size fit into an igraph_integer_t ? IGRAPH_ERROR("Degree sequence vector too long.", IGRAPH_EINVAL); } bool directed = indeg != 0; try { if (directed) { return igraph_i_realize_directed_degree_sequence(graph, outdeg, indeg, allowed_edge_types, method); } else { return igraph_i_realize_undirected_degree_sequence(graph, outdeg, allowed_edge_types, method); } } catch (const std::bad_alloc &) { IGRAPH_ERROR("Cannot realize degree sequence due to insufficient memory.", IGRAPH_ENOMEM); } } leidenbase/src/core/misc/graphicality.c0000644000176200001440000010203214447675375017667 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_graphicality.h" #include "igraph_qsort.h" #define IGRAPH_I_MULTI_EDGES_SW 0x02 /* 010, more than one edge allowed between distinct vertices */ #define IGRAPH_I_MULTI_LOOPS_SW 0x04 /* 100, more than one self-loop allowed on the same vertex */ static int igraph_i_is_graphical_undirected_multi_loops(const igraph_vector_t *degrees, igraph_bool_t *res); static int igraph_i_is_graphical_undirected_loopless_multi(const igraph_vector_t *degrees, igraph_bool_t *res); static int igraph_i_is_graphical_undirected_loopy_simple(const igraph_vector_t *degrees, igraph_bool_t *res); static int igraph_i_is_graphical_undirected_simple(const igraph_vector_t *degrees, igraph_bool_t *res); static int igraph_i_is_graphical_directed_loopy_multi(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res); static int igraph_i_is_graphical_directed_loopless_multi(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res); static int igraph_i_is_graphical_directed_loopy_simple(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res); static int igraph_i_is_graphical_directed_simple(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res); static int igraph_i_is_bigraphical_multi(const igraph_vector_t *degrees1, const igraph_vector_t *degrees2, igraph_bool_t *res); static int igraph_i_is_bigraphical_simple(const igraph_vector_t *degrees1, const igraph_vector_t *degrees2, igraph_bool_t *res); /** * \function igraph_is_graphical * \brief Is there a graph with the given degree sequence? * * Determines whether a sequence of integers can be the degree sequence of some graph. * The classical concept of graphicality assumes simple graphs. This function can perform * the check also when either self-loops, multi-edge, or both are allowed in the graph. * * * For simple undirected graphs, the Erdős-Gallai conditions are checked using the linear-time * algorithm of Cloteaux. If both self-loops and multi-edges are allowed, * it is sufficient to chek that that sum of degrees is even. If only multi-edges are allowed, but * not self-loops, there is an additional condition that the sum of degrees be no smaller than twice * the maximum degree. If at most one self-loop is allowed per vertex, but no multi-edges, a modified * version of the Erdős-Gallai conditions are used (see Cairns & Mendan). * * * For simple directed graphs, the Fulkerson-Chen-Anstee theorem is used with the relaxation by Berger. * If both self-loops and multi-edges are allowed, then it is sufficient to check that the sum of * in- and out-degrees is the same. If only multi-edges are allowed, but not self loops, there is an * additional condition that the sum of out-degrees (or equivalently, in-degrees) is no smaller than * the maximum total degree. If single self-loops are allowed, but not multi-edges, the problem is equivalent * to realizability as a simple bipartite graph, thus the Gale-Ryser theorem can be used; see * \ref igraph_is_bigraphical() for more information. * * * References: * * * P. Erdős and T. Gallai, Gráfok előírt fokú pontokkal, Matematikai Lapok 11, pp. 264–274 (1960). * https://users.renyi.hu/~p_erdos/1961-05.pdf * * * Z Király, Recognizing graphic degree sequences and generating all realizations. * TR-2011-11, Egerváry Research Group, H-1117, Budapest, Hungary. ISSN 1587-4451 (2012). * http://bolyai.cs.elte.hu/egres/tr/egres-11-11.pdf * * * B. Cloteaux, Is This for Real? Fast Graphicality Testing, Comput. Sci. Eng. 17, 91 (2015). * https://dx.doi.org/10.1109/MCSE.2015.125 * * * A. Berger, A note on the characterization of digraphic sequences, Discrete Math. 314, 38 (2014). * https://dx.doi.org/10.1016/j.disc.2013.09.010 * * * G. Cairns and S. Mendan, Degree Sequence for Graphs with Loops (2013). * https://arxiv.org/abs/1303.2145v1 * * \param out_degrees A vector of integers specifying the degree sequence for * undirected graphs or the out-degree sequence for directed graphs. * \param in_degrees A vector of integers specifying the in-degree sequence for * directed graphs. For undirected graphs, it must be \c NULL. * \param allowed_edge_types The types of edges to allow in the graph: * \clist * \cli IGRAPH_SIMPLE_SW * simple graphs (i.e. no self-loops or multi-edges allowed). * \cli IGRAPH_LOOPS_SW * single self-loops are allowed, but not multi-edges. * \cli IGRAPH_MULTI_SW * multi-edges are allowed, but not self-loops. * \cli IGRAPH_LOOPS_SW | IGRAPH_MULTI_SW * both self-loops and multi-edges are allowed. * \endclist * \param res Pointer to a Boolean. The result will be stored here. * * \return Error code. * * \sa \ref igraph_is_bigraphical() to check if a bi-degree-sequence can be realized as a bipartite graph; * \ref igraph_realize_degree_sequence() to construct a graph with a given degree sequence. * * Time complexity: O(n^2) for simple directed graphs, O(n log n) for graphs with self-loops, * and O(n) for all other cases, where n is the length of the degree sequence(s). */ int igraph_is_graphical(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, const igraph_edge_type_sw_t allowed_edge_types, igraph_bool_t *res) { /* Undirected case: */ if (in_degrees == NULL) { if ( (allowed_edge_types & IGRAPH_LOOPS_SW) && (allowed_edge_types & IGRAPH_I_MULTI_LOOPS_SW )) { /* Typically this case is used when multiple edges are allowed both as self-loops and * between distinct vertices. However, the conditions are the same even if multi-edges * are not allowed between distinct vertices (only as self-loops). Therefore, we * do not test IGRAPH_I_MULTI_EDGES_SW in the if (...). */ return igraph_i_is_graphical_undirected_multi_loops(out_degrees, res); } else if ( ! (allowed_edge_types & IGRAPH_LOOPS_SW) && (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) ) { return igraph_i_is_graphical_undirected_loopless_multi(out_degrees, res); } else if ( (allowed_edge_types & IGRAPH_LOOPS_SW) && ! (allowed_edge_types & IGRAPH_I_MULTI_LOOPS_SW) && ! (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) ) { return igraph_i_is_graphical_undirected_loopy_simple(out_degrees, res); } else if ( ! (allowed_edge_types & IGRAPH_LOOPS_SW) && ! (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) ) { return igraph_i_is_graphical_undirected_simple(out_degrees, res); } else { /* Remainig case: * - At most one self-loop per vertex but multi-edges between distinct vertices allowed. * These cases cannot currently be requested through the documented API, * so no explanatory error message for now. */ return IGRAPH_UNIMPLEMENTED; } } /* Directed case: */ else { if ( (allowed_edge_types & IGRAPH_LOOPS_SW) && (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) && (allowed_edge_types & IGRAPH_I_MULTI_LOOPS_SW ) ) { return igraph_i_is_graphical_directed_loopy_multi(out_degrees, in_degrees, res); } else if ( ! (allowed_edge_types & IGRAPH_LOOPS_SW) && (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) ) { return igraph_i_is_graphical_directed_loopless_multi(out_degrees, in_degrees, res); } else if ( (allowed_edge_types & IGRAPH_LOOPS_SW) && ! (allowed_edge_types & IGRAPH_I_MULTI_LOOPS_SW) && ! (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) ) { return igraph_i_is_graphical_directed_loopy_simple(out_degrees, in_degrees, res); } else if ( ! (allowed_edge_types & IGRAPH_LOOPS_SW) && ! (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) ) { return igraph_i_is_graphical_directed_simple(out_degrees, in_degrees, res); } else { /* Remainig cases: * - At most one self-loop per vertex but multi-edges between distinct vertices allowed. * - At most one edge between distinct vertices but multi-self-loops allowed. * These cases cannot currently be requested through the documented API, * so no explanatory error message for now. */ return IGRAPH_UNIMPLEMENTED; } } /* can't reach here */ } /** * \function igraph_is_bigraphical * \brief Is there a bipartite graph with the given bi-degree-sequence? * * Determines whether two sequences of integers can be the degree sequences of * a bipartite graph. Such a pair of degree sequence is called \em bigraphical. * * * When multi-edges are allowed, it is sufficient to check that the sum of degrees is the * same in the two partitions. For simple graphs, the Gale-Ryser theorem is used * with Berger's relaxation. * * * References: * * * H. J. Ryser, Combinatorial Properties of Matrices of Zeros and Ones, Can. J. Math. 9, 371 (1957). * https://dx.doi.org/10.4153/cjm-1957-044-3 * * * D. Gale, A theorem on flows in networks, Pacific J. Math. 7, 1073 (1957). * https://dx.doi.org/10.2140/pjm.1957.7.1073 * * * A. Berger, A note on the characterization of digraphic sequences, Discrete Math. 314, 38 (2014). * https://dx.doi.org/10.1016/j.disc.2013.09.010 * * \param degrees1 A vector of integers specifying the degrees in the first partition * \param degrees2 A vector of integers specifying the degrees in the second partition * \param allowed_edge_types The types of edges to allow in the graph: * \clist * \cli IGRAPH_SIMPLE_SW * simple graphs (i.e. no multi-edges allowed). * \cli IGRAPH_MULTI_SW * multi-edges are allowed. * \endclist * \param res Pointer to a Boolean. The result will be stored here. * * \return Error code. * * \sa \ref igraph_is_graphical() * * Time complexity: O(n log n) for simple graphs, O(n) for multigraphs, * where n is the length of the larger degree sequence. */ int igraph_is_bigraphical(const igraph_vector_t *degrees1, const igraph_vector_t *degrees2, const igraph_edge_type_sw_t allowed_edge_types, igraph_bool_t *res) { /* Note: Bipartite graphs can't have self-loops so we ignore the IGRAPH_LOOPS_SW bit. */ if (allowed_edge_types & IGRAPH_I_MULTI_EDGES_SW) { return igraph_i_is_bigraphical_multi(degrees1, degrees2, res); } else { return igraph_i_is_bigraphical_simple(degrees1, degrees2, res); } } /***** Undirected case *****/ /* Undirected graph with multi-self-loops: * - Degrees must be non-negative. * - The sum of degrees must be even. * * These conditions are valid regardless of whether multi-edges are allowed between distinct vertices. */ static int igraph_i_is_graphical_undirected_multi_loops(const igraph_vector_t *degrees, igraph_bool_t *res) { long int sum_parity = 0; /* 0 if the degree sum is even, 1 if it is odd */ long int n = igraph_vector_size(degrees); long int i; for (i=0; i < n; ++i) { long int d = VECTOR(*degrees)[i]; if (d < 0) { *res = 0; return IGRAPH_SUCCESS; } sum_parity = (sum_parity + d) & 1; } *res = (sum_parity == 0); return IGRAPH_SUCCESS; } /* Undirected loopless multigraph: * - Degrees must be non-negative. * - The sum of degrees must be even. * - The sum of degrees must be no smaller than 2*d_max. */ static int igraph_i_is_graphical_undirected_loopless_multi(const igraph_vector_t *degrees, igraph_bool_t *res) { long int i; long int n = igraph_vector_size(degrees); long int dsum, dmax; /* Zero-length sequences are considered graphical. */ if (n == 0) { *res = 1; return IGRAPH_SUCCESS; } dsum = 0; dmax = 0; for (i=0; i < n; ++i) { long int d = VECTOR(*degrees)[i]; if (d < 0) { *res = 0; return IGRAPH_SUCCESS; } dsum += d; if (d > dmax) { dmax = d; } } *res = (dsum % 2 == 0) && (dsum >= 2*dmax); return IGRAPH_SUCCESS; } /* Undirected graph with no multi-edges and at most one self-loop per vertex: * - Degrees must be non-negative. * - The sum of degrees must be even. * - Use the modification of the Erdős-Gallai theorem due to Cairns and Mendan. */ static int igraph_i_is_graphical_undirected_loopy_simple(const igraph_vector_t *degrees, igraph_bool_t *res) { igraph_vector_t work; long int w, b, s, c, n, k; n = igraph_vector_size(degrees); /* Zero-length sequences are considered graphical. */ if (n == 0) { *res = 1; return IGRAPH_SUCCESS; } /* The conditions from the loopy multigraph case are necessary here as well. */ IGRAPH_CHECK(igraph_i_is_graphical_undirected_multi_loops(degrees, res)); if (! *res) { return IGRAPH_SUCCESS; } /* * We follow this paper: * * G. Cairns & S. Mendan: Degree Sequences for Graphs with Loops, 2013 * https://arxiv.org/abs/1303.2145v1 * * They give the following modification of the Erdős-Gallai theorem: * * A non-increasing degree sequence d_1 >= ... >= d_n has a realization as * a simple graph with loops (i.e. at most one self-loop allowed on each vertex) * iff * * \sum_{i=1}^k d_i <= k(k+1) + \sum_{i=k+1}^{n} min(d_i, k) * * for each k=1..n * * The difference from Erdős-Gallai is that here we have the term * k(k+1) instead of k(k-1). * * The implementation is analogous to igraph_i_is_graphical_undirected_simple(), * which in turn is based on Király 2012. See comments in that function for details. * w and k are zero-based here, unlike in the statement of the theorem above. */ IGRAPH_CHECK(igraph_vector_copy(&work, degrees)); IGRAPH_FINALLY(igraph_vector_destroy, &work); igraph_vector_reverse_sort(&work); *res = 1; w = n - 1; b = 0; s = 0; c = 0; for (k = 0; k < n; k++) { b += VECTOR(work)[k]; c += w; while (w > k && VECTOR(work)[w] <= k + 1) { s += VECTOR(work)[w]; c -= (k + 1); w--; } if (b > c + s + 2*(k + 1)) { *res = 0; break; } if (w == k) { break; } } igraph_vector_destroy(&work); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Undirected simple graph: * - Degrees must be non-negative. * - The sum of degrees must be even. * - Use the Erdős-Gallai theorem. */ static int igraph_i_is_graphical_undirected_simple(const igraph_vector_t *degrees, igraph_bool_t *res) { igraph_vector_int_t num_degs; /* num_degs[d] is the # of vertices with degree d */ const long int p = igraph_vector_size(degrees); long int dmin, dmax, dsum; long int n; /* number of non-zero degrees */ long int k, sum_deg, sum_ni, sum_ini; long int i, dk; long int zverovich_bound; if (p == 0) { *res = 1; return IGRAPH_SUCCESS; } /* The following implementation of the Erdős-Gallai test * is mostly a direct translation of the Python code given in * * Brian Cloteaux, Is This for Real? Fast Graphicality Testing, * Computing Prescriptions, pp. 91-95, vol. 17 (2015) * https://dx.doi.org/10.1109/MCSE.2015.125 * * It uses counting sort to achieve linear runtime. */ IGRAPH_VECTOR_INT_INIT_FINALLY(&num_degs, p); dmin = p; dmax = 0; dsum = 0; n = 0; for (i=0; i < p; ++i) { long int d = VECTOR(*degrees)[i]; if (d < 0 || d >= p) { *res = 0; goto finish; } if (d > 0) { dmax = d > dmax ? d : dmax; dmin = d < dmin ? d : dmin; dsum += d; n++; VECTOR(num_degs)[d] += 1; } } if (dsum % 2 != 0) { *res = 0; goto finish; } if (n == 0) { *res = 1; goto finish; /* all degrees are zero => graphical */ } /* According to: * * G. Cairns, S. Mendan, and Y. Nikolayevsky, A sharp refinement of a result of Zverovich-Zverovich, * Discrete Math. 338, 1085 (2015). * https://dx.doi.org/10.1016/j.disc.2015.02.001 * * a sufficient but not necessary condition of graphicality for a sequence of * n strictly positive integers is that * * dmin * n >= floor( (dmax + dmin + 1)^2 / 4 ) - 1 * if dmin is odd or (dmax + dmin) mod 4 == 1 * * or * * dmin * n >= floor( (dmax + dmin + 1)^2 / 4 ) * otherwise. */ zverovich_bound = ((dmax + dmin + 1) * (dmax + dmin + 1)) / 4; if (dmin % 2 == 1 || (dmax + dmin) % 4 == 1) { zverovich_bound -= 1; } if (dmin*n >= zverovich_bound) { *res = 1; goto finish; } k = 0; sum_deg = 0; sum_ni = 0; sum_ini = 0; for (dk = dmax; dk >= dmin; --dk) { long int run_size, v; if (dk < k+1) { *res = 1; goto finish; } run_size = VECTOR(num_degs)[dk]; if (run_size > 0) { if (dk < k + run_size) { run_size = dk - k; } sum_deg += run_size * dk; for (v=0; v < run_size; ++v) { sum_ni += VECTOR(num_degs)[k+v]; sum_ini += (k+v) * VECTOR(num_degs)[k+v]; } k += run_size; if (sum_deg > k*(n-1) - k*sum_ni + sum_ini) { *res = 0; goto finish; } } } *res = 1; finish: igraph_vector_int_destroy(&num_degs); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /***** Directed case *****/ /* Directed loopy multigraph: * - Degrees must be non-negative. * - The sum of in- and out-degrees must be the same. */ static int igraph_i_is_graphical_directed_loopy_multi(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res) { long int sumdiff; /* difference between sum of in- and out-degrees */ long int n = igraph_vector_size(out_degrees); long int i; if (igraph_vector_size(in_degrees) != n) { IGRAPH_ERROR("The length of out- and in-degree sequences must be the same.", IGRAPH_EINVAL); } sumdiff = 0; for (i=0; i < n; ++i) { long int dout = VECTOR(*out_degrees)[i]; long int din = VECTOR(*in_degrees)[i]; if (dout < 0 || din < 0) { *res = 0; return IGRAPH_SUCCESS; } sumdiff += din - dout; } *res = sumdiff == 0; return IGRAPH_SUCCESS; } /* Directed loopless multigraph: * - Degrees must be non-negative. * - The sum of in- and out-degrees must be the same. * - The sum of out-degrees must be no smaller than d_max, * where d_max is the largest total degree. */ static int igraph_i_is_graphical_directed_loopless_multi(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res) { long int i, sumin, sumout, dmax; long int n = igraph_vector_size(out_degrees); if (igraph_vector_size(in_degrees) != n) { IGRAPH_ERROR("The length of out- and in-degree sequences must be the same.", IGRAPH_EINVAL); } sumin = 0; sumout = 0; dmax = 0; for (i=0; i < n; ++i) { long int dout = VECTOR(*out_degrees)[i]; long int din = VECTOR(*in_degrees)[i]; long int d = dout + din; if (dout < 0 || din < 0) { *res = 0; return IGRAPH_SUCCESS; } sumin += din; sumout += dout; if (d > dmax) { dmax = d; } } *res = (sumin == sumout) && (sumout >= dmax); return IGRAPH_SUCCESS; } /* Directed graph with no multi-edges and at most one self-loop per vertex: * - Degrees must be non-negative. * - Equivalent to bipartite simple graph. */ static int igraph_i_is_graphical_directed_loopy_simple(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res) { long int n = igraph_vector_size(out_degrees); if (igraph_vector_size(in_degrees) != n) { IGRAPH_ERROR("The length of out- and in-degree sequences must be the same.", IGRAPH_EINVAL); } return igraph_i_is_bigraphical_simple(out_degrees, in_degrees, res); } /* Directed simple graph: * - Degrees must be non-negative. * - The sum of in- and out-degrees must be the same. * - Use the Fulkerson-Chen-Anstee theorem */ typedef struct { const igraph_vector_t* first; const igraph_vector_t* second; } igraph_i_qsort_dual_vector_cmp_data_t; static int igraph_i_qsort_dual_vector_cmp_desc(void* data, const void *p1, const void *p2) { igraph_i_qsort_dual_vector_cmp_data_t* sort_data = (igraph_i_qsort_dual_vector_cmp_data_t*)data; long int index1 = *((long int*)p1); long int index2 = *((long int*)p2); if (VECTOR(*sort_data->first)[index1] < VECTOR(*sort_data->first)[index2]) { return 1; } if (VECTOR(*sort_data->first)[index1] > VECTOR(*sort_data->first)[index2]) { return -1; } if (VECTOR(*sort_data->second)[index1] < VECTOR(*sort_data->second)[index2]) { return 1; } if (VECTOR(*sort_data->second)[index1] > VECTOR(*sort_data->second)[index2]) { return -1; } return 0; } static int igraph_i_is_graphical_directed_simple(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res) { igraph_vector_long_t index_array; long int i, j, vcount, lhs, rhs; igraph_i_qsort_dual_vector_cmp_data_t sort_data; /* The conditions from the loopy multigraph case are necessary here as well. */ IGRAPH_CHECK(igraph_i_is_graphical_directed_loopy_multi(out_degrees, in_degrees, res)); if (! *res) { return IGRAPH_SUCCESS; } vcount = igraph_vector_size(out_degrees); if (vcount == 0) { *res = 1; return IGRAPH_SUCCESS; } /* Create an index vector that sorts the vertices by decreasing in-degree */ IGRAPH_CHECK(igraph_vector_long_init_seq(&index_array, 0, vcount - 1)); IGRAPH_FINALLY(igraph_vector_long_destroy, &index_array); /* Set up the auxiliary struct for sorting */ sort_data.first = in_degrees; sort_data.second = out_degrees; /* Sort the index vector */ igraph_qsort_r(VECTOR(index_array), vcount, sizeof(long int), &sort_data, igraph_i_qsort_dual_vector_cmp_desc); /* Be optimistic, then check whether the Fulkerson–Chen–Anstee condition * holds for every k. In particular, for every k in [0; n), it must be true * that: * * \sum_{i=0}^k indegree[i] <= * \sum_{i=0}^k min(outdegree[i], k) + * \sum_{i=k+1}^{n-1} min(outdegree[i], k + 1) */ #define INDEGREE(x) (VECTOR(*in_degrees)[VECTOR(index_array)[x]]) #define OUTDEGREE(x) (VECTOR(*out_degrees)[VECTOR(index_array)[x]]) *res = 1; lhs = 0; for (i = 0; i < vcount; i++) { lhs += INDEGREE(i); /* It is enough to check for indexes where the in-degree is about to * decrease in the next step; see "Stronger condition" in the Wikipedia * entry for the Fulkerson-Chen-Anstee condition */ if (i != vcount - 1 && INDEGREE(i) == INDEGREE(i + 1)) { continue; } rhs = 0; for (j = 0; j <= i; j++) { rhs += OUTDEGREE(j) < i ? OUTDEGREE(j) : i; } for (j = i + 1; j < vcount; j++) { rhs += OUTDEGREE(j) < (i + 1) ? OUTDEGREE(j) : (i + 1); } if (lhs > rhs) { *res = 0; break; } } #undef INDEGREE #undef OUTDEGREE igraph_vector_long_destroy(&index_array); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /***** Bipartite case *****/ /* Bipartite graph with multi-eges: * - Degrees must be non-negative. * - Sum of degrees must be the same in the two partitions. */ static int igraph_i_is_bigraphical_multi(const igraph_vector_t *degrees1, const igraph_vector_t *degrees2, igraph_bool_t *res) { long int i; long int sum1, sum2; long int n1 = igraph_vector_size(degrees1), n2 = igraph_vector_size(degrees2); sum1 = 0; for (i=0; i < n1; ++i) { long int d = VECTOR(*degrees1)[i]; if (d < 0) { *res = 0; return IGRAPH_SUCCESS; } sum1 += d; } sum2 = 0; for (i=0; i < n2; ++i) { long int d = VECTOR(*degrees2)[i]; if (d < 0) { *res = 0; return IGRAPH_SUCCESS; } sum2 += d; } *res = (sum1 == sum2); return IGRAPH_SUCCESS; } /* Bipartite simple graph: * - Degrees must be non-negative. * - Sum of degrees must be the same in the two partitions. * - Use the Gale-Ryser theorem. */ static int igraph_i_is_bigraphical_simple(const igraph_vector_t *degrees1, const igraph_vector_t *degrees2, igraph_bool_t *res) { igraph_vector_t sorted_deg1, sorted_deg2; long int n1 = igraph_vector_size(degrees1), n2 = igraph_vector_size(degrees2); long int i, k; long lhs_sum, partial_rhs_sum; if (n1 == 0 && n2 == 0) { *res = 1; return IGRAPH_SUCCESS; } /* The conditions from the multigraph case are necessary here as well. */ IGRAPH_CHECK(igraph_i_is_bigraphical_multi(degrees1, degrees2, res)); if (! *res) { return IGRAPH_SUCCESS; } /* Ensure that degrees1 is the shorter vector as a minor optimization: */ if (n2 < n1) { const igraph_vector_t *tmp; long int n; tmp = degrees1; degrees1 = degrees2; degrees2 = tmp; n = n1; n1 = n2; n2 = n; } /* Copy and sort both vectors: */ IGRAPH_CHECK(igraph_vector_copy(&sorted_deg1, degrees1)); IGRAPH_FINALLY(igraph_vector_destroy, &sorted_deg1); igraph_vector_reverse_sort(&sorted_deg1); /* decreasing sort */ IGRAPH_CHECK(igraph_vector_copy(&sorted_deg2, degrees2)); IGRAPH_FINALLY(igraph_vector_destroy, &sorted_deg2); igraph_vector_sort(&sorted_deg2); /* increasing sort */ /* * We follow the description of the Gale-Ryser theorem in: * * A. Berger, A note on the characterization of digraphic sequences, Discrete Math. 314, 38 (2014). * http://dx.doi.org/10.1016/j.disc.2013.09.010 * * Gale-Ryser condition with 0-based indexing: * * a_i and b_i denote the degree sequences of the two partitions. * * Assuming that a_0 >= a_1 >= ... >= a_{n_1 - 1}, * * \sum_{i=0}^k a_i <= \sum_{j=0}^{n_2} min(b_i, k+1) * * for all 0 <= k < n_1 */ /* While this formulation does not require sorting degree2, * doing so allows for a linear-time incremental computation * of the inequality's right-hand-side. */ *res = 1; /* be optimistic */ lhs_sum = 0; partial_rhs_sum = 0; /* the sum of those elements in sorted_deg2 which are <= (k+1) */ i = 0; /* points past the first element of sorted_deg2 which > (k+1) */ for (k=0; k < n1; ++k) { lhs_sum += VECTOR(sorted_deg1)[k]; /* Based on Theorem 3 in [Berger 2014], it is sufficient to do the check * for k such that a_k > a_{k+1} and for k=(n_1-1). */ if (k < n1-1 && VECTOR(sorted_deg1)[k] == VECTOR(sorted_deg1)[k+1]) continue; while (i < n2 && VECTOR(sorted_deg2)[i] <= k+1) { partial_rhs_sum += VECTOR(sorted_deg2)[i]; i++; } /* rhs_sum for a given k is partial_rhs_sum + (n2 - i) * (k+1) */ if (lhs_sum > partial_rhs_sum + (n2 - i) * (k+1) ) { *res = 0; break; } } igraph_vector_destroy(&sorted_deg2); igraph_vector_destroy(&sorted_deg1); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /***** Legacy functions *****/ #define SUCCEED { \ if (res) { \ *res = 1; \ } \ return IGRAPH_SUCCESS; \ } #define FAIL { \ if (res) { \ *res = 0; \ } \ return IGRAPH_SUCCESS; \ } /** * \function igraph_is_degree_sequence * \brief Determines whether a degree sequence is valid. * * \deprecated-by igraph_is_graphical 0.9 * * * A sequence of n integers is a valid degree sequence if there exists some * graph where the degree of the i-th vertex is equal to the i-th element of the * sequence. Note that the graph may contain multiple or loop edges; if you are * interested in whether the degrees of some \em simple graph may realize the * given sequence, use \ref igraph_is_graphical_degree_sequence. * * * In particular, the function checks whether all the degrees are non-negative. * For undirected graphs, it also checks whether the sum of degrees is even. * For directed graphs, the function checks whether the lengths of the two * degree vectors are equal and whether their sums are also equal. These are * known sufficient and necessary conditions for a degree sequence to be * valid. * * \param out_degrees an integer vector specifying the degree sequence for * undirected graphs or the out-degree sequence for directed graphs. * \param in_degrees an integer vector specifying the in-degrees of the * vertices for directed graphs. For undirected graphs, this must be null. * \param res pointer to a boolean variable, the result will be stored here * \return Error code. * * Time complexity: O(n), where n is the length of the degree sequence. */ int igraph_is_degree_sequence(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res) { IGRAPH_WARNING("igraph_is_degree_sequence is deprecated, use igraph_is_graphical."); /* degrees must be non-negative */ if (igraph_vector_any_smaller(out_degrees, 0)) { FAIL; } if (in_degrees && igraph_vector_any_smaller(in_degrees, 0)) { FAIL; } if (in_degrees == 0) { /* sum of degrees must be even */ if (((long int)igraph_vector_sum(out_degrees) % 2) != 0) { FAIL; } } else { /* length of the two degree vectors must be equal */ if (igraph_vector_size(out_degrees) != igraph_vector_size(in_degrees)) { FAIL; } /* sum of in-degrees must be equal to sum of out-degrees */ if (igraph_vector_sum(out_degrees) != igraph_vector_sum(in_degrees)) { FAIL; } } SUCCEED; } #undef SUCCEED #undef FAIL /** * \function igraph_is_graphical_degree_sequence * \brief Determines whether a sequence of integers can be the degree sequence of some simple graph. * * \deprecated-by igraph_is_graphical 0.9 * * * References: * * * Hakimi SL: On the realizability of a set of integers as degrees of the * vertices of a simple graph. J SIAM Appl Math 10:496-506, 1962. * * * PL Erdős, I Miklós and Z Toroczkai: A simple Havel-Hakimi type algorithm * to realize graphical degree sequences of directed graphs. * The Electronic Journal of Combinatorics 17(1):R66, 2010. * https://dx.doi.org/10.1017/S0963548317000499 * * * Z Kiraly: Recognizing graphic degree sequences and generating all * realizations. TR-2011-11, Egervary Research Group, H-1117, Budapest, * Hungary. ISSN 1587-4451, 2012. * https://www.cs.elte.hu/egres/tr/egres-11-11.pdf * * \param out_degrees an integer vector specifying the degree sequence for * undirected graphs or the out-degree sequence for directed graphs. * \param in_degrees an integer vector specifying the in-degrees of the * vertices for directed graphs. For undirected graphs, this must be null. * \param res pointer to a boolean variable, the result will be stored here * \return Error code. * * Time complexity: O(n log n) for undirected graphs, O(n^2) for directed * graphs, where n is the length of the degree sequence. */ int igraph_is_graphical_degree_sequence(const igraph_vector_t *out_degrees, const igraph_vector_t *in_degrees, igraph_bool_t *res) { IGRAPH_WARNING("igraph_is_graphical_degree_sequence is deprecated, use igraph_is_graphical."); return igraph_is_graphical(out_degrees, in_degrees, IGRAPH_SIMPLE_SW, res); } leidenbase/src/core/misc/conversion.c0000644000176200001440000010377114447675375017407 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_conversion.h" #include "igraph_iterators.h" #include "igraph_interface.h" #include "igraph_attributes.h" #include "igraph_constructors.h" #include "igraph_structural.h" #include "igraph_sparsemat.h" #include "igraph_random.h" #include "core/fixed_vectorlist.h" #include "graph/attributes.h" #include "misc/conversion_internal.h" /** * \ingroup conversion * \function igraph_get_adjacency * \brief Returns the adjacency matrix of a graph * * * The result is an adjacency matrix. Entry i, j of the matrix * contains the number of edges connecting vertex i to vertex j. * \param graph Pointer to the graph to convert * \param res Pointer to an initialized matrix object, it will be * resized if needed. * \param type Constant giving the type of the adjacency matrix to * create for undirected graphs. It is ignored for directed * graphs. Possible values: * \clist * \cli IGRAPH_GET_ADJACENCY_UPPER * the upper right triangle of the matrix is used. * \cli IGRAPH_GET_ADJACENCY_LOWER * the lower left triangle of the matrix is used. * \cli IGRAPH_GET_ADJACENCY_BOTH * the whole matrix is used, a symmetric matrix is returned * if the graph is undirected. * \endclist * \param type eids Logical, if true, then the edges ids plus one * are stored in the adjacency matrix, instead of the number of * edges between the two vertices. (The plus one is needed, since * edge ids start from zero, and zero means no edge in this case.) * \return Error code: * \c IGRAPH_EINVAL invalid type argument. * * \sa igraph_get_adjacency_sparse if you want a sparse matrix representation * * Time complexity: O(|V||V|), * |V| is the * number of vertices in the graph. */ int igraph_get_adjacency(const igraph_t *graph, igraph_matrix_t *res, igraph_get_adjacency_t type, igraph_bool_t eids) { igraph_eit_t edgeit; long int no_of_nodes = igraph_vcount(graph); igraph_bool_t directed = igraph_is_directed(graph); int retval = 0; long int from, to; igraph_integer_t ffrom, fto; IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, no_of_nodes)); igraph_matrix_null(res); IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(0), &edgeit)); IGRAPH_FINALLY(igraph_eit_destroy, &edgeit); if (directed) { while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); igraph_edge(graph, (igraph_integer_t) edge, &ffrom, &fto); from = ffrom; to = fto; if (eids) { MATRIX(*res, from, to) = edge + 1; } else { MATRIX(*res, from, to) += 1; } IGRAPH_EIT_NEXT(edgeit); } } else if (type == IGRAPH_GET_ADJACENCY_UPPER) { while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); igraph_edge(graph, (igraph_integer_t) edge, &ffrom, &fto); from = ffrom; to = fto; if (to < from) { if (eids) { MATRIX(*res, to, from) = edge + 1; } else { MATRIX(*res, to, from) += 1; } } else { if (eids) { MATRIX(*res, from, to) = edge + 1; } else { MATRIX(*res, from, to) += 1; } } IGRAPH_EIT_NEXT(edgeit); } } else if (type == IGRAPH_GET_ADJACENCY_LOWER) { while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); igraph_edge(graph, (igraph_integer_t) edge, &ffrom, &fto); from = ffrom; to = fto; if (to < from) { if (eids) { MATRIX(*res, from, to) = edge + 1; } else { MATRIX(*res, from, to) += 1; } } else { if (eids) { MATRIX(*res, to, from) = edge + 1; } else { MATRIX(*res, to, from) += 1; } } IGRAPH_EIT_NEXT(edgeit); } } else if (type == IGRAPH_GET_ADJACENCY_BOTH) { while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); igraph_edge(graph, (igraph_integer_t) edge, &ffrom, &fto); from = ffrom; to = fto; if (eids) { MATRIX(*res, from, to) = edge + 1; } else { MATRIX(*res, from, to) += 1; } if (from != to) { if (eids) { MATRIX(*res, to, from) = edge + 1; } else { MATRIX(*res, to, from) += 1; } } IGRAPH_EIT_NEXT(edgeit); } } else { IGRAPH_ERROR("Invalid type argument", IGRAPH_EINVAL); } igraph_eit_destroy(&edgeit); IGRAPH_FINALLY_CLEAN(1); return retval; } /** * \ingroup conversion * \function igraph_get_adjacency_sparse * \brief Returns the adjacency matrix of a graph in sparse matrix format. * * * The result is an adjacency matrix. Entry i, j of the matrix * contains the number of edges connecting vertex i to vertex j. * \param graph Pointer to the graph to convert. * \param res Pointer to an initialized sparse matrix object, it will be * resized if needed. * \param type Constant giving the type of the adjacency matrix to * create for undirected graphs. It is ignored for directed * graphs. Possible values: * \clist * \cli IGRAPH_GET_ADJACENCY_UPPER * the upper right triangle of the matrix is used. * \cli IGRAPH_GET_ADJACENCY_LOWER * the lower left triangle of the matrix is used. * \cli IGRAPH_GET_ADJACENCY_BOTH * the whole matrix is used, a symmetric matrix is returned. * \endclist * \return Error code: * \c IGRAPH_EINVAL invalid type argument. * * \sa igraph_get_adjacency if you would like to get a normal matrix * ( \type igraph_matrix_t ) * * Time complexity: O(|V||V|), * |V| is the * number of vertices in the graph. */ int igraph_get_adjacency_sparse(const igraph_t *graph, igraph_spmatrix_t *res, igraph_get_adjacency_t type) { igraph_eit_t edgeit; long int no_of_nodes = igraph_vcount(graph); igraph_bool_t directed = igraph_is_directed(graph); long int from, to; igraph_integer_t ffrom, fto; igraph_spmatrix_null(res); IGRAPH_CHECK(igraph_spmatrix_resize(res, no_of_nodes, no_of_nodes)); IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(0), &edgeit)); IGRAPH_FINALLY(igraph_eit_destroy, &edgeit); if (directed) { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from = ffrom; to = fto; igraph_spmatrix_add_e(res, from, to, 1); IGRAPH_EIT_NEXT(edgeit); } } else if (type == IGRAPH_GET_ADJACENCY_UPPER) { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from = ffrom; to = fto; if (to < from) { igraph_spmatrix_add_e(res, to, from, 1); } else { igraph_spmatrix_add_e(res, from, to, 1); } IGRAPH_EIT_NEXT(edgeit); } } else if (type == IGRAPH_GET_ADJACENCY_LOWER) { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from = ffrom; to = fto; if (to > from) { igraph_spmatrix_add_e(res, to, from, 1); } else { igraph_spmatrix_add_e(res, from, to, 1); } IGRAPH_EIT_NEXT(edgeit); } } else if (type == IGRAPH_GET_ADJACENCY_BOTH) { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from = ffrom; to = fto; igraph_spmatrix_add_e(res, from, to, 1); if (from != to) { igraph_spmatrix_add_e(res, to, from, 1); } IGRAPH_EIT_NEXT(edgeit); } } else { IGRAPH_ERROR("Invalid type argument.", IGRAPH_EINVAL); } igraph_eit_destroy(&edgeit); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \ingroup conversion * \function igraph_get_edgelist * \brief Returns the list of edges in a graph * * The order of the edges is given by the edge ids. * \param graph Pointer to the graph object * \param res Pointer to an initialized vector object, it will be * resized. * \param bycol Logical, if true, the edges will be returned * columnwise, e.g. the first edge is * res[0]->res[|E|], the second is * res[1]->res[|E|+1], etc. * \return Error code. * * \sa \ref igraph_edges() to return the result only for some edge ids. * * Time complexity: O(|E|), the * number of edges in the graph. */ int igraph_get_edgelist(const igraph_t *graph, igraph_vector_t *res, igraph_bool_t bycol) { igraph_eit_t edgeit; long int no_of_edges = igraph_ecount(graph); long int vptr = 0; igraph_integer_t from, to; IGRAPH_CHECK(igraph_vector_resize(res, no_of_edges * 2)); IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID), &edgeit)); IGRAPH_FINALLY(igraph_eit_destroy, &edgeit); if (bycol) { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &from, &to); VECTOR(*res)[vptr] = from; VECTOR(*res)[vptr + no_of_edges] = to; vptr++; IGRAPH_EIT_NEXT(edgeit); } } else { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &from, &to); VECTOR(*res)[vptr++] = from; VECTOR(*res)[vptr++] = to; IGRAPH_EIT_NEXT(edgeit); } } igraph_eit_destroy(&edgeit); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_to_directed * \brief Convert an undirected graph to a directed one * * * If the supplied graph is directed, this function does nothing. * \param graph The graph object to convert. * \param mode Constant, specifies the details of how exactly the * conversion is done. Possible values: * \clist * \cli IGRAPH_TO_DIRECTED_ARBITRARY * The number of edges in the * graph stays the same, an arbitrarily directed edge is * created for each undirected edge. * \cli IGRAPH_TO_DIRECTED_MUTUAL * Two directed edges are * created for each undirected edge, one in each direction. * \cli IGRAPH_TO_DIRECTED_RANDOM * Each undirected edge is converted to a randomly oriented * directed one. * \cli IGRAPH_TO_DIRECTED_ACYCLIC * Each undirected edge is converted to a directed edge oriented * from a lower index vertex to a higher index one. If no self-loops * were present, then the result is a directed acyclic graph. * \endclist * \return Error code. * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges. */ int igraph_to_directed(igraph_t *graph, igraph_to_directed_t mode) { long int no_of_edges = igraph_ecount(graph); long int no_of_nodes = igraph_vcount(graph); if (igraph_is_directed(graph)) { return IGRAPH_SUCCESS; } switch (mode) { case IGRAPH_TO_DIRECTED_ARBITRARY: case IGRAPH_TO_DIRECTED_RANDOM: case IGRAPH_TO_DIRECTED_ACYCLIC: { igraph_t newgraph; igraph_vector_t edges; long int size = no_of_edges * 2; long int i; IGRAPH_VECTOR_INIT_FINALLY(&edges, size); IGRAPH_CHECK(igraph_get_edgelist(graph, &edges, 0)); if (mode == IGRAPH_TO_DIRECTED_RANDOM) { RNG_BEGIN(); for (i=0; i < no_of_edges; ++i) { if (RNG_INTEGER(0,1)) { igraph_real_t temp = VECTOR(edges)[2*i]; VECTOR(edges)[2*i] = VECTOR(edges)[2*i+1]; VECTOR(edges)[2*i+1] = temp; } } RNG_END(); } else if (mode == IGRAPH_TO_DIRECTED_ACYCLIC) { /* Currently, the endpoints of undirected edges are ordered in the internal graph datastructure, i.e. it is always true that from < to. However, it is not guaranteed that this will not be changed in the future, and this ordering should not be relied on outside of the implementation of the minimal API in type_indexededgelist.c. Therefore, we order the edge endpoints anyway in the following loop: */ for (i=0; i < no_of_edges; ++i) { if (VECTOR(edges)[2*i] > VECTOR(edges)[2*i+1]) { igraph_real_t temp = VECTOR(edges)[2*i]; VECTOR(edges)[2*i] = VECTOR(edges)[2*i+1]; VECTOR(edges)[2*i+1] = temp; } } } IGRAPH_CHECK(igraph_create(&newgraph, &edges, (igraph_integer_t) no_of_nodes, IGRAPH_DIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1, 1, 1); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(2); igraph_destroy(graph); *graph = newgraph; break; } case IGRAPH_TO_DIRECTED_MUTUAL: { igraph_t newgraph; igraph_vector_t edges; igraph_vector_t index; long int size = no_of_edges * 4; long int i; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, size)); IGRAPH_CHECK(igraph_get_edgelist(graph, &edges, 0)); IGRAPH_CHECK(igraph_vector_resize(&edges, no_of_edges * 4)); IGRAPH_VECTOR_INIT_FINALLY(&index, no_of_edges * 2); for (i = 0; i < no_of_edges; i++) { VECTOR(edges)[no_of_edges * 2 + i * 2] = VECTOR(edges)[i * 2 + 1]; VECTOR(edges)[no_of_edges * 2 + i * 2 + 1] = VECTOR(edges)[i * 2]; VECTOR(index)[i] = VECTOR(index)[no_of_edges + i] = i; } IGRAPH_CHECK(igraph_create(&newgraph, &edges, (igraph_integer_t) no_of_nodes, IGRAPH_DIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1, 1,/*edges=*/0); IGRAPH_CHECK(igraph_i_attribute_permute_edges(graph, &newgraph, &index)); igraph_vector_destroy(&index); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(3); igraph_destroy(graph); *graph = newgraph; break; } default: IGRAPH_ERROR("Cannot direct graph, invalid mode", IGRAPH_EINVAL); } return IGRAPH_SUCCESS; } /** * \function igraph_to_undirected * \brief Convert a directed graph to an undirected one. * * * If the supplied graph is undirected, this function does nothing. * * \param graph The graph object to convert. * \param mode Constant, specifies the details of how exactly the * conversion is done. Possible values: \c * IGRAPH_TO_UNDIRECTED_EACH: the number of edges remains * constant, an undirected edge is created for each directed * one, this version might create graphs with multiple edges; * \c IGRAPH_TO_UNDIRECTED_COLLAPSE: one undirected edge will * be created for each pair of vertices that are connected * with at least one directed edge, no multiple edges will be * created. \c IGRAPH_TO_UNDIRECTED_MUTUAL creates an undirected * edge for each pair of mutual edges in the directed graph. * Non-mutual edges are lost; loop edges are kept unconditionally. * This mode might create multiple edges. * \param edge_comb What to do with the edge attributes. See the igraph * manual section about attributes for details. \c NULL means that * the edge attributes are lost during the conversion, \em except * when \c mode is \c IGRAPH_TO_UNDIRECTED_EACH, in which case the * edge attributes are kept intact. * \return Error code. * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges. * * \example examples/simple/igraph_to_undirected.c */ int igraph_to_undirected(igraph_t *graph, igraph_to_undirected_t mode, const igraph_attribute_combination_t *edge_comb) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vector_t edges; igraph_t newgraph; igraph_bool_t attr = edge_comb && igraph_has_attribute_table(); if (mode != IGRAPH_TO_UNDIRECTED_EACH && mode != IGRAPH_TO_UNDIRECTED_COLLAPSE && mode != IGRAPH_TO_UNDIRECTED_MUTUAL) { IGRAPH_ERROR("Cannot undirect graph, invalid mode", IGRAPH_EINVAL); } if (!igraph_is_directed(graph)) { return 0; } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); if (mode == IGRAPH_TO_UNDIRECTED_EACH) { igraph_es_t es; igraph_eit_t eit; IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); IGRAPH_CHECK(igraph_es_all(&es, IGRAPH_EDGEORDER_ID)); IGRAPH_FINALLY(igraph_es_destroy, &es); IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); while (!IGRAPH_EIT_END(eit)) { long int edge = IGRAPH_EIT_GET(eit); igraph_integer_t from, to; igraph_edge(graph, (igraph_integer_t) edge, &from, &to); IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_EIT_NEXT(eit); } igraph_eit_destroy(&eit); igraph_es_destroy(&es); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(&newgraph, &edges, (igraph_integer_t) no_of_nodes, IGRAPH_UNDIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); igraph_vector_destroy(&edges); IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1, 1, 1); IGRAPH_FINALLY_CLEAN(2); igraph_destroy(graph); *graph = newgraph; } else if (mode == IGRAPH_TO_UNDIRECTED_COLLAPSE) { igraph_vector_t inadj, outadj; long int i; igraph_vector_t mergeinto; long int actedge = 0; if (attr) { IGRAPH_VECTOR_INIT_FINALLY(&mergeinto, no_of_edges); } IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); IGRAPH_VECTOR_INIT_FINALLY(&inadj, 0); IGRAPH_VECTOR_INIT_FINALLY(&outadj, 0); for (i = 0; i < no_of_nodes; i++) { long int n_out, n_in; long int p1 = -1, p2 = -1; long int e1 = 0, e2 = 0, n1 = 0, n2 = 0, last; IGRAPH_CHECK(igraph_incident(graph, &outadj, (igraph_integer_t) i, IGRAPH_OUT)); IGRAPH_CHECK(igraph_incident(graph, &inadj, (igraph_integer_t) i, IGRAPH_IN)); n_out = igraph_vector_size(&outadj); n_in = igraph_vector_size(&inadj); #define STEPOUT() if ( (++p1) < n_out) { \ e1 = (long int) VECTOR(outadj)[p1]; \ n1 = IGRAPH_TO(graph, e1); \ } #define STEPIN() if ( (++p2) < n_in) { \ e2 = (long int) VECTOR(inadj )[p2]; \ n2 = IGRAPH_FROM(graph, e2); \ } #define ADD_NEW_EDGE() { \ IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); \ IGRAPH_CHECK(igraph_vector_push_back(&edges, last)); \ } #define MERGE_INTO_CURRENT_EDGE(which) { \ if (attr) { \ VECTOR(mergeinto)[which] = actedge; \ } \ } STEPOUT(); STEPIN(); while (p1 < n_out && n1 <= i && p2 < n_in && n2 <= i) { last = (n1 <= n2) ? n1 : n2; ADD_NEW_EDGE(); while (p1 < n_out && last == n1) { MERGE_INTO_CURRENT_EDGE(e1); STEPOUT(); } while (p2 < n_in && last == n2) { MERGE_INTO_CURRENT_EDGE(e2); STEPIN(); } actedge++; } while (p1 < n_out && n1 <= i) { last = n1; ADD_NEW_EDGE(); while (p1 < n_out && last == n1) { MERGE_INTO_CURRENT_EDGE(e1); STEPOUT(); } actedge++; } while (p2 < n_in && n2 <= i) { last = n2; ADD_NEW_EDGE(); while (p2 < n_in && last == n2) { MERGE_INTO_CURRENT_EDGE(e2); STEPIN(); } actedge++; } } #undef MERGE_INTO_CURRENT_EDGE #undef ADD_NEW_EDGE #undef STEPOUT #undef STEPIN igraph_vector_destroy(&outadj); igraph_vector_destroy(&inadj); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(&newgraph, &edges, (igraph_integer_t) no_of_nodes, IGRAPH_UNDIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); igraph_vector_destroy(&edges); IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1, 1, 0); /* no edge attributes */ if (attr) { igraph_fixed_vectorlist_t vl; IGRAPH_CHECK(igraph_fixed_vectorlist_convert(&vl, &mergeinto, actedge)); IGRAPH_FINALLY(igraph_fixed_vectorlist_destroy, &vl); IGRAPH_CHECK(igraph_i_attribute_combine_edges(graph, &newgraph, &vl.v, edge_comb)); igraph_fixed_vectorlist_destroy(&vl); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_FINALLY_CLEAN(2); igraph_destroy(graph); *graph = newgraph; if (attr) { igraph_vector_destroy(&mergeinto); IGRAPH_FINALLY_CLEAN(1); } } else if (mode == IGRAPH_TO_UNDIRECTED_MUTUAL) { igraph_vector_t inadj, outadj; long int i; igraph_vector_t mergeinto; long int actedge = 0; if (attr) { IGRAPH_VECTOR_INIT_FINALLY(&mergeinto, no_of_edges); igraph_vector_fill(&mergeinto, -1); } IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); IGRAPH_VECTOR_INIT_FINALLY(&inadj, 0); IGRAPH_VECTOR_INIT_FINALLY(&outadj, 0); for (i = 0; i < no_of_nodes; i++) { long int n_out, n_in; long int p1 = -1, p2 = -1; long int e1 = 0, e2 = 0, n1 = 0, n2 = 0; IGRAPH_CHECK(igraph_incident(graph, &outadj, (igraph_integer_t) i, IGRAPH_OUT)); IGRAPH_CHECK(igraph_incident(graph, &inadj, (igraph_integer_t) i, IGRAPH_IN)); n_out = igraph_vector_size(&outadj); n_in = igraph_vector_size(&inadj); #define STEPOUT() if ( (++p1) < n_out) { \ e1 = (long int) VECTOR(outadj)[p1]; \ n1 = IGRAPH_TO(graph, e1); \ } #define STEPIN() if ( (++p2) < n_in) { \ e2 = (long int) VECTOR(inadj )[p2]; \ n2 = IGRAPH_FROM(graph, e2); \ } STEPOUT(); STEPIN(); while (p1 < n_out && n1 <= i && p2 < n_in && n2 <= i) { if (n1 == n2) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, n1)); if (attr) { VECTOR(mergeinto)[e1] = actedge; VECTOR(mergeinto)[e2] = actedge; actedge++; } STEPOUT(); STEPIN(); } else if (n1 < n2) { STEPOUT(); } else { /* n2= 2 vertices can be represented by a * sequence of n-2 integers, each between 0 and n-1 (inclusive). * * \param graph Pointer to an initialized graph object which must be a tree on n >= 2 vertices. * \param prufer A pointer to the integer vector that should hold the Prüfer sequence; the vector must be initialized and will be resized to n - 2. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * there is not enough memory to perform the operation. * \cli IGRAPH_EINVAL * the graph is not a tree or it is has less than vertices * \endclist * * \sa \ref igraph_from_prufer() * */ int igraph_to_prufer(const igraph_t *graph, igraph_vector_int_t* prufer) { /* For generating the Prüfer sequence, we enumerate the vertices u of the tree. We keep track of the degrees of all vertices, treating vertices of degree 0 as removed. We maintain the invariant that all leafs that are still contained in the tree are >= u. If u is a leaf, we remove it and add its unique neighbor to the prüfer sequence. If the removal of u turns the neighbor into a leaf which is < u, we repeat the procedure for the new leaf and so on. */ igraph_integer_t u; igraph_vector_t degrees, neighbors; igraph_integer_t prufer_index = 0; igraph_integer_t n = igraph_vcount(graph); igraph_bool_t is_tree = 0; IGRAPH_CHECK(igraph_is_tree(graph, &is_tree, NULL, IGRAPH_ALL)); if (!is_tree) { IGRAPH_ERROR("The graph must be a tree", IGRAPH_EINVAL); } if (n < 2) { IGRAPH_ERROR("The tree must have at least 2 vertices", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_int_resize(prufer, n - 2)); IGRAPH_VECTOR_INIT_FINALLY(°rees, n); IGRAPH_VECTOR_INIT_FINALLY(&neighbors, 1); IGRAPH_CHECK(igraph_degree(graph, °rees, igraph_vss_all(), IGRAPH_ALL, IGRAPH_NO_LOOPS)); for (u = 0; u < n; ++u) { igraph_integer_t degree = VECTOR(degrees)[u]; igraph_integer_t leaf = u; while (degree == 1 && leaf <= u) { igraph_integer_t i; igraph_integer_t neighbor = 0; igraph_integer_t neighbor_count = 0; VECTOR(degrees)[leaf] = 0; /* mark leaf v as deleted */ IGRAPH_CHECK(igraph_neighbors(graph, &neighbors, leaf, IGRAPH_ALL)); /* Find the unique remaining neighbor of the leaf */ neighbor_count = igraph_vector_size(&neighbors); for (i = 0; i < neighbor_count; i++) { neighbor = VECTOR(neighbors)[i]; if (VECTOR(degrees)[neighbor] > 0) { break; } } /* remember that we have removed the leaf */ VECTOR(degrees)[neighbor]--; degree = VECTOR(degrees)[neighbor]; /* Add the neighbor to the prufer sequence unless it is the last vertex (i.e. degree == 0) */ if (degree > 0) { VECTOR(*prufer)[prufer_index] = neighbor; prufer_index++; } leaf = neighbor; } } igraph_vector_destroy(°rees); igraph_vector_destroy(&neighbors); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } leidenbase/src/core/misc/bipartite.c0000644000176200001440000012152114447675375017176 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2008-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_bipartite.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_constructors.h" #include "igraph_dqueue.h" #include "igraph_random.h" #include "igraph_nongraph.h" #include "graph/attributes.h" /** * \section about_bipartite Bipartite networks in igraph * * * A bipartite network contains two kinds of vertices and connections * are only possible between two vertices of different kinds. There are * many natural examples, e.g. movies and actors as vertices and a * movie is connected to all participating actors, etc. * * * igraph does not have direct support for bipartite networks, at * least not at the C language level. In other words the igraph_t * structure does not contain information about the vertex types. * The C functions for bipartite networks usually have an additional * input argument to graph, called \c types, a boolean vector giving * the vertex types. * * * Most functions creating bipartite networks are able to create this * extra vector, you just need to supply an initialized boolean vector * to them. */ /** * \function igraph_bipartite_projection_size * \brief Calculate the number of vertices and edges in the bipartite projections. * * This function calculates the number of vertices and edges in the * two projections of a bipartite network. This is useful if you have * a big bipartite network and you want to estimate the amount of * memory you would need to calculate the projections themselves. * * \param graph The input graph. * \param types Boolean vector giving the vertex types of the graph. * \param vcount1 Pointer to an \c igraph_integer_t, the number of * vertices in the first projection is stored here. * \param ecount1 Pointer to an \c igraph_integer_t, the number of * edges in the first projection is stored here. * \param vcount2 Pointer to an \c igraph_integer_t, the number of * vertices in the second projection is stored here. * \param ecount2 Pointer to an \c igraph_integer_t, the number of * edges in the second projection is stored here. * \return Error code. * * \sa \ref igraph_bipartite_projection() to calculate the actual * projection. * * Time complexity: O(|V|*d^2+|E|), |V| is the number of vertices, |E| * is the number of edges, d is the average (total) degree of the * graphs. * * \example examples/simple/igraph_bipartite_projection.c */ int igraph_bipartite_projection_size(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_integer_t *vcount1, igraph_integer_t *ecount1, igraph_integer_t *vcount2, igraph_integer_t *ecount2) { long int no_of_nodes = igraph_vcount(graph); long int vc1 = 0, ec1 = 0, vc2 = 0, ec2 = 0; igraph_adjlist_t adjlist; igraph_vector_long_t added; long int i; IGRAPH_CHECK(igraph_vector_long_init(&added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &added); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); for (i = 0; i < no_of_nodes; i++) { igraph_vector_int_t *neis1; long int neilen1, j; long int *ecptr; if (VECTOR(*types)[i]) { vc2++; ecptr = &ec2; } else { vc1++; ecptr = &ec1; } neis1 = igraph_adjlist_get(&adjlist, i); neilen1 = igraph_vector_int_size(neis1); for (j = 0; j < neilen1; j++) { long int k, neilen2, nei = (long int) VECTOR(*neis1)[j]; igraph_vector_int_t *neis2 = igraph_adjlist_get(&adjlist, nei); if (IGRAPH_UNLIKELY(VECTOR(*types)[i] == VECTOR(*types)[nei])) { IGRAPH_ERROR("Non-bipartite edge found in bipartite projection", IGRAPH_EINVAL); } neilen2 = igraph_vector_int_size(neis2); for (k = 0; k < neilen2; k++) { long int nei2 = (long int) VECTOR(*neis2)[k]; if (nei2 <= i) { continue; } if (VECTOR(added)[nei2] == i + 1) { continue; } VECTOR(added)[nei2] = i + 1; (*ecptr)++; } } } *vcount1 = (igraph_integer_t) vc1; *ecount1 = (igraph_integer_t) ec1; *vcount2 = (igraph_integer_t) vc2; *ecount2 = (igraph_integer_t) ec2; igraph_adjlist_destroy(&adjlist); igraph_vector_long_destroy(&added); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_bipartite_projection(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_t *proj, int which, igraph_vector_t *multiplicity) { long int no_of_nodes = igraph_vcount(graph); long int i, j, k; igraph_integer_t remaining_nodes = 0; igraph_vector_t vertex_perm, vertex_index; igraph_vector_t edges; igraph_adjlist_t adjlist; igraph_vector_int_t *neis1, *neis2; long int neilen1, neilen2; igraph_vector_long_t added; igraph_vector_t mult; if (which < 0) { return 0; } IGRAPH_VECTOR_INIT_FINALLY(&vertex_perm, 0); IGRAPH_CHECK(igraph_vector_reserve(&vertex_perm, no_of_nodes)); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&vertex_index, no_of_nodes); IGRAPH_CHECK(igraph_vector_long_init(&added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &added); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); /* we won't need the 'mult' vector if 'multiplicity' is NULL, but MSVC will * throw warnings in the compiler output if we initialize it conditionally */ IGRAPH_VECTOR_INIT_FINALLY(&mult, multiplicity ? no_of_nodes : 1); if (multiplicity) { igraph_vector_clear(multiplicity); } for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*types)[i] == which) { VECTOR(vertex_index)[i] = ++remaining_nodes; igraph_vector_push_back(&vertex_perm, i); } } for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*types)[i] == which) { long int new_i = (long int) VECTOR(vertex_index)[i] - 1; long int iedges = 0; neis1 = igraph_adjlist_get(&adjlist, i); neilen1 = igraph_vector_int_size(neis1); for (j = 0; j < neilen1; j++) { long int nei = (long int) VECTOR(*neis1)[j]; if (IGRAPH_UNLIKELY(VECTOR(*types)[i] == VECTOR(*types)[nei])) { IGRAPH_ERROR("Non-bipartite edge found in bipartite projection", IGRAPH_EINVAL); } neis2 = igraph_adjlist_get(&adjlist, nei); neilen2 = igraph_vector_int_size(neis2); for (k = 0; k < neilen2; k++) { long int nei2 = (long int) VECTOR(*neis2)[k], new_nei2; if (nei2 <= i) { continue; } if (VECTOR(added)[nei2] == i + 1) { if (multiplicity) { VECTOR(mult)[nei2] += 1; } continue; } VECTOR(added)[nei2] = i + 1; if (multiplicity) { VECTOR(mult)[nei2] = 1; } iedges++; IGRAPH_CHECK(igraph_vector_push_back(&edges, new_i)); if (multiplicity) { /* If we need the multiplicity as well, then we put in the old vertex ids here and rewrite it later */ IGRAPH_CHECK(igraph_vector_push_back(&edges, nei2)); } else { new_nei2 = (long int) VECTOR(vertex_index)[nei2] - 1; IGRAPH_CHECK(igraph_vector_push_back(&edges, new_nei2)); } } } if (multiplicity) { /* OK, we need to go through all the edges added for vertex new_i and check their multiplicity */ long int now = igraph_vector_size(&edges); long int from = now - iedges * 2; for (j = from; j < now; j += 2) { long int nei2 = (long int) VECTOR(edges)[j + 1]; long int new_nei2 = (long int) VECTOR(vertex_index)[nei2] - 1; long int m = (long int) VECTOR(mult)[nei2]; VECTOR(edges)[j + 1] = new_nei2; IGRAPH_CHECK(igraph_vector_push_back(multiplicity, m)); } } } /* if VECTOR(*type)[i] == which */ } igraph_vector_destroy(&mult); igraph_adjlist_destroy(&adjlist); igraph_vector_long_destroy(&added); igraph_vector_destroy(&vertex_index); IGRAPH_FINALLY_CLEAN(4); IGRAPH_CHECK(igraph_create(proj, &edges, remaining_nodes, /*directed=*/ 0)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, proj); IGRAPH_I_ATTRIBUTE_DESTROY(proj); IGRAPH_I_ATTRIBUTE_COPY(proj, graph, 1, 0, 0); IGRAPH_CHECK(igraph_i_attribute_permute_vertices(graph, proj, &vertex_perm)); igraph_vector_destroy(&vertex_perm); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_bipartite_projection * \brief Create one or both projections of a bipartite (two-mode) network. * * Creates one or both projections of a bipartite graph. * * \param graph The bipartite input graph. Directedness of the edges * is ignored. * \param types Boolean vector giving the vertex types of the graph. * \param proj1 Pointer to an uninitialized graph object, the first * projection will be created here. It a null pointer, then it is * ignored, see also the \p probe1 argument. * \param proj2 Pointer to an uninitialized graph object, the second * projection is created here, if it is not a null pointer. See also * the \p probe1 argument. * \param multiplicity1 Pointer to a vector, or a null pointer. If not * the latter, then the multiplicity of the edges is stored * here. E.g. if there is an A-C-B and also an A-D-B triple in the * bipartite graph (but no more X, such that A-X-B is also in the * graph), then the multiplicity of the A-B edge in the projection * will be 2. * \param multiplicity2 The same as \c multiplicity1, but for the * other projection. * \param probe1 This argument can be used to specify the order of the * projections in the resulting list. When it is non-negative, then * it is considered as a vertex ID and the projection containing * this vertex will be the first one in the result. Setting this * argument to a non-negative value implies that \c proj1 must be * a non-null pointer. If you don't care about the ordering of the * projections, pass -1 here. * \return Error code. * * \sa \ref igraph_bipartite_projection_size() to calculate the number * of vertices and edges in the projections, without creating the * projection graphs themselves. * * Time complexity: O(|V|*d^2+|E|), |V| is the number of vertices, |E| * is the number of edges, d is the average (total) degree of the * graphs. * * \example examples/simple/igraph_bipartite_projection.c */ int igraph_bipartite_projection(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_t *proj1, igraph_t *proj2, igraph_vector_t *multiplicity1, igraph_vector_t *multiplicity2, igraph_integer_t probe1) { long int no_of_nodes = igraph_vcount(graph); /* t1 is -1 if proj1 is omitted, it is 0 if it belongs to type zero, it is 1 if it belongs to type one. The same for t2 */ int t1, t2; if (igraph_vector_bool_size(types) != no_of_nodes) { IGRAPH_ERROR("Invalid bipartite type vector size", IGRAPH_EINVAL); } if (probe1 >= no_of_nodes) { IGRAPH_ERROR("No such vertex to probe", IGRAPH_EINVAL); } if (probe1 >= 0 && !proj1) { IGRAPH_ERROR("`probe1' given, but `proj1' is a null pointer", IGRAPH_EINVAL); } if (probe1 >= 0) { t1 = VECTOR(*types)[(long int)probe1]; if (proj2) { t2 = 1 - t1; } else { t2 = -1; } } else { t1 = proj1 ? 0 : -1; t2 = proj2 ? 1 : -1; } IGRAPH_CHECK(igraph_i_bipartite_projection(graph, types, proj1, t1, multiplicity1)); IGRAPH_FINALLY(igraph_destroy, proj1); IGRAPH_CHECK(igraph_i_bipartite_projection(graph, types, proj2, t2, multiplicity2)); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_full_bipartite * \brief Create a full bipartite network. * * A bipartite network contains two kinds of vertices and connections * are only possible between two vertices of different kind. There are * many natural examples, e.g. movies and actors as vertices and a * movie is connected to all participating actors, etc. * * * igraph does not have direct support for bipartite networks, at * least not at the C language level. In other words the igraph_t * structure does not contain information about the vertex types. * The C functions for bipartite networks usually have an additional * input argument to graph, called \c types, a boolean vector giving * the vertex types. * * * Most functions creating bipartite networks are able to create this * extra vector, you just need to supply an initialized boolean vector * to them. * * \param graph Pointer to an igraph_t object, the graph will be * created here. * \param types Pointer to a boolean vector. If not a null pointer, * then the vertex types will be stored here. * \param n1 Integer, the number of vertices of the first kind. * \param n2 Integer, the number of vertices of the second kind. * \param directed Boolean, whether to create a directed graph. * \param mode A constant that gives the type of connections for * directed graphs. If \c IGRAPH_OUT, then edges point from vertices * of the first kind to vertices of the second kind; if \c * IGRAPH_IN, then the opposite direction is realized; if \c * IGRAPH_ALL, then mutual edges will be created. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. * * \sa \ref igraph_full() for non-bipartite full graphs. */ int igraph_full_bipartite(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_bool_t directed, igraph_neimode_t mode) { igraph_integer_t nn1 = n1, nn2 = n2; igraph_integer_t no_of_nodes = nn1 + nn2; igraph_vector_t edges; long int no_of_edges; long int ptr = 0; long int i, j; if (!directed) { no_of_edges = nn1 * nn2; } else if (mode == IGRAPH_OUT || mode == IGRAPH_IN) { no_of_edges = nn1 * nn2; } else { /* mode==IGRAPH_ALL */ no_of_edges = nn1 * nn2 * 2; } IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); if (!directed || mode == IGRAPH_OUT) { for (i = 0; i < nn1; i++) { for (j = 0; j < nn2; j++) { VECTOR(edges)[ptr++] = i; VECTOR(edges)[ptr++] = nn1 + j; } } } else if (mode == IGRAPH_IN) { for (i = 0; i < nn1; i++) { for (j = 0; j < nn2; j++) { VECTOR(edges)[ptr++] = nn1 + j; VECTOR(edges)[ptr++] = i; } } } else { for (i = 0; i < nn1; i++) { for (j = 0; j < nn2; j++) { VECTOR(edges)[ptr++] = i; VECTOR(edges)[ptr++] = nn1 + j; VECTOR(edges)[ptr++] = nn1 + j; VECTOR(edges)[ptr++] = i; } } } IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, graph); if (types) { IGRAPH_CHECK(igraph_vector_bool_resize(types, no_of_nodes)); igraph_vector_bool_null(types); for (i = nn1; i < no_of_nodes; i++) { VECTOR(*types)[i] = 1; } } IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_create_bipartite * \brief Create a bipartite graph. * * This is a simple wrapper function to create a bipartite graph. It * does a little more than \ref igraph_create(), e.g. it checks that * the graph is indeed bipartite with respect to the given \p types * vector. If there is an edge connecting two vertices of the same * kind, then an error is reported. * * \param graph Pointer to an uninitialized graph object, the result is * created here. * \param types Boolean vector giving the vertex types. The length of * the vector defines the number of vertices in the graph. * \param edges Vector giving the edges of the graph. The highest * vertex id in this vector must be smaller than the length of the * \p types vector. * \param directed Boolean scalar, whether to create a directed * graph. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. * * \example examples/simple/igraph_bipartite_create.c */ int igraph_create_bipartite(igraph_t *graph, const igraph_vector_bool_t *types, const igraph_vector_t *edges, igraph_bool_t directed) { igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vector_bool_size(types); long int no_of_edges = igraph_vector_size(edges); igraph_real_t min_edge = 0, max_edge = 0; long int i; if (no_of_edges % 2 != 0) { IGRAPH_ERROR("Invalid (odd) edges vector", IGRAPH_EINVEVECTOR); } no_of_edges /= 2; if (no_of_edges != 0) { igraph_vector_minmax(edges, &min_edge, &max_edge); } if (min_edge < 0 || max_edge >= no_of_nodes) { IGRAPH_ERROR("Invalid (negative or too large) vertex id", IGRAPH_EINVVID); } /* Check bipartiteness */ for (i = 0; i < no_of_edges * 2; i += 2) { long int from = (long int) VECTOR(*edges)[i]; long int to = (long int) VECTOR(*edges)[i + 1]; long int t1 = VECTOR(*types)[from]; long int t2 = VECTOR(*types)[to]; if ( (t1 && t2) || (!t1 && !t2) ) { IGRAPH_ERROR("Invalid edges, not a bipartite graph", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_empty(graph, no_of_nodes, directed)); IGRAPH_FINALLY(igraph_destroy, graph); IGRAPH_CHECK(igraph_add_edges(graph, edges, 0)); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_incidence * \brief Creates a bipartite graph from an incidence matrix. * * A bipartite (or two-mode) graph contains two types of vertices and * edges always connect vertices of different types. An incidence * matrix is an nxm matrix, n and m are the number of vertices of the * two types, respectively. Nonzero elements in the matrix denote * edges between the two corresponding vertices. * * * Note that this function can operate in two modes, depending on the * \p multiple argument. If it is FALSE (i.e. 0), then a single edge is * created for every non-zero element in the incidence matrix. If \p * multiple is TRUE (i.e. 1), then the matrix elements are rounded up * to the closest non-negative integer to get the number of edges to * create between a pair of vertices. * * * This function does not create multiple edges if \p multiple is * \c FALSE, but might create some if it is \c TRUE. * * \param graph Pointer to an uninitialized graph object. * \param types Pointer to an initialized boolean vector, or a null * pointer. If not a null pointer, then the vertex types are stored * here. It is resized as needed. * \param incidence The incidence matrix. * \param directed Gives whether to create an undirected or a directed * graph. * \param mode Specifies the direction of the edges in a directed * graph. If \c IGRAPH_OUT, then edges point from vertices * of the first kind (corresponding to rows) to vertices of the * second kind (corresponding to columns); if \c * IGRAPH_IN, then the opposite direction is realized; if \c * IGRAPH_ALL, then mutual edges will be created. * \param multiple How to interpret the incidence matrix elements. See * details below. * \return Error code. * * Time complexity: O(n*m), the size of the incidence matrix. */ int igraph_incidence(igraph_t *graph, igraph_vector_bool_t *types, const igraph_matrix_t *incidence, igraph_bool_t directed, igraph_neimode_t mode, igraph_bool_t multiple) { igraph_integer_t n1 = (igraph_integer_t) igraph_matrix_nrow(incidence); igraph_integer_t n2 = (igraph_integer_t) igraph_matrix_ncol(incidence); igraph_integer_t no_of_nodes = n1 + n2; igraph_vector_t edges; long int i, j, k; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); if (multiple) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { long int elem = (long int) MATRIX(*incidence, i, j); long int from, to; if (!elem) { continue; } if (mode == IGRAPH_IN) { from = n1 + j; to = i; } else { from = i; to = n1 + j; } if (mode != IGRAPH_ALL || !directed) { for (k = 0; k < elem; k++) { IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); } } else { for (k = 0; k < elem; k++) { IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); } } } } } else { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { long int from, to; if (MATRIX(*incidence, i, j) != 0) { if (mode == IGRAPH_IN) { from = n1 + j; to = i; } else { from = i; to = n1 + j; } if (mode != IGRAPH_ALL || !directed) { IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); } else { IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); } } } } } IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, graph); if (types) { IGRAPH_CHECK(igraph_vector_bool_resize(types, no_of_nodes)); igraph_vector_bool_null(types); for (i = n1; i < no_of_nodes; i++) { VECTOR(*types)[i] = 1; } } IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_get_incidence * \brief Convert a bipartite graph into an incidence matrix. * * \param graph The input graph, edge directions are ignored. * \param types Boolean vector containing the vertex types. All vertices * in one part of the graph should have type 0, the others type 1. * \param res Pointer to an initialized matrix, the result is stored * here. An element of the matrix gives the number of edges * (irrespectively of their direction) between the two corresponding * vertices. The rows will correspond to vertices with type 0, * the columns correspond to vertices with type 1. * \param row_ids Pointer to an initialized vector or a null * pointer. If not a null pointer, then the vertex ids (in the * graph) corresponding to the rows of the result matrix are stored * here. * \param col_ids Pointer to an initialized vector or a null * pointer. If not a null pointer, then the vertex ids corresponding * to the columns of the result matrix are stored here. * \return Error code. * * Time complexity: O(n*m), n and m are number of vertices of the two * different kind. * * \sa \ref igraph_incidence() for the opposite operation. */ int igraph_get_incidence(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_matrix_t *res, igraph_vector_t *row_ids, igraph_vector_t *col_ids) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int n1 = 0, n2 = 0, i; igraph_vector_t perm; long int p1, p2; long int ignored_edges = 0; if (igraph_vector_bool_size(types) != no_of_nodes) { IGRAPH_ERRORF("Vertex type vector size (%ld) not equal to number of vertices (%ld).", IGRAPH_EINVAL, igraph_vector_bool_size(types), no_of_nodes); } for (i = 0; i < no_of_nodes; i++) { n1 += VECTOR(*types)[i] == 0 ? 1 : 0; } n2 = no_of_nodes - n1; IGRAPH_VECTOR_INIT_FINALLY(&perm, no_of_nodes); for (i = 0, p1 = 0, p2 = n1; i < no_of_nodes; i++) { VECTOR(perm)[i] = VECTOR(*types)[i] ? p2++ : p1++; } IGRAPH_CHECK(igraph_matrix_resize(res, n1, n2)); igraph_matrix_null(res); for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); long int from2 = (long int) VECTOR(perm)[from]; long int to2 = (long int) VECTOR(perm)[to]; if (VECTOR(*types)[from] == VECTOR(*types)[to]) { ignored_edges++; } else if (! VECTOR(*types)[from]) { MATRIX(*res, from2, to2 - n1) += 1; } else { MATRIX(*res, to2, from2 - n1) += 1; } } if (ignored_edges) { IGRAPH_WARNINGF("%ld edges running within partitions were ignored.", ignored_edges); } if (row_ids) { IGRAPH_CHECK(igraph_vector_resize(row_ids, n1)); } if (col_ids) { IGRAPH_CHECK(igraph_vector_resize(col_ids, n2)); } if (row_ids || col_ids) { for (i = 0; i < no_of_nodes; i++) { if (! VECTOR(*types)[i]) { if (row_ids) { long int i2 = (long int) VECTOR(perm)[i]; VECTOR(*row_ids)[i2] = i; } } else { if (col_ids) { long int i2 = (long int) VECTOR(perm)[i]; VECTOR(*col_ids)[i2 - n1] = i; } } } } igraph_vector_destroy(&perm); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \function igraph_is_bipartite * \brief Check whether a graph is bipartite. * * This function checks whether a graph is bipartite. It tries * to find a mapping that gives a possible division of the vertices into two * classes, such that no two vertices of the same class are connected by an * edge. * * * The existence of such a mapping is equivalent of having no circuits of * odd length in the graph. A graph with loop edges cannot be bipartite. * * * Note that the mapping is not necessarily unique, e.g. if the graph has * at least two components, then the vertices in the separate components * can be mapped independently. * * \param graph The input graph. * \param res Pointer to a boolean, the result is stored here. * \param types Pointer to an initialized boolean vector, or a null * pointer. If not a null pointer and a mapping was found, then it * is stored here. If not a null pointer, but no mapping was found, * the contents of this vector is invalid. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. */ int igraph_is_bipartite(const igraph_t *graph, igraph_bool_t *res, igraph_vector_bool_t *types) { /* We basically do a breadth first search and label the vertices along the way. We stop as soon as we can find a contradiction. In the 'seen' vector 0 means 'not seen yet', 1 means type 1, 2 means type 2. */ long int no_of_nodes = igraph_vcount(graph); igraph_vector_char_t seen; igraph_dqueue_t Q; igraph_vector_t neis; igraph_bool_t bi = 1; long int i; IGRAPH_CHECK(igraph_vector_char_init(&seen, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_char_destroy, &seen); IGRAPH_DQUEUE_INIT_FINALLY(&Q, 100); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); for (i = 0; bi && i < no_of_nodes; i++) { if (VECTOR(seen)[i]) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&Q, i)); VECTOR(seen)[i] = 1; while (bi && !igraph_dqueue_empty(&Q)) { long int n, j; igraph_integer_t actnode = (igraph_integer_t) igraph_dqueue_pop(&Q); char acttype = VECTOR(seen)[actnode]; IGRAPH_CHECK(igraph_neighbors(graph, &neis, actnode, IGRAPH_ALL)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (VECTOR(seen)[nei]) { long int neitype = VECTOR(seen)[nei]; if (neitype == acttype) { bi = 0; break; } } else { VECTOR(seen)[nei] = 3 - acttype; IGRAPH_CHECK(igraph_dqueue_push(&Q, nei)); } } } } igraph_vector_destroy(&neis); igraph_dqueue_destroy(&Q); IGRAPH_FINALLY_CLEAN(2); if (res) { *res = bi; } if (types && bi) { IGRAPH_CHECK(igraph_vector_bool_resize(types, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { VECTOR(*types)[i] = VECTOR(seen)[i] - 1; } } igraph_vector_char_destroy(&seen); IGRAPH_FINALLY_CLEAN(1); return 0; } int igraph_bipartite_game_gnp(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_real_t p, igraph_bool_t directed, igraph_neimode_t mode) { int retval = 0; igraph_vector_t edges, s; int i; if (p < 0.0 || p > 1.0) { IGRAPH_ERROR("Invalid connection probability", IGRAPH_EINVAL); } if (types) { IGRAPH_CHECK(igraph_vector_bool_resize(types, n1 + n2)); igraph_vector_bool_null(types); for (i = n1; i < n1 + n2; i++) { VECTOR(*types)[i] = 1; } } if (p == 0 || n1 * n2 < 1) { IGRAPH_CHECK(retval = igraph_empty(graph, n1 + n2, directed)); } else if (p == 1.0) { IGRAPH_CHECK(retval = igraph_full_bipartite(graph, types, n1, n2, directed, mode)); } else { long int to, from, slen; double maxedges, last; if (!directed || mode != IGRAPH_ALL) { maxedges = (double) n1 * (double) n2; } else { maxedges = 2.0 * (double) n1 * (double) n2; } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&s, 0); IGRAPH_CHECK(igraph_vector_reserve(&s, (long) (maxedges * p * 1.1))); RNG_BEGIN(); last = RNG_GEOM(p); while (last < maxedges) { IGRAPH_CHECK(igraph_vector_push_back(&s, last)); last += RNG_GEOM(p); last += 1; } RNG_END(); slen = igraph_vector_size(&s); IGRAPH_CHECK(igraph_vector_reserve(&edges, slen * 2)); for (i = 0; i < slen; i++) { if (!directed || mode != IGRAPH_ALL) { to = (long) floor(VECTOR(s)[i] / n1); from = (long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1); to += n1; } else { long int n1n2 = n1 * n2; if (VECTOR(s)[i] < n1n2) { to = (long) floor(VECTOR(s)[i] / n1); from = (long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1); to += n1; } else { to = (long) floor( (VECTOR(s)[i] - n1n2) / n2); from = (long) (VECTOR(s)[i] - n1n2 - ((igraph_real_t) to) * n2); from += n1; } } if (mode != IGRAPH_IN) { igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } else { igraph_vector_push_back(&edges, to); igraph_vector_push_back(&edges, from); } } igraph_vector_destroy(&s); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(retval = igraph_create(graph, &edges, n1 + n2, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); } return retval; } int igraph_bipartite_game_gnm(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_integer_t m, igraph_bool_t directed, igraph_neimode_t mode) { igraph_vector_t edges; igraph_vector_t s; int retval = 0; if (n1 < 0 || n2 < 0) { IGRAPH_ERROR("Invalid number of vertices", IGRAPH_EINVAL); } if (m < 0) { IGRAPH_ERROR("Invalid number of edges", IGRAPH_EINVAL); } if (types) { long int i; IGRAPH_CHECK(igraph_vector_bool_resize(types, n1 + n2)); igraph_vector_bool_null(types); for (i = n1; i < n1 + n2; i++) { VECTOR(*types)[i] = 1; } } if (m == 0 || n1 * n2 == 0) { if (m > 0) { IGRAPH_ERROR("Invalid number (too large) of edges", IGRAPH_EINVAL); } IGRAPH_CHECK(retval = igraph_empty(graph, n1 + n2, directed)); } else { long int i; double maxedges; if (!directed || mode != IGRAPH_ALL) { maxedges = (double) n1 * (double) n2; } else { maxedges = 2.0 * (double) n1 * (double) n2; } if (m > maxedges) { IGRAPH_ERROR("Invalid number (too large) of edges", IGRAPH_EINVAL); } if (maxedges == m) { IGRAPH_CHECK(retval = igraph_full_bipartite(graph, types, n1, n2, directed, mode)); } else { long int to, from; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&s, 0); IGRAPH_CHECK(igraph_random_sample(&s, 0, maxedges - 1, m)); IGRAPH_CHECK(igraph_vector_reserve(&edges, igraph_vector_size(&s) * 2)); for (i = 0; i < m; i++) { if (!directed || mode != IGRAPH_ALL) { to = (long) floor(VECTOR(s)[i] / n1); from = (long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1); to += n1; } else { long int n1n2 = n1 * n2; if (VECTOR(s)[i] < n1n2) { to = (long) floor(VECTOR(s)[i] / n1); from = (long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1); to += n1; } else { to = (long) floor( (VECTOR(s)[i] - n1n2) / n2); from = (long) (VECTOR(s)[i] - n1n2 - ((igraph_real_t) to) * n2); from += n1; } } if (mode != IGRAPH_IN) { igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } else { igraph_vector_push_back(&edges, to); igraph_vector_push_back(&edges, from); } } igraph_vector_destroy(&s); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(retval = igraph_create(graph, &edges, n1 + n2, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); } } return retval; } /** * \function igraph_bipartite_game * \brief Generate a bipartite random graph (similar to Erdős-Rényi). * * Similarly to unipartite (one-mode) networks, we can define the * G(n,p), and G(n,m) graph classes for bipartite graphs, via their * generating process. In G(n,p) every possible edge between top and * bottom vertices is realized with probablity p, independently of the * rest of the edges. In G(n,m), we uniformly choose m edges to * realize. * * \param graph Pointer to an uninitialized igraph graph, the result * is stored here. * \param types Pointer to an initialized boolean vector, or a null * pointer. If not a null pointer, then the vertex types are stored * here. Bottom vertices come first, n1 of them, then n2 top * vertices. * \param type The type of the random graph, possible values: * \clist * \cli IGRAPH_ERDOS_RENYI_GNM * G(n,m) graph, * m edges are * selected uniformly randomly in a graph with * n vertices. * \cli IGRAPH_ERDOS_RENYI_GNP * G(n,p) graph, * every possible edge is included in the graph with * probability p. * \endclist * \param n1 The number of bottom vertices. * \param n2 The number of top verices. * \param p The connection probability for G(n,p) graphs. It is * ignored for G(n,m) graphs. * \param m The number of edges for G(n,m) graphs. It is ignored for * G(n,p) graphs. * \param directed Boolean, whether to generate a directed graph. See * also the \p mode argument. * \param mode Specifies how to direct the edges in directed * graphs. If it is \c IGRAPH_OUT, then directed edges point from * bottom vertices to top vertices. If it is \c IGRAPH_IN, edges * point from top vertices to bottom vertices. \c IGRAPH_OUT and * \c IGRAPH_IN do not generate mutual edges. If this argument is * \c IGRAPH_ALL, then each edge direction is considered * independently and mutual edges might be generated. This * argument is ignored for undirected graphs. * \return Error code. * * \sa \ref igraph_erdos_renyi_game. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. */ int igraph_bipartite_game(igraph_t *graph, igraph_vector_bool_t *types, igraph_erdos_renyi_t type, igraph_integer_t n1, igraph_integer_t n2, igraph_real_t p, igraph_integer_t m, igraph_bool_t directed, igraph_neimode_t mode) { if (n1 < 0 || n2 < 0) { IGRAPH_ERROR("Invalid number of vertices for bipartite game.", IGRAPH_EINVAL); } if (type == IGRAPH_ERDOS_RENYI_GNP) { return igraph_bipartite_game_gnp(graph, types, n1, n2, p, directed, mode); } else if (type == IGRAPH_ERDOS_RENYI_GNM) { return igraph_bipartite_game_gnm(graph, types, n1, n2, m, directed, mode); } else { IGRAPH_ERROR("Invalid bipartite game type.", IGRAPH_EINVAL); } } leidenbase/src/core/misc/coloring.c0000644000176200001440000001300314447675375017022 0ustar liggesusers/* Heuristic graph coloring algorithms. Copyright (C) 2017 Szabolcs Horvat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_coloring.h" #include "igraph_interface.h" #include "igraph_adjlist.h" #include "core/indheap.h" #include "core/interruption.h" static int igraph_i_vertex_coloring_greedy_cn(const igraph_t *graph, igraph_vector_int_t *colors) { long i, vertex, maxdeg; long vc = igraph_vcount(graph); igraph_2wheap_t cn; /* indexed heap storing number of already coloured neighbours */ igraph_vector_int_t neigh_colors; igraph_adjlist_t adjlist; IGRAPH_CHECK(igraph_vector_int_resize(colors, vc)); igraph_vector_int_fill(colors, 0); /* Nothing to do for 0 or 1 vertices. * Remember that colours are integers starting from 0, * and the 'colors' vector is already 0-initialized above. */ if (vc <= 1) { return IGRAPH_SUCCESS; } IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); /* find maximum degree and a corresponding vertex */ { igraph_vector_t degree; IGRAPH_CHECK(igraph_vector_init(°ree, 0)); IGRAPH_FINALLY(igraph_vector_destroy, °ree); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, 0)); vertex = igraph_vector_which_max(°ree); maxdeg = VECTOR(degree)[vertex]; igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_CHECK(igraph_vector_int_init(&neigh_colors, 0)); IGRAPH_CHECK(igraph_vector_int_reserve(&neigh_colors, maxdeg)); IGRAPH_FINALLY(igraph_vector_int_destroy, &neigh_colors); IGRAPH_CHECK(igraph_2wheap_init(&cn, vc)); IGRAPH_FINALLY(igraph_2wheap_destroy, &cn); for (i = 0; i < vc; ++i) if (i != vertex) { igraph_2wheap_push_with_index(&cn, i, 0); /* should not fail since memory was already reserved */ } while (1) { igraph_vector_int_t *neighbors = igraph_adjlist_get(&adjlist, vertex); long neigh_count = igraph_vector_int_size(neighbors); /* colour current vertex */ { igraph_integer_t col; IGRAPH_CHECK(igraph_vector_int_resize(&neigh_colors, neigh_count)); for (i = 0; i < neigh_count; ++i) { VECTOR(neigh_colors)[i] = VECTOR(*colors)[ VECTOR(*neighbors)[i] ]; } igraph_vector_int_sort(&neigh_colors); i = 0; col = 0; do { while (i < neigh_count && VECTOR(neigh_colors)[i] == col) { i++; } col++; } while (i < neigh_count && VECTOR(neigh_colors)[i] == col); VECTOR(*colors)[vertex] = col; } /* increment number of coloured neighbours for each neighbour of vertex */ for (i = 0; i < neigh_count; ++i) { long idx = VECTOR(*neighbors)[i]; if (igraph_2wheap_has_elem(&cn, idx)) { igraph_2wheap_modify(&cn, idx, igraph_2wheap_get(&cn, idx) + 1); } } /* stop if no more vertices left to colour */ if (igraph_2wheap_empty(&cn)) { break; } igraph_2wheap_delete_max_index(&cn, &vertex); IGRAPH_ALLOW_INTERRUPTION(); } /* subtract 1 from each colour value, so that colours start at 0 */ igraph_vector_int_add_constant(colors, -1); /* free data structures */ igraph_vector_int_destroy(&neigh_colors); igraph_adjlist_destroy(&adjlist); igraph_2wheap_destroy(&cn); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /** * \function igraph_vertex_coloring_greedy * \brief Computes a vertex coloring using a greedy algorithm. * * * This function assigns a "color"—represented as a non-negative integer—to * each vertex of the graph in such a way that neighboring vertices never have * the same color. The obtained coloring is not necessarily minimal. * * * Vertices are colored one by one, choosing the smallest color index that * differs from that of already colored neighbors. * Colors are represented with non-negative integers 0, 1, 2, ... * * \param graph The input graph. * \param colors Pointer to an initialized integer vector. The vertex colors will be stored here. * \param heuristic The vertex ordering heuristic to use during greedy coloring. See \ref igraph_coloring_greedy_t * * \return Error code. * * \example examples/simple/igraph_coloring.c */ int igraph_vertex_coloring_greedy(const igraph_t *graph, igraph_vector_int_t *colors, igraph_coloring_greedy_t heuristic) { switch (heuristic) { case IGRAPH_COLORING_GREEDY_COLORED_NEIGHBORS: return igraph_i_vertex_coloring_greedy_cn(graph, colors); default: return IGRAPH_EINVAL; } } leidenbase/src/core/misc/sir.c0000644000176200001440000002234114447675375016010 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2014 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_epidemics.h" #include "igraph_random.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_psumtree.h" #include "igraph_memory.h" #include "igraph_structural.h" #include "core/interruption.h" int igraph_sir_init(igraph_sir_t *sir) { IGRAPH_CHECK(igraph_vector_init(&sir->times, 1)); IGRAPH_FINALLY(igraph_vector_destroy, &sir->times); IGRAPH_CHECK(igraph_vector_int_init(&sir->no_s, 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &sir->no_s); IGRAPH_CHECK(igraph_vector_int_init(&sir->no_i, 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &sir->no_i); IGRAPH_CHECK(igraph_vector_int_init(&sir->no_r, 1)); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_sir_destroy * \brief Deallocates memory associated with a SIR simulation run. * * \param sir The \ref igraph_sir_t object storing the simulation. */ void igraph_sir_destroy(igraph_sir_t *sir) { igraph_vector_destroy(&sir->times); igraph_vector_int_destroy(&sir->no_s); igraph_vector_int_destroy(&sir->no_i); igraph_vector_int_destroy(&sir->no_r); } static void igraph_i_sir_destroy(igraph_vector_ptr_t *v) { int i, n = igraph_vector_ptr_size(v); for (i = 0; i < n; i++) { if ( VECTOR(*v)[i] ) { igraph_sir_destroy( VECTOR(*v)[i]) ; IGRAPH_FREE( VECTOR(*v)[i] ); /* this also sets the vector_ptr element to NULL */ } } } #define S_S 0 #define S_I 1 #define S_R 2 /** * \function igraph_sir * \brief Performs a number of SIR epidemics model runs on a graph. * * The SIR model is a simple model from epidemiology. The individuals * of the population might be in three states: susceptible, infected * and recovered. Recovered people are assumed to be immune to the * disease. Susceptibles become infected with a rate that depends on * their number of infected neigbors. Infected people become recovered * with a constant rate. See these parameters below. * * * This function runs multiple simulations, all starting with a * single uniformly randomly chosen infected individual. A simulation * is stopped when no infected individuals are left. * * \param graph The graph to perform the model on. For directed graphs * edge directions are ignored and a warning is given. * \param beta The rate of infection of an individual that is * susceptible and has a single infected neighbor. * The infection rate of a susceptible individual with n * infected neighbors is n times beta. Formally * this is the rate parameter of an exponential distribution. * \param gamma The rate of recovery of an infected individual. * Formally, this is the rate parameter of an exponential * distribution. * \param no_sim The number of simulation runs to perform. * \param result The result of the simulation is stored here, * in a list of \ref igraph_sir_t objects. To deallocate * memory, the user needs to call \ref igraph_sir_destroy on * each element, before destroying the pointer vector itself * using \ref igraph_vector_ptr_destroy_all(). * \return Error code. * * Time complexity: O(no_sim * (|V| + |E| log(|V|))). */ int igraph_sir(const igraph_t *graph, igraph_real_t beta, igraph_real_t gamma, igraph_integer_t no_sim, igraph_vector_ptr_t *result) { int infected; igraph_vector_int_t status; igraph_adjlist_t adjlist; int no_of_nodes = igraph_vcount(graph); int i, j, ns, ni, nr; igraph_vector_int_t *neis; igraph_psumtree_t tree; igraph_real_t psum; int neilen; igraph_bool_t simple; if (no_of_nodes == 0) { IGRAPH_ERROR("Cannot run SIR model on empty graph.", IGRAPH_EINVAL); } if (igraph_is_directed(graph)) { IGRAPH_WARNING("Edge directions are ignored in SIR model."); } if (beta < 0) { IGRAPH_ERROR("The infection rate beta must be non-negative in SIR model.", IGRAPH_EINVAL); } /* With a recovery rate of zero, the simulation would never stop. */ if (gamma <= 0) { IGRAPH_ERROR("The recovery rate gamma must be positive in SIR model.", IGRAPH_EINVAL); } if (no_sim <= 0) { IGRAPH_ERROR("Number of SIR simulations must be positive.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_is_simple(graph, &simple)); if (!simple) { IGRAPH_ERROR("SIR model only works with simple graphs.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_int_init(&status, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &status); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_psumtree_init(&tree, no_of_nodes)); IGRAPH_FINALLY(igraph_psumtree_destroy, &tree); IGRAPH_CHECK(igraph_vector_ptr_resize(result, no_sim)); igraph_vector_ptr_null(result); IGRAPH_FINALLY(igraph_i_sir_destroy, result); for (i = 0; i < no_sim; i++) { igraph_sir_t *sir = IGRAPH_CALLOC(1, igraph_sir_t); if (!sir) { IGRAPH_ERROR("Cannot run SIR model.", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_sir_init(sir)); VECTOR(*result)[i] = sir; } RNG_BEGIN(); for (j = 0; j < no_sim; j++) { igraph_sir_t *sir = VECTOR(*result)[j]; igraph_vector_t *times_v = &sir->times; igraph_vector_int_t *no_s_v = &sir->no_s; igraph_vector_int_t *no_i_v = &sir->no_i; igraph_vector_int_t *no_r_v = &sir->no_r; infected = RNG_INTEGER(0, no_of_nodes - 1); /* Initially infected */ igraph_vector_int_null(&status); VECTOR(status)[infected] = S_I; ns = no_of_nodes - 1; ni = 1; nr = 0; VECTOR(*times_v)[0] = 0.0; VECTOR(*no_s_v)[0] = ns; VECTOR(*no_i_v)[0] = ni; VECTOR(*no_r_v)[0] = nr; if (igraph_psumtree_sum(&tree) != 0) { igraph_psumtree_reset(&tree); } /* Rates */ IGRAPH_CHECK(igraph_psumtree_update(&tree, infected, gamma)); neis = igraph_adjlist_get(&adjlist, infected); neilen = igraph_vector_int_size(neis); for (i = 0; i < neilen; i++) { int nei = VECTOR(*neis)[i]; IGRAPH_CHECK(igraph_psumtree_update(&tree, nei, beta)); } while (ni > 0) { igraph_real_t tt; igraph_real_t r; long int vchange; IGRAPH_ALLOW_INTERRUPTION(); psum = igraph_psumtree_sum(&tree); tt = igraph_rng_get_exp(igraph_rng_default(), psum); r = RNG_UNIF(0, psum); igraph_psumtree_search(&tree, &vchange, r); neis = igraph_adjlist_get(&adjlist, vchange); neilen = igraph_vector_int_size(neis); if (VECTOR(status)[vchange] == S_I) { VECTOR(status)[vchange] = S_R; ni--; nr++; IGRAPH_CHECK(igraph_psumtree_update(&tree, vchange, 0.0)); for (i = 0; i < neilen; i++) { int nei = VECTOR(*neis)[i]; if (VECTOR(status)[nei] == S_S) { igraph_real_t rate = igraph_psumtree_get(&tree, nei); IGRAPH_CHECK(igraph_psumtree_update(&tree, nei, rate - beta)); } } } else { /* S_S */ VECTOR(status)[vchange] = S_I; ns--; ni++; IGRAPH_CHECK(igraph_psumtree_update(&tree, vchange, gamma)); for (i = 0; i < neilen; i++) { int nei = VECTOR(*neis)[i]; if (VECTOR(status)[nei] == S_S) { igraph_real_t rate = igraph_psumtree_get(&tree, nei); IGRAPH_CHECK(igraph_psumtree_update(&tree, nei, rate + beta)); } } } IGRAPH_CHECK(igraph_vector_push_back(times_v, tt + igraph_vector_tail(times_v))); IGRAPH_CHECK(igraph_vector_int_push_back(no_s_v, ns)); IGRAPH_CHECK(igraph_vector_int_push_back(no_i_v, ni)); IGRAPH_CHECK(igraph_vector_int_push_back(no_r_v, nr)); } /* psum > 0 */ } /* j < no_sim */ RNG_END(); igraph_psumtree_destroy(&tree); igraph_adjlist_destroy(&adjlist); igraph_vector_int_destroy(&status); IGRAPH_FINALLY_CLEAN(4); /* + result */ return IGRAPH_SUCCESS; } leidenbase/src/core/misc/scan.c0000644000176200001440000007574014447675375016152 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_scan.h" #include "igraph_adjlist.h" #include "igraph_arpack.h" #include "igraph_centrality.h" #include "igraph_dqueue.h" #include "igraph_eigen.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_operators.h" #include "igraph_stack.h" #include "igraph_structural.h" #include "core/interruption.h" #include "properties/properties_internal.h" /** * \section about_local_scan * * * The scan statistic is a summary of the locality statistics that is computed * from the local neighborhood of each vertex. For details, see * Priebe, C. E., Conroy, J. M., Marchette, D. J., Park, Y. (2005). * Scan Statistics on Enron Graphs. Computational and Mathematical Organization Theory. * */ /** * \function igraph_local_scan_0 * Local scan-statistics, k=0 * * K=0 scan-statistics is arbitrarily defined as the vertex degree for * unweighted, and the vertex strength for weighted graphs. See \ref * igraph_degree() and \ref igraph_strength(). * * \param graph The input graph * \param res An initialized vector, the results are stored here. * \param weights Weight vector for weighted graphs, null pointer for * unweighted graphs. * \param mode Type of the neighborhood, \c IGRAPH_OUT means outgoing, * \c IGRAPH_IN means incoming and \c IGRAPH_ALL means all edges. * \return Error code. * */ int igraph_local_scan_0(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights, igraph_neimode_t mode) { if (weights) { igraph_strength(graph, res, igraph_vss_all(), mode, /*loops=*/ 1, weights); } else { igraph_degree(graph, res, igraph_vss_all(), mode, /*loops=*/ 1); } return 0; } /* This removes loop, multiple edges and edges that point "backwards" according to the rank vector. It works on edge lists */ static int igraph_i_trans4_il_simplify(const igraph_t *graph, igraph_inclist_t *il, const igraph_vector_int_t *rank) { long int i; long int n = il->length; igraph_vector_int_t mark; igraph_vector_int_init(&mark, n); IGRAPH_FINALLY(igraph_vector_int_destroy, &mark); for (i = 0; i < n; i++) { igraph_vector_int_t *v = &il->incs[i]; int j, l = igraph_vector_int_size(v); int irank = VECTOR(*rank)[i]; VECTOR(mark)[i] = i + 1; for (j = 0; j < l; /* nothing */) { long int edge = (long int) VECTOR(*v)[j]; long int e = IGRAPH_OTHER(graph, edge, i); if (VECTOR(*rank)[e] > irank && VECTOR(mark)[e] != i + 1) { VECTOR(mark)[e] = i + 1; j++; } else { VECTOR(*v)[j] = igraph_vector_int_tail(v); igraph_vector_int_pop_back(v); l--; } } } igraph_vector_int_destroy(&mark); IGRAPH_FINALLY_CLEAN(1); return 0; } /* This one handles both weighted and unweighted cases */ static int igraph_i_local_scan_1_directed(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights, igraph_neimode_t mode) { int no_of_nodes = igraph_vcount(graph); igraph_inclist_t incs; int i, node; igraph_vector_int_t neis; IGRAPH_CHECK(igraph_inclist_init(graph, &incs, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &incs); igraph_vector_int_init(&neis, no_of_nodes); IGRAPH_FINALLY(igraph_vector_int_destroy, &neis); igraph_vector_resize(res, no_of_nodes); igraph_vector_null(res); for (node = 0; node < no_of_nodes; node++) { igraph_vector_int_t *edges1 = igraph_inclist_get(&incs, node); int edgeslen1 = igraph_vector_int_size(edges1); IGRAPH_ALLOW_INTERRUPTION(); /* Mark neighbors and self*/ VECTOR(neis)[node] = node + 1; for (i = 0; i < edgeslen1; i++) { int e = VECTOR(*edges1)[i]; int nei = IGRAPH_OTHER(graph, e, node); igraph_real_t w = weights ? VECTOR(*weights)[e] : 1; VECTOR(neis)[nei] = node + 1; VECTOR(*res)[node] += w; } /* Crawl neighbors */ for (i = 0; i < edgeslen1; i++) { int e2 = VECTOR(*edges1)[i]; int nei = IGRAPH_OTHER(graph, e2, node); if (nei == node) { break; } igraph_vector_int_t *edges2 = igraph_inclist_get(&incs, nei); int j, edgeslen2 = igraph_vector_int_size(edges2); for (j = 0; j < edgeslen2; j++) { int e2 = VECTOR(*edges2)[j]; int nei2 = IGRAPH_OTHER(graph, e2, nei); igraph_real_t w2 = weights ? VECTOR(*weights)[e2] : 1; if (VECTOR(neis)[nei2] == node + 1) { VECTOR(*res)[node] += w2; } } } } /* node < no_of_nodes */ igraph_vector_int_destroy(&neis); igraph_inclist_destroy(&incs); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_local_scan_1_directed_all(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights) { int no_of_nodes = igraph_vcount(graph); igraph_inclist_t incs; int i, node; igraph_vector_int_t neis; IGRAPH_CHECK(igraph_inclist_init(graph, &incs, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &incs); igraph_vector_int_init(&neis, no_of_nodes); IGRAPH_FINALLY(igraph_vector_int_destroy, &neis); igraph_vector_resize(res, no_of_nodes); igraph_vector_null(res); for (node = 0; node < no_of_nodes; node++) { igraph_vector_int_t *edges1 = igraph_inclist_get(&incs, node); int edgeslen1 = igraph_vector_int_size(edges1); IGRAPH_ALLOW_INTERRUPTION(); /* Mark neighbors. We also count the edges that are incident to ego. Note that this time we do not mark ego, because we don't want to double count its incident edges later, when we are going over the incident edges of ego's neighbors. */ for (i = 0; i < edgeslen1; i++) { int e = VECTOR(*edges1)[i]; int nei = IGRAPH_OTHER(graph, e, node); igraph_real_t w = weights ? VECTOR(*weights)[e] : 1; VECTOR(neis)[nei] = node + 1; VECTOR(*res)[node] += w; } /* Crawl neighbors. We make sure that each neighbor of 'node' is only crawed once. We count all qualifying edges of ego, and then unmark ego to avoid double counting. */ for (i = 0; i < edgeslen1; i++) { int e2 = VECTOR(*edges1)[i]; int nei = IGRAPH_OTHER(graph, e2, node); igraph_vector_int_t *edges2; int j, edgeslen2; if (VECTOR(neis)[nei] != node + 1) { continue; } edges2 = igraph_inclist_get(&incs, nei); edgeslen2 = igraph_vector_int_size(edges2); for (j = 0; j < edgeslen2; j++) { int e2 = VECTOR(*edges2)[j]; int nei2 = IGRAPH_OTHER(graph, e2, nei); igraph_real_t w2 = weights ? VECTOR(*weights)[e2] : 1; if (VECTOR(neis)[nei2] == node + 1) { VECTOR(*res)[node] += w2; } } VECTOR(neis)[nei] = 0; } } /* node < no_of_nodes */ igraph_vector_int_destroy(&neis); igraph_inclist_destroy(&incs); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_local_scan_1_sumweights(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights) { long int no_of_nodes = igraph_vcount(graph); long int node, i, j, nn; igraph_inclist_t allinc; igraph_vector_int_t *neis1, *neis2; long int neilen1, neilen2; long int *neis; long int maxdegree; igraph_vector_int_t order; igraph_vector_int_t rank; igraph_vector_t degree, *edge1 = °ree; /* reuse degree as edge1 */ if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } igraph_vector_int_init(&order, no_of_nodes); IGRAPH_FINALLY(igraph_vector_int_destroy, &order); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS)); maxdegree = (long int) igraph_vector_max(°ree) + 1; igraph_vector_order1_int(°ree, &order, maxdegree); igraph_vector_int_init(&rank, no_of_nodes); IGRAPH_FINALLY(igraph_vector_int_destroy, &rank); for (i = 0; i < no_of_nodes; i++) { VECTOR(rank)[ VECTOR(order)[i] ] = no_of_nodes - i - 1; } IGRAPH_CHECK(igraph_inclist_init(graph, &allinc, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &allinc); IGRAPH_CHECK(igraph_i_trans4_il_simplify(graph, &allinc, &rank)); neis = IGRAPH_CALLOC(no_of_nodes, long int); if (neis == 0) { IGRAPH_ERROR("undirected local transitivity failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, neis); IGRAPH_CHECK(igraph_strength(graph, res, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, weights)); for (nn = no_of_nodes - 1; nn >= 0; nn--) { node = VECTOR(order)[nn]; IGRAPH_ALLOW_INTERRUPTION(); neis1 = igraph_inclist_get(&allinc, node); neilen1 = igraph_vector_int_size(neis1); /* Mark the neighbors of the node */ for (i = 0; i < neilen1; i++) { int edge = VECTOR(*neis1)[i]; int nei = IGRAPH_OTHER(graph, edge, node); VECTOR(*edge1)[nei] = VECTOR(*weights)[edge]; neis[nei] = node + 1; } for (i = 0; i < neilen1; i++) { long int edge = VECTOR(*neis1)[i]; long int nei = IGRAPH_OTHER(graph, edge, node); igraph_real_t w = VECTOR(*weights)[edge]; neis2 = igraph_inclist_get(&allinc, nei); neilen2 = igraph_vector_int_size(neis2); for (j = 0; j < neilen2; j++) { long int edge2 = VECTOR(*neis2)[j]; long int nei2 = IGRAPH_OTHER(graph, edge2, nei); igraph_real_t w2 = VECTOR(*weights)[edge2]; if (neis[nei2] == node + 1) { VECTOR(*res)[node] += w2; VECTOR(*res)[nei2] += w; VECTOR(*res)[nei] += VECTOR(*edge1)[nei2]; } } } } igraph_free(neis); igraph_inclist_destroy(&allinc); igraph_vector_int_destroy(&rank); igraph_vector_destroy(°ree); igraph_vector_int_destroy(&order); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \function igraph_local_scan_1_ecount * Local scan-statistics, k=1, edge count and sum of weights * * Count the number of edges or the sum the edge weights in the * 1-neighborhood of vertices. * * \param graph The input graph * \param res An initialized vector, the results are stored here. * \param weights Weight vector for weighted graphs, null pointer for * unweighted graphs. * \param mode Type of the neighborhood, \c IGRAPH_OUT means outgoing, * \c IGRAPH_IN means incoming and \c IGRAPH_ALL means all edges. * \return Error code. * */ int igraph_local_scan_1_ecount(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights, igraph_neimode_t mode) { if (igraph_is_directed(graph)) { if (mode != IGRAPH_ALL) { return igraph_i_local_scan_1_directed(graph, res, weights, mode); } else { return igraph_i_local_scan_1_directed_all(graph, res, weights); } } else { if (weights) { return igraph_i_local_scan_1_sumweights(graph, res, weights); } else { return igraph_local_scan_k_ecount(graph, 1, res, weights, mode); } } return 0; } static int igraph_i_local_scan_0_them_w(const igraph_t *us, const igraph_t *them, igraph_vector_t *res, const igraph_vector_t *weights_them, igraph_neimode_t mode) { igraph_t is; igraph_vector_t map2; int i, m; if (!weights_them) { IGRAPH_ERROR("Edge weights not given for weighted scan-0", IGRAPH_EINVAL); } if (igraph_vector_size(weights_them) != igraph_ecount(them)) { IGRAPH_ERROR("Invalid weights length for scan-0", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&map2, 0); igraph_intersection(&is, us, them, /*map1=*/ 0, &map2); IGRAPH_FINALLY(igraph_destroy, &is); /* Rewrite the map as edge weights */ m = igraph_vector_size(&map2); for (i = 0; i < m; i++) { VECTOR(map2)[i] = VECTOR(*weights_them)[ (int) VECTOR(map2)[i] ]; } igraph_strength(&is, res, igraph_vss_all(), mode, IGRAPH_LOOPS, /*weights=*/ &map2); igraph_destroy(&is); igraph_vector_destroy(&map2); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_local_scan_0_them * Local THEM scan-statistics, k=0 * * K=0 scan-statistics is arbitrarily defined as the vertex degree for * unweighted, and the vertex strength for weighted graphs. See \ref * igraph_degree() and \ref igraph_strength(). * * \param us The input graph, to use to extract the neighborhoods. * \param them The input graph to use for the actually counting. * \param res An initialized vector, the results are stored here. * \param weights_them Weight vector for weighted graphs, null pointer for * unweighted graphs. * \param mode Type of the neighborhood, \c IGRAPH_OUT means outgoing, * \c IGRAPH_IN means incoming and \c IGRAPH_ALL means all edges. * \return Error code. * */ int igraph_local_scan_0_them(const igraph_t *us, const igraph_t *them, igraph_vector_t *res, const igraph_vector_t *weights_them, igraph_neimode_t mode) { igraph_t is; if (igraph_vcount(us) != igraph_vcount(them)) { IGRAPH_ERROR("Number of vertices don't match in scan-0", IGRAPH_EINVAL); } if (igraph_is_directed(us) != igraph_is_directed(them)) { IGRAPH_ERROR("Directedness don't match in scan-0", IGRAPH_EINVAL); } if (weights_them) { return igraph_i_local_scan_0_them_w(us, them, res, weights_them, mode); } igraph_intersection(&is, us, them, /*edgemap1=*/ 0, /*edgemap2=*/ 0); IGRAPH_FINALLY(igraph_destroy, &is); igraph_degree(&is, res, igraph_vss_all(), mode, IGRAPH_LOOPS); igraph_destroy(&is); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_local_scan_1_ecount_them * Local THEM scan-statistics, k=1, edge count and sum of weights * * Count the number of edges or the sum the edge weights in the * 1-neighborhood of vertices. * * \param us The input graph to extract the neighborhoods. * \param them The input graph to perform the counting. * \param weights_them Weight vector for weighted graphs, null pointer for * unweighted graphs. * \param mode Type of the neighborhood, \c IGRAPH_OUT means outgoing, * \c IGRAPH_IN means incoming and \c IGRAPH_ALL means all edges. * \return Error code. * * \sa \ref igraph_local_scan_1_ecount() for the US statistics. */ int igraph_local_scan_1_ecount_them(const igraph_t *us, const igraph_t *them, igraph_vector_t *res, const igraph_vector_t *weights_them, igraph_neimode_t mode) { int no_of_nodes = igraph_vcount(us); igraph_adjlist_t adj_us; igraph_inclist_t incs_them; igraph_vector_int_t neis; int node; if (igraph_vcount(them) != no_of_nodes) { IGRAPH_ERROR("Number of vertices must match in scan-1", IGRAPH_EINVAL); } if (igraph_is_directed(us) != igraph_is_directed(them)) { IGRAPH_ERROR("Directedness must match in scan-1", IGRAPH_EINVAL); } if (weights_them && igraph_vector_size(weights_them) != igraph_ecount(them)) { IGRAPH_ERROR("Invalid weight vector length in scan-1 (them)", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_adjlist_init( us, &adj_us, mode, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE )); IGRAPH_FINALLY(igraph_adjlist_destroy, &adj_us); IGRAPH_CHECK(igraph_inclist_init(them, &incs_them, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &incs_them); IGRAPH_CHECK(igraph_vector_int_init(&neis, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &neis); IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes)); igraph_vector_null(res); for (node = 0; node < no_of_nodes; node++) { igraph_vector_int_t *neis_us = igraph_adjlist_get(&adj_us, node); igraph_vector_int_t *edges1_them = igraph_inclist_get(&incs_them, node); int len1_us = igraph_vector_int_size(neis_us); int len1_them = igraph_vector_int_size(edges1_them); int i; IGRAPH_ALLOW_INTERRUPTION(); /* Mark neighbors and self in us */ VECTOR(neis)[node] = node + 1; for (i = 0; i < len1_us; i++) { int nei = VECTOR(*neis_us)[i]; VECTOR(neis)[nei] = node + 1; } /* Crawl neighbors in them, first ego */ for (i = 0; i < len1_them; i++) { int e = VECTOR(*edges1_them)[i]; int nei = IGRAPH_OTHER(them, e, node); if (VECTOR(neis)[nei] == node + 1) { igraph_real_t w = weights_them ? VECTOR(*weights_them)[e] : 1; VECTOR(*res)[node] += w; } } /* Then the rest */ for (i = 0; i < len1_us; i++) { int nei = VECTOR(*neis_us)[i]; igraph_vector_int_t *edges2_them = igraph_inclist_get(&incs_them, nei); int j, len2_them = igraph_vector_int_size(edges2_them); for (j = 0; j < len2_them; j++) { int e2 = VECTOR(*edges2_them)[j]; int nei2 = IGRAPH_OTHER(them, e2, nei); if (VECTOR(neis)[nei2] == node + 1) { igraph_real_t w = weights_them ? VECTOR(*weights_them)[e2] : 1; VECTOR(*res)[node] += w; } } } /* For undirected, it was double counted */ if (mode == IGRAPH_ALL || ! igraph_is_directed(us)) { VECTOR(*res)[node] /= 2.0; } } /* node < no_of_nodes */ igraph_vector_int_destroy(&neis); igraph_inclist_destroy(&incs_them); igraph_adjlist_destroy(&adj_us); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_local_scan_k_ecount * \brief Sum the number of edges or the weights in k-neighborhood of every vertex. * * \param graph The input graph. * \param k The size of the neighborhood, non-negative integer. * The k=0 case is special, see \ref igraph_local_scan_0(). * \param res An initialized vector, the results are stored here. * \param weights Weight vector for weighted graphs, null pointer for * unweighted graphs. * \param mode Type of the neighborhood, \c IGRAPH_OUT means outgoing, * \c IGRAPH_IN means incoming and \c IGRAPH_ALL means all edges. * \return Error code. * */ int igraph_local_scan_k_ecount(const igraph_t *graph, int k, igraph_vector_t *res, const igraph_vector_t *weights, igraph_neimode_t mode) { int no_of_nodes = igraph_vcount(graph); int node; igraph_dqueue_int_t Q; igraph_vector_int_t marked; igraph_inclist_t incs; if (k < 0) { IGRAPH_ERROR("k must be non-negative in k-scan.", IGRAPH_EINVAL); } if (weights && igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERRORF("The weight vector length (%ld) in k-scan should equal " "the number of edges of the graph (%d).", IGRAPH_EINVAL, igraph_vector_size(weights), igraph_ecount(graph)); } if (k == 0) { return igraph_local_scan_0(graph, res, weights, mode); } if (k == 1 && igraph_is_directed(graph)) { return igraph_local_scan_1_ecount(graph, res, weights, mode); } /* We do a BFS form each node, and simply count the number of edges on the way */ IGRAPH_CHECK(igraph_dqueue_int_init(&Q, 100)); IGRAPH_FINALLY(igraph_dqueue_int_destroy, &Q); IGRAPH_CHECK(igraph_vector_int_init(&marked, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &marked); IGRAPH_CHECK(igraph_inclist_init(graph, &incs, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &incs); IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes)); igraph_vector_null(res); for (node = 0 ; node < no_of_nodes ; node++) { igraph_dqueue_int_push(&Q, node); igraph_dqueue_int_push(&Q, 0); VECTOR(marked)[node] = node + 1; while (!igraph_dqueue_int_empty(&Q)) { int act = igraph_dqueue_int_pop(&Q); int dist = igraph_dqueue_int_pop(&Q) + 1; igraph_vector_int_t *edges = igraph_inclist_get(&incs, act); int i, edgeslen = igraph_vector_int_size(edges); for (i = 0; i < edgeslen; i++) { int edge = VECTOR(*edges)[i]; int nei = IGRAPH_OTHER(graph, edge, act); if (dist <= k || VECTOR(marked)[nei] == node + 1) { igraph_real_t w = weights ? VECTOR(*weights)[edge] : 1; VECTOR(*res)[node] += w; } if (dist <= k && VECTOR(marked)[nei] != node + 1) { igraph_dqueue_int_push(&Q, nei); igraph_dqueue_int_push(&Q, dist); VECTOR(marked)[nei] = node + 1; } } } if (mode == IGRAPH_ALL || ! igraph_is_directed(graph)) { VECTOR(*res)[node] /= 2.0; } } /* node < no_of_nodes */ igraph_inclist_destroy(&incs); igraph_vector_int_destroy(&marked); igraph_dqueue_int_destroy(&Q); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /** * \function igraph_local_scan_k_ecount_them * Local THEM scan-statistics, general function, edge count and sum of weights * * Count the number of edges or the sum the edge weights in the * k-neighborhood of vertices. * * \param us The input graph to extract the neighborhoods. * \param them The input graph to perform the counting. * \param k The size of the neighborhood, non-negative integer. * The k=0 case is special, see \ref igraph_local_scan_0_them(). * \param weights_them Weight vector for weighted graphs, null pointer for * unweighted graphs. * \param mode Type of the neighborhood, \c IGRAPH_OUT means outgoing, * \c IGRAPH_IN means incoming and \c IGRAPH_ALL means all edges. * \return Error code. * * \sa \ref igraph_local_scan_1_ecount() for the US statistics. */ int igraph_local_scan_k_ecount_them(const igraph_t *us, const igraph_t *them, int k, igraph_vector_t *res, const igraph_vector_t *weights_them, igraph_neimode_t mode) { int no_of_nodes = igraph_vcount(us); int node; igraph_dqueue_int_t Q; igraph_vector_int_t marked; igraph_stack_int_t ST; igraph_inclist_t incs_us, incs_them; if (igraph_vcount(them) != no_of_nodes) { IGRAPH_ERROR("Number of vertices must match in scan-k", IGRAPH_EINVAL); } if (igraph_is_directed(us) != igraph_is_directed(them)) { IGRAPH_ERROR("Directedness must match in scan-k", IGRAPH_EINVAL); } if (k < 0) { IGRAPH_ERROR("k must be non-negative in k-scan", IGRAPH_EINVAL); } if (weights_them && igraph_vector_size(weights_them) != igraph_ecount(them)) { IGRAPH_ERROR("Invalid weight vector length in k-scan (them)", IGRAPH_EINVAL); } if (k == 0) { return igraph_local_scan_0_them(us, them, res, weights_them, mode); } if (k == 1) { return igraph_local_scan_1_ecount_them(us, them, res, weights_them, mode); } /* We mark the nodes in US in a BFS. Then we check the outgoing edges of all marked nodes in THEM. */ IGRAPH_CHECK(igraph_dqueue_int_init(&Q, 100)); IGRAPH_FINALLY(igraph_dqueue_int_destroy, &Q); IGRAPH_CHECK(igraph_vector_int_init(&marked, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &marked); IGRAPH_CHECK(igraph_inclist_init(us, &incs_us, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &incs_us); IGRAPH_CHECK(igraph_inclist_init(them, &incs_them, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &incs_them); IGRAPH_CHECK(igraph_stack_int_init(&ST, 100)); IGRAPH_FINALLY(igraph_stack_int_destroy, &ST); IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes)); igraph_vector_null(res); for (node = 0; node < no_of_nodes; node++) { /* BFS to mark the nodes in US */ IGRAPH_CHECK(igraph_dqueue_int_push(&Q, node)); IGRAPH_CHECK(igraph_dqueue_int_push(&Q, 0)); IGRAPH_CHECK(igraph_stack_int_push(&ST, node)); VECTOR(marked)[node] = node + 1; while (!igraph_dqueue_int_empty(&Q)) { int act = igraph_dqueue_int_pop(&Q); int dist = igraph_dqueue_int_pop(&Q) + 1; igraph_vector_int_t *edges = igraph_inclist_get(&incs_us, act); int i, edgeslen = igraph_vector_int_size(edges); for (i = 0; i < edgeslen; i++) { int edge = VECTOR(*edges)[i]; int nei = IGRAPH_OTHER(us, edge, act); if (dist <= k && VECTOR(marked)[nei] != node + 1) { igraph_dqueue_int_push(&Q, nei); igraph_dqueue_int_push(&Q, dist); VECTOR(marked)[nei] = node + 1; igraph_stack_int_push(&ST, nei); } } } /* Now check the edges of all nodes in THEM */ while (!igraph_stack_int_empty(&ST)) { int act = igraph_stack_int_pop(&ST); igraph_vector_int_t *edges = igraph_inclist_get(&incs_them, act); int i, edgeslen = igraph_vector_int_size(edges); for (i = 0; i < edgeslen; i++) { int edge = VECTOR(*edges)[i]; int nei = IGRAPH_OTHER(them, edge, act); if (VECTOR(marked)[nei] == node + 1) { igraph_real_t w = weights_them ? VECTOR(*weights_them)[edge] : 1; VECTOR(*res)[node] += w; } } } if (mode == IGRAPH_ALL || ! igraph_is_directed(us)) { VECTOR(*res)[node] /= 2; } } /* node < no_of_nodes */ igraph_stack_int_destroy(&ST); igraph_inclist_destroy(&incs_them); igraph_inclist_destroy(&incs_us); igraph_vector_int_destroy(&marked); igraph_dqueue_int_destroy(&Q); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \function igraph_local_scan_neighborhood_ecount * Local scan-statistics with pre-calculated neighborhoods * * Count the number of edges, or sum the edge weigths in * neighborhoods given as a parameter. * * \param graph The graph to perform the counting/summing in. * \param res Initialized vector, the result is stored here. * \param weights Weight vector for weighted graphs, null pointer for * unweighted graphs. * \param neighborhoods List of igraph_vector_int_t * objects, the neighborhoods, one for each vertex in the * graph. * \return Error code. */ int igraph_local_scan_neighborhood_ecount(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *weights, const igraph_vector_ptr_t *neighborhoods) { int node, no_of_nodes = igraph_vcount(graph); igraph_inclist_t incs; igraph_vector_int_t marked; igraph_bool_t directed = igraph_is_directed(graph); if (weights && igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length in local scan", IGRAPH_EINVAL); } if (igraph_vector_ptr_size(neighborhoods) != no_of_nodes) { IGRAPH_ERROR("Invalid neighborhood list length in local scan", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_int_init(&marked, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &marked); IGRAPH_CHECK(igraph_inclist_init(graph, &incs, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &incs); IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes)); igraph_vector_null(res); for (node = 0; node < no_of_nodes; node++) { igraph_vector_int_t *nei = VECTOR(*neighborhoods)[node]; int i, neilen = igraph_vector_int_size(nei); VECTOR(marked)[node] = node + 1; for (i = 0; i < neilen; i++) { int vertex = VECTOR(*nei)[i]; if (vertex < 0 || vertex >= no_of_nodes) { IGRAPH_ERROR("Invalid vertex id in neighborhood list in local scan", IGRAPH_EINVAL); } VECTOR(marked)[vertex] = node + 1; } for (i = 0; i < neilen; i++) { int vertex = VECTOR(*nei)[i]; igraph_vector_int_t *edges = igraph_inclist_get(&incs, vertex); int j, edgeslen = igraph_vector_int_size(edges); for (j = 0; j < edgeslen; j++) { int edge = VECTOR(*edges)[j]; int nei2 = IGRAPH_OTHER(graph, edge, vertex); if (VECTOR(marked)[nei2] == node + 1) { igraph_real_t w = weights ? VECTOR(*weights)[edge] : 1; VECTOR(*res)[node] += w; } } } if (!directed) { VECTOR(*res)[node] /= 2.0; } } igraph_inclist_destroy(&incs); igraph_vector_int_destroy(&marked); IGRAPH_FINALLY_CLEAN(2); return 0; } leidenbase/src/core/misc/embedding.c0000644000176200001440000011653114447675375017136 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_embedding.h" #include "igraph_adjlist.h" #include "igraph_blas.h" #include "igraph_centrality.h" #include "igraph_interface.h" #include "igraph_structural.h" typedef struct { const igraph_t *graph; const igraph_vector_t *cvec; const igraph_vector_t *cvec2; igraph_adjlist_t *outlist, *inlist; igraph_inclist_t *eoutlist, *einlist; igraph_vector_t *tmp; const igraph_vector_t *weights; } igraph_i_asembedding_data_t; /* Adjacency matrix, unweighted, undirected. Eigendecomposition is used */ static int igraph_i_asembeddingu(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_adjlist_t *outlist = data->outlist; const igraph_vector_t *cvec = data->cvec; igraph_vector_int_t *neis; int i, j, nlen; /* to = (A+cD) from */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(outlist, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; to[i] += from[nei]; } to[i] += VECTOR(*cvec)[i] * from[i]; } return 0; } /* Adjacency matrix, weighted, undirected. Eigendecomposition is used. */ static int igraph_i_asembeddinguw(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_inclist_t *outlist = data->eoutlist; const igraph_vector_t *cvec = data->cvec; const igraph_vector_t *weights = data->weights; const igraph_t *graph = data->graph; igraph_vector_int_t *incs; int i, j, nlen; /* to = (A+cD) from */ for (i = 0; i < n; i++) { incs = igraph_inclist_get(outlist, i); nlen = igraph_vector_int_size(incs); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int edge = VECTOR(*incs)[j]; long int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; to[i] += w * from[nei]; } to[i] += VECTOR(*cvec)[i] * from[i]; } return 0; } /* Adjacency matrix, unweighted, directed. SVD. */ static int igraph_i_asembedding(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_adjlist_t *outlist = data->outlist; igraph_adjlist_t *inlist = data->inlist; const igraph_vector_t *cvec = data->cvec; igraph_vector_t *tmp = data->tmp; igraph_vector_int_t *neis; int i, j, nlen; /* tmp = (A+cD)' from */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(inlist, i); nlen = igraph_vector_int_size(neis); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; VECTOR(*tmp)[i] += from[nei]; } VECTOR(*tmp)[i] += VECTOR(*cvec)[i] * from[i]; } /* to = (A+cD) tmp */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(outlist, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; to[i] += VECTOR(*tmp)[nei]; } to[i] += VECTOR(*cvec)[i] * VECTOR(*tmp)[i]; } return 0; } /* Adjacency matrix, unweighted, directed. SVD, right eigenvectors */ static int igraph_i_asembedding_right(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_adjlist_t *inlist = data->inlist; const igraph_vector_t *cvec = data->cvec; igraph_vector_int_t *neis; int i, j, nlen; /* to = (A+cD)' from */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(inlist, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; to[i] += from[nei]; } to[i] += VECTOR(*cvec)[i] * from[i]; } return 0; } /* Adjacency matrix, weighted, directed. SVD. */ static int igraph_i_asembeddingw(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_inclist_t *outlist = data->eoutlist; igraph_inclist_t *inlist = data->einlist; const igraph_vector_t *cvec = data->cvec; const igraph_vector_t *weights = data->weights; const igraph_t *graph = data->graph; igraph_vector_t *tmp = data->tmp; igraph_vector_int_t *incs; int i, j, nlen; /* tmp = (A+cD)' from */ for (i = 0; i < n; i++) { incs = igraph_inclist_get(inlist, i); nlen = igraph_vector_int_size(incs); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { long int edge = VECTOR(*incs)[j]; long int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; VECTOR(*tmp)[i] += w * from[nei]; } VECTOR(*tmp)[i] += VECTOR(*cvec)[i] * from[i]; } /* to = (A+cD) tmp */ for (i = 0; i < n; i++) { incs = igraph_inclist_get(outlist, i); nlen = igraph_vector_int_size(incs); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int edge = VECTOR(*incs)[j]; long int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; to[i] += w * VECTOR(*tmp)[nei]; } to[i] += VECTOR(*cvec)[i] * VECTOR(*tmp)[i]; } return 0; } /* Adjacency matrix, weighted, directed. SVD, right eigenvectors. */ static int igraph_i_asembeddingw_right(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_inclist_t *inlist = data->einlist; const igraph_vector_t *cvec = data->cvec; const igraph_vector_t *weights = data->weights; const igraph_t *graph = data->graph; igraph_vector_int_t *incs; int i, j, nlen; /* to = (A+cD)' from */ for (i = 0; i < n; i++) { incs = igraph_inclist_get(inlist, i); nlen = igraph_vector_int_size(incs); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int edge = VECTOR(*incs)[j]; long int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; to[i] += w * from[nei]; } to[i] += VECTOR(*cvec)[i] * from[i]; } return 0; } /* Laplacian D-A, unweighted, undirected. Eigendecomposition. */ static int igraph_i_lsembedding_da(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_adjlist_t *outlist = data->outlist; const igraph_vector_t *cvec = data->cvec; igraph_vector_int_t *neis; int i, j, nlen; /* to = (D-A) from */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(outlist, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; to[i] -= from[nei]; } to[i] += VECTOR(*cvec)[i] * from[i]; } return 0; } /* Laplacian D-A, weighted, undirected. Eigendecomposition. */ static int igraph_i_lsembedding_daw(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_inclist_t *outlist = data->eoutlist; const igraph_vector_t *cvec = data->cvec; const igraph_vector_t *weights = data->weights; const igraph_t *graph = data->graph; igraph_vector_int_t *incs; int i, j, nlen; /* to = (D-A) from */ for (i = 0; i < n; i++) { incs = igraph_inclist_get(outlist, i); nlen = igraph_vector_int_size(incs); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int edge = VECTOR(*incs)[j]; long int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; to[i] -= w * from[nei]; } to[i] += VECTOR(*cvec)[i] * from[i]; } return 0; } /* Laplacian DAD, unweighted, undirected. Eigendecomposition. */ static int igraph_i_lsembedding_dad(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_adjlist_t *outlist = data->outlist; const igraph_vector_t *cvec = data->cvec; igraph_vector_t *tmp = data->tmp; igraph_vector_int_t *neis; int i, j, nlen; /* to = D^1/2 from */ for (i = 0; i < n; i++) { to[i] = VECTOR(*cvec)[i] * from[i]; } /* tmp = A to */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(outlist, i); nlen = igraph_vector_int_size(neis); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; VECTOR(*tmp)[i] += to[nei]; } } /* to = D tmp */ for (i = 0; i < n; i++) { to[i] = VECTOR(*cvec)[i] * VECTOR(*tmp)[i]; } return 0; } static int igraph_i_lsembedding_dadw(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_inclist_t *outlist = data->eoutlist; const igraph_vector_t *cvec = data->cvec; const igraph_vector_t *weights = data->weights; const igraph_t *graph = data->graph; igraph_vector_t *tmp = data->tmp; igraph_vector_int_t *incs; int i, j, nlen; /* to = D^-1/2 from */ for (i = 0; i < n; i++) { to[i] = VECTOR(*cvec)[i] * from[i]; } /* tmp = A' to */ for (i = 0; i < n; i++) { incs = igraph_inclist_get(outlist, i); nlen = igraph_vector_int_size(incs); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { long int edge = VECTOR(*incs)[j]; long int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; VECTOR(*tmp)[i] += w * to[nei]; } } /* to = D tmp */ for (i = 0; i < n; i++) { to[i] = VECTOR(*cvec)[i] * VECTOR(*cvec)[i] * VECTOR(*tmp)[i]; } /* tmp = A to */ for (i = 0; i < n; i++) { incs = igraph_inclist_get(outlist, i); nlen = igraph_vector_int_size(incs); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { long int edge = VECTOR(*incs)[j]; long int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; VECTOR(*tmp)[i] += w * to[nei]; } } /* to = D^-1/2 tmp */ for (i = 0; i < n; i++) { to[i] = VECTOR(*cvec)[i] * VECTOR(*tmp)[i]; } return 0; } /* Laplacian I-DAD, unweighted, undirected. Eigendecomposition. */ static int igraph_i_lsembedding_idad(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { int i; igraph_i_lsembedding_dad(to, from, n, extra); for (i = 0; i < n; i++) { to[i] = from[i] - to[i]; } return 0; } static int igraph_i_lsembedding_idadw(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { int i; igraph_i_lsembedding_dadw(to, from, n, extra); for (i = 0; i < n; i++) { to[i] = from[i] - to[i]; } return 0; } /* Laplacian OAP, unweighted, directed. SVD. */ static int igraph_i_lseembedding_oap(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_adjlist_t *outlist = data->outlist; igraph_adjlist_t *inlist = data->inlist; const igraph_vector_t *deg_in = data->cvec; const igraph_vector_t *deg_out = data->cvec2; igraph_vector_t *tmp = data->tmp; igraph_vector_int_t *neis; int i, j, nlen; /* tmp = O' from */ for (i = 0; i < n; i++) { VECTOR(*tmp)[i] = VECTOR(*deg_out)[i] * from[i]; } /* to = A' tmp */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(inlist, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { int nei = VECTOR(*neis)[j]; to[i] += VECTOR(*tmp)[nei]; } } /* tmp = P' to */ for (i = 0; i < n; i++) { VECTOR(*tmp)[i] = VECTOR(*deg_in)[i] * to[i]; } /* to = P tmp */ for (i = 0; i < n; i++) { to[i] = VECTOR(*deg_in)[i] * VECTOR(*tmp)[i]; } /* tmp = A to */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(outlist, i); nlen = igraph_vector_int_size(neis); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { int nei = VECTOR(*neis)[j]; VECTOR(*tmp)[i] += to[nei]; } } /* to = O tmp */ for (i = 0; i < n; i++) { to[i] = VECTOR(*deg_out)[i] * VECTOR(*tmp)[i]; } return 0; } /* Laplacian OAP, unweighted, directed. SVD, right eigenvectors. */ static int igraph_i_lseembedding_oap_right(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_adjlist_t *inlist = data->inlist; const igraph_vector_t *deg_in = data->cvec; const igraph_vector_t *deg_out = data->cvec2; igraph_vector_t *tmp = data->tmp; igraph_vector_int_t *neis; int i, j, nlen; /* to = O' from */ for (i = 0; i < n; i++) { to[i] = VECTOR(*deg_out)[i] * from[i]; } /* tmp = A' to */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(inlist, i); nlen = igraph_vector_int_size(neis); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { int nei = VECTOR(*neis)[j]; VECTOR(*tmp)[i] += to[nei]; } } /* to = P' tmp */ for (i = 0; i < n; i++) { to[i] = VECTOR(*deg_in)[i] * VECTOR(*tmp)[i]; } return 0; } /* Laplacian OAP, weighted, directed. SVD. */ static int igraph_i_lseembedding_oapw(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_inclist_t *outlist = data->eoutlist; igraph_inclist_t *inlist = data->einlist; const igraph_vector_t *deg_in = data->cvec; const igraph_vector_t *deg_out = data->cvec2; const igraph_vector_t *weights = data->weights; const igraph_t *graph = data->graph; igraph_vector_t *tmp = data->tmp; igraph_vector_int_t *neis; int i, j, nlen; /* tmp = O' from */ for (i = 0; i < n; i++) { VECTOR(*tmp)[i] = VECTOR(*deg_out)[i] * from[i]; } /* to = A' tmp */ for (i = 0; i < n; i++) { neis = igraph_inclist_get(inlist, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { int edge = VECTOR(*neis)[j]; int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; to[i] += w * VECTOR(*tmp)[nei]; } } /* tmp = P' to */ for (i = 0; i < n; i++) { VECTOR(*tmp)[i] = VECTOR(*deg_in)[i] * to[i]; } /* to = P tmp */ for (i = 0; i < n; i++) { to[i] = VECTOR(*deg_in)[i] * VECTOR(*tmp)[i]; } /* tmp = A to */ for (i = 0; i < n; i++) { neis = igraph_inclist_get(outlist, i); nlen = igraph_vector_int_size(neis); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { int edge = VECTOR(*neis)[j]; int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; VECTOR(*tmp)[i] += w * to[nei]; } } /* to = O tmp */ for (i = 0; i < n; i++) { to[i] = VECTOR(*deg_out)[i] * VECTOR(*tmp)[i]; } return 0; } /* Laplacian OAP, weighted, directed. SVD, right eigenvectors. */ static int igraph_i_lseembedding_oapw_right(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_asembedding_data_t *data = extra; igraph_inclist_t *inlist = data->einlist; const igraph_vector_t *deg_in = data->cvec; const igraph_vector_t *deg_out = data->cvec2; const igraph_vector_t *weights = data->weights; const igraph_t *graph = data->graph; igraph_vector_t *tmp = data->tmp; igraph_vector_int_t *neis; int i, j, nlen; /* to = O' from */ for (i = 0; i < n; i++) { to[i] = VECTOR(*deg_out)[i] * from[i]; } /* tmp = A' to */ for (i = 0; i < n; i++) { neis = igraph_inclist_get(inlist, i); nlen = igraph_vector_int_size(neis); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { int edge = VECTOR(*neis)[j]; int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; VECTOR(*tmp)[i] += w * to[nei]; } } /* to = P' tmp */ for (i = 0; i < n; i++) { to[i] = VECTOR(*deg_in)[i] * VECTOR(*tmp)[i]; } return 0; } static int igraph_i_spectral_embedding(const igraph_t *graph, igraph_integer_t no, const igraph_vector_t *weights, igraph_eigen_which_position_t which, igraph_bool_t scaled, igraph_matrix_t *X, igraph_matrix_t *Y, igraph_vector_t *D, const igraph_vector_t *cvec, const igraph_vector_t *cvec2, igraph_arpack_options_t *options, igraph_arpack_function_t *callback, igraph_arpack_function_t *callback_right, igraph_bool_t symmetric, igraph_bool_t eigen, igraph_bool_t zapsmall) { igraph_integer_t vc = igraph_vcount(graph); igraph_vector_t tmp; igraph_adjlist_t outlist, inlist; igraph_inclist_t eoutlist, einlist; int i, j, cveclen = igraph_vector_size(cvec); igraph_i_asembedding_data_t data; igraph_vector_t tmpD; data.graph = graph; data.cvec = cvec; data.cvec2 = cvec2; data.outlist = &outlist; data.inlist = &inlist; data.eoutlist = &eoutlist; data.einlist = &einlist; data.tmp = &tmp; data.weights = weights; if (weights && igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } if (which != IGRAPH_EIGEN_LM && which != IGRAPH_EIGEN_LA && which != IGRAPH_EIGEN_SA) { IGRAPH_ERROR("Invalid eigenvalue chosen, must be one of " "`largest magnitude', `largest algebraic' or " "`smallest algebraic'", IGRAPH_EINVAL); } if (no > vc) { IGRAPH_ERROR("Too many singular values requested", IGRAPH_EINVAL); } if (no <= 0) { IGRAPH_ERROR("No singular values requested", IGRAPH_EINVAL); } if (cveclen != 1 && cveclen != vc) { IGRAPH_ERROR("Augmentation vector size is invalid, it should be " "the number of vertices or scalar", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_resize(X, vc, no)); if (Y) { IGRAPH_CHECK(igraph_matrix_resize(Y, vc, no)); } /* empty graph */ if (igraph_ecount(graph) == 0) { igraph_matrix_null(X); if (Y) { igraph_matrix_null(Y); } return 0; } igraph_vector_init(&tmp, vc); IGRAPH_FINALLY(igraph_vector_destroy, &tmp); if (!weights) { IGRAPH_CHECK(igraph_adjlist_init(graph, &outlist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &outlist); if (!symmetric) { IGRAPH_CHECK(igraph_adjlist_init(graph, &inlist, IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &inlist); } } else { IGRAPH_CHECK(igraph_inclist_init(graph, &eoutlist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &eoutlist); if (!symmetric) { IGRAPH_CHECK(igraph_inclist_init(graph, &einlist, IGRAPH_IN, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &einlist); } } IGRAPH_VECTOR_INIT_FINALLY(&tmpD, no); options->n = vc; options->start = 0; /* random start vector */ options->nev = no; switch (which) { case IGRAPH_EIGEN_LM: options->which[0] = 'L'; options->which[1] = 'M'; break; case IGRAPH_EIGEN_LA: options->which[0] = 'L'; options->which[1] = 'A'; break; case IGRAPH_EIGEN_SA: options->which[0] = 'S'; options->which[1] = 'A'; break; default: break; } options->ncv = no + 3; if (options->ncv > vc) { options->ncv = vc; } IGRAPH_CHECK(igraph_arpack_rssolve(callback, &data, options, 0, &tmpD, X)); if (!symmetric) { /* calculate left eigenvalues */ IGRAPH_CHECK(igraph_matrix_resize(Y, vc, no)); for (i = 0; i < no; i++) { igraph_real_t norm; igraph_vector_t v; callback_right(&MATRIX(*Y, 0, i), &MATRIX(*X, 0, i), vc, &data); igraph_vector_view(&v, &MATRIX(*Y, 0, i), vc); norm = 1.0 / igraph_blas_dnrm2(&v); igraph_vector_scale(&v, norm); } } else if (Y) { IGRAPH_CHECK(igraph_matrix_update(Y, X)); } if (zapsmall) { igraph_vector_zapsmall(&tmpD, 0); igraph_matrix_zapsmall(X, 0); if (Y) { igraph_matrix_zapsmall(Y, 0); } } if (D) { igraph_vector_update(D, &tmpD); if (!eigen) { for (i = 0; i < no; i++) { VECTOR(*D)[i] = sqrt(VECTOR(*D)[i]); } } } if (scaled) { if (eigen) { /* eigenvalues were calculated */ for (i = 0; i < no; i++) { VECTOR(tmpD)[i] = sqrt(fabs(VECTOR(tmpD)[i])); } } else { /* singular values were calculated */ for (i = 0; i < no; i++) { VECTOR(tmpD)[i] = sqrt(sqrt(VECTOR(tmpD)[i])); } } for (j = 0; j < vc; j++) { for (i = 0; i < no; i++) { MATRIX(*X, j, i) *= VECTOR(tmpD)[i]; } } if (Y) { for (j = 0; j < vc; j++) { for (i = 0; i < no; i++) { MATRIX(*Y, j, i) *= VECTOR(tmpD)[i]; } } } } igraph_vector_destroy(&tmpD); if (!weights) { if (!symmetric) { igraph_adjlist_destroy(&inlist); IGRAPH_FINALLY_CLEAN(1); } igraph_adjlist_destroy(&outlist); } else { if (!symmetric) { igraph_inclist_destroy(&einlist); IGRAPH_FINALLY_CLEAN(1); } igraph_inclist_destroy(&eoutlist); } igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_adjacency_spectral_embedding * Adjacency spectral embedding * * Spectral decomposition of the adjacency matrices of graphs. * This function computes an n-dimensional Euclidean * representation of the graph based on its adjacency * matrix, A. This representation is computed via the singular value * decomposition of the adjacency matrix, A=U D V^T. In the case, * where the graph is a random dot product graph generated using latent * position vectors in R^n for each vertex, the embedding will * provide an estimate of these latent vectors. * * * For undirected graphs, the latent positions are calculated as * X = U^n D^(1/2) where U^n equals to the first no columns of U, and * D^(1/2) is a diagonal matrix containing the square root of the selected * singular values on the diagonal. * * * For directed graphs, the embedding is defined as the pair * X = U^n D^(1/2), Y = V^n D^(1/2). * (For undirected graphs U=V, so it is sufficient to keep one of them.) * * \param graph The input graph, can be directed or undirected. * \param n An integer scalar. This value is the embedding dimension of * the spectral embedding. Should be smaller than the number of * vertices. The largest n-dimensional non-zero * singular values are used for the spectral embedding. * \param weights Optional edge weights. Supply a null pointer for * unweighted graphs. * \param which Which eigenvalues (or singular values, for directed * graphs) to use, possible values: * \clist * \cli IGRAPH_EIGEN_LM * the ones with the largest magnitude * \cli IGRAPH_EIGEN_LA * the (algebraic) largest ones * \cli IGRAPH_EIGEN_SA * the (algebraic) smallest ones. * \endclist * For directed graphs, IGRAPH_EIGEN_LM and * IGRAPH_EIGEN_LA are the same because singular * values are used for the ordering instead of eigenvalues. * \param scaled Whether to return X and Y (if \c scaled is true), or * U and V. * \param X Initialized matrix, the estimated latent positions are * stored here. * \param Y Initialized matrix or a null pointer. If not a null * pointer, then the second half of the latent positions are * stored here. (For undirected graphs, this always equals X.) * \param D Initialized vector or a null pointer. If not a null * pointer, then the eigenvalues (for undirected graphs) or the * singular values (for directed graphs) are stored here. * \param cvec A numeric vector, its length is the number vertices in the * graph. This vector is added to the diagonal of the adjacency * matrix, before performing the SVD. * \param options Options to ARPACK. See \ref igraph_arpack_options_t * for details. Note that the function overwrites the * n (number of vertices), nev and * which parameters and it always starts the * calculation from a random start vector. * \return Error code. * */ int igraph_adjacency_spectral_embedding(const igraph_t *graph, igraph_integer_t n, const igraph_vector_t *weights, igraph_eigen_which_position_t which, igraph_bool_t scaled, igraph_matrix_t *X, igraph_matrix_t *Y, igraph_vector_t *D, const igraph_vector_t *cvec, igraph_arpack_options_t *options) { igraph_arpack_function_t *callback, *callback_right; igraph_bool_t directed = igraph_is_directed(graph); if (directed) { callback = weights ? igraph_i_asembeddingw : igraph_i_asembedding; callback_right = (weights ? igraph_i_asembeddingw_right : igraph_i_asembedding_right); } else { callback = weights ? igraph_i_asembeddinguw : igraph_i_asembeddingu; callback_right = 0; } return igraph_i_spectral_embedding(graph, n, weights, which, scaled, X, Y, D, cvec, /* deg2=*/ 0, options, callback, callback_right, /*symmetric=*/ !directed, /*eigen=*/ !directed, /*zapsmall=*/ 1); } static int igraph_i_lse_und(const igraph_t *graph, igraph_integer_t no, const igraph_vector_t *weights, igraph_eigen_which_position_t which, igraph_laplacian_spectral_embedding_type_t type, igraph_bool_t scaled, igraph_matrix_t *X, igraph_matrix_t *Y, igraph_vector_t *D, igraph_arpack_options_t *options) { igraph_arpack_function_t *callback; igraph_vector_t deg; switch (type) { case IGRAPH_EMBEDDING_D_A: callback = weights ? igraph_i_lsembedding_daw : igraph_i_lsembedding_da; break; case IGRAPH_EMBEDDING_DAD: callback = weights ? igraph_i_lsembedding_dadw : igraph_i_lsembedding_dad; break; case IGRAPH_EMBEDDING_I_DAD: callback = weights ? igraph_i_lsembedding_idadw : igraph_i_lsembedding_idad; break; default: IGRAPH_ERROR("Invalid Laplacian spectral embedding type", IGRAPH_EINVAL); break; } IGRAPH_VECTOR_INIT_FINALLY(°, 0); igraph_strength(graph, °, igraph_vss_all(), IGRAPH_ALL, /*loops=*/ 1, weights); switch (type) { case IGRAPH_EMBEDDING_D_A: break; case IGRAPH_EMBEDDING_DAD: case IGRAPH_EMBEDDING_I_DAD: { int i, n = igraph_vector_size(°); for (i = 0; i < n; i++) { VECTOR(deg)[i] = 1.0 / sqrt(VECTOR(deg)[i]); } } break; default: break; } IGRAPH_CHECK(igraph_i_spectral_embedding(graph, no, weights, which, scaled, X, Y, D, /*cvec=*/ °, /*deg2=*/ 0, options, callback, 0, /*symmetric=*/ 1, /*eigen=*/ 1, /*zapsmall=*/ 1)); igraph_vector_destroy(°); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_lse_dir(const igraph_t *graph, igraph_integer_t no, const igraph_vector_t *weights, igraph_eigen_which_position_t which, igraph_laplacian_spectral_embedding_type_t type, igraph_bool_t scaled, igraph_matrix_t *X, igraph_matrix_t *Y, igraph_vector_t *D, igraph_arpack_options_t *options) { igraph_arpack_function_t *callback = weights ? igraph_i_lseembedding_oapw : igraph_i_lseembedding_oap; igraph_arpack_function_t *callback_right = weights ? igraph_i_lseembedding_oapw_right : igraph_i_lseembedding_oap_right; igraph_vector_t deg_in, deg_out; int i, n = igraph_vcount(graph); if (type != IGRAPH_EMBEDDING_OAP) { IGRAPH_ERROR("Invalid Laplacian spectral embedding type", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(°_in, n); IGRAPH_VECTOR_INIT_FINALLY(°_out, n); igraph_strength(graph, °_in, igraph_vss_all(), IGRAPH_IN, /*loops=*/ 1, weights); igraph_strength(graph, °_out, igraph_vss_all(), IGRAPH_OUT, /*loops=*/ 1, weights); for (i = 0; i < n; i++) { VECTOR(deg_in)[i] = 1.0 / sqrt(VECTOR(deg_in)[i]); VECTOR(deg_out)[i] = 1.0 / sqrt(VECTOR(deg_out)[i]); } IGRAPH_CHECK(igraph_i_spectral_embedding(graph, no, weights, which, scaled, X, Y, D, /*cvec=*/ °_in, /*deg2=*/ °_out, options, callback, callback_right, /*symmetric=*/ 0, /*eigen=*/ 0, /*zapsmall=*/ 1)); igraph_vector_destroy(°_in); igraph_vector_destroy(°_out); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_laplacian_spectral_embedding * Spectral embedding of the Laplacian of a graph * * This function essentially does the same as * \ref igraph_adjacency_spectral_embedding, but works on the Laplacian * of the graph, instead of the adjacency matrix. * \param graph The input graph. * \param n The number of eigenvectors (or singular vectors if the graph * is directed) to use for the embedding. * \param weights Optional edge weights. Supply a null pointer for * unweighted graphs. * \param which Which eigenvalues (or singular values, for directed * graphs) to use, possible values: * \clist * \cli IGRAPH_EIGEN_LM * the ones with the largest magnitude * \cli IGRAPH_EIGEN_LA * the (algebraic) largest ones * \cli IGRAPH_EIGEN_SA * the (algebraic) smallest ones. * \endclist * For directed graphs, IGRAPH_EIGEN_LM and * IGRAPH_EIGEN_LA are the same because singular * values are used for the ordering instead of eigenvalues. * \param type The type of the Laplacian to use. Various definitions * exist for the Laplacian of a graph, and one can choose * between them with this argument. Possible values: * \clist * \cli IGRAPH_EMBEDDING_D_A * means D - A where D is the * degree matrix and A is the adjacency matrix * \cli IGRAPH_EMBEDDING_DAD * means Di times A times Di, * where Di is the inverse of the square root of the degree matrix; * \cli IGRAPH_EMBEDDING_I_DAD * means I - Di A Di, where I * is the identity matrix. * \endclist * \param scaled Whether to return X and Y (if \c scaled is true), or * U and V. * \param X Initialized matrix, the estimated latent positions are * stored here. * \param Y Initialized matrix or a null pointer. If not a null * pointer, then the second half of the latent positions are * stored here. (For undirected graphs, this always equals X.) * \param D Initialized vector or a null pointer. If not a null * pointer, then the eigenvalues (for undirected graphs) or the * singular values (for directed graphs) are stored here. * \param options Options to ARPACK. See \ref igraph_arpack_options_t * for details. Note that the function overwrites the * n (number of vertices), nev and * which parameters and it always starts the * calculation from a random start vector. * \return Error code. * * \sa \ref igraph_adjacency_spectral_embedding to embed the adjacency * matrix. */ int igraph_laplacian_spectral_embedding(const igraph_t *graph, igraph_integer_t n, const igraph_vector_t *weights, igraph_eigen_which_position_t which, igraph_laplacian_spectral_embedding_type_t type, igraph_bool_t scaled, igraph_matrix_t *X, igraph_matrix_t *Y, igraph_vector_t *D, igraph_arpack_options_t *options) { if (igraph_is_directed(graph)) { return igraph_i_lse_dir(graph, n, weights, which, type, scaled, X, Y, D, options); } else { return igraph_i_lse_und(graph, n, weights, which, type, scaled, X, Y, D, options); } } /** * \function igraph_dim_select * Dimensionality selection * * Dimensionality selection for singular values using * profile likelihood. * * * The input of the function is a numeric vector which contains * the measure of "importance" for each dimension. * * * For spectral embedding, these are the singular values of the adjacency * matrix. The singular values are assumed to be generated from a * Gaussian mixture distribution with two components that have different * means and same variance. The dimensionality d is chosen to * maximize the likelihood when the d largest singular values are * assigned to one component of the mixture and the rest of the singular * values assigned to the other component. * * * This function can also be used for the general separation problem, * where we assume that the left and the right of the vector are coming * from two normal distributions, with different means, and we want * to know their border. * * \param sv A numeric vector, the ordered singular values. * \param dim The result is stored here. * \return Error code. * * Time complexity: O(n), n is the number of values in sv. * * \sa \ref igraph_adjacency_spectral_embedding(). */ int igraph_dim_select(const igraph_vector_t *sv, igraph_integer_t *dim) { int i, n = igraph_vector_size(sv); igraph_real_t x, x2, sum1 = 0.0, sum2 = igraph_vector_sum(sv); igraph_real_t sumsq1 = 0.0, sumsq2 = 0.0; /* to be set */ igraph_real_t oldmean1, oldmean2, mean1 = 0.0, mean2 = sum2 / n; igraph_real_t varsq1 = 0.0, varsq2 = 0.0; /* to be set */ igraph_real_t var1, var2, sd, profile, max = IGRAPH_NEGINFINITY; if (n == 0) { IGRAPH_ERROR("Need at least one singular value for dimensionality " "selection", IGRAPH_EINVAL); } if (n == 1) { *dim = 1; return 0; } for (i = 0; i < n; i++) { x = VECTOR(*sv)[i]; sumsq2 += x * x; varsq2 += (mean2 - x) * (mean2 - x); } for (i = 0; i < n - 1; i++) { int n1 = i + 1, n2 = n - i - 1, n1m1 = n1 - 1, n2m1 = n2 - 1; x = VECTOR(*sv)[i]; x2 = x * x; sum1 += x; sum2 -= x; sumsq1 += x2; sumsq2 -= x2; oldmean1 = mean1; oldmean2 = mean2; mean1 = sum1 / n1; mean2 = sum2 / n2; varsq1 += (x - oldmean1) * (x - mean1); varsq2 -= (x - oldmean2) * (x - mean2); var1 = i == 0 ? 0 : varsq1 / n1m1; var2 = i == n - 2 ? 0 : varsq2 / n2m1; sd = sqrt(( n1m1 * var1 + n2m1 * var2) / (n - 2)); profile = /* - n * log(2.0*M_PI)/2.0 */ /* This is redundant */ - n * log(sd) - ((sumsq1 - 2 * mean1 * sum1 + n1 * mean1 * mean1) + (sumsq2 - 2 * mean2 * sum2 + n2 * mean2 * mean2)) / 2.0 / sd / sd; if (profile > max) { max = profile; *dim = n1; } } /* Plus the last case, all elements in one group */ x = VECTOR(*sv)[n - 1]; sum1 += x; oldmean1 = mean1; mean1 = sum1 / n; sumsq1 += x * x; varsq1 += (x - oldmean1) * (x - mean1); var1 = varsq1 / (n - 1); sd = sqrt(var1); profile = /* - n * log(2.0*M_PI)/2.0 */ /* This is redundant */ - n * log(sd) - (sumsq1 - 2 * mean1 * sum1 + n * mean1 * mean1) / 2.0 / sd / sd; if (profile > max) { max = profile; *dim = n; } return 0; } leidenbase/src/core/misc/cocitation.c0000644000176200001440000007045114447675375017354 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph R package. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_cocitation.h" #include "igraph_memory.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "core/interruption.h" #include int igraph_cocitation_real(const igraph_t *graph, igraph_matrix_t *res, igraph_vs_t vids, igraph_neimode_t mode, igraph_vector_t *weights); /** * \ingroup structural * \function igraph_cocitation * \brief Cocitation coupling. * * * Two vertices are cocited if there is another vertex citing both of * them. \ref igraph_cocitation() simply counts how many times two vertices are * cocited. * The cocitation score for each given vertex and all other vertices * in the graph will be calculated. * \param graph The graph object to analyze. * \param res Pointer to a matrix, the result of the calculation will * be stored here. The number of its rows is the same as the * number of vertex ids in \p vids, the number of * columns is the number of vertices in the graph. * \param vids The vertex ids of the vertices for which the * calculation will be done. * \return Error code: * \c IGRAPH_EINVVID: invalid vertex id. * * Time complexity: O(|V|d^2), |V| is * the number of vertices in the graph, * d is the (maximum) degree of * the vertices in the graph. * * \sa \ref igraph_bibcoupling() * * \example examples/simple/igraph_cocitation.c */ int igraph_cocitation(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids) { return igraph_cocitation_real(graph, res, vids, IGRAPH_OUT, 0); } /** * \ingroup structural * \function igraph_bibcoupling * \brief Bibliographic coupling. * * * The bibliographic coupling of two vertices is the number * of other vertices they both cite, \ref igraph_bibcoupling() calculates * this. * The bibliographic coupling score for each given vertex and all * other vertices in the graph will be calculated. * \param graph The graph object to analyze. * \param res Pointer to a matrix, the result of the calculation will * be stored here. The number of its rows is the same as the * number of vertex ids in \p vids, the number of * columns is the number of vertices in the graph. * \param vids The vertex ids of the vertices for which the * calculation will be done. * \return Error code: * \c IGRAPH_EINVVID: invalid vertex id. * * Time complexity: O(|V|d^2), * |V| is the number of vertices in * the graph, d is the (maximum) * degree of the vertices in the graph. * * \sa \ref igraph_cocitation() * * \example examples/simple/igraph_cocitation.c */ int igraph_bibcoupling(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids) { return igraph_cocitation_real(graph, res, vids, IGRAPH_IN, 0); } /** * \ingroup structural * \function igraph_similarity_inverse_log_weighted * \brief Vertex similarity based on the inverse logarithm of vertex degrees. * * * The inverse log-weighted similarity of two vertices is the number of * their common neighbors, weighted by the inverse logarithm of their degrees. * It is based on the assumption that two vertices should be considered * more similar if they share a low-degree common neighbor, since high-degree * common neighbors are more likely to appear even by pure chance. * * * Isolated vertices will have zero similarity to any other vertex. * Self-similarities are not calculated. * * * See the following paper for more details: Lada A. Adamic and Eytan Adar: * Friends and neighbors on the Web. Social Networks, 25(3):211-230, 2003. * * \param graph The graph object to analyze. * \param res Pointer to a matrix, the result of the calculation will * be stored here. The number of its rows is the same as the * number of vertex ids in \p vids, the number of * columns is the number of vertices in the graph. * \param vids The vertex ids of the vertices for which the * calculation will be done. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing edges will be considered for each node. Nodes * will be weighted according to their in-degree. * \cli IGRAPH_IN * the incoming edges will be considered for each node. Nodes * will be weighted according to their out-degree. * \cli IGRAPH_ALL * the directed graph is considered as an undirected one for the * computation. Every node is weighted according to its undirected * degree. * \endclist * \return Error code: * \c IGRAPH_EINVVID: invalid vertex id. * * Time complexity: O(|V|d^2), * |V| is the number of vertices in * the graph, d is the (maximum) * degree of the vertices in the graph. * * \example examples/simple/igraph_similarity.c */ int igraph_similarity_inverse_log_weighted(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids, igraph_neimode_t mode) { igraph_vector_t weights; igraph_neimode_t mode0; long int i, no_of_nodes; switch (mode) { case IGRAPH_OUT: mode0 = IGRAPH_IN; break; case IGRAPH_IN: mode0 = IGRAPH_OUT; break; default: mode0 = IGRAPH_ALL; } no_of_nodes = igraph_vcount(graph); IGRAPH_VECTOR_INIT_FINALLY(&weights, no_of_nodes); IGRAPH_CHECK(igraph_degree(graph, &weights, igraph_vss_all(), mode0, 1)); for (i = 0; i < no_of_nodes; i++) { if (VECTOR(weights)[i] > 1) { VECTOR(weights)[i] = 1.0 / log(VECTOR(weights)[i]); } } IGRAPH_CHECK(igraph_cocitation_real(graph, res, vids, mode0, &weights)); igraph_vector_destroy(&weights); IGRAPH_FINALLY_CLEAN(1); return 0; } int igraph_cocitation_real(const igraph_t *graph, igraph_matrix_t *res, igraph_vs_t vids, igraph_neimode_t mode, igraph_vector_t *weights) { long int no_of_nodes = igraph_vcount(graph); long int no_of_vids; long int from, i, j, k, l, u, v; igraph_vector_t neis = IGRAPH_VECTOR_NULL; igraph_vector_t vid_reverse_index; igraph_vit_t vit; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); no_of_vids = IGRAPH_VIT_SIZE(vit); /* Create a mapping from vertex IDs to the row of the matrix where * the result for this vertex will appear */ IGRAPH_VECTOR_INIT_FINALLY(&vid_reverse_index, no_of_nodes); igraph_vector_fill(&vid_reverse_index, -1); for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { v = IGRAPH_VIT_GET(vit); if (v < 0 || v >= no_of_nodes) { IGRAPH_ERROR("invalid vertex ID in vertex selector", IGRAPH_EINVAL); } VECTOR(vid_reverse_index)[v] = i; } IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_matrix_resize(res, no_of_vids, no_of_nodes)); igraph_matrix_null(res); /* The result */ for (from = 0; from < no_of_nodes; from++) { igraph_real_t weight = 1; IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) from, mode)); if (weights) { weight = VECTOR(*weights)[from]; } for (i = 0; i < igraph_vector_size(&neis) - 1; i++) { u = (long int) VECTOR(neis)[i]; k = (long int) VECTOR(vid_reverse_index)[u]; for (j = i + 1; j < igraph_vector_size(&neis); j++) { v = (long int) VECTOR(neis)[j]; l = (long int) VECTOR(vid_reverse_index)[v]; if (k != -1) { MATRIX(*res, k, v) += weight; } if (l != -1) { MATRIX(*res, l, u) += weight; } } } } /* Clean up */ igraph_vector_destroy(&neis); igraph_vector_destroy(&vid_reverse_index); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(3); return 0; } static int igraph_i_neisets_intersect(const igraph_vector_int_t *v1, const igraph_vector_int_t *v2, long int *len_union, long int *len_intersection) { /* ASSERT: v1 and v2 are sorted */ long int i, j, i0, jj0; i0 = igraph_vector_int_size(v1); jj0 = igraph_vector_int_size(v2); *len_union = i0 + jj0; *len_intersection = 0; i = 0; j = 0; while (i < i0 && j < jj0) { if (VECTOR(*v1)[i] == VECTOR(*v2)[j]) { (*len_intersection)++; (*len_union)--; i++; j++; } else if (VECTOR(*v1)[i] < VECTOR(*v2)[j]) { i++; } else { j++; } } return 0; } /** * \ingroup structural * \function igraph_similarity_jaccard * \brief Jaccard similarity coefficient for the given vertices. * * * The Jaccard similarity coefficient of two vertices is the number of common * neighbors divided by the number of vertices that are neighbors of at * least one of the two vertices being considered. This function calculates * the pairwise Jaccard similarities for some (or all) of the vertices. * * \param graph The graph object to analyze * \param res Pointer to a matrix, the result of the calculation will * be stored here. The number of its rows and columns is the same * as the number of vertex ids in \p vids. * \param vids The vertex ids of the vertices for which the * calculation will be done. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing edges will be considered for each node. * \cli IGRAPH_IN * the incoming edges will be considered for each node. * \cli IGRAPH_ALL * the directed graph is considered as an undirected one for the * computation. * \endclist * \param loops Whether to include the vertices themselves in the neighbor * sets. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(|V|^2 d), * |V| is the number of vertices in the vertex iterator given, d is the * (maximum) degree of the vertices in the graph. * * \sa \ref igraph_similarity_dice(), a measure very similar to the Jaccard * coefficient * * \example examples/simple/igraph_similarity.c */ int igraph_similarity_jaccard(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops) { igraph_lazy_adjlist_t al; igraph_vit_t vit, vit2; long int i, j, k; long int len_union, len_intersection; igraph_vector_int_t *v1, *v2; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit2)); IGRAPH_FINALLY(igraph_vit_destroy, &vit2); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &al, mode, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &al); IGRAPH_CHECK(igraph_matrix_resize(res, IGRAPH_VIT_SIZE(vit), IGRAPH_VIT_SIZE(vit))); if (loops) { for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { i = IGRAPH_VIT_GET(vit); v1 = igraph_lazy_adjlist_get(&al, (igraph_integer_t) i); if (!igraph_vector_int_binsearch(v1, i, &k)) { igraph_vector_int_insert(v1, k, i); } } } for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { MATRIX(*res, i, i) = 1.0; for (IGRAPH_VIT_RESET(vit2), j = 0; !IGRAPH_VIT_END(vit2); IGRAPH_VIT_NEXT(vit2), j++) { if (j <= i) { continue; } v1 = igraph_lazy_adjlist_get(&al, IGRAPH_VIT_GET(vit)); v2 = igraph_lazy_adjlist_get(&al, IGRAPH_VIT_GET(vit2)); igraph_i_neisets_intersect(v1, v2, &len_union, &len_intersection); if (len_union > 0) { MATRIX(*res, i, j) = ((igraph_real_t)len_intersection) / len_union; } else { MATRIX(*res, i, j) = 0.0; } MATRIX(*res, j, i) = MATRIX(*res, i, j); } } igraph_lazy_adjlist_destroy(&al); igraph_vit_destroy(&vit); igraph_vit_destroy(&vit2); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \ingroup structural * \function igraph_similarity_jaccard_pairs * \brief Jaccard similarity coefficient for given vertex pairs. * * * The Jaccard similarity coefficient of two vertices is the number of common * neighbors divided by the number of vertices that are neighbors of at * least one of the two vertices being considered. This function calculates * the pairwise Jaccard similarities for a list of vertex pairs. * * \param graph The graph object to analyze * \param res Pointer to a vector, the result of the calculation will * be stored here. The number of elements is the same as the number * of pairs in \p pairs. * \param pairs A vector that contains the pairs for which the similarity * will be calculated. Each pair is defined by two consecutive elements, * i.e. the first and second element of the vector specifies the first * pair, the third and fourth element specifies the second pair and so on. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing edges will be considered for each node. * \cli IGRAPH_IN * the incoming edges will be considered for each node. * \cli IGRAPH_ALL * the directed graph is considered as an undirected one for the * computation. * \endclist * \param loops Whether to include the vertices themselves in the neighbor * sets. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(nd), n is the number of pairs in the given vector, d is * the (maximum) degree of the vertices in the graph. * * \sa \ref igraph_similarity_jaccard() to calculate the Jaccard similarity * between all pairs of a vertex set, or \ref igraph_similarity_dice() and * \ref igraph_similarity_dice_pairs() for a measure very similar to the * Jaccard coefficient * * \example examples/simple/igraph_similarity.c */ int igraph_similarity_jaccard_pairs(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *pairs, igraph_neimode_t mode, igraph_bool_t loops) { igraph_lazy_adjlist_t al; long int i, j, k, u, v; long int len_union, len_intersection; igraph_vector_int_t *v1, *v2; igraph_bool_t *seen; k = igraph_vector_size(pairs); if (k % 2 != 0) { IGRAPH_ERROR("number of elements in `pairs' must be even", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_resize(res, k / 2)); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &al, mode, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &al); if (loops) { /* Add the loop edges */ i = igraph_vcount(graph); seen = IGRAPH_CALLOC(i, igraph_bool_t); if (seen == 0) { IGRAPH_ERROR("cannot calculate Jaccard similarity", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, seen); for (i = 0; i < k; i++) { j = (long int) VECTOR(*pairs)[i]; if (seen[j]) { continue; } seen[j] = 1; v1 = igraph_lazy_adjlist_get(&al, (igraph_integer_t) j); if (!igraph_vector_int_binsearch(v1, j, &u)) { igraph_vector_int_insert(v1, u, j); } } IGRAPH_FREE(seen); IGRAPH_FINALLY_CLEAN(1); } for (i = 0, j = 0; i < k; i += 2, j++) { u = (long int) VECTOR(*pairs)[i]; v = (long int) VECTOR(*pairs)[i + 1]; if (u == v) { VECTOR(*res)[j] = 1.0; continue; } v1 = igraph_lazy_adjlist_get(&al, (igraph_integer_t) u); v2 = igraph_lazy_adjlist_get(&al, (igraph_integer_t) v); igraph_i_neisets_intersect(v1, v2, &len_union, &len_intersection); if (len_union > 0) { VECTOR(*res)[j] = ((igraph_real_t)len_intersection) / len_union; } else { VECTOR(*res)[j] = 0.0; } } igraph_lazy_adjlist_destroy(&al); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup structural * \function igraph_similarity_jaccard_es * \brief Jaccard similarity coefficient for a given edge selector. * * * The Jaccard similarity coefficient of two vertices is the number of common * neighbors divided by the number of vertices that are neighbors of at * least one of the two vertices being considered. This function calculates * the pairwise Jaccard similarities for the endpoints of edges in a given edge * selector. * * \param graph The graph object to analyze * \param res Pointer to a vector, the result of the calculation will * be stored here. The number of elements is the same as the number * of edges in \p es. * \param es An edge selector that specifies the edges to be included in the * result. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing edges will be considered for each node. * \cli IGRAPH_IN * the incoming edges will be considered for each node. * \cli IGRAPH_ALL * the directed graph is considered as an undirected one for the * computation. * \endclist * \param loops Whether to include the vertices themselves in the neighbor * sets. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(nd), n is the number of edges in the edge selector, d is * the (maximum) degree of the vertices in the graph. * * \sa \ref igraph_similarity_jaccard() and \ref igraph_similarity_jaccard_pairs() * to calculate the Jaccard similarity between all pairs of a vertex set or * some selected vertex pairs, or \ref igraph_similarity_dice(), * \ref igraph_similarity_dice_pairs() and \ref igraph_similarity_dice_es() for a * measure very similar to the Jaccard coefficient * * \example examples/simple/igraph_similarity.c */ int igraph_similarity_jaccard_es(const igraph_t *graph, igraph_vector_t *res, const igraph_es_t es, igraph_neimode_t mode, igraph_bool_t loops) { igraph_vector_t v; igraph_eit_t eit; IGRAPH_VECTOR_INIT_FINALLY(&v, 0); IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); while (!IGRAPH_EIT_END(eit)) { long int eid = IGRAPH_EIT_GET(eit); igraph_vector_push_back(&v, IGRAPH_FROM(graph, eid)); igraph_vector_push_back(&v, IGRAPH_TO(graph, eid)); IGRAPH_EIT_NEXT(eit); } igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_similarity_jaccard_pairs(graph, res, &v, mode, loops)); igraph_vector_destroy(&v); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_similarity_dice * \brief Dice similarity coefficient. * * * The Dice similarity coefficient of two vertices is twice the number of common * neighbors divided by the sum of the degrees of the vertices. This function * calculates the pairwise Dice similarities for some (or all) of the vertices. * * \param graph The graph object to analyze * \param res Pointer to a matrix, the result of the calculation will * be stored here. The number of its rows and columns is the same * as the number of vertex ids in \p vids. * \param vids The vertex ids of the vertices for which the * calculation will be done. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing edges will be considered for each node. * \cli IGRAPH_IN * the incoming edges will be considered for each node. * \cli IGRAPH_ALL * the directed graph is considered as an undirected one for the * computation. * \endclist * \param loops Whether to include the vertices themselves as their own * neighbors. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(|V|^2 d), * |V| is the number of vertices in the vertex iterator given, d is the * (maximum) degree of the vertices in the graph. * * \sa \ref igraph_similarity_jaccard(), a measure very similar to the Dice * coefficient * * \example examples/simple/igraph_similarity.c */ int igraph_similarity_dice(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops) { long int i, j, nr, nc; IGRAPH_CHECK(igraph_similarity_jaccard(graph, res, vids, mode, loops)); nr = igraph_matrix_nrow(res); nc = igraph_matrix_ncol(res); for (i = 0; i < nr; i++) { for (j = 0; j < nc; j++) { igraph_real_t x = MATRIX(*res, i, j); MATRIX(*res, i, j) = 2 * x / (1 + x); } } return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_similarity_dice_pairs * \brief Dice similarity coefficient for given vertex pairs. * * * The Dice similarity coefficient of two vertices is twice the number of common * neighbors divided by the sum of the degrees of the vertices. This function * calculates the pairwise Dice similarities for a list of vertex pairs. * * \param graph The graph object to analyze * \param res Pointer to a vector, the result of the calculation will * be stored here. The number of elements is the same as the number * of pairs in \p pairs. * \param pairs A vector that contains the pairs for which the similarity * will be calculated. Each pair is defined by two consecutive elements, * i.e. the first and second element of the vector specifies the first * pair, the third and fourth element specifies the second pair and so on. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing edges will be considered for each node. * \cli IGRAPH_IN * the incoming edges will be considered for each node. * \cli IGRAPH_ALL * the directed graph is considered as an undirected one for the * computation. * \endclist * \param loops Whether to include the vertices themselves as their own * neighbors. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(nd), n is the number of pairs in the given vector, d is * the (maximum) degree of the vertices in the graph. * * \sa \ref igraph_similarity_dice() to calculate the Dice similarity * between all pairs of a vertex set, or \ref igraph_similarity_jaccard(), * \ref igraph_similarity_jaccard_pairs() and \ref igraph_similarity_jaccard_es() * for a measure very similar to the Dice coefficient * * \example examples/simple/igraph_similarity.c */ int igraph_similarity_dice_pairs(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_t *pairs, igraph_neimode_t mode, igraph_bool_t loops) { long int i, n; IGRAPH_CHECK(igraph_similarity_jaccard_pairs(graph, res, pairs, mode, loops)); n = igraph_vector_size(res); for (i = 0; i < n; i++) { igraph_real_t x = VECTOR(*res)[i]; VECTOR(*res)[i] = 2 * x / (1 + x); } return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_similarity_dice_es * \brief Dice similarity coefficient for a given edge selector. * * * The Dice similarity coefficient of two vertices is twice the number of common * neighbors divided by the sum of the degrees of the vertices. This function * calculates the pairwise Dice similarities for the endpoints of edges in a given * edge selector. * * \param graph The graph object to analyze * \param res Pointer to a vector, the result of the calculation will * be stored here. The number of elements is the same as the number * of edges in \p es. * \param es An edge selector that specifies the edges to be included in the * result. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing edges will be considered for each node. * \cli IGRAPH_IN * the incoming edges will be considered for each node. * \cli IGRAPH_ALL * the directed graph is considered as an undirected one for the * computation. * \endclist * \param loops Whether to include the vertices themselves as their own * neighbors. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(nd), n is the number of pairs in the given vector, d is * the (maximum) degree of the vertices in the graph. * * \sa \ref igraph_similarity_dice() and \ref igraph_similarity_dice_pairs() * to calculate the Dice similarity between all pairs of a vertex set or * some selected vertex pairs, or \ref igraph_similarity_jaccard(), * \ref igraph_similarity_jaccard_pairs() and \ref igraph_similarity_jaccard_es() * for a measure very similar to the Dice coefficient * * \example examples/simple/igraph_similarity.c */ int igraph_similarity_dice_es(const igraph_t *graph, igraph_vector_t *res, const igraph_es_t es, igraph_neimode_t mode, igraph_bool_t loops) { long int i, n; IGRAPH_CHECK(igraph_similarity_jaccard_es(graph, res, es, mode, loops)); n = igraph_vector_size(res); for (i = 0; i < n; i++) { igraph_real_t x = VECTOR(*res)[i]; VECTOR(*res)[i] = 2 * x / (1 + x); } return IGRAPH_SUCCESS; } leidenbase/src/core/misc/motifs.c0000644000176200001440000012541114447675375016516 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_motifs.h" #include "igraph_memory.h" #include "igraph_random.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_nongraph.h" #include "igraph_stack.h" #include "core/interruption.h" #include "isomorphism/isoclasses.h" #include "graph/neighbors.h" /** * Callback function for igraph_motifs_randesu that counts the motifs by * isomorphism class in a histogram. */ static igraph_bool_t igraph_i_motifs_randesu_update_hist( const igraph_t *graph, igraph_vector_t *vids, int isoclass, void* extra) { igraph_vector_t *hist = (igraph_vector_t*)extra; IGRAPH_UNUSED(graph); IGRAPH_UNUSED(vids); VECTOR(*hist)[isoclass]++; return 0; } /** * \function igraph_motifs_randesu * \brief Count the number of motifs in a graph. * * * Motifs are small weakly connected induced subgraphs of a given structure in a * graph. It is argued that the motif profile (i.e. the number of * different motifs in the graph) is characteristic for different * types of networks and network function is related to the motifs in * the graph. * * * This function is able to find directed motifs of sizes three * and four and undirected motifs of sizes three to six * (i.e. the number of different subgraphs with three to six * vertices in the network). * * * In a big network the total number of motifs can be very large, so * it takes a lot of time to find all of them, a sampling method can * be used. This function is capable of doing sampling via the * \p cut_prob argument. This argument gives the probability that * a branch of the motif search tree will not be explored. See * S. Wernicke and F. Rasche: FANMOD: a tool for fast network motif * detection, Bioinformatics 22(9), 1152--1153, 2006 for details. * https://doi.org/10.1093/bioinformatics/btl038 * * * Set the \p cut_prob argument to a zero vector for finding all * motifs. * * * Directed motifs will be counted in directed graphs and undirected * motifs in undirected graphs. * * \param graph The graph to find the motifs in. * \param hist The result of the computation, it gives the number of * motifs found for each isomorphism class. See * \ref igraph_isoclass() for help about isomorphism classes. * Note that this function does \em not count isomorphism * classes that are not connected and will report NaN (more * precisely \c IGRAPH_NAN) for them. * \param size The size of the motifs to search for. For directed graphs, * only 3 and 4 are implemented, for undirected, 3 to 6. * The limitation is not in the motif finding code, but the graph * isomorphism code. * \param cut_prob Vector of probabilities for cutting the search tree * at a given level. The first element is the first level, etc. * Supply all zeros here (of length \p size) to find all motifs * in a graph. * \return Error code. * * \sa \ref igraph_motifs_randesu_estimate() for estimating the number * of motifs in a graph, this can help to set the \p cut_prob * parameter; \ref igraph_motifs_randesu_no() to calculate the total * number of motifs of a given size in a graph; * \ref igraph_motifs_randesu_callback() for calling a callback function * for every motif found; \ref igraph_subisomorphic_lad() for finding * subgraphs on more than 4 (directed) or 6 (undirected) vertices. * * Time complexity: TODO. * * \example examples/simple/igraph_motifs_randesu.c */ int igraph_motifs_randesu(const igraph_t *graph, igraph_vector_t *hist, int size, const igraph_vector_t *cut_prob) { igraph_bool_t directed = igraph_is_directed(graph); int histlen; if (directed) { switch (size) { case 3: histlen = 16; break; case 4: histlen = 218; break; default: IGRAPH_ERROR("In directed graphs, only 3 and 4 vertex motifs are supported.", IGRAPH_UNIMPLEMENTED); } } else { switch (size) { case 3: histlen = 4; break; case 4: histlen = 11; break; case 5: histlen = 34; break; case 6: histlen = 156; break; default: IGRAPH_ERROR("In undirected graphs, only 3 to 6 vertex motifs are supported.", IGRAPH_UNIMPLEMENTED); } } if (igraph_vector_size(cut_prob) != size) { IGRAPH_ERRORF("Cut probability vector size (%ld) must agree with motif size (%" IGRAPH_PRId ").", IGRAPH_EINVAL, igraph_vector_size(cut_prob), size); } IGRAPH_CHECK(igraph_vector_resize(hist, histlen)); igraph_vector_null(hist); IGRAPH_CHECK(igraph_motifs_randesu_callback(graph, size, cut_prob, &igraph_i_motifs_randesu_update_hist, hist)); if (size == 3) { if (directed) { VECTOR(*hist)[0] = VECTOR(*hist)[1] = VECTOR(*hist)[3] = IGRAPH_NAN; } else { VECTOR(*hist)[0] = VECTOR(*hist)[1] = IGRAPH_NAN; } } else if (size == 4) { if (directed) { int not_connected[] = { 0, 1, 2, 4, 5, 6, 9, 10, 11, 15, 22, 23, 27, 28, 33, 34, 39, 62, 120 }; int i, n = sizeof(not_connected) / sizeof(int); for (i = 0; i < n; i++) { VECTOR(*hist)[not_connected[i]] = IGRAPH_NAN; } } else { VECTOR(*hist)[0] = VECTOR(*hist)[1] = VECTOR(*hist)[2] = VECTOR(*hist)[3] = VECTOR(*hist)[5] = IGRAPH_NAN; } } else if (size == 5) { /* undirected only */ int not_connected[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 19 }; int i, n = sizeof(not_connected) / sizeof(int); for (i = 0; i < n; i++) { VECTOR(*hist)[not_connected[i]] = IGRAPH_NAN; } } else if (size == 6) { /* undirected only */ int not_connected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 38, 44, 50, 51, 54, 74, 77, 89, 120}; int i, n = sizeof(not_connected) / sizeof(int); for (i = 0; i < n; i++) { VECTOR(*hist)[not_connected[i]] = IGRAPH_NAN; } } return IGRAPH_SUCCESS; } /** * \function igraph_motifs_randesu_callback * \brief Finds motifs in a graph and calls a function for each of them. * * * Similarly to \ref igraph_motifs_randesu(), this function is able to find * directed motifs of sizes three and four and undirected motifs of sizes * three to six (i.e. the number of different subgraphs with three to six * vertices in the network). However, instead of * counting them, the function will call a callback function for each motif * found to allow further tests or post-processing. * * * The \p cut_prob argument also allows sampling the motifs, just like for * \ref igraph_motifs_randesu(). Set the \p cut_prob argument to a zero vector * for finding all motifs. * * \param graph The graph to find the motifs in. * \param size The size of the motifs to search for. Only three and * four are implemented currently. The limitation is not in the * motif finding code, but the graph isomorphism code. * \param cut_prob Vector of probabilities for cutting the search tree * at a given level. The first element is the first level, etc. * Supply all zeros here (of length \c size) to find all motifs * in a graph. * \param callback A pointer to a function of type \ref igraph_motifs_handler_t. * This function will be called whenever a new motif is found. * \param extra Extra argument to pass to the callback function. * \return Error code. * * Time complexity: TODO. * * \example examples/simple/igraph_motifs_randesu.c */ int igraph_motifs_randesu_callback(const igraph_t *graph, int size, const igraph_vector_t *cut_prob, igraph_motifs_handler_t *callback, void* extra) { long int no_of_nodes = igraph_vcount(graph); igraph_adjlist_t allneis, alloutneis; igraph_vector_int_t *neis; long int father; long int i, j, s; long int motifs = 0; IGRAPH_UNUSED(motifs); /* We mark it as unused to prevent warnings about unused-but-set-variables. */ igraph_vector_t vids; /* this is G */ igraph_vector_t adjverts; /* this is V_E */ igraph_stack_t stack; /* this is S */ long int *added; char *subg; const unsigned int *arr_idx, *arr_code; unsigned int code = 0; unsigned int mul, idx; igraph_bool_t terminate = 0; if (igraph_is_directed(graph)) { switch (size) { case 3: arr_idx = igraph_i_isoclass_3_idx; arr_code = igraph_i_isoclass2_3; mul = 3; break; case 4: arr_idx = igraph_i_isoclass_4_idx; arr_code = igraph_i_isoclass2_4; mul = 4; break; default: IGRAPH_ERROR("In directed graphs, only 3 and 4 vertex motifs are supported.", IGRAPH_UNIMPLEMENTED); } } else { switch (size) { case 3: arr_idx = igraph_i_isoclass_3u_idx; arr_code = igraph_i_isoclass2_3u; mul = 3; break; case 4: arr_idx = igraph_i_isoclass_4u_idx; arr_code = igraph_i_isoclass2_4u; mul = 4; break; case 5: arr_idx = igraph_i_isoclass_5u_idx; arr_code = igraph_i_isoclass2_5u; mul = 5; break; case 6: arr_idx = igraph_i_isoclass_6u_idx; arr_code = igraph_i_isoclass2_6u; mul = 6; break; default: IGRAPH_ERROR("In undirected graphs, only 3 to 6 vertex motifs are supported.", IGRAPH_UNIMPLEMENTED); } } if (igraph_vector_size(cut_prob) != size) { IGRAPH_ERRORF("Cut probability vector size (%ld) must agree with motif size (%" IGRAPH_PRId ").", IGRAPH_EINVAL, igraph_vector_size(cut_prob), size); } added = IGRAPH_CALLOC(no_of_nodes, long int); if (added == 0) { IGRAPH_ERROR("Cannot find motifs", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); subg = IGRAPH_CALLOC(no_of_nodes, char); if (subg == 0) { IGRAPH_ERROR("Cannot find motifs", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, subg); IGRAPH_CHECK(igraph_adjlist_init(graph, &allneis, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); IGRAPH_CHECK(igraph_adjlist_init(graph, &alloutneis, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &alloutneis); IGRAPH_VECTOR_INIT_FINALLY(&vids, 0); IGRAPH_VECTOR_INIT_FINALLY(&adjverts, 0); IGRAPH_CHECK(igraph_stack_init(&stack, 0)); IGRAPH_FINALLY(igraph_stack_destroy, &stack); RNG_BEGIN(); for (father = 0; father < no_of_nodes; father++) { long int level; IGRAPH_ALLOW_INTERRUPTION(); if (VECTOR(*cut_prob)[0] == 1 || RNG_UNIF01() < VECTOR(*cut_prob)[0]) { continue; } /* init G */ igraph_vector_clear(&vids); level = 0; IGRAPH_CHECK(igraph_vector_push_back(&vids, father)); subg[father] = 1; added[father] += 1; level += 1; /* init V_E */ igraph_vector_clear(&adjverts); neis = igraph_adjlist_get(&allneis, father); s = igraph_vector_int_size(neis); for (i = 0; i < s; i++) { long int nei = (long int) VECTOR(*neis)[i]; if (!added[nei] && nei > father) { IGRAPH_CHECK(igraph_vector_push_back(&adjverts, nei)); IGRAPH_CHECK(igraph_vector_push_back(&adjverts, father)); } added[nei] += 1; } /* init S */ igraph_stack_clear(&stack); while (level > 1 || !igraph_vector_empty(&adjverts)) { igraph_real_t cp = VECTOR(*cut_prob)[level]; if (level == size - 1) { s = igraph_vector_size(&adjverts) / 2; for (i = 0; i < s; i++) { long int k, s2; long int last; if (cp != 0 && RNG_UNIF01() < cp) { continue; } motifs += 1; last = (long int) VECTOR(adjverts)[2 * i]; IGRAPH_CHECK(igraph_vector_push_back(&vids, last)); subg[last] = (char) size; code = 0; idx = 0; for (k = 0; k < size; k++) { long int from = (long int) VECTOR(vids)[k]; neis = igraph_adjlist_get(&alloutneis, from); s2 = igraph_vector_int_size(neis); for (j = 0; j < s2; j++) { long int nei = (long int) VECTOR(*neis)[j]; if (subg[nei] && k != subg[nei] - 1) { idx = (unsigned char) (mul * k + (subg[nei] - 1)); code |= arr_idx[idx]; } } } if (callback(graph, &vids, (int) arr_code[code], extra)) { terminate = 1; break; } igraph_vector_pop_back(&vids); subg[last] = 0; } } /* did the callback function asked us to terminate the search? */ if (terminate) { break; } /* can we step down? */ if (level < size - 1 && !igraph_vector_empty(&adjverts)) { /* we might step down */ long int neifather = (long int) igraph_vector_pop_back(&adjverts); long int nei = (long int) igraph_vector_pop_back(&adjverts); if (cp == 0 || RNG_UNIF01() > cp) { /* yes, step down */ IGRAPH_CHECK(igraph_vector_push_back(&vids, nei)); subg[nei] = (char) level + 1; added[nei] += 1; level += 1; IGRAPH_CHECK(igraph_stack_push(&stack, neifather)); IGRAPH_CHECK(igraph_stack_push(&stack, nei)); IGRAPH_CHECK(igraph_stack_push(&stack, level)); neis = igraph_adjlist_get(&allneis, nei); s = igraph_vector_int_size(neis); for (i = 0; i < s; i++) { long int nei2 = (long int) VECTOR(*neis)[i]; if (!added[nei2] && nei2 > father) { IGRAPH_CHECK(igraph_vector_push_back(&adjverts, nei2)); IGRAPH_CHECK(igraph_vector_push_back(&adjverts, nei)); } added[nei2] += 1; } } } else { /* no, step back */ long int nei, neifather; while (!igraph_stack_empty(&stack) && level == igraph_stack_top(&stack) - 1) { igraph_stack_pop(&stack); nei = (long int) igraph_stack_pop(&stack); neifather = (long int) igraph_stack_pop(&stack); igraph_vector_push_back(&adjverts, nei); igraph_vector_push_back(&adjverts, neifather); } nei = (long int) igraph_vector_pop_back(&vids); subg[nei] = 0; added[nei] -= 1; level -= 1; neis = igraph_adjlist_get(&allneis, nei); s = igraph_vector_int_size(neis); for (i = 0; i < s; i++) { added[ (long int) VECTOR(*neis)[i] ] -= 1; } while (!igraph_vector_empty(&adjverts) && igraph_vector_tail(&adjverts) == nei) { igraph_vector_pop_back(&adjverts); igraph_vector_pop_back(&adjverts); } } } /* while */ /* did the callback function asked us to terminate the search? */ if (terminate) { break; } /* clear the added vector */ added[father] -= 1; subg[father] = 0; neis = igraph_adjlist_get(&allneis, father); s = igraph_vector_int_size(neis); for (i = 0; i < s; i++) { added[ (long int) VECTOR(*neis)[i] ] -= 1; } } /* for father */ RNG_END(); IGRAPH_FREE(added); IGRAPH_FREE(subg); igraph_vector_destroy(&vids); igraph_vector_destroy(&adjverts); igraph_adjlist_destroy(&alloutneis); igraph_adjlist_destroy(&allneis); igraph_stack_destroy(&stack); IGRAPH_FINALLY_CLEAN(7); return IGRAPH_SUCCESS; } /** * \function igraph_motifs_randesu_estimate * \brief Estimate the total number of motifs in a graph. * * This function estimates the total number of weakly connected induced * subgraphs, called motifs, of a fixed number of vertices. For * example, an undirected complete graph on \c n vertices * will have one motif of size \c n, and \c n motifs * of \p size n - 1. As another example, one triangle * and a separate vertex will have zero motifs of size four. * * * This function is useful for large graphs for which it is not * feasible to count all the different motifs, because there are very * many of them. * * * The total number of motifs is estimated by taking a sample of * vertices and counts all motifs in which these vertices are * included. (There is also a \p cut_prob parameter which gives the * probabilities to cut a branch of the search tree.) * * * Directed motifs will be counted in directed graphs and undirected * motifs in undirected graphs. * * \param graph The graph object to study. * \param est Pointer to an integer type, the result will be stored * here. * \param size The size of the motifs to look for. * \param cut_prob Vector giving the probabilities to cut a branch of * the search tree and omit counting the motifs in that branch. * It contains a probability for each level. Supply \p size * zeros here to count all the motifs in the sample. * \param sample_size The number of vertices to use as the * sample. This parameter is only used if the \p parsample * argument is a null pointer. * \param parsample Either pointer to an initialized vector or a null * pointer. If a vector then the vertex ids in the vector are * used as a sample. If a null pointer then the \p sample_size * argument is used to create a sample of vertices drawn with * uniform probability. * \return Error code. * \sa \ref igraph_motifs_randesu(), \ref igraph_motifs_randesu_no(). * * Time complexity: TODO. */ int igraph_motifs_randesu_estimate(const igraph_t *graph, igraph_integer_t *est, int size, const igraph_vector_t *cut_prob, igraph_integer_t sample_size, const igraph_vector_t *parsample) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t neis; igraph_vector_t vids; /* this is G */ igraph_vector_t adjverts; /* this is V_E */ igraph_stack_t stack; /* this is S */ long int *added; igraph_vector_t *sample; long int sam; long int i; if (size < 3) { IGRAPH_ERRORF("Motif size must be at least 3, received %" IGRAPH_PRId ".", IGRAPH_EINVAL, (igraph_integer_t) size); } if (igraph_vector_size(cut_prob) != size) { IGRAPH_ERRORF("Cut probability vector size (%ld) must agree with motif size (%" IGRAPH_PRId ").", IGRAPH_EINVAL, igraph_vector_size(cut_prob), size); } if (parsample && igraph_vector_size(parsample) != 0) { igraph_real_t min, max; igraph_vector_minmax(parsample, &min, &max); if (min < 0 || max >= no_of_nodes) { IGRAPH_ERROR("Sample vertex id out of range.", IGRAPH_EINVAL); } } if (no_of_nodes == 0) { *est = 0; return IGRAPH_SUCCESS; } added = IGRAPH_CALLOC(no_of_nodes, long int); if (added == 0) { IGRAPH_ERROR("Cannot find motifs.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); IGRAPH_VECTOR_INIT_FINALLY(&vids, 0); IGRAPH_VECTOR_INIT_FINALLY(&adjverts, 0); IGRAPH_CHECK(igraph_stack_init(&stack, 0)); IGRAPH_FINALLY(igraph_stack_destroy, &stack); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); if (parsample == NULL) { sample = IGRAPH_CALLOC(1, igraph_vector_t); if (sample == NULL) { IGRAPH_ERROR("Cannot estimate motifs.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, sample); IGRAPH_VECTOR_INIT_FINALLY(sample, 0); IGRAPH_CHECK(igraph_random_sample(sample, 0, no_of_nodes - 1, sample_size)); } else { sample = (igraph_vector_t*)parsample; sample_size = (igraph_integer_t) igraph_vector_size(sample); } *est = 0; RNG_BEGIN(); for (sam = 0; sam < sample_size; sam++) { long int father = (long int) VECTOR(*sample)[sam]; long int level, s; IGRAPH_ALLOW_INTERRUPTION(); if (VECTOR(*cut_prob)[0] == 1 || RNG_UNIF01() < VECTOR(*cut_prob)[0]) { continue; } /* init G */ igraph_vector_clear(&vids); level = 0; IGRAPH_CHECK(igraph_vector_push_back(&vids, father)); added[father] += 1; level += 1; /* init V_E */ igraph_vector_clear(&adjverts); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) father, IGRAPH_ALL)); s = igraph_vector_size(&neis); for (i = 0; i < s; i++) { long int nei = (long int) VECTOR(neis)[i]; if (!added[nei] && nei > father) { IGRAPH_CHECK(igraph_vector_push_back(&adjverts, nei)); IGRAPH_CHECK(igraph_vector_push_back(&adjverts, father)); } added[nei] += 1; } /* init S */ igraph_stack_clear(&stack); while (level > 1 || !igraph_vector_empty(&adjverts)) { igraph_real_t cp = VECTOR(*cut_prob)[level]; if (level == size - 1) { s = igraph_vector_size(&adjverts) / 2; for (i = 0; i < s; i++) { if (cp != 0 && RNG_UNIF01() < cp) { continue; } (*est) += 1; } } if (level < size - 1 && !igraph_vector_empty(&adjverts)) { /* We might step down */ long int neifather = (long int) igraph_vector_pop_back(&adjverts); long int nei = (long int) igraph_vector_pop_back(&adjverts); if (cp == 0 || RNG_UNIF01() > cp) { /* Yes, step down */ IGRAPH_CHECK(igraph_vector_push_back(&vids, nei)); added[nei] += 1; level += 1; IGRAPH_CHECK(igraph_stack_push(&stack, neifather)); IGRAPH_CHECK(igraph_stack_push(&stack, nei)); IGRAPH_CHECK(igraph_stack_push(&stack, level)); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) nei, IGRAPH_ALL)); s = igraph_vector_size(&neis); for (i = 0; i < s; i++) { long int nei2 = (long int) VECTOR(neis)[i]; if (!added[nei2] && nei2 > father) { IGRAPH_CHECK(igraph_vector_push_back(&adjverts, nei2)); IGRAPH_CHECK(igraph_vector_push_back(&adjverts, nei)); } added[nei2] += 1; } } } else { /* no, step back */ long int nei, neifather; while (!igraph_stack_empty(&stack) && level == igraph_stack_top(&stack) - 1) { igraph_stack_pop(&stack); nei = (long int) igraph_stack_pop(&stack); neifather = (long int) igraph_stack_pop(&stack); igraph_vector_push_back(&adjverts, nei); igraph_vector_push_back(&adjverts, neifather); } nei = (long int) igraph_vector_pop_back(&vids); added[nei] -= 1; level -= 1; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) nei, IGRAPH_ALL)); s = igraph_vector_size(&neis); for (i = 0; i < s; i++) { added[ (long int) VECTOR(neis)[i] ] -= 1; } while (!igraph_vector_empty(&adjverts) && igraph_vector_tail(&adjverts) == nei) { igraph_vector_pop_back(&adjverts); igraph_vector_pop_back(&adjverts); } } } /* while */ /* clear the added vector */ added[father] -= 1; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) father, IGRAPH_ALL)); s = igraph_vector_size(&neis); for (i = 0; i < s; i++) { added[ (long int) VECTOR(neis)[i] ] -= 1; } } /* for father */ RNG_END(); (*est) *= ((double)no_of_nodes / sample_size); if (parsample == 0) { igraph_vector_destroy(sample); IGRAPH_FREE(sample); IGRAPH_FINALLY_CLEAN(2); } IGRAPH_FREE(added); igraph_vector_destroy(&vids); igraph_vector_destroy(&adjverts); igraph_stack_destroy(&stack); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \function igraph_motifs_randesu_no * \brief Count the total number of motifs in a graph. * * * This function counts the total number of motifs in a graph, * i.e. the number of of (weakly) connected triplets or quadruplets, * without assigning isomorphism classes to them. * * \param graph The graph object to study. * \param no Pointer to an integer type, the result will be stored * here. * \param size The size of the motifs to count. * \param cut_prob Vector giving the probabilities that a branch of * the search tree will be cut at a given level. * \return Error code. * \sa \ref igraph_motifs_randesu(), \ref * igraph_motifs_randesu_estimate(). * * Time complexity: TODO. */ int igraph_motifs_randesu_no(const igraph_t *graph, igraph_integer_t *no, int size, const igraph_vector_t *cut_prob) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t neis; igraph_vector_t vids; /* this is G */ igraph_vector_t adjverts; /* this is V_E */ igraph_stack_t stack; /* this is S */ long int *added; long int father; long int i; if (size < 3) { IGRAPH_ERRORF("Motif size must be at least 3, received %" IGRAPH_PRId ".", IGRAPH_EINVAL, (igraph_integer_t) size); } if (igraph_vector_size(cut_prob) != size) { IGRAPH_ERRORF("Cut probability vector size (%ld) must agree with motif size (%" IGRAPH_PRId ").", IGRAPH_EINVAL, igraph_vector_size(cut_prob), size); } added = IGRAPH_CALLOC(no_of_nodes, long int); if (added == 0) { IGRAPH_ERROR("Cannot find motifs.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); IGRAPH_VECTOR_INIT_FINALLY(&vids, 0); IGRAPH_VECTOR_INIT_FINALLY(&adjverts, 0); IGRAPH_CHECK(igraph_stack_init(&stack, 0)); IGRAPH_FINALLY(igraph_stack_destroy, &stack); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); *no = 0; RNG_BEGIN(); for (father = 0; father < no_of_nodes; father++) { long int level, s; IGRAPH_ALLOW_INTERRUPTION(); if (VECTOR(*cut_prob)[0] == 1 || RNG_UNIF01() < VECTOR(*cut_prob)[0]) { continue; } /* init G */ igraph_vector_clear(&vids); level = 0; IGRAPH_CHECK(igraph_vector_push_back(&vids, father)); added[father] += 1; level += 1; /* init V_E */ igraph_vector_clear(&adjverts); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) father, IGRAPH_ALL)); s = igraph_vector_size(&neis); for (i = 0; i < s; i++) { long int nei = (long int) VECTOR(neis)[i]; if (!added[nei] && nei > father) { IGRAPH_CHECK(igraph_vector_push_back(&adjverts, nei)); IGRAPH_CHECK(igraph_vector_push_back(&adjverts, father)); } added[nei] += 1; } /* init S */ igraph_stack_clear(&stack); while (level > 1 || !igraph_vector_empty(&adjverts)) { igraph_real_t cp = VECTOR(*cut_prob)[level]; if (level == size - 1) { s = igraph_vector_size(&adjverts) / 2; for (i = 0; i < s; i++) { if (cp != 0 && RNG_UNIF01() < cp) { continue; } (*no) += 1; } } if (level < size - 1 && !igraph_vector_empty(&adjverts)) { /* We might step down */ long int neifather = (long int) igraph_vector_pop_back(&adjverts); long int nei = (long int) igraph_vector_pop_back(&adjverts); if (cp == 0 || RNG_UNIF01() > cp) { /* Yes, step down */ IGRAPH_CHECK(igraph_vector_push_back(&vids, nei)); added[nei] += 1; level += 1; IGRAPH_CHECK(igraph_stack_push(&stack, neifather)); IGRAPH_CHECK(igraph_stack_push(&stack, nei)); IGRAPH_CHECK(igraph_stack_push(&stack, level)); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) nei, IGRAPH_ALL)); s = igraph_vector_size(&neis); for (i = 0; i < s; i++) { long int nei2 = (long int) VECTOR(neis)[i]; if (!added[nei2] && nei2 > father) { IGRAPH_CHECK(igraph_vector_push_back(&adjverts, nei2)); IGRAPH_CHECK(igraph_vector_push_back(&adjverts, nei)); } added[nei2] += 1; } } } else { /* no, step back */ long int nei, neifather; while (!igraph_stack_empty(&stack) && level == igraph_stack_top(&stack) - 1) { igraph_stack_pop(&stack); nei = (long int) igraph_stack_pop(&stack); neifather = (long int) igraph_stack_pop(&stack); igraph_vector_push_back(&adjverts, nei); igraph_vector_push_back(&adjverts, neifather); } nei = (long int) igraph_vector_pop_back(&vids); added[nei] -= 1; level -= 1; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) nei, IGRAPH_ALL)); s = igraph_vector_size(&neis); for (i = 0; i < s; i++) { added[ (long int) VECTOR(neis)[i] ] -= 1; } while (!igraph_vector_empty(&adjverts) && igraph_vector_tail(&adjverts) == nei) { igraph_vector_pop_back(&adjverts); igraph_vector_pop_back(&adjverts); } } } /* while */ /* clear the added vector */ added[father] -= 1; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) father, IGRAPH_ALL)); s = igraph_vector_size(&neis); for (i = 0; i < s; i++) { added[ (long int) VECTOR(neis)[i] ] -= 1; } } /* for father */ RNG_END(); IGRAPH_FREE(added); igraph_vector_destroy(&vids); igraph_vector_destroy(&adjverts); igraph_stack_destroy(&stack); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; } /** * \function igraph_dyad_census * \brief Calculating the dyad census as defined by Holland and Leinhardt. * * * Dyad census means classifying each pair of vertices of a directed * graph into three categories: mutual (there is at least one edge from * \c a to \c b and also from \c b to \c a); asymmetric (there is at least * one edge either from \c a to \c b or from \c b to \c a, but not the other * way) and null (no edges between \c a and \c b in either direction). * * * Holland, P.W. and Leinhardt, S. (1970). A Method for Detecting * Structure in Sociometric Data. American Journal of Sociology, * 70, 492-513. * * \param graph The input graph. For an undirected graph, there are no * asymmetric connections. * \param mut Pointer to an integer, the number of mutual dyads is * stored here. * \param asym Pointer to an integer, the number of asymmetric dyads * is stored here. * \param null Pointer to an integer, the number of null dyads is * stored here. In case of an integer overflow (i.e. too many * null dyads), -1 will be returned. * \return Error code. * * \sa \ref igraph_reciprocity(), \ref igraph_triad_census(). * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges. */ int igraph_dyad_census(const igraph_t *graph, igraph_integer_t *mut, igraph_integer_t *asym, igraph_integer_t *null) { igraph_integer_t nonrec = 0, rec = 0; igraph_vector_t inneis, outneis; igraph_integer_t vc = igraph_vcount(graph); long int i; IGRAPH_VECTOR_INIT_FINALLY(&inneis, 0); IGRAPH_VECTOR_INIT_FINALLY(&outneis, 0); for (i = 0; i < vc; i++) { long int ideg, odeg; long int ip, op; IGRAPH_CHECK(igraph_i_neighbors(graph, &inneis, i, IGRAPH_IN, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_CHECK(igraph_i_neighbors(graph, &outneis, i, IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); ideg = igraph_vector_size(&inneis); odeg = igraph_vector_size(&outneis); ip = op = 0; while (ip < ideg && op < odeg) { if (VECTOR(inneis)[ip] < VECTOR(outneis)[op]) { nonrec += 1; ip++; } else if (VECTOR(inneis)[ip] > VECTOR(outneis)[op]) { nonrec += 1; op++; } else { rec += 1; ip++; op++; } } nonrec += (ideg - ip) + (odeg - op); } igraph_vector_destroy(&inneis); igraph_vector_destroy(&outneis); IGRAPH_FINALLY_CLEAN(2); *mut = rec / 2; *asym = nonrec / 2; if (vc % 2) { *null = vc * ((vc - 1) / 2); } else { *null = (vc / 2) * (vc - 1); } if (*null < vc && vc > 2) { IGRAPH_WARNING("Integer overflow, returning -1."); *null = -1; } else { *null = *null - (*mut) - (*asym); } return IGRAPH_SUCCESS; } /** * \function igraph_triad_census_24 * TODO */ int igraph_triad_census_24(const igraph_t *graph, igraph_real_t *res2, igraph_real_t *res4) { long int vc = igraph_vcount(graph); igraph_vector_long_t seen; igraph_vector_int_t *neis, *neis2; long int i, j, k, s, neilen, neilen2, ign; igraph_adjlist_t adjlist; IGRAPH_CHECK(igraph_vector_long_init(&seen, vc)); IGRAPH_FINALLY(igraph_vector_long_destroy, &seen); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); *res2 = *res4 = 0; for (i = 0; i < vc; i++) { IGRAPH_ALLOW_INTERRUPTION(); neis = igraph_adjlist_get(&adjlist, i); neilen = igraph_vector_int_size(neis); /* mark neighbors of i & i itself */ VECTOR(seen)[i] = i + 1; ign = 0; for (j = 0; j < neilen; j++) { long int nei = (long int) VECTOR(*neis)[j]; if (VECTOR(seen)[nei] == i + 1 || VECTOR(seen)[nei] == -(i + 1)) { /* multiple edges or loop edge */ VECTOR(seen)[nei] = -(i + 1); ign++; } else { VECTOR(seen)[nei] = i + 1; } } for (j = 0; j < neilen; j++) { long int nei = (long int) VECTOR(*neis)[j]; if (nei <= i || (j > 0 && nei == VECTOR(*neis)[j - 1])) { continue; } neis2 = igraph_adjlist_get(&adjlist, nei); neilen2 = igraph_vector_int_size(neis2); s = 0; for (k = 0; k < neilen2; k++) { long int nei2 = (long int) VECTOR(*neis2)[k]; if (k > 0 && nei2 == VECTOR(*neis2)[k - 1]) { continue; } if (VECTOR(seen)[nei2] != i + 1 && VECTOR(seen)[nei2] != -(i + 1)) { s++; } } if (VECTOR(seen)[nei] > 0) { *res2 += vc - s - neilen + ign - 1; } else { *res4 += vc - s - neilen + ign - 1; } } } igraph_adjlist_destroy(&adjlist); igraph_vector_long_destroy(&seen); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_triad_census * \brief Triad census, as defined by Davis and Leinhardt * * * Calculating the triad census means classifying every triple of * vertices in a directed graph. A triple can be in one of 16 states: * \clist * \cli 003 * A, B, C, the empty graph. * \cli 012 * A->B, C, a graph with a single directed edge. * \cli 102 * A<->B, C, a graph with a mutual connection between two vertices. * \cli 021D * A<-B->C, the binary out-tree. * \cli 021U * A->B<-C, the binary in-tree. * \cli 021C * A->B->C, the directed line. * \cli 111D * A<->B<-C. * \cli 111U * A<->B->C. * \cli 030T * A->B<-C, A->C. * \cli 030C * A<-B<-C, A->C. * \cli 201 * A<->B<->C. * \cli 120D * A<-B->C, A<->C. * \cli 120U * A->B<-C, A<->C. * \cli 120C * A->B->C, A<->C. * \cli 210 * A->B<->C, A<->C. * \cli 300 * A<->B<->C, A<->C, the complete graph. * \endclist * * * See also Davis, J.A. and Leinhardt, S. (1972). The Structure of * Positive Interpersonal Relations in Small Groups. In J. Berger * (Ed.), Sociological Theories in Progress, Volume 2, 218-251. * Boston: Houghton Mifflin. * * * This function calls \ref igraph_motifs_randesu() which is an * implementation of the FANMOD motif finder tool, see \ref * igraph_motifs_randesu() for details. Note that the order of the * triads is not the same for \ref igraph_triad_census() and \ref * igraph_motifs_randesu(). * * \param graph The input graph. A warning is given for undirected * graphs, as the result is undefined for those. * \param res Pointer to an initialized vector, the result is stored * here in the same order as given in the list above. Note that this * order is different than the one used by \ref igraph_motifs_randesu(). * \return Error code. * * \sa \ref igraph_motifs_randesu(), \ref igraph_dyad_census(). * * Time complexity: TODO. */ int igraph_triad_census(const igraph_t *graph, igraph_vector_t *res) { igraph_vector_t cut_prob; igraph_real_t m2, m4; igraph_vector_t tmp; igraph_integer_t vc = igraph_vcount(graph); igraph_real_t total; if (!igraph_is_directed(graph)) { IGRAPH_WARNING("Triad census called on an undirected graph"); } IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_VECTOR_INIT_FINALLY(&cut_prob, 3); /* all zeros */ IGRAPH_CHECK(igraph_vector_resize(res, 16)); igraph_vector_null(res); IGRAPH_CHECK(igraph_motifs_randesu(graph, &tmp, 3, &cut_prob)); IGRAPH_CHECK(igraph_triad_census_24(graph, &m2, &m4)); total = ((igraph_real_t)vc) * (vc - 1); total *= (vc - 2); total /= 6; /* Reorder */ if (igraph_is_directed(graph)) { VECTOR(tmp)[0] = 0; VECTOR(tmp)[1] = m2; VECTOR(tmp)[3] = m4; VECTOR(tmp)[0] = total - igraph_vector_sum(&tmp); VECTOR(*res)[0] = VECTOR(tmp)[0]; VECTOR(*res)[1] = VECTOR(tmp)[1]; VECTOR(*res)[2] = VECTOR(tmp)[3]; VECTOR(*res)[3] = VECTOR(tmp)[6]; VECTOR(*res)[4] = VECTOR(tmp)[2]; VECTOR(*res)[5] = VECTOR(tmp)[4]; VECTOR(*res)[6] = VECTOR(tmp)[5]; VECTOR(*res)[7] = VECTOR(tmp)[9]; VECTOR(*res)[8] = VECTOR(tmp)[7]; VECTOR(*res)[9] = VECTOR(tmp)[11]; VECTOR(*res)[10] = VECTOR(tmp)[10]; VECTOR(*res)[11] = VECTOR(tmp)[8]; VECTOR(*res)[12] = VECTOR(tmp)[13]; VECTOR(*res)[13] = VECTOR(tmp)[12]; VECTOR(*res)[14] = VECTOR(tmp)[14]; VECTOR(*res)[15] = VECTOR(tmp)[15]; } else { VECTOR(tmp)[0] = 0; VECTOR(tmp)[1] = m2; VECTOR(tmp)[0] = total - igraph_vector_sum(&tmp); VECTOR(*res)[0] = VECTOR(tmp)[0]; VECTOR(*res)[2] = VECTOR(tmp)[1]; VECTOR(*res)[10] = VECTOR(tmp)[2]; VECTOR(*res)[15] = VECTOR(tmp)[3]; } igraph_vector_destroy(&cut_prob); igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(2); return 0; } leidenbase/src/core/misc/chordality.c0000644000176200001440000003746614447675375017373 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2008-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_structural.h" #include "igraph_error.h" #include "igraph_adjlist.h" #include "igraph_interface.h" /** * \function igraph_maximum_cardinality_search * \brief Maximum cardinality search. * * This function implements the maximum cardinality search algorithm. * It computes a rank \p alpha for each vertex, such that visiting * vertices in decreasing rank order corresponds to always choosing * the vertex with the most already visited neighbors as the next one * to visit. * * * Maximum cardinality search is useful in deciding the chordality * of a graph. A graph is chordal if and only if any two neighbors * of a vertex which are higher in rank than it are connected to * each other. * * * References: * * * Robert E Tarjan and Mihalis Yannakakis: Simple linear-time * algorithms to test chordality of graphs, test acyclicity of * hypergraphs, and selectively reduce acyclic hypergraphs. * SIAM Journal of Computation 13, 566--579, 1984. * https://doi.org/10.1137/0213035 * * \param graph The input graph. Edge directions will be ignored. * \param alpha Pointer to an initialized vector, the result is stored here. * It will be resized, as needed. Upon return it contains * the rank of the each vertex in the range 0 to n - 1, * where \c n is the number of vertices. * \param alpham1 Pointer to an initialized vector or a \c NULL * pointer. If not \c NULL, then the inverse of \p alpha is stored * here. In other words, the elements of \p alpham1 are vertex IDs * in reverse maximum cardinality search order. * \return Error code. * * Time complexity: O(|V|+|E|), linear in terms of the number of * vertices and edges. * * \sa \ref igraph_is_chordal(). */ int igraph_maximum_cardinality_search(const igraph_t *graph, igraph_vector_t *alpha, igraph_vector_t *alpham1) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_long_t size; igraph_vector_long_t head, next, prev; /* doubly linked list with head */ long int i; igraph_adjlist_t adjlist; /***************/ /* local j, v; */ /***************/ long int j, v; if (no_of_nodes == 0) { igraph_vector_clear(alpha); if (alpham1) { igraph_vector_clear(alpham1); } return IGRAPH_SUCCESS; } IGRAPH_CHECK(igraph_vector_long_init(&size, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &size); IGRAPH_CHECK(igraph_vector_long_init(&head, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &head); IGRAPH_CHECK(igraph_vector_long_init(&next, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &next); IGRAPH_CHECK(igraph_vector_long_init(&prev, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &prev); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_vector_resize(alpha, no_of_nodes)); if (alpham1) { IGRAPH_CHECK(igraph_vector_resize(alpham1, no_of_nodes)); } /***********************************************/ /* for i in [0,n-1] -> set(i) := emptyset rof; */ /***********************************************/ /* nothing to do, 'head' contains all zeros */ /*********************************************************/ /* for v in vertices -> size(v):=0; add v to set(0) rof; */ /*********************************************************/ VECTOR(head)[0] = 1; for (v = 0; v < no_of_nodes; v++) { VECTOR(next)[v] = v + 2; VECTOR(prev)[v] = v; } VECTOR(next)[no_of_nodes - 1] = 0; /* size is already all zero */ /***************/ /* i:=n; j:=0; */ /***************/ i = no_of_nodes; j = 0; /**************/ /* do i>=1 -> */ /**************/ while (i >= 1) { long int x, k, len; igraph_vector_int_t *neis; /********************************/ /* v := delete any from set(j) */ /********************************/ v = VECTOR(head)[j] - 1; x = VECTOR(next)[v]; VECTOR(head)[j] = x; if (x != 0) { VECTOR(prev)[x - 1] = 0; } /*************************************************/ /* alpha(v) := i; alpham1(i) := v; size(v) := -1 */ /*************************************************/ VECTOR(*alpha)[v] = i - 1; if (alpham1) { VECTOR(*alpham1)[i - 1] = v; } VECTOR(size)[v] = -1; /********************************************/ /* for {v,w} in E such that size(w) >= 0 -> */ /********************************************/ neis = igraph_adjlist_get(&adjlist, v); len = igraph_vector_int_size(neis); for (k = 0; k < len; k++) { long int w = (long int) VECTOR(*neis)[k]; long int ws = VECTOR(size)[w]; if (ws >= 0) { /******************************/ /* delete w from set(size(w)) */ /******************************/ long int nw = VECTOR(next)[w]; long int pw = VECTOR(prev)[w]; if (nw != 0) { VECTOR(prev)[nw - 1] = pw; } if (pw != 0) { VECTOR(next)[pw - 1] = nw; } else { VECTOR(head)[ws] = nw; } /******************************/ /* size(w) := size(w)+1 */ /******************************/ VECTOR(size)[w] += 1; /******************************/ /* add w to set(size(w)) */ /******************************/ ws = VECTOR(size)[w]; nw = VECTOR(head)[ws]; VECTOR(next)[w] = nw; VECTOR(prev)[w] = 0; if (nw != 0) { VECTOR(prev)[nw - 1] = w + 1; } VECTOR(head)[ws] = w + 1; } } /***********************/ /* i := i-1; j := j+1; */ /***********************/ i -= 1; j += 1; /*********************************************/ /* do j>=0 and set(j)=emptyset -> j:=j-1; od */ /*********************************************/ if (j < no_of_nodes) { while (j >= 0 && VECTOR(head)[j] == 0) { j--; } } } igraph_adjlist_destroy(&adjlist); igraph_vector_long_destroy(&prev); igraph_vector_long_destroy(&next); igraph_vector_long_destroy(&head); igraph_vector_long_destroy(&size); IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; } /** * \function igraph_is_chordal * \brief Decides whether a graph is chordal. * * A graph is chordal if each of its cycles of four or more nodes * has a chord, i.e. an edge joining two nodes that are not * adjacent in the cycle. An equivalent definition is that any * chordless cycles have at most three nodes. * * If either \p alpha or \p alpham1 is given, then the other is * calculated by taking simply the inverse. If neither are given, * then \ref igraph_maximum_cardinality_search() is called to calculate * them. * * \param graph The input graph. Edge directions will be ignored. * \param alpha Either an alpha vector coming from * \ref igraph_maximum_cardinality_search() (on the same graph), or a * \c NULL pointer. * \param alpham1 Either an inverse alpha vector coming from \ref * igraph_maximum_cardinality_search() (on the same graph) or a \c NULL * pointer. * \param chordal Pointer to a boolean. If not NULL the result is stored here. * \param fill_in Pointer to an initialized vector, or a \c NULL * pointer. If not a \c NULL pointer, then the fill-in, also called the * chordal completion of the graph is stored here. * The chordal completion is a set of edges that are needed to * make the graph chordal. The vector is resized as needed. * Note that the chordal completion returned by this function may not * be minimal, i.e. some of the returned fill-in edges may not be needed * to make the graph chordal. * \param newgraph Pointer to an uninitialized graph, or a \c NULL * pointer. If not a null pointer, then a new triangulated graph is * created here. This essentially means adding the fill-in edges to * the original graph. * \return Error code. * * Time complexity: O(n). * * \sa \ref igraph_maximum_cardinality_search(). */ int igraph_is_chordal(const igraph_t *graph, const igraph_vector_t *alpha, const igraph_vector_t *alpham1, igraph_bool_t *chordal, igraph_vector_t *fill_in, igraph_t *newgraph) { long int no_of_nodes = igraph_vcount(graph); const igraph_vector_t *my_alpha = alpha, *my_alpham1 = alpham1; igraph_vector_t v_alpha, v_alpham1; igraph_vector_long_t f, index; long int i; igraph_adjlist_t adjlist; igraph_vector_long_t mark; igraph_bool_t calc_edges = fill_in || newgraph; igraph_vector_t *my_fill_in = fill_in, v_fill_in; /*****************/ /* local v, w, x */ /*****************/ long int v, w, x; if (alpha && (igraph_vector_size(alpha) != no_of_nodes)) { IGRAPH_ERRORF("Alpha vector size (%ld) not equal to number of nodes (%ld).", IGRAPH_EINVAL, igraph_vector_size(alpha), no_of_nodes); } if (alpham1 && (igraph_vector_size(alpham1) != no_of_nodes)) { IGRAPH_ERRORF("Inverse alpha vector size (%ld) not equal to number of nodes (%ld).", IGRAPH_EINVAL, igraph_vector_size(alpham1), no_of_nodes); } if (!chordal && !calc_edges) { /* Nothing to calculate */ return IGRAPH_SUCCESS; } if (!alpha && !alpham1) { IGRAPH_VECTOR_INIT_FINALLY(&v_alpha, no_of_nodes); my_alpha = &v_alpha; IGRAPH_VECTOR_INIT_FINALLY(&v_alpham1, no_of_nodes); my_alpham1 = &v_alpham1; IGRAPH_CHECK(igraph_maximum_cardinality_search(graph, (igraph_vector_t*) my_alpha, (igraph_vector_t*) my_alpham1)); } else if (alpha && !alpham1) { long int v; IGRAPH_VECTOR_INIT_FINALLY(&v_alpham1, no_of_nodes); my_alpham1 = &v_alpham1; for (v = 0; v < no_of_nodes; v++) { long int i = (long int) VECTOR(*my_alpha)[v]; VECTOR(*my_alpham1)[i] = v; } } else if (!alpha && alpham1) { long int i; IGRAPH_VECTOR_INIT_FINALLY(&v_alpha, no_of_nodes); my_alpha = &v_alpha; for (i = 0; i < no_of_nodes; i++) { long int v = (long int) VECTOR(*my_alpham1)[i]; VECTOR(*my_alpha)[v] = i; } } if (!fill_in && newgraph) { IGRAPH_VECTOR_INIT_FINALLY(&v_fill_in, 0); my_fill_in = &v_fill_in; } IGRAPH_CHECK(igraph_vector_long_init(&f, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &f); IGRAPH_CHECK(igraph_vector_long_init(&index, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &index); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_vector_long_init(&mark, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &mark); if (my_fill_in) { igraph_vector_clear(my_fill_in); } if (chordal) { *chordal = 1; } /*********************/ /* for i in [1,n] -> */ /*********************/ for (i = 0; i < no_of_nodes; i++) { igraph_vector_int_t *neis; long int j, len; /**********************************************/ /* w := alpham1(i); f(w) := w; index(w) := i; */ /**********************************************/ w = (long int) VECTOR(*my_alpham1)[i]; VECTOR(f)[w] = w; VECTOR(index)[w] = i; /******************************************/ /* for {v,w} in E such that alpha(v) */ /******************************************/ neis = igraph_adjlist_get(&adjlist, w); len = igraph_vector_int_size(neis); for (j = 0; j < len; j++) { v = (long int) VECTOR(*neis)[j]; VECTOR(mark)[v] = w + 1; } for (j = 0; j < len; j++) { v = (long int) VECTOR(*neis)[j]; if (VECTOR(*my_alpha)[v] >= i) { continue; } /**********/ /* x := v */ /**********/ x = v; /********************/ /* do index(x) */ /********************/ while (VECTOR(index)[x] < i) { /******************/ /* index(x) := i; */ /******************/ VECTOR(index)[x] = i; /**********************************/ /* add {x,w} to E union F(alpha); */ /**********************************/ if (VECTOR(mark)[x] != w + 1) { if (chordal) { *chordal = 0; } if (my_fill_in) { IGRAPH_CHECK(igraph_vector_push_back(my_fill_in, x)); IGRAPH_CHECK(igraph_vector_push_back(my_fill_in, w)); } if (!calc_edges) { /* make sure that we exit from all loops */ i = no_of_nodes; j = len; break; } } /*************/ /* x := f(x) */ /*************/ x = VECTOR(f)[x]; } /* while (VECTOR(index)[x] < i) */ /*****************************/ /* if (f(x)=x -> f(x):=w; fi */ /*****************************/ if (VECTOR(f)[x] == x) { VECTOR(f)[x] = w; } } } igraph_vector_long_destroy(&mark); igraph_adjlist_destroy(&adjlist); igraph_vector_long_destroy(&index); igraph_vector_long_destroy(&f); IGRAPH_FINALLY_CLEAN(4); if (newgraph) { IGRAPH_CHECK(igraph_copy(newgraph, graph)); IGRAPH_FINALLY(igraph_destroy, newgraph); IGRAPH_CHECK(igraph_add_edges(newgraph, my_fill_in, 0)); IGRAPH_FINALLY_CLEAN(1); } if (!fill_in && newgraph) { igraph_vector_destroy(&v_fill_in); IGRAPH_FINALLY_CLEAN(1); } if (!alpha && !alpham1) { igraph_vector_destroy(&v_alpham1); igraph_vector_destroy(&v_alpha); IGRAPH_FINALLY_CLEAN(2); } else if (alpha && !alpham1) { igraph_vector_destroy(&v_alpham1); IGRAPH_FINALLY_CLEAN(1); } else if (!alpha && alpham1) { igraph_vector_destroy(&v_alpha); IGRAPH_FINALLY_CLEAN(1); } return IGRAPH_SUCCESS; } leidenbase/src/core/misc/mixing.c0000644000176200001440000002533414447675375016513 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_mixing.h" #include "igraph_interface.h" /** * \function igraph_assortativity_nominal * Assortativity of a graph based on vertex categories * * Assuming the vertices of the input graph belong to different * categories, this function calculates the assortativity coefficient of * the graph. The assortativity coefficient is between minus one and one * and it is one if all connections stay within categories, it is * minus one, if the network is perfectly disassortative. For a * randomly connected network it is (asymptotically) zero. * * See equation (2) in M. E. J. Newman: Mixing patterns * in networks, Phys. Rev. E 67, 026126 (2003) * (http://arxiv.org/abs/cond-mat/0209450) for the proper * definition. * * \param graph The input graph, it can be directed or undirected. * \param types Vector giving the vertex types. They are assumed to be * integer numbers, starting with zero. * \param res Pointer to a real variable, the result is stored here. * \param directed Boolean, it gives whether to consider edge * directions in a directed graph. It is ignored for undirected * graphs. * \return Error code. * * Time complexity: O(|E|+t), |E| is the number of edges, t is the * number of vertex types. * * \sa \ref igraph_assortativity if the vertex types are defines by * numeric values (e.g. vertex degree), instead of categories. * * \example examples/simple/assortativity.c */ int igraph_assortativity_nominal(const igraph_t *graph, const igraph_vector_t *types, igraph_real_t *res, igraph_bool_t directed) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int no_of_types; igraph_vector_t ai, bi, eii; long int e, i; igraph_real_t sumaibi = 0.0, sumeii = 0.0; if (igraph_vector_size(types) != no_of_nodes) { IGRAPH_ERROR("Invalid `types' vector length", IGRAPH_EINVAL); } if (no_of_nodes == 0) { *res = IGRAPH_NAN; return IGRAPH_SUCCESS; } /* 'types' length > 0 here, safe to call vector_min() */ if (igraph_vector_min(types) < 0) { IGRAPH_ERROR("Invalid `types' vector", IGRAPH_EINVAL); } directed = directed && igraph_is_directed(graph); no_of_types = (long int) igraph_vector_max(types) + 1; IGRAPH_VECTOR_INIT_FINALLY(&ai, no_of_types); IGRAPH_VECTOR_INIT_FINALLY(&bi, no_of_types); IGRAPH_VECTOR_INIT_FINALLY(&eii, no_of_types); for (e = 0; e < no_of_edges; e++) { long int from = IGRAPH_FROM(graph, e); long int to = IGRAPH_TO(graph, e); long int from_type = (long int) VECTOR(*types)[from]; long int to_type = (long int) VECTOR(*types)[to]; VECTOR(ai)[from_type] += 1; VECTOR(bi)[to_type] += 1; if (from_type == to_type) { VECTOR(eii)[from_type] += 1; } if (!directed) { if (from_type == to_type) { VECTOR(eii)[from_type] += 1; } VECTOR(ai)[to_type] += 1; VECTOR(bi)[from_type] += 1; } } for (i = 0; i < no_of_types; i++) { sumaibi += (VECTOR(ai)[i] / no_of_edges) * (VECTOR(bi)[i] / no_of_edges); sumeii += (VECTOR(eii)[i] / no_of_edges); } if (!directed) { sumaibi /= 4.0; sumeii /= 2.0; } *res = (sumeii - sumaibi) / (1.0 - sumaibi); igraph_vector_destroy(&eii); igraph_vector_destroy(&bi); igraph_vector_destroy(&ai); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_assortativity * Assortativity based on numeric properties of vertices * * This function calculates the assortativity coefficient of the input * graph. This coefficient is basically the correlation between the * actual connectivity patterns of the vertices and the pattern * expected from the distribution of the vertex types. * * See equation (21) in M. E. J. Newman: Mixing patterns * in networks, Phys. Rev. E 67, 026126 (2003) * (http://arxiv.org/abs/cond-mat/0209450) for the proper * definition. The actual calculation is performed using equation (26) * in the same paper for directed graphs, and equation (4) in * M. E. J. Newman: Assortative mixing in networks, * Phys. Rev. Lett. 89, 208701 (2002) * (http://arxiv.org/abs/cond-mat/0205405/) for undirected graphs. * * \param graph The input graph, it can be directed or undirected. * \param types1 The vertex values, these can be arbitrary numeric * values. * \param types2 A second value vector to be using for the incoming * edges when calculating assortativity for a directed graph. * Supply a null pointer here if you want to use the same values * for outgoing and incoming edges. This argument is ignored * (with a warning) if it is not a null pointer and undirected * assortativity coefficient is being calculated. * \param res Pointer to a real variable, the result is stored here. * \param directed Boolean, whether to consider edge directions for * directed graphs. It is ignored for undirected graphs. * \return Error code. * * Time complexity: O(|E|), linear in the number of edges of the * graph. * * \sa \ref igraph_assortativity_nominal() if you have discrete vertex * categories instead of numeric labels, and \ref * igraph_assortativity_degree() for the special case of assortativity * based on vertex degree. * * \example examples/simple/assortativity.c */ int igraph_assortativity(const igraph_t *graph, const igraph_vector_t *types1, const igraph_vector_t *types2, igraph_real_t *res, igraph_bool_t directed) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int e; directed = directed && igraph_is_directed(graph); if (!directed && types2) { IGRAPH_WARNING("Only `types1' is used for undirected case"); } if (igraph_vector_size(types1) != no_of_nodes) { IGRAPH_ERROR("Invalid `types1' vector length", IGRAPH_EINVAL); } if (types2 && igraph_vector_size(types2) != no_of_nodes) { IGRAPH_ERROR("Invalid `types2' vector length", IGRAPH_EINVAL); } if (!directed) { igraph_real_t num1 = 0.0, num2 = 0.0, den1 = 0.0; for (e = 0; e < no_of_edges; e++) { long int from = IGRAPH_FROM(graph, e); long int to = IGRAPH_TO(graph, e); igraph_real_t from_type = VECTOR(*types1)[from]; igraph_real_t to_type = VECTOR(*types1)[to]; num1 += from_type * to_type; num2 += from_type + to_type; den1 += from_type * from_type + to_type * to_type; } num1 /= no_of_edges; den1 /= no_of_edges * 2; num2 /= no_of_edges * 2; num2 = num2 * num2; *res = (num1 - num2) / (den1 - num2); } else { igraph_real_t num1 = 0.0, num2 = 0.0, num3 = 0.0, den1 = 0.0, den2 = 0.0; igraph_real_t num, den; if (!types2) { types2 = types1; } for (e = 0; e < no_of_edges; e++) { long int from = IGRAPH_FROM(graph, e); long int to = IGRAPH_TO(graph, e); igraph_real_t from_type = VECTOR(*types1)[from]; igraph_real_t to_type = VECTOR(*types2)[to]; num1 += from_type * to_type; num2 += from_type; num3 += to_type; den1 += from_type * from_type; den2 += to_type * to_type; } num = num1 - num2 * num3 / no_of_edges; den = sqrt(den1 - num2 * num2 / no_of_edges) * sqrt(den2 - num3 * num3 / no_of_edges); *res = num / den; } return 0; } /** * \function igraph_assortativity_degree * Assortativity of a graph based on vertex degree * * Assortativity based on vertex degree, please see the discussion at * the documentation of \ref igraph_assortativity() for details. * * \param graph The input graph, it can be directed or undirected. * \param res Pointer to a real variable, the result is stored here. * \param directed Boolean, whether to consider edge directions for * directed graphs. This argument is ignored for undirected * graphs. Supply 1 (=TRUE) here to do the natural thing, i.e. use * directed version of the measure for directed graphs and the * undirected version for undirected graphs. * \return Error code. * * Time complexity: O(|E|+|V|), |E| is the number of edges, |V| is * the number of vertices. * * \sa \ref igraph_assortativity() for the general function * calculating assortativity for any kind of numeric vertex values. * * \example examples/simple/assortativity.c */ int igraph_assortativity_degree(const igraph_t *graph, igraph_real_t *res, igraph_bool_t directed) { directed = directed && igraph_is_directed(graph); if (directed) { igraph_vector_t indegree, outdegree; igraph_vector_init(&indegree, 0); igraph_vector_init(&outdegree, 0); igraph_degree(graph, &indegree, igraph_vss_all(), IGRAPH_IN, /*loops=*/ 1); igraph_degree(graph, &outdegree, igraph_vss_all(), IGRAPH_OUT, /*loops=*/ 1); igraph_vector_add_constant(&indegree, -1); igraph_vector_add_constant(&outdegree, -1); igraph_assortativity(graph, &outdegree, &indegree, res, /*directed=*/ 1); igraph_vector_destroy(&indegree); igraph_vector_destroy(&outdegree); } else { igraph_vector_t degree; igraph_vector_init(°ree, 0); igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, /*loops=*/ 1); igraph_vector_add_constant(°ree, -1); igraph_assortativity(graph, °ree, 0, res, /*directed=*/ 0); igraph_vector_destroy(°ree); } return 0; } leidenbase/src/core/misc/feedback_arc_set.h0000644000176200001440000000252514447675375020446 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_FEEDBACK_ARC_SET_INTERNAL_H #define IGRAPH_FEEDBACK_ARC_SET_INTERNAL_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_vector.h" __BEGIN_DECLS int igraph_i_feedback_arc_set_undirected(const igraph_t *graph, igraph_vector_t *result, const igraph_vector_t *weights, igraph_vector_t *layering); int igraph_i_feedback_arc_set_eades(const igraph_t *graph, igraph_vector_t *result, const igraph_vector_t *weights, igraph_vector_t *layering); __END_DECLS #endif leidenbase/src/core/misc/conversion_internal.h0000644000176200001440000000177014447675375021304 0ustar liggesusers/* IGraph library. Copyright (C) 2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IGRAPH_MISC_CONVERSION_INTERNAL_H #define IGRAPH_MISC_CONVERSION_INTERNAL_H #include "igraph_sparsemat.h" #include "igraph_types.h" int igraph_i_normalize_sparsemat(igraph_sparsemat_t *sparsemat, igraph_bool_t column_wise); #endif leidenbase/src/core/misc/matching.c0000644000176200001440000012314214447675375017006 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2012 Tamas Nepusz This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_matching.h" #include "igraph_adjlist.h" #include "igraph_constructors.h" #include "igraph_conversion.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_structural.h" #include /* #define MATCHING_DEBUG */ #ifdef _MSC_VER /* MSVC does not support variadic macros */ #include static void debug(const char* fmt, ...) { va_list args; va_start(args, fmt); #ifdef MATCHING_DEBUG vfprintf(stderr, fmt, args); #endif va_end(args); } #else #ifdef MATCHING_DEBUG #define debug(...) fprintf(stderr, __VA_ARGS__) #else #define debug(...) #endif #endif /** * \function igraph_is_matching * Checks whether the given matching is valid for the given graph. * * This function checks a matching vector and verifies whether its length * matches the number of vertices in the given graph, its values are between * -1 (inclusive) and the number of vertices (exclusive), and whether there * exists a corresponding edge in the graph for every matched vertex pair. * For bipartite graphs, it also verifies whether the matched vertices are * in different parts of the graph. * * \param graph The input graph. It can be directed but the edge directions * will be ignored. * \param types If the graph is bipartite and you are interested in bipartite * matchings only, pass the vertex types here. If the graph is * non-bipartite, simply pass \c NULL. * \param matching The matching itself. It must be a vector where element i * contains the ID of the vertex that vertex i is matched to, * or -1 if vertex i is unmatched. * \param result Pointer to a boolean variable, the result will be returned * here. * * \sa \ref igraph_is_maximal_matching() if you are also interested in whether * the matching is maximal (i.e. non-extendable). * * Time complexity: O(|V|+|E|) where |V| is the number of vertices and * |E| is the number of edges. * * \example examples/simple/igraph_maximum_bipartite_matching.c */ int igraph_is_matching(const igraph_t* graph, const igraph_vector_bool_t* types, const igraph_vector_long_t* matching, igraph_bool_t* result) { long int i, j, no_of_nodes = igraph_vcount(graph); igraph_bool_t conn; /* Checking match vector length */ if (igraph_vector_long_size(matching) != no_of_nodes) { *result = 0; return IGRAPH_SUCCESS; } for (i = 0; i < no_of_nodes; i++) { j = VECTOR(*matching)[i]; /* Checking range of each element in the match vector */ if (j < -1 || j >= no_of_nodes) { *result = 0; return IGRAPH_SUCCESS; } /* When i is unmatched, we're done */ if (j == -1) { continue; } /* Matches must be mutual */ if (VECTOR(*matching)[j] != i) { *result = 0; return IGRAPH_SUCCESS; } /* Matched vertices must be connected */ IGRAPH_CHECK(igraph_are_connected(graph, (igraph_integer_t) i, (igraph_integer_t) j, &conn)); if (!conn) { /* Try the other direction -- for directed graphs */ IGRAPH_CHECK(igraph_are_connected(graph, (igraph_integer_t) j, (igraph_integer_t) i, &conn)); if (!conn) { *result = 0; return IGRAPH_SUCCESS; } } } if (types != 0) { /* Matched vertices must be of different types */ for (i = 0; i < no_of_nodes; i++) { j = VECTOR(*matching)[i]; if (j == -1) { continue; } if (VECTOR(*types)[i] == VECTOR(*types)[j]) { *result = 0; return IGRAPH_SUCCESS; } } } *result = 1; return IGRAPH_SUCCESS; } /** * \function igraph_is_maximal_matching * Checks whether a matching in a graph is maximal. * * A matching is maximal if and only if there exists no unmatched vertex in a * graph such that one of its neighbors is also unmatched. * * \param graph The input graph. It can be directed but the edge directions * will be ignored. * \param types If the graph is bipartite and you are interested in bipartite * matchings only, pass the vertex types here. If the graph is * non-bipartite, simply pass \c NULL. * \param matching The matching itself. It must be a vector where element i * contains the ID of the vertex that vertex i is matched to, * or -1 if vertex i is unmatched. * \param result Pointer to a boolean variable, the result will be returned * here. * * \sa \ref igraph_is_matching() if you are only interested in whether a * matching vector is valid for a given graph. * * Time complexity: O(|V|+|E|) where |V| is the number of vertices and * |E| is the number of edges. * * \example examples/simple/igraph_maximum_bipartite_matching.c */ int igraph_is_maximal_matching(const igraph_t* graph, const igraph_vector_bool_t* types, const igraph_vector_long_t* matching, igraph_bool_t* result) { long int i, j, n, no_of_nodes = igraph_vcount(graph); igraph_vector_t neis; igraph_bool_t valid; IGRAPH_CHECK(igraph_is_matching(graph, types, matching, &valid)); if (!valid) { *result = 0; return IGRAPH_SUCCESS; } IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); valid = 1; for (i = 0; i < no_of_nodes; i++) { j = VECTOR(*matching)[i]; if (j != -1) { continue; } IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) i, IGRAPH_ALL)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { if (VECTOR(*matching)[(long int)VECTOR(neis)[j]] == -1) { if (types == 0 || VECTOR(*types)[i] != VECTOR(*types)[(long int)VECTOR(neis)[j]]) { valid = 0; break; } } } } igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(1); *result = valid; return IGRAPH_SUCCESS; } static int igraph_i_maximum_bipartite_matching_unweighted( const igraph_t* graph, const igraph_vector_bool_t* types, igraph_integer_t* matching_size, igraph_vector_long_t* matching); static int igraph_i_maximum_bipartite_matching_weighted( const igraph_t* graph, const igraph_vector_bool_t* types, igraph_integer_t* matching_size, igraph_real_t* matching_weight, igraph_vector_long_t* matching, const igraph_vector_t* weights, igraph_real_t eps); #define MATCHED(v) (VECTOR(match)[v] != -1) #define UNMATCHED(v) (!MATCHED(v)) /** * \function igraph_maximum_bipartite_matching * Calculates a maximum matching in a bipartite graph. * * A matching in a bipartite graph is a partial assignment of vertices * of the first kind to vertices of the second kind such that each vertex of * the first kind is matched to at most one vertex of the second kind and * vice versa, and matched vertices must be connected by an edge in the graph. * The size (or cardinality) of a matching is the number of edges. * A matching is a maximum matching if there exists no other matching with * larger cardinality. For weighted graphs, a maximum matching is a matching * whose edges have the largest possible total weight among all possible * matchings. * * * Maximum matchings in bipartite graphs are found by the push-relabel algorithm * with greedy initialization and a global relabeling after every n/2 steps where * n is the number of vertices in the graph. * * * References: Cherkassky BV, Goldberg AV, Martin P, Setubal JC and Stolfi J: * Augment or push: A computational study of bipartite matching and * unit-capacity flow algorithms. ACM Journal of Experimental Algorithmics 3, * 1998. * * * Kaya K, Langguth J, Manne F and Ucar B: Experiments on push-relabel-based * maximum cardinality matching algorithms for bipartite graphs. Technical * Report TR/PA/11/33 of the Centre Europeen de Recherche et de Formation * Avancee en Calcul Scientifique, 2011. * * \param graph The input graph. It can be directed but the edge directions * will be ignored. * \param types Boolean vector giving the vertex types of the graph. * \param matching_size The size of the matching (i.e. the number of matched * vertex pairs will be returned here). It may be \c NULL * if you don't need this. * \param matching_weight The weight of the matching if the edges are weighted, * or the size of the matching again if the edges are * unweighted. It may be \c NULL if you don't need this. * \param matching The matching itself. It must be a vector where element i * contains the ID of the vertex that vertex i is matched to, * or -1 if vertex i is unmatched. * \param weights A null pointer (=no edge weights), or a vector giving the * weights of the edges. Note that the algorithm is stable * only for integer weights. * \param eps A small real number used in equality tests in the weighted * bipartite matching algorithm. Two real numbers are considered * equal in the algorithm if their difference is smaller than * \c eps. This is required to avoid the accumulation of numerical * errors. It is advised to pass a value derived from the * \c DBL_EPSILON constant in \c float.h here. If you are * running the algorithm with no \c weights vector, this argument * is ignored. * \return Error code. * * Time complexity: O(sqrt(|V|) |E|) for unweighted graphs (according to the * technical report referenced above), O(|V||E|) for weighted graphs. * * \example examples/simple/igraph_maximum_bipartite_matching.c */ int igraph_maximum_bipartite_matching(const igraph_t* graph, const igraph_vector_bool_t* types, igraph_integer_t* matching_size, igraph_real_t* matching_weight, igraph_vector_long_t* matching, const igraph_vector_t* weights, igraph_real_t eps) { /* Sanity checks */ if (igraph_vector_bool_size(types) < igraph_vcount(graph)) { IGRAPH_ERROR("types vector too short", IGRAPH_EINVAL); } if (weights && igraph_vector_size(weights) < igraph_ecount(graph)) { IGRAPH_ERROR("weights vector too short", IGRAPH_EINVAL); } if (weights == 0) { IGRAPH_CHECK(igraph_i_maximum_bipartite_matching_unweighted(graph, types, matching_size, matching)); if (matching_weight != 0) { *matching_weight = *matching_size; } return IGRAPH_SUCCESS; } else { IGRAPH_CHECK(igraph_i_maximum_bipartite_matching_weighted(graph, types, matching_size, matching_weight, matching, weights, eps)); return IGRAPH_SUCCESS; } } static int igraph_i_maximum_bipartite_matching_unweighted_relabel( const igraph_t* graph, const igraph_vector_bool_t* types, igraph_vector_t* labels, igraph_vector_long_t* matching, igraph_bool_t smaller_set); /** * Finding maximum bipartite matchings on bipartite graphs using the * push-relabel algorithm. * * The implementation follows the pseudocode in Algorithm 1 of the * following paper: * * Kaya K, Langguth J, Manne F and Ucar B: Experiments on push-relabel-based * maximum cardinality matching algorithms for bipartite graphs. Technical * Report TR/PA/11/33 of CERFACS (Centre Européen de Recherche et de Formation * Avancée en Calcul Scientifique). * http://www.cerfacs.fr/algor/reports/2011/TR_PA_11_33.pdf */ static int igraph_i_maximum_bipartite_matching_unweighted( const igraph_t* graph, const igraph_vector_bool_t* types, igraph_integer_t* matching_size, igraph_vector_long_t* matching) { long int i, j, k, n, no_of_nodes = igraph_vcount(graph); long int num_matched; /* number of matched vertex pairs */ igraph_vector_long_t match; /* will store the matching */ igraph_vector_t labels; /* will store the labels */ igraph_vector_t neis; /* used to retrieve the neighbors of a node */ igraph_dqueue_long_t q; /* a FIFO for push ordering */ igraph_bool_t smaller_set; /* denotes which part of the bipartite graph is smaller */ long int label_changed = 0; /* Counter to decide when to run a global relabeling */ long int relabeling_freq = no_of_nodes / 2; /* We will use: * - FIFO push ordering * - global relabeling frequency: n/2 steps where n is the number of nodes * - simple greedy matching for initialization */ /* (1) Initialize data structures */ IGRAPH_CHECK(igraph_vector_long_init(&match, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &match); IGRAPH_VECTOR_INIT_FINALLY(&labels, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_dqueue_long_init(&q, 0)); IGRAPH_FINALLY(igraph_dqueue_long_destroy, &q); /* (2) Initially, every node is unmatched */ igraph_vector_long_fill(&match, -1); /* (3) Find an initial matching in a greedy manner. * At the same time, find which side of the graph is smaller. */ num_matched = 0; j = 0; for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*types)[i]) { j++; } if (MATCHED(i)) { continue; } IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) i, IGRAPH_ALL)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { k = (long int) VECTOR(neis)[j]; if (VECTOR(*types)[k] == VECTOR(*types)[i]) { IGRAPH_ERROR("Graph is not bipartite with supplied types vector", IGRAPH_EINVAL); } if (UNMATCHED(k)) { /* We match vertex i to vertex VECTOR(neis)[j] */ VECTOR(match)[k] = i; VECTOR(match)[i] = k; num_matched++; break; } } } smaller_set = (j <= no_of_nodes / 2); /* (4) Set the initial labeling -- lines 1 and 2 in the tech report */ IGRAPH_CHECK(igraph_i_maximum_bipartite_matching_unweighted_relabel( graph, types, &labels, &match, smaller_set)); /* (5) Fill the push queue with the unmatched nodes from the smaller set. */ for (i = 0; i < no_of_nodes; i++) { if (UNMATCHED(i) && VECTOR(*types)[i] == smaller_set) { IGRAPH_CHECK(igraph_dqueue_long_push(&q, i)); } } /* (6) Main loop from the referenced tech report -- lines 4--13 */ label_changed = 0; while (!igraph_dqueue_long_empty(&q)) { long int v = igraph_dqueue_long_pop(&q); /* Line 13 */ long int u = -1, label_u = 2 * no_of_nodes; long int w; if (label_changed >= relabeling_freq) { /* Run global relabeling */ IGRAPH_CHECK(igraph_i_maximum_bipartite_matching_unweighted_relabel( graph, types, &labels, &match, smaller_set)); label_changed = 0; } debug("Considering vertex %ld\n", v); /* Line 5: find row u among the neighbors of v s.t. label(u) is minimal */ IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) v, IGRAPH_ALL)); n = igraph_vector_size(&neis); for (i = 0; i < n; i++) { if (VECTOR(labels)[(long int)VECTOR(neis)[i]] < label_u) { u = (long int) VECTOR(neis)[i]; label_u = (long int) VECTOR(labels)[u]; label_changed++; } } debug(" Neighbor with smallest label: %ld (label=%ld)\n", u, label_u); if (label_u < no_of_nodes) { /* Line 6 */ VECTOR(labels)[v] = VECTOR(labels)[u] + 1; /* Line 7 */ if (MATCHED(u)) { /* Line 8 */ w = VECTOR(match)[u]; debug(" Vertex %ld is matched to %ld, performing a double push\n", u, w); if (w != v) { VECTOR(match)[u] = -1; VECTOR(match)[w] = -1; /* Line 9 */ IGRAPH_CHECK(igraph_dqueue_long_push(&q, w)); /* Line 10 */ debug(" Unmatching & activating vertex %ld\n", w); num_matched--; } } VECTOR(match)[u] = v; VECTOR(match)[v] = u; /* Line 11 */ num_matched++; VECTOR(labels)[u] += 2; /* Line 12 */ label_changed++; } } /* Fill the output parameters */ if (matching != 0) { IGRAPH_CHECK(igraph_vector_long_update(matching, &match)); } if (matching_size != 0) { *matching_size = (igraph_integer_t) num_matched; } /* Release everything */ igraph_dqueue_long_destroy(&q); igraph_vector_destroy(&neis); igraph_vector_destroy(&labels); igraph_vector_long_destroy(&match); IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; } static int igraph_i_maximum_bipartite_matching_unweighted_relabel( const igraph_t* graph, const igraph_vector_bool_t* types, igraph_vector_t* labels, igraph_vector_long_t* match, igraph_bool_t smaller_set) { long int i, j, n, no_of_nodes = igraph_vcount(graph), matched_to; igraph_dqueue_long_t q; igraph_vector_t neis; debug("Running global relabeling.\n"); /* Set all the labels to no_of_nodes first */ igraph_vector_fill(labels, no_of_nodes); /* Allocate vector for neighbors */ IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); /* Create a FIFO for the BFS and initialize it with the unmatched rows * (i.e. members of the larger set) */ IGRAPH_CHECK(igraph_dqueue_long_init(&q, 0)); IGRAPH_FINALLY(igraph_dqueue_long_destroy, &q); for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*types)[i] != smaller_set && VECTOR(*match)[i] == -1) { IGRAPH_CHECK(igraph_dqueue_long_push(&q, i)); VECTOR(*labels)[i] = 0; } } /* Run the BFS */ while (!igraph_dqueue_long_empty(&q)) { long int v = igraph_dqueue_long_pop(&q); long int w; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) v, IGRAPH_ALL)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { w = (long int) VECTOR(neis)[j]; if (VECTOR(*labels)[w] == no_of_nodes) { VECTOR(*labels)[w] = VECTOR(*labels)[v] + 1; matched_to = VECTOR(*match)[w]; if (matched_to != -1 && VECTOR(*labels)[matched_to] == no_of_nodes) { IGRAPH_CHECK(igraph_dqueue_long_push(&q, matched_to)); VECTOR(*labels)[matched_to] = VECTOR(*labels)[w] + 1; } } } } igraph_dqueue_long_destroy(&q); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /** * Finding maximum bipartite matchings on bipartite graphs using the * Hungarian algorithm (a.k.a. Kuhn-Munkres algorithm). * * The algorithm uses a maximum cardinality matching on a subset of * tight edges as a starting point. This is achieved by * \c igraph_i_maximum_bipartite_matching_unweighted on the restricted * graph. * * The algorithm works reliably only if the weights are integers. The * \c eps parameter should specity a very small number; if the slack on * an edge falls below \c eps, it will be considered tight. If all your * weights are integers, you can safely set \c eps to zero. */ static int igraph_i_maximum_bipartite_matching_weighted( const igraph_t* graph, const igraph_vector_bool_t* types, igraph_integer_t* matching_size, igraph_real_t* matching_weight, igraph_vector_long_t* matching, const igraph_vector_t* weights, igraph_real_t eps) { long int i, j, k, n, no_of_nodes, no_of_edges; igraph_integer_t u, v, w, msize; igraph_t newgraph; igraph_vector_long_t match; /* will store the matching */ igraph_vector_t slack; /* will store the slack on each edge */ igraph_vector_t parent; /* parent vertices during a BFS */ igraph_vector_t vec1, vec2; /* general temporary vectors */ igraph_vector_t labels; /* will store the labels */ igraph_dqueue_long_t q; /* a FIFO for BST */ igraph_bool_t smaller_set_type; /* denotes which part of the bipartite graph is smaller */ igraph_vector_t smaller_set; /* stores the vertex IDs of the smaller set */ igraph_vector_t larger_set; /* stores the vertex IDs of the larger set */ long int smaller_set_size; /* size of the smaller set */ long int larger_set_size; /* size of the larger set */ igraph_real_t dual; /* solution of the dual problem */ IGRAPH_UNUSED(dual); /* We mark it as unused to prevent warnings about unused-but-set-variables. */ igraph_adjlist_t tight_phantom_edges; /* adjacency list to manage tight phantom edges */ igraph_integer_t alternating_path_endpoint; igraph_vector_int_t* neis; igraph_vector_int_t *neis2; igraph_inclist_t inclist; /* incidence list of the original graph */ /* The Hungarian algorithm is originally for complete bipartite graphs. * For non-complete bipartite graphs, a phantom edge of weight zero must be * added between every pair of non-connected vertices. We don't do this * explicitly of course. See the comments below about how phantom edges * are taken into account. */ no_of_nodes = igraph_vcount(graph); no_of_edges = igraph_ecount(graph); if (eps < 0) { IGRAPH_WARNING("negative epsilon given, clamping to zero"); eps = 0; } /* (1) Initialize data structures */ IGRAPH_CHECK(igraph_vector_long_init(&match, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &match); IGRAPH_CHECK(igraph_vector_init(&slack, no_of_edges)); IGRAPH_FINALLY(igraph_vector_destroy, &slack); IGRAPH_VECTOR_INIT_FINALLY(&vec1, 0); IGRAPH_VECTOR_INIT_FINALLY(&vec2, 0); IGRAPH_VECTOR_INIT_FINALLY(&labels, no_of_nodes); IGRAPH_CHECK(igraph_dqueue_long_init(&q, 0)); IGRAPH_FINALLY(igraph_dqueue_long_destroy, &q); IGRAPH_VECTOR_INIT_FINALLY(&parent, no_of_nodes); IGRAPH_CHECK(igraph_adjlist_init_empty(&tight_phantom_edges, (igraph_integer_t) no_of_nodes)); IGRAPH_FINALLY(igraph_adjlist_destroy, &tight_phantom_edges); IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); IGRAPH_VECTOR_INIT_FINALLY(&smaller_set, 0); IGRAPH_VECTOR_INIT_FINALLY(&larger_set, 0); /* (2) Find which set is the smaller one */ j = 0; for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*types)[i] == 0) { j++; } } smaller_set_type = (j > no_of_nodes / 2); smaller_set_size = smaller_set_type ? (no_of_nodes - j) : j; larger_set_size = no_of_nodes - smaller_set_size; IGRAPH_CHECK(igraph_vector_reserve(&smaller_set, smaller_set_size)); IGRAPH_CHECK(igraph_vector_reserve(&larger_set, larger_set_size)); for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*types)[i] == smaller_set_type) { IGRAPH_CHECK(igraph_vector_push_back(&smaller_set, i)); } else { IGRAPH_CHECK(igraph_vector_push_back(&larger_set, i)); } } /* (3) Calculate the initial labeling and the set of tight edges. Use the * smaller set only. Here we can assume that there are no phantom edges * among the tight ones. */ dual = 0; for (i = 0; i < no_of_nodes; i++) { igraph_real_t max_weight = 0; if (VECTOR(*types)[i] != smaller_set_type) { VECTOR(labels)[i] = 0; continue; } neis = igraph_inclist_get(&inclist, i); n = igraph_vector_int_size(neis); for (j = 0, k = 0; j < n; j++) { k = (long int) VECTOR(*neis)[j]; u = IGRAPH_OTHER(graph, k, i); if (VECTOR(*types)[u] == VECTOR(*types)[i]) { IGRAPH_ERROR("Graph is not bipartite with supplied types vector", IGRAPH_EINVAL); } if (VECTOR(*weights)[k] > max_weight) { max_weight = VECTOR(*weights)[k]; } } VECTOR(labels)[i] = max_weight; dual += max_weight; } igraph_vector_clear(&vec1); IGRAPH_CHECK(igraph_get_edgelist(graph, &vec2, 0)); #define IS_TIGHT(i) (VECTOR(slack)[i] <= eps) for (i = 0, j = 0; i < no_of_edges; i++, j += 2) { u = (igraph_integer_t) VECTOR(vec2)[j]; v = (igraph_integer_t) VECTOR(vec2)[j + 1]; VECTOR(slack)[i] = VECTOR(labels)[u] + VECTOR(labels)[v] - VECTOR(*weights)[i]; if (IS_TIGHT(i)) { IGRAPH_CHECK(igraph_vector_push_back(&vec1, u)); IGRAPH_CHECK(igraph_vector_push_back(&vec1, v)); } } igraph_vector_clear(&vec2); /* (4) Construct a temporary graph on which the initial maximum matching * will be calculated (only on the subset of tight edges) */ IGRAPH_CHECK(igraph_create(&newgraph, &vec1, (igraph_integer_t) no_of_nodes, 0)); IGRAPH_FINALLY(igraph_destroy, &newgraph); IGRAPH_CHECK(igraph_maximum_bipartite_matching(&newgraph, types, &msize, 0, &match, 0, 0)); igraph_destroy(&newgraph); IGRAPH_FINALLY_CLEAN(1); /* (5) Main loop until the matching becomes maximal */ while (msize < smaller_set_size) { igraph_real_t min_slack, min_slack_2; igraph_integer_t min_slack_u, min_slack_v; /* mark min_slack_u as unused; it is actually used when debugging, but * gcc complains when we are not debugging */ IGRAPH_UNUSED(min_slack_u); /* (7) Fill the push queue with the unmatched nodes from the smaller set. */ igraph_vector_clear(&vec1); igraph_vector_clear(&vec2); igraph_vector_fill(&parent, -1); for (j = 0; j < smaller_set_size; j++) { i = VECTOR(smaller_set)[j]; if (UNMATCHED(i)) { IGRAPH_CHECK(igraph_dqueue_long_push(&q, i)); VECTOR(parent)[i] = i; IGRAPH_CHECK(igraph_vector_push_back(&vec1, i)); } } #ifdef MATCHING_DEBUG debug("Matching:"); igraph_vector_long_print(&match); debug("Unmatched vertices are marked by non-negative numbers:\n"); igraph_vector_print(&parent); debug("Labeling:"); igraph_vector_print(&labels); debug("Slacks:"); igraph_vector_print(&slack); #endif /* (8) Run the BFS */ alternating_path_endpoint = -1; while (!igraph_dqueue_long_empty(&q)) { v = (int) igraph_dqueue_long_pop(&q); debug("Considering vertex %ld\n", (long int)v); /* v is always in the smaller set. Find the neighbors of v, which * are all in the larger set. Find the pairs of these nodes in * the smaller set and push them to the queue. Mark the traversed * nodes as seen. * * Here we have to be careful as there are two types of incident * edges on v: real edges and phantom ones. Real edges are * given by igraph_inclist_get. Phantom edges are not given so we * (ab)use an adjacency list data structure that lists the * vertices connected to v by phantom edges only. */ neis = igraph_inclist_get(&inclist, v); n = igraph_vector_int_size(neis); for (i = 0; i < n; i++) { j = (long int) VECTOR(*neis)[i]; /* We only care about tight edges */ if (!IS_TIGHT(j)) { continue; } /* Have we seen the other endpoint already? */ u = IGRAPH_OTHER(graph, j, v); if (VECTOR(parent)[u] >= 0) { continue; } debug(" Reached vertex %ld via edge %ld\n", (long)u, (long)j); VECTOR(parent)[u] = v; IGRAPH_CHECK(igraph_vector_push_back(&vec2, u)); w = (int) VECTOR(match)[u]; if (w == -1) { /* u is unmatched and it is in the larger set. Therefore, we * could improve the matching by following the parents back * from u to the root. */ alternating_path_endpoint = u; break; /* since we don't need any more endpoints that come from v */ } else { IGRAPH_CHECK(igraph_dqueue_long_push(&q, w)); VECTOR(parent)[w] = u; } IGRAPH_CHECK(igraph_vector_push_back(&vec1, w)); } /* Now do the same with the phantom edges */ neis2 = igraph_adjlist_get(&tight_phantom_edges, v); n = igraph_vector_int_size(neis2); for (i = 0; i < n; i++) { u = (igraph_integer_t) VECTOR(*neis2)[i]; /* Have we seen u already? */ if (VECTOR(parent)[u] >= 0) { continue; } /* Check if the edge is really tight; it might have happened that the * edge became non-tight in the meanwhile. We do not remove these from * tight_phantom_edges at the moment, so we check them once again here. */ if (fabs(VECTOR(labels)[(long int)v] + VECTOR(labels)[(long int)u]) > eps) { continue; } debug(" Reached vertex %ld via tight phantom edge\n", (long)u); VECTOR(parent)[u] = v; IGRAPH_CHECK(igraph_vector_push_back(&vec2, u)); w = (int) VECTOR(match)[u]; if (w == -1) { /* u is unmatched and it is in the larger set. Therefore, we * could improve the matching by following the parents back * from u to the root. */ alternating_path_endpoint = u; break; /* since we don't need any more endpoints that come from v */ } else { IGRAPH_CHECK(igraph_dqueue_long_push(&q, w)); VECTOR(parent)[w] = u; } IGRAPH_CHECK(igraph_vector_push_back(&vec1, w)); } } /* Okay; did we have an alternating path? */ if (alternating_path_endpoint != -1) { #ifdef MATCHING_DEBUG debug("BFS parent tree:"); igraph_vector_print(&parent); #endif /* Increase the size of the matching with the alternating path. */ v = alternating_path_endpoint; u = (igraph_integer_t) VECTOR(parent)[v]; debug("Extending matching with alternating path ending in %ld.\n", (long int)v); while (u != v) { w = (int) VECTOR(match)[v]; if (w != -1) { VECTOR(match)[w] = -1; } VECTOR(match)[v] = u; VECTOR(match)[v] = u; w = (int) VECTOR(match)[u]; if (w != -1) { VECTOR(match)[w] = -1; } VECTOR(match)[u] = v; v = (igraph_integer_t) VECTOR(parent)[u]; u = (igraph_integer_t) VECTOR(parent)[v]; } msize++; #ifdef MATCHING_DEBUG debug("New matching after update:"); igraph_vector_long_print(&match); debug("Matching size is now: %ld\n", (long)msize); #endif continue; } #ifdef MATCHING_DEBUG debug("Vertices reachable from unmatched ones via tight edges:\n"); igraph_vector_print(&vec1); igraph_vector_print(&vec2); #endif /* At this point, vec1 contains the nodes in the smaller set (A) * reachable from unmatched nodes in A via tight edges only, while vec2 * contains the nodes in the larger set (B) reachable from unmatched * nodes in A via tight edges only. Also, parent[i] >= 0 if node i * is reachable */ /* Check the edges between reachable nodes in A and unreachable * nodes in B, and find the minimum slack on them. * * Since the weights are positive, we do no harm if we first * assume that there are no "real" edges between the two sets * mentioned above and determine an upper bound for min_slack * based on this. */ min_slack = IGRAPH_INFINITY; min_slack_u = min_slack_v = 0; n = igraph_vector_size(&vec1); for (j = 0; j < larger_set_size; j++) { i = VECTOR(larger_set)[j]; if (VECTOR(labels)[i] < min_slack) { min_slack = VECTOR(labels)[i]; min_slack_v = (igraph_integer_t) i; } } min_slack_2 = IGRAPH_INFINITY; for (i = 0; i < n; i++) { u = (igraph_integer_t) VECTOR(vec1)[i]; /* u is surely from the smaller set, but we are interested in it * only if it is reachable from an unmatched vertex */ if (VECTOR(parent)[u] < 0) { continue; } if (VECTOR(labels)[u] < min_slack_2) { min_slack_2 = VECTOR(labels)[u]; min_slack_u = u; } } min_slack += min_slack_2; debug("Starting approximation for min_slack = %.4f (based on vertex pair %ld--%ld)\n", min_slack, (long int)min_slack_u, (long int)min_slack_v); n = igraph_vector_size(&vec1); for (i = 0; i < n; i++) { u = (igraph_integer_t) VECTOR(vec1)[i]; /* u is a reachable node in A; get its incident edges. * * There are two types of incident edges: 1) real edges, * 2) phantom edges. Phantom edges were treated earlier * when we determined the initial value for min_slack. */ debug("Trying to expand along vertex %ld\n", (long int)u); neis = igraph_inclist_get(&inclist, u); k = igraph_vector_int_size(neis); for (j = 0; j < k; j++) { /* v is the vertex sitting at the other end of an edge incident * on u; check whether it was reached */ v = IGRAPH_OTHER(graph, VECTOR(*neis)[j], u); debug(" Edge %ld -- %ld (ID=%ld)\n", (long int)u, (long int)v, (long int)VECTOR(*neis)[j]); if (VECTOR(parent)[v] >= 0) { /* v was reached, so we are not interested in it */ debug(" %ld was reached, so we are not interested in it\n", (long int)v); continue; } /* v is the ID of the edge from now on */ v = (igraph_integer_t) VECTOR(*neis)[j]; if (VECTOR(slack)[v] < min_slack) { min_slack = VECTOR(slack)[v]; min_slack_u = u; min_slack_v = IGRAPH_OTHER(graph, v, u); } debug(" Slack of this edge: %.4f, min slack is now: %.4f\n", VECTOR(slack)[v], min_slack); } } debug("Minimum slack: %.4f on edge %d--%d\n", min_slack, (int)min_slack_u, (int)min_slack_v); if (min_slack > 0) { /* Decrease the label of reachable nodes in A by min_slack. * Also update the dual solution */ n = igraph_vector_size(&vec1); for (i = 0; i < n; i++) { u = (igraph_integer_t) VECTOR(vec1)[i]; VECTOR(labels)[u] -= min_slack; neis = igraph_inclist_get(&inclist, u); k = igraph_vector_int_size(neis); for (j = 0; j < k; j++) { debug(" Decreasing slack of edge %ld (%ld--%ld) by %.4f\n", (long)VECTOR(*neis)[j], (long)u, (long)IGRAPH_OTHER(graph, VECTOR(*neis)[j], u), min_slack); VECTOR(slack)[(long int)VECTOR(*neis)[j]] -= min_slack; } dual -= min_slack; } /* Increase the label of reachable nodes in B by min_slack. * Also update the dual solution */ n = igraph_vector_size(&vec2); for (i = 0; i < n; i++) { u = (igraph_integer_t) VECTOR(vec2)[i]; VECTOR(labels)[u] += min_slack; neis = igraph_inclist_get(&inclist, u); k = igraph_vector_int_size(neis); for (j = 0; j < k; j++) { debug(" Increasing slack of edge %ld (%ld--%ld) by %.4f\n", (long)VECTOR(*neis)[j], (long)u, (long)IGRAPH_OTHER(graph, (long)VECTOR(*neis)[j], u), min_slack); VECTOR(slack)[(long int)VECTOR(*neis)[j]] += min_slack; } dual += min_slack; } } /* Update the set of tight phantom edges. * Note that we must do it even if min_slack is zero; the reason is that * it can happen that min_slack is zero in the first step if there are * isolated nodes in the input graph. * * TODO: this is O(n^2) here. Can we do it faster? */ for (i = 0; i < smaller_set_size; i++) { u = VECTOR(smaller_set)[i]; for (j = 0; j < larger_set_size; j++) { v = VECTOR(larger_set)[j]; if (VECTOR(labels)[(long int)u] + VECTOR(labels)[(long int)v] <= eps) { /* Tight phantom edge found. Note that we don't have to check whether * u and v are connected; if they were, then the slack of this edge * would be negative. */ neis2 = igraph_adjlist_get(&tight_phantom_edges, u); if (!igraph_vector_int_binsearch(neis2, v, &k)) { debug("New tight phantom edge: %ld -- %ld\n", (long)u, (long)v); IGRAPH_CHECK(igraph_vector_int_insert(neis2, k, v)); } } } } #ifdef MATCHING_DEBUG debug("New labels:"); igraph_vector_print(&labels); debug("Slacks after updating with min_slack:"); igraph_vector_print(&slack); #endif } /* Cleanup: remove phantom edges from the matching */ for (i = 0; i < smaller_set_size; i++) { u = VECTOR(smaller_set)[i]; v = VECTOR(match)[u]; if (v != -1) { neis2 = igraph_adjlist_get(&tight_phantom_edges, u); if (igraph_vector_int_binsearch(neis2, v, 0)) { VECTOR(match)[u] = VECTOR(match)[v] = -1; msize--; } } } /* Fill the output parameters */ if (matching != 0) { IGRAPH_CHECK(igraph_vector_long_update(matching, &match)); } if (matching_size != 0) { *matching_size = msize; } if (matching_weight != 0) { *matching_weight = 0; for (i = 0; i < no_of_edges; i++) { if (IS_TIGHT(i)) { IGRAPH_CHECK(igraph_edge(graph, (igraph_integer_t) i, &u, &v)); if (VECTOR(match)[u] == v) { *matching_weight += VECTOR(*weights)[i]; } } } } /* Release everything */ #undef IS_TIGHT igraph_vector_destroy(&larger_set); igraph_vector_destroy(&smaller_set); igraph_inclist_destroy(&inclist); igraph_adjlist_destroy(&tight_phantom_edges); igraph_vector_destroy(&parent); igraph_dqueue_long_destroy(&q); igraph_vector_destroy(&labels); igraph_vector_destroy(&vec1); igraph_vector_destroy(&vec2); igraph_vector_destroy(&slack); igraph_vector_long_destroy(&match); IGRAPH_FINALLY_CLEAN(11); return IGRAPH_SUCCESS; } int igraph_maximum_matching(const igraph_t* graph, igraph_integer_t* matching_size, igraph_real_t* matching_weight, igraph_vector_long_t* matching, const igraph_vector_t* weights) { IGRAPH_UNUSED(graph); IGRAPH_UNUSED(matching_size); IGRAPH_UNUSED(matching_weight); IGRAPH_UNUSED(matching); IGRAPH_UNUSED(weights); IGRAPH_ERROR("maximum matching on general graphs not implemented yet", IGRAPH_UNIMPLEMENTED); } #ifdef MATCHING_DEBUG #undef MATCHING_DEBUG #endif leidenbase/src/core/misc/spanning_trees.c0000644000176200001440000004441014447675375020233 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011 Gabor Csardi Rue de l'Industrie 5, Lausanne 1005, Switzerland This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_adjlist.h" #include "igraph_components.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_operators.h" #include "igraph_progress.h" #include "igraph_random.h" #include "igraph_structural.h" #include "core/indheap.h" #include "core/interruption.h" static int igraph_i_minimum_spanning_tree_unweighted(const igraph_t *graph, igraph_vector_t *result); static int igraph_i_minimum_spanning_tree_prim(const igraph_t *graph, igraph_vector_t *result, const igraph_vector_t *weights); /** * \ingroup structural * \function igraph_minimum_spanning_tree * \brief Calculates one minimum spanning tree of a graph. * * * If the graph has more minimum spanning trees (this is always the * case, except if it is a forest) this implementation returns only * the same one. * * * Directed graphs are considered as undirected for this computation. * * * If the graph is not connected then its minimum spanning forest is * returned. This is the set of the minimum spanning trees of each * component. * * \param graph The graph object. * \param res An initialized vector, the IDs of the edges that constitute * a spanning tree will be returned here. Use * \ref igraph_subgraph_edges() to extract the spanning tree as * a separate graph object. * \param weights A vector containing the weights of the edges * in the same order as the simple edge iterator visits them * (i.e. in increasing order of edge IDs). * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * * Time complexity: O(|V|+|E|) for the unweighted case, O(|E| log |V|) * for the weighted case. |V| is the number of vertices, |E| the * number of edges in the graph. * * \sa \ref igraph_minimum_spanning_tree_unweighted() and * \ref igraph_minimum_spanning_tree_prim() if you only need the * tree as a separate graph object. * * \example examples/simple/igraph_minimum_spanning_tree.c */ int igraph_minimum_spanning_tree(const igraph_t* graph, igraph_vector_t* res, const igraph_vector_t* weights) { if (weights == 0) { IGRAPH_CHECK(igraph_i_minimum_spanning_tree_unweighted(graph, res)); } else { IGRAPH_CHECK(igraph_i_minimum_spanning_tree_prim(graph, res, weights)); } return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_minimum_spanning_tree_unweighted * \brief Calculates one minimum spanning tree of an unweighted graph. * * * If the graph has more minimum spanning trees (this is always the * case, except if it is a forest) this implementation returns only * the same one. * * * Directed graphs are considered as undirected for this computation. * * * If the graph is not connected then its minimum spanning forest is * returned. This is the set of the minimum spanning trees of each * component. * \param graph The graph object. * \param mst The minimum spanning tree, another graph object. Do * \em not initialize this object before passing it to * this function, but be sure to call \ref igraph_destroy() on it if * you don't need it any more. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * * Time complexity: O(|V|+|E|), * |V| is the * number of vertices, |E| the number * of edges in the graph. * * \sa \ref igraph_minimum_spanning_tree_prim() for weighted graphs, * \ref igraph_minimum_spanning_tree() if you need the IDs of the * edges that constitute the spanning tree. */ int igraph_minimum_spanning_tree_unweighted(const igraph_t *graph, igraph_t *mst) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; IGRAPH_VECTOR_INIT_FINALLY(&edges, igraph_vcount(graph) - 1); IGRAPH_CHECK(igraph_i_minimum_spanning_tree_unweighted(graph, &edges)); IGRAPH_CHECK(igraph_subgraph_edges(graph, mst, igraph_ess_vector(&edges), /* delete_vertices = */ 0)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup structural * \function igraph_minimum_spanning_tree_prim * \brief Calculates one minimum spanning tree of a weighted graph. * * * This function uses Prim's method for carrying out the computation, * see Prim, R.C.: Shortest connection networks and some * generalizations, Bell System Technical * Journal, Vol. 36, * 1957, 1389--1401. * * * If the graph has more than one minimum spanning tree, the current * implementation returns always the same one. * * * Directed graphs are considered as undirected for this computation. * * * If the graph is not connected then its minimum spanning forest is * returned. This is the set of the minimum spanning trees of each * component. * * \param graph The graph object. * \param mst The result of the computation, a graph object containing * the minimum spanning tree of the graph. * Do \em not initialize this object before passing it to * this function, but be sure to call \ref igraph_destroy() on it if * you don't need it any more. * \param weights A vector containing the weights of the edges * in the same order as the simple edge iterator visits them * (i.e. in increasing order of edge IDs). * \return Error code: * \c IGRAPH_ENOMEM, not enough memory. * \c IGRAPH_EINVAL, length of weight vector does not * match number of edges. * * Time complexity: O(|E| log |V|), * |V| is the number of vertices, * |E| the number of edges in the * graph. * * \sa \ref igraph_minimum_spanning_tree_unweighted() for unweighted graphs, * \ref igraph_minimum_spanning_tree() if you need the IDs of the * edges that constitute the spanning tree. * * \example examples/simple/igraph_minimum_spanning_tree.c */ int igraph_minimum_spanning_tree_prim(const igraph_t *graph, igraph_t *mst, const igraph_vector_t *weights) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; IGRAPH_VECTOR_INIT_FINALLY(&edges, igraph_vcount(graph) - 1); IGRAPH_CHECK(igraph_i_minimum_spanning_tree_prim(graph, &edges, weights)); IGRAPH_CHECK(igraph_subgraph_edges(graph, mst, igraph_ess_vector(&edges), /* delete_vertices = */ 0)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_minimum_spanning_tree_unweighted(const igraph_t* graph, igraph_vector_t* res) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); char *already_added; char *added_edges; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; igraph_vector_t tmp = IGRAPH_VECTOR_NULL; long int i, j; igraph_vector_clear(res); added_edges = IGRAPH_CALLOC(no_of_edges, char); if (added_edges == 0) { IGRAPH_ERROR("unweighted spanning tree failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added_edges); already_added = IGRAPH_CALLOC(no_of_nodes, char); if (already_added == 0) { IGRAPH_ERROR("unweighted spanning tree failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); for (i = 0; i < no_of_nodes; i++) { if (already_added[i] > 0) { continue; } IGRAPH_ALLOW_INTERRUPTION(); already_added[i] = 1; IGRAPH_CHECK(igraph_dqueue_push(&q, i)); while (! igraph_dqueue_empty(&q)) { long int tmp_size; long int act_node = (long int) igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_incident(graph, &tmp, (igraph_integer_t) act_node, IGRAPH_ALL)); tmp_size = igraph_vector_size(&tmp); for (j = 0; j < tmp_size; j++) { long int edge = (long int) VECTOR(tmp)[j]; if (added_edges[edge] == 0) { igraph_integer_t to = IGRAPH_OTHER(graph, edge, act_node); if (already_added[(long int) to] == 0) { already_added[(long int) to] = 1; added_edges[edge] = 1; IGRAPH_CHECK(igraph_vector_push_back(res, edge)); IGRAPH_CHECK(igraph_dqueue_push(&q, to)); } } } } } igraph_dqueue_destroy(&q); IGRAPH_FREE(already_added); igraph_vector_destroy(&tmp); IGRAPH_FREE(added_edges); IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; } static int igraph_i_minimum_spanning_tree_prim( const igraph_t* graph, igraph_vector_t* res, const igraph_vector_t *weights) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); char *already_added; char *added_edges; igraph_d_indheap_t heap = IGRAPH_D_INDHEAP_NULL; igraph_integer_t mode = IGRAPH_ALL; igraph_vector_t adj; long int i, j; igraph_vector_clear(res); if (weights == 0) { return igraph_i_minimum_spanning_tree_unweighted(graph, res); } if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weights length", IGRAPH_EINVAL); } added_edges = IGRAPH_CALLOC(no_of_edges, char); if (added_edges == 0) { IGRAPH_ERROR("prim spanning tree failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added_edges); already_added = IGRAPH_CALLOC(no_of_nodes, char); if (already_added == 0) { IGRAPH_ERROR("prim spanning tree failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_CHECK(igraph_d_indheap_init(&heap, 0)); IGRAPH_FINALLY(igraph_d_indheap_destroy, &heap); IGRAPH_VECTOR_INIT_FINALLY(&adj, 0); for (i = 0; i < no_of_nodes; i++) { long int adj_size; if (already_added[i] > 0) { continue; } IGRAPH_ALLOW_INTERRUPTION(); already_added[i] = 1; /* add all edges of the first vertex */ igraph_incident(graph, &adj, (igraph_integer_t) i, (igraph_neimode_t) mode); adj_size = igraph_vector_size(&adj); for (j = 0; j < adj_size; j++) { igraph_integer_t edgeno = (long int) VECTOR(adj)[j]; igraph_integer_t neighbor = IGRAPH_OTHER(graph, edgeno, i); if (already_added[(long int) neighbor] == 0) { IGRAPH_CHECK(igraph_d_indheap_push(&heap, -VECTOR(*weights)[edgeno], i, edgeno)); } } while (! igraph_d_indheap_empty(&heap)) { /* Get minimal edge */ long int from, edge; igraph_d_indheap_max_index(&heap, &from, &edge); /* Erase it */ igraph_d_indheap_delete_max(&heap); /* Is this edge already included? */ if (added_edges[edge] == 0) { igraph_integer_t to = IGRAPH_OTHER(graph, edge, from); /* Does it point to a visited node? */ if (already_added[(long int)to] == 0) { already_added[(long int)to] = 1; added_edges[edge] = 1; IGRAPH_CHECK(igraph_vector_push_back(res, edge)); /* add all outgoing edges */ igraph_incident(graph, &adj, to, (igraph_neimode_t) mode); adj_size = igraph_vector_size(&adj); for (j = 0; j < adj_size; j++) { long int edgeno = (long int) VECTOR(adj)[j]; long int neighbor = IGRAPH_OTHER(graph, edgeno, to); if (already_added[neighbor] == 0) { IGRAPH_CHECK(igraph_d_indheap_push(&heap, -VECTOR(*weights)[edgeno], to, edgeno)); } } } /* for */ } /* if !already_added */ } /* while in the same component */ } /* for all nodes */ igraph_d_indheap_destroy(&heap); IGRAPH_FREE(already_added); igraph_vector_destroy(&adj); IGRAPH_FREE(added_edges); IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; } /* igraph_random_spanning_tree */ /* Loop-erased random walk (LERW) implementation. * res must be an initialized vector. The edge IDs of the spanning tree * will be added to the end of it. res will not be cleared before doing this. * * The walk is started from vertex start. comp_size must be the size of the connected * component containing start. */ static int igraph_i_lerw(const igraph_t *graph, igraph_vector_t *res, igraph_integer_t start, igraph_integer_t comp_size, igraph_vector_bool_t *visited, const igraph_inclist_t *il) { igraph_integer_t visited_count; IGRAPH_CHECK(igraph_vector_reserve(res, igraph_vector_size(res) + comp_size - 1)); RNG_BEGIN(); VECTOR(*visited)[start] = 1; visited_count = 1; while (visited_count < comp_size) { long degree, edge; igraph_vector_int_t *edges; edges = igraph_inclist_get(il, start); /* choose a random edge */ degree = igraph_vector_int_size(edges); edge = VECTOR(*edges)[ RNG_INTEGER(0, degree - 1) ]; /* set 'start' to the next vertex */ start = IGRAPH_OTHER(graph, edge, start); /* if the next vertex hasn't been visited yet, register the edge we just traversed */ if (! VECTOR(*visited)[start]) { IGRAPH_CHECK(igraph_vector_push_back(res, edge)); VECTOR(*visited)[start] = 1; visited_count++; } IGRAPH_ALLOW_INTERRUPTION(); } RNG_END(); return IGRAPH_SUCCESS; } /** * \function igraph_random_spanning_tree * \brief Uniformly sample the spanning trees of a graph * * Performs a loop-erased random walk on the graph to uniformly sample * its spanning trees. Edge directions are ignored. * * * Multi-graphs are supported, and edge multiplicities will affect the sampling * frequency. For example, consider the 3-cycle graph 1=2-3-1, with two edges * between vertices 1 and 2. Due to these parallel edges, the trees 1-2-3 * and 3-1-2 will be sampled with multiplicity 2, while the tree * 2-3-1 will be sampled with multiplicity 1. * * \param graph The input graph. Edge directions are ignored. * \param res An initialized vector, the IDs of the edges that constitute * a spanning tree will be returned here. Use * \ref igraph_subgraph_edges() to extract the spanning tree as * a separate graph object. * \param vid This parameter is relevant if the graph is not connected. * If negative, a random spanning forest of all components will be * generated. Otherwise, it should be the ID of a vertex. A random * spanning tree of the component containing the vertex will be * generated. * * \return Error code. * * \sa \ref igraph_minimum_spanning_tree(), \ref igraph_random_walk() * */ int igraph_random_spanning_tree(const igraph_t *graph, igraph_vector_t *res, igraph_integer_t vid) { igraph_inclist_t il; igraph_vector_bool_t visited; igraph_integer_t vcount = igraph_vcount(graph); if (vid >= vcount) { IGRAPH_ERROR("Invalid vertex id given for random spanning tree", IGRAPH_EINVVID); } IGRAPH_CHECK(igraph_inclist_init(graph, &il, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &il); IGRAPH_CHECK(igraph_vector_bool_init(&visited, vcount)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &visited); igraph_vector_clear(res); if (vid < 0) { /* generate random spanning forest: consider each component separately */ igraph_vector_t membership, csize; igraph_integer_t comp_count; igraph_integer_t i; IGRAPH_VECTOR_INIT_FINALLY(&membership, 0); IGRAPH_VECTOR_INIT_FINALLY(&csize, 0); IGRAPH_CHECK(igraph_clusters(graph, &membership, &csize, &comp_count, IGRAPH_WEAK)); /* for each component ... */ for (i = 0; i < comp_count; ++i) { /* ... find a vertex to start the LERW from */ igraph_integer_t j = 0; while (VECTOR(membership)[j] != i) { ++j; } IGRAPH_CHECK(igraph_i_lerw(graph, res, j, (igraph_integer_t) VECTOR(csize)[i], &visited, &il)); } igraph_vector_destroy(&membership); igraph_vector_destroy(&csize); IGRAPH_FINALLY_CLEAN(2); } else { /* consider the component containing vid */ igraph_vector_t comp_vertices; igraph_integer_t comp_size; /* we measure the size of the component */ IGRAPH_VECTOR_INIT_FINALLY(&comp_vertices, 0); IGRAPH_CHECK(igraph_subcomponent(graph, &comp_vertices, vid, IGRAPH_ALL)); comp_size = (igraph_integer_t) igraph_vector_size(&comp_vertices); igraph_vector_destroy(&comp_vertices); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_i_lerw(graph, res, vid, comp_size, &visited, &il)); } igraph_vector_bool_destroy(&visited); igraph_inclist_destroy(&il); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } leidenbase/src/core/internal/0000755000176200001440000000000014532173045015704 5ustar liggesusersleidenbase/src/core/internal/glpk_support.c0000644000176200001440000001335714452066050020610 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "internal/glpk_support.h" #ifdef HAVE_GLPK #include "igraph_error.h" #include "core/interruption.h" #include IGRAPH_THREAD_LOCAL igraph_i_glpk_error_info_t igraph_i_glpk_error_info; /* glp_at_error() was added in GLPK 4.57. Due to the R interface, we need to * support ancient GLPK versions like GLPK 4.38 so we need to guard the * invocation of glp_at_error(). Note that this is a temporary workaround only * for sake of supporting R 4.1, so it is enabled only if USING_R is defined */ #ifdef USING_R # define HAS_GLP_AT_ERROR (GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION >= 57)) #else # define HAS_GLP_AT_ERROR 1 #endif int igraph_i_glpk_terminal_hook(void *info, const char *s) { IGRAPH_UNUSED(info); if (igraph_i_interruption_handler && !igraph_i_glpk_error_info.is_interrupted && igraph_allow_interruption(NULL) != IGRAPH_SUCCESS) { /* If an interruption has already occurred, do not set another error, to avoid an infinite loop between the term_hook (this function) and the error_hook. */ igraph_i_glpk_error_info.is_interrupted = 1; glp_error("GLPK was interrupted."); /* This dummy message is never printed */ #if HAS_GLP_AT_ERROR } else if (glp_at_error()) { /* Copy the error messages into a buffer for later reporting */ /* We must use glp_at_error() instead of igraph_i_glpk_error_info.is_error * to determine if a message is an error message, as the reporting function is * called before the error function. */ const size_t n = sizeof(igraph_i_glpk_error_info.msg) / sizeof(char) - 1; while (*s != '\0' && igraph_i_glpk_error_info.msg_ptr < igraph_i_glpk_error_info.msg + n) { *(igraph_i_glpk_error_info.msg_ptr++) = *(s++); } *igraph_i_glpk_error_info.msg_ptr = '\0'; #endif } return 1; /* Non-zero return value signals to GLPK not to print to the terminal */ } void igraph_i_glpk_error_hook(void *info) { IGRAPH_UNUSED(info); igraph_i_glpk_error_info.is_error = 1; glp_free_env(); longjmp(igraph_i_glpk_error_info.jmp, 1); } void igraph_i_glpk_interruption_hook(glp_tree *tree, void *info) { IGRAPH_UNUSED(info); /* This is a callback function meant to be used with glp_intopt(), in order to support interruption. It is essentially a GLPK-compatible replacement for IGRAPH_ALLOW_INTERRUPTION(). Calling glp_ios_terminate() from glp_intopt()'s callback function signals to GLPK that it should terminate the optimization and return with the code GLP_ESTOP. */ if (igraph_i_interruption_handler) { if (igraph_allow_interruption(NULL) != IGRAPH_SUCCESS) { glp_ios_terminate(tree); } } } /** * \ingroup internal * \function igraph_i_glp_delete_prob * \brief Safe replacement for glp_delete_prob(). * * This function is meant to be used with IGRAPH_FINALLY() * in conjunction with glp_create_prob(). * * When using GLPK, normally glp_delete_prob() is used to free * problems created with glp_create_prob(). However, when GLPK * encounters an error, the error handler installed by igraph * will call glp_free_env() which invalidates all problems. * Calling glp_delete_prob() would then lead to a crash. * This replacement function avoids this situation by first * checking if GLPK is at an error state. */ void igraph_i_glp_delete_prob(glp_prob *p) { if (! igraph_i_glpk_error_info.is_error) { glp_delete_prob(p); } } int igraph_i_glpk_check(int retval, const char* message) { char* code = "none"; char message_and_code[4096]; if (retval == IGRAPH_SUCCESS) { return IGRAPH_SUCCESS; } /* handle errors */ #define HANDLE_CODE(c) case c: code = #c; retval = IGRAPH_##c; break; #define HANDLE_CODE2(c) case c: code = #c; retval = IGRAPH_FAILURE; break; #define HANDLE_CODE3(c) case c: code = #c; retval = IGRAPH_INTERRUPTED; break; switch (retval) { HANDLE_CODE(GLP_EBOUND); HANDLE_CODE(GLP_EROOT); HANDLE_CODE(GLP_ENOPFS); HANDLE_CODE(GLP_ENODFS); HANDLE_CODE(GLP_EFAIL); HANDLE_CODE(GLP_EMIPGAP); HANDLE_CODE(GLP_ETMLIM); HANDLE_CODE3(GLP_ESTOP); HANDLE_CODE2(GLP_EBADB); HANDLE_CODE2(GLP_ESING); HANDLE_CODE2(GLP_ECOND); HANDLE_CODE2(GLP_EOBJLL); HANDLE_CODE2(GLP_EOBJUL); HANDLE_CODE2(GLP_EITLIM); default: IGRAPH_ERROR("Unknown GLPK error", IGRAPH_FAILURE); } #undef HANDLE_CODE #undef HANDLE_CODE2 #undef HANDLE_CODE3 snprintf(message_and_code, (size_t)4096, "%s (%s)", message, code); IGRAPH_ERROR(message_and_code, retval); } #else int igraph_glpk_dummy() { /* get rid of "ISO C requires a translation unit to contain at least one * declaration" warning */ return 'd' + 'u' + 'm' + 'm' + 'y'; } #endif leidenbase/src/core/internal/hacks.h0000644000176200001440000000310514447675374017166 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_HACKS_INTERNAL_H #define IGRAPH_HACKS_INTERNAL_H #include "config.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS /* empty */ #define __END_DECLS /* empty */ #endif __BEGIN_DECLS #ifndef HAVE_STRDUP #define strdup igraph_i_strdup char* igraph_i_strdup(const char *s); #endif #ifndef HAVE_STPCPY #define stpcpy igraph_i_stpcpy char* igraph_i_stpcpy(char* s1, const char* s2); #endif #ifndef HAVE_STRCASECMP #ifdef HAVE__STRICMP #define strcasecmp _stricmp #else #error "igraph needs strcasecmp() or _stricmp()" #endif #endif __END_DECLS #endif leidenbase/src/core/internal/pstdint.h0000644000176200001440000007244214447675374017574 0ustar liggesusers/* A portable stdint.h **************************************************************************** * BSD License: **************************************************************************** * * Copyright (c) 2005-2007 Paul Hsieh * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * **************************************************************************** * * Version 0.1.11 * * The ANSI C standard committee, for the C99 standard, specified the * inclusion of a new standard include file called stdint.h. This is * a very useful and long desired include file which contains several * very precise definitions for integer scalar types that is * critically important for making portable several classes of * applications including cryptography, hashing, variable length * integer libraries and so on. But for most developers its likely * useful just for programming sanity. * * The problem is that most compiler vendors have decided not to * implement the C99 standard, and the next C++ language standard * (which has a lot more mindshare these days) will be a long time in * coming and its unknown whether or not it will include stdint.h or * how much adoption it will have. Either way, it will be a long time * before all compilers come with a stdint.h and it also does nothing * for the extremely large number of compilers available today which * do not include this file, or anything comparable to it. * * So that's what this file is all about. Its an attempt to build a * single universal include file that works on as many platforms as * possible to deliver what stdint.h is supposed to. A few things * that should be noted about this file: * * 1) It is not guaranteed to be portable and/or present an identical * interface on all platforms. The extreme variability of the * ANSI C standard makes this an impossibility right from the * very get go. Its really only meant to be useful for the vast * majority of platforms that possess the capability of * implementing usefully and precisely defined, standard sized * integer scalars. Systems which are not intrinsically 2s * complement may produce invalid constants. * * 2) There is an unavoidable use of non-reserved symbols. * * 3) Other standard include files are invoked. * * 4) This file may come in conflict with future platforms that do * include stdint.h. The hope is that one or the other can be * used with no real difference. * * 5) In the current verison, if your platform can't represent * int32_t, int16_t and int8_t, it just dumps out with a compiler * error. * * 6) 64 bit integers may or may not be defined. Test for their * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX. * Note that this is different from the C99 specification which * requires the existence of 64 bit support in the compiler. If * this is not defined for your platform, yet it is capable of * dealing with 64 bits then it is because this file has not yet * been extended to cover all of your system's capabilities. * * 7) (u)intptr_t may or may not be defined. Test for its presence * with the test: #ifdef PTRDIFF_MAX. If this is not defined * for your platform, then it is because this file has not yet * been extended to cover all of your system's capabilities, not * because its optional. * * 8) The following might not been defined even if your platform is * capable of defining it: * * WCHAR_MIN * WCHAR_MAX * (u)int64_t * PTRDIFF_MIN * PTRDIFF_MAX * (u)intptr_t * * 9) The following have not been defined: * * WINT_MIN * WINT_MAX * * 10) The criteria for defining (u)int_least(*)_t isn't clear, * except for systems which don't have a type that precisely * defined 8, 16, or 32 bit types (which this include file does * not support anyways). Default definitions have been given. * * 11) The criteria for defining (u)int_fast(*)_t isn't something I * would trust to any particular compiler vendor or the ANSI C * committee. It is well known that "compatible systems" are * commonly created that have very different performance * characteristics from the systems they are compatible with, * especially those whose vendors make both the compiler and the * system. Default definitions have been given, but its strongly * recommended that users never use these definitions for any * reason (they do *NOT* deliver any serious guarantee of * improved performance -- not in this file, nor any vendor's * stdint.h). * * 12) The following macros: * * PRINTF_INTMAX_MODIFIER * PRINTF_INT64_MODIFIER * PRINTF_INT32_MODIFIER * PRINTF_INT16_MODIFIER * PRINTF_LEAST64_MODIFIER * PRINTF_LEAST32_MODIFIER * PRINTF_LEAST16_MODIFIER * PRINTF_INTPTR_MODIFIER * * are strings which have been defined as the modifiers required * for the "d", "u" and "x" printf formats to correctly output * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t, * (u)least32_t, (u)least16_t and (u)intptr_t types respectively. * PRINTF_INTPTR_MODIFIER is not defined for some systems which * provide their own stdint.h. PRINTF_INT64_MODIFIER is not * defined if INT64_MAX is not defined. These are an extension * beyond what C99 specifies must be in stdint.h. * * In addition, the following macros are defined: * * PRINTF_INTMAX_HEX_WIDTH * PRINTF_INT64_HEX_WIDTH * PRINTF_INT32_HEX_WIDTH * PRINTF_INT16_HEX_WIDTH * PRINTF_INT8_HEX_WIDTH * PRINTF_INTMAX_DEC_WIDTH * PRINTF_INT64_DEC_WIDTH * PRINTF_INT32_DEC_WIDTH * PRINTF_INT16_DEC_WIDTH * PRINTF_INT8_DEC_WIDTH * * Which specifies the maximum number of characters required to * print the number of that type in either hexadecimal or decimal. * These are an extension beyond what C99 specifies must be in * stdint.h. * * Compilers tested (all with 0 warnings at their highest respective * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32 * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3 * * This file should be considered a work in progress. Suggestions for * improvements, especially those which increase coverage are strongly * encouraged. * * Acknowledgements * * The following people have made significant contributions to the * development and testing of this file: * * Chris Howie * John Steele Scott * Dave Thorup * */ #include #include #include /* * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. */ #if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) )) && !defined (_PSTDINT_H_INCLUDED) #include #define _PSTDINT_H_INCLUDED #ifndef PRINTF_INT64_MODIFIER #define PRINTF_INT64_MODIFIER "ll" #endif #ifndef PRINTF_INT32_MODIFIER #define PRINTF_INT32_MODIFIER "l" #endif #ifndef PRINTF_INT16_MODIFIER #define PRINTF_INT16_MODIFIER "h" #endif #ifndef PRINTF_INTMAX_MODIFIER #define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER #endif #ifndef PRINTF_INT64_HEX_WIDTH #define PRINTF_INT64_HEX_WIDTH "16" #endif #ifndef PRINTF_INT32_HEX_WIDTH #define PRINTF_INT32_HEX_WIDTH "8" #endif #ifndef PRINTF_INT16_HEX_WIDTH #define PRINTF_INT16_HEX_WIDTH "4" #endif #ifndef PRINTF_INT8_HEX_WIDTH #define PRINTF_INT8_HEX_WIDTH "2" #endif #ifndef PRINTF_INT64_DEC_WIDTH #define PRINTF_INT64_DEC_WIDTH "20" #endif #ifndef PRINTF_INT32_DEC_WIDTH #define PRINTF_INT32_DEC_WIDTH "10" #endif #ifndef PRINTF_INT16_DEC_WIDTH #define PRINTF_INT16_DEC_WIDTH "5" #endif #ifndef PRINTF_INT8_DEC_WIDTH #define PRINTF_INT8_DEC_WIDTH "3" #endif #ifndef PRINTF_INTMAX_HEX_WIDTH #define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH #endif #ifndef PRINTF_INTMAX_DEC_WIDTH #define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH #endif /* * Something really weird is going on with Open Watcom. Just pull some of * these duplicated definitions from Open Watcom's stdint.h file for now. */ #if defined (__WATCOMC__) && __WATCOMC__ >= 1250 #if !defined (INT64_C) #define INT64_C(x) (x + (INT64_MAX - INT64_MAX)) #endif #if !defined (UINT64_C) #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) #endif #if !defined (INT32_C) #define INT32_C(x) (x + (INT32_MAX - INT32_MAX)) #endif #if !defined (UINT32_C) #define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX)) #endif #if !defined (INT16_C) #define INT16_C(x) (x) #endif #if !defined (UINT16_C) #define UINT16_C(x) (x) #endif #if !defined (INT8_C) #define INT8_C(x) (x) #endif #if !defined (UINT8_C) #define UINT8_C(x) (x) #endif #if !defined (UINT64_MAX) #define UINT64_MAX 18446744073709551615ULL #endif #if !defined (INT64_MAX) #define INT64_MAX 9223372036854775807LL #endif #if !defined (UINT32_MAX) #define UINT32_MAX 4294967295UL #endif #if !defined (INT32_MAX) #define INT32_MAX 2147483647L #endif #if !defined (INTMAX_MAX) #define INTMAX_MAX INT64_MAX #endif #if !defined (INTMAX_MIN) #define INTMAX_MIN INT64_MIN #endif #endif #endif #ifndef _PSTDINT_H_INCLUDED #define _PSTDINT_H_INCLUDED #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif /* * Deduce the type assignments from limits.h under the assumption that * integer sizes in bits are powers of 2, and follow the ANSI * definitions. */ #ifndef UINT8_MAX #define UINT8_MAX 0xff #endif #ifndef uint8_t #if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S) typedef unsigned char uint8_t; #define UINT8_C(v) ((uint8_t) v) #else # error "Platform not supported" #endif #endif #ifndef INT8_MAX #define INT8_MAX 0x7f #endif #ifndef INT8_MIN #define INT8_MIN INT8_C(0x80) #endif #ifndef int8_t #if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S) typedef signed char int8_t; #define INT8_C(v) ((int8_t) v) #else # error "Platform not supported" #endif #endif #ifndef UINT16_MAX #define UINT16_MAX 0xffff #endif #ifndef uint16_t #if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S) typedef unsigned int uint16_t; #ifndef PRINTF_INT16_MODIFIER #define PRINTF_INT16_MODIFIER "" #endif #define UINT16_C(v) ((uint16_t) (v)) #elif (USHRT_MAX == UINT16_MAX) typedef unsigned short uint16_t; #define UINT16_C(v) ((uint16_t) (v)) #ifndef PRINTF_INT16_MODIFIER #define PRINTF_INT16_MODIFIER "h" #endif #else #error "Platform not supported" #endif #endif #ifndef INT16_MAX #define INT16_MAX 0x7fff #endif #ifndef INT16_MIN #define INT16_MIN INT16_C(0x8000) #endif #ifndef int16_t #if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S) typedef signed int int16_t; #define INT16_C(v) ((int16_t) (v)) #ifndef PRINTF_INT16_MODIFIER #define PRINTF_INT16_MODIFIER "" #endif #elif (SHRT_MAX == INT16_MAX) typedef signed short int16_t; #define INT16_C(v) ((int16_t) (v)) #ifndef PRINTF_INT16_MODIFIER #define PRINTF_INT16_MODIFIER "h" #endif #else #error "Platform not supported" #endif #endif #ifndef UINT32_MAX #define UINT32_MAX (0xffffffffUL) #endif #ifndef uint32_t #if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S) typedef unsigned long uint32_t; #define UINT32_C(v) v ## UL #ifndef PRINTF_INT32_MODIFIER #define PRINTF_INT32_MODIFIER "l" #endif #elif (UINT_MAX == UINT32_MAX) typedef unsigned int uint32_t; #ifndef PRINTF_INT32_MODIFIER #define PRINTF_INT32_MODIFIER "" #endif #define UINT32_C(v) v ## U #elif (USHRT_MAX == UINT32_MAX) typedef unsigned short uint32_t; #define UINT32_C(v) ((unsigned short) (v)) #ifndef PRINTF_INT32_MODIFIER #define PRINTF_INT32_MODIFIER "" #endif #else #error "Platform not supported" #endif #endif #ifndef INT32_MAX #define INT32_MAX (0x7fffffffL) #endif #ifndef INT32_MIN #define INT32_MIN INT32_C(0x80000000) #endif #ifndef int32_t #if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S) typedef signed long int32_t; #define INT32_C(v) v ## L #ifndef PRINTF_INT32_MODIFIER #define PRINTF_INT32_MODIFIER "l" #endif #elif (INT_MAX == INT32_MAX) typedef signed int int32_t; #define INT32_C(v) v #ifndef PRINTF_INT32_MODIFIER #define PRINTF_INT32_MODIFIER "" #endif #elif (SHRT_MAX == INT32_MAX) typedef signed short int32_t; #define INT32_C(v) ((short) (v)) #ifndef PRINTF_INT32_MODIFIER #define PRINTF_INT32_MODIFIER "" #endif #else #error "Platform not supported" #endif #endif /* * The macro stdint_int64_defined is temporarily used to record * whether or not 64 integer support is available. It must be * defined for any 64 integer extensions for new platforms that are * added. */ #undef stdint_int64_defined #if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S) #if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S) #define stdint_int64_defined typedef long long int64_t; typedef unsigned long long uint64_t; #define UINT64_C(v) v ## ULL #define INT64_C(v) v ## LL #ifndef PRINTF_INT64_MODIFIER #define PRINTF_INT64_MODIFIER "ll" #endif #endif #endif #if !defined (stdint_int64_defined) #if defined(__GNUC__) #define stdint_int64_defined __extension__ typedef long long int64_t; __extension__ typedef unsigned long long uint64_t; #define UINT64_C(v) v ## ULL #define INT64_C(v) v ## LL #ifndef PRINTF_INT64_MODIFIER #define PRINTF_INT64_MODIFIER "ll" #endif #elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S) #define stdint_int64_defined typedef long long int64_t; typedef unsigned long long uint64_t; #define UINT64_C(v) v ## ULL #define INT64_C(v) v ## LL #ifndef PRINTF_INT64_MODIFIER #define PRINTF_INT64_MODIFIER "ll" #endif #elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC) #define stdint_int64_defined typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #define UINT64_C(v) v ## UI64 #define INT64_C(v) v ## I64 #ifndef PRINTF_INT64_MODIFIER #define PRINTF_INT64_MODIFIER "I64" #endif #endif #endif #if !defined (LONG_LONG_MAX) && defined (INT64_C) #define LONG_LONG_MAX INT64_C (9223372036854775807) #endif #ifndef ULONG_LONG_MAX #define ULONG_LONG_MAX UINT64_C (18446744073709551615) #endif #if !defined (INT64_MAX) && defined (INT64_C) #define INT64_MAX INT64_C (9223372036854775807) #endif #if !defined (INT64_MIN) && defined (INT64_C) #define INT64_MIN INT64_C (-9223372036854775808) #endif #if !defined (UINT64_MAX) && defined (INT64_C) #define UINT64_MAX UINT64_C (18446744073709551615) #endif /* * Width of hexadecimal for number field. */ #ifndef PRINTF_INT64_HEX_WIDTH #define PRINTF_INT64_HEX_WIDTH "16" #endif #ifndef PRINTF_INT32_HEX_WIDTH #define PRINTF_INT32_HEX_WIDTH "8" #endif #ifndef PRINTF_INT16_HEX_WIDTH #define PRINTF_INT16_HEX_WIDTH "4" #endif #ifndef PRINTF_INT8_HEX_WIDTH #define PRINTF_INT8_HEX_WIDTH "2" #endif #ifndef PRINTF_INT64_DEC_WIDTH #define PRINTF_INT64_DEC_WIDTH "20" #endif #ifndef PRINTF_INT32_DEC_WIDTH #define PRINTF_INT32_DEC_WIDTH "10" #endif #ifndef PRINTF_INT16_DEC_WIDTH #define PRINTF_INT16_DEC_WIDTH "5" #endif #ifndef PRINTF_INT8_DEC_WIDTH #define PRINTF_INT8_DEC_WIDTH "3" #endif /* * Ok, lets not worry about 128 bit integers for now. Moore's law says * we don't need to worry about that until about 2040 at which point * we'll have bigger things to worry about. */ #ifdef stdint_int64_defined typedef int64_t intmax_t; typedef uint64_t uintmax_t; #define INTMAX_MAX INT64_MAX #define INTMAX_MIN INT64_MIN #define UINTMAX_MAX UINT64_MAX #define UINTMAX_C(v) UINT64_C(v) #define INTMAX_C(v) INT64_C(v) #ifndef PRINTF_INTMAX_MODIFIER #define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER #endif #ifndef PRINTF_INTMAX_HEX_WIDTH #define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH #endif #ifndef PRINTF_INTMAX_DEC_WIDTH #define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH #endif #else typedef int32_t intmax_t; typedef uint32_t uintmax_t; #define INTMAX_MAX INT32_MAX #define UINTMAX_MAX UINT32_MAX #define UINTMAX_C(v) UINT32_C(v) #define INTMAX_C(v) INT32_C(v) #ifndef PRINTF_INTMAX_MODIFIER #define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER #endif #ifndef PRINTF_INTMAX_HEX_WIDTH #define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH #endif #ifndef PRINTF_INTMAX_DEC_WIDTH #define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH #endif #endif /* * Because this file currently only supports platforms which have * precise powers of 2 as bit sizes for the default integers, the * least definitions are all trivial. Its possible that a future * version of this file could have different definitions. */ #ifndef stdint_least_defined typedef int8_t int_least8_t; typedef uint8_t uint_least8_t; typedef int16_t int_least16_t; typedef uint16_t uint_least16_t; typedef int32_t int_least32_t; typedef uint32_t uint_least32_t; #define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER #define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER #define UINT_LEAST8_MAX UINT8_MAX #define INT_LEAST8_MAX INT8_MAX #define UINT_LEAST16_MAX UINT16_MAX #define INT_LEAST16_MAX INT16_MAX #define UINT_LEAST32_MAX UINT32_MAX #define INT_LEAST32_MAX INT32_MAX #define INT_LEAST8_MIN INT8_MIN #define INT_LEAST16_MIN INT16_MIN #define INT_LEAST32_MIN INT32_MIN #ifdef stdint_int64_defined typedef int64_t int_least64_t; typedef uint64_t uint_least64_t; #define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER #define UINT_LEAST64_MAX UINT64_MAX #define INT_LEAST64_MAX INT64_MAX #define INT_LEAST64_MIN INT64_MIN #endif #endif #undef stdint_least_defined /* * The ANSI C committee pretending to know or specify anything about * performance is the epitome of misguided arrogance. The mandate of * this file is to *ONLY* ever support that absolute minimum * definition of the fast integer types, for compatibility purposes. * No extensions, and no attempt to suggest what may or may not be a * faster integer type will ever be made in this file. Developers are * warned to stay away from these types when using this or any other * stdint.h. */ typedef int_least8_t int_fast8_t; typedef uint_least8_t uint_fast8_t; typedef int_least16_t int_fast16_t; typedef uint_least16_t uint_fast16_t; typedef int_least32_t int_fast32_t; typedef uint_least32_t uint_fast32_t; #define UINT_FAST8_MAX UINT_LEAST8_MAX #define INT_FAST8_MAX INT_LEAST8_MAX #define UINT_FAST16_MAX UINT_LEAST16_MAX #define INT_FAST16_MAX INT_LEAST16_MAX #define UINT_FAST32_MAX UINT_LEAST32_MAX #define INT_FAST32_MAX INT_LEAST32_MAX #define INT_FAST8_MIN INT_LEAST8_MIN #define INT_FAST16_MIN INT_LEAST16_MIN #define INT_FAST32_MIN INT_LEAST32_MIN #ifdef stdint_int64_defined typedef int_least64_t int_fast64_t; typedef uint_least64_t uint_fast64_t; #define UINT_FAST64_MAX UINT_LEAST64_MAX #define INT_FAST64_MAX INT_LEAST64_MAX #define INT_FAST64_MIN INT_LEAST64_MIN #endif #undef stdint_int64_defined /* * Whatever piecemeal, per compiler thing we can do about the wchar_t * type limits. */ #if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) #include #ifndef WCHAR_MIN #define WCHAR_MIN 0 #endif #ifndef WCHAR_MAX #define WCHAR_MAX ((wchar_t)-1) #endif #endif /* * Whatever piecemeal, per compiler/platform thing we can do about the * (u)intptr_t types and limits. */ #if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED) #define STDINT_H_UINTPTR_T_DEFINED #endif #ifndef STDINT_H_UINTPTR_T_DEFINED #if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) #define stdint_intptr_bits 64 #elif defined (__WATCOMC__) || defined (__TURBOC__) #if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) #define stdint_intptr_bits 16 #else #define stdint_intptr_bits 32 #endif #elif defined (__i386__) || defined (_WIN32) || defined (WIN32) #define stdint_intptr_bits 32 #elif defined (__INTEL_COMPILER) /* TODO -- what will Intel do about x86-64? */ #endif #ifdef stdint_intptr_bits #define stdint_intptr_glue3_i(a,b,c) a##b##c #define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c) #ifndef PRINTF_INTPTR_MODIFIER #define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER) #endif #ifndef PTRDIFF_MAX #define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) #endif #ifndef PTRDIFF_MIN #define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) #endif #ifndef UINTPTR_MAX #define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX) #endif #ifndef INTPTR_MAX #define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) #endif #ifndef INTPTR_MIN #define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) #endif #ifndef INTPTR_C #define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x) #endif #ifndef UINTPTR_C #define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x) #endif typedef stdint_intptr_glue3(uint, stdint_intptr_bits, _t) uintptr_t; typedef stdint_intptr_glue3( int, stdint_intptr_bits, _t) intptr_t; #else /* TODO -- This following is likely wrong for some platforms, and does nothing for the definition of uintptr_t. */ typedef ptrdiff_t intptr_t; #endif #define STDINT_H_UINTPTR_T_DEFINED #endif /* * Assumes sig_atomic_t is signed and we have a 2s complement machine. */ #ifndef SIG_ATOMIC_MAX #define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1) #endif #endif #if defined (__TEST_PSTDINT_FOR_CORRECTNESS) /* * Please compile with the maximum warning settings to make sure macros are not * defined more than once. */ #include #include #include #define glue3_aux(x,y,z) x ## y ## z #define glue3(x,y,z) glue3_aux(x,y,z) #define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,=) glue3(UINT,bits,_C) (0); #define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,=) glue3(INT,bits,_C) (0); #define DECL(us,bits) glue3(DECL,us,) (bits) #define TESTUMAX(bits) glue3(u,bits,=) glue3(~,u,bits); if (glue3(UINT,bits,_MAX) glue3(!=,u,bits)) printf ("Something wrong with UINT%d_MAX\n", bits) int main () { DECL(I, 8) DECL(U, 8) DECL(I, 16) DECL(U, 16) DECL(I, 32) DECL(U, 32) #ifdef INT64_MAX DECL(I, 64) DECL(U, 64) #endif intmax_t imax = INTMAX_C(0); uintmax_t umax = UINTMAX_C(0); char str0[256], str1[256]; sprintf (str0, "%d %x\n", 0, ~0); sprintf (str1, "%d %x\n", i8, ~0); if (0 != strcmp (str0, str1)) { printf ("Something wrong with i8 : %s\n", str1); } sprintf (str1, "%u %x\n", u8, ~0); if (0 != strcmp (str0, str1)) { printf ("Something wrong with u8 : %s\n", str1); } sprintf (str1, "%d %x\n", i16, ~0); if (0 != strcmp (str0, str1)) { printf ("Something wrong with i16 : %s\n", str1); } sprintf (str1, "%u %x\n", u16, ~0); if (0 != strcmp (str0, str1)) { printf ("Something wrong with u16 : %s\n", str1); } sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0); if (0 != strcmp (str0, str1)) { printf ("Something wrong with i32 : %s\n", str1); } sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0); if (0 != strcmp (str0, str1)) { printf ("Something wrong with u32 : %s\n", str1); } #ifdef INT64_MAX sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0); if (0 != strcmp (str0, str1)) { printf ("Something wrong with i64 : %s\n", str1); } #endif sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0); if (0 != strcmp (str0, str1)) { printf ("Something wrong with imax : %s\n", str1); } sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0); if (0 != strcmp (str0, str1)) { printf ("Something wrong with umax : %s\n", str1); } TESTUMAX(8); TESTUMAX(16); TESTUMAX(32); #ifdef INT64_MAX TESTUMAX(64); #endif return EXIT_SUCCESS; } #endif leidenbase/src/core/internal/qsort.c0000644000176200001440000001573514447675374017254 0ustar liggesusers/*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* This file originates from the following URL: * * https://cgit.freebsd.org/src/commit/lib/libc/stdlib/qsort.c?id=7f8f79a5c444a565a32b0c6578b07f8d496f6c49 * * Create a diff against the revision given above to see what we have changed * to facilitate inclusion into igraph */ #include "igraph_qsort.h" #ifdef _MSC_VER /* MSVC does not have inline when compiling C source files */ #define inline __inline #define __unused #endif #ifndef __unused #define __unused __attribute__ ((unused)) #endif #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #if defined(I_AM_QSORT_R) typedef int cmp_t(void *, const void *, const void *); #elif defined(I_AM_QSORT_S) typedef int cmp_t(const void *, const void *, void *); #else typedef int cmp_t(const void *, const void *); #endif static inline char *med3(char *, char *, char *, cmp_t *, void *); #define MIN(a, b) ((a) < (b) ? a : b) /* * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". */ static inline void swapfunc(char *a, char *b, size_t es) { char t; do { t = *a; *a++ = *b; *b++ = t; } while (--es > 0); } #define vecswap(a, b, n) \ if ((n) > 0) swapfunc(a, b, n) #if defined(I_AM_QSORT_R) #define CMP(t, x, y) (cmp((t), (x), (y))) #elif defined(I_AM_QSORT_S) #define CMP(t, x, y) (cmp((x), (y), (t))) #else #define CMP(t, x, y) (cmp((x), (y))) #endif static inline char * med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk #if !defined(I_AM_QSORT_R) && !defined(I_AM_QSORT_S) __unused #endif ) { return CMP(thunk, a, b) < 0 ? (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); } /* * The actual qsort() implementation is static to avoid preemptible calls when * recursing. Also give them different names for improved debugging. */ #if defined(I_AM_QSORT_R) #define local_qsort local_qsort_r #elif defined(I_AM_QSORT_S) #define local_qsort local_qsort_s #endif static void local_qsort(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk) { char *pa, *pb, *pc, *pd, *pl, *pm, *pn; size_t d1, d2; int cmp_result; int swap_cnt; loop: swap_cnt = 0; if (n < 7) { for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; pl -= es) swapfunc(pl, pl - es, es); return; } pm = (char *)a + (n / 2) * es; if (n > 7) { pl = a; pn = (char *)a + (n - 1) * es; if (n > 40) { size_t d = (n / 8) * es; pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); pm = med3(pm - d, pm, pm + d, cmp, thunk); pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); } pm = med3(pl, pm, pn, cmp, thunk); } swapfunc(a, pm, es); pa = pb = (char *)a + es; pc = pd = (char *)a + (n - 1) * es; for (;;) { while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) { if (cmp_result == 0) { swap_cnt = 1; swapfunc(pa, pb, es); pa += es; } pb += es; } while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) { if (cmp_result == 0) { swap_cnt = 1; swapfunc(pc, pd, es); pd -= es; } pc -= es; } if (pb > pc) break; swapfunc(pb, pc, es); swap_cnt = 1; pb += es; pc -= es; } if (swap_cnt == 0) { /* Switch to insertion sort */ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; pl -= es) swapfunc(pl, pl - es, es); return; } pn = (char *)a + n * es; d1 = MIN(pa - (char *)a, pb - pa); vecswap(a, pb - d1, d1); /* * Cast es to preserve signedness of right-hand side of MIN() * expression, to avoid sign ambiguity in the implied comparison. es * is safely within [0, SSIZE_MAX]. */ d1 = MIN(pd - pc, pn - pd - (ptrdiff_t)es); vecswap(pb, pn - d1, d1); d1 = pb - pa; d2 = pd - pc; if (d1 <= d2) { /* Recurse on left partition, then iterate on right partition */ if (d1 > es) { local_qsort(a, d1 / es, es, cmp, thunk); } if (d2 > es) { /* Iterate rather than recurse to save stack space */ /* qsort(pn - d2, d2 / es, es, cmp); */ a = pn - d2; n = d2 / es; goto loop; } } else { /* Recurse on right partition, then iterate on left partition */ if (d2 > es) { local_qsort(pn - d2, d2 / es, es, cmp, thunk); } if (d1 > es) { /* Iterate rather than recurse to save stack space */ /* qsort(a, d1 / es, es, cmp); */ n = d1 / es; goto loop; } } } #if defined(I_AM_QSORT_R) void igraph_qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) { local_qsort_r(a, n, es, cmp, thunk); } #elif defined(I_AM_QSORT_S) errno_t igraph_qsort_s(void *a, rsize_t n, rsize_t es, cmp_t *cmp, void *thunk) { if (n > RSIZE_MAX) { __throw_constraint_handler_s("qsort_s : n > RSIZE_MAX", EINVAL); return (EINVAL); } else if (es > RSIZE_MAX) { __throw_constraint_handler_s("qsort_s : es > RSIZE_MAX", EINVAL); return (EINVAL); } else if (n != 0) { if (a == NULL) { __throw_constraint_handler_s("qsort_s : a == NULL", EINVAL); return (EINVAL); } else if (cmp == NULL) { __throw_constraint_handler_s("qsort_s : cmp == NULL", EINVAL); return (EINVAL); } } local_qsort_s(a, n, es, cmp, thunk); return (0); } #else void igraph_qsort(void *a, size_t n, size_t es, cmp_t *cmp) { local_qsort(a, n, es, cmp, NULL); } #endif leidenbase/src/core/internal/qsort_r.c0000644000176200001440000000033114447675374017557 0ustar liggesusers/* * This file is in the public domain. Originally written by Garrett * A. Wollman. * * $FreeBSD: src/lib/libc/stdlib/qsort_r.c,v 1.1 2002/09/10 02:04:49 wollman Exp $ */ #define I_AM_QSORT_R #include "qsort.c" leidenbase/src/core/internal/zeroin.c0000644000176200001440000001743214447675374017406 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* from GNU R's zeroin.c, minor modifications by Gabor Csardi */ /* from NETLIB c/brent.shar with max.iter, add'l info and convergence details hacked in by Peter Dalgaard */ /************************************************************************* * C math library * function ZEROIN - obtain a function zero within the given range * * Input * double zeroin(ax,bx,f,info,Tol,Maxit) * double ax; Root will be seeked for within * double bx; a range [ax,bx] * double (*f)(double x, void *info); Name of the function whose zero * will be seeked for * void *info; Add'l info passed to f * double *Tol; Acceptable tolerance for the root * value. * May be specified as 0.0 to cause * the program to find the root as * accurate as possible * * int *Maxit; Max. iterations * * * Output * Zeroin returns an estimate for the root with accuracy * 4*EPSILON*abs(x) + tol * *Tol returns estimated precision * *Maxit returns actual # of iterations, or -1 if maxit was * reached without convergence. * * Algorithm * G.Forsythe, M.Malcolm, C.Moler, Computer methods for mathematical * computations. M., Mir, 1980, p.180 of the Russian edition * * The function makes use of the bisection procedure combined with * the linear or quadric inverse interpolation. * At every step program operates on three abscissae - a, b, and c. * b - the last and the best approximation to the root * a - the last but one approximation * c - the last but one or even earlier approximation than a that * 1) |f(b)| <= |f(c)| * 2) f(b) and f(c) have opposite signs, i.e. b and c confine * the root * At every step Zeroin selects one of the two new approximations, the * former being obtained by the bisection procedure and the latter * resulting in the interpolation (if a,b, and c are all different * the quadric interpolation is utilized, otherwise the linear one). * If the latter (i.e. obtained by the interpolation) point is * reasonable (i.e. lies within the current interval [b,c] not being * too close to the boundaries) it is accepted. The bisection result * is used in the other case. Therefore, the range of uncertainty is * ensured to be reduced at least by the factor 1.6 * ************************************************************************ */ #include "igraph_nongraph.h" #include "igraph_types.h" #include "core/interruption.h" #include #include #define EPSILON DBL_EPSILON int igraph_zeroin( /* An estimate of the root */ igraph_real_t *ax, /* Left border | of the range */ igraph_real_t *bx, /* Right border| the root is seeked*/ igraph_real_t (*f)(igraph_real_t x, void *info), /* Function under investigation */ void *info, /* Add'l info passed on to f */ igraph_real_t *Tol, /* Acceptable tolerance */ int *Maxit, /* Max # of iterations */ igraph_real_t *res) { /* Result is stored here */ igraph_real_t a, b, c, /* Abscissae, descr. see above */ fa, fb, fc; /* f(a), f(b), f(c) */ igraph_real_t tol; int maxit; a = *ax; b = *bx; fa = (*f)(a, info); fb = (*f)(b, info); c = a; fc = fa; maxit = *Maxit + 1; tol = * Tol; /* First test if we have found a root at an endpoint */ if (fa == 0.0) { *Tol = 0.0; *Maxit = 0; *res = a; return 0; } if (fb == 0.0) { *Tol = 0.0; *Maxit = 0; *res = b; return 0; } while (maxit--) { /* Main iteration loop */ igraph_real_t prev_step = b - a; /* Distance from the last but one to the last approximation */ igraph_real_t tol_act; /* Actual tolerance */ igraph_real_t p; /* Interpolation step is calcu- */ igraph_real_t q; /* lated in the form p/q; divi- * sion operations is delayed * until the last moment */ igraph_real_t new_step; /* Step at this iteration */ IGRAPH_ALLOW_INTERRUPTION(); if ( fabs(fc) < fabs(fb) ) { /* Swap data for b to be the */ a = b; b = c; c = a; /* best approximation */ fa = fb; fb = fc; fc = fa; } tol_act = 2 * EPSILON * fabs(b) + tol / 2; new_step = (c - b) / 2; if ( fabs(new_step) <= tol_act || fb == (igraph_real_t)0 ) { *Maxit -= maxit; *Tol = fabs(c - b); *res = b; return 0; /* Acceptable approx. is found */ } /* Decide if the interpolation can be tried */ if ( fabs(prev_step) >= tol_act /* If prev_step was large enough*/ && fabs(fa) > fabs(fb) ) { /* and was in true direction, * Interpolation may be tried */ register igraph_real_t t1, cb, t2; cb = c - b; if ( a == c ) { /* If we have only two distinct */ /* points linear interpolation */ t1 = fb / fa; /* can only be applied */ p = cb * t1; q = 1.0 - t1; } else { /* Quadric inverse interpolation*/ q = fa / fc; t1 = fb / fc; t2 = fb / fa; p = t2 * ( cb * q * (q - t1) - (b - a) * (t1 - 1.0) ); q = (q - 1.0) * (t1 - 1.0) * (t2 - 1.0); } if ( p > (igraph_real_t)0 ) { /* p was calculated with the */ q = -q; /* opposite sign; make p positive */ } else { /* and assign possible minus to */ p = -p; /* q */ } if ( p < (0.75 * cb * q - fabs(tol_act * q) / 2) /* If b+p/q falls in [b,c]*/ && p < fabs(prev_step * q / 2) ) { /* and isn't too large */ new_step = p / q; } /* it is accepted * If p/q is too large then the * bisection procedure can * reduce [b,c] range to more * extent */ } if ( fabs(new_step) < tol_act) { /* Adjust the step to be not less*/ if ( new_step > (igraph_real_t)0 ) { /* than tolerance */ new_step = tol_act; } else { new_step = -tol_act; } } a = b; fa = fb; /* Save the previous approx. */ b += new_step; fb = (*f)(b, info); /* Do step to a new approxim. */ if ( (fb > 0 && fc > 0) || (fb < 0 && fc < 0) ) { /* Adjust c for it to have a sign opposite to that of b */ c = a; fc = fa; } } /* failed! */ *Tol = fabs(c - b); *Maxit = -1; *res = b; return IGRAPH_DIVERGED; } leidenbase/src/core/internal/hacks.c0000644000176200001440000000313714447675374017166 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "internal/hacks.h" #include #include /* These are implementations of common C functions that may be missing from some * compilers; for instance, icc does not provide stpcpy so we implement it * here. */ /** * Drop-in replacement for strdup. * Used only in compilers that do not have strdup or _strdup */ char* igraph_i_strdup(const char *s) { size_t n = strlen(s) + 1; char* result = (char*)malloc(sizeof(char) * n); if (result) { memcpy(result, s, n); } return result; } /** * Drop-in replacement for stpcpy. * Used only in compilers that do not have stpcpy */ char* igraph_i_stpcpy(char* s1, const char* s2) { char* result = strcpy(s1, s2); return result + strlen(s1); } leidenbase/src/core/internal/lsap.c0000644000176200001440000003730314447675374017036 0ustar liggesusers #include "igraph_lsap.h" #include "igraph_error.h" /* #include */ #include #include /* INT_MAX */ #include /* DBL_MAX */ #include /* constants used for improving readability of code */ #define COVERED 1 #define UNCOVERED 0 #define ASSIGNED 1 #define UNASSIGNED 0 #define TRUE 1 #define FALSE 0 #define MARKED 1 #define UNMARKED 0 #define REDUCE 1 #define NOREDUCE 0 typedef struct { int n; /* order of problem */ double **C; /* cost matrix */ double **c; /* reduced cost matrix */ int *s; /* assignment */ int *f; /* column i is assigned to f[i] */ int na; /* number of assigned items; */ int runs; /* number of iterations */ double cost; /* minimum cost */ time_t rtime; /* time */ } AP; /* public interface */ /* constructors and destructor */ static AP *ap_create_problem(double *t, int n); /* static AP *ap_create_problem_from_matrix(double **t, int n); */ /* static AP *ap_read_problem(char *file); */ static void ap_free(AP *p); static int ap_assignment(AP *p, int *res); /* static int ap_costmatrix(AP *p, double **m); */ /* static int ap_datamatrix(AP *p, double **m); */ /* static int ap_iterations(AP *p); */ static int ap_hungarian(AP *p); /* static double ap_mincost(AP *p); */ /* static void ap_print_solution(AP *p); */ /* static void ap_show_data(AP *p); */ /* static int ap_size(AP *p); */ /* static int ap_time(AP *p); */ /* error reporting */ /* static void ap_error(char *message); */ /* private functions */ static void preprocess(AP *p); static void preassign(AP *p); static int cover(AP *p, int *ri, int *ci); static void reduce(AP *p, int *ri, int *ci); int ap_hungarian(AP *p) { int n; /* size of problem */ int *ri; /* covered rows */ int *ci; /* covered columns */ time_t start, end; /* timer */ int i, j, ok; start = time(0); n = p->n; p->runs = 0; /* allocate memory */ p->s = calloc(1 + n, sizeof(int)); p->f = calloc(1 + n, sizeof(int)); ri = calloc(1 + n, sizeof(int)); ci = calloc(1 + n, sizeof(int)); if (ri == NULL || ci == NULL || p->s == NULL || p->f == NULL) { IGRAPH_ERROR("ap_hungarian: could not allocate memory", IGRAPH_ENOMEM); } preprocess(p); preassign(p); while (p->na < n) { if (REDUCE == cover(p, ri, ci)) { reduce(p, ri, ci); } ++p->runs; } end = time(0); p->rtime = end - start; /* check if assignment is a permutation of (1..n) */ for (i = 1; i <= n; i++) { ok = 0; for (j = 1; j <= n; j++) if (p->s[j] == i) { ++ok; } if (ok != 1) IGRAPH_ERROR("ap_hungarian: error in assignment, is not a permutation", IGRAPH_EINVAL); } /* calculate cost of assignment */ p->cost = 0; for (i = 1; i <= n; i++) { p->cost += p->C[i][p->s[i]]; } /* reset result back to base-0 indexing */ for (i = 1; i <= n; i++) { p->s[i - 1] = p->s[i] - 1; } /* free memory */ free(ri); free(ci); return 0; } /* abbreviated interface */ int ap_assignment(AP *p, int *res) { int i; if (p->s == NULL) { ap_hungarian(p); } for (i = 0; i < p->n; i++) { res[i] = p->s[i]; } return p->n; } /*******************************************************************/ /* constructors */ /* read data from file */ /*******************************************************************/ #if 0 AP *ap_read_problem(char *file) { FILE *f; int i, j, c; int m, n; double x; double **t; int nrow, ncol; AP *p; f = fopen(file, "r"); if (f == NULL) { return NULL; } t = (double **)malloc(sizeof(double*)); m = 0; n = 0; nrow = 0; ncol = 0; while (EOF != (i = fscanf(f, "%lf", &x))) { if (i == 1) { if (n == 0) { t = (double **) realloc(t, (m + 1) * sizeof(double *)); t[m] = (double *) malloc(sizeof(double)); } else { t[m] = (double *) realloc(t[m], (n + 1) * sizeof(double)); } t[m][n++] = x; ncol = (ncol < n) ? n : ncol; c = fgetc(f); if (c == '\n') { n = 0; ++m; nrow = (nrow < m) ? m : nrow; } } } fclose(f); /* prepare data */ if (nrow != ncol) { /* fprintf(stderr,"ap_read_problem: problem not quadratic\nrows =%d, cols = %d\n",nrow,ncol); */ IGRAPH_WARNINGF("ap_read_problem: problem not quadratic; rows = %d, cols = %d.", nrow, ncol); return NULL; } p = (AP*) malloc(sizeof(AP)); p->n = ncol; p->C = (double **) malloc((1 + nrow) * sizeof(double *)); p->c = (double **) malloc((1 + nrow) * sizeof(double *)); if (p->C == NULL || p->c == NULL) { return NULL; } for (i = 1; i <= nrow; i++) { p->C[i] = (double *) calloc(ncol + 1, sizeof(double)); p->c[i] = (double *) calloc(ncol + 1, sizeof(double)); if (p->C[i] == NULL || p->c[i] == NULL) { return NULL; } } for (i = 1; i <= nrow; i++) for ( j = 1; j <= ncol; j++) { p->C[i][j] = t[i - 1][j - 1]; p->c[i][j] = t[i - 1][j - 1]; } for (i = 0; i < nrow; i++) { free(t[i]); } free(t); p->cost = 0; p->s = NULL; p->f = NULL; return p; } #endif #if 0 AP *ap_create_problem_from_matrix(double **t, int n) { int i, j; AP *p; p = (AP*) malloc(sizeof(AP)); if (p == NULL) { return NULL; } p->n = n; p->C = (double **) malloc((n + 1) * sizeof(double *)); p->c = (double **) malloc((n + 1) * sizeof(double *)); if (p->C == NULL || p->c == NULL) { return NULL; } for (i = 1; i <= n; i++) { p->C[i] = (double *) calloc(n + 1, sizeof(double)); p->c[i] = (double *) calloc(n + 1, sizeof(double)); if (p->C[i] == NULL || p->c[i] == NULL) { return NULL; } } for (i = 1; i <= n; i++) for ( j = 1; j <= n; j++) { p->C[i][j] = t[i - 1][j - 1]; p->c[i][j] = t[i - 1][j - 1]; } p->cost = 0; p->s = NULL; p->f = NULL; return p; } #endif /* read data from vector */ AP *ap_create_problem(double *t, int n) { int i, j; AP *p; p = (AP*) malloc(sizeof(AP)); if (p == NULL) { return NULL; } p->n = n; p->C = (double **) malloc((n + 1) * sizeof(double *)); p->c = (double **) malloc((n + 1) * sizeof(double *)); if (p->C == NULL || p->c == NULL) { return NULL; } for (i = 1; i <= n; i++) { p->C[i] = (double *) calloc(n + 1, sizeof(double)); p->c[i] = (double *) calloc(n + 1, sizeof(double)); if (p->C[i] == NULL || p->c[i] == NULL) { return NULL; } } for (i = 1; i <= n; i++) for ( j = 1; j <= n; j++) { p->C[i][j] = t[n * (j - 1) + i - 1]; p->c[i][j] = t[n * (j - 1) + i - 1]; } p->cost = 0; p->s = NULL; p->f = NULL; return p; } /* destructor */ void ap_free(AP *p) { int i; free(p->s); free(p->f); for (i = 1; i <= p->n; i++) { free(p->C[i]); free(p->c[i]); } free(p->C); free(p->c); free(p); } /* set + get functions */ /* void ap_show_data(AP *p) { int i, j; for(i = 1; i <= p->n; i++){ for(j = 1; j <= p->n; j++) printf("%6.2f ", p->c[i][j]); printf("\n"); } } double ap_mincost(AP *p) { if (p->s == NULL) { ap_hungarian(p); } return p->cost; } int ap_size(AP *p) { return p->n; } int ap_time(AP *p) { return (int) p->rtime; } int ap_iterations(AP *p) { return p->runs; } void ap_print_solution(AP *p) { int i; printf("%d itertations, %d secs.\n",p->runs, (int)p->rtime); printf("Min Cost: %10.4f\n",p->cost); for(i = 0; i < p->n; i++) printf("%4d",p->s[i]); printf("\n"); } int ap_costmatrix(AP *p, double **m) { int i, j; for (i = 0; i < p->n; i++) for (j = 0; j < p->n; j++) { m[i][j] = p->C[i + 1][j + 1]; } return p->n; } int ap_datamatrix(AP *p, double **m) { int i, j; for (i = 0; i < p->n; i++) for (j = 0; j < p->n; j++) { m[i][j] = p->c[i + 1][j + 1]; } return p->n; } */ /* error reporting */ /* void ap_error(char *message) { fprintf(stderr,"%s\n",message); exit(1); } */ /*************************************************************/ /* these functions are used internally */ /* by ap_hungarian */ /*************************************************************/ int cover(AP *p, int *ri, int *ci) { int *mr, i, r; int n; n = p->n; mr = calloc(1 + p->n, sizeof(int)); /* reset cover indices */ for (i = 1; i <= n; i++) { if (p->s[i] == UNASSIGNED) { ri[i] = UNCOVERED; mr[i] = MARKED; } else { ri[i] = COVERED; } ci[i] = UNCOVERED; } while (TRUE) { /* find marked row */ r = 0; for (i = 1; i <= n; i++) if (mr[i] == MARKED) { r = i; break; } if (r == 0) { break; } for (i = 1; i <= n; i++) if (p->c[r][i] == 0 && ci[i] == UNCOVERED) { if (p->f[i]) { ri[p->f[i]] = UNCOVERED; mr[p->f[i]] = MARKED; ci[i] = COVERED; } else { if (p->s[r] == UNASSIGNED) { ++p->na; } p->f[p->s[r]] = 0; p->f[i] = r; p->s[r] = i; free(mr); return NOREDUCE; } } mr[r] = UNMARKED; } free(mr); return REDUCE; } void reduce(AP *p, int *ri, int *ci) { int i, j, n; double min; n = p->n; /* find minimum in uncovered c-matrix */ min = DBL_MAX; for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) if (ri[i] == UNCOVERED && ci[j] == UNCOVERED) { if (p->c[i][j] < min) { min = p->c[i][j]; } } /* subtract min from each uncovered element and add it to each element */ /* which is covered twice */ for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) { if (ri[i] == UNCOVERED && ci[j] == UNCOVERED) { p->c[i][j] -= min; } if (ri[i] == COVERED && ci[j] == COVERED) { p->c[i][j] += min; } } } void preassign(AP *p) { int i, j, min, r, c, n, count; int *ri, *ci, *rz, *cz; n = p->n; p->na = 0; /* row and column markers */ ri = calloc(1 + n, sizeof(int)); ci = calloc(1 + n, sizeof(int)); /* row and column counts of zeroes */ rz = calloc(1 + n, sizeof(int)); cz = calloc(1 + n, sizeof(int)); for (i = 1; i <= n; i++) { count = 0; for (j = 1; j <= n; j++) if (p->c[i][j] == 0) { ++count; } rz[i] = count; } for (i = 1; i <= n; i++) { count = 0; for (j = 1; j <= n; j++) if (p->c[j][i] == 0) { ++count; } cz[i] = count; } while (TRUE) { /* find unassigned row with least number of zeroes > 0 */ min = INT_MAX; r = 0; for (i = 1; i <= n; i++) if (rz[i] > 0 && rz[i] < min && ri[i] == UNASSIGNED) { min = rz[i]; r = i; } /* check if we are done */ if (r == 0) { break; } /* find unassigned column in row r with least number of zeroes */ c = 0; min = INT_MAX; for (i = 1; i <= n; i++) if (p->c[r][i] == 0 && cz[i] < min && ci[i] == UNASSIGNED) { min = cz[i]; c = i; } if (c) { ++p->na; p->s[r] = c; p->f[c] = r; ri[r] = ASSIGNED; ci[c] = ASSIGNED; /* adjust zero counts */ cz[c] = 0; for (i = 1; i <= n; i++) if (p->c[i][c] == 0) { --rz[i]; } } } /* free memory */ free(ri); free(ci); free(rz); free(cz); } void preprocess(AP *p) { int i, j, n; double min; n = p->n; /* subtract column minima in each row */ for (i = 1; i <= n; i++) { min = p->c[i][1]; for (j = 2; j <= n; j++) if (p->c[i][j] < min) { min = p->c[i][j]; } for (j = 1; j <= n; j++) { p->c[i][j] -= min; } } /* subtract row minima in each column */ for (i = 1; i <= n; i++) { min = p->c[1][i]; for (j = 2; j <= n; j++) if (p->c[j][i] < min) { min = p->c[j][i]; } for (j = 1; j <= n; j++) { p->c[j][i] -= min; } } } /** * \function igraph_solve_lsap * \brief Solve a balanced linear assignment problem. * * This functions solves a linear assinment problem using the Hungarian * method. A number of tasks, an equal number of agents, and the cost * of each agent to perform the tasks is given. This function then * assigns one task to each agent in such a way that the total cost is * minimized. * * * If the cost should be maximized instead of minimized, the cost matrix * should be negated. * * * To solve an unbalanced assignment problem, where the number of agents * is greater than the number of tasks, an extra task with zero cost * should be added. * * \param c The assignment problem, where the number of rows is the * number of agents, the number of columns is the number of * tasks, and each element is the cost of an agent to perform * the task. * \param n The number of rows and columns of \p c. * \param p An initialized vector which will store the result. The nth * entry gives the task the nth agent is assigned to minimize * the total cost. * \return Error code. * * Time complexity: O(n^3), where n is the number of agents. */ int igraph_solve_lsap(igraph_matrix_t *c, igraph_integer_t n, igraph_vector_int_t *p) { AP *ap; if(n != igraph_matrix_nrow(c)) { IGRAPH_ERRORF("n (%" IGRAPH_PRId ") " "not equal to number of agents (%ld).", IGRAPH_EINVAL, n, igraph_matrix_nrow(c)); } if(n != igraph_matrix_ncol(c)) { IGRAPH_ERRORF("n (%" IGRAPH_PRId ") " "not equal to number of tasks (%ld).", IGRAPH_EINVAL, n, igraph_matrix_ncol(c)); } IGRAPH_CHECK(igraph_vector_int_resize(p, n)); igraph_vector_int_null(p); ap = ap_create_problem(&MATRIX(*c, 0, 0), n); ap_hungarian(ap); ap_assignment(ap, VECTOR(*p)); ap_free(ap); return IGRAPH_SUCCESS; } leidenbase/src/core/internal/glpk_support.h0000644000176200001440000001352014447675374020630 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_GLPK_SUPPORT_H #define IGRAPH_GLPK_SUPPORT_H #include "config.h" /* Note: only files calling the GLPK routines directly need to include this header. */ #ifdef HAVE_GLPK #include #include typedef struct igraph_i_glpk_error_info_s { jmp_buf jmp; /* used for bailing when there is a GLPK error */ int is_interrupted; /* Boolean; true if there was an interruption */ int is_error; /* Boolean; true if the error hook was called */ char msg[4096]; /* GLPK error messages are collected here */ char *msg_ptr; /* Points to the end (null terminator) of msg */ } igraph_i_glpk_error_info_t; extern IGRAPH_THREAD_LOCAL igraph_i_glpk_error_info_t igraph_i_glpk_error_info; int igraph_i_glpk_check(int retval, const char* message); void igraph_i_glpk_interruption_hook(glp_tree *tree, void *info); void igraph_i_glpk_error_hook(void *info); int igraph_i_glpk_terminal_hook(void *info, const char *s); void igraph_i_glp_delete_prob(glp_prob *p); #define IGRAPH_GLPK_CHECK(func, message) do { \ int igraph_i_ret = igraph_i_glpk_check(func, message); \ if (IGRAPH_UNLIKELY(igraph_i_ret != 0)) { \ return igraph_i_ret; \ } } while (0) /** * \ingroup internal * \define IGRAPH_GLPK_SETUP * * Use this macro at the start of igraph functions that use GLPK routines * directly. * * - IGRAPH_GLPK_SETUP() must be called in all top-level functions that * use GLPK, before beginning to use any GLPK functions. * * - Do NOT call glp_term_out(OFF) as interruption support relies on * the terminal hook being called. * * - This must be a macro and not a function, as jumping into a function * that has already returned with longjmp() is not possible. * * This setup step is necessary in order to support interruption, as * well as to handle fatal GLPK errors gracefully. See here for details: * * https://lists.gnu.org/archive/html/help-glpk/2019-10/msg00000.html * * Interruption support for GLPK is essential because it is practically * impossible to predict how long it will take to solve a problem. It * may take less than a second or it may never finish in practice. * * It does the following: * * - Initialize the data structure where we keep track of GLPK's current * error and interruption state, \c igraph_i_glpk_error_info. * - Set an error hook and a terminal hook for GLPK. * - Provide a return point for the longjmp() called from the error hook. * * There are two interruption mechanisms we can use with GLPK. glp_intopt() * supports a callback function which can signal a request for interruption. * However, glp_intopt() internally calls glp_simplex(), which may again * take a very long time. * * The recommended way to interrupt glp_simplex() is to check for interruption * from the terminal hook, which is normally meant for intercepting output. * This interruption is possible only as often as there is output, which may * be at intervals of a few seconds in practice. * * Interruption is achieved by setting an error with glp_error(), which * triggers a call to the error hook. From the error hook, we free all * GLPK resources using glp_free_env() and do a longjmp(). * * The use of these mechanisms makes it unsafe to use igraph's GLPK-reliant * functions from a process which also uses GLPK for other purposes. * To avoid this problem, GLPK should ideally be linked to igraph statically. */ #define IGRAPH_GLPK_SETUP() \ do { \ glp_error_hook(igraph_i_glpk_error_hook, NULL); \ glp_term_hook(igraph_i_glpk_terminal_hook, NULL); \ igraph_i_glpk_error_info.is_interrupted = 0; \ igraph_i_glpk_error_info.is_error = 0; \ igraph_i_glpk_error_info.msg_ptr = igraph_i_glpk_error_info.msg; \ if (setjmp(igraph_i_glpk_error_info.jmp)) { \ if (igraph_i_glpk_error_info.is_interrupted) { \ return IGRAPH_INTERRUPTED; \ } else { \ if (igraph_i_glpk_error_info.msg_ptr != igraph_i_glpk_error_info.msg) { \ while ( *(igraph_i_glpk_error_info.msg_ptr - 1) == '\n' && \ igraph_i_glpk_error_info.msg_ptr > igraph_i_glpk_error_info.msg ) { \ igraph_i_glpk_error_info.msg_ptr--; \ } \ *igraph_i_glpk_error_info.msg_ptr = '\0'; \ igraph_error(igraph_i_glpk_error_info.msg, IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EGLP); \ } else if (igraph_i_glpk_error_info.is_error) { \ /* This branch can never be reached unless compiled with USING_R and using */ \ /* the hack to support pre-4.57 GLPK versions. See comments in glpk_support.c. */ \ igraph_error("Error while running GLPK solver.", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EGLP); \ } \ return IGRAPH_EGLP; \ } \ } \ } while (0) #endif #endif leidenbase/src/core/internal/gmp_internal.h0000644000176200001440000000164314447675374020561 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2020 The igraph development team it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_GMP_H #define IGRAPH_GMP_H #include "config.h" #ifdef INTERNAL_GMP #include "mini-gmp/mini-gmp.h" #else #include #endif #endif leidenbase/src/core/operators/0000755000176200001440000000000014532173045016106 5ustar liggesusersleidenbase/src/core/operators/rewire_internal.h0000644000176200001440000000040114447675375021465 0ustar liggesusers#ifndef IGRAPH_OPERATORS_REWIRE_INTERNAL_H #define IGRAPH_OPERATORS_REWIRE_INTERNAL_H #include "igraph_interface.h" IGRAPH_PRIVATE_EXPORT int igraph_i_rewire(igraph_t *graph, igraph_integer_t n, igraph_rewiring_t mode, igraph_bool_t use_adjlist); #endif leidenbase/src/core/operators/rewire_edges.c0000644000176200001440000003246214447675375020747 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_conversion.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_random.h" #include "graph/attributes.h" static int igraph_i_rewire_edges_no_multiple(igraph_t *graph, igraph_real_t prob, igraph_bool_t loops, igraph_vector_t *edges) { int no_verts = igraph_vcount(graph); int no_edges = igraph_ecount(graph); igraph_vector_t eorder, tmp; igraph_vector_int_t first, next, prev, marked; int i, to_rewire, last_other = -1; /* Create our special graph representation */ # define ADD_STUB(vertex, stub) do { \ if (VECTOR(first)[(vertex)]) { \ VECTOR(prev)[(int) VECTOR(first)[(vertex)]-1]=(stub)+1; \ } \ VECTOR(next)[(stub)]=VECTOR(first)[(vertex)]; \ VECTOR(prev)[(stub)]=0; \ VECTOR(first)[(vertex)]=(stub)+1; \ } while (0) # define DEL_STUB(vertex, stub) do { \ if (VECTOR(next)[(stub)]) { \ VECTOR(prev)[VECTOR(next)[(stub)]-1]=VECTOR(prev)[(stub)]; \ } \ if (VECTOR(prev)[(stub)]) { \ VECTOR(next)[VECTOR(prev)[(stub)]-1]=VECTOR(next)[(stub)]; \ } else { \ VECTOR(first)[(vertex)]=VECTOR(next)[(stub)]; \ } \ } while (0) # define MARK_NEIGHBORS(vertex) do { \ int xxx_ =VECTOR(first)[(vertex)]; \ while (xxx_) { \ int o= (int) VECTOR(*edges)[xxx_ % 2 ? xxx_ : xxx_-2]; \ VECTOR(marked)[o]=other+1; \ xxx_=VECTOR(next)[xxx_-1]; \ } \ } while (0) IGRAPH_CHECK(igraph_vector_int_init(&first, no_verts)); IGRAPH_FINALLY(igraph_vector_int_destroy, &first); IGRAPH_CHECK(igraph_vector_int_init(&next, no_edges * 2)); IGRAPH_FINALLY(igraph_vector_int_destroy, &next); IGRAPH_CHECK(igraph_vector_int_init(&prev, no_edges * 2)); IGRAPH_FINALLY(igraph_vector_int_destroy, &prev); IGRAPH_CHECK(igraph_get_edgelist(graph, edges, /*bycol=*/ 0)); IGRAPH_VECTOR_INIT_FINALLY(&eorder, no_edges); IGRAPH_VECTOR_INIT_FINALLY(&tmp, no_edges); for (i = 0; i < no_edges; i++) { int idx1 = 2 * i, idx2 = idx1 + 1, from = (int) VECTOR(*edges)[idx1], to = (int) VECTOR(*edges)[idx2]; VECTOR(tmp)[i] = from; ADD_STUB(from, idx1); ADD_STUB(to, idx2); } IGRAPH_CHECK(igraph_vector_order1(&tmp, &eorder, no_verts)); igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_vector_int_init(&marked, no_verts)); IGRAPH_FINALLY(igraph_vector_int_destroy, &marked); /* Rewire the stubs, part I */ to_rewire = (int) RNG_GEOM(prob); while (to_rewire < no_edges) { int stub = (int) (2 * VECTOR(eorder)[to_rewire] + 1); int v = (int) VECTOR(*edges)[stub]; int ostub = stub - 1; int other = (int) VECTOR(*edges)[ostub]; int pot; if (last_other != other) { MARK_NEIGHBORS(other); } /* Do the rewiring */ do { if (loops) { pot = (int) RNG_INTEGER(0, no_verts - 1); } else { pot = (int) RNG_INTEGER(0, no_verts - 2); pot = pot != other ? pot : no_verts - 1; } } while (VECTOR(marked)[pot] == other + 1 && pot != v); if (pot != v) { DEL_STUB(v, stub); ADD_STUB(pot, stub); VECTOR(marked)[v] = 0; VECTOR(marked)[pot] = other + 1; VECTOR(*edges)[stub] = pot; } to_rewire += RNG_GEOM(prob) + 1; last_other = other; } /* Create the new index, from the potentially rewired stubs */ IGRAPH_VECTOR_INIT_FINALLY(&tmp, no_edges); for (i = 0; i < no_edges; i++) { VECTOR(tmp)[i] = VECTOR(*edges)[2 * i + 1]; } IGRAPH_CHECK(igraph_vector_order1(&tmp, &eorder, no_verts)); igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); /* Rewire the stubs, part II */ igraph_vector_int_null(&marked); last_other = -1; to_rewire = (int) RNG_GEOM(prob); while (to_rewire < no_edges) { int stub = (int) (2 * VECTOR(eorder)[to_rewire]); int v = (int) VECTOR(*edges)[stub]; int ostub = stub + 1; int other = (int) VECTOR(*edges)[ostub]; int pot; if (last_other != other) { MARK_NEIGHBORS(other); } /* Do the rewiring */ do { if (loops) { pot = (int) RNG_INTEGER(0, no_verts - 1); } else { pot = (int) RNG_INTEGER(0, no_verts - 2); pot = pot != other ? pot : no_verts - 1; } } while (VECTOR(marked)[pot] == other + 1 && pot != v); if (pot != v) { DEL_STUB(v, stub); ADD_STUB(pot, stub); VECTOR(marked)[v] = 0; VECTOR(marked)[pot] = other + 1; VECTOR(*edges)[stub] = pot; } to_rewire += RNG_GEOM(prob) + 1; last_other = other; } igraph_vector_int_destroy(&marked); igraph_vector_int_destroy(&prev); igraph_vector_int_destroy(&next); igraph_vector_int_destroy(&first); igraph_vector_destroy(&eorder); IGRAPH_FINALLY_CLEAN(5); return 0; } #undef ADD_STUB #undef DEL_STUB #undef MARK_NEIGHBORS /** * \function igraph_rewire_edges * \brief Rewires the edges of a graph with constant probability. * * This function rewires the edges of a graph with a constant * probability. More precisely each end point of each edge is rewired * to a uniformly randomly chosen vertex with constant probability \p * prob. * * Note that this function modifies the input \p graph, * call \ref igraph_copy() if you want to keep it. * * \param graph The input graph, this will be rewired, it can be * directed or undirected. * \param prob The rewiring probability a constant between zero and * one (inclusive). * \param loops Boolean, whether loop edges are allowed in the new * graph, or not. * \param multiple Boolean, whether multiple edges are allowed in the * new graph. * \return Error code. * * \sa \ref igraph_watts_strogatz_game() uses this function for the * rewiring. * * Time complexity: O(|V|+|E|). */ int igraph_rewire_edges(igraph_t *graph, igraph_real_t prob, igraph_bool_t loops, igraph_bool_t multiple) { igraph_t newgraph; long int no_of_edges = igraph_ecount(graph); long int no_of_nodes = igraph_vcount(graph); long int endpoints = no_of_edges * 2; long int to_rewire; igraph_vector_t edges; if (prob < 0 || prob > 1) { IGRAPH_ERROR("Rewiring probability should be between zero and one", IGRAPH_EINVAL); } if (prob == 0) { /* This is easy, just leave things as they are */ return IGRAPH_SUCCESS; } IGRAPH_VECTOR_INIT_FINALLY(&edges, endpoints); RNG_BEGIN(); if (prob != 0 && no_of_edges > 0) { if (multiple) { /* If multiple edges are allowed, then there is an easy and fast method. Each endpoint of an edge is rewired with probability p, so the "skips" between the really rewired endpoints follow a geometric distribution. */ IGRAPH_CHECK(igraph_get_edgelist(graph, &edges, 0)); to_rewire = (long int) RNG_GEOM(prob); while (to_rewire < endpoints) { if (loops) { VECTOR(edges)[to_rewire] = RNG_INTEGER(0, no_of_nodes - 1); } else { long int opos = to_rewire % 2 ? to_rewire - 1 : to_rewire + 1; long int nei = (long int) VECTOR(edges)[opos]; long int r = RNG_INTEGER(0, no_of_nodes - 2); VECTOR(edges)[ to_rewire ] = (r != nei ? r : no_of_nodes - 1); } to_rewire += RNG_GEOM(prob) + 1; } } else { IGRAPH_CHECK(igraph_i_rewire_edges_no_multiple(graph, prob, loops, &edges)); } } RNG_END(); IGRAPH_CHECK(igraph_create(&newgraph, &edges, (igraph_integer_t) no_of_nodes, igraph_is_directed(graph))); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &newgraph); IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1, 1, 1); IGRAPH_FINALLY_CLEAN(1); igraph_destroy(graph); *graph = newgraph; return 0; } /** * \function igraph_rewire_directed_edges * \brief Rewires the chosen endpoint of directed edges. * * This function rewires either the start or end of directed edges in a graph * with a constant probability. Correspondingly, either the in-degree sequence * or the out-degree sequence of the graph will be preserved. * * Note that this function modifies the input \p graph, * call \ref igraph_copy() if you want to keep it. * * This function can produce multiple edges between two vertices. * * \param graph The input graph, this will be rewired, it can be * directed or undirected. If it is undirected or \p mode is set to * IGRAPH_ALL, \ref igraph_rewire_edges() will be called. * \param prob The rewiring probability, a constant between zero and * one (inclusive). * \param loops Boolean, whether loop edges are allowed in the new * graph, or not. * \param mode The endpoints of directed edges to rewire. It is ignored for * undirected graphs. Possible values: * \clist * \cli IGRAPH_OUT * rewire the end of each directed edge * \cli IGRAPH_IN * rewire the start of each directed edge * \cli IGRAPH_ALL * rewire both endpoints of each edge * \endclist * \return Error code. * * \sa \ref igraph_rewire_edges(), \ref igraph_rewire() * * Time complexity: O(|E|). */ int igraph_rewire_directed_edges(igraph_t *graph, igraph_real_t prob, igraph_bool_t loops, igraph_neimode_t mode) { if (prob < 0 || prob > 1) { IGRAPH_ERROR("Rewiring probability should be between zero and one", IGRAPH_EINVAL); } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } if (prob == 0) { return IGRAPH_SUCCESS; } if (igraph_is_directed(graph) && mode != IGRAPH_ALL) { igraph_t newgraph; long int no_of_edges = igraph_ecount(graph); long int no_of_nodes = igraph_vcount(graph); long int to_rewire; long int offset = 0; igraph_vector_t edges; IGRAPH_VECTOR_INIT_FINALLY(&edges, 2 * no_of_edges); switch (mode) { case IGRAPH_IN: offset = 0; break; case IGRAPH_OUT: offset = 1; break; case IGRAPH_ALL: break; /* suppress compiler warning */ } IGRAPH_CHECK(igraph_get_edgelist(graph, &edges, 0)); RNG_BEGIN(); to_rewire = RNG_GEOM(prob); while (to_rewire < no_of_edges) { if (loops) { VECTOR(edges)[2 * to_rewire + offset] = RNG_INTEGER(0, no_of_nodes - 1); } else { long int nei = (long int) VECTOR(edges)[2 * to_rewire + (1 - offset)]; long int r = RNG_INTEGER(0, no_of_nodes - 2); VECTOR(edges)[2 * to_rewire + offset] = (r != nei ? r : no_of_nodes - 1); } to_rewire += RNG_GEOM(prob) + 1; } RNG_END(); IGRAPH_CHECK(igraph_create(&newgraph, &edges, (igraph_integer_t) no_of_nodes, igraph_is_directed(graph))); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &newgraph); IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1, 1, 1); IGRAPH_FINALLY_CLEAN(1); igraph_destroy(graph); *graph = newgraph; } else { IGRAPH_CHECK(igraph_rewire_edges(graph, prob, loops, /* multiple = */ 1)); } return 0; } leidenbase/src/core/operators/rewire.c0000644000176200001440000002511514447675375017575 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_adjlist.h" #include "igraph_conversion.h" #include "igraph_interface.h" #include "igraph_iterators.h" #include "igraph_progress.h" #include "igraph_random.h" #include "igraph_structural.h" #include "core/interruption.h" #include "operators/rewire_internal.h" /* Threshold that defines when to switch over to using adjacency lists during * rewiring */ #define REWIRE_ADJLIST_THRESHOLD 10 /* Not declared static so that the testsuite can use it, but not part of the public API. */ int igraph_i_rewire(igraph_t *graph, igraph_integer_t n, igraph_rewiring_t mode, igraph_bool_t use_adjlist) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); char message[256]; igraph_integer_t a, b, c, d, dummy, num_swaps, num_successful_swaps; igraph_vector_t eids, edgevec, alledges; igraph_bool_t directed, loops, ok; igraph_es_t es; igraph_adjlist_t al; if (no_of_nodes < 4) { IGRAPH_ERROR("graph unsuitable for rewiring", IGRAPH_EINVAL); } directed = igraph_is_directed(graph); loops = (mode & IGRAPH_REWIRING_SIMPLE_LOOPS); RNG_BEGIN(); IGRAPH_VECTOR_INIT_FINALLY(&eids, 2); if (use_adjlist) { /* As well as the sorted adjacency list, we maintain an unordered * list of edges for picking a random edge in constant time. */ IGRAPH_CHECK(igraph_adjlist_init(graph, &al, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &al); IGRAPH_VECTOR_INIT_FINALLY(&alledges, no_of_edges * 2); igraph_get_edgelist(graph, &alledges, /*bycol=*/ 0); } else { IGRAPH_VECTOR_INIT_FINALLY(&edgevec, 4); es = igraph_ess_vector(&eids); } /* We don't want the algorithm to get stuck in an infinite loop when * it can't choose two edges satisfying the conditions. Instead of * this, we choose two arbitrary edges and if they have endpoints * in common, we just decrease the number of trials left and continue * (so unsuccessful rewirings still count as a trial) */ num_swaps = num_successful_swaps = 0; while (num_swaps < n) { IGRAPH_ALLOW_INTERRUPTION(); if (num_swaps % 1000 == 0) { snprintf(message, sizeof(message), "Random rewiring (%.2f%% of the trials were successful)", num_swaps > 0 ? ((100.0 * num_successful_swaps) / num_swaps) : 0.0); IGRAPH_PROGRESS(message, (100.0 * num_swaps) / n, 0); } switch (mode) { case IGRAPH_REWIRING_SIMPLE: case IGRAPH_REWIRING_SIMPLE_LOOPS: ok = 1; /* Choose two edges randomly */ VECTOR(eids)[0] = RNG_INTEGER(0, no_of_edges - 1); do { VECTOR(eids)[1] = RNG_INTEGER(0, no_of_edges - 1); } while (VECTOR(eids)[0] == VECTOR(eids)[1]); /* Get the endpoints */ if (use_adjlist) { a = VECTOR(alledges)[((igraph_integer_t)VECTOR(eids)[0]) * 2]; b = VECTOR(alledges)[(((igraph_integer_t)VECTOR(eids)[0]) * 2) + 1]; c = VECTOR(alledges)[((igraph_integer_t)VECTOR(eids)[1]) * 2]; d = VECTOR(alledges)[(((igraph_integer_t)VECTOR(eids)[1]) * 2) + 1]; } else { IGRAPH_CHECK(igraph_edge(graph, (igraph_integer_t) VECTOR(eids)[0], &a, &b)); IGRAPH_CHECK(igraph_edge(graph, (igraph_integer_t) VECTOR(eids)[1], &c, &d)); } /* For an undirected graph, we have two "variants" of each edge, i.e. * a -- b and b -- a. Since some rewirings can be performed only when we * "swap" the endpoints, we do it now with probability 0.5 */ if (!directed && RNG_UNIF01() < 0.5) { dummy = c; c = d; d = dummy; if (use_adjlist) { /* Flip the edge in the unordered edge-list, so the update later on * hits the correct end. */ VECTOR(alledges)[((igraph_integer_t)VECTOR(eids)[1]) * 2] = c; VECTOR(alledges)[(((igraph_integer_t)VECTOR(eids)[1]) * 2) + 1] = d; } } /* If we do not touch loops, check whether a == b or c == d and disallow * the swap if needed */ if (!loops && (a == b || c == d)) { ok = 0; } else { /* Check whether they are suitable for rewiring */ if (a == c || b == d) { /* Swapping would have no effect */ ok = 0; } else { /* a != c && b != d */ /* If a == d or b == c, the swap would generate at least one loop, so * we disallow them unless we want to have loops */ ok = loops || (a != d && b != c); /* Also, if a == b and c == d and we allow loops, doing the swap * would result in a multiple edge if the graph is undirected */ ok = ok && (directed || a != b || c != d); } } /* All good so far. Now check for the existence of a --> d and c --> b to * disallow the creation of multiple edges */ if (ok) { if (use_adjlist) { if (igraph_adjlist_has_edge(&al, a, d, directed)) { ok = 0; } } else { IGRAPH_CHECK(igraph_are_connected(graph, a, d, &ok)); ok = !ok; } } if (ok) { if (use_adjlist) { if (igraph_adjlist_has_edge(&al, c, b, directed)) { ok = 0; } } else { IGRAPH_CHECK(igraph_are_connected(graph, c, b, &ok)); ok = !ok; } } /* If we are still okay, we can perform the rewiring */ if (ok) { /* printf("Deleting: %ld -> %ld, %ld -> %ld\n", (long)a, (long)b, (long)c, (long)d); */ if (use_adjlist) { /* Replace entry in sorted adjlist: */ IGRAPH_CHECK(igraph_adjlist_replace_edge(&al, a, b, d, directed)); IGRAPH_CHECK(igraph_adjlist_replace_edge(&al, c, d, b, directed)); /* Also replace in unsorted edgelist: */ VECTOR(alledges)[(((igraph_integer_t)VECTOR(eids)[0]) * 2) + 1] = d; VECTOR(alledges)[(((igraph_integer_t)VECTOR(eids)[1]) * 2) + 1] = b; } else { IGRAPH_CHECK(igraph_delete_edges(graph, es)); VECTOR(edgevec)[0] = a; VECTOR(edgevec)[1] = d; VECTOR(edgevec)[2] = c; VECTOR(edgevec)[3] = b; /* printf("Adding: %ld -> %ld, %ld -> %ld\n", (long)a, (long)d, (long)c, (long)b); */ igraph_add_edges(graph, &edgevec, 0); } num_successful_swaps++; } break; default: RNG_END(); IGRAPH_ERROR("unknown rewiring mode", IGRAPH_EINVMODE); } num_swaps++; } if (use_adjlist) { /* Replace graph edges with the adjlist current state */ IGRAPH_CHECK(igraph_delete_edges(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID))); IGRAPH_CHECK(igraph_add_edges(graph, &alledges, 0)); } IGRAPH_PROGRESS("Random rewiring: ", 100.0, 0); if (use_adjlist) { igraph_vector_destroy(&alledges); igraph_adjlist_destroy(&al); } else { igraph_vector_destroy(&edgevec); } igraph_vector_destroy(&eids); IGRAPH_FINALLY_CLEAN(use_adjlist ? 3 : 2); RNG_END(); return 0; } /** * \ingroup structural * \function igraph_rewire * \brief Randomly rewires a graph while preserving the degree distribution. * * * This function generates a new graph based on the original one by randomly * rewiring edges while preserving the original graph's degree distribution. * Please note that the rewiring is done "in place", so no new graph will * be allocated. If you would like to keep the original graph intact, use * \ref igraph_copy() beforehand. * * \param graph The graph object to be rewired. * \param n Number of rewiring trials to perform. * \param mode The rewiring algorithm to be used. It can be one of the following flags: * \clist * \cli IGRAPH_REWIRING_SIMPLE * Simple rewiring algorithm which chooses two arbitrary edges * in each step (namely (a,b) and (c,d)) and substitutes them * with (a,d) and (c,b) if they don't exist. The method will * neither destroy nor create self-loops. * \cli IGRAPH_REWIRING_SIMPLE_LOOPS * Same as \c IGRAPH_REWIRING_SIMPLE but allows the creation or * destruction of self-loops. * \endclist * * \return Error code: * \clist * \cli IGRAPH_EINVMODE * Invalid rewiring mode. * \cli IGRAPH_EINVAL * Graph unsuitable for rewiring (e.g. it has * less than 4 nodes in case of \c IGRAPH_REWIRING_SIMPLE) * \cli IGRAPH_ENOMEM * Not enough memory for temporary data. * \endclist * * Time complexity: TODO. */ int igraph_rewire(igraph_t *graph, igraph_integer_t n, igraph_rewiring_t mode) { igraph_bool_t use_adjlist = n >= REWIRE_ADJLIST_THRESHOLD; return igraph_i_rewire(graph, n, mode, use_adjlist); } leidenbase/src/core/operators/subgraph.h0000644000176200001440000000232314447675375020114 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_OPERATORS_SUBGRAPH_INTERNAL_H #define IGRAPH_OPERATORS_SUBGRAPH_INTERNAL_H #include "igraph_interface.h" IGRAPH_PRIVATE_EXPORT int igraph_i_induced_subgraph_map( const igraph_t *graph, igraph_t *res, const igraph_vs_t vids, igraph_subgraph_implementation_t impl, igraph_vector_t *map, igraph_vector_t *invmap, igraph_bool_t map_is_prepared ); #endif leidenbase/src/core/operators/subgraph.c0000644000176200001440000004231114447675375020110 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "core/interruption.h" #include "graph/attributes.h" #include "operators/subgraph.h" /** * Subgraph creation, old version: it copies the graph and then deletes * unneeded vertices. */ static int igraph_i_induced_subgraph_copy_and_delete( const igraph_t *graph, igraph_t *res, const igraph_vs_t vids, igraph_vector_t *map, igraph_vector_t *invmap ) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t delete = IGRAPH_VECTOR_NULL; char *remain; long int i; igraph_vit_t vit; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_VECTOR_INIT_FINALLY(&delete, 0); remain = IGRAPH_CALLOC(no_of_nodes, char); if (remain == 0) { IGRAPH_ERROR("subgraph failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, remain); IGRAPH_CHECK(igraph_vector_reserve(&delete, no_of_nodes - IGRAPH_VIT_SIZE(vit))); for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { remain[ (long int) IGRAPH_VIT_GET(vit) ] = 1; } for (i = 0; i < no_of_nodes; i++) { IGRAPH_ALLOW_INTERRUPTION(); if (remain[i] == 0) { IGRAPH_CHECK(igraph_vector_push_back(&delete, i)); } } IGRAPH_FREE(remain); IGRAPH_FINALLY_CLEAN(1); /* must set res->attr to 0 before calling igraph_copy */ res->attr = 0; /* Why is this needed? TODO */ IGRAPH_CHECK(igraph_copy(res, graph)); IGRAPH_FINALLY(igraph_destroy, res); IGRAPH_CHECK(igraph_delete_vertices_idx(res, igraph_vss_vector(&delete), map, invmap)); igraph_vector_destroy(&delete); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * Subgraph creation, new version: creates the new graph instead of * copying the old one. * * map_is_prepared is an indicator that the caller has already prepared the * 'map' vector and that this function should not resize or clear it. This * is used to spare an O(n) operation (where n is the number of vertices in * the _original_ graph) in cases when induced_subgraph() is repeatedly * called on the same graph; one example is igraph_decompose(). */ static int igraph_i_induced_subgraph_create_from_scratch( const igraph_t *graph, igraph_t *res, const igraph_vs_t vids, igraph_vector_t *map, igraph_vector_t *invmap, igraph_bool_t map_is_prepared ) { igraph_bool_t directed = igraph_is_directed(graph); long int no_of_nodes = igraph_vcount(graph); long int no_of_new_nodes = 0; long int i, j, n; long int to; igraph_integer_t eid; igraph_vector_t vids_old2new, vids_new2old; igraph_vector_t eids_new2old; igraph_vector_t nei_edges; igraph_vector_t new_edges; igraph_vit_t vit; igraph_vector_t *my_vids_old2new = &vids_old2new, *my_vids_new2old = &vids_new2old; /* The order of initialization is important here, they will be destroyed in the * opposite order */ IGRAPH_VECTOR_INIT_FINALLY(&eids_new2old, 0); if (invmap) { my_vids_new2old = invmap; igraph_vector_clear(my_vids_new2old); } else { IGRAPH_VECTOR_INIT_FINALLY(&vids_new2old, 0); } IGRAPH_VECTOR_INIT_FINALLY(&new_edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&nei_edges, 0); if (map) { my_vids_old2new = map; if (!map_is_prepared) { IGRAPH_CHECK(igraph_vector_resize(map, no_of_nodes)); igraph_vector_null(map); } } else { IGRAPH_VECTOR_INIT_FINALLY(&vids_old2new, no_of_nodes); } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); /* Calculate the mapping from the old node IDs to the new ones. The other * igraph_simplify implementation in igraph_i_simplify_copy_and_delete * ensures that the order of vertex IDs is kept during remapping (i.e. * if the old ID of vertex A is less than the old ID of vertex B, then * the same will also be true for the new IDs). To ensure compatibility * with the other implementation, we have to fetch the vertex IDs into * a vector first and then sort it. We temporarily use new_edges for that. */ IGRAPH_CHECK(igraph_vit_as_vector(&vit, &nei_edges)); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); igraph_vector_sort(&nei_edges); n = igraph_vector_size(&nei_edges); for (i = 0; i < n; i++) { long int vid = (long int) VECTOR(nei_edges)[i]; if (VECTOR(*my_vids_old2new)[vid] == 0) { IGRAPH_CHECK(igraph_vector_push_back(my_vids_new2old, vid)); no_of_new_nodes++; VECTOR(*my_vids_old2new)[vid] = no_of_new_nodes; } } /* Create the new edge list */ for (i = 0; i < no_of_new_nodes; i++) { long int old_vid = (long int) VECTOR(*my_vids_new2old)[i]; long int new_vid = i; igraph_bool_t skip_loop_edge; IGRAPH_CHECK(igraph_incident(graph, &nei_edges, old_vid, IGRAPH_OUT)); n = igraph_vector_size(&nei_edges); if (directed) { /* directed graph; this is easier */ for (j = 0; j < n; j++) { eid = (igraph_integer_t) VECTOR(nei_edges)[j]; to = (long int) VECTOR(*my_vids_old2new)[ (long int)IGRAPH_TO(graph, eid) ]; if (!to) { continue; } IGRAPH_CHECK(igraph_vector_push_back(&new_edges, new_vid)); IGRAPH_CHECK(igraph_vector_push_back(&new_edges, to - 1)); IGRAPH_CHECK(igraph_vector_push_back(&eids_new2old, eid)); } } else { /* undirected graph. We need to be careful with loop edges as each * loop edge will appear twice. We use a boolean flag to skip every * second loop edge */ skip_loop_edge = 0; for (j = 0; j < n; j++) { eid = (igraph_integer_t) VECTOR(nei_edges)[j]; if (IGRAPH_FROM(graph, eid) != old_vid) { /* avoid processing edges twice */ continue; } to = (long int) VECTOR(*my_vids_old2new)[ (long int)IGRAPH_TO(graph, eid) ]; if (!to) { continue; } to -= 1; if (new_vid == to) { /* this is a loop edge; check whether we need to skip it */ skip_loop_edge = !skip_loop_edge; if (skip_loop_edge) { continue; } } IGRAPH_CHECK(igraph_vector_push_back(&new_edges, new_vid)); IGRAPH_CHECK(igraph_vector_push_back(&new_edges, to)); IGRAPH_CHECK(igraph_vector_push_back(&eids_new2old, eid)); } } } /* Get rid of some vectors that are not needed anymore */ if (!map) { igraph_vector_destroy(&vids_old2new); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&nei_edges); IGRAPH_FINALLY_CLEAN(1); /* Create the new graph */ IGRAPH_CHECK(igraph_create(res, &new_edges, (igraph_integer_t) no_of_new_nodes, directed)); IGRAPH_I_ATTRIBUTE_DESTROY(res); /* Now we can also get rid of the new_edges vector */ igraph_vector_destroy(&new_edges); IGRAPH_FINALLY_CLEAN(1); /* Make sure that the newly created graph is destroyed if something happens from * now on */ IGRAPH_FINALLY(igraph_destroy, res); /* Copy the graph attributes */ IGRAPH_CHECK(igraph_i_attribute_copy(res, graph, /* ga = */ 1, /* va = */ 0, /* ea = */ 0)); /* Copy the vertex attributes */ IGRAPH_CHECK(igraph_i_attribute_permute_vertices(graph, res, my_vids_new2old)); /* Copy the edge attributes */ IGRAPH_CHECK(igraph_i_attribute_permute_edges(graph, res, &eids_new2old)); if (!invmap) { igraph_vector_destroy(my_vids_new2old); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&eids_new2old); IGRAPH_FINALLY_CLEAN(2); /* 1 + 1 since we don't need to destroy res */ return 0; } /** * \ingroup structural * \function igraph_induced_subgraph * \brief Creates a subgraph induced by the specified vertices. * * * This function collects the specified vertices and all edges between * them to a new graph. * As the vertex ids in a graph always start with zero, this function * very likely needs to reassign ids to the vertices. * \param graph The graph object. * \param res The subgraph, another graph object will be stored here, * do \em not initialize this object before calling this * function, and call \ref igraph_destroy() on it if you don't need * it any more. * \param vids A vertex selector describing which vertices to keep. * \param impl This parameter selects which implementation should we * use when constructing the new graph. Basically there are two * possibilities: \c IGRAPH_SUBGRAPH_COPY_AND_DELETE copies the * existing graph and deletes the vertices that are not needed * in the new graph, while \c IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH * constructs the new graph from scratch without copying the old * one. The latter is more efficient if you are extracting a * relatively small subpart of a very large graph, while the * former is better if you want to extract a subgraph whose size * is comparable to the size of the whole graph. There is a third * possibility: \c IGRAPH_SUBGRAPH_AUTO will select one of the * two methods automatically based on the ratio of the number * of vertices in the new and the old graph. * * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * \c IGRAPH_EINVVID, invalid vertex id in * \p vids. * * Time complexity: O(|V|+|E|), * |V| and * |E| are the number of vertices and * edges in the original graph. * * \sa \ref igraph_delete_vertices() to delete the specified set of * vertices from a graph, the opposite of this function. */ int igraph_induced_subgraph(const igraph_t *graph, igraph_t *res, const igraph_vs_t vids, igraph_subgraph_implementation_t impl) { return igraph_induced_subgraph_map(graph, res, vids, impl, /* map= */ 0, /* invmap= */ 0); } static int igraph_i_induced_subgraph_suggest_implementation( const igraph_t *graph, const igraph_vs_t vids, igraph_subgraph_implementation_t *result) { double ratio; igraph_integer_t num_vs; if (igraph_vs_is_all(&vids)) { ratio = 1.0; } else { IGRAPH_CHECK(igraph_vs_size(graph, &vids, &num_vs)); ratio = (igraph_real_t) num_vs / igraph_vcount(graph); } /* TODO: needs benchmarking; threshold was chosen totally arbitrarily */ if (ratio > 0.5) { *result = IGRAPH_SUBGRAPH_COPY_AND_DELETE; } else { *result = IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH; } return 0; } int igraph_i_induced_subgraph_map(const igraph_t *graph, igraph_t *res, const igraph_vs_t vids, igraph_subgraph_implementation_t impl, igraph_vector_t *map, igraph_vector_t *invmap, igraph_bool_t map_is_prepared) { if (impl == IGRAPH_SUBGRAPH_AUTO) { IGRAPH_CHECK(igraph_i_induced_subgraph_suggest_implementation(graph, vids, &impl)); } switch (impl) { case IGRAPH_SUBGRAPH_COPY_AND_DELETE: return igraph_i_induced_subgraph_copy_and_delete(graph, res, vids, map, invmap); case IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH: return igraph_i_induced_subgraph_create_from_scratch(graph, res, vids, map, invmap, /* map_is_prepared = */ map_is_prepared); default: IGRAPH_ERROR("unknown subgraph implementation type", IGRAPH_EINVAL); } } int igraph_induced_subgraph_map(const igraph_t *graph, igraph_t *res, const igraph_vs_t vids, igraph_subgraph_implementation_t impl, igraph_vector_t *map, igraph_vector_t *invmap) { return igraph_i_induced_subgraph_map(graph, res,vids, impl, map, invmap, /* map_is_prepared = */ 0); } /** * \ingroup structural * \function igraph_subgraph_edges * \brief Creates a subgraph with the specified edges and their endpoints. * * * This function collects the specified edges and their endpoints to a new * graph. * As the vertex ids in a graph always start with zero, this function * very likely needs to reassign ids to the vertices. * \param graph The graph object. * \param res The subgraph, another graph object will be stored here, * do \em not initialize this object before calling this * function, and call \ref igraph_destroy() on it if you don't need * it any more. * \param eids An edge selector describing which edges to keep. * \param delete_vertices Whether to delete the vertices not incident on any * of the specified edges as well. If \c FALSE, the number of vertices * in the result graph will always be equal to the number of vertices * in the input graph. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * \c IGRAPH_EINVEID, invalid edge id in * \p eids. * * Time complexity: O(|V|+|E|), * |V| and * |E| are the number of vertices and * edges in the original graph. * * \sa \ref igraph_delete_edges() to delete the specified set of * edges from a graph, the opposite of this function. */ int igraph_subgraph_edges(const igraph_t *graph, igraph_t *res, const igraph_es_t eids, igraph_bool_t delete_vertices) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vector_t delete = IGRAPH_VECTOR_NULL; char *vremain, *eremain; long int i; igraph_eit_t eit; IGRAPH_CHECK(igraph_eit_create(graph, eids, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); IGRAPH_VECTOR_INIT_FINALLY(&delete, 0); vremain = IGRAPH_CALLOC(no_of_nodes, char); if (vremain == 0) { IGRAPH_ERROR("subgraph_edges failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, vremain); eremain = IGRAPH_CALLOC(no_of_edges, char); if (eremain == 0) { IGRAPH_ERROR("subgraph_edges failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, eremain); IGRAPH_CHECK(igraph_vector_reserve(&delete, no_of_edges - IGRAPH_EIT_SIZE(eit))); /* Collect the vertex and edge IDs that will remain */ for (IGRAPH_EIT_RESET(eit); !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { igraph_integer_t from, to; long int eid = (long int) IGRAPH_EIT_GET(eit); IGRAPH_CHECK(igraph_edge(graph, (igraph_integer_t) eid, &from, &to)); eremain[eid] = vremain[(long int)from] = vremain[(long int)to] = 1; } /* Collect the edge IDs to be deleted */ for (i = 0; i < no_of_edges; i++) { IGRAPH_ALLOW_INTERRUPTION(); if (eremain[i] == 0) { IGRAPH_CHECK(igraph_vector_push_back(&delete, i)); } } IGRAPH_FREE(eremain); IGRAPH_FINALLY_CLEAN(1); /* Delete the unnecessary edges */ /* must set res->attr to 0 before calling igraph_copy */ res->attr = 0; /* Why is this needed? TODO */ IGRAPH_CHECK(igraph_copy(res, graph)); IGRAPH_FINALLY(igraph_destroy, res); IGRAPH_CHECK(igraph_delete_edges(res, igraph_ess_vector(&delete))); if (delete_vertices) { /* Collect the vertex IDs to be deleted */ igraph_vector_clear(&delete); for (i = 0; i < no_of_nodes; i++) { IGRAPH_ALLOW_INTERRUPTION(); if (vremain[i] == 0) { IGRAPH_CHECK(igraph_vector_push_back(&delete, i)); } } } IGRAPH_FREE(vremain); IGRAPH_FINALLY_CLEAN(1); /* Delete the unnecessary vertices */ if (delete_vertices) { IGRAPH_CHECK(igraph_delete_vertices(res, igraph_vss_vector(&delete))); } igraph_vector_destroy(&delete); igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(3); return 0; } leidenbase/src/core/operators/connect_neighborhood.c0000644000176200001440000001412314447675375022455 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" /** * \function igraph_connect_neighborhood * \brief Connects every vertex to its neighborhood * * This function adds new edges to the input graph. Each vertex is connected * to all vertices reachable by at most \p order steps from it * (unless a connection already existed). In other words, the \p order power of * the graph is computed. * * Note that the input graph is modified in place, no * new graph is created. Call \ref igraph_copy() if you want to keep * the original graph as well. * * For undirected graphs reachability is always * symmetric: if vertex A can be reached from vertex B in at * most \p order steps, then the opposite is also true. Only one * undirected (A,B) edge will be added in this case. * \param graph The input graph, this is the output graph as well. * \param order Integer constant, it gives the distance within which * the vertices will be connected to the source vertex. * \param mode Constant, it specifies how the neighborhood search is * performed for directed graphs. If \c IGRAPH_OUT then vertices * reachable from the source vertex will be connected, \c IGRAPH_IN * is the opposite. If \c IGRAPH_ALL then the directed graph is * considered as an undirected one. * \return Error code. * * \sa \ref igraph_lattice() uses this function to connect the * neighborhood of the vertices. * * Time complexity: O(|V|*d^k), |V| is the number of vertices in the * graph, d is the average degree and k is the \p order argument. */ int igraph_connect_neighborhood(igraph_t *graph, igraph_integer_t order, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); igraph_dqueue_t q; igraph_vector_t edges; long int i, j, in; long int *added; igraph_vector_t neis; if (order < 0) { IGRAPH_ERROR("Negative order, cannot connect neighborhood", IGRAPH_EINVAL); } if (order < 2) { IGRAPH_WARNING("Order smaller than two, graph will be unchanged"); } if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); added = IGRAPH_CALLOC(no_of_nodes, long int); if (added == 0) { IGRAPH_ERROR("Cannot connect neighborhood", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); for (i = 0; i < no_of_nodes; i++) { added[i] = i + 1; igraph_neighbors(graph, &neis, (igraph_integer_t) i, mode); in = igraph_vector_size(&neis); if (order > 1) { for (j = 0; j < in; j++) { long int nei = (long int) VECTOR(neis)[j]; added[nei] = i + 1; igraph_dqueue_push(&q, nei); igraph_dqueue_push(&q, 1); } } while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); long int n; igraph_neighbors(graph, &neis, (igraph_integer_t) actnode, mode); n = igraph_vector_size(&neis); if (actdist < order - 1) { for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (added[nei] != i + 1) { added[nei] = i + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, nei)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); if (mode != IGRAPH_ALL || i < nei) { if (mode == IGRAPH_IN) { IGRAPH_CHECK(igraph_vector_push_back(&edges, nei)); IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); } else { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, nei)); } } } } } else { for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (added[nei] != i + 1) { added[nei] = i + 1; if (mode != IGRAPH_ALL || i < nei) { if (mode == IGRAPH_IN) { IGRAPH_CHECK(igraph_vector_push_back(&edges, nei)); IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); } else { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, nei)); } } } } } } /* while q not empty */ } /* for i < no_of_nodes */ igraph_vector_destroy(&neis); igraph_dqueue_destroy(&q); igraph_free(added); IGRAPH_FINALLY_CLEAN(3); IGRAPH_CHECK(igraph_add_edges(graph, &edges, 0)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/operators/disjoint_union.c0000644000176200001440000001424214447675375021332 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "operators/misc_internal.h" /** * \function igraph_disjoint_union * \brief Creates the union of two disjoint graphs * * * First the vertices of the second graph will be relabeled with new * vertex ids to have two disjoint sets of vertex ids, then the union * of the two graphs will be formed. * If the two graphs have |V1| and |V2| vertices and |E1| and |E2| * edges respectively then the new graph will have |V1|+|V2| vertices * and |E1|+|E2| edges. * * * Both graphs need to have the same directedness, i.e. either both * directed or both undirected. * * * The current version of this function cannot handle graph, vertex * and edge attributes, they will be lost. * * \param res Pointer to an uninitialized graph object, the result * will stored here. * \param left The first graph. * \param right The second graph. * \return Error code. * \sa \ref igraph_disjoint_union_many() for creating the disjoint union * of more than two graphs, \ref igraph_union() for non-disjoint * union. * * Time complexity: O(|V1|+|V2|+|E1|+|E2|). * * \example examples/simple/igraph_disjoint_union.c */ int igraph_disjoint_union(igraph_t *res, const igraph_t *left, const igraph_t *right) { long int no_of_nodes_left = igraph_vcount(left); long int no_of_nodes_right = igraph_vcount(right); long int no_of_edges_left = igraph_ecount(left); long int no_of_edges_right = igraph_ecount(right); igraph_vector_t edges; igraph_bool_t directed_left = igraph_is_directed(left); igraph_integer_t from, to; long int i; if (directed_left != igraph_is_directed(right)) { IGRAPH_ERROR("Cannot union directed and undirected graphs", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, 2 * (no_of_edges_left + no_of_edges_right))); for (i = 0; i < no_of_edges_left; i++) { igraph_edge(left, (igraph_integer_t) i, &from, &to); igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } for (i = 0; i < no_of_edges_right; i++) { igraph_edge(right, (igraph_integer_t) i, &from, &to); igraph_vector_push_back(&edges, from + no_of_nodes_left); igraph_vector_push_back(&edges, to + no_of_nodes_left); } IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) (no_of_nodes_left + no_of_nodes_right), directed_left)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_disjoint_union_many * \brief The disjint union of many graphs. * * * First the vertices in the graphs will be relabeled with new vertex * ids to have pairwise disjoint vertex id sets and then the union of * the graphs is formed. * The number of vertices and edges in the result is the total number * of vertices and edges in the graphs. * * * All graphs need to have the same directedness, i.e. either all * directed or all undirected. If the graph list has length zero, * the result will be a \em directed graph with no vertices. * * * The current version of this function cannot handle graph, vertex * and edge attributes, they will be lost. * * \param res Pointer to an uninitialized graph object, the result of * the operation will be stored here. * \param graphs Pointer vector, contains pointers to initialized * graph objects. * \return Error code. * \sa \ref igraph_disjoint_union() for an easier syntax if you have * only two graphs, \ref igraph_union_many() for non-disjoint union. * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges in the result. */ int igraph_disjoint_union_many(igraph_t *res, const igraph_vector_ptr_t *graphs) { long int no_of_graphs = igraph_vector_ptr_size(graphs); igraph_bool_t directed = 1; igraph_vector_t edges; long int no_of_edges = 0; long int shift = 0; igraph_t *graph; long int i, j; igraph_integer_t from, to; if (no_of_graphs != 0) { graph = VECTOR(*graphs)[0]; directed = igraph_is_directed(graph); for (i = 0; i < no_of_graphs; i++) { graph = VECTOR(*graphs)[i]; no_of_edges += igraph_ecount(graph); if (directed != igraph_is_directed(graph)) { IGRAPH_ERROR("Cannot union directed and undirected graphs", IGRAPH_EINVAL); } } } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, 2 * no_of_edges)); for (i = 0; i < no_of_graphs; i++) { long int ec; graph = VECTOR(*graphs)[i]; ec = igraph_ecount(graph); for (j = 0; j < ec; j++) { igraph_edge(graph, (igraph_integer_t) j, &from, &to); igraph_vector_push_back(&edges, from + shift); igraph_vector_push_back(&edges, to + shift); } shift += igraph_vcount(graph); } IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) shift, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/operators/misc_internal.h0000644000176200001440000000307414447675375021134 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2020 The igraph development team 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_OPERATORS_MISC_INTERNAL_H #define IGRAPH_OPERATORS_MISC_INTERNAL_H #include "igraph_decls.h" #include "igraph_datatype.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS #define IGRAPH_MERGE_MODE_UNION 1 #define IGRAPH_MERGE_MODE_INTERSECTION 2 int igraph_i_order_edgelist_cmp(void *edges, const void *e1, const void *e2); int igraph_i_merge(igraph_t *res, int mode, const igraph_t *left, const igraph_t *right, igraph_vector_t *edge_map1, igraph_vector_t *edge_map2); void igraph_i_union_intersection_destroy_vectors(igraph_vector_ptr_t *v); void igraph_i_union_intersection_destroy_vector_longs(igraph_vector_ptr_t *v); __END_DECLS #endif leidenbase/src/core/operators/union.c0000644000176200001440000002326614447675375017435 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "igraph_operators.h" #include "igraph_constructors.h" #include "igraph_conversion.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_qsort.h" #include "operators/misc_internal.h" /** * \function igraph_union * \brief Calculates the union of two graphs. * * * The number of vertices in the result is that of the larger graph * from the two arguments. The result graph contains edges which are * present in at least one of the operand graphs. * * \param res Pointer to an uninitialized graph object, the result * will be stored here. * \param left The first graph. * \param right The second graph. * \param edge_map1 Pointer to an initialized vector or a null pointer. * If not a null pointer, it will contain a mapping from the edges * of the first argument graph (\p left) to the edges of the * result graph. * \param edge_map2 The same as \p edge_map1, but for the second * graph, \p right. * \return Error code. * \sa \ref igraph_union_many() for the union of many graphs, * \ref igraph_intersection() and \ref igraph_difference() for other * operators. * * Time complexity: O(|V|+|E|), |V| is the number of * vertices, |E| the number of edges in the result graph. * * \example examples/simple/igraph_union.c */ int igraph_union(igraph_t *res, const igraph_t *left, const igraph_t *right, igraph_vector_t *edge_map1, igraph_vector_t *edge_map2) { return igraph_i_merge(res, IGRAPH_MERGE_MODE_UNION, left, right, edge_map1, edge_map2); } /** * \function igraph_union_many * \brief Creates the union of many graphs. * * * The result graph will contain as many vertices as the largest graph * among the arguments does, and an edge will be included in it if it * is part of at least one operand graph. * * * The directedness of the operand graphs must be the same. * If the graph list has length zero, the result will be a \em directed * graph with no vertices. * * \param res Pointer to an uninitialized graph object, this will * contain the result. * \param graphs Pointer vector, contains pointers to the operands of * the union operator, graph objects of course. * \param edgemaps If not a null pointer, then it must be an initialized * pointer vector and the mappings of edges from the graphs to the * result graph will be stored here, in the same order as * \p graphs. Each mapping is stored in a separate * \type igraph_vector_t object. * \return Error code. * \sa \ref igraph_union() for the union of two graphs, \ref * igraph_intersection_many(), \ref igraph_intersection() and \ref * igraph_difference for other operators. * * * Time complexity: O(|V|+|E|), |V| is the number of vertices * in largest graph and |E| is the number of edges in the result graph. * * \example examples/simple/igraph_union.c */ int igraph_union_many(igraph_t *res, const igraph_vector_ptr_t *graphs, igraph_vector_ptr_t *edgemaps) { long int no_of_graphs = igraph_vector_ptr_size(graphs); long int no_of_nodes = 0; igraph_bool_t directed = 1; igraph_vector_t edges; igraph_vector_ptr_t edge_vects, order_vects; igraph_vector_long_t no_edges; long int i, j, tailfrom = no_of_graphs > 0 ? 0 : -1, tailto = -1; long int idx = 0; /* Check directedness */ if (no_of_graphs != 0) { directed = igraph_is_directed(VECTOR(*graphs)[0]); no_of_nodes = igraph_vcount(VECTOR(*graphs)[0]); } for (i = 1; i < no_of_graphs; i++) { if (directed != igraph_is_directed(VECTOR(*graphs)[i])) { IGRAPH_ERROR("Cannot union directed and undirected graphs", IGRAPH_EINVAL); } } if (edgemaps) { IGRAPH_CHECK(igraph_vector_ptr_resize(edgemaps, no_of_graphs)); igraph_vector_ptr_null(edgemaps); IGRAPH_FINALLY(igraph_i_union_intersection_destroy_vectors, edgemaps); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_long_init(&no_edges, no_of_graphs)); IGRAPH_FINALLY(igraph_vector_long_destroy, &no_edges); /* Calculate number of nodes, query number of edges */ for (i = 0; i < no_of_graphs; i++) { long int n = igraph_vcount(VECTOR(*graphs)[i]); if (n > no_of_nodes) { no_of_nodes = n; } VECTOR(no_edges)[i] = igraph_ecount(VECTOR(*graphs)[i]); } if (edgemaps) { for (i = 0; i < no_of_graphs; i++) { VECTOR(*edgemaps)[i] = IGRAPH_CALLOC(1, igraph_vector_t); if (!VECTOR(*edgemaps)[i]) { IGRAPH_ERROR("Cannot union graphs", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(VECTOR(*edgemaps)[i], VECTOR(no_edges)[i])); } } /* Allocate memory for the edge lists and their index vectors */ if (no_of_graphs != 0) { IGRAPH_CHECK(igraph_vector_ptr_init(&edge_vects, no_of_graphs)); IGRAPH_FINALLY(igraph_i_union_intersection_destroy_vectors, &edge_vects); IGRAPH_CHECK(igraph_vector_ptr_init(&order_vects, no_of_graphs)); IGRAPH_FINALLY(igraph_i_union_intersection_destroy_vector_longs, &order_vects); } for (i = 0; i < no_of_graphs; i++) { VECTOR(edge_vects)[i] = IGRAPH_CALLOC(1, igraph_vector_t); VECTOR(order_vects)[i] = IGRAPH_CALLOC(1, igraph_vector_long_t); if (! VECTOR(edge_vects)[i] || ! VECTOR(order_vects)[i]) { IGRAPH_ERROR("Cannot union graphs", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(VECTOR(edge_vects)[i], 2 * VECTOR(no_edges)[i])); IGRAPH_CHECK(igraph_vector_long_init(VECTOR(order_vects)[i], VECTOR(no_edges)[i])); } /* Query and sort the edge lists */ for (i = 0; i < no_of_graphs; i++) { long int k, j, n = VECTOR(no_edges)[i]; igraph_vector_t *edges = VECTOR(edge_vects)[i]; igraph_vector_long_t *order = VECTOR(order_vects)[i]; IGRAPH_CHECK(igraph_get_edgelist(VECTOR(*graphs)[i], edges, /*bycol=*/0)); if (!directed) { for (k = 0, j = 0; k < n; k++, j += 2) { if (VECTOR(*edges)[j] > VECTOR(*edges)[j + 1]) { long int tmp = VECTOR(*edges)[j]; VECTOR(*edges)[j] = VECTOR(*edges)[j + 1]; VECTOR(*edges)[j + 1] = tmp; } } } for (k = 0; k < n; k++) { VECTOR(*order)[k] = k; } igraph_qsort_r(VECTOR(*order), n, sizeof(VECTOR(*order)[0]), edges, igraph_i_order_edgelist_cmp); } while (tailfrom >= 0) { /* Get the largest tail element */ tailfrom = tailto = -1; for (j = 0; j < no_of_graphs; j++) { if (!igraph_vector_long_empty(VECTOR(order_vects)[j])) { long int edge = igraph_vector_long_tail(VECTOR(order_vects)[j]); igraph_vector_t *ev = VECTOR(edge_vects)[j]; long int from = VECTOR(*ev)[2 * edge]; long int to = VECTOR(*ev)[2 * edge + 1]; if (from > tailfrom || (from == tailfrom && to > tailto)) { tailfrom = from; tailto = to; } } } if (tailfrom < 0) { continue; } /* add the edge */ IGRAPH_CHECK(igraph_vector_push_back(&edges, tailfrom)); IGRAPH_CHECK(igraph_vector_push_back(&edges, tailto)); /* update edge lists, we just modify the 'order' vectors */ for (j = 0; j < no_of_graphs; j++) { if (!igraph_vector_long_empty(VECTOR(order_vects)[j])) { long int edge = igraph_vector_long_tail(VECTOR(order_vects)[j]); igraph_vector_t *ev = VECTOR(edge_vects)[j]; long int from = VECTOR(*ev)[2 * edge]; long int to = VECTOR(*ev)[2 * edge + 1]; if (from == tailfrom && to == tailto) { igraph_vector_long_pop_back(VECTOR(order_vects)[j]); if (edgemaps) { igraph_vector_t *map = VECTOR(*edgemaps)[j]; VECTOR(*map)[edge] = idx; } } } } idx++; } if (no_of_graphs > 0) { igraph_i_union_intersection_destroy_vector_longs(&order_vects); igraph_i_union_intersection_destroy_vectors(&edge_vects); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_long_destroy(&no_edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); if (edgemaps) { IGRAPH_FINALLY_CLEAN(1); } return 0; } leidenbase/src/core/operators/difference.c0000644000176200001440000001443514447675375020375 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_adjlist.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "graph/attributes.h" #include "core/interruption.h" /** * \function igraph_difference * \brief Calculate the difference of two graphs * * * The number of vertices in the result is the number of vertices in * the original graph, i.e. the left, first operand. In the results * graph only edges will be included from \p orig which are not * present in \p sub. * * \param res Pointer to an uninitialized graph object, the result * will be stored here. * \param orig The left operand of the operator, a graph object. * \param sub The right operand of the operator, a graph object. * \return Error code. * \sa \ref igraph_intersection() and \ref igraph_union() for other * operators. * * Time complexity: O(|V|+|E|), |V| is the number vertices in * the smaller graph, |E| is the * number of edges in the result graph. * * \example examples/simple/igraph_difference.c */ int igraph_difference(igraph_t *res, const igraph_t *orig, const igraph_t *sub) { /* Quite nasty, but we will use that an edge adjacency list contains the vertices according to the order of the vertex ids at the "other" end of the edge. */ long int no_of_nodes_orig = igraph_vcount(orig); long int no_of_nodes_sub = igraph_vcount(sub); long int no_of_nodes = no_of_nodes_orig; long int smaller_nodes; igraph_bool_t directed = igraph_is_directed(orig); igraph_vector_t edges; igraph_vector_t edge_ids; igraph_vector_int_t *nei1, *nei2; igraph_inclist_t inc_orig, inc_sub; long int i; igraph_integer_t v1, v2; if (directed != igraph_is_directed(sub)) { IGRAPH_ERROR("Cannot subtract directed and undirected graphs", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edge_ids, 0); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_inclist_init(orig, &inc_orig, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &inc_orig); IGRAPH_CHECK(igraph_inclist_init(sub, &inc_sub, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &inc_sub); smaller_nodes = no_of_nodes_orig > no_of_nodes_sub ? no_of_nodes_sub : no_of_nodes_orig; for (i = 0; i < smaller_nodes; i++) { long int n1, n2, e1, e2; IGRAPH_ALLOW_INTERRUPTION(); nei1 = igraph_inclist_get(&inc_orig, i); nei2 = igraph_inclist_get(&inc_sub, i); n1 = igraph_vector_int_size(nei1) - 1; n2 = igraph_vector_int_size(nei2) - 1; while (n1 >= 0 && n2 >= 0) { e1 = (long int) VECTOR(*nei1)[n1]; e2 = (long int) VECTOR(*nei2)[n2]; v1 = IGRAPH_OTHER(orig, e1, i); v2 = IGRAPH_OTHER(sub, e2, i); if (!directed && v1 < i) { n1--; } else if (!directed && v2 < i) { n2--; } else if (v1 > v2) { IGRAPH_CHECK(igraph_vector_push_back(&edge_ids, e1)); IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, v1)); n1--; /* handle loop edges properly in undirected graphs */ if (!directed && i == v1) { n1--; } } else if (v2 > v1) { n2--; } else { n1--; n2--; } } /* Copy remaining edges */ while (n1 >= 0) { e1 = (long int) VECTOR(*nei1)[n1]; v1 = IGRAPH_OTHER(orig, e1, i); if (directed || v1 >= i) { IGRAPH_CHECK(igraph_vector_push_back(&edge_ids, e1)); IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, v1)); /* handle loop edges properly in undirected graphs */ if (!directed && v1 == i) { n1--; } } n1--; } } /* copy remaining edges, use the previous value of 'i' */ for (; i < no_of_nodes_orig; i++) { long int n1, e1; nei1 = igraph_inclist_get(&inc_orig, i); n1 = igraph_vector_int_size(nei1) - 1; while (n1 >= 0) { e1 = (long int) VECTOR(*nei1)[n1]; v1 = IGRAPH_OTHER(orig, e1, i); if (directed || v1 >= i) { IGRAPH_CHECK(igraph_vector_push_back(&edge_ids, e1)); IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, v1)); /* handle loop edges properly in undirected graphs */ if (!directed && v1 == i) { n1--; } } n1--; } } igraph_inclist_destroy(&inc_sub); igraph_inclist_destroy(&inc_orig); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); /* Attributes */ if (orig->attr) { IGRAPH_I_ATTRIBUTE_DESTROY(res); IGRAPH_I_ATTRIBUTE_COPY(res, orig, /*graph=*/1, /*vertex=*/1, /*edge=*/0); IGRAPH_CHECK(igraph_i_attribute_permute_edges(orig, res, &edge_ids)); } igraph_vector_destroy(&edge_ids); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/operators/contract.c0000644000176200001440000001244214447675375020114 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "graph/attributes.h" static void igraph_i_simplify_free(igraph_vector_ptr_t *p) { long int i, n = igraph_vector_ptr_size(p); for (i = 0; i < n; i++) { igraph_vector_t *v = VECTOR(*p)[i]; if (v) { igraph_vector_destroy(v); } } igraph_vector_ptr_destroy(p); } /** * \function igraph_contract_vertices * Replace multiple vertices with a single one. * * This function creates a new graph, by merging several * vertices into one. The vertices in the new graph correspond * to sets of vertices in the input graph. * \param graph The input graph, it can be directed or * undirected. * \param mapping A vector giving the mapping. For each * vertex in the original graph, it should contain * its id in the new graph. * \param vertex_comb What to do with the vertex attributes. * \c NULL means that vertex attributes are not kept * after the contraction (not even for unaffected * vertices). See the igraph manual section about attributes * for details. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number * or vertices plus edges. */ int igraph_contract_vertices(igraph_t *graph, const igraph_vector_t *mapping, const igraph_attribute_combination_t *vertex_comb) { igraph_vector_t edges; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_bool_t vattr = vertex_comb && igraph_has_attribute_table(); igraph_t res; long int e, last = -1; long int no_new_vertices; if (igraph_vector_size(mapping) != no_of_nodes) { IGRAPH_ERROR("Invalid mapping vector length", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); if (no_of_nodes > 0) { last = (long int) igraph_vector_max(mapping); } for (e = 0; e < no_of_edges; e++) { long int from = IGRAPH_FROM(graph, e); long int to = IGRAPH_TO(graph, e); long int nfrom = (long int) VECTOR(*mapping)[from]; long int nto = (long int) VECTOR(*mapping)[to]; igraph_vector_push_back(&edges, nfrom); igraph_vector_push_back(&edges, nto); if (nfrom > last) { last = nfrom; } if (nto > last) { last = nto; } } no_new_vertices = last + 1; IGRAPH_CHECK(igraph_create(&res, &edges, (igraph_integer_t) no_new_vertices, igraph_is_directed(graph))); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &res); IGRAPH_I_ATTRIBUTE_DESTROY(&res); IGRAPH_I_ATTRIBUTE_COPY(&res, graph, /*graph=*/ 1, /*vertex=*/ 0, /*edge=*/ 1); if (vattr) { long int i; igraph_vector_ptr_t merges; igraph_vector_t sizes; igraph_vector_t *vecs; vecs = IGRAPH_CALLOC(no_new_vertices, igraph_vector_t); if (!vecs) { IGRAPH_ERROR("Cannot combine attributes while contracting" " vertices", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, vecs); IGRAPH_CHECK(igraph_vector_ptr_init(&merges, no_new_vertices)); IGRAPH_FINALLY(igraph_i_simplify_free, &merges); IGRAPH_VECTOR_INIT_FINALLY(&sizes, no_new_vertices); for (i = 0; i < no_of_nodes; i++) { long int to = (long int) VECTOR(*mapping)[i]; VECTOR(sizes)[to] += 1; } for (i = 0; i < no_new_vertices; i++) { igraph_vector_t *v = &vecs[i]; IGRAPH_CHECK(igraph_vector_init(v, (long int) VECTOR(sizes)[i])); igraph_vector_clear(v); VECTOR(merges)[i] = v; } for (i = 0; i < no_of_nodes; i++) { long int to = (long int) VECTOR(*mapping)[i]; igraph_vector_t *v = &vecs[to]; igraph_vector_push_back(v, i); } IGRAPH_CHECK(igraph_i_attribute_combine_vertices(graph, &res, &merges, vertex_comb)); igraph_vector_destroy(&sizes); igraph_i_simplify_free(&merges); igraph_free(vecs); IGRAPH_FINALLY_CLEAN(3); } IGRAPH_FINALLY_CLEAN(1); igraph_destroy(graph); *graph = res; return 0; } leidenbase/src/core/operators/compose.c0000644000176200001440000001147714447675375017753 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "core/interruption.h" /** * \function igraph_compose * \brief Calculates the composition of two graphs * * The composition of graphs contains the same number of vertices as * the bigger graph of the two operands. It contains an (i,j) edge if * and only if there is a k vertex, such that the first graphs * contains an (i,k) edge and the second graph a (k,j) edge. * * This is of course exactly the composition of two * binary relations. * * Two two graphs must have the same directedness, * otherwise the function returns with an error message. * Note that for undirected graphs the two relations are by definition * symmetric. * * \param res Pointer to an uninitialized graph object, the result * will be stored here. * \param g1 The firs operand, a graph object. * \param g2 The second operand, another graph object. * \param edge_map1 If not a null pointer, then it must be a pointer * to an initialized vector, and a mapping from the edges of * the result graph to the edges of the first graph is stored * here. * \param edge_map1 If not a null pointer, then it must be a pointer * to an initialized vector, and a mapping from the edges of * the result graph to the edges of the second graph is stored * here. * \return Error code. * * Time complexity: O(|V|*d1*d2), |V| is the number of vertices in the * first graph, d1 and d2 the average degree in the first and second * graphs. * * \example examples/simple/igraph_compose.c */ int igraph_compose(igraph_t *res, const igraph_t *g1, const igraph_t *g2, igraph_vector_t *edge_map1, igraph_vector_t *edge_map2) { long int no_of_nodes_left = igraph_vcount(g1); long int no_of_nodes_right = igraph_vcount(g2); long int no_of_nodes; igraph_bool_t directed = igraph_is_directed(g1); igraph_vector_t edges; igraph_vector_t neis1, neis2; long int i; if (directed != igraph_is_directed(g2)) { IGRAPH_ERROR("Cannot compose directed and undirected graph", IGRAPH_EINVAL); } no_of_nodes = no_of_nodes_left > no_of_nodes_right ? no_of_nodes_left : no_of_nodes_right; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&neis1, 0); IGRAPH_VECTOR_INIT_FINALLY(&neis2, 0); if (edge_map1) { igraph_vector_clear(edge_map1); } if (edge_map2) { igraph_vector_clear(edge_map2); } for (i = 0; i < no_of_nodes_left; i++) { IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_incident(g1, &neis1, (igraph_integer_t) i, IGRAPH_OUT)); while (!igraph_vector_empty(&neis1)) { long int con = (long int) igraph_vector_pop_back(&neis1); long int v1 = IGRAPH_OTHER(g1, con, i); if (v1 < no_of_nodes_right) { IGRAPH_CHECK(igraph_incident(g2, &neis2, (igraph_integer_t) v1, IGRAPH_OUT)); } else { continue; } while (!igraph_vector_empty(&neis2)) { long int con2 = igraph_vector_pop_back(&neis2); long int v2 = IGRAPH_OTHER(g2, con2, v1); IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, v2)); if (edge_map1) { IGRAPH_CHECK(igraph_vector_push_back(edge_map1, con)); } if (edge_map2) { IGRAPH_CHECK(igraph_vector_push_back(edge_map2, con2)); } } } } igraph_vector_destroy(&neis1); igraph_vector_destroy(&neis2); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/operators/permute.c0000644000176200001440000000675114447675375017766 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "graph/attributes.h" /** * \function igraph_permute_vertices * Permute the vertices * * This function creates a new graph from the input graph by permuting * its vertices according to the specified mapping. Call this function * with the output of \ref igraph_canonical_permutation() to create * the canonical form of a graph. * \param graph The input graph. * \param res Pointer to an uninitialized graph object. The new graph * is created here. * \param permutation The permutation to apply. Vertex 0 is mapped to * the first element of the vector, vertex 1 to the second, * etc. Note that it is not checked that the vector contains every * element only once, and no range checking is performed either. * \return Error code. * * Time complexity: O(|V|+|E|), linear in terms of the number of * vertices and edges. */ int igraph_permute_vertices(const igraph_t *graph, igraph_t *res, const igraph_vector_t *permutation) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vector_t edges; long int i, p = 0; if (igraph_vector_size(permutation) != no_of_nodes) { IGRAPH_ERROR("Permute vertices: invalid permutation vector size", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); for (i = 0; i < no_of_edges; i++) { VECTOR(edges)[p++] = VECTOR(*permutation)[ (long int) IGRAPH_FROM(graph, i) ]; VECTOR(edges)[p++] = VECTOR(*permutation)[ (long int) IGRAPH_TO(graph, i) ]; } IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) no_of_nodes, igraph_is_directed(graph))); /* Attributes */ if (graph->attr) { igraph_vector_t index; igraph_vector_t vtypes; IGRAPH_I_ATTRIBUTE_DESTROY(res); IGRAPH_I_ATTRIBUTE_COPY(res, graph, /*graph=*/1, /*vertex=*/0, /*edge=*/1); IGRAPH_VECTOR_INIT_FINALLY(&vtypes, 0); IGRAPH_CHECK(igraph_i_attribute_get_info(graph, 0, 0, 0, &vtypes, 0, 0)); if (igraph_vector_size(&vtypes) != 0) { IGRAPH_VECTOR_INIT_FINALLY(&index, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { VECTOR(index)[ (long int) VECTOR(*permutation)[i] ] = i; } IGRAPH_CHECK(igraph_i_attribute_permute_vertices(graph, res, &index)); igraph_vector_destroy(&index); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&vtypes); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/operators/add_edge.c0000644000176200001440000000403714447675375020014 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_interface.h" /** * \function igraph_add_edge * \brief Adds a single edge to a graph. * * * For directed graphs the edge points from \p from to \p to. * * * Note that if you want to add many edges to a big graph, then it is * inefficient to add them one by one, it is better to collect them into * a vector and add all of them via a single \ref igraph_add_edges() call. * \param igraph The graph. * \param from The id of the first vertex of the edge. * \param to The id of the second vertex of the edge. * \return Error code. * * \sa \ref igraph_add_edges() to add many edges, \ref * igraph_delete_edges() to remove edges and \ref * igraph_add_vertices() to add vertices. * * Time complexity: O(|V|+|E|), the number of edges plus the number of * vertices. */ int igraph_add_edge(igraph_t *graph, igraph_integer_t from, igraph_integer_t to) { igraph_vector_t edges; int ret; IGRAPH_VECTOR_INIT_FINALLY(&edges, 2); VECTOR(edges)[0] = from; VECTOR(edges)[1] = to; IGRAPH_CHECK(ret = igraph_add_edges(graph, &edges, 0)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return ret; } leidenbase/src/core/operators/complementer.c0000644000176200001440000000704214447675375020771 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "graph/attributes.h" #include "core/interruption.h" /** * \function igraph_complementer * \brief Create the complementer of a graph * * The complementer graph means that all edges which are * not part of the original graph will be included in the result. * * \param res Pointer to an uninitialized graph object. * \param graph The original graph. * \param loops Whether to add loop edges to the complementer graph. * \return Error code. * \sa \ref igraph_union(), \ref igraph_intersection() and \ref * igraph_difference(). * * Time complexity: O(|V|+|E1|+|E2|), |V| is the number of * vertices in the graph, |E1| is the number of edges in the original * and |E2| in the complementer graph. * * \example examples/simple/igraph_complementer.c */ int igraph_complementer(igraph_t *res, const igraph_t *graph, igraph_bool_t loops) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t edges; igraph_vector_t neis; long int i, j; long int zero = 0, *limit; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); if (igraph_is_directed(graph)) { limit = &zero; } else { limit = &i; } for (i = 0; i < no_of_nodes; i++) { IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) i, IGRAPH_OUT)); if (loops) { for (j = no_of_nodes - 1; j >= *limit; j--) { if (igraph_vector_empty(&neis) || j > igraph_vector_tail(&neis)) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } else { igraph_vector_pop_back(&neis); } } } else { for (j = no_of_nodes - 1; j >= *limit; j--) { if (igraph_vector_empty(&neis) || j > igraph_vector_tail(&neis)) { if (i != j) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } } else { igraph_vector_pop_back(&neis); } } } } IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) no_of_nodes, igraph_is_directed(graph))); igraph_vector_destroy(&edges); igraph_vector_destroy(&neis); IGRAPH_I_ATTRIBUTE_DESTROY(res); IGRAPH_I_ATTRIBUTE_COPY(res, graph, /*graph=*/1, /*vertex=*/1, /*edge=*/0); IGRAPH_FINALLY_CLEAN(2); return 0; } leidenbase/src/core/operators/misc_internal.c0000644000176200001440000002214014447675375021122 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "operators/misc_internal.h" #include "igraph_constructors.h" #include "igraph_conversion.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_qsort.h" void igraph_i_union_intersection_destroy_vectors(igraph_vector_ptr_t *v) { long int i, n = igraph_vector_ptr_size(v); for (i = 0; i < n; i++) { if (VECTOR(*v)[i] != 0) { igraph_vector_destroy(VECTOR(*v)[i]); IGRAPH_FREE(VECTOR(*v)[i]); } } igraph_vector_ptr_destroy(v); } void igraph_i_union_intersection_destroy_vector_longs(igraph_vector_ptr_t *v) { long int i, n = igraph_vector_ptr_size(v); for (i = 0; i < n; i++) { if (VECTOR(*v)[i] != 0) { igraph_vector_long_destroy(VECTOR(*v)[i]); IGRAPH_FREE(VECTOR(*v)[i]); } } igraph_vector_ptr_destroy(v); } int igraph_i_order_edgelist_cmp(void *edges, const void *e1, const void *e2) { igraph_vector_t *edgelist = edges; long int edge1 = (*(const long int*) e1) * 2; long int edge2 = (*(const long int*) e2) * 2; long int from1 = VECTOR(*edgelist)[edge1]; long int from2 = VECTOR(*edgelist)[edge2]; if (from1 < from2) { return -1; } else if (from1 > from2) { return 1; } else { long int to1 = VECTOR(*edgelist)[edge1 + 1]; long int to2 = VECTOR(*edgelist)[edge2 + 1]; if (to1 < to2) { return -1; } else if (to1 > to2) { return 1; } else { return 0; } } } int igraph_i_merge(igraph_t *res, int mode, const igraph_t *left, const igraph_t *right, igraph_vector_t *edge_map1, igraph_vector_t *edge_map2) { long int no_of_nodes_left = igraph_vcount(left); long int no_of_nodes_right = igraph_vcount(right); long int no_of_nodes; long int no_edges_left = igraph_ecount(left); long int no_edges_right = igraph_ecount(right); igraph_bool_t directed = igraph_is_directed(left); igraph_vector_t edges; igraph_vector_t edges1, edges2; igraph_vector_long_t order1, order2; long int i, j, eptr = 0; long int idx1, idx2, edge1 = -1, edge2 = -1, from1 = -1, from2 = -1, to1 = -1, to2 = -1; igraph_bool_t l; if (directed != igraph_is_directed(right)) { IGRAPH_ERROR("Cannot make union or intersection of directed " "and undirected graph", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&edges1, no_edges_left * 2); IGRAPH_VECTOR_INIT_FINALLY(&edges2, no_edges_right * 2); IGRAPH_CHECK(igraph_vector_long_init(&order1, no_edges_left)); IGRAPH_FINALLY(igraph_vector_long_destroy, &order1); IGRAPH_CHECK(igraph_vector_long_init(&order2, no_edges_right)); IGRAPH_FINALLY(igraph_vector_long_destroy, &order2); if (edge_map1) { switch (mode) { case IGRAPH_MERGE_MODE_UNION: IGRAPH_CHECK(igraph_vector_resize(edge_map1, no_edges_left)); break; case IGRAPH_MERGE_MODE_INTERSECTION: igraph_vector_clear(edge_map1); break; } } if (edge_map2) { switch (mode) { case IGRAPH_MERGE_MODE_UNION: IGRAPH_CHECK(igraph_vector_resize(edge_map2, no_edges_right)); break; case IGRAPH_MERGE_MODE_INTERSECTION: igraph_vector_clear(edge_map2); break; } } no_of_nodes = no_of_nodes_left > no_of_nodes_right ? no_of_nodes_left : no_of_nodes_right; /* We merge the two edge lists. We need to sort them first. For undirected graphs, we also need to make sure that for every edge, that larger (non-smaller) vertex id is in the second column. */ IGRAPH_CHECK(igraph_get_edgelist(left, &edges1, /*bycol=*/ 0)); IGRAPH_CHECK(igraph_get_edgelist(right, &edges2, /*bycol=*/ 0)); if (!directed) { for (i = 0, j = 0; i < no_edges_left; i++, j += 2) { if (VECTOR(edges1)[j] > VECTOR(edges1)[j + 1]) { long int tmp = VECTOR(edges1)[j]; VECTOR(edges1)[j] = VECTOR(edges1)[j + 1]; VECTOR(edges1)[j + 1] = tmp; } } for (i = 0, j = 0; i < no_edges_right; i++, j += 2) { if (VECTOR(edges2)[j] > VECTOR(edges2)[j + 1]) { long int tmp = VECTOR(edges2)[j]; VECTOR(edges2)[j] = VECTOR(edges2)[j + 1]; VECTOR(edges2)[j + 1] = tmp; } } } for (i = 0; i < no_edges_left; i++) { VECTOR(order1)[i] = i; } for (i = 0; i < no_edges_right; i++) { VECTOR(order2)[i] = i; } igraph_qsort_r(VECTOR(order1), no_edges_left, sizeof(VECTOR(order1)[0]), &edges1, igraph_i_order_edgelist_cmp); igraph_qsort_r(VECTOR(order2), no_edges_right, sizeof(VECTOR(order2)[0]), &edges2, igraph_i_order_edgelist_cmp); #define INC1() if ( (++idx1) < no_edges_left) { \ edge1 = VECTOR(order1)[idx1]; \ from1 = VECTOR(edges1)[2*edge1]; \ to1 = VECTOR(edges1)[2*edge1+1]; \ } #define INC2() if ( (++idx2) < no_edges_right) { \ edge2 = VECTOR(order2)[idx2]; \ from2 = VECTOR(edges2)[2*edge2]; \ to2 = VECTOR(edges2)[2*edge2+1]; \ } idx1 = idx2 = -1; INC1(); INC2(); #define CONT() switch (mode) { \ case IGRAPH_MERGE_MODE_UNION: \ l = idx1 < no_edges_left || idx2 < no_edges_right; \ break; \ case IGRAPH_MERGE_MODE_INTERSECTION: \ l = idx1 < no_edges_left && idx2 < no_edges_right; \ break; \ default: \ IGRAPH_ASSERT(! "Invalid merge mode."); \ } CONT(); while (l) { if (idx2 >= no_edges_right || (idx1 < no_edges_left && from1 < from2) || (idx1 < no_edges_left && from1 == from2 && to1 < to2)) { /* Edge from first graph */ if (mode == IGRAPH_MERGE_MODE_UNION) { IGRAPH_CHECK(igraph_vector_push_back(&edges, from1)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to1)); if (edge_map1) { VECTOR(*edge_map1)[edge1] = eptr; } eptr++; } INC1(); } else if (idx1 >= no_edges_left || (idx2 < no_edges_right && from2 < from1) || (idx2 < no_edges_right && from1 == from2 && to2 < to1)) { /* Edge from second graph */ if (mode == IGRAPH_MERGE_MODE_UNION) { IGRAPH_CHECK(igraph_vector_push_back(&edges, from2)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to2)); if (edge_map2) { VECTOR(*edge_map2)[edge2] = eptr; } eptr++; } INC2(); } else { /* Edge from both */ IGRAPH_CHECK(igraph_vector_push_back(&edges, from1)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to1)); if (mode == IGRAPH_MERGE_MODE_UNION) { if (edge_map1) { VECTOR(*edge_map1)[edge1] = eptr; } if (edge_map2) { VECTOR(*edge_map2)[edge2] = eptr; } } else if (mode == IGRAPH_MERGE_MODE_INTERSECTION) { if (edge_map1) { IGRAPH_CHECK(igraph_vector_push_back(edge_map1, edge1)); } if (edge_map2) { IGRAPH_CHECK(igraph_vector_push_back(edge_map2, edge2)); } } eptr++; INC1(); INC2(); } CONT(); } #undef INC1 #undef INC2 igraph_vector_long_destroy(&order2); igraph_vector_long_destroy(&order1); igraph_vector_destroy(&edges2); igraph_vector_destroy(&edges1); IGRAPH_FINALLY_CLEAN(4); IGRAPH_CHECK(igraph_create(res, &edges, no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/operators/simplify.c0000644000176200001440000001316314447675375020134 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "core/fixed_vectorlist.h" #include "graph/attributes.h" /** * \ingroup structural * \function igraph_simplify * \brief Removes loop and/or multiple edges from the graph. * * \param graph The graph object. * \param multiple Logical, if true, multiple edges will be removed. * \param loops Logical, if true, loops (self edges) will be removed. * \param edge_comb What to do with the edge attributes. \c NULL means to * discard the edge attributes after the operation, even for edges * that were unaffeccted. See the igraph manual section about attributes * for details. * \return Error code: * \c IGRAPH_ENOMEM if we are out of memory. * * Time complexity: O(|V|+|E|). * * \example examples/simple/igraph_simplify.c */ int igraph_simplify(igraph_t *graph, igraph_bool_t multiple, igraph_bool_t loops, const igraph_attribute_combination_t *edge_comb) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int edge; igraph_bool_t attr = edge_comb && igraph_has_attribute_table(); long int from, to, pfrom = -1, pto = -2; igraph_t res; igraph_es_t es; igraph_eit_t eit; igraph_vector_t mergeinto; long int actedge; if (!multiple && !loops) /* nothing to do */ { return IGRAPH_SUCCESS; } if (!multiple) { /* removing loop edges only, this is simple. No need to combine anything * and the whole process can be done in-place */ IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_es_all(&es, IGRAPH_EDGEORDER_ID)); IGRAPH_FINALLY(igraph_es_destroy, &es); IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); while (!IGRAPH_EIT_END(eit)) { edge = IGRAPH_EIT_GET(eit); from = IGRAPH_FROM(graph, edge); to = IGRAPH_TO(graph, edge); if (from == to) { IGRAPH_CHECK(igraph_vector_push_back(&edges, edge)); } IGRAPH_EIT_NEXT(eit); } igraph_eit_destroy(&eit); igraph_es_destroy(&es); IGRAPH_FINALLY_CLEAN(2); if (igraph_vector_size(&edges) > 0) { IGRAPH_CHECK(igraph_delete_edges(graph, igraph_ess_vector(&edges))); } igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } if (attr) { IGRAPH_VECTOR_INIT_FINALLY(&mergeinto, no_of_edges); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); IGRAPH_CHECK(igraph_es_all(&es, IGRAPH_EDGEORDER_FROM)); IGRAPH_FINALLY(igraph_es_destroy, &es); IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); for (actedge = -1; !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { edge = IGRAPH_EIT_GET(eit); from = IGRAPH_FROM(graph, edge); to = IGRAPH_TO(graph, edge); if (loops && from == to) { /* Loop edge to be removed */ if (attr) { VECTOR(mergeinto)[edge] = -1; } } else if (multiple && from == pfrom && to == pto) { /* Multiple edge to be contracted */ if (attr) { VECTOR(mergeinto)[edge] = actedge; } } else { /* Edge to be kept */ igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); if (attr) { actedge++; VECTOR(mergeinto)[edge] = actedge; } } pfrom = from; pto = to; } igraph_eit_destroy(&eit); igraph_es_destroy(&es); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(&res, &edges, (igraph_integer_t) no_of_nodes, igraph_is_directed(graph))); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &res); IGRAPH_I_ATTRIBUTE_DESTROY(&res); IGRAPH_I_ATTRIBUTE_COPY(&res, graph, /*graph=*/ 1, /*vertex=*/ 1, /*edge=*/ 0); if (attr) { igraph_fixed_vectorlist_t vl; IGRAPH_CHECK(igraph_fixed_vectorlist_convert(&vl, &mergeinto, actedge + 1)); IGRAPH_FINALLY(igraph_fixed_vectorlist_destroy, &vl); IGRAPH_CHECK(igraph_i_attribute_combine_edges(graph, &res, &vl.v, edge_comb)); igraph_fixed_vectorlist_destroy(&vl); igraph_vector_destroy(&mergeinto); IGRAPH_FINALLY_CLEAN(2); } IGRAPH_FINALLY_CLEAN(1); igraph_destroy(graph); *graph = res; return 0; } leidenbase/src/core/operators/intersection.c0000644000176200001440000002705414447675375021012 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_operators.h" #include "igraph_constructors.h" #include "igraph_conversion.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_qsort.h" #include "operators/misc_internal.h" #include /** * \function igraph_intersection * \brief Collect the common edges from two graphs. * * * The result graph contains only edges present both in the first and * the second graph. The number of vertices in the result graph is the * same as the larger from the two arguments. * * \param res Pointer to an uninitialized graph object. This will * contain the result of the operation. * \param left The first operand, a graph object. * \param right The second operand, a graph object. * \param edge_map1 Null pointer, or an initialized \type igraph_vector_t. * If the latter, then a mapping from the edges of the result graph, to * the edges of the \p left input graph is stored here. * \param edge_map2 Null pointer, or an \type igraph_vector_t. The same * as \p edge_map1, but for the \p right input graph. * \return Error code. * \sa \ref igraph_intersection_many() to calculate the intersection * of many graphs at once, \ref igraph_union(), \ref * igraph_difference() for other operators. * * Time complexity: O(|V|+|E|), |V| is the number of nodes, |E| * is the number of edges in the smaller graph of the two. (The one * containing less vertices is considered smaller.) * * \example examples/simple/igraph_intersection.c */ int igraph_intersection(igraph_t *res, const igraph_t *left, const igraph_t *right, igraph_vector_t *edge_map1, igraph_vector_t *edge_map2) { return igraph_i_merge(res, IGRAPH_MERGE_MODE_INTERSECTION, left, right, edge_map1, edge_map2); } /** * \function igraph_intersection_many * \brief The intersection of more than two graphs. * * * This function calculates the intersection of the graphs stored in * the \p graphs argument. Only those edges will be included in the * result graph which are part of every graph in \p graphs. * * * The number of vertices in the result graph will be the maximum * number of vertices in the argument graphs. * * \param res Pointer to an uninitialized graph object, the result of * the operation will be stored here. * \param graphs Pointer vector, contains pointers to graphs objects, * the operands of the intersection operator. * \param edgemaps If not a null pointer, then it must be an initialized * pointer vector and the mappings of edges from the graphs to the * result graph will be stored here, in the same order as * \p graphs. Each mapping is stored in a separate * \type igraph_vector_t object. For the edges that are not in * the intersection, -1 is stored. * \return Error code. * \sa \ref igraph_intersection() for the intersection of two graphs, * \ref igraph_union_many(), \ref igraph_union() and \ref * igraph_difference() for other operators. * * Time complexity: O(|V|+|E|), |V| is the number of vertices, * |E| is the number of edges in the smallest graph (i.e. the graph having * the less vertices). */ int igraph_intersection_many(igraph_t *res, const igraph_vector_ptr_t *graphs, igraph_vector_ptr_t *edgemaps) { long int no_of_graphs = igraph_vector_ptr_size(graphs); long int no_of_nodes = 0; igraph_bool_t directed = 1; igraph_vector_t edges; igraph_vector_ptr_t edge_vects, order_vects; long int i, j, tailfrom = no_of_graphs > 0 ? 0 : -1, tailto = -1; igraph_vector_long_t no_edges; igraph_bool_t allne = no_of_graphs == 0 ? 0 : 1, allsame = 0; long int idx = 0; /* Check directedness */ if (no_of_graphs != 0) { directed = igraph_is_directed(VECTOR(*graphs)[0]); } for (i = 1; i < no_of_graphs; i++) { if (directed != igraph_is_directed(VECTOR(*graphs)[i])) { IGRAPH_ERROR("Cannot intersect directed and undirected graphs", IGRAPH_EINVAL); } } if (edgemaps) { IGRAPH_CHECK(igraph_vector_ptr_resize(edgemaps, no_of_graphs)); igraph_vector_ptr_null(edgemaps); IGRAPH_FINALLY(igraph_i_union_intersection_destroy_vectors, edgemaps); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_long_init(&no_edges, no_of_graphs)); IGRAPH_FINALLY(igraph_vector_long_destroy, &no_edges); /* Calculate number of nodes, query number of edges */ for (i = 0; i < no_of_graphs; i++) { long int n = igraph_vcount(VECTOR(*graphs)[i]); if (n > no_of_nodes) { no_of_nodes = n; } VECTOR(no_edges)[i] = igraph_ecount(VECTOR(*graphs)[i]); allne = allne && VECTOR(no_edges)[i] > 0; } if (edgemaps) { for (i = 0; i < no_of_graphs; i++) { VECTOR(*edgemaps)[i] = IGRAPH_CALLOC(1, igraph_vector_t); if (!VECTOR(*edgemaps)[i]) { IGRAPH_ERROR("Cannot intersect graphs", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(VECTOR(*edgemaps)[i], VECTOR(no_edges)[i])); igraph_vector_fill(VECTOR(*edgemaps)[i], -1); } } /* Allocate memory for the edge lists and their index vectors */ if (no_of_graphs != 0) { IGRAPH_CHECK(igraph_vector_ptr_init(&edge_vects, no_of_graphs)); IGRAPH_FINALLY(igraph_i_union_intersection_destroy_vectors, &edge_vects); IGRAPH_CHECK(igraph_vector_ptr_init(&order_vects, no_of_graphs)); IGRAPH_FINALLY(igraph_i_union_intersection_destroy_vector_longs, &order_vects); } for (i = 0; i < no_of_graphs; i++) { VECTOR(edge_vects)[i] = IGRAPH_CALLOC(1, igraph_vector_t); VECTOR(order_vects)[i] = IGRAPH_CALLOC(1, igraph_vector_long_t); if (! VECTOR(edge_vects)[i] || ! VECTOR(order_vects)[i]) { IGRAPH_ERROR("Cannot intersect graphs", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(VECTOR(edge_vects)[i], 2 * VECTOR(no_edges)[i])); IGRAPH_CHECK(igraph_vector_long_init(VECTOR(order_vects)[i], VECTOR(no_edges)[i])); } /* Query and sort the edge lists */ for (i = 0; i < no_of_graphs; i++) { long int k, j, n = VECTOR(no_edges)[i]; igraph_vector_t *edges = VECTOR(edge_vects)[i]; igraph_vector_long_t *order = VECTOR(order_vects)[i]; IGRAPH_CHECK(igraph_get_edgelist(VECTOR(*graphs)[i], edges, /*bycol=*/0)); if (!directed) { for (k = 0, j = 0; k < n; k++, j += 2) { if (VECTOR(*edges)[j] > VECTOR(*edges)[j + 1]) { long int tmp = VECTOR(*edges)[j]; VECTOR(*edges)[j] = VECTOR(*edges)[j + 1]; VECTOR(*edges)[j + 1] = tmp; } } } for (k = 0; k < n; k++) { VECTOR(*order)[k] = k; } igraph_qsort_r(VECTOR(*order), n, sizeof(VECTOR(*order)[0]), edges, igraph_i_order_edgelist_cmp); } /* Do the merge. We work from the end of the edge lists, because then we don't have to keep track of where we are right now in the edge and order lists. We find the "largest" edge, and if it is present in all graphs, then we copy it to the result. We remove all instances of this edge. */ while (allne) { /* Look for the smallest tail element */ for (j = 0, tailfrom = LONG_MAX, tailto = LONG_MAX; j < no_of_graphs; j++) { long int edge = igraph_vector_long_tail(VECTOR(order_vects)[j]); igraph_vector_t *ev = VECTOR(edge_vects)[j]; long int from = VECTOR(*ev)[2 * edge]; long int to = VECTOR(*ev)[2 * edge + 1]; if (from < tailfrom || (from == tailfrom && to < tailto)) { tailfrom = from; tailto = to; } } /* OK, now remove all elements from the tail(s) that are bigger than the smallest tail element. */ for (j = 0, allsame = 1; j < no_of_graphs; j++) { long int from = -1, to = -1; while (1) { long int edge = igraph_vector_long_tail(VECTOR(order_vects)[j]); igraph_vector_t *ev = VECTOR(edge_vects)[j]; from = VECTOR(*ev)[2 * edge]; to = VECTOR(*ev)[2 * edge + 1]; if (from > tailfrom || (from == tailfrom && to > tailto)) { igraph_vector_long_pop_back(VECTOR(order_vects)[j]); if (igraph_vector_long_empty(VECTOR(order_vects)[j])) { allne = 0; break; } } else { break; } } if (from != tailfrom || to != tailto) { allsame = 0; } } /* Add the edge, if the smallest tail element was present in all graphs. */ if (allsame) { IGRAPH_CHECK(igraph_vector_push_back(&edges, tailfrom)); IGRAPH_CHECK(igraph_vector_push_back(&edges, tailto)); } /* Drop edges matching the smalles tail elements from the order vectors, build edge maps */ if (allne) { for (j = 0; j < no_of_graphs; j++) { long int edge = igraph_vector_long_tail(VECTOR(order_vects)[j]); igraph_vector_t *ev = VECTOR(edge_vects)[j]; long int from = VECTOR(*ev)[2 * edge]; long int to = VECTOR(*ev)[2 * edge + 1]; if (from == tailfrom && to == tailto) { igraph_vector_long_pop_back(VECTOR(order_vects)[j]); if (igraph_vector_long_empty(VECTOR(order_vects)[j])) { allne = 0; } if (edgemaps && allsame) { igraph_vector_t *map = VECTOR(*edgemaps)[j]; VECTOR(*map)[edge] = idx; } } } if (allsame) { idx++; } } } /* while allne */ if (no_of_graphs > 0) { igraph_i_union_intersection_destroy_vector_longs(&order_vects); igraph_i_union_intersection_destroy_vectors(&edge_vects); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_long_destroy(&no_edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); if (edgemaps) { IGRAPH_FINALLY_CLEAN(1); } return 0; } leidenbase/src/core/constructors/0000755000176200001440000000000014532173045016640 5ustar liggesusersleidenbase/src/core/constructors/basic_constructors.c0000644000176200001440000001165114447675374022742 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "igraph_interface.h" /** * \section about_generators * * Graph generators create graphs. * * Almost all functions which create graph objects are documented * here. The exceptions are \ref igraph_induced_subgraph() and alike, these * create graphs based on another graph. */ /** * \ingroup generators * \function igraph_create * \brief Creates a graph with the specified edges. * * \param graph An uninitialized graph object. * \param edges The edges to add, the first two elements are the first * edge, etc. * \param n The number of vertices in the graph, if smaller or equal * to the highest vertex id in the \p edges vector it * will be increased automatically. So it is safe to give 0 * here. * \param directed Boolean, whether to create a directed graph or * not. If yes, then the first edge points from the first * vertex id in \p edges to the second, etc. * \return Error code: * \c IGRAPH_EINVEVECTOR: invalid edges * vector (odd number of vertices). * \c IGRAPH_EINVVID: invalid (negative) * vertex id. * * Time complexity: O(|V|+|E|), * |V| is the number of vertices, * |E| the number of edges in the * graph. * * \example examples/simple/igraph_create.c */ int igraph_create(igraph_t *graph, const igraph_vector_t *edges, igraph_integer_t n, igraph_bool_t directed) { igraph_bool_t has_edges = igraph_vector_size(edges) > 0; igraph_real_t max = has_edges ? igraph_vector_max(edges) + 1 : 0; if (igraph_vector_size(edges) % 2 != 0) { IGRAPH_ERROR("Invalid (odd) edges vector", IGRAPH_EINVEVECTOR); } if (has_edges && !igraph_vector_isininterval(edges, 0, max - 1)) { IGRAPH_ERROR("Invalid (negative) vertex id", IGRAPH_EINVVID); } IGRAPH_CHECK(igraph_empty(graph, n, directed)); IGRAPH_FINALLY(igraph_destroy, graph); if (has_edges) { igraph_integer_t vc = igraph_vcount(graph); if (vc < max) { IGRAPH_CHECK(igraph_add_vertices(graph, (igraph_integer_t) (max - vc), 0)); } IGRAPH_CHECK(igraph_add_edges(graph, edges, 0)); } IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_small * \brief Shorthand to create a small graph, giving the edges as arguments. * * * This function is handy when a relatively small graph needs to be created. * Instead of giving the edges as a vector, they are given simply as * arguments and a '-1' needs to be given after the last meaningful * edge argument. * * Note that only graphs which have vertices less than * the highest value of the 'int' type can be created this way. If you * give larger values then the result is undefined. * * \param graph Pointer to an uninitialized graph object. The result * will be stored here. * \param n The number of vertices in the graph; a nonnegative integer. * \param directed Logical constant; gives whether the graph should be * directed. Supported values are: * \clist * \cli IGRAPH_DIRECTED * The graph to be created will be \em directed. * \cli IGRAPH_UNDIRECTED * The graph to be created will be \em undirected. * \endclist * \param ... The additional arguments giving the edges of the * graph. Don't forget to supply an additional '-1' after the last * (meaningful) argument. * \return Error code. * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges in the graph to create. * * \example examples/simple/igraph_small.c */ int igraph_small(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, ...) { igraph_vector_t edges; va_list ap; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); va_start(ap, directed); while (1) { int num = va_arg(ap, int); if (num == -1) { break; } igraph_vector_push_back(&edges, num); } IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/constructors/de_bruijn.c0000644000176200001440000000623314447675374020772 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "igraph_interface.h" /** * \function igraph_de_bruijn * \brief Generate a de Bruijn graph. * * A de Bruijn graph represents relationships between strings. An alphabet * of \c m letters are used and strings of length \c n are considered. * A vertex corresponds to every possible string and there is a directed edge * from vertex \c v to vertex \c w if the string of \c v can be transformed into * the string of \c w by removing its first letter and appending a letter to it. * * * Please note that the graph will have \c m to the power \c n vertices and * even more edges, so probably you don't want to supply too big numbers for * \c m and \c n. * * * De Bruijn graphs have some interesting properties, please see another source, * e.g. Wikipedia for details. * * \param graph Pointer to an uninitialized graph object, the result will be * stored here. * \param m Integer, the number of letters in the alphabet. * \param n Integer, the length of the strings. * \return Error code. * * \sa \ref igraph_kautz(). * * Time complexity: O(|V|+|E|), the number of vertices plus the number of edges. */ int igraph_de_bruijn(igraph_t *graph, igraph_integer_t m, igraph_integer_t n) { /* m - number of symbols */ /* n - length of strings */ long int no_of_nodes, no_of_edges; igraph_vector_t edges; long int i, j; long int mm = m; if (m < 0 || n < 0) { IGRAPH_ERROR("`m' and `n' should be non-negative in a de Bruijn graph", IGRAPH_EINVAL); } if (n == 0) { return igraph_empty(graph, 1, IGRAPH_DIRECTED); } if (m == 0) { return igraph_empty(graph, 0, IGRAPH_DIRECTED); } no_of_nodes = (long int) pow(m, n); no_of_edges = no_of_nodes * m; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); for (i = 0; i < no_of_nodes; i++) { long int basis = (i * mm) % no_of_nodes; for (j = 0; j < m; j++) { igraph_vector_push_back(&edges, i); igraph_vector_push_back(&edges, basis + j); } } IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, IGRAPH_DIRECTED)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/constructors/lcf.c0000644000176200001440000001105614447675374017574 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "igraph_operators.h" /** * \function igraph_lcf_vector * \brief Creates a graph from LCF notation. * * This function is essentially the same as \ref igraph_lcf(), only * the way for giving the arguments is different. See \ref * igraph_lcf() for details. * \param graph Pointer to an uninitialized graph object. * \param n Integer constant giving the number of vertices. * \param shifts A vector giving the shifts. * \param repeats An integer constant giving the number of repeats * for the shifts. * \return Error code. * * \sa \ref igraph_lcf(), \ref igraph_extended_chordal_ring() * * Time complexity: O(|V|+|E|), linear in the number of vertices plus * the number of edges. */ int igraph_lcf_vector(igraph_t *graph, igraph_integer_t n, const igraph_vector_t *shifts, igraph_integer_t repeats) { igraph_vector_t edges; long int no_of_shifts = igraph_vector_size(shifts); long int ptr = 0, i, sptr = 0; long int no_of_nodes = n; long int no_of_edges = n + no_of_shifts * repeats; if (repeats < 0) { IGRAPH_ERROR("number of repeats must be positive", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 2 * no_of_edges); if (no_of_nodes > 0) { /* Create a ring first */ for (i = 0; i < no_of_nodes; i++) { VECTOR(edges)[ptr++] = i; VECTOR(edges)[ptr++] = i + 1; } VECTOR(edges)[ptr - 1] = 0; } /* Then add the rest */ while (ptr < 2 * no_of_edges) { long int sh = (long int) VECTOR(*shifts)[sptr % no_of_shifts]; long int from = sptr % no_of_nodes; long int to = (no_of_nodes + sptr + sh) % no_of_nodes; VECTOR(edges)[ptr++] = from; VECTOR(edges)[ptr++] = to; sptr++; } IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, IGRAPH_UNDIRECTED)); IGRAPH_CHECK(igraph_simplify(graph, 1 /* true */, 1 /* true */, NULL)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_lcf * \brief Creates a graph from LCF notation. * * * LCF is short for Lederberg-Coxeter-Frucht, it is a concise notation for * 3-regular Hamiltonian graphs. It consists of three parameters: the * number of vertices in the graph, a list of shifts giving additional * edges to a cycle backbone, and another integer giving how many times * the shifts should be performed. See * http://mathworld.wolfram.com/LCFNotation.html for details. * * \param graph Pointer to an uninitialized graph object. * \param n Integer, the number of vertices in the graph. * \param ... The shifts and the number of repeats for the shifts, * plus an additional 0 to mark the end of the arguments. * \return Error code. * * \sa See \ref igraph_lcf_vector() for a similar function using a * vector_t instead of the variable length argument list. * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges. * * \example examples/simple/igraph_lcf.c */ int igraph_lcf(igraph_t *graph, igraph_integer_t n, ...) { igraph_vector_t shifts; igraph_integer_t repeats; va_list ap; IGRAPH_VECTOR_INIT_FINALLY(&shifts, 0); va_start(ap, n); while (1) { int num = va_arg(ap, int); if (num == 0) { break; } IGRAPH_CHECK(igraph_vector_push_back(&shifts, num)); } if (igraph_vector_size(&shifts) == 0) { repeats = 0; } else { repeats = (igraph_integer_t) igraph_vector_pop_back(&shifts); } IGRAPH_CHECK(igraph_lcf_vector(graph, n, &shifts, repeats)); igraph_vector_destroy(&shifts); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/constructors/famous.c0000644000176200001440000005274214447675374020331 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "igraph_constructors.h" #include "internal/hacks.h" const igraph_real_t igraph_i_famous_bull[] = { 5, 5, 0, 0, 1, 0, 2, 1, 2, 1, 3, 2, 4 }; const igraph_real_t igraph_i_famous_chvatal[] = { 12, 24, 0, 5, 6, 6, 7, 7, 8, 8, 9, 5, 9, 4, 5, 4, 8, 2, 8, 2, 6, 0, 6, 0, 9, 3, 9, 3, 7, 1, 7, 1, 5, 1, 10, 4, 10, 4, 11, 2, 11, 0, 10, 0, 11, 3, 11, 3, 10, 1, 2 }; const igraph_real_t igraph_i_famous_coxeter[] = { 28, 42, 0, 0, 1, 0, 2, 0, 7, 1, 4, 1, 13, 2, 3, 2, 8, 3, 6, 3, 9, 4, 5, 4, 12, 5, 6, 5, 11, 6, 10, 7, 19, 7, 24, 8, 20, 8, 23, 9, 14, 9, 22, 10, 15, 10, 21, 11, 16, 11, 27, 12, 17, 12, 26, 13, 18, 13, 25, 14, 17, 14, 18, 15, 18, 15, 19, 16, 19, 16, 20, 17, 20, 21, 23, 21, 26, 22, 24, 22, 27, 23, 25, 24, 26, 25, 27 }; const igraph_real_t igraph_i_famous_cubical[] = { 8, 12, 0, 0, 1, 1, 2, 2, 3, 0, 3, 4, 5, 5, 6, 6, 7, 4, 7, 0, 4, 1, 5, 2, 6, 3, 7 }; const igraph_real_t igraph_i_famous_diamond[] = { 4, 5, 0, 0, 1, 0, 2, 1, 2, 1, 3, 2, 3 }; const igraph_real_t igraph_i_famous_dodecahedron[] = { 20, 30, 0, 0, 1, 0, 4, 0, 5, 1, 2, 1, 6, 2, 3, 2, 7, 3, 4, 3, 8, 4, 9, 5, 10, 5, 11, 6, 10, 6, 14, 7, 13, 7, 14, 8, 12, 8, 13, 9, 11, 9, 12, 10, 15, 11, 16, 12, 17, 13, 18, 14, 19, 15, 16, 15, 19, 16, 17, 17, 18, 18, 19 }; const igraph_real_t igraph_i_famous_folkman[] = { 20, 40, 0, 0, 5, 0, 8, 0, 10, 0, 13, 1, 7, 1, 9, 1, 12, 1, 14, 2, 6, 2, 8, 2, 11, 2, 13, 3, 5, 3, 7, 3, 10, 3, 12, 4, 6, 4, 9, 4, 11, 4, 14, 5, 15, 5, 19, 6, 15, 6, 16, 7, 16, 7, 17, 8, 17, 8, 18, 9, 18, 9, 19, 10, 15, 10, 19, 11, 15, 11, 16, 12, 16, 12, 17, 13, 17, 13, 18, 14, 18, 14, 19 }; const igraph_real_t igraph_i_famous_franklin[] = { 12, 18, 0, 0, 1, 0, 2, 0, 6, 1, 3, 1, 7, 2, 4, 2, 10, 3, 5, 3, 11, 4, 5, 4, 6, 5, 7, 6, 8, 7, 9, 8, 9, 8, 11, 9, 10, 10, 11 }; const igraph_real_t igraph_i_famous_frucht[] = { 12, 18, 0, 0, 1, 0, 2, 0, 11, 1, 3, 1, 6, 2, 5, 2, 10, 3, 4, 3, 6, 4, 8, 4, 11, 5, 9, 5, 10, 6, 7, 7, 8, 7, 9, 8, 9, 10, 11 }; const igraph_real_t igraph_i_famous_grotzsch[] = { 11, 20, 0, 0, 1, 0, 2, 0, 7, 0, 10, 1, 3, 1, 6, 1, 9, 2, 4, 2, 6, 2, 8, 3, 4, 3, 8, 3, 10, 4, 7, 4, 9, 5, 6, 5, 7, 5, 8, 5, 9, 5, 10 }; const igraph_real_t igraph_i_famous_heawood[] = { 14, 21, 0, 0, 1, 0, 5, 0, 13, 1, 2, 1, 10, 2, 3, 2, 7, 3, 4, 3, 12, 4, 5, 4, 9, 5, 6, 6, 7, 6, 11, 7, 8, 8, 9, 8, 13, 9, 10, 10, 11, 11, 12, 12, 13 }; const igraph_real_t igraph_i_famous_herschel[] = { 11, 18, 0, 0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 6, 1, 7, 2, 10, 3, 9, 4, 8, 4, 9, 5, 8, 5, 10, 6, 8, 6, 9, 7, 8, 7, 10 }; const igraph_real_t igraph_i_famous_house[] = { 5, 6, 0, 0, 1, 0, 2, 1, 3, 2, 3, 2, 4, 3, 4 }; const igraph_real_t igraph_i_famous_housex[] = { 5, 8, 0, 0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3, 2, 4, 3, 4 }; const igraph_real_t igraph_i_famous_icosahedron[] = { 12, 30, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 8, 1, 2, 1, 6, 1, 7, 1, 8, 2, 4, 2, 5, 2, 6, 3, 4, 3, 8, 3, 9, 3, 11, 4, 5, 4, 11, 5, 6, 5, 10, 5, 11, 6, 7, 6, 10, 7, 8, 7, 9, 7, 10, 8, 9, 9, 10, 9, 11, 10, 11 }; const igraph_real_t igraph_i_famous_krackhardt_kite[] = { 10, 18, 0, 0, 1, 0, 2, 0, 3, 0, 5, 1, 3, 1, 4, 1, 6, 2, 3, 2, 5, 3, 4, 3, 5, 3, 6, 4, 6, 5, 6, 5, 7, 6, 7, 7, 8, 8, 9 }; const igraph_real_t igraph_i_famous_levi[] = { 30, 45, 0, 0, 1, 0, 7, 0, 29, 1, 2, 1, 24, 2, 3, 2, 11, 3, 4, 3, 16, 4, 5, 4, 21, 5, 6, 5, 26, 6, 7, 6, 13, 7, 8, 8, 9, 8, 17, 9, 10, 9, 22, 10, 11, 10, 27, 11, 12, 12, 13, 12, 19, 13, 14, 14, 15, 14, 23, 15, 16, 15, 28, 16, 17, 17, 18, 18, 19, 18, 25, 19, 20, 20, 21, 20, 29, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29 }; const igraph_real_t igraph_i_famous_mcgee[] = { 24, 36, 0, 0, 1, 0, 7, 0, 23, 1, 2, 1, 18, 2, 3, 2, 14, 3, 4, 3, 10, 4, 5, 4, 21, 5, 6, 5, 17, 6, 7, 6, 13, 7, 8, 8, 9, 8, 20, 9, 10, 9, 16, 10, 11, 11, 12, 11, 23, 12, 13, 12, 19, 13, 14, 14, 15, 15, 16, 15, 22, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23 }; const igraph_real_t igraph_i_famous_meredith[] = { 70, 140, 0, 0, 4, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 7, 11, 7, 12, 7, 13, 8, 11, 8, 12, 8, 13, 9, 11, 9, 12, 9, 13, 10, 11, 10, 12, 10, 13, 14, 18, 14, 19, 14, 20, 15, 18, 15, 19, 15, 20, 16, 18, 16, 19, 16, 20, 17, 18, 17, 19, 17, 20, 21, 25, 21, 26, 21, 27, 22, 25, 22, 26, 22, 27, 23, 25, 23, 26, 23, 27, 24, 25, 24, 26, 24, 27, 28, 32, 28, 33, 28, 34, 29, 32, 29, 33, 29, 34, 30, 32, 30, 33, 30, 34, 31, 32, 31, 33, 31, 34, 35, 39, 35, 40, 35, 41, 36, 39, 36, 40, 36, 41, 37, 39, 37, 40, 37, 41, 38, 39, 38, 40, 38, 41, 42, 46, 42, 47, 42, 48, 43, 46, 43, 47, 43, 48, 44, 46, 44, 47, 44, 48, 45, 46, 45, 47, 45, 48, 49, 53, 49, 54, 49, 55, 50, 53, 50, 54, 50, 55, 51, 53, 51, 54, 51, 55, 52, 53, 52, 54, 52, 55, 56, 60, 56, 61, 56, 62, 57, 60, 57, 61, 57, 62, 58, 60, 58, 61, 58, 62, 59, 60, 59, 61, 59, 62, 63, 67, 63, 68, 63, 69, 64, 67, 64, 68, 64, 69, 65, 67, 65, 68, 65, 69, 66, 67, 66, 68, 66, 69, 2, 50, 1, 51, 9, 57, 8, 58, 16, 64, 15, 65, 23, 36, 22, 37, 30, 43, 29, 44, 3, 21, 7, 24, 14, 31, 0, 17, 10, 28, 38, 42, 35, 66, 59, 63, 52, 56, 45, 49 }; const igraph_real_t igraph_i_famous_noperfectmatching[] = { 16, 27, 0, 0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3, 2, 4, 3, 4, 4, 5, 5, 6, 5, 7, 6, 12, 6, 13, 7, 8, 7, 9, 8, 9, 8, 10, 8, 11, 9, 10, 9, 11, 10, 11, 12, 13, 12, 14, 12, 15, 13, 14, 13, 15, 14, 15 }; const igraph_real_t igraph_i_famous_nonline[] = { 50, 72, 0, 0, 1, 0, 2, 0, 3, 4, 6, 4, 7, 5, 6, 5, 7, 6, 7, 7, 8, 9, 11, 9, 12, 9, 13, 10, 11, 10, 12, 10, 13, 11, 12, 11, 13, 12, 13, 14, 15, 15, 16, 15, 17, 16, 17, 16, 18, 17, 18, 18, 19, 20, 21, 20, 22, 20, 23, 21, 22, 21, 23, 21, 24, 22, 23, 22, 24, 24, 25, 26, 27, 26, 28, 26, 29, 27, 28, 27, 29, 27, 30, 27, 31, 28, 29, 28, 30, 28, 31, 30, 31, 32, 34, 32, 35, 32, 36, 33, 34, 33, 35, 33, 37, 34, 35, 36, 37, 38, 39, 38, 40, 38, 43, 39, 40, 39, 41, 39, 42, 39, 43, 40, 41, 41, 42, 42, 43, 44, 45, 44, 46, 45, 46, 45, 47, 46, 47, 46, 48, 47, 48, 47, 49, 48, 49 }; const igraph_real_t igraph_i_famous_octahedron[] = { 6, 12, 0, 0, 1, 0, 2, 1, 2, 3, 4, 3, 5, 4, 5, 0, 3, 0, 5, 1, 3, 1, 4, 2, 4, 2, 5 }; const igraph_real_t igraph_i_famous_petersen[] = { 10, 15, 0, 0, 1, 0, 4, 0, 5, 1, 2, 1, 6, 2, 3, 2, 7, 3, 4, 3, 8, 4, 9, 5, 7, 5, 8, 6, 8, 6, 9, 7, 9 }; const igraph_real_t igraph_i_famous_robertson[] = { 19, 38, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 0, 18, 0, 4, 4, 9, 9, 13, 13, 17, 2, 17, 2, 6, 6, 10, 10, 15, 0, 15, 1, 8, 8, 16, 5, 16, 5, 12, 1, 12, 7, 18, 7, 14, 3, 14, 3, 11, 11, 18 }; const igraph_real_t igraph_i_famous_smallestcyclicgroup[] = { 9, 15, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 7, 1, 8, 2, 5, 2, 6, 2, 7, 3, 8, 4, 5, 6, 7 }; const igraph_real_t igraph_i_famous_tetrahedron[] = { 4, 6, 0, 0, 3, 1, 3, 2, 3, 0, 1, 1, 2, 0, 2 }; const igraph_real_t igraph_i_famous_thomassen[] = { 34, 52, 0, 0, 2, 0, 3, 1, 3, 1, 4, 2, 4, 5, 7, 5, 8, 6, 8, 6, 9, 7, 9, 10, 12, 10, 13, 11, 13, 11, 14, 12, 14, 15, 17, 15, 18, 16, 18, 16, 19, 17, 19, 9, 19, 4, 14, 24, 25, 25, 26, 20, 26, 20, 21, 21, 22, 22, 23, 23, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 24, 33, 5, 24, 6, 25, 7, 26, 8, 20, 0, 20, 1, 21, 2, 22, 3, 23, 10, 27, 11, 28, 12, 29, 13, 30, 15, 30, 16, 31, 17, 32, 18, 33 }; const igraph_real_t igraph_i_famous_tutte[] = { 46, 69, 0, 0, 10, 0, 11, 0, 12, 1, 2, 1, 7, 1, 19, 2, 3, 2, 41, 3, 4, 3, 27, 4, 5, 4, 33, 5, 6, 5, 45, 6, 9, 6, 29, 7, 8, 7, 21, 8, 9, 8, 22, 9, 24, 10, 13, 10, 14, 11, 26, 11, 28, 12, 30, 12, 31, 13, 15, 13, 21, 14, 15, 14, 18, 15, 16, 16, 17, 16, 20, 17, 18, 17, 23, 18, 24, 19, 25, 19, 40, 20, 21, 20, 22, 22, 23, 23, 24, 25, 26, 25, 38, 26, 34, 27, 28, 27, 39, 28, 34, 29, 30, 29, 44, 30, 35, 31, 32, 31, 35, 32, 33, 32, 42, 33, 43, 34, 36, 35, 37, 36, 38, 36, 39, 37, 42, 37, 44, 38, 40, 39, 41, 40, 41, 42, 43, 43, 45, 44, 45 }; const igraph_real_t igraph_i_famous_uniquely3colorable[] = { 12, 22, 0, 0, 1, 0, 3, 0, 6, 0, 8, 1, 4, 1, 7, 1, 9, 2, 3, 2, 6, 2, 7, 2, 9, 2, 11, 3, 4, 3, 10, 4, 5, 4, 11, 5, 6, 5, 7, 5, 8, 5, 10, 8, 11, 9, 10 }; const igraph_real_t igraph_i_famous_walther[] = { 25, 31, 0, 0, 1, 1, 2, 1, 8, 2, 3, 2, 13, 3, 4, 3, 16, 4, 5, 5, 6, 5, 19, 6, 7, 6, 20, 7, 21, 8, 9, 8, 13, 9, 10, 9, 22, 10, 11, 10, 20, 11, 12, 13, 14, 14, 15, 14, 23, 15, 16, 15, 17, 17, 18, 18, 19, 18, 24, 20, 24, 22, 23, 23, 24 }; const igraph_real_t igraph_i_famous_zachary[] = { 34, 78, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 10, 0, 11, 0, 12, 0, 13, 0, 17, 0, 19, 0, 21, 0, 31, 1, 2, 1, 3, 1, 7, 1, 13, 1, 17, 1, 19, 1, 21, 1, 30, 2, 3, 2, 7, 2, 27, 2, 28, 2, 32, 2, 9, 2, 8, 2, 13, 3, 7, 3, 12, 3, 13, 4, 6, 4, 10, 5, 6, 5, 10, 5, 16, 6, 16, 8, 30, 8, 32, 8, 33, 9, 33, 13, 33, 14, 32, 14, 33, 15, 32, 15, 33, 18, 32, 18, 33, 19, 33, 20, 32, 20, 33, 22, 32, 22, 33, 23, 25, 23, 27, 23, 32, 23, 33, 23, 29, 24, 25, 24, 27, 24, 31, 25, 31, 26, 29, 26, 33, 27, 33, 28, 31, 28, 33, 29, 32, 29, 33, 30, 32, 30, 33, 31, 32, 31, 33, 32, 33 }; static int igraph_i_famous(igraph_t *graph, const igraph_real_t *data) { long int no_of_nodes = (long int) data[0]; long int no_of_edges = (long int) data[1]; igraph_bool_t directed = (igraph_bool_t) data[2]; igraph_vector_t edges; igraph_vector_view(&edges, data + 3, 2 * no_of_edges); IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, directed)); return 0; } /** * \function igraph_famous * \brief Create a famous graph by simply providing its name. * * * The name of the graph can be simply supplied as a string. * Note that this function creates graphs which don't take any parameters, * there are separate functions for graphs with parameters, e.g. \ref * igraph_full() for creating a full graph. * * * The following graphs are supported: * \clist * \cli Bull * The bull graph, 5 vertices, 5 edges, resembles the * head of a bull if drawn properly. * \cli Chvatal * This is the smallest triangle-free graph that is * both 4-chromatic and 4-regular. According to the Grunbaum * conjecture there exists an m-regular, m-chromatic graph * with n vertices for every m>1 and n>2. The Chvatal graph * is an example for m=4 and n=12. It has 24 edges. * \cli Coxeter * A non-Hamiltonian cubic symmetric graph with 28 * vertices and 42 edges. * \cli Cubical * The Platonic graph of the cube. A convex regular * polyhedron with 8 vertices and 12 edges. * \cli Diamond * A graph with 4 vertices and 5 edges, resembles a * schematic diamond if drawn properly. * \cli Dodecahedral, Dodecahedron * Another Platonic solid * with 20 vertices and 30 edges. * \cli Folkman * The semisymmetric graph with minimum number of * vertices, 20 and 40 edges. A semisymmetric graph is * regular, edge transitive and not vertex transitive. * \cli Franklin * This is a graph whose embedding to the Klein * bottle can be colored with six colors, it is a * counterexample to the necessity of the Heawood * conjecture on a Klein bottle. It has 12 vertices and 18 * edges. * \cli Frucht * The Frucht Graph is the smallest cubical graph * whose automorphism group consists only of the identity * element. It has 12 vertices and 18 edges. * \cli Grotzsch * The Grötzsch graph is a triangle-free graph with * 11 vertices, 20 edges, and chromatic number 4. It is named after * German mathematician Herbert Grötzsch, and its existence * demonstrates that the assumption of planarity is necessary in * Grötzsch's theorem that every triangle-free planar * graph is 3-colorable. * \cli Heawood * The Heawood graph is an undirected graph with 14 * vertices and 21 edges. The graph is cubic, and all cycles in the * graph have six or more edges. Every smaller cubic graph has shorter * cycles, so this graph is the 6-cage, the smallest cubic graph of * girth 6. * \cli Herschel * The Herschel graph is the smallest * nonhamiltonian polyhedral graph. It is the * unique such graph on 11 nodes, and has 18 edges. * \cli House * The house graph is a 5-vertex, 6-edge graph, the * schematic draw of a house if drawn properly, basically a * triangle on top of a square. * \cli HouseX * The same as the house graph with an X in the square. 5 * vertices and 8 edges. * \cli Icosahedral, Icosahedron * A Platonic solid with 12 * vertices and 30 edges. * \cli Krackhardt_Kite * A social network with 10 vertices and 18 edges. * Krackhardt, D. Assessing the Political Landscape: * Structure, Cognition, and Power in Organizations. * Admin. Sci. Quart. 35, 342-369, 1990. * \cli Levi * The graph is a 4-arc transitive cubic graph, it has * 30 vertices and 45 edges. * \cli McGee * The McGee graph is the unique 3-regular 7-cage * graph, it has 24 vertices and 36 edges. * \cli Meredith * The Meredith graph is a quartic graph on 70 * nodes and 140 edges that is a counterexample to the conjecture that * every 4-regular 4-connected graph is Hamiltonian. * \cli Noperfectmatching * A connected graph with 16 vertices and * 27 edges containing no perfect matching. A matching in a graph * is a set of pairwise non-incident edges; that is, no two edges * share a common vertex. A perfect matching is a matching * which covers all vertices of the graph. * \cli Nonline * A graph whose connected components are the 9 * graphs whose presence as a vertex-induced subgraph in a * graph makes a nonline graph. It has 50 vertices and 72 edges. * \cli Octahedral, Octahedron * Platonic solid with 6 * vertices and 12 edges. * \cli Petersen * A 3-regular graph with 10 vertices and 15 edges. It is * the smallest hypohamiltonian graph, i.e. it is * non-hamiltonian but removing any single vertex from it makes it * Hamiltonian. * \cli Robertson * The unique (4,5)-cage graph, i.e. a 4-regular * graph of girth 5. It has 19 vertices and 38 edges. * \cli Smallestcyclicgroup * A smallest nontrivial graph * whose automorphism group is cyclic. It has 9 vertices and * 15 edges. * \cli Tetrahedral, Tetrahedron * Platonic solid with 4 * vertices and 6 edges. * \cli Thomassen * The smallest hypotraceable graph, * on 34 vertices and 52 edges. A hypotracable graph does * not contain a Hamiltonian path but after removing any * single vertex from it the remainder always contains a * Hamiltonian path. A graph containing a Hamiltonian path * is called traceable. * \cli Tutte * Tait's Hamiltonian graph conjecture states that * every 3-connected 3-regular planar graph is Hamiltonian. * This graph is a counterexample. It has 46 vertices and 69 * edges. * \cli Uniquely3colorable * Returns a 12-vertex, triangle-free * graph with chromatic number 3 that is uniquely * 3-colorable. * \cli Walther * An identity graph with 25 vertices and 31 * edges. An identity graph has a single graph automorphism, * the trivial one. * \cli Zachary * Social network of friendships between 34 members of a * karate club at a US university in the 1970s. See * W. W. Zachary, An information flow model for conflict and * fission in small groups, Journal of Anthropological * Research 33, 452-473 (1977). * \endclist * * \param graph Pointer to an uninitialized graph object. * \param name Character constant, the name of the graph to be * created, it is case insensitive. * \return Error code, \c IGRAPH_EINVAL if there is no graph with the * given name. * * \sa Other functions for creating graph structures: * \ref igraph_ring(), \ref igraph_tree(), \ref igraph_lattice(), \ref * igraph_full(). * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges in the graph. */ int igraph_famous(igraph_t *graph, const char *name) { if (!strcasecmp(name, "bull")) { return igraph_i_famous(graph, igraph_i_famous_bull); } else if (!strcasecmp(name, "chvatal")) { return igraph_i_famous(graph, igraph_i_famous_chvatal); } else if (!strcasecmp(name, "coxeter")) { return igraph_i_famous(graph, igraph_i_famous_coxeter); } else if (!strcasecmp(name, "cubical")) { return igraph_i_famous(graph, igraph_i_famous_cubical); } else if (!strcasecmp(name, "diamond")) { return igraph_i_famous(graph, igraph_i_famous_diamond); } else if (!strcasecmp(name, "dodecahedral") || !strcasecmp(name, "dodecahedron")) { return igraph_i_famous(graph, igraph_i_famous_dodecahedron); } else if (!strcasecmp(name, "folkman")) { return igraph_i_famous(graph, igraph_i_famous_folkman); } else if (!strcasecmp(name, "franklin")) { return igraph_i_famous(graph, igraph_i_famous_franklin); } else if (!strcasecmp(name, "frucht")) { return igraph_i_famous(graph, igraph_i_famous_frucht); } else if (!strcasecmp(name, "grotzsch")) { return igraph_i_famous(graph, igraph_i_famous_grotzsch); } else if (!strcasecmp(name, "heawood")) { return igraph_i_famous(graph, igraph_i_famous_heawood); } else if (!strcasecmp(name, "herschel")) { return igraph_i_famous(graph, igraph_i_famous_herschel); } else if (!strcasecmp(name, "house")) { return igraph_i_famous(graph, igraph_i_famous_house); } else if (!strcasecmp(name, "housex")) { return igraph_i_famous(graph, igraph_i_famous_housex); } else if (!strcasecmp(name, "icosahedral") || !strcasecmp(name, "icosahedron")) { return igraph_i_famous(graph, igraph_i_famous_icosahedron); } else if (!strcasecmp(name, "krackhardt_kite")) { return igraph_i_famous(graph, igraph_i_famous_krackhardt_kite); } else if (!strcasecmp(name, "levi")) { return igraph_i_famous(graph, igraph_i_famous_levi); } else if (!strcasecmp(name, "mcgee")) { return igraph_i_famous(graph, igraph_i_famous_mcgee); } else if (!strcasecmp(name, "meredith")) { return igraph_i_famous(graph, igraph_i_famous_meredith); } else if (!strcasecmp(name, "noperfectmatching")) { return igraph_i_famous(graph, igraph_i_famous_noperfectmatching); } else if (!strcasecmp(name, "nonline")) { return igraph_i_famous(graph, igraph_i_famous_nonline); } else if (!strcasecmp(name, "octahedral") || !strcasecmp(name, "octahedron")) { return igraph_i_famous(graph, igraph_i_famous_octahedron); } else if (!strcasecmp(name, "petersen")) { return igraph_i_famous(graph, igraph_i_famous_petersen); } else if (!strcasecmp(name, "robertson")) { return igraph_i_famous(graph, igraph_i_famous_robertson); } else if (!strcasecmp(name, "smallestcyclicgroup")) { return igraph_i_famous(graph, igraph_i_famous_smallestcyclicgroup); } else if (!strcasecmp(name, "tetrahedral") || !strcasecmp(name, "tetrahedron")) { return igraph_i_famous(graph, igraph_i_famous_tetrahedron); } else if (!strcasecmp(name, "thomassen")) { return igraph_i_famous(graph, igraph_i_famous_thomassen); } else if (!strcasecmp(name, "tutte")) { return igraph_i_famous(graph, igraph_i_famous_tutte); } else if (!strcasecmp(name, "uniquely3colorable")) { return igraph_i_famous(graph, igraph_i_famous_uniquely3colorable); } else if (!strcasecmp(name, "walther")) { return igraph_i_famous(graph, igraph_i_famous_walther); } else if (!strcasecmp(name, "zachary")) { return igraph_i_famous(graph, igraph_i_famous_zachary); } IGRAPH_ERRORF("%s is not a known graph. See the documentation for valid graph names.", IGRAPH_EINVAL, name); } leidenbase/src/core/constructors/full.c0000644000176200001440000001257314447675374017777 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "igraph_interface.h" /** * \ingroup generators * \function igraph_full * \brief Creates a full graph (directed or undirected, with or without loops). * * * In a full graph every possible edge is present, every vertex is * connected to every other vertex. A full graph in \c igraph should be * distinguished from the concept of complete graphs as used in graph theory. * If n is a positive integer, then the complete graph K_n on n vertices is * the undirected simple graph with the following property. For any distinct * pair (u,v) of vertices in K_n, uv (or equivalently vu) is an edge of K_n. * In \c igraph, a full graph on n vertices can be K_n, a directed version of * K_n, or K_n with at least one loop edge. In any case, if F is a full graph * on n vertices as generated by \c igraph, then K_n is a subgraph of the * undirected version of F. * * \param graph Pointer to an uninitialized graph object. * \param n Integer, the number of vertices in the graph. * \param directed Logical, whether to create a directed graph. * \param loops Logical, whether to include self-edges (loops). * \return Error code: * \c IGRAPH_EINVAL: invalid number of vertices. * * Time complexity: O(|V|+|E|), * |V| is the number of vertices, * |E| the number of edges in the * graph. Of course this is the same as * O(|E|)=O(|V||V|) * here. * * \sa \ref igraph_lattice(), \ref igraph_star(), \ref igraph_tree() * for creating other regular structures. * * \example examples/simple/igraph_full.c */ int igraph_full(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, igraph_bool_t loops) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int i, j; if (n < 0) { IGRAPH_ERROR("invalid number of vertices", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); if (directed && loops) { IGRAPH_CHECK(igraph_vector_reserve(&edges, 2 * n * n)); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { igraph_vector_push_back(&edges, i); /* reserved */ igraph_vector_push_back(&edges, j); /* reserved */ } } } else if (directed && !loops) { IGRAPH_CHECK(igraph_vector_reserve(&edges, 2 * n * (n - 1))); for (i = 0; i < n; i++) { for (j = 0; j < i; j++) { igraph_vector_push_back(&edges, i); /* reserved */ igraph_vector_push_back(&edges, j); /* reserved */ } for (j = i + 1; j < n; j++) { igraph_vector_push_back(&edges, i); /* reserved */ igraph_vector_push_back(&edges, j); /* reserved */ } } } else if (!directed && loops) { IGRAPH_CHECK(igraph_vector_reserve(&edges, n * (n + 1))); for (i = 0; i < n; i++) { for (j = i; j < n; j++) { igraph_vector_push_back(&edges, i); /* reserved */ igraph_vector_push_back(&edges, j); /* reserved */ } } } else { IGRAPH_CHECK(igraph_vector_reserve(&edges, n * (n - 1))); for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { igraph_vector_push_back(&edges, i); /* reserved */ igraph_vector_push_back(&edges, j); /* reserved */ } } } IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_full_citation * Creates a full citation graph * * This is a directed graph, where every i->j edge is * present if and only if j<i. * If the \c directed argument is zero then an undirected graph is * created, and it is just a full graph. * \param graph Pointer to an uninitialized graph object, the result * is stored here. * \param n The number of vertices. * \param directed Whether to created a directed graph. If zero an * undirected graph is created. * \return Error code. * * Time complexity: O(|V|^2), as we have many edges. */ int igraph_full_citation(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed) { igraph_vector_t edges; long int i, j, ptr = 0; IGRAPH_VECTOR_INIT_FINALLY(&edges, n * (n - 1)); for (i = 1; i < n; i++) { for (j = 0; j < i; j++) { VECTOR(edges)[ptr++] = i; VECTOR(edges)[ptr++] = j; } } IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/constructors/atlas.c0000644000176200001440000000540214447675374020132 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph R package. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "constructors/atlas-edges.h" /** * \function igraph_atlas * \brief Create a small graph from the \quote Graph Atlas \endquote. * * * The number of the graph is given as a parameter. * The graphs are listed: \olist * \oli in increasing order of number of nodes; * \oli for a fixed number of nodes, in increasing order of the * number of edges; * \oli for fixed numbers of nodes and edges, in increasing * order of the degree sequence, for example 111223 < 112222; * \oli for fixed degree sequence, in increasing number of * automorphisms. * \endolist * * * The data was converted from the NetworkX software package, * see http://networkx.github.io . * * * See \emb An Atlas of Graphs \eme by Ronald C. Read and Robin J. Wilson, * Oxford University Press, 1998. * * \param graph Pointer to an uninitialized graph object. * \param number The number of the graph to generate. * * Added in version 0.2. * * Time complexity: O(|V|+|E|), the number of vertices plus the number of * edges. * * \example examples/simple/igraph_atlas.c */ int igraph_atlas(igraph_t *graph, int number) { igraph_integer_t pos, n, e; igraph_vector_t v = IGRAPH_VECTOR_NULL; if (number < 0 || number >= (int) (sizeof(igraph_i_atlas_edges_pos) / sizeof(long int))) { IGRAPH_ERROR("No such graph in atlas", IGRAPH_EINVAL); } pos = (igraph_integer_t) igraph_i_atlas_edges_pos[number]; n = (igraph_integer_t) igraph_i_atlas_edges[pos]; e = (igraph_integer_t) igraph_i_atlas_edges[pos + 1]; IGRAPH_CHECK(igraph_create(graph, igraph_vector_view(&v, igraph_i_atlas_edges + pos + 2, e * 2), n, IGRAPH_UNDIRECTED)); return 0; } leidenbase/src/core/constructors/linegraph.c0000644000176200001440000001302014447675374020772 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "igraph_interface.h" #include "core/interruption.h" /* Note to self: tried using adjacency lists instead of igraph_incident queries, * with minimal performance improvements on a graph with 70K vertices and 360K * edges. (1.09s instead of 1.10s). I think it's not worth the fuss. */ static int igraph_i_linegraph_undirected(const igraph_t *graph, igraph_t *linegraph) { long int no_of_edges = igraph_ecount(graph); long int i, j, n; igraph_vector_t adjedges, adjedges2; igraph_vector_t edges; long int prev = -1; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&adjedges, 0); IGRAPH_VECTOR_INIT_FINALLY(&adjedges2, 0); for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); IGRAPH_ALLOW_INTERRUPTION(); if (from != prev) { IGRAPH_CHECK(igraph_incident(graph, &adjedges, (igraph_integer_t) from, IGRAPH_ALL)); } n = igraph_vector_size(&adjedges); for (j = 0; j < n; j++) { long int e = (long int) VECTOR(adjedges)[j]; if (e < i) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, e)); } } IGRAPH_CHECK(igraph_incident(graph, &adjedges2, (igraph_integer_t) to, IGRAPH_ALL)); n = igraph_vector_size(&adjedges2); for (j = 0; j < n; j++) { long int e = (long int) VECTOR(adjedges2)[j]; if (e < i) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, e)); } } prev = from; } igraph_vector_destroy(&adjedges); igraph_vector_destroy(&adjedges2); IGRAPH_FINALLY_CLEAN(2); igraph_create(linegraph, &edges, (igraph_integer_t) no_of_edges, igraph_is_directed(graph)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_linegraph_directed(const igraph_t *graph, igraph_t *linegraph) { long int no_of_edges = igraph_ecount(graph); long int i, j, n; igraph_vector_t adjedges; igraph_vector_t edges; long int prev = -1; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&adjedges, 0); for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); IGRAPH_ALLOW_INTERRUPTION(); if (from != prev) { IGRAPH_CHECK(igraph_incident(graph, &adjedges, (igraph_integer_t) from, IGRAPH_IN)); } n = igraph_vector_size(&adjedges); for (j = 0; j < n; j++) { long int e = (long int) VECTOR(adjedges)[j]; IGRAPH_CHECK(igraph_vector_push_back(&edges, e)); IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); } prev = from; } igraph_vector_destroy(&adjedges); IGRAPH_FINALLY_CLEAN(1); igraph_create(linegraph, &edges, (igraph_integer_t) no_of_edges, igraph_is_directed(graph)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_linegraph * \brief Create the line graph of a graph. * * The line graph L(G) of a G undirected graph is defined as follows. * L(G) has one vertex for each edge in G and two different vertices in L(G) * are connected by an edge if their corresponding edges share an end point. * In a multigraph, if two end points are shared, two edges are created. * The vertex of a loop is counted as two end points. * * * The line graph L(G) of a G directed graph is slightly different, * L(G) has one vertex for each edge in G and two vertices in L(G) are connected * by a directed edge if the target of the first vertex's corresponding edge * is the same as the source of the second vertex's corresponding edge. * * * Edge \em i in the original graph will correspond to vertex \em i * in the line graph. * * * The first version of this function was contributed by Vincent Matossian, * thanks. * \param graph The input graph, may be directed or undirected. * \param linegraph Pointer to an uninitialized graph object, the * result is stored here. * \return Error code. * * Time complexity: O(|V|+|E|), the number of edges plus the number of vertices. */ int igraph_linegraph(const igraph_t *graph, igraph_t *linegraph) { if (igraph_is_directed(graph)) { return igraph_i_linegraph_directed(graph, linegraph); } else { return igraph_i_linegraph_undirected(graph, linegraph); } } leidenbase/src/core/constructors/adjacency.c0000644000176200001440000005500314447675374020751 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "igraph_adjlist.h" #include "igraph_attributes.h" #include "igraph_interface.h" static int igraph_i_adjacency_directed(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges); static int igraph_i_adjacency_max(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges); static int igraph_i_adjacency_upper(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges); static int igraph_i_adjacency_lower(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges); static int igraph_i_adjacency_min(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges); static int igraph_i_adjacency_directed(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j, k; for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < no_of_nodes; j++) { long int M = (long int) MATRIX(*adjmatrix, i, j); for (k = 0; k < M; k++) { IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); } } } return 0; } static int igraph_i_adjacency_max(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j, k; for (i = 0; i < no_of_nodes; i++) { for (j = i; j < no_of_nodes; j++) { long int M1 = (long int) MATRIX(*adjmatrix, i, j); long int M2 = (long int) MATRIX(*adjmatrix, j, i); if (M1 < M2) { M1 = M2; } for (k = 0; k < M1; k++) { IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); } } } return 0; } static int igraph_i_adjacency_upper(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j, k; for (i = 0; i < no_of_nodes; i++) { for (j = i; j < no_of_nodes; j++) { long int M = (long int) MATRIX(*adjmatrix, i, j); for (k = 0; k < M; k++) { IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); } } } return 0; } static int igraph_i_adjacency_lower(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j, k; for (i = 0; i < no_of_nodes; i++) { for (j = 0; j <= i; j++) { long int M = (long int) MATRIX(*adjmatrix, i, j); for (k = 0; k < M; k++) { IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); } } } return 0; } static int igraph_i_adjacency_min(const igraph_matrix_t *adjmatrix, igraph_vector_t *edges) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j, k; for (i = 0; i < no_of_nodes; i++) { for (j = i; j < no_of_nodes; j++) { long int M1 = (long int) MATRIX(*adjmatrix, i, j); long int M2 = (long int) MATRIX(*adjmatrix, j, i); if (M1 > M2) { M1 = M2; } for (k = 0; k < M1; k++) { IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); } } } return 0; } /** * \ingroup generators * \function igraph_adjacency * \brief Creates a graph from an adjacency matrix. * * The order of the vertices in the matrix is preserved, i.e. the vertex * corresponding to the first row/column will be vertex with id 0, the * next row is for vertex 1, etc. * \param graph Pointer to an uninitialized graph object. * \param adjmatrix The adjacency matrix. How it is interpreted * depends on the \p mode argument. * \param mode Constant to specify how the given matrix is interpreted * as an adjacency matrix. Possible values * (A(i,j) * is the element in row i and column * j in the adjacency matrix * \p adjmatrix): * \clist * \cli IGRAPH_ADJ_DIRECTED * the graph will be directed and * an element gives the number of edges between two vertices. * \cli IGRAPH_ADJ_UNDIRECTED * this is the same as \c IGRAPH_ADJ_MAX, * for convenience. * \cli IGRAPH_ADJ_MAX * undirected graph will be created * and the number of edges between vertices * i and * j is * max(A(i,j), A(j,i)). * \cli IGRAPH_ADJ_MIN * undirected graph will be created * with min(A(i,j), A(j,i)) * edges between vertices * i and * j. * \cli IGRAPH_ADJ_PLUS * undirected graph will be created * with A(i,j)+A(j,i) edges * between vertices * i and * j. * \cli IGRAPH_ADJ_UPPER * undirected graph will be created, * only the upper right triangle (including the diagonal) is * used for the number of edges. * \cli IGRAPH_ADJ_LOWER * undirected graph will be created, * only the lower left triangle (including the diagonal) is * used for creating the edges. * \endclist * \return Error code, * \c IGRAPH_NONSQUARE: non-square matrix. * * Time complexity: O(|V||V|), * |V| is the number of vertices in the graph. * * \example examples/simple/igraph_adjacency.c */ int igraph_adjacency(igraph_t *graph, const igraph_matrix_t *adjmatrix, igraph_adjacency_t mode) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int no_of_nodes; /* Some checks */ if (igraph_matrix_nrow(adjmatrix) != igraph_matrix_ncol(adjmatrix)) { IGRAPH_ERROR("Non-square matrix", IGRAPH_NONSQUARE); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); /* Collect the edges */ no_of_nodes = igraph_matrix_nrow(adjmatrix); switch (mode) { case IGRAPH_ADJ_DIRECTED: IGRAPH_CHECK(igraph_i_adjacency_directed(adjmatrix, &edges)); break; case IGRAPH_ADJ_MAX: IGRAPH_CHECK(igraph_i_adjacency_max(adjmatrix, &edges)); break; case IGRAPH_ADJ_UPPER: IGRAPH_CHECK(igraph_i_adjacency_upper(adjmatrix, &edges)); break; case IGRAPH_ADJ_LOWER: IGRAPH_CHECK(igraph_i_adjacency_lower(adjmatrix, &edges)); break; case IGRAPH_ADJ_MIN: IGRAPH_CHECK(igraph_i_adjacency_min(adjmatrix, &edges)); break; case IGRAPH_ADJ_PLUS: IGRAPH_CHECK(igraph_i_adjacency_directed(adjmatrix, &edges)); break; } IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, (mode == IGRAPH_ADJ_DIRECTED))); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_weighted_adjacency_directed( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops); static int igraph_i_weighted_adjacency_plus( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops); static int igraph_i_weighted_adjacency_max( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops); static int igraph_i_weighted_adjacency_upper( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops); static int igraph_i_weighted_adjacency_lower( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops); static int igraph_i_weighted_adjacency_min( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops); static int igraph_i_weighted_adjacency_directed( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j; for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < no_of_nodes; j++) { igraph_real_t M = MATRIX(*adjmatrix, i, j); if (M == 0.0) { continue; } if (i == j && !loops) { continue; } IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); IGRAPH_CHECK(igraph_vector_push_back(weights, M)); } } return 0; } static int igraph_i_weighted_adjacency_plus( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j; for (i = 0; i < no_of_nodes; i++) { for (j = i; j < no_of_nodes; j++) { igraph_real_t M = MATRIX(*adjmatrix, i, j) + MATRIX(*adjmatrix, j, i); if (M == 0.0) { continue; } if (i == j && !loops) { continue; } if (i == j) { M /= 2; } IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); IGRAPH_CHECK(igraph_vector_push_back(weights, M)); } } return 0; } static int igraph_i_weighted_adjacency_max( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j; for (i = 0; i < no_of_nodes; i++) { for (j = i; j < no_of_nodes; j++) { igraph_real_t M1 = MATRIX(*adjmatrix, i, j); igraph_real_t M2 = MATRIX(*adjmatrix, j, i); if (M1 < M2) { M1 = M2; } if (M1 == 0.0) { continue; } if (i == j && !loops) { continue; } IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); IGRAPH_CHECK(igraph_vector_push_back(weights, M1)); } } return 0; } static int igraph_i_weighted_adjacency_upper( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j; for (i = 0; i < no_of_nodes; i++) { for (j = i; j < no_of_nodes; j++) { igraph_real_t M = MATRIX(*adjmatrix, i, j); if (M == 0.0) { continue; } if (i == j && !loops) { continue; } IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); IGRAPH_CHECK(igraph_vector_push_back(weights, M)); } } return 0; } static int igraph_i_weighted_adjacency_lower( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j; for (i = 0; i < no_of_nodes; i++) { for (j = 0; j <= i; j++) { igraph_real_t M = MATRIX(*adjmatrix, i, j); if (M == 0.0) { continue; } if (i == j && !loops) { continue; } IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); IGRAPH_CHECK(igraph_vector_push_back(weights, M)); } } return 0; } static int igraph_i_weighted_adjacency_min( const igraph_matrix_t *adjmatrix, igraph_vector_t *edges, igraph_vector_t *weights, igraph_bool_t loops) { long int no_of_nodes = igraph_matrix_nrow(adjmatrix); long int i, j; for (i = 0; i < no_of_nodes; i++) { for (j = i; j < no_of_nodes; j++) { igraph_real_t M1 = MATRIX(*adjmatrix, i, j); igraph_real_t M2 = MATRIX(*adjmatrix, j, i); if (M1 > M2) { M1 = M2; } if (M1 == 0.0) { continue; } if (i == j && !loops) { continue; } IGRAPH_CHECK(igraph_vector_push_back(edges, i)); IGRAPH_CHECK(igraph_vector_push_back(edges, j)); IGRAPH_CHECK(igraph_vector_push_back(weights, M1)); } } return 0; } /** * \ingroup generators * \function igraph_weighted_adjacency * \brief Creates a graph from a weighted adjacency matrix. * * The order of the vertices in the matrix is preserved, i.e. the vertex * corresponding to the first row/column will be vertex with id 0, the * next row is for vertex 1, etc. * \param graph Pointer to an uninitialized graph object. * \param adjmatrix The weighted adjacency matrix. How it is interpreted * depends on the \p mode argument. The common feature is that * edges with zero weights are considered nonexistent (however, * negative weights are permitted). * \param mode Constant to specify how the given matrix is interpreted * as an adjacency matrix. Possible values * (A(i,j) * is the element in row i and column * j in the adjacency matrix * \p adjmatrix): * \clist * \cli IGRAPH_ADJ_DIRECTED * the graph will be directed and * an element gives the weight of the edge between two vertices. * \cli IGRAPH_ADJ_UNDIRECTED * this is the same as \c IGRAPH_ADJ_MAX, * for convenience. * \cli IGRAPH_ADJ_MAX * undirected graph will be created * and the weight of the edge between vertices * i and * j is * max(A(i,j), A(j,i)). * \cli IGRAPH_ADJ_MIN * undirected graph will be created * with edge weight min(A(i,j), A(j,i)) * between vertices * i and * j. * \cli IGRAPH_ADJ_PLUS * undirected graph will be created * with edge weight A(i,j)+A(j,i) * between vertices * i and * j. * \cli IGRAPH_ADJ_UPPER * undirected graph will be created, * only the upper right triangle (including the diagonal) is * used for the edge weights. * \cli IGRAPH_ADJ_LOWER * undirected graph will be created, * only the lower left triangle (including the diagonal) is * used for the edge weights. * \endclist * \param attr the name of the attribute that will store the edge weights. * If \c NULL , it will use \c weight as the attribute name. * \param loops Logical scalar, whether to ignore the diagonal elements * in the adjacency matrix. * \return Error code, * \c IGRAPH_NONSQUARE: non-square matrix. * * Time complexity: O(|V||V|), * |V| is the number of vertices in the graph. * * \example examples/simple/igraph_weighted_adjacency.c */ int igraph_weighted_adjacency(igraph_t *graph, const igraph_matrix_t *adjmatrix, igraph_adjacency_t mode, const char* attr, igraph_bool_t loops) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; igraph_vector_t weights = IGRAPH_VECTOR_NULL; const char* default_attr = "weight"; igraph_vector_ptr_t attr_vec; igraph_attribute_record_t attr_rec; long int no_of_nodes; /* Some checks */ if (igraph_matrix_nrow(adjmatrix) != igraph_matrix_ncol(adjmatrix)) { IGRAPH_ERROR("Non-square matrix", IGRAPH_NONSQUARE); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&weights, 0); IGRAPH_VECTOR_PTR_INIT_FINALLY(&attr_vec, 1); /* Collect the edges */ no_of_nodes = igraph_matrix_nrow(adjmatrix); switch (mode) { case IGRAPH_ADJ_DIRECTED: IGRAPH_CHECK(igraph_i_weighted_adjacency_directed(adjmatrix, &edges, &weights, loops)); break; case IGRAPH_ADJ_MAX: IGRAPH_CHECK(igraph_i_weighted_adjacency_max(adjmatrix, &edges, &weights, loops)); break; case IGRAPH_ADJ_UPPER: IGRAPH_CHECK(igraph_i_weighted_adjacency_upper(adjmatrix, &edges, &weights, loops)); break; case IGRAPH_ADJ_LOWER: IGRAPH_CHECK(igraph_i_weighted_adjacency_lower(adjmatrix, &edges, &weights, loops)); break; case IGRAPH_ADJ_MIN: IGRAPH_CHECK(igraph_i_weighted_adjacency_min(adjmatrix, &edges, &weights, loops)); break; case IGRAPH_ADJ_PLUS: IGRAPH_CHECK(igraph_i_weighted_adjacency_plus(adjmatrix, &edges, &weights, loops)); break; } /* Prepare attribute record */ attr_rec.name = attr ? attr : default_attr; attr_rec.type = IGRAPH_ATTRIBUTE_NUMERIC; attr_rec.value = &weights; VECTOR(attr_vec)[0] = &attr_rec; /* Create graph */ IGRAPH_CHECK(igraph_empty(graph, (igraph_integer_t) no_of_nodes, (mode == IGRAPH_ADJ_DIRECTED))); IGRAPH_FINALLY(igraph_destroy, graph); if (igraph_vector_size(&edges) > 0) { IGRAPH_CHECK(igraph_add_edges(graph, &edges, &attr_vec)); } IGRAPH_FINALLY_CLEAN(1); /* Cleanup */ igraph_vector_destroy(&edges); igraph_vector_destroy(&weights); igraph_vector_ptr_destroy(&attr_vec); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_adjlist * \brief Creates a graph from an adjacency list. * * An adjacency list is a list of vectors, containing the neighbors * of all vertices. For operations that involve many changes to the * graph structure, it is recommended that you convert the graph into * an adjacency list via \ref igraph_adjlist_init(), perform the * modifications (these are cheap for an adjacency list) and then * recreate the igraph graph via this function. * * \param graph Pointer to an uninitialized graph object. * \param adjlist The adjacency list. * \param mode Whether or not to create a directed graph. \c IGRAPH_ALL * means an undirected graph, \c IGRAPH_OUT means a * directed graph from an out-adjacency list (i.e. each * list contains the successors of the corresponding * vertices), \c IGRAPH_IN means a directed graph from an * in-adjacency list * \param duplicate Logical, for undirected graphs this specified * whether each edge is included twice, in the vectors of * both adjacent vertices. If this is false (0), then it is * assumed that every edge is included only once. This argument * is ignored for directed graphs. * \return Error code. * * \sa \ref igraph_adjlist_init() for the opposite operation. * * Time complexity: O(|V|+|E|). * */ int igraph_adjlist(igraph_t *graph, const igraph_adjlist_t *adjlist, igraph_neimode_t mode, igraph_bool_t duplicate) { long int no_of_nodes = igraph_adjlist_size(adjlist); long int no_of_edges = 0; long int i; igraph_vector_t edges; long int edgeptr = 0; duplicate = duplicate && (mode == IGRAPH_ALL); /* only duplicate if undirected */ for (i = 0; i < no_of_nodes; i++) { no_of_edges += igraph_vector_int_size(igraph_adjlist_get(adjlist, i)); } if (duplicate) { no_of_edges /= 2; } IGRAPH_VECTOR_INIT_FINALLY(&edges, 2 * no_of_edges); for (i = 0; i < no_of_nodes; i++) { igraph_vector_int_t *neis = igraph_adjlist_get(adjlist, i); long int j, n = igraph_vector_int_size(neis); long int loops = 0; for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(*neis)[j]; if (nei == i) { loops++; } else { if (! duplicate || nei > i) { if (edgeptr + 2 > 2 * no_of_edges) { IGRAPH_ERROR("Invalid adjacency list, most probably not correctly" " duplicated edges for an undirected graph", IGRAPH_EINVAL); } if (mode == IGRAPH_IN) { VECTOR(edges)[edgeptr++] = nei; VECTOR(edges)[edgeptr++] = i; } else { VECTOR(edges)[edgeptr++] = i; VECTOR(edges)[edgeptr++] = nei; } } } } /* loops */ if (duplicate) { loops = loops / 2; } if (edgeptr + 2 * loops > 2 * no_of_edges) { IGRAPH_ERROR("Invalid adjacency list, most probably not correctly" " duplicated edges for an undirected graph", IGRAPH_EINVAL); } for (j = 0; j < loops; j++) { VECTOR(edges)[edgeptr++] = i; VECTOR(edges)[edgeptr++] = i; } } if (mode == IGRAPH_ALL) IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, 0)); else IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, 1)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/constructors/kautz.c0000644000176200001440000001405314447675374020166 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "igraph_interface.h" /** * \function igraph_kautz * \brief Generate a Kautz graph. * * A Kautz graph is a labeled graph, vertices are labeled by strings * of length \c n+1 above an alphabet with \c m+1 letters, with * the restriction that every two consecutive letters in the string * must be different. There is a directed edge from a vertex \c v to * another vertex \c w if it is possible to transform the string of * \c v into the string of \c w by removing the first letter and * appending a letter to it. For string length 1 the new letter * cannot equal the old letter, so there are no loops. * * * Kautz graphs have some interesting properties, see e.g. Wikipedia * for details. * * * Vincent Matossian wrote the first version of this function in R, * thanks. * \param graph Pointer to an uninitialized graph object, the result * will be stored here. * \param m Integer, \c m+1 is the number of letters in the alphabet. * \param n Integer, \c n+1 is the length of the strings. * \return Error code. * * \sa \ref igraph_de_bruijn(). * * Time complexity: O(|V|* [(m+1)/m]^n +|E|), in practice it is more * like O(|V|+|E|). |V| is the number of vertices, |E| is the number * of edges and \c m and \c n are the corresponding arguments. */ int igraph_kautz(igraph_t *graph, igraph_integer_t m, igraph_integer_t n) { /* m+1 - number of symbols */ /* n+1 - length of strings */ long int mm = m; long int no_of_nodes, no_of_edges; long int allstrings; long int i, j, idx = 0; igraph_vector_t edges; igraph_vector_long_t digits, table; igraph_vector_long_t index1, index2; long int actb = 0; long int actvalue = 0; if (m < 0 || n < 0) { IGRAPH_ERROR("`m' and `n' should be non-negative in a Kautz graph", IGRAPH_EINVAL); } if (n == 0) { return igraph_full(graph, m + 1, IGRAPH_DIRECTED, IGRAPH_NO_LOOPS); } if (m == 0) { return igraph_empty(graph, 0, IGRAPH_DIRECTED); } no_of_nodes = (long int) ((m + 1) * pow(m, n)); no_of_edges = no_of_nodes * m; allstrings = (long int) pow(m + 1, n + 1); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_long_init(&table, n + 1)); IGRAPH_FINALLY(igraph_vector_long_destroy, &table); j = 1; for (i = n; i >= 0; i--) { VECTOR(table)[i] = j; j *= (m + 1); } IGRAPH_CHECK(igraph_vector_long_init(&digits, n + 1)); IGRAPH_FINALLY(igraph_vector_long_destroy, &digits); IGRAPH_CHECK(igraph_vector_long_init(&index1, (long int) pow(m + 1, n + 1))); IGRAPH_FINALLY(igraph_vector_long_destroy, &index1); IGRAPH_CHECK(igraph_vector_long_init(&index2, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &index2); /* Fill the index tables*/ while (1) { /* at the beginning of the loop, 0:actb contain the valid prefix */ /* we might need to fill it to get a valid string */ long int z = 0; if (VECTOR(digits)[actb] == 0) { z = 1; } for (actb++; actb <= n; actb++) { VECTOR(digits)[actb] = z; actvalue += z * VECTOR(table)[actb]; z = 1 - z; } actb = n; /* ok, we have a valid string now */ VECTOR(index1)[actvalue] = idx + 1; VECTOR(index2)[idx] = actvalue; idx++; /* finished? */ if (idx >= no_of_nodes) { break; } /* not yet, we need a valid prefix now */ while (1) { /* try to increase digits at position actb */ long int next = VECTOR(digits)[actb] + 1; if (actb != 0 && VECTOR(digits)[actb - 1] == next) { next++; } if (next <= m) { /* ok, no problem */ actvalue += (next - VECTOR(digits)[actb]) * VECTOR(table)[actb]; VECTOR(digits)[actb] = next; break; } else { /* bad luck, try the previous digit */ actvalue -= VECTOR(digits)[actb] * VECTOR(table)[actb]; actb--; } } } IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); /* Now come the edges at last */ for (i = 0; i < no_of_nodes; i++) { long int fromvalue = VECTOR(index2)[i]; long int lastdigit = fromvalue % (mm + 1); long int basis = (fromvalue * (mm + 1)) % allstrings; for (j = 0; j <= m; j++) { long int tovalue, to; if (j == lastdigit) { continue; } tovalue = basis + j; to = VECTOR(index1)[tovalue] - 1; if (to < 0) { continue; } igraph_vector_push_back(&edges, i); igraph_vector_push_back(&edges, to); } } igraph_vector_long_destroy(&index2); igraph_vector_long_destroy(&index1); igraph_vector_long_destroy(&digits); igraph_vector_long_destroy(&table); IGRAPH_FINALLY_CLEAN(4); IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, IGRAPH_DIRECTED)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/constructors/prufer.c0000644000176200001440000000704314447675374020334 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "igraph_interface.h" /** * \ingroup generators * \function igraph_from_prufer * \brief Generates a tree from a Prüfer sequence. * * A Prüfer sequence is a unique sequence of integers associated * with a labelled tree. A tree on n vertices can be represented by a * sequence of n-2 integers, each between 0 and n-1 (inclusive). * * The algorithm used by this function is based on * Paulius Micikevičius, Saverio Caminiti, Narsingh Deo: * Linear-time Algorithms for Encoding Trees as Sequences of Node Labels * * \param graph Pointer to an uninitialized graph object. * \param prufer The Prüfer sequence * \return Error code: * \clist * \cli IGRAPH_ENOMEM * there is not enough memory to perform the operation. * \cli IGRAPH_EINVAL * invalid Prüfer sequence given * \endclist * * \sa \ref igraph_to_prufer(), \ref igraph_tree(), \ref igraph_tree_game() * */ int igraph_from_prufer(igraph_t *graph, const igraph_vector_int_t *prufer) { igraph_vector_int_t degree; igraph_vector_t edges; long n; long i, k; long u, v; /* vertices */ long ec; n = igraph_vector_int_size(prufer) + 2; IGRAPH_VECTOR_INT_INIT_FINALLY(°ree, n); /* initializes vector to zeros */ IGRAPH_VECTOR_INIT_FINALLY(&edges, 2 * (n - 1)); /* build out-degree vector (i.e. number of child vertices) and verify Prufer sequence */ for (i = 0; i < n - 2; ++i) { long u = VECTOR(*prufer)[i]; if (u >= n || u < 0) { IGRAPH_ERROR("Invalid Prufer sequence", IGRAPH_EINVAL); } VECTOR(degree)[u] += 1; } v = 0; /* initialize v now, in case Prufer sequence is empty */ k = 0; /* index into the Prufer vector */ ec = 0; /* index into the edges vector */ for (i = 0; i < n; ++i) { u = i; while (k < n - 2 && u <= i && (VECTOR(degree)[u] == 0)) { /* u is a leaf here */ v = VECTOR(*prufer)[k]; /* parent of u */ /* add edge */ VECTOR(edges)[ec++] = v; VECTOR(edges)[ec++] = u; k += 1; VECTOR(degree)[v] -= 1; u = v; } if (k == n - 2) { break; } } /* find u for last edge, v is already set */ for (u = i + 1; u < n; ++u) if ((VECTOR(degree)[u] == 0) && u != v) { break; } /* add last edge */ VECTOR(edges)[ec++] = v; VECTOR(edges)[ec++] = u; IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) n, /* directed = */ 0)); igraph_vector_destroy(&edges); igraph_vector_int_destroy(°ree); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } leidenbase/src/core/constructors/regular.c0000644000176200001440000004323214447675374020472 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_operators.h" #include "core/interruption.h" /** * \ingroup generators * \function igraph_star * \brief Creates a \em star graph, every vertex connects only to the center. * * \param graph Pointer to an uninitialized graph object, this will * be the result. * \param n Integer constant, the number of vertices in the graph. * \param mode Constant, gives the type of the star graph to * create. Possible values: * \clist * \cli IGRAPH_STAR_OUT * directed star graph, edges point * \em from the center to the other vertices. * \cli IGRAPH_STAR_IN * directed star graph, edges point * \em to the center from the other vertices. * \cli IGRAPH_STAR_MUTUAL * directed star graph with mutual edges. * \cli IGRAPH_STAR_UNDIRECTED * an undirected star graph is * created. * \endclist * \param center Id of the vertex which will be the center of the * graph. * \return Error code: * \clist * \cli IGRAPH_EINVVID * invalid number of vertices. * \cli IGRAPH_EINVAL * invalid center vertex. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(|V|), the * number of vertices in the graph. * * \sa \ref igraph_lattice(), \ref igraph_ring(), \ref igraph_tree() * for creating other regular structures. * * \example examples/simple/igraph_star.c */ int igraph_star(igraph_t *graph, igraph_integer_t n, igraph_star_mode_t mode, igraph_integer_t center) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int i; if (n < 0) { IGRAPH_ERROR("Invalid number of vertices", IGRAPH_EINVVID); } if (center < 0 || center > n - 1) { IGRAPH_ERROR("Invalid center vertex", IGRAPH_EINVAL); } if (mode != IGRAPH_STAR_OUT && mode != IGRAPH_STAR_IN && mode != IGRAPH_STAR_MUTUAL && mode != IGRAPH_STAR_UNDIRECTED) { IGRAPH_ERROR("invalid mode", IGRAPH_EINVMODE); } if (mode != IGRAPH_STAR_MUTUAL) { IGRAPH_VECTOR_INIT_FINALLY(&edges, (n - 1) * 2); } else { IGRAPH_VECTOR_INIT_FINALLY(&edges, (n - 1) * 2 * 2); } if (mode == IGRAPH_STAR_OUT) { for (i = 0; i < center; i++) { VECTOR(edges)[2 * i] = center; VECTOR(edges)[2 * i + 1] = i; } for (i = center + 1; i < n; i++) { VECTOR(edges)[2 * (i - 1)] = center; VECTOR(edges)[2 * (i - 1) + 1] = i; } } else if (mode == IGRAPH_STAR_MUTUAL) { for (i = 0; i < center; i++) { VECTOR(edges)[4 * i] = center; VECTOR(edges)[4 * i + 1] = i; VECTOR(edges)[4 * i + 2] = i; VECTOR(edges)[4 * i + 3] = center; } for (i = center + 1; i < n; i++) { VECTOR(edges)[4 * i - 4] = center; VECTOR(edges)[4 * i - 3] = i; VECTOR(edges)[4 * i - 2] = i; VECTOR(edges)[4 * i - 1] = center; } } else { for (i = 0; i < center; i++) { VECTOR(edges)[2 * i + 1] = center; VECTOR(edges)[2 * i] = i; } for (i = center + 1; i < n; i++) { VECTOR(edges)[2 * (i - 1) + 1] = center; VECTOR(edges)[2 * (i - 1)] = i; } } IGRAPH_CHECK(igraph_create(graph, &edges, 0, (mode != IGRAPH_STAR_UNDIRECTED))); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup generators * \function igraph_lattice * \brief Arbitrary dimensional square lattices. * * Creates d-dimensional square lattices of the given size. Optionally, * the lattice can be made periodic, and the neighbors within a given * graph distance can be connected. * * * In the zero-dimensional case, the singleton graph is returned. * * * The vertices of the resulting graph are ordered such that the * index of the vertex at position (i_0, i_1, i_2, ..., i_d) * in a lattice of size (n_0, n_1, ..., n_d) will be * i_0 + n_0 * i_1 + n_0 * n_1 * i_2 + .... * * \param graph An uninitialized graph object. * \param dimvector Vector giving the sizes of the lattice in each of * its dimensions. The dimension of the lattice will be the * same as the length of this vector. * \param nei Integer value giving the distance (number of steps) * within which two vertices will be connected. * \param directed Boolean, whether to create a directed graph. * If the \c mutual and \c circular arguments are not set to true, * edges will be directed from lower-index vertices towards * higher-index ones. * \param mutual Boolean, if the graph is directed this gives whether * to create all connections as mutual. * \param circular Boolean, defines whether the generated lattice is * periodic. * \return Error code: * \c IGRAPH_EINVAL: invalid (negative) * dimension vector. * * Time complexity: If \p nei is less than two then it is O(|V|+|E|) (as * far as I remember), |V| and |E| are the number of vertices * and edges in the generated graph. Otherwise it is O(|V|*d^k+|E|), d * is the average degree of the graph, k is the \p nei argument. */ int igraph_lattice(igraph_t *graph, const igraph_vector_t *dimvector, igraph_integer_t nei, igraph_bool_t directed, igraph_bool_t mutual, igraph_bool_t circular) { long int dims = igraph_vector_size(dimvector); long int no_of_nodes = (long int) igraph_vector_prod(dimvector); igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int *coords, *weights; long int i, j; int carry, pos; if (igraph_vector_any_smaller(dimvector, 0)) { IGRAPH_ERROR("Invalid dimension vector", IGRAPH_EINVAL); } /* init coords & weights */ coords = IGRAPH_CALLOC(dims, long int); if (coords == 0) { IGRAPH_ERROR("Lattice creation failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, coords); weights = IGRAPH_CALLOC(dims, long int); if (weights == 0) { IGRAPH_ERROR("Lattice creation failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, weights); if (dims > 0) { weights[0] = 1; for (i = 1; i < dims; i++) { weights[i] = weights[i - 1] * (long int) VECTOR(*dimvector)[i - 1]; } } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_nodes * dims + mutual * directed * no_of_nodes * dims)); for (i = 0; i < no_of_nodes; i++) { IGRAPH_ALLOW_INTERRUPTION(); for (j = 0; j < dims; j++) { if (circular || coords[j] != VECTOR(*dimvector)[j] - 1) { long int new_nei; if (coords[j] != VECTOR(*dimvector)[j] - 1) { new_nei = i + weights[j] + 1; } else { new_nei = i - (long int) (VECTOR(*dimvector)[j] - 1) * weights[j] + 1; } if (new_nei != i + 1 && (VECTOR(*dimvector)[j] != 2 || coords[j] != 1 || directed)) { igraph_vector_push_back(&edges, i); /* reserved */ igraph_vector_push_back(&edges, new_nei - 1); /* reserved */ } } /* if circular || coords[j] */ if (mutual && directed && (circular || coords[j] != 0)) { long int new_nei; if (coords[j] != 0) { new_nei = i - weights[j] + 1; } else { new_nei = i + (long int) (VECTOR(*dimvector)[j] - 1) * weights[j] + 1; } if (new_nei != i + 1 && (VECTOR(*dimvector)[j] != 2 || !circular)) { igraph_vector_push_back(&edges, i); /* reserved */ igraph_vector_push_back(&edges, new_nei - 1); /* reserved */ } } /* if circular || coords[0] */ } /* for j= 2) { IGRAPH_CHECK(igraph_connect_neighborhood(graph, nei, IGRAPH_ALL)); } /* clean up */ IGRAPH_FREE(coords); IGRAPH_FREE(weights); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \ingroup generators * \function igraph_ring * \brief Creates a \em cycle graph or a \em path graph. * * A circular ring on \c n vertices is commonly known in graph * theory as the cycle graph, and often denoted by C_n. * Removing a single edge from the cycle graph C_n results * in the path graph P_n. This function can generate both. * * * This function is a convenience wrapper for the one-dimensional case of * \ref igraph_lattice(). * * \param graph Pointer to an uninitialized graph object. * \param n The number of vertices in the graph. * \param directed Logical, whether to create a directed graph. * All edges will be oriented in the same direction along * the cycle or path. * \param mutual Logical, whether to create mutual edges in directed * graphs. It is ignored for undirected graphs. * \param circular Logical, whether to create a closed ring (a cycle) * or an open path. * \return Error code: * \c IGRAPH_EINVAL: invalid number of vertices. * * Time complexity: O(|V|), the number of vertices in the graph. * * \sa \ref igraph_lattice() for generating more general lattices. * * \example examples/simple/igraph_ring.c */ int igraph_ring(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, igraph_bool_t mutual, igraph_bool_t circular) { igraph_vector_t v = IGRAPH_VECTOR_NULL; if (n < 0) { IGRAPH_ERRORF("The number of vertices must be non-negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, n); } IGRAPH_VECTOR_INIT_FINALLY(&v, 1); VECTOR(v)[0] = n; IGRAPH_CHECK(igraph_lattice(graph, &v, 1, directed, mutual, circular)); igraph_vector_destroy(&v); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \ingroup generators * \function igraph_tree * \brief Creates a tree in which almost all vertices have the same number of children. * * To obtain a completely symmetric tree with \c l layers, where each * vertex has precisely \p children descendants, use * n = (children^(l+1) - 1) / (children - 1). * Such trees are often called k-ary trees, where \c k refers * to the number of children. * * * Note that for n=0, the null graph is returned, * which is not considered to be a tree by \ref igraph_is_tree(). * * \param graph Pointer to an uninitialized graph object. * \param n Integer, the number of vertices in the graph. * \param children Integer, the number of children of a vertex in the * tree. * \param type Constant, gives whether to create a directed tree, and * if this is the case, also its orientation. Possible values: * \clist * \cli IGRAPH_TREE_OUT * directed tree, the edges point * from the parents to their children, * \cli IGRAPH_TREE_IN * directed tree, the edges point from * the children to their parents. * \cli IGRAPH_TREE_UNDIRECTED * undirected tree. * \endclist * \return Error code: * \c IGRAPH_EINVAL: invalid number of vertices. * \c IGRAPH_INVMODE: invalid mode argument. * * Time complexity: O(|V|+|E|), the * number of vertices plus the number of edges in the graph. * * \sa \ref igraph_lattice(), \ref igraph_star() for creating other regular * structures; \ref igraph_from_prufer() for creating arbitrary trees; * \ref igraph_tree_game() for uniform random sampling of trees. * * \example examples/simple/igraph_tree.c */ int igraph_tree(igraph_t *graph, igraph_integer_t n, igraph_integer_t children, igraph_tree_mode_t type) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int i, j; long int idx = 0; long int to = 1; if (n < 0) { IGRAPH_ERROR("Number of vertices cannot be negative.", IGRAPH_EINVAL); } if (children <= 0) { IGRAPH_ERROR("Number of children must be positive.", IGRAPH_EINVAL); } if (type != IGRAPH_TREE_OUT && type != IGRAPH_TREE_IN && type != IGRAPH_TREE_UNDIRECTED) { IGRAPH_ERROR("Invalid tree orientation type.", IGRAPH_EINVMODE); } IGRAPH_VECTOR_INIT_FINALLY(&edges, n > 0 ? 2 * (n - 1) : 0); i = 0; if (type == IGRAPH_TREE_OUT) { while (idx < 2 * (n - 1)) { for (j = 0; j < children && idx < 2 * (n - 1); j++) { VECTOR(edges)[idx++] = i; VECTOR(edges)[idx++] = to++; } i++; } } else { while (idx < 2 * (n - 1)) { for (j = 0; j < children && idx < 2 * (n - 1); j++) { VECTOR(edges)[idx++] = to++; VECTOR(edges)[idx++] = i; } i++; } } IGRAPH_CHECK(igraph_create(graph, &edges, n, type != IGRAPH_TREE_UNDIRECTED)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_extended_chordal_ring * \brief Create an extended chordal ring. * * An extended chordal ring is a cycle graph with additional chords * connecting its vertices. * * Each row \c L of the matrix \p W specifies a set of chords to be * inserted, in the following way: vertex \c i will connect to a vertex * L[(i mod p)] steps ahead of it along the cycle, where * \c p is the length of \c L. * In other words, vertex \c i will be connected to vertex * (i + L[(i mod p)]) mod nodes. If multiple edges are * defined in this way, this will output a non-simple graph. The result * can be simplified using \ref igraph_simplify(). * * * See also Kotsis, G: Interconnection Topologies for Parallel Processing * Systems, PARS Mitteilungen 11, 1-6, 1993. The igraph extended chordal * rings are not identical to the ones in the paper. In igraph * the matrix specifies which edges to add. In the paper, a condition is * specified which should simultaneously hold between two endpoints and * the reverse endpoints. * * \param graph Pointer to an uninitialized graph object, the result * will be stored here. * \param nodes Integer constant, the number of vertices in the * graph. It must be at least 3. * \param W The matrix specifying the extra edges. The number of * columns should divide the number of total vertices. The elements * are allowed to be negative. * \param directed Whether the graph should be directed. * \return Error code. * * \sa \ref igraph_ring(), \ref igraph_lcf(), \ref igraph_lcf_vector(). * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges. */ int igraph_extended_chordal_ring( igraph_t *graph, igraph_integer_t nodes, const igraph_matrix_t *W, igraph_bool_t directed) { igraph_vector_t edges; long int period = igraph_matrix_ncol(W); long int nrow = igraph_matrix_nrow(W); long int i, j, mpos = 0, epos = 0; if (nodes < 3) { IGRAPH_ERROR("An extended chordal ring has at least 3 nodes", IGRAPH_EINVAL); } if ((long int)nodes % period != 0) { IGRAPH_ERROR("The period (number of columns in W) should divide the " "number of nodes", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 2 * (nodes + nodes * nrow)); for (i = 0; i < nodes - 1; i++) { VECTOR(edges)[epos++] = i; VECTOR(edges)[epos++] = i + 1; } VECTOR(edges)[epos++] = nodes - 1; VECTOR(edges)[epos++] = 0; if (nrow > 0) { for (i = 0; i < nodes; i++) { for (j = 0; j < nrow; j++) { long int offset = (long int) MATRIX(*W, j, mpos); long int v = (i + offset) % nodes; if (v < 0) { v += nodes; /* handle negative offsets */ } VECTOR(edges)[epos++] = i; VECTOR(edges)[epos++] = v; } mpos++; if (mpos == period) { mpos = 0; } } } IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/constructors/atlas-edges.h0000644000176200001440000027450314447675374021236 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS /* empty */ #define __END_DECLS /* empty */ #endif __BEGIN_DECLS #include "igraph_types.h" const igraph_real_t igraph_i_atlas_edges[] = { 0, 0, 1, 0, 2, 0, 2, 1, 0, 1, 3, 0, 3, 1, 1, 2, 3, 2, 0, 1, 0, 2, 3, 3, 0, 1, 0, 2, 1, 2, 4, 0, 4, 1, 3, 2, 4, 2, 3, 2, 3, 1, 4, 2, 0, 1, 3, 2, 4, 3, 3, 2, 1, 2, 3, 1, 4, 3, 3, 0, 3, 1, 3, 2, 4, 3, 0, 1, 1, 2, 0, 3, 4, 4, 3, 2, 1, 2, 3, 1, 3, 0, 4, 4, 0, 1, 1, 2, 2, 3, 0, 3, 4, 5, 0, 1, 0, 2, 0, 3, 1, 2, 2, 3, 4, 6, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 0, 5, 1, 4, 3, 5, 2, 1, 2, 0, 1, 5, 2, 0, 2, 4, 3, 5, 3, 1, 2, 0, 1, 2, 0, 5, 3, 4, 3, 3, 2, 3, 1, 5, 3, 3, 2, 4, 3, 0, 4, 5, 3, 1, 2, 0, 1, 4, 3, 5, 4, 4, 3, 1, 2, 3, 1, 3, 2, 5, 4, 0, 3, 1, 0, 2, 1, 3, 2, 5, 4, 4, 3, 4, 0, 4, 1, 4, 2, 5, 4, 4, 0, 3, 1, 4, 3, 3, 2, 5, 4, 2, 3, 1, 2, 0, 1, 4, 0, 5, 4, 1, 2, 0, 1, 2, 0, 4, 3, 5, 5, 0, 3, 2, 0, 3, 2, 1, 0, 2, 1, 5, 5, 4, 2, 4, 3, 2, 3, 4, 1, 4, 0, 5, 5, 0, 1, 1, 2, 2, 3, 0, 4, 0, 2, 5, 5, 4, 0, 1, 2, 4, 3, 3, 2, 3, 1, 5, 5, 1, 0, 4, 1, 2, 4, 3, 2, 1, 3, 5, 5, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 6, 1, 0, 4, 1, 4, 0, 0, 3, 1, 3, 3, 4, 5, 6, 1, 0, 4, 1, 2, 4, 3, 2, 1, 3, 2, 1, 5, 6, 1, 0, 4, 1, 2, 4, 3, 2, 1, 3, 3, 4, 5, 6, 0, 1, 4, 3, 2, 3, 4, 2, 4, 0, 4, 1, 5, 6, 0, 4, 3, 0, 4, 3, 2, 3, 1, 2, 0, 1, 5, 6, 2, 1, 0, 2, 3, 0, 1, 3, 4, 1, 0, 4, 5, 7, 4, 0, 1, 2, 4, 3, 3, 2, 3, 1, 4, 1, 2, 4, 5, 7, 4, 1, 2, 4, 3, 2, 1, 3, 3, 4, 0, 3, 4, 0, 5, 7, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 7, 2, 1, 0, 2, 3, 0, 1, 3, 4, 1, 0, 4, 2, 4, 5, 8, 1, 0, 4, 1, 2, 4, 3, 2, 1, 3, 4, 0, 3, 4, 0, 3, 5, 8, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 9, 0, 1, 3, 4, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 5, 10, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4, 6, 0, 6, 1, 5, 4, 6, 2, 0, 3, 5, 4, 6, 2, 1, 3, 1, 2, 6, 3, 1, 3, 2, 1, 3, 2, 6, 3, 0, 3, 5, 0, 4, 0, 6, 3, 4, 3, 5, 4, 0, 5, 6, 3, 4, 3, 5, 1, 5, 2, 6, 3, 1, 2, 3, 0, 5, 4, 6, 4, 0, 3, 4, 0, 5, 4, 0, 5, 6, 4, 3, 0, 5, 3, 4, 5, 0, 4, 6, 4, 5, 1, 5, 3, 5, 2, 0, 5, 6, 4, 4, 3, 3, 1, 4, 0, 3, 2, 6, 4, 0, 2, 1, 3, 2, 1, 5, 3, 6, 4, 1, 3, 2, 1, 3, 2, 0, 5, 6, 4, 1, 2, 0, 3, 5, 0, 4, 0, 6, 4, 4, 5, 1, 2, 0, 5, 3, 4, 6, 4, 0, 2, 4, 0, 3, 1, 5, 3, 6, 5, 3, 0, 5, 3, 4, 5, 0, 4, 5, 0, 6, 5, 5, 3, 3, 1, 3, 2, 4, 3, 4, 5, 6, 5, 5, 3, 5, 4, 2, 3, 3, 4, 0, 4, 6, 5, 4, 3, 1, 2, 4, 0, 3, 2, 3, 1, 6, 5, 1, 4, 3, 4, 4, 0, 2, 1, 3, 2, 6, 5, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 6, 5, 5, 3, 5, 4, 5, 0, 5, 1, 5, 2, 6, 5, 1, 4, 5, 1, 1, 0, 2, 1, 2, 3, 6, 5, 0, 1, 3, 4, 0, 2, 3, 0, 5, 3, 6, 5, 1, 0, 2, 1, 2, 4, 1, 3, 5, 3, 6, 5, 4, 3, 0, 5, 4, 0, 3, 2, 3, 1, 6, 5, 1, 2, 0, 1, 4, 5, 1, 3, 2, 3, 6, 5, 0, 1, 0, 5, 2, 3, 3, 4, 4, 5, 6, 5, 4, 3, 5, 1, 5, 2, 0, 3, 4, 0, 6, 5, 1, 2, 3, 0, 5, 3, 4, 5, 0, 4, 6, 6, 0, 3, 5, 0, 4, 5, 3, 4, 5, 3, 4, 0, 6, 6, 1, 4, 2, 4, 4, 0, 2, 3, 3, 1, 3, 4, 6, 6, 1, 4, 2, 4, 4, 0, 2, 1, 3, 1, 2, 3, 6, 6, 2, 0, 5, 4, 4, 3, 5, 3, 4, 0, 2, 4, 6, 6, 3, 2, 4, 3, 0, 4, 1, 0, 2, 1, 0, 3, 6, 6, 4, 1, 3, 1, 4, 2, 3, 2, 2, 0, 1, 0, 6, 6, 5, 2, 5, 3, 5, 4, 3, 4, 5, 1, 5, 0, 6, 6, 4, 3, 4, 2, 4, 0, 1, 4, 3, 0, 5, 3, 6, 6, 4, 3, 3, 5, 5, 4, 5, 1, 3, 2, 4, 0, 6, 6, 4, 2, 1, 2, 4, 3, 4, 1, 4, 0, 0, 5, 6, 6, 1, 2, 3, 1, 0, 3, 2, 0, 4, 0, 5, 0, 6, 6, 2, 0, 4, 2, 1, 4, 2, 1, 3, 1, 5, 3, 6, 6, 1, 2, 3, 1, 0, 3, 2, 0, 4, 0, 5, 3, 6, 6, 5, 3, 2, 5, 2, 0, 4, 2, 4, 3, 3, 1, 6, 6, 0, 2, 3, 4, 1, 0, 5, 3, 4, 5, 3, 0, 6, 6, 1, 2, 3, 0, 5, 3, 4, 5, 0, 4, 5, 0, 6, 6, 4, 3, 1, 2, 4, 0, 3, 2, 3, 1, 5, 0, 6, 6, 1, 4, 2, 4, 4, 0, 0, 5, 3, 1, 2, 3, 6, 6, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 5, 6, 6, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 6, 1, 3, 2, 1, 3, 2, 0, 4, 5, 0, 4, 5, 6, 7, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 0, 5, 6, 7, 1, 4, 2, 4, 2, 1, 3, 1, 2, 3, 2, 0, 0, 1, 6, 7, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 6, 7, 0, 1, 3, 2, 0, 2, 3, 0, 3, 1, 5, 1, 5, 2, 6, 7, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 3, 4, 6, 7, 1, 0, 4, 1, 2, 4, 3, 2, 5, 1, 2, 5, 1, 2, 6, 7, 0, 4, 2, 0, 1, 2, 3, 1, 5, 3, 3, 0, 2, 3, 6, 7, 1, 4, 2, 4, 2, 3, 2, 1, 3, 1, 4, 5, 0, 4, 6, 7, 1, 0, 4, 1, 2, 4, 3, 2, 5, 1, 2, 5, 4, 5, 6, 7, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 4, 6, 7, 0, 5, 4, 0, 5, 4, 0, 2, 3, 0, 3, 2, 0, 1, 6, 7, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 5, 4, 1, 6, 7, 0, 1, 4, 0, 1, 4, 0, 2, 3, 0, 3, 2, 3, 5, 6, 7, 1, 4, 2, 4, 4, 0, 0, 5, 3, 1, 2, 3, 3, 4, 6, 7, 2, 0, 3, 2, 4, 3, 5, 4, 2, 5, 1, 2, 4, 1, 6, 7, 1, 5, 0, 1, 4, 0, 3, 4, 2, 3, 1, 2, 0, 3, 6, 7, 1, 4, 2, 4, 4, 0, 0, 5, 3, 1, 2, 3, 2, 1, 6, 7, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 0, 2, 5, 1, 6, 7, 2, 0, 4, 1, 1, 2, 5, 4, 2, 5, 3, 1, 5, 3, 6, 7, 5, 0, 3, 5, 2, 3, 0, 2, 1, 3, 4, 1, 3, 4, 6, 7, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 2, 3, 6, 7, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 6, 7, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 6, 7, 1, 2, 0, 1, 2, 0, 3, 0, 4, 3, 5, 4, 3, 5, 6, 8, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 6, 8, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 6, 8, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 0, 0, 4, 6, 8, 1, 2, 3, 1, 0, 3, 1, 0, 2, 0, 3, 2, 5, 3, 4, 0, 6, 8, 0, 1, 2, 4, 0, 2, 5, 2, 3, 1, 3, 2, 2, 1, 4, 1, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 1, 5, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 6, 8, 0, 1, 2, 5, 0, 2, 4, 0, 3, 1, 3, 2, 2, 1, 5, 1, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 0, 6, 8, 0, 1, 2, 5, 0, 2, 4, 0, 3, 1, 3, 2, 3, 0, 5, 1, 6, 8, 2, 0, 3, 2, 4, 3, 5, 4, 2, 5, 1, 2, 4, 1, 5, 3, 6, 8, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 0, 5, 5, 4, 6, 8, 0, 1, 2, 5, 0, 2, 4, 0, 3, 1, 3, 2, 5, 1, 5, 3, 6, 8, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 3, 4, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 2, 0, 2, 6, 8, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 6, 8, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 1, 4, 0, 1, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 6, 8, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 2, 1, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 4, 5, 5, 3, 1, 5, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 1, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 5, 5, 2, 5, 0, 6, 8, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 4, 1, 5, 2, 6, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 6, 9, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 4, 2, 6, 9, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 0, 4, 6, 9, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 4, 5, 6, 9, 2, 0, 4, 1, 1, 2, 5, 4, 2, 5, 3, 1, 5, 3, 3, 2, 4, 3, 6, 9, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 4, 5, 6, 9, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 4, 5, 6, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 3, 0, 6, 9, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 0, 4, 1, 0, 4, 1, 6, 9, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 1, 0, 5, 1, 6, 9, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 4, 4, 0, 5, 0, 6, 9, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 6, 9, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 4, 0, 6, 9, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 6, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 6, 9, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 2, 0, 6, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 4, 5, 2, 5, 3, 6, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 5, 1, 6, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 4, 2, 5, 2, 6, 9, 2, 3, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 1, 0, 5, 2, 6, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 5, 2, 4, 1, 6, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 0, 2, 6, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 4, 5, 6, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 0, 5, 6, 10, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 4, 5, 1, 0, 6, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 3, 5, 1, 5, 6, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 4, 0, 2, 4, 6, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 5, 2, 6, 10, 1, 0, 4, 1, 0, 4, 5, 0, 4, 5, 3, 4, 1, 3, 5, 1, 2, 3, 1, 2, 6, 10, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 5, 2, 6, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 4, 1, 6, 10, 0, 1, 2, 4, 0, 2, 4, 5, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 6, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 6, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 0, 2, 1, 3, 5, 1, 6, 10, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 3, 2, 0, 3, 6, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 5, 3, 2, 5, 1, 0, 6, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 0, 2, 1, 5, 6, 11, 0, 1, 2, 4, 0, 2, 2, 1, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 0, 3, 6, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 0, 4, 5, 6, 11, 0, 1, 1, 2, 2, 3, 4, 5, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 0, 2, 6, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 5, 3, 2, 5, 1, 0, 5, 1, 6, 11, 1, 3, 4, 1, 3, 4, 2, 3, 0, 2, 4, 0, 5, 4, 2, 5, 4, 2, 0, 5, 1, 5, 6, 11, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 0, 3, 1, 4, 0, 1, 6, 11, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 0, 1, 2, 0, 3, 2, 6, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 1, 4, 0, 3, 6, 12, 0, 1, 1, 2, 0, 2, 2, 3, 4, 5, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 4, 3, 6, 12, 3, 2, 1, 3, 2, 1, 0, 2, 5, 0, 2, 5, 2, 4, 5, 1, 0, 3, 1, 4, 0, 1, 0, 4, 6, 12, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 0, 1, 2, 0, 3, 2, 4, 5, 6, 12, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 0, 3, 1, 4, 0, 1, 2, 3, 6, 12, 0, 1, 1, 2, 0, 2, 3, 2, 3, 1, 4, 0, 2, 4, 5, 1, 0, 5, 4, 5, 3, 4, 5, 3, 6, 13, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 0, 3, 1, 4, 0, 1, 2, 3, 0, 4, 6, 13, 0, 1, 1, 2, 0, 2, 3, 2, 3, 1, 4, 0, 2, 4, 5, 1, 0, 5, 4, 5, 3, 4, 5, 3, 3, 0, 6, 14, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 1, 4, 1, 3, 2, 0, 4, 0, 5, 3, 6, 15, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 3, 4, 3, 5, 4, 5, 7, 0, 7, 1, 6, 5, 7, 2, 2, 3, 1, 2, 7, 2, 5, 4, 6, 0, 7, 3, 0, 4, 4, 2, 2, 0, 7, 3, 0, 1, 0, 6, 0, 5, 7, 3, 5, 4, 6, 0, 5, 6, 7, 3, 3, 2, 1, 2, 5, 6, 7, 3, 3, 1, 5, 6, 0, 4, 7, 4, 2, 5, 6, 2, 5, 6, 1, 2, 7, 4, 1, 2, 4, 1, 5, 4, 2, 5, 7, 4, 1, 0, 5, 1, 1, 2, 4, 1, 7, 4, 1, 0, 2, 1, 5, 2, 6, 2, 7, 4, 3, 4, 2, 3, 1, 2, 0, 1, 7, 4, 4, 2, 0, 4, 2, 0, 5, 6, 7, 4, 0, 1, 6, 0, 0, 5, 4, 2, 7, 4, 3, 1, 5, 4, 6, 5, 0, 6, 7, 4, 0, 4, 3, 0, 2, 5, 6, 2, 7, 4, 2, 3, 1, 2, 6, 0, 5, 4, 7, 5, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 7, 5, 2, 5, 6, 2, 5, 6, 4, 2, 3, 2, 7, 5, 4, 2, 4, 0, 2, 0, 5, 4, 6, 0, 7, 5, 2, 5, 6, 2, 5, 6, 1, 2, 0, 1, 7, 5, 4, 1, 0, 4, 3, 0, 1, 3, 2, 1, 7, 5, 1, 2, 0, 1, 4, 0, 3, 4, 2, 3, 7, 5, 5, 1, 5, 0, 2, 5, 3, 5, 4, 5, 7, 5, 1, 5, 6, 1, 1, 0, 2, 1, 3, 2, 7, 5, 1, 5, 4, 1, 2, 3, 6, 2, 2, 1, 7, 5, 1, 5, 6, 1, 1, 2, 2, 3, 4, 3, 7, 5, 2, 1, 3, 2, 4, 3, 5, 4, 3, 6, 7, 5, 6, 5, 2, 6, 1, 2, 5, 2, 3, 4, 7, 5, 4, 3, 5, 4, 6, 5, 0, 6, 1, 0, 7, 5, 0, 4, 3, 0, 2, 5, 6, 2, 5, 6, 7, 5, 4, 1, 5, 2, 6, 5, 3, 6, 2, 3, 7, 5, 1, 4, 3, 1, 1, 0, 2, 1, 6, 5, 7, 5, 0, 4, 3, 0, 1, 0, 2, 1, 6, 5, 7, 5, 0, 4, 3, 0, 2, 1, 5, 2, 6, 2, 7, 5, 6, 5, 3, 4, 2, 3, 1, 2, 0, 1, 7, 5, 2, 3, 1, 2, 6, 0, 5, 6, 5, 4, 7, 5, 0, 1, 4, 6, 5, 4, 3, 2, 6, 5, 7, 6, 1, 5, 6, 1, 5, 6, 2, 5, 1, 2, 6, 2, 7, 6, 1, 4, 3, 1, 2, 3, 4, 2, 1, 0, 2, 1, 7, 6, 0, 4, 3, 0, 1, 3, 2, 1, 1, 4, 3, 4, 7, 6, 5, 2, 4, 5, 2, 4, 3, 2, 6, 3, 2, 6, 7, 6, 1, 2, 4, 1, 5, 4, 2, 5, 0, 1, 4, 0, 7, 6, 1, 2, 5, 1, 4, 5, 2, 4, 0, 2, 5, 0, 7, 6, 2, 5, 6, 2, 5, 6, 2, 4, 1, 2, 3, 2, 7, 6, 1, 4, 3, 1, 2, 3, 1, 2, 2, 5, 6, 2, 7, 6, 5, 4, 6, 5, 1, 6, 5, 1, 3, 6, 0, 1, 7, 6, 6, 5, 1, 6, 5, 1, 3, 1, 0, 3, 1, 4, 7, 6, 0, 4, 3, 0, 2, 3, 4, 2, 2, 5, 6, 2, 7, 6, 1, 4, 3, 1, 2, 3, 1, 2, 2, 5, 6, 5, 7, 6, 2, 3, 1, 2, 3, 6, 5, 4, 6, 5, 5, 2, 7, 6, 2, 5, 6, 2, 5, 6, 1, 4, 3, 1, 2, 1, 7, 6, 4, 5, 0, 4, 3, 0, 2, 3, 4, 2, 6, 3, 7, 6, 0, 4, 3, 0, 1, 3, 6, 5, 1, 4, 1, 0, 7, 6, 1, 4, 3, 1, 2, 3, 5, 2, 6, 5, 2, 6, 7, 6, 6, 3, 5, 6, 4, 5, 1, 4, 2, 1, 5, 2, 7, 6, 1, 0, 3, 1, 6, 3, 5, 6, 4, 5, 1, 4, 7, 6, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 7, 6, 0, 4, 3, 0, 4, 3, 2, 5, 6, 2, 5, 6, 7, 6, 6, 3, 0, 6, 6, 2, 5, 6, 6, 1, 4, 6, 7, 6, 2, 4, 5, 2, 2, 3, 6, 2, 1, 2, 1, 0, 7, 6, 1, 0, 2, 1, 5, 2, 1, 4, 3, 1, 6, 2, 7, 6, 1, 0, 2, 1, 3, 6, 1, 3, 4, 1, 5, 4, 7, 6, 1, 0, 2, 1, 5, 2, 6, 5, 1, 4, 3, 1, 7, 6, 1, 0, 2, 4, 5, 2, 6, 5, 2, 6, 3, 2, 7, 6, 4, 0, 1, 4, 3, 1, 2, 1, 5, 2, 6, 2, 7, 6, 6, 5, 1, 2, 0, 1, 2, 0, 3, 2, 0, 4, 7, 6, 0, 4, 3, 0, 1, 0, 2, 1, 5, 2, 6, 2, 7, 6, 1, 0, 3, 1, 6, 3, 2, 6, 4, 1, 5, 4, 7, 6, 2, 5, 6, 2, 4, 2, 1, 4, 3, 1, 0, 3, 7, 6, 0, 4, 3, 0, 2, 3, 4, 2, 1, 2, 6, 5, 7, 6, 0, 4, 3, 0, 2, 1, 5, 2, 6, 5, 2, 6, 7, 6, 3, 4, 1, 0, 2, 1, 5, 2, 6, 5, 2, 6, 7, 6, 4, 5, 0, 4, 3, 0, 6, 3, 1, 0, 2, 1, 7, 6, 2, 5, 6, 2, 5, 6, 1, 4, 3, 1, 1, 0, 7, 6, 4, 5, 3, 4, 2, 3, 1, 2, 0, 1, 6, 0, 7, 6, 6, 4, 5, 6, 4, 5, 2, 3, 1, 2, 0, 1, 7, 6, 0, 1, 4, 0, 2, 3, 5, 2, 6, 5, 3, 6, 7, 6, 1, 2, 0, 1, 4, 0, 3, 4, 2, 3, 6, 5, 7, 7, 1, 4, 3, 1, 2, 3, 4, 2, 1, 0, 2, 1, 3, 4, 7, 7, 1, 2, 5, 1, 4, 5, 2, 4, 0, 2, 5, 0, 5, 2, 7, 7, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 7, 7, 1, 2, 5, 1, 4, 5, 2, 4, 0, 2, 5, 0, 1, 0, 7, 7, 0, 4, 3, 0, 2, 3, 4, 2, 2, 5, 6, 2, 2, 0, 7, 7, 1, 4, 3, 1, 2, 3, 4, 2, 1, 0, 2, 1, 2, 6, 7, 7, 1, 4, 3, 1, 2, 3, 4, 2, 1, 0, 3, 4, 6, 3, 7, 7, 0, 4, 3, 0, 2, 3, 4, 2, 2, 5, 6, 2, 3, 4, 7, 7, 0, 4, 3, 0, 1, 3, 3, 6, 1, 4, 1, 0, 5, 4, 7, 7, 0, 4, 3, 0, 1, 3, 6, 5, 1, 4, 1, 0, 3, 4, 7, 7, 5, 2, 4, 5, 2, 4, 3, 2, 6, 3, 2, 6, 2, 1, 7, 7, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 0, 2, 2, 5, 7, 7, 5, 2, 4, 5, 2, 4, 3, 2, 6, 3, 2, 6, 3, 1, 7, 7, 1, 4, 3, 1, 2, 3, 4, 2, 2, 0, 2, 1, 6, 0, 7, 7, 1, 2, 5, 1, 4, 5, 2, 4, 0, 2, 5, 0, 3, 5, 7, 7, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 0, 2, 3, 5, 7, 7, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 0, 2, 1, 5, 7, 7, 3, 2, 4, 3, 3, 5, 2, 4, 5, 2, 6, 1, 6, 4, 7, 7, 1, 2, 5, 1, 4, 5, 2, 4, 0, 2, 5, 0, 0, 3, 7, 7, 3, 4, 1, 3, 2, 1, 6, 2, 5, 6, 1, 5, 4, 1, 7, 7, 0, 1, 4, 0, 1, 4, 2, 1, 3, 2, 5, 3, 4, 5, 7, 7, 6, 3, 5, 6, 1, 5, 2, 1, 3, 2, 4, 2, 5, 4, 7, 7, 1, 2, 4, 1, 5, 4, 6, 5, 3, 6, 2, 3, 5, 2, 7, 7, 4, 1, 3, 4, 1, 3, 2, 1, 6, 2, 5, 6, 2, 5, 7, 7, 3, 0, 6, 3, 0, 6, 1, 0, 0, 2, 5, 0, 0, 4, 7, 7, 1, 5, 6, 1, 1, 2, 3, 1, 4, 3, 1, 4, 4, 0, 7, 7, 5, 0, 6, 5, 0, 6, 5, 2, 1, 5, 6, 3, 4, 6, 7, 7, 4, 1, 0, 4, 1, 0, 2, 1, 0, 3, 6, 0, 4, 5, 7, 7, 5, 2, 6, 5, 2, 6, 2, 4, 3, 2, 1, 0, 2, 1, 7, 7, 4, 1, 0, 4, 3, 0, 1, 3, 2, 1, 1, 5, 6, 1, 7, 7, 1, 0, 4, 1, 0, 4, 5, 4, 2, 1, 3, 2, 6, 1, 7, 7, 0, 1, 4, 0, 1, 4, 2, 1, 3, 2, 5, 4, 6, 4, 7, 7, 2, 3, 5, 2, 6, 5, 3, 6, 1, 2, 4, 5, 0, 5, 7, 7, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 2, 1, 6, 5, 7, 7, 2, 5, 6, 2, 5, 6, 4, 2, 1, 2, 0, 1, 3, 1, 7, 7, 2, 5, 6, 2, 4, 2, 1, 4, 3, 1, 2, 3, 0, 1, 7, 7, 6, 2, 5, 6, 2, 5, 1, 2, 0, 1, 4, 1, 3, 1, 7, 7, 0, 4, 3, 0, 1, 3, 4, 1, 5, 4, 2, 1, 6, 3, 7, 7, 2, 5, 6, 2, 5, 6, 4, 5, 3, 6, 1, 2, 0, 1, 7, 7, 2, 5, 6, 2, 1, 4, 1, 2, 0, 1, 4, 0, 0, 3, 7, 7, 6, 5, 1, 2, 4, 1, 0, 4, 3, 0, 1, 3, 3, 4, 7, 7, 4, 1, 0, 4, 1, 0, 3, 6, 2, 3, 0, 2, 5, 0, 7, 7, 4, 1, 0, 4, 3, 0, 1, 3, 2, 1, 5, 2, 6, 1, 7, 7, 4, 1, 0, 4, 1, 0, 2, 3, 0, 2, 5, 0, 6, 5, 7, 7, 0, 1, 5, 0, 6, 5, 3, 6, 2, 3, 0, 2, 4, 0, 7, 7, 1, 0, 4, 1, 2, 4, 3, 2, 4, 3, 0, 4, 6, 5, 7, 7, 3, 6, 2, 3, 1, 2, 0, 1, 4, 0, 1, 4, 5, 4, 7, 7, 1, 0, 5, 1, 6, 5, 2, 6, 1, 2, 3, 2, 4, 3, 7, 7, 2, 3, 1, 2, 0, 1, 4, 0, 5, 4, 6, 5, 4, 1, 7, 7, 5, 2, 6, 5, 2, 6, 1, 2, 4, 1, 0, 4, 3, 1, 7, 7, 2, 3, 1, 2, 0, 1, 4, 0, 5, 4, 6, 5, 5, 2, 7, 7, 1, 4, 0, 1, 2, 0, 3, 2, 5, 3, 0, 5, 6, 3, 7, 7, 2, 1, 3, 2, 6, 3, 5, 6, 0, 5, 2, 0, 5, 4, 7, 7, 5, 2, 6, 5, 2, 6, 1, 2, 0, 1, 4, 0, 3, 0, 7, 7, 4, 1, 0, 4, 3, 0, 1, 3, 2, 1, 5, 2, 6, 2, 7, 7, 1, 0, 2, 1, 5, 2, 4, 5, 0, 4, 4, 1, 6, 3, 7, 7, 2, 5, 6, 2, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 7, 7, 6, 5, 0, 4, 3, 0, 1, 3, 4, 1, 2, 4, 3, 2, 7, 7, 2, 1, 5, 2, 4, 5, 0, 4, 3, 0, 6, 3, 2, 6, 7, 7, 4, 0, 3, 4, 1, 3, 2, 1, 5, 2, 6, 5, 2, 6, 7, 7, 6, 5, 2, 6, 1, 2, 4, 1, 0, 4, 3, 0, 1, 3, 7, 7, 4, 1, 0, 4, 2, 0, 3, 2, 6, 3, 5, 6, 0, 5, 7, 7, 0, 4, 3, 0, 4, 3, 2, 1, 5, 2, 6, 5, 2, 6, 7, 7, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 0, 6, 7, 7, 1, 0, 4, 1, 0, 4, 5, 2, 6, 5, 3, 6, 2, 3, 7, 8, 0, 1, 4, 0, 5, 4, 2, 5, 1, 2, 5, 1, 4, 1, 2, 4, 7, 8, 4, 1, 5, 4, 2, 5, 1, 2, 0, 1, 5, 0, 0, 4, 2, 0, 7, 8, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 3, 4, 5, 1, 6, 1, 7, 8, 4, 1, 5, 4, 2, 5, 1, 2, 5, 1, 6, 5, 2, 4, 3, 2, 7, 8, 1, 3, 0, 1, 4, 0, 2, 4, 1, 2, 4, 1, 5, 4, 1, 5, 7, 8, 2, 0, 3, 2, 6, 3, 5, 6, 0, 5, 3, 0, 0, 6, 4, 0, 7, 8, 1, 0, 2, 1, 5, 2, 4, 5, 0, 4, 2, 0, 5, 0, 6, 5, 7, 8, 1, 0, 2, 1, 3, 2, 1, 3, 4, 3, 2, 4, 5, 2, 3, 5, 7, 8, 2, 0, 3, 2, 6, 3, 5, 6, 0, 5, 3, 0, 6, 0, 4, 5, 7, 8, 1, 0, 2, 1, 4, 3, 1, 5, 4, 1, 2, 4, 5, 2, 3, 5, 7, 8, 3, 5, 2, 1, 4, 3, 1, 5, 4, 1, 2, 4, 5, 2, 4, 6, 7, 8, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 3, 4, 2, 1, 5, 2, 7, 8, 3, 5, 2, 1, 4, 3, 1, 5, 4, 1, 2, 4, 5, 2, 0, 3, 7, 8, 4, 0, 2, 4, 0, 2, 3, 0, 2, 3, 5, 2, 6, 5, 2, 6, 7, 8, 3, 2, 6, 3, 5, 6, 2, 5, 0, 2, 5, 0, 4, 5, 2, 4, 7, 8, 0, 5, 4, 0, 2, 4, 5, 2, 1, 5, 4, 1, 3, 4, 5, 3, 7, 8, 2, 3, 1, 2, 4, 1, 5, 4, 1, 5, 5, 2, 6, 5, 3, 6, 7, 8, 5, 2, 4, 5, 0, 4, 3, 0, 6, 3, 2, 6, 4, 2, 3, 2, 7, 8, 0, 4, 3, 0, 1, 3, 4, 1, 2, 4, 3, 2, 5, 4, 2, 5, 7, 8, 5, 6, 2, 5, 6, 2, 3, 2, 4, 3, 0, 4, 3, 0, 2, 4, 7, 8, 1, 0, 5, 0, 3, 2, 1, 3, 5, 2, 6, 1, 6, 2, 6, 5, 7, 8, 5, 4, 6, 5, 3, 6, 0, 3, 4, 0, 2, 4, 3, 2, 0, 2, 7, 8, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 4, 2, 1, 5, 7, 8, 5, 0, 6, 2, 0, 6, 1, 0, 2, 1, 5, 2, 4, 5, 4, 6, 7, 8, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 2, 1, 1, 5, 6, 1, 7, 8, 0, 2, 4, 0, 1, 4, 0, 1, 3, 0, 1, 3, 5, 1, 6, 1, 7, 8, 4, 2, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 1, 5, 6, 1, 7, 8, 0, 4, 3, 0, 4, 3, 1, 4, 3, 1, 1, 5, 2, 1, 6, 1, 7, 8, 2, 1, 0, 2, 3, 0, 5, 3, 2, 5, 3, 2, 4, 3, 6, 5, 7, 8, 4, 2, 0, 4, 3, 0, 1, 3, 4, 1, 3, 4, 1, 5, 6, 1, 7, 8, 2, 1, 0, 2, 3, 0, 5, 3, 2, 5, 6, 5, 4, 3, 5, 0, 7, 8, 1, 0, 2, 1, 3, 2, 1, 3, 4, 2, 3, 4, 4, 5, 6, 4, 7, 8, 6, 5, 1, 2, 4, 1, 0, 4, 3, 0, 1, 3, 0, 1, 3, 4, 7, 8, 0, 1, 6, 5, 2, 3, 6, 4, 6, 3, 6, 2, 6, 0, 6, 1, 7, 8, 6, 4, 1, 2, 2, 3, 6, 5, 4, 5, 6, 2, 6, 0, 6, 1, 7, 8, 0, 1, 1, 2, 2, 3, 6, 5, 6, 4, 6, 3, 6, 0, 6, 2, 7, 8, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 6, 1, 5, 1, 2, 5, 7, 8, 3, 0, 2, 3, 4, 2, 0, 4, 1, 0, 2, 1, 5, 2, 6, 2, 7, 8, 2, 1, 3, 2, 6, 3, 5, 6, 0, 5, 2, 0, 5, 2, 4, 5, 7, 8, 1, 0, 2, 1, 3, 2, 4, 3, 5, 2, 1, 5, 6, 1, 2, 6, 7, 8, 2, 5, 4, 2, 1, 4, 3, 1, 0, 3, 1, 0, 2, 1, 6, 2, 7, 8, 4, 5, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 6, 3, 7, 8, 0, 1, 4, 0, 1, 4, 2, 1, 4, 2, 5, 4, 1, 5, 6, 3, 7, 8, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 1, 6, 5, 0, 7, 8, 4, 5, 0, 4, 1, 0, 4, 1, 3, 0, 1, 3, 6, 1, 2, 6, 7, 8, 2, 5, 4, 2, 0, 4, 1, 0, 4, 1, 3, 0, 1, 3, 6, 1, 7, 8, 1, 6, 2, 1, 0, 2, 1, 0, 4, 1, 3, 4, 2, 3, 4, 5, 7, 8, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 1, 6, 5, 3, 7, 8, 0, 4, 3, 0, 4, 3, 1, 4, 3, 1, 5, 1, 6, 2, 1, 6, 7, 8, 2, 3, 1, 2, 0, 1, 5, 0, 4, 5, 0, 4, 2, 0, 6, 5, 7, 8, 4, 5, 0, 4, 3, 0, 1, 3, 4, 1, 2, 4, 3, 2, 6, 2, 7, 8, 2, 3, 1, 2, 0, 1, 4, 0, 5, 4, 4, 1, 2, 6, 5, 2, 7, 8, 0, 1, 1, 2, 2, 3, 6, 3, 4, 5, 6, 2, 6, 0, 6, 1, 7, 8, 4, 1, 0, 4, 3, 0, 1, 3, 0, 1, 2, 1, 5, 2, 6, 2, 7, 8, 0, 1, 1, 2, 2, 3, 6, 5, 4, 5, 6, 2, 6, 4, 6, 1, 7, 8, 0, 1, 4, 0, 0, 2, 5, 0, 6, 5, 3, 6, 2, 3, 5, 2, 7, 8, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 2, 5, 6, 2, 7, 8, 4, 5, 3, 4, 1, 3, 2, 1, 6, 2, 4, 6, 3, 2, 0, 1, 7, 8, 1, 0, 2, 6, 3, 2, 4, 3, 5, 2, 1, 5, 6, 1, 6, 5, 7, 8, 2, 3, 1, 2, 0, 1, 4, 0, 5, 4, 6, 5, 5, 2, 4, 1, 7, 8, 4, 1, 0, 4, 3, 0, 1, 3, 3, 4, 2, 1, 2, 5, 6, 2, 7, 8, 0, 6, 4, 0, 1, 4, 3, 1, 0, 3, 2, 4, 3, 2, 5, 2, 7, 8, 0, 4, 3, 0, 1, 3, 4, 1, 2, 4, 3, 2, 1, 0, 6, 5, 7, 8, 0, 1, 4, 0, 3, 2, 6, 3, 5, 6, 2, 5, 6, 2, 3, 5, 7, 8, 5, 2, 6, 5, 2, 6, 4, 2, 0, 4, 3, 0, 2, 3, 1, 2, 7, 8, 2, 0, 1, 2, 0, 1, 5, 0, 4, 5, 0, 4, 6, 0, 3, 6, 7, 8, 0, 1, 2, 0, 3, 2, 2, 1, 1, 4, 5, 4, 5, 3, 1, 6, 7, 8, 1, 6, 2, 1, 0, 2, 1, 0, 4, 1, 3, 4, 2, 3, 5, 6, 7, 8, 6, 1, 0, 6, 1, 0, 5, 1, 0, 5, 2, 1, 3, 2, 4, 3, 7, 8, 6, 5, 2, 6, 1, 2, 4, 1, 3, 4, 0, 3, 4, 0, 2, 4, 7, 8, 1, 6, 0, 1, 5, 0, 1, 5, 3, 0, 4, 3, 2, 4, 0, 2, 7, 8, 2, 6, 4, 2, 0, 4, 1, 0, 4, 1, 3, 4, 5, 3, 2, 5, 7, 8, 1, 0, 2, 1, 6, 2, 5, 6, 1, 5, 4, 1, 3, 4, 2, 3, 7, 8, 6, 1, 4, 3, 1, 0, 5, 1, 3, 2, 2, 1, 4, 6, 5, 4, 7, 8, 4, 2, 0, 4, 1, 0, 4, 1, 3, 4, 6, 3, 5, 6, 3, 5, 7, 8, 4, 1, 2, 4, 0, 2, 6, 0, 3, 6, 0, 3, 5, 0, 4, 5, 7, 8, 5, 6, 4, 5, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 7, 8, 6, 3, 5, 6, 4, 5, 0, 4, 1, 0, 2, 1, 5, 2, 4, 1, 7, 8, 0, 1, 2, 0, 3, 2, 2, 1, 1, 4, 5, 4, 5, 3, 4, 6, 7, 8, 4, 0, 3, 4, 2, 3, 6, 2, 5, 6, 1, 5, 4, 1, 2, 1, 7, 8, 6, 1, 0, 6, 4, 3, 5, 1, 0, 5, 2, 1, 3, 2, 5, 6, 7, 8, 6, 2, 5, 6, 3, 5, 6, 3, 4, 3, 0, 4, 1, 0, 4, 1, 7, 8, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 6, 5, 1, 7, 8, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 6, 4, 2, 7, 8, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 5, 6, 0, 5, 7, 8, 4, 0, 2, 4, 3, 2, 6, 3, 5, 6, 4, 5, 1, 2, 5, 1, 7, 8, 5, 1, 2, 4, 3, 2, 0, 3, 5, 0, 4, 5, 1, 2, 0, 6, 7, 8, 5, 6, 2, 5, 4, 2, 0, 4, 3, 0, 2, 3, 1, 4, 3, 1, 7, 8, 0, 4, 1, 0, 4, 1, 3, 4, 5, 3, 6, 5, 2, 6, 4, 2, 7, 8, 0, 1, 6, 5, 2, 3, 3, 4, 6, 4, 0, 5, 6, 2, 6, 1, 7, 8, 1, 2, 0, 1, 4, 0, 5, 4, 2, 5, 3, 2, 6, 3, 5, 6, 7, 8, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 6, 1, 6, 7, 8, 6, 2, 5, 6, 2, 5, 1, 2, 4, 1, 0, 4, 3, 0, 1, 3, 7, 8, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 5, 6, 1, 7, 8, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 3, 7, 8, 0, 4, 1, 0, 3, 2, 1, 4, 2, 5, 5, 3, 6, 4, 6, 3, 7, 8, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 6, 2, 5, 6, 2, 5, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 7, 9, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 4, 2, 7, 9, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 0, 4, 7, 9, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 4, 5, 7, 9, 2, 0, 4, 1, 1, 2, 5, 4, 2, 5, 3, 1, 5, 3, 3, 2, 4, 3, 7, 9, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 4, 5, 7, 9, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 4, 5, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 3, 0, 7, 9, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 0, 4, 1, 0, 4, 1, 7, 9, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 1, 0, 5, 1, 7, 9, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 4, 4, 0, 5, 0, 7, 9, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 7, 9, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 4, 0, 7, 9, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 7, 9, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 2, 0, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 4, 5, 2, 5, 3, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 5, 1, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 4, 2, 5, 2, 7, 9, 2, 3, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 1, 0, 5, 2, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 5, 2, 4, 1, 7, 9, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 0, 0, 4, 0, 6, 7, 9, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 0, 0, 4, 2, 6, 7, 9, 1, 2, 3, 1, 0, 3, 1, 0, 2, 0, 3, 2, 5, 3, 4, 0, 1, 6, 7, 9, 0, 1, 2, 4, 0, 2, 3, 1, 3, 2, 2, 1, 4, 1, 5, 2, 2, 6, 7, 9, 0, 1, 2, 4, 0, 2, 5, 2, 3, 1, 3, 2, 2, 1, 4, 1, 1, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 1, 5, 1, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 1, 5, 4, 6, 7, 9, 0, 1, 2, 5, 0, 2, 4, 0, 3, 1, 3, 2, 2, 1, 5, 1, 1, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 4, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 3, 6, 7, 9, 0, 1, 2, 5, 0, 2, 4, 0, 3, 1, 3, 2, 2, 1, 5, 1, 0, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 0, 1, 6, 7, 9, 2, 0, 3, 2, 4, 3, 5, 4, 2, 5, 1, 2, 4, 1, 5, 3, 2, 6, 7, 9, 0, 1, 2, 5, 0, 2, 4, 0, 3, 1, 3, 2, 3, 0, 5, 1, 0, 6, 7, 9, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 0, 0, 4, 5, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 0, 4, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 2, 6, 7, 9, 2, 0, 3, 2, 4, 3, 5, 4, 2, 5, 1, 2, 4, 1, 5, 3, 5, 6, 7, 9, 1, 2, 3, 1, 0, 3, 1, 0, 2, 0, 3, 2, 4, 0, 6, 5, 6, 3, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 0, 0, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 6, 5, 4, 0, 3, 2, 4, 7, 9, 0, 1, 2, 5, 0, 2, 4, 0, 3, 1, 3, 2, 2, 1, 5, 1, 5, 6, 7, 9, 2, 0, 3, 2, 4, 3, 5, 4, 2, 5, 1, 2, 4, 1, 5, 3, 4, 6, 7, 9, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 4, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 0, 2, 6, 7, 9, 0, 1, 2, 5, 0, 2, 4, 0, 3, 1, 3, 2, 3, 0, 5, 1, 5, 6, 7, 9, 0, 1, 2, 5, 0, 2, 5, 4, 3, 1, 3, 2, 3, 0, 5, 1, 2, 6, 7, 9, 0, 1, 2, 5, 0, 2, 4, 0, 3, 1, 3, 2, 5, 1, 5, 3, 0, 6, 7, 9, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 0, 5, 5, 4, 5, 6, 7, 9, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 6, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 3, 4, 4, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 2, 0, 2, 0, 6, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 3, 4, 3, 6, 7, 9, 0, 1, 2, 4, 0, 2, 5, 2, 3, 1, 3, 2, 2, 1, 4, 1, 5, 6, 7, 9, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 4, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 2, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 6, 5, 6, 1, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 3, 4, 2, 6, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 3, 4, 0, 6, 7, 9, 1, 3, 2, 1, 0, 2, 5, 0, 6, 5, 3, 6, 1, 6, 0, 1, 1, 4, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 0, 6, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 2, 1, 4, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 5, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 4, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 5, 6, 7, 9, 1, 3, 2, 1, 0, 2, 5, 0, 6, 5, 3, 6, 1, 6, 0, 1, 0, 4, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 2, 0, 2, 1, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 2, 0, 2, 4, 6, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 2, 1, 2, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 3, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 2, 6, 7, 9, 0, 1, 2, 5, 0, 2, 5, 1, 3, 1, 3, 2, 2, 1, 6, 0, 6, 4, 7, 9, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 1, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 0, 5, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 0, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 3, 6, 7, 9, 1, 3, 2, 1, 0, 2, 5, 0, 6, 5, 3, 6, 1, 6, 0, 1, 2, 4, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 4, 5, 5, 3, 1, 5, 3, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 1, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 1, 4, 6, 7, 9, 0, 1, 2, 5, 0, 2, 5, 1, 3, 1, 3, 2, 3, 0, 6, 4, 6, 0, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 5, 5, 2, 5, 0, 1, 6, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 2, 1, 6, 0, 7, 9, 5, 3, 3, 2, 4, 3, 5, 4, 2, 5, 1, 2, 4, 1, 6, 0, 6, 2, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 5, 5, 2, 5, 0, 0, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 4, 5, 5, 3, 1, 5, 5, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 4, 6, 7, 9, 1, 3, 2, 1, 0, 2, 5, 0, 6, 5, 3, 6, 1, 6, 0, 1, 5, 4, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 4, 1, 5, 2, 5, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 4, 5, 5, 3, 1, 5, 1, 6, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 2, 1, 3, 6, 7, 9, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 0, 5, 5, 4, 4, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 4, 5, 5, 3, 1, 5, 0, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 5, 5, 2, 5, 0, 4, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 1, 0, 6, 7, 9, 0, 1, 2, 5, 0, 2, 5, 3, 3, 1, 3, 2, 5, 1, 6, 4, 6, 0, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 4, 1, 5, 2, 0, 6, 7, 9, 6, 3, 1, 2, 6, 5, 3, 4, 6, 4, 0, 5, 6, 0, 6, 1, 6, 2, 7, 9, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 6, 2, 5, 6, 2, 5, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 3, 4, 6, 5, 6, 0, 7, 9, 1, 4, 2, 4, 2, 3, 0, 4, 3, 1, 4, 5, 0, 5, 6, 4, 6, 3, 7, 9, 4, 1, 5, 4, 6, 5, 3, 6, 2, 3, 1, 2, 5, 2, 0, 5, 2, 0, 7, 9, 4, 1, 3, 1, 2, 3, 4, 0, 5, 0, 5, 2, 5, 4, 6, 4, 5, 6, 7, 9, 1, 0, 2, 1, 6, 2, 3, 6, 5, 3, 4, 5, 3, 4, 2, 3, 0, 2, 7, 9, 0, 2, 5, 0, 1, 5, 2, 1, 4, 2, 5, 4, 6, 5, 3, 6, 2, 3, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 0, 6, 1, 3, 4, 1, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 4, 5, 1, 6, 1, 0, 6, 7, 9, 0, 4, 1, 0, 4, 1, 3, 4, 2, 3, 6, 2, 5, 6, 1, 5, 2, 1, 7, 9, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 5, 3, 6, 5, 3, 6, 7, 9, 6, 5, 3, 6, 2, 3, 0, 4, 0, 5, 1, 0, 2, 0, 1, 2, 5, 4, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 3, 5, 1, 6, 1, 0, 6, 7, 9, 5, 2, 6, 5, 3, 6, 2, 3, 0, 2, 4, 0, 5, 4, 1, 5, 0, 1, 7, 9, 2, 4, 1, 2, 4, 1, 5, 4, 0, 5, 1, 0, 6, 4, 3, 6, 2, 3, 7, 9, 6, 2, 5, 6, 2, 5, 1, 2, 0, 1, 4, 0, 1, 4, 3, 1, 0, 3, 7, 9, 0, 5, 6, 0, 1, 6, 4, 1, 2, 4, 3, 2, 1, 3, 5, 1, 6, 5, 7, 9, 6, 5, 3, 6, 2, 3, 5, 2, 0, 5, 1, 0, 4, 1, 0, 4, 2, 0, 7, 9, 0, 4, 3, 0, 1, 3, 4, 1, 2, 4, 6, 2, 5, 6, 2, 5, 3, 2, 7, 9, 1, 0, 4, 1, 5, 4, 0, 5, 6, 0, 3, 6, 2, 3, 0, 2, 3, 4, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 1, 6, 3, 7, 9, 0, 1, 1, 2, 2, 3, 0, 3, 4, 1, 5, 4, 5, 3, 6, 0, 6, 4, 7, 9, 0, 1, 4, 0, 1, 4, 2, 1, 5, 2, 4, 5, 6, 5, 3, 6, 2, 3, 7, 9, 1, 0, 6, 3, 0, 4, 5, 0, 3, 5, 5, 6, 1, 2, 1, 4, 6, 2, 7, 9, 6, 2, 5, 6, 2, 5, 1, 2, 0, 3, 4, 0, 1, 4, 3, 1, 3, 4, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 1, 5, 6, 6, 0, 7, 9, 0, 4, 1, 0, 2, 1, 3, 2, 0, 3, 2, 4, 5, 4, 6, 5, 3, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 4, 2, 6, 1, 5, 6, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 3, 5, 4, 6, 1, 6, 5, 7, 9, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 4, 6, 2, 7, 9, 0, 4, 3, 0, 4, 3, 6, 1, 5, 6, 1, 5, 2, 1, 5, 2, 6, 2, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 0, 2, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 4, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 0, 7, 10, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 4, 5, 1, 0, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 3, 5, 1, 5, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 4, 0, 2, 4, 7, 10, 1, 0, 4, 1, 0, 4, 5, 0, 4, 5, 3, 4, 1, 3, 5, 1, 2, 3, 1, 2, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 5, 2, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 4, 1, 7, 10, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 5, 2, 7, 10, 0, 1, 2, 4, 0, 2, 4, 5, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 0, 2, 1, 3, 5, 1, 7, 10, 0, 1, 1, 2, 3, 4, 0, 2, 3, 0, 2, 4, 5, 2, 1, 5, 4, 1, 3, 5, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 5, 3, 2, 5, 1, 0, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 4, 2, 2, 6, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 4, 2, 1, 6, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 0, 4, 1, 6, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 0, 4, 0, 6, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 0, 4, 3, 6, 7, 10, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 4, 5, 4, 6, 7, 10, 2, 0, 4, 1, 1, 2, 5, 4, 2, 5, 3, 1, 5, 3, 3, 2, 4, 3, 3, 6, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 4, 5, 2, 6, 7, 10, 2, 0, 4, 1, 1, 2, 5, 4, 2, 5, 3, 1, 5, 3, 3, 2, 4, 3, 2, 6, 7, 10, 2, 3, 1, 2, 4, 1, 5, 4, 2, 5, 0, 2, 4, 0, 0, 1, 5, 0, 6, 5, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 0, 4, 5, 6, 7, 10, 2, 0, 4, 1, 1, 2, 5, 4, 2, 5, 3, 1, 5, 3, 3, 2, 4, 3, 4, 6, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 4, 5, 6, 5, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 6, 7, 10, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 4, 5, 6, 5, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 3, 0, 0, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 3, 0, 2, 6, 7, 10, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 4, 5, 1, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 3, 0, 3, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 0, 4, 1, 0, 4, 1, 0, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 1, 0, 5, 1, 1, 6, 7, 10, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 4, 4, 0, 5, 0, 0, 6, 7, 10, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 3, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 3, 0, 5, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 4, 0, 3, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 1, 0, 5, 1, 0, 6, 7, 10, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 2, 0, 5, 3, 2, 3, 6, 2, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 6, 4, 6, 2, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 2, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 1, 0, 5, 1, 5, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 3, 0, 4, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 3, 6, 7, 10, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 4, 4, 0, 5, 0, 2, 6, 7, 10, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 2, 0, 5, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 4, 0, 2, 6, 7, 10, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 2, 0, 5, 3, 2, 3, 0, 6, 7, 10, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 1, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 4, 6, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 6, 4, 6, 0, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 5, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 0, 4, 1, 0, 4, 1, 5, 6, 7, 10, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 2, 0, 0, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 1, 0, 5, 1, 2, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 4, 2, 5, 2, 2, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 4, 5, 2, 5, 3, 5, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 5, 1, 0, 6, 7, 10, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 5, 4, 4, 0, 5, 0, 5, 6, 7, 10, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 6, 5, 6, 4, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 4, 0, 1, 6, 7, 10, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 4, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 4, 5, 2, 5, 3, 4, 6, 7, 10, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 2, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 4, 5, 2, 5, 3, 0, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 4, 2, 5, 2, 5, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 5, 1, 1, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 3, 6, 7, 10, 4, 3, 4, 1, 1, 2, 5, 4, 2, 5, 3, 1, 5, 3, 3, 2, 6, 0, 6, 2, 7, 10, 1, 0, 2, 1, 3, 2, 4, 3, 5, 4, 1, 5, 6, 1, 4, 6, 2, 6, 5, 2, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 4, 2, 5, 2, 0, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 5, 1, 3, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 5, 1, 2, 6, 7, 10, 0, 1, 2, 5, 0, 2, 3, 0, 3, 1, 3, 2, 2, 1, 5, 1, 6, 5, 6, 4, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 1, 6, 7, 10, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 5, 6, 7, 10, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 2, 0, 1, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 4, 5, 2, 5, 3, 1, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 4, 2, 5, 2, 1, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 0, 5, 2, 5, 0, 5, 1, 4, 6, 7, 10, 2, 3, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 1, 0, 5, 2, 4, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 5, 2, 4, 1, 0, 6, 7, 10, 4, 0, 1, 4, 3, 1, 2, 3, 1, 2, 6, 1, 0, 6, 5, 0, 1, 5, 0, 1, 7, 10, 3, 2, 6, 3, 5, 6, 0, 5, 2, 0, 5, 2, 1, 5, 2, 1, 4, 2, 5, 4, 7, 10, 2, 0, 1, 2, 3, 1, 0, 3, 6, 0, 1, 6, 5, 1, 0, 5, 4, 0, 1, 4, 7, 10, 6, 4, 1, 2, 6, 5, 3, 4, 4, 5, 0, 5, 6, 0, 6, 1, 6, 2, 6, 3, 7, 10, 0, 1, 6, 5, 2, 3, 3, 4, 6, 4, 0, 5, 6, 0, 6, 1, 6, 2, 6, 3, 7, 10, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 0, 5, 5, 2, 6, 1, 2, 6, 7, 10, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 5, 0, 5, 2, 6, 2, 0, 6, 7, 10, 6, 4, 1, 2, 6, 5, 3, 4, 4, 5, 0, 5, 6, 3, 6, 1, 6, 2, 0, 4, 7, 10, 1, 0, 2, 1, 0, 2, 3, 2, 4, 3, 2, 4, 5, 2, 4, 5, 6, 4, 1, 6, 7, 10, 0, 1, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 5, 2, 6, 7, 10, 0, 2, 5, 0, 4, 5, 2, 4, 1, 2, 5, 1, 6, 5, 3, 6, 2, 3, 2, 6, 7, 10, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 5, 1, 0, 5, 6, 0, 2, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 2, 6, 4, 0, 2, 4, 0, 7, 10, 0, 4, 3, 0, 2, 3, 5, 2, 6, 5, 2, 6, 4, 2, 1, 4, 3, 1, 4, 3, 7, 10, 1, 6, 2, 1, 0, 2, 1, 0, 4, 1, 3, 4, 2, 3, 5, 6, 4, 5, 3, 1, 7, 10, 6, 5, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 1, 6, 2, 6, 4, 7, 10, 0, 1, 6, 5, 2, 3, 3, 4, 6, 4, 0, 5, 6, 0, 6, 1, 6, 2, 5, 3, 7, 10, 0, 1, 1, 2, 2, 3, 5, 4, 0, 4, 5, 0, 5, 3, 5, 2, 6, 5, 6, 1, 7, 10, 0, 3, 2, 0, 1, 2, 3, 1, 4, 3, 2, 4, 0, 4, 6, 0, 5, 6, 0, 5, 7, 10, 0, 3, 2, 0, 1, 2, 3, 1, 4, 3, 0, 5, 0, 4, 6, 0, 5, 6, 1, 4, 7, 10, 0, 1, 6, 5, 2, 3, 3, 4, 6, 4, 0, 5, 6, 0, 6, 1, 6, 2, 4, 2, 7, 10, 1, 2, 5, 1, 6, 5, 2, 6, 1, 6, 5, 2, 4, 1, 0, 4, 3, 0, 1, 3, 7, 10, 4, 2, 6, 2, 5, 3, 4, 1, 2, 0, 6, 3, 5, 2, 0, 1, 0, 4, 6, 0, 7, 10, 4, 2, 3, 6, 5, 3, 5, 1, 2, 0, 6, 0, 5, 2, 1, 4, 0, 4, 5, 4, 7, 10, 4, 0, 5, 4, 4, 1, 2, 1, 3, 2, 0, 3, 3, 4, 5, 3, 6, 1, 6, 5, 7, 10, 0, 4, 1, 0, 2, 1, 4, 2, 3, 4, 5, 3, 4, 5, 5, 2, 6, 3, 2, 6, 7, 10, 1, 6, 2, 1, 0, 2, 1, 0, 4, 1, 3, 4, 2, 3, 5, 6, 4, 5, 4, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 3, 6, 1, 6, 5, 5, 1, 7, 10, 1, 0, 4, 1, 0, 4, 2, 0, 3, 2, 6, 3, 5, 6, 0, 5, 5, 2, 6, 2, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 3, 5, 1, 5, 4, 6, 1, 5, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 4, 1, 6, 1, 6, 5, 7, 10, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 5, 3, 2, 5, 6, 1, 4, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 2, 5, 4, 6, 5, 6, 0, 0, 2, 7, 10, 2, 0, 5, 2, 1, 5, 0, 1, 3, 0, 5, 3, 6, 5, 4, 6, 0, 4, 4, 3, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 4, 2, 1, 5, 6, 2, 6, 5, 7, 10, 5, 0, 6, 5, 2, 6, 3, 2, 0, 3, 4, 0, 2, 4, 4, 3, 1, 4, 3, 1, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 6, 3, 5, 6, 3, 5, 4, 5, 4, 6, 7, 10, 5, 2, 2, 1, 3, 2, 4, 3, 1, 4, 5, 0, 6, 1, 6, 0, 1, 5, 2, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 2, 6, 4, 4, 2, 5, 1, 7, 10, 4, 2, 2, 3, 4, 1, 0, 1, 3, 0, 6, 4, 0, 6, 5, 0, 4, 5, 1, 5, 7, 10, 2, 1, 5, 2, 3, 5, 0, 3, 4, 0, 6, 4, 3, 6, 1, 3, 4, 1, 5, 4, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 1, 5, 2, 6, 5, 6, 3, 7, 10, 0, 1, 4, 0, 1, 4, 2, 1, 5, 2, 4, 5, 6, 5, 3, 6, 2, 3, 5, 3, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 5, 6, 1, 6, 2, 4, 2, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 3, 5, 2, 6, 5, 6, 4, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 3, 6, 2, 4, 0, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 4, 6, 5, 6, 3, 7, 10, 0, 5, 6, 0, 1, 6, 0, 1, 1, 5, 2, 1, 3, 2, 4, 3, 6, 4, 4, 5, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 5, 6, 4, 2, 0, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 1, 6, 5, 6, 3, 7, 10, 2, 1, 2, 0, 3, 2, 4, 3, 1, 4, 5, 1, 5, 0, 6, 0, 1, 6, 6, 5, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 3, 5, 1, 6, 1, 6, 4, 6, 5, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 5, 2, 4, 1, 6, 0, 5, 6, 7, 10, 3, 1, 0, 3, 5, 0, 1, 5, 2, 1, 6, 2, 0, 6, 0, 4, 4, 2, 4, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 4, 6, 1, 6, 2, 6, 5, 7, 10, 0, 3, 2, 0, 1, 2, 3, 1, 4, 3, 2, 4, 5, 4, 5, 0, 6, 4, 6, 1, 7, 10, 0, 1, 6, 5, 2, 3, 3, 4, 6, 4, 0, 5, 6, 2, 6, 1, 4, 2, 5, 1, 7, 10, 5, 2, 6, 5, 2, 6, 4, 2, 0, 4, 3, 0, 2, 3, 1, 0, 1, 3, 4, 1, 7, 10, 3, 4, 1, 3, 4, 1, 0, 4, 3, 0, 1, 0, 2, 1, 5, 2, 6, 5, 2, 6, 7, 10, 5, 6, 2, 5, 6, 2, 3, 6, 0, 3, 4, 0, 5, 4, 1, 4, 3, 1, 2, 1, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 1, 6, 5, 4, 2, 7, 10, 1, 0, 2, 1, 3, 2, 0, 3, 5, 0, 1, 5, 4, 5, 6, 4, 3, 6, 2, 6, 7, 10, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 4, 1, 2, 5, 6, 0, 3, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 0, 2, 1, 5, 7, 11, 0, 1, 2, 4, 0, 2, 2, 1, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 0, 3, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 0, 4, 5, 7, 11, 0, 1, 1, 2, 2, 3, 4, 5, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 0, 2, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 3, 2, 5, 1, 0, 4, 1, 5, 1, 7, 11, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 4, 6, 5, 6, 7, 11, 3, 6, 1, 3, 2, 1, 0, 2, 5, 0, 6, 5, 2, 6, 5, 1, 0, 3, 1, 6, 0, 1, 7, 11, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 0, 1, 2, 0, 3, 2, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 1, 4, 0, 3, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 4, 6, 4, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 6, 4, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 2, 4, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 2, 5, 6, 2, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 2, 0, 6, 7, 11, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4, 6, 5, 7, 11, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 4, 5, 1, 0, 4, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 3, 5, 1, 5, 1, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 3, 5, 1, 5, 6, 4, 7, 11, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 4, 5, 1, 0, 1, 6, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 4, 0, 2, 4, 2, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 3, 5, 1, 5, 5, 6, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 5, 2, 2, 6, 7, 11, 1, 0, 4, 1, 0, 4, 5, 0, 4, 5, 3, 4, 1, 3, 5, 1, 2, 3, 1, 2, 6, 1, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 5, 2, 3, 6, 7, 11, 1, 0, 4, 1, 0, 4, 5, 0, 4, 5, 3, 4, 1, 3, 5, 1, 2, 3, 1, 2, 6, 4, 7, 11, 0, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 11, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 5, 2, 0, 6, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 5, 2, 0, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 4, 1, 1, 6, 7, 11, 1, 0, 4, 1, 0, 4, 5, 0, 4, 5, 3, 4, 1, 3, 5, 1, 2, 3, 1, 2, 5, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 5, 4, 3, 5, 1, 5, 0, 6, 7, 11, 0, 1, 2, 4, 0, 2, 4, 5, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 2, 6, 7, 11, 1, 0, 4, 1, 0, 4, 5, 0, 4, 5, 3, 4, 1, 3, 5, 1, 2, 3, 1, 2, 3, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 4, 1, 2, 6, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 5, 2, 5, 6, 7, 11, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 5, 2, 5, 6, 7, 11, 0, 1, 2, 4, 0, 2, 4, 5, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 5, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 4, 5, 6, 7, 11, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 5, 2, 1, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 4, 1, 4, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 4, 1, 5, 6, 7, 11, 0, 1, 2, 4, 0, 2, 4, 5, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 4, 6, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 4, 0, 2, 4, 1, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 6, 5, 6, 2, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 5, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 0, 2, 1, 3, 5, 1, 1, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 1, 6, 7, 11, 1, 0, 4, 1, 0, 4, 5, 0, 4, 5, 3, 4, 1, 3, 5, 1, 2, 3, 1, 2, 2, 6, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 3, 2, 0, 3, 2, 4, 5, 2, 1, 6, 7, 11, 0, 6, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 5, 6, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 5, 3, 2, 5, 1, 0, 1, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 0, 2, 1, 3, 5, 1, 5, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 0, 2, 1, 3, 5, 1, 6, 3, 7, 11, 4, 3, 0, 4, 1, 0, 2, 1, 3, 2, 0, 5, 5, 3, 0, 3, 1, 5, 5, 2, 4, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 5, 0, 5, 2, 0, 5, 1, 4, 1, 6, 3, 7, 11, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 3, 2, 0, 3, 1, 6, 7, 11, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 5, 3, 2, 5, 1, 0, 6, 2, 7, 11, 0, 1, 2, 4, 0, 2, 4, 5, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 0, 6, 7, 11, 0, 6, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 7, 11, 6, 5, 0, 6, 5, 0, 1, 5, 6, 1, 2, 6, 5, 2, 3, 5, 6, 3, 4, 6, 5, 4, 7, 11, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 5, 1, 2, 5, 6, 2, 1, 6, 3, 1, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 1, 3, 5, 6, 1, 4, 6, 1, 4, 3, 1, 7, 11, 1, 4, 2, 3, 4, 2, 0, 6, 4, 5, 6, 5, 3, 1, 6, 4, 3, 0, 3, 6, 4, 3, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 4, 2, 6, 4, 2, 6, 5, 2, 0, 2, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 4, 0, 3, 0, 2, 0, 6, 0, 3, 6, 7, 11, 0, 1, 2, 0, 5, 2, 6, 5, 2, 6, 1, 2, 4, 1, 2, 4, 3, 2, 4, 3, 3, 1, 7, 11, 4, 5, 1, 4, 2, 1, 3, 2, 6, 3, 5, 6, 2, 5, 4, 2, 3, 5, 0, 5, 2, 0, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 4, 2, 5, 2, 5, 0, 6, 2, 4, 6, 5, 4, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 6, 1, 2, 6, 0, 2, 6, 0, 5, 2, 0, 5, 7, 11, 0, 5, 6, 0, 1, 6, 5, 1, 2, 5, 6, 2, 4, 3, 3, 2, 4, 5, 6, 4, 6, 5, 7, 11, 0, 5, 6, 0, 1, 6, 5, 1, 2, 5, 6, 2, 3, 6, 5, 3, 4, 5, 6, 4, 4, 3, 7, 11, 0, 5, 0, 6, 1, 2, 1, 6, 2, 4, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 0, 2, 2, 4, 5, 2, 4, 5, 6, 5, 6, 0, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 0, 6, 4, 2, 0, 4, 2, 0, 6, 4, 7, 11, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 5, 1, 5, 2, 6, 1, 2, 6, 4, 2, 5, 4, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 5, 1, 2, 5, 4, 2, 6, 2, 4, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 4, 6, 2, 0, 2, 4, 0, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 3, 1, 5, 3, 4, 5, 1, 4, 6, 5, 6, 1, 7, 11, 0, 4, 3, 0, 4, 3, 2, 4, 3, 2, 1, 3, 2, 1, 4, 1, 5, 2, 6, 5, 2, 6, 7, 11, 0, 5, 0, 6, 1, 4, 1, 6, 2, 3, 2, 5, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 11, 0, 1, 4, 0, 5, 4, 6, 5, 3, 6, 2, 3, 1, 2, 4, 1, 2, 4, 5, 2, 1, 5, 7, 11, 0, 4, 3, 0, 4, 3, 2, 4, 6, 2, 1, 6, 5, 1, 2, 5, 3, 2, 1, 3, 4, 1, 7, 11, 0, 1, 6, 5, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 7, 11, 4, 1, 0, 4, 1, 0, 3, 1, 0, 3, 5, 1, 6, 5, 1, 6, 2, 1, 5, 2, 6, 2, 7, 11, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 4, 6, 5, 4, 6, 7, 11, 1, 0, 2, 1, 3, 2, 4, 3, 0, 4, 2, 0, 5, 2, 6, 5, 3, 6, 6, 0, 0, 5, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 2, 4, 0, 6, 4, 0, 6, 3, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 2, 0, 5, 2, 6, 5, 4, 6, 0, 5, 6, 0, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 2, 6, 3, 6, 0, 3, 4, 0, 7, 11, 4, 6, 5, 4, 6, 5, 3, 6, 5, 3, 2, 5, 3, 2, 5, 0, 6, 0, 1, 0, 2, 1, 7, 11, 2, 0, 4, 2, 5, 4, 3, 5, 1, 3, 0, 1, 2, 1, 3, 2, 6, 3, 5, 6, 4, 3, 7, 11, 4, 3, 4, 2, 1, 4, 3, 1, 0, 3, 1, 0, 3, 2, 3, 5, 2, 5, 6, 0, 4, 6, 7, 11, 0, 1, 0, 2, 2, 3, 5, 1, 1, 3, 5, 2, 6, 3, 6, 0, 5, 3, 4, 5, 3, 4, 7, 11, 4, 0, 1, 4, 6, 1, 0, 6, 3, 0, 1, 3, 5, 1, 0, 5, 6, 5, 2, 3, 0, 2, 7, 11, 0, 1, 5, 0, 4, 5, 1, 4, 2, 1, 3, 2, 4, 3, 4, 2, 6, 4, 2, 6, 3, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 5, 1, 3, 5, 6, 3, 4, 6, 5, 6, 7, 11, 6, 3, 5, 6, 2, 5, 3, 2, 5, 3, 4, 5, 2, 4, 1, 2, 5, 1, 0, 1, 4, 0, 7, 11, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 1, 6, 5, 4, 6, 7, 11, 0, 4, 3, 0, 2, 3, 5, 2, 6, 5, 2, 6, 4, 2, 1, 4, 3, 1, 1, 0, 2, 1, 7, 11, 5, 0, 0, 1, 3, 0, 5, 3, 2, 5, 6, 2, 4, 6, 5, 4, 1, 5, 6, 1, 3, 6, 7, 11, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 2, 1, 5, 1, 2, 5, 6, 4, 6, 2, 3, 6, 7, 11, 3, 2, 6, 3, 5, 6, 0, 5, 2, 0, 1, 2, 0, 1, 5, 1, 2, 5, 4, 2, 6, 4, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 4, 1, 5, 3, 5, 1, 6, 4, 6, 5, 3, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 3, 6, 0, 6, 2, 6, 3, 5, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 5, 1, 6, 5, 4, 6, 3, 6, 1, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 5, 1, 6, 5, 1, 6, 2, 6, 4, 2, 7, 11, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 3, 4, 2, 6, 1, 6, 4, 5, 2, 3, 5, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 5, 1, 6, 1, 4, 6, 6, 5, 2, 6, 7, 11, 0, 3, 0, 6, 1, 2, 1, 5, 2, 4, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 11, 5, 1, 6, 5, 4, 6, 3, 4, 2, 3, 0, 2, 1, 0, 5, 0, 6, 0, 2, 6, 4, 2, 7, 11, 1, 0, 2, 1, 3, 2, 4, 3, 0, 4, 5, 2, 3, 5, 6, 0, 6, 5, 6, 2, 3, 6, 7, 11, 0, 3, 4, 0, 2, 4, 3, 2, 1, 3, 4, 1, 5, 1, 6, 0, 6, 1, 5, 3, 4, 5, 7, 11, 0, 5, 0, 6, 1, 3, 1, 4, 2, 3, 2, 5, 2, 6, 3, 4, 4, 5, 4, 6, 5, 6, 7, 11, 0, 2, 1, 0, 2, 1, 0, 3, 3, 1, 5, 4, 5, 3, 6, 4, 6, 2, 6, 0, 1, 6, 7, 11, 4, 1, 5, 4, 2, 5, 1, 2, 0, 1, 5, 0, 6, 5, 3, 6, 2, 3, 0, 2, 4, 0, 7, 11, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 6, 1, 6, 2, 5, 1, 3, 5, 5, 2, 4, 5, 7, 11, 0, 5, 0, 6, 1, 4, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 3, 6, 4, 6, 2, 2, 0, 4, 0, 7, 11, 0, 2, 1, 0, 2, 1, 0, 3, 3, 1, 5, 4, 5, 3, 6, 4, 6, 2, 4, 0, 1, 4, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 1, 5, 2, 6, 2, 0, 6, 1, 6, 7, 11, 0, 3, 4, 0, 1, 4, 3, 1, 4, 3, 0, 1, 2, 4, 6, 2, 5, 6, 2, 5, 1, 2, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 4, 5, 2, 5, 3, 6, 1, 6, 5, 7, 11, 4, 1, 5, 4, 2, 5, 1, 2, 0, 1, 4, 0, 5, 0, 6, 5, 3, 6, 2, 3, 5, 3, 7, 11, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 3, 4, 2, 5, 1, 5, 4, 6, 5, 4, 6, 7, 11, 0, 1, 1, 2, 2, 3, 5, 4, 0, 4, 5, 0, 5, 1, 5, 2, 5, 3, 6, 3, 6, 4, 7, 11, 0, 4, 3, 0, 1, 3, 4, 1, 3, 4, 5, 1, 6, 5, 1, 6, 2, 1, 5, 2, 6, 2, 7, 11, 4, 1, 0, 4, 3, 0, 2, 5, 5, 4, 6, 5, 2, 6, 1, 2, 3, 1, 6, 3, 2, 3, 7, 11, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 2, 5, 4, 5, 3, 6, 0, 6, 5, 3, 6, 7, 11, 5, 2, 2, 4, 5, 3, 4, 1, 5, 4, 0, 1, 3, 0, 0, 2, 6, 2, 6, 3, 0, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 4, 5, 2, 5, 3, 6, 1, 0, 6, 7, 11, 0, 3, 0, 4, 1, 2, 1, 5, 1, 6, 2, 4, 2, 6, 3, 5, 3, 6, 4, 5, 5, 6, 7, 11, 4, 0, 3, 4, 5, 3, 0, 5, 1, 0, 2, 1, 3, 2, 4, 1, 5, 2, 6, 4, 5, 6, 7, 11, 2, 3, 4, 2, 0, 4, 5, 0, 1, 5, 4, 1, 3, 4, 5, 3, 1, 0, 6, 5, 6, 2, 7, 11, 4, 1, 0, 4, 3, 0, 4, 3, 5, 4, 6, 5, 2, 6, 1, 2, 3, 1, 6, 3, 2, 5, 7, 11, 0, 3, 4, 0, 2, 4, 3, 2, 1, 3, 0, 1, 6, 0, 5, 6, 2, 5, 1, 5, 4, 1, 7, 11, 0, 3, 0, 4, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 6, 4, 5, 5, 6, 7, 11, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 3, 4, 2, 5, 1, 5, 4, 6, 1, 5, 6, 7, 11, 4, 1, 5, 4, 6, 5, 3, 6, 2, 3, 1, 2, 0, 1, 5, 0, 4, 0, 5, 2, 6, 2, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 4, 2, 3, 5, 4, 5, 3, 0, 6, 5, 6, 1, 7, 11, 0, 4, 1, 0, 4, 1, 3, 4, 2, 3, 1, 2, 6, 1, 5, 6, 3, 5, 5, 4, 2, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 5, 1, 4, 2, 6, 2, 3, 6, 4, 6, 7, 11, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 2, 1, 6, 5, 2, 4, 1, 0, 3, 7, 11, 0, 3, 0, 4, 1, 2, 1, 5, 1, 6, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 7, 11, 0, 1, 1, 2, 2, 3, 5, 4, 0, 4, 5, 3, 5, 1, 6, 3, 6, 4, 4, 2, 0, 3, 7, 11, 0, 4, 0, 5, 0, 6, 1, 3, 1, 5, 1, 6, 2, 3, 2, 4, 2, 6, 3, 6, 4, 5, 7, 11, 4, 3, 2, 4, 3, 2, 0, 3, 2, 1, 5, 4, 5, 0, 6, 4, 6, 1, 1, 5, 0, 6, 7, 11, 6, 4, 3, 6, 1, 3, 4, 1, 0, 4, 2, 0, 3, 2, 0, 1, 5, 0, 6, 5, 5, 2, 7, 11, 6, 1, 2, 6, 1, 2, 0, 1, 3, 0, 4, 3, 5, 4, 3, 5, 2, 0, 4, 0, 5, 6, 7, 12, 0, 1, 1, 2, 2, 3, 4, 5, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 4, 3, 0, 2, 7, 12, 3, 6, 1, 3, 2, 1, 0, 2, 5, 0, 6, 5, 2, 6, 5, 1, 0, 3, 1, 6, 0, 1, 0, 6, 7, 12, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 3, 2, 5, 1, 0, 4, 1, 5, 1, 2, 4, 7, 12, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 0, 3, 1, 4, 0, 1, 2, 3, 7, 12, 0, 1, 1, 2, 0, 2, 3, 2, 3, 1, 4, 0, 2, 4, 5, 1, 0, 5, 4, 5, 3, 4, 5, 3, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 0, 2, 1, 5, 6, 1, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 0, 2, 4, 6, 5, 3, 7, 12, 0, 1, 2, 4, 0, 2, 2, 1, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 0, 3, 1, 6, 7, 12, 0, 1, 2, 4, 0, 2, 2, 1, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 0, 3, 3, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 0, 4, 5, 4, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 0, 4, 5, 6, 1, 7, 12, 0, 1, 2, 4, 0, 2, 2, 1, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 0, 3, 0, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 0, 4, 5, 0, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 0, 4, 5, 2, 6, 7, 12, 0, 1, 1, 2, 2, 3, 4, 5, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 0, 2, 1, 6, 7, 12, 0, 1, 1, 2, 2, 3, 4, 5, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 0, 2, 4, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 0, 2, 6, 1, 6, 5, 7, 12, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 1, 5, 3, 2, 5, 1, 0, 4, 1, 1, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 3, 5, 0, 3, 5, 6, 7, 12, 3, 6, 1, 3, 2, 1, 0, 2, 5, 0, 6, 5, 2, 6, 5, 1, 0, 3, 1, 6, 0, 1, 1, 4, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 3, 5, 0, 3, 3, 6, 7, 12, 0, 1, 2, 4, 0, 2, 2, 1, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 0, 3, 4, 6, 7, 12, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 1, 5, 3, 2, 5, 1, 0, 4, 1, 2, 6, 7, 12, 3, 6, 1, 3, 2, 1, 0, 2, 5, 0, 6, 5, 2, 6, 5, 1, 0, 3, 1, 6, 0, 1, 0, 4, 7, 12, 1, 3, 4, 1, 3, 4, 2, 3, 0, 2, 4, 0, 5, 4, 2, 5, 4, 2, 0, 5, 1, 5, 3, 6, 7, 12, 1, 3, 4, 1, 3, 4, 2, 3, 0, 2, 4, 0, 5, 4, 2, 5, 4, 2, 0, 5, 1, 5, 0, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 0, 4, 5, 5, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 1, 4, 0, 3, 5, 6, 7, 12, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 0, 1, 2, 0, 3, 2, 4, 6, 7, 12, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 0, 1, 2, 0, 3, 2, 0, 6, 7, 12, 3, 6, 1, 3, 2, 1, 0, 2, 5, 0, 6, 5, 2, 6, 5, 1, 0, 3, 1, 6, 0, 1, 4, 5, 7, 12, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 0, 1, 2, 0, 3, 2, 3, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 1, 4, 0, 3, 0, 6, 7, 12, 0, 1, 1, 2, 2, 3, 4, 5, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 0, 2, 5, 6, 7, 12, 0, 3, 6, 0, 5, 6, 3, 5, 1, 3, 6, 1, 4, 6, 3, 4, 2, 3, 6, 2, 3, 6, 5, 4, 7, 12, 0, 1, 4, 0, 5, 4, 1, 5, 4, 1, 2, 4, 1, 2, 6, 1, 4, 6, 2, 6, 3, 2, 4, 3, 7, 12, 4, 1, 3, 2, 3, 0, 4, 2, 5, 1, 5, 0, 3, 5, 4, 3, 5, 4, 6, 5, 3, 6, 4, 6, 7, 12, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 4, 2, 3, 4, 5, 3, 0, 5, 6, 3, 1, 6, 7, 12, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 6, 3, 0, 6, 5, 0, 1, 5, 4, 1, 2, 4, 7, 12, 6, 2, 5, 6, 3, 5, 2, 3, 1, 2, 4, 1, 5, 4, 2, 5, 4, 2, 0, 4, 1, 0, 5, 1, 7, 12, 5, 4, 6, 5, 3, 6, 4, 3, 0, 4, 3, 0, 1, 3, 0, 1, 4, 1, 3, 5, 2, 3, 4, 2, 7, 12, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 1, 0, 2, 1, 5, 0, 1, 5, 6, 1, 0, 6, 7, 12, 1, 2, 0, 1, 2, 0, 3, 2, 0, 3, 1, 3, 4, 2, 0, 4, 5, 4, 2, 5, 6, 2, 1, 6, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 2, 4, 5, 6, 4, 3, 6, 7, 12, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 1, 0, 2, 1, 5, 0, 1, 5, 6, 1, 2, 6, 7, 12, 1, 2, 0, 1, 2, 0, 3, 2, 0, 3, 1, 3, 4, 2, 0, 4, 6, 4, 2, 6, 5, 2, 4, 5, 7, 12, 1, 0, 2, 1, 0, 2, 3, 0, 4, 3, 0, 4, 5, 0, 3, 5, 4, 5, 6, 4, 3, 6, 6, 0, 7, 12, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 4, 1, 0, 4, 5, 0, 2, 5, 6, 5, 2, 6, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 6, 4, 0, 6, 5, 0, 3, 5, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 1, 5, 6, 1, 0, 6, 5, 0, 4, 5, 7, 12, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 1, 0, 2, 1, 6, 1, 0, 6, 5, 0, 2, 5, 7, 12, 5, 4, 3, 5, 4, 3, 6, 4, 3, 6, 2, 3, 4, 2, 0, 4, 3, 0, 1, 0, 2, 1, 6, 2, 7, 12, 4, 1, 3, 2, 3, 0, 4, 2, 5, 1, 5, 0, 3, 5, 4, 3, 5, 4, 6, 5, 0, 6, 3, 6, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 6, 1, 0, 6, 5, 0, 1, 5, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 3, 1, 5, 1, 6, 5, 4, 6, 7, 12, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 1, 0, 2, 1, 5, 4, 3, 5, 6, 3, 4, 6, 7, 12, 1, 0, 2, 1, 3, 2, 0, 3, 4, 3, 1, 4, 4, 0, 5, 4, 0, 5, 3, 5, 6, 0, 1, 6, 7, 12, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 1, 0, 2, 1, 6, 2, 4, 6, 5, 0, 1, 5, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 5, 4, 2, 5, 1, 5, 6, 1, 5, 6, 7, 12, 0, 2, 1, 0, 2, 1, 0, 3, 3, 1, 4, 2, 5, 3, 6, 1, 6, 4, 4, 0, 3, 4, 1, 5, 7, 12, 0, 1, 1, 2, 0, 2, 3, 0, 3, 2, 4, 3, 4, 1, 0, 4, 5, 2, 5, 4, 6, 0, 3, 6, 7, 12, 5, 0, 2, 5, 6, 2, 3, 6, 2, 3, 1, 2, 0, 1, 4, 0, 1, 4, 5, 1, 6, 5, 0, 2, 7, 12, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 1, 0, 2, 1, 6, 4, 2, 6, 5, 2, 3, 5, 7, 12, 0, 2, 1, 0, 5, 1, 3, 5, 6, 3, 2, 6, 4, 2, 3, 4, 5, 4, 2, 5, 1, 2, 4, 1, 7, 12, 0, 2, 1, 0, 2, 1, 0, 3, 3, 1, 4, 0, 1, 4, 4, 2, 3, 4, 5, 4, 6, 5, 3, 6, 7, 12, 0, 1, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 6, 1, 2, 6, 4, 6, 3, 4, 5, 3, 6, 5, 7, 12, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 1, 0, 2, 1, 5, 0, 6, 5, 0, 6, 3, 4, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 1, 2, 5, 6, 0, 3, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 3, 5, 1, 5, 4, 6, 3, 4, 6, 1, 6, 6, 5, 7, 12, 0, 5, 0, 6, 1, 3, 1, 4, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 2, 6, 5, 0, 6, 6, 2, 0, 5, 1, 5, 6, 1, 7, 12, 0, 1, 6, 5, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 5, 1, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 6, 1, 5, 6, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 1, 4, 5, 6, 4, 5, 6, 7, 12, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 1, 5, 3, 2, 5, 1, 0, 4, 1, 6, 3, 6, 1, 7, 12, 0, 4, 0, 6, 1, 3, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 5, 4, 5, 4, 6, 5, 6, 7, 12, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 5, 6, 7, 12, 0, 1, 2, 4, 0, 2, 2, 1, 4, 6, 4, 1, 5, 1, 5, 2, 5, 3, 0, 3, 6, 1, 2, 6, 7, 12, 0, 1, 1, 2, 2, 3, 5, 4, 0, 4, 5, 3, 5, 1, 6, 3, 6, 4, 4, 2, 0, 3, 4, 3, 7, 12, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 3, 2, 5, 1, 0, 4, 1, 6, 1, 6, 5, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 1, 6, 5, 0, 6, 1, 6, 7, 12, 0, 3, 4, 0, 2, 4, 3, 2, 1, 3, 4, 1, 1, 0, 5, 1, 5, 2, 6, 1, 2, 6, 4, 6, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 2, 5, 0, 5, 4, 4, 1, 1, 6, 5, 3, 1, 5, 6, 2, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 2, 5, 0, 5, 4, 4, 1, 1, 5, 5, 3, 6, 1, 4, 6, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 2, 5, 0, 5, 4, 4, 1, 1, 5, 5, 3, 6, 1, 0, 6, 7, 12, 4, 3, 1, 2, 0, 1, 0, 3, 4, 0, 6, 4, 4, 2, 5, 4, 6, 2, 6, 3, 3, 2, 5, 1, 7, 12, 2, 3, 4, 2, 0, 4, 6, 0, 6, 5, 4, 5, 1, 3, 5, 1, 0, 5, 6, 1, 3, 6, 5, 3, 7, 12, 0, 3, 0, 5, 1, 2, 1, 5, 1, 6, 2, 4, 2, 6, 3, 4, 3, 6, 4, 5, 4, 6, 5, 6, 7, 12, 0, 3, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 12, 0, 1, 1, 2, 2, 3, 4, 5, 0, 4, 4, 3, 5, 3, 6, 1, 3, 6, 6, 2, 0, 6, 4, 6, 7, 12, 0, 1, 2, 4, 0, 2, 6, 1, 3, 1, 3, 2, 4, 1, 5, 1, 5, 2, 5, 3, 0, 3, 4, 6, 7, 12, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 3, 2, 5, 1, 0, 4, 1, 6, 3, 1, 6, 7, 12, 4, 3, 1, 2, 5, 0, 0, 3, 4, 0, 4, 1, 4, 2, 5, 1, 6, 2, 6, 3, 3, 2, 6, 4, 7, 12, 2, 3, 4, 2, 5, 4, 0, 5, 6, 0, 1, 6, 3, 1, 6, 3, 5, 3, 1, 5, 4, 0, 3, 0, 7, 12, 0, 3, 0, 5, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 6, 4, 6, 5, 6, 7, 12, 3, 2, 1, 2, 5, 0, 0, 3, 4, 0, 4, 1, 6, 4, 5, 1, 6, 2, 6, 3, 6, 1, 0, 6, 7, 12, 0, 5, 0, 6, 1, 3, 1, 4, 1, 6, 2, 3, 2, 4, 2, 6, 3, 5, 4, 5, 4, 6, 5, 6, 7, 12, 0, 3, 0, 5, 1, 2, 1, 4, 1, 6, 2, 4, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 12, 0, 3, 0, 6, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 4, 6, 5, 6, 7, 12, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 6, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 2, 5, 0, 5, 4, 4, 1, 3, 4, 5, 3, 2, 6, 6, 1, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 2, 5, 0, 5, 4, 4, 1, 3, 4, 5, 3, 6, 1, 6, 5, 7, 12, 0, 2, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 12, 0, 5, 0, 6, 1, 3, 1, 4, 1, 6, 2, 3, 2, 4, 2, 5, 3, 4, 3, 6, 4, 5, 5, 6, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 1, 2, 4, 5, 2, 0, 5, 4, 3, 6, 5, 6, 4, 3, 5, 7, 12, 0, 2, 0, 6, 1, 2, 1, 4, 1, 5, 2, 3, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 12, 0, 2, 0, 6, 1, 3, 1, 4, 1, 5, 2, 4, 2, 5, 3, 4, 3, 5, 3, 6, 4, 6, 5, 6, 7, 12, 0, 2, 0, 6, 1, 3, 1, 4, 1, 5, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 12, 0, 5, 0, 6, 1, 3, 1, 4, 1, 6, 2, 3, 2, 4, 2, 6, 3, 4, 3, 5, 4, 5, 5, 6, 7, 12, 0, 5, 0, 6, 1, 2, 1, 5, 1, 6, 2, 3, 2, 4, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 12, 3, 0, 2, 3, 4, 2, 0, 4, 5, 1, 5, 2, 6, 1, 6, 0, 3, 6, 5, 3, 4, 5, 6, 4, 7, 12, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 12, 0, 1, 0, 2, 1, 5, 1, 6, 2, 3, 2, 4, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 12, 3, 0, 2, 3, 4, 2, 0, 4, 5, 1, 5, 2, 6, 1, 6, 0, 3, 6, 5, 3, 6, 4, 1, 3, 7, 12, 0, 4, 0, 5, 0, 6, 1, 3, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 3, 6, 4, 6, 5, 6, 7, 12, 2, 3, 4, 2, 5, 2, 4, 1, 6, 0, 3, 0, 3, 1, 6, 3, 5, 6, 1, 5, 4, 0, 3, 4, 7, 12, 2, 3, 4, 2, 4, 1, 2, 5, 6, 0, 6, 4, 3, 1, 6, 3, 0, 3, 1, 5, 4, 0, 5, 3, 7, 12, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 6, 2, 3, 2, 6, 3, 5, 4, 5, 4, 6, 5, 6, 7, 12, 3, 0, 2, 3, 4, 2, 0, 4, 5, 1, 5, 2, 6, 1, 6, 0, 3, 6, 1, 3, 6, 4, 5, 4, 7, 12, 6, 3, 1, 2, 2, 3, 0, 3, 4, 2, 5, 0, 0, 6, 4, 1, 3, 4, 6, 5, 5, 1, 0, 4, 7, 12, 0, 3, 0, 5, 0, 6, 1, 2, 1, 5, 1, 6, 2, 4, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 7, 12, 0, 3, 0, 5, 0, 6, 1, 2, 1, 4, 1, 6, 2, 3, 2, 5, 3, 4, 4, 5, 4, 6, 5, 6, 7, 12, 0, 3, 0, 5, 0, 6, 1, 2, 1, 5, 1, 6, 2, 3, 2, 4, 3, 4, 4, 5, 4, 6, 5, 6, 7, 12, 0, 4, 3, 0, 1, 3, 4, 1, 1, 0, 4, 5, 2, 4, 6, 2, 5, 6, 2, 5, 3, 2, 6, 3, 7, 12, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 5, 2, 5, 4, 6, 4, 6, 3, 6, 2, 5, 3, 7, 12, 0, 4, 0, 5, 0, 6, 1, 3, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 4, 5, 4, 6, 7, 12, 3, 0, 4, 2, 3, 1, 4, 0, 5, 2, 5, 1, 4, 3, 5, 4, 3, 5, 6, 1, 0, 6, 2, 6, 7, 12, 1, 0, 4, 1, 0, 4, 5, 0, 6, 5, 1, 6, 3, 4, 5, 3, 2, 3, 5, 2, 6, 3, 2, 6, 7, 12, 0, 1, 2, 0, 2, 3, 3, 4, 0, 4, 0, 5, 6, 1, 4, 6, 6, 5, 2, 6, 3, 1, 5, 3, 7, 12, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 7, 12, 3, 6, 1, 2, 0, 6, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 1, 2, 5, 4, 5, 6, 4, 7, 13, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 0, 6, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 0, 1, 1, 2, 2, 3, 4, 5, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 4, 3, 0, 2, 6, 4, 7, 13, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 0, 3, 1, 4, 0, 1, 0, 4, 1, 6, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 6, 4, 5, 5, 6, 7, 13, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 0, 3, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 13, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 5, 6, 7, 13, 0, 6, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 0, 1, 2, 0, 3, 2, 4, 5, 1, 6, 7, 13, 0, 1, 1, 2, 2, 3, 4, 5, 0, 4, 1, 3, 4, 1, 2, 4, 0, 3, 5, 3, 4, 3, 0, 2, 5, 6, 7, 13, 0, 5, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 6, 4, 6, 5, 6, 7, 13, 0, 6, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 7, 13, 5, 6, 0, 5, 6, 0, 4, 6, 5, 4, 1, 5, 6, 1, 3, 6, 5, 3, 2, 5, 6, 2, 1, 0, 2, 1, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 2, 6, 7, 13, 3, 4, 0, 3, 4, 0, 1, 4, 3, 1, 2, 3, 4, 2, 1, 0, 2, 1, 6, 0, 3, 6, 5, 3, 4, 5, 7, 13, 3, 4, 0, 3, 4, 0, 1, 4, 3, 1, 2, 3, 4, 2, 1, 0, 2, 1, 6, 0, 3, 6, 5, 3, 0, 5, 7, 13, 3, 4, 0, 3, 4, 0, 1, 4, 3, 1, 2, 3, 4, 2, 1, 0, 2, 1, 6, 4, 0, 6, 5, 0, 3, 5, 7, 13, 0, 5, 0, 6, 1, 3, 1, 4, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 5, 4, 6, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4, 5, 1, 6, 5, 1, 6, 7, 13, 0, 4, 0, 6, 1, 3, 1, 5, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 0, 5, 0, 6, 1, 4, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 5, 6, 7, 13, 0, 5, 0, 6, 1, 3, 1, 4, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4, 5, 3, 6, 5, 4, 6, 7, 13, 0, 5, 0, 6, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 13, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 3, 2, 5, 1, 0, 4, 1, 6, 1, 6, 5, 5, 1, 7, 13, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 4, 0, 5, 6, 0, 3, 6, 6, 4, 7, 13, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 3, 2, 5, 1, 0, 4, 1, 6, 1, 5, 1, 2, 6, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 5, 6, 7, 13, 1, 0, 2, 1, 4, 2, 1, 4, 3, 1, 0, 3, 2, 3, 5, 2, 1, 5, 0, 5, 6, 0, 1, 6, 2, 6, 7, 13, 2, 5, 6, 2, 5, 6, 4, 5, 3, 4, 0, 3, 4, 0, 1, 4, 3, 1, 6, 3, 2, 1, 4, 2, 3, 2, 7, 13, 0, 3, 0, 6, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 13, 2, 4, 3, 2, 1, 3, 4, 1, 0, 4, 3, 0, 6, 3, 1, 6, 5, 1, 4, 5, 6, 4, 3, 5, 1, 2, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 4, 2, 5, 3, 5, 3, 6, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 5, 5, 6, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 3, 2, 5, 3, 6, 4, 5, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 6, 2, 4, 2, 5, 3, 4, 3, 5, 7, 13, 0, 2, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 2, 5, 1, 2, 5, 1, 4, 5, 3, 4, 0, 3, 4, 0, 3, 2, 4, 2, 1, 3, 6, 3, 2, 6, 1, 6, 7, 13, 0, 4, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 5, 6, 7, 13, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 3, 2, 5, 1, 0, 4, 1, 0, 4, 6, 1, 4, 6, 7, 13, 2, 3, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 1, 0, 5, 2, 5, 0, 6, 5, 1, 6, 4, 0, 7, 13, 0, 1, 1, 2, 0, 2, 3, 0, 1, 3, 3, 2, 4, 0, 2, 5, 3, 4, 5, 3, 0, 5, 6, 4, 6, 1, 7, 13, 2, 3, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 1, 0, 5, 2, 6, 2, 5, 6, 0, 5, 1, 2, 7, 13, 5, 4, 6, 2, 6, 4, 4, 3, 5, 0, 3, 1, 3, 2, 6, 3, 5, 6, 4, 0, 1, 4, 5, 1, 0, 3, 7, 13, 0, 2, 0, 6, 1, 3, 1, 4, 1, 5, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 1, 5, 4, 1, 0, 4, 5, 0, 2, 5, 4, 2, 3, 4, 5, 3, 0, 1, 2, 0, 3, 2, 6, 5, 6, 4, 7, 13, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 3, 2, 5, 1, 0, 4, 1, 0, 4, 0, 6, 4, 6, 7, 13, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 1, 0, 5, 0, 4, 5, 1, 5, 6, 1, 0, 6, 3, 6, 7, 13, 0, 5, 0, 6, 1, 2, 1, 5, 1, 6, 2, 3, 2, 4, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 4, 1, 5, 3, 2, 5, 1, 0, 6, 3, 4, 6, 5, 1, 7, 13, 5, 2, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 1, 0, 6, 2, 6, 3, 1, 2, 3, 1, 4, 0, 7, 13, 1, 0, 2, 1, 0, 2, 0, 3, 3, 2, 6, 2, 1, 6, 5, 1, 6, 5, 4, 6, 5, 4, 0, 5, 4, 0, 7, 13, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 6, 7, 13, 0, 5, 0, 6, 1, 3, 1, 4, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 7, 13, 0, 1, 1, 2, 4, 1, 3, 1, 0, 4, 2, 3, 0, 3, 2, 0, 5, 0, 6, 5, 4, 6, 3, 5, 4, 2, 7, 13, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 6, 5, 6, 7, 13, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 0, 3, 0, 4, 2, 3, 6, 5, 0, 6, 7, 13, 5, 2, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 1, 0, 6, 2, 6, 3, 2, 3, 5, 0, 4, 0, 7, 13, 0, 1, 1, 2, 2, 3, 5, 4, 0, 4, 5, 0, 5, 1, 5, 2, 5, 3, 6, 3, 6, 4, 4, 2, 0, 3, 7, 13, 0, 1, 0, 6, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 6, 5, 6, 7, 13, 0, 1, 0, 6, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 13, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 6, 2, 0, 6, 5, 0, 2, 5, 5, 3, 4, 5, 6, 4, 3, 6, 7, 13, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 6, 5, 0, 6, 0, 2, 2, 5, 5, 3, 4, 5, 6, 4, 3, 6, 7, 13, 3, 4, 0, 3, 4, 0, 3, 6, 3, 1, 2, 3, 4, 2, 1, 0, 2, 1, 5, 2, 3, 5, 6, 2, 5, 6, 7, 13, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 6, 5, 3, 6, 4, 6, 7, 13, 1, 0, 2, 1, 6, 0, 1, 4, 3, 1, 0, 3, 2, 3, 1, 6, 1, 5, 2, 6, 4, 3, 5, 4, 6, 5, 7, 13, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 5, 2, 6, 3, 5, 4, 6, 7, 13, 0, 6, 1, 2, 2, 3, 0, 3, 4, 2, 5, 0, 6, 3, 4, 1, 3, 4, 6, 5, 1, 5, 3, 5, 1, 3, 7, 13, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 6, 4, 4, 3, 5, 4, 5, 2, 6, 0, 3, 6, 3, 5, 7, 13, 0, 1, 1, 2, 2, 3, 3, 6, 0, 4, 6, 5, 0, 6, 6, 4, 2, 5, 5, 3, 4, 5, 1, 5, 6, 1, 7, 13, 0, 4, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 5, 6, 7, 13, 0, 4, 0, 5, 0, 6, 1, 3, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 4, 5, 4, 6, 5, 6, 7, 13, 2, 3, 5, 2, 6, 5, 3, 6, 4, 3, 5, 4, 0, 5, 2, 0, 1, 2, 0, 1, 5, 1, 4, 2, 6, 4, 7, 13, 2, 1, 0, 5, 6, 0, 4, 6, 5, 4, 1, 5, 6, 1, 3, 6, 5, 3, 2, 5, 6, 2, 1, 0, 3, 4, 7, 13, 0, 1, 2, 0, 2, 3, 3, 4, 0, 4, 0, 5, 6, 1, 4, 6, 6, 5, 2, 6, 3, 1, 5, 3, 6, 0, 7, 13, 0, 4, 0, 5, 0, 6, 1, 2, 1, 5, 1, 6, 2, 3, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 13, 2, 3, 0, 2, 3, 0, 4, 3, 4, 6, 5, 1, 4, 5, 3, 1, 5, 2, 6, 0, 6, 1, 2, 1, 4, 1, 7, 13, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 3, 5, 4, 5, 2, 5, 1, 6, 5, 1, 6, 2, 6, 7, 13, 0, 4, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 6, 7, 13, 3, 0, 2, 3, 4, 2, 0, 4, 5, 1, 5, 2, 6, 1, 6, 0, 3, 6, 1, 3, 6, 4, 5, 4, 5, 3, 7, 13, 0, 4, 0, 5, 0, 6, 1, 2, 1, 4, 1, 5, 2, 3, 2, 6, 3, 4, 3, 5, 3, 6, 4, 6, 5, 6, 7, 13, 0, 4, 0, 5, 0, 6, 1, 3, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 3, 4, 3, 6, 4, 6, 5, 6, 7, 13, 0, 2, 0, 5, 0, 6, 1, 2, 1, 4, 1, 6, 2, 3, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 3, 4, 5, 0, 3, 5, 0, 6, 6, 4, 2, 3, 4, 2, 1, 0, 2, 1, 1, 6, 5, 1, 2, 5, 6, 2, 7, 13, 0, 2, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 13, 3, 0, 2, 3, 4, 2, 0, 4, 5, 3, 5, 2, 5, 4, 1, 3, 1, 0, 4, 1, 6, 0, 3, 6, 1, 6, 7, 13, 2, 3, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 6, 0, 1, 6, 6, 3, 4, 6, 1, 2, 5, 0, 7, 13, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 7, 13, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 7, 13, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 5, 3, 5, 4, 6, 4, 6, 2, 6, 5, 5, 2, 3, 6, 7, 13, 0, 1, 0, 5, 0, 6, 1, 3, 1, 4, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 5, 6, 7, 13, 0, 1, 0, 5, 0, 6, 1, 3, 1, 4, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 7, 13, 0, 1, 2, 0, 2, 3, 3, 4, 0, 4, 0, 5, 6, 1, 4, 6, 6, 5, 2, 6, 3, 1, 5, 3, 2, 1, 7, 14, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 1, 4, 1, 3, 2, 0, 4, 0, 5, 3, 7, 14, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 0, 3, 1, 4, 0, 1, 2, 3, 0, 4, 1, 6, 7, 14, 0, 6, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 6, 5, 6, 7, 14, 0, 6, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 14, 0, 3, 1, 2, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4, 3, 6, 5, 3, 4, 5, 6, 4, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4, 6, 2, 1, 6, 5, 1, 0, 5, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4, 5, 2, 3, 5, 6, 4, 0, 6, 7, 14, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 2, 4, 5, 1, 0, 3, 1, 4, 0, 1, 0, 4, 6, 4, 0, 6, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 3, 4, 3, 5, 4, 6, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 6, 2, 5, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 3, 4, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 0, 1, 5, 1, 0, 4, 1, 4, 5, 3, 2, 5, 6, 4, 0, 6, 7, 14, 1, 3, 2, 1, 0, 2, 5, 0, 4, 5, 3, 4, 5, 3, 2, 5, 1, 0, 4, 1, 6, 1, 5, 1, 2, 6, 0, 4, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 6, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 14, 2, 3, 4, 2, 6, 3, 4, 0, 6, 0, 3, 4, 3, 1, 5, 4, 5, 0, 0, 3, 1, 5, 5, 3, 6, 4, 6, 1, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4, 5, 3, 6, 5, 4, 6, 5, 4, 7, 14, 3, 1, 1, 4, 2, 3, 3, 4, 0, 4, 1, 5, 0, 1, 0, 2, 2, 5, 5, 3, 4, 5, 1, 2, 6, 2, 5, 6, 7, 14, 0, 3, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 14, 0, 3, 0, 6, 1, 2, 1, 4, 1, 5, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 14, 0, 1, 0, 6, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 4, 6, 5, 2, 1, 5, 0, 5, 6, 3, 7, 14, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 4, 2, 3, 0, 6, 1, 5, 6, 7, 14, 0, 4, 0, 6, 1, 2, 1, 3, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 14, 0, 4, 0, 6, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 5, 6, 7, 14, 0, 5, 0, 6, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 5, 6, 7, 14, 2, 3, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 1, 2, 5, 2, 4, 0, 3, 1, 5, 0, 6, 5, 6, 4, 0, 1, 7, 14, 2, 3, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 5, 2, 6, 0, 6, 1, 5, 0, 1, 2, 3, 1, 4, 0, 7, 14, 5, 6, 0, 5, 6, 0, 4, 6, 5, 4, 1, 5, 6, 1, 3, 6, 5, 3, 2, 5, 6, 2, 1, 0, 2, 1, 3, 4, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 5, 1, 6, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 5, 6, 7, 14, 0, 1, 2, 0, 2, 3, 3, 4, 0, 4, 0, 5, 6, 1, 4, 6, 6, 5, 2, 6, 3, 1, 5, 3, 6, 0, 3, 6, 7, 14, 3, 1, 4, 2, 4, 5, 4, 0, 1, 4, 0, 3, 5, 0, 5, 2, 6, 1, 3, 6, 6, 0, 5, 6, 6, 2, 4, 6, 7, 14, 0, 4, 3, 0, 2, 3, 4, 2, 1, 4, 3, 1, 1, 0, 2, 1, 5, 4, 1, 5, 6, 1, 3, 6, 0, 5, 6, 0, 7, 14, 3, 4, 4, 2, 1, 5, 4, 0, 1, 4, 5, 3, 3, 0, 5, 2, 6, 4, 0, 6, 3, 6, 2, 6, 5, 6, 1, 6, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 4, 1, 5, 2, 3, 2, 6, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 2, 3, 4, 2, 6, 3, 4, 0, 4, 5, 3, 4, 3, 1, 5, 2, 1, 6, 5, 6, 6, 0, 5, 3, 6, 4, 0, 1, 7, 14, 0, 4, 0, 5, 0, 6, 1, 3, 1, 5, 1, 6, 2, 3, 2, 4, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 14, 0, 4, 0, 5, 0, 6, 1, 2, 1, 5, 1, 6, 2, 3, 2, 4, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 2, 3, 4, 2, 6, 3, 4, 0, 1, 4, 6, 0, 3, 1, 5, 2, 4, 5, 5, 6, 1, 5, 5, 3, 6, 4, 3, 0, 7, 14, 3, 1, 4, 2, 0, 3, 4, 0, 1, 4, 5, 3, 5, 0, 5, 2, 6, 4, 1, 6, 6, 3, 0, 6, 6, 5, 2, 6, 7, 14, 0, 1, 4, 2, 3, 0, 4, 0, 4, 5, 5, 3, 1, 3, 5, 2, 6, 4, 2, 6, 6, 5, 3, 6, 6, 1, 0, 6, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 6, 2, 5, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 14, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 5, 1, 6, 2, 3, 2, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 14, 2, 3, 4, 2, 6, 3, 4, 0, 1, 4, 6, 1, 3, 1, 5, 2, 5, 0, 5, 6, 4, 5, 5, 3, 6, 0, 3, 0, 7, 14, 2, 3, 4, 2, 3, 0, 4, 0, 4, 5, 3, 4, 3, 1, 5, 2, 0, 1, 5, 6, 6, 0, 5, 3, 6, 4, 1, 6, 7, 14, 0, 4, 0, 5, 0, 6, 1, 3, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 5, 6, 7, 14, 0, 3, 0, 4, 0, 6, 1, 2, 1, 4, 1, 5, 2, 3, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 5, 6, 7, 14, 0, 1, 0, 5, 0, 6, 1, 4, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 5, 6, 7, 14, 0, 1, 0, 4, 0, 6, 1, 3, 1, 5, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 2, 3, 4, 2, 6, 3, 4, 0, 1, 4, 4, 5, 3, 1, 5, 2, 5, 0, 6, 1, 0, 6, 5, 3, 6, 4, 3, 0, 7, 14, 0, 1, 0, 5, 0, 6, 1, 3, 1, 4, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 2, 3, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 14, 0, 4, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 5, 6, 7, 14, 2, 3, 4, 2, 6, 3, 4, 0, 4, 5, 3, 5, 3, 1, 5, 2, 3, 0, 1, 4, 6, 0, 1, 6, 6, 4, 0, 1, 7, 14, 0, 4, 0, 5, 0, 6, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 6, 7, 14, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 4, 6, 7, 14, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 5, 1, 6, 2, 3, 2, 4, 2, 6, 3, 4, 3, 5, 4, 6, 5, 6, 7, 14, 0, 3, 0, 4, 0, 5, 1, 2, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 6, 4, 6, 5, 6, 7, 14, 0, 3, 0, 4, 0, 5, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 6, 4, 6, 5, 6, 7, 14, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 0, 6, 0, 2, 5, 0, 3, 5, 1, 3, 6, 1, 4, 6, 2, 4, 7, 14, 0, 3, 0, 4, 0, 5, 0, 6, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 6, 4, 5, 7, 15, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 3, 4, 3, 5, 4, 5, 7, 15, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 1, 4, 1, 3, 2, 0, 4, 0, 5, 3, 1, 6, 7, 15, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 2, 4, 5, 2, 1, 5, 1, 4, 1, 3, 2, 0, 4, 0, 5, 3, 0, 6, 7, 15, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 3, 4, 3, 5, 3, 6, 5, 6, 7, 15, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 5, 1, 6, 2, 4, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 15, 3, 4, 4, 5, 0, 3, 0, 4, 0, 5, 0, 6, 3, 6, 4, 6, 5, 6, 1, 5, 3, 5, 2, 3, 2, 4, 1, 6, 0, 1, 7, 15, 3, 4, 4, 5, 0, 3, 0, 4, 0, 5, 0, 6, 3, 6, 1, 3, 1, 4, 1, 5, 3, 5, 2, 3, 2, 4, 6, 1, 4, 6, 7, 15, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 4, 2, 4, 3, 5, 1, 0, 5, 5, 2, 3, 5, 4, 5, 6, 1, 5, 6, 7, 15, 4, 3, 4, 5, 5, 3, 0, 1, 0, 5, 0, 3, 2, 4, 1, 5, 1, 3, 6, 5, 3, 6, 6, 0, 1, 6, 6, 2, 4, 6, 7, 15, 3, 4, 4, 5, 5, 6, 0, 4, 0, 5, 0, 6, 3, 6, 1, 3, 4, 6, 1, 5, 3, 5, 2, 3, 2, 4, 1, 6, 0, 1, 7, 15, 0, 2, 0, 6, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 15, 6, 1, 4, 5, 0, 3, 0, 4, 0, 5, 0, 6, 3, 6, 1, 3, 1, 4, 1, 5, 3, 5, 2, 3, 2, 4, 5, 6, 4, 6, 7, 15, 3, 4, 4, 5, 0, 3, 0, 4, 0, 5, 4, 6, 3, 6, 1, 3, 1, 4, 1, 5, 3, 5, 2, 3, 2, 4, 5, 6, 5, 2, 7, 15, 3, 4, 4, 5, 0, 3, 0, 4, 6, 0, 4, 6, 3, 6, 1, 3, 1, 4, 1, 5, 3, 5, 2, 3, 2, 4, 5, 6, 5, 2, 7, 15, 0, 1, 1, 2, 0, 2, 3, 0, 1, 3, 2, 3, 5, 1, 3, 5, 4, 3, 2, 4, 6, 2, 3, 6, 6, 1, 0, 5, 4, 0, 7, 15, 0, 1, 2, 0, 3, 2, 4, 3, 1, 4, 3, 1, 4, 2, 0, 4, 3, 0, 6, 3, 4, 6, 5, 4, 3, 5, 6, 2, 5, 1, 7, 15, 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 4, 2, 3, 2, 4, 3, 4, 5, 3, 4, 5, 6, 4, 5, 6, 6, 3, 7, 15, 0, 1, 1, 2, 2, 3, 0, 3, 4, 0, 4, 3, 4, 2, 6, 1, 2, 6, 5, 2, 4, 5, 6, 4, 0, 6, 6, 5, 3, 6, 7, 15, 0, 1, 5, 3, 1, 3, 0, 4, 3, 0, 4, 3, 2, 4, 5, 2, 4, 5, 6, 4, 2, 6, 6, 5, 3, 6, 6, 1, 0, 6, 7, 15, 5, 2, 4, 5, 3, 1, 0, 4, 0, 5, 0, 3, 2, 4, 1, 5, 1, 4, 6, 3, 1, 6, 6, 0, 5, 6, 6, 2, 4, 6, 7, 15, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 0, 5, 0, 3, 2, 0, 3, 1, 6, 4, 5, 6, 6, 3, 0, 6, 6, 2, 1, 6, 7, 15, 5, 2, 3, 0, 5, 3, 0, 4, 0, 5, 4, 3, 2, 4, 1, 5, 1, 4, 6, 4, 2, 6, 6, 0, 5, 6, 6, 3, 1, 6, 7, 15, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 6, 2, 3, 2, 4, 2, 5, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 15, 6, 1, 4, 5, 0, 3, 0, 4, 0, 5, 4, 6, 3, 6, 1, 3, 1, 4, 0, 6, 3, 5, 2, 3, 2, 4, 5, 6, 5, 2, 7, 15, 3, 4, 0, 1, 0, 3, 0, 4, 0, 5, 4, 6, 3, 6, 1, 3, 1, 4, 6, 0, 1, 6, 2, 3, 2, 4, 5, 6, 5, 2, 7, 15, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 6, 7, 15, 5, 2, 4, 5, 5, 3, 0, 4, 0, 1, 1, 3, 2, 4, 3, 0, 1, 4, 6, 4, 1, 6, 6, 0, 3, 6, 6, 2, 5, 6, 7, 15, 5, 0, 4, 3, 5, 3, 5, 2, 0, 1, 1, 3, 2, 4, 3, 0, 1, 4, 6, 2, 5, 6, 6, 4, 3, 6, 6, 0, 1, 6, 7, 15, 3, 4, 4, 5, 0, 3, 4, 6, 0, 1, 1, 6, 3, 6, 1, 3, 1, 4, 6, 0, 0, 5, 2, 3, 2, 4, 5, 6, 5, 2, 7, 15, 0, 2, 0, 3, 0, 6, 1, 3, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 15, 0, 4, 0, 5, 0, 6, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 7, 15, 3, 4, 5, 0, 0, 3, 0, 4, 4, 6, 1, 6, 3, 6, 1, 3, 1, 4, 6, 0, 1, 5, 2, 3, 2, 4, 5, 6, 5, 2, 7, 15, 6, 4, 5, 2, 0, 3, 0, 4, 2, 4, 1, 6, 3, 6, 1, 3, 1, 4, 6, 0, 3, 5, 2, 3, 0, 1, 5, 6, 4, 5, 7, 15, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 5, 1, 6, 2, 3, 2, 4, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 15, 0, 1, 0, 2, 0, 3, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 15, 2, 3, 0, 2, 3, 0, 4, 3, 1, 4, 5, 1, 4, 5, 1, 0, 5, 2, 6, 2, 5, 6, 6, 1, 0, 6, 6, 4, 3, 6, 7, 15, 3, 0, 3, 5, 3, 4, 2, 0, 2, 5, 2, 4, 1, 4, 1, 5, 1, 0, 6, 0, 1, 6, 6, 5, 3, 6, 6, 4, 2, 6, 7, 15, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 5, 6, 7, 15, 3, 4, 6, 2, 0, 3, 0, 4, 5, 0, 1, 6, 3, 6, 1, 3, 1, 4, 6, 0, 4, 5, 2, 3, 2, 4, 5, 1, 5, 2, 7, 15, 3, 4, 6, 2, 0, 3, 0, 4, 5, 0, 5, 6, 3, 6, 1, 3, 1, 4, 0, 1, 4, 6, 2, 3, 2, 4, 5, 1, 5, 2, 7, 15, 0, 1, 1, 2, 2, 3, 3, 4, 0, 4, 6, 2, 1, 6, 6, 0, 4, 6, 5, 4, 0, 5, 3, 5, 6, 3, 5, 2, 1, 5, 7, 16, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 3, 4, 3, 5, 4, 5, 2, 6, 7, 16, 3, 0, 4, 1, 4, 3, 1, 3, 4, 0, 2, 5, 6, 2, 5, 6, 1, 5, 4, 5, 3, 5, 0, 5, 0, 6, 3, 6, 4, 6, 6, 1, 7, 16, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 6, 2, 3, 2, 4, 2, 5, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 16, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 7, 16, 3, 4, 5, 1, 0, 3, 0, 4, 5, 0, 4, 6, 3, 6, 1, 3, 1, 4, 6, 0, 3, 5, 2, 3, 2, 4, 5, 6, 4, 5, 2, 5, 7, 16, 2, 4, 3, 1, 3, 0, 4, 3, 4, 0, 5, 2, 4, 5, 5, 0, 3, 5, 5, 1, 6, 5, 1, 6, 3, 6, 6, 0, 4, 6, 6, 2, 7, 16, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 5, 1, 6, 2, 3, 2, 4, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 16, 2, 4, 4, 1, 3, 0, 3, 1, 4, 0, 5, 2, 4, 5, 5, 0, 3, 5, 6, 5, 1, 5, 6, 1, 3, 6, 4, 6, 6, 2, 6, 0, 7, 16, 0, 1, 0, 3, 0, 5, 0, 6, 1, 3, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 16, 2, 5, 0, 1, 4, 5, 1, 3, 5, 0, 4, 3, 5, 3, 2, 4, 1, 4, 3, 0, 6, 3, 2, 6, 6, 4, 5, 6, 6, 1, 0, 6, 7, 16, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 3, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 7, 16, 2, 5, 5, 1, 3, 1, 0, 4, 5, 0, 4, 3, 5, 3, 2, 4, 1, 4, 3, 0, 6, 2, 4, 6, 5, 6, 6, 1, 0, 6, 3, 6, 7, 16, 1, 6, 0, 1, 0, 3, 0, 4, 5, 0, 4, 6, 3, 6, 1, 3, 1, 4, 6, 0, 3, 5, 2, 3, 2, 4, 5, 6, 4, 5, 2, 5, 7, 16, 3, 4, 5, 1, 0, 3, 0, 4, 5, 0, 4, 6, 3, 6, 1, 3, 1, 4, 6, 0, 1, 6, 2, 3, 2, 4, 5, 6, 0, 1, 2, 5, 7, 16, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 7, 16, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 5, 6, 7, 16, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 5, 6, 7, 16, 2, 5, 5, 1, 3, 5, 0, 4, 0, 1, 4, 3, 3, 2, 2, 4, 1, 4, 0, 5, 6, 4, 2, 6, 6, 3, 5, 6, 6, 1, 0, 6, 7, 16, 5, 6, 5, 1, 0, 3, 0, 4, 0, 1, 4, 6, 3, 6, 1, 3, 1, 4, 6, 0, 3, 5, 2, 3, 2, 4, 6, 2, 4, 5, 2, 5, 7, 16, 3, 4, 5, 1, 0, 3, 0, 4, 0, 1, 4, 6, 3, 6, 1, 3, 1, 4, 6, 0, 5, 0, 2, 3, 2, 4, 6, 2, 6, 5, 2, 5, 7, 16, 5, 0, 5, 1, 0, 3, 0, 4, 6, 1, 4, 6, 3, 6, 1, 3, 1, 4, 6, 0, 3, 5, 2, 3, 2, 4, 6, 2, 4, 5, 2, 5, 7, 17, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 3, 4, 3, 5, 4, 5, 6, 2, 1, 6, 7, 17, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 4, 5, 4, 6, 7, 17, 4, 0, 4, 3, 0, 1, 3, 0, 2, 4, 3, 1, 5, 3, 4, 5, 5, 2, 6, 5, 5, 0, 1, 5, 6, 1, 0, 6, 6, 4, 2, 6, 3, 6, 7, 17, 0, 1, 5, 1, 5, 3, 0, 4, 5, 0, 4, 3, 3, 1, 2, 5, 1, 4, 3, 0, 2, 4, 6, 2, 5, 6, 6, 3, 1, 6, 6, 0, 4, 6, 7, 17, 3, 4, 5, 1, 0, 3, 0, 4, 4, 5, 4, 6, 3, 6, 1, 3, 1, 4, 0, 1, 3, 5, 2, 3, 2, 4, 2, 5, 5, 0, 5, 6, 6, 2, 7, 17, 3, 2, 4, 1, 0, 1, 3, 0, 2, 4, 4, 3, 5, 1, 4, 5, 5, 2, 0, 5, 5, 3, 6, 5, 2, 6, 6, 3, 0, 6, 1, 6, 4, 6, 7, 17, 3, 2, 4, 1, 4, 0, 3, 0, 2, 4, 3, 1, 5, 2, 4, 5, 5, 0, 3, 5, 5, 1, 6, 5, 2, 6, 6, 0, 3, 6, 6, 4, 1, 6, 7, 17, 3, 2, 5, 1, 5, 0, 0, 4, 0, 1, 4, 3, 5, 3, 2, 5, 1, 4, 3, 0, 2, 4, 6, 4, 5, 6, 6, 2, 3, 6, 6, 0, 1, 6, 7, 17, 3, 2, 5, 1, 5, 0, 0, 4, 4, 5, 0, 1, 3, 1, 2, 5, 1, 4, 3, 0, 2, 4, 6, 0, 3, 6, 6, 1, 5, 6, 6, 2, 4, 6, 7, 17, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 5, 3, 6, 4, 5, 4, 6, 7, 18, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 3, 4, 3, 5, 4, 5, 6, 1, 0, 6, 5, 6, 7, 18, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 7, 18, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 4, 1, 5, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 4, 6, 5, 6, 7, 18, 0, 1, 0, 2, 0, 3, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 18, 4, 0, 4, 5, 3, 0, 3, 5, 2, 0, 2, 5, 1, 3, 1, 4, 1, 5, 1, 0, 2, 3, 2, 4, 6, 0, 5, 6, 6, 1, 2, 6, 6, 4, 3, 6, 7, 19, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 19, 0, 1, 0, 2, 0, 3, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 6, 4, 5, 4, 6, 5, 6, 7, 20, 0, 1, 0, 2, 0, 3, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, 7, 21, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 4, 5, 4, 6, 5, 6, }; const long int igraph_i_atlas_edges_pos[] = {0, 2, 4, 6, 10, 12, 16, 22, 30, 32, 36, 42, 48, 56, 64, 72, 82, 92, 104, 118, 120, 124, 130, 136, 144, 152, 160, 168, 178, 188, 198, 208, 218, 228, 240, 252, 264, 276, 288, 300, 314, 328, 342, 356, 370, 384, 400, 416, 432, 448, 466, 484, 504, 526, 528, 532, 538, 544, 552, 560, 568, 576, 584, 594, 604, 614, 624, 634, 644, 654, 664, 674, 686, 698, 710, 722, 734, 746, 758, 770, 782, 794, 806, 818, 830, 842, 854, 868, 882, 896, 910, 924, 938, 952, 966, 980, 994, 1008, 1022, 1036, 1050, 1064, 1078, 1092, 1106, 1120, 1134, 1148, 1164, 1180, 1196, 1212, 1228, 1244, 1260, 1276, 1292, 1308, 1324, 1340, 1356, 1372, 1388, 1404, 1420, 1436, 1452, 1468, 1484, 1500, 1516, 1532, 1550, 1568, 1586, 1604, 1622, 1640, 1658, 1676, 1694, 1712, 1730, 1748, 1766, 1784, 1802, 1820, 1838, 1856, 1874, 1892, 1910, 1928, 1946, 1964, 1984, 2004, 2024, 2044, 2064, 2084, 2104, 2124, 2144, 2164, 2184, 2204, 2224, 2244, 2264, 2284, 2304, 2324, 2344, 2364, 2384, 2406, 2428, 2450, 2472, 2494, 2516, 2538, 2560, 2582, 2604, 2626, 2648, 2670, 2692, 2714, 2738, 2762, 2786, 2810, 2834, 2858, 2882, 2906, 2930, 2956, 2982, 3008, 3034, 3060, 3088, 3116, 3146, 3178, 3180, 3184, 3190, 3196, 3204, 3212, 3220, 3228, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316, 3326, 3336, 3348, 3360, 3372, 3384, 3396, 3408, 3420, 3432, 3444, 3456, 3468, 3480, 3492, 3504, 3516, 3528, 3540, 3552, 3564, 3576, 3588, 3602, 3616, 3630, 3644, 3658, 3672, 3686, 3700, 3714, 3728, 3742, 3756, 3770, 3784, 3798, 3812, 3826, 3840, 3854, 3868, 3882, 3896, 3910, 3924, 3938, 3952, 3966, 3980, 3994, 4008, 4022, 4036, 4050, 4064, 4078, 4092, 4106, 4120, 4134, 4148, 4162, 4178, 4194, 4210, 4226, 4242, 4258, 4274, 4290, 4306, 4322, 4338, 4354, 4370, 4386, 4402, 4418, 4434, 4450, 4466, 4482, 4498, 4514, 4530, 4546, 4562, 4578, 4594, 4610, 4626, 4642, 4658, 4674, 4690, 4706, 4722, 4738, 4754, 4770, 4786, 4802, 4818, 4834, 4850, 4866, 4882, 4898, 4914, 4930, 4946, 4962, 4978, 4994, 5010, 5026, 5042, 5058, 5074, 5090, 5106, 5122, 5138, 5154, 5170, 5186, 5202, 5220, 5238, 5256, 5274, 5292, 5310, 5328, 5346, 5364, 5382, 5400, 5418, 5436, 5454, 5472, 5490, 5508, 5526, 5544, 5562, 5580, 5598, 5616, 5634, 5652, 5670, 5688, 5706, 5724, 5742, 5760, 5778, 5796, 5814, 5832, 5850, 5868, 5886, 5904, 5922, 5940, 5958, 5976, 5994, 6012, 6030, 6048, 6066, 6084, 6102, 6120, 6138, 6156, 6174, 6192, 6210, 6228, 6246, 6264, 6282, 6300, 6318, 6336, 6354, 6372, 6390, 6408, 6426, 6444, 6462, 6480, 6498, 6516, 6534, 6552, 6570, 6588, 6606, 6624, 6642, 6660, 6678, 6696, 6714, 6732, 6750, 6768, 6786, 6804, 6822, 6840, 6858, 6876, 6894, 6912, 6930, 6948, 6968, 6988, 7008, 7028, 7048, 7068, 7088, 7108, 7128, 7148, 7168, 7188, 7208, 7228, 7248, 7268, 7288, 7308, 7328, 7348, 7368, 7388, 7408, 7428, 7448, 7468, 7488, 7508, 7528, 7548, 7568, 7588, 7608, 7628, 7648, 7668, 7688, 7708, 7728, 7748, 7768, 7788, 7808, 7828, 7848, 7868, 7888, 7908, 7928, 7948, 7968, 7988, 8008, 8028, 8048, 8068, 8088, 8108, 8128, 8148, 8168, 8188, 8208, 8228, 8248, 8268, 8288, 8308, 8328, 8348, 8368, 8388, 8408, 8428, 8448, 8468, 8488, 8508, 8528, 8548, 8568, 8588, 8608, 8628, 8648, 8668, 8688, 8708, 8728, 8748, 8768, 8788, 8808, 8828, 8848, 8868, 8888, 8908, 8928, 8948, 8968, 8988, 9008, 9028, 9048, 9068, 9088, 9108, 9128, 9148, 9168, 9188, 9208, 9228, 9248, 9268, 9288, 9308, 9328, 9348, 9368, 9388, 9408, 9428, 9448, 9468, 9488, 9508, 9528, 9548, 9568, 9590, 9612, 9634, 9656, 9678, 9700, 9722, 9744, 9766, 9788, 9810, 9832, 9854, 9876, 9898, 9920, 9942, 9964, 9986, 10008, 10030, 10052, 10074, 10096, 10118, 10140, 10162, 10184, 10206, 10228, 10250, 10272, 10294, 10316, 10338, 10360, 10382, 10404, 10426, 10448, 10470, 10492, 10514, 10536, 10558, 10580, 10602, 10624, 10646, 10668, 10690, 10712, 10734, 10756, 10778, 10800, 10822, 10844, 10866, 10888, 10910, 10932, 10954, 10976, 10998, 11020, 11042, 11064, 11086, 11108, 11130, 11152, 11174, 11196, 11218, 11240, 11262, 11284, 11306, 11328, 11350, 11372, 11394, 11416, 11438, 11460, 11482, 11504, 11526, 11548, 11570, 11592, 11614, 11636, 11658, 11680, 11702, 11724, 11746, 11768, 11790, 11812, 11834, 11856, 11878, 11900, 11922, 11944, 11966, 11988, 12010, 12032, 12054, 12076, 12098, 12120, 12142, 12164, 12186, 12208, 12230, 12252, 12274, 12296, 12318, 12340, 12362, 12384, 12406, 12428, 12450, 12472, 12494, 12516, 12538, 12560, 12582, 12604, 12626, 12648, 12670, 12692, 12714, 12736, 12758, 12780, 12802, 12824, 12848, 12872, 12896, 12920, 12944, 12968, 12992, 13016, 13040, 13064, 13088, 13112, 13136, 13160, 13184, 13208, 13232, 13256, 13280, 13304, 13328, 13352, 13376, 13400, 13424, 13448, 13472, 13496, 13520, 13544, 13568, 13592, 13616, 13640, 13664, 13688, 13712, 13736, 13760, 13784, 13808, 13832, 13856, 13880, 13904, 13928, 13952, 13976, 14000, 14024, 14048, 14072, 14096, 14120, 14144, 14168, 14192, 14216, 14240, 14264, 14288, 14312, 14336, 14360, 14384, 14408, 14432, 14456, 14480, 14504, 14528, 14552, 14576, 14600, 14624, 14648, 14672, 14696, 14720, 14744, 14768, 14792, 14816, 14840, 14864, 14888, 14912, 14936, 14960, 14984, 15008, 15032, 15056, 15080, 15104, 15128, 15152, 15176, 15200, 15224, 15248, 15272, 15296, 15320, 15344, 15368, 15392, 15416, 15440, 15464, 15488, 15512, 15536, 15560, 15584, 15608, 15632, 15656, 15680, 15704, 15728, 15752, 15776, 15800, 15824, 15848, 15872, 15896, 15920, 15944, 15968, 15992, 16016, 16040, 16064, 16088, 16112, 16136, 16160, 16184, 16208, 16232, 16256, 16280, 16304, 16328, 16352, 16376, 16402, 16428, 16454, 16480, 16506, 16532, 16558, 16584, 16610, 16636, 16662, 16688, 16714, 16740, 16766, 16792, 16818, 16844, 16870, 16896, 16922, 16948, 16974, 17000, 17026, 17052, 17078, 17104, 17130, 17156, 17182, 17208, 17234, 17260, 17286, 17312, 17338, 17364, 17390, 17416, 17442, 17468, 17494, 17520, 17546, 17572, 17598, 17624, 17650, 17676, 17702, 17728, 17754, 17780, 17806, 17832, 17858, 17884, 17910, 17936, 17962, 17988, 18014, 18040, 18066, 18092, 18118, 18144, 18170, 18196, 18222, 18248, 18274, 18300, 18326, 18352, 18378, 18404, 18430, 18456, 18482, 18508, 18534, 18560, 18586, 18612, 18638, 18664, 18690, 18716, 18742, 18768, 18794, 18820, 18846, 18872, 18898, 18924, 18950, 18976, 19002, 19028, 19054, 19080, 19106, 19132, 19158, 19184, 19210, 19236, 19262, 19288, 19314, 19340, 19366, 19392, 19418, 19444, 19470, 19496, 19522, 19548, 19574, 19600, 19626, 19652, 19678, 19704, 19730, 19756, 19782, 19810, 19838, 19866, 19894, 19922, 19950, 19978, 20006, 20034, 20062, 20090, 20118, 20146, 20174, 20202, 20230, 20258, 20286, 20314, 20342, 20370, 20398, 20426, 20454, 20482, 20510, 20538, 20566, 20594, 20622, 20650, 20678, 20706, 20734, 20762, 20790, 20818, 20846, 20874, 20902, 20930, 20958, 20986, 21014, 21042, 21070, 21098, 21126, 21154, 21182, 21210, 21238, 21266, 21294, 21322, 21350, 21378, 21406, 21434, 21462, 21490, 21518, 21546, 21574, 21602, 21630, 21658, 21686, 21714, 21742, 21770, 21798, 21826, 21854, 21882, 21910, 21938, 21966, 21994, 22022, 22050, 22078, 22106, 22134, 22162, 22190, 22218, 22246, 22274, 22302, 22330, 22358, 22386, 22414, 22442, 22470, 22498, 22528, 22558, 22588, 22618, 22648, 22678, 22708, 22738, 22768, 22798, 22828, 22858, 22888, 22918, 22948, 22978, 23008, 23038, 23068, 23098, 23128, 23158, 23188, 23218, 23248, 23278, 23308, 23338, 23368, 23398, 23428, 23458, 23488, 23518, 23548, 23578, 23608, 23638, 23668, 23698, 23728, 23758, 23788, 23818, 23848, 23878, 23908, 23938, 23968, 23998, 24028, 24058, 24088, 24118, 24148, 24178, 24208, 24238, 24268, 24298, 24328, 24358, 24388, 24418, 24448, 24480, 24512, 24544, 24576, 24608, 24640, 24672, 24704, 24736, 24768, 24800, 24832, 24864, 24896, 24928, 24960, 24992, 25024, 25056, 25088, 25120, 25152, 25184, 25216, 25248, 25280, 25312, 25344, 25376, 25408, 25440, 25472, 25504, 25536, 25568, 25600, 25632, 25664, 25696, 25728, 25760, 25794, 25828, 25862, 25896, 25930, 25964, 25998, 26032, 26066, 26100, 26134, 26168, 26202, 26236, 26270, 26304, 26338, 26372, 26406, 26440, 26474, 26510, 26546, 26582, 26618, 26654, 26690, 26726, 26762, 26798, 26834, 26872, 26910, 26948, 26986, 27024, 27064, 27104, 27146}; __END_DECLS leidenbase/src/core/games/0000755000176200001440000000000014532173045015164 5ustar liggesusersleidenbase/src/core/games/citations.c0000644000176200001440000004256514447675374017362 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_memory.h" #include "igraph_psumtree.h" #include "igraph_random.h" #include "igraph_interface.h" typedef struct { long int no; igraph_psumtree_t *sumtrees; } igraph_i_citing_cited_type_game_struct_t; static void igraph_i_citing_cited_type_game_free ( igraph_i_citing_cited_type_game_struct_t *s); /** * \function igraph_lastcit_game * \brief Simulates a citation network, based on time passed since the last citation. * * This is a quite special stochastic graph generator, it models an * evolving graph. In each time step a single vertex is added to the * network and it cites a number of other vertices (as specified by * the \p edges_per_step argument). The cited vertices are selected * based on the last time they were cited. Time is measured by the * addition of vertices and it is binned into \p agebins bins. * So if the current time step is \c t and the last citation to a * given \c i vertex was made in time step \c t0, then \c * (t-t0)/binwidth is calculated where binwidth is \c nodes/agebins+1, * in the last expression '/' denotes integer division, so the * fraction part is omitted. * * * The \p preference argument specifies the preferences for the * citation lags, i.e. its first elements contains the attractivity * of the very recently cited vertices, etc. The last element is * special, it contains the attractivity of the vertices which were * never cited. This element should be bigger than zero. * * * Note that this function generates networks with multiple edges if * \p edges_per_step is bigger than one, call \ref igraph_simplify() * on the result to get rid of these edges. * \param graph Pointer to an uninitialized graph object, the result * will be stored here. * \param node The number of vertices in the network. * \param edges_per_node The number of edges to add in each time * step. * \param agebins The number of age bins to use. * \param preference Pointer to an initialized vector of length * \c agebins+1. This contains the `attractivity' of the various * age bins, the last element is the attractivity of the vertices * which were never cited, and it should be greater than zero. * It is a good idea to have all positive values in this vector. * Preferences cannot be negative. * \param directed Logical constant, whether to create directed * networks. * \return Error code. * * \sa \ref igraph_barabasi_aging_game(). * * Time complexity: O(|V|*a+|E|*log|V|), |V| is the number of vertices, * |E| is the total number of edges, a is the \p agebins parameter. */ int igraph_lastcit_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t edges_per_node, igraph_integer_t agebins, const igraph_vector_t *preference, igraph_bool_t directed) { long int no_of_nodes = nodes; igraph_psumtree_t sumtree; igraph_vector_t edges; long int i, j, k; long int *lastcit; long int *index; long int binwidth; if (agebins != igraph_vector_size(preference) - 1) { IGRAPH_ERRORF("The `preference' vector should be of length `agebins' plus one." "Number of agebins is %"IGRAPH_PRId", preference vector is of length %ld.", IGRAPH_EINVAL, agebins, igraph_vector_size(preference)); } if (nodes < 0 ) { IGRAPH_ERRORF("Number of nodes should be non-negative, received %"IGRAPH_PRId".", IGRAPH_EINVAL, nodes); } if (agebins < 1 ) { IGRAPH_ERRORF("Number of age bins should be at least 1, received %"IGRAPH_PRId".", IGRAPH_EINVAL, agebins); } if (VECTOR(*preference)[agebins] <= 0) { IGRAPH_ERRORF("The last element of the `preference' vector needs to be positive, but is %g.", IGRAPH_EINVAL, VECTOR(*preference)[agebins]); } if (igraph_vector_min(preference) < 0) { IGRAPH_ERRORF("The preference vector must contain only non-negative values, but found %g.", IGRAPH_EINVAL, igraph_vector_min(preference)); } if (nodes == 0) { IGRAPH_CHECK(igraph_empty(graph, nodes, directed)); return IGRAPH_SUCCESS; } binwidth = no_of_nodes / agebins + 1; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); lastcit = IGRAPH_CALLOC(no_of_nodes, long int); if (!lastcit) { IGRAPH_ERROR("lastcit game failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, lastcit); index = IGRAPH_CALLOC(no_of_nodes + 1, long int); if (!index) { IGRAPH_ERROR("lastcit game failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, index); IGRAPH_CHECK(igraph_psumtree_init(&sumtree, nodes)); IGRAPH_FINALLY(igraph_psumtree_destroy, &sumtree); IGRAPH_CHECK(igraph_vector_reserve(&edges, nodes * edges_per_node)); /* The first node */ IGRAPH_CHECK(igraph_psumtree_update(&sumtree, 0, VECTOR(*preference)[agebins])); index[0] = 0; index[1] = 0; RNG_BEGIN(); for (i = 1; i < no_of_nodes; i++) { /* Add new edges */ for (j = 0; j < edges_per_node; j++) { long int to; igraph_real_t sum = igraph_psumtree_sum(&sumtree); igraph_psumtree_search(&sumtree, &to, RNG_UNIF(0, sum)); igraph_vector_push_back(&edges, i); igraph_vector_push_back(&edges, to); lastcit[to] = i + 1; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, to, VECTOR(*preference)[0])); } /* Add the node itself */ IGRAPH_CHECK(igraph_psumtree_update(&sumtree, i, VECTOR(*preference)[agebins])); index[i + 1] = index[i] + edges_per_node; /* Update the preference of some vertices if they got to another bin. We need to know the citations of some older vertices, this is in the index. */ for (k = 1; i - binwidth * k >= 1; k++) { long int shnode = i - binwidth * k; long int m = index[shnode], n = index[shnode + 1]; for (j = 2 * m; j < 2 * n; j += 2) { long int cnode = (long int) VECTOR(edges)[j + 1]; if (lastcit[cnode] == shnode + 1) { IGRAPH_CHECK(igraph_psumtree_update(&sumtree, cnode, VECTOR(*preference)[k])); } } } } RNG_END(); igraph_psumtree_destroy(&sumtree); igraph_free(index); igraph_free(lastcit); IGRAPH_FINALLY_CLEAN(3); IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_cited_type_game * \brief Simulates a citation based on vertex types. * * Function to create a network based on some vertex categories. This * function creates a citation network: in each step a single vertex * and \p edges_per_step citing edges are added. Nodes with * different categories may have different probabilities to get * cited, as given by the \p pref vector. * * * Note that this function might generate networks with multiple edges * if \p edges_per_step is greater than one. You might want to call * \ref igraph_simplify() on the result to remove multiple edges. * \param graph Pointer to an uninitialized graph object. * \param nodes The number of vertices in the network. * \param types Numeric vector giving the categories of the vertices, * so it should contain \p nodes non-negative integer * numbers. Types are numbered from zero. * \param pref The attractivity of the different vertex categories in * a vector. Its length should be the maximum element in \p types * plus one (types are numbered from zero). * \param edges_per_step Integer constant, the number of edges to add * in each time step. * \param directed Logical constant, whether to create a directed * network. * \return Error code. * * \sa \ref igraph_citing_cited_type_game() for a bit more general * game. * * Time complexity: O((|V|+|E|)log|V|), |V| and |E| are number of * vertices and edges, respectively. */ int igraph_cited_type_game(igraph_t *graph, igraph_integer_t nodes, const igraph_vector_t *types, const igraph_vector_t *pref, igraph_integer_t edges_per_step, igraph_bool_t directed) { igraph_vector_t edges; igraph_vector_t cumsum; igraph_real_t sum, nnval; long int i, j, type; long int pref_len = igraph_vector_size(pref); if (igraph_vector_size(types) != nodes) { IGRAPH_ERRORF("Length of types vector (%ld) must match number of nodes (%" IGRAPH_PRId ").", IGRAPH_EINVAL, (long) igraph_vector_size(types), nodes); } if (nodes == 0) { igraph_empty(graph, 0, directed); return IGRAPH_SUCCESS; } /* the case of zero-length type vector is caught above, safe to call vector_min here */ if (igraph_vector_min(types) < 0) { IGRAPH_ERRORF("Types should be non-negative, but found %g.", IGRAPH_EINVAL, igraph_vector_min(types)); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&cumsum, 2); IGRAPH_CHECK(igraph_vector_reserve(&cumsum, nodes + 1)); IGRAPH_CHECK(igraph_vector_reserve(&edges, nodes * edges_per_step)); /* first node */ VECTOR(cumsum)[0] = 0; type = (long int) VECTOR(*types)[0]; if (type >= pref_len) { goto err_pref_too_short; } nnval = VECTOR(*pref)[type]; if (nnval < 0) { goto err_pref_neg; } sum = VECTOR(cumsum)[1] = nnval; RNG_BEGIN(); for (i = 1; i < nodes; i++) { for (j = 0; j < edges_per_step; j++) { long int to; if (sum > 0) { igraph_vector_binsearch(&cumsum, RNG_UNIF(0, sum), &to); } else { to = i + 1; } igraph_vector_push_back(&edges, i); igraph_vector_push_back(&edges, to - 1); } type = (long int) VECTOR(*types)[i]; if (type >= pref_len) { goto err_pref_too_short; } nnval = VECTOR(*pref)[type]; if (nnval < 0) { goto err_pref_neg; } sum += nnval; igraph_vector_push_back(&cumsum, sum); } RNG_END(); igraph_vector_destroy(&cumsum); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; err_pref_too_short: IGRAPH_ERRORF("Preference vector should have length at least %ld with the given types.", IGRAPH_EINVAL, (long) igraph_vector_max(types) + 1); err_pref_neg: IGRAPH_ERRORF("Preferences should be non-negative, but found %g.", IGRAPH_EINVAL, igraph_vector_min(pref)); } static void igraph_i_citing_cited_type_game_free(igraph_i_citing_cited_type_game_struct_t *s) { long int i; if (!s->sumtrees) { return; } for (i = 0; i < s->no; i++) { igraph_psumtree_destroy(&s->sumtrees[i]); } igraph_free(s->sumtrees); } /** * \function igraph_citing_cited_type_game * \brief Simulates a citation network based on vertex types. * * This game is similar to \ref igraph_cited_type_game() but here the * category of the citing vertex is also considered. * * * An evolving citation network is modeled here, a single vertex and * its \p edges_per_step citation are added in each time step. The * odds the a given vertex is cited by the new vertex depends on the * category of both the citing and the cited vertex and is given in * the \p pref matrix. The categories of the citing vertex correspond * to the rows, the categories of the cited vertex to the columns of * this matrix. I.e. the element in row \c i and column \c j gives the * probability that a \c j vertex is cited, if the category of the * citing vertex is \c i. * * * Note that this function might generate networks with multiple edges * if \p edges_per_step is greater than one. You might want to call * \ref igraph_simplify() on the result to remove multiple edges. * \param graph Pointer to an uninitialized graph object. * \param nodes The number of vertices in the network. * \param types A numeric matrix of length \p nodes, containing the * categories of the vertices. The categories are numbered from * zero. * \param pref The preference matrix, a square matrix is required, * both the number of rows and columns should be the maximum * element in \p types plus one (types are numbered from zero). * \param directed Logical constant, whether to create a directed * network. * \return Error code. * * Time complexity: O((|V|+|E|)log|V|), |V| and |E| are number of * vertices and edges, respectively. */ int igraph_citing_cited_type_game(igraph_t *graph, igraph_integer_t nodes, const igraph_vector_t *types, const igraph_matrix_t *pref, igraph_integer_t edges_per_step, igraph_bool_t directed) { igraph_vector_t edges; igraph_i_citing_cited_type_game_struct_t str = { 0, NULL }; igraph_psumtree_t *sumtrees; igraph_vector_t sums; long int no_of_types; long int i, j; if (igraph_vector_size(types) != nodes) { IGRAPH_ERRORF("Length of types vector (%ld) not equal to number" " of nodes (%" IGRAPH_PRId ").", IGRAPH_EINVAL, igraph_vector_size(types), nodes); } /* avoid calling vector_max on empty vector */ no_of_types = nodes == 0 ? 0 : igraph_vector_max(types) + 1; if (igraph_matrix_ncol(pref) != no_of_types) { IGRAPH_ERRORF("Number of preference matrix columns (%ld) not " "equal to number of types (%ld).", IGRAPH_EINVAL, igraph_matrix_ncol(pref), no_of_types); } if (igraph_matrix_nrow(pref) != no_of_types) { IGRAPH_ERRORF("Number of preference matrix rows (%ld) not " "equal to number of types (%ld).", IGRAPH_EINVAL, igraph_matrix_nrow(pref), no_of_types); } /* return an empty graph if nodes is zero */ if (nodes == 0) { return igraph_empty(graph, 0, directed); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); str.sumtrees = sumtrees = IGRAPH_CALLOC(no_of_types, igraph_psumtree_t); if (!sumtrees) { IGRAPH_ERROR("Citing-cited type game failed.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_i_citing_cited_type_game_free, &str); for (i = 0; i < no_of_types; i++) { IGRAPH_CHECK(igraph_psumtree_init(&sumtrees[i], nodes)); str.no++; } IGRAPH_VECTOR_INIT_FINALLY(&sums, no_of_types); IGRAPH_CHECK(igraph_vector_reserve(&edges, nodes * edges_per_step)); /* First node */ for (i = 0; i < no_of_types; i++) { long int type = (long int) VECTOR(*types)[0]; if ( MATRIX(*pref, i, type) < 0) { IGRAPH_ERRORF("Preference matrix contains negative entry: %g.", IGRAPH_EINVAL, MATRIX(*pref, i, type)); } IGRAPH_CHECK(igraph_psumtree_update(&sumtrees[i], 0, MATRIX(*pref, i, type))); VECTOR(sums)[i] = MATRIX(*pref, i, type); } RNG_BEGIN(); for (i = 1; i < nodes; i++) { long int type = (long int) VECTOR(*types)[i]; igraph_real_t sum = VECTOR(sums)[type]; for (j = 0; j < edges_per_step; j++) { long int to; igraph_psumtree_search(&sumtrees[type], &to, RNG_UNIF(0, sum)); igraph_vector_push_back(&edges, i); igraph_vector_push_back(&edges, to); } /* add i */ for (j = 0; j < no_of_types; j++) { if ( MATRIX(*pref, j, type) < 0) { IGRAPH_ERRORF("Preference matrix contains negative entry: %g.", IGRAPH_EINVAL, MATRIX(*pref, j, type)); } IGRAPH_CHECK(igraph_psumtree_update(&sumtrees[j], i, MATRIX(*pref, j, type))); VECTOR(sums)[j] += MATRIX(*pref, j, type); } } RNG_END(); igraph_i_citing_cited_type_game_free(&str); IGRAPH_FINALLY_CLEAN(1); igraph_create(graph, &edges, nodes, directed); igraph_vector_destroy(&edges); igraph_vector_destroy(&sums); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } leidenbase/src/core/games/erdos_renyi.c0000644000176200001440000002376614447675374017711 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_nongraph.h" #include "igraph_random.h" /** * \section about_games * * Games are randomized graph generators. Randomization means that * they generate a different graph every time you call them. */ int igraph_erdos_renyi_game_gnp( igraph_t *graph, igraph_integer_t n, igraph_real_t p, igraph_bool_t directed, igraph_bool_t loops ) { long int no_of_nodes = n; igraph_vector_t edges = IGRAPH_VECTOR_NULL; igraph_vector_t s = IGRAPH_VECTOR_NULL; int retval = 0; long int vsize; if (n < 0) { IGRAPH_ERROR("Invalid number of vertices", IGRAPH_EINVAL); } if (p < 0.0 || p > 1.0) { IGRAPH_ERROR("Invalid probability given", IGRAPH_EINVAL); } if (p == 0.0 || no_of_nodes == 0) { IGRAPH_CHECK(retval = igraph_empty(graph, n, directed)); } else if (p == 1.0) { IGRAPH_CHECK(retval = igraph_full(graph, n, directed, loops)); } else { long int i; double maxedges = n, last; if (directed && loops) { maxedges *= n; } else if (directed && !loops) { maxedges *= (n - 1); } else if (!directed && loops) { maxedges *= (n + 1) / 2.0; } else { maxedges *= (n - 1) / 2.0; } IGRAPH_VECTOR_INIT_FINALLY(&s, 0); IGRAPH_CHECK(igraph_vector_reserve(&s, (long int) (maxedges * p * 1.1))); RNG_BEGIN(); last = RNG_GEOM(p); while (last < maxedges) { IGRAPH_CHECK(igraph_vector_push_back(&s, last)); last += RNG_GEOM(p); last += 1; } RNG_END(); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, igraph_vector_size(&s) * 2)); vsize = igraph_vector_size(&s); if (directed && loops) { for (i = 0; i < vsize; i++) { long int to = (long int) floor(VECTOR(s)[i] / no_of_nodes); long int from = (long int) (VECTOR(s)[i] - ((igraph_real_t)to) * no_of_nodes); igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } } else if (directed && !loops) { for (i = 0; i < vsize; i++) { long int to = (long int) floor(VECTOR(s)[i] / no_of_nodes); long int from = (long int) (VECTOR(s)[i] - ((igraph_real_t)to) * no_of_nodes); if (from == to) { to = no_of_nodes - 1; } igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } } else if (!directed && loops) { for (i = 0; i < vsize; i++) { long int to = (long int) floor((sqrt(8 * VECTOR(s)[i] + 1) - 1) / 2); long int from = (long int) (VECTOR(s)[i] - (((igraph_real_t)to) * (to + 1)) / 2); igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } } else { /* !directed && !loops */ for (i = 0; i < vsize; i++) { long int to = (long int) floor((sqrt(8 * VECTOR(s)[i] + 1) + 1) / 2); long int from = (long int) (VECTOR(s)[i] - (((igraph_real_t)to) * (to - 1)) / 2); igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } } igraph_vector_destroy(&s); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(retval = igraph_create(graph, &edges, n, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); } return retval; } int igraph_erdos_renyi_game_gnm( igraph_t *graph, igraph_integer_t n, igraph_real_t m, igraph_bool_t directed, igraph_bool_t loops ) { igraph_integer_t no_of_nodes = n; igraph_integer_t no_of_edges = (igraph_integer_t) m; igraph_vector_t edges = IGRAPH_VECTOR_NULL; igraph_vector_t s = IGRAPH_VECTOR_NULL; int retval = 0; if (n < 0) { IGRAPH_ERROR("Invalid number of vertices", IGRAPH_EINVAL); } if (m < 0) { IGRAPH_ERROR("Invalid number of edges", IGRAPH_EINVAL); } if (m == 0.0 || no_of_nodes == 0) { IGRAPH_CHECK(retval = igraph_empty(graph, n, directed)); } else { long int i; double maxedges = n; if (directed && loops) { maxedges *= n; } else if (directed && !loops) { maxedges *= (n - 1); } else if (!directed && loops) { maxedges *= (n + 1) / 2.0; } else { maxedges *= (n - 1) / 2.0; } if (no_of_edges > maxedges) { IGRAPH_ERROR("Invalid number (too large) of edges", IGRAPH_EINVAL); } if (maxedges == no_of_edges) { retval = igraph_full(graph, n, directed, loops); } else { long int slen; IGRAPH_VECTOR_INIT_FINALLY(&s, 0); IGRAPH_CHECK(igraph_random_sample(&s, 0, maxedges - 1, (igraph_integer_t) no_of_edges)); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, igraph_vector_size(&s) * 2)); slen = igraph_vector_size(&s); if (directed && loops) { for (i = 0; i < slen; i++) { long int to = (long int) floor(VECTOR(s)[i] / no_of_nodes); long int from = (long int) (VECTOR(s)[i] - ((igraph_real_t)to) * no_of_nodes); igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } } else if (directed && !loops) { for (i = 0; i < slen; i++) { long int from = (long int) floor(VECTOR(s)[i] / (no_of_nodes - 1)); long int to = (long int) (VECTOR(s)[i] - ((igraph_real_t)from) * (no_of_nodes - 1)); if (from == to) { to = no_of_nodes - 1; } igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } } else if (!directed && loops) { for (i = 0; i < slen; i++) { long int to = (long int) floor((sqrt(8 * VECTOR(s)[i] + 1) - 1) / 2); long int from = (long int) (VECTOR(s)[i] - (((igraph_real_t)to) * (to + 1)) / 2); igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } } else { /* !directed && !loops */ for (i = 0; i < slen; i++) { long int to = (long int) floor((sqrt(8 * VECTOR(s)[i] + 1) + 1) / 2); long int from = (long int) (VECTOR(s)[i] - (((igraph_real_t)to) * (to - 1)) / 2); igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } } igraph_vector_destroy(&s); IGRAPH_FINALLY_CLEAN(1); retval = igraph_create(graph, &edges, n, directed); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); } } return retval; } /** * \ingroup generators * \function igraph_erdos_renyi_game * \brief Generates a random (Erdős-Rényi) graph. * * \param graph Pointer to an uninitialized graph object. * \param type The type of the random graph, possible values: * \clist * \cli IGRAPH_ERDOS_RENYI_GNM * G(n,m) graph, * m edges are * selected uniformly randomly in a graph with * n vertices. * \cli IGRAPH_ERDOS_RENYI_GNP * G(n,p) graph, * every possible edge is included in the graph with * probability p. * \endclist * \param n The number of vertices in the graph. * \param p_or_m This is the p parameter for * G(n,p) graphs and the * m * parameter for G(n,m) graphs. * \param directed Logical, whether to generate a directed graph. * \param loops Logical, whether to generate loops (self) edges. * \return Error code: * \c IGRAPH_EINVAL: invalid * \p type, \p n, * \p p or \p m * parameter. * \c IGRAPH_ENOMEM: there is not enough * memory for the operation. * * Time complexity: O(|V|+|E|), the * number of vertices plus the number of edges in the graph. * * \sa \ref igraph_barabasi_game(), \ref igraph_growing_random_game() * * \example examples/simple/igraph_erdos_renyi_game.c */ int igraph_erdos_renyi_game(igraph_t *graph, igraph_erdos_renyi_t type, igraph_integer_t n, igraph_real_t p_or_m, igraph_bool_t directed, igraph_bool_t loops) { int retval = 0; if (type == IGRAPH_ERDOS_RENYI_GNP) { retval = igraph_erdos_renyi_game_gnp(graph, n, p_or_m, directed, loops); } else if (type == IGRAPH_ERDOS_RENYI_GNM) { retval = igraph_erdos_renyi_game_gnm(graph, n, p_or_m, directed, loops); } else { IGRAPH_ERROR("Invalid type", IGRAPH_EINVAL); } return retval; } leidenbase/src/core/games/establishment.c0000644000176200001440000001473514447675374020225 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_memory.h" #include "igraph_nongraph.h" #include "igraph_random.h" /** * \function igraph_establishment_game * \brief Generates a graph with a simple growing model with vertex types. * * * The simulation goes like this: a single vertex is added at each * time step. This new vertex tries to connect to \p k vertices in the * graph. The probability that such a connection is realized depends * on the types of the vertices involved. * * \param graph Pointer to an uninitialized graph. * \param nodes The number of vertices in the graph. * \param types The number of vertex types. * \param k The number of connections tried in each time step. * \param type_dist Vector giving the distribution of vertex types. * If \c NULL, the distribution is assumed to be uniform. * \param pref_matrix Matrix giving the connection probabilities for * different vertex types. * \param directed Logical, whether to generate a directed graph. * \param node_type_vec An initialized vector or \c NULL. * If not \c NULL, the type of each node will be stored here. * \return Error code. * * Added in version 0.2. * * Time complexity: O(|V|*k*log(|V|)), |V| is the number of vertices * and k is the \p k parameter. */ int igraph_establishment_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t types, igraph_integer_t k, const igraph_vector_t *type_dist, const igraph_matrix_t *pref_matrix, igraph_bool_t directed, igraph_vector_t *node_type_vec) { long int i, j; igraph_vector_t edges; igraph_vector_t cumdist; igraph_vector_t potneis; igraph_real_t maxcum; igraph_vector_t *nodetypes; /* Argument contracts */ if(nodes < 0){ IGRAPH_ERROR("The number of vertices must be non-negative.", IGRAPH_EINVAL); } if (types < 1) { IGRAPH_ERROR("The number of vertex types must be at least 1.", IGRAPH_EINVAL); } if (type_dist) { igraph_real_t lo; if (igraph_vector_size(type_dist) != types) { IGRAPH_ERROR("The vertex type distribution vector must agree in length with the number of types.", IGRAPH_EINVAL); } lo = igraph_vector_min(type_dist); if (lo < 0) { IGRAPH_ERROR("The vertex type distribution vector must not contain negative values.", IGRAPH_EINVAL); } if (igraph_is_nan(lo)) { IGRAPH_ERROR("The vertex type distribution vector must not contain NaN.", IGRAPH_EINVAL); } } if (igraph_matrix_nrow(pref_matrix) != types || igraph_matrix_ncol(pref_matrix) != types) { IGRAPH_ERROR("The preference matrix must be square and agree in dimensions with the number of types.", IGRAPH_EINVAL); } { igraph_real_t lo, hi; igraph_matrix_minmax(pref_matrix, &lo, &hi); if (lo < 0 || hi > 1) { IGRAPH_ERROR("The preference matrix must contain probabilities in [0, 1].", IGRAPH_EINVAL); } if (igraph_is_nan(lo) || igraph_is_nan(hi)) { IGRAPH_ERROR("The preference matrix must not contain NaN.", IGRAPH_EINVAL); } } if (! directed && ! igraph_matrix_is_symmetric(pref_matrix)) { IGRAPH_ERROR("The preference matrix must be symmetric when generating undirected graphs.", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&cumdist, types + 1); IGRAPH_VECTOR_INIT_FINALLY(&potneis, k); if (type_dist) { VECTOR(cumdist)[0] = 0; for (i = 0; i < types; ++i) { VECTOR(cumdist)[i + 1] = VECTOR(cumdist)[i] + VECTOR(*type_dist)[i]; } } else { for (i = 0; i < types+1; ++i) { VECTOR(cumdist)[i] = i; } } maxcum = igraph_vector_tail(&cumdist); if (maxcum <= 0) { IGRAPH_ERROR("The vertex type distribution vector must contain at least one positive value.", IGRAPH_EINVAL); } if (node_type_vec) { nodetypes = node_type_vec; IGRAPH_CHECK(igraph_vector_resize(nodetypes, nodes)); } else { nodetypes = IGRAPH_CALLOC(1, igraph_vector_t); if (! nodetypes) { IGRAPH_ERROR("Insufficient memory for establishment_game.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, nodetypes); IGRAPH_VECTOR_INIT_FINALLY(nodetypes, nodes); } RNG_BEGIN(); for (i = 0; i < nodes; i++) { igraph_real_t uni = RNG_UNIF(0, maxcum); long int type; igraph_vector_binsearch(&cumdist, uni, &type); VECTOR(*nodetypes)[i] = type - 1; } for (i = k; i < nodes; i++) { long int type1 = (long int) VECTOR(*nodetypes)[i]; igraph_random_sample(&potneis, 0, i - 1, k); for (j = 0; j < k; j++) { long int type2 = (long int) VECTOR(*nodetypes)[(long int)VECTOR(potneis)[j]]; if (RNG_UNIF01() < MATRIX(*pref_matrix, type1, type2)) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, VECTOR(potneis)[j])); } } } RNG_END(); if (! node_type_vec) { igraph_vector_destroy(nodetypes); IGRAPH_FREE(nodetypes); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_destroy(&potneis); igraph_vector_destroy(&cumdist); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/games/growing_random.c0000644000176200001440000000637414447675374020377 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_random.h" /** * \ingroup generators * \function igraph_growing_random_game * \brief Generates a growing random graph. * * * This function simulates a growing random graph. We start out with * one vertex. In each step a new vertex is added and a number of new * edges are also added. These graphs are known to be different * from standard (not growing) random graphs. * \param graph Uninitialized graph object. * \param n The number of vertices in the graph. * \param m The number of edges to add in a time step (i.e. after * adding a vertex). * \param directed Boolean, whether to generate a directed graph. * \param citation Boolean, if \c TRUE, the edges always * originate from the most recently added vertex and are * connected to a previous vertex. * \return Error code: * \c IGRAPH_EINVAL: invalid * \p n or \p m * parameter. * * Time complexity: O(|V|+|E|), the * number of vertices plus the number of edges. */ int igraph_growing_random_game(igraph_t *graph, igraph_integer_t n, igraph_integer_t m, igraph_bool_t directed, igraph_bool_t citation) { long int no_of_nodes = n; long int no_of_neighbors = m; long int no_of_edges; igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int resp = 0; long int i, j; if (n < 0) { IGRAPH_ERROR("Invalid number of vertices", IGRAPH_EINVAL); } if (m < 0) { IGRAPH_ERROR("Invalid number of edges per step (m)", IGRAPH_EINVAL); } no_of_edges = no_of_nodes > 0 ? (no_of_nodes - 1) * no_of_neighbors : 0; IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); RNG_BEGIN(); for (i = 1; i < no_of_nodes; i++) { for (j = 0; j < no_of_neighbors; j++) { if (citation) { long int to = RNG_INTEGER(0, i - 1); VECTOR(edges)[resp++] = i; VECTOR(edges)[resp++] = to; } else { long int from = RNG_INTEGER(0, i); long int to = RNG_INTEGER(1, i); VECTOR(edges)[resp++] = from; VECTOR(edges)[resp++] = to; } } } RNG_END(); IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/games/dotproduct.c0000644000176200001440000002167414447675374017552 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2014 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_random.h" #include "igraph_constructors.h" #include "igraph_blas.h" /** * \function igraph_dot_product_game * \brief Generates a random dot product graph. * * In this model, each vertex is represented by a latent * position vector. Probability of an edge between two vertices are given * by the dot product of their latent position vectors. * * * See also Christine Leigh Myers Nickel: Random dot product graphs, a * model for social networks. Dissertation, Johns Hopkins University, * Maryland, USA, 2006. * * \param graph The output graph is stored here. * \param vecs A matrix in which each latent position vector is a * column. The dot product of the latent position vectors should be * in the [0,1] interval, otherwise a warning is given. For * negative dot products, no edges are added; dot products that are * larger than one always add an edge. * \param directed Should the generated graph be directed? * \return Error code. * * Time complexity: O(n*n*m), where n is the number of vertices, * and m is the length of the latent vectors. * * \sa \ref igraph_sample_dirichlet(), \ref * igraph_sample_sphere_volume(), \ref igraph_sample_sphere_surface() * for functions to generate the latent vectors. */ int igraph_dot_product_game(igraph_t *graph, const igraph_matrix_t *vecs, igraph_bool_t directed) { igraph_integer_t nrow = igraph_matrix_nrow(vecs); igraph_integer_t ncol = igraph_matrix_ncol(vecs); int i, j; igraph_vector_t edges; igraph_bool_t warned_neg = 0, warned_big = 0; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); RNG_BEGIN(); for (i = 0; i < ncol; i++) { int from = directed ? 0 : i + 1; igraph_vector_t v1; igraph_vector_view(&v1, &MATRIX(*vecs, 0, i), nrow); for (j = from; j < ncol; j++) { igraph_real_t prob; igraph_vector_t v2; if (i == j) { continue; } igraph_vector_view(&v2, &MATRIX(*vecs, 0, j), nrow); igraph_blas_ddot(&v1, &v2, &prob); if (prob < 0 && ! warned_neg) { warned_neg = 1; IGRAPH_WARNING("Negative connection probability in " "dot-product graph"); } else if (prob > 1 && ! warned_big) { warned_big = 1; IGRAPH_WARNING("Greater than 1 connection probability in " "dot-product graph"); IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } else if (RNG_UNIF01() < prob) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } } } RNG_END(); igraph_create(graph, &edges, ncol, directed); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_sample_sphere_surface * Sample points uniformly from the surface of a sphere * * The center of the sphere is at the origin. * * \param dim The dimension of the random vectors. * \param n The number of vectors to sample. * \param radius Radius of the sphere, it must be positive. * \param positive Whether to restrict sampling to the positive * orthant. * \param res Pointer to an initialized matrix, the result is * stored here, each column will be a sampled vector. The matrix is * resized, as needed. * \return Error code. * * Time complexity: O(n*dim*g), where g is the time complexity of * generating a standard normal random number. * * \sa \ref igraph_sample_sphere_volume(), \ref * igraph_sample_dirichlet() for other similar samplers. */ int igraph_sample_sphere_surface(igraph_integer_t dim, igraph_integer_t n, igraph_real_t radius, igraph_bool_t positive, igraph_matrix_t *res) { igraph_integer_t i, j; if (dim < 2) { IGRAPH_ERROR("Sphere must be at least two dimensional to sample from " "surface", IGRAPH_EINVAL); } if (n < 0) { IGRAPH_ERROR("Number of samples must be non-negative", IGRAPH_EINVAL); } if (radius <= 0) { IGRAPH_ERROR("Sphere radius must be positive", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_resize(res, dim, n)); RNG_BEGIN(); for (i = 0; i < n; i++) { igraph_real_t *col = &MATRIX(*res, 0, i); igraph_real_t sum = 0.0; for (j = 0; j < dim; j++) { col[j] = RNG_NORMAL(0, 1); sum += col[j] * col[j]; } sum = sqrt(sum); for (j = 0; j < dim; j++) { col[j] = radius * col[j] / sum; } if (positive) { for (j = 0; j < dim; j++) { col[j] = fabs(col[j]); } } } RNG_END(); return 0; } /** * \function igraph_sample_sphere_volume * Sample points uniformly from the volume of a sphere * * The center of the sphere is at the origin. * * \param dim The dimension of the random vectors. * \param n The number of vectors to sample. * \param radius Radius of the sphere, it must be positive. * \param positive Whether to restrict sampling to the positive * orthant. * \param res Pointer to an initialized matrix, the result is * stored here, each column will be a sampled vector. The matrix is * resized, as needed. * \return Error code. * * Time complexity: O(n*dim*g), where g is the time complexity of * generating a standard normal random number. * * \sa \ref igraph_sample_sphere_surface(), \ref * igraph_sample_dirichlet() for other similar samplers. */ int igraph_sample_sphere_volume(igraph_integer_t dim, igraph_integer_t n, igraph_real_t radius, igraph_bool_t positive, igraph_matrix_t *res) { igraph_integer_t i, j; /* Arguments are checked by the following call */ IGRAPH_CHECK(igraph_sample_sphere_surface(dim, n, radius, positive, res)); RNG_BEGIN(); for (i = 0; i < n; i++) { igraph_real_t *col = &MATRIX(*res, 0, i); igraph_real_t U = pow(RNG_UNIF01(), 1.0 / dim); for (j = 0; j < dim; j++) { col[j] *= U; } } RNG_END(); return 0; } /** * \function igraph_sample_dirichlet * Sample points from a Dirichlet distribution * * \param n The number of vectors to sample. * \param alpha The parameters of the Dirichlet distribution. They * must be positive. The length of this vector gives the dimension * of the generated samples. * \param res Pointer to an initialized matrix, the result is stored * here, one sample in each column. It will be resized, as needed. * \return Error code. * * Time complexity: O(n * dim * g), where dim is the dimension of the * sample vectors, set by the length of alpha, and g is the time * complexity of sampling from a Gamma distribution. * * \sa \ref igraph_sample_sphere_surface() and * \ref igraph_sample_sphere_volume() for other methods to sample * latent vectors. */ int igraph_sample_dirichlet(igraph_integer_t n, const igraph_vector_t *alpha, igraph_matrix_t *res) { igraph_integer_t len = igraph_vector_size(alpha); igraph_integer_t i; igraph_vector_t vec; if (n < 0) { IGRAPH_ERROR("Number of samples should be non-negative", IGRAPH_EINVAL); } if (len < 2) { IGRAPH_ERROR("Dirichlet parameter vector too short, must " "have at least two entries", IGRAPH_EINVAL); } if (igraph_vector_min(alpha) <= 0) { IGRAPH_ERROR("Dirichlet concentration parameters must be positive", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_resize(res, len, n)); RNG_BEGIN(); for (i = 0; i < n; i++) { igraph_vector_view(&vec, &MATRIX(*res, 0, i), len); igraph_rng_get_dirichlet(igraph_rng_default(), alpha, &vec); } RNG_END(); return 0; } leidenbase/src/core/games/grg.c0000644000176200001440000001234214447675374016132 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_random.h" #include "core/interruption.h" /** * \function igraph_grg_game * \brief Generates a geometric random graph. * * A geometric random graph is created by dropping points (i.e. vertices) * randomly on the unit square and then connecting all those pairs * which are less than \c radius apart in Euclidean distance. * * * Original code contributed by Keith Briggs, thanks Keith. * * \param graph Pointer to an uninitialized graph object. * \param nodes The number of vertices in the graph. * \param radius The radius within which the vertices will be connected. * \param torus Logical constant. If true, periodic boundary conditions * will be used, i.e. the vertices are assumed to be on a torus * instead of a square. * \param x An initialized vector or \c NULL. If not \c NULL, the points' * x coordinates will be returned here. * \param y An initialized vector or \c NULL. If not \c NULL, the points' * y coordinates will be returned here. * \return Error code. * * Time complexity: TODO, less than O(|V|^2+|E|). * * \example examples/simple/igraph_grg_game.c */ int igraph_grg_game(igraph_t *graph, igraph_integer_t nodes, igraph_real_t radius, igraph_bool_t torus, igraph_vector_t *x, igraph_vector_t *y) { long int i; igraph_vector_t myx, myy, *xx = &myx, *yy = &myy, edges; igraph_real_t r2 = radius * radius; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, nodes)); if (x) { xx = x; IGRAPH_CHECK(igraph_vector_resize(xx, nodes)); } else { IGRAPH_VECTOR_INIT_FINALLY(xx, nodes); } if (y) { yy = y; IGRAPH_CHECK(igraph_vector_resize(yy, nodes)); } else { IGRAPH_VECTOR_INIT_FINALLY(yy, nodes); } RNG_BEGIN(); for (i = 0; i < nodes; i++) { VECTOR(*xx)[i] = RNG_UNIF01(); VECTOR(*yy)[i] = RNG_UNIF01(); } RNG_END(); igraph_vector_sort(xx); if (!torus) { for (i = 0; i < nodes; i++) { igraph_real_t xx1 = VECTOR(*xx)[i]; igraph_real_t yy1 = VECTOR(*yy)[i]; long int j = i + 1; igraph_real_t dx, dy; IGRAPH_ALLOW_INTERRUPTION(); while ( j < nodes && (dx = VECTOR(*xx)[j] - xx1) < radius) { dy = VECTOR(*yy)[j] - yy1; if (dx * dx + dy * dy < r2) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } j++; } } } else { for (i = 0; i < nodes; i++) { igraph_real_t xx1 = VECTOR(*xx)[i]; igraph_real_t yy1 = VECTOR(*yy)[i]; long int j = i + 1; igraph_real_t dx, dy; IGRAPH_ALLOW_INTERRUPTION(); while ( j < nodes && (dx = VECTOR(*xx)[j] - xx1) < radius) { dy = fabs(VECTOR(*yy)[j] - yy1); if (dx > 0.5) { dx = 1 - dx; } if (dy > 0.5) { dy = 1 - dy; } if (dx * dx + dy * dy < r2) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } j++; } if (j == nodes) { j = 0; while (j < i && (dx = 1 - xx1 + VECTOR(*xx)[j]) < radius && xx1 - VECTOR(*xx)[j] >= radius) { dy = fabs(VECTOR(*yy)[j] - yy1); if (dy > 0.5) { dy = 1 - dy; } if (dx * dx + dy * dy < r2) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } j++; } } } } if (!y) { igraph_vector_destroy(yy); IGRAPH_FINALLY_CLEAN(1); } if (!x) { igraph_vector_destroy(xx); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_CHECK(igraph_create(graph, &edges, nodes, IGRAPH_UNDIRECTED)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/games/degree_sequence.c0000644000176200001440000006745514447675374020515 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_adjlist.h" #include "igraph_constructors.h" #include "igraph_conversion.h" #include "igraph_graphicality.h" #include "igraph_memory.h" #include "igraph_random.h" #include "igraph_vector_ptr.h" #include "core/interruption.h" #include "core/set.h" static int igraph_i_degree_sequence_game_simple(igraph_t *graph, const igraph_vector_t *out_seq, const igraph_vector_t *in_seq) { long int outsum = 0, insum = 0; igraph_bool_t directed = (in_seq != 0 && igraph_vector_size(in_seq) != 0); igraph_bool_t degseq_ok; long int no_of_nodes, no_of_edges; long int *bag1 = 0, *bag2 = 0; long int bagp1 = 0, bagp2 = 0; igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int i, j; IGRAPH_CHECK(igraph_is_graphical(out_seq, in_seq, IGRAPH_LOOPS_SW | IGRAPH_MULTI_SW, °seq_ok)); if (!degseq_ok) { IGRAPH_ERROR(in_seq ? "No directed graph can realize the given degree sequences" : "No undirected graph can realize the given degree sequence", IGRAPH_EINVAL); } outsum = (long int) igraph_vector_sum(out_seq); if (directed) { insum = (long int) igraph_vector_sum(in_seq); } no_of_nodes = igraph_vector_size(out_seq); no_of_edges = directed ? outsum : outsum / 2; bag1 = IGRAPH_CALLOC(outsum, long int); if (bag1 == 0) { IGRAPH_ERROR("degree sequence game (simple)", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, bag1); for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < VECTOR(*out_seq)[i]; j++) { bag1[bagp1++] = i; } } if (directed) { bag2 = IGRAPH_CALLOC(insum, long int); if (bag2 == 0) { IGRAPH_ERROR("degree sequence game (simple)", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, bag2); for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < VECTOR(*in_seq)[i]; j++) { bag2[bagp2++] = i; } } } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); RNG_BEGIN(); if (directed) { for (i = 0; i < no_of_edges; i++) { long int from = RNG_INTEGER(0, bagp1 - 1); long int to = RNG_INTEGER(0, bagp2 - 1); igraph_vector_push_back(&edges, bag1[from]); /* safe, already reserved */ igraph_vector_push_back(&edges, bag2[to]); /* ditto */ bag1[from] = bag1[bagp1 - 1]; bag2[to] = bag2[bagp2 - 1]; bagp1--; bagp2--; } } else { for (i = 0; i < no_of_edges; i++) { long int from = RNG_INTEGER(0, bagp1 - 1); long int to; igraph_vector_push_back(&edges, bag1[from]); /* safe, already reserved */ bag1[from] = bag1[bagp1 - 1]; bagp1--; to = RNG_INTEGER(0, bagp1 - 1); igraph_vector_push_back(&edges, bag1[to]); /* ditto */ bag1[to] = bag1[bagp1 - 1]; bagp1--; } } RNG_END(); IGRAPH_FREE(bag1); IGRAPH_FINALLY_CLEAN(1); if (directed) { IGRAPH_FREE(bag2); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_degree_sequence_game_no_multiple_undirected( igraph_t *graph, const igraph_vector_t *seq) { igraph_vector_t stubs = IGRAPH_VECTOR_NULL; igraph_vector_int_t *neis; igraph_vector_t residual_degrees = IGRAPH_VECTOR_NULL; igraph_set_t incomplete_vertices; igraph_adjlist_t al; igraph_bool_t finished, failed; igraph_integer_t from, to, dummy; long int i, j, k; long int no_of_nodes, outsum = 0; igraph_bool_t degseq_ok; IGRAPH_CHECK(igraph_is_graphical(seq, 0, IGRAPH_SIMPLE_SW, °seq_ok)); if (!degseq_ok) { IGRAPH_ERROR("No simple undirected graph can realize the given degree sequence", IGRAPH_EINVAL); } outsum = (long int) igraph_vector_sum(seq); no_of_nodes = igraph_vector_size(seq); /* Allocate required data structures */ IGRAPH_CHECK(igraph_adjlist_init_empty(&al, (igraph_integer_t) no_of_nodes)); IGRAPH_FINALLY(igraph_adjlist_destroy, &al); IGRAPH_VECTOR_INIT_FINALLY(&stubs, 0); IGRAPH_CHECK(igraph_vector_reserve(&stubs, outsum)); IGRAPH_VECTOR_INIT_FINALLY(&residual_degrees, no_of_nodes); IGRAPH_CHECK(igraph_set_init(&incomplete_vertices, 0)); IGRAPH_FINALLY(igraph_set_destroy, &incomplete_vertices); /* Start the RNG */ RNG_BEGIN(); /* Outer loop; this will try to construct a graph several times from scratch * until it finally succeeds. */ finished = 0; while (!finished) { IGRAPH_ALLOW_INTERRUPTION(); /* Be optimistic :) */ failed = 0; /* Clear the adjacency list to get rid of the previous attempt (if any) */ igraph_adjlist_clear(&al); /* Initialize the residual degrees from the degree sequence */ IGRAPH_CHECK(igraph_vector_update(&residual_degrees, seq)); /* While there are some unconnected stubs left... */ while (!finished && !failed) { /* Construct the initial stub vector */ igraph_vector_clear(&stubs); for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < VECTOR(residual_degrees)[i]; j++) { igraph_vector_push_back(&stubs, i); } } /* Clear the skipped stub counters and the set of incomplete vertices */ igraph_vector_null(&residual_degrees); igraph_set_clear(&incomplete_vertices); /* Shuffle the stubs in-place */ igraph_vector_shuffle(&stubs); /* Connect the stubs where possible */ k = igraph_vector_size(&stubs); for (i = 0; i < k; ) { from = (igraph_integer_t) VECTOR(stubs)[i++]; to = (igraph_integer_t) VECTOR(stubs)[i++]; if (from > to) { dummy = from; from = to; to = dummy; } neis = igraph_adjlist_get(&al, from); if (from == to || igraph_vector_int_binsearch(neis, to, &j)) { /* Edge exists already */ VECTOR(residual_degrees)[from]++; VECTOR(residual_degrees)[to]++; IGRAPH_CHECK(igraph_set_add(&incomplete_vertices, from)); IGRAPH_CHECK(igraph_set_add(&incomplete_vertices, to)); } else { /* Insert the edge */ IGRAPH_CHECK(igraph_vector_int_insert(neis, j, to)); } } finished = igraph_set_empty(&incomplete_vertices); if (!finished) { /* We are not done yet; check if the remaining stubs are feasible. This * is done by enumerating all possible pairs and checking whether at * least one feasible pair is found. */ i = 0; failed = 1; while (failed && igraph_set_iterate(&incomplete_vertices, &i, &from)) { j = 0; while (igraph_set_iterate(&incomplete_vertices, &j, &to)) { if (from == to) { /* This is used to ensure that each pair is checked once only */ break; } if (from > to) { dummy = from; from = to; to = dummy; } neis = igraph_adjlist_get(&al, from); if (!igraph_vector_int_binsearch(neis, to, 0)) { /* Found a suitable pair, so we can continue */ failed = 0; break; } } } } } } /* Finish the RNG */ RNG_END(); /* Clean up */ igraph_set_destroy(&incomplete_vertices); igraph_vector_destroy(&residual_degrees); igraph_vector_destroy(&stubs); IGRAPH_FINALLY_CLEAN(3); /* Create the graph. We cannot use IGRAPH_ALL here for undirected graphs * because we did not add edges in both directions in the adjacency list. * We will use igraph_to_undirected in an extra step. */ IGRAPH_CHECK(igraph_adjlist(graph, &al, IGRAPH_OUT, 1)); IGRAPH_CHECK(igraph_to_undirected(graph, IGRAPH_TO_UNDIRECTED_EACH, 0)); /* Clear the adjacency list */ igraph_adjlist_destroy(&al); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } static int igraph_i_degree_sequence_game_no_multiple_directed(igraph_t *graph, const igraph_vector_t *out_seq, const igraph_vector_t *in_seq) { igraph_adjlist_t al; igraph_bool_t deg_seq_ok, failed, finished; igraph_vector_t in_stubs = IGRAPH_VECTOR_NULL; igraph_vector_t out_stubs = IGRAPH_VECTOR_NULL; igraph_vector_int_t *neis; igraph_vector_t residual_in_degrees = IGRAPH_VECTOR_NULL; igraph_vector_t residual_out_degrees = IGRAPH_VECTOR_NULL; igraph_set_t incomplete_in_vertices; igraph_set_t incomplete_out_vertices; igraph_integer_t from, to; long int i, j, k; long int no_of_nodes, outsum; IGRAPH_CHECK(igraph_is_graphical(out_seq, in_seq, IGRAPH_SIMPLE_SW, °_seq_ok)); if (!deg_seq_ok) { IGRAPH_ERROR("No simple directed graph can realize the given degree sequence", IGRAPH_EINVAL); } outsum = (long int) igraph_vector_sum(out_seq); no_of_nodes = igraph_vector_size(out_seq); /* Allocate required data structures */ IGRAPH_CHECK(igraph_adjlist_init_empty(&al, (igraph_integer_t) no_of_nodes)); IGRAPH_FINALLY(igraph_adjlist_destroy, &al); IGRAPH_VECTOR_INIT_FINALLY(&out_stubs, 0); IGRAPH_CHECK(igraph_vector_reserve(&out_stubs, outsum)); IGRAPH_VECTOR_INIT_FINALLY(&in_stubs, 0); IGRAPH_CHECK(igraph_vector_reserve(&in_stubs, outsum)); IGRAPH_VECTOR_INIT_FINALLY(&residual_out_degrees, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&residual_in_degrees, no_of_nodes); IGRAPH_CHECK(igraph_set_init(&incomplete_out_vertices, 0)); IGRAPH_FINALLY(igraph_set_destroy, &incomplete_out_vertices); IGRAPH_CHECK(igraph_set_init(&incomplete_in_vertices, 0)); IGRAPH_FINALLY(igraph_set_destroy, &incomplete_in_vertices); /* Start the RNG */ RNG_BEGIN(); /* Outer loop; this will try to construct a graph several times from scratch * until it finally succeeds. */ finished = 0; while (!finished) { IGRAPH_ALLOW_INTERRUPTION(); /* Be optimistic :) */ failed = 0; /* Clear the adjacency list to get rid of the previous attempt (if any) */ igraph_adjlist_clear(&al); /* Initialize the residual degrees from the degree sequences */ IGRAPH_CHECK(igraph_vector_update(&residual_out_degrees, out_seq)); IGRAPH_CHECK(igraph_vector_update(&residual_in_degrees, in_seq)); /* While there are some unconnected stubs left... */ while (!finished && !failed) { /* Construct the initial stub vectors */ igraph_vector_clear(&out_stubs); igraph_vector_clear(&in_stubs); for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < VECTOR(residual_out_degrees)[i]; j++) { igraph_vector_push_back(&out_stubs, i); } for (j = 0; j < VECTOR(residual_in_degrees)[i]; j++) { igraph_vector_push_back(&in_stubs, i); } } /* Clear the skipped stub counters and the set of incomplete vertices */ igraph_vector_null(&residual_out_degrees); igraph_vector_null(&residual_in_degrees); igraph_set_clear(&incomplete_out_vertices); igraph_set_clear(&incomplete_in_vertices); /* Shuffle the out-stubs in-place */ igraph_vector_shuffle(&out_stubs); /* Connect the stubs where possible */ k = igraph_vector_size(&out_stubs); for (i = 0; i < k; i++) { from = (igraph_integer_t) VECTOR(out_stubs)[i]; to = (igraph_integer_t) VECTOR(in_stubs)[i]; neis = igraph_adjlist_get(&al, from); if (from == to || igraph_vector_int_binsearch(neis, to, &j)) { /* Edge exists already */ VECTOR(residual_out_degrees)[from]++; VECTOR(residual_in_degrees)[to]++; IGRAPH_CHECK(igraph_set_add(&incomplete_out_vertices, from)); IGRAPH_CHECK(igraph_set_add(&incomplete_in_vertices, to)); } else { /* Insert the edge */ IGRAPH_CHECK(igraph_vector_int_insert(neis, j, to)); } } /* Are we finished? */ finished = igraph_set_empty(&incomplete_out_vertices); if (!finished) { /* We are not done yet; check if the remaining stubs are feasible. This * is done by enumerating all possible pairs and checking whether at * least one feasible pair is found. */ i = 0; failed = 1; while (failed && igraph_set_iterate(&incomplete_out_vertices, &i, &from)) { j = 0; while (igraph_set_iterate(&incomplete_in_vertices, &j, &to)) { neis = igraph_adjlist_get(&al, from); if (from != to && !igraph_vector_int_binsearch(neis, to, 0)) { /* Found a suitable pair, so we can continue */ failed = 0; break; } } } } } } /* Finish the RNG */ RNG_END(); /* Clean up */ igraph_set_destroy(&incomplete_in_vertices); igraph_set_destroy(&incomplete_out_vertices); igraph_vector_destroy(&residual_in_degrees); igraph_vector_destroy(&residual_out_degrees); igraph_vector_destroy(&in_stubs); igraph_vector_destroy(&out_stubs); IGRAPH_FINALLY_CLEAN(6); /* Create the graph */ IGRAPH_CHECK(igraph_adjlist(graph, &al, IGRAPH_OUT, 1)); /* Clear the adjacency list */ igraph_adjlist_destroy(&al); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* swap two elements of a vector_int */ #define SWAP_INT_ELEM(vec, i, j) \ { \ igraph_integer_t temp; \ temp = VECTOR(vec)[i]; \ VECTOR(vec)[i] = VECTOR(vec)[j]; \ VECTOR(vec)[j] = temp; \ } static int igraph_i_degree_sequence_game_no_multiple_undirected_uniform(igraph_t *graph, const igraph_vector_t *degseq) { igraph_vector_int_t stubs; igraph_vector_t edges; igraph_bool_t degseq_ok; igraph_vector_ptr_t adjlist; long i, j; long vcount, ecount, stub_count; IGRAPH_CHECK(igraph_is_graphical(degseq, NULL, IGRAPH_SIMPLE_SW, °seq_ok)); if (!degseq_ok) { IGRAPH_ERROR("No simple undirected graph can realize the given degree sequence", IGRAPH_EINVAL); } stub_count = (long) igraph_vector_sum(degseq); ecount = stub_count / 2; vcount = igraph_vector_size(degseq); IGRAPH_VECTOR_INT_INIT_FINALLY(&stubs, stub_count); IGRAPH_VECTOR_INIT_FINALLY(&edges, stub_count); /* Fill stubs vector. */ { long k = 0; for (i = 0; i < vcount; ++i) { long deg = (long) VECTOR(*degseq)[i]; for (j = 0; j < deg; ++j) { VECTOR(stubs)[k++] = i; } } } /* Build an adjacency list in terms of sets; used to check for multi-edges. */ IGRAPH_CHECK(igraph_vector_ptr_init(&adjlist, vcount)); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&adjlist, igraph_set_destroy); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &adjlist); for (i = 0; i < vcount; ++i) { igraph_set_t *set = IGRAPH_CALLOC(1, igraph_set_t); if (! set) { IGRAPH_ERROR("Out of memory", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_set_init(set, 0)); VECTOR(adjlist)[i] = set; IGRAPH_CHECK(igraph_set_reserve(set, (long) VECTOR(*degseq)[i])); } RNG_BEGIN(); for (;;) { igraph_bool_t success = 1; /* Shuffle stubs vector with Fisher-Yates and check for self-loops and multi-edges as we go. */ for (i = 0; i < ecount; ++i) { long k, from, to; k = RNG_INTEGER(2*i, stub_count-1); SWAP_INT_ELEM(stubs, 2*i, k); k = RNG_INTEGER(2*i+1, stub_count-1); SWAP_INT_ELEM(stubs, 2*i+1, k); from = VECTOR(stubs)[2*i]; to = VECTOR(stubs)[2*i+1]; /* self-loop, fail */ if (from == to) { success = 0; break; } /* multi-edge, fail */ if (igraph_set_contains((igraph_set_t *) VECTOR(adjlist)[to], from)) { success = 0; break; } /* sets are already reserved */ igraph_set_add((igraph_set_t *) VECTOR(adjlist)[to], from); igraph_set_add((igraph_set_t *) VECTOR(adjlist)[from], to); /* register edge */ VECTOR(edges)[2 * i] = from; VECTOR(edges)[2 * i + 1] = to; } if (success) { break; } /* Clear adjacency list. */ for (j = 0; j < vcount; ++j) { igraph_set_clear((igraph_set_t *) VECTOR(adjlist)[j]); } IGRAPH_ALLOW_INTERRUPTION(); } RNG_END(); igraph_vector_ptr_destroy_all(&adjlist); igraph_vector_int_destroy(&stubs); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(graph, &edges, vcount, /* directed = */ 0)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } static int igraph_i_degree_sequence_game_no_multiple_directed_uniform( igraph_t *graph, const igraph_vector_t *out_deg, const igraph_vector_t *in_deg) { igraph_vector_int_t out_stubs, in_stubs; igraph_vector_t edges; igraph_bool_t degseq_ok; igraph_vector_ptr_t adjlist; long i, j; long vcount, ecount; IGRAPH_CHECK(igraph_is_graphical(out_deg, in_deg, IGRAPH_SIMPLE_SW, °seq_ok)); if (!degseq_ok) { IGRAPH_ERROR("No simple directed graph can realize the given degree sequence", IGRAPH_EINVAL); } ecount = (long) igraph_vector_sum(out_deg); vcount = igraph_vector_size(out_deg); IGRAPH_VECTOR_INT_INIT_FINALLY(&out_stubs, ecount); IGRAPH_VECTOR_INT_INIT_FINALLY(&in_stubs, ecount); IGRAPH_VECTOR_INIT_FINALLY(&edges, 2 * ecount); /* Fill in- and out-stubs vectors. */ { long k = 0, l = 0; for (i = 0; i < vcount; ++i) { long dout, din; dout = (long) VECTOR(*out_deg)[i]; for (j = 0; j < dout; ++j) { VECTOR(out_stubs)[k++] = i; } din = (long) VECTOR(*in_deg)[i]; for (j = 0; j < din; ++j) { VECTOR(in_stubs)[l++] = i; } } } /* Build an adjacency list in terms of sets; used to check for multi-edges. */ IGRAPH_CHECK(igraph_vector_ptr_init(&adjlist, vcount)); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&adjlist, igraph_set_destroy); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &adjlist); for (i = 0; i < vcount; ++i) { igraph_set_t *set = IGRAPH_CALLOC(1, igraph_set_t); if (! set) { IGRAPH_ERROR("Out of memory", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_set_init(set, 0)); VECTOR(adjlist)[i] = set; IGRAPH_CHECK(igraph_set_reserve(set, (long) VECTOR(*out_deg)[i])); } RNG_BEGIN(); for (;;) { igraph_bool_t success = 1; /* Shuffle out-stubs vector with Fisher-Yates and check for self-loops and multi-edges as we go. */ for (i = 0; i < ecount; ++i) { long k, from, to; igraph_set_t *set; k = RNG_INTEGER(i, ecount-1); SWAP_INT_ELEM(out_stubs, i, k); from = VECTOR(out_stubs)[i]; to = VECTOR(in_stubs)[i]; /* self-loop, fail */ if (to == from) { success = 0; break; } /* multi-edge, fail */ set = (igraph_set_t *) VECTOR(adjlist)[from]; if (igraph_set_contains(set, to)) { success = 0; break; } /* sets are already reserved */ igraph_set_add(set, to); /* register edge */ VECTOR(edges)[2 * i] = from; VECTOR(edges)[2 * i + 1] = to; } if (success) { break; } /* Clear adjacency list. */ for (j = 0; j < vcount; ++j) { igraph_set_clear((igraph_set_t *) VECTOR(adjlist)[j]); } IGRAPH_ALLOW_INTERRUPTION(); } RNG_END(); igraph_vector_ptr_destroy_all(&adjlist); igraph_vector_int_destroy(&out_stubs); igraph_vector_int_destroy(&in_stubs); IGRAPH_FINALLY_CLEAN(3); IGRAPH_CHECK(igraph_create(graph, &edges, vcount, /* directed = */ 1)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } #undef SWAP_INT_ELEM /* This is in gengraph_mr-connected.cpp */ int igraph_degree_sequence_game_vl(igraph_t *graph, const igraph_vector_t *out_seq, const igraph_vector_t *in_seq); /** * \ingroup generators * \function igraph_degree_sequence_game * \brief Generates a random graph with a given degree sequence. * * \param graph Pointer to an uninitialized graph object. * \param out_deg The degree sequence for an undirected graph (if * \p in_seq is \c NULL or of length zero), or the out-degree * sequence of a directed graph (if \p in_deq is not * of length zero). * \param in_deg It is either a zero-length vector or * \c NULL (if an undirected * graph is generated), or the in-degree sequence. * \param method The method to generate the graph. Possible values: * \clist * \cli IGRAPH_DEGSEQ_SIMPLE * This method implements the configuration model. * For undirected graphs, it puts all vertex IDs in a bag * such that the multiplicity of a vertex in the bag is the same as * its degree. Then it draws pairs from the bag until the bag becomes * empty. This method may generate both loop (self) edges and multiple * edges. For directed graphs, the algorithm is basically the same, * but two separate bags are used for the in- and out-degrees. * Undirected graphs are generated with probability proportional to * (\prod_{i<j} A_{ij} ! \prod_i A_{ii} !!)^{-1}, * where \c A denotes the adjacency matrix and !! denotes * the double factorial. Here \c A is assumed to have twice the number of * self-loops on its diagonal. * The corresponding expression for directed graphs is * (\prod_{i,j} A_{ij}!)^{-1}. * Thus the probability of all simple graphs (which only have 0s and 1s * in the adjacency matrix) is the same, while that of * non-simple ones depends on their edge and self-loop multiplicities. * \cli IGRAPH_DEGSEQ_SIMPLE_NO_MULTIPLE * This method generates simple graphs. * It is similar to \c IGRAPH_DEGSEQ_SIMPLE * but tries to avoid multiple and loop edges and restarts the * generation from scratch if it gets stuck. It can generate all simple * realizations of a degree sequence, but it is not guaranteed * to sample them uniformly. This method is relatively fast and it will * eventually succeed if the provided degree sequence is graphical, * but there is no upper bound on the number of iterations. * \cli IGRAPH_DEGSEQ_SIMPLE_NO_MULTIPLE_UNIFORM * This method is identical to \c IGRAPH_DEGSEQ_SIMPLE, but if the * generated graph is not simple, it rejects it and re-starts the * generation. It generates all simple graphs with the same probability. * \cli IGRAPH_DEGSEQ_VL * This method samples undirected \em connected graphs approximately * uniformly. It is a Monte Carlo method based on degree-preserving * edge swaps. * This generator should be favoured if undirected and connected * graphs are to be generated and execution time is not a concern. * igraph uses the original implementation of Fabien Viger; for the algorithm, * see https://www-complexnetworks.lip6.fr/~latapy/FV/generation.html * and the paper https://arxiv.org/abs/cs/0502085 * \endclist * \return Error code: * \c IGRAPH_ENOMEM: there is not enough * memory to perform the operation. * \c IGRAPH_EINVAL: invalid method parameter, or * invalid in- and/or out-degree vectors. The degree vectors * should be non-negative, \p out_deg should sum * up to an even integer for undirected graphs; the length * and sum of \p out_deg and * \p in_deg * should match for directed graphs. * * Time complexity: O(|V|+|E|), the number of vertices plus the number of edges * for \c IGRAPH_DEGSEQ_SIMPLE. The time complexity of the * other modes is not known. * * \sa \ref igraph_barabasi_game(), \ref igraph_erdos_renyi_game(), * \ref igraph_is_graphical() * * \example examples/simple/igraph_degree_sequence_game.c */ int igraph_degree_sequence_game(igraph_t *graph, const igraph_vector_t *out_deg, const igraph_vector_t *in_deg, igraph_degseq_t method) { if (in_deg && igraph_vector_empty(in_deg) && !igraph_vector_empty(out_deg)) { in_deg = 0; } switch (method) { case IGRAPH_DEGSEQ_SIMPLE: return igraph_i_degree_sequence_game_simple(graph, out_deg, in_deg); case IGRAPH_DEGSEQ_VL: return igraph_degree_sequence_game_vl(graph, out_deg, in_deg); case IGRAPH_DEGSEQ_SIMPLE_NO_MULTIPLE: if (in_deg == 0) { return igraph_i_degree_sequence_game_no_multiple_undirected(graph, out_deg); } else { return igraph_i_degree_sequence_game_no_multiple_directed(graph, out_deg, in_deg); } case IGRAPH_DEGSEQ_SIMPLE_NO_MULTIPLE_UNIFORM: if (in_deg == 0) { return igraph_i_degree_sequence_game_no_multiple_undirected_uniform(graph, out_deg); } else { return igraph_i_degree_sequence_game_no_multiple_directed_uniform(graph, out_deg, in_deg); } default: IGRAPH_ERROR("Invalid degree sequence game method", IGRAPH_EINVAL); } } leidenbase/src/core/games/watts_strogatz.c0000644000176200001440000000701714447675374020455 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_interface.h" /** * \function igraph_watts_strogatz_game * \brief The Watts-Strogatz small-world model. * * This function generates a graph according to the Watts-Strogatz * model of small-world networks. The graph is obtained by creating a * circular undirected lattice and then rewire the edges randomly with * a constant probability. * * See also: Duncan J Watts and Steven H Strogatz: * Collective dynamics of small world networks, Nature * 393, 440-442, 1998. * * \param graph The graph to initialize. * \param dim The dimension of the lattice. * \param size The size of the lattice along each dimension. * \param nei The size of the neighborhood for each vertex. This is * the same as the \p nei argument of \ref * igraph_connect_neighborhood(). * \param p The rewiring probability. A real number between zero and * one (inclusive). * \param loops Logical, whether to generate loop edges. * \param multiple Logical, whether to allow multiple edges in the * generated graph. * \return Error code. * * \sa \ref igraph_lattice(), \ref igraph_connect_neighborhood() and * \ref igraph_rewire_edges() can be used if more flexibility is * needed, e.g. a different type of lattice. * * Time complexity: O(|V|*d^o+|E|), |V| and |E| are the number of * vertices and edges, d is the average degree, o is the \p nei * argument. */ int igraph_watts_strogatz_game(igraph_t *graph, igraph_integer_t dim, igraph_integer_t size, igraph_integer_t nei, igraph_real_t p, igraph_bool_t loops, igraph_bool_t multiple) { igraph_vector_t dimvector; long int i; if (dim < 1) { IGRAPH_ERROR("WS game: dimension should be at least one", IGRAPH_EINVAL); } if (size < 1) { IGRAPH_ERROR("WS game: lattice size should be at least one", IGRAPH_EINVAL); } if (p < 0 || p > 1) { IGRAPH_ERROR("WS game: rewiring probability should be between 0 and 1", IGRAPH_EINVAL); } /* Create the lattice first */ IGRAPH_VECTOR_INIT_FINALLY(&dimvector, dim); for (i = 0; i < dim; i++) { VECTOR(dimvector)[i] = size; } IGRAPH_CHECK(igraph_lattice(graph, &dimvector, nei, IGRAPH_UNDIRECTED, 0 /* mutual */, 1 /* circular */)); igraph_vector_destroy(&dimvector); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, graph); /* Rewire the edges then */ IGRAPH_CHECK(igraph_rewire_edges(graph, p, loops, multiple)); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/games/correlated.c0000644000176200001440000003010014447675374017467 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_conversion.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_qsort.h" #include "igraph_random.h" #include "igraph_structural.h" #include "core/interruption.h" /* The "code" of an edge is a single index representing its location in the adjacency matrix, * More specifically, the relevant parts of the adjacency matrix (i.e. non-diagonal in directed, * upper triangular in undirecred) are column-wise concatenated into an array. The "code" is * the index in this array. We use floating point numbers for the code, as it can easily * exceed integers representable on 32 bits. */ #define D_CODE(f,t) (((t)==no_of_nodes-1 ? (f) : (t)) * no_of_nodes + (f)) #define U_CODE(f,t) ((t) * ((t)-1) / 2 + (f)) #define CODE(f,t) (directed ? D_CODE((double)(f),(double)(t)) : U_CODE((double)(f),(double)(t))) /* TODO: Slight speedup may be possible if repeated vertex count queries are avoided. */ static int code_cmp(void *graph, const void *va, const void *vb) { const igraph_real_t *a = (const igraph_real_t *) va; const igraph_real_t *b = (const igraph_real_t *) vb; const long int no_of_nodes = igraph_vcount((igraph_t *) graph); const igraph_bool_t directed = igraph_is_directed((igraph_t *) graph); const igraph_real_t codea = CODE(a[0], a[1]); const igraph_real_t codeb = CODE(b[0], b[1]); if (codea < codeb) { return -1; } else if (codea > codeb) { return 1; } else { return 0; } } /* Sort an edge vector by edge codes. */ static void sort_edges(igraph_vector_t *edges, const igraph_t *graph) { igraph_qsort_r(VECTOR(*edges), igraph_vector_size(edges) / 2, 2*sizeof(igraph_real_t), (void *) graph, code_cmp); } /** * \function igraph_correlated_game * \brief Generates a random graph correlated to an existing graph. * * Sample a new graph by perturbing the adjacency matrix of a * given simple graph and shuffling its vertices. * * \param old_graph The original graph, it must be simple. * \param new_graph The new graph will be stored here. * \param corr A scalar in the unit interval [0,1], the target Pearson * correlation between the adjacency matrices of the original and the * generated graph (the adjacency matrix being used as a vector). * \param p A numeric scalar, the probability of an edge between two * vertices, it must in the open (0,1) interval. Typically, * the density of \p old_graph. * \param permutation A permutation to apply to the vertices of the * generated graph. It can also be a null pointer, in which case * the vertices will not be permuted. * \return Error code * * \sa \ref igraph_correlated_pair_game() for generating a pair * of correlated random graphs in one go. */ int igraph_correlated_game(const igraph_t *old_graph, igraph_t *new_graph, igraph_real_t corr, igraph_real_t p, const igraph_vector_t *permutation) { long int no_of_nodes = igraph_vcount(old_graph); long int no_of_edges = igraph_ecount(old_graph); igraph_bool_t directed = igraph_is_directed(old_graph); igraph_real_t no_of_all = directed ? no_of_nodes * (no_of_nodes - 1) : no_of_nodes * (no_of_nodes - 1) / 2; igraph_real_t no_of_missing = no_of_all - no_of_edges; igraph_real_t q = p + corr * (1 - p); igraph_real_t p_del = 1 - q; igraph_real_t p_add = ((1 - q) * (p / (1 - p))); igraph_vector_t add, delete, edges, newedges; igraph_real_t last; long int p_e = 0, p_a = 0, p_d = 0, no_add, no_del; igraph_real_t inf = IGRAPH_INFINITY; igraph_real_t next_e, next_a, next_d; long int i; igraph_bool_t simple; if (corr < 0 || corr > 1) { IGRAPH_ERRORF("Correlation must be in [0,1] in correlated Erdos-Renyi game, got %g.", IGRAPH_EINVAL, corr); } if (p <= 0 || p >= 1) { IGRAPH_ERRORF("Edge probability must be in (0,1) in correlated Erdos-Renyi game, got %g.", IGRAPH_EINVAL, p); } if (permutation) { if (igraph_vector_size(permutation) != no_of_nodes) { IGRAPH_ERROR("Invalid permutation length in correlated Erdos-Renyi game.", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_is_simple(old_graph, &simple)); if (! simple) { IGRAPH_ERROR("The original graph must be simple for correlated Erdos-Renyi game.", IGRAPH_EINVAL); } /* Special cases */ if (corr == 0) { return igraph_erdos_renyi_game(new_graph, IGRAPH_ERDOS_RENYI_GNP, no_of_nodes, p, directed, IGRAPH_NO_LOOPS); } if (corr == 1) { /* We don't copy, because we don't need the attributes.... */ IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); IGRAPH_CHECK(igraph_get_edgelist(old_graph, &edges, /* bycol= */ 0)); if (permutation) { int newec = igraph_vector_size(&edges); for (i = 0; i < newec; i++) { int tmp = VECTOR(edges)[i]; VECTOR(edges)[i] = VECTOR(*permutation)[tmp]; } } IGRAPH_CHECK(igraph_create(new_graph, &edges, no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } IGRAPH_VECTOR_INIT_FINALLY(&newedges, 0); IGRAPH_VECTOR_INIT_FINALLY(&add, 0); IGRAPH_VECTOR_INIT_FINALLY(&delete, 0); IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); IGRAPH_CHECK(igraph_get_edgelist(old_graph, &edges, /* bycol= */ 0)); /* The samping method used is analogous to the one in igraph_erdos_renyi_game_gnp(), * and assumes that the edge list of the old graph is in order of increasing "codes". * Even IGRAPH_EDGEORDER_TO does not guarantee this, therefore we sort explicitly. */ sort_edges(&edges, old_graph); RNG_BEGIN(); if (p_del > 0) { last = RNG_GEOM(p_del); while (last < no_of_edges) { IGRAPH_CHECK(igraph_vector_push_back(&delete, last)); last += RNG_GEOM(p_del); last += 1; } } no_del = igraph_vector_size(&delete); if (p_add > 0) { last = RNG_GEOM(p_add); while (last < no_of_missing) { IGRAPH_CHECK(igraph_vector_push_back(&add, last)); last += RNG_GEOM(p_add); last += 1; } } no_add = igraph_vector_size(&add); RNG_END(); /* Now we are merging the original edges, the edges that are removed, and the new edges. We have the following pointers: - p_a: the next edge to add - p_d: the next edge to delete - p_e: the next original edge - next_e: the code of the next edge in 'edges' - next_a: the code of the next edge to add - next_d: the code of the next edge to delete */ #define CODEE() (CODE(VECTOR(edges)[2*p_e], VECTOR(edges)[2*p_e+1])) /* First we (re)code the edges to delete */ for (i = 0; i < no_del; i++) { int td = VECTOR(delete)[i]; int from = VECTOR(edges)[2 * td]; int to = VECTOR(edges)[2 * td + 1]; VECTOR(delete)[i] = CODE(from, to); } IGRAPH_CHECK(igraph_vector_reserve(&newedges, (no_of_edges - no_del + no_add) * 2)); /* Now we can do the merge. Additional edges are tricky, because the code must be shifted by the edges in the original graph. */ #define UPD_E() \ { if (p_e < no_of_edges) { next_e=CODEE(); } else { next_e = inf; } } #define UPD_A() \ { if (p_a < no_add) { \ next_a = VECTOR(add)[p_a] + p_e; } else { next_a = inf; } } #define UPD_D() \ { if (p_d < no_del) { \ next_d = VECTOR(delete)[p_d]; } else { next_d = inf; } } UPD_E(); UPD_A(); UPD_D(); while (next_e != inf || next_a != inf || next_d != inf) { IGRAPH_ALLOW_INTERRUPTION(); if (next_e <= next_a && next_e < next_d) { /* keep an edge */ IGRAPH_CHECK(igraph_vector_push_back(&newedges, VECTOR(edges)[2 * p_e])); IGRAPH_CHECK(igraph_vector_push_back(&newedges, VECTOR(edges)[2 * p_e + 1])); p_e ++; UPD_E(); UPD_A() } else if (next_e <= next_a && next_e == next_d) { /* delete an edge */ p_e ++; UPD_E(); UPD_A(); p_d++; UPD_D(); } else { /* add an edge */ long int to, from; IGRAPH_ASSERT(igraph_finite(next_a)); if (directed) { to = (long int) floor(next_a / no_of_nodes); from = (long int) (next_a - ((igraph_real_t)to) * no_of_nodes); if (from == to) { to = no_of_nodes - 1; } } else { to = (long int) floor((sqrt(8 * next_a + 1) + 1) / 2); from = (long int) (next_a - (((igraph_real_t)to) * (to - 1)) / 2); } IGRAPH_CHECK(igraph_vector_push_back(&newedges, from)); IGRAPH_CHECK(igraph_vector_push_back(&newedges, to)); p_a++; UPD_A(); } } igraph_vector_destroy(&edges); igraph_vector_destroy(&add); igraph_vector_destroy(&delete); IGRAPH_FINALLY_CLEAN(3); if (permutation) { long int newec = igraph_vector_size(&newedges); for (i = 0; i < newec; i++) { long int tmp = VECTOR(newedges)[i]; VECTOR(newedges)[i] = VECTOR(*permutation)[tmp]; } } IGRAPH_CHECK(igraph_create(new_graph, &newedges, no_of_nodes, directed)); igraph_vector_destroy(&newedges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } #undef D_CODE #undef U_CODE #undef CODE #undef CODEE #undef UPD_E #undef UPD_A #undef UPD_D /** * \function igraph_correlated_pair_game * \brief Generates pairs of correlated random graphs. * * Sample two random graphs, with given correlation. * * \param graph1 The first graph will be stored here. * \param graph2 The second graph will be stored here. * \param n The number of vertices in both graphs. * \param corr A scalar in the unit interval, the target Pearson * correlation between the adjacency matrices of the original the * generated graph (the adjacency matrix being used as a vector). * \param p A numeric scalar, the probability of an edge between two * vertices, it must in the open (0,1) interval. * \param directed Whether to generate directed graphs. * \param permutation A permutation to apply to the vertices of the * second graph. It can also be a null pointer, in which case * the vertices will not be permuted. * \return Error code * * \sa \ref igraph_correlated_game() for generating a correlated pair * to a given graph. */ int igraph_correlated_pair_game(igraph_t *graph1, igraph_t *graph2, igraph_integer_t n, igraph_real_t corr, igraph_real_t p, igraph_bool_t directed, const igraph_vector_t *permutation) { IGRAPH_CHECK(igraph_erdos_renyi_game(graph1, IGRAPH_ERDOS_RENYI_GNP, n, p, directed, IGRAPH_NO_LOOPS)); IGRAPH_CHECK(igraph_correlated_game(graph1, graph2, corr, p, permutation)); return IGRAPH_SUCCESS; } leidenbase/src/core/games/callaway_traits.c0000644000176200001440000001610014447675374020532 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_memory.h" #include "igraph_random.h" /** * \function igraph_callaway_traits_game * \brief Simulates a growing network with vertex types. * * * The different types of vertices prefer to connect other types of * vertices with a given probability. * * * The simulation goes like this: in each discrete time step a new * vertex is added to the graph. The type of this vertex is generated * based on \p type_dist. Then two vertices are selected uniformly * randomly from the graph. The probability that they will be * connected depends on the types of these vertices and is taken from * \p pref_matrix. Then another two vertices are selected and this is * repeated \p edges_per_step times in each time step. * * * References: * * * D. S. Callaway, J. E. Hopcroft, J. M. Kleinberg, M. E. J. Newman, and S. H. Strogatz, * Are randomly grown graphs really random? * Phys. Rev. E 64, 041902 (2001). * https://doi.org/10.1103/PhysRevE.64.041902 * * \param graph Pointer to an uninitialized graph. * \param nodes The number of nodes in the graph. * \param types Number of node types. * \param edges_per_step The number of connections tried in each time step. * \param type_dist Vector giving the distribution of the vertex types. * If \c NULL, the distribution is assumed to be uniform. * \param pref_matrix Matrix giving the connection probabilities for * the vertex types. * \param directed Logical, whether to generate a directed graph. * \param node_type_vec An initialized vector or \c NULL. * If not \c NULL, the type of each node will be stored here. * \return Error code. * * Added in version 0.2. * * Time complexity: O(|V|*k*log(|V|)), |V| is the number of vertices, * k is \p edges_per_step. */ int igraph_callaway_traits_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t types, igraph_integer_t edges_per_step, const igraph_vector_t *type_dist, const igraph_matrix_t *pref_matrix, igraph_bool_t directed, igraph_vector_t *node_type_vec) { long int i, j; igraph_vector_t edges; igraph_vector_t cumdist; igraph_real_t maxcum; igraph_vector_t *nodetypes; /* Argument contracts */ if(nodes < 0){ IGRAPH_ERROR("The number of vertices must be non-negative.", IGRAPH_EINVAL); } if (types < 1) { IGRAPH_ERROR("The number of vertex types must be at least 1.", IGRAPH_EINVAL); } if (type_dist) { igraph_real_t lo; if (igraph_vector_size(type_dist) != types) { IGRAPH_ERROR("The vertex type distribution vector must agree in length with the number of types.", IGRAPH_EINVAL); } lo = igraph_vector_min(type_dist); if (lo < 0) { IGRAPH_ERROR("The vertex type distribution vector must not contain negative values.", IGRAPH_EINVAL); } if (igraph_is_nan(lo)) { IGRAPH_ERROR("The vertex type distribution vector must not contain NaN.", IGRAPH_EINVAL); } } if (igraph_matrix_nrow(pref_matrix) != types || igraph_matrix_ncol(pref_matrix) != types) { IGRAPH_ERROR("The preference matrix must be square and agree in dimensions with the number of types.", IGRAPH_EINVAL); } { igraph_real_t lo, hi; igraph_matrix_minmax(pref_matrix, &lo, &hi); if (lo < 0 || hi > 1) { IGRAPH_ERROR("The preference matrix must contain probabilities in [0, 1].", IGRAPH_EINVAL); } if (igraph_is_nan(lo) || igraph_is_nan(hi)) { IGRAPH_ERROR("The preference matrix must not contain NaN.", IGRAPH_EINVAL); } } if (! directed && ! igraph_matrix_is_symmetric(pref_matrix)) { IGRAPH_ERROR("The preference matrix must be symmetric when generating undirected graphs.", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&cumdist, types + 1); if (type_dist) { VECTOR(cumdist)[0] = 0; for (i = 0; i < types; ++i) { VECTOR(cumdist)[i + 1] = VECTOR(cumdist)[i] + VECTOR(*type_dist)[i]; } } else { for (i = 0; i < types+1; ++i) { VECTOR(cumdist)[i] = i; } } maxcum = igraph_vector_tail(&cumdist); if (maxcum <= 0) { IGRAPH_ERROR("The vertex type distribution vector must contain at least one positive value.", IGRAPH_EINVAL); } if (node_type_vec) { nodetypes = node_type_vec; IGRAPH_CHECK(igraph_vector_resize(nodetypes, nodes)); } else { nodetypes = IGRAPH_CALLOC(1, igraph_vector_t); if (! nodetypes) { IGRAPH_ERROR("Insufficient memory for callaway_traits_game.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, nodetypes); IGRAPH_VECTOR_INIT_FINALLY(nodetypes, nodes); } RNG_BEGIN(); for (i = 0; i < nodes; i++) { igraph_real_t uni = RNG_UNIF(0, maxcum); long int type; igraph_vector_binsearch(&cumdist, uni, &type); VECTOR(*nodetypes)[i] = type - 1; } for (i = 1; i < nodes; i++) { for (j = 0; j < edges_per_step; j++) { long int node1 = RNG_INTEGER(0, i); long int node2 = RNG_INTEGER(0, i); long int type1 = (long int) VECTOR(*nodetypes)[node1]; long int type2 = (long int) VECTOR(*nodetypes)[node2]; /* printf("unif: %f, %f, types: %li, %li\n", uni1, uni2, type1, type2); */ if (RNG_UNIF01() < MATRIX(*pref_matrix, type1, type2)) { IGRAPH_CHECK(igraph_vector_push_back(&edges, node1)); IGRAPH_CHECK(igraph_vector_push_back(&edges, node2)); } } } RNG_END(); if (! node_type_vec) { igraph_vector_destroy(nodetypes); IGRAPH_FREE(nodetypes); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_destroy(&cumdist); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/games/tree.c0000644000176200001440000001423214447675374016312 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_random.h" /* Uniform sampling of labelled trees (igraph_tree_game) */ /* The following implementation uniformly samples Prufer trees and converts * them to trees. */ static int igraph_i_tree_game_prufer(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed) { igraph_vector_int_t prufer; long i; if (directed) { IGRAPH_ERROR("The Prufer method for random tree generation does not support directed trees", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_int_init(&prufer, n - 2)); IGRAPH_FINALLY(igraph_vector_int_destroy, &prufer); RNG_BEGIN(); for (i = 0; i < n - 2; ++i) { VECTOR(prufer)[i] = RNG_INTEGER(0, n - 1); } RNG_END(); IGRAPH_CHECK(igraph_from_prufer(graph, &prufer)); igraph_vector_int_destroy(&prufer); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* The following implementation is based on loop-erased random walks and Wilson's algorithm * for uniformly sampling spanning trees. We effectively sample spanning trees of the complete * graph. */ /* swap two elements of a vector_int */ #define SWAP_INT_ELEM(vec, i, j) \ { \ igraph_integer_t temp; \ temp = VECTOR(vec)[i]; \ VECTOR(vec)[i] = VECTOR(vec)[j]; \ VECTOR(vec)[j] = temp; \ } static int igraph_i_tree_game_loop_erased_random_walk(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed) { igraph_vector_t edges; igraph_vector_int_t vertices; igraph_vector_bool_t visited; long i, j, k; IGRAPH_VECTOR_INIT_FINALLY(&edges, 2 * (n - 1)); IGRAPH_CHECK(igraph_vector_bool_init(&visited, n)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &visited); /* The vertices vector contains visited vertices between 0..k-1, unvisited ones between k..n-1. */ IGRAPH_CHECK(igraph_vector_int_init_seq(&vertices, 0, n - 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vertices); RNG_BEGIN(); /* A simple implementation could be as below. This is for illustration only. * The actually implemented algorithm avoids unnecessary walking on the already visited * portion of the vertex set. */ /* // pick starting point for the walk i = RNG_INTEGER(0, n-1); VECTOR(visited)[i] = 1; k=1; while (k < n) { // pick next vertex in the walk j = RNG_INTEGER(0, n-1); // if it has not been visited before, connect to the previous vertex in the sequence if (! VECTOR(visited)[j]) { VECTOR(edges)[2*k - 2] = i; VECTOR(edges)[2*k - 1] = j; VECTOR(visited)[j] = 1; k++; } i=j; } */ i = RNG_INTEGER(0, n - 1); VECTOR(visited)[i] = 1; SWAP_INT_ELEM(vertices, 0, i); for (k = 1; k < n; ++k) { j = RNG_INTEGER(0, n - 1); if (VECTOR(visited)[VECTOR(vertices)[j]]) { i = VECTOR(vertices)[j]; j = RNG_INTEGER(k, n - 1); } VECTOR(visited)[VECTOR(vertices)[j]] = 1; SWAP_INT_ELEM(vertices, k, j); VECTOR(edges)[2 * k - 2] = i; i = VECTOR(vertices)[k]; VECTOR(edges)[2 * k - 1] = i; } RNG_END(); IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); igraph_vector_int_destroy(&vertices); igraph_vector_bool_destroy(&visited); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } #undef SWAP_INT_ELEM /** * \ingroup generators * \function igraph_tree_game * \brief Generates a random tree with the given number of nodes. * * This function samples uniformly from the set of labelled trees, * i.e. it generates each labelled tree with the same probability. * * * Note that for n=0, the null graph is returned, * which is not considered to be a tree by \ref igraph_is_tree(). * * \param graph Pointer to an uninitialized graph object. * \param n The number of nodes in the tree. * \param directed Whether to create a directed tree. The edges are oriented away from the root. * \param method The algorithm to use to generate the tree. Possible values: * \clist * \cli IGRAPH_RANDOM_TREE_PRUFER * This algorithm samples Prüfer sequences uniformly, then converts them to trees. * Directed trees are not currently supported. * \cli IGRAPH_RANDOM_LERW * This algorithm effectively performs a loop-erased random walk on the complete graph * to uniformly sample its spanning trees (Wilson's algorithm). * \endclist * \return Error code: * \c IGRAPH_ENOMEM: there is not enough * memory to perform the operation. * \c IGRAPH_EINVAL: invalid tree size * * \sa \ref igraph_from_prufer() * */ int igraph_tree_game(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, igraph_random_tree_t method) { if (n < 2) { IGRAPH_CHECK(igraph_empty(graph, n, directed)); return IGRAPH_SUCCESS; } switch (method) { case IGRAPH_RANDOM_TREE_PRUFER: return igraph_i_tree_game_prufer(graph, n, directed); case IGRAPH_RANDOM_TREE_LERW: return igraph_i_tree_game_loop_erased_random_walk(graph, n, directed); default: IGRAPH_ERROR("Invalid method for random tree construction", IGRAPH_EINVAL); } } leidenbase/src/core/games/degree_sequence_vl/0000755000176200001440000000000014532173045021010 5ustar liggesusersleidenbase/src/core/games/degree_sequence_vl/gengraph_graph_molloy_hash.cpp0000644000176200001440000010230514447675374027110 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gengraph_definitions.h" #include #include #include #include #include #include "gengraph_qsort.h" #include "gengraph_hash.h" #include "gengraph_degree_sequence.h" #include "gengraph_graph_molloy_hash.h" #include "config.h" #include "core/math.h" #include "igraph_constructors.h" #include "igraph_error.h" #include "igraph_statusbar.h" #include "igraph_progress.h" namespace gengraph { //_________________________________________________________________________ void graph_molloy_hash::compute_neigh() { int *p = links; for (int i = 0; i < n; i++) { neigh[i] = p; p += HASH_SIZE(deg[i]); } } //_________________________________________________________________________ void graph_molloy_hash::compute_size() { size = 0; for (int i = 0; i < n; i++) { size += HASH_SIZE(deg[i]); } } //_________________________________________________________________________ void graph_molloy_hash::init() { for (int i = 0; i < size; i++) { links[i] = HASH_NONE; } } //_________________________________________________________________________ graph_molloy_hash::graph_molloy_hash(degree_sequence °s) { igraph_status("Allocating memory for graph...", 0); int s = alloc(degs); igraph_statusf("%d bytes allocated successfully\n", 0, s); } //_________________________________________________________________________ int graph_molloy_hash::alloc(degree_sequence °s) { n = degs.size(); a = degs.sum(); assert(a % 2 == 0); deg = degs.seq(); compute_size(); deg = new int[n + size]; if (deg == NULL) { return 0; } int i; for (i = 0; i < n; i++) { deg[i] = degs[i]; } links = deg + n; init(); neigh = new int*[n]; if (neigh == NULL) { return 0; } compute_neigh(); return sizeof(int *)*n + sizeof(int) * (n + size); } //_________________________________________________________________________ graph_molloy_hash::~graph_molloy_hash() { if (deg != NULL) { delete[] deg; } if (neigh != NULL) { delete[] neigh; } deg = NULL; neigh = NULL; } //_________________________________________________________________________ graph_molloy_hash::graph_molloy_hash(int *svg) { // Read n n = *(svg++); // Read a a = *(svg++); assert(a % 2 == 0); // Read degree sequence degree_sequence dd(n, svg); // Build neigh[] and alloc links[] alloc(dd); dd.detach(); // Read links[] restore(svg + n); } //_________________________________________________________________________ int *graph_molloy_hash::hard_copy() { int *hc = new int[2 + n + a / 2]; // to store n,a,deg[] and links[] hc[0] = n; hc[1] = a; memcpy(hc + 2, deg, sizeof(int)*n); int *p = hc + 2 + n; int *l = links; for (int i = 0; i < n; i++) for (int j = HASH_SIZE(deg[i]); j--; l++) { int d; if ((d = *l) != HASH_NONE && d >= i) { *(p++) = d; } } assert(p == hc + 2 + n + a / 2); return hc; } //_________________________________________________________________________ bool graph_molloy_hash::is_connected() { bool *visited = new bool[n]; int *buff = new int[n]; int comp_size = depth_search(visited, buff); delete[] visited; delete[] buff; return (comp_size == n); } //_________________________________________________________________________ int* graph_molloy_hash::backup() { int *b = new int[a / 2]; int *c = b; int *p = links; for (int i = 0; i < n; i++) for (int d = HASH_SIZE(deg[i]); d--; p++) if (*p != HASH_NONE && *p > i) { *(c++) = *p; } assert(c == b + (a / 2)); return b; } //_________________________________________________________________________ void graph_molloy_hash::restore(int* b) { init(); int i; int *dd = new int[n]; memcpy(dd, deg, sizeof(int)*n); for (i = 0; i < n; i++) { deg[i] = 0; } for (i = 0; i < n - 1; i++) { while (deg[i] < dd[i]) { add_edge(i, *b, dd); b++; } } delete[] dd; } //_________________________________________________________________________ bool graph_molloy_hash::isolated(int v, int K, int *Kbuff, bool *visited) { if (K < 2) { return false; } #ifdef OPT_ISOLATED if (K <= deg[v] + 1) { return false; } #endif //OPT_ISOLATED int *seen = Kbuff; int *known = Kbuff; int *max = Kbuff + K; *(known++) = v; visited[v] = true; bool is_isolated = true; while (known != seen) { v = *(seen++); int *ww = neigh[v]; int w; for (int d = HASH_SIZE(deg[v]); d--; ww++) if ((w = *ww) != HASH_NONE && !visited[w]) { #ifdef OPT_ISOLATED if (K <= deg[w] + 1 || known == max) { #else //OPT_ISOLATED if (known == max) { #endif //OPT_ISOLATED is_isolated = false; goto end_isolated; } visited[w] = true; *(known++) = w; } } end_isolated: // Undo the changes to visited[]... while (known != Kbuff) { visited[*(--known)] = false; } return is_isolated; } //_________________________________________________________________________ int graph_molloy_hash::random_edge_swap(int K, int *Kbuff, bool *visited) { // Pick two random vertices a and c int f1 = pick_random_vertex(); int f2 = pick_random_vertex(); // Check that f1 != f2 if (f1 == f2) { return 0; } // Get two random edges (f1,*f1t1) and (f2,*f2t2) int *f1t1 = random_neighbour(f1); int t1 = *f1t1; int *f2t2 = random_neighbour(f2); int t2 = *f2t2; // Check simplicity if (t1 == t2 || f1 == t2 || f2 == t1) { return 0; } if (is_edge(f1, t2) || is_edge(f2, t1)) { return 0; } // Swap int *f1t2 = H_rpl(neigh[f1], deg[f1], f1t1, t2); int *f2t1 = H_rpl(neigh[f2], deg[f2], f2t2, t1); int *t1f2 = H_rpl(neigh[t1], deg[t1], f1, f2); int *t2f1 = H_rpl(neigh[t2], deg[t2], f2, f1); // isolation test if (K <= 2) { return 1; } if ( !isolated(f1, K, Kbuff, visited) && !isolated(f2, K, Kbuff, visited) ) { return 1; } // undo swap H_rpl(neigh[f1], deg[f1], f1t2, t1); H_rpl(neigh[f2], deg[f2], f2t1, t2); H_rpl(neigh[t1], deg[t1], t1f2, f1); H_rpl(neigh[t2], deg[t2], t2f1, f2); return 0; } //_________________________________________________________________________ unsigned long graph_molloy_hash::shuffle(unsigned long times, unsigned long maxtimes, int type) { igraph_progress("Shuffle", 0, 0); // assert(verify()); // counters unsigned long nb_swaps = 0; unsigned long all_swaps = 0; unsigned long cost = 0; // window double T = double(min((unsigned long)(a), times) / 10); if (type == OPTIMAL_HEURISTICS) { T = double(optimal_window()); } if (type == BRUTE_FORCE_HEURISTICS) { T = double(times * 2); } // isolation test parameter, and buffers double K = 2.4; int *Kbuff = new int[int(K) + 1]; bool *visited = new bool[n]; for (int i = 0; i < n; i++) { visited[i] = false; } // Used for monitoring , active only if VERBOSE() int failures = 0; int successes = 0; double avg_K = 0; double avg_T = 0; unsigned long next = times; next = 0; // Shuffle: while #edge swap attempts validated by connectivity < times ... while (times > nb_swaps && maxtimes > all_swaps) { // Backup graph int *save = backup(); // Prepare counters, K, T unsigned long swaps = 0; int K_int = 0; if (type == FINAL_HEURISTICS || type == BRUTE_FORCE_HEURISTICS) { K_int = int(K); } unsigned long T_int = (unsigned long)(floor(T)); if (T_int < 1) { T_int = 1; } // compute cost cost += T_int; if (K_int > 2) { cost += (unsigned long)(K_int) * (unsigned long)(T_int); } // Perform T edge swap attempts for (int i = T_int; i > 0; i--) { // try one swap swaps += (unsigned long)(random_edge_swap(K_int, Kbuff, visited)); all_swaps++; // Verbose if (nb_swaps + swaps > next) { next = (nb_swaps + swaps) + max((unsigned long)(100), (unsigned long)(times / 1000)); int progress = int(double(nb_swaps + swaps) / double(times)); igraph_progress("Shuffle", progress, 0); } } // test connectivity cost += (unsigned long)(a / 2); bool ok = is_connected(); // performance monitor { avg_T += double(T_int); avg_K += double(K_int); if (ok) { successes++; } else { failures++; } } // restore graph if needed, and count validated swaps if (ok) { nb_swaps += swaps; } else { restore(save); next = nb_swaps; } delete[] save; // Adjust K and T following the heuristics. switch (type) { int steps; case GKAN_HEURISTICS: if (ok) { T += 1.0; } else { T *= 0.5; } break; case FAB_HEURISTICS: steps = 50 / (8 + failures + successes); if (steps < 1) { steps = 1; } while (steps--) if (ok) { T *= 1.17182818; } else { T *= 0.9; } if (T > double(5 * a)) { T = double(5 * a); } break; case FINAL_HEURISTICS: if (ok) { if ((K + 10.0)*T > 5.0 * double(a)) { K /= 1.03; } else { T *= 2; } } else { K *= 1.35; delete[] Kbuff; Kbuff = new int[int(K) + 1]; } break; case OPTIMAL_HEURISTICS: if (ok) { T = double(optimal_window()); } break; case BRUTE_FORCE_HEURISTICS: K *= 2; delete[] Kbuff; Kbuff = new int[int(K) + 1]; break; default: throw std::invalid_argument("Error in graph_molloy_hash::shuffle(): Unknown heuristics type."); } } delete[] Kbuff; delete[] visited; if (maxtimes <= all_swaps) { IGRAPH_WARNING("Cannot shuffle graph, maybe it is the only realization of its degree sequence?"); } // Status report { igraph_status("*** Shuffle Monitor ***\n", 0); igraph_statusf(" - Average cost : %f / validated edge swap\n", 0, double(cost) / double(nb_swaps)); igraph_statusf(" - Connectivity tests : %d (%d successes, %d failures)\n", 0, successes + failures, successes, failures); igraph_statusf(" - Average window : %d\n", 0, int(avg_T / double(successes + failures))); if (type == FINAL_HEURISTICS || type == BRUTE_FORCE_HEURISTICS) igraph_statusf(" - Average isolation test width : %f\n", 0, avg_K / double(successes + failures)); } return nb_swaps; } //_________________________________________________________________________ void graph_molloy_hash::print(FILE *f) { int i, j; for (i = 0; i < n; i++) { fprintf(f, "%d", i); for (j = 0; j < HASH_SIZE(deg[i]); j++) if (neigh[i][j] != HASH_NONE) { fprintf(f, " %d", neigh[i][j]); } fprintf(f, "\n"); } } int graph_molloy_hash::print(igraph_t *graph) { int i, j; long int ptr = 0; igraph_vector_t edges; IGRAPH_VECTOR_INIT_FINALLY(&edges, a); // every edge is counted twice.... for (i = 0; i < n; i++) { for (j = 0; j < HASH_SIZE(deg[i]); j++) { if (neigh[i][j] != HASH_NONE) { if (neigh[i][j] > i) { VECTOR(edges)[ptr++] = i; VECTOR(edges)[ptr++] = neigh[i][j]; } } } } IGRAPH_CHECK(igraph_create(graph, &edges, n, /*undirected=*/ 0)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } //_________________________________________________________________________ bool graph_molloy_hash::try_shuffle(int T, int K, int *backup_graph) { // init all int *Kbuff = NULL; bool *visited = NULL; if (K > 2) { Kbuff = new int[K]; visited = new bool[n]; for (int i = 0; i < n; i++) { visited[i] = false; } } int *back = backup_graph; if (back == NULL) { back = backup(); } // perform T edge swap attempts while (T--) { random_edge_swap(K, Kbuff, visited); } // clean if (visited != NULL) { delete[] visited; } if (Kbuff != NULL) { delete[] Kbuff; } // check & restore bool yo = is_connected(); restore(back); if (backup_graph == NULL) { delete[] back; } return yo; } //_________________________________________________________________________ #define _TRUST_BERNOULLI_LOWER 0.01 bool bernoulli_param_is_lower(int success, int trials, double param) { if (double(success) >= double(trials)*param) { return false; } double comb = 1.0; double fact = 1.0; for (int i = 0; i < success; i++) { comb *= double(trials - i); fact *= double(i + 1); } comb /= fact; comb *= pow(param, double(success)) * exp(double(trials - success) * log1p(-param)); double sum = comb; while (success && sum < _TRUST_BERNOULLI_LOWER) { comb *= double(success) * (1.0 - param) / (double(trials - success) * param); sum += comb; success--; } // fprintf(stderr,"bernoulli test : %d/%d success against p=%f -> %s\n",success, trials, param, (sum < _TRUST_BERNOULLI_LOWER) ? "lower" : "can't say"); return (sum < _TRUST_BERNOULLI_LOWER); } //_________________________________________________________________________ #define _MIN_SUCCESS_FOR_BERNOULLI_TRUST 100 double graph_molloy_hash::average_cost(int T, int *backup, double min_cost) { if (T < 1) { return 1e+99; } int successes = 0; int trials = 0; while (successes < _MIN_SUCCESS_FOR_BERNOULLI_TRUST && !bernoulli_param_is_lower(successes, trials, 1.0 / min_cost)) { if (try_shuffle(T, 0, backup)) { successes++; } trials++; } if (successes >= _MIN_SUCCESS_FOR_BERNOULLI_TRUST) { return double(trials) / double(successes) * (1.0 + double(a / 2) / double(T)); } else { return 2.0 * min_cost; } } //_________________________________________________________________________ int graph_molloy_hash::optimal_window() { int Tmax; int optimal_T = 1; double min_cost = 1e+99; int *back = backup(); // on cherche une borne sup pour Tmax int been_greater = 0; for (Tmax = 1; Tmax <= 5 * a ; Tmax *= 2) { double c = average_cost(Tmax, back, min_cost); if (c > 1.5 * min_cost) { break; } if (c > 1.2 * min_cost && ++been_greater >= 3) { break; } if (c < min_cost) { min_cost = c; optimal_T = Tmax; } igraph_statusf("Tmax = %d [%f]", 0, Tmax, min_cost); } // on cree Tmin int Tmin = int(0.5 * double(a) / (min_cost - 1.0)); igraph_statusf("Optimal T is in [%d, %d]\n", 0, Tmin, Tmax); // on cherche autour double span = 2.0; int try_again = 4; while (span > 1.05 && optimal_T <= 5 * a) { igraph_statusf("Best T [cost]: %d [%f]", 0, optimal_T, min_cost); int T_low = int(double(optimal_T) / span); int T_high = int(double(optimal_T) * span); double c_low = average_cost(T_low, back, min_cost); double c_high = average_cost(T_high, back, min_cost); if (c_low < min_cost && c_high < min_cost) { if (try_again--) { continue; } { igraph_status("Warning: when looking for optimal T,\n", 0); igraph_statusf("Low: %d [%f] Middle: %d [%f] High: %d [%f]\n", 0, T_low, c_low, optimal_T, min_cost, T_high, c_high); } delete[] back; return optimal_T; } if (c_low < min_cost) { optimal_T = T_low; min_cost = c_low; } else if (c_high < min_cost) { optimal_T = T_high; min_cost = c_high; }; span = pow(span, 0.618); } delete[] back; return optimal_T; } //_________________________________________________________________________ double graph_molloy_hash::eval_K(int quality) { double K = 5.0; double avg_K = 1.0; for (int i = quality; i--; ) { int int_K = int(floor(K + 0.5)); if (try_shuffle(a / (int_K + 1), int_K)) { K *= 0.8; /*fprintf(stderr,"+");*/ } else { K *= 1.25; /*fprintf(stderr,"-");*/ } if (i < quality / 2) { avg_K *= K; } } return pow(avg_K, 1.0 / double(quality / 2)); } //_________________________________________________________________________ double graph_molloy_hash::effective_K(int K, int quality) { if (K < 3) { return 0.0; } long sum_K = 0; int *Kbuff = new int[K]; bool *visited = new bool[n]; int i; for (i = 0; i < n; i++) { visited[i] = false; } for (int i = 0; i < quality; i++) { // assert(verify()); int f1, f2, t1, t2; int *f1t1, *f2t2; do { // Pick two random vertices do { f1 = pick_random_vertex(); f2 = pick_random_vertex(); } while (f1 == f2); // Pick two random neighbours f1t1 = random_neighbour(f1); t1 = *f1t1; f2t2 = random_neighbour(f2); t2 = *f2t2; // test simplicity } while (t1 == t2 || f1 == t2 || f2 == t1 || is_edge(f1, t2) || is_edge(f2, t1)); // swap swap_edges(f1, t2, f2, t1); // assert(verify()); sum_K += effective_isolated(deg[f1] > deg[t2] ? f1 : t2, K, Kbuff, visited); // assert(verify()); sum_K += effective_isolated(deg[f2] > deg[t1] ? f2 : t1, K, Kbuff, visited); // assert(verify()); // undo swap swap_edges(f1, t2, f2, t1); // assert(verify()); } delete[] Kbuff; delete[] visited; return double(sum_K) / double(2 * quality); } //_________________________________________________________________________ long graph_molloy_hash::effective_isolated(int v, int K, int *Kbuff, bool *visited) { int i; for (i = 0; i < K; i++) { Kbuff[i] = -1; } long count = 0; int left = K; int *KB = Kbuff; //yapido = (my_random()%1000 == 0); depth_isolated(v, count, left, K, KB, visited); while (KB-- != Kbuff) { visited[*KB] = false; } //if(yapido) fprintf(stderr,"\n"); return count; } //_________________________________________________________________________ void graph_molloy_hash::depth_isolated(int v, long &calls, int &left_to_explore, int dmax, int * &Kbuff, bool *visited) { if (left_to_explore == 0) { return; } // if(yapido) fprintf(stderr,"%d ",deg[v]); if (--left_to_explore == 0) { return; } if (deg[v] + 1 >= dmax) { left_to_explore = 0; return; } *(Kbuff++) = v; visited[v] = true; // print(); // fflush(stdout); calls++; int *copy = NULL; int *w = neigh[v]; if (IS_HASH(deg[v])) { copy = new int[deg[v]]; H_copy(copy, w, deg[v]); w = copy; } qsort(deg, w, deg[v]); w += deg[v]; for (int i = deg[v]; i--; ) { if (visited[*--w]) { calls++; } else { depth_isolated(*w, calls, left_to_explore, dmax, Kbuff, visited); } if (left_to_explore == 0) { break; } } if (copy != NULL) { delete[] copy; } } //_________________________________________________________________________ int graph_molloy_hash::depth_search(bool *visited, int *buff, int v0) { for (int i = 0; i < n; i++) { visited[i] = false; } int *to_visit = buff; int nb_visited = 1; visited[v0] = true; *(to_visit++) = v0; while (to_visit != buff && nb_visited < n) { int v = *(--to_visit); int *ww = neigh[v]; int w; for (int k = HASH_SIZE(deg[v]); k--; ww++) { if (HASH_NONE != (w = *ww) && !visited[w]) { visited[w] = true; nb_visited++; *(to_visit++) = w; } } } return nb_visited; } //_________________________________________________________________________ // bool graph_molloy_hash::verify() { // fprintf(stderr,"Warning: graph_molloy_hash::verify() called..\n"); // fprintf(stderr," try to convert graph into graph_molloy_opt() instead\n"); // return true; // } /*____________________________________________________________________________ Not to use anymore : use graph_molloy_opt class instead bool graph_molloy_hash::verify() { int i; assert(neigh[0]==links); // verify edges count int sum = 0; for(i=0; in) n=i; n++; // degrees ? if(VERBOSE()) fprintf(stderr,"%d, #edges=",n); int *degs = new int[n]; rewind(f); while(fgets(buff,FBUFF_SIZE,f)) { int d = 0; if(sscanf(buff,"%d",&i)==1) { char *b = buff; while(skip_int(b)) d++; degs[i]=d; } } // allocate memory degree_sequence dd(n,degs); if(VERBOSE()) fprintf(stderr,"%d\nAllocating memory...",dd.sum()); alloc(dd); // add edges if(VERBOSE()) fprintf(stderr,"done\nCreating edges..."); rewind(f); for(i=0; im) m=deg[k]; return m; } bool graph_molloy_hash::havelhakimi() { int i; int dmax = max_degree()+1; // Sort vertices using basket-sort, in descending degrees int *nb = new int[dmax]; int *sorted = new int[n]; // init basket for(i=0; i=0; i--) { int t=nb[i]; nb[i]=c; c+=t; } // sort for(i=0; i0; ) { // pick a vertex. we could pick any, but here we pick the one with biggest degree int v = sorted[first]; // look for current degree of v while(nb[d]<=first) d--; // store it in dv int dv = d; // bind it ! c -= dv; int dc = d; // residual degree of vertices we bind to int fc = ++first; // position of the first vertex with degree dc while(dv>0 && dc>0) { int lc = nb[dc]; if(lc!=fc) { while(dv>0 && lc>fc) { // binds v with sorted[--lc] dv--; int w = sorted[--lc]; add_edge(v,w); } fc = nb[dc]; nb[dc] = lc; } dc--; } if(dv != 0) { // We couldn't bind entirely v if(VERBOSE()) { fprintf(stderr,"Error in graph_molloy_hash::havelhakimi() :\n"); fprintf(stderr,"Couldn't bind vertex %d entirely (%d edges remaining)\n",v,dv); } delete[] nb; delete[] sorted; return false; } } assert(c==0); delete[] nb; delete[] sorted; return true; } bool graph_molloy_hash::make_connected() { assert(verify()); if(a/2 < n-1) { // fprintf(stderr,"\ngraph::make_connected() failed : #edges < #vertices-1\n"); return false; } int i; // Data struct for the visit : // - buff[] contains vertices to visit // - dist[V] is V's distance modulo 4 to the root of its comp, or -1 if it hasn't been visited yet #define MC_BUFF_SIZE (n+2) int *buff = new int[MC_BUFF_SIZE]; unsigned char * dist = new unsigned char[n]; #define NOT_VISITED 255 #define FORBIDDEN 254 for(i=n; i>0; dist[--i]=NOT_VISITED); // Data struct to store components : either surplus trees or surplus edges are stored at buff[]'s end // - A Tree is coded by one of its vertices // - An edge (a,b) is coded by the TWO ints a and b int *ffub = buff+MC_BUFF_SIZE; edge *edges = (edge *) ffub; int *trees = ffub; int *min_ffub = buff+1+(MC_BUFF_SIZE%2 ? 0 : 1); // There will be only one "fatty" component, and trees. edge fatty_edge; fatty_edge.from = -1; bool enough_edges = false; // start main loop for(int v0=0; v0min_ffub) min_ffub+=2; // update limit of ffub's storage //assert(verify()); } else if(dist[w]==next_dist || (w!=HASH_NONE && w>v && dist[w]==current_dist)) { // we found a removable edge if(is_a_tree) { // we must first merge with the fatty component is_a_tree = false; if(fatty_edge.from < 0) { // we ARE the first component! fatty is us fatty_edge.from = v; fatty_edge.to = w; } else { // we connect to fatty swap_edges(fatty_edge.from, fatty_edge.to, v, w); //assert(verify()); } } else { // we have removable edges to give! if(trees!=ffub) { // some trees still.. Let's merge with them! assert(trees>=min_ffub); assert(edges==(edge *)ffub); swap_edges(v,w,*trees,neigh[*trees][0]); trees++; //assert(verify()); } else if(!enough_edges) { // Store the removable edge for future use if(edges<=(edge *)min_ffub+1) enough_edges = true; else { edges--; edges->from = v; edges->to = w; } } } } } } // Mark component while(to_visit!=buff) dist[*(--to_visit)] = FORBIDDEN; // Check if it is a tree if(is_a_tree ) { assert(deg[v0]!=0); if(edges!=(edge *)ffub) { // let's bind the tree we found with a removable edge in stock assert(trees == ffub); if(edges<(edge *)min_ffub) edges=(edge *)min_ffub; swap_edges(v0,neigh[v0][0],edges->from,edges->to); edges++; assert(verify()); } else { // add the tree to the list of trees assert(trees>min_ffub); *(--trees) = v0; assert(verify()); } } } delete[] buff; delete[] dist; return(trees == ffub); } int64_t graph_molloy_hash::slow_connected_shuffle(int64_t times) { assert(verify()); int64_t nb_swaps = 0; int T = 1; while(times>nb_swaps) { // Backup graph int *save = backup(); // Swaps int swaps = 0; for(int i=T; i>0; i--) { // Pick two random vertices a and c int f1 = pick_random_vertex(); int f2 = pick_random_vertex(); // Check that f1 != f2 if(f1==f2) continue; // Get two random edges (f1,*f1t1) and (f2,*f2t2) int *f1t1 = random_neighbour(f1); int t1 = *f1t1; int *f2t2 = random_neighbour(f2); int t2 = *f2t2; // Check simplicity if(t1==t2 || f1==t2 || f2==t1) continue; if(is_edge(f1,t2) || is_edge(f2,t1)) continue; // Swap H_rpl(neigh[f1],deg[f1],f1t1,t2); H_rpl(neigh[f2],deg[f2],f2t2,t1); H_rpl(neigh[t1],deg[t1],f1,f2); H_rpl(neigh[t2],deg[t2],f2,f1); swaps++; } // test connectivity bool ok = is_connected(); if(ok) { nb_swaps += swaps; } else { restore(save); } delete[] save; } return nb_swaps; } int graph_molloy_hash::width_search(unsigned char *dist, int *buff, int v0) { for(int i=0; i. */ #ifndef _VERTEX_COVER_H #define _VERTEX_COVER_H // vertex_cover() builds a list of vertices which covers every edge of the graph // Input is a classical adjacency-list graph // As an output, vertex_cover() modify the degrees in degs[], so that // any vertex with a degree > 0 belongs to the vertex coverage. // Moreover, vertex_cover() keeps links[] intact, permuting only the adjacency lists #include "gengraph_box_list.h" #include namespace gengraph { void vertex_cover(int n, int *links, int *deg, int **neigh = NULL) { int i; // create and initialize neigh[] if (neigh == NULL) { neigh = new int*[n]; neigh[0] = links; for (i = 1; i < n; i++) { neigh[i] = neigh[i - 1] + deg[i]; } } // create box_list box_list bl(n, deg); do { int v; // remove vertices adjacent to vertices of degree 1 while ((v = bl.get_one()) >= 0) { bl.pop_vertex(v, neigh); } // remove vertex of max degree and its highest-degree neighbour if (!bl.is_empty()) { v = bl.get_max(); int *w = neigh[v]; int v2 = *(w++); int dm = deg[v2]; int k = deg[v] - 1; while (k--) if (deg[*(w++)] > dm) { v2 = *(w - 1); dm = deg[v2]; }; bl.pop_vertex(v, neigh); bl.pop_vertex(v2, neigh); } } while (!bl.is_empty()); } } // namespace gengraph #endif //_VERTEX_COVER_H leidenbase/src/core/games/degree_sequence_vl/gengraph_powerlaw.h0000644000176200001440000000571614447675374024726 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef _POWERLAW_H #define _POWERLAW_H // pascalou #ifndef pascalou #include "gengraph_definitions.h" #endif // Discrete integer power-law : P(X=min+k) is proportionnal to (k+k0)^-alpha // - possibility to determine a range [Min, Max] of possible samples // - possibility to automatically compute k0 to obtain a given mean z namespace gengraph { #define POWERLAW_TABLE 10000 class powerlaw { private: double alpha; // Exponent int mini; // Minimum sample int maxi; // Maximum sample double offset; // Offset int tabulated; // Number of values to tabulate int *table; // Table containing cumulative distribution for k=mini..mini+tabulated-1 int *dt; // Table delimiters int max_dt; // number of delimiters - 1 double proba_big; // Probability to take a non-tabulated value double table_mul; // equal to (1-proba_big)/(RAND_MAX+1) // Sample a non-tabulated value >= mini+tabulated inline double big_sample(double randomfloat) { return double(mini) + pow(_a * randomfloat + _b, _exp) - offset; } inline double big_inv_sample(double s) { return (pow(s - double(mini) + offset, 1.0 / _exp) - _b) / _a; } double _exp, _a, _b; // Cached values used by big_sample(); // Dichotomic adjust of offset, so that to_adjust() returns value with // a precision of eps. Note that to_adjust() must be an increasing function of offset. void adjust_offset_mean(double value, double eps, double fac); public: int sample(); // Return a random integer double proba(int); // Return probability to return integer double error(); // Returns relative numerical error done by this class double mean(); // Returns mean of the sampler int median(); // Returns median of the sampler // Initialize the power-law sampler. void init_to_offset(double, int); // Same, but also returns the offset found double init_to_mean(double); double init_to_median(double); inline void init() { init_to_offset(double(mini), POWERLAW_TABLE); }; ~powerlaw(); powerlaw(double exponent, int mini, int maxi = -1); }; } // namespace gengraph #endif //_POWERLAW_H leidenbase/src/core/games/degree_sequence_vl/gengraph_random.cpp0000644000176200001440000001723614447675374024701 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define RNG_C #ifdef RCSID static const char rcsid[] = "$Id: random.cpp,v 1.15 2003/05/14 03:04:45 wilder Exp wilder $"; #endif //________________________________________________________________________ // See the header file random.h for a description of the contents of this // file as well as references and credits. #include "gengraph_random.h" #include using namespace std; using namespace KW_RNG; //________________________________________________________________________ // RNG::RNOR generates normal variates with rejection. // nfix() generates variates after rejection in RNOR. // Despite rejection, this method is much faster than Box-Muller. // double RNG::nfix(slong h, ulong i) // { // const double r = 3.442620f; // The starting of the right tail // static double x, y; // for(;;) { // x = h * wn[i]; // // If i == 0, handle the base strip // if (i==0){ // do { // x = -log(rand_open01()) * 0.2904764; // .2904764 is 1/r // y = -log(rand_open01()); // } while (y + y < x * x); // return ((h > 0) ? r + x : -r - x); // } // // If i > 0, handle the wedges of other strips // if (fn[i] + rand_open01() * (fn[i - 1] - fn[i]) < exp(-.5 * x * x) ) // return x; // // start all over // h = rand_int32(); // i = h & 127; // if ((ulong) abs((sint) h) < kn[i]) // return (h * wn[i]); // } // } // RNG::nfix // // __________________________________________________________________________ // // RNG::RNOR generates exponential variates with rejection. // // efix() generates variates after rejection in REXP. // double RNG::efix(ulong j, ulong i) // { // double x; // for (;;) // { // if (i == 0) // return (7.69711 - log(rand_open01())); // x = j * we[i]; // if (fe[i] + rand_open01() * (fe[i - 1] - fe[i]) < exp(-x)) // return (x); // j = rand_int32(); // i = (j & 255); // if (j < ke[i]) // return (j * we[i]); // } // } // RNG::efix // // __________________________________________________________________________ // // This procedure creates the tables used by RNOR and REXP // void RNG::zigset() // { // const double m1 = 2147483648.0; // 2^31 // const double m2 = 4294967296.0; // 2^32 // const double vn = 9.91256303526217e-3; // const double ve = 3.949659822581572e-3; // double dn = 3.442619855899, tn = dn; // double de = 7.697117470131487, te = de; // int i; // // Set up tables for RNOR // double q = vn / exp(-.5 * dn * dn); // kn[0] = (ulong) ((dn / q) * m1); // kn[1] = 0; // wn[0] = q / m1; // wn[127] = dn / m1; // fn[0]=1.; // fn[127] = exp(-.5 * dn * dn); // for(i = 126; i >= 1; i--) // { // dn = sqrt(-2 * log(vn / dn + exp(-.5 * dn * dn))); // kn[i + 1] = (ulong) ((dn / tn) * m1); // tn = dn; // fn[i] = exp(-.5 * dn * dn); // wn[i] = dn / m1; // } // // Set up tables for REXP // q = ve / exp(-de); // ke[0] = (ulong) ((de / q) * m2); // ke[1] = 0; // we[0] = q / m2; // we[255] = de / m2; // fe[0] = 1.; // fe[255] = exp(-de); // for (i = 254; i >= 1; i--) // { // de = -log(ve / de + exp(-de)); // ke[i+1] = (ulong) ((de / te) * m2); // te = de; // fe[i] = exp(-de); // we[i] = de / m2; // } // } // RNG::zigset // // __________________________________________________________________________ // // Generate a gamma variate with parameters 'shape' and 'scale' // double RNG::gamma(double shape, double scale) // { // if (shape < 1) // return gamma(shape + 1, scale) * pow(rand_open01(), 1.0 / shape); // const double d = shape - 1.0 / 3.0; // const double c = 1.0 / sqrt(9.0 * d); // double x, v, u; // for (;;) { // do { // x = RNOR(); // v = 1.0 + c * x; // } while (v <= 0.0); // v = v * v * v; // u = rand_open01(); // if (u < 1.0 - 0.0331 * x * x * x * x) // return (d * v / scale); // if (log(u) < 0.5 * x * x + d * (1.0 - v + log(v))) // return (d * v / scale); // } // } // RNG::gamma // // __________________________________________________________________________ // // gammalog returns the logarithm of the gamma function. From Numerical // // Recipes. // double gammalog(double xx) // { // static double cof[6]={ // 76.18009172947146, -86.50532032941677, 24.01409824083091, // -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5}; // double x = xx; // double y = xx; // double tmp = x + 5.5; // tmp -= (x + 0.5) * log(tmp); // double ser=1.000000000190015; // for (int j=0; j<=5; j++) // ser += cof[j] / ++y; // return -tmp + log(2.5066282746310005 * ser / x); // } // // __________________________________________________________________________ // // Generate a Poisson variate // // This is essentially the algorithm from Numerical Recipes // double RNG::poisson(double lambda) // { // static double sq, alxm, g, oldm = -1.0; // double em, t, y; // if (lambda < 12.0) { // if (lambda != oldm) { // oldm = lambda; // g = exp(-lambda); // } // em = -1; // t = 1.0; // do { // ++em; // t *= rand_open01(); // } while (t > g); // } else { // if (lambda != oldm) { // oldm = lambda; // sq = sqrt(2.0 * lambda); // alxm = log(lambda); // g = lambda * alxm - gammalog(lambda + 1.0); // } // do { // do { // y = tan(PI * rand_open01()); // em = sq * y + lambda; // } while (em < 0.0); // em = floor(em); // t = 0.9 * (1.0 + y * y) * exp(em * alxm - gammalog(em + 1.0)-g); // } while (rand_open01() > t); // } // return em; // } // RNG::poisson // // __________________________________________________________________________ // // Generate a binomial variate // // This is essentially the algorithm from Numerical Recipes // int RNG::binomial(double pp, int n) // { // if(n==0) return 0; // if(pp==0.0) return 0; // if(pp==1.0) return n; // double p = (pp<0.5 ? pp : 1.0-pp); // double am = n*p; // int bnl = 0; // if(n<25) { // for(int j=n; j--; ) if(rand_closed01()= en + 1.0); // em = floor(em); // t = 1.2 * sq * (1 + y * y) * exp(oldg - gammalog(em + 1.0) - // gammalog(en - em + 1.0) + em * log(p) + (en - em) * log(pc)); // } while (rand_closed01() > t); // bnl = int(em); // } // if (p!=pp) bnl=n-bnl; // return bnl; // } // RNG::binomial // __________________________________________________________________________ // rng.C leidenbase/src/core/games/degree_sequence_vl/gengraph_powerlaw.cpp0000644000176200001440000002000514447675374025245 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // Pascalou ... #ifdef pascalou #define my_random() random() #define MY_RAND_MAX 0x7FFFFFFF #else #include "gengraph_definitions.h" #endif #include "gengraph_powerlaw.h" #include #include #include #include "igraph_error.h" namespace gengraph { // Destructor powerlaw::~powerlaw() { delete[] table; if (dt != NULL) { delete[] dt; } } // Constructor powerlaw::powerlaw(double _alpha, int _mini, int _maxi) { alpha = _alpha; mini = _mini; maxi = _maxi; if (alpha <= 2.0 && maxi < 0) igraph_warningf("powerlaw exponent %f should be > 2 when no " "Maximum is specified", IGRAPH_FILE_BASENAME, __LINE__, -1, alpha); if (alpha <= 1.0 && maxi >= 0) igraph_warningf("powerlaw exponent %f should be > 1", IGRAPH_FILE_BASENAME, __LINE__, -1, alpha); if (maxi >= 0 && mini > maxi) igraph_warningf("powerlaw max %d should be greater than min %d", IGRAPH_FILE_BASENAME, __LINE__, -1, maxi, mini); table = new int[POWERLAW_TABLE]; tabulated = 0; dt = NULL; } // Sample int powerlaw::sample() { if (proba_big != 0 && test_proba(proba_big)) { return int(floor(0.5 + big_sample(random_float()))); } int r = my_random(); // table[] contains integer from MY_RAND_MAX downto 0, in blocks. Search block... if (r > (MY_RAND_MAX >> max_dt)) { return mini; } int k = 0; while (k < max_dt) { r <<= 1; r += random_bit(); k++; }; int a = 0; int b; while ((b = dt[k++]) < 0 || r < table[b]) { if (b >= 0) { a = b + 1; if (a == tabulated - 1) { break; } r <<= 1; r += random_bit(); } } // Now that we found the good block, run a dichotomy on this block [a,b] while (a < b) { int c = (a + b) / 2; if (r < table[c]) { a = c + 1; } else { b = c; } } return mini + a; } // Proba double powerlaw::proba(int k) { if (k < mini || (maxi >= 0 && k > maxi)) { return 0.0; } if (k >= mini + tabulated) { return proba_big * (big_inv_sample(double(k) - 0.5) - big_inv_sample(double(k) + 0.5)); } else { double div = table_mul; int prev_pos_in_table = k - mini - 1; if (prev_pos_in_table < 0) { return (double(MY_RAND_MAX) + 1.0 - double(table[0] >> max_dt)) * div; } // what block are we in ? int k1 = 0; while (k1 < max_dt) { div *= 0.5; k1++; }; while (dt[k1] < 0 || dt[k1] < prev_pos_in_table) { k1++; div *= 0.5; }; double prob2 = double(table[prev_pos_in_table + 1]); if (dt[k1] == prev_pos_in_table) do { prob2 *= 0.5; } while (dt[++k1] < 0); return (double(table[prev_pos_in_table]) - prob2) * div; } } // Relative Error double powerlaw::error() { return 1.0 / (double(tabulated) * double(tabulated)); } // Mean double powerlaw::mean() { double sum = 0.0; for (int i = mini + tabulated; --i >= mini; ) { sum += double(i) * proba(i); } // add proba_big * integral(big_sample(t),t=0..1) if (proba_big != 0) { sum += proba_big * ((pow(_a + _b, _exp + 1.0) - pow(_b, _exp + 1.0)) / (_a * (_exp + 1.0)) + double(mini) - offset - sum); } return sum; } // Median. Returns integer Med such that P(X<=Med) >= 1/2 int powerlaw::median() { if (proba_big > 0.5) { return int(floor(0.5 + big_sample(1.0 - 0.5 / proba_big))); } double sum = 0.0; int i = mini; while (sum < 0.5) { sum += proba(i++); } return i - 1; } void powerlaw::init_to_offset(double _offset, int _tabulated) { offset = _offset; tabulated = _tabulated; if (maxi >= 0 && tabulated > maxi - mini) { tabulated = maxi - mini + 1; } double sum = 0.0; double item = double(tabulated) + offset; // Compute sum of tabulated probabilities for (int i = tabulated; i--; ) { sum += pow(item -= 1.0, -alpha); } // Compute others parameters : proba_big, table_mul, _a, _b, _exp if (maxi > 0 && maxi <= mini + tabulated - 1) { proba_big = 0; table_mul = inv_RANDMAX; } else { if (maxi < 0) { _b = 0.0; } else { _b = pow(double(maxi - mini) + 0.5 + offset, 1.0 - alpha); } _a = pow(double(tabulated) - 0.5 + offset, 1.0 - alpha) - _b; _exp = 1.0 / (1.0 - alpha); double sum_big = _a * (-_exp); proba_big = sum_big / (sum + sum_big); table_mul = inv_RANDMAX * sum / (sum + sum_big); } // How many delimiters will be necessary for the table ? max_dt = max(0, int(floor(alpha * log(double(tabulated)) / log(2.0))) - 6); if (dt != NULL) { delete[] dt; } dt = new int[max_dt + 1]; // Create table as decreasing integers from MY_RAND_MAX+1 (in virtual position -1) down to 0 // Every time the index crosses a delimiter, numbers get doubled. double ssum = 0; double mul = (double(MY_RAND_MAX) + 1.0) * pow(2.0, max_dt) / sum; item = double(tabulated) + offset; int k = max_dt; dt[k--] = tabulated - 1; for (int i = tabulated; --i > 0; ) { table[i] = int(floor(0.5 + ssum)); ssum += mul * pow(item -= 1.0, -alpha); if (ssum > double(MY_RAND_MAX / 2) && k >= 0) { while ((ssum *= 0.5) > double(MY_RAND_MAX / 2)) { mul *= 0.5; dt[k--] = -1; }; mul *= 0.5; dt[k--] = i - 1; } } table[0] = int(floor(0.5 + ssum)); max_dt = k + 1; } void powerlaw::adjust_offset_mean(double _mean, double err, double factor) { // Set two bounds for offset double ol = offset; double oh = offset; if (mean() < _mean) { do { ol = oh; oh *= factor; init_to_offset(oh, tabulated); } while (mean() < _mean); } else { do { oh = ol; ol /= factor; init_to_offset(ol, tabulated); } while (mean() > _mean); } // Now, dichotomy while (fabs(oh - ol) > err * ol) { double oc = sqrt(oh * ol); init_to_offset(oc, tabulated); if (mean() < _mean) { ol = oc; } else { oh = oc; } } init_to_offset(sqrt(ol * oh), tabulated); } double powerlaw::init_to_mean(double _mean) { if (maxi >= 0 && _mean >= 0.5 * double((mini + maxi))) { /* Cannot use IGRAPH_ERRORF() as this function does not * return an igraph error code. */ igraph_errorf("Fatal error in powerlaw::init_to_mean(%f): " "Mean must be in ]min, (min+max)/2[ = ]%d, %d[", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL, _mean, mini, (mini + maxi) / 2); return (-1.0); } init_to_offset(_mean - double(mini), 100); adjust_offset_mean(_mean, 0.01, 2); init_to_offset(offset, POWERLAW_TABLE); double eps = 1.0 / (double(POWERLAW_TABLE)); adjust_offset_mean(_mean, eps * eps, 1.01); return offset; } } // namespace gengraph leidenbase/src/core/games/degree_sequence_vl/gengraph_header.h0000644000176200001440000000551714447675374024315 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gengraph_definitions.h" #include #include #include "gengraph_random.h" namespace gengraph { static KW_RNG::RNG _my_random; int my_random() { return _my_random.rand_int31(); } void my_srandom(int x) { _my_random.init(x, !x * 13, x * x + 1, (x >> 16) + (x << 16)); } int my_binomial(double pp, int n) { return _my_random.binomial(pp, n); } double my_random01() { return _my_random.rand_halfopen01(); } } namespace gengraph { static int VERB; int VERBOSE() { return VERB; } void SET_VERBOSE(int v) { VERB = v; } //Hash profiling static unsigned long _hash_rm_i = 0; static unsigned long _hash_rm_c = 0; static unsigned long _hash_add_i = 0; static unsigned long _hash_add_c = 0; static unsigned long _hash_put_i = 0; static unsigned long _hash_put_c = 0; static unsigned long _hash_find_i = 0; static unsigned long _hash_find_c = 0; static unsigned long _hash_rand_i = 0; static unsigned long _hash_rand_c = 0; static unsigned long _hash_expand = 0; inline void _hash_add_iter() { _hash_add_i++; } inline void _hash_add_call() { _hash_add_c++; } inline void _hash_put_iter() { _hash_put_i++; } inline void _hash_put_call() { _hash_put_c++; } inline void _hash_rm_iter() { _hash_rm_i++; } inline void _hash_rm_call() { _hash_rm_c++; } inline void _hash_find_iter() { _hash_find_i++; } inline void _hash_find_call() { _hash_find_c++; } inline void _hash_rand_iter() { _hash_rand_i++; } inline void _hash_rand_call() { _hash_rand_c++; } inline void _hash_expand_call() { _hash_expand++; } // void _hash_prof() { // fprintf(stderr,"HASH_ADD : %lu / %lu\n", _hash_add_c , _hash_add_i); // fprintf(stderr,"HASH_PUT : %lu / %lu\n", _hash_put_c , _hash_put_i); // fprintf(stderr,"HASH_FIND: %lu / %lu\n", _hash_find_c, _hash_find_i); // fprintf(stderr,"HASH_RM : %lu / %lu\n", _hash_rm_c , _hash_rm_i); // fprintf(stderr,"HASH_RAND: %lu / %lu\n", _hash_rand_c, _hash_rand_i); // fprintf(stderr,"HASH_EXPAND : %lu calls\n", _hash_expand); // } } // namespace gengraph leidenbase/src/core/games/degree_sequence_vl/gengraph_graph_molloy_optimized.cpp0000644000176200001440000020622314447675374030175 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gengraph_definitions.h" #include #include #include #include #include "gengraph_qsort.h" #include "gengraph_box_list.h" #include "gengraph_vertex_cover.h" #include "gengraph_degree_sequence.h" #include "gengraph_graph_molloy_optimized.h" #include "igraph_error.h" #include "igraph_statusbar.h" #include "igraph_progress.h" using namespace std; namespace gengraph { void graph_molloy_opt::breadth_search(int *dist, int v0, int *buff) { bool tmpbuff = (buff == NULL); if (tmpbuff) { buff = new int[n]; } for (int i = 0; i < n; i++) { dist[i] = -1; } dist[v0] = 0; int *visited = buff; int *to_visit = buff; *to_visit++ = v0; while (visited != to_visit) { int v = *visited++; int *w = neigh[v]; int dd = dist[v] + 1; for (int d = deg[v]; d--; w++) if (dist[*w] < 0) { dist[*w] = dd; *to_visit++ = *w; } } if (tmpbuff) { delete[] buff; } } int graph_molloy_opt::max_degree() { int m = 0; for (int k = 0; k < n; k++) if (deg[k] > m) { m = deg[k]; } return m; } void graph_molloy_opt::compute_neigh() { int *p = links; for (int i = 0; i < n; i++) { neigh[i] = p; p += deg[i]; } } void graph_molloy_opt::alloc(degree_sequence °s) { n = degs.size(); a = degs.sum(); assert(a % 2 == 0); deg = new int[n + a]; for (int i = 0; i < n; i++) { deg[i] = degs[i]; } links = deg + n; neigh = new int*[n]; compute_neigh(); } graph_molloy_opt::graph_molloy_opt(degree_sequence °s) { alloc(degs); } // graph_molloy_opt::graph_molloy_opt(FILE *f) { // char *buff = new char[FBUFF_SIZE]; // // How many vertices ? // if(VERBOSE()) fprintf(stderr,"Read file: #vertices="); // int i; // int n=0; // while(fgets(buff,FBUFF_SIZE,f)) if(sscanf(buff,"%d",&i)==1 && i>n) n=i; // n++; // // degrees ? // if(VERBOSE()) fprintf(stderr,"%d, #edges=",n); // int *degs = new int[n]; // for(i=0; i= i) { *(c++) = *p; } } } assert(c == b + (a / 2)); return b; } int *graph_molloy_opt::hard_copy() { int *hc = new int[2 + n + a / 2]; // to store n,a,deg[] and links[] hc[0] = n; hc[1] = a; memcpy(hc + 2, deg, sizeof(int)*n); int *c = hc + 2 + n; for (int i = 0; i < n; i++) { int *p = neigh[i]; for (int d = deg[i]; d--; p++) { assert(*p != i); if (*p >= i) { *(c++) = *p; } } } assert(c == hc + 2 + n + a / 2); return hc; } void graph_molloy_opt::restore(int* b) { int i; for (i = 0; i < n; i++) { deg[i] = 0; } int *p = links; for (i = 0; i < n - 1; i++) { p += deg[i]; deg[i] = int(neigh[i + 1] - neigh[i]); assert((neigh[i] + deg[i]) == neigh[i + 1]); while (p != neigh[i + 1]) { // b points to the current 'j' neigh[*b][deg[*b]++] = i; *(p++) = *(b++); } } } int* graph_molloy_opt::backup_degs(int *b) { if (b == NULL) { b = new int[n]; } memcpy(b, deg, sizeof(int)*n); return b; } void graph_molloy_opt::restore_degs_only(int *b) { memcpy(deg, b, sizeof(int)*n); refresh_nbarcs(); } void graph_molloy_opt::restore_degs_and_neigh(int *b) { restore_degs_only(b); compute_neigh(); } void graph_molloy_opt::restore_degs(int last_degree) { a = last_degree; deg[n - 1] = last_degree; for (int i = n - 2; i >= 0; i--) { a += (deg[i] = int(neigh[i + 1] - neigh[i])); } refresh_nbarcs(); } void graph_molloy_opt::clean() { int *b = hard_copy(); replace(b); delete[] b; } void graph_molloy_opt::replace(int *_hardcopy) { delete[] deg; n = *(_hardcopy++); a = *(_hardcopy++); deg = new int[a + n]; memcpy(deg, _hardcopy, sizeof(int)*n); links = deg + n; compute_neigh(); restore(_hardcopy + n); } int* graph_molloy_opt::components(int *comp) { int i; // breadth-first search buffer int *buff = new int[n]; // comp[i] will contain the index of the component that contains vertex i if (comp == NULL) { comp = new int[n]; } memset(comp, 0, sizeof(int)*n); // current component index int curr_comp = 0; // loop over all non-visited vertices... for (int v0 = 0; v0 < n; v0++) if (comp[v0] == 0) { curr_comp++; // initiate breadth-first search int *to_visit = buff; int *visited = buff; *(to_visit++) = v0; comp[v0] = curr_comp; // breadth-first search while (visited != to_visit) { int v = *(visited++); int d = deg[v]; for (int *w = neigh[v]; d--; w++) if (comp[*w] == 0) { comp[*w] = curr_comp; *(to_visit++) = *w; } } } // compute component sizes and store them in buff[] int nb_comp = 0; memset(buff, 0, sizeof(int)*n); for (i = 0; i < n; i++) if (buff[comp[i] - 1]++ == 0 && comp[i] > nb_comp) { nb_comp = comp[i]; } // box-sort sizes int offset = 0; int *box = pre_boxsort(buff, nb_comp, offset); for (i = nb_comp - 1; i >= 0; i--) { buff[i] = --box[buff[i] - offset]; } delete[] box; // reassign component indexes for (int *c = comp + n; comp != c--; *c = buff[*c - 1]) { } // clean.. at last! delete[] buff; return comp; } void graph_molloy_opt::giant_comp() { int *comp = components(); // Clear edges of all vertices that do not belong to comp 0 for (int i = 0; i < n; i++) if (comp[i] != 0) { deg[i] = 0; } // Clean comp[] delete[] comp; } int graph_molloy_opt::nbvertices_comp() { int *comp = components(); // Count all vertices that belong to comp 0 int nb = 0; for (int i = 0; i < n; i++) if (comp[i] == 0) { nb++; } // Clean comp[] delete[] comp; return nb; } int graph_molloy_opt::nbarcs_comp() { int *comp = components(); // Count all vertices that belong to comp 0 int nb = 0; for (int i = 0; i < n; i++) if (comp[i] == 0) { nb += deg[i]; } // Clean comp[] delete[] comp; return nb; } bool graph_molloy_opt::havelhakimi() { int i; int dmax = max_degree() + 1; // Sort vertices using basket-sort, in descending degrees int *nb = new int[dmax]; int *sorted = new int[n]; // init basket for (i = 0; i < dmax; i++) { nb[i] = 0; } // count basket for (i = 0; i < n; i++) { nb[deg[i]]++; } // cumul int c = 0; for (i = dmax - 1; i >= 0; i--) { c += nb[i]; nb[i] = -nb[i] + c; } // sort for (i = 0; i < n; i++) { sorted[nb[deg[i]]++] = i; } // Binding process starts int first = 0; // vertex with biggest residual degree int d = dmax - 1; // maximum residual degree available for (c = a / 2; c > 0; ) { // pick a vertex. we could pick any, but here we pick the one with biggest degree int v = sorted[first]; // look for current degree of v while (nb[d] <= first) { d--; } // store it in dv int dv = d; // bind it ! c -= dv; int dc = d; // residual degree of vertices we bind to int fc = ++first; // position of the first vertex with degree dc while (dv > 0 && dc > 0) { int lc = nb[dc]; if (lc != fc) { while (dv > 0 && lc > fc) { // binds v with sorted[--lc] dv--; int w = sorted[--lc]; *(neigh[v]++) = w; *(neigh[w]++) = v; } fc = nb[dc]; nb[dc] = lc; } dc--; } if (dv != 0) { // We couldn't bind entirely v delete[] nb; delete[] sorted; compute_neigh(); /* Cannot use IGRAPH_ERRORF() as this function does not return * an error code. This situation should only occur when the degree * sequence is not graphical, but that is already checked at the top * level. Therefore, we report EINTERNAL, as triggering this * indicates a bug. */ igraph_errorf("Error in graph_molloy_opt::havelhakimi(): " "Couldn't bind vertex %d entirely (%d edges remaining)", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINTERNAL, v, dv); return false; } } assert(c == 0); compute_neigh(); delete[] nb; delete[] sorted; return true; } bool graph_molloy_opt::is_connected() { bool *visited = new bool[n]; for (int i = n; i > 0; visited[--i] = false) { } int *to_visit = new int[n]; int *stop = to_visit; int left = n - 1; *(to_visit++) = 0; visited[0] = true; while (left > 0 && to_visit != stop) { int v = *(--to_visit); int *w = neigh[v]; for (int k = deg[v]; k--; w++) if (!visited[*w]) { visited[*w] = true; left--; *(to_visit++) = *w; } } delete[] visited; delete[] stop; assert(left >= 0); return (left == 0); } bool graph_molloy_opt::make_connected() { //assert(verify()); if (a / 2 < n - 1) { // fprintf(stderr,"\ngraph::make_connected() failed : #edges < #vertices-1\n"); return false; } int i; // Data struct for the visit : // - buff[] contains vertices to visit // - dist[V] is V's distance modulo 4 to the root of its comp, or -1 if it hasn't been visited yet #define MC_BUFF_SIZE (n+2) int *buff = new int[MC_BUFF_SIZE]; unsigned char * dist = new unsigned char[n]; #define NOT_VISITED 255 #define FORBIDDEN 254 for (i = n; i > 0; dist[--i] = NOT_VISITED) { } // Data struct to store components : either surplus trees or surplus edges are stored at buff[]'s end // - A Tree is coded by one of its vertices // - An edge (a,b) is coded by the TWO ints a and b int *ffub = buff + MC_BUFF_SIZE; edge *edges = (edge *) ffub; int *trees = ffub; int *min_ffub = buff + 1 + (MC_BUFF_SIZE % 2 ? 0 : 1); // There will be only one "fatty" component, and trees. edge fatty_edge = { -1, -1 }; bool enough_edges = false; // start main loop for (int v0 = 0; v0 < n; v0++) if (dist[v0] == NOT_VISITED) { // is v0 an isolated vertex? if (deg[v0] == 0) { delete[] dist; delete[] buff; /* Cannot use IGRAPH_ERROR() as this function does not return an error code. */ igraph_error("Cannot create connected graph from degree sequence: " "vertex with degree 0 found.", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return false; } dist[v0] = 0; // root int *to_visit = buff; int *current = buff; *(to_visit++) = v0; // explore component connected to v0 bool is_a_tree = true; while (current != to_visit) { int v = *(current++); unsigned char current_dist = dist[v]; unsigned char next_dist = (current_dist + 1) & 0x03; //unsigned char prev_dist = (current_dist-1) & 0x03; int* ww = neigh[v]; int w; for (int k = deg[v]; k--; ww++) { if (dist[w = *ww] == NOT_VISITED) { // we didn't visit *w yet dist[w] = next_dist; *(to_visit++) = w; if (to_visit > min_ffub) { min_ffub += 2; // update limit of ffub's storage } //assert(verify()); } else if (dist[w] == next_dist || (w >= v && dist[w] == current_dist)) { // we found a removable edge if (trees != ffub) { // some trees still.. Let's merge with them! assert(trees >= min_ffub); assert(edges == (edge *)ffub); swap_edges(v, w, *trees, neigh[*trees][0]); trees++; //assert(verify()); } else if (is_a_tree) { // we must merge with the fatty component is_a_tree = false; if (fatty_edge.from < 0) { // we ARE the first component! fatty is us fatty_edge.from = v; fatty_edge.to = w; } else { // we connect to fatty swap_edges(fatty_edge.from, fatty_edge.to, v, w); fatty_edge.to = w; //assert(verify()); } } else if (!enough_edges) { // Store the removable edge for future use if (edges <= (edge *)min_ffub + 1) { enough_edges = true; } else { edges--; edges->from = v; edges->to = w; } } } } } // Mark component while (to_visit != buff) { dist[*(--to_visit)] = FORBIDDEN; } // Check if it is a tree if (is_a_tree ) { assert(deg[v0] != 0); if (edges != (edge *)ffub) { // let's bind the tree we found with a removable edge in stock assert(trees == ffub); if (edges < (edge *)min_ffub) { edges = (edge *)min_ffub; } swap_edges(v0, neigh[v0][0], edges->from, edges->to); edges++; assert(verify()); } else if (fatty_edge.from >= 0) { // if there is a fatty component, let's merge with it ! and discard fatty :-/ assert(trees == ffub); swap_edges(v0, neigh[v0][0], fatty_edge.from, fatty_edge.to); fatty_edge.from = -1; fatty_edge.to = -1; assert(verify()); } else { // add the tree to the list of trees assert(trees > min_ffub); *(--trees) = v0; assert(verify()); } } } delete[] buff; delete[] dist; // Should ALWAYS return true : either we have no tree left, or we are a unique, big tree return (trees == ffub || ((trees + 1) == ffub && fatty_edge.from < 0)); } bool graph_molloy_opt::swap_edges_simple(int from1, int to1, int from2, int to2) { if (from1 == to1 || from1 == from2 || from1 == to2 || to1 == from2 || to1 == to2 || from2 == to2) { return false; } if (is_edge(from1, to2) || is_edge(from2, to1)) { return false; } swap_edges(from1, to1, from2, to2); return true; } long graph_molloy_opt::fab_connected_shuffle(long times) { //assert(verify()); long nb_swaps = 0; double T = double(min(a, times)) / 10.0; double q1 = 1.131; double q2 = 0.9237; while (times > 0) { long iperiod = max(1, long(T)); // Backup graph int *save = backup(); //assert(verify()); // Swaps long swaps = 0; for (long i = iperiod; i > 0; i--) { // Pick two random vertices int f1 = links[my_random() % a]; int f2 = links[my_random() % a]; if (f1 == f2) { continue; } // Pick two random neighbours int *f1t1 = neigh[f1] + my_random() % deg[f1]; int *f2t2 = neigh[f2] + my_random() % deg[f2]; int t1 = *f1t1; int t2 = *f2t2; // test simplicity if (t1 != t2 && f1 != t2 && f2 != t1 && is_edge(f1, t2) && !is_edge(f2, t1)) { // swap *f1t1 = t2; *f2t2 = t1; fast_rpl(neigh[t1], f1, f2); fast_rpl(neigh[t2], f2, f1); swaps++; } } //assert(verify()); // test connectivity if (is_connected()) { nb_swaps += swaps; times -= iperiod; // adjust T T *= q1; } else { restore(save); //assert(verify()); T *= q2; } delete[] save; } return nb_swaps; } long graph_molloy_opt::opt_fab_connected_shuffle(long times) { //assert(verify()); long nb_swaps = 0; double T = double(min(a, times)) / 10.0; double q1 = 1.131; double q2 = 0.9237; while (times > 0) { long iperiod = max(1, long(T)); // Backup graph int *save = backup(); //assert(verify()); // Swaps long swaps = 0; for (long i = iperiod; i > 0; i--) { // Pick two random vertices int f1 = links[my_random() % a]; int f2 = links[my_random() % a]; if (f1 == f2) { continue; } // Pick two random neighbours int *f1t1 = neigh[f1] + my_random() % deg[f1]; int *f2t2 = neigh[f2] + my_random() % deg[f2]; int t1 = *f1t1; int t2 = *f2t2; if ( // test simplicity t1 != t2 && f1 != t2 && f2 != t1 && is_edge(f1, t2) && !is_edge(f2, t1) && // test isolated pair (deg[f1] > 1 || deg[t2] > 1) && (deg[f2] > 1 || deg[t1] > 1) ) { // swap *f1t1 = t2; *f2t2 = t1; fast_rpl(neigh[t1], f1, f2); fast_rpl(neigh[t2], f2, f1); swaps++; } } //assert(verify()); // test connectivity if (is_connected()) { nb_swaps += swaps; times -= iperiod; // adjust T T *= q1; } else { restore(save); //assert(verify()); T *= q2; } delete[] save; } return nb_swaps; } long graph_molloy_opt::gkantsidis_connected_shuffle(long times) { //assert(verify()); long nb_swaps = 0; long T = min(a, times) / 10; while (times > 0) { // Backup graph int *save = backup(); //assert(verify()); // Swaps long swaps = 0; for (int i = T; i > 0; i--) { // Pick two random vertices int f1 = links[my_random() % a]; int f2 = links[my_random() % a]; if (f1 == f2) { continue; } // Pick two random neighbours int *f1t1 = neigh[f1] + my_random() % deg[f1]; int *f2t2 = neigh[f2] + my_random() % deg[f2]; int t1 = *f1t1; int t2 = *f2t2; // test simplicity if (t1 != t2 && f1 != t2 && f2 != t1 && is_edge(f1, t2) && !is_edge(f2, t1)) { // swap *f1t1 = t2; *f2t2 = t1; fast_rpl(neigh[t1], f1, f2); fast_rpl(neigh[t2], f2, f1); swaps++; } } //assert(verify()); // test connectivity if (is_connected()) { nb_swaps += swaps; times -= T; // adjust T T++; } else { restore(save); //assert(verify()); T /= 2; if (T == 0) T = 1; } delete[] save; } return nb_swaps; } long graph_molloy_opt::slow_connected_shuffle(long times) { //assert(verify()); long nb_swaps = 0; while (times--) { // Pick two random vertices int f1 = links[my_random() % a]; int f2 = links[my_random() % a]; if (f1 == f2) { continue; } // Pick two random neighbours int *f1t1 = neigh[f1] + my_random() % deg[f1]; int *f2t2 = neigh[f2] + my_random() % deg[f2]; int t1 = *f1t1; int t2 = *f2t2; // test simplicity if (t1 != t2 && f1 != t2 && f2 != t1 && is_edge(f1, t2) && !is_edge(f2, t1)) { // swap *f1t1 = t2; *f2t2 = t1; int *t1f1 = fast_rpl(neigh[t1], f1, f2); int *t2f2 = fast_rpl(neigh[t2], f2, f1); // test connectivity if (is_connected()) { nb_swaps++; } else { // undo swap *t1f1 = f1; *t2f2 = f2; *f1t1 = t1; *f2t2 = t2; } } } return nb_swaps; } void graph_molloy_opt::print(FILE *f, bool NOZERO) { int i, j; for (i = 0; i < n; i++) { if (!NOZERO || deg[i] > 0) { fprintf(f, "%d", i); for (j = 0; j < deg[i]; j++) { fprintf(f, " %d", neigh[i][j]); } fprintf(f, "\n"); } } } long graph_molloy_opt::effective_isolated(int v, int K, int *Kbuff, bool *visited) { int i; for (i = 0; i < K; i++) { Kbuff[i] = -1; } long count = 0; int left = K; int *KB = Kbuff; //yapido = (my_random()%1000 == 0); depth_isolated(v, count, left, K, KB, visited); while (KB-- != Kbuff) { visited[*KB] = false; } //if(yapido) fprintf(stderr,"\n"); return count; } void graph_molloy_opt::depth_isolated(int v, long &calls, int &left_to_explore, int dmax, int * &Kbuff, bool *visited) { if (left_to_explore == 0) { return; } // if(yapido) fprintf(stderr,"%d ",deg[v]); if (--left_to_explore == 0) { return; } if (deg[v] + 1 >= dmax) { left_to_explore = 0; return; } *(Kbuff++) = v; visited[v] = true; calls++; int *w = neigh[v]; qsort(deg, w, deg[v]); w += deg[v]; for (int i = deg[v]; i--; ) { if (visited[*--w]) { calls++; } else { depth_isolated(*w, calls, left_to_explore, dmax, Kbuff, visited); } if (left_to_explore == 0) { break; } } } int graph_molloy_opt::depth_search(bool *visited, int *buff, int v0) { for (int i = 0; i < n; i++) { visited[i] = false; } int *to_visit = buff; int nb_visited = 1; visited[v0] = true; *(to_visit++) = v0; while (to_visit != buff && nb_visited < n) { int v = *(--to_visit); int *ww = neigh[v]; int w; for (int k = deg[v]; k--; ww++) if (!visited[w = *ww]) { visited[w] = true; nb_visited++; *(to_visit++) = w; } } return nb_visited; } int graph_molloy_opt::width_search(unsigned char *dist, int *buff, int v0, int toclear) { if (toclear >= 0) for (int i = 0; i < toclear; i++) { dist[buff[i]] = 0; } else for (int i = 0; i < n; i++) { dist[i] = 0; } int *to_visit = buff; int *to_add = buff; int nb_visited = 1; dist[v0] = 1; *(to_add++) = v0; while (to_visit != to_add && nb_visited < n) { int v = *(to_visit++); int *ww = neigh[v]; int w; unsigned char d = next_dist(dist[v]); for (int k = deg[v]; k--; ww++) if (dist[w = *ww] == 0) { dist[w] = d; nb_visited++; *(to_add++) = w; } } return nb_visited; } double graph_molloy_opt::avg_dist(unsigned char *dist, int *buff, int v0, int &nb_visited, int toclear) { nb_visited = width_search(dist, buff, v0, toclear); unsigned char curr_dist = 1; assert(curr_dist == dist[v0]); double total_dist = 0.0; int current_dist = 0; for (int p = 0; p < nb_visited; p++) { v0 = buff[p]; if (dist[v0] != curr_dist) { current_dist++; curr_dist = dist[v0]; } total_dist += double(current_dist); } nb_visited--; return total_dist / double(nb_visited); } void graph_molloy_opt::add_traceroute_edge(int v, int k, int *newdeg, double **edge_redudancy, double red) { int *ww = neigh[v] + k; int w = *ww; int k2 = 0; // Is neigh[v][k] a new edge ? if (k >= newdeg[v]) { int *p = neigh[v] + (newdeg[v]++); *ww = *p; *p = w; // Now, add the dual edge ww = neigh[w]; p = ww + (newdeg[w]); while (ww != p && *ww != v) { ww++; k2++; } if (ww == p) { // dual edge was not discovered.. search it and add it. while (*ww != v) { ww++; k2++; } *ww = *p; *p = v; newdeg[w]++; } } // if edge redudancy is asked, look for dual edge else if (edge_redudancy != NULL) for (int *ww = neigh[w]; * (ww++) != v; k2++) { } // add edge redudancy if (edge_redudancy != NULL) { edge_redudancy[v][k] += red; edge_redudancy[w][k2] += red; } assert(newdeg[v] <= deg[v]); } // dist[] MUST be full of zeros !!!! int graph_molloy_opt::breadth_path_search(int src, int *buff, double *paths, unsigned char *dist) { unsigned char last_dist = 0; unsigned char curr_dist = 1; int *to_visit = buff; int *visited = buff; *(to_visit++) = src; paths[src] = 1.0; dist[src] = curr_dist; int nb_visited = 1; while (visited != to_visit) { int v = *(visited++); if (last_dist == (curr_dist = dist[v])) { break; } unsigned char nd = next_dist(curr_dist); int *ww = neigh[v]; double p = paths[v]; for (int k = deg[v]; k--;) { int w = *(ww++); unsigned char d = dist[w]; if (d == 0) { // not visited yet ! *(to_visit++) = w; dist[w] = nd; paths[w] = p; // is it the last one ? if (++nb_visited == n) { last_dist = nd; } } else if (d == nd) { if ((paths[w] += p) == numeric_limits::infinity()) { IGRAPH_ERROR("Fatal error : too many (>MAX_DOUBLE) possible" " paths in graph", IGRAPH_EOVERFLOW); } } } } assert(to_visit == buff + nb_visited); return nb_visited; } // dist[] MUST be full of zeros !!!! void graph_molloy_opt::explore_usp(double *target, int nb_vertices, int *buff, double *paths, unsigned char *dist, int *newdeg, double **edge_redudancy) { while (--nb_vertices) { int v = buff[nb_vertices]; if (target[v] > 0.0) { unsigned char pd = prev_dist(dist[v]); int *ww = neigh[v]; int k = 0; // pick ONE father at random double father_index = my_random01() * paths[v]; double f = 0.0; int father = -1; while (f < father_index) { while (dist[father = ww[k++]] != pd) { } f += paths[father]; } // increase target[] of father target[father] += target[v]; // add edge, if necessary if (newdeg != NULL) { add_traceroute_edge(v, k - 1, newdeg, edge_redudancy, target[v]); } } // clear dist[] dist[v] = 0; } dist[buff[0]] = 0; } // dist[] MUST be full of zeros !!!! void graph_molloy_opt::explore_asp(double *target, int nb_vertices, int *buff, double *paths, unsigned char *dist, int *newdeg, double **edge_redudancy) { while (--nb_vertices) { int v = buff[nb_vertices]; if (target[v] > 0.0) { unsigned char pd = prev_dist(dist[v]); int *ww = neigh[v]; int dv = deg[v]; double f = target[v] / paths[v]; // pick ALL fathers int father; for (int k = 0; k < dv; k++) if (dist[father = ww[k]] == pd) { // increase target[] of father target[father] += paths[father] * f; // add edge, if necessary if (newdeg != NULL) { add_traceroute_edge(v, k, newdeg, edge_redudancy, target[v]); } } } // clear dist[] dist[v] = 0; } dist[buff[0]] = 0; } // dist[] MUST be full of zeros !!!! void graph_molloy_opt::explore_rsp(double *target, int nb_vertices, int *buff, double *paths, unsigned char *dist, int *newdeg, double** edge_redudancy) { while (--nb_vertices) { int v = buff[nb_vertices]; if (target[v] > 0.0) { unsigned char pd = prev_dist(dist[v]); int *ww = neigh[v]; // for all fathers : do we take it ? int paths_left = int(target[v]); double father_index = paths[v]; int father; for (int k = 0; k < deg[v]; k++) if (dist[father = ww[k]] == pd) { double pf = paths[father]; int to_add_to_father = my_binomial(pf / father_index, paths_left); father_index -= pf; if (to_add_to_father > 0) { paths_left -= to_add_to_father; // increase target[] of father target[father] += to_add_to_father; // add edge, if necessary if (newdeg != NULL) { add_traceroute_edge(v, k, newdeg, edge_redudancy, target[v]); } } } } // clear dist[] dist[v] = 0; } dist[buff[0]] = 0; } double *graph_molloy_opt::vertex_betweenness(int mode, bool trivial_paths) { char MODES[3] = {'U', 'A', 'R'}; igraph_statusf("Computing vertex betweenness %cSP...", 0, MODES[mode]); // breadth-first search vertex fifo int *buff = new int[n]; // breadth-first search path count double *paths = new double[n]; // breadth-first search distance vector unsigned char *dist = new unsigned char[n]; // global betweenness double *b = new double[n]; // local betweenness (for one source) double *target = new double[n]; // init all int progress = 0; memset(dist, 0, sizeof(unsigned char)*n); for (double *yo = target + n; (yo--) != target; *yo = 1.0) { } for (double *yo = b + n; (yo--) != b; *yo = 0.0) { } int progress_steps = max(1000, n / 10); // Main loop for (int v0 = 0; v0 < n; v0++) { // Verbose if (v0 > (progress * n) / progress_steps) { progress++; igraph_progressf("Computing vertex betweenness %cSP", 100.0 * double(progress) / double(progress_steps), 0, MODES[mode]); } // Breadth-first search int nb_vertices = breadth_path_search(v0, buff, paths, dist); // initialize target[vertices in component] to 1 //for(int *yo = buff+nb_vertices; (yo--)!=buff; target[*yo]=1.0); // backwards-cumulative exploration switch (mode) { case MODE_USP: explore_usp(target, nb_vertices, buff, paths, dist); break; case MODE_ASP: explore_asp(target, nb_vertices, buff, paths, dist); break; case MODE_RSP: explore_rsp(target, nb_vertices, buff, paths, dist); break; default: IGRAPH_WARNING("graph_molloy_opt::vertex_betweenness() " "called with Invalid Mode"); } // add targets[vertices in component] to global betweenness and reset targets[] if (nb_vertices == n) { // cache optimization if all vertices are in component double *bb = b; double *tt_end = target + n; if (trivial_paths) for (double *yo = target; yo != tt_end; * (bb++) += *(yo++)) {} else { for (double *yo = target; yo != tt_end; * (bb++) += (*(yo++) - 1.0)) { } b[*buff] -= (target[*buff] - 1.0); } for (double *yo = target; yo != tt_end; * (yo++) = 1.0) { } } else { if (trivial_paths) for (int *yo = buff + nb_vertices; (yo--) != buff; b[*yo] += target[*yo]) { } else for (int *yo = buff + nb_vertices; (--yo) != buff; b[*yo] += (target[*yo] - 1.0)) { } for (int *yo = buff + nb_vertices; (yo--) != buff; target[*yo] = 1.0) { } } } // Clean all & return delete[] target; delete[] dist; delete[] buff; delete[] paths; igraph_status("Done\n", 0); return b; } double graph_molloy_opt::traceroute_sample(int mode, int nb_src, int *src, int nb_dst, int* dst, double *redudancy, double **edge_redudancy) { // verify & verbose assert(verify()); char MODES[3] = {'U', 'A', 'R'}; igraph_statusf("traceroute %cSP on G(N=%d,M=%d) with %d src and %d dst...", 0, MODES[mode], nbvertices_real(), nbarcs(), nb_src, nb_dst); // create dst[] buffer if necessary bool newdist = dst == NULL; if (newdist) { dst = new int[n]; } // breadth-first search vertex fifo int *buff = new int[n]; // breadth-first search path count double *paths = new double[n]; // breadth-first search distance vector unsigned char *dist = new unsigned char[n]; // newdeg[] allows to tag discovered edges int *newdeg = new int[n]; // target[v] is > 0 if v is a destination double *target = new double[n]; // init all int i; memset(dist, 0, sizeof(unsigned char)*n); memset(newdeg, 0, sizeof(int)*n); for (double *yo = target + n; (yo--) != target; *yo = 0.0) { } if (redudancy != NULL) for (double *yo = redudancy + n; (yo--) != redudancy; *yo = 0.0) { } // src_0 counts the number of sources having degree 0 int src_0 = 0; // nopath counts the number of pairs (src,dst) having no possible path int nopath = 0; // nb_paths & total_dist are for the average distance estimator int nb_paths = 0; double total_dist = 0; // s will be the current source int s; while (nb_src--) if (deg[s = *(src++)] == 0) { src_0++; } else { // breadth-first search int nb_vertices = breadth_path_search(s, buff, paths, dist); // do we have to pick new destinations ? if (newdist) { pick_random_dst(double(nb_dst), NULL, dst); } // mark reachable destinations as "targets" for (i = 0; i < nb_dst; i++) { if (dist[dst[i]] != 0) { target[dst[i]] = 1.0; } else { nopath++; } } // compute avg_dist estimator int current_dist = 0; unsigned char curr_dist = 1; for (int p = 1; p < nb_vertices; p++) { int v = buff[p]; if (dist[v] != curr_dist) { curr_dist = dist[v]; current_dist++; } if (target[v] > 0.0) { total_dist += double(current_dist); nb_paths++; } } // substract target[] to redudancy if needed if (redudancy != NULL) for (i = 1; i < nb_vertices; i++) { redudancy[buff[i]] -= (target[buff[i]]); } // traceroute exploration switch (mode) { case MODE_USP: explore_usp(target, nb_vertices, buff, paths, dist, newdeg, edge_redudancy); break; case MODE_ASP: explore_asp(target, nb_vertices, buff, paths, dist, newdeg, edge_redudancy); break; case MODE_RSP: explore_rsp(target, nb_vertices, buff, paths, dist, newdeg, edge_redudancy); break; default: IGRAPH_WARNING("graph_molloy_opt::traceroute_sample() called " "with Invalid Mode"); } // add target[] to redudancy[] if needed if (redudancy != NULL) for (i = 1; i < nb_vertices; i++) { redudancy[buff[i]] += (target[buff[i]]); } // clear target[] for (int *yo = buff + nb_vertices; yo-- != buff; target[*yo] = 0.0) { } } // update degrees for (i = 0; i < n; i++) { deg[i] = newdeg[i]; } refresh_nbarcs(); // clean all delete[] buff; delete[] paths; delete[] dist; delete[] newdeg; delete[] target; if (newdist) { delete[] dst; } { igraph_statusf("discovered %d vertices and %d edges\n", 0, nbvertices_real(), nbarcs()); if (src_0) igraph_warningf("%d sources had degree 0\n", IGRAPH_FILE_BASENAME, __LINE__, -1, src_0); if (nopath) igraph_warningf("%d (src,dst) pairs had no possible path\n", IGRAPH_FILE_BASENAME, __LINE__, -1, nopath); } return total_dist / double(nb_paths); } int graph_molloy_opt::disconnecting_edges() { int removed = 0; while (is_connected()) { // replace random edge by loops int i; do { i = pick_random_vertex(); } while (i < 0 || deg[i] < 1); int *p = neigh[i] + (my_random() % deg[i]); int j = *p; *p = i; fast_rpl(neigh[j], i, j); removed++; } return removed; } void graph_molloy_opt::vertex_covering() { vertex_cover(n, links, deg, neigh); } // optimisations a faire : // 1/ arreter le breadth-first search qd on a vu toutes les dst // 2/ faire une seule redescente pour toutes les dst. double graph_molloy_opt::path_sampling(int *nb_dst, int *dst, double* redudancies, double **edge_redudancies) { assert(verify()); // do we have to store the destinations (for one src) in a temp buffer? bool NOMEM = (dst == NULL); if (NOMEM) { dst = new int[n]; } int i; int next_step = n + 1; { igraph_status("Sampling paths", 0); next_step = 0; } // breadth-first search buffers buff[] and dist[] int *buff = new int[n]; unsigned char *dist = new unsigned char[n]; for (i = 0; i < n; i++) { dist[i] = 0; } // nb_pos[] counts the number of possible paths to get to a vertex int *nb_pos = new int[n]; for (i = 0; i < n; i++) { nb_pos[i] = 0; } // newdeg[i] is the number of edges of vertex i "seen" by traceroute int *newdeg = new int[n]; for (i = 0; i < n; i++) { newdeg[i] = 0; } // src_0 counts the number of sources having degree 0 int src_0 = 0; // nopath counts the number of pairs (src,dst) having no possible path int nopath = 0; // nb_paths & total_dist are for the average distance estimator int nb_paths = 0; unsigned int total_dist = 0; unsigned int total_dist64 = 0; // s is the source of the breadth-first search for (int s = 0; s < n; s++) if (nb_dst[s] > 0) { if (deg[s] == 0) { src_0++; } else { if (s > next_step) { next_step = s + (n / 1000) + 1; igraph_progress("Sampling paths", double(s) / double(n), 0); } int v; // breadth-first search int *to_visit = buff; int *visited = buff; *(to_visit++) = s; dist[s] = 1; nb_pos[s] = 1; while (visited != to_visit) { v = *(visited++); unsigned char n_dist = next_dist(dist[v]); int *w0 = neigh[v]; for (int *w = w0 + deg[v]; w-- != w0; ) { unsigned char d2 = dist[*w]; if (d2 == 0) { dist[*w] = d2 = n_dist; *(to_visit++) = *w; } if (d2 == n_dist) { nb_pos[*w] += nb_pos[v]; } } } // for every target, pick a random path. int t_index = nb_dst[s]; // create dst[] if necessary if (NOMEM) { pick_random_src(double(t_index), NULL, dst); } while (t_index--) if (dist[v = *(dst++)] == 0) { nopath++; } else { #ifdef DEGSEQ_VL_DEBUG igraph_statusf("Sampling path %d -> %d\n", 0, s, v); #endif // DEGSEQ_VL_DEBUG nb_paths++; // while we haven't reached the source.. while (v != s) { // pick a random father int index = my_random() % nb_pos[v]; unsigned char p_dist = prev_dist(dist[v]); int *w = neigh[v]; int k = 0; int new_father; while (dist[new_father = w[k]] != p_dist || (index -= nb_pos[new_father]) >= 0) { k++; } // add edge add_traceroute_edge(v, k, newdeg, edge_redudancies, 1.0); if (redudancies != NULL && new_father != s) { redudancies[new_father] += 1.0; } // step down to father v = new_father; // increase total distance total_dist++; if (total_dist == 0) { total_dist64++; } } } // reset (int *)dst if necessary if (NOMEM) { dst -= nb_dst[s]; } // clear breadth-first search buffers while (visited != buff) { v = *(--visited); dist[v] = 0; nb_pos[v] = 0; } } } // update degrees for (i = 0; i < n; i++) { deg[i] = newdeg[i]; } refresh_nbarcs(); // clean delete[] newdeg; delete[] buff; delete[] dist; delete[] nb_pos; if (NOMEM) { delete[] dst; } if (VERBOSE()) { igraph_status("Sampling paths : Done \n", 0); if (src_0) igraph_warningf("%d sources had degree 0", IGRAPH_FILE_BASENAME, __LINE__, -1, src_0); if (nopath) igraph_warningf("%d (src,dst) pairs had no possible path", IGRAPH_FILE_BASENAME, __LINE__, -1, nopath); } double tdist = double(total_dist64); if (total_dist64 > 0) { tdist *= 4294967296.0; } tdist += double(total_dist); return tdist / double(nb_paths); } int *graph_molloy_opt::vertices_real(int &nb_v) { int *yo; if (nb_v < 0) { nb_v = 0; for (yo = deg; yo != deg + n; ) if (*(yo++) > 0) { nb_v++; } } if (nb_v == 0) { IGRAPH_WARNING("graph is empty"); return NULL; } int *buff = new int[nb_v]; yo = buff; for (int i = 0; i < n; i++) if (deg[i] > 0) { *(yo++) = i; } if (yo != buff + nb_v) { igraph_warningf("wrong #vertices in graph_molloy_opt::vertices_real(%d)", IGRAPH_FILE_BASENAME, __LINE__, -1, nb_v); delete[] buff; return NULL; } else { return buff; } } int *graph_molloy_opt::pick_random_vertices(int &k, int *output, int nb_v, int *among) { int i; bool CREATED_AMONG = false; if (among == NULL && k > 0) { among = vertices_real(nb_v); CREATED_AMONG = true; } if (k > nb_v) { igraph_warningf("Warning : tried to pick %d among %d vertices. " "Picked only %d", IGRAPH_FILE_BASENAME, __LINE__, -1, k, nb_v, nb_v); k = nb_v; } if (k > 0) { if (output == NULL) { output = new int[k]; } for (i = 0; i < k; i++) { int tmp = i + my_random() % (nb_v - i); output[i] = among[tmp]; among[tmp] = among[i]; among[i] = output[i]; } } if (CREATED_AMONG) { delete[] among; } return output; } int *graph_molloy_opt::pick_random_src(double k, int *nb, int* buff, int nb_v, int* among) { bool AMONG_CREATED = false; if (among == NULL || nb_v < 0) { AMONG_CREATED = true; among = vertices_real(nb_v); } int kk = int(floor(0.5 + (k >= 1.0 ? k : k * double(nb_v)))); if (kk == 0) { kk = 1; } int *yo = pick_random_vertices(kk, buff, nb_v, among); if (nb != NULL) { *nb = kk; } if (AMONG_CREATED) { delete[] among; } return yo; } int *graph_molloy_opt::pick_random_dst(double k, int *nb, int* buff, int nb_v, int* among) { bool AMONG_CREATED = false; if (among == NULL || nb_v < 0) { AMONG_CREATED = true; among = vertices_real(nb_v); } int kk = int(floor(0.5 + (k > 1.0 ? k : k * double(nb_v)))); if (kk == 0) { kk = 1; } int *yo = pick_random_vertices(kk, buff, nb_v, among); if (nb != NULL) { *nb = kk; } if (AMONG_CREATED) { delete[] among; } return yo; } int graph_molloy_opt::core() { box_list b(n, deg); int v; int removed = 0; while ((v = b.get_one()) >= 0) { b.pop_vertex(v, neigh); deg[v] = 0; removed++; } refresh_nbarcs(); return removed; } int graph_molloy_opt::try_disconnect(int K, int max_tries) { bool *visited = new bool[n]; for (bool *p = visited + n; p != visited; * (--p) = false) { } int *Kbuff = new int[K]; int tries = 0; int next_step = -1; if (VERBOSE()) { next_step = 0; } bool yo = true; while (yo && tries < max_tries) { if (tries == next_step) { igraph_statusf("Trying to disconnect the graph... " "%d edges swaps done so far", 0, tries); next_step += 100; } int v1 = pick_random_vertex(); int v2 = pick_random_vertex(); int w1 = *(random_neighbour(v1)); int w2 = *(random_neighbour(v2)); if (swap_edges_simple(v1, w1, v2, w2)) { tries++; yo = (!isolated(v1, K, Kbuff, visited) && !isolated(v2, K, Kbuff, visited) && !is_connected()); swap_edges(v1, w2, v2, w1); } } delete[] visited; delete[] Kbuff; return tries; } bool graph_molloy_opt::isolated(int v, int K, int *Kbuff, bool *visited) { if (K < 2) { return false; } #ifdef OPT_ISOLATED if (K <= deg[v] + 1) { return false; } #endif //OPT_ISOLATED int *seen = Kbuff; int *known = Kbuff; int *max = Kbuff + (K - 1); *(known++) = v; visited[v] = true; bool is_isolated = true; while (known != seen) { v = *(seen++); int *w = neigh[v]; for (int d = deg[v]; d--; w++) if (!visited[*w]) { #ifdef OPT_ISOLATED if (K <= deg[*w] + 1 || known == max) { #else //OPT_ISOLATED if (known == max) { #endif //OPT_ISOLATED is_isolated = false; goto end_isolated; } visited[*w] = true; *(known++) = *w; } } end_isolated: // Undo the changes to visited[]... while (known != Kbuff) { visited[*(--known)] = false; } return is_isolated; } double graph_molloy_opt::rho(int mode, int nb_src, int *src, int nb_dst, int *dst) { assert(verify()); // create dst[] buffer if necessary bool newdist = dst == NULL; if (newdist) { dst = new int[n]; } // breadth-first search vertex fifo int *buff = new int[n]; // breadth-first search path count double *paths = new double[n]; // breadth-first search distance vector unsigned char *dist = new unsigned char[n]; // target[v] is > 0 if v is a destination double *target = new double[n]; // times_seen count the times we saw each vertex int *times_seen = new int[n]; // init all int i; memset(dist, 0, sizeof(unsigned char)*n); memset(times_seen, 0, sizeof(int)*n); for (double *yo = target + n; (yo--) != target; *yo = 0.0) { } // src_0 counts the number of sources having degree 0 int src_0 = 0; // nopath counts the number of pairs (src,dst) having no possible path int nopath = 0; // s will be the current source int s; for (int nsrc = 0; nsrc < nb_src; nsrc++) if (deg[s = *(src++)] == 0) { src_0++; } else { // breadth-first search int nb_vertices = breadth_path_search(s, buff, paths, dist); // do we have to pick new destinations ? if (newdist) { pick_random_dst(double(nb_dst), NULL, dst); } // mark reachable destinations as "targets" and substract one time_seen for (i = 0; i < nb_dst; i++) { if (dist[dst[i]] != 0) { target[dst[i]] = 1.0; } else { nopath++; } } // traceroute exploration switch (mode) { case MODE_USP: explore_usp(target, nb_vertices, buff, paths, dist); break; case MODE_ASP: explore_asp(target, nb_vertices, buff, paths, dist); break; case MODE_RSP: explore_rsp(target, nb_vertices, buff, paths, dist); break; default: IGRAPH_WARNING("graph_molloy_opt::rho() called with Invalid Mode"); } // remove destinations that weren't discovered by a path coming through for (i = 0; i < nb_dst; i++) { int yo = dst[i]; if (target[yo] == 1.0) { target[yo] = 0.0; } } // add target[] to times_seen[] for (i = 1; i < nb_vertices; i++) { int yo = buff[i]; if (target[yo] != 0.0) { target[yo] = 0.0; times_seen[yo]++; } } // also clear the source target[buff[0]] = 0.0; } // clean all delete[] buff; delete[] paths; delete[] dist; delete[] target; if (newdist) { delete[] dst; } // compute rho double sum_nij = 0.0; double sum_ni = 0.0; for (i = 0; i < n; i++) { double d = double(times_seen[i]); sum_ni += d; sum_nij += d * d; } delete[] times_seen; { igraph_status("done\n", 0); if (src_0) igraph_warningf("%d sources had degree 0", IGRAPH_FILE_BASENAME, __LINE__, -1, src_0); if (nopath) igraph_warningf("%d (src,dst) pairs had no possible path", IGRAPH_FILE_BASENAME, __LINE__, -1, nopath); } return (sum_nij - sum_ni) * double(n) * double(nb_src) / (sum_ni * sum_ni * double(nb_src - 1)); } void graph_molloy_opt::sort() { for (int v = 0; v < n; v++) { qsort(neigh[v], deg[v]); } } int* graph_molloy_opt::sort_vertices(int *buff) { // pre-sort vertices by degrees buff = boxsort(deg, n, buff); // sort vertices having the same degrees int i = 0; while (i < n) { int d = deg[buff[i]]; int j = i + 1; while (j < n && deg[buff[j]] == d) { j++; } lex_qsort(neigh, buff + i, j - i, d); i = j; } return buff; } int graph_molloy_opt::cycles(int v) { return v; } // void graph_molloy_opt::remove_vertex(int v) { // fprintf(stderr,"Warning : graph_molloy_opt::remove_vertex(%d) called",v); // } bool graph_molloy_opt::verify(int mode) { IGRAPH_UNUSED(mode); #ifndef NDEBUG int i, j, k; assert(neigh[0] == links); // verify edges count if ((mode & VERIFY_NOARCS) == 0) { int sum = 0; for (i = 0; i < n; i++) { sum += deg[i]; } assert(sum == a); } // verify neigh[] and deg[] compatibility if ((mode & VERIFY_NONEIGH) == 0) for (i = 0; i < n - 1; i++) { assert(neigh[i] + deg[i] == neigh[i + 1]); } // verify vertex range for (i = 0; i < a; i++) { assert(links[i] >= 0 && links[i] < n); } // verify simplicity // for(i=0; i 0); } #endif return true; } /*___________________________________________________________________________________ Not to use anymore : use graph_molloy_hash class instead void graph_molloy_opt::shuffle(long times) { while(times) { int f1 = links[my_random()%a]; int f2 = links[my_random()%a]; int t1 = neigh[f1][my_random()%deg[f1]]; int t2 = neigh[f2][my_random()%deg[f2]]; if(swap_edges_simple(f1,t1,f2,t2)) times--; } } long graph_molloy_opt::connected_shuffle(long times) { //assert(verify()); #ifdef PERFORMANCE_MONITOR long failures = 0; long successes = 0; double avg_K = 0.0; long avg_T = 0; #endif //PERFORMANCE_MONITOR long nb_swaps = 0; long T = min(a,times)/10; double double_K = 1.0; int K = int(double_K); double Q1 = 1.35; double Q2 = 1.01; int *Kbuff = new int[K]; bool *visited = new bool[n]; for(int i=0; inb_swaps) { // Backup graph #ifdef PERFORMANCE_MONITOR avg_K+=double_K; avg_T+=T; #endif //PERFORMANCE_MONITOR int *save = backup(); //assert(verify()); // Swaps long swaps = 0; for(int i=T; i>0; i--) { // Pick two random vertices int f1 = pick_random_vertex(); int f2 = pick_random_vertex(); if(f1==f2) continue; // Pick two random neighbours int *f1t1 = random_neighbour(f1); int t1 = *f1t1; int *f2t2 = random_neighbour(f2); int t2 = *f2t2; // test simplicity if(t1!=t2 && f1!=t2 && f2!=t1 && !is_edge(f1,t2) && !is_edge(f2,t1)) { // swap *f1t1 = t2; *f2t2 = t1; int *t1f1 = fast_rpl(neigh[t1],f1,f2); int *t2f2 = fast_rpl(neigh[t2],f2,f1); // isolation test if(isolated(f1, K, Kbuff, visited) || isolated(f2, K, Kbuff, visited)) { // undo swap *t1f1 = f1; *t2f2 = f2; *f1t1 = t1; *f2t2 = t2; } else swaps++; } } //assert(verify()); // test connectivity bool ok = is_connected(); #ifdef PERFORMANCE_MONITOR if(ok) successes++; else failures++; #endif //PERFORMANCE_MONITOR if(ok) { nb_swaps += swaps; // adjust K and T if((K+10)*T>5*a) { double_K/=Q2; K = int(double_K); } else T*=2; } else { restore(save); //assert(verify()); double_K*=Q1; K = int(double_K); delete[] Kbuff; Kbuff = new int[K]; } delete[] save; } #ifdef PERFORMANCE_MONITOR fprintf(stderr,"\n*** Performance Monitor ***\n"); fprintf(stderr," - Connectivity test successes : %ld\n",successes); fprintf(stderr," - Connectivity test failures : %ld\n",failures); fprintf(stderr," - Average window : %ld\n",avg_T/long(successes+failures)); fprintf(stderr," - Average isolation test width : %f\n",avg_K/double(successes+failures)); #endif //PERFORMANCE_MONITOR return nb_swaps; } bool graph_molloy_opt::try_shuffle(int T, int K) { int i; int *Kbuff = NULL; if(K>0) Kbuff = new int[K]; bool *visited = new bool[n]; for(i=0; i0; i--) { // Pick two random vertices int f1 = pick_random_vertex(); int f2 = pick_random_vertex(); if(f1==f2) continue; // Pick two random neighbours int *f1t1 = random_neighbour(f1); int t1 = *f1t1; int *f2t2 = random_neighbour(f2); int t2 = *f2t2; // test simplicity if(t1!=t2 && f1!=t2 && f2!=t1 && is_edge(f1,t2) && !is_edge(f2,t1)) { // swap *f1t1 = t2; *f2t2 = t1; int *t1f1 = fast_rpl(neigh[t1],f1,f2); int *t2f2 = fast_rpl(neigh[t2],f2,f1); // isolation test if(isolated(f1, K, Kbuff, visited) || isolated(f2, K, Kbuff, visited)) { // undo swap *t1f1 = f1; *t2f2 = f2; *f1t1 = t1; *f2t2 = t2; } } } delete[] visited; if(Kbuff != NULL) delete[] Kbuff; bool yo = is_connected(); restore(back); delete[] back; return yo; } double graph_molloy_opt::window(int K, double ratio) { int steps = 100; double T = double(a*10); double q2 = 0.1; double q1 = pow(q2,(ratio-1.0)/ratio); int failures = 0; int successes = 0; int *Kbuff = new int[K]; bool *visited = new bool[n]; while(successes<10*steps) { int *back=backup(); for(int i=int(T); i>0; i--) { // Pick two random vertices int f1 = links[my_random()%a]; int f2 = links[my_random()%a]; if(f1==f2) continue; // Pick two random neighbours int *f1t1 = neigh[f1]+my_random()%deg[f1]; int *f2t2 = neigh[f2]+my_random()%deg[f2]; int t1 = *f1t1; int t2 = *f2t2; // test simplicity if(t1!=t2 && f1!=t2 && f2!=t1 && is_edge(f1,t2) && !is_edge(f2,t1)) { // swap *f1t1 = t2; *f2t2 = t1; int *t1f1 = fast_rpl(neigh[t1],f1,f2); int *t2f2 = fast_rpl(neigh[t2],f2,f1); // isolation test if(isolated(f1, K, Kbuff, visited) || isolated(f2, K, Kbuff, visited)) { // undo swap *t1f1 = f1; *t2f2 = f2; *f1t1 = t1; *f2t2 = t2; } } } if(is_connected()) { T *= q1; if(T>double(5*a)) T=double(5*a); successes++; if((successes%steps)==0) { q2 = sqrt(q2); q1 = sqrt(q1); } } else { T*=q2; failures++; } if(VERBOSE()) fprintf(stderr,"."); restore(back); delete[] back; } delete[] Kbuff; delete[] visited; if(VERBOSE()) fprintf(stderr,"Failures:%d Successes:%d\n",failures, successes); return T; } double graph_molloy_opt::eval_K(int quality) { double K = 5.0; double avg_K = 1.0; for(int i=quality; i--; ) { int int_K = int(floor(K+0.5)); if(try_shuffle(a/(int_K+1),int_K)) { K*=0.8; fprintf(stderr,"+"); } else { K*=1.25; fprintf(stderr,"-"); } if(ideg[t2] ? f1 : t2, K, Kbuff, visited); sum_K += effective_isolated(deg[f2]>deg[t1] ? f2 : t1, K, Kbuff, visited); // undo swap swap_edges(f1,t2,f2,t1); // assert(verify()); } delete[] Kbuff; delete[] visited; return double(sum_K)/double(2*quality); } //___________________________________________________________________________________ */ /***** NOT USED ANYMORE (Modif 22/04/2005) ****** int64_t *graph_molloy_opt::vertex_betweenness_usp(bool trivial_paths) { if(VERBOSE()) fprintf(stderr,"Computing vertex betweenness USP..."); int i; unsigned char *dist = new unsigned char[n]; int *buff = new int[n]; int64_t *b = new int64_t[n]; int *bb = new int[n]; int *dd = new int[max_degree()]; for(i=0; i(progress*n)/1000) { progress++; fprintf(stderr,"\rComputing vertex betweenness USP : %d.%d%% ",progress/10,progress%10); } int nb_vertices = width_search(dist, buff, v0); int nv = nb_vertices; for(i=0; i(progress*n)/1000) { progress++; fprintf(stderr,"\rComputing vertex betweenness RSP : %d.%d%% ",progress/10,progress%10); } int nb_vertices = width_search(dist, buff, v0); int nv = nb_vertices; for(i=0; i1 && to_give>2*n_father) { int o = rng.binomial(1.0/n_father,to_give); to_give -= o; bb[dd[--n_father]]+=o; } if(n_father==1) bb[dd[0]]+=to_give; else { while(to_give--) bb[dd[my_random()%n_father]]++; } } if(trivial_paths) bb[v]++; } for(i=0; i0) { if(VERBOSE()==VERBOSE_LOTS && v0>(progress*n)/1000) { progress++; fprintf(stderr,"\rComputing vertex betweenness ASP : %d.%d%% ",progress/10,progress%10); } int nb_vertices = width_search(dist, buff, v0); if(!trivial_paths) dist[v0]=2; int nv = nb_vertices; for(i=0; i. */ #ifndef GRAPH_MOLLOY_HASH_H #define GRAPH_MOLLOY_HASH_H #include "gengraph_definitions.h" #include "gengraph_hash.h" #include "gengraph_degree_sequence.h" #include #include // This class handles graphs with a constant degree sequence. #define FINAL_HEURISTICS 0 #define GKAN_HEURISTICS 1 #define FAB_HEURISTICS 2 #define OPTIMAL_HEURISTICS 3 #define BRUTE_FORCE_HEURISTICS 4 namespace gengraph { //**************************** // class graph_molloy_hash //**************************** class graph_molloy_hash { private: // Number of vertices int n; //Number of arcs ( = #edges * 2 ) int a; //Total size of links[] int size; // The degree sequence of the graph int *deg; // The array containing all links int *links; // The array containing pointers to adjacency list of every vertices int **neigh; // Counts total size void compute_size(); // Build neigh with deg and links void compute_neigh(); // Allocate memory according to degree_sequence (for constructor use only!!) int alloc(degree_sequence &); // Add edge (u,v). Return FALSE if vertex a is already full. // WARNING : only to be used by havelhakimi(), restore() or constructors inline bool add_edge(int u, int v, int *realdeg) { int deg_u = realdeg[u]; if (deg_u == deg[u]) { return false; } // Check that edge was not already inserted assert(fast_search(neigh[u], int((u == n - 1 ? links + size : neigh[u + 1]) - neigh[u]), v) == NULL); assert(fast_search(neigh[v], int((v == n - 1 ? links + size : neigh[v + 1]) - neigh[v]), u) == NULL); assert(deg[u] < deg_u); int deg_v = realdeg[v]; if (IS_HASH(deg_u)) { *H_add(neigh[u], HASH_EXPAND(deg_u), v) = v; } else { neigh[u][deg[u]] = v; } if (IS_HASH(deg_v)) { *H_add(neigh[v], HASH_EXPAND(deg_v), u) = u; } else { neigh[v][deg[v]] = u; } deg[u]++; deg[v]++; // Check that edge was actually inserted assert(fast_search(neigh[u], int((u == n - 1 ? links + size : neigh[u + 1]) - neigh[u]), v) != NULL); assert(fast_search(neigh[v], int((v == n - 1 ? links + size : neigh[v + 1]) - neigh[v]), u) != NULL); return true; } // Swap edges inline void swap_edges(int from1, int to1, int from2, int to2) { H_rpl(neigh[from1], deg[from1], to1, to2); H_rpl(neigh[from2], deg[from2], to2, to1); H_rpl(neigh[to1], deg[to1], from1, from2); H_rpl(neigh[to2], deg[to2], from2, from1); } // Backup graph [sizeof(int) bytes per edge] int* backup(); // Test if vertex is in an isolated component of size dmax. void depth_isolated(int v, long &calls, int &left_to_explore, int dmax, int * &Kbuff, bool *visited); public: //degree of v inline int degree(const int v) { return deg[v]; }; // For debug purposes : verify validity of the graph (symetry, simplicity) bool verify(); // Destroy deg[], neigh[] and links[] ~graph_molloy_hash(); // Allocate memory for the graph. Create deg and links. No edge is created. graph_molloy_hash(degree_sequence &); // Create graph from hard copy graph_molloy_hash(int *); // Create hard copy of graph int *hard_copy(); // Restore from backup void restore(int* back); //Clear hash tables void init(); // nb arcs inline int nbarcs() { return a; }; // nb vertices inline int nbvertices() { return n; }; // print graph in SUCC_LIST mode, in stdout void print(FILE *f = stdout); int print(igraph_t *graph); // Test if graph is connected bool is_connected(); // is edge ? inline bool is_edge(int u, int v) { assert(H_is(neigh[u], deg[u], v) == (fast_search(neigh[u], HASH_SIZE(deg[u]), v) != NULL)); assert(H_is(neigh[v], deg[v], u) == (fast_search(neigh[v], HASH_SIZE(deg[v]), u) != NULL)); assert(H_is(neigh[u], deg[u], v) == H_is(neigh[v], deg[v], u)); if (deg[u] < deg[v]) { return H_is(neigh[u], deg[u], v); } else { return H_is(neigh[v], deg[v], u); } } // Random edge swap ATTEMPT. Return 1 if attempt was a succes, 0 otherwise int random_edge_swap(int K = 0, int *Kbuff = NULL, bool *visited = NULL); // Connected Shuffle unsigned long shuffle(unsigned long, unsigned long, int type); // Optimal window for the gkantsidis heuristics int optimal_window(); // Average unitary cost per post-validated edge swap, for some window double average_cost(int T, int *back, double min_cost); // Get caracteristic K double eval_K(int quality = 100); // Get effective K double effective_K(int K, int quality = 10000); // Try to shuffle T times. Return true if at the end, the graph was still connected. bool try_shuffle(int T, int K, int *back = NULL); /*_____________________________________________________________________________ Not to use anymore : use graph_molloy_opt class instead private: // breadth-first search. Store the distance (modulo 3) in dist[]. Returns eplorated component size. int width_search(unsigned char *dist, int *buff, int v0=0); public: // Create graph graph_molloy_hash(FILE *f); // Bind the graph avoiding multiple edges or self-edges (return false if fail) bool havelhakimi(); // Get the graph connected (return false if fail) bool make_connected(); // "Fab" Shuffle (Optimized heuristic of Gkantsidis algo.) long long fab_connected_shuffle(long long); // Naive Shuffle long long slow_connected_shuffle(long long); // Maximum degree int max_degree(); // compute vertex betweenness : for each vertex, a unique random shortest path is chosen. // this choice is consistent (if shortest path from a to c goes through b and then d, // then shortest path from a to d goes through b). If(trivial path), also count all the // shortest paths where vertex is an extremity int *vertex_betweenness_rsp(bool trivial_path); // same, but when multiple shortest path are possible, average the weights. double *vertex_betweenness_asp(bool trivial_path); //___________________________________________________________________________________ */ }; } // namespace gengraph #endif //GRAPH_MOLLOY_HASH_H leidenbase/src/core/games/degree_sequence_vl/gengraph_definitions.h0000644000176200001440000001104514447675374025371 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DEFINITIONS_H #define DEFINITIONS_H #include #include #include #include "internal/hacks.h" namespace gengraph { // Max line size in files #define FBUFF_SIZE 1000000 // disable lousy VC++ warnings #ifdef _ATL_VER_ #pragma warning(disable : 4127) #endif //_ATL_VER_ // Verbose #define VERBOSE_NONE 0 #define VERBOSE_SOME 1 #define VERBOSE_LOTS 2 int VERBOSE(); void SET_VERBOSE(int v); // Random number generator void my_srandom(int); int my_random(); int my_binomial(double pp, int n); double my_random01(); // (0,1] #define MY_RAND_MAX 0x7FFFFFFF // IPv4 address direct translation into 32-bit uint + special IP defs typedef unsigned int ip_addr; #define IP_NONE 0x7FFFFFFF #define IP_STAR 0x00000000 #define IP_MYSELF 0x7F000001 //inline double round(double x) throw () { return (floor(0.5+x)); } // Min & Max #ifndef min #define defmin(type) inline type min(type a, type b) { return ab ? a : b; } defmax(int) defmax(double) defmax(unsigned long) #endif //max // Traceroute Sampling #define MODE_USP 0 #define MODE_ASP 1 #define MODE_RSP 2 // Debug definitions //#define PERFORMANCE_MONITOR //#define OPT_ISOLATED // Max Int #ifndef MAX_INT #define MAX_INT 0x7FFFFFFF #endif //MAX_INT //Edge type typedef struct { int from; int to; } edge; // Tag Int #define TAG_INT 0x40000000 // Oldies .... #define S_VECTOR_RAW //********************* // Routine definitions //********************* /* log(1+x) inline double logp(double x) { if(fabs(x)<1e-6) return x+0.5*x*x+0.333333333333333*x*x*x; else return log(1.0+x); } */ //Fast search or replace inline int* fast_rpl(int *m, const int a, const int b) { while (*m != a) { m++; } *m = b; return m; } inline int* fast_search(int *m, const int size, const int a) { int *p = m + size; while (m != p--) if (*p == a) { return p; } return NULL; } // Lovely percentage print // inline void print_percent(double yo, FILE *f = stderr) { // int arf = int(100.0*yo); // if(double(arf)>100.0*yo) arf--; // if(arf<100) fprintf(f," "); // if(arf<10) fprintf(f," "); // fprintf(f,"%d.%d%%",arf,int(1000.0*yo-double(10*arf))); // } // Skips non-numerical chars, then numerical chars, then non-numerical chars. inline char skip_int(char* &c) { while (*c < '0' || *c > '9') { c++; } while (*c >= '0' && *c <= '9') { c++; } while (*c != 0 && (*c < '0' || *c > '9')) { c++; } return *c; } // distance+1 modulo 255 for breadth-first search inline unsigned char next_dist(const unsigned char c) { return c == 255 ? 1 : c + 1; } inline unsigned char prev_dist(const unsigned char c) { return c == 1 ? 255 : c - 1; } // 1/(RANDMAX+1) #define inv_RANDMAX (1.0/(1.0+double(MY_RAND_MAX))) // random number in ]0,1[, _very_ accurate around 0 inline double random_float() { int r = my_random(); double mul = inv_RANDMAX; while (r <= 0x7FFFFF) { r <<= 8; r += (my_random() & 0xFF); mul *= (1.0 / 256.0); } return double(r) * mul; } // Return true with probability p. Very accurate when p is small. #define test_proba(p) (random_float()<(p)) // Random bit generator, sparwise. static int _random_bits_stored = 0; static int _random_bits = 0; inline int random_bit() { int a = _random_bits; _random_bits = a >> 1; if (_random_bits_stored--) { return a & 0x1; } a = my_random(); _random_bits = a >> 1; _random_bits_stored = 30; return a & 0x1; } // Hash Profiling (see hash.h) void _hash_prof(); } // namespace gengraph #endif //DEFINITIONS_H leidenbase/src/core/games/degree_sequence_vl/gengraph_degree_sequence.cpp0000644000176200001440000002675214447675374026547 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gengraph_definitions.h" #include "gengraph_random.h" #include "gengraph_powerlaw.h" #include "gengraph_degree_sequence.h" #include "gengraph_hash.h" #include "igraph_statusbar.h" #include #include #include #include #include #include // using namespace __gnu_cxx; using namespace std; namespace gengraph { // shuffle an int[] randomly void random_permute(int *a, int n); // sort an array of positive integers in time & place O(n + max) void cumul_sort(int *q, int n); void degree_sequence::detach() { deg = NULL; } degree_sequence::~degree_sequence() { if (deg != NULL) { delete[] deg; } deg = NULL; } void degree_sequence::make_even(int mini, int maxi) { if (total % 2 == 0) { return; } if (maxi < 0) { maxi = 0x7FFFFFFF; } int i; for (i = 0; i < n; i++) { if (deg[i] > mini) { deg[i]--; total--; break; } else if (deg[i] < maxi) { deg[i]++; total++; break; } } if (i == n) { IGRAPH_WARNING("Warning: degree_sequence::make_even() forced one " "degree to go over degmax"); deg[0]++; total++; } } void degree_sequence::shuffle() { random_permute(deg, n); } void degree_sequence::sort() { cumul_sort(deg, n); } void degree_sequence::compute_total() { total = 0; for (int i = 0; i < n; i++) { total += deg[i]; } } degree_sequence:: degree_sequence(int n0, int *degs) { deg = degs; n = n0; compute_total(); } degree_sequence:: degree_sequence(const igraph_vector_t *out_seq) { n = igraph_vector_size(out_seq); deg = new int[n]; for (long int i = 0; i < n; i++) { deg[i] = VECTOR(*out_seq)[i]; } compute_total(); } #ifndef FBUFF_SIZE #define FBUFF_SIZE 999 #endif //FBUFF_SIZE // degree_sequence::degree_sequence(FILE *f, bool DISTRIB) { // n = 0; // total = 0; // char *buff = new char[FBUFF_SIZE]; // char *c; // vector degree; // if(!DISTRIB) { // // Input is a 'raw' degree sequence d0 d1 d2 d3 ... // while(fgets(buff, FBUFF_SIZE, f)) { // int d = strtol(buff, &c, 10); // if(c == buff) continue; // degree.push_back(d); // total += d; // } // n = int(degree.size()); // deg = new int[n]; // int *yo = deg; // vector::iterator end = degree.end(); // for(vector::iterator it=degree.begin(); it!=end; *(yo++) = *(it++)); // } // else { // // Input is a degree distribution : d0 #(degree=d0), d1 #(degree=d1), ... // vector n_with_degree; // int line = 0; // int syntax = 0; // int ignored = 0; // int first_syntax = 0; // int first_ignored = 0; // while(fgets(buff, FBUFF_SIZE, f)) { // line++; // int d = strtol(buff, &c, 10); // if(c == buff) { ignored++; first_ignored = line; continue; } // char *cc; // int i = strtol(c, &cc, 10); // if(cc == c) { syntax++; first_syntax = line; continue; } // n += i; // total += i*d; // degree.push_back(d); // n_with_degree.push_back(i); // if( cc != c) { syntax++; first_syntax = line; } // } // if(VERBOSE()) { // if(ignored > 0) fprintf(stderr,"Ignored %d lines (first was line #%d)\n", ignored, first_ignored); // if(syntax > 0) fprintf(stderr,"Found %d probable syntax errors (first was line #%d)\n", syntax, first_syntax); // } // deg = new int[n]; // int *yo = deg; // vector::iterator it_n = n_with_degree.begin(); // for(vector::iterator it = degree.begin(); it != degree.end(); it++) // for(int k = *(it_n++); k--; *yo++ = *it); // } // if(VERBOSE()) { // if(total % 2 != 0) fprintf(stderr,"Warning: degree sequence is odd\n"); // fprintf(stderr,"Degree sequence created. N=%d, 2M=%d\n", n, total); // } // } // n vertices, exponent, min degree, max degree, average degree (optional, default is -1) degree_sequence:: degree_sequence(int _n, double exp, int degmin, int degmax, double z) { n = _n; if (exp == 0.0) { // Binomial distribution if (z < 0) { throw std::invalid_argument( "Fatal error in degree_sequence constructor: " "positive average degree must be specified."); } if (degmax < 0) { degmax = n - 1; } total = int(floor(double(n) * z + 0.5)); deg = new int[n]; KW_RNG::RNG myrand; double p = (z - double(degmin)) / double(n); total = 0; for (int i = 0; i < n; i++) { do { deg[i] = 1 + myrand.binomial(p, n); } while (deg[i] > degmax); total += deg[i]; } } else { // Power-law distribution igraph_status("Creating powerlaw sampler...", 0); powerlaw pw(exp, degmin, degmax); if (z == -1.0) { pw.init(); igraph_statusf("done. Mean=%f\n", 0, pw.mean()); } else { double offset = pw.init_to_mean(z); igraph_statusf("done. Offset=%f, Mean=%f\n", 0, offset, pw.mean()); } deg = new int[n]; total = 0; int i; igraph_statusf("Sampling %d random numbers...", 0, n); for (i = 0; i < n; i++) { deg[i] = pw.sample(); total += deg[i]; } igraph_status("done\nSimple statistics on degrees...", 0); int wanted_total = int(floor(z * n + 0.5)); sort(); igraph_statusf("done : Max=%d, Total=%d.\n", 0, deg[0], total); if (z != -1.0) { igraph_statusf("Adjusting total to %d...", 0, wanted_total); int iterations = 0; while (total != wanted_total) { sort(); for (i = 0; i < n && total > wanted_total; i++) { total -= deg[i]; if (total + degmin <= wanted_total) { deg[i] = wanted_total - total; } else { deg[i] = pw.sample(); } total += deg[i]; } iterations += i; for (i = n - 1; i > 0 && total < wanted_total; i--) { total -= deg[i]; if (total + (deg[0] >> 1) >= wanted_total) { deg[i] = wanted_total - total; } else { deg[i] = pw.sample(); } total += deg[i]; } iterations += n - 1 - i; } igraph_statusf("done(%d iterations).", 0, iterations); igraph_statusf(" Now, degmax = %d\n", 0, dmax()); } shuffle(); } } // void degree_sequence::print() { // for(int i=0; ideg[i]) dmin=deg[i]; // int *dd = new int[dmax-dmin+1]; // for(i=dmin; i<=dmax; i++) dd[i-dmin]=0; // if(VERBOSE()) fprintf(stderr,"Computing cumulative distribution..."); // for(i=0; i0) printf("%d %d\n",i,dd[i-dmin]); // delete[] dd; // } bool degree_sequence::havelhakimi() { int i; int dm = dmax() + 1; // Sort vertices using basket-sort, in descending degrees int *nb = new int[dm]; int *sorted = new int[n]; // init basket for (i = 0; i < dm; i++) { nb[i] = 0; } // count basket for (i = 0; i < n; i++) { nb[deg[i]]++; } // cumul int c = 0; for (i = dm - 1; i >= 0; i--) { int t = nb[i]; nb[i] = c; c += t; } // sort for (i = 0; i < n; i++) { sorted[nb[deg[i]]++] = i; } // Binding process starts int first = 0; // vertex with biggest residual degree int d = dm - 1; // maximum residual degree available for (c = total / 2; c > 0; ) { // We design by 'v' the vertex of highest degree (indexed by first) // look for current degree of v while (nb[d] <= first) { d--; } // store it in dv int dv = d; // bind it ! c -= dv; int dc = d; // residual degree of vertices we bind to int fc = ++first; // position of the first vertex with degree dc while (dv > 0 && dc > 0) { int lc = nb[dc]; if (lc != fc) { while (dv > 0 && lc > fc) { // binds v with sorted[--lc] dv--; lc--; } fc = nb[dc]; nb[dc] = lc; } dc--; } if (dv != 0) { // We couldn't bind entirely v delete[] nb; delete[] sorted; return false; } } delete[] nb; delete[] sorted; return true; } //************************* // Subroutines definitions //************************* inline int int_adjust(double x) { return (int(floor(x + random_float()))); } void random_permute(int *a, int n) { int j, tmp; for (int i = 0; i < n - 1; i++) { j = i + my_random() % (n - i); tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } void cumul_sort(int *q, int n) { // looks for the maximum q[i] and minimum if (n == 0) { return; } int qmax = q[0]; int qmin = q[0]; int i; for (i = 0; i < n; i++) if (q[i] > qmax) { qmax = q[i]; } for (i = 0; i < n; i++) if (q[i] < qmin) { qmin = q[i]; } // counts #q[i] with given q int *nb = new int[qmax - qmin + 1]; for (int *onk = nb + (qmax - qmin + 1); onk != nb; * (--onk) = 0) { } for (i = 0; i < n; i++) { nb[q[i] - qmin]++; } // counts cumulative distribution for (i = qmax - qmin; i > 0; i--) { nb[i - 1] += nb[i]; } // sort by q[i] int last_q; int tmp; int modifier = qmax - qmin + 1; for (int current = 0; current < n; current++) { tmp = q[current]; if (tmp >= qmin && tmp <= qmax) { last_q = qmin; do { q[current] = last_q + modifier; last_q = tmp; current = --nb[last_q - qmin]; } while ((tmp = q[current]) >= qmin && tmp <= qmax); q[current] = last_q + modifier; } } delete[] nb; for (i = 0; i < n; i++) { q[i] = q[i] - modifier; } } } // namespace gengraph leidenbase/src/core/games/degree_sequence_vl/gengraph_graph_molloy_optimized.h0000644000176200001440000002722414447675374027644 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GRAPH_MOLLOY_OPT_H #define GRAPH_MOLLOY_OPT_H #include "gengraph_definitions.h" #include "gengraph_degree_sequence.h" #include "gengraph_qsort.h" #include #include "gengraph_random.h" namespace gengraph { // This class handles graphs with a constant degree sequence. class graph_molloy_opt { private: // Random generator KW_RNG::RNG rng; // Number of vertices int n; //Number of arcs ( = #edges * 2 ) int a; // The degree sequence of the graph int *deg; // The array containing all links int *links; // The array containing pointers to adjacency list of every vertices int **neigh; // Allocate memory according to degree_sequence (for constructor use only!!) void alloc(degree_sequence &); // Compute #edges inline void refresh_nbarcs() { a = 0; for (int* d = deg + n; d != deg; ) { a += *(--d); } } // Build neigh with deg and links void compute_neigh(); // Swap edges. The swap MUST be valid !!! inline void swap_edges(int from1, int to1, int from2, int to2) { fast_rpl(neigh[from1], to1, to2); fast_rpl(neigh[from2], to2, to1); fast_rpl(neigh[to1], from1, from2); fast_rpl(neigh[to2], from2, from1); } // Swap edges only if they are simple. return false if unsuccessful. bool swap_edges_simple(int, int, int, int); // Test if vertex is in an isolated component of size dmax. void depth_isolated(int v, long &calls, int &left_to_explore, int dmax, int * &Kbuff, bool *visited); // breadth-first search. Store the distance (modulo 3) in dist[]. Returns eplorated component size. int width_search(unsigned char *dist, int *buff, int v0 = 0, int toclear = -1); // depth-first search. int depth_search(bool *visited, int *buff, int v0 = 0); // breadth-first search that count the number of shortest paths going from src to each vertex int breadth_path_search(int src, int *buff, double *paths, unsigned char *dist); // Used by traceroute_sample() ONLY void add_traceroute_edge(int, int, int*, double** red = NULL, double t = 1.0); // Used by traceroute() and betweenness(). if newdeg[]=NULL, do not discover edges. // breadth_path_search() must have been called to give the corresponding buff[],dist[],paths[] and nb_vertices void explore_usp(double *target, int nb_vertices, int *buff, double *paths, unsigned char *dist, int *newdeg = NULL, double **edge_redudancy = NULL); void explore_asp(double *target, int nb_vertices, int *buff, double *paths, unsigned char *dist, int *newdeg = NULL, double **edge_redudancy = NULL); void explore_rsp(double *target, int nb_vertices, int *buff, double *paths, unsigned char *dist, int *newdeg = NULL, double **edge_redudancy = NULL); // Return component indexes where vertices belong to, starting from 0, // sorted by size (biggest component has index 0) int *components(int *comp = NULL); // pick k random vertices of degree > 0. int *pick_random_vertices(int &k, int *output = NULL, int nb_v = -1, int *among = NULL); public: // neigh[] inline int** neighbors() { return neigh; }; // deg[] inline int* degrees() { return deg; }; //adjacency list of v inline int* operator[](const int v) { return neigh[v]; }; //degree of v inline int degree(const int v) { return deg[v]; }; //compare adjacency lists inline int compare(const int v, const int w) { return deg[v] == deg[w] ? lex_comp(neigh[v], neigh[w], deg[v]) : (deg[v] > deg[w] ? -1 : 1); }; // Detach deg[] and neigh[] void detach(); // Destroy deg and links ~graph_molloy_opt(); // Create graph from file (stdin not supported unless rewind() possible) graph_molloy_opt(FILE *f); // Allocate memory for the graph. Create deg and links. No edge is created. graph_molloy_opt(degree_sequence &); // Create graph from hard copy graph_molloy_opt(int *); // Create hard copy of graph int *hard_copy(); // Remove unused edges, updates neigh[], recreate links[] void clean(); // nb arcs inline int nbarcs() { return a; }; // last degree inline int last_degree() { return deg[n - 1]; }; // nb vertices inline int nbvertices() { return n; }; // nb vertices having degree > 0 inline int nbvertices_real() { int s = 0; for (int *d = deg + n; d-- != deg; ) if (*d) { s++; } return s; }; // return list of vertices with degree > 0. Compute #vertices, if not given. int *vertices_real(int &nb_v); // Keep only giant component void giant_comp(); // nb vertices in giant component int nbvertices_comp(); // nb arcs in giant component int nbarcs_comp(); // print graph in SUCC_LIST mode, in stdout void print(FILE *f = stdout, bool NOZERO = true); // Bind the graph avoiding multiple edges or self-edges (return false if fail) bool havelhakimi(); // Get the graph connected (return false if fail) bool make_connected(); // Test if graph is connected bool is_connected(); // Maximum degree int max_degree(); // breadth-first search. Store the distance (modulo 3) in dist[]. void breadth_search(int *dist, int v0 = 0, int* buff = NULL); // is edge ? inline bool is_edge(const int u, const int v) { if (deg[v] < deg[u]) { return (fast_search(neigh[v], deg[v], u) != NULL); } else { return (fast_search(neigh[u], deg[u], v) != NULL); } } // Backup graph [sizeof(int) bytes per edge] int* backup(int *here = NULL); // Restore from backup. Assume that degrees haven't changed void restore(int* back); // Resplace with hard backup. void replace(int* _hardbackup); // Backup degs of graph int* backup_degs(int *here = NULL); // Restore degs from neigh[]. Need last degree, though void restore_degs(int last_degree); // Restore degs[] from backup. Assume that links[] has only been permuted void restore_degs_only(int* backup_degs); // Restore degs[] and neigh[]. Assume that links[] has only been permuted void restore_degs_and_neigh(int* backup_degs); // WARNING : the following shuffle() algorithms are slow. // Use graph_molloy_hash::connected_shuffle() instead. // "Fab" Shuffle (Optimized heuristic of Gkantsidis algo.) long fab_connected_shuffle(long); // "Optimized-Fab" Shuffle (Optimized heuristic of Gkantsidis algo, with isolated pairs) long opt_fab_connected_shuffle(long); // Gkantsidis Shuffle long gkantsidis_connected_shuffle(long); // Connected Shuffle long slow_connected_shuffle(long); // shortest paths where vertex is an extremity double *vertex_betweenness(int mode, bool trivial_path = false); // Sample the graph with traceroute-like exploration from src[] to dst[]. // if dst[]=NULL, pick nb_dst new random destinations for each src double traceroute_sample(int mode, int nb_src, int *src, int nb_dst, int* dst, double *redudancy = NULL, double **edge_redudancy = NULL); // does one breadth-first search and returns the average_distance. double avg_dist(unsigned char *dist, int *buff, int v0, int &nb_vertices, int toclear = -1); // Number of edges needed to disconnect graph (one random instance) int disconnecting_edges(); // Compute vertex covering of the graph. Warning : this modifies degs[] void vertex_covering(); // Path sampling. Input is nb_dst[] and dst[]. nb_dst[v],dst[v] describe all paths (v,x) double path_sampling(int *nb_dst, int *dst = NULL, double *redudancies = NULL, double **edge_redudancy = NULL); // keep only core (tree parts are deleted). Returns number of removed vertices. int core(); // try to disconnect the graph by swapping edges (with isolation tests) int try_disconnect(int K, int max_tries = 10000000); // Eric & Cun-Hui estimator double rho(int mode, int nb_src, int *src, int nb_dst, int *dst = NULL); // sort adjacency lists void sort(); // sort the vertices according to their degrees (highest first) and to their adjacency lists (lexicographic) int* sort_vertices(int *buff = NULL); // count cycles passing through vertex v int cycles(int v); // remove vertex (i.e. remove all edges adjacent to vertex) void remove_vertex(int v); // pick k random vertices of degree > 0. If k \in [0,1[, k is understood as a density. int *pick_random_src(double k, int *nb = NULL, int* buff = NULL, int nb_v = -1, int* among = NULL); // pick k random vertices of degree > 0. If k \in [0,1], k is understood as a density. int *pick_random_dst(double k, int *nb = NULL, int* buff = NULL, int nb_v = -1, int* among = NULL); // For debug purposes : verify validity of the graph (symetry, simplicity) #define VERIFY_NORMAL 0 #define VERIFY_NONEIGH 1 #define VERIFY_NOARCS 2 bool verify(int mode = VERIFY_NORMAL); /*___________________________________________________________________________________ Not to use anymore : use graph_molloy_hash class instead public: // Shuffle. returns number of swaps done. void shuffle(long); // Connected Shuffle long connected_shuffle(long); // Get caracteristic K double eval_K(int quality = 100); // Get effective K double effective_K(int K, int quality = 10000); // Test window double window(int K, double ratio); // Try to shuffle n times. Return true if at the end, the graph was still connected. bool try_shuffle(int T, int K); //___________________________________________________________________________________ */ /*___________________________________________________________________________________ Not to use anymore : replaced by vertex_betweenness() 22/04/2005 // shortest paths where vertex is an extremity long long *vertex_betweenness_usp(bool trivial_path); // shortest paths where vertex is an extremity long long *vertex_betweenness_rsp(bool trivial_path); // same, but when multiple shortest path are possible, average the weights. double *vertex_betweenness_asp(bool trivial_path); //___________________________________________________________________________________ */ }; } // namespace gengraph #endif //GRAPH_MOLLOY_OPT_H leidenbase/src/core/games/degree_sequence_vl/gengraph_box_list.cpp0000644000176200001440000000467014447675374025242 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gengraph_box_list.h" #include namespace gengraph { void box_list::insert(int v) { int d = deg[v]; if (d < 1) { return; } if (d > dmax) { dmax = d; } int yo = list[d - 1]; list[d - 1] = v; prev[v] = -1; next[v] = yo; if (yo >= 0) { prev[yo] = v; } } void box_list::pop(int v) { int p = prev[v]; int nxt = next[v]; if (p < 0) { int d = deg[v]; assert(list[d - 1] == v); list[d - 1] = nxt; if (d == dmax && nxt < 0) { do { dmax--; } while (dmax > 0 && list[dmax - 1] < 0); } } else { next[p] = nxt; } if (nxt >= 0) { prev[nxt] = p; } } box_list::box_list(int n0, int *deg0) : n(n0), deg(deg0) { next = new int[n]; prev = new int[n]; dmax = -1; int i; for (i = 0; i < n; i++) if (deg[i] > dmax) { dmax = deg[i]; } list = new int[dmax]; for (i = 0; i < dmax; i++) { list[i] = -1; } for (i = 0; i < n; i++) { insert(i); } } box_list::~box_list() { delete[] prev; delete[] next; delete[] list; } void box_list::pop_vertex(int v, int **neigh) { int k = deg[v]; if (k < 1) { return; } pop(v); int *w = neigh[v]; while (k--) { int v2 = *(w++); int *w2 = neigh[v2]; while (*w2 != v) { w2++; } int *w3 = neigh[v2] + (deg[v2] - 1); assert(w2 <= w3); int tmp = *w3; *w3 = *w2; *w2 = tmp; pop(v2); deg[v2]--; insert(v2); } } } // namespace gengraph leidenbase/src/core/games/degree_sequence_vl/gengraph_mr-connected.cpp0000644000176200001440000001524214447675374025772 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gengraph_header.h" #include "gengraph_graph_molloy_optimized.h" #include "gengraph_graph_molloy_hash.h" #include "gengraph_degree_sequence.h" #include "gengraph_random.h" #include "igraph_datatype.h" #include "igraph_graphicality.h" #include "igraph_types.h" #include "igraph_error.h" #include "core/exceptions.h" namespace gengraph { // return negative number if program should exit int parse_options(int &argc, char** &argv); // options // static const bool MONITOR_TIME = false; static const int SHUFFLE_TYPE = FINAL_HEURISTICS; // static const bool RAW_DEGREES = false; // static const FILE *Fdeg = stdin; //_________________________________________________________________________ // int main(int argc, char** argv) { // // options // SET_VERBOSE(VERBOSE_NONE); // if(parse_options(argc, argv) < 0) return -1; // //Read degree distribution // degree_sequence dd(Fdeg, !RAW_DEGREES); // //Allocate memory // if(VERBOSE()) fprintf(stderr,"Allocate memory for graph..."); // graph_molloy_opt g(dd); // dd.~degree_sequence(); // //Realize degree sequence // if(VERBOSE()) fprintf(stderr,"done\nRealize degree sequence..."); // bool FAILED = !g.havelhakimi(); // if(VERBOSE()) fprintf(stderr," %s\n", FAILED ? "Failed" : "Success"); // if(FAILED) return 2; // //Merge connected components together // if(VERBOSE()) fprintf(stderr,"Connecting..."); // FAILED = !g.make_connected(); // if(VERBOSE()) fprintf(stderr," %s\n", FAILED ? "Failed" : "Success"); // if(FAILED) return 3; // //Convert graph_molloy_opt to graph_molloy_hash // if(VERBOSE()) fprintf(stderr,"Convert adjacency lists into hash tables..."); // int *hc = g.hard_copy(); // g.~graph_molloy_opt(); // graph_molloy_hash gh(hc); // delete[] hc; // if(VERBOSE()) fprintf(stderr,"Done\n"); // //Shuffle // gh.shuffle(5*gh.nbarcs(), SHUFFLE_TYPE); // //Output // gh.print(); // if(MONITOR_TIME) { // double t = double(clock()) / double(CLOCKS_PER_SEC); // fprintf(stderr,"Time used: %f\n", t); // } // return 0; // } //_________________________________________________________________________ // int parse_options(int &argc, char** &argv) { // bool HELP = false; // int argc0 = argc; // argc = 1; // for(int a=1; a %s returns a graph in its standard output\n",argv[0]); // fprintf(stderr," If no file is given, %s reads its standard input\n",argv[0]); // fprintf(stderr," [-v] and [-vv] options causes extra verbose.\n"); // fprintf(stderr," [-g] option uses the Gkantsidis heuristics.\n"); // fprintf(stderr," [-b] option uses the Brute Force heuristics.\n"); // fprintf(stderr," [-f] option uses the Modified Gkantsidis heuristics.\n"); // fprintf(stderr," [-o] option uses the Optimal Gkantsidis heuristics.\n"); // fprintf(stderr," [-t] option monitors computation time\n"); // fprintf(stderr," [-s] does a srandom(0) to get a constant random graph\n"); // fprintf(stderr," [-raw] is to take raw degree sequences as input\n"); // return -1; // } // return 0; // } } // namespace gengraph using namespace gengraph; extern "C" { int igraph_degree_sequence_game_vl(igraph_t *graph, const igraph_vector_t *out_seq, const igraph_vector_t *in_seq) { IGRAPH_HANDLE_EXCEPTIONS( igraph_bool_t is_graphical; if (in_seq && igraph_vector_size(in_seq) != 0) { IGRAPH_ERROR("This generator works with undirected graphs only", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_is_graphical(out_seq, 0, IGRAPH_SIMPLE_SW, &is_graphical)); if (!is_graphical) { IGRAPH_ERROR("Cannot realize the given degree sequence as an undirected, simple graph", IGRAPH_EINVAL); } RNG_BEGIN(); degree_sequence *dd = new degree_sequence(out_seq); graph_molloy_opt *g = new graph_molloy_opt(*dd); delete dd; if (!g->havelhakimi()) { delete g; RNG_END(); IGRAPH_FATAL("g->havelhakimi() failed; please report as a bug."); } if (!g->make_connected()) { delete g; RNG_END(); IGRAPH_ERROR("Cannot make a connected graph from the given degree sequence", IGRAPH_EINVAL); } int *hc = g->hard_copy(); delete g; graph_molloy_hash *gh = new graph_molloy_hash(hc); delete [] hc; gh->shuffle(5 * gh->nbarcs(), 100 * gh->nbarcs(), SHUFFLE_TYPE); IGRAPH_CHECK(gh->print(graph)); delete gh; RNG_END(); ); return IGRAPH_SUCCESS; } } leidenbase/src/core/games/degree_sequence_vl/gengraph_random.h0000644000176200001440000001644314447675374024345 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef RNG_H #define RNG_H #include "igraph_random.h" namespace KW_RNG { typedef signed int sint; typedef unsigned int uint; typedef signed long slong; typedef unsigned long ulong; class RNG { public: RNG() { } RNG(ulong z_, ulong w_, ulong jsr_, ulong jcong_ ) { IGRAPH_UNUSED(z_); IGRAPH_UNUSED(w_); IGRAPH_UNUSED(jsr_); IGRAPH_UNUSED(jcong_); }; ~RNG() { } void init(ulong z_, ulong w_, ulong jsr_, ulong jcong_ ) { IGRAPH_UNUSED(z_); IGRAPH_UNUSED(w_); IGRAPH_UNUSED(jsr_); IGRAPH_UNUSED(jcong_); } long rand_int31() { return RNG_INT31(); } double rand_halfopen01() { // (0,1] return RNG_UNIF01(); } int binomial(double pp, int n) { return RNG_BINOM(n, pp); } }; } // namespace KW_RNG /* This was the original RNG, but now we use the igraph version */ // __________________________________________________________________________ // random.h - a Random Number Generator Class // random.cpp - contains the non-inline class methods // __________________________________________________________________________ // This C++ code uses the simple, very fast "KISS" (Keep It Simple // Stupid) random number generator suggested by George Marsaglia in a // Usenet posting from 1999. He describes it as "one of my favorite // generators". It generates high-quality random numbers that // apparently pass all commonly used tests for randomness. In fact, it // generates random numbers by combining the results of three other good // random number generators that have different periods and are // constructed from completely different algorithms. It does not have // the ultra-long period of some other generators - a "problem" that can // be fixed fairly easily - but that seems to be its only potential // problem. The period is about 2^123. // The ziggurat method of Marsaglia is used to generate exponential and // normal variates. The method as well as source code can be found in // the article "The Ziggurat Method for Generating Random Variables" by // Marsaglia and Tsang, Journal of Statistical Software 5, 2000. // The method for generating gamma variables appears in "A Simple Method // for Generating Gamma Variables" by Marsaglia and Tsang, ACM // Transactions on Mathematical Software, Vol. 26, No 3, Sep 2000, pages // 363-372. // The code for Poisson and Binomial random numbers comes from // Numerical Recipes in C. // Some of this code is unlikely to work correctly as is on 64 bit // machines. // #include // #include // #ifdef _WIN32 // #include // #define getpid _getpid // #else // #include // #endif // //#ifdef _WIN32 // static const double PI = 3.1415926535897932; // static const double AD_l = 0.6931471805599453; // static const double AD_a = 5.7133631526454228; // static const double AD_b = 3.4142135623730950; // static const double AD_c = -1.6734053240284925; // static const double AD_p = 0.9802581434685472; // static const double AD_A = 5.6005707569738080; // static const double AD_B = 3.3468106480569850; // static const double AD_H = 0.0026106723602095; // static const double AD_D = 0.0857864376269050; // //#endif //_WIN32 // namespace KW_RNG { // class RNG // { // private: // ulong z, w, jsr, jcong; // Seeds // ulong kn[128], ke[256]; // double wn[128],fn[128], we[256],fe[256]; // /* // #ifndef _WIN32 // static const double PI = 3.1415926535897932; // static const double AD_l = 0.6931471805599453; // static const double AD_a = 5.7133631526454228; // static const double AD_b = 3.4142135623730950; // static const double AD_c = -1.6734053240284925; // static const double AD_p = 0.9802581434685472; // static const double AD_A = 5.6005707569738080; // static const double AD_B = 3.3468106480569850; // static const double AD_H = 0.0026106723602095; // static const double AD_D = 0.0857864376269050; // #endif //_WIN32 // */ // public: // RNG() { init(); zigset(); } // RNG(ulong z_, ulong w_, ulong jsr_, ulong jcong_ ) : // z(z_), w(w_), jsr(jsr_), jcong(jcong_) { zigset(); } // ~RNG() { } // inline ulong znew() // { return (z = 36969 * (z & 65535) + (z >> 16)); } // inline ulong wnew() // { return (w = 18000 * (w & 65535) + (w >> 16)); } // inline ulong MWC() // { return (((znew() & 65535) << 16) + wnew()); } // inline ulong SHR3() // { jsr ^= ((jsr & 32767) << 17); jsr ^= (jsr >> 13); return (jsr ^= ((jsr << 5) & 0xFFFFFFFF)); } // inline ulong CONG() // { return (jcong = (69069 * jcong + 1234567) & 0xFFFFFFFF); } // inline double RNOR() { // slong h = rand_int32(); // ulong i = h & 127; // return (((ulong) abs((sint) h) < kn[i]) ? h * wn[i] : nfix(h, i)); // } // inline double REXP() { // ulong j = rand_int32(); // ulong i = j & 255; // return ((j < ke[i]) ? j * we[i] : efix(j, i)); // } // double nfix(slong h, ulong i); // double efix(ulong j, ulong i); // void zigset(); // inline void init() // { ulong yo = time(0) + getpid(); // z = w = jsr = jcong = yo; } // inline void init(ulong z_, ulong w_, ulong jsr_, ulong jcong_ ) // { z = z_; w = w_; jsr = jsr_; jcong = jcong_; } // inline ulong rand_int32() // [0,2^32-1] // { return ((MWC() ^ CONG()) + SHR3()) & 0xFFFFFFFF; } // inline long rand_int31() // [0,2^31-1] // { return long(rand_int32() >> 1);} // inline double rand_closed01() // [0,1] // { return ((double) rand_int32() / 4294967295.0); } // inline double rand_open01() // (0,1) // { return (((double) rand_int32() + 0.5) / 4294967296.0); } // inline double rand_halfclosed01() // [0,1) // { return ((double) rand_int32() / 4294967296.0); } // inline double rand_halfopen01() // (0,1] // { return (((double) rand_int32() + 0.5) / 4294967295.5); } // // Continuous Distributions // inline double uniform(double x = 0.0, double y = 1.0) // { return rand_closed01() * (y - x) + x; } // inline double normal(double mu = 0.0, double sd = 1.0) // { return RNOR() * sd + mu; } // inline double exponential(double lambda = 1) // { return REXP() / lambda; } // double gamma(double shape = 1, double scale = 1); // double chi_square(double df) // { return gamma(df / 2.0, 0.5); } // double beta(double a1, double a2) // { double x1 = gamma(a1, 1); return (x1 / (x1 + gamma(a2, 1))); } // // Discrete Distributions // double poisson(double lambda); // int binomial(double pp, int n); // }; // class RNG // } // namespace #endif // RNG_H leidenbase/src/core/games/degree_sequence_vl/gengraph_degree_sequence.h0000644000176200001440000000465514447675374026212 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DEGREE_SEQUENCE_H #define DEGREE_SEQUENCE_H #include "igraph_types.h" #include "igraph_datatype.h" namespace gengraph { class degree_sequence { private: int n; int * deg; int total; public : // #vertices inline int size() { return n; }; inline int sum() { return total; }; inline int operator[](int i) { return deg[i]; }; inline int *seq() { return deg; }; inline void assign(int n0, int* d0) { n = n0; deg = d0; }; inline int dmax() { int dm = deg[0]; for (int i = 1; i < n; i++) if (deg[i] > dm) { dm = deg[i]; } return dm; } void make_even(int mini = -1, int maxi = -1); void sort(); void shuffle(); // raw constructor degree_sequence(int n, int *degs); // read-from-file constrictor degree_sequence(FILE *f, bool DISTRIB = true); // simple power-law constructor : Pk = int((x+k0)^(-exp),x=k..k+1), with k0 so that avg(X)=z degree_sequence(int n, double exp, int degmin, int degmax, double avg_degree = -1.0); // igraph constructor degree_sequence(const igraph_vector_t *out_seq); // destructor ~degree_sequence(); // unbind the deg[] vector (so that it doesn't get deleted when the class is destroyed) void detach(); // compute total number of arcs void compute_total(); // raw print (vertex by vertex) void print(); // distribution print (degree frequency) void print_cumul(); // is degree sequence realizable ? bool havelhakimi(); }; } // namespace gengraph #endif //DEGREE_SEQUENCE_H leidenbase/src/core/games/degree_sequence_vl/gengraph_qsort.h0000644000176200001440000003334114447675374024231 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef QSORT_H #define QSORT_H #include #include namespace gengraph { //___________________________________________________________________________ // check if every element is zero inline bool check_zero(int *mem, int n) { for (int *v = mem + n; v != mem; ) if (*(--v) != 0) { return false; } return true; } //___________________________________________________________________________ // Sort simple integer arrays in ASCENDING order //___________________________________________________________________________ inline int med3(int a, int b, int c) { if (a < b) { if (c < b) { return (a < c) ? c : a; } else { return b; } } else { if (c < a) { return (b < c) ? c : b; } else { return a; } } } inline void isort(int *v, int t) { if (t < 2) { return; } for (int i = 1; i < t; i++) { int *w = v + i; int tmp = *w; while (w != v && *(w - 1) > tmp) { *w = *(w - 1); w--; } *w = tmp; } } inline int partitionne(int *v, int t, int p) { int i = 0; int j = t - 1; while (i < j) { while (i <= j && v[i] < p) { i++; } while (i <= j && v[j] > p) { j--; } if (i < j) { int tmp = v[i]; v[i++] = v[j]; v[j--] = tmp; } } if (i == j && v[i] < p) { i++; } assert(i != 0 && i != t); return i; } inline void qsort(int *v, int t) { if (t < 15) { isort(v, t); } else { int x = partitionne(v, t, med3(v[t >> 1], v[(t >> 2) + 2], v[t - (t >> 1) - 2])); qsort(v, x); qsort(v + x, t - x); } } inline int qsort_median(int *v, int t, int pos) { if (t < 10) { isort(v, t); return v[pos]; } int x = partitionne(v, t, med3(v[t >> 1], v[(t >> 2) + 2], v[t - (t >> 1) - 2])); if (pos < x) { return qsort_median(v, x, pos); } else { return qsort_median(v + x, t - x, pos - x); } } inline int qsort_median(int *v, int t) { return qsort_median(v, t, t / 2); } //___________________________________________________________________________ // Sort simple double arrays in ASCENDING order //___________________________________________________________________________ inline double med3(double a, double b, double c) { if (a < b) { if (c < b) { return (a < c) ? c : a; } else { return b; } } else { if (c < a) { return (b < c) ? c : b; } else { return a; } } } inline void isort(double *v, int t) { if (t < 2) { return; } for (int i = 1; i < t; i++) { double *w = v + i; double tmp = *w; while (w != v && *(w - 1) > tmp) { *w = *(w - 1); w--; } *w = tmp; } } inline int partitionne(double *v, int t, double p) { int i = 0; int j = t - 1; while (i < j) { while (i <= j && v[i] < p) { i++; } while (i <= j && v[j] > p) { j--; } if (i < j) { double tmp = v[i]; v[i++] = v[j]; v[j--] = tmp; } } if (i == j && v[i] < p) { i++; } assert(i != 0 && i != t); return i; } inline void qsort(double *v, int t) { if (t < 15) { isort(v, t); } else { int x = partitionne(v, t, med3(v[t >> 1], v[(t >> 2) + 2], v[t - (t >> 1) - 2])); qsort(v, x); qsort(v + x, t - x); } } inline double qsort_median(double *v, int t, int pos) { if (t < 10) { isort(v, t); return v[pos]; } int x = partitionne(v, t, med3(v[t >> 1], v[(t >> 2) + 2], v[t - (t >> 1) - 2])); if (pos < x) { return qsort_median(v, x, pos); } else { return qsort_median(v + x, t - x, pos - x); } } inline double qsort_median(double *v, int t) { return qsort_median(v, t, t / 2); } //___________________________________________________________________________ // Sort integer arrays according to value stored in mem[], in ASCENDING order inline void isort(int *mem, int *v, int t) { if (t < 2) { return; } for (int i = 1; i < t; i++) { int vtmp = v[i]; int tmp = mem[vtmp]; int j; for (j = i; j > 0 && tmp < mem[v[j - 1]]; j--) { v[j] = v[j - 1]; } v[j] = vtmp; } } inline void qsort(int *mem, int *v, int t) { if (t < 15) { isort(mem, v, t); } else { int p = med3(mem[v[t >> 1]], mem[v[(t >> 2) + 3]], mem[v[t - (t >> 1) - 3]]); int i = 0; int j = t - 1; while (i < j) { while (i <= j && mem[v[i]] < p) { i++; } while (i <= j && mem[v[j]] > p) { j--; } if (i < j) { int tmp = v[i]; v[i++] = v[j]; v[j--] = tmp; } } if (i == j && mem[v[i]] < p) { i++; } assert(i != 0 && i != t); qsort(mem, v, i); qsort(mem, v + i, t - i); } } //Box-Sort 1..n according to value stored in mem[], in DESCENDING order. inline int *pre_boxsort(int *mem, int n, int &offset) { int *yo; // maximum and minimum int mx = mem[0]; int mn = mem[0]; for (yo = mem + n - 1; yo != mem; yo--) { int x = *yo; if (x > mx) { mx = x; } if (x < mn) { mn = x; } } // box int c = mx - mn + 1; int *box = new int[c]; for (yo = box + c; yo != box; * (--yo) = 0) { } for (yo = mem + n; yo != mem; box[*(--yo) - mn]++) { } // cumul sum int sum = 0; for (yo = box + c; yo != box; ) { sum += *(--yo); *yo = sum; } offset = mn; return box; } inline int *boxsort(int *mem, int n, int *buff = NULL) { int i; if (n <= 0) { return buff; } int offset = 0; int *box = pre_boxsort(mem, n, offset); // sort if (buff == NULL) { buff = new int[n]; } for (i = 0; i < n; i++) { buff[--box[mem[i] - offset]] = i; } // clean delete[] box; return buff; } // merge two sorted arays in their intersection. Store the result in first array, and return length inline int intersect(int *a, int a_len, int *b, int b_len) { if (a_len == 0 || b_len == 0) { return 0; } int *asup = a + a_len; int *bsup = b + b_len; int len = 0; int *p = a; do { if (*a == *b) { p[len++] = *a; } do if (++a == asup) { return len; } while (*a < *b); if (*a == *b) { p[len++] = *a; } do if (++b == bsup) { return len; } while (*b < *a); } while (true); } // merge two sorted arays in their union, store result in m inline int unify(int *m, int *a, int a_len, int *b, int b_len) { int *asup = a + a_len; int *bsup = b + b_len; int len = 0; while (a != asup && b != bsup) { if (*a < *b) { m[len++] = *(a++); } else { if (*a == *b) { a++; } m[len++] = *(b++); } } while (a != asup) { m[len++] = *(a++); } while (b != asup) { m[len++] = *(b++); } return len; } // lexicographic compare inline int lex_comp(int *v1, int *v2, int n) { int *stop = v1 + n; while (v1 != stop && *v1 == *v2) { v1++; v2++; }; if (v1 == stop) { return 0; } else if (*v1 < *v2) { return -1; } else { return 1; } } // lexicographic median of three inline int *lex_med3(int *a, int *b, int *c, int s) { int ab = lex_comp(a, b, s); if (ab == 0) { return a; } else { int cb = lex_comp(c, b, s); if (cb == 0) { return b; } int ca = lex_comp(c, a, s); if (ab < 0) { if (cb > 0) { return b; } else { return (ca > 0) ? c : a; } } else { if (cb < 0) { return b; } else { return (ca < 0) ? c : a; } } } } // Lexicographic sort inline void lex_isort(int **l, int *v, int t, int s) { if (t < 2) { return; } for (int i = 1; i < t; i++) { int *w = v + i; int tmp = *w; while (w != v && lex_comp(l[tmp], l[*(w - 1)], s) < 0) { *w = *(w - 1); w--; } *w = tmp; } } #ifdef _STABLE_SORT_ONLY #define _CRITICAL_SIZE_QSORT 0x7FFFFFFF #warning "lex_qsort will be replaced by lex_isort" #else #define _CRITICAL_SIZE_QSORT 15 #endif inline void lex_qsort(int **l, int *v, int t, int s) { if (t < _CRITICAL_SIZE_QSORT) { lex_isort(l, v, t, s); } else { int *p = lex_med3(l[v[t >> 1]], l[v[(t >> 2) + 2]], l[v[t - (t >> 1) - 2]], s); int i = 0; int j = t - 1; // printf("pivot = %d\n",p); while (i < j) { // for(int k=0; k 0) { j--; } if (i < j) { // printf(" swap %d[%d] with %d[%d]\n",i,v[i],j,v[j]); int tmp = v[i]; v[i++] = v[j]; v[j--] = tmp; } } if (i == j && lex_comp(l[v[i]], p, s) < 0) { i++; } assert(i != 0 && i != t); lex_qsort(l, v, i, s); lex_qsort(l, v + i, t - i, s); } } // lexicographic indirect compare inline int lex_comp_indirect(int *key, int *v1, int *v2, int n) { int *stop = v1 + n; while (v1 != stop && key[*v1] == key[*v2]) { v1++; v2++; }; if (v1 == stop) { return 0; } else if (key[*v1] < key[*v2]) { return -1; } else { return 1; } } inline int qsort_min(const int a, const int b) { return a <= b ? a : b; } // mix indirect compare inline int mix_comp_indirect(int *key, int a, int b, int **neigh, int *degs) { if (key[a] < key[b]) { return -1; } else if (key[a] > key[b]) { return 1; } else { int cmp = lex_comp_indirect(key, neigh[a], neigh[b], qsort_min(degs[a], degs[b])); if (cmp == 0) { if (degs[a] > degs[b]) { return -1; } if (degs[a] < degs[b]) { return 1; } } return cmp; } } // lexicographic indirect median of three inline int mix_med3_indirect(int *key, int a, int b, int c, int **neigh, int *degs) { int ab = mix_comp_indirect(key, a, b, neigh, degs); if (ab == 0) { return a; } else { int cb = mix_comp_indirect(key, c, b, neigh, degs); if (cb == 0) { return b; } int ca = mix_comp_indirect(key, c, a, neigh, degs); if (ab < 0) { if (cb > 0) { return b; } else { return (ca > 0) ? c : a; } } else { if (cb < 0) { return b; } else { return (ca < 0) ? c : a; } } } } // Sort integer arrays in ASCENDING order inline void mix_isort_indirect(int *key, int *v, int t, int **neigh, int *degs) { if (t < 2) { return; } for (int i = 1; i < t; i++) { int *w = v + i; int tmp = *w; while (w != v && mix_comp_indirect(key, tmp, *(w - 1), neigh, degs) < 0) { *w = *(w - 1); w--; } *w = tmp; } } inline void mix_qsort_indirect(int *key, int *v, int t, int **neigh, int *degs) { if (t < 15) { mix_isort_indirect(key, v, t, neigh, degs); } else { int p = mix_med3_indirect(key, v[t >> 1], v[(t >> 2) + 2], v[t - (t >> 1) - 2], neigh, degs); int i = 0; int j = t - 1; // printf("pivot = %d\n",p); while (i < j) { // for(int k=0; k 0) { j--; } if (i < j) { // printf(" swap %d[%d] with %d[%d]\n",i,v[i],j,v[j]); int tmp = v[i]; v[i++] = v[j]; v[j--] = tmp; } } if (i == j && mix_comp_indirect(key, v[i], p, neigh, degs) < 0) { i++; } assert(i != 0 && i != t); mix_qsort_indirect(key, v, i, neigh, degs); mix_qsort_indirect(key, v + i, t - i, neigh, degs); } } } // namespace gengraph #endif //QSORT_H leidenbase/src/core/games/degree_sequence_vl/gengraph_hash.h0000644000176200001440000002126014447675374024001 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef HASH_H #define HASH_H #include #include "gengraph_definitions.h" //_________________________________________________________________________ // Hash table profiling... Active only if definition below is uncommented //_________________________________________________________________________ //#define _HASH_PROFILE namespace gengraph { #ifdef _HASH_PROFILE void _hash_add_iter(); void _hash_add_call(); void _hash_put_iter(); void _hash_put_call(); void _hash_rm_iter(); void _hash_rm_call(); void _hash_find_iter(); void _hash_find_call(); void _hash_rand_iter(); void _hash_rand_call(); void _hash_expand_call(); void _hash_prof(); #define _HASH_ADD_ITER() _hash_add_iter() #define _HASH_ADD_CALL() _hash_add_call() #define _HASH_PUT_ITER() _hash_put_iter() #define _HASH_PUT_CALL() _hash_put_call() #define _HASH_RM_ITER() _hash_rm_iter() #define _HASH_RM_CALL() _hash_rm_call() #define _HASH_FIND_ITER() _hash_find_iter() #define _HASH_FIND_CALL() _hash_find_call() #define _HASH_RAND_ITER() _hash_rand_iter() #define _HASH_RAND_CALL() _hash_rand_call() #define _HASH_EXP_CALL() _hash_expand_call() #else #define _HASH_ADD_ITER() {} #define _HASH_ADD_CALL() {} #define _HASH_PUT_ITER() {} #define _HASH_PUT_CALL() {} #define _HASH_RM_ITER() {} #define _HASH_RM_CALL() {} #define _HASH_FIND_ITER() {} #define _HASH_FIND_CALL() {} #define _HASH_RAND_ITER() {} #define _HASH_RAND_CALL() {} #define _HASH_EXP_CALL() {} #endif //_________________________________________________________________________ // Hash Table properties. Works best when HASH_SIZE_IS_POWER2 is uncommented // but takes 2.25 times the needed space, in average (from 1.5 to 3) // If you have memory issues, Try to comment it: tables will take 1.5 times // the minimal space //_________________________________________________________________________ #define HASH_SIZE_IS_POWER2 #define MACRO_RATHER_THAN_INLINE // under HASH_MIN_SIZE, vectors are not hash table (just a simle array) #define HASH_MIN_SIZE 100 #define IS_HASH(x) ((x)>HASH_MIN_SIZE) #define HASH_NONE (-1) #ifdef HASH_SIZE_IS_POWER2 inline int HASH_EXPAND(int x) { _HASH_EXP_CALL(); x += x; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; return x + 1; } #define HASH_KEY(x,size) ((x*2198737)&((size)-1)) #endif //HASH_SIZE_IS_POWER2 #ifdef MACRO_RATHER_THAN_INLINE #ifndef HASH_SIZE_IS_POWER2 #define HASH_EXPAND(x) ((x)+((x)>>1)) #define HASH_UNEXPAND(x) ((((x)<<1)+1)/3) #define HASH_KEY(x,size) ((x)%(size)) #endif //HASH_SIZE_IS_POWER2 #define HASH_SIZE(x) (IS_HASH(x) ? HASH_EXPAND(x) : (x) ) #define HASH_REKEY(k,size) ((k)==0 ? (size)-1 : (k)-1) #else //MACRO_RATHER_THAN_INLINE #ifndef HASH_SIZE_IS_POWER2 inline int HASH_KEY(const int x, const int size) { assert(x >= 0); return x % size; }; inline int HASH_EXPAND(const int x) { _HASH_EXP_CALL(); return x + (x >> 1); }; inline int HASH_UNEXPAND(const int x) { return ((x << 1) + 1) / 3; }; #endif //HASH_SIZE_IS_POWER2 inline int HASH_REKEY(const int k, const int s) { assert(k >= 0); if (k == 0) { return s - 1; } else { return k - 1; } }; inline int HASH_SIZE(const int x) { if (IS_HASH(x)) { return HASH_EXPAND(x); } else { return x; } }; #endif //MACRO_RATHER_THAN_INLINE inline int HASH_PAIR_KEY(const int x, const int y, const int size) { return HASH_KEY(x * 1434879443 + y, size); } //_________________________________________________________________________ // Hash-only functions : table must NOT be Raw. // the argument 'size' is the total size of the hash table //_________________________________________________________________________ // copy hash table into raw vector inline void H_copy(int *mem, int *h, int size) { for (int i = HASH_EXPAND(size); i--; h++) if (*h != HASH_NONE) { *(mem++) = *h; } } // Look for the place to add an element. Return NULL if element is already here. inline int* H_add(int* h, const int size, int a) { _HASH_ADD_CALL(); _HASH_ADD_ITER(); int k = HASH_KEY(a, size); if (h[k] == HASH_NONE) { return h + k; } while (h[k] != a) { _HASH_ADD_ITER(); k = HASH_REKEY(k, size); if (h[k] == HASH_NONE) { return h + k; } } return NULL; } // would element be well placed in newk ? inline bool H_better(const int a, const int size, const int currentk, const int newk) { int k = HASH_KEY(a, size); if (newk < currentk) { return (k < currentk && k >= newk); } else { return (k < currentk || k >= newk); } } // removes h[k] inline void H_rm(int* h, const int size, int k) { _HASH_RM_CALL(); int lasthole = k; do { _HASH_RM_ITER(); k = HASH_REKEY(k, size); int next = h[k]; if (next == HASH_NONE) { break; } if (H_better(next, size, k, lasthole)) { h[lasthole] = next; lasthole = k; } } while (true); h[lasthole] = HASH_NONE; } //put a inline int* H_put(int* h, const int size, const int a) { assert(H_add(h, size, a) != NULL); _HASH_PUT_CALL(); _HASH_PUT_ITER(); int k = HASH_KEY(a, size); while (h[k] != HASH_NONE) { k = HASH_REKEY(k, size); _HASH_PUT_ITER(); } h[k] = a; assert(H_add(h, size, a) == NULL); return h + k; } // find A inline int H_find(int *h, int size, const int a) { assert(H_add(h, size, a) == NULL); _HASH_FIND_CALL(); _HASH_FIND_ITER(); int k = HASH_KEY(a, size); while (h[k] != a) { k = HASH_REKEY(k, size); _HASH_FIND_ITER(); } return k; } // Look for the place to add an element. Return NULL if element is already here. inline bool H_pair_insert(int* h, const int size, int a, int b) { _HASH_ADD_CALL(); _HASH_ADD_ITER(); int k = HASH_PAIR_KEY(a, b, size); if (h[2 * k] == HASH_NONE) { h[2 * k] = a; h[2 * k + 1] = b; return true; } while (h[2 * k] != a || h[2 * k + 1] != b) { _HASH_ADD_ITER(); k = HASH_REKEY(k, size); if (h[2 * k] == HASH_NONE) { h[2 * k] = a; h[2 * k + 1] = b; return true; } } return false; } //_________________________________________________________________________ // Generic functions : table can be either Hash or Raw. // the argument 'size' is the number of elements //_________________________________________________________________________ // Look for an element inline bool H_is(int *mem, const int size, const int elem) { if (IS_HASH(size)) { return (H_add(mem, HASH_EXPAND(size), elem) == NULL); } else { return fast_search(mem, size, elem) != NULL; } } //pick random location (containing an element) inline int* H_random(int* mem, int size) { if (!IS_HASH(size)) { return mem + (my_random() % size); } _HASH_RAND_CALL(); size = HASH_EXPAND(size); int* yo; do { yo = mem + HASH_KEY(my_random(), size); _HASH_RAND_ITER(); } while (*yo == HASH_NONE); return yo; } // replace *k by b inline int* H_rpl(int *mem, int size, int* k, const int b) { assert(!H_is(mem, size, b)); if (!IS_HASH(size)) { *k = b; return k; } else { size = HASH_EXPAND(size); assert(mem + int(k - mem) == k); H_rm(mem, size, int(k - mem)); return H_put(mem, size, b); } } // replace a by b inline int* H_rpl(int *mem, int size, const int a, const int b) { assert(H_is(mem, size, a)); assert(!H_is(mem, size, b)); if (!IS_HASH(size)) { return fast_rpl(mem, a, b); } else { size = HASH_EXPAND(size); H_rm(mem, size, H_find(mem, size, a)); return H_put(mem, size, b); } } } // namespace gengraph #endif //HASH_H leidenbase/src/core/games/degree_sequence_vl/gengraph_box_list.h0000644000176200001440000000514214447675374024702 0ustar liggesusers/* * * gengraph - generation of random simple connected graphs with prescribed * degree sequence * * Copyright (C) 2006 Fabien Viger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // This class allows to maintain a list of vertices, // sorted by degree (largest degrees first) // Operations allowed : // - get the vertex having max degree -> Cost = O(1) // - remove any vertex from the graph -> Cost = Sum(degrees of neighbours) // [ could be O(degree) if optimized ] #ifndef _BOX_LIST_H #define _BOX_LIST_H namespace gengraph { class box_list { private: int n; // INITIAL number of vertices int dmax; // CURRENT Maximum degree int *deg; // CURRENT Degrees (points directly to the deg[] of the graph // Vertices are grouped by degree: one double-chained lists for each degree int *list; // list[d-1] is the head of list of vertices of degree d int *next; // next[v]/prev[v] are the vertices next/previous to v int *prev; // in the list where v belongs void pop(int); // pop(v) just removes v from its list void insert(int); // insert(v) insert v at the head of its list public: // Ctor. Takes O(n) time. box_list(int n0, int *deg0); // Dtor ~box_list(); // Self-explaining inline routines inline bool is_empty() { return dmax < 1; }; inline int get_max() { return list[dmax - 1]; }; inline int get_one() { return list[0]; }; inline int get_min() { int i = 0; while (list[i] < 0) { i++; } return list[i]; }; // Remove v from box_list // Also, semi-remove vertex v from graph: all neighbours of v will swap // their last neighbour wit hv, and then decrease their degree, so // that any arc w->v virtually disappear // Actually, adjacency lists are just permuted, and deg[] is changed void pop_vertex(int v, int **neigh); }; } // namespace gengraph #endif //_BOX_LIST_H leidenbase/src/core/games/islands.c0000644000176200001440000001273214447675374017013 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_random.h" /** * \ingroup generators * \function igraph_simple_interconnected_islands_game * \brief Generates a random graph made of several interconnected islands, each island being a random graph. * * \param graph Pointer to an uninitialized graph object. * \param islands_n The number of islands in the graph. * \param islands_size The size of islands in the graph. * \param islands_pin The probability to create each possible edge into each island. * \param n_inter The number of edges to create between two islands. * * \return Error code: * \c IGRAPH_EINVAL: invalid parameter * \c IGRAPH_ENOMEM: there is not enough * memory for the operation. * * Time complexity: O(|V|+|E|), the * number of vertices plus the number of edges in the graph. * */ int igraph_simple_interconnected_islands_game( igraph_t *graph, igraph_integer_t islands_n, igraph_integer_t islands_size, igraph_real_t islands_pin, igraph_integer_t n_inter) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; igraph_vector_t s = IGRAPH_VECTOR_NULL; int nbNodes; double maxpossibleedgesPerIsland; double maxedgesPerIsland; int nbEdgesInterIslands; double maxedges; int startIsland = 0; int endIsland = 0; int i, j, is; double myrand, last; long int vsize; if (islands_n < 0) { IGRAPH_ERRORF("Number of islands cannot be negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, islands_n); } if (islands_size < 0) { IGRAPH_ERRORF("Size of islands cannot be negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, islands_size); } if (islands_pin < 0 || islands_pin > 1) { IGRAPH_ERRORF("Edge probability within islands should be between 0 and 1, got %g.", IGRAPH_EINVAL, islands_pin); } if (n_inter < 0) { IGRAPH_ERRORF("Number of inter-island links cannot be negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, n_inter); } /* how much memory ? */ nbNodes = islands_n * islands_size; maxpossibleedgesPerIsland = ((double)islands_size * ((double)islands_size - (double)1)) / (double)2; maxedgesPerIsland = islands_pin * maxpossibleedgesPerIsland; nbEdgesInterIslands = n_inter * (islands_n * (islands_n - 1)) / 2; maxedges = maxedgesPerIsland * islands_n + nbEdgesInterIslands; /* reserve enough space for all the edges */ IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, (long int) maxedges)); RNG_BEGIN(); /* first create all the islands */ for (is = 0; is < islands_n; is++) { /* for each island */ /* index for start and end of nodes in this island */ startIsland = islands_size * is; endIsland = startIsland + islands_size - 1; /* create the random numbers to be used (into s) */ IGRAPH_VECTOR_INIT_FINALLY(&s, 0); IGRAPH_CHECK(igraph_vector_reserve(&s, (long int) maxedgesPerIsland)); last = RNG_GEOM(islands_pin); while (last < maxpossibleedgesPerIsland) { /* maxedgesPerIsland */ IGRAPH_CHECK(igraph_vector_push_back(&s, last)); myrand = RNG_GEOM(islands_pin); last += myrand; /* RNG_GEOM(islands_pin); */ last += 1; } /* change this to edges ! */ vsize = igraph_vector_size(&s); for (i = 0; i < vsize; i++) { long int to = (long int) floor((sqrt(8 * VECTOR(s)[i] + 1) + 1) / 2); long int from = (long int) (VECTOR(s)[i] - (((igraph_real_t)to) * (to - 1)) / 2); to += startIsland; from += startIsland; igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } /* clear the memory used for random number for this island */ igraph_vector_destroy(&s); IGRAPH_FINALLY_CLEAN(1); /* create the links with other islands */ for (i = is + 1; i < islands_n; i++) { /* for each other island (not the previous ones) */ for (j = 0; j < n_inter; j++) { /* for each link between islands */ long int from = RNG_INTEGER(startIsland, endIsland); long int to = RNG_INTEGER(i * islands_size, (i + 1) * islands_size - 1); igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } } } RNG_END(); /* actually fill the graph object */ IGRAPH_CHECK(igraph_create(graph, &edges, nbNodes, 0)); /* clean remaining things */ igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/games/sbm.c0000644000176200001440000005611514447675374016142 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph R library. Copyright (C) 2003-2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_interface.h" #include "igraph_vector.h" #include "igraph_matrix.h" #include "igraph_random.h" #include "igraph_constructors.h" #include "igraph_games.h" #include "core/interruption.h" #include /* for DBL_EPSILON */ #include /* for sqrt */ /** * \function igraph_sbm_game * \brief Sample from a stochastic block model. * * This function samples graphs from a stochastic block * model by (doing the equivalent of) Bernoulli * trials for each potential edge with the probabilities * given by the Bernoulli rate matrix, \p pref_matrix. * See Faust, K., & Wasserman, S. (1992a). Blockmodels: * Interpretation and evaluation. Social Networks, 14, 5-–61. * * * The order of the vertex ids in the generated graph corresponds to * the \p block_sizes argument. * * \param graph The output graph. This should be a pointer to an * uninitialized graph. * \param n Number of vertices. * \param pref_matrix The matrix giving the Bernoulli rates. * This is a KxK matrix, where K is the number of groups. * The probability of creating an edge between vertices from * groups i and j is given by element (i,j). * \param block_sizes An integer vector giving the number of * vertices in each group. * \param directed Boolean, whether to create a directed graph. If * this argument is false, then \p pref_matrix must be symmetric. * \param loops Boolean, whether to create self-loops. * \return Error code. * * Time complexity: O(|V|+|E|+K^2), where |V| is the number of * vertices, |E| is the number of edges, and K is the number of * groups. * * \sa \ref igraph_erdos_renyi_game() for a simple Bernoulli graph. * */ int igraph_sbm_game(igraph_t *graph, igraph_integer_t n, const igraph_matrix_t *pref_matrix, const igraph_vector_int_t *block_sizes, igraph_bool_t directed, igraph_bool_t loops) { long int no_blocks = igraph_matrix_nrow(pref_matrix); long int from, to, fromoff = 0; igraph_real_t minp, maxp; igraph_vector_t edges; /* ------------------------------------------------------------ */ /* Check arguments */ /* ------------------------------------------------------------ */ if (igraph_matrix_ncol(pref_matrix) != no_blocks) { IGRAPH_ERROR("Preference matrix is not square.", IGRAPH_NONSQUARE); } if (no_blocks > 0) { igraph_matrix_minmax(pref_matrix, &minp, &maxp); if (minp < 0 || maxp > 1) { IGRAPH_ERROR("Connection probabilities must be in [0,1].", IGRAPH_EINVAL); } } if (!directed && !igraph_matrix_is_symmetric(pref_matrix)) { IGRAPH_ERROR("Preference matrix must be symmetric for undirected graphs.", IGRAPH_EINVAL); } if (igraph_vector_int_size(block_sizes) != no_blocks) { IGRAPH_ERRORF("Block size vector length (%ld) does not agree with " "preference matrix size (%ld).", IGRAPH_EINVAL, igraph_vector_int_size(block_sizes), no_blocks); } if (no_blocks > 0) { if (igraph_vector_int_min(block_sizes) < 0) { IGRAPH_ERRORF("Block sizes must be non-negative, but got %" IGRAPH_PRId ".", IGRAPH_EINVAL, igraph_vector_int_min(block_sizes)); } } if (igraph_vector_int_sum(block_sizes) != n) { IGRAPH_ERRORF("Sum of the block sizes (%" IGRAPH_PRId ") must equal the number of vertices (%" IGRAPH_PRId ").", IGRAPH_EINVAL, igraph_vector_int_sum(block_sizes), n); } /* Since the sum of the block sizes should equal the number of vertices, * and the block sizes are non-negative, the number of vertices is * guaranteed to be non-negative. This shouldn't be checked separately. */ IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); RNG_BEGIN(); for (from = 0; from < no_blocks; from++) { double fromsize = VECTOR(*block_sizes)[from]; long int start = directed ? 0 : from; long int i, tooff = 0; IGRAPH_ALLOW_INTERRUPTION(); for (i = 0; i < start; i++) { tooff += VECTOR(*block_sizes)[i]; } for (to = start; to < no_blocks; to++) { double tosize = VECTOR(*block_sizes)[to]; igraph_real_t prob = MATRIX(*pref_matrix, from, to); double maxedges, last = RNG_GEOM(prob); if (directed && loops) { maxedges = fromsize * tosize; while (last < maxedges) { long int vto = floor(last / fromsize); long int vfrom = last - (igraph_real_t)vto * fromsize; igraph_vector_push_back(&edges, fromoff + vfrom); igraph_vector_push_back(&edges, tooff + vto); last += RNG_GEOM(prob); last += 1; } } else if (directed && !loops && from != to) { maxedges = fromsize * tosize; while (last < maxedges) { long int vto = floor(last / fromsize); long int vfrom = last - (igraph_real_t)vto * fromsize; igraph_vector_push_back(&edges, fromoff + vfrom); igraph_vector_push_back(&edges, tooff + vto); last += RNG_GEOM(prob); last += 1; } } else if (directed && !loops && from == to) { maxedges = fromsize * (fromsize - 1); while (last < maxedges) { long int vto = floor(last / fromsize); long int vfrom = last - (igraph_real_t)vto * fromsize; if (vfrom == vto) { vto = fromsize - 1; } igraph_vector_push_back(&edges, fromoff + vfrom); igraph_vector_push_back(&edges, tooff + vto); last += RNG_GEOM(prob); last += 1; } } else if (!directed && loops && from != to) { maxedges = fromsize * tosize; while (last < maxedges) { long int vto = floor(last / fromsize); long int vfrom = last - (igraph_real_t)vto * fromsize; igraph_vector_push_back(&edges, fromoff + vfrom); igraph_vector_push_back(&edges, tooff + vto); last += RNG_GEOM(prob); last += 1; } } else if (!directed && loops && from == to) { maxedges = fromsize * (fromsize + 1) / 2.0; while (last < maxedges) { long int vto = floor((sqrt(8 * last + 1) - 1) / 2); long int vfrom = last - (((igraph_real_t)vto) * (vto + 1)) / 2; igraph_vector_push_back(&edges, fromoff + vfrom); igraph_vector_push_back(&edges, tooff + vto); last += RNG_GEOM(prob); last += 1; } } else if (!directed && !loops && from != to) { maxedges = fromsize * tosize; while (last < maxedges) { long int vto = floor(last / fromsize); long int vfrom = last - (igraph_real_t)vto * fromsize; igraph_vector_push_back(&edges, fromoff + vfrom); igraph_vector_push_back(&edges, tooff + vto); last += RNG_GEOM(prob); last += 1; } } else { /*!directed && !loops && from==to */ maxedges = fromsize * (fromsize - 1) / 2.0; while (last < maxedges) { long int vto = floor((sqrt(8 * last + 1) + 1) / 2); long int vfrom = last - (((igraph_real_t)vto) * (vto - 1)) / 2; igraph_vector_push_back(&edges, fromoff + vfrom); igraph_vector_push_back(&edges, tooff + vto); last += RNG_GEOM(prob); last += 1; } } tooff += tosize; } fromoff += fromsize; } RNG_END(); igraph_create(graph, &edges, n, directed); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \function igraph_hsbm_game * \brief Hierarchical stochastic block model. * * The function generates a random graph according to the hierarchical * stochastic block model. * * \param graph The generated graph is stored here. * \param n The number of vertices in the graph. * \param m The number of vertices per block. n/m must be integer. * \param rho The fraction of vertices per cluster, * within a block. Must sum up to 1, and rho * m must be integer * for all elements of rho. * \param C A square, symmetric numeric matrix, the Bernoulli rates for * the clusters within a block. Its size must mach the size of the * \code{rho} vector. * \param p The Bernoulli rate of connections between * vertices in different blocks. * \return Error code. * * \sa \ref igraph_sbm_game() for the classic stochastic block model, * \ref igraph_hsbm_list_game() for a more general version. */ int igraph_hsbm_game(igraph_t *graph, igraph_integer_t n, igraph_integer_t m, const igraph_vector_t *rho, const igraph_matrix_t *C, igraph_real_t p) { int b, i, k = igraph_vector_size(rho); igraph_vector_t csizes; igraph_real_t sq_dbl_epsilon = sqrt(DBL_EPSILON); int no_blocks = n / m; igraph_vector_t edges; int offset = 0; if (n < 1) { IGRAPH_ERROR("`n' must be positive for HSBM", IGRAPH_EINVAL); } if (m < 1) { IGRAPH_ERROR("`m' must be positive for HSBM", IGRAPH_EINVAL); } if ((long) n % (long) m) { IGRAPH_ERROR("`n' must be a multiple of `m' for HSBM", IGRAPH_EINVAL); } if (!igraph_vector_isininterval(rho, 0, 1)) { IGRAPH_ERROR("`rho' must be between zero and one for HSBM", IGRAPH_EINVAL); } if (igraph_matrix_min(C) < 0 || igraph_matrix_max(C) > 1) { IGRAPH_ERROR("`C' must be between zero and one for HSBM", IGRAPH_EINVAL); } if (fabs(igraph_vector_sum(rho) - 1.0) > sq_dbl_epsilon) { IGRAPH_ERROR("`rho' must sum up to 1 for HSBM", IGRAPH_EINVAL); } if (igraph_matrix_nrow(C) != k || igraph_matrix_ncol(C) != k) { IGRAPH_ERROR("`C' dimensions must match `rho' dimensions in HSBM", IGRAPH_EINVAL); } if (!igraph_matrix_is_symmetric(C)) { IGRAPH_ERROR("`C' must be a symmetric matrix", IGRAPH_EINVAL); } if (p < 0 || p > 1) { IGRAPH_ERROR("`p' must be a probability for HSBM", IGRAPH_EINVAL); } for (i = 0; i < k; i++) { igraph_real_t s = VECTOR(*rho)[i] * m; if (fabs(round(s) - s) > sq_dbl_epsilon) { IGRAPH_ERROR("`rho' * `m' is not integer in HSBM", IGRAPH_EINVAL); } } IGRAPH_VECTOR_INIT_FINALLY(&csizes, k); for (i = 0; i < k; i++) { VECTOR(csizes)[i] = round(VECTOR(*rho)[i] * m); } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); RNG_BEGIN(); /* Block models first */ for (b = 0; b < no_blocks; b++) { int from, to, fromoff = 0; for (from = 0; from < k; from++) { int fromsize = VECTOR(csizes)[from]; int i, tooff = 0; for (i = 0; i < from; i++) { tooff += VECTOR(csizes)[i]; } for (to = from; to < k; to++) { int tosize = VECTOR(csizes)[to]; igraph_real_t prob = MATRIX(*C, from, to); igraph_real_t maxedges; igraph_real_t last = RNG_GEOM(prob); if (from != to) { maxedges = fromsize * tosize; while (last < maxedges) { int vto = floor(last / fromsize); int vfrom = last - (igraph_real_t)vto * fromsize; igraph_vector_push_back(&edges, offset + fromoff + vfrom); igraph_vector_push_back(&edges, offset + tooff + vto); last += RNG_GEOM(prob); last += 1; } } else { /* from==to */ maxedges = fromsize * (fromsize - 1) / 2.0; while (last < maxedges) { int vto = floor((sqrt(8 * last + 1) + 1) / 2); int vfrom = last - (((igraph_real_t)vto) * (vto - 1)) / 2; igraph_vector_push_back(&edges, offset + fromoff + vfrom); igraph_vector_push_back(&edges, offset + tooff + vto); last += RNG_GEOM(prob); last += 1; } } tooff += tosize; } fromoff += fromsize; } offset += m; } /* And now the rest, if not a special case */ if (p == 1) { int fromoff = 0, tooff = m; for (b = 0; b < no_blocks; b++) { igraph_real_t fromsize = m; igraph_real_t tosize = n - tooff; int from, to; for (from = 0; from < fromsize; from++) { for (to = 0; to < tosize; to++) { igraph_vector_push_back(&edges, fromoff + from); igraph_vector_push_back(&edges, tooff + to); } } fromoff += m; tooff += m; } } else if (p > 0) { int fromoff = 0, tooff = m; for (b = 0; b < no_blocks; b++) { igraph_real_t fromsize = m; igraph_real_t tosize = n - tooff; igraph_real_t maxedges = fromsize * tosize; igraph_real_t last = RNG_GEOM(p); while (last < maxedges) { int vto = floor(last / fromsize); int vfrom = last - (igraph_real_t) vto * fromsize; igraph_vector_push_back(&edges, fromoff + vfrom); igraph_vector_push_back(&edges, tooff + vto); last += RNG_GEOM(p); last += 1; } fromoff += m; tooff += m; } } RNG_END(); igraph_create(graph, &edges, n, /*directed=*/ 0); igraph_vector_destroy(&edges); igraph_vector_destroy(&csizes); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_hsbm_list_game * \brief Hierarchical stochastic block model, more general version. * * The function generates a random graph according to the hierarchical * stochastic block model. * * \param graph The generated graph is stored here. * \param n The number of vertices in the graph. * \param mlist An integer vector of block sizes. * \param rholist A list of rho vectors (\c igraph_vector_t objects), one * for each block. * \param Clist A list of square matrices (\c igraph_matrix_t objects), * one for each block, giving the Bernoulli rates of connections * within the block. * \param p The Bernoulli rate of connections between * vertices in different blocks. * \return Error code. * * \sa \ref igraph_sbm_game() for the classic stochastic block model, * \ref igraph_hsbm_game() for a simpler general version. */ int igraph_hsbm_list_game(igraph_t *graph, igraph_integer_t n, const igraph_vector_int_t *mlist, const igraph_vector_ptr_t *rholist, const igraph_vector_ptr_t *Clist, igraph_real_t p) { int i, no_blocks = igraph_vector_ptr_size(rholist); igraph_real_t sq_dbl_epsilon = sqrt(DBL_EPSILON); igraph_vector_t csizes, edges; int b, offset = 0; if (n < 1) { IGRAPH_ERROR("`n' must be positive for HSBM", IGRAPH_EINVAL); } if (no_blocks == 0) { IGRAPH_ERROR("`rholist' empty for HSBM", IGRAPH_EINVAL); } if (igraph_vector_ptr_size(Clist) != no_blocks && igraph_vector_int_size(mlist) != no_blocks) { IGRAPH_ERROR("`rholist' must have same length as `Clist' and `m' " "for HSBM", IGRAPH_EINVAL); } if (p < 0 || p > 1) { IGRAPH_ERROR("`p' must be a probability for HSBM", IGRAPH_EINVAL); } /* Checks for m's */ if (igraph_vector_int_sum(mlist) != n) { IGRAPH_ERROR("`m' must sum up to `n' for HSBM", IGRAPH_EINVAL); } if (igraph_vector_int_min(mlist) < 1) { IGRAPH_ERROR("`m' must be positive for HSBM", IGRAPH_EINVAL); } /* Checks for the rhos */ for (i = 0; i < no_blocks; i++) { const igraph_vector_t *rho = VECTOR(*rholist)[i]; if (!igraph_vector_isininterval(rho, 0, 1)) { IGRAPH_ERROR("`rho' must be between zero and one for HSBM", IGRAPH_EINVAL); } if (fabs(igraph_vector_sum(rho) - 1.0) > sq_dbl_epsilon) { IGRAPH_ERROR("`rho' must sum up to 1 for HSBM", IGRAPH_EINVAL); } } /* Checks for the Cs */ for (i = 0; i < no_blocks; i++) { const igraph_matrix_t *C = VECTOR(*Clist)[i]; if (igraph_matrix_min(C) < 0 || igraph_matrix_max(C) > 1) { IGRAPH_ERROR("`C' must be between zero and one for HSBM", IGRAPH_EINVAL); } if (!igraph_matrix_is_symmetric(C)) { IGRAPH_ERROR("`C' must be a symmetric matrix", IGRAPH_EINVAL); } } /* Check that C and rho sizes match */ for (i = 0; i < no_blocks; i++) { const igraph_vector_t *rho = VECTOR(*rholist)[i]; const igraph_matrix_t *C = VECTOR(*Clist)[i]; int k = igraph_vector_size(rho); if (igraph_matrix_nrow(C) != k || igraph_matrix_ncol(C) != k) { IGRAPH_ERROR("`C' dimensions must match `rho' dimensions in HSBM", IGRAPH_EINVAL); } } /* Check that rho * m is integer */ for (i = 0; i < no_blocks; i++) { const igraph_vector_t *rho = VECTOR(*rholist)[i]; igraph_real_t m = VECTOR(*mlist)[i]; int j, k = igraph_vector_size(rho); for (j = 0; j < k; j++) { igraph_real_t s = VECTOR(*rho)[j] * m; if (fabs(round(s) - s) > sq_dbl_epsilon) { IGRAPH_ERROR("`rho' * `m' is not integer in HSBM", IGRAPH_EINVAL); } } } IGRAPH_VECTOR_INIT_FINALLY(&csizes, 0); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); RNG_BEGIN(); /* Block models first */ for (b = 0; b < no_blocks; b++) { int from, to, fromoff = 0; const igraph_vector_t *rho = VECTOR(*rholist)[b]; const igraph_matrix_t *C = VECTOR(*Clist)[b]; igraph_real_t m = VECTOR(*mlist)[b]; int k = igraph_vector_size(rho); igraph_vector_resize(&csizes, k); for (i = 0; i < k; i++) { VECTOR(csizes)[i] = round(VECTOR(*rho)[i] * m); } for (from = 0; from < k; from++) { int fromsize = VECTOR(csizes)[from]; int i, tooff = 0; for (i = 0; i < from; i++) { tooff += VECTOR(csizes)[i]; } for (to = from; to < k; to++) { int tosize = VECTOR(csizes)[to]; igraph_real_t prob = MATRIX(*C, from, to); igraph_real_t maxedges; igraph_real_t last = RNG_GEOM(prob); if (from != to) { maxedges = fromsize * tosize; while (last < maxedges) { int vto = floor(last / fromsize); int vfrom = last - (igraph_real_t)vto * fromsize; igraph_vector_push_back(&edges, offset + fromoff + vfrom); igraph_vector_push_back(&edges, offset + tooff + vto); last += RNG_GEOM(prob); last += 1; } } else { /* from==to */ maxedges = fromsize * (fromsize - 1) / 2.0; while (last < maxedges) { int vto = floor((sqrt(8 * last + 1) + 1) / 2); int vfrom = last - (((igraph_real_t)vto) * (vto - 1)) / 2; igraph_vector_push_back(&edges, offset + fromoff + vfrom); igraph_vector_push_back(&edges, offset + tooff + vto); last += RNG_GEOM(prob); last += 1; } } tooff += tosize; } fromoff += fromsize; } offset += m; } /* And now the rest, if not a special case */ if (p == 1) { int fromoff = 0, tooff = VECTOR(*mlist)[0]; for (b = 0; b < no_blocks; b++) { igraph_real_t fromsize = VECTOR(*mlist)[b]; igraph_real_t tosize = n - tooff; int from, to; for (from = 0; from < fromsize; from++) { for (to = 0; to < tosize; to++) { igraph_vector_push_back(&edges, fromoff + from); igraph_vector_push_back(&edges, tooff + to); } } fromoff += fromsize; if (b + 1 < no_blocks) { tooff += VECTOR(*mlist)[b + 1]; } } } else if (p > 0) { int fromoff = 0, tooff = VECTOR(*mlist)[0]; for (b = 0; b < no_blocks; b++) { igraph_real_t fromsize = VECTOR(*mlist)[b]; igraph_real_t tosize = n - tooff; igraph_real_t maxedges = fromsize * tosize; igraph_real_t last = RNG_GEOM(p); while (last < maxedges) { int vto = floor(last / fromsize); int vfrom = last - (igraph_real_t) vto * fromsize; igraph_vector_push_back(&edges, fromoff + vfrom); igraph_vector_push_back(&edges, tooff + vto); last += RNG_GEOM(p); last += 1; } fromoff += fromsize; if (b + 1 < no_blocks) { tooff += VECTOR(*mlist)[b + 1]; } } } RNG_END(); igraph_create(graph, &edges, n, /*directed=*/ 0); igraph_vector_destroy(&edges); igraph_vector_destroy(&csizes); IGRAPH_FINALLY_CLEAN(2); return 0; } leidenbase/src/core/games/barabasi.c0000644000176200001440000007200414447675374017120 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_conversion.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_psumtree.h" #include "igraph_random.h" #include "core/interruption.h" static int igraph_i_barabasi_game_bag(igraph_t *graph, igraph_integer_t n, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_bool_t directed, const igraph_t *start_from); static int igraph_i_barabasi_game_psumtree_multiple(igraph_t *graph, igraph_integer_t n, igraph_real_t power, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t A, igraph_bool_t directed, const igraph_t *start_from); static int igraph_i_barabasi_game_psumtree(igraph_t *graph, igraph_integer_t n, igraph_real_t power, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t A, igraph_bool_t directed, const igraph_t *start_from); static int igraph_i_barabasi_game_bag(igraph_t *graph, igraph_integer_t n, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_bool_t directed, const igraph_t *start_from) { long int no_of_nodes = n; long int no_of_neighbors = m; long int *bag; long int bagp = 0; igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int resp; long int i, j, k; long int bagsize, start_nodes, start_edges, new_edges, no_of_edges; if (!directed) { outpref = 1; } start_nodes = start_from ? igraph_vcount(start_from) : 1; start_edges = start_from ? igraph_ecount(start_from) : 0; if (outseq) { if (igraph_vector_size(outseq) > 1) { new_edges = (long int) (igraph_vector_sum(outseq) - VECTOR(*outseq)[0]); } else { new_edges = 0; } } else { new_edges = (no_of_nodes - start_nodes) * no_of_neighbors; } no_of_edges = start_edges + new_edges; resp = start_edges * 2; bagsize = no_of_nodes + no_of_edges + (outpref ? no_of_edges : 0); IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); bag = IGRAPH_CALLOC(bagsize, long int); if (bag == 0) { IGRAPH_ERROR("barabasi_game failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, bag); /* The first node(s) in the bag */ if (start_from) { igraph_vector_t deg; long int ii, jj, sn = igraph_vcount(start_from); igraph_neimode_t mm = outpref ? IGRAPH_ALL : IGRAPH_IN; IGRAPH_VECTOR_INIT_FINALLY(°, sn); IGRAPH_CHECK(igraph_degree(start_from, °, igraph_vss_all(), mm, IGRAPH_LOOPS)); for (ii = 0; ii < sn; ii++) { long int d = (long int) VECTOR(deg)[ii]; for (jj = 0; jj <= d; jj++) { bag[bagp++] = ii; } } igraph_vector_destroy(°); IGRAPH_FINALLY_CLEAN(1); } else { bag[bagp++] = 0; } /* Initialize the edges vector */ if (start_from) { IGRAPH_CHECK(igraph_get_edgelist(start_from, &edges, /* bycol= */ 0)); igraph_vector_resize(&edges, no_of_edges * 2); } RNG_BEGIN(); /* and the others */ for (i = (start_from ? start_nodes : 1), k = (start_from ? 0 : 1); i < no_of_nodes; i++, k++) { IGRAPH_ALLOW_INTERRUPTION(); /* draw edges */ if (outseq) { no_of_neighbors = (long int) VECTOR(*outseq)[k]; } for (j = 0; j < no_of_neighbors; j++) { long int to = bag[RNG_INTEGER(0, bagp - 1)]; VECTOR(edges)[resp++] = i; VECTOR(edges)[resp++] = to; } /* update bag */ bag[bagp++] = i; for (j = 0; j < no_of_neighbors; j++) { bag[bagp++] = (long int) VECTOR(edges)[resp - 2 * j - 1]; if (outpref) { bag[bagp++] = i; } } } RNG_END(); IGRAPH_FREE(bag); IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_barabasi_game_psumtree_multiple(igraph_t *graph, igraph_integer_t n, igraph_real_t power, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t A, igraph_bool_t directed, const igraph_t *start_from) { long int no_of_nodes = n; long int no_of_neighbors = m; igraph_vector_t edges; long int i, j, k; igraph_psumtree_t sumtree; long int edgeptr = 0; igraph_vector_t degree; long int start_nodes, start_edges, new_edges, no_of_edges; if (!directed) { outpref = 1; } start_nodes = start_from ? igraph_vcount(start_from) : 1; start_edges = start_from ? igraph_ecount(start_from) : 0; if (outseq) { if (igraph_vector_size(outseq) > 1) { new_edges = (long int) (igraph_vector_sum(outseq) - VECTOR(*outseq)[0]); } else { new_edges = 0; } } else { new_edges = (no_of_nodes - start_nodes) * no_of_neighbors; } no_of_edges = start_edges + new_edges; edgeptr = start_edges * 2; IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); IGRAPH_CHECK(igraph_psumtree_init(&sumtree, no_of_nodes)); IGRAPH_FINALLY(igraph_psumtree_destroy, &sumtree); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); /* first node(s) */ if (start_from) { long int ii, sn = igraph_vcount(start_from); igraph_neimode_t mm = outpref ? IGRAPH_ALL : IGRAPH_IN; IGRAPH_CHECK(igraph_degree(start_from, °ree, igraph_vss_all(), mm, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_vector_resize(°ree, no_of_nodes)); for (ii = 0; ii < sn; ii++) { IGRAPH_CHECK(igraph_psumtree_update(&sumtree, ii, pow(VECTOR(degree)[ii], power) + A)); } } else { IGRAPH_CHECK(igraph_psumtree_update(&sumtree, 0, A)); } /* Initialize the edges vector */ if (start_from) { IGRAPH_CHECK(igraph_get_edgelist(start_from, &edges, /* bycol= */ 0)); igraph_vector_resize(&edges, no_of_edges * 2); } RNG_BEGIN(); /* and the rest */ for (i = (start_from ? start_nodes : 1), k = (start_from ? 0 : 1); i < no_of_nodes; i++, k++) { igraph_real_t sum = igraph_psumtree_sum(&sumtree); long int to; IGRAPH_ALLOW_INTERRUPTION(); if (outseq) { no_of_neighbors = (long int) VECTOR(*outseq)[k]; } for (j = 0; j < no_of_neighbors; j++) { igraph_psumtree_search(&sumtree, &to, RNG_UNIF(0, sum)); VECTOR(degree)[to]++; VECTOR(edges)[edgeptr++] = i; VECTOR(edges)[edgeptr++] = to; } /* update probabilities */ for (j = 0; j < no_of_neighbors; j++) { long int nn = (long int) VECTOR(edges)[edgeptr - 2 * j - 1]; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, nn, pow(VECTOR(degree)[nn], power) + A)); } if (outpref) { VECTOR(degree)[i] += no_of_neighbors; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, i, pow(VECTOR(degree)[i], power) + A)); } else { IGRAPH_CHECK(igraph_psumtree_update(&sumtree, i, A)); } } RNG_END(); igraph_psumtree_destroy(&sumtree); igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_barabasi_game_psumtree(igraph_t *graph, igraph_integer_t n, igraph_real_t power, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t A, igraph_bool_t directed, const igraph_t *start_from) { long int no_of_nodes = n; long int no_of_neighbors = m; igraph_vector_t edges; long int i, j, k; igraph_psumtree_t sumtree; long int edgeptr = 0; igraph_vector_t degree; long int start_nodes, start_edges, new_edges, no_of_edges; if (!directed) { outpref = 1; } start_nodes = start_from ? igraph_vcount(start_from) : 1; start_edges = start_from ? igraph_ecount(start_from) : 0; if (outseq) { if (igraph_vector_size(outseq) > 1) { new_edges = (long int) (igraph_vector_sum(outseq) - VECTOR(*outseq)[0]); } else { new_edges = 0; } } else { new_edges = (no_of_nodes - start_nodes) * no_of_neighbors; } no_of_edges = start_edges + new_edges; edgeptr = start_edges * 2; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); IGRAPH_CHECK(igraph_psumtree_init(&sumtree, no_of_nodes)); IGRAPH_FINALLY(igraph_psumtree_destroy, &sumtree); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); RNG_BEGIN(); /* first node(s) */ if (start_from) { long int ii, sn = igraph_vcount(start_from); igraph_neimode_t mm = outpref ? IGRAPH_ALL : IGRAPH_IN; IGRAPH_CHECK(igraph_degree(start_from, °ree, igraph_vss_all(), mm, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_vector_resize(°ree, no_of_nodes)); for (ii = 0; ii < sn; ii++) { IGRAPH_CHECK(igraph_psumtree_update(&sumtree, ii, pow(VECTOR(degree)[ii], power) + A)); } } else { IGRAPH_CHECK(igraph_psumtree_update(&sumtree, 0, A)); } /* Initialize the edges vector */ if (start_from) { IGRAPH_CHECK(igraph_get_edgelist(start_from, &edges, /* bycol= */ 0)); } /* and the rest */ for (i = (start_from ? start_nodes : 1), k = (start_from ? 0 : 1); i < no_of_nodes; i++, k++) { igraph_real_t sum; long int to; IGRAPH_ALLOW_INTERRUPTION(); if (outseq) { no_of_neighbors = (long int) VECTOR(*outseq)[k]; } if (no_of_neighbors >= i) { /* All existing vertices are cited */ for (to = 0; to < i; to++) { VECTOR(degree)[to]++; IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); edgeptr += 2; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, to, pow(VECTOR(degree)[to], power) + A)); } } else { for (j = 0; j < no_of_neighbors; j++) { sum = igraph_psumtree_sum(&sumtree); igraph_psumtree_search(&sumtree, &to, RNG_UNIF(0, sum)); VECTOR(degree)[to]++; IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); edgeptr += 2; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, to, 0.0)); } /* update probabilities */ for (j = 0; j < no_of_neighbors; j++) { long int nn = (long int) VECTOR(edges)[edgeptr - 2 * j - 1]; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, nn, pow(VECTOR(degree)[nn], power) + A)); } } if (outpref) { VECTOR(degree)[i] += no_of_neighbors > i ? i : no_of_neighbors; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, i, pow(VECTOR(degree)[i], power) + A)); } else { IGRAPH_CHECK(igraph_psumtree_update(&sumtree, i, A)); } } RNG_END(); igraph_psumtree_destroy(&sumtree); igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup generators * \function igraph_barabasi_game * \brief Generates a graph based on the Barabási-Albert model. * * \param graph An uninitialized graph object. * \param n The number of vertices in the graph. * \param power Power of the preferential attachment. The probability * that a vertex is cited is proportional to d^power+A, where * d is its degree (see also the \p outpref argument), power * and A are given by arguments. In the classic preferential * attachment model power=1. * \param m The number of outgoing edges generated for each * vertex. (Only if \p outseq is \c NULL.) * \param outseq Gives the (out-)degrees of the vertices. If this is * constant, this can be a NULL pointer or an empty (but * initialized!) vector, in this case \p m contains * the constant out-degree. The very first vertex has by definition * no outgoing edges, so the first number in this vector is * ignored. * \param outpref Boolean, if true not only the in- but also the out-degree * of a vertex increases its citation probability. I.e., the * citation probability is determined by the total degree of * the vertices. Ignored and assumed to be true if the graph * being generated is undirected. * \param A The probability that a vertex is cited is proportional to * d^power+A, where d is its degree (see also the \p outpref * argument), power and A are given by arguments. In the * previous versions of the function this parameter was * implicitly set to one. * \param directed Boolean, whether to generate a directed graph. * \param algo The algorithm to use to generate the network. Possible * values: * \clist * \cli IGRAPH_BARABASI_BAG * This is the algorithm that was previously (before version * 0.6) solely implemented in igraph. It works by putting the * ids of the vertices into a bag (multiset, really), exactly * as many times as their (in-)degree, plus once more. Then * the required number of cited vertices are drawn from the * bag, with replacement. This method might generate multiple * edges. It only works if power=1 and A=1. * \cli IGRAPH_BARABASI_PSUMTREE * This algorithm uses a partial prefix-sum tree to generate * the graph. It does not generate multiple edges and * works for any power and A values. * \cli IGRAPH_BARABASI_PSUMTREE_MULTIPLE * This algorithm also uses a partial prefix-sum tree to * generate the graph. The difference is, that now multiple * edges are allowed. This method was implemented under the * name \c igraph_nonlinear_barabasi_game before version 0.6. * \endclist * \param start_from Either a null pointer, or a graph. In the former * case, the starting configuration is a clique of size \p m. * In the latter case, the graph is a starting configuration. * The graph must be non-empty, i.e. it must have at least one * vertex. If a graph is supplied here and the \p outseq * argument is also given, then \p outseq should only contain * information on the vertices that are not in the \p * start_from graph. * \return Error code: * \c IGRAPH_EINVAL: invalid \p n, * \p m or \p outseq parameter. * * Time complexity: O(|V|+|E|), the * number of vertices plus the number of edges. * * \example examples/simple/igraph_barabasi_game.c * \example examples/simple/igraph_barabasi_game2.c */ int igraph_barabasi_game(igraph_t *graph, igraph_integer_t n, igraph_real_t power, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t A, igraph_bool_t directed, igraph_barabasi_algorithm_t algo, const igraph_t *start_from) { long int start_nodes = start_from ? igraph_vcount(start_from) : 0; long int newn = start_from ? n - start_nodes : n; /* Fix obscure parameterizations */ if (outseq && igraph_vector_size(outseq) == 0) { outseq = 0; } if (!directed) { outpref = 1; } /* Check arguments */ if (algo != IGRAPH_BARABASI_BAG && algo != IGRAPH_BARABASI_PSUMTREE && algo != IGRAPH_BARABASI_PSUMTREE_MULTIPLE) { IGRAPH_ERROR("Invalid algorithm", IGRAPH_EINVAL); } if (n < 0) { IGRAPH_ERROR("Invalid number of vertices.", IGRAPH_EINVAL); } else if (newn < 0) { IGRAPH_ERROR("Starting graph has too many vertices.", IGRAPH_EINVAL); } if (start_from && start_nodes == 0) { IGRAPH_ERROR("Cannot start from an empty graph.", IGRAPH_EINVAL); } if (outseq != 0 && igraph_vector_size(outseq) != 0 && igraph_vector_size(outseq) != newn) { IGRAPH_ERROR("Invalid out-degree sequence length.", IGRAPH_EINVAL); } if ( (outseq == 0 || igraph_vector_size(outseq) == 0) && m < 0) { IGRAPH_ERROR("Number of edges added per step must not be negative.", IGRAPH_EINVAL); } if (outseq && igraph_vector_min(outseq) < 0) { IGRAPH_ERROR("Negative out-degree in sequence.", IGRAPH_EINVAL); } if (!outpref && A <= 0) { IGRAPH_ERROR("Constant attractiveness (A) must be positive.", IGRAPH_EINVAL); } if (outpref && A < 0) { IGRAPH_ERROR("Constant attractiveness (A) must be non-negative.", IGRAPH_EINVAL); } if (algo == IGRAPH_BARABASI_BAG) { if (power != 1) { IGRAPH_ERROR("Power must be one for 'bag' algorithm.", IGRAPH_EINVAL); } if (A != 1) { IGRAPH_ERROR("Constant attractiveness (A) must be one for bag algorithm.", IGRAPH_EINVAL); } } if (start_from && directed != igraph_is_directed(start_from)) { IGRAPH_WARNING("Directedness of the start graph and the output graph mismatch."); } if (start_from && !igraph_is_directed(start_from) && !outpref) { IGRAPH_ERROR("`outpref' must be true if starting from an undirected graph.", IGRAPH_EINVAL); } if (n == 0) { return igraph_empty(graph, 0, directed); } if (algo == IGRAPH_BARABASI_BAG) { return igraph_i_barabasi_game_bag(graph, n, m, outseq, outpref, directed, start_from); } else if (algo == IGRAPH_BARABASI_PSUMTREE) { return igraph_i_barabasi_game_psumtree(graph, n, power, m, outseq, outpref, A, directed, start_from); } else if (algo == IGRAPH_BARABASI_PSUMTREE_MULTIPLE) { return igraph_i_barabasi_game_psumtree_multiple(graph, n, power, m, outseq, outpref, A, directed, start_from); } return 0; } /** * \function igraph_barabasi_aging_game * \brief Preferential attachment with aging of vertices. * * * This game starts with one vertex (if \p nodes > 0). In each step * a new node is added, and it is connected to \p m existing nodes. * Existing nodes to connect to are chosen with probability dependent * on their (in-)degree (\c k) and age (\c l). * The degree-dependent part is * deg_coef * k^pa_exp + zero_deg_appeal, * while the age-dependent part is * age_coef * l^aging_exp + zero_age_appeal, * which are summed to obtain the final weight. * * * The age \c l is based on the number of vertices in the * network and the \p aging_bins argument: the age of a node * is incremented by 1 after each * floor(nodes / aging_bins) + 1 * time steps. * * \param graph Pointer to an uninitialized graph object. * \param nodes The number of vertices in the graph. * \param m The number of edges to add in each time step. * Ignored if \p outseq is a non-zero length vector. * \param outseq The number of edges to add in each time step. If it * is \c NULL or a zero-length vector then it is ignored * and the \p m argument is used instead. * \param outpref Logical constant, whether the edges * initiated by a vertex contribute to the probability to gain * a new edge. * \param pa_exp The exponent of the preferential attachment, a small * positive number usually, the value 1 yields the classic * linear preferential attachment. * \param aging_exp The exponent of the aging, this is a negative * number usually. * \param aging_bins Integer constant, the number of age bins to use. * \param zero_deg_appeal The degree dependent part of the * attractiveness of the zero degree vertices. * \param zero_age_appeal The age dependent part of the attractiveness * of the vertices of age zero. This parameter is usually zero. * \param deg_coef The coefficient for the degree. * \param age_coef The coefficient for the age. * \param directed Logical constant, whether to generate a directed * graph. * \return Error code. * * Time complexity: O((|V|+|V|/aging_bins)*log(|V|)+|E|). |V| is the number * of vertices, |E| the number of edges. */ int igraph_barabasi_aging_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t pa_exp, igraph_real_t aging_exp, igraph_integer_t aging_bins, igraph_real_t zero_deg_appeal, igraph_real_t zero_age_appeal, igraph_real_t deg_coef, igraph_real_t age_coef, igraph_bool_t directed) { long int no_of_nodes = nodes; long int no_of_neighbors = m; long int binwidth; long int no_of_edges; igraph_vector_t edges; long int i, j, k; igraph_psumtree_t sumtree; long int edgeptr = 0; igraph_vector_t degree; if (no_of_nodes < 0) { IGRAPH_ERRORF("Number of nodes must not be negative, got %ld.", IGRAPH_EINVAL, no_of_nodes); } if (outseq != 0 && igraph_vector_size(outseq) != 0 && igraph_vector_size(outseq) != no_of_nodes) { IGRAPH_ERRORF("The length of the out-degree sequence (%ld) does not agree with the number of nodes (%ld).", IGRAPH_EINVAL, igraph_vector_size(outseq), no_of_nodes); } if ( (outseq == 0 || igraph_vector_size(outseq) == 0) && m < 0) { IGRAPH_ERRORF("The number of edges per time step must not be negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, m); } if (aging_bins <= 0) { IGRAPH_ERRORF("Number of aging bins must be positive, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, aging_bins); } if (deg_coef < 0) { IGRAPH_ERRORF("Degree coefficient must be non-negative, got %g.", IGRAPH_EINVAL, deg_coef); } if (age_coef < 0) { IGRAPH_ERRORF("Age coefficient must be non-negative, got %g.", IGRAPH_EINVAL, deg_coef); } if (zero_deg_appeal < 0) { IGRAPH_ERRORF("Zero degree appeal must be non-negative, got %g.", IGRAPH_EINVAL, zero_deg_appeal); } if (zero_age_appeal < 0) { IGRAPH_ERRORF("Zero age appeal must be non-negative, got %g.", IGRAPH_EINVAL, zero_age_appeal); } if (no_of_nodes == 0) { return igraph_empty(graph, 0, directed); } binwidth = no_of_nodes / aging_bins + 1; if (outseq == 0 || igraph_vector_size(outseq) == 0) { no_of_neighbors = m; no_of_edges = (no_of_nodes - 1) * no_of_neighbors; } else { no_of_edges = 0; for (i = 1; i < igraph_vector_size(outseq); i++) { no_of_edges += VECTOR(*outseq)[i]; } } IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); IGRAPH_CHECK(igraph_psumtree_init(&sumtree, no_of_nodes)); IGRAPH_FINALLY(igraph_psumtree_destroy, &sumtree); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); RNG_BEGIN(); /* first node */ IGRAPH_CHECK(igraph_psumtree_update(&sumtree, 0, zero_deg_appeal * (1 + zero_age_appeal))); /* and the rest */ for (i = 1; i < no_of_nodes; i++) { igraph_real_t sum; long int to; IGRAPH_ALLOW_INTERRUPTION(); if (outseq != 0 && igraph_vector_size(outseq) != 0) { no_of_neighbors = (long int) VECTOR(*outseq)[i]; } sum = igraph_psumtree_sum(&sumtree); for (j = 0; j < no_of_neighbors; j++) { igraph_psumtree_search(&sumtree, &to, RNG_UNIF(0, sum)); VECTOR(degree)[to]++; VECTOR(edges)[edgeptr++] = i; VECTOR(edges)[edgeptr++] = to; } /* update probabilities */ for (j = 0; j < no_of_neighbors; j++) { long int n = (long int) VECTOR(edges)[edgeptr - 2 * j - 1]; long int age = (i - n) / binwidth; IGRAPH_CHECK(igraph_psumtree_update( &sumtree, n, (deg_coef * pow(VECTOR(degree)[n], pa_exp) + zero_deg_appeal) * (age_coef * pow(age + 1, aging_exp) + zero_age_appeal) )); } if (outpref) { VECTOR(degree)[i] += no_of_neighbors; IGRAPH_CHECK(igraph_psumtree_update( &sumtree, i, (zero_age_appeal + 1) * (deg_coef * pow(VECTOR(degree)[i], pa_exp) + zero_deg_appeal) )); } else { IGRAPH_CHECK(igraph_psumtree_update( &sumtree, i, (1 + zero_age_appeal) * zero_deg_appeal )); } /* aging */ for (k = 1; binwidth * k <= i; k++) { long int shnode = i - binwidth * k; long int deg = (long int) VECTOR(degree)[shnode]; long int age = (i - shnode) / binwidth; /* igraph_real_t old=igraph_psumtree_get(&sumtree, shnode); */ IGRAPH_CHECK(igraph_psumtree_update( &sumtree, shnode, (deg_coef * pow(deg, pa_exp) + zero_deg_appeal) * (age_coef * pow(age + 2, aging_exp) + zero_age_appeal) )); } } RNG_END(); igraph_vector_destroy(°ree); igraph_psumtree_destroy(&sumtree); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/games/recent_degree.c0000644000176200001440000003417314447675374020154 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_dqueue.h" #include "igraph_psumtree.h" #include "igraph_random.h" #include "igraph_interface.h" /** * \function igraph_recent_degree_game * \brief Stochastic graph generator based on the number of incident edges a node has gained recently. * * \param graph Pointer to an uninitialized graph object. * \param nodes The number of vertices in the graph, this is the same as * the number of time steps. * \param power The exponent, the probability that a node gains a * new edge is proportional to the number of edges it has * gained recently (in the last \p window time steps) to \p * power. * \param time_window Integer constant, the size of the time window to use * to count the number of recent edges. * \param m Integer constant, the number of edges to add per time * step if the \p outseq parameter is a null pointer or a * zero-length vector. * \param outseq The number of edges to add in each time step. This * argument is ignored if it is a null pointer or a zero length * vector. In this case the constant \p m parameter is used. * \param outpref Logical constant, if true the edges originated by a * vertex also count as recent incident edges. * For most applications it is reasonable to set it to false. * \param zero_appeal Constant giving the attractiveness of the * vertices which haven't gained any edge recently. * \param directed Logical constant, whether to generate a directed * graph. * \return Error code. * * Time complexity: O(|V|*log(|V|)+|E|), |V| is the number of * vertices, |E| is the number of edges in the graph. * */ int igraph_recent_degree_game(igraph_t *graph, igraph_integer_t nodes, igraph_real_t power, igraph_integer_t time_window, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t zero_appeal, igraph_bool_t directed) { long int no_of_nodes = nodes; long int no_of_neighbors = 0; long int no_of_edges; igraph_vector_t edges; long int i, j; igraph_psumtree_t sumtree; long int edgeptr = 0; igraph_vector_t degree; igraph_dqueue_t history; igraph_bool_t have_outseq = outseq && igraph_vector_size(outseq) > 0; if (no_of_nodes < 0) { IGRAPH_ERRORF("Number of vertices cannot be negative, got %ld.", IGRAPH_EINVAL, no_of_nodes); } if (have_outseq && igraph_vector_size(outseq) != no_of_nodes) { IGRAPH_ERRORF("Out-degree sequence is specified, but its length (%ld) does not equal the number of nodes (%ld).", IGRAPH_EINVAL, (long) igraph_vector_size(outseq), no_of_nodes); } if (!have_outseq && m < 0) { IGRAPH_ERRORF("Numer of edges per step cannot be negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, m); } if (time_window < 0) { IGRAPH_ERRORF("Time window cannot be negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, time_window); } if (zero_appeal < 0) { IGRAPH_ERRORF("The zero appeal cannot be negative, got %g.", IGRAPH_EINVAL, zero_appeal); } if (nodes == 0) { igraph_empty(graph, 0, directed); return IGRAPH_SUCCESS; } if (!have_outseq) { no_of_neighbors = m; no_of_edges = (no_of_nodes - 1) * no_of_neighbors; } else { long int outseq_len = igraph_vector_size(outseq); no_of_edges = 0; for (i = 1; i < outseq_len; i++) { no_of_edges += VECTOR(*outseq)[i]; } } IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); IGRAPH_CHECK(igraph_psumtree_init(&sumtree, no_of_nodes)); IGRAPH_FINALLY(igraph_psumtree_destroy, &sumtree); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); IGRAPH_CHECK(igraph_dqueue_init(&history, 1.5 * time_window * no_of_edges / no_of_nodes + 10)); IGRAPH_FINALLY(igraph_dqueue_destroy, &history); RNG_BEGIN(); /* first node */ IGRAPH_CHECK(igraph_psumtree_update(&sumtree, 0, zero_appeal)); igraph_dqueue_push(&history, -1); /* and the rest */ for (i = 1; i < no_of_nodes; i++) { igraph_real_t sum; long int to; if (have_outseq) { no_of_neighbors = (long int) VECTOR(*outseq)[i]; } if (i >= time_window) { while ((j = (long int) igraph_dqueue_pop(&history)) != -1) { VECTOR(degree)[j] -= 1; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, j, pow(VECTOR(degree)[j], power) + zero_appeal)); } } sum = igraph_psumtree_sum(&sumtree); for (j = 0; j < no_of_neighbors; j++) { igraph_psumtree_search(&sumtree, &to, RNG_UNIF(0, sum)); VECTOR(degree)[to]++; VECTOR(edges)[edgeptr++] = i; VECTOR(edges)[edgeptr++] = to; igraph_dqueue_push(&history, to); } igraph_dqueue_push(&history, -1); /* update probabilities */ for (j = 0; j < no_of_neighbors; j++) { long int nn = (long int) VECTOR(edges)[edgeptr - 2 * j - 1]; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, nn, pow(VECTOR(degree)[nn], power) + zero_appeal)); } if (outpref) { VECTOR(degree)[i] += no_of_neighbors; IGRAPH_CHECK(igraph_psumtree_update(&sumtree, i, pow(VECTOR(degree)[i], power) + zero_appeal)); } else { IGRAPH_CHECK(igraph_psumtree_update(&sumtree, i, zero_appeal)); } } RNG_END(); igraph_dqueue_destroy(&history); igraph_psumtree_destroy(&sumtree); igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(3); IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_recent_degree_aging_game * \brief Preferential attachment based on the number of edges gained recently, with aging of vertices. * * * This game is very similar to \ref igraph_barabasi_aging_game(), * except that instead of the total number of incident edges the * number of edges gained in the last \p time_window time steps are * counted. * * The degree dependent part of the attractiveness is * given by k to the power of \p pa_exp plus \p zero_appeal; the age * dependent part is l to the power to \p aging_exp. * k is the number of edges gained in the last \p time_window time * steps, l is the age of the vertex. * \param graph Pointer to an uninitialized graph object. * \param nodes The number of vertices in the graph. * \param m The number of edges to add in each time step. If the \p * outseq argument is not a null vector or a zero-length vector * then it is ignored. * \param outseq Vector giving the number of edges to add in each time * step. If it is a null pointer or a zero-length vector then * it is ignored and the \p m argument is used. * \param outpref Logical constant, if true the edges initiated by a * vertex are also counted. Normally it is false. * \param pa_exp The exponent for the preferential attachment. * \param aging_exp The exponent for the aging, normally it is * negative: old vertices gain edges with less probability. * \param aging_bins Integer constant, the number of age bins to use. * \param time_window The time window to use to count the number of * incident edges for the vertices. * \param zero_appeal The degree dependent part of the attractiveness * for zero degree vertices. * \param directed Logical constant, whether to create a directed * graph. * \return Error code. * * Time complexity: O((|V|+|V|/aging_bins)*log(|V|)+|E|). |V| is the number * of vertices, |E| the number of edges. */ int igraph_recent_degree_aging_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t m, const igraph_vector_t *outseq, igraph_bool_t outpref, igraph_real_t pa_exp, igraph_real_t aging_exp, igraph_integer_t aging_bins, igraph_integer_t time_window, igraph_real_t zero_appeal, igraph_bool_t directed) { long int no_of_nodes = nodes; long int no_of_neighbors; long int binwidth; long int no_of_edges; igraph_vector_t edges; long int i, j, k; igraph_psumtree_t sumtree; long int edgeptr = 0; igraph_vector_t degree; igraph_dqueue_t history; igraph_bool_t have_outseq = outseq && igraph_vector_size(outseq) > 0; if (no_of_nodes == 0) { igraph_empty(graph, 0, directed); return IGRAPH_SUCCESS; } if (no_of_nodes < 0) { IGRAPH_ERRORF("Number of nodes should not be negative, got %ld.", IGRAPH_EINVAL, no_of_nodes); } if (have_outseq && igraph_vector_size(outseq) != no_of_nodes) { IGRAPH_ERRORF("Out-degree sequence is specified, but its length (%ld) does not equal the number of nodes (%ld).", IGRAPH_EINVAL, (long) igraph_vector_size(outseq), no_of_nodes); } if (!have_outseq && m < 0) { IGRAPH_ERRORF("Numer of edges per step cannot be negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, m); } if (aging_bins <= 0) { IGRAPH_ERRORF("Aging bins should be positive, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, aging_bins); } if (time_window < 0) { IGRAPH_ERRORF("Time window cannot be negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, time_window); } if (zero_appeal < 0) { IGRAPH_ERRORF("The zero appeal cannot be negative, got %g.", IGRAPH_EINVAL, zero_appeal); } if (!have_outseq) { no_of_neighbors = m; no_of_edges = (no_of_nodes - 1) * no_of_neighbors; } else { long int outseq_len = igraph_vector_size(outseq); no_of_edges = 0; for (i = 1; i < outseq_len; i++) { no_of_edges += VECTOR(*outseq)[i]; } } binwidth = nodes / aging_bins + 1; IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); IGRAPH_CHECK(igraph_psumtree_init(&sumtree, no_of_nodes)); IGRAPH_FINALLY(igraph_psumtree_destroy, &sumtree); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); IGRAPH_CHECK(igraph_dqueue_init(&history, 1.5 * time_window * no_of_edges / no_of_nodes + 10)); IGRAPH_FINALLY(igraph_dqueue_destroy, &history); RNG_BEGIN(); /* first node */ IGRAPH_CHECK(igraph_psumtree_update(&sumtree, 0, zero_appeal)); igraph_dqueue_push(&history, -1); /* and the rest */ for (i = 1; i < no_of_nodes; i++) { igraph_real_t sum; long int to; if (have_outseq) { no_of_neighbors = (long int) VECTOR(*outseq)[i]; } if (i >= time_window) { while ((j = (long int) igraph_dqueue_pop(&history)) != -1) { long int age = (i - j) / binwidth; VECTOR(degree)[j] -= 1; IGRAPH_CHECK(igraph_psumtree_update( &sumtree, j, (pow(VECTOR(degree)[j], pa_exp) + zero_appeal) * pow(age + 1, aging_exp) )); } } sum = igraph_psumtree_sum(&sumtree); for (j = 0; j < no_of_neighbors; j++) { igraph_psumtree_search(&sumtree, &to, RNG_UNIF(0, sum)); VECTOR(degree)[to]++; VECTOR(edges)[edgeptr++] = i; VECTOR(edges)[edgeptr++] = to; igraph_dqueue_push(&history, to); } igraph_dqueue_push(&history, -1); /* update probabilities */ for (j = 0; j < no_of_neighbors; j++) { long int n = (long int) VECTOR(edges)[edgeptr - 2 * j - 1]; long int age = (i - n) / binwidth; IGRAPH_CHECK(igraph_psumtree_update( &sumtree, n, (pow(VECTOR(degree)[n], pa_exp) + zero_appeal) * pow(age + 1, aging_exp) )); } if (outpref) { VECTOR(degree)[i] += no_of_neighbors; IGRAPH_CHECK(igraph_psumtree_update( &sumtree, i, pow(VECTOR(degree)[i], pa_exp) + zero_appeal )); } else { IGRAPH_CHECK(igraph_psumtree_update(&sumtree, i, zero_appeal)); } /* aging */ for (k = 1; binwidth * k <= i; k++) { long int shnode = i - binwidth * k; long int deg = (long int) VECTOR(degree)[shnode]; long int age = (i - shnode) / binwidth; IGRAPH_CHECK(igraph_psumtree_update( &sumtree, shnode, (pow(deg, pa_exp) + zero_appeal) * pow(age + 2, aging_exp) )); } } RNG_END(); igraph_dqueue_destroy(&history); igraph_vector_destroy(°ree); igraph_psumtree_destroy(&sumtree); IGRAPH_FINALLY_CLEAN(3); IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/games/forestfire.c0000644000176200001440000002326614447675374017532 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_memory.h" #include "igraph_random.h" #include "igraph_progress.h" #include "igraph_interface.h" #include "igraph_constructors.h" #include "igraph_dqueue.h" #include "core/interruption.h" typedef struct igraph_i_forest_fire_data_t { igraph_vector_t *inneis; igraph_vector_t *outneis; long int no_of_nodes; } igraph_i_forest_fire_data_t; static void igraph_i_forest_fire_free(igraph_i_forest_fire_data_t *data) { long int i; for (i = 0; i < data->no_of_nodes; i++) { igraph_vector_destroy(data->inneis + i); igraph_vector_destroy(data->outneis + i); } } /** * \function igraph_forest_fire_game * \brief Generates a network according to the \quote forest fire game \endquote. * * The forest fire model intends to reproduce the following network * characteristics, observed in real networks: * \ilist * \ili Heavy-tailed in-degree distribution. * \ili Heavy-tailed out-degree distribution. * \ili Communities. * \ili Densification power-law. The network is densifying in time, * according to a power-law rule. * \ili Shrinking diameter. The diameter of the network decreases in * time. * \endilist * * * The network is generated in the following way. One vertex is added at * a time. This vertex connects to (cites) ambs vertices already * present in the network, chosen uniformly random. Now, for each cited * vertex v we do the following procedure: * \olist * \oli We generate two random numbers, x and y, that are * geometrically distributed with means p/(1-p) and * rp(1-rp). (p is \p fw_prob, r is * \p bw_factor.) The new vertex cites x outgoing neighbors * and y incoming neighbors of v, from those which are * not yet cited by the new vertex. If there are less than x or * y such vertices available then we cite all of them. * \oli The same procedure is applied to all the newly cited * vertices. * \endolist * * See also: * Jure Leskovec, Jon Kleinberg and Christos Faloutsos. Graphs over time: * densification laws, shrinking diameters and possible explanations. * \emb KDD '05: Proceeding of the eleventh ACM SIGKDD international * conference on Knowledge discovery in data mining \eme, 177--187, 2005. * * Note however, that the version of the model in the published paper is incorrect * in the sense that it cannot generate the kind of graphs the authors * claim. A corrected version is available from * http://cs.stanford.edu/people/jure/pubs/powergrowth-tkdd.pdf , our * implementation is based on this. * * \param graph Pointer to an uninitialized graph object. * \param nodes The number of vertices in the graph. * \param fw_prob The forward burning probability. * \param bw_factor The backward burning ratio. The backward burning probability is calculated as bw.factor*fw.prob. * \param pambs The number of ambassador vertices. * \param directed Whether to create a directed graph. * \return Error code. * * Time complexity: TODO. */ int igraph_forest_fire_game(igraph_t *graph, igraph_integer_t nodes, igraph_real_t fw_prob, igraph_real_t bw_factor, igraph_integer_t pambs, igraph_bool_t directed) { igraph_vector_long_t visited; long int no_of_nodes = nodes, actnode, i; igraph_vector_t edges; igraph_vector_t *inneis, *outneis; igraph_i_forest_fire_data_t data; igraph_dqueue_t neiq; long int ambs = pambs; igraph_real_t param_geom_out = 1 - fw_prob; igraph_real_t param_geom_in = 1 - fw_prob * bw_factor; if (fw_prob < 0 || fw_prob >= 1) { IGRAPH_ERROR("Forest fire model: 'fw_prob' must satisfy 0 <= fw_prob < 1.", IGRAPH_EINVAL); } if (bw_factor * fw_prob < 0 || bw_factor * fw_prob >= 1) { IGRAPH_ERROR("Forest fire model: 'bw_factor' must satisfy 0 <= bw_factor * fw_prob < 1.", IGRAPH_EINVAL); } if (ambs < 0) { IGRAPH_ERROR("Forest fire model: Number of ambassadors must not be negative.", IGRAPH_EINVAL); } if (ambs == 0) { IGRAPH_CHECK(igraph_empty(graph, nodes, directed)); return 0; } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); inneis = IGRAPH_CALLOC(no_of_nodes, igraph_vector_t); if (!inneis) { IGRAPH_ERROR("Cannot run forest fire model.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, inneis); outneis = IGRAPH_CALLOC(no_of_nodes, igraph_vector_t); if (!outneis) { IGRAPH_ERROR("Cannot run forest fire model.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, outneis); data.inneis = inneis; data.outneis = outneis; data.no_of_nodes = no_of_nodes; IGRAPH_FINALLY(igraph_i_forest_fire_free, &data); for (i = 0; i < no_of_nodes; i++) { IGRAPH_CHECK(igraph_vector_init(inneis + i, 0)); IGRAPH_CHECK(igraph_vector_init(outneis + i, 0)); } IGRAPH_CHECK(igraph_vector_long_init(&visited, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &visited); IGRAPH_DQUEUE_INIT_FINALLY(&neiq, 10); RNG_BEGIN(); #define ADD_EDGE_TO(nei) \ if (VECTOR(visited)[(nei)] != actnode+1) { \ VECTOR(visited)[(nei)] = actnode+1; \ IGRAPH_CHECK(igraph_dqueue_push(&neiq, nei)); \ IGRAPH_CHECK(igraph_vector_push_back(&edges, actnode)); \ IGRAPH_CHECK(igraph_vector_push_back(&edges, nei)); \ IGRAPH_CHECK(igraph_vector_push_back(outneis+actnode, nei)); \ IGRAPH_CHECK(igraph_vector_push_back(inneis+nei, actnode)); \ } IGRAPH_PROGRESS("Forest fire: ", 0.0, NULL); for (actnode = 1; actnode < no_of_nodes; actnode++) { IGRAPH_PROGRESS("Forest fire: ", 100.0 * actnode / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); /* We don't want to visit the current vertex */ VECTOR(visited)[actnode] = actnode + 1; /* Choose ambassador(s) */ for (i = 0; i < ambs; i++) { long int a = RNG_INTEGER(0, actnode - 1); ADD_EDGE_TO(a); } while (!igraph_dqueue_empty(&neiq)) { long int actamb = (long int) igraph_dqueue_pop(&neiq); igraph_vector_t *outv = outneis + actamb; igraph_vector_t *inv = inneis + actamb; long int no_in = igraph_vector_size(inv); long int no_out = igraph_vector_size(outv); long int neis_out = (long int) RNG_GEOM(param_geom_out); long int neis_in = (long int) RNG_GEOM(param_geom_in); /* outgoing neighbors */ if (neis_out >= no_out) { for (i = 0; i < no_out; i++) { long int nei = (long int) VECTOR(*outv)[i]; ADD_EDGE_TO(nei); } } else { long int oleft = no_out; for (i = 0; i < neis_out && oleft > 0; ) { long int which = RNG_INTEGER(0, oleft - 1); long int nei = (long int) VECTOR(*outv)[which]; VECTOR(*outv)[which] = VECTOR(*outv)[oleft - 1]; VECTOR(*outv)[oleft - 1] = nei; if (VECTOR(visited)[nei] != actnode + 1) { ADD_EDGE_TO(nei); i++; } oleft--; } } /* incoming neighbors */ if (neis_in >= no_in) { for (i = 0; i < no_in; i++) { long int nei = (long int) VECTOR(*inv)[i]; ADD_EDGE_TO(nei); } } else { long int ileft = no_in; for (i = 0; i < neis_in && ileft > 0; ) { long int which = RNG_INTEGER(0, ileft - 1); long int nei = (long int) VECTOR(*inv)[which]; VECTOR(*inv)[which] = VECTOR(*inv)[ileft - 1]; VECTOR(*inv)[ileft - 1] = nei; if (VECTOR(visited)[nei] != actnode + 1) { ADD_EDGE_TO(nei); i++; } ileft--; } } } /* while neiq not empty */ } /* actnode < no_of_nodes */ #undef ADD_EDGE_TO RNG_END(); IGRAPH_PROGRESS("Forest fire: ", 100.0, NULL); igraph_dqueue_destroy(&neiq); igraph_vector_long_destroy(&visited); igraph_i_forest_fire_free(&data); igraph_free(outneis); igraph_free(inneis); IGRAPH_FINALLY_CLEAN(5); IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/games/static_fitness.c0000644000176200001440000004162014447675374020376 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_adjlist.h" #include "igraph_conversion.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "igraph_random.h" #include "core/interruption.h" /** * \ingroup generators * \function igraph_static_fitness_game * \brief Non-growing random graph with edge probabilities proportional to node fitness scores. * * This game generates a directed or undirected random graph where the * probability of an edge between vertices i and j depends on the fitness * scores of the two vertices involved. For undirected graphs, each vertex * has a single fitness score. For directed graphs, each vertex has an out- * and an in-fitness, and the probability of an edge from i to j depends on * the out-fitness of vertex i and the in-fitness of vertex j. * * * The generation process goes as follows. We start from N disconnected nodes * (where N is given by the length of the fitness vector). Then we randomly * select two vertices i and j, with probabilities proportional to their * fitnesses. (When the generated graph is directed, i is selected according to * the out-fitnesses and j is selected according to the in-fitnesses). If the * vertices are not connected yet (or if multiple edges are allowed), we * connect them; otherwise we select a new pair. This is repeated until the * desired number of links are created. * * * It can be shown that the \em expected degree of each vertex will be * proportional to its fitness, although the actual, observed degree will not * be. If you need to generate a graph with an exact degree sequence, consider * \ref igraph_degree_sequence_game instead. * * * This model is commonly used to generate static scale-free networks. To * achieve this, you have to draw the fitness scores from the desired power-law * distribution. Alternatively, you may use \ref igraph_static_power_law_game * which generates the fitnesses for you with a given exponent. * * * Reference: Goh K-I, Kahng B, Kim D: Universal behaviour of load distribution * in scale-free networks. Phys Rev Lett 87(27):278701, 2001. * * \param graph Pointer to an uninitialized graph object. * \param fitness_out A numeric vector containing the fitness of each vertex. * For directed graphs, this specifies the out-fitness * of each vertex. * \param fitness_in If \c NULL, the generated graph will be undirected. * If not \c NULL, this argument specifies the in-fitness * of each vertex. * \param no_of_edges The number of edges in the generated graph. * \param loops Whether to allow loop edges in the generated graph. * \param multiple Whether to allow multiple edges in the generated graph. * * \return Error code: * \c IGRAPH_EINVAL: invalid parameter * \c IGRAPH_ENOMEM: there is not enough * memory for the operation. * * Time complexity: O(|V| + |E| log |E|). */ int igraph_static_fitness_game(igraph_t *graph, igraph_integer_t no_of_edges, const igraph_vector_t *fitness_out, const igraph_vector_t *fitness_in, igraph_bool_t loops, igraph_bool_t multiple) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; igraph_integer_t no_of_nodes; igraph_integer_t outnodes, innodes, nodes; igraph_vector_t cum_fitness_in, cum_fitness_out; igraph_vector_t *p_cum_fitness_in, *p_cum_fitness_out; igraph_real_t x, max_in, max_out; igraph_real_t max_no_of_edges; igraph_bool_t is_directed = (fitness_in != 0); float num_steps; igraph_integer_t step_counter = 0; long int i, from, to, pos; if (fitness_out == 0) { IGRAPH_ERROR("fitness_out must not be null.", IGRAPH_EINVAL); } if (no_of_edges < 0) { IGRAPH_ERRORF("Number of edges cannot be negative, got %" IGRAPH_PRId ".", IGRAPH_EINVAL, no_of_edges); } no_of_nodes = (igraph_integer_t) igraph_vector_size(fitness_out); if (no_of_nodes == 0) { IGRAPH_CHECK(igraph_empty(graph, 0, is_directed)); return IGRAPH_SUCCESS; } if (is_directed && igraph_vector_size(fitness_in) != no_of_nodes) { IGRAPH_ERROR("fitness_in must have the same size as fitness_out.", IGRAPH_EINVAL); } /* Sanity checks for the fitnesses */ if (igraph_vector_min(fitness_out) < 0) { IGRAPH_ERROR("Fitness scores must be non-negative.", IGRAPH_EINVAL); } if (fitness_in != 0 && igraph_vector_min(fitness_in) < 0) { IGRAPH_ERROR("Fitness scores must be non-negative.", IGRAPH_EINVAL); } /* Avoid getting into an infinite loop when too many edges are requested */ if (!multiple) { if (is_directed) { outnodes = innodes = nodes = 0; for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*fitness_out)[i] != 0) { outnodes++; } if (VECTOR(*fitness_in)[i] != 0) { innodes++; } if (VECTOR(*fitness_out)[i] != 0 && VECTOR(*fitness_in)[i] != 0) { nodes++; } } max_no_of_edges = ((igraph_real_t) outnodes) * innodes - (loops ? 0 : nodes); } else { nodes = 0; for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*fitness_out)[i] != 0) { nodes++; } } max_no_of_edges = loops ? nodes * ((igraph_real_t)nodes + 1) / 2 : nodes * ((igraph_real_t)nodes - 1) / 2; } if (no_of_edges > max_no_of_edges) { IGRAPH_ERROR("Too many edges requested.", IGRAPH_EINVAL); } } /* Calculate the cumulative fitness scores */ IGRAPH_VECTOR_INIT_FINALLY(&cum_fitness_out, no_of_nodes); IGRAPH_CHECK(igraph_vector_cumsum(&cum_fitness_out, fitness_out)); max_out = igraph_vector_tail(&cum_fitness_out); p_cum_fitness_out = &cum_fitness_out; if (is_directed) { IGRAPH_VECTOR_INIT_FINALLY(&cum_fitness_in, no_of_nodes); IGRAPH_CHECK(igraph_vector_cumsum(&cum_fitness_in, fitness_in)); max_in = igraph_vector_tail(&cum_fitness_in); p_cum_fitness_in = &cum_fitness_in; } else { max_in = max_out; p_cum_fitness_in = &cum_fitness_out; } RNG_BEGIN(); num_steps = no_of_edges; if (multiple) { /* Generating when multiple edges are allowed */ IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, 2 * no_of_edges)); while (no_of_edges > 0) { /* Report progress after every 10000 edges */ if ((step_counter++) % 10000 == 0) { IGRAPH_PROGRESS("Static fitness game", 100.0 * (1 - no_of_edges / num_steps), NULL); IGRAPH_ALLOW_INTERRUPTION(); } x = RNG_UNIF(0, max_out); igraph_vector_binsearch(p_cum_fitness_out, x, &from); x = RNG_UNIF(0, max_in); igraph_vector_binsearch(p_cum_fitness_in, x, &to); /* Skip if loop edge and loops = false */ if (!loops && from == to) { continue; } igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); no_of_edges--; } /* Create the graph */ IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, is_directed)); /* Clear the edge list */ igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); } else { /* Multiple edges are disallowed */ igraph_adjlist_t al; igraph_vector_int_t* neis; IGRAPH_CHECK(igraph_adjlist_init_empty(&al, no_of_nodes)); IGRAPH_FINALLY(igraph_adjlist_destroy, &al); while (no_of_edges > 0) { /* Report progress after every 10000 edges */ if ((step_counter++) % 10000 == 0) { IGRAPH_PROGRESS("Static fitness game", 100.0 * (1 - no_of_edges / num_steps), NULL); IGRAPH_ALLOW_INTERRUPTION(); } x = RNG_UNIF(0, max_out); igraph_vector_binsearch(p_cum_fitness_out, x, &from); x = RNG_UNIF(0, max_in); igraph_vector_binsearch(p_cum_fitness_in, x, &to); /* Skip if loop edge and loops = false */ if (!loops && from == to) { continue; } /* For undirected graphs, ensure that from < to */ if (!is_directed && from > to) { pos = from; from = to; to = pos; } /* Is there already an edge? If so, try again */ neis = igraph_adjlist_get(&al, from); if (igraph_vector_int_binsearch(neis, to, &pos)) { continue; } /* Insert the edge */ IGRAPH_CHECK(igraph_vector_int_insert(neis, pos, to)); no_of_edges--; } /* Create the graph. We cannot use IGRAPH_ALL here for undirected graphs * because we did not add edges in both directions in the adjacency list. * We will use igraph_to_undirected in an extra step. */ IGRAPH_CHECK(igraph_adjlist(graph, &al, IGRAPH_OUT, 1)); if (!is_directed) { IGRAPH_CHECK(igraph_to_undirected(graph, IGRAPH_TO_UNDIRECTED_EACH, 0)); } /* Clear the adjacency list */ igraph_adjlist_destroy(&al); IGRAPH_FINALLY_CLEAN(1); } RNG_END(); IGRAPH_PROGRESS("Static fitness game", 100.0, NULL); /* Cleanup before we create the graph */ if (is_directed) { igraph_vector_destroy(&cum_fitness_in); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&cum_fitness_out); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \ingroup generators * \function igraph_static_power_law_game * \brief Generates a non-growing random graph with expected power-law degree distributions. * * This game generates a directed or undirected random graph where the * degrees of vertices follow power-law distributions with prescribed * exponents. For directed graphs, the exponents of the in- and out-degree * distributions may be specified separately. * * * The game simply uses \ref igraph_static_fitness_game with appropriately * constructed fitness vectors. In particular, the fitness of vertex i * is i-alpha, where alpha = 1/(gamma-1) * and gamma is the exponent given in the arguments. * * * To remove correlations between in- and out-degrees in case of directed * graphs, the in-fitness vector will be shuffled after it has been set up * and before \ref igraph_static_fitness_game is called. * * * Note that significant finite size effects may be observed for exponents * smaller than 3 in the original formulation of the game. This function * provides an argument that lets you remove the finite size effects by * assuming that the fitness of vertex i is * (i+i0-1)-alpha, * where i0 is a constant chosen appropriately to ensure that the maximum * degree is less than the square root of the number of edges times the * average degree; see the paper of Chung and Lu, and Cho et al for more * details. * * * References: * * * Goh K-I, Kahng B, Kim D: Universal behaviour of load distribution * in scale-free networks. Phys Rev Lett 87(27):278701, 2001. * * * Chung F and Lu L: Connected components in a random graph with given * degree sequences. Annals of Combinatorics 6, 125-145, 2002. * * * Cho YS, Kim JS, Park J, Kahng B, Kim D: Percolation transitions in * scale-free networks under the Achlioptas process. Phys Rev Lett * 103:135702, 2009. * * \param graph Pointer to an uninitialized graph object. * \param no_of_nodes The number of nodes in the generated graph. * \param no_of_edges The number of edges in the generated graph. * \param exponent_out The power law exponent of the degree distribution. * For directed graphs, this specifies the exponent of the * out-degree distribution. It must be greater than or * equal to 2. If you pass \c IGRAPH_INFINITY here, you * will get back an Erdos-Renyi random network. * \param exponent_in If negative, the generated graph will be undirected. * If greater than or equal to 2, this argument specifies * the exponent of the in-degree distribution. If * non-negative but less than 2, an error will be * generated. * \param loops Whether to allow loop edges in the generated graph. * \param multiple Whether to allow multiple edges in the generated graph. * \param finite_size_correction Whether to use the proposed finite size * correction of Cho et al. * * \return Error code: * \c IGRAPH_EINVAL: invalid parameter * \c IGRAPH_ENOMEM: there is not enough * memory for the operation. * * Time complexity: O(|V| + |E| log |E|). */ int igraph_static_power_law_game(igraph_t *graph, igraph_integer_t no_of_nodes, igraph_integer_t no_of_edges, igraph_real_t exponent_out, igraph_real_t exponent_in, igraph_bool_t loops, igraph_bool_t multiple, igraph_bool_t finite_size_correction) { igraph_vector_t fitness_out, fitness_in; igraph_real_t alpha_out = 0.0, alpha_in = 0.0; long int i; igraph_real_t j; if (no_of_nodes < 0) { IGRAPH_ERRORF("Number of nodes cannot be negative, got %" IGRAPH_PRId".", IGRAPH_EINVAL, no_of_nodes); } /* Calculate alpha_out */ if (exponent_out < 2) { IGRAPH_ERRORF("Out-degree exponent must be >= 2, got %g.", IGRAPH_EINVAL, exponent_out); } else if (igraph_finite(exponent_out)) { alpha_out = -1.0 / (exponent_out - 1); } else { alpha_out = 0.0; } /* Construct the out-fitnesses */ IGRAPH_VECTOR_INIT_FINALLY(&fitness_out, no_of_nodes); j = no_of_nodes; if (finite_size_correction && alpha_out < -0.5) { /* See the Cho et al paper, first page first column + footnote 7 */ j += pow(no_of_nodes, 1 + 0.5 / alpha_out) * pow(10 * sqrt(2) * (1 + alpha_out), -1.0 / alpha_out) - 1; } if (j < no_of_nodes) { j = no_of_nodes; } for (i = 0; i < no_of_nodes; i++, j--) { VECTOR(fitness_out)[i] = pow(j, alpha_out); } if (exponent_in >= 0) { if (exponent_in < 2) { IGRAPH_ERRORF("For directed graphs the in-degree exponent must be >= 2, got %g.", IGRAPH_EINVAL, exponent_in); } else if (igraph_finite(exponent_in)) { alpha_in = -1.0 / (exponent_in - 1); } else { alpha_in = 0.0; } IGRAPH_VECTOR_INIT_FINALLY(&fitness_in, no_of_nodes); j = no_of_nodes; if (finite_size_correction && alpha_in < -0.5) { /* See the Cho et al paper, first page first column + footnote 7 */ j += pow(no_of_nodes, 1 + 0.5 / alpha_in) * pow(10 * sqrt(2) * (1 + alpha_in), -1.0 / alpha_in) - 1; } if (j < no_of_nodes) { j = no_of_nodes; } for (i = 0; i < no_of_nodes; i++, j--) { VECTOR(fitness_in)[i] = pow(j, alpha_in); } IGRAPH_CHECK(igraph_vector_shuffle(&fitness_in)); IGRAPH_CHECK(igraph_static_fitness_game(graph, no_of_edges, &fitness_out, &fitness_in, loops, multiple)); igraph_vector_destroy(&fitness_in); IGRAPH_FINALLY_CLEAN(1); } else { IGRAPH_CHECK(igraph_static_fitness_game(graph, no_of_edges, &fitness_out, 0, loops, multiple)); } igraph_vector_destroy(&fitness_out); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/games/preference.c0000644000176200001440000006042114447675374017472 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_constructors.h" #include "igraph_memory.h" #include "igraph_random.h" #include "core/interruption.h" static void igraph_i_preference_game_free_vids_by_type(igraph_vector_ptr_t *vecs) { int i = 0, n; igraph_vector_t *v; n = (int) igraph_vector_ptr_size(vecs); for (i = 0; i < n; i++) { v = (igraph_vector_t*)VECTOR(*vecs)[i]; if (v) { igraph_vector_destroy(v); } } igraph_vector_ptr_destroy_all(vecs); } /** * \function igraph_preference_game * \brief Generates a graph with vertex types and connection preferences. * * * This is practically the nongrowing variant of * \ref igraph_establishment_game(). A given number of vertices are * generated. Every vertex is assigned to a vertex type according to * the given type probabilities. Finally, every * vertex pair is evaluated and an edge is created between them with a * probability depending on the types of the vertices involved. * * * In other words, this function generates a graph according to a * block-model. Vertices are divided into groups (or blocks), and * the probability the two vertices are connected depends on their * groups only. * * \param graph Pointer to an uninitialized graph. * \param nodes The number of vertices in the graph. * \param types The number of vertex types. * \param type_dist Vector giving the distribution of vertex types. If * \c NULL, all vertex types will have equal probability. See also the * \p fixed_sizes argument. * \param fixed_sizes Boolean. If true, then the number of vertices with a * given vertex type is fixed and the \p type_dist argument gives these * numbers for each vertex type. If true, and \p type_dist is \c NULL, * then the function tries to make vertex groups of the same size. If this * is not possible, then some groups will have an extra vertex. * \param pref_matrix Matrix giving the connection probabilities for * different vertex types. This should be symmetric if the requested * graph is undirected. * \param node_type_vec A vector where the individual generated vertex types * will be stored. If \c NULL, the vertex types won't be saved. * \param directed Logical, whether to generate a directed graph. If undirected * graphs are requested, only the lower left triangle of the preference * matrix is considered. * \param loops Logical, whether loop edges are allowed. * \return Error code. * * Added in version 0.3. * * Time complexity: O(|V|+|E|), the * number of vertices plus the number of edges in the graph. * * \sa \ref igraph_asymmetric_preference_game(), * \ref igraph_establishment_game(), \ref igraph_callaway_traits_game() */ int igraph_preference_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t types, const igraph_vector_t *type_dist, igraph_bool_t fixed_sizes, const igraph_matrix_t *pref_matrix, igraph_vector_t *node_type_vec, igraph_bool_t directed, igraph_bool_t loops) { long int i, j; igraph_vector_t edges, s; igraph_vector_t* nodetypes; igraph_vector_ptr_t vids_by_type; igraph_real_t maxcum, maxedges; if(nodes < 0){ IGRAPH_ERROR("The number of vertices must be non-negative.", IGRAPH_EINVAL); } if (types < 1) { IGRAPH_ERROR("The number of vertex types must be at least 1.", IGRAPH_EINVAL); } if (type_dist) { igraph_real_t lo; if (igraph_vector_size(type_dist) != types) { IGRAPH_ERROR("The vertex type distribution vector must agree in length with the number of types.", IGRAPH_EINVAL); } lo = igraph_vector_min(type_dist); if (lo < 0) { IGRAPH_ERROR("The vertex type distribution vector must not contain negative values.", IGRAPH_EINVAL); } if (igraph_is_nan(lo)) { IGRAPH_ERROR("The vertex type distribution vector must not contain NaN.", IGRAPH_EINVAL); } } if (igraph_matrix_nrow(pref_matrix) != types || igraph_matrix_ncol(pref_matrix) != types) { IGRAPH_ERROR("The preference matrix must be square and agree in dimensions with the number of types.", IGRAPH_EINVAL); } { igraph_real_t lo, hi; igraph_matrix_minmax(pref_matrix, &lo, &hi); if (lo < 0 || hi > 1) { IGRAPH_ERROR("The preference matrix must contain probabilities in [0, 1].", IGRAPH_EINVAL); } if (igraph_is_nan(lo) || igraph_is_nan(hi)) { IGRAPH_ERROR("The preference matrix must not contain NaN.", IGRAPH_EINVAL); } } if (! directed && ! igraph_matrix_is_symmetric(pref_matrix)) { IGRAPH_ERROR("The preference matrix must be symmetric when generating undirected graphs.", IGRAPH_EINVAL); } if (fixed_sizes && type_dist) { if (igraph_vector_sum(type_dist) != nodes) { IGRAPH_ERROR("Invalid group sizes, their sum must match the number of vertices.", IGRAPH_EINVAL); } } if (node_type_vec) { IGRAPH_CHECK(igraph_vector_resize(node_type_vec, nodes)); nodetypes = node_type_vec; } else { nodetypes = IGRAPH_CALLOC(1, igraph_vector_t); if (nodetypes == 0) { IGRAPH_ERROR("Insufficient memory for preference_game.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, nodetypes); IGRAPH_VECTOR_INIT_FINALLY(nodetypes, nodes); } IGRAPH_CHECK(igraph_vector_ptr_init(&vids_by_type, types)); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &vids_by_type); for (i = 0; i < types; i++) { VECTOR(vids_by_type)[i] = IGRAPH_CALLOC(1, igraph_vector_t); if (VECTOR(vids_by_type)[i] == 0) { IGRAPH_ERROR("Insufficient memory for preference_game.", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(VECTOR(vids_by_type)[i], 0)); } IGRAPH_FINALLY_CLEAN(1); /* removing igraph_vector_ptr_destroy_all */ IGRAPH_FINALLY(igraph_i_preference_game_free_vids_by_type, &vids_by_type); RNG_BEGIN(); if (!fixed_sizes) { igraph_vector_t cumdist; IGRAPH_VECTOR_INIT_FINALLY(&cumdist, types + 1); VECTOR(cumdist)[0] = 0; if (type_dist) { for (i = 0; i < types; i++) { VECTOR(cumdist)[i + 1] = VECTOR(cumdist)[i] + VECTOR(*type_dist)[i]; } } else { for (i = 0; i < types; i++) { VECTOR(cumdist)[i + 1] = i + 1; } } maxcum = igraph_vector_tail(&cumdist); for (i = 0; i < nodes; i++) { long int type1; igraph_real_t uni1 = RNG_UNIF(0, maxcum); igraph_vector_binsearch(&cumdist, uni1, &type1); VECTOR(*nodetypes)[i] = type1 - 1; IGRAPH_CHECK(igraph_vector_push_back( (igraph_vector_t*)VECTOR(vids_by_type)[type1 - 1], i)); } igraph_vector_destroy(&cumdist); IGRAPH_FINALLY_CLEAN(1); } else { long int an = 0; if (type_dist) { for (i = 0; i < types; i++) { long int no = (long int) VECTOR(*type_dist)[i]; igraph_vector_t *v = VECTOR(vids_by_type)[i]; for (j = 0; j < no && an < nodes; j++) { VECTOR(*nodetypes)[an] = i; IGRAPH_CHECK(igraph_vector_push_back(v, an)); an++; } } } else { long int fixno = (long int) ceil( (double)nodes / types); for (i = 0; i < types; i++) { igraph_vector_t *v = VECTOR(vids_by_type)[i]; for (j = 0; j < fixno && an < nodes; j++) { VECTOR(*nodetypes)[an++] = i; IGRAPH_CHECK(igraph_vector_push_back(v, an)); an++; } } } } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&s, 0); for (i = 0; i < types; i++) { for (j = 0; j < types; j++) { /* Generating the random subgraph between vertices of type i and j */ long int k, l; igraph_real_t p, last; igraph_vector_t *v1, *v2; long int v1_size, v2_size; IGRAPH_ALLOW_INTERRUPTION(); v1 = (igraph_vector_t*)VECTOR(vids_by_type)[i]; v2 = (igraph_vector_t*)VECTOR(vids_by_type)[j]; v1_size = igraph_vector_size(v1); v2_size = igraph_vector_size(v2); p = MATRIX(*pref_matrix, i, j); igraph_vector_clear(&s); if (i != j) { /* The two vertex sets are disjoint, this is the easier case */ if (i > j && !directed) { continue; } maxedges = v1_size * v2_size; } else { if (directed && loops) { maxedges = v1_size * v1_size; } else if (directed && !loops) { maxedges = v1_size * (v1_size - 1); } else if (!directed && loops) { maxedges = v1_size * (v1_size + 1) / 2; } else { maxedges = v1_size * (v1_size - 1) / 2; } } IGRAPH_CHECK(igraph_vector_reserve(&s, (long int) (maxedges * p * 1.1))); last = RNG_GEOM(p); while (last < maxedges) { IGRAPH_CHECK(igraph_vector_push_back(&s, last)); last += RNG_GEOM(p); last += 1; } l = igraph_vector_size(&s); IGRAPH_CHECK(igraph_vector_reserve(&edges, igraph_vector_size(&edges) + l * 2)); if (i != j) { /* Generating the subgraph between vertices of type i and j */ for (k = 0; k < l; k++) { long int to = (long int) floor(VECTOR(s)[k] / v1_size); long int from = (long int) (VECTOR(s)[k] - ((igraph_real_t)to) * v1_size); igraph_vector_push_back(&edges, VECTOR(*v1)[from]); igraph_vector_push_back(&edges, VECTOR(*v2)[to]); } } else { /* Generating the subgraph among vertices of type i */ if (directed && loops) { for (k = 0; k < l; k++) { long int to = (long int) floor(VECTOR(s)[k] / v1_size); long int from = (long int) (VECTOR(s)[k] - ((igraph_real_t)to) * v1_size); igraph_vector_push_back(&edges, VECTOR(*v1)[from]); igraph_vector_push_back(&edges, VECTOR(*v1)[to]); } } else if (directed && !loops) { for (k = 0; k < l; k++) { long int to = (long int) floor(VECTOR(s)[k] / v1_size); long int from = (long int) (VECTOR(s)[k] - ((igraph_real_t)to) * v1_size); if (from == to) { to = v1_size - 1; } igraph_vector_push_back(&edges, VECTOR(*v1)[from]); igraph_vector_push_back(&edges, VECTOR(*v1)[to]); } } else if (!directed && loops) { for (k = 0; k < l; k++) { long int to = (long int) floor((sqrt(8 * VECTOR(s)[k] + 1) - 1) / 2); long int from = (long int) (VECTOR(s)[k] - (((igraph_real_t)to) * (to + 1)) / 2); igraph_vector_push_back(&edges, VECTOR(*v1)[from]); igraph_vector_push_back(&edges, VECTOR(*v1)[to]); } } else { for (k = 0; k < l; k++) { long int to = (long int) floor((sqrt(8 * VECTOR(s)[k] + 1) + 1) / 2); long int from = (long int) (VECTOR(s)[k] - (((igraph_real_t)to) * (to - 1)) / 2); igraph_vector_push_back(&edges, VECTOR(*v1)[from]); igraph_vector_push_back(&edges, VECTOR(*v1)[to]); } } } } } RNG_END(); igraph_vector_destroy(&s); igraph_i_preference_game_free_vids_by_type(&vids_by_type); IGRAPH_FINALLY_CLEAN(2); if (node_type_vec == 0) { igraph_vector_destroy(nodetypes); IGRAPH_FREE(nodetypes); IGRAPH_FINALLY_CLEAN(2); } IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \function igraph_asymmetric_preference_game * \brief Generates a graph with asymmetric vertex types and connection preferences. * * * This is the asymmetric variant of \ref igraph_preference_game(). * A given number of vertices are generated. Every vertex is assigned to an * "outgoing" and an "incoming " vertex type according to the given joint * type probabilities. Finally, every vertex pair is evaluated and a * directed edge is created between them with a probability depending on the * "outgoing" type of the source vertex and the "incoming" type of the target * vertex. * * \param graph Pointer to an uninitialized graph. * \param nodes The number of vertices in the graph. * \param out_types The number of vertex out-types. * \param in_types The number of vertex in-types. * \param type_dist_matrix Matrix of size out_types * in_types, * giving the joint distribution of vertex types. * If \c NULL, incoming and outgoing vertex types are independent and uniformly * distributed. * \param pref_matrix Matrix of size out_types * in_types, * giving the connection probabilities for different vertex types. * \param node_type_out_vec A vector where the individual generated "outgoing" * vertex types will be stored. If \c NULL, the vertex types won't be saved. * \param node_type_in_vec A vector where the individual generated "incoming" * vertex types will be stored. If \c NULL, the vertex types won't be saved. * \param loops Logical, whether loop edges are allowed. * \return Error code. * * Added in version 0.3. * * Time complexity: O(|V|+|E|), the * number of vertices plus the number of edges in the graph. * * \sa \ref igraph_preference_game() */ int igraph_asymmetric_preference_game(igraph_t *graph, igraph_integer_t nodes, igraph_integer_t out_types, igraph_integer_t in_types, const igraph_matrix_t *type_dist_matrix, const igraph_matrix_t *pref_matrix, igraph_vector_t *node_type_out_vec, igraph_vector_t *node_type_in_vec, igraph_bool_t loops) { long int i, j, k; igraph_vector_t edges, cumdist, s, intersect; igraph_vector_t *nodetypes_in; igraph_vector_t *nodetypes_out; igraph_vector_ptr_t vids_by_intype, vids_by_outtype; igraph_real_t maxcum, maxedges; if(nodes < 0){ IGRAPH_ERROR("The number of vertices must not be negative.", IGRAPH_EINVAL); } if (in_types < 1) { IGRAPH_ERROR("The number of vertex in-types must be at least 1.", IGRAPH_EINVAL); } if (out_types < 1) { IGRAPH_ERROR("The number of vertex out-types must be at least 1.", IGRAPH_EINVAL); } if (type_dist_matrix) { igraph_real_t lo; if (igraph_matrix_nrow(type_dist_matrix) != out_types || igraph_matrix_ncol(type_dist_matrix) != in_types) { IGRAPH_ERROR("The type distribution matrix must have dimensions out_types * in_types.", IGRAPH_EINVAL); } lo = igraph_matrix_min(type_dist_matrix); if (lo < 0) { IGRAPH_ERROR("The type distribution matrix must not contain negative values.", IGRAPH_EINVAL); } if (igraph_is_nan(lo)) { IGRAPH_ERROR("The type distribution matrix must not contain NaN.", IGRAPH_EINVAL); } } if (igraph_matrix_nrow(pref_matrix) != out_types || igraph_matrix_ncol(pref_matrix) != in_types) { IGRAPH_ERROR("The preference matrix must have dimensions out_types * in_types.", IGRAPH_EINVAL); } { igraph_real_t lo, hi; igraph_matrix_minmax(pref_matrix, &lo, &hi); if (lo < 0 || hi > 1) { IGRAPH_ERROR("The preference matrix must contain probabilities in [0, 1].", IGRAPH_EINVAL); } if (igraph_is_nan(lo) || igraph_is_nan(hi)) { IGRAPH_ERROR("The preference matrix must not contain NaN.", IGRAPH_EINVAL); } } IGRAPH_VECTOR_INIT_FINALLY(&cumdist, in_types * out_types + 1); if (node_type_in_vec) { nodetypes_in = node_type_in_vec; IGRAPH_CHECK(igraph_vector_resize(nodetypes_in, nodes)); } else { nodetypes_in = IGRAPH_CALLOC(1, igraph_vector_t); if (nodetypes_in == 0) { IGRAPH_ERROR("Insufficient memory for asymmetric_preference_game.", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(nodetypes_in, nodes); } if (node_type_out_vec) { nodetypes_out = node_type_out_vec; IGRAPH_CHECK(igraph_vector_resize(nodetypes_out, nodes)); } else { nodetypes_out = IGRAPH_CALLOC(1, igraph_vector_t); if (nodetypes_out == 0) { IGRAPH_ERROR("Insufficient memory for asymmetric_preference_game.", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(nodetypes_out, nodes); } IGRAPH_CHECK(igraph_vector_ptr_init(&vids_by_intype, in_types)); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &vids_by_intype); IGRAPH_CHECK(igraph_vector_ptr_init(&vids_by_outtype, out_types)); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &vids_by_outtype); for (i = 0; i < in_types; i++) { VECTOR(vids_by_intype)[i] = IGRAPH_CALLOC(1, igraph_vector_t); if (! VECTOR(vids_by_intype)[i]) { IGRAPH_ERROR("Insufficient memory for asymmetric_preference_game.", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(VECTOR(vids_by_intype)[i], 0)); } for (i = 0; i < out_types; i++) { VECTOR(vids_by_outtype)[i] = IGRAPH_CALLOC(1, igraph_vector_t); if (! VECTOR(vids_by_outtype)[i]) { IGRAPH_ERROR("Insufficient memory for asymmetric_preference_game.", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(VECTOR(vids_by_outtype)[i], 0)); } IGRAPH_FINALLY_CLEAN(2); /* removing igraph_vector_ptr_destroy_all */ IGRAPH_FINALLY(igraph_i_preference_game_free_vids_by_type, &vids_by_intype); IGRAPH_FINALLY(igraph_i_preference_game_free_vids_by_type, &vids_by_outtype); VECTOR(cumdist)[0] = 0; if (type_dist_matrix) { for (i = 0, k = 0; i < out_types; i++) { for (j = 0; j < in_types; j++, k++) { VECTOR(cumdist)[k + 1] = VECTOR(cumdist)[k] + MATRIX(*type_dist_matrix, i, j); } } } else { for (i = 0; i < out_types * in_types; i++) { VECTOR(cumdist)[i + 1] = i + 1; } } maxcum = igraph_vector_tail(&cumdist); RNG_BEGIN(); for (i = 0; i < nodes; i++) { long int type1, type2; igraph_real_t uni1 = RNG_UNIF(0, maxcum); igraph_vector_binsearch(&cumdist, uni1, &type1); type2 = (type1 - 1) % (long int) out_types; type1 = (type1 - 1) / (long int) out_types; VECTOR(*nodetypes_in)[i] = type1; VECTOR(*nodetypes_out)[i] = type2; IGRAPH_CHECK(igraph_vector_push_back( (igraph_vector_t*)VECTOR(vids_by_intype)[type1], i)); IGRAPH_CHECK(igraph_vector_push_back( (igraph_vector_t*)VECTOR(vids_by_outtype)[type2], i)); } igraph_vector_destroy(&cumdist); IGRAPH_FINALLY_CLEAN(1); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&s, 0); IGRAPH_VECTOR_INIT_FINALLY(&intersect, 0); for (i = 0; i < out_types; i++) { for (j = 0; j < in_types; j++) { long int kk, l, c = 0; igraph_real_t p, last; igraph_vector_t *v1, *v2; long int v1_size, v2_size; IGRAPH_ALLOW_INTERRUPTION(); v1 = (igraph_vector_t*)VECTOR(vids_by_outtype)[i]; v2 = (igraph_vector_t*)VECTOR(vids_by_intype)[j]; v1_size = igraph_vector_size(v1); v2_size = igraph_vector_size(v2); maxedges = v1_size * v2_size; if (!loops) { IGRAPH_CHECK(igraph_vector_intersect_sorted(v1, v2, &intersect)); c = igraph_vector_size(&intersect); maxedges -= c; } p = MATRIX(*pref_matrix, i, j); igraph_vector_clear(&s); IGRAPH_CHECK(igraph_vector_reserve(&s, (long int) (maxedges * p * 1.1))); last = RNG_GEOM(p); while (last < maxedges) { IGRAPH_CHECK(igraph_vector_push_back(&s, last)); last += RNG_GEOM(p); last += 1; } l = igraph_vector_size(&s); IGRAPH_CHECK(igraph_vector_reserve(&edges, igraph_vector_size(&edges) + l * 2)); if (!loops && c > 0) { for (kk = 0; kk < l; kk++) { long int to = (long int) floor(VECTOR(s)[kk] / v1_size); long int from = (long int) (VECTOR(s)[kk] - ((igraph_real_t)to) * v1_size); if (VECTOR(*v1)[from] == VECTOR(*v2)[to]) { /* remap loop edges */ to = v2_size - 1; igraph_vector_binsearch(&intersect, VECTOR(*v1)[from], &c); from = v1_size - 1; if (VECTOR(*v1)[from] == VECTOR(*v2)[to]) { from--; } while (c > 0) { c--; from--; if (VECTOR(*v1)[from] == VECTOR(*v2)[to]) { from--; } } } igraph_vector_push_back(&edges, VECTOR(*v1)[from]); igraph_vector_push_back(&edges, VECTOR(*v2)[to]); } } else { for (kk = 0; kk < l; kk++) { long int to = (long int) floor(VECTOR(s)[kk] / v1_size); long int from = (long int) (VECTOR(s)[kk] - ((igraph_real_t)to) * v1_size); igraph_vector_push_back(&edges, VECTOR(*v1)[from]); igraph_vector_push_back(&edges, VECTOR(*v2)[to]); } } } } RNG_END(); igraph_vector_destroy(&s); igraph_vector_destroy(&intersect); igraph_i_preference_game_free_vids_by_type(&vids_by_intype); igraph_i_preference_game_free_vids_by_type(&vids_by_outtype); IGRAPH_FINALLY_CLEAN(4); if (node_type_out_vec == 0) { igraph_vector_destroy(nodetypes_out); IGRAPH_FREE(nodetypes_out); IGRAPH_FINALLY_CLEAN(1); } if (node_type_in_vec == 0) { igraph_vector_destroy(nodetypes_in); IGRAPH_FREE(nodetypes_in); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_CHECK(igraph_create(graph, &edges, nodes, 1)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/games/k_regular.c0000644000176200001440000000665514447675374017340 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_games.h" #include "igraph_interface.h" /** * \ingroup generators * \function igraph_k_regular_game * \brief Generates a random graph where each vertex has the same degree. * * This game generates a directed or undirected random graph where the * degrees of vertices are equal to a predefined constant k. For undirected * graphs, at least one of k and the number of vertices must be even. * * * Currently, this game simply uses \ref igraph_degree_sequence_game with * the \c SIMPLE_NO_MULTIPLE method and appropriately constructed degree sequences. * Thefore, it does not sample uniformly: while it can generate all k-regular graphs * with the given number of vertices, it does not generate each one with the same * probability. * * \param graph Pointer to an uninitialized graph object. * \param no_of_nodes The number of nodes in the generated graph. * \param k The degree of each vertex in an undirected graph, or * the out-degree and in-degree of each vertex in a * directed graph. * \param directed Whether the generated graph will be directed. * \param multiple Whether to allow multiple edges in the generated graph. * * \return Error code: * \c IGRAPH_EINVAL: invalid parameter; e.g., negative number of nodes, * or odd number of nodes and odd k for undirected * graphs. * \c IGRAPH_ENOMEM: there is not enough memory for the operation. * * Time complexity: O(|V|+|E|) if \c multiple is true, otherwise not known. */ int igraph_k_regular_game(igraph_t *graph, igraph_integer_t no_of_nodes, igraph_integer_t k, igraph_bool_t directed, igraph_bool_t multiple) { igraph_vector_t degseq; igraph_degseq_t mode = multiple ? IGRAPH_DEGSEQ_SIMPLE : IGRAPH_DEGSEQ_SIMPLE_NO_MULTIPLE; /* Note to self: we are not using IGRAPH_DEGSEQ_VL when multiple = false * because the VL method is not really good at generating k-regular graphs. * Actually, that's why we have added SIMPLE_NO_MULTIPLE. */ if (no_of_nodes < 0) { IGRAPH_ERROR("number of nodes must be non-negative", IGRAPH_EINVAL); } if (k < 0) { IGRAPH_ERROR("degree must be non-negative", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(°seq, no_of_nodes); igraph_vector_fill(°seq, k); IGRAPH_CHECK(igraph_degree_sequence_game(graph, °seq, directed ? °seq : 0, mode)); igraph_vector_destroy(°seq); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/scg/0000755000176200001440000000000014532173045014644 5ustar liggesusersleidenbase/src/core/scg/scg_exact_scg.c0000644000176200001440000000431214447675375017626 0ustar liggesusers/* * SCGlib : A C library for the spectral coarse graining of matrices * as described in the paper: Shrinking Matrices while preserving their * eigenpairs with Application to the Spectral Coarse Graining of Graphs. * Preprint available at * * Copyright (C) 2008 David Morton de Lachapelle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * DESCRIPTION * ----------- * The exact_coarse_graining function labels all the objects whose * components in 'v' are equal. The result is stored in 'gr'. Labels * are positive consecutive integers starting from 0. * See also Section 5.4.1 (last paragraph) of the above reference. */ #include "scg_headers.h" #include "igraph_memory.h" #include "igraph_qsort.h" #include int igraph_i_exact_coarse_graining(const igraph_real_t *v, int *gr, int n) { int i, gr_nb; igraph_i_scg_indval_t *w = IGRAPH_CALLOC(n, igraph_i_scg_indval_t); if (!w) { IGRAPH_ERROR("SCG error", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, w); for (i = 0; i < n; i++) { w[i].val = v[i]; w[i].ind = i; } igraph_qsort(w, (size_t) n, sizeof(igraph_i_scg_indval_t), igraph_i_compare_ind_val); gr_nb = 0; gr[w[0].ind] = gr_nb; for (i = 1; i < n; i++) { if ( fabs(w[i].val - w[i - 1].val) > 1e-14 ) { gr_nb++; } gr[w[i].ind] = gr_nb; } IGRAPH_FREE(w); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/scg/scg.c0000644000176200001440000027053214447675375015617 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2011-12 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * SCGlib : A C library for the spectral coarse graining of matrices * as described in the paper: Shrinking Matrices while preserving their * eigenpairs with Application to the Spectral Coarse Graining of Graphs. * Preprint available at * * Copyright (C) 2008 David Morton de Lachapelle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * DESCRIPTION * ----------- * The grouping function takes as argument 'nev' eigenvectors and * and tries to minimize the eigenpair shifts induced by the coarse * graining (Section 5 of the above reference). The eigenvectors are * stored in a 'nev'x'n' matrix 'v'. * The 'algo' parameter can take the following values * 1 -> Optimal method (sec. 5.3.1) * 2 -> Intervals+k-means (sec. 5.3.3) * 3 -> Intervals (sec. 5.3.2) * 4 -> Exact SCG (sec. 5.4.1--last paragraph) * 'nt' is a vector of length 'nev' giving either the size of the * partitions (if algo = 1) or the number of intervals to cut the * eigenvectors if algo = 2 or algo = 3. When algo = 4 this parameter * is ignored. 'maxiter' fixes the maximum number of iterations of * the k-means algorithm, and is only considered when algo = 2. * All the algorithms try to find a minimizing partition of * ||v_i-Pv_i|| where P is a problem-specific projector and v_i denotes * the eigenvectors stored in v. The final partition is worked out * as decribed in Method 1 of Section 5.4.2. * 'matrix' provides the type of SCG (i.e. the form of P). So far, * the options are those described in section 6, that is: * 1 -> Symmetric (sec. 6.1) * 2 -> Laplacian (sec. 6.2) * 3 -> Stochastic (sec. 6.3) * In the stochastic case, a valid distribution probability 'p' must be * provided. In all other cases, 'p' is ignored and can be set to NULL. * The group labels in the final partition are given in 'gr' as positive * consecutive integers starting from 0. */ #include "igraph_scg.h" #include "igraph_eigen.h" #include "igraph_interface.h" #include "igraph_structural.h" #include "igraph_community.h" #include "igraph_constructors.h" #include "igraph_conversion.h" #include "igraph_memory.h" #include "igraph_qsort.h" #include "misc/conversion_internal.h" #include "scg_headers.h" #include "math.h" /** * \section about_scg * * * The SCG functions provide a framework, called Spectral Coarse Graining * (SCG), for reducing large graphs while preserving their * spectral-related features, that is features * closely related with the eigenvalues and eigenvectors of a graph * matrix (which for now can be the adjacency, the stochastic, or the * Laplacian matrix). * * * * Common examples of such features comprise the first-passage-time of * random walkers on Markovian graphs, thermodynamic properties of * lattice models in statistical physics (e.g. Ising model), and the * epidemic threshold of epidemic network models (SIR and SIS models). * * * * SCG differs from traditional clustering schemes by producing a * coarse-grained graph (not just a partition of * the vertices), representative of the original one. As shown in [1], * Principal Component Analysis can be viewed as a particular SCG, * called exact SCG, where the matrix to be * coarse-grained is the covariance matrix of some data set. * * * * SCG should be of interest to practitioners of various * fields dealing with problems where matrix eigenpairs play an important * role, as for instance is the case of dynamical processes on networks. * * *
SCG in brief * * The main idea of SCG is to operate on a matrix a shrinkage operation * specifically designed to preserve some of the matrix eigenpairs while * not altering other important matrix features (such as its structure). * Mathematically, this idea was expressed as follows. Consider a * (complex) n x n matrix M and form the product *
* M'=LMR*, *
* where n' < n and L, R are from C[n'xn]} and are such * that LR*=I[n'] (R* denotes the conjugate transpose of R). Under * these assumptions, it can be shown that P=R*L is an n'-rank * projector and that, if (lambda, v) is a (right) * eigenpair of M (i.e. Mv=lambda v} and P is orthogonal, there exists * an eigenvalue lambda' of M' such that *
* |lambda-lambda'| <= const ||e[P](v)|| * [1+O(||e[P](v)||2)], *
* where ||e[P](v)||=||v-Pv||. Hence, if P (or equivalently * L, R) is chosen so as to make ||e[P](v)|| as small as possible, one * can preserve to any desired level the original eigenvalue * lambda in the coarse-grained matrix M'; * under extra assumptions on M, this result can be generalized to * eigenvectors [1]. This leads to the following generic definition of a * SCG problem. *
* * * Given M (C[nxn]) and (lambda, v), a (right) eigenpair of M to be * preserved by the coarse graining, the problem is to find a projector * P' solving *
* min(||e[P](v)||, p in Omega), *
* where Omega is a set of projectors in C[nxn] described by some * ad hoc constraints c[1], ..., c[r] * (e.g. c[1]: P in R[nxn], c[2]: P=t(P), c[3]: P[i,j] >= 0}, etc). *
* * * Choosing pertinent constraints to solve the SCG problem is of great * importance in applications. For instance, in the absence of * constraints the SCG problem is solved trivially by * P'=vv* (v is assumed normalized). We have designed a particular * constraint, called homogeneous mixing, which * ensures that vertices belonging to the same group are merged * consistently from a physical point of view (see [1] for * details). Under this constraint the SCG problem reduces to finding * the partition of 1, ..., n (labeling the original vertices) * minimizing *
* ||e[P](v)||2 = * sum([v(i)-(Pv)(i)]2; * alpha=1,...,n', i in alpha), *
* where alpha denotes a group (i.e. a block) in a partition of * {1, ..., n}, and |alpha| is the number of elements in alpha. *
* * * If M is symmetric or stochastic, for instance, then it may be * desirable (or mandatory) to choose L, R so that M' is symmetric or * stochastic as well. This structural constraint * has led to the construction of particular semi-projectors for * symmetric [1], stochastic [3] and Laplacian [2] matrices, that are * made available. * * * * In short, the coarse graining of matrices and graphs involves: * \olist * \oli Retrieving a matrix or a graph matrix M from the * problem. * \oli Computing the eigenpairs of M to be preserved in the * coarse-grained graph or matrix. * \oli Setting some problem-specific constraints (e.g. dimension of * the coarse-grained object). * \oli Solving the constrained SCG problem, that is finding P'. * \oli Computing from P' two semi-projectors L' and R' * (e.g. following the method proposed in [1]). * \oli Working out the product M'=L'MR'* and, if needed, defining * from M' a coarse-grained graph. * \endolist * *
* *
Functions for performing SCG * * The main functions are \ref igraph_scg_adjacency(), \ref * igraph_scg_laplacian() and \ref igraph_scg_stochastic(). * These functions handle all the steps involved in the * Spectral Coarse Graining (SCG) of some particular matrices and graphs * as described above and in reference [1]. In more details, * they compute some prescribed eigenpairs of a matrix or a * graph matrix, (for now adjacency, Laplacian and stochastic matrices are * available), work out an optimal partition to preserve the eigenpairs, * and finally output a coarse-grained matrix or graph along with other * useful information. * * * * These steps can also be carried out independently: (1) Use * \ref igraph_get_adjacency(), \ref igraph_get_sparsemat(), * \ref igraph_laplacian(), \ref igraph_get_stochastic() or \ref * igraph_get_stochastic_sparsemat() to compute a matrix M. * (2) Work out some prescribed eigenpairs of M e.g. by * means of \ref igraph_arpack_rssolve() or \ref * igraph_arpack_rnsolve(). (3) Invoke one the four * algorithms of the function \ref igraph_scg_grouping() to get a * partition that will preserve the eigenpairs in the coarse-grained * matrix. (4) Compute the semi-projectors L and R using * \ref igraph_scg_semiprojectors() and from there the coarse-grained * matrix M'=LMR*. If necessary, construct a coarse-grained graph from * M' (e.g. as in [1]). * *
* *
References * * [1] D. Morton de Lachapelle, D. Gfeller, and P. De Los Rios, * Shrinking Matrices while Preserving their Eigenpairs with Application * to the Spectral Coarse Graining of Graphs. Submitted to * SIAM Journal on Matrix Analysis and * Applications, 2008. * http://people.epfl.ch/david.morton * * * [2] D. Gfeller, and P. De Los Rios, Spectral Coarse Graining and * Synchronization in Oscillator Networks. * Physical Review Letters, * 100(17), 2008. * http://arxiv.org/abs/0708.2055 * * * [3] D. Gfeller, and P. De Los Rios, Spectral Coarse Graining of Complex * Networks, Physical Review Letters, * 99(3), 2007. * http://arxiv.org/abs/0706.0812 * *
*/ /** * \function igraph_scg_grouping * \brief SCG problem solver. * * This function solves the Spectral Coarse Graining (SCG) problem; * either exactly, or approximately but faster. * *
* The algorithm \c IGRAPH_SCG_OPTIMUM solves the SCG problem exactly * for each eigenvector in \p V. The running time of this algorithm is * O(max(nt) m^2) for the symmetric and Laplacian matrix problems. * It is O(m^3) for the stochastic problem. Here m is the number * of rows in \p V. In all three cases, the memory usage is O(m^2). * * * The algorithms \c IGRAPH_SCG_INTERV and \c IGRAPH_SCG_INTERV_KM solve * the SCG problem approximately by performing a (for now) constant * binning of the components of the eigenvectors, that is nt_vec[i] * constant-size bins are used to partition the ith eigenvector in \c V. * When \p algo is \c IGRAPH_SCG_INTERV_KM, the (Lloyd) k-means algorithm is * run on each partition obtained by \c IGRAPH_SCG_INTERV to improve * accuracy. * * * Once a minimizing partition (either exact or approximate) has been * found for each eigenvector, the final grouping is worked out as * follows: two vertices are grouped together in the final partition if * they are grouped together in each minimizing partition. In general, the * size of the final partition is not known in advance when the number * of columns in \p V is larger than one. * * * Finally, the algorithm \c IGRAPH_SCG_EXACT groups the vertices with * equal components in each eigenvector. The last three algorithms * essentially have linear running time and memory load. * * \param V The matrix of eigenvectors to be preserved by coarse * graining, each column is an eigenvector. * \param groups Pointer to an initialized vector; the result of the * SCG is stored here. * \param nt Positive integer. When \p algo is \c IGRAPH_SCG_OPTIMUM, * it gives the number of groups to partition each eigenvector * separately. When \p algo is \c IGRAPH_SCG_INTERV or \c * IGRAPH_SCG_INTERV_KM, it gives the number of intervals to * partition each eigenvector. This is ignored when \p algo is \c * IGRAPH_SCG_EXACT. * \param nt_vec May be (1) a numeric vector of length one, or * (2) a vector of the same length as the number of eigenvectors given in \p V, or * (3) a \c NULL pointer. * If not \c NULL, then this argument gives the number of * groups or intervals, and \p nt is ignored. Different number of * groups or intervals can be specified for each eigenvector. * \param mtype The type of semi-projectors used in the SCG. Possible * values are \c IGRAPH_SCG_SYMMETRIC, \c IGRAPH_SCG_STOCHASTIC and * \c IGRAPH_SCG_LAPLACIAN. * \param algo The algorithm to solve the SCG problem. Possible * values: \c IGRAPH_SCG_OPTIMUM, \c IGRAPH_SCG_INTERV_KM, \c * IGRAPH_SCG_INTERV and \c IGRAPH_SCG_EXACT. Please see the * details about them above. * \param p A probability vector, or \c NULL. This argument must be * given if \p mtype is \c IGRAPH_SCG_STOCHASTIC, but it is ignored * otherwise. For the stochastic case it gives the stationary * probability distribution of a Markov chain, the one specified by * the graph/matrix under study. * \param maxiter A positive integer giving the number of iterations * of the k-means algorithm when \p algo is \c * IGRAPH_SCG_INTERV_KM. It is ignored in other cases. A reasonable * (initial) value for this argument is 100. * \return Error code. * * Time complexity: see description above. * * \sa \ref igraph_scg_adjacency(), \ref igraph_scg_laplacian(), \ref * igraph_scg_stochastic(). * * \example examples/simple/igraph_scg_grouping.c * \example examples/simple/igraph_scg_grouping2.c * \example examples/simple/igraph_scg_grouping3.c * \example examples/simple/igraph_scg_grouping4.c */ int igraph_scg_grouping(const igraph_matrix_t *V, igraph_vector_t *groups, igraph_integer_t nt, const igraph_vector_t *nt_vec, igraph_scg_matrix_t mtype, igraph_scg_algorithm_t algo, const igraph_vector_t *p, igraph_integer_t maxiter) { int no_of_nodes = (int) igraph_matrix_nrow(V); int nev = (int) igraph_matrix_ncol(V); igraph_matrix_int_t gr_mat; int i; if (nt_vec && igraph_vector_size(nt_vec) != 1 && igraph_vector_size(nt_vec) != nev) { IGRAPH_ERROR("Invalid length for interval specification", IGRAPH_EINVAL); } if (nt_vec && igraph_vector_size(nt_vec) == 1) { nt = (igraph_integer_t) VECTOR(*nt_vec)[0]; nt_vec = 0; } if (!nt_vec && algo != IGRAPH_SCG_EXACT) { if (nt <= 1 || nt >= no_of_nodes) { IGRAPH_ERROR("Invalid interval specification", IGRAPH_EINVAL); } } else if (algo != IGRAPH_SCG_EXACT) { igraph_real_t min, max; igraph_vector_minmax(nt_vec, &min, &max); if (min <= 1 || max >= no_of_nodes) { IGRAPH_ERROR("Invalid interval specification", IGRAPH_EINVAL); } } if (mtype == IGRAPH_SCG_STOCHASTIC && !p) { IGRAPH_ERROR("The p vector must be given for the stochastic matrix case", IGRAPH_EINVAL); } if (p) { if (igraph_vector_size(p) != no_of_nodes) { IGRAPH_ERROR("Invalid p vector size", IGRAPH_EINVAL); } if (igraph_vector_min(p) < 0) { IGRAPH_ERROR("The elements of the p vector must be non-negative", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_vector_resize(groups, no_of_nodes)); #define INVEC(i) (nt_vec ? VECTOR(*nt_vec)[i] : nt) IGRAPH_CHECK(igraph_matrix_int_init(&gr_mat, no_of_nodes, nev)); IGRAPH_FINALLY(igraph_matrix_int_destroy, &gr_mat); switch (algo) { case IGRAPH_SCG_OPTIMUM: for (i = 0; i < nev; i++) { IGRAPH_CHECK(igraph_i_optimal_partition(&MATRIX(*V, 0, i), &MATRIX(gr_mat, 0, i), no_of_nodes, (int) INVEC(i), mtype, p ? VECTOR(*p) : 0, 0)); } break; case IGRAPH_SCG_INTERV_KM: for (i = 0; i < nev; i++) { igraph_vector_t tmpv; igraph_vector_view(&tmpv, &MATRIX(*V, 0, i), no_of_nodes); IGRAPH_CHECK(igraph_i_intervals_plus_kmeans(&tmpv, &MATRIX(gr_mat, 0, i), no_of_nodes, (int) INVEC(i), maxiter)); } break; case IGRAPH_SCG_INTERV: for (i = 0; i < nev; i++) { igraph_vector_t tmpv; igraph_vector_view(&tmpv, &MATRIX(*V, 0, i), no_of_nodes); IGRAPH_CHECK(igraph_i_intervals_method(&tmpv, &MATRIX(gr_mat, 0, i), no_of_nodes, (int) INVEC(i))); } break; case IGRAPH_SCG_EXACT: for (i = 0; i < nev; i++) { IGRAPH_CHECK(igraph_i_exact_coarse_graining(&MATRIX(*V, 0, i), &MATRIX(gr_mat, 0, i), no_of_nodes)); } break; } #undef INVEC if (nev == 1) { for (i = 0; i < no_of_nodes; i++) { VECTOR(*groups)[i] = MATRIX(gr_mat, i, 0); } } else { igraph_i_scg_groups_t *g; int gr_nb = 0; g = IGRAPH_CALLOC(no_of_nodes, igraph_i_scg_groups_t); IGRAPH_FINALLY(igraph_free, g); IGRAPH_CHECK(igraph_matrix_int_transpose(&gr_mat)); for (i = 0; i < no_of_nodes; i++) { g[i].ind = i; g[i].n = nev; g[i].gr = &MATRIX(gr_mat, 0, i); } igraph_qsort(g, (size_t) no_of_nodes, sizeof(igraph_i_scg_groups_t), igraph_i_compare_groups); VECTOR(*groups)[g[0].ind] = gr_nb; for (i = 1; i < no_of_nodes; i++) { if (igraph_i_compare_groups(&g[i], &g[i - 1]) != 0) { gr_nb++; } VECTOR(*groups)[g[i].ind] = gr_nb; } IGRAPH_FREE(g); IGRAPH_FINALLY_CLEAN(1); } igraph_matrix_int_destroy(&gr_mat); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_reindex_membership(groups, 0, 0)); return 0; } static int igraph_i_scg_semiprojectors_sym(const igraph_vector_t *groups, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse, int no_of_groups, int no_of_nodes) { igraph_vector_t tab; int i; IGRAPH_VECTOR_INIT_FINALLY(&tab, no_of_groups); for (i = 0; i < no_of_nodes; i++) { VECTOR(tab)[ (int) VECTOR(*groups)[i] ] += 1; } for (i = 0; i < no_of_groups; i++) { VECTOR(tab)[i] = sqrt(VECTOR(tab)[i]); } if (L) { IGRAPH_CHECK(igraph_matrix_resize(L, no_of_groups, no_of_nodes)); igraph_matrix_null(L); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; MATRIX(*L, g, i) = 1 / VECTOR(tab)[g]; } } if (R) { if (L) { IGRAPH_CHECK(igraph_matrix_update(R, L)); } else { IGRAPH_CHECK(igraph_matrix_resize(R, no_of_groups, no_of_nodes)); igraph_matrix_null(R); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; MATRIX(*R, g, i) = 1 / VECTOR(tab)[g]; } } } if (Lsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Lsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Lsparse, g, i, 1 / VECTOR(tab)[g])); } } if (Rsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Rsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Rsparse, g, i, 1 / VECTOR(tab)[g])); } } igraph_vector_destroy(&tab); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_scg_semiprojectors_lap(const igraph_vector_t *groups, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse, int no_of_groups, int no_of_nodes, igraph_scg_norm_t norm) { igraph_vector_t tab; int i; IGRAPH_VECTOR_INIT_FINALLY(&tab, no_of_groups); for (i = 0; i < no_of_nodes; i++) { VECTOR(tab)[ (int) VECTOR(*groups)[i] ] += 1; } for (i = 0; i < no_of_groups; i++) { VECTOR(tab)[i] = VECTOR(tab)[i]; } if (norm == IGRAPH_SCG_NORM_ROW) { if (L) { IGRAPH_CHECK(igraph_matrix_resize(L, no_of_groups, no_of_nodes)); igraph_matrix_null(L); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; MATRIX(*L, g, i) = 1.0 / VECTOR(tab)[g]; } } if (R) { IGRAPH_CHECK(igraph_matrix_resize(R, no_of_groups, no_of_nodes)); igraph_matrix_null(R); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; MATRIX(*R, g, i) = 1.0; } } if (Lsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Lsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Lsparse, g, i, 1.0 / VECTOR(tab)[g])); } } if (Rsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Rsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Rsparse, g, i, 1.0)); } } } else { if (L) { IGRAPH_CHECK(igraph_matrix_resize(L, no_of_groups, no_of_nodes)); igraph_matrix_null(L); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; MATRIX(*L, g, i) = 1.0; } } if (R) { IGRAPH_CHECK(igraph_matrix_resize(R, no_of_groups, no_of_nodes)); igraph_matrix_null(R); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; MATRIX(*R, g, i) = 1.0 / VECTOR(tab)[g]; } } if (Lsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Lsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Lsparse, g, i, 1.0)); } } if (Rsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Rsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Rsparse, g, i, 1.0 / VECTOR(tab)[g])); } } } igraph_vector_destroy(&tab); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_scg_semiprojectors_sto(const igraph_vector_t *groups, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse, int no_of_groups, int no_of_nodes, const igraph_vector_t *p, igraph_scg_norm_t norm) { igraph_vector_t pgr, pnormed; int i; IGRAPH_VECTOR_INIT_FINALLY(&pgr, no_of_groups); IGRAPH_VECTOR_INIT_FINALLY(&pnormed, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; VECTOR(pgr)[g] += VECTOR(*p)[i]; } for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; VECTOR(pnormed)[i] = VECTOR(*p)[i] / VECTOR(pgr)[g]; } if (norm == IGRAPH_SCG_NORM_ROW) { if (L) { IGRAPH_CHECK(igraph_matrix_resize(L, no_of_groups, no_of_nodes)); igraph_matrix_null(L); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; MATRIX(*L, g, i) = VECTOR(pnormed)[i]; } } if (R) { IGRAPH_CHECK(igraph_matrix_resize(R, no_of_groups, no_of_nodes)); igraph_matrix_null(R); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; MATRIX(*R, g, i) = 1.0; } } if (Lsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Lsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Lsparse, g, i, VECTOR(pnormed)[i])); } } if (Rsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Rsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Rsparse, g, i, 1.0)); } } } else { if (L) { IGRAPH_CHECK(igraph_matrix_resize(L, no_of_groups, no_of_nodes)); igraph_matrix_null(L); for (i = 0; i < no_of_nodes; i++) { int g = (int ) VECTOR(*groups)[i]; MATRIX(*L, g, i) = 1.0; } } if (R) { IGRAPH_CHECK(igraph_matrix_resize(R, no_of_groups, no_of_nodes)); igraph_matrix_null(R); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; MATRIX(*R, g, i) = VECTOR(pnormed)[i]; } } if (Lsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Lsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Lsparse, g, i, 1.0)); } } if (Rsparse) { IGRAPH_CHECK(igraph_sparsemat_init(Rsparse, no_of_groups, no_of_nodes, /* nzmax= */ no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { int g = (int) VECTOR(*groups)[i]; IGRAPH_CHECK(igraph_sparsemat_entry(Rsparse, g, i, VECTOR(pnormed)[i])); } } } igraph_vector_destroy(&pnormed); igraph_vector_destroy(&pgr); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_scg_semiprojectors * \brief Compute SCG semi-projectors for a given partition. * * The three types of semi-projectors are defined as follows. * Let gamma(j) label the group of vertex j in a partition of all the * vertices. * * * The symmetric semi-projectors are defined as *
* L[alpha,j] = R[alpha,j] = 1/sqrt(|alpha|) delta[alpha,gamma(j)], *
* the (row) Laplacian semi-projectors as *
* L[alpha,j] = 1/|alpha| delta[alpha,gamma(j)] *
* and *
* R[alpha,j] = delta[alpha,gamma(j)], *
* and the (row) stochastic semi-projectors as *
* L[alpha,j] = p[1][j] / sum(p[1][k]; k in gamma(j)) * delta[alpha,gamma(j)] *
* and *
* R[alpha,j] = delta[alpha,gamma(j)], *
* where p[1] is the (left) eigenvector associated with the * one-eigenvalue of the stochastic matrix. L and R are * defined in a symmetric way when \p norm is \c * IGRAPH_SCG_NORM_COL. All these semi-projectors verify various * properties described in the reference. * \param groups A vector of integers, giving the group label of every * vertex in the partition. Group labels should start at zero and * should be sequential. * \param mtype The type of semi-projectors. For now \c * IGRAPH_SCG_SYMMETRIC, \c IGRAPH_SCG_STOCHASTIC and \c * IGRAP_SCG_LAPLACIAN are supported. * \param L If not a \c NULL pointer, then it must be a pointer to * an initialized matrix. The left semi-projector is stored here. * \param R If not a \c NULL pointer, then it must be a pointer to * an initialized matrix. The right semi-projector is stored here. * \param Lsparse If not a \c NULL pointer, then it must be a pointer * to an uninitialized sparse matrix. The left semi-projector is * stored here. * \param Rsparse If not a \c NULL pointer, then it must be a pointer * to an uninitialized sparse matrix. The right semi-projector is * stored here. * \param p \c NULL, or a probability vector of the same length as \p * groups. \p p is the stationary probability distribution of a * Markov chain when \p mtype is \c IGRAPH_SCG_STOCHASTIC. This * argument is ignored in all other cases. * \param norm Either \c IGRAPH_SCG_NORM_ROW or \c IGRAPH_SCG_NORM_COL. * Specifies whether the rows or the columns of the Laplacian * matrix sum up to zero, or whether the rows or the columns of the * stochastic matrix sum up to one. * \return Error code. * * Time complexity: TODO. * * \sa \ref igraph_scg_adjacency(), \ref igraph_scg_stochastic() and * \ref igraph_scg_laplacian(), \ref igraph_scg_grouping(). * * \example examples/simple/igraph_scg_semiprojectors.c * \example examples/simple/igraph_scg_semiprojectors2.c * \example examples/simple/igraph_scg_semiprojectors3.c */ int igraph_scg_semiprojectors(const igraph_vector_t *groups, igraph_scg_matrix_t mtype, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse, const igraph_vector_t *p, igraph_scg_norm_t norm) { int no_of_nodes = (int) igraph_vector_size(groups); int no_of_groups; igraph_real_t min, max; igraph_vector_minmax(groups, &min, &max); no_of_groups = (int) max + 1; if (min < 0 || max >= no_of_nodes) { IGRAPH_ERROR("Invalid membership vector", IGRAPH_EINVAL); } if (mtype == IGRAPH_SCG_STOCHASTIC && !p) { IGRAPH_ERROR("`p' must be given for the stochastic matrix case", IGRAPH_EINVAL); } if (p && igraph_vector_size(p) != no_of_nodes) { IGRAPH_ERROR("Invalid `p' vector length, should match number of vertices", IGRAPH_EINVAL); } switch (mtype) { case IGRAPH_SCG_SYMMETRIC: IGRAPH_CHECK(igraph_i_scg_semiprojectors_sym(groups, L, R, Lsparse, Rsparse, no_of_groups, no_of_nodes)); break; case IGRAPH_SCG_LAPLACIAN: IGRAPH_CHECK(igraph_i_scg_semiprojectors_lap(groups, L, R, Lsparse, Rsparse, no_of_groups, no_of_nodes, norm)); break; case IGRAPH_SCG_STOCHASTIC: IGRAPH_CHECK(igraph_i_scg_semiprojectors_sto(groups, L, R, Lsparse, Rsparse, no_of_groups, no_of_nodes, p, norm)); break; } return 0; } /** * \function igraph_scg_norm_eps * \brief Calculate SCG residuals. * * Computes |v[i]-Pv[i]|, where v[i] is the i-th eigenvector in \p V * and P is the projector corresponding to the \p mtype argument. * * \param V The matrix of eigenvectors to be preserved by coarse * graining, each column is an eigenvector. * \param groups A vector of integers, giving the group label of every * vertex in the partition. Group labels should start at zero and * should be sequential. * \param eps Pointer to a real value, the result is stored here. * \param mtype The type of semi-projectors. For now \c * IGRAPH_SCG_SYMMETRIC, \c IGRAPH_SCG_STOCHASTIC and \c * IGRAP_SCG_LAPLACIAN are supported. * \param p \c NULL, or a probability vector of the same length as \p * groups. \p p is the stationary probability distribution of a * Markov chain when \p mtype is \c IGRAPH_SCG_STOCHASTIC. This * argument is ignored in all other cases. * \param norm Either \c IGRAPH_SCG_NORM_ROW or \c IGRAPH_SCG_NORM_COL. * Specifies whether the rows or the columns of the Laplacian * matrix sum up to zero, or whether the rows or the columns of the * stochastic matrix sum up to one. * \return Error code. * * Time complexity: TODO. * * \sa \ref igraph_scg_adjacency(), \ref igraph_scg_stochastic() and * \ref igraph_scg_laplacian(), \ref igraph_scg_grouping(), \ref * igraph_scg_semiprojectors(). */ int igraph_scg_norm_eps(const igraph_matrix_t *V, const igraph_vector_t *groups, igraph_vector_t *eps, igraph_scg_matrix_t mtype, const igraph_vector_t *p, igraph_scg_norm_t norm) { int no_of_nodes = (int) igraph_vector_size(groups); int no_of_vectors = (int) igraph_matrix_ncol(V); igraph_real_t min, max; igraph_sparsemat_t Lsparse, Rsparse, Lsparse2, Rsparse2, Rsparse3, proj; igraph_vector_t x, res; int k, i; if (igraph_matrix_nrow(V) != no_of_nodes) { IGRAPH_ERROR("Eigenvector length and group vector length do not match", IGRAPH_EINVAL); } igraph_vector_minmax(groups, &min, &max); if (min < 0 || max >= no_of_nodes) { IGRAPH_ERROR("Invalid membership vector", IGRAPH_EINVAL); } if (mtype == IGRAPH_SCG_STOCHASTIC && !p) { IGRAPH_ERROR("`p' must be given for the stochastic matrix case", IGRAPH_EINVAL); } if (p && igraph_vector_size(p) != no_of_nodes) { IGRAPH_ERROR("Invalid `p' vector length, should match number of vertices", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_scg_semiprojectors(groups, mtype, /* L= */ 0, /* R= */ 0, &Lsparse, &Rsparse, p, norm)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &Lsparse); IGRAPH_FINALLY(igraph_sparsemat_destroy, &Rsparse); IGRAPH_CHECK(igraph_sparsemat_compress(&Lsparse, &Lsparse2)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &Lsparse2); IGRAPH_CHECK(igraph_sparsemat_compress(&Rsparse, &Rsparse2)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &Rsparse2); IGRAPH_CHECK(igraph_sparsemat_transpose(&Rsparse2, &Rsparse3, /*values=*/ 1)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &Rsparse3); IGRAPH_CHECK(igraph_sparsemat_multiply(&Rsparse3, &Lsparse2, &proj)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &proj); IGRAPH_VECTOR_INIT_FINALLY(&res, no_of_nodes); IGRAPH_CHECK(igraph_vector_resize(eps, no_of_vectors)); for (k = 0; k < no_of_vectors; k++) { igraph_vector_view(&x, &MATRIX(*V, 0, k), no_of_nodes); igraph_vector_null(&res); IGRAPH_CHECK(igraph_sparsemat_gaxpy(&proj, &x, &res)); VECTOR(*eps)[k] = 0.0; for (i = 0; i < no_of_nodes; i++) { igraph_real_t di = MATRIX(*V, i, k) - VECTOR(res)[i]; VECTOR(*eps)[k] += di * di; } VECTOR(*eps)[k] = sqrt(VECTOR(*eps)[k]); } igraph_vector_destroy(&res); igraph_sparsemat_destroy(&proj); igraph_sparsemat_destroy(&Rsparse3); igraph_sparsemat_destroy(&Rsparse2); igraph_sparsemat_destroy(&Lsparse2); igraph_sparsemat_destroy(&Rsparse); igraph_sparsemat_destroy(&Lsparse); IGRAPH_FINALLY_CLEAN(7); return 0; } static int igraph_i_matrix_laplacian(const igraph_matrix_t *matrix, igraph_matrix_t *mymatrix, igraph_scg_norm_t norm) { igraph_vector_t degree; int i, j, n = (int) igraph_matrix_nrow(matrix); IGRAPH_CHECK(igraph_matrix_resize(mymatrix, n, n)); IGRAPH_VECTOR_INIT_FINALLY(°ree, n); if (norm == IGRAPH_SCG_NORM_ROW) { IGRAPH_CHECK(igraph_matrix_rowsum(matrix, °ree)); } else { IGRAPH_CHECK(igraph_matrix_colsum(matrix, °ree)); } for (i = 0; i < n; i++) { VECTOR(degree)[i] -= MATRIX(*matrix, i, i); } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { MATRIX(*mymatrix, i, j) = - MATRIX(*matrix, i, j); } MATRIX(*mymatrix, i, i) = VECTOR(degree)[i]; } igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_sparsemat_laplacian(const igraph_sparsemat_t *sparse, igraph_sparsemat_t *mysparse, igraph_scg_norm_t norm) { igraph_vector_t degree; int i, n = (int) igraph_sparsemat_nrow(sparse); int nzmax = igraph_sparsemat_nzmax(sparse); igraph_sparsemat_iterator_t it; IGRAPH_CHECK(igraph_sparsemat_init(mysparse, n, n, nzmax + n)); IGRAPH_FINALLY(igraph_sparsemat_destroy, mysparse); igraph_sparsemat_iterator_init(&it, (igraph_sparsemat_t *) sparse); IGRAPH_VECTOR_INIT_FINALLY(°ree, n); for (igraph_sparsemat_iterator_reset(&it); !igraph_sparsemat_iterator_end(&it); igraph_sparsemat_iterator_next(&it)) { int row = igraph_sparsemat_iterator_row(&it); int col = igraph_sparsemat_iterator_col(&it); if (row != col) { igraph_real_t val = igraph_sparsemat_iterator_get(&it); if (norm == IGRAPH_SCG_NORM_ROW) { VECTOR(degree)[row] += val; } else { VECTOR(degree)[col] += val; } } } /* Diagonal */ for (i = 0; i < n; i++) { igraph_sparsemat_entry(mysparse, i, i, VECTOR(degree)[i]); } /* And the rest, filter out diagonal elements */ for (igraph_sparsemat_iterator_reset(&it); !igraph_sparsemat_iterator_end(&it); igraph_sparsemat_iterator_next(&it)) { int row = igraph_sparsemat_iterator_row(&it); int col = igraph_sparsemat_iterator_col(&it); if (row != col) { igraph_real_t val = igraph_sparsemat_iterator_get(&it); igraph_sparsemat_entry(mysparse, row, col, -val); } } igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(2); /* + mysparse */ return 0; } static int igraph_i_matrix_stochastic(const igraph_matrix_t *matrix, igraph_matrix_t *mymatrix, igraph_scg_norm_t norm) { int i, j, n = (int) igraph_matrix_nrow(matrix); IGRAPH_CHECK(igraph_matrix_copy(mymatrix, matrix)); if (norm == IGRAPH_SCG_NORM_ROW) { for (i = 0; i < n; i++) { igraph_real_t sum = 0.0; for (j = 0; j < n; j++) { sum += MATRIX(*matrix, i, j); } if (sum == 0) { IGRAPH_WARNING("Zero degree vertices"); } for (j = 0; j < n; j++) { MATRIX(*mymatrix, i, j) = MATRIX(*matrix, i, j) / sum; } } } else { for (i = 0; i < n; i++) { igraph_real_t sum = 0.0; for (j = 0; j < n; j++) { sum += MATRIX(*matrix, j, i); } if (sum == 0) { IGRAPH_WARNING("Zero degree vertices"); } for (j = 0; j < n; j++) { MATRIX(*mymatrix, j, i) = MATRIX(*matrix, j, i) / sum; } } } return 0; } static int igraph_i_sparsemat_stochastic(const igraph_sparsemat_t *sparse, igraph_sparsemat_t *mysparse, igraph_scg_norm_t norm) { IGRAPH_CHECK(igraph_sparsemat_copy(mysparse, sparse)); IGRAPH_FINALLY(igraph_sparsemat_destroy, mysparse); IGRAPH_CHECK(igraph_i_normalize_sparsemat(mysparse, norm == IGRAPH_SCG_NORM_COL)); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_scg_get_result(igraph_scg_matrix_t type, const igraph_matrix_t *matrix, const igraph_sparsemat_t *sparsemat, const igraph_sparsemat_t *Lsparse, const igraph_sparsemat_t *Rsparse_t, igraph_t *scg_graph, igraph_matrix_t *scg_matrix, igraph_sparsemat_t *scg_sparsemat, igraph_bool_t directed) { /* We need to calculate either scg_matrix (if input is dense), or scg_sparsemat (if input is sparse). For the latter we might need to temporarily use another matrix. */ if (matrix) { igraph_matrix_t *my_scg_matrix = scg_matrix, v_scg_matrix; igraph_matrix_t tmp; igraph_sparsemat_t *myLsparse = (igraph_sparsemat_t *) Lsparse, v_Lsparse; if (!scg_matrix) { my_scg_matrix = &v_scg_matrix; IGRAPH_CHECK(igraph_matrix_init(my_scg_matrix, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, my_scg_matrix); } if (!igraph_sparsemat_is_cc(Lsparse)) { myLsparse = &v_Lsparse; IGRAPH_CHECK(igraph_sparsemat_compress(Lsparse, myLsparse)); IGRAPH_FINALLY(igraph_sparsemat_destroy, myLsparse); } IGRAPH_CHECK(igraph_matrix_init(&tmp, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, &tmp); IGRAPH_CHECK(igraph_sparsemat_dense_multiply(matrix, Rsparse_t, &tmp)); IGRAPH_CHECK(igraph_sparsemat_multiply_by_dense(myLsparse, &tmp, my_scg_matrix)); igraph_matrix_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); if (scg_sparsemat) { IGRAPH_CHECK(igraph_matrix_as_sparsemat(scg_sparsemat, my_scg_matrix, /* tol= */ 0)); IGRAPH_FINALLY(igraph_sparsemat_destroy, scg_sparsemat); } if (scg_graph) { if (type != IGRAPH_SCG_LAPLACIAN) { IGRAPH_CHECK(igraph_weighted_adjacency(scg_graph, my_scg_matrix, directed ? IGRAPH_ADJ_DIRECTED : IGRAPH_ADJ_UNDIRECTED, "weight", /*loops=*/ 1)); } else { int i, j, n = (int) igraph_matrix_nrow(my_scg_matrix); igraph_matrix_t tmp; IGRAPH_MATRIX_INIT_FINALLY(&tmp, n, n); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { MATRIX(tmp, i, j) = -MATRIX(*my_scg_matrix, i, j); } MATRIX(tmp, i, i) = 0; } IGRAPH_CHECK(igraph_weighted_adjacency(scg_graph, &tmp, directed ? IGRAPH_ADJ_DIRECTED : IGRAPH_ADJ_UNDIRECTED, "weight", /*loops=*/ 0)); igraph_matrix_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_FINALLY(igraph_destroy, scg_graph); } if (scg_graph) { IGRAPH_FINALLY_CLEAN(1); } if (scg_sparsemat) { IGRAPH_FINALLY_CLEAN(1); } if (!igraph_sparsemat_is_cc(Lsparse)) { igraph_sparsemat_destroy(myLsparse); IGRAPH_FINALLY_CLEAN(1); } if (!scg_matrix) { igraph_matrix_destroy(my_scg_matrix); IGRAPH_FINALLY_CLEAN(1); } } else { /* sparsemat */ igraph_sparsemat_t *my_scg_sparsemat = scg_sparsemat, v_scg_sparsemat; igraph_sparsemat_t tmp, *mysparsemat = (igraph_sparsemat_t *) sparsemat, v_sparsemat, *myLsparse = (igraph_sparsemat_t *) Lsparse, v_Lsparse; if (!scg_sparsemat) { my_scg_sparsemat = &v_scg_sparsemat; } if (!igraph_sparsemat_is_cc(sparsemat)) { mysparsemat = &v_sparsemat; IGRAPH_CHECK(igraph_sparsemat_compress(sparsemat, mysparsemat)); IGRAPH_FINALLY(igraph_sparsemat_destroy, mysparsemat); } if (!igraph_sparsemat_is_cc(Lsparse)) { myLsparse = &v_Lsparse; IGRAPH_CHECK(igraph_sparsemat_compress(Lsparse, myLsparse)); IGRAPH_FINALLY(igraph_sparsemat_destroy, myLsparse); } IGRAPH_CHECK(igraph_sparsemat_multiply(mysparsemat, Rsparse_t, &tmp)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tmp); IGRAPH_CHECK(igraph_sparsemat_multiply(myLsparse, &tmp, my_scg_sparsemat)); igraph_sparsemat_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, my_scg_sparsemat); if (scg_matrix) { IGRAPH_CHECK(igraph_sparsemat_as_matrix(scg_matrix, my_scg_sparsemat)); } if (scg_graph) { if (type != IGRAPH_SCG_LAPLACIAN) { IGRAPH_CHECK(igraph_weighted_sparsemat(scg_graph, my_scg_sparsemat, directed, "weight", /*loops=*/ 1)); } else { igraph_sparsemat_t tmp; IGRAPH_CHECK(igraph_sparsemat_copy(&tmp, my_scg_sparsemat)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tmp); IGRAPH_CHECK(igraph_sparsemat_neg(&tmp)); IGRAPH_CHECK(igraph_weighted_sparsemat(scg_graph, &tmp, directed, "weight", /*loops=*/ 0)); igraph_sparsemat_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_FINALLY(igraph_destroy, scg_graph); } if (scg_graph) { IGRAPH_FINALLY_CLEAN(1); } if (!scg_sparsemat) { igraph_sparsemat_destroy(my_scg_sparsemat); } IGRAPH_FINALLY_CLEAN(1); /* my_scg_sparsemat */ if (!igraph_sparsemat_is_cc(Lsparse)) { igraph_sparsemat_destroy(myLsparse); IGRAPH_FINALLY_CLEAN(1); } if (!igraph_sparsemat_is_cc(sparsemat)) { igraph_sparsemat_destroy(mysparsemat); IGRAPH_FINALLY_CLEAN(1); } } return 0; } static int igraph_i_scg_common_checks(const igraph_t *graph, const igraph_matrix_t *matrix, const igraph_sparsemat_t *sparsemat, const igraph_vector_t *ev, igraph_integer_t nt, const igraph_vector_t *nt_vec, const igraph_matrix_t *vectors, const igraph_matrix_complex_t *vectors_cmplx, const igraph_vector_t *groups, const igraph_t *scg_graph, const igraph_matrix_t *scg_matrix, const igraph_sparsemat_t *scg_sparsemat, const igraph_vector_t *p, igraph_real_t *evmin, igraph_real_t *evmax) { int no_of_nodes = -1; igraph_real_t min, max; int no_of_ev = (int) igraph_vector_size(ev); if ( (graph ? 1 : 0) + (matrix ? 1 : 0) + (sparsemat ? 1 : 0) != 1 ) { IGRAPH_ERROR("Give exactly one of `graph', `matrix' and `sparsemat'", IGRAPH_EINVAL); } if (graph) { no_of_nodes = igraph_vcount(graph); } else if (matrix) { no_of_nodes = (int) igraph_matrix_nrow(matrix); } else if (sparsemat) { no_of_nodes = (int) igraph_sparsemat_nrow(sparsemat); } if ((matrix && igraph_matrix_ncol(matrix) != no_of_nodes) || (sparsemat && igraph_sparsemat_ncol(sparsemat) != no_of_nodes)) { IGRAPH_ERROR("Matrix must be square", IGRAPH_NONSQUARE); } igraph_vector_minmax(ev, evmin, evmax); if (*evmin < 0 || *evmax >= no_of_nodes) { IGRAPH_ERROR("Invalid eigenvectors given", IGRAPH_EINVAL); } if (!nt_vec && (nt <= 1 || nt >= no_of_nodes)) { IGRAPH_ERROR("Invalid interval specification", IGRAPH_EINVAL); } if (nt_vec) { if (igraph_vector_size(nt_vec) != 1 && igraph_vector_size(nt_vec) != no_of_ev) { IGRAPH_ERROR("Invalid length for interval specification", IGRAPH_EINVAL); } igraph_vector_minmax(nt_vec, &min, &max); if (min <= 1 || max >= no_of_nodes) { IGRAPH_ERROR("Invalid interval specification", IGRAPH_EINVAL); } } if (vectors && igraph_matrix_size(vectors) != 0 && (igraph_matrix_ncol(vectors) != no_of_ev || igraph_matrix_nrow(vectors) != no_of_nodes)) { IGRAPH_ERROR("Invalid eigenvector matrix size", IGRAPH_EINVAL); } if (vectors_cmplx && igraph_matrix_complex_size(vectors_cmplx) != 0 && (igraph_matrix_complex_ncol(vectors_cmplx) != no_of_ev || igraph_matrix_complex_nrow(vectors_cmplx) != no_of_nodes)) { IGRAPH_ERROR("Invalid eigenvector matrix size", IGRAPH_EINVAL); } if (groups && igraph_vector_size(groups) != 0 && igraph_vector_size(groups) != no_of_nodes) { IGRAPH_ERROR("Invalid `groups' vector size", IGRAPH_EINVAL); } if ( (scg_graph != 0) + (scg_matrix != 0) + (scg_sparsemat != 0) == 0 ) { IGRAPH_ERROR("No output is requested, please give at least one of " "`scg_graph', `scg_matrix' and `scg_sparsemat'", IGRAPH_EINVAL); } if (p && igraph_vector_size(p) != 0 && igraph_vector_size(p) != no_of_nodes) { IGRAPH_ERROR("Invalid `p' vector size", IGRAPH_EINVAL); } return 0; } /** * \function igraph_scg_adjacency * Spectral coarse graining, symmetric case. * * This function handles all the steps involved in the Spectral Coarse * Graining (SCG) of some matrices and graphs as described in the * reference below. * * \param graph The input graph. Exactly one of \p graph, \p matrix * and \p sparsemat must be given, the other two must be \c NULL * pointers. * \param matrix The input matrix. Exactly one of \p graph, \p matrix * and \p sparsemat must be given, the other two must be \c NULL * pointers. * \param sparsemat The input sparse matrix. Exactly one of \p graph, * \p matrix and \p sparsemat must be given, the other two must be * \c NULL pointers. * \param ev A vector of positive integers giving the indexes of the * eigenpairs to be preserved. 1 designates the eigenvalue with * largest algebraic value, 2 the one with second largest algebraic * value, etc. * \param nt Positive integer. When \p algo is \c IGRAPH_SCG_OPTIMUM, * it gives the number of groups to partition each eigenvector * separately. When \p algo is \c IGRAPH_SCG_INTERV or \c * IGRAPH_SCG_INTERV_KM, it gives the number of intervals to * partition each eigenvector. This is ignored when \p algo is \c * IGRAPH_SCG_EXACT. * \param nt_vec A numeric vector of length one or the length must * match the number of eigenvectors given in \p V, or a \c NULL * pointer. If not \c NULL, then this argument gives the number of * groups or intervals, and \p nt is ignored. Different number of * groups or intervals can be specified for each eigenvector. * \param algo The algorithm to solve the SCG problem. Possible * values: \c IGRAPH_SCG_OPTIMUM, \c IGRAPH_SCG_INTERV_KM, \c * IGRAPH_SCG_INTERV and \c IGRAPH_SCG_EXACT. Please see the * details about them above. * \param values If this is not \c NULL and the eigenvectors are * re-calculated, then the eigenvalues are stored here. * \param vectors If this is not \c NULL, and not a zero-length * matrix, then it is interpreted as the eigenvectors to use for * the coarse-graining. Otherwise the eigenvectors are * re-calculated, and they are stored here. (If this is not \c NULL.) * \param groups If this is not \c NULL, and not a zero-length vector, * then it is interpreted as the vector of group labels. (Group * labels are integers from zero and are sequential.) Otherwise * group labels are re-calculated and stored here, if this argument * is not a null pointer. * \param use_arpack Whether to use ARPACK for solving the * eigenproblem. Currently ARPACK is not implemented. * \param maxiter A positive integer giving the number of iterations * of the k-means algorithm when \p algo is \c * IGRAPH_SCG_INTERV_KM. It is ignored in other cases. A reasonable * (initial) value for this argument is 100. * \param scg_graph If not a \c NULL pointer, then the coarse-grained * graph is returned here. * \param scg_matrix If not a \c NULL pointer, then it must be an * initialied matrix, and the coarse-grained matrix is returned * here. * \param scg_sparsemat If not a \c NULL pointer, then the coarse * grained matrix is returned here, in sparse matrix form. * \param L If not a \c NULL pointer, then it must be an initialized * matrix and the left semi-projector is returned here. * \param R If not a \c NULL pointer, then it must be an initialized * matrix and the right semi-projector is returned here. * \param Lsparse If not a \c NULL pointer, then the left * semi-projector is returned here. * \param Rsparse If not a \c NULL pointer, then the right * semi-projector is returned here. * \return Error code. * * Time complexity: TODO. * * \sa \ref igraph_scg_grouping(), \ref igraph_scg_semiprojectors(), * \ref igraph_scg_stochastic() and \ref igraph_scg_laplacian(). * * \example examples/simple/scg.c */ int igraph_scg_adjacency(const igraph_t *graph, const igraph_matrix_t *matrix, const igraph_sparsemat_t *sparsemat, const igraph_vector_t *ev, igraph_integer_t nt, const igraph_vector_t *nt_vec, igraph_scg_algorithm_t algo, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_t *groups, igraph_bool_t use_arpack, igraph_integer_t maxiter, igraph_t *scg_graph, igraph_matrix_t *scg_matrix, igraph_sparsemat_t *scg_sparsemat, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse) { igraph_sparsemat_t *mysparsemat = (igraph_sparsemat_t*) sparsemat, real_sparsemat; int no_of_ev = (int) igraph_vector_size(ev); /* eigenvectors are calculated and returned */ igraph_bool_t do_vectors = vectors && igraph_matrix_size(vectors) == 0; /* groups are calculated */ igraph_bool_t do_groups = !groups || igraph_vector_size(groups) == 0; /* eigenvectors are not returned but must be calculated for groups */ igraph_bool_t tmp_vectors = !do_vectors && do_groups; /* need temporary vector for groups */ igraph_bool_t tmp_groups = !groups; igraph_matrix_t myvectors; igraph_vector_t mygroups; igraph_bool_t tmp_lsparse = !Lsparse, tmp_rsparse = !Rsparse; igraph_sparsemat_t myLsparse, myRsparse, tmpsparse, Rsparse_t; int no_of_nodes; igraph_real_t evmin, evmax; igraph_bool_t directed; /* --------------------------------------------------------------------*/ /* Argument checks */ IGRAPH_CHECK(igraph_i_scg_common_checks(graph, matrix, sparsemat, ev, nt, nt_vec, vectors, 0, groups, scg_graph, scg_matrix, scg_sparsemat, /*p=*/ 0, &evmin, &evmax)); if (graph) { no_of_nodes = igraph_vcount(graph); directed = igraph_is_directed(graph); } else if (matrix) { no_of_nodes = (int) igraph_matrix_nrow(matrix); directed = !igraph_matrix_is_symmetric(matrix); } else { no_of_nodes = (int) igraph_sparsemat_nrow(sparsemat); directed = !igraph_sparsemat_is_symmetric(sparsemat); } /* -------------------------------------------------------------------- */ /* Convert graph, if needed */ if (graph) { mysparsemat = &real_sparsemat; IGRAPH_CHECK(igraph_get_sparsemat(graph, mysparsemat)); IGRAPH_FINALLY(igraph_sparsemat_destroy, mysparsemat); } /* -------------------------------------------------------------------- */ /* Compute eigenpairs, if needed */ if (tmp_vectors) { vectors = &myvectors; IGRAPH_MATRIX_INIT_FINALLY(vectors, no_of_nodes, no_of_ev); } if (do_vectors || tmp_vectors) { igraph_arpack_options_t options; igraph_eigen_which_t which; igraph_matrix_t tmp; igraph_vector_t tmpev; igraph_vector_t tmpeval; int i; which.pos = IGRAPH_EIGEN_SELECT; which.il = (int) (no_of_nodes - evmax + 1); which.iu = (int) (no_of_nodes - evmin + 1); if (values) { IGRAPH_VECTOR_INIT_FINALLY(&tmpeval, 0); } IGRAPH_CHECK(igraph_matrix_init(&tmp, no_of_nodes, which.iu - which.il + 1)); IGRAPH_FINALLY(igraph_matrix_destroy, &tmp); IGRAPH_CHECK(igraph_eigen_matrix_symmetric(matrix, mysparsemat, /* fun= */ 0, no_of_nodes, /* extra= */ 0, /* algorithm= */ use_arpack ? IGRAPH_EIGEN_ARPACK : IGRAPH_EIGEN_LAPACK, &which, &options, /*storage=*/ 0, values ? &tmpeval : 0, &tmp)); IGRAPH_VECTOR_INIT_FINALLY(&tmpev, no_of_ev); for (i = 0; i < no_of_ev; i++) { VECTOR(tmpev)[i] = evmax - VECTOR(*ev)[i]; } if (values) { IGRAPH_CHECK(igraph_vector_index(&tmpeval, values, &tmpev)); } IGRAPH_CHECK(igraph_matrix_select_cols(&tmp, vectors, &tmpev)); igraph_vector_destroy(&tmpev); igraph_matrix_destroy(&tmp); IGRAPH_FINALLY_CLEAN(2); if (values) { igraph_vector_destroy(&tmpeval); IGRAPH_FINALLY_CLEAN(1); } } /* -------------------------------------------------------------------- */ /* Work out groups, if needed */ if (tmp_groups) { groups = &mygroups; IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t*)groups, no_of_nodes); } if (do_groups) { IGRAPH_CHECK(igraph_scg_grouping(vectors, (igraph_vector_t*)groups, nt, nt_vec, IGRAPH_SCG_SYMMETRIC, algo, /*p=*/ 0, maxiter)); } /* -------------------------------------------------------------------- */ /* Perform coarse graining */ if (tmp_lsparse) { Lsparse = &myLsparse; } if (tmp_rsparse) { Rsparse = &myRsparse; } IGRAPH_CHECK(igraph_scg_semiprojectors(groups, IGRAPH_SCG_SYMMETRIC, L, R, Lsparse, Rsparse, /*p=*/ 0, IGRAPH_SCG_NORM_ROW)); if (tmp_groups) { igraph_vector_destroy((igraph_vector_t*) groups); IGRAPH_FINALLY_CLEAN(1); } if (tmp_vectors) { igraph_matrix_destroy(vectors); IGRAPH_FINALLY_CLEAN(1); } if (Rsparse) { IGRAPH_FINALLY(igraph_sparsemat_destroy, Rsparse); } if (Lsparse) { IGRAPH_FINALLY(igraph_sparsemat_destroy, Lsparse); } /* -------------------------------------------------------------------- */ /* Compute coarse grained matrix/graph/sparse matrix */ IGRAPH_CHECK(igraph_sparsemat_compress(Rsparse, &tmpsparse)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tmpsparse); IGRAPH_CHECK(igraph_sparsemat_transpose(&tmpsparse, &Rsparse_t, /*values=*/ 1)); igraph_sparsemat_destroy(&tmpsparse); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &Rsparse_t); IGRAPH_CHECK(igraph_i_scg_get_result(IGRAPH_SCG_SYMMETRIC, matrix, mysparsemat, Lsparse, &Rsparse_t, scg_graph, scg_matrix, scg_sparsemat, directed)); /* -------------------------------------------------------------------- */ /* Clean up */ igraph_sparsemat_destroy(&Rsparse_t); IGRAPH_FINALLY_CLEAN(1); if (Lsparse) { IGRAPH_FINALLY_CLEAN(1); } if (Rsparse) { IGRAPH_FINALLY_CLEAN(1); } if (graph) { igraph_sparsemat_destroy(mysparsemat); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_scg_stochastic * Spectral coarse graining, stochastic case. * * This function handles all the steps involved in the Spectral Coarse * Graining (SCG) of some matrices and graphs as described in the * reference below. * * \param graph The input graph. Exactly one of \p graph, \p matrix * and \p sparsemat must be given, the other two must be \c NULL * pointers. * \param matrix The input matrix. Exactly one of \p graph, \p matrix * and \p sparsemat must be given, the other two must be \c NULL * pointers. * \param sparsemat The input sparse matrix. Exactly one of \p graph, * \p matrix and \p sparsemat must be given, the other two must be * \c NULL pointers. * \param ev A vector of positive integers giving the indexes of the * eigenpairs to be preserved. 1 designates the eigenvalue with * largest magnitude, 2 the one with second largest magnitude, etc. * \param nt Positive integer. When \p algo is \c IGRAPH_SCG_OPTIMUM, * it gives the number of groups to partition each eigenvector * separately. When \p algo is \c IGRAPH_SCG_INTERV or \c * IGRAPH_SCG_INTERV_KM, it gives the number of intervals to * partition each eigenvector. This is ignored when \p algo is \c * IGRAPH_SCG_EXACT. * \param nt_vec A numeric vector of length one or the length must * match the number of eigenvectors given in \p V, or a \c NULL * pointer. If not \c NULL, then this argument gives the number of * groups or intervals, and \p nt is ignored. Different number of * groups or intervals can be specified for each eigenvector. * \param algo The algorithm to solve the SCG problem. Possible * values: \c IGRAPH_SCG_OPTIMUM, \c IGRAPH_SCG_INTERV_KM, \c * IGRAPH_SCG_INTERV and \c IGRAPH_SCG_EXACT. Please see the * details about them above. * \param norm Either \c IGRAPH_SCG_NORM_ROW or \c IGRAPH_SCG_NORM_COL. * Specifies whether the rows or the columns of the * stochastic matrix sum up to one. * \param values If this is not \c NULL and the eigenvectors are * re-calculated, then the eigenvalues are stored here. * \param vectors If this is not \c NULL, and not a zero-length * matrix, then it is interpreted as the eigenvectors to use for * the coarse-graining. Otherwise the eigenvectors are * re-calculated, and they are stored here. (If this is not \c NULL.) * \param groups If this is not \c NULL, and not a zero-length vector, * then it is interpreted as the vector of group labels. (Group * labels are integers from zero and are sequential.) Otherwise * group labels are re-calculated and stored here, if this argument * is not a null pointer. * \param p If this is not \c NULL, and not zero length, then it is * interpreted as the stationary probability distribution of the * Markov chain corresponding to the input matrix/graph. Its length * must match the number of vertices in the input graph (or number * of rows in the input matrix). If not given, then the stationary * distribution is calculated and stored here. (Unless this * argument is a \c NULL pointer, in which case it is not stored.) * \param use_arpack Whether to use ARPACK for solving the * eigenproblem. Currently ARPACK is not implemented. * \param maxiter A positive integer giving the number of iterations * of the k-means algorithm when \p algo is \c * IGRAPH_SCG_INTERV_KM. It is ignored in other cases. A reasonable * (initial) value for this argument is 100. * \param scg_graph If not a \c NULL pointer, then the coarse-grained * graph is returned here. * \param scg_matrix If not a \c NULL pointer, then it must be an * initialied matrix, and the coarse-grained matrix is returned * here. * \param scg_sparsemat If not a \c NULL pointer, then the coarse * grained matrix is returned here, in sparse matrix form. * \param L If not a \c NULL pointer, then it must be an initialized * matrix and the left semi-projector is returned here. * \param R If not a \c NULL pointer, then it must be an initialized * matrix and the right semi-projector is returned here. * \param Lsparse If not a \c NULL pointer, then the left * semi-projector is returned here. * \param Rsparse If not a \c NULL pointer, then the right * semi-projector is returned here. * \return Error code. * * Time complexity: TODO. * * \sa \ref igraph_scg_grouping(), \ref igraph_scg_semiprojectors(), * \ref igraph_scg_adjacency() and \ref igraph_scg_laplacian(). */ int igraph_scg_stochastic(const igraph_t *graph, const igraph_matrix_t *matrix, const igraph_sparsemat_t *sparsemat, const igraph_vector_t *ev, igraph_integer_t nt, const igraph_vector_t *nt_vec, igraph_scg_algorithm_t algo, igraph_scg_norm_t norm, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors, igraph_vector_t *groups, igraph_vector_t *p, igraph_bool_t use_arpack, igraph_integer_t maxiter, igraph_t *scg_graph, igraph_matrix_t *scg_matrix, igraph_sparsemat_t *scg_sparsemat, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse) { igraph_matrix_t *mymatrix = (igraph_matrix_t*) matrix, real_matrix; igraph_sparsemat_t *mysparsemat = (igraph_sparsemat_t*) sparsemat, real_sparsemat; int no_of_nodes; igraph_real_t evmin, evmax; igraph_arpack_options_t options; igraph_eigen_which_t which; /* eigenvectors are calculated and returned */ igraph_bool_t do_vectors = vectors && igraph_matrix_complex_size(vectors) == 0; /* groups are calculated */ igraph_bool_t do_groups = !groups || igraph_vector_size(groups) == 0; igraph_bool_t tmp_groups = !groups; /* eigenvectors are not returned but must be calculated for groups */ igraph_bool_t tmp_vectors = !do_vectors && do_groups; igraph_matrix_complex_t myvectors; igraph_vector_t mygroups; igraph_bool_t do_p = !p || igraph_vector_size(p) == 0; igraph_vector_t *myp = (igraph_vector_t *) p, real_p; int no_of_ev = (int) igraph_vector_size(ev); igraph_bool_t tmp_lsparse = !Lsparse, tmp_rsparse = !Rsparse; igraph_sparsemat_t myLsparse, myRsparse, tmpsparse, Rsparse_t; /* --------------------------------------------------------------------*/ /* Argument checks */ IGRAPH_CHECK(igraph_i_scg_common_checks(graph, matrix, sparsemat, ev, nt, nt_vec, 0, vectors, groups, scg_graph, scg_matrix, scg_sparsemat, p, &evmin, &evmax)); if (graph) { no_of_nodes = igraph_vcount(graph); } else if (matrix) { no_of_nodes = (int) igraph_matrix_nrow(matrix); } else { no_of_nodes = (int) igraph_sparsemat_nrow(sparsemat); } /* -------------------------------------------------------------------- */ /* Convert graph, if needed */ if (graph) { mysparsemat = &real_sparsemat; IGRAPH_CHECK(igraph_get_stochastic_sparsemat(graph, mysparsemat, norm == IGRAPH_SCG_NORM_COL)); IGRAPH_FINALLY(igraph_sparsemat_destroy, mysparsemat); } else if (matrix) { mymatrix = &real_matrix; IGRAPH_CHECK(igraph_i_matrix_stochastic(matrix, mymatrix, norm)); IGRAPH_FINALLY(igraph_matrix_destroy, mymatrix); } else { /* sparsemat */ mysparsemat = &real_sparsemat; IGRAPH_CHECK(igraph_i_sparsemat_stochastic(sparsemat, mysparsemat, norm)); IGRAPH_FINALLY(igraph_sparsemat_destroy, mysparsemat); } /* -------------------------------------------------------------------- */ /* Compute eigenpairs, if needed */ if (tmp_vectors) { vectors = &myvectors; IGRAPH_CHECK(igraph_matrix_complex_init(vectors, no_of_nodes, no_of_ev)); IGRAPH_FINALLY(igraph_matrix_complex_destroy, vectors); } if (do_vectors || tmp_vectors) { igraph_matrix_complex_t tmp; igraph_vector_t tmpev; igraph_vector_complex_t tmpeval; int i; which.pos = IGRAPH_EIGEN_SELECT; which.il = (int) (no_of_nodes - evmax + 1); which.iu = (int) (no_of_nodes - evmin + 1); if (values) { IGRAPH_CHECK(igraph_vector_complex_init(&tmpeval, 0)); IGRAPH_FINALLY(igraph_vector_complex_destroy, &tmpeval); } IGRAPH_CHECK(igraph_matrix_complex_init(&tmp, no_of_nodes, which.iu - which.il + 1)); IGRAPH_FINALLY(igraph_matrix_complex_destroy, &tmp); IGRAPH_CHECK(igraph_eigen_matrix(mymatrix, mysparsemat, /*fun=*/ 0, no_of_nodes, /*extra=*/ 0, use_arpack ? IGRAPH_EIGEN_ARPACK : IGRAPH_EIGEN_LAPACK, &which, &options, /*storage=*/ 0, values ? &tmpeval : 0, &tmp)); IGRAPH_VECTOR_INIT_FINALLY(&tmpev, no_of_ev); for (i = 0; i < no_of_ev; i++) { VECTOR(tmpev)[i] = evmax - VECTOR(*ev)[i]; } if (values) { IGRAPH_CHECK(igraph_vector_complex_index(&tmpeval, values, &tmpev)); } IGRAPH_CHECK(igraph_matrix_complex_select_cols(&tmp, vectors, &tmpev)); igraph_vector_destroy(&tmpev); igraph_matrix_complex_destroy(&tmp); IGRAPH_FINALLY_CLEAN(2); if (values) { igraph_vector_complex_destroy(&tmpeval); IGRAPH_FINALLY_CLEAN(1); } } /* Compute p if not supplied */ if (do_p) { igraph_eigen_which_t w; igraph_matrix_complex_t tmp; igraph_arpack_options_t o; igraph_matrix_t trans, *mytrans = &trans; igraph_sparsemat_t sparse_trans, *mysparse_trans = &sparse_trans; int i; igraph_arpack_options_init(&o); if (!p) { IGRAPH_VECTOR_INIT_FINALLY(&real_p, no_of_nodes); myp = &real_p; } else { IGRAPH_CHECK(igraph_vector_resize(p, no_of_nodes)); } IGRAPH_CHECK(igraph_matrix_complex_init(&tmp, 0, 0)); IGRAPH_FINALLY(igraph_matrix_complex_destroy, &tmp); w.pos = IGRAPH_EIGEN_LR; w.howmany = 1; if (mymatrix) { IGRAPH_CHECK(igraph_matrix_copy(&trans, mymatrix)); IGRAPH_FINALLY(igraph_matrix_destroy, &trans); IGRAPH_CHECK(igraph_matrix_transpose(&trans)); mysparse_trans = 0; } else { IGRAPH_CHECK(igraph_sparsemat_transpose(mysparsemat, &sparse_trans, /*values=*/ 1)); IGRAPH_FINALLY(igraph_sparsemat_destroy, mysparse_trans); mytrans = 0; } IGRAPH_CHECK(igraph_eigen_matrix(mytrans, mysparse_trans, /*fun=*/ 0, no_of_nodes, /*extra=*/ 0, /*algorith=*/ use_arpack ? IGRAPH_EIGEN_ARPACK : IGRAPH_EIGEN_LAPACK, &w, &o, /*storage=*/ 0, /*values=*/ 0, &tmp)); if (mymatrix) { igraph_matrix_destroy(&trans); IGRAPH_FINALLY_CLEAN(1); } else { igraph_sparsemat_destroy(mysparse_trans); IGRAPH_FINALLY_CLEAN(1); } for (i = 0; i < no_of_nodes; i++) { VECTOR(*myp)[i] = fabs(IGRAPH_REAL(MATRIX(tmp, i, 0))); } igraph_matrix_complex_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); } /* -------------------------------------------------------------------- */ /* Work out groups, if needed */ /* TODO: use complex part as well */ if (tmp_groups) { groups = &mygroups; IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t*)groups, no_of_nodes); } if (do_groups) { igraph_matrix_t tmp; IGRAPH_MATRIX_INIT_FINALLY(&tmp, 0, 0); IGRAPH_CHECK(igraph_matrix_complex_real(vectors, &tmp)); IGRAPH_CHECK(igraph_scg_grouping(&tmp, (igraph_vector_t*)groups, nt, nt_vec, IGRAPH_SCG_STOCHASTIC, algo, myp, maxiter)); igraph_matrix_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); } /* -------------------------------------------------------------------- */ /* Perform coarse graining */ if (tmp_lsparse) { Lsparse = &myLsparse; } if (tmp_rsparse) { Rsparse = &myRsparse; } IGRAPH_CHECK(igraph_scg_semiprojectors(groups, IGRAPH_SCG_STOCHASTIC, L, R, Lsparse, Rsparse, myp, norm)); if (tmp_groups) { igraph_vector_destroy((igraph_vector_t*) groups); IGRAPH_FINALLY_CLEAN(1); } if (!p && do_p) { igraph_vector_destroy(myp); IGRAPH_FINALLY_CLEAN(1); } if (tmp_vectors) { igraph_matrix_complex_destroy(vectors); IGRAPH_FINALLY_CLEAN(1); } if (Rsparse) { IGRAPH_FINALLY(igraph_sparsemat_destroy, Rsparse); } if (Lsparse) { IGRAPH_FINALLY(igraph_sparsemat_destroy, Lsparse); } /* -------------------------------------------------------------------- */ /* Compute coarse grained matrix/graph/sparse matrix */ IGRAPH_CHECK(igraph_sparsemat_compress(Rsparse, &tmpsparse)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tmpsparse); IGRAPH_CHECK(igraph_sparsemat_transpose(&tmpsparse, &Rsparse_t, /*values=*/ 1)); igraph_sparsemat_destroy(&tmpsparse); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &Rsparse_t); IGRAPH_CHECK(igraph_i_scg_get_result(IGRAPH_SCG_STOCHASTIC, mymatrix, mysparsemat, Lsparse, &Rsparse_t, scg_graph, scg_matrix, scg_sparsemat, /*directed=*/ 1)); /* -------------------------------------------------------------------- */ /* Clean up */ igraph_sparsemat_destroy(&Rsparse_t); IGRAPH_FINALLY_CLEAN(1); if (Lsparse) { IGRAPH_FINALLY_CLEAN(1); } if (Rsparse) { IGRAPH_FINALLY_CLEAN(1); } if (graph) { igraph_sparsemat_destroy(mysparsemat); IGRAPH_FINALLY_CLEAN(1); } else if (matrix) { igraph_matrix_destroy(mymatrix); IGRAPH_FINALLY_CLEAN(1); } else { igraph_sparsemat_destroy(mysparsemat); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_scg_laplacian * \brief Spectral coarse graining, Laplacian case. * * This function handles all the steps involved in the Spectral Coarse * Graining (SCG) of some matrices and graphs as described in the * reference below. * * \param graph The input graph. Exactly one of \p graph, \p matrix * and \p sparsemat must be given, the other two must be \c NULL * pointers. * \param matrix The input matrix. Exactly one of \p graph, \p matrix * and \p sparsemat must be given, the other two must be \c NULL * pointers. * \param sparsemat The input sparse matrix. Exactly one of \p graph, * \p matrix and \p sparsemat must be given, the other two must be * \c NULL pointers. * \param ev A vector of positive integers giving the indexes of the * eigenpairs to be preserved. 1 designates the eigenvalue with * largest magnitude, 2 the one with second largest magnitude, etc. * \param nt Positive integer. When \p algo is \c IGRAPH_SCG_OPTIMUM, * it gives the number of groups to partition each eigenvector * separately. When \p algo is \c IGRAPH_SCG_INTERV or \c * IGRAPH_SCG_INTERV_KM, it gives the number of intervals to * partition each eigenvector. This is ignored when \p algo is \c * IGRAPH_SCG_EXACT. * \param nt_vec A numeric vector of length one or the length must * match the number of eigenvectors given in \p V, or a \c NULL * pointer. If not \c NULL, then this argument gives the number of * groups or intervals, and \p nt is ignored. Different number of * groups or intervals can be specified for each eigenvector. * \param algo The algorithm to solve the SCG problem. Possible * values: \c IGRAPH_SCG_OPTIMUM, \c IGRAPH_SCG_INTERV_KM, \c * IGRAPH_SCG_INTERV and \c IGRAPH_SCG_EXACT. Please see the * details about them above. * \param norm Either \c IGRAPH_SCG_NORM_ROW or \c IGRAPH_SCG_NORM_COL. * Specifies whether the rows or the columns of the Laplacian * matrix sum up to zero. * \param direction Whether to work with left or right eigenvectors. * Possible values: \c IGRAPH_SCG_DIRECTION_DEFAULT, \c * IGRAPH_SCG_DIRECTION_LEFT, \c IGRAPH_SCG_DIRECTION_RIGHT. This * argument is currently ignored and right eigenvectors are always * used. * \param values If this is not \c NULL and the eigenvectors are * re-calculated, then the eigenvalues are stored here. * \param vectors If this is not \c NULL, and not a zero-length * matrix, then it is interpreted as the eigenvectors to use for * the coarse-graining. Otherwise the eigenvectors are * re-calculated, and they are stored here. (If this is not \c NULL.) * \param groups If this is not \c NULL, and not a zero-length vector, * then it is interpreted as the vector of group labels. (Group * labels are integers from zero and are sequential.) Otherwise * group labels are re-calculated and stored here, if this argument * is not a null pointer. * \param use_arpack Whether to use ARPACK for solving the * eigenproblem. Currently ARPACK is not implemented. * \param maxiter A positive integer giving the number of iterations * of the k-means algorithm when \p algo is \c * IGRAPH_SCG_INTERV_KM. It is ignored in other cases. A reasonable * (initial) value for this argument is 100. * \param scg_graph If not a \c NULL pointer, then the coarse-grained * graph is returned here. * \param scg_matrix If not a \c NULL pointer, then it must be an * initialied matrix, and the coarse-grained matrix is returned * here. * \param scg_sparsemat If not a \c NULL pointer, then the coarse * grained matrix is returned here, in sparse matrix form. * \param L If not a \c NULL pointer, then it must be an initialized * matrix and the left semi-projector is returned here. * \param R If not a \c NULL pointer, then it must be an initialized * matrix and the right semi-projector is returned here. * \param Lsparse If not a \c NULL pointer, then the left * semi-projector is returned here. * \param Rsparse If not a \c NULL pointer, then the right * semi-projector is returned here. * \return Error code. * * Time complexity: TODO. * * \sa \ref igraph_scg_grouping(), \ref igraph_scg_semiprojectors(), * \ref igraph_scg_stochastic() and \ref igraph_scg_adjacency(). */ int igraph_scg_laplacian(const igraph_t *graph, const igraph_matrix_t *matrix, const igraph_sparsemat_t *sparsemat, const igraph_vector_t *ev, igraph_integer_t nt, const igraph_vector_t *nt_vec, igraph_scg_algorithm_t algo, igraph_scg_norm_t norm, igraph_scg_direction_t direction, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors, igraph_vector_t *groups, igraph_bool_t use_arpack, igraph_integer_t maxiter, igraph_t *scg_graph, igraph_matrix_t *scg_matrix, igraph_sparsemat_t *scg_sparsemat, igraph_matrix_t *L, igraph_matrix_t *R, igraph_sparsemat_t *Lsparse, igraph_sparsemat_t *Rsparse) { igraph_matrix_t *mymatrix = (igraph_matrix_t*) matrix, real_matrix; igraph_sparsemat_t *mysparsemat = (igraph_sparsemat_t*) sparsemat, real_sparsemat; int no_of_nodes; igraph_real_t evmin, evmax; igraph_arpack_options_t options; igraph_eigen_which_t which; /* eigenvectors are calculated and returned */ igraph_bool_t do_vectors = vectors && igraph_matrix_complex_size(vectors) == 0; /* groups are calculated */ igraph_bool_t do_groups = !groups || igraph_vector_size(groups) == 0; igraph_bool_t tmp_groups = !groups; /* eigenvectors are not returned but must be calculated for groups */ igraph_bool_t tmp_vectors = !do_vectors && do_groups; igraph_matrix_complex_t myvectors; igraph_vector_t mygroups; int no_of_ev = (int) igraph_vector_size(ev); igraph_bool_t tmp_lsparse = !Lsparse, tmp_rsparse = !Rsparse; igraph_sparsemat_t myLsparse, myRsparse, tmpsparse, Rsparse_t; IGRAPH_UNUSED(direction); /* --------------------------------------------------------------------*/ /* Argument checks */ IGRAPH_CHECK(igraph_i_scg_common_checks(graph, matrix, sparsemat, ev, nt, nt_vec, 0, vectors, groups, scg_graph, scg_matrix, scg_sparsemat, /*p=*/ 0, &evmin, &evmax)); if (graph) { no_of_nodes = igraph_vcount(graph); } else if (matrix) { no_of_nodes = (int) igraph_matrix_nrow(matrix); } else { no_of_nodes = (int) igraph_sparsemat_nrow(sparsemat); } /* -------------------------------------------------------------------- */ /* Convert graph, if needed, get Laplacian matrix */ if (graph) { mysparsemat = &real_sparsemat; IGRAPH_CHECK(igraph_sparsemat_init(mysparsemat, 0, 0, 0)); IGRAPH_FINALLY(igraph_sparsemat_destroy, mysparsemat); IGRAPH_CHECK(igraph_laplacian(graph, 0, mysparsemat, /*normalized=*/ 0, /*weights=*/ 0)); } else if (matrix) { mymatrix = &real_matrix; IGRAPH_MATRIX_INIT_FINALLY(mymatrix, no_of_nodes, no_of_nodes); IGRAPH_CHECK(igraph_i_matrix_laplacian(matrix, mymatrix, norm)); } else { /* sparsemat */ mysparsemat = &real_sparsemat; IGRAPH_CHECK(igraph_i_sparsemat_laplacian(sparsemat, mysparsemat, norm == IGRAPH_SCG_NORM_COL)); IGRAPH_FINALLY(igraph_sparsemat_destroy, mysparsemat); } /* -------------------------------------------------------------------- */ /* Compute eigenpairs, if needed */ if (tmp_vectors) { vectors = &myvectors; IGRAPH_CHECK(igraph_matrix_complex_init(vectors, no_of_nodes, no_of_ev)); IGRAPH_FINALLY(igraph_matrix_complex_destroy, vectors); } if (do_vectors || tmp_vectors) { igraph_matrix_complex_t tmp; igraph_vector_t tmpev; igraph_vector_complex_t tmpeval; int i; which.pos = IGRAPH_EIGEN_SELECT; which.il = (int) (no_of_nodes - evmax + 1); which.iu = (int) (no_of_nodes - evmin + 1); if (values) { IGRAPH_CHECK(igraph_vector_complex_init(&tmpeval, 0)); IGRAPH_FINALLY(igraph_vector_complex_destroy, &tmpeval); } IGRAPH_CHECK(igraph_matrix_complex_init(&tmp, no_of_nodes, which.iu - which.il + 1)); IGRAPH_FINALLY(igraph_matrix_complex_destroy, &tmp); IGRAPH_CHECK(igraph_eigen_matrix(mymatrix, mysparsemat, /*fun=*/ 0, no_of_nodes, /*extra=*/ 0, use_arpack ? IGRAPH_EIGEN_ARPACK : IGRAPH_EIGEN_LAPACK, &which, &options, /*storage=*/ 0, values ? &tmpeval : 0, &tmp)); IGRAPH_VECTOR_INIT_FINALLY(&tmpev, no_of_ev); for (i = 0; i < no_of_ev; i++) { VECTOR(tmpev)[i] = evmax - VECTOR(*ev)[i]; } if (values) { IGRAPH_CHECK(igraph_vector_complex_index(&tmpeval, values, &tmpev)); } IGRAPH_CHECK(igraph_matrix_complex_select_cols(&tmp, vectors, &tmpev)); igraph_vector_destroy(&tmpev); igraph_matrix_complex_destroy(&tmp); IGRAPH_FINALLY_CLEAN(2); if (values) { igraph_vector_complex_destroy(&tmpeval); IGRAPH_FINALLY_CLEAN(1); } } /* -------------------------------------------------------------------- */ /* Work out groups, if needed */ /* TODO: use complex part as well */ if (tmp_groups) { groups = &mygroups; IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t*)groups, no_of_nodes); } if (do_groups) { igraph_matrix_t tmp; IGRAPH_MATRIX_INIT_FINALLY(&tmp, 0, 0); IGRAPH_CHECK(igraph_matrix_complex_real(vectors, &tmp)); IGRAPH_CHECK(igraph_scg_grouping(&tmp, (igraph_vector_t*)groups, nt, nt_vec, IGRAPH_SCG_LAPLACIAN, algo, /*p=*/ 0, maxiter)); igraph_matrix_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); } /* -------------------------------------------------------------------- */ /* Perform coarse graining */ if (tmp_lsparse) { Lsparse = &myLsparse; } if (tmp_rsparse) { Rsparse = &myRsparse; } IGRAPH_CHECK(igraph_scg_semiprojectors(groups, IGRAPH_SCG_LAPLACIAN, L, R, Lsparse, Rsparse, /*p=*/ 0, norm)); if (tmp_groups) { igraph_vector_destroy((igraph_vector_t*) groups); IGRAPH_FINALLY_CLEAN(1); } if (tmp_vectors) { igraph_matrix_complex_destroy(vectors); IGRAPH_FINALLY_CLEAN(1); } if (Rsparse) { IGRAPH_FINALLY(igraph_sparsemat_destroy, Rsparse); } if (Lsparse) { IGRAPH_FINALLY(igraph_sparsemat_destroy, Lsparse); } /* -------------------------------------------------------------------- */ /* Compute coarse grained matrix/graph/sparse matrix */ IGRAPH_CHECK(igraph_sparsemat_compress(Rsparse, &tmpsparse)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tmpsparse); IGRAPH_CHECK(igraph_sparsemat_transpose(&tmpsparse, &Rsparse_t, /*values=*/ 1)); igraph_sparsemat_destroy(&tmpsparse); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &Rsparse_t); IGRAPH_CHECK(igraph_i_scg_get_result(IGRAPH_SCG_LAPLACIAN, mymatrix, mysparsemat, Lsparse, &Rsparse_t, scg_graph, scg_matrix, scg_sparsemat, /*directed=*/ 1)); /* -------------------------------------------------------------------- */ /* Clean up */ igraph_sparsemat_destroy(&Rsparse_t); IGRAPH_FINALLY_CLEAN(1); if (Lsparse) { IGRAPH_FINALLY_CLEAN(1); } if (Rsparse) { IGRAPH_FINALLY_CLEAN(1); } if (graph) { igraph_sparsemat_destroy(mysparsemat); IGRAPH_FINALLY_CLEAN(1); } else if (matrix) { igraph_matrix_destroy(mymatrix); IGRAPH_FINALLY_CLEAN(1); } else { igraph_sparsemat_destroy(mysparsemat); IGRAPH_FINALLY_CLEAN(1); } return 0; } leidenbase/src/core/scg/scg_approximate_methods.c0000644000176200001440000001415514447675375021750 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2011-12 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * SCGlib : A C library for the spectral coarse graining of matrices * as described in the paper: Shrinking Matrices while preserving their * eigenpairs with Application to the Spectral Coarse Graining of Graphs. * Preprint available at * * Copyright (C) 2008 David Morton de Lachapelle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * DESCRIPTION * ----------- * The intervals_method and intervals_plus_kmeans implements the * methods of sec. 5.3.2 and sec. 5.3.3 of the above reference. * They take an eigenvector 'v' as parameter and a vector 'breaks' * of length 'nb', which provide the intervals used to cut 'v'. * Then all components of 'v' that fall into the same interval are * assigned the same group label in 'gr'. The group labels are * positive consecutive integers starting from 0. * The intervals_method function is adapted from bincode of the R * base package. * The intervals_plus_kmeans is initialized with regularly-spaced * breaks, which rougly corresponds to the intervals_method. Then * kmeans minimizes iteratively the objective function until it gets * stuck in a (usually) local minimum, or until 'itermax' is reached. * So far, the breaks_computation function allows computation of * constant bins, as used in intervals_method, and of equidistant * centers as used in intervals_plus_kmeans. */ #include "scg_headers.h" #include "igraph_error.h" #include "igraph_types.h" #include "igraph_vector.h" int igraph_i_intervals_plus_kmeans(const igraph_vector_t *v, int *gr, int n, int n_interv, int maxiter) { int i; igraph_vector_t centers; IGRAPH_VECTOR_INIT_FINALLY(¢ers, n_interv); igraph_i_breaks_computation(v, ¢ers, n_interv, 2); IGRAPH_CHECK(igraph_i_kmeans_Lloyd(v, n, 1, ¢ers, n_interv, gr, maxiter)); /*renumber the groups*/ for (i = 0; i < n; i++) { gr[i] = gr[i] - 1; } igraph_vector_destroy(¢ers); IGRAPH_FINALLY_CLEAN(1); return 0; } int igraph_i_intervals_method(const igraph_vector_t *v, int *gr, int n, int n_interv) { int i, lo, hi, new; const int lft = 1; const int include_border = 1; igraph_vector_t breaks; IGRAPH_VECTOR_INIT_FINALLY(&breaks, n_interv + 1); IGRAPH_CHECK(igraph_i_breaks_computation(v, &breaks, n_interv + 1, 1)); for (i = 0; i < n; i++) { lo = 0; hi = n_interv; if (VECTOR(*v)[i] < VECTOR(breaks)[lo] || VECTOR(breaks)[hi] < VECTOR(*v)[i] || (VECTOR(*v)[i] == VECTOR(breaks)[lft ? hi : lo] && !include_border)) { /* Do nothing */ } else { while (hi - lo >= 2) { new = (hi + lo) / 2; if (VECTOR(*v)[i] > VECTOR(breaks)[new] || (lft && VECTOR(*v)[i] == VECTOR(breaks)[new])) { lo = new; } else { hi = new; } } gr[i] = lo; } } igraph_vector_destroy(&breaks); IGRAPH_FINALLY_CLEAN(1); return 0; } int igraph_i_breaks_computation(const igraph_vector_t *v, igraph_vector_t *breaks, int nb, int method) { int i; igraph_real_t eps, vmin, vmax; igraph_vector_minmax(v, &vmin, &vmax); if (vmax == vmin) { IGRAPH_ERROR("There is only one (repeated) value in argument 'v' " "of bin_size_computation()", IGRAPH_EINVAL); } if (nb < 2) { IGRAPH_ERROR("'nb' in bin_size_computation() must be >= 2", IGRAPH_EINVAL); } switch (method) { case 1: /* constant bins for fixed-size intervals method */ eps = (vmax - vmin) / (igraph_real_t)(nb - 1); VECTOR(*breaks)[0] = vmin; for (i = 1; i < nb - 1; i++) { VECTOR(*breaks)[i] = VECTOR(*breaks)[i - 1] + eps; } VECTOR(*breaks)[nb - 1] = vmax; break; case 2: /* equidistant centers for kmeans */ eps = (vmax - vmin) / (igraph_real_t)nb; VECTOR(*breaks)[0] = vmin + eps / 2.; for (i = 1; i < nb; i++) { VECTOR(*breaks)[i] = VECTOR(*breaks)[i - 1] + eps; } break; /* TODO: implement logarithmic binning for power-law-like distributions */ default: IGRAPH_ERROR("Internal SCG error, this should ot happen", IGRAPH_FAILURE); } return 0; } leidenbase/src/core/scg/scg_kmeans.c0000644000176200001440000000656114447675375017154 0ustar liggesusers/* * SCGlib : A C library for the spectral coarse graining of matrices * as described in the paper: Shrinking Matrices while preserving their * eigenpairs with Application to the Spectral Coarse Graining of Graphs. * Preprint available at * * Copyright (C) 2008 David Morton de Lachapelle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * DESCRIPTION * ----------- * The kmeans_Lloyd function is adapted from the R-stats package. * It perfoms Lloyd's k-means clustering on a p x n data matrix * stored row-wise in a vector 'x'. 'cen' contains k initial centers. * The group label to which each object belongs is stored in 'cl'. * Labels are positive consecutive integers starting from 0. * See also Section 5.3.3 of the above reference. */ #include "scg_headers.h" int igraph_i_kmeans_Lloyd(const igraph_vector_t *x, int n, int p, igraph_vector_t *cen, int k, int *cl, int maxiter) { int iter, i, j, c, it, inew = 0; igraph_real_t best, dd, tmp; int updated; igraph_vector_int_t nc; IGRAPH_CHECK(igraph_vector_int_init(&nc, k)); IGRAPH_FINALLY(igraph_vector_int_destroy, &nc); for (i = 0; i < n; i++) { cl[i] = -1; } for (iter = 0; iter < maxiter; iter++) { updated = 0; for (i = 0; i < n; i++) { /* find nearest centre for each point */ best = IGRAPH_INFINITY; for (j = 0; j < k; j++) { dd = 0.0; for (c = 0; c < p; c++) { tmp = VECTOR(*x)[i + n * c] - VECTOR(*cen)[j + k * c]; dd += tmp * tmp; } if (dd < best) { best = dd; inew = j + 1; } } if (cl[i] != inew) { updated = 1; cl[i] = inew; } } if (!updated) { break; } /* update each centre */ for (j = 0; j < k * p; j++) { VECTOR(*cen)[j] = 0.0; } for (j = 0; j < k; j++) { VECTOR(nc)[j] = 0; } for (i = 0; i < n; i++) { it = cl[i] - 1; VECTOR(nc)[it]++; for (c = 0; c < p; c++) { VECTOR(*cen)[it + c * k] += VECTOR(*x)[i + c * n]; } } for (j = 0; j < k * p; j++) { VECTOR(*cen)[j] /= VECTOR(nc)[j % k]; } } igraph_vector_int_destroy(&nc); IGRAPH_FINALLY_CLEAN(1); /* convervenge check */ if (iter >= maxiter - 1) { IGRAPH_ERROR("Lloyd k-means did not converge", IGRAPH_FAILURE); } return 0; } leidenbase/src/core/scg/scg_headers.h0000644000176200001440000001155214447675375017312 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * SCGlib : A C library for the spectral coarse graining of matrices * as described in the paper: Shrinking Matrices while preserving their * eigenpairs with Application to the Spectral Coarse Graining of Graphs. * Preprint available at * * Copyright (C) 2008 David Morton de Lachapelle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * DESCRIPTION * ----------- * This file contains the headers of the library SCGlib. * For use with R software define * the constant R_COMPIL and refer to the R documentation to compile * a dynamic library. The scg_r_wrapper function should be useful. */ #ifndef SCG_HEADERS_H #define SCG_HEADERS_H #include "igraph_types.h" #include "igraph_vector.h" #include #include typedef struct ind_val { int ind; igraph_real_t val; } igraph_i_scg_indval_t; int igraph_i_compare_ind_val(const void *a, const void *b); typedef struct groups { int ind; int n; int* gr; } igraph_i_scg_groups_t; /*------------------------------------------------- ------------DEFINED IN scg_approximate_methods.c--- ---------------------------------------------------*/ int igraph_i_breaks_computation(const igraph_vector_t *v, igraph_vector_t *breaks, int nb, int method); int igraph_i_intervals_plus_kmeans(const igraph_vector_t *v, int *gr, int n, int n_interv, int maxiter); int igraph_i_intervals_method(const igraph_vector_t *v, int *gr, int n, int n_interv); /*------------------------------------------------- ------------DEFINED IN scg_optimal_method.c-------- ---------------------------------------------------*/ int igraph_i_cost_matrix(igraph_real_t *Cv, const igraph_i_scg_indval_t *vs, int n, int matrix, const igraph_vector_t *ps); int igraph_i_optimal_partition(const igraph_real_t *v, igraph_integer_t *gr, int n, int nt, int matrix, const igraph_real_t *p, igraph_real_t *value); /*------------------------------------------------- ------------DEFINED IN scg_kmeans.c---------------- ---------------------------------------------------*/ int igraph_i_kmeans_Lloyd(const igraph_vector_t *x, int n, int p, igraph_vector_t *centers, int k, int *cl, int maxiter); /*------------------------------------------------- ------------DEFINED IN scg_exact_scg.c------------- ---------------------------------------------------*/ int igraph_i_exact_coarse_graining(const igraph_real_t *v, int *gr, int n); /*------------------------------------------------- ------------DEFINED IN scg_utils.c----------------- ---------------------------------------------------*/ int igraph_i_compare_groups(const void *a, const void *b); int igraph_i_compare_real(const void *a, const void *b); int igraph_i_compare_int(const void *a, const void *b); igraph_real_t *igraph_i_real_sym_matrix(int size); #define igraph_i_real_sym_mat_get(S,i,j) S[i+j*(j+1)/2] #define igraph_i_real_sym_mat_set(S,i,j,val) S[i+j*(j+1)/2] = val #define igraph_i_free_real_sym_matrix(S) IGRAPH_FREE(S) #endif leidenbase/src/core/scg/scg_utils.c0000644000176200001440000000600414447675375017026 0ustar liggesusers/* * SCGlib : A C library for the spectral coarse graining of matrices * as described in the paper: Shrinking Matrices while preserving their * eigenpairs with Application to the Spectral Coarse Graining of Graphs. * Preprint available at * * Copyright (C) 2008 David Morton de Lachapelle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * DESCRIPTION * ----------- * This files contains the data structures and error handing * functions used throughout the SCGlib. */ #include "scg_headers.h" #include "igraph_error.h" #include "igraph_memory.h" /*to be used with qsort and struct ind_val arrays */ int igraph_i_compare_ind_val(const void *a, const void *b) { igraph_i_scg_indval_t *arg1 = (igraph_i_scg_indval_t *) a; igraph_i_scg_indval_t *arg2 = (igraph_i_scg_indval_t *) b; if ( arg1->val < arg2->val ) { return -1; } else if ( arg1->val == arg2->val ) { return 0; } else { return 1; } } /*to be used with qsort and struct groups*/ int igraph_i_compare_groups(const void *a, const void *b) { igraph_i_scg_groups_t *arg1 = (igraph_i_scg_groups_t *) a; igraph_i_scg_groups_t *arg2 = (igraph_i_scg_groups_t *) b; int i; for (i = 0; i < arg1->n; i++) { if (arg1->gr[i] > arg2->gr[i]) { return 1; } else if (arg1->gr[i] < arg2->gr[i]) { return -1; } } return 0; } /*to be used with qsort and real_vectors */ int igraph_i_compare_real(const void *a, const void *b) { igraph_real_t arg1 = * (igraph_real_t *) a; igraph_real_t arg2 = * (igraph_real_t *) b; if (arg1 < arg2) { return -1; } else if (arg1 == arg2) { return 0; } else { return 1; } } /*to be used with qsort and integer vectors */ int igraph_i_compare_int(const void *a, const void *b) { int arg1 = * (int *) a; int arg2 = * (int *) b; return (arg1 - arg2); } /* allocate a igraph_real_t symmetrix matrix with dimension size x size in vector format*/ igraph_real_t *igraph_i_real_sym_matrix(int size) { igraph_real_t *S = IGRAPH_CALLOC(size * (size + 1) / 2, igraph_real_t); if (!S) { igraph_error("allocation failure in real_sym_matrix()", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); } return S; } leidenbase/src/core/scg/scg_optimal_method.c0000644000176200001440000001754114447675375020703 0ustar liggesusers/* * SCGlib : A C library for the spectral coarse graining of matrices * as described in the paper: Shrinking Matrices while preserving their * eigenpairs with Application to the Spectral Coarse Graining of Graphs. * Preprint available at * * Copyright (C) 2008 David Morton de Lachapelle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * DESCRIPTION * ----------- * This file implements algorithm 5.8 of the above reference. * The optimal_partition function returns the minimizing partition * with size 'nt' of the objective function ||v-Pv||, where P is * a problem-specific projector. So far, Symmetric (matrix=1), * Laplacian (matrix=2) and Stochastic (matrix=3) projectors * have been implemented (the cost_matrix function below). * In the stochastic case, 'p' is expected to be a valid propability * vector. In all other cases, 'p' is ignored and can be set to NULL. * The group labels are given in 'gr' as positive consecutive integers * starting from 0. */ #include "scg_headers.h" #include "igraph_error.h" #include "igraph_memory.h" #include "igraph_matrix.h" #include "igraph_vector.h" #include "igraph_qsort.h" int igraph_i_optimal_partition(const igraph_real_t *v, igraph_integer_t *gr, int n, int nt, int matrix, const igraph_real_t *p, igraph_real_t *value) { int i, non_ties, q, j, l, part_ind, col; igraph_i_scg_indval_t *vs = IGRAPH_CALLOC(n, igraph_i_scg_indval_t); igraph_real_t *Cv, temp, sumOfSquares; igraph_vector_t ps; igraph_matrix_t F; igraph_matrix_int_t Q; /*----------------------------------------------- -----Sorts v and counts non-ties----------------- -----------------------------------------------*/ if (!vs) { IGRAPH_ERROR("SCG error", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, vs); for (i = 0; i < n; i++) { vs[i].val = v[i]; vs[i].ind = i; } igraph_qsort(vs, (size_t) n, sizeof(igraph_i_scg_indval_t), igraph_i_compare_ind_val); non_ties = 1; for (i = 1; i < n; i++) { if (vs[i].val < vs[i - 1].val - 1e-14 || vs[i].val > vs[i - 1].val + 1e-14) { non_ties++; } } if (nt >= non_ties) { IGRAPH_ERROR("`Invalid number of intervals, should be smaller than " "number of unique values in V", IGRAPH_EINVAL); } /*------------------------------------------------ ------Computes Cv, the matrix of costs------------ ------------------------------------------------*/ Cv = igraph_i_real_sym_matrix(n); if (!Cv) { IGRAPH_ERROR("SCG error", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, Cv); /* if stochastic SCG orders p */ if (matrix == 3) { IGRAPH_VECTOR_INIT_FINALLY(&ps, n); for (i = 0; i < n; i++) { VECTOR(ps)[i] = p[vs[i].ind]; } } IGRAPH_CHECK(igraph_i_cost_matrix(Cv, vs, n, matrix, &ps)); if (matrix == 3) { igraph_vector_destroy(&ps); IGRAPH_FINALLY_CLEAN(1); } /*------------------------------------------------- -------Fills up matrices F and Q------------------- -------------------------------------------------*/ /*here j also is a counter but the use of unsigned variables is to be proscribed in "for (unsigned int j=...;j>=0;j--)", for such loops never ends!*/ IGRAPH_MATRIX_INIT_FINALLY(&F, nt, n); IGRAPH_CHECK(igraph_matrix_int_init(&Q, nt, n)); IGRAPH_FINALLY(igraph_matrix_int_destroy, &Q); for (i = 0; i < n; i++) { MATRIX(Q, 0, i)++; } for (i = 0; i < nt; i++) { MATRIX(Q, i, i) = i + 1; } for (i = 0; i < n; i++) { MATRIX(F, 0, i) = igraph_i_real_sym_mat_get(Cv, 0, i); } for (i = 1; i < nt; i++) for (j = i + 1; j < n; j++) { MATRIX(F, i, j) = MATRIX(F, i - 1, i - 1) + igraph_i_real_sym_mat_get(Cv, i, j); MATRIX(Q, i, j) = 2; for (q = i - 1; q <= j - 1; q++) { temp = MATRIX(F, i - 1, q) + igraph_i_real_sym_mat_get(Cv, q + 1, j); if (temp < MATRIX(F, i, j)) { MATRIX(F, i, j) = temp; MATRIX(Q, i, j) = q + 2; } } } igraph_i_free_real_sym_matrix(Cv); IGRAPH_FINALLY_CLEAN(1); /*-------------------------------------------------- -------Back-tracks through Q to work out the groups- --------------------------------------------------*/ part_ind = nt; col = n - 1; for (j = nt - 1; j >= 0; j--) { for (i = MATRIX(Q, j, col) - 1; i <= col; i++) { gr[vs[i].ind] = part_ind - 1; } if (MATRIX(Q, j, col) != 2) { col = MATRIX(Q, j, col) - 2; part_ind -= 1; } else { if (j > 1) { for (l = 0; l <= (j - 1); l++) { gr[vs[l].ind] = l; } break; } else { col = MATRIX(Q, j, col) - 2; part_ind -= 1; } } } sumOfSquares = MATRIX(F, nt - 1, n - 1); igraph_matrix_destroy(&F); igraph_matrix_int_destroy(&Q); IGRAPH_FREE(vs); IGRAPH_FINALLY_CLEAN(3); if (value) { *value = sumOfSquares; } return 0; } int igraph_i_cost_matrix(igraph_real_t*Cv, const igraph_i_scg_indval_t *vs, int n, int matrix, const igraph_vector_t *ps) { /* if symmetric of Laplacian SCG -> same Cv */ if (matrix == 1 || matrix == 2) { int i, j; igraph_vector_t w, w2; IGRAPH_VECTOR_INIT_FINALLY(&w, n + 1); IGRAPH_VECTOR_INIT_FINALLY(&w2, n + 1); VECTOR(w)[1] = vs[0].val; VECTOR(w2)[1] = vs[0].val * vs[0].val; for (i = 2; i <= n; i++) { VECTOR(w)[i] = VECTOR(w)[i - 1] + vs[i - 1].val; VECTOR(w2)[i] = VECTOR(w2)[i - 1] + vs[i - 1].val * vs[i - 1].val; } for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { igraph_real_t v = (VECTOR(w2)[j + 1] - VECTOR(w2)[i]) - (VECTOR(w)[j + 1] - VECTOR(w)[i]) * (VECTOR(w)[j + 1] - VECTOR(w)[i]) / (j - i + 1); igraph_i_real_sym_mat_set(Cv, i, j, v); } } igraph_vector_destroy(&w); igraph_vector_destroy(&w2); IGRAPH_FINALLY_CLEAN(2); } /* if stochastic */ /* TODO: optimize it to O(n^2) instead of O(n^3) (as above) */ if (matrix == 3) { int i, j, k; igraph_real_t t1, t2; for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { t1 = t2 = 0; for (k = i; k < j; k++) { t1 += VECTOR(*ps)[k]; t2 += VECTOR(*ps)[k] * vs[k].val; } t1 = t2 / t1; t2 = 0; for (k = i; k < j; k++) { t2 += (vs[k].val - t1) * (vs[k].val - t1); } igraph_i_real_sym_mat_set(Cv, i, j, t2); } } } return 0; } leidenbase/src/core/layout/0000755000176200001440000000000014532173045015405 5ustar liggesusersleidenbase/src/core/layout/kamada_kawai.c0000644000176200001440000006742214447675374020177 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_interface.h" #include "igraph_paths.h" #include "igraph_random.h" #include "core/interruption.h" /** * \ingroup layout * \function igraph_layout_kamada_kawai * \brief Places the vertices on a plane according to the Kamada-Kawai algorithm. * * This is a force-directed layout. A spring is inserted between all pairs * of vertices, both those which are directly connected and those that are not. * The unstretched length of springs is chosen based on the graph distance * between the corresponding pair of vertices. Thus, in a weighted graph, increasing * the weight between two vertices pushes them apart. The Young modulus of springs * is inversely proportional to the graph distance, ensuring that springs between * far-apart veritces will have a smaller effect on the layout. * *
* This layout algorithm is not suitable for large graphs. The memory * requirements are of the order O(|V|^2). * * * Reference: * * * Kamada, T. and Kawai, S.: * An Algorithm for Drawing General Undirected Graphs. * Information Processing Letters, 31/1, 7--15, 1989. * https://doi.org/10.1016/0020-0190(89)90102-6 * * \param graph A graph object. * \param res Pointer to an initialized matrix object. This will * contain the result (x-positions in column zero and * y-positions in column one) and will be resized if needed. * \param use_seed Boolean, whether to use the values supplied in the * \p res argument as the initial configuration. If zero and there * are any limits on the X or Y coordinates, then a random initial * configuration is used. Otherwise the vertices are placed on a * circle of radius 1 as the initial configuration. * \param maxiter The maximum number of iterations to perform. A reasonable * default value is at least ten (or more) times the number of * vertices. * \param epsilon Stop the iteration, if the maximum delta value of the * algorithm is smaller than still. It is safe to leave it at zero, * and then \p maxiter iterations are performed. * \param kkconst The Kamada-Kawai vertex attraction constant. * Typical value: number of vertices. * \param weights Edge weights, larger values will result longer edges. * \param minx Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote x \endquote coordinate for every vertex. * \param maxx Same as \p minx, but the maximum \quote x \endquote * coordinates. * \param miny Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote y \endquote coordinate for every vertex. * \param maxy Same as \p miny, but the maximum \quote y \endquote * coordinates. * \return Error code. * * Time complexity: O(|V|) for each iteration, after an O(|V|^2 * log|V|) initialization step. |V| is the number of vertices in the * graph. */ int igraph_layout_kamada_kawai(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t epsilon, igraph_real_t kkconst, const igraph_vector_t *weights, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_integer_t no_edges = igraph_ecount(graph); igraph_real_t L, L0 = sqrt(no_nodes); igraph_matrix_t dij, lij, kij; igraph_real_t max_dij; igraph_vector_t D1, D2; igraph_integer_t i, j, m; if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negatice in " "Kamada-Kawai layout", IGRAPH_EINVAL); } if (kkconst <= 0) { IGRAPH_ERROR("`K' constant must be positive in Kamada-Kawai layout", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 2)) { IGRAPH_ERROR("Invalid start position matrix size in " "Kamada-Kawai layout", IGRAPH_EINVAL); } if (weights && igraph_vector_size(weights) != no_edges) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } if (minx && igraph_vector_size(minx) != no_nodes) { IGRAPH_ERROR("Invalid minx vector length", IGRAPH_EINVAL); } if (maxx && igraph_vector_size(maxx) != no_nodes) { IGRAPH_ERROR("Invalid maxx vector length", IGRAPH_EINVAL); } if (minx && maxx && !igraph_vector_all_le(minx, maxx)) { IGRAPH_ERROR("minx must not be greater than maxx", IGRAPH_EINVAL); } if (miny && igraph_vector_size(miny) != no_nodes) { IGRAPH_ERROR("Invalid miny vector length", IGRAPH_EINVAL); } if (maxy && igraph_vector_size(maxy) != no_nodes) { IGRAPH_ERROR("Invalid maxy vector length", IGRAPH_EINVAL); } if (miny && maxy && !igraph_vector_all_le(miny, maxy)) { IGRAPH_ERROR("miny must not be greater than maxy", IGRAPH_EINVAL); } if (!use_seed) { if (minx || maxx || miny || maxy) { const igraph_real_t width = sqrt(no_nodes), height = width; IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2)); RNG_BEGIN(); for (i = 0; i < no_nodes; i++) { igraph_real_t x1 = minx ? VECTOR(*minx)[i] : -width / 2; igraph_real_t x2 = maxx ? VECTOR(*maxx)[i] : width / 2; igraph_real_t y1 = miny ? VECTOR(*miny)[i] : -height / 2; igraph_real_t y2 = maxy ? VECTOR(*maxy)[i] : height / 2; if (!igraph_finite(x1)) { x1 = -width / 2; } if (!igraph_finite(x2)) { x2 = width / 2; } if (!igraph_finite(y1)) { y1 = -height / 2; } if (!igraph_finite(y2)) { y2 = height / 2; } MATRIX(*res, i, 0) = RNG_UNIF(x1, x2); MATRIX(*res, i, 1) = RNG_UNIF(y1, y2); } RNG_END(); } else { igraph_layout_circle(graph, res, /* order= */ igraph_vss_all()); } } if (no_nodes <= 1) { return 0; } IGRAPH_MATRIX_INIT_FINALLY(&dij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&kij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&lij, no_nodes, no_nodes); if (weights && no_edges > 0 && igraph_vector_min(weights) < 0) { IGRAPH_CHECK(igraph_shortest_paths_bellman_ford(graph, &dij, igraph_vss_all(), igraph_vss_all(), weights, IGRAPH_ALL)); } else { IGRAPH_CHECK(igraph_shortest_paths_dijkstra(graph, &dij, igraph_vss_all(), igraph_vss_all(), weights, IGRAPH_ALL)); } max_dij = 0.0; for (i = 0; i < no_nodes; i++) { for (j = i + 1; j < no_nodes; j++) { if (!igraph_finite(MATRIX(dij, i, j))) { continue; } if (MATRIX(dij, i, j) > max_dij) { max_dij = MATRIX(dij, i, j); } } } for (i = 0; i < no_nodes; i++) { for (j = 0; j < no_nodes; j++) { if (MATRIX(dij, i, j) > max_dij) { MATRIX(dij, i, j) = max_dij; } } } L = L0 / max_dij; for (i = 0; i < no_nodes; i++) { for (j = 0; j < no_nodes; j++) { igraph_real_t tmp = MATRIX(dij, i, j) * MATRIX(dij, i, j); if (i == j) { continue; } MATRIX(kij, i, j) = kkconst / tmp; MATRIX(lij, i, j) = L * MATRIX(dij, i, j); } } /* Initialize delta */ IGRAPH_VECTOR_INIT_FINALLY(&D1, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&D2, no_nodes); for (m = 0; m < no_nodes; m++) { igraph_real_t myD1 = 0.0, myD2 = 0.0; for (i = 0; i < no_nodes; i++) { igraph_real_t dx, dy, mi_dist; if (i == m) { continue; } dx = MATRIX(*res, m, 0) - MATRIX(*res, i, 0); dy = MATRIX(*res, m, 1) - MATRIX(*res, i, 1); mi_dist = sqrt(dx * dx + dy * dy); myD1 += MATRIX(kij, m, i) * (dx - MATRIX(lij, m, i) * dx / mi_dist); myD2 += MATRIX(kij, m, i) * (dy - MATRIX(lij, m, i) * dy / mi_dist); } VECTOR(D1)[m] = myD1; VECTOR(D2)[m] = myD2; } for (j = 0; j < maxiter; j++) { igraph_real_t myD1, myD2, A, B, C; igraph_real_t max_delta, delta_x, delta_y; igraph_real_t old_x, old_y, new_x, new_y; IGRAPH_ALLOW_INTERRUPTION(); myD1 = 0.0, myD2 = 0.0, A = 0.0, B = 0.0, C = 0.0; /* Select maximal delta */ m = 0; max_delta = -1; for (i = 0; i < no_nodes; i++) { igraph_real_t delta = (VECTOR(D1)[i] * VECTOR(D1)[i] + VECTOR(D2)[i] * VECTOR(D2)[i]); if (delta > max_delta) { m = i; max_delta = delta; } } if (max_delta < epsilon) { break; } old_x = MATRIX(*res, m, 0); old_y = MATRIX(*res, m, 1); /* Calculate D1 and D2, A, B, C */ for (i = 0; i < no_nodes; i++) { igraph_real_t dx, dy, dist, den; if (i == m) { continue; } dx = old_x - MATRIX(*res, i, 0); dy = old_y - MATRIX(*res, i, 1); dist = sqrt(dx * dx + dy * dy); den = dist * (dx * dx + dy * dy); A += MATRIX(kij, m, i) * (1 - MATRIX(lij, m, i) * dy * dy / den); B += MATRIX(kij, m, i) * MATRIX(lij, m, i) * dx * dy / den; C += MATRIX(kij, m, i) * (1 - MATRIX(lij, m, i) * dx * dx / den); } myD1 = VECTOR(D1)[m]; myD2 = VECTOR(D2)[m]; /* Need to solve some linear equations */ delta_y = (B * myD1 - myD2 * A) / (C * A - B * B); delta_x = - (myD1 + B * delta_y) / A; new_x = old_x + delta_x; new_y = old_y + delta_y; /* Limits, if given */ if (minx && new_x < VECTOR(*minx)[m]) { new_x = VECTOR(*minx)[m]; } if (maxx && new_x > VECTOR(*maxx)[m]) { new_x = VECTOR(*maxx)[m]; } if (miny && new_y < VECTOR(*miny)[m]) { new_y = VECTOR(*miny)[m]; } if (maxy && new_y > VECTOR(*maxy)[m]) { new_y = VECTOR(*maxy)[m]; } /* Update delta, only with/for the affected node */ VECTOR(D1)[m] = VECTOR(D2)[m] = 0.0; for (i = 0; i < no_nodes; i++) { igraph_real_t old_dx, old_dy, new_dx, new_dy, new_mi_dist, old_mi_dist; if (i == m) { continue; } old_dx = old_x - MATRIX(*res, i, 0); old_dy = old_y - MATRIX(*res, i, 1); old_mi_dist = sqrt(old_dx * old_dx + old_dy * old_dy); new_dx = new_x - MATRIX(*res, i, 0); new_dy = new_y - MATRIX(*res, i, 1); new_mi_dist = sqrt(new_dx * new_dx + new_dy * new_dy); VECTOR(D1)[i] -= MATRIX(kij, m, i) * (-old_dx + MATRIX(lij, m, i) * old_dx / old_mi_dist); VECTOR(D2)[i] -= MATRIX(kij, m, i) * (-old_dy + MATRIX(lij, m, i) * old_dy / old_mi_dist); VECTOR(D1)[i] += MATRIX(kij, m, i) * (-new_dx + MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[i] += MATRIX(kij, m, i) * (-new_dy + MATRIX(lij, m, i) * new_dy / new_mi_dist); VECTOR(D1)[m] += MATRIX(kij, m, i) * (new_dx - MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[m] += MATRIX(kij, m, i) * (new_dy - MATRIX(lij, m, i) * new_dy / new_mi_dist); } /* Update coordinates*/ MATRIX(*res, m, 0) = new_x; MATRIX(*res, m, 1) = new_y; } igraph_vector_destroy(&D2); igraph_vector_destroy(&D1); igraph_matrix_destroy(&lij); igraph_matrix_destroy(&kij); igraph_matrix_destroy(&dij); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \ingroup layout * \function igraph_layout_kamada_kawai_3d * \brief 3D version of the Kamada-Kawai layout generator. * * This is the 3D version of igraph_layout_kamada_kawai(). * See the documentation of that function for more information. * * * This layout algorithm is not suitable for large graphs. The memory * requirements are of the order O(|V|^2). * * \param graph A graph object. * \param res Pointer to an initialized matrix object. This will * contain the result (x-, y- and z-positions in columns one * through three) and will be resized if needed. * \param use_seed Boolean, whether to use the values supplied in the * \p res argument as the initial configuration. If zero and there * are any limits on the z, y or z coordinates, then a random initial * configuration is used. Otherwise the vertices are placed uniformly * on a sphere of radius 1 as the initial configuration. * \param maxiter The maximum number of iterations to perform. A reasonable * default value is at least ten (or more) times the number of * vertices. * \param epsilon Stop the iteration, if the maximum delta value of the * algorithm is smaller than still. It is safe to leave it at zero, * and then \p maxiter iterations are performed. * \param kkconst The Kamada-Kawai vertex attraction constant. * Typical value: number of vertices. * \param weights Edge weights, larger values will result longer edges. * \param minx Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote x \endquote coordinate for every vertex. * \param maxx Same as \p minx, but the maximum \quote x \endquote * coordinates. * \param miny Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote y \endquote coordinate for every vertex. * \param maxy Same as \p miny, but the maximum \quote y \endquote * coordinates. * \param minz Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote z \endquote coordinate for every vertex. * \param maxz Same as \p minz, but the maximum \quote z \endquote * coordinates. * \return Error code. * * Time complexity: O(|V|) for each iteration, after an O(|V|^2 * log|V|) initialization step. |V| is the number of vertices in the * graph. */ int igraph_layout_kamada_kawai_3d(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t epsilon, igraph_real_t kkconst, const igraph_vector_t *weights, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy, const igraph_vector_t *minz, const igraph_vector_t *maxz) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_integer_t no_edges = igraph_ecount(graph); igraph_real_t L, L0 = sqrt(no_nodes); igraph_matrix_t dij, lij, kij; igraph_real_t max_dij; igraph_vector_t D1, D2, D3; igraph_integer_t i, j, m; if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negatice in " "Kamada-Kawai layout", IGRAPH_EINVAL); } if (kkconst <= 0) { IGRAPH_ERROR("`K' constant must be positive in Kamada-Kawai layout", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 3)) { IGRAPH_ERROR("Invalid start position matrix size in " "3d Kamada-Kawai layout", IGRAPH_EINVAL); } if (weights && igraph_vector_size(weights) != no_edges) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } if (minx && igraph_vector_size(minx) != no_nodes) { IGRAPH_ERROR("Invalid minx vector length", IGRAPH_EINVAL); } if (maxx && igraph_vector_size(maxx) != no_nodes) { IGRAPH_ERROR("Invalid maxx vector length", IGRAPH_EINVAL); } if (minx && maxx && !igraph_vector_all_le(minx, maxx)) { IGRAPH_ERROR("minx must not be greater than maxx", IGRAPH_EINVAL); } if (miny && igraph_vector_size(miny) != no_nodes) { IGRAPH_ERROR("Invalid miny vector length", IGRAPH_EINVAL); } if (maxy && igraph_vector_size(maxy) != no_nodes) { IGRAPH_ERROR("Invalid maxy vector length", IGRAPH_EINVAL); } if (miny && maxy && !igraph_vector_all_le(miny, maxy)) { IGRAPH_ERROR("miny must not be greater than maxy", IGRAPH_EINVAL); } if (minz && igraph_vector_size(minz) != no_nodes) { IGRAPH_ERROR("Invalid minz vector length", IGRAPH_EINVAL); } if (maxz && igraph_vector_size(maxz) != no_nodes) { IGRAPH_ERROR("Invalid maxz vector length", IGRAPH_EINVAL); } if (minz && maxz && !igraph_vector_all_le(minz, maxz)) { IGRAPH_ERROR("minz must not be greater than maxz", IGRAPH_EINVAL); } if (!use_seed) { if (minx || maxx || miny || maxy || minz || maxz) { const igraph_real_t width = sqrt(no_nodes), height = width, depth = width; IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 3)); RNG_BEGIN(); for (i = 0; i < no_nodes; i++) { igraph_real_t x1 = minx ? VECTOR(*minx)[i] : -width / 2; igraph_real_t x2 = maxx ? VECTOR(*maxx)[i] : width / 2; igraph_real_t y1 = miny ? VECTOR(*miny)[i] : -height / 2; igraph_real_t y2 = maxy ? VECTOR(*maxy)[i] : height / 2; igraph_real_t z1 = minz ? VECTOR(*minz)[i] : -depth / 2; igraph_real_t z2 = maxz ? VECTOR(*maxz)[i] : depth / 2; if (!igraph_finite(x1)) { x1 = -width / 2; } if (!igraph_finite(x2)) { x2 = width / 2; } if (!igraph_finite(y1)) { y1 = -height / 2; } if (!igraph_finite(y2)) { y2 = height / 2; } if (!igraph_finite(z1)) { z1 = -depth / 2; } if (!igraph_finite(z2)) { z2 = depth / 2; } MATRIX(*res, i, 0) = RNG_UNIF(x1, x2); MATRIX(*res, i, 1) = RNG_UNIF(y1, y2); MATRIX(*res, i, 2) = RNG_UNIF(z1, z2); } RNG_END(); } else { igraph_layout_sphere(graph, res); } } if (no_nodes <= 1) { return 0; } IGRAPH_MATRIX_INIT_FINALLY(&dij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&kij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&lij, no_nodes, no_nodes); IGRAPH_CHECK(igraph_shortest_paths_dijkstra(graph, &dij, igraph_vss_all(), igraph_vss_all(), weights, IGRAPH_ALL)); max_dij = 0.0; for (i = 0; i < no_nodes; i++) { for (j = i + 1; j < no_nodes; j++) { if (!igraph_finite(MATRIX(dij, i, j))) { continue; } if (MATRIX(dij, i, j) > max_dij) { max_dij = MATRIX(dij, i, j); } } } for (i = 0; i < no_nodes; i++) { for (j = 0; j < no_nodes; j++) { if (MATRIX(dij, i, j) > max_dij) { MATRIX(dij, i, j) = max_dij; } } } L = L0 / max_dij; for (i = 0; i < no_nodes; i++) { for (j = 0; j < no_nodes; j++) { igraph_real_t tmp = MATRIX(dij, i, j) * MATRIX(dij, i, j); if (i == j) { continue; } MATRIX(kij, i, j) = kkconst / tmp; MATRIX(lij, i, j) = L * MATRIX(dij, i, j); } } /* Initialize delta */ IGRAPH_VECTOR_INIT_FINALLY(&D1, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&D2, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&D3, no_nodes); for (m = 0; m < no_nodes; m++) { igraph_real_t dx, dy, dz, mi_dist; igraph_real_t myD1 = 0.0, myD2 = 0.0, myD3 = 0.0; for (i = 0; i < no_nodes; i++) { if (i == m) { continue; } dx = MATRIX(*res, m, 0) - MATRIX(*res, i, 0); dy = MATRIX(*res, m, 1) - MATRIX(*res, i, 1); dz = MATRIX(*res, m, 2) - MATRIX(*res, i, 2); mi_dist = sqrt(dx * dx + dy * dy + dz * dz); myD1 += MATRIX(kij, m, i) * (dx - MATRIX(lij, m, i) * dx / mi_dist); myD2 += MATRIX(kij, m, i) * (dy - MATRIX(lij, m, i) * dy / mi_dist); myD3 += MATRIX(kij, m, i) * (dz - MATRIX(lij, m, i) * dz / mi_dist); } VECTOR(D1)[m] = myD1; VECTOR(D2)[m] = myD2; VECTOR(D3)[m] = myD3; } for (j = 0; j < maxiter; j++) { igraph_real_t Ax = 0.0, Ay = 0.0, Az = 0.0; igraph_real_t Axx = 0.0, Axy = 0.0, Axz = 0.0, Ayy = 0.0, Ayz = 0.0, Azz = 0.0; igraph_real_t max_delta, delta_x, delta_y, delta_z; igraph_real_t old_x, old_y, old_z, new_x, new_y, new_z; igraph_real_t detnum; IGRAPH_ALLOW_INTERRUPTION(); /* Select maximal delta */ m = 0; max_delta = -1; for (i = 0; i < no_nodes; i++) { igraph_real_t delta = (VECTOR(D1)[i] * VECTOR(D1)[i] + VECTOR(D2)[i] * VECTOR(D2)[i] + VECTOR(D3)[i] * VECTOR(D3)[i]); if (delta > max_delta) { m = i; max_delta = delta; } } if (max_delta < epsilon) { break; } old_x = MATRIX(*res, m, 0); old_y = MATRIX(*res, m, 1); old_z = MATRIX(*res, m, 2); /* Calculate D1, D2 and D3, and other coefficients */ for (i = 0; i < no_nodes; i++) { igraph_real_t dx, dy, dz, dist, den, k_mi, l_mi; if (i == m) { continue; } dx = old_x - MATRIX(*res, i, 0); dy = old_y - MATRIX(*res, i, 1); dz = old_z - MATRIX(*res, i, 2); dist = sqrt(dx * dx + dy * dy + dz * dz); den = dist * (dx * dx + dy * dy + dz * dz); k_mi = MATRIX(kij, m, i); l_mi = MATRIX(lij, m, i); Axx += k_mi * (1 - l_mi * (dy * dy + dz * dz) / den); Ayy += k_mi * (1 - l_mi * (dx * dx + dz * dz) / den); Azz += k_mi * (1 - l_mi * (dx * dx + dy * dy) / den); Axy += k_mi * l_mi * dx * dy / den; Axz += k_mi * l_mi * dx * dz / den; Ayz += k_mi * l_mi * dy * dz / den; } Ax = -VECTOR(D1)[m]; Ay = -VECTOR(D2)[m]; Az = -VECTOR(D3)[m]; /* Need to solve some linear equations, we just use Cramer's rule */ #define DET(a,b,c,d,e,f,g,h,i) ((a*e*i+b*f*g+c*d*h)-(c*e*g+b*d*i+a*f*h)) detnum = DET(Axx, Axy, Axz, Axy, Ayy, Ayz, Axz, Ayz, Azz); if (detnum != 0) { delta_x = DET(Ax, Ay, Az, Axy, Ayy, Ayz, Axz, Ayz, Azz) / detnum; delta_y = DET(Axx, Axy, Axz, Ax, Ay, Az, Axz, Ayz, Azz) / detnum; delta_z = DET(Axx, Axy, Axz, Axy, Ayy, Ayz, Ax, Ay, Az ) / detnum; } else { /* No new stable position for node m; this can happen in rare * cases, e.g., if the graph has two nodes only. It's best to leave * the node where it is. */ delta_x = delta_y = delta_z = 0; } new_x = old_x + delta_x; new_y = old_y + delta_y; new_z = old_z + delta_z; /* Limits, if given */ if (minx && new_x < VECTOR(*minx)[m]) { new_x = VECTOR(*minx)[m]; } if (maxx && new_x > VECTOR(*maxx)[m]) { new_x = VECTOR(*maxx)[m]; } if (miny && new_y < VECTOR(*miny)[m]) { new_y = VECTOR(*miny)[m]; } if (maxy && new_y > VECTOR(*maxy)[m]) { new_y = VECTOR(*maxy)[m]; } if (minz && new_z < VECTOR(*minz)[m]) { new_z = VECTOR(*minz)[m]; } if (maxz && new_z > VECTOR(*maxz)[m]) { new_z = VECTOR(*maxz)[m]; } /* Update delta, only with/for the affected node */ VECTOR(D1)[m] = VECTOR(D2)[m] = VECTOR(D3)[m] = 0.0; for (i = 0; i < no_nodes; i++) { igraph_real_t old_dx, old_dy, old_dz, old_mi_dist, new_dx, new_dy, new_dz, new_mi_dist; if (i == m) { continue; } old_dx = old_x - MATRIX(*res, i, 0); old_dy = old_y - MATRIX(*res, i, 1); old_dz = old_z - MATRIX(*res, i, 2); old_mi_dist = sqrt(old_dx * old_dx + old_dy * old_dy + old_dz * old_dz); new_dx = new_x - MATRIX(*res, i, 0); new_dy = new_y - MATRIX(*res, i, 1); new_dz = new_z - MATRIX(*res, i, 2); new_mi_dist = sqrt(new_dx * new_dx + new_dy * new_dy + new_dz * new_dz); VECTOR(D1)[i] -= MATRIX(kij, m, i) * (-old_dx + MATRIX(lij, m, i) * old_dx / old_mi_dist); VECTOR(D2)[i] -= MATRIX(kij, m, i) * (-old_dy + MATRIX(lij, m, i) * old_dy / old_mi_dist); VECTOR(D3)[i] -= MATRIX(kij, m, i) * (-old_dz + MATRIX(lij, m, i) * old_dz / old_mi_dist); VECTOR(D1)[i] += MATRIX(kij, m, i) * (-new_dx + MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[i] += MATRIX(kij, m, i) * (-new_dy + MATRIX(lij, m, i) * new_dy / new_mi_dist); VECTOR(D3)[i] += MATRIX(kij, m, i) * (-new_dz + MATRIX(lij, m, i) * new_dz / new_mi_dist); VECTOR(D1)[m] += MATRIX(kij, m, i) * (new_dx - MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[m] += MATRIX(kij, m, i) * (new_dy - MATRIX(lij, m, i) * new_dy / new_mi_dist); VECTOR(D3)[m] += MATRIX(kij, m, i) * (new_dz - MATRIX(lij, m, i) * new_dz / new_mi_dist); } /* Update coordinates*/ MATRIX(*res, m, 0) = new_x; MATRIX(*res, m, 1) = new_y; MATRIX(*res, m, 2) = new_z; } igraph_vector_destroy(&D3); igraph_vector_destroy(&D2); igraph_vector_destroy(&D1); igraph_matrix_destroy(&lij); igraph_matrix_destroy(&kij); igraph_matrix_destroy(&dij); IGRAPH_FINALLY_CLEAN(6); return 0; } leidenbase/src/core/layout/large_graph.c0000644000176200001440000003255014447675374020052 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "igraph_random.h" #include "igraph_structural.h" #include "igraph_visitor.h" #include "core/grid.h" #include "core/interruption.h" #include "core/math.h" static void igraph_i_norm2d(igraph_real_t *x, igraph_real_t *y) { igraph_real_t len = sqrt((*x) * (*x) + (*y) * (*y)); if (len != 0) { *x /= len; *y /= len; } } /** * \function igraph_layout_lgl * \brief Force based layout algorithm for large graphs. * * * This is a layout generator similar to the Large Graph Layout * algorithm and program * (http://lgl.sourceforge.net/). But unlike LGL, this * version uses a Fruchterman-Reingold style simulated annealing * algorithm for placing the vertices. The speedup is achieved by * placing the vertices on a grid and calculating the repulsion only * for vertices which are closer to each other than a limit. * * \param graph The (initialized) graph object to place. * \param res Pointer to an initialized matrix object to hold the * result. It will be resized if needed. * \param maxit The maximum number of cooling iterations to perform * for each layout step. A reasonable default is 150. * \param maxdelta The maximum length of the move allowed for a vertex * in a single iteration. A reasonable default is the number of * vertices. * \param area This parameter gives the area of the square on which * the vertices will be placed. A reasonable default value is the * number of vertices squared. * \param coolexp The cooling exponent. A reasonable default value is * 1.5. * \param repulserad Determines the radius at which vertex-vertex * repulsion cancels out attraction of adjacent vertices. A * reasonable default value is \p area times the number of vertices. * \param cellsize The size of the grid cells, one side of the * square. A reasonable default value is the fourth root of * \p area (or the square root of the number of vertices if \p area * is also left at its default value). * \param proot The root vertex, this is placed first, its neighbors * in the first iteration, second neighbors in the second, etc. If * negative then a random vertex is chosen. * \return Error code. * * Added in version 0.2. * * Time complexity: ideally O(dia*maxit*(|V|+|E|)), |V| is the number * of vertices, * dia is the diameter of the graph, worst case complexity is still * O(dia*maxit*(|V|^2+|E|)), this is the case when all vertices happen to be * in the same grid cell. */ int igraph_layout_lgl(const igraph_t *graph, igraph_matrix_t *res, igraph_integer_t maxit, igraph_real_t maxdelta, igraph_real_t area, igraph_real_t coolexp, igraph_real_t repulserad, igraph_real_t cellsize, igraph_integer_t proot) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_t mst; long int root; long int no_of_layers, actlayer = 0; igraph_vector_t vids; igraph_vector_t layers; igraph_vector_t parents; igraph_vector_t edges; igraph_2dgrid_t grid; igraph_vector_t eids; igraph_vector_t forcex; igraph_vector_t forcey; igraph_real_t frk = sqrt(area / no_of_nodes); igraph_real_t H_n = 0; IGRAPH_CHECK(igraph_minimum_spanning_tree_unweighted(graph, &mst)); IGRAPH_FINALLY(igraph_destroy, &mst); IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 2)); /* Determine the root vertex, random pick right now */ if (proot < 0) { root = RNG_INTEGER(0, no_of_nodes - 1); } else { root = proot; } /* Assign the layers */ IGRAPH_VECTOR_INIT_FINALLY(&vids, 0); IGRAPH_VECTOR_INIT_FINALLY(&layers, 0); IGRAPH_VECTOR_INIT_FINALLY(&parents, 0); IGRAPH_CHECK(igraph_bfs_simple(&mst, (igraph_integer_t) root, IGRAPH_ALL, &vids, &layers, &parents)); no_of_layers = igraph_vector_size(&layers) - 1; /* We don't need the mst any more */ igraph_destroy(&mst); igraph_empty(&mst, 0, IGRAPH_UNDIRECTED); /* to make finalization work */ IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges)); IGRAPH_VECTOR_INIT_FINALLY(&eids, 0); IGRAPH_VECTOR_INIT_FINALLY(&forcex, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&forcey, no_of_nodes); /* Place the vertices randomly */ IGRAPH_CHECK(igraph_layout_random(graph, res)); igraph_matrix_scale(res, 1e6); /* This is the grid for calculating the vertices near to a given vertex */ IGRAPH_CHECK(igraph_2dgrid_init(&grid, res, -sqrt(area / M_PI), sqrt(area / M_PI), cellsize, -sqrt(area / M_PI), sqrt(area / M_PI), cellsize)); IGRAPH_FINALLY(igraph_2dgrid_destroy, &grid); /* Place the root vertex */ igraph_2dgrid_add(&grid, root, 0, 0); for (actlayer = 1; actlayer < no_of_layers; actlayer++) { H_n += 1.0 / actlayer; } for (actlayer = 1; actlayer < no_of_layers; actlayer++) { igraph_real_t c = 1; long int i, j; igraph_real_t massx, massy; igraph_real_t px, py; igraph_real_t sx, sy; long int it = 0; igraph_real_t epsilon = 10e-6; igraph_real_t maxchange = epsilon + 1; long int pairs; igraph_real_t sconst = sqrt(area / M_PI) / H_n; igraph_2dgrid_iterator_t vidit; /* printf("Layer %li:\n", actlayer); */ /*-----------------------------------------*/ /* Step 1: place the next layer on spheres */ /*-----------------------------------------*/ RNG_BEGIN(); j = (long int) VECTOR(layers)[actlayer]; for (i = (long int) VECTOR(layers)[actlayer - 1]; i < VECTOR(layers)[actlayer]; i++) { long int vid = (long int) VECTOR(vids)[i]; long int par = (long int) VECTOR(parents)[vid]; IGRAPH_ALLOW_INTERRUPTION(); igraph_2dgrid_getcenter(&grid, &massx, &massy); igraph_i_norm2d(&massx, &massy); px = MATRIX(*res, vid, 0) - MATRIX(*res, par, 0); py = MATRIX(*res, vid, 1) - MATRIX(*res, par, 1); igraph_i_norm2d(&px, &py); sx = c * (massx + px) + MATRIX(*res, vid, 0); sy = c * (massy + py) + MATRIX(*res, vid, 1); /* The neighbors of 'vid' */ while (j < VECTOR(layers)[actlayer + 1] && VECTOR(parents)[(long int)VECTOR(vids)[j]] == vid) { igraph_real_t rx, ry; if (actlayer == 1) { igraph_real_t phi = 2 * M_PI / (VECTOR(layers)[2] - 1) * (j - 1); rx = cos(phi); ry = sin(phi); } else { rx = RNG_UNIF(-1, 1); ry = RNG_UNIF(-1, 1); } igraph_i_norm2d(&rx, &ry); rx = rx / actlayer * sconst; ry = ry / actlayer * sconst; igraph_2dgrid_add(&grid, (long int) VECTOR(vids)[j], sx + rx, sy + ry); j++; } } RNG_END(); /*-----------------------------------------*/ /* Step 2: add the edges of the next layer */ /*-----------------------------------------*/ for (j = (long int) VECTOR(layers)[actlayer]; j < VECTOR(layers)[actlayer + 1]; j++) { long int vid = (long int) VECTOR(vids)[j]; long int k; IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_incident(graph, &eids, (igraph_integer_t) vid, IGRAPH_ALL)); for (k = 0; k < igraph_vector_size(&eids); k++) { long int eid = (long int) VECTOR(eids)[k]; igraph_integer_t from, to; igraph_edge(graph, (igraph_integer_t) eid, &from, &to); if ((from != vid && igraph_2dgrid_in(&grid, from)) || (to != vid && igraph_2dgrid_in(&grid, to))) { igraph_vector_push_back(&edges, eid); } } } /*-----------------------------------------*/ /* Step 3: let the springs spring */ /*-----------------------------------------*/ maxchange = epsilon + 1; while (it < maxit && maxchange > epsilon) { long int jj; igraph_real_t t = maxdelta * pow((maxit - it) / (double)maxit, coolexp); long int vid, nei; IGRAPH_PROGRESS("Large graph layout", 100.0 * ((actlayer - 1.0) / (no_of_layers - 1.0) + ((float)it) / (maxit * (no_of_layers - 1.0))), 0); /* init */ igraph_vector_null(&forcex); igraph_vector_null(&forcey); maxchange = 0; /* attractive "forces" along the edges */ for (jj = 0; jj < igraph_vector_size(&edges); jj++) { igraph_integer_t from, to; igraph_real_t xd, yd, dist, force; IGRAPH_ALLOW_INTERRUPTION(); igraph_edge(graph, (igraph_integer_t) VECTOR(edges)[jj], &from, &to); xd = MATRIX(*res, (long int)from, 0) - MATRIX(*res, (long int)to, 0); yd = MATRIX(*res, (long int)from, 1) - MATRIX(*res, (long int)to, 1); dist = sqrt(xd * xd + yd * yd); if (dist != 0) { xd /= dist; yd /= dist; } force = dist * dist / frk; VECTOR(forcex)[(long int)from] -= xd * force; VECTOR(forcex)[(long int)to] += xd * force; VECTOR(forcey)[(long int)from] -= yd * force; VECTOR(forcey)[(long int)to] += yd * force; } /* repulsive "forces" of the vertices nearby */ pairs = 0; igraph_2dgrid_reset(&grid, &vidit); while ( (vid = igraph_2dgrid_next(&grid, &vidit) - 1) != -1) { while ( (nei = igraph_2dgrid_next_nei(&grid, &vidit) - 1) != -1) { igraph_real_t xd = MATRIX(*res, (long int)vid, 0) - MATRIX(*res, (long int)nei, 0); igraph_real_t yd = MATRIX(*res, (long int)vid, 1) - MATRIX(*res, (long int)nei, 1); igraph_real_t dist = sqrt(xd * xd + yd * yd); igraph_real_t force; if (dist < cellsize) { pairs++; if (dist == 0) { dist = epsilon; }; xd /= dist; yd /= dist; force = frk * frk * (1.0 / dist - dist * dist / repulserad); VECTOR(forcex)[(long int)vid] += xd * force; VECTOR(forcex)[(long int)nei] -= xd * force; VECTOR(forcey)[(long int)vid] += yd * force; VECTOR(forcey)[(long int)nei] -= yd * force; } } } /* printf("verties: %li iterations: %li\n", */ /* (long int) VECTOR(layers)[actlayer+1], pairs); */ /* apply the changes */ for (jj = 0; jj < VECTOR(layers)[actlayer + 1]; jj++) { long int vvid = (long int) VECTOR(vids)[jj]; igraph_real_t fx = VECTOR(forcex)[vvid]; igraph_real_t fy = VECTOR(forcey)[vvid]; igraph_real_t ded = sqrt(fx * fx + fy * fy); if (ded > t) { ded = t / ded; fx *= ded; fy *= ded; } igraph_2dgrid_move(&grid, vvid, fx, fy); if (fx > maxchange) { maxchange = fx; } if (fy > maxchange) { maxchange = fy; } } it++; /* printf("%li iterations, maxchange: %f\n", it, (double)maxchange); */ } } IGRAPH_PROGRESS("Large graph layout", 100.0, 0); igraph_destroy(&mst); igraph_vector_destroy(&vids); igraph_vector_destroy(&layers); igraph_vector_destroy(&parents); igraph_vector_destroy(&edges); igraph_2dgrid_destroy(&grid); igraph_vector_destroy(&eids); igraph_vector_destroy(&forcex); igraph_vector_destroy(&forcey); IGRAPH_FINALLY_CLEAN(9); return 0; } leidenbase/src/core/layout/layout_bipartite.c0000644000176200001440000000606414447675374021160 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_interface.h" /** * \function igraph_layout_bipartite * Simple layout for bipartite graphs. * * The layout is created by first placing the vertices in two rows, * according to their types. Then the positions within the rows are * optimized to minimize edge crossings, by calling \ref * igraph_layout_sugiyama(). * * \param graph The input graph. * \param types A boolean vector containing ones and zeros, the vertex * types. Its length must match the number of vertices in the graph. * \param res Pointer to an initialized matrix, the result, the x and * y coordinates are stored here. * \param hgap The preferred minimum horizontal gap between vertices * in the same layer (i.e. vertices of the same type). * \param vgap The distance between layers. * \param maxiter Maximum number of iterations in the crossing * minimization stage. 100 is a reasonable default; if you feel * that you have too many edge crossings, increase this. * \return Error code. * * \sa \ref igraph_layout_sugiyama(). */ int igraph_layout_bipartite(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_matrix_t *res, igraph_real_t hgap, igraph_real_t vgap, long int maxiter) { long int i, no_of_nodes = igraph_vcount(graph); igraph_vector_t layers; if (igraph_vector_bool_size(types) != no_of_nodes) { IGRAPH_ERRORF("The vertex type vector size (%ld) should be equal to the number of nodes (%ld).", IGRAPH_EINVAL, igraph_vector_bool_size(types), no_of_nodes); } if (hgap < 0) { IGRAPH_ERRORF("The horizontal gap cannot be negative, got %f.", IGRAPH_EINVAL, hgap); } IGRAPH_VECTOR_INIT_FINALLY(&layers, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { VECTOR(layers)[i] = VECTOR(*types)[i] ? 0 : 1; } IGRAPH_CHECK(igraph_layout_sugiyama(graph, res, /*extd_graph=*/ 0, /*extd_to_orig_eids=*/ 0, &layers, hgap, vgap, maxiter, /*weights=*/ 0)); igraph_vector_destroy(&layers); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/layout/merge_grid.c0000644000176200001440000001502614447675374017702 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph package. Copyright (C) 2006-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_memory.h" #include "layout/merge_grid.h" static int igraph_i_layout_mergegrid_which(igraph_i_layout_mergegrid_t *grid, igraph_real_t xc, igraph_real_t yc, long int *x, long int *y) { if (xc <= grid->minx) { *x = 0; } else if (xc >= grid->maxx) { *x = grid->stepsx - 1; } else { *x = (long int) floor((xc - (grid->minx)) / (grid->deltax)); } if (yc <= grid->miny) { *y = 0; } else if (yc >= grid->maxy) { *y = grid->stepsy - 1; } else { *y = (long int) floor((yc - (grid->miny)) / (grid->deltay)); } return 0; } int igraph_i_layout_mergegrid_init(igraph_i_layout_mergegrid_t *grid, igraph_real_t minx, igraph_real_t maxx, long int stepsx, igraph_real_t miny, igraph_real_t maxy, long int stepsy) { grid->minx = minx; grid->maxx = maxx; grid->stepsx = stepsx; grid->deltax = (maxx - minx) / stepsx; grid->miny = miny; grid->maxy = maxy; grid->stepsy = stepsy; grid->deltay = (maxy - miny) / stepsy; grid->data = IGRAPH_CALLOC(stepsx * stepsy, long int); if (grid->data == 0) { IGRAPH_ERROR("Cannot create grid", IGRAPH_ENOMEM); } return 0; } void igraph_i_layout_mergegrid_destroy(igraph_i_layout_mergegrid_t *grid) { IGRAPH_FREE(grid->data); } #define MAT(i,j) (grid->data[(grid->stepsy)*(j)+(i)]) #define DIST2(x2,y2) (sqrt(pow(x-(x2),2)+pow(y-(y2), 2))) int igraph_i_layout_merge_place_sphere(igraph_i_layout_mergegrid_t *grid, igraph_real_t x, igraph_real_t y, igraph_real_t r, long int id) { long int cx, cy; long int i, j; igraph_i_layout_mergegrid_which(grid, x, y, &cx, &cy); MAT(cx, cy) = id + 1; #define DIST(i,j) (DIST2(grid->minx+(cx+(i))*grid->deltax, \ grid->miny+(cy+(j))*grid->deltay)) for (i = 0; cx + i < grid->stepsx && DIST(i, 0) < r; i++) { for (j = 0; cy + j < grid->stepsy && DIST(i, j) < r; j++) { MAT(cx + i, cy + j) = id + 1; } } #undef DIST #define DIST(i,j) (DIST2(grid->minx+(cx+(i))*grid->deltax, \ grid->miny+(cy-(j)+1)*grid->deltay)) for (i = 0; cx + i < grid->stepsx && DIST(i, 0) < r; i++) { for (j = 1; cy - j > 0 && DIST(i, j) < r; j++) { MAT(cx + i, cy - j) = id + 1; } } #undef DIST #define DIST(i,j) (DIST2(grid->minx+(cx-(i)+1)*grid->deltax, \ grid->miny+(cy+(j))*grid->deltay)) for (i = 1; cx - i > 0 && DIST(i, 0) < r; i++) { for (j = 0; cy + j < grid->stepsy && DIST(i, j) < r; j++) { MAT(cx - i, cy + j) = id + 1; } } #undef DIST #define DIST(i,j) (DIST2(grid->minx+(cx-(i)+1)*grid->deltax, \ grid->miny+(cy-(j)+1)*grid->deltay)) for (i = 1; cx - i > 0 && DIST(i, 0) < r; i++) { for (j = 1; cy - j > 0 && DIST(i, j) < r; j++) { MAT(cx - i, cy - j) = id + 1; } } #undef DIST #undef DIST2 return 0; } long int igraph_i_layout_mergegrid_get(igraph_i_layout_mergegrid_t *grid, igraph_real_t x, igraph_real_t y) { long int cx, cy; long int res; if (x <= grid->minx || x >= grid->maxx || y <= grid->miny || y >= grid->maxy) { res = -1; } else { igraph_i_layout_mergegrid_which(grid, x, y, &cx, &cy); res = MAT(cx, cy) - 1; } return res; } #define DIST2(x2,y2) (sqrt(pow(x-(x2),2)+pow(y-(y2), 2))) long int igraph_i_layout_mergegrid_get_sphere(igraph_i_layout_mergegrid_t *grid, igraph_real_t x, igraph_real_t y, igraph_real_t r) { long int cx, cy; long int i, j; long int ret; if (x - r <= grid->minx || x + r >= grid->maxx || y - r <= grid->miny || y + r >= grid->maxy) { ret = -1; } else { igraph_i_layout_mergegrid_which(grid, x, y, &cx, &cy); ret = MAT(cx, cy) - 1; #define DIST(i,j) (DIST2(grid->minx+(cx+(i))*grid->deltax, \ grid->miny+(cy+(j))*grid->deltay)) for (i = 0; ret < 0 && cx + i < grid->stepsx && DIST(i, 0) < r; i++) { for (j = 0; ret < 0 && cy + j < grid->stepsy && DIST(i, j) < r; j++) { ret = MAT(cx + i, cy + j) - 1; } } #undef DIST #define DIST(i,j) (DIST2(grid->minx+(cx+(i))*grid->deltax, \ grid->miny+(cy-(j)+1)*grid->deltay)) for (i = 0; ret < 0 && cx + i < grid->stepsx && DIST(i, 0) < r; i++) { for (j = 1; ret < 0 && cy - j > 0 && DIST(i, j) < r; j++) { ret = MAT(cx + i, cy - j) - 1; } } #undef DIST #define DIST(i,j) (DIST2(grid->minx+(cx-(i)+1)*grid->deltax, \ grid->miny+(cy+(j))*grid->deltay)) for (i = 1; ret < 0 && cx - i > 0 && DIST(i, 0) < r; i++) { for (j = 0; ret < 0 && cy + j < grid->stepsy && DIST(i, j) < r; j++) { ret = MAT(cx - i, cy + j) - 1; } } #undef DIST #define DIST(i,j) (DIST2(grid->minx+(cx-(i)+1)*grid->deltax, \ grid->miny+(cy-(j)+1)*grid->deltay)) for (i = 1; ret < 0 && cx + i > 0 && DIST(i, 0) < r; i++) { for (j = 1; ret < 0 && cy + i > 0 && DIST(i, j) < r; j++) { ret = MAT(cx - i, cy - j) - 1; } } #undef DIST } return ret; } /* int print_grid(igraph_i_layout_mergegrid_t *grid) { */ /* long int i,j; */ /* for (i=0; istepsx; i++) { */ /* for (j=0; jstepsy; j++) { */ /* printf("%li ", MAT(i,j)-1); */ /* } */ /* printf("\n"); */ /* } */ /* } */ leidenbase/src/core/layout/gem.c0000644000176200001440000002257414447675374016354 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_interface.h" #include "igraph_random.h" #include "core/math.h" #include "core/interruption.h" /** * \ingroup layout * \function igraph_layout_gem * * The GEM layout algorithm, as described in Arne Frick, Andreas Ludwig, * Heiko Mehldau: A Fast Adaptive Layout Algorithm for Undirected Graphs, * Proc. Graph Drawing 1994, LNCS 894, pp. 388-403, 1995. * \param graph The input graph. Edge directions are ignored in * directed graphs. * \param res The result is stored here. If the \p use_seed argument * is true (non-zero), then this matrix is also used as the * starting point of the algorithm. * \param use_seed Boolean, whether to use the supplied coordinates in * \p res as the starting point. If false (zero), then a * uniform random starting point is used. * \param maxiter The maximum number of iterations to * perform. Updating a single vertex counts as an iteration. * A reasonable default is 40 * n * n, where n is the number of * vertices. The original paper suggests 4 * n * n, but this * usually only works if the other parameters are set up carefully. * \param temp_max The maximum allowed local temperature. A reasonable * default is the number of vertices. * \param temp_min The global temperature at which the algorithm * terminates (even before reaching \p maxiter iterations). A * reasonable default is 1/10. * \param temp_init Initial local temperature of all vertices. A * reasonable default is the square root of the number of * vertices. * \return Error code. * * Time complexity: O(t * n * (n+e)), where n is the number of vertices, * e is the number of edges and t is the number of time steps * performed. */ int igraph_layout_gem(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t temp_max, igraph_real_t temp_min, igraph_real_t temp_init) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_vector_int_t perm; igraph_vector_float_t impulse_x, impulse_y, temp, skew_gauge; igraph_integer_t i; float temp_global; igraph_integer_t perm_pointer = 0; float barycenter_x = 0, barycenter_y = 0; igraph_vector_t phi; igraph_vector_t neis; const float elen_des2 = 128 * 128; const float gamma = 1 / 16.0f; const float alpha_o = (float)M_PI; const float alpha_r = (float)M_PI / 3.0f; const float sigma_o = 1.0f / 3.0f; const float sigma_r = 1.0f / 2.0f / no_nodes; if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negative in GEM layout", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 2)) { IGRAPH_ERROR("Invalid start position matrix size in GEM layout", IGRAPH_EINVAL); } if (temp_max <= 0) { IGRAPH_ERROR("Maximum temperature should be positive in GEM layout", IGRAPH_EINVAL); } if (temp_min <= 0) { IGRAPH_ERROR("Minimum temperature should be positive in GEM layout", IGRAPH_EINVAL); } if (temp_init <= 0) { IGRAPH_ERROR("Initial temperature should be positive in GEM layout", IGRAPH_EINVAL); } if (temp_max < temp_init || temp_init < temp_min) { IGRAPH_ERROR("Minimum <= Initial <= Maximum temperature is required " "in GEM layout", IGRAPH_EINVAL); } if (no_nodes == 0) { return 0; } IGRAPH_CHECK(igraph_vector_float_init(&impulse_x, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &impulse_x); IGRAPH_CHECK(igraph_vector_float_init(&impulse_y, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &impulse_y); IGRAPH_CHECK(igraph_vector_float_init(&temp, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &temp); IGRAPH_CHECK(igraph_vector_float_init(&skew_gauge, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &skew_gauge); IGRAPH_CHECK(igraph_vector_int_init_seq(&perm, 0, no_nodes - 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &perm); IGRAPH_VECTOR_INIT_FINALLY(&phi, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis, 10); RNG_BEGIN(); /* Initialization */ igraph_degree(graph, &phi, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS); if (!use_seed) { const igraph_real_t width_half = no_nodes * 100, height_half = width_half; IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2)); for (i = 0; i < no_nodes; i++) { MATRIX(*res, i, 0) = RNG_UNIF(-width_half, width_half); MATRIX(*res, i, 1) = RNG_UNIF(-height_half, height_half); barycenter_x += MATRIX(*res, i, 0); barycenter_y += MATRIX(*res, i, 1); VECTOR(phi)[i] *= (VECTOR(phi)[i] / 2.0 + 1.0); } } else { for (i = 0; i < no_nodes; i++) { barycenter_x += MATRIX(*res, i, 0); barycenter_y += MATRIX(*res, i, 1); VECTOR(phi)[i] *= (VECTOR(phi)[i] / 2.0 + 1.0); } } igraph_vector_float_fill(&temp, temp_init); temp_global = temp_init * no_nodes; while (temp_global > temp_min * no_nodes && maxiter > 0) { igraph_integer_t u, v, nlen, j; float px, py, pvx, pvy; IGRAPH_ALLOW_INTERRUPTION(); /* choose a vertex v to update */ if (!perm_pointer) { igraph_vector_int_shuffle(&perm); perm_pointer = no_nodes - 1; } v = VECTOR(perm)[perm_pointer--]; /* compute v's impulse */ px = (barycenter_x / no_nodes - MATRIX(*res, v, 0)) * gamma * VECTOR(phi)[v]; py = (barycenter_y / no_nodes - MATRIX(*res, v, 1)) * gamma * VECTOR(phi)[v]; px += RNG_UNIF(-32.0, 32.0); py += RNG_UNIF(-32.0, 32.0); for (u = 0; u < no_nodes; u++) { float dx, dy, dist2; if (u == v) { continue; } dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); dist2 = dx * dx + dy * dy; if (dist2 != 0) { px += dx * elen_des2 / dist2; py += dy * elen_des2 / dist2; } } IGRAPH_CHECK(igraph_neighbors(graph, &neis, v, IGRAPH_ALL)); nlen = igraph_vector_size(&neis); for (j = 0; j < nlen; j++) { igraph_integer_t u = VECTOR(neis)[j]; float dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); float dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); float dist2 = dx * dx + dy * dy; px -= dx * dist2 / (elen_des2 * VECTOR(phi)[v]); py -= dy * dist2 / (elen_des2 * VECTOR(phi)[v]); } /* update v's position and temperature */ if (px != 0 || py != 0) { float plen = sqrtf(px * px + py * py); px *= VECTOR(temp)[v] / plen; py *= VECTOR(temp)[v] / plen; MATRIX(*res, v, 0) += px; MATRIX(*res, v, 1) += py; barycenter_x += px; barycenter_y += py; } pvx = VECTOR(impulse_x)[v]; pvy = VECTOR(impulse_y)[v]; if (pvx != 0 || pvy != 0) { float beta = atan2f(pvy - py, pvx - px); float sin_beta = sinf(beta); float sign_sin_beta = (sin_beta > 0) ? 1 : ((sin_beta < 0) ? -1 : 0); float cos_beta = cosf(beta); float abs_cos_beta = fabsf(cos_beta); float old_temp = VECTOR(temp)[v]; if (sin(beta) >= sin(M_PI_2 + alpha_r / 2.0)) { VECTOR(skew_gauge)[v] += sigma_r * sign_sin_beta; } if (abs_cos_beta >= cosf(alpha_o / 2.0)) { VECTOR(temp)[v] *= sigma_o * cos_beta; } VECTOR(temp)[v] *= (1 - fabsf(VECTOR(skew_gauge)[v])); if (VECTOR(temp)[v] > temp_max) { VECTOR(temp)[v] = temp_max; } VECTOR(impulse_x)[v] = px; VECTOR(impulse_y)[v] = py; temp_global += VECTOR(temp)[v] - old_temp; } maxiter--; } /* while temp && iter */ RNG_END(); igraph_vector_destroy(&neis); igraph_vector_destroy(&phi); igraph_vector_int_destroy(&perm); igraph_vector_float_destroy(&skew_gauge); igraph_vector_float_destroy(&temp); igraph_vector_float_destroy(&impulse_y); igraph_vector_float_destroy(&impulse_x); IGRAPH_FINALLY_CLEAN(7); return 0; } leidenbase/src/core/layout/merge_dla.c0000644000176200001440000002324514447675374017517 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_progress.h" #include "igraph_random.h" #include "core/grid.h" #include "core/interruption.h" #include "core/math.h" #include "layout/merge_grid.h" #include "layout/layout_internal.h" /** * \function igraph_layout_merge_dla * \brief Merge multiple layouts by using a DLA algorithm * * * First each layout is covered by a circle. Then the layout of the * largest graph is placed at the origin. Then the other layouts are * placed by the DLA algorithm, larger ones first and smaller ones * last. * \param thegraphs Pointer vector containing the graph objects of * which the layouts will be merged. * \param coords Pointer vector containing matrix objects with the 2d * layouts of the graphs in \p thegraphs. * \param res Pointer to an initialized matrix object, the result will * be stored here. It will be resized if needed. * \return Error code. * * Added in version 0.2. This function is experimental. * * * Time complexity: TODO. */ int igraph_layout_merge_dla(const igraph_vector_ptr_t *thegraphs, const igraph_vector_ptr_t *coords, igraph_matrix_t *res) { long int graphs = igraph_vector_ptr_size(coords); igraph_vector_t sizes; igraph_vector_t x, y, r; igraph_vector_t nx, ny, nr; long int allnodes = 0; long int i, j; long int actg; igraph_i_layout_mergegrid_t grid; long int jpos = 0; igraph_real_t minx, maxx, miny, maxy; igraph_real_t area = 0; igraph_real_t maxr = 0; long int respos; /* Graphs are currently not used, only the coordinates */ IGRAPH_UNUSED(thegraphs); IGRAPH_VECTOR_INIT_FINALLY(&sizes, graphs); IGRAPH_VECTOR_INIT_FINALLY(&x, graphs); IGRAPH_VECTOR_INIT_FINALLY(&y, graphs); IGRAPH_VECTOR_INIT_FINALLY(&r, graphs); IGRAPH_VECTOR_INIT_FINALLY(&nx, graphs); IGRAPH_VECTOR_INIT_FINALLY(&ny, graphs); IGRAPH_VECTOR_INIT_FINALLY(&nr, graphs); RNG_BEGIN(); for (i = 0; i < igraph_vector_ptr_size(coords); i++) { igraph_matrix_t *mat = VECTOR(*coords)[i]; long int size = igraph_matrix_nrow(mat); if (igraph_matrix_ncol(mat) != 2) { IGRAPH_ERROR("igraph_layout_merge_dla works for 2D layouts only", IGRAPH_EINVAL); } IGRAPH_ALLOW_INTERRUPTION(); allnodes += size; VECTOR(sizes)[i] = size; VECTOR(r)[i] = pow(size, .75); area += VECTOR(r)[i] * VECTOR(r)[i]; if (VECTOR(r)[i] > maxr) { maxr = VECTOR(r)[i]; } igraph_i_layout_sphere_2d(mat, igraph_vector_e_ptr(&nx, i), igraph_vector_e_ptr(&ny, i), igraph_vector_e_ptr(&nr, i)); } igraph_vector_order2(&sizes); /* largest first */ /* 0. create grid */ minx = miny = -sqrt(5 * area); maxx = maxy = sqrt(5 * area); igraph_i_layout_mergegrid_init(&grid, minx, maxx, 200, miny, maxy, 200); IGRAPH_FINALLY(igraph_i_layout_mergegrid_destroy, &grid); /* fprintf(stderr, "Ok, starting DLA\n"); */ /* 1. place the largest */ actg = (long int) VECTOR(sizes)[jpos++]; igraph_i_layout_merge_place_sphere(&grid, 0, 0, VECTOR(r)[actg], actg); IGRAPH_PROGRESS("Merging layouts via DLA", 0.0, NULL); while (jpos < graphs) { IGRAPH_ALLOW_INTERRUPTION(); /* fprintf(stderr, "comp: %li", jpos); */ IGRAPH_PROGRESS("Merging layouts via DLA", (100.0 * jpos) / graphs, NULL); actg = (long int) VECTOR(sizes)[jpos++]; /* 2. random walk, TODO: tune parameters */ igraph_i_layout_merge_dla(&grid, actg, igraph_vector_e_ptr(&x, actg), igraph_vector_e_ptr(&y, actg), VECTOR(r)[actg], 0, 0, maxx, maxx + 5); /* 3. place sphere */ igraph_i_layout_merge_place_sphere(&grid, VECTOR(x)[actg], VECTOR(y)[actg], VECTOR(r)[actg], actg); } IGRAPH_PROGRESS("Merging layouts via DLA", 100.0, NULL); /* Create the result */ IGRAPH_CHECK(igraph_matrix_resize(res, allnodes, 2)); respos = 0; for (i = 0; i < graphs; i++) { long int size = igraph_matrix_nrow(VECTOR(*coords)[i]); igraph_real_t xx = VECTOR(x)[i]; igraph_real_t yy = VECTOR(y)[i]; igraph_real_t rr = VECTOR(r)[i] / VECTOR(nr)[i]; igraph_matrix_t *mat = VECTOR(*coords)[i]; IGRAPH_ALLOW_INTERRUPTION(); if (VECTOR(nr)[i] == 0) { rr = 1; } for (j = 0; j < size; j++) { MATRIX(*res, respos, 0) = rr * (MATRIX(*mat, j, 0) - VECTOR(nx)[i]); MATRIX(*res, respos, 1) = rr * (MATRIX(*mat, j, 1) - VECTOR(ny)[i]); MATRIX(*res, respos, 0) += xx; MATRIX(*res, respos, 1) += yy; ++respos; } } RNG_END(); igraph_i_layout_mergegrid_destroy(&grid); igraph_vector_destroy(&sizes); igraph_vector_destroy(&x); igraph_vector_destroy(&y); igraph_vector_destroy(&r); igraph_vector_destroy(&nx); igraph_vector_destroy(&ny); igraph_vector_destroy(&nr); IGRAPH_FINALLY_CLEAN(8); return 0; } int igraph_i_layout_sphere_2d(igraph_matrix_t *coords, igraph_real_t *x, igraph_real_t *y, igraph_real_t *r) { long int nodes = igraph_matrix_nrow(coords); long int i; igraph_real_t xmin, xmax, ymin, ymax; xmin = xmax = MATRIX(*coords, 0, 0); ymin = ymax = MATRIX(*coords, 0, 1); for (i = 1; i < nodes; i++) { if (MATRIX(*coords, i, 0) < xmin) { xmin = MATRIX(*coords, i, 0); } else if (MATRIX(*coords, i, 0) > xmax) { xmax = MATRIX(*coords, i, 0); } if (MATRIX(*coords, i, 1) < ymin) { ymin = MATRIX(*coords, i, 1); } else if (MATRIX(*coords, i, 1) > ymax) { ymax = MATRIX(*coords, i, 1); } } *x = (xmin + xmax) / 2; *y = (ymin + ymax) / 2; *r = sqrt( (xmax - xmin) * (xmax - xmin) + (ymax - ymin) * (ymax - ymin) ) / 2; return 0; } int igraph_i_layout_sphere_3d(igraph_matrix_t *coords, igraph_real_t *x, igraph_real_t *y, igraph_real_t *z, igraph_real_t *r) { long int nodes = igraph_matrix_nrow(coords); long int i; igraph_real_t xmin, xmax, ymin, ymax, zmin, zmax; xmin = xmax = MATRIX(*coords, 0, 0); ymin = ymax = MATRIX(*coords, 0, 1); zmin = zmax = MATRIX(*coords, 0, 2); for (i = 1; i < nodes; i++) { if (MATRIX(*coords, i, 0) < xmin) { xmin = MATRIX(*coords, i, 0); } else if (MATRIX(*coords, i, 0) > xmax) { xmax = MATRIX(*coords, i, 0); } if (MATRIX(*coords, i, 1) < ymin) { ymin = MATRIX(*coords, i, 1); } else if (MATRIX(*coords, i, 1) > ymax) { ymax = MATRIX(*coords, i, 1); } if (MATRIX(*coords, i, 2) < zmin) { zmin = MATRIX(*coords, i, 2); } else if (MATRIX(*coords, i, 2) > zmax) { zmax = MATRIX(*coords, i, 2); } } *x = (xmin + xmax) / 2; *y = (ymin + ymax) / 2; *z = (zmin + zmax) / 2; *r = sqrt( (xmax - xmin) * (xmax - xmin) + (ymax - ymin) * (ymax - ymin) + (zmax - zmin) * (zmax - zmin) ) / 2; return 0; } #define DIST(x,y) (sqrt(pow((x)-cx,2)+pow((y)-cy,2))) int igraph_i_layout_merge_dla(igraph_i_layout_mergegrid_t *grid, long int actg, igraph_real_t *x, igraph_real_t *y, igraph_real_t r, igraph_real_t cx, igraph_real_t cy, igraph_real_t startr, igraph_real_t killr) { long int sp = -1; igraph_real_t angle, len; long int steps = 0; /* The graph is not used, only its coordinates */ IGRAPH_UNUSED(actg); while (sp < 0) { /* start particle */ do { steps++; angle = RNG_UNIF(0, 2 * M_PI); len = RNG_UNIF(.5 * startr, startr); *x = cx + len * cos(angle); *y = cy + len * sin(angle); sp = igraph_i_layout_mergegrid_get_sphere(grid, *x, *y, r); } while (sp >= 0); while (sp < 0 && DIST(*x, *y) < killr) { igraph_real_t nx, ny; steps++; angle = RNG_UNIF(0, 2 * M_PI); len = RNG_UNIF(0, startr / 100); nx = *x + len * cos(angle); ny = *y + len * sin(angle); sp = igraph_i_layout_mergegrid_get_sphere(grid, nx, ny, r); if (sp < 0) { *x = nx; *y = ny; } } } /* fprintf(stderr, "%li ", steps); */ return 0; } leidenbase/src/core/layout/layout_random.c0000644000176200001440000000533414447675374020454 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_interface.h" #include "igraph_random.h" /** * \ingroup layout * \function igraph_layout_random * \brief Places the vertices uniform randomly on a plane. * * \param graph Pointer to an initialized graph object. * \param res Pointer to an initialized matrix object. This will * contain the result and will be resized as needed. * \return Error code. The current implementation always returns with * success. * * Time complexity: O(|V|), the * number of vertices. */ int igraph_layout_random(const igraph_t *graph, igraph_matrix_t *res) { long int no_of_nodes = igraph_vcount(graph); long int i; IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 2)); RNG_BEGIN(); for (i = 0; i < no_of_nodes; i++) { MATRIX(*res, i, 0) = RNG_UNIF(-1, 1); MATRIX(*res, i, 1) = RNG_UNIF(-1, 1); } RNG_END(); return 0; } /** * \function igraph_layout_random_3d * \brief Places the vertices uniform randomly in a cube. * * * Vertex coordinates range from -1 to 1, and are placed in 3 columns * of a matrix, with a row for each vertex. * * \param graph The graph to place. * \param res Pointer to an initialized matrix object. It will be * resized to hold the result. * \return Error code. The current implementation always returns with * success. * * Added in version 0.2. * * Time complexity: O(|V|), the number of vertices. */ int igraph_layout_random_3d(const igraph_t *graph, igraph_matrix_t *res) { long int no_of_nodes = igraph_vcount(graph); long int i; IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 3)); RNG_BEGIN(); for (i = 0; i < no_of_nodes; i++) { MATRIX(*res, i, 0) = RNG_UNIF(-1, 1); MATRIX(*res, i, 1) = RNG_UNIF(-1, 1); MATRIX(*res, i, 2) = RNG_UNIF(-1, 1); } RNG_END(); return IGRAPH_SUCCESS; } leidenbase/src/core/layout/reingold_tilford.c0000644000176200001440000011517414447675374021131 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_adjlist.h" #include "igraph_components.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_paths.h" #include "igraph_progress.h" #include "igraph_structural.h" #include "core/math.h" static int igraph_i_layout_reingold_tilford_unreachable( const igraph_t *graph, igraph_neimode_t mode, long int real_root, long int no_of_nodes, igraph_vector_t *pnewedges) { long int no_of_newedges; igraph_vector_t visited; long int i, j, n; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; igraph_adjlist_t allneis; igraph_vector_int_t *neis; igraph_vector_resize(pnewedges, 0); /* traverse from real_root and see what nodes you cannot reach */ no_of_newedges = 0; IGRAPH_VECTOR_INIT_FINALLY(&visited, no_of_nodes); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_adjlist_init(graph, &allneis, mode, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); /* start from real_root and go BFS */ IGRAPH_CHECK(igraph_dqueue_push(&q, real_root)); while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); neis = igraph_adjlist_get(&allneis, actnode); n = igraph_vector_int_size(neis); VECTOR(visited)[actnode] = 1; for (j = 0; j < n; j++) { long int neighbor = (long int) VECTOR(*neis)[j]; if (!(long int)VECTOR(visited)[neighbor]) { IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); } } } for (j = 0; j < no_of_nodes; j++) { no_of_newedges += 1 - VECTOR(visited)[j]; } /* if any nodes are unreachable, add edges between them and real_root */ if (no_of_newedges != 0) { igraph_vector_resize(pnewedges, no_of_newedges * 2); j = 0; for (i = 0; i < no_of_nodes; i++) { if (!VECTOR(visited)[i]) { if (mode != IGRAPH_IN) { VECTOR(*pnewedges)[2 * j] = real_root; VECTOR(*pnewedges)[2 * j + 1] = i; } else { VECTOR(*pnewedges)[2 * j] = i; VECTOR(*pnewedges)[2 * j + 1] = real_root; } j++; } } } igraph_dqueue_destroy(&q); igraph_adjlist_destroy(&allneis); igraph_vector_destroy(&visited); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /* Internal structure for Reingold-Tilford layout */ struct igraph_i_reingold_tilford_vertex { long int parent; /* Parent node index */ long int level; /* Level of the node */ igraph_real_t offset; /* X offset from parent node */ long int left_contour; /* Next left node of the contour of the subtree rooted at this node */ long int right_contour; /* Next right node of the contour of the subtree rooted at this node */ igraph_real_t offset_to_left_contour; /* X offset when following the left contour */ igraph_real_t offset_to_right_contour; /* X offset when following the right contour */ long int left_extreme; /* Leftmost node on the deepest layer of the subtree rooted at this node */ long int right_extreme; /* Rightmost node on the deepest layer of the subtree rooted at this node */ igraph_real_t offset_to_left_extreme; /* X offset when jumping to the left extreme node */ igraph_real_t offset_to_right_extreme; /* X offset when jumping to the right extreme node */ }; static int igraph_i_layout_reingold_tilford_postorder(struct igraph_i_reingold_tilford_vertex *vdata, long int node, long int vcount); static int igraph_i_layout_reingold_tilford_calc_coords(struct igraph_i_reingold_tilford_vertex *vdata, igraph_matrix_t *res, long int node, long int vcount, igraph_real_t xpos); /* uncomment the next line for debugging the Reingold-Tilford layout */ /* #define LAYOUT_RT_DEBUG 1 */ static int igraph_i_layout_reingold_tilford(const igraph_t *graph, igraph_matrix_t *res, igraph_neimode_t mode, long int root) { long int no_of_nodes = igraph_vcount(graph); long int i, n, j; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; igraph_adjlist_t allneis; igraph_vector_int_t *neis; struct igraph_i_reingold_tilford_vertex *vdata; IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 2)); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_adjlist_init(graph, &allneis, mode, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); vdata = IGRAPH_CALLOC(no_of_nodes, struct igraph_i_reingold_tilford_vertex); if (vdata == 0) { IGRAPH_ERROR("igraph_layout_reingold_tilford failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, vdata); for (i = 0; i < no_of_nodes; i++) { vdata[i].parent = -1; vdata[i].level = -1; vdata[i].offset = 0.0; vdata[i].left_contour = -1; vdata[i].right_contour = -1; vdata[i].offset_to_left_contour = 0.0; vdata[i].offset_to_right_contour = 0.0; vdata[i].left_extreme = i; vdata[i].right_extreme = i; vdata[i].offset_to_left_extreme = 0.0; vdata[i].offset_to_right_extreme = 0.0; } vdata[root].parent = root; vdata[root].level = 0; MATRIX(*res, root, 1) = 0; /* Step 1: assign Y coordinates based on BFS and setup parents vector */ IGRAPH_CHECK(igraph_dqueue_push(&q, root)); IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); neis = igraph_adjlist_get(&allneis, actnode); n = igraph_vector_int_size(neis); for (j = 0; j < n; j++) { long int neighbor = (long int) VECTOR(*neis)[j]; if (vdata[neighbor].parent >= 0) { continue; } MATRIX(*res, neighbor, 1) = actdist + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); vdata[neighbor].parent = actnode; vdata[neighbor].level = actdist + 1; } } /* Step 2: postorder tree traversal, determines the appropriate X * offsets for every node */ igraph_i_layout_reingold_tilford_postorder(vdata, root, no_of_nodes); /* Step 3: calculate real coordinates based on X offsets */ igraph_i_layout_reingold_tilford_calc_coords(vdata, res, root, no_of_nodes, vdata[root].offset); igraph_dqueue_destroy(&q); igraph_adjlist_destroy(&allneis); igraph_free(vdata); IGRAPH_FINALLY_CLEAN(3); IGRAPH_PROGRESS("Reingold-Tilford tree layout", 100.0, NULL); #ifdef LAYOUT_RT_DEBUG for (i = 0; i < no_of_nodes; i++) { printf( "%3ld: offset = %.2f, contours = [%ld, %ld], contour offsets = [%.2f, %.2f]\n", i, vdata[i].offset, vdata[i].left_contour, vdata[i].right_contour, vdata[i].offset_to_left_contour, vdata[i].offset_to_right_contour ); if (vdata[i].left_extreme != i || vdata[i].right_extreme != i) { printf( " extrema = [%ld, %ld], offsets to extrema = [%.2f, %.2f]\n", vdata[i].left_extreme, vdata[i].right_extreme, vdata[i].offset_to_left_extreme, vdata[i].offset_to_right_extreme ); } } #endif return 0; } static int igraph_i_layout_reingold_tilford_calc_coords( struct igraph_i_reingold_tilford_vertex *vdata, igraph_matrix_t *res, long int node, long int vcount, igraph_real_t xpos) { long int i; MATRIX(*res, node, 0) = xpos; for (i = 0; i < vcount; i++) { if (i == node) { continue; } if (vdata[i].parent == node) { igraph_i_layout_reingold_tilford_calc_coords(vdata, res, i, vcount, xpos + vdata[i].offset); } } return 0; } static int igraph_i_layout_reingold_tilford_postorder( struct igraph_i_reingold_tilford_vertex *vdata, long int node, long int vcount) { long int i, j, childcount, leftroot, leftrootidx; const igraph_real_t minsep = 1; igraph_real_t avg; #ifdef LAYOUT_RT_DEBUG printf("Starting visiting node %ld\n", node); #endif /* Check whether this node is a leaf node */ childcount = 0; for (i = 0; i < vcount; i++) { if (i == node) { continue; } if (vdata[i].parent == node) { /* Node i is a child, so visit it recursively */ childcount++; igraph_i_layout_reingold_tilford_postorder(vdata, i, vcount); } } if (childcount == 0) { return 0; } /* Here we can assume that all of the subtrees have been placed and their * left and right contours are calculated. Let's place them next to each * other as close as we can. * We will take each subtree in an arbitrary order. The root of the * first one will be placed at offset 0, the next ones will be placed * as close to each other as possible. leftroot stores the root of the * rightmost subtree of the already placed subtrees - its right contour * will be checked against the left contour of the next subtree */ leftroot = leftrootidx = -1; avg = 0.0; #ifdef LAYOUT_RT_DEBUG printf("Visited node %ld and arranged its subtrees\n", node); #endif for (i = 0, j = 0; i < vcount; i++) { if (i == node) { continue; } if (vdata[i].parent == node) { if (leftroot >= 0) { /* Now we will follow the right contour of leftroot and the * left contour of the subtree rooted at i */ long lnode, rnode, auxnode; igraph_real_t loffset, roffset, rootsep, newoffset; #ifdef LAYOUT_RT_DEBUG printf(" Placing child %ld on level %ld, to the right of %ld\n", i, vdata[i].level, leftroot); #endif lnode = leftroot; rnode = i; rootsep = vdata[leftroot].offset + minsep; loffset = vdata[leftroot].offset; roffset = loffset + minsep; /* Keep on updating the right contour now that we have attached * a new node to the subtree being built */ vdata[node].right_contour = i; vdata[node].offset_to_right_contour = rootsep; #ifdef LAYOUT_RT_DEBUG printf(" Contour: [%ld, %ld], offsets: [%lf, %lf], rootsep: %lf\n", lnode, rnode, loffset, roffset, rootsep); #endif while ((lnode >= 0) && (rnode >= 0)) { /* Step to the next level on the right contour of the left subtree */ if (vdata[lnode].right_contour >= 0) { loffset += vdata[lnode].offset_to_right_contour; lnode = vdata[lnode].right_contour; } else { /* Left subtree ended there. The left and right contour * of the left subtree will continue to the next step * on the right subtree. */ if (vdata[rnode].left_contour >= 0) { auxnode = vdata[node].left_extreme; /* this is the "threading" step that the original * paper is talking about */ newoffset = (vdata[node].offset_to_right_extreme - vdata[node].offset_to_left_extreme) + minsep + vdata[rnode].offset_to_left_contour; vdata[auxnode].left_contour = vdata[rnode].left_contour; vdata[auxnode].right_contour = vdata[rnode].left_contour; vdata[auxnode].offset_to_left_contour = vdata[auxnode].offset_to_right_contour = newoffset; /* since we attached a larger subtree to the * already placed left subtree, we need to update * the extrema of the subtree rooted at 'node' */ vdata[node].left_extreme = vdata[i].left_extreme; vdata[node].right_extreme = vdata[i].right_extreme; vdata[node].offset_to_left_extreme = vdata[i].offset_to_left_extreme + rootsep; vdata[node].offset_to_right_extreme = vdata[i].offset_to_right_extreme + rootsep; #ifdef LAYOUT_RT_DEBUG printf(" Left subtree ended earlier, continuing left subtree's left and right contour on right subtree (node %ld gets connected to node %ld)\n", auxnode, vdata[rnode].left_contour); printf(" New contour following offset for node %ld is %lf\n", auxnode, vdata[auxnode].offset_to_left_contour); #endif } else { /* Both subtrees are ending at the same time; the * left extreme node of the subtree rooted at * 'node' remains the same but the right extreme * will change */ vdata[node].right_extreme = vdata[i].right_extreme; vdata[node].offset_to_right_extreme = vdata[i].offset_to_right_extreme + rootsep; } lnode = -1; } /* Step to the next level on the left contour of the right subtree */ if (vdata[rnode].left_contour >= 0) { roffset += vdata[rnode].offset_to_left_contour; rnode = vdata[rnode].left_contour; } else { /* Right subtree ended here. The right contour of the right * subtree will continue to the next step on the left subtree. * Note that lnode has already been advanced here */ if (lnode >= 0) { auxnode = vdata[i].right_extreme; /* this is the "threading" step that the original * paper is talking about */ newoffset = loffset - rootsep - vdata[i].offset_to_right_extreme; vdata[auxnode].left_contour = lnode; vdata[auxnode].right_contour = lnode; vdata[auxnode].offset_to_left_contour = vdata[auxnode].offset_to_right_contour = newoffset; /* no need to update the extrema of the subtree * rooted at 'node' because the right subtree was * smaller */ #ifdef LAYOUT_RT_DEBUG printf(" Right subtree ended earlier, continuing right subtree's left and right contour on left subtree (node %ld gets connected to node %ld)\n", auxnode, lnode); printf(" New contour following offset for node %ld is %lf\n", auxnode, vdata[auxnode].offset_to_left_contour); #endif } rnode = -1; } #ifdef LAYOUT_RT_DEBUG printf(" Contour: [%ld, %ld], offsets: [%lf, %lf], rootsep: %lf\n", lnode, rnode, loffset, roffset, rootsep); #endif /* Push subtrees away if necessary */ if ((lnode >= 0) && (rnode >= 0) && (roffset - loffset < minsep)) { #ifdef LAYOUT_RT_DEBUG printf(" Pushing right subtree away by %lf\n", minsep-roffset+loffset); #endif rootsep += minsep - roffset + loffset; roffset = loffset + minsep; vdata[node].offset_to_right_contour = rootsep; } } #ifdef LAYOUT_RT_DEBUG printf(" Offset of subtree with root node %ld will be %lf\n", i, rootsep); #endif vdata[i].offset = rootsep; vdata[node].offset_to_right_contour = rootsep; avg = (avg * j) / (j + 1) + rootsep / (j + 1); leftrootidx = j; leftroot = i; } else { /* This is the first child of the node being considered so we * can simply place the subtree on our virtual canvas */ #ifdef LAYOUT_RT_DEBUG printf(" Placing child %ld on level %ld as first child\n", i, vdata[i].level); #endif leftrootidx = j; leftroot = i; vdata[node].left_contour = i; vdata[node].right_contour = i; vdata[node].offset_to_left_contour = 0.0; vdata[node].offset_to_right_contour = 0.0; vdata[node].left_extreme = vdata[i].left_extreme; vdata[node].right_extreme = vdata[i].right_extreme; vdata[node].offset_to_left_extreme = vdata[i].offset_to_left_extreme; vdata[node].offset_to_right_extreme = vdata[i].offset_to_right_extreme; avg = vdata[i].offset; } j++; } } #ifdef LAYOUT_RT_DEBUG printf("Shifting node %ld to be centered above children. Shift amount: %lf\n", node, avg); #endif vdata[node].offset_to_left_contour -= avg; vdata[node].offset_to_right_contour -= avg; vdata[node].offset_to_left_extreme -= avg; vdata[node].offset_to_right_extreme -= avg; for (i = 0, j = 0; i < vcount; i++) { if (i == node) { continue; } if (vdata[i].parent == node) { vdata[i].offset -= avg; } } return 0; } /* This function computes the number of outgoing (or incoming) connections * of clusters, represented as a membership vector. It only works with * directed graphs. */ int igraph_i_layout_reingold_tilford_cluster_degrees_directed( const igraph_t *graph, const igraph_vector_t *membership, igraph_integer_t no_comps, igraph_neimode_t mode, igraph_vector_t *degrees) { igraph_eit_t eit; if (! igraph_is_directed(graph) || (mode != IGRAPH_OUT && mode != IGRAPH_IN)) { IGRAPH_ERROR("Directed graph expected.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_resize(degrees, no_comps)); igraph_vector_null(degrees); IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID), &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); for (; !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { igraph_integer_t eid = IGRAPH_EIT_GET(eit); igraph_integer_t from = IGRAPH_FROM(graph, eid); igraph_integer_t to = IGRAPH_TO(graph, eid); igraph_integer_t from_cl = VECTOR(*membership)[from]; igraph_integer_t to_cl = VECTOR(*membership)[to]; igraph_integer_t cl = mode == IGRAPH_OUT ? from_cl : to_cl; if (from_cl != to_cl) { VECTOR(*degrees)[cl] += 1; } } igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Heuristic method to choose "nice" roots for the Reingold-Tilford layout algorithm. * * The principle is to select a minimal set of roots so that all other vertices * will be reachable from them. * * In the undirected case, one root is chosen from each connected component. * In the directed case, one root is chosen from each strongly connected component * that has no incoming (or outgoing) edges (depending on 'mode'). * When more than one root choice is possible, nodes are prioritized based on * either lowest ecccentricity (if 'use_ecccentricity' is true) or based on * highest degree (out- or in-degree in directed mode). */ int igraph_i_layout_reingold_tilford_select_roots( const igraph_t *graph, igraph_neimode_t mode, igraph_vector_t *roots, igraph_bool_t use_eccentricity) { igraph_integer_t no_of_nodes = igraph_vcount(graph); igraph_vector_t order, membership; igraph_integer_t no_comps; long int i, j; if (! igraph_is_directed(graph)) { mode = IGRAPH_ALL; } IGRAPH_VECTOR_INIT_FINALLY(&order, no_of_nodes); if (use_eccentricity) { /* Sort vertices by decreasing eccenticity. */ igraph_vector_t ecc; IGRAPH_VECTOR_INIT_FINALLY(&ecc, no_of_nodes); IGRAPH_CHECK(igraph_eccentricity(graph, &ecc, igraph_vss_all(), mode)); IGRAPH_CHECK(igraph_vector_qsort_ind(&ecc, &order, /* descending= */ 0)); igraph_vector_destroy(&ecc); IGRAPH_FINALLY_CLEAN(1); } else { /* Sort vertices by decreasing degree (out- or in-degree in directed case). */ IGRAPH_CHECK(igraph_sort_vertex_ids_by_degree(graph, &order, igraph_vss_all(), mode, 0, IGRAPH_DESCENDING, 0)); } IGRAPH_VECTOR_INIT_FINALLY(&membership, no_of_nodes); IGRAPH_CHECK(igraph_clusters(graph, &membership, /*csize=*/ NULL, &no_comps, mode == IGRAPH_ALL ? IGRAPH_WEAK : IGRAPH_STRONG)); IGRAPH_CHECK(igraph_vector_resize(roots, no_comps)); igraph_vector_fill(roots, -1); /* -1 signifies a not-yet-determined root for a component */ if (mode != IGRAPH_ALL) { /* Directed case: * * We break the graph into strongly-connected components and find those components * which have no incoming (outgoing) edges. The largest out-degree (in-degree) * nodes from these components will be chosen as roots. When the graph is a DAG, * these will simply be the source (sink) nodes. */ igraph_vector_t cluster_degrees; IGRAPH_VECTOR_INIT_FINALLY(&cluster_degrees, no_of_nodes); IGRAPH_CHECK(igraph_i_layout_reingold_tilford_cluster_degrees_directed( graph, &membership, no_comps, mode == IGRAPH_OUT ? IGRAPH_IN : IGRAPH_OUT, /* reverse direction */ &cluster_degrees)); /* Iterate through nodes in decreasing out-degree (or in-degree) order * and record largest degree node in each strongly-connected component * which has no incoming (outgoing) edges. */ for (i = 0; i < no_of_nodes; ++i) { long int v = (long int) VECTOR(order)[i]; long int cl = VECTOR(membership)[v]; if (VECTOR(cluster_degrees)[cl] == 0 && VECTOR(*roots)[cl] == -1) { VECTOR(*roots)[cl] = v; } } igraph_vector_destroy(&cluster_degrees); IGRAPH_FINALLY_CLEAN(1); /* Remove remaining -1 indices. These correspond to components that * did have some incoming edges. */ for (i=0, j=0; i < no_comps; ++i) { if (VECTOR(*roots)[i] == -1) { continue; } VECTOR(*roots)[j++] = VECTOR(*roots)[i]; } igraph_vector_resize(roots, j); } else { /* Undirected case: * * Select the highest degree node from each component. */ long int no_seen = 0; for (i=0; i < no_of_nodes; ++i) { long int v = VECTOR(order)[i]; long int cl = VECTOR(membership)[v]; if (VECTOR(*roots)[cl] == -1) { no_seen += 1; VECTOR(*roots)[cl] = v; } if (no_seen == no_comps) { /* All components have roots now. */ break; } } } igraph_vector_destroy(&membership); igraph_vector_destroy(&order); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /** * \function igraph_layout_reingold_tilford * \brief Reingold-Tilford layout for tree graphs * * * Arranges the nodes in a tree where the given node is used as the root. * The tree is directed downwards and the parents are centered above its * children. For the exact algorithm, see: * * * Reingold, E and Tilford, J: Tidier drawing of trees. * IEEE Trans. Softw. Eng., SE-7(2):223--228, 1981. * https://doi.org/10.1109/TSE.1981.234519 * * * If the given graph is not a tree, a breadth-first search is executed * first to obtain a possible spanning tree. * * \param graph The graph object. * \param res The result, the coordinates in a matrix. The parameter * should point to an initialized matrix object and will be resized. * \param mode Specifies which edges to consider when building the tree. * If it is \c IGRAPH_OUT then only the outgoing, if it is \c IGRAPH_IN * then only the incoming edges of a parent are considered. If it is * \c IGRAPH_ALL then all edges are used (this was the behavior in * igraph 0.5 and before). This parameter also influences how the root * vertices are calculated, if they are not given. See the \p roots parameter. * \param roots The index of the root vertex or root vertices. The set of roots * should be specified so that all vertices of the graph are reachable from them. * Simply put, in the udirected case, one root should be given from each * connected component. If \p roots is \c NULL or a pointer to an empty vector, * then the roots will be selected automatically. Currently, automatic root * selection prefers low ecccentricity vertices in graphs with fewer than * 500 vertices, and high degree vertices (acording to \p mode) in larger graphs. * The root selecton heuristic may change without notice. To ensure a consistent * output, please specify the roots manually. * \param rootlevel This argument can be useful when drawing forests which are * not trees (i.e. they are unconnected and have tree components). It specifies * the level of the root vertices for every tree in the forest. It is only * considered if not a null pointer and the \p roots argument is also given * (and it is not a null pointer of an empty vector). * \return Error code. * * Added in version 0.2. * * \sa \ref igraph_layout_reingold_tilford_circular(). * * \example examples/simple/igraph_layout_reingold_tilford.c */ int igraph_layout_reingold_tilford(const igraph_t *graph, igraph_matrix_t *res, igraph_neimode_t mode, const igraph_vector_t *roots, const igraph_vector_t *rootlevel) { long int no_of_nodes_orig = igraph_vcount(graph); long int no_of_nodes = no_of_nodes_orig; long int real_root; igraph_t extended; const igraph_t *pextended = graph; igraph_vector_t myroots; const igraph_vector_t *proots = roots; long int i; igraph_vector_t newedges; /* TODO: possible speedup could be achieved if we use a table for storing * the children of each node in the tree. (Now the implementation uses a * single array containing the parent of each node and a node's children * are determined by looking for other nodes that have this node as parent) */ /* at various steps it might be necessary to add edges to the graph */ IGRAPH_VECTOR_INIT_FINALLY(&newedges, 0); if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } if ( (!roots || igraph_vector_size(roots) == 0) && rootlevel && igraph_vector_size(rootlevel) != 0 ) { IGRAPH_WARNING("Reingold-Tilford layout: 'rootlevel' ignored"); } /* ----------------------------------------------------------------------- */ /* If root vertices are not given, perform automated root selection. */ if (!roots || igraph_vector_size(roots) == 0) { IGRAPH_VECTOR_INIT_FINALLY(&myroots, 0); igraph_i_layout_reingold_tilford_select_roots(graph, mode, &myroots, no_of_nodes < 500); proots = &myroots; } else if (rootlevel && igraph_vector_size(rootlevel) > 0 && igraph_vector_size(roots) > 1) { /* ----------------------------------------------------------------------- */ /* Many roots were given to us, check 'rootlevel' */ long int plus_levels = 0; long int i; if (igraph_vector_size(roots) != igraph_vector_size(rootlevel)) { IGRAPH_ERROR("Reingold-Tilford: 'roots' and 'rootlevel' lengths differ", IGRAPH_EINVAL); } /* count the rootlevels that are not zero */ for (i = 0; i < igraph_vector_size(roots); i++) { plus_levels += VECTOR(*rootlevel)[i]; } /* make copy of graph, add vertices/edges */ if (plus_levels != 0) { long int edgeptr = 0; pextended = &extended; IGRAPH_CHECK(igraph_copy(&extended, graph)); IGRAPH_FINALLY(igraph_destroy, &extended); IGRAPH_CHECK(igraph_add_vertices(&extended, (igraph_integer_t) plus_levels, 0)); igraph_vector_resize(&newedges, plus_levels * 2); for (i = 0; i < igraph_vector_size(roots); i++) { long int rl = (long int) VECTOR(*rootlevel)[i]; long int rn = (long int) VECTOR(*roots)[i]; long int j; /* zero-level roots don't get anything special */ if (rl == 0) { continue; } /* for each nonzero-level root, add vertices and edges at all levels [1, 2, .., rl] piercing through the graph. If mode=="in" they pierce the other way */ if (mode != IGRAPH_IN) { VECTOR(newedges)[edgeptr++] = no_of_nodes; VECTOR(newedges)[edgeptr++] = rn; for (j = 0; j < rl - 1; j++) { VECTOR(newedges)[edgeptr++] = no_of_nodes + 1; VECTOR(newedges)[edgeptr++] = no_of_nodes; no_of_nodes++; } } else { VECTOR(newedges)[edgeptr++] = rn; VECTOR(newedges)[edgeptr++] = no_of_nodes; for (j = 0; j < rl - 1; j++) { VECTOR(newedges)[edgeptr++] = no_of_nodes; VECTOR(newedges)[edgeptr++] = no_of_nodes + 1; no_of_nodes++; } } /* move on to the next root */ VECTOR(*roots)[i] = no_of_nodes++; } /* actually add the edges to the graph */ IGRAPH_CHECK(igraph_add_edges(&extended, &newedges, 0)); } } /* We have root vertices now. If one or more nonzero-level roots were chosen by the user, we have copied the graph and added a few vertices and (directed) edges to connect those floating roots to nonfloating, zero-level equivalent roots. Below, the function igraph_i_layout_reingold_tilford(pextended, res, mode, real_root) calculates the actual rt coordinates of the graph. However, for simplicity that function requires a connected graph and a single root. For directed graphs, it needs not be strongly connected, however all nodes must be reachable from the root following the stream (i.e. the root must be a "mother vertex"). So before we call that function we have to make sure the (copied) graph satisfies that condition. That requires: 1. if there is more than one root, defining a single real_root 2. if a real_root is defined, adding edges to connect all roots to it 3. ensure real_root is mother of the whole graph. If it is not, add shortcut edges from real_root to any disconnected node for now. NOTE: 3. could be done better, e.g. by topological sorting of some kind. But for now it's ok like this. */ /* if there is only one root, no need for real_root */ if (igraph_vector_size(proots) == 1) { real_root = (long int) VECTOR(*proots)[0]; if (real_root < 0 || real_root >= no_of_nodes) { IGRAPH_ERROR("Invalid vertex id.", IGRAPH_EINVVID); } /* else, we need to make real_root */ } else { long int no_of_newedges; /* Make copy of the graph unless it exists already */ if (pextended == graph) { pextended = &extended; IGRAPH_CHECK(igraph_copy(&extended, graph)); IGRAPH_FINALLY(igraph_destroy, &extended); } /* add real_root to the vertices */ real_root = no_of_nodes; IGRAPH_CHECK(igraph_add_vertices(&extended, 1, 0)); no_of_nodes++; /* add edges from the roots to real_root */ no_of_newedges = igraph_vector_size(proots); igraph_vector_resize(&newedges, no_of_newedges * 2); for (i = 0; i < no_of_newedges; i++) { VECTOR(newedges)[2 * i] = no_of_nodes - 1; VECTOR(newedges)[2 * i + 1] = VECTOR(*proots)[i]; } IGRAPH_CHECK(igraph_add_edges(&extended, &newedges, 0)); } /* prepare edges to unreachable parts of the graph */ IGRAPH_CHECK(igraph_i_layout_reingold_tilford_unreachable(pextended, mode, real_root, no_of_nodes, &newedges)); if (igraph_vector_size(&newedges) != 0) { /* Make copy of the graph unless it exists already */ if (pextended == graph) { pextended = &extended; IGRAPH_CHECK(igraph_copy(&extended, graph)); IGRAPH_FINALLY(igraph_destroy, &extended); } IGRAPH_CHECK(igraph_add_edges(&extended, &newedges, 0)); } igraph_vector_destroy(&newedges); IGRAPH_FINALLY_CLEAN(1); /* ----------------------------------------------------------------------- */ /* Layout */ IGRAPH_CHECK(igraph_i_layout_reingold_tilford(pextended, res, mode, real_root)); /* Remove the new vertices from the layout */ if (no_of_nodes != no_of_nodes_orig) { if (no_of_nodes - 1 == no_of_nodes_orig) { IGRAPH_CHECK(igraph_matrix_remove_row(res, no_of_nodes_orig)); } else { igraph_matrix_t tmp; long int i; IGRAPH_MATRIX_INIT_FINALLY(&tmp, no_of_nodes_orig, 2); for (i = 0; i < no_of_nodes_orig; i++) { MATRIX(tmp, i, 0) = MATRIX(*res, i, 0); MATRIX(tmp, i, 1) = MATRIX(*res, i, 1); } IGRAPH_CHECK(igraph_matrix_update(res, &tmp)); igraph_matrix_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); } } if (pextended != graph) { igraph_destroy(&extended); IGRAPH_FINALLY_CLEAN(1); } /* Remove the roots vector if it was created by us */ if (proots != roots) { igraph_vector_destroy(&myroots); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_layout_reingold_tilford_circular * \brief Circular Reingold-Tilford layout for trees * * * This layout is almost the same as \ref igraph_layout_reingold_tilford(), but * the tree is drawn in a circular way, with the root vertex in the center. * * \param graph The graph object. * \param res The result, the coordinates in a matrix. The parameter * should point to an initialized matrix object and will be resized. * \param mode Specifies which edges to consider when building the tree. * If it is \c IGRAPH_OUT then only the outgoing, if it is \c IGRAPH_IN * then only the incoming edges of a parent are considered. If it is * \c IGRAPH_ALL then all edges are used (this was the behavior in * igraph 0.5 and before). This parameter also influences how the root * vertices are calculated, if they are not given. See the \p roots parameter. * \param roots The index of the root vertex or root vertices. The set of roots * should be specified so that all vertices of the graph are reachable from them. * Simply put, in the udirected case, one root should be given from each * connected component. If \p roots is \c NULL or a pointer to an empty vector, * then the roots will be selected automatically. Currently, automatic root * selection prefers low ecccentricity vertices in graphs with fewer than * 500 vertices, and high degree vertices (acording to \p mode) in larger graphs. * The root selecton heuristic may change without notice. To ensure a consistent * output, please specify the roots manually. * \param rootlevel This argument can be useful when drawing forests which are * not trees (i.e. they are unconnected and have tree components). It specifies * the level of the root vertices for every tree in the forest. It is only * considered if not a null pointer and the \p roots argument is also given * (and it is not a null pointer or an empty vector). * \return Error code. * * \sa \ref igraph_layout_reingold_tilford(). */ int igraph_layout_reingold_tilford_circular(const igraph_t *graph, igraph_matrix_t *res, igraph_neimode_t mode, const igraph_vector_t *roots, const igraph_vector_t *rootlevel) { long int no_of_nodes = igraph_vcount(graph); long int i; igraph_real_t ratio; igraph_real_t minx, maxx; IGRAPH_CHECK(igraph_layout_reingold_tilford(graph, res, mode, roots, rootlevel)); if (no_of_nodes == 0) { return IGRAPH_SUCCESS; } ratio = 2 * M_PI * (no_of_nodes - 1.0) / no_of_nodes; minx = maxx = MATRIX(*res, 0, 0); for (i = 1; i < no_of_nodes; i++) { if (MATRIX(*res, i, 0) > maxx) { maxx = MATRIX(*res, i, 0); } if (MATRIX(*res, i, 0) < minx) { minx = MATRIX(*res, i, 0); } } if (maxx > minx) { ratio /= (maxx - minx); } for (i = 0; i < no_of_nodes; i++) { igraph_real_t phi = (MATRIX(*res, i, 0) - minx) * ratio; igraph_real_t r = MATRIX(*res, i, 1); MATRIX(*res, i, 0) = r * cos(phi); MATRIX(*res, i, 1) = r * sin(phi); } return IGRAPH_SUCCESS; } leidenbase/src/core/layout/sugiyama.c0000644000176200001440000015173414447675374017424 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_centrality.h" #include "igraph_components.h" #include "igraph_constants.h" #include "igraph_constructors.h" #include "igraph_datatype.h" #include "igraph_error.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_structural.h" #include "igraph_types.h" #include "internal/glpk_support.h" #include "misc/feedback_arc_set.h" #include "config.h" #include /* #define SUGIYAMA_DEBUG */ #ifdef _MSC_VER /* MSVC does not support variadic macros */ #include static void debug(const char* fmt, ...) { va_list args; va_start(args, fmt); #ifdef SUGIYAMA_DEBUG vfprintf(stderr, fmt, args); #endif va_end(args); } #else #ifdef SUGIYAMA_DEBUG #define debug(...) fprintf(stderr, __VA_ARGS__) #else #define debug(...) #endif #endif /* MSVC uses __forceinline instead of inline */ #ifdef _MSC_VER #define INLINE __forceinline #else #define INLINE inline #endif /* * Implementation of the Sugiyama layout algorithm as described in: * * [1] K. Sugiyama, S. Tagawa and M. Toda, "Methods for Visual Understanding of * Hierarchical Systems". IEEE Transactions on Systems, Man and Cybernetics * 11(2):109-125, 1981. * * The layering (if not given in advance) is calculated by ... TODO * * [2] TODO * * The X coordinates of nodes within a layer are calculated using the method of * Brandes & Köpf: * * [3] U. Brandes and B. Köpf, "Fast and Simple Horizontal Coordinate * Assignment". In: Lecture Notes in Computer Science 2265:31-44, 2002. * * Layer compaction is done according to: * * [4] N.S. Nikolov and A. Tarassov, "Graph layering by promotion of nodes". * Journal of Discrete Applied Mathematics, special issue: IV ALIO/EURO * workshop on applied combinatorial optimization, 154(5). * * The steps of the algorithm are as follows: * * 1. Cycle removal by finding an approximately minimal feedback arc set * and reversing the direction of edges in the set. Algorithms for * finding minimal feedback arc sets are as follows: * * - Find a cycle and find its minimum weight edge. Decrease the weight * of all the edges by w. Remove those edges whose weight became zero. * Repeat until there are no cycles. Re-introduce removed edges in * decreasing order of weights, ensuring that no cycles are created. * * - Order the vertices somehow and remove edges which point backwards * in the ordering. Eades et al proposed the following procedure: * * 1. Iteratively remove sinks and prepend them to a vertex sequence * s2. * * 2. Iteratively remove sources and append them to a vertex sequence * s1. * * 3. Choose a vertex u s.t. the difference between the number of * rightward arcs and the number of leftward arcs is the largest, * remove u and append it to s1. Goto step 1 if there are still * more vertices. * * 4. Concatenate s1 with s2. * * This algorithm is known to produce feedback arc sets at most the * size of m/2 - n/6, where m is the number of edges. Further * improvements are possible in step 3 which bring down the size of * the set to at most m/4 for cubic directed graphs, see Eades (1995). * * - For undirected graphs, find a maximum weight spanning tree and * remove all the edges not in the spanning tree. For directed graphs, * find minimal cuts iteratively and remove edges pointing from A to * B or from B to A in the cut, depending on which one is smaller. Yes, * this is time-consuming. * * 2. Assigning vertices to layers according to [2]. * * 3. Extracting weakly connected components. The remaining steps are * executed for each component. * * 4. Compacting the layering using the method of [4]. TODO * Steps 2-4 are performed only when no layering is given in advance. * * 5. Adding dummy nodes to ensure that each edge spans at most one layer * only. * * 6. Finding an optimal ordering of vertices within a layer using the * Sugiyama framework [1]. * * 7. Assigning horizontal coordinates to each vertex using [3]. * * 8. ??? * * 9. Profit! */ /** * Data structure to store a layering of the graph. */ typedef struct { igraph_vector_ptr_t layers; } igraph_i_layering_t; /** * Initializes a layering. */ static int igraph_i_layering_init(igraph_i_layering_t* layering, const igraph_vector_t* membership) { long int i, n, num_layers; if (igraph_vector_size(membership) == 0) { num_layers = 0; } else { num_layers = (long int) igraph_vector_max(membership) + 1; } IGRAPH_CHECK(igraph_vector_ptr_init(&layering->layers, num_layers)); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &layering->layers); for (i = 0; i < num_layers; i++) { igraph_vector_t* vec = IGRAPH_CALLOC(1, igraph_vector_t); IGRAPH_VECTOR_INIT_FINALLY(vec, 0); VECTOR(layering->layers)[i] = vec; IGRAPH_FINALLY_CLEAN(1); } IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&layering->layers, igraph_vector_destroy); n = igraph_vector_size(membership); for (i = 0; i < n; i++) { long int l = (long int) VECTOR(*membership)[i]; igraph_vector_t* vec = VECTOR(layering->layers)[l]; IGRAPH_CHECK(igraph_vector_push_back(vec, i)); } IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * Destroys a layering. */ static void igraph_i_layering_destroy(igraph_i_layering_t* layering) { igraph_vector_ptr_destroy_all(&layering->layers); } /** * Returns the number of layers in a layering. */ static int igraph_i_layering_num_layers(const igraph_i_layering_t* layering) { return (int) igraph_vector_ptr_size(&layering->layers); } /** * Returns the list of vertices in a given layer */ static igraph_vector_t* igraph_i_layering_get(const igraph_i_layering_t* layering, long int index) { return (igraph_vector_t*)VECTOR(layering->layers)[index]; } /** * Forward declarations */ static int igraph_i_layout_sugiyama_place_nodes_vertically(const igraph_t* graph, const igraph_vector_t* weights, igraph_vector_t* membership); static int igraph_i_layout_sugiyama_order_nodes_horizontally(const igraph_t* graph, igraph_matrix_t* layout, const igraph_i_layering_t* layering, long int maxiter); static int igraph_i_layout_sugiyama_place_nodes_horizontally(const igraph_t* graph, igraph_matrix_t* layout, const igraph_i_layering_t* layering, igraph_real_t hgap, igraph_integer_t no_of_real_nodes); /** * Calculated the median of four numbers (not necessarily sorted). */ static INLINE igraph_real_t igraph_i_median_4(igraph_real_t x1, igraph_real_t x2, igraph_real_t x3, igraph_real_t x4) { igraph_real_t arr[4] = { x1, x2, x3, x4 }; igraph_vector_t vec; igraph_vector_view(&vec, arr, 4); igraph_vector_sort(&vec); return (arr[1] + arr[2]) / 2.0; } /** * \ingroup layout * \function igraph_layout_sugiyama * \brief Sugiyama layout algorithm for layered directed acyclic graphs. * * * This layout algorithm is designed for directed acyclic graphs where each * vertex is assigned to a layer. Layers are indexed from zero, and vertices * of the same layer will be placed on the same horizontal line. The X coordinates * of vertices within each layer are decided by the heuristic proposed by * Sugiyama et al to minimize edge crossings. * * * You can also try to lay out undirected graphs, graphs containing cycles, or * graphs without an a priori layered assignment with this algorithm. igraph * will try to eliminate cycles and assign vertices to layers, but there is no * guarantee on the quality of the layout in such cases. * * * The Sugiyama layout may introduce "bends" on the edges in order to obtain a * visually more pleasing layout. This is achieved by adding dummy nodes to * edges spanning more than one layer. The resulting layout assigns coordinates * not only to the nodes of the original graph but also to the dummy nodes. * The layout algorithm will also return the extended graph with the dummy nodes. * An edge in the original graph may either be mapped to a single edge in the * extended graph or a \em path that starts and ends in the original * source and target vertex and passes through multiple dummy vertices. In * such cases, the user may also request the mapping of the edges of the extended * graph back to the edges of the original graph. * * * For more details, see K. Sugiyama, S. Tagawa and M. Toda, "Methods for Visual * Understanding of Hierarchical Systems". IEEE Transactions on Systems, Man and * Cybernetics 11(2):109-125, 1981. * * \param graph Pointer to an initialized graph object. * \param res Pointer to an initialized matrix object. This will contain * the result and will be resized as needed. The first |V| rows * of the layout will contain the coordinates of the original graph, * the remaining rows contain the positions of the dummy nodes. * Therefore, you can use the result both with \p graph or with * \p extended_graph. * \param extended_graph Pointer to an uninitialized graph object or \c NULL. * The extended graph with the added dummy nodes will be * returned here. In this graph, each edge points downwards * to lower layers, spans exactly one layer and the first * |V| vertices coincide with the vertices of the * original graph. * \param extd_to_orig_eids Pointer to a vector or \c NULL. If not \c NULL, the * mapping from the edge IDs of the extended graph back * to the edge IDs of the original graph will be stored * here. * \param layers The layer index for each vertex or \c NULL if the layers should * be determined automatically by igraph. * \param hgap The preferred minimum horizontal gap between vertices in the same * layer. * \param vgap The distance between layers. * \param maxiter Maximum number of iterations in the crossing minimization stage. * 100 is a reasonable default; if you feel that you have too * many edge crossings, increase this. * \param weights Weights of the edges. These are used only if the graph contains * cycles; igraph will tend to reverse edges with smaller * weights when breaking the cycles. */ int igraph_layout_sugiyama(const igraph_t *graph, igraph_matrix_t *res, igraph_t *extd_graph, igraph_vector_t *extd_to_orig_eids, const igraph_vector_t* layers, igraph_real_t hgap, igraph_real_t vgap, long int maxiter, const igraph_vector_t *weights) { long int i, j, k, l, m, nei; long int no_of_nodes = (long int)igraph_vcount(graph); long int comp_idx; long int next_extd_vertex_id = no_of_nodes; igraph_bool_t directed = igraph_is_directed(graph); igraph_integer_t no_of_components; /* number of components of the original graph */ igraph_vector_t membership; /* components of the original graph */ igraph_vector_t extd_edgelist; /* edge list of the extended graph */ igraph_vector_t layers_own; /* layer indices after having eliminated empty layers */ igraph_real_t dx = 0, dx2 = 0; /* displacement of the current component on the X axis */ igraph_vector_t layer_to_y; /* mapping from layer indices to final Y coordinates */ if (layers && igraph_vector_size(layers) != no_of_nodes) { IGRAPH_ERROR("layer vector too short or too long", IGRAPH_EINVAL); } if (extd_graph != 0) { IGRAPH_VECTOR_INIT_FINALLY(&extd_edgelist, 0); if (extd_to_orig_eids != 0) { igraph_vector_clear(extd_to_orig_eids); } } IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 2)); IGRAPH_VECTOR_INIT_FINALLY(&membership, 0); IGRAPH_VECTOR_INIT_FINALLY(&layer_to_y, 0); /* 1. Find a feedback arc set if we don't have a layering yet. If we do have * a layering, we can leave all the edges as is as they will be re-oriented * to point downwards only anyway. */ if (layers == 0) { IGRAPH_VECTOR_INIT_FINALLY(&layers_own, no_of_nodes); IGRAPH_CHECK(igraph_i_layout_sugiyama_place_nodes_vertically( graph, weights, &layers_own)); } else { IGRAPH_CHECK(igraph_vector_copy(&layers_own, layers)); IGRAPH_FINALLY(igraph_vector_destroy, &layers_own); } /* Normalize layering, eliminate empty layers */ if (no_of_nodes > 0) { igraph_vector_t inds; IGRAPH_VECTOR_INIT_FINALLY(&inds, 0); IGRAPH_CHECK((int) igraph_vector_qsort_ind(&layers_own, &inds, 0)); j = -1; dx = VECTOR(layers_own)[(long int)VECTOR(inds)[0]] - 1; for (i = 0; i < no_of_nodes; i++) { k = (long int)VECTOR(inds)[i]; if (VECTOR(layers_own)[k] > dx) { /* New layer starts here */ dx = VECTOR(layers_own)[k]; j++; IGRAPH_CHECK(igraph_vector_push_back(&layer_to_y, dx * vgap)); } VECTOR(layers_own)[k] = j; } igraph_vector_destroy(&inds); IGRAPH_FINALLY_CLEAN(1); } /* 2. Find the connected components. */ IGRAPH_CHECK(igraph_clusters(graph, &membership, 0, &no_of_components, IGRAPH_WEAK)); /* 3. For each component... */ dx = 0; for (comp_idx = 0; comp_idx < no_of_components; comp_idx++) { /* Extract the edges of the comp_idx'th component and add dummy nodes for edges * spanning more than one layer. */ long int component_size, next_new_vertex_id; igraph_vector_t old2new_vertex_ids; igraph_vector_t new2old_vertex_ids; igraph_vector_t new_layers; igraph_vector_t edgelist; igraph_vector_t neis; IGRAPH_VECTOR_INIT_FINALLY(&edgelist, 0); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_INIT_FINALLY(&new2old_vertex_ids, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&old2new_vertex_ids, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&new_layers, 0); igraph_vector_fill(&old2new_vertex_ids, -1); /* Construct a mapping from the old vertex ids to the new ones */ for (i = 0, next_new_vertex_id = 0; i < no_of_nodes; i++) { if (VECTOR(membership)[i] == comp_idx) { IGRAPH_CHECK(igraph_vector_push_back(&new_layers, VECTOR(layers_own)[i])); VECTOR(new2old_vertex_ids)[next_new_vertex_id] = i; VECTOR(old2new_vertex_ids)[i] = next_new_vertex_id; next_new_vertex_id++; } } component_size = next_new_vertex_id; /* Construct a proper layering of the component in new_graph where each edge * points downwards and spans exactly one layer. */ for (i = 0; i < no_of_nodes; i++) { if (VECTOR(membership)[i] != comp_idx) { continue; } /* Okay, this vertex is in the component we are considering. * Add the neighbors of this vertex, excluding loops */ IGRAPH_CHECK(igraph_incident(graph, &neis, (igraph_integer_t) i, IGRAPH_OUT)); j = igraph_vector_size(&neis); for (k = 0; k < j; k++) { long int eid = (long int) VECTOR(neis)[k]; if (directed) { nei = IGRAPH_TO(graph, eid); } else { nei = IGRAPH_OTHER(graph, eid, i); if (nei < i) { /* to avoid considering edges twice */ continue; } } if (VECTOR(layers_own)[i] == VECTOR(layers_own)[nei]) { /* Edge goes within the same layer, we don't need this in the * layered graph, but we need it in the extended graph */ if (extd_graph != 0) { IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, i)); IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, nei)); if (extd_to_orig_eids != 0) { IGRAPH_CHECK(igraph_vector_push_back(extd_to_orig_eids, eid)); } } } else if (VECTOR(layers_own)[i] > VECTOR(layers_own)[nei]) { /* Edge goes upwards, we have to flip it */ IGRAPH_CHECK(igraph_vector_push_back(&edgelist, VECTOR(old2new_vertex_ids)[nei])); for (l = (long int) VECTOR(layers_own)[nei] + 1; l < VECTOR(layers_own)[i]; l++) { IGRAPH_CHECK(igraph_vector_push_back(&new_layers, l)); IGRAPH_CHECK(igraph_vector_push_back(&edgelist, next_new_vertex_id)); IGRAPH_CHECK(igraph_vector_push_back(&edgelist, next_new_vertex_id++)); } IGRAPH_CHECK(igraph_vector_push_back(&edgelist, VECTOR(old2new_vertex_ids)[i])); /* Also add the edge to the extended graph if needed, but this time * with the proper orientation */ if (extd_graph != 0) { IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, i)); next_extd_vertex_id += VECTOR(layers_own)[i] - VECTOR(layers_own)[nei] - 1; for (l = (long int) VECTOR(layers_own)[i] - 1, m = 1; l > VECTOR(layers_own)[nei]; l--, m++) { IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, next_extd_vertex_id - m)); IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, next_extd_vertex_id - m)); if (extd_to_orig_eids != 0) { IGRAPH_CHECK(igraph_vector_push_back(extd_to_orig_eids, eid)); } } IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, nei)); if (extd_to_orig_eids != 0) { IGRAPH_CHECK(igraph_vector_push_back(extd_to_orig_eids, eid)); } } } else { /* Edge goes downwards */ IGRAPH_CHECK(igraph_vector_push_back(&edgelist, VECTOR(old2new_vertex_ids)[i])); for (l = (long int) VECTOR(layers_own)[i] + 1; l < VECTOR(layers_own)[nei]; l++) { IGRAPH_CHECK(igraph_vector_push_back(&new_layers, l)); IGRAPH_CHECK(igraph_vector_push_back(&edgelist, next_new_vertex_id)); IGRAPH_CHECK(igraph_vector_push_back(&edgelist, next_new_vertex_id++)); } IGRAPH_CHECK(igraph_vector_push_back(&edgelist, VECTOR(old2new_vertex_ids)[nei])); /* Also add the edge to the extended graph */ if (extd_graph != 0) { IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, i)); for (l = (long int) VECTOR(layers_own)[i] + 1; l < VECTOR(layers_own)[nei]; l++) { IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, next_extd_vertex_id)); IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, next_extd_vertex_id++)); if (extd_to_orig_eids != 0) { IGRAPH_CHECK(igraph_vector_push_back(extd_to_orig_eids, eid)); } } IGRAPH_CHECK(igraph_vector_push_back(&extd_edgelist, nei)); if (extd_to_orig_eids != 0) { IGRAPH_CHECK(igraph_vector_push_back(extd_to_orig_eids, eid)); } } } } } /* At this point, we have the subgraph with the dummy nodes and * edges, so we can run Sugiyama's algorithm on it. */ { igraph_matrix_t layout; igraph_i_layering_t layering; igraph_t subgraph; IGRAPH_CHECK(igraph_matrix_init(&layout, next_new_vertex_id, 2)); IGRAPH_FINALLY(igraph_matrix_destroy, &layout); IGRAPH_CHECK(igraph_create(&subgraph, &edgelist, (igraph_integer_t) next_new_vertex_id, 1)); IGRAPH_FINALLY(igraph_destroy, &subgraph); /* igraph_vector_print(&edgelist); igraph_vector_print(&new_layers); */ /* Assign the vertical coordinates */ for (i = 0; i < next_new_vertex_id; i++) { MATRIX(layout, i, 1) = VECTOR(new_layers)[i]; } /* Create a layering */ IGRAPH_CHECK(igraph_i_layering_init(&layering, &new_layers)); IGRAPH_FINALLY(igraph_i_layering_destroy, &layering); /* Find the order in which the nodes within a layer should be placed */ IGRAPH_CHECK(igraph_i_layout_sugiyama_order_nodes_horizontally(&subgraph, &layout, &layering, maxiter)); /* Assign the horizontal coordinates. This is according to the algorithm * of Brandes & Köpf */ IGRAPH_CHECK(igraph_i_layout_sugiyama_place_nodes_horizontally(&subgraph, &layout, &layering, hgap, (igraph_integer_t) component_size)); /* Re-assign rows into the result matrix, and at the same time, */ /* adjust dx so that the next component does not overlap this one */ j = next_new_vertex_id - component_size; k = igraph_matrix_nrow(res); IGRAPH_CHECK(igraph_matrix_add_rows(res, j)); dx2 = dx; for (i = 0; i < component_size; i++) { l = (long int)VECTOR(new2old_vertex_ids)[i]; MATRIX(*res, l, 0) = MATRIX(layout, i, 0) + dx; MATRIX(*res, l, 1) = VECTOR(layer_to_y)[(long)MATRIX(layout, i, 1)]; if (dx2 < MATRIX(*res, l, 0)) { dx2 = MATRIX(*res, l, 0); } } for (i = component_size; i < next_new_vertex_id; i++) { MATRIX(*res, k, 0) = MATRIX(layout, i, 0) + dx; MATRIX(*res, k, 1) = VECTOR(layer_to_y)[(long)MATRIX(layout, i, 1)]; if (dx2 < MATRIX(*res, k, 0)) { dx2 = MATRIX(*res, k, 0); } k++; } dx = dx2 + hgap; igraph_destroy(&subgraph); igraph_i_layering_destroy(&layering); igraph_matrix_destroy(&layout); IGRAPH_FINALLY_CLEAN(3); } igraph_vector_destroy(&new_layers); igraph_vector_destroy(&old2new_vertex_ids); igraph_vector_destroy(&new2old_vertex_ids); igraph_vector_destroy(&edgelist); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(5); } igraph_vector_destroy(&layers_own); igraph_vector_destroy(&layer_to_y); igraph_vector_destroy(&membership); IGRAPH_FINALLY_CLEAN(3); if (extd_graph != 0) { IGRAPH_CHECK(igraph_create(extd_graph, &extd_edgelist, (igraph_integer_t) next_extd_vertex_id, igraph_is_directed(graph))); igraph_vector_destroy(&extd_edgelist); IGRAPH_FINALLY_CLEAN(1); } return IGRAPH_SUCCESS; } static int igraph_i_layout_sugiyama_place_nodes_vertically(const igraph_t* graph, const igraph_vector_t* weights, igraph_vector_t* membership) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); if (no_of_edges == 0) { igraph_vector_fill(membership, 0); return IGRAPH_SUCCESS; } #ifdef HAVE_GLPK if (igraph_is_directed(graph) && no_of_nodes <= 1000) { /* Network simplex algorithm of Gansner et al, using the original linear * programming formulation */ long int i, j; igraph_vector_t outdegs, indegs, feedback_edges; glp_prob *ip; glp_smcp parm; /* Allocate storage and create the problem */ ip = glp_create_prob(); IGRAPH_FINALLY(glp_delete_prob, ip); IGRAPH_VECTOR_INIT_FINALLY(&feedback_edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&outdegs, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&indegs, no_of_nodes); /* Find an approximate feedback edge set */ IGRAPH_CHECK(igraph_i_feedback_arc_set_eades(graph, &feedback_edges, weights, 0)); igraph_vector_sort(&feedback_edges); /* Calculate in- and out-strengths for the remaining edges */ IGRAPH_CHECK(igraph_strength(graph, &indegs, igraph_vss_all(), IGRAPH_IN, 1, weights)); IGRAPH_CHECK(igraph_strength(graph, &outdegs, igraph_vss_all(), IGRAPH_IN, 1, weights)); j = igraph_vector_size(&feedback_edges); for (i = 0; i < j; i++) { long int eid = (long int) VECTOR(feedback_edges)[i]; long int from = IGRAPH_FROM(graph, eid); long int to = IGRAPH_TO(graph, eid); VECTOR(outdegs)[from] -= weights ? VECTOR(*weights)[eid] : 1; VECTOR(indegs)[to] -= weights ? VECTOR(*weights)[eid] : 1; } /* Configure GLPK */ glp_term_out(GLP_OFF); glp_init_smcp(&parm); parm.msg_lev = GLP_MSG_OFF; parm.presolve = GLP_OFF; /* Set up variables and objective function coefficients */ glp_set_obj_dir(ip, GLP_MIN); glp_add_cols(ip, (int) no_of_nodes); IGRAPH_CHECK(igraph_vector_sub(&outdegs, &indegs)); for (i = 1; i <= no_of_nodes; i++) { glp_set_col_kind(ip, (int) i, GLP_IV); glp_set_col_bnds(ip, (int) i, GLP_LO, 0.0, 0.0); glp_set_obj_coef(ip, (int) i, VECTOR(outdegs)[i - 1]); } igraph_vector_destroy(&indegs); igraph_vector_destroy(&outdegs); IGRAPH_FINALLY_CLEAN(2); /* Add constraints */ glp_add_rows(ip, (int) no_of_edges); IGRAPH_CHECK(igraph_vector_push_back(&feedback_edges, -1)); j = 0; for (i = 0; i < no_of_edges; i++) { int ind[3]; double val[3] = {0, -1, 1}; ind[1] = IGRAPH_FROM(graph, i) + 1; ind[2] = IGRAPH_TO(graph, i) + 1; if (ind[1] == ind[2]) { if (VECTOR(feedback_edges)[j] == i) { j++; } continue; } if (VECTOR(feedback_edges)[j] == i) { /* This is a feedback edge, add it reversed */ glp_set_row_bnds(ip, (int) i + 1, GLP_UP, -1, -1); j++; } else { glp_set_row_bnds(ip, (int) i + 1, GLP_LO, 1, 1); } glp_set_mat_row(ip, (int) i + 1, 2, ind, val); } /* Solve the problem */ IGRAPH_GLPK_CHECK(glp_simplex(ip, &parm), "Vertical arrangement step using IP failed"); /* The problem is totally unimodular, therefore the output of the simplex * solver can be converted to an integer solution easily */ for (i = 0; i < no_of_nodes; i++) { VECTOR(*membership)[i] = floor(glp_get_col_prim(ip, (int) i + 1)); } glp_delete_prob(ip); igraph_vector_destroy(&feedback_edges); IGRAPH_FINALLY_CLEAN(2); } else if (igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_feedback_arc_set_eades(graph, 0, weights, membership)); } else { IGRAPH_CHECK(igraph_i_feedback_arc_set_undirected(graph, 0, weights, membership)); } #else if (igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_feedback_arc_set_eades(graph, 0, weights, membership)); } else { IGRAPH_CHECK(igraph_i_feedback_arc_set_undirected(graph, 0, weights, membership)); } #endif return IGRAPH_SUCCESS; } static int igraph_i_layout_sugiyama_calculate_barycenters(const igraph_t* graph, const igraph_i_layering_t* layering, long int layer_index, igraph_neimode_t direction, const igraph_matrix_t* layout, igraph_vector_t* barycenters) { long int i, j, m, n; igraph_vector_t* layer_members = igraph_i_layering_get(layering, layer_index); igraph_vector_t neis; IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); n = igraph_vector_size(layer_members); IGRAPH_CHECK(igraph_vector_resize(barycenters, n)); igraph_vector_null(barycenters); for (i = 0; i < n; i++) { IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) VECTOR(*layer_members)[i], direction)); m = igraph_vector_size(&neis); if (m == 0) { /* No neighbors in this direction. Just use the current X coordinate */ VECTOR(*barycenters)[i] = MATRIX(*layout, i, 0); } else { for (j = 0; j < m; j++) { VECTOR(*barycenters)[i] += MATRIX(*layout, (long)VECTOR(neis)[j], 0); } VECTOR(*barycenters)[i] /= m; } } igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * Given a properly layered graph where each edge points downwards and spans * exactly one layer, arranges the nodes in each layer horizontally in a way * that strives to minimize edge crossings. */ static int igraph_i_layout_sugiyama_order_nodes_horizontally(const igraph_t* graph, igraph_matrix_t* layout, const igraph_i_layering_t* layering, long int maxiter) { long int i, n, nei; long int no_of_vertices = igraph_vcount(graph); long int no_of_layers = igraph_i_layering_num_layers(layering); long int iter, layer_index; igraph_vector_t* layer_members; igraph_vector_t neis, barycenters, sort_indices; igraph_bool_t changed; /* The first column of the matrix will serve as the ordering */ /* Start with a first-seen ordering within each layer */ { long int *xs = IGRAPH_CALLOC(no_of_layers, long int); if (xs == 0) { IGRAPH_ERROR("cannot order nodes horizontally", IGRAPH_ENOMEM); } for (i = 0; i < no_of_vertices; i++) { MATRIX(*layout, i, 0) = xs[(long int)MATRIX(*layout, i, 1)]++; } free(xs); } IGRAPH_VECTOR_INIT_FINALLY(&barycenters, 0); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_INIT_FINALLY(&sort_indices, 0); /* Start the effective part of the Sugiyama algorithm */ iter = 0; changed = 1; while (changed && iter < maxiter) { changed = 0; /* Phase 1 */ /* Moving downwards and sorting by upper barycenters */ for (layer_index = 1; layer_index < no_of_layers; layer_index++) { layer_members = igraph_i_layering_get(layering, layer_index); n = igraph_vector_size(layer_members); igraph_i_layout_sugiyama_calculate_barycenters(graph, layering, layer_index, IGRAPH_IN, layout, &barycenters); #ifdef SUGIYAMA_DEBUG printf("Layer %ld, aligning to upper barycenters\n", layer_index); printf("Vertices: "); igraph_vector_print(layer_members); printf("Barycenters: "); igraph_vector_print(&barycenters); #endif IGRAPH_CHECK((int) igraph_vector_qsort_ind(&barycenters, &sort_indices, 0)); for (i = 0; i < n; i++) { nei = (long)VECTOR(*layer_members)[(long)VECTOR(sort_indices)[i]]; VECTOR(barycenters)[i] = nei; MATRIX(*layout, nei, 0) = i; } if (!igraph_vector_all_e(layer_members, &barycenters)) { IGRAPH_CHECK(igraph_vector_update(layer_members, &barycenters)); #ifdef SUGIYAMA_DEBUG printf("New vertex order: "); igraph_vector_print(layer_members); #endif changed = 1; } else { #ifdef SUGIYAMA_DEBUG printf("Order did not change.\n"); #endif } } /* Moving upwards and sorting by lower barycenters */ for (layer_index = no_of_layers - 2; layer_index >= 0; layer_index--) { layer_members = igraph_i_layering_get(layering, layer_index); n = igraph_vector_size(layer_members); igraph_i_layout_sugiyama_calculate_barycenters(graph, layering, layer_index, IGRAPH_OUT, layout, &barycenters); #ifdef SUGIYAMA_DEBUG printf("Layer %ld, aligning to lower barycenters\n", layer_index); printf("Vertices: "); igraph_vector_print(layer_members); printf("Barycenters: "); igraph_vector_print(&barycenters); #endif IGRAPH_CHECK((int) igraph_vector_qsort_ind(&barycenters, &sort_indices, 0)); for (i = 0; i < n; i++) { nei = (long)VECTOR(*layer_members)[(long)VECTOR(sort_indices)[i]]; VECTOR(barycenters)[i] = nei; MATRIX(*layout, nei, 0) = i; } if (!igraph_vector_all_e(layer_members, &barycenters)) { IGRAPH_CHECK(igraph_vector_update(layer_members, &barycenters)); #ifdef SUGIYAMA_DEBUG printf("New vertex order: "); igraph_vector_print(layer_members); #endif changed = 1; } else { #ifdef SUGIYAMA_DEBUG printf("Order did not change.\n"); #endif } } #ifdef SUGIYAMA_DEBUG printf("==== Finished iteration %ld\n", iter); #endif iter++; } igraph_vector_destroy(&barycenters); igraph_vector_destroy(&neis); igraph_vector_destroy(&sort_indices); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } #define IS_DUMMY(v) ((v >= no_of_real_nodes)) #define IS_INNER_SEGMENT(u, v) (IS_DUMMY(u) && IS_DUMMY(v)) #define X_POS(v) (MATRIX(*layout, v, 0)) static int igraph_i_layout_sugiyama_vertical_alignment(const igraph_t* graph, const igraph_i_layering_t* layering, const igraph_matrix_t* layout, const igraph_vector_bool_t* ignored_edges, igraph_bool_t reverse, igraph_bool_t align_right, igraph_vector_t* roots, igraph_vector_t* align); static int igraph_i_layout_sugiyama_horizontal_compaction(const igraph_t* graph, const igraph_vector_t* vertex_to_the_left, const igraph_vector_t* roots, const igraph_vector_t* align, igraph_real_t hgap, igraph_vector_t* xs); static int igraph_i_layout_sugiyama_horizontal_compaction_place_block(long int v, const igraph_vector_t* vertex_to_the_left, const igraph_vector_t* roots, const igraph_vector_t* align, igraph_vector_t* sinks, igraph_vector_t* shifts, igraph_real_t hgap, igraph_vector_t* xs); static int igraph_i_layout_sugiyama_place_nodes_horizontally(const igraph_t* graph, igraph_matrix_t* layout, const igraph_i_layering_t* layering, igraph_real_t hgap, igraph_integer_t no_of_real_nodes) { long int i, j, k, l, n; long int no_of_layers = igraph_i_layering_num_layers(layering); long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vector_t neis1, neis2; igraph_vector_t xs[4]; igraph_vector_t roots, align; igraph_vector_t vertex_to_the_left; igraph_vector_bool_t ignored_edges; /* { igraph_vector_t edgelist; IGRAPH_VECTOR_INIT_FINALLY(&edgelist, 0); IGRAPH_CHECK(igraph_get_edgelist(graph, &edgelist, 0)); igraph_vector_print(&edgelist); igraph_vector_destroy(&edgelist); IGRAPH_FINALLY_CLEAN(1); for (i = 0; i < no_of_layers; i++) { igraph_vector_t* layer = igraph_i_layering_get(layering, i); igraph_vector_print(layer); } } */ IGRAPH_CHECK(igraph_vector_bool_init(&ignored_edges, no_of_edges)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &ignored_edges); IGRAPH_VECTOR_INIT_FINALLY(&vertex_to_the_left, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis1, 0); IGRAPH_VECTOR_INIT_FINALLY(&neis2, 0); /* First, find all type 1 conflicts and mark one of the edges participating * in the conflict as being ignored. If one of the edges in the conflict * is a non-inner segment and the other is an inner segment, we ignore the * non-inner segment as we want to keep inner segments vertical. */ for (i = 0; i < no_of_layers - 1; i++) { igraph_vector_t* vertices = igraph_i_layering_get(layering, i); n = igraph_vector_size(vertices); /* Find all the edges from this layer to the next */ igraph_vector_clear(&neis1); for (j = 0; j < n; j++) { IGRAPH_CHECK(igraph_neighbors(graph, &neis2, (igraph_integer_t) VECTOR(*vertices)[j], IGRAPH_OUT)); IGRAPH_CHECK(igraph_vector_append(&neis1, &neis2)); } /* Consider all pairs of edges and check whether they are in a type 1 * conflict */ n = igraph_vector_size(&neis1); for (j = 0; j < n; j++) { long int u = IGRAPH_FROM(graph, j); long int v = IGRAPH_TO(graph, j); igraph_bool_t j_inner = IS_INNER_SEGMENT(u, v); igraph_bool_t crossing; for (k = j + 1; k < n; k++) { long int w = IGRAPH_FROM(graph, k); long int x = IGRAPH_TO(graph, k); if (IS_INNER_SEGMENT(w, x) == j_inner) { continue; } /* Do the u --> v and w --> x edges cross? */ crossing = (u == w || v == x); if (!crossing) { if (X_POS(u) <= X_POS(w)) { crossing = X_POS(v) >= X_POS(x); } else { crossing = X_POS(v) <= X_POS(x); } } if (crossing) { if (j_inner) { VECTOR(ignored_edges)[k] = 1; } else { VECTOR(ignored_edges)[j] = 1; } } } } } igraph_vector_destroy(&neis1); igraph_vector_destroy(&neis2); IGRAPH_FINALLY_CLEAN(2); /* * Prepare vertex_to_the_left where the ith element stores * the index of the vertex to the left of vertex i, or i itself if the * vertex is the leftmost vertex in a layer. */ for (i = 0; i < no_of_layers; i++) { igraph_vector_t* vertices = igraph_i_layering_get(layering, i); n = igraph_vector_size(vertices); if (n == 0) { continue; } k = l = (long int)VECTOR(*vertices)[0]; VECTOR(vertex_to_the_left)[k] = k; for (j = 1; j < n; j++) { k = (long int)VECTOR(*vertices)[j]; VECTOR(vertex_to_the_left)[k] = l; l = k; } } /* Type 1 conflicts found, ignored edges chosen, vertex_to_the_left * prepared. Run vertical alignment for all four combinations */ for (i = 0; i < 4; i++) { IGRAPH_VECTOR_INIT_FINALLY(&xs[i], no_of_nodes); } IGRAPH_VECTOR_INIT_FINALLY(&roots, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&align, no_of_nodes); for (i = 0; i < 4; i++) { IGRAPH_CHECK(igraph_i_layout_sugiyama_vertical_alignment(graph, layering, layout, &ignored_edges, /* reverse = */ (igraph_bool_t) i / 2, /* align_right = */ i % 2, &roots, &align)); IGRAPH_CHECK(igraph_i_layout_sugiyama_horizontal_compaction(graph, &vertex_to_the_left, &roots, &align, hgap, &xs[i])); } { igraph_real_t width, min_width, mins[4], maxs[4], diff; /* Find the alignment with the minimum width */ min_width = IGRAPH_INFINITY; j = 0; for (i = 0; i < 4; i++) { mins[i] = igraph_vector_min(&xs[i]); maxs[i] = igraph_vector_max(&xs[i]); width = maxs[i] - mins[i]; if (width < min_width) { min_width = width; j = i; } } /* Leftmost alignments: align them s.t. the min X coordinate is equal to * the minimum X coordinate of the alignment with the smallest width. * Rightmost alignments: align them s.t. the max X coordinate is equal to * the max X coordinate of the alignment with the smallest width. */ for (i = 0; i < 4; i++) { if (j == i) { continue; } if (i % 2 == 0) { /* Leftmost alignment */ diff = mins[j] - mins[i]; } else { /* Rightmost alignment */ diff = maxs[j] - maxs[i]; } igraph_vector_add_constant(&xs[i], diff); } } /* For every vertex, find the median of the X coordinates in the four * alignments */ for (i = 0; i < no_of_nodes; i++) { X_POS(i) = igraph_i_median_4(VECTOR(xs[0])[i], VECTOR(xs[1])[i], VECTOR(xs[2])[i], VECTOR(xs[3])[i]); } igraph_vector_destroy(&roots); igraph_vector_destroy(&align); IGRAPH_FINALLY_CLEAN(2); for (i = 0; i < 4; i++) { igraph_vector_destroy(&xs[i]); } IGRAPH_FINALLY_CLEAN(4); igraph_vector_destroy(&vertex_to_the_left); IGRAPH_FINALLY_CLEAN(1); igraph_vector_bool_destroy(&ignored_edges); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } static int igraph_i_layout_sugiyama_vertical_alignment(const igraph_t* graph, const igraph_i_layering_t* layering, const igraph_matrix_t* layout, const igraph_vector_bool_t* ignored_edges, igraph_bool_t reverse, igraph_bool_t align_right, igraph_vector_t* roots, igraph_vector_t* align) { long int i, j, k, n, di, dj, i_limit, j_limit, r; long int no_of_layers = igraph_i_layering_num_layers(layering); long int no_of_nodes = igraph_vcount(graph); igraph_neimode_t neimode = (reverse ? IGRAPH_OUT : IGRAPH_IN); igraph_vector_t neis, xs, inds; IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_INIT_FINALLY(&xs, 0); IGRAPH_VECTOR_INIT_FINALLY(&inds, 0); IGRAPH_CHECK(igraph_vector_resize(roots, no_of_nodes)); IGRAPH_CHECK(igraph_vector_resize(align, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { VECTOR(*roots)[i] = VECTOR(*align)[i] = i; } /* When reverse = False, we are aligning "upwards" in the tree, hence we * have to loop i from 1 to no_of_layers-1 (inclusive) and use neimode=IGRAPH_IN. * When reverse = True, we are aligning "downwards", hence we have to loop * i from no_of_layers-2 to 0 (inclusive) and use neimode=IGRAPH_OUT. */ i = reverse ? (no_of_layers - 2) : 1; di = reverse ? -1 : 1; i_limit = reverse ? -1 : no_of_layers; for (; i != i_limit; i += di) { igraph_vector_t *layer = igraph_i_layering_get(layering, i); /* r = 0 in the paper, but C arrays are indexed from 0 */ r = align_right ? LONG_MAX : -1; /* If align_right is 1, we have to process the layer in reverse order */ j = align_right ? (igraph_vector_size(layer) - 1) : 0; dj = align_right ? -1 : 1; j_limit = align_right ? -1 : igraph_vector_size(layer); for (; j != j_limit; j += dj) { long int medians[2]; long int vertex = (long int) VECTOR(*layer)[j]; long int pos; if (VECTOR(*align)[vertex] != vertex) /* This vertex is already aligned with some other vertex, * so there's nothing to do */ { continue; } /* Find the neighbors of vertex j in layer i */ IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) vertex, neimode)); n = igraph_vector_size(&neis); if (n == 0) /* No neighbors in this direction, continue */ { continue; } if (n == 1) { /* Just one neighbor; the median is trivial */ medians[0] = (long int) VECTOR(neis)[0]; medians[1] = -1; } else { /* Sort the neighbors by their X coordinates */ IGRAPH_CHECK(igraph_vector_resize(&xs, n)); for (k = 0; k < n; k++) { VECTOR(xs)[k] = X_POS((long int)VECTOR(neis)[k]); } IGRAPH_CHECK((int) igraph_vector_qsort_ind(&xs, &inds, 0)); if (n % 2 == 1) { /* Odd number of neighbors, so the median is unique */ medians[0] = (long int) VECTOR(neis)[(long int)VECTOR(inds)[n / 2]]; medians[1] = -1; } else { /* Even number of neighbors, so we have two medians. The order * depends on whether we are processing the layer in leftmost * or rightmost fashion. */ if (align_right) { medians[0] = (long int) VECTOR(neis)[(long int)VECTOR(inds)[n / 2]]; medians[1] = (long int) VECTOR(neis)[(long int)VECTOR(inds)[n / 2 - 1]]; } else { medians[0] = (long int) VECTOR(neis)[(long int)VECTOR(inds)[n / 2 - 1]]; medians[1] = (long int) VECTOR(neis)[(long int)VECTOR(inds)[n / 2]]; } } } /* Try aligning with the medians */ for (k = 0; k < 2; k++) { igraph_integer_t eid; if (medians[k] < 0) { continue; } if (VECTOR(*align)[vertex] != vertex) { /* Vertex already aligned, continue */ continue; } /* Is the edge between medians[k] and vertex ignored * because of a type 1 conflict? */ IGRAPH_CHECK(igraph_get_eid(graph, &eid, (igraph_integer_t) vertex, (igraph_integer_t) medians[k], 0, 1)); if (VECTOR(*ignored_edges)[(long int)eid]) { continue; } /* Okay, align with the median if possible */ pos = (long int) X_POS(medians[k]); if ((align_right && r > pos) || (!align_right && r < pos)) { VECTOR(*align)[medians[k]] = vertex; VECTOR(*roots)[vertex] = VECTOR(*roots)[medians[k]]; VECTOR(*align)[vertex] = VECTOR(*roots)[medians[k]]; r = pos; } } } } igraph_vector_destroy(&inds); igraph_vector_destroy(&neis); igraph_vector_destroy(&xs); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /* * Runs a horizontal compaction given a vertical alignment (in `align`) * and the roots (in `roots`). These come out directly from * igraph_i_layout_sugiyama_vertical_alignment. * * Returns the X coordinates for each vertex in `xs`. * * `graph` is the input graph, `layering` is the layering on which we operate. * `hgap` is the preferred horizontal gap between vertices. */ static int igraph_i_layout_sugiyama_horizontal_compaction(const igraph_t* graph, const igraph_vector_t* vertex_to_the_left, const igraph_vector_t* roots, const igraph_vector_t* align, igraph_real_t hgap, igraph_vector_t* xs) { long int i; long int no_of_nodes = igraph_vcount(graph); igraph_vector_t sinks, shifts, old_xs; igraph_real_t shift; /* Initialization */ IGRAPH_VECTOR_INIT_FINALLY(&sinks, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&shifts, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&old_xs, no_of_nodes); IGRAPH_CHECK(igraph_vector_resize(xs, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { VECTOR(sinks)[i] = i; } igraph_vector_fill(&shifts, IGRAPH_INFINITY); igraph_vector_fill(xs, -1); /* Calculate the coordinates of the vertices relative to their sinks * in their own class. At the end of this for loop, xs will contain the * relative displacement of a vertex from its sink, while the shifts list * will contain the absolute displacement of the sinks. * (For the sinks only, of course, the rest is undefined and unused) */ for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*roots)[i] == i) { IGRAPH_CHECK( igraph_i_layout_sugiyama_horizontal_compaction_place_block(i, vertex_to_the_left, roots, align, &sinks, &shifts, hgap, xs) ); } } /* In "sinks", only those indices `i` matter for which `i` is in `roots`. * All the other values will never be touched. */ /* Calculate the absolute coordinates */ IGRAPH_CHECK(igraph_vector_update(&old_xs, xs)); for (i = 0; i < no_of_nodes; i++) { long int root = (long int) VECTOR(*roots)[i]; VECTOR(*xs)[i] = VECTOR(old_xs)[root]; shift = VECTOR(shifts)[(long int)VECTOR(sinks)[root]]; if (shift < IGRAPH_INFINITY) { VECTOR(*xs)[i] += shift; } } igraph_vector_destroy(&sinks); igraph_vector_destroy(&shifts); igraph_vector_destroy(&old_xs); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } static int igraph_i_layout_sugiyama_horizontal_compaction_place_block(long int v, const igraph_vector_t* vertex_to_the_left, const igraph_vector_t* roots, const igraph_vector_t* align, igraph_vector_t* sinks, igraph_vector_t* shifts, igraph_real_t hgap, igraph_vector_t* xs) { long int u, w; long int u_sink, v_sink; if (VECTOR(*xs)[v] >= 0) { return IGRAPH_SUCCESS; } VECTOR(*xs)[v] = 0; w = v; do { /* Check whether vertex w is the leftmost in its own layer */ u = (long int) VECTOR(*vertex_to_the_left)[w]; if (u != w) { /* Get the root of u (proceeding all the way upwards in the block) */ u = (long int) VECTOR(*roots)[u]; /* Place the block of u recursively */ IGRAPH_CHECK( igraph_i_layout_sugiyama_horizontal_compaction_place_block(u, vertex_to_the_left, roots, align, sinks, shifts, hgap, xs) ); u_sink = (long int) VECTOR(*sinks)[u]; v_sink = (long int) VECTOR(*sinks)[v]; /* If v is its own sink yet, set its sink to the sink of u */ if (v_sink == v) { VECTOR(*sinks)[v] = v_sink = u_sink; } /* If v and u have different sinks (i.e. they are in different classes), * shift the sink of u so that the two blocks are separated by the * preferred gap */ if (v_sink != u_sink) { if (VECTOR(*shifts)[u_sink] > VECTOR(*xs)[v] - VECTOR(*xs)[u] - hgap) { VECTOR(*shifts)[u_sink] = VECTOR(*xs)[v] - VECTOR(*xs)[u] - hgap; } } else { /* v and u have the same sink, i.e. they are in the same class. Make sure * that v is separated from u by at least hgap. */ if (VECTOR(*xs)[v] < VECTOR(*xs)[u] + hgap) { VECTOR(*xs)[v] = VECTOR(*xs)[u] + hgap; } } } /* Follow the alignment */ w = (long int) VECTOR(*align)[w]; } while (w != v); return IGRAPH_SUCCESS; } #undef IS_INNER_SEGMENT #undef IS_DUMMY #undef X_POS #ifdef SUGIYAMA_DEBUG #undef SUGIYAMA_DEBUG #endif leidenbase/src/core/layout/drl/0000755000176200001440000000000014532173045016166 5ustar liggesusersleidenbase/src/core/layout/drl/drl_layout_3d.h0000644000176200001440000000563614447675374021136 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This file contains compile time parameters which affect the entire // DrL program. #define DRL_VERSION "3.2 5/5/2006" // compile time parameters for MPI message passing #define MAX_PROCS 256 // maximum number of processors #define MAX_FILE_NAME 250 // max length of filename #define MAX_INT_LENGTH 4 // max length of integer suffix of intermediate .coord file // Compile time adjustable parameters for the Density grid #define GRID_SIZE 100 // size of Density grid #define VIEW_SIZE 250.0 // actual physical size of layout plane // these values use more memory but have // little effect on performance or layout #define RADIUS 10 // radius for density fall-off: // larger values tends to slow down // the program and clump the data #define HALF_VIEW 125.0 // 1/2 of VIEW_SIZE #define VIEW_TO_GRID .4 // ratio of GRID_SIZE to VIEW_SIZE /* // original values for VxOrd #define GRID_SIZE 400 // size of VxOrd Density grid #define VIEW_SIZE 1600.0 // actual physical size of VxOrd plane #define RADIUS 10 // radius for density fall-off #define HALF_VIEW 800 // 1/2 of VIEW_SIZE #define VIEW_TO_GRID .25 // ratio of GRID_SIZE to VIEW_SIZE */ leidenbase/src/core/layout/drl/DensityGrid.h0000644000176200001440000000532514447675374020612 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __DENSITY_GRID_H__ #define __DENSITY_GRID_H__ // Compile time adjustable parameters #include "drl_layout.h" #include "drl_Node.h" #ifdef MUSE_MPI #include #endif #include namespace drl { class DensityGrid { public: // Methods void Init(); void Subtract(Node &n, bool first_add, bool fine_first_add, bool fineDensity); void Add(Node &n, bool fineDensity ); float GetDensity(float Nx, float Ny, bool fineDensity); // Contructor/Destructor DensityGrid() {}; ~DensityGrid(); private: // Private Members void Subtract( Node &N ); void Add( Node &N ); void fineSubtract( Node &N ); void fineAdd( Node &N ); // new dynamic variables -- SBM float (*fall_off)[RADIUS * 2 + 1]; float (*Density)[GRID_SIZE]; std::deque* Bins; // old static variables //float fall_off[RADIUS*2+1][RADIUS*2+1]; //float Density[GRID_SIZE][GRID_SIZE]; //deque Bins[GRID_SIZE][GRID_SIZE]; }; } // namespace drl #endif // __DENSITY_GRID_H__ leidenbase/src/core/layout/drl/drl_graph.h0000644000176200001440000001146114447675374020325 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // The graph class contains the methods necessary to draw the // graph. It calls on the density server class to obtain // position and density information #include "DensityGrid.h" #include "igraph_layout.h" #include #include #include namespace drl { // layout schedule information struct layout_schedule { int iterations; float temperature; float attraction; float damping_mult; time_t time_elapsed; }; class graph { public: // Methods void init_parms ( int rand_seed, float edge_cut, float real_parm ); void init_parms ( const igraph_layout_drl_options_t *options ); void read_parms ( char *parms_file ); void read_real ( char *real_file ); int read_real ( const igraph_matrix_t *real_mat, const igraph_vector_bool_t *fixed); void scan_int ( char *filename ); void read_int ( char *file_name ); void draw_graph ( int int_out, char *coord_file ); int draw_graph (igraph_matrix_t *res); void write_coord ( const char *file_name ); void write_sim ( const char *file_name ); float get_tot_energy ( ); // Con/Decon graph( int proc_id, int tot_procs, char *int_file ); ~graph( ) { } graph( const igraph_t *igraph, const igraph_layout_drl_options_t *options, const igraph_vector_t *weights); private: // Methods int ReCompute ( ); void update_nodes ( ); float Compute_Node_Energy ( int node_ind ); void Solve_Analytic ( int node_ind, float &pos_x, float &pos_y ); void get_positions ( std::vector &node_indices, float return_positions[2 * MAX_PROCS] ); void update_density ( std::vector &node_indices, float old_positions[2 * MAX_PROCS], float new_positions[2 * MAX_PROCS] ); void update_node_pos ( int node_ind, float old_positions[2 * MAX_PROCS], float new_positions[2 * MAX_PROCS] ); // MPI information int myid, num_procs; // graph decomposition information int num_nodes; // number of nodes in graph float highest_sim; // highest sim for normalization std::map id_catalog; // id_catalog[file id] = internal id std::map > neighbors; // neighbors of nodes on this proc. // graph layout information std::vector positions; DensityGrid density_server; // original VxOrd information int STAGE, iterations; float temperature, attraction, damping_mult; float min_edges, CUT_END, cut_length_end, cut_off_length, cut_rate; bool first_add, fine_first_add, fineDensity; // scheduling variables layout_schedule liquid; layout_schedule expansion; layout_schedule cooldown; layout_schedule crunch; layout_schedule simmer; // timing statistics time_t start_time, stop_time; // online clustering information int real_iterations; // number of iterations to hold .real input fixed int tot_iterations; int tot_expected_iterations; // for progress bar bool real_fixed; }; } // namespace drl leidenbase/src/core/layout/drl/DensityGrid_3d.h0000644000176200001440000000540414447675374021176 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __DENSITY_GRID_H__ #define __DENSITY_GRID_H__ // Compile time adjustable parameters #include "drl_layout_3d.h" #include "drl_Node_3d.h" #ifdef MUSE_MPI #include #endif #include namespace drl3d { class DensityGrid { public: // Methods void Init(); void Subtract(Node &n, bool first_add, bool fine_first_add, bool fineDensity); void Add(Node &n, bool fineDensity ); float GetDensity(float Nx, float Ny, float Nz, bool fineDensity); // Contructor/Destructor DensityGrid() {}; ~DensityGrid(); private: // Private Members void Subtract( Node &N ); void Add( Node &N ); void fineSubtract( Node &N ); void fineAdd( Node &N ); // new dynamic variables -- SBM float (*fall_off)[RADIUS * 2 + 1][RADIUS * 2 + 1]; float (*Density)[GRID_SIZE][GRID_SIZE]; std::deque* Bins; // old static variables //float fall_off[RADIUS*2+1][RADIUS*2+1]; //float Density[GRID_SIZE][GRID_SIZE]; //deque Bins[GRID_SIZE][GRID_SIZE]; }; } // namespace drl3d #endif // __DENSITY_GRID_H__ leidenbase/src/core/layout/drl/DensityGrid_3d.cpp0000644000176200001440000002412714447675374021534 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This file contains the member definitions of the DensityGrid.h class // This code is modified from the original code by B.N. Wylie #include "drl_Node_3d.h" #include "DensityGrid_3d.h" #include "igraph_error.h" #include #include using namespace std; #define GET_BIN(z, y, x) (Bins[(z*GRID_SIZE+y)*GRID_SIZE+x]) namespace drl3d { //******************************************************* // Density Grid Destructor -- deallocates memory used // for Density matrix, fall_off matrix, and node deque. DensityGrid::~DensityGrid () { delete[] Density; delete[] fall_off; delete[] Bins; } /********************************************* * Function: Density_Grid::Reset * * Description: Reset the density grid * *********************************************/ // changed from reset to init since we will only // call this once in the parallel version of layout void DensityGrid::Init() { try { Density = new float[GRID_SIZE][GRID_SIZE][GRID_SIZE]; fall_off = new float[RADIUS * 2 + 1][RADIUS * 2 + 1][RADIUS * 2 + 1]; Bins = new deque[GRID_SIZE * GRID_SIZE * GRID_SIZE]; } catch (bad_alloc&) { // cout << "Error: Out of memory! Program stopped." << endl; #ifdef MUSE_MPI MPI_Abort ( MPI_COMM_WORLD, 1 ); #else igraph_error("DrL is out of memory", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return; #endif } // Clear Grid int i; for (i = 0; i < GRID_SIZE; i++) for (int j = 0; j < GRID_SIZE; j++) for (int k = 0; k < GRID_SIZE; k++) { Density[i][j][k] = 0; GET_BIN(i, j, k).erase(GET_BIN(i, j, k).begin(), GET_BIN(i, j, k).end()); } // Compute fall off for (i = -RADIUS; i <= RADIUS; i++) for (int j = -RADIUS; j <= RADIUS; j++) for (int k = -RADIUS; k <= RADIUS; k++) { fall_off[i + RADIUS][j + RADIUS][k + RADIUS] = (float)((RADIUS - fabs((float)i)) / RADIUS) * (float)((RADIUS - fabs((float)j)) / RADIUS) * (float)((RADIUS - fabs((float)k)) / RADIUS); } } /*************************************************** * Function: DensityGrid::GetDensity * * Description: Get_Density from density grid * **************************************************/ float DensityGrid::GetDensity(float Nx, float Ny, float Nz, bool fineDensity) { deque::iterator BI; int x_grid, y_grid, z_grid; float x_dist, y_dist, z_dist, distance, density = 0; int boundary = 10; // boundary around plane /* Where to look */ x_grid = (int)((Nx + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((Ny + HALF_VIEW + .5) * VIEW_TO_GRID); z_grid = (int)((Nz + HALF_VIEW + .5) * VIEW_TO_GRID); // Check for edges of density grid (10000 is arbitrary high density) if (x_grid > GRID_SIZE - boundary || x_grid < boundary) { return 10000; } if (y_grid > GRID_SIZE - boundary || y_grid < boundary) { return 10000; } if (z_grid > GRID_SIZE - boundary || z_grid < boundary) { return 10000; } // Fine density? if (fineDensity) { // Go through nearest bins for (int k = z_grid - 1; k <= z_grid + 1; k++) for (int i = y_grid - 1; i <= y_grid + 1; i++) for (int j = x_grid - 1; j <= x_grid + 1; j++) { // Look through bin and add fine repulsions for (BI = GET_BIN(k, i, j).begin(); BI < GET_BIN(k, i, j).end(); ++BI) { x_dist = Nx - (BI->x); y_dist = Ny - (BI->y); z_dist = Nz - (BI->z); distance = x_dist * x_dist + y_dist * y_dist + z_dist * z_dist; density += 1e-4 / (distance + 1e-50); } } // Course density } else { // Add rough estimate density = Density[z_grid][y_grid][x_grid]; density *= density; } return density; } /// Wrapper functions for the Add and subtract methods /// Nodes should all be passed by constant ref void DensityGrid::Add(Node &n, bool fineDensity) { if (fineDensity) { fineAdd(n); } else { Add(n); } } void DensityGrid::Subtract( Node &n, bool first_add, bool fine_first_add, bool fineDensity) { if ( fineDensity && !fine_first_add ) { fineSubtract (n); } else if ( !first_add ) { Subtract(n); } } /*************************************************** * Function: DensityGrid::Subtract * * Description: Subtract a node from density grid * **************************************************/ void DensityGrid::Subtract(Node &N) { int x_grid, y_grid, z_grid, diam; float *den_ptr, *fall_ptr; /* Where to subtract */ x_grid = (int)((N.sub_x + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((N.sub_y + HALF_VIEW + .5) * VIEW_TO_GRID); z_grid = (int)((N.sub_z + HALF_VIEW + .5) * VIEW_TO_GRID); x_grid -= RADIUS; y_grid -= RADIUS; z_grid -= RADIUS; diam = 2 * RADIUS; // check to see that we are inside grid if ( (x_grid >= GRID_SIZE) || (x_grid < 0) || (y_grid >= GRID_SIZE) || (y_grid < 0) || (z_grid >= GRID_SIZE) || (z_grid < 0) ) { #ifdef MUSE_MPI MPI_Abort ( MPI_COMM_WORLD, 1 ); #else igraph_error("Exceeded density grid in DrL", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EDRL); return; #endif } /* Subtract density values */ den_ptr = &Density[z_grid][y_grid][x_grid]; fall_ptr = &fall_off[0][0][0]; for (int i = 0; i <= diam; i++) { for (int j = 0; j <= diam; j++) for (int k = 0; k <= diam; k++) { *den_ptr++ -= *fall_ptr++; } den_ptr += GRID_SIZE - (diam + 1); } } /*************************************************** * Function: DensityGrid::Add * * Description: Add a node to the density grid * **************************************************/ void DensityGrid::Add(Node &N) { int x_grid, y_grid, z_grid, diam; float *den_ptr, *fall_ptr; /* Where to add */ x_grid = (int)((N.x + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((N.y + HALF_VIEW + .5) * VIEW_TO_GRID); z_grid = (int)((N.z + HALF_VIEW + .5) * VIEW_TO_GRID); N.sub_x = N.x; N.sub_y = N.y; N.sub_z = N.z; x_grid -= RADIUS; y_grid -= RADIUS; z_grid -= RADIUS; diam = 2 * RADIUS; // check to see that we are inside grid if ( (x_grid >= GRID_SIZE) || (x_grid < 0) || (y_grid >= GRID_SIZE) || (y_grid < 0) || (z_grid >= GRID_SIZE) || (z_grid < 0) ) { #ifdef MUSE_MPI MPI_Abort ( MPI_COMM_WORLD, 1 ); #else igraph_error("Exceeded density grid in DrL", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EDRL); return; #endif } /* Add density values */ den_ptr = &Density[z_grid][y_grid][x_grid]; fall_ptr = &fall_off[0][0][0]; for (int i = 0; i <= diam; i++) { for (int j = 0; j <= diam; j++) for (int k = 0; k <= diam; k++) { *den_ptr++ += *fall_ptr++; } den_ptr += GRID_SIZE - (diam + 1); } } /*************************************************** * Function: DensityGrid::fineSubtract * * Description: Subtract a node from bins * **************************************************/ void DensityGrid::fineSubtract(Node &N) { int x_grid, y_grid, z_grid; /* Where to subtract */ x_grid = (int)((N.sub_x + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((N.sub_y + HALF_VIEW + .5) * VIEW_TO_GRID); z_grid = (int)((N.sub_z + HALF_VIEW + .5) * VIEW_TO_GRID); GET_BIN(z_grid, y_grid, x_grid).pop_front(); } /*************************************************** * Function: DensityGrid::fineAdd * * Description: Add a node to the bins * **************************************************/ void DensityGrid::fineAdd(Node &N) { int x_grid, y_grid, z_grid; /* Where to add */ x_grid = (int)((N.x + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((N.y + HALF_VIEW + .5) * VIEW_TO_GRID); z_grid = (int)((N.z + HALF_VIEW + .5) * VIEW_TO_GRID); N.sub_x = N.x; N.sub_y = N.y; N.sub_z = N.z; GET_BIN(z_grid, y_grid, x_grid).push_back(N); } } // namespace drl3d leidenbase/src/core/layout/drl/drl_graph.cpp0000644000176200001440000012066414447675374020666 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This file contains the member definitions of the master class #include #include #include using namespace std; #include "drl_graph.h" #include "igraph_random.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "core/interruption.h" #ifdef MUSE_MPI #include #endif namespace drl { // constructor -- initializes the schedule variables (as in // graph constructor) // graph::graph ( int proc_id, int tot_procs, char *int_file ) // { // // MPI parameters // myid = proc_id; // num_procs = tot_procs; // // initial annealing parameters // STAGE = 0; // iterations = 0; // temperature = 2000; // attraction = 10; // damping_mult = 1.0; // min_edges = 20; // first_add = fine_first_add = true; // fineDensity = false; // // Brian's original Vx schedule // liquid.iterations = 200; // liquid.temperature = 2000; // liquid.attraction = 2; // liquid.damping_mult = 1.0; // liquid.time_elapsed = 0; // expansion.iterations = 200; // expansion.temperature = 2000; // expansion.attraction = 10; // expansion.damping_mult = 1.0; // expansion.time_elapsed = 0; // cooldown.iterations = 200; // cooldown.temperature = 2000; // cooldown.attraction = 1; // cooldown.damping_mult = .1; // cooldown.time_elapsed = 0; // crunch.iterations = 50; // crunch.temperature = 250; // crunch.attraction = 1; // crunch. damping_mult = .25; // crunch.time_elapsed = 0; // simmer.iterations = 100; // simmer.temperature = 250; // simmer.attraction = .5; // simmer.damping_mult = 0.0; // simmer.time_elapsed = 0; // // scan .int file for node info // scan_int ( int_file ); // // populate node positions and ids // positions.reserve ( num_nodes ); // map < int, int >::iterator cat_iter; // for ( cat_iter = id_catalog.begin(); // cat_iter != id_catalog.end(); // cat_iter++ ) // positions.push_back ( Node( cat_iter->first ) ); // /* // // output positions .ids for debugging // for ( int id = 0; id < num_nodes; id++ ) // cout << positions[id].id << endl; // */ // // read .int file for graph info // read_int ( int_file ); // // initialize density server // density_server.Init(); // } graph::graph(const igraph_t *igraph, const igraph_layout_drl_options_t *options, const igraph_vector_t *weights) { myid = 0; num_procs = 1; STAGE = 0; iterations = options->init_iterations; temperature = options->init_temperature; attraction = options->init_attraction; damping_mult = options->init_damping_mult; min_edges = 20; first_add = fine_first_add = true; fineDensity = false; // Brian's original Vx schedule liquid.iterations = options->liquid_iterations; liquid.temperature = options->liquid_temperature; liquid.attraction = options->liquid_attraction; liquid.damping_mult = options->liquid_damping_mult; liquid.time_elapsed = 0; expansion.iterations = options->expansion_iterations; expansion.temperature = options->expansion_temperature; expansion.attraction = options->expansion_attraction; expansion.damping_mult = options->expansion_damping_mult; expansion.time_elapsed = 0; cooldown.iterations = options->cooldown_iterations; cooldown.temperature = options->cooldown_temperature; cooldown.attraction = options->cooldown_attraction; cooldown.damping_mult = options->cooldown_damping_mult; cooldown.time_elapsed = 0; crunch.iterations = options->crunch_iterations; crunch.temperature = options->crunch_temperature; crunch.attraction = options->crunch_attraction; crunch.damping_mult = options->crunch_damping_mult; crunch.time_elapsed = 0; simmer.iterations = options->simmer_iterations; simmer.temperature = options->simmer_temperature; simmer.attraction = options->simmer_attraction; simmer.damping_mult = options->simmer_damping_mult; simmer.time_elapsed = 0; // scan .int file for node info highest_sim = 1.0; num_nodes = igraph_vcount(igraph); long int no_of_edges = igraph_ecount(igraph); for (long int i = 0; i < num_nodes; i++) { id_catalog[i] = 1; } map< int, int>::iterator cat_iter; for ( cat_iter = id_catalog.begin(); cat_iter != id_catalog.end(); cat_iter++) { cat_iter->second = cat_iter->first; } // populate node positions and ids positions.reserve ( num_nodes ); for ( cat_iter = id_catalog.begin(); cat_iter != id_catalog.end(); cat_iter++ ) { positions.push_back ( Node( cat_iter->first ) ); } // read .int file for graph info long int node_1, node_2; double weight; for (long int i = 0; i < no_of_edges; i++) { node_1 = IGRAPH_FROM(igraph, i); node_2 = IGRAPH_TO(igraph, i); weight = weights ? VECTOR(*weights)[i] : 1.0 ; (neighbors[id_catalog[node_1]])[id_catalog[node_2]] = weight; (neighbors[id_catalog[node_2]])[id_catalog[node_1]] = weight; } // initialize density server density_server.Init(); } // The following subroutine scans the .int file for the following // information: number nodes, node ids, and highest similarity. The // corresponding graph globals are populated: num_nodes, id_catalog, // and highest_sim. // void graph::scan_int ( char *filename ) // { // cout << "Proc. " << myid << " scanning .int file ..." << endl; // // Open (sim) File // ifstream fp ( filename ); // if ( !fp ) // { // cout << "Error: could not open " << filename << ". Program terminated." << endl; // #ifdef MUSE_MPI // MPI_Abort ( MPI_COMM_WORLD, 1 ); // #else // exit (1); // #endif // } // // Read file, parse, and add into data structure // int id1, id2; // float edge_weight; // highest_sim = -1.0; // while ( !fp.eof () ) // { // fp >> id1 >> id2 >> edge_weight; // // ignore negative weights! // if ( edge_weight <= 0 ) // { // cout << "Error: found negative edge weight in " << filename << ". Program stopped." << endl; // #ifdef MUSE_MPI // MPI_Abort ( MPI_COMM_WORLD, 1 ); // #else // exit (1); // #endif // } // if ( highest_sim < edge_weight ) // highest_sim = edge_weight; // id_catalog[id1] = 1; // id_catalog[id2] = 1; // } // fp.close(); // if ( id_catalog.size() == 0 ) // { // cout << "Error: Proc. " << myid << ": " << filename << " is empty. Program terminated." << endl; // #ifdef MUSE_MPI // MPI_Abort ( MPI_COMM_WORLD, 1 ); // #else // exit (1); // #endif // } // // label nodes with sequential integers starting at 0 // map< int, int>::iterator cat_iter; // int id_label; // for ( cat_iter = id_catalog.begin(), id_label = 0; // cat_iter != id_catalog.end(); cat_iter++, id_label++ ) // cat_iter->second = id_label; // /* // // output id_catalog for debugging: // for ( cat_iter = id_catalog.begin(); // cat_iter != id_catalog.end(); // cat_iter++ ) // cout << cat_iter->first << "\t" << cat_iter->second << endl; // */ // num_nodes = id_catalog.size(); // } // read in .parms file, if present /* void graph::read_parms ( char *parms_file ) { // read from .parms file ifstream parms_in ( parms_file ); if ( !parms_in ) { cout << "Error: could not open .parms file! Program stopped." << endl; #ifdef MUSE_MPI MPI_Abort ( MPI_COMM_WORLD, 1 ); #else exit (1); #endif } cout << "Processor " << myid << " reading .parms file." << endl; // read in stage parameters string parm_label; // this is ignored in the .parms file // initial parameters parms_in >> parm_label >> iterations; parms_in >> parm_label >> temperature; parms_in >> parm_label >> attraction; parms_in >> parm_label >> damping_mult; // liquid stage parms_in >> parm_label >> liquid.iterations; parms_in >> parm_label >> liquid.temperature; parms_in >> parm_label >> liquid.attraction; parms_in >> parm_label >> liquid.damping_mult; // expansion stage parms_in >> parm_label >> expansion.iterations; parms_in >> parm_label >> expansion.temperature; parms_in >> parm_label >> expansion.attraction; parms_in >> parm_label >> expansion.damping_mult; // cooldown stage parms_in >> parm_label >> cooldown.iterations; parms_in >> parm_label >> cooldown.temperature; parms_in >> parm_label >> cooldown.attraction; parms_in >> parm_label >> cooldown.damping_mult; // crunch stage parms_in >> parm_label >> crunch.iterations; parms_in >> parm_label >> crunch.temperature; parms_in >> parm_label >> crunch.attraction; parms_in >> parm_label >> crunch.damping_mult; // simmer stage parms_in >> parm_label >> simmer.iterations; parms_in >> parm_label >> simmer.temperature; parms_in >> parm_label >> simmer.attraction; parms_in >> parm_label >> simmer.damping_mult; parms_in.close(); // print out parameters for double checking if ( myid == 0 ) { cout << "Processor 0 reports the following inputs:" << endl; cout << "inital.iterations = " << iterations << endl; cout << "initial.temperature = " << temperature << endl; cout << "initial.attraction = " << attraction << endl; cout << "initial.damping_mult = " << damping_mult << endl; cout << " ..." << endl; cout << "liquid.iterations = " << liquid.iterations << endl; cout << "liquid.temperature = " << liquid.temperature << endl; cout << "liquid.attraction = " << liquid.attraction << endl; cout << "liquid.damping_mult = " << liquid.damping_mult << endl; cout << " ..." << endl; cout << "simmer.iterations = " << simmer.iterations << endl; cout << "simmer.temperature = " << simmer.temperature << endl; cout << "simmer.attraction = " << simmer.attraction << endl; cout << "simmer.damping_mult = " << simmer.damping_mult << endl; } } */ // init_parms -- this subroutine initializes the edge_cut variables // used in the original VxOrd starting with the edge_cut parameter. // In our version, edge_cut = 0 means no cutting, 1 = maximum cut. // We also set the random seed here. void graph::init_parms ( int rand_seed, float edge_cut, float real_parm ) { IGRAPH_UNUSED(rand_seed); // first we translate edge_cut the former tcl sliding scale //CUT_END = cut_length_end = 39000.0 * (1.0 - edge_cut) + 1000.0; CUT_END = cut_length_end = 40000.0 * (1.0 - edge_cut); // cut_length_end cannot actually be 0 if ( cut_length_end <= 1.0 ) { cut_length_end = 1.0; } float cut_length_start = 4.0 * cut_length_end; // now we set the parameters used by ReCompute cut_off_length = cut_length_start; cut_rate = ( cut_length_start - cut_length_end ) / 400.0; // finally set the number of iterations to leave .real coords fixed int full_comp_iters; full_comp_iters = liquid.iterations + expansion.iterations + cooldown.iterations + crunch.iterations + 3; // adjust real parm to iterations (do not enter simmer halfway) if ( real_parm < 0 ) { real_iterations = (int)real_parm; } else if ( real_parm == 1) { real_iterations = full_comp_iters + simmer.iterations + 100; } else { real_iterations = (int)(real_parm * full_comp_iters); } tot_iterations = 0; if ( real_iterations > 0 ) { real_fixed = true; } else { real_fixed = false; } // calculate total expected iterations (for progress bar display) tot_expected_iterations = liquid.iterations + expansion.iterations + cooldown.iterations + crunch.iterations + simmer.iterations; /* // output edge_cutting parms (for debugging) cout << "Processor " << myid << ": " << "cut_length_end = CUT_END = " << cut_length_end << ", cut_length_start = " << cut_length_start << ", cut_rate = " << cut_rate << endl; */ // set random seed // srand ( rand_seed ); // Don't need this in igraph } void graph::init_parms(const igraph_layout_drl_options_t *options) { double rand_seed = 0.0; double real_in = -1.0; init_parms(rand_seed, options->edge_cut, real_in); } // The following subroutine reads a .real file to obtain initial // coordinates. If a node is missing coordinates the coordinates // are computed // void graph::read_real ( char *real_file ) // { // cout << "Processor " << myid << " reading .real file ..." << endl; // // read in .real file and mark as fixed // ifstream real_in ( real_file ); // if ( !real_in ) // { // cout << "Error: proc. " << myid << " could not open .real file." << endl; // #ifdef MUSE_MPI // MPI_Abort ( MPI_COMM_WORLD, 1 ); // #else // exit (1); // #endif // } // int real_id; // float real_x, real_y; // while ( !real_in.eof () ) // { // real_id = -1; // real_in >> real_id >> real_x >> real_y; // if ( real_id >= 0 ) // { // positions[id_catalog[real_id]].x = real_x; // positions[id_catalog[real_id]].y = real_y; // positions[id_catalog[real_id]].fixed = true; // /* // // output positions read (for debugging) // cout << id_catalog[real_id] << " (" << positions[id_catalog[real_id]].x // << ", " << positions[id_catalog[real_id]].y << ") " // << positions[id_catalog[real_id]].fixed << endl; // */ // // add node to density grid // if ( real_iterations > 0 ) // density_server.Add ( positions[id_catalog[real_id]], fineDensity ); // } // } // real_in.close(); // } int graph::read_real ( const igraph_matrix_t *real_mat, const igraph_vector_bool_t *fixed) { long int n = igraph_matrix_nrow(real_mat); for (long int i = 0; i < n; i++) { positions[id_catalog[i]].x = MATRIX(*real_mat, i, 0); positions[id_catalog[i]].y = MATRIX(*real_mat, i, 1); positions[id_catalog[i]].fixed = fixed ? VECTOR(*fixed)[i] : false; if ( real_iterations > 0 ) { density_server.Add ( positions[id_catalog[i]], fineDensity ); } } return 0; } // The read_part_int subroutine reads the .int // file produced by convert_sim and gathers the nodes and their // neighbors in the range start_ind to end_ind. // void graph::read_int ( char *file_name ) // { // ifstream int_file; // int_file.open ( file_name ); // if ( !int_file ) // { // cout << "Error (worker process " << myid << "): could not open .int file." << endl; // #ifdef MUSE_MPI // MPI_Abort ( MPI_COMM_WORLD, 1 ); // #else // exit (1); // #endif // } // cout << "Processor " << myid << " reading .int file ..." << endl; // int node_1, node_2; // float weight; // while ( !int_file.eof() ) // { // weight = 0; // all weights should be >= 0 // int_file >> node_1 >> node_2 >> weight; // if ( weight ) // otherwise we are at end of file // // or it is a self-connected node // { // // normalization from original vxord // weight /= highest_sim; // weight = weight*fabs(weight); // // initialize graph // if ( ( node_1 % num_procs ) == myid ) // (neighbors[id_catalog[node_1]])[id_catalog[node_2]] = weight; // if ( ( node_2 % num_procs ) == myid ) // (neighbors[id_catalog[node_2]])[id_catalog[node_1]] = weight; // } // } // int_file.close(); // /* // // the following code outputs the contents of the neighbors structure // // (to be used for debugging) // map >::iterator i; // map::iterator j; // for ( i = neighbors.begin(); i != neighbors.end(); i++ ) { // cout << myid << ": " << i->first << " "; // for (j = (i->second).begin(); j != (i->second).end(); j++ ) // cout << j->first << " (" << j->second << ") "; // cout << endl; // } // */ // } /********************************************* * Function: ReCompute * * Description: Compute the graph locations * * Modified from original code by B. Wylie * ********************************************/ int graph::ReCompute( ) { // carryover from original VxOrd int MIN = 1; /* // output parameters (for debugging) cout << "ReCompute is using the following parameters: "<< endl; cout << "STAGE: " << STAGE << ", iter: " << iterations << ", temp = " << temperature << ", attract = " << attraction << ", damping_mult = " << damping_mult << ", min_edges = " << min_edges << ", cut_off_length = " << cut_off_length << ", fineDensity = " << fineDensity << endl; */ /* igraph progress report */ float progress = (tot_iterations * 100.0 / tot_expected_iterations); switch (STAGE) { case 0: if (iterations == 0) { IGRAPH_PROGRESS("DrL layout (initialization stage)", progress, 0); } else { IGRAPH_PROGRESS("DrL layout (liquid stage)", progress, 0); } break; case 1: IGRAPH_PROGRESS("DrL layout (expansion stage)", progress, 0); break; case 2: IGRAPH_PROGRESS("DrL layout (cooldown and cluster phase)", progress, 0); break; case 3: IGRAPH_PROGRESS("DrL layout (crunch phase)", progress, 0); break; case 5: IGRAPH_PROGRESS("DrL layout (simmer phase)", progress, 0); break; case 6: IGRAPH_PROGRESS("DrL layout (final phase)", 100.0, 0); break; default: IGRAPH_PROGRESS("DrL layout (unknown phase)", 0.0, 0); break; } /* Compute Energies for individual nodes */ update_nodes (); // check to see if we need to free fixed nodes tot_iterations++; if ( tot_iterations >= real_iterations ) { real_fixed = false; } // **************************************** // AUTOMATIC CONTROL SECTION // **************************************** // STAGE 0: LIQUID if (STAGE == 0) { if ( iterations == 0 ) { start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering liquid stage ..."; } if (iterations < liquid.iterations) { temperature = liquid.temperature; attraction = liquid.attraction; damping_mult = liquid.damping_mult; iterations++; // if ( myid == 0 ) // cout << "." << flush; } else { stop_time = time( NULL ); liquid.time_elapsed = liquid.time_elapsed + (stop_time - start_time); temperature = expansion.temperature; attraction = expansion.attraction; damping_mult = expansion.damping_mult; iterations = 0; // go to next stage STAGE = 1; start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering expansion stage ..."; } } // STAGE 1: EXPANSION if (STAGE == 1) { if (iterations < expansion.iterations) { // Play with vars if (attraction > 1) { attraction -= .05f; } if (min_edges > 12) { min_edges -= .05f; } cut_off_length -= cut_rate; if (damping_mult > .1) { damping_mult -= .005f; } iterations++; // if ( myid == 0 ) cout << "." << flush; } else { stop_time = time( NULL ); expansion.time_elapsed = expansion.time_elapsed + (stop_time - start_time); min_edges = 12; damping_mult = cooldown.damping_mult; STAGE = 2; attraction = cooldown.attraction; temperature = cooldown.temperature; iterations = 0; start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering cool-down stage ..."; } } // STAGE 2: Cool down and cluster else if (STAGE == 2) { if (iterations < cooldown.iterations) { // Reduce temperature if (temperature > 50) { temperature -= 10; } // Reduce cut length if (cut_off_length > cut_length_end) { cut_off_length -= cut_rate * 2; } if (min_edges > MIN) { min_edges -= .2f; } //min_edges = 99; iterations++; // if ( myid == 0 ) // cout << "." << flush; } else { stop_time = time( NULL ); cooldown.time_elapsed = cooldown.time_elapsed + (stop_time - start_time); cut_off_length = cut_length_end; temperature = crunch.temperature; damping_mult = crunch.damping_mult; min_edges = MIN; //min_edges = 99; // In other words: no more cutting STAGE = 3; iterations = 0; attraction = crunch.attraction; start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering crunch stage ..."; } } // STAGE 3: Crunch else if (STAGE == 3) { if (iterations < crunch.iterations) { iterations++; // if ( myid == 0 ) cout << "." << flush; } else { stop_time = time( NULL ); crunch.time_elapsed = crunch.time_elapsed + (stop_time - start_time); iterations = 0; temperature = simmer.temperature; attraction = simmer.attraction; damping_mult = simmer.damping_mult; min_edges = 99; fineDensity = true; STAGE = 5; start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering simmer stage ..."; } } // STAGE 5: Simmer else if ( STAGE == 5 ) { if (iterations < simmer.iterations) { if (temperature > 50) { temperature -= 2; } iterations++; // if ( myid == 0 ) cout << "." << flush; } else { stop_time = time( NULL ); simmer.time_elapsed = simmer.time_elapsed + (stop_time - start_time); STAGE = 6; // if ( myid == 0 ) // cout << "Layout calculation completed in " << // ( liquid.time_elapsed + expansion.time_elapsed + // cooldown.time_elapsed + crunch.time_elapsed + // simmer.time_elapsed ) // << " seconds (not including I/O)." // << endl; } } // STAGE 6: All Done! else if ( STAGE == 6) { /* // output parameters (for debugging) cout << "ReCompute is using the following parameters: "<< endl; cout << "STAGE: " << STAGE << ", iter: " << iterations << ", temp = " << temperature << ", attract = " << attraction << ", damping_mult = " << damping_mult << ", min_edges = " << min_edges << ", cut_off_length = " << cut_off_length << ", fineDensity = " << fineDensity << endl; */ return 0; } // **************************************** // END AUTOMATIC CONTROL SECTION // **************************************** // Still need more recomputation return 1; } // update_nodes -- this function will complete the primary node update // loop in layout's recompute routine. It follows exactly the same // sequence to ensure similarity of parallel layout to the standard layout void graph::update_nodes ( ) { vector node_indices; // node list of nodes currently being updated float old_positions[2 * MAX_PROCS]; // positions before update float new_positions[2 * MAX_PROCS]; // positions after update bool all_fixed; // check if all nodes are fixed // initial node list consists of 0,1,...,num_procs for ( int i = 0; i < num_procs; i++ ) { node_indices.push_back( i ); } // next we calculate the number of nodes there would be if the // num_nodes by num_procs schedule grid were perfectly square int square_num_nodes = (int)(num_procs + num_procs * floor ((float)(num_nodes - 1) / (float)num_procs )); for ( int i = myid; i < square_num_nodes; i += num_procs ) { // get old positions get_positions ( node_indices, old_positions ); // default new position is old position get_positions ( node_indices, new_positions ); if ( i < num_nodes ) { // advance random sequence according to myid for ( int j = 0; j < 2 * myid; j++ ) { RNG_UNIF01(); } // rand(); // calculate node energy possibilities if ( !(positions[i].fixed && real_fixed) ) { update_node_pos ( i, old_positions, new_positions ); } // advance random sequence for next iteration for ( unsigned int j = 2 * myid; j < 2 * (node_indices.size() - 1); j++ ) { RNG_UNIF01(); } // rand(); } else { // advance random sequence according to use by // the other processors for ( unsigned int j = 0; j < 2 * (node_indices.size()); j++ ) { RNG_UNIF01(); } //rand(); } // check if anything was actually updated (e.g. everything was fixed) all_fixed = true; for ( unsigned int j = 0; j < node_indices.size (); j++ ) if ( !(positions [ node_indices[j] ].fixed && real_fixed) ) { all_fixed = false; } // update positions across processors (if not all fixed) if ( !all_fixed ) { #ifdef MUSE_MPI MPI_Allgather ( &new_positions[2 * myid], 2, MPI_FLOAT, new_positions, 2, MPI_FLOAT, MPI_COMM_WORLD ); #endif // update positions (old to new) update_density ( node_indices, old_positions, new_positions ); } /* if ( myid == 0 ) { // output node list (for debugging) for ( unsigned int j = 0; j < node_indices.size(); j++ ) cout << node_indices[j] << " "; cout << endl; } */ // compute node list for next update for ( unsigned int j = 0; j < node_indices.size(); j++ ) { node_indices [j] += num_procs; } while ( !node_indices.empty() && node_indices.back() >= num_nodes ) { node_indices.pop_back ( ); } } // update first_add and fine_first_add first_add = false; if ( fineDensity ) { fine_first_add = false; } } // The get_positions function takes the node_indices list // and returns the corresponding positions in an array. void graph::get_positions ( vector &node_indices, float return_positions[2 * MAX_PROCS] ) { // fill positions for (unsigned int i = 0; i < node_indices.size(); i++) { return_positions[2 * i] = positions[ node_indices[i] ].x; return_positions[2 * i + 1] = positions[ node_indices[i] ].y; } } // update_node_pos -- this subroutine does the actual work of computing // the new position of a given node. num_act_proc gives the number // of active processes at this level for use by the random number // generators. void graph::update_node_pos ( int node_ind, float old_positions[2 * MAX_PROCS], float new_positions[2 * MAX_PROCS] ) { float energies[2]; // node energies for possible positions float updated_pos[2][2]; // possible positions float pos_x, pos_y; // old VxOrd parameter float jump_length = .010 * temperature; // subtract old node density_server.Subtract ( positions[node_ind], first_add, fine_first_add, fineDensity ); // compute node energy for old solution energies[0] = Compute_Node_Energy ( node_ind ); // move node to centroid position Solve_Analytic ( node_ind, pos_x, pos_y ); positions[node_ind].x = updated_pos[0][0] = pos_x; positions[node_ind].y = updated_pos[0][1] = pos_y; /* // ouput random numbers (for debugging) int rand_0, rand_1; rand_0 = rand(); rand_1 = rand(); cout << myid << ": " << rand_0 << ", " << rand_1 << endl; */ // Do random method (RAND_MAX is C++ maximum random number) updated_pos[1][0] = updated_pos[0][0] + (.5 - RNG_UNIF01()) * jump_length; updated_pos[1][1] = updated_pos[0][1] + (.5 - RNG_UNIF01()) * jump_length; // compute node energy for random position positions[node_ind].x = updated_pos[1][0]; positions[node_ind].y = updated_pos[1][1]; energies[1] = Compute_Node_Energy ( node_ind ); /* // output update possiblities (debugging): cout << node_ind << ": (" << updated_pos[0][0] << "," << updated_pos[0][1] << "), " << energies[0] << "; (" << updated_pos[1][0] << "," << updated_pos[1][1] << "), " << energies[1] << endl; */ // add back old position positions[node_ind].x = old_positions[2 * myid]; positions[node_ind].y = old_positions[2 * myid + 1]; if ( !fineDensity && !first_add ) { density_server.Add ( positions[node_ind], fineDensity ); } else if ( !fine_first_add ) { density_server.Add ( positions[node_ind], fineDensity ); } // choose updated node position with lowest energy if ( energies[0] < energies[1] ) { new_positions[2 * myid] = updated_pos[0][0]; new_positions[2 * myid + 1] = updated_pos[0][1]; positions[node_ind].energy = energies[0]; } else { new_positions[2 * myid] = updated_pos[1][0]; new_positions[2 * myid + 1] = updated_pos[1][1]; positions[node_ind].energy = energies[1]; } } // update_density takes a sequence of node_indices and their positions and // updates the positions by subtracting the old positions and adding the // new positions to the density grid. void graph::update_density ( vector &node_indices, float old_positions[2 * MAX_PROCS], float new_positions[2 * MAX_PROCS] ) { // go through each node and subtract old position from // density grid before adding new position for ( unsigned int i = 0; i < node_indices.size(); i++ ) { positions[node_indices[i]].x = old_positions[2 * i]; positions[node_indices[i]].y = old_positions[2 * i + 1]; density_server.Subtract ( positions[node_indices[i]], first_add, fine_first_add, fineDensity ); positions[node_indices[i]].x = new_positions[2 * i]; positions[node_indices[i]].y = new_positions[2 * i + 1]; density_server.Add ( positions[node_indices[i]], fineDensity ); } } /******************************************** * Function: Compute_Node_Energy * * Description: Compute the node energy * * This code has been modified from the * * original code by B. Wylie. * *********************************************/ float graph::Compute_Node_Energy( int node_ind ) { /* Want to expand 4th power range of attraction */ float attraction_factor = attraction * attraction * attraction * attraction * 2e-2; map ::iterator EI; float x_dis, y_dis; float energy_distance, weight; float node_energy = 0; // Add up all connection energies for (EI = neighbors[node_ind].begin(); EI != neighbors[node_ind].end(); ++EI) { // Get edge weight weight = EI->second; // Compute x,y distance x_dis = positions[ node_ind ].x - positions[ EI->first ].x; y_dis = positions[ node_ind ].y - positions[ EI->first ].y; // Energy Distance energy_distance = x_dis * x_dis + y_dis * y_dis; if (STAGE < 2) { energy_distance *= energy_distance; } // In the liquid phase we want to discourage long link distances if (STAGE == 0) { energy_distance *= energy_distance; } node_energy += weight * attraction_factor * energy_distance; } // output effect of density (debugging) //cout << "[before: " << node_energy; // add density node_energy += density_server.GetDensity ( positions[ node_ind ].x, positions[ node_ind ].y, fineDensity ); // after calling density server (debugging) //cout << ", after: " << node_energy << "]" << endl; // return computated energy return node_energy; } /********************************************* * Function: Solve_Analytic * * Description: Compute the node position * * This is a modified version of the function * * originally written by B. Wylie * *********************************************/ void graph::Solve_Analytic( int node_ind, float &pos_x, float &pos_y ) { map ::iterator EI; float total_weight = 0; float x_dis, y_dis, x_cen = 0, y_cen = 0; float x = 0, y = 0, dis; float damping, weight; // Sum up all connections for (EI = neighbors[node_ind].begin(); EI != neighbors[node_ind].end(); ++EI) { weight = EI->second; total_weight += weight; x += weight * positions[ EI->first ].x; y += weight * positions[ EI->first ].y; } // Now set node position if (total_weight > 0) { // Compute centriod x_cen = x / total_weight; y_cen = y / total_weight; damping = 1.0 - damping_mult; pos_x = damping * positions[ node_ind ].x + (1.0 - damping) * x_cen; pos_y = damping * positions[ node_ind ].y + (1.0 - damping) * y_cen; } else { pos_x = positions[ node_ind ].x; pos_y = positions[ node_ind ].y; } // No cut edge flag (?) if (min_edges == 99) { return; } // Don't cut at end of scale if ( CUT_END >= 39500 ) { return; } float num_connections = sqrt((double)neighbors[node_ind].size()); float maxLength = 0; map::iterator maxIndex; // Go through nodes edges... cutting if necessary for (EI = maxIndex = neighbors[node_ind].begin(); EI != neighbors[node_ind].end(); ++EI) { // Check for at least min edges if (neighbors[node_ind].size() < min_edges) { continue; } x_dis = x_cen - positions[ EI->first ].x; y_dis = y_cen - positions[ EI->first ].y; dis = x_dis * x_dis + y_dis * y_dis; dis *= num_connections; // Store maximum edge if (dis > maxLength) { maxLength = dis; maxIndex = EI; } } // If max length greater than cut_length then cut if (maxLength > cut_off_length) { neighbors[ node_ind ].erase( maxIndex ); } } // write_coord writes out the coordinate file of the final solutions // void graph::write_coord( const char *file_name ) // { // ofstream coordOUT( file_name ); // if ( !coordOUT ) // { // cout << "Could not open " << file_name << ". Program terminated." << endl; // #ifdef MUSE_MPI // MPI_Abort ( MPI_COMM_WORLD, 1 ); // #else // exit (1); // #endif // } // cout << "Writing out solution to " << file_name << " ..." << endl; // for (unsigned int i = 0; i < positions.size(); i++) { // coordOUT << positions[i].id << "\t" << positions[i].x << "\t" << positions[i].y < >::iterator i; map::iterator j; for ( i = neighbors.begin(); i != neighbors.end(); i++ ) for (j = (i->second).begin(); j != (i->second).end(); j++ ) simOUT << positions[i->first].id << "\t" << positions[j->first].id << "\t" << j->second << endl; simOUT.close(); } */ // get_tot_energy adds up the energy for each node to give an estimate of the // quality of the minimization. float graph::get_tot_energy ( ) { float my_tot_energy, tot_energy; my_tot_energy = 0; for ( int i = myid; i < num_nodes; i += num_procs ) { my_tot_energy += positions[i].energy; } //vector::iterator i; //for ( i = positions.begin(); i != positions.end(); i++ ) // tot_energy += i->energy; #ifdef MUSE_MPI MPI_Reduce ( &my_tot_energy, &tot_energy, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD ); #else tot_energy = my_tot_energy; #endif return tot_energy; } // The following subroutine draws the graph with possible intermediate // output (int_out is set to 0 if not proc. 0). int_out is the parameter // passed by the user, and coord_file is the .coord file. // void graph::draw_graph ( int int_out, char *coord_file ) // { // // layout graph (with possible intermediate output) // int count_iter = 0, count_file = 1; // char int_coord_file [MAX_FILE_NAME + MAX_INT_LENGTH]; // while ( ReCompute( ) ) // if ( (int_out > 0) && (count_iter == int_out) ) // { // // output intermediate solution // sprintf ( int_coord_file, "%s.%d", coord_file, count_file ); // write_coord ( int_coord_file ); // count_iter = 0; // count_file++; // } // else // count_iter++; // } int graph::draw_graph(igraph_matrix_t *res) { int count_iter = 0; while (ReCompute()) { IGRAPH_ALLOW_INTERRUPTION(); count_iter++; } long int n = positions.size(); IGRAPH_CHECK(igraph_matrix_resize(res, n, 2)); for (long int i = 0; i < n; i++) { MATRIX(*res, i, 0) = positions[i].x; MATRIX(*res, i, 1) = positions[i].y; } return 0; } } // namespace drl leidenbase/src/core/layout/drl/drl_Node_3d.h0000644000176200001440000000442714447675374020503 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __NODE_H__ #define __NODE_H__ // The node class contains information about a given node for // use by the density server process. // structure coord used to pass position information between // density server and graph class namespace drl3d { class Node { public: bool fixed; // if true do not change the // position of this node int id; float x, y, z; float sub_x, sub_y, sub_z; float energy; public: Node( int node_id ) { x = y = z = 0.0; fixed = false; id = node_id; } ~Node() { } }; } // namespace drl3d #endif //__NODE_H__ leidenbase/src/core/layout/drl/drl_layout.h0000644000176200001440000000564214447675374020545 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This file contains compile time parameters which affect the entire // DrL program. #define DRL_VERSION "3.2 5/5/2006" // compile time parameters for MPI message passing #define MAX_PROCS 256 // maximum number of processors #define MAX_FILE_NAME 250 // max length of filename #define MAX_INT_LENGTH 4 // max length of integer suffix of intermediate .coord file // Compile time adjustable parameters for the Density grid #define GRID_SIZE 1000 // size of Density grid #define VIEW_SIZE 4000.0 // actual physical size of layout plane // these values use more memory but have // little effect on performance or layout #define RADIUS 10 // radius for density fall-off: // larger values tends to slow down // the program and clump the data #define HALF_VIEW 2000 // 1/2 of VIEW_SIZE #define VIEW_TO_GRID .25 // ratio of GRID_SIZE to VIEW_SIZE /* // original values for VxOrd #define GRID_SIZE 400 // size of VxOrd Density grid #define VIEW_SIZE 1600.0 // actual physical size of VxOrd plane #define RADIUS 10 // radius for density fall-off #define HALF_VIEW 800 // 1/2 of VIEW_SIZE #define VIEW_TO_GRID .25 // ratio of GRID_SIZE to VIEW_SIZE */ leidenbase/src/core/layout/drl/drl_graph_3d.cpp0000644000176200001440000007057514447675374021261 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This file contains the member definitions of the master class #include #include #include using namespace std; #include "drl_graph_3d.h" #include "igraph_random.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "core/interruption.h" #ifdef MUSE_MPI #include #endif namespace drl3d { graph::graph(const igraph_t *igraph, const igraph_layout_drl_options_t *options, const igraph_vector_t *weights) { myid = 0; num_procs = 1; STAGE = 0; iterations = options->init_iterations; temperature = options->init_temperature; attraction = options->init_attraction; damping_mult = options->init_damping_mult; min_edges = 20; first_add = fine_first_add = true; fineDensity = false; // Brian's original Vx schedule liquid.iterations = options->liquid_iterations; liquid.temperature = options->liquid_temperature; liquid.attraction = options->liquid_attraction; liquid.damping_mult = options->liquid_damping_mult; liquid.time_elapsed = 0; expansion.iterations = options->expansion_iterations; expansion.temperature = options->expansion_temperature; expansion.attraction = options->expansion_attraction; expansion.damping_mult = options->expansion_damping_mult; expansion.time_elapsed = 0; cooldown.iterations = options->cooldown_iterations; cooldown.temperature = options->cooldown_temperature; cooldown.attraction = options->cooldown_attraction; cooldown.damping_mult = options->cooldown_damping_mult; cooldown.time_elapsed = 0; crunch.iterations = options->crunch_iterations; crunch.temperature = options->crunch_temperature; crunch.attraction = options->crunch_attraction; crunch.damping_mult = options->crunch_damping_mult; crunch.time_elapsed = 0; simmer.iterations = options->simmer_iterations; simmer.temperature = options->simmer_temperature; simmer.attraction = options->simmer_attraction; simmer.damping_mult = options->simmer_damping_mult; simmer.time_elapsed = 0; // scan .int file for node info highest_sim = 1.0; num_nodes = igraph_vcount(igraph); long int no_of_edges = igraph_ecount(igraph); for (long int i = 0; i < num_nodes; i++) { id_catalog[i] = 1; } map< int, int>::iterator cat_iter; for ( cat_iter = id_catalog.begin(); cat_iter != id_catalog.end(); cat_iter++) { cat_iter->second = cat_iter->first; } // populate node positions and ids positions.reserve ( num_nodes ); for ( cat_iter = id_catalog.begin(); cat_iter != id_catalog.end(); cat_iter++ ) { positions.push_back ( Node( cat_iter->first ) ); } // read .int file for graph info long int node_1, node_2; double weight; for (long int i = 0; i < no_of_edges; i++) { node_1 = IGRAPH_FROM(igraph, i); node_2 = IGRAPH_TO(igraph, i); weight = weights ? VECTOR(*weights)[i] : 1.0 ; (neighbors[id_catalog[node_1]])[id_catalog[node_2]] = weight; (neighbors[id_catalog[node_2]])[id_catalog[node_1]] = weight; } // initialize density server density_server.Init(); } // init_parms -- this subroutine initializes the edge_cut variables // used in the original VxOrd starting with the edge_cut parameter. // In our version, edge_cut = 0 means no cutting, 1 = maximum cut. // We also set the random seed here. void graph::init_parms ( int rand_seed, float edge_cut, float real_parm ) { IGRAPH_UNUSED(rand_seed); // first we translate edge_cut the former tcl sliding scale //CUT_END = cut_length_end = 39000.0 * (1.0 - edge_cut) + 1000.0; CUT_END = cut_length_end = 40000.0 * (1.0 - edge_cut); // cut_length_end cannot actually be 0 if ( cut_length_end <= 1.0 ) { cut_length_end = 1.0; } float cut_length_start = 4.0 * cut_length_end; // now we set the parameters used by ReCompute cut_off_length = cut_length_start; cut_rate = ( cut_length_start - cut_length_end ) / 400.0; // finally set the number of iterations to leave .real coords fixed int full_comp_iters; full_comp_iters = liquid.iterations + expansion.iterations + cooldown.iterations + crunch.iterations + 3; // adjust real parm to iterations (do not enter simmer halfway) if ( real_parm < 0 ) { real_iterations = (int)real_parm; } else if ( real_parm == 1) { real_iterations = full_comp_iters + simmer.iterations + 100; } else { real_iterations = (int)(real_parm * full_comp_iters); } tot_iterations = 0; if ( real_iterations > 0 ) { real_fixed = true; } else { real_fixed = false; } // calculate total expected iterations (for progress bar display) tot_expected_iterations = liquid.iterations + expansion.iterations + cooldown.iterations + crunch.iterations + simmer.iterations; /* // output edge_cutting parms (for debugging) cout << "Processor " << myid << ": " << "cut_length_end = CUT_END = " << cut_length_end << ", cut_length_start = " << cut_length_start << ", cut_rate = " << cut_rate << endl; */ // set random seed // srand ( rand_seed ); // Don't need this in igraph } void graph::init_parms(const igraph_layout_drl_options_t *options) { double rand_seed = 0.0; double real_in = -1.0; init_parms(rand_seed, options->edge_cut, real_in); } int graph::read_real ( const igraph_matrix_t *real_mat, const igraph_vector_bool_t *fixed) { long int n = igraph_matrix_nrow(real_mat); for (long int i = 0; i < n; i++) { positions[id_catalog[i]].x = MATRIX(*real_mat, i, 0); positions[id_catalog[i]].y = MATRIX(*real_mat, i, 1); positions[id_catalog[i]].z = MATRIX(*real_mat, i, 2); positions[id_catalog[i]].fixed = fixed ? VECTOR(*fixed)[i] : false; if ( real_iterations > 0 ) { density_server.Add ( positions[id_catalog[i]], fineDensity ); } } return 0; } /********************************************* * Function: ReCompute * * Description: Compute the graph locations * * Modified from original code by B. Wylie * ********************************************/ int graph::ReCompute( ) { // carryover from original VxOrd int MIN = 1; /* // output parameters (for debugging) cout << "ReCompute is using the following parameters: "<< endl; cout << "STAGE: " << STAGE << ", iter: " << iterations << ", temp = " << temperature << ", attract = " << attraction << ", damping_mult = " << damping_mult << ", min_edges = " << min_edges << ", cut_off_length = " << cut_off_length << ", fineDensity = " << fineDensity << endl; */ /* igraph progress report */ float progress = (tot_iterations * 100.0 / tot_expected_iterations); switch (STAGE) { case 0: if (iterations == 0) { IGRAPH_PROGRESS("DrL layout (initialization stage)", progress, 0); } else { IGRAPH_PROGRESS("DrL layout (liquid stage)", progress, 0); } break; case 1: IGRAPH_PROGRESS("DrL layout (expansion stage)", progress, 0); break; case 2: IGRAPH_PROGRESS("DrL layout (cooldown and cluster phase)", progress, 0); break; case 3: IGRAPH_PROGRESS("DrL layout (crunch phase)", progress, 0); break; case 5: IGRAPH_PROGRESS("DrL layout (simmer phase)", progress, 0); break; case 6: IGRAPH_PROGRESS("DrL layout (final phase)", 100.0, 0); break; default: IGRAPH_PROGRESS("DrL layout (unknown phase)", 0.0, 0); break; } /* Compute Energies for individual nodes */ update_nodes (); // check to see if we need to free fixed nodes tot_iterations++; if ( tot_iterations >= real_iterations ) { real_fixed = false; } // **************************************** // AUTOMATIC CONTROL SECTION // **************************************** // STAGE 0: LIQUID if (STAGE == 0) { if ( iterations == 0 ) { start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering liquid stage ..."; } if (iterations < liquid.iterations) { temperature = liquid.temperature; attraction = liquid.attraction; damping_mult = liquid.damping_mult; iterations++; // if ( myid == 0 ) // cout << "." << flush; } else { stop_time = time( NULL ); liquid.time_elapsed = liquid.time_elapsed + (stop_time - start_time); temperature = expansion.temperature; attraction = expansion.attraction; damping_mult = expansion.damping_mult; iterations = 0; // go to next stage STAGE = 1; start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering expansion stage ..."; } } // STAGE 1: EXPANSION if (STAGE == 1) { if (iterations < expansion.iterations) { // Play with vars if (attraction > 1) { attraction -= .05f; } if (min_edges > 12) { min_edges -= .05f; } cut_off_length -= cut_rate; if (damping_mult > .1) { damping_mult -= .005f; } iterations++; // if ( myid == 0 ) cout << "." << flush; } else { stop_time = time( NULL ); expansion.time_elapsed = expansion.time_elapsed + (stop_time - start_time); min_edges = 12; damping_mult = cooldown.damping_mult; STAGE = 2; attraction = cooldown.attraction; temperature = cooldown.temperature; iterations = 0; start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering cool-down stage ..."; } } // STAGE 2: Cool down and cluster else if (STAGE == 2) { if (iterations < cooldown.iterations) { // Reduce temperature if (temperature > 50) { temperature -= 10; } // Reduce cut length if (cut_off_length > cut_length_end) { cut_off_length -= cut_rate * 2; } if (min_edges > MIN) { min_edges -= .2f; } //min_edges = 99; iterations++; // if ( myid == 0 ) // cout << "." << flush; } else { stop_time = time( NULL ); cooldown.time_elapsed = cooldown.time_elapsed + (stop_time - start_time); cut_off_length = cut_length_end; temperature = crunch.temperature; damping_mult = crunch.damping_mult; min_edges = MIN; //min_edges = 99; // In other words: no more cutting STAGE = 3; iterations = 0; attraction = crunch.attraction; start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering crunch stage ..."; } } // STAGE 3: Crunch else if (STAGE == 3) { if (iterations < crunch.iterations) { iterations++; // if ( myid == 0 ) cout << "." << flush; } else { stop_time = time( NULL ); crunch.time_elapsed = crunch.time_elapsed + (stop_time - start_time); iterations = 0; temperature = simmer.temperature; attraction = simmer.attraction; damping_mult = simmer.damping_mult; min_edges = 99; fineDensity = true; STAGE = 5; start_time = time( NULL ); // if ( myid == 0 ) // cout << "Entering simmer stage ..."; } } // STAGE 5: Simmer else if ( STAGE == 5 ) { if (iterations < simmer.iterations) { if (temperature > 50) { temperature -= 2; } iterations++; // if ( myid == 0 ) cout << "." << flush; } else { stop_time = time( NULL ); simmer.time_elapsed = simmer.time_elapsed + (stop_time - start_time); STAGE = 6; // if ( myid == 0 ) // cout << "Layout calculation completed in " << // ( liquid.time_elapsed + expansion.time_elapsed + // cooldown.time_elapsed + crunch.time_elapsed + // simmer.time_elapsed ) // << " seconds (not including I/O)." // << endl; } } // STAGE 6: All Done! else if ( STAGE == 6) { /* // output parameters (for debugging) cout << "ReCompute is using the following parameters: "<< endl; cout << "STAGE: " << STAGE << ", iter: " << iterations << ", temp = " << temperature << ", attract = " << attraction << ", damping_mult = " << damping_mult << ", min_edges = " << min_edges << ", cut_off_length = " << cut_off_length << ", fineDensity = " << fineDensity << endl; */ return 0; } // **************************************** // END AUTOMATIC CONTROL SECTION // **************************************** // Still need more recomputation return 1; } // update_nodes -- this function will complete the primary node update // loop in layout's recompute routine. It follows exactly the same // sequence to ensure similarity of parallel layout to the standard layout void graph::update_nodes ( ) { vector node_indices; // node list of nodes currently being updated float old_positions[2 * MAX_PROCS]; // positions before update float new_positions[2 * MAX_PROCS]; // positions after update bool all_fixed; // check if all nodes are fixed // initial node list consists of 0,1,...,num_procs for ( int i = 0; i < num_procs; i++ ) { node_indices.push_back( i ); } // next we calculate the number of nodes there would be if the // num_nodes by num_procs schedule grid were perfectly square int square_num_nodes = (int)(num_procs + num_procs * floor ((float)(num_nodes - 1) / (float)num_procs )); for ( int i = myid; i < square_num_nodes; i += num_procs ) { // get old positions get_positions ( node_indices, old_positions ); // default new position is old position get_positions ( node_indices, new_positions ); if ( i < num_nodes ) { // advance random sequence according to myid for ( int j = 0; j < 2 * myid; j++ ) { RNG_UNIF01(); } // rand(); // calculate node energy possibilities if ( !(positions[i].fixed && real_fixed) ) { update_node_pos ( i, old_positions, new_positions ); } // advance random sequence for next iteration for ( unsigned int j = 2 * myid; j < 2 * (node_indices.size() - 1); j++ ) { RNG_UNIF01(); } // rand(); } else { // advance random sequence according to use by // the other processors for ( unsigned int j = 0; j < 2 * (node_indices.size()); j++ ) { RNG_UNIF01(); } //rand(); } // check if anything was actually updated (e.g. everything was fixed) all_fixed = true; for ( unsigned int j = 0; j < node_indices.size (); j++ ) if ( !(positions [ node_indices[j] ].fixed && real_fixed) ) { all_fixed = false; } // update positions across processors (if not all fixed) if ( !all_fixed ) { #ifdef MUSE_MPI MPI_Allgather ( &new_positions[2 * myid], 2, MPI_FLOAT, new_positions, 2, MPI_FLOAT, MPI_COMM_WORLD ); #endif // update positions (old to new) update_density ( node_indices, old_positions, new_positions ); } /* if ( myid == 0 ) { // output node list (for debugging) for ( unsigned int j = 0; j < node_indices.size(); j++ ) cout << node_indices[j] << " "; cout << endl; } */ // compute node list for next update for ( unsigned int j = 0; j < node_indices.size(); j++ ) { node_indices [j] += num_procs; } while ( !node_indices.empty() && node_indices.back() >= num_nodes ) { node_indices.pop_back ( ); } } // update first_add and fine_first_add first_add = false; if ( fineDensity ) { fine_first_add = false; } } // The get_positions function takes the node_indices list // and returns the corresponding positions in an array. void graph::get_positions ( vector &node_indices, float return_positions[3 * MAX_PROCS] ) { // fill positions for (unsigned int i = 0; i < node_indices.size(); i++) { return_positions[3 * i] = positions[ node_indices[i] ].x; return_positions[3 * i + 1] = positions[ node_indices[i] ].y; return_positions[3 * i + 2] = positions[ node_indices[i] ].z; } } // update_node_pos -- this subroutine does the actual work of computing // the new position of a given node. num_act_proc gives the number // of active processes at this level for use by the random number // generators. void graph::update_node_pos ( int node_ind, float old_positions[3 * MAX_PROCS], float new_positions[3 * MAX_PROCS] ) { float energies[2]; // node energies for possible positions float updated_pos[2][3]; // possible positions float pos_x, pos_y, pos_z; // old VxOrd parameter float jump_length = .010 * temperature; // subtract old node density_server.Subtract ( positions[node_ind], first_add, fine_first_add, fineDensity ); // compute node energy for old solution energies[0] = Compute_Node_Energy ( node_ind ); // move node to centroid position Solve_Analytic ( node_ind, pos_x, pos_y, pos_z ); positions[node_ind].x = updated_pos[0][0] = pos_x; positions[node_ind].y = updated_pos[0][1] = pos_y; positions[node_ind].z = updated_pos[0][2] = pos_z; /* // ouput random numbers (for debugging) int rand_0, rand_1; rand_0 = rand(); rand_1 = rand(); cout << myid << ": " << rand_0 << ", " << rand_1 << endl; */ // Do random method (RAND_MAX is C++ maximum random number) updated_pos[1][0] = updated_pos[0][0] + (.5 - RNG_UNIF01()) * jump_length; updated_pos[1][1] = updated_pos[0][1] + (.5 - RNG_UNIF01()) * jump_length; updated_pos[1][2] = updated_pos[0][2] + (.5 - RNG_UNIF01()) * jump_length; // compute node energy for random position positions[node_ind].x = updated_pos[1][0]; positions[node_ind].y = updated_pos[1][1]; positions[node_ind].z = updated_pos[1][2]; energies[1] = Compute_Node_Energy ( node_ind ); /* // output update possiblities (debugging): cout << node_ind << ": (" << updated_pos[0][0] << "," << updated_pos[0][1] << "), " << energies[0] << "; (" << updated_pos[1][0] << "," << updated_pos[1][1] << "), " << energies[1] << endl; */ // add back old position positions[node_ind].x = old_positions[3 * myid]; positions[node_ind].y = old_positions[3 * myid + 1]; positions[node_ind].z = old_positions[3 * myid + 2]; if ( !fineDensity && !first_add ) { density_server.Add ( positions[node_ind], fineDensity ); } else if ( !fine_first_add ) { density_server.Add ( positions[node_ind], fineDensity ); } // choose updated node position with lowest energy if ( energies[0] < energies[1] ) { new_positions[3 * myid] = updated_pos[0][0]; new_positions[3 * myid + 1] = updated_pos[0][1]; new_positions[3 * myid + 2] = updated_pos[0][2]; positions[node_ind].energy = energies[0]; } else { new_positions[3 * myid] = updated_pos[1][0]; new_positions[3 * myid + 1] = updated_pos[1][1]; new_positions[3 * myid + 2] = updated_pos[1][2]; positions[node_ind].energy = energies[1]; } } // update_density takes a sequence of node_indices and their positions and // updates the positions by subtracting the old positions and adding the // new positions to the density grid. void graph::update_density ( vector &node_indices, float old_positions[3 * MAX_PROCS], float new_positions[3 * MAX_PROCS] ) { // go through each node and subtract old position from // density grid before adding new position for ( unsigned int i = 0; i < node_indices.size(); i++ ) { positions[node_indices[i]].x = old_positions[3 * i]; positions[node_indices[i]].y = old_positions[3 * i + 1]; positions[node_indices[i]].z = old_positions[3 * i + 2]; density_server.Subtract ( positions[node_indices[i]], first_add, fine_first_add, fineDensity ); positions[node_indices[i]].x = new_positions[3 * i]; positions[node_indices[i]].y = new_positions[3 * i + 1]; positions[node_indices[i]].z = new_positions[3 * i + 2]; density_server.Add ( positions[node_indices[i]], fineDensity ); } } /******************************************** * Function: Compute_Node_Energy * * Description: Compute the node energy * * This code has been modified from the * * original code by B. Wylie. * *********************************************/ float graph::Compute_Node_Energy( int node_ind ) { /* Want to expand 4th power range of attraction */ float attraction_factor = attraction * attraction * attraction * attraction * 2e-2; map ::iterator EI; float x_dis, y_dis, z_dis; float energy_distance, weight; float node_energy = 0; // Add up all connection energies for (EI = neighbors[node_ind].begin(); EI != neighbors[node_ind].end(); ++EI) { // Get edge weight weight = EI->second; // Compute x,y distance x_dis = positions[ node_ind ].x - positions[ EI->first ].x; y_dis = positions[ node_ind ].y - positions[ EI->first ].y; z_dis = positions[ node_ind ].z - positions[ EI->first ].z; // Energy Distance energy_distance = x_dis * x_dis + y_dis * y_dis + z_dis * z_dis; if (STAGE < 2) { energy_distance *= energy_distance; } // In the liquid phase we want to discourage long link distances if (STAGE == 0) { energy_distance *= energy_distance; } node_energy += weight * attraction_factor * energy_distance; } // output effect of density (debugging) //cout << "[before: " << node_energy; // add density node_energy += density_server.GetDensity ( positions[ node_ind ].x, positions[ node_ind ].y, positions[ node_ind ].z, fineDensity ); // after calling density server (debugging) //cout << ", after: " << node_energy << "]" << endl; // return computated energy return node_energy; } /********************************************* * Function: Solve_Analytic * * Description: Compute the node position * * This is a modified version of the function * * originally written by B. Wylie * *********************************************/ void graph::Solve_Analytic( int node_ind, float &pos_x, float &pos_y, float &pos_z) { map ::iterator EI; float total_weight = 0; float x_dis, y_dis, z_dis, x_cen = 0, y_cen = 0, z_cen = 0; float x = 0, y = 0, z = 0, dis; float damping, weight; // Sum up all connections for (EI = neighbors[node_ind].begin(); EI != neighbors[node_ind].end(); ++EI) { weight = EI->second; total_weight += weight; x += weight * positions[ EI->first ].x; y += weight * positions[ EI->first ].y; z += weight * positions[ EI->first ].z; } // Now set node position if (total_weight > 0) { // Compute centriod x_cen = x / total_weight; y_cen = y / total_weight; z_cen = z / total_weight; damping = 1.0 - damping_mult; pos_x = damping * positions[ node_ind ].x + (1.0 - damping) * x_cen; pos_y = damping * positions[ node_ind ].y + (1.0 - damping) * y_cen; pos_z = damping * positions[ node_ind ].z + (1.0 - damping) * z_cen; } // No cut edge flag (?) if (min_edges == 99) { return; } // Don't cut at end of scale if ( CUT_END >= 39500 ) { return; } float num_connections = (float)sqrt((float)neighbors[node_ind].size()); float maxLength = 0; map::iterator maxIndex; // Go through nodes edges... cutting if necessary for (EI = maxIndex = neighbors[node_ind].begin(); EI != neighbors[node_ind].end(); ++EI) { // Check for at least min edges if (neighbors[node_ind].size() < min_edges) { continue; } x_dis = x_cen - positions[ EI->first ].x; y_dis = y_cen - positions[ EI->first ].y; z_dis = z_cen - positions[ EI->first ].z; dis = x_dis * x_dis + y_dis * y_dis + z_dis * z_dis; dis *= num_connections; // Store maximum edge if (dis > maxLength) { maxLength = dis; maxIndex = EI; } } // If max length greater than cut_length then cut if (maxLength > cut_off_length) { neighbors[ node_ind ].erase( maxIndex ); } } // get_tot_energy adds up the energy for each node to give an estimate of the // quality of the minimization. float graph::get_tot_energy ( ) { float my_tot_energy, tot_energy; my_tot_energy = 0; for ( int i = myid; i < num_nodes; i += num_procs ) { my_tot_energy += positions[i].energy; } //vector::iterator i; //for ( i = positions.begin(); i != positions.end(); i++ ) // tot_energy += i->energy; #ifdef MUSE_MPI MPI_Reduce ( &my_tot_energy, &tot_energy, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD ); #else tot_energy = my_tot_energy; #endif return tot_energy; } int graph::draw_graph(igraph_matrix_t *res) { int count_iter = 0; while (ReCompute()) { IGRAPH_ALLOW_INTERRUPTION(); count_iter++; } long int n = positions.size(); IGRAPH_CHECK(igraph_matrix_resize(res, n, 3)); for (long int i = 0; i < n; i++) { MATRIX(*res, i, 0) = positions[i].x; MATRIX(*res, i, 1) = positions[i].y; MATRIX(*res, i, 2) = positions[i].z; } return 0; } } // namespace drl3d leidenbase/src/core/layout/drl/drl_graph_3d.h0000644000176200001440000001073114447675374020712 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // The graph class contains the methods necessary to draw the // graph. It calls on the density server class to obtain // position and density information #include "DensityGrid_3d.h" #include "igraph_layout.h" #include #include #include namespace drl3d { // layout schedule information struct layout_schedule { int iterations; float temperature; float attraction; float damping_mult; time_t time_elapsed; }; class graph { public: // Methods void init_parms ( int rand_seed, float edge_cut, float real_parm ); void init_parms ( const igraph_layout_drl_options_t *options ); int read_real ( const igraph_matrix_t *real_mat, const igraph_vector_bool_t *fixed); int draw_graph (igraph_matrix_t *res); float get_tot_energy ( ); // Con/Decon graph( const igraph_t *igraph, const igraph_layout_drl_options_t *options, const igraph_vector_t *weights); ~graph( ) { } private: // Methods int ReCompute ( ); void update_nodes ( ); float Compute_Node_Energy ( int node_ind ); void Solve_Analytic ( int node_ind, float &pos_x, float &pos_y, float &pos_z ); void get_positions ( std::vector &node_indices, float return_positions[3 * MAX_PROCS] ); void update_density ( std::vector &node_indices, float old_positions[3 * MAX_PROCS], float new_positions[3 * MAX_PROCS] ); void update_node_pos ( int node_ind, float old_positions[3 * MAX_PROCS], float new_positions[3 * MAX_PROCS] ); // MPI information int myid, num_procs; // graph decomposition information int num_nodes; // number of nodes in graph float highest_sim; // highest sim for normalization std::map id_catalog; // id_catalog[file id] = internal id std::map > neighbors; // neighbors of nodes on this proc. // graph layout information std::vector positions; DensityGrid density_server; // original VxOrd information int STAGE, iterations; float temperature, attraction, damping_mult; float min_edges, CUT_END, cut_length_end, cut_off_length, cut_rate; bool first_add, fine_first_add, fineDensity; // scheduling variables layout_schedule liquid; layout_schedule expansion; layout_schedule cooldown; layout_schedule crunch; layout_schedule simmer; // timing statistics time_t start_time, stop_time; // online clustering information int real_iterations; // number of iterations to hold .real input fixed int tot_iterations; int tot_expected_iterations; // for progress bar bool real_fixed; }; } // namespace drl3d leidenbase/src/core/layout/drl/drl_layout_3d.cpp0000644000176200001440000001106214447675374021457 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // Layout // // This program implements a parallel force directed graph drawing // algorithm. The algorithm used is based upon a random decomposition // of the graph and simulated shared memory of node position and density. // In this version, the simulated shared memory is spread among all processors // // The structure of the inputs and outputs of this code will be displayed // if the program is called without parameters, or if an erroneous // parameter is passed to the program. // // S. Martin // 5/6/2005 // C++ library routines #include #include using namespace std; // layout routines and constants #include "drl_layout_3d.h" #include "drl_parse.h" #include "drl_graph_3d.h" // MPI #ifdef MUSE_MPI #include #endif using namespace drl3d; #include "igraph_layout.h" #include "igraph_random.h" #include "igraph_interface.h" #include "core/exceptions.h" /** * \function igraph_layout_drl_3d * The DrL layout generator, 3d version. * * This function implements the force-directed DrL layout generator. * Please see more in the technical report: Martin, S., Brown, W.M., * Klavans, R., Boyack, K.W., DrL: Distributed Recursive (Graph) * Layout. SAND Reports, 2008. 2936: p. 1-10. * * This function uses a modified DrL generator that does * the layout in three dimensions. * \param graph The input graph. * \param use_seed Logical scalar, if true, then the coordinates * supplied in the \p res argument are used as starting points. * \param res Pointer to a matrix, the result layout is stored * here. It will be resized as needed. * \param options The parameters to pass to the layout generator. * \param weights Edge weights, pointer to a vector. If this is a null * pointer then every edge will have the same weight. * \param fixed Pointer to a logical vector, or a null pointer. This * can be used to fix the position of some vertices. Vertices for * which it is true will not be moved, but stay at the coordinates * given in the \p res matrix. This argument is ignored if it is a * null pointer or if use_seed is false. * \return Error code. * * Time complexity: ???. * * \sa \ref igraph_layout_drl() for the standard 2d version. */ int igraph_layout_drl_3d(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, const igraph_layout_drl_options_t *options, const igraph_vector_t *weights, const igraph_vector_bool_t *fixed) { IGRAPH_HANDLE_EXCEPTIONS( RNG_BEGIN(); drl3d::graph neighbors(graph, options, weights); neighbors.init_parms(options); if (use_seed) { IGRAPH_CHECK(igraph_matrix_resize(res, igraph_vcount(graph), 3)); neighbors.read_real(res, fixed); } neighbors.draw_graph(res); RNG_END(); ); return 0; } leidenbase/src/core/layout/drl/drl_layout.cpp0000644000176200001440000004071414447675374021077 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // Layout // // This program implements a parallel force directed graph drawing // algorithm. The algorithm used is based upon a random decomposition // of the graph and simulated shared memory of node position and density. // In this version, the simulated shared memory is spread among all processors // // The structure of the inputs and outputs of this code will be displayed // if the program is called without parameters, or if an erroneous // parameter is passed to the program. // // S. Martin // 5/6/2005 // C++ library routines #include #include using namespace std; // layout routines and constants #include "drl_layout.h" #include "drl_parse.h" #include "drl_graph.h" // MPI #ifdef MUSE_MPI #include #endif using namespace drl; #include "igraph_layout.h" #include "igraph_random.h" #include "igraph_interface.h" #include "core/exceptions.h" namespace drl { // int main(int argc, char **argv) { // // initialize MPI // int myid, num_procs; // #ifdef MUSE_MPI // MPI_Init ( &argc, &argv ); // MPI_Comm_size ( MPI_COMM_WORLD, &num_procs ); // MPI_Comm_rank ( MPI_COMM_WORLD, &myid ); // #else // myid = 0; // num_procs = 1; // #endif // // parameters that must be broadcast to all processors // int rand_seed; // float edge_cut; // char int_file[MAX_FILE_NAME]; // char coord_file[MAX_FILE_NAME]; // char real_file[MAX_FILE_NAME]; // char parms_file[MAX_FILE_NAME]; // int int_out = 0; // int edges_out = 0; // int parms_in = 0; // float real_in = -1.0; // // user interaction is handled by processor 0 // if ( myid == 0 ) // { // if ( num_procs > MAX_PROCS ) // { // cout << "Error: Maximum number of processors is " << MAX_PROCS << "." << endl; // cout << "Adjust compile time parameter." << endl; // #ifdef MUSE_MPI // MPI_Abort ( MPI_COMM_WORLD, 1 ); // #else // exit (1); // #endif // } // // get user input // parse command_line ( argc, argv ); // rand_seed = command_line.rand_seed; // edge_cut = command_line.edge_cut; // int_out = command_line.int_out; // edges_out = command_line.edges_out; // parms_in = command_line.parms_in; // real_in = command_line.real_in; // strcpy ( coord_file, command_line.coord_file.c_str() ); // strcpy ( int_file, command_line.sim_file.c_str() ); // strcpy ( real_file, command_line.real_file.c_str() ); // strcpy ( parms_file, command_line.parms_file.c_str() ); // } // // now we initialize all processors by reading .int file // #ifdef MUSE_MPI // MPI_Bcast ( &int_file, MAX_FILE_NAME, MPI_CHAR, 0, MPI_COMM_WORLD ); // #endif // graph neighbors ( myid, num_procs, int_file ); // // check for user supplied parameters // #ifdef MUSE_MPI // MPI_Bcast ( &parms_in, 1, MPI_INT, 0, MPI_COMM_WORLD ); // #endif // if ( parms_in ) // { // #ifdef MUSE_MPI // MPI_Bcast ( &parms_file, MAX_FILE_NAME, MPI_CHAR, 0, MPI_COMM_WORLD ); // #endif // neighbors.read_parms ( parms_file ); // } // // set random seed, edge cutting, and real iterations parameters // #ifdef MUSE_MPI // MPI_Bcast ( &rand_seed, 1, MPI_INT, 0, MPI_COMM_WORLD ); // MPI_Bcast ( &edge_cut, 1, MPI_FLOAT, 0, MPI_COMM_WORLD ); // MPI_Bcast ( &real_in, 1, MPI_INT, 0, MPI_COMM_WORLD ); // #endif // neighbors.init_parms ( rand_seed, edge_cut, real_in ); // // check for .real file with existing coordinates // if ( real_in >= 0 ) // { // #ifdef MUSE_MPI // MPI_Bcast ( &real_file, MAX_FILE_NAME, MPI_CHAR, 0, MPI_COMM_WORLD ); // #endif // neighbors.read_real ( real_file ); // } // neighbors.draw_graph ( int_out, coord_file ); // // do we have to write out the edges? // #ifdef MUSE_MPI // MPI_Bcast ( &edges_out, 1, MPI_INT, 0, MPI_COMM_WORLD ); // #endif // if ( edges_out ) // { // #ifdef MUSE_MPI // MPI_Bcast ( &coord_file, MAX_FILE_NAME, MPI_CHAR, 0, MPI_COMM_WORLD ); // #endif // for ( int i = 0; i < num_procs; i++ ) // { // if ( myid == i ) // neighbors.write_sim ( coord_file ); // #ifdef MUSE_MPI // MPI_Barrier ( MPI_COMM_WORLD ); // #endif // } // } // // finally we output file and quit // float tot_energy; // tot_energy = neighbors.get_tot_energy (); // if ( myid == 0 ) // { // neighbors.write_coord ( coord_file ); // cout << "Total Energy: " << tot_energy << "." << endl // << "Program terminated successfully." << endl; // } // // MPI finalize // #ifdef MUSE_MPI // MPI_Finalize (); // #endif // return 0; // } } // namespace drl /** * \section about_drl * * * DrL is a sophisticated layout generator developed and implemented by * Shawn Martin et al. As of October 2012 the original DrL homepage is * unfortunately not available. You can read more about this algorithm * in the following technical report: Martin, S., Brown, W.M., * Klavans, R., Boyack, K.W., DrL: Distributed Recursive (Graph) * Layout. SAND Reports, 2008. 2936: p. 1-10. * * * * Only a subset of the complete DrL functionality is * included in igraph, parallel runs and recursive, multi-level * layouting is not supported. * * * * The parameters of the layout are stored in an \ref * igraph_layout_drl_options_t structure, this can be initialized by * calling the function \ref igraph_layout_drl_options_init(). * The fields of this structure can then be adjusted by hand if needed. * The layout is calculated by an \ref igraph_layout_drl() call. * */ /** * \function igraph_layout_drl_options_init * Initialize parameters for the DrL layout generator * * This function can be used to initialize the struct holding the * parameters for the DrL layout generator. There are a number of * predefined templates available, it is a good idea to start from one * of these by modifying some parameters. * \param options The struct to initialize. * \param templ The template to use. Currently the following templates * are supplied: \c IGRAPH_LAYOUT_DRL_DEFAULT, \c * IGRAPH_LAYOUT_DRL_COARSEN, \c IGRAPH_LAYOUT_DRL_COARSEST, * \c IGRAPH_LAYOUT_DRL_REFINE and \c IGRAPH_LAYOUT_DRL_FINAL. * \return Error code. * * Time complexity: O(1). */ int igraph_layout_drl_options_init(igraph_layout_drl_options_t *options, igraph_layout_drl_default_t templ) { options->edge_cut = 32.0 / 40.0; switch (templ) { case IGRAPH_LAYOUT_DRL_DEFAULT: options->init_iterations = 0; options->init_temperature = 2000; options->init_attraction = 10; options->init_damping_mult = 1.0; options->liquid_iterations = 200; options->liquid_temperature = 2000; options->liquid_attraction = 10; options->liquid_damping_mult = 1.0; options->expansion_iterations = 200; options->expansion_temperature = 2000; options->expansion_attraction = 2; options->expansion_damping_mult = 1.0; options->cooldown_iterations = 200; options->cooldown_temperature = 2000; options->cooldown_attraction = 1; options->cooldown_damping_mult = .1; options->crunch_iterations = 50; options->crunch_temperature = 250; options->crunch_attraction = 1; options->crunch_damping_mult = 0.25; options->simmer_iterations = 100; options->simmer_temperature = 250; options->simmer_attraction = .5; options->simmer_damping_mult = 0; break; case IGRAPH_LAYOUT_DRL_COARSEN: options->init_iterations = 0; options->init_temperature = 2000; options->init_attraction = 10; options->init_damping_mult = 1.0; options->liquid_iterations = 200; options->liquid_temperature = 2000; options->liquid_attraction = 2; options->liquid_damping_mult = 1.0; options->expansion_iterations = 200; options->expansion_temperature = 2000; options->expansion_attraction = 10; options->expansion_damping_mult = 1.0; options->cooldown_iterations = 200; options->cooldown_temperature = 2000; options->cooldown_attraction = 1; options->cooldown_damping_mult = .1; options->crunch_iterations = 50; options->crunch_temperature = 250; options->crunch_attraction = 1; options->crunch_damping_mult = 0.25; options->simmer_iterations = 100; options->simmer_temperature = 250; options->simmer_attraction = .5; options->simmer_damping_mult = 0; break; case IGRAPH_LAYOUT_DRL_COARSEST: options->init_iterations = 0; options->init_temperature = 2000; options->init_attraction = 10; options->init_damping_mult = 1.0; options->liquid_iterations = 200; options->liquid_temperature = 2000; options->liquid_attraction = 2; options->liquid_damping_mult = 1.0; options->expansion_iterations = 200; options->expansion_temperature = 2000; options->expansion_attraction = 10; options->expansion_damping_mult = 1.0; options->cooldown_iterations = 200; options->cooldown_temperature = 2000; options->cooldown_attraction = 1; options->cooldown_damping_mult = .1; options->crunch_iterations = 200; options->crunch_temperature = 250; options->crunch_attraction = 1; options->crunch_damping_mult = 0.25; options->simmer_iterations = 100; options->simmer_temperature = 250; options->simmer_attraction = .5; options->simmer_damping_mult = 0; break; case IGRAPH_LAYOUT_DRL_REFINE: options->init_iterations = 0; options->init_temperature = 50; options->init_attraction = .5; options->init_damping_mult = 0; options->liquid_iterations = 0; options->liquid_temperature = 2000; options->liquid_attraction = 2; options->liquid_damping_mult = 1.0; options->expansion_iterations = 50; options->expansion_temperature = 500; options->expansion_attraction = .1; options->expansion_damping_mult = .25; options->cooldown_iterations = 50; options->cooldown_temperature = 200; options->cooldown_attraction = 1; options->cooldown_damping_mult = .1; options->crunch_iterations = 50; options->crunch_temperature = 250; options->crunch_attraction = 1; options->crunch_damping_mult = 0.25; options->simmer_iterations = 0; options->simmer_temperature = 250; options->simmer_attraction = .5; options->simmer_damping_mult = 0; break; case IGRAPH_LAYOUT_DRL_FINAL: options->init_iterations = 0; options->init_temperature = 50; options->init_attraction = .5; options->init_damping_mult = 0; options->liquid_iterations = 0; options->liquid_temperature = 2000; options->liquid_attraction = 2; options->liquid_damping_mult = 1.0; options->expansion_iterations = 50; options->expansion_temperature = 50; options->expansion_attraction = .1; options->expansion_damping_mult = .25; options->cooldown_iterations = 50; options->cooldown_temperature = 200; options->cooldown_attraction = 1; options->cooldown_damping_mult = .1; options->crunch_iterations = 50; options->crunch_temperature = 250; options->crunch_attraction = 1; options->crunch_damping_mult = 0.25; options->simmer_iterations = 25; options->simmer_temperature = 250; options->simmer_attraction = .5; options->simmer_damping_mult = 0; break; default: IGRAPH_ERROR("Unknown DrL template", IGRAPH_EINVAL); break; } return IGRAPH_SUCCESS; } /** * \function igraph_layout_drl * The DrL layout generator * * This function implements the force-directed DrL layout generator. * Please see more in the following technical report: Martin, S., * Brown, W.M., Klavans, R., Boyack, K.W., DrL: Distributed Recursive * (Graph) Layout. SAND Reports, 2008. 2936: p. 1-10. * \param graph The input graph. * \param use_seed Logical scalar, if true, then the coordinates * supplied in the \p res argument are used as starting points. * \param res Pointer to a matrix, the result layout is stored * here. It will be resized as needed. * \param options The parameters to pass to the layout generator. * \param weights Edge weights, pointer to a vector. If this is a null * pointer then every edge will have the same weight. * \param fixed Pointer to a logical vector, or a null pointer. Originally, * this argument was used in the DrL algorithm to keep the nodes marked * with this argument as fixed; fixed nodes would then keep their * positions in the initial stages of the algorithm. However, due to how * the DrL code imported into igraph is organized, it seems that the * argument does not do anything and we are not sure whether this is a * bug or a feature in DrL. We are leaving the argument here in order not * to break the API, but note that at the present stage it has no effect. * \return Error code. * * Time complexity: ???. */ int igraph_layout_drl(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, const igraph_layout_drl_options_t *options, const igraph_vector_t *weights, const igraph_vector_bool_t *fixed) { const char msg[] = "Damping multipliers cannot be negative, got %f."; if (options->init_damping_mult < 0) { IGRAPH_ERRORF(msg, IGRAPH_EINVAL, options->init_damping_mult); } if (options->liquid_damping_mult < 0) { IGRAPH_ERRORF(msg, IGRAPH_EINVAL, options->liquid_damping_mult); } if (options->expansion_damping_mult < 0) { IGRAPH_ERRORF(msg, IGRAPH_EINVAL, options->expansion_damping_mult); } if (options->cooldown_damping_mult < 0) { IGRAPH_ERRORF(msg, IGRAPH_EINVAL, options->cooldown_damping_mult); } if (options->crunch_damping_mult < 0) { IGRAPH_ERRORF(msg, IGRAPH_EINVAL, options->crunch_damping_mult); } if (options->simmer_damping_mult < 0) { IGRAPH_ERRORF(msg, IGRAPH_EINVAL, options->simmer_damping_mult); } IGRAPH_HANDLE_EXCEPTIONS( RNG_BEGIN(); drl::graph neighbors(graph, options, weights); neighbors.init_parms(options); if (use_seed) { IGRAPH_CHECK(igraph_matrix_resize(res, igraph_vcount(graph), 2)); neighbors.read_real(res, fixed); } neighbors.draw_graph(res); RNG_END(); ); return IGRAPH_SUCCESS; } leidenbase/src/core/layout/drl/drl_parse.cpp0000644000176200001440000001627214447675374020676 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This file contains the methods for the parse.h class #include "drl_layout.h" #include "drl_parse.h" namespace drl { // void parse::print_syntax( const char *error_string ) // { // cout << endl << "Error: " << error_string << endl; // cout << endl << "Layout" << endl // << "------" << endl // << "S. Martin" << endl // << "Version " << DRL_VERSION << endl << endl // << "This program provides a parallel adaptation of a force directed" << endl // << "graph layout algorithm for use with large datasets." << endl << endl // << "Usage: layout [options] root_file" << endl << endl // << "root_file -- the root name of the file being processed." << endl << endl // << "INPUT" << endl // << "-----" << endl // << "root_file.int -- the input file containing the graph to draw using layout." << endl // << " The .int file must have the suffix \".int\" and each line of .int file" << endl // << " should have the form" << endl // << "\tnode_id node_id weight" << endl // << " where node_id's are integers in sequence starting from 0, and" << endl // << " weight is a float > 0." << endl << endl // << "OUTPUT" << endl // << "------" << endl // << "root_file.icoord -- the resulting output file, containing an ordination" << endl // << " of the graph. The .icoord file will have the suffix \".icoord\" and" << endl // << " each line of the .icoord file will be of the form" << endl // << "\tnode_id x-coord y-coord" << endl << endl // << "Options:" << endl << endl // << "\t-s {int>=0} random seed (default value is 0)" << endl // << "\t-c {real[0,1]} edge cutting (default 32/40 = .8)" << endl // << "\t (old max was 39/40 = .975)" << endl // << "\t-p input parameters from .parms file" << endl // << "\t-r {real[0,1]} input coordinates from .real file" << endl // << "\t (hold fixed until fraction of optimization schedule reached)" << endl // << "\t-i {int>=0} intermediate output interval (default 0: no output)" << endl // << "\t-e output .iedges file (same prefix as .coord file)" << endl << endl; // #ifdef MUSE_MPI // MPI_Abort ( MPI_COMM_WORLD, 1 ); // #else // exit (1); // #endif // } // parse::parse ( int argc, char** argv) // { // map m; // // make sure there is at least one argument // if ( argc < 2) // print_syntax ( "not enough arguments!" ); // // make sure coord_file ends in ".coord" // parms_file = real_file = sim_file = coord_file = argv[argc-1]; // parms_file = parms_file + ".parms"; // real_file = real_file + ".real"; // sim_file = sim_file + ".int"; // coord_file = coord_file + ".icoord"; // char error_string[200]; // sprintf ( error_string, "%s %d %s", "root file name cannot be longer than", MAX_FILE_NAME-7, // "characters."); // if ( coord_file.length() > MAX_FILE_NAME ) // print_syntax ( error_string ); // // echo sim_file and coord_file // cout << "Using " << sim_file << " for .int file, and " << coord_file << " for .icoord file." << endl; // // set defaults // rand_seed = 0; // //edge_cut = 32.0/39.0; // (old default) // edge_cut = 32.0/40.0; // int_out = 0; // edges_out = 0; // parms_in = 0; // real_in = -1.0; // // now check for optional arguments // string arg; // for( int i = 1; i= (argc-1) ) // print_syntax ( "-s flag has no argument." ); // else // { // rand_seed = atoi ( argv[i] ); // if ( rand_seed < 0 ) // print_syntax ( "random seed must be >= 0." ); // } // } // // check for edge cutting // else if ( arg == "-c" ) // { // i++; // if ( i >= (argc-1) ) // print_syntax ( "-c flag has no argument." ); // else // { // edge_cut = atof ( argv[i] ); // if ( (edge_cut < 0) || (edge_cut > 1) ) // print_syntax ( "edge cut must be between 0 and 1." ); // } // } // // check for intermediate output // else if ( arg == "-i" ) // { // i++; // if ( i >= (argc-1) ) // print_syntax ( "-i flag has no argument." ); // else // { // int_out = atoi ( argv[i] ); // if ( int_out < 0 ) // print_syntax ( "intermediate output must be >= 0." ); // } // } // // check for .real input // else if ( arg == "-r" ) // { // i++; // if ( i >= (argc-1) ) // print_syntax ( "-r flag has no argument." ); // else // { // real_in = atof ( argv[i] ); // if ( (real_in < 0) || (real_in > 1) ) // print_syntax ( "real iteration fraction must be from 0 to 1." ); // } // } // else if ( arg == "-e" ) // edges_out = 1; // else if ( arg == "-p" ) // parms_in = 1; // else // print_syntax ( "unrecongized option!" ); // } // if ( parms_in ) // cout << "Using " << parms_file << " for .parms file." << endl; // if ( real_in >= 0 ) // cout << "Using " << real_file << " for .real file." << endl; // // echo arguments input or default // cout << "Using random seed = " << rand_seed << endl // << " edge_cutting = " << edge_cut << endl // << " intermediate output = " << int_out << endl // << " output .iedges file = " << edges_out << endl; // if ( real_in >= 0 ) // cout << " holding .real fixed until iterations = " << real_in << endl; // } } // namespace drl leidenbase/src/core/layout/drl/drl_parse.h0000644000176200001440000000517114447675374020337 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // The parse class contains the methods necessary to parse // the command line, print help, and do error checking #ifdef MUSE_MPI #include #endif #include namespace drl { class parse { public: // Methods parse ( int argc, char **argv ); ~parse () {} // user parameters std::string sim_file; // .sim file std::string coord_file; // .coord file std::string parms_file; // .parms file std::string real_file; // .real file int rand_seed; // random seed int >= 0 float edge_cut; // edge cutting real [0,1] int int_out; // intermediate output, int >= 1 int edges_out; // true if .edges file is requested int parms_in; // true if .parms file is to be read float real_in; // true if .real file is to be read private: void print_syntax ( const char *error_string ); }; } // namespace drl leidenbase/src/core/layout/drl/DensityGrid.cpp0000644000176200001440000002162414447675374021145 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This file contains the member definitions of the DensityGrid.h class // This code is modified from the original code by B.N. Wylie #include "drl_Node.h" #include "DensityGrid.h" #include "igraph_error.h" #include #include using namespace std; #define GET_BIN(y, x) (Bins[y*GRID_SIZE+x]) namespace drl { //******************************************************* // Density Grid Destructor -- deallocates memory used // for Density matrix, fall_off matrix, and node deque. DensityGrid::~DensityGrid () { delete[] Density; delete[] fall_off; delete[] Bins; } /********************************************* * Function: Density_Grid::Reset * * Description: Reset the density grid * *********************************************/ // changed from reset to init since we will only // call this once in the parallel version of layout void DensityGrid::Init() { try { Density = new float[GRID_SIZE][GRID_SIZE]; fall_off = new float[RADIUS * 2 + 1][RADIUS * 2 + 1]; Bins = new deque[GRID_SIZE * GRID_SIZE]; } catch (bad_alloc&) { // cout << "Error: Out of memory! Program stopped." << endl; #ifdef MUSE_MPI MPI_Abort ( MPI_COMM_WORLD, 1 ); #else igraph_error("DrL is out of memory", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return; #endif } // Clear Grid int i; for (i = 0; i < GRID_SIZE; i++) for (int j = 0; j < GRID_SIZE; j++) { Density[i][j] = 0; GET_BIN(i, j).erase(GET_BIN(i, j).begin(), GET_BIN(i, j).end()); } // Compute fall off for (i = -RADIUS; i <= RADIUS; i++) for (int j = -RADIUS; j <= RADIUS; j++) { fall_off[i + RADIUS][j + RADIUS] = (float)((RADIUS - fabs((float)i)) / RADIUS) * (float)((RADIUS - fabs((float)j)) / RADIUS); } } /*************************************************** * Function: DensityGrid::GetDensity * * Description: Get_Density from density grid * **************************************************/ float DensityGrid::GetDensity(float Nx, float Ny, bool fineDensity) { deque::iterator BI; int x_grid, y_grid; float x_dist, y_dist, distance, density = 0; int boundary = 10; // boundary around plane /* Where to look */ x_grid = (int)((Nx + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((Ny + HALF_VIEW + .5) * VIEW_TO_GRID); // Check for edges of density grid (10000 is arbitrary high density) if (x_grid > GRID_SIZE - boundary || x_grid < boundary) { return 10000; } if (y_grid > GRID_SIZE - boundary || y_grid < boundary) { return 10000; } // Fine density? if (fineDensity) { // Go through nearest bins for (int i = y_grid - 1; i <= y_grid + 1; i++) for (int j = x_grid - 1; j <= x_grid + 1; j++) { // Look through bin and add fine repulsions for (BI = GET_BIN(i, j).begin(); BI != GET_BIN(i, j).end(); ++BI) { x_dist = Nx - (BI->x); y_dist = Ny - (BI->y); distance = x_dist * x_dist + y_dist * y_dist; density += 1e-4 / (distance + 1e-50); } } // Course density } else { // Add rough estimate density = Density[y_grid][x_grid]; density *= density; } return density; } /// Wrapper functions for the Add and subtract methods /// Nodes should all be passed by constant ref void DensityGrid::Add(Node &n, bool fineDensity) { if (fineDensity) { fineAdd(n); } else { Add(n); } } void DensityGrid::Subtract( Node &n, bool first_add, bool fine_first_add, bool fineDensity) { if ( fineDensity && !fine_first_add ) { fineSubtract (n); } else if ( !first_add ) { Subtract(n); } } /*************************************************** * Function: DensityGrid::Subtract * * Description: Subtract a node from density grid * **************************************************/ void DensityGrid::Subtract(Node &N) { int x_grid, y_grid, diam; float *den_ptr, *fall_ptr; /* Where to subtract */ x_grid = (int)((N.sub_x + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((N.sub_y + HALF_VIEW + .5) * VIEW_TO_GRID); x_grid -= RADIUS; y_grid -= RADIUS; diam = 2 * RADIUS; // check to see that we are inside grid if ( (x_grid >= GRID_SIZE) || (x_grid < 0) || (y_grid >= GRID_SIZE) || (y_grid < 0) ) { #ifdef MUSE_MPI MPI_Abort ( MPI_COMM_WORLD, 1 ); #else igraph_error("Exceeded density grid in DrL", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EDRL); return; #endif } /* Subtract density values */ den_ptr = &Density[y_grid][x_grid]; fall_ptr = &fall_off[0][0]; for (int i = 0; i <= diam; i++) { for (int j = 0; j <= diam; j++) { *den_ptr++ -= *fall_ptr++; } den_ptr += GRID_SIZE - (diam + 1); } } /*************************************************** * Function: DensityGrid::Add * * Description: Add a node to the density grid * **************************************************/ void DensityGrid::Add(Node &N) { int x_grid, y_grid, diam; float *den_ptr, *fall_ptr; /* Where to add */ x_grid = (int)((N.x + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((N.y + HALF_VIEW + .5) * VIEW_TO_GRID); N.sub_x = N.x; N.sub_y = N.y; x_grid -= RADIUS; y_grid -= RADIUS; diam = 2 * RADIUS; // check to see that we are inside grid if ( (x_grid >= GRID_SIZE) || (x_grid < 0) || (y_grid >= GRID_SIZE) || (y_grid < 0) ) { #ifdef MUSE_MPI MPI_Abort ( MPI_COMM_WORLD, 1 ); #else igraph_error("Exceeded density grid in DrL", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EDRL); return; #endif } /* Add density values */ den_ptr = &Density[y_grid][x_grid]; fall_ptr = &fall_off[0][0]; for (int i = 0; i <= diam; i++) { for (int j = 0; j <= diam; j++) { *den_ptr++ += *fall_ptr++; } den_ptr += GRID_SIZE - (diam + 1); } } /*************************************************** * Function: DensityGrid::fineSubtract * * Description: Subtract a node from bins * **************************************************/ void DensityGrid::fineSubtract(Node &N) { int x_grid, y_grid; /* Where to subtract */ x_grid = (int)((N.sub_x + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((N.sub_y + HALF_VIEW + .5) * VIEW_TO_GRID); GET_BIN(y_grid, x_grid).pop_front(); } /*************************************************** * Function: DensityGrid::fineAdd * * Description: Add a node to the bins * **************************************************/ void DensityGrid::fineAdd(Node &N) { int x_grid, y_grid; /* Where to add */ x_grid = (int)((N.x + HALF_VIEW + .5) * VIEW_TO_GRID); y_grid = (int)((N.y + HALF_VIEW + .5) * VIEW_TO_GRID); N.sub_x = N.x; N.sub_y = N.y; GET_BIN(y_grid, x_grid).push_back(N); } } // namespace drl leidenbase/src/core/layout/drl/drl_Node.h0000644000176200001440000000440514447675374020111 0ustar liggesusers/* * Copyright 2007 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains * certain rights in this software. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sandia National Laboratories nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __NODE_H__ #define __NODE_H__ // The node class contains information about a given node for // use by the density server process. // structure coord used to pass position information between // density server and graph class namespace drl { class Node { public: bool fixed; // if true do not change the // position of this node int id; float x, y; float sub_x, sub_y; float energy; public: Node( int node_id ) { x = y = 0.0; fixed = false; id = node_id; } ~Node() { } }; } // namespace drl #endif //__NODE_H__ leidenbase/src/core/layout/circular.c0000644000176200001440000001417114447675374017402 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_interface.h" #include "core/interruption.h" #include "core/math.h" /** * \ingroup layout * \function igraph_layout_circle * \brief Places the vertices uniformly on a circle, in the order of vertex ids. * * \param graph Pointer to an initialized graph object. * \param res Pointer to an initialized matrix object. This will * contain the result and will be resized as needed. * \param order The order of the vertices on the circle. The vertices * not included here, will be placed at (0,0). Supply * \ref igraph_vss_all() here for all vertices, in the order of * their vertex ids. * \return Error code. * * Time complexity: O(|V|), the * number of vertices. */ int igraph_layout_circle(const igraph_t *graph, igraph_matrix_t *res, igraph_vs_t order) { long int no_of_nodes = igraph_vcount(graph); igraph_integer_t vs_size; long int i; igraph_vit_t vit; IGRAPH_CHECK(igraph_vs_size(graph, &order, &vs_size)); IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 2)); igraph_matrix_null(res); igraph_vit_create(graph, order, &vit); for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { igraph_real_t phi = 2 * M_PI / vs_size * i; int idx = IGRAPH_VIT_GET(vit); MATRIX(*res, idx, 0) = cos(phi); MATRIX(*res, idx, 1) = sin(phi); } igraph_vit_destroy(&vit); return 0; } /** * \function igraph_layout_star * \brief Generates a star-like layout. * * \param graph The input graph. Its edges are ignored by this function. * \param res Pointer to an initialized matrix object. This will * contain the result and will be resized as needed. * \param center The id of the vertex to put in the center. * \param order A numeric vector giving the order of the vertices * (including the center vertex!). If a null pointer, then the * vertices are placed in increasing vertex id order. * \return Error code. * * Time complexity: O(|V|), linear in the number of vertices. * * \sa \ref igraph_layout_circle() and other layout generators. */ int igraph_layout_star(const igraph_t *graph, igraph_matrix_t *res, igraph_integer_t center, const igraph_vector_t *order) { long int no_of_nodes = igraph_vcount(graph); long int c = center; long int i; igraph_real_t step; igraph_real_t phi; if (center < 0 || center >= no_of_nodes) { IGRAPH_ERROR("The given center is not a vertex of the graph.", IGRAPH_EINVAL); } if (order && igraph_vector_size(order) != no_of_nodes) { IGRAPH_ERROR("Invalid order vector length.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 2)); if (no_of_nodes == 1) { MATRIX(*res, 0, 0) = MATRIX(*res, 0, 1) = 0.0; } else { for (i = 0, step = 2 * M_PI / (no_of_nodes - 1), phi = 0; i < no_of_nodes; i++) { long int node = order ? (long int) VECTOR(*order)[i] : i; if (order && (node < 0 || node >= no_of_nodes)) { IGRAPH_ERROR("Elements in the order vector are not all vertices of the graph.", IGRAPH_EINVAL); } if (node != c) { MATRIX(*res, node, 0) = cos(phi); MATRIX(*res, node, 1) = sin(phi); phi += step; } else { MATRIX(*res, node, 0) = MATRIX(*res, node, 1) = 0.0; } } } return 0; } /** * \function igraph_layout_sphere * \brief Places vertices (more or less) uniformly on a sphere. * * * The algorithm was described in the following paper: * Distributing many points on a sphere by E.B. Saff and * A.B.J. Kuijlaars, \emb Mathematical Intelligencer \eme 19.1 (1997) * 5--11. * * \param graph Pointer to an initialized graph object. * \param res Pointer to an initialized matrix object. This will * contain the result and will be resized as needed. * \return Error code. The current implementation always returns with * success. * * Added in version 0.2. * * Time complexity: O(|V|), the number of vertices in the graph. */ int igraph_layout_sphere(const igraph_t *graph, igraph_matrix_t *res) { long int no_of_nodes = igraph_vcount(graph); long int i; igraph_real_t h; IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 3)); if (no_of_nodes != 0) { MATRIX(*res, 0, 0) = M_PI; MATRIX(*res, 0, 1) = 0; } for (i = 1; i < no_of_nodes - 1; i++) { h = -1 + 2 * i / (double)(no_of_nodes - 1); MATRIX(*res, i, 0) = acos(h); MATRIX(*res, i, 1) = fmod((MATRIX(*res, i - 1, 1) + 3.6 / sqrt(no_of_nodes * (1 - h * h))), 2 * M_PI); IGRAPH_ALLOW_INTERRUPTION(); } if (no_of_nodes >= 2) { MATRIX(*res, no_of_nodes - 1, 0) = 0; MATRIX(*res, no_of_nodes - 1, 1) = 0; } for (i = 0; i < no_of_nodes; i++) { igraph_real_t x = cos(MATRIX(*res, i, 1)) * sin(MATRIX(*res, i, 0)); igraph_real_t y = sin(MATRIX(*res, i, 1)) * sin(MATRIX(*res, i, 0)); igraph_real_t z = cos(MATRIX(*res, i, 0)); MATRIX(*res, i, 0) = x; MATRIX(*res, i, 1) = y; MATRIX(*res, i, 2) = z; IGRAPH_ALLOW_INTERRUPTION(); } return 0; } leidenbase/src/core/layout/layout_grid.c0000644000176200001440000000723214447675374020120 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_interface.h" /** * \ingroup layout * \function igraph_layout_grid * \brief Places the vertices on a regular grid on the plane. * * \param graph Pointer to an initialized graph object. * \param res Pointer to an initialized matrix object. This will * contain the result and will be resized as needed. * \param width The number of vertices in a single row of the grid. * When zero or negative, the width of the grid will be the * square root of the number of vertices, rounded up if needed. * \return Error code. The current implementation always returns with * success. * * Time complexity: O(|V|), the number of vertices. */ int igraph_layout_grid(const igraph_t *graph, igraph_matrix_t *res, long int width) { long int i, no_of_nodes = igraph_vcount(graph); igraph_real_t x, y; IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 2)); if (width <= 0) { width = (long int) ceil(sqrt(no_of_nodes)); } x = y = 0; for (i = 0; i < no_of_nodes; i++) { MATRIX(*res, i, 0) = x++; MATRIX(*res, i, 1) = y; if (x == width) { x = 0; y++; } } return 0; } /** * \ingroup layout * \function igraph_layout_grid_3d * \brief Places the vertices on a regular grid in the 3D space. * * \param graph Pointer to an initialized graph object. * \param res Pointer to an initialized matrix object. This will * contain the result and will be resized as needed. * \param width The number of vertices in a single row of the grid. When * zero or negative, the width is determined automatically. * \param height The number of vertices in a single column of the grid. When * zero or negative, the height is determined automatically. * * \return Error code. The current implementation always returns with * success. * * Time complexity: O(|V|), the number of vertices. */ int igraph_layout_grid_3d(const igraph_t *graph, igraph_matrix_t *res, long int width, long int height) { long int i, no_of_nodes = igraph_vcount(graph); igraph_real_t x, y, z; IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, 3)); if (width <= 0 && height <= 0) { width = height = (long int) ceil(pow(no_of_nodes, 1.0 / 3)); } else if (width <= 0) { width = (long int) ceil(sqrt(no_of_nodes / (double)height)); } else if (height <= 0) { height = (long int) ceil(sqrt(no_of_nodes / (double)width)); } x = y = z = 0; for (i = 0; i < no_of_nodes; i++) { MATRIX(*res, i, 0) = x++; MATRIX(*res, i, 1) = y; MATRIX(*res, i, 2) = z; if (x == width) { x = 0; y++; if (y == height) { y = 0; z++; } } } return 0; } leidenbase/src/core/layout/merge_grid.h0000644000176200001440000000437614447675374017715 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_LAYOUT_MERGE_GRID_H #define IGRAPH_LAYOUT_MERGE_GRID_H #include "igraph_decls.h" #include "igraph_types.h" __BEGIN_DECLS /* A type of grid used for merging layouts; each cell is owned by exactly one graph */ typedef struct igraph_i_layout_mergegrid_t { long int *data; long int stepsx, stepsy; igraph_real_t minx, maxx, deltax; igraph_real_t miny, maxy, deltay; } igraph_i_layout_mergegrid_t; IGRAPH_PRIVATE_EXPORT int igraph_i_layout_mergegrid_init(igraph_i_layout_mergegrid_t *grid, igraph_real_t minx, igraph_real_t maxx, long int stepsx, igraph_real_t miny, igraph_real_t maxy, long int stepsy); IGRAPH_PRIVATE_EXPORT void igraph_i_layout_mergegrid_destroy(igraph_i_layout_mergegrid_t *grid); IGRAPH_PRIVATE_EXPORT int igraph_i_layout_merge_place_sphere(igraph_i_layout_mergegrid_t *grid, igraph_real_t x, igraph_real_t y, igraph_real_t r, long int id); long int igraph_i_layout_mergegrid_get(igraph_i_layout_mergegrid_t *grid, igraph_real_t x, igraph_real_t y); long int igraph_i_layout_mergegrid_get_sphere(igraph_i_layout_mergegrid_t *g, igraph_real_t x, igraph_real_t y, igraph_real_t r); __END_DECLS #endif leidenbase/src/core/layout/davidson_harel.c0000644000176200001440000004507514447675374020567 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_interface.h" #include "igraph_random.h" #include "core/math.h" #include "core/interruption.h" #include "layout/layout_internal.h" #include /* not 'static', used in tests */ igraph_bool_t igraph_i_layout_segments_intersect(float p0_x, float p0_y, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y) { float s1_x = p1_x - p0_x; float s1_y = p1_y - p0_y; float s2_x = p3_x - p2_x; float s2_y = p3_y - p2_y; float s1, s2, t1, t2, s, t; s1 = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)); s2 = (-s2_x * s1_y + s1_x * s2_y); if (s2 == 0) { return 0; } t1 = ( s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)); t2 = (-s2_x * s1_y + s1_x * s2_y); s = s1 / s2; t = t1 / t2; return s >= 0 && s <= 1 && t >= 0 && t <= 1 ? 1 : 0; } /* not 'static', used in tests */ float igraph_i_layout_point_segment_dist2(float v_x, float v_y, float u1_x, float u1_y, float u2_x, float u2_y) { float dx = u2_x - u1_x; float dy = u2_y - u1_y; float l2 = dx * dx + dy * dy; float t, p_x, p_y; if (l2 == 0) { return (v_x - u1_x) * (v_x - u1_x) + (v_y - u1_y) * (v_y - u1_y); } t = ((v_x - u1_x) * dx + (v_y - u1_y) * dy) / l2; if (t < 0.0) { return (v_x - u1_x) * (v_x - u1_x) + (v_y - u1_y) * (v_y - u1_y); } else if (t > 1.0) { return (v_x - u2_x) * (v_x - u2_x) + (v_y - u2_y) * (v_y - u2_y); } p_x = u1_x + t * dx; p_y = u1_y + t * dy; return (v_x - p_x) * (v_x - p_x) + (v_y - p_y) * (v_y - p_y); } /** * \function igraph_layout_davidson_harel * Davidson-Harel layout algorithm * * This function implements the algorithm by Davidson and Harel, * see Ron Davidson, David Harel: Drawing Graphs Nicely Using * Simulated Annealing. ACM Transactions on Graphics 15(4), * pp. 301-331, 1996. * * * The algorithm uses simulated annealing and a sophisticated * energy function, which is unfortunately hard to parameterize * for different graphs. The original publication did not disclose any * parameter values, and the ones below were determined by * experimentation. * * * The algorithm consists of two phases, an annealing phase, and a * fine-tuning phase. There is no simulated annealing in the second * phase. * * * Our implementation tries to follow the original publication, as * much as possible. The only major difference is that coordinates are * explicitly kept within the bounds of the rectangle of the layout. * * \param graph The input graph, edge directions are ignored. * \param res A matrix, the result is stored here. It can be used to * supply start coordinates, see \p use_seed. * \param use_seed Boolean, whether to use the supplied \p res as * start coordinates. * \param maxiter The maximum number of annealing iterations. A * reasonable value for smaller graphs is 10. * \param fineiter The number of fine tuning iterations. A reasonable * value is max(10, log2(n)) where n is the number of vertices. * \param cool_fact Cooling factor. A reasonable value is 0.75. * \param weight_node_dist Weight for the node-node distances * component of the energy function. Reasonable value: 1.0. * \param weight_border Weight for the distance from the border * component of the energy function. It can be set to zero, if * vertices are allowed to sit on the border. * \param weight_edge_lengths Weight for the edge length component * of the energy function, a reasonable value is the density of * the graph divided by 10. * \param weight_edge_crossings Weight for the edge crossing component * of the energy function, a reasonable default is 1 minus the * square root of the density of the graph. * \param weight_node_edge_dist Weight for the node-edge distance * component of the energy function. A reasonable value is * 1 minus the density, divided by 5. * \return Error code. * * Time complexity: one first phase iteration has time complexity * O(n^2+m^2), one fine tuning iteration has time complexity O(mn). * Time complexity might be smaller if some of the weights of the * components of the energy function are set to zero. * */ int igraph_layout_davidson_harel(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_integer_t fineiter, igraph_real_t cool_fact, igraph_real_t weight_node_dist, igraph_real_t weight_border, igraph_real_t weight_edge_lengths, igraph_real_t weight_edge_crossings, igraph_real_t weight_node_edge_dist) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_integer_t no_edges = igraph_ecount(graph); float width = sqrt(no_nodes) * 10, height = width; igraph_vector_int_t perm; igraph_bool_t fine_tuning = 0; igraph_integer_t round, i; igraph_vector_float_t try_x, try_y; igraph_vector_int_t try_idx; float move_radius = width / 2; float fine_tuning_factor = 0.01f; igraph_vector_t neis; float min_x = width / 2, max_x = -width / 2, min_y = height / 2, max_y = -height / 2; igraph_integer_t no_tries = 30; float w_node_dist = weight_node_dist ; /* 1.0 */ float w_borderlines = weight_border; /* 0.0 */ float w_edge_lengths = weight_edge_lengths; /* 0.0001; */ float w_edge_crossings = weight_edge_crossings; /* 1.0 */ float w_node_edge_dist = weight_node_edge_dist; /* 0.2 */ if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 2)) { IGRAPH_ERROR("Invalid start position matrix size in " "Davidson-Harel layout", IGRAPH_EINVAL); } if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negative in " "Davidson-Harel layout", IGRAPH_EINVAL); } if (fineiter < 0) { IGRAPH_ERROR("Number of fine tuning iterations must be non-negative in " "Davidson-Harel layout", IGRAPH_EINVAL); } if (cool_fact <= 0 || cool_fact >= 1) { IGRAPH_ERROR("Cooling factor must be in (0,1) in " "Davidson-Harel layout", IGRAPH_EINVAL); } if (no_nodes == 0) { return 0; } IGRAPH_CHECK(igraph_vector_int_init_seq(&perm, 0, no_nodes - 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &perm); IGRAPH_CHECK(igraph_vector_float_init(&try_x, no_tries)); IGRAPH_FINALLY(igraph_vector_float_destroy, &try_x); IGRAPH_CHECK(igraph_vector_float_init(&try_y, no_tries)); IGRAPH_FINALLY(igraph_vector_float_destroy, &try_y); IGRAPH_CHECK(igraph_vector_int_init_seq(&try_idx, 0, no_tries - 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &try_idx); IGRAPH_VECTOR_INIT_FINALLY(&neis, 100); RNG_BEGIN(); if (!use_seed) { IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2)); for (i = 0; i < no_nodes; i++) { float x, y; x = MATRIX(*res, i, 0) = RNG_UNIF(-width / 2, width / 2); y = MATRIX(*res, i, 1) = RNG_UNIF(-height / 2, height / 2); if (x < min_x) { min_x = x; } else if (x > max_x) { max_x = x; } if (y < min_y) { min_y = y; } else if (y > max_y) { max_y = y; } } } else { min_x = IGRAPH_INFINITY; max_x = IGRAPH_NEGINFINITY; min_y = IGRAPH_INFINITY; max_y = IGRAPH_NEGINFINITY; for (i = 0; i < no_nodes; i++) { float x = MATRIX(*res, i, 0); float y = MATRIX(*res, i, 1); if (x < min_x) { min_x = x; } else if (x > max_x) { max_x = x; } if (y < min_y) { min_y = y; } else if (y > max_y) { max_y = y; } } } for (i = 0; i < no_tries; i++) { float phi = 2 * M_PI / no_tries * i; VECTOR(try_x)[i] = cos(phi); VECTOR(try_y)[i] = sin(phi); } for (round = 0; round < maxiter + fineiter; round++) { igraph_integer_t p; igraph_vector_int_shuffle(&perm); IGRAPH_ALLOW_INTERRUPTION(); fine_tuning = round >= maxiter; if (fine_tuning) { float fx = fine_tuning_factor * (max_x - min_x); float fy = fine_tuning_factor * (max_y - min_y); move_radius = fx < fy ? fx : fy; } for (p = 0; p < no_nodes; p++) { igraph_integer_t t; igraph_integer_t v = VECTOR(perm)[p]; igraph_vector_int_shuffle(&try_idx); for (t = 0; t < no_tries; t++) { float diff_energy = 0.0; int ti = VECTOR(try_idx)[t]; /* Try moving it */ float old_x = MATRIX(*res, v, 0); float old_y = MATRIX(*res, v, 1); float new_x = old_x + move_radius * VECTOR(try_x)[ti]; float new_y = old_y + move_radius * VECTOR(try_y)[ti]; if (new_x < -width / 2) { new_x = -width / 2 - 1e-6; } if (new_x > width / 2) { new_x = width / 2 - 1e-6; } if (new_y < -height / 2) { new_y = -height / 2 - 1e-6; } if (new_y > height / 2) { new_y = height / 2 - 1e-6; } if (w_node_dist != 0) { igraph_integer_t u; for (u = 0; u < no_nodes; u++) { float odx, ody, odist2, dx, dy, dist2; if (u == v) { continue; } odx = old_x - MATRIX(*res, u, 0); ody = old_y - MATRIX(*res, u, 1); dx = new_x - MATRIX(*res, u, 0); dy = new_y - MATRIX(*res, u, 1); odist2 = odx * odx + ody * ody; dist2 = dx * dx + dy * dy; diff_energy += w_node_dist / dist2 - w_node_dist / odist2; } } if (w_borderlines != 0) { float odx1 = width / 2 - old_x, odx2 = old_x + width / 2; float ody1 = height / 2 - old_y, ody2 = old_y + height / 2; float dx1 = width / 2 - new_x, dx2 = new_x + width / 2; float dy1 = height / 2 - new_y, dy2 = new_y + height / 2; if (odx1 < 0) { odx1 = 2; } if (odx2 < 0) { odx2 = 2; } if (ody1 < 0) { ody1 = 2; } if (ody2 < 0) { ody2 = 2; } if (dx1 < 0) { dx1 = 2; } if (dx2 < 0) { dx2 = 2; } if (dy1 < 0) { dy1 = 2; } if (dy2 < 0) { dy2 = 2; } diff_energy -= w_borderlines * (1.0 / (odx1 * odx1) + 1.0 / (odx2 * odx2) + 1.0 / (ody1 * ody1) + 1.0 / (ody2 * ody2)); diff_energy += w_borderlines * (1.0 / (dx1 * dx1) + 1.0 / (dx2 * dx2) + 1.0 / (dy1 * dy1) + 1.0 / (dy2 * dy2)); } if (w_edge_lengths != 0) { igraph_integer_t len, j; igraph_neighbors(graph, &neis, v, IGRAPH_ALL); len = igraph_vector_size(&neis); for (j = 0; j < len; j++) { igraph_integer_t u = VECTOR(neis)[j]; float odx = old_x - MATRIX(*res, u, 0); float ody = old_y - MATRIX(*res, u, 1); float odist2 = odx * odx + ody * ody; float dx = new_x - MATRIX(*res, u, 0); float dy = new_y - MATRIX(*res, u, 1); float dist2 = dx * dx + dy * dy; diff_energy += w_edge_lengths * (dist2 - odist2); } } if (w_edge_crossings != 0) { igraph_integer_t len, j, no = 0; igraph_neighbors(graph, &neis, v, IGRAPH_ALL); len = igraph_vector_size(&neis); for (j = 0; j < len; j++) { igraph_integer_t u = VECTOR(neis)[j]; float u_x = MATRIX(*res, u, 0); float u_y = MATRIX(*res, u, 1); igraph_integer_t e; for (e = 0; e < no_edges; e++) { igraph_integer_t u1 = IGRAPH_FROM(graph, e); igraph_integer_t u2 = IGRAPH_TO(graph, e); float u1_x, u1_y, u2_x, u2_y; if (u1 == v || u2 == v || u1 == u || u2 == u) { continue; } u1_x = MATRIX(*res, u1, 0); u1_y = MATRIX(*res, u1, 1); u2_x = MATRIX(*res, u2, 0); u2_y = MATRIX(*res, u2, 1); no -= igraph_i_layout_segments_intersect(old_x, old_y, u_x, u_y, u1_x, u1_y, u2_x, u2_y); no += igraph_i_layout_segments_intersect(new_x, new_y, u_x, u_y, u1_x, u1_y, u2_x, u2_y); } } diff_energy += w_edge_crossings * no; } if (w_node_edge_dist != 0 && fine_tuning) { igraph_integer_t e, no; /* All non-incident edges from the moved 'v' */ for (e = 0; e < no_edges; e++) { igraph_integer_t u1 = IGRAPH_FROM(graph, e); igraph_integer_t u2 = IGRAPH_TO(graph, e); float u1_x, u1_y, u2_x, u2_y, d_ev; if (u1 == v || u2 == v) { continue; } u1_x = MATRIX(*res, u1, 0); u1_y = MATRIX(*res, u1, 1); u2_x = MATRIX(*res, u2, 0); u2_y = MATRIX(*res, u2, 1); d_ev = igraph_i_layout_point_segment_dist2(old_x, old_y, u1_x, u1_y, u2_x, u2_y); diff_energy -= w_node_edge_dist / d_ev; d_ev = igraph_i_layout_point_segment_dist2(new_x, new_y, u1_x, u1_y, u2_x, u2_y); diff_energy += w_node_edge_dist / d_ev; } /* All other nodes from all of v's incident edges */ igraph_incident(graph, &neis, v, IGRAPH_ALL); no = igraph_vector_size(&neis); for (e = 0; e < no; e++) { igraph_integer_t mye = VECTOR(neis)[e]; igraph_integer_t u = IGRAPH_OTHER(graph, mye, v); float u_x = MATRIX(*res, u, 0); float u_y = MATRIX(*res, u, 1); igraph_integer_t w; for (w = 0; w < no_nodes; w++) { float w_x, w_y, d_ev; if (w == v || w == u) { continue; } w_x = MATRIX(*res, w, 0); w_y = MATRIX(*res, w, 1); d_ev = igraph_i_layout_point_segment_dist2(w_x, w_y, old_x, old_y, u_x, u_y); diff_energy -= w_node_edge_dist / d_ev; d_ev = igraph_i_layout_point_segment_dist2(w_x, w_y, new_x, new_y, u_x, u_y); diff_energy += w_node_edge_dist / d_ev; } } } /* w_node_edge_dist != 0 && fine_tuning */ if (diff_energy < 0 || (!fine_tuning && RNG_UNIF01() < exp(-diff_energy / move_radius))) { MATRIX(*res, v, 0) = new_x; MATRIX(*res, v, 1) = new_y; if (new_x < min_x) { min_x = new_x; } else if (new_x > max_x) { max_x = new_x; } if (new_y < min_y) { min_y = new_y; } else if (new_y > max_y) { max_y = new_y; } } } /* t < no_tries */ } /* p < no_nodes */ move_radius *= cool_fact; } /* round < maxiter */ RNG_END(); igraph_vector_destroy(&neis); igraph_vector_int_destroy(&try_idx); igraph_vector_float_destroy(&try_x); igraph_vector_float_destroy(&try_y); igraph_vector_int_destroy(&perm); IGRAPH_FINALLY_CLEAN(5); return 0; } leidenbase/src/core/layout/fruchterman_reingold.c0000644000176200001440000006772014447675374022007 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_random.h" #include "igraph_interface.h" #include "igraph_components.h" #include "core/grid.h" #include "core/interruption.h" static int igraph_layout_i_fr(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t niter, igraph_real_t start_temp, const igraph_vector_t *weight, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_integer_t no_edges = igraph_ecount(graph); igraph_integer_t i; igraph_vector_float_t dispx, dispy; igraph_real_t temp = start_temp; igraph_real_t difftemp = start_temp / niter; float width = sqrtf(no_nodes), height = width; igraph_bool_t conn = 1; float C = 0; IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK)); if (!conn) { C = no_nodes * sqrtf(no_nodes); } RNG_BEGIN(); if (!use_seed) { IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2)); for (i = 0; i < no_nodes; i++) { igraph_real_t x1 = minx ? VECTOR(*minx)[i] : -width / 2; igraph_real_t x2 = maxx ? VECTOR(*maxx)[i] : width / 2; igraph_real_t y1 = miny ? VECTOR(*miny)[i] : -height / 2; igraph_real_t y2 = maxy ? VECTOR(*maxy)[i] : height / 2; if (!igraph_finite(x1)) { x1 = -sqrt(no_nodes) / 2; } if (!igraph_finite(x2)) { x2 = sqrt(no_nodes) / 2; } if (!igraph_finite(y1)) { y1 = -sqrt(no_nodes) / 2; } if (!igraph_finite(y2)) { y2 = sqrt(no_nodes) / 2; } MATRIX(*res, i, 0) = RNG_UNIF(x1, x2); MATRIX(*res, i, 1) = RNG_UNIF(y1, y2); } } IGRAPH_CHECK(igraph_vector_float_init(&dispx, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &dispx); IGRAPH_CHECK(igraph_vector_float_init(&dispy, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &dispy); for (i = 0; i < niter; i++) { igraph_integer_t v, u, e; IGRAPH_ALLOW_INTERRUPTION(); /* calculate repulsive forces, we have a special version for unconnected graphs */ igraph_vector_float_null(&dispx); igraph_vector_float_null(&dispy); if (conn) { for (v = 0; v < no_nodes; v++) { for (u = v + 1; u < no_nodes; u++) { float dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); float dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); float dlen = dx * dx + dy * dy; if (dlen == 0) { dx = RNG_UNIF01() * 1e-9; dy = RNG_UNIF01() * 1e-9; dlen = dx * dx + dy * dy; } VECTOR(dispx)[v] += dx / dlen; VECTOR(dispy)[v] += dy / dlen; VECTOR(dispx)[u] -= dx / dlen; VECTOR(dispy)[u] -= dy / dlen; } } } else { for (v = 0; v < no_nodes; v++) { for (u = v + 1; u < no_nodes; u++) { float dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); float dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); float dlen, rdlen; dlen = dx * dx + dy * dy; if (dlen == 0) { dx = RNG_UNIF(0, 1e-6); dy = RNG_UNIF(0, 1e-6); dlen = dx * dx + dy * dy; } rdlen = sqrt(dlen); VECTOR(dispx)[v] += dx * (C - dlen * rdlen) / (dlen * C); VECTOR(dispy)[v] += dy * (C - dlen * rdlen) / (dlen * C); VECTOR(dispx)[u] -= dx * (C - dlen * rdlen) / (dlen * C); VECTOR(dispy)[u] -= dy * (C - dlen * rdlen) / (dlen * C); } } } /* calculate attractive forces */ for (e = 0; e < no_edges; e++) { /* each edges is an ordered pair of vertices v and u */ igraph_integer_t v = IGRAPH_FROM(graph, e); igraph_integer_t u = IGRAPH_TO(graph, e); igraph_real_t dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); igraph_real_t dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); igraph_real_t w = weight ? VECTOR(*weight)[e] : 1.0; igraph_real_t dlen = sqrt(dx * dx + dy * dy) * w; VECTOR(dispx)[v] -= (dx * dlen); VECTOR(dispy)[v] -= (dy * dlen); VECTOR(dispx)[u] += (dx * dlen); VECTOR(dispy)[u] += (dy * dlen); } /* limit max displacement to temperature t and prevent from displacement outside frame */ for (v = 0; v < no_nodes; v++) { igraph_real_t dx = VECTOR(dispx)[v] + RNG_UNIF01() * 1e-9; igraph_real_t dy = VECTOR(dispy)[v] + RNG_UNIF01() * 1e-9; igraph_real_t displen = sqrt(dx * dx + dy * dy); igraph_real_t mx = fabs(dx) < temp ? dx : temp; igraph_real_t my = fabs(dy) < temp ? dy : temp; if (displen > 0) { MATRIX(*res, v, 0) += (dx / displen) * mx; MATRIX(*res, v, 1) += (dy / displen) * my; } if (minx && MATRIX(*res, v, 0) < VECTOR(*minx)[v]) { MATRIX(*res, v, 0) = VECTOR(*minx)[v]; } if (maxx && MATRIX(*res, v, 0) > VECTOR(*maxx)[v]) { MATRIX(*res, v, 0) = VECTOR(*maxx)[v]; } if (miny && MATRIX(*res, v, 1) < VECTOR(*miny)[v]) { MATRIX(*res, v, 1) = VECTOR(*miny)[v]; } if (maxy && MATRIX(*res, v, 1) > VECTOR(*maxy)[v]) { MATRIX(*res, v, 1) = VECTOR(*maxy)[v]; } } temp -= difftemp; } RNG_END(); igraph_vector_float_destroy(&dispx); igraph_vector_float_destroy(&dispy); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_layout_i_grid_fr( const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t niter, igraph_real_t start_temp, const igraph_vector_t *weight, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_integer_t no_edges = igraph_ecount(graph); float width = sqrtf(no_nodes), height = width; igraph_2dgrid_t grid; igraph_vector_float_t dispx, dispy; igraph_real_t temp = start_temp; igraph_real_t difftemp = start_temp / niter; igraph_2dgrid_iterator_t vidit; igraph_integer_t i; const float cellsize = 2.0; RNG_BEGIN(); if (!use_seed) { IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2)); for (i = 0; i < no_nodes; i++) { igraph_real_t x1 = minx ? VECTOR(*minx)[i] : -width / 2; igraph_real_t x2 = maxx ? VECTOR(*maxx)[i] : width / 2; igraph_real_t y1 = miny ? VECTOR(*miny)[i] : -height / 2; igraph_real_t y2 = maxy ? VECTOR(*maxy)[i] : height / 2; if (!igraph_finite(x1)) { x1 = -sqrt(no_nodes) / 2; } if (!igraph_finite(x2)) { x2 = sqrt(no_nodes) / 2; } if (!igraph_finite(y1)) { y1 = -sqrt(no_nodes) / 2; } if (!igraph_finite(y2)) { y2 = sqrt(no_nodes) / 2; } MATRIX(*res, i, 0) = RNG_UNIF(x1, x2); MATRIX(*res, i, 1) = RNG_UNIF(y1, y2); } } /* make grid */ IGRAPH_CHECK(igraph_2dgrid_init(&grid, res, -width / 2, width / 2, cellsize, -height / 2, height / 2, cellsize)); IGRAPH_FINALLY(igraph_2dgrid_destroy, &grid); /* place vertices on grid */ for (i = 0; i < no_nodes; i++) { igraph_2dgrid_add2(&grid, i); } IGRAPH_CHECK(igraph_vector_float_init(&dispx, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &dispx); IGRAPH_CHECK(igraph_vector_float_init(&dispy, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &dispy); for (i = 0; i < niter; i++) { igraph_integer_t v, u, e; IGRAPH_ALLOW_INTERRUPTION(); igraph_vector_float_null(&dispx); igraph_vector_float_null(&dispy); /* repulsion */ igraph_2dgrid_reset(&grid, &vidit); while ( (v = igraph_2dgrid_next(&grid, &vidit) - 1) != -1) { while ( (u = igraph_2dgrid_next_nei(&grid, &vidit) - 1) != -1) { float dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); float dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); float dlen = dx * dx + dy * dy; if (dlen < cellsize * cellsize) { VECTOR(dispx)[v] += dx / dlen; VECTOR(dispy)[v] += dy / dlen; VECTOR(dispx)[u] -= dx / dlen; VECTOR(dispy)[u] -= dy / dlen; } } } /* attraction */ for (e = 0; e < no_edges; e++) { igraph_integer_t v = IGRAPH_FROM(graph, e); igraph_integer_t u = IGRAPH_TO(graph, e); igraph_real_t dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); igraph_real_t dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); igraph_real_t w = weight ? VECTOR(*weight)[e] : 1.0; igraph_real_t dlen = sqrt(dx * dx + dy * dy) * w; VECTOR(dispx)[v] -= (dx * dlen); VECTOR(dispy)[v] -= (dy * dlen); VECTOR(dispx)[u] += (dx * dlen); VECTOR(dispy)[u] += (dy * dlen); } /* update */ for (v = 0; v < no_nodes; v++) { igraph_real_t dx = VECTOR(dispx)[v] + RNG_UNIF01() * 1e-9; igraph_real_t dy = VECTOR(dispy)[v] + RNG_UNIF01() * 1e-9; igraph_real_t displen = sqrt(dx * dx + dy * dy); igraph_real_t mx = fabs(dx) < temp ? dx : temp; igraph_real_t my = fabs(dy) < temp ? dy : temp; if (displen > 0) { MATRIX(*res, v, 0) += (dx / displen) * mx; MATRIX(*res, v, 1) += (dy / displen) * my; } if (minx && MATRIX(*res, v, 0) < VECTOR(*minx)[v]) { MATRIX(*res, v, 0) = VECTOR(*minx)[v]; } if (maxx && MATRIX(*res, v, 0) > VECTOR(*maxx)[v]) { MATRIX(*res, v, 0) = VECTOR(*maxx)[v]; } if (miny && MATRIX(*res, v, 1) < VECTOR(*miny)[v]) { MATRIX(*res, v, 1) = VECTOR(*miny)[v]; } if (maxy && MATRIX(*res, v, 1) > VECTOR(*maxy)[v]) { MATRIX(*res, v, 1) = VECTOR(*maxy)[v]; } } temp -= difftemp; } igraph_vector_float_destroy(&dispx); igraph_vector_float_destroy(&dispy); igraph_2dgrid_destroy(&grid); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \ingroup layout * \function igraph_layout_fruchterman_reingold * \brief Places the vertices on a plane according to the Fruchterman-Reingold algorithm. * * * This is a force-directed layout, see Fruchterman, T.M.J. and * Reingold, E.M.: Graph Drawing by Force-directed Placement. * Software -- Practice and Experience, 21/11, 1129--1164, * 1991. * \param graph Pointer to an initialized graph object. * \param res Pointer to an initialized matrix object. This will * contain the result and will be resized as needed. * \param use_seed Logical, if true the supplied values in the * \p res argument are used as an initial layout, if * false a random initial layout is used. * \param niter The number of iterations to do. A reasonable * default value is 500. * \param start_temp Start temperature. This is the maximum amount * of movement allowed along one axis, within one step, for a * vertex. Currently it is decreased linearly to zero during * the iteration. * \param grid Whether to use the (fast but less accurate) grid based * version of the algorithm. Possible values: \c * IGRAPH_LAYOUT_GRID, \c IGRAPH_LAYOUT_NOGRID, \c * IGRAPH_LAYOUT_AUTOGRID. The last one uses the grid based * version only for large graphs, currently the ones with * more than 1000 vertices. * \param weight Pointer to a vector containing edge weights, * the attraction along the edges will be multiplied by these. * It will be ignored if it is a null-pointer. * \param minx Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote x \endquote coordinate for every vertex. * \param maxx Same as \p minx, but the maximum \quote x \endquote * coordinates. * \param miny Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote y \endquote coordinate for every vertex. * \param maxy Same as \p miny, but the maximum \quote y \endquote * coordinates. * \return Error code. * * Time complexity: O(|V|^2) in each * iteration, |V| is the number of * vertices in the graph. */ int igraph_layout_fruchterman_reingold(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t niter, igraph_real_t start_temp, igraph_layout_grid_t grid, const igraph_vector_t *weight, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy) { igraph_integer_t no_nodes = igraph_vcount(graph); if (niter < 0) { IGRAPH_ERROR("Number of iterations must be non-negative in " "Fruchterman-Reingold layout.", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 2)) { IGRAPH_ERROR("Invalid start position matrix size in " "Fruchterman-Reingold layout.", IGRAPH_EINVAL); } if (weight && igraph_vector_size(weight) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length.", IGRAPH_EINVAL); } if (minx && igraph_vector_size(minx) != no_nodes) { IGRAPH_ERROR("Invalid minx vector length.", IGRAPH_EINVAL); } if (maxx && igraph_vector_size(maxx) != no_nodes) { IGRAPH_ERROR("Invalid maxx vector length.", IGRAPH_EINVAL); } if (minx && maxx && !igraph_vector_all_le(minx, maxx)) { IGRAPH_ERROR("minx must not be greater than maxx.", IGRAPH_EINVAL); } if (miny && igraph_vector_size(miny) != no_nodes) { IGRAPH_ERROR("Invalid miny vector length.", IGRAPH_EINVAL); } if (maxy && igraph_vector_size(maxy) != no_nodes) { IGRAPH_ERROR("Invalid maxy vector length.", IGRAPH_EINVAL); } if (miny && maxy && !igraph_vector_all_le(miny, maxy)) { IGRAPH_ERROR("miny must not be greater than maxy.", IGRAPH_EINVAL); } if (grid == IGRAPH_LAYOUT_AUTOGRID) { if (no_nodes > 1000) { grid = IGRAPH_LAYOUT_GRID; } else { grid = IGRAPH_LAYOUT_NOGRID; } } if (grid == IGRAPH_LAYOUT_GRID) { return igraph_layout_i_grid_fr(graph, res, use_seed, niter, start_temp, weight, minx, maxx, miny, maxy); } else { return igraph_layout_i_fr(graph, res, use_seed, niter, start_temp, weight, minx, maxx, miny, maxy); } } /** * \function igraph_layout_fruchterman_reingold_3d * \brief 3D Fruchterman-Reingold algorithm. * * This is the 3D version of the force based * Fruchterman-Reingold layout (see \ref * igraph_layout_fruchterman_reingold for the 2D version * * \param graph Pointer to an initialized graph object. * \param res Pointer to an initialized matrix object. This will * contain the result and will be resized as needed. * \param use_seed Logical, if true the supplied values in the * \p res argument are used as an initial layout, if * false a random initial layout is used. * \param niter The number of iterations to do. A reasonable * default value is 500. * \param start_temp Start temperature. This is the maximum amount * of movement alloved along one axis, within one step, for a * vertex. Currently it is decreased linearly to zero during * the iteration. * \param weight Pointer to a vector containing edge weights, * the attraction along the edges will be multiplied by these. * It will be ignored if it is a null-pointer. * \param minx Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote x \endquote coordinate for every vertex. * \param maxx Same as \p minx, but the maximum \quote x \endquote * coordinates. * \param miny Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote y \endquote coordinate for every vertex. * \param maxy Same as \p miny, but the maximum \quote y \endquote * coordinates. * \param minz Pointer to a vector, or a \c NULL pointer. If not a * \c NULL pointer then the vector gives the minimum * \quote z \endquote coordinate for every vertex. * \param maxz Same as \p minz, but the maximum \quote z \endquote * coordinates. * \return Error code. * * Added in version 0.2. * * Time complexity: O(|V|^2) in each * iteration, |V| is the number of * vertices in the graph. * */ int igraph_layout_fruchterman_reingold_3d(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t niter, igraph_real_t start_temp, const igraph_vector_t *weight, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy, const igraph_vector_t *minz, const igraph_vector_t *maxz) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_integer_t no_edges = igraph_ecount(graph); igraph_integer_t i; igraph_vector_float_t dispx, dispy, dispz; igraph_real_t temp = start_temp; igraph_real_t difftemp = start_temp / niter; float width = sqrtf(no_nodes), height = width, depth = width; igraph_bool_t conn = 1; float C = 0; if (niter < 0) { IGRAPH_ERROR("Number of iterations must be non-negative in " "Fruchterman-Reingold layout", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 3)) { IGRAPH_ERROR("Invalid start position matrix size in " "Fruchterman-Reingold layout", IGRAPH_EINVAL); } if (weight && igraph_vector_size(weight) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } if (minx && igraph_vector_size(minx) != no_nodes) { IGRAPH_ERROR("Invalid minx vector length", IGRAPH_EINVAL); } if (maxx && igraph_vector_size(maxx) != no_nodes) { IGRAPH_ERROR("Invalid maxx vector length", IGRAPH_EINVAL); } if (minx && maxx && !igraph_vector_all_le(minx, maxx)) { IGRAPH_ERROR("minx must not be greater than maxx", IGRAPH_EINVAL); } if (miny && igraph_vector_size(miny) != no_nodes) { IGRAPH_ERROR("Invalid miny vector length", IGRAPH_EINVAL); } if (maxy && igraph_vector_size(maxy) != no_nodes) { IGRAPH_ERROR("Invalid maxy vector length", IGRAPH_EINVAL); } if (miny && maxy && !igraph_vector_all_le(miny, maxy)) { IGRAPH_ERROR("miny must not be greater than maxy", IGRAPH_EINVAL); } if (minz && igraph_vector_size(minz) != no_nodes) { IGRAPH_ERROR("Invalid minz vector length", IGRAPH_EINVAL); } if (maxz && igraph_vector_size(maxz) != no_nodes) { IGRAPH_ERROR("Invalid maxz vector length", IGRAPH_EINVAL); } if (minz && maxz && !igraph_vector_all_le(minz, maxz)) { IGRAPH_ERROR("minz must not be greater than maxz", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK)); if (!conn) { C = no_nodes * sqrtf(no_nodes); } RNG_BEGIN(); if (!use_seed) { IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 3)); for (i = 0; i < no_nodes; i++) { igraph_real_t x1 = minx ? VECTOR(*minx)[i] : -width / 2; igraph_real_t x2 = maxx ? VECTOR(*maxx)[i] : width / 2; igraph_real_t y1 = miny ? VECTOR(*miny)[i] : -height / 2; igraph_real_t y2 = maxy ? VECTOR(*maxy)[i] : height / 2; igraph_real_t z1 = minz ? VECTOR(*minz)[i] : -depth / 2; igraph_real_t z2 = maxz ? VECTOR(*maxz)[i] : depth / 2; MATRIX(*res, i, 0) = RNG_UNIF(x1, x2); MATRIX(*res, i, 1) = RNG_UNIF(y1, y2); MATRIX(*res, i, 2) = RNG_UNIF(z1, z2); } } IGRAPH_CHECK(igraph_vector_float_init(&dispx, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &dispx); IGRAPH_CHECK(igraph_vector_float_init(&dispy, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &dispy); IGRAPH_CHECK(igraph_vector_float_init(&dispz, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &dispz); for (i = 0; i < niter; i++) { igraph_integer_t v, u, e; IGRAPH_ALLOW_INTERRUPTION(); /* calculate repulsive forces, we have a special version for unconnected graphs */ igraph_vector_float_null(&dispx); igraph_vector_float_null(&dispy); igraph_vector_float_null(&dispz); if (conn) { for (v = 0; v < no_nodes; v++) { for (u = v + 1; u < no_nodes; u++) { float dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); float dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); float dz = MATRIX(*res, v, 2) - MATRIX(*res, u, 2); float dlen = dx * dx + dy * dy + dz * dz; if (dlen == 0) { dx = RNG_UNIF01() * 1e-9; dy = RNG_UNIF01() * 1e-9; dz = RNG_UNIF01() * 1e-9; dlen = dx * dx + dy * dy + dz * dz; } VECTOR(dispx)[v] += dx / dlen; VECTOR(dispy)[v] += dy / dlen; VECTOR(dispz)[v] += dz / dlen; VECTOR(dispx)[u] -= dx / dlen; VECTOR(dispy)[u] -= dy / dlen; VECTOR(dispz)[u] -= dz / dlen; } } } else { for (v = 0; v < no_nodes; v++) { for (u = v + 1; u < no_nodes; u++) { float dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); float dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); float dz = MATRIX(*res, v, 2) - MATRIX(*res, u, 2); float dlen, rdlen; dlen = dx * dx + dy * dy + dz * dz; if (dlen == 0) { dx = RNG_UNIF01() * 1e-9; dy = RNG_UNIF01() * 1e-9; dz = RNG_UNIF01() * 1e-9; dlen = dx * dx + dy * dy + dz * dz; } rdlen = sqrt(dlen); VECTOR(dispx)[v] += dx * (C - dlen * rdlen) / (dlen * C); VECTOR(dispy)[v] += dy * (C - dlen * rdlen) / (dlen * C); VECTOR(dispy)[v] += dz * (C - dlen * rdlen) / (dlen * C); VECTOR(dispx)[u] -= dx * (C - dlen * rdlen) / (dlen * C); VECTOR(dispy)[u] -= dy * (C - dlen * rdlen) / (dlen * C); VECTOR(dispz)[u] -= dz * (C - dlen * rdlen) / (dlen * C); } } } /* calculate attractive forces */ for (e = 0; e < no_edges; e++) { /* each edges is an ordered pair of vertices v and u */ igraph_integer_t v = IGRAPH_FROM(graph, e); igraph_integer_t u = IGRAPH_TO(graph, e); igraph_real_t dx = MATRIX(*res, v, 0) - MATRIX(*res, u, 0); igraph_real_t dy = MATRIX(*res, v, 1) - MATRIX(*res, u, 1); igraph_real_t dz = MATRIX(*res, v, 2) - MATRIX(*res, u, 2); igraph_real_t w = weight ? VECTOR(*weight)[e] : 1.0; igraph_real_t dlen = sqrt(dx * dx + dy * dy + dz * dz) * w; VECTOR(dispx)[v] -= (dx * dlen); VECTOR(dispy)[v] -= (dy * dlen); VECTOR(dispz)[v] -= (dz * dlen); VECTOR(dispx)[u] += (dx * dlen); VECTOR(dispy)[u] += (dy * dlen); VECTOR(dispz)[u] += (dz * dlen); } /* limit max displacement to temperature t and prevent from displacement outside frame */ for (v = 0; v < no_nodes; v++) { igraph_real_t dx = VECTOR(dispx)[v] + RNG_UNIF01() * 1e-9; igraph_real_t dy = VECTOR(dispy)[v] + RNG_UNIF01() * 1e-9; igraph_real_t dz = VECTOR(dispz)[v] + RNG_UNIF01() * 1e-9; igraph_real_t displen = sqrt(dx * dx + dy * dy + dz * dz); igraph_real_t mx = fabs(dx) < temp ? dx : temp; igraph_real_t my = fabs(dy) < temp ? dy : temp; igraph_real_t mz = fabs(dz) < temp ? dz : temp; if (displen > 0) { MATRIX(*res, v, 0) += (dx / displen) * mx; MATRIX(*res, v, 1) += (dy / displen) * my; MATRIX(*res, v, 2) += (dz / displen) * mz; } if (minx && MATRIX(*res, v, 0) < VECTOR(*minx)[v]) { MATRIX(*res, v, 0) = VECTOR(*minx)[v]; } if (maxx && MATRIX(*res, v, 0) > VECTOR(*maxx)[v]) { MATRIX(*res, v, 0) = VECTOR(*maxx)[v]; } if (miny && MATRIX(*res, v, 1) < VECTOR(*miny)[v]) { MATRIX(*res, v, 1) = VECTOR(*miny)[v]; } if (maxy && MATRIX(*res, v, 1) > VECTOR(*maxy)[v]) { MATRIX(*res, v, 1) = VECTOR(*maxy)[v]; } if (minz && MATRIX(*res, v, 2) < VECTOR(*minz)[v]) { MATRIX(*res, v, 2) = VECTOR(*minz)[v]; } if (maxz && MATRIX(*res, v, 2) > VECTOR(*maxz)[v]) { MATRIX(*res, v, 2) = VECTOR(*maxz)[v]; } } temp -= difftemp; } RNG_END(); igraph_vector_float_destroy(&dispx); igraph_vector_float_destroy(&dispy); igraph_vector_float_destroy(&dispz); IGRAPH_FINALLY_CLEAN(3); return 0; } leidenbase/src/core/layout/mds.c0000644000176200001440000002726214447675374016366 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_blas.h" #include "igraph_components.h" #include "igraph_eigen.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_operators.h" #include "igraph_paths.h" #include "igraph_random.h" #include "igraph_structural.h" static int igraph_i_layout_mds_step(igraph_real_t *to, const igraph_real_t *from, int n, void *extra); static int igraph_i_layout_mds_single(const igraph_t* graph, igraph_matrix_t *res, igraph_matrix_t *dist, long int dim); static int igraph_i_layout_mds_step(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_matrix_t* matrix = (igraph_matrix_t*)extra; IGRAPH_UNUSED(n); igraph_blas_dgemv_array(0, 1, matrix, from, 0, to); return 0; } /* MDS layout for a connected graph, with no error checking on the * input parameters. The distance matrix will be modified in-place. */ int igraph_i_layout_mds_single(const igraph_t* graph, igraph_matrix_t *res, igraph_matrix_t *dist, long int dim) { long int no_of_nodes = igraph_vcount(graph); long int nev = dim; igraph_matrix_t vectors; igraph_vector_t values, row_means; igraph_real_t grand_mean; long int i, j, k; igraph_eigen_which_t which; /* Handle the trivial cases */ if (no_of_nodes == 1) { IGRAPH_CHECK(igraph_matrix_resize(res, 1, dim)); igraph_matrix_fill(res, 0); return IGRAPH_SUCCESS; } if (no_of_nodes == 2) { IGRAPH_CHECK(igraph_matrix_resize(res, 2, dim)); igraph_matrix_fill(res, 0); for (j = 0; j < dim; j++) { MATRIX(*res, 1, j) = 1; } return IGRAPH_SUCCESS; } /* Initialize some stuff */ IGRAPH_VECTOR_INIT_FINALLY(&values, no_of_nodes); IGRAPH_CHECK(igraph_matrix_init(&vectors, no_of_nodes, dim)); IGRAPH_FINALLY(igraph_matrix_destroy, &vectors); /* Take the square of the distance matrix */ for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < no_of_nodes; j++) { MATRIX(*dist, i, j) *= MATRIX(*dist, i, j); } } /* Double centering of the distance matrix */ IGRAPH_VECTOR_INIT_FINALLY(&row_means, no_of_nodes); igraph_vector_fill(&values, 1.0 / no_of_nodes); igraph_blas_dgemv(0, 1, dist, &values, 0, &row_means); grand_mean = igraph_vector_sum(&row_means) / no_of_nodes; igraph_matrix_add_constant(dist, grand_mean); for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < no_of_nodes; j++) { MATRIX(*dist, i, j) -= VECTOR(row_means)[i] + VECTOR(row_means)[j]; MATRIX(*dist, i, j) *= -0.5; } } igraph_vector_destroy(&row_means); IGRAPH_FINALLY_CLEAN(1); /* Calculate the top `dim` eigenvectors. */ which.pos = IGRAPH_EIGEN_LA; which.howmany = (int) nev; IGRAPH_CHECK(igraph_eigen_matrix_symmetric(/*A=*/ 0, /*sA=*/ 0, /*fun=*/ igraph_i_layout_mds_step, /*n=*/ (int) no_of_nodes, /*extra=*/ dist, /*algorithm=*/ IGRAPH_EIGEN_LAPACK, &which, /*options=*/ 0, /*storage=*/ 0, &values, &vectors)); /* Calculate and normalize the final coordinates */ for (j = 0; j < nev; j++) { VECTOR(values)[j] = sqrt(fabs(VECTOR(values)[j])); } IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, dim)); for (i = 0; i < no_of_nodes; i++) { for (j = 0, k = nev - 1; j < nev; j++, k--) { MATRIX(*res, i, k) = VECTOR(values)[j] * MATRIX(vectors, i, j); } } igraph_matrix_destroy(&vectors); igraph_vector_destroy(&values); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /** * \function igraph_layout_mds * \brief Place the vertices on a plane using multidimensional scaling. * * * This layout requires a distance matrix, where the intersection of * row i and column j specifies the desired distance between vertex i * and vertex j. The algorithm will try to place the vertices in a * space having a given number of dimensions in a way that approximates * the distance relations prescribed in the distance matrix. igraph * uses the classical multidimensional scaling by Torgerson; for more * details, see Cox & Cox: Multidimensional Scaling (1994), Chapman * and Hall, London. * * * If the input graph is disconnected, igraph will decompose it * first into its subgraphs, lay out the subgraphs one by one * using the appropriate submatrices of the distance matrix, and * then merge the layouts using \ref igraph_layout_merge_dla. * Since \ref igraph_layout_merge_dla works for 2D layouts only, * you cannot run the MDS layout on disconnected graphs for * more than two dimensions. * * * Warning: if the graph is symmetric to the exchange of two vertices * (as is the case with leaves of a tree connecting to the same parent), * classical multidimensional scaling may assign the same coordinates to * these vertices. * * \param graph A graph object. * \param res Pointer to an initialized matrix object. This will * contain the result and will be resized if needed. * \param dist The distance matrix. It must be symmetric and this * function does not check whether the matrix is indeed * symmetric. Results are unspecified if you pass a non-symmetric * matrix here. You can set this parameter to null; in this * case, the shortest path lengths between vertices will be * used as distances. * \param dim The number of dimensions in the embedding space. For * 2D layouts, supply 2 here. * \return Error code. * * Added in version 0.6. * * * Time complexity: usually around O(|V|^2 dim). */ int igraph_layout_mds(const igraph_t* graph, igraph_matrix_t *res, const igraph_matrix_t *dist, long int dim) { long int i, no_of_nodes = igraph_vcount(graph); igraph_matrix_t m; igraph_bool_t conn; RNG_BEGIN(); /* Check the distance matrix */ if (dist && (igraph_matrix_nrow(dist) != no_of_nodes || igraph_matrix_ncol(dist) != no_of_nodes)) { IGRAPH_ERROR("invalid distance matrix size", IGRAPH_EINVAL); } /* Check the number of dimensions */ if (dim <= 1) { IGRAPH_ERROR("dim must be positive", IGRAPH_EINVAL); } if (dim > no_of_nodes) { IGRAPH_ERROR("dim must be less than the number of nodes", IGRAPH_EINVAL); } /* Copy or obtain the distance matrix */ if (dist == 0) { IGRAPH_CHECK(igraph_matrix_init(&m, no_of_nodes, no_of_nodes)); IGRAPH_FINALLY(igraph_matrix_destroy, &m); IGRAPH_CHECK(igraph_shortest_paths(graph, &m, igraph_vss_all(), igraph_vss_all(), IGRAPH_ALL)); } else { IGRAPH_CHECK(igraph_matrix_copy(&m, dist)); IGRAPH_FINALLY(igraph_matrix_destroy, &m); /* Make sure that the diagonal contains zeroes only */ for (i = 0; i < no_of_nodes; i++) { MATRIX(m, i, i) = 0.0; } } /* Check whether the graph is connected */ IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK)); if (conn) { /* Yes, it is, just do the MDS */ IGRAPH_CHECK(igraph_i_layout_mds_single(graph, res, &m, dim)); } else { /* The graph is not connected, lay out the components one by one */ igraph_vector_ptr_t layouts; igraph_vector_t comp, vertex_order; igraph_t subgraph; igraph_matrix_t *layout; igraph_matrix_t dist_submatrix; igraph_bool_t *seen_vertices; long int j, n, processed_vertex_count = 0; IGRAPH_VECTOR_INIT_FINALLY(&comp, 0); IGRAPH_VECTOR_INIT_FINALLY(&vertex_order, no_of_nodes); IGRAPH_CHECK(igraph_vector_ptr_init(&layouts, 0)); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &layouts); igraph_vector_ptr_set_item_destructor(&layouts, (igraph_finally_func_t*)igraph_matrix_destroy); IGRAPH_CHECK(igraph_matrix_init(&dist_submatrix, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, &dist_submatrix); seen_vertices = IGRAPH_CALLOC(no_of_nodes, igraph_bool_t); if (seen_vertices == 0) { IGRAPH_ERROR("cannot calculate MDS layout", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, seen_vertices); for (i = 0; i < no_of_nodes; i++) { if (seen_vertices[i]) { continue; } /* This is a vertex whose component we did not lay out so far */ IGRAPH_CHECK(igraph_subcomponent(graph, &comp, i, IGRAPH_ALL)); /* Take the subgraph */ IGRAPH_CHECK(igraph_induced_subgraph(graph, &subgraph, igraph_vss_vector(&comp), IGRAPH_SUBGRAPH_AUTO)); IGRAPH_FINALLY(igraph_destroy, &subgraph); /* Calculate the submatrix of the distances */ IGRAPH_CHECK(igraph_matrix_select_rows_cols(&m, &dist_submatrix, &comp, &comp)); /* Allocate a new matrix for storing the layout */ layout = IGRAPH_CALLOC(1, igraph_matrix_t); if (layout == 0) { IGRAPH_ERROR("cannot calculate MDS layout", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, layout); IGRAPH_CHECK(igraph_matrix_init(layout, 0, 0)); IGRAPH_FINALLY(igraph_matrix_destroy, layout); /* Lay out the subgraph */ IGRAPH_CHECK(igraph_i_layout_mds_single(&subgraph, layout, &dist_submatrix, dim)); /* Store the layout */ IGRAPH_CHECK(igraph_vector_ptr_push_back(&layouts, layout)); IGRAPH_FINALLY_CLEAN(2); /* ownership of layout taken by layouts */ /* Free the newly created subgraph */ igraph_destroy(&subgraph); IGRAPH_FINALLY_CLEAN(1); /* Mark all the vertices in the component as visited */ n = igraph_vector_size(&comp); for (j = 0; j < n; j++) { seen_vertices[(long int)VECTOR(comp)[j]] = 1; VECTOR(vertex_order)[(long int)VECTOR(comp)[j]] = processed_vertex_count++; } } /* Merge the layouts - reusing dist_submatrix here */ IGRAPH_CHECK(igraph_layout_merge_dla(0, &layouts, &dist_submatrix)); /* Reordering the rows of res to match the original graph */ IGRAPH_CHECK(igraph_matrix_select_rows(&dist_submatrix, res, &vertex_order)); igraph_free(seen_vertices); igraph_matrix_destroy(&dist_submatrix); igraph_vector_ptr_destroy_all(&layouts); igraph_vector_destroy(&vertex_order); igraph_vector_destroy(&comp); IGRAPH_FINALLY_CLEAN(5); } RNG_END(); igraph_matrix_destroy(&m); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/layout/graphopt.c0000644000176200001440000004162614447675374017427 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_layout.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "core/interruption.h" #define COULOMBS_CONSTANT 8987500000.0 static igraph_real_t igraph_i_distance_between( const igraph_matrix_t *c, long int a, long int b); static int igraph_i_determine_electric_axal_forces( const igraph_matrix_t *pos, igraph_real_t *x, igraph_real_t *y, igraph_real_t directed_force, igraph_real_t distance, long int other_node, long int this_node); static int igraph_i_apply_electrical_force( const igraph_matrix_t *pos, igraph_vector_t *pending_forces_x, igraph_vector_t *pending_forces_y, long int other_node, long int this_node, igraph_real_t node_charge, igraph_real_t distance); static int igraph_i_determine_spring_axal_forces( const igraph_matrix_t *pos, igraph_real_t *x, igraph_real_t *y, igraph_real_t directed_force, igraph_real_t distance, igraph_real_t spring_length, long int other_node, long int this_node); static int igraph_i_apply_spring_force( const igraph_matrix_t *pos, igraph_vector_t *pending_forces_x, igraph_vector_t *pending_forces_y, long int other_node, long int this_node, igraph_real_t spring_length, igraph_real_t spring_constant); static int igraph_i_move_nodes( igraph_matrix_t *pos, const igraph_vector_t *pending_forces_x, const igraph_vector_t *pending_forces_y, igraph_real_t node_mass, igraph_real_t max_sa_movement); static igraph_real_t igraph_i_distance_between( const igraph_matrix_t *c, long int a, long int b) { igraph_real_t diffx = MATRIX(*c, a, 0) - MATRIX(*c, b, 0); igraph_real_t diffy = MATRIX(*c, a, 1) - MATRIX(*c, b, 1); return sqrt( diffx * diffx + diffy * diffy ); } static int igraph_i_determine_electric_axal_forces(const igraph_matrix_t *pos, igraph_real_t *x, igraph_real_t *y, igraph_real_t directed_force, igraph_real_t distance, long int other_node, long int this_node) { // We know what the directed force is. We now need to translate it // into the appropriate x and y components. // First, assume: // other_node // /| // directed_force / | // / | y // /______| // this_node x // // other_node.x > this_node.x // other_node.y > this_node.y // the force will be on this_node away from other_node // the proportion (distance/y_distance) is equal to the proportion // (directed_force/y_force), as the two triangles are similar. // therefore, the magnitude of y_force = (directed_force*y_distance)/distance // the sign of y_force is negative, away from other_node igraph_real_t x_distance, y_distance; y_distance = MATRIX(*pos, other_node, 1) - MATRIX(*pos, this_node, 1); if (y_distance < 0) { y_distance = -y_distance; } *y = -1 * ((directed_force * y_distance) / distance); // the x component works in exactly the same way. x_distance = MATRIX(*pos, other_node, 0) - MATRIX(*pos, this_node, 0); if (x_distance < 0) { x_distance = -x_distance; } *x = -1 * ((directed_force * x_distance) / distance); // Now we need to reverse the polarity of our answers based on the falsness // of our assumptions. if (MATRIX(*pos, other_node, 0) < MATRIX(*pos, this_node, 0)) { *x = *x * -1; } if (MATRIX(*pos, other_node, 1) < MATRIX(*pos, this_node, 1)) { *y = *y * -1; } return 0; } static int igraph_i_apply_electrical_force( const igraph_matrix_t *pos, igraph_vector_t *pending_forces_x, igraph_vector_t *pending_forces_y, long int other_node, long int this_node, igraph_real_t node_charge, igraph_real_t distance) { igraph_real_t directed_force = COULOMBS_CONSTANT * ((node_charge * node_charge) / (distance * distance)); igraph_real_t x_force, y_force; igraph_i_determine_electric_axal_forces(pos, &x_force, &y_force, directed_force, distance, other_node, this_node); VECTOR(*pending_forces_x)[this_node] += x_force; VECTOR(*pending_forces_y)[this_node] += y_force; VECTOR(*pending_forces_x)[other_node] -= x_force; VECTOR(*pending_forces_y)[other_node] -= y_force; return 0; } static int igraph_i_determine_spring_axal_forces( const igraph_matrix_t *pos, igraph_real_t *x, igraph_real_t *y, igraph_real_t directed_force, igraph_real_t distance, igraph_real_t spring_length, long int other_node, long int this_node) { // if the spring is just the right size, the forces will be 0, so we can // skip the computation. // // if the spring is too long, our forces will be identical to those computed // by determine_electrical_axal_forces() (this_node will be pulled toward // other_node). // // if the spring is too short, our forces will be the opposite of those // computed by determine_electrical_axal_forces() (this_node will be pushed // away from other_node) // // finally, since both nodes are movable, only one-half of the total force // should be applied to each node, so half the forces for our answer. if (distance == spring_length) { *x = 0.0; *y = 0.0; } else { igraph_i_determine_electric_axal_forces(pos, x, y, directed_force, distance, other_node, this_node); if (distance < spring_length) { *x = -1 * *x; *y = -1 * *y; } *x = 0.5 * *x; *y = 0.5 * *y; } return 0; } static int igraph_i_apply_spring_force( const igraph_matrix_t *pos, igraph_vector_t *pending_forces_x, igraph_vector_t *pending_forces_y, long int other_node, long int this_node, igraph_real_t spring_length, igraph_real_t spring_constant) { // determined using Hooke's Law: // force = -kx // where: // k = spring constant // x = displacement from ideal length in meters igraph_real_t distance, displacement, directed_force, x_force, y_force; distance = igraph_i_distance_between(pos, other_node, this_node); // let's protect ourselves from division by zero by ignoring two nodes that // happen to be in the same place. Since we separate all nodes before we // work on any of them, this will only happen in extremely rare circumstances, // and when it does, electrical force will probably push one or both of them // one way or another anyway. if (distance == 0.0) { return 0; } displacement = distance - spring_length; if (displacement < 0) { displacement = -displacement; } directed_force = -1 * spring_constant * displacement; // remember, this is force directed away from the spring; // a negative number is back towards the spring (or, in our case, back towards // the other node) // get the force that should be applied to >this< node igraph_i_determine_spring_axal_forces(pos, &x_force, &y_force, directed_force, distance, spring_length, other_node, this_node); VECTOR(*pending_forces_x)[this_node] += x_force; VECTOR(*pending_forces_y)[this_node] += y_force; VECTOR(*pending_forces_x)[other_node] -= x_force; VECTOR(*pending_forces_y)[other_node] -= y_force; return 0; } static int igraph_i_move_nodes( igraph_matrix_t *pos, const igraph_vector_t *pending_forces_x, const igraph_vector_t *pending_forces_y, igraph_real_t node_mass, igraph_real_t max_sa_movement) { // Since each iteration is isolated, time is constant at 1. // Therefore: // Force effects acceleration. // acceleration (d(velocity)/time) = velocity // velocity (d(displacement)/time) = displacement // displacement = acceleration // determined using Newton's second law: // sum(F) = ma // therefore: // acceleration = force / mass // velocity = force / mass // displacement = force / mass long int this_node, no_of_nodes = igraph_vector_size(pending_forces_x); for (this_node = 0; this_node < no_of_nodes; this_node++) { igraph_real_t x_movement, y_movement; x_movement = VECTOR(*pending_forces_x)[this_node] / node_mass; if (x_movement > max_sa_movement) { x_movement = max_sa_movement; } else if (x_movement < -max_sa_movement) { x_movement = -max_sa_movement; } y_movement = VECTOR(*pending_forces_y)[this_node] / node_mass; if (y_movement > max_sa_movement) { y_movement = max_sa_movement; } else if (y_movement < -max_sa_movement) { y_movement = -max_sa_movement; } MATRIX(*pos, this_node, 0) += x_movement; MATRIX(*pos, this_node, 1) += y_movement; } return 0; } /** * \function igraph_layout_graphopt * \brief Optimizes vertex layout via the graphopt algorithm. * * * This is a port of the graphopt layout algorithm by Michael Schmuhl. * graphopt version 0.4.1 was rewritten in C and the support for * layers was removed (might be added later) and a code was a bit * reorganized to avoid some unnecessary steps is the node charge (see below) * is zero. * * * Graphopt uses physical analogies for defining attracting and repelling * forces among the vertices and then the physical system is simulated * until it reaches an equilibrium. (There is no simulated annealing or * anything like that, so a stable fixed point is not guaranteed.) * * * See also http://www.schmuhl.org/graphopt/ for the original graphopt. * \param graph The input graph. * \param res Pointer to an initialized matrix, the result will be stored here * and its initial contents are used as the starting point of the simulation * if the \p use_seed argument is true. Note that in this case the * matrix should have the proper size, otherwise a warning is issued and * the supplied values are ignored. If no starting positions are given * (or they are invalid) then a random starting position is used. * The matrix will be resized if needed. * \param niter Integer constant, the number of iterations to perform. * Should be a couple of hundred in general. If you have a large graph * then you might want to only do a few iterations and then check the * result. If it is not good enough you can feed it in again in * the \p res argument. The original graphopt default is 500. * \param node_charge The charge of the vertices, used to calculate electric * repulsion. The original graphopt default is 0.001. * \param node_mass The mass of the vertices, used for the spring forces. * The original graphopt defaults to 30. * \param spring_length The length of the springs. * The original graphopt defaults to zero. * \param spring_constant The spring constant, the original graphopt defaults * to one. * \param max_sa_movement Real constant, it gives the maximum amount of movement * allowed in a single step along a single axis. The original graphopt * default is 5. * \param use_seed Logical scalar, whether to use the positions in \p res as * a starting configuration. See also \p res above. * \return Error code. * * Time complexity: O(n (|V|^2+|E|) ), n is the number of iterations, * |V| is the number of vertices, |E| the number * of edges. If \p node_charge is zero then it is only O(n|E|). */ int igraph_layout_graphopt(const igraph_t *graph, igraph_matrix_t *res, igraph_integer_t niter, igraph_real_t node_charge, igraph_real_t node_mass, igraph_real_t spring_length, igraph_real_t spring_constant, igraph_real_t max_sa_movement, igraph_bool_t use_seed) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vector_t pending_forces_x, pending_forces_y; /* Set a flag to calculate (or not) the electrical forces that the nodes */ /* apply on each other based on if both node types' charges are zero. */ igraph_bool_t apply_electric_charges = (node_charge != 0); long int this_node, other_node, edge; igraph_real_t distance; long int i; IGRAPH_VECTOR_INIT_FINALLY(&pending_forces_x, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&pending_forces_y, no_of_nodes); if (use_seed) { if (igraph_matrix_nrow(res) != no_of_nodes || igraph_matrix_ncol(res) != 2) { IGRAPH_WARNING("Invalid size for initial matrix, starting from random layout."); IGRAPH_CHECK(igraph_layout_random(graph, res)); } } else { IGRAPH_CHECK(igraph_layout_random(graph, res)); } IGRAPH_PROGRESS("Graphopt layout", 0, NULL); for (i = niter; i > 0; i--) { /* Report progress in approx. every 100th step */ if (i % 10 == 0) { IGRAPH_PROGRESS("Graphopt layout", 100.0 - 100.0 * i / niter, NULL); } /* Clear pending forces on all nodes */ igraph_vector_null(&pending_forces_x); igraph_vector_null(&pending_forces_y); // Apply electrical force applied by all other nodes if (apply_electric_charges) { // Iterate through all nodes for (this_node = 0; this_node < no_of_nodes; this_node++) { IGRAPH_ALLOW_INTERRUPTION(); for (other_node = this_node + 1; other_node < no_of_nodes; other_node++) { distance = igraph_i_distance_between(res, this_node, other_node); // let's protect ourselves from division by zero by ignoring // two nodes that happen to be in the same place. Since we // separate all nodes before we work on any of them, this // will only happen in extremely rare circumstances, and when // it does, springs will probably pull them apart anyway. // also, if we are more than 50 away, the electric force // will be negligible. // ***** may not always be desirable **** if ((distance != 0.0) && (distance < 500.0)) { // if (distance != 0.0) { // Apply electrical force from node(counter2) on // node(counter) igraph_i_apply_electrical_force(res, &pending_forces_x, &pending_forces_y, other_node, this_node, node_charge, distance); } } } } // Apply force from springs for (edge = 0; edge < no_of_edges; edge++) { long int tthis_node = IGRAPH_FROM(graph, edge); long int oother_node = IGRAPH_TO(graph, edge); // Apply spring force on both nodes igraph_i_apply_spring_force(res, &pending_forces_x, &pending_forces_y, oother_node, tthis_node, spring_length, spring_constant); } // Effect the movement of the nodes based on all pending forces igraph_i_move_nodes(res, &pending_forces_x, &pending_forces_y, node_mass, max_sa_movement); } IGRAPH_PROGRESS("Graphopt layout", 100, NULL); igraph_vector_destroy(&pending_forces_y); igraph_vector_destroy(&pending_forces_x); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } leidenbase/src/core/layout/layout_internal.h0000644000176200001440000000463014447675374021013 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_LAYOUT_INTERNAL_H #define IGRAPH_LAYOUT_INTERNAL_H #include "igraph_types.h" #include "layout/merge_grid.h" __BEGIN_DECLS IGRAPH_PRIVATE_EXPORT int igraph_i_layout_merge_dla(igraph_i_layout_mergegrid_t *grid, long int actg, igraph_real_t *x, igraph_real_t *y, igraph_real_t r, igraph_real_t cx, igraph_real_t cy, igraph_real_t startr, igraph_real_t killr); IGRAPH_PRIVATE_EXPORT int igraph_i_layout_sphere_2d(igraph_matrix_t *coords, igraph_real_t *x, igraph_real_t *y, igraph_real_t *r); IGRAPH_PRIVATE_EXPORT int igraph_i_layout_sphere_3d(igraph_matrix_t *coords, igraph_real_t *x, igraph_real_t *y, igraph_real_t *z, igraph_real_t *r); IGRAPH_PRIVATE_EXPORT float igraph_i_layout_point_segment_dist2(float v_x, float v_y, float u1_x, float u1_y, float u2_x, float u2_y); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_i_layout_segments_intersect(float p0_x, float p0_y, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y); __END_DECLS #endif leidenbase/src/core/f2c.h0000644000176200001440000001227414447675374014742 0ustar liggesusers/* f2c.h -- Standard Fortran to C header file */ /** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ #ifndef F2C_INCLUDE #define F2C_INCLUDE #include "linalg/blas_internal.h" #include "linalg/lapack_internal.h" #include "linalg/arpack_internal.h" typedef int integer; typedef unsigned int uinteger; typedef char *address; typedef short int shortint; typedef float real; typedef double doublereal; typedef struct { real r, i; } f2c_complex; typedef struct { doublereal r, i; } doublecomplex; typedef int logical; typedef short int shortlogical; typedef char logical1; typedef char integer1; #ifdef INTEGER_STAR_8 /* Adjust for integer*8. */ typedef long longint; /* system-dependent */ typedef unsigned long ulongint; /* system-dependent */ #define qbit_clear(a,b) ((a) & ~((ulongint)1 << (b))) #define qbit_set(a,b) ((a) | ((ulongint)1 << (b))) #endif #define TRUE_ (1) #define FALSE_ (0) /* Extern is for use with -E */ #ifndef Extern #define Extern extern #endif /* I/O stuff */ #ifdef f2c_i2 /* for -i2 */ typedef short flag; typedef short ftnlen; typedef short ftnint; #else typedef int flag; typedef int ftnlen; typedef int ftnint; #endif /*external read, write*/ typedef struct { flag cierr; ftnint ciunit; flag ciend; char *cifmt; ftnint cirec; } cilist; /*internal read, write*/ typedef struct { flag icierr; char *iciunit; flag iciend; char *icifmt; ftnint icirlen; ftnint icirnum; } icilist; /*open*/ typedef struct { flag oerr; ftnint ounit; char *ofnm; ftnlen ofnmlen; char *osta; char *oacc; char *ofm; ftnint orl; char *oblnk; } olist; /*close*/ typedef struct { flag cerr; ftnint cunit; char *csta; } cllist; /*rewind, backspace, endfile*/ typedef struct { flag aerr; ftnint aunit; } alist; /* inquire */ typedef struct { flag inerr; ftnint inunit; char *infile; ftnlen infilen; ftnint *inex; /*parameters in standard's order*/ ftnint *inopen; ftnint *innum; ftnint *innamed; char *inname; ftnlen innamlen; char *inacc; ftnlen inacclen; char *inseq; ftnlen inseqlen; char *indir; ftnlen indirlen; char *infmt; ftnlen infmtlen; char *inform; ftnint informlen; char *inunf; ftnlen inunflen; ftnint *inrecl; ftnint *innrec; char *inblank; ftnlen inblanklen; } inlist; #define VOID void union Multitype { /* for multiple entry points */ integer1 g; shortint h; integer i; /* longint j; */ real r; doublereal d; f2c_complex c; doublecomplex z; }; typedef union Multitype Multitype; /*typedef long int Long;*/ /* No longer used; formerly in Namelist */ struct Vardesc { /* for Namelist */ char *name; char *addr; ftnlen *dims; int type; }; typedef struct Vardesc Vardesc; struct Namelist { char *name; Vardesc **vars; int nvars; }; typedef struct Namelist Namelist; #define abs(x) ((x) >= 0 ? (x) : -(x)) #define dabs(x) (doublereal)abs(x) #ifndef min #define min(a,b) ((a) <= (b) ? (a) : (b)) #endif #ifndef max #define max(a,b) ((a) >= (b) ? (a) : (b)) #endif #define dmin(a,b) (doublereal)min(a,b) #define dmax(a,b) (doublereal)max(a,b) #define bit_test(a,b) ((a) >> (b) & 1) #define bit_clear(a,b) ((a) & ~((uinteger)1 << (b))) #define bit_set(a,b) ((a) | ((uinteger)1 << (b))) /* procedure parameter types for -A and -C++ */ #define F2C_proc_par_types 1 #ifdef __cplusplus typedef int /* Unknown procedure type */ (*U_fp)(...); typedef shortint (*J_fp)(...); typedef integer (*I_fp)(...); typedef real (*R_fp)(...); typedef doublereal (*D_fp)(...), (*E_fp)(...); typedef /* Complex */ VOID (*C_fp)(...); typedef /* Double Complex */ VOID (*Z_fp)(...); typedef logical (*L_fp)(...); typedef shortlogical (*K_fp)(...); typedef /* Character */ VOID (*H_fp)(...); typedef /* Subroutine */ int (*S_fp)(...); #else typedef int /* Unknown procedure type */ (*U_fp)(); typedef shortint (*J_fp)(); typedef integer (*I_fp)(); typedef real (*R_fp)(); typedef doublereal (*D_fp)(), (*E_fp)(); typedef /* Complex */ VOID (*C_fp)(); typedef /* Double Complex */ VOID (*Z_fp)(); typedef logical (*L_fp)(); typedef shortlogical (*K_fp)(); typedef /* Character */ VOID (*H_fp)(); typedef /* Subroutine */ int (*S_fp)(); #endif /* E_fp is for real functions when -R is not specified */ typedef VOID C_f; /* complex function */ typedef VOID H_f; /* character function */ typedef VOID Z_f; /* double complex function */ typedef doublereal E_f; /* real function with -R not specified */ /* undef any lower-case symbols that your C compiler predefines, e.g.: */ #ifndef Skip_f2c_Undefs #undef cray #undef gcos #undef mc68010 #undef mc68020 #undef mips #undef pdp11 #undef sgi #undef sparc #undef sun #undef sun2 #undef sun3 #undef sun4 #undef u370 #undef u3b #undef u3b2 #undef u3b5 #undef unix #undef vax #endif #include "config.h" #endif leidenbase/src/core/paths/0000755000176200001440000000000014532173045015207 5ustar liggesusersleidenbase/src/core/paths/simple_paths.c0000644000176200001440000001420414447675375020066 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2014 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_paths.h" #include "igraph_interface.h" #include "igraph_vector_ptr.h" #include "igraph_iterators.h" #include "igraph_adjlist.h" #include "igraph_stack.h" #include "core/interruption.h" /** * \function igraph_get_all_simple_paths * \brief List all simple paths from one source. * * A path is simple if its vertices are unique, i.e. no vertex * is visited more than once. * * * Note that potentially there are exponentially many * paths between two vertices of a graph, and you may * run out of memory when using this function, if your * graph is lattice-like. * * * This function currently ignored multiple and loop edges. * \param graph The input graph. * \param res Initialized integer vector, all paths are * returned here, separated by -1 markers. The paths * are included in arbitrary order, as they are found. * \param from The start vertex. * \param to The target vertices. * \param cutoff Maximum length of path that is considered. If * negative, paths of all lengths are considered. * \param mode The type of the paths to consider, it is ignored * for undirected graphs. * \return Error code. * * Time complexity: O(n!) in the worst case, n is the number of * vertices. */ int igraph_get_all_simple_paths(const igraph_t *graph, igraph_vector_int_t *res, igraph_integer_t from, const igraph_vs_t to, igraph_integer_t cutoff, igraph_neimode_t mode) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_vit_t vit; igraph_bool_t toall = igraph_vs_is_all(&to); igraph_vector_char_t markto; igraph_lazy_adjlist_t adjlist; igraph_vector_int_t stack, dist; igraph_vector_char_t added; igraph_vector_int_t nptr; int iteration = 0; if (from < 0 || from >= no_nodes) { IGRAPH_ERROR("Invalid starting vertex", IGRAPH_EINVAL); } if (!toall) { igraph_vector_char_init(&markto, no_nodes); IGRAPH_FINALLY(igraph_vector_char_destroy, &markto); IGRAPH_CHECK(igraph_vit_create(graph, to, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); for (; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { VECTOR(markto)[ IGRAPH_VIT_GET(vit) ] = 1; } igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_CHECK(igraph_vector_char_init(&added, no_nodes)); IGRAPH_FINALLY(igraph_vector_char_destroy, &added); IGRAPH_CHECK(igraph_vector_int_init(&stack, 100)); IGRAPH_FINALLY(igraph_vector_int_destroy, &stack); IGRAPH_CHECK(igraph_vector_int_init(&dist, 100)); IGRAPH_FINALLY(igraph_vector_int_destroy, &dist); IGRAPH_CHECK(igraph_lazy_adjlist_init( graph, &adjlist, mode, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE )); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_vector_int_init(&nptr, no_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &nptr); igraph_vector_int_clear(res); igraph_vector_int_clear(&stack); igraph_vector_int_clear(&dist); igraph_vector_int_push_back(&stack, from); igraph_vector_int_push_back(&dist, 0); VECTOR(added)[from] = 1; while (!igraph_vector_int_empty(&stack)) { int act = igraph_vector_int_tail(&stack); int curdist = igraph_vector_int_tail(&dist); igraph_vector_int_t *neis = igraph_lazy_adjlist_get(&adjlist, act); int n = igraph_vector_int_size(neis); int *ptr = igraph_vector_int_e_ptr(&nptr, act); igraph_bool_t any; igraph_bool_t within_dist; int nei; if (iteration == 0) { IGRAPH_ALLOW_INTERRUPTION(); } within_dist = (curdist < cutoff || cutoff < 0); if (within_dist) { /* Search for a neighbor that was not yet visited */ any = 0; while (!any && (*ptr) < n) { nei = (int) VECTOR(*neis)[(*ptr)]; any = !VECTOR(added)[nei]; (*ptr) ++; } } if (within_dist && any) { /* There is such a neighbor, add it */ IGRAPH_CHECK(igraph_vector_int_push_back(&stack, nei)); IGRAPH_CHECK(igraph_vector_int_push_back(&dist, curdist + 1)); VECTOR(added)[nei] = 1; /* Add to results */ if (toall || VECTOR(markto)[nei]) { IGRAPH_CHECK(igraph_vector_int_append(res, &stack)); IGRAPH_CHECK(igraph_vector_int_push_back(res, -1)); } } else { /* There is no such neighbor, finished with the subtree */ int up = igraph_vector_int_pop_back(&stack); igraph_vector_int_pop_back(&dist); VECTOR(added)[up] = 0; VECTOR(nptr)[up] = 0; } iteration++; if (iteration >= 10000) { iteration = 0; } } igraph_vector_int_destroy(&nptr); igraph_lazy_adjlist_destroy(&adjlist); igraph_vector_int_destroy(&dist); igraph_vector_int_destroy(&stack); igraph_vector_char_destroy(&added); IGRAPH_FINALLY_CLEAN(5); if (!toall) { igraph_vector_char_destroy(&markto); IGRAPH_FINALLY_CLEAN(1); } return 0; } leidenbase/src/core/paths/dijkstra.c0000644000176200001440000012522414447675375017216 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_paths.h" #include "igraph_adjlist.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_stack.h" #include "core/indheap.h" #include "core/interruption.h" #include "core/math.h" #include /* memset */ /** * \function igraph_shortest_paths_dijkstra * \brief Weighted shortest path lengths between vertices. * * This function implements Dijkstra's algorithm to find the weighted * shortest path lengths to all vertices from a single source. It is run * independently for the given sources. It uses a binary heap for * efficient implementation. * * \param graph The input graph, can be directed. * \param res The result, a matrix. A pointer to an initialized matrix * should be passed here. The matrix will be resized as needed. * Each row contains the distances from a single source, to the * vertices given in the \c to argument. * Unreachable vertices has distance * \c IGRAPH_INFINITY. * \param from The source vertices. * \param to The target vertices. It is not allowed to include a * vertex twice or more. * \param weights The edge weights. All edge weights must be * non-negative for Dijkstra's algorithm to work. Additionally, no * edge weight may be NaN. If either case does not hold, an error * is returned. If this is a null pointer, then the unweighted * version, \ref igraph_shortest_paths() is called. * \param mode For directed graphs; whether to follow paths along edge * directions (\c IGRAPH_OUT), or the opposite (\c IGRAPH_IN), or * ignore edge directions completely (\c IGRAPH_ALL). It is ignored * for undirected graphs. * \return Error code. * * Time complexity: O(s*|E|log|E|+|V|), where |V| is the number of * vertices, |E| the number of edges and s the number of sources. * * \sa \ref igraph_shortest_paths() for a (slightly) faster unweighted * version or \ref igraph_shortest_paths_bellman_ford() for a weighted * variant that works in the presence of negative edge weights (but no * negative loops). * * \example examples/simple/dijkstra.c */ int igraph_shortest_paths_dijkstra(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode) { /* Implementation details. This is the basic Dijkstra algorithm, with a binary heap. The heap is indexed, i.e. it stores not only the distances, but also which vertex they belong to. From now on we use a 2-way heap, so the distances can be queried directly from the heap. Dirty tricks: - the opposite of the distance is stored in the heap, as it is a maximum heap and we need a minimum heap. - we don't use IGRAPH_INFINITY in the res matrix during the computation, as IGRAPH_FINITE() might involve a function call and we want to spare that. -1 will denote infinity instead. */ long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_2wheap_t Q; igraph_vit_t fromvit, tovit; long int no_of_from, no_of_to; igraph_lazy_inclist_t inclist; long int i, j; igraph_real_t my_infinity = IGRAPH_INFINITY; igraph_bool_t all_to; igraph_vector_t indexv; if (!weights) { return igraph_shortest_paths(graph, res, from, to, mode); } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length does not match", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t min = igraph_vector_min(weights); if (min < 0) { IGRAPH_ERROR("Weight vector must be non-negative", IGRAPH_EINVAL); } else if (igraph_is_nan(min)) { IGRAPH_ERROR("Weight vector must not contain NaN values", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_vit_create(graph, from, &fromvit)); IGRAPH_FINALLY(igraph_vit_destroy, &fromvit); no_of_from = IGRAPH_VIT_SIZE(fromvit); IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &inclist, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); all_to = igraph_vs_is_all(&to); if (all_to) { no_of_to = no_of_nodes; } else { IGRAPH_VECTOR_INIT_FINALLY(&indexv, no_of_nodes); IGRAPH_CHECK(igraph_vit_create(graph, to, &tovit)); IGRAPH_FINALLY(igraph_vit_destroy, &tovit); no_of_to = IGRAPH_VIT_SIZE(tovit); for (i = 0; !IGRAPH_VIT_END(tovit); IGRAPH_VIT_NEXT(tovit)) { long int v = IGRAPH_VIT_GET(tovit); if (VECTOR(indexv)[v]) { IGRAPH_ERROR("Duplicate vertices in `to', this is not allowed", IGRAPH_EINVAL); } VECTOR(indexv)[v] = ++i; } } IGRAPH_CHECK(igraph_matrix_resize(res, no_of_from, no_of_to)); igraph_matrix_fill(res, my_infinity); for (IGRAPH_VIT_RESET(fromvit), i = 0; !IGRAPH_VIT_END(fromvit); IGRAPH_VIT_NEXT(fromvit), i++) { long int reached = 0; long int source = IGRAPH_VIT_GET(fromvit); igraph_2wheap_clear(&Q); igraph_2wheap_push_with_index(&Q, source, -1.0); while (!igraph_2wheap_empty(&Q)) { long int minnei = igraph_2wheap_max_index(&Q); igraph_real_t mindist = -igraph_2wheap_deactivate_max(&Q); igraph_vector_int_t *neis; long int nlen; if (all_to) { MATRIX(*res, i, minnei) = mindist - 1.0; } else { if (VECTOR(indexv)[minnei]) { MATRIX(*res, i, (long int)(VECTOR(indexv)[minnei] - 1)) = mindist - 1.0; reached++; if (reached == no_of_to) { igraph_2wheap_clear(&Q); break; } } } /* Now check all neighbors of 'minnei' for a shorter path */ neis = igraph_lazy_inclist_get(&inclist, (igraph_integer_t) minnei); nlen = igraph_vector_int_size(neis); for (j = 0; j < nlen; j++) { long int edge = (long int) VECTOR(*neis)[j]; long int tto = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_bool_t active = igraph_2wheap_has_active(&Q, tto); igraph_bool_t has = igraph_2wheap_has_elem(&Q, tto); igraph_real_t curdist = active ? -igraph_2wheap_get(&Q, tto) : 0.0; if (!has) { /* This is the first non-infinite distance */ IGRAPH_CHECK(igraph_2wheap_push_with_index(&Q, tto, -altdist)); } else if (altdist < curdist) { /* This is a shorter path */ IGRAPH_CHECK(igraph_2wheap_modify(&Q, tto, -altdist)); } } } /* !igraph_2wheap_empty(&Q) */ } /* !IGRAPH_VIT_END(fromvit) */ if (!all_to) { igraph_vit_destroy(&tovit); igraph_vector_destroy(&indexv); IGRAPH_FINALLY_CLEAN(2); } igraph_lazy_inclist_destroy(&inclist); igraph_2wheap_destroy(&Q); igraph_vit_destroy(&fromvit); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \ingroup structural * \function igraph_get_shortest_paths_dijkstra * \brief Weighted shortest paths from a vertex. * * * If there is more than one path with the smallest weight between two vertices, this * function gives only one of them. * \param graph The graph object. * \param vertices The result, the ids of the vertices along the paths. * This is a pointer vector, each element points to a vector * object. These should be initialized before passing them to * the function, which will properly clear and/or resize them * and fill the ids of the vertices along the geodesics from/to * the vertices. Supply a null pointer here if you don't need * these vectors. Normally, either this argument, or the \c * edges should be non-null, but no error or warning is given * if they are both null pointers. * \param edges The result, the ids of the edges along the paths. * This is a pointer vector, each element points to a vector * object. These should be initialized before passing them to * the function, which will properly clear and/or resize them * and fill the ids of the vertices along the geodesics from/to * the vertices. Supply a null pointer here if you don't need * these vectors. Normally, either this argument, or the \c * vertices should be non-null, but no error or warning is given * if they are both null pointers. * \param from The id of the vertex from/to which the geodesics are * calculated. * \param to Vertex sequence with the ids of the vertices to/from which the * shortest paths will be calculated. A vertex might be given multiple * times. * \param weights The edge weights. All edge weights must be * non-negative for Dijkstra's algorithm to work. Additionally, no * edge weight may be NaN. If either case does not hold, an error * is returned. If this is a null pointer, then the unweighted * version, \ref igraph_get_shortest_paths() is called. * \param mode The type of shortest paths to be use for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing paths are calculated. * \cli IGRAPH_IN * the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an * undirected one for the computation. * \endclist * \param predecessors A pointer to an initialized igraph vector or null. * If not null, a vector containing the predecessor of each vertex in * the single source shortest path tree is returned here. The * predecessor of vertex i in the tree is the vertex from which vertex i * was reached. The predecessor of the start vertex (in the \c from * argument) is itself by definition. If the predecessor is -1, it means * that the given vertex was not reached from the source during the * search. Note that the search terminates if all the vertices in * \c to are reached. * \param inbound_edges A pointer to an initialized igraph vector or null. * If not null, a vector containing the inbound edge of each vertex in * the single source shortest path tree is returned here. The * inbound edge of vertex i in the tree is the edge via which vertex i * was reached. The start vertex and vertices that were not reached * during the search will have -1 in the corresponding entry of the * vector. Note that the search terminates if all the vertices in * \c to are reached. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * \p from is invalid vertex id, or the length of \p to is * not the same as the length of \p res. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(|E|log|E|+|V|), where |V| is the number of * vertices and |E| is the number of edges * * \sa \ref igraph_shortest_paths_dijkstra() if you only need the path length but * not the paths themselves, \ref igraph_get_shortest_paths() if all edge * weights are equal. * * \example examples/simple/igraph_get_shortest_paths_dijkstra.c */ int igraph_get_shortest_paths_dijkstra(const igraph_t *graph, igraph_vector_ptr_t *vertices, igraph_vector_ptr_t *edges, igraph_integer_t from, igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode, igraph_vector_long_t *predecessors, igraph_vector_long_t *inbound_edges) { /* Implementation details. This is the basic Dijkstra algorithm, with a binary heap. The heap is indexed, i.e. it stores not only the distances, but also which vertex they belong to. The other mapping, i.e. getting the distance for a vertex is not in the heap (that would by the double-indexed heap), but in the result matrix. Dirty tricks: - the opposite of the distance is stored in the heap, as it is a maximum heap and we need a minimum heap. - we don't use IGRAPH_INFINITY in the distance vector during the computation, as IGRAPH_FINITE() might involve a function call and we want to spare that. So we store distance+1.0 instead of distance, and zero denotes infinity. - `parents' assigns the inbound edge IDs of all vertices in the shortest path tree to the vertices. In this implementation, the edge ID + 1 is stored, zero means unreachable vertices. */ long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vit_t vit; igraph_2wheap_t Q; igraph_lazy_inclist_t inclist; igraph_vector_t dists; long int *parents; igraph_bool_t *is_target; long int i, to_reach; if (!weights) { return igraph_get_shortest_paths(graph, vertices, edges, from, to, mode, predecessors, inbound_edges); } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length does not match", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t min = igraph_vector_min(weights); if (min < 0) { IGRAPH_ERROR("Weight vector must be non-negative", IGRAPH_EINVAL); } else if (igraph_is_nan(min)) { IGRAPH_ERROR("Weight vector must not contain NaN values", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_vit_create(graph, to, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); if (vertices && IGRAPH_VIT_SIZE(vit) != igraph_vector_ptr_size(vertices)) { IGRAPH_ERROR("Size of `vertices' and `to' should match", IGRAPH_EINVAL); } if (edges && IGRAPH_VIT_SIZE(vit) != igraph_vector_ptr_size(edges)) { IGRAPH_ERROR("Size of `edges' and `to' should match", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &inclist, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); IGRAPH_VECTOR_INIT_FINALLY(&dists, no_of_nodes); igraph_vector_fill(&dists, -1.0); parents = IGRAPH_CALLOC(no_of_nodes, long int); if (parents == 0) { IGRAPH_ERROR("Can't calculate shortest paths", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, parents); is_target = IGRAPH_CALLOC(no_of_nodes, igraph_bool_t); if (is_target == 0) { IGRAPH_ERROR("Can't calculate shortest paths", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, is_target); /* Mark the vertices we need to reach */ to_reach = IGRAPH_VIT_SIZE(vit); for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { if (!is_target[ (long int) IGRAPH_VIT_GET(vit) ]) { is_target[ (long int) IGRAPH_VIT_GET(vit) ] = 1; } else { to_reach--; /* this node was given multiple times */ } } VECTOR(dists)[(long int)from] = 0.0; /* zero distance */ parents[(long int)from] = 0; igraph_2wheap_push_with_index(&Q, from, 0); while (!igraph_2wheap_empty(&Q) && to_reach > 0) { long int nlen, minnei = igraph_2wheap_max_index(&Q); igraph_real_t mindist = -igraph_2wheap_delete_max(&Q); igraph_vector_int_t *neis; IGRAPH_ALLOW_INTERRUPTION(); if (is_target[minnei]) { is_target[minnei] = 0; to_reach--; } /* Now check all neighbors of 'minnei' for a shorter path */ neis = igraph_lazy_inclist_get(&inclist, (igraph_integer_t) minnei); nlen = igraph_vector_int_size(neis); for (i = 0; i < nlen; i++) { long int edge = (long int) VECTOR(*neis)[i]; long int tto = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_real_t curdist = VECTOR(dists)[tto]; if (curdist < 0) { /* This is the first finite distance */ VECTOR(dists)[tto] = altdist; parents[tto] = edge + 1; IGRAPH_CHECK(igraph_2wheap_push_with_index(&Q, tto, -altdist)); } else if (altdist < curdist) { /* This is a shorter path */ VECTOR(dists)[tto] = altdist; parents[tto] = edge + 1; IGRAPH_CHECK(igraph_2wheap_modify(&Q, tto, -altdist)); } } } /* !igraph_2wheap_empty(&Q) */ if (to_reach > 0) { IGRAPH_WARNING("Couldn't reach some vertices"); } /* Create `predecessors' if needed */ if (predecessors) { IGRAPH_CHECK(igraph_vector_long_resize(predecessors, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { if (i == from) { /* i is the start vertex */ VECTOR(*predecessors)[i] = i; } else if (parents[i] <= 0) { /* i was not reached */ VECTOR(*predecessors)[i] = -1; } else { /* i was reached via the edge with ID = parents[i] - 1 */ VECTOR(*predecessors)[i] = IGRAPH_OTHER(graph, parents[i] - 1, i); } } } /* Create `inbound_edges' if needed */ if (inbound_edges) { IGRAPH_CHECK(igraph_vector_long_resize(inbound_edges, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { if (parents[i] <= 0) { /* i was not reached */ VECTOR(*inbound_edges)[i] = -1; } else { /* i was reached via the edge with ID = parents[i] - 1 */ VECTOR(*inbound_edges)[i] = parents[i] - 1; } } } /* Reconstruct the shortest paths based on vertex and/or edge IDs */ if (vertices || edges) { for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int node = IGRAPH_VIT_GET(vit); long int size, act, edge; igraph_vector_t *vvec = 0, *evec = 0; if (vertices) { vvec = VECTOR(*vertices)[i]; igraph_vector_clear(vvec); } if (edges) { evec = VECTOR(*edges)[i]; igraph_vector_clear(evec); } IGRAPH_ALLOW_INTERRUPTION(); size = 0; act = node; while (parents[act]) { size++; edge = parents[act] - 1; act = IGRAPH_OTHER(graph, edge, act); } if (vvec && (size > 0 || node == from)) { IGRAPH_CHECK(igraph_vector_resize(vvec, size + 1)); VECTOR(*vvec)[size] = node; } if (evec) { IGRAPH_CHECK(igraph_vector_resize(evec, size)); } act = node; while (parents[act]) { edge = parents[act] - 1; act = IGRAPH_OTHER(graph, edge, act); size--; if (vvec) { VECTOR(*vvec)[size] = act; } if (evec) { VECTOR(*evec)[size] = edge; } } } } igraph_lazy_inclist_destroy(&inclist); igraph_2wheap_destroy(&Q); igraph_vector_destroy(&dists); IGRAPH_FREE(is_target); IGRAPH_FREE(parents); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(6); return 0; } /** * \function igraph_get_shortest_path_dijkstra * \brief Weighted shortest path from one vertex to another one. * * Calculates a single (positively) weighted shortest path from * a single vertex to another one, using Dijkstra's algorithm. * * This function is a special case (and a wrapper) to * \ref igraph_get_shortest_paths_dijkstra(). * * \param graph The input graph, it can be directed or undirected. * \param vertices Pointer to an initialized vector or a null * pointer. If not a null pointer, then the vertex ids along * the path are stored here, including the source and target * vertices. * \param edges Pointer to an uninitialized vector or a null * pointer. If not a null pointer, then the edge ids along the * path are stored here. * \param from The id of the source vertex. * \param to The id of the target vertex. * \param weights The edge weights. All edge weights must be * non-negative for Dijkstra's algorithm to work. Additionally, no * edge weight may be NaN. If either case does not hold, an error * is returned. If this is a null pointer, then the unweighted * version, \ref igraph_get_shortest_paths() is called. * \param mode A constant specifying how edge directions are * considered in directed graphs. \c IGRAPH_OUT follows edge * directions, \c IGRAPH_IN follows the opposite directions, * and \c IGRAPH_ALL ignores edge directions. This argument is * ignored for undirected graphs. * \return Error code. * * Time complexity: O(|E|log|E|+|V|), |V| is the number of vertices, * |E| is the number of edges in the graph. * * \sa \ref igraph_get_shortest_paths_dijkstra() for the version with * more target vertices. */ int igraph_get_shortest_path_dijkstra(const igraph_t *graph, igraph_vector_t *vertices, igraph_vector_t *edges, igraph_integer_t from, igraph_integer_t to, const igraph_vector_t *weights, igraph_neimode_t mode) { igraph_vector_ptr_t vertices2, *vp = &vertices2; igraph_vector_ptr_t edges2, *ep = &edges2; if (vertices) { IGRAPH_CHECK(igraph_vector_ptr_init(&vertices2, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &vertices2); VECTOR(vertices2)[0] = vertices; } else { vp = 0; } if (edges) { IGRAPH_CHECK(igraph_vector_ptr_init(&edges2, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &edges2); VECTOR(edges2)[0] = edges; } else { ep = 0; } IGRAPH_CHECK(igraph_get_shortest_paths_dijkstra(graph, vp, ep, from, igraph_vss_1(to), weights, mode, 0, 0)); if (edges) { igraph_vector_ptr_destroy(&edges2); IGRAPH_FINALLY_CLEAN(1); } if (vertices) { igraph_vector_ptr_destroy(&vertices2); IGRAPH_FINALLY_CLEAN(1); } return 0; } /* Compares two paths based on their last elements. Required by * igraph_get_all_shortest_paths_dijkstra to put the final result * in order. Assumes that both paths are pointers to igraph_vector_t * objects and that they are not empty */ static int igraph_i_vector_tail_cmp(const void* path1, const void* path2) { return (int) (igraph_vector_tail(*(const igraph_vector_t**)path1) - igraph_vector_tail(*(const igraph_vector_t**)path2)); } /** * \ingroup structural * \function igraph_get_all_shortest_paths_dijkstra * \brief All weighted shortest paths (geodesics) from a vertex. * * \param graph The graph object. * \param res Pointer to an initialized pointer vector, the result * will be stored here in igraph_vector_t objects. Each vector * object contains the vertices along a shortest path from \p from * to another vertex. The vectors are ordered according to their * target vertex: first the shortest paths to vertex 0, then to * vertex 1, etc. No data is included for unreachable vertices. * \param nrgeo Pointer to an initialized igraph_vector_t object or * NULL. If not NULL the number of shortest paths from \p from are * stored here for every vertex in the graph. Note that the values * will be accurate only for those vertices that are in the target * vertex sequence (see \p to), since the search terminates as soon * as all the target vertices have been found. * \param from The id of the vertex from/to which the geodesics are * calculated. * \param to Vertex sequence with the ids of the vertices to/from which the * shortest paths will be calculated. A vertex might be given multiple * times. * \param weights The edge weights. All edge weights must be * non-negative for Dijkstra's algorithm to work. Additionally, no * edge weight may be NaN. If either case does not hold, an error * is returned. If this is a null pointer, then the unweighted * version, \ref igraph_get_all_shortest_paths() is called. * \param mode The type of shortest paths to be use for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing paths are calculated. * \cli IGRAPH_IN * the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an * undirected one for the computation. * \endclist * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * \p from is invalid vertex id, or the length of \p to is * not the same as the length of \p res. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(|E|log|E|+|V|), where |V| is the number of * vertices and |E| is the number of edges * * \sa \ref igraph_shortest_paths_dijkstra() if you only need the path * length but not the paths themselves, \ref igraph_get_all_shortest_paths() * if all edge weights are equal. * * \example examples/simple/igraph_get_all_shortest_paths_dijkstra.c */ int igraph_get_all_shortest_paths_dijkstra(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_vector_t *nrgeo, igraph_integer_t from, igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode) { /* Implementation details: see igraph_get_shortest_paths_dijkstra, it's basically the same. */ long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vit_t vit; igraph_2wheap_t Q; igraph_lazy_inclist_t inclist; igraph_vector_t dists, order; igraph_vector_ptr_t parents; igraph_finally_func_t *res_item_destructor; unsigned char *is_target; long int i, n, to_reach; int cmp_result; const double eps = IGRAPH_SHORTEST_PATH_EPSILON; if (!weights) { return igraph_get_all_shortest_paths(graph, res, nrgeo, from, to, mode); } if (res == 0 && nrgeo == 0) { return IGRAPH_SUCCESS; } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length does not match", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t min = igraph_vector_min(weights); if (min < 0) { IGRAPH_ERROR("Weight vector must be non-negative", IGRAPH_EINVAL); } else if (igraph_is_nan(min)) { IGRAPH_ERROR("Weight vector must not contain NaN values", IGRAPH_EINVAL); } } /* parents stores a vector for each vertex, listing the parent vertices * of each vertex in the traversal */ IGRAPH_CHECK(igraph_vector_ptr_init(&parents, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &parents); igraph_vector_ptr_set_item_destructor(&parents, (igraph_finally_func_t*)igraph_vector_destroy); for (i = 0; i < no_of_nodes; i++) { igraph_vector_t* parent_vec; parent_vec = IGRAPH_CALLOC(1, igraph_vector_t); if (parent_vec == 0) { IGRAPH_ERROR("cannot run igraph_get_all_shortest_paths", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(parent_vec, 0)); VECTOR(parents)[i] = parent_vec; } /* distance of each vertex from the root */ IGRAPH_VECTOR_INIT_FINALLY(&dists, no_of_nodes); igraph_vector_fill(&dists, -1.0); /* order lists the order of vertices in which they were found during * the traversal */ IGRAPH_VECTOR_INIT_FINALLY(&order, 0); /* boolean array to mark whether a given vertex is a target or not */ is_target = IGRAPH_CALLOC(no_of_nodes, unsigned char); if (is_target == 0) { IGRAPH_ERROR("Can't calculate shortest paths", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, is_target); /* two-way heap storing vertices and distances */ IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); /* lazy adjacency edge list to query neighbours efficiently */ IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &inclist, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); /* Mark the vertices we need to reach */ IGRAPH_CHECK(igraph_vit_create(graph, to, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); to_reach = IGRAPH_VIT_SIZE(vit); for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { if (!is_target[ (long int) IGRAPH_VIT_GET(vit) ]) { is_target[ (long int) IGRAPH_VIT_GET(vit) ] = 1; } else { to_reach--; /* this node was given multiple times */ } } igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); VECTOR(dists)[(long int)from] = 0.0; /* zero distance */ igraph_2wheap_push_with_index(&Q, from, 0); while (!igraph_2wheap_empty(&Q) && to_reach > 0) { long int nlen, minnei = igraph_2wheap_max_index(&Q); igraph_real_t mindist = -igraph_2wheap_delete_max(&Q); igraph_vector_int_t *neis; IGRAPH_ALLOW_INTERRUPTION(); /* printf("Reached vertex %ld, is_target[%ld] = %d, %ld to go\n", minnei, minnei, (int)is_target[minnei], to_reach - is_target[minnei]); */ if (is_target[minnei]) { is_target[minnei] = 0; to_reach--; } /* Mark that we have reached this vertex */ IGRAPH_CHECK(igraph_vector_push_back(&order, minnei)); /* Now check all neighbors of 'minnei' for a shorter path */ neis = igraph_lazy_inclist_get(&inclist, (igraph_integer_t) minnei); nlen = igraph_vector_int_size(neis); for (i = 0; i < nlen; i++) { long int edge = (long int) VECTOR(*neis)[i]; long int tto = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_real_t curdist = VECTOR(dists)[tto]; igraph_vector_t *parent_vec; cmp_result = igraph_cmp_epsilon(curdist, altdist, eps); if (curdist < 0) { /* This is the first non-infinite distance */ VECTOR(dists)[tto] = altdist; parent_vec = (igraph_vector_t*)VECTOR(parents)[tto]; IGRAPH_CHECK(igraph_vector_push_back(parent_vec, minnei)); IGRAPH_CHECK(igraph_2wheap_push_with_index(&Q, tto, -altdist)); } else if (cmp_result == 0 /* altdist == curdist */ && VECTOR(*weights)[edge] > 0) { /* This is an alternative path with exactly the same length. * Note that we consider this case only if the edge via which we * reached the node has a nonzero weight; otherwise we could create * infinite loops in undirected graphs by traversing zero-weight edges * back-and-forth */ parent_vec = (igraph_vector_t*)VECTOR(parents)[tto]; IGRAPH_CHECK(igraph_vector_push_back(parent_vec, minnei)); } else if (cmp_result > 0 /* altdist < curdist */) { /* This is a shorter path */ VECTOR(dists)[tto] = altdist; parent_vec = (igraph_vector_t*)VECTOR(parents)[tto]; igraph_vector_clear(parent_vec); IGRAPH_CHECK(igraph_vector_push_back(parent_vec, minnei)); IGRAPH_CHECK(igraph_2wheap_modify(&Q, tto, -altdist)); } } } /* !igraph_2wheap_empty(&Q) */ if (to_reach > 0) { IGRAPH_WARNING("Couldn't reach some vertices"); } /* we don't need these anymore */ igraph_lazy_inclist_destroy(&inclist); igraph_2wheap_destroy(&Q); IGRAPH_FINALLY_CLEAN(2); /* printf("Order:\n"); igraph_vector_print(&order); printf("Parent vertices:\n"); for (i = 0; i < no_of_nodes; i++) { if (igraph_vector_size(VECTOR(parents)[i]) > 0) { printf("[%ld]: ", (long int)i); igraph_vector_print(VECTOR(parents)[i]); } } */ if (nrgeo) { IGRAPH_CHECK(igraph_vector_resize(nrgeo, no_of_nodes)); igraph_vector_null(nrgeo); /* Theoretically, we could calculate nrgeo in parallel with the traversal. * However, that way we would have to check whether nrgeo is null or not * every time we want to update some element in nrgeo. Since we need the * order vector anyway for building the final result, we could just as well * build nrgeo here. */ VECTOR(*nrgeo)[(long int)from] = 1; n = igraph_vector_size(&order); for (i = 1; i < n; i++) { long int node, j, k; igraph_vector_t *parent_vec; node = (long int)VECTOR(order)[i]; /* now, take the parent vertices */ parent_vec = (igraph_vector_t*)VECTOR(parents)[node]; k = igraph_vector_size(parent_vec); for (j = 0; j < k; j++) { VECTOR(*nrgeo)[node] += VECTOR(*nrgeo)[(long int)VECTOR(*parent_vec)[j]]; } } } if (res) { igraph_vector_t *path, *paths_index, *parent_vec; igraph_stack_t stack; long int j, node; /* a shortest path from the starting vertex to vertex i can be * obtained by calculating the shortest paths from the "parents" * of vertex i in the traversal. Knowing which of the vertices * are "targets" (see is_target), we can collect for which other * vertices do we need to calculate the shortest paths. We reuse * is_target for that; is_target = 0 means that we don't need the * vertex, is_target = 1 means that the vertex is a target (hence * we need it), is_target = 2 means that the vertex is not a target * but it stands between a shortest path between the root and one * of the targets */ if (igraph_vs_is_all(&to)) { memset(is_target, 1, sizeof(unsigned char) * (size_t) no_of_nodes); } else { memset(is_target, 0, sizeof(unsigned char) * (size_t) no_of_nodes); IGRAPH_CHECK(igraph_stack_init(&stack, 0)); IGRAPH_FINALLY(igraph_stack_destroy, &stack); /* Add the target vertices to the queue */ IGRAPH_CHECK(igraph_vit_create(graph, to, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { i = (long int) IGRAPH_VIT_GET(vit); if (!is_target[i]) { is_target[i] = 1; IGRAPH_CHECK(igraph_stack_push(&stack, i)); } } igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); while (!igraph_stack_empty(&stack)) { /* For each parent of node i, get its parents */ igraph_real_t el = igraph_stack_pop(&stack); parent_vec = (igraph_vector_t*)VECTOR(parents)[(long int) el]; i = igraph_vector_size(parent_vec); for (j = 0; j < i; j++) { /* For each parent, check if it's already in the stack. * If not, push it and mark it in is_target */ n = (long int) VECTOR(*parent_vec)[j]; if (!is_target[n]) { is_target[n] = 2; IGRAPH_CHECK(igraph_stack_push(&stack, n)); } } } igraph_stack_destroy(&stack); IGRAPH_FINALLY_CLEAN(1); } /* now, reconstruct the shortest paths from the parent list in the * order we've found the nodes during the traversal. * dists is being re-used as a vector where element i tells the * index in res where the shortest paths leading to vertex i * start, plus one (so that zero means that there are no paths * for a given vertex). */ paths_index = &dists; n = igraph_vector_size(&order); igraph_vector_null(paths_index); /* clear the paths vector */ igraph_vector_ptr_clear(res); res_item_destructor = igraph_vector_ptr_get_item_destructor(res); igraph_vector_ptr_set_item_destructor(res, (igraph_finally_func_t*)igraph_vector_destroy); /* by definition, the shortest path leading to the starting vertex * consists of the vertex itself only */ path = IGRAPH_CALLOC(1, igraph_vector_t); if (path == 0) IGRAPH_ERROR("cannot run igraph_get_all_shortest_paths_dijkstra", IGRAPH_ENOMEM); IGRAPH_FINALLY(igraph_free, path); IGRAPH_CHECK(igraph_vector_init(path, 1)); IGRAPH_CHECK(igraph_vector_ptr_push_back(res, path)); IGRAPH_FINALLY_CLEAN(1); /* ownership of path passed to res */ VECTOR(*path)[0] = from; VECTOR(*paths_index)[(long int)from] = 1; for (i = 1; i < n; i++) { long int m, path_count; igraph_vector_t *parent_path; node = (long int) VECTOR(order)[i]; /* if we don't need the shortest paths for this node (because * it is not standing in a shortest path between the source * node and any of the target nodes), skip it */ if (!is_target[node]) { continue; } IGRAPH_ALLOW_INTERRUPTION(); /* we are calculating the shortest paths of node now. */ /* first, we update the paths_index */ path_count = igraph_vector_ptr_size(res); VECTOR(*paths_index)[node] = path_count + 1; /* res_end = (igraph_vector_t*)&(VECTOR(*res)[path_count]); */ /* now, take the parent vertices */ parent_vec = (igraph_vector_t*)VECTOR(parents)[node]; m = igraph_vector_size(parent_vec); /* printf("Calculating shortest paths to vertex %ld\n", node); printf("Parents are: "); igraph_vector_print(parent_vec); */ for (j = 0; j < m; j++) { /* for each parent, copy the shortest paths leading to that parent * and add the current vertex in the end */ long int parent_node = (long int) VECTOR(*parent_vec)[j]; long int parent_path_idx = (long int) VECTOR(*paths_index)[parent_node] - 1; /* printf(" Considering parent: %ld\n", parent_node); printf(" Paths to parent start at index %ld in res\n", parent_path_idx); */ IGRAPH_ASSERT(parent_path_idx >= 0); for (; parent_path_idx < path_count; parent_path_idx++) { parent_path = (igraph_vector_t*)VECTOR(*res)[parent_path_idx]; if (igraph_vector_tail(parent_path) != parent_node) { break; } path = IGRAPH_CALLOC(1, igraph_vector_t); if (path == 0) IGRAPH_ERROR("cannot run igraph_get_all_shortest_paths_dijkstra", IGRAPH_ENOMEM); IGRAPH_FINALLY(igraph_free, path); IGRAPH_CHECK(igraph_vector_copy(path, parent_path)); IGRAPH_CHECK(igraph_vector_ptr_push_back(res, path)); IGRAPH_FINALLY_CLEAN(1); /* ownership of path passed to res */ IGRAPH_CHECK(igraph_vector_push_back(path, node)); } } } /* remove the path vector's original item destructor */ igraph_vector_ptr_set_item_destructor(res, res_item_destructor); /* free those paths from the result vector which we won't need */ n = igraph_vector_ptr_size(res); j = 0; for (i = 0; i < n; i++) { igraph_real_t tmp; path = (igraph_vector_t*)VECTOR(*res)[i]; tmp = igraph_vector_tail(path); if (is_target[(long int)tmp] == 1) { /* we need this path, keep it */ VECTOR(*res)[j] = path; j++; } else { /* we don't need this path, free it */ igraph_vector_destroy(path); free(path); } } IGRAPH_CHECK(igraph_vector_ptr_resize(res, j)); /* sort the paths by the target vertices */ igraph_vector_ptr_sort(res, igraph_i_vector_tail_cmp); } /* free the allocated memory */ igraph_vector_destroy(&order); IGRAPH_FREE(is_target); igraph_vector_destroy(&dists); igraph_vector_ptr_destroy_all(&parents); IGRAPH_FINALLY_CLEAN(4); return 0; } leidenbase/src/core/paths/random_walk.c0000644000176200001440000002443014447675375017676 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2014 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_paths.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_random.h" #include "igraph_memory.h" #include "core/interruption.h" /** * \function igraph_random_walk * Perform a random walk on a graph * * Performs a random walk with a given length on a graph, from the given * start vertex. Edge directions are (potentially) considered, depending on * the \p mode argument. * * \param graph The input graph, it can be directed or undirected. * Multiple edges are respected, so are loop edges. * \param walk An allocated vector, the result is stored here. * It will be resized as needed. * \param start The start vertex for the walk. * \param steps The number of steps to take. If the random walk gets * stuck, then the \p stuck argument specifies what happens. * \param mode How to walk along the edges in directed graphs. * \c IGRAPH_OUT means following edge directions, \c IGRAPH_IN means * going opposite the edge directions, \c IGRAPH_ALL means ignoring * edge directions. This argument is ignored for undirected graphs. * \param stuck What to do if the random walk gets stuck. * \c IGRAPH_RANDOM_WALK_STUCK_RETURN means that the function returns * with a shorter walk; \c IGRAPH_RANDOM_WALK_STUCK_ERROR means * that an error is reported. In both cases \p walk is truncated * to contain the actual interrupted walk. * \return Error code. * * Time complexity: O(l + d), where \c l is the length of the * walk, and \c d is the total degree of the visited nodes. */ int igraph_random_walk(const igraph_t *graph, igraph_vector_t *walk, igraph_integer_t start, igraph_neimode_t mode, igraph_integer_t steps, igraph_random_walk_stuck_t stuck) { /* TODO: - multiple walks potentially from multiple start vertices - weights */ igraph_lazy_adjlist_t adj; igraph_integer_t vc = igraph_vcount(graph); igraph_integer_t i; if (start < 0 || start >= vc) { IGRAPH_ERROR("Invalid start vertex.", IGRAPH_EINVAL); } if (steps < 0) { IGRAPH_ERROR("Invalid number of steps.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adj, mode, IGRAPH_LOOPS, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adj); IGRAPH_CHECK(igraph_vector_resize(walk, steps)); RNG_BEGIN(); VECTOR(*walk)[0] = start; for (i = 1; i < steps; i++) { igraph_vector_int_t *neis; igraph_integer_t nn; neis = igraph_lazy_adjlist_get(&adj, start); nn = igraph_vector_int_size(neis); if (IGRAPH_UNLIKELY(nn == 0)) { igraph_vector_resize(walk, i); if (stuck == IGRAPH_RANDOM_WALK_STUCK_RETURN) { break; } else { IGRAPH_ERROR("Random walk got stuck.", IGRAPH_ERWSTUCK); } } start = VECTOR(*walk)[i] = VECTOR(*neis)[ RNG_INTEGER(0, nn - 1) ]; } RNG_END(); igraph_lazy_adjlist_destroy(&adj); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Used as item destructor for 'cdfs' in igraph_random_edge_walk(). */ static void vec_destr(igraph_vector_t *vec) { if (vec != NULL) { igraph_vector_destroy(vec); } } /** * \function igraph_random_edge_walk * \brief Perform a random walk on a graph and return the traversed edges * * Performs a random walk with a given length on a graph, from the given * start vertex. Edge directions are (potentially) considered, depending on * the \p mode argument. * * \param graph The input graph, it can be directed or undirected. * Multiple edges are respected, so are loop edges. * \param weights A vector of non-negative edge weights. It is assumed * that at least one strictly positive weight is found among the * outgoing edges of each vertex. Additionally, no edge weight may * be NaN. If either case does not hold, an error is returned. If it * is a NULL pointer, all edges are considered to have equal weight. * \param edgewalk An initialized vector; the indices of traversed * edges are stored here. It will be resized as needed. * \param start The start vertex for the walk. * \param steps The number of steps to take. If the random walk gets * stuck, then the \p stuck argument specifies what happens. * \param mode How to walk along the edges in directed graphs. * \c IGRAPH_OUT means following edge directions, \c IGRAPH_IN means * going opposite the edge directions, \c IGRAPH_ALL means ignoring * edge directions. This argument is ignored for undirected graphs. * \param stuck What to do if the random walk gets stuck. * \c IGRAPH_RANDOM_WALK_STUCK_RETURN means that the function returns * with a shorter walk; \c IGRAPH_RANDOM_WALK_STUCK_ERROR means * that an error is reported. In both cases, \p edgewalk is truncated * to contain the actual interrupted walk. * * \return Error code. * */ int igraph_random_edge_walk(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_t *edgewalk, igraph_integer_t start, igraph_neimode_t mode, igraph_integer_t steps, igraph_random_walk_stuck_t stuck) { igraph_integer_t vc = igraph_vcount(graph); igraph_integer_t ec = igraph_ecount(graph); igraph_integer_t i; igraph_inclist_t il; igraph_vector_t weight_temp; igraph_vector_ptr_t cdfs; /* cumulative distribution vectors for each node, used for weighted choice */ if (! (mode == IGRAPH_ALL || mode == IGRAPH_IN || mode == IGRAPH_OUT)) { IGRAPH_ERROR("Invalid mode parameter.", IGRAPH_EINVMODE); } /* ref switch statement at end of main loop */ if (! igraph_is_directed(graph)) { mode = IGRAPH_ALL; } if (start < 0 || start >= vc) { IGRAPH_ERROR("Invalid start vertex.", IGRAPH_EINVAL); } if (steps < 0) { IGRAPH_ERROR("Invalid number of steps.", IGRAPH_EINVAL); } if (weights) { if (igraph_vector_size(weights) != ec) { IGRAPH_ERROR("Invalid weight vector length.", IGRAPH_EINVAL); } if (ec > 0) { igraph_real_t min = igraph_vector_min(weights); if (min < 0) { IGRAPH_ERROR("Weights must be non-negative.", IGRAPH_EINVAL); } else if (igraph_is_nan(min)) { IGRAPH_ERROR("Weights must not contain NaN values.", IGRAPH_EINVAL); } } } IGRAPH_CHECK(igraph_vector_resize(edgewalk, steps)); IGRAPH_CHECK(igraph_inclist_init(graph, &il, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &il); IGRAPH_VECTOR_INIT_FINALLY(&weight_temp, 0); /* cdf vectors will be computed lazily */ IGRAPH_CHECK(igraph_vector_ptr_init(&cdfs, vc)); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &cdfs); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&cdfs, vec_destr); for (i = 0; i < vc; ++i) { VECTOR(cdfs)[i] = NULL; } RNG_BEGIN(); for (i = 0; i < steps; ++i) { long degree, edge, idx; igraph_vector_int_t *edges = igraph_inclist_get(&il, start); degree = igraph_vector_int_size(edges); /* are we stuck? */ if (IGRAPH_UNLIKELY(degree == 0)) { igraph_vector_resize(edgewalk, i); /* can't fail since size is reduced, skip IGRAPH_CHECK */ if (stuck == IGRAPH_RANDOM_WALK_STUCK_RETURN) { break; } else { IGRAPH_ERROR("Random walk got stuck.", IGRAPH_ERWSTUCK); } } if (weights) { /* weighted: choose an out-edge with probability proportional to its weight */ igraph_real_t r; igraph_vector_t **cd = (igraph_vector_t **) & (VECTOR(cdfs)[start]); /* compute out-edge cdf for this node if not already done */ if (IGRAPH_UNLIKELY(! *cd)) { long j; *cd = IGRAPH_CALLOC(1, igraph_vector_t); if (*cd == NULL) { IGRAPH_ERROR("Random edge walk failed.", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(*cd, degree)); IGRAPH_CHECK(igraph_vector_resize(&weight_temp, degree)); for (j = 0; j < degree; ++j) { VECTOR(weight_temp)[j] = VECTOR(*weights)[ VECTOR(*edges)[j] ]; } IGRAPH_CHECK(igraph_vector_cumsum(*cd, &weight_temp)); } r = RNG_UNIF(0, VECTOR( **cd )[degree - 1]); igraph_vector_binsearch(*cd, r, &idx); } else { /* unweighted: choose an out-edge at random */ idx = RNG_INTEGER(0, degree - 1); } edge = VECTOR(*edges)[idx]; VECTOR(*edgewalk)[i] = edge; /* travel along edge in a direction specified by 'mode' */ /* note: 'mode' is always set to IGRAPH_ALL for undirected graphs */ switch (mode) { case IGRAPH_OUT: start = IGRAPH_TO(graph, edge); break; case IGRAPH_IN: start = IGRAPH_FROM(graph, edge); break; case IGRAPH_ALL: start = IGRAPH_OTHER(graph, edge, start); break; } IGRAPH_ALLOW_INTERRUPTION(); } RNG_END(); igraph_vector_ptr_destroy_all(&cdfs); igraph_vector_destroy(&weight_temp); igraph_inclist_destroy(&il); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } leidenbase/src/core/paths/histogram.c0000644000176200001440000001201414447675375017370 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_paths.h" #include "igraph_adjlist.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "core/interruption.h" /** * \function igraph_path_length_hist * Create a histogram of all shortest path lengths. * * This function calculates a histogram, by calculating the * shortest path length between each pair of vertices. For directed * graphs both directions might be considered and then every pair of vertices * appears twice in the histogram. * \param graph The input graph. * \param res Pointer to an initialized vector, the result is stored * here. The first (i.e. zeroth) element contains the number of * shortest paths of length 1, etc. The supplied vector is resized * as needed. * \param unconnected Pointer to a real number, the number of * pairs for which the second vertex is not reachable from the * first is stored here. * \param directed Whether to consider directed paths in a directed * graph (if not zero). This argument is ignored for undirected * graphs. * \return Error code. * * Time complexity: O(|V||E|), the number of vertices times the number * of edges. * * \sa \ref igraph_average_path_length() and \ref igraph_shortest_paths() */ int igraph_path_length_hist(const igraph_t *graph, igraph_vector_t *res, igraph_real_t *unconnected, igraph_bool_t directed) { long int no_of_nodes = igraph_vcount(graph); long int i, j, n; igraph_vector_long_t already_added; long int nodes_reached; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; igraph_vector_int_t *neis; igraph_neimode_t dirmode; igraph_adjlist_t allneis; igraph_real_t unconn = 0; long int ressize; if (directed) { dirmode = IGRAPH_OUT; } else { dirmode = IGRAPH_ALL; } IGRAPH_CHECK(igraph_vector_long_init(&already_added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &already_added); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_adjlist_init(graph, &allneis, dirmode, IGRAPH_LOOPS, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); IGRAPH_CHECK(igraph_vector_resize(res, 0)); ressize = 0; for (i = 0; i < no_of_nodes; i++) { nodes_reached = 1; /* itself */ IGRAPH_CHECK(igraph_dqueue_push(&q, i)); IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); VECTOR(already_added)[i] = i + 1; IGRAPH_PROGRESS("Path length histogram: ", 100.0 * i / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); neis = igraph_adjlist_get(&allneis, actnode); n = igraph_vector_int_size(neis); for (j = 0; j < n; j++) { long int neighbor = (long int) VECTOR(*neis)[j]; if (VECTOR(already_added)[neighbor] == i + 1) { continue; } VECTOR(already_added)[neighbor] = i + 1; nodes_reached++; if (actdist + 1 > ressize) { IGRAPH_CHECK(igraph_vector_resize(res, actdist + 1)); for (; ressize < actdist + 1; ressize++) { VECTOR(*res)[ressize] = 0; } } VECTOR(*res)[actdist] += 1; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); } } /* while !igraph_dqueue_empty */ unconn += (no_of_nodes - nodes_reached); } /* for i This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_paths.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_dqueue.h" #include "igraph_memory.h" #include "igraph_progress.h" #include "core/indheap.h" #include "core/interruption.h" #include /*****************************************************/ /***** Average path length and global efficiency *****/ /*****************************************************/ /* Computes the average of pairwise distances (used for igraph_average_path_length), * or of inverse pairwise distances (used for igraph_global_efficiency), in an unweighted graph. */ static int igraph_i_average_path_length_unweighted( const igraph_t *graph, igraph_real_t *res, igraph_real_t *unconnected_pairs, /* if not NULL, will be set to the no. of non-connected ordered vertex pairs */ const igraph_bool_t directed, const igraph_bool_t invert, /* average inverse distances instead of distances */ const igraph_bool_t unconn /* average over connected pairs instead of all pairs */) { long int no_of_nodes = igraph_vcount(graph); long int source, j, n; long int *already_added; igraph_real_t no_of_pairs = no_of_nodes > 0 ? no_of_nodes * (no_of_nodes - 1.0) : 0.0; /* no. of ordered vertex pairs */ igraph_real_t no_of_conn_pairs = 0.0; /* no. of ordered pairs between which there is a path */ igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; igraph_vector_int_t *neis; igraph_adjlist_t allneis; *res = 0; already_added = IGRAPH_CALLOC(no_of_nodes, long int); if (already_added == 0) { IGRAPH_ERROR("Average path length calculation failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_adjlist_init( graph, &allneis, directed ? IGRAPH_OUT : IGRAPH_ALL, IGRAPH_LOOPS, IGRAPH_MULTIPLE )); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); for (source = 0; source < no_of_nodes; source++) { IGRAPH_CHECK(igraph_dqueue_push(&q, source)); IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); already_added[source] = source + 1; IGRAPH_ALLOW_INTERRUPTION(); while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); neis = igraph_adjlist_get(&allneis, actnode); n = igraph_vector_int_size(neis); for (j = 0; j < n; j++) { long int neighbor = (long int) VECTOR(*neis)[j]; if (already_added[neighbor] == source + 1) { continue; } already_added[neighbor] = source + 1; if (invert) { *res += 1.0/(actdist + 1.0); } else { *res += actdist + 1.0; } no_of_conn_pairs += 1; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); } } /* while !igraph_dqueue_empty */ } /* for source < no_of_nodes */ if (no_of_pairs == 0) { *res = IGRAPH_NAN; /* can't average zero items */ } else { if (unconn) { /* average over connected pairs */ if (no_of_conn_pairs == 0) { *res = IGRAPH_NAN; /* can't average zero items */ } else { *res /= no_of_conn_pairs; } } else { /* average over all pairs */ /* no_of_conn_pairs < no_of_pairs implies that the graph is disconnected */ if (no_of_conn_pairs < no_of_pairs && ! invert) { /* When invert=false, assume the distance between non-connected pairs to be infinity */ *res = IGRAPH_INFINITY; } else { /* When invert=true, assume the inverse distance between non-connected pairs * to be zero. Therefore, no special treatment is needed for disconnected graphs. */ *res /= no_of_pairs; } } } if (unconnected_pairs) *unconnected_pairs = no_of_pairs - no_of_conn_pairs; /* clean */ IGRAPH_FREE(already_added); igraph_dqueue_destroy(&q); igraph_adjlist_destroy(&allneis); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /* Computes the average of pairwise distances (used for igraph_average_path_length_dijkstra), * or of inverse pairwise distances (used for igraph_global_efficiency), in an unweighted graph. * Uses Dijkstra's algorithm, therefore all weights must be non-negative. */ static int igraph_i_average_path_length_dijkstra( const igraph_t *graph, igraph_real_t *res, igraph_real_t *unconnected_pairs, const igraph_vector_t *weights, const igraph_bool_t directed, const igraph_bool_t invert, /* average inverse distances instead of distances */ const igraph_bool_t unconn /* average over connected pairs instead of all pairs */) { /* Implementation details. This is the basic Dijkstra algorithm, with a binary heap. The heap is indexed, i.e. it stores not only the distances, but also which vertex they belong to. From now on we use a 2-way heap, so the distances can be queried directly from the heap. Dirty tricks: - the opposite of the distance is stored in the heap, as it is a maximum heap and we need a minimum heap. - we don't use IGRAPH_INFINITY in the res matrix during the computation, as IGRAPH_FINITE() might involve a function call and we want to spare that. -1 will denote infinity instead. */ long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_2wheap_t Q; igraph_lazy_inclist_t inclist; long int source, j; igraph_real_t no_of_pairs; igraph_real_t no_of_conn_pairs = 0.0; /* no. of ordered pairs between which there is a path */ if (!weights) { return igraph_i_average_path_length_unweighted(graph, res, unconnected_pairs, directed, invert, unconn); } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERRORF("Weight vector length (%ld) does not match the number of edges (%ld).", IGRAPH_EINVAL, igraph_vector_size(weights), no_of_edges); } if (no_of_edges > 0) { igraph_real_t min = igraph_vector_min(weights); if (min < 0) { IGRAPH_ERRORF("Weight vector must be non-negative, got %g.", IGRAPH_EINVAL, min); } else if (igraph_is_nan(min)) { IGRAPH_ERROR("Weight vector must not contain NaN values.", IGRAPH_EINVAL); } } /* Avoid returning a negative zero, which would be printed as -0 in tests. */ if (no_of_nodes > 0) { no_of_pairs = no_of_nodes * (no_of_nodes - 1.0); } else { no_of_pairs = 0; } IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); IGRAPH_CHECK(igraph_lazy_inclist_init( graph, &inclist, directed ? IGRAPH_OUT : IGRAPH_ALL, IGRAPH_LOOPS )); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); *res = 0.0; for (source = 0; source < no_of_nodes; ++source) { IGRAPH_ALLOW_INTERRUPTION(); igraph_2wheap_clear(&Q); igraph_2wheap_push_with_index(&Q, source, -1.0); while (!igraph_2wheap_empty(&Q)) { long int minnei = igraph_2wheap_max_index(&Q); igraph_real_t mindist = -igraph_2wheap_deactivate_max(&Q); igraph_vector_int_t *neis; long int nlen; if (minnei != source) { if (invert) { *res += 1.0/(mindist - 1.0); } else { *res += mindist - 1.0; } no_of_conn_pairs += 1; } /* Now check all neighbors of 'minnei' for a shorter path */ neis = igraph_lazy_inclist_get(&inclist, (igraph_integer_t) minnei); nlen = igraph_vector_int_size(neis); for (j = 0; j < nlen; j++) { long int edge = (long int) VECTOR(*neis)[j]; long int tto = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_bool_t active = igraph_2wheap_has_active(&Q, tto); igraph_bool_t has = igraph_2wheap_has_elem(&Q, tto); igraph_real_t curdist = active ? -igraph_2wheap_get(&Q, tto) : 0.0; if (!has) { /* This is the first non-infinite distance */ IGRAPH_CHECK(igraph_2wheap_push_with_index(&Q, tto, -altdist)); } else if (altdist < curdist) { /* This is a shorter path */ IGRAPH_CHECK(igraph_2wheap_modify(&Q, tto, -altdist)); } } } /* !igraph_2wheap_empty(&Q) */ } /* for source < no_of_nodes */ if (no_of_pairs == 0) { *res = IGRAPH_NAN; /* can't average zero items */ } else { if (unconn) { /* average over connected pairs */ if (no_of_conn_pairs == 0) { *res = IGRAPH_NAN; /* can't average zero items */ } else { *res /= no_of_conn_pairs; } } else { /* average over all pairs */ /* no_of_conn_pairs < no_of_pairs implies that the graph is disconnected */ if (no_of_conn_pairs < no_of_pairs && ! invert) { *res = IGRAPH_INFINITY; } else { *res /= no_of_pairs; } } } if (unconnected_pairs) *unconnected_pairs = no_of_pairs - no_of_conn_pairs; igraph_lazy_inclist_destroy(&inclist); igraph_2wheap_destroy(&Q); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_average_path_length * \brief Calculates the average unweighted shortest path length between all vertex pairs. * * * If no vertex pairs can be included in the calculation, for example because the graph * has fewer than two vertices, or if the graph has no edges and \c unconn is set to \c TRUE, * NaN is returned. * * \param graph The graph object. * \param res Pointer to a real number, this will contain the result. * \param unconn_pairs Pointer to a real number. If not a null pointer, the number of * ordered vertex pairs where the second vertex is unreachable from the first one * will be stored here. * \param directed Boolean, whether to consider directed * paths. Ignored for undirected graphs. * \param unconn What to do if the graph is not connected. If * \c TRUE, only those vertex pairs will be included in the calculation * between which there is a path. If \c FALSE, \c IGRAPH_INFINITY is returned * for disconnected graphs. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for data structures * * Time complexity: O(|V| |E|), the number of vertices times the number of edges. * * \sa \ref igraph_average_path_length_dijkstra() for the weighted version. * * \example examples/simple/igraph_average_path_length.c */ int igraph_average_path_length(const igraph_t *graph, igraph_real_t *res, igraph_real_t *unconn_pairs, igraph_bool_t directed, igraph_bool_t unconn) { return igraph_i_average_path_length_unweighted(graph, res, unconn_pairs, directed, /* invert= */ 0, unconn); } /** * \ingroup structural * \function igraph_average_path_length_dijkstra * \brief Calculates the average weighted shortest path length between all vertex pairs. * * * If no vertex pairs can be included in the calculation, for example because the graph * has fewer than two vertices, or if the graph has no edges and \c unconn is set to \c TRUE, * NaN is returned. * * * All distinct ordered vertex pairs are taken into account. * * \param graph The graph object. * \param res Pointer to a real number, this will contain the result. * \param unconn_pairs Pointer to a real number. If not a null pointer, the number of * ordered vertex pairs where the second vertex is unreachable from the first one * will be stored here. * \param weights The edge weights. All edge weights must be * non-negative for Dijkstra's algorithm to work. Additionally, no * edge weight may be NaN. If either case does not hold, an error * is returned. If this is a null pointer, then the unweighted * version, \ref igraph_average_path_length() is called. * \param directed Boolean, whether to consider directed paths. * Ignored for undirected graphs. * \param unconn If \c TRUE, only those pairs are considered for the calculation * between which there is a path. If \c FALSE, \c IGRAPH_INFINITY is returned * for disconnected graphs. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for data structures * \cli IGRAPH_EINVAL * invalid weight vector * \endclist * * Time complexity: O(|V| |E| log|E| + |V|), where |V| is the number of * vertices and |E| is the number of edges. * * \sa \ref igraph_average_path_length() for a slightly faster unweighted version. * * \example examples/simple/igraph_grg_game.c */ int igraph_average_path_length_dijkstra(const igraph_t *graph, igraph_real_t *res, igraph_real_t *unconn_pairs, const igraph_vector_t *weights, igraph_bool_t directed, igraph_bool_t unconn) { return igraph_i_average_path_length_dijkstra(graph, res, unconn_pairs, weights, directed, /* invert= */ 0, unconn); } /** * \ingroup structural * \function igraph_global_efficiency * \brief Calculates the global efficiency of a network. * * * The global efficiency of a network is defined as the average of inverse distances * between all pairs of vertices: E_g = 1/(N*(N-1)) sum_{i!=j} 1/d_ij, * where N is the number of vertices. * The inverse distance between pairs that are not reachable from each other is considered * to be zero. For graphs with fewer than 2 vertices, NaN is returned. * * * Reference: * V. Latora and M. Marchiori, * Efficient Behavior of Small-World Networks, * Phys. Rev. Lett. 87, 198701 (2001). * https://dx.doi.org/10.1103/PhysRevLett.87.198701 * * \param graph The graph object. * \param res Pointer to a real number, this will contain the result. * \param weights The edge weights. All edge weights must be * non-negative for Dijkstra's algorithm to work. Additionally, no * edge weight may be NaN. If either case does not hold, an error * is returned. If this is a null pointer, then the unweighted * version, \ref igraph_average_path_length() is used in calculating * the global efficiency. * \param directed Boolean, whether to consider directed paths. * Ignored for undirected graphs. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for data structures * \cli IGRAPH_EINVAL * invalid weight vector * \endclist * * Time complexity: O(|V| |E| log|E| + |V|) for weighted graphs and * O(|V| |E|) for unweighted ones. |V| denotes the number of * vertices and |E| denotes the number of edges. * */ int igraph_global_efficiency(const igraph_t *graph, igraph_real_t *res, const igraph_vector_t *weights, igraph_bool_t directed) { return igraph_i_average_path_length_dijkstra(graph, res, NULL, weights, directed, /* invert= */ 1, /* unconn= */ 0); } /****************************/ /***** Local efficiency *****/ /****************************/ static int igraph_i_local_efficiency_unweighted( const igraph_t *graph, const igraph_adjlist_t *adjlist, igraph_dqueue_t *q, long int *already_counted, igraph_vector_t *vertex_neis, igraph_vector_char_t *nei_mask, igraph_real_t *res, igraph_integer_t vertex, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); long int vertex_neis_size; long int neighbor_count; /* unlike 'vertex_neis_size', 'neighbor_count' does not count self-loops and multi-edges */ long int i, j; igraph_dqueue_clear(q); /* already_counted[i] is 0 iff vertex i was not reached so far, otherwise * it is the index of the source vertex in vertex_neis that it was reached * from, plus 1 */ memset(already_counted, 0, no_of_nodes * sizeof(long int)); IGRAPH_CHECK(igraph_neighbors(graph, vertex_neis, vertex, mode)); vertex_neis_size = igraph_vector_size(vertex_neis); igraph_vector_char_fill(nei_mask, 0); neighbor_count = 0; for (i=0; i < vertex_neis_size; ++i) { long int v = VECTOR(*vertex_neis)[i]; if (v != vertex && ! VECTOR(*nei_mask)[v]) { VECTOR(*nei_mask)[v] = 1; /* mark as unprocessed neighbour */ neighbor_count++; } } *res = 0.0; /* when the neighbor count is smaller than 2, we return 0.0 */ if (neighbor_count < 2) { return IGRAPH_SUCCESS; } for (i=0; i < vertex_neis_size; ++i) { long int source = VECTOR(*vertex_neis)[i]; long int reached = 0; IGRAPH_ALLOW_INTERRUPTION(); if (source == vertex) continue; if (VECTOR(*nei_mask)[source] == 2) continue; VECTOR(*nei_mask)[source] = 2; /* mark neighbour as already processed */ IGRAPH_CHECK(igraph_dqueue_push(q, source)); IGRAPH_CHECK(igraph_dqueue_push(q, 0)); already_counted[source] = i + 1; while (!igraph_dqueue_empty(q)) { igraph_vector_int_t *act_neis; long int act_neis_size; long int act = (long int) igraph_dqueue_pop(q); long int actdist = (long int) igraph_dqueue_pop(q); if (act != source && VECTOR(*nei_mask)[act]) { *res += 1.0 / actdist; reached++; if (reached == neighbor_count) { igraph_dqueue_clear(q); break; } } act_neis = igraph_adjlist_get(adjlist, act); act_neis_size = igraph_vector_int_size(act_neis); for (j = 0; j < act_neis_size; j++) { long int neighbor = (long int) VECTOR(*act_neis)[j]; if (neighbor == vertex || already_counted[neighbor] == i + 1) continue; already_counted[neighbor] = i + 1; IGRAPH_CHECK(igraph_dqueue_push(q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(q, actdist + 1)); } } } *res /= neighbor_count * (neighbor_count - 1.0); return IGRAPH_SUCCESS; } static int igraph_i_local_efficiency_dijkstra( const igraph_t *graph, igraph_lazy_inclist_t *inclist, igraph_2wheap_t *Q, igraph_vector_t *vertex_neis, igraph_vector_char_t *nei_mask, /* true if the corresponding node is a neighbour of 'vertex' */ igraph_real_t *res, igraph_integer_t vertex, igraph_neimode_t mode, const igraph_vector_t *weights) { /* Implementation details. This is the basic Dijkstra algorithm, with a binary heap. The heap is indexed, i.e. it stores not only the distances, but also which vertex they belong to. From now on we use a 2-way heap, so the distances can be queried directly from the heap. Dirty tricks: - the opposite of the distance is stored in the heap, as it is a maximum heap and we need a minimum heap. - we don't use IGRAPH_INFINITY in the res matrix during the computation, as IGRAPH_FINITE() might involve a function call and we want to spare that. -1 will denote infinity instead. */ long int i, j; long int vertex_neis_size; long int neighbor_count; /* unlike 'inc_edges_size', 'neighbor_count' does not count self-loops or multi-edges */ IGRAPH_CHECK(igraph_neighbors(graph, vertex_neis, vertex, mode)); vertex_neis_size = igraph_vector_size(vertex_neis); igraph_vector_char_fill(nei_mask, 0); neighbor_count = 0; for (i=0; i < vertex_neis_size; ++i) { long int v = VECTOR(*vertex_neis)[i]; if (v != vertex && ! VECTOR(*nei_mask)[v]) { VECTOR(*nei_mask)[v] = 1; /* mark as unprocessed neighbour */ neighbor_count++; } } *res = 0.0; /* when the neighbor count is smaller than 2, we return 0.0 */ if (neighbor_count < 2) { return IGRAPH_SUCCESS; } for (i=0; i < vertex_neis_size; ++i) { long int source = VECTOR(*vertex_neis)[i]; long int reached = 0; IGRAPH_ALLOW_INTERRUPTION(); if (source == vertex) continue; /* avoid processing a neighbour twice in multigraphs */ if (VECTOR(*nei_mask)[source] == 2) continue; VECTOR(*nei_mask)[source] = 2; /* mark as already processed */ igraph_2wheap_clear(Q); igraph_2wheap_push_with_index(Q, source, -1.0); while (!igraph_2wheap_empty(Q)) { long int minnei = igraph_2wheap_max_index(Q); igraph_real_t mindist = -igraph_2wheap_deactivate_max(Q); igraph_vector_int_t *neis; long int nlen; if (minnei != source && VECTOR(*nei_mask)[minnei]) { *res += 1.0/(mindist - 1.0); reached++; if (reached == neighbor_count) { igraph_2wheap_clear(Q); break; } } /* Now check all neighbors of 'minnei' for a shorter path */ neis = igraph_lazy_inclist_get(inclist, (igraph_integer_t) minnei); nlen = igraph_vector_int_size(neis); for (j = 0; j < nlen; j++) { igraph_real_t altdist, curdist; igraph_bool_t active, has; long int edge = (long int) VECTOR(*neis)[j]; long int tto = IGRAPH_OTHER(graph, edge, minnei); if (tto == vertex) continue; altdist = mindist + VECTOR(*weights)[edge]; active = igraph_2wheap_has_active(Q, tto); has = igraph_2wheap_has_elem(Q, tto); curdist = active ? -igraph_2wheap_get(Q, tto) : 0.0; if (!has) { /* This is the first non-infinite distance */ IGRAPH_CHECK(igraph_2wheap_push_with_index(Q, tto, -altdist)); } else if (altdist < curdist) { /* This is a shorter path */ IGRAPH_CHECK(igraph_2wheap_modify(Q, tto, -altdist)); } } } /* !igraph_2wheap_empty(&Q) */ } *res /= neighbor_count * (neighbor_count - 1.0); return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_local_efficiency * \brief Calculates the local efficiency around each vertex in a network. * * * The local efficiency of a network around a vertex is defined as follows: * We remove the vertex and compute the distances (shortest path lengths) between * its neighbours through the rest of the network. The local efficiency around the * removed vertex is the average of the inverse of these distances. * * * The inverse distance between two vertices which are not reachable from each other * is considered to be zero. The local efficiency around a vertex with fewer than two * neighbours is taken to be zero by convention. * * * Reference: * I. Vragović, E. Louis, and A. Díaz-Guilera, * Efficiency of informational transfer in regular and complex networks, * Phys. Rev. E 71, 1 (2005). * http://dx.doi.org/10.1103/PhysRevE.71.036122 * * \param graph The graph object. * \param res Pointer to an initialized vector, this will contain the result. * \param vids The vertices around which the local efficiency will be calculated. * \param weights The edge weights. All edge weights must be * non-negative. Additionally, no edge weight may be NaN. If either * case does not hold, an error is returned. If this is a null * pointer, then the unweighted version, * \ref igraph_average_path_length() is called. * \param directed Boolean, whether to consider directed paths. * Ignored for undirected graphs. * \param mode How to determine the local neighborhood of each vertex * in directed graphs. Ignored in undirected graphs. * \clist * \cli IGRAPH_ALL * take both in- and out-neighbours; * this is a reasonable default for high-level interfaces. * \cli IGRAPH_OUT * take only out-neighbours * \cli IGRAPH_IN * take only in-neighbours * \endclist * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for data structures * \cli IGRAPH_EINVAL * invalid weight vector * \endclist * * Time complexity: O(|E|^2 log|E|) for weighted graphs and * O(|E|^2) for unweighted ones. |E| denotes the number of edges. * * \sa \ref igraph_average_local_efficiency() * */ int igraph_local_efficiency(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, const igraph_vector_t *weights, igraph_bool_t directed, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int nodes_to_calc; /* no. of vertices includes in computation */ igraph_vit_t vit; igraph_vector_t vertex_neis; igraph_vector_char_t nei_mask; long int i; /* 'nei_mask' is a vector indexed by vertices. The meaning of its values is as follows: * 0: not a neighbour of 'vertex' * 1: a not-yet-processed neighbour of 'vertex' * 2: an already processed neighbour of 'vertex' * * Marking neighbours of already processed is necessary to avoid processing them more * than once in multigraphs. */ IGRAPH_CHECK(igraph_vector_char_init(&nei_mask, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_char_destroy, &nei_mask); IGRAPH_VECTOR_INIT_FINALLY(&vertex_neis, 0); IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); if (! weights) /* unweighted case */ { long int *already_counted; igraph_adjlist_t adjlist; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; already_counted = IGRAPH_CALLOC(no_of_nodes, long int); if (already_counted == 0) { IGRAPH_ERROR("Local efficiency calculation failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_counted); IGRAPH_CHECK(igraph_adjlist_init( graph, &adjlist, directed ? IGRAPH_OUT : IGRAPH_ALL, IGRAPH_LOOPS, IGRAPH_MULTIPLE )); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); for (IGRAPH_VIT_RESET(vit), i=0; ! IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { IGRAPH_CHECK(igraph_i_local_efficiency_unweighted( graph, &adjlist, &q, already_counted, &vertex_neis, &nei_mask, &(VECTOR(*res)[i]), IGRAPH_VIT_GET(vit), mode)); } igraph_dqueue_destroy(&q); igraph_adjlist_destroy(&adjlist); IGRAPH_FREE(already_counted); IGRAPH_FINALLY_CLEAN(3); } else /* weighted case */ { igraph_lazy_inclist_t inclist; igraph_2wheap_t Q; if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length does not match the number of edges", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t min = igraph_vector_min(weights); if (min < 0) { IGRAPH_ERROR("Weight vector must be non-negative", IGRAPH_EINVAL); } else if (igraph_is_nan(min)) { IGRAPH_ERROR("Weight vector must not contain NaN values", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_lazy_inclist_init( graph, &inclist, directed ? IGRAPH_OUT : IGRAPH_ALL, IGRAPH_LOOPS )); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); for (IGRAPH_VIT_RESET(vit), i=0; ! IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { IGRAPH_CHECK(igraph_i_local_efficiency_dijkstra( graph, &inclist, &Q, &vertex_neis, &nei_mask, &(VECTOR(*res)[i]), IGRAPH_VIT_GET(vit), mode, weights)); } igraph_2wheap_destroy(&Q); igraph_lazy_inclist_destroy(&inclist); IGRAPH_FINALLY_CLEAN(2); } igraph_vit_destroy(&vit); igraph_vector_destroy(&vertex_neis); igraph_vector_char_destroy(&nei_mask); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_average_local_efficiency * \brief Calculates the average local efficiency in a network. * * For the null graph, zero is returned by convention. * * \param graph The graph object. * \param res Pointer to a real number, this will contain the result. * \param weights The edge weights. They must be all non-negative. * If a null pointer is given, all weights are assumed to be 1. * \param directed Boolean, whether to consider directed paths. * Ignored for undirected graphs. * \param mode How to determine the local neighborhood of each vertex * in directed graphs. Ignored in undirected graphs. * \clist * \cli IGRAPH_ALL * take both in- and out-neighbours; * this is a reasonable default for high-level interfaces. * \cli IGRAPH_OUT * take only out-neighbours * \cli IGRAPH_IN * take only in-neighbours * \endclist * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for data structures * \cli IGRAPH_EINVAL * invalid weight vector * \endclist * * Time complexity: O(|E|^2 log|E|) for weighted graphs and * O(|E|^2) for unweighted ones. |E| denotes the number of edges. * * \sa \ref igraph_local_efficiency() * */ int igraph_average_local_efficiency(const igraph_t *graph, igraph_real_t *res, const igraph_vector_t *weights, igraph_bool_t directed, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t local_eff; /* If there are fewer than 3 vertices, no vertex has more than one neighbour, thus all local efficiencies are zero. For the null graph, we return zero by convention. */ if (no_of_nodes < 3) { *res = 0; return IGRAPH_SUCCESS; } IGRAPH_VECTOR_INIT_FINALLY(&local_eff, no_of_nodes); IGRAPH_CHECK(igraph_local_efficiency(graph, &local_eff, igraph_vss_all(), weights, directed, mode)); *res = igraph_vector_sum(&local_eff); *res /= no_of_nodes; igraph_vector_destroy(&local_eff); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /***************************/ /***** Graph diameter ******/ /***************************/ /** * \ingroup structural * \function igraph_diameter * \brief Calculates the diameter of a graph (longest geodesic). * * The diameter of a graph is the length of the longest shortest path it has. * This function computes both the diameter, as well as the corresponding path. * The diameter of the null graph is considered be infinity by convention. * * If the graph has no vertices, \c IGRAPH_NAN is returned. * * \param graph The graph object. * \param pres Pointer to a real number, if not \c NULL then it will contain * the diameter (the actual distance). * \param pfrom Pointer to an integer, if not \c NULL it will be set to the * source vertex of the diameter path. If the graph has no diameter path, * it will be set to -1. * \param pto Pointer to an integer, if not \c NULL it will be set to the * target vertex of the diameter path. If the graph has no diameter path, * it will be set to -1. * \param path Pointer to an initialized vector. If not \c NULL the actual * longest geodesic path will be stored here. The vector will be * resized as needed. * \param directed Boolean, whether to consider directed * paths. Ignored for undirected graphs. * \param unconn What to do if the graph is not connected. If * \c TRUE the longest geodesic within a component * will be returned, otherwise \c IGRAPH_INFINITY is returned. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * * Time complexity: O(|V||E|), the * number of vertices times the number of edges. * * \sa \ref igraph_diameter_dijkstra() * * \example examples/simple/igraph_diameter.c */ int igraph_diameter(const igraph_t *graph, igraph_real_t *pres, igraph_integer_t *pfrom, igraph_integer_t *pto, igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t unconn) { long int no_of_nodes = igraph_vcount(graph); long int i, j, n; long int *already_added; long int nodes_reached; long int from = 0, to = 0; igraph_real_t res = 0; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; igraph_vector_int_t *neis; igraph_neimode_t dirmode; igraph_adjlist_t allneis; /* See https://github.com/igraph/igraph/issues/1538#issuecomment-724071857 * for why we return NaN for the null graph. */ if (no_of_nodes == 0) { if (pres) { *pres = IGRAPH_NAN; } if (path) { igraph_vector_clear(path); } if (pfrom) { *pfrom = -1; } if (pto) { *pto = -1; } return IGRAPH_SUCCESS; } if (directed) { dirmode = IGRAPH_OUT; } else { dirmode = IGRAPH_ALL; } already_added = IGRAPH_CALLOC(no_of_nodes, long int); if (already_added == 0) { IGRAPH_ERROR("diameter failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_adjlist_init(graph, &allneis, dirmode, IGRAPH_LOOPS, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); for (i = 0; i < no_of_nodes; i++) { nodes_reached = 1; IGRAPH_CHECK(igraph_dqueue_push(&q, i)); IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); already_added[i] = i + 1; IGRAPH_PROGRESS("Diameter: ", 100.0 * i / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); if (actdist > res) { res = actdist; from = i; to = actnode; } neis = igraph_adjlist_get(&allneis, actnode); n = igraph_vector_int_size(neis); for (j = 0; j < n; j++) { long int neighbor = (long int) VECTOR(*neis)[j]; if (already_added[neighbor] == i + 1) { continue; } already_added[neighbor] = i + 1; nodes_reached++; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); } } /* while !igraph_dqueue_empty */ /* not connected, return IGRAPH_INFINITY */ if (nodes_reached != no_of_nodes && !unconn) { res = IGRAPH_INFINITY; from = -1; to = -1; break; } } /* for i 0) { igraph_real_t min = igraph_vector_min(weights); if (min < 0) { IGRAPH_ERROR("Weight vector must be non-negative", IGRAPH_EINVAL); } else if (igraph_is_nan(min)) { IGRAPH_ERROR("Weight vector must not contain NaN values", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, dirmode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); for (source = 0; source < no_of_nodes; source++) { IGRAPH_PROGRESS("Weighted diameter: ", source * 100.0 / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); igraph_2wheap_clear(&Q); igraph_2wheap_push_with_index(&Q, source, -1.0); nodes_reached = 0.0; while (!igraph_2wheap_empty(&Q)) { long int minnei = igraph_2wheap_max_index(&Q); igraph_real_t mindist = -igraph_2wheap_deactivate_max(&Q); igraph_vector_int_t *neis; long int nlen; if (mindist > res) { res = mindist; from = source; to = minnei; } nodes_reached++; /* Now check all neighbors of 'minnei' for a shorter path */ neis = igraph_inclist_get(&inclist, minnei); nlen = igraph_vector_int_size(neis); for (j = 0; j < nlen; j++) { long int edge = (long int) VECTOR(*neis)[j]; long int tto = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_bool_t active = igraph_2wheap_has_active(&Q, tto); igraph_bool_t has = igraph_2wheap_has_elem(&Q, tto); igraph_real_t curdist = active ? -igraph_2wheap_get(&Q, tto) : 0.0; if (!has) { /* First finite distance */ IGRAPH_CHECK(igraph_2wheap_push_with_index(&Q, tto, -altdist)); } else if (altdist < curdist) { /* A shorter path */ IGRAPH_CHECK(igraph_2wheap_modify(&Q, tto, -altdist)); } } } /* !igraph_2wheap_empty(&Q) */ /* not connected, return infinity */ if (nodes_reached != no_of_nodes && !unconn) { res = IGRAPH_INFINITY; from = to = -1; break; } } /* source < no_of_nodes */ /* Compensate for the +1 that we have added to distances */ res -= 1; igraph_inclist_destroy(&inclist); igraph_2wheap_destroy(&Q); IGRAPH_FINALLY_CLEAN(2); IGRAPH_PROGRESS("Weighted diameter: ", 100.0, NULL); if (pres) { *pres = res; } if (pfrom) { *pfrom = (igraph_integer_t) from; } if (pto) { *pto = (igraph_integer_t) to; } if (path) { if (!igraph_finite(res)) { igraph_vector_clear(path); } else { igraph_vector_ptr_t tmpptr; igraph_vector_ptr_init(&tmpptr, 1); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &tmpptr); VECTOR(tmpptr)[0] = path; IGRAPH_CHECK(igraph_get_shortest_paths_dijkstra(graph, /*vertices=*/ &tmpptr, /*edges=*/ 0, (igraph_integer_t) from, igraph_vss_1((igraph_integer_t) to), weights, dirmode, /*predecessors=*/ 0, /*inbound_edges=*/ 0)); igraph_vector_ptr_destroy(&tmpptr); IGRAPH_FINALLY_CLEAN(1); } } return 0; } leidenbase/src/core/paths/unweighted.c0000644000176200001440000004643714447675375017556 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_paths.h" #include "igraph_adjlist.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "core/interruption.h" /** * \ingroup structural * \function igraph_shortest_paths * \brief The length of the shortest paths between vertices. * * \param graph The graph object. * \param res The result of the calculation, a matrix. A pointer to an * initialized matrix, to be more precise. The matrix will be * resized if needed. It will have the same * number of rows as the length of the \c from * argument, and its number of columns is the number of * vertices in the \c to argument. One row of the matrix shows the * distances from/to a given vertex to the ones in \c to. * For the unreachable vertices IGRAPH_INFINITY is returned. * \param from The source vertices. * \param to The target vertices. It is not allowed to include a * vertex twice or more. * \param mode The type of shortest paths to be used for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the lengths of the outgoing paths are calculated. * \cli IGRAPH_IN * the lengths of the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an undirected one for * the computation. * \endclist * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary * data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(n(|V|+|E|)), * n is the * number of vertices to calculate, |V| and * |E| are the number of vertices and * edges in the graph. * * \sa \ref igraph_get_shortest_paths() to get the paths themselves, * \ref igraph_shortest_paths_dijkstra() for the weighted version. */ int igraph_shortest_paths(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); long int no_of_from, no_of_to; long int *already_counted; igraph_adjlist_t adjlist; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; igraph_vector_int_t *neis; igraph_bool_t all_to; long int i, j; igraph_vit_t fromvit, tovit; igraph_real_t my_infinity = IGRAPH_INFINITY; igraph_vector_t indexv; if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } IGRAPH_CHECK(igraph_vit_create(graph, from, &fromvit)); IGRAPH_FINALLY(igraph_vit_destroy, &fromvit); no_of_from = IGRAPH_VIT_SIZE(fromvit); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); already_counted = IGRAPH_CALLOC(no_of_nodes, long int); if (already_counted == 0) { IGRAPH_ERROR("shortest paths failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_counted); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); all_to = igraph_vs_is_all(&to); if (all_to) { no_of_to = no_of_nodes; } else { IGRAPH_VECTOR_INIT_FINALLY(&indexv, no_of_nodes); IGRAPH_CHECK(igraph_vit_create(graph, to, &tovit)); IGRAPH_FINALLY(igraph_vit_destroy, &tovit); no_of_to = IGRAPH_VIT_SIZE(tovit); for (i = 0; !IGRAPH_VIT_END(tovit); IGRAPH_VIT_NEXT(tovit)) { long int v = IGRAPH_VIT_GET(tovit); if (VECTOR(indexv)[v]) { IGRAPH_ERROR("Duplicate vertices in `to', this is not allowed", IGRAPH_EINVAL); } VECTOR(indexv)[v] = ++i; } } IGRAPH_CHECK(igraph_matrix_resize(res, no_of_from, no_of_to)); igraph_matrix_fill(res, my_infinity); for (IGRAPH_VIT_RESET(fromvit), i = 0; !IGRAPH_VIT_END(fromvit); IGRAPH_VIT_NEXT(fromvit), i++) { long int reached = 0; IGRAPH_CHECK(igraph_dqueue_push(&q, IGRAPH_VIT_GET(fromvit))); IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); already_counted[ (long int) IGRAPH_VIT_GET(fromvit) ] = i + 1; IGRAPH_ALLOW_INTERRUPTION(); while (!igraph_dqueue_empty(&q)) { long int act = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); if (all_to) { MATRIX(*res, i, act) = actdist; } else { if (VECTOR(indexv)[act]) { MATRIX(*res, i, (long int)(VECTOR(indexv)[act] - 1)) = actdist; reached++; if (reached == no_of_to) { igraph_dqueue_clear(&q); break; } } } neis = igraph_adjlist_get(&adjlist, act); long int nei_count = igraph_vector_int_size(neis); for (j = 0; j < nei_count; j++) { long int neighbor = (long int) VECTOR(*neis)[j]; if (already_counted[neighbor] == i + 1) { continue; } already_counted[neighbor] = i + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); } } } /* Clean */ if (!all_to) { igraph_vit_destroy(&tovit); igraph_vector_destroy(&indexv); IGRAPH_FINALLY_CLEAN(2); } IGRAPH_FREE(already_counted); igraph_dqueue_destroy(&q); igraph_vit_destroy(&fromvit); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(4); return 0; } /** * \ingroup structural * \function igraph_get_shortest_paths * \brief Shortest paths from a vertex. * * * If there is more than one geodesic between two vertices, this * function gives only one of them. * \param graph The graph object. * \param vertices The result, the ids of the vertices along the paths. * This is a pointer vector, each element points to a vector * object. These should be initialized before passing them to * the function, which will properly clear and/or resize them * and fill the ids of the vertices along the geodesics from/to * the vertices. Supply a null pointer here if you don't need * these vectors. * \param edges The result, the ids of the edges along the paths. * This is a pointer vector, each element points to a vector * object. These should be initialized before passing them to * the function, which will properly clear and/or resize them * and fill the ids of the vertices along the geodesics from/to * the vertices. Supply a null pointer here if you don't need * these vectors. * \param from The id of the vertex from/to which the geodesics are * calculated. * \param to Vertex sequence with the ids of the vertices to/from which the * shortest paths will be calculated. A vertex might be given multiple * times. * \param mode The type of shortest paths to be used for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing paths are calculated. * \cli IGRAPH_IN * the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an * undirected one for the computation. * \endclist * \param predecessors A pointer to an initialized igraph vector or null. * If not null, a vector containing the predecessor of each vertex in * the single source shortest path tree is returned here. The * predecessor of vertex i in the tree is the vertex from which vertex i * was reached. The predecessor of the start vertex (in the \c from * argument) is itself by definition. If the predecessor is -1, it means * that the given vertex was not reached from the source during the * search. Note that the search terminates if all the vertices in * \c to are reached. * \param inbound_edges A pointer to an initialized igraph vector or null. * If not null, a vector containing the inbound edge of each vertex in * the single source shortest path tree is returned here. The * inbound edge of vertex i in the tree is the edge via which vertex i * was reached. The start vertex and vertices that were not reached * during the search will have -1 in the corresponding entry of the * vector. Note that the search terminates if all the vertices in * \c to are reached. * * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * \p from is invalid vertex id, or the length of \p to is * not the same as the length of \p res. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(|V|+|E|), * |V| is the number of vertices, * |E| the number of edges in the * graph. * * \sa \ref igraph_shortest_paths() if you only need the path length but * not the paths themselves. * * \example examples/simple/igraph_get_shortest_paths.c */ int igraph_get_shortest_paths(const igraph_t *graph, igraph_vector_ptr_t *vertices, igraph_vector_ptr_t *edges, igraph_integer_t from, const igraph_vs_t to, igraph_neimode_t mode, igraph_vector_long_t *predecessors, igraph_vector_long_t *inbound_edges) { /* TODO: use inclist_t if to is long (longer than 1?) */ long int no_of_nodes = igraph_vcount(graph); long int *father; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; long int i, j, vsize; igraph_vector_t tmp = IGRAPH_VECTOR_NULL; igraph_vit_t vit; long int to_reach; long int reached = 0; if (from < 0 || from >= no_of_nodes) { IGRAPH_ERROR("cannot get shortest paths", IGRAPH_EINVVID); } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } IGRAPH_CHECK(igraph_vit_create(graph, to, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); if (vertices && IGRAPH_VIT_SIZE(vit) != igraph_vector_ptr_size(vertices)) { IGRAPH_ERROR("Size of the `vertices' and the `to' should match", IGRAPH_EINVAL); } if (edges && IGRAPH_VIT_SIZE(vit) != igraph_vector_ptr_size(edges)) { IGRAPH_ERROR("Size of the `edges' and the `to' should match", IGRAPH_EINVAL); } father = IGRAPH_CALLOC(no_of_nodes, long int); if (father == 0) { IGRAPH_ERROR("cannot get shortest paths", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, father); IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); /* Mark the vertices we need to reach */ to_reach = IGRAPH_VIT_SIZE(vit); for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { if (father[ (long int) IGRAPH_VIT_GET(vit) ] == 0) { father[ (long int) IGRAPH_VIT_GET(vit) ] = -1; } else { to_reach--; /* this node was given multiple times */ } } /* Meaning of father[i]: * * - If father[i] < 0, it means that vertex i has to be reached and has not * been reached yet. * * - If father[i] = 0, it means that vertex i does not have to be reached and * it has not been reached yet. * * - If father[i] = 1, it means that vertex i is the start vertex. * * - Otherwise, father[i] is the ID of the edge from which vertex i was * reached plus 2. */ IGRAPH_CHECK(igraph_dqueue_push(&q, from + 1)); if (father[ (long int) from ] < 0) { reached++; } father[ (long int)from ] = 1; while (!igraph_dqueue_empty(&q) && reached < to_reach) { long int act = (long int) igraph_dqueue_pop(&q) - 1; IGRAPH_CHECK(igraph_incident(graph, &tmp, (igraph_integer_t) act, mode)); vsize = igraph_vector_size(&tmp); for (j = 0; j < vsize; j++) { long int edge = (long int) VECTOR(tmp)[j]; long int neighbor = IGRAPH_OTHER(graph, edge, act); if (father[neighbor] > 0) { continue; } else if (father[neighbor] < 0) { reached++; } father[neighbor] = edge + 2; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor + 1)); } } if (reached < to_reach) { IGRAPH_WARNING("Couldn't reach some vertices"); } /* Create `predecessors' if needed */ if (predecessors) { IGRAPH_CHECK(igraph_vector_long_resize(predecessors, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { if (father[i] <= 0) { /* i was not reached */ VECTOR(*predecessors)[i] = -1; } else if (father[i] == 1) { /* i is the start vertex */ VECTOR(*predecessors)[i] = i; } else { /* i was reached via the edge with ID = father[i] - 2 */ VECTOR(*predecessors)[i] = IGRAPH_OTHER(graph, father[i] - 2, i); } } } /* Create `inbound_edges' if needed */ if (inbound_edges) { IGRAPH_CHECK(igraph_vector_long_resize(inbound_edges, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { if (father[i] <= 1) { /* i was not reached or i is the start vertex */ VECTOR(*inbound_edges)[i] = -1; } else { /* i was reached via the edge with ID = father[i] - 2 */ VECTOR(*inbound_edges)[i] = father[i] - 2; } } } /* Create `vertices' and `edges' if needed */ if (vertices || edges) { for (IGRAPH_VIT_RESET(vit), j = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), j++) { long int node = IGRAPH_VIT_GET(vit); igraph_vector_t *vvec = 0, *evec = 0; if (vertices) { vvec = VECTOR(*vertices)[j]; igraph_vector_clear(vvec); } if (edges) { evec = VECTOR(*edges)[j]; igraph_vector_clear(evec); } IGRAPH_ALLOW_INTERRUPTION(); if (father[node] > 0) { long int act = node; long int size = 0; long int edge; while (father[act] > 1) { size++; edge = father[act] - 2; act = IGRAPH_OTHER(graph, edge, act); } if (vvec) { IGRAPH_CHECK(igraph_vector_resize(vvec, size + 1)); VECTOR(*vvec)[size] = node; } if (evec) { IGRAPH_CHECK(igraph_vector_resize(evec, size)); } act = node; while (father[act] > 1) { size--; edge = father[act] - 2; act = IGRAPH_OTHER(graph, edge, act); if (vvec) { VECTOR(*vvec)[size] = act; } if (evec) { VECTOR(*evec)[size] = edge; } } } } } /* Clean */ IGRAPH_FREE(father); igraph_dqueue_destroy(&q); igraph_vector_destroy(&tmp); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(4); return 0; } /** * \function igraph_get_shortest_path * \brief Shortest path from one vertex to another one. * * Calculates and returns a single unweighted shortest path from a * given vertex to another one. If there are more than one shortest * paths between the two vertices, then an arbitrary one is returned. * * This function is a wrapper to \ref * igraph_get_shortest_paths(), for the special case when only one * target vertex is considered. * \param graph The input graph, it can be directed or * undirected. Directed paths are considered in directed * graphs. * \param vertices Pointer to an initialized vector or a null * pointer. If not a null pointer, then the vertex ids along * the path are stored here, including the source and target * vertices. * \param edges Pointer to an uninitialized vector or a null * pointer. If not a null pointer, then the edge ids along the * path are stored here. * \param from The id of the source vertex. * \param to The id of the target vertex. * \param mode A constant specifying how edge directions are * considered in directed graphs. Valid modes are: * \c IGRAPH_OUT, follows edge directions; * \c IGRAPH_IN, follows the opposite directions; and * \c IGRAPH_ALL, ignores edge directions. This argument is * ignored for undirected graphs. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges in the graph. * * \sa \ref igraph_get_shortest_paths() for the version with more target * vertices. */ int igraph_get_shortest_path(const igraph_t *graph, igraph_vector_t *vertices, igraph_vector_t *edges, igraph_integer_t from, igraph_integer_t to, igraph_neimode_t mode) { igraph_vector_ptr_t vertices2, *vp = &vertices2; igraph_vector_ptr_t edges2, *ep = &edges2; if (vertices) { IGRAPH_CHECK(igraph_vector_ptr_init(&vertices2, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &vertices2); VECTOR(vertices2)[0] = vertices; } else { vp = 0; } if (edges) { IGRAPH_CHECK(igraph_vector_ptr_init(&edges2, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &edges2); VECTOR(edges2)[0] = edges; } else { ep = 0; } IGRAPH_CHECK(igraph_get_shortest_paths(graph, vp, ep, from, igraph_vss_1(to), mode, 0, 0)); if (edges) { igraph_vector_ptr_destroy(&edges2); IGRAPH_FINALLY_CLEAN(1); } if (vertices) { igraph_vector_ptr_destroy(&vertices2); IGRAPH_FINALLY_CLEAN(1); } return 0; } leidenbase/src/core/paths/all_shortest_paths.c0000644000176200001440000002757314447675375021315 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_paths.h" #include "igraph_adjlist.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "core/interruption.h" #include /* memset */ static void igraph_i_gasp_paths_destroy(igraph_vector_ptr_t *v) { long int i; for (i = 0; i < igraph_vector_ptr_size(v); i++) { if (VECTOR(*v)[i] != 0) { igraph_vector_destroy(VECTOR(*v)[i]); IGRAPH_FREE(VECTOR(*v)[i]); } } igraph_vector_ptr_destroy(v); } /** * \function igraph_get_all_shortest_paths * \brief All shortest paths (geodesics) from a vertex. * * When there is more than one shortest path between two vertices, * all of them will be returned. * * \param graph The graph object. * \param res Pointer to an initialized pointer vector, the result * will be stored here in \ref igraph_vector_t objects. Each vector * object contains the vertices along a shortest path from \p from * to another vertex. The vectors are ordered according to their * target vertex: first the shortest paths to vertex 0, then to * vertex 1, etc. No data is included for unreachable vertices. * \param nrgeo Pointer to an initialized \ref igraph_vector_t object or * \c NULL. If not \c NULL the number of shortest paths from \p from are * stored here for every vertex in the graph. Note that the values * will be accurate only for those vertices that are in the target * vertex sequence (see \p to), since the search terminates as soon * as all the target vertices have been found. * \param from The id of the vertex from/to which the geodesics are * calculated. * \param to Vertex sequence with the ids of the vertices to/from which the * shortest paths will be calculated. A vertex might be given multiple * times. * \param mode The type of shortest paths to be use for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the lengths of the outgoing paths are calculated. * \cli IGRAPH_IN * the lengths of the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an * undirected one for the computation. * \endclist * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * \p from is invalid vertex id. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Added in version 0.2. * * Time complexity: O(|V|+|E|) for most graphs, O(|V|^2) in the worst * case. */ int igraph_get_all_shortest_paths(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_vector_t *nrgeo, igraph_integer_t from, const igraph_vs_t to, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); long int *geodist; igraph_vector_ptr_t paths; igraph_dqueue_t q; igraph_vector_t *vptr; igraph_vector_t neis; igraph_vector_t ptrlist; igraph_vector_t ptrhead; long int n, j, i; long int to_reach, reached = 0, maxdist = 0; igraph_vit_t vit; if (from < 0 || from >= no_of_nodes) { IGRAPH_ERROR("cannot get shortest paths", IGRAPH_EINVVID); } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } IGRAPH_CHECK(igraph_vit_create(graph, to, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); /* paths will store the shortest paths during the search */ IGRAPH_CHECK(igraph_vector_ptr_init(&paths, 0)); IGRAPH_FINALLY(igraph_i_gasp_paths_destroy, &paths); /* neis is a temporary vector holding the neighbors of the * node being examined */ IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); /* ptrlist stores indices into the paths vector, in the order * of how they were found. ptrhead is a second-level index that * will be used to find paths that terminate in a given vertex */ IGRAPH_VECTOR_INIT_FINALLY(&ptrlist, 0); /* ptrhead contains indices into ptrlist. * ptrhead[i] = j means that element #j-1 in ptrlist contains * the shortest path from the root to node i. ptrhead[i] = 0 * means that node i was not reached so far */ IGRAPH_VECTOR_INIT_FINALLY(&ptrhead, no_of_nodes); /* geodist[i] == 0 if i was not reached yet and it is not in the * target vertex sequence, or -1 if i was not reached yet and it * is in the target vertex sequence. Otherwise it is * one larger than the length of the shortest path from the * source */ geodist = IGRAPH_CALLOC(no_of_nodes, long int); if (geodist == 0) { IGRAPH_ERROR("Cannot calculate shortest paths", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, geodist); /* dequeue to store the BFS queue -- odd elements are the vertex indices, * even elements are the distances from the root */ IGRAPH_CHECK(igraph_dqueue_init(&q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &q); if (nrgeo) { IGRAPH_CHECK(igraph_vector_resize(nrgeo, no_of_nodes)); igraph_vector_null(nrgeo); } /* use geodist to count how many vertices we have to reach */ to_reach = IGRAPH_VIT_SIZE(vit); for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { if (geodist[ (long int) IGRAPH_VIT_GET(vit) ] == 0) { geodist[ (long int) IGRAPH_VIT_GET(vit) ] = -1; } else { to_reach--; /* this node was given multiple times */ } } if (geodist[ (long int) from ] < 0) { reached++; } /* from -> from */ vptr = IGRAPH_CALLOC(1, igraph_vector_t); /* TODO: dirty */ IGRAPH_CHECK(igraph_vector_ptr_push_back(&paths, vptr)); IGRAPH_CHECK(igraph_vector_init(vptr, 1)); VECTOR(*vptr)[0] = from; geodist[(long int)from] = 1; VECTOR(ptrhead)[(long int)from] = 1; IGRAPH_CHECK(igraph_vector_push_back(&ptrlist, 0)); if (nrgeo) { VECTOR(*nrgeo)[(long int)from] = 1; } /* Init queue */ IGRAPH_CHECK(igraph_dqueue_push(&q, from)); IGRAPH_CHECK(igraph_dqueue_push(&q, 0.0)); while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); IGRAPH_ALLOW_INTERRUPTION(); if (reached >= to_reach) { /* all nodes were reached. Since we need all the shortest paths * to all these nodes, we can stop the search only if the distance * of the current node to the root is larger than the distance of * any of the nodes we wanted to reach */ if (actdist > maxdist) { /* safety check, maxdist should have been set when we reached the last node */ if (maxdist < 0) { IGRAPH_ERROR("possible bug in igraph_get_all_shortest_paths, " "maxdist is negative", IGRAPH_EINVAL); } break; } } IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) actnode, mode)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { long int neighbor = (long int) VECTOR(neis)[j]; long int fatherptr; if (geodist[neighbor] > 0 && geodist[neighbor] - 1 < actdist + 1) { /* this node was reached via a shorter path before */ continue; } /* yay, found another shortest path to neighbor */ if (nrgeo) { /* the number of geodesics leading to neighbor must be * increased by the number of geodesics leading to actnode */ VECTOR(*nrgeo)[neighbor] += VECTOR(*nrgeo)[actnode]; } if (geodist[neighbor] <= 0) { /* this node was not reached yet, push it into the queue */ IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); if (geodist[neighbor] < 0) { reached++; } if (reached == to_reach) { maxdist = actdist; } } geodist[neighbor] = actdist + 2; /* copy all existing paths to the parent */ fatherptr = (long int) VECTOR(ptrhead)[actnode]; while (fatherptr != 0) { /* allocate a new igraph_vector_t at the end of paths */ vptr = IGRAPH_CALLOC(1, igraph_vector_t); IGRAPH_CHECK(igraph_vector_ptr_push_back(&paths, vptr)); IGRAPH_CHECK(igraph_vector_copy(vptr, VECTOR(paths)[fatherptr - 1])); IGRAPH_CHECK(igraph_vector_reserve(vptr, actdist + 2)); IGRAPH_CHECK(igraph_vector_push_back(vptr, neighbor)); IGRAPH_CHECK(igraph_vector_push_back(&ptrlist, VECTOR(ptrhead)[neighbor])); VECTOR(ptrhead)[neighbor] = igraph_vector_size(&ptrlist); fatherptr = (long int) VECTOR(ptrlist)[fatherptr - 1]; } } } igraph_dqueue_destroy(&q); IGRAPH_FINALLY_CLEAN(1); /* mark the nodes for which we need the result */ memset(geodist, 0, sizeof(long int) * (size_t) no_of_nodes); for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { geodist[ (long int) IGRAPH_VIT_GET(vit) ] = 1; } /* count the number of paths in the result */ n = 0; for (i = 0; i < no_of_nodes; i++) { long int fatherptr = (long int) VECTOR(ptrhead)[i]; if (geodist[i] > 0) { while (fatherptr != 0) { n++; fatherptr = (long int) VECTOR(ptrlist)[fatherptr - 1]; } } } IGRAPH_CHECK(igraph_vector_ptr_resize(res, n)); j = 0; for (i = 0; i < no_of_nodes; i++) { long int fatherptr = (long int) VECTOR(ptrhead)[i]; IGRAPH_ALLOW_INTERRUPTION(); /* do we need the paths leading to vertex i? */ if (geodist[i] > 0) { /* yes, copy them to the result vector */ while (fatherptr != 0) { VECTOR(*res)[j++] = VECTOR(paths)[fatherptr - 1]; fatherptr = (long int) VECTOR(ptrlist)[fatherptr - 1]; } } else { /* no, free them */ while (fatherptr != 0) { igraph_vector_destroy(VECTOR(paths)[fatherptr - 1]); IGRAPH_FREE(VECTOR(paths)[fatherptr - 1]); fatherptr = (long int) VECTOR(ptrlist)[fatherptr - 1]; } } } IGRAPH_FREE(geodist); igraph_vector_destroy(&ptrlist); igraph_vector_destroy(&ptrhead); igraph_vector_destroy(&neis); igraph_vector_ptr_destroy(&paths); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(6); return 0; } leidenbase/src/core/paths/johnson.c0000644000176200001440000001726314447675375017064 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_paths.h" #include "igraph_conversion.h" #include "igraph_interface.h" /** * \function igraph_shortest_paths_johnson * \brief Weighted shortest path lengths between vertices, using Johnson's algorithm. * * See Wikipedia at http://en.wikipedia.org/wiki/Johnson's_algorithm * for Johnson's algorithm. This algorithm works even if the graph * contains negative edge weights, and it is worth using it if we * calculate the shortest paths from many sources. * * * If no edge weights are supplied, then the unweighted * version, \ref igraph_shortest_paths() is called. * * * If all the supplied edge weights are non-negative, * then Dijkstra's algorithm is used by calling * \ref igraph_shortest_paths_dijkstra(). * * \param graph The input graph. If negative weights are present, it * should be directed. * \param res Pointer to an initialized matrix, the result will be * stored here, one line for each source vertex, one column for each * target vertex. * \param from The source vertices. * \param to The target vertices. It is not allowed to include a * vertex twice or more. * \param weights Optional edge weights. If it is a null-pointer, then * the unweighted breadth-first search based \ref * igraph_shortest_paths() will be called. * \return Error code. * * Time complexity: O(s|V|log|V|+|V||E|), |V| and |E| are the number * of vertices and edges, s is the number of source vertices. * * \sa \ref igraph_shortest_paths() for a faster unweighted version * or \ref igraph_shortest_paths_dijkstra() if you do not have negative * edge weights, \ref igraph_shortest_paths_bellman_ford() if you only * need to calculate shortest paths from a couple of sources. */ int igraph_shortest_paths_johnson(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, const igraph_vector_t *weights) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_t newgraph; igraph_vector_t edges, newweights; igraph_matrix_t bfres; long int i, ptr; long int nr, nc; igraph_vit_t fromvit; /* If no weights, then we can just run the unweighted version */ if (!weights) { return igraph_shortest_paths(graph, res, from, to, IGRAPH_OUT); } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length does not match", IGRAPH_EINVAL); } /* If no edges, then we can just run the unweighted version */ if (no_of_edges == 0) { return igraph_shortest_paths(graph, res, from, to, IGRAPH_OUT); } /* If no negative weights, then we can run Dijkstra's algorithm */ { igraph_real_t min_weight = igraph_vector_min(weights); if (igraph_is_nan(min_weight)) { IGRAPH_ERROR("Weight vector must not contain NaN values", IGRAPH_EINVAL); } if (min_weight >= 0) { return igraph_shortest_paths_dijkstra(graph, res, from, to, weights, IGRAPH_OUT); } } if (!igraph_is_directed(graph)) { IGRAPH_ERROR("Johnson's shortest path: undirected graph and negative weight", IGRAPH_EINVAL); } /* ------------------------------------------------------------ */ /* -------------------- Otherwise proceed --------------------- */ IGRAPH_MATRIX_INIT_FINALLY(&bfres, 0, 0); IGRAPH_VECTOR_INIT_FINALLY(&newweights, 0); IGRAPH_CHECK(igraph_empty(&newgraph, (igraph_integer_t) no_of_nodes + 1, igraph_is_directed(graph))); IGRAPH_FINALLY(igraph_destroy, &newgraph); /* Add a new node to the graph, plus edges from it to all the others. */ IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2 + no_of_nodes * 2); igraph_get_edgelist(graph, &edges, /*bycol=*/ 0); igraph_vector_resize(&edges, no_of_edges * 2 + no_of_nodes * 2); for (i = 0, ptr = no_of_edges * 2; i < no_of_nodes; i++) { VECTOR(edges)[ptr++] = no_of_nodes; VECTOR(edges)[ptr++] = i; } IGRAPH_CHECK(igraph_add_edges(&newgraph, &edges, 0)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_vector_reserve(&newweights, no_of_edges + no_of_nodes)); igraph_vector_update(&newweights, weights); igraph_vector_resize(&newweights, no_of_edges + no_of_nodes); for (i = no_of_edges; i < no_of_edges + no_of_nodes; i++) { VECTOR(newweights)[i] = 0; } /* Run Bellmann-Ford algorithm on the new graph, starting from the new vertex. */ IGRAPH_CHECK(igraph_shortest_paths_bellman_ford(&newgraph, &bfres, igraph_vss_1((igraph_integer_t) no_of_nodes), igraph_vss_all(), &newweights, IGRAPH_OUT)); igraph_destroy(&newgraph); IGRAPH_FINALLY_CLEAN(1); /* Now the edges of the original graph are reweighted, using the values from the BF algorithm. Instead of w(u,v) we will have w(u,v) + h(u) - h(v) */ igraph_vector_resize(&newweights, no_of_edges); for (i = 0; i < no_of_edges; i++) { long int ffrom = IGRAPH_FROM(graph, i); long int tto = IGRAPH_TO(graph, i); VECTOR(newweights)[i] += MATRIX(bfres, 0, ffrom) - MATRIX(bfres, 0, tto); } /* Run Dijkstra's algorithm on the new weights */ IGRAPH_CHECK(igraph_shortest_paths_dijkstra(graph, res, from, to, &newweights, IGRAPH_OUT)); igraph_vector_destroy(&newweights); IGRAPH_FINALLY_CLEAN(1); /* Reweight the shortest paths */ nr = igraph_matrix_nrow(res); nc = igraph_matrix_ncol(res); IGRAPH_CHECK(igraph_vit_create(graph, from, &fromvit)); IGRAPH_FINALLY(igraph_vit_destroy, &fromvit); for (i = 0; i < nr; i++, IGRAPH_VIT_NEXT(fromvit)) { long int v1 = IGRAPH_VIT_GET(fromvit); if (igraph_vs_is_all(&to)) { long int v2; for (v2 = 0; v2 < nc; v2++) { igraph_real_t sub = MATRIX(bfres, 0, v1) - MATRIX(bfres, 0, v2); MATRIX(*res, i, v2) -= sub; } } else { long int j; igraph_vit_t tovit; IGRAPH_CHECK(igraph_vit_create(graph, to, &tovit)); IGRAPH_FINALLY(igraph_vit_destroy, &tovit); for (j = 0, IGRAPH_VIT_RESET(tovit); j < nc; j++, IGRAPH_VIT_NEXT(tovit)) { long int v2 = IGRAPH_VIT_GET(tovit); igraph_real_t sub = MATRIX(bfres, 0, v1) - MATRIX(bfres, 0, v2); MATRIX(*res, i, j) -= sub; } igraph_vit_destroy(&tovit); IGRAPH_FINALLY_CLEAN(1); } } igraph_vit_destroy(&fromvit); igraph_matrix_destroy(&bfres); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } leidenbase/src/core/paths/distances.c0000644000176200001440000001642614447675375017363 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_paths.h" #include "igraph_datatype.h" #include "igraph_dqueue.h" #include "igraph_iterators.h" #include "igraph_vector.h" #include "igraph_interface.h" #include "igraph_adjlist.h" #include "core/interruption.h" static int igraph_i_eccentricity(const igraph_t *graph, igraph_vector_t *res, igraph_vs_t vids, igraph_neimode_t mode, const igraph_adjlist_t *adjlist) { int no_of_nodes = igraph_vcount(graph); igraph_dqueue_long_t q; igraph_vit_t vit; igraph_vector_int_t counted; int i, mark = 1; igraph_vector_t vneis; igraph_vector_int_t *neis; IGRAPH_CHECK(igraph_dqueue_long_init(&q, 100)); IGRAPH_FINALLY(igraph_dqueue_long_destroy, &q); IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_CHECK(igraph_vector_int_init(&counted, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &counted); if (!adjlist) { IGRAPH_VECTOR_INIT_FINALLY(&vneis, 0); } IGRAPH_CHECK(igraph_vector_resize(res, IGRAPH_VIT_SIZE(vit))); igraph_vector_fill(res, -1); for (i = 0, IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), mark++, i++) { long int source; source = IGRAPH_VIT_GET(vit); IGRAPH_CHECK(igraph_dqueue_long_push(&q, source)); IGRAPH_CHECK(igraph_dqueue_long_push(&q, 0)); VECTOR(counted)[source] = mark; IGRAPH_ALLOW_INTERRUPTION(); while (!igraph_dqueue_long_empty(&q)) { long int act = igraph_dqueue_long_pop(&q); long int dist = igraph_dqueue_long_pop(&q); int j, n; if (dist > VECTOR(*res)[i]) { VECTOR(*res)[i] = dist; } if (adjlist) { neis = igraph_adjlist_get(adjlist, act); n = (int) igraph_vector_int_size(neis); for (j = 0; j < n; j++) { int nei = (int) VECTOR(*neis)[j]; if (VECTOR(counted)[nei] != mark) { VECTOR(counted)[nei] = mark; IGRAPH_CHECK(igraph_dqueue_long_push(&q, nei)); IGRAPH_CHECK(igraph_dqueue_long_push(&q, dist + 1)); } } } else { IGRAPH_CHECK(igraph_neighbors(graph, &vneis, (igraph_integer_t) act, mode)); n = (int) igraph_vector_size(&vneis); for (j = 0; j < n; j++) { int nei = (int) VECTOR(vneis)[j]; if (VECTOR(counted)[nei] != mark) { VECTOR(counted)[nei] = mark; IGRAPH_CHECK(igraph_dqueue_long_push(&q, nei)); IGRAPH_CHECK(igraph_dqueue_long_push(&q, dist + 1)); } } } } /* while !igraph_dqueue_long_empty(dqueue) */ } /* for IGRAPH_VIT_NEXT(vit) */ if (!adjlist) { igraph_vector_destroy(&vneis); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_int_destroy(&counted); igraph_vit_destroy(&vit); igraph_dqueue_long_destroy(&q); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_eccentricity * \brief Eccentricity of some vertices. * * The eccentricity of a vertex is calculated by measuring the shortest * distance from (or to) the vertex, to (or from) all vertices in the * graph, and taking the maximum. * * * This implementation ignores vertex pairs that are in different * components. Isolated vertices have eccentricity zero. * * \param graph The input graph, it can be directed or undirected. * \param res Pointer to an initialized vector, the result is stored * here. * \param vids The vertices for which the eccentricity is calculated. * \param mode What kind of paths to consider for the calculation: * \c IGRAPH_OUT, paths that follow edge directions; * \c IGRAPH_IN, paths that follow the opposite directions; and * \c IGRAPH_ALL, paths that ignore edge directions. This argument * is ignored for undirected graphs. * \return Error code. * * Time complexity: O(v*(|V|+|E|)), where |V| is the number of * vertices, |E| is the number of edges and v is the number of * vertices for which eccentricity is calculated. * * \sa \ref igraph_radius(). * * \example examples/simple/igraph_eccentricity.c */ int igraph_eccentricity(const igraph_t *graph, igraph_vector_t *res, igraph_vs_t vids, igraph_neimode_t mode) { return igraph_i_eccentricity(graph, res, vids, mode, /*adjlist=*/ 0); } /** * \function igraph_radius * \brief Radius of a graph. * * The radius of a graph is the defined as the minimum eccentricity of * its vertices, see \ref igraph_eccentricity(). * * \param graph The input graph, it can be directed or undirected. * \param radius Pointer to a real variable, the result is stored * here. * \param mode What kind of paths to consider for the calculation: * \c IGRAPH_OUT, paths that follow edge directions; * \c IGRAPH_IN, paths that follow the opposite directions; and * \c IGRAPH_ALL, paths that ignore edge directions. This argument * is ignored for undirected graphs. * \return Error code. * * Time complexity: O(|V|(|V|+|E|)), where |V| is the number of * vertices and |E| is the number of edges. * * \sa \ref igraph_eccentricity(). * * \example examples/simple/igraph_radius.c */ int igraph_radius(const igraph_t *graph, igraph_real_t *radius, igraph_neimode_t mode) { int no_of_nodes = igraph_vcount(graph); if (no_of_nodes == 0) { *radius = IGRAPH_NAN; } else { igraph_adjlist_t adjlist; igraph_vector_t ecc; IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_VECTOR_INIT_FINALLY(&ecc, igraph_vcount(graph)); IGRAPH_CHECK(igraph_i_eccentricity(graph, &ecc, igraph_vss_all(), mode, &adjlist)); *radius = igraph_vector_min(&ecc); igraph_vector_destroy(&ecc); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(2); } return 0; } leidenbase/src/core/paths/eulerian.c0000644000176200001440000005415714447675375017215 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_eulerian.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_components.h" #include "igraph_stack.h" /** * \section about_eulerian * * These functions calculate whether an Eulerian path or cycle exists * and if so, can find them. */ /* solution adapted from https://www.geeksforgeeks.org/eulerian-path-and-circuit/ The function returns one of the following values has_path is set to 1 if a path exists, 0 otherwise has_cycle is set to 1 if a cycle exists, 0 otherwise */ static int igraph_i_is_eulerian_undirected(const igraph_t *graph, igraph_bool_t *has_path, igraph_bool_t *has_cycle, igraph_integer_t *start_of_path) { igraph_integer_t odd; igraph_vector_t degree, csize; /* boolean vector to mark singletons: */ igraph_vector_t nonsingleton; long int i, n, vsize; long int cluster_count; /* number of self-looping singletons: */ long int es; /* will be set to 1 if there are non-isolated vertices, otherwise 0: */ long int ens; n = igraph_vcount(graph); if (igraph_ecount(graph) == 0 || n <= 1) { start_of_path = 0; /* in case the graph has one vertex with self-loops */ *has_path = 1; *has_cycle = 1; return IGRAPH_SUCCESS; } /* check for connectedness, but singletons are special since they affect * the Eulerian nature only if there is a self-loop AND another edge * somewhere else in the graph */ IGRAPH_VECTOR_INIT_FINALLY(&csize, 0); IGRAPH_CHECK(igraph_clusters(graph, NULL, &csize, NULL, IGRAPH_WEAK)); cluster_count = 0; vsize = igraph_vector_size(&csize); for (i = 0; i < vsize; i++) { if (VECTOR(csize)[i] > 1) { cluster_count++; if (cluster_count > 1) { /* disconnected edges, they'll never reach each other */ *has_path = 0; *has_cycle = 0; igraph_vector_destroy(&csize); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } } } igraph_vector_destroy(&csize); IGRAPH_FINALLY_CLEAN(1); /* the graph is connected except for singletons */ /* find singletons (including those with self-loops) */ IGRAPH_VECTOR_INIT_FINALLY(&nonsingleton, 0); IGRAPH_CHECK(igraph_degree(graph, &nonsingleton, igraph_vss_all(), IGRAPH_ALL, IGRAPH_NO_LOOPS)); /* check the degrees for odd/even: * - >= 2 odd means no cycle (1 odd is impossible) * - > 2 odd means no path * plus there are a few corner cases with singletons */ IGRAPH_VECTOR_INIT_FINALLY(°ree, 0); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS)); odd = 0; es = 0; ens = 0; for (i = 0; i < n; i++) { long int deg = (long int) VECTOR(degree)[i]; /* Eulerian is about edges, so skip free vertices */ if (deg == 0) continue; if (!VECTOR(nonsingleton)[i]) { /* singleton with self loops */ es++; } else { /* at least one non-singleton */ ens = 1; /* note: self-loops count for two (in and out) */ if (deg % 2) odd++; } if (es + ens > 1) { /* 2+ singletons with self loops or singleton with self-loops and * 1+ edges in the non-singleton part of the graph. */ *has_path = 0; *has_cycle = 0; igraph_vector_destroy(&nonsingleton); igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } } igraph_vector_destroy(&nonsingleton); IGRAPH_FINALLY_CLEAN(1); /* this is the usual algorithm on the connected part of the graph */ if (odd > 2) { *has_path = 0; *has_cycle = 0; } else if (odd == 2) { *has_path = 1; *has_cycle = 0; } else { *has_path = 1; *has_cycle = 1; } /* set start of path if there is one but there is no cycle */ /* note: we cannot do this in the previous loop because at that time we are * not sure yet if a path exists */ for (i = 0; i < n; i++) { if ((*has_cycle && ((long int) VECTOR(degree)[i]) > 0) || (!*has_cycle && ((long int) VECTOR(degree)[i]) %2 == 1)) { *start_of_path = i; break; } } igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } static int igraph_i_is_eulerian_directed(const igraph_t *graph, igraph_bool_t *has_path, igraph_bool_t *has_cycle, igraph_integer_t *start_of_path) { igraph_integer_t incoming_excess, outgoing_excess, n; long int i, vsize; long int cluster_count; igraph_vector_t out_degree, in_degree, csize; /* boolean vector to mark singletons: */ igraph_vector_t nonsingleton; /* number of self-looping singletons: */ long int es; /* will be set to 1 if there are non-isolated vertices, otherwise 0: */ long int ens; n = igraph_vcount(graph); if (igraph_ecount(graph) == 0 || n <= 1) { start_of_path = 0; /* in case the graph has one vertex with self-loops */ *has_path = 1; *has_cycle = 1; return IGRAPH_SUCCESS; } incoming_excess = 0; outgoing_excess = 0; /* check for weak connectedness, but singletons are special since they affect * the Eulerian nature only if there is a self-loop AND another edge * somewhere else in the graph */ IGRAPH_VECTOR_INIT_FINALLY(&csize, 0); IGRAPH_CHECK(igraph_clusters(graph, NULL, &csize, NULL, IGRAPH_WEAK)); cluster_count = 0; vsize = igraph_vector_size(&csize); for (i = 0; i < vsize; i++) { if (VECTOR(csize)[i] > 1) { cluster_count++; if (cluster_count > 1) { /* weakly disconnected edges, they'll never reach each other */ *has_path = 0; *has_cycle = 0; igraph_vector_destroy(&csize); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } } } igraph_vector_destroy(&csize); IGRAPH_FINALLY_CLEAN(1); /* the graph is weakly connected except for singletons */ /* find the singletons (including those with self-loops) */ IGRAPH_VECTOR_INIT_FINALLY(&nonsingleton, 0); IGRAPH_CHECK(igraph_degree(graph, &nonsingleton, igraph_vss_all(), IGRAPH_ALL, IGRAPH_NO_LOOPS)); /* checking if no. of incoming edges == outgoing edges * plus there are a few corner cases with singletons */ IGRAPH_VECTOR_INIT_FINALLY(&out_degree, 0); IGRAPH_CHECK(igraph_degree(graph, &out_degree, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); IGRAPH_VECTOR_INIT_FINALLY(&in_degree, 0); IGRAPH_CHECK(igraph_degree(graph, &in_degree, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS)); es = 0; ens = 0; *start_of_path = -1; for (i = 0; i < n; i++) { long int degin = VECTOR(in_degree)[i]; long int degout = VECTOR(out_degree)[i]; /* Eulerian is about edges, so skip free vertices */ if (degin + degout == 0) continue; if (!VECTOR(nonsingleton)[i]) { /* singleton with self loops */ es++; /* if we ever want a path, it has to be this self-loop */ *start_of_path = i; } else { /* at least one non-singleton */ ens = 1; } if (es + ens > 1) { /* 2+ singletons with self loops or singleton with self-loops and * 1+ edges in the non-singleton part of the graph. */ *has_path = 0; *has_cycle = 0; igraph_vector_destroy(&nonsingleton); igraph_vector_destroy(&in_degree); igraph_vector_destroy(&out_degree); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /* as long as we have perfect balance, you can start * anywhere with an edge */ if (*start_of_path == -1 && incoming_excess == 0 && outgoing_excess == 0) { *start_of_path = i; } /* same in and out (including self-loops, even in singletons) */ if (degin == degout) { continue; } /* non-singleton, in != out */ if (degin > degout) { incoming_excess += degin - degout; } else { outgoing_excess += degout - degin; if (outgoing_excess == 1) { *start_of_path = i; } } /* too much imbalance, either of the following: * 1. 1+ vertices have 2+ in/out * 2. 2+ nodes have 1+ in/out */ if (incoming_excess > 1 || outgoing_excess > 1) { *has_path = 0; *has_cycle = 0; igraph_vector_destroy(&nonsingleton); igraph_vector_destroy(&in_degree); igraph_vector_destroy(&out_degree); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } } *has_path = 1; /* perfect edge balance -> strong connectivity */ *has_cycle = (incoming_excess == 0) && (outgoing_excess == 0); /* either way, the start was set already */ igraph_vector_destroy(&nonsingleton); igraph_vector_destroy(&in_degree); igraph_vector_destroy(&out_degree); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /** * \ingroup Eulerian * \function igraph_is_eulerian * \brief Checks whether an Eulerian path or cycle exists * * An Eulerian path traverses each edge of the graph precisely once. A closed * Eulerian path is referred to as an Eulerian cycle. * * \param graph The graph object. * \param has_path Pointer to a Boolean, will be set to true if an Eulerian path exists. * \param has_cycle Pointer to a Boolean, will be set to true if an Eulerian cycle exists. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * * Time complexity: O(|V|+|E|), the number of vertices plus the number of edges. * */ int igraph_is_eulerian(const igraph_t *graph, igraph_bool_t *has_path, igraph_bool_t *has_cycle) { igraph_integer_t start_of_path = 0; if (igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_is_eulerian_directed(graph, has_path, has_cycle, &start_of_path)); } else { IGRAPH_CHECK(igraph_i_is_eulerian_undirected(graph, has_path, has_cycle, &start_of_path)); } return IGRAPH_SUCCESS; } static int igraph_i_eulerian_path_undirected(const igraph_t *graph, igraph_vector_t *edge_res, igraph_vector_t *vertex_res, igraph_integer_t start_of_path) { long int curr; igraph_integer_t n, m; igraph_inclist_t il; igraph_stack_t path, tracker, edge_tracker, edge_path; igraph_vector_bool_t visited_list; igraph_vector_t degree; n = igraph_vcount(graph); m = igraph_ecount(graph); if (edge_res) { igraph_vector_clear(edge_res); } if (vertex_res) { igraph_vector_clear(vertex_res); } if (m == 0 || n == 0) { return IGRAPH_SUCCESS; } IGRAPH_VECTOR_INIT_FINALLY(°ree, 0); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_stack_init(&path, n)); IGRAPH_FINALLY(igraph_stack_destroy, &path); IGRAPH_CHECK(igraph_stack_init(&tracker, n)); IGRAPH_FINALLY(igraph_stack_destroy, &tracker); IGRAPH_CHECK(igraph_stack_init(&edge_path, n)); IGRAPH_FINALLY(igraph_stack_destroy, &edge_path); IGRAPH_CHECK(igraph_stack_init(&edge_tracker, n)); IGRAPH_FINALLY(igraph_stack_destroy, &edge_tracker); IGRAPH_VECTOR_BOOL_INIT_FINALLY(&visited_list, m); IGRAPH_CHECK(igraph_stack_push(&tracker, start_of_path)); IGRAPH_CHECK(igraph_inclist_init(graph, &il, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &il); curr = start_of_path; while (!igraph_stack_empty(&tracker)) { if (VECTOR(degree)[curr] != 0) { igraph_vector_int_t *incedges; long nc, edge = -1; long int j, next; IGRAPH_CHECK(igraph_stack_push(&tracker, curr)); incedges = igraph_inclist_get(&il, curr); nc = igraph_vector_int_size(incedges); IGRAPH_ASSERT(nc > 0); for (j = 0; j < nc; j++) { edge = (long) VECTOR(*incedges)[j]; if (!VECTOR(visited_list)[edge]) { break; } } next = IGRAPH_OTHER(graph, edge, curr); IGRAPH_CHECK(igraph_stack_push(&edge_tracker, edge)); /* remove edge here */ VECTOR(degree)[curr]--; VECTOR(degree)[next]--; VECTOR(visited_list)[edge] = 1; curr = next; } else { /* back track to find remaining circuit */ igraph_integer_t curr_e; IGRAPH_CHECK(igraph_stack_push(&path, curr)); curr = igraph_stack_pop(&tracker); if (!igraph_stack_empty(&edge_tracker)) { curr_e = igraph_stack_pop(&edge_tracker); IGRAPH_CHECK(igraph_stack_push(&edge_path, curr_e)); } } } if (edge_res) { IGRAPH_CHECK(igraph_vector_reserve(edge_res, m)); while (!igraph_stack_empty(&edge_path)) { IGRAPH_CHECK(igraph_vector_push_back(edge_res, igraph_stack_pop(&edge_path))); } } if (vertex_res) { IGRAPH_CHECK(igraph_vector_reserve(vertex_res, m+1)); while (!igraph_stack_empty(&path)) { IGRAPH_CHECK(igraph_vector_push_back(vertex_res, igraph_stack_pop(&path))); } } igraph_stack_destroy(&path); igraph_stack_destroy(&tracker); igraph_stack_destroy(&edge_path); igraph_stack_destroy(&edge_tracker); igraph_vector_bool_destroy(&visited_list); igraph_inclist_destroy(&il); igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(7); return IGRAPH_SUCCESS; } /* solution adapted from https://www.geeksforgeeks.org/hierholzers-algorithm-directed-graph/ */ static int igraph_i_eulerian_path_directed(const igraph_t *graph, igraph_vector_t *edge_res, igraph_vector_t *vertex_res, igraph_integer_t start_of_path) { long int curr; igraph_integer_t n, m; igraph_inclist_t il; igraph_stack_t path, tracker, edge_tracker, edge_path; igraph_vector_bool_t visited_list; igraph_vector_t remaining_out_edges; n = igraph_vcount(graph); m = igraph_ecount(graph); if (edge_res) { igraph_vector_clear(edge_res); } if (vertex_res) { igraph_vector_clear(vertex_res); } if (m == 0 || n == 0) { return IGRAPH_SUCCESS; } IGRAPH_CHECK(igraph_stack_init(&path, n)); IGRAPH_FINALLY(igraph_stack_destroy, &path); IGRAPH_CHECK(igraph_stack_init(&tracker, n)); IGRAPH_FINALLY(igraph_stack_destroy, &tracker); IGRAPH_CHECK(igraph_stack_init(&edge_path, n)); IGRAPH_FINALLY(igraph_stack_destroy, &edge_path); IGRAPH_CHECK(igraph_stack_init(&edge_tracker, n)); IGRAPH_FINALLY(igraph_stack_destroy, &edge_tracker); IGRAPH_VECTOR_BOOL_INIT_FINALLY(&visited_list, m); IGRAPH_CHECK(igraph_stack_push(&tracker, start_of_path)); IGRAPH_CHECK(igraph_inclist_init(graph, &il, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &il); IGRAPH_VECTOR_INIT_FINALLY(&remaining_out_edges, 0); IGRAPH_CHECK(igraph_degree(graph, &remaining_out_edges, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); curr = start_of_path; while (!igraph_stack_empty(&tracker)) { if (VECTOR(remaining_out_edges)[curr] != 0) { igraph_vector_int_t *incedges; long nc, edge = -1; long int j, next; IGRAPH_CHECK(igraph_stack_push(&tracker, curr)); incedges = igraph_inclist_get(&il, curr); nc = igraph_vector_int_size(incedges); IGRAPH_ASSERT(nc > 0); for (j = 0; j < nc; j++) { edge = (long) VECTOR(*incedges)[j]; if (!VECTOR(visited_list)[edge]) { break; } } next = IGRAPH_TO(graph, edge); IGRAPH_CHECK(igraph_stack_push(&edge_tracker, edge)); /* remove edge here */ VECTOR(remaining_out_edges)[curr]--; VECTOR(visited_list)[edge] = 1; curr = next; } else { /* back track to find remaining circuit */ igraph_integer_t curr_e; IGRAPH_CHECK(igraph_stack_push(&path, curr)); curr = igraph_stack_pop(&tracker); if (!igraph_stack_empty(&edge_tracker)) { curr_e = igraph_stack_pop(&edge_tracker); IGRAPH_CHECK(igraph_stack_push(&edge_path, curr_e)); } } } if (edge_res) { IGRAPH_CHECK(igraph_vector_reserve(edge_res, m)); while (!igraph_stack_empty(&edge_path)) { IGRAPH_CHECK(igraph_vector_push_back(edge_res, igraph_stack_pop(&edge_path))); } } if (vertex_res) { IGRAPH_CHECK(igraph_vector_reserve(vertex_res, m+1)); while (!igraph_stack_empty(&path)) { IGRAPH_CHECK(igraph_vector_push_back(vertex_res, igraph_stack_pop(&path))); } } igraph_stack_destroy(&path); igraph_stack_destroy(&tracker); igraph_stack_destroy(&edge_path); igraph_stack_destroy(&edge_tracker); igraph_vector_bool_destroy(&visited_list); igraph_inclist_destroy(&il); igraph_vector_destroy(&remaining_out_edges); IGRAPH_FINALLY_CLEAN(7); return IGRAPH_SUCCESS; } /** * \ingroup Eulerian * \function igraph_eulerian_cycle * \brief Finds an Eulerian cycle * * Finds an Eulerian cycle, if it exists. An Eulerian cycle is a closed path * that traverses each edge precisely once. * * * This function uses Hierholzer's algorithm. * * \param graph The graph object. * \param edge_res Pointer to an initialised vector. The indices of edges * belonging to the cycle will be stored here. May be \c NULL * if it is not needed by the caller. * \param vertex_res Pointer to an initialised vector. The indices of vertices * belonging to the cycle will be stored here. May be \c NULL * if it is not needed by the caller. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * graph does not have an Eulerian cycle. * \endclist * * Time complexity: O(|V|+|E|), the number of vertices plus the number of edges. * */ int igraph_eulerian_cycle(const igraph_t *graph, igraph_vector_t *edge_res, igraph_vector_t *vertex_res) { igraph_bool_t has_cycle; igraph_bool_t has_path; igraph_integer_t start_of_path = 0; if (igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_is_eulerian_directed(graph, &has_path, &has_cycle, &start_of_path)); if (!has_cycle) { IGRAPH_ERROR("The graph does not have an Eulerian cycle.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_i_eulerian_path_directed(graph, edge_res, vertex_res, start_of_path)); } else { IGRAPH_CHECK(igraph_i_is_eulerian_undirected(graph, &has_path, &has_cycle, &start_of_path)); if (!has_cycle) { IGRAPH_ERROR("The graph does not have an Eulerian cycle.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_i_eulerian_path_undirected(graph, edge_res, vertex_res, start_of_path)); } return IGRAPH_SUCCESS; } /** * \ingroup Eulerian * \function igraph_eulerian_path * \brief Finds an Eulerian path * * Finds an Eulerian path, if it exists. An Eulerian path traverses * each edge precisely once. * * * This function uses Hierholzer's algorithm. * * \param graph The graph object. * \param edge_res Pointer to an initialised vector. The indices of edges * belonging to the path will be stored here. May be \c NULL * if it is not needed by the caller. * \param vertex_res Pointer to an initialised vector. The indices of vertices * belonging to the path will be stored here. May be \c NULL * if it is not needed by the caller. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * graph does not have an Eulerian path. * \endclist * * Time complexity: O(|V|+|E|), the number of vertices plus the number of edges. * */ int igraph_eulerian_path(const igraph_t *graph, igraph_vector_t *edge_res, igraph_vector_t *vertex_res) { igraph_bool_t has_cycle; igraph_bool_t has_path; igraph_integer_t start_of_path = 0; if (igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_is_eulerian_directed(graph, &has_path, &has_cycle, &start_of_path)); if (!has_path) { IGRAPH_ERROR("The graph does not have an Eulerian path.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_i_eulerian_path_directed(graph, edge_res, vertex_res, start_of_path)); } else { IGRAPH_CHECK(igraph_i_is_eulerian_undirected(graph, &has_path, &has_cycle, &start_of_path)); if (!has_path) { IGRAPH_ERROR("The graph does not have an Eulerian path.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_i_eulerian_path_undirected(graph, edge_res, vertex_res, start_of_path)); } return IGRAPH_SUCCESS; } leidenbase/src/core/paths/bellman_ford.c0000644000176200001440000005457614447675375020042 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_paths.h" #include "igraph_adjlist.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_stack.h" #include "core/indheap.h" #include "core/interruption.h" #include /** * \function igraph_shortest_paths_bellman_ford * \brief Weighted shortest path lengths between vertices, allowing negative weights. * * This function implements the Bellman-Ford algorithm to find the weighted * shortest paths to all vertices from a single source, allowing negative weights. * It is run independently for the given sources. If there are no negative * weights, you are better off with \ref igraph_shortest_paths_dijkstra() . * * \param graph The input graph, can be directed. * \param res The result, a matrix. A pointer to an initialized matrix * should be passed here, the matrix will be resized if needed. * Each row contains the distances from a single source, to all * vertices in the graph, in the order of vertex ids. For unreachable * vertices the matrix contains \c IGRAPH_INFINITY. * \param from The source vertices. * \param to The target vertices. It is not allowed to include a * vertex twice or more. * \param weights The edge weights. There mustn't be any closed loop in * the graph that has a negative total weight (since this would allow * us to decrease the weight of any path containing at least a single * vertex of this loop infinitely). Additionally, no edge weight may * be NaN. If either case does not hold, an error is returned. If this * is a null pointer, then the unweighted version, * \ref igraph_shortest_paths() is called. * \param mode For directed graphs; whether to follow paths along edge * directions (\c IGRAPH_OUT), or the opposite (\c IGRAPH_IN), or * ignore edge directions completely (\c IGRAPH_ALL). It is ignored * for undirected graphs. * \return Error code. * * Time complexity: O(s*|E|*|V|), where |V| is the number of * vertices, |E| the number of edges and s the number of sources. * * \sa \ref igraph_shortest_paths() for a faster unweighted version * or \ref igraph_shortest_paths_dijkstra() if you do not have negative * edge weights. * * \example examples/simple/bellman_ford.c */ int igraph_shortest_paths_bellman_ford(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_lazy_inclist_t inclist; long int i, j, k; long int no_of_from, no_of_to; igraph_dqueue_t Q; igraph_vector_t clean_vertices; igraph_vector_t num_queued; igraph_vit_t fromvit, tovit; igraph_real_t my_infinity = IGRAPH_INFINITY; igraph_bool_t all_to; igraph_vector_t dist; /* - speedup: a vertex is marked clean if its distance from the source did not change during the last phase. Neighbors of a clean vertex are not relaxed again, since it would mean no change in the shortest path values. Dirty vertices are queued. Negative loops can be detected by checking whether a vertex has been queued at least n times. */ if (!weights) { return igraph_shortest_paths(graph, res, from, to, mode); } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length does not match", IGRAPH_EINVAL); } if (no_of_edges > 0 && igraph_vector_is_any_nan(weights)) { IGRAPH_ERROR("Weight vector must not contain NaN values", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vit_create(graph, from, &fromvit)); IGRAPH_FINALLY(igraph_vit_destroy, &fromvit); no_of_from = IGRAPH_VIT_SIZE(fromvit); IGRAPH_DQUEUE_INIT_FINALLY(&Q, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&clean_vertices, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&num_queued, no_of_nodes); IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &inclist, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); all_to = igraph_vs_is_all(&to); if (all_to) { no_of_to = no_of_nodes; } else { IGRAPH_CHECK(igraph_vit_create(graph, to, &tovit)); IGRAPH_FINALLY(igraph_vit_destroy, &tovit); no_of_to = IGRAPH_VIT_SIZE(tovit); } IGRAPH_VECTOR_INIT_FINALLY(&dist, no_of_nodes); IGRAPH_CHECK(igraph_matrix_resize(res, no_of_from, no_of_to)); for (IGRAPH_VIT_RESET(fromvit), i = 0; !IGRAPH_VIT_END(fromvit); IGRAPH_VIT_NEXT(fromvit), i++) { long int source = IGRAPH_VIT_GET(fromvit); igraph_vector_fill(&dist, my_infinity); VECTOR(dist)[source] = 0; igraph_vector_null(&clean_vertices); igraph_vector_null(&num_queued); /* Fill the queue with vertices to be checked */ for (j = 0; j < no_of_nodes; j++) { IGRAPH_CHECK(igraph_dqueue_push(&Q, j)); } while (!igraph_dqueue_empty(&Q)) { igraph_vector_int_t *neis; long int nlen; j = (long int) igraph_dqueue_pop(&Q); VECTOR(clean_vertices)[j] = 1; VECTOR(num_queued)[j] += 1; if (VECTOR(num_queued)[j] > no_of_nodes) { IGRAPH_ERROR("cannot run Bellman-Ford algorithm", IGRAPH_ENEGLOOP); } /* If we cannot get to j in finite time yet, there is no need to relax * its edges */ if (!IGRAPH_FINITE(VECTOR(dist)[j])) { continue; } neis = igraph_lazy_inclist_get(&inclist, (igraph_integer_t) j); nlen = igraph_vector_int_size(neis); for (k = 0; k < nlen; k++) { long int nei = (long int) VECTOR(*neis)[k]; long int target = IGRAPH_OTHER(graph, nei, j); if (VECTOR(dist)[target] > VECTOR(dist)[j] + VECTOR(*weights)[nei]) { /* relax the edge */ VECTOR(dist)[target] = VECTOR(dist)[j] + VECTOR(*weights)[nei]; if (VECTOR(clean_vertices)[target]) { VECTOR(clean_vertices)[target] = 0; IGRAPH_CHECK(igraph_dqueue_push(&Q, target)); } } } } /* Copy it to the result */ if (all_to) { igraph_matrix_set_row(res, &dist, i); } else { for (IGRAPH_VIT_RESET(tovit), j = 0; !IGRAPH_VIT_END(tovit); IGRAPH_VIT_NEXT(tovit), j++) { long int v = IGRAPH_VIT_GET(tovit); MATRIX(*res, i, j) = VECTOR(dist)[v]; } } } igraph_vector_destroy(&dist); IGRAPH_FINALLY_CLEAN(1); if (!all_to) { igraph_vit_destroy(&tovit); IGRAPH_FINALLY_CLEAN(1); } igraph_vit_destroy(&fromvit); igraph_dqueue_destroy(&Q); igraph_vector_destroy(&clean_vertices); igraph_vector_destroy(&num_queued); igraph_lazy_inclist_destroy(&inclist); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \ingroup structural * \function igraph_get_shortest_paths_bellman_ford * \brief Weighted shortest paths from a vertex, allowing negative weights. * * This function calculates weighted shortest paths from or to a single vertex, * and allows negative weights. When there is more than one shortest path between * two vertices, only one of them is returned. * * If there are no negative weights, you are better off with * \ref igraph_get_shortest_paths_dijkstra() . * * \param graph The input graph, can be directed. * \param vertices The result, the ids of the vertices along the paths. * This is a pointer vector, each element points to a vector * object. These should be initialized before passing them to * the function, which will properly clear and/or resize them * and fill the ids of the vertices along the geodesics from/to * the vertices. Supply a null pointer here if you don't need * these vectors. Normally, either this argument, or the \c * edges should be non-null, but no error or warning is given * if they are both null pointers. * \param edges The result, the ids of the edges along the paths. * This is a pointer vector, each element points to a vector * object. These should be initialized before passing them to * the function, which will properly clear and/or resize them * and fill the ids of the vertices along the geodesics from/to * the vertices. Supply a null pointer here if you don't need * these vectors. Normally, either this argument, or the \c * vertices should be non-null, but no error or warning is given * if they are both null pointers. * \param from The id of the vertex from/to which the geodesics are * calculated. * \param to Vertex sequence with the ids of the vertices to/from which the * shortest paths will be calculated. A vertex might be given multiple * times. * \param weights The edge weights. There mustn't be any closed loop in * the graph that has a negative total weight (since this would allow * us to decrease the weight of any path containing at least a single * vertex of this loop infinitely). If this is a null pointer, then the * unweighted version, \ref igraph_shortest_paths() is called. * \param mode For directed graphs; whether to follow paths along edge * directions (\c IGRAPH_OUT), or the opposite (\c IGRAPH_IN), or * ignore edge directions completely (\c IGRAPH_ALL). It is ignored * for undirected graphs. * \param predecessors A pointer to an initialized igraph vector or null. * If not null, a vector containing the predecessor of each vertex in * the single source shortest path tree is returned here. The * predecessor of vertex i in the tree is the vertex from which vertex i * was reached. The predecessor of the start vertex (in the \c from * argument) is itself by definition. If the predecessor is -1, it means * that the given vertex was not reached from the source during the * search. Note that the search terminates if all the vertices in * \c to are reached. * \param inbound_edges A pointer to an initialized igraph vector or null. * If not null, a vector containing the inbound edge of each vertex in * the single source shortest path tree is returned here. The * inbound edge of vertex i in the tree is the edge via which vertex i * was reached. The start vertex and vertices that were not reached * during the search will have -1 in the corresponding entry of the * vector. Note that the search terminates if all the vertices in * \c to are reached. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * Not enough memory for temporary data. * \cli IGRAPH_EINVAL * The weight vector doesn't math the number of edges. * \cli IGRAPH_EINVVID * \p from is invalid vertex id, or the length of \p to is * not the same as the length of \p vertices or \p edges. * \cli IGRAPH_ENEGLOOP * Bellman-ford algorithm encounted a negative loop. * \endclist * * Time complexity: O(|E|*|V|), where |V| is the number of * vertices, |E| the number of edges. * * \sa \ref igraph_shortest_paths() for a faster unweighted version * or \ref igraph_shortest_paths_dijkstra() if you do not have negative * edge weights. */ int igraph_get_shortest_paths_bellman_ford(const igraph_t *graph, igraph_vector_ptr_t *vertices, igraph_vector_ptr_t *edges, igraph_integer_t from, igraph_vs_t to, const igraph_vector_t *weights, igraph_neimode_t mode, igraph_vector_long_t *predecessors, igraph_vector_long_t *inbound_edges) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int *parents; igraph_lazy_inclist_t inclist; long int i, j, k; igraph_dqueue_t Q; igraph_vector_t clean_vertices; igraph_vector_t num_queued; igraph_vit_t tovit; igraph_real_t my_infinity = IGRAPH_INFINITY; igraph_vector_t dist; if (!weights) { return igraph_get_shortest_paths(graph, vertices, edges, from, to, mode, predecessors, inbound_edges); } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length must match number of edges.", IGRAPH_EINVAL); } IGRAPH_DQUEUE_INIT_FINALLY(&Q, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&clean_vertices, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&num_queued, no_of_nodes); IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &inclist, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); IGRAPH_CHECK(igraph_vit_create(graph, to, &tovit)); IGRAPH_FINALLY(igraph_vit_destroy, &tovit); if (vertices && IGRAPH_VIT_SIZE(tovit) != igraph_vector_ptr_size(vertices)) { IGRAPH_ERROR("Size of `vertices' and `to' should match.", IGRAPH_EINVAL); } if (edges && IGRAPH_VIT_SIZE(tovit) != igraph_vector_ptr_size(edges)) { IGRAPH_ERROR("Size of `edges' and `to' should match.", IGRAPH_EINVAL); } parents = IGRAPH_CALLOC(no_of_nodes, long int); if (parents == 0) { IGRAPH_ERROR("Insufficient memory for shortest paths with Bellman-Ford.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, parents); IGRAPH_VECTOR_INIT_FINALLY(&dist, no_of_nodes); igraph_vector_fill(&dist, my_infinity); VECTOR(dist)[from] = 0; igraph_vector_null(&clean_vertices); igraph_vector_null(&num_queued); /* Fill the queue with vertices to be checked */ for (j = 0; j < no_of_nodes; j++) { IGRAPH_CHECK(igraph_dqueue_push(&Q, j)); } while (!igraph_dqueue_empty(&Q)) { igraph_vector_int_t *neis; long int nlen; j = (long int) igraph_dqueue_pop(&Q); VECTOR(clean_vertices)[j] = 1; VECTOR(num_queued)[j] += 1; if (VECTOR(num_queued)[j] > no_of_nodes) { IGRAPH_ERROR("cannot run Bellman-Ford algorithm", IGRAPH_ENEGLOOP); } /* If we cannot get to j in finite time yet, there is no need to relax * its edges */ if (!IGRAPH_FINITE(VECTOR(dist)[j])) { continue; } neis = igraph_lazy_inclist_get(&inclist, (igraph_integer_t) j); nlen = igraph_vector_int_size(neis); for (k = 0; k < nlen; k++) { long int nei = (long int) VECTOR(*neis)[k]; long int target = IGRAPH_OTHER(graph, nei, j); if (VECTOR(dist)[target] > VECTOR(dist)[j] + VECTOR(*weights)[nei]) { /* relax the edge */ VECTOR(dist)[target] = VECTOR(dist)[j] + VECTOR(*weights)[nei]; parents[target] = nei + 1; if (VECTOR(clean_vertices)[target]) { VECTOR(clean_vertices)[target] = 0; IGRAPH_CHECK(igraph_dqueue_push(&Q, target)); } } } } /* Create `predecessors' if needed */ if (predecessors) { IGRAPH_CHECK(igraph_vector_long_resize(predecessors, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { if (i == from) { /* i is the start vertex */ VECTOR(*predecessors)[i] = i; } else if (parents[i] <= 0) { /* i was not reached */ VECTOR(*predecessors)[i] = -1; } else { /* i was reached via the edge with ID = parents[i] - 1 */ VECTOR(*predecessors)[i] = IGRAPH_OTHER(graph, parents[i] - 1, i); } } } /* Create `inbound_edges' if needed */ if (inbound_edges) { IGRAPH_CHECK(igraph_vector_long_resize(inbound_edges, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { if (parents[i] <= 0) { /* i was not reached */ VECTOR(*inbound_edges)[i] = -1; } else { /* i was reached via the edge with ID = parents[i] - 1 */ VECTOR(*inbound_edges)[i] = parents[i] - 1; } } } /* Reconstruct the shortest paths based on vertex and/or edge IDs */ if (vertices || edges) { for (IGRAPH_VIT_RESET(tovit), i = 0; !IGRAPH_VIT_END(tovit); IGRAPH_VIT_NEXT(tovit), i++) { long int node = IGRAPH_VIT_GET(tovit); long int size, act, edge; igraph_vector_t *vvec = 0, *evec = 0; if (vertices) { vvec = VECTOR(*vertices)[i]; igraph_vector_clear(vvec); } if (edges) { evec = VECTOR(*edges)[i]; igraph_vector_clear(evec); } IGRAPH_ALLOW_INTERRUPTION(); size = 0; act = node; while (parents[act]) { size++; edge = parents[act] - 1; act = IGRAPH_OTHER(graph, edge, act); } if (vvec && (size > 0 || node == from)) { IGRAPH_CHECK(igraph_vector_resize(vvec, size + 1)); VECTOR(*vvec)[size] = node; } if (evec) { IGRAPH_CHECK(igraph_vector_resize(evec, size)); } act = node; while (parents[act]) { edge = parents[act] - 1; act = IGRAPH_OTHER(graph, edge, act); size--; if (vvec) { VECTOR(*vvec)[size] = act; } if (evec) { VECTOR(*evec)[size] = edge; } } } } igraph_vector_destroy(&dist); IGRAPH_FINALLY_CLEAN(1); igraph_vit_destroy(&tovit); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FREE(parents); igraph_dqueue_destroy(&Q); igraph_vector_destroy(&clean_vertices); igraph_vector_destroy(&num_queued); igraph_lazy_inclist_destroy(&inclist); IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; } /** * \function igraph_get_shortest_path_bellman_ford * \brief Weighted shortest path from one vertex to another one. * * Calculates a single (positively) weighted shortest path from * a single vertex to another one, using Bellman-Ford algorithm. * * * This function is a special case (and a wrapper) to * \ref igraph_get_shortest_paths_bellman_ford(). * * \param graph The input graph, it can be directed or undirected. * \param vertices Pointer to an initialized vector or a null * pointer. If not a null pointer, then the vertex ids along * the path are stored here, including the source and target * vertices. * \param edges Pointer to an uninitialized vector or a null * pointer. If not a null pointer, then the edge ids along the * path are stored here. * \param from The id of the source vertex. * \param to The id of the target vertex. * \param weights The edge weights. There mustn't be any closed loop in * the graph that has a negative total weight (since this would allow * us to decrease the weight of any path containing at least a single * vertex of this loop infinitely). If this is a null pointer, then the * unweighted version is called. * \param mode A constant specifying how edge directions are * considered in directed graphs. \c IGRAPH_OUT follows edge * directions, \c IGRAPH_IN follows the opposite directions, * and \c IGRAPH_ALL ignores edge directions. This argument is * ignored for undirected graphs. * \return Error code. * * Time complexity: O(|E|log|E|+|V|), |V| is the number of vertices, * |E| is the number of edges in the graph. * * \sa \ref igraph_get_shortest_paths_bellman_ford() for the version with * more target vertices. */ int igraph_get_shortest_path_bellman_ford(const igraph_t *graph, igraph_vector_t *vertices, igraph_vector_t *edges, igraph_integer_t from, igraph_integer_t to, const igraph_vector_t *weights, igraph_neimode_t mode) { igraph_vector_ptr_t vertices2, *vp = &vertices2; igraph_vector_ptr_t edges2, *ep = &edges2; if (vertices) { IGRAPH_CHECK(igraph_vector_ptr_init(&vertices2, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &vertices2); VECTOR(vertices2)[0] = vertices; } else { vp = NULL; } if (edges) { IGRAPH_CHECK(igraph_vector_ptr_init(&edges2, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &edges2); VECTOR(edges2)[0] = edges; } else { ep = NULL; } IGRAPH_CHECK(igraph_get_shortest_paths_bellman_ford(graph, vp, ep, from, igraph_vss_1(to), weights, mode, NULL, NULL)); if (edges) { igraph_vector_ptr_destroy(&edges2); IGRAPH_FINALLY_CLEAN(1); } if (vertices) { igraph_vector_ptr_destroy(&vertices2); IGRAPH_FINALLY_CLEAN(1); } return IGRAPH_SUCCESS; } leidenbase/src/core/core/0000755000176200001440000000000014532173045015020 5ustar liggesusersleidenbase/src/core/core/progress.c0000644000176200001440000001343514447675374017057 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_progress.h" #include "config.h" static IGRAPH_THREAD_LOCAL igraph_progress_handler_t *igraph_i_progress_handler = 0; static IGRAPH_THREAD_LOCAL char igraph_i_progressmsg_buffer[1000]; /** * \function igraph_progress * Report progress * * Note that the usual way to report progress is the \ref IGRAPH_PROGRESS * macro, as that takes care of the return value of the progress * handler. * \param message A string describing the function or algorithm * that is reporting the progress. Current igraph functions * always use the name \p message argument if reporting from the * same function. * \param percent Numeric, the percentage that was completed by the * algorithm or function. * \param data User-defined data. Current igraph functions that * report progress pass a null pointer here. Users can * write their own progress handlers and functions with progress * reporting, and then pass some meaningfull context here. * \return If there is a progress handler installed and * it does not return \c IGRAPH_SUCCESS, then \c IGRAPH_INTERRUPTED * is returned. * * Time complexity: O(1). */ int igraph_progress(const char *message, igraph_real_t percent, void *data) { if (igraph_i_progress_handler) { if (igraph_i_progress_handler(message, percent, data) != IGRAPH_SUCCESS) { return IGRAPH_INTERRUPTED; } } return IGRAPH_SUCCESS; } /** * \function igraph_progressf * Report progress, printf-like version * * This is a more flexible version of \ref igraph_progress(), with * a printf-like template string. First the template string * is filled with the additional arguments and then \ref * igraph_progress() is called. * * Note that there is an upper limit for the length of * the \p message string, currently 1000 characters. * \param message A string describing the function or algorithm * that is reporting the progress. For this function this is a * template string, using the same syntax as the standard * \c libc \c printf function. * \param percent Numeric, the percentage that was completed by the * algorithm or function. * \param data User-defined data. Current igraph functions that * report progress pass a null pointer here. Users can * write their own progress handlers and functions with progress * reporting, and then pass some meaningfull context here. * \param ... Additional argument that were specified in the * \p message argument. * \return If there is a progress handler installed and * it does not return \c IGRAPH_SUCCESS, then \c IGRAPH_INTERRUPTED * is returned. * \return */ int igraph_progressf(const char *message, igraph_real_t percent, void *data, ...) { va_list ap; va_start(ap, data); vsnprintf(igraph_i_progressmsg_buffer, sizeof(igraph_i_progressmsg_buffer) / sizeof(char), message, ap); return igraph_progress(igraph_i_progressmsg_buffer, percent, data); } #ifndef USING_R /** * \function igraph_progress_handler_stderr * \brief A simple predefined progress handler. * * This simple progress handler first prints \p message, and then * the percentage complete value in a short message to standard error. * \param message A string describing the function or algorithm * that is reporting the progress. Current igraph functions * always use the same \p message argument if reporting from the * same function. * \param percent Numeric, the percentage that was completed by the * algorithm or function. * \param data User-defined data. Current igraph functions that * report progress pass a null pointer here. Users can * write their own progress handlers and functions with progress * reporting, and then pass some meaningfull context here. * \return This function always returns with \c IGRAPH_SUCCESS. * * Time complexity: O(1). */ int igraph_progress_handler_stderr(const char *message, igraph_real_t percent, void* data) { IGRAPH_UNUSED(data); fputs(message, stderr); fprintf(stderr, "%.1f percent ready.\n", percent); return IGRAPH_SUCCESS; } #endif /** * \function igraph_set_progress_handler * \brief Install a progress handler, or remove the current handler. * * There is a single simple predefined progress handler: * \ref igraph_progress_handler_stderr(). * \param new_handler Pointer to a function of type * \ref igraph_progress_handler_t, the progress handler function to * install. To uninstall the current progress handler, this argument * can be a null pointer. * \return Pointer to the previously installed progress handler function. * * Time complexity: O(1). */ igraph_progress_handler_t * igraph_set_progress_handler(igraph_progress_handler_t new_handler) { igraph_progress_handler_t *previous_handler = igraph_i_progress_handler; igraph_i_progress_handler = new_handler; return previous_handler; } leidenbase/src/core/core/cutheap.h0000644000176200001440000000436314447675374016651 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CORE_CUTHEAP_H #define IGRAPH_CORE_CUTHEAP_H #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS /* empty */ #define __END_DECLS /* empty */ #endif #include "igraph_types.h" #include "igraph_vector.h" __BEGIN_DECLS /* Special maximum heap, needed for the minimum cut algorithm */ typedef struct igraph_i_cutheap_t { igraph_vector_t heap; igraph_vector_t index; igraph_vector_t hptr; long int dnodes; } igraph_i_cutheap_t; IGRAPH_PRIVATE_EXPORT int igraph_i_cutheap_init(igraph_i_cutheap_t *ch, igraph_integer_t nodes); IGRAPH_PRIVATE_EXPORT void igraph_i_cutheap_destroy(igraph_i_cutheap_t *ch); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_i_cutheap_empty(igraph_i_cutheap_t *ch); IGRAPH_PRIVATE_EXPORT igraph_integer_t igraph_i_cutheap_active_size(igraph_i_cutheap_t *ch); IGRAPH_PRIVATE_EXPORT igraph_integer_t igraph_i_cutheap_size(igraph_i_cutheap_t *ch); IGRAPH_PRIVATE_EXPORT igraph_real_t igraph_i_cutheap_maxvalue(igraph_i_cutheap_t *ch); IGRAPH_PRIVATE_EXPORT igraph_integer_t igraph_i_cutheap_popmax(igraph_i_cutheap_t *ch); IGRAPH_PRIVATE_EXPORT int igraph_i_cutheap_update(igraph_i_cutheap_t *ch, igraph_integer_t index, igraph_real_t add); IGRAPH_PRIVATE_EXPORT int igraph_i_cutheap_reset_undefine(igraph_i_cutheap_t *ch, long int vertex); __END_DECLS #endif leidenbase/src/core/core/error.c0000644000176200001440000003307414453302741016323 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include "igraph_error.h" #include "igraph_types.h" #include #include #include /* Detecting ASan with GCC: * https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html * Detecting ASan with Clang: * https://clang.llvm.org/docs/AddressSanitizer.html#conditional-compilation-with-has-feature-address-sanitizer */ #if defined(__SANITIZE_ADDRESS__) # define IGRAPH_SANITIZER_AVAILABLE 1 #elif defined(__has_feature) # if __has_feature(address_sanitizer) # define IGRAPH_SANITIZER_AVAILABLE 1 # endif #endif #ifdef IGRAPH_SANITIZER_AVAILABLE #include #endif #ifdef USING_R #include #endif /***** Helper functions *****/ /* All calls to abort() in this compilation unit must go through igraph_abort(), * in order to make it easy for igraph's R interface to not have any reference to abort(), * which is disallowed by CRAN. * * Since the R interface sets its own error / fatal error handlers, this function * is never actually called by it. * * Note that some of the other #ifndef USING_R's in this file are still needed * to avoid references to fprintf and stderr. */ static IGRAPH_NORETURN void igraph_abort(void) { #ifndef USING_R #ifdef IGRAPH_SANITIZER_AVAILABLE fprintf(stderr, "\nStack trace:\n"); __sanitizer_print_stack_trace(); #endif abort(); #else /* R's error() function is declared 'noreturn'. We use it here to satisfy the compiler that igraph_abort() does indeed not return. */ error("igraph_abort() was called. This should never happen. Please report this as an igraph bug, along with steps to reproduce it."); #endif } /***** Handling errors *****/ static IGRAPH_THREAD_LOCAL igraph_error_handler_t *igraph_i_error_handler = 0; static IGRAPH_THREAD_LOCAL char igraph_i_errormsg_buffer[500]; static IGRAPH_THREAD_LOCAL char igraph_i_warningmsg_buffer[500]; static IGRAPH_THREAD_LOCAL char igraph_i_fatalmsg_buffer[500]; /* Error strings corresponding to each igraph_error_type_t enum value. */ static const char *igraph_i_error_strings[] = { /* 0 */ "No error", /* 1 */ "Failed", /* 2 */ "Out of memory", /* 3 */ "Parse error", /* 4 */ "Invalid value", /* 5 */ "Already exists", /* 6 */ "Invalid edge vector", /* 7 */ "Invalid vertex id", /* 8 */ "Non-square matrix", /* 9 */ "Invalid mode", /* 10 */ "File operation error", /* 11 */ "Unfold infinite iterator", /* 12 */ "Unimplemented function call", /* 13 */ "Interrupted", /* 14 */ "Numeric procedure did not converge", /* 15 */ "Matrix-vector product failed", /* 16 */ "N must be positive", /* 17 */ "NEV must be positive", /* 18 */ "NCV must be greater than NEV and less than or equal to N " "(and for the non-symmetric solver NCV-NEV >=2 must also hold)", /* 19 */ "Maximum number of iterations should be positive", /* 20 */ "Invalid WHICH parameter", /* 21 */ "Invalid BMAT parameter", /* 22 */ "WORKL is too small", /* 23 */ "LAPACK error in tridiagonal eigenvalue calculation", /* 24 */ "Starting vector is zero", /* 25 */ "MODE is invalid", /* 26 */ "MODE and BMAT are not compatible", /* 27 */ "ISHIFT must be 0 or 1", /* 28 */ "NEV and WHICH='BE' are incompatible", /* 29 */ "Could not build an Arnoldi factorization", /* 30 */ "No eigenvalues to sufficient accuracy", /* 31 */ "HOWMNY is invalid", /* 32 */ "HOWMNY='S' is not implemented", /* 33 */ "Different number of converged Ritz values", /* 34 */ "Error from calculation of a real Schur form", /* 35 */ "LAPACK (dtrevc) error for calculating eigenvectors", /* 36 */ "Unknown ARPACK error", /* 37 */ "Negative loop detected while calculating shortest paths", /* 38 */ "Internal error, likely a bug in igraph", /* 39 */ "Maximum number of iterations reached", /* 40 */ "No shifts could be applied during a cycle of the " "Implicitly restarted Arnoldi iteration. One possibility " "is to increase the size of NCV relative to NEV", /* 41 */ "The Schur form computed by LAPACK routine dlahqr " "could not be reordered by LAPACK routine dtrsen.", /* 42 */ "Big integer division by zero", /* 43 */ "GLPK Error, GLP_EBOUND", /* 44 */ "GLPK Error, GLP_EROOT", /* 45 */ "GLPK Error, GLP_ENOPFS", /* 46 */ "GLPK Error, GLP_ENODFS", /* 47 */ "GLPK Error, GLP_EFAIL", /* 48 */ "GLPK Error, GLP_EMIPGAP", /* 49 */ "GLPK Error, GLP_ETMLIM", /* 50 */ "GLPK Error, GLP_STOP", /* 51 */ "Internal attribute handler error", /* 52 */ "Unimplemented attribute combination for this type", /* 53 */ "LAPACK call resulted in an error", /* 54 */ "Internal DrL error", /* 55 */ "Integer or double overflow", /* 56 */ "Internal GPLK error", /* 57 */ "CPU time exceeded", /* 58 */ "Integer or double underflow", /* 59 */ "Random walk got stuck", /* 60 */ "Search stopped; this error should never be visible to the user, " "please report this error along with the steps to reproduce it." }; const char* igraph_strerror(const int igraph_errno) { if (igraph_errno < 0 || ((unsigned long)igraph_errno) >= sizeof(igraph_i_error_strings) / sizeof(char *)) { return "Invalid error code; no error string available."; } return igraph_i_error_strings[igraph_errno]; } int igraph_error(const char *reason, const char *file, int line, int igraph_errno) { if (igraph_i_error_handler) { igraph_i_error_handler(reason, file, line, igraph_errno); #ifndef USING_R } else { igraph_error_handler_abort(reason, file, line, igraph_errno); #endif } return igraph_errno; } int igraph_errorf(const char *reason, const char *file, int line, int igraph_errno, ...) { va_list ap; va_start(ap, igraph_errno); vsnprintf(igraph_i_errormsg_buffer, sizeof(igraph_i_errormsg_buffer) / sizeof(char), reason, ap); return igraph_error(igraph_i_errormsg_buffer, file, line, igraph_errno); } int igraph_errorvf(const char *reason, const char *file, int line, int igraph_errno, va_list ap) { vsnprintf(igraph_i_errormsg_buffer, sizeof(igraph_i_errormsg_buffer) / sizeof(char), reason, ap); return igraph_error(igraph_i_errormsg_buffer, file, line, igraph_errno); } #ifndef USING_R void igraph_error_handler_abort(const char *reason, const char *file, int line, int igraph_errno) { fprintf(stderr, "Error at %s:%i : %s - %s.\n", file, line, reason, igraph_strerror(igraph_errno)); igraph_abort(); } #endif void igraph_error_handler_ignore(const char *reason, const char *file, int line, int igraph_errno) { IGRAPH_UNUSED(reason); IGRAPH_UNUSED(file); IGRAPH_UNUSED(line); IGRAPH_UNUSED(igraph_errno); IGRAPH_FINALLY_FREE(); } #ifndef USING_R void igraph_error_handler_printignore(const char *reason, const char *file, int line, int igraph_errno) { fprintf(stderr, "Error at %s:%i : %s - %s.\n", file, line, reason, igraph_strerror(igraph_errno)); IGRAPH_FINALLY_FREE(); } #endif igraph_error_handler_t *igraph_set_error_handler(igraph_error_handler_t *new_handler) { igraph_error_handler_t *previous_handler = igraph_i_error_handler; igraph_i_error_handler = new_handler; return previous_handler; } /***** "Finally" stack *****/ IGRAPH_THREAD_LOCAL struct igraph_i_protectedPtr igraph_i_finally_stack[100]; /* * Adds another element to the free list */ void IGRAPH_FINALLY_REAL(void (*func)(void*), void* ptr) { int no = igraph_i_finally_stack[0].all; IGRAPH_ASSERT(no < 100); IGRAPH_ASSERT(no >= 0); igraph_i_finally_stack[no].ptr = ptr; igraph_i_finally_stack[no].func = func; igraph_i_finally_stack[0].all ++; /* printf("--> Finally stack contains now %d elements\n", igraph_i_finally_stack[0].all); */ } void IGRAPH_FINALLY_CLEAN(int minus) { igraph_i_finally_stack[0].all -= minus; if (igraph_i_finally_stack[0].all < 0) { int left = igraph_i_finally_stack[0].all + minus; /* Set to zero in case fatal error handler does a longjmp instead of terminating the process: */ igraph_i_finally_stack[0].all = 0; IGRAPH_FATALF("Corrupt finally stack: trying to pop %d element(s) when only %d left.", minus, left); } /* printf("<-- Finally stack contains now %d elements\n", igraph_i_finally_stack[0].all); */ } void IGRAPH_FINALLY_FREE(void) { int p; /* printf("[X] Finally stack will be cleaned (contained %d elements)\n", igraph_i_finally_stack[0].all); */ for (p = igraph_i_finally_stack[0].all - 1; p >= 0; p--) { igraph_i_finally_stack[p].func(igraph_i_finally_stack[p].ptr); } igraph_i_finally_stack[0].all = 0; } int IGRAPH_FINALLY_STACK_SIZE(void) { return igraph_i_finally_stack[0].all; } /***** Handling warnings *****/ static IGRAPH_THREAD_LOCAL igraph_warning_handler_t *igraph_i_warning_handler = 0; /** * \function igraph_warning_handler_ignore * \brief Ignores all warnings. * * This warning handler function simply ignores all warnings. * \param reason Textual description of the warning. * \param file The source file in which the warning was noticed. * \param line The number of line in the source file which triggered the * warning.. * \param igraph_errno Warnings could have potentially error codes as well, * but this is currently not used in igraph. */ void igraph_warning_handler_ignore(const char *reason, const char *file, int line, int igraph_errno) { IGRAPH_UNUSED(reason); IGRAPH_UNUSED(file); IGRAPH_UNUSED(line); IGRAPH_UNUSED(igraph_errno); } #ifndef USING_R /** * \function igraph_warning_handler_print * \brief Prints all warnings to the standard error. * * This warning handler function simply prints all warnings to the * standard error. * \param reason Textual description of the warning. * \param file The source file in which the warning was noticed. * \param line The number of line in the source file which triggered the * warning.. * \param igraph_errno Warnings could have potentially error codes as well, * but this is currently not used in igraph. */ void igraph_warning_handler_print(const char *reason, const char *file, int line, int igraph_errno) { IGRAPH_UNUSED(igraph_errno); fprintf(stderr, "Warning at %s:%i : %s\n", file, line, reason); } #endif int igraph_warning(const char *reason, const char *file, int line, int igraph_errno) { if (igraph_i_warning_handler) { igraph_i_warning_handler(reason, file, line, igraph_errno); #ifndef USING_R } else { igraph_warning_handler_print(reason, file, line, igraph_errno); #endif } return igraph_errno; } int igraph_warningf(const char *reason, const char *file, int line, int igraph_errno, ...) { va_list ap; va_start(ap, igraph_errno); vsnprintf(igraph_i_warningmsg_buffer, sizeof(igraph_i_warningmsg_buffer) / sizeof(char), reason, ap); return igraph_warning(igraph_i_warningmsg_buffer, file, line, igraph_errno); } igraph_warning_handler_t *igraph_set_warning_handler(igraph_warning_handler_t *new_handler) { igraph_warning_handler_t *previous_handler = igraph_i_warning_handler; igraph_i_warning_handler = new_handler; return previous_handler; } /***** Handling fatal errors *****/ static IGRAPH_THREAD_LOCAL igraph_fatal_handler_t *igraph_i_fatal_handler = NULL; igraph_fatal_handler_t *igraph_set_fatal_handler(igraph_fatal_handler_t *new_handler) { igraph_fatal_handler_t *previous_handler = igraph_i_fatal_handler; igraph_i_fatal_handler = new_handler; return previous_handler; } #ifndef USING_R void igraph_fatal_handler_abort(const char *reason, const char *file, int line) { fprintf(stderr, "Fatal error at %s:%i : %s\n", file, line, reason); igraph_abort(); } #endif void igraph_fatal(const char *reason, const char *file, int line) { if (igraph_i_fatal_handler) { igraph_i_fatal_handler(reason, file, line); #ifndef USING_R } else { igraph_fatal_handler_abort(reason, file, line); #endif } /* The following line should never be reached, as fatal error handlers are not supposed to return. It is here to satisfy the compiler that this function indeed does not return. */ igraph_abort(); } void igraph_fatalf(const char *reason, const char *file, int line, ...) { va_list ap; va_start(ap, line); vsnprintf(igraph_i_fatalmsg_buffer, sizeof(igraph_i_fatalmsg_buffer) / sizeof(char), reason, ap); va_end(ap); igraph_fatal(igraph_i_fatalmsg_buffer, file, line); } leidenbase/src/core/core/buckets.h0000644000176200001440000000534014447675374016654 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CORE_BUCKETS_H #define IGRAPH_CORE_BUCKETS_H #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS /* empty */ #define __END_DECLS /* empty */ #endif #include "igraph_types.h" #include "igraph_vector.h" __BEGIN_DECLS /* Buckets, needed for the maximum flow algorithm */ typedef struct igraph_buckets_t { igraph_vector_long_t bptr; igraph_vector_long_t buckets; igraph_integer_t max, no; } igraph_buckets_t; int igraph_buckets_init(igraph_buckets_t *b, long int bsize, long int size); void igraph_buckets_destroy(igraph_buckets_t *b); void igraph_buckets_clear(igraph_buckets_t *b); long int igraph_buckets_popmax(igraph_buckets_t *b); long int igraph_buckets_pop(igraph_buckets_t *b, long int bucket); igraph_bool_t igraph_buckets_empty(const igraph_buckets_t *b); igraph_bool_t igraph_buckets_empty_bucket(const igraph_buckets_t *b, long int bucket); void igraph_buckets_add(igraph_buckets_t *b, long int bucket, long int elem); typedef struct igraph_dbuckets_t { igraph_vector_long_t bptr; igraph_vector_long_t next, prev; igraph_integer_t max, no; } igraph_dbuckets_t; int igraph_dbuckets_init(igraph_dbuckets_t *b, long int bsize, long int size); void igraph_dbuckets_destroy(igraph_dbuckets_t *b); void igraph_dbuckets_clear(igraph_dbuckets_t *b); long int igraph_dbuckets_popmax(igraph_dbuckets_t *b); long int igraph_dbuckets_pop(igraph_dbuckets_t *b, long int bucket); igraph_bool_t igraph_dbuckets_empty(const igraph_dbuckets_t *b); igraph_bool_t igraph_dbuckets_empty_bucket(const igraph_dbuckets_t *b, long int bucket); void igraph_dbuckets_add(igraph_dbuckets_t *b, long int bucket, long int elem); void igraph_dbuckets_delete(igraph_dbuckets_t *b, long int bucket, long int elem); __END_DECLS #endif leidenbase/src/core/core/vector_ptr.c0000644000176200001440000005056114447675374017403 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_vector_ptr.h" #include "igraph_memory.h" #include "igraph_error.h" #include "igraph_qsort.h" #include /* memcpy & co. */ #include /** * \section about_igraph_vector_ptr_objects Pointer vectors * (igraph_vector_ptr_t) * * The \type igraph_vector_ptr_t data type is very similar to * the \ref igraph_vector_t type, but it stores generic pointers instead of * real numbers. * * This type has the same space complexity as \ref * igraph_vector_t, and most implemented operations work the same way * as for \ref igraph_vector_t. * * This type is mostly used to pass to or receive from a set of * graphs to some \a igraph functions, such as \ref * igraph_decompose(), which decomposes a graph to connected * components. * * The same \ref VECTOR macro used for ordinary vectors can be * used for pointer vectors as well, please note that a typeless * generic pointer will be provided by this macro and you may need to * cast it to a specific pointer before starting to work with it. * * Pointer vectors may have an associated item destructor function * which takes a pointer and returns nothing. The item destructor will * be called on each item in the pointer vector when it is destroyed by * \ref igraph_vector_ptr_destroy() or \ref igraph_vector_ptr_destroy_all(), * or when its elements are freed by \ref igraph_vector_ptr_free_all(). * Note that the semantics of an item destructor does not coincide with * C++ destructors; for instance, when a pointer vector is resized to a * smaller size, the extra items will \em not be destroyed automatically! * Nevertheless, item destructors may become handy in many cases; for * instance, a vector of graphs generated by \ref igraph_decompose() can * be destroyed with a single call to \ref igraph_vector_ptr_destroy_all() * if the item destructor is set to \ref igraph_destroy(). */ /** * \ingroup vectorptr * \function igraph_vector_ptr_init * \brief Initialize a pointer vector (constructor). * * * This is the constructor of the pointer vector data type. All * pointer vectors constructed this way should be destroyed via * calling \ref igraph_vector_ptr_destroy(). * \param v Pointer to an uninitialized * igraph_vector_ptr_t object, to be created. * \param size Integer, the size of the pointer vector. * \return Error code: * \c IGRAPH_ENOMEM if out of memory * * Time complexity: operating system dependent, the amount of \quote * time \endquote required to allocate \p size elements. */ int igraph_vector_ptr_init(igraph_vector_ptr_t* v, int long size) { long int alloc_size = size > 0 ? size : 1; IGRAPH_ASSERT(v != NULL); if (size < 0) { size = 0; } v->stor_begin = IGRAPH_CALLOC(alloc_size, void*); if (v->stor_begin == 0) { IGRAPH_ERROR("vector ptr init failed", IGRAPH_ENOMEM); } v->stor_end = v->stor_begin + alloc_size; v->end = v->stor_begin + size; v->item_destructor = 0; return 0; } /** */ const igraph_vector_ptr_t *igraph_vector_ptr_view(const igraph_vector_ptr_t *v, void *const *data, long int length) { igraph_vector_ptr_t *v2 = (igraph_vector_ptr_t*) v; v2->stor_begin = (void **)data; v2->stor_end = (void**)data + length; v2->end = v2->stor_end; v2->item_destructor = 0; return v; } /** * \ingroup vectorptr * \function igraph_vector_ptr_destroy * \brief Destroys a pointer vector. * * * The destructor for pointer vectors. * \param v Pointer to the pointer vector to destroy. * * Time complexity: operating system dependent, the \quote time * \endquote required to deallocate O(n) bytes, n is the number of * elements allocated for the pointer vector (not necessarily the * number of elements in the vector). */ void igraph_vector_ptr_destroy(igraph_vector_ptr_t* v) { IGRAPH_ASSERT(v != 0); if (v->stor_begin != 0) { IGRAPH_FREE(v->stor_begin); v->stor_begin = NULL; } } static void igraph_i_vector_ptr_call_item_destructor_all(igraph_vector_ptr_t* v) { void **ptr; if (v->item_destructor != 0) { for (ptr = v->stor_begin; ptr < v->end; ptr++) { if (*ptr != 0) { v->item_destructor(*ptr); } } } } /** * \ingroup vectorptr * \function igraph_vector_ptr_free_all * \brief Frees all the elements of a pointer vector. * * If an item destructor is set for this pointer vector, this function will * first call the destructor on all elements of the vector and then * free all the elements using \ref igraph_free(). If an item destructor is not set, * the elements will simply be freed. * * \param v Pointer to the pointer vector whose elements will be freed. * * Time complexity: operating system dependent, the \quote time * \endquote required to call the destructor n times and then * deallocate O(n) pointers, each pointing to a memory area of * arbitrary size. n is the number of elements in the pointer vector. */ void igraph_vector_ptr_free_all(igraph_vector_ptr_t* v) { void **ptr; IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->stor_begin != 0); igraph_i_vector_ptr_call_item_destructor_all(v); for (ptr = v->stor_begin; ptr < v->end; ptr++) { IGRAPH_FREE(*ptr); } } /** * \ingroup vectorptr * \function igraph_vector_ptr_destroy_all * \brief Frees all the elements and destroys the pointer vector. * * This function is equivalent to \ref igraph_vector_ptr_free_all() * followed by \ref igraph_vector_ptr_destroy(). * * \param v Pointer to the pointer vector to destroy. * * Time complexity: operating system dependent, the \quote time * \endquote required to deallocate O(n) pointers, each pointing to * a memory area of arbitrary size, plus the \quote time \endquote * required to deallocate O(n) bytes, n being the number of elements * allocated for the pointer vector (not necessarily the number of * elements in the vector). */ void igraph_vector_ptr_destroy_all(igraph_vector_ptr_t* v) { IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->stor_begin != 0); igraph_vector_ptr_free_all(v); igraph_vector_ptr_set_item_destructor(v, 0); igraph_vector_ptr_destroy(v); } /** * \ingroup vectorptr * \brief Reserves memory for a pointer vector for later use. * * @return Error code: * - IGRAPH_ENOMEM: out of memory */ int igraph_vector_ptr_reserve(igraph_vector_ptr_t* v, long int size) { long int actual_size = igraph_vector_ptr_size(v); void **tmp; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); if (size <= igraph_vector_ptr_size(v)) { return 0; } tmp = IGRAPH_REALLOC(v->stor_begin, (size_t) size, void*); if (tmp == 0) { IGRAPH_ERROR("vector ptr reserve failed", IGRAPH_ENOMEM); } v->stor_begin = tmp; v->stor_end = v->stor_begin + size; v->end = v->stor_begin + actual_size; return 0; } /** * \ingroup vectorptr * \brief Decides whether the pointer vector is empty. */ igraph_bool_t igraph_vector_ptr_empty(const igraph_vector_ptr_t* v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); return v->stor_begin == v->end; } /** * \ingroup vectorptr * \function igraph_vector_ptr_size * \brief Gives the number of elements in the pointer vector. * * \param v The pointer vector object. * \return The size of the object, i.e. the number of pointers stored. * * Time complexity: O(1). */ long int igraph_vector_ptr_size(const igraph_vector_ptr_t* v) { IGRAPH_ASSERT(v != NULL); /* IGRAPH_ASSERT(v->stor_begin != NULL); */ /* TODO */ return v->end - v->stor_begin; } /** * \ingroup vectorptr * \function igraph_vector_ptr_clear * \brief Removes all elements from a pointer vector. * * * This function resizes a pointer to vector to zero length. Note that * the pointed objects are \em not deallocated, you should call * \ref igraph_free() on them, or make sure that their allocated memory is freed * in some other way, you'll get memory leaks otherwise. If you have * set up an item destructor earlier, the destructor will be called * on every element. * * * Note that the current implementation of this function does * \em not deallocate the memory required for storing the * pointers, so making a pointer vector smaller this way does not give * back any memory. This behavior might change in the future. * \param v The pointer vector to clear. * * Time complexity: O(1). */ void igraph_vector_ptr_clear(igraph_vector_ptr_t* v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); igraph_i_vector_ptr_call_item_destructor_all(v); v->end = v->stor_begin; } /** * \ingroup vectorptr * \function igraph_vector_ptr_push_back * \brief Appends an element to the back of a pointer vector. * * \param v The pointer vector. * \param e The new element to include in the pointer vector. * \return Error code. * \sa igraph_vector_push_back() for the corresponding operation of * the ordinary vector type. * * Time complexity: O(1) or O(n), n is the number of elements in the * vector. The pointer vector implementation ensures that n subsequent * push_back operations need O(n) time to complete. */ int igraph_vector_ptr_push_back(igraph_vector_ptr_t* v, void* e) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); /* full, allocate more storage */ if (v->stor_end == v->end) { long int new_size = igraph_vector_ptr_size(v) * 2; if (new_size == 0) { new_size = 1; } IGRAPH_CHECK(igraph_vector_ptr_reserve(v, new_size)); } *(v->end) = e; v->end += 1; return 0; } void *igraph_vector_ptr_pop_back(igraph_vector_ptr_t *v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_ASSERT(v->stor_begin != v->end); v->end -= 1; return *(v->end); } /** * \ingroup vectorptr * \function igraph_vector_ptr_insert * \brief Inserts a single element into a pointer vector. * * Note that this function does not do range checking. Insertion will shift the * elements from the position given to the end of the vector one position to the * right, and the new element will be inserted in the empty space created at * the given position. The size of the vector will increase by one. * * \param v The pointer vector object. * \param pos The position where the new element is inserted. * \param e The inserted element */ int igraph_vector_ptr_insert(igraph_vector_ptr_t* v, long int pos, void* e) { long int size = igraph_vector_ptr_size(v); IGRAPH_CHECK(igraph_vector_ptr_resize(v, size + 1)); if (pos < size) { memmove(v->stor_begin + pos + 1, v->stor_begin + pos, sizeof(void*) * (size_t) (size - pos)); } v->stor_begin[pos] = e; return 0; } /** * \ingroup vectorptr * \function igraph_vector_ptr_e * \brief Access an element of a pointer vector. * * \param v Pointer to a pointer vector. * \param pos The index of the pointer to return. * \return The pointer at \p pos position. * * Time complexity: O(1). */ void *igraph_vector_ptr_e(const igraph_vector_ptr_t* v, long int pos) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); return *(v->stor_begin + pos); } /** * \ingroup vectorptr * \function igraph_vector_ptr_set * \brief Assign to an element of a pointer vector. * * \param v Pointer to a pointer vector. * \param pos The index of the pointer to update. * \param value The new pointer to set in the vector. * * Time complexity: O(1). */ void igraph_vector_ptr_set(igraph_vector_ptr_t* v, long int pos, void* value) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); *(v->stor_begin + pos) = value; } /** * \ingroup vectorptr * \brief Set all elements of a pointer vector to the NULL pointer. */ void igraph_vector_ptr_null(igraph_vector_ptr_t* v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); if (igraph_vector_ptr_size(v) > 0) { memset(v->stor_begin, 0, sizeof(void*) * (size_t) igraph_vector_ptr_size(v)); } } /** * \ingroup vectorptr * \function igraph_vector_ptr_resize * \brief Resizes a pointer vector. * * * Note that if a vector is made smaller the pointed object are not * deallocated by this function and the item destructor is not called * on the extra elements. * * \param v A pointer vector. * \param newsize The new size of the pointer vector. * \return Error code. * * Time complexity: O(1) if the vector if made smaller. Operating * system dependent otherwise, the amount of \quote time \endquote * needed to allocate the memory for the vector elements. */ int igraph_vector_ptr_resize(igraph_vector_ptr_t* v, long int newsize) { IGRAPH_CHECK(igraph_vector_ptr_reserve(v, newsize)); v->end = v->stor_begin + newsize; return 0; } /** * \ingroup vectorptr * \brief Initializes a pointer vector from an array (constructor). * * \return Error code: * \c IGRAPH_ENOMEM if out of memory */ int igraph_vector_ptr_init_copy(igraph_vector_ptr_t *v, void * *data, long int length) { v->stor_begin = IGRAPH_CALLOC(length, void*); if (v->stor_begin == 0) { IGRAPH_ERROR("cannot init ptr vector from array", IGRAPH_ENOMEM); } v->stor_end = v->stor_begin + length; v->end = v->stor_end; v->item_destructor = 0; memcpy(v->stor_begin, data, (size_t) length * sizeof(void*)); return 0; } /** * \ingroup vectorptr * \brief Copy the contents of a pointer vector to a regular C array. */ void igraph_vector_ptr_copy_to(const igraph_vector_ptr_t *v, void** to) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); if (v->end != v->stor_begin) { memcpy(to, v->stor_begin, sizeof(void*) * (size_t) (v->end - v->stor_begin)); } } /** * \ingroup vectorptr * \function igraph_vector_ptr_copy * \brief Copy a pointer vector (constructor). * * * This function creates a pointer vector by copying another one. This * is shallow copy, only the pointers in the vector will be copied. * * * It is potentially dangerous to copy a pointer vector with an associated * item destructor. The copied vector will inherit the item destructor, * which may cause problems when both vectors are destroyed as the items * might get destroyed twice. Make sure you know what you are doing when * copying a pointer vector with an item destructor, or unset the item * destructor on one of the vectors later. * * \param to Pointer to an uninitialized pointer vector object. * \param from A pointer vector object. * \return Error code: * \c IGRAPH_ENOMEM if out of memory * * Time complexity: O(n) if allocating memory for n elements can be * done in O(n) time. */ int igraph_vector_ptr_copy(igraph_vector_ptr_t *to, const igraph_vector_ptr_t *from) { long int from_size; IGRAPH_ASSERT(from != NULL); /* IGRAPH_ASSERT(from->stor_begin != NULL); */ /* TODO */ from_size = igraph_vector_ptr_size(from); to->stor_begin = IGRAPH_CALLOC(from_size, void*); if (to->stor_begin == 0) { IGRAPH_ERROR("cannot copy ptr vector", IGRAPH_ENOMEM); } to->stor_end = to->stor_begin + igraph_vector_ptr_size(from); to->end = to->stor_end; to->item_destructor = from->item_destructor; memcpy(to->stor_begin, from->stor_begin, (size_t) igraph_vector_ptr_size(from)*sizeof(void*)); return 0; } /** * \ingroup vectorptr * \brief Remove an element from a pointer vector. */ void igraph_vector_ptr_remove(igraph_vector_ptr_t *v, long int pos) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); if (pos + 1 < igraph_vector_ptr_size(v)) { /* No need to move data when removing the last element. */ memmove(v->stor_begin + pos, v->stor_begin + pos + 1, sizeof(void*) * (size_t) (igraph_vector_ptr_size(v) - pos - 1)); } v->end--; } /** * \ingroup vectorptr * \function igraph_vector_ptr_sort * \brief Sorts the pointer vector based on an external comparison function. * * Sometimes it is necessary to sort the pointers in the vector based on * the property of the element being referenced by the pointer. This * function allows us to sort the vector based on an arbitrary external * comparison function which accepts two void * pointers \c p1 and \c p2 * and returns an integer less than, equal to or greater than zero if the * first argument is considered to be respectively less than, equal to, or * greater than the second. \c p1 and \c p2 will point to the pointer in the * vector, so they have to be double-dereferenced if one wants to get access * to the underlying object the address of which is stored in \c v. * * \param v The pointer vector to be sorted. * \param compar A qsort-compatible comparison function. It must take pointers to the * elements of the pointer vector. For example, if the pointer vector contains * igraph_vector_t * pointers, then the comparison function must * interpret its arguments as igraph_vector_t **. * * \example examples/simple/igraph_vector_ptr_sort.c */ void igraph_vector_ptr_sort(igraph_vector_ptr_t *v, int (*compar)(const void*, const void*)) { igraph_qsort(v->stor_begin, (size_t) igraph_vector_ptr_size(v), sizeof(void*), compar); } int igraph_vector_ptr_index_int(igraph_vector_ptr_t *v, const igraph_vector_int_t *idx) { void **tmp; int i, n = igraph_vector_int_size(idx); tmp = IGRAPH_CALLOC(n, void*); if (!tmp) { IGRAPH_ERROR("Cannot index pointer vector", IGRAPH_ENOMEM); } for (i = 0; i < n; i++) { tmp[i] = VECTOR(*v)[ VECTOR(*idx)[i] ]; } IGRAPH_FREE(v->stor_begin); v->stor_begin = tmp; v->stor_end = v->end = tmp + n; return 0; } int igraph_vector_ptr_append(igraph_vector_ptr_t *to, const igraph_vector_ptr_t *from) { long int origsize = igraph_vector_ptr_size(to); long int othersize = igraph_vector_ptr_size(from); long int i; IGRAPH_CHECK(igraph_vector_ptr_resize(to, origsize + othersize)); for (i = 0; i < othersize; i++, origsize++) { to->stor_begin[origsize] = from->stor_begin[i]; } return 0; } /** * \ingroup vectorptr * \function igraph_vector_ptr_set_item_destructor * \brief Sets the item destructor for this pointer vector. * * The item destructor is a function which will be called on every non-null * pointer stored in this vector when \ref igraph_vector_ptr_destroy(), * igraph_vector_ptr_destroy_all() or \ref igraph_vector_ptr_free_all() * is called. * * \return The old item destructor. * * Time complexity: O(1). */ igraph_finally_func_t* igraph_vector_ptr_set_item_destructor( igraph_vector_ptr_t *v, igraph_finally_func_t *func) { igraph_finally_func_t* result = v->item_destructor; v->item_destructor = func; return result; } /** * \ingroup vectorptr * \function igraph_vector_ptr_get_item_destructor * \brief Gets the current item destructor for this pointer vector. * * The item destructor is a function which will be called on every non-null * pointer stored in this vector when \ref igraph_vector_ptr_destroy(), * igraph_vector_ptr_destroy_all() or \ref igraph_vector_ptr_free_all() * is called. * * \return The current item destructor. * * Time complexity: O(1). */ igraph_finally_func_t* igraph_vector_ptr_get_item_destructor(const igraph_vector_ptr_t *v) { IGRAPH_ASSERT(v != 0); return v->item_destructor; } leidenbase/src/core/core/buckets.c0000644000176200001440000001370314447675374016651 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "core/buckets.h" /* The igraph_buckets_t data structure can store at most 'size' * unique integers in 'bsize' buckets. It has the following simple * operations (in addition to _init() and _destroy(): * - _add() adding an element to the given bucket. * - _popmax() removing an element from the bucket with the highest * id. * Currently buckets work as stacks, last-in-first-out mode. * - _empty() queries whether the buckets is empty. * * Internal representation: we use a vector to create single linked * lists, and another vector that points to the starting element of * each bucket. Zero means the end of the chain. So bucket i contains * elements bptr[i], buckets[bptr[i]], buckets[buckets[bptr[i]]], * etc., until a zero is found. * * We also keep the total number of elements in the buckets and the * id of the non-empty bucket with the highest id, to facilitate the * _empty() and _popmax() operations. */ int igraph_buckets_init(igraph_buckets_t *b, long int bsize, long int size) { IGRAPH_VECTOR_LONG_INIT_FINALLY(&b->bptr, bsize); IGRAPH_VECTOR_LONG_INIT_FINALLY(&b->buckets, size); b->max = -1; b->no = 0; IGRAPH_FINALLY_CLEAN(2); return 0; } void igraph_buckets_destroy(igraph_buckets_t *b) { igraph_vector_long_destroy(&b->bptr); igraph_vector_long_destroy(&b->buckets); } long int igraph_buckets_popmax(igraph_buckets_t *b) { /* Precondition: there is at least a non-empty bucket */ /* Search for the highest bucket first */ long int max; while ( (max = (long int) VECTOR(b->bptr)[(long int) b->max]) == 0) { b->max --; } VECTOR(b->bptr)[(long int) b->max] = VECTOR(b->buckets)[max - 1]; b->no--; return max - 1; } long int igraph_buckets_pop(igraph_buckets_t *b, long int bucket) { long int ret = VECTOR(b->bptr)[bucket] - 1; VECTOR(b->bptr)[bucket] = VECTOR(b->buckets)[ret]; b->no--; return ret; } igraph_bool_t igraph_buckets_empty(const igraph_buckets_t *b) { return (b->no == 0); } igraph_bool_t igraph_buckets_empty_bucket(const igraph_buckets_t *b, long int bucket) { return VECTOR(b->bptr)[bucket] == 0; } void igraph_buckets_add(igraph_buckets_t *b, long int bucket, long int elem) { VECTOR(b->buckets)[(long int) elem] = VECTOR(b->bptr)[(long int) bucket]; VECTOR(b->bptr)[(long int) bucket] = elem + 1; if (bucket > b->max) { b->max = (int) bucket; } b->no++; } void igraph_buckets_clear(igraph_buckets_t *b) { igraph_vector_long_null(&b->bptr); igraph_vector_long_null(&b->buckets); b->max = -1; b->no = 0; } int igraph_dbuckets_init(igraph_dbuckets_t *b, long int bsize, long int size) { IGRAPH_VECTOR_LONG_INIT_FINALLY(&b->bptr, bsize); IGRAPH_VECTOR_LONG_INIT_FINALLY(&b->next, size); IGRAPH_VECTOR_LONG_INIT_FINALLY(&b->prev, size); b->max = -1; b->no = 0; IGRAPH_FINALLY_CLEAN(3); return 0; } void igraph_dbuckets_destroy(igraph_dbuckets_t *b) { igraph_vector_long_destroy(&b->bptr); igraph_vector_long_destroy(&b->next); igraph_vector_long_destroy(&b->prev); } void igraph_dbuckets_clear(igraph_dbuckets_t *b) { igraph_vector_long_null(&b->bptr); igraph_vector_long_null(&b->next); igraph_vector_long_null(&b->prev); b->max = -1; b->no = 0; } long int igraph_dbuckets_popmax(igraph_dbuckets_t *b) { long int max; while ( (max = (long int) VECTOR(b->bptr)[(long int) b->max]) == 0) { b->max --; } return igraph_dbuckets_pop(b, b->max); } long int igraph_dbuckets_pop(igraph_dbuckets_t *b, long int bucket) { long int ret = VECTOR(b->bptr)[bucket] - 1; long int next = VECTOR(b->next)[ret]; VECTOR(b->bptr)[bucket] = next; if (next != 0) { VECTOR(b->prev)[next - 1] = 0; } b->no--; return ret; } igraph_bool_t igraph_dbuckets_empty(const igraph_dbuckets_t *b) { return (b->no == 0); } igraph_bool_t igraph_dbuckets_empty_bucket(const igraph_dbuckets_t *b, long int bucket) { return VECTOR(b->bptr)[bucket] == 0; } void igraph_dbuckets_add(igraph_dbuckets_t *b, long int bucket, long int elem) { long int oldfirst = VECTOR(b->bptr)[bucket]; VECTOR(b->bptr)[bucket] = elem + 1; VECTOR(b->next)[elem] = oldfirst; if (oldfirst != 0) { VECTOR(b->prev)[oldfirst - 1] = elem + 1; } if (bucket > b->max) { b->max = (int) bucket; } b->no++; } /* Remove an arbitrary element */ void igraph_dbuckets_delete(igraph_dbuckets_t *b, long int bucket, long int elem) { if (VECTOR(b->bptr)[bucket] == elem + 1) { /* First element in bucket */ long int next = VECTOR(b->next)[elem]; if (next != 0) { VECTOR(b->prev)[next - 1] = 0; } VECTOR(b->bptr)[bucket] = next; } else { long int next = VECTOR(b->next)[elem]; long int prev = VECTOR(b->prev)[elem]; if (next != 0) { VECTOR(b->prev)[next - 1] = prev; } if (prev != 0) { VECTOR(b->next)[prev - 1] = next; } } b->no--; } leidenbase/src/core/core/matrix.pmt0000644000176200001440000014105414447675374017074 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_memory.h" #include "igraph_random.h" #include "igraph_error.h" #include /* memcpy & co. */ #include /** * \section about_igraph_matrix_t_objects About \type igraph_matrix_t objects * * This type is just an interface to \type igraph_vector_t. * * The \type igraph_matrix_t type usually stores n * elements in O(n) space, but not always. See the documentation of * the vector type. */ /** * \section igraph_matrix_constructor_and_destructor Matrix constructors and * destructors */ /** * \ingroup matrix * \function igraph_matrix_init * \brief Initializes a matrix. * * * Every matrix needs to be initialized before using it. This is done * by calling this function. A matrix has to be destroyed if it is not * needed any more; see \ref igraph_matrix_destroy(). * \param m Pointer to a not yet initialized matrix object to be * initialized. * \param nrow The number of rows in the matrix. * \param ncol The number of columns in the matrix. * \return Error code. * * Time complexity: usually O(n), * n is the * number of elements in the matrix. */ int FUNCTION(igraph_matrix, init)(TYPE(igraph_matrix) *m, long int nrow, long int ncol) { IGRAPH_CHECK(FUNCTION(igraph_vector, init)(&m->data, nrow * ncol)); m->nrow = nrow; m->ncol = ncol; return IGRAPH_SUCCESS; } const TYPE(igraph_matrix) *FUNCTION(igraph_matrix, view)(const TYPE(igraph_matrix) *m, const BASE *data, long int nrow, long int ncol) { TYPE(igraph_matrix) *m2 = (TYPE(igraph_matrix)*)m; FUNCTION(igraph_vector, view)(&m2->data, data, nrow * ncol); m2->nrow = nrow; m2->ncol = ncol; return m; } /** * \ingroup matrix * \function igraph_matrix_destroy * \brief Destroys a matrix object. * * * This function frees all the memory allocated for a matrix * object. The destroyed object needs to be reinitialized before using * it again. * \param m The matrix to destroy. * * Time complexity: operating system dependent. */ void FUNCTION(igraph_matrix, destroy)(TYPE(igraph_matrix) *m) { FUNCTION(igraph_vector, destroy)(&m->data); } /** * \ingroup matrix * \function igraph_matrix_capacity * \brief Returns the number of elements allocated for a matrix. * * Note that this might be different from the size of the matrix (as * queried by \ref igraph_matrix_size(), and specifies how many elements * the matrix can hold, without reallocation. * \param v Pointer to the (previously initialized) matrix object * to query. * \return The allocated capacity. * * \sa \ref igraph_matrix_size(), \ref igraph_matrix_nrow(), * \ref igraph_matrix_ncol(). * * Time complexity: O(1). */ long int FUNCTION(igraph_matrix, capacity)(const TYPE(igraph_matrix) *m) { return FUNCTION(igraph_vector, capacity)(&m->data); } /** * \section igraph_matrix_accessing_elements Accessing elements of a matrix */ /** * \ingroup matrix * \function igraph_matrix_resize * \brief Resizes a matrix. * * * This function resizes a matrix by adding more elements to it. * The matrix contains arbitrary data after resizing it. * That is, after calling this function you cannot expect that element * (i,j) in the matrix remains the * same as before. * \param m Pointer to an already initialized matrix object. * \param nrow The number of rows in the resized matrix. * \param ncol The number of columns in the resized matrix. * \return Error code. * * Time complexity: O(1) if the * matrix gets smaller, usually O(n) * if it gets larger, n is the * number of elements in the resized matrix. */ int FUNCTION(igraph_matrix, resize)(TYPE(igraph_matrix) *m, long int nrow, long int ncol) { IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(&m->data, nrow * ncol)); m->nrow = nrow; m->ncol = ncol; return 0; } /** * \ingroup matrix * \function igraph_matrix_resize_min * \brief Deallocates unused memory for a matrix. * * * Note that this function might fail if there is not enough memory * available. * * * Also note, that this function leaves the matrix intact, i.e. * it does not destroy any of the elements. However, usually it involves * copying the matrix in memory. * \param m Pointer to an initialized matrix. * \return Error code. * * \sa \ref igraph_matrix_resize(). * * Time complexity: operating system dependent. */ int FUNCTION(igraph_matrix, resize_min)(TYPE(igraph_matrix) *m) { TYPE(igraph_vector) tmp; long int size = FUNCTION(igraph_matrix, size)(m); long int capacity = FUNCTION(igraph_matrix, capacity)(m); if (size == capacity) { return 0; } IGRAPH_CHECK(FUNCTION(igraph_vector, init)(&tmp, size)); FUNCTION(igraph_vector, update)(&tmp, &m->data); FUNCTION(igraph_vector, destroy)(&m->data); m->data = tmp; return 0; } /** * \ingroup matrix * \function igraph_matrix_size * \brief The number of elements in a matrix. * * \param m Pointer to an initialized matrix object. * \return The size of the matrix. * * Time complexity: O(1). */ long int FUNCTION(igraph_matrix, size)(const TYPE(igraph_matrix) *m) { return (m->nrow) * (m->ncol); } /** * \ingroup matrix * \function igraph_matrix_nrow * \brief The number of rows in a matrix. * * \param m Pointer to an initialized matrix object. * \return The number of rows in the matrix. * * Time complexity: O(1). */ long int FUNCTION(igraph_matrix, nrow)(const TYPE(igraph_matrix) *m) { return m->nrow; } /** * \ingroup matrix * \function igraph_matrix_ncol * \brief The number of columns in a matrix. * * \param m Pointer to an initialized matrix object. * \return The number of columns in the matrix. * * Time complexity: O(1). */ long int FUNCTION(igraph_matrix, ncol)(const TYPE(igraph_matrix) *m) { return m->ncol; } /** * \ingroup matrix * \function igraph_matrix_copy_to * \brief Copies a matrix to a regular C array. * * * The matrix is copied columnwise, as this is the format most * programs and languages use. * The C array should be of sufficient size; there are (of course) no * range checks. * \param m Pointer to an initialized matrix object. * \param to Pointer to a C array; the place to copy the data to. * \return Error code. * * Time complexity: O(n), * n is the number of * elements in the matrix. */ void FUNCTION(igraph_matrix, copy_to)(const TYPE(igraph_matrix) *m, BASE *to) { FUNCTION(igraph_vector, copy_to)(&m->data, to); } /** * \ingroup matrix * \function igraph_matrix_null * \brief Sets all elements in a matrix to zero. * * \param m Pointer to an initialized matrix object. * * Time complexity: O(n), * n is the number of elements in * the matrix. */ void FUNCTION(igraph_matrix, null)(TYPE(igraph_matrix) *m) { FUNCTION(igraph_vector, null)(&m->data); } /** * \ingroup matrix * \function igraph_matrix_add_cols * \brief Adds columns to a matrix. * \param m The matrix object. * \param n The number of columns to add. * \return Error code, \c IGRAPH_ENOMEM if there is * not enough memory to perform the operation. * * Time complexity: linear with the number of elements of the new, * resized matrix. */ int FUNCTION(igraph_matrix, add_cols)(TYPE(igraph_matrix) *m, long int n) { IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(m, m->nrow, m->ncol + n)); return 0; } /** * \ingroup matrix * \function igraph_matrix_add_rows * \brief Adds rows to a matrix. * \param m The matrix object. * \param n The number of rows to add. * \return Error code, \c IGRAPH_ENOMEM if there * isn't enough memory for the operation. * * Time complexity: linear with the number of elements of the new, * resized matrix. */ int FUNCTION(igraph_matrix, add_rows)(TYPE(igraph_matrix) *m, long int n) { long int i; IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(&m->data, (m->ncol) * (m->nrow + n))); for (i = m->ncol - 1; i >= 0; i--) { FUNCTION(igraph_vector, move_interval2)(&m->data, (m->nrow)*i, (m->nrow) * (i + 1), (m->nrow + n)*i); } m->nrow += n; return 0; } /** * \ingroup matrix * \function igraph_matrix_remove_col * \brief Removes a column from a matrix. * * \param m The matrix object. * \param col The column to remove. * \return Error code, always returns with success. * * Time complexity: linear with the number of elements of the new, * resized matrix. */ int FUNCTION(igraph_matrix, remove_col)(TYPE(igraph_matrix) *m, long int col) { FUNCTION(igraph_vector, remove_section)(&m->data, (m->nrow)*col, (m->nrow) * (col + 1)); m->ncol--; return 0; } /** * \ingroup matrix * \function igraph_matrix_permdelete_rows * \brief Removes rows from a matrix (for internal use). * * Time complexity: linear with the number of elements of the original * matrix. */ int FUNCTION(igraph_matrix, permdelete_rows)(TYPE(igraph_matrix) *m, long int *index, long int nremove) { long int i, j; for (j = 0; j < m->nrow; j++) { if (index[j] != 0) { for (i = 0; i < m->ncol; i++) { MATRIX(*m, index[j] - 1, i) = MATRIX(*m, j, i); } } } /* Remove unnecessary elements from the end of each column */ for (i = 0; i < m->ncol; i++) FUNCTION(igraph_vector, remove_section)(&m->data, (i + 1) * (m->nrow - nremove), (i + 1) * (m->nrow - nremove) + nremove); IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(m, m->nrow - nremove, m->ncol)); return 0; } /** * \ingroup matrix * \function igraph_matrix_delete_rows_neg * \brief Removes columns from a matrix (for internal use). * * Time complexity: linear with the number of elements of the original * matrix. */ int FUNCTION(igraph_matrix, delete_rows_neg)(TYPE(igraph_matrix) *m, const igraph_vector_t *neg, long int nremove) { long int i, j, idx = 0; for (i = 0; i < m->ncol; i++) { for (j = 0; j < m->nrow; j++) { if (VECTOR(*neg)[j] >= 0) { MATRIX(*m, idx++, i) = MATRIX(*m, j, i); } } idx = 0; } IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(m, m->nrow - nremove, m->ncol)); return 0; } /** * \ingroup matrix * \function igraph_matrix_copy * \brief Copies a matrix. * * * Creates a matrix object by copying from an existing matrix. * \param to Pointer to an uninitialized matrix object. * \param from The initialized matrix object to copy. * \return Error code, \c IGRAPH_ENOMEM if there * isn't enough memory to allocate the new matrix. * * Time complexity: O(n), the number * of elements in the matrix. */ int FUNCTION(igraph_matrix, copy)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from) { IGRAPH_CHECK(FUNCTION(igraph_vector, copy)(&to->data, &from->data)); to->nrow = from->nrow; to->ncol = from->ncol; return IGRAPH_SUCCESS; } #ifndef NOTORDERED /** * \function igraph_matrix_max * \brief Largest element of a matrix. * * * If the matrix is empty, an arbitrary number is returned. * \param m The matrix object. * \return The maximum element of \p m, or NaN if any element is NaN. * * Added in version 0.2. * * Time complexity: O(mn), the number of elements in the matrix. */ igraph_real_t FUNCTION(igraph_matrix, max)(const TYPE(igraph_matrix) *m) { return FUNCTION(igraph_vector, max)(&m->data); } #endif /** * \function igraph_matrix_scale * * Multiplies each element of the matrix by a constant. * \param m The matrix. * \param by The constant. * * Added in version 0.2. * * Time complexity: O(n), the number of elements in the matrix. */ void FUNCTION(igraph_matrix, scale)(TYPE(igraph_matrix) *m, BASE by) { FUNCTION(igraph_vector, scale)(&m->data, by); } /** * \function igraph_matrix_select_rows * \brief Select some rows of a matrix. * * This function selects some rows of a matrix and returns them in a * new matrix. The result matrix should be initialized before calling * the function. * \param m The input matrix. * \param res The result matrix. It should be initialized and will be * resized as needed. * \param rows Vector; it contains the row indices (starting with * zero) to extract. Note that no range checking is performed. * \return Error code. * * Time complexity: O(nm), n is the number of rows, m the number of * columns of the result matrix. */ int FUNCTION(igraph_matrix, select_rows)(const TYPE(igraph_matrix) *m, TYPE(igraph_matrix) *res, const igraph_vector_t *rows) { long int norows = igraph_vector_size(rows); long int i, j, ncols = FUNCTION(igraph_matrix, ncol)(m); IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(res, norows, ncols)); for (i = 0; i < norows; i++) { for (j = 0; j < ncols; j++) { MATRIX(*res, i, j) = MATRIX(*m, (long int)VECTOR(*rows)[i], j); } } return 0; } /** * \function igraph_matrix_select_rows_cols * \brief Select some rows and columns of a matrix. * * This function selects some rows and columns of a matrix and returns * them in a new matrix. The result matrix should be initialized before * calling the function. * \param m The input matrix. * \param res The result matrix. It should be initialized and will be * resized as needed. * \param rows Vector; it contains the row indices (starting with * zero) to extract. Note that no range checking is performed. * \param cols Vector; it contains the column indices (starting with * zero) to extract. Note that no range checking is performed. * \return Error code. * * Time complexity: O(nm), n is the number of rows, m the number of * columns of the result matrix. */ int FUNCTION(igraph_matrix, select_rows_cols)(const TYPE(igraph_matrix) *m, TYPE(igraph_matrix) *res, const igraph_vector_t *rows, const igraph_vector_t *cols) { long int nrows = igraph_vector_size(rows); long int ncols = igraph_vector_size(cols); long int i, j; IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(res, nrows, ncols)); for (i = 0; i < nrows; i++) { for (j = 0; j < ncols; j++) { MATRIX(*res, i, j) = MATRIX(*m, (long int)VECTOR(*rows)[i], (long int)VECTOR(*cols)[j]); } } return 0; } /** * \function igraph_matrix_get_col * \brief Select a column. * * Extract a column of a matrix and return it as a vector. * \param m The input matrix. * \param res The result will we stored in this vector. It should be * initialized and will be resized as needed. * \param index The index of the column to select. * \return Error code. * * Time complexity: O(n), the number of rows in the matrix. */ int FUNCTION(igraph_matrix, get_col)(const TYPE(igraph_matrix) *m, TYPE(igraph_vector) *res, long int index) { long int nrow = FUNCTION(igraph_matrix, nrow)(m); if (index >= m->ncol) { IGRAPH_ERROR("Index out of range for selecting matrix column", IGRAPH_EINVAL); } IGRAPH_CHECK(FUNCTION(igraph_vector, get_interval)(&m->data, res, nrow * index, nrow * (index + 1))); return 0; } /** * \function igraph_matrix_sum * \brief Sum of elements. * * Returns the sum of the elements of a matrix. * \param m The input matrix. * \return The sum of the elements. * * Time complexity: O(mn), the number of elements in the matrix. */ BASE FUNCTION(igraph_matrix, sum)(const TYPE(igraph_matrix) *m) { return FUNCTION(igraph_vector, sum)(&m->data); } /** * \function igraph_matrix_all_e * \brief Are all elements equal? * * \param lhs The first matrix. * \param rhs The second matrix. * \return Positive integer (=true) if the elements in the \p lhs are all * equal to the corresponding elements in \p rhs. Returns \c 0 * (=false) if the dimensions of the matrices don't match. * * Time complexity: O(nm), the size of the matrices. */ igraph_bool_t FUNCTION(igraph_matrix, all_e)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs) { return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow && FUNCTION(igraph_vector, all_e)(&lhs->data, &rhs->data); } igraph_bool_t FUNCTION(igraph_matrix, is_equal)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs) { return FUNCTION(igraph_matrix, all_e)(lhs, rhs); } #ifndef NOTORDERED /** * \function igraph_matrix_all_l * \brief Are all elements less? * * \param lhs The first matrix. * \param rhs The second matrix. * \return Positive integer (=true) if the elements in the \p lhs are all * less than the corresponding elements in \p rhs. Returns \c 0 * (=false) if the dimensions of the matrices don't match. * * Time complexity: O(nm), the size of the matrices. */ igraph_bool_t FUNCTION(igraph_matrix, all_l)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs) { return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow && FUNCTION(igraph_vector, all_l)(&lhs->data, &rhs->data); } /** * \function igraph_matrix_all_g * \brief Are all elements greater? * * \param lhs The first matrix. * \param rhs The second matrix. * \return Positive integer (=true) if the elements in the \p lhs are all * greater than the corresponding elements in \p rhs. Returns \c 0 * (=false) if the dimensions of the matrices don't match. * * Time complexity: O(nm), the size of the matrices. */ igraph_bool_t FUNCTION(igraph_matrix, all_g)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs) { return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow && FUNCTION(igraph_vector, all_g)(&lhs->data, &rhs->data); } /** * \function igraph_matrix_all_le * \brief Are all elements less or equal? * * \param lhs The first matrix. * \param rhs The second matrix. * \return Positive integer (=true) if the elements in the \p lhs are all * less than or equal to the corresponding elements in \p * rhs. Returns \c 0 (=false) if the dimensions of the matrices * don't match. * * Time complexity: O(nm), the size of the matrices. */ igraph_bool_t FUNCTION(igraph_matrix, all_le)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs) { return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow && FUNCTION(igraph_vector, all_le)(&lhs->data, &rhs->data); } /** * \function igraph_matrix_all_ge * \brief Are all elements greater or equal? * * \param lhs The first matrix. * \param rhs The second matrix. * \return Positive integer (=true) if the elements in the \p lhs are all * greater than or equal to the corresponding elements in \p * rhs. Returns \c 0 (=false) if the dimensions of the matrices * don't match. * * Time complexity: O(nm), the size of the matrices. */ igraph_bool_t FUNCTION(igraph_matrix, all_ge)(const TYPE(igraph_matrix) *lhs, const TYPE(igraph_matrix) *rhs) { return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow && FUNCTION(igraph_vector, all_ge)(&lhs->data, &rhs->data); } #endif #ifndef NOTORDERED /** * \function igraph_matrix_maxdifference * \brief Maximum absolute difference between two matrices. * * Calculate the maximum absolute difference of two matrices. Both matrices * must be non-empty. If their dimensions differ then a warning is given and * the comparison is performed by vectors columnwise from both matrices. * The remaining elements in the larger vector are ignored. * \param m1 The first matrix. * \param m2 The second matrix. * \return The element with the largest absolute value in \c m1 - \c m2. * * Time complexity: O(mn), the elements in the smaller matrix. */ igraph_real_t FUNCTION(igraph_matrix, maxdifference)(const TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2) { long int col1 = FUNCTION(igraph_matrix, ncol)(m1); long int col2 = FUNCTION(igraph_matrix, ncol)(m2); long int row1 = FUNCTION(igraph_matrix, nrow)(m1); long int row2 = FUNCTION(igraph_matrix, nrow)(m2); if (col1 != col2 || row1 != row2) { IGRAPH_WARNING("Comparing non-conformant matrices"); } return FUNCTION(igraph_vector, maxdifference)(&m1->data, &m2->data); } #endif /** * \function igraph_matrix_transpose * \brief Transpose a matrix. * * Calculate the transpose of a matrix. Note that the function * reallocates the memory used for the matrix. * \param m The input (and output) matrix. * \return Error code. * * Time complexity: O(mn), the number of elements in the matrix. */ int FUNCTION(igraph_matrix, transpose)(TYPE(igraph_matrix) *m) { long int nrow = m->nrow; long int ncol = m->ncol; if (nrow > 1 && ncol > 1) { TYPE(igraph_vector) newdata; long int i, size = nrow * ncol, mod = size - 1; IGRAPH_CHECK(FUNCTION(igraph_vector, init)(&newdata, size)); IGRAPH_FINALLY(FUNCTION(igraph_vector, destroy), &newdata); for (i = 0; i < size; i++) { VECTOR(newdata)[i] = VECTOR(m->data)[ (i * nrow) % mod ]; } VECTOR(newdata)[size - 1] = VECTOR(m->data)[size - 1]; FUNCTION(igraph_vector, destroy)(&m->data); IGRAPH_FINALLY_CLEAN(1); m->data = newdata; } m->nrow = ncol; m->ncol = nrow; return 0; } /** * \function igraph_matrix_e * Extract an element from a matrix. * * Use this if you need a function for some reason and cannot use the * \ref MATRIX macro. Note that no range checking is performed. * \param m The input matrix. * \param row The row index. * \param col The column index. * \return The element in the given row and column. * * Time complexity: O(1). */ BASE FUNCTION(igraph_matrix, e)(const TYPE(igraph_matrix) *m, long int row, long int col) { return MATRIX(*m, row, col); } /** * \function igraph_matrix_e_ptr * Pointer to an element of a matrix. * * The function returns a pointer to an element. No range checking is * performed. * \param m The input matrix. * \param row The row index. * \param col The column index. * \return Pointer to the element in the given row and column. * * Time complexity: O(1). */ BASE* FUNCTION(igraph_matrix, e_ptr)(const TYPE(igraph_matrix) *m, long int row, long int col) { return &MATRIX(*m, row, col); } /** * \function igraph_matrix_set * Set an element. * * Set an element of a matrix. No range checking is performed. * \param m The input matrix. * \param row The row index. * \param col The column index. * \param value The new value of the element. * * Time complexity: O(1). */ void FUNCTION(igraph_matrix, set)(TYPE(igraph_matrix)* m, long int row, long int col, BASE value) { MATRIX(*m, row, col) = value; } /** * \function igraph_matrix_fill * Fill with an element. * * Set the matrix to a constant matrix. * \param m The input matrix. * \param e The element to set. * * Time complexity: O(mn), the number of elements. */ void FUNCTION(igraph_matrix, fill)(TYPE(igraph_matrix) *m, BASE e) { FUNCTION(igraph_vector, fill)(&m->data, e); } /** * \function igraph_matrix_update * Update from another matrix. * * This function replicates \p from in the matrix \p to. * Note that \p to must be already initialized. * \param to The result matrix. * \param from The matrix to replicate; it is left unchanged. * \return Error code. * * Time complexity: O(mn), the number of elements. */ int FUNCTION(igraph_matrix, update)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from) { IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(to, from->nrow, from->ncol)); FUNCTION(igraph_vector, update)(&to->data, &from->data); return 0; } /** * \function igraph_matrix_rbind * Combine two matrices rowwise. * * This function places the rows of \p from below the rows of \c to * and stores the result in \p to. The number of columns in the two * matrices must match. * \param to The upper matrix; the result is also stored here. * \param from The lower matrix. It is left unchanged. * \return Error code. * * Time complexity: O(mn), the number of elements in the newly created * matrix. */ int FUNCTION(igraph_matrix, rbind)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from) { long int tocols = to->ncol, fromcols = from->ncol; long int torows = to->nrow, fromrows = from->nrow; long int offset, c, r, index, offset2; if (tocols != fromcols) { IGRAPH_ERROR("Cannot do rbind, number of columns do not match", IGRAPH_EINVAL); } IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(&to->data, tocols * (fromrows + torows))); to->nrow += fromrows; offset = (tocols - 1) * fromrows; index = tocols * torows - 1; for (c = tocols - 1; c > 0; c--) { for (r = 0; r < torows; r++, index--) { VECTOR(to->data)[index + offset] = VECTOR(to->data)[index]; } offset -= fromrows; } offset = torows; offset2 = 0; for (c = 0; c < tocols; c++) { memcpy(VECTOR(to->data) + offset, VECTOR(from->data) + offset2, sizeof(BASE) * (size_t) fromrows); offset += fromrows + torows; offset2 += fromrows; } return 0; } /** * \function igraph_matrix_cbind * Combine matrices columnwise. * * This function places the columns of \p from on the right of \p to, * and stores the result in \p to. * \param to The left matrix; the result is stored here too. * \param from The right matrix. It is left unchanged. * \return Error code. * * Time complexity: O(mn), the number of elements on the new matrix. */ int FUNCTION(igraph_matrix, cbind)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from) { long int tocols = to->ncol, fromcols = from->ncol; long int torows = to->nrow, fromrows = from->nrow; if (torows != fromrows) { IGRAPH_ERROR("Cannot do rbind, number of rows do not match", IGRAPH_EINVAL); } IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(to, torows, tocols + fromcols)); FUNCTION(igraph_vector, copy_to)(&from->data, VECTOR(to->data) + tocols * torows); return 0; } /** * \function igraph_matrix_swap * Swap two matrices. * * The contents of the two matrices will be swapped. * \param m1 The first matrix. * \param m2 The second matrix. * \return Error code. * * Time complexity: O(1). */ int FUNCTION(igraph_matrix, swap)(TYPE(igraph_matrix) *m1, TYPE(igraph_matrix) *m2) { return FUNCTION(igraph_vector, swap)(&m1->data, &m2->data); } /** * \function igraph_matrix_get_row * Extract a row. * * Extract a row from a matrix and return it as a vector. * \param m The input matrix. * \param res Pointer to an initialized vector; it will be resized if * needed. * \param index The index of the row to select. * \return Error code. * * Time complexity: O(n), the number of columns in the matrix. */ int FUNCTION(igraph_matrix, get_row)(const TYPE(igraph_matrix) *m, TYPE(igraph_vector) *res, long int index) { long int rows = m->nrow, cols = m->ncol; long int i, j; if (index >= rows) { IGRAPH_ERROR("Index out of range for selecting matrix row", IGRAPH_EINVAL); } IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(res, cols)); for (i = index, j = 0; j < cols; i += rows, j++) { VECTOR(*res)[j] = VECTOR(m->data)[i]; } return 0; } /** * \function igraph_matrix_set_row * Set a row from a vector. * * Sets the elements of a row with the given vector. This has the effect of * setting row \c index to have the elements in the vector \c v. The length of * the vector and the number of columns in the matrix must match, * otherwise an error is triggered. * \param m The input matrix. * \param v The vector containing the new elements of the row. * \param index Index of the row to set. * \return Error code. * * Time complexity: O(n), the number of columns in the matrix. */ int FUNCTION(igraph_matrix, set_row)(TYPE(igraph_matrix) *m, const TYPE(igraph_vector) *v, long int index) { long int rows = m->nrow, cols = m->ncol; long int i, j; if (index >= rows) { IGRAPH_ERROR("Index out of range for selecting matrix row", IGRAPH_EINVAL); } if (FUNCTION(igraph_vector, size)(v) != cols) { IGRAPH_ERROR("Cannot set matrix row, invalid vector length", IGRAPH_EINVAL); } for (i = index, j = 0; j < cols; i += rows, j++) { VECTOR(m->data)[i] = VECTOR(*v)[j]; } return 0; } /** * \function igraph_matrix_set_col * Set a column from a vector. * * Sets the elements of a column with the given vector. In effect, column * \c index will be set with elements from the vector \c v. The length of * the vector and the number of rows in the matrix must match, * otherwise an error is triggered. * \param m The input matrix. * \param v The vector containing the new elements of the column. * \param index Index of the column to set. * \return Error code. * * Time complexity: O(m), the number of rows in the matrix. */ int FUNCTION(igraph_matrix, set_col)(TYPE(igraph_matrix) *m, const TYPE(igraph_vector) *v, long int index) { long int rows = m->nrow, cols = m->ncol; long int i, j; if (index >= cols) { IGRAPH_ERROR("Index out of range for setting matrix column", IGRAPH_EINVAL); } if (FUNCTION(igraph_vector, size)(v) != rows) { IGRAPH_ERROR("Cannot set matrix column, invalid vector length", IGRAPH_EINVAL); } for (i = index * rows, j = 0; j < rows; i++, j++) { VECTOR(m->data)[i] = VECTOR(*v)[j]; } return 0; } /** * \function igraph_matrix_swap_rows * Swap two rows. * * Swap two rows in the matrix. * \param m The input matrix. * \param i The index of the first row. * \param j The index of the second row. * \return Error code. * * Time complexity: O(n), the number of columns. */ int FUNCTION(igraph_matrix, swap_rows)(TYPE(igraph_matrix) *m, long int i, long int j) { long int ncol = m->ncol, nrow = m->nrow; long int n = nrow * ncol; long int index1, index2; if (i >= nrow || j >= nrow) { IGRAPH_ERROR("Cannot swap rows, index out of range", IGRAPH_EINVAL); } if (i == j) { return 0; } for (index1 = i, index2 = j; index1 < n; index1 += nrow, index2 += nrow) { BASE tmp; tmp = VECTOR(m->data)[index1]; VECTOR(m->data)[index1] = VECTOR(m->data)[index2]; VECTOR(m->data)[index2] = tmp; } return 0; } /** * \function igraph_matrix_swap_cols * Swap two columns. * * Swap two columns in the matrix. * \param m The input matrix. * \param i The index of the first column. * \param j The index of the second column. * \return Error code. * * Time complexity: O(m), the number of rows. */ int FUNCTION(igraph_matrix, swap_cols)(TYPE(igraph_matrix) *m, long int i, long int j) { long int ncol = m->ncol, nrow = m->nrow; long int k, index1, index2; if (i >= ncol || j >= ncol) { IGRAPH_ERROR("Cannot swap columns, index out of range", IGRAPH_EINVAL); } if (i == j) { return 0; } for (index1 = i * nrow, index2 = j * nrow, k = 0; k < nrow; k++, index1++, index2++) { BASE tmp = VECTOR(m->data)[index1]; VECTOR(m->data)[index1] = VECTOR(m->data)[index2]; VECTOR(m->data)[index2] = tmp; } return 0; } /** * \function igraph_matrix_add_constant * Add a constant to every element. * * \param m The input matrix. * \param plud The constant to add. * * Time complexity: O(mn), the number of elements. */ void FUNCTION(igraph_matrix, add_constant)(TYPE(igraph_matrix) *m, BASE plus) { FUNCTION(igraph_vector, add_constant)(&m->data, plus); } /** * \function igraph_matrix_add * Add two matrices. * * Add \p m2 to \p m1, and store the result in \p m1. The dimensions of the * matrices must match. * \param m1 The first matrix; the result will be stored here. * \param m2 The second matrix; it is left unchanged. * \return Error code. * * Time complexity: O(mn), the number of elements. */ int FUNCTION(igraph_matrix, add)(TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2) { if (m1->nrow != m2->nrow || m1->ncol != m2->ncol) { IGRAPH_ERROR("Cannot add non-conformant matrices", IGRAPH_EINVAL); } return FUNCTION(igraph_vector, add)(&m1->data, &m2->data); } /** * \function igraph_matrix_sub * Difference of two matrices. * * Subtract \p m2 from \p m1 and store the result in \p m1. * The dimensions of the two matrices must match. * \param m1 The first matrix; the result is stored here. * \param m2 The second matrix; it is left unchanged. * \return Error code. * * Time complexity: O(mn), the number of elements. */ int FUNCTION(igraph_matrix, sub)(TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2) { if (m1->nrow != m2->nrow || m1->ncol != m2->ncol) { IGRAPH_ERROR("Cannot subtract non-conformant matrices", IGRAPH_EINVAL); } return FUNCTION(igraph_vector, sub)(&m1->data, &m2->data); } /** * \function igraph_matrix_mul_elements * Elementwise multiplication. * * Multiply \p m1 by \p m2 elementwise and store the result in \p m1. * The dimensions of the two matrices must match. * \param m1 The first matrix; the result is stored here. * \param m2 The second matrix; it is left unchanged. * \return Error code. * * Time complexity: O(mn), the number of elements. */ int FUNCTION(igraph_matrix, mul_elements)(TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2) { if (m1->nrow != m2->nrow || m1->ncol != m2->ncol) { IGRAPH_ERROR("Cannot multiply non-conformant matrices", IGRAPH_EINVAL); } return FUNCTION(igraph_vector, mul)(&m1->data, &m2->data); } /** * \function igraph_matrix_div_elements * Elementwise division. * * Divide \p m1 by \p m2 elementwise and store the result in \p m1. * The dimensions of the two matrices must match. * \param m1 The dividend. The result is store here. * \param m2 The divisor. It is left unchanged. * \return Error code. * * Time complexity: O(mn), the number of elements. */ int FUNCTION(igraph_matrix, div_elements)(TYPE(igraph_matrix) *m1, const TYPE(igraph_matrix) *m2) { if (m1->nrow != m2->nrow || m1->ncol != m2->ncol) { IGRAPH_ERROR("Cannot divide non-conformant matrices", IGRAPH_EINVAL); } return FUNCTION(igraph_vector, div)(&m1->data, &m2->data); } #ifndef NOTORDERED /** * \function igraph_matrix_min * \brief Smallest element of a matrix. * * The matrix must be non-empty. * \param m The input matrix. * \return The smallest element of \p m, or NaN if any element is NaN. * * Time complexity: O(mn), the number of elements in the matrix. */ igraph_real_t FUNCTION(igraph_matrix, min)(const TYPE(igraph_matrix) *m) { return FUNCTION(igraph_vector, min)(&m->data); } /** * \function igraph_matrix_which_min * \brief Indices of the smallest element. * * * The matrix must be non-empty. If the smallest element is not unique, * then the indices of the first such element are returned. If the matrix contains * NaN values, the indices of the first NaN value are returned. * \param m The matrix. * \param i Pointer to a long int. The row index of the * minimum is stored here. * \param j Pointer to a long int. The column index of * the minimum is stored here. * \return Error code. * * Time complexity: O(mn), the number of elements. */ int FUNCTION(igraph_matrix, which_min)(const TYPE(igraph_matrix) *m, long int *i, long int *j) { long int vmin = FUNCTION(igraph_vector, which_min)(&m->data); *i = vmin % m->nrow; *j = vmin / m->nrow; return 0; } /** * \function igraph_matrix_which_max * \brief Indices of the largest element. * * * The matrix must be non-empty. If the largest element is not unique, * then the indices of the first such element are returned. If the matrix contains * NaN values, the indices of the first NaN value are returned. * \param m The matrix. * \param i Pointer to a long int. The row index of the * maximum is stored here. * \param j Pointer to a long int. The column index of * the maximum is stored here. * \return Error code. * * Time complexity: O(mn), the number of elements. */ int FUNCTION(igraph_matrix, which_max)(const TYPE(igraph_matrix) *m, long int *i, long int *j) { long int vmax = FUNCTION(igraph_vector, which_max)(&m->data); *i = vmax % m->nrow; *j = vmax / m->nrow; return 0; } /** * \function igraph_matrix_minmax * \brief Minimum and maximum elements of a matrix. * * Handy if you want to have both the smallest and largest element of * a matrix. The matrix is only traversed once. The matrix must be non-empty. * If a matrix contains at least one NaN, both \c min and \c max will be NaN. * \param m The input matrix. It must contain at least one element. * \param min Pointer to a base type variable. The minimum is stored here. * \param max Pointer to a base type variable. The maximum is stored here. * \return Error code. * * Time complexity: O(mn), the number of elements. */ int FUNCTION(igraph_matrix, minmax)(const TYPE(igraph_matrix) *m, BASE *min, BASE *max) { return FUNCTION(igraph_vector, minmax)(&m->data, min, max); } /** * \function igraph_matrix_which_minmax * \brief Indices of the minimum and maximum elements * * * Handy if you need the indices of the smallest and largest * elements. The matrix is traversed only once. The matrix must be * non-empty. If the minimum or maximum is not unique, the index * of the first minimum or the first maximum is returned, respectively. * If a matrix contains at least one NaN, both \c which_min and \c which_max * will point to the first NaN value. * \param m The input matrix. * \param imin Pointer to a long int, the row index of * the minimum is stored here. * \param jmin Pointer to a long int, the column index of * the minimum is stored here. * \param imax Pointer to a long int, the row index of * the maximum is stored here. * \param jmax Pointer to a long int, the column index of * the maximum is stored here. * \return Error code. * * Time complexity: O(mn), the number of elements. */ int FUNCTION(igraph_matrix, which_minmax)(const TYPE(igraph_matrix) *m, long int *imin, long int *jmin, long int *imax, long int *jmax) { long int vmin, vmax; FUNCTION(igraph_vector, which_minmax)(&m->data, &vmin, &vmax); *imin = vmin % m->nrow; *jmin = vmin / m->nrow; *imax = vmax % m->nrow; *jmax = vmax / m->nrow; return 0; } #endif /** * \function igraph_matrix_isnull * Check for a null matrix. * * Checks whether all elements are zero. * \param m The input matrix. * \return Boolean, \c TRUE is \p m contains only zeros and \c FALSE * otherwise. * * Time complexity: O(mn), the number of elements. */ igraph_bool_t FUNCTION(igraph_matrix, isnull)(const TYPE(igraph_matrix) *m) { return FUNCTION(igraph_vector, isnull)(&m->data); } /** * \function igraph_matrix_empty * Check for an empty matrix. * * It is possible to have a matrix with zero rows or zero columns, or * even both. This functions checks for these. * \param m The input matrix. * \return Boolean, \c TRUE if the matrix contains zero elements, and * \c FALSE otherwise. * * Time complexity: O(1). */ igraph_bool_t FUNCTION(igraph_matrix, empty)(const TYPE(igraph_matrix) *m) { return FUNCTION(igraph_vector, empty)(&m->data); } /** * \function igraph_matrix_is_symmetric * Check for symmetric matrix. * * A non-square matrix is not symmetric by definition. * \param m The input matrix. * \return Boolean, \c TRUE if the matrix is square and symmetric, \c * FALSE otherwise. * * Time complexity: O(mn), the number of elements. O(1) for non-square * matrices. */ igraph_bool_t FUNCTION(igraph_matrix, is_symmetric)(const TYPE(igraph_matrix) *m) { long int n = m->nrow; long int r, c; if (m->ncol != n) { return 0; } for (r = 1; r < n; r++) { for (c = 0; c < r; c++) { BASE a1 = MATRIX(*m, r, c); BASE a2 = MATRIX(*m, c, r); #ifdef EQ if (!EQ(a1, a2)) { return 0; } #else if (a1 != a2) { return 0; } #endif } } return 1; } /** * \function igraph_matrix_prod * Product of the elements. * * Note this function can result in overflow easily, even for not too * big matrices. * \param m The input matrix. * \return The product of the elements. * * Time complexity: O(mn), the number of elements. */ BASE FUNCTION(igraph_matrix, prod)(const TYPE(igraph_matrix) *m) { return FUNCTION(igraph_vector, prod)(&m->data); } /** * \function igraph_matrix_rowsum * Rowwise sum. * * Calculate the sum of the elements in each row. * \param m The input matrix. * \param res Pointer to an initialized vector; the result is stored * here. It will be resized if necessary. * \return Error code. * * Time complexity: O(mn), the number of elements in the matrix. */ int FUNCTION(igraph_matrix, rowsum)(const TYPE(igraph_matrix) *m, TYPE(igraph_vector) *res) { long int nrow = m->nrow, ncol = m->ncol; long int r, c; BASE sum; IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(res, nrow)); for (r = 0; r < nrow; r++) { sum = ZERO; for (c = 0; c < ncol; c++) { #ifdef SUM SUM(sum, sum, MATRIX(*m, r, c)); #else sum += MATRIX(*m, r, c); #endif } VECTOR(*res)[r] = sum; } return 0; } /** * \function igraph_matrix_colsum * Columnwise sum. * * Calculate the sum of the elements in each column. * \param m The input matrix. * \param res Pointer to an initialized vector; the result is stored * here. It will be resized if necessary. * \return Error code. * * Time complexity: O(mn), the number of elements in the matrix. */ int FUNCTION(igraph_matrix, colsum)(const TYPE(igraph_matrix) *m, TYPE(igraph_vector) *res) { long int nrow = m->nrow, ncol = m->ncol; long int r, c; BASE sum; IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(res, ncol)); for (c = 0; c < ncol; c++) { sum = ZERO; for (r = 0; r < nrow; r++) { #ifdef SUM SUM(sum, sum, MATRIX(*m, r, c)); #else sum += MATRIX(*m, r, c); #endif } VECTOR(*res)[c] = sum; } return 0; } /** * \function igraph_matrix_contains * Search for an element. * * Search for the given element in the matrix. * \param m The input matrix. * \param e The element to search for. * \return Boolean, \c TRUE if the matrix contains \p e, \c FALSE * otherwise. * * Time complexity: O(mn), the number of elements. */ igraph_bool_t FUNCTION(igraph_matrix, contains)(const TYPE(igraph_matrix) *m, BASE e) { return FUNCTION(igraph_vector, contains)(&m->data, e); } /** * \function igraph_matrix_search * Search from a given position. * * Search for an element in a matrix and start the search from the * given position. The search is performed columnwise. * \param m The input matrix. * \param from The position to search from, the positions are * enumerated columnwise. * \param what The element to search for. * \param pos Pointer to a long int. If the element is * found, then this is set to the position of its first appearance. * \param row Pointer to a long int. If the element is * found, then this is set to its row index. * \param col Pointer to a long int. If the element is * found, then this is set to its column index. * \return Boolean, \c TRUE if the element is found, \c FALSE * otherwise. * * Time complexity: O(mn), the number of elements. */ igraph_bool_t FUNCTION(igraph_matrix, search)(const TYPE(igraph_matrix) *m, long int from, BASE what, long int *pos, long int *row, long int *col) { igraph_bool_t find = FUNCTION(igraph_vector, search)(&m->data, from, what, pos); if (find) { *row = *pos % m->nrow; *col = *pos / m->nrow; } return find; } /** * \function igraph_matrix_remove_row * Remove a row. * * A row is removed from the matrix. * \param m The input matrix. * \param row The index of the row to remove. * \return Error code. * * Time complexity: O(mn), the number of elements in the matrix. */ int FUNCTION(igraph_matrix, remove_row)(TYPE(igraph_matrix) *m, long int row) { long int c, r, index = row + 1, leap = 1, n = m->nrow * m->ncol; if (row >= m->nrow) { IGRAPH_ERROR("Cannot remove row, index out of range", IGRAPH_EINVAL); } for (c = 0; c < m->ncol; c++) { for (r = 0; r < m->nrow - 1 && index < n; r++) { VECTOR(m->data)[index - leap] = VECTOR(m->data)[index]; index++; } leap++; index++; } m->nrow--; IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(&m->data, m->nrow * m->ncol)); return 0; } /** * \function igraph_matrix_select_cols * \brief Select some columns of a matrix. * * This function selects some columns of a matrix and returns them in a * new matrix. The result matrix should be initialized before calling * the function. * \param m The input matrix. * \param res The result matrix. It should be initialized and will be * resized as needed. * \param cols Vector; it contains the column indices (starting with * zero) to extract. Note that no range checking is performed. * \return Error code. * * Time complexity: O(nm), n is the number of rows, m the number of * columns of the result matrix. */ int FUNCTION(igraph_matrix, select_cols)(const TYPE(igraph_matrix) *m, TYPE(igraph_matrix) *res, const igraph_vector_t *cols) { long int ncols = igraph_vector_size(cols); long int nrows = m->nrow; long int i, j; IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(res, nrows, ncols)); for (i = 0; i < nrows; i++) { for (j = 0; j < ncols; j++) { MATRIX(*res, i, j) = MATRIX(*m, i, (long int)VECTOR(*cols)[j]); } } return 0; } #ifdef OUT_FORMAT #ifndef USING_R int FUNCTION(igraph_matrix, print)(const TYPE(igraph_matrix) *m) { long int nr = FUNCTION(igraph_matrix, nrow)(m); long int nc = FUNCTION(igraph_matrix, ncol)(m); long int i, j; for (i = 0; i < nr; i++) { for (j = 0; j < nc; j++) { if (j != 0) { putchar(' '); } printf(OUT_FORMAT, MATRIX(*m, i, j)); } printf("\n"); } return 0; } int FUNCTION(igraph_matrix, printf)(const TYPE(igraph_matrix) *m, const char *format) { long int nr = FUNCTION(igraph_matrix, nrow)(m); long int nc = FUNCTION(igraph_matrix, ncol)(m); long int i, j; for (i = 0; i < nr; i++) { for (j = 0; j < nc; j++) { if (j != 0) { putchar(' '); } printf(format, MATRIX(*m, i, j)); } printf("\n"); } return 0; } #endif int FUNCTION(igraph_matrix, fprint)(const TYPE(igraph_matrix) *m, FILE *file) { long int nr = FUNCTION(igraph_matrix, nrow)(m); long int nc = FUNCTION(igraph_matrix, ncol)(m); long int i, j; for (i = 0; i < nr; i++) { for (j = 0; j < nc; j++) { if (j != 0) { fputc(' ', file); } fprintf(file, OUT_FORMAT, MATRIX(*m, i, j)); } fprintf(file, "\n"); } return 0; } #endif leidenbase/src/core/core/indheap.h0000644000176200001440000001346514447675374016633 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CORE_INDHEAP_H #define IGRAPH_CORE_INDHEAP_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_vector.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Indexed heap */ /* -------------------------------------------------- */ /** * Indexed heap data type. * \ingroup internal */ typedef struct s_indheap { igraph_real_t* stor_begin; igraph_real_t* stor_end; igraph_real_t* end; int destroy; long int* index_begin; } igraph_indheap_t; #define IGRAPH_INDHEAP_NULL { 0,0,0,0,0 } int igraph_indheap_init (igraph_indheap_t* h, long int size); int igraph_indheap_init_array (igraph_indheap_t *t, igraph_real_t* data, long int len); void igraph_indheap_destroy (igraph_indheap_t* h); int igraph_indheap_clear(igraph_indheap_t *h); igraph_bool_t igraph_indheap_empty (igraph_indheap_t* h); int igraph_indheap_push (igraph_indheap_t* h, igraph_real_t elem); int igraph_indheap_push_with_index(igraph_indheap_t* h, long int idx, igraph_real_t elem); int igraph_indheap_modify(igraph_indheap_t* h, long int idx, igraph_real_t elem); igraph_real_t igraph_indheap_max (igraph_indheap_t* h); igraph_real_t igraph_indheap_delete_max(igraph_indheap_t* h); long int igraph_indheap_size (igraph_indheap_t* h); int igraph_indheap_reserve (igraph_indheap_t* h, long int size); long int igraph_indheap_max_index(igraph_indheap_t *h); /* -------------------------------------------------- */ /* Doubly indexed heap */ /* -------------------------------------------------- */ /* This is a heap containing double elements and two indices, its intended usage is the storage of weighted edges. */ /** * Doubly indexed heap data type. * \ingroup internal */ typedef struct s_indheap_d { igraph_real_t* stor_begin; igraph_real_t* stor_end; igraph_real_t* end; int destroy; long int* index_begin; long int* index2_begin; } igraph_d_indheap_t; #define IGRAPH_D_INDHEAP_NULL { 0,0,0,0,0,0 } IGRAPH_PRIVATE_EXPORT int igraph_d_indheap_init(igraph_d_indheap_t *h, long int size); IGRAPH_PRIVATE_EXPORT void igraph_d_indheap_destroy(igraph_d_indheap_t *h); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_d_indheap_empty(igraph_d_indheap_t *h); IGRAPH_PRIVATE_EXPORT int igraph_d_indheap_push(igraph_d_indheap_t *h, igraph_real_t elem, long int idx, long int idx2); IGRAPH_PRIVATE_EXPORT igraph_real_t igraph_d_indheap_max(igraph_d_indheap_t *h); IGRAPH_PRIVATE_EXPORT igraph_real_t igraph_d_indheap_delete_max(igraph_d_indheap_t *h); IGRAPH_PRIVATE_EXPORT long int igraph_d_indheap_size(igraph_d_indheap_t *h); IGRAPH_PRIVATE_EXPORT int igraph_d_indheap_reserve(igraph_d_indheap_t *h, long int size); IGRAPH_PRIVATE_EXPORT void igraph_d_indheap_max_index(igraph_d_indheap_t *h, long int *idx, long int *idx2); /* -------------------------------------------------- */ /* Two-way indexed heap */ /* -------------------------------------------------- */ /* This is a smart indexed heap. In addition to the "normal" indexed heap it allows to access every element through its index in O(1) time. In other words, for this heap the _modify operation is O(1), the normal heap does this in O(n) time.... */ typedef struct igraph_2wheap_t { long int size; igraph_vector_t data; igraph_vector_long_t index; igraph_vector_long_t index2; } igraph_2wheap_t; IGRAPH_PRIVATE_EXPORT int igraph_2wheap_init(igraph_2wheap_t *h, long int size); IGRAPH_PRIVATE_EXPORT void igraph_2wheap_destroy(igraph_2wheap_t *h); IGRAPH_PRIVATE_EXPORT int igraph_2wheap_clear(igraph_2wheap_t *h); IGRAPH_PRIVATE_EXPORT int igraph_2wheap_push_with_index(igraph_2wheap_t *h, long int idx, igraph_real_t elem); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_2wheap_empty(const igraph_2wheap_t *h); IGRAPH_PRIVATE_EXPORT long int igraph_2wheap_size(const igraph_2wheap_t *h); IGRAPH_PRIVATE_EXPORT long int igraph_2wheap_max_size(const igraph_2wheap_t *h); IGRAPH_PRIVATE_EXPORT igraph_real_t igraph_2wheap_max(const igraph_2wheap_t *h); IGRAPH_PRIVATE_EXPORT long int igraph_2wheap_max_index(const igraph_2wheap_t *h); IGRAPH_PRIVATE_EXPORT igraph_real_t igraph_2wheap_deactivate_max(igraph_2wheap_t *h); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_2wheap_has_elem(const igraph_2wheap_t *h, long int idx); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_2wheap_has_active(const igraph_2wheap_t *h, long int idx); IGRAPH_PRIVATE_EXPORT igraph_real_t igraph_2wheap_get(const igraph_2wheap_t *h, long int idx); IGRAPH_PRIVATE_EXPORT igraph_real_t igraph_2wheap_delete_max(igraph_2wheap_t *h); IGRAPH_PRIVATE_EXPORT igraph_real_t igraph_2wheap_delete_max_index(igraph_2wheap_t *h, long int *idx); IGRAPH_PRIVATE_EXPORT int igraph_2wheap_modify(igraph_2wheap_t *h, long int idx, igraph_real_t elem); IGRAPH_PRIVATE_EXPORT int igraph_2wheap_check(igraph_2wheap_t *h); __END_DECLS #endif leidenbase/src/core/core/psumtree.c0000644000176200001440000002105014447675374017047 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA Copyright (C) 2006 Elliot Paquette Kalamazoo College, 1200 Academy st, Kalamazoo, MI This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_psumtree.h" #include "igraph_error.h" #include static double igraph_i_log2(double f) { return log(f) / log(2.0); } /** * \ingroup psumtree * \section igraph_psumtree * * The \type igraph_psumtree_t data type represents a partial prefix sum * tree. A partial prefix sum tree is a data structure that can be used to draw * samples from a discrete probability distribution with dynamic probabilities * that are updated frequently. This is achieved by creating a binary tree where * the leaves are the items. Each leaf contains the probability corresponding to * the items. Intermediate nodes of the tree always contain the sum of its two * children. When the value of a leaf node is updated, the values of its * ancestors are also updated accordingly. * * Samples can be drawn from the probability distribution represented by * the tree by generating a uniform random number between 0 (inclusive) and the * value of the root of the tree (exclusive), and then following the branches * of the tree as follows. In each step, the value in the current node is * compared with the generated number. If the value in the node is larger, * the left branch of the tree is taken; otherwise the generated number is * decreased by the value in the node and the right branch of the tree is * taken, until a leaf node is reached. * * Note that the sampling process works only if all the values in the tree * are non-negative. This is enforced by the object; in particular, trying to * set a negative value for an item will produce an igraph error. */ /* * Internally, a partial prefix sum tree is stored in a contiguous chunk of * memory which we treat as a vector v. The first part (0,...,offset - 1) of * the vector v contains the prefixes of the values contained in the latter part * (offset, offset + size - 1) of vector v. * * More precisely: the part between (offset, offset + size - 1) of vector v * contains the values (not necessarily probabilities) corresponding to the * individual items. For the part in front of it, it holds that the value at * index i (zero-based) is the sum of values at index (2*i + 1) and index * (2*i + 2). The item at index zero contains the sum of all values in the * slice between (offset, offset + size - 1). */ /** * \ingroup psumtree * \function igraph_psumtree_init * \brief Initializes a partial prefix sum tree. * * * The tree is initialized with a fixed number of elements. After initialization, * the value corresponding to each element is zero. * * \param t The tree to initialize * \param size The number of elements in the tree * \return Error code, typically \c IGRAPH_ENOMEM if there is not enough memory * * Time complexity: O(n) for a tree containing n elements */ int igraph_psumtree_init(igraph_psumtree_t *t, long int size) { t->size = size; t->offset = (long int) (pow(2, ceil(igraph_i_log2(size))) - 1); IGRAPH_CHECK(igraph_vector_init(&t->v, t->offset + t->size)); return 0; } /** * \ingroup psumtree * \function igraph_psumtree_reset * \brief Resets all the values in the tree to zero. * * \param t The tree to reset. */ void igraph_psumtree_reset(igraph_psumtree_t *t) { igraph_vector_fill(&(t->v), 0); } /** * \ingroup psumtree * \function igraph_psumtree_destroy * \brief Destroys a partial prefix sum tree. * * * All partial prefix sum trees initialized by \ref igraph_psumtree_init() * should be properly destroyed by this function. A destroyed tree needs to be * reinitialized by \ref igraph_psumtree_init() if you want to use it again. * * \param t Pointer to the (previously initialized) tree to destroy. * * Time complexity: operating system dependent. */ void igraph_psumtree_destroy(igraph_psumtree_t *t) { igraph_vector_destroy(&(t->v)); } /** * \ingroup psumtree * \function igraph_psumtree_get * \brief Retrieves the value corresponding to an item in the tree. * * * * \param t The tree to query. * \param idx The index of the item whose value is to be retrieved. * \return The value corresponding to the item with the given index. * * Time complexity: O(1) */ igraph_real_t igraph_psumtree_get(const igraph_psumtree_t *t, long int idx) { const igraph_vector_t *tree = &t->v; return VECTOR(*tree)[t->offset + idx]; } /** * \ingroup psumtree * \function igraph_psumtree_search * \brief Finds an item in the tree, given a value. * * This function finds the item with the lowest index where it holds that the * sum of all the items with a \em lower index is less than or equal to the given * value and that the sum of all the items with a lower index plus the item * itself is larger than the given value. * * * If you think about the partial prefix sum tree as a tool to sample from a * discrete probability distribution, then calling this function repeatedly * with uniformly distributed random numbers in the range 0 (inclusive) to the * sum of all values in the tree (exclusive) will sample the items in the tree * with a probability that is proportional to their associated values. * * \param t The tree to query. * \param idx The index of the item is returned here. * \param search The value to use for the search. * \return Error code; currently the search always succeeds. * * Time complexity: O(log n), where n is the number of items in the tree. */ int igraph_psumtree_search(const igraph_psumtree_t *t, long int *idx, igraph_real_t search) { const igraph_vector_t *tree = &t->v; long int i = 1; long int size = igraph_vector_size(tree); while ( 2 * i + 1 <= size) { if ( search <= VECTOR(*tree)[i * 2 - 1] ) { i <<= 1; } else { search -= VECTOR(*tree)[i * 2 - 1]; i <<= 1; i += 1; } } if (2 * i <= size) { i = 2 * i; } *idx = i - t->offset - 1; return IGRAPH_SUCCESS; } /** * \ingroup psumtree * \function igraph_psumtree_update * \brief Updates the value associated to an item in the tree. * * \param t The tree to query. * \param idx The index of the item to update. * \param new_value The new value of the item. * \return Error code, \c IGRAPH_EINVAL if the new value is negative or NaN, * \c IGRAPH_SUCCESS if the operation was successful. * * Time complexity: O(log n), where n is the number of items in the tree. */ int igraph_psumtree_update(igraph_psumtree_t *t, long int idx, igraph_real_t new_value) { const igraph_vector_t *tree = &t->v; igraph_real_t difference; if (new_value >= 0) { idx = idx + t->offset + 1; difference = new_value - VECTOR(*tree)[idx - 1]; while ( idx >= 1 ) { VECTOR(*tree)[idx - 1] += difference; idx >>= 1; } return IGRAPH_SUCCESS; } else { /* caters for negative values and NaN */ return IGRAPH_EINVAL; } } /** * \ingroup psumtree * \function igraph_psumtree_size * \brief Returns the size of the tree. * * \param t The tree object * \return The number of discrete items in the tree. * * Time complexity: O(1). */ long int igraph_psumtree_size(const igraph_psumtree_t *t) { return t->size; } /** * \ingroup psumtree * \function igraph_psumtree_sum * \brief Returns the sum of the values of the leaves in the tree. * * \param t The tree object * \return The sum of the values of the leaves in the tree. * * Time complexity: O(1). */ igraph_real_t igraph_psumtree_sum(const igraph_psumtree_t *t) { return VECTOR(t->v)[0]; } leidenbase/src/core/core/grid.h0000644000176200001440000000571614447675374016150 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CORE_GRID_H #define IGRAPH_CORE_GRID_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_matrix.h" #include "igraph_vector.h" __BEGIN_DECLS /** * 2d grid containing points */ typedef struct igraph_2dgrid_t { igraph_matrix_t *coords; igraph_real_t minx, maxx, deltax; igraph_real_t miny, maxy, deltay; long int stepsx, stepsy; igraph_matrix_t startidx; igraph_vector_t next; igraph_vector_t prev; igraph_real_t massx, massy; /* The sum of the coordinates */ long int vertices; /* Number of active vertices */ } igraph_2dgrid_t; int igraph_2dgrid_init(igraph_2dgrid_t *grid, igraph_matrix_t *coords, igraph_real_t minx, igraph_real_t maxx, igraph_real_t deltax, igraph_real_t miny, igraph_real_t maxy, igraph_real_t deltay); void igraph_2dgrid_destroy(igraph_2dgrid_t *grid); void igraph_2dgrid_add(igraph_2dgrid_t *grid, long int elem, igraph_real_t xc, igraph_real_t yc); void igraph_2dgrid_add2(igraph_2dgrid_t *grid, long int elem); void igraph_2dgrid_move(igraph_2dgrid_t *grid, long int elem, igraph_real_t xc, igraph_real_t yc); void igraph_2dgrid_getcenter(const igraph_2dgrid_t *grid, igraph_real_t *massx, igraph_real_t *massy); igraph_bool_t igraph_2dgrid_in(const igraph_2dgrid_t *grid, long int elem); igraph_real_t igraph_2dgrid_dist(const igraph_2dgrid_t *grid, long int e1, long int e2); int igraph_2dgrid_neighbors(igraph_2dgrid_t *grid, igraph_vector_t *eids, igraph_integer_t vid, igraph_real_t r); typedef struct igraph_2dgrid_iterator_t { long int vid, x, y; long int nei; long int nx[4], ny[4], ncells; } igraph_2dgrid_iterator_t; void igraph_2dgrid_reset(igraph_2dgrid_t *grid, igraph_2dgrid_iterator_t *it); igraph_integer_t igraph_2dgrid_next(igraph_2dgrid_t *grid, igraph_2dgrid_iterator_t *it); igraph_integer_t igraph_2dgrid_next_nei(igraph_2dgrid_t *grid, igraph_2dgrid_iterator_t *it); __END_DECLS #endif leidenbase/src/core/core/strvector.c0000644000176200001440000004200214447675374017236 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_strvector.h" #include "igraph_memory.h" #include "igraph_error.h" #include /* memcpy & co. */ #include /** * \section igraph_strvector_t * The igraph_strvector_t type is a vector of strings. * The current implementation is very simple and not too efficient. It * works fine for not too many strings, e.g. the list of attribute * names is returned in a string vector by \ref * igraph_cattribute_list(). Do not expect great performance from this * type. * * * \example examples/simple/igraph_strvector.c * */ /** * \ingroup strvector * \function igraph_strvector_init * \brief Initialize * * Reserves memory for the string vector, a string vector must be * first initialized before calling other functions on it. * All elements of the string vector are set to the empty string. * \param sv Pointer to an initialized string vector. * \param len The (initial) length of the string vector. * \return Error code. * * Time complexity: O(\p len). */ int igraph_strvector_init(igraph_strvector_t *sv, long int len) { long int i; sv->data = IGRAPH_CALLOC(len, char*); if (sv->data == 0) { IGRAPH_ERROR("strvector init failed", IGRAPH_ENOMEM); } for (i = 0; i < len; i++) { sv->data[i] = IGRAPH_CALLOC(1, char); if (sv->data[i] == 0) { igraph_strvector_destroy(sv); IGRAPH_ERROR("strvector init failed", IGRAPH_ENOMEM); } sv->data[i][0] = '\0'; } sv->len = len; return 0; } /** * \ingroup strvector * \function igraph_strvector_destroy * \brief Free allocated memory * * Destroy a string vector. It may be reinitialized with \ref * igraph_strvector_init() later. * \param sv The string vector. * * Time complexity: O(l), the total length of the strings, maybe less * depending on the memory manager. */ void igraph_strvector_destroy(igraph_strvector_t *sv) { long int i; IGRAPH_ASSERT(sv != 0); if (sv->data != 0) { for (i = 0; i < sv->len; i++) { if (sv->data[i] != 0) { IGRAPH_FREE(sv->data[i]); } } IGRAPH_FREE(sv->data); } } /** * \ingroup strvector * \function igraph_strvector_get * \brief Indexing * * Query an element of a string vector. See also the \ref STR macro * for an easier way. * \param sv The input string vector. * \param idx The index of the element to query. * \param Pointer to a char*, the address of the string * is stored here. * * Time complexity: O(1). */ void igraph_strvector_get(const igraph_strvector_t *sv, long int idx, char **value) { IGRAPH_ASSERT(sv != 0); IGRAPH_ASSERT(sv->data != 0); IGRAPH_ASSERT(sv->data[idx] != 0); *value = sv->data[idx]; } /** * \ingroup strvector * \function igraph_strvector_set * \brief Set an element * * The provided \p value is copied into the \p idx position in the * string vector. * \param sv The string vector. * \param idx The position to set. * \param value The new value. * \return Error code. * * Time complexity: O(l), the length of the new string. Maybe more, * depending on the memory management, if reallocation is needed. */ int igraph_strvector_set(igraph_strvector_t *sv, long int idx, const char *value) { size_t value_len; IGRAPH_ASSERT(sv != 0); IGRAPH_ASSERT(sv->data != 0); value_len = strlen(value); if (sv->data[idx] == 0) { sv->data[idx] = IGRAPH_CALLOC(value_len + 1, char); if (sv->data[idx] == 0) { IGRAPH_ERROR("strvector set failed", IGRAPH_ENOMEM); } } else { char *tmp = IGRAPH_REALLOC(sv->data[idx], value_len + 1, char); if (tmp == 0) { IGRAPH_ERROR("strvector set failed", IGRAPH_ENOMEM); } sv->data[idx] = tmp; } strcpy(sv->data[idx], value); return 0; } /** * \ingroup strvector * \function igraph_strvector_set2 * \brief Sets an element. * * This is almost the same as \ref igraph_strvector_set, but the new * value is not a zero terminated string, but its length is given. * \param sv The string vector. * \param idx The position to set. * \param value The new value. * \param len The length of the new value. * \return Error code. * * Time complexity: O(l), the length of the new string. Maybe more, * depending on the memory management, if reallocation is needed. */ int igraph_strvector_set2(igraph_strvector_t *sv, long int idx, const char *value, int len) { if (idx < 0 || idx >= sv->len) { IGRAPH_ERROR("String vector index out of bounds.", IGRAPH_EINVAL); } IGRAPH_ASSERT(sv != 0); IGRAPH_ASSERT(sv->data != 0); if (sv->data[idx] == 0) { sv->data[idx] = IGRAPH_CALLOC(len + 1, char); if (sv->data[idx] == 0) { IGRAPH_ERROR("strvector set failed", IGRAPH_ENOMEM); } } else { char *tmp = IGRAPH_REALLOC(sv->data[idx], (size_t) len + 1, char); if (tmp == 0) { IGRAPH_ERROR("strvector set failed", IGRAPH_ENOMEM); } sv->data[idx] = tmp; } memcpy(sv->data[idx], value, (size_t) len * sizeof(char)); sv->data[idx][len] = '\0'; return IGRAPH_SUCCESS; } /** * \ingroup strvector * \function igraph_strvector_remove_section * \brief Removes a section from a string vector. * \todo repair realloc */ void igraph_strvector_remove_section(igraph_strvector_t *v, long int from, long int to) { long int i; /* char **tmp; */ IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->data != 0); for (i = from; i < to; i++) { if (v->data[i] != 0) { IGRAPH_FREE(v->data[i]); } } for (i = 0; i < v->len - to; i++) { v->data[from + i] = v->data[to + i]; } v->len -= (to - from); /* try to make it smaller */ /* tmp=IGRAPH_REALLOC(v->data, v->len, char*); */ /* if (tmp!=0) { */ /* v->data=tmp; */ /* } */ } /** * \ingroup strvector * \function igraph_strvector_remove * \brief Removes a single element from a string vector. * * The string will be one shorter. * \param v The string vector. * \param elem The index of the element to remove. * * Time complexity: O(n), the length of the string. */ void igraph_strvector_remove(igraph_strvector_t *v, long int elem) { IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->data != 0); igraph_strvector_remove_section(v, elem, elem + 1); } /** * \ingroup strvector * \function igraph_strvector_move_interval * \brief Copies an interval of a string vector. */ void igraph_strvector_move_interval(igraph_strvector_t *v, long int begin, long int end, long int to) { long int i; IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->data != 0); for (i = to; i < to + end - begin; i++) { if (v->data[i] != 0) { IGRAPH_FREE(v->data[i]); } } for (i = 0; i < end - begin; i++) { if (v->data[begin + i] != 0) { size_t len = strlen(v->data[begin + i]) + 1; v->data[to + i] = IGRAPH_CALLOC(len, char); memcpy(v->data[to + i], v->data[begin + i], sizeof(char)*len); } } } /** * \ingroup strvector * \function igraph_strvector_copy * \brief Initialization by copying. * * Initializes a string vector by copying another string vector. * \param to Pointer to an uninitialized string vector. * \param from The other string vector, to be copied. * \return Error code. * * Time complexity: O(l), the total length of the strings in \p from. */ int igraph_strvector_copy(igraph_strvector_t *to, const igraph_strvector_t *from) { long int i; char *str; IGRAPH_ASSERT(from != 0); /* IGRAPH_ASSERT(from->data != 0); */ to->data = IGRAPH_CALLOC(from->len, char*); if (to->data == 0) { IGRAPH_ERROR("Cannot copy string vector", IGRAPH_ENOMEM); } to->len = from->len; for (i = 0; i < from->len; i++) { int ret; igraph_strvector_get(from, i, &str); ret = igraph_strvector_set(to, i, str); if (ret != 0) { igraph_strvector_destroy(to); IGRAPH_ERROR("cannot copy string vector", ret); } } return 0; } /** * \function igraph_strvector_append * Concatenate two string vectors. * * \param to The first string vector, the result is stored here. * \param from The second string vector, it is kept unchanged. * \return Error code. * * Time complexity: O(n+l2), n is the number of strings in the new * string vector, l2 is the total length of strings in the \p from * string vector. */ int igraph_strvector_append(igraph_strvector_t *to, const igraph_strvector_t *from) { long int len1 = igraph_strvector_size(to), len2 = igraph_strvector_size(from); long int i; igraph_bool_t error = 0; IGRAPH_CHECK(igraph_strvector_resize(to, len1 + len2)); for (i = 0; i < len2; i++) { if (from->data[i][0] != '\0') { IGRAPH_FREE(to->data[len1 + i]); to->data[len1 + i] = strdup(from->data[i]); if (!to->data[len1 + i]) { error = 1; break; } } } if (error) { igraph_strvector_resize(to, len1); IGRAPH_ERROR("Cannot append string vector", IGRAPH_ENOMEM); } return 0; } /** * \function igraph_strvector_clear * Remove all elements * * After this operation the string vector will be empty. * \param sv The string vector. * * Time complexity: O(l), the total length of strings, maybe less, * depending on the memory manager. */ void igraph_strvector_clear(igraph_strvector_t *sv) { long int i, n = igraph_strvector_size(sv); char **tmp; for (i = 0; i < n; i++) { IGRAPH_FREE(sv->data[i]); } sv->len = 0; /* try to give back some memory */ tmp = IGRAPH_REALLOC(sv->data, 1, char*); if (tmp != 0) { sv->data = tmp; } } /** * \ingroup strvector * \function igraph_strvector_resize * \brief Resize * * If the new size is bigger then empty strings are added, if it is * smaller then the unneeded elements are removed. * \param v The string vector. * \param newsize The new size. * \return Error code. * * Time complexity: O(n), the number of strings if the vector is made * bigger, O(l), the total length of the deleted strings if it is made * smaller, maybe less, depending on memory management. */ int igraph_strvector_resize(igraph_strvector_t* v, long int newsize) { long int toadd = newsize - v->len, i, j; char **tmp; long int reallocsize = newsize; IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->data != 0); /* printf("resize %li to %li\n", v->len, newsize); */ if (newsize < v->len) { for (i = newsize; i < v->len; i++) { IGRAPH_FREE(v->data[i]); } /* try to give back some space */ tmp = IGRAPH_REALLOC(v->data, (size_t) reallocsize, char*); /* printf("resize %li to %li, %p\n", v->len, newsize, tmp); */ if (tmp != 0) { v->data = tmp; } } else if (newsize > v->len) { igraph_bool_t error = 0; tmp = IGRAPH_REALLOC(v->data, (size_t) reallocsize, char*); if (tmp == 0) { IGRAPH_ERROR("cannot resize string vector", IGRAPH_ENOMEM); } v->data = tmp; for (i = 0; i < toadd; i++) { v->data[v->len + i] = IGRAPH_CALLOC(1, char); if (v->data[v->len + i] == 0) { error = 1; break; } v->data[v->len + i][0] = '\0'; } if (error) { /* There was an error, free everything we've allocated so far */ for (j = 0; j < i; j++) { if (v->data[v->len + i] != 0) { IGRAPH_FREE(v->data[v->len + i]); } } /* Try to give back space */ tmp = IGRAPH_REALLOC(v->data, (size_t) (v->len), char*); if (tmp != 0) { v->data = tmp; } IGRAPH_ERROR("Cannot resize string vector", IGRAPH_ENOMEM); } } v->len = newsize; return 0; } /** * \ingroup strvector * \function igraph_strvector_size * \brief Gives the size of a string vector. * * \param sv The string vector. * \return The length of the string vector. * * Time complexity: O(1). */ long int igraph_strvector_size(const igraph_strvector_t *sv) { IGRAPH_ASSERT(sv != 0); IGRAPH_ASSERT(sv->data != 0); return sv->len; } /** * \ingroup strvector * \function igraph_strvector_add * \brief Adds an element to the back of a string vector. * * \param v The string vector. * \param value The string to add, it will be copied. * \return Error code. * * Time complexity: O(n+l), n is the total number of strings, l is the * length of the new string. */ int igraph_strvector_add(igraph_strvector_t *v, const char *value) { long int s = igraph_strvector_size(v); long int value_len = strlen(value); char **tmp; IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->data != 0); tmp = IGRAPH_REALLOC(v->data, (size_t) s + 1, char*); if (tmp == 0) { IGRAPH_ERROR("cannot add string to string vector", IGRAPH_ENOMEM); } v->data = tmp; v->data[s] = IGRAPH_CALLOC(value_len + 1, char); if (v->data[s] == 0) { IGRAPH_ERROR("cannot add string to string vector", IGRAPH_ENOMEM); } strcpy(v->data[s], value); v->len += 1; return 0; } /** * \ingroup strvector * \function igraph_strvector_permdelete * \brief Removes elements from a string vector (for internal use) */ void igraph_strvector_permdelete(igraph_strvector_t *v, const igraph_vector_t *index, long int nremove) { long int i; char **tmp; IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->data != 0); for (i = 0; i < igraph_strvector_size(v); i++) { if (VECTOR(*index)[i] != 0) { v->data[ (long int) VECTOR(*index)[i] - 1 ] = v->data[i]; } else { IGRAPH_FREE(v->data[i]); } } /* Try to make it shorter */ tmp = IGRAPH_REALLOC(v->data, v->len - nremove ? (size_t) (v->len - nremove) : 1, char*); if (tmp != 0) { v->data = tmp; } v->len -= nremove; } /** * \ingroup strvector * \function igraph_strvector_remove_negidx * \brief Removes elements from a string vector (for internal use) */ void igraph_strvector_remove_negidx(igraph_strvector_t *v, const igraph_vector_t *neg, long int nremove) { long int i, idx = 0; char **tmp; IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->data != 0); for (i = 0; i < igraph_strvector_size(v); i++) { if (VECTOR(*neg)[i] >= 0) { v->data[idx++] = v->data[i]; } else { IGRAPH_FREE(v->data[i]); } } /* Try to give back some memory */ tmp = IGRAPH_REALLOC(v->data, v->len - nremove ? (size_t) (v->len - nremove) : 1, char*); if (tmp != 0) { v->data = tmp; } v->len -= nremove; } /** * \ingroup strvector * \function igraph_strvector_print * \brief Prints a string vector. * * \param v The string vector. * \param file The file to write to. * \param sep The separator to print between strings. * \return Error code. */ int igraph_strvector_print(const igraph_strvector_t *v, FILE *file, const char *sep) { long int i, n = igraph_strvector_size(v); if (n != 0) { fprintf(file, "%s", STR(*v, 0)); } for (i = 1; i < n; i++) { fprintf(file, "%s%s", sep, STR(*v, i)); } return IGRAPH_SUCCESS; } int igraph_strvector_index(const igraph_strvector_t *v, igraph_strvector_t *newv, const igraph_vector_t *idx) { long int i, newlen = igraph_vector_size(idx); IGRAPH_CHECK(igraph_strvector_resize(newv, newlen)); for (i = 0; i < newlen; i++) { long int j = (long int) VECTOR(*idx)[i]; char *str; igraph_strvector_get(v, j, &str); igraph_strvector_set(newv, i, str); } return 0; } leidenbase/src/core/core/set.h0000644000176200001440000000454514447675374016015 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CORE_SET_H #define IGRAPH_CORE_SET_H #include "igraph_decls.h" #include "igraph_types.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Flexible set */ /* -------------------------------------------------- */ /** * Set containing integer numbers regardless of the order * \ingroup types */ typedef struct s_set { igraph_integer_t* stor_begin; igraph_integer_t* stor_end; igraph_integer_t* end; } igraph_set_t; #define IGRAPH_SET_NULL { 0,0,0 } #define IGRAPH_SET_INIT_FINALLY(v, size) \ do { IGRAPH_CHECK(igraph_set_init(v, size)); \ IGRAPH_FINALLY(igraph_set_destroy, v); } while (0) IGRAPH_PRIVATE_EXPORT int igraph_set_init(igraph_set_t* set, long int size); IGRAPH_PRIVATE_EXPORT void igraph_set_destroy(igraph_set_t* set); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_set_inited(igraph_set_t* set); IGRAPH_PRIVATE_EXPORT int igraph_set_reserve(igraph_set_t* set, long int size); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_set_empty(const igraph_set_t* set); IGRAPH_PRIVATE_EXPORT void igraph_set_clear(igraph_set_t* set); IGRAPH_PRIVATE_EXPORT long int igraph_set_size(const igraph_set_t* set); IGRAPH_PRIVATE_EXPORT int igraph_set_add(igraph_set_t* v, igraph_integer_t e); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_set_contains(igraph_set_t* set, igraph_integer_t e); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_set_iterate(igraph_set_t* set, long int* state, igraph_integer_t* element); __END_DECLS #endif leidenbase/src/core/core/spmatrix.c0000644000176200001440000010053214447675374017055 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_spmatrix.h" #include "igraph_error.h" #include /* memcpy & co. */ /** * \section igraph_spmatrix_constructor_and_destructor Sparse matrix constructors * and destructors. */ /** * \ingroup matrix * \function igraph_spmatrix_init * \brief Initializes a sparse matrix. * * * Every sparse matrix needs to be initialized before using it, this is done * by calling this function. A matrix has to be destroyed if it is not * needed any more, see \ref igraph_spmatrix_destroy(). * \param m Pointer to a not yet initialized sparse matrix object to be * initialized. * \param nrow The number of rows in the matrix. * \param ncol The number of columns in the matrix. * \return Error code. * * Time complexity: operating system dependent. */ int igraph_spmatrix_init(igraph_spmatrix_t *m, long int nrow, long int ncol) { IGRAPH_ASSERT(m != NULL); IGRAPH_VECTOR_INIT_FINALLY(&m->ridx, 0); IGRAPH_VECTOR_INIT_FINALLY(&m->cidx, ncol + 1); IGRAPH_VECTOR_INIT_FINALLY(&m->data, 0); IGRAPH_FINALLY_CLEAN(3); m->nrow = nrow; m->ncol = ncol; return 0; } /** * \ingroup matrix * \function igraph_spmatrix_destroy * \brief Destroys a sparse matrix object. * * * This function frees all the memory allocated for a sparse matrix * object. The destroyed object needs to be reinitialized before using * it again. * \param m The matrix to destroy. * * Time complexity: operating system dependent. */ void igraph_spmatrix_destroy(igraph_spmatrix_t *m) { IGRAPH_ASSERT(m != NULL); igraph_vector_destroy(&m->ridx); igraph_vector_destroy(&m->cidx); igraph_vector_destroy(&m->data); } /** * \ingroup matrix * \function igraph_spmatrix_copy * \brief Copies a sparse matrix. * * * Creates a sparse matrix object by copying another one. * \param to Pointer to an uninitialized sparse matrix object. * \param from The initialized sparse matrix object to copy. * \return Error code, \c IGRAPH_ENOMEM if there * isn't enough memory to allocate the new sparse matrix. * * Time complexity: O(n), the number * of elements in the matrix. */ int igraph_spmatrix_copy(igraph_spmatrix_t *to, const igraph_spmatrix_t *from) { IGRAPH_ASSERT(from != NULL); IGRAPH_ASSERT(to != NULL); to->nrow = from->nrow; to->ncol = from->ncol; IGRAPH_CHECK(igraph_vector_copy(&to->ridx, &from->ridx)); IGRAPH_CHECK(igraph_vector_copy(&to->cidx, &from->cidx)); IGRAPH_CHECK(igraph_vector_copy(&to->data, &from->data)); return 0; } /** * \section igraph_spmatrix_accessing_elements Accessing elements of a sparse matrix */ /** * \ingroup matrix * \function igraph_spmatrix_e * \brief Accessing an element of a sparse matrix. * * Note that there are no range checks right now. * \param m The matrix object. * \param row The index of the row, starting with zero. * \param col The index of the column, starting with zero. * * Time complexity: O(log n), where n is the number of nonzero elements in * the requested column. */ igraph_real_t igraph_spmatrix_e(const igraph_spmatrix_t *m, long int row, long int col) { long int start, end; IGRAPH_ASSERT(m != NULL); start = (long) VECTOR(m->cidx)[col]; end = (long) VECTOR(m->cidx)[col + 1] - 1; if (end < start) { return 0; } /* Elements residing in column col are between m->data[start] and * m->data[end], inclusive, ordered by row index */ while (start < end - 1) { long int mid = (start + end) / 2; if (VECTOR(m->ridx)[mid] > row) { end = mid; } else if (VECTOR(m->ridx)[mid] < row) { start = mid; } else { start = mid; break; } } if (VECTOR(m->ridx)[start] == row) { return VECTOR(m->data)[start]; } if (VECTOR(m->ridx)[start] != row && VECTOR(m->ridx)[end] == row) { return VECTOR(m->data)[end]; } return 0; } /** * \ingroup matrix * \function igraph_spmatrix_set * \brief Setting an element of a sparse matrix. * * Note that there are no range checks right now. * \param m The matrix object. * \param row The index of the row, starting with zero. * \param col The index of the column, starting with zero. * \param value The new value. * * Time complexity: O(log n), where n is the number of nonzero elements in * the requested column. */ int igraph_spmatrix_set(igraph_spmatrix_t *m, long int row, long int col, igraph_real_t value) { long int start, end; IGRAPH_ASSERT(m != NULL); start = (long) VECTOR(m->cidx)[col]; end = (long) VECTOR(m->cidx)[col + 1] - 1; if (end < start) { /* First element in the column */ if (value == 0.0) { return 0; } IGRAPH_CHECK(igraph_vector_insert(&m->ridx, start, row)); IGRAPH_CHECK(igraph_vector_insert(&m->data, start, value)); for (start = col + 1; start < m->ncol + 1; start++) { VECTOR(m->cidx)[start]++; } return 0; } /* Elements residing in column col are between m->data[start] and * m->data[end], inclusive, ordered by row index */ while (start < end - 1) { long int mid = (start + end) / 2; if (VECTOR(m->ridx)[mid] > row) { end = mid; } else if (VECTOR(m->ridx)[mid] < row) { start = mid; } else { start = mid; break; } } if (VECTOR(m->ridx)[start] == row) { /* Overwriting a value - or deleting it if it has been overwritten by zero */ if (value == 0) { igraph_vector_remove(&m->ridx, start); igraph_vector_remove(&m->data, start); for (start = col + 1; start < m->ncol + 1; start++) { VECTOR(m->cidx)[start]--; } } else { VECTOR(m->data)[start] = value; } return 0; } else if (VECTOR(m->ridx)[end] == row) { /* Overwriting a value - or deleting it if it has been overwritten by zero */ if (value == 0) { igraph_vector_remove(&m->ridx, end); igraph_vector_remove(&m->data, end); for (start = col + 1; start < m->ncol + 1; start++) { VECTOR(m->cidx)[start]--; } } else { VECTOR(m->data)[end] = value; } return 0; } /* New element has to be inserted, but only if not a zero is * being written into the matrix */ if (value != 0.0) { if (VECTOR(m->ridx)[end] < row) { IGRAPH_CHECK(igraph_vector_insert(&m->ridx, end + 1, row)); IGRAPH_CHECK(igraph_vector_insert(&m->data, end + 1, value)); } else if (VECTOR(m->ridx)[start] < row) { IGRAPH_CHECK(igraph_vector_insert(&m->ridx, start + 1, row)); IGRAPH_CHECK(igraph_vector_insert(&m->data, start + 1, value)); } else { IGRAPH_CHECK(igraph_vector_insert(&m->ridx, start, row)); IGRAPH_CHECK(igraph_vector_insert(&m->data, start, value)); } for (start = col + 1; start < m->ncol + 1; start++) { VECTOR(m->cidx)[start]++; } } return 0; } /** * \ingroup matrix * \function igraph_spmatrix_add_e * \brief Adding a real value to an element of a sparse matrix. * * Note that there are no range checks right now. This is implemented to avoid * double lookup of a given element in the matrix by using \ref igraph_spmatrix_e() * and \ref igraph_spmatrix_set() consecutively. * * \param m The matrix object. * \param row The index of the row, starting with zero. * \param col The index of the column, starting with zero. * \param value The value to add. * * Time complexity: O(log n), where n is the number of nonzero elements in * the requested column. */ int igraph_spmatrix_add_e(igraph_spmatrix_t *m, long int row, long int col, igraph_real_t value) { long int start, end; IGRAPH_ASSERT(m != NULL); start = (long) VECTOR(m->cidx)[col]; end = (long) VECTOR(m->cidx)[col + 1] - 1; if (end < start) { /* First element in the column */ if (value == 0.0) { return 0; } IGRAPH_CHECK(igraph_vector_insert(&m->ridx, start, row)); IGRAPH_CHECK(igraph_vector_insert(&m->data, start, value)); for (start = col + 1; start < m->ncol + 1; start++) { VECTOR(m->cidx)[start]++; } return 0; } /* Elements residing in column col are between m->data[start] and * m->data[end], inclusive, ordered by row index */ while (start < end - 1) { long int mid = (start + end) / 2; if (VECTOR(m->ridx)[mid] > row) { end = mid; } else if (VECTOR(m->ridx)[mid] < row) { start = mid; } else { start = mid; break; } } if (VECTOR(m->ridx)[start] == row) { /* Overwriting a value */ if (VECTOR(m->data)[start] == -1) { igraph_vector_remove(&m->ridx, start); igraph_vector_remove(&m->data, start); for (start = col + 1; start < m->ncol + 1; start++) { VECTOR(m->cidx)[start]--; } } else { VECTOR(m->data)[start] += value; } return 0; } else if (VECTOR(m->ridx)[end] == row) { /* Overwriting a value */ if (VECTOR(m->data)[end] == -1) { igraph_vector_remove(&m->ridx, end); igraph_vector_remove(&m->data, end); for (start = col + 1; start < m->ncol + 1; start++) { VECTOR(m->cidx)[start]--; } } else { VECTOR(m->data)[end] += value; } return 0; } /* New element has to be inserted, but only if not a zero is * being added to a zero element of the matrix */ if (value != 0.0) { if (VECTOR(m->ridx)[end] < row) { IGRAPH_CHECK(igraph_vector_insert(&m->ridx, end + 1, row)); IGRAPH_CHECK(igraph_vector_insert(&m->data, end + 1, value)); } else if (VECTOR(m->ridx)[start] < row) { IGRAPH_CHECK(igraph_vector_insert(&m->ridx, start + 1, row)); IGRAPH_CHECK(igraph_vector_insert(&m->data, start + 1, value)); } else { IGRAPH_CHECK(igraph_vector_insert(&m->ridx, start, row)); IGRAPH_CHECK(igraph_vector_insert(&m->data, start, value)); } for (start = col + 1; start < m->ncol + 1; start++) { VECTOR(m->cidx)[start]++; } } return 0; } /** * \function igraph_spmatrix_add_col_values * \brief Adds the values of a column to another column. * * \param to The index of the column to be added to. * \param from The index of the column to be added. * \return Error code. */ int igraph_spmatrix_add_col_values(igraph_spmatrix_t *m, long int to, long int from) { long int i; if (to < 0 || to >= m->ncol) { IGRAPH_ERROR("The 'to' column does not exist.", IGRAPH_EINVAL); } if (from < 0 || from >= m->ncol) { IGRAPH_ERROR("The 'from' column does not exist.", IGRAPH_EINVAL); } /* TODO: I think this implementation could be speeded up if I don't use * igraph_spmatrix_add_e directly -- but maybe it's not worth the fuss */ for (i = (long int) VECTOR(m->cidx)[from]; i < VECTOR(m->cidx)[from + 1]; i++) { IGRAPH_CHECK(igraph_spmatrix_add_e(m, (long int) VECTOR(m->ridx)[i], to, VECTOR(m->data)[i])); } return IGRAPH_SUCCESS; } /** * \ingroup matrix * \function igraph_spmatrix_resize * \brief Resizes a sparse matrix. * * * This function resizes a sparse matrix by adding more elements to it. * The matrix retains its data even after resizing it, except for the data * which lies outside the new boundaries (if the new size is smaller). * \param m Pointer to an already initialized sparse matrix object. * \param nrow The number of rows in the resized matrix. * \param ncol The number of columns in the resized matrix. * \return Error code. * * Time complexity: O(n). * n is the number of elements in the old matrix. */ int igraph_spmatrix_resize(igraph_spmatrix_t *m, long int nrow, long int ncol) { long int i, j, ci, ei, mincol; IGRAPH_ASSERT(m != NULL); /* Iterating through the matrix data and deleting unnecessary data. */ /* At the same time, we create the new indices as well */ if (nrow < m->nrow) { ei = j = 0; mincol = (m->ncol < ncol) ? m->ncol : ncol; for (ci = 0; ci < mincol; ci++) { for (; ei < VECTOR(m->cidx)[ci + 1]; ei++) { if (VECTOR(m->ridx)[ei] < nrow) { VECTOR(m->ridx)[j] = VECTOR(m->ridx)[ei]; VECTOR(m->data)[j] = VECTOR(m->data)[ei]; j++; } } VECTOR(m->cidx)[ci] = j; } /* Contract the row index and the data vector */ IGRAPH_CHECK(igraph_vector_resize(&m->ridx, j)); IGRAPH_CHECK(igraph_vector_resize(&m->cidx, j)); } /* Updating cidx */ IGRAPH_CHECK(igraph_vector_resize(&m->cidx, ncol + 1)); for (i = m->ncol + 1; i < ncol + 1; i++) { VECTOR(m->cidx)[i] = VECTOR(m->cidx)[m->ncol]; } m->nrow = nrow; m->ncol = ncol; return 0; } /** * \ingroup matrix * \function igraph_spmatrix_count_nonzero * \brief The number of non-zero elements in a sparse matrix. * * \param m Pointer to an initialized sparse matrix object. * \return The size of the matrix. * * Time complexity: O(1). */ long int igraph_spmatrix_count_nonzero(const igraph_spmatrix_t *m) { IGRAPH_ASSERT(m != NULL); return igraph_vector_size(&m->data); } /** * \ingroup matrix * \function igraph_spmatrix_size * \brief The number of elements in a sparse matrix. * * \param m Pointer to an initialized sparse matrix object. * \return The size of the matrix. * * Time complexity: O(1). */ long int igraph_spmatrix_size(const igraph_spmatrix_t *m) { IGRAPH_ASSERT(m != NULL); return (m->nrow) * (m->ncol); } /** * \ingroup matrix * \function igraph_spmatrix_nrow * \brief The number of rows in a sparse matrix. * * \param m Pointer to an initialized sparse matrix object. * \return The number of rows in the matrix. * * Time complexity: O(1). */ long int igraph_spmatrix_nrow(const igraph_spmatrix_t *m) { IGRAPH_ASSERT(m != NULL); return m->nrow; } /** * \ingroup matrix * \function igraph_spmatrix_ncol * \brief The number of columns in a sparse matrix. * * \param m Pointer to an initialized sparse matrix object. * \return The number of columns in the sparse matrix. * * Time complexity: O(1). */ long int igraph_spmatrix_ncol(const igraph_spmatrix_t *m) { IGRAPH_ASSERT(m != NULL); return m->ncol; } /** * \ingroup matrix * \brief Copies a sparse matrix to a regular C array. * * * The matrix is copied columnwise, as this is the format most * programs and languages use. * The C array should be of sufficient size, there are (of course) no * range checks done. * \param m Pointer to an initialized sparse matrix object. * \param to Pointer to a C array, the place to copy the data to. * \return Error code. * * Time complexity: O(n), * n is the number of * elements in the matrix. */ int igraph_spmatrix_copy_to(const igraph_spmatrix_t *m, igraph_real_t *to) { long int c, dest_idx, idx; memset(to, 0, sizeof(igraph_real_t) * (size_t) igraph_spmatrix_size(m)); for (c = 0, dest_idx = 0; c < m->ncol; c++, dest_idx += m->nrow) { for (idx = (long int) VECTOR(m->cidx)[c]; idx < VECTOR(m->cidx)[c + 1]; idx++) { to[dest_idx + (long)VECTOR(m->ridx)[idx]] = VECTOR(m->data)[idx]; } } return 0; } /** * \ingroup matrix * \brief Sets all element in a sparse matrix to zero. * * \param m Pointer to an initialized matrix object. * \return Error code, always returns with success. * * Time complexity: O(n), * n is the number of columns in the matrix */ int igraph_spmatrix_null(igraph_spmatrix_t *m) { IGRAPH_ASSERT(m != NULL); igraph_vector_clear(&m->data); igraph_vector_clear(&m->ridx); igraph_vector_null(&m->cidx); return 0; } /** * \ingroup matrix * \function igraph_spmatrix_add_cols * \brief Adds columns to a sparse matrix. * \param m The sparse matrix object. * \param n The number of columns to add. * \return Error code. * * Time complexity: O(1). */ int igraph_spmatrix_add_cols(igraph_spmatrix_t *m, long int n) { igraph_spmatrix_resize(m, m->nrow, m->ncol + n); return 0; } /** * \ingroup matrix * \function igraph_spmatrix_add_rows * \brief Adds rows to a sparse matrix. * \param m The sparse matrix object. * \param n The number of rows to add. * \return Error code. * * Time complexity: O(1). */ int igraph_spmatrix_add_rows(igraph_spmatrix_t *m, long int n) { igraph_spmatrix_resize(m, m->nrow + n, m->ncol); return 0; } /** * \function igraph_spmatrix_clear_row * \brief Clears a row in the matrix (sets all of its elements to zero). * \param m The matrix. * \param row The index of the row to be cleared. * \return Error code. * * Time complexity: O(n), the number of nonzero elements in the matrix. */ int igraph_spmatrix_clear_row(igraph_spmatrix_t *m, long int row) { if (row < 0 || row >= m->nrow) { IGRAPH_ERROR("The row does not exist.", IGRAPH_EINVAL); } long int ci, ei, i, j, nremove = 0, nremove_old = 0; igraph_vector_t permvec; IGRAPH_ASSERT(m != NULL); IGRAPH_VECTOR_INIT_FINALLY(&permvec, igraph_vector_size(&m->data)); for (ci = 0, i = 0, j = 1; ci < m->ncol; ci++) { for (ei = (long int) VECTOR(m->cidx)[ci]; ei < VECTOR(m->cidx)[ci + 1]; ei++) { if (VECTOR(m->ridx)[ei] == row) { /* this element will be deleted, so all elements in cidx from the * column index of this element will have to be decreased by one */ nremove++; } else { /* this element will be kept */ VECTOR(permvec)[i] = j; j++; } i++; } if (ci > 0) { VECTOR(m->cidx)[ci] -= nremove_old; } nremove_old = nremove; } VECTOR(m->cidx)[m->ncol] -= nremove; igraph_vector_permdelete(&m->ridx, &permvec, nremove); igraph_vector_permdelete(&m->data, &permvec, nremove); igraph_vector_destroy(&permvec); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Unused local functions---temporarily disabled */ #if 0 static int igraph_i_spmatrix_clear_row_fast(igraph_spmatrix_t *m, long int row) { long int ei, n; IGRAPH_ASSERT(m != NULL); n = igraph_vector_size(&m->data); for (ei = 0; ei < n; ei++) { if (VECTOR(m->ridx)[ei] == row) { VECTOR(m->data)[ei] = 0.0; } } return 0; } static int igraph_i_spmatrix_cleanup(igraph_spmatrix_t *m) { long int ci, ei, i, j, nremove = 0, nremove_old = 0; igraph_vector_t permvec; IGRAPH_ASSERT(m != NULL); IGRAPH_VECTOR_INIT_FINALLY(&permvec, igraph_vector_size(&m->data)); for (ci = 0, i = 0, j = 1; ci < m->ncol; ci++) { for (ei = (long int) VECTOR(m->cidx)[ci]; ei < VECTOR(m->cidx)[ci + 1]; ei++) { if (VECTOR(m->data)[ei] == 0.0) { /* this element will be deleted, so all elements in cidx from the * column index of this element will have to be decreased by one */ nremove++; } else { /* this element will be kept */ VECTOR(permvec)[i] = j; j++; } i++; } if (ci > 0) { VECTOR(m->cidx)[ci] -= nremove_old; } nremove_old = nremove; } VECTOR(m->cidx)[m->ncol] -= nremove; igraph_vector_permdelete(&m->ridx, &permvec, nremove); igraph_vector_permdelete(&m->data, &permvec, nremove); igraph_vector_destroy(&permvec); IGRAPH_FINALLY_CLEAN(1); return 0; } #endif /** * \function igraph_spmatrix_clear_col * \brief Clears a column in the matrix (sets all of its elements to zero). * \param m The matrix. * \param col The index of the column to be cleared. * \return Error code. * * Time complexity: TODO */ int igraph_spmatrix_clear_col(igraph_spmatrix_t *m, long int col) { if (col < 0 || col >= m->ncol) { IGRAPH_ERROR("The column does not exist.", IGRAPH_EINVAL); } long int i, n; IGRAPH_ASSERT(m != NULL); n = (long)VECTOR(m->cidx)[col + 1] - (long)VECTOR(m->cidx)[col]; if (n == 0) { return 0; } igraph_vector_remove_section(&m->ridx, (long int) VECTOR(m->cidx)[col], (long int) VECTOR(m->cidx)[col + 1]); igraph_vector_remove_section(&m->data, (long int) VECTOR(m->cidx)[col], (long int) VECTOR(m->cidx)[col + 1]); for (i = col + 1; i <= m->ncol; i++) { VECTOR(m->cidx)[i] -= n; } return IGRAPH_SUCCESS; } /** * \function igraph_spmatrix_scale * \brief Multiplies each element of the sparse matrix by a constant. * \param m The matrix. * \param by The constant. * * Time complexity: O(n), the number of elements in the matrix. */ void igraph_spmatrix_scale(igraph_spmatrix_t *m, igraph_real_t by) { IGRAPH_ASSERT(m != NULL); igraph_vector_scale(&m->data, by); } /** * \function igraph_spmatrix_colsums * \brief Calculates the column sums of the matrix. * \param m The matrix. * \param res An initialized \c igraph_vector_t, the result will be stored here. * The vector will be resized as needed. * * Time complexity: O(n), the number of nonzero elements in the matrix. */ int igraph_spmatrix_colsums(const igraph_spmatrix_t *m, igraph_vector_t *res) { long int i, c; IGRAPH_ASSERT(m != NULL); IGRAPH_CHECK(igraph_vector_resize(res, m->ncol)); igraph_vector_null(res); for (c = 0; c < m->ncol; c++) { for (i = (long int) VECTOR(m->cidx)[c]; i < VECTOR(m->cidx)[c + 1]; i++) { VECTOR(*res)[c] += VECTOR(m->data)[i]; } } return 0; } /** * \function igraph_spmatrix_rowsums * \brief Calculates the row sums of the matrix. * \param m The matrix. * \param res An initialized \c igraph_vector_t, the result will be stored here. * The vector will be resized as needed. * * Time complexity: O(n), the number of nonzero elements in the matrix. */ int igraph_spmatrix_rowsums(const igraph_spmatrix_t *m, igraph_vector_t *res) { long int i, n; IGRAPH_ASSERT(m != NULL); IGRAPH_CHECK(igraph_vector_resize(res, m->nrow)); n = igraph_vector_size(&m->data); igraph_vector_null(res); for (i = 0; i < n; i++) { VECTOR(*res)[(long int)VECTOR(m->ridx)[i]] += VECTOR(m->data)[i]; } return 0; } /** * \function igraph_spmatrix_max_nonzero * \brief Returns the maximum nonzero element of a matrix. * If the matrix is empty, zero is returned. * * \param m the matrix object. * \param ridx the row index of the maximum element if not \c NULL. * \param cidx the column index of the maximum element if not \c NULL. * * Time complexity: O(n), the number of nonzero elements in the matrix. */ igraph_real_t igraph_spmatrix_max_nonzero(const igraph_spmatrix_t *m, igraph_real_t *ridx, igraph_real_t *cidx) { igraph_real_t res; long int i, n, maxidx; IGRAPH_ASSERT(m != NULL); n = igraph_vector_size(&m->data); if (n == 0) { return 0.0; } maxidx = -1; for (i = 0; i < n; i++) if (VECTOR(m->data)[i] != 0.0 && (maxidx == -1 || VECTOR(m->data)[i] >= VECTOR(m->data)[maxidx])) { maxidx = i; } if (maxidx == -1) { return 0.0; } res = VECTOR(m->data)[maxidx]; if (ridx != 0) { *ridx = VECTOR(m->ridx)[maxidx]; } if (cidx != 0) { igraph_vector_binsearch(&m->cidx, maxidx, &i); while (VECTOR(m->cidx)[i + 1] == VECTOR(m->cidx)[i]) { i++; } *cidx = (igraph_real_t)i; } return res; } /** * \function igraph_spmatrix_max * \brief Returns the maximum element of a matrix. * If the matrix is empty, zero is returned. * * \param m the matrix object. * \param ridx the row index of the maximum element if not \c NULL. * \param cidx the column index of the maximum element if not \c NULL. * * Time complexity: O(n), the number of nonzero elements in the matrix. */ igraph_real_t igraph_spmatrix_max(const igraph_spmatrix_t *m, igraph_real_t *ridx, igraph_real_t *cidx) { igraph_real_t res; long int i, j, k, maxidx; IGRAPH_ASSERT(m != NULL); i = igraph_vector_size(&m->data); if (i == 0) { return 0.0; } maxidx = (long)igraph_vector_which_max(&m->data); res = VECTOR(m->data)[maxidx]; if (res >= 0.0 || i == m->nrow * m->ncol) { if (ridx != 0) { *ridx = VECTOR(m->ridx)[maxidx]; } if (cidx != 0) { igraph_vector_binsearch(&m->cidx, maxidx, &i); i--; while (i < m->ncol - 1 && VECTOR(m->cidx)[i + 1] == VECTOR(m->cidx)[i]) { i++; } *cidx = (igraph_real_t)i; } return res; } /* the maximal nonzero element is negative and there is at least a * single zero */ res = 0.0; if (cidx != 0 || ridx != 0) { for (i = 0; i < m->ncol; i++) { if (VECTOR(m->cidx)[i + 1] - VECTOR(m->cidx)[i] < m->nrow) { if (cidx != 0) { *cidx = i; } if (ridx != 0) { for (j = (long int) VECTOR(m->cidx)[i], k = 0; j < VECTOR(m->cidx)[i + 1]; j++, k++) { if (VECTOR(m->ridx)[j] != k) { *ridx = k; break; } } } break; } } } return res; } /* Unused function, temporarily disabled */ /* static int igraph_i_spmatrix_get_col_nonzero_indices(const igraph_spmatrix_t *m, igraph_vector_t *res, long int col) { long int i, n; IGRAPH_ASSERT(m != NULL); n = (long int) (VECTOR(m->cidx)[col + 1] - VECTOR(m->cidx)[col]); IGRAPH_CHECK(igraph_vector_resize(res, n)); for (i = (long int) VECTOR(m->cidx)[col], n = 0; i < VECTOR(m->cidx)[col + 1]; i++, n++) if (VECTOR(m->data)[i] != 0.0) { VECTOR(*res)[n] = VECTOR(m->ridx)[i]; } return 0; } */ /** * \section igraph_spmatrix_iterating Iterating over the non-zero elements of a sparse matrix * * The \type igraph_spmatrix_iter_t type represents an iterator that can * be used to step over the non-zero elements of a sparse matrix in columnwise * order efficiently. In general, you shouldn't modify the elements of the matrix * while iterating over it; doing so will probably invalidate the iterator, but * there are no checks to prevent you from doing this. * * To access the row index of the current element of the iterator, use its * \c ri field. Similarly, the \c ci field stores the column index of the current * element and the \c value field stores the value of the element. */ /** * \function igraph_spmatrix_iter_create * \brief Creates a sparse matrix iterator corresponding to the given matrix. * * \param mit pointer to the matrix iterator being initialized * \param m pointer to the matrix we will be iterating over * \return Error code. The current implementation is always successful. * * Time complexity: O(1). */ int igraph_spmatrix_iter_create(igraph_spmatrix_iter_t *mit, const igraph_spmatrix_t *m) { mit->m = m; IGRAPH_CHECK(igraph_spmatrix_iter_reset(mit)); return 0; } /** * \function igraph_spmatrix_iter_reset * \brief Resets a sparse matrix iterator. * * * After resetting, the iterator will point to the first nonzero element (if any). * * \param mit pointer to the matrix iterator being reset * \return Error code. The current implementation is always successful. * * Time complexity: O(1). */ int igraph_spmatrix_iter_reset(igraph_spmatrix_iter_t *mit) { IGRAPH_ASSERT(mit->m); if (igraph_spmatrix_count_nonzero(mit->m) == 0) { mit->pos = mit->ri = mit->ci = -1L; mit->value = -1; return 0; } mit->ci = 0; mit->pos = -1; IGRAPH_CHECK(igraph_spmatrix_iter_next(mit)); return 0; } /** * \function igraph_spmatrix_iter_next * \brief Moves a sparse matrix iterator to the next nonzero element. * * * You should call this function only if \ref igraph_spmatrix_iter_end() * returns FALSE (0). * * \param mit pointer to the matrix iterator being moved * \return Error code. The current implementation is always successful. * * Time complexity: O(1). */ int igraph_spmatrix_iter_next(igraph_spmatrix_iter_t *mit) { mit->pos++; if (igraph_spmatrix_iter_end(mit)) { return 0; } mit->ri = (long int)VECTOR(mit->m->ridx)[mit->pos]; mit->value = VECTOR(mit->m->data)[mit->pos]; while (VECTOR(mit->m->cidx)[mit->ci + 1] <= mit->pos) { mit->ci++; } return 0; } /** * \function igraph_spmatrix_iter_end * \brief Checks whether there are more elements in the iterator. * * * You should call this function before calling \ref igraph_spmatrix_iter_next() * to make sure you have more elements in the iterator. * * \param mit pointer to the matrix iterator being checked * \return TRUE (1) if there are more elements in the iterator, * FALSE (0) otherwise. * * Time complexity: O(1). */ igraph_bool_t igraph_spmatrix_iter_end(igraph_spmatrix_iter_t *mit) { return mit->pos >= igraph_spmatrix_count_nonzero(mit->m); } /** * \function igraph_spmatrix_iter_destroy * \brief Frees the memory used by the iterator. * * * The current implementation does not allocate any memory upon * creation, so this function does nothing. However, since there is * no guarantee that future implementations will not allocate any * memory in \ref igraph_spmatrix_iter_create(), you are still * required to call this function whenever you are done with the * iterator. * * \param mit pointer to the matrix iterator being destroyed * * Time complexity: O(1). */ void igraph_spmatrix_iter_destroy(igraph_spmatrix_iter_t *mit) { IGRAPH_UNUSED(mit); /* Nothing to do at the moment */ } #ifndef USING_R /** * \function igraph_spmatrix_print * \brief Prints a sparse matrix. * * Prints a sparse matrix to the standard output. Only the non-zero entries * are printed. * * \return Error code. * * Time complexity: O(n), the number of non-zero elements. */ int igraph_spmatrix_print(const igraph_spmatrix_t* matrix) { return igraph_spmatrix_fprint(matrix, stdout); } #endif /** * \function igraph_spmatrix_fprint * \brief Prints a sparse matrix to the given file. * * Prints a sparse matrix to the given file. Only the non-zero entries * are printed. * * \return Error code. * * Time complexity: O(n), the number of non-zero elements. */ int igraph_spmatrix_fprint(const igraph_spmatrix_t* matrix, FILE *file) { igraph_spmatrix_iter_t mit; IGRAPH_CHECK(igraph_spmatrix_iter_create(&mit, matrix)); IGRAPH_FINALLY(igraph_spmatrix_iter_destroy, &mit); while (!igraph_spmatrix_iter_end(&mit)) { fprintf(file, "[%ld, %ld] = %.4f\n", (long int)mit.ri, (long int)mit.ci, mit.value); igraph_spmatrix_iter_next(&mit); } igraph_spmatrix_iter_destroy(&mit); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/core/interruption.h0000644000176200001440000000352114447675374017755 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_INTERRUPT_INTERNAL_H #define IGRAPH_INTERRUPT_INTERNAL_H #include "igraph_decls.h" #include "igraph_interrupt.h" #include "config.h" __BEGIN_DECLS extern IGRAPH_THREAD_LOCAL igraph_interruption_handler_t *igraph_i_interruption_handler; /** * \define IGRAPH_ALLOW_INTERRUPTION * \brief * * This macro should be called when interruption is allowed. It calls * \ref igraph_allow_interruption() with the proper parameters and if that returns * anything but \c IGRAPH_SUCCESS then * the macro returns the "calling" function as well, with the proper * error code (\c IGRAPH_INTERRUPTED). */ #define IGRAPH_ALLOW_INTERRUPTION() \ do { \ if (igraph_i_interruption_handler) { if (igraph_allow_interruption(NULL) != IGRAPH_SUCCESS) return IGRAPH_INTERRUPTED; \ } } while (0) #define IGRAPH_ALLOW_INTERRUPTION_NORETURN() \ do { \ if (igraph_i_interruption_handler) { igraph_allow_interruption(NULL); } \ } while (0) __END_DECLS #endif leidenbase/src/core/core/memory.c0000644000176200001440000000464314447675374016524 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_memory.h" /** * \function igraph_free * \brief Deallocate memory that was allocated by igraph functions. * * Some igraph functions return a pointer vector (igraph_vector_ptr_t) * containing pointers to other igraph or other data types. These data * types are dynamically allocated and have to be deallocated * manually when the user does not need them any more. This can be done * by calling igraph_free on them. * * * Here is a complete example on how to use \c igraph_free properly. * * \example examples/simple/igraph_free.c * * \param p Pointer to the piece of memory to be deallocated. * \return Error code, currently always zero, meaning success. * * Time complexity: platform dependent, ideally it should be O(1). * * \sa \ref igraph_malloc() */ void igraph_free(void *p) { IGRAPH_FREE(p); } /** * \function igraph_malloc * \brief Allocate memory that can be safely deallocated by igraph functions. * * Some igraph functions, such as \ref igraph_vector_ptr_free_all() and * \ref igraph_vector_ptr_destroy_all() can free memory that may have been * allocated by the user. \c igraph_malloc() works exactly like \c malloc() * from the C standard library, but it is guaranteed that it can be safely * paired with the \c free() function used by igraph internally (which is * also user-accessible through \ref igraph_free()). * * \param n Number of bytes to be allocated. * \return Pointer to the piece of allocated memory. * * \sa \ref igraph_free() */ void *igraph_malloc(size_t n) { return malloc(n); } leidenbase/src/core/core/indheap.c0000644000176200001440000006405614447675374016630 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" #include "core/indheap.h" #include /* memcpy & co. */ #include /* -------------------------------------------------- */ /* Indexed heap */ /* -------------------------------------------------- */ #define PARENT(x) (((x)+1)/2-1) #define LEFTCHILD(x) (((x)+1)*2-1) #define RIGHTCHILD(x) (((x)+1)*2) static void igraph_indheap_i_build(igraph_indheap_t* h, long int head); static void igraph_indheap_i_shift_up(igraph_indheap_t* h, long int elem); static void igraph_indheap_i_sink(igraph_indheap_t* h, long int head); static void igraph_indheap_i_switch(igraph_indheap_t* h, long int e1, long int e2); /** * \ingroup indheap * \brief Initializes an indexed heap (constructor). * * @return Error code: * - IGRAPH_ENOMEM: out of memory */ int igraph_indheap_init(igraph_indheap_t* h, long int alloc_size) { if (alloc_size <= 0 ) { alloc_size = 1; } h->stor_begin = IGRAPH_CALLOC(alloc_size, igraph_real_t); if (h->stor_begin == 0) { h->index_begin = 0; IGRAPH_ERROR("indheap init failed", IGRAPH_ENOMEM); } h->index_begin = IGRAPH_CALLOC(alloc_size, long int); if (h->index_begin == 0) { IGRAPH_FREE(h->stor_begin); h->stor_begin = 0; IGRAPH_ERROR("indheap init failed", IGRAPH_ENOMEM); } h->stor_end = h->stor_begin + alloc_size; h->end = h->stor_begin; h->destroy = 1; return 0; } int igraph_indheap_clear(igraph_indheap_t *h) { h->end = h->stor_begin; return 0; } /** * \ingroup indheap * \brief Initializes and build an indexed heap from a C array (constructor). * * @return Error code: * - IGRAPH_ENOMEM: out of memory */ int igraph_indheap_init_array (igraph_indheap_t *h, igraph_real_t* data, long int len) { long int i; h->stor_begin = IGRAPH_CALLOC(len, igraph_real_t); if (h->stor_begin == 0) { h->index_begin = 0; IGRAPH_ERROR("indheap init from array failed", IGRAPH_ENOMEM); } h->index_begin = IGRAPH_CALLOC(len, long int); if (h->index_begin == 0) { IGRAPH_FREE(h->stor_begin); h->stor_begin = 0; IGRAPH_ERROR("indheap init from array failed", IGRAPH_ENOMEM); } h->stor_end = h->stor_begin + len; h->end = h->stor_end; h->destroy = 1; memcpy(h->stor_begin, data, (size_t) len * sizeof(igraph_real_t)); for (i = 0; i < len; i++) { h->index_begin[i] = i + 1; } igraph_indheap_i_build (h, 0); return 0; } /** * \ingroup indheap * \brief Destroys an initialized indexed heap. */ void igraph_indheap_destroy (igraph_indheap_t* h) { IGRAPH_ASSERT(h != 0); if (h->destroy) { if (h->stor_begin != 0) { IGRAPH_FREE(h->stor_begin); h->stor_begin = 0; } if (h->index_begin != 0) { IGRAPH_FREE(h->index_begin); h->index_begin = 0; } } } /** * \ingroup indheap * \brief Checks whether a heap is empty. */ igraph_bool_t igraph_indheap_empty (igraph_indheap_t* h) { IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); return h->stor_begin == h->end; } /** * \ingroup indheap * \brief Adds an element to an indexed heap. */ int igraph_indheap_push (igraph_indheap_t* h, igraph_real_t elem) { IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); /* full, allocate more storage */ if (h->stor_end == h->end) { long int new_size = igraph_indheap_size(h) * 2; if (new_size == 0) { new_size = 1; } IGRAPH_CHECK(igraph_indheap_reserve(h, new_size)); } *(h->end) = elem; h->end += 1; *(h->index_begin + igraph_indheap_size(h) - 1) = igraph_indheap_size(h) - 1; /* maintain indheap */ igraph_indheap_i_shift_up(h, igraph_indheap_size(h) - 1); return 0; } /** * \ingroup indheap * \brief Adds an element to an indexed heap with a given index. */ int igraph_indheap_push_with_index(igraph_indheap_t* h, long int idx, igraph_real_t elem) { IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); /* full, allocate more storage */ if (h->stor_end == h->end) { long int new_size = igraph_indheap_size(h) * 2; if (new_size == 0) { new_size = 1; } IGRAPH_CHECK(igraph_indheap_reserve(h, new_size)); } *(h->end) = elem; h->end += 1; *(h->index_begin + igraph_indheap_size(h) - 1) = idx; /* maintain indheap */ igraph_indheap_i_shift_up(h, igraph_indheap_size(h) - 1); return 0; } /** * \ingroup indheap * \brief Modifies an element in an indexed heap. */ int igraph_indheap_modify(igraph_indheap_t* h, long int idx, igraph_real_t elem) { long int i, n; IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); n = igraph_indheap_size(h); for (i = 0; i < n; i++) if (h->index_begin[i] == idx) { h->stor_begin[i] = elem; break; } if (i == n) { return 0; } /* maintain indheap */ igraph_indheap_i_build(h, 0); return 0; } /** * \ingroup indheap * \brief Returns the largest element in an indexed heap. */ igraph_real_t igraph_indheap_max (igraph_indheap_t* h) { IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); IGRAPH_ASSERT(h->stor_begin != h->end); return h->stor_begin[0]; } /** * \ingroup indheap * \brief Removes the largest element from an indexed heap. */ igraph_real_t igraph_indheap_delete_max(igraph_indheap_t* h) { igraph_real_t tmp; IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); tmp = h->stor_begin[0]; igraph_indheap_i_switch(h, 0, igraph_indheap_size(h) - 1); h->end -= 1; igraph_indheap_i_sink(h, 0); return tmp; } /** * \ingroup indheap * \brief Gives the number of elements in an indexed heap. */ long int igraph_indheap_size (igraph_indheap_t* h) { IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); return h->end - h->stor_begin; } /** * \ingroup indheap * \brief Reserves more memory for an indexed heap. * * @return Error code: * - IGRAPH_ENOMEM: out of memory */ int igraph_indheap_reserve (igraph_indheap_t* h, long int size) { long int actual_size = igraph_indheap_size(h); igraph_real_t *tmp1; long int *tmp2; IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); if (size <= actual_size) { return 0; } tmp1 = IGRAPH_CALLOC(size, igraph_real_t); if (tmp1 == 0) { IGRAPH_ERROR("indheap reserve failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmp1); tmp2 = IGRAPH_CALLOC(size, long int); if (tmp2 == 0) { IGRAPH_ERROR("indheap reserve failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmp2); memcpy(tmp1, h->stor_begin, (size_t) actual_size * sizeof(igraph_real_t)); memcpy(tmp2, h->index_begin, (size_t) actual_size * sizeof(long int)); IGRAPH_FREE(h->stor_begin); IGRAPH_FREE(h->index_begin); h->stor_begin = tmp1; h->index_begin = tmp2; h->stor_end = h->stor_begin + size; h->end = h->stor_begin + actual_size; IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \ingroup indheap * \brief Returns the index of the largest element in an indexed heap. */ long int igraph_indheap_max_index(igraph_indheap_t *h) { IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); return h->index_begin[0]; } /** * \ingroup indheap * \brief Builds an indexed heap, this function should not be called * directly. */ static void igraph_indheap_i_build(igraph_indheap_t* h, long int head) { long int size = igraph_indheap_size(h); if (RIGHTCHILD(head) < size) { /* both subtrees */ igraph_indheap_i_build(h, LEFTCHILD(head) ); igraph_indheap_i_build(h, RIGHTCHILD(head)); igraph_indheap_i_sink(h, head); } else if (LEFTCHILD(head) < size) { /* only left */ igraph_indheap_i_build(h, LEFTCHILD(head)); igraph_indheap_i_sink(h, head); } else { /* none */ } } /** * \ingroup indheap * \brief Moves an element up in the heap, don't call this function * directly. */ static void igraph_indheap_i_shift_up(igraph_indheap_t *h, long int elem) { if (elem == 0 || h->stor_begin[elem] < h->stor_begin[PARENT(elem)]) { /* at the top */ } else { igraph_indheap_i_switch(h, elem, PARENT(elem)); igraph_indheap_i_shift_up(h, PARENT(elem)); } } /** * \ingroup indheap * \brief Moves an element down in the heap, don't call this function * directly. */ static void igraph_indheap_i_sink(igraph_indheap_t* h, long int head) { long int size = igraph_indheap_size(h); if (LEFTCHILD(head) >= size) { /* no subtrees */ } else if (RIGHTCHILD(head) == size || h->stor_begin[LEFTCHILD(head)] >= h->stor_begin[RIGHTCHILD(head)]) { /* sink to the left if needed */ if (h->stor_begin[head] < h->stor_begin[LEFTCHILD(head)]) { igraph_indheap_i_switch(h, head, LEFTCHILD(head)); igraph_indheap_i_sink(h, LEFTCHILD(head)); } } else { /* sink to the right */ if (h->stor_begin[head] < h->stor_begin[RIGHTCHILD(head)]) { igraph_indheap_i_switch(h, head, RIGHTCHILD(head)); igraph_indheap_i_sink(h, RIGHTCHILD(head)); } } } /** * \ingroup indheap * \brief Switches two elements in a heap, don't call this function * directly. */ static void igraph_indheap_i_switch(igraph_indheap_t* h, long int e1, long int e2) { if (e1 != e2) { igraph_real_t tmp = h->stor_begin[e1]; h->stor_begin[e1] = h->stor_begin[e2]; h->stor_begin[e2] = tmp; tmp = h->index_begin[e1]; h->index_begin[e1] = h->index_begin[e2]; h->index_begin[e2] = (long int) tmp; } } /*************************************************/ /* -------------------------------------------------- */ /* Doubly indexed heap */ /* -------------------------------------------------- */ /* static void igraph_d_indheap_i_build(igraph_d_indheap_t* h, long int head); */ /* Unused function */ static void igraph_d_indheap_i_shift_up(igraph_d_indheap_t* h, long int elem); static void igraph_d_indheap_i_sink(igraph_d_indheap_t* h, long int head); static void igraph_d_indheap_i_switch(igraph_d_indheap_t* h, long int e1, long int e2); /** * \ingroup doubleindheap * \brief Initializes an empty doubly indexed heap object (constructor). * * @return Error code: * - IGRAPH_ENOMEM: out of memory */ int igraph_d_indheap_init (igraph_d_indheap_t* h, long int alloc_size) { if (alloc_size <= 0 ) { alloc_size = 1; } h->stor_begin = IGRAPH_CALLOC(alloc_size, igraph_real_t); if (h->stor_begin == 0) { h->index_begin = 0; h->index2_begin = 0; IGRAPH_ERROR("d_indheap init failed", IGRAPH_ENOMEM); } h->stor_end = h->stor_begin + alloc_size; h->end = h->stor_begin; h->destroy = 1; h->index_begin = IGRAPH_CALLOC(alloc_size, long int); if (h->index_begin == 0) { IGRAPH_FREE(h->stor_begin); h->stor_begin = 0; h->index2_begin = 0; IGRAPH_ERROR("d_indheap init failed", IGRAPH_ENOMEM); } h->index2_begin = IGRAPH_CALLOC(alloc_size, long int); if (h->index2_begin == 0) { IGRAPH_FREE(h->stor_begin); IGRAPH_FREE(h->index_begin); h->stor_begin = 0; h->index_begin = 0; IGRAPH_ERROR("d_indheap init failed", IGRAPH_ENOMEM); } return 0; } /** * \ingroup doubleindheap * \brief Destroys an initialized doubly indexed heap object. */ void igraph_d_indheap_destroy (igraph_d_indheap_t* h) { IGRAPH_ASSERT(h != 0); if (h->destroy) { if (h->stor_begin != 0) { IGRAPH_FREE(h->stor_begin); h->stor_begin = 0; } if (h->index_begin != 0) { IGRAPH_FREE(h->index_begin); h->index_begin = 0; } if (h->index2_begin != 0) { IGRAPH_FREE(h->index2_begin); h->index2_begin = 0; } } } /** * \ingroup doubleindheap * \brief Decides whether a heap is empty. */ igraph_bool_t igraph_d_indheap_empty (igraph_d_indheap_t* h) { IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); return h->stor_begin == h->end; } /** * \ingroup doubleindheap * \brief Adds an element to the heap. */ int igraph_d_indheap_push (igraph_d_indheap_t* h, igraph_real_t elem, long int idx, long int idx2) { IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); /* full, allocate more storage */ if (h->stor_end == h->end) { long int new_size = igraph_d_indheap_size(h) * 2; if (new_size == 0) { new_size = 1; } IGRAPH_CHECK(igraph_d_indheap_reserve(h, new_size)); } *(h->end) = elem; h->end += 1; *(h->index_begin + igraph_d_indheap_size(h) - 1) = idx ; *(h->index2_begin + igraph_d_indheap_size(h) - 1) = idx2 ; /* maintain d_indheap */ igraph_d_indheap_i_shift_up(h, igraph_d_indheap_size(h) - 1); return 0; } /** * \ingroup doubleindheap * \brief Returns the largest element in the heap. */ igraph_real_t igraph_d_indheap_max (igraph_d_indheap_t* h) { IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); IGRAPH_ASSERT(h->stor_begin != h->end); return h->stor_begin[0]; } /** * \ingroup doubleindheap * \brief Removes the largest element from the heap. */ igraph_real_t igraph_d_indheap_delete_max(igraph_d_indheap_t* h) { igraph_real_t tmp; IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); tmp = h->stor_begin[0]; igraph_d_indheap_i_switch(h, 0, igraph_d_indheap_size(h) - 1); h->end -= 1; igraph_d_indheap_i_sink(h, 0); return tmp; } /** * \ingroup doubleindheap * \brief Gives the number of elements in the heap. */ long int igraph_d_indheap_size (igraph_d_indheap_t* h) { IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); return h->end - h->stor_begin; } /** * \ingroup doubleindheap * \brief Allocates memory for a heap. * * @return Error code: * - IGRAPH_ENOMEM: out of memory */ int igraph_d_indheap_reserve (igraph_d_indheap_t* h, long int size) { long int actual_size = igraph_d_indheap_size(h); igraph_real_t *tmp1; long int *tmp2, *tmp3; IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); if (size <= actual_size) { return 0; } tmp1 = IGRAPH_CALLOC(size, igraph_real_t); if (tmp1 == 0) { IGRAPH_ERROR("d_indheap reserve failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmp1); tmp2 = IGRAPH_CALLOC(size, long int); if (tmp2 == 0) { IGRAPH_ERROR("d_indheap reserve failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmp2); tmp3 = IGRAPH_CALLOC(size, long int); if (tmp3 == 0) { IGRAPH_ERROR("d_indheap reserve failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmp3); memcpy(tmp1, h->stor_begin, (size_t) actual_size * sizeof(igraph_real_t)); memcpy(tmp2, h->index_begin, (size_t) actual_size * sizeof(long int)); memcpy(tmp3, h->index2_begin, (size_t) actual_size * sizeof(long int)); IGRAPH_FREE(h->stor_begin); IGRAPH_FREE(h->index_begin); IGRAPH_FREE(h->index2_begin); h->stor_begin = tmp1; h->stor_end = h->stor_begin + size; h->end = h->stor_begin + actual_size; h->index_begin = tmp2; h->index2_begin = tmp3; IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \ingroup doubleindheap * \brief Gives the indices of the maximal element in the heap. */ void igraph_d_indheap_max_index(igraph_d_indheap_t *h, long int *idx, long int *idx2) { IGRAPH_ASSERT(h != 0); IGRAPH_ASSERT(h->stor_begin != 0); (*idx) = h->index_begin[0]; (*idx2) = h->index2_begin[0]; } /** * \ingroup doubleindheap * \brief Builds the heap, don't call it directly. */ /* Unused function, temporarily disabled */ #if 0 static void igraph_d_indheap_i_build(igraph_d_indheap_t* h, long int head) { long int size = igraph_d_indheap_size(h); if (RIGHTCHILD(head) < size) { /* both subtrees */ igraph_d_indheap_i_build(h, LEFTCHILD(head) ); igraph_d_indheap_i_build(h, RIGHTCHILD(head)); igraph_d_indheap_i_sink(h, head); } else if (LEFTCHILD(head) < size) { /* only left */ igraph_d_indheap_i_build(h, LEFTCHILD(head)); igraph_d_indheap_i_sink(h, head); } else { /* none */ } } #endif /** * \ingroup doubleindheap * \brief Moves an element up in the heap, don't call it directly. */ static void igraph_d_indheap_i_shift_up(igraph_d_indheap_t *h, long int elem) { if (elem == 0 || h->stor_begin[elem] < h->stor_begin[PARENT(elem)]) { /* at the top */ } else { igraph_d_indheap_i_switch(h, elem, PARENT(elem)); igraph_d_indheap_i_shift_up(h, PARENT(elem)); } } /** * \ingroup doubleindheap * \brief Moves an element down in the heap, don't call it directly. */ static void igraph_d_indheap_i_sink(igraph_d_indheap_t* h, long int head) { long int size = igraph_d_indheap_size(h); if (LEFTCHILD(head) >= size) { /* no subtrees */ } else if (RIGHTCHILD(head) == size || h->stor_begin[LEFTCHILD(head)] >= h->stor_begin[RIGHTCHILD(head)]) { /* sink to the left if needed */ if (h->stor_begin[head] < h->stor_begin[LEFTCHILD(head)]) { igraph_d_indheap_i_switch(h, head, LEFTCHILD(head)); igraph_d_indheap_i_sink(h, LEFTCHILD(head)); } } else { /* sink to the right */ if (h->stor_begin[head] < h->stor_begin[RIGHTCHILD(head)]) { igraph_d_indheap_i_switch(h, head, RIGHTCHILD(head)); igraph_d_indheap_i_sink(h, RIGHTCHILD(head)); } } } /** * \ingroup doubleindheap * \brief Switches two elements in the heap, don't call it directly. */ static void igraph_d_indheap_i_switch(igraph_d_indheap_t* h, long int e1, long int e2) { if (e1 != e2) { long int tmpi; igraph_real_t tmp = h->stor_begin[e1]; h->stor_begin[e1] = h->stor_begin[e2]; h->stor_begin[e2] = tmp; tmpi = h->index_begin[e1]; h->index_begin[e1] = h->index_begin[e2]; h->index_begin[e2] = tmpi; tmpi = h->index2_begin[e1]; h->index2_begin[e1] = h->index2_begin[e2]; h->index2_begin[e2] = tmpi; } } /*************************************************/ /* -------------------------------------------------- */ /* Two-way indexed heap */ /* -------------------------------------------------- */ #undef PARENT #undef LEFTCHILD #undef RIGHTCHILD #define PARENT(x) (((x)+1)/2-1) #define LEFTCHILD(x) (((x)+1)*2-1) #define RIGHTCHILD(x) (((x)+1)*2) /* This is a smart indexed heap. In addition to the "normal" indexed heap it allows to access every element through its index in O(1) time. In other words, for this heap the indexing operation is O(1), the normal heap does this in O(n) time.... */ static void igraph_i_2wheap_switch(igraph_2wheap_t *h, long int e1, long int e2) { if (e1 != e2) { long int tmp1, tmp2; igraph_real_t tmp3 = VECTOR(h->data)[e1]; VECTOR(h->data)[e1] = VECTOR(h->data)[e2]; VECTOR(h->data)[e2] = tmp3; tmp1 = VECTOR(h->index)[e1]; tmp2 = VECTOR(h->index)[e2]; VECTOR(h->index2)[tmp1] = e2 + 2; VECTOR(h->index2)[tmp2] = e1 + 2; VECTOR(h->index)[e1] = tmp2; VECTOR(h->index)[e2] = tmp1; } } static void igraph_i_2wheap_shift_up(igraph_2wheap_t *h, long int elem) { if (elem == 0 || VECTOR(h->data)[elem] < VECTOR(h->data)[PARENT(elem)]) { /* at the top */ } else { igraph_i_2wheap_switch(h, elem, PARENT(elem)); igraph_i_2wheap_shift_up(h, PARENT(elem)); } } static void igraph_i_2wheap_sink(igraph_2wheap_t *h, long int head) { long int size = igraph_2wheap_size(h); if (LEFTCHILD(head) >= size) { /* no subtrees */ } else if (RIGHTCHILD(head) == size || VECTOR(h->data)[LEFTCHILD(head)] >= VECTOR(h->data)[RIGHTCHILD(head)]) { /* sink to the left if needed */ if (VECTOR(h->data)[head] < VECTOR(h->data)[LEFTCHILD(head)]) { igraph_i_2wheap_switch(h, head, LEFTCHILD(head)); igraph_i_2wheap_sink(h, LEFTCHILD(head)); } } else { /* sink to the right */ if (VECTOR(h->data)[head] < VECTOR(h->data)[RIGHTCHILD(head)]) { igraph_i_2wheap_switch(h, head, RIGHTCHILD(head)); igraph_i_2wheap_sink(h, RIGHTCHILD(head)); } } } /* ------------------ */ /* These are public */ /* ------------------ */ int igraph_2wheap_init(igraph_2wheap_t *h, long int size) { h->size = size; /* We start with the biggest */ IGRAPH_CHECK(igraph_vector_long_init(&h->index2, size)); IGRAPH_FINALLY(igraph_vector_long_destroy, &h->index2); IGRAPH_VECTOR_INIT_FINALLY(&h->data, 0); IGRAPH_CHECK(igraph_vector_long_init(&h->index, 0)); /* IGRAPH_FINALLY(igraph_vector_long_destroy, &h->index); */ IGRAPH_FINALLY_CLEAN(2); return 0; } void igraph_2wheap_destroy(igraph_2wheap_t *h) { igraph_vector_destroy(&h->data); igraph_vector_long_destroy(&h->index); igraph_vector_long_destroy(&h->index2); } int igraph_2wheap_clear(igraph_2wheap_t *h) { igraph_vector_clear(&h->data); igraph_vector_long_clear(&h->index); igraph_vector_long_null(&h->index2); return 0; } igraph_bool_t igraph_2wheap_empty(const igraph_2wheap_t *h) { return igraph_vector_empty(&h->data); } int igraph_2wheap_push_with_index(igraph_2wheap_t *h, long int idx, igraph_real_t elem) { /* printf("-> %.2g [%li]\n", elem, idx); */ long int size = igraph_vector_size(&h->data); IGRAPH_CHECK(igraph_vector_push_back(&h->data, elem)); IGRAPH_CHECK(igraph_vector_long_push_back(&h->index, idx)); VECTOR(h->index2)[idx] = size + 2; /* maintain heap */ igraph_i_2wheap_shift_up(h, size); return 0; } long int igraph_2wheap_size(const igraph_2wheap_t *h) { return igraph_vector_size(&h->data); } long int igraph_2wheap_max_size(const igraph_2wheap_t *h) { return h->size; } igraph_real_t igraph_2wheap_max(const igraph_2wheap_t *h) { return VECTOR(h->data)[0]; } long int igraph_2wheap_max_index(const igraph_2wheap_t *h) { return VECTOR(h->index)[0]; } igraph_bool_t igraph_2wheap_has_elem(const igraph_2wheap_t *h, long int idx) { return VECTOR(h->index2)[idx] != 0; } igraph_bool_t igraph_2wheap_has_active(const igraph_2wheap_t *h, long int idx) { return VECTOR(h->index2)[idx] > 1; } igraph_real_t igraph_2wheap_get(const igraph_2wheap_t *h, long int idx) { long int i = VECTOR(h->index2)[idx] - 2; return VECTOR(h->data)[i]; } igraph_real_t igraph_2wheap_delete_max(igraph_2wheap_t *h) { igraph_real_t tmp = VECTOR(h->data)[0]; long int tmpidx = VECTOR(h->index)[0]; igraph_i_2wheap_switch(h, 0, igraph_2wheap_size(h) - 1); igraph_vector_pop_back(&h->data); igraph_vector_long_pop_back(&h->index); VECTOR(h->index2)[tmpidx] = 0; igraph_i_2wheap_sink(h, 0); /* printf("<-max %.2g\n", tmp); */ return tmp; } igraph_real_t igraph_2wheap_deactivate_max(igraph_2wheap_t *h) { igraph_real_t tmp = VECTOR(h->data)[0]; long int tmpidx = VECTOR(h->index)[0]; igraph_i_2wheap_switch(h, 0, igraph_2wheap_size(h) - 1); igraph_vector_pop_back(&h->data); igraph_vector_long_pop_back(&h->index); VECTOR(h->index2)[tmpidx] = 1; igraph_i_2wheap_sink(h, 0); return tmp; } igraph_real_t igraph_2wheap_delete_max_index(igraph_2wheap_t *h, long int *idx) { igraph_real_t tmp = VECTOR(h->data)[0]; long int tmpidx = VECTOR(h->index)[0]; igraph_i_2wheap_switch(h, 0, igraph_2wheap_size(h) - 1); igraph_vector_pop_back(&h->data); igraph_vector_long_pop_back(&h->index); VECTOR(h->index2)[tmpidx] = 0; igraph_i_2wheap_sink(h, 0); if (idx) { *idx = tmpidx; } return tmp; } int igraph_2wheap_modify(igraph_2wheap_t *h, long int idx, igraph_real_t elem) { long int pos = VECTOR(h->index2)[idx] - 2; /* printf("-- %.2g -> %.2g\n", VECTOR(h->data)[pos], elem); */ VECTOR(h->data)[pos] = elem; igraph_i_2wheap_sink(h, pos); igraph_i_2wheap_shift_up(h, pos); return 0; } /* Check that the heap is in a consistent state */ int igraph_2wheap_check(igraph_2wheap_t *h) { long int size = igraph_2wheap_size(h); long int i; igraph_bool_t error = 0; /* Check the heap property */ for (i = 0; i < size; i++) { if (LEFTCHILD(i) >= size) { break; } if (VECTOR(h->data)[LEFTCHILD(i)] > VECTOR(h->data)[i]) { error = 1; break; } if (RIGHTCHILD(i) >= size) { break; } if (VECTOR(h->data)[RIGHTCHILD(i)] > VECTOR(h->data)[i]) { error = 1; break; } } if (error) { IGRAPH_ERROR("Inconsistent heap", IGRAPH_EINTERNAL); } return 0; } leidenbase/src/core/core/array.pmt0000644000176200001440000000526714447675374016713 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" int FUNCTION(igraph_array3, init)(TYPE(igraph_array3) *a, long int n1, long int n2, long int n3) { int ret; ret = FUNCTION(igraph_vector, init)(&a->data, n1 * n2 * n3); a->n1 = n1; a->n2 = n2; a->n3 = n3; a->n1n2 = n1 * n2; return ret; } void FUNCTION(igraph_array3, destroy)(TYPE(igraph_array3) *a) { FUNCTION(igraph_vector, destroy)(&a->data); } long int FUNCTION(igraph_array3, size)(const TYPE(igraph_array3) *a) { return (a->n1n2) * (a->n3); } long int FUNCTION(igraph_array3, n)(const TYPE(igraph_array3) *a, long int idx) { switch (idx) { case 1: return a->n1; break; case 2: return a->n2; break; case 3: return a->n3; break; } return 0; } int FUNCTION(igraph_array3, resize)(TYPE(igraph_array3) *a, long int n1, long int n2, long int n3) { int ret = FUNCTION(igraph_vector, resize)(&a->data, n1 * n2 * n3); a->n1 = n1; a->n2 = n2; a->n3 = n3; a->n1n2 = n1 * n2; return ret; } void FUNCTION(igraph_array3, null)(TYPE(igraph_array3) *a) { FUNCTION(igraph_vector, null)(&a->data); } BASE FUNCTION(igraph_array3, sum)(const TYPE(igraph_array3) *a) { return FUNCTION(igraph_vector, sum)(&a->data); } void FUNCTION(igraph_array3, scale)(TYPE(igraph_array3) *a, BASE by) { FUNCTION(igraph_vector, scale)(&a->data, by); } void FUNCTION(igraph_array3, fill)(TYPE(igraph_array3) *a, BASE e) { FUNCTION(igraph_vector, fill)(&a->data, e); } int FUNCTION(igraph_array3, update)(TYPE(igraph_array3) *to, const TYPE(igraph_array3) *from) { IGRAPH_CHECK(FUNCTION(igraph_array3, resize)(to, from->n1, from->n2, from->n3)); FUNCTION(igraph_vector, update)(&to->data, &from->data); return 0; } leidenbase/src/core/core/sparsemat.c0000644000176200001440000030706314447675375017216 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "igraph_sparsemat.h" #include "igraph_error.h" #include "igraph_interface.h" #include "igraph_constructors.h" #include "igraph_memory.h" #include "igraph_vector_ptr.h" #include "igraph_attributes.h" #include /** * \section about_sparsemat About sparse matrices * * * The igraph_sparsemat_t data type stores sparse matrices, * i.e. matrices in which the majority of the elements are zero. * * * The data type is essentially a wrapper to some of the * functions in the CXSparse library, by Tim Davis, see * http://faculty.cse.tamu.edu/davis/suitesparse.html * * * * Matrices can be stored in two formats: triplet and * column-compressed. The triplet format is intended for sparse matrix * initialization, as it is easy to add new (non-zero) elements to * it. Most of the computations are done on sparse matrices in * column-compressed format, after the user has converted the triplet * matrix to column-compressed, via \ref igraph_sparsemat_compress(). * * * * Both formats are dynamic, in the sense that new elements can be * added to them, possibly resulting the allocation of more memory. * * * * Row and column indices follow the C convention and are zero-based. * * * * \example examples/simple/igraph_sparsemat.c * \example examples/simple/igraph_sparsemat3.c * \example examples/simple/igraph_sparsemat4.c * \example examples/simple/igraph_sparsemat6.c * \example examples/simple/igraph_sparsemat7.c * \example examples/simple/igraph_sparsemat8.c * */ /** * \function igraph_sparsemat_init * \brief Initializes a sparse matrix, in triplet format. * * This is the most common way to create a sparse matrix, together * with the \ref igraph_sparsemat_entry() function, which can be used to * add the non-zero elements one by one. Once done, the user can call * \ref igraph_sparsemat_compress() to convert the matrix to * column-compressed, to allow computations with it. * * The user must call \ref igraph_sparsemat_destroy() on * the matrix to deallocate the memory, once the matrix is no more * needed. * \param A Pointer to a not yet initialized sparse matrix. * \param rows The number of rows in the matrix. * \param cols The number of columns. * \param nzmax The maximum number of non-zero elements in the * matrix. It is not compulsory to get this right, but it is * useful for the allocation of the proper amount of memory. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_init(igraph_sparsemat_t *A, int rows, int cols, int nzmax) { if (rows < 0) { IGRAPH_ERROR("Negative number of rows", IGRAPH_EINVAL); } if (cols < 0) { IGRAPH_ERROR("Negative number of columns", IGRAPH_EINVAL); } A->cs = cs_spalloc( rows, cols, nzmax, /*values=*/ 1, /*triplet=*/ 1); if (!A->cs) { IGRAPH_ERROR("Cannot allocate memory for sparse matrix", IGRAPH_ENOMEM); } return 0; } /** * \function igraph_sparsemat_copy * \brief Copies a sparse matrix. * * Create a sparse matrix object, by copying another one. The source * matrix can be either in triplet or column-compressed format. * * * Exactly the same amount of memory will be allocated to the * copy matrix, as it is currently for the original one. * \param to Pointer to an uninitialized sparse matrix, the copy will * be created here. * \param from The sparse matrix to copy. * \return Error code. * * Time complexity: O(n+nzmax), the number of columns plus the maximum * number of non-zero elements. */ int igraph_sparsemat_copy(igraph_sparsemat_t *to, const igraph_sparsemat_t *from) { CS_INT ne = from->cs->nz == -1 ? from->cs->n + 1 : from->cs->nzmax; to->cs = cs_spalloc(from->cs->m, from->cs->n, from->cs->nzmax, /*values=*/ 1, /*triplet=*/ igraph_sparsemat_is_triplet(from)); to->cs->nzmax = from->cs->nzmax; to->cs->m = from->cs->m; to->cs->n = from->cs->n; to->cs->nz = from->cs->nz; memcpy(to->cs->p, from->cs->p, sizeof(int) * (size_t) ne); memcpy(to->cs->i, from->cs->i, sizeof(int) * (size_t) (from->cs->nzmax)); memcpy(to->cs->x, from->cs->x, sizeof(double) * (size_t) (from->cs->nzmax)); return 0; } /** * \function igraph_sparsemat_destroy * \brief Deallocates memory used by a sparse matrix. * * One destroyed, the sparse matrix must be initialized again, before * calling any other operation on it. * \param A The sparse matrix to destroy. * * Time complexity: O(1). */ void igraph_sparsemat_destroy(igraph_sparsemat_t *A) { cs_spfree(A->cs); } /** * \function igraph_sparsemat_realloc * \brief Allocates more (or less) memory for a sparse matrix. * * Sparse matrices automatically allocate more memory, as needed. To * control memory allocation, the user can call this function, to * allocate memory for a given number of non-zero elements. * * \param A The sparse matrix, it can be in triplet or * column-compressed format. * \param nzmax The new maximum number of non-zero elements. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_realloc(igraph_sparsemat_t *A, int nzmax) { if (!cs_sprealloc(A->cs, nzmax)) { IGRAPH_ERROR("Could not allocate more memory for sparse matrix.", IGRAPH_ENOMEM); } return IGRAPH_SUCCESS; } /** * \function igraph_sparsemat_nrow * \brief Number of rows. * * \param A The input matrix, in triplet or column-compressed format. * \return The number of rows in the \p A matrix. * * Time complexity: O(1). */ long int igraph_sparsemat_nrow(const igraph_sparsemat_t *A) { return A->cs->m; } /** * \function igraph_sparsemat_ncol * \brief Number of columns. * * \param A The input matrix, in triplet or column-compressed format. * \return The number of columns in the \p A matrix. * * Time complexity: O(1). */ long int igraph_sparsemat_ncol(const igraph_sparsemat_t *A) { return A->cs->n; } /** * \function igraph_sparsemat_type * \brief Type of a sparse matrix (triplet or column-compressed). * * Gives whether a sparse matrix is stored in the triplet format or in * column-compressed format. * \param A The input matrix. * \return Either \c IGRAPH_SPARSEMAT_CC or \c * IGRAPH_SPARSEMAT_TRIPLET. * * Time complexity: O(1). */ igraph_sparsemat_type_t igraph_sparsemat_type(const igraph_sparsemat_t *A) { return A->cs->nz < 0 ? IGRAPH_SPARSEMAT_CC : IGRAPH_SPARSEMAT_TRIPLET; } /** * \function igraph_sparsemat_is_triplet * \brief Is this sparse matrix in triplet format? * * Decides whether a sparse matrix is in triplet format. * \param A The input matrix. * \return One if the input matrix is in triplet format, zero * otherwise. * * Time complexity: O(1). */ igraph_bool_t igraph_sparsemat_is_triplet(const igraph_sparsemat_t *A) { return A->cs->nz >= 0; } /** * \function igraph_sparsemat_is_cc * \brief Is this sparse matrix in column-compressed format? * * Decides whether a sparse matrix is in column-compressed format. * \param A The input matrix. * \return One if the input matrix is in column-compressed format, zero * otherwise. * * Time complexity: O(1). */ igraph_bool_t igraph_sparsemat_is_cc(const igraph_sparsemat_t *A) { return A->cs->nz < 0; } /** * \function igraph_sparsemat_permute * \brief Permutes the rows and columns of a sparse matrix. * * \param A The input matrix, it must be in column-compressed format. * \param p Integer vector, giving the permutation of the rows. * \param q Integer vector, the permutation of the columns. * \param res Pointer to an uninitialized sparse matrix, the result is * stored here. * \return Error code. * * Time complexity: O(m+n+nz), the number of rows plus the number of * columns plus the number of non-zero elements in the matrix. */ int igraph_sparsemat_permute(const igraph_sparsemat_t *A, const igraph_vector_int_t *p, const igraph_vector_int_t *q, igraph_sparsemat_t *res) { CS_INT nrow = A->cs->m, ncol = A->cs->n; igraph_vector_int_t pinv; CS_INT i; if (nrow != igraph_vector_int_size(p)) { IGRAPH_ERROR("Invalid row permutation length", IGRAPH_FAILURE); } if (ncol != igraph_vector_int_size(q)) { IGRAPH_ERROR("Invalid column permutation length", IGRAPH_FAILURE); } /* We invert the permutation by hand */ IGRAPH_CHECK(igraph_vector_int_init(&pinv, nrow)); IGRAPH_FINALLY(igraph_vector_int_destroy, &pinv); for (i = 0; i < nrow; i++) { VECTOR(pinv)[ VECTOR(*p)[i] ] = (int) i; } /* And call the permutation routine */ res->cs = cs_permute(A->cs, VECTOR(pinv), VECTOR(*q), /*values=*/ 1); if (!res->cs) { IGRAPH_ERROR("Cannot index sparse matrix", IGRAPH_FAILURE); } igraph_vector_int_destroy(&pinv); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_sparsemat_index_rows(const igraph_sparsemat_t *A, const igraph_vector_int_t *p, igraph_sparsemat_t *res, igraph_real_t *constres) { igraph_sparsemat_t II, II2; CS_INT nrow = A->cs->m; long int idx_rows = igraph_vector_int_size(p); long int k; /* Create index matrix */ IGRAPH_CHECK(igraph_sparsemat_init(&II2, (int) idx_rows, (int) nrow, (int) idx_rows)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &II2); for (k = 0; k < idx_rows; k++) { igraph_sparsemat_entry(&II2, (int) k, VECTOR(*p)[k], 1.0); } IGRAPH_CHECK(igraph_sparsemat_compress(&II2, &II)); igraph_sparsemat_destroy(&II2); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &II); /* Multiply */ IGRAPH_CHECK(igraph_sparsemat_multiply(&II, A, res)); igraph_sparsemat_destroy(&II); IGRAPH_FINALLY_CLEAN(1); if (constres) { if (res->cs->p[1] != 0) { *constres = res->cs->x[0]; } else { *constres = 0.0; } } return 0; } static int igraph_i_sparsemat_index_cols(const igraph_sparsemat_t *A, const igraph_vector_int_t *q, igraph_sparsemat_t *res, igraph_real_t *constres) { igraph_sparsemat_t JJ, JJ2; CS_INT ncol = A->cs->n; long int idx_cols = igraph_vector_int_size(q); long int k; /* Create index matrix */ IGRAPH_CHECK(igraph_sparsemat_init(&JJ2, (int) ncol, (int) idx_cols, (int) idx_cols)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &JJ2); for (k = 0; k < idx_cols; k++) { igraph_sparsemat_entry(&JJ2, VECTOR(*q)[k], (int) k, 1.0); } IGRAPH_CHECK(igraph_sparsemat_compress(&JJ2, &JJ)); igraph_sparsemat_destroy(&JJ2); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &JJ); /* Multiply */ IGRAPH_CHECK(igraph_sparsemat_multiply(A, &JJ, res)); igraph_sparsemat_destroy(&JJ); IGRAPH_FINALLY_CLEAN(1); if (constres) { if (res->cs->p [1] != 0) { *constres = res->cs->x [0]; } else { *constres = 0.0; } } return 0; } /** * \function igraph_sparsemat_index * \brief Extracts a submatrix or a single element. * * This function indexes into a sparse matrix. * It serves two purposes. First, it can extract * submatrices from a sparse matrix. Second, as a special case, it can * extract a single element from a sparse matrix. * * \param A The input matrix, it must be in column-compressed format. * \param p An integer vector, or a null pointer. The selected row * index or indices. A null pointer selects all rows. * \param q An integer vector, or a null pointer. The selected column * index or indices. A null pointer selects all columns. * \param res Pointer to an uninitialized sparse matrix, or a null * pointer. If not a null pointer, then the selected submatrix is * stored here. * \param constres Pointer to a real variable or a null pointer. If * not a null pointer, then the first non-zero element in the * selected submatrix is stored here, if there is one. Otherwise * zero is stored here. This behavior is handy if one * wants to select a single entry from the matrix. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_index(const igraph_sparsemat_t *A, const igraph_vector_int_t *p, const igraph_vector_int_t *q, igraph_sparsemat_t *res, igraph_real_t *constres) { igraph_sparsemat_t II, JJ, II2, JJ2, tmp; CS_INT nrow = A->cs->m; CS_INT ncol = A->cs->n; long int idx_rows = p ? igraph_vector_int_size(p) : -1; long int idx_cols = q ? igraph_vector_int_size(q) : -1; long int k; igraph_sparsemat_t *myres = res, mres; if (!p && !q) { IGRAPH_ERROR("No index vectors", IGRAPH_EINVAL); } if (!res && (idx_rows != 1 || idx_cols != 1)) { IGRAPH_ERROR("Sparse matrix indexing: must give `res' if not a " "single element is selected", IGRAPH_EINVAL); } if (!q) { return igraph_i_sparsemat_index_rows(A, p, res, constres); } if (!p) { return igraph_i_sparsemat_index_cols(A, q, res, constres); } if (!res) { myres = &mres; } /* Create first index matrix */ IGRAPH_CHECK(igraph_sparsemat_init(&II2, (int) idx_rows, (int) nrow, (int) idx_rows)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &II2); for (k = 0; k < idx_rows; k++) { igraph_sparsemat_entry(&II2, (int) k, VECTOR(*p)[k], 1.0); } IGRAPH_CHECK(igraph_sparsemat_compress(&II2, &II)); igraph_sparsemat_destroy(&II2); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &II); /* Create second index matrix */ IGRAPH_CHECK(igraph_sparsemat_init(&JJ2, (int) ncol, (int) idx_cols, (int) idx_cols)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &JJ2); for (k = 0; k < idx_cols; k++) { igraph_sparsemat_entry(&JJ2, VECTOR(*q)[k], (int) k, 1.0); } IGRAPH_CHECK(igraph_sparsemat_compress(&JJ2, &JJ)); igraph_sparsemat_destroy(&JJ2); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &JJ); /* Multiply */ IGRAPH_CHECK(igraph_sparsemat_multiply(&II, A, &tmp)); igraph_sparsemat_destroy(&II); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tmp); IGRAPH_CHECK(igraph_sparsemat_multiply(&tmp, &JJ, myres)); igraph_sparsemat_destroy(&tmp); igraph_sparsemat_destroy(&JJ); IGRAPH_FINALLY_CLEAN(2); if (constres) { if (myres->cs->p [1] != 0) { *constres = myres->cs->x [0]; } else { *constres = 0.0; } } if (!res) { igraph_sparsemat_destroy(myres); } return 0; } /** * \function igraph_sparsemat_entry * \brief Adds an element to a sparse matrix. * * This function can be used to add the entries to a sparse matrix, * after initializing it with \ref igraph_sparsemat_init(). If you add * multiple entries in the same position, they will all be saved, and * the resulting value is the sum of all entries in that position. * * \param A The input matrix, it must be in triplet format. * \param row The row index of the entry to add. * \param col The column index of the entry to add. * \param elem The value of the entry. * \return Error code. * * Time complexity: O(1) on average. */ int igraph_sparsemat_entry(igraph_sparsemat_t *A, int row, int col, igraph_real_t elem) { if (!igraph_sparsemat_is_triplet(A)) { IGRAPH_ERROR("Entries can only be added to sparse matrices that are in triplet format.", IGRAPH_EINVAL); } if (!cs_entry(A->cs, row, col, elem)) { IGRAPH_ERROR("Cannot add entry to sparse matrix.", IGRAPH_FAILURE); } return IGRAPH_SUCCESS; } /** * \function igraph_sparsemat_compress * \brief Converts a sparse matrix to column-compressed format. * * Converts a sparse matrix from triplet format to column-compressed format. * Almost all sparse matrix operations require that the matrix is in * column-compressed format. * * \param A The input matrix, it must be in triplet format. * \param res Pointer to an uninitialized sparse matrix object, the * compressed version of \p A is stored here. * \return Error code. * * Time complexity: O(nz) where \c nz is the number of non-zero elements. */ int igraph_sparsemat_compress(const igraph_sparsemat_t *A, igraph_sparsemat_t *res) { if (! igraph_sparsemat_is_triplet(A)) { IGRAPH_ERROR("Sparse matrix to compress is not in triplet format.", IGRAPH_EINVAL); } res->cs = cs_compress(A->cs); if (!res->cs) { IGRAPH_ERROR("Cannot compress sparse matrix", IGRAPH_FAILURE); } return IGRAPH_SUCCESS; } /** * \function igraph_sparsemat_transpose * \brief Transposes a sparse matrix. * * \param A The input matrix, column-compressed or triple format. * \param res Pointer to an uninitialized sparse matrix, the result is * stored here. * \param values If this is non-zero, the matrix transpose is * calculated the normal way. If it is zero, then only the pattern * of the input matrix is stored in the result, the values are not. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_transpose(const igraph_sparsemat_t *A, igraph_sparsemat_t *res, int values) { if (A->cs->nz < 0) { /* column-compressed */ res->cs = cs_transpose(A->cs, values); if (!res->cs) { IGRAPH_ERROR("Cannot transpose sparse matrix", IGRAPH_FAILURE); } } else { /* triplets */ CS_INT *tmp; IGRAPH_CHECK(igraph_sparsemat_copy(res, A)); tmp = res->cs->p; res->cs->p = res->cs->i; res->cs->i = tmp; } return 0; } static int igraph_i_sparsemat_is_symmetric_cc(const igraph_sparsemat_t *A, igraph_bool_t *result) { igraph_sparsemat_t t, tt; igraph_bool_t res; int nz; IGRAPH_CHECK(igraph_sparsemat_transpose(A, &t, /*values=*/ 1)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &t); IGRAPH_CHECK(igraph_sparsemat_dupl(&t)); IGRAPH_CHECK(igraph_sparsemat_transpose(&t, &tt, /*values=*/ 1)); igraph_sparsemat_destroy(&t); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tt); IGRAPH_CHECK(igraph_sparsemat_transpose(&tt, &t, /*values=*/ 1)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &t); nz = t.cs->p[t.cs->n]; res = memcmp(t.cs->i, tt.cs->i, sizeof(int) * (size_t) nz) == 0; res = res && memcmp(t.cs->p, tt.cs->p, sizeof(int) * (size_t)(t.cs->n + 1)) == 0; res = res && memcmp(t.cs->x, tt.cs->x, sizeof(igraph_real_t) * (size_t)nz) == 0; igraph_sparsemat_destroy(&t); igraph_sparsemat_destroy(&tt); IGRAPH_FINALLY_CLEAN(2); *result = res; return IGRAPH_SUCCESS; } static int igraph_i_sparsemat_is_symmetric_triplet(const igraph_sparsemat_t *A, igraph_bool_t *result) { igraph_sparsemat_t tmp; IGRAPH_CHECK(igraph_sparsemat_compress(A, &tmp)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tmp); IGRAPH_CHECK(igraph_i_sparsemat_is_symmetric_cc(&tmp, result)); igraph_sparsemat_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } igraph_bool_t igraph_sparsemat_is_symmetric(const igraph_sparsemat_t *A) { igraph_bool_t res = 0; if (A->cs->m != A->cs->n) { return 0; } /* TODO(ntamas): return values from igraph_i_sparsemat_is_symmetric_... are * ignored here; this should be fixed. Right now these functions don't * change 'res' if they fail so we will report matrices as not being * symmetric if an error happens */ if (A->cs->nz < 0) { igraph_i_sparsemat_is_symmetric_cc(A, &res); } else { igraph_i_sparsemat_is_symmetric_triplet(A, &res); } return res; } /** * \function igraph_sparsemat_dupl * \brief Removes duplicate elements from a sparse matrix. * * It is possible that a column-compressed sparse matrix stores a * single matrix entry in multiple pieces. The entry is then the sum * of all its pieces. (Some functions create matrices like this.) This * function eliminates the multiple pieces. * \param A The input matrix, in column-compressed format. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_dupl(igraph_sparsemat_t *A) { if (!cs_dupl(A->cs)) { IGRAPH_ERROR("Cannot remove duplicates from sparse matrix", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_fkeep * \brief Filters the elements of a sparse matrix. * * This function can be used to filter the (non-zero) elements of a * sparse matrix. For all entries, it calls the supplied function and * depending on the return values either keeps, or deleted the element * from the matrix. * \param A The input matrix, in column-compressed format. * \param fkeep The filter function. It must take four arguments: the * first is an \c int, the row index of the entry, the second is * another \c int, the column index. The third is \c igraph_real_t, * the value of the entry. The fourth element is a \c void pointer, * the \p other argument is passed here. The function must return * an \c int. If this is zero, then the entry is deleted, otherwise * it is kept. * \param other A \c void pointer that is passed to the filtering * function. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_fkeep( igraph_sparsemat_t *A, igraph_integer_t (*fkeep)(igraph_integer_t, igraph_integer_t, igraph_real_t, void*), void *other ) { IGRAPH_ASSERT(A); IGRAPH_ASSERT(fkeep); if (!igraph_sparsemat_is_cc(A)) { IGRAPH_ERROR("The sparse matrix is not in compressed format.", IGRAPH_EINVAL); } if (cs_fkeep(A->cs, fkeep, other) < 0) { IGRAPH_ERROR("External function cs_keep has returned an unknown error while filtering the matrix.", IGRAPH_FAILURE); } return IGRAPH_SUCCESS; } /** * \function igraph_sparsemat_dropzeros * \brief Drops the zero elements from a sparse matrix. * * As a result of matrix operations, some of the entries in a sparse * matrix might be zero. This function removes these entries. * \param A The input matrix, it must be in column-compressed format. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_dropzeros(igraph_sparsemat_t *A) { if (!cs_dropzeros(A->cs)) { IGRAPH_ERROR("Cannot drop zeros from sparse matrix", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_droptol * \brief Drops the almost zero elements from a sparse matrix. * * This function is similar to \ref igraph_sparsemat_dropzeros(), but it * also drops entries that are closer to zero than the given tolerance * threshold. * \param A The input matrix, it must be in column-compressed format. * \param tol Real number, giving the tolerance threshold. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_droptol(igraph_sparsemat_t *A, igraph_real_t tol) { IGRAPH_ASSERT(A); if (!igraph_sparsemat_is_cc(A)) { IGRAPH_ERROR("The sparse matrix is not in compressed format.", IGRAPH_EINVAL); } if (cs_droptol(A->cs, tol) < 0) { IGRAPH_ERROR("External function cs_droptol has returned an unknown error.", IGRAPH_FAILURE); } return IGRAPH_SUCCESS; } /** * \function igraph_sparsemat_multiply * \brief Matrix multiplication. * * Multiplies two sparse matrices. * \param A The first input matrix (left hand side), in * column-compressed format. * \param B The second input matrix (right hand side), in * column-compressed format. * \param res Pointer to an uninitialized sparse matrix, the result is * stored here. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_multiply(const igraph_sparsemat_t *A, const igraph_sparsemat_t *B, igraph_sparsemat_t *res) { res->cs = cs_multiply(A->cs, B->cs); if (!res->cs) { IGRAPH_ERROR("Cannot multiply matrices", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_add * \brief Sum of two sparse matrices. * * \param A The first input matrix, in column-compressed format. * \param B The second input matrix, in column-compressed format. * \param alpha Real scalar, \p A is multiplied by \p alpha before the * addition. * \param beta Real scalar, \p B is multiplied by \p beta before the * addition. * \param res Pointer to an uninitialized sparse matrix, the result * is stored here. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_add(const igraph_sparsemat_t *A, const igraph_sparsemat_t *B, igraph_real_t alpha, igraph_real_t beta, igraph_sparsemat_t *res) { res->cs = cs_add(A->cs, B->cs, alpha, beta); if (!res->cs) { IGRAPH_ERROR("Cannot add matrices", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_gaxpy * \brief Matrix-vector product, added to another vector. * * \param A The input matrix, in column-compressed format. * \param x The input vector, its size must match the number of * columns in \p A. * \param res This vector is added to the matrix-vector product * and it is overwritten by the result. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_gaxpy(const igraph_sparsemat_t *A, const igraph_vector_t *x, igraph_vector_t *res) { if (A->cs->n != igraph_vector_size(x) || A->cs->m != igraph_vector_size(res)) { IGRAPH_ERROR("Invalid matrix/vector size for multiplication", IGRAPH_EINVAL); } if (! (cs_gaxpy(A->cs, VECTOR(*x), VECTOR(*res)))) { IGRAPH_ERROR("Cannot perform sparse matrix vector multiplication", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_lsolve * \brief Solves a lower-triangular linear system. * * Solve the Lx=b linear equation system, where the L coefficient * matrix is square and lower-triangular, with a zero-free diagonal. * \param L The input matrix, in column-compressed format. * \param b The right hand side of the linear system. * \param res An initialized vector, the result is stored here. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_lsolve(const igraph_sparsemat_t *L, const igraph_vector_t *b, igraph_vector_t *res) { if (L->cs->m != L->cs->n) { IGRAPH_ERROR("Cannot perform lower triangular solve", IGRAPH_NONSQUARE); } if (res != b) { IGRAPH_CHECK(igraph_vector_update(res, b)); } if (! cs_lsolve(L->cs, VECTOR(*res))) { IGRAPH_ERROR("Cannot perform lower triangular solve", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_ltsolve * \brief Solves an upper-triangular linear system. * * Solve the L'x=b linear equation system, where the L * matrix is square and lower-triangular, with a zero-free diagonal. * \param L The input matrix, in column-compressed format. * \param b The right hand side of the linear system. * \param res An initialized vector, the result is stored here. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_ltsolve(const igraph_sparsemat_t *L, const igraph_vector_t *b, igraph_vector_t *res) { if (L->cs->m != L->cs->n) { IGRAPH_ERROR("Cannot perform transposed lower triangular solve", IGRAPH_NONSQUARE); } if (res != b) { IGRAPH_CHECK(igraph_vector_update(res, b)); } if (!cs_ltsolve(L->cs, VECTOR(*res))) { IGRAPH_ERROR("Cannot perform lower triangular solve", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_usolve * \brief Solves an upper-triangular linear system. * * Solves the Ux=b upper triangular system. * \param U The input matrix, in column-compressed format. * \param b The right hand side of the linear system. * \param res An initialized vector, the result is stored here. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_usolve(const igraph_sparsemat_t *U, const igraph_vector_t *b, igraph_vector_t *res) { if (U->cs->m != U->cs->n) { IGRAPH_ERROR("Cannot perform upper triangular solve", IGRAPH_NONSQUARE); } if (res != b) { IGRAPH_CHECK(igraph_vector_update(res, b)); } if (! cs_usolve(U->cs, VECTOR(*res))) { IGRAPH_ERROR("Cannot perform upper triangular solve", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_utsolve * \brief Solves a lower-triangular linear system. * * This is the same as \ref igraph_sparsemat_usolve(), but U'x=b is * solved, where the apostrophe denotes the transpose. * \param U The input matrix, in column-compressed format. * \param b The right hand side of the linear system. * \param res An initialized vector, the result is stored here. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_utsolve(const igraph_sparsemat_t *U, const igraph_vector_t *b, igraph_vector_t *res) { if (U->cs->m != U->cs->n) { IGRAPH_ERROR("Cannot perform transposed upper triangular solve", IGRAPH_NONSQUARE); } if (res != b) { IGRAPH_CHECK(igraph_vector_update(res, b)); } if (!cs_utsolve(U->cs, VECTOR(*res))) { IGRAPH_ERROR("Cannot perform transposed upper triangular solve", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_cholsol * \brief Solves a symmetric linear system via Cholesky decomposition. * * Solve Ax=b, where A is a symmetric positive definite matrix. * \param A The input matrix, in column-compressed format. * \param v The right hand side. * \param res An initialized vector, the result is stored here. * \param order An integer giving the ordering method to use for the * factorization. Zero is the natural ordering; if it is one, then * the fill-reducing minimum-degree ordering of A+A' is used. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_cholsol(const igraph_sparsemat_t *A, const igraph_vector_t *b, igraph_vector_t *res, int order) { if (A->cs->m != A->cs->n) { IGRAPH_ERROR("Cannot perform sparse symmetric solve", IGRAPH_NONSQUARE); } if (res != b) { IGRAPH_CHECK(igraph_vector_update(res, b)); } if (! cs_cholsol(order, A->cs, VECTOR(*res))) { IGRAPH_ERROR("Cannot perform sparse symmetric solve", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_lusol * \brief Solves a linear system via LU decomposition. * * Solve Ax=b, via LU factorization of A. * \param A The input matrix, in column-compressed format. * \param b The right hand side of the equation. * \param res An initialized vector, the result is stored here. * \param order The ordering method to use, zero means the natural * ordering, one means the fill-reducing minimum-degree ordering of * A+A', two means the ordering of A'*A, after removing the dense * rows from A. Three means the ordering of A'*A. * \param tol Real number, the tolerance limit to use for the numeric * LU factorization. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_lusol(const igraph_sparsemat_t *A, const igraph_vector_t *b, igraph_vector_t *res, int order, igraph_real_t tol) { if (A->cs->m != A->cs->n) { IGRAPH_ERROR("Cannot perform LU solve", IGRAPH_NONSQUARE); } if (res != b) { IGRAPH_CHECK(igraph_vector_update(res, b)); } if (! cs_lusol(order, A->cs, VECTOR(*res), tol)) { IGRAPH_ERROR("Cannot perform LU solve", IGRAPH_FAILURE); } return 0; } static int igraph_i_sparsemat_cc(igraph_t *graph, const igraph_sparsemat_t *A, igraph_bool_t directed) { igraph_vector_t edges; CS_INT no_of_nodes = A->cs->m; CS_INT no_of_edges = A->cs->p[A->cs->n]; CS_INT *p = A->cs->p; CS_INT *i = A->cs->i; long int from = 0; long int to = 0; long int e = 0; if (no_of_nodes != A->cs->n) { IGRAPH_ERROR("Cannot create graph object", IGRAPH_NONSQUARE); } IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); while (*p < no_of_edges) { while (to < * (p + 1)) { if (directed || from >= *i) { VECTOR(edges)[e++] = from; VECTOR(edges)[e++] = (*i); } to++; i++; } from++; p++; } igraph_vector_resize(&edges, e); IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_sparsemat_triplet(igraph_t *graph, const igraph_sparsemat_t *A, igraph_bool_t directed) { igraph_vector_t edges; CS_INT no_of_nodes = A->cs->m; CS_INT no_of_edges = A->cs->nz; CS_INT *i = A->cs->p; CS_INT *j = A->cs->i; long int e; if (no_of_nodes != A->cs->n) { IGRAPH_ERROR("Cannot create graph object", IGRAPH_NONSQUARE); } IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); for (e = 0; e < 2 * no_of_edges; i++, j++) { if (directed || *i >= *j) { VECTOR(edges)[e++] = (*i); VECTOR(edges)[e++] = (*j); } } igraph_vector_resize(&edges, e); IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_sparsemat * \brief Creates an igraph graph from a sparse matrix. * * One edge is created for each non-zero entry in the matrix. If you * have a symmetric matrix, and want to create an undirected graph, * then delete the entries in the upper diagonal first, or call \ref * igraph_simplify() on the result graph to eliminate the multiple * edges. * \param graph Pointer to an uninitialized igraph_t object, the * graphs is stored here. * \param A The input matrix, in triplet or column-compressed format. * \param directed Boolean scalar, whether to create a directed * graph. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat(igraph_t *graph, const igraph_sparsemat_t *A, igraph_bool_t directed) { if (A->cs->nz < 0) { return (igraph_i_sparsemat_cc(graph, A, directed)); } else { return (igraph_i_sparsemat_triplet(graph, A, directed)); } } static int igraph_i_weighted_sparsemat_cc(const igraph_sparsemat_t *A, igraph_bool_t directed, const char *attr, igraph_bool_t loops, igraph_vector_t *edges, igraph_vector_t *weights) { CS_INT no_of_edges = A->cs->p[A->cs->n]; CS_INT *p = A->cs->p; CS_INT *i = A->cs->i; CS_ENTRY *x = A->cs->x; long int from = 0; long int to = 0; long int e = 0, w = 0; IGRAPH_UNUSED(attr); igraph_vector_resize(edges, no_of_edges * 2); igraph_vector_resize(weights, no_of_edges); while (*p < no_of_edges) { while (to < * (p + 1)) { if ( (loops || from != *i) && (directed || from >= *i) && *x != 0) { VECTOR(*edges)[e++] = (*i); VECTOR(*edges)[e++] = from; VECTOR(*weights)[w++] = (*x); } to++; i++; x++; } from++; p++; } igraph_vector_resize(edges, e); igraph_vector_resize(weights, w); return 0; } static int igraph_i_weighted_sparsemat_triplet(const igraph_sparsemat_t *A, igraph_bool_t directed, const char *attr, igraph_bool_t loops, igraph_vector_t *edges, igraph_vector_t *weights) { IGRAPH_UNUSED(A); IGRAPH_UNUSED(directed); IGRAPH_UNUSED(attr); IGRAPH_UNUSED(loops); IGRAPH_UNUSED(edges); IGRAPH_UNUSED(weights); /* TODO */ IGRAPH_ERROR("Triplet matrices are not implemented", IGRAPH_UNIMPLEMENTED); } int igraph_weighted_sparsemat(igraph_t *graph, const igraph_sparsemat_t *A, igraph_bool_t directed, const char *attr, igraph_bool_t loops) { igraph_vector_t edges, weights; CS_INT pot_edges = A->cs->nz < 0 ? A->cs->p[A->cs->n] : A->cs->nz; const char* default_attr = "weight"; igraph_vector_ptr_t attr_vec; igraph_attribute_record_t attr_rec; CS_INT no_of_nodes = A->cs->m; if (no_of_nodes != A->cs->n) { IGRAPH_ERROR("Cannot create graph object", IGRAPH_NONSQUARE); } IGRAPH_VECTOR_INIT_FINALLY(&edges, pot_edges * 2); IGRAPH_VECTOR_INIT_FINALLY(&weights, pot_edges); IGRAPH_VECTOR_PTR_INIT_FINALLY(&attr_vec, 1); if (A->cs->nz < 0) { IGRAPH_CHECK(igraph_i_weighted_sparsemat_cc(A, directed, attr, loops, &edges, &weights)); } else { IGRAPH_CHECK(igraph_i_weighted_sparsemat_triplet(A, directed, attr, loops, &edges, &weights)); } /* Prepare attribute record */ attr_rec.name = attr ? attr : default_attr; attr_rec.type = IGRAPH_ATTRIBUTE_NUMERIC; attr_rec.value = &weights; VECTOR(attr_vec)[0] = &attr_rec; /* Create graph */ IGRAPH_CHECK(igraph_empty(graph, (igraph_integer_t) no_of_nodes, directed)); IGRAPH_FINALLY(igraph_destroy, graph); if (igraph_vector_size(&edges) > 0) { IGRAPH_CHECK(igraph_add_edges(graph, &edges, &attr_vec)); } IGRAPH_FINALLY_CLEAN(1); /* Cleanup */ igraph_vector_destroy(&edges); igraph_vector_destroy(&weights); igraph_vector_ptr_destroy(&attr_vec); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_get_sparsemat * \brief Converts an igraph graph to a sparse matrix. * * If the graph is undirected, then a symmetric matrix is created. * \param graph The input graph. * \param res Pointer to an uninitialized sparse matrix. The result * will be stored here. * \return Error code. * * Time complexity: TODO. */ int igraph_get_sparsemat(const igraph_t *graph, igraph_sparsemat_t *res) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_bool_t directed = igraph_is_directed(graph); long int nzmax = directed ? no_of_edges : no_of_edges * 2; long int i; IGRAPH_CHECK(igraph_sparsemat_init(res, (igraph_integer_t) no_of_nodes, (igraph_integer_t) no_of_nodes, (igraph_integer_t) nzmax)); for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); IGRAPH_CHECK(igraph_sparsemat_entry(res, (int) from, (int) to, 1.0)); if (!directed && from != to) { IGRAPH_CHECK(igraph_sparsemat_entry(res, (int) to, (int) from, 1.0)); } } return 0; } #define CHECK(x) if ((x)<0) { IGRAPH_ERROR("Cannot write to file", IGRAPH_EFILE); } /** * \function igraph_sparsemat_print * \brief Prints a sparse matrix to a file. * * Only the non-zero entries are printed. This function serves more as * a debugging utility, as currently there is no function that could * read back the printed matrix from the file. * \param A The input matrix, triplet or column-compressed format. * \param outstream The stream to print it to. * \return Error code. * * Time complexity: O(nz) for triplet matrices, O(n+nz) for * column-compressed matrices. nz is the number of non-zero elements, * n is the number columns in the matrix. */ int igraph_sparsemat_print(const igraph_sparsemat_t *A, FILE *outstream) { if (A->cs->nz < 0) { /* CC */ CS_INT j, p; for (j = 0; j < A->cs->n; j++) { CHECK(fprintf(outstream, "col " CS_ID ": locations " CS_ID " to " CS_ID "\n", j, A->cs->p[j], A->cs->p[j + 1] - 1)); for (p = A->cs->p[j]; p < A->cs->p[j + 1]; p++) { CHECK(fprintf(outstream, CS_ID " : %g\n", A->cs->i[p], A->cs->x[p])); } } } else { /* Triplet */ CS_INT p; for (p = 0; p < A->cs->nz; p++) { CHECK(fprintf(outstream, CS_ID " " CS_ID " : %g\n", A->cs->i[p], A->cs->p[p], A->cs->x[p])); } } return 0; } #undef CHECK static int igraph_i_sparsemat_eye_triplet(igraph_sparsemat_t *A, int n, int nzmax, igraph_real_t value) { long int i; IGRAPH_CHECK(igraph_sparsemat_init(A, n, n, nzmax)); for (i = 0; i < n; i++) { igraph_sparsemat_entry(A, (int) i, (int) i, value); } return 0; } static int igraph_i_sparsemat_eye_cc(igraph_sparsemat_t *A, int n, igraph_real_t value) { CS_INT i; A->cs = cs_spalloc(n, n, n, /*values=*/ 1, /*triplet=*/ 0); if (!A->cs) { IGRAPH_ERROR("Cannot create eye sparse matrix", IGRAPH_FAILURE); } for (i = 0; i < n; i++) { A->cs->p [i] = i; A->cs->i [i] = i; A->cs->x [i] = value; } A->cs->p [n] = n; return 0; } /** * \function igraph_sparsemat_eye * \brief Creates a sparse identity matrix. * * \param A An uninitialized sparse matrix, the result is stored * here. * \param n The number of rows and number of columns in the matrix. * \param nzmax The maximum number of non-zero elements, this * essentially gives the amount of memory that will be allocated for * matrix elements. * \param value The value to store in the diagonal. * \param compress Whether to create a column-compressed matrix. If * false, then a triplet matrix is created. * \return Error code. * * Time complexity: O(n). */ int igraph_sparsemat_eye(igraph_sparsemat_t *A, int n, int nzmax, igraph_real_t value, igraph_bool_t compress) { if (compress) { return (igraph_i_sparsemat_eye_cc(A, n, value)); } else { return (igraph_i_sparsemat_eye_triplet(A, n, nzmax, value)); } } static int igraph_i_sparsemat_diag_triplet(igraph_sparsemat_t *A, int nzmax, const igraph_vector_t *values) { int i, n = (int) igraph_vector_size(values); IGRAPH_CHECK(igraph_sparsemat_init(A, n, n, nzmax)); for (i = 0; i < n; i++) { igraph_sparsemat_entry(A, i, i, VECTOR(*values)[i]); } return 0; } static int igraph_i_sparsemat_diag_cc(igraph_sparsemat_t *A, const igraph_vector_t *values) { CS_INT i, n = igraph_vector_size(values); A->cs = cs_spalloc(n, n, n, /*values=*/ 1, /*triplet=*/ 0); if (!A->cs) { IGRAPH_ERROR("Cannot create eye sparse matrix", IGRAPH_FAILURE); } for (i = 0; i < n; i++) { A->cs->p [i] = i; A->cs->i [i] = i; A->cs->x [i] = VECTOR(*values)[i]; } A->cs->p [n] = n; return 0; } /** * \function igraph_sparsemat_diag * \brief Creates a sparse diagonal matrix. * * \param A An uninitialized sparse matrix, the result is stored * here. * \param nzmax The maximum number of non-zero elements, this * essentially gives the amount of memory that will be allocated for * matrix elements. * \param values The values to store in the diagonal, the size of the * matrix defined by the length of this vector. * \param compress Whether to create a column-compressed matrix. If * false, then a triplet matrix is created. * \return Error code. * * Time complexity: O(n), the length of the diagonal vector. */ int igraph_sparsemat_diag(igraph_sparsemat_t *A, int nzmax, const igraph_vector_t *values, igraph_bool_t compress) { if (compress) { return (igraph_i_sparsemat_diag_cc(A, values)); } else { return (igraph_i_sparsemat_diag_triplet(A, nzmax, values)); } } static int igraph_i_sparsemat_arpack_multiply(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_sparsemat_t *A = extra; igraph_vector_t vto, vfrom; igraph_vector_view(&vto, to, n); igraph_vector_view(&vfrom, from, n); igraph_vector_null(&vto); IGRAPH_CHECK(igraph_sparsemat_gaxpy(A, &vfrom, &vto)); return 0; } typedef struct igraph_i_sparsemat_arpack_rssolve_data_t { igraph_sparsemat_symbolic_t *dis; igraph_sparsemat_numeric_t *din; igraph_real_t tol; igraph_sparsemat_solve_t method; } igraph_i_sparsemat_arpack_rssolve_data_t; static int igraph_i_sparsemat_arpack_solve(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_sparsemat_arpack_rssolve_data_t *data = extra; igraph_vector_t vfrom, vto; igraph_vector_view(&vfrom, from, n); igraph_vector_view(&vto, to, n); if (data->method == IGRAPH_SPARSEMAT_SOLVE_LU) { IGRAPH_CHECK(igraph_sparsemat_luresol(data->dis, data->din, &vfrom, &vto)); } else if (data->method == IGRAPH_SPARSEMAT_SOLVE_QR) { IGRAPH_CHECK(igraph_sparsemat_qrresol(data->dis, data->din, &vfrom, &vto)); } return 0; } /** * \function igraph_sparsemat_arpack_rssolve * \brief Eigenvalues and eigenvectors of a symmetric sparse matrix via ARPACK. * * \param The input matrix, must be column-compressed. * \param options It is passed to \ref igraph_arpack_rssolve(). See * \ref igraph_arpack_options_t for the details. If \c mode is 1, * then ARPACK uses regular mode, if \c mode is 3, then shift and * invert mode is used and the \c sigma structure member defines * the shift. * \param storage Storage for ARPACK. See \ref * igraph_arpack_rssolve() and \ref igraph_arpack_storage_t for * details. * \param values An initialized vector or a null pointer, the * eigenvalues are stored here. * \param vectors An initialised matrix, or a null pointer, the * eigenvectors are stored here, in the columns. * \param solvemethod The method to solve the linear system, if \c * mode is 3, i.e. the shift and invert mode is used. * Possible values: * \clist * \cli IGRAPH_SPARSEMAT_SOLVE_LU * The linear system is solved using LU decomposition. * \cli IGRAPH_SPARSEMAT_SOLVE_QR * The linear system is solved using QR decomposition. * \endclist * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_arpack_rssolve(const igraph_sparsemat_t *A, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_sparsemat_solve_t solvemethod) { int n = (int) igraph_sparsemat_nrow(A); if (n != igraph_sparsemat_ncol(A)) { IGRAPH_ERROR("Non-square matrix for ARPACK", IGRAPH_NONSQUARE); } options->n = n; if (options->mode == 1) { IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_sparsemat_arpack_multiply, (void*) A, options, storage, values, vectors)); } else if (options->mode == 3) { igraph_real_t sigma = options->sigma; igraph_sparsemat_t OP, eye; igraph_sparsemat_symbolic_t symb; igraph_sparsemat_numeric_t num; igraph_i_sparsemat_arpack_rssolve_data_t data; /*-----------------------------------*/ /* We need to factor the (A-sigma*I) */ /*-----------------------------------*/ /* Create (A-sigma*I) */ IGRAPH_CHECK(igraph_sparsemat_eye(&eye, /*n=*/ n, /*nzmax=*/ n, /*value=*/ -sigma, /*compress=*/ 1)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &eye); IGRAPH_CHECK(igraph_sparsemat_add(/*A=*/ A, /*B=*/ &eye, /*alpha=*/ 1.0, /*beta=*/ 1.0, /*res=*/ &OP)); igraph_sparsemat_destroy(&eye); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_sparsemat_destroy, &OP); if (solvemethod == IGRAPH_SPARSEMAT_SOLVE_LU) { /* Symbolic analysis */ IGRAPH_CHECK(igraph_sparsemat_symblu(/*order=*/ 0, &OP, &symb)); IGRAPH_FINALLY(igraph_sparsemat_symbolic_destroy, &symb); /* Numeric LU factorization */ IGRAPH_CHECK(igraph_sparsemat_lu(&OP, &symb, &num, /*tol=*/ 0)); IGRAPH_FINALLY(igraph_sparsemat_numeric_destroy, &num); } else if (solvemethod == IGRAPH_SPARSEMAT_SOLVE_QR) { /* Symbolic analysis */ IGRAPH_CHECK(igraph_sparsemat_symbqr(/*order=*/ 0, &OP, &symb)); IGRAPH_FINALLY(igraph_sparsemat_symbolic_destroy, &symb); /* Numeric QR factorization */ IGRAPH_CHECK(igraph_sparsemat_qr(&OP, &symb, &num)); IGRAPH_FINALLY(igraph_sparsemat_numeric_destroy, &num); } data.dis = &symb; data.din = # data.tol = options->tol; data.method = solvemethod; IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_sparsemat_arpack_solve, (void*) &data, options, storage, values, vectors)); igraph_sparsemat_numeric_destroy(&num); igraph_sparsemat_symbolic_destroy(&symb); igraph_sparsemat_destroy(&OP); IGRAPH_FINALLY_CLEAN(3); } return 0; } /** * \function igraph_sparsemat_arpack_rnsolve * \brief Eigenvalues and eigenvectors of a nonsymmetric sparse matrix via ARPACK. * * Eigenvalues and/or eigenvectors of a nonsymmetric sparse matrix. * \param A The input matrix, in column-compressed mode. * \param options ARPACK options, it is passed to \ref * igraph_arpack_rnsolve(). See also \ref igraph_arpack_options_t * for details. * \param storage Storage for ARPACK, this is passed to \ref * igraph_arpack_rnsolve(). See \ref igraph_arpack_storage_t for * details. * \param values An initialized matrix, or a null pointer. If not a * null pointer, then the eigenvalues are stored here, the first * column is the real part, the second column is the imaginary * part. * \param vectors An initialized matrix, or a null pointer. If not a * null pointer, then the eigenvectors are stored here, please see * \ref igraph_arpack_rnsolve() for the format. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_arpack_rnsolve(const igraph_sparsemat_t *A, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_matrix_t *values, igraph_matrix_t *vectors) { int n = (int) igraph_sparsemat_nrow(A); if (n != igraph_sparsemat_ncol(A)) { IGRAPH_ERROR("Non-square matrix for ARPACK", IGRAPH_NONSQUARE); } options->n = n; return igraph_arpack_rnsolve(igraph_i_sparsemat_arpack_multiply, (void*) A, options, storage, values, vectors); } /** * \function igraph_sparsemat_symbqr * \brief Symbolic QR decomposition. * * QR decomposition of sparse matrices involves two steps, the first * is calling this function, and then \ref * igraph_sparsemat_qr(). * \param order The ordering to use: 0 means natural ordering, 1 means * minimum degree ordering of A+A', 2 is minimum degree ordering of * A'A after removing the dense rows from A, and 3 is the minimum * degree ordering of A'A. * \param A The input matrix, in column-compressed format. * \param dis The result of the symbolic analysis is stored here. Once * not needed anymore, it must be destroyed by calling \ref * igraph_sparsemat_symbolic_destroy(). * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_symbqr(long int order, const igraph_sparsemat_t *A, igraph_sparsemat_symbolic_t *dis) { dis->symbolic = cs_sqr((int) order, A->cs, /*qr=*/ 1); if (!dis->symbolic) { IGRAPH_ERROR("Cannot do symbolic QR decomposition", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_symblu * \brief Symbolic LU decomposition. * * LU decomposition of sparse matrices involves two steps, the first * is calling this function, and then \ref igraph_sparsemat_lu(). * \param order The ordering to use: 0 means natural ordering, 1 means * minimum degree ordering of A+A', 2 is minimum degree ordering of * A'A after removing the dense rows from A, and 3 is the minimum * degree ordering of A'A. * \param A The input matrix, in column-compressed format. * \param dis The result of the symbolic analysis is stored here. Once * not needed anymore, it must be destroyed by calling \ref * igraph_sparsemat_symbolic_destroy(). * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_symblu(long int order, const igraph_sparsemat_t *A, igraph_sparsemat_symbolic_t *dis) { dis->symbolic = cs_sqr((int) order, A->cs, /*qr=*/ 0); if (!dis->symbolic) { IGRAPH_ERROR("Cannot do symbolic LU decomposition", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_lu * \brief LU decomposition of a sparse matrix. * * Performs numeric sparse LU decomposition of a matrix. * \param A The input matrix, in column-compressed format. * \param dis The symbolic analysis for LU decomposition, coming from * a call to the \ref igraph_sparsemat_symblu() function. * \param din The numeric decomposition, the result is stored here. It * can be used to solve linear systems with changing right hand * side vectors, by calling \ref igraph_sparsemat_luresol(). Once * not needed any more, it must be destroyed by calling \ref * igraph_sparsemat_symbolic_destroy() on it. * \param tol The tolerance for the numeric LU decomposition. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_lu(const igraph_sparsemat_t *A, const igraph_sparsemat_symbolic_t *dis, igraph_sparsemat_numeric_t *din, double tol) { din->numeric = cs_lu(A->cs, dis->symbolic, tol); if (!din->numeric) { IGRAPH_ERROR("Cannot do LU decomposition", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_qr * \brief QR decomposition of a sparse matrix. * * Numeric QR decomposition of a sparse matrix. * \param A The input matrix, in column-compressed format. * \param dis The result of the symbolic QR analysis, from the * function \ref igraph_sparsemat_symbqr(). * \param din The result of the decomposition is stored here, it can * be used to solve many linear systems with the same coefficient * matrix and changing right hand sides, using the \ref * igraph_sparsemat_qrresol() function. Once not needed any more, * one should call \ref igraph_sparsemat_numeric_destroy() on it to * free the allocated memory. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_qr(const igraph_sparsemat_t *A, const igraph_sparsemat_symbolic_t *dis, igraph_sparsemat_numeric_t *din) { din->numeric = cs_qr(A->cs, dis->symbolic); if (!din->numeric) { IGRAPH_ERROR("Cannot do QR decomposition", IGRAPH_FAILURE); } return 0; } /** * \function igraph_sparsemat_luresol * \brief Solves a linear system using a precomputed LU decomposition. * * Uses the LU decomposition of a matrix to solve linear systems. * \param dis The symbolic analysis of the coefficient matrix, the * result of \ref igraph_sparsemat_symblu(). * \param din The LU decomposition, the result of a call to \ref * igraph_sparsemat_lu(). * \param b A vector that defines the right hand side of the linear * equation system. * \param res An initialized vector, the solution of the linear system * is stored here. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_luresol(const igraph_sparsemat_symbolic_t *dis, const igraph_sparsemat_numeric_t *din, const igraph_vector_t *b, igraph_vector_t *res) { int n = din->numeric->L->n; igraph_real_t *workspace; if (res != b) { IGRAPH_CHECK(igraph_vector_update(res, b)); } workspace = IGRAPH_CALLOC(n, igraph_real_t); if (!workspace) { IGRAPH_ERROR("Cannot LU (re)solve sparse matrix", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, workspace); if (!cs_ipvec(din->numeric->pinv, VECTOR(*res), workspace, n)) { IGRAPH_ERROR("Cannot LU (re)solve sparse matrix", IGRAPH_FAILURE); } if (!cs_lsolve(din->numeric->L, workspace)) { IGRAPH_ERROR("Cannot LU (re)solve sparse matrix", IGRAPH_FAILURE); } if (!cs_usolve(din->numeric->U, workspace)) { IGRAPH_ERROR("Cannot LU (re)solve sparse matrix", IGRAPH_FAILURE); } if (!cs_ipvec(dis->symbolic->q, workspace, VECTOR(*res), n)) { IGRAPH_ERROR("Cannot LU (re)solve sparse matrix", IGRAPH_FAILURE); } IGRAPH_FREE(workspace); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_sparsemat_qrresol * \brief Solves a linear system using a precomputed QR decomposition. * * Solves a linear system using a QR decomposition of its coefficient * matrix. * \param dis Symbolic analysis of the coefficient matrix, the result * of \ref igraph_sparsemat_symbqr(). * \param din The QR decomposition of the coefficient matrix, the * result of \ref igraph_sparsemat_qr(). * \param b Vector, giving the right hand side of the linear equation * system. * \param res An initialized vector, the solution is stored here. It * is resized as needed. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_qrresol(const igraph_sparsemat_symbolic_t *dis, const igraph_sparsemat_numeric_t *din, const igraph_vector_t *b, igraph_vector_t *res) { int n = din->numeric->L->n; igraph_real_t *workspace; int k; if (res != b) { IGRAPH_CHECK(igraph_vector_update(res, b)); } workspace = IGRAPH_CALLOC(dis->symbolic ? dis->symbolic->m2 : 1, igraph_real_t); if (!workspace) { IGRAPH_ERROR("Cannot QR (re)solve sparse matrix", IGRAPH_FAILURE); } IGRAPH_FINALLY(igraph_free, workspace); if (!cs_ipvec(dis->symbolic->pinv, VECTOR(*res), workspace, n)) { IGRAPH_ERROR("Cannot QR (re)solve sparse matrix", IGRAPH_FAILURE); } for (k = 0; k < n; k++) { if (!cs_happly(din->numeric->L, k, din->numeric->B[k], workspace)) { IGRAPH_ERROR("Cannot QR (re)solve sparse matrix", IGRAPH_FAILURE); } } if (!cs_usolve(din->numeric->U, workspace)) { IGRAPH_ERROR("Cannot QR (re)solve sparse matrix", IGRAPH_FAILURE); } if (!cs_ipvec(dis->symbolic->q, workspace, VECTOR(*res), n)) { IGRAPH_ERROR("Cannot QR (re)solve sparse matrix", IGRAPH_FAILURE); } IGRAPH_FREE(workspace); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_sparsemat_symbolic_destroy * \brief Deallocates memory after a symbolic decomposition. * * Frees the memory allocated by \ref igraph_sparsemat_symbqr() or * \ref igraph_sparsemat_symblu(). * \param dis The symbolic analysis. * * Time complexity: O(1). */ void igraph_sparsemat_symbolic_destroy(igraph_sparsemat_symbolic_t *dis) { cs_sfree(dis->symbolic); dis->symbolic = 0; } /** * \function igraph_sparsemat_numeric_destroy * \brief Deallocates memory after a numeric decomposition. * * Frees the memoty allocated by \ref igraph_sparsemat_qr() or \ref * igraph_sparsemat_lu(). * \param din The LU or QR decomposition. * * Time complexity: O(1). */ void igraph_sparsemat_numeric_destroy(igraph_sparsemat_numeric_t *din) { cs_nfree(din->numeric); din->numeric = 0; } /** * \function igraph_matrix_as_sparsemat * \brief Converts a dense matrix to a sparse matrix. * * \param res An uninitialized sparse matrix, the result is stored * here. * \param mat The dense input matrix. * \param tol Real scalar, the tolerance. Values closer than \p tol to * zero are considered as zero, and will not be included in the * sparse matrix. * \return Error code. * * Time complexity: O(mn), the number of elements in the dense * matrix. */ int igraph_matrix_as_sparsemat(igraph_sparsemat_t *res, const igraph_matrix_t *mat, igraph_real_t tol) { int nrow = (int) igraph_matrix_nrow(mat); int ncol = (int) igraph_matrix_ncol(mat); int i, j, nzmax = 0; for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) { if (fabs(MATRIX(*mat, i, j)) > tol) { nzmax++; } } } IGRAPH_CHECK(igraph_sparsemat_init(res, nrow, ncol, nzmax)); for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) { if (fabs(MATRIX(*mat, i, j)) > tol) { IGRAPH_CHECK(igraph_sparsemat_entry(res, i, j, MATRIX(*mat, i, j))); } } } return 0; } static int igraph_i_sparsemat_as_matrix_cc(igraph_matrix_t *res, const igraph_sparsemat_t *spmat) { long int nrow = igraph_sparsemat_nrow(spmat); long int ncol = igraph_sparsemat_ncol(spmat); CS_INT from = 0, to = 0; CS_INT *p = spmat->cs->p; CS_INT *i = spmat->cs->i; CS_ENTRY *x = spmat->cs->x; CS_INT nzmax = spmat->cs->nzmax; IGRAPH_CHECK(igraph_matrix_resize(res, nrow, ncol)); igraph_matrix_null(res); while (*p < nzmax) { while (to < * (p + 1)) { MATRIX(*res, *i, from) += *x; to++; i++; x++; } from++; p++; } return 0; } static int igraph_i_sparsemat_as_matrix_triplet(igraph_matrix_t *res, const igraph_sparsemat_t *spmat) { long int nrow = igraph_sparsemat_nrow(spmat); long int ncol = igraph_sparsemat_ncol(spmat); CS_INT *i = spmat->cs->p; CS_INT *j = spmat->cs->i; CS_ENTRY *x = spmat->cs->x; CS_INT nz = spmat->cs->nz; CS_INT e; IGRAPH_CHECK(igraph_matrix_resize(res, nrow, ncol)); igraph_matrix_null(res); for (e = 0; e < nz; e++, i++, j++, x++) { MATRIX(*res, *j, *i) += *x; } return 0; } /** * \function igraph_sparsemat_as_matrix * \brief Converts a sparse matrix to a dense matrix. * * \param res Pointer to an initialized matrix, the result is stored * here. It will be resized to the required size. * \param spmat The input sparse matrix, in triplet or * column-compressed format. * \return Error code. * * Time complexity: O(mn), the number of elements in the dense * matrix. */ int igraph_sparsemat_as_matrix(igraph_matrix_t *res, const igraph_sparsemat_t *spmat) { if (spmat->cs->nz < 0) { return (igraph_i_sparsemat_as_matrix_cc(res, spmat)); } else { return (igraph_i_sparsemat_as_matrix_triplet(res, spmat)); } } /** * \function igraph_sparsemat_max * \brief Maximum of a sparse matrix. * * \param A The input matrix, column-compressed. * \return The maximum in the input matrix, or \c IGRAPH_NEGINFINITY * if the matrix has zero elements. * * Time complexity: TODO. */ igraph_real_t igraph_sparsemat_max(igraph_sparsemat_t *A) { CS_INT i, n; CS_ENTRY *ptr; igraph_real_t res; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); ptr = A->cs->x; n = A->cs->nz == -1 ? A->cs->p[A->cs->n] : A->cs->nz; if (n == 0) { return IGRAPH_NEGINFINITY; } res = *ptr; for (i = 1; i < n; i++, ptr++) { if (*ptr > res) { res = *ptr; } } return res; } /* TODO: CC matrix don't actually need _dupl, because the elements are right beside each other. Same for max and minmax. */ /** * \function igraph_sparsemat_min * \brief Minimum of a sparse matrix. * * \param A The input matrix, column-compressed. * \return The minimum in the input matrix, or \c IGRAPH_POSINFINITY * if the matrix has zero elements. * * Time complexity: TODO. */ igraph_real_t igraph_sparsemat_min(igraph_sparsemat_t *A) { CS_INT i, n; CS_ENTRY *ptr; igraph_real_t res; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); ptr = A->cs->x; n = A->cs->nz == -1 ? A->cs->p[A->cs->n] : A->cs->nz; if (n == 0) { return IGRAPH_POSINFINITY; } res = *ptr; for (i = 1; i < n; i++, ptr++) { if (*ptr < res) { res = *ptr; } } return res; } /** * \function igraph_sparsemat_minmax * \brief Minimum and maximum of a sparse matrix. * * \param A The input matrix, column-compressed. * \param min The minimum in the input matrix is stored here, or \c * IGRAPH_POSINFINITY if the matrix has zero elements. * \param max The maximum in the input matrix is stored here, or \c * IGRAPH_NEGINFINITY if the matrix has zero elements. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_minmax(igraph_sparsemat_t *A, igraph_real_t *min, igraph_real_t *max) { CS_INT i, n; CS_ENTRY *ptr; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); ptr = A->cs->x; n = A->cs->nz == -1 ? A->cs->p[A->cs->n] : A->cs->nz; if (n == 0) { *min = IGRAPH_POSINFINITY; *max = IGRAPH_NEGINFINITY; return 0; } *min = *max = *ptr; for (i = 1; i < n; i++, ptr++) { if (*ptr > *max) { *max = *ptr; } else if (*ptr < *min) { *min = *ptr; } } return 0; } /** * \function igraph_sparsemat_count_nonzero * \brief Counts nonzero elements of a sparse matrix. * * \param A The input matrix, column-compressed. * \return Error code. * * Time complexity: TODO. */ long int igraph_sparsemat_count_nonzero(igraph_sparsemat_t *A) { CS_INT i, n; CS_ENTRY *ptr; int res = 0; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); ptr = A->cs->x; n = A->cs->nz == -1 ? A->cs->p[A->cs->n] : A->cs->nz; if (n == 0) { return 0; } for (i = 0; i < n; i++, ptr++) { if (*ptr) { res++; } } return res; } /** * \function igraph_sparsemat_count_nonzerotol * \brief Counts nonzero elements of a sparse matrix, ignoring elements close to zero. * * Count the number of matrix entries that are closer to zero than \p * tol. * \param The input matrix, column-compressed. * \param Real scalar, the tolerance. * \return Error code. * * Time complexity: TODO. */ long int igraph_sparsemat_count_nonzerotol(igraph_sparsemat_t *A, igraph_real_t tol) { CS_INT i, n; CS_ENTRY *ptr; int res = 0; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); ptr = A->cs->x; n = A->cs->nz == -1 ? A->cs->p[A->cs->n] : A->cs->nz; if (n == 0) { return 0; } for (i = 0; i < n; i++, ptr++) { if (*ptr < - tol || *ptr > tol) { res++; } } return res; } static int igraph_i_sparsemat_rowsums_triplet(const igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT i; CS_INT *pi = A->cs->i; CS_ENTRY *px = A->cs->x; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->m)); igraph_vector_null(res); for (i = 0; i < A->cs->nz; i++, pi++, px++) { VECTOR(*res)[ *pi ] += *px; } return 0; } static int igraph_i_sparsemat_rowsums_cc(const igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT ne = A->cs->p[A->cs->n]; CS_ENTRY *px = A->cs->x; CS_INT *pi = A->cs->i; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->m)); igraph_vector_null(res); for (; pi < A->cs->i + ne; pi++, px++) { VECTOR(*res)[ *pi ] += *px; } return 0; } /** * \function igraph_sparsemat_rowsums * \brief Row-wise sums. * * \param A The input matrix, in triplet or column-compressed format. * \param res An initialized vector, the result is stored here. It * will be resized as needed. * \return Error code. * * Time complexity: O(nz), the number of non-zero elements. */ int igraph_sparsemat_rowsums(const igraph_sparsemat_t *A, igraph_vector_t *res) { if (igraph_sparsemat_is_triplet(A)) { return igraph_i_sparsemat_rowsums_triplet(A, res); } else { return igraph_i_sparsemat_rowsums_cc(A, res); } } static int igraph_i_sparsemat_rowmins_triplet(const igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT i; CS_INT *pi = A->cs->i; CS_ENTRY *px = A->cs->x; double inf = IGRAPH_INFINITY; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->m)); igraph_vector_fill(res, inf); for (i = 0; i < A->cs->nz; i++, pi++, px++) { if (*px < VECTOR(*res)[ *pi ]) { VECTOR(*res)[ *pi ] = *px; } } return 0; } static int igraph_i_sparsemat_rowmins_cc(igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT ne; CS_ENTRY *px; CS_INT *pi; double inf = IGRAPH_INFINITY; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); ne = A->cs->p[A->cs->n]; px = A->cs->x; pi = A->cs->i; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->m)); igraph_vector_fill(res, inf); for (; pi < A->cs->i + ne; pi++, px++) { if (*px < VECTOR(*res)[ *pi ]) { VECTOR(*res)[ *pi ] = *px; } } return 0; } int igraph_sparsemat_rowmins(igraph_sparsemat_t *A, igraph_vector_t *res) { if (igraph_sparsemat_is_triplet(A)) { return igraph_i_sparsemat_rowmins_triplet(A, res); } else { return igraph_i_sparsemat_rowmins_cc(A, res); } } static int igraph_i_sparsemat_rowmaxs_triplet(const igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT i; CS_INT *pi = A->cs->i; CS_ENTRY *px = A->cs->x; double inf = IGRAPH_NEGINFINITY; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->m)); igraph_vector_fill(res, inf); for (i = 0; i < A->cs->nz; i++, pi++, px++) { if (*px > VECTOR(*res)[ *pi ]) { VECTOR(*res)[ *pi ] = *px; } } return 0; } static int igraph_i_sparsemat_rowmaxs_cc(igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT ne; CS_ENTRY *px; CS_INT *pi; double inf = IGRAPH_NEGINFINITY; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); ne = A->cs->p[A->cs->n]; px = A->cs->x; pi = A->cs->i; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->m)); igraph_vector_fill(res, inf); for (; pi < A->cs->i + ne; pi++, px++) { if (*px > VECTOR(*res)[ *pi ]) { VECTOR(*res)[ *pi ] = *px; } } return 0; } int igraph_sparsemat_rowmaxs(igraph_sparsemat_t *A, igraph_vector_t *res) { if (igraph_sparsemat_is_triplet(A)) { return igraph_i_sparsemat_rowmaxs_triplet(A, res); } else { return igraph_i_sparsemat_rowmaxs_cc(A, res); } } static int igraph_i_sparsemat_colmins_triplet(const igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT i; CS_INT *pp = A->cs->p; CS_ENTRY *px = A->cs->x; double inf = IGRAPH_INFINITY; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->n)); igraph_vector_fill(res, inf); for (i = 0; i < A->cs->nz; i++, pp++, px++) { if (*px < VECTOR(*res)[ *pp ]) { VECTOR(*res)[ *pp ] = *px; } } return 0; } static int igraph_i_sparsemat_colmins_cc(igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT n; CS_ENTRY *px; CS_INT *pp; CS_INT *pi; double *pr; double inf = IGRAPH_INFINITY; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); n = A->cs->n; px = A->cs->x; pp = A->cs->p; pi = A->cs->i; IGRAPH_CHECK(igraph_vector_resize(res, n)); igraph_vector_fill(res, inf); pr = VECTOR(*res); for (; pp < A->cs->p + n; pp++, pr++) { for (; pi < A->cs->i + * (pp + 1); pi++, px++) { if (*px < *pr) { *pr = *px; } } } return 0; } int igraph_sparsemat_colmins(igraph_sparsemat_t *A, igraph_vector_t *res) { if (igraph_sparsemat_is_triplet(A)) { return igraph_i_sparsemat_colmins_triplet(A, res); } else { return igraph_i_sparsemat_colmins_cc(A, res); } } static int igraph_i_sparsemat_colmaxs_triplet(const igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT i; CS_INT *pp = A->cs->p; CS_ENTRY *px = A->cs->x; double inf = IGRAPH_NEGINFINITY; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->n)); igraph_vector_fill(res, inf); for (i = 0; i < A->cs->nz; i++, pp++, px++) { if (*px > VECTOR(*res)[ *pp ]) { VECTOR(*res)[ *pp ] = *px; } } return 0; } static int igraph_i_sparsemat_colmaxs_cc(igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT n; CS_ENTRY *px; CS_INT *pp; CS_INT *pi; double *pr; double inf = IGRAPH_NEGINFINITY; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); n = A->cs->n; px = A->cs->x; pp = A->cs->p; pi = A->cs->i; IGRAPH_CHECK(igraph_vector_resize(res, n)); igraph_vector_fill(res, inf); pr = VECTOR(*res); for (; pp < A->cs->p + n; pp++, pr++) { for (; pi < A->cs->i + * (pp + 1); pi++, px++) { if (*px > *pr) { *pr = *px; } } } return 0; } int igraph_sparsemat_colmaxs(igraph_sparsemat_t *A, igraph_vector_t *res) { if (igraph_sparsemat_is_triplet(A)) { return igraph_i_sparsemat_colmaxs_triplet(A, res); } else { return igraph_i_sparsemat_colmaxs_cc(A, res); } } static int igraph_i_sparsemat_which_min_rows_triplet(igraph_sparsemat_t *A, igraph_vector_t *res, igraph_vector_int_t *pos) { CS_INT i; CS_INT *pi = A->cs->i; CS_INT *pp = A->cs->p; CS_ENTRY *px = A->cs->x; double inf = IGRAPH_INFINITY; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->m)); IGRAPH_CHECK(igraph_vector_int_resize(pos, A->cs->m)); igraph_vector_fill(res, inf); igraph_vector_int_null(pos); for (i = 0; i < A->cs->nz; i++, pi++, px++, pp++) { if (*px < VECTOR(*res)[ *pi ]) { VECTOR(*res)[ *pi ] = *px; VECTOR(*pos)[ *pi ] = *pp; } } return 0; } static int igraph_i_sparsemat_which_min_rows_cc(igraph_sparsemat_t *A, igraph_vector_t *res, igraph_vector_int_t *pos) { CS_INT n; CS_ENTRY *px; CS_INT *pp; CS_INT *pi; double inf = IGRAPH_INFINITY; int j; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); n = A->cs->n; px = A->cs->x; pp = A->cs->p; pi = A->cs->i; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->m)); IGRAPH_CHECK(igraph_vector_int_resize(pos, A->cs->m)); igraph_vector_fill(res, inf); igraph_vector_int_null(pos); for (j = 0; pp < A->cs->p + n; pp++, j++) { for (; pi < A->cs->i + * (pp + 1); pi++, px++) { if (*px < VECTOR(*res)[ *pi ]) { VECTOR(*res)[ *pi ] = *px; VECTOR(*pos)[ *pi ] = j; } } } return 0; } int igraph_sparsemat_which_min_rows(igraph_sparsemat_t *A, igraph_vector_t *res, igraph_vector_int_t *pos) { if (igraph_sparsemat_is_triplet(A)) { return igraph_i_sparsemat_which_min_rows_triplet(A, res, pos); } else { return igraph_i_sparsemat_which_min_rows_cc(A, res, pos); } } static int igraph_i_sparsemat_which_min_cols_triplet(igraph_sparsemat_t *A, igraph_vector_t *res, igraph_vector_int_t *pos) { CS_INT i; CS_INT *pi = A->cs->i; CS_INT *pp = A->cs->p; CS_ENTRY *px = A->cs->x; double inf = IGRAPH_INFINITY; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->n)); IGRAPH_CHECK(igraph_vector_int_resize(pos, A->cs->n)); igraph_vector_fill(res, inf); igraph_vector_int_null(pos); for (i = 0; i < A->cs->nz; i++, pi++, pp++, px++) { if (*px < VECTOR(*res)[ *pp ]) { VECTOR(*res)[ *pp ] = *px; VECTOR(*pos)[ *pp ] = *pi; } } return 0; } static int igraph_i_sparsemat_which_min_cols_cc(igraph_sparsemat_t *A, igraph_vector_t *res, igraph_vector_int_t *pos) { CS_INT n, j, p; CS_ENTRY *px; double *pr; igraph_integer_t *ppos; double inf = IGRAPH_INFINITY; IGRAPH_CHECK(igraph_sparsemat_dupl(A)); n = A->cs->n; px = A->cs->x; IGRAPH_CHECK(igraph_vector_resize(res, n)); igraph_vector_fill(res, inf); pr = VECTOR(*res); IGRAPH_CHECK(igraph_vector_int_resize(pos, n)); igraph_vector_int_null(pos); ppos = VECTOR(*pos); for (j = 0; j < A->cs->n; j++, pr++, ppos++) { for (p = A->cs->p[j]; p < A->cs->p[j + 1]; p++, px++) { if (*px < *pr) { *pr = *px; *ppos = A->cs->i[p]; } } } return 0; } int igraph_sparsemat_which_min_cols(igraph_sparsemat_t *A, igraph_vector_t *res, igraph_vector_int_t *pos) { if (igraph_sparsemat_is_triplet(A)) { return igraph_i_sparsemat_which_min_cols_triplet(A, res, pos); } else { return igraph_i_sparsemat_which_min_cols_cc(A, res, pos); } } static int igraph_i_sparsemat_colsums_triplet(const igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT i; CS_INT *pp = A->cs->p; CS_ENTRY *px = A->cs->x; IGRAPH_CHECK(igraph_vector_resize(res, A->cs->n)); igraph_vector_null(res); for (i = 0; i < A->cs->nz; i++, pp++, px++) { VECTOR(*res)[ *pp ] += *px; } return 0; } static int igraph_i_sparsemat_colsums_cc(const igraph_sparsemat_t *A, igraph_vector_t *res) { CS_INT n = A->cs->n; CS_ENTRY *px = A->cs->x; CS_INT *pp = A->cs->p; CS_INT *pi = A->cs->i; double *pr; IGRAPH_CHECK(igraph_vector_resize(res, n)); igraph_vector_null(res); pr = VECTOR(*res); for (; pp < A->cs->p + n; pp++, pr++) { for (; pi < A->cs->i + * (pp + 1); pi++, px++) { *pr += *px; } } return 0; } /** * \function igraph_sparsemat_colsums * \brief Column-wise sums. * * \param A The input matrix, in triplet or column-compressed format. * \param res An initialized vector, the result is stored here. It * will be resized as needed. * \return Error code. * * Time complexity: O(nz) for triplet matrices, O(nz+n) for * column-compressed ones, nz is the number of non-zero elements, n is * the number of columns. */ int igraph_sparsemat_colsums(const igraph_sparsemat_t *A, igraph_vector_t *res) { if (igraph_sparsemat_is_triplet(A)) { return igraph_i_sparsemat_colsums_triplet(A, res); } else { return igraph_i_sparsemat_colsums_cc(A, res); } } /** * \function igraph_sparsemat_scale * \brief Scales a sparse matrix. * * Multiplies all elements of a sparse matrix, by the given scalar. * \param A The input matrix. * \param by The scaling factor. * \return Error code. * * Time complexity: O(nz), the number of non-zero elements in the * matrix. */ int igraph_sparsemat_scale(igraph_sparsemat_t *A, igraph_real_t by) { CS_ENTRY *px = A->cs->x; CS_INT n = A->cs->nz == -1 ? A->cs->p[A->cs->n] : A->cs->nz; CS_ENTRY *stop = px + n; for (; px < stop; px++) { *px *= by; } return 0; } /** * \function igraph_sparsemat_add_rows * \brief Adds rows to a sparse matrix. * * The current matrix elements are retained and all elements in the * new rows are zero. * \param A The input matrix, in triplet or column-compressed format. * \param n The number of rows to add. * \return Error code. * * Time complexity: O(1). */ int igraph_sparsemat_add_rows(igraph_sparsemat_t *A, long int n) { A->cs->m += n; return 0; } /** * \function igraph_sparsemat_add_cols * \brief Adds columns to a sparse matrix. * * The current matrix elements are retained, and all elements in the * new columns are zero. * \param A The input matrix, in triplet or column-compressed format. * \param n The number of columns to add. * \return Error code. * * Time complexity: TODO. */ int igraph_sparsemat_add_cols(igraph_sparsemat_t *A, long int n) { if (igraph_sparsemat_is_triplet(A)) { A->cs->n += n; } else { CS_INT realloc_ok = 0, i; CS_INT *newp = cs_realloc(A->cs->p, (A->cs->n + n + 1), sizeof(int), &realloc_ok); if (!realloc_ok) { IGRAPH_ERROR("Cannot add columns to sparse matrix", IGRAPH_ENOMEM); } if (newp != A->cs->p) { A->cs->p = newp; } for (i = A->cs->n + 1; i < A->cs->n + n + 1; i++) { A->cs->p[i] = A->cs->p[i - 1]; } A->cs->n += n; } return 0; } /** * \function igraph_sparsemat_resize * \brief Resizes a sparse matrix. * * This function resizes a sparse matrix. The resized sparse matrix * will be empty. * * \param A The initialized sparse matrix to resize. * \param nrow The new number of rows. * \param ncol The new number of columns. * \param nzmax The new maximum number of elements. * \return Error code. * * Time complexity: O(nzmax), the maximum number of non-zero elements. */ int igraph_sparsemat_resize(igraph_sparsemat_t *A, long int nrow, long int ncol, int nzmax) { if (A->cs->nz < 0) { igraph_sparsemat_t tmp; IGRAPH_CHECK(igraph_sparsemat_init(&tmp, (int) nrow, (int) ncol, nzmax)); igraph_sparsemat_destroy(A); *A = tmp; } else { IGRAPH_CHECK(igraph_sparsemat_realloc(A, nzmax)); A->cs->m = (int) nrow; A->cs->n = (int) ncol; A->cs->nz = 0; } return 0; } /** * \function igraph_sparsemat_nonzero_storage * \brief Returns number of stored entries of a sparse matrix. * * This function will return the number of stored entries of a sparse * matrix. These entries can be zero, and multiple entries can be * at the same position. Use \ref igraph_sparsemat_dupl() to sum * duplicate entries, and \ref igraph_sparsemat_dropzeros() to remove * zeros. * * \param A A sparse matrix in either triplet or compressed form. * \return Number of stored entries. * * Time complexity: O(1). */ int igraph_sparsemat_nonzero_storage(const igraph_sparsemat_t *A) { if (A->cs->nz < 0) { return A->cs->p[A->cs->n]; } else { return A->cs->nz; } } int igraph_sparsemat_getelements(const igraph_sparsemat_t *A, igraph_vector_int_t *i, igraph_vector_int_t *j, igraph_vector_t *x) { CS_INT nz = A->cs->nz; if (nz < 0) { nz = A->cs->p[A->cs->n]; IGRAPH_CHECK(igraph_vector_int_resize(i, nz)); IGRAPH_CHECK(igraph_vector_int_resize(j, A->cs->n + 1)); IGRAPH_CHECK(igraph_vector_resize(x, nz)); memcpy(VECTOR(*i), A->cs->i, (size_t) nz * sizeof(int)); memcpy(VECTOR(*j), A->cs->p, (size_t) (A->cs->n + 1) * sizeof(int)); memcpy(VECTOR(*x), A->cs->x, (size_t) nz * sizeof(igraph_real_t)); } else { IGRAPH_CHECK(igraph_vector_int_resize(i, nz)); IGRAPH_CHECK(igraph_vector_int_resize(j, nz)); IGRAPH_CHECK(igraph_vector_resize(x, nz)); memcpy(VECTOR(*i), A->cs->i, (size_t) nz * sizeof(int)); memcpy(VECTOR(*j), A->cs->p, (size_t) nz * sizeof(int)); memcpy(VECTOR(*x), A->cs->x, (size_t) nz * sizeof(igraph_real_t)); } return 0; } int igraph_sparsemat_scale_rows(igraph_sparsemat_t *A, const igraph_vector_t *fact) { CS_INT *i = A->cs->i; CS_ENTRY *x = A->cs->x; CS_INT no_of_edges = A->cs->nz < 0 ? A->cs->p[A->cs->n] : A->cs->nz; CS_INT e; for (e = 0; e < no_of_edges; e++, x++, i++) { igraph_real_t f = VECTOR(*fact)[*i]; (*x) *= f; } return 0; } static int igraph_i_sparsemat_scale_cols_cc(igraph_sparsemat_t *A, const igraph_vector_t *fact) { CS_INT *i = A->cs->i; CS_ENTRY *x = A->cs->x; CS_INT no_of_edges = A->cs->p[A->cs->n]; CS_INT e; CS_INT c = 0; /* actual column */ for (e = 0; e < no_of_edges; e++, x++, i++) { igraph_real_t f; while (c < A->cs->n && A->cs->p[c + 1] == e) { c++; } f = VECTOR(*fact)[c]; (*x) *= f; } return 0; } static int igraph_i_sparsemat_scale_cols_triplet(igraph_sparsemat_t *A, const igraph_vector_t *fact) { CS_INT *j = A->cs->p; CS_ENTRY *x = A->cs->x; CS_INT no_of_edges = A->cs->nz; CS_INT e; for (e = 0; e < no_of_edges; e++, x++, j++) { igraph_real_t f = VECTOR(*fact)[*j]; (*x) *= f; } return 0; } int igraph_sparsemat_scale_cols(igraph_sparsemat_t *A, const igraph_vector_t *fact) { if (A->cs->nz < 0) { return igraph_i_sparsemat_scale_cols_cc(A, fact); } else { return igraph_i_sparsemat_scale_cols_triplet(A, fact); } } int igraph_sparsemat_multiply_by_dense(const igraph_sparsemat_t *A, const igraph_matrix_t *B, igraph_matrix_t *res) { int m = (int) igraph_sparsemat_nrow(A); int n = (int) igraph_sparsemat_ncol(A); int p = (int) igraph_matrix_ncol(B); int i; if (igraph_matrix_nrow(B) != n) { IGRAPH_ERROR("Invalid dimensions in sparse-dense matrix product", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_resize(res, m, p)); igraph_matrix_null(res); for (i = 0; i < p; i++) { if (!(cs_gaxpy(A->cs, &MATRIX(*B, 0, i), &MATRIX(*res, 0, i)))) { IGRAPH_ERROR("Cannot perform sparse-dense matrix multiplication", IGRAPH_FAILURE); } } return 0; } int igraph_sparsemat_dense_multiply(const igraph_matrix_t *A, const igraph_sparsemat_t *B, igraph_matrix_t *res) { int m = (int) igraph_matrix_nrow(A); int n = (int) igraph_matrix_ncol(A); int p = (int) igraph_sparsemat_ncol(B); int r, c; CS_INT *Bp = B->cs->p; if (igraph_sparsemat_nrow(B) != n) { IGRAPH_ERROR("Invalid dimensions in dense-sparse matrix product", IGRAPH_EINVAL); } if (!igraph_sparsemat_is_cc(B)) { IGRAPH_ERROR("Dense-sparse product is only implemented for " "column-compressed sparse matrices", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_resize(res, m, p)); igraph_matrix_null(res); for (c = 0; c < p; c++) { for (r = 0; r < m; r++) { int idx = *Bp; while (idx < * (Bp + 1)) { MATRIX(*res, r, c) += MATRIX(*A, r, B->cs->i[idx]) * B->cs->x[idx]; idx++; } } Bp++; } return 0; } /** * \function igraph_sparsemat_view * \brief Initialize a sparse matrix and set all parameters. * * This function can be used to temporarily handle existing sparse matrix data, * usually created by another software library, as an \c igraph_sparsemat_t object, * and thus avoid unnecessary copying. It supports data stored in either the * compressed sparse column format, or the (i, j, x) triplet format * where \c i and \c j are the matrix indices of a non-zero element, and \c x * is its value. * * * The compressed sparse column (or row) format is commonly used to represent * sparse matrix data. It consists of three vectors, the \p p column pointers, the * \p i row indices, and the \p x values. p[k] is the number * of non-zero entires in matrix columns k-1 and lower. * p[0] is always zero and p[n] is always the total * number of non-zero entires in the matrix. i[l] is the row index * of the \c l-th stored element, while x[l] is its value. * If a matrix element with indices (j, k) is explicitly stored, * it must be located between positions p[k] and p[k+1] - 1 * (inclusive) in the \p i and \p x vectors. * * * Do not call \ref igraph_sparsemat_destroy() on a sparse matrix created with * this function. Instead, \ref igraph_free() must be called on the \c cs * field of \p A to free the storage allocated by this function. * * * Warning: Matrices created with this function must not be used with functions * that may reallocate the underlying storage, such as \ref igraph_sparsemat_entry(). * * \param A The non-initialized sparse matrix. * \param nzmax The maximum number of entries, typically the actual number of entries. * \param m The number of matrix rows. * \param n The number of matrix columns. * \param p For a compressed matrix, this is the column pointer vector, and * must be of size n+1. For a triplet format matrix, it * is a vector of column indices and must be of size \p nzmax. * \param i The row vector. This should contain the row indices of the * elements in \p x. It must be of size \p nzmax. * \param x The values of the non-zero elements of the sparse matrix. * It must be of size \p nzmax. * \param nz For a compressed matrix, is must be -1. For a triplet format * matrix, is must contain the number of entries. * \return Error code. * * Time complexity: O(1). */ int igraph_sparsemat_view(igraph_sparsemat_t *A, int nzmax, int m, int n, int *p, int *i, double *x, int nz) { A->cs = IGRAPH_CALLOC(1, cs_di); A->cs->nzmax = nzmax; A->cs->m = m; A->cs->n = n; A->cs->p = p; A->cs->i = i; A->cs->x = x; A->cs->nz = nz; return IGRAPH_SUCCESS; } int igraph_i_sparsemat_view(igraph_sparsemat_t *A, int nzmax, int m, int n, int *p, int *i, double *x, int nz) { IGRAPH_WARNING("igraph_i_sparsemat_view() is deprecated, use igraph_sparsemat_view()"); return igraph_sparsemat_view(A, nzmax, m, n, p, i, x, nz); } int igraph_sparsemat_sort(const igraph_sparsemat_t *A, igraph_sparsemat_t *sorted) { igraph_sparsemat_t tmp; IGRAPH_CHECK(igraph_sparsemat_transpose(A, &tmp, /*values=*/ 1)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tmp); IGRAPH_CHECK(igraph_sparsemat_transpose(&tmp, sorted, /*values=*/ 1)); igraph_sparsemat_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_sparsemat_getelements_sorted * \brief Returns the sorted elements of a sparse matrix. * * This function will sort a sparse matrix and return the elements in * 3 vectors. Two vectors will indicate where the elements are located, * and one will give the elements. * * \param A A sparse matrix in either triplet or compressed form. * \param i An initialized int vector. This will store the rows of the * returned elements. * \param j An initialized int vector. For a triplet matrix this will * store the columns of the returned elements. For a compressed * matrix, if the column index is \c k, then j[k] * is the index in \p x of the start of the \c k-th column, and * the last element of \c j is the total number of elements. * The total number of elements in the \c k-th column is * therefore j[k+1] - j[k]. For example, if there * is one element in the first column, and five in the second, * \c j will be set to {0, 1, 6}. * \param x An initialized vector. The elements will be placed here. * \return Error code. * * Time complexity: O(n), the number of stored elements in the sparse matrix. */ int igraph_sparsemat_getelements_sorted(const igraph_sparsemat_t *A, igraph_vector_int_t *i, igraph_vector_int_t *j, igraph_vector_t *x) { if (A->cs->nz < 0) { igraph_sparsemat_t tmp; IGRAPH_CHECK(igraph_sparsemat_sort(A, &tmp)); IGRAPH_FINALLY(igraph_sparsemat_destroy, &tmp); IGRAPH_CHECK(igraph_sparsemat_getelements(&tmp, i, j, x)); igraph_sparsemat_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); } else { IGRAPH_CHECK(igraph_sparsemat_getelements(A, i, j, x)); } return IGRAPH_SUCCESS; } int igraph_sparsemat_nzmax(const igraph_sparsemat_t *A) { return A->cs->nzmax; } int igraph_sparsemat_neg(igraph_sparsemat_t *A) { CS_INT i, nz = A->cs->nz == -1 ? A->cs->p[A->cs->n] : A->cs->nz; CS_ENTRY *px = A->cs->x; for (i = 0; i < nz; i++, px++) { *px = - (*px); } return 0; } /** * \function igraph_sparsemat_iterator_init * \brief Initialize a sparse matrix iterator. * * \param it A pointer to an uninitialized sparse matrix iterator. * \param sparsemat Pointer to the sparse matrix. * \return Error code. This will always return \c IGRAPH_SUCCESS * * Time complexity: O(n), the number of columns of the sparse matrix. */ int igraph_sparsemat_iterator_init(igraph_sparsemat_iterator_t *it, igraph_sparsemat_t *sparsemat) { it->mat = sparsemat; igraph_sparsemat_iterator_reset(it); return IGRAPH_SUCCESS; } /** * \function igraph_sparsemat_iterator_reset * \brief Reset a sparse matrix iterator to the first element. * * \param it A pointer to the sparse matrix iterator. * \return Error code. This will always return \c IGRAPH_SUCCESS * * Time complexity: O(n), the number of columns of the sparse matrix. */ int igraph_sparsemat_iterator_reset(igraph_sparsemat_iterator_t *it) { it->pos = 0; it->col = 0; if (!igraph_sparsemat_is_triplet(it->mat)) { while (it->col < it->mat->cs->n && it->mat->cs->p[it->col + 1] == it->pos) { it->col ++; } } return IGRAPH_SUCCESS; } /** * \function igraph_sparsemat_iterator_end * \brief Query if the iterator is past the last element. * * \param it A pointer to the sparse matrix iterator. * \return true if the iterator is past the last element, false if it * points to an element in a sparse matrix. * * Time complexity: O(1). */ igraph_bool_t igraph_sparsemat_iterator_end(const igraph_sparsemat_iterator_t *it) { CS_INT nz = it->mat->cs->nz == -1 ? it->mat->cs->p[it->mat->cs->n] : it->mat->cs->nz; return it->pos >= nz; } /** * \function igraph_sparsemat_iterator_row * \brief Return the row of the iterator. * * \param it A pointer to the sparse matrix iterator. * \return The row of the element at the current iterator position. * * Time complexity: O(1). */ int igraph_sparsemat_iterator_row(const igraph_sparsemat_iterator_t *it) { return it->mat->cs->i[it->pos]; } /** * \function igraph_sparsemat_iterator_col * \brief Return the column of the iterator. * * \param it A pointer to the sparse matrix iterator. * \return The column of the element at the current iterator position. * * Time complexity: O(1). */ int igraph_sparsemat_iterator_col(const igraph_sparsemat_iterator_t *it) { if (igraph_sparsemat_is_triplet(it->mat)) { return it->mat->cs->p[it->pos]; } else { return it->col; } } /** * \function igraph_sparsemat_iterator_get * \brief Return the element at the current iterator position. * * \param it A pointer to the sparse matrix iterator. * \return The value of the element at the current iterator position. * * Time complexity: O(1). */ igraph_real_t igraph_sparsemat_iterator_get(const igraph_sparsemat_iterator_t *it) { return it->mat->cs->x[it->pos]; } /** * \function igraph_sparsemat_iterator_next * \brief Let a sparse matrix iterator go to the next element. * * \param it A pointer to the sparse matrix iterator. * \return The position of the iterator in the element vector. * * Time complexity: O(n), the number of columns of the sparse matrix. */ int igraph_sparsemat_iterator_next(igraph_sparsemat_iterator_t *it) { it->pos += 1; while (it->col < it->mat->cs->n && it->mat->cs->p[it->col + 1] == it->pos) { it->col++; } return it->pos; } /** * \function igraph_sparsemat_iterator_idx * \brief Returns the element vector index of a sparse matrix iterator. * * \param it A pointer to the sparse matrix iterator. * \return The position of the iterator in the element vector. * * Time complexity: O(1). */ int igraph_sparsemat_iterator_idx(const igraph_sparsemat_iterator_t *it) { return it->pos; } leidenbase/src/core/core/stack.c0000644000176200001440000000425414447675374016317 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_error.h" #include "igraph_types.h" #include "igraph_stack.h" #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "stack.pmt" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_LONG #include "igraph_pmt.h" #include "stack.pmt" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_INT #include "igraph_pmt.h" #include "stack.pmt" #include "igraph_pmt_off.h" #undef BASE_INT #define BASE_CHAR #include "igraph_pmt.h" #include "stack.pmt" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "stack.pmt" #include "igraph_pmt_off.h" #undef BASE_BOOL #define BASE_PTR #include "igraph_pmt.h" #include "stack.pmt" #include "igraph_pmt_off.h" #undef BASE_PTR /** * \ingroup stack * \brief Calls free() on all elements of a pointer stack. */ void igraph_stack_ptr_free_all(igraph_stack_ptr_t* v) { void **ptr; IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->stor_begin != 0); for (ptr = v->stor_begin; ptr < v->end; ptr++) { IGRAPH_FREE(*ptr); } } /** * \ingroup stack * \brief Calls free() on all elements and destroys the stack. */ void igraph_stack_ptr_destroy_all(igraph_stack_ptr_t* v) { IGRAPH_ASSERT(v != 0); IGRAPH_ASSERT(v->stor_begin != 0); igraph_stack_ptr_free_all(v); igraph_stack_ptr_destroy(v); } leidenbase/src/core/core/printing.c0000644000176200001440000001033014447675374017034 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include #ifdef _MSC_VER #define snprintf _snprintf #endif #ifdef DBL_DIG /* Use DBL_DIG to determine the maximum precision used for %g */ #define STRINGIFY_HELPER(x) #x #define STRINGIFY(x) STRINGIFY_HELPER(x) #define IGRAPH_REAL_PRINTF_PRECISE_FORMAT "%." STRINGIFY(DBL_DIG) "g" #else /* Assume a precision of 10 digits for %g */ #define IGRAPH_REAL_PRINTF_PRECISE_FORMAT "%.10g" #endif #ifndef USING_R int igraph_real_printf(igraph_real_t val) { if (igraph_finite(val)) { return printf("%g", val); } else if (igraph_is_nan(val)) { return printf("NaN"); } else if (igraph_is_inf(val)) { if (val < 0) { return printf("-Inf"); } else { return printf("Inf"); } } else { /* fallback */ return printf("%g", val); } } #endif int igraph_real_fprintf(FILE *file, igraph_real_t val) { if (igraph_finite(val)) { return fprintf(file, "%g", val); } else if (igraph_is_nan(val)) { return fprintf(file, "NaN"); } else if (igraph_is_inf(val)) { if (val < 0) { return fprintf(file, "-Inf"); } else { return fprintf(file, "Inf"); } } else { /* fallback */ return fprintf(file, "%g", val); } } int igraph_real_snprintf(char* str, size_t size, igraph_real_t val) { if (igraph_finite(val)) { return snprintf(str, size, "%g", val); } else if (igraph_is_nan(val)) { return snprintf(str, size, "NaN"); } else if (igraph_is_inf(val)) { if (val < 0) { return snprintf(str, size, "-Inf"); } else { return snprintf(str, size, "Inf"); } } else { /* fallback */ return snprintf(str, size, "%g", val); } } #ifndef USING_R int igraph_real_printf_precise(igraph_real_t val) { if (igraph_finite(val)) { return printf(IGRAPH_REAL_PRINTF_PRECISE_FORMAT, val); } else if (igraph_is_nan(val)) { return printf("NaN"); } else if (igraph_is_inf(val)) { if (val < 0) { return printf("-Inf"); } else { return printf("Inf"); } } else { /* fallback */ return printf(IGRAPH_REAL_PRINTF_PRECISE_FORMAT, val); } } #endif int igraph_real_fprintf_precise(FILE *file, igraph_real_t val) { if (igraph_finite(val)) { return fprintf(file, IGRAPH_REAL_PRINTF_PRECISE_FORMAT, val); } else if (igraph_is_nan(val)) { return fprintf(file, "NaN"); } else if (igraph_is_inf(val)) { if (val < 0) { return fprintf(file, "-Inf"); } else { return fprintf(file, "Inf"); } } else { /* fallback */ return fprintf(file, IGRAPH_REAL_PRINTF_PRECISE_FORMAT, val); } } int igraph_real_snprintf_precise(char* str, size_t size, igraph_real_t val) { if (igraph_finite(val)) { return snprintf(str, size, IGRAPH_REAL_PRINTF_PRECISE_FORMAT, val); } else if (igraph_is_nan(val)) { return snprintf(str, size, "NaN"); } else if (igraph_is_inf(val)) { if (val < 0) { return snprintf(str, size, "-Inf"); } else { return snprintf(str, size, "Inf"); } } else { /* fallback */ return snprintf(str, size, IGRAPH_REAL_PRINTF_PRECISE_FORMAT, val); } } leidenbase/src/core/core/heap.c0000644000176200001440000000331714447675374016126 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_heap.h" #define BASE_IGRAPH_REAL #define HEAP_TYPE_MAX #include "igraph_pmt.h" #include "heap.pmt" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MAX #define HEAP_TYPE_MIN #include "igraph_pmt.h" #include "heap.pmt" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MIN #undef BASE_IGRAPH_REAL #define BASE_LONG #define HEAP_TYPE_MAX #include "igraph_pmt.h" #include "heap.pmt" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MAX #define HEAP_TYPE_MIN #include "igraph_pmt.h" #include "heap.pmt" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MIN #undef BASE_LONG #define BASE_CHAR #define HEAP_TYPE_MAX #include "igraph_pmt.h" #include "heap.pmt" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MAX #define HEAP_TYPE_MIN #include "igraph_pmt.h" #include "heap.pmt" #include "igraph_pmt_off.h" #undef HEAP_TYPE_MIN #undef BASE_CHAR leidenbase/src/core/core/vector.c0000644000176200001440000003617214447675374016520 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_error.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_complex.h" #include #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "vector.pmt" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_FLOAT #include "igraph_pmt.h" #include "vector.pmt" #include "igraph_pmt_off.h" #undef BASE_FLOAT #define BASE_LONG #include "igraph_pmt.h" #include "vector.pmt" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_CHAR #include "igraph_pmt.h" #include "vector.pmt" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "vector.pmt" #include "igraph_pmt_off.h" #undef BASE_BOOL #define BASE_INT #include "igraph_pmt.h" #include "vector.pmt" #include "igraph_pmt_off.h" #undef BASE_INT #define BASE_COMPLEX #include "igraph_pmt.h" #include "vector.pmt" #include "igraph_pmt_off.h" #undef BASE_COMPLEX #include "core/math.h" #include "core/indheap.h" /** * \ingroup vector * \function igraph_vector_floor * \brief Transform a real vector to a long vector by flooring each element. * * * Flooring means rounding down to the nearest integer. * * \param from The original real vector object. * \param to Pointer to an initialized long vector. The result will * be stored here. * \return Error code: * \c IGRAPH_ENOMEM: out of memory * * Time complexity: O(n), where n is the number of elements in the vector. */ int igraph_vector_floor(const igraph_vector_t *from, igraph_vector_long_t *to) { long int i, n = igraph_vector_size(from); IGRAPH_CHECK(igraph_vector_long_resize(to, n)); for (i = 0; i < n; i++) { VECTOR(*to)[i] = (long int) floor(VECTOR(*from)[i]); } return IGRAPH_SUCCESS; } int igraph_vector_round(const igraph_vector_t *from, igraph_vector_long_t *to) { long int i, n = igraph_vector_size(from); IGRAPH_CHECK(igraph_vector_long_resize(to, n)); for (i = 0; i < n; i++) { VECTOR(*to)[i] = (long int) round(VECTOR(*from)[i]); } return 0; } int igraph_vector_order2(igraph_vector_t *v) { igraph_indheap_t heap; igraph_indheap_init_array(&heap, VECTOR(*v), igraph_vector_size(v)); IGRAPH_FINALLY(igraph_indheap_destroy, &heap); igraph_vector_clear(v); while (!igraph_indheap_empty(&heap)) { IGRAPH_CHECK(igraph_vector_push_back(v, igraph_indheap_max_index(&heap) - 1)); igraph_indheap_delete_max(&heap); } igraph_indheap_destroy(&heap); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup vector * \function igraph_vector_order * \brief Calculate the order of the elements in a vector. * * * The smallest element will have order zero, the second smallest * order one, etc. * \param v The original \type igraph_vector_t object. * \param v2 A secondary key, another \type igraph_vector_t object. * \param res An initialized \type igraph_vector_t object, it will be * resized to match the size of \p v. The * result of the computation will be stored here. * \param nodes Hint, the largest element in \p v. * \return Error code: * \c IGRAPH_ENOMEM: out of memory * * Time complexity: O() */ int igraph_vector_order(const igraph_vector_t* v, const igraph_vector_t *v2, igraph_vector_t* res, igraph_real_t nodes) { long int edges = igraph_vector_size(v); igraph_vector_t ptr; igraph_vector_t rad; long int i, j; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_VECTOR_INIT_FINALLY(&ptr, (long int) nodes + 1); IGRAPH_VECTOR_INIT_FINALLY(&rad, edges); IGRAPH_CHECK(igraph_vector_resize(res, edges)); for (i = 0; i < edges; i++) { long int radix = (long int) v2->stor_begin[i]; if (VECTOR(ptr)[radix] != 0) { VECTOR(rad)[i] = VECTOR(ptr)[radix]; } VECTOR(ptr)[radix] = i + 1; } j = 0; for (i = 0; i < nodes + 1; i++) { if (VECTOR(ptr)[i] != 0) { long int next = (long int) VECTOR(ptr)[i] - 1; res->stor_begin[j++] = next; while (VECTOR(rad)[next] != 0) { next = (long int) VECTOR(rad)[next] - 1; res->stor_begin[j++] = next; } } } igraph_vector_null(&ptr); igraph_vector_null(&rad); for (i = 0; i < edges; i++) { long int edge = (long int) VECTOR(*res)[edges - i - 1]; long int radix = (long int) VECTOR(*v)[edge]; if (VECTOR(ptr)[radix] != 0) { VECTOR(rad)[edge] = VECTOR(ptr)[radix]; } VECTOR(ptr)[radix] = edge + 1; } j = 0; for (i = 0; i < nodes + 1; i++) { if (VECTOR(ptr)[i] != 0) { long int next = (long int) VECTOR(ptr)[i] - 1; res->stor_begin[j++] = next; while (VECTOR(rad)[next] != 0) { next = (long int) VECTOR(rad)[next] - 1; res->stor_begin[j++] = next; } } } igraph_vector_destroy(&ptr); igraph_vector_destroy(&rad); IGRAPH_FINALLY_CLEAN(2); return 0; } int igraph_vector_order1(const igraph_vector_t* v, igraph_vector_t* res, igraph_real_t nodes) { long int edges = igraph_vector_size(v); igraph_vector_t ptr; igraph_vector_t rad; long int i, j; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_VECTOR_INIT_FINALLY(&ptr, (long int) nodes + 1); IGRAPH_VECTOR_INIT_FINALLY(&rad, edges); IGRAPH_CHECK(igraph_vector_resize(res, edges)); for (i = 0; i < edges; i++) { long int radix = (long int) v->stor_begin[i]; if (VECTOR(ptr)[radix] != 0) { VECTOR(rad)[i] = VECTOR(ptr)[radix]; } VECTOR(ptr)[radix] = i + 1; } j = 0; for (i = 0; i < nodes + 1; i++) { if (VECTOR(ptr)[i] != 0) { long int next = (long int) VECTOR(ptr)[i] - 1; res->stor_begin[j++] = next; while (VECTOR(rad)[next] != 0) { next = (long int) VECTOR(rad)[next] - 1; res->stor_begin[j++] = next; } } } igraph_vector_destroy(&ptr); igraph_vector_destroy(&rad); IGRAPH_FINALLY_CLEAN(2); return 0; } int igraph_vector_order1_int(const igraph_vector_t* v, igraph_vector_int_t* res, igraph_real_t nodes) { long int edges = igraph_vector_size(v); igraph_vector_t ptr; igraph_vector_t rad; long int i, j; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_VECTOR_INIT_FINALLY(&ptr, (long int) nodes + 1); IGRAPH_VECTOR_INIT_FINALLY(&rad, edges); IGRAPH_CHECK(igraph_vector_int_resize(res, edges)); for (i = 0; i < edges; i++) { long int radix = (long int) v->stor_begin[i]; if (VECTOR(ptr)[radix] != 0) { VECTOR(rad)[i] = VECTOR(ptr)[radix]; } VECTOR(ptr)[radix] = i + 1; } j = 0; for (i = 0; i < nodes + 1; i++) { if (VECTOR(ptr)[i] != 0) { long int next = (long int) VECTOR(ptr)[i] - 1; res->stor_begin[j++] = next; while (VECTOR(rad)[next] != 0) { next = (long int) VECTOR(rad)[next] - 1; res->stor_begin[j++] = next; } } } igraph_vector_destroy(&ptr); igraph_vector_destroy(&rad); IGRAPH_FINALLY_CLEAN(2); return 0; } int igraph_vector_rank(const igraph_vector_t *v, igraph_vector_t *res, long int nodes) { igraph_vector_t rad; igraph_vector_t ptr; long int edges = igraph_vector_size(v); long int i, c = 0; IGRAPH_VECTOR_INIT_FINALLY(&rad, nodes); IGRAPH_VECTOR_INIT_FINALLY(&ptr, edges); IGRAPH_CHECK(igraph_vector_resize(res, edges)); for (i = 0; i < edges; i++) { long int elem = (long int) VECTOR(*v)[i]; VECTOR(ptr)[i] = VECTOR(rad)[elem]; VECTOR(rad)[elem] = i + 1; } for (i = 0; i < nodes; i++) { long int p = (long int) VECTOR(rad)[i]; while (p != 0) { VECTOR(*res)[p - 1] = c++; p = (long int) VECTOR(ptr)[p - 1]; } } igraph_vector_destroy(&ptr); igraph_vector_destroy(&rad); IGRAPH_FINALLY_CLEAN(2); return 0; } #ifndef USING_R int igraph_vector_complex_print(const igraph_vector_complex_t *v) { long int i, n = igraph_vector_complex_size(v); if (n != 0) { igraph_complex_t z = VECTOR(*v)[0]; printf("%g%+gi", IGRAPH_REAL(z), IGRAPH_IMAG(z)); } for (i = 1; i < n; i++) { igraph_complex_t z = VECTOR(*v)[i]; printf(" %g%+gi", IGRAPH_REAL(z), IGRAPH_IMAG(z)); } printf("\n"); return 0; } #endif int igraph_vector_complex_fprint(const igraph_vector_complex_t *v, FILE *file) { long int i, n = igraph_vector_complex_size(v); if (n != 0) { igraph_complex_t z = VECTOR(*v)[0]; fprintf(file, "%g%+g", IGRAPH_REAL(z), IGRAPH_IMAG(z)); } for (i = 1; i < n; i++) { igraph_complex_t z = VECTOR(*v)[i]; fprintf(file, " %g%+g", IGRAPH_REAL(z), IGRAPH_IMAG(z)); } fprintf(file, "\n"); return 0; } int igraph_vector_complex_real(const igraph_vector_complex_t *v, igraph_vector_t *real) { long int i, n = igraph_vector_complex_size(v); IGRAPH_CHECK(igraph_vector_resize(real, n)); for (i = 0; i < n; i++) { VECTOR(*real)[i] = IGRAPH_REAL(VECTOR(*v)[i]); } return 0; } int igraph_vector_complex_imag(const igraph_vector_complex_t *v, igraph_vector_t *imag) { long int i, n = igraph_vector_complex_size(v); IGRAPH_CHECK(igraph_vector_resize(imag, n)); for (i = 0; i < n; i++) { VECTOR(*imag)[i] = IGRAPH_IMAG(VECTOR(*v)[i]); } return 0; } int igraph_vector_complex_realimag(const igraph_vector_complex_t *v, igraph_vector_t *real, igraph_vector_t *imag) { long int i, n = igraph_vector_complex_size(v); IGRAPH_CHECK(igraph_vector_resize(real, n)); IGRAPH_CHECK(igraph_vector_resize(imag, n)); for (i = 0; i < n; i++) { igraph_complex_t z = VECTOR(*v)[i]; VECTOR(*real)[i] = IGRAPH_REAL(z); VECTOR(*imag)[i] = IGRAPH_IMAG(z); } return 0; } int igraph_vector_complex_create(igraph_vector_complex_t *v, const igraph_vector_t *real, const igraph_vector_t *imag) { long int i, n = igraph_vector_size(real); if (n != igraph_vector_size(imag)) { IGRAPH_ERROR("Real and imag vector sizes don't match", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_complex_init(v, n)); /* FINALLY not needed */ for (i = 0; i < n; i++) { VECTOR(*v)[i] = igraph_complex(VECTOR(*real)[i], VECTOR(*imag)[i]); } return 0; } int igraph_vector_complex_create_polar(igraph_vector_complex_t *v, const igraph_vector_t *r, const igraph_vector_t *theta) { long int i, n = igraph_vector_size(r); if (n != igraph_vector_size(theta)) { IGRAPH_ERROR("'r' and 'theta' vector sizes don't match", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_complex_init(v, n)); /* FINALLY not needed */ for (i = 0; i < n; i++) { VECTOR(*v)[i] = igraph_complex_polar(VECTOR(*r)[i], VECTOR(*theta)[i]); } return 0; } igraph_bool_t igraph_vector_e_tol(const igraph_vector_t *lhs, const igraph_vector_t *rhs, igraph_real_t tol) { long int i, s; IGRAPH_ASSERT(lhs != 0); IGRAPH_ASSERT(rhs != 0); IGRAPH_ASSERT(lhs->stor_begin != 0); IGRAPH_ASSERT(rhs->stor_begin != 0); s = igraph_vector_size(lhs); if (s != igraph_vector_size(rhs)) { return 0; } else { if (tol == 0) { tol = DBL_EPSILON; } for (i = 0; i < s; i++) { igraph_real_t l = VECTOR(*lhs)[i]; igraph_real_t r = VECTOR(*rhs)[i]; if (l < r - tol || l > r + tol) { return 0; } } return 1; } } int igraph_vector_zapsmall(igraph_vector_t *v, igraph_real_t tol) { long int i, n = igraph_vector_size(v); if (tol < 0.0) { IGRAPH_ERROR("`tol' tolerance must be non-negative", IGRAPH_EINVAL); } if (tol == 0.0) { tol = sqrt(DBL_EPSILON); } for (i = 0; i < n; i++) { igraph_real_t val = VECTOR(*v)[i]; if (val < tol && val > -tol) { VECTOR(*v)[i] = 0.0; } } return 0; } /** * \ingroup vector * \function igraph_vector_is_nan * \brief Check for each element if it is NaN. * * * \param v The \type igraph_vector_t object to check. * \param is_nan The resulting boolean vector indicating for each element * whether it is NaN or not. * \return Error code, * \c IGRAPH_ENOMEM if there is not enough * memory. Note that this function \em never returns an error * if the vector \p is_nan will already be large enough. * Time complexity: O(n), the number of elements. */ int igraph_vector_is_nan(const igraph_vector_t *v, igraph_vector_bool_t *is_nan) { igraph_real_t *ptr; igraph_bool_t *ptr_nan; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_ASSERT(is_nan != NULL); IGRAPH_ASSERT(is_nan->stor_begin != NULL); IGRAPH_CHECK(igraph_vector_bool_resize(is_nan, igraph_vector_size(v))); for (ptr = v->stor_begin, ptr_nan = is_nan->stor_begin; ptr < v->end; ptr++, ptr_nan++) { *ptr_nan = igraph_is_nan(*ptr) ? 1 : 0; } return IGRAPH_SUCCESS; } /** * \ingroup vector * \function igraph_vector_is_any_nan * \brief Check if any element is NaN. * * * \param v The \type igraph_vector_t object to check. * \return 1 if any element is NaN, 0 otherwise. * * Time complexity: O(n), the number of elements. */ igraph_bool_t igraph_vector_is_any_nan(const igraph_vector_t *v) { igraph_real_t *ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); ptr = v->stor_begin; while (ptr < v->end) { if (igraph_is_nan(*ptr)) { return 1; } ptr++; } return 0; } leidenbase/src/core/core/set.c0000644000176200001440000002107514447675374016005 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" #include "core/set.h" #include /* memmove */ #define SET(s) ((s).stor_begin) /** * \ingroup set * \function igraph_set_init * \brief Initializes a set. * * \param set pointer to the set to be initialized * \param size the expected number of elements in the set * * \return error code: * \c IGRAPH_ENOMEM if there is not enough memory. * * Time complexity: operating system dependent, should be around * O(n), n is the expected size of the set. */ int igraph_set_init(igraph_set_t *set, int long size) { long int alloc_size; if (size < 0) { size = 0; } alloc_size = size > 0 ? size : 1; set->stor_begin = IGRAPH_CALLOC(alloc_size, igraph_integer_t); set->stor_end = set->stor_begin + alloc_size; set->end = set->stor_begin; return 0; } /** * \ingroup set * \function igraph_set_destroy * \brief Destroys a set object. * * \param set pointer to the set to be destroyed * * Time complexity: operating system dependent. */ void igraph_set_destroy(igraph_set_t* set) { IGRAPH_ASSERT(set != 0); if (set->stor_begin != 0) { IGRAPH_FREE(set->stor_begin); set->stor_begin = NULL; } } /** * \ingroup set * \function igraph_set_inited * \brief Determines whether a set is initialized or not. * * This function checks whether the internal storage for the members of the * set has been allocated or not, and it assumes that the pointer for the * internal storage area contains \c NULL if the area is not initialized yet. * This only applies if you have allocated an array of sets with \c IGRAPH_CALLOC or * if you used the \c IGRAPH_SET_NULL constant to initialize the set. * * \param set The set object. * * Time complexity: O(1) */ igraph_bool_t igraph_set_inited(igraph_set_t* set) { return (set->stor_begin != 0); } /** * \ingroup set * \function igraph_set_reserve * \brief Reserve memory for a set. * * \param set The set object. * \param size the new \em allocated size of the set. * * Time complexity: operating system dependent, should be around * O(n), n is the new allocated size of the set. */ int igraph_set_reserve(igraph_set_t* set, long int size) { long int actual_size = igraph_set_size(set); igraph_integer_t *tmp; IGRAPH_ASSERT(set != NULL); IGRAPH_ASSERT(set->stor_begin != NULL); if (size <= actual_size) { return 0; } tmp = IGRAPH_REALLOC(set->stor_begin, (size_t) size, igraph_integer_t); if (tmp == 0) { IGRAPH_ERROR("cannot reserve space for set", IGRAPH_ENOMEM); } set->stor_begin = tmp; set->stor_end = set->stor_begin + size; set->end = set->stor_begin + actual_size; return 0; } /** * \ingroup set * \function igraph_set_empty * \brief Decides whether the size of the set is zero. * * \param set The set object. * \return Non-zero number if the size of the set is not zero and * zero otherwise. * * Time complexity: O(1). */ igraph_bool_t igraph_set_empty(const igraph_set_t* set) { IGRAPH_ASSERT(set != NULL); IGRAPH_ASSERT(set->stor_begin != NULL); return set->stor_begin == set->end; } /** * \ingroup set * \function igraph_set_clear * \brief Removes all elements from a set. * * * This function simply sets the size of the set to zero, it does * not free any allocated memory. For that you have to call * \ref igraph_set_destroy(). * \param v The set object. * * Time complexity: O(1). */ void igraph_set_clear(igraph_set_t* set) { IGRAPH_ASSERT(set != NULL); IGRAPH_ASSERT(set->stor_begin != NULL); set->end = set->stor_begin; } /** * \ingroup set * \function igraph_set_size * \brief Gives the size (=length) of the set. * * \param v The set object * \return The size of the set. * * Time complexity: O(1). */ long int igraph_set_size(const igraph_set_t* set) { IGRAPH_ASSERT(set != NULL); IGRAPH_ASSERT(set->stor_begin != NULL); return set->end - set->stor_begin; } /** * \ingroup set * \function igraph_set_add * \brief Adds an element to the set. * * \param set The set object. * \param e The element to be added. * \return Error code: * \c IGRAPH_ENOMEM: not enough memory. * * Time complexity: O(log(n)), n is the number of elements in \p set. */ int igraph_set_add(igraph_set_t* set, igraph_integer_t e) { long int left, right, middle; long int size; IGRAPH_ASSERT(set != NULL); IGRAPH_ASSERT(set->stor_begin != NULL); size = igraph_set_size(set); /* search where to insert the new element */ left = 0; right = size - 1; while (left < right - 1) { middle = (left + right) / 2; if (SET(*set)[middle] > e) { right = middle; } else if (SET(*set)[middle] < e) { left = middle; } else { left = middle; break; } } if (right >= 0 && SET(*set)[left] != e && SET(*set)[right] == e) { left = right; } while (left < size && set->stor_begin[left] < e) { left++; } if (left >= size || set->stor_begin[left] != e) { /* full, allocate more storage */ if (set->stor_end == set->end) { long int new_size = size * 2; if (new_size == 0) { new_size = 1; } IGRAPH_CHECK(igraph_set_reserve(set, new_size)); } /* Element should be inserted at position 'left' */ if (left < size) memmove(set->stor_begin + left + 1, set->stor_begin + left, (size_t) (size - left)*sizeof(set->stor_begin[0])); set->stor_begin[left] = e; set->end += 1; } return 0; } /** * \ingroup set * \function igraph_set_contains * \brief Checks whether a given element is in the set or not. * * \param set The set object. * \param e The element being sought. * \return Positive integer (true) if \p e is found, zero (false) otherwise. * * Time complexity: O(log(n)), n is the number of elements in \p set. */ igraph_bool_t igraph_set_contains(igraph_set_t* set, igraph_integer_t e) { long int left, right, middle; IGRAPH_ASSERT(set != NULL); IGRAPH_ASSERT(set->stor_begin != NULL); left = 0; right = igraph_set_size(set) - 1; if (right == -1) { return 0; /* the set is empty */ } /* search for the new element */ while (left < right - 1) { middle = (left + right) / 2; if (SET(*set)[middle] > e) { right = middle; } else if (SET(*set)[middle] < e) { left = middle; } else { return 1; } } return SET(*set)[left] == e || SET(*set)[right] == e; } /** * \ingroup set * \function igraph_set_iterate * \brief Iterates through the element to the set. * * Elements are returned in an arbitrary order. * * \param set The set object. * \param state Internal state of the iteration. * This should be a pointer to a \c long variable * which must be zero for the first invocation. * The object should not be adjusted and its value should * not be used for anything during the iteration. * \param element The next element or \c NULL (if the iteration * has ended) is returned here. * * \return Nonzero if there are more elements, zero otherwise. */ igraph_bool_t igraph_set_iterate(igraph_set_t* set, long int* state, igraph_integer_t* element) { IGRAPH_ASSERT(set != 0); IGRAPH_ASSERT(set->stor_begin != 0); IGRAPH_ASSERT(state != 0); IGRAPH_ASSERT(element != 0); if (*state < igraph_set_size(set)) { *element = set->stor_begin[*state]; *state = *state + 1; return 1; } else { *element = 0; return 0; } } leidenbase/src/core/core/stack.pmt0000644000176200001440000001666214447675374016703 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" #include "config.h" #include /* memcpy & co. */ #include /** * \ingroup stack * \function igraph_stack_init * \brief Initializes a stack. * * The initialized stack is always empty. * \param s Pointer to an uninitialized stack. * \param size The number of elements to allocate memory for. * \return Error code. * * Time complexity: O(\p size). */ int FUNCTION(igraph_stack, init) (TYPE(igraph_stack)* s, long int size) { long int alloc_size; IGRAPH_ASSERT(s != NULL); if (size < 0) { size = 0; } alloc_size = size > 0 ? size : 1; s->stor_begin = IGRAPH_CALLOC(alloc_size, BASE); if (s->stor_begin == 0) { IGRAPH_ERROR("stack init failed", IGRAPH_ENOMEM); } s->stor_end = s->stor_begin + alloc_size; s->end = s->stor_begin; return 0; } /** * \ingroup stack * \function igraph_stack_destroy * \brief Destroys a stack object. * * Deallocate the memory used for a stack. * It is possible to reinitialize a destroyed stack again by * \ref igraph_stack_init(). * \param s The stack to destroy. * * Time complexity: O(1). */ void FUNCTION(igraph_stack, destroy) (TYPE(igraph_stack)* s) { IGRAPH_ASSERT(s != NULL); if (s->stor_begin != 0) { IGRAPH_FREE(s->stor_begin); s->stor_begin = NULL; } } /** * \ingroup stack * \function igraph_stack_reserve * \brief Reserve memory. * * Reserve memory for future use. The actual size of the stack is * unchanged. * \param s The stack object. * \param size The number of elements to reserve memory for. If it is * not bigger than the current size then nothing happens. * \return Error code. * * Time complexity: should be around O(n), the new allocated size of * the stack. */ int FUNCTION(igraph_stack, reserve) (TYPE(igraph_stack)* s, long int size) { long int actual_size = FUNCTION(igraph_stack, size)(s); BASE *tmp; IGRAPH_ASSERT(s != NULL); IGRAPH_ASSERT(s->stor_begin != NULL); if (size <= actual_size) { return 0; } tmp = IGRAPH_REALLOC(s->stor_begin, (size_t) size, BASE); if (tmp == 0) { IGRAPH_ERROR("stack reserve failed", IGRAPH_ENOMEM); } s->stor_begin = tmp; s->stor_end = s->stor_begin + size; s->end = s->stor_begin + actual_size; return 0; } /** * \ingroup stack * \function igraph_stack_empty * \brief Decides whether a stack object is empty. * * \param s The stack object. * \return Boolean, \c TRUE if the stack is empty, \c FALSE * otherwise. * * Time complexity: O(1). */ igraph_bool_t FUNCTION(igraph_stack, empty) (TYPE(igraph_stack)* s) { IGRAPH_ASSERT(s != NULL); IGRAPH_ASSERT(s->stor_begin != NULL); IGRAPH_ASSERT(s->end != NULL); return s->stor_begin == s->end; } /** * \ingroup stack * \function igraph_stack_size * \brief Returns the number of elements in a stack. * * \param s The stack object. * \return The number of elements in the stack. * * Time complexity: O(1). */ long int FUNCTION(igraph_stack, size) (const TYPE(igraph_stack)* s) { IGRAPH_ASSERT(s != NULL); IGRAPH_ASSERT(s->stor_begin != NULL); return s->end - s->stor_begin; } /** * \ingroup stack * \function igraph_stack_clear * \brief Removes all elements from a stack. * * \param s The stack object. * * Time complexity: O(1). */ void FUNCTION(igraph_stack, clear) (TYPE(igraph_stack)* s) { IGRAPH_ASSERT(s != NULL); IGRAPH_ASSERT(s->stor_begin != NULL); s->end = s->stor_begin; } /** * \ingroup stack * \function igraph_stack_push * \brief Places an element on the top of a stack. * * The capacity of the stack is increased, if needed. * \param s The stack object. * \param elem The element to push. * \return Error code. * * Time complexity: O(1) is no reallocation is needed, O(n) * otherwise, but it is ensured that n push operations are performed * in O(n) time. */ int FUNCTION(igraph_stack, push)(TYPE(igraph_stack)* s, BASE elem) { IGRAPH_ASSERT(s != NULL); IGRAPH_ASSERT(s->stor_begin != NULL); if (s->end == s->stor_end) { /* full, allocate more storage */ BASE *bigger = NULL, *old = s->stor_begin; bigger = IGRAPH_CALLOC(2 * FUNCTION(igraph_stack, size)(s), BASE); if (bigger == 0) { IGRAPH_ERROR("stack push failed", IGRAPH_ENOMEM); } memcpy(bigger, s->stor_begin, (size_t) FUNCTION(igraph_stack, size)(s)*sizeof(BASE)); s->end = bigger + (s->stor_end - s->stor_begin); s->stor_end = bigger + 2 * (s->stor_end - s->stor_begin); s->stor_begin = bigger; *(s->end) = elem; (s->end) += 1; IGRAPH_FREE(old); } else { *(s->end) = elem; (s->end) += 1; } return 0; } /** * \ingroup stack * \function igraph_stack_pop * \brief Removes and returns an element from the top of a stack. * * The stack must contain at least one element, call \ref * igraph_stack_empty() to make sure of this. * \param s The stack object. * \return The removed top element. * * Time complexity: O(1). */ BASE FUNCTION(igraph_stack, pop) (TYPE(igraph_stack)* s) { IGRAPH_ASSERT(s != NULL); IGRAPH_ASSERT(s->stor_begin != NULL); IGRAPH_ASSERT(s->end != NULL); IGRAPH_ASSERT(s->end != s->stor_begin); (s->end)--; return *(s->end); } /** * \ingroup stack * \function igraph_stack_top * \brief Query top element. * * Returns the top element of the stack, without removing it. * The stack must be non-empty. * \param s The stack. * \return The top element. * * Time complexity: O(1). */ BASE FUNCTION(igraph_stack, top) (const TYPE(igraph_stack)* s) { IGRAPH_ASSERT(s != NULL); IGRAPH_ASSERT(s->stor_begin != NULL); IGRAPH_ASSERT(s->end != NULL); IGRAPH_ASSERT(s->end != s->stor_begin); return *(s->end - 1); } #if defined (OUT_FORMAT) #ifndef USING_R int FUNCTION(igraph_stack, print)(const TYPE(igraph_stack) *s) { long int i, n = FUNCTION(igraph_stack, size)(s); if (n != 0) { printf(OUT_FORMAT, s->stor_begin[0]); } for (i = 1; i < n; i++) { printf(" " OUT_FORMAT, s->stor_begin[i]); } printf("\n"); return 0; } #endif int FUNCTION(igraph_stack, fprint)(const TYPE(igraph_stack) *s, FILE *file) { long int i, n = FUNCTION(igraph_stack, size)(s); if (n != 0) { fprintf(file, OUT_FORMAT, s->stor_begin[0]); } for (i = 1; i < n; i++) { fprintf(file, " " OUT_FORMAT, s->stor_begin[i]); } fprintf(file, "\n"); return 0; } #endif leidenbase/src/core/core/marked_queue.c0000644000176200001440000000651314447675374017661 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "core/marked_queue.h" #define BATCH_MARKER -1 int igraph_marked_queue_init(igraph_marked_queue_t *q, long int size) { IGRAPH_CHECK(igraph_dqueue_init(&q->Q, 0)); IGRAPH_FINALLY(igraph_dqueue_destroy, &q->Q); IGRAPH_CHECK(igraph_vector_long_init(&q->set, size)); q->mark = 1; q->size = 0; IGRAPH_FINALLY_CLEAN(1); return 0; } void igraph_marked_queue_destroy(igraph_marked_queue_t *q) { igraph_vector_long_destroy(&q->set); igraph_dqueue_destroy(&q->Q); } void igraph_marked_queue_reset(igraph_marked_queue_t *q) { igraph_dqueue_clear(&q->Q); q->size = 0; q->mark += 1; if (q->mark == 0) { igraph_vector_long_null(&q->set); q->mark += 1; } } igraph_bool_t igraph_marked_queue_empty(const igraph_marked_queue_t *q) { return q->size == 0; } long int igraph_marked_queue_size(const igraph_marked_queue_t *q) { return q->size; } igraph_bool_t igraph_marked_queue_iselement(const igraph_marked_queue_t *q, long int elem) { return (VECTOR(q->set)[elem] == q->mark); } int igraph_marked_queue_push(igraph_marked_queue_t *q, long int elem) { if (VECTOR(q->set)[elem] != q->mark) { IGRAPH_CHECK(igraph_dqueue_push(&q->Q, elem)); VECTOR(q->set)[elem] = q->mark; q->size += 1; } return 0; } int igraph_marked_queue_start_batch(igraph_marked_queue_t *q) { IGRAPH_CHECK(igraph_dqueue_push(&q->Q, BATCH_MARKER)); return 0; } void igraph_marked_queue_pop_back_batch(igraph_marked_queue_t *q) { long int size = igraph_dqueue_size(&q->Q); long int elem; while (size > 0 && (elem = (long int) igraph_dqueue_pop_back(&q->Q)) != BATCH_MARKER) { VECTOR(q->set)[elem] = 0; size--; q->size--; } } #ifndef USING_R int igraph_marked_queue_print(const igraph_marked_queue_t *q) { IGRAPH_CHECK(igraph_dqueue_print(&q->Q)); return 0; } #endif int igraph_marked_queue_fprint(const igraph_marked_queue_t *q, FILE *file) { IGRAPH_CHECK(igraph_dqueue_fprint(&q->Q, file)); return 0; } int igraph_marked_queue_as_vector(const igraph_marked_queue_t *q, igraph_vector_t *vec) { long int i, p, n = igraph_dqueue_size(&q->Q); IGRAPH_CHECK(igraph_vector_resize(vec, q->size)); for (i = 0, p = 0; i < n; i++) { igraph_real_t e = igraph_dqueue_e(&q->Q, i); if (e != BATCH_MARKER) { VECTOR(*vec)[p++] = e; } } return 0; } leidenbase/src/core/core/trie.c0000644000176200001440000003004514447675374016152 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_random.h" #include "igraph_error.h" #include "core/trie.h" #include "config.h" #include /** * \ingroup igraphtrie * \brief Creates a trie node (not to be called directly) * \return Error code: errors by igraph_strvector_init(), * igraph_vector_ptr_init() and igraph_vector_init() might be returned. */ static int igraph_i_trie_init_node(igraph_trie_node_t *t) { IGRAPH_STRVECTOR_INIT_FINALLY(&t->strs, 0); IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 0); IGRAPH_VECTOR_INIT_FINALLY(&t->values, 0); IGRAPH_FINALLY_CLEAN(3); return 0; } static void igraph_i_trie_destroy_node(igraph_trie_node_t *t); /** * \ingroup igraphtrie * \brief Creates a trie. * \return Error code: errors by igraph_strvector_init(), * igraph_vector_ptr_init() and igraph_vector_init() might be returned. */ int igraph_trie_init(igraph_trie_t *t, igraph_bool_t storekeys) { t->maxvalue = -1; t->storekeys = storekeys; IGRAPH_CHECK(igraph_i_trie_init_node( (igraph_trie_node_t *) t )); IGRAPH_FINALLY(igraph_i_trie_destroy_node, (igraph_trie_node_t *) t ); if (storekeys) { IGRAPH_CHECK(igraph_strvector_init(&t->keys, 0)); } IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup igraphtrie * \brief Destroys a node of a trie (not to be called directly). */ static void igraph_i_trie_destroy_node_helper(igraph_trie_node_t *t, igraph_bool_t sfree) { long int i; igraph_strvector_destroy(&t->strs); for (i = 0; i < igraph_vector_ptr_size(&t->children); i++) { igraph_trie_node_t *child = VECTOR(t->children)[i]; if (child != 0) { igraph_i_trie_destroy_node_helper(child, 1); } } igraph_vector_ptr_destroy(&t->children); igraph_vector_destroy(&t->values); if (sfree) { IGRAPH_FREE(t); } } static void igraph_i_trie_destroy_node(igraph_trie_node_t *t) { igraph_i_trie_destroy_node_helper(t, 0); } /** * \ingroup igraphtrie * \brief Destroys a trie (frees allocated memory). */ void igraph_trie_destroy(igraph_trie_t *t) { if (t->storekeys) { igraph_strvector_destroy(&t->keys); } igraph_i_trie_destroy_node( (igraph_trie_node_t*) t); } /** * \ingroup igraphtrie * \brief Internal helping function for igraph_trie_t */ static long int igraph_i_strdiff(const char *str, const char *key) { long int diff = 0; while (key[diff] != '\0' && str[diff] != '\0' && str[diff] == key[diff]) { diff++; } return diff; } /** * \ingroup igraphtrie * \brief Search/insert in a trie (not to be called directly). * * @return Error code: * - IGRAPH_ENOMEM: out of memory */ int igraph_trie_get_node(igraph_trie_node_t *t, const char *key, igraph_real_t newvalue, long int *id) { char *str; long int i; igraph_bool_t add; /* If newvalue is negative, we don't add the node if nonexistent, only check * for its existence */ add = (newvalue >= 0); for (i = 0; i < igraph_strvector_size(&t->strs); i++) { long int diff; igraph_strvector_get(&t->strs, i, &str); diff = igraph_i_strdiff(str, key); if (diff == 0) { /* ------------------------------------ */ /* No match, next */ } else if (str[diff] == '\0' && key[diff] == '\0') { /* ------------------------------------ */ /* They are exactly the same */ if (VECTOR(t->values)[i] != -1) { *id = (long int) VECTOR(t->values)[i]; return 0; } else { VECTOR(t->values)[i] = newvalue; *id = (long int) newvalue; return 0; } } else if (str[diff] == '\0') { /* ------------------------------------ */ /* str is prefix of key, follow its link if there is one */ igraph_trie_node_t *node = VECTOR(t->children)[i]; if (node != 0) { return igraph_trie_get_node(node, key + diff, newvalue, id); } else if (add) { igraph_trie_node_t *node = IGRAPH_CALLOC(1, igraph_trie_node_t); if (node == 0) { IGRAPH_ERROR("cannot add to trie", IGRAPH_ENOMEM); } IGRAPH_STRVECTOR_INIT_FINALLY(&node->strs, 1); IGRAPH_VECTOR_PTR_INIT_FINALLY(&node->children, 1); IGRAPH_VECTOR_INIT_FINALLY(&node->values, 1); IGRAPH_CHECK(igraph_strvector_set(&node->strs, 0, key + diff)); VECTOR(node->children)[0] = 0; VECTOR(node->values)[0] = newvalue; VECTOR(t->children)[i] = node; *id = (long int) newvalue; IGRAPH_FINALLY_CLEAN(3); return 0; } else { *id = -1; return 0; } } else if (key[diff] == '\0' && add) { /* ------------------------------------ */ /* key is prefix of str, the node has to be cut */ char *str2; igraph_trie_node_t *node = IGRAPH_CALLOC(1, igraph_trie_node_t); if (node == 0) { IGRAPH_ERROR("cannot add to trie", IGRAPH_ENOMEM); } IGRAPH_STRVECTOR_INIT_FINALLY(&node->strs, 1); IGRAPH_VECTOR_PTR_INIT_FINALLY(&node->children, 1); IGRAPH_VECTOR_INIT_FINALLY(&node->values, 1); IGRAPH_CHECK(igraph_strvector_set(&node->strs, 0, str + diff)); VECTOR(node->children)[0] = VECTOR(t->children)[i]; VECTOR(node->values)[0] = VECTOR(t->values)[i]; str2 = strdup(str); if (str2 == 0) { IGRAPH_ERROR("cannot add to trie", IGRAPH_ENOMEM); } str2[diff] = '\0'; IGRAPH_FINALLY(igraph_free, str2); IGRAPH_CHECK(igraph_strvector_set(&t->strs, i, str2)); IGRAPH_FREE(str2); IGRAPH_FINALLY_CLEAN(4); VECTOR(t->values)[i] = newvalue; VECTOR(t->children)[i] = node; *id = (long int) newvalue; return 0; } else if (add) { /* ------------------------------------ */ /* the first diff characters match */ char *str2; igraph_trie_node_t *node = IGRAPH_CALLOC(1, igraph_trie_node_t); if (node == 0) { IGRAPH_ERROR("cannot add to trie", IGRAPH_ENOMEM); } IGRAPH_STRVECTOR_INIT_FINALLY(&node->strs, 2); IGRAPH_VECTOR_PTR_INIT_FINALLY(&node->children, 2); IGRAPH_VECTOR_INIT_FINALLY(&node->values, 2); IGRAPH_CHECK(igraph_strvector_set(&node->strs, 0, str + diff)); IGRAPH_CHECK(igraph_strvector_set(&node->strs, 1, key + diff)); VECTOR(node->children)[0] = VECTOR(t->children)[i]; VECTOR(node->children)[1] = 0; VECTOR(node->values)[0] = VECTOR(t->values)[i]; VECTOR(node->values)[1] = newvalue; str2 = strdup(str); if (str2 == 0) { IGRAPH_ERROR("cannot add to trie", IGRAPH_ENOMEM); } str2[diff] = '\0'; IGRAPH_FINALLY(igraph_free, str2); IGRAPH_CHECK(igraph_strvector_set(&t->strs, i, str2)); IGRAPH_FREE(str2); IGRAPH_FINALLY_CLEAN(4); VECTOR(t->values)[i] = -1; VECTOR(t->children)[i] = node; *id = (long int) newvalue; return 0; } else { /* ------------------------------------------------- */ /* No match, but we requested not to add the new key */ *id = -1; return 0; } } /* ------------------------------------ */ /* Nothing matches */ if (add) { IGRAPH_CHECK(igraph_vector_ptr_reserve(&t->children, igraph_vector_ptr_size(&t->children) + 1)); IGRAPH_CHECK(igraph_vector_reserve(&t->values, igraph_vector_size(&t->values) + 1)); IGRAPH_CHECK(igraph_strvector_add(&t->strs, key)); igraph_vector_ptr_push_back(&t->children, 0); /* allocated */ igraph_vector_push_back(&t->values, newvalue); /* allocated */ *id = (long int) newvalue; } else { *id = -1; } return 0; } /** * \ingroup igraphtrie * \brief Search/insert in a trie. */ int igraph_trie_get(igraph_trie_t *t, const char *key, long int *id) { if (!t->storekeys) { IGRAPH_CHECK(igraph_trie_get_node( (igraph_trie_node_t*) t, key, t->maxvalue + 1, id)); if (*id > t->maxvalue) { t->maxvalue = *id; } return 0; } else { int ret; igraph_error_handler_t *oldhandler; oldhandler = igraph_set_error_handler(igraph_error_handler_ignore); /* Add it to the string vector first, we can undo this later */ ret = igraph_strvector_add(&t->keys, key); if (ret != 0) { igraph_set_error_handler(oldhandler); IGRAPH_ERROR("cannot get element from trie", ret); } ret = igraph_trie_get_node( (igraph_trie_node_t*) t, key, t->maxvalue + 1, id); if (ret != 0) { igraph_strvector_resize(&t->keys, igraph_strvector_size(&t->keys) - 1); igraph_set_error_handler(oldhandler); IGRAPH_ERROR("cannot get element from trie", ret); } /* everything is fine */ if (*id > t->maxvalue) { t->maxvalue = *id; } else { igraph_strvector_resize(&t->keys, igraph_strvector_size(&t->keys) - 1); } igraph_set_error_handler(oldhandler); } return 0; } /** * \ingroup igraphtrie * \brief Search/insert in a trie (for internal use). * * @return Error code: * - IGRAPH_ENOMEM: out of memory */ int igraph_trie_get2(igraph_trie_t *t, const char *key, long int length, long int *id) { char *tmp = IGRAPH_CALLOC(length + 1, char); if (tmp == 0) { IGRAPH_ERROR("Cannot get from trie", IGRAPH_ENOMEM); } strncpy(tmp, key, length); tmp[length] = '\0'; IGRAPH_FINALLY(igraph_free, tmp); IGRAPH_CHECK(igraph_trie_get(t, tmp, id)); IGRAPH_FREE(tmp); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup igraphtrie * \brief Search in a trie. * This variant does not add \c key to the trie if it does not exist. * In this case, a negative id is returned. */ int igraph_trie_check(igraph_trie_t *t, const char *key, long int *id) { IGRAPH_CHECK(igraph_trie_get_node( (igraph_trie_node_t*) t, key, -1, id)); return 0; } /** * \ingroup igraphtrie * \brief Get an element of a trie based on its index. */ void igraph_trie_idx(igraph_trie_t *t, long int idx, char **str) { igraph_strvector_get(&t->keys, idx, str); } /** * \ingroup igraphtrie * \brief Returns the size of a trie. */ long int igraph_trie_size(igraph_trie_t *t) { return t->maxvalue + 1; } /* Hmmm, very dirty.... */ int igraph_trie_getkeys(igraph_trie_t *t, const igraph_strvector_t **strv) { *strv = &t->keys; return 0; } leidenbase/src/core/core/math.h0000644000176200001440000000447114447675374016151 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2008-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_MATH_H #define IGRAPH_MATH_H #include "igraph_decls.h" #include "config.h" #include #include __BEGIN_DECLS /** * \def IGRAPH_SHORTEST_PATH_EPSILON * * Relative error threshold used in weighted shortest path calculations * to decide whether two shortest paths are of equal length. */ #define IGRAPH_SHORTEST_PATH_EPSILON 1e-10 /* * Compiler-related hacks, mostly because of Microsoft Visual C++ */ double igraph_i_round(double X); int igraph_i_snprintf(char *buffer, size_t count, const char *format, ...); double igraph_log2(const double a); double igraph_log1p(double a); double igraph_fmin(double a, double b); #ifndef HAVE_LOG2 #define log2(a) igraph_log2(a) #endif #ifndef HAVE_LOG1P #define log1p(a) igraph_log1p(a) #endif #ifndef HAVE_FMIN #define fmin(a,b) igraph_fmin((a),(b)) #endif #ifndef HAVE_ROUND #define round igraph_i_round #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923 #endif #ifndef M_LN2 #define M_LN2 0.69314718055994530942 #endif #ifndef M_SQRT2 #define M_SQRT2 1.4142135623730950488016887 #endif #ifndef M_LN_SQRT_2PI #define M_LN_SQRT_2PI 0.918938533204672741780329736406 /* log(sqrt(2*pi)) == log(2*pi)/2 */ #endif IGRAPH_PRIVATE_EXPORT int igraph_almost_equals(double a, double b, double eps); IGRAPH_PRIVATE_EXPORT int igraph_cmp_epsilon(double a, double b, double eps); __END_DECLS #endif leidenbase/src/core/core/trie.h0000644000176200001440000000471514447675374016164 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_CORE_TRIE_H #define IGRAPH_CORE_TRIE_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_strvector.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS /** * Trie data type * \ingroup internal */ typedef struct s_igraph_trie_node { igraph_strvector_t strs; igraph_vector_ptr_t children; igraph_vector_t values; } igraph_trie_node_t; typedef struct s_igraph_trie { igraph_strvector_t strs; igraph_vector_ptr_t children; igraph_vector_t values; long int maxvalue; igraph_bool_t storekeys; igraph_strvector_t keys; } igraph_trie_t; #define IGRAPH_TRIE_NULL { IGRAPH_STRVECTOR_NULL, IGRAPH_VECTOR_PTR_NULL, \ IGRAPH_VECTOR_NULL, 0, 0, IGRAPH_STRVECTOR_NULL } #define IGRAPH_TRIE_INIT_FINALLY(tr, sk) \ do { IGRAPH_CHECK(igraph_trie_init(tr, sk)); \ IGRAPH_FINALLY(igraph_trie_destroy, tr); } while (0) IGRAPH_PRIVATE_EXPORT int igraph_trie_init(igraph_trie_t *t, igraph_bool_t storekeys); IGRAPH_PRIVATE_EXPORT void igraph_trie_destroy(igraph_trie_t *t); IGRAPH_PRIVATE_EXPORT int igraph_trie_get(igraph_trie_t *t, const char *key, long int *id); IGRAPH_PRIVATE_EXPORT int igraph_trie_check(igraph_trie_t *t, const char *key, long int *id); IGRAPH_PRIVATE_EXPORT int igraph_trie_get2(igraph_trie_t *t, const char *key, long int length, long int *id); IGRAPH_PRIVATE_EXPORT void igraph_trie_idx(igraph_trie_t *t, long int idx, char **str); IGRAPH_PRIVATE_EXPORT int igraph_trie_getkeys(igraph_trie_t *t, const igraph_strvector_t **strv); IGRAPH_PRIVATE_EXPORT long int igraph_trie_size(igraph_trie_t *t); __END_DECLS #endif leidenbase/src/core/core/array.c0000644000176200001440000000260114447675374016322 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_array.h" #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "array.pmt" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_LONG #include "igraph_pmt.h" #include "array.pmt" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_CHAR #include "igraph_pmt.h" #include "array.pmt" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "array.pmt" #include "igraph_pmt_off.h" #undef BASE_BOOL leidenbase/src/core/core/heap.pmt0000644000176200001440000002346214447675374016507 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_memory.h" #include "igraph_error.h" #include "config.h" #include /* memcpy & co. */ #include #define PARENT(x) (((x)+1)/2-1) #define LEFTCHILD(x) (((x)+1)*2-1) #define RIGHTCHILD(x) (((x)+1)*2) /* Declare internal functions */ static void FUNCTION(igraph_heap, i_build)(BASE* arr, long int size, long int head); static void FUNCTION(igraph_heap, i_shift_up)(BASE* arr, long int size, long int elem); static void FUNCTION(igraph_heap, i_sink)(BASE* arr, long int size, long int head); static void FUNCTION(igraph_heap, i_switch)(BASE* arr, long int e1, long int e2); /** * \ingroup heap * \function igraph_heap_init * \brief Initializes an empty heap object. * * Creates an empty heap, but allocates size for some elements. * \param h Pointer to an uninitialized heap object. * \param alloc_size Number of elements to allocate memory for. * \return Error code. * * Time complexity: O(\p alloc_size), assuming memory allocation is a * linear operation. */ int FUNCTION(igraph_heap, init)(TYPE(igraph_heap)* h, long int alloc_size) { if (alloc_size <= 0 ) { alloc_size = 1; } h->stor_begin = IGRAPH_CALLOC(alloc_size, BASE); if (h->stor_begin == 0) { IGRAPH_ERROR("heap init failed", IGRAPH_ENOMEM); } h->stor_end = h->stor_begin + alloc_size; h->end = h->stor_begin; h->destroy = 1; return 0; } /** * \ingroup heap * \function igraph_heap_init_array * \brief Build a heap from an array. * * Initializes a heap object from an array, the heap is also * built of course (constructor). * \param h Pointer to an uninitialized heap object. * \param data Pointer to an array of base data type. * \param len The length of the array at \p data. * \return Error code. * * Time complexity: O(n), the number of elements in the heap. */ int FUNCTION(igraph_heap, init_array)(TYPE(igraph_heap) *h, BASE* data, long int len) { h->stor_begin = IGRAPH_CALLOC(len, BASE); if (h->stor_begin == 0) { IGRAPH_ERROR("heap init from array failed", IGRAPH_ENOMEM); } h->stor_end = h->stor_begin + len; h->end = h->stor_end; h->destroy = 1; memcpy(h->stor_begin, data, (size_t) len * sizeof(igraph_real_t)); FUNCTION(igraph_heap, i_build) (h->stor_begin, h->end - h->stor_begin, 0); return 0; } /** * \ingroup heap * \function igraph_heap_destroy * \brief Destroys an initialized heap object. * * \param h The heap object. * * Time complexity: O(1). */ void FUNCTION(igraph_heap, destroy)(TYPE(igraph_heap)* h) { if (h->destroy) { if (h->stor_begin != 0) { IGRAPH_FREE(h->stor_begin); h->stor_begin = 0; } } } /** * \ingroup heap * \function igraph_heap_empty * \brief Decides whether a heap object is empty. * * \param h The heap object. * \return \c TRUE if the heap is empty, \c FALSE otherwise. * * TIme complexity: O(1). */ igraph_bool_t FUNCTION(igraph_heap, empty)(TYPE(igraph_heap)* h) { IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); return h->stor_begin == h->end; } /** * \ingroup heap * \function igraph_heap_push * \brief Add an element. * * Adds an element to the heap. * \param h The heap object. * \param elem The element to add. * \return Error code. * * Time complexity: O(log n), n is the number of elements in the * heap if no reallocation is needed, O(n) otherwise. It is ensured * that n push operations are performed in O(n log n) time. */ int FUNCTION(igraph_heap, push)(TYPE(igraph_heap)* h, BASE elem) { IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); /* full, allocate more storage */ if (h->stor_end == h->end) { long int new_size = FUNCTION(igraph_heap, size)(h) * 2; if (new_size == 0) { new_size = 1; } IGRAPH_CHECK(FUNCTION(igraph_heap, reserve)(h, new_size)); } *(h->end) = elem; h->end += 1; /* maintain heap */ FUNCTION(igraph_heap, i_shift_up)(h->stor_begin, FUNCTION(igraph_heap, size)(h), FUNCTION(igraph_heap, size)(h) - 1); return 0; } /** * \ingroup heap * \function igraph_heap_top * \brief Top element. * * For maximum heaps this is the largest, for minimum heaps the * smallest element of the heap. * \param h The heap object. * \return The top element. * * Time complexity: O(1). */ BASE FUNCTION(igraph_heap, top)(TYPE(igraph_heap)* h) { IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); IGRAPH_ASSERT(h->stor_begin != h->end); return h->stor_begin[0]; } /** * \ingroup heap * \function igraph_heap_delete_top * \brief Return and removes the top element * * Removes and returns the top element of the heap. For maximum heaps * this is the largest, for minimum heaps the smallest element. * \param h The heap object. * \return The top element. * * Time complexity: O(log n), n is the number of elements in the * heap. */ BASE FUNCTION(igraph_heap, delete_top)(TYPE(igraph_heap)* h) { BASE tmp; IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); tmp = h->stor_begin[0]; FUNCTION(igraph_heap, i_switch)(h->stor_begin, 0, FUNCTION(igraph_heap, size)(h) - 1); h->end -= 1; FUNCTION(igraph_heap, i_sink)(h->stor_begin, h->end - h->stor_begin, 0); return tmp; } /** * \ingroup heap * \function igraph_heap_size * \brief Number of elements * * Gives the number of elements in a heap. * \param h The heap object. * \return The number of elements in the heap. * * Time complexity: O(1). */ long int FUNCTION(igraph_heap, size)(TYPE(igraph_heap)* h) { IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); return h->end - h->stor_begin; } /** * \ingroup heap * \function igraph_heap_reserve * \brief Allocate more memory * * Allocates memory for future use. The size of the heap is * unchanged. If the heap is larger than the \p size parameter then * nothing happens. * \param h The heap object. * \param size The number of elements to allocate memory for. * \return Error code. * * Time complexity: O(\p size) if \p size is larger than the current * number of elements. O(1) otherwise. */ int FUNCTION(igraph_heap, reserve)(TYPE(igraph_heap)* h, long int size) { long int actual_size = FUNCTION(igraph_heap, size)(h); BASE *tmp; IGRAPH_ASSERT(h != NULL); IGRAPH_ASSERT(h->stor_begin != NULL); if (size <= actual_size) { return 0; } tmp = IGRAPH_REALLOC(h->stor_begin, (size_t) size, BASE); if (tmp == 0) { IGRAPH_ERROR("heap reserve failed", IGRAPH_ENOMEM); } h->stor_begin = tmp; h->stor_end = h->stor_begin + size; h->end = h->stor_begin + actual_size; return 0; } /** * \ingroup heap * \brief Build a heap, this should not be called directly. */ void FUNCTION(igraph_heap, i_build)(BASE* arr, long int size, long int head) { if (RIGHTCHILD(head) < size) { /* both subtrees */ FUNCTION(igraph_heap, i_build)(arr, size, LEFTCHILD(head) ); FUNCTION(igraph_heap, i_build)(arr, size, RIGHTCHILD(head)); FUNCTION(igraph_heap, i_sink)(arr, size, head); } else if (LEFTCHILD(head) < size) { /* only left */ FUNCTION(igraph_heap, i_build)(arr, size, LEFTCHILD(head)); FUNCTION(igraph_heap, i_sink)(arr, size, head); } else { /* none */ } } /** * \ingroup heap * \brief Shift an element upwards in a heap, this should not be * called directly. */ void FUNCTION(igraph_heap, i_shift_up)(BASE* arr, long int size, long int elem) { if (elem == 0 || arr[elem] HEAPLESS arr[PARENT(elem)]) { /* at the top */ } else { FUNCTION(igraph_heap, i_switch)(arr, elem, PARENT(elem)); FUNCTION(igraph_heap, i_shift_up)(arr, size, PARENT(elem)); } } /** * \ingroup heap * \brief Moves an element down in a heap, this function should not be * called directly. */ void FUNCTION(igraph_heap, i_sink)(BASE* arr, long int size, long int head) { if (LEFTCHILD(head) >= size) { /* no subtrees */ } else if (RIGHTCHILD(head) == size || arr[LEFTCHILD(head)] HEAPMOREEQ arr[RIGHTCHILD(head)]) { /* sink to the left if needed */ if (arr[head] HEAPLESS arr[LEFTCHILD(head)]) { FUNCTION(igraph_heap, i_switch)(arr, head, LEFTCHILD(head)); FUNCTION(igraph_heap, i_sink)(arr, size, LEFTCHILD(head)); } } else { /* sink to the right */ if (arr[head] HEAPLESS arr[RIGHTCHILD(head)]) { FUNCTION(igraph_heap, i_switch)(arr, head, RIGHTCHILD(head)); FUNCTION(igraph_heap, i_sink)(arr, size, RIGHTCHILD(head)); } } } /** * \ingroup heap * \brief Switches two elements in a heap, this function should not be * called directly. */ void FUNCTION(igraph_heap, i_switch)(BASE* arr, long int e1, long int e2) { if (e1 != e2) { BASE tmp = arr[e1]; arr[e1] = arr[e2]; arr[e2] = tmp; } } leidenbase/src/core/core/cutheap.c0000644000176200001440000001321314447675374016636 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "core/cutheap.h" #define PARENT(x) ((x)/2) #define LEFTCHILD(x) ((x)*2+1) #define RIGHTCHILD(x) ((x)*2) #define INACTIVE IGRAPH_INFINITY #define UNDEFINED 0.0 #define INDEXINC 1 static void igraph_i_cutheap_switch(igraph_i_cutheap_t *ch, long int hidx1, long int hidx2) { if (hidx1 != hidx2) { long int idx1 = (long int) VECTOR(ch->index)[hidx1]; long int idx2 = (long int) VECTOR(ch->index)[hidx2]; igraph_real_t tmp = VECTOR(ch->heap)[hidx1]; VECTOR(ch->heap)[hidx1] = VECTOR(ch->heap)[hidx2]; VECTOR(ch->heap)[hidx2] = tmp; VECTOR(ch->index)[hidx1] = idx2; VECTOR(ch->index)[hidx2] = idx1; VECTOR(ch->hptr)[idx1] = hidx2 + INDEXINC; VECTOR(ch->hptr)[idx2] = hidx1 + INDEXINC; } } static void igraph_i_cutheap_sink(igraph_i_cutheap_t *ch, long int hidx) { long int size = igraph_vector_size(&ch->heap); if (LEFTCHILD(hidx) >= size) { /* leaf node */ } else if (RIGHTCHILD(hidx) == size || VECTOR(ch->heap)[LEFTCHILD(hidx)] >= VECTOR(ch->heap)[RIGHTCHILD(hidx)]) { /* sink to the left if needed */ if (VECTOR(ch->heap)[hidx] < VECTOR(ch->heap)[LEFTCHILD(hidx)]) { igraph_i_cutheap_switch(ch, hidx, LEFTCHILD(hidx)); igraph_i_cutheap_sink(ch, LEFTCHILD(hidx)); } } else { /* sink to the right */ if (VECTOR(ch->heap)[hidx] < VECTOR(ch->heap)[RIGHTCHILD(hidx)]) { igraph_i_cutheap_switch(ch, hidx, RIGHTCHILD(hidx)); igraph_i_cutheap_sink(ch, RIGHTCHILD(hidx)); } } } static void igraph_i_cutheap_shift_up(igraph_i_cutheap_t *ch, long int hidx) { if (hidx == 0 || VECTOR(ch->heap)[hidx] < VECTOR(ch->heap)[PARENT(hidx)]) { /* at the top */ } else { igraph_i_cutheap_switch(ch, hidx, PARENT(hidx)); igraph_i_cutheap_shift_up(ch, PARENT(hidx)); } } int igraph_i_cutheap_init(igraph_i_cutheap_t *ch, igraph_integer_t nodes) { ch->dnodes = nodes; IGRAPH_VECTOR_INIT_FINALLY(&ch->heap, nodes); /* all zero */ IGRAPH_CHECK(igraph_vector_init_seq(&ch->index, 0, nodes - 1)); IGRAPH_FINALLY(igraph_vector_destroy, &ch->index); IGRAPH_CHECK(igraph_vector_init_seq(&ch->hptr, INDEXINC, nodes + INDEXINC - 1)); IGRAPH_FINALLY_CLEAN(2); return 0; } void igraph_i_cutheap_destroy(igraph_i_cutheap_t *ch) { igraph_vector_destroy(&ch->hptr); igraph_vector_destroy(&ch->index); igraph_vector_destroy(&ch->heap); } igraph_bool_t igraph_i_cutheap_empty(igraph_i_cutheap_t *ch) { return igraph_vector_empty(&ch->heap); } /* Number of active vertices */ igraph_integer_t igraph_i_cutheap_active_size(igraph_i_cutheap_t *ch) { return (igraph_integer_t) igraph_vector_size(&ch->heap); } /* Number of all (defined) vertices */ igraph_integer_t igraph_i_cutheap_size(igraph_i_cutheap_t *ch) { return (igraph_integer_t) (ch->dnodes); } igraph_real_t igraph_i_cutheap_maxvalue(igraph_i_cutheap_t *ch) { return VECTOR(ch->heap)[0]; } igraph_integer_t igraph_i_cutheap_popmax(igraph_i_cutheap_t *ch) { long int size = igraph_vector_size(&ch->heap); igraph_integer_t maxindex = (igraph_integer_t) VECTOR(ch->index)[0]; /* put the last element to the top */ igraph_i_cutheap_switch(ch, 0, size - 1); /* remove the last element */ VECTOR(ch->hptr)[(long int) igraph_vector_tail(&ch->index)] = INACTIVE; igraph_vector_pop_back(&ch->heap); igraph_vector_pop_back(&ch->index); igraph_i_cutheap_sink(ch, 0); return maxindex; } /* Update the value of an active vertex, if not active it will be ignored */ int igraph_i_cutheap_update(igraph_i_cutheap_t *ch, igraph_integer_t index, igraph_real_t add) { igraph_real_t hidx = VECTOR(ch->hptr)[(long int)index]; if (hidx != INACTIVE && hidx != UNDEFINED) { long int hidx2 = (long int) (hidx - INDEXINC); /* printf("updating vertex %li, heap index %li\n", (long int) index, hidx2); */ VECTOR(ch->heap)[hidx2] += add; igraph_i_cutheap_sink(ch, hidx2); igraph_i_cutheap_shift_up(ch, hidx2); } return 0; } /* Reset the value of all vertices to zero and make them active */ int igraph_i_cutheap_reset_undefine(igraph_i_cutheap_t *ch, long int vertex) { long int i, j, n = igraph_vector_size(&ch->hptr); /* undefine */ VECTOR(ch->hptr)[vertex] = UNDEFINED; ch->dnodes -= 1; IGRAPH_CHECK(igraph_vector_resize(&ch->heap, ch->dnodes)); igraph_vector_null(&ch->heap); IGRAPH_CHECK(igraph_vector_resize(&ch->index, ch->dnodes)); j = 0; for (i = 0; i < n; i++) { if (VECTOR(ch->hptr)[i] != UNDEFINED) { VECTOR(ch->index)[j] = i; VECTOR(ch->hptr)[i] = j + INDEXINC; j++; } } return 0; } leidenbase/src/core/core/grid.c0000644000176200001440000002520114447675374016132 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph R package. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "core/grid.h" #include /* internal function */ int igraph_2dgrid_which(igraph_2dgrid_t *grid, igraph_real_t xc, igraph_real_t yc, long int *x, long int *y) { if (xc <= grid->minx) { *x = 0; } else if (xc >= grid->maxx) { *x = grid->stepsx - 1; } else { *x = (long int) floor((xc - (grid->minx)) / (grid->deltax)); } if (yc <= grid->miny) { *y = 0; } else if (yc >= grid->maxy) { *y = grid->stepsy - 1; } else { *y = (long int) floor((yc - (grid->miny)) / (grid->deltay)); } return 0; } int igraph_2dgrid_init(igraph_2dgrid_t *grid, igraph_matrix_t *coords, igraph_real_t minx, igraph_real_t maxx, igraph_real_t deltax, igraph_real_t miny, igraph_real_t maxy, igraph_real_t deltay) { long int i; grid->coords = coords; grid->minx = minx; grid->maxx = maxx; grid->deltax = deltax; grid->miny = miny; grid->maxy = maxy; grid->deltay = deltay; grid->stepsx = (long int) ceil((maxx - minx) / deltax); grid->stepsy = (long int) ceil((maxy - miny) / deltay); IGRAPH_CHECK(igraph_matrix_init(&grid->startidx, grid->stepsx, grid->stepsy)); IGRAPH_FINALLY(igraph_matrix_destroy, &grid->startidx); IGRAPH_VECTOR_INIT_FINALLY(&grid->next, igraph_matrix_nrow(coords)); IGRAPH_VECTOR_INIT_FINALLY(&grid->prev, igraph_matrix_nrow(coords)); for (i = 0; i < igraph_vector_size(&grid->next); i++) { VECTOR(grid->next)[i] = -1; } grid->massx = 0; grid->massy = 0; grid->vertices = 0; IGRAPH_FINALLY_CLEAN(3); return 0; } void igraph_2dgrid_destroy(igraph_2dgrid_t *grid) { igraph_matrix_destroy(&grid->startidx); igraph_vector_destroy(&grid->next); igraph_vector_destroy(&grid->prev); } void igraph_2dgrid_add(igraph_2dgrid_t *grid, long int elem, igraph_real_t xc, igraph_real_t yc) { long int x, y; long int first; MATRIX(*grid->coords, elem, 0) = xc; MATRIX(*grid->coords, elem, 1) = yc; /* add to cell */ igraph_2dgrid_which(grid, xc, yc, &x, &y); first = (long int) MATRIX(grid->startidx, x, y); VECTOR(grid->prev)[elem] = 0; VECTOR(grid->next)[elem] = first; if (first != 0) { VECTOR(grid->prev)[first - 1] = elem + 1; } MATRIX(grid->startidx, x, y) = elem + 1; grid->massx += xc; grid->massy += yc; grid->vertices += 1; } void igraph_2dgrid_add2(igraph_2dgrid_t *grid, long int elem) { long int x, y; long int first; igraph_real_t xc, yc; xc = MATRIX(*grid->coords, elem, 0); yc = MATRIX(*grid->coords, elem, 1); /* add to cell */ igraph_2dgrid_which(grid, xc, yc, &x, &y); first = (long int) MATRIX(grid->startidx, x, y); VECTOR(grid->prev)[elem] = 0; VECTOR(grid->next)[elem] = first; if (first != 0) { VECTOR(grid->prev)[first - 1] = elem + 1; } MATRIX(grid->startidx, x, y) = elem + 1; grid->massx += xc; grid->massy += yc; grid->vertices += 1; } void igraph_2dgrid_move(igraph_2dgrid_t *grid, long int elem, igraph_real_t xc, igraph_real_t yc) { long int oldx, oldy; long int newx, newy; igraph_real_t oldxc = MATRIX(*grid->coords, elem, 0); igraph_real_t oldyc = MATRIX(*grid->coords, elem, 1); long int first; xc = oldxc + xc; yc = oldyc + yc; igraph_2dgrid_which(grid, oldxc, oldyc, &oldx, &oldy); igraph_2dgrid_which(grid, xc, yc, &newx, &newy); if (oldx != newx || oldy != newy) { /* remove from this cell */ if (VECTOR(grid->prev)[elem] != 0) { VECTOR(grid->next) [ (long int) VECTOR(grid->prev)[elem] - 1 ] = VECTOR(grid->next)[elem]; } else { MATRIX(grid->startidx, oldx, oldy) = VECTOR(grid->next)[elem]; } if (VECTOR(grid->next)[elem] != 0) { VECTOR(grid->prev)[ (long int) VECTOR(grid->next)[elem] - 1 ] = VECTOR(grid->prev)[elem]; } /* add to this cell */ first = (long int) MATRIX(grid->startidx, newx, newy); VECTOR(grid->prev)[elem] = 0; VECTOR(grid->next)[elem] = first; if (first != 0) { VECTOR(grid->prev)[first - 1] = elem + 1; } MATRIX(grid->startidx, newx, newy) = elem + 1; } grid->massx += -oldxc + xc; grid->massy += -oldyc + yc; MATRIX(*grid->coords, elem, 0) = xc; MATRIX(*grid->coords, elem, 1) = yc; } void igraph_2dgrid_getcenter(const igraph_2dgrid_t *grid, igraph_real_t *massx, igraph_real_t *massy) { *massx = (grid->massx) / (grid->vertices); *massy = (grid->massy) / (grid->vertices); } igraph_bool_t igraph_2dgrid_in(const igraph_2dgrid_t *grid, long int elem) { return VECTOR(grid->next)[elem] != -1; } igraph_real_t igraph_2dgrid_dist(const igraph_2dgrid_t *grid, long int e1, long int e2) { igraph_real_t x = MATRIX(*grid->coords, e1, 0) - MATRIX(*grid->coords, e2, 0); igraph_real_t y = MATRIX(*grid->coords, e1, 1) - MATRIX(*grid->coords, e2, 1); return sqrt(x * x + y * y); } igraph_real_t igraph_2dgrid_dist2(const igraph_2dgrid_t *grid, long int e1, long int e2) { igraph_real_t x = MATRIX(*grid->coords, e1, 0) - MATRIX(*grid->coords, e2, 0); igraph_real_t y = MATRIX(*grid->coords, e1, 1) - MATRIX(*grid->coords, e2, 1); return x * x + y * y; } static int igraph_i_2dgrid_addvertices(igraph_2dgrid_t *grid, igraph_vector_t *eids, igraph_integer_t vid, igraph_real_t r, long int x, long int y) { long int act; igraph_real_t *v = VECTOR(grid->next); r = r * r; act = (long int) MATRIX(grid->startidx, x, y); while (act != 0) { if (igraph_2dgrid_dist2(grid, vid, act - 1) < r) { IGRAPH_CHECK(igraph_vector_push_back(eids, act - 1)); } act = (long int) v[act - 1]; } return 0; } int igraph_2dgrid_neighbors(igraph_2dgrid_t *grid, igraph_vector_t *eids, igraph_integer_t vid, igraph_real_t r) { igraph_real_t xc = MATRIX(*grid->coords, (long int)vid, 0); igraph_real_t yc = MATRIX(*grid->coords, (long int)vid, 1); long int x, y; igraph_vector_clear(eids); igraph_2dgrid_which(grid, xc, yc, &x, &y); /* this cell */ igraph_i_2dgrid_addvertices(grid, eids, vid, r, x, y); /* left */ if (x != 0) { igraph_i_2dgrid_addvertices(grid, eids, vid, r, x - 1, y); } /* right */ if (x != grid->stepsx - 1) { igraph_i_2dgrid_addvertices(grid, eids, vid, r, x + 1, y); } /* up */ if (y != 0) { igraph_i_2dgrid_addvertices(grid, eids, vid, r, x, y - 1); } /* down */ if (y != grid->stepsy - 1) { igraph_i_2dgrid_addvertices(grid, eids, vid, r, x, y + 1); } /* up & left */ if (x != 0 && y != 0) { igraph_i_2dgrid_addvertices(grid, eids, vid, r, x - 1, y - 1); } /* up & right */ if (x != grid->stepsx - 1 && y != 0) { igraph_i_2dgrid_addvertices(grid, eids, vid, r, x + 1, y - 1); } /* down & left */ if (x != 0 && y != grid->stepsy - 1) { igraph_i_2dgrid_addvertices(grid, eids, vid, r, x - 1, y + 1); } /* down & right */ if (x != grid->stepsx - 1 && y != grid->stepsy - 1) { igraph_i_2dgrid_addvertices(grid, eids, vid, r, x - 1, y + 1); } return 0; } void igraph_2dgrid_reset(igraph_2dgrid_t *grid, igraph_2dgrid_iterator_t *it) { /* Search for the first cell containing a vertex */ it->x = 0; it->y = 0; it->vid = (long int) MATRIX(grid->startidx, 0, 0); while ( it->vid == 0 && (it->x < grid->stepsx - 1 || it->y < grid->stepsy - 1)) { it->x += 1; if (it->x == grid->stepsx) { it->x = 0; it->y += 1; } it->vid = (long int) MATRIX(grid->startidx, it->x, it->y); } } igraph_integer_t igraph_2dgrid_next(igraph_2dgrid_t *grid, igraph_2dgrid_iterator_t *it) { long int ret = it->vid; if (ret == 0) { return 0; } /* First neighbor */ it->ncells = -1; if (it->x != grid->stepsx - 1) { it->ncells += 1; it->nx[it->ncells] = it->x + 1; it->ny[it->ncells] = it->y; } if (it->y != grid->stepsy - 1) { it->ncells += 1; it->nx[it->ncells] = it->x; it->ny[it->ncells] = it->y + 1; } if (it->ncells == 1) { it->ncells += 1; it->nx[it->ncells] = it->x + 1; it->ny[it->ncells] = it->y + 1; } it->ncells += 1; it->nx[it->ncells] = it->x; it->ny[it->ncells] = it->y; it->nei = (long int) VECTOR(grid->next) [ ret - 1 ]; while (it->ncells > 0 && it->nei == 0 ) { it->ncells -= 1; it->nei = (long int) MATRIX(grid->startidx, it->nx[it->ncells], it->ny[it->ncells]); } /* Next vertex */ it->vid = (long int) VECTOR(grid->next)[ it->vid - 1 ]; while ( (it->x < grid->stepsx - 1 || it->y < grid->stepsy - 1) && it->vid == 0) { it->x += 1; if (it->x == grid->stepsx) { it->x = 0; it->y += 1; } it->vid = (long int) MATRIX(grid->startidx, it->x, it->y); } return (igraph_integer_t) ret; } igraph_integer_t igraph_2dgrid_next_nei(igraph_2dgrid_t *grid, igraph_2dgrid_iterator_t *it) { long int ret = it->nei; if (it->nei != 0) { it->nei = (long int) VECTOR(grid->next) [ ret - 1 ]; } while (it->ncells > 0 && it->nei == 0 ) { it->ncells -= 1; it->nei = (long int) MATRIX(grid->startidx, it->nx[it->ncells], it->ny[it->ncells]); } return (igraph_integer_t) ret; } leidenbase/src/core/core/matrix.c0000644000176200001440000001152114447675374016511 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_matrix.h" #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "matrix.pmt" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_INT #include "igraph_pmt.h" #include "matrix.pmt" #include "igraph_pmt_off.h" #undef BASE_INT #define BASE_LONG #include "igraph_pmt.h" #include "matrix.pmt" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_CHAR #include "igraph_pmt.h" #include "matrix.pmt" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "matrix.pmt" #include "igraph_pmt_off.h" #undef BASE_BOOL #define BASE_COMPLEX #include "igraph_pmt.h" #include "matrix.pmt" #include "igraph_pmt_off.h" #undef BASE_COMPLEX #ifndef USING_R int igraph_matrix_complex_print(const igraph_matrix_complex_t *m) { long int nr = igraph_matrix_complex_nrow(m); long int nc = igraph_matrix_complex_ncol(m); long int i, j; for (i = 0; i < nr; i++) { for (j = 0; j < nc; j++) { igraph_complex_t z = MATRIX(*m, i, j); if (j != 0) { putchar(' '); } printf("%g%+gi", IGRAPH_REAL(z), IGRAPH_IMAG(z)); } printf("\n"); } return 0; } #endif int igraph_matrix_complex_fprint(const igraph_matrix_complex_t *m, FILE *file) { long int nr = igraph_matrix_complex_nrow(m); long int nc = igraph_matrix_complex_ncol(m); long int i, j; for (i = 0; i < nr; i++) { for (j = 0; j < nc; j++) { igraph_complex_t z = MATRIX(*m, i, j); if (j != 0) { fputc(' ', file); } fprintf(file, "%g%+gi", IGRAPH_REAL(z), IGRAPH_IMAG(z)); } fprintf(file, "\n"); } return 0; } int igraph_matrix_complex_real(const igraph_matrix_complex_t *v, igraph_matrix_t *real) { long int nrow = igraph_matrix_complex_nrow(v); long int ncol = igraph_matrix_complex_ncol(v); IGRAPH_CHECK(igraph_matrix_resize(real, nrow, ncol)); IGRAPH_CHECK(igraph_vector_complex_real(&v->data, &real->data)); return 0; } int igraph_matrix_complex_imag(const igraph_matrix_complex_t *v, igraph_matrix_t *imag) { long int nrow = igraph_matrix_complex_nrow(v); long int ncol = igraph_matrix_complex_ncol(v); IGRAPH_CHECK(igraph_matrix_resize(imag, nrow, ncol)); IGRAPH_CHECK(igraph_vector_complex_imag(&v->data, &imag->data)); return 0; } int igraph_matrix_complex_realimag(const igraph_matrix_complex_t *v, igraph_matrix_t *real, igraph_matrix_t *imag) { long int nrow = igraph_matrix_complex_nrow(v); long int ncol = igraph_matrix_complex_ncol(v); IGRAPH_CHECK(igraph_matrix_resize(real, nrow, ncol)); IGRAPH_CHECK(igraph_matrix_resize(imag, nrow, ncol)); IGRAPH_CHECK(igraph_vector_complex_realimag(&v->data, &real->data, &imag->data)); return 0; } int igraph_matrix_complex_create(igraph_matrix_complex_t *v, const igraph_matrix_t *real, const igraph_matrix_t *imag) { IGRAPH_CHECK(igraph_vector_complex_create(&v->data, &real->data, &imag->data)); return 0; } int igraph_matrix_complex_create_polar(igraph_matrix_complex_t *v, const igraph_matrix_t *r, const igraph_matrix_t *theta) { IGRAPH_CHECK(igraph_vector_complex_create_polar(&v->data, &r->data, &theta->data)); return 0; } igraph_bool_t igraph_matrix_all_e_tol(const igraph_matrix_t *lhs, const igraph_matrix_t *rhs, igraph_real_t tol) { return igraph_vector_e_tol(&lhs->data, &rhs->data, tol); } int igraph_matrix_zapsmall(igraph_matrix_t *m, igraph_real_t tol) { return igraph_vector_zapsmall(&m->data, tol); } leidenbase/src/core/core/estack.h0000644000176200001440000000337514447675374016474 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_ESTACK_H #define IGRAPH_ESTACK_H #include "igraph_stack.h" #include "igraph_vector.h" typedef struct igraph_estack_t { igraph_stack_long_t stack; igraph_vector_bool_t isin; } igraph_estack_t; IGRAPH_PRIVATE_EXPORT int igraph_estack_init(igraph_estack_t *s, long int setsize, long int stacksize); IGRAPH_PRIVATE_EXPORT void igraph_estack_destroy(igraph_estack_t *s); IGRAPH_PRIVATE_EXPORT int igraph_estack_push(igraph_estack_t *s, long int elem); IGRAPH_PRIVATE_EXPORT long int igraph_estack_pop(igraph_estack_t *s); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_estack_iselement(const igraph_estack_t *s, long int elem); IGRAPH_PRIVATE_EXPORT long int igraph_estack_size(const igraph_estack_t *s); IGRAPH_PRIVATE_EXPORT int igraph_estack_print(const igraph_estack_t *s); #endif leidenbase/src/core/core/exceptions.h0000644000176200001440000000140214447675374017370 0ustar liggesusers#ifndef IGRAPH_HANDLE_EXCEPTIONS_H #define IGRAPH_HANDLE_EXCEPTIONS_H #include #include /* igraph functions which may be called from C code must not throw C++ exceptions. * This includes all public functions. This macro is meant to handle exceptions thrown * by C++ libraries used by igraph (such as bliss). Wrap the entire body * of public functions implemented in C++ in IGRAPH_HANDLE_EXCEPTIONS(). */ #define IGRAPH_HANDLE_EXCEPTIONS(code) \ try { code; } \ catch (const std::bad_alloc &e) { IGRAPH_ERROR(e.what(), IGRAPH_ENOMEM); } \ catch (const std::exception &e) { IGRAPH_ERROR(e.what(), IGRAPH_FAILURE); } \ catch (...) { IGRAPH_ERROR("Unknown exception caught.", IGRAPH_FAILURE); } #endif // IGRAPH_HANDLE_EXCEPTIONS_H leidenbase/src/core/core/marked_queue.h0000644000176200001440000000546214447675374017670 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_MARKED_QUEUE_H #define IGRAPH_MARKED_QUEUE_H #include "igraph_vector.h" #include "igraph_dqueue.h" #include /* This is essentially a double ended queue, with some extra features: (1) The is-element? operation is fast, O(1). This requires that we know a limit for the number of elements in the queue. (2) We can insert elements in batches, and the whole batch can be removed at once. Currently only the top-end operations are implemented, so the queue is essentially a stack. */ typedef struct igraph_marked_queue_t { igraph_dqueue_t Q; igraph_vector_long_t set; long int mark; long int size; } igraph_marked_queue_t; IGRAPH_PRIVATE_EXPORT int igraph_marked_queue_init(igraph_marked_queue_t *q, long int size); IGRAPH_PRIVATE_EXPORT void igraph_marked_queue_destroy(igraph_marked_queue_t *q); IGRAPH_PRIVATE_EXPORT void igraph_marked_queue_reset(igraph_marked_queue_t *q); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_marked_queue_empty(const igraph_marked_queue_t *q); IGRAPH_PRIVATE_EXPORT long int igraph_marked_queue_size(const igraph_marked_queue_t *q); IGRAPH_PRIVATE_EXPORT int igraph_marked_queue_print(const igraph_marked_queue_t *q); IGRAPH_PRIVATE_EXPORT int igraph_marked_queue_fprint(const igraph_marked_queue_t *q, FILE *file); IGRAPH_PRIVATE_EXPORT igraph_bool_t igraph_marked_queue_iselement(const igraph_marked_queue_t *q, long int elem); IGRAPH_PRIVATE_EXPORT int igraph_marked_queue_push(igraph_marked_queue_t *q, long int elem); IGRAPH_PRIVATE_EXPORT int igraph_marked_queue_start_batch(igraph_marked_queue_t *q); IGRAPH_PRIVATE_EXPORT void igraph_marked_queue_pop_back_batch(igraph_marked_queue_t *q); IGRAPH_PRIVATE_EXPORT int igraph_marked_queue_as_vector(const igraph_marked_queue_t *q, igraph_vector_t *vec); #endif leidenbase/src/core/core/fixed_vectorlist.c0000644000176200001440000000502514447675374020564 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_memory.h" #include "core/fixed_vectorlist.h" void igraph_fixed_vectorlist_destroy(igraph_fixed_vectorlist_t *l) { long int i, n = igraph_vector_ptr_size(&l->v); for (i = 0; i < n; i++) { igraph_vector_t *v = VECTOR(l->v)[i]; if (v) { igraph_vector_destroy(v); } } igraph_vector_ptr_destroy(&l->v); igraph_free(l->vecs); } int igraph_fixed_vectorlist_convert(igraph_fixed_vectorlist_t *l, const igraph_vector_t *from, long int size) { igraph_vector_t sizes; long int i, no = igraph_vector_size(from); l->vecs = IGRAPH_CALLOC(size, igraph_vector_t); if (!l->vecs) { IGRAPH_ERROR("Cannot merge attributes for simplify", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, l->vecs); IGRAPH_CHECK(igraph_vector_ptr_init(&l->v, size)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &l->v); IGRAPH_VECTOR_INIT_FINALLY(&sizes, size); for (i = 0; i < no; i++) { long int to = (long int) VECTOR(*from)[i]; if (to >= 0) { VECTOR(sizes)[to] += 1; } } for (i = 0; i < size; i++) { igraph_vector_t *v = &(l->vecs[i]); IGRAPH_CHECK(igraph_vector_init(v, (long int) VECTOR(sizes)[i])); igraph_vector_clear(v); VECTOR(l->v)[i] = v; } for (i = 0; i < no; i++) { long int to = (long int) VECTOR(*from)[i]; if (to >= 0) { igraph_vector_t *v = &(l->vecs[to]); igraph_vector_push_back(v, i); } } igraph_vector_destroy(&sizes); IGRAPH_FINALLY_CLEAN(3); return 0; } leidenbase/src/core/core/dqueue.pmt0000644000176200001440000002277214447675374017065 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_memory.h" #include "igraph_error.h" #include "config.h" #include /* memcpy & co. */ #include /** * \section igraph_dqueue * * This is the classic data type of the double ended queue. Most of * the time it is used if a First-In-First-Out (FIFO) behavior is * needed. See the operations below. * * * * \example examples/simple/dqueue.c * */ /** * \ingroup dqueue * \function igraph_dqueue_init * \brief Initialize a double ended queue (deque). * * The queue will be always empty. * \param q Pointer to an uninitialized deque. * \param size How many elements to allocate memory for. * \return Error code. * * Time complexity: O(\p size). */ int FUNCTION(igraph_dqueue, init) (TYPE(igraph_dqueue)* q, long int size) { IGRAPH_ASSERT(q != 0); if (size <= 0 ) { size = 1; } q->stor_begin = IGRAPH_CALLOC(size, BASE); if (q->stor_begin == 0) { IGRAPH_ERROR("dqueue init failed", IGRAPH_ENOMEM); } q->stor_end = q->stor_begin + size; q->begin = q->stor_begin; q->end = NULL; return 0; } /** * \ingroup dqueue * \function igraph_dqueue_destroy * \brief Destroy a double ended queue. * * \param q The queue to destroy * * Time complexity: O(1). */ void FUNCTION(igraph_dqueue, destroy) (TYPE(igraph_dqueue)* q) { IGRAPH_ASSERT(q != 0); if (q->stor_begin != 0) { IGRAPH_FREE(q->stor_begin); q->stor_begin = 0; } } /** * \ingroup dqueue * \function igraph_dqueue_empty * \brief Decide whether the queue is empty. * * \param q The queue. * \return Boolean, \c TRUE if \p q contains at least one element, \c * FALSE otherwise. * * Time complexity: O(1). */ igraph_bool_t FUNCTION(igraph_dqueue, empty) (const TYPE(igraph_dqueue)* q) { IGRAPH_ASSERT(q != 0); IGRAPH_ASSERT(q->stor_begin != 0); return q->end == NULL; } /** * \ingroup dqueue * \function igraph_dqueue_clear * \brief Remove all elements from the queue. * * \param q The queue * * Time complexity: O(1). */ void FUNCTION(igraph_dqueue, clear) (TYPE(igraph_dqueue)* q) { IGRAPH_ASSERT(q != 0); IGRAPH_ASSERT(q->stor_begin != 0); q->begin = q->stor_begin; q->end = NULL; } /** * \ingroup dqueue * \function igraph_dqueue_full * \brief Check whether the queue is full. * * If a queue is full the next igraph_dqueue_push() operation will allocate * more memory. * \param q The queue. * \return \c TRUE if \p q is full, \c FALSE otherwise. * * Time complecity: O(1). */ igraph_bool_t FUNCTION(igraph_dqueue, full) (TYPE(igraph_dqueue)* q) { IGRAPH_ASSERT(q != 0); IGRAPH_ASSERT(q->stor_begin != 0); return q->begin == q->end; } /** * \ingroup dqueue * \function igraph_dqueue_size * \brief Number of elements in the queue. * * \param q The queue. * \return Integer, the number of elements currently in the queue. * * Time complexity: O(1). */ long int FUNCTION(igraph_dqueue, size) (const TYPE(igraph_dqueue)* q) { IGRAPH_ASSERT(q != 0); IGRAPH_ASSERT(q->stor_begin != 0); if (q->end == NULL) { return 0; } else if (q->begin < q->end) { return q->end - q->begin; } else { return q->stor_end - q->begin + q->end - q->stor_begin; } } /** * \ingroup dqueue * \function igraph_dqueue_head * \brief Head of the queue. * * The queue must contain at least one element. * \param q The queue. * \return The first element in the queue. * * Time complexity: O(1). */ BASE FUNCTION(igraph_dqueue, head) (const TYPE(igraph_dqueue)* q) { IGRAPH_ASSERT(q != 0); IGRAPH_ASSERT(q->stor_begin != 0); return *(q->begin); } /** * \ingroup dqueue * \function igraph_dqueue_back * \brief Tail of the queue. * * The queue must contain at least one element. * \param q The queue. * \return The last element in the queue. * * Time complexity: O(1). */ BASE FUNCTION(igraph_dqueue, back) (const TYPE(igraph_dqueue)* q) { IGRAPH_ASSERT(q != 0); IGRAPH_ASSERT(q->stor_begin != 0); if (q->end == q->stor_begin) { return *(q->stor_end - 1); } return *(q->end - 1); } /** * \ingroup dqueue * \function igraph_dqueue_pop * \brief Remove the head. * * Removes and returns the first element in the queue. The queue must * be non-empty. * \param q The input queue. * \return The first element in the queue. * * Time complexity: O(1). */ BASE FUNCTION(igraph_dqueue, pop) (TYPE(igraph_dqueue)* q) { BASE tmp = *(q->begin); IGRAPH_ASSERT(q != 0); IGRAPH_ASSERT(q->stor_begin != 0); (q->begin)++; if (q->begin == q->stor_end) { q->begin = q->stor_begin; } if (q->begin == q->end) { q->end = NULL; } return tmp; } /** * \ingroup dqueue * \function igraph_dqueue_pop_back * \brief Remove the tail * * Removes and returns the last element in the queue. The queue must * be non-empty. * \param q The queue. * \return The last element in the queue. * * Time complexity: O(1). */ BASE FUNCTION(igraph_dqueue, pop_back) (TYPE(igraph_dqueue)* q) { BASE tmp; IGRAPH_ASSERT(q != 0); IGRAPH_ASSERT(q->stor_begin != 0); if (q->end != q->stor_begin) { tmp = *((q->end) - 1); q->end = (q->end) - 1; } else { tmp = *((q->stor_end) - 1); q->end = (q->stor_end) - 1; } if (q->begin == q->end) { q->end = NULL; } return tmp; } /** * \ingroup dqueue * \function igraph_dqueue_push * \brief Appends an element. * * Append an element to the end of the queue. * \param q The queue. * \param elem The element to append. * \return Error code. * * Time complexity: O(1) if no memory allocation is needed, O(n), the * number of elements in the queue otherwise. But not that by * allocating always twice as much memory as the current size of the * queue we ensure that n push operations can always be done in at * most O(n) time. (Assuming memory allocation is at most linear.) */ int FUNCTION(igraph_dqueue, push) (TYPE(igraph_dqueue)* q, BASE elem) { IGRAPH_ASSERT(q != 0); IGRAPH_ASSERT(q->stor_begin != 0); if (q->begin != q->end) { /* not full */ if (q->end == NULL) { q->end = q->begin; } *(q->end) = elem; (q->end)++; if (q->end == q->stor_end) { q->end = q->stor_begin; } } else { /* full, allocate more storage */ BASE *bigger = NULL, *old = q->stor_begin; bigger = IGRAPH_CALLOC( 2 * (q->stor_end - q->stor_begin) + 1, BASE ); if (bigger == 0) { IGRAPH_ERROR("dqueue push failed", IGRAPH_ENOMEM); } if (q->stor_end - q->begin) { memcpy(bigger, q->begin, (size_t)(q->stor_end - q->begin) * sizeof(BASE)); } if (q->end - q->stor_begin > 0) { memcpy(bigger + (q->stor_end - q->begin), q->stor_begin, (size_t)(q->end - q->stor_begin) * sizeof(BASE)); } q->end = bigger + (q->stor_end - q->stor_begin); q->stor_end = bigger + 2 * (q->stor_end - q->stor_begin) + 1; q->stor_begin = bigger; q->begin = bigger; *(q->end) = elem; (q->end)++; if (q->end == q->stor_end) { q->end = q->stor_begin; } IGRAPH_FREE(old); } return 0; } #if defined (OUT_FORMAT) #ifndef USING_R int FUNCTION(igraph_dqueue, print)(const TYPE(igraph_dqueue)* q) { return FUNCTION(igraph_dqueue, fprint)(q, stdout); } #endif int FUNCTION(igraph_dqueue, fprint)(const TYPE(igraph_dqueue)* q, FILE *file) { if (q->end != NULL) { /* There is one element at least */ BASE *p = q->begin; fprintf(file, OUT_FORMAT, *p); p++; if (q->end > q->begin) { /* Q is in one piece */ while (p != q->end) { fprintf(file, " " OUT_FORMAT, *p); p++; } } else { /* Q is in two pieces */ while (p != q->stor_end) { fprintf(file, " " OUT_FORMAT, *p); p++; } p = q->stor_begin; while (p != q->end) { fprintf(file, " " OUT_FORMAT, *p); p++; } } } fprintf(file, "\n"); return 0; } #endif BASE FUNCTION(igraph_dqueue, e)(const TYPE(igraph_dqueue) *q, long int idx) { if ((q->begin + idx < q->end) || (q->begin >= q->end && q->begin + idx < q->stor_end)) { return q->begin[idx]; } else if (q->begin >= q->end && q->stor_begin + idx < q->end) { idx = idx - (q->stor_end - q->begin); return q->stor_begin[idx]; } else { return 0; /* Error */ } } leidenbase/src/core/core/estack.c0000644000176200001440000000412614447675374016462 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "core/estack.h" int igraph_estack_init(igraph_estack_t *s, long int setsize, long int stacksize) { IGRAPH_CHECK(igraph_vector_bool_init(&s->isin, setsize)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &s->isin); IGRAPH_CHECK(igraph_stack_long_init(&s->stack, stacksize)); IGRAPH_FINALLY_CLEAN(1); return 0; } void igraph_estack_destroy(igraph_estack_t *s) { igraph_stack_long_destroy(&s->stack); igraph_vector_bool_destroy(&s->isin); } int igraph_estack_push(igraph_estack_t *s, long int elem) { if ( !VECTOR(s->isin)[elem] ) { IGRAPH_CHECK(igraph_stack_long_push(&s->stack, elem)); VECTOR(s->isin)[elem] = 1; } return 0; } long int igraph_estack_pop(igraph_estack_t *s) { long int elem = igraph_stack_long_pop(&s->stack); VECTOR(s->isin)[elem] = 0; return elem; } igraph_bool_t igraph_estack_iselement(const igraph_estack_t *s, long int elem) { return VECTOR(s->isin)[elem]; } long int igraph_estack_size(const igraph_estack_t *s) { return igraph_stack_long_size(&s->stack); } #ifndef USING_R int igraph_estack_print(const igraph_estack_t *s) { return igraph_stack_long_print(&s->stack); } #endif leidenbase/src/core/core/interruption.c0000644000176200001440000000267414447675374017760 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_interrupt.h" #include "config.h" IGRAPH_THREAD_LOCAL igraph_interruption_handler_t *igraph_i_interruption_handler = 0; int igraph_allow_interruption(void* data) { if (igraph_i_interruption_handler) { return igraph_i_interruption_handler(data); } return IGRAPH_SUCCESS; } igraph_interruption_handler_t * igraph_set_interruption_handler (igraph_interruption_handler_t * new_handler) { igraph_interruption_handler_t * previous_handler = igraph_i_interruption_handler; igraph_i_interruption_handler = new_handler; return previous_handler; } leidenbase/src/core/core/vector.pmt0000644000176200001440000025343414447675374017100 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_memory.h" #include "igraph_error.h" #include "igraph_random.h" #include "igraph_qsort.h" #include /* memcpy & co. */ #include #include /* va_start & co */ #include /** * \ingroup vector * \section about_igraph_vector_t_objects About \type igraph_vector_t objects * * The \type igraph_vector_t data type is a simple and efficient * interface to arrays containing numbers. It is something * similar as (but much simpler than) the \type vector template * in the C++ standard library. * * Vectors are used extensively in \a igraph, all * functions which expect or return a list of numbers use * igraph_vector_t to achieve this. * * The \type igraph_vector_t type usually uses * O(n) space * to store n elements. Sometimes it * uses more, this is because vectors can shrink, but even if they * shrink, the current implementation does not free a single bit of * memory. * * The elements in an \type igraph_vector_t * object are indexed from zero, we follow the usual C convention * here. * * The elements of a vector always occupy a single block of * memory, the starting address of this memory block can be queried * with the \ref VECTOR macro. This way, vector objects can be used * with standard mathematical libraries, like the GNU Scientific * Library. */ /** * \ingroup vector * \section igraph_vector_constructors_and_destructors Constructors and * Destructors * * \type igraph_vector_t objects have to be initialized before using * them, this is analogous to calling a constructor on them. There are a * number of \type igraph_vector_t constructors, for your * convenience. \ref igraph_vector_init() is the basic constructor, it * creates a vector of the given length, filled with zeros. * \ref igraph_vector_copy() creates a new identical copy * of an already existing and initialized vector. \ref * igraph_vector_init_copy() creates a vector by copying a regular C array. * \ref igraph_vector_init_seq() creates a vector containing a regular * sequence with increment one. * * \ref igraph_vector_view() is a special constructor, it allows you to * handle a regular C array as a \type vector without copying * its elements. * * * If a \type igraph_vector_t object is not needed any more, it * should be destroyed to free its allocated memory by calling the * \type igraph_vector_t destructor, \ref igraph_vector_destroy(). * * Note that vectors created by \ref igraph_vector_view() are special, * you mustn't call \ref igraph_vector_destroy() on these. */ /** * \ingroup vector * \function igraph_vector_init * \brief Initializes a vector object (constructor). * * * Every vector needs to be initialized before it can be used, and * there are a number of initialization functions or otherwise called * constructors. This function constructs a vector of the given size and * initializes each entry to 0. Note that \ref igraph_vector_null() can be * used to set each element of a vector to zero. However, if you want a * vector of zeros, it is much faster to use this function than to create a * vector and then invoke \ref igraph_vector_null(). * * * Every vector object initialized by this function should be * destroyed (ie. the memory allocated for it should be freed) when it * is not needed anymore, the \ref igraph_vector_destroy() function is * responsible for this. * \param v Pointer to a not yet initialized vector object. * \param size The size of the vector. * \return error code: * \c IGRAPH_ENOMEM if there is not enough memory. * * Time complexity: operating system dependent, the amount of * \quote time \endquote required to allocate * O(n) elements, * n is the number of elements. */ int FUNCTION(igraph_vector, init) (TYPE(igraph_vector)* v, int long size) { long int alloc_size = size > 0 ? size : 1; IGRAPH_ASSERT(size >= 0); v->stor_begin = IGRAPH_CALLOC(alloc_size, BASE); if (v->stor_begin == 0) { IGRAPH_ERROR("cannot init vector", IGRAPH_ENOMEM); } v->stor_end = v->stor_begin + alloc_size; v->end = v->stor_begin + size; return 0; } /** * \ingroup vector * \function igraph_vector_view * \brief Handle a regular C array as a \type igraph_vector_t. * * * This is a special \type igraph_vector_t constructor. It allows to * handle a regular C array as a \type igraph_vector_t temporarily. * Be sure that you \em don't ever call the destructor (\ref * igraph_vector_destroy()) on objects created by this constructor. * \param v Pointer to an uninitialized \type igraph_vector_t object. * \param data Pointer, the C array. It may not be \c NULL. * \param length The length of the C array. * \return Pointer to the vector object, the same as the * \p v parameter, for convenience. * * Time complexity: O(1) */ const TYPE(igraph_vector)*FUNCTION(igraph_vector, view) (const TYPE(igraph_vector) *v, const BASE *data, long int length) { TYPE(igraph_vector) *v2 = (TYPE(igraph_vector)*)v; IGRAPH_ASSERT(data != 0); v2->stor_begin = (BASE*)data; v2->stor_end = (BASE*)data + length; v2->end = v2->stor_end; return v; } #ifndef BASE_COMPLEX /** * \ingroup vector * \function igraph_vector_init_real * \brief Create an \type igraph_vector_t from the parameters. * * * Because of how C and the C library handles variable length argument * lists, it is required that you supply real constants to this * function. This means that * \verbatim igraph_vector_t v; * igraph_vector_init_real(&v, 5, 1,2,3,4,5); \endverbatim * is an error at runtime and the results are undefined. This is * the proper way: * \verbatim igraph_vector_t v; * igraph_vector_init_real(&v, 5, 1.0,2.0,3.0,4.0,5.0); \endverbatim * \param v Pointer to an uninitialized \type igraph_vector_t object. * \param no Positive integer, the number of \type igraph_real_t * parameters to follow. * \param ... The elements of the vector. * \return Error code, this can be \c IGRAPH_ENOMEM * if there isn't enough memory to allocate the vector. * * \sa \ref igraph_vector_init_real_end(), \ref igraph_vector_init_int() for similar * functions. * * Time complexity: depends on the time required to allocate memory, * but at least O(n), the number of * elements in the vector. */ int FUNCTION(igraph_vector, init_real)(TYPE(igraph_vector) *v, int no, ...) { int i = 0; va_list ap; IGRAPH_CHECK(FUNCTION(igraph_vector, init)(v, no)); va_start(ap, no); for (i = 0; i < no; i++) { VECTOR(*v)[i] = (BASE) va_arg(ap, double); } va_end(ap); return 0; } /** * \ingroup vector * \function igraph_vector_init_real_end * \brief Create an \type igraph_vector_t from the parameters. * * * This constructor is similar to \ref igraph_vector_init_real(), the only * difference is that instead of giving the number of elements in the * vector, a special marker element follows the last real vector * element. * \param v Pointer to an uninitialized \type igraph_vector_t object. * \param endmark This element will signal the end of the vector. It * will \em not be part of the vector. * \param ... The elements of the vector. * \return Error code, \c IGRAPH_ENOMEM if there * isn't enough memory. * * \sa \ref igraph_vector_init_real() and \ref igraph_vector_init_int_end() for * similar functions. * * Time complexity: at least O(n) for * n elements plus the time * complexity of the memory allocation. */ int FUNCTION(igraph_vector, init_real_end)(TYPE(igraph_vector) *v, double endmark, ...) { int i = 0, n = 0; va_list ap; va_start(ap, endmark); while (1) { BASE num = (BASE) va_arg(ap, double); if (num == endmark) { break; } n++; } va_end(ap); IGRAPH_CHECK(FUNCTION(igraph_vector, init)(v, n)); IGRAPH_FINALLY(FUNCTION(igraph_vector, destroy), v); va_start(ap, endmark); for (i = 0; i < n; i++) { VECTOR(*v)[i] = (BASE) va_arg(ap, double); } va_end(ap); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup vector * \function igraph_vector_init_int * \brief Create an \type igraph_vector_t containing the parameters. * * * This function is similar to \ref igraph_vector_init_real(), but it expects * \type int parameters. It is important that all parameters * should be of this type, otherwise the result of the function call * is undefined. * \param v Pointer to an uninitialized \type igraph_vector_t object. * \param no The number of \type int parameters to follow. * \param ... The elements of the vector. * \return Error code, \c IGRAPH_ENOMEM if there is * not enough memory. * \sa \ref igraph_vector_init_real() and igraph_vector_init_int_end(), these are * similar functions. * * Time complexity: at least O(n) for * n elements plus the time * complexity of the memory allocation. */ int FUNCTION(igraph_vector, init_int)(TYPE(igraph_vector) *v, int no, ...) { int i = 0; va_list ap; IGRAPH_CHECK(FUNCTION(igraph_vector, init)(v, no)); va_start(ap, no); for (i = 0; i < no; i++) { VECTOR(*v)[i] = (BASE) va_arg(ap, int); } va_end(ap); return 0; } /** * \ingroup vector * \function igraph_vector_init_int_end * \brief Create an \type igraph_vector_t from the parameters. * * * This constructor is similar to \ref igraph_vector_init_int(), the only * difference is that instead of giving the number of elements in the * vector, a special marker element follows the last real vector * element. * \param v Pointer to an uninitialized \type igraph_vector_t object. * \param endmark This element will signal the end of the vector. It * will \em not be part of the vector. * \param ... The elements of the vector. * \return Error code, \c IGRAPH_ENOMEM if there * isn't enough memory. * * \sa \ref igraph_vector_init_int() and \ref igraph_vector_init_real_end() for * similar functions. * * Time complexity: at least O(n) for * n elements plus the time * complexity of the memory allocation. */ int FUNCTION(igraph_vector_init, int_end)(TYPE(igraph_vector) *v, int endmark, ...) { int i = 0, n = 0; va_list ap; va_start(ap, endmark); while (1) { int num = va_arg(ap, int); if (num == endmark) { break; } n++; } va_end(ap); IGRAPH_CHECK(FUNCTION(igraph_vector, init)(v, n)); IGRAPH_FINALLY(FUNCTION(igraph_vector, destroy), v); va_start(ap, endmark); for (i = 0; i < n; i++) { VECTOR(*v)[i] = (BASE) va_arg(ap, int); } va_end(ap); IGRAPH_FINALLY_CLEAN(1); return 0; } #endif /* ifndef BASE_COMPLEX */ /** * \ingroup vector * \function igraph_vector_destroy * \brief Destroys a vector object. * * * All vectors initialized by \ref igraph_vector_init() should be properly * destroyed by this function. A destroyed vector needs to be * reinitialized by \ref igraph_vector_init(), \ref igraph_vector_init_copy() or * another constructor. * \param v Pointer to the (previously initialized) vector object to * destroy. * * Time complexity: operating system dependent. */ void FUNCTION(igraph_vector, destroy) (TYPE(igraph_vector)* v) { IGRAPH_ASSERT(v != 0); if (v->stor_begin != 0) { IGRAPH_FREE(v->stor_begin); v->stor_begin = NULL; } } /** * \ingroup vector * \function igraph_vector_capacity * \brief Returns the allocated capacity of the vector * * Note that this might be different from the size of the vector (as * queried by \ref igraph_vector_size(), and specifies how many elements * the vector can hold, without reallocation. * \param v Pointer to the (previously initialized) vector object * to query. * \return The allocated capacity. * * \sa \ref igraph_vector_size(). * * Time complexity: O(1). */ long int FUNCTION(igraph_vector, capacity)(const TYPE(igraph_vector)*v) { return v->stor_end - v->stor_begin; } /** * \ingroup vector * \function igraph_vector_reserve * \brief Reserves memory for a vector. * * * \a igraph vectors are flexible, they can grow and * shrink. Growing * however occasionally needs the data in the vector to be copied. * In order to avoid this, you can call this function to reserve space for * future growth of the vector. * * * Note that this function does \em not change the size of the * vector. Let us see a small example to clarify things: if you * reserve space for 100 elements and the size of your * vector was (and still is) 60, then you can surely add additional 40 * elements to your vector before it will be copied. * \param v The vector object. * \param size The new \em allocated size of the vector. * \return Error code: * \c IGRAPH_ENOMEM if there is not enough memory. * * Time complexity: operating system dependent, should be around * O(n), n * is the new allocated size of the vector. */ int FUNCTION(igraph_vector, reserve) (TYPE(igraph_vector)* v, long int size) { long int actual_size = FUNCTION(igraph_vector, size)(v); BASE *tmp; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); if (size <= actual_size) { return 0; } tmp = IGRAPH_REALLOC(v->stor_begin, (size_t) size, BASE); if (tmp == 0) { IGRAPH_ERROR("cannot reserve space for vector", IGRAPH_ENOMEM); } v->stor_begin = tmp; v->stor_end = v->stor_begin + size; v->end = v->stor_begin + actual_size; return 0; } /** * \ingroup vector * \function igraph_vector_empty * \brief Decides whether the size of the vector is zero. * * \param v The vector object. * \return Non-zero number (true) if the size of the vector is zero and * zero (false) otherwise. * * Time complexity: O(1). */ igraph_bool_t FUNCTION(igraph_vector, empty) (const TYPE(igraph_vector)* v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); return v->stor_begin == v->end; } /** * \ingroup vector * \function igraph_vector_size * \brief Returns the size (=length) of the vector. * * \param v The vector object * \return The size of the vector. * * Time complexity: O(1). */ long int FUNCTION(igraph_vector, size) (const TYPE(igraph_vector)* v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); return v->end - v->stor_begin; } /** * \ingroup vector * \function igraph_vector_clear * \brief Removes all elements from a vector. * * * This function simply sets the size of the vector to zero, it does * not free any allocated memory. For that you have to call * \ref igraph_vector_destroy(). * \param v The vector object. * * Time complexity: O(1). */ void FUNCTION(igraph_vector, clear) (TYPE(igraph_vector)* v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); v->end = v->stor_begin; } /** * \ingroup vector * \function igraph_vector_push_back * \brief Appends one element to a vector. * * * This function resizes the vector to be one element longer and * sets the very last element in the vector to \p e. * \param v The vector object. * \param e The element to append to the vector. * \return Error code: * \c IGRAPH_ENOMEM: not enough memory. * * Time complexity: operating system dependent. What is important is that * a sequence of n * subsequent calls to this function has time complexity * O(n), even if there * hadn't been any space reserved for the new elements by * \ref igraph_vector_reserve(). This is implemented by a trick similar to the C++ * \type vector class: each time more memory is allocated for a * vector, the size of the additionally allocated memory is the same * as the vector's current length. (We assume here that the time * complexity of memory allocation is at most linear.) */ int FUNCTION(igraph_vector, push_back) (TYPE(igraph_vector)* v, BASE e) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); /* full, allocate more storage */ if (v->stor_end == v->end) { long int new_size = FUNCTION(igraph_vector, size)(v) * 2; if (new_size == 0) { new_size = 1; } IGRAPH_CHECK(FUNCTION(igraph_vector, reserve)(v, new_size)); } *(v->end) = e; v->end += 1; return 0; } /** * \ingroup vector * \function igraph_vector_insert * \brief Inserts a single element into a vector. * * Note that this function does not do range checking. Insertion will shift the * elements from the position given to the end of the vector one position to the * right, and the new element will be inserted in the empty space created at * the given position. The size of the vector will increase by one. * * \param v The vector object. * \param pos The position where the new element is to be inserted. * \param value The new element to be inserted. */ int FUNCTION(igraph_vector, insert)(TYPE(igraph_vector) *v, long int pos, BASE value) { size_t size = (size_t) FUNCTION(igraph_vector, size)(v); if (pos < 0) { return IGRAPH_EINVAL; } IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(v, (long) size + 1)); if (((unsigned long)pos) < size) { memmove(v->stor_begin + pos + 1, v->stor_begin + pos, sizeof(BASE) * (size - (size_t) pos)); } v->stor_begin[pos] = value; return 0; } /** * \ingroup vector * \section igraph_vector_accessing_elements Accessing elements * * The simplest way to access an element of a vector is to use the * \ref VECTOR macro. This macro can be used both for querying and setting * \type igraph_vector_t elements. If you need a function, \ref * igraph_vector_e() queries and \ref igraph_vector_set() sets an element of a * vector. \ref igraph_vector_e_ptr() returns the address of an element. * * \ref igraph_vector_tail() returns the last element of a non-empty * vector. There is no igraph_vector_head() function * however, as it is easy to write VECTOR(v)[0] * instead. */ /** * \ingroup vector * \function igraph_vector_e * \brief Access an element of a vector. * \param v The \type igraph_vector_t object. * \param pos The position of the element, the index of the first * element is zero. * \return The desired element. * \sa \ref igraph_vector_e_ptr() and the \ref VECTOR macro. * * Time complexity: O(1). */ BASE FUNCTION(igraph_vector, e) (const TYPE(igraph_vector)* v, long int pos) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); return * (v->stor_begin + pos); } /** * \ingroup vector * \function igraph_vector_e_ptr * \brief Get the address of an element of a vector * \param v The \type igraph_vector_t object. * \param pos The position of the element, the position of the first * element is zero. * \return Pointer to the desired element. * \sa \ref igraph_vector_e() and the \ref VECTOR macro. * * Time complexity: O(1). */ BASE* FUNCTION(igraph_vector, e_ptr) (const TYPE(igraph_vector)* v, long int pos) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); return v->stor_begin + pos; } /** * \ingroup vector * \function igraph_vector_set * \brief Assignment to an element of a vector. * \param v The \type igraph_vector_t element. * \param pos Position of the element to set. * \param value New value of the element. * \sa \ref igraph_vector_e(). */ void FUNCTION(igraph_vector, set) (TYPE(igraph_vector)* v, long int pos, BASE value) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); *(v->stor_begin + pos) = value; } /** * \ingroup vector * \function igraph_vector_null * \brief Sets each element in the vector to zero. * * * Note that \ref igraph_vector_init() sets the elements to zero as well, so * it makes no sense to call this function on a just initialized * vector. Thus if you want to construct a vector of zeros, then you should * use \ref igraph_vector_init(). * \param v The vector object. * * Time complexity: O(n), the size of * the vector. */ void FUNCTION(igraph_vector, null) (TYPE(igraph_vector)* v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); if (FUNCTION(igraph_vector, size)(v) > 0) { memset(v->stor_begin, 0, sizeof(BASE) * (size_t) FUNCTION(igraph_vector, size)(v)); } } /** * \function igraph_vector_fill * \brief Fill a vector with a constant element * * Sets each element of the vector to the supplied constant. * \param vector The vector to work on. * \param e The element to fill with. * * Time complexity: O(n), the size of the vector. */ void FUNCTION(igraph_vector, fill) (TYPE(igraph_vector)* v, BASE e) { BASE *ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); for (ptr = v->stor_begin; ptr < v->end; ptr++) { *ptr = e; } } /** * \ingroup vector * \function igraph_vector_tail * \brief Returns the last element in a vector. * * * It is an error to call this function on an empty vector, the result * is undefined. * \param v The vector object. * \return The last element. * * Time complexity: O(1). */ BASE FUNCTION(igraph_vector, tail)(const TYPE(igraph_vector) *v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); return *((v->end) - 1); } /** * \ingroup vector * \function igraph_vector_pop_back * \brief Removes and returns the last element of a vector. * * * It is an error to call this function with an empty vector. * \param v The vector object. * \return The removed last element. * * Time complexity: O(1). */ BASE FUNCTION(igraph_vector, pop_back)(TYPE(igraph_vector)* v) { BASE tmp; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_ASSERT(v->end != v->stor_begin); tmp = FUNCTION(igraph_vector, e)(v, FUNCTION(igraph_vector, size)(v) - 1); v->end -= 1; return tmp; } #ifndef NOTORDERED /** * \ingroup vector * \function igraph_vector_sort_cmp * \brief Internal comparison function of vector elements, used by * \ref igraph_vector_sort(). */ static int FUNCTION(igraph_vector, sort_cmp)(const void *a, const void *b) { const BASE *da = (const BASE *) a; const BASE *db = (const BASE *) b; return (*da > *db) - (*da < *db); } /** * \ingroup vector * \function igraph_vector_reverse_sort_cmp * \brief Internal comparison function of vector elements, used by * \ref igraph_vector_reverse_sort(). */ static int FUNCTION(igraph_vector, reverse_sort_cmp)(const void *a, const void *b) { const BASE *da = (const BASE *) a; const BASE *db = (const BASE *) b; return (*da < *db) - (*da > *db); } /** * \ingroup vector * \function igraph_vector_sort * \brief Sorts the elements of the vector into ascending order. * * * If the vector contains any NaN values, the resulting ordering of * NaN values is undefined and may appear anywhere in the vector. * \param v Pointer to an initialized vector object. * * Time complexity: * O(n log n) for n elements. */ void FUNCTION(igraph_vector, sort)(TYPE(igraph_vector) *v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); igraph_qsort(v->stor_begin, (size_t) FUNCTION(igraph_vector, size)(v), sizeof(BASE), FUNCTION(igraph_vector, sort_cmp)); } /** * \ingroup vector * \function igraph_vector_reverse_sort * \brief Sorts the elements of the vector into descending order. * * * If the vector contains any NaN values, the resulting ordering of * NaN values is undefined and may appear anywhere in the vector. * \param v Pointer to an initialized vector object. * * Time complexity: * O(n log n) for n elements. */ void FUNCTION(igraph_vector, reverse_sort)(TYPE(igraph_vector) *v) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); igraph_qsort(v->stor_begin, (size_t) FUNCTION(igraph_vector, size)(v), sizeof(BASE), FUNCTION(igraph_vector, reverse_sort_cmp)); } /** * Ascending comparison function passed to qsort from igraph_vector_qsort_ind */ static int FUNCTION(igraph_vector, i_qsort_ind_cmp_asc)(const void *p1, const void *p2) { BASE **pa = (BASE **) p1; BASE **pb = (BASE **) p2; if ( **pa < **pb ) { return -1; } if ( **pa > **pb) { return 1; } return 0; } /** * Descending comparison function passed to qsort from igraph_vector_qsort_ind */ static int FUNCTION(igraph_vector, i_qsort_ind_cmp_desc)(const void *p1, const void *p2) { BASE **pa = (BASE **) p1; BASE **pb = (BASE **) p2; if ( **pa < **pb ) { return 1; } if ( **pa > **pb) { return -1; } return 0; } /** * \function igraph_vector_qsort_ind * \brief Return a permutation of indices that sorts a vector * * Takes an unsorted array \c v as input and computes an array of * indices inds such that v[ inds[i] ], with i increasing from 0, is * an ordered array (either ascending or descending, depending on * \v order). The order of indices for identical elements is not * defined. If the vector contains any NaN values, the ordering of * NaN values is undefined. * * \param v the array to be sorted * \param inds the output array of indices. This must be initialized, * but will be resized * \param descending whether the output array should be sorted in descending * order. * \return Error code. * * This routine uses igraph's built-in qsort routine. * Algorithm: 1) create an array of pointers to the elements of v. 2) * Pass this array to qsort. 3) after sorting the difference between * the pointer value and the first pointer value gives its original * position in the array. Use this to set the values of inds. */ long int FUNCTION(igraph_vector, qsort_ind)(TYPE(igraph_vector) *v, igraph_vector_t *inds, igraph_bool_t descending) { unsigned long int i; BASE **vind, *first; size_t n = (size_t) FUNCTION(igraph_vector, size)(v); IGRAPH_CHECK(igraph_vector_resize(inds, (long) n)); if (n == 0) { return 0; } vind = IGRAPH_CALLOC(n, BASE*); if (vind == 0) { IGRAPH_ERROR("igraph_vector_qsort_ind failed", IGRAPH_ENOMEM); } for (i = 0; i < n; i++) { vind[i] = &VECTOR(*v)[i]; } first = vind[0]; if (descending) { igraph_qsort(vind, n, sizeof(BASE**), FUNCTION(igraph_vector, i_qsort_ind_cmp_desc)); } else { igraph_qsort(vind, n, sizeof(BASE**), FUNCTION(igraph_vector, i_qsort_ind_cmp_asc)); } for (i = 0; i < n; i++) { VECTOR(*inds)[i] = vind[i] - first; } IGRAPH_FREE(vind); return 0; } /** * \function igraph_vector_lex_cmp * \brief Lexicographical comparison of two vectors. * * * If the elements of two vectors match but one is shorter, the shorter * one comes first. Thus {1, 3} comes after {1, 2, 3}, but before {1, 3, 4}. * * * This function is typically used together with \ref igraph_vector_ptr_sort(). * * \param lhs Pointer to a pointer to the first vector (interpreted as an igraph_vector_t **). * \param rhs Pointer to a pointer to the second vector (interpreted as an igraph_vector_t **). * \return -1 if \p lhs is lexicographically smaller, * 0 if \p lhs and \p rhs are equal, else 1. * \sa \ref igraph_vector_colex_cmp() to compare vectors starting from * the last element. * * Time complexity: O(n), the number of elements in the smaller vector. * * \example examples/simple/igraph_vector_ptr_sort.c */ int FUNCTION(igraph_vector, lex_cmp)(const void *lhs, const void *rhs) { const TYPE(igraph_vector) *a = * (TYPE(igraph_vector) **) lhs; const TYPE(igraph_vector) *b = * (TYPE(igraph_vector) **) rhs; long int i, sa, sb; sa = FUNCTION(igraph_vector, size)(a); sb = FUNCTION(igraph_vector, size)(b); for (i = 0; i < sa; i++) { if (i >= sb) { /* b is shorter, and equal to the first part of a */ return 1; } if (VECTOR(*a)[i] < VECTOR(*b)[i]) { return -1; } if (VECTOR(*a)[i] > VECTOR(*b)[i]) { return 1; } } if (i == sb) { return 0; } /* a is shorter, and equal to the first part of b */ return -1; } /** * \function igraph_vector_colex_cmp * \brief Colexicographical comparison of two vectors. * * * This comparison starts from the last element of both vectors and * moves backward. If the elements of two vectors match but one is * shorter, the shorter one comes first. Thus {1, 2} comes after {3, 2, 1}, * but before {0, 1, 2}. * * * This function is typically used together with \ref igraph_vector_ptr_sort(). * * \param lhs Pointer to a pointer to the first vector (interpreted as an igraph_vector_t **). * \param rhs Pointer to a pointer to the second vector (interpreted as an igraph_vector_t **). * \return -1 if \p lhs in reverse order is * lexicographically smaller than the reverse of \p rhs, * 0 if \p lhs and \p rhs are equal, else 1. * \sa \ref igraph_vector_lex_cmp() to compare vectors starting from * the first element. * * Time complexity: O(n), the number of elements in the smaller vector. * * \example examples/simple/igraph_vector_ptr_sort.c */ int FUNCTION(igraph_vector, colex_cmp)(const void *lhs, const void *rhs) { const TYPE(igraph_vector) *a = * (TYPE(igraph_vector) **) lhs; const TYPE(igraph_vector) *b = * (TYPE(igraph_vector) **) rhs; long int i, sa, sb, rai, rbi; sa = FUNCTION(igraph_vector, size)(a); sb = FUNCTION(igraph_vector, size)(b); for (i = 0; i < sa; i++) { if (i >= sb) { /* b is shorter, and equal to the last part of a */ return 1; } /* use reversed indexes */ rai = sa - i - 1; rbi = sb - i - 1; if (VECTOR(*a)[rai] < VECTOR(*b)[rbi]) { return -1; } if (VECTOR(*a)[rai] > VECTOR(*b)[rbi]) { return 1; } } if (i == sb) { return 0; } /* a is shorter, and equal to the last part of b */ return -1; } #endif /*NOTORDERED*/ /** * \ingroup vector * \function igraph_vector_resize * \brief Resize the vector. * * * Note that this function does not free any memory, just sets the * size of the vector to the given one. It can on the other hand * allocate more memory if the new size is larger than the previous * one. In this case the newly appeared elements in the vector are * \em not set to zero, they are uninitialized. * \param v The vector object * \param newsize The new size of the vector. * \return Error code, * \c IGRAPH_ENOMEM if there is not enough * memory. Note that this function \em never returns an error * if the vector is made smaller. * \sa \ref igraph_vector_reserve() for allocating memory for future * extensions of a vector. \ref igraph_vector_resize_min() for * deallocating the unnneded memory for a vector. * * Time complexity: O(1) if the new * size is smaller, operating system dependent if it is larger. In the * latter case it is usually around * O(n), * n is the new size of the vector. */ int FUNCTION(igraph_vector, resize)(TYPE(igraph_vector)* v, long int newsize) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_CHECK(FUNCTION(igraph_vector, reserve)(v, newsize)); v->end = v->stor_begin + newsize; return 0; } /** * \ingroup vector * \function igraph_vector_resize_min * \brief Deallocate the unused memory of a vector. * * * Note that this function involves additional memory allocation and * may result an out-of-memory error. * \param v Pointer to an initialized vector. * \return Error code. * * \sa \ref igraph_vector_resize(), \ref igraph_vector_reserve(). * * Time complexity: operating system dependent. */ int FUNCTION(igraph_vector, resize_min)(TYPE(igraph_vector)*v) { size_t size; BASE *tmp; if (v->stor_end == v->end) { return 0; } size = (size_t) (v->end - v->stor_begin); tmp = IGRAPH_REALLOC(v->stor_begin, size, BASE); if (tmp == 0) { IGRAPH_ERROR("cannot resize vector", IGRAPH_ENOMEM); } else { v->stor_begin = tmp; v->stor_end = v->end = v->stor_begin + size; } return 0; } #ifndef NOTORDERED /* We will use x != x for NaN checks below and Clang does not like it unless * we disable a warning */ #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wtautological-compare" #endif /** * \ingroup vector * \function igraph_vector_max * \brief Largest element of a vector. * * * If the size of the vector is zero, an arbitrary number is * returned. * \param v The vector object. * \return The maximum element of \p v, or NaN if any element is NaN. * * Time complexity: O(n), the number of elements. */ BASE FUNCTION(igraph_vector, max)(const TYPE(igraph_vector)* v) { BASE max; BASE *ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_ASSERT(v->stor_begin != v->end); max = *(v->stor_begin); #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) if (igraph_is_nan(max)) { return max; }; /* Result is NaN */ #endif ptr = v->stor_begin + 1; while (ptr < v->end) { if ((*ptr) > max) { max = *ptr; } #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) else if (igraph_is_nan(*ptr)) return *ptr; /* Result is NaN */ #endif ptr++; } return max; } /** * \ingroup vector * \function igraph_vector_which_max * \brief Gives the index of the maximum element of the vector. * * * If the size of the vector is zero, -1 is returned. If the largest * element is not unique, then the index of the first is returned. * If the vector contains NaN values, the index of the first NaN value * is returned. * \param v The vector object. * \return The index of the first maximum element. * * Time complexity: O(n), n is the size of the vector. */ long int FUNCTION(igraph_vector, which_max)(const TYPE(igraph_vector)* v) { if (!FUNCTION(igraph_vector, empty)(v)) { BASE *max; BASE *ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_ASSERT(v->stor_begin != v->end); max = ptr = v->stor_begin; #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) if (igraph_is_nan(*ptr)) { return ptr - v->stor_begin; } /* Result is NaN */ #endif ptr++; while (ptr < v->end) { if (*ptr > *max) { max = ptr; } #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) else if (igraph_is_nan(*ptr)) { return ptr - v->stor_begin; /* Result is NaN */ } #endif ptr++; } return max - v->stor_begin; } return -1; } /** * \ingroup vector * \function igraph_vector_min * \brief Smallest element of a vector. * * The vector must be non-empty. * \param v The input vector. * \return The smallest element of \p v, or NaN if any element is NaN. * * Time complexity: O(n), the number of elements. */ BASE FUNCTION(igraph_vector, min)(const TYPE(igraph_vector)* v) { BASE min; BASE *ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_ASSERT(v->stor_begin != v->end); min = *(v->stor_begin); #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) if (igraph_is_nan(min)) { return min; }; /* Result is NaN */ #endif ptr = v->stor_begin + 1; while (ptr < v->end) { if ((*ptr) < min) { min = *ptr; } #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) else if (igraph_is_nan(*ptr)) { return *ptr; /* Result is NaN */ } #endif ptr++; } return min; } /** * \ingroup vector * \function igraph_vector_which_min * \brief Index of the smallest element. * * * The vector must be non-empty. If the smallest element is not unique, * then the index of the first is returned. If the vector contains NaN * values, the index of the first NaN value is returned. * \param v The input vector. * \return Index of the smallest element. * * Time complexity: O(n), the number of elements. */ long int FUNCTION(igraph_vector, which_min)(const TYPE(igraph_vector)* v) { if (!FUNCTION(igraph_vector, empty)(v)) { BASE *min; BASE *ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_ASSERT(v->stor_begin != v->end); min = ptr = v->stor_begin; #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) if (igraph_is_nan(*ptr)) { return ptr - v->stor_begin; } /* Result is NaN */ #endif ptr++; while (ptr < v->end) { if (*ptr < *min) { min = ptr; } #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) else if (igraph_is_nan(*ptr)) { return ptr - v->stor_begin; /* Result is NaN */ } #endif ptr++; } return min - v->stor_begin; } return -1; } #ifdef __clang__ #pragma clang diagnostic pop #endif #endif /** * \ingroup vector * \function igraph_vector_init_copy * \brief Initializes a vector from an ordinary C array (constructor). * * \param v Pointer to an uninitialized vector object. * \param data A regular C array. * \param length The length of the C array. * \return Error code: * \c IGRAPH_ENOMEM if there is not enough memory. * * Time complexity: operating system specific, usually * O(\p length). */ int FUNCTION(igraph_vector, init_copy)(TYPE(igraph_vector) *v, const BASE *data, long int length) { v->stor_begin = IGRAPH_CALLOC(length, BASE); if (v->stor_begin == 0) { IGRAPH_ERROR("cannot init vector from array", IGRAPH_ENOMEM); } v->stor_end = v->stor_begin + length; v->end = v->stor_end; memcpy(v->stor_begin, data, (size_t) length * sizeof(BASE)); return 0; } /** * \ingroup vector * \function igraph_vector_copy_to * \brief Copies the contents of a vector to a C array. * * * The C array should have sufficient length. * \param v The vector object. * \param to The C array. * * Time complexity: O(n), * n is the size of the vector. */ void FUNCTION(igraph_vector, copy_to)(const TYPE(igraph_vector) *v, BASE *to) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); if (v->end != v->stor_begin) { memcpy(to, v->stor_begin, sizeof(BASE) * (size_t) (v->end - v->stor_begin)); } } /** * \ingroup vector * \function igraph_vector_copy * \brief Initializes a vector from another vector object (constructor). * * * The contents of the existing vector object will be copied to * the new one. * \param to Pointer to a not yet initialized vector object. * \param from The original vector object to copy. * \return Error code: * \c IGRAPH_ENOMEM if there is not enough memory. * * Time complexity: operating system dependent, usually * O(n), * n is the size of the vector. */ int FUNCTION(igraph_vector, copy)(TYPE(igraph_vector) *to, const TYPE(igraph_vector) *from) { long int from_size; IGRAPH_ASSERT(from != NULL); IGRAPH_ASSERT(from->stor_begin != NULL); from_size = FUNCTION(igraph_vector, size)(from); to->stor_begin = IGRAPH_CALLOC(from_size, BASE); if (to->stor_begin == 0) { IGRAPH_ERROR("cannot copy vector", IGRAPH_ENOMEM); } to->stor_end = to->stor_begin + FUNCTION(igraph_vector, size)(from); to->end = to->stor_end; memcpy(to->stor_begin, from->stor_begin, (size_t) FUNCTION(igraph_vector, size)(from) * sizeof(BASE)); return 0; } /** * \ingroup vector * \function igraph_vector_sum * \brief Calculates the sum of the elements in the vector. * * * For the empty vector 0.0 is returned. * \param v The vector object. * \return The sum of the elements. * * Time complexity: O(n), the size of * the vector. */ BASE FUNCTION(igraph_vector, sum)(const TYPE(igraph_vector) *v) { BASE res = ZERO; BASE *p; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); for (p = v->stor_begin; p < v->end; p++) { #ifdef SUM SUM(res, res, *p); #else res += *p; #endif } return res; } igraph_real_t FUNCTION(igraph_vector, sumsq)(const TYPE(igraph_vector) *v) { igraph_real_t res = 0.0; BASE *p; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); for (p = v->stor_begin; p < v->end; p++) { #ifdef SQ res += SQ(*p); #else res += (*p) * (*p); #endif } return res; } /** * \ingroup vector * \function igraph_vector_prod * \brief Calculates the product of the elements in the vector. * * * For the empty vector one (1) is returned. * \param v The vector object. * \return The product of the elements. * * Time complexity: O(n), the size of * the vector. */ BASE FUNCTION(igraph_vector, prod)(const TYPE(igraph_vector) *v) { BASE res = ONE; BASE *p; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); for (p = v->stor_begin; p < v->end; p++) { #ifdef PROD PROD(res, res, *p); #else res *= *p; #endif } return res; } /** * \ingroup vector * \function igraph_vector_cumsum * \brief Calculates the cumulative sum of the elements in the vector. * * * \param to An initialized vector object that will store the cumulative * sums. Element i of this vector will store the sum of the elements * of the 'from' vector, up to and including element i. * \param from The input vector. * \return Error code. * * Time complexity: O(n), the size of the vector. */ int FUNCTION(igraph_vector, cumsum)(TYPE(igraph_vector) *to, const TYPE(igraph_vector) *from) { BASE res = ZERO; BASE *p, *p2; IGRAPH_ASSERT(from != NULL); IGRAPH_ASSERT(from->stor_begin != NULL); IGRAPH_ASSERT(to != NULL); IGRAPH_ASSERT(to->stor_begin != NULL); IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(to, FUNCTION(igraph_vector, size)(from))); for (p = from->stor_begin, p2 = to->stor_begin; p < from->end; p++, p2++) { #ifdef SUM SUM(res, res, *p); #else res += *p; #endif *p2 = res; } return 0; } #ifndef NOTORDERED /** * \ingroup vector * \function igraph_vector_init_seq * \brief Initializes a vector with a sequence. * * * The vector will contain the numbers \p from, * \p from+1, ..., \p to. * \param v Pointer to an uninitialized vector object. * \param from The lower limit in the sequence (inclusive). * \param to The upper limit in the sequence (inclusive). * \return Error code: * \c IGRAPH_ENOMEM: out of memory. * * Time complexity: O(n), the number * of elements in the vector. */ int FUNCTION(igraph_vector, init_seq)(TYPE(igraph_vector) *v, BASE from, BASE to) { BASE *p; IGRAPH_CHECK(FUNCTION(igraph_vector, init)(v, (long int) (to - from + 1))); for (p = v->stor_begin; p < v->end; p++) { *p = from++; } return 0; } #endif /** * \ingroup vector * \function igraph_vector_remove_section * \brief Deletes a section from a vector. * * * Note that this function does not do range checking. The result is * undefined if you supply invalid limits. * \param v The vector object. * \param from The position of the first element to remove. * \param to The position of the first element \em not to remove. * * Time complexity: O(n-from), * n is the number of elements in the * vector. */ void FUNCTION(igraph_vector, remove_section)(TYPE(igraph_vector) *v, long int from, long int to) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); /* Not removing from the end? */ if (to < FUNCTION(igraph_vector, size)(v)) { memmove(v->stor_begin + from, v->stor_begin + to, sizeof(BASE) * (size_t) (v->end - v->stor_begin - to)); } v->end -= (to - from); } /** * \ingroup vector * \function igraph_vector_remove * \brief Removes a single element from a vector. * * Note that this function does not do range checking. * \param v The vector object. * \param elem The position of the element to remove. * * Time complexity: O(n-elem), * n is the number of elements in the * vector. */ void FUNCTION(igraph_vector, remove)(TYPE(igraph_vector) *v, long int elem) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); FUNCTION(igraph_vector, remove_section)(v, elem, elem + 1); } /** * \ingroup vector * \function igraph_vector_move_interval * \brief Copies a section of a vector. * * * The result of this function is undefined if the source and target * intervals overlap. * \param v The vector object. * \param begin The position of the first element to move. * \param end The position of the first element \em not to move. * \param to The target position. * \return Error code, the current implementation always returns with * success. * * Time complexity: O(end-begin). */ int FUNCTION(igraph_vector, move_interval)(TYPE(igraph_vector) *v, long int begin, long int end, long int to) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); memcpy(v->stor_begin + to, v->stor_begin + begin, sizeof(BASE) * (size_t) (end - begin)); return 0; } int FUNCTION(igraph_vector, move_interval2)(TYPE(igraph_vector) *v, long int begin, long int end, long int to) { IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); memmove(v->stor_begin + to, v->stor_begin + begin, sizeof(BASE) * (size_t) (end - begin)); return 0; } /** * \ingroup vector * \function igraph_vector_permdelete * \brief Remove elements of a vector (for internal use). */ void FUNCTION(igraph_vector, permdelete)(TYPE(igraph_vector) *v, const igraph_vector_t *index, long int nremove) { long int i, n; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); n = FUNCTION(igraph_vector, size)(v); for (i = 0; i < n; i++) { if (VECTOR(*index)[i] != 0) { VECTOR(*v)[ (long int)VECTOR(*index)[i] - 1 ] = VECTOR(*v)[i]; } } v->end -= nremove; } #ifndef NOTORDERED /** * \ingroup vector * \function igraph_vector_isininterval * \brief Checks if all elements of a vector are in the given * interval. * * \param v The vector object. * \param low The lower limit of the interval (inclusive). * \param high The higher limit of the interval (inclusive). * \return True (positive integer) if all vector elements are in the * interval, false (zero) otherwise. If any element is NaN, it will * return \c 0 (=false). * * Time complexity: O(n), the number * of elements in the vector. */ igraph_bool_t FUNCTION(igraph_vector, isininterval)(const TYPE(igraph_vector) *v, BASE low, BASE high) { BASE *ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); for (ptr = v->stor_begin; ptr < v->end; ptr++) { if (!(*ptr >= low && *ptr <= high)) { return 0; } } return 1; } /** * \ingroup vector * \function igraph_vector_any_smaller * \brief Checks if any element of a vector is smaller than a limit. * * \param v The \type igraph_vector_t object. * \param limit The limit. * \return True (positive integer) if the vector contains at least one * smaller element than \p limit, false (zero) * otherwise. * * Time complexity: O(n), the number * of elements in the vector. */ igraph_bool_t FUNCTION(igraph_vector, any_smaller)(const TYPE(igraph_vector) *v, BASE limit) { BASE *ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); for (ptr = v->stor_begin; ptr < v->end; ptr++) { if (*ptr < limit) { return 1; } } return 0; } #endif /** * \ingroup vector * \function igraph_vector_all_e * \brief Are all elements equal? * * \param lhs The first vector. * \param rhs The second vector. * \return Positive integer (=true) if the elements in the \p lhs are all * equal to the corresponding elements in \p rhs. Returns \c 0 * (=false) if the lengths of the vectors don't match. * * Time complexity: O(n), the length of the vectors. */ igraph_bool_t FUNCTION(igraph_vector, all_e)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs) { long int i, s; IGRAPH_ASSERT(lhs != 0); IGRAPH_ASSERT(rhs != 0); IGRAPH_ASSERT(lhs->stor_begin != 0); IGRAPH_ASSERT(rhs->stor_begin != 0); s = FUNCTION(igraph_vector, size)(lhs); if (s != FUNCTION(igraph_vector, size)(rhs)) { return 0; } else { for (i = 0; i < s; i++) { BASE l = VECTOR(*lhs)[i]; BASE r = VECTOR(*rhs)[i]; #ifdef EQ if (!EQ(l, r)) { #else if (l != r) { #endif return 0; } } return 1; } } igraph_bool_t FUNCTION(igraph_vector, is_equal)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs) { return FUNCTION(igraph_vector, all_e)(lhs, rhs); } #ifndef NOTORDERED /** * \ingroup vector * \function igraph_vector_all_l * \brief Are all elements less? * * \param lhs The first vector. * \param rhs The second vector. * \return Positive integer (=true) if the elements in the \p lhs are all * less than the corresponding elements in \p rhs. Returns \c 0 * (=false) if the lengths of the vectors don't match. If any element * is NaN, it will return \c 0 (=false). * * Time complexity: O(n), the length of the vectors. */ igraph_bool_t FUNCTION(igraph_vector, all_l)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs) { long int i, s; IGRAPH_ASSERT(lhs != 0); IGRAPH_ASSERT(rhs != 0); IGRAPH_ASSERT(lhs->stor_begin != 0); IGRAPH_ASSERT(rhs->stor_begin != 0); s = FUNCTION(igraph_vector, size)(lhs); if (s != FUNCTION(igraph_vector, size)(rhs)) { return 0; } else { for (i = 0; i < s; i++) { BASE l = VECTOR(*lhs)[i]; BASE r = VECTOR(*rhs)[i]; if (l >= r) { return 0; } } return 1; } } /** * \ingroup vector * \function igraph_vector_all_g * \brief Are all elements greater? * * \param lhs The first vector. * \param rhs The second vector. * \return Positive integer (=true) if the elements in the \p lhs are all * greater than the corresponding elements in \p rhs. Returns \c 0 * (=false) if the lengths of the vectors don't match. If any element * is NaN, it will return \c 0 (=false). * * Time complexity: O(n), the length of the vectors. */ igraph_bool_t FUNCTION(igraph_vector, all_g)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs) { long int i, s; IGRAPH_ASSERT(lhs != 0); IGRAPH_ASSERT(rhs != 0); IGRAPH_ASSERT(lhs->stor_begin != 0); IGRAPH_ASSERT(rhs->stor_begin != 0); s = FUNCTION(igraph_vector, size)(lhs); if (s != FUNCTION(igraph_vector, size)(rhs)) { return 0; } else { for (i = 0; i < s; i++) { BASE l = VECTOR(*lhs)[i]; BASE r = VECTOR(*rhs)[i]; if (l <= r) { return 0; } } return 1; } } /** * \ingroup vector * \function igraph_vector_all_le * \brief Are all elements less or equal? * * \param lhs The first vector. * \param rhs The second vector. * \return Positive integer (=true) if the elements in the \p lhs are all * less than or equal to the corresponding elements in \p * rhs. Returns \c 0 (=false) if the lengths of the vectors don't * match. If any element is NaN, it will return \c 0 (=false). * * Time complexity: O(n), the length of the vectors. */ igraph_bool_t FUNCTION(igraph_vector, all_le)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs) { long int i, s; IGRAPH_ASSERT(lhs != 0); IGRAPH_ASSERT(rhs != 0); IGRAPH_ASSERT(lhs->stor_begin != 0); IGRAPH_ASSERT(rhs->stor_begin != 0); s = FUNCTION(igraph_vector, size)(lhs); if (s != FUNCTION(igraph_vector, size)(rhs)) { return 0; } else { for (i = 0; i < s; i++) { BASE l = VECTOR(*lhs)[i]; BASE r = VECTOR(*rhs)[i]; if (l > r) { return 0; } } return 1; } } /** * \ingroup vector * \function igraph_vector_all_ge * \brief Are all elements greater or equal? * * \param lhs The first vector. * \param rhs The second vector. * \return Positive integer (=true) if the elements in the \p lhs are all * greater than or equal to the corresponding elements in \p * rhs. Returns \c 0 (=false) if the lengths of the vectors don't * match. If any element is NaN, it will return \c 0 (=false). * * Time complexity: O(n), the length of the vectors. */ igraph_bool_t FUNCTION(igraph_vector, all_ge)(const TYPE(igraph_vector) *lhs, const TYPE(igraph_vector) *rhs) { long int i, s; IGRAPH_ASSERT(lhs != 0); IGRAPH_ASSERT(rhs != 0); IGRAPH_ASSERT(lhs->stor_begin != 0); IGRAPH_ASSERT(rhs->stor_begin != 0); s = FUNCTION(igraph_vector, size)(lhs); if (s != FUNCTION(igraph_vector, size)(rhs)) { return 0; } else { for (i = 0; i < s; i++) { BASE l = VECTOR(*lhs)[i]; BASE r = VECTOR(*rhs)[i]; if (l < r) { return 0; } } return 1; } } #endif #ifndef NOTORDERED igraph_bool_t FUNCTION(igraph_i_vector, binsearch_slice)(const TYPE(igraph_vector) *v, BASE what, long int *pos, long int start, long int end); /** * \ingroup vector * \function igraph_vector_binsearch * \brief Finds an element by binary searching a sorted vector. * * * It is assumed that the vector is sorted. If the specified element * (\p what) is not in the vector, then the * position of where it should be inserted (to keep the vector sorted) * is returned. If the vector contains any NaN values, the returned * value is undefined and \p pos may point to any position. * \param v The \type igraph_vector_t object. * \param what The element to search for. * \param pos Pointer to a \type long int. This is set to the * position of an instance of \p what in the * vector if it is present. If \p v does not * contain \p what then * \p pos is set to the position to which it * should be inserted (to keep the the vector sorted of course). * \return Positive integer (true) if \p what is * found in the vector, zero (false) otherwise. * * Time complexity: O(log(n)), * n is the number of elements in * \p v. */ igraph_bool_t FUNCTION(igraph_vector, binsearch)(const TYPE(igraph_vector) *v, BASE what, long int *pos) { return FUNCTION(igraph_i_vector, binsearch_slice)(v, what, pos, 0, FUNCTION(igraph_vector, size)(v)); } /** * \ingroup vector * \function igraph_vector_binsearch_slice * \brief Finds an element by binary searching a sorted slice of a vector. * * * It is assumed that the indicated slice of the vector, from \p start to \p end, * is sorted. If the specified element (\p what) is not in the slice of the * vector, then the position of where it should be inserted (to keep the vector * sorted) is returned. If the indicated slice contains any NaN values, the * returned value is undefined and \c pos may point to any position within * the slice. * \param v The \type igraph_vector_t object. * \param what The element to search for. * \param pos Pointer to a \type long int. This is set to the position of an * instance of \p what in the slice of the vector if it is present. If \p * v does not contain \p what then \p pos is set to the position to which * it should be inserted (to keep the the vector sorted). * \param start The start position of the slice to search (inclusive). * \param end The end position of the slice to search (exclusive). * \return Positive integer (true) if \p what is found in the vector, * zero (false) otherwise. * * Time complexity: O(log(n)), * n is the number of elements in the slice of \p v, i.e. \p end - \p start. */ igraph_bool_t FUNCTION(igraph_vector, binsearch_slice)(const TYPE(igraph_vector) *v, BASE what, long int *pos, long int start, long int end) { long int left = start; long int right = end - 1; if (left < 0) IGRAPH_ERROR("Invalid start position.", IGRAPH_EINVAL); if (right >= FUNCTION(igraph_vector, size)(v)) IGRAPH_ERROR("Invalid end position.", IGRAPH_EINVAL); if (left > right) IGRAPH_ERROR("Invalid slice, start position must be smaller than end position.", IGRAPH_EINVAL); return FUNCTION(igraph_i_vector, binsearch_slice)(v, what, pos, start, end); } igraph_bool_t FUNCTION(igraph_i_vector, binsearch_slice)(const TYPE(igraph_vector) *v, BASE what, long int *pos, long int start, long int end) { long int left = start; long int right = end - 1; while (left <= right) { /* (right + left) / 2 could theoretically overflow for long vectors */ long int middle = left + ((right - left) >> 1); if (VECTOR(*v)[middle] > what) { right = middle - 1; } else if (VECTOR(*v)[middle] < what) { left = middle + 1; } else { if (pos != 0) { *pos = middle; } return 1; } } /* if we are here, the element was not found */ if (pos != 0) { *pos = left; } return 0; } /** * \ingroup vector * \function igraph_vector_binsearch2 * \brief Binary search, without returning the index. * * * It is assumed that the vector is sorted. * \param v The \type igraph_vector_t object. * \param what The element to search for. * \return Positive integer (true) if \p what is * found in the vector, zero (false) otherwise. * * Time complexity: O(log(n)), * n is the number of elements in * \p v. */ igraph_bool_t FUNCTION(igraph_vector, binsearch2)(const TYPE(igraph_vector) *v, BASE what) { long int left = 0; long int right = FUNCTION(igraph_vector, size)(v) - 1; while (left <= right) { /* (right + left) / 2 could theoretically overflow for long vectors */ long int middle = left + ((right - left) >> 1); if (what < VECTOR(*v)[middle]) { right = middle - 1; } else if (what > VECTOR(*v)[middle]) { left = middle + 1; } else { return 1; } } return 0; } #endif /** * \function igraph_vector_scale * \brief Multiply all elements of a vector by a constant * * \param v The vector. * \param by The constant. * \return Error code. The current implementation always returns with success. * * Added in version 0.2. * * Time complexity: O(n), the number of elements in a vector. */ void FUNCTION(igraph_vector, scale)(TYPE(igraph_vector) *v, BASE by) { long int i; for (i = 0; i < FUNCTION(igraph_vector, size)(v); i++) { #ifdef PROD PROD(VECTOR(*v)[i], VECTOR(*v)[i], by); #else VECTOR(*v)[i] *= by; #endif } } /** * \function igraph_vector_add_constant * \brief Add a constant to the vector. * * \p plus is added to every element of \p v. Note that overflow * might happen. * \param v The input vector. * \param plus The constant to add. * * Time complexity: O(n), the number of elements. */ void FUNCTION(igraph_vector, add_constant)(TYPE(igraph_vector) *v, BASE plus) { long int i, n = FUNCTION(igraph_vector, size)(v); for (i = 0; i < n; i++) { #ifdef SUM SUM(VECTOR(*v)[i], VECTOR(*v)[i], plus); #else VECTOR(*v)[i] += plus; #endif } } /** * \function igraph_vector_contains * \brief Linear search in a vector. * * Check whether the supplied element is included in the vector, by * linear search. * \param v The input vector. * \param e The element to look for. * \return \c TRUE if the element is found and \c FALSE otherwise. * * Time complexity: O(n), the length of the vector. */ igraph_bool_t FUNCTION(igraph_vector, contains)(const TYPE(igraph_vector) *v, BASE e) { BASE *p = v->stor_begin; while (p < v->end) { #ifdef EQ if (EQ(*p, e)) { #else if (*p == e) { #endif return 1; } p++; } return 0; } /** * \function igraph_vector_search * \brief Search from a given position * * The supplied element \p what is searched in vector \p v, starting * from element index \p from. If found then the index of the first * instance (after \p from) is stored in \p pos. * \param v The input vector. * \param from The index to start searching from. No range checking is * performed. * \param what The element to find. * \param pos If not \c NULL then the index of the found element is * stored here. * \return Boolean, \c TRUE if the element was found, \c FALSE * otherwise. * * Time complexity: O(m), the number of elements to search, the length * of the vector minus the \p from argument. */ igraph_bool_t FUNCTION(igraph_vector, search)(const TYPE(igraph_vector) *v, long int from, BASE what, long int *pos) { long int i, n = FUNCTION(igraph_vector, size)(v); for (i = from; i < n; i++) { #ifdef EQ if (EQ(VECTOR(*v)[i], what)) { break; } #else if (VECTOR(*v)[i] == what) { break; } #endif } if (i < n) { if (pos != 0) { *pos = i; } return 1; } else { return 0; } } #ifndef NOTORDERED /** * \function igraph_vector_filter_smaller * \ingroup internal */ int FUNCTION(igraph_vector, filter_smaller)(TYPE(igraph_vector) *v, BASE elem) { long int i = 0, n = FUNCTION(igraph_vector, size)(v); long int s; while (i < n && VECTOR(*v)[i] < elem) { i++; } s = i; while (s < n && VECTOR(*v)[s] == elem) { s++; } FUNCTION(igraph_vector, remove_section)(v, 0, i + (s - i) / 2); return 0; } #endif /** * \function igraph_vector_append * \brief Append a vector to another one. * * The target vector will be resized (except when \p from is empty). * \param to The vector to append to. * \param from The vector to append, it is kept unchanged. * \return Error code. * * Time complexity: O(n), the number of elements in the new vector. */ int FUNCTION(igraph_vector, append)(TYPE(igraph_vector) *to, const TYPE(igraph_vector) *from) { long tosize, fromsize; tosize = FUNCTION(igraph_vector, size)(to); fromsize = FUNCTION(igraph_vector, size)(from); IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(to, tosize + fromsize)); memcpy(to->stor_begin + tosize, from->stor_begin, sizeof(BASE) * (size_t) fromsize); to->end = to->stor_begin + tosize + fromsize; return 0; } /** * \function igraph_vector_get_interval */ int FUNCTION(igraph_vector, get_interval)(const TYPE(igraph_vector) *v, TYPE(igraph_vector) *res, long int from, long int to) { IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(res, to - from)); memcpy(res->stor_begin, v->stor_begin + from, (size_t) (to - from) * sizeof(BASE)); return 0; } #ifndef NOTORDERED /** * \function igraph_vector_maxdifference * \brief The maximum absolute difference of \p m1 and \p m2 * * The element with the largest absolute value in \p m1 - \p m2 is * returned. Both vectors must be non-empty, but they not need to have * the same length, the extra elements in the longer vector are ignored. If * any value is NaN in the shorter vector, the result will be NaN. * \param m1 The first vector. * \param m2 The second vector. * \return The maximum absolute difference of \p m1 and \p m2. * * Time complexity: O(n), the number of elements in the shorter * vector. */ igraph_real_t FUNCTION(igraph_vector, maxdifference)(const TYPE(igraph_vector) *m1, const TYPE(igraph_vector) *m2) { long int n1 = FUNCTION(igraph_vector, size)(m1); long int n2 = FUNCTION(igraph_vector, size)(m2); long int n = n1 < n2 ? n1 : n2; long int i; igraph_real_t diff = 0.0; for (i = 0; i < n; i++) { igraph_real_t d = fabs((igraph_real_t)(VECTOR(*m1)[i]) - (igraph_real_t)(VECTOR(*m2)[i])); if (d > diff) { diff = d; } #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) else if (igraph_is_nan(d)) { /* Result is NaN */ return d; }; #endif } return diff; } #endif /** * \function igraph_vector_update * \brief Update a vector from another one. * * After this operation the contents of \p to will be exactly the same * as that of \p from. The vector \p to will be resized if it was originally * shorter or longer than \p from. * \param to The vector to update. * \param from The vector to update from. * \return Error code. * * Time complexity: O(n), the number of elements in \p from. */ int FUNCTION(igraph_vector, update)(TYPE(igraph_vector) *to, const TYPE(igraph_vector) *from) { size_t n = (size_t) FUNCTION(igraph_vector, size)(from); IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(to, (long) n)); memcpy(to->stor_begin, from->stor_begin, sizeof(BASE)*n); return 0; } /** * \function igraph_vector_swap * \brief Swap elements of two vectors. * * \param v1 The first vector. * \param v2 The second vector. * \return Error code. * * Time complexity: O(1). */ int FUNCTION(igraph_vector, swap)(TYPE(igraph_vector) *v1, TYPE(igraph_vector) *v2) { TYPE(igraph_vector) tmp; tmp = *v1; *v1 = *v2; *v2 = tmp; return IGRAPH_SUCCESS; } /** * \function igraph_vector_swap_elements * \brief Swap two elements in a vector. * * Note that currently no range checking is performed. * \param v The input vector. * \param i Index of the first element. * \param j Index of the second element (may be the same as the * first one). * \return Error code, currently always \c IGRAPH_SUCCESS. * * Time complexity: O(1). */ int FUNCTION(igraph_vector, swap_elements)(TYPE(igraph_vector) *v, long int i, long int j) { BASE tmp = VECTOR(*v)[i]; VECTOR(*v)[i] = VECTOR(*v)[j]; VECTOR(*v)[j] = tmp; return 0; } /** * \function igraph_vector_reverse * \brief Reverse the elements of a vector. * * The first element will be last, the last element will be * first, etc. * \param v The input vector. * \return Error code, currently always \c IGRAPH_SUCCESS. * * Time complexity: O(n), the number of elements. */ int FUNCTION(igraph_vector, reverse)(TYPE(igraph_vector) *v) { long int n = FUNCTION(igraph_vector, size)(v), n2 = n / 2; long int i, j; for (i = 0, j = n - 1; i < n2; i++, j--) { BASE tmp; tmp = VECTOR(*v)[i]; VECTOR(*v)[i] = VECTOR(*v)[j]; VECTOR(*v)[j] = tmp; } return 0; } /** * \ingroup vector * \function igraph_vector_shuffle * \brief Shuffles a vector in-place using the Fisher-Yates method * * * The Fisher-Yates shuffle ensures that every permutation is * equally probable when using a proper randomness source. Of course * this does not apply to pseudo-random generators as the cycle of * these generators is less than the number of possible permutations * of the vector if the vector is long enough. * \param v The vector object. * \return Error code, currently always \c IGRAPH_SUCCESS. * * Time complexity: O(n), * n is the number of elements in the * vector. * * * References: * \clist * \cli (Fisher & Yates 1963) * R. A. Fisher and F. Yates. \emb Statistical Tables for Biological, * Agricultural and Medical Research. \eme Oliver and Boyd, 6th edition, * 1963, page 37. * \cli (Knuth 1998) * D. E. Knuth. \emb Seminumerical Algorithms, \eme volume 2 of \emb The Art * of Computer Programming. \eme Addison-Wesley, 3rd edition, 1998, page 145. * \endclist * * \example examples/simple/igraph_fisher_yates_shuffle.c */ int FUNCTION(igraph_vector, shuffle)(TYPE(igraph_vector) *v) { long int n = FUNCTION(igraph_vector, size)(v); long int k; BASE dummy; RNG_BEGIN(); while (n > 1) { k = RNG_INTEGER(0, n - 1); n--; dummy = VECTOR(*v)[n]; VECTOR(*v)[n] = VECTOR(*v)[k]; VECTOR(*v)[k] = dummy; } RNG_END(); return IGRAPH_SUCCESS; } /** * \function igraph_vector_add * \brief Add two vectors. * * Add the elements of \p v2 to \p v1, the result is stored in \p * v1. The two vectors must have the same length. * \param v1 The first vector, the result will be stored here. * \param v2 The second vector, its contents will be unchanged. * \return Error code. * * Time complexity: O(n), the number of elements. */ int FUNCTION(igraph_vector, add)(TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2) { long int n1 = FUNCTION(igraph_vector, size)(v1); long int n2 = FUNCTION(igraph_vector, size)(v2); long int i; if (n1 != n2) { IGRAPH_ERROR("Vectors must have the same number of elements for swapping", IGRAPH_EINVAL); } for (i = 0; i < n1; i++) { #ifdef SUM SUM(VECTOR(*v1)[i], VECTOR(*v1)[i], VECTOR(*v2)[i]); #else VECTOR(*v1)[i] += VECTOR(*v2)[i]; #endif } return 0; } /** * \function igraph_vector_sub * \brief Subtract a vector from another one. * * Subtract the elements of \p v2 from \p v1, the result is stored in * \p v1. The two vectors must have the same length. * \param v1 The first vector, to subtract from. The result is stored * here. * \param v2 The vector to subtract, it will be unchanged. * \return Error code. * * Time complexity: O(n), the length of the vectors. */ int FUNCTION(igraph_vector, sub)(TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2) { long int n1 = FUNCTION(igraph_vector, size)(v1); long int n2 = FUNCTION(igraph_vector, size)(v2); long int i; if (n1 != n2) { IGRAPH_ERROR("Vectors must have the same number of elements for swapping", IGRAPH_EINVAL); } for (i = 0; i < n1; i++) { #ifdef DIFF DIFF(VECTOR(*v1)[i], VECTOR(*v1)[i], VECTOR(*v2)[i]); #else VECTOR(*v1)[i] -= VECTOR(*v2)[i]; #endif } return 0; } /** * \function igraph_vector_mul * \brief Multiply two vectors. * * \p v1 will be multiplied by \p v2, elementwise. The two vectors * must have the same length. * \param v1 The first vector, the result will be stored here. * \param v2 The second vector, it is left unchanged. * \return Error code. * * Time complexity: O(n), the number of elements. */ int FUNCTION(igraph_vector, mul)(TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2) { long int n1 = FUNCTION(igraph_vector, size)(v1); long int n2 = FUNCTION(igraph_vector, size)(v2); long int i; if (n1 != n2) { IGRAPH_ERROR("Vectors must have the same number of elements for swapping", IGRAPH_EINVAL); } for (i = 0; i < n1; i++) { #ifdef PROD PROD(VECTOR(*v1)[i], VECTOR(*v1)[i], VECTOR(*v2)[i]); #else VECTOR(*v1)[i] *= VECTOR(*v2)[i]; #endif } return 0; } /** * \function igraph_vector_div * \brief Divide a vector by another one. * * \p v1 is divided by \p v2, elementwise. They must have the same length. If the * base type of the vector can generate divide by zero errors then * please make sure that \p v2 contains no zero if you want to avoid * trouble. * \param v1 The dividend. The result is also stored here. * \param v2 The divisor, it is left unchanged. * \return Error code. * * Time complexity: O(n), the length of the vectors. */ int FUNCTION(igraph_vector, div)(TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2) { long int n1 = FUNCTION(igraph_vector, size)(v1); long int n2 = FUNCTION(igraph_vector, size)(v2); long int i; if (n1 != n2) { IGRAPH_ERROR("Vectors must have the same number of elements for swapping", IGRAPH_EINVAL); } for (i = 0; i < n1; i++) { #ifdef DIV DIV(VECTOR(*v1)[i], VECTOR(*v1)[i], VECTOR(*v2)[i]); #else VECTOR(*v1)[i] /= VECTOR(*v2)[i]; #endif } return 0; } #ifndef NOABS int FUNCTION(igraph_vector, abs)(TYPE(igraph_vector) *v) { #ifdef UNSIGNED /* Nothing do to, unsigned type */ IGRAPH_UNUSED(v); #else long int i, n = FUNCTION(igraph_vector, size)(v); for (i = 0; i < n; i++) { VECTOR(*v)[i] = VECTOR(*v)[i] >= 0 ? VECTOR(*v)[i] : -VECTOR(*v)[i]; } #endif return 0; } #endif #ifndef NOTORDERED /** * \function igraph_vector_minmax * \brief Minimum and maximum elements of a vector. * * Handy if you want to have both the smallest and largest element of * a vector. The vector is only traversed once. The vector must be non-empty. * If a vector contains at least one NaN, both \c min and \c max will be NaN. * \param v The input vector. It must contain at least one element. * \param min Pointer to a base type variable, the minimum is stored * here. * \param max Pointer to a base type variable, the maximum is stored * here. * \return Error code. * * Time complexity: O(n), the number of elements. */ int FUNCTION(igraph_vector, minmax)(const TYPE(igraph_vector) *v, BASE *min, BASE *max) { BASE* ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_ASSERT(v->stor_begin != v->end); *min = *max = *(v->stor_begin); #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) if (igraph_is_nan(*min)) { return IGRAPH_SUCCESS; }; /* Result is NaN */ #endif ptr = v->stor_begin + 1; while (ptr < v->end) { if (*ptr > *max) { *max = *ptr; } else if (*ptr < *min) { *min = *ptr; } #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) else if (igraph_is_nan(*ptr)) { /* Result is NaN */ *min = *max = *ptr; return IGRAPH_SUCCESS; }; #endif ptr++; } return IGRAPH_SUCCESS; } /** * \function igraph_vector_which_minmax * \brief Index of the minimum and maximum elements * * * Handy if you need the indices of the smallest and largest * elements. The vector is traversed only once. The vector must be * non-empty. If the minimum or maximum is not unique, the index * of the first minimum or the first maximum is returned, respectively. * If a vector contains at least one NaN, both \c which_min and \c which_max * will point to the first NaN value. * \param v The input vector. It must contain at least one element. * \param which_min The index of the minimum element will be stored * here. * \param which_max The index of the maximum element will be stored * here. * \return Error code. * * Time complexity: O(n), the number of elements. */ int FUNCTION(igraph_vector, which_minmax)(const TYPE(igraph_vector) *v, long int *which_min, long int *which_max) { BASE *min, *max; BASE *ptr; IGRAPH_ASSERT(v != NULL); IGRAPH_ASSERT(v->stor_begin != NULL); IGRAPH_ASSERT(v->stor_begin != v->end); ptr = v->stor_begin; min = max = ptr; #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) if (igraph_is_nan(*ptr)) { /* Result is NaN */ *which_min = *which_max = 0; return IGRAPH_SUCCESS; } #endif while (ptr < v->end) { if (*ptr > *max) { max = ptr; } else if (*ptr < *min) { min = ptr; } #if defined(BASE_IGRAPH_REAL) || defined(BASE_FLOAT) else if (igraph_is_nan(*ptr)) { /* Result is NaN */ *which_min = *which_max = ptr - v->stor_begin; return IGRAPH_SUCCESS; } #endif ptr++; } *which_min = min - v->stor_begin; *which_max = max - v->stor_begin; return IGRAPH_SUCCESS; } #endif /** * \function igraph_vector_isnull * \brief Are all elements zero? * * Checks whether all elements of a vector are zero. * \param v The input vector * \return Boolean, \c TRUE if the vector contains only zeros, \c * FALSE otherwise. * * Time complexity: O(n), the number of elements. */ igraph_bool_t FUNCTION(igraph_vector, isnull)(const TYPE(igraph_vector) *v) { long int n = FUNCTION(igraph_vector, size)(v); long int i = 0; #ifdef EQ while (i < n && EQ(VECTOR(*v)[i], ZERO)) { #else while (i < n && VECTOR(*v)[i] == ZERO) { #endif i++; } return i == n; } #ifndef NOTORDERED int FUNCTION(igraph_i_vector, intersect_sorted)( const TYPE(igraph_vector) *v1, long int begin1, long int end1, const TYPE(igraph_vector) *v2, long int begin2, long int end2, TYPE(igraph_vector) *result); /** * \function igraph_vector_intersect_sorted * \brief Calculates the intersection of two sorted vectors * * The elements that are contained in both vectors are stored in the result * vector. All three vectors must be initialized. * * * Instead of the naive intersection which takes O(n), this function uses * the set intersection method of Ricardo Baeza-Yates, which is more efficient * when one of the vectors is significantly smaller than the other, and * gives similar performance on average when the two vectors are equal. * * * The algorithm keeps the multiplicities of the elements: if an element appears * k1 times in the first vector and k2 times in the second, the result * will include that element min(k1, k2) times. * * * Reference: Baeza-Yates R: A fast set intersection algorithm for sorted * sequences. In: Lecture Notes in Computer Science, vol. 3109/2004, pp. * 400--408, 2004. Springer Berlin/Heidelberg. ISBN: 978-3-540-22341-2. * * \param v1 the first vector * \param v2 the second vector * \param result the result vector, which will also be sorted. * * Time complexity: O(m log(n)) where m is the size of the smaller vector * and n is the size of the larger one. */ int FUNCTION(igraph_vector, intersect_sorted)(const TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2, TYPE(igraph_vector) *result) { long int size1, size2; size1 = FUNCTION(igraph_vector, size)(v1); size2 = FUNCTION(igraph_vector, size)(v2); FUNCTION(igraph_vector, clear)(result); if (size1 == 0 || size2 == 0) { return 0; } IGRAPH_CHECK(FUNCTION(igraph_i_vector, intersect_sorted)( v1, 0, size1, v2, 0, size2, result)); return 0; } int FUNCTION(igraph_i_vector, intersect_sorted)( const TYPE(igraph_vector) *v1, long int begin1, long int end1, const TYPE(igraph_vector) *v2, long int begin2, long int end2, TYPE(igraph_vector) *result) { long int size1, size2, probe1, probe2; if (begin1 == end1 || begin2 == end2) { return 0; } size1 = end1 - begin1; size2 = end2 - begin2; if (size1 < size2) { probe1 = begin1 + (size1 >> 1); /* pick the median element */ FUNCTION(igraph_i_vector, binsearch_slice)(v2, VECTOR(*v1)[probe1], &probe2, begin2, end2); IGRAPH_CHECK(FUNCTION(igraph_i_vector, intersect_sorted)( v1, begin1, probe1, v2, begin2, probe2, result )); if (!(probe2 == end2 || VECTOR(*v1)[probe1] < VECTOR(*v2)[probe2])) { IGRAPH_CHECK(FUNCTION(igraph_vector, push_back)(result, VECTOR(*v2)[probe2])); probe2++; } IGRAPH_CHECK(FUNCTION(igraph_i_vector, intersect_sorted)( v1, probe1 + 1, end1, v2, probe2, end2, result )); } else { probe2 = begin2 + (size2 >> 1); /* pick the median element */ FUNCTION(igraph_i_vector, binsearch_slice)(v1, VECTOR(*v2)[probe2], &probe1, begin1, end1); IGRAPH_CHECK(FUNCTION(igraph_i_vector, intersect_sorted)( v1, begin1, probe1, v2, begin2, probe2, result )); if (!(probe1 == end1 || VECTOR(*v2)[probe2] < VECTOR(*v1)[probe1])) { IGRAPH_CHECK(FUNCTION(igraph_vector, push_back)(result, VECTOR(*v2)[probe2])); probe1++; } IGRAPH_CHECK(FUNCTION(igraph_i_vector, intersect_sorted)( v1, probe1, end1, v2, probe2 + 1, end2, result )); } return 0; } /** * \function igraph_vector_difference_sorted * \brief Calculates the difference between two sorted vectors (considered as sets) * * The elements that are contained in only the first vector but not the second are * stored in the result vector. All three vectors must be initialized. * * \param v1 the first vector * \param v2 the second vector * \param result the result vector */ int FUNCTION(igraph_vector, difference_sorted)(const TYPE(igraph_vector) *v1, const TYPE(igraph_vector) *v2, TYPE(igraph_vector) *result) { long int i, j, i0, j0; i0 = FUNCTION(igraph_vector, size)(v1); j0 = FUNCTION(igraph_vector, size)(v2); i = j = 0; if (i0 == 0) { /* v1 is empty, this is easy */ FUNCTION(igraph_vector, clear)(result); return IGRAPH_SUCCESS; } if (j0 == 0) { /* v2 is empty, this is easy */ IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(result, i0)); memcpy(result->stor_begin, v1->stor_begin, sizeof(BASE) * (size_t) i0); return IGRAPH_SUCCESS; } FUNCTION(igraph_vector, clear)(result); /* Copy the part of v1 that is less than the first element of v2 */ while (i < i0 && VECTOR(*v1)[i] < VECTOR(*v2)[j]) { i++; } if (i > 0) { IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(result, i)); memcpy(result->stor_begin, v1->stor_begin, sizeof(BASE) * (size_t) i); } while (i < i0 && j < j0) { BASE element = VECTOR(*v1)[i]; if (element == VECTOR(*v2)[j]) { i++; j++; while (i < i0 && VECTOR(*v1)[i] == element) { i++; } while (j < j0 && VECTOR(*v2)[j] == element) { j++; } } else if (element < VECTOR(*v2)[j]) { IGRAPH_CHECK(FUNCTION(igraph_vector, push_back)(result, element)); i++; } else { j++; } } if (i < i0) { long int oldsize = FUNCTION(igraph_vector, size)(result); IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(result, oldsize + i0 - i)); memcpy(result->stor_begin + oldsize, v1->stor_begin + i, sizeof(BASE) * (size_t) (i0 - i)); } return 0; } #endif #if defined(OUT_FORMAT) #ifndef USING_R int FUNCTION(igraph_vector, print)(const TYPE(igraph_vector) *v) { long int i, n = FUNCTION(igraph_vector, size)(v); if (n != 0) { #ifdef PRINTFUNC PRINTFUNC(VECTOR(*v)[0]); #else printf(OUT_FORMAT, VECTOR(*v)[0]); #endif } for (i = 1; i < n; i++) { #ifdef PRINTFUNC putchar(' '); PRINTFUNC(VECTOR(*v)[i]); #else printf(" " OUT_FORMAT, VECTOR(*v)[i]); #endif } printf("\n"); return 0; } int FUNCTION(igraph_vector, printf)(const TYPE(igraph_vector) *v, const char *format) { long int i, n = FUNCTION(igraph_vector, size)(v); if (n != 0) { printf(format, VECTOR(*v)[0]); } for (i = 1; i < n; i++) { putchar(' '); printf(format, VECTOR(*v)[i]); } printf("\n"); return 0; } #endif int FUNCTION(igraph_vector, fprint)(const TYPE(igraph_vector) *v, FILE *file) { long int i, n = FUNCTION(igraph_vector, size)(v); if (n != 0) { #ifdef FPRINTFUNC FPRINTFUNC(file, VECTOR(*v)[0]); #else fprintf(file, OUT_FORMAT, VECTOR(*v)[0]); #endif } for (i = 1; i < n; i++) { #ifdef FPRINTFUNC fputc(' ', file); FPRINTFUNC(file, VECTOR(*v)[i]); #else fprintf(file, " " OUT_FORMAT, VECTOR(*v)[i]); #endif } fprintf(file, "\n"); return 0; } #endif int FUNCTION(igraph_vector, index)(const TYPE(igraph_vector) *v, TYPE(igraph_vector) *newv, const igraph_vector_t *idx) { long int i, newlen = igraph_vector_size(idx); IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(newv, newlen)); for (i = 0; i < newlen; i++) { long int j = (long int) VECTOR(*idx)[i]; VECTOR(*newv)[i] = VECTOR(*v)[j]; } return 0; } int FUNCTION(igraph_vector, index_int)(TYPE(igraph_vector) *v, const igraph_vector_int_t *idx) { BASE *tmp; int i, n = igraph_vector_int_size(idx); tmp = IGRAPH_CALLOC(n, BASE); if (!tmp) { IGRAPH_ERROR("Cannot index vector", IGRAPH_ENOMEM); } for (i = 0; i < n; i++) { tmp[i] = VECTOR(*v)[ VECTOR(*idx)[i] ]; } IGRAPH_FREE(v->stor_begin); v->stor_begin = tmp; v->stor_end = v->end = tmp + n; return 0; } leidenbase/src/core/core/statusbar.c0000644000176200001440000001051214447675374017214 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_statusbar.h" #include "igraph_error.h" #include "config.h" #include #include static IGRAPH_THREAD_LOCAL igraph_status_handler_t *igraph_i_status_handler = 0; /** * \function igraph_status * Report status from an igraph function. * * It calls the installed status handler function, if there is * one. Otherwise it does nothing. Note that the standard way to * report the status from an igraph function is the * \ref IGRAPH_STATUS or \ref IGRAPH_STATUSF macro, as these * take care of the termination of the calling function if the * status handler returns with \c IGRAPH_INTERRUPTED. * \param message The status message. * \param data Additional context, with user-defined semantics. * Existing igraph functions pass a null pointer here. * \return Error code. If a status handler function was called * and it did not return with \c IGRAPH_SUCCESS, then * \c IGRAPH_INTERRUPTED is returned by \c igraph_status(). * * Time complexity: O(1). */ int igraph_status(const char *message, void *data) { if (igraph_i_status_handler) { if (igraph_i_status_handler(message, data) != IGRAPH_SUCCESS) { return IGRAPH_INTERRUPTED; } } return IGRAPH_SUCCESS; } /** * \function igraph_statusf * Report status, more flexible printf-like version. * * This is the more flexible version of \ref igraph_status(), * that has a syntax similar to the \c printf standard C library function. * It substitutes the values of the additional arguments into the * \p message template string and calls \ref igraph_status(). * \param message Status message template string, the syntax is the same * as for the \c printf function. * \param data Additional context, with user-defined semantics. * Existing igraph functions pass a null pointer here. * \param ... The additional arguments to fill the template given in the * \p message argument. * \return Error code. If a status handler function was called * and it did not return with \c IGRAPH_SUCCESS, then * \c IGRAPH_INTERRUPTED is returned by \c igraph_status(). */ int igraph_statusf(const char *message, void *data, ...) { char buffer[300]; va_list ap; va_start(ap, data); vsnprintf(buffer, sizeof(buffer) - 1, message, ap); return igraph_status(buffer, data); } #ifndef USING_R /** * \function igraph_status_handler_stderr * A simple predefined status handler function. * * A simple status handler function, that writes the status * message to the standard errror. * \param message The status message. * \param data Additional context, with user-defined semantics. * Existing igraph functions pass a null pointer here. * \return Error code. * * Time complexity: O(1). */ int igraph_status_handler_stderr(const char *message, void *data) { IGRAPH_UNUSED(data); fputs(message, stderr); return 0; } #endif /** * \function igraph_set_status_handler * Install of uninstall a status handler function. * * To uninstall the currently installed status handler, call * this function with a null pointer. * \param new_handler The status handler function to install. * \return The previously installed status handler function. * * Time complexity: O(1). */ igraph_status_handler_t * igraph_set_status_handler(igraph_status_handler_t new_handler) { igraph_status_handler_t *previous_handler = igraph_i_status_handler; igraph_i_status_handler = new_handler; return previous_handler; } leidenbase/src/core/core/fixed_vectorlist.h0000644000176200001440000000317714447675374020577 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_TYPES_INTERNAL_H #define IGRAPH_TYPES_INTERNAL_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS /* -------------------------------------------------- */ /* Vectorlist, fixed length */ /* -------------------------------------------------- */ typedef struct igraph_fixed_vectorlist_t { igraph_vector_t *vecs; igraph_vector_ptr_t v; long int length; } igraph_fixed_vectorlist_t; void igraph_fixed_vectorlist_destroy(igraph_fixed_vectorlist_t *l); int igraph_fixed_vectorlist_convert(igraph_fixed_vectorlist_t *l, const igraph_vector_t *from, long int size); __END_DECLS #endif leidenbase/src/core/core/dqueue.c0000644000176200001440000000272714447675374016505 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_types.h" #include "igraph_dqueue.h" #define BASE_IGRAPH_REAL #include "igraph_pmt.h" #include "dqueue.pmt" #include "igraph_pmt_off.h" #undef BASE_IGRAPH_REAL #define BASE_LONG #include "igraph_pmt.h" #include "dqueue.pmt" #include "igraph_pmt_off.h" #undef BASE_LONG #define BASE_CHAR #include "igraph_pmt.h" #include "dqueue.pmt" #include "igraph_pmt_off.h" #undef BASE_CHAR #define BASE_BOOL #include "igraph_pmt.h" #include "dqueue.pmt" #include "igraph_pmt_off.h" #undef BASE_BOOL #define BASE_INT #include "igraph_pmt.h" #include "dqueue.pmt" #include "igraph_pmt_off.h" #undef BASE_INT leidenbase/src/core/cliques/0000755000176200001440000000000014532173045015535 5ustar liggesusersleidenbase/src/core/cliques/cliquer/0000755000176200001440000000000014532173045017201 5ustar liggesusersleidenbase/src/core/cliques/cliquer/reorder.h0000644000176200001440000000172414447675374021041 0ustar liggesusers #ifndef CLIQUER_REORDER_H #define CLIQUER_REORDER_H #include "set.h" #include "graph.h" extern void reorder_set(set_t s,int *order); extern void reorder_graph(graph_t *g, int *order); extern int *reorder_duplicate(int *order,int n); extern void reorder_invert(int *order,int n); extern void reorder_reverse(int *order,int n); extern int *reorder_ident(int n); extern boolean reorder_is_bijection(int *order,int n); #define reorder_by_default reorder_by_greedy_coloring extern int *reorder_by_greedy_coloring(graph_t *g, boolean weighted); extern int *reorder_by_weighted_greedy_coloring(graph_t *g, boolean weighted); extern int *reorder_by_unweighted_greedy_coloring(graph_t *g,boolean weighted); extern int *reorder_by_degree(graph_t *g, boolean weighted); extern int *reorder_by_random(graph_t *g, boolean weighted); extern int *reorder_by_ident(graph_t *g, boolean weighted); extern int *reorder_by_reverse(graph_t *g, boolean weighted); #endif /* !CLIQUER_REORDER_H */ leidenbase/src/core/cliques/cliquer/set.h0000644000176200001440000002226414447675374020174 0ustar liggesusers /* * This file contains the set handling routines. * * Copyright (C) 2002 Sampo Niskanen, Patric Östergård. * Licensed under the GNU GPL, read the file LICENSE for details. */ #ifndef CLIQUER_SET_H #define CLIQUER_SET_H #include #include #include #include #include "misc.h" /* * Sets are arrays of setelement's (typically unsigned long int's) with * representative bits for each value they can contain. The values * are numbered 0,...,n-1. */ /*** Variable types and constants. ***/ /* * If setelement hasn't been declared: * - use "unsigned long int" as setelement * - try to deduce size from ULONG_MAX */ #ifndef ELEMENTSIZE typedef unsigned long int setelement; # if (ULONG_MAX == 65535) # define ELEMENTSIZE 16 # elif (ULONG_MAX == 4294967295) # define ELEMENTSIZE 32 # else # define ELEMENTSIZE 64 # endif #endif /* !ELEMENTSIZE */ typedef setelement * set_t; /*** Counting amount of 1 bits in a setelement ***/ /* Array for amount of 1 bits in a byte. */ static int set_bit_count[256] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 }; /* The following macros assume that all higher bits are 0. * They may in some cases be useful also on with other ELEMENTSIZE's, * so we define them all. */ #define SET_ELEMENT_BIT_COUNT_8(a) (set_bit_count[(a)]) #define SET_ELEMENT_BIT_COUNT_16(a) (set_bit_count[(a)>>8] + \ set_bit_count[(a)&0xFF]) #define SET_ELEMENT_BIT_COUNT_32(a) (set_bit_count[(a)>>24] + \ set_bit_count[((a)>>16)&0xFF] + \ set_bit_count[((a)>>8)&0xFF] + \ set_bit_count[(a)&0xFF]) #define SET_ELEMENT_BIT_COUNT_64(a) (set_bit_count[(a)>>56] + \ set_bit_count[((a)>>48)&0xFF] + \ set_bit_count[((a)>>40)&0xFF] + \ set_bit_count[((a)>>32)&0xFF] + \ set_bit_count[((a)>>24)&0xFF] + \ set_bit_count[((a)>>16)&0xFF] + \ set_bit_count[((a)>>8)&0xFF] + \ set_bit_count[(a)&0xFF]) #if (ELEMENTSIZE==64) # define SET_ELEMENT_BIT_COUNT(a) SET_ELEMENT_BIT_COUNT_64(a) # define FULL_ELEMENT ((setelement)0xFFFFFFFFFFFFFFFF) #elif (ELEMENTSIZE==32) # define SET_ELEMENT_BIT_COUNT(a) SET_ELEMENT_BIT_COUNT_32(a) # define FULL_ELEMENT ((setelement)0xFFFFFFFF) #elif (ELEMENTSIZE==16) # define SET_ELEMENT_BIT_COUNT(a) SET_ELEMENT_BIT_COUNT_16(a) # define FULL_ELEMENT ((setelement)0xFFFF) #else # error "SET_ELEMENT_BIT_COUNT(a) not defined for current ELEMENTSIZE" #endif /*** Macros and functions ***/ /* * Gives a value with bit x (counting from lsb up) set. * * Making this as a table might speed up things on some machines * (though on most modern machines it's faster to shift instead of * using memory). Making it a macro makes it easy to change. */ #define SET_BIT_MASK(x) ((setelement)1<<(x)) /* Set element handling macros */ #define SET_ELEMENT_INTERSECT(a,b) ((a)&(b)) #define SET_ELEMENT_UNION(a,b) ((a)|(b)) #define SET_ELEMENT_DIFFERENCE(a,b) ((a)&(~(b))) #define SET_ELEMENT_CONTAINS(e,v) ((e)&SET_BIT_MASK(v)) /* Set handling macros */ #define SET_ADD_ELEMENT(s,a) \ ((s)[(a)/ELEMENTSIZE] |= SET_BIT_MASK((a)%ELEMENTSIZE)) #define SET_DEL_ELEMENT(s,a) \ ((s)[(a)/ELEMENTSIZE] &= ~SET_BIT_MASK((a)%ELEMENTSIZE)) #define SET_CONTAINS_FAST(s,a) (SET_ELEMENT_CONTAINS((s)[(a)/ELEMENTSIZE], \ (a)%ELEMENTSIZE)) #define SET_CONTAINS(s,a) (((a)0); n=(size/ELEMENTSIZE+1)+1; s=calloc(n,sizeof(setelement)); s[0]=size; return &(s[1]); } /* * set_free() * * Free the memory associated with set s. */ UNUSED_FUNCTION INLINE static void set_free(set_t s) { ASSERT(s!=NULL); free(&(s[-1])); } /* * set_resize() * * Resizes set s to given size. If the size is less than SET_MAX_SIZE(s), * the last elements are dropped. * * Returns a pointer to the new set. */ UNUSED_FUNCTION INLINE static set_t set_resize(set_t s, unsigned int size) { unsigned int n; ASSERT(size>0); n=(size/ELEMENTSIZE+1); s=((setelement *)realloc(s-1,(n+1)*sizeof(setelement)))+1; if (n>SET_ARRAY_LENGTH(s)) memset(s+SET_ARRAY_LENGTH(s),0, (n-SET_ARRAY_LENGTH(s))*sizeof(setelement)); if (size < SET_MAX_SIZE(s)) s[(size-1)/ELEMENTSIZE] &= (FULL_ELEMENT >> (ELEMENTSIZE-size%ELEMENTSIZE)); s[-1]=size; return s; } /* * set_size() * * Returns the number of elements in set s. */ UNUSED_FUNCTION INLINE static int set_size(set_t s) { int count=0; setelement *c; for (c=s; c < s+SET_ARRAY_LENGTH(s); c++) count+=SET_ELEMENT_BIT_COUNT(*c); return count; } /* * set_duplicate() * * Returns a newly allocated duplicate of set s. */ UNUSED_FUNCTION INLINE static set_t set_duplicate(set_t s) { set_t new; new=set_new(SET_MAX_SIZE(s)); memcpy(new,s,SET_ARRAY_LENGTH(s)*sizeof(setelement)); return new; } /* * set_copy() * * Copies set src to dest. If dest is NULL, is equal to set_duplicate. * If dest smaller than src, it is freed and a new set of the same size as * src is returned. */ UNUSED_FUNCTION INLINE static set_t set_copy(set_t dest,set_t src) { if (dest==NULL) return set_duplicate(src); if (SET_MAX_SIZE(dest)=0) { * // i is in set s * } */ UNUSED_FUNCTION INLINE static int set_return_next(set_t s, unsigned int n) { n++; if (n >= SET_MAX_SIZE(s)) return -1; while (n%ELEMENTSIZE) { if (SET_CONTAINS(s,n)) return n; n++; if (n >= SET_MAX_SIZE(s)) return -1; } while (s[n/ELEMENTSIZE]==0) { n+=ELEMENTSIZE; if (n >= SET_MAX_SIZE(s)) return -1; } while (!SET_CONTAINS(s,n)) { n++; if (n >= SET_MAX_SIZE(s)) return -1; } return n; } /* * set_print() * * Prints the size and contents of set s to stdout. * Mainly useful for debugging purposes and trivial output. */ /* UNUSED_FUNCTION static void set_print(set_t s) { int i; printf("size=%d(max %d)",set_size(s),(int)SET_MAX_SIZE(s)); for (i=0; iedges[(i)],(j))) #define GRAPH_IS_EDGE(g,i,j) (((i)<((g)->n))?SET_CONTAINS((g)->edges[(i)], \ (j)):FALSE) #define GRAPH_ADD_EDGE(g,i,j) do { \ SET_ADD_ELEMENT((g)->edges[(i)],(j)); \ SET_ADD_ELEMENT((g)->edges[(j)],(i)); \ } while (FALSE) #define GRAPH_DEL_EDGE(g,i,j) do { \ SET_DEL_ELEMENT((g)->edges[(i)],(j)); \ SET_DEL_ELEMENT((g)->edges[(j)],(i)); \ } while (FALSE) extern graph_t *graph_new(int n); extern void graph_free(graph_t *g); extern void graph_resize(graph_t *g, int size); extern void graph_crop(graph_t *g); extern boolean graph_weighted(graph_t *g); extern int graph_edge_count(graph_t *g); /* extern graph_t *graph_read_dimacs(FILE *fp); extern graph_t *graph_read_dimacs_file(char *file); extern boolean graph_write_dimacs_ascii(graph_t *g, char *comment,FILE *fp); extern boolean graph_write_dimacs_ascii_file(graph_t *g,char *comment, char *file); extern boolean graph_write_dimacs_binary(graph_t *g, char *comment,FILE *fp); extern boolean graph_write_dimacs_binary_file(graph_t *g, char *comment, char *file); extern void graph_print(graph_t *g); extern boolean graph_test(graph_t *g, FILE *output); extern int graph_test_regular(graph_t *g); */ UNUSED_FUNCTION INLINE static int graph_subgraph_weight(graph_t *g,set_t s) { unsigned int i,j; int count=0; setelement e; for (i=0; iweights[i*ELEMENTSIZE+j]; e = e>>1; } } } return count; } UNUSED_FUNCTION INLINE static int graph_vertex_degree(graph_t *g, int v) { return set_size(g->edges[v]); } #endif /* !CLIQUER_GRAPH_H */ leidenbase/src/core/cliques/cliquer/cliquerconf.h0000644000176200001440000000361214447675374021707 0ustar liggesusers #ifndef CLIQUERCONF_H #define CLIQUERCONF_H /* * setelement is the basic memory type used in sets. It is often fastest * to be as large as can fit into the CPU registers. * * ELEMENTSIZE is the size of one setelement, measured in bits. It must * be either 16, 32 or 64 (otherwise additional changes must be made to * the source). * * The default is to use "unsigned long int" and attempt to guess the * size using , which should work pretty well. Check functioning * with "make test". */ /* typedef unsigned long int setelement; */ /* #define ELEMENTSIZE 64 */ /* * INLINE is a command prepended to function declarations to instruct the * compiler to inline the function. If inlining is not desired, define blank. * * The default is to use "inline", which is recognized by most compilers. */ /* #define INLINE */ /* #define INLINE __inline__ */ #if __STDC_VERSION__ >= 199901L #define INLINE inline #else #if defined(_MSC_VER) #define INLINE __inline #elif defined(__GNUC__) #define INLINE __inline__ #else #define INLINE #endif #endif /* * Set handling functions are defined as static functions in set.h for * performance reasons. This may cause unnecessary warnings from the * compiler. Some compilers (such as GCC) have the possibility to turn * off the warnings on a per-function basis using a flag prepended to * the function declaration. * * The default is to use the correct attribute when compiling with GCC, * or no flag otherwise. */ /* #define UNUSED_FUNCTION __attribute__((unused)) */ /* #define UNUSED_FUNCTION */ /* * Uncommenting the following will disable all assertions (checks that * function arguments and other variables are correct). This is highly * discouraged, as it allows bugs to go unnoticed easier. The assertions * are set so that they do not slow down programs notably. */ /* #define ASSERT(x) */ #endif /* !CLIQUERCONF_H */ leidenbase/src/core/cliques/cliquer/reorder.c0000644000176200001440000002140514447675374021032 0ustar liggesusers /* * This file contains the vertex reordering routines. * * Copyright (C) 2002 Sampo Niskanen, Patric Östergård. * Licensed under the GNU GPL, read the file LICENSE for details. */ #include "reorder.h" #include #include #include /* * reorder_set() * * Reorders the set s with a function i -> order[i]. * * Note: Assumes that order is the same size as SET_MAX_SIZE(s). */ void reorder_set(set_t s,int *order) { set_t tmp; int i,j; setelement e; ASSERT(reorder_is_bijection(order,SET_MAX_SIZE(s))); tmp=set_new(SET_MAX_SIZE(s)); for (i=0; i<(SET_MAX_SIZE(s)/ELEMENTSIZE); i++) { e=s[i]; if (e==0) continue; for (j=0; j>1; } } if (SET_MAX_SIZE(s)%ELEMENTSIZE) { e=s[i]; for (j=0; j<(SET_MAX_SIZE(s)%ELEMENTSIZE); j++) { if (e&1) { SET_ADD_ELEMENT(tmp,order[i*ELEMENTSIZE+j]); } e = e>>1; } } set_copy(s,tmp); set_free(tmp); return; } /* * reorder_graph() * * Reorders the vertices in the graph with function i -> order[i]. * * Note: Assumes that order is of size g->n. */ void reorder_graph(graph_t *g, int *order) { int i; set_t *tmp_e; int *tmp_w; ASSERT(reorder_is_bijection(order,g->n)); tmp_e=malloc(g->n * sizeof(set_t)); tmp_w=malloc(g->n * sizeof(int)); for (i=0; in; i++) { reorder_set(g->edges[i],order); tmp_e[order[i]]=g->edges[i]; tmp_w[order[i]]=g->weights[i]; } for (i=0; in; i++) { g->edges[i]=tmp_e[i]; g->weights[i]=tmp_w[i]; } free(tmp_e); free(tmp_w); return; } /* * reorder_duplicate() * * Returns a newly allocated duplicate of the given ordering. */ int *reorder_duplicate(int *order,int n) { int *new; new=malloc(n*sizeof(int)); memcpy(new,order,n*sizeof(int)); return new; } /* * reorder_invert() * * Inverts the given ordering so that new[old[i]]==i. * * Note: Asserts that order is a bijection. */ void reorder_invert(int *order,int n) { int *new; int i; ASSERT(reorder_is_bijection(order,n)); new=malloc(n*sizeof(int)); for (i=0; i {0,...,n-1}. * * Returns TRUE if it is a bijection, FALSE otherwise. */ boolean reorder_is_bijection(int *order,int n) { boolean *used; int i; used=calloc(n,sizeof(boolean)); for (i=0; i=n) { free(used); return FALSE; } if (used[order[i]]) { free(used); return FALSE; } used[order[i]]=TRUE; } for (i=0; in); } /* * reorder_by_reverse() * * Returns a reverse identity ordering. */ int *reorder_by_reverse(graph_t *g,boolean weighted) { int i; int *order; order=malloc(g->n * sizeof(int)); for (i=0; i < g->n; i++) order[i]=g->n-i-1; return order; } /* * reorder_by_greedy_coloring() * * Equivalent to reorder_by_weighted_greedy_coloring or * reorder_by_unweighted_greedy_coloring according to the value of weighted. */ int *reorder_by_greedy_coloring(graph_t *g,boolean weighted) { if (weighted) return reorder_by_weighted_greedy_coloring(g,weighted); else return reorder_by_unweighted_greedy_coloring(g,weighted); } /* * reorder_by_unweighted_greedy_coloring() * * Returns an ordering for the graph g by coloring the clique one * color at a time, always adding the vertex of largest degree within * the uncolored graph, and numbering these vertices 0, 1, ... * * Experimentally efficient for use with unweighted graphs. */ int *reorder_by_unweighted_greedy_coloring(graph_t *g,boolean weighted) { int i,j,v; boolean *tmp_used; int *degree; /* -1 for used vertices */ int *order; int maxdegree,maxvertex=0; boolean samecolor; tmp_used=calloc(g->n,sizeof(boolean)); degree=calloc(g->n,sizeof(int)); order=calloc(g->n,sizeof(int)); for (i=0; i < g->n; i++) { for (j=0; j < g->n; j++) { ASSERT(!((i==j) && GRAPH_IS_EDGE(g,i,j))); if (GRAPH_IS_EDGE(g,i,j)) degree[i]++; } } v=0; while (v < g->n) { /* Reset tmp_used. */ memset(tmp_used,0,g->n * sizeof(boolean)); do { /* Find vertex to be colored. */ maxdegree=0; samecolor=FALSE; for (i=0; i < g->n; i++) { if (!tmp_used[i] && degree[i] >= maxdegree) { maxvertex=i; maxdegree=degree[i]; samecolor=TRUE; } } if (samecolor) { order[v]=maxvertex; degree[maxvertex]=-1; v++; /* Mark neighbors not to color with same * color and update neighbor degrees. */ for (i=0; i < g->n; i++) { if (GRAPH_IS_EDGE(g,maxvertex,i)) { tmp_used[i]=TRUE; degree[i]--; } } } } while (samecolor); } free(tmp_used); free(degree); return order; } /* * reorder_by_weighted_greedy_coloring() * * Returns an ordering for the graph g by coloring the clique one * color at a time, always adding the vertex that (in order of importance): * 1. has the minimum weight in the remaining graph * 2. has the largest sum of weights surrounding the vertex * * Experimentally efficient for use with weighted graphs. */ int *reorder_by_weighted_greedy_coloring(graph_t *g, boolean weighted) { int i,j,p=0; int cnt; int *nwt; /* Sum of surrounding vertices' weights */ int min_wt,max_nwt; boolean *used; int *order; nwt=malloc(g->n * sizeof(int)); order=malloc(g->n * sizeof(int)); used=calloc(g->n,sizeof(boolean)); for (i=0; i < g->n; i++) { nwt[i]=0; for (j=0; j < g->n; j++) if (GRAPH_IS_EDGE(g, i, j)) nwt[i] += g->weights[j]; } for (cnt=0; cnt < g->n; cnt++) { min_wt=INT_MAX; max_nwt=-1; for (i=g->n-1; i>=0; i--) if ((!used[i]) && (g->weights[i] < min_wt)) min_wt=g->weights[i]; for (i=g->n-1; i>=0; i--) { if (used[i] || (g->weights[i] > min_wt)) continue; if (nwt[i] > max_nwt) { max_nwt=nwt[i]; p=i; } } order[cnt]=p; used[p]=TRUE; for (j=0; j < g->n; j++) if ((!used[j]) && (GRAPH_IS_EDGE(g, p, j))) nwt[j] -= g->weights[p]; } free(nwt); free(used); ASSERT(reorder_is_bijection(order,g->n)); return order; } /* * reorder_by_degree() * * Returns a reordering of the graph g so that the vertices with largest * degrees (most neighbors) are first. */ int *reorder_by_degree(graph_t *g, boolean weighted) { int i,j,v; int *degree; int *order; int maxdegree,maxvertex=0; degree=calloc(g->n,sizeof(int)); order=calloc(g->n,sizeof(int)); for (i=0; i < g->n; i++) { for (j=0; j < g->n; j++) { ASSERT(!((i==j) && GRAPH_IS_EDGE(g,i,j))); if (GRAPH_IS_EDGE(g,i,j)) degree[i]++; } } for (v=0; v < g->n; v++) { maxdegree=0; for (i=0; i < g->n; i++) { if (degree[i] >= maxdegree) { maxvertex=i; maxdegree=degree[i]; } } order[v]=maxvertex; degree[maxvertex]=-1; /* used */ /*** Max. degree withing unselected graph: for (i=0; i < g->n; i++) { if (GRAPH_IS_EDGE(g,maxvertex,i)) degree[i]--; } ***/ } free(degree); return order; } /* * reorder_by_random() * * Returns a random reordering for graph g. * Note: Used the functions rand() and srand() to generate the random * numbers. srand() is re-initialized every time reorder_by_random() * is called using the system time. */ int *reorder_by_random(graph_t *g, boolean weighted) { int i,r; int *new; boolean *used; new=calloc(g->n, sizeof(int)); used=calloc(g->n, sizeof(boolean)); for (i=0; i < g->n; i++) { do { r = igraph_rng_get_integer(igraph_rng_default(), 0, g->n - 1); } while (used[r]); new[i]=r; used[r]=TRUE; } free(used); return new; } leidenbase/src/core/cliques/cliquer/cliquer_graph.c0000644000176200001440000003777314447675374022234 0ustar liggesusers /* * This file contains the graph handling routines. * * Copyright (C) 2002 Sampo Niskanen, Patric Östergård. * Licensed under the GNU GPL, read the file LICENSE for details. */ #include #include #include #include "graph.h" /* static graph_t *graph_read_dimacs_binary(FILE *fp,char *firstline); static graph_t *graph_read_dimacs_ascii(FILE *fp,char *firstline); */ /* * graph_new() * * Returns a newly allocated graph with n vertices all with weight 1, * and no edges. */ graph_t *graph_new(int n) { graph_t *g; int i; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(n>0); g=malloc(sizeof(graph_t)); g->n=n; g->edges=malloc(g->n * sizeof(set_t)); g->weights=malloc(g->n * sizeof(int)); for (i=0; i < g->n; i++) { g->edges[i]=set_new(n); g->weights[i]=1; } return g; } /* * graph_free() * * Frees the memory associated with the graph g. */ void graph_free(graph_t *g) { int i; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(g!=NULL); ASSERT(g->n > 0); for (i=0; i < g->n; i++) { set_free(g->edges[i]); } free(g->weights); free(g->edges); free(g); return; } /* * graph_resize() * * Resizes graph g to given size. If size > g->n, the new vertices are * not connected to any others and their weights are set to 1. * If size < g->n, the last g->n - size vertices are removed. */ void graph_resize(graph_t *g, int size) { int i; ASSERT(g!=NULL); ASSERT(g->n > 0); ASSERT(size > 0); if (g->n == size) return; /* Free/alloc extra edge-sets */ for (i=size; i < g->n; i++) set_free(g->edges[i]); g->edges=realloc(g->edges, size * sizeof(set_t)); for (i=g->n; i < size; i++) g->edges[i]=set_new(size); /* Resize original sets */ for (i=0; i < MIN(g->n,size); i++) { g->edges[i]=set_resize(g->edges[i],size); } /* Weights */ g->weights=realloc(g->weights,size * sizeof(int)); for (i=g->n; iweights[i]=1; g->n=size; return; } /* * graph_crop() * * Resizes the graph so as to remove all highest-valued isolated vertices. */ void graph_crop(graph_t *g) { int i; for (i=g->n-1; i>=1; i--) if (set_size(g->edges[i])>0) break; graph_resize(g,i+1); return; } /* * graph_weighted() * * Returns TRUE if all vertex weights of graph g are all the same. * * Note: Does NOT require weights to be 1. */ boolean graph_weighted(graph_t *g) { int i,w; w=g->weights[0]; for (i=1; i < g->n; i++) if (g->weights[i] != w) return TRUE; return FALSE; } /* * graph_edge_count() * * Returns the number of edges in graph g. */ int graph_edge_count(graph_t *g) { int i; int count=0; for (i=0; i < g->n; i++) { count += set_size(g->edges[i]); } return count/2; } #if 0 /* * graph_write_dimacs_ascii_file() * * Writes an ASCII dimacs-format file of graph g, with comment, to * given file. * * Returns TRUE if successful, FALSE if an error occurred. */ boolean graph_write_dimacs_ascii_file(graph_t *g, char *comment, char *file) { FILE *fp; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(file!=NULL); if ((fp=fopen(file,"wb"))==NULL) return FALSE; if (!graph_write_dimacs_ascii(g,comment,fp)) { fclose(fp); return FALSE; } fclose(fp); return TRUE; } /* * graph_write_dimacs_ascii() * * Writes an ASCII dimacs-format file of graph g, with comment, to the * file stream fp. * * Returns TRUE if successful, FALSE if an error occurred. */ boolean graph_write_dimacs_ascii(graph_t *g, char *comment, FILE *fp) { int i,j; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(graph_test(g,NULL)); ASSERT(fp!=NULL); if (comment) fprintf(fp,"c %s\n",comment); fprintf(fp,"p edge %d %d\n",g->n,graph_edge_count(g)); for (i=0; i < g->n; i++) if (g->weights[i]!=1) fprintf(fp,"n %d %d\n",i+1,g->weights[i]); for (i=0; i < g->n; i++) for (j=0; j= headersize) { \ headersize+=1024; \ header=realloc(header,headersize); \ } \ strncat(header,s,1000); \ headerlength+=strlen(s); boolean graph_write_dimacs_binary(graph_t *g, char *comment,FILE *fp) { char *buf; char *header=NULL; int headersize=0; int headerlength=0; int i,j; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(graph_test(g,NULL)); ASSERT(fp!=NULL); buf=malloc(MAX(1024,g->n/8+1)); header=malloc(1024); header[0]=0; headersize=1024; if (comment) { strcpy(buf,"c "); strncat(buf,comment,1000); strcat(buf,"\n"); STR_APPEND(buf); } sprintf(buf,"p edge %d %d\n",g->n,graph_edge_count(g)); STR_APPEND(buf); for (i=0; i < g->n; i++) { if (g->weights[i]!=1) { sprintf(buf,"n %d %d\n",i+1,g->weights[i]); STR_APPEND(buf); } } fprintf(fp,"%d\n",(int)strlen(header)); fprintf(fp,"%s",header); free(header); for (i=0; i < g->n; i++) { memset(buf,0,i/8+1); for (j=0; j=strlen(str)) /* blank line */ return TRUE; if (str[i+1]!=0 && !isspace(str[i+1])) /* not 1-char field */ return FALSE; switch (str[i]) { case 'c': return TRUE; case 'p': if (g->n != 0) return FALSE; if (sscanf(str," p %15s %d %d %2s",tmp,&(g->n),&i,tmp)!=3) return FALSE; if (g->n <= 0) return FALSE; g->edges=calloc(g->n,sizeof(set_t)); for (i=0; in; i++) g->edges[i]=set_new(g->n); g->weights=calloc(g->n,sizeof(int)); for (i=0; in; i++) g->weights[i]=1; return TRUE; case 'n': if ((g->n <= 0) || (g->weights == NULL)) return FALSE; if (sscanf(str," n %d %d %2s",&i,&w,tmp)!=2) return FALSE; if (i<1 || i>g->n) return FALSE; if (w<=0) return FALSE; g->weights[i-1]=w; return TRUE; case 'e': if ((g->n <= 0) || (g->edges == NULL)) return FALSE; if (sscanf(str," e %d %d %2s",&i,&j,tmp)!=2) return FALSE; if (i<1 || j<1 || i>g->n || j>g->n) return FALSE; if (i==j) /* We want antireflexive graphs. */ return TRUE; GRAPH_ADD_EDGE(g,i-1,j-1); return TRUE; case 'd': case 'v': case 'x': return TRUE; default: fprintf(stderr,"Warning: ignoring field '%c' in " "input.\n",str[i]); return TRUE; } } /* * graph_read_dimacs_binary() * * Reads a dimacs-format binary file from file stream fp with the first * line being firstline. * * Returns the newly-allocated graph or NULL if an error occurred. * * TODO: This function leaks memory when reading erroneous files. */ static graph_t *graph_read_dimacs_binary(FILE *fp,char *firstline) { int length=0; graph_t *g; int i,j; char *buffer; char *start; char *end; char **buf; char tmp[10]; if (sscanf(firstline," %d %2s",&length,tmp)!=1) return NULL; if (length<=0) { fprintf(stderr,"Malformed preamble: preamble size < 0.\n"); return NULL; } buffer=malloc(length+2); if (fread(buffer,1,length,fp)n <= 0) { fprintf(stderr,"Malformed preamble: number of " "vertices <= 0\n"); free(g); return NULL; } /* Binary part. */ buf=calloc(g->n,sizeof(char*)); for (i=0; i < g->n; i++) { buf[i]=calloc(g->n,1); if (fread(buf[i],1,i/8+1,fp) < (i/8+1)) { fprintf(stderr,"Unexpected end of file when " "reading graph.\n"); return NULL; } } for (i=0; i < g->n; i++) { for (j=0; jn <= 0) { free(g); fprintf(stderr,"Unexpected end of file when reading graph.\n"); return NULL; } return g; } #endif #if 0 /* * graph_print() * * Prints a representation of the graph g to stdout (along with any errors * noticed). Mainly useful for debugging purposes and trivial output. * * The output consists of a first line describing the dimensions and then * one line per vertex containing the vertex number (numbered 0,...,n-1), * the vertex weight (if the graph is weighted), "->" and then a list * of all vertices it is adjacent to. */ void graph_print(graph_t *g) { int i,j; int asymm=0; int refl=0; int nonpos=0; int extra=0; unsigned int weight=0; boolean weighted; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); if (g==NULL) { printf(" WARNING: Graph pointer is NULL!\n"); return; } if (g->n <= 0) { printf(" WARNING: Graph has %d vertices " "(should be positive)!\n",g->n); return; } weighted=graph_weighted(g); printf("%s graph has %d vertices, %d edges (density %.2f).\n", weighted?"Weighted":((g->weights[0]==1)? "Unweighted":"Semi-weighted"), g->n,graph_edge_count(g), (float)graph_edge_count(g)/((float)(g->n - 1)*(g->n)/2)); for (i=0; i < g->n; i++) { printf("%2d",i); if (weighted) { printf(" w=%d",g->weights[i]); if (g->weights[i] <= 0) { printf("*NON-POSITIVE*"); nonpos++; } } if (weight < INT_MAX) weight+=g->weights[i]; printf(" ->"); for (j=0; j < g->n; j++) { if (SET_CONTAINS_FAST(g->edges[i],j)) { printf(" %d",j); if (i==j) { printf("*REFLEXIVE*"); refl++; } if (!SET_CONTAINS_FAST(g->edges[j],i)) { printf("*ASYMMERTIC*"); asymm++; } } } for (j=g->n; j < SET_ARRAY_LENGTH(g->edges[i])*ELEMENTSIZE; j++) { if (SET_CONTAINS_FAST(g->edges[i],j)) { printf(" %d*NON-EXISTENT*",j); extra++; } } printf("\n"); } if (asymm) printf(" WARNING: Graph contained %d asymmetric edges!\n", asymm); if (refl) printf(" WARNING: Graph contained %d reflexive edges!\n", refl); if (nonpos) printf(" WARNING: Graph contained %d non-positive vertex " "weights!\n",nonpos); if (extra) printf(" WARNING: Graph contained %d edges to " "non-existent vertices!\n",extra); if (weight>=INT_MAX) printf(" WARNING: Total graph weight >= INT_MAX!\n"); return; } /* * graph_test() * * Tests graph g to be valid. Checks that g is non-NULL, the edges are * symmetric and anti-reflexive, and that all vertex weights are positive. * If output is non-NULL, prints a few lines telling the status of the graph * to file descriptor output. * * Returns TRUE if the graph is valid, FALSE otherwise. */ boolean graph_test(graph_t *g,FILE *output) { int i,j; int edges=0; int asymm=0; int nonpos=0; int refl=0; int extra=0; unsigned int weight=0; boolean weighted; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); if (g==NULL) { if (output) fprintf(output," WARNING: Graph pointer is NULL!\n"); return FALSE; } weighted=graph_weighted(g); for (i=0; i < g->n; i++) { if (g->edges[i]==NULL) { if (output) fprintf(output," WARNING: Graph edge set " "NULL!\n" " (further warning suppressed)\n"); return FALSE; } if (SET_MAX_SIZE(g->edges[i]) < g->n) { if (output) fprintf(output," WARNING: Graph edge set " "too small!\n" " (further warnings suppressed)\n"); return FALSE; } for (j=0; j < g->n; j++) { if (SET_CONTAINS_FAST(g->edges[i],j)) { edges++; if (i==j) { refl++; } if (!SET_CONTAINS_FAST(g->edges[j],i)) { asymm++; } } } for (j=g->n; j < SET_ARRAY_LENGTH(g->edges[i])*ELEMENTSIZE; j++) { if (SET_CONTAINS_FAST(g->edges[i],j)) extra++; } if (g->weights[i] <= 0) nonpos++; if (weightweights[i]; } edges/=2; /* Each is counted twice. */ if (output) { /* Semi-weighted means all weights are equal, but not 1. */ fprintf(output,"%s graph has %d vertices, %d edges " "(density %.2f).\n", weighted?"Weighted": ((g->weights[0]==1)?"Unweighted":"Semi-weighted"), g->n,edges,(float)edges/((float)(g->n - 1)*(g->n)/2)); if (asymm) fprintf(output," WARNING: Graph contained %d " "asymmetric edges!\n",asymm); if (refl) fprintf(output," WARNING: Graph contained %d " "reflexive edges!\n",refl); if (nonpos) fprintf(output," WARNING: Graph contained %d " "non-positive vertex weights!\n",nonpos); if (extra) fprintf(output," WARNING: Graph contained %d edges " "to non-existent vertices!\n",extra); if (weight>=INT_MAX) fprintf(output," WARNING: Total graph weight >= " "INT_MAX!\n"); if (asymm==0 && refl==0 && nonpos==0 && extra==0 && weight=INT_MAX) return FALSE; return TRUE; } /* * graph_test_regular() * * Returns the vertex degree for regular graphs, or -1 if the graph is * not regular. */ int graph_test_regular(graph_t *g) { int i,n; n=set_size(g->edges[0]); for (i=1; i < g->n; i++) { if (set_size(g->edges[i]) != n) return -1; } return n; } #endif leidenbase/src/core/cliques/cliquer/misc.h0000644000176200001440000000174314447675374020333 0ustar liggesusers #ifndef CLIQUER_MISC_H #define CLIQUER_MISC_H #include "igraph_error.h" #include "cliquerconf.h" /* * We #define boolean instead of using a typedef because nauty.h uses it * also. AFAIK, there is no way to check for an existing typedef, and * re-typedefing is illegal (even when using exactly the same datatype!). */ #ifndef boolean #define boolean int #endif /* * The original cliquer source has some functions incorrectly marked as unused, * thus leave this undefined. */ #define UNUSED_FUNCTION /* * Default inlining directive: "inline" */ #ifndef INLINE #define INLINE inline #endif #include #include #ifndef ASSERT #define ASSERT IGRAPH_ASSERT #endif /* !ASSERT */ #ifndef FALSE #define FALSE (0) #endif #ifndef TRUE #define TRUE (!FALSE) #endif #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #endif #ifndef MAX #define MAX(a,b) (((a)>(b))?(a):(b)) #endif #ifndef ABS #define ABS(v) (((v)<0)?(-(v)):(v)) #endif #endif /* !CLIQUER_MISC_H */ leidenbase/src/core/cliques/cliquer/cliquer.c0000644000176200001440000013141714447675374021041 0ustar liggesusers /* * This file contains the clique searching routines. * * Copyright (C) 2002 Sampo Niskanen, Patric Östergård. * Licensed under the GNU GPL, read the file LICENSE for details. */ #include #include #include /* #include #include #include */ #include "cliquer.h" #include "config.h" /* Default cliquer options */ IGRAPH_THREAD_LOCAL clique_options clique_default_options = { reorder_by_default, NULL, /*clique_print_time*/ NULL, NULL, NULL, NULL, NULL, 0 }; /* Calculate d/q, rounding result upwards/downwards. */ #define DIV_UP(d,q) (((d)+(q)-1)/(q)) #define DIV_DOWN(d,q) ((int)((d)/(q))) /* Global variables used: */ /* These must be saved and restored in re-entrance. */ static IGRAPH_THREAD_LOCAL int *clique_size; /* c[i] == max. clique size in {0,1,...,i-1} */ static IGRAPH_THREAD_LOCAL set_t current_clique; /* Current clique being searched. */ static IGRAPH_THREAD_LOCAL set_t best_clique; /* Largest/heaviest clique found so far. */ /*static struct tms cputimer;*/ /* Timer for opts->time_function() */ /*static struct timeval realtimer;*/ /* Timer for opts->time_function() */ static IGRAPH_THREAD_LOCAL int clique_list_count=0; /* No. of cliques in opts->clique_list[] */ static IGRAPH_THREAD_LOCAL int weight_multiplier=1; /* Weights multiplied by this when passing * to time_function(). */ /* List cache (contains memory blocks of size g->n * sizeof(int)) */ static IGRAPH_THREAD_LOCAL int **temp_list=NULL; static IGRAPH_THREAD_LOCAL int temp_count=0; /* * Macros for re-entrance. ENTRANCE_SAVE() must be called immediately * after variable definitions, ENTRANCE_RESTORE() restores global * variables to original values. entrance_level should be increased * and decreased accordingly. */ static IGRAPH_THREAD_LOCAL int entrance_level=0; /* How many levels for entrance have occurred? */ #define ENTRANCE_SAVE() \ int *old_clique_size = clique_size; \ set_t old_current_clique = current_clique; \ set_t old_best_clique = best_clique; \ int old_clique_list_count = clique_list_count; \ int old_weight_multiplier = weight_multiplier; \ int **old_temp_list = temp_list; \ int old_temp_count = temp_count; \ /*struct tms old_cputimer; \ struct timeval old_realtimer; \ memcpy(&old_cputimer,&cputimer,sizeof(struct tms)); \ memcpy(&old_realtimer,&realtimer,sizeof(struct timeval));*/ #define ENTRANCE_RESTORE() \ clique_size = old_clique_size; \ current_clique = old_current_clique; \ best_clique = old_best_clique; \ clique_list_count = old_clique_list_count; \ weight_multiplier = old_weight_multiplier; \ temp_list = old_temp_list; \ temp_count = old_temp_count; \ /*memcpy(&cputimer,&old_cputimer,sizeof(struct tms)); \ memcpy(&realtimer,&old_realtimer,sizeof(struct timeval));*/ /* Number of clock ticks per second (as returned by sysconf(_SC_CLK_TCK)) */ /*static int clocks_per_sec=0;*/ /* Recursion and helper functions */ static boolean sub_unweighted_single(int *table, int size, int min_size, graph_t *g); static CLIQUER_LARGE_INT sub_unweighted_all(int *table, int size, int min_size, int max_size, boolean maximal, graph_t *g, clique_options *opts); static int sub_weighted_all(int *table, int size, int weight, int current_weight, int prune_low, int prune_high, int min_weight, int max_weight, boolean maximal, graph_t *g, clique_options *opts); static boolean store_clique(set_t clique, graph_t *g, clique_options *opts); static boolean is_maximal(set_t clique, graph_t *g); static boolean false_function(set_t clique,graph_t *g,clique_options *opts); /***** Unweighted searches *****/ /* * Unweighted searches are done separately from weighted searches because * some effective pruning methods can be used when the vertex weights * are all 1. Single and all clique finding routines are separated, * because the single clique finding routine can store the found clique * while it is returning from the recursion, thus requiring no implicit * storing of the current clique. When searching for all cliques the * current clique must be stored. */ /* * unweighted_clique_search_single() * * Searches for a single clique of size min_size. Stores maximum clique * sizes into clique_size[]. * * table - the order of the vertices in g to use * min_size - minimum size of clique to search for. If min_size==0, * searches for a maximum clique. * g - the graph * opts - time printing options * * opts->time_function is called after each base-level recursion, if * non-NULL. * * Returns the size of the clique found, or 0 if min_size>0 and a clique * of that size was not found (or if time_function aborted the search). * The largest clique found is stored in current_clique. * * Note: Does NOT use opts->user_function of opts->clique_list. */ static int unweighted_clique_search_single(int *table, int min_size, graph_t *g, clique_options *opts) { /* struct tms tms; struct timeval timeval; */ int i,j; int v,w; int *newtable; int newsize; v=table[0]; clique_size[v]=1; set_empty(current_clique); SET_ADD_ELEMENT(current_clique,v); if (min_size==1) return 1; if (temp_count) { temp_count--; newtable=temp_list[temp_count]; } else { newtable=malloc(g->n * sizeof(int)); } for (i=1; i < g->n; i++) { w=v; v=table[i]; newsize=0; for (j=0; jtime_function) { gettimeofday(&timeval,NULL); times(&tms); if (!opts->time_function(entrance_level, i+1,g->n,clique_size[v] * weight_multiplier, (double)(tms.tms_utime- cputimer.tms_utime)/ clocks_per_sec, timeval.tv_sec- realtimer.tv_sec+ (double)(timeval.tv_usec- realtimer.tv_usec)/ 1000000,opts)) { temp_list[temp_count++]=newtable; return 0; } } */ if (min_size) { if (clique_size[v]>=min_size) { temp_list[temp_count++]=newtable; return clique_size[v]; } if (clique_size[v]+g->n-i-1 < min_size) { temp_list[temp_count++]=newtable; return 0; } } } temp_list[temp_count++]=newtable; if (min_size) return 0; return clique_size[v]; } /* * sub_unweighted_single() * * Recursion function for searching for a single clique of size min_size. * * table - subset of the vertices in graph * size - size of table * min_size - size of clique to look for within the subgraph * (decreased with every recursion) * g - the graph * * Returns TRUE if a clique of size min_size is found, FALSE otherwise. * If a clique of size min_size is found, it is stored in current_clique. * * clique_size[] for all values in table must be defined and correct, * otherwise inaccurate results may occur. */ static boolean sub_unweighted_single(int *table, int size, int min_size, graph_t *g) { int i; int v; int *newtable; int *p1, *p2; /* Zero or one vertices needed anymore. */ if (min_size <= 1) { if (size>0 && min_size==1) { set_empty(current_clique); SET_ADD_ELEMENT(current_clique,table[0]); return TRUE; } if (min_size==0) { set_empty(current_clique); return TRUE; } return FALSE; } if (size < min_size) return FALSE; /* Dynamic memory allocation with cache */ if (temp_count) { temp_count--; newtable=temp_list[temp_count]; } else { newtable=malloc(g->n * sizeof(int)); } for (i = size-1; i >= 0; i--) { v = table[i]; if (clique_size[v] < min_size) break; /* This is faster when compiling with gcc than placing * this in the for-loop condition. */ if (i+1 < min_size) break; /* Very ugly code, but works faster than "for (i=...)" */ p1 = newtable; for (p2=table; p2 < table+i; p2++) { int w = *p2; if (GRAPH_IS_EDGE(g, v, w)) { *p1 = w; p1++; } } /* Avoid unneccessary loops (next size == p1-newtable) */ if (p1-newtable < min_size-1) continue; /* Now p1-newtable >= min_size-1 >= 2-1 == 1, so we can use * p1-newtable-1 safely. */ if (clique_size[newtable[p1-newtable-1]] < min_size-1) continue; if (sub_unweighted_single(newtable,p1-newtable, min_size-1,g)) { /* Clique found. */ SET_ADD_ELEMENT(current_clique,v); temp_list[temp_count++]=newtable; return TRUE; } } temp_list[temp_count++]=newtable; return FALSE; } /* * unweighted_clique_search_all() * * Searches for all cliques with size at least min_size and at most * max_size. Stores the cliques as opts declares. * * table - the order of the vertices in g to search * start - first index where the subgraph table[0], ..., table[start] * might include a requested kind of clique * min_size - minimum size of clique to search for. min_size > 0 ! * max_size - maximum size of clique to search for. If no upper limit * is desired, use eg. INT_MAX * maximal - requires cliques to be maximal * g - the graph * opts - time printing and clique storage options * * Cliques found are stored as defined by opts->user_function and * opts->clique_list. opts->time_function is called after each * base-level recursion, if non-NULL. * * clique_size[] must be defined and correct for all values of * table[0], ..., table[start-1]. * * Returns the number of cliques stored (not neccessarily number of cliques * in graph, if user/time_function aborts). */ static CLIQUER_LARGE_INT unweighted_clique_search_all(int *table, int start, int min_size, int max_size, boolean maximal, graph_t *g, clique_options *opts) { /* struct timeval timeval; struct tms tms; */ int i, j; int v; int *newtable; int newsize; CLIQUER_LARGE_INT r; CLIQUER_LARGE_INT count=0; if (temp_count) { temp_count--; newtable=temp_list[temp_count]; } else { newtable=malloc(g->n * sizeof(int)); } clique_list_count=0; set_empty(current_clique); for (i=start; i < g->n; i++) { v=table[i]; clique_size[v]=min_size; /* Do not prune here. */ newsize=0; for (j=0; jtime_function) { gettimeofday(&timeval,NULL); times(&tms); if (!opts->time_function(entrance_level, i+1,g->n,min_size * weight_multiplier, (double)(tms.tms_utime- cputimer.tms_utime)/ clocks_per_sec, timeval.tv_sec- realtimer.tv_sec+ (double)(timeval.tv_usec- realtimer.tv_usec)/ 1000000,opts)) { /* Abort. */ break; } } #endif } temp_list[temp_count++]=newtable; return count; } /* * sub_unweighted_all() * * Recursion function for searching for all cliques of given size. * * table - subset of vertices of graph g * size - size of table * min_size - minimum size of cliques to search for (decreased with * every recursion) * max_size - maximum size of cliques to search for (decreased with * every recursion). If no upper limit is desired, use * eg. INT_MAX * maximal - require cliques to be maximal (passed through) * g - the graph * opts - storage options * * All cliques of suitable size found are stored according to opts. * * Returns the number of cliques found. If user_function returns FALSE, * then the number of cliques is returned negative. * * Uses current_clique to store the currently-being-searched clique. * clique_size[] for all values in table must be defined and correct, * otherwise inaccurate results may occur. */ static CLIQUER_LARGE_INT sub_unweighted_all(int *table, int size, int min_size, int max_size, boolean maximal, graph_t *g, clique_options *opts) { int i; int v; int *newtable; int *p1, *p2; CLIQUER_LARGE_INT n; CLIQUER_LARGE_INT count=0; /* Amount of cliques found */ if (min_size <= 0) { if ((!maximal) || is_maximal(current_clique,g)) { /* We've found one. Store it. */ count++; if (!store_clique(current_clique,g,opts)) { return -count; } } if (max_size <= 0) { /* If we add another element, size will be too big. */ return count; } } if (size < min_size) { return count; } /* Dynamic memory allocation with cache */ if (temp_count) { temp_count--; newtable=temp_list[temp_count]; } else { newtable=malloc(g->n * sizeof(int)); } for (i=size-1; i>=0; i--) { v = table[i]; if (clique_size[v] < min_size) { break; } if (i+1 < min_size) { break; } /* Very ugly code, but works faster than "for (i=...)" */ p1 = newtable; for (p2=table; p2 < table+i; p2++) { int w = *p2; if (GRAPH_IS_EDGE(g, v, w)) { *p1 = w; p1++; } } /* Avoid unneccessary loops (next size == p1-newtable) */ if (p1-newtable < min_size-1) { continue; } SET_ADD_ELEMENT(current_clique,v); n=sub_unweighted_all(newtable,p1-newtable, min_size-1,max_size-1,maximal,g,opts); SET_DEL_ELEMENT(current_clique,v); if (n < 0) { /* Abort. */ count -= n; count = -count; break; } count+=n; } temp_list[temp_count++]=newtable; return count; } /***** Weighted clique searches *****/ /* * Weighted clique searches can use the same recursive routine, because * in both cases (single/all) they have to search through all potential * permutations searching for heavier cliques. */ /* * weighted_clique_search_single() * * Searches for a single clique of weight at least min_weight, and at * most max_weight. Stores maximum clique sizes into clique_size[] * (or min_weight-1, whichever is smaller). * * table - the order of the vertices in g to use * min_weight - minimum weight of clique to search for. If min_weight==0, * then searches for a maximum weight clique * max_weight - maximum weight of clique to search for. If no upper limit * is desired, use eg. INT_MAX * g - the graph * opts - time printing options * * opts->time_function is called after each base-level recursion, if * non-NULL. * * Returns 0 if a clique of requested weight was not found (also if * time_function requested an abort), otherwise returns >= 1. * If min_weight==0 (search for maximum-weight clique), then the return * value is the weight of the clique found. The found clique is stored * in best_clique. * * Note: Does NOT use opts->user_function of opts->clique_list. */ static int weighted_clique_search_single(int *table, int min_weight, int max_weight, graph_t *g, clique_options *opts) { /* struct timeval timeval; struct tms tms; */ int i,j; int v; int *newtable; int newsize; int newweight; int search_weight; int min_w; clique_options localopts; if (min_weight==0) min_w=INT_MAX; else min_w=min_weight; if (min_weight==1) { /* min_weight==1 may cause trouble in the routine, and * it's trivial to check as it's own case. * We write nothing to clique_size[]. */ for (i=0; i < g->n; i++) { if (g->weights[table[i]] <= max_weight) { set_empty(best_clique); SET_ADD_ELEMENT(best_clique,table[i]); return g->weights[table[i]]; } } return 0; } localopts.time_function=NULL; localopts.reorder_function=NULL; localopts.reorder_map=NULL; localopts.user_function=false_function; localopts.user_data=NULL; localopts.clique_list=&best_clique; localopts.clique_list_length=1; clique_list_count=0; v=table[0]; set_empty(best_clique); SET_ADD_ELEMENT(best_clique,v); search_weight=g->weights[v]; if (min_weight && (search_weight >= min_weight)) { if (search_weight <= max_weight) { /* Found suitable clique. */ return search_weight; } search_weight=min_weight-1; } clique_size[v]=search_weight; set_empty(current_clique); if (temp_count) { temp_count--; newtable=temp_list[temp_count]; } else { newtable=malloc(g->n * sizeof(int)); } for (i = 1; i < g->n; i++) { v=table[i]; newsize=0; newweight=0; for (j=0; jweights[table[j]]; newtable[newsize]=table[j]; newsize++; } } SET_ADD_ELEMENT(current_clique,v); search_weight=sub_weighted_all(newtable,newsize,newweight, g->weights[v],search_weight, clique_size[table[i-1]] + g->weights[v], min_w,max_weight,FALSE, g,&localopts); SET_DEL_ELEMENT(current_clique,v); if (search_weight < 0) { break; } clique_size[v]=search_weight; /* if (opts->time_function) { gettimeofday(&timeval,NULL); times(&tms); if (!opts->time_function(entrance_level, i+1,g->n,clique_size[v] * weight_multiplier, (double)(tms.tms_utime- cputimer.tms_utime)/ clocks_per_sec, timeval.tv_sec- realtimer.tv_sec+ (double)(timeval.tv_usec- realtimer.tv_usec)/ 1000000,opts)) { set_free(current_clique); current_clique=NULL; break; } } */ } temp_list[temp_count++]=newtable; if (min_weight && (search_weight > 0)) { /* Requested clique has not been found. */ return 0; } return clique_size[table[i-1]]; } /* * weighted_clique_search_all() * * Searches for all cliques with weight at least min_weight and at most * max_weight. Stores the cliques as opts declares. * * table - the order of the vertices in g to search * start - first index where the subgraph table[0], ..., table[start] * might include a requested kind of clique * min_weight - minimum weight of clique to search for. min_weight > 0 ! * max_weight - maximum weight of clique to search for. If no upper limit * is desired, use eg. INT_MAX * maximal - search only for maximal cliques * g - the graph * opts - time printing and clique storage options * * Cliques found are stored as defined by opts->user_function and * opts->clique_list. opts->time_function is called after each * base-level recursion, if non-NULL. * * clique_size[] must be defined and correct for all values of * table[0], ..., table[start-1]. * * Returns the number of cliques stored (not neccessarily number of cliques * in graph, if user/time_function aborts). */ static int weighted_clique_search_all(int *table, int start, int min_weight, int max_weight, boolean maximal, graph_t *g, clique_options *opts) { /* struct timeval timeval; struct tms tms; */ int i,j; int v; int *newtable; int newsize; int newweight; if (temp_count) { temp_count--; newtable=temp_list[temp_count]; } else { newtable=malloc(g->n * sizeof(int)); } clique_list_count=0; set_empty(current_clique); for (i=start; i < g->n; i++) { v=table[i]; clique_size[v]=min_weight; /* Do not prune here. */ newsize=0; newweight=0; for (j=0; jweights[table[j]]; newsize++; } } SET_ADD_ELEMENT(current_clique,v); j=sub_weighted_all(newtable,newsize,newweight, g->weights[v],min_weight-1,INT_MAX, min_weight,max_weight,maximal,g,opts); SET_DEL_ELEMENT(current_clique,v); if (j<0) { /* Abort. */ break; } /* if (opts->time_function) { gettimeofday(&timeval,NULL); times(&tms); if (!opts->time_function(entrance_level, i+1,g->n,clique_size[v] * weight_multiplier, (double)(tms.tms_utime- cputimer.tms_utime)/ clocks_per_sec, timeval.tv_sec- realtimer.tv_sec+ (double)(timeval.tv_usec- realtimer.tv_usec)/ 1000000,opts)) { set_free(current_clique); current_clique=NULL; break; } } */ } temp_list[temp_count++]=newtable; return clique_list_count; } /* * sub_weighted_all() * * Recursion function for searching for all cliques of given weight. * * table - subset of vertices of graph g * size - size of table * weight - total weight of vertices in table * current_weight - weight of clique found so far * prune_low - ignore all cliques with weight less or equal to this value * (often heaviest clique found so far) (passed through) * prune_high - maximum weight possible for clique in this subgraph * (passed through) * min_size - minimum weight of cliques to search for (passed through) * Must be greater than 0. * max_size - maximum weight of cliques to search for (passed through) * If no upper limit is desired, use eg. INT_MAX * maximal - search only for maximal cliques * g - the graph * opts - storage options * * All cliques of suitable weight found are stored according to opts. * * Returns weight of heaviest clique found (prune_low if a heavier clique * hasn't been found); if a clique with weight at least min_size is found * then min_size-1 is returned. If clique storage failed, -1 is returned. * * The largest clique found smaller than max_weight is stored in * best_clique, if non-NULL. * * Uses current_clique to store the currently-being-searched clique. * clique_size[] for all values in table must be defined and correct, * otherwise inaccurate results may occur. * * To search for a single maximum clique, use min_weight==max_weight==INT_MAX, * with best_clique non-NULL. To search for a single given-weight clique, * use opts->clique_list and opts->user_function=false_function. When * searching for all cliques, min_weight should be given the minimum weight * desired. */ static int sub_weighted_all(int *table, int size, int weight, int current_weight, int prune_low, int prune_high, int min_weight, int max_weight, boolean maximal, graph_t *g, clique_options *opts) { int i; int v,w; int *newtable; int *p1, *p2; int newweight; if (current_weight >= min_weight) { if ((current_weight <= max_weight) && ((!maximal) || is_maximal(current_clique,g))) { /* We've found one. Store it. */ if (!store_clique(current_clique,g,opts)) { return -1; } } if (current_weight >= max_weight) { /* Clique too heavy. */ return min_weight-1; } } if (size <= 0) { /* current_weight < min_weight, prune_low < min_weight, * so return value is always < min_weight. */ if (current_weight>prune_low) { if (best_clique) { best_clique = set_copy(best_clique,current_clique); } if (current_weight < min_weight) return current_weight; else return min_weight-1; } else { return prune_low; } } /* Dynamic memory allocation with cache */ if (temp_count) { temp_count--; newtable=temp_list[temp_count]; } else { newtable=malloc(g->n * sizeof(int)); } for (i = size-1; i >= 0; i--) { v = table[i]; if (current_weight+clique_size[v] <= prune_low) { /* Dealing with subset without heavy enough clique. */ break; } if (current_weight+weight <= prune_low) { /* Even if all elements are added, won't do. */ break; } /* Very ugly code, but works faster than "for (i=...)" */ p1 = newtable; newweight = 0; for (p2=table; p2 < table+i; p2++) { w = *p2; if (GRAPH_IS_EDGE(g, v, w)) { *p1 = w; newweight += g->weights[w]; p1++; } } w=g->weights[v]; weight-=w; /* Avoid a few unneccessary loops */ if (current_weight+w+newweight <= prune_low) { continue; } SET_ADD_ELEMENT(current_clique,v); prune_low=sub_weighted_all(newtable,p1-newtable, newweight, current_weight+w, prune_low,prune_high, min_weight,max_weight,maximal, g,opts); SET_DEL_ELEMENT(current_clique,v); if ((prune_low<0) || (prune_low>=prune_high)) { /* Impossible to find larger clique. */ break; } } temp_list[temp_count++]=newtable; return prune_low; } /***** Helper functions *****/ /* * store_clique() * * Stores a clique according to given user options. * * clique - the clique to store * opts - storage options * * Returns FALSE if opts->user_function() returned FALSE; otherwise * returns TRUE. */ static boolean store_clique(set_t clique, graph_t *g, clique_options *opts) { clique_list_count++; /* clique_list[] */ if (opts->clique_list) { /* * This has been a major source of bugs: * Has clique_list_count been set to 0 before calling * the recursions? */ if (clique_list_count <= 0) { IGRAPH_FATAL("CLIQUER INTERNAL ERROR: clique_list_count has negative value! Please report as a bug."); } if (clique_list_count <= opts->clique_list_length) opts->clique_list[clique_list_count-1] = set_copy(opts->clique_list[clique_list_count-1], clique); } /* user_function() */ if (opts->user_function) { if (!opts->user_function(clique,g,opts)) { /* User function requested abort. */ return FALSE; } } return TRUE; } /* * maximalize_clique() * * Adds greedily all possible vertices in g to set s to make it a maximal * clique. * * s - clique of vertices to make maximal * g - graph * * Note: Not very optimized (uses a simple O(n^2) routine), but is called * at maximum once per clique_xxx() call, so it shouldn't matter. */ static void maximalize_clique(set_t s,graph_t *g) { int i,j; boolean add; for (i=0; i < g->n; i++) { add=TRUE; for (j=0; j < g->n; j++) { if (SET_CONTAINS_FAST(s,j) && !GRAPH_IS_EDGE(g,i,j)) { add=FALSE; break; } } if (add) { SET_ADD_ELEMENT(s,i); } } return; } /* * is_maximal() * * Check whether a clique is maximal or not. * * clique - set of vertices in clique * g - graph * * Returns TRUE is clique is a maximal clique of g, otherwise FALSE. */ static boolean is_maximal(set_t clique, graph_t *g) { int i,j; int *table; int len; boolean addable; if (temp_count) { temp_count--; table=temp_list[temp_count]; } else { table=malloc(g->n * sizeof(int)); } len=0; for (i=0; i < g->n; i++) if (SET_CONTAINS_FAST(clique,i)) table[len++]=i; for (i=0; i < g->n; i++) { addable=TRUE; for (j=0; jtime_function() requests abort). * * The returned clique is newly allocated and can be freed by set_free(). * * Note: Does NOT use opts->user_function() or opts->clique_list[]. */ set_t clique_unweighted_find_single(graph_t *g,int min_size,int max_size, boolean maximal, clique_options *opts) { int i; int *table; set_t s; ENTRANCE_SAVE(); entrance_level++; if (opts==NULL) opts=&clique_default_options; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(g!=NULL); ASSERT(min_size>=0); ASSERT(max_size>=0); ASSERT((max_size==0) || (min_size <= max_size)); ASSERT(!((min_size==0) && (max_size>0))); ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); if ((max_size>0) && (min_size>max_size)) { /* state was not changed */ entrance_level--; return NULL; } /* if (clocks_per_sec==0) clocks_per_sec=sysconf(_SC_CLK_TCK); ASSERT(clocks_per_sec>0); */ /* Dynamic allocation */ current_clique=set_new(g->n); clique_size=malloc(g->n * sizeof(int)); /* table allocated later */ temp_list=malloc((g->n+2)*sizeof(int *)); temp_count=0; /* "start clock" */ /* gettimeofday(&realtimer,NULL); times(&cputimer); */ /* reorder */ if (opts->reorder_function) { table=opts->reorder_function(g,FALSE); } else if (opts->reorder_map) { table=reorder_duplicate(opts->reorder_map,g->n); } else { table=reorder_ident(g->n); } ASSERT(reorder_is_bijection(table,g->n)); if (unweighted_clique_search_single(table,min_size,g,opts)==0) { set_free(current_clique); current_clique=NULL; goto cleanreturn; } if (maximal && (min_size>0)) { maximalize_clique(current_clique,g); if ((max_size > 0) && (set_size(current_clique) > max_size)) { clique_options localopts; s = set_new(g->n); localopts.time_function = opts->time_function; localopts.output = opts->output; localopts.user_function = false_function; localopts.clique_list = &s; localopts.clique_list_length = 1; for (i=0; i < g->n-1; i++) if (clique_size[table[i]]>=min_size) break; if (unweighted_clique_search_all(table,i,min_size, max_size,maximal, g,&localopts)) { set_free(current_clique); current_clique=s; } else { set_free(current_clique); current_clique=NULL; } } } cleanreturn: s=current_clique; /* Free resources */ for (i=0; i < temp_count; i++) free(temp_list[i]); free(temp_list); free(table); free(clique_size); ENTRANCE_RESTORE(); entrance_level--; return s; } /* * clique_unweighted_find_all() * * Find all cliques with size at least min_size and at most max_size. * * g - the graph * min_size - minimum size of cliques to search for. If min_size==0, * searches for maximum cliques. * max_size - maximum size of cliques to search for. If max_size==0, no * upper limit is used. If min_size==0, this must also be 0. * maximal - require cliques to be maximal cliques * opts - time printing and clique storage options * * Returns the number of cliques found. This can be less than the number * of cliques in the graph iff opts->time_function() or opts->user_function() * returns FALSE (request abort). * * The cliques found are stored in opts->clique_list[] and * opts->user_function() is called with them (if non-NULL). The cliques * stored in opts->clique_list[] are newly allocated, and can be freed * by set_free(). */ CLIQUER_LARGE_INT clique_unweighted_find_all(graph_t *g, int min_size, int max_size, boolean maximal, clique_options *opts) { int i; int *table; CLIQUER_LARGE_INT count; ENTRANCE_SAVE(); entrance_level++; if (opts==NULL) opts=&clique_default_options; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(g!=NULL); ASSERT(min_size>=0); ASSERT(max_size>=0); ASSERT((max_size==0) || (min_size <= max_size)); ASSERT(!((min_size==0) && (max_size>0))); ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); if ((max_size>0) && (min_size>max_size)) { /* state was not changed */ entrance_level--; return 0; } /* if (clocks_per_sec==0) clocks_per_sec=sysconf(_SC_CLK_TCK); ASSERT(clocks_per_sec>0); */ /* Dynamic allocation */ current_clique=set_new(g->n); clique_size=malloc(g->n * sizeof(int)); /* table allocated later */ temp_list=malloc((g->n+2)*sizeof(int *)); temp_count=0; clique_list_count=0; memset(clique_size,0,g->n * sizeof(int)); /* "start clock" */ /* gettimeofday(&realtimer,NULL); times(&cputimer); */ /* reorder */ if (opts->reorder_function) { table=opts->reorder_function(g,FALSE); } else if (opts->reorder_map) { table=reorder_duplicate(opts->reorder_map,g->n); } else { table=reorder_ident(g->n); } ASSERT(reorder_is_bijection(table,g->n)); /* Search as normal until there is a chance to find a suitable * clique. */ if (unweighted_clique_search_single(table,min_size,g,opts)==0) { count=0; goto cleanreturn; } if (min_size==0 && max_size==0) { min_size=max_size=clique_size[table[g->n-1]]; maximal=FALSE; /* No need to test, since we're searching * for maximum cliques. */ } if (max_size==0) { max_size=INT_MAX; } for (i=0; i < g->n-1; i++) if (clique_size[table[i]] >= min_size) break; count=unweighted_clique_search_all(table,i,min_size,max_size, maximal,g,opts); cleanreturn: /* Free resources */ for (i=0; itime_function() requests abort). * * The returned clique is newly allocated and can be freed by set_free(). * * Note: Does NOT use opts->user_function() or opts->clique_list[]. * Note: Automatically uses clique_unweighted_find_single if all vertex * weights are the same. */ set_t clique_find_single(graph_t *g,int min_weight,int max_weight, boolean maximal, clique_options *opts) { int i; int *table; set_t s; ENTRANCE_SAVE(); entrance_level++; if (opts==NULL) opts=&clique_default_options; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(g!=NULL); ASSERT(min_weight>=0); ASSERT(max_weight>=0); ASSERT((max_weight==0) || (min_weight <= max_weight)); ASSERT(!((min_weight==0) && (max_weight>0))); ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); if ((max_weight>0) && (min_weight>max_weight)) { /* state was not changed */ entrance_level--; return NULL; } /* if (clocks_per_sec==0) clocks_per_sec=sysconf(_SC_CLK_TCK); ASSERT(clocks_per_sec>0); */ /* Check whether we can use unweighted routines. */ if (!graph_weighted(g)) { min_weight=DIV_UP(min_weight,g->weights[0]); if (max_weight) { max_weight=DIV_DOWN(max_weight,g->weights[0]); if (max_weight < min_weight) { /* state was not changed */ entrance_level--; return NULL; } } weight_multiplier = g->weights[0]; entrance_level--; s=clique_unweighted_find_single(g,min_weight,max_weight, maximal,opts); ENTRANCE_RESTORE(); return s; } /* Dynamic allocation */ current_clique=set_new(g->n); best_clique=set_new(g->n); clique_size=malloc(g->n * sizeof(int)); memset(clique_size, 0, g->n * sizeof(int)); /* table allocated later */ temp_list=malloc((g->n+2)*sizeof(int *)); temp_count=0; clique_list_count=0; /* "start clock" */ /* gettimeofday(&realtimer,NULL); times(&cputimer); */ /* reorder */ if (opts->reorder_function) { table=opts->reorder_function(g,TRUE); } else if (opts->reorder_map) { table=reorder_duplicate(opts->reorder_map,g->n); } else { table=reorder_ident(g->n); } ASSERT(reorder_is_bijection(table,g->n)); if (max_weight==0) max_weight=INT_MAX; if (weighted_clique_search_single(table,min_weight,max_weight, g,opts)==0) { /* Requested clique has not been found. */ set_free(best_clique); best_clique=NULL; goto cleanreturn; } if (maximal && (min_weight>0)) { maximalize_clique(best_clique,g); if (graph_subgraph_weight(g,best_clique) > max_weight) { clique_options localopts; localopts.time_function = opts->time_function; localopts.output = opts->output; localopts.user_function = false_function; localopts.clique_list = &best_clique; localopts.clique_list_length = 1; for (i=0; i < g->n-1; i++) if ((clique_size[table[i]] >= min_weight) || (clique_size[table[i]] == 0)) break; if (!weighted_clique_search_all(table,i,min_weight, max_weight,maximal, g,&localopts)) { set_free(best_clique); best_clique=NULL; } } } cleanreturn: s=best_clique; /* Free resources */ for (i=0; i < temp_count; i++) free(temp_list[i]); free(temp_list); temp_list=NULL; temp_count=0; free(table); set_free(current_clique); current_clique=NULL; free(clique_size); clique_size=NULL; ENTRANCE_RESTORE(); entrance_level--; return s; } /* * clique_find_all() * * Find all cliques with weight at least min_weight and at most max_weight. * * g - the graph * min_weight - minimum weight of cliques to search for. If min_weight==0, * searches for maximum weight cliques. * max_weight - maximum weight of cliques to search for. If max_weight==0, * no upper limit is used. If min_weight==0, max_weight must * also be 0. * maximal - require cliques to be maximal cliques * opts - time printing and clique storage options * * Returns the number of cliques found. This can be less than the number * of cliques in the graph iff opts->time_function() or opts->user_function() * returns FALSE (request abort). * * The cliques found are stored in opts->clique_list[] and * opts->user_function() is called with them (if non-NULL). The cliques * stored in opts->clique_list[] are newly allocated, and can be freed * by set_free(). * * Note: Automatically uses clique_unweighted_find_all if all vertex * weights are the same. */ int clique_find_all(graph_t *g, int min_weight, int max_weight, boolean maximal, clique_options *opts) { int i,n; int *table; CLIQUER_LARGE_INT r; ENTRANCE_SAVE(); entrance_level++; if (opts==NULL) opts=&clique_default_options; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(g!=NULL); ASSERT(min_weight>=0); ASSERT(max_weight>=0); ASSERT((max_weight==0) || (min_weight <= max_weight)); ASSERT(!((min_weight==0) && (max_weight>0))); ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); if ((max_weight>0) && (min_weight>max_weight)) { /* state was not changed */ entrance_level--; return 0; } /* if (clocks_per_sec==0) clocks_per_sec=sysconf(_SC_CLK_TCK); ASSERT(clocks_per_sec>0); */ if (!graph_weighted(g)) { min_weight=DIV_UP(min_weight,g->weights[0]); if (max_weight) { max_weight=DIV_DOWN(max_weight,g->weights[0]); if (max_weight < min_weight) { /* state was not changed */ entrance_level--; return 0; } } weight_multiplier = g->weights[0]; entrance_level--; r=clique_unweighted_find_all(g,min_weight,max_weight,maximal, opts); ENTRANCE_RESTORE(); return r; } /* Dynamic allocation */ current_clique=set_new(g->n); best_clique=set_new(g->n); clique_size=malloc(g->n * sizeof(int)); memset(clique_size, 0, g->n * sizeof(int)); /* table allocated later */ temp_list=malloc((g->n+2)*sizeof(int *)); temp_count=0; /* "start clock" */ /* gettimeofday(&realtimer,NULL); times(&cputimer); */ /* reorder */ if (opts->reorder_function) { table=opts->reorder_function(g,TRUE); } else if (opts->reorder_map) { table=reorder_duplicate(opts->reorder_map,g->n); } else { table=reorder_ident(g->n); } ASSERT(reorder_is_bijection(table,g->n)); /* First phase */ n=weighted_clique_search_single(table,min_weight,INT_MAX,g,opts); if (n==0) { /* Requested clique has not been found. */ goto cleanreturn; } if (min_weight==0) { min_weight=n; max_weight=n; maximal=FALSE; /* They're maximum cliques already. */ } if (max_weight==0) max_weight=INT_MAX; for (i=0; i < g->n; i++) if ((clique_size[table[i]] >= min_weight) || (clique_size[table[i]] == 0)) break; /* Second phase */ n=weighted_clique_search_all(table,i,min_weight,max_weight,maximal, g,opts); cleanreturn: /* Free resources */ for (i=0; i < temp_count; i++) free(temp_list[i]); free(temp_list); free(table); set_free(current_clique); set_free(best_clique); free(clique_size); ENTRANCE_RESTORE(); entrance_level--; return n; } #if 0 /* * clique_print_time() * * Reports current running information every 0.1 seconds or when values * change. * * level - re-entrance level * i - current recursion level * n - maximum recursion level * max - weight of heaviest clique found * cputime - CPU time used in algorithm so far * realtime - real time used in algorithm so far * opts - prints information to (FILE *)opts->output (or stdout if NULL) * * Returns always TRUE (ie. never requests abort). */ boolean clique_print_time(int level, int i, int n, int max, double cputime, double realtime, clique_options *opts) { static float prev_time=100; static int prev_i=100; static int prev_max=100; static int prev_level=0; FILE *fp=opts->output; int j; if (fp==NULL) fp=stdout; if (ABS(prev_time-realtime)>0.1 || i==n || ioutput (or stdout if NULL) * * Returns always TRUE (ie. never requests abort). */ boolean clique_print_time_always(int level, int i, int n, int max, double cputime, double realtime, clique_options *opts) { static float prev_time=100; static int prev_i=100; FILE *fp=opts->output; int j; if (fp==NULL) fp=stdout; for (j=1; j /* This is an igraph-specific modification to cliquer. * We use a 64-bit CLIQUER_LARGE_INT (even on 32-bit systems) in places * which are prone to overflow. Since cliquer indicates interruption by * returning -1 times the clique count, the effect of overflow is that * it returns a partial (i.e. incorrect) result without warning. */ #include #ifndef CLIQUER_LARGE_INT #define CLIQUER_LARGE_INT int64_t #endif #include "set.h" #include "graph.h" #include "reorder.h" typedef struct _clique_options clique_options; struct _clique_options { int *(*reorder_function)(graph_t *, boolean); int *reorder_map; /* arguments: level, n, max, user_time, system_time, opts */ boolean (*time_function)(int,int,int,int,double,double, clique_options *); FILE *output; boolean (*user_function)(set_t,graph_t *,clique_options *); void *user_data; set_t *clique_list; int clique_list_length; }; /* Weighted clique functions */ extern int clique_max_weight(graph_t *g,clique_options *opts); extern set_t clique_find_single(graph_t *g,int min_weight,int max_weight, boolean maximal, clique_options *opts); extern int clique_find_all(graph_t *g, int req_weight, boolean exact, boolean maximal, clique_options *opts); /* Unweighted clique functions */ #define clique_unweighted_max_size clique_unweighted_max_weight extern int clique_unweighted_max_weight(graph_t *g, clique_options *opts); extern set_t clique_unweighted_find_single(graph_t *g,int min_size, int max_size,boolean maximal, clique_options *opts); extern CLIQUER_LARGE_INT clique_unweighted_find_all(graph_t *g, int min_size, int max_size, boolean maximal, clique_options *opts); /* Time printing functions */ /* extern boolean clique_print_time(int level, int i, int n, int max, double cputime, double realtime, clique_options *opts); extern boolean clique_print_time_always(int level, int i, int n, int max, double cputime, double realtime, clique_options *opts); */ /* Alternate spelling (let's be a little forgiving): */ #define cliquer_options clique_options #define cliquer_default_options clique_default_options #endif /* !CLIQUER_H */ leidenbase/src/core/cliques/cliques.c0000644000176200001440000012414414447675374017375 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_cliques.h" #include "igraph_error.h" #include "igraph_memory.h" #include "igraph_constants.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "igraph_stack.h" #include "cliques/cliquer_internal.h" #include "core/interruption.h" #include "core/set.h" #include /* memset */ static void igraph_i_cliques_free_res(igraph_vector_ptr_t *res) { long i, n; n = igraph_vector_ptr_size(res); for (i = 0; i < n; i++) { if (VECTOR(*res)[i] != 0) { igraph_vector_destroy(VECTOR(*res)[i]); igraph_free(VECTOR(*res)[i]); } } igraph_vector_ptr_clear(res); } static int igraph_i_find_k_cliques( const igraph_t *graph, long int size, const igraph_real_t *member_storage, igraph_real_t **new_member_storage, long int old_clique_count, long int *clique_count, igraph_vector_t *neis, igraph_bool_t independent_vertices) { long int j, k, l, m, n, new_member_storage_size; const igraph_real_t *c1, *c2; igraph_real_t v1, v2; igraph_bool_t ok; /* Allocate the storage */ *new_member_storage = IGRAPH_REALLOC(*new_member_storage, (size_t) (size * old_clique_count), igraph_real_t); if (*new_member_storage == 0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } new_member_storage_size = size * old_clique_count; IGRAPH_FINALLY(igraph_free, *new_member_storage); m = n = 0; /* Now consider all pairs of i-1-cliques and see if they can be merged */ for (j = 0; j < old_clique_count; j++) { for (k = j + 1; k < old_clique_count; k++) { IGRAPH_ALLOW_INTERRUPTION(); /* Since cliques are represented by their vertex indices in increasing * order, two cliques can be merged iff they have exactly the same * indices excluding one AND there is an edge between the two different * vertices */ c1 = member_storage + j * (size - 1); c2 = member_storage + k * (size - 1); /* Find the longest prefixes of c1 and c2 that are equal */ for (l = 0; l < size - 1 && c1[l] == c2[l]; l++) { (*new_member_storage)[m++] = c1[l]; } /* Now, if l == size-1, the two vectors are totally equal. This is a bug */ if (l == size - 1) { IGRAPH_WARNING("possible bug in igraph_cliques"); m = n; } else { /* Assuming that j (*new_member_storage)[m - 1]) { (*new_member_storage)[m++] = v2; n = m; } else { m = n; } } else { m = n; } } /* See if new_member_storage is full. If so, reallocate */ if (m == new_member_storage_size) { IGRAPH_FINALLY_CLEAN(1); *new_member_storage = IGRAPH_REALLOC(*new_member_storage, (size_t) new_member_storage_size * 2, igraph_real_t); if (*new_member_storage == 0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } new_member_storage_size *= 2; IGRAPH_FINALLY(igraph_free, *new_member_storage); } } } } /* Calculate how many cliques we have found */ *clique_count = n / size; IGRAPH_FINALLY_CLEAN(1); return 0; } /* Internal function for calculating cliques or independent vertex sets. * They are practically the same except that the complementer of the graph * should be used in the latter case. */ static int igraph_i_cliques(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size, igraph_bool_t independent_vertices) { igraph_integer_t no_of_nodes; igraph_vector_t neis; igraph_real_t *member_storage = 0, *new_member_storage, *c1; long int i, j, k, clique_count, old_clique_count; if (igraph_is_directed(graph)) { IGRAPH_WARNING("directionality of edges is ignored for directed graphs"); } no_of_nodes = igraph_vcount(graph); if (min_size < 0) { min_size = 0; } if (max_size > no_of_nodes || max_size <= 0) { max_size = no_of_nodes; } igraph_vector_ptr_clear(res); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_FINALLY(igraph_i_cliques_free_res, res); /* Will be resized later, if needed. */ member_storage = IGRAPH_CALLOC(1, igraph_real_t); if (member_storage == 0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, member_storage); /* Find all 1-cliques: every vertex will be a clique */ new_member_storage = IGRAPH_CALLOC(no_of_nodes, igraph_real_t); if (new_member_storage == 0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, new_member_storage); for (i = 0; i < no_of_nodes; i++) { new_member_storage[i] = i; } clique_count = no_of_nodes; old_clique_count = 0; /* Add size 1 cliques if requested */ if (min_size <= 1) { IGRAPH_CHECK(igraph_vector_ptr_resize(res, no_of_nodes)); igraph_vector_ptr_null(res); for (i = 0; i < no_of_nodes; i++) { igraph_vector_t *p = IGRAPH_CALLOC(1, igraph_vector_t); if (p == 0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, p); IGRAPH_CHECK(igraph_vector_init(p, 1)); VECTOR(*p)[0] = i; VECTOR(*res)[i] = p; IGRAPH_FINALLY_CLEAN(1); } } for (i = 2; i <= max_size && clique_count > 1; i++) { /* Here new_member_storage contains the cliques found in the previous iteration. Save this into member_storage, might be needed later */ c1 = member_storage; member_storage = new_member_storage; new_member_storage = c1; old_clique_count = clique_count; IGRAPH_ALLOW_INTERRUPTION(); /* Calculate the cliques */ IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_i_find_k_cliques(graph, i, member_storage, &new_member_storage, old_clique_count, &clique_count, &neis, independent_vertices)); IGRAPH_FINALLY(igraph_free, member_storage); IGRAPH_FINALLY(igraph_free, new_member_storage); /* Add the cliques just found to the result if requested */ if (i >= min_size && i <= max_size) { for (j = 0, k = 0; j < clique_count; j++, k += i) { igraph_vector_t *p = IGRAPH_CALLOC(1, igraph_vector_t); if (p == 0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, p); IGRAPH_CHECK(igraph_vector_init_copy(p, &new_member_storage[k], i)); IGRAPH_FINALLY(igraph_vector_destroy, p); IGRAPH_CHECK(igraph_vector_ptr_push_back(res, p)); IGRAPH_FINALLY_CLEAN(2); } } } /* i <= max_size && clique_count != 0 */ igraph_free(member_storage); igraph_free(new_member_storage); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(4); /* 3 here, +1 is igraph_i_cliques_free_res */ return 0; } /** * \function igraph_cliques * \brief Finds all or some cliques in a graph. * * * Cliques are fully connected subgraphs of a graph. * * * If you are only interested in the size of the largest clique in the graph, * use \ref igraph_clique_number() instead. * * The current implementation of this function * uses version 1.21 of the Cliquer library by Sampo Niskanen and * Patric R. J. Östergård, http://users.aalto.fi/~pat/cliquer.html * * \param graph The input graph. * \param res Pointer to a pointer vector, the result will be stored * here, i.e. \p res will contain pointers to \ref igraph_vector_t * objects which contain the indices of vertices involved in a clique. * The pointer vector will be resized if needed but note that the * objects in the pointer vector will not be freed. * \param min_size Integer giving the minimum size of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the cliques to be * returned. If negative or zero, no upper bound will be used. * \return Error code. * * \sa \ref igraph_largest_cliques() and \ref igraph_clique_number(). * * Time complexity: Exponential * * \example examples/simple/igraph_cliques.c */ int igraph_cliques(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size) { return igraph_i_cliquer_cliques(graph, res, min_size, max_size); } /** * \function igraph_clique_size_hist * \brief Counts cliques of each size in the graph. * * * Cliques are fully connected subgraphs of a graph. * * The current implementation of this function * uses version 1.21 of the Cliquer library by Sampo Niskanen and * Patric R. J. Östergård, http://users.aalto.fi/~pat/cliquer.html * * \param graph The input graph. * \param hist Pointer to an initialized vector. The result will be stored * here. The first element will store the number of size-1 cliques, the second * element the number of size-2 cliques, etc. For cliques smaller than \p min_size, * zero counts will be returned. * \param min_size Integer giving the minimum size of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the cliques to be * returned. If negative or zero, no upper bound will be used. * \return Error code. * * \sa \ref igraph_cliques() and \ref igraph_cliques_callback() * * Time complexity: Exponential * */ int igraph_clique_size_hist(const igraph_t *graph, igraph_vector_t *hist, igraph_integer_t min_size, igraph_integer_t max_size) { return igraph_i_cliquer_histogram(graph, hist, min_size, max_size); } /** * \function igraph_cliques_callback * \brief Calls a function for each clique in the graph. * * * Cliques are fully connected subgraphs of a graph. This function * enumerates all cliques within the given size range and calls * \p cliquehandler_fn for each of them. The cliques are passed to the * callback function as a pointer to an \ref igraph_vector_t. Destroying and * freeing this vector is left up to the user. Use \ref igraph_vector_destroy() * to destroy it first, then free it using \ref igraph_free(). * * The current implementation of this function * uses version 1.21 of the Cliquer library by Sampo Niskanen and * Patric R. J. Östergård, http://users.aalto.fi/~pat/cliquer.html * * \param graph The input graph. * \param min_size Integer giving the minimum size of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the cliques to be * returned. If negative or zero, no upper bound will be used. * \param cliquehandler_fn Callback function to be called for each clique. * See also \ref igraph_clique_handler_t. * \param arg Extra argument to supply to \p cliquehandler_fn. * \return Error code. * * \sa \ref igraph_cliques() * * Time complexity: Exponential * */ int igraph_cliques_callback(const igraph_t *graph, igraph_integer_t min_size, igraph_integer_t max_size, igraph_clique_handler_t *cliquehandler_fn, void *arg) { return igraph_i_cliquer_callback(graph, min_size, max_size, cliquehandler_fn, arg); } /** * \function igraph_weighted_cliques * \brief Finds all cliques in a given weight range in a vertex weighted graph. * * * Cliques are fully connected subgraphs of a graph. * The weight of a clique is the sum of the weights * of individual vertices within the clique. * * The current implementation of this function * uses version 1.21 of the Cliquer library by Sampo Niskanen and * Patric R. J. Östergård, http://users.aalto.fi/~pat/cliquer.html * * Only positive integer vertex weights are supported. * * \param graph The input graph. * \param vertex_weights A vector of vertex weights. The current implementation * will truncate all weights to their integer parts. You may pass \c NULL * here to make each vertex have a weight of 1. * \param res Pointer to a pointer vector, the result will be stored * here, i.e. \p res will contain pointers to \ref igraph_vector_t * objects which contain the indices of vertices involved in a clique. * The pointer vector will be resized if needed but note that the * objects in the pointer vector will not be freed. * \param min_weight Integer giving the minimum weight of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_weight Integer giving the maximum weight of the cliques to be * returned. If negative or zero, no upper bound will be used. * \param maximal If true, only maximal cliques will be returned * \return Error code. * * \sa \ref igraph_cliques(), \ref igraph_maximal_cliques() * * Time complexity: Exponential * */ int igraph_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res, igraph_real_t min_weight, igraph_real_t max_weight, igraph_bool_t maximal) { if (vertex_weights) { return igraph_i_weighted_cliques(graph, vertex_weights, res, min_weight, max_weight, maximal); } else if (maximal) { return igraph_maximal_cliques(graph, res, min_weight, max_weight); } else { return igraph_cliques(graph, res, min_weight, max_weight); } } /** * \function igraph_largest_weighted_cliques * \brief Finds the largest weight clique(s) in a graph. * * * Finds the clique(s) having the largest weight in the graph. * * The current implementation of this function * uses version 1.21 of the Cliquer library by Sampo Niskanen and * Patric R. J. Östergård, http://users.aalto.fi/~pat/cliquer.html * * Only positive integer vertex weights are supported. * * \param graph The input graph. * \param vertex_weights A vector of vertex weights. The current implementation * will truncate all weights to their integer parts. You may pass \c NULL * here to make each vertex have a weight of 1. * \param res Pointer to a pointer vector, the result will be stored * here, i.e. \p res will contain pointers to \ref igraph_vector_t * objects which contain the indices of vertices involved in a clique. * The pointer vector will be resized if needed but note that the * objects in the pointer vector will not be freed. * \return Error code. * * \sa \ref igraph_weighted_cliques(), \ref igraph_weighted_clique_number(), \ref igraph_largest_cliques() * * Time complexity: TODO */ int igraph_largest_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res) { if (vertex_weights) { return igraph_i_largest_weighted_cliques(graph, vertex_weights, res); } else { return igraph_largest_cliques(graph, res); } } /** * \function igraph_weighted_clique_number * \brief Finds the weight of the largest weight clique in the graph. * * The current implementation of this function * uses version 1.21 of the Cliquer library by Sampo Niskanen and * Patric R. J. Östergård, http://users.aalto.fi/~pat/cliquer.html * * Only positive integer vertex weights are supported. * * \param graph The input graph. * \param vertex_weights A vector of vertex weights. The current implementation * will truncate all weights to their integer parts. You may pass \c NULL * here to make each vertex have a weight of 1. * \param res The largest weight will be returned to the \c igraph_real_t * pointed to by this variable. * \return Error code. * * \sa \ref igraph_weighted_cliques(), \ref igraph_largest_weighted_cliques(), \ref igraph_clique_number() * * Time complexity: TODO * */ int igraph_weighted_clique_number(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_real_t *res) { if (vertex_weights) { return igraph_i_weighted_clique_number(graph, vertex_weights, res); } else { igraph_integer_t res_int; IGRAPH_CHECK(igraph_clique_number(graph, &res_int)); if (res) { *res = res_int; } return IGRAPH_SUCCESS; } } typedef int(*igraph_i_maximal_clique_func_t)(const igraph_vector_t*, void*, igraph_bool_t*); typedef struct { igraph_vector_ptr_t* result; igraph_integer_t min_size; igraph_integer_t max_size; } igraph_i_maximal_clique_data_t; static int igraph_i_maximal_or_largest_cliques_or_indsets( const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t *clique_number, igraph_bool_t keep_only_largest, igraph_bool_t complementer); /** * \function igraph_independent_vertex_sets * \brief Finds all independent vertex sets in a graph. * * * A vertex set is considered independent if there are no edges between * them. * * * If you are interested in the size of the largest independent vertex set, * use \ref igraph_independence_number() instead. * * * The current implementation was ported to igraph from the Very Nauty Graph * Library by Keith Briggs and uses the algorithm from the paper * S. Tsukiyama, M. Ide, H. Ariyoshi and I. Shirawaka. A new algorithm * for generating all the maximal independent sets. SIAM J Computing, * 6:505--517, 1977. * * \param graph The input graph. * \param res Pointer to a pointer vector, the result will be stored * here, i.e. \p res will contain pointers to \ref igraph_vector_t * objects which contain the indices of vertices involved in an independent * vertex set. The pointer vector will be resized if needed but note that the * objects in the pointer vector will not be freed. * \param min_size Integer giving the minimum size of the sets to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the sets to be * returned. If negative or zero, no upper bound will be used. * \return Error code. * * \sa \ref igraph_largest_independent_vertex_sets(), * \ref igraph_independence_number(). * * Time complexity: TODO * * \example examples/simple/igraph_independent_sets.c */ int igraph_independent_vertex_sets(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size) { return igraph_i_cliques(graph, res, min_size, max_size, 1); } /** * \function igraph_largest_independent_vertex_sets * \brief Finds the largest independent vertex set(s) in a graph. * * * An independent vertex set is largest if there is no other * independent vertex set with more vertices in the graph. * * * The current implementation was ported to igraph from the Very Nauty Graph * Library by Keith Briggs and uses the algorithm from the paper * S. Tsukiyama, M. Ide, H. Ariyoshi and I. Shirawaka. A new algorithm * for generating all the maximal independent sets. SIAM J Computing, * 6:505--517, 1977. * * \param graph The input graph. * \param res Pointer to a pointer vector, the result will be stored * here. It will be resized as needed. * \return Error code. * * \sa \ref igraph_independent_vertex_sets(), \ref * igraph_maximal_independent_vertex_sets(). * * Time complexity: TODO */ int igraph_largest_independent_vertex_sets(const igraph_t *graph, igraph_vector_ptr_t *res) { return igraph_i_maximal_or_largest_cliques_or_indsets(graph, res, 0, 1, 0); } typedef struct igraph_i_max_ind_vsets_data_t { igraph_integer_t matrix_size; igraph_adjlist_t adj_list; /* Adjacency list of the graph */ igraph_vector_t deg; /* Degrees of individual nodes */ igraph_set_t* buckets; /* Bucket array */ /* The IS value for each node. Still to be explained :) */ igraph_integer_t* IS; igraph_integer_t largest_set_size; /* Size of the largest set encountered */ igraph_bool_t keep_only_largest; /* True if we keep only the largest sets */ } igraph_i_max_ind_vsets_data_t; static int igraph_i_maximal_independent_vertex_sets_backtrack( const igraph_t *graph, igraph_vector_ptr_t *res, igraph_i_max_ind_vsets_data_t *clqdata, igraph_integer_t level) { long int v1, v2, v3, c, j, k; igraph_vector_int_t *neis1, *neis2; igraph_bool_t f; igraph_integer_t j1; long int it_state; IGRAPH_ALLOW_INTERRUPTION(); if (level >= clqdata->matrix_size - 1) { igraph_integer_t size = 0; if (res) { igraph_vector_t *vec; vec = IGRAPH_CALLOC(1, igraph_vector_t); if (vec == 0) { IGRAPH_ERROR("igraph_i_maximal_independent_vertex_sets failed", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(vec, 0); for (v1 = 0; v1 < clqdata->matrix_size; v1++) if (clqdata->IS[v1] == 0) { IGRAPH_CHECK(igraph_vector_push_back(vec, v1)); } size = (igraph_integer_t) igraph_vector_size(vec); if (!clqdata->keep_only_largest) { IGRAPH_CHECK(igraph_vector_ptr_push_back(res, vec)); } else { if (size > clqdata->largest_set_size) { /* We are keeping only the largest sets, and we've found one that's * larger than all previous sets, so we have to clear the list */ j = igraph_vector_ptr_size(res); for (v1 = 0; v1 < j; v1++) { igraph_vector_destroy(VECTOR(*res)[v1]); free(VECTOR(*res)[v1]); } igraph_vector_ptr_clear(res); IGRAPH_CHECK(igraph_vector_ptr_push_back(res, vec)); } else if (size == clqdata->largest_set_size) { IGRAPH_CHECK(igraph_vector_ptr_push_back(res, vec)); } else { igraph_vector_destroy(vec); free(vec); } } IGRAPH_FINALLY_CLEAN(1); } else { for (v1 = 0, size = 0; v1 < clqdata->matrix_size; v1++) if (clqdata->IS[v1] == 0) { size++; } } if (size > clqdata->largest_set_size) { clqdata->largest_set_size = size; } } else { v1 = level + 1; /* Count the number of vertices with an index less than v1 that have * an IS value of zero */ neis1 = igraph_adjlist_get(&clqdata->adj_list, v1); c = 0; j = 0; while (j < VECTOR(clqdata->deg)[v1] && (v2 = (long int) VECTOR(*neis1)[j]) <= level) { if (clqdata->IS[v2] == 0) { c++; } j++; } if (c == 0) { /* If there are no such nodes... */ j = 0; while (j < VECTOR(clqdata->deg)[v1] && (v2 = (long int) VECTOR(*neis1)[j]) <= level) { clqdata->IS[v2]++; j++; } IGRAPH_CHECK(igraph_i_maximal_independent_vertex_sets_backtrack(graph, res, clqdata, (igraph_integer_t) v1)); j = 0; while (j < VECTOR(clqdata->deg)[v1] && (v2 = (long int) VECTOR(*neis1)[j]) <= level) { clqdata->IS[v2]--; j++; } } else { /* If there are such nodes, store the count in the IS value of v1 */ clqdata->IS[v1] = (igraph_integer_t) c; IGRAPH_CHECK(igraph_i_maximal_independent_vertex_sets_backtrack(graph, res, clqdata, (igraph_integer_t) v1)); clqdata->IS[v1] = 0; f = 1; j = 0; while (j < VECTOR(clqdata->deg)[v1] && (v2 = (long int) VECTOR(*neis1)[j]) <= level) { if (clqdata->IS[v2] == 0) { IGRAPH_CHECK(igraph_set_add(&clqdata->buckets[v1], (igraph_integer_t) j)); neis2 = igraph_adjlist_get(&clqdata->adj_list, v2); k = 0; while (k < VECTOR(clqdata->deg)[v2] && (v3 = (long int) VECTOR(*neis2)[k]) <= level) { clqdata->IS[v3]--; if (clqdata->IS[v3] == 0) { f = 0; } k++; } } clqdata->IS[v2]++; j++; } if (f) { IGRAPH_CHECK(igraph_i_maximal_independent_vertex_sets_backtrack(graph, res, clqdata, (igraph_integer_t) v1)); } j = 0; while (j < VECTOR(clqdata->deg)[v1] && (v2 = (long int) VECTOR(*neis1)[j]) <= level) { clqdata->IS[v2]--; j++; } it_state = 0; while (igraph_set_iterate(&clqdata->buckets[v1], &it_state, &j1)) { j = (long)j1; v2 = (long int) VECTOR(*neis1)[j]; neis2 = igraph_adjlist_get(&clqdata->adj_list, v2); k = 0; while (k < VECTOR(clqdata->deg)[v2] && (v3 = (long int) VECTOR(*neis2)[k]) <= level) { clqdata->IS[v3]++; k++; } } igraph_set_clear(&clqdata->buckets[v1]); } } return 0; } static void igraph_i_free_set_array(igraph_set_t* array) { long int i = 0; while (igraph_set_inited(array + i)) { igraph_set_destroy(array + i); i++; } IGRAPH_FREE(array); } /** * \function igraph_maximal_independent_vertex_sets * \brief Finds all maximal independent vertex sets of a graph. * * * A maximal independent vertex set is an independent vertex set which * can't be extended any more by adding a new vertex to it. * * * The algorithm used here is based on the following paper: * S. Tsukiyama, M. Ide, H. Ariyoshi and I. Shirawaka. A new algorithm for * generating all the maximal independent sets. SIAM J Computing, * 6:505--517, 1977. * * * The implementation was originally written by Kevin O'Neill and modified * by K M Briggs in the Very Nauty Graph Library. I simply re-wrote it to * use igraph's data structures. * * * If you are interested in the size of the largest independent vertex set, * use \ref igraph_independence_number() instead. * * \param graph The input graph. * \param res Pointer to a pointer vector, the result will be stored * here, i.e. \p res will contain pointers to \ref igraph_vector_t * objects which contain the indices of vertices involved in an independent * vertex set. The pointer vector will be resized if needed but note that the * objects in the pointer vector will not be freed. * \return Error code. * * \sa \ref igraph_maximal_cliques(), \ref * igraph_independence_number() * * Time complexity: TODO. */ int igraph_maximal_independent_vertex_sets(const igraph_t *graph, igraph_vector_ptr_t *res) { igraph_i_max_ind_vsets_data_t clqdata; igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph), i; if (igraph_is_directed(graph)) { IGRAPH_WARNING("directionality of edges is ignored for directed graphs"); } clqdata.matrix_size = no_of_nodes; clqdata.keep_only_largest = 0; IGRAPH_CHECK(igraph_adjlist_init( graph, &clqdata.adj_list, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE )); IGRAPH_FINALLY(igraph_adjlist_destroy, &clqdata.adj_list); clqdata.IS = IGRAPH_CALLOC(no_of_nodes, igraph_integer_t); if (clqdata.IS == 0) { IGRAPH_ERROR("igraph_maximal_independent_vertex_sets failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, clqdata.IS); IGRAPH_VECTOR_INIT_FINALLY(&clqdata.deg, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { VECTOR(clqdata.deg)[i] = igraph_vector_int_size(igraph_adjlist_get(&clqdata.adj_list, i)); } clqdata.buckets = IGRAPH_CALLOC(no_of_nodes + 1, igraph_set_t); if (clqdata.buckets == 0) { IGRAPH_ERROR("igraph_maximal_independent_vertex_sets failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_i_free_set_array, clqdata.buckets); for (i = 0; i < no_of_nodes; i++) { IGRAPH_CHECK(igraph_set_init(&clqdata.buckets[i], 0)); } igraph_vector_ptr_clear(res); /* Do the show */ clqdata.largest_set_size = 0; IGRAPH_CHECK(igraph_i_maximal_independent_vertex_sets_backtrack(graph, res, &clqdata, 0)); /* Cleanup */ for (i = 0; i < no_of_nodes; i++) { igraph_set_destroy(&clqdata.buckets[i]); } igraph_adjlist_destroy(&clqdata.adj_list); igraph_vector_destroy(&clqdata.deg); igraph_free(clqdata.IS); igraph_free(clqdata.buckets); IGRAPH_FINALLY_CLEAN(4); return 0; } /** * \function igraph_independence_number * \brief Finds the independence number of the graph. * * * The independence number of a graph is the cardinality of the largest * independent vertex set. * * * The current implementation was ported to igraph from the Very Nauty Graph * Library by Keith Briggs and uses the algorithm from the paper * S. Tsukiyama, M. Ide, H. Ariyoshi and I. Shirawaka. A new algorithm * for generating all the maximal independent sets. SIAM J Computing, * 6:505--517, 1977. * * \param graph The input graph. * \param no The independence number will be returned to the \c * igraph_integer_t pointed by this variable. * \return Error code. * * \sa \ref igraph_independent_vertex_sets(). * * Time complexity: TODO. */ int igraph_independence_number(const igraph_t *graph, igraph_integer_t *no) { igraph_i_max_ind_vsets_data_t clqdata; igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph), i; if (igraph_is_directed(graph)) { IGRAPH_WARNING("directionality of edges is ignored for directed graphs"); } clqdata.matrix_size = no_of_nodes; clqdata.keep_only_largest = 0; IGRAPH_CHECK(igraph_adjlist_init( graph, &clqdata.adj_list, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE )); IGRAPH_FINALLY(igraph_adjlist_destroy, &clqdata.adj_list); clqdata.IS = IGRAPH_CALLOC(no_of_nodes, igraph_integer_t); if (clqdata.IS == 0) { IGRAPH_ERROR("igraph_independence_number failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, clqdata.IS); IGRAPH_VECTOR_INIT_FINALLY(&clqdata.deg, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { VECTOR(clqdata.deg)[i] = igraph_vector_int_size(igraph_adjlist_get(&clqdata.adj_list, i)); } clqdata.buckets = IGRAPH_CALLOC(no_of_nodes + 1, igraph_set_t); if (clqdata.buckets == 0) { IGRAPH_ERROR("igraph_independence_number failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_i_free_set_array, clqdata.buckets); for (i = 0; i < no_of_nodes; i++) { IGRAPH_CHECK(igraph_set_init(&clqdata.buckets[i], 0)); } /* Do the show */ clqdata.largest_set_size = 0; IGRAPH_CHECK(igraph_i_maximal_independent_vertex_sets_backtrack(graph, 0, &clqdata, 0)); *no = clqdata.largest_set_size; /* Cleanup */ for (i = 0; i < no_of_nodes; i++) { igraph_set_destroy(&clqdata.buckets[i]); } igraph_adjlist_destroy(&clqdata.adj_list); igraph_vector_destroy(&clqdata.deg); igraph_free(clqdata.IS); igraph_free(clqdata.buckets); IGRAPH_FINALLY_CLEAN(4); return 0; } /*************************************************************************/ /* MAXIMAL CLIQUES, LARGEST CLIQUES */ /*************************************************************************/ static igraph_bool_t igraph_i_maximal_cliques_store_max_size(igraph_vector_t* clique, void* data) { igraph_integer_t* result = (igraph_integer_t*)data; if (*result < igraph_vector_size(clique)) { *result = (igraph_integer_t) igraph_vector_size(clique); } igraph_vector_destroy(clique); igraph_Free(clique); return 1; } static igraph_bool_t igraph_i_largest_cliques_store(igraph_vector_t* clique, void* data) { igraph_vector_ptr_t* result = (igraph_vector_ptr_t*)data; long int i, n; /* Is the current clique at least as large as the others that we have found? */ if (!igraph_vector_ptr_empty(result)) { n = igraph_vector_size(clique); if (n < igraph_vector_size(VECTOR(*result)[0])) { igraph_vector_destroy(clique); igraph_Free(clique); return 1; } if (n > igraph_vector_size(VECTOR(*result)[0])) { for (i = 0; i < igraph_vector_ptr_size(result); i++) { igraph_vector_destroy(VECTOR(*result)[i]); } igraph_vector_ptr_free_all(result); igraph_vector_ptr_resize(result, 0); } } IGRAPH_CHECK(igraph_vector_ptr_push_back(result, clique)); return 1; } /** * \function igraph_largest_cliques * \brief Finds the largest clique(s) in a graph. * * * A clique is largest (quite intuitively) if there is no other clique * in the graph which contains more vertices. * * * Note that this is not necessarily the same as a maximal clique, * i.e. the largest cliques are always maximal but a maximal clique is * not always largest. * * The current implementation of this function searches * for maximal cliques using \ref igraph_maximal_cliques_callback() and drops * those that are not the largest. * * The implementation of this function changed between * igraph 0.5 and 0.6, so the order of the cliques and the order of * vertices within the cliques will almost surely be different between * these two versions. * * \param graph The input graph. * \param res Pointer to an initialized pointer vector, the result * will be stored here. It will be resized as needed. Note that * vertices of a clique may be returned in arbitrary order. * \return Error code. * * \sa \ref igraph_cliques(), \ref igraph_maximal_cliques() * * Time complexity: O(3^(|V|/3)) worst case. */ int igraph_largest_cliques(const igraph_t *graph, igraph_vector_ptr_t *res) { igraph_vector_ptr_clear(res); IGRAPH_FINALLY(igraph_i_cliques_free_res, res); IGRAPH_CHECK(igraph_maximal_cliques_callback(graph, &igraph_i_largest_cliques_store, (void*)res, 0, 0)); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /** * \function igraph_clique_number * \brief Finds the clique number of the graph. * * * The clique number of a graph is the size of the largest clique. * * The current implementation of this function searches * for maximal cliques using \ref igraph_maximal_cliques_callback() and keeps * track of the size of the largest clique that was found. * * \param graph The input graph. * \param no The clique number will be returned to the \c igraph_integer_t * pointed by this variable. * \return Error code. * * \sa \ref igraph_cliques(), \ref igraph_largest_cliques(). * * Time complexity: O(3^(|V|/3)) worst case. */ int igraph_clique_number(const igraph_t *graph, igraph_integer_t *no) { *no = 0; return igraph_maximal_cliques_callback(graph, &igraph_i_maximal_cliques_store_max_size, (void*)no, 0, 0); } static int igraph_i_maximal_or_largest_cliques_or_indsets(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t *clique_number, igraph_bool_t keep_only_largest, igraph_bool_t complementer) { igraph_i_max_ind_vsets_data_t clqdata; igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph), i; if (igraph_is_directed(graph)) { IGRAPH_WARNING("directionality of edges is ignored for directed graphs"); } clqdata.matrix_size = no_of_nodes; clqdata.keep_only_largest = keep_only_largest; if (complementer) { IGRAPH_CHECK(igraph_adjlist_init_complementer(graph, &clqdata.adj_list, IGRAPH_ALL, 0)); } else { IGRAPH_CHECK(igraph_adjlist_init( graph, &clqdata.adj_list, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE )); } IGRAPH_FINALLY(igraph_adjlist_destroy, &clqdata.adj_list); clqdata.IS = IGRAPH_CALLOC(no_of_nodes, igraph_integer_t); if (clqdata.IS == 0) { IGRAPH_ERROR("igraph_i_maximal_or_largest_cliques_or_indsets failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, clqdata.IS); IGRAPH_VECTOR_INIT_FINALLY(&clqdata.deg, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { VECTOR(clqdata.deg)[i] = igraph_vector_int_size(igraph_adjlist_get(&clqdata.adj_list, i)); } clqdata.buckets = IGRAPH_CALLOC(no_of_nodes + 1, igraph_set_t); if (clqdata.buckets == 0) { IGRAPH_ERROR("igraph_maximal_or_largest_cliques_or_indsets failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_i_free_set_array, clqdata.buckets); for (i = 0; i < no_of_nodes; i++) { IGRAPH_CHECK(igraph_set_init(&clqdata.buckets[i], 0)); } if (res) { igraph_vector_ptr_clear(res); } /* Do the show */ clqdata.largest_set_size = 0; IGRAPH_CHECK(igraph_i_maximal_independent_vertex_sets_backtrack(graph, res, &clqdata, 0)); /* Cleanup */ for (i = 0; i < no_of_nodes; i++) { igraph_set_destroy(&clqdata.buckets[i]); } igraph_adjlist_destroy(&clqdata.adj_list); igraph_vector_destroy(&clqdata.deg); igraph_free(clqdata.IS); igraph_free(clqdata.buckets); IGRAPH_FINALLY_CLEAN(4); if (clique_number) { *clique_number = clqdata.largest_set_size; } return 0; } leidenbase/src/core/cliques/cliquer_wrapper.c0000644000176200001440000002546614447675374021143 0ustar liggesusers #include "igraph_error.h" #include "igraph_memory.h" #include "igraph_constants.h" #include "core/interruption.h" #include "cliques/cliquer_internal.h" #include "cliques/cliquer/cliquer.h" #include "config.h" /* Call this to allow for interruption in Cliquer callback functions */ #define CLIQUER_ALLOW_INTERRUPTION() \ { \ if (igraph_i_interruption_handler) \ if (igraph_allow_interruption(NULL) != IGRAPH_SUCCESS) { \ cliquer_interrupted = 1; \ return FALSE; \ } \ } /* Interruptable Cliquer functions must be wrapped in CLIQUER_INTERRUPTABLE when called */ #define CLIQUER_INTERRUPTABLE(x) \ { \ cliquer_interrupted = 0; \ x; \ if (cliquer_interrupted) return IGRAPH_INTERRUPTED; \ } /* Nonzero value signals interuption from Cliquer callback function */ static IGRAPH_THREAD_LOCAL int cliquer_interrupted; /* For use with IGRAPH_FINALLY */ static void free_clique_list(igraph_vector_ptr_t *vp) { igraph_integer_t i, len; len = igraph_vector_ptr_size(vp); for (i = 0; i < len; ++i) { igraph_vector_destroy((igraph_vector_t *) VECTOR(*vp)[i]); } igraph_vector_ptr_free_all(vp); } /* We shall use this option struct for all calls to Cliquer */ static IGRAPH_THREAD_LOCAL clique_options igraph_cliquer_opt = { reorder_by_default, NULL, NULL, NULL, NULL, NULL, NULL, 0 }; /* Convert an igraph graph to a Cliquer graph */ static void igraph_to_cliquer(const igraph_t *ig, graph_t **cg) { igraph_integer_t vcount, ecount; int i; if (igraph_is_directed(ig)) { IGRAPH_WARNING("Edge directions are ignored for clique calculations"); } vcount = igraph_vcount(ig); ecount = igraph_ecount(ig); *cg = graph_new(vcount); for (i = 0; i < ecount; ++i) { long s, t; s = IGRAPH_FROM(ig, i); t = IGRAPH_TO(ig, i); if (s != t) { GRAPH_ADD_EDGE(*cg, s, t); } } } /* Copy weights to a Cliquer graph */ static int set_weights(const igraph_vector_t *vertex_weights, graph_t *g) { int i; IGRAPH_ASSERT(vertex_weights != NULL); if (igraph_vector_size(vertex_weights) != g->n) { IGRAPH_ERROR("Invalid vertex weight vector length", IGRAPH_EINVAL); } for (i = 0; i < g->n; ++i) { g->weights[i] = VECTOR(*vertex_weights)[i]; if (g->weights[i] != VECTOR(*vertex_weights)[i]) { IGRAPH_WARNING("Only integer vertex weights are supported; weights will be truncated to their integer parts"); } if (g->weights[i] <= 0) { IGRAPH_ERROR("Vertex weights must be positive", IGRAPH_EINVAL); } } return IGRAPH_SUCCESS; } /* Find all cliques. */ static boolean collect_cliques_callback(set_t s, graph_t *g, clique_options *opt) { igraph_vector_ptr_t *list; igraph_vector_t *clique; int i, j; IGRAPH_UNUSED(g); CLIQUER_ALLOW_INTERRUPTION(); list = (igraph_vector_ptr_t *) opt->user_data; clique = (igraph_vector_t *) malloc(sizeof(igraph_vector_t)); igraph_vector_init(clique, set_size(s)); i = -1; j = 0; while ((i = set_return_next(s, i)) >= 0) { VECTOR(*clique)[j++] = i; } igraph_vector_ptr_push_back(list, clique); return TRUE; } int igraph_i_cliquer_cliques(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size) { graph_t *g; igraph_integer_t vcount = igraph_vcount(graph); if (vcount == 0) { igraph_vector_ptr_clear(res); return IGRAPH_SUCCESS; } if (min_size <= 0) { min_size = 1; } if (max_size <= 0) { max_size = 0; } if (max_size > 0 && max_size < min_size) { IGRAPH_ERROR("max_size must not be smaller than min_size", IGRAPH_EINVAL); } igraph_to_cliquer(graph, &g); IGRAPH_FINALLY(graph_free, g); igraph_vector_ptr_clear(res); igraph_cliquer_opt.user_data = res; igraph_cliquer_opt.user_function = &collect_cliques_callback; IGRAPH_FINALLY(free_clique_list, res); CLIQUER_INTERRUPTABLE(clique_unweighted_find_all(g, min_size, max_size, /* maximal= */ FALSE, &igraph_cliquer_opt)); IGRAPH_FINALLY_CLEAN(1); graph_free(g); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Count cliques of each size. */ static boolean count_cliques_callback(set_t s, graph_t *g, clique_options *opt) { igraph_vector_t *hist; IGRAPH_UNUSED(g); CLIQUER_ALLOW_INTERRUPTION(); hist = (igraph_vector_t *) opt->user_data; VECTOR(*hist)[set_size(s) - 1] += 1; return TRUE; } int igraph_i_cliquer_histogram(const igraph_t *graph, igraph_vector_t *hist, igraph_integer_t min_size, igraph_integer_t max_size) { graph_t *g; int i; igraph_integer_t vcount = igraph_vcount(graph); if (vcount == 0) { igraph_vector_clear(hist); return IGRAPH_SUCCESS; } if (min_size <= 0) { min_size = 1; } if (max_size <= 0) { max_size = vcount; /* also used for initial hist vector size, do not set to zero */ } if (max_size < min_size) { IGRAPH_ERRORF("Maximum clique size (%" IGRAPH_PRId ") must not be " "smaller than minimum clique size (%" IGRAPH_PRId ").", IGRAPH_EINVAL, max_size, min_size); } igraph_to_cliquer(graph, &g); IGRAPH_FINALLY(graph_free, g); igraph_vector_resize(hist, max_size); igraph_vector_null(hist); igraph_cliquer_opt.user_data = hist; igraph_cliquer_opt.user_function = &count_cliques_callback; CLIQUER_INTERRUPTABLE(clique_unweighted_find_all(g, min_size, max_size, /* maximal= */ FALSE, &igraph_cliquer_opt)); for (i = max_size; i > 0; --i) if (VECTOR(*hist)[i - 1] > 0) { break; } igraph_vector_resize(hist, i); igraph_vector_resize_min(hist); graph_free(g); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Call function for each clique. */ struct callback_data { igraph_clique_handler_t *handler; void *arg; }; static boolean callback_callback(set_t s, graph_t *g, clique_options *opt) { igraph_vector_t *clique; struct callback_data *cd; int i, j; IGRAPH_UNUSED(g); CLIQUER_ALLOW_INTERRUPTION(); cd = (struct callback_data *) opt->user_data; clique = (igraph_vector_t *) malloc(sizeof(igraph_vector_t)); igraph_vector_init(clique, set_size(s)); i = -1; j = 0; while ((i = set_return_next(s, i)) >= 0) { VECTOR(*clique)[j++] = i; } return (*(cd->handler))(clique, cd->arg); } int igraph_i_cliquer_callback(const igraph_t *graph, igraph_integer_t min_size, igraph_integer_t max_size, igraph_clique_handler_t *cliquehandler_fn, void *arg) { graph_t *g; struct callback_data cd; igraph_integer_t vcount = igraph_vcount(graph); if (vcount == 0) { return IGRAPH_SUCCESS; } if (min_size <= 0) { min_size = 1; } if (max_size <= 0) { max_size = 0; } if (max_size > 0 && max_size < min_size) { IGRAPH_ERROR("max_size must not be smaller than min_size", IGRAPH_EINVAL); } igraph_to_cliquer(graph, &g); IGRAPH_FINALLY(graph_free, g); cd.handler = cliquehandler_fn; cd.arg = arg; igraph_cliquer_opt.user_data = &cd; igraph_cliquer_opt.user_function = &callback_callback; CLIQUER_INTERRUPTABLE(clique_unweighted_find_all(g, min_size, max_size, /* maximal= */ FALSE, &igraph_cliquer_opt)); graph_free(g); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Find weighted cliques in given weight range. */ int igraph_i_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res, igraph_real_t min_weight, igraph_real_t max_weight, igraph_bool_t maximal) { graph_t *g; igraph_integer_t vcount = igraph_vcount(graph); if (vcount == 0) { igraph_vector_ptr_clear(res); return IGRAPH_SUCCESS; } if (min_weight != (int) min_weight) { IGRAPH_WARNING("Only integer vertex weights are supported; the minimum weight will be truncated to its integer part"); min_weight = (int) min_weight; } if (max_weight != (int) max_weight) { IGRAPH_WARNING("Only integer vertex weights are supported; the maximum weight will be truncated to its integer part"); max_weight = (int) max_weight; } if (min_weight <= 0) { min_weight = 1; } if (max_weight <= 0) { max_weight = 0; } if (max_weight > 0 && max_weight < min_weight) { IGRAPH_ERROR("max_weight must not be smaller than min_weight", IGRAPH_EINVAL); } igraph_to_cliquer(graph, &g); IGRAPH_FINALLY(graph_free, g); IGRAPH_CHECK(set_weights(vertex_weights, g)); igraph_vector_ptr_clear(res); igraph_cliquer_opt.user_data = res; igraph_cliquer_opt.user_function = &collect_cliques_callback; IGRAPH_FINALLY(free_clique_list, res); CLIQUER_INTERRUPTABLE(clique_find_all(g, min_weight, max_weight, maximal, &igraph_cliquer_opt)); IGRAPH_FINALLY_CLEAN(1); graph_free(g); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Find largest weighted cliques. */ int igraph_i_largest_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res) { graph_t *g; igraph_integer_t vcount = igraph_vcount(graph); if (vcount == 0) { igraph_vector_ptr_clear(res); return IGRAPH_SUCCESS; } igraph_to_cliquer(graph, &g); IGRAPH_FINALLY(graph_free, g); IGRAPH_CHECK(set_weights(vertex_weights, g)); igraph_vector_ptr_clear(res); igraph_cliquer_opt.user_data = res; igraph_cliquer_opt.user_function = &collect_cliques_callback; IGRAPH_FINALLY(free_clique_list, res); CLIQUER_INTERRUPTABLE(clique_find_all(g, 0, 0, FALSE, &igraph_cliquer_opt)); IGRAPH_FINALLY_CLEAN(1); graph_free(g); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* Find weight of largest weight clique. */ int igraph_i_weighted_clique_number(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_real_t *res) { graph_t *g; igraph_integer_t vcount = igraph_vcount(graph); if (vcount == 0) { *res = 0; return IGRAPH_SUCCESS; } igraph_to_cliquer(graph, &g); IGRAPH_FINALLY(graph_free, g); IGRAPH_CHECK(set_weights(vertex_weights, g)); igraph_cliquer_opt.user_function = NULL; /* we are not using a callback function, thus this is not interruptable */ *res = clique_max_weight(g, &igraph_cliquer_opt); graph_free(g); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/cliques/maximal_cliques_template.h0000644000176200001440000003425714447675374023012 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef IGRAPH_MC_ORIG #define RESTYPE igraph_vector_ptr_t *res #define RESNAME res #define SUFFIX #define RECORD do { \ igraph_vector_t *cl=IGRAPH_CALLOC(1, igraph_vector_t); \ int j; \ if (!cl) { \ IGRAPH_ERROR("Cannot list maximal cliques", IGRAPH_ENOMEM); \ } \ IGRAPH_CHECK(igraph_vector_ptr_push_back(res, cl)); \ IGRAPH_CHECK(igraph_vector_init(cl, clsize)); \ for (j=0; j hsize) { \ long hcapacity = igraph_vector_capacity(hist); \ long j; \ int err; \ if (hcapacity < clsize && clsize < 2*hcapacity) \ err = igraph_vector_reserve(hist, 2*hcapacity); \ err = igraph_vector_resize(hist, clsize); \ if (err != IGRAPH_SUCCESS) \ IGRAPH_ERROR("Cannot count maximal cliques", IGRAPH_ENOMEM); \ for (j=hsize; j < clsize; j++) \ VECTOR(*hist)[j] = 0; \ } \ VECTOR(*hist)[clsize-1] += 1; \ } while (0) #define FINALLY \ igraph_vector_clear(hist); \ igraph_vector_reserve(hist, 50); /* initially reserve space for 50 elements */ #define CLEANUP #define FOR_LOOP_OVER_VERTICES for (i=0; i PE && XS > XE) { /* Found a maximum clique, report it */ int clsize = igraph_vector_int_size(R); if (min_size <= clsize && (clsize <= max_size || max_size <= 0)) { RECORD; } } else if (PS <= PE) { /* Select a pivot element */ int pivot, mynextv; IGRAPH_CHECK(igraph_i_maximal_cliques_select_pivot( PX, PS, PE, XS, XE, pos, adjlist, &pivot, nextv, oldPS, oldXE )); while ((mynextv = igraph_vector_int_pop_back(nextv)) != -1) { int newPS, newXE; /* Going down, prepare */ IGRAPH_CHECK(igraph_i_maximal_cliques_down( PX, PS, PE, XS, XE, pos, adjlist, mynextv, R, &newPS, &newXE )); /* Recursive call */ err = FUNCTION(igraph_i_maximal_cliques_bk, SUFFIX)( PX, newPS, PE, XS, newXE, PS, XE, R, pos, adjlist, RESNAME, nextv, H, min_size, max_size); if (err == IGRAPH_STOP) { return err; } else { IGRAPH_CHECK(err); } /* Putting v from P to X */ if (igraph_vector_int_tail(nextv) != -1) { IGRAPH_CHECK(igraph_i_maximal_cliques_PX( PX, PS, &PE, &XS, XE, pos, adjlist, mynextv, H )); } } } /* Putting back vertices from X to P, see notes in H */ IGRAPH_CHECK(igraph_i_maximal_cliques_up(PX, PS, PE, XS, XE, pos, adjlist, R, H)); return 0; } int FUNCTION(igraph_maximal_cliques, SUFFIX)( const igraph_t *graph, RESTYPE, igraph_integer_t min_size, igraph_integer_t max_size) { /* Implementation details. TODO */ igraph_vector_int_t PX, R, H, pos, nextv; igraph_vector_t coreness, order; igraph_vector_int_t rank; /* TODO: this is not needed */ int i, ii, nn, no_of_nodes = igraph_vcount(graph); igraph_adjlist_t adjlist, fulladjlist; igraph_real_t pgreset = round(no_of_nodes / 100.0), pg = pgreset, pgc = 0; int err; IGRAPH_UNUSED(nn); if (igraph_is_directed(graph)) { IGRAPH_WARNING("Edge directions are ignored for maximal clique " "calculation"); } IGRAPH_VECTOR_INIT_FINALLY(&order, no_of_nodes); IGRAPH_VECTOR_INT_INIT_FINALLY(&rank, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&coreness, no_of_nodes); IGRAPH_CHECK(igraph_coreness(graph, &coreness, /*mode=*/ IGRAPH_ALL)); IGRAPH_CHECK(igraph_vector_qsort_ind(&coreness, &order, /*descending=*/ 0)); for (ii = 0; ii < no_of_nodes; ii++) { int v = VECTOR(order)[ii]; VECTOR(rank)[v] = ii; } igraph_vector_destroy(&coreness); IGRAPH_FINALLY_CLEAN(1); igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); igraph_adjlist_init(graph, &fulladjlist, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE); IGRAPH_FINALLY(igraph_adjlist_destroy, &fulladjlist); IGRAPH_VECTOR_INT_INIT_FINALLY(&PX, 20); IGRAPH_VECTOR_INT_INIT_FINALLY(&R, 20); IGRAPH_VECTOR_INT_INIT_FINALLY(&H, 100); IGRAPH_VECTOR_INT_INIT_FINALLY(&pos, no_of_nodes); IGRAPH_VECTOR_INT_INIT_FINALLY(&nextv, 100); FINALLY; FOR_LOOP_OVER_VERTICES { int v; int vrank; igraph_vector_int_t *vneis; int vdeg; int Pptr, Xptr, PS, PE, XS, XE; int j; FOR_LOOP_OVER_VERTICES_PREPARE; v = VECTOR(order)[i]; vrank = VECTOR(rank)[v]; vneis = igraph_adjlist_get(&fulladjlist, v); vdeg = igraph_vector_int_size(vneis); Pptr = 0; Xptr = vdeg - 1; PS = 0; XE = vdeg - 1; pg--; if (pg <= 0) { IGRAPH_PROGRESS("Maximal cliques: ", pgc++, NULL); pg = pgreset; } IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_vector_int_resize(&PX, vdeg)); IGRAPH_CHECK(igraph_vector_int_resize(&R, 1)); IGRAPH_CHECK(igraph_vector_int_resize(&H, 1)); igraph_vector_int_null(&pos); /* TODO: makes it quadratic? */ IGRAPH_CHECK(igraph_vector_int_resize(&nextv, 1)); VECTOR(H)[0] = -1; /* marks the end of the recursion */ VECTOR(nextv)[0] = -1; /* ================================================================*/ /* P <- G(v[i]) intersect { v[i+1], ..., v[n-1] } X <- G(v[i]) intersect { v[0], ..., v[i-1] } */ VECTOR(R)[0] = v; for (j = 0; j < vdeg; j++) { int vx = VECTOR(*vneis)[j]; if (VECTOR(rank)[vx] > vrank) { VECTOR(PX)[Pptr] = vx; VECTOR(pos)[vx] = Pptr + 1; Pptr++; } else if (VECTOR(rank)[vx] < vrank) { VECTOR(PX)[Xptr] = vx; VECTOR(pos)[vx] = Xptr + 1; Xptr--; } } PE = Pptr - 1; XS = Xptr + 1; /* end of P, start of X in PX */ /* Create an adjacency list that is specific to the v vertex. It only contains 'v' and its neighbors. Moreover, we only deal with the vertices in P and X (and R). */ IGRAPH_CHECK(igraph_vector_int_update( igraph_adjlist_get(&adjlist, v), igraph_adjlist_get(&fulladjlist, v) )); for (j = 0; j <= vdeg - 1; j++) { int vv = VECTOR(PX)[j]; igraph_vector_int_t *fadj = igraph_adjlist_get(&fulladjlist, vv); igraph_vector_int_t *radj = igraph_adjlist_get(&adjlist, vv); int k, fn = igraph_vector_int_size(fadj); igraph_vector_int_clear(radj); for (k = 0; k < fn; k++) { int nei = VECTOR(*fadj)[k]; int neipos = VECTOR(pos)[nei] - 1; if (neipos >= PS && neipos <= XE) { IGRAPH_CHECK(igraph_vector_int_push_back(radj, nei)); } } } /* Reorder the adjacency lists, according to P and X. */ IGRAPH_CHECK(igraph_i_maximal_cliques_reorder_adjlists( &PX, PS, PE, XS, XE, &pos, &adjlist )); err = FUNCTION(igraph_i_maximal_cliques_bk, SUFFIX)( &PX, PS, PE, XS, XE, PS, XE, &R, &pos, &adjlist, RESNAME, &nextv, &H, min_size, max_size); if (err == IGRAPH_STOP) { break; } else { IGRAPH_CHECK(err); } } IGRAPH_PROGRESS("Maximal cliques: ", 100.0, NULL); CLEANUP; igraph_vector_int_destroy(&nextv); igraph_vector_int_destroy(&pos); igraph_vector_int_destroy(&H); igraph_vector_int_destroy(&R); igraph_vector_int_destroy(&PX); igraph_adjlist_destroy(&fulladjlist); igraph_adjlist_destroy(&adjlist); igraph_vector_int_destroy(&rank); igraph_vector_destroy(&order); IGRAPH_FINALLY_CLEAN(9); return IGRAPH_SUCCESS; } #undef RESTYPE #undef RESNAME #undef SUFFIX #undef RECORD #undef FINALLY #undef CLEANUP #undef FOR_LOOP_OVER_VERTICES #undef FOR_LOOP_OVER_VERTICES_PREPARE leidenbase/src/core/cliques/glet.c0000644000176200001440000007527614447675374016676 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_graphlets.h" #include "igraph_conversion.h" #include "igraph_constructors.h" #include "igraph_cliques.h" #include "igraph_memory.h" #include "igraph_operators.h" #include "igraph_qsort.h" #include "igraph_structural.h" /** * \section graphlets_intro Introduction * * * Graphlet decomposition models a weighted undirected graph * via the union of potentially overlapping dense social groups. * This is done by a two-step algorithm. In the first step, a candidate * set of groups (a candidate basis) is created by finding cliques * in the thresholded input graph. In the second step, * the graph is projected onto the candidate basis, resulting in a * weight coefficient for each clique in the candidate basis. * * * * For more information on graphlet decomposition, see * Hossein Azari Soufiani and Edoardo M Airoldi: "Graphlet decomposition of a weighted network", * https://arxiv.org/abs/1203.2821 and http://proceedings.mlr.press/v22/azari12/azari12.pdf * * * * igraph contains three functions for performing the graphlet * decomponsition of a graph. The first is \ref igraph_graphlets(), which * performs both steps of the method and returns a list of subgraphs * with their corresponding weights. The other two functions * correspond to the first and second steps of the algorithm, and they are * useful if the user wishes to perform them individually: * \ref igraph_graphlets_candidate_basis() and * \ref igraph_graphlets_project(). * * * * * Note: The term "graphlet" is used for several unrelated concepts * in the literature. If you are looking to count induced subgraphs, see * \ref igraph_motifs_randesu() and \ref igraph_subisomorphic_lad(). * * */ typedef struct { igraph_vector_int_t *resultids; igraph_t *result; igraph_vector_t *resultweights; int nc; } igraph_i_subclique_next_free_t; static void igraph_i_subclique_next_free(void *ptr) { igraph_i_subclique_next_free_t *data = ptr; int i; if (data->resultids) { for (i = 0; i < data->nc; i++) { igraph_vector_int_destroy(&data->resultids[i]); } IGRAPH_FREE(data->resultids); } if (data->result) { for (i = 0; i < data->nc; i++) { igraph_destroy(&data->result[i]); } IGRAPH_FREE(data->result); } if (data->resultweights) { for (i = 0; i < data->nc; i++) { igraph_vector_destroy(&data->resultweights[i]); } IGRAPH_FREE(data->resultweights); } } /** * \function igraph_i_subclique_next * Calculate subcliques of the cliques found at the previous level * * \param graph Input graph. * \param weight Edge weights. * \param ids The ids of the vertices in the input graph. * \param cliques A list of vectors, vertex ids for cliques. * \param result The result is stored here, a list of graphs is stored * here. * \param resultids The ids of the vertices in the result graphs is * stored here. * \param clique_thr The thresholds for the cliques are stored here, * if not a null pointer. * \param next_thr The next thresholds for the cliques are stored * here, if not a null pointer. * */ static int igraph_i_subclique_next(const igraph_t *graph, const igraph_vector_t *weights, const igraph_vector_int_t *ids, const igraph_vector_ptr_t *cliques, igraph_t **result, igraph_vector_t **resultweights, igraph_vector_int_t **resultids, igraph_vector_t *clique_thr, igraph_vector_t *next_thr) { /* The input is a set of cliques, that were found at a previous level. For each clique, we calculate the next threshold, drop the isolate vertices, and create a new graph from them. */ igraph_vector_int_t mark, map; igraph_vector_int_t edges; igraph_vector_t neis, newedges; igraph_integer_t c, nc = igraph_vector_ptr_size(cliques); igraph_integer_t no_of_nodes = igraph_vcount(graph); igraph_integer_t no_of_edges = igraph_ecount(graph); igraph_i_subclique_next_free_t freedata = { 0, 0, 0, nc }; if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Invalid length of weight vector", IGRAPH_EINVAL); } if (igraph_vector_int_size(ids) != no_of_nodes) { IGRAPH_ERROR("Invalid length of ID vector", IGRAPH_EINVAL); } IGRAPH_FINALLY(igraph_i_subclique_next_free, &freedata); *resultids = IGRAPH_CALLOC(nc, igraph_vector_int_t); if (!*resultids) { IGRAPH_ERROR("Cannot calculate next cliques", IGRAPH_ENOMEM); } freedata.resultids = *resultids; *resultweights = IGRAPH_CALLOC(nc, igraph_vector_t); if (!*resultweights) { IGRAPH_ERROR("Cannot calculate next cliques", IGRAPH_ENOMEM); } freedata.resultweights = *resultweights; *result = IGRAPH_CALLOC(nc, igraph_t); if (!*result) { IGRAPH_ERROR("Cannot calculate next cliques", IGRAPH_ENOMEM); } freedata.result = *result; igraph_vector_init(&newedges, 100); IGRAPH_FINALLY(igraph_vector_destroy, &newedges); igraph_vector_int_init(&mark, no_of_nodes); IGRAPH_FINALLY(igraph_vector_int_destroy, &mark); igraph_vector_int_init(&map, no_of_nodes); IGRAPH_FINALLY(igraph_vector_int_destroy, &map); igraph_vector_int_init(&edges, 100); IGRAPH_FINALLY(igraph_vector_int_destroy, &edges); igraph_vector_init(&neis, 10); IGRAPH_FINALLY(igraph_vector_destroy, &neis); if (clique_thr) { igraph_vector_resize(clique_thr, nc); } if (next_thr) { igraph_vector_resize(next_thr, nc); } /* Iterate over all cliques. We will create graphs for all subgraphs defined by the cliques. */ for (c = 0; c < nc; c++) { igraph_vector_t *clique = VECTOR(*cliques)[c]; igraph_real_t minweight = IGRAPH_INFINITY, nextweight = IGRAPH_INFINITY; igraph_integer_t e, v, clsize = igraph_vector_size(clique); igraph_integer_t noe, nov = 0; igraph_vector_int_t *newids = (*resultids) + c; igraph_vector_t *neww = (*resultweights) + c; igraph_t *newgraph = (*result) + c; igraph_vector_int_clear(&edges); igraph_vector_clear(&newedges); /* --------------------------------------------------- */ /* Iterate over the vertices of a clique and find the edges within the clique, put them in a list. At the same time, search for the minimum edge weight within the clique and the next edge weight if any. */ for (v = 0; v < clsize; v++) { igraph_integer_t i, neilen, node = VECTOR(*clique)[v]; igraph_incident(graph, &neis, node, IGRAPH_ALL); neilen = igraph_vector_size(&neis); VECTOR(mark)[node] = c + 1; for (i = 0; i < neilen; i++) { igraph_integer_t edge = VECTOR(neis)[i]; igraph_integer_t nei = IGRAPH_OTHER(graph, edge, node); if (VECTOR(mark)[nei] == c + 1) { igraph_real_t w = VECTOR(*weights)[edge]; igraph_vector_int_push_back(&edges, edge); if (w < minweight) { nextweight = minweight; minweight = w; } else if (w > minweight && w < nextweight) { nextweight = w; } } } } /* v < clsize */ /* --------------------------------------------------- */ /* OK, we have stored the edges and found the weight of the clique and the next weight to consider */ if (clique_thr) { VECTOR(*clique_thr)[c] = minweight; } if (next_thr) { VECTOR(*next_thr )[c] = nextweight; } /* --------------------------------------------------- */ /* Now we create the subgraph from the edges above the next threshold, and their incident vertices. */ igraph_vector_int_init(newids, 0); igraph_vector_init(neww, 0); /* We use mark[] to denote the vertices already mapped to the new graph. If this is -(c+1), then the vertex was mapped, otherwise it was not. The mapping itself is in map[]. */ noe = igraph_vector_int_size(&edges); for (e = 0; e < noe; e++) { igraph_integer_t edge = VECTOR(edges)[e]; igraph_integer_t from, to; igraph_real_t w = VECTOR(*weights)[edge]; igraph_edge(graph, edge, &from, &to); if (w >= nextweight) { if (VECTOR(mark)[from] == c + 1) { VECTOR(map)[from] = nov++; VECTOR(mark)[from] = -(c + 1); igraph_vector_int_push_back(newids, VECTOR(*ids)[from]); } if (VECTOR(mark)[to] == c + 1) { VECTOR(map)[to] = nov++; VECTOR(mark)[to] = -(c + 1); igraph_vector_int_push_back(newids, VECTOR(*ids)[to]); } igraph_vector_push_back(neww, w); igraph_vector_push_back(&newedges, VECTOR(map)[from]); igraph_vector_push_back(&newedges, VECTOR(map)[to]); } } igraph_create(newgraph, &newedges, nov, IGRAPH_UNDIRECTED); /* --------------------------------------------------- */ } /* c < nc */ igraph_vector_destroy(&neis); igraph_vector_int_destroy(&edges); igraph_vector_int_destroy(&mark); igraph_vector_int_destroy(&map); igraph_vector_destroy(&newedges); IGRAPH_FINALLY_CLEAN(6); /* + freedata */ return 0; } static void igraph_i_graphlets_destroy_vectorlist(igraph_vector_ptr_t *vl) { int i, n = igraph_vector_ptr_size(vl); for (i = 0; i < n; i++) { igraph_vector_t *v = (igraph_vector_t*) VECTOR(*vl)[i]; if (v) { igraph_vector_destroy(v); } } igraph_vector_ptr_destroy(vl); } static int igraph_i_graphlets(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_ptr_t *cliques, igraph_vector_t *thresholds, const igraph_vector_int_t *ids, igraph_real_t startthr) { /* This version is different from the main function, and is appropriate to use in recursive calls, because it _adds_ the results to 'cliques' and 'thresholds' and uses the supplied 'startthr' */ igraph_vector_ptr_t mycliques; int no_of_edges = igraph_ecount(graph); igraph_vector_t subv; igraph_t subg; int i, nographs, nocliques; igraph_t *newgraphs = 0; igraph_vector_t *newweights = 0; igraph_vector_int_t *newids = 0; igraph_vector_t clique_thr, next_thr; igraph_i_subclique_next_free_t freedata = { 0, 0, 0, 0 }; IGRAPH_CHECK(igraph_vector_ptr_init(&mycliques, 0)); IGRAPH_FINALLY(igraph_i_graphlets_destroy_vectorlist, &mycliques); IGRAPH_VECTOR_INIT_FINALLY(&subv, 0); /* We start by finding cliques at the lowest threshold */ for (i = 0; i < no_of_edges; i++) { if (VECTOR(*weights)[i] >= startthr) { IGRAPH_CHECK(igraph_vector_push_back(&subv, i)); } } igraph_subgraph_edges(graph, &subg, igraph_ess_vector(&subv), /*delete_vertices=*/ 0); IGRAPH_FINALLY(igraph_destroy, &subg); igraph_maximal_cliques(&subg, &mycliques, /*min_size=*/ 0, /*max_size=*/ 0); igraph_destroy(&subg); IGRAPH_FINALLY_CLEAN(1); nocliques = igraph_vector_ptr_size(&mycliques); igraph_vector_destroy(&subv); IGRAPH_FINALLY_CLEAN(1); /* Get the next cliques and thresholds */ IGRAPH_VECTOR_INIT_FINALLY(&next_thr, 0); IGRAPH_VECTOR_INIT_FINALLY(&clique_thr, 0); igraph_i_subclique_next(graph, weights, ids, &mycliques, &newgraphs, &newweights, &newids, &clique_thr, &next_thr); freedata.result = newgraphs; freedata.resultids = newids; freedata.resultweights = newweights; freedata.nc = nocliques; IGRAPH_FINALLY(igraph_i_subclique_next_free, &freedata); /* Store cliques at the current level */ igraph_vector_append(thresholds, &clique_thr); for (i = 0; i < nocliques; i++) { igraph_vector_t *cl = (igraph_vector_t*) VECTOR(mycliques)[i]; int j, n = igraph_vector_size(cl); for (j = 0; j < n; j++) { int node = VECTOR(*cl)[j]; VECTOR(*cl)[j] = VECTOR(*ids)[node]; } igraph_vector_sort(cl); } igraph_vector_ptr_append(cliques, &mycliques); /* Recursive calls for cliques found */ nographs = igraph_vector_ptr_size(&mycliques); for (i = 0; i < nographs; i++) { igraph_t *g = newgraphs + i; if (igraph_vcount(g) > 1) { igraph_vector_t *w_sub = newweights + i; igraph_vector_int_t *ids_sub = newids + i; igraph_i_graphlets(g, w_sub, cliques, thresholds, ids_sub, VECTOR(next_thr)[i]); } } igraph_vector_destroy(&clique_thr); igraph_vector_destroy(&next_thr); igraph_i_subclique_next_free(&freedata); igraph_vector_ptr_destroy(&mycliques); /* contents was copied over */ IGRAPH_FINALLY_CLEAN(4); return 0; } typedef struct { const igraph_vector_ptr_t *cliques; const igraph_vector_t *thresholds; } igraph_i_graphlets_filter_t; static int igraph_i_graphlets_filter_cmp(void *data, const void *a, const void *b) { igraph_i_graphlets_filter_t *ddata = (igraph_i_graphlets_filter_t *) data; int *aa = (int*) a; int *bb = (int*) b; igraph_real_t t_a = VECTOR(*ddata->thresholds)[*aa]; igraph_real_t t_b = VECTOR(*ddata->thresholds)[*bb]; igraph_vector_t *v_a, *v_b; int s_a, s_b; if (t_a < t_b) { return -1; } else if (t_a > t_b) { return 1; } v_a = (igraph_vector_t*) VECTOR(*ddata->cliques)[*aa]; v_b = (igraph_vector_t*) VECTOR(*ddata->cliques)[*bb]; s_a = igraph_vector_size(v_a); s_b = igraph_vector_size(v_b); if (s_a < s_b) { return -1; } else if (s_a > s_b) { return 1; } else { return 0; } } static int igraph_i_graphlets_filter(igraph_vector_ptr_t *cliques, igraph_vector_t *thresholds) { /* Filter out non-maximal cliques. Every non-maximal clique is part of a maximal clique, at the same threshold. First we order the cliques, according to their threshold, and then according to their size. So when we look for a candidate superset, we only need to check the cliques next in the list, until their threshold is different. */ int i, iptr, nocliques = igraph_vector_ptr_size(cliques); igraph_vector_int_t order; igraph_i_graphlets_filter_t sortdata = { cliques, thresholds }; igraph_vector_int_init(&order, nocliques); IGRAPH_FINALLY(igraph_vector_int_destroy, &order); for (i = 0; i < nocliques; i++) { VECTOR(order)[i] = i; } igraph_qsort_r(VECTOR(order), nocliques, sizeof(int), &sortdata, igraph_i_graphlets_filter_cmp); for (i = 0; i < nocliques - 1; i++) { int ri = VECTOR(order)[i]; igraph_vector_t *needle = VECTOR(*cliques)[ri]; igraph_real_t thr_i = VECTOR(*thresholds)[ri]; int n_i = igraph_vector_size(needle); int j = i + 1; for (j = i + 1; j < nocliques; j++) { int rj = VECTOR(order)[j]; igraph_real_t thr_j = VECTOR(*thresholds)[rj]; igraph_vector_t *hay; int n_j, pi = 0, pj = 0; /* Done, not found */ if (thr_j != thr_i) { break; } /* Check size of hay */ hay = VECTOR(*cliques)[rj]; n_j = igraph_vector_size(hay); if (n_i > n_j) { continue; } /* Check if hay is a superset */ while (pi < n_i && pj < n_j && n_i - pi <= n_j - pj) { int ei = VECTOR(*needle)[pi]; int ej = VECTOR(*hay)[pj]; if (ei < ej) { break; } else if (ei > ej) { pj++; } else { pi++; pj++; } } if (pi == n_i) { /* Found, delete immediately */ igraph_vector_destroy(needle); igraph_free(needle); VECTOR(*cliques)[ri] = 0; break; } } } /* Remove null pointers from the list of cliques */ for (i = 0, iptr = 0; i < nocliques; i++) { igraph_vector_t *v = VECTOR(*cliques)[i]; if (v) { VECTOR(*cliques)[iptr] = v; VECTOR(*thresholds)[iptr] = VECTOR(*thresholds)[i]; iptr++; } } igraph_vector_ptr_resize(cliques, iptr); igraph_vector_resize(thresholds, iptr); igraph_vector_int_destroy(&order); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_graphlets_candidate_basis * Calculate a candidate graphlets basis * * \param graph The input graph, it must be a simple graph, edge directions are * ignored. * \param weights Weights of the edges, a vector. * \param cliques An initialized vector of pointers. * The graphlet basis is stored here. Each element of the pointer * vector will be a vector of vertex ids. Each elements must be * destroyed using \ref igraph_vector_destroy() and \ref igraph_free(). * \param thresholds An initialized vector, the (highest possible) * weight thresholds for finding the basis subgraphs are stored * here. * \return Error code. * * See also: \ref igraph_graphlets() and \ref igraph_graphlets_project(). */ int igraph_graphlets_candidate_basis(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_ptr_t *cliques, igraph_vector_t *thresholds) { int no_of_nodes = igraph_vcount(graph); int no_of_edges = igraph_ecount(graph); igraph_real_t minthr; igraph_vector_int_t ids; igraph_bool_t simple; int i; /* Some checks */ if (weights == NULL) { IGRAPH_ERROR("Graphlet functions require weighted graphs", IGRAPH_EINVAL); } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_is_simple(graph, &simple)); if (!simple) { IGRAPH_ERROR("Graphlets work on simple graphs only", IGRAPH_EINVAL); } minthr = igraph_vector_min(weights); igraph_vector_ptr_clear(cliques); igraph_vector_clear(thresholds); igraph_vector_int_init(&ids, no_of_nodes); IGRAPH_FINALLY(igraph_vector_int_destroy, &ids); for (i = 0; i < no_of_nodes; i++) { VECTOR(ids)[i] = i; } igraph_i_graphlets(graph, weights, cliques, thresholds, &ids, minthr); igraph_vector_int_destroy(&ids); IGRAPH_FINALLY_CLEAN(1); igraph_i_graphlets_filter(cliques, thresholds); return 0; } /* TODO: not made static because it is used by the R interface */ int igraph_i_graphlets_project(const igraph_t *graph, const igraph_vector_t *weights, const igraph_vector_ptr_t *cliques, igraph_vector_t *Mu, igraph_bool_t startMu, int niter, int vid1) { int no_of_nodes = igraph_vcount(graph); int no_of_edges = igraph_ecount(graph); int no_cliques = igraph_vector_ptr_size(cliques); igraph_vector_int_t vcl, vclidx, ecl, eclidx, cel, celidx; igraph_vector_t edgelist, newweights, normfact; int i, total_vertices, e, ptr, total_edges; igraph_bool_t simple; /* Check arguments */ if (weights == NULL) { IGRAPH_ERROR("Graphlet functions require weighted graphs", IGRAPH_EINVAL); } if (no_of_edges != igraph_vector_size(weights)) { IGRAPH_ERROR("Invalid weight vector size", IGRAPH_EINVAL); } if (startMu && igraph_vector_size(Mu) != no_cliques) { IGRAPH_ERROR("Invalid start coefficient vector size", IGRAPH_EINVAL); } if (niter < 0) { IGRAPH_ERROR("Number of iterations must be non-negative", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_is_simple(graph, &simple)); if (!simple) { IGRAPH_ERROR("Graphlets work on simple graphs only", IGRAPH_EINVAL); } if (!startMu) { igraph_vector_resize(Mu, no_cliques); igraph_vector_fill(Mu, 1); } /* Count # cliques per vertex. Also, create an index for the edges per clique. */ IGRAPH_CHECK(igraph_vector_int_init(&vclidx, no_of_nodes + 2)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vclidx); IGRAPH_CHECK(igraph_vector_int_init(&celidx, no_cliques + 3)); IGRAPH_FINALLY(igraph_vector_int_destroy, &celidx); for (i = 0, total_vertices = 0, total_edges = 0; i < no_cliques; i++) { igraph_vector_t *v = VECTOR(*cliques)[i]; int j, n = igraph_vector_size(v); total_vertices += n; total_edges += n * (n - 1) / 2; VECTOR(celidx)[i + 2] = total_edges; for (j = 0; j < n; j++) { int vv = VECTOR(*v)[j] - vid1; VECTOR(vclidx)[vv + 2] += 1; } } VECTOR(celidx)[i + 2] = total_edges; /* Finalize index vector */ for (i = 0; i < no_of_nodes; i++) { VECTOR(vclidx)[i + 2] += VECTOR(vclidx)[i + 1]; } /* Create vertex-clique list, the cliques for each vertex. */ IGRAPH_CHECK(igraph_vector_int_init(&vcl, total_vertices)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vcl); for (i = 0; i < no_cliques; i++) { igraph_vector_t *v = VECTOR(*cliques)[i]; int j, n = igraph_vector_size(v); for (j = 0; j < n; j++) { int vv = VECTOR(*v)[j] - vid1; int p = VECTOR(vclidx)[vv + 1]; VECTOR(vcl)[p] = i; VECTOR(vclidx)[vv + 1] += 1; } } /* Create an edge-clique list, the cliques of each edge */ IGRAPH_CHECK(igraph_vector_int_init(&ecl, total_edges)); IGRAPH_FINALLY(igraph_vector_int_destroy, &ecl); IGRAPH_CHECK(igraph_vector_int_init(&eclidx, no_of_edges + 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &eclidx); IGRAPH_CHECK(igraph_vector_init(&edgelist, no_of_edges * 2)); IGRAPH_FINALLY(igraph_vector_destroy, &edgelist); IGRAPH_CHECK(igraph_get_edgelist(graph, &edgelist, /*by_col=*/ 0)); for (i = 0, e = 0, ptr = 0; e < no_of_edges; e++) { int from = VECTOR(edgelist)[i++]; int to = VECTOR(edgelist)[i++]; int from_s = VECTOR(vclidx)[from]; int from_e = VECTOR(vclidx)[from + 1]; int to_s = VECTOR(vclidx)[to]; int to_e = VECTOR(vclidx)[to + 1]; VECTOR(eclidx)[e] = ptr; while (from_s < from_e && to_s < to_e) { int from_v = VECTOR(vcl)[from_s]; int to_v = VECTOR(vcl)[to_s]; if (from_v == to_v) { VECTOR(ecl)[ptr++] = from_v; from_s++; to_s++; } else if (from_v < to_v) { from_s++; } else { to_s++; } } } VECTOR(eclidx)[e] = ptr; igraph_vector_destroy(&edgelist); IGRAPH_FINALLY_CLEAN(1); /* Convert the edge-clique list to a clique-edge list */ IGRAPH_CHECK(igraph_vector_int_init(&cel, total_edges)); IGRAPH_FINALLY(igraph_vector_int_destroy, &cel); for (i = 0; i < no_of_edges; i++) { int ecl_s = VECTOR(eclidx)[i], ecl_e = VECTOR(eclidx)[i + 1], j; for (j = ecl_s; j < ecl_e; j++) { int cl = VECTOR(ecl)[j]; int epos = VECTOR(celidx)[cl + 1]; VECTOR(cel)[epos] = i; VECTOR(celidx)[cl + 1] += 1; } } /* Normalizing factors for the iteration */ IGRAPH_CHECK(igraph_vector_init(&normfact, no_cliques)); IGRAPH_FINALLY(igraph_vector_destroy, &normfact); for (i = 0; i < no_cliques; i++) { igraph_vector_t *v = VECTOR(*cliques)[i]; int n = igraph_vector_size(v); VECTOR(normfact)[i] = n * (n + 1) / 2; } /* We have the clique-edge list, so do the projection now */ IGRAPH_CHECK(igraph_vector_init(&newweights, no_of_edges)); IGRAPH_FINALLY(igraph_vector_destroy, &newweights); for (i = 0; i < niter; i++) { for (e = 0; e < no_of_edges; e++) { int start = VECTOR(eclidx)[e]; int end = VECTOR(eclidx)[e + 1]; VECTOR(newweights)[e] = 0.0001; while (start < end) { int clique = VECTOR(ecl)[start++]; VECTOR(newweights)[e] += VECTOR(*Mu)[clique]; } } for (e = 0; e < no_cliques; e++) { igraph_real_t sumratio = 0; int start = VECTOR(celidx)[e]; int end = VECTOR(celidx)[e + 1]; while (start < end) { int edge = VECTOR(cel)[start++]; sumratio += VECTOR(*weights)[edge] / VECTOR(newweights)[edge]; } VECTOR(*Mu)[e] *= sumratio / VECTOR(normfact)[e]; } } igraph_vector_destroy(&newweights); igraph_vector_destroy(&normfact); igraph_vector_int_destroy(&cel); igraph_vector_int_destroy(&eclidx); igraph_vector_int_destroy(&ecl); igraph_vector_int_destroy(&vcl); igraph_vector_int_destroy(&celidx); igraph_vector_int_destroy(&vclidx); IGRAPH_FINALLY_CLEAN(8); return 0; } /** * \function igraph_graphlets_project * Project a graph on a graphlets basis * * Note that the graph projected does not have to be the same that * was used to calculate the graphlet basis, but it is assumed that * it has the same number of vertices, and the vertex ids of the two * graphs match. * \param graph The input graph, it must be a simple graph, edge directions are * ignored. * \param weights Weights of the edges in the input graph, a vector. * \param cliques The graphlet basis, a pointer vector, in which each * element is a vector of vertex ids. * \param Mu An initialized vector, the weights of the graphlets will * be stored here. This vector is also used to initialize the * the weight vector for the iterative algorithm, if the * \c startMu argument is true (non-zero). * \param startMu If true (non-zero), then the supplied Mu vector is * used as the starting point of the iteration. Otherwise a * constant 1 vector is used. * \param niter Integer scalar, the number of iterations to perform. * \return Error code. * * See also: \ref igraph_graphlets() and * \ref igraph_graphlets_candidate_basis(). */ int igraph_graphlets_project(const igraph_t *graph, const igraph_vector_t *weights, const igraph_vector_ptr_t *cliques, igraph_vector_t *Mu, igraph_bool_t startMu, int niter) { return igraph_i_graphlets_project(graph, weights, cliques, Mu, startMu, niter, /*vid1=*/ 0); } typedef struct igraph_i_graphlets_order_t { const igraph_vector_ptr_t *cliques; const igraph_vector_t *Mu; } igraph_i_graphlets_order_t; static int igraph_i_graphlets_order_cmp(void *data, const void *a, const void *b) { igraph_i_graphlets_order_t *ddata = (igraph_i_graphlets_order_t*) data; int *aa = (int*) a; int *bb = (int*) b; igraph_real_t Mu_a = VECTOR(*ddata->Mu)[*aa]; igraph_real_t Mu_b = VECTOR(*ddata->Mu)[*bb]; if (Mu_a < Mu_b) { return 1; } else if (Mu_a > Mu_b) { return -1; } else { return 0; } } /** * \function igraph_graphlets * Calculate graphlets basis and project the graph on it * * This function simply calls \ref igraph_graphlets_candidate_basis() * and \ref igraph_graphlets_project(), and then orders the graphlets * according to decreasing weights. * \param graph The input graph, it must be a simple graph, edge directions are * ignored. * \param weights Weights of the edges, a vector. * \param cliques An initialized vector of pointers. * The graphlet basis is stored here. Each element of the pointer * vector will be a vector of vertex ids. * \param Mu An initialized vector, the weights of the graphlets will * be stored here. * \param niter Integer scalar, the number of iterations to perform * for the projection step. * \return Error code. * * See also: \ref igraph_graphlets_candidate_basis() and * \ref igraph_graphlets_project(). */ int igraph_graphlets(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_ptr_t *cliques, igraph_vector_t *Mu, int niter) { int i, nocliques; igraph_vector_t thresholds; igraph_vector_int_t order; igraph_i_graphlets_order_t sortdata = { cliques, Mu }; igraph_vector_init(&thresholds, 0); IGRAPH_FINALLY(igraph_vector_destroy, &thresholds); igraph_graphlets_candidate_basis(graph, weights, cliques, &thresholds); igraph_vector_destroy(&thresholds); IGRAPH_FINALLY_CLEAN(1); igraph_graphlets_project(graph, weights, cliques, Mu, /*startMu=*/ 0, niter); nocliques = igraph_vector_ptr_size(cliques); igraph_vector_int_init(&order, nocliques); IGRAPH_FINALLY(igraph_vector_int_destroy, &order); for (i = 0; i < nocliques; i++) { VECTOR(order)[i] = i; } igraph_qsort_r(VECTOR(order), nocliques, sizeof(int), &sortdata, igraph_i_graphlets_order_cmp); igraph_vector_ptr_index_int(cliques, &order); igraph_vector_index_int(Mu, &order); igraph_vector_int_destroy(&order); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/cliques/cliquer_internal.h0000644000176200001440000000236014447675374021270 0ustar liggesusers#ifndef IGRAPH_CLIQUER_H #define IGRAPH_CLIQUER_H #include "igraph_interface.h" #include "igraph_cliques.h" int igraph_i_cliquer_cliques(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size); int igraph_i_cliquer_histogram(const igraph_t *graph, igraph_vector_t *hist, igraph_integer_t min_size, igraph_integer_t max_size); int igraph_i_cliquer_callback(const igraph_t *graph, igraph_integer_t min_size, igraph_integer_t max_size, igraph_clique_handler_t *cliquehandler_fn, void *arg); int igraph_i_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res, igraph_real_t min_weight, igraph_real_t max_weight, igraph_bool_t maximal); int igraph_i_largest_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res); int igraph_i_weighted_clique_number(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_real_t *res); #endif // IGRAPH_CLIQUER_H leidenbase/src/core/cliques/maximal_cliques.c0000644000176200001440000004741514447675374021112 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2013 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_cliques.h" #include "igraph_adjlist.h" #include "igraph_constants.h" #include "igraph_community.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_progress.h" #include "core/interruption.h" #define CONCAT2x(a,b) a ## b #define CONCAT2(a,b) CONCAT2x(a,b) #define FUNCTION(name,sfx) CONCAT2(name,sfx) static int igraph_i_maximal_cliques_reorder_adjlists( const igraph_vector_int_t *PX, int PS, int PE, int XS, int XE, const igraph_vector_int_t *pos, igraph_adjlist_t *adjlist); static int igraph_i_maximal_cliques_select_pivot( const igraph_vector_int_t *PX, int PS, int PE, int XS, int XE, const igraph_vector_int_t *pos, const igraph_adjlist_t *adjlist, int *pivot, igraph_vector_int_t *nextv, int oldPS, int oldXE); static int igraph_i_maximal_cliques_down( igraph_vector_int_t *PX, int PS, int PE, int XS, int XE, igraph_vector_int_t *pos, igraph_adjlist_t *adjlist, int mynextv, igraph_vector_int_t *R, int *newPS, int *newXE); static int igraph_i_maximal_cliques_PX( igraph_vector_int_t *PX, int PS, int *PE, int *XS, int XE, igraph_vector_int_t *pos, igraph_adjlist_t *adjlist, int v, igraph_vector_int_t *H); static int igraph_i_maximal_cliques_up( igraph_vector_int_t *PX, int PS, int PE, int XS, int XE, igraph_vector_int_t *pos, igraph_adjlist_t *adjlist, igraph_vector_int_t *R, igraph_vector_int_t *H); #define PRINT_PX do { \ int j; \ printf("PX="); \ for (j=0; j= sPS && avneipos <= sPE) { if (pp != avnei) { int tmp = *avnei; *avnei = *pp; *pp = tmp; } pp++; } } } return IGRAPH_SUCCESS; } static int igraph_i_maximal_cliques_select_pivot( const igraph_vector_int_t *PX, int PS, int PE, int XS, int XE, const igraph_vector_int_t *pos, const igraph_adjlist_t *adjlist, int *pivot, igraph_vector_int_t *nextv, int oldPS, int oldXE) { igraph_vector_int_t *pivotvectneis; int i, pivotvectlen, j, usize = -1; int soldPS = oldPS + 1, soldXE = oldXE + 1, sPS = PS + 1, sPE = PE + 1; IGRAPH_UNUSED(XS); /* Choose a pivotvect, and bring up P vertices at the same time */ for (i = PS; i <= XE; i++) { int av = VECTOR(*PX)[i]; igraph_vector_int_t *avneis = igraph_adjlist_get(adjlist, av); int *avp = VECTOR(*avneis); int avlen = igraph_vector_int_size(avneis); int *ave = avp + avlen; int *avnei = avp, *pp = avp; for (; avnei < ave; avnei++) { int avneipos = VECTOR(*pos)[(int)(*avnei)]; if (avneipos < soldPS || avneipos > soldXE) { break; } if (avneipos >= sPS && avneipos <= sPE) { if (pp != avnei) { int tmp = *avnei; *avnei = *pp; *pp = tmp; } pp++; } } if ((j = pp - avp) > usize) { *pivot = av; usize = j; } } IGRAPH_CHECK(igraph_vector_int_push_back(nextv, -1)); pivotvectneis = igraph_adjlist_get(adjlist, *pivot); pivotvectlen = igraph_vector_int_size(pivotvectneis); for (j = PS; j <= PE; j++) { int vcand = VECTOR(*PX)[j]; igraph_bool_t nei = 0; int k = 0; for (k = 0; k < pivotvectlen; k++) { int unv = VECTOR(*pivotvectneis)[k]; int unvpos = VECTOR(*pos)[unv]; if (unvpos < sPS || unvpos > sPE) { break; } if (unv == vcand) { nei = 1; break; } } if (!nei) { IGRAPH_CHECK(igraph_vector_int_push_back(nextv, vcand)); } } return IGRAPH_SUCCESS; } #define SWAP(p1,p2) do { \ int v1=VECTOR(*PX)[p1]; \ int v2=VECTOR(*PX)[p2]; \ VECTOR(*PX)[p1] = v2; \ VECTOR(*PX)[p2] = v1; \ VECTOR(*pos)[v1] = (p2)+1; \ VECTOR(*pos)[v2] = (p1)+1; \ } while (0) static int igraph_i_maximal_cliques_down(igraph_vector_int_t *PX, int PS, int PE, int XS, int XE, igraph_vector_int_t *pos, igraph_adjlist_t *adjlist, int mynextv, igraph_vector_int_t *R, int *newPS, int *newXE) { igraph_vector_int_t *vneis = igraph_adjlist_get(adjlist, mynextv); int j, vneislen = igraph_vector_int_size(vneis); int sPS = PS + 1, sPE = PE + 1, sXS = XS + 1, sXE = XE + 1; *newPS = PE + 1; *newXE = XS - 1; for (j = 0; j < vneislen; j++) { int vnei = VECTOR(*vneis)[j]; int vneipos = VECTOR(*pos)[vnei]; if (vneipos >= sPS && vneipos <= sPE) { (*newPS)--; SWAP(vneipos - 1, *newPS); } else if (vneipos >= sXS && vneipos <= sXE) { (*newXE)++; SWAP(vneipos - 1, *newXE); } } IGRAPH_CHECK(igraph_vector_int_push_back(R, mynextv)); return IGRAPH_SUCCESS; } #undef SWAP static int igraph_i_maximal_cliques_PX(igraph_vector_int_t *PX, int PS, int *PE, int *XS, int XE, igraph_vector_int_t *pos, igraph_adjlist_t *adjlist, int v, igraph_vector_int_t *H) { int vpos = VECTOR(*pos)[v] - 1; int tmp = VECTOR(*PX)[*PE]; IGRAPH_UNUSED(PS); IGRAPH_UNUSED(XE); IGRAPH_UNUSED(adjlist); VECTOR(*PX)[vpos] = tmp; VECTOR(*PX)[*PE] = v; VECTOR(*pos)[v] = (*PE) + 1; VECTOR(*pos)[tmp] = vpos + 1; (*PE)--; (*XS)--; IGRAPH_CHECK(igraph_vector_int_push_back(H, v)); return IGRAPH_SUCCESS; } static int igraph_i_maximal_cliques_up(igraph_vector_int_t *PX, int PS, int PE, int XS, int XE, igraph_vector_int_t *pos, igraph_adjlist_t *adjlist, igraph_vector_int_t *R, igraph_vector_int_t *H) { int vv; IGRAPH_UNUSED(PS); IGRAPH_UNUSED(XE); IGRAPH_UNUSED(adjlist); igraph_vector_int_pop_back(R); while ((vv = igraph_vector_int_pop_back(H)) != -1) { int vvpos = VECTOR(*pos)[vv]; int tmp = VECTOR(*PX)[XS]; VECTOR(*PX)[XS] = vv; VECTOR(*PX)[vvpos - 1] = tmp; VECTOR(*pos)[vv] = XS + 1; VECTOR(*pos)[tmp] = vvpos; PE++; XS++; } return 0; } /** * \function igraph_maximal_cliques * \brief Finds all maximal cliques in a graph. * * * A maximal clique is a clique which can't be extended any more by * adding a new vertex to it. * * * If you are only interested in the size of the largest clique in the * graph, use \ref igraph_clique_number() instead. * * * The current implementation uses a modified Bron-Kerbosch * algorithm to find the maximal cliques, see: David Eppstein, * Maarten Löffler, Darren Strash: Listing All Maximal Cliques in * Sparse Graphs in Near-Optimal Time. Algorithms and Computation, * Lecture Notes in Computer Science Volume 6506, 2010, pp 403-414. * * The implementation of this function changed between * igraph 0.5 and 0.6 and also between 0.6 and 0.7, so the order of * the cliques and the order of vertices within the cliques will * almost surely be different between these three versions. * * \param graph The input graph. * \param res Pointer to a pointer vector, the result will be stored * here, i.e. \p res will contain pointers to \ref igraph_vector_t * objects which contain the indices of vertices involved in a clique. * The pointer vector will be resized if needed but note that the * objects in the pointer vector will not be freed. Note that vertices * of a clique may be returned in arbitrary order. * \param min_size Integer giving the minimum size of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the cliques to be * returned. If negative or zero, no upper bound will be used. * \return Error code. * * \sa \ref igraph_maximal_independent_vertex_sets(), \ref * igraph_clique_number() * * Time complexity: O(d(n-d)3^(d/3)) worst case, d is the degeneracy * of the graph, this is typically small for sparse graphs. * * \example examples/simple/igraph_maximal_cliques.c */ int igraph_maximal_cliques(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size); #define IGRAPH_MC_ORIG #include "maximal_cliques_template.h" #undef IGRAPH_MC_ORIG /** * \function igraph_maximal_cliques_count * Count the number of maximal cliques in a graph * * * The current implementation uses a modified Bron-Kerbosch * algorithm to find the maximal cliques, see: David Eppstein, * Maarten Löffler, Darren Strash: Listing All Maximal Cliques in * Sparse Graphs in Near-Optimal Time. Algorithms and Computation, * Lecture Notes in Computer Science Volume 6506, 2010, pp 403-414. * * \param graph The input graph. * \param res Pointer to an \c igraph_integer_t; the number of maximal * cliques will be stored here. * \param min_size Integer giving the minimum size of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the cliques to be * returned. If negative or zero, no upper bound will be used. * \return Error code. * * \sa \ref igraph_maximal_cliques(). * * Time complexity: O(d(n-d)3^(d/3)) worst case, d is the degeneracy * of the graph, this is typically small for sparse graphs. * * \example examples/simple/igraph_maximal_cliques.c */ int igraph_maximal_cliques_count(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t min_size, igraph_integer_t max_size); #define IGRAPH_MC_COUNT #include "maximal_cliques_template.h" #undef IGRAPH_MC_COUNT /** * \function igraph_maximal_cliques_file * \brief Find maximal cliques and write them to a file. * * This function enumerates all maximal cliques and writes them to file. * * * * Edge directions are ignored. * * * * \param graph The input graph. * \param outfile Pointer to the output file, it should be writable. * \param min_size Integer giving the minimum size of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the cliques to be * returned. If negative or zero, no upper bound will be used. * \return Error code. * * \sa \ref igraph_maximal_cliques(). * * Time complexity: O(d(n-d)3^(d/3)) worst case, d is the degeneracy * of the graph, this is typically small for sparse graphs.* * */ int igraph_maximal_cliques_file(const igraph_t *graph, FILE *outfile, igraph_integer_t min_size, igraph_integer_t max_size); #define IGRAPH_MC_FILE #include "maximal_cliques_template.h" #undef IGRAPH_MC_FILE /** * \function igraph_maximal_cliques_subset * Maximal cliques for a subset of initial vertices * * This function enumerates all maximal cliques for a subset of initial * vertices and writes them to file. * * * * Edge directions are ignored. * * * * \param graph The input graph. * \param subset Pointer to an \c igraph_vector_int_t containing the * subset of initial vertices * \param res Pointer to an \c igraph_ptr_t; the cliques will be * stored here * \param no Pointer to an \c igraph_integer_t; the number of maximal * cliques will be stored here. * \param outfile Pointer to an output file or \c NULL. * When not \c NULL, the file should be writable. * \param min_size Integer giving the minimum size of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the cliques to be * returned. If negative or zero, no upper bound will be used. * \return Error code. * * \sa \ref igraph_maximal_cliques(). * * Time complexity: O(d(n-d)3^(d/3)) worst case, d is the degeneracy * of the graph, this is typically small for sparse graphs. * */ int igraph_maximal_cliques_subset(const igraph_t *graph, igraph_vector_int_t *subset, igraph_vector_ptr_t *res, igraph_integer_t *no, FILE *outfile, igraph_integer_t min_size, igraph_integer_t max_size); #define IGRAPH_MC_FULL #include "maximal_cliques_template.h" #undef IGRAPH_MC_FULL /** * \function igraph_maximal_cliques_callback * \brief Finds maximal cliques in a graph and calls a function for each one. * * This function enumerates all maximal cliques within the given size range * and calls \p cliquehandler_fn for each of them. The cliques are passed to the * callback function as a pointer to an \ref igraph_vector_t. Destroying and * freeing this vector is left up to the user. Use \ref igraph_vector_destroy() * to destroy it first, then free it using \ref igraph_free(). * * * * Edge directions are ignored. * * * * \param graph The input graph. * \param cliquehandler_fn Callback function to be called for each clique. * See also \ref igraph_clique_handler_t. * \param arg Extra argument to supply to \p cliquehandler_fn. * \param min_size Integer giving the minimum size of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the cliques to be * returned. If negative or zero, no upper bound will be used. * \return Error code. * * \sa \ref igraph_maximal_cliques(). * * Time complexity: O(d(n-d)3^(d/3)) worst case, d is the degeneracy * of the graph, this is typically small for sparse graphs. * */ int igraph_maximal_cliques_callback(const igraph_t *graph, igraph_clique_handler_t *cliquehandler_fn, void *arg, igraph_integer_t min_size, igraph_integer_t max_size); #define IGRAPH_MC_CALLBACK #include "maximal_cliques_template.h" #undef IGRAPH_MC_CALLBACK /** * \function igraph_maximal_cliques_hist * \brief Counts the number of maximal cliques of each size in a graph. * * This function counts how many maximal cliques of each size are present in * the graph. Size-1 maximal cliques are simply isolated vertices. * * * * Edge directions are ignored. * * * * \param graph The input graph. * \param hist Pointer to an initialized vector. The result will be stored * here. The first element will store the number of size-1 maximal cliques, * the second element the number of size-2 maximal cliques, etc. * For cliques smaller than \p min_size, zero counts will be returned. * \param min_size Integer giving the minimum size of the cliques to be * returned. If negative or zero, no lower bound will be used. * \param max_size Integer giving the maximum size of the cliques to be * returned. If negative or zero, no upper bound will be used. * \return Error code. * * \sa \ref igraph_maximal_cliques(). * * Time complexity: O(d(n-d)3^(d/3)) worst case, d is the degeneracy * of the graph, this is typically small for sparse graphs. * */ int igraph_maximal_cliques_hist(const igraph_t *graph, igraph_vector_t *hist, igraph_integer_t min_size, igraph_integer_t max_size); #define IGRAPH_MC_HIST #include "maximal_cliques_template.h" #undef IGRAPH_MC_HIST leidenbase/src/core/flow/0000755000176200001440000000000014532173045015037 5ustar liggesusersleidenbase/src/core/flow/st-cuts.c0000644000176200001440000016542614447675374016644 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_flow.h" #include "igraph_adjlist.h" #include "igraph_constants.h" #include "igraph_constructors.h" #include "igraph_components.h" #include "igraph_error.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_operators.h" #include "igraph_stack.h" #include "igraph_visitor.h" #include "core/math.h" #include "core/estack.h" #include "core/marked_queue.h" #include "graph/attributes.h" #include "flow/flow_internal.h" typedef int igraph_provan_shier_pivot_t(const igraph_t *graph, const igraph_marked_queue_t *S, const igraph_estack_t *T, long int source, long int target, long int *v, igraph_vector_t *Isv, void *arg); /** * \function igraph_even_tarjan_reduction * Even-Tarjan reduction of a graph * * A digraph is created with twice as many vertices and edges. For each * original vertex i, two vertices i'= i and i'' = i' + n are created, * with a directed edge from i' to i''. For each original directed edge * from i to j, two new edges are created, from i' to j'' and from i'' * to j'. * * This reduction is used in the paper (observation 2): * Arkady Kanevsky: Finding all minimum-size separating vertex sets in * a graph, Networks 23, 533--541, 1993. * * The original paper where this reduction was conceived is * Shimon Even and R. Endre Tarjan: Network Flow and Testing Graph * Connectivity, SIAM J. Comput., 4(4), 507–518. * * \param graph A graph. Although directness is not checked, this function * is commonly used only on directed graphs. * \param graphbar Pointer to a new directed graph that will contain the * reduction, with twice as many vertices and edges. * \param capacity Pointer to an initialized vector or a null pointer. If * not a null pointer, then it will be filled the capacity from * the reduction: the first |E| elements are 1, the remaining |E| * are equal to |V| (which is used to mean infinity). * \return Error code. * * Time complexity: O(|E|+|V|). * * \example examples/simple/even_tarjan.c */ int igraph_even_tarjan_reduction(const igraph_t *graph, igraph_t *graphbar, igraph_vector_t *capacity) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int new_no_of_nodes = no_of_nodes * 2; long int new_no_of_edges = no_of_nodes + no_of_edges * 2; igraph_vector_t edges; long int edgeptr = 0, capptr = 0; long int i; IGRAPH_VECTOR_INIT_FINALLY(&edges, new_no_of_edges * 2); if (capacity) { IGRAPH_CHECK(igraph_vector_resize(capacity, new_no_of_edges)); } /* Every vertex 'i' is replaced by two vertices, i' and i'' */ /* id[i'] := id[i] ; id[i''] := id[i] + no_of_nodes */ /* One edge for each original vertex, for i, we add (i',i'') */ for (i = 0; i < no_of_nodes; i++) { VECTOR(edges)[edgeptr++] = i; VECTOR(edges)[edgeptr++] = i + no_of_nodes; if (capacity) { VECTOR(*capacity)[capptr++] = 1.0; } } /* Two news edges for each original edge (from,to) becomes (from'',to'), (to'',from') */ for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); VECTOR(edges)[edgeptr++] = from + no_of_nodes; VECTOR(edges)[edgeptr++] = to; VECTOR(edges)[edgeptr++] = to + no_of_nodes; VECTOR(edges)[edgeptr++] = from; if (capacity) { VECTOR(*capacity)[capptr++] = no_of_nodes; /* TODO: should be Inf */ VECTOR(*capacity)[capptr++] = no_of_nodes; /* TODO: should be Inf */ } } IGRAPH_CHECK(igraph_create(graphbar, &edges, (igraph_integer_t) new_no_of_nodes, IGRAPH_DIRECTED)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_residual_graph(const igraph_t *graph, const igraph_vector_t *capacity, igraph_t *residual, igraph_vector_t *residual_capacity, const igraph_vector_t *flow, igraph_vector_t *tmp) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int i, no_new_edges = 0; long int edgeptr = 0, capptr = 0; for (i = 0; i < no_of_edges; i++) { if (VECTOR(*flow)[i] < VECTOR(*capacity)[i]) { no_new_edges++; } } IGRAPH_CHECK(igraph_vector_resize(tmp, no_new_edges * 2)); if (residual_capacity) { IGRAPH_CHECK(igraph_vector_resize(residual_capacity, no_new_edges)); } for (i = 0; i < no_of_edges; i++) { igraph_real_t c = VECTOR(*capacity)[i] - VECTOR(*flow)[i]; if (c > 0) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); VECTOR(*tmp)[edgeptr++] = from; VECTOR(*tmp)[edgeptr++] = to; if (residual_capacity) { VECTOR(*residual_capacity)[capptr++] = c; } } } IGRAPH_CHECK(igraph_create(residual, tmp, (igraph_integer_t) no_of_nodes, IGRAPH_DIRECTED)); return 0; } int igraph_residual_graph(const igraph_t *graph, const igraph_vector_t *capacity, igraph_t *residual, igraph_vector_t *residual_capacity, const igraph_vector_t *flow) { igraph_vector_t tmp; long int no_of_edges = igraph_ecount(graph); if (igraph_vector_size(capacity) != no_of_edges) { IGRAPH_ERROR("Invalid `capacity' vector size", IGRAPH_EINVAL); } if (igraph_vector_size(flow) != no_of_edges) { IGRAPH_ERROR("Invalid `flow' vector size", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_CHECK(igraph_i_residual_graph(graph, capacity, residual, residual_capacity, flow, &tmp)); igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_reverse_residual_graph(const igraph_t *graph, const igraph_vector_t *capacity, igraph_t *residual, const igraph_vector_t *flow, igraph_vector_t *tmp) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int i, no_new_edges = 0; long int edgeptr = 0; for (i = 0; i < no_of_edges; i++) { igraph_real_t cap = capacity ? VECTOR(*capacity)[i] : 1.0; if (VECTOR(*flow)[i] > 0) { no_new_edges++; } if (VECTOR(*flow)[i] < cap) { no_new_edges++; } } IGRAPH_CHECK(igraph_vector_resize(tmp, no_new_edges * 2)); for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); igraph_real_t cap = capacity ? VECTOR(*capacity)[i] : 1.0; if (VECTOR(*flow)[i] > 0) { VECTOR(*tmp)[edgeptr++] = from; VECTOR(*tmp)[edgeptr++] = to; } if (VECTOR(*flow)[i] < cap) { VECTOR(*tmp)[edgeptr++] = to; VECTOR(*tmp)[edgeptr++] = from; } } IGRAPH_CHECK(igraph_create(residual, tmp, (igraph_integer_t) no_of_nodes, IGRAPH_DIRECTED)); return 0; } int igraph_reverse_residual_graph(const igraph_t *graph, const igraph_vector_t *capacity, igraph_t *residual, const igraph_vector_t *flow) { igraph_vector_t tmp; long int no_of_edges = igraph_ecount(graph); if (capacity && igraph_vector_size(capacity) != no_of_edges) { IGRAPH_ERROR("Invalid `capacity' vector size", IGRAPH_EINVAL); } if (igraph_vector_size(flow) != no_of_edges) { IGRAPH_ERROR("Invalid `flow' vector size", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_CHECK(igraph_i_reverse_residual_graph(graph, capacity, residual, flow, &tmp)); igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); return 0; } typedef struct igraph_i_dbucket_t { igraph_vector_long_t head; igraph_vector_long_t next; } igraph_i_dbucket_t; static int igraph_i_dbucket_init(igraph_i_dbucket_t *buck, long int size) { IGRAPH_CHECK(igraph_vector_long_init(&buck->head, size)); IGRAPH_FINALLY(igraph_vector_long_destroy, &buck->head); IGRAPH_CHECK(igraph_vector_long_init(&buck->next, size)); IGRAPH_FINALLY_CLEAN(1); return 0; } static void igraph_i_dbucket_destroy(igraph_i_dbucket_t *buck) { igraph_vector_long_destroy(&buck->head); igraph_vector_long_destroy(&buck->next); } static int igraph_i_dbucket_insert(igraph_i_dbucket_t *buck, long int bid, long int elem) { /* Note: we can do this, since elem is not in any buckets */ VECTOR(buck->next)[elem] = VECTOR(buck->head)[bid]; VECTOR(buck->head)[bid] = elem + 1; return 0; } static long int igraph_i_dbucket_empty(const igraph_i_dbucket_t *buck, long int bid) { return VECTOR(buck->head)[bid] == 0; } static long int igraph_i_dbucket_delete(igraph_i_dbucket_t *buck, long int bid) { long int elem = VECTOR(buck->head)[bid] - 1; VECTOR(buck->head)[bid] = VECTOR(buck->next)[elem]; return elem; } static int igraph_i_dominator_LINK(long int v, long int w, igraph_vector_long_t *ancestor) { VECTOR(*ancestor)[w] = v + 1; return 0; } /* TODO: don't always reallocate path */ static int igraph_i_dominator_COMPRESS(long int v, igraph_vector_long_t *ancestor, igraph_vector_long_t *label, igraph_vector_long_t *semi) { igraph_stack_long_t path; long int w = v; long int top, pretop; IGRAPH_CHECK(igraph_stack_long_init(&path, 10)); IGRAPH_FINALLY(igraph_stack_long_destroy, &path); while (VECTOR(*ancestor)[w] != 0) { IGRAPH_CHECK(igraph_stack_long_push(&path, w)); w = VECTOR(*ancestor)[w] - 1; } top = igraph_stack_long_pop(&path); while (!igraph_stack_long_empty(&path)) { pretop = igraph_stack_long_pop(&path); if (VECTOR(*semi)[VECTOR(*label)[top]] < VECTOR(*semi)[VECTOR(*label)[pretop]]) { VECTOR(*label)[pretop] = VECTOR(*label)[top]; } VECTOR(*ancestor)[pretop] = VECTOR(*ancestor)[top]; top = pretop; } igraph_stack_long_destroy(&path); IGRAPH_FINALLY_CLEAN(1); return 0; } static long int igraph_i_dominator_EVAL(long int v, igraph_vector_long_t *ancestor, igraph_vector_long_t *label, igraph_vector_long_t *semi) { if (VECTOR(*ancestor)[v] == 0) { return v; } else { igraph_i_dominator_COMPRESS(v, ancestor, label, semi); return VECTOR(*label)[v]; } } /* TODO: implement the faster version. */ /** * \function igraph_dominator_tree * Calculates the dominator tree of a flowgraph * * A flowgraph is a directed graph with a distinguished start (or * root) vertex r, such that for any vertex v, there is a path from r * to v. A vertex v dominates another vertex w (not equal to v), if * every path from r to w contains v. Vertex v is the immediate * dominator or w, v=idom(w), if v dominates w and every other * dominator of w dominates v. The edges {(idom(w), w)| w is not r} * form a directed tree, rooted at r, called the dominator tree of the * graph. Vertex v dominates vertex w if and only if v is an ancestor * of w in the dominator tree. * * This function implements the Lengauer-Tarjan algorithm * to construct the dominator tree of a directed graph. For details * please see Thomas Lengauer, Robert Endre Tarjan: A fast algorithm * for finding dominators in a flowgraph, ACM Transactions on * Programming Languages and Systems (TOPLAS) I/1, 121--141, 1979. * * \param graph A directed graph. If it is not a flowgraph, and it * contains some vertices not reachable from the root vertex, * then these vertices will be collected in the \c leftout * vector. * \param root The id of the root (or source) vertex, this will be the * root of the tree. * \param dom Pointer to an initialized vector or a null pointer. If * not a null pointer, then the immediate dominator of each * vertex will be stored here. For vertices that are not * reachable from the root, NaN is stored here. For * the root vertex itself, -1 is added. * \param domtree Pointer to an uninitialized igraph_t, or NULL. If * not a null pointer, then the dominator tree is returned * here. The graph contains the vertices that are unreachable * from the root (if any), these will be isolates. * \param leftout Pointer to an initialized vector object, or NULL. If * not NULL, then the ids of the vertices that are unreachable * from the root vertex (and thus not part of the dominator * tree) are stored here. * \param mode Constant, must be \c IGRAPH_IN or \c IGRAPH_OUT. If it * is \c IGRAPH_IN, then all directions are considered as * opposite to the original one in the input graph. * \return Error code. * * Time complexity: very close to O(|E|+|V|), linear in the number of * edges and vertices. More precisely, it is O(|V|+|E|alpha(|E|,|V|)), * where alpha(|E|,|V|) is a functional inverse of Ackermann's * function. * * \example examples/simple/dominator_tree.c */ int igraph_dominator_tree(const igraph_t *graph, igraph_integer_t root, igraph_vector_t *dom, igraph_t *domtree, igraph_vector_t *leftout, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); igraph_adjlist_t succ, pred; igraph_vector_t parent; igraph_vector_long_t semi; /* +1 always */ igraph_vector_t vertex; /* +1 always */ igraph_i_dbucket_t bucket; igraph_vector_long_t ancestor; igraph_vector_long_t label; igraph_neimode_t invmode = mode == IGRAPH_IN ? IGRAPH_OUT : IGRAPH_IN; long int i; igraph_vector_t vdom, *mydom = dom; long int component_size = 0; if (root < 0 || root >= no_of_nodes) { IGRAPH_ERROR("Invalid root vertex id for dominator tree", IGRAPH_EINVAL); } if (!igraph_is_directed(graph)) { IGRAPH_ERROR("Dominator tree of an undirected graph requested", IGRAPH_EINVAL); } if (mode == IGRAPH_ALL) { IGRAPH_ERROR("Invalid neighbor mode for dominator tree", IGRAPH_EINVAL); } if (dom) { IGRAPH_CHECK(igraph_vector_resize(dom, no_of_nodes)); } else { mydom = &vdom; IGRAPH_VECTOR_INIT_FINALLY(mydom, no_of_nodes); } igraph_vector_fill(mydom, IGRAPH_NAN); IGRAPH_CHECK(igraph_vector_init(&parent, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_destroy, &parent); IGRAPH_CHECK(igraph_vector_long_init(&semi, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &semi); IGRAPH_CHECK(igraph_vector_init(&vertex, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_destroy, &vertex); IGRAPH_CHECK(igraph_vector_long_init(&ancestor, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &ancestor); IGRAPH_CHECK(igraph_vector_long_init_seq(&label, 0, no_of_nodes - 1)); IGRAPH_FINALLY(igraph_vector_long_destroy, &label); IGRAPH_CHECK(igraph_adjlist_init(graph, &succ, mode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &succ); IGRAPH_CHECK(igraph_adjlist_init(graph, &pred, invmode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &pred); IGRAPH_CHECK(igraph_i_dbucket_init(&bucket, no_of_nodes)); IGRAPH_FINALLY(igraph_i_dbucket_destroy, &bucket); /* DFS first, to set semi, vertex and parent, step 1 */ IGRAPH_CHECK(igraph_dfs(graph, root, mode, /*unreachable=*/ 0, /*order=*/ &vertex, /*order_out=*/ 0, /*father=*/ &parent, /*dist=*/ 0, /*in_callback=*/ 0, /*out_callback=*/ 0, /*extra=*/ 0)); for (i = 0; i < no_of_nodes; i++) { if (IGRAPH_FINITE(VECTOR(vertex)[i])) { long int t = (long int) VECTOR(vertex)[i]; VECTOR(semi)[t] = component_size + 1; VECTOR(vertex)[component_size] = t + 1; component_size++; } } if (leftout) { long int n = no_of_nodes - component_size; long int p = 0, j; IGRAPH_CHECK(igraph_vector_resize(leftout, n)); for (j = 0; j < no_of_nodes && p < n; j++) { if (!IGRAPH_FINITE(VECTOR(parent)[j])) { VECTOR(*leftout)[p++] = j; } } } /* We need to go over 'pred' because it should contain only the edges towards the target vertex. */ for (i = 0; i < no_of_nodes; i++) { igraph_vector_int_t *v = igraph_adjlist_get(&pred, i); long int j, n = igraph_vector_int_size(v); for (j = 0; j < n; ) { long int v2 = (long int) VECTOR(*v)[j]; if (IGRAPH_FINITE(VECTOR(parent)[v2])) { j++; } else { VECTOR(*v)[j] = VECTOR(*v)[n - 1]; igraph_vector_int_pop_back(v); n--; } } } /* Now comes the main algorithm, steps 2 & 3 */ for (i = component_size - 1; i > 0; i--) { long int w = (long int) VECTOR(vertex)[i] - 1; igraph_vector_int_t *predw = igraph_adjlist_get(&pred, w); long int j, n = igraph_vector_int_size(predw); for (j = 0; j < n; j++) { long int v = (long int) VECTOR(*predw)[j]; long int u = igraph_i_dominator_EVAL(v, &ancestor, &label, &semi); if (VECTOR(semi)[u] < VECTOR(semi)[w]) { VECTOR(semi)[w] = VECTOR(semi)[u]; } } igraph_i_dbucket_insert(&bucket, (long int) VECTOR(vertex)[ VECTOR(semi)[w] - 1 ] - 1, w); igraph_i_dominator_LINK((long int) VECTOR(parent)[w], w, &ancestor); while (!igraph_i_dbucket_empty(&bucket, (long int) VECTOR(parent)[w])) { long int v = igraph_i_dbucket_delete(&bucket, (long int) VECTOR(parent)[w]); long int u = igraph_i_dominator_EVAL(v, &ancestor, &label, &semi); VECTOR(*mydom)[v] = VECTOR(semi)[u] < VECTOR(semi)[v] ? u : VECTOR(parent)[w]; } } /* Finally, step 4 */ for (i = 1; i < component_size; i++) { long int w = (long int) VECTOR(vertex)[i] - 1; if (VECTOR(*mydom)[w] != VECTOR(vertex)[VECTOR(semi)[w] - 1] - 1) { VECTOR(*mydom)[w] = VECTOR(*mydom)[(long int)VECTOR(*mydom)[w]]; } } VECTOR(*mydom)[(long int)root] = -1; igraph_i_dbucket_destroy(&bucket); igraph_adjlist_destroy(&pred); igraph_adjlist_destroy(&succ); igraph_vector_long_destroy(&label); igraph_vector_long_destroy(&ancestor); igraph_vector_destroy(&vertex); igraph_vector_long_destroy(&semi); igraph_vector_destroy(&parent); IGRAPH_FINALLY_CLEAN(8); if (domtree) { igraph_vector_t edges; long int ptr = 0; IGRAPH_VECTOR_INIT_FINALLY(&edges, component_size * 2 - 2); for (i = 0; i < no_of_nodes; i++) { if (i != root && IGRAPH_FINITE(VECTOR(*mydom)[i])) { if (mode == IGRAPH_OUT) { VECTOR(edges)[ptr++] = VECTOR(*mydom)[i]; VECTOR(edges)[ptr++] = i; } else { VECTOR(edges)[ptr++] = i; VECTOR(edges)[ptr++] = VECTOR(*mydom)[i]; } } } IGRAPH_CHECK(igraph_create(domtree, &edges, (igraph_integer_t) no_of_nodes, IGRAPH_DIRECTED)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_I_ATTRIBUTE_DESTROY(domtree); IGRAPH_I_ATTRIBUTE_COPY(domtree, graph, /*graph=*/ 1, /*vertex=*/ 1, /*edge=*/ 0); } if (!dom) { igraph_vector_destroy(&vdom); IGRAPH_FINALLY_CLEAN(1); } return 0; } typedef struct igraph_i_all_st_cuts_minimal_dfs_data_t { igraph_stack_t *stack; igraph_vector_bool_t *nomark; const igraph_vector_bool_t *GammaX; long int root; const igraph_vector_t *map; } igraph_i_all_st_cuts_minimal_dfs_data_t; static igraph_bool_t igraph_i_all_st_cuts_minimal_dfs_incb( const igraph_t *graph, igraph_integer_t vid, igraph_integer_t dist, void *extra) { igraph_i_all_st_cuts_minimal_dfs_data_t *data = extra; igraph_stack_t *stack = data->stack; igraph_vector_bool_t *nomark = data->nomark; const igraph_vector_bool_t *GammaX = data->GammaX; const igraph_vector_t *map = data->map; long int realvid = (long int) VECTOR(*map)[(long int)vid]; IGRAPH_UNUSED(graph); IGRAPH_UNUSED(dist); if (VECTOR(*GammaX)[(long int)realvid]) { if (!igraph_stack_empty(stack)) { long int top = (long int) igraph_stack_top(stack); VECTOR(*nomark)[top] = 1; /* we just found a smaller one */ } igraph_stack_push(stack, realvid); /* TODO: error check */ } return 0; } static igraph_bool_t igraph_i_all_st_cuts_minimal_dfs_otcb( const igraph_t *graph, igraph_integer_t vid, igraph_integer_t dist, void *extra) { igraph_i_all_st_cuts_minimal_dfs_data_t *data = extra; igraph_stack_t *stack = data->stack; const igraph_vector_t *map = data->map; long int realvid = (long int) VECTOR(*map)[(long int)vid]; IGRAPH_UNUSED(graph); IGRAPH_UNUSED(dist); if (!igraph_stack_empty(stack) && igraph_stack_top(stack) == realvid) { igraph_stack_pop(stack); } return 0; } static int igraph_i_all_st_cuts_minimal(const igraph_t *graph, const igraph_t *domtree, long int root, const igraph_marked_queue_t *X, const igraph_vector_bool_t *GammaX, const igraph_vector_t *invmap, igraph_vector_t *minimal) { long int no_of_nodes = igraph_vcount(graph); igraph_stack_t stack; igraph_vector_bool_t nomark; igraph_i_all_st_cuts_minimal_dfs_data_t data; long int i; IGRAPH_UNUSED(X); IGRAPH_CHECK(igraph_stack_init(&stack, 10)); IGRAPH_FINALLY(igraph_stack_destroy, &stack); IGRAPH_CHECK(igraph_vector_bool_init(&nomark, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &nomark); data.stack = &stack; data.nomark = &nomark; data.GammaX = GammaX; data.root = root; data.map = invmap; /* We mark all GammaX elements as minimal first. TODO: actually, we could just use GammaX to return the minimal elements. */ for (i = 0; i < no_of_nodes; i++) { VECTOR(nomark)[i] = VECTOR(*GammaX)[i] == 0 ? 1 : 0; } /* We do a reverse DFS from root. If, along a path we find a GammaX vertex after (=below) another GammaX vertex, we mark the higher one as non-minimal. */ IGRAPH_CHECK(igraph_dfs(domtree, (igraph_integer_t) root, IGRAPH_IN, /*unreachable=*/ 0, /*order=*/ 0, /*order_out=*/ 0, /*father=*/ 0, /*dist=*/ 0, /*in_callback=*/ igraph_i_all_st_cuts_minimal_dfs_incb, /*out_callback=*/ igraph_i_all_st_cuts_minimal_dfs_otcb, /*extra=*/ &data)); igraph_vector_clear(minimal); for (i = 0; i < no_of_nodes; i++) { if (!VECTOR(nomark)[i]) { IGRAPH_CHECK(igraph_vector_push_back(minimal, i)); } } igraph_vector_bool_destroy(&nomark); igraph_stack_destroy(&stack); IGRAPH_FINALLY_CLEAN(2); return 0; } /* not 'static' because used in igraph_all_st_cuts.c test program */ int igraph_i_all_st_cuts_pivot(const igraph_t *graph, const igraph_marked_queue_t *S, const igraph_estack_t *T, long int source, long int target, long int *v, igraph_vector_t *Isv, void *arg) { long int no_of_nodes = igraph_vcount(graph); igraph_t Sbar; igraph_vector_t Sbar_map, Sbar_invmap; igraph_vector_t keep; igraph_t domtree; igraph_vector_t leftout; long int i, nomin, n; long int root; igraph_vector_t M; igraph_vector_bool_t GammaS; igraph_vector_t Nuv; igraph_vector_t Isv_min; igraph_vector_t GammaS_vec; long int Sbar_size; IGRAPH_UNUSED(arg); /* We need to create the graph induced by Sbar */ IGRAPH_VECTOR_INIT_FINALLY(&Sbar_map, 0); IGRAPH_VECTOR_INIT_FINALLY(&Sbar_invmap, 0); IGRAPH_VECTOR_INIT_FINALLY(&keep, 0); for (i = 0; i < no_of_nodes; i++) { if (!igraph_marked_queue_iselement(S, i)) { IGRAPH_CHECK(igraph_vector_push_back(&keep, i)); } } Sbar_size = igraph_vector_size(&keep); IGRAPH_CHECK(igraph_induced_subgraph_map(graph, &Sbar, igraph_vss_vector(&keep), IGRAPH_SUBGRAPH_AUTO, /* map= */ &Sbar_map, /* invmap= */ &Sbar_invmap)); igraph_vector_destroy(&keep); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &Sbar); root = (long int) VECTOR(Sbar_map)[target] - 1; /* -------------------------------------------------------------*/ /* Construct the dominator tree of Sbar */ IGRAPH_VECTOR_INIT_FINALLY(&leftout, 0); IGRAPH_CHECK(igraph_dominator_tree(&Sbar, (igraph_integer_t) root, /*dom=*/ 0, &domtree, &leftout, IGRAPH_IN)); IGRAPH_FINALLY(igraph_destroy, &domtree); /* -------------------------------------------------------------*/ /* Identify the set M of minimal elements of Gamma(S) with respect to the dominator relation. */ /* First we create GammaS */ /* TODO: use the adjacency list, instead of neighbors() */ IGRAPH_CHECK(igraph_vector_bool_init(&GammaS, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &GammaS); if (igraph_marked_queue_size(S) == 0) { VECTOR(GammaS)[(long int) VECTOR(Sbar_map)[source] - 1] = 1; } else { for (i = 0; i < no_of_nodes; i++) { if (igraph_marked_queue_iselement(S, i)) { igraph_vector_t neis; long int j; IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) i, IGRAPH_OUT)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (!igraph_marked_queue_iselement(S, nei)) { VECTOR(GammaS)[nei] = 1; } } igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(1); } } } /* Relabel left out vertices (set K in Provan & Shier) to correspond to node labelling of graph instead of SBar. At the same time ensure that GammaS is a proper subset of L, where L are the nodes in the dominator tree. */ n = igraph_vector_size(&leftout); for (i = 0; i < n; i++) { VECTOR(leftout)[i] = VECTOR(Sbar_invmap)[(long int)VECTOR(leftout)[i]]; VECTOR(GammaS)[(long int)VECTOR(leftout)[i]] = 0; } IGRAPH_VECTOR_INIT_FINALLY(&M, 0); if (igraph_ecount(&domtree) > 0) { IGRAPH_CHECK(igraph_i_all_st_cuts_minimal(graph, &domtree, root, S, &GammaS, &Sbar_invmap, &M)); } igraph_vector_clear(Isv); IGRAPH_VECTOR_INIT_FINALLY(&Nuv, 0); IGRAPH_VECTOR_INIT_FINALLY(&Isv_min, 0); IGRAPH_VECTOR_INIT_FINALLY(&GammaS_vec, 0); for (i = 0; i < no_of_nodes; i++) { if (VECTOR(GammaS)[i]) { IGRAPH_CHECK(igraph_vector_push_back(&GammaS_vec, i)); } } nomin = igraph_vector_size(&M); for (i = 0; i < nomin; i++) { /* -------------------------------------------------------------*/ /* For each v in M find the set Nu(v)=dom(Sbar, v)-K Nu(v) contains all vertices that are dominated by v, for every v, this is a subtree of the dominator tree, rooted at v. The different subtrees are disjoint. */ long int min = (long int) VECTOR(Sbar_map)[(long int) VECTOR(M)[i] ] - 1; long int nuvsize, isvlen, j; IGRAPH_CHECK(igraph_dfs(&domtree, (igraph_integer_t) min, IGRAPH_IN, /*unreachable=*/ 0, /*order=*/ &Nuv, /*order_out=*/ 0, /*father=*/ 0, /*dist=*/ 0, /*in_callback=*/ 0, /*out_callback=*/ 0, /*extra=*/ 0)); /* Remove the NAN values from the end of the vector */ for (nuvsize = 0; nuvsize < Sbar_size; nuvsize++) { igraph_real_t t = VECTOR(Nuv)[nuvsize]; if (IGRAPH_FINITE(t)) { VECTOR(Nuv)[nuvsize] = VECTOR(Sbar_invmap)[(long int) t]; } else { break; } } igraph_vector_resize(&Nuv, nuvsize); /* -------------------------------------------------------------*/ /* By a BFS search of determine I(S,v)-K. I(S,v) contains all vertices that are in Nu(v) and that are reachable from Gamma(S) via a path in Nu(v). */ IGRAPH_CHECK(igraph_bfs(graph, /*root=*/ -1, /*roots=*/ &GammaS_vec, /*mode=*/ IGRAPH_OUT, /*unreachable=*/ 0, /*restricted=*/ &Nuv, /*order=*/ &Isv_min, /*rank=*/ 0, /*father=*/ 0, /*pred=*/ 0, /*succ=*/ 0, /*dist=*/ 0, /*callback=*/ 0, /*extra=*/ 0)); for (isvlen = 0; isvlen < no_of_nodes; isvlen++) { if (!IGRAPH_FINITE(VECTOR(Isv_min)[isvlen])) { break; } } igraph_vector_resize(&Isv_min, isvlen); /* -------------------------------------------------------------*/ /* For each c in M check whether Isv-K is included in Tbar. If such a v is found, compute Isv={x|v[Nu(v) U K]x} and return v and Isv; otherwise return Isv={}. */ for (j = 0; j < isvlen; j++) { long int u = (long int) VECTOR(Isv_min)[j]; if (igraph_estack_iselement(T, u) || u == target) { break; } } /* We might have found one */ if (j == isvlen) { *v = (long int) VECTOR(M)[i]; /* Calculate real Isv */ IGRAPH_CHECK(igraph_vector_append(&Nuv, &leftout)); IGRAPH_CHECK(igraph_bfs(graph, /*root=*/ (igraph_integer_t) *v, /*roots=*/ 0, /*mode=*/ IGRAPH_OUT, /*unreachable=*/ 0, /*restricted=*/ &Nuv, /*order=*/ &Isv_min, /*rank=*/ 0, /*father=*/ 0, /*pred=*/ 0, /*succ=*/ 0, /*dist=*/ 0, /*callback=*/ 0, /*extra=*/ 0)); for (isvlen = 0; isvlen < no_of_nodes; isvlen++) { if (!IGRAPH_FINITE(VECTOR(Isv_min)[isvlen])) { break; } } igraph_vector_resize(&Isv_min, isvlen); igraph_vector_update(Isv, &Isv_min); break; } } igraph_vector_destroy(&GammaS_vec); igraph_vector_destroy(&Isv_min); igraph_vector_destroy(&Nuv); IGRAPH_FINALLY_CLEAN(3); igraph_vector_destroy(&M); igraph_vector_bool_destroy(&GammaS); igraph_destroy(&domtree); igraph_vector_destroy(&leftout); igraph_destroy(&Sbar); igraph_vector_destroy(&Sbar_map); igraph_vector_destroy(&Sbar_invmap); IGRAPH_FINALLY_CLEAN(7); return 0; } /* TODO: This is a temporary recursive version, without proper error handling */ int igraph_provan_shier_list(const igraph_t *graph, igraph_marked_queue_t *S, igraph_estack_t *T, long int source, long int target, igraph_vector_ptr_t *result, igraph_provan_shier_pivot_t *pivot, void *pivot_arg) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t Isv; long int v = 0; long int i, n; igraph_vector_init(&Isv, 0); pivot(graph, S, T, source, target, &v, &Isv, pivot_arg); if (igraph_vector_size(&Isv) == 0) { if (igraph_marked_queue_size(S) != 0 && igraph_marked_queue_size(S) != no_of_nodes) { igraph_vector_t *vec = IGRAPH_CALLOC(1, igraph_vector_t); igraph_vector_init(vec, igraph_marked_queue_size(S)); igraph_marked_queue_as_vector(S, vec); IGRAPH_CHECK(igraph_vector_ptr_push_back(result, vec)); } } else { /* Put v into T */ igraph_estack_push(T, v); /* Go down left in the search tree */ igraph_provan_shier_list(graph, S, T, source, target, result, pivot, pivot_arg); /* Take out v from T */ igraph_estack_pop(T); /* Add Isv to S */ igraph_marked_queue_start_batch(S); n = igraph_vector_size(&Isv); for (i = 0; i < n; i++) { if (!igraph_marked_queue_iselement(S, (long int) VECTOR(Isv)[i])) { igraph_marked_queue_push(S, (long int) VECTOR(Isv)[i]); } } /* Go down right in the search tree */ igraph_provan_shier_list(graph, S, T, source, target, result, pivot, pivot_arg); /* Take out Isv from S */ igraph_marked_queue_pop_back_batch(S); } igraph_vector_destroy(&Isv); return 0; } /** * \function igraph_all_st_cuts * List all edge-cuts between two vertices in a directed graph * * This function lists all edge-cuts between a source and a target * vertex. Every cut is listed exactly once. The implemented algorithm * is described in JS Provan and DR Shier: A Paradigm for listing * (s,t)-cuts in graphs, Algorithmica 15, 351--372, 1996. * * \param graph The input graph, is must be directed. * \param cuts An initialized pointer vector, the cuts are stored * here. It is a list of pointers to igraph_vector_t * objects. Each vector will contain the ids of the edges in * the cut. This argument is ignored if it is a null pointer. * To free all memory allocated for \c cuts, you need call * \ref igraph_vector_destroy() and then \ref igraph_free() on * each element, before destroying the pointer vector itself. * \param partition1s An initialized pointer vector, the list of * vertex sets, generating the actual edge cuts, are stored * here. Each vector contains a set of vertex ids. If X is such * a set, then all edges going from X to the complement of X * form an (s,t) edge-cut in the graph. This argument is * ignored if it is a null pointer. * To free all memory allocated for \c partition1s, you need call * \ref igraph_vector_destroy() and then \ref igraph_free() on * each element, before destroying the pointer vector itself. * \param source The id of the source vertex. * \param target The id of the target vertex. * \return Error code. * * Time complexity: O(n(|V|+|E|)), where |V| is the number of * vertices, |E| is the number of edges, and n is the number of cuts. */ int igraph_all_st_cuts(const igraph_t *graph, igraph_vector_ptr_t *cuts, igraph_vector_ptr_t *partition1s, igraph_integer_t source, igraph_integer_t target) { /* S is a special stack, in which elements are pushed in batches. It is then possible to remove the whole batch in one step. T is a stack with an is-element operation. Every element is included at most once. */ long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_marked_queue_t S; igraph_estack_t T; igraph_vector_ptr_t *mypartition1s = partition1s, vpartition1s; long int i, nocuts; if (!igraph_is_directed(graph)) { IGRAPH_ERROR("Listing all s-t cuts only implemented for " "directed graphs", IGRAPH_UNIMPLEMENTED); } if (!partition1s) { mypartition1s = &vpartition1s; IGRAPH_CHECK(igraph_vector_ptr_init(mypartition1s, 0)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, mypartition1s); } else { igraph_vector_ptr_clear(mypartition1s); } IGRAPH_CHECK(igraph_marked_queue_init(&S, no_of_nodes)); IGRAPH_FINALLY(igraph_marked_queue_destroy, &S); IGRAPH_CHECK(igraph_estack_init(&T, no_of_nodes, 0)); IGRAPH_FINALLY(igraph_estack_destroy, &T); if (cuts) { igraph_vector_ptr_clear(cuts); } /* We call it with S={}, T={} */ IGRAPH_CHECK(igraph_provan_shier_list(graph, &S, &T, source, target, mypartition1s, igraph_i_all_st_cuts_pivot, /*pivot_arg=*/ 0)); nocuts = igraph_vector_ptr_size(mypartition1s); if (cuts) { igraph_vector_long_t inS; IGRAPH_CHECK(igraph_vector_long_init(&inS, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &inS); IGRAPH_CHECK(igraph_vector_ptr_resize(cuts, nocuts)); for (i = 0; i < nocuts; i++) { igraph_vector_t *cut; igraph_vector_t *part = VECTOR(*mypartition1s)[i]; long int cutsize = 0; long int j, partlen = igraph_vector_size(part); /* Mark elements */ for (j = 0; j < partlen; j++) { long int v = (long int) VECTOR(*part)[j]; VECTOR(inS)[v] = i + 1; } /* Check how many edges */ for (j = 0; j < no_of_edges; j++) { long int from = IGRAPH_FROM(graph, j); long int to = IGRAPH_TO(graph, j); long int pfrom = VECTOR(inS)[from]; long int pto = VECTOR(inS)[to]; if (pfrom == i + 1 && pto != i + 1) { cutsize++; } } /* Add the edges */ cut = IGRAPH_CALLOC(1, igraph_vector_t); if (!cut) { IGRAPH_ERROR("Cannot calculate s-t cuts", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(cut, cutsize); cutsize = 0; for (j = 0; j < no_of_edges; j++) { long int from = IGRAPH_FROM(graph, j); long int to = IGRAPH_TO(graph, j); long int pfrom = VECTOR(inS)[from]; long int pto = VECTOR(inS)[to]; if ((pfrom == i + 1 && pto != i + 1)) { VECTOR(*cut)[cutsize++] = j; } } VECTOR(*cuts)[i] = cut; IGRAPH_FINALLY_CLEAN(1); } igraph_vector_long_destroy(&inS); IGRAPH_FINALLY_CLEAN(1); } igraph_estack_destroy(&T); igraph_marked_queue_destroy(&S); IGRAPH_FINALLY_CLEAN(2); if (!partition1s) { for (i = 0; i < nocuts; i++) { igraph_vector_t *cut = VECTOR(*mypartition1s)[i]; igraph_vector_destroy(cut); igraph_free(cut); VECTOR(*mypartition1s)[i] = 0; } igraph_vector_ptr_destroy(mypartition1s); IGRAPH_FINALLY_CLEAN(1); } return 0; } /* We need to find the minimal active elements of Sbar. I.e. all active Sbar elements 'v', s.t. there is no other 'w' active Sbar element from which 'v' is reachable. (Not necessarily through active vertices.) We calculate the in-degree of all vertices in Sbar first. Then we look at the vertices with zero in-degree. If these are active, then they are minimal. If they are are not active, then we remove them from the graph, and check whether they resulted in more zero-indegree vertices. */ static int igraph_i_all_st_mincuts_minimal(const igraph_t *Sbar, const igraph_vector_bool_t *active, const igraph_vector_t *invmap, igraph_vector_t *minimal) { long int no_of_nodes = igraph_vcount(Sbar); igraph_vector_t indeg; long int i, minsize; igraph_vector_t neis; IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_INIT_FINALLY(&indeg, no_of_nodes); IGRAPH_CHECK(igraph_degree(Sbar, &indeg, igraph_vss_all(), IGRAPH_IN, /*loops=*/ 1)); #define ACTIVE(x) (VECTOR(*active)[(long int)VECTOR(*invmap)[(x)]]) #define ZEROIN(x) (VECTOR(indeg)[(x)]==0) for (i = 0; i < no_of_nodes; i++) { if (!ACTIVE(i)) { long int j, n; IGRAPH_CHECK(igraph_neighbors(Sbar, &neis, (igraph_integer_t) i, IGRAPH_OUT)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; VECTOR(indeg)[nei] -= 1; } } } for (minsize = 0, i = 0; i < no_of_nodes; i++) { if (ACTIVE(i) && ZEROIN(i)) { minsize++; } } IGRAPH_CHECK(igraph_vector_resize(minimal, minsize)); for (minsize = 0, i = 0; i < no_of_nodes; i++) { if (ACTIVE(i) && ZEROIN(i)) { VECTOR(*minimal)[minsize++] = i; } } #undef ACTIVE #undef ZEROIN igraph_vector_destroy(&indeg); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(2); return 0; } typedef struct igraph_i_all_st_mincuts_data_t { const igraph_vector_bool_t *active; } igraph_i_all_st_mincuts_data_t; static int igraph_i_all_st_mincuts_pivot(const igraph_t *graph, const igraph_marked_queue_t *S, const igraph_estack_t *T, long int source, long int target, long int *v, igraph_vector_t *Isv, void *arg) { igraph_i_all_st_mincuts_data_t *data = arg; const igraph_vector_bool_t *active = data->active; long int no_of_nodes = igraph_vcount(graph); long int i, j; igraph_vector_t Sbar_map, Sbar_invmap; igraph_vector_t keep; igraph_t Sbar; igraph_vector_t M; long int nomin; IGRAPH_UNUSED(source); IGRAPH_UNUSED(target); if (igraph_marked_queue_size(S) == no_of_nodes) { igraph_vector_clear(Isv); return 0; } /* Create the graph induced by Sbar */ IGRAPH_VECTOR_INIT_FINALLY(&Sbar_map, 0); IGRAPH_VECTOR_INIT_FINALLY(&Sbar_invmap, 0); IGRAPH_VECTOR_INIT_FINALLY(&keep, 0); for (i = 0; i < no_of_nodes; i++) { if (!igraph_marked_queue_iselement(S, i)) { IGRAPH_CHECK(igraph_vector_push_back(&keep, i)); } } /* TODO: it is not even necessary to create Sbar explicitly, we just need to find the M elements efficiently. See the Provan-Shier paper for details. */ IGRAPH_CHECK(igraph_induced_subgraph_map(graph, &Sbar, igraph_vss_vector(&keep), IGRAPH_SUBGRAPH_AUTO, /* map= */ &Sbar_map, /* invmap= */ &Sbar_invmap)); IGRAPH_FINALLY(igraph_destroy, &Sbar); /* ------------------------------------------------------------- */ /* Identify the set M of minimal elements that are active */ IGRAPH_VECTOR_INIT_FINALLY(&M, 0); IGRAPH_CHECK(igraph_i_all_st_mincuts_minimal(&Sbar, active, &Sbar_invmap, &M)); /* ------------------------------------------------------------- */ /* Now find a minimal element that is not in T */ igraph_vector_clear(Isv); nomin = igraph_vector_size(&M); for (i = 0; i < nomin; i++) { long int min = (long int) VECTOR(Sbar_invmap)[ (long int) VECTOR(M)[i] ]; if (min != target) if (!igraph_estack_iselement(T, min)) { break; } } if (i != nomin) { /* OK, we found a pivot element. I(S,v) contains all elements that can reach the pivot element */ igraph_vector_t Isv_min; IGRAPH_VECTOR_INIT_FINALLY(&Isv_min, 0); *v = (long int) VECTOR(Sbar_invmap)[ (long int) VECTOR(M)[i] ]; /* TODO: restricted == keep ? */ IGRAPH_CHECK(igraph_bfs(graph, /*root=*/ (igraph_integer_t) *v,/*roots=*/ 0, /*mode=*/ IGRAPH_IN, /*unreachable=*/ 0, /*restricted=*/ &keep, /*order=*/ &Isv_min, /*rank=*/ 0, /*father=*/ 0, /*pred=*/ 0, /*succ=*/ 0, /*dist=*/ 0, /*callback=*/ 0, /*extra=*/ 0)); for (j = 0; j < no_of_nodes; j++) { igraph_real_t u = VECTOR(Isv_min)[j]; if (!IGRAPH_FINITE(u)) { break; } if (!igraph_estack_iselement(T, u)) { IGRAPH_CHECK(igraph_vector_push_back(Isv, u)); } } igraph_vector_destroy(&Isv_min); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&M); igraph_destroy(&Sbar); igraph_vector_destroy(&keep); igraph_vector_destroy(&Sbar_invmap); igraph_vector_destroy(&Sbar_map); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \function igraph_all_st_mincuts * All minimum s-t cuts of a directed graph * * This function lists all edge cuts between two vertices, in a directed graph, * with minimum total capacity. Possibly, multiple cuts may have the same total * capacity, although there is often only one minimum cut in weighted graphs. * It is recommended to supply integer-values capacities. Otherwise, not all * minimum cuts may be detected because of numerical roundoff errors. * The implemented algorithm is described in JS Provan and DR * Shier: A Paradigm for listing (s,t)-cuts in graphs, Algorithmica 15, * 351--372, 1996. * * \param graph The input graph, it must be directed. * \param value Pointer to a real number, the value of the minimum cut * is stored here, unless it is a null pointer. * \param cuts An initialized pointer vector, the cuts are stored * here. It is a list of pointers to igraph_vector_t * objects. Each vector will contain the ids of the edges in * the cut. This argument is ignored if it is a null pointer. * To free all memory allocated for \c cuts, you need call * \ref igraph_vector_destroy() and then \ref igraph_free() on * each element, before destroying the pointer vector itself. * \param partition1s An initialized pointer vector, the list of * vertex sets, generating the actual edge cuts, are stored * here. Each vector contains a set of vertex ids. If X is such * a set, then all edges going from X to the complement of X * form an (s,t) edge-cut in the graph. This argument is * ignored if it is a null pointer. * \param source The id of the source vertex. * \param target The id of the target vertex. * \param capacity Vector of edge capacities. All capacities must be * strictly positive. If this is a null pointer, then all edges * are assumed to have capacity one. * \return Error code. * * Time complexity: O(n(|V|+|E|))+O(F), where |V| is the number of * vertices, |E| is the number of edges, and n is the number of cuts; * O(F) is the time complexity of the maximum flow algorithm, see \ref * igraph_maxflow(). * * \example examples/simple/igraph_all_st_mincuts.c */ int igraph_all_st_mincuts(const igraph_t *graph, igraph_real_t *value, igraph_vector_ptr_t *cuts, igraph_vector_ptr_t *partition1s, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vector_t flow; igraph_t residual; igraph_vector_t NtoL; long int newsource, newtarget; igraph_marked_queue_t S; igraph_estack_t T; igraph_i_all_st_mincuts_data_t pivot_data; igraph_vector_bool_t VE1bool; igraph_vector_t VE1; long int VE1size = 0; long int i, nocuts; igraph_integer_t proj_nodes; igraph_vector_t revmap_ptr, revmap_next; igraph_vector_ptr_t closedsets; igraph_vector_ptr_t *mypartition1s = partition1s, vpartition1s; igraph_maxflow_stats_t stats; /* -------------------------------------------------------------------- */ /* Error checks */ if (!igraph_is_directed(graph)) { IGRAPH_ERROR("S-t cuts can only be listed in directed graphs", IGRAPH_UNIMPLEMENTED); } if (source < 0 || source >= no_of_nodes) { IGRAPH_ERROR("Invalid `source' vertex", IGRAPH_EINVAL); } if (target < 0 || target >= no_of_nodes) { IGRAPH_ERROR("Invalid `target' vertex", IGRAPH_EINVAL); } if (source == target) { IGRAPH_ERROR("`source' and 'target' are the same vertex", IGRAPH_EINVAL); } if (capacity != NULL && igraph_vector_min(capacity) <= 0) { IGRAPH_ERROR("Not all capacities are strictly positive.", IGRAPH_EINVAL); } if (!partition1s) { mypartition1s = &vpartition1s; IGRAPH_CHECK(igraph_vector_ptr_init(mypartition1s, 0)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, mypartition1s); } /* -------------------------------------------------------------------- */ /* We need to calculate the maximum flow first */ IGRAPH_VECTOR_INIT_FINALLY(&flow, 0); IGRAPH_CHECK(igraph_maxflow(graph, value, &flow, /*cut=*/ 0, /*partition1=*/ 0, /*partition2=*/ 0, /*source=*/ source, /*target=*/ target, capacity, &stats)); /* -------------------------------------------------------------------- */ /* Then we need the reverse residual graph */ IGRAPH_CHECK(igraph_reverse_residual_graph(graph, capacity, &residual, &flow)); IGRAPH_FINALLY(igraph_destroy, &residual); /* -------------------------------------------------------------------- */ /* We shrink it to its strongly connected components */ IGRAPH_VECTOR_INIT_FINALLY(&NtoL, 0); IGRAPH_CHECK(igraph_clusters(&residual, /*membership=*/ &NtoL, /*csize=*/ 0, /*no=*/ &proj_nodes, IGRAPH_STRONG)); IGRAPH_CHECK(igraph_contract_vertices(&residual, /*mapping=*/ &NtoL, /*vertex_comb=*/ 0)); IGRAPH_CHECK(igraph_simplify(&residual, /*multiple=*/ 1, /*loops=*/ 1, /*edge_comb=*/ 0)); newsource = (long int) VECTOR(NtoL)[(long int)source]; newtarget = (long int) VECTOR(NtoL)[(long int)target]; /* TODO: handle the newsource == newtarget case */ /* -------------------------------------------------------------------- */ /* Determine the active vertices in the projection */ IGRAPH_VECTOR_INIT_FINALLY(&VE1, 0); IGRAPH_CHECK(igraph_vector_bool_init(&VE1bool, proj_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &VE1bool); for (i = 0; i < no_of_edges; i++) { if (VECTOR(flow)[i] > 0) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); long int pfrom = (long int) VECTOR(NtoL)[from]; long int pto = (long int) VECTOR(NtoL)[to]; if (!VECTOR(VE1bool)[pfrom]) { VECTOR(VE1bool)[pfrom] = 1; VE1size++; } if (!VECTOR(VE1bool)[pto]) { VECTOR(VE1bool)[pto] = 1; VE1size++; } } } IGRAPH_CHECK(igraph_vector_reserve(&VE1, VE1size)); for (i = 0; i < proj_nodes; i++) { if (VECTOR(VE1bool)[i]) { igraph_vector_push_back(&VE1, i); } } if (cuts) { igraph_vector_ptr_clear(cuts); } if (partition1s) { igraph_vector_ptr_clear(partition1s); } /* -------------------------------------------------------------------- */ /* Everything is ready, list the cuts, using the right PIVOT function */ IGRAPH_CHECK(igraph_marked_queue_init(&S, no_of_nodes)); IGRAPH_FINALLY(igraph_marked_queue_destroy, &S); IGRAPH_CHECK(igraph_estack_init(&T, no_of_nodes, 0)); IGRAPH_FINALLY(igraph_estack_destroy, &T); pivot_data.active = &VE1bool; IGRAPH_CHECK(igraph_vector_ptr_init(&closedsets, 0)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &closedsets); /* TODO */ IGRAPH_CHECK(igraph_provan_shier_list(&residual, &S, &T, newsource, newtarget, &closedsets, igraph_i_all_st_mincuts_pivot, &pivot_data)); /* Convert the closed sets in the contracted graphs to cutsets in the original graph */ IGRAPH_VECTOR_INIT_FINALLY(&revmap_ptr, igraph_vcount(&residual)); IGRAPH_VECTOR_INIT_FINALLY(&revmap_next, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { long int id = (long int) VECTOR(NtoL)[i]; VECTOR(revmap_next)[i] = VECTOR(revmap_ptr)[id]; VECTOR(revmap_ptr)[id] = i + 1; } /* Create partitions in original graph */ nocuts = igraph_vector_ptr_size(&closedsets); igraph_vector_ptr_clear(mypartition1s); IGRAPH_CHECK(igraph_vector_ptr_reserve(mypartition1s, nocuts)); for (i = 0; i < nocuts; i++) { igraph_vector_t *supercut = VECTOR(closedsets)[i]; long int j, supercutsize = igraph_vector_size(supercut); igraph_vector_t *cut = IGRAPH_CALLOC(1, igraph_vector_t); IGRAPH_VECTOR_INIT_FINALLY(cut, 0); /* TODO: better allocation */ for (j = 0; j < supercutsize; j++) { long int vtx = (long int) VECTOR(*supercut)[j]; long int ovtx = (long int) VECTOR(revmap_ptr)[vtx]; while (ovtx != 0) { ovtx--; IGRAPH_CHECK(igraph_vector_push_back(cut, ovtx)); ovtx = (long int) VECTOR(revmap_next)[ovtx]; } } igraph_vector_ptr_push_back(mypartition1s, cut); IGRAPH_FINALLY_CLEAN(1); igraph_vector_destroy(supercut); igraph_free(supercut); VECTOR(closedsets)[i] = 0; } igraph_vector_destroy(&revmap_next); igraph_vector_destroy(&revmap_ptr); igraph_vector_ptr_destroy(&closedsets); IGRAPH_FINALLY_CLEAN(3); /* Create cuts in original graph */ if (cuts) { igraph_vector_long_t memb; IGRAPH_CHECK(igraph_vector_long_init(&memb, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &memb); IGRAPH_CHECK(igraph_vector_ptr_resize(cuts, nocuts)); for (i = 0; i < nocuts; i++) { igraph_vector_t *part = VECTOR(*mypartition1s)[i]; long int j, n = igraph_vector_size(part); igraph_vector_t *v; v = IGRAPH_CALLOC(1, igraph_vector_t); if (!v) { IGRAPH_ERROR("Cannot list minimum s-t cuts", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(v, 0); for (j = 0; j < n; j++) { long int vtx = (long int) VECTOR(*part)[j]; VECTOR(memb)[vtx] = i + 1; } for (j = 0; j < no_of_edges; j++) { if (VECTOR(flow)[j] > 0) { long int from = IGRAPH_FROM(graph, j); long int to = IGRAPH_TO(graph, j); if (VECTOR(memb)[from] == i + 1 && VECTOR(memb)[to] != i + 1) { IGRAPH_CHECK(igraph_vector_push_back(v, j)); /* TODO: allocation */ } } } VECTOR(*cuts)[i] = v; IGRAPH_FINALLY_CLEAN(1); } igraph_vector_long_destroy(&memb); IGRAPH_FINALLY_CLEAN(1); } igraph_estack_destroy(&T); igraph_marked_queue_destroy(&S); igraph_vector_bool_destroy(&VE1bool); igraph_vector_destroy(&VE1); igraph_vector_destroy(&NtoL); igraph_destroy(&residual); igraph_vector_destroy(&flow); IGRAPH_FINALLY_CLEAN(7); if (!partition1s) { for (i = 0; i < nocuts; i++) { igraph_vector_t *cut = VECTOR(*mypartition1s)[i]; igraph_vector_destroy(cut); igraph_free(cut); VECTOR(*mypartition1s)[i] = 0; } igraph_vector_ptr_destroy(mypartition1s); IGRAPH_FINALLY_CLEAN(1); } return 0; } leidenbase/src/core/flow/flow.c0000644000176200001440000030217314447675374016201 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_flow.h" #include "igraph_adjlist.h" #include "igraph_components.h" #include "igraph_conversion.h" #include "igraph_constants.h" #include "igraph_constructors.h" #include "igraph_dqueue.h" #include "igraph_error.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_progress.h" #include "igraph_operators.h" #include "igraph_structural.h" #include "igraph_topology.h" #include "core/buckets.h" #include "core/cutheap.h" #include "core/interruption.h" #include "core/math.h" #include "config.h" /* * Some general remarks about the functions in this file. * * The following measures can be calculated: * ( 1) s-t maximum flow value, directed graph * ( 2) s-t maximum flow value, undirected graph * ( 3) s-t maximum flow, directed graph * ( 4) s-t maximum flow, undirected graph * ( 5) s-t minimum cut value, directed graph * ( 6) s-t minimum cut value, undirected graph * ( 7) minimum cut value, directed graph * ( 8) minimum cut value, undirected graph * ( 9) s-t minimum cut, directed graph * (10) s-t minimum cut, undirected graph * (11) minimum cut, directed graph * (12) minimum cut, undirected graph * (13) s-t edge connectivity, directed graph * (14) s-t edge connectivity, undirected graph * (15) edge connectivity, directed graph * (16) edge connectivity, undirected graph * (17) s-t vertex connectivity, directed graph * (18) s-t vertex connectivity, undirected graph * (19) vertex connectivity, directed graph * (20) vertex connectivity, undirected graph * (21) s-t number of edge disjoint paths, directed graph * (22) s-t number of edge disjoint paths, undirected graph * (23) s-t number of vertex disjoint paths, directed graph * (24) s-t number of vertex disjoint paths, undirected graph * (25) graph adhesion, directed graph * (26) graph adhesion, undirected graph * (27) graph cohesion, directed graph * (28) graph cohesion, undirected graph * * This is how they are calculated: * ( 1) igraph_maxflow_value, calls igraph_maxflow. * ( 2) igraph_maxflow_value, calls igraph_maxflow, this calls * igraph_i_maxflow_undirected. This transforms the graph into a * directed graph, including two mutual edges instead of every * undirected edge, then igraph_maxflow is called again with the * directed graph. * ( 3) igraph_maxflow, does the push-relabel algorithm, optionally * calculates the cut, the partitions and the flow itself. * ( 4) igraph_maxflow calls igraph_i_maxflow_undirected, this converts * the undirected graph into a directed one, adding two mutual edges * for each undirected edge, then igraph_maxflow is called again, * with the directed graph. After igraph_maxflow returns, we need * to edit the flow (and the cut) to make it sense for the * original graph. * ( 5) igraph_st_mincut_value, we just call igraph_maxflow_value * ( 6) igraph_st_mincut_value, we just call igraph_maxflow_value * ( 7) igraph_mincut_value, we call igraph_maxflow_value (|V|-1)*2 * times, from vertex 0 to all other vertices and from all other * vertices to vertex 0 * ( 8) We call igraph_i_mincut_value_undirected, that calls * igraph_i_mincut_undirected with partition=partition2=cut=NULL * The Stoer-Wagner algorithm is used. * ( 9) igraph_st_mincut, just calls igraph_maxflow. * (10) igraph_st_mincut, just calls igraph_maxflow. * (11) igraph_mincut, calls igraph_i_mincut_directed, which runs * the maximum flow algorithm 2(|V|-1) times, from vertex zero to * and from all other vertices and stores the smallest cut. * (12) igraph_mincut, igraph_i_mincut_undirected is called, * this is the Stoer-Wagner algorithm * (13) We just call igraph_maxflow_value, back to (1) * (14) We just call igraph_maxflow_value, back to (2) * (15) We just call igraph_mincut_value (possibly after some basic * checks). Back to (7) * (16) We just call igraph_mincut_value (possibly after some basic * checks). Back to (8). * (17) We call igraph_i_st_vertex_connectivity_directed. * That creates a new graph with 2*|V| vertices and smartly chosen * edges, so that the s-t edge connectivity of this graph is the * same as the s-t vertex connectivity of the original graph. * So finally it calls igraph_maxflow_value, go to (1) * (18) We call igraph_i_st_vertex_connectivity_undirected. * We convert the graph to a directed one, * IGRAPH_TO_DIRECTED_MUTUAL method. Then we call * igraph_i_st_vertex_connectivity_directed, see (17). * (19) We call igraph_i_vertex_connectivity_directed. * That calls igraph_st_vertex_connectivity for all pairs of * vertices. Back to (17). * (20) We call igraph_i_vertex_connectivity_undirected. * That converts the graph into a directed one * (IGRAPH_TO_DIRECTED_MUTUAL) and calls the directed version, * igraph_i_vertex_connectivity_directed, see (19). * (21) igraph_edge_disjoint_paths, we just call igraph_maxflow_value, (1). * (22) igraph_edge_disjoint_paths, we just call igraph_maxflow_value, (2). * (23) igraph_vertex_disjoint_paths, if there is a connection between * the two vertices, then we remove that (or all of them if there * are many), as this could mess up vertex connectivity * calculation. The we call * igraph_i_st_vertex_connectivity_directed, see (19). * (24) igraph_vertex_disjoint_paths, if there is a connection between * the two vertices, then we remove that (or all of them if there * are many), as this could mess up vertex connectivity * calculation. The we call * igraph_i_st_vertex_connectivity_undirected, see (20). * (25) We just call igraph_edge_connectivity, see (15). * (26) We just call igraph_edge_connectivity, see (16). * (27) We just call igraph_vertex_connectivity, see (19). * (28) We just call igraph_vertex_connectivity, see (20). */ /* * This is an internal function that calculates the maximum flow value * on undirected graphs, either for an s-t vertex pair or for the * graph (i.e. all vertex pairs). * * It does it by converting the undirected graph to a corresponding * directed graph, including reciprocal directed edges instead of each * undirected edge. */ static int igraph_i_maxflow_undirected(const igraph_t *graph, igraph_real_t *value, igraph_vector_t *flow, igraph_vector_t *cut, igraph_vector_t *partition, igraph_vector_t *partition2, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity, igraph_maxflow_stats_t *stats) { igraph_integer_t no_of_edges = (igraph_integer_t) igraph_ecount(graph); igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph); igraph_vector_t edges; igraph_vector_t newcapacity; igraph_t newgraph; long int i; /* We need to convert this to directed by hand, since we need to be sure that the edge ids will be handled properly to build the new capacity vector. */ IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&newcapacity, no_of_edges * 2); IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 4)); IGRAPH_CHECK(igraph_get_edgelist(graph, &edges, 0)); IGRAPH_CHECK(igraph_vector_resize(&edges, no_of_edges * 4)); for (i = 0; i < no_of_edges; i++) { VECTOR(edges)[no_of_edges * 2 + i * 2] = VECTOR(edges)[i * 2 + 1]; VECTOR(edges)[no_of_edges * 2 + i * 2 + 1] = VECTOR(edges)[i * 2]; VECTOR(newcapacity)[i] = VECTOR(newcapacity)[no_of_edges + i] = capacity ? VECTOR(*capacity)[i] : 1.0; } IGRAPH_CHECK(igraph_create(&newgraph, &edges, no_of_nodes, IGRAPH_DIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); IGRAPH_CHECK(igraph_maxflow(&newgraph, value, flow, cut, partition, partition2, source, target, &newcapacity, stats)); if (cut) { long int i, cs = igraph_vector_size(cut); for (i = 0; i < cs; i++) { if (VECTOR(*cut)[i] >= no_of_edges) { VECTOR(*cut)[i] -= no_of_edges; } } } /* The flow has one non-zero value for each real-nonreal edge pair, by definition, we convert it to a positive-negative vector. If for an edge the flow is negative that means that it is going from the bigger vertex id to the smaller one. For positive values the direction is the opposite. */ if (flow) { long int i; for (i = 0; i < no_of_edges; i++) { VECTOR(*flow)[i] -= VECTOR(*flow)[i + no_of_edges]; } IGRAPH_CHECK(igraph_vector_resize(flow, no_of_edges)); } igraph_destroy(&newgraph); igraph_vector_destroy(&edges); igraph_vector_destroy(&newcapacity); IGRAPH_FINALLY_CLEAN(3); return 0; } #define FIRST(i) (VECTOR(*first)[(i)]) #define LAST(i) (VECTOR(*first)[(i)+1]) #define CURRENT(i) (VECTOR(*current)[(i)]) #define RESCAP(i) (VECTOR(*rescap)[(i)]) #define REV(i) (VECTOR(*rev)[(i)]) #define HEAD(i) (VECTOR(*to)[(i)]) #define EXCESS(i) (VECTOR(*excess)[(i)]) #define DIST(i) (VECTOR(*distance)[(i)]) #define DISCHARGE(v) (igraph_i_mf_discharge((v), ¤t, &first, &rescap, \ &to, &distance, &excess, \ no_of_nodes, source, target, \ &buckets, &ibuckets, \ &rev, stats, &npushsince, \ &nrelabelsince)) #define PUSH(v,e,n) (igraph_i_mf_push((v), (e), (n), current, rescap, \ excess, target, source, buckets, \ ibuckets, distance, rev, stats, \ npushsince)) #define RELABEL(v) (igraph_i_mf_relabel((v), no_of_nodes, distance, \ first, rescap, to, current, \ stats, nrelabelsince)) #define GAP(b) (igraph_i_mf_gap((b), stats, buckets, ibuckets, \ no_of_nodes, distance)) #define BFS() (igraph_i_mf_bfs(&bfsq, source, target, no_of_nodes, \ &buckets, &ibuckets, &distance, \ &first, ¤t, &to, &excess, \ &rescap, &rev)) static void igraph_i_mf_gap(long int b, igraph_maxflow_stats_t *stats, igraph_buckets_t *buckets, igraph_dbuckets_t *ibuckets, long int no_of_nodes, igraph_vector_long_t *distance) { IGRAPH_UNUSED(buckets); long int bo; (stats->nogap)++; for (bo = b + 1; bo <= no_of_nodes; bo++) { while (!igraph_dbuckets_empty_bucket(ibuckets, bo)) { long int n = igraph_dbuckets_pop(ibuckets, bo); (stats->nogapnodes)++; DIST(n) = no_of_nodes; } } } static void igraph_i_mf_relabel(long int v, long int no_of_nodes, igraph_vector_long_t *distance, igraph_vector_long_t *first, igraph_vector_t *rescap, igraph_vector_long_t *to, igraph_vector_long_t *current, igraph_maxflow_stats_t *stats, int *nrelabelsince) { long int min = no_of_nodes; long int k, l, min_edge = 0; (stats->norelabel)++; (*nrelabelsince)++; DIST(v) = no_of_nodes; for (k = FIRST(v), l = LAST(v); k < l; k++) { if (RESCAP(k) > 0 && DIST(HEAD(k)) < min) { min = DIST(HEAD(k)); min_edge = k; } } min++; if (min < no_of_nodes) { DIST(v) = min; CURRENT(v) = min_edge; } } static void igraph_i_mf_push(long int v, long int e, long int n, igraph_vector_long_t *current, igraph_vector_t *rescap, igraph_vector_t *excess, long int target, long int source, igraph_buckets_t *buckets, igraph_dbuckets_t *ibuckets, igraph_vector_long_t *distance, igraph_vector_long_t *rev, igraph_maxflow_stats_t *stats, int *npushsince) { IGRAPH_UNUSED(current); IGRAPH_UNUSED(source); igraph_real_t delta = RESCAP(e) < EXCESS(v) ? RESCAP(e) : EXCESS(v); (stats->nopush)++; (*npushsince)++; if (EXCESS(n) == 0 && n != target) { igraph_dbuckets_delete(ibuckets, DIST(n), n); igraph_buckets_add(buckets, (long int) DIST(n), n); } RESCAP(e) -= delta; RESCAP(REV(e)) += delta; EXCESS(n) += delta; EXCESS(v) -= delta; } static void igraph_i_mf_discharge(long int v, igraph_vector_long_t *current, igraph_vector_long_t *first, igraph_vector_t *rescap, igraph_vector_long_t *to, igraph_vector_long_t *distance, igraph_vector_t *excess, long int no_of_nodes, long int source, long int target, igraph_buckets_t *buckets, igraph_dbuckets_t *ibuckets, igraph_vector_long_t *rev, igraph_maxflow_stats_t *stats, int *npushsince, int *nrelabelsince) { do { long int i; long int start = (long int) CURRENT(v); long int stop = (long int) LAST(v); for (i = start; i < stop; i++) { if (RESCAP(i) > 0) { long int nei = HEAD(i); if (DIST(v) == DIST(nei) + 1) { PUSH((v), i, nei); if (EXCESS(v) == 0) { break; } } } } if (i == stop) { long int origdist = DIST(v); RELABEL(v); if (igraph_buckets_empty_bucket(buckets, origdist) && igraph_dbuckets_empty_bucket(ibuckets, origdist)) { GAP(origdist); } if (DIST(v) == no_of_nodes) { break; } } else { CURRENT(v) = i; igraph_dbuckets_add(ibuckets, DIST(v), v); break; } } while (1); } static void igraph_i_mf_bfs(igraph_dqueue_long_t *bfsq, long int source, long int target, long int no_of_nodes, igraph_buckets_t *buckets, igraph_dbuckets_t *ibuckets, igraph_vector_long_t *distance, igraph_vector_long_t *first, igraph_vector_long_t *current, igraph_vector_long_t *to, igraph_vector_t *excess, igraph_vector_t *rescap, igraph_vector_long_t *rev) { long int k, l; IGRAPH_UNUSED(source); igraph_buckets_clear(buckets); igraph_dbuckets_clear(ibuckets); igraph_vector_long_fill(distance, no_of_nodes); DIST(target) = 0; igraph_dqueue_long_push(bfsq, target); while (!igraph_dqueue_long_empty(bfsq)) { long int node = igraph_dqueue_long_pop(bfsq); long int ndist = DIST(node) + 1; for (k = FIRST(node), l = LAST(node); k < l; k++) { if (RESCAP(REV(k)) > 0) { long int nei = HEAD(k); if (DIST(nei) == no_of_nodes) { DIST(nei) = ndist; CURRENT(nei) = FIRST(nei); if (EXCESS(nei) > 0) { igraph_buckets_add(buckets, ndist, nei); } else { igraph_dbuckets_add(ibuckets, ndist, nei); } igraph_dqueue_long_push(bfsq, nei); } } } } } /** * \function igraph_maxflow * Maximum network flow between a pair of vertices * * This function implements the Goldberg-Tarjan algorithm for * calculating value of the maximum flow in a directed or undirected * graph. The algorithm was given in Andrew V. Goldberg, Robert * E. Tarjan: A New Approach to the Maximum-Flow Problem, Journal of * the ACM, 35(4), 921-940, 1988. * * The input of the function is a graph, a vector * of real numbers giving the capacity of the edges and two vertices * of the graph, the source and the target. A flow is a function * assigning positive real numbers to the edges and satisfying two * requirements: (1) the flow value is less than the capacity of the * edge and (2) at each vertex except the source and the target, the * incoming flow (i.e. the sum of the flow on the incoming edges) is * the same as the outgoing flow (i.e. the sum of the flow on the * outgoing edges). The value of the flow is the incoming flow at the * target vertex. The maximum flow is the flow with the maximum * value. * * \param graph The input graph, either directed or undirected. * \param value Pointer to a real number, the value of the maximum * will be placed here, unless it is a null pointer. * \param flow If not a null pointer, then it must be a pointer to an * initialized vector. The vector will be resized, and the flow * on each edge will be placed in it, in the order of the edge * ids. For undirected graphs this argument is bit trickier, * since for these the flow direction is not predetermined by * the edge direction. For these graphs the elements of the * \p flow vector can be negative, this means that the flow * goes from the bigger vertex id to the smaller one. Positive * values mean that the flow goes from the smaller vertex id to * the bigger one. * \param cut A null pointer or a pointer to an initialized vector. * If not a null pointer, then the minimum cut corresponding to * the maximum flow is stored here, i.e. all edge ids that are * part of the minimum cut are stored in the vector. * \param partition A null pointer or a pointer to an initialized * vector. If not a null pointer, then the first partition of * the minimum cut that corresponds to the maximum flow will be * placed here. The first partition is always the one that * contains the source vertex. * \param partition2 A null pointer or a pointer to an initialized * vector. If not a null pointer, then the second partition of * the minimum cut that corresponds to the maximum flow will be * placed here. The second partition is always the one that * contains the target vertex. * \param source The id of the source vertex. * \param target The id of the target vertex. * \param capacity Vector containing the capacity of the edges. If NULL, then * every edge is considered to have capacity 1.0. * \param stats Counts of the number of different operations * preformed by the algorithm are stored here. * \return Error code. * * Time complexity: O(|V|^3). In practice it is much faster, but i * cannot prove a better lower bound for the data structure i've * used. In fact, this implementation runs much faster than the * \c hi_pr implementation discussed in * B. V. Cherkassky and A. V. Goldberg: On implementing the * push-relabel method for the maximum flow problem, (Algorithmica, * 19:390--410, 1997) on all the graph classes i've tried. * * \sa \ref igraph_mincut_value(), \ref igraph_edge_connectivity(), * \ref igraph_vertex_connectivity() for * properties based on the maximum flow. * * \example examples/simple/flow.c * \example examples/simple/flow2.c */ int igraph_maxflow(const igraph_t *graph, igraph_real_t *value, igraph_vector_t *flow, igraph_vector_t *cut, igraph_vector_t *partition, igraph_vector_t *partition2, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity, igraph_maxflow_stats_t *stats) { igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph); igraph_integer_t no_of_orig_edges = (igraph_integer_t) igraph_ecount(graph); igraph_integer_t no_of_edges = 2 * no_of_orig_edges; igraph_vector_t rescap, excess; igraph_vector_long_t from, to, rev, distance; igraph_vector_t edges, rank; igraph_vector_long_t current, first; igraph_buckets_t buckets; igraph_dbuckets_t ibuckets; igraph_dqueue_long_t bfsq; long int i, j, idx; int npushsince = 0, nrelabelsince = 0; igraph_maxflow_stats_t local_stats; /* used if the user passed a null pointer for stats */ if (stats == 0) { stats = &local_stats; } if (!igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_maxflow_undirected(graph, value, flow, cut, partition, partition2, source, target, capacity, stats)); return 0; } if (capacity && igraph_vector_size(capacity) != no_of_orig_edges) { IGRAPH_ERROR("Invalid capacity vector", IGRAPH_EINVAL); } if (source < 0 || source >= no_of_nodes || target < 0 || target >= no_of_nodes) { IGRAPH_ERROR("Invalid source or target vertex", IGRAPH_EINVAL); } stats->nopush = stats->norelabel = stats->nogap = stats->nogapnodes = stats->nobfs = 0; /* * The data structure: * - First of all, we consider every edge twice, first the edge * itself, but also its opposite. * - (from, to) contain all edges (original + opposite), ordered by * the id of the source vertex. During the algorithm we just need * 'to', so from is destroyed soon. We only need it in the * beginning, to create the 'first' pointers. * - 'first' is a pointer vector for 'to', first[i] points to the * first neighbor of vertex i and first[i+1]-1 is the last * neighbor of vertex i. (Unless vertex i is isolate, in which * case first[i]==first[i+1]). * - 'rev' contains a mapping from an edge to its opposite pair * - 'rescap' contains the residual capacities of the edges, this is * initially equal to the capacity of the edges for the original * edges and it is zero for the opposite edges. * - 'excess' contains the excess flow for the vertices. I.e. the flow * that is coming in, but it is not going out. * - 'current' stores the next neighboring vertex to check, for every * vertex, when excess flow is being pushed to neighbors. * - 'distance' stores the distance of the vertices from the source. * - 'rank' and 'edges' are only needed temporarily, for ordering and * storing the edges. * - we use an igraph_buckets_t data structure ('buckets') to find * the vertices with the highest 'distance' values quickly. * This always contains the vertices that have a positive excess * flow. */ #undef FIRST #undef LAST #undef CURRENT #undef RESCAP #undef REV #undef HEAD #undef EXCESS #undef DIST #define FIRST(i) (VECTOR(first)[(i)]) #define LAST(i) (VECTOR(first)[(i)+1]) #define CURRENT(i) (VECTOR(current)[(i)]) #define RESCAP(i) (VECTOR(rescap)[(i)]) #define REV(i) (VECTOR(rev)[(i)]) #define HEAD(i) (VECTOR(to)[(i)]) #define EXCESS(i) (VECTOR(excess)[(i)]) #define DIST(i) (VECTOR(distance)[(i)]) igraph_dqueue_long_init(&bfsq, no_of_nodes); IGRAPH_FINALLY(igraph_dqueue_long_destroy, &bfsq); IGRAPH_VECTOR_LONG_INIT_FINALLY(&to, no_of_edges); IGRAPH_VECTOR_LONG_INIT_FINALLY(&rev, no_of_edges); IGRAPH_VECTOR_INIT_FINALLY(&rescap, no_of_edges); IGRAPH_VECTOR_INIT_FINALLY(&excess, no_of_nodes); IGRAPH_VECTOR_LONG_INIT_FINALLY(&distance, no_of_nodes); IGRAPH_VECTOR_LONG_INIT_FINALLY(&first, no_of_nodes + 1); IGRAPH_VECTOR_INIT_FINALLY(&rank, no_of_edges); IGRAPH_VECTOR_LONG_INIT_FINALLY(&from, no_of_edges); IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges); /* Create the basic data structure */ IGRAPH_CHECK(igraph_get_edgelist(graph, &edges, 0)); IGRAPH_CHECK(igraph_vector_rank(&edges, &rank, no_of_nodes)); for (i = 0; i < no_of_edges; i += 2) { long int pos = (long int) VECTOR(rank)[i]; long int pos2 = (long int) VECTOR(rank)[i + 1]; VECTOR(from)[pos] = VECTOR(edges)[i]; VECTOR(to)[pos] = VECTOR(edges)[i + 1]; VECTOR(from)[pos2] = VECTOR(edges)[i + 1]; VECTOR(to)[pos2] = VECTOR(edges)[i]; VECTOR(rev)[pos] = pos2; VECTOR(rev)[pos2] = pos; VECTOR(rescap)[pos] = capacity ? VECTOR(*capacity)[i / 2] : 1.0; VECTOR(rescap)[pos2] = 0.0; } /* The first pointers. This is a but trickier, than one would think, because of the possible isolate vertices. */ idx = -1; for (i = 0; i <= VECTOR(from)[0]; i++) { idx++; VECTOR(first)[idx] = 0; } for (i = 1; i < no_of_edges; i++) { long int n = (long int) (VECTOR(from)[i] - VECTOR(from)[ (long int) VECTOR(first)[idx] ]); for (j = 0; j < n; j++) { idx++; VECTOR(first)[idx] = i; } } idx++; while (idx < no_of_nodes + 1) { VECTOR(first)[idx++] = no_of_edges; } igraph_vector_long_destroy(&from); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(2); if (!flow) { igraph_vector_destroy(&rank); IGRAPH_FINALLY_CLEAN(1); } /* And the current pointers, initially the same as the first */ IGRAPH_VECTOR_LONG_INIT_FINALLY(¤t, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { VECTOR(current)[i] = VECTOR(first)[i]; } /* OK, the graph is set up, initialization */ IGRAPH_CHECK(igraph_buckets_init(&buckets, no_of_nodes + 1, no_of_nodes)); IGRAPH_FINALLY(igraph_buckets_destroy, &buckets); IGRAPH_CHECK(igraph_dbuckets_init(&ibuckets, no_of_nodes + 1, no_of_nodes)); IGRAPH_FINALLY(igraph_dbuckets_destroy, &ibuckets); /* Send as much flow as possible from the source to its neighbors */ for (i = FIRST(source), j = LAST(source); i < j; i++) { if (HEAD(i) != source) { igraph_real_t delta = RESCAP(i); RESCAP(i) = 0; RESCAP(REV(i)) += delta; EXCESS(HEAD(i)) += delta; } } BFS(); (stats->nobfs)++; while (!igraph_buckets_empty(&buckets)) { long int vertex = igraph_buckets_popmax(&buckets); DISCHARGE(vertex); if (npushsince > no_of_nodes / 2 && nrelabelsince > no_of_nodes) { (stats->nobfs)++; BFS(); npushsince = nrelabelsince = 0; } } /* Store the result */ if (value) { *value = EXCESS(target); } /* If we also need the minimum cut */ if (cut || partition || partition2) { /* We need to find all vertices from which the target is reachable in the residual graph. We do a breadth-first search, going backwards. */ igraph_dqueue_t Q; igraph_vector_bool_t added; long int marked = 0; IGRAPH_CHECK(igraph_vector_bool_init(&added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &added); IGRAPH_CHECK(igraph_dqueue_init(&Q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &Q); igraph_dqueue_push(&Q, target); VECTOR(added)[(long int)target] = 1; marked++; while (!igraph_dqueue_empty(&Q)) { long int actnode = (long int) igraph_dqueue_pop(&Q); for (i = FIRST(actnode), j = LAST(actnode); i < j; i++) { long int nei = HEAD(i); if (!VECTOR(added)[nei] && RESCAP(REV(i)) > 0.0) { VECTOR(added)[nei] = 1; marked++; IGRAPH_CHECK(igraph_dqueue_push(&Q, nei)); } } } igraph_dqueue_destroy(&Q); IGRAPH_FINALLY_CLEAN(1); /* Now we marked each vertex that is on one side of the cut, check the crossing edges */ if (cut) { igraph_vector_clear(cut); for (i = 0; i < no_of_orig_edges; i++) { long int f = IGRAPH_FROM(graph, i); long int t = IGRAPH_TO(graph, i); if (!VECTOR(added)[f] && VECTOR(added)[t]) { IGRAPH_CHECK(igraph_vector_push_back(cut, i)); } } } if (partition2) { long int x = 0; IGRAPH_CHECK(igraph_vector_resize(partition2, marked)); for (i = 0; i < no_of_nodes; i++) { if (VECTOR(added)[i]) { VECTOR(*partition2)[x++] = i; } } } if (partition) { long int x = 0; IGRAPH_CHECK(igraph_vector_resize(partition, no_of_nodes - marked)); for (i = 0; i < no_of_nodes; i++) { if (!VECTOR(added)[i]) { VECTOR(*partition)[x++] = i; } } } igraph_vector_bool_destroy(&added); IGRAPH_FINALLY_CLEAN(1); } if (flow) { /* Initialize the backward distances, with a breadth-first search from the source */ igraph_dqueue_t Q; igraph_vector_int_t added; long int j, k, l; igraph_t flow_graph; igraph_vector_t flow_edges; igraph_bool_t dag; IGRAPH_CHECK(igraph_vector_int_init(&added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &added); IGRAPH_CHECK(igraph_dqueue_init(&Q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &Q); igraph_dqueue_push(&Q, source); igraph_dqueue_push(&Q, 0); VECTOR(added)[(long int)source] = 1; while (!igraph_dqueue_empty(&Q)) { long int actnode = (long int) igraph_dqueue_pop(&Q); long int actdist = (long int) igraph_dqueue_pop(&Q); DIST(actnode) = actdist; for (i = FIRST(actnode), j = LAST(actnode); i < j; i++) { long int nei = HEAD(i); if (!VECTOR(added)[nei] && RESCAP(REV(i)) > 0.0) { VECTOR(added)[nei] = 1; IGRAPH_CHECK(igraph_dqueue_push(&Q, nei)); IGRAPH_CHECK(igraph_dqueue_push(&Q, actdist + 1)); } } } /* !igraph_dqueue_empty(&Q) */ igraph_vector_int_destroy(&added); igraph_dqueue_destroy(&Q); IGRAPH_FINALLY_CLEAN(2); /* Reinitialize the buckets */ igraph_buckets_clear(&buckets); for (i = 0; i < no_of_nodes; i++) { if (EXCESS(i) > 0.0 && i != source && i != target) { igraph_buckets_add(&buckets, (long int) DIST(i), i); } } /* Now we return the flow to the source */ while (!igraph_buckets_empty(&buckets)) { long int vertex = igraph_buckets_popmax(&buckets); /* DISCHARGE(vertex) comes here */ do { for (i = (long int) CURRENT(vertex), j = LAST(vertex); i < j; i++) { if (RESCAP(i) > 0) { long int nei = HEAD(i); if (DIST(vertex) == DIST(nei) + 1) { igraph_real_t delta = RESCAP(i) < EXCESS(vertex) ? RESCAP(i) : EXCESS(vertex); RESCAP(i) -= delta; RESCAP(REV(i)) += delta; if (nei != source && EXCESS(nei) == 0.0 && DIST(nei) != no_of_nodes) { igraph_buckets_add(&buckets, (long int) DIST(nei), nei); } EXCESS(nei) += delta; EXCESS(vertex) -= delta; if (EXCESS(vertex) == 0) { break; } } } } if (i == j) { /* RELABEL(vertex) comes here */ igraph_real_t min; long int min_edge = 0; DIST(vertex) = min = no_of_nodes; for (k = FIRST(vertex), l = LAST(vertex); k < l; k++) { if (RESCAP(k) > 0) { if (DIST(HEAD(k)) < min) { min = DIST(HEAD(k)); min_edge = k; } } } min++; if (min < no_of_nodes) { DIST(vertex) = min; CURRENT(vertex) = min_edge; /* Vertex is still active */ igraph_buckets_add(&buckets, (long int) DIST(vertex), vertex); } /* TODO: gap heuristics here ??? */ } else { CURRENT(vertex) = FIRST(vertex); } break; } while (1); } /* We need to eliminate flow cycles now. Before that we check that there is a cycle in the flow graph. First we do a couple of DFSes from the source vertex to the target and factor out the paths we find. If there is no more path to the target, then all remaining flow must be in flow cycles, so we don't need it at all. Some details. 'stack' contains the whole path of the DFS, both the vertices and the edges, they are alternating in the stack. 'current' helps finding the next outgoing edge of a vertex quickly, the next edge of 'v' is FIRST(v)+CURRENT(v). If this is LAST(v), then there are no more edges to try. The 'added' vector contains 0 if the vertex was not visited before, 1 if it is currently in 'stack', and 2 if it is not in 'stack', but it was visited before. */ IGRAPH_VECTOR_INIT_FINALLY(&flow_edges, 0); for (i = 0, j = 0; i < no_of_edges; i += 2, j++) { long int pos = (long int) VECTOR(rank)[i]; if ((capacity ? VECTOR(*capacity)[j] : 1.0) > RESCAP(pos)) { IGRAPH_CHECK(igraph_vector_push_back(&flow_edges, IGRAPH_FROM(graph, j))); IGRAPH_CHECK(igraph_vector_push_back(&flow_edges, IGRAPH_TO(graph, j))); } } IGRAPH_CHECK(igraph_create(&flow_graph, &flow_edges, no_of_nodes, IGRAPH_DIRECTED)); igraph_vector_destroy(&flow_edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &flow_graph); IGRAPH_CHECK(igraph_is_dag(&flow_graph, &dag)); igraph_destroy(&flow_graph); IGRAPH_FINALLY_CLEAN(1); if (!dag) { igraph_vector_long_t stack; igraph_vector_t mycap; IGRAPH_CHECK(igraph_vector_long_init(&stack, 0)); IGRAPH_FINALLY(igraph_vector_long_destroy, &stack); IGRAPH_CHECK(igraph_vector_int_init(&added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &added); IGRAPH_VECTOR_INIT_FINALLY(&mycap, no_of_edges); #define MYCAP(i) (VECTOR(mycap)[(i)]) for (i = 0; i < no_of_edges; i += 2) { long int pos = (long int) VECTOR(rank)[i]; long int pos2 = (long int) VECTOR(rank)[i + 1]; MYCAP(pos) = (capacity ? VECTOR(*capacity)[i / 2] : 1.0) - RESCAP(pos); MYCAP(pos2) = 0.0; } do { igraph_vector_long_null(¤t); igraph_vector_long_clear(&stack); igraph_vector_int_null(&added); IGRAPH_CHECK(igraph_vector_long_push_back(&stack, -1)); IGRAPH_CHECK(igraph_vector_long_push_back(&stack, source)); VECTOR(added)[(long int)source] = 1; while (!igraph_vector_long_empty(&stack) && igraph_vector_long_tail(&stack) != target) { long int actnode = igraph_vector_long_tail(&stack); long int edge = FIRST(actnode) + (long int) CURRENT(actnode); long int nei; while (edge < LAST(actnode) && MYCAP(edge) == 0.0) { edge++; } nei = edge < LAST(actnode) ? HEAD(edge) : -1; if (edge < LAST(actnode) && !VECTOR(added)[nei]) { /* Go forward along next edge, if the vertex was not visited before */ IGRAPH_CHECK(igraph_vector_long_push_back(&stack, edge)); IGRAPH_CHECK(igraph_vector_long_push_back(&stack, nei)); VECTOR(added)[nei] = 1; CURRENT(actnode) += 1; } else if (edge < LAST(actnode) && VECTOR(added)[nei] == 1) { /* We found a flow cycle, factor it out. Go back in stack until we find 'nei' again, determine the flow along the cycle. */ igraph_real_t thisflow = MYCAP(edge); long int idx; for (idx = igraph_vector_long_size(&stack) - 2; idx >= 0 && VECTOR(stack)[idx + 1] != nei; idx -= 2) { long int e = VECTOR(stack)[idx]; igraph_real_t rcap = e >= 0 ? MYCAP(e) : MYCAP(edge); if (rcap < thisflow) { thisflow = rcap; } } MYCAP(edge) -= thisflow; RESCAP(edge) += thisflow; for (idx = igraph_vector_long_size(&stack) - 2; idx >= 0 && VECTOR(stack)[idx + 1] != nei; idx -= 2) { long int e = VECTOR(stack)[idx]; if (e >= 0) { MYCAP(e) -= thisflow; RESCAP(e) += thisflow; } } CURRENT(actnode) += 1; } else if (edge < LAST(actnode)) { /* && VECTOR(added)[nei]==2 */ /* The next edge leads to a vertex that was visited before, but it is currently not in 'stack' */ CURRENT(actnode) += 1; } else { /* Go backward, take out the node and the edge that leads to it */ igraph_vector_long_pop_back(&stack); igraph_vector_long_pop_back(&stack); VECTOR(added)[actnode] = 2; } } /* If non-empty, then it contains a path from source to target in the residual graph. We factor out this path from the flow. */ if (!igraph_vector_long_empty(&stack)) { long int pl = igraph_vector_long_size(&stack); igraph_real_t thisflow = EXCESS(target); for (i = 2; i < pl; i += 2) { long int edge = VECTOR(stack)[i]; igraph_real_t rcap = MYCAP(edge); if (rcap < thisflow) { thisflow = rcap; } } for (i = 2; i < pl; i += 2) { long int edge = VECTOR(stack)[i]; MYCAP(edge) -= thisflow; } } } while (!igraph_vector_long_empty(&stack)); igraph_vector_destroy(&mycap); igraph_vector_int_destroy(&added); igraph_vector_long_destroy(&stack); IGRAPH_FINALLY_CLEAN(3); } /* ----------------------------------------------------------- */ IGRAPH_CHECK(igraph_vector_resize(flow, no_of_orig_edges)); for (i = 0, j = 0; i < no_of_edges; i += 2, j++) { long int pos = (long int) VECTOR(rank)[i]; VECTOR(*flow)[j] = (capacity ? VECTOR(*capacity)[j] : 1.0) - RESCAP(pos); } igraph_vector_destroy(&rank); IGRAPH_FINALLY_CLEAN(1); } igraph_dbuckets_destroy(&ibuckets); igraph_buckets_destroy(&buckets); igraph_vector_long_destroy(¤t); igraph_vector_long_destroy(&first); igraph_vector_long_destroy(&distance); igraph_vector_destroy(&excess); igraph_vector_destroy(&rescap); igraph_vector_long_destroy(&rev); igraph_vector_long_destroy(&to); igraph_dqueue_long_destroy(&bfsq); IGRAPH_FINALLY_CLEAN(10); return 0; } /** * \function igraph_maxflow_value * \brief Maximum flow in a network with the push/relabel algorithm * * This function implements the Goldberg-Tarjan algorithm for * calculating value of the maximum flow in a directed or undirected * graph. The algorithm was given in Andrew V. Goldberg, Robert * E. Tarjan: A New Approach to the Maximum-Flow Problem, Journal of * the ACM, 35(4), 921-940, 1988. * * The input of the function is a graph, a vector * of real numbers giving the capacity of the edges and two vertices * of the graph, the source and the target. A flow is a function * assigning positive real numbers to the edges and satisfying two * requirements: (1) the flow value is less than the capacity of the * edge and (2) at each vertex except the source and the target, the * incoming flow (i.e. the sum of the flow on the incoming edges) is * the same as the outgoing flow (i.e. the sum of the flow on the * outgoing edges). The value of the flow is the incoming flow at the * target vertex. The maximum flow is the flow with the maximum * value. * * According to a theorem by Ford and Fulkerson * (L. R. Ford Jr. and D. R. Fulkerson. Maximal flow through a * network. Canadian J. Math., 8:399-404, 1956.) the maximum flow * between two vertices is the same as the * minimum cut between them (also called the minimum s-t cut). So \ref * igraph_st_mincut_value() gives the same result in all cases as \c * igraph_maxflow_value(). * * Note that the value of the maximum flow is the same as the * minimum cut in the graph. * \param graph The input graph, either directed or undirected. * \param value Pointer to a real number, the result will be placed here. * \param source The id of the source vertex. * \param target The id of the target vertex. * \param capacity Vector containing the capacity of the edges. If NULL, then * every edge is considered to have capacity 1.0. * \param stats Counts of the number of different operations * preformed by the algorithm are stored here. * \return Error code. * * Time complexity: O(|V|^3). * * \sa \ref igraph_maxflow() to calculate the actual flow. * \ref igraph_mincut_value(), \ref igraph_edge_connectivity(), * \ref igraph_vertex_connectivity() for * properties based on the maximum flow. */ int igraph_maxflow_value(const igraph_t *graph, igraph_real_t *value, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity, igraph_maxflow_stats_t *stats) { return igraph_maxflow(graph, value, /*flow=*/ 0, /*cut=*/ 0, /*partition=*/ 0, /*partition1=*/ 0, source, target, capacity, stats); } /** * \function igraph_st_mincut_value * \brief The minimum s-t cut in a graph * * The minimum s-t cut in a weighted (=valued) graph is the * total minimum edge weight needed to remove from the graph to * eliminate all paths from a given vertex (\c source) to * another vertex (\c target). Directed paths are considered in * directed graphs, and undirected paths in undirected graphs. * * The minimum s-t cut between two vertices is known to be same * as the maximum flow between these two vertices. So this function * calls \ref igraph_maxflow_value() to do the calculation. * \param graph The input graph. * \param value Pointer to a real variable, the result will be stored * here. * \param source The id of the source vertex. * \param target The id of the target vertex. * \param capacity Pointer to the capacity vector, it should contain * non-negative numbers and its length should be the same the * the number of edges in the graph. It can be a null pointer, then * every edge has unit capacity. * \return Error code. * * Time complexity: O(|V|^3), see also the discussion for \ref * igraph_maxflow_value(), |V| is the number of vertices. */ int igraph_st_mincut_value(const igraph_t *graph, igraph_real_t *value, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity) { if (source == target) { IGRAPH_ERROR("source and target vertices are the same", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_maxflow_value(graph, value, source, target, capacity, 0)); return 0; } /** * \function igraph_st_mincut * Minimum cut between a source and a target vertex * * Finds the edge set that has the smallest total capacity among all * edge sets that disconnect the source and target vertices. * * The calculation is performed using maximum flow * techniques, by calling \ref igraph_maxflow(). * \param graph The input graph. * \param value Pointer to a real variable, the value of the cut is * stored here. * \param cut Pointer to a real vector, the edge ids that are included * in the cut are stored here. This argument is ignored if it * is a null pointer. * \param partition Pointer to a real vector, the vertex ids of the * vertices in the first partition of the cut are stored * here. The first partition is always the one that contains the * source vertex. This argument is ignored if it is a null pointer. * \param partition2 Pointer to a real vector, the vertex ids of the * vertices in the second partition of the cut are stored here. * The second partition is always the one that contains the * target vertex. This argument is ignored if it is a null pointer. * \param source Integer, the id of the source vertex. * \param target Integer, the id of the target vertex. * \param capacity Vector containing the capacity of the edges. If a * null pointer, then every edge is considered to have capacity * 1.0. * \return Error code. * * \sa \ref igraph_maxflow(). * * Time complexity: see \ref igraph_maxflow(). */ int igraph_st_mincut(const igraph_t *graph, igraph_real_t *value, igraph_vector_t *cut, igraph_vector_t *partition, igraph_vector_t *partition2, igraph_integer_t source, igraph_integer_t target, const igraph_vector_t *capacity) { return igraph_maxflow(graph, value, /*flow=*/ 0, cut, partition, partition2, source, target, capacity, 0); } /* This is a flow-based version, but there is a better one for undirected graphs */ /* int igraph_i_mincut_value_undirected(const igraph_t *graph, */ /* igraph_real_t *res, */ /* const igraph_vector_t *capacity) { */ /* long int no_of_edges=igraph_ecount(graph); */ /* long int no_of_nodes=igraph_vcount(graph); */ /* igraph_vector_t edges; */ /* igraph_vector_t newcapacity; */ /* igraph_t newgraph; */ /* long int i; */ /* /\* We need to convert this to directed by hand, since we need to be */ /* sure that the edge ids will be handled properly to build the new */ /* capacity vector. *\/ */ /* IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); */ /* IGRAPH_VECTOR_INIT_FINALLY(&newcapacity, no_of_edges*2); */ /* IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges*4)); */ /* IGRAPH_CHECK(igraph_get_edgelist(graph, &edges, 0)); */ /* IGRAPH_CHECK(igraph_vector_resize(&edges, no_of_edges*4)); */ /* for (i=0; i= 2) { long int last; igraph_real_t acut; long int a, n; igraph_vector_int_t *edges, *edges2; igraph_vector_int_t *neis, *neis2; do { a = igraph_i_cutheap_popmax(&heap); /* update the weights of the active vertices connected to a */ edges = igraph_inclist_get(&inclist, a); neis = igraph_adjlist_get(&adjlist, a); n = igraph_vector_int_size(edges); for (i = 0; i < n; i++) { igraph_integer_t edge = (igraph_integer_t) VECTOR(*edges)[i]; igraph_integer_t to = (igraph_integer_t) VECTOR(*neis)[i]; igraph_real_t weight = capacity ? VECTOR(*capacity)[(long int)edge] : 1.0; igraph_i_cutheap_update(&heap, to, weight); } } while (igraph_i_cutheap_active_size(&heap) > 1); /* Now, there is only one active vertex left, calculate the cut of the phase */ acut = igraph_i_cutheap_maxvalue(&heap); last = igraph_i_cutheap_popmax(&heap); if (acut < mincut) { mincut = acut; mincut_step = act_step; } if (mincut == 0) { break; } /* And contract the last and the remaining vertex (a and last) */ /* Before actually doing that, make some notes */ act_step++; if (calc_cut) { IGRAPH_CHECK(igraph_vector_push_back(&mergehist, a)); IGRAPH_CHECK(igraph_vector_push_back(&mergehist, last)); } /* First remove the a--last edge if there is one, a is still the last deactivated vertex */ edges = igraph_inclist_get(&inclist, a); neis = igraph_adjlist_get(&adjlist, a); n = igraph_vector_int_size(edges); for (i = 0; i < n; ) { if (VECTOR(*neis)[i] == last) { VECTOR(*neis)[i] = VECTOR(*neis)[n - 1]; VECTOR(*edges)[i] = VECTOR(*edges)[n - 1]; igraph_vector_int_pop_back(neis); igraph_vector_int_pop_back(edges); n--; } else { i++; } } edges = igraph_inclist_get(&inclist, last); neis = igraph_adjlist_get(&adjlist, last); n = igraph_vector_int_size(edges); for (i = 0; i < n; ) { if (VECTOR(*neis)[i] == a) { VECTOR(*neis)[i] = VECTOR(*neis)[n - 1]; VECTOR(*edges)[i] = VECTOR(*edges)[n - 1]; igraph_vector_int_pop_back(neis); igraph_vector_int_pop_back(edges); n--; } else { i++; } } /* Now rewrite the edge lists of last's neighbors */ neis = igraph_adjlist_get(&adjlist, last); n = igraph_vector_int_size(neis); for (i = 0; i < n; i++) { igraph_integer_t nei = (igraph_integer_t) VECTOR(*neis)[i]; long int n2, j; neis2 = igraph_adjlist_get(&adjlist, nei); n2 = igraph_vector_int_size(neis2); for (j = 0; j < n2; j++) { if (VECTOR(*neis2)[j] == last) { VECTOR(*neis2)[j] = a; } } } /* And append the lists of last to the lists of a */ edges = igraph_inclist_get(&inclist, a); neis = igraph_adjlist_get(&adjlist, a); edges2 = igraph_inclist_get(&inclist, last); neis2 = igraph_adjlist_get(&adjlist, last); IGRAPH_CHECK(igraph_vector_int_append(edges, edges2)); IGRAPH_CHECK(igraph_vector_int_append(neis, neis2)); igraph_vector_int_clear(edges2); /* TODO: free it */ igraph_vector_int_clear(neis2); /* TODO: free it */ /* Remove the deleted vertex from the heap entirely */ igraph_i_cutheap_reset_undefine(&heap, last); } *res = mincut; igraph_inclist_destroy(&inclist); igraph_adjlist_destroy(&adjlist); igraph_i_cutheap_destroy(&heap); IGRAPH_FINALLY_CLEAN(3); if (calc_cut) { long int bignode = (long int) VECTOR(mergehist)[2 * mincut_step + 1]; long int i, idx; long int size = 1; char *mark; mark = IGRAPH_CALLOC(no_of_nodes, char); if (!mark) { IGRAPH_ERROR("Not enough memory for minimum cut", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, mark); /* first count the vertices in the partition */ mark[bignode] = 1; for (i = mincut_step - 1; i >= 0; i--) { if ( mark[ (long int) VECTOR(mergehist)[2 * i] ] ) { size++; mark [ (long int) VECTOR(mergehist)[2 * i + 1] ] = 1; } } /* now store them, if requested */ if (partition) { IGRAPH_CHECK(igraph_vector_resize(partition, size)); idx = 0; VECTOR(*partition)[idx++] = bignode; for (i = mincut_step - 1; i >= 0; i--) { if (mark[ (long int) VECTOR(mergehist)[2 * i] ]) { VECTOR(*partition)[idx++] = VECTOR(mergehist)[2 * i + 1]; } } } /* The other partition too? */ if (partition2) { IGRAPH_CHECK(igraph_vector_resize(partition2, no_of_nodes - size)); idx = 0; for (i = 0; i < no_of_nodes; i++) { if (!mark[i]) { VECTOR(*partition2)[idx++] = i; } } } /* The edges in the cut are also requested? */ /* We want as few memory allocated for 'cut' as possible, so we first collect the edges in mergehist, we don't need that anymore. Then we copy it to 'cut'; */ if (cut) { igraph_integer_t from, to; igraph_vector_clear(&mergehist); for (i = 0; i < no_of_edges; i++) { igraph_edge(graph, (igraph_integer_t) i, &from, &to); if ((mark[(long int)from] && !mark[(long int)to]) || (mark[(long int)to] && !mark[(long int)from])) { IGRAPH_CHECK(igraph_vector_push_back(&mergehist, i)); } } igraph_vector_clear(cut); IGRAPH_CHECK(igraph_vector_append(cut, &mergehist)); } igraph_free(mark); igraph_vector_destroy(&mergehist); IGRAPH_FINALLY_CLEAN(2); } return 0; } static int igraph_i_mincut_directed(const igraph_t *graph, igraph_real_t *value, igraph_vector_t *partition, igraph_vector_t *partition2, igraph_vector_t *cut, const igraph_vector_t *capacity) { long int i; long int no_of_nodes = igraph_vcount(graph); igraph_real_t flow; igraph_real_t minmaxflow = IGRAPH_INFINITY; igraph_vector_t mypartition, mypartition2, mycut; igraph_vector_t *ppartition = 0, *ppartition2 = 0, *pcut = 0; igraph_vector_t bestpartition, bestpartition2, bestcut; if (partition) { IGRAPH_VECTOR_INIT_FINALLY(&bestpartition, 0); } if (partition2) { IGRAPH_VECTOR_INIT_FINALLY(&bestpartition2, 0); } if (cut) { IGRAPH_VECTOR_INIT_FINALLY(&bestcut, 0); } if (partition) { IGRAPH_VECTOR_INIT_FINALLY(&mypartition, 0); ppartition = &mypartition; } if (partition2) { IGRAPH_VECTOR_INIT_FINALLY(&mypartition2, 0); ppartition2 = &mypartition2; } if (cut) { IGRAPH_VECTOR_INIT_FINALLY(&mycut, 0); pcut = &mycut; } for (i = 1; i < no_of_nodes; i++) { IGRAPH_CHECK(igraph_maxflow(graph, /*value=*/ &flow, /*flow=*/ 0, pcut, ppartition, ppartition2, /*source=*/ 0, /*target=*/ (igraph_integer_t) i, capacity, 0)); if (flow < minmaxflow) { minmaxflow = flow; if (cut) { IGRAPH_CHECK(igraph_vector_update(&bestcut, &mycut)); } if (partition) { IGRAPH_CHECK(igraph_vector_update(&bestpartition, &mypartition)); } if (partition2) { IGRAPH_CHECK(igraph_vector_update(&bestpartition2, &mypartition2)); } if (minmaxflow == 0) { break; } } IGRAPH_CHECK(igraph_maxflow(graph, /*value=*/ &flow, /*flow=*/ 0, pcut, ppartition, ppartition2, /*source=*/ (igraph_integer_t) i, /*target=*/ 0, capacity, 0)); if (flow < minmaxflow) { minmaxflow = flow; if (cut) { IGRAPH_CHECK(igraph_vector_update(&bestcut, &mycut)); } if (partition) { IGRAPH_CHECK(igraph_vector_update(&bestpartition, &mypartition)); } if (partition2) { IGRAPH_CHECK(igraph_vector_update(&bestpartition2, &mypartition2)); } if (minmaxflow == 0) { break; } } } if (value) { *value = minmaxflow; } if (cut) { igraph_vector_destroy(&mycut); IGRAPH_FINALLY_CLEAN(1); } if (partition) { igraph_vector_destroy(&mypartition); IGRAPH_FINALLY_CLEAN(1); } if (partition2) { igraph_vector_destroy(&mypartition2); IGRAPH_FINALLY_CLEAN(1); } if (cut) { IGRAPH_CHECK(igraph_vector_update(cut, &bestcut)); igraph_vector_destroy(&bestcut); IGRAPH_FINALLY_CLEAN(1); } if (partition2) { IGRAPH_CHECK(igraph_vector_update(partition2, &bestpartition2)); igraph_vector_destroy(&bestpartition2); IGRAPH_FINALLY_CLEAN(1); } if (partition) { IGRAPH_CHECK(igraph_vector_update(partition, &bestpartition)); igraph_vector_destroy(&bestpartition); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_mincut * \brief Calculates the minimum cut in a graph. * * This function calculates the minimum cut in a graph. * The minimum cut is the minimum set of edges which needs to be * removed to disconnect the graph. The minimum is calculated using * the weights (\p capacity) of the edges, so the cut with the minimum * total capacity is calculated. * * For directed graphs an implementation based on * calculating 2|V|-2 maximum flows is used. * For undirected graphs we use the Stoer-Wagner * algorithm, as described in M. Stoer and F. Wagner: A simple min-cut * algorithm, Journal of the ACM, 44 585-591, 1997. * * * The first implementation of the actual cut calculation for * undirected graphs was made by Gregory Benison, thanks Greg. * \param graph The input graph. * \param value Pointer to a float, the value of the cut will be * stored here. * \param partition Pointer to an initialized vector, the ids * of the vertices in the first partition after separating the * graph will be stored here. The vector will be resized as * needed. This argument is ignored if it is a NULL pointer. * \param partition2 Pointer to an initialized vector the ids * of the vertices in the second partition will be stored here. * The vector will be resized as needed. This argument is ignored * if it is a NULL pointer. * \param cut Pointer to an initialized vector, the ids of the edges * in the cut will be stored here. This argument is ignored if it * is a NULL pointer. * \param capacity A numeric vector giving the capacities of the * edges. If a null pointer then all edges have unit capacity. * \return Error code. * * \sa \ref igraph_mincut_value(), a simpler interface for calculating * the value of the cut only. * * Time complexity: for directed graphs it is O(|V|^4), but see the * remarks at \ref igraph_maxflow(). For undirected graphs it is * O(|V||E|+|V|^2 log|V|). |V| and |E| are the number of vertices and * edges respectively. * * \example examples/simple/igraph_mincut.c */ int igraph_mincut(const igraph_t *graph, igraph_real_t *value, igraph_vector_t *partition, igraph_vector_t *partition2, igraph_vector_t *cut, const igraph_vector_t *capacity) { if (igraph_is_directed(graph)) { if (partition || partition2 || cut) { igraph_i_mincut_directed(graph, value, partition, partition2, cut, capacity); } else { return igraph_mincut_value(graph, value, capacity); } } else { IGRAPH_CHECK(igraph_i_mincut_undirected(graph, value, partition, partition2, cut, capacity)); return IGRAPH_SUCCESS; } return 0; } static int igraph_i_mincut_value_undirected(const igraph_t *graph, igraph_real_t *res, const igraph_vector_t *capacity) { return igraph_i_mincut_undirected(graph, res, 0, 0, 0, capacity); } /** * \function igraph_mincut_value * \brief The minimum edge cut in a graph * * The minimum edge cut in a graph is the total minimum * weight of the edges needed to remove from the graph to make the * graph \em not strongly connected. (If the original graph is not * strongly connected then this is zero.) Note that in undirected * graphs strong connectedness is the same as weak connectedness. * * The minimum cut can be calculated with maximum flow * techniques, although the current implementation does this only for * directed graphs and a separate non-flow based implementation is * used for undirected graphs. See Mechthild Stoer and Frank Wagner: A * simple min-cut algorithm, Journal of the ACM 44 585--591, 1997. * For directed graphs * the maximum flow is calculated between a fixed vertex and all the * other vertices in the graph and this is done in both * directions. Then the minimum is taken to get the minimum cut. * * \param graph The input graph. * \param res Pointer to a real variable, the result will be stored * here. * \param capacity Pointer to the capacity vector, it should contain * the same number of non-negative numbers as the number of edges in * the graph. If a null pointer then all edges will have unit capacity. * \return Error code. * * \sa \ref igraph_mincut(), \ref igraph_maxflow_value(), \ref * igraph_st_mincut_value(). * * Time complexity: O(log(|V|)*|V|^2) for undirected graphs and * O(|V|^4) for directed graphs, but see also the discussion at the * documentation of \ref igraph_maxflow_value(). */ int igraph_mincut_value(const igraph_t *graph, igraph_real_t *res, const igraph_vector_t *capacity) { long int no_of_nodes = igraph_vcount(graph); igraph_real_t minmaxflow, flow; long int i; minmaxflow = IGRAPH_INFINITY; if (!igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_mincut_value_undirected(graph, res, capacity)); return 0; } for (i = 1; i < no_of_nodes; i++) { IGRAPH_CHECK(igraph_maxflow_value(graph, &flow, 0, (igraph_integer_t) i, capacity, 0)); if (flow < minmaxflow) { minmaxflow = flow; if (flow == 0) { break; } } IGRAPH_CHECK(igraph_maxflow_value(graph, &flow, (igraph_integer_t) i, 0, capacity, 0)); if (flow < minmaxflow) { minmaxflow = flow; if (flow == 0) { break; } } } if (res) { *res = minmaxflow; } return 0; } static int igraph_i_st_vertex_connectivity_directed(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target, igraph_vconn_nei_t neighbors) { igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph); igraph_integer_t no_of_edges = (igraph_integer_t) igraph_ecount(graph); igraph_vector_t edges; igraph_real_t real_res; igraph_t newgraph; long int i; igraph_bool_t conn1; if (source < 0 || source >= no_of_nodes || target < 0 || target >= no_of_nodes) { IGRAPH_ERROR("Invalid source or target vertex", IGRAPH_EINVAL); } switch (neighbors) { case IGRAPH_VCONN_NEI_ERROR: IGRAPH_CHECK(igraph_are_connected(graph, source, target, &conn1)); if (conn1) { IGRAPH_ERROR("vertices connected", IGRAPH_EINVAL); } break; case IGRAPH_VCONN_NEI_NEGATIVE: IGRAPH_CHECK(igraph_are_connected(graph, source, target, &conn1)); if (conn1) { *res = -1; return 0; } break; case IGRAPH_VCONN_NEI_NUMBER_OF_NODES: IGRAPH_CHECK(igraph_are_connected(graph, source, target, &conn1)); if (conn1) { *res = no_of_nodes; return 0; } break; case IGRAPH_VCONN_NEI_IGNORE: break; default: IGRAPH_ERROR("Unknown `igraph_vconn_nei_t'", IGRAPH_EINVAL); break; } /* Create the new graph */ IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, 2 * (no_of_edges + no_of_nodes))); IGRAPH_CHECK(igraph_get_edgelist(graph, &edges, 0)); IGRAPH_CHECK(igraph_vector_resize(&edges, 2 * (no_of_edges + no_of_nodes))); for (i = 0; i < 2 * no_of_edges; i += 2) { igraph_integer_t to = (igraph_integer_t) VECTOR(edges)[i + 1]; if (to != source && to != target) { VECTOR(edges)[i + 1] = no_of_nodes + to; } } for (i = 0; i < no_of_nodes; i++) { VECTOR(edges)[ 2 * (no_of_edges + i) ] = no_of_nodes + i; VECTOR(edges)[ 2 * (no_of_edges + i) + 1 ] = i; } IGRAPH_CHECK(igraph_create(&newgraph, &edges, 2 * no_of_nodes, igraph_is_directed(graph))); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &newgraph); /* Do the maximum flow */ IGRAPH_CHECK(igraph_maxflow_value(&newgraph, &real_res, source, target, 0, 0)); *res = (igraph_integer_t)real_res; igraph_destroy(&newgraph); IGRAPH_FINALLY_CLEAN(1); return 0; } static int igraph_i_st_vertex_connectivity_undirected(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target, igraph_vconn_nei_t neighbors) { igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph); igraph_t newgraph; igraph_bool_t conn; if (source < 0 || source >= no_of_nodes || target < 0 || target >= no_of_nodes) { IGRAPH_ERROR("Invalid source or target vertex", IGRAPH_EINVAL); } switch (neighbors) { case IGRAPH_VCONN_NEI_ERROR: IGRAPH_CHECK(igraph_are_connected(graph, source, target, &conn)); if (conn) { IGRAPH_ERROR("vertices connected", IGRAPH_EINVAL); } break; case IGRAPH_VCONN_NEI_NEGATIVE: IGRAPH_CHECK(igraph_are_connected(graph, source, target, &conn)); if (conn) { *res = -1; return 0; } break; case IGRAPH_VCONN_NEI_NUMBER_OF_NODES: IGRAPH_CHECK(igraph_are_connected(graph, source, target, &conn)); if (conn) { *res = no_of_nodes; return 0; } break; case IGRAPH_VCONN_NEI_IGNORE: break; default: IGRAPH_ERROR("Unknown `igraph_vconn_nei_t'", IGRAPH_EINVAL); break; } IGRAPH_CHECK(igraph_copy(&newgraph, graph)); IGRAPH_FINALLY(igraph_destroy, &newgraph); IGRAPH_CHECK(igraph_to_directed(&newgraph, IGRAPH_TO_DIRECTED_MUTUAL)); IGRAPH_CHECK(igraph_i_st_vertex_connectivity_directed(&newgraph, res, source, target, IGRAPH_VCONN_NEI_IGNORE)); igraph_destroy(&newgraph); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_st_vertex_connectivity * \brief The vertex connectivity of a pair of vertices * * The vertex connectivity of two vertices (\c source and * \c target) is the minimum number of vertices that have to be * deleted to eliminate all paths from \c source to \c * target. Directed paths are considered in directed graphs. * * The vertex connectivity of a pair is the same as the number * of different (i.e. node-independent) paths from source to * target. * * The current implementation uses maximum flow calculations to * obtain the result. * \param graph The input graph. * \param res Pointer to an integer, the result will be stored here. * \param source The id of the source vertex. * \param target The id of the target vertex. * \param neighbors A constant giving what to do if the two vertices * are connected. Possible values: * \c IGRAPH_VCONN_NEI_ERROR, stop with an error message, * \c IGRAPH_VCONN_NEGATIVE, return -1. * \c IGRAPH_VCONN_NUMBER_OF_NODES, return the number of nodes. * \c IGRAPH_VCONN_IGNORE, ignore the fact that the two vertices * are connected and calculate the number of vertices needed * to eliminate all paths except for the trivial (direct) paths * between \p source and \p vertex. TODO: what about neighbors? * \return Error code. * * Time complexity: O(|V|^3), but see the discussion at \ref * igraph_maxflow_value(). * * \sa \ref igraph_vertex_connectivity(), * \ref igraph_edge_connectivity(), * \ref igraph_maxflow_value(). */ int igraph_st_vertex_connectivity(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target, igraph_vconn_nei_t neighbors) { if (source == target) { IGRAPH_ERROR("source and target vertices are the same", IGRAPH_EINVAL); } if (igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_st_vertex_connectivity_directed(graph, res, source, target, neighbors)); } else { IGRAPH_CHECK(igraph_i_st_vertex_connectivity_undirected(graph, res, source, target, neighbors)); } return 0; } static int igraph_i_vertex_connectivity_directed(const igraph_t *graph, igraph_integer_t *res) { igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph); long int i, j; igraph_integer_t minconn = no_of_nodes - 1, conn = 0; for (i = 0; i < no_of_nodes; i++) { for (j = 0; j < no_of_nodes; j++) { if (i == j) { continue; } IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_st_vertex_connectivity(graph, &conn, (igraph_integer_t) i, (igraph_integer_t) j, IGRAPH_VCONN_NEI_NUMBER_OF_NODES)); if (conn < minconn) { minconn = conn; if (conn == 0) { break; } } } if (conn == 0) { break; } } if (res) { *res = minconn; } return 0; } static int igraph_i_vertex_connectivity_undirected(const igraph_t *graph, igraph_integer_t *res) { igraph_t newgraph; IGRAPH_CHECK(igraph_copy(&newgraph, graph)); IGRAPH_FINALLY(igraph_destroy, &newgraph); IGRAPH_CHECK(igraph_to_directed(&newgraph, IGRAPH_TO_DIRECTED_MUTUAL)); IGRAPH_CHECK(igraph_i_vertex_connectivity_directed(&newgraph, res)); igraph_destroy(&newgraph); IGRAPH_FINALLY_CLEAN(1); return 0; } /* Use that vertex.connectivity(G) <= edge.connectivity(G) <= min(degree(G)) */ static int igraph_i_connectivity_checks(const igraph_t *graph, igraph_integer_t *res, igraph_bool_t *found) { igraph_bool_t conn; *found = 0; if (igraph_vcount(graph) == 0) { *res = 0; *found = 1; return 0; } IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_STRONG)); if (!conn) { *res = 0; *found = 1; } else { igraph_vector_t degree; IGRAPH_VECTOR_INIT_FINALLY(°ree, 0); if (!igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); if (igraph_vector_min(°ree) == 1) { *res = 1; *found = 1; } } else { /* directed, check both in- & out-degree */ IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); if (igraph_vector_min(°ree) == 1) { *res = 1; *found = 1; } else { IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS)); if (igraph_vector_min(°ree) == 1) { *res = 1; *found = 1; } } } igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_vertex_connectivity * The vertex connectivity of a graph * * The vertex connectivity of a graph is the minimum * vertex connectivity along each pairs of vertices in the graph. * * The vertex connectivity of a graph is the same as group * cohesion as defined in Douglas R. White and Frank Harary: The * cohesiveness of blocks in social networks: node connectivity and * conditional density, Sociological Methodology 31:305--359, 2001. * \param graph The input graph. * \param res Pointer to an integer, the result will be stored here. * \param checks Logical constant. Whether to check that the graph is * connected and also the degree of the vertices. If the graph is * not (strongly) connected then the connectivity is obviously zero. Otherwise * if the minimum degree is one then the vertex connectivity is also * one. It is a good idea to perform these checks, as they can be * done quickly compared to the connectivity calculation itself. * They were suggested by Peter McMahan, thanks Peter. * \return Error code. * * Time complexity: O(|V|^5). * * \sa \ref igraph_st_vertex_connectivity(), \ref igraph_maxflow_value(), * and \ref igraph_edge_connectivity(). */ int igraph_vertex_connectivity(const igraph_t *graph, igraph_integer_t *res, igraph_bool_t checks) { igraph_bool_t ret = 0; if (checks) { IGRAPH_CHECK(igraph_i_connectivity_checks(graph, res, &ret)); } /* Are we done yet? */ if (!ret) { if (igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_vertex_connectivity_directed(graph, res)); } else { IGRAPH_CHECK(igraph_i_vertex_connectivity_undirected(graph, res)); } } return 0; } /** * \function igraph_st_edge_connectivity * \brief Edge connectivity of a pair of vertices * * The edge connectivity of two vertices (\c source and * \c target) in a graph is the minimum number of edges that * have to be deleted from the graph to eliminate all paths from \c * source to \c target. * * This function uses the maximum flow algorithm to calculate * the edge connectivity. * \param graph The input graph, it has to be directed. * \param res Pointer to an integer, the result will be stored here. * \param source The id of the source vertex. * \param target The id of the target vertex. * \return Error code. * * Time complexity: O(|V|^3). * * \sa \ref igraph_maxflow_value(), \ref igraph_edge_connectivity(), * \ref igraph_st_vertex_connectivity(), \ref * igraph_vertex_connectivity(). */ int igraph_st_edge_connectivity(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target) { igraph_real_t flow; if (source == target) { IGRAPH_ERROR("source and target vertices are the same", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_maxflow_value(graph, &flow, source, target, 0, 0)); *res = (igraph_integer_t) flow; return 0; } /** * \function igraph_edge_connectivity * \brief The minimum edge connectivity in a graph. * * This is the minimum of the edge connectivity over all * pairs of vertices in the graph. * * * The edge connectivity of a graph is the same as group adhesion as * defined in Douglas R. White and Frank Harary: The cohesiveness of * blocks in social networks: node connectivity and conditional * density, Sociological Methodology 31:305--359, 2001. * \param graph The input graph. * \param res Pointer to an integer, the result will be stored here. * \param checks Logical constant. Whether to check that the graph is * connected and also the degree of the vertices. If the graph is * not (strongly) connected then the connectivity is obviously zero. Otherwise * if the minimum degree is one then the edge connectivity is also * one. It is a good idea to perform these checks, as they can be * done quickly compared to the connectivity calculation itself. * They were suggested by Peter McMahan, thanks Peter. * \return Error code. * * Time complexity: O(log(|V|)*|V|^2) for undirected graphs and * O(|V|^4) for directed graphs, but see also the discussion at the * documentation of \ref igraph_maxflow_value(). * * \sa \ref igraph_st_edge_connectivity(), \ref igraph_maxflow_value(), * \ref igraph_vertex_connectivity(). */ int igraph_edge_connectivity(const igraph_t *graph, igraph_integer_t *res, igraph_bool_t checks) { igraph_bool_t ret = 0; igraph_integer_t number_of_nodes = igraph_vcount(graph); /* igraph_mincut_value returns infinity for the singleton graph, * which cannot be cast to an integer. We catch this case early * and postulate the edge-connectivity of this graph to be 0. * This is consistent with what other software packages return. */ if (number_of_nodes <= 1) { *res = 0; return 0; } /* Use that vertex.connectivity(G) <= edge.connectivity(G) <= min(degree(G)) */ if (checks) { IGRAPH_CHECK(igraph_i_connectivity_checks(graph, res, &ret)); } if (!ret) { igraph_real_t real_res; IGRAPH_CHECK(igraph_mincut_value(graph, &real_res, 0)); *res = (igraph_integer_t)real_res; } return 0; } /** * \function igraph_edge_disjoint_paths * \brief The maximum number of edge-disjoint paths between two vertices. * * A set of paths between two vertices is called * edge-disjoint if they do not share any edges. The maximum number of * edge-disjoint paths are calculated by this function using maximum * flow techniques. Directed paths are considered in directed * graphs. * * Note that the number of disjoint paths is the same as the * edge connectivity of the two vertices using uniform edge weights. * \param graph The input graph, can be directed or undirected. * \param res Pointer to an integer variable, the result will be * stored here. * \param source The id of the source vertex. * \param target The id of the target vertex. * \return Error code. * * Time complexity: O(|V|^3), but see the discussion at \ref * igraph_maxflow_value(). * * \sa \ref igraph_vertex_disjoint_paths(), \ref * igraph_st_edge_connectivity(), \ref igraph_maxflow_value(). */ int igraph_edge_disjoint_paths(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target) { igraph_real_t flow; if (source == target) { IGRAPH_ERROR("Not implemented for source=target", IGRAPH_UNIMPLEMENTED); } IGRAPH_CHECK(igraph_maxflow_value(graph, &flow, source, target, 0, 0)); *res = (igraph_integer_t) flow; return 0; } /** * \function igraph_vertex_disjoint_paths * \brief Maximum number of vertex-disjoint paths between two vertices. * * A set of paths between two vertices is called * vertex-disjoint if they share no vertices. The calculation is * performed by using maximum flow techniques. * * Note that the number of vertex-disjoint paths is the same as * the vertex connectivity of the two vertices in most cases (if the * two vertices are not connected by an edge). * \param graph The input graph. * \param res Pointer to an integer variable, the result will be * stored here. * \param source The id of the source vertex. * \param target The id of the target vertex. * \return Error code. * * Time complexity: O(|V|^3). * * \sa \ref igraph_edge_disjoint_paths(), \ref * igraph_vertex_connectivity(), \ref igraph_maxflow_value(). */ int igraph_vertex_disjoint_paths(const igraph_t *graph, igraph_integer_t *res, igraph_integer_t source, igraph_integer_t target) { igraph_bool_t conn; if (source == target) { IGRAPH_ERROR("The source==target case is not implemented", IGRAPH_UNIMPLEMENTED); } IGRAPH_CHECK(igraph_are_connected(graph, source, target, &conn)); if (conn) { /* We need to remove every (possibly directed) edge between source and target and calculate the disjoint paths on the new graph. Finally we add 1 for the removed connection(s). */ igraph_es_t es; igraph_vector_t v; igraph_t newgraph; IGRAPH_VECTOR_INIT_FINALLY(&v, 2); VECTOR(v)[0] = source; VECTOR(v)[1] = target; IGRAPH_CHECK(igraph_es_multipairs(&es, &v, IGRAPH_DIRECTED)); IGRAPH_FINALLY(igraph_es_destroy, &es); IGRAPH_CHECK(igraph_copy(&newgraph, graph)); IGRAPH_FINALLY(igraph_destroy, &newgraph); IGRAPH_CHECK(igraph_delete_edges(&newgraph, es)); if (igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_st_vertex_connectivity_directed(&newgraph, res, source, target, IGRAPH_VCONN_NEI_IGNORE)); } else { IGRAPH_CHECK(igraph_i_st_vertex_connectivity_undirected(&newgraph, res, source, target, IGRAPH_VCONN_NEI_IGNORE)); } if (res) { *res += 1; } IGRAPH_FINALLY_CLEAN(3); igraph_destroy(&newgraph); igraph_es_destroy(&es); igraph_vector_destroy(&v); } /* These do nothing if the two vertices are connected, so it is safe to call them. */ if (igraph_is_directed(graph)) { IGRAPH_CHECK(igraph_i_st_vertex_connectivity_directed(graph, res, source, target, IGRAPH_VCONN_NEI_IGNORE)); } else { IGRAPH_CHECK(igraph_i_st_vertex_connectivity_undirected(graph, res, source, target, IGRAPH_VCONN_NEI_IGNORE)); } return 0; } /** * \function igraph_adhesion * \brief Graph adhesion, this is (almost) the same as edge connectivity. * * This quantity is defined by White and Harary in * The cohesiveness of blocks in social networks: node connectivity and * conditional density, (Sociological Methodology 31:305--359, 2001) * and basically it is the edge connectivity of the graph * with uniform edge weights. * \param graph The input graph, either directed or undirected. * \param res Pointer to an integer, the result will be stored here. * \param checks Logical constant. Whether to check that the graph is * connected and also the degree of the vertices. If the graph is * not (strongly) connected then the adhesion is obviously zero. Otherwise * if the minimum degree is one then the adhesion is also * one. It is a good idea to perform these checks, as they can be * done quickly compared to the edge connectivity calculation itself. * They were suggested by Peter McMahan, thanks Peter. * \return Error code. * * Time complexity: O(log(|V|)*|V|^2) for undirected graphs and * O(|V|^4) for directed graphs, but see also the discussion at the * documentation of \ref igraph_maxflow_value(). * * \sa \ref igraph_cohesion(), \ref igraph_maxflow_value(), \ref * igraph_edge_connectivity(), \ref igraph_mincut_value(). */ int igraph_adhesion(const igraph_t *graph, igraph_integer_t *res, igraph_bool_t checks) { return igraph_edge_connectivity(graph, res, checks); } /** * \function igraph_cohesion * \brief Graph cohesion, this is the same as vertex connectivity. * * This quantity was defined by White and Harary in The * cohesiveness of blocks in social networks: node connectivity and * conditional density, (Sociological Methodology 31:305--359, 2001) * and it is the same as the vertex connectivity of a * graph. * \param graph The input graph. * \param res Pointer to an integer variable, the result will be * stored here. * \param checks Logical constant. Whether to check that the graph is * connected and also the degree of the vertices. If the graph is * not (strongly) connected then the cohesion is obviously zero. Otherwise * if the minimum degree is one then the cohesion is also * one. It is a good idea to perform these checks, as they can be * done quickly compared to the vertex connectivity calculation itself. * They were suggested by Peter McMahan, thanks Peter. * \return Error code. * * Time complexity: O(|V|^4), |V| is the number of vertices. In * practice it is more like O(|V|^2), see \ref igraph_maxflow_value(). * * \sa \ref igraph_vertex_connectivity(), \ref igraph_adhesion(), * \ref igraph_maxflow_value(). */ int igraph_cohesion(const igraph_t *graph, igraph_integer_t *res, igraph_bool_t checks) { IGRAPH_CHECK(igraph_vertex_connectivity(graph, res, checks)); return 0; } /** * \function igraph_gomory_hu_tree * \brief Gomory-Hu tree of a graph. * * * The Gomory-Hu tree is a concise representation of the value of all the * maximum flows (or minimum cuts) in a graph. The vertices of the tree * correspond exactly to the vertices of the original graph in the same order. * Edges of the Gomory-Hu tree are annotated by flow values. The value of * the maximum flow (or minimum cut) between an arbitrary (u,v) vertex * pair in the original graph is then given by the minimum flow value (i.e. * edge annotation) along the shortest path between u and v in the * Gomory-Hu tree. * * This implementation uses Gusfield's algorithm to construct the * Gomory-Hu tree. See the following paper for more details: * * * Gusfield D: Very simple methods for all pairs network flow analysis. SIAM J * Comput 19(1):143-155, 1990. * * \param graph The input graph. * \param tree Pointer to an uninitialized graph; the result will be * stored here. * \param flows Pointer to an uninitialized vector; the flow values * corresponding to each edge in the Gomory-Hu tree will * be returned here. You may pass a NULL pointer here if you are * not interested in the flow values. * \param capacity Vector containing the capacity of the edges. If NULL, then * every edge is considered to have capacity 1.0. * \return Error code. * * Time complexity: O(|V|^4) since it performs a max-flow calculation * between vertex zero and every other vertex and max-flow is * O(|V|^3). * * \sa \ref igraph_maxflow() */ int igraph_gomory_hu_tree(const igraph_t *graph, igraph_t *tree, igraph_vector_t *flows, const igraph_vector_t *capacity) { igraph_integer_t no_of_nodes = igraph_vcount(graph); igraph_integer_t source, target, mid, i, n; igraph_vector_t neighbors; igraph_vector_t flow_values; igraph_vector_t partition; igraph_vector_t partition2; igraph_real_t flow_value; if (igraph_is_directed(graph)) { IGRAPH_ERROR("Gomory-Hu tree can only be calculated for undirected graphs", IGRAPH_EINVAL); } /* Allocate memory */ IGRAPH_VECTOR_INIT_FINALLY(&neighbors, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&flow_values, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&partition, 0); IGRAPH_VECTOR_INIT_FINALLY(&partition2, 0); /* Initialize the tree: every edge points to node 0 */ /* Actually, this is done implicitly since both 'neighbors' and 'flow_values' are * initialized to zero already */ /* For each source vertex except vertex zero... */ for (source = 1; source < no_of_nodes; source++) { IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_PROGRESS("Gomory-Hu tree", (100.0 * (source - 1)) / (no_of_nodes - 1), 0); /* Find its current neighbor in the tree */ target = VECTOR(neighbors)[(long int)source]; /* Find the maximum flow between source and target */ IGRAPH_CHECK(igraph_maxflow(graph, &flow_value, 0, 0, &partition, &partition2, source, target, capacity, 0)); /* Store the maximum flow */ VECTOR(flow_values)[(long int)source] = flow_value; /* Update the tree */ /* igraph_maxflow() guarantees that the source vertex will be in &partition * and not in &partition2 so we need to iterate over &partition to find * all the nodes that are of interest to us */ n = igraph_vector_size(&partition); for (i = 0; i < n; i++) { mid = VECTOR(partition)[i]; if (mid != source) { if (VECTOR(neighbors)[(long int)mid] == target) { VECTOR(neighbors)[(long int)mid] = source; } else if (VECTOR(neighbors)[(long int)target] == mid) { VECTOR(neighbors)[(long int)target] = source; VECTOR(neighbors)[(long int)source] = mid; VECTOR(flow_values)[(long int)source] = VECTOR(flow_values)[(long int)target]; VECTOR(flow_values)[(long int)target] = flow_value; } } } } IGRAPH_PROGRESS("Gomory-Hu tree", 100.0, 0); /* Re-use the 'partition' vector as an edge list now */ IGRAPH_CHECK(igraph_vector_resize(&partition, 2 * (no_of_nodes - 1))); for (i = 1, mid = 0; i < no_of_nodes; i++, mid += 2) { VECTOR(partition)[(long int)mid] = i; VECTOR(partition)[(long int)mid + 1] = VECTOR(neighbors)[(long int)i]; } /* Create the tree graph; we use igraph_subgraph_edges here to keep the * graph and vertex attributes */ IGRAPH_CHECK(igraph_subgraph_edges(graph, tree, igraph_ess_none(), 0)); IGRAPH_CHECK(igraph_add_edges(tree, &partition, 0)); /* Free the allocated memory */ igraph_vector_destroy(&partition2); igraph_vector_destroy(&partition); igraph_vector_destroy(&neighbors); IGRAPH_FINALLY_CLEAN(3); /* Return the flow values to the caller */ if (flows != 0) { IGRAPH_CHECK(igraph_vector_update(flows, &flow_values)); if (no_of_nodes > 0) { igraph_vector_remove(flows, 0); } } /* Free the remaining allocated memory */ igraph_vector_destroy(&flow_values); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } leidenbase/src/core/flow/flow_internal.h0000644000176200001440000000277114447675374020103 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_FLOW_INTERNAL_H #define IGRAPH_FLOW_INTERNAL_H #include "igraph_types.h" __BEGIN_DECLS IGRAPH_PRIVATE_EXPORT int igraph_i_all_st_cuts_pivot(const igraph_t *graph, const igraph_marked_queue_t *S, const igraph_estack_t *T, long int source, long int target, long int *v, igraph_vector_t *Isv, void *arg); __END_DECLS #endif leidenbase/src/core/io/0000755000176200001440000000000014532173045014477 5ustar liggesusersleidenbase/src/core/io/ncol-parser.h0000644000176200001440000000601314447675375017117 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ #ifndef YY_IGRAPH_NCOL_YY_YY_TAB_H_INCLUDED # define YY_IGRAPH_NCOL_YY_YY_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int igraph_ncol_yydebug; #endif /* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { YYEMPTY = -2, YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ ALNUM = 258, /* ALNUM */ NEWLINE = 259, /* NEWLINE */ ERROR = 260 /* ERROR */ }; typedef enum yytokentype yytoken_kind_t; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 79 "src/core/io/ncol-parser.y" long int edgenum; double weightnum; #line 74 "yy.tab.h" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif /* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE YYLTYPE; struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; }; # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif int igraph_ncol_yyparse (igraph_i_ncol_parsedata_t* context); #endif /* !YY_IGRAPH_NCOL_YY_YY_TAB_H_INCLUDED */ leidenbase/src/core/io/graphdb.c0000644000176200001440000000720514447675374016277 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_constructors.h" #include "core/trie.h" static int igraph_i_read_graph_graphdb_getword(FILE *instream) { int b1, b2; unsigned char c1, c2; b1 = fgetc(instream); b2 = fgetc(instream); if (b1 != EOF) { c1 = (unsigned char) b1; c2 = (unsigned char) b2; return c1 | (c2 << 8); } else { return -1; } } /** * \function igraph_read_graph_graphdb * \brief Read a graph in the binary graph database format. * * This is a binary format, used in the graph database * for isomorphism testing. From the (now defunct) graph database * homepage: * * * \blockquote * The graphs are stored in a compact binary format, one graph per * file. The file is composed of 16 bit words, which are represented * using the so-called little-endian convention, i.e. the least * significant byte of the word is stored first. * * * Then, for each node, the file contains the list of edges coming * out of the node itself. The list is represented by a word encoding * its length, followed by a word for each edge, representing the * destination node of the edge. Node numeration is 0-based, so the * first node of the graph has index 0. \endblockquote * * * Only unlabelled graphs are implemented. * \param graph Pointer to an uninitialized graph object. * \param instream The stream to read from. * \param directed Logical scalar, whether to create a directed graph. * \return Error code. * * Time complexity: O(|V|+|E|), the number of vertices plus the * number of edges. * * \example examples/simple/igraph_read_graph_graphdb.c */ int igraph_read_graph_graphdb(igraph_t *graph, FILE *instream, igraph_bool_t directed) { igraph_vector_t edges; long int nodes; long int i, j; igraph_bool_t end = 0; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); nodes = igraph_i_read_graph_graphdb_getword(instream); if (nodes < 0) { IGRAPH_ERROR("Can't read from file", IGRAPH_EFILE); } for (i = 0; !end && i < nodes; i++) { long int len = igraph_i_read_graph_graphdb_getword(instream); if (len < 0) { end = 1; break; } for (j = 0; ! end && j < len; j++) { long int to = igraph_i_read_graph_graphdb_getword(instream); if (to < 0) { end = 1; break; } IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); } } if (end) { IGRAPH_ERROR("Truncated graphdb file", IGRAPH_EFILE); } IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/io/pajek-parser.c0000644000176200001440000032030514447675375017254 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ #define YYBISON 30802 /* Bison version string. */ #define YYBISON_VERSION "3.8.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Substitute the variable and function names. */ #define yyparse igraph_pajek_yyparse #define yylex igraph_pajek_yylex #define yyerror igraph_pajek_yyerror #define yydebug igraph_pajek_yydebug #define yynerrs igraph_pajek_yynerrs /* First part of user prologue. */ #line 23 "src/core/io/pajek-parser.y" /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" #include "igraph_attributes.h" #include "config.h" #include "core/math.h" #include "io/pajek-header.h" #include "io/pajek-parser.h" /* it must come first because of YYSTYPE */ #include "io/pajek-lexer.h" #include "internal/hacks.h" int igraph_pajek_yyerror(YYLTYPE* locp, igraph_i_pajek_parsedata_t *context, const char *s); int igraph_i_pajek_add_string_vertex_attribute(const char *name, const char *value, int len, igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_add_string_edge_attribute(const char *name, const char *value, int len, igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_add_numeric_vertex_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_add_numeric_edge_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_add_numeric_attribute(igraph_trie_t *names, igraph_vector_ptr_t *attrs, long int count, const char *attrname, igraph_integer_t vid, igraph_real_t number); int igraph_i_pajek_add_string_attribute(igraph_trie_t *names, igraph_vector_ptr_t *attrs, long int count, const char *attrname, igraph_integer_t vid, const char *str); int igraph_i_pajek_add_bipartite_type(igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_check_bipartite(igraph_i_pajek_parsedata_t *context); extern igraph_real_t igraph_pajek_get_number(const char *str, long int len); extern long int igraph_i_pajek_actvertex; extern long int igraph_i_pajek_actedge; #define scanner context->scanner #line 158 "yy.tab.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif #include "io/pajek-parser.h" /* Symbol kind. */ enum yysymbol_kind_t { YYSYMBOL_YYEMPTY = -2, YYSYMBOL_YYEOF = 0, /* "end of file" */ YYSYMBOL_YYerror = 1, /* error */ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ YYSYMBOL_NEWLINE = 3, /* NEWLINE */ YYSYMBOL_NUM = 4, /* NUM */ YYSYMBOL_ALNUM = 5, /* ALNUM */ YYSYMBOL_QSTR = 6, /* QSTR */ YYSYMBOL_PSTR = 7, /* PSTR */ YYSYMBOL_NETWORKLINE = 8, /* NETWORKLINE */ YYSYMBOL_VERTICESLINE = 9, /* VERTICESLINE */ YYSYMBOL_ARCSLINE = 10, /* ARCSLINE */ YYSYMBOL_EDGESLINE = 11, /* EDGESLINE */ YYSYMBOL_ARCSLISTLINE = 12, /* ARCSLISTLINE */ YYSYMBOL_EDGESLISTLINE = 13, /* EDGESLISTLINE */ YYSYMBOL_MATRIXLINE = 14, /* MATRIXLINE */ YYSYMBOL_ERROR = 15, /* ERROR */ YYSYMBOL_VP_X_FACT = 16, /* VP_X_FACT */ YYSYMBOL_VP_Y_FACT = 17, /* VP_Y_FACT */ YYSYMBOL_VP_IC = 18, /* VP_IC */ YYSYMBOL_VP_BC = 19, /* VP_BC */ YYSYMBOL_VP_LC = 20, /* VP_LC */ YYSYMBOL_VP_LR = 21, /* VP_LR */ YYSYMBOL_VP_LPHI = 22, /* VP_LPHI */ YYSYMBOL_VP_BW = 23, /* VP_BW */ YYSYMBOL_VP_FOS = 24, /* VP_FOS */ YYSYMBOL_VP_PHI = 25, /* VP_PHI */ YYSYMBOL_VP_R = 26, /* VP_R */ YYSYMBOL_VP_Q = 27, /* VP_Q */ YYSYMBOL_VP_LA = 28, /* VP_LA */ YYSYMBOL_VP_FONT = 29, /* VP_FONT */ YYSYMBOL_VP_URL = 30, /* VP_URL */ YYSYMBOL_VP_SIZE = 31, /* VP_SIZE */ YYSYMBOL_EP_C = 32, /* EP_C */ YYSYMBOL_EP_S = 33, /* EP_S */ YYSYMBOL_EP_A = 34, /* EP_A */ YYSYMBOL_EP_W = 35, /* EP_W */ YYSYMBOL_EP_H1 = 36, /* EP_H1 */ YYSYMBOL_EP_H2 = 37, /* EP_H2 */ YYSYMBOL_EP_A1 = 38, /* EP_A1 */ YYSYMBOL_EP_A2 = 39, /* EP_A2 */ YYSYMBOL_EP_K1 = 40, /* EP_K1 */ YYSYMBOL_EP_K2 = 41, /* EP_K2 */ YYSYMBOL_EP_AP = 42, /* EP_AP */ YYSYMBOL_EP_P = 43, /* EP_P */ YYSYMBOL_EP_L = 44, /* EP_L */ YYSYMBOL_EP_LP = 45, /* EP_LP */ YYSYMBOL_EP_LR = 46, /* EP_LR */ YYSYMBOL_EP_LPHI = 47, /* EP_LPHI */ YYSYMBOL_EP_LC = 48, /* EP_LC */ YYSYMBOL_EP_LA = 49, /* EP_LA */ YYSYMBOL_EP_SIZE = 50, /* EP_SIZE */ YYSYMBOL_EP_FOS = 51, /* EP_FOS */ YYSYMBOL_YYACCEPT = 52, /* $accept */ YYSYMBOL_input = 53, /* input */ YYSYMBOL_nethead = 54, /* nethead */ YYSYMBOL_vertices = 55, /* vertices */ YYSYMBOL_verticeshead = 56, /* verticeshead */ YYSYMBOL_vertdefs = 57, /* vertdefs */ YYSYMBOL_vertexline = 58, /* vertexline */ YYSYMBOL_59_1 = 59, /* $@1 */ YYSYMBOL_vertex = 60, /* vertex */ YYSYMBOL_vertexid = 61, /* vertexid */ YYSYMBOL_vertexcoords = 62, /* vertexcoords */ YYSYMBOL_shape = 63, /* shape */ YYSYMBOL_params = 64, /* params */ YYSYMBOL_param = 65, /* param */ YYSYMBOL_vpword = 66, /* vpword */ YYSYMBOL_67_2 = 67, /* $@2 */ YYSYMBOL_68_3 = 68, /* $@3 */ YYSYMBOL_69_4 = 69, /* $@4 */ YYSYMBOL_70_5 = 70, /* $@5 */ YYSYMBOL_71_6 = 71, /* $@6 */ YYSYMBOL_vpwordpar = 72, /* vpwordpar */ YYSYMBOL_edgeblock = 73, /* edgeblock */ YYSYMBOL_arcs = 74, /* arcs */ YYSYMBOL_arcsdefs = 75, /* arcsdefs */ YYSYMBOL_arcsline = 76, /* arcsline */ YYSYMBOL_77_7 = 77, /* $@7 */ YYSYMBOL_arcfrom = 78, /* arcfrom */ YYSYMBOL_arcto = 79, /* arcto */ YYSYMBOL_edges = 80, /* edges */ YYSYMBOL_edgesdefs = 81, /* edgesdefs */ YYSYMBOL_edgesline = 82, /* edgesline */ YYSYMBOL_83_8 = 83, /* $@8 */ YYSYMBOL_edgefrom = 84, /* edgefrom */ YYSYMBOL_edgeto = 85, /* edgeto */ YYSYMBOL_weight = 86, /* weight */ YYSYMBOL_edgeparams = 87, /* edgeparams */ YYSYMBOL_edgeparam = 88, /* edgeparam */ YYSYMBOL_epword = 89, /* epword */ YYSYMBOL_90_9 = 90, /* $@9 */ YYSYMBOL_91_10 = 91, /* $@10 */ YYSYMBOL_92_11 = 92, /* $@11 */ YYSYMBOL_93_12 = 93, /* $@12 */ YYSYMBOL_94_13 = 94, /* $@13 */ YYSYMBOL_epwordpar = 95, /* epwordpar */ YYSYMBOL_arcslist = 96, /* arcslist */ YYSYMBOL_arcslistlines = 97, /* arcslistlines */ YYSYMBOL_arclistline = 98, /* arclistline */ YYSYMBOL_arctolist = 99, /* arctolist */ YYSYMBOL_arclistfrom = 100, /* arclistfrom */ YYSYMBOL_arclistto = 101, /* arclistto */ YYSYMBOL_edgeslist = 102, /* edgeslist */ YYSYMBOL_edgelistlines = 103, /* edgelistlines */ YYSYMBOL_edgelistline = 104, /* edgelistline */ YYSYMBOL_edgetolist = 105, /* edgetolist */ YYSYMBOL_edgelistfrom = 106, /* edgelistfrom */ YYSYMBOL_edgelistto = 107, /* edgelistto */ YYSYMBOL_adjmatrix = 108, /* adjmatrix */ YYSYMBOL_matrixline = 109, /* matrixline */ YYSYMBOL_adjmatrixlines = 110, /* adjmatrixlines */ YYSYMBOL_adjmatrixline = 111, /* adjmatrixline */ YYSYMBOL_adjmatrixnumbers = 112, /* adjmatrixnumbers */ YYSYMBOL_adjmatrixentry = 113, /* adjmatrixentry */ YYSYMBOL_longint = 114, /* longint */ YYSYMBOL_number = 115, /* number */ YYSYMBOL_words = 116, /* words */ YYSYMBOL_word = 117 /* word */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif /* Work around bug in HP-UX 11.23, which defines these macros incorrectly for preprocessor constants. This workaround can likely be removed in 2023, as HPE has promised support for HP-UX 11.23 (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of . */ #ifdef __hpux # undef UINT_LEAST8_MAX # undef UINT_LEAST16_MAX # define UINT_LEAST8_MAX 255 # define UINT_LEAST16_MAX 65535 #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_uint8 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YY_USE(E) ((void) (E)) #else # define YY_USE(E) /* empty */ #endif /* Suppress an incorrect diagnostic about yylval being uninitialized. */ #if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ # if __GNUC__ * 100 + __GNUC_MINOR__ < 407 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") # else # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # endif # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if 1 /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* 1 */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ + YYSIZEOF (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 5 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 250 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 52 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 66 /* YYNRULES -- Number of rules. */ #define YYNRULES 137 /* YYNSTATES -- Number of states. */ #define YYNSTATES 207 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 306 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK \ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { 0, 189, 189, 193, 193, 195, 197, 201, 207, 207, 209, 210, 211, 211, 214, 216, 221, 222, 226, 232, 232, 236, 236, 239, 240, 243, 246, 251, 256, 261, 264, 267, 270, 273, 276, 279, 282, 285, 290, 290, 294, 294, 298, 298, 302, 302, 307, 307, 314, 316, 316, 316, 316, 316, 316, 318, 319, 321, 321, 323, 324, 324, 330, 332, 334, 335, 337, 337, 339, 340, 340, 346, 348, 350, 350, 354, 354, 357, 358, 363, 366, 369, 372, 375, 378, 381, 384, 387, 390, 393, 396, 399, 402, 405, 410, 410, 414, 414, 418, 418, 422, 422, 426, 426, 432, 434, 436, 436, 438, 438, 440, 440, 442, 444, 449, 451, 451, 453, 453, 455, 455, 457, 459, 466, 468, 473, 473, 475, 477, 477, 479, 499, 502, 505, 505, 507, 509, 511 }; #endif /** Accessing symbol of state STATE. */ #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) #if 1 /* The user-facing name of the symbol whose (internal) number is YYSYMBOL. No bounds checking. */ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "\"end of file\"", "error", "\"invalid token\"", "NEWLINE", "NUM", "ALNUM", "QSTR", "PSTR", "NETWORKLINE", "VERTICESLINE", "ARCSLINE", "EDGESLINE", "ARCSLISTLINE", "EDGESLISTLINE", "MATRIXLINE", "ERROR", "VP_X_FACT", "VP_Y_FACT", "VP_IC", "VP_BC", "VP_LC", "VP_LR", "VP_LPHI", "VP_BW", "VP_FOS", "VP_PHI", "VP_R", "VP_Q", "VP_LA", "VP_FONT", "VP_URL", "VP_SIZE", "EP_C", "EP_S", "EP_A", "EP_W", "EP_H1", "EP_H2", "EP_A1", "EP_A2", "EP_K1", "EP_K2", "EP_AP", "EP_P", "EP_L", "EP_LP", "EP_LR", "EP_LPHI", "EP_LC", "EP_LA", "EP_SIZE", "EP_FOS", "$accept", "input", "nethead", "vertices", "verticeshead", "vertdefs", "vertexline", "$@1", "vertex", "vertexid", "vertexcoords", "shape", "params", "param", "vpword", "$@2", "$@3", "$@4", "$@5", "$@6", "vpwordpar", "edgeblock", "arcs", "arcsdefs", "arcsline", "$@7", "arcfrom", "arcto", "edges", "edgesdefs", "edgesline", "$@8", "edgefrom", "edgeto", "weight", "edgeparams", "edgeparam", "epword", "$@9", "$@10", "$@11", "$@12", "$@13", "epwordpar", "arcslist", "arcslistlines", "arclistline", "arctolist", "arclistfrom", "arclistto", "edgeslist", "edgelistlines", "edgelistline", "edgetolist", "edgelistfrom", "edgelistto", "adjmatrix", "matrixline", "adjmatrixlines", "adjmatrixline", "adjmatrixnumbers", "adjmatrixentry", "longint", "number", "words", "word", YY_NULLPTR }; static const char * yysymbol_name (yysymbol_kind_t yysymbol) { return yytname[yysymbol]; } #endif #define YYPACT_NINF (-167) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-129) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { -4, -167, 7, 36, 22, -167, 44, -167, 49, -167, -167, -167, -167, -167, -167, 44, 10, -167, -167, 12, 27, 51, 56, -167, -167, -167, -167, -167, -167, 58, 29, -167, -167, 59, -167, 60, -167, -167, -167, -167, -167, 61, -167, 31, -167, 33, -167, 35, 37, 39, -167, 5, -167, -167, 44, -167, 31, -167, -167, 44, -167, 33, -167, -167, -167, -167, -167, -167, -167, -167, -167, 62, 65, -167, 65, -167, -167, -167, -167, -167, 47, 53, -167, -167, 5, 65, 65, 65, -167, -167, -167, -167, -167, -167, -167, -167, 65, -167, -167, -167, 219, -167, 150, 170, -167, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -167, -167, 65, -167, -167, -167, 65, 65, -167, 65, 65, 65, 65, 65, 65, 65, 65, -167, -167, 65, 65, 65, -167, 65, 65, 65, -167, -167, -167, -167, -167, 5, 65, 5, 65, 5, 65, -167, -167, -167, -167, -167, -167, -167, -167, 5, 5, -167, 5, 65, -167, 5, -167, -167, -167, -167, -167, -167, -167, -167, 5, 5, -167, -167, -167, 5, -167, -167, -167, -167, -167, 65, -167, 65, -167, 65, -167, -167, -167, -167, 65, -167, -167, -167, -167, -167, -167, -167, -167 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 3, 133, 0, 0, 0, 1, 0, 49, 0, 4, 136, 135, 137, 134, 131, 6, 2, 8, 7, 0, 0, 0, 0, 124, 50, 51, 52, 53, 54, 0, 5, 57, 132, 0, 66, 0, 106, 115, 125, 10, 9, 12, 14, 55, 57, 64, 66, 105, 114, 123, 11, 0, 59, 58, 0, 62, 56, 68, 67, 0, 71, 65, 108, 107, 110, 112, 117, 116, 119, 121, 126, 0, 128, 130, 16, 15, 60, 63, 69, 72, 0, 0, 127, 129, 19, 0, 73, 73, 109, 111, 113, 118, 120, 122, 21, 20, 17, 75, 74, 75, 0, 18, 0, 0, 13, 0, 0, 42, 44, 46, 0, 0, 0, 0, 0, 0, 0, 0, 38, 40, 0, 22, 23, 61, 102, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 96, 98, 0, 0, 0, 100, 0, 0, 0, 76, 77, 70, 24, 25, 0, 0, 0, 0, 0, 0, 29, 30, 31, 32, 33, 34, 35, 36, 0, 0, 37, 0, 0, 79, 0, 80, 81, 82, 83, 84, 85, 86, 87, 0, 0, 88, 89, 90, 0, 91, 92, 93, 43, 48, 0, 45, 0, 47, 0, 39, 41, 103, 104, 0, 95, 97, 99, 101, 26, 27, 28, 78 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -145, -167, -167, 26, -167, -167, -167, -167, -167, 25, -167, -167, -167, -167, -15, -26, -167, -167, -167, -167, -167, -167, -167, -166, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, 2, -167, -1, -19, -167, -2 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_uint8 yydefgoto[] = { 0, 2, 3, 7, 8, 30, 40, 51, 41, 74, 84, 94, 100, 121, 122, 163, 164, 149, 151, 153, 187, 16, 24, 43, 53, 86, 54, 76, 25, 45, 58, 87, 59, 78, 97, 102, 144, 145, 169, 178, 179, 183, 166, 196, 26, 47, 63, 80, 64, 89, 27, 48, 67, 81, 68, 92, 28, 29, 49, 70, 71, 72, 55, 73, 4, 188 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { 33, 35, 13, 199, 1, 15, 190, 5, 192, 10, 11, 12, 200, 201, 18, 31, 32, 202, 194, 195, 19, 20, 21, 22, 23, 9, 10, 11, 12, 42, 34, 32, 39, 14, 52, 14, 57, 14, 62, 14, 66, 14, -128, 32, 60, 6, 65, 69, 14, 75, 88, 14, 17, 77, 36, 85, 91, 14, 79, 37, 60, 38, 44, 46, 50, 82, 96, 98, 98, 32, 56, 61, 99, 103, 83, 0, 0, 101, 0, 90, 93, 0, 95, 0, 0, 0, 147, 148, 150, 152, 154, 155, 156, 157, 158, 159, 160, 161, 162, 0, 0, 165, 0, 0, 0, 167, 168, 0, 170, 171, 172, 173, 174, 175, 176, 177, 0, 0, 180, 181, 182, 0, 184, 185, 186, 0, 0, 0, 0, 0, 0, 189, 0, 191, 0, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 197, 0, 0, 203, 0, 204, 146, 205, 0, 197, 197, 0, 206, 0, 197, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120 }; static const yytype_int16 yycheck[] = { 19, 20, 4, 169, 8, 6, 151, 0, 153, 4, 5, 6, 178, 179, 15, 3, 4, 183, 163, 164, 10, 11, 12, 13, 14, 3, 4, 5, 6, 30, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 45, 9, 47, 48, 4, 51, 3, 4, 3, 54, 3, 74, 3, 4, 59, 3, 61, 3, 3, 3, 3, 3, 85, 86, 87, 4, 44, 46, 87, 99, 72, -1, -1, 96, -1, 80, 81, -1, 84, -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, -1, -1, 120, -1, -1, -1, 124, 125, -1, 127, 128, 129, 130, 131, 132, 133, 134, -1, -1, 137, 138, 139, -1, 141, 142, 143, -1, -1, -1, -1, -1, -1, 150, -1, 152, -1, 154, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 167, -1, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 166, -1, -1, 169, -1, -1, 189, -1, 191, 3, 193, -1, 178, 179, -1, 198, -1, 183, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { 0, 8, 53, 54, 116, 0, 9, 55, 56, 3, 4, 5, 6, 117, 4, 114, 73, 3, 114, 10, 11, 12, 13, 14, 74, 80, 96, 102, 108, 109, 57, 3, 4, 115, 3, 115, 3, 3, 3, 3, 58, 60, 114, 75, 3, 81, 3, 97, 103, 110, 3, 59, 3, 76, 78, 114, 75, 3, 82, 84, 114, 81, 3, 98, 100, 114, 3, 104, 106, 114, 111, 112, 113, 115, 61, 117, 79, 114, 85, 114, 99, 105, 3, 112, 62, 115, 77, 83, 3, 101, 114, 3, 107, 114, 63, 117, 115, 86, 115, 86, 64, 115, 87, 87, 3, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 65, 66, 3, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 88, 89, 3, 115, 115, 69, 115, 70, 115, 71, 115, 115, 115, 115, 115, 115, 115, 115, 115, 67, 68, 115, 94, 115, 115, 90, 115, 115, 115, 115, 115, 115, 115, 115, 91, 92, 115, 115, 115, 93, 115, 115, 115, 72, 117, 115, 72, 115, 72, 115, 72, 72, 95, 117, 115, 95, 95, 95, 95, 115, 115, 115, 115 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int8 yyr1[] = { 0, 52, 53, 54, 54, 55, 56, 56, 57, 57, 58, 58, 59, 58, 60, 61, 62, 62, 62, 63, 63, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 66, 68, 66, 69, 66, 70, 66, 71, 66, 72, 73, 73, 73, 73, 73, 73, 74, 74, 75, 75, 76, 77, 76, 78, 79, 80, 80, 81, 81, 82, 83, 82, 84, 85, 86, 86, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 90, 89, 91, 89, 92, 89, 93, 89, 94, 89, 95, 96, 97, 97, 98, 98, 99, 99, 100, 101, 102, 103, 103, 104, 104, 105, 105, 106, 107, 108, 109, 110, 110, 111, 112, 112, 113, 114, 115, 116, 116, 117, 117, 117 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ static const yytype_int8 yyr2[] = { 0, 2, 3, 0, 3, 3, 2, 3, 0, 2, 1, 2, 0, 7, 1, 1, 0, 2, 3, 0, 1, 0, 2, 1, 2, 2, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 1, 0, 2, 2, 2, 2, 2, 3, 4, 0, 2, 1, 0, 6, 1, 1, 3, 4, 0, 2, 1, 0, 6, 1, 1, 0, 1, 0, 2, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 1, 3, 0, 2, 1, 3, 0, 2, 1, 1, 3, 0, 2, 1, 3, 0, 2, 1, 1, 3, 1, 0, 2, 2, 0, 2, 1, 1, 1, 0, 2, 1, 1, 1 }; enum { YYENOMEM = -2 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Backward compatibility with an undocumented macro. Use YYerror or YYUNDEF. */ #define YYERRCODE YYUNDEF /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (N) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (0) #endif #define YYRHSLOC(Rhs, K) ((Rhs)[K]) /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* YYLOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ # ifndef YYLOCATION_PRINT # if defined YY_LOCATION_PRINT /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc)) # elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL /* Print *YYLOCP on YYO. Private, do not rely on its existence. */ YY_ATTRIBUTE_UNUSED static int yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) { int res = 0; int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; if (0 <= yylocp->first_line) { res += YYFPRINTF (yyo, "%d", yylocp->first_line); if (0 <= yylocp->first_column) res += YYFPRINTF (yyo, ".%d", yylocp->first_column); } if (0 <= yylocp->last_line) { if (yylocp->first_line < yylocp->last_line) { res += YYFPRINTF (yyo, "-%d", yylocp->last_line); if (0 <= end_col) res += YYFPRINTF (yyo, ".%d", end_col); } else if (0 <= end_col && yylocp->first_column < end_col) res += YYFPRINTF (yyo, "-%d", end_col); } return res; } # define YYLOCATION_PRINT yy_location_print_ /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc)) # else # define YYLOCATION_PRINT(File, Loc) ((void) 0) /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT YYLOCATION_PRINT # endif # endif /* !defined YYLOCATION_PRINT */ # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Kind, Value, Location, context); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_pajek_parsedata_t* context) { FILE *yyoutput = yyo; YY_USE (yyoutput); YY_USE (yylocationp); YY_USE (context); if (!yyvaluep) return; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_pajek_parsedata_t* context) { YYFPRINTF (yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); YYLOCATION_PRINT (yyo, yylocationp); YYFPRINTF (yyo, ": "); yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp, context); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, igraph_i_pajek_parsedata_t* context) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), &yyvsp[(yyi + 1) - (yynrhs)], &(yylsp[(yyi + 1) - (yynrhs)]), context); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, yylsp, Rule, context); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) ((void) 0) # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif /* Context of a parse error. */ typedef struct { yy_state_t *yyssp; yysymbol_kind_t yytoken; YYLTYPE *yylloc; } yypcontext_t; /* Put in YYARG at most YYARGN of the expected tokens given the current YYCTX, and return the number of tokens stored in YYARG. If YYARG is null, return the number of expected tokens (guaranteed to be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. Return 0 if there are more than YYARGN expected tokens, yet fill YYARG up to YYARGN. */ static int yypcontext_expected_tokens (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; int yyn = yypact[+*yyctx->yyssp]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror && !yytable_value_is_error (yytable[yyx + yyn])) { if (!yyarg) ++yycount; else if (yycount == yyargn) return 0; else yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); } } if (yyarg && yycount == 0 && 0 < yyargn) yyarg[0] = YYSYMBOL_YYEMPTY; return yycount; } #ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) { YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif #endif #ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif #endif #ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; else goto append; append: default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (yyres) return yystpcpy (yyres, yystr) - yyres; else return yystrlen (yystr); } #endif static int yy_syntax_error_arguments (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yyctx->yytoken != YYSYMBOL_YYEMPTY) { int yyn; if (yyarg) yyarg[yycount] = yyctx->yytoken; ++yycount; yyn = yypcontext_expected_tokens (yyctx, yyarg ? yyarg + 1 : yyarg, yyargn - 1); if (yyn == YYENOMEM) return YYENOMEM; else yycount += yyn; } return yycount; } /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the required number of bytes is too large to store. */ static int yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, const yypcontext_t *yyctx) { enum { YYARGS_MAX = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ yysymbol_kind_t yyarg[YYARGS_MAX]; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; /* Actual size of YYARG. */ int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); if (yycount == YYENOMEM) return YYENOMEM; switch (yycount) { #define YYCASE_(N, S) \ case N: \ yyformat = S; \ break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); #undef YYCASE_ } /* Compute error message size. Don't count the "%s"s, but reserve room for the terminator. */ yysize = yystrlen (yyformat) - 2 * yycount + 1; { int yyi; for (yyi = 0; yyi < yycount; ++yyi) { YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return YYENOMEM; } } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return -1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); yyformat += 2; } else { ++yyp; ++yyformat; } } return 0; } /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, igraph_i_pajek_parsedata_t* context) { YY_USE (yyvaluep); YY_USE (yylocationp); YY_USE (context); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*----------. | yyparse. | `----------*/ int yyparse (igraph_i_pajek_parsedata_t* context) { /* Lookahead token kind. */ int yychar; /* The semantic value of the lookahead symbol. */ /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Location data for the lookahead symbol. */ static YYLTYPE yyloc_default # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL = { 1, 1, 1, 1 } # endif ; YYLTYPE yylloc = yyloc_default; /* Number of syntax errors so far. */ int yynerrs = 0; yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus = 0; /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* Their size. */ YYPTRDIFF_T yystacksize = YYINITDEPTH; /* The state stack: array, bottom, top. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss = yyssa; yy_state_t *yyssp = yyss; /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp = yyvs; /* The location stack: array, bottom, top. */ YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp = yyls; int yyn; /* The return value of yyparse. */ int yyresult; /* Lookahead symbol kind. */ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; /* The locations where the error started and ended. */ YYLTYPE yyerror_range[3]; /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ yylsp[0] = yylloc; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE YYNOMEM; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; YYLTYPE *yyls1 = yyls; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yyls1, yysize * YYSIZEOF (*yylsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; yyls = yyls1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) YYNOMEM; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) YYNOMEM; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; yylsp = yyls + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (&yylval, &yylloc, scanner); } if (yychar <= YYEOF) { yychar = YYEOF; yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else if (yychar == YYerror) { /* The scanner already issued an error message, process directly to error recovery. But do not keep the error token as lookahead, it is too special and may lead us to an endless loop in error recovery. */ yychar = YYUNDEF; yytoken = YYSYMBOL_YYerror; yyerror_range[1] = yylloc; goto yyerrlab1; } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END *++yylsp = yylloc; /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); yyerror_range[1] = yyloc; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: /* input: nethead vertices edgeblock */ #line 189 "src/core/io/pajek-parser.y" { if (context->vcount2 > 0) { igraph_i_pajek_check_bipartite(context); } } #line 1830 "yy.tab.c" break; case 6: /* verticeshead: VERTICESLINE longint */ #line 197 "src/core/io/pajek-parser.y" { context->vcount=(yyvsp[0].intnum); context->vcount2=0; } #line 1839 "yy.tab.c" break; case 7: /* verticeshead: VERTICESLINE longint longint */ #line 201 "src/core/io/pajek-parser.y" { context->vcount=(yyvsp[-1].intnum); context->vcount2=(yyvsp[0].intnum); igraph_i_pajek_add_bipartite_type(context); } #line 1849 "yy.tab.c" break; case 12: /* $@1: %empty */ #line 211 "src/core/io/pajek-parser.y" { context->actvertex=(yyvsp[0].intnum); } #line 1855 "yy.tab.c" break; case 13: /* vertexline: vertex $@1 vertexid vertexcoords shape params NEWLINE */ #line 211 "src/core/io/pajek-parser.y" { } #line 1861 "yy.tab.c" break; case 14: /* vertex: longint */ #line 214 "src/core/io/pajek-parser.y" { (yyval.intnum)=(yyvsp[0].intnum); context->mode=1; } #line 1867 "yy.tab.c" break; case 15: /* vertexid: word */ #line 216 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_string_vertex_attribute("id", (yyvsp[0].string).str, (yyvsp[0].string).len, context); igraph_i_pajek_add_string_vertex_attribute("name", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 1876 "yy.tab.c" break; case 17: /* vertexcoords: number number */ #line 222 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("x", (yyvsp[-1].realnum), context); igraph_i_pajek_add_numeric_vertex_attribute("y", (yyvsp[0].realnum), context); } #line 1885 "yy.tab.c" break; case 18: /* vertexcoords: number number number */ #line 226 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("x", (yyvsp[-2].realnum), context); igraph_i_pajek_add_numeric_vertex_attribute("y", (yyvsp[-1].realnum), context); igraph_i_pajek_add_numeric_vertex_attribute("z", (yyvsp[0].realnum), context); } #line 1895 "yy.tab.c" break; case 20: /* shape: word */ #line 232 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_string_vertex_attribute("shape", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 1903 "yy.tab.c" break; case 24: /* param: VP_X_FACT number */ #line 240 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("xfact", (yyvsp[0].realnum), context); } #line 1911 "yy.tab.c" break; case 25: /* param: VP_Y_FACT number */ #line 243 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("yfact", (yyvsp[0].realnum), context); } #line 1919 "yy.tab.c" break; case 26: /* param: VP_IC number number number */ #line 246 "src/core/io/pajek-parser.y" { /* RGB color */ igraph_i_pajek_add_numeric_vertex_attribute("color-red", (yyvsp[-2].realnum), context); igraph_i_pajek_add_numeric_vertex_attribute("color-green", (yyvsp[-1].realnum), context); igraph_i_pajek_add_numeric_vertex_attribute("color-blue", (yyvsp[0].realnum), context); } #line 1929 "yy.tab.c" break; case 27: /* param: VP_BC number number number */ #line 251 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("framecolor-red", (yyvsp[-2].realnum), context); igraph_i_pajek_add_numeric_vertex_attribute("framecolor-green", (yyvsp[-1].realnum), context); igraph_i_pajek_add_numeric_vertex_attribute("framecolor-blue", (yyvsp[0].realnum), context); } #line 1939 "yy.tab.c" break; case 28: /* param: VP_LC number number number */ #line 256 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("labelcolor-red", (yyvsp[-2].realnum), context); igraph_i_pajek_add_numeric_vertex_attribute("labelcolor-green", (yyvsp[-1].realnum), context); igraph_i_pajek_add_numeric_vertex_attribute("labelcolor-blue", (yyvsp[0].realnum), context); } #line 1949 "yy.tab.c" break; case 29: /* param: VP_LR number */ #line 261 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("labeldist", (yyvsp[0].realnum), context); } #line 1957 "yy.tab.c" break; case 30: /* param: VP_LPHI number */ #line 264 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("labeldegree2", (yyvsp[0].realnum), context); } #line 1965 "yy.tab.c" break; case 31: /* param: VP_BW number */ #line 267 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("framewidth", (yyvsp[0].realnum), context); } #line 1973 "yy.tab.c" break; case 32: /* param: VP_FOS number */ #line 270 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("fontsize", (yyvsp[0].realnum), context); } #line 1981 "yy.tab.c" break; case 33: /* param: VP_PHI number */ #line 273 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("rotation", (yyvsp[0].realnum), context); } #line 1989 "yy.tab.c" break; case 34: /* param: VP_R number */ #line 276 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("radius", (yyvsp[0].realnum), context); } #line 1997 "yy.tab.c" break; case 35: /* param: VP_Q number */ #line 279 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("diamondratio", (yyvsp[0].realnum), context); } #line 2005 "yy.tab.c" break; case 36: /* param: VP_LA number */ #line 282 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("labeldegree", (yyvsp[0].realnum), context); } #line 2013 "yy.tab.c" break; case 37: /* param: VP_SIZE number */ #line 285 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_vertex_attribute("vertexsize", (yyvsp[0].realnum), context); } #line 2021 "yy.tab.c" break; case 38: /* $@2: %empty */ #line 290 "src/core/io/pajek-parser.y" { context->mode=3; } #line 2027 "yy.tab.c" break; case 39: /* vpword: VP_FONT $@2 vpwordpar */ #line 290 "src/core/io/pajek-parser.y" { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("font", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2036 "yy.tab.c" break; case 40: /* $@3: %empty */ #line 294 "src/core/io/pajek-parser.y" { context->mode=3; } #line 2042 "yy.tab.c" break; case 41: /* vpword: VP_URL $@3 vpwordpar */ #line 294 "src/core/io/pajek-parser.y" { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("url", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2051 "yy.tab.c" break; case 42: /* $@4: %empty */ #line 298 "src/core/io/pajek-parser.y" { context->mode=3; } #line 2057 "yy.tab.c" break; case 43: /* vpword: VP_IC $@4 vpwordpar */ #line 298 "src/core/io/pajek-parser.y" { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("color", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2066 "yy.tab.c" break; case 44: /* $@5: %empty */ #line 302 "src/core/io/pajek-parser.y" { context->mode=3; } #line 2072 "yy.tab.c" break; case 45: /* vpword: VP_BC $@5 vpwordpar */ #line 302 "src/core/io/pajek-parser.y" { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("framecolor", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2082 "yy.tab.c" break; case 46: /* $@6: %empty */ #line 307 "src/core/io/pajek-parser.y" { context->mode=3; } #line 2088 "yy.tab.c" break; case 47: /* vpword: VP_LC $@6 vpwordpar */ #line 307 "src/core/io/pajek-parser.y" { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("labelcolor", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2098 "yy.tab.c" break; case 48: /* vpwordpar: word */ #line 314 "src/core/io/pajek-parser.y" { (yyval.string)=(yyvsp[0].string); } #line 2104 "yy.tab.c" break; case 55: /* arcs: ARCSLINE NEWLINE arcsdefs */ #line 318 "src/core/io/pajek-parser.y" { context->directed=1; } #line 2110 "yy.tab.c" break; case 56: /* arcs: ARCSLINE number NEWLINE arcsdefs */ #line 319 "src/core/io/pajek-parser.y" { context->directed=1; } #line 2116 "yy.tab.c" break; case 60: /* $@7: %empty */ #line 324 "src/core/io/pajek-parser.y" { context->actedge++; context->mode=2; } #line 2123 "yy.tab.c" break; case 61: /* arcsline: arcfrom arcto $@7 weight edgeparams NEWLINE */ #line 325 "src/core/io/pajek-parser.y" { igraph_vector_push_back(context->vector, (yyvsp[-5].intnum)-1); igraph_vector_push_back(context->vector, (yyvsp[-4].intnum)-1); } #line 2131 "yy.tab.c" break; case 64: /* edges: EDGESLINE NEWLINE edgesdefs */ #line 334 "src/core/io/pajek-parser.y" { context->directed=0; } #line 2137 "yy.tab.c" break; case 65: /* edges: EDGESLINE number NEWLINE edgesdefs */ #line 335 "src/core/io/pajek-parser.y" { context->directed=0; } #line 2143 "yy.tab.c" break; case 69: /* $@8: %empty */ #line 340 "src/core/io/pajek-parser.y" { context->actedge++; context->mode=2; } #line 2150 "yy.tab.c" break; case 70: /* edgesline: edgefrom edgeto $@8 weight edgeparams NEWLINE */ #line 341 "src/core/io/pajek-parser.y" { igraph_vector_push_back(context->vector, (yyvsp[-5].intnum)-1); igraph_vector_push_back(context->vector, (yyvsp[-4].intnum)-1); } #line 2158 "yy.tab.c" break; case 74: /* weight: number */ #line 350 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("weight", (yyvsp[0].realnum), context); } #line 2166 "yy.tab.c" break; case 78: /* edgeparam: EP_C number number number */ #line 358 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("color-red", (yyvsp[-2].realnum), context); igraph_i_pajek_add_numeric_edge_attribute("color-green", (yyvsp[-1].realnum), context); igraph_i_pajek_add_numeric_edge_attribute("color-blue", (yyvsp[0].realnum), context); } #line 2176 "yy.tab.c" break; case 79: /* edgeparam: EP_S number */ #line 363 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("arrowsize", (yyvsp[0].realnum), context); } #line 2184 "yy.tab.c" break; case 80: /* edgeparam: EP_W number */ #line 366 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("edgewidth", (yyvsp[0].realnum), context); } #line 2192 "yy.tab.c" break; case 81: /* edgeparam: EP_H1 number */ #line 369 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("hook1", (yyvsp[0].realnum), context); } #line 2200 "yy.tab.c" break; case 82: /* edgeparam: EP_H2 number */ #line 372 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("hook2", (yyvsp[0].realnum), context); } #line 2208 "yy.tab.c" break; case 83: /* edgeparam: EP_A1 number */ #line 375 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("angle1", (yyvsp[0].realnum), context); } #line 2216 "yy.tab.c" break; case 84: /* edgeparam: EP_A2 number */ #line 378 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("angle2", (yyvsp[0].realnum), context); } #line 2224 "yy.tab.c" break; case 85: /* edgeparam: EP_K1 number */ #line 381 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("velocity1", (yyvsp[0].realnum), context); } #line 2232 "yy.tab.c" break; case 86: /* edgeparam: EP_K2 number */ #line 384 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("velocity2", (yyvsp[0].realnum), context); } #line 2240 "yy.tab.c" break; case 87: /* edgeparam: EP_AP number */ #line 387 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("arrowpos", (yyvsp[0].realnum), context); } #line 2248 "yy.tab.c" break; case 88: /* edgeparam: EP_LP number */ #line 390 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("labelpos", (yyvsp[0].realnum), context); } #line 2256 "yy.tab.c" break; case 89: /* edgeparam: EP_LR number */ #line 393 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("labelangle", (yyvsp[0].realnum), context); } #line 2264 "yy.tab.c" break; case 90: /* edgeparam: EP_LPHI number */ #line 396 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("labelangle2", (yyvsp[0].realnum), context); } #line 2272 "yy.tab.c" break; case 91: /* edgeparam: EP_LA number */ #line 399 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("labeldegree", (yyvsp[0].realnum), context); } #line 2280 "yy.tab.c" break; case 92: /* edgeparam: EP_SIZE number */ #line 402 "src/core/io/pajek-parser.y" { /* what is this??? */ igraph_i_pajek_add_numeric_edge_attribute("arrowsize", (yyvsp[0].realnum), context); } #line 2288 "yy.tab.c" break; case 93: /* edgeparam: EP_FOS number */ #line 405 "src/core/io/pajek-parser.y" { igraph_i_pajek_add_numeric_edge_attribute("fontsize", (yyvsp[0].realnum), context); } #line 2296 "yy.tab.c" break; case 94: /* $@9: %empty */ #line 410 "src/core/io/pajek-parser.y" { context->mode=4; } #line 2302 "yy.tab.c" break; case 95: /* epword: EP_A $@9 epwordpar */ #line 410 "src/core/io/pajek-parser.y" { context->mode=2; igraph_i_pajek_add_string_edge_attribute("arrowtype", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2311 "yy.tab.c" break; case 96: /* $@10: %empty */ #line 414 "src/core/io/pajek-parser.y" { context->mode=4; } #line 2317 "yy.tab.c" break; case 97: /* epword: EP_P $@10 epwordpar */ #line 414 "src/core/io/pajek-parser.y" { context->mode=2; igraph_i_pajek_add_string_edge_attribute("linepattern", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2326 "yy.tab.c" break; case 98: /* $@11: %empty */ #line 418 "src/core/io/pajek-parser.y" { context->mode=4; } #line 2332 "yy.tab.c" break; case 99: /* epword: EP_L $@11 epwordpar */ #line 418 "src/core/io/pajek-parser.y" { context->mode=2; igraph_i_pajek_add_string_edge_attribute("label", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2341 "yy.tab.c" break; case 100: /* $@12: %empty */ #line 422 "src/core/io/pajek-parser.y" { context->mode=4; } #line 2347 "yy.tab.c" break; case 101: /* epword: EP_LC $@12 epwordpar */ #line 422 "src/core/io/pajek-parser.y" { context->mode=2; igraph_i_pajek_add_string_edge_attribute("labelcolor", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2356 "yy.tab.c" break; case 102: /* $@13: %empty */ #line 426 "src/core/io/pajek-parser.y" { context->mode=4; } #line 2362 "yy.tab.c" break; case 103: /* epword: EP_C $@13 epwordpar */ #line 426 "src/core/io/pajek-parser.y" { context->mode=2; igraph_i_pajek_add_string_edge_attribute("color", (yyvsp[0].string).str, (yyvsp[0].string).len, context); } #line 2371 "yy.tab.c" break; case 104: /* epwordpar: word */ #line 432 "src/core/io/pajek-parser.y" { context->mode=2; (yyval.string)=(yyvsp[0].string); } #line 2377 "yy.tab.c" break; case 105: /* arcslist: ARCSLISTLINE NEWLINE arcslistlines */ #line 434 "src/core/io/pajek-parser.y" { context->directed=1; } #line 2383 "yy.tab.c" break; case 112: /* arclistfrom: longint */ #line 442 "src/core/io/pajek-parser.y" { context->mode=0; context->actfrom=labs((yyvsp[0].intnum))-1; } #line 2389 "yy.tab.c" break; case 113: /* arclistto: longint */ #line 444 "src/core/io/pajek-parser.y" { igraph_vector_push_back(context->vector, context->actfrom); igraph_vector_push_back(context->vector, labs((yyvsp[0].intnum))-1); } #line 2398 "yy.tab.c" break; case 114: /* edgeslist: EDGESLISTLINE NEWLINE edgelistlines */ #line 449 "src/core/io/pajek-parser.y" { context->directed=0; } #line 2404 "yy.tab.c" break; case 121: /* edgelistfrom: longint */ #line 457 "src/core/io/pajek-parser.y" { context->mode=0; context->actfrom=labs((yyvsp[0].intnum))-1; } #line 2410 "yy.tab.c" break; case 122: /* edgelistto: longint */ #line 459 "src/core/io/pajek-parser.y" { igraph_vector_push_back(context->vector, context->actfrom); igraph_vector_push_back(context->vector, labs((yyvsp[0].intnum))-1); } #line 2419 "yy.tab.c" break; case 124: /* matrixline: MATRIXLINE */ #line 468 "src/core/io/pajek-parser.y" { context->actfrom=0; context->actto=0; context->directed=(context->vcount2==0); } #line 2428 "yy.tab.c" break; case 127: /* adjmatrixline: adjmatrixnumbers NEWLINE */ #line 475 "src/core/io/pajek-parser.y" { context->actfrom++; context->actto=0; } #line 2434 "yy.tab.c" break; case 130: /* adjmatrixentry: number */ #line 479 "src/core/io/pajek-parser.y" { if ((yyvsp[0].realnum) != 0) { if (context->vcount2==0) { context->actedge++; igraph_i_pajek_add_numeric_edge_attribute("weight", (yyvsp[0].realnum), context); igraph_vector_push_back(context->vector, context->actfrom); igraph_vector_push_back(context->vector, context->actto); } else if (context->vcount2 + context->actto < context->vcount) { context->actedge++; igraph_i_pajek_add_numeric_edge_attribute("weight", (yyvsp[0].realnum), context); igraph_vector_push_back(context->vector, context->actfrom); igraph_vector_push_back(context->vector, context->vcount2+context->actto); } } context->actto++; } #line 2456 "yy.tab.c" break; case 131: /* longint: NUM */ #line 499 "src/core/io/pajek-parser.y" { (yyval.intnum)=igraph_pajek_get_number(igraph_pajek_yyget_text(scanner), igraph_pajek_yyget_leng(scanner)); } #line 2463 "yy.tab.c" break; case 132: /* number: NUM */ #line 502 "src/core/io/pajek-parser.y" { (yyval.realnum)=igraph_pajek_get_number(igraph_pajek_yyget_text(scanner), igraph_pajek_yyget_leng(scanner)); } #line 2470 "yy.tab.c" break; case 135: /* word: ALNUM */ #line 507 "src/core/io/pajek-parser.y" { (yyval.string).str=igraph_pajek_yyget_text(scanner); (yyval.string).len=igraph_pajek_yyget_leng(scanner); } #line 2477 "yy.tab.c" break; case 136: /* word: NUM */ #line 509 "src/core/io/pajek-parser.y" { (yyval.string).str=igraph_pajek_yyget_text(scanner); (yyval.string).len=igraph_pajek_yyget_leng(scanner); } #line 2484 "yy.tab.c" break; case 137: /* word: QSTR */ #line 511 "src/core/io/pajek-parser.y" { (yyval.string).str=igraph_pajek_yyget_text(scanner)+1; (yyval.string).len=igraph_pajek_yyget_leng(scanner)-2; } #line 2491 "yy.tab.c" break; #line 2495 "yy.tab.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; *++yyvsp = yyval; *++yylsp = yyloc; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; { yypcontext_t yyctx = {yyssp, yytoken, &yylloc}; char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == -1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (yymsg) { yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); yymsgp = yymsg; } else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = YYENOMEM; } } yyerror (&yylloc, context, yymsgp); if (yysyntax_error_status == YYENOMEM) YYNOMEM; } } yyerror_range[1] = yylloc; if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, &yylloc, context); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYSYMBOL_YYerror; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yyerror_range[1] = *yylsp; yydestruct ("Error: popping", YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp, context); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END yyerror_range[2] = yylloc; ++yylsp; YYLLOC_DEFAULT (*yylsp, yyerror_range, 2); /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturnlab; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturnlab; /*-----------------------------------------------------------. | yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | `-----------------------------------------------------------*/ yyexhaustedlab: yyerror (&yylloc, context, YY_("memory exhausted")); yyresult = 2; goto yyreturnlab; /*----------------------------------------------------------. | yyreturnlab -- parsing is finished, clean up and return. | `----------------------------------------------------------*/ yyreturnlab: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, context); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp, context); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); return yyresult; } #line 514 "src/core/io/pajek-parser.y" int igraph_pajek_yyerror(YYLTYPE* locp, igraph_i_pajek_parsedata_t *context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char)-1, "Parse error in Pajek file, line %i (%s)", locp->first_line, s); return 0; } igraph_real_t igraph_pajek_get_number(const char *str, long int length) { igraph_real_t num; char *tmp=IGRAPH_CALLOC(length+1, char); strncpy(tmp, str, length); tmp[length]='\0'; sscanf(tmp, "%lf", &num); IGRAPH_FREE(tmp); return num; } /* TODO: NA's */ int igraph_i_pajek_add_numeric_attribute(igraph_trie_t *names, igraph_vector_ptr_t *attrs, long int count, const char *attrname, igraph_integer_t vid, igraph_real_t number) { long int attrsize=igraph_trie_size(names); long int id; igraph_vector_t *na; igraph_attribute_record_t *rec; igraph_trie_get(names, attrname, &id); if (id == attrsize) { /* add a new attribute */ rec=IGRAPH_CALLOC(1, igraph_attribute_record_t); na=IGRAPH_CALLOC(1, igraph_vector_t); igraph_vector_init(na, count); rec->name=strdup(attrname); rec->type=IGRAPH_ATTRIBUTE_NUMERIC; rec->value=na; igraph_vector_ptr_push_back(attrs, rec); } rec=VECTOR(*attrs)[id]; na=(igraph_vector_t*)rec->value; if (igraph_vector_size(na) == vid) { IGRAPH_CHECK(igraph_vector_push_back(na, number)); } else if (igraph_vector_size(na) < vid) { long int origsize=igraph_vector_size(na); IGRAPH_CHECK(igraph_vector_resize(na, (long int)vid+1)); for (;origsizename=strdup(attrname); rec->type=IGRAPH_ATTRIBUTE_STRING; rec->value=na; igraph_vector_ptr_push_back(attrs, rec); } rec=VECTOR(*attrs)[id]; na=(igraph_strvector_t*)rec->value; if (igraph_strvector_size(na) <= vid) { long int origsize=igraph_strvector_size(na); IGRAPH_CHECK(igraph_strvector_resize(na, vid+1)); for (;origsizevertex_attribute_names, context->vertex_attributes, context->vcount, name, context->actvertex-1, tmp); IGRAPH_FREE(tmp); IGRAPH_FINALLY_CLEAN(1); return ret; } int igraph_i_pajek_add_string_edge_attribute(const char *name, const char *value, int len, igraph_i_pajek_parsedata_t *context) { char *tmp; int ret; tmp=IGRAPH_CALLOC(len+1, char); if (tmp==0) { IGRAPH_ERROR("cannot add element to hash table", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmp); strncpy(tmp, value, len); tmp[len]='\0'; ret=igraph_i_pajek_add_string_attribute(context->edge_attribute_names, context->edge_attributes, context->actedge, name, context->actedge-1, tmp); IGRAPH_FREE(tmp); IGRAPH_FINALLY_CLEAN(1); return ret; } int igraph_i_pajek_add_numeric_vertex_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context) { return igraph_i_pajek_add_numeric_attribute(context->vertex_attribute_names, context->vertex_attributes, context->vcount, name, context->actvertex-1, value); } int igraph_i_pajek_add_numeric_edge_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context) { return igraph_i_pajek_add_numeric_attribute(context->edge_attribute_names, context->edge_attributes, context->actedge, name, context->actedge-1, value); } int igraph_i_pajek_add_bipartite_type(igraph_i_pajek_parsedata_t *context) { const char *attrname="type"; igraph_trie_t *names=context->vertex_attribute_names; igraph_vector_ptr_t *attrs=context->vertex_attributes; int i, n=context->vcount, n1=context->vcount2; long int attrid, attrsize=igraph_trie_size(names); igraph_attribute_record_t *rec; igraph_vector_t *na; if (n1 > n) { IGRAPH_ERROR("Invalid number of vertices in bipartite Pajek file", IGRAPH_PARSEERROR); } igraph_trie_get(names, attrname, &attrid); if (attrid != attrsize) { IGRAPH_ERROR("Duplicate 'type' attribute in Pajek file, " "this should not happen", IGRAPH_EINTERNAL); } /* add a new attribute */ rec=IGRAPH_CALLOC(1, igraph_attribute_record_t); na=IGRAPH_CALLOC(1, igraph_vector_t); igraph_vector_init(na, n); rec->name=strdup(attrname); rec->type=IGRAPH_ATTRIBUTE_NUMERIC; rec->value=na; igraph_vector_ptr_push_back(attrs, rec); for (i=0; ivector; int i, n1=context->vcount2; int ne=igraph_vector_size(edges); for (i=0; i n1 && v2 > n1) ) { IGRAPH_WARNING("Invalid edge in bipartite graph"); } } return 0; } leidenbase/src/core/io/lgl-parser.y0000644000176200001440000001032114447675374016757 0ustar liggesusers/* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" #include "config.h" #include "core/math.h" #include "io/lgl-header.h" #include "io/parsers/lgl-parser.h" #include "io/parsers/lgl-lexer.h" #include "internal/hacks.h" int igraph_lgl_yyerror(YYLTYPE* locp, igraph_i_lgl_parsedata_t *context, const char *s); igraph_real_t igraph_lgl_get_number(const char *str, long int len); #define scanner context->scanner %} %pure-parser /* bison: do not remove the equals sign; macOS XCode ships with bison 2.3, which * needs the equals sign */ %name-prefix="igraph_lgl_yy" %defines %locations %error-verbose %parse-param { igraph_i_lgl_parsedata_t* context } %lex-param { void *scanner } %union { long int edgenum; double weightnum; } %type edgeid %type weight %token ALNUM %token NEWLINE %token HASH %token ERROR %% input : /* empty */ | input NEWLINE | input vertex ; vertex : vertexdef edges ; vertexdef : HASH edgeid NEWLINE { context->actvertex=$2; } ; edges : /* empty */ | edges edge ; edge : edgeid NEWLINE { igraph_vector_push_back(context->vector, context->actvertex); igraph_vector_push_back(context->vector, $1); igraph_vector_push_back(context->weights, 0); } | edgeid weight NEWLINE { igraph_vector_push_back(context->vector, context->actvertex); igraph_vector_push_back(context->vector, $1); igraph_vector_push_back(context->weights, $2); context->has_weights = 1; } ; edgeid : ALNUM { igraph_trie_get2(context->trie, igraph_lgl_yyget_text(scanner), igraph_lgl_yyget_leng(scanner), &$$); }; weight : ALNUM { $$=igraph_lgl_get_number(igraph_lgl_yyget_text(scanner), igraph_lgl_yyget_leng(scanner)); } ; %% int igraph_lgl_yyerror(YYLTYPE* locp, igraph_i_lgl_parsedata_t *context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char), "Parse error in LGL file, line %i (%s)", locp->first_line, s); return 0; } igraph_real_t igraph_lgl_get_number(const char *str, long int length) { igraph_real_t num; char *tmp=IGRAPH_CALLOC(length+1, char); strncpy(tmp, str, length); tmp[length]='\0'; sscanf(tmp, "%lf", &num); IGRAPH_FREE(tmp); return num; } leidenbase/src/core/io/lgl-lexer.h0000644000176200001440000004213714447675375016574 0ustar liggesusers#ifndef igraph_lgl_yyHEADER_H #define igraph_lgl_yyHEADER_H 1 #define igraph_lgl_yyIN_HEADER 1 #line 6 "src/core/io/lgl-lexer.h" #line 8 "src/core/io/lgl-lexer.h" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_lgl_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_lgl_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_lgl_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_lgl_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_lgl_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_lgl_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_lgl_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_lgl_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_lgl_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_lgl_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_lgl_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_lgl_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_lgl_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_lgl_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_lgl_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_lgl_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_lgl_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_lgl_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_lgl_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_lgl_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_lgl_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_lgl_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_lgl_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_lgl_yyensure_buffer_stack #endif #ifdef yylex #define igraph_lgl_yylex_ALREADY_DEFINED #else #define yylex igraph_lgl_yylex #endif #ifdef yyrestart #define igraph_lgl_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_lgl_yyrestart #endif #ifdef yylex_init #define igraph_lgl_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_lgl_yylex_init #endif #ifdef yylex_init_extra #define igraph_lgl_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_lgl_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_lgl_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_lgl_yylex_destroy #endif #ifdef yyget_debug #define igraph_lgl_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_lgl_yyget_debug #endif #ifdef yyset_debug #define igraph_lgl_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_lgl_yyset_debug #endif #ifdef yyget_extra #define igraph_lgl_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_lgl_yyget_extra #endif #ifdef yyset_extra #define igraph_lgl_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_lgl_yyset_extra #endif #ifdef yyget_in #define igraph_lgl_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_lgl_yyget_in #endif #ifdef yyset_in #define igraph_lgl_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_lgl_yyset_in #endif #ifdef yyget_out #define igraph_lgl_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_lgl_yyget_out #endif #ifdef yyset_out #define igraph_lgl_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_lgl_yyset_out #endif #ifdef yyget_leng #define igraph_lgl_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_lgl_yyget_leng #endif #ifdef yyget_text #define igraph_lgl_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_lgl_yyget_text #endif #ifdef yyget_lineno #define igraph_lgl_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_lgl_yyget_lineno #endif #ifdef yyset_lineno #define igraph_lgl_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_lgl_yyset_lineno #endif #ifdef yyget_column #define igraph_lgl_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_lgl_yyget_column #endif #ifdef yyset_column #define igraph_lgl_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_lgl_yyset_column #endif #ifdef yywrap #define igraph_lgl_yywrap_ALREADY_DEFINED #else #define yywrap igraph_lgl_yywrap #endif #ifdef yyget_lval #define igraph_lgl_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_lgl_yyget_lval #endif #ifdef yyset_lval #define igraph_lgl_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_lgl_yyset_lval #endif #ifdef yyget_lloc #define igraph_lgl_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_lgl_yyget_lloc #endif #ifdef yyset_lloc #define igraph_lgl_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_lgl_yyset_lloc #endif #ifdef yyalloc #define igraph_lgl_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_lgl_yyalloc #endif #ifdef yyrealloc #define igraph_lgl_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_lgl_yyrealloc #endif #ifdef yyfree #define igraph_lgl_yyfree_ALREADY_DEFINED #else #define yyfree igraph_lgl_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); /* Begin user sect3 */ #define igraph_lgl_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP #define yytext_ptr yytext_r #ifdef YY_HEADER_EXPORT_START_CONDITIONS #define INITIAL 0 #endif #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* yy_get_previous_state - get the state just before the EOB char was reached */ #undef YY_NEW_FILE #undef YY_FLUSH_BUFFER #undef yy_set_bol #undef yy_new_buffer #undef yy_set_interactive #undef YY_DO_BEFORE_ACTION #ifdef YY_DECL_IS_OURS #undef YY_DECL_IS_OURS #undef YY_DECL #endif #ifndef igraph_lgl_yy_create_buffer_ALREADY_DEFINED #undef yy_create_buffer #endif #ifndef igraph_lgl_yy_delete_buffer_ALREADY_DEFINED #undef yy_delete_buffer #endif #ifndef igraph_lgl_yy_scan_buffer_ALREADY_DEFINED #undef yy_scan_buffer #endif #ifndef igraph_lgl_yy_scan_string_ALREADY_DEFINED #undef yy_scan_string #endif #ifndef igraph_lgl_yy_scan_bytes_ALREADY_DEFINED #undef yy_scan_bytes #endif #ifndef igraph_lgl_yy_init_buffer_ALREADY_DEFINED #undef yy_init_buffer #endif #ifndef igraph_lgl_yy_flush_buffer_ALREADY_DEFINED #undef yy_flush_buffer #endif #ifndef igraph_lgl_yy_load_buffer_state_ALREADY_DEFINED #undef yy_load_buffer_state #endif #ifndef igraph_lgl_yy_switch_to_buffer_ALREADY_DEFINED #undef yy_switch_to_buffer #endif #ifndef igraph_lgl_yypush_buffer_state_ALREADY_DEFINED #undef yypush_buffer_state #endif #ifndef igraph_lgl_yypop_buffer_state_ALREADY_DEFINED #undef yypop_buffer_state #endif #ifndef igraph_lgl_yyensure_buffer_stack_ALREADY_DEFINED #undef yyensure_buffer_stack #endif #ifndef igraph_lgl_yylex_ALREADY_DEFINED #undef yylex #endif #ifndef igraph_lgl_yyrestart_ALREADY_DEFINED #undef yyrestart #endif #ifndef igraph_lgl_yylex_init_ALREADY_DEFINED #undef yylex_init #endif #ifndef igraph_lgl_yylex_init_extra_ALREADY_DEFINED #undef yylex_init_extra #endif #ifndef igraph_lgl_yylex_destroy_ALREADY_DEFINED #undef yylex_destroy #endif #ifndef igraph_lgl_yyget_debug_ALREADY_DEFINED #undef yyget_debug #endif #ifndef igraph_lgl_yyset_debug_ALREADY_DEFINED #undef yyset_debug #endif #ifndef igraph_lgl_yyget_extra_ALREADY_DEFINED #undef yyget_extra #endif #ifndef igraph_lgl_yyset_extra_ALREADY_DEFINED #undef yyset_extra #endif #ifndef igraph_lgl_yyget_in_ALREADY_DEFINED #undef yyget_in #endif #ifndef igraph_lgl_yyset_in_ALREADY_DEFINED #undef yyset_in #endif #ifndef igraph_lgl_yyget_out_ALREADY_DEFINED #undef yyget_out #endif #ifndef igraph_lgl_yyset_out_ALREADY_DEFINED #undef yyset_out #endif #ifndef igraph_lgl_yyget_leng_ALREADY_DEFINED #undef yyget_leng #endif #ifndef igraph_lgl_yyget_text_ALREADY_DEFINED #undef yyget_text #endif #ifndef igraph_lgl_yyget_lineno_ALREADY_DEFINED #undef yyget_lineno #endif #ifndef igraph_lgl_yyset_lineno_ALREADY_DEFINED #undef yyset_lineno #endif #ifndef igraph_lgl_yyget_column_ALREADY_DEFINED #undef yyget_column #endif #ifndef igraph_lgl_yyset_column_ALREADY_DEFINED #undef yyset_column #endif #ifndef igraph_lgl_yywrap_ALREADY_DEFINED #undef yywrap #endif #ifndef igraph_lgl_yyget_lval_ALREADY_DEFINED #undef yyget_lval #endif #ifndef igraph_lgl_yyset_lval_ALREADY_DEFINED #undef yyset_lval #endif #ifndef igraph_lgl_yyget_lloc_ALREADY_DEFINED #undef yyget_lloc #endif #ifndef igraph_lgl_yyset_lloc_ALREADY_DEFINED #undef yyset_lloc #endif #ifndef igraph_lgl_yyalloc_ALREADY_DEFINED #undef yyalloc #endif #ifndef igraph_lgl_yyrealloc_ALREADY_DEFINED #undef yyrealloc #endif #ifndef igraph_lgl_yyfree_ALREADY_DEFINED #undef yyfree #endif #ifndef igraph_lgl_yytext_ALREADY_DEFINED #undef yytext #endif #ifndef igraph_lgl_yyleng_ALREADY_DEFINED #undef yyleng #endif #ifndef igraph_lgl_yyin_ALREADY_DEFINED #undef yyin #endif #ifndef igraph_lgl_yyout_ALREADY_DEFINED #undef yyout #endif #ifndef igraph_lgl_yy_flex_debug_ALREADY_DEFINED #undef yy_flex_debug #endif #ifndef igraph_lgl_yylineno_ALREADY_DEFINED #undef yylineno #endif #ifndef igraph_lgl_yytables_fload_ALREADY_DEFINED #undef yytables_fload #endif #ifndef igraph_lgl_yytables_destroy_ALREADY_DEFINED #undef yytables_destroy #endif #ifndef igraph_lgl_yyTABLES_NAME_ALREADY_DEFINED #undef yyTABLES_NAME #endif #line 101 "src/core/io/lgl-lexer.l" #line 735 "src/core/io/lgl-lexer.h" #undef igraph_lgl_yyIN_HEADER #endif /* igraph_lgl_yyHEADER_H */ leidenbase/src/core/io/ncol-header.h0000644000176200001440000000216114447675374017052 0ustar liggesusers/* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge MA, 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_error.h" #include "igraph_vector.h" #include "core/trie.h" typedef struct { void *scanner; int eof; char errmsg[300]; int has_weights; igraph_vector_t *vector; igraph_vector_t *weights; igraph_trie_t *trie; } igraph_i_ncol_parsedata_t; leidenbase/src/core/io/ncol-lexer.l0000644000176200001440000000562014447675374016750 0ustar liggesusers/* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "io/ncol-header.h" #include "io/parsers/ncol-parser.h" #define YY_EXTRA_TYPE igraph_i_ncol_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in NCOL parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif %} %option noyywrap %option prefix="igraph_ncol_yy" %option nounput %option noinput %option nodefault %option reentrant %option bison-bridge %option bison-locations alnum [^ \t\n\r\0] %% /* ------------------------------------------------whitespace------*/ [ \t]+ { } /* ---------------------------------------------------newline------*/ \n\r|\r\n|\n|\r { return NEWLINE; } /* ----------------------------------------------alphanumeric------*/ {alnum}+ { return ALNUM; } <> { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; return NEWLINE; } } /* ---------------------------------------------anything else------*/ . { return ERROR; } %% leidenbase/src/core/io/gml-parser.h0000644000176200001440000000636414447675375016754 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ #ifndef YY_IGRAPH_GML_YY_YY_TAB_H_INCLUDED # define YY_IGRAPH_GML_YY_YY_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int igraph_gml_yydebug; #endif /* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { YYEMPTY = -2, YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ STRING = 258, /* STRING */ NUM = 259, /* NUM */ KEYWORD = 260, /* KEYWORD */ LISTOPEN = 261, /* LISTOPEN */ LISTCLOSE = 262, /* LISTCLOSE */ EOFF = 263, /* EOFF */ ERROR = 264 /* ERROR */ }; typedef enum yytokentype yytoken_kind_t; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 91 "src/core/io/gml-parser.y" struct { char *s; int len; } str; void *tree; double real; #line 82 "yy.tab.h" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif /* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE YYLTYPE; struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; }; # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif int igraph_gml_yyparse (igraph_i_gml_parsedata_t* context); #endif /* !YY_IGRAPH_GML_YY_YY_TAB_H_INCLUDED */ leidenbase/src/core/io/pajek-lexer.l0000644000176200001440000001476714447675374017123 0ustar liggesusers/* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "io/pajek-header.h" #include "io/parsers/pajek-parser.h" #define YY_EXTRA_TYPE igraph_i_pajek_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in Pajek parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif %} %option noyywrap %option prefix="igraph_pajek_yy" %option nounput %option noinput %option nodefault %option reentrant %option bison-bridge %option bison-locations digit [0-9] word [^ \t\r\n\0] %% [ \t]+ { } %[^\n]*\n[\r]* { } %[^\n]*\r[\n]* { } \*[Nn][eE][Tt] { return NETWORKLINE; } \*[Nn][Ee][Tt][Ww][Oo][Rr][Kk] { return NETWORKLINE; } \*[Vv][Ee][Rr][Tt][Ii][Cc][Ee][Ss] { return VERTICESLINE; } \*[Aa][Rr][Cc][Ss] { return ARCSLINE; } \*[Ee][Dd][Gg][Ee][Ss] { return EDGESLINE; } \*[Aa][Rr][Cc][Ss][Ll][Ii][Ss][Tt] { return ARCSLISTLINE; } \*[Ee][Dd][Gg][Ee][Ss][Ll][Ii][Ss][Tt] { return EDGESLISTLINE; } \*[Mm][Aa][Tt][Rr][Ii][Xx] { return MATRIXLINE; } \n\r|\r\n|\n|\r { yyextra->mode=0; return NEWLINE; } \"[^\"]*\" { return QSTR; } \([^\)]*\) { return PSTR; } \-?{digit}+(\.{digit}+)?([eE](\+|\-)?{digit}+)? { return NUM; } [Xx]_[Ff][Aa][Cc][Tt]/[ \t\n\r] { if (yyextra->mode==1) { return VP_X_FACT; } else { return ALNUM; } } [Yy]_[Ff][Aa][Cc][Tt]/[ \t\n\r] { if (yyextra->mode==1) { return VP_Y_FACT; } else { return ALNUM; } } [Ii][Cc]/[ \t\n\r] { if (yyextra->mode==1) { return VP_IC; } else { return ALNUM; } } [Bb][Cc]/[ \t\n\r] { if (yyextra->mode==1) { return VP_BC; } else { return ALNUM; } } [Bb][Ww]/[ \t\n\r] { if (yyextra->mode==1) { return VP_BW; } else { return ALNUM; } } [Pp][Hh][Ii]/[ \t\n\r] { if (yyextra->mode==1) { return VP_PHI; } else { return ALNUM; } } [Rr]/[ \t\n\r] { if (yyextra->mode==1) { return VP_R; } else { return ALNUM; } } [Qq]/[ \t\n\r] { if (yyextra->mode==1) { return VP_Q; } else { return ALNUM; } } [Ff][Oo][Nn][Tt]/[ \t\n\r] { if (yyextra->mode==1) { return VP_FONT; } else { return ALNUM; } } [Uu][Rr][Ll]/[ \t\n\r] { if (yyextra->mode==1) { return VP_URL; } else { return ALNUM; } } [Cc]/[ \t\n\r] { if (yyextra->mode==2) { return EP_C; } else { return ALNUM; } } [Pp]/[ \t\n\r] { if (yyextra->mode==2) { return EP_P; } else { return ALNUM; } } [Ss]/[ \t\n\r] { if (yyextra->mode==2) { return EP_S; } else { return ALNUM; } } [Aa]/[ \t\n\r] { if (yyextra->mode==2) { return EP_A; } else { return ALNUM; } } [Ww]/[ \t\n\r] { if (yyextra->mode==2) { return EP_W; } else { return ALNUM; } } [Hh]1/[ \t\n\r] { if (yyextra->mode==2) { return EP_H1; } else { return ALNUM; } } [Hh]2/[ \t\n\r] { if (yyextra->mode==2) { return EP_H2; } else { return ALNUM; } } [Aa]1/[ \t\n\r] { if (yyextra->mode==2) { return EP_A1; } else { return ALNUM; } } [Aa]2/[ \t\n\r] { if (yyextra->mode==2) { return EP_A2; } else { return ALNUM; } } [Kk]1/[ \t\n\r] { if (yyextra->mode==2) { return EP_K1; } else { return ALNUM; } } [Kk]2/[ \t\n\r] { if (yyextra->mode==2) { return EP_K2; } else { return ALNUM; } } [Aa][Pp]/[ \t\n\r] { if (yyextra->mode==2) { return EP_AP; } else { return ALNUM; } } [Ll]/[ \t\n\r] { if (yyextra->mode==2) { return EP_L; } else { return ALNUM; } } [Ll][Pp]/[ \t\n\r] { if (yyextra->mode==2) { return EP_LP; } else { return ALNUM; } } [Ll][Pp][Hh][Ii]/[ \t\n\r] { if (yyextra->mode==1) { return VP_LPHI; } else if (yyextra->mode==2) { return EP_LPHI; } else { return ALNUM; } } [Ll][Cc]/[ \t\n\r] { if (yyextra->mode==1) { return VP_LC; } else if (yyextra->mode==2) { return EP_LC; } else { return ALNUM; } } [Ll][Rr]/[ \t\n\r] { if (yyextra->mode==1) { return VP_LR; } else if (yyextra->mode==2) { return EP_LR; } else { return ALNUM; } } [Ll][Aa]/[ \t\n\r] { if (yyextra->mode==1) { return VP_LA; } else if (yyextra->mode==2) { return EP_LA; } else { return ALNUM; } } [Ss][Ii][Zz][Ee]/[ \t\n\r] { if (yyextra->mode==1) { return VP_SIZE; } else if (yyextra->mode==2) { return EP_SIZE; } else { return ALNUM; } } [Ff][Oo][Ss]/[ \t\n\r] { if (yyextra->mode==1) { return VP_FOS; } else if (yyextra->mode==2) { return EP_FOS; } else { return ALNUM; } } {word}+ { return ALNUM; } <> { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; return NEWLINE; } } . { return ERROR; } %% leidenbase/src/core/io/dimacs.c0000644000176200001440000002626414447675374016136 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_iterators.h" #include "core/interruption.h" #include /** * \function igraph_read_graph_dimacs * \brief Read a graph in DIMACS format. * * This function reads the DIMACS file format, more specifically the * version for network flow problems, see the files at * ftp://dimacs.rutgers.edu/pub/netflow/general-info/ * * * This is a line-oriented text file (ASCII) format. The first * character of each line defines the type of the line. If the first * character is c the line is a comment line and it is * ignored. There is one problem line (p in the file, it * must appear before any node and arc descriptor lines. The problem * line has three fields separated by spaces: the problem type * (min, max or asn), the * number of vertices and number of edges in the graph. * Exactly two node identification lines are expected * (n), one for the source, one for the target vertex. * These have two fields: the id of the vertex and the type of the * vertex, either s (=source) or t * (=target). Arc lines start with a and have three * fields: the source vertex, the target vertex and the edge capacity. * * * Vertex ids are numbered from 1. * \param graph Pointer to an uninitialized graph object. * \param instream The file to read from. * \param source Pointer to an integer, the id of the source node will * be stored here. (The igraph vertex id, which is one less than * the actual number in the file.) It is ignored if * NULL. * \param target Pointer to an integer, the (igraph) id of the target * node will be stored here. It is ignored if NULL. * \param capacity Pointer to an initialized vector, the capacity of * the edges will be stored here if not NULL. * \param directed Boolean, whether to create a directed graph. * \return Error code. * * Time complexity: O(|V|+|E|+c), the number of vertices plus the * number of edges, plus the size of the file in characters. * * \sa \ref igraph_write_graph_dimacs() */ int igraph_read_graph_dimacs(igraph_t *graph, FILE *instream, igraph_strvector_t *problem, igraph_vector_t *label, igraph_integer_t *source, igraph_integer_t *target, igraph_vector_t *capacity, igraph_bool_t directed) { igraph_vector_t edges; long int no_of_nodes = -1; long int no_of_edges = -1; long int tsource = -1; long int ttarget = -1; char prob[21]; char c; int problem_type = 0; #define PROBLEM_EDGE 1 #define PROBLEM_MAX 2 IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); if (capacity) { igraph_vector_clear(capacity); } while (!feof(instream)) { int read; char str[3]; IGRAPH_ALLOW_INTERRUPTION(); read = fscanf(instream, "%2c", str); if (feof(instream)) { break; } if (read != 1) { IGRAPH_ERROR("parsing dimacs file failed", IGRAPH_PARSEERROR); } switch (str[0]) { long int tmp, tmp2; long int from, to; igraph_real_t cap; case 'c': /* comment */ break; case 'p': if (no_of_nodes != -1) { IGRAPH_ERROR("reading dimacs file failed, double 'p' line", IGRAPH_PARSEERROR); } read = fscanf(instream, "%20s %li %li", prob, &no_of_nodes, &no_of_edges); if (read != 3) { IGRAPH_ERROR("reading dimacs file failed", IGRAPH_PARSEERROR); } if (!strcmp(prob, "edge")) { /* edge list */ problem_type = PROBLEM_EDGE; if (label) { long int i; IGRAPH_CHECK(igraph_vector_resize(label, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { VECTOR(*label)[i] = i + 1; } } } else if (!strcmp(prob, "max")) { /* maximum flow problem */ problem_type = PROBLEM_MAX; if (capacity) { IGRAPH_CHECK(igraph_vector_reserve(capacity, no_of_edges)); } } else { IGRAPH_ERROR("Unknown problem type, should be 'edge' or 'max'", IGRAPH_PARSEERROR); } if (problem) { igraph_strvector_clear(problem); IGRAPH_CHECK(igraph_strvector_add(problem, prob)); } IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges * 2)); break; case 'n': /* for MAX this is either the source or target vertex, for EDGE this is a vertex label */ if (problem_type == PROBLEM_MAX) { str[0] = 'x'; read = fscanf(instream, "%li %1s", &tmp, str); if (str[0] == 's') { if (tsource != -1) { IGRAPH_ERROR("reading dimacsfile: multiple source vertex line", IGRAPH_PARSEERROR); } else { tsource = tmp; } } else if (str[0] == 't') { if (ttarget != -1) { IGRAPH_ERROR("reading dimacsfile: multiple target vertex line", IGRAPH_PARSEERROR); } else { ttarget = tmp; } } else { IGRAPH_ERROR("invalid node descriptor line in dimacs file", IGRAPH_PARSEERROR); } } else { read = fscanf(instream, "%li %li", &tmp, &tmp2); if (label) { VECTOR(*label)[tmp] = tmp2; } } break; case 'a': /* This is valid only for MAX, a weighted edge */ if (problem_type != PROBLEM_MAX) { IGRAPH_ERROR("'a' lines are allowed only in MAX problem files", IGRAPH_PARSEERROR); } read = fscanf(instream, "%li %li %lf", &from, &to, &cap); if (read != 3) { IGRAPH_ERROR("reading dimacs file", IGRAPH_PARSEERROR); } IGRAPH_CHECK(igraph_vector_push_back(&edges, from - 1)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to - 1)); if (capacity) { IGRAPH_CHECK(igraph_vector_push_back(capacity, cap)); } break; case 'e': /* Edge line, only in EDGE */ if (problem_type != PROBLEM_EDGE) { IGRAPH_ERROR("'e' lines are allowed only in EDGE problem files", IGRAPH_PARSEERROR); } read = fscanf(instream, "%li %li", &from, &to); if (read != 2) { IGRAPH_ERROR("reading dimacs file", IGRAPH_PARSEERROR); } IGRAPH_CHECK(igraph_vector_push_back(&edges, from - 1)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to - 1)); break; default: IGRAPH_ERROR("unknown line type in dimacs file", IGRAPH_PARSEERROR); } /* Go to next line */ while (!feof(instream) && (c = (char) getc(instream)) != '\n') ; } if (source) { *source = (igraph_integer_t) tsource - 1; } if (target) { *target = (igraph_integer_t) ttarget - 1; } IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_write_graph_dimacs * \brief Write a graph in DIMACS format. * * This function writes a graph to an output stream in DIMACS format, * describing a maximum flow problem. * See ftp://dimacs.rutgers.edu/pub/netflow/general-info/ * * * This file format is discussed in the documentation of \ref * igraph_read_graph_dimacs(), see that for more information. * * \param graph The graph to write to the stream. * \param outstream The stream. * \param source Integer, the id of the source vertex for the maximum * flow. * \param target Integer, the id of the target vertex. * \param capacity Pointer to an initialized vector containing the * edge capacity values. * \return Error code. * * Time complexity: O(|E|), the number of edges in the graph. * * \sa igraph_read_graph_dimacs() */ int igraph_write_graph_dimacs(const igraph_t *graph, FILE *outstream, long int source, long int target, const igraph_vector_t *capacity) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_eit_t it; long int i = 0; int ret, ret1, ret2, ret3; if (igraph_vector_size(capacity) != no_of_edges) { IGRAPH_ERROR("invalid capacity vector length", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID), &it)); IGRAPH_FINALLY(igraph_eit_destroy, &it); ret = fprintf(outstream, "c created by igraph\np max %li %li\nn %li s\nn %li t\n", no_of_nodes, no_of_edges, source + 1, target + 1); if (ret < 0) { IGRAPH_ERROR("Write error", IGRAPH_EFILE); } while (!IGRAPH_EIT_END(it)) { igraph_integer_t from, to; igraph_real_t cap; igraph_edge(graph, IGRAPH_EIT_GET(it), &from, &to); cap = VECTOR(*capacity)[i++]; ret1 = fprintf(outstream, "a %li %li ", (long int) from + 1, (long int) to + 1); ret2 = igraph_real_fprintf_precise(outstream, cap); ret3 = fputc('\n', outstream); if (ret1 < 0 || ret2 < 0 || ret3 == EOF) { IGRAPH_ERROR("Write error", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } igraph_eit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/io/ncol-parser.c0000644000176200001440000016102414447675375017116 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ #define YYBISON 30802 /* Bison version string. */ #define YYBISON_VERSION "3.8.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Substitute the variable and function names. */ #define yyparse igraph_ncol_yyparse #define yylex igraph_ncol_yylex #define yyerror igraph_ncol_yyerror #define yydebug igraph_ncol_yydebug #define yynerrs igraph_ncol_yynerrs /* First part of user prologue. */ #line 23 "src/core/io/ncol-parser.y" /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" #include "config.h" #include "core/math.h" #include "io/ncol-header.h" #include "io/ncol-parser.h" #include "io/ncol-lexer.h" #include "internal/hacks.h" int igraph_ncol_yyerror(YYLTYPE* locp, igraph_i_ncol_parsedata_t *context, const char *s); igraph_real_t igraph_ncol_get_number(const char *str, long int len); #define scanner context->scanner #line 122 "yy.tab.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif #include "io/ncol-parser.h" /* Symbol kind. */ enum yysymbol_kind_t { YYSYMBOL_YYEMPTY = -2, YYSYMBOL_YYEOF = 0, /* "end of file" */ YYSYMBOL_YYerror = 1, /* error */ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ YYSYMBOL_ALNUM = 3, /* ALNUM */ YYSYMBOL_NEWLINE = 4, /* NEWLINE */ YYSYMBOL_ERROR = 5, /* ERROR */ YYSYMBOL_YYACCEPT = 6, /* $accept */ YYSYMBOL_input = 7, /* input */ YYSYMBOL_edge = 8, /* edge */ YYSYMBOL_edgeid = 9, /* edgeid */ YYSYMBOL_weight = 10 /* weight */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif /* Work around bug in HP-UX 11.23, which defines these macros incorrectly for preprocessor constants. This workaround can likely be removed in 2023, as HPE has promised support for HP-UX 11.23 (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of . */ #ifdef __hpux # undef UINT_LEAST8_MAX # undef UINT_LEAST16_MAX # define UINT_LEAST8_MAX 255 # define UINT_LEAST16_MAX 65535 #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_int8 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YY_USE(E) ((void) (E)) #else # define YY_USE(E) /* empty */ #endif /* Suppress an incorrect diagnostic about yylval being uninitialized. */ #if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ # if __GNUC__ * 100 + __GNUC_MINOR__ < 407 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") # else # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # endif # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if 1 /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* 1 */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ + YYSIZEOF (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 10 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 6 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 5 /* YYNRULES -- Number of rules. */ #define YYNRULES 8 /* YYNSTATES -- Number of states. */ #define YYNSTATES 12 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 260 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK \ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int8 yyrline[] = { 0, 93, 93, 94, 95, 98, 103, 111, 116 }; #endif /** Accessing symbol of state STATE. */ #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) #if 1 /* The user-facing name of the symbol whose (internal) number is YYSYMBOL. No bounds checking. */ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "\"end of file\"", "error", "\"invalid token\"", "ALNUM", "NEWLINE", "ERROR", "$accept", "input", "edge", "edgeid", "weight", YY_NULLPTR }; static const char * yysymbol_name (yysymbol_kind_t yysymbol) { return yytname[yysymbol]; } #endif #define YYPACT_NINF (-3) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-1) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int8 yypact[] = { -3, 0, -3, -3, -3, -3, 2, -2, -3, -3, 3, -3 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_int8 yydefact[] = { 2, 0, 1, 7, 3, 4, 0, 0, 8, 5, 0, 6 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -3, -3, -3, 4, -3 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { 0, 1, 5, 6, 10 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { 2, 8, 9, 3, 4, 3, 0, 11, 0, 0, 7 }; static const yytype_int8 yycheck[] = { 0, 3, 4, 3, 4, 3, -1, 4, -1, -1, 6 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { 0, 7, 0, 3, 4, 8, 9, 9, 3, 4, 10, 4 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int8 yyr1[] = { 0, 6, 7, 7, 7, 8, 8, 9, 10 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ static const yytype_int8 yyr2[] = { 0, 2, 0, 2, 2, 3, 4, 1, 1 }; enum { YYENOMEM = -2 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Backward compatibility with an undocumented macro. Use YYerror or YYUNDEF. */ #define YYERRCODE YYUNDEF /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (N) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (0) #endif #define YYRHSLOC(Rhs, K) ((Rhs)[K]) /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* YYLOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ # ifndef YYLOCATION_PRINT # if defined YY_LOCATION_PRINT /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc)) # elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL /* Print *YYLOCP on YYO. Private, do not rely on its existence. */ YY_ATTRIBUTE_UNUSED static int yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) { int res = 0; int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; if (0 <= yylocp->first_line) { res += YYFPRINTF (yyo, "%d", yylocp->first_line); if (0 <= yylocp->first_column) res += YYFPRINTF (yyo, ".%d", yylocp->first_column); } if (0 <= yylocp->last_line) { if (yylocp->first_line < yylocp->last_line) { res += YYFPRINTF (yyo, "-%d", yylocp->last_line); if (0 <= end_col) res += YYFPRINTF (yyo, ".%d", end_col); } else if (0 <= end_col && yylocp->first_column < end_col) res += YYFPRINTF (yyo, "-%d", end_col); } return res; } # define YYLOCATION_PRINT yy_location_print_ /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc)) # else # define YYLOCATION_PRINT(File, Loc) ((void) 0) /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT YYLOCATION_PRINT # endif # endif /* !defined YYLOCATION_PRINT */ # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Kind, Value, Location, context); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_ncol_parsedata_t* context) { FILE *yyoutput = yyo; YY_USE (yyoutput); YY_USE (yylocationp); YY_USE (context); if (!yyvaluep) return; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_ncol_parsedata_t* context) { YYFPRINTF (yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); YYLOCATION_PRINT (yyo, yylocationp); YYFPRINTF (yyo, ": "); yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp, context); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, igraph_i_ncol_parsedata_t* context) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), &yyvsp[(yyi + 1) - (yynrhs)], &(yylsp[(yyi + 1) - (yynrhs)]), context); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, yylsp, Rule, context); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) ((void) 0) # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif /* Context of a parse error. */ typedef struct { yy_state_t *yyssp; yysymbol_kind_t yytoken; YYLTYPE *yylloc; } yypcontext_t; /* Put in YYARG at most YYARGN of the expected tokens given the current YYCTX, and return the number of tokens stored in YYARG. If YYARG is null, return the number of expected tokens (guaranteed to be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. Return 0 if there are more than YYARGN expected tokens, yet fill YYARG up to YYARGN. */ static int yypcontext_expected_tokens (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; int yyn = yypact[+*yyctx->yyssp]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror && !yytable_value_is_error (yytable[yyx + yyn])) { if (!yyarg) ++yycount; else if (yycount == yyargn) return 0; else yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); } } if (yyarg && yycount == 0 && 0 < yyargn) yyarg[0] = YYSYMBOL_YYEMPTY; return yycount; } #ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) { YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif #endif #ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif #endif #ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; else goto append; append: default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (yyres) return yystpcpy (yyres, yystr) - yyres; else return yystrlen (yystr); } #endif static int yy_syntax_error_arguments (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yyctx->yytoken != YYSYMBOL_YYEMPTY) { int yyn; if (yyarg) yyarg[yycount] = yyctx->yytoken; ++yycount; yyn = yypcontext_expected_tokens (yyctx, yyarg ? yyarg + 1 : yyarg, yyargn - 1); if (yyn == YYENOMEM) return YYENOMEM; else yycount += yyn; } return yycount; } /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the required number of bytes is too large to store. */ static int yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, const yypcontext_t *yyctx) { enum { YYARGS_MAX = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ yysymbol_kind_t yyarg[YYARGS_MAX]; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; /* Actual size of YYARG. */ int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); if (yycount == YYENOMEM) return YYENOMEM; switch (yycount) { #define YYCASE_(N, S) \ case N: \ yyformat = S; \ break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); #undef YYCASE_ } /* Compute error message size. Don't count the "%s"s, but reserve room for the terminator. */ yysize = yystrlen (yyformat) - 2 * yycount + 1; { int yyi; for (yyi = 0; yyi < yycount; ++yyi) { YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return YYENOMEM; } } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return -1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); yyformat += 2; } else { ++yyp; ++yyformat; } } return 0; } /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, igraph_i_ncol_parsedata_t* context) { YY_USE (yyvaluep); YY_USE (yylocationp); YY_USE (context); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*----------. | yyparse. | `----------*/ int yyparse (igraph_i_ncol_parsedata_t* context) { /* Lookahead token kind. */ int yychar; /* The semantic value of the lookahead symbol. */ /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Location data for the lookahead symbol. */ static YYLTYPE yyloc_default # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL = { 1, 1, 1, 1 } # endif ; YYLTYPE yylloc = yyloc_default; /* Number of syntax errors so far. */ int yynerrs = 0; yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus = 0; /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* Their size. */ YYPTRDIFF_T yystacksize = YYINITDEPTH; /* The state stack: array, bottom, top. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss = yyssa; yy_state_t *yyssp = yyss; /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp = yyvs; /* The location stack: array, bottom, top. */ YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp = yyls; int yyn; /* The return value of yyparse. */ int yyresult; /* Lookahead symbol kind. */ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; /* The locations where the error started and ended. */ YYLTYPE yyerror_range[3]; /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ yylsp[0] = yylloc; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE YYNOMEM; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; YYLTYPE *yyls1 = yyls; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yyls1, yysize * YYSIZEOF (*yylsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; yyls = yyls1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) YYNOMEM; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) YYNOMEM; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; yylsp = yyls + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (&yylval, &yylloc, scanner); } if (yychar <= YYEOF) { yychar = YYEOF; yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else if (yychar == YYerror) { /* The scanner already issued an error message, process directly to error recovery. But do not keep the error token as lookahead, it is too special and may lead us to an endless loop in error recovery. */ yychar = YYUNDEF; yytoken = YYSYMBOL_YYerror; yyerror_range[1] = yylloc; goto yyerrlab1; } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END *++yylsp = yylloc; /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); yyerror_range[1] = yyloc; YY_REDUCE_PRINT (yyn); switch (yyn) { case 5: /* edge: edgeid edgeid NEWLINE */ #line 98 "src/core/io/ncol-parser.y" { igraph_vector_push_back(context->vector, (yyvsp[-2].edgenum)); igraph_vector_push_back(context->vector, (yyvsp[-1].edgenum)); igraph_vector_push_back(context->weights, 0); } #line 1512 "yy.tab.c" break; case 6: /* edge: edgeid edgeid weight NEWLINE */ #line 103 "src/core/io/ncol-parser.y" { igraph_vector_push_back(context->vector, (yyvsp[-3].edgenum)); igraph_vector_push_back(context->vector, (yyvsp[-2].edgenum)); igraph_vector_push_back(context->weights, (yyvsp[-1].weightnum)); context->has_weights = 1; } #line 1523 "yy.tab.c" break; case 7: /* edgeid: ALNUM */ #line 111 "src/core/io/ncol-parser.y" { igraph_trie_get2(context->trie, igraph_ncol_yyget_text(scanner), igraph_ncol_yyget_leng(scanner), &(yyval.edgenum)); } #line 1532 "yy.tab.c" break; case 8: /* weight: ALNUM */ #line 116 "src/core/io/ncol-parser.y" { (yyval.weightnum)=igraph_ncol_get_number(igraph_ncol_yyget_text(scanner), igraph_ncol_yyget_leng(scanner)); } #line 1539 "yy.tab.c" break; #line 1543 "yy.tab.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; *++yyvsp = yyval; *++yylsp = yyloc; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; { yypcontext_t yyctx = {yyssp, yytoken, &yylloc}; char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == -1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (yymsg) { yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); yymsgp = yymsg; } else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = YYENOMEM; } } yyerror (&yylloc, context, yymsgp); if (yysyntax_error_status == YYENOMEM) YYNOMEM; } } yyerror_range[1] = yylloc; if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, &yylloc, context); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYSYMBOL_YYerror; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yyerror_range[1] = *yylsp; yydestruct ("Error: popping", YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp, context); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END yyerror_range[2] = yylloc; ++yylsp; YYLLOC_DEFAULT (*yylsp, yyerror_range, 2); /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturnlab; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturnlab; /*-----------------------------------------------------------. | yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | `-----------------------------------------------------------*/ yyexhaustedlab: yyerror (&yylloc, context, YY_("memory exhausted")); yyresult = 2; goto yyreturnlab; /*----------------------------------------------------------. | yyreturnlab -- parsing is finished, clean up and return. | `----------------------------------------------------------*/ yyreturnlab: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, context); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp, context); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); return yyresult; } #line 119 "src/core/io/ncol-parser.y" int igraph_ncol_yyerror(YYLTYPE* locp, igraph_i_ncol_parsedata_t *context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char)-1, "Parse error in NCOL file, line %i (%s)", locp->first_line, s); return 0; } igraph_real_t igraph_ncol_get_number(const char *str, long int length) { igraph_real_t num; char *tmp=IGRAPH_CALLOC(length+1, char); strncpy(tmp, str, length); tmp[length]='\0'; sscanf(tmp, "%lf", &num); IGRAPH_FREE(tmp); return num; } leidenbase/src/core/io/lgl-parser.h0000644000176200001440000000606314447675375016747 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ #ifndef YY_IGRAPH_LGL_YY_YY_TAB_H_INCLUDED # define YY_IGRAPH_LGL_YY_YY_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int igraph_lgl_yydebug; #endif /* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { YYEMPTY = -2, YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ ALNUM = 258, /* ALNUM */ NEWLINE = 259, /* NEWLINE */ HASH = 260, /* HASH */ ERROR = 261 /* ERROR */ }; typedef enum yytokentype yytoken_kind_t; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 78 "src/core/io/lgl-parser.y" long int edgenum; double weightnum; #line 75 "yy.tab.h" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif /* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE YYLTYPE; struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; }; # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif int igraph_lgl_yyparse (igraph_i_lgl_parsedata_t* context); #endif /* !YY_IGRAPH_LGL_YY_YY_TAB_H_INCLUDED */ leidenbase/src/core/io/ncol-parser.y0000644000176200001440000001000514447675374017133 0ustar liggesusers/* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" #include "config.h" #include "core/math.h" #include "io/ncol-header.h" #include "io/parsers/ncol-parser.h" #include "io/parsers/ncol-lexer.h" #include "internal/hacks.h" int igraph_ncol_yyerror(YYLTYPE* locp, igraph_i_ncol_parsedata_t *context, const char *s); igraph_real_t igraph_ncol_get_number(const char *str, long int len); #define scanner context->scanner %} %pure-parser /* bison: do not remove the equals sign; macOS XCode ships with bison 2.3, which * needs the equals sign */ %name-prefix="igraph_ncol_yy" %defines %locations %error-verbose %parse-param { igraph_i_ncol_parsedata_t* context } %lex-param { void *scanner } %union { long int edgenum; double weightnum; } %type edgeid %type weight %token ALNUM %token NEWLINE %token ERROR %% input : /* empty */ | input NEWLINE | input edge ; edge : edgeid edgeid NEWLINE { igraph_vector_push_back(context->vector, $1); igraph_vector_push_back(context->vector, $2); igraph_vector_push_back(context->weights, 0); } | edgeid edgeid weight NEWLINE { igraph_vector_push_back(context->vector, $1); igraph_vector_push_back(context->vector, $2); igraph_vector_push_back(context->weights, $3); context->has_weights = 1; } ; edgeid : ALNUM { igraph_trie_get2(context->trie, igraph_ncol_yyget_text(scanner), igraph_ncol_yyget_leng(scanner), &$$); }; weight : ALNUM { $$=igraph_ncol_get_number(igraph_ncol_yyget_text(scanner), igraph_ncol_yyget_leng(scanner)); } ; %% int igraph_ncol_yyerror(YYLTYPE* locp, igraph_i_ncol_parsedata_t *context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char)-1, "Parse error in NCOL file, line %i (%s)", locp->first_line, s); return 0; } igraph_real_t igraph_ncol_get_number(const char *str, long int length) { igraph_real_t num; char *tmp=IGRAPH_CALLOC(length+1, char); strncpy(tmp, str, length); tmp[length]='\0'; sscanf(tmp, "%lf", &num); IGRAPH_FREE(tmp); return num; } leidenbase/src/core/io/ncol.c0000644000176200001440000003434414447675374015627 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_attributes.h" #include "igraph_interface.h" #include "graph/attributes.h" #include "ncol-header.h" int igraph_ncol_yylex_init_extra (igraph_i_ncol_parsedata_t* user_defined, void* scanner); void igraph_ncol_yylex_destroy (void *scanner ); int igraph_ncol_yyparse (igraph_i_ncol_parsedata_t* context); void igraph_ncol_yyset_in (FILE * in_str, void* yyscanner ); /** * \ingroup loadsave * \function igraph_read_graph_ncol * \brief Reads an .ncol file used by LGL. * * Also useful for creating graphs from \quote named\endquote (and * optionally weighted) edge lists. * * * This format is used by the Large Graph Layout program * (http://lgl.sourceforge.net), and it is simply a * symbolic weighted edge list. It is a simple text file with one edge * per line. An edge is defined by two symbolic vertex names separated * by whitespace. The vertex names themselves cannot contain * whitespace. They may be followed by an optional number, * the weight of the edge; the number can be negative and can be in * scientific notation. If there is no weight specified to an edge it * is assumed to be zero. * * * The resulting graph is always undirected. * LGL cannot deal with files which contain multiple or loop edges, * this is however not checked here, as \a igraph is happy with * these. * * \param graph Pointer to an uninitialized graph object. * \param instream Pointer to a stream, it should be readable. * \param predefnames Pointer to the symbolic names of the vertices in * the file. If \c NULL is given here then vertex ids will be * assigned to vertex names in the order of their appearance in * the .ncol file. If it is not \c NULL and some unknown * vertex names are found in the .ncol file then new vertex * ids will be assigned to them. * \param names Logical value, if TRUE the symbolic names of the * vertices will be added to the graph as a vertex attribute * called \quote name\endquote. * \param weights Whether to add the weights of the edges to the * graph as an edge attribute called \quote weight\endquote. * \c IGRAPH_ADD_WEIGHTS_YES adds the weights (even if they * are not present in the file, in this case they are assumed * to be zero). \c IGRAPH_ADD_WEIGHTS_NO does not add any * edge attribute. \c IGRAPH_ADD_WEIGHTS_IF_PRESENT adds the * attribute if and only if there is at least one explicit * edge weight in the input file. * \param directed Whether to create a directed graph. As this format * was originally used only for undirected graphs there is no * information in the file about the directedness of the graph. * Set this parameter to \c IGRAPH_DIRECTED or \c * IGRAPH_UNDIRECTED to create a directed or undirected graph. * \return Error code: * \c IGRAPH_PARSEERROR: if there is a * problem reading * the file, or the file is syntactically incorrect. * * Time complexity: * O(|V|+|E|log(|V|)) if we neglect * the time required by the parsing. As usual * |V| is the number of vertices, * while |E| is the number of edges. * * \sa \ref igraph_read_graph_lgl(), \ref igraph_write_graph_ncol() */ int igraph_read_graph_ncol(igraph_t *graph, FILE *instream, const igraph_strvector_t *predefnames, igraph_bool_t names, igraph_add_weights_t weights, igraph_bool_t directed) { igraph_vector_t edges, ws; igraph_trie_t trie = IGRAPH_TRIE_NULL; igraph_integer_t no_of_nodes; long int no_predefined = 0; igraph_vector_ptr_t name, weight; igraph_vector_ptr_t *pname = 0, *pweight = 0; igraph_attribute_record_t namerec, weightrec; const char *namestr = "name", *weightstr = "weight"; igraph_i_ncol_parsedata_t context; IGRAPH_CHECK(igraph_empty(graph, 0, directed)); IGRAPH_FINALLY(igraph_destroy, graph); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_TRIE_INIT_FINALLY(&trie, names); IGRAPH_VECTOR_INIT_FINALLY(&ws, 0); /* Add the predefined names, if any */ if (predefnames != 0) { long int i, id, n; char *key; n = no_predefined = igraph_strvector_size(predefnames); for (i = 0; i < n; i++) { igraph_strvector_get(predefnames, i, &key); igraph_trie_get(&trie, key, &id); if (id != i) { IGRAPH_WARNING("reading NCOL file, duplicate entry in predefnames"); no_predefined--; } } } context.has_weights = 0; context.vector = &edges; context.weights = &ws; context.trie = ≜ context.eof = 0; igraph_ncol_yylex_init_extra(&context, &context.scanner); IGRAPH_FINALLY(igraph_ncol_yylex_destroy, context.scanner); igraph_ncol_yyset_in(instream, context.scanner); if (igraph_ncol_yyparse(&context)) { if (context.errmsg[0] != 0) { IGRAPH_ERROR(context.errmsg, IGRAPH_PARSEERROR); } else { IGRAPH_ERROR("Cannot read NCOL file", IGRAPH_PARSEERROR); } } if (predefnames != 0 && igraph_trie_size(&trie) != no_predefined) { IGRAPH_WARNING("unknown vertex/vertices found, predefnames extended"); } if (names) { const igraph_strvector_t *namevec; IGRAPH_CHECK(igraph_vector_ptr_init(&name, 1)); pname = &name; igraph_trie_getkeys(&trie, &namevec); /* dirty */ namerec.name = namestr; namerec.type = IGRAPH_ATTRIBUTE_STRING; namerec.value = namevec; VECTOR(name)[0] = &namerec; } if (weights == IGRAPH_ADD_WEIGHTS_YES || (weights == IGRAPH_ADD_WEIGHTS_IF_PRESENT && context.has_weights)) { IGRAPH_CHECK(igraph_vector_ptr_init(&weight, 1)); pweight = &weight; weightrec.name = weightstr; weightrec.type = IGRAPH_ATTRIBUTE_NUMERIC; weightrec.value = &ws; VECTOR(weight)[0] = &weightrec; } if (igraph_vector_empty(&edges)) { no_of_nodes = 0; } else { no_of_nodes = igraph_vector_max(&edges) + 1; } IGRAPH_CHECK(igraph_add_vertices(graph, no_of_nodes, pname)); IGRAPH_CHECK(igraph_add_edges(graph, &edges, pweight)); if (pname) { igraph_vector_ptr_destroy(pname); } if (pweight) { igraph_vector_ptr_destroy(pweight); } igraph_vector_destroy(&ws); igraph_trie_destroy(&trie); igraph_vector_destroy(&edges); igraph_ncol_yylex_destroy(context.scanner); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \ingroup loadsave * \function igraph_write_graph_ncol * \brief Writes the graph to a file in .ncol format. * * * .ncol is a format used by LGL, see \ref * igraph_read_graph_ncol() for details. * * * Note that having multiple or loop edges in an * .ncol file breaks the LGL software but * \a igraph does not check for this condition. * * * This format cannot represent zero-degree vertices. * * \param graph The graph to write. * \param outstream The stream object to write to, it should be * writable. * \param names The name of a string vertex attribute, if symbolic names * are to be written to the file. Supply \c NULL to write vertex * ids instead. * \param weights The name of a numerical edge attribute, which will be * written as weights to the file. Supply \c NULL to skip writing * edge weights. * \return Error code: * \c IGRAPH_EFILE if there is an error writing the * file. * * Time complexity: O(|E|), the * number of edges. All file operations are expected to have time * complexity O(1). * * \sa \ref igraph_read_graph_ncol(), \ref igraph_write_graph_lgl() */ int igraph_write_graph_ncol(const igraph_t *graph, FILE *outstream, const char *names, const char *weights) { igraph_eit_t it; igraph_attribute_type_t nametype, weighttype; IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_FROM), &it)); IGRAPH_FINALLY(igraph_eit_destroy, &it); /* Check if we have the names attribute */ if (names && !igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, names)) { names = 0; IGRAPH_WARNING("names attribute does not exists"); } if (names) { IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &nametype, IGRAPH_ATTRIBUTE_VERTEX, names)); if (nametype != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_WARNING("ignoring names attribute, unknown attribute type"); names = 0; } } /* Check the weights as well */ if (weights && !igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, weights)) { weights = 0; IGRAPH_WARNING("weights attribute does not exists"); } if (weights) { IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &weighttype, IGRAPH_ATTRIBUTE_EDGE, weights)); if (weighttype != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_WARNING("ignoring weights attribute, unknown attribute type"); weights = 0; } } if (names == 0 && weights == 0) { /* No names, no weights */ while (!IGRAPH_EIT_END(it)) { igraph_integer_t from, to; int ret; igraph_edge(graph, IGRAPH_EIT_GET(it), &from, &to); ret = fprintf(outstream, "%li %li\n", (long int) from, (long int) to); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } } else if (weights == 0) { /* No weights, but use names */ igraph_strvector_t nvec; IGRAPH_CHECK(igraph_strvector_init(&nvec, igraph_vcount(graph))); IGRAPH_FINALLY(igraph_strvector_destroy, &nvec); IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr(graph, names, igraph_vss_all(), &nvec)); while (!IGRAPH_EIT_END(it)) { igraph_integer_t edge = IGRAPH_EIT_GET(it); igraph_integer_t from, to; int ret = 0; char *str1, *str2; igraph_edge(graph, edge, &from, &to); igraph_strvector_get(&nvec, from, &str1); igraph_strvector_get(&nvec, to, &str2); ret = fprintf(outstream, "%s %s\n", str1, str2); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } igraph_strvector_destroy(&nvec); IGRAPH_FINALLY_CLEAN(1); } else if (names == 0) { /* No names but weights */ igraph_vector_t wvec; IGRAPH_VECTOR_INIT_FINALLY(&wvec, igraph_ecount(graph)); IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr(graph, weights, igraph_ess_all(IGRAPH_EDGEORDER_ID), &wvec)); while (!IGRAPH_EIT_END(it)) { igraph_integer_t edge = IGRAPH_EIT_GET(it); igraph_integer_t from, to; int ret1, ret2, ret3; igraph_edge(graph, edge, &from, &to); ret1 = fprintf(outstream, "%li %li ", (long int)from, (long int)to); ret2 = igraph_real_fprintf_precise(outstream, VECTOR(wvec)[(long int)edge]); ret3 = fputc('\n', outstream); if (ret1 < 0 || ret2 < 0 || ret3 == EOF) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } igraph_vector_destroy(&wvec); IGRAPH_FINALLY_CLEAN(1); } else { /* Both names and weights */ igraph_strvector_t nvec; igraph_vector_t wvec; IGRAPH_VECTOR_INIT_FINALLY(&wvec, igraph_ecount(graph)); IGRAPH_CHECK(igraph_strvector_init(&nvec, igraph_vcount(graph))); IGRAPH_FINALLY(igraph_strvector_destroy, &nvec); IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr(graph, weights, igraph_ess_all(IGRAPH_EDGEORDER_ID), &wvec)); IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr(graph, names, igraph_vss_all(), &nvec)); while (!IGRAPH_EIT_END(it)) { igraph_integer_t edge = IGRAPH_EIT_GET(it); igraph_integer_t from, to; int ret = 0, ret2 = 0; char *str1, *str2; igraph_edge(graph, edge, &from, &to); igraph_strvector_get(&nvec, from, &str1); igraph_strvector_get(&nvec, to, &str2); ret = fprintf(outstream, "%s %s ", str1, str2); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = igraph_real_fprintf_precise(outstream, VECTOR(wvec)[(long int)edge]); ret2 = fputc('\n', outstream); if (ret < 0 || ret2 == EOF) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } igraph_strvector_destroy(&nvec); igraph_vector_destroy(&wvec); IGRAPH_FINALLY_CLEAN(2); } igraph_eit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/io/edgelist.c0000644000176200001440000001201714447675374016465 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_iterators.h" #include "core/interruption.h" #include /** * \section about_loadsave * * These functions can write a graph to a file, or read a graph * from a file. * * Note that as \a igraph uses the traditional C streams, it is * possible to read/write files from/to memory, at least on GNU * operating systems supporting \quote non-standard\endquote streams. */ /** * \ingroup loadsave * \function igraph_read_graph_edgelist * \brief Reads an edge list from a file and creates a graph. * * * This format is simply a series of an even number of non-negative integers separated by * whitespace. The integers represent vertex IDs. Placing each edge (i.e. pair of integers) * on a separate line is not required, but it is recommended for readability. * Edges of directed graphs are assumed to be in "from, to" order. * \param graph Pointer to an uninitialized graph object. * \param instream Pointer to a stream, it should be readable. * \param n The number of vertices in the graph. If smaller than the * largest integer in the file it will be ignored. It is thus * safe to supply zero here. * \param directed Logical, if true the graph is directed, if false it * will be undirected. * \return Error code: * \c IGRAPH_PARSEERROR: if there is a * problem reading the file, or the file is syntactically * incorrect. * * Time complexity: O(|V|+|E|), the * number of vertices plus the number of edges. It is assumed that * reading an integer requires O(1) * time. */ int igraph_read_graph_edgelist(igraph_t *graph, FILE *instream, igraph_integer_t n, igraph_bool_t directed) { igraph_vector_t edges = IGRAPH_VECTOR_NULL; long int from, to; int c; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_CHECK(igraph_vector_reserve(&edges, 100)); /* skip all whitespace */ do { c = getc (instream); } while (isspace (c)); ungetc (c, instream); while (!feof(instream)) { int read; IGRAPH_ALLOW_INTERRUPTION(); read = fscanf(instream, "%li", &from); if (read != 1) { IGRAPH_ERROR("parsing edgelist file failed", IGRAPH_PARSEERROR); } read = fscanf(instream, "%li", &to); if (read != 1) { IGRAPH_ERROR("parsing edgelist file failed", IGRAPH_PARSEERROR); } IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); /* skip all whitespace */ do { c = getc (instream); } while (isspace (c)); ungetc (c, instream); } IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \ingroup loadsave * \function igraph_write_graph_edgelist * \brief Writes the edge list of a graph to a file. * * * One edge is written per line, separated by a single space. * For directed graphs edges are written in from, to order. * \param graph The graph object to write. * \param outstream Pointer to a stream, it should be writable. * \return Error code: * \c IGRAPH_EFILE if there is an error writing the * file. * * Time complexity: O(|E|), the * number of edges in the graph. It is assumed that writing an * integer to the file requires O(1) * time. */ int igraph_write_graph_edgelist(const igraph_t *graph, FILE *outstream) { igraph_eit_t it; IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_FROM), &it)); IGRAPH_FINALLY(igraph_eit_destroy, &it); while (!IGRAPH_EIT_END(it)) { igraph_integer_t from, to; int ret; igraph_edge(graph, IGRAPH_EIT_GET(it), &from, &to); ret = fprintf(outstream, "%li %li\n", (long int) from, (long int) to); if (ret < 0) { IGRAPH_ERROR("Write error", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } igraph_eit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/io/gml-lexer.h0000644000176200001440000004213714447675375016575 0ustar liggesusers#ifndef igraph_gml_yyHEADER_H #define igraph_gml_yyHEADER_H 1 #define igraph_gml_yyIN_HEADER 1 #line 6 "src/core/io/gml-lexer.h" #line 8 "src/core/io/gml-lexer.h" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_gml_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_gml_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_gml_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_gml_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_gml_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_gml_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_gml_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_gml_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_gml_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_gml_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_gml_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_gml_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_gml_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_gml_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_gml_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_gml_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_gml_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_gml_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_gml_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_gml_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_gml_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_gml_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_gml_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_gml_yyensure_buffer_stack #endif #ifdef yylex #define igraph_gml_yylex_ALREADY_DEFINED #else #define yylex igraph_gml_yylex #endif #ifdef yyrestart #define igraph_gml_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_gml_yyrestart #endif #ifdef yylex_init #define igraph_gml_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_gml_yylex_init #endif #ifdef yylex_init_extra #define igraph_gml_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_gml_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_gml_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_gml_yylex_destroy #endif #ifdef yyget_debug #define igraph_gml_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_gml_yyget_debug #endif #ifdef yyset_debug #define igraph_gml_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_gml_yyset_debug #endif #ifdef yyget_extra #define igraph_gml_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_gml_yyget_extra #endif #ifdef yyset_extra #define igraph_gml_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_gml_yyset_extra #endif #ifdef yyget_in #define igraph_gml_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_gml_yyget_in #endif #ifdef yyset_in #define igraph_gml_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_gml_yyset_in #endif #ifdef yyget_out #define igraph_gml_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_gml_yyget_out #endif #ifdef yyset_out #define igraph_gml_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_gml_yyset_out #endif #ifdef yyget_leng #define igraph_gml_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_gml_yyget_leng #endif #ifdef yyget_text #define igraph_gml_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_gml_yyget_text #endif #ifdef yyget_lineno #define igraph_gml_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_gml_yyget_lineno #endif #ifdef yyset_lineno #define igraph_gml_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_gml_yyset_lineno #endif #ifdef yyget_column #define igraph_gml_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_gml_yyget_column #endif #ifdef yyset_column #define igraph_gml_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_gml_yyset_column #endif #ifdef yywrap #define igraph_gml_yywrap_ALREADY_DEFINED #else #define yywrap igraph_gml_yywrap #endif #ifdef yyget_lval #define igraph_gml_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_gml_yyget_lval #endif #ifdef yyset_lval #define igraph_gml_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_gml_yyset_lval #endif #ifdef yyget_lloc #define igraph_gml_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_gml_yyget_lloc #endif #ifdef yyset_lloc #define igraph_gml_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_gml_yyset_lloc #endif #ifdef yyalloc #define igraph_gml_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_gml_yyalloc #endif #ifdef yyrealloc #define igraph_gml_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_gml_yyrealloc #endif #ifdef yyfree #define igraph_gml_yyfree_ALREADY_DEFINED #else #define yyfree igraph_gml_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); /* Begin user sect3 */ #define igraph_gml_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP #define yytext_ptr yytext_r #ifdef YY_HEADER_EXPORT_START_CONDITIONS #define INITIAL 0 #endif #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* yy_get_previous_state - get the state just before the EOB char was reached */ #undef YY_NEW_FILE #undef YY_FLUSH_BUFFER #undef yy_set_bol #undef yy_new_buffer #undef yy_set_interactive #undef YY_DO_BEFORE_ACTION #ifdef YY_DECL_IS_OURS #undef YY_DECL_IS_OURS #undef YY_DECL #endif #ifndef igraph_gml_yy_create_buffer_ALREADY_DEFINED #undef yy_create_buffer #endif #ifndef igraph_gml_yy_delete_buffer_ALREADY_DEFINED #undef yy_delete_buffer #endif #ifndef igraph_gml_yy_scan_buffer_ALREADY_DEFINED #undef yy_scan_buffer #endif #ifndef igraph_gml_yy_scan_string_ALREADY_DEFINED #undef yy_scan_string #endif #ifndef igraph_gml_yy_scan_bytes_ALREADY_DEFINED #undef yy_scan_bytes #endif #ifndef igraph_gml_yy_init_buffer_ALREADY_DEFINED #undef yy_init_buffer #endif #ifndef igraph_gml_yy_flush_buffer_ALREADY_DEFINED #undef yy_flush_buffer #endif #ifndef igraph_gml_yy_load_buffer_state_ALREADY_DEFINED #undef yy_load_buffer_state #endif #ifndef igraph_gml_yy_switch_to_buffer_ALREADY_DEFINED #undef yy_switch_to_buffer #endif #ifndef igraph_gml_yypush_buffer_state_ALREADY_DEFINED #undef yypush_buffer_state #endif #ifndef igraph_gml_yypop_buffer_state_ALREADY_DEFINED #undef yypop_buffer_state #endif #ifndef igraph_gml_yyensure_buffer_stack_ALREADY_DEFINED #undef yyensure_buffer_stack #endif #ifndef igraph_gml_yylex_ALREADY_DEFINED #undef yylex #endif #ifndef igraph_gml_yyrestart_ALREADY_DEFINED #undef yyrestart #endif #ifndef igraph_gml_yylex_init_ALREADY_DEFINED #undef yylex_init #endif #ifndef igraph_gml_yylex_init_extra_ALREADY_DEFINED #undef yylex_init_extra #endif #ifndef igraph_gml_yylex_destroy_ALREADY_DEFINED #undef yylex_destroy #endif #ifndef igraph_gml_yyget_debug_ALREADY_DEFINED #undef yyget_debug #endif #ifndef igraph_gml_yyset_debug_ALREADY_DEFINED #undef yyset_debug #endif #ifndef igraph_gml_yyget_extra_ALREADY_DEFINED #undef yyget_extra #endif #ifndef igraph_gml_yyset_extra_ALREADY_DEFINED #undef yyset_extra #endif #ifndef igraph_gml_yyget_in_ALREADY_DEFINED #undef yyget_in #endif #ifndef igraph_gml_yyset_in_ALREADY_DEFINED #undef yyset_in #endif #ifndef igraph_gml_yyget_out_ALREADY_DEFINED #undef yyget_out #endif #ifndef igraph_gml_yyset_out_ALREADY_DEFINED #undef yyset_out #endif #ifndef igraph_gml_yyget_leng_ALREADY_DEFINED #undef yyget_leng #endif #ifndef igraph_gml_yyget_text_ALREADY_DEFINED #undef yyget_text #endif #ifndef igraph_gml_yyget_lineno_ALREADY_DEFINED #undef yyget_lineno #endif #ifndef igraph_gml_yyset_lineno_ALREADY_DEFINED #undef yyset_lineno #endif #ifndef igraph_gml_yyget_column_ALREADY_DEFINED #undef yyget_column #endif #ifndef igraph_gml_yyset_column_ALREADY_DEFINED #undef yyset_column #endif #ifndef igraph_gml_yywrap_ALREADY_DEFINED #undef yywrap #endif #ifndef igraph_gml_yyget_lval_ALREADY_DEFINED #undef yyget_lval #endif #ifndef igraph_gml_yyset_lval_ALREADY_DEFINED #undef yyset_lval #endif #ifndef igraph_gml_yyget_lloc_ALREADY_DEFINED #undef yyget_lloc #endif #ifndef igraph_gml_yyset_lloc_ALREADY_DEFINED #undef yyset_lloc #endif #ifndef igraph_gml_yyalloc_ALREADY_DEFINED #undef yyalloc #endif #ifndef igraph_gml_yyrealloc_ALREADY_DEFINED #undef yyrealloc #endif #ifndef igraph_gml_yyfree_ALREADY_DEFINED #undef yyfree #endif #ifndef igraph_gml_yytext_ALREADY_DEFINED #undef yytext #endif #ifndef igraph_gml_yyleng_ALREADY_DEFINED #undef yyleng #endif #ifndef igraph_gml_yyin_ALREADY_DEFINED #undef yyin #endif #ifndef igraph_gml_yyout_ALREADY_DEFINED #undef yyout #endif #ifndef igraph_gml_yy_flex_debug_ALREADY_DEFINED #undef yy_flex_debug #endif #ifndef igraph_gml_yylineno_ALREADY_DEFINED #undef yylineno #endif #ifndef igraph_gml_yytables_fload_ALREADY_DEFINED #undef yytables_fload #endif #ifndef igraph_gml_yytables_destroy_ALREADY_DEFINED #undef yytables_destroy #endif #ifndef igraph_gml_yyTABLES_NAME_ALREADY_DEFINED #undef yyTABLES_NAME #endif #line 112 "src/core/io/gml-lexer.l" #line 735 "src/core/io/gml-lexer.h" #undef igraph_gml_yyIN_HEADER #endif /* igraph_gml_yyHEADER_H */ leidenbase/src/core/io/gml.c0000644000176200001440000007772114447675375015462 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_attributes.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_version.h" #include "core/trie.h" #include "graph/attributes.h" #include "io/gml-header.h" #include #include #include int igraph_gml_yylex_init_extra (igraph_i_gml_parsedata_t* user_defined, void* scanner); void igraph_gml_yylex_destroy (void *scanner ); int igraph_gml_yyparse (igraph_i_gml_parsedata_t* context); void igraph_gml_yyset_in (FILE * in_str, void* yyscanner ); static void igraph_i_gml_destroy_attrs(igraph_vector_ptr_t **ptr) { long int i; igraph_vector_ptr_t *vec; for (i = 0; i < 3; i++) { long int j; vec = ptr[i]; for (j = 0; j < igraph_vector_ptr_size(vec); j++) { igraph_attribute_record_t *atrec = VECTOR(*vec)[j]; if (atrec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *value = (igraph_vector_t*)atrec->value; if (value != 0) { igraph_vector_destroy(value); IGRAPH_FREE(value); } } else { igraph_strvector_t *value = (igraph_strvector_t*)atrec->value; if (value != 0) { igraph_strvector_destroy(value); IGRAPH_FREE(value); } } IGRAPH_FREE(atrec->name); IGRAPH_FREE(atrec); } igraph_vector_ptr_destroy(vec); } } static int igraph_i_gml_toreal(igraph_gml_tree_t *node, long int pos, igraph_real_t *result) { igraph_real_t value = 0.0; int type = igraph_gml_tree_type(node, pos); switch (type) { case IGRAPH_I_GML_TREE_INTEGER: value = igraph_gml_tree_get_integer(node, pos); break; case IGRAPH_I_GML_TREE_REAL: value = igraph_gml_tree_get_real(node, pos); break; default: IGRAPH_ERROR("Internal error while parsing GML file.", IGRAPH_FAILURE); break; } *result = value; return IGRAPH_SUCCESS; } static const char *igraph_i_gml_tostring(igraph_gml_tree_t *node, long int pos) { int type = igraph_gml_tree_type(node, pos); static char tmp[256]; const char *p = tmp; long int i; igraph_real_t d; switch (type) { case IGRAPH_I_GML_TREE_INTEGER: i = igraph_gml_tree_get_integer(node, pos); snprintf(tmp, sizeof(tmp) / sizeof(char), "%li", i); break; case IGRAPH_I_GML_TREE_REAL: d = igraph_gml_tree_get_real(node, pos); igraph_real_snprintf_precise(tmp, sizeof(tmp) / sizeof(char), d); break; case IGRAPH_I_GML_TREE_STRING: p = igraph_gml_tree_get_string(node, pos); break; default: break; } return p; } int igraph_i_gml_parsedata_init(igraph_i_gml_parsedata_t* context) { context->eof = 0; context->depth = 0; context->scanner = 0; context->tree = 0; context->errmsg[0] = 0; return IGRAPH_SUCCESS; } void igraph_i_gml_parsedata_destroy(igraph_i_gml_parsedata_t* context) { if (context->tree != 0) { igraph_gml_tree_destroy(context->tree); context->tree = 0; } if (context->scanner != 0) { igraph_gml_yylex_destroy(context->scanner); context->scanner = 0; } } /** * \function igraph_read_graph_gml * \brief Read a graph in GML format. * * GML is a simple textual format, see * http://www.fim.uni-passau.de/en/fim/faculty/chairs/theoretische-informatik/projects.html for details. * * * Although all syntactically correct GML can be parsed, * we implement only a subset of this format, some attributes might be * ignored. Here is a list of all the differences: * \olist * \oli Only node and edge attributes are * used, and only if they have a simple type: integer, real or * string. So if an attribute is an array or a record, then it is * ignored. This is also true if only some values of the * attribute are complex. * \oli Top level attributes except for Version and the * first graph attribute are completely ignored. * \oli Graph attributes except for node and * edge are completely ignored. * \oli There is no maximum line length. * \oli There is no maximum keyword length. * \oli Character entities in strings are not interpreted. * \oli We allow inf (infinity) and nan * (not a number) as a real number. This is case insensitive, so * nan, NaN and NAN are equal. * \endolist * * Please contact us if you cannot live with these * limitations of the GML parser. * \param graph Pointer to an uninitialized graph object. * \param instream The stream to read the GML file from. * \return Error code. * * Time complexity: should be proportional to the length of the file. * * \sa \ref igraph_read_graph_graphml() for a more modern format, * \ref igraph_write_graph_gml() for writing GML files. * * \example examples/simple/gml.c */ int igraph_read_graph_gml(igraph_t *graph, FILE *instream) { long int i, p; long int no_of_nodes = 0, no_of_edges = 0; igraph_trie_t trie; igraph_vector_t edges; igraph_bool_t directed = IGRAPH_UNDIRECTED; igraph_gml_tree_t *gtree; long int gidx; igraph_trie_t vattrnames; igraph_trie_t eattrnames; igraph_trie_t gattrnames; igraph_vector_ptr_t gattrs = IGRAPH_VECTOR_PTR_NULL, vattrs = IGRAPH_VECTOR_PTR_NULL, eattrs = IGRAPH_VECTOR_PTR_NULL; igraph_vector_ptr_t *attrs[3]; long int edgeptr = 0; igraph_i_gml_parsedata_t context; attrs[0] = &gattrs; attrs[1] = &vattrs; attrs[2] = &eattrs; IGRAPH_CHECK(igraph_i_gml_parsedata_init(&context)); IGRAPH_FINALLY(igraph_i_gml_parsedata_destroy, &context); igraph_gml_yylex_init_extra(&context, &context.scanner); igraph_gml_yyset_in(instream, context.scanner); i = igraph_gml_yyparse(&context); if (i != 0) { if (context.errmsg[0] != 0) { IGRAPH_ERROR(context.errmsg, IGRAPH_PARSEERROR); } else { IGRAPH_ERROR("Cannot read GML file.", IGRAPH_PARSEERROR); } } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); /* Check version, if present, integer and not '1' then ignored */ i = igraph_gml_tree_find(context.tree, "Version", 0); if (i >= 0 && igraph_gml_tree_type(context.tree, i) == IGRAPH_I_GML_TREE_INTEGER && igraph_gml_tree_get_integer(context.tree, i) != 1) { IGRAPH_ERROR("Unknown GML version.", IGRAPH_UNIMPLEMENTED); /* RETURN HERE!!!! */ } /* get the graph */ gidx = igraph_gml_tree_find(context.tree, "graph", 0); if (gidx == -1) { IGRAPH_ERROR("No 'graph' object in GML file.", IGRAPH_PARSEERROR); } if (igraph_gml_tree_type(context.tree, gidx) != IGRAPH_I_GML_TREE_TREE) { IGRAPH_ERROR("Invalid type for 'graph' object in GML file.", IGRAPH_PARSEERROR); } gtree = igraph_gml_tree_get_tree(context.tree, gidx); IGRAPH_FINALLY(igraph_i_gml_destroy_attrs, attrs); igraph_vector_ptr_init(&gattrs, 0); igraph_vector_ptr_init(&vattrs, 0); igraph_vector_ptr_init(&eattrs, 0); IGRAPH_TRIE_INIT_FINALLY(&trie, 0); IGRAPH_TRIE_INIT_FINALLY(&vattrnames, 0); IGRAPH_TRIE_INIT_FINALLY(&eattrnames, 0); IGRAPH_TRIE_INIT_FINALLY(&gattrnames, 0); /* Is is directed? */ i = igraph_gml_tree_find(gtree, "directed", 0); if (i >= 0 && igraph_gml_tree_type(gtree, i) == IGRAPH_I_GML_TREE_INTEGER) { if (igraph_gml_tree_get_integer(gtree, i) == 1) { directed = IGRAPH_DIRECTED; } } /* Now we go over all objects in the graph and collect the attribute names and types. Plus we collect node ids. We also do some checks. */ for (i = 0; i < igraph_gml_tree_length(gtree); i++) { long int j; char cname[100]; const char *name = igraph_gml_tree_name(gtree, i); if (!strcmp(name, "node")) { igraph_gml_tree_t *node; igraph_bool_t hasid; no_of_nodes++; if (igraph_gml_tree_type(gtree, i) != IGRAPH_I_GML_TREE_TREE) { IGRAPH_ERROR("'node' is not a list in GML file.", IGRAPH_PARSEERROR); } node = igraph_gml_tree_get_tree(gtree, i); hasid = 0; for (j = 0; j < igraph_gml_tree_length(node); j++) { const char *name = igraph_gml_tree_name(node, j); long int trieid, triesize = igraph_trie_size(&vattrnames); IGRAPH_CHECK(igraph_trie_get(&vattrnames, name, &trieid)); if (trieid == triesize) { /* new attribute */ igraph_attribute_record_t *atrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); int type = igraph_gml_tree_type(node, j); if (!atrec) { IGRAPH_ERROR("Cannot read GML file.", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_ptr_push_back(&vattrs, atrec)); atrec->name = strdup(name); if (type == IGRAPH_I_GML_TREE_INTEGER || type == IGRAPH_I_GML_TREE_REAL) { atrec->type = IGRAPH_ATTRIBUTE_NUMERIC; } else { atrec->type = IGRAPH_ATTRIBUTE_STRING; } } else { /* already seen, should we update type? */ igraph_attribute_record_t *atrec = VECTOR(vattrs)[trieid]; int type1 = atrec->type; int type2 = igraph_gml_tree_type(node, j); if (type1 == IGRAPH_ATTRIBUTE_NUMERIC && type2 == IGRAPH_I_GML_TREE_STRING) { atrec->type = IGRAPH_ATTRIBUTE_STRING; } } /* check id */ if (!hasid && !strcmp(name, "id")) { long int id; if (igraph_gml_tree_type(node, j) != IGRAPH_I_GML_TREE_INTEGER) { IGRAPH_ERROR("Non-integer node id in GML file.", IGRAPH_PARSEERROR); } id = igraph_gml_tree_get_integer(node, j); snprintf(cname, sizeof(cname) / sizeof(char) -1, "%li", id); IGRAPH_CHECK(igraph_trie_get(&trie, cname, &id)); hasid = 1; } } if (!hasid) { IGRAPH_ERROR("Node without 'id' while parsing GML file.", IGRAPH_PARSEERROR); } } else if (!strcmp(name, "edge")) { igraph_gml_tree_t *edge; igraph_bool_t has_source = 0, has_target = 0; no_of_edges++; if (igraph_gml_tree_type(gtree, i) != IGRAPH_I_GML_TREE_TREE) { IGRAPH_ERROR("'edge' is not a list in GML file.", IGRAPH_PARSEERROR); } edge = igraph_gml_tree_get_tree(gtree, i); has_source = has_target = 0; for (j = 0; j < igraph_gml_tree_length(edge); j++) { const char *name = igraph_gml_tree_name(edge, j); if (!strcmp(name, "source")) { has_source = 1; if (igraph_gml_tree_type(edge, j) != IGRAPH_I_GML_TREE_INTEGER) { IGRAPH_ERROR("Non-integer 'source' for an edge in GML file.", IGRAPH_PARSEERROR); } } else if (!strcmp(name, "target")) { has_target = 1; if (igraph_gml_tree_type(edge, j) != IGRAPH_I_GML_TREE_INTEGER) { IGRAPH_ERROR("Non-integer 'source' for an edge in GML file.", IGRAPH_PARSEERROR); } } else { long int trieid, triesize = igraph_trie_size(&eattrnames); IGRAPH_CHECK(igraph_trie_get(&eattrnames, name, &trieid)); if (trieid == triesize) { /* new attribute */ igraph_attribute_record_t *atrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); int type = igraph_gml_tree_type(edge, j); if (!atrec) { IGRAPH_ERROR("Cannot read GML file.", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_ptr_push_back(&eattrs, atrec)); atrec->name = strdup(name); if (type == IGRAPH_I_GML_TREE_INTEGER || type == IGRAPH_I_GML_TREE_REAL) { atrec->type = IGRAPH_ATTRIBUTE_NUMERIC; } else { atrec->type = IGRAPH_ATTRIBUTE_STRING; } } else { /* already seen, should we update type? */ igraph_attribute_record_t *atrec = VECTOR(eattrs)[trieid]; int type1 = atrec->type; int type2 = igraph_gml_tree_type(edge, j); if (type1 == IGRAPH_ATTRIBUTE_NUMERIC && type2 == IGRAPH_I_GML_TREE_STRING) { atrec->type = IGRAPH_ATTRIBUTE_STRING; } } } } /* for */ if (!has_source) { IGRAPH_ERROR("No 'source' for edge in GML file.", IGRAPH_PARSEERROR); } if (!has_target) { IGRAPH_ERROR("No 'target' for edge in GML file.", IGRAPH_PARSEERROR); } } else { /* anything to do? Maybe add as graph attribute.... */ } } /* check vertex id uniqueness */ if (igraph_trie_size(&trie) != no_of_nodes) { IGRAPH_ERROR("Node 'id' not unique in GML file.", IGRAPH_PARSEERROR); } /* now we allocate the vectors and strvectors for the attributes */ for (i = 0; i < igraph_vector_ptr_size(&vattrs); i++) { igraph_attribute_record_t *atrec = VECTOR(vattrs)[i]; int type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *p = IGRAPH_CALLOC(1, igraph_vector_t); atrec->value = p; IGRAPH_CHECK(igraph_vector_init(p, no_of_nodes)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *p = IGRAPH_CALLOC(1, igraph_strvector_t); atrec->value = p; IGRAPH_CHECK(igraph_strvector_init(p, no_of_nodes)); } else { IGRAPH_WARNING("A composite attribute was ignored in the GML file."); } } for (i = 0; i < igraph_vector_ptr_size(&eattrs); i++) { igraph_attribute_record_t *atrec = VECTOR(eattrs)[i]; int type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *p = IGRAPH_CALLOC(1, igraph_vector_t); atrec->value = p; IGRAPH_CHECK(igraph_vector_init(p, no_of_edges)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *p = IGRAPH_CALLOC(1, igraph_strvector_t); atrec->value = p; IGRAPH_CHECK(igraph_strvector_init(p, no_of_edges)); } else { IGRAPH_WARNING("A composite attribute was ignored in the GML file."); } } /* Ok, now the edges, attributes too */ IGRAPH_CHECK(igraph_vector_resize(&edges, no_of_edges * 2)); p = -1; while ( (p = igraph_gml_tree_find(gtree, "edge", p + 1)) != -1) { igraph_gml_tree_t *edge; long int from, to, fromidx = 0, toidx = 0; char name[100]; long int j; edge = igraph_gml_tree_get_tree(gtree, p); for (j = 0; j < igraph_gml_tree_length(edge); j++) { const char *n = igraph_gml_tree_name(edge, j); if (!strcmp(n, "source")) { fromidx = igraph_gml_tree_find(edge, "source", 0); } else if (!strcmp(n, "target")) { toidx = igraph_gml_tree_find(edge, "target", 0); } else { long int edgeid = edgeptr / 2; long int trieidx; igraph_attribute_record_t *atrec; int type; igraph_trie_get(&eattrnames, n, &trieidx); atrec = VECTOR(eattrs)[trieidx]; type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *v = (igraph_vector_t *)atrec->value; IGRAPH_CHECK(igraph_i_gml_toreal(edge, j, VECTOR(*v) + edgeid)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *v = (igraph_strvector_t *)atrec->value; const char *value = igraph_i_gml_tostring(edge, j); IGRAPH_CHECK(igraph_strvector_set(v, edgeid, value)); } } } from = igraph_gml_tree_get_integer(edge, fromidx); to = igraph_gml_tree_get_integer(edge, toidx); snprintf(name, sizeof(name) / sizeof(char) -1, "%li", from); IGRAPH_CHECK(igraph_trie_get(&trie, name, &from)); snprintf(name, sizeof(name) / sizeof(char) -1, "%li", to); IGRAPH_CHECK(igraph_trie_get(&trie, name, &to)); if (igraph_trie_size(&trie) != no_of_nodes) { IGRAPH_ERROR("Unknown node id found in an edge in GML file.", IGRAPH_PARSEERROR); } VECTOR(edges)[edgeptr++] = from; VECTOR(edges)[edgeptr++] = to; } /* and add vertex attributes */ for (i = 0; i < igraph_gml_tree_length(gtree); i++) { const char *n; char name[100]; long int j, k; n = igraph_gml_tree_name(gtree, i); if (!strcmp(n, "node")) { igraph_gml_tree_t *node = igraph_gml_tree_get_tree(gtree, i); long int iidx = igraph_gml_tree_find(node, "id", 0); long int id = igraph_gml_tree_get_integer(node, iidx); snprintf(name, sizeof(name) / sizeof(char) -1, "%li", id); igraph_trie_get(&trie, name, &id); for (j = 0; j < igraph_gml_tree_length(node); j++) { const char *aname = igraph_gml_tree_name(node, j); igraph_attribute_record_t *atrec; int type; igraph_trie_get(&vattrnames, aname, &k); atrec = VECTOR(vattrs)[k]; type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *v = (igraph_vector_t *)atrec->value; IGRAPH_CHECK(igraph_i_gml_toreal(node, j, VECTOR(*v) + id)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *v = (igraph_strvector_t *)atrec->value; const char *value = igraph_i_gml_tostring(node, j); IGRAPH_CHECK(igraph_strvector_set(v, id, value)); } } } } igraph_trie_destroy(&trie); igraph_trie_destroy(&gattrnames); igraph_trie_destroy(&vattrnames); igraph_trie_destroy(&eattrnames); IGRAPH_FINALLY_CLEAN(4); IGRAPH_CHECK(igraph_empty_attrs(graph, 0, directed, 0)); /* TODO */ IGRAPH_CHECK(igraph_add_vertices(graph, (igraph_integer_t) no_of_nodes, &vattrs)); IGRAPH_CHECK(igraph_add_edges(graph, &edges, &eattrs)); igraph_i_gml_destroy_attrs(attrs); igraph_vector_destroy(&edges); igraph_i_gml_parsedata_destroy(&context); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } static int igraph_i_gml_convert_to_key(const char *orig, char **key) { int no = 1; char strno[50]; size_t i, len = strlen(orig), newlen = 0, plen = 0; /* do we need a prefix? */ if (len == 0 || !isalpha(orig[0])) { no++; snprintf(strno, sizeof(strno) - 1, "igraph"); plen = newlen = strlen(strno); } for (i = 0; i < len; i++) { if (isalnum(orig[i])) { newlen++; } } *key = IGRAPH_CALLOC(newlen + 1, char); if (! *key) { IGRAPH_ERROR("Writing GML format failed.", IGRAPH_ENOMEM); } memcpy(*key, strno, plen * sizeof(char)); for (i = 0; i < len; i++) { if (isalnum(orig[i])) { (*key)[plen++] = orig[i]; } } (*key)[newlen] = '\0'; return IGRAPH_SUCCESS; } #define CHECK(cmd) do { ret=cmd; if (ret<0) IGRAPH_ERROR("Writing GML format failed.", IGRAPH_EFILE); } while (0) /** * \function igraph_write_graph_gml * \brief Write the graph to a stream in GML format * * GML is a quite general textual format, see * http://www.fim.uni-passau.de/en/fim/faculty/chairs/theoretische-informatik/projects.html for details. * * The graph, vertex and edges attributes are written to the * file as well, if they are numeric or string. * * As igraph is more forgiving about attribute names, it might * be necessary to simplify the them before writing to the GML file. * This way we'll have a syntactically correct GML file. The following * simple procedure is performed on each attribute name: first the alphanumeric * characters are extracted, the others are ignored. Then if the first character * is not a letter then the attribute name is prefixed with igraph. * Note that this might result identical names for two attributes, igraph * does not check this. * * The id vertex attribute is treated specially. * If the id argument is not 0 then it should be a numeric * vector with the vertex ids and the id vertex attribute is * ignored (if there is one). If id is 0 and there is a * numeric id vertex attribute that is used instead. If ids * are not specified in either way then the regular igraph vertex ids are used. * * Note that whichever way vertex ids are specified, their * uniqueness is not checked. * * If the graph has edge attributes named source * or target they're silently ignored. GML uses these attributes * to specify the edges, so we cannot write them to the file. Rename them * before calling this function if you want to preserve them. * \param graph The graph to write to the stream. * \param outstream The stream to write the file to. * \param id Either NULL or a numeric vector with the vertex ids. * See details above. * \param creator An optional string to write to the stream in the creator line. * If this is 0 then the current date and time is added. * \return Error code. * * Time complexity: should be proportional to the number of characters written * to the file. * * \sa \ref igraph_read_graph_gml() for reading GML files, * \ref igraph_read_graph_graphml() for a more modern format. * * \example examples/simple/gml.c */ int igraph_write_graph_gml(const igraph_t *graph, FILE *outstream, const igraph_vector_t *id, const char *creator) { int ret; igraph_strvector_t gnames, vnames, enames; igraph_vector_t gtypes, vtypes, etypes; igraph_vector_t numv; igraph_strvector_t strv; igraph_vector_bool_t boolv; long int i; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vector_t v_myid; const igraph_vector_t *myid = id; time_t curtime = time(0); char *timestr = ctime(&curtime); timestr[strlen(timestr) - 1] = '\0'; /* nicely remove \n */ CHECK(fprintf(outstream, "Creator \"igraph %s\"\nVersion 1\ngraph\n[\n", creator ? creator : timestr)); IGRAPH_STRVECTOR_INIT_FINALLY(&gnames, 0); IGRAPH_STRVECTOR_INIT_FINALLY(&vnames, 0); IGRAPH_STRVECTOR_INIT_FINALLY(&enames, 0); IGRAPH_VECTOR_INIT_FINALLY(>ypes, 0); IGRAPH_VECTOR_INIT_FINALLY(&vtypes, 0); IGRAPH_VECTOR_INIT_FINALLY(&etypes, 0); IGRAPH_CHECK(igraph_i_attribute_get_info(graph, &gnames, >ypes, &vnames, &vtypes, &enames, &etypes)); IGRAPH_VECTOR_INIT_FINALLY(&numv, 1); IGRAPH_STRVECTOR_INIT_FINALLY(&strv, 1); IGRAPH_VECTOR_BOOL_INIT_FINALLY(&boolv, 1); /* Check whether there is an 'id' node attribute if the supplied is 0 */ if (!id) { igraph_bool_t found = 0; for (i = 0; i < igraph_vector_size(&vtypes); i++) { char *n; igraph_strvector_get(&vnames, i, &n); if (!strcmp(n, "id") && VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { found = 1; break; } } if (found) { IGRAPH_VECTOR_INIT_FINALLY(&v_myid, no_of_nodes); IGRAPH_CHECK(igraph_i_attribute_get_numeric_vertex_attr(graph, "id", igraph_vss_all(), &v_myid)); myid = &v_myid; } } /* directedness */ CHECK(fprintf(outstream, " directed %i\n", igraph_is_directed(graph) ? 1 : 0)); /* Graph attributes first */ for (i = 0; i < igraph_vector_size(>ypes); i++) { char *name, *newname; igraph_strvector_get(&gnames, i, &name); IGRAPH_CHECK(igraph_i_gml_convert_to_key(name, &newname)); IGRAPH_FINALLY(igraph_free, newname); if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_i_attribute_get_numeric_graph_attr(graph, name, &numv)); CHECK(fprintf(outstream, " %s ", newname)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(numv)[0])); CHECK(fputc('\n', outstream)); } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_STRING) { char *s; IGRAPH_CHECK(igraph_i_attribute_get_string_graph_attr(graph, name, &strv)); igraph_strvector_get(&strv, 0, &s); CHECK(fprintf(outstream, " %s \"%s\"\n", newname, s)); } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_CHECK(igraph_i_attribute_get_bool_graph_attr(graph, name, &boolv)); CHECK(fprintf(outstream, " %s %d\n", newname, VECTOR(boolv)[0] ? 1 : 0)); IGRAPH_WARNING("A boolean graph attribute was converted to numeric"); } else { IGRAPH_WARNING("A non-numeric, non-string, non-boolean graph attribute ignored"); } IGRAPH_FREE(newname); IGRAPH_FINALLY_CLEAN(1); } /* Now come the vertices */ for (i = 0; i < no_of_nodes; i++) { long int j; CHECK(fprintf(outstream, " node\n [\n")); /* id */ CHECK(fprintf(outstream, " id %li\n", myid ? (long int)VECTOR(*myid)[i] : i)); /* other attributes */ for (j = 0; j < igraph_vector_size(&vtypes); j++) { int type = (int) VECTOR(vtypes)[j]; char *name, *newname; igraph_strvector_get(&vnames, j, &name); if (!strcmp(name, "id")) { continue; } IGRAPH_CHECK(igraph_i_gml_convert_to_key(name, &newname)); IGRAPH_FINALLY(igraph_free, newname); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_i_attribute_get_numeric_vertex_attr(graph, name, igraph_vss_1((igraph_integer_t) i), &numv)); CHECK(fprintf(outstream, " %s ", newname)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(numv)[0])); CHECK(fputc('\n', outstream)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { char *s; IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr(graph, name, igraph_vss_1((igraph_integer_t) i), &strv)); igraph_strvector_get(&strv, 0, &s); CHECK(fprintf(outstream, " %s \"%s\"\n", newname, s)); } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_CHECK(igraph_i_attribute_get_bool_vertex_attr(graph, name, igraph_vss_1((igraph_integer_t) i), &boolv)); CHECK(fprintf(outstream, " %s %d\n", newname, VECTOR(boolv)[0] ? 1 : 0)); IGRAPH_WARNING("A boolean vertex attribute was converted to numeric"); } else { IGRAPH_WARNING("A non-numeric, non-string, non-boolean edge attribute was ignored"); } IGRAPH_FREE(newname); IGRAPH_FINALLY_CLEAN(1); } CHECK(fprintf(outstream, " ]\n")); } /* The edges too */ for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); long int j; CHECK(fprintf(outstream, " edge\n [\n")); /* source and target */ CHECK(fprintf(outstream, " source %li\n", myid ? (long int)VECTOR(*myid)[from] : from)); CHECK(fprintf(outstream, " target %li\n", myid ? (long int)VECTOR(*myid)[to] : to)); /* other attributes */ for (j = 0; j < igraph_vector_size(&etypes); j++) { int type = (int) VECTOR(etypes)[j]; char *name, *newname; igraph_strvector_get(&enames, j, &name); if (!strcmp(name, "source") || !strcmp(name, "target")) { continue; } IGRAPH_CHECK(igraph_i_gml_convert_to_key(name, &newname)); IGRAPH_FINALLY(igraph_free, newname); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) i), &numv)); CHECK(fprintf(outstream, " %s ", newname)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(numv)[0])); CHECK(fputc('\n', outstream)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { char *s; IGRAPH_CHECK(igraph_i_attribute_get_string_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) i), &strv)); igraph_strvector_get(&strv, 0, &s); CHECK(fprintf(outstream, " %s \"%s\"\n", newname, s)); } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_CHECK(igraph_i_attribute_get_bool_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) i), &boolv)); CHECK(fprintf(outstream, " %s %d\n", newname, VECTOR(boolv)[0] ? 1 : 0)); IGRAPH_WARNING("A boolean edge attribute was converted to numeric"); } else { IGRAPH_WARNING("A non-numeric, non-string, non-boolean edge attribute was ignored"); } IGRAPH_FREE(newname); IGRAPH_FINALLY_CLEAN(1); } CHECK(fprintf(outstream, " ]\n")); } CHECK(fprintf(outstream, "]\n")); if (&v_myid == myid) { igraph_vector_destroy(&v_myid); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_bool_destroy(&boolv); igraph_strvector_destroy(&strv); igraph_vector_destroy(&numv); igraph_vector_destroy(&etypes); igraph_vector_destroy(&vtypes); igraph_vector_destroy(>ypes); igraph_strvector_destroy(&enames); igraph_strvector_destroy(&vnames); igraph_strvector_destroy(&gnames); IGRAPH_FINALLY_CLEAN(9); return IGRAPH_SUCCESS; } #undef CHECK leidenbase/src/core/io/dl-lexer.l0000644000176200001440000001060114447675374016407 0ustar liggesusers/* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include "io/dl-header.h" #include "io/parsers/dl-parser.h" #define YY_EXTRA_TYPE igraph_i_dl_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in DL parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif %} %option noyywrap %option prefix="igraph_dl_yy" %option nounput %option noinput %option nodefault %option reentrant %option bison-bridge %option bison-locations digit [0-9] whitespace [ \t\v\f] %x LABELM FULLMATRIX EDGELIST NODELIST %% <*>\n\r|\r\n|\r|\n { return NEWLINE; } [dD][lL]{whitespace}+ { return DL; } [nN]{whitespace}*[=]{whitespace}* { return NEQ; } {digit}+ { return NUM; } [dD][aA][tT][aA][:] { switch (yyextra->mode) { case 0: BEGIN(FULLMATRIX); break; case 1: BEGIN(EDGELIST); break; case 2: BEGIN(NODELIST); break; } return DATA; } [lL][aA][bB][eE][lL][sS]: { BEGIN(LABELM); return LABELS; } [lL][aA][bB][eE][lL][sS]{whitespace}+[eE][mM][bB][eE][dD][dD][eE][dD]:?{whitespace}* { return LABELSEMBEDDED; } [fF][oO][rR][mM][aA][tT]{whitespace}*[=]{whitespace}*[fF][uU][lL][lL][mM][aA][tT][rR][iI][xX]{whitespace}* { yyextra->mode=0; return FORMATFULLMATRIX; } [fF][oO][rR][mM][aA][tT]{whitespace}*[=]{whitespace}*[eE][dD][gG][eE][lL][iI][sS][tT][1]{whitespace}* { yyextra->mode=1; return FORMATEDGELIST1; } [fF][oO][rR][mM][aA][tT]{whitespace}*[=]{whitespace}*[nN][oO][dD][eE][lL][iI][sS][tT][1]{whitespace}* { yyextra->mode=2; return FORMATNODELIST1; } [, ] { /* eaten up */ } [^, \t\n\r\f\v]+{whitespace}* { return LABEL; } {digit}{whitespace}* { return DIGIT; } [^ \t\n\r\v\f,]+ { return LABEL; } {whitespace} { } \-?{digit}+(\.{digit}+)?([eE](\+|\-)?{digit}+)? { return NUM; } [^ \t\n\r\v\f,]+ { return LABEL; } {whitespace}* { } {digit}+ { return NUM; } [^ \t\r\n\v\f,]+ { return LABEL; } {whitespace}* { } {whitespace}+ { /* eaten up */ } <> { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; BEGIN(INITIAL); return EOFF; } } <*>. { return 0; } leidenbase/src/core/io/ncol-lexer.c0000644000176200001440000017042514447675375016746 0ustar liggesusers#line 2 "src/core/io/ncol-lexer.c" #line 4 "src/core/io/ncol-lexer.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_ncol_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_ncol_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_ncol_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_ncol_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_ncol_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_ncol_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_ncol_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_ncol_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_ncol_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_ncol_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_ncol_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_ncol_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_ncol_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_ncol_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_ncol_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_ncol_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_ncol_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_ncol_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_ncol_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_ncol_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_ncol_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_ncol_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_ncol_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_ncol_yyensure_buffer_stack #endif #ifdef yylex #define igraph_ncol_yylex_ALREADY_DEFINED #else #define yylex igraph_ncol_yylex #endif #ifdef yyrestart #define igraph_ncol_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_ncol_yyrestart #endif #ifdef yylex_init #define igraph_ncol_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_ncol_yylex_init #endif #ifdef yylex_init_extra #define igraph_ncol_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_ncol_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_ncol_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_ncol_yylex_destroy #endif #ifdef yyget_debug #define igraph_ncol_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_ncol_yyget_debug #endif #ifdef yyset_debug #define igraph_ncol_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_ncol_yyset_debug #endif #ifdef yyget_extra #define igraph_ncol_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_ncol_yyget_extra #endif #ifdef yyset_extra #define igraph_ncol_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_ncol_yyset_extra #endif #ifdef yyget_in #define igraph_ncol_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_ncol_yyget_in #endif #ifdef yyset_in #define igraph_ncol_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_ncol_yyset_in #endif #ifdef yyget_out #define igraph_ncol_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_ncol_yyget_out #endif #ifdef yyset_out #define igraph_ncol_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_ncol_yyset_out #endif #ifdef yyget_leng #define igraph_ncol_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_ncol_yyget_leng #endif #ifdef yyget_text #define igraph_ncol_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_ncol_yyget_text #endif #ifdef yyget_lineno #define igraph_ncol_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_ncol_yyget_lineno #endif #ifdef yyset_lineno #define igraph_ncol_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_ncol_yyset_lineno #endif #ifdef yyget_column #define igraph_ncol_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_ncol_yyget_column #endif #ifdef yyset_column #define igraph_ncol_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_ncol_yyset_column #endif #ifdef yywrap #define igraph_ncol_yywrap_ALREADY_DEFINED #else #define yywrap igraph_ncol_yywrap #endif #ifdef yyget_lval #define igraph_ncol_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_ncol_yyget_lval #endif #ifdef yyset_lval #define igraph_ncol_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_ncol_yyset_lval #endif #ifdef yyget_lloc #define igraph_ncol_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_ncol_yyget_lloc #endif #ifdef yyset_lloc #define igraph_ncol_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_ncol_yyset_lloc #endif #ifdef yyalloc #define igraph_ncol_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_ncol_yyalloc #endif #ifdef yyrealloc #define igraph_ncol_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_ncol_yyrealloc #endif #ifdef yyfree #define igraph_ncol_yyfree_ALREADY_DEFINED #else #define yyfree igraph_ncol_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define igraph_ncol_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void __attribute__((unused)) yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 5 #define YY_END_OF_BUFFER 6 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[13] = { 0, 0, 0, 6, 3, 1, 2, 2, 4, 3, 1, 2, 0 } ; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static const YY_CHAR yy_meta[6] = { 0, 1, 2, 3, 4, 5 } ; static const flex_int16_t yy_base[17] = { 0, 0, 0, 10, 0, 0, 0, 0, 11, 0, 0, 11, 11, 8, 6, 3, 3 } ; static const flex_int16_t yy_def[17] = { 0, 12, 1, 12, 13, 14, 15, 16, 12, 13, 14, 12, 0, 12, 12, 12, 12 } ; static const flex_int16_t yy_nxt[17] = { 0, 4, 5, 6, 7, 8, 11, 11, 10, 9, 12, 3, 12, 12, 12, 12, 12 } ; static const flex_int16_t yy_chk[17] = { 0, 1, 1, 1, 1, 1, 16, 15, 14, 13, 3, 12, 12, 12, 12, 12, 12 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "src/core/io/ncol-lexer.l" /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #line 24 "src/core/io/ncol-lexer.l" /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "io/ncol-header.h" #include "io/ncol-parser.h" #define YY_EXTRA_TYPE igraph_i_ncol_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in NCOL parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif #line 722 "src/core/io/ncol-lexer.c" #define YY_NO_INPUT 1 #line 724 "src/core/io/ncol-lexer.c" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; YYSTYPE * yylval_r; YYLTYPE * yylloc_r; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r # define yylloc yyg->yylloc_r int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; yylloc = yylloc_param; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 76 "src/core/io/ncol-lexer.l" #line 79 "src/core/io/ncol-lexer.l" /* ------------------------------------------------whitespace------*/ #line 1011 "src/core/io/ncol-lexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 13 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 11 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 80 "src/core/io/ncol-lexer.l" { } YY_BREAK /* ---------------------------------------------------newline------*/ case 2: /* rule 2 can match eol */ YY_RULE_SETUP #line 83 "src/core/io/ncol-lexer.l" { return NEWLINE; } YY_BREAK /* ----------------------------------------------alphanumeric------*/ case 3: YY_RULE_SETUP #line 86 "src/core/io/ncol-lexer.l" { return ALNUM; } YY_BREAK case YY_STATE_EOF(INITIAL): #line 88 "src/core/io/ncol-lexer.l" { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; return NEWLINE; } } YY_BREAK /* ---------------------------------------------anything else------*/ case 4: YY_RULE_SETUP #line 97 "src/core/io/ncol-lexer.l" { return ERROR; } YY_BREAK case 5: YY_RULE_SETUP #line 99 "src/core/io/ncol-lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK #line 1107 "src/core/io/ncol-lexer.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 5); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 13 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; YY_CHAR yy_c = 5; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 13 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_is_jam = (yy_current_state == 12); (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void __attribute__((unused)) yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ YYSTYPE * yyget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } YYLTYPE *yyget_lloc (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylloc; } void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylloc = yylloc_param; } /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 99 "src/core/io/ncol-lexer.l" leidenbase/src/core/io/lgl-header.h0000644000176200001440000000220314447675374016672 0ustar liggesusers/* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge MA, 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_error.h" #include "igraph_vector.h" #include "core/trie.h" typedef struct { void *scanner; int eof; char errmsg[300]; int has_weights; igraph_vector_t *vector; igraph_vector_t *weights; igraph_trie_t *trie; int actvertex; } igraph_i_lgl_parsedata_t; leidenbase/src/core/io/leda.c0000644000176200001440000002336114447675374015576 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_attributes.h" #include "igraph_interface.h" #include "igraph_iterators.h" #include "graph/attributes.h" #include #define CHECK(cmd) do { ret=cmd; if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } while (0) /** * \function igraph_write_graph_leda * \brief Write a graph in LEDA native graph format. * * This function writes a graph to an output stream in LEDA format. * See http://www.algorithmic-solutions.info/leda_guide/graphs/leda_native_graph_fileformat.html * * * The support for the LEDA format is very basic at the moment; igraph * writes only the LEDA graph section which supports one selected vertex * and edge attribute and no layout information or visual attributes. * * \param graph The graph to write to the stream. * \param outstream The stream. * \param vertex_attr_name The name of the vertex attribute whose values * are to be stored in the output or \c NULL if no * vertex attribute has to be stored. * \param edge_attr_name The name of the edge attribute whose values * are to be stored in the output or \c NULL if no * edge attribute has to be stored. * \return Error code. * * Time complexity: O(|V|+|E|), the number of vertices and edges in the * graph. * * \example examples/simple/igraph_write_graph_leda.c */ int igraph_write_graph_leda(const igraph_t *graph, FILE *outstream, const char* vertex_attr_name, const char* edge_attr_name) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_eit_t it; long int i = 0; int ret; igraph_attribute_type_t vertex_attr_type = IGRAPH_ATTRIBUTE_DEFAULT; igraph_attribute_type_t edge_attr_type = IGRAPH_ATTRIBUTE_DEFAULT; igraph_integer_t from, to, rev; IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_FROM), &it)); IGRAPH_FINALLY(igraph_eit_destroy, &it); /* Check if we have the vertex attribute */ if (vertex_attr_name && !igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, vertex_attr_name)) { vertex_attr_name = 0; IGRAPH_WARNING("specified vertex attribute does not exist"); } if (vertex_attr_name) { IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &vertex_attr_type, IGRAPH_ATTRIBUTE_VERTEX, vertex_attr_name)); if (vertex_attr_type != IGRAPH_ATTRIBUTE_NUMERIC && vertex_attr_type != IGRAPH_ATTRIBUTE_STRING) { vertex_attr_name = 0; vertex_attr_type = IGRAPH_ATTRIBUTE_DEFAULT; IGRAPH_WARNING("specified vertex attribute must be numeric or string"); } } /* Check if we have the edge attribute */ if (edge_attr_name && !igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, edge_attr_name)) { edge_attr_name = 0; IGRAPH_WARNING("specified edge attribute does not exist"); } if (edge_attr_name) { IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &edge_attr_type, IGRAPH_ATTRIBUTE_EDGE, edge_attr_name)); if (edge_attr_type != IGRAPH_ATTRIBUTE_NUMERIC && edge_attr_type != IGRAPH_ATTRIBUTE_STRING) { edge_attr_name = 0; edge_attr_type = IGRAPH_ATTRIBUTE_DEFAULT; IGRAPH_WARNING("specified edge attribute must be numeric or string"); } } /* Start writing header */ CHECK(fprintf(outstream, "LEDA.GRAPH\n")); switch (vertex_attr_type) { case IGRAPH_ATTRIBUTE_NUMERIC: CHECK(fprintf(outstream, "float\n")); break; case IGRAPH_ATTRIBUTE_STRING: CHECK(fprintf(outstream, "string\n")); break; default: CHECK(fprintf(outstream, "void\n")); } switch (edge_attr_type) { case IGRAPH_ATTRIBUTE_NUMERIC: CHECK(fprintf(outstream, "float\n")); break; case IGRAPH_ATTRIBUTE_STRING: CHECK(fprintf(outstream, "string\n")); break; default: CHECK(fprintf(outstream, "void\n")); } CHECK(fprintf(outstream, "%d\n", (igraph_is_directed(graph) ? -1 : -2))); /* Start writing vertices */ CHECK(fprintf(outstream, "# Vertices\n")); CHECK(fprintf(outstream, "%ld\n", no_of_nodes)); if (vertex_attr_type == IGRAPH_ATTRIBUTE_NUMERIC) { /* Vertices with numeric attributes */ igraph_vector_t values; IGRAPH_VECTOR_INIT_FINALLY(&values, no_of_nodes); IGRAPH_CHECK(igraph_i_attribute_get_numeric_vertex_attr( graph, vertex_attr_name, igraph_vss_all(), &values)); for (i = 0; i < no_of_nodes; i++) { CHECK(fprintf(outstream, "|{")); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(values)[i])); CHECK(fprintf(outstream, "}|\n")); } igraph_vector_destroy(&values); IGRAPH_FINALLY_CLEAN(1); } else if (vertex_attr_type == IGRAPH_ATTRIBUTE_STRING) { /* Vertices with string attributes */ igraph_strvector_t values; IGRAPH_CHECK(igraph_strvector_init(&values, no_of_nodes)); IGRAPH_FINALLY(igraph_strvector_destroy, &values); IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr( graph, vertex_attr_name, igraph_vss_all(), &values)); for (i = 0; i < no_of_nodes; i++) { const char* str = STR(values, i); if (strchr(str, '\n') != 0) { IGRAPH_ERROR("edge attribute values cannot contain newline characters", IGRAPH_EINVAL); } CHECK(fprintf(outstream, "|{%s}|\n", str)); } igraph_strvector_destroy(&values); IGRAPH_FINALLY_CLEAN(1); } else { /* Vertices with no attributes */ for (i = 0; i < no_of_nodes; i++) { CHECK(fprintf(outstream, "|{}|\n")); } } CHECK(fprintf(outstream, "# Edges\n")); CHECK(fprintf(outstream, "%ld\n", no_of_edges)); if (edge_attr_type == IGRAPH_ATTRIBUTE_NUMERIC) { /* Edges with numeric attributes */ igraph_vector_t values; IGRAPH_VECTOR_INIT_FINALLY(&values, no_of_nodes); IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr( graph, edge_attr_name, igraph_ess_all(IGRAPH_EDGEORDER_ID), &values)); while (!IGRAPH_EIT_END(it)) { long int eid = IGRAPH_EIT_GET(it); igraph_edge(graph, (igraph_integer_t) eid, &from, &to); igraph_get_eid(graph, &rev, to, from, 1, 0); if (rev == IGRAPH_EIT_GET(it)) { rev = -1; } CHECK(fprintf(outstream, "%ld %ld %ld |{", (long int) from + 1, (long int) to + 1, (long int) rev + 1)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(values)[eid])); CHECK(fprintf(outstream, "}|\n")); IGRAPH_EIT_NEXT(it); } igraph_vector_destroy(&values); IGRAPH_FINALLY_CLEAN(1); } else if (edge_attr_type == IGRAPH_ATTRIBUTE_STRING) { /* Edges with string attributes */ igraph_strvector_t values; IGRAPH_CHECK(igraph_strvector_init(&values, no_of_nodes)); IGRAPH_FINALLY(igraph_strvector_destroy, &values); IGRAPH_CHECK(igraph_i_attribute_get_string_edge_attr( graph, edge_attr_name, igraph_ess_all(IGRAPH_EDGEORDER_ID), &values)); while (!IGRAPH_EIT_END(it)) { long int eid = IGRAPH_EIT_GET(it); const char* str = STR(values, eid); igraph_edge(graph, (igraph_integer_t) eid, &from, &to); igraph_get_eid(graph, &rev, to, from, 1, 0); if (rev == IGRAPH_EIT_GET(it)) { rev = -1; } if (strchr(str, '\n') != 0) { IGRAPH_ERROR("edge attribute values cannot contain newline characters", IGRAPH_EINVAL); } CHECK(fprintf(outstream, "%ld %ld %ld |{%s}|\n", (long int) from + 1, (long int) to + 1, (long int) rev + 1, str)); IGRAPH_EIT_NEXT(it); } igraph_strvector_destroy(&values); IGRAPH_FINALLY_CLEAN(1); } else { /* Edges with no attributes */ while (!IGRAPH_EIT_END(it)) { igraph_edge(graph, IGRAPH_EIT_GET(it), &from, &to); igraph_get_eid(graph, &rev, to, from, 1, 0); if (rev == IGRAPH_EIT_GET(it)) { rev = -1; } CHECK(fprintf(outstream, "%ld %ld %ld |{}|\n", (long int) from + 1, (long int) to + 1, (long int) rev + 1)); IGRAPH_EIT_NEXT(it); } } igraph_eit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); return 0; } #undef CHECK leidenbase/src/core/io/dl-lexer.c0000644000176200001440000021017414447675375016406 0ustar liggesusers#line 2 "src/core/io/dl-lexer.c" #line 4 "src/core/io/dl-lexer.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_dl_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_dl_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_dl_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_dl_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_dl_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_dl_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_dl_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_dl_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_dl_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_dl_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_dl_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_dl_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_dl_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_dl_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_dl_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_dl_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_dl_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_dl_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_dl_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_dl_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_dl_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_dl_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_dl_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_dl_yyensure_buffer_stack #endif #ifdef yylex #define igraph_dl_yylex_ALREADY_DEFINED #else #define yylex igraph_dl_yylex #endif #ifdef yyrestart #define igraph_dl_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_dl_yyrestart #endif #ifdef yylex_init #define igraph_dl_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_dl_yylex_init #endif #ifdef yylex_init_extra #define igraph_dl_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_dl_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_dl_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_dl_yylex_destroy #endif #ifdef yyget_debug #define igraph_dl_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_dl_yyget_debug #endif #ifdef yyset_debug #define igraph_dl_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_dl_yyset_debug #endif #ifdef yyget_extra #define igraph_dl_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_dl_yyget_extra #endif #ifdef yyset_extra #define igraph_dl_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_dl_yyset_extra #endif #ifdef yyget_in #define igraph_dl_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_dl_yyget_in #endif #ifdef yyset_in #define igraph_dl_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_dl_yyset_in #endif #ifdef yyget_out #define igraph_dl_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_dl_yyget_out #endif #ifdef yyset_out #define igraph_dl_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_dl_yyset_out #endif #ifdef yyget_leng #define igraph_dl_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_dl_yyget_leng #endif #ifdef yyget_text #define igraph_dl_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_dl_yyget_text #endif #ifdef yyget_lineno #define igraph_dl_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_dl_yyget_lineno #endif #ifdef yyset_lineno #define igraph_dl_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_dl_yyset_lineno #endif #ifdef yyget_column #define igraph_dl_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_dl_yyget_column #endif #ifdef yyset_column #define igraph_dl_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_dl_yyset_column #endif #ifdef yywrap #define igraph_dl_yywrap_ALREADY_DEFINED #else #define yywrap igraph_dl_yywrap #endif #ifdef yyget_lval #define igraph_dl_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_dl_yyget_lval #endif #ifdef yyset_lval #define igraph_dl_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_dl_yyset_lval #endif #ifdef yyget_lloc #define igraph_dl_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_dl_yyget_lloc #endif #ifdef yyset_lloc #define igraph_dl_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_dl_yyset_lloc #endif #ifdef yyalloc #define igraph_dl_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_dl_yyalloc #endif #ifdef yyrealloc #define igraph_dl_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_dl_yyrealloc #endif #ifdef yyfree #define igraph_dl_yyfree_ALREADY_DEFINED #else #define yyfree igraph_dl_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) #define igraph_dl_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void __attribute__((unused)) yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 24 #define YY_END_OF_BUFFER 25 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[129] = { 0, 0, 0, 0, 0, 0, 0, 18, 18, 21, 21, 25, 23, 22, 1, 1, 4, 23, 23, 23, 23, 12, 11, 12, 12, 14, 15, 13, 17, 18, 17, 16, 20, 21, 19, 22, 1, 4, 0, 0, 0, 0, 0, 3, 12, 12, 12, 12, 14, 13, 17, 18, 16, 17, 17, 20, 21, 19, 0, 2, 0, 0, 3, 12, 12, 16, 17, 16, 0, 0, 0, 12, 12, 5, 0, 0, 5, 12, 0, 0, 12, 0, 0, 0, 6, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 10, 7, 7, 9, 8, 10, 8, 0 } ; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 9, 1, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 12, 1, 1, 13, 1, 1, 1, 14, 15, 1, 16, 17, 18, 19, 1, 20, 1, 1, 21, 22, 23, 24, 1, 1, 25, 26, 27, 28, 1, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 1, 16, 17, 18, 19, 1, 20, 1, 1, 21, 22, 23, 24, 1, 1, 25, 26, 27, 28, 1, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static const YY_CHAR yy_meta[30] = { 0, 1, 2, 3, 3, 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static const flex_int16_t yy_base[138] = { 0, 0, 22, 44, 64, 84, 94, 104, 114, 124, 134, 287, 288, 4, 282, 282, 2, 1, 260, 269, 15, 29, 288, 39, 50, 0, 288, 34, 0, 52, 19, 64, 0, 54, 51, 74, 288, 67, 255, 88, 256, 265, 138, 98, 108, 118, 128, 144, 0, 145, 0, 151, 151, 72, 159, 0, 152, 153, 265, 169, 256, 260, 170, 171, 175, 171, 168, 173, 264, 261, 253, 184, 185, 288, 246, 246, 189, 193, 195, 197, 199, 205, 218, 209, 288, 210, 0, 255, 242, 245, 246, 248, 245, 249, 231, 228, 217, 211, 200, 184, 181, 172, 150, 138, 138, 128, 126, 106, 75, 66, 67, 45, 45, 36, 42, 39, 22, 26, 219, 211, 6, 220, 227, 228, 232, 237, 238, 242, 288, 247, 250, 253, 256, 259, 262, 7, 6, 0 } ; static const flex_int16_t yy_def[138] = { 0, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 134, 128, 134, 134, 135, 128, 135, 136, 128, 136, 136, 137, 128, 137, 128, 128, 128, 128, 128, 128, 128, 128, 128, 134, 128, 134, 134, 135, 128, 136, 128, 136, 136, 136, 137, 128, 137, 128, 128, 128, 128, 128, 134, 134, 136, 136, 136, 128, 128, 128, 134, 134, 128, 128, 128, 134, 134, 128, 128, 134, 128, 128, 128, 128, 128, 82, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128 } ; static const flex_int16_t yy_nxt[318] = { 0, 55, 13, 14, 15, 13, 35, 50, 48, 35, 16, 16, 37, 37, 128, 38, 17, 42, 18, 128, 42, 19, 39, 20, 13, 14, 15, 13, 43, 52, 52, 45, 16, 16, 45, 125, 49, 121, 17, 49, 18, 45, 120, 19, 45, 20, 12, 14, 15, 22, 119, 22, 45, 46, 51, 45, 56, 51, 118, 56, 23, 57, 57, 117, 47, 24, 12, 14, 15, 22, 116, 22, 115, 53, 52, 52, 35, 37, 37, 35, 23, 54, 65, 65, 114, 24, 26, 14, 15, 26, 59, 12, 113, 59, 27, 27, 26, 14, 15, 26, 62, 12, 112, 62, 27, 27, 29, 14, 15, 29, 45, 12, 30, 45, 31, 31, 29, 14, 15, 29, 45, 12, 30, 45, 31, 31, 33, 14, 15, 33, 45, 12, 111, 45, 34, 34, 33, 14, 15, 33, 42, 12, 110, 42, 34, 34, 45, 49, 109, 45, 49, 43, 108, 51, 56, 63, 51, 56, 107, 64, 53, 52, 52, 57, 57, 66, 106, 66, 54, 67, 67, 59, 62, 45, 59, 62, 45, 45, 67, 67, 45, 65, 65, 67, 67, 71, 45, 45, 54, 45, 45, 45, 72, 105, 45, 45, 76, 81, 45, 83, 81, 85, 83, 104, 85, 103, 77, 81, 82, 84, 81, 83, 85, 124, 83, 85, 124, 102, 82, 80, 86, 122, 126, 86, 122, 126, 90, 90, 101, 122, 122, 123, 122, 122, 124, 87, 88, 124, 100, 127, 126, 89, 127, 126, 127, 99, 98, 127, 12, 12, 12, 21, 21, 21, 25, 25, 25, 28, 28, 28, 32, 32, 32, 44, 44, 97, 96, 95, 94, 93, 92, 91, 79, 78, 75, 74, 73, 70, 69, 68, 61, 60, 58, 41, 40, 36, 36, 128, 11, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } ; static const flex_int16_t yy_chk[318] = { 0, 137, 1, 1, 1, 1, 13, 136, 135, 13, 1, 1, 16, 16, 0, 17, 1, 20, 1, 0, 20, 1, 17, 1, 2, 2, 2, 2, 20, 30, 30, 21, 2, 2, 21, 120, 27, 117, 2, 27, 2, 23, 116, 2, 23, 2, 3, 3, 3, 3, 115, 3, 24, 23, 29, 24, 33, 29, 114, 33, 3, 34, 34, 113, 24, 3, 4, 4, 4, 4, 112, 4, 111, 31, 31, 31, 35, 37, 37, 35, 4, 31, 53, 53, 110, 4, 5, 5, 5, 5, 39, 5, 109, 39, 5, 5, 6, 6, 6, 6, 43, 6, 108, 43, 6, 6, 7, 7, 7, 7, 44, 7, 7, 44, 7, 7, 8, 8, 8, 8, 45, 8, 8, 45, 8, 8, 9, 9, 9, 9, 46, 9, 107, 46, 9, 9, 10, 10, 10, 10, 42, 10, 106, 42, 10, 10, 47, 49, 105, 47, 49, 42, 104, 51, 56, 46, 51, 56, 103, 47, 52, 52, 52, 57, 57, 54, 102, 54, 52, 54, 54, 59, 62, 63, 59, 62, 63, 64, 66, 66, 64, 65, 65, 67, 67, 63, 71, 72, 65, 71, 72, 76, 64, 101, 76, 77, 71, 78, 77, 79, 78, 80, 79, 100, 80, 99, 72, 81, 78, 79, 81, 83, 85, 119, 83, 85, 119, 98, 81, 77, 82, 118, 121, 82, 118, 121, 83, 85, 97, 122, 123, 118, 122, 123, 124, 82, 82, 124, 96, 125, 126, 82, 125, 126, 127, 95, 94, 127, 129, 129, 129, 130, 130, 130, 131, 131, 131, 132, 132, 132, 133, 133, 133, 134, 134, 93, 92, 91, 90, 89, 88, 87, 75, 74, 70, 69, 68, 61, 60, 58, 41, 40, 38, 19, 18, 15, 14, 11, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "src/core/io/dl-lexer.l" /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #line 24 "src/core/io/dl-lexer.l" /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include "io/dl-header.h" #include "io/dl-parser.h" #define YY_EXTRA_TYPE igraph_i_dl_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in DL parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif #line 827 "src/core/io/dl-lexer.c" #define YY_NO_INPUT 1 #line 830 "src/core/io/dl-lexer.c" #define INITIAL 0 #define LABELM 1 #define FULLMATRIX 2 #define EDGELIST 3 #define NODELIST 4 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; YYSTYPE * yylval_r; YYLTYPE * yylloc_r; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r # define yylloc yyg->yylloc_r int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; yylloc = yylloc_param; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 80 "src/core/io/dl-lexer.l" #line 1119 "src/core/io/dl-lexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 129 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 288 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 82 "src/core/io/dl-lexer.l" { return NEWLINE; } YY_BREAK case 2: YY_RULE_SETUP #line 84 "src/core/io/dl-lexer.l" { return DL; } YY_BREAK case 3: YY_RULE_SETUP #line 85 "src/core/io/dl-lexer.l" { return NEQ; } YY_BREAK case 4: YY_RULE_SETUP #line 87 "src/core/io/dl-lexer.l" { return NUM; } YY_BREAK case 5: YY_RULE_SETUP #line 89 "src/core/io/dl-lexer.l" { switch (yyextra->mode) { case 0: BEGIN(FULLMATRIX); break; case 1: BEGIN(EDGELIST); break; case 2: BEGIN(NODELIST); break; } return DATA; } YY_BREAK case 6: YY_RULE_SETUP #line 100 "src/core/io/dl-lexer.l" { BEGIN(LABELM); return LABELS; } YY_BREAK case 7: YY_RULE_SETUP #line 101 "src/core/io/dl-lexer.l" { return LABELSEMBEDDED; } YY_BREAK case 8: YY_RULE_SETUP #line 103 "src/core/io/dl-lexer.l" { yyextra->mode=0; return FORMATFULLMATRIX; } YY_BREAK case 9: YY_RULE_SETUP #line 105 "src/core/io/dl-lexer.l" { yyextra->mode=1; return FORMATEDGELIST1; } YY_BREAK case 10: YY_RULE_SETUP #line 107 "src/core/io/dl-lexer.l" { yyextra->mode=2; return FORMATNODELIST1; } YY_BREAK case 11: YY_RULE_SETUP #line 110 "src/core/io/dl-lexer.l" { /* eaten up */ } YY_BREAK case 12: YY_RULE_SETUP #line 111 "src/core/io/dl-lexer.l" { return LABEL; } YY_BREAK case 13: YY_RULE_SETUP #line 113 "src/core/io/dl-lexer.l" { return DIGIT; } YY_BREAK case 14: YY_RULE_SETUP #line 114 "src/core/io/dl-lexer.l" { return LABEL; } YY_BREAK case 15: YY_RULE_SETUP #line 115 "src/core/io/dl-lexer.l" { } YY_BREAK case 16: YY_RULE_SETUP #line 117 "src/core/io/dl-lexer.l" { return NUM; } YY_BREAK case 17: YY_RULE_SETUP #line 118 "src/core/io/dl-lexer.l" { return LABEL; } YY_BREAK case 18: YY_RULE_SETUP #line 119 "src/core/io/dl-lexer.l" { } YY_BREAK case 19: YY_RULE_SETUP #line 121 "src/core/io/dl-lexer.l" { return NUM; } YY_BREAK case 20: YY_RULE_SETUP #line 122 "src/core/io/dl-lexer.l" { return LABEL; } YY_BREAK case 21: YY_RULE_SETUP #line 123 "src/core/io/dl-lexer.l" { } YY_BREAK case 22: YY_RULE_SETUP #line 125 "src/core/io/dl-lexer.l" { /* eaten up */ } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(LABELM): case YY_STATE_EOF(FULLMATRIX): case YY_STATE_EOF(EDGELIST): case YY_STATE_EOF(NODELIST): #line 127 "src/core/io/dl-lexer.l" { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; BEGIN(INITIAL); return EOFF; } } YY_BREAK case 23: YY_RULE_SETUP #line 137 "src/core/io/dl-lexer.l" { return 0; } YY_BREAK case 24: YY_RULE_SETUP #line 138 "src/core/io/dl-lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK #line 1327 "src/core/io/dl-lexer.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 129 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 129 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_is_jam = (yy_current_state == 128); (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void __attribute__((unused)) yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ YYSTYPE * yyget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } YYLTYPE *yyget_lloc (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylloc; } void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylloc = yylloc_param; } /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 138 "src/core/io/dl-lexer.l" leidenbase/src/core/io/gml-lexer.c0000644000176200001440000017412214447675375016570 0ustar liggesusers#line 2 "src/core/io/gml-lexer.c" #line 4 "src/core/io/gml-lexer.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_gml_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_gml_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_gml_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_gml_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_gml_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_gml_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_gml_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_gml_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_gml_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_gml_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_gml_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_gml_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_gml_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_gml_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_gml_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_gml_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_gml_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_gml_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_gml_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_gml_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_gml_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_gml_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_gml_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_gml_yyensure_buffer_stack #endif #ifdef yylex #define igraph_gml_yylex_ALREADY_DEFINED #else #define yylex igraph_gml_yylex #endif #ifdef yyrestart #define igraph_gml_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_gml_yyrestart #endif #ifdef yylex_init #define igraph_gml_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_gml_yylex_init #endif #ifdef yylex_init_extra #define igraph_gml_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_gml_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_gml_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_gml_yylex_destroy #endif #ifdef yyget_debug #define igraph_gml_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_gml_yyget_debug #endif #ifdef yyset_debug #define igraph_gml_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_gml_yyset_debug #endif #ifdef yyget_extra #define igraph_gml_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_gml_yyget_extra #endif #ifdef yyset_extra #define igraph_gml_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_gml_yyset_extra #endif #ifdef yyget_in #define igraph_gml_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_gml_yyget_in #endif #ifdef yyset_in #define igraph_gml_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_gml_yyset_in #endif #ifdef yyget_out #define igraph_gml_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_gml_yyget_out #endif #ifdef yyset_out #define igraph_gml_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_gml_yyset_out #endif #ifdef yyget_leng #define igraph_gml_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_gml_yyget_leng #endif #ifdef yyget_text #define igraph_gml_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_gml_yyget_text #endif #ifdef yyget_lineno #define igraph_gml_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_gml_yyget_lineno #endif #ifdef yyset_lineno #define igraph_gml_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_gml_yyset_lineno #endif #ifdef yyget_column #define igraph_gml_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_gml_yyget_column #endif #ifdef yyset_column #define igraph_gml_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_gml_yyset_column #endif #ifdef yywrap #define igraph_gml_yywrap_ALREADY_DEFINED #else #define yywrap igraph_gml_yywrap #endif #ifdef yyget_lval #define igraph_gml_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_gml_yyget_lval #endif #ifdef yyset_lval #define igraph_gml_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_gml_yyset_lval #endif #ifdef yyget_lloc #define igraph_gml_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_gml_yyget_lloc #endif #ifdef yyset_lloc #define igraph_gml_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_gml_yyset_lloc #endif #ifdef yyalloc #define igraph_gml_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_gml_yyalloc #endif #ifdef yyrealloc #define igraph_gml_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_gml_yyrealloc #endif #ifdef yyfree #define igraph_gml_yyfree_ALREADY_DEFINED #else #define yyfree igraph_gml_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define igraph_gml_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void __attribute__((unused)) yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 10 #define YY_END_OF_BUFFER 11 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[29] = { 0, 0, 0, 11, 9, 8, 7, 7, 9, 9, 3, 4, 5, 6, 1, 9, 7, 0, 2, 3, 0, 0, 4, 0, 1, 3, 0, 3, 0 } ; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 6, 1, 1, 1, 1, 1, 1, 1, 7, 1, 8, 9, 1, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 11, 11, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 13, 1, 14, 1, 11, 1, 11, 11, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static const YY_CHAR yy_meta[16] = { 0, 1, 1, 1, 2, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 4 } ; static const flex_int16_t yy_base[32] = { 0, 0, 12, 44, 45, 45, 39, 39, 36, 30, 10, 0, 45, 45, 36, 35, 45, 32, 45, 0, 26, 16, 0, 32, 45, 15, 22, 11, 45, 27, 14, 30 } ; static const flex_int16_t yy_def[32] = { 0, 28, 1, 28, 28, 28, 28, 28, 29, 28, 28, 30, 28, 28, 28, 31, 28, 29, 28, 10, 28, 28, 30, 31, 28, 28, 28, 28, 0, 28, 28, 28 } ; static const flex_int16_t yy_nxt[61] = { 0, 4, 5, 6, 7, 8, 4, 4, 9, 4, 10, 11, 11, 12, 13, 4, 14, 22, 15, 20, 19, 27, 21, 26, 26, 25, 27, 21, 17, 17, 17, 23, 27, 23, 23, 24, 25, 18, 24, 16, 19, 18, 16, 16, 28, 3, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28 } ; static const flex_int16_t yy_chk[61] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 30, 2, 10, 10, 27, 10, 21, 21, 25, 21, 25, 29, 29, 29, 31, 26, 31, 31, 23, 20, 17, 15, 14, 9, 8, 7, 6, 3, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "src/core/io/gml-lexer.l" /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #line 24 "src/core/io/gml-lexer.l" /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "io/gml-header.h" #include "io/gml-parser.h" #define YY_EXTRA_TYPE igraph_i_gml_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in GML parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif #line 736 "src/core/io/gml-lexer.c" #define YY_NO_INPUT 1 #line 738 "src/core/io/gml-lexer.c" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; YYSTYPE * yylval_r; YYLTYPE * yylloc_r; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r # define yylloc yyg->yylloc_r int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; yylloc = yylloc_param; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 77 "src/core/io/gml-lexer.l" #line 1026 "src/core/io/gml-lexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 29 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 45 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 79 "src/core/io/gml-lexer.l" { /* comments ignored */ } YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP #line 81 "src/core/io/gml-lexer.l" { return STRING; } YY_BREAK case 3: YY_RULE_SETUP #line 82 "src/core/io/gml-lexer.l" { return NUM; } YY_BREAK case 4: YY_RULE_SETUP #line 83 "src/core/io/gml-lexer.l" { return KEYWORD; } YY_BREAK case 5: YY_RULE_SETUP #line 84 "src/core/io/gml-lexer.l" { yyextra->depth++; if (yyextra->depth >= 32) { return ERROR; } else { return LISTOPEN; } } YY_BREAK case 6: YY_RULE_SETUP #line 92 "src/core/io/gml-lexer.l" { yyextra->depth--; if (yyextra->depth < 0) { return ERROR; } else { return LISTCLOSE; } } YY_BREAK case 7: /* rule 7 can match eol */ YY_RULE_SETUP #line 100 "src/core/io/gml-lexer.l" { } YY_BREAK case 8: /* rule 8 can match eol */ YY_RULE_SETUP #line 101 "src/core/io/gml-lexer.l" { /* other whitespace ignored */ } YY_BREAK case YY_STATE_EOF(INITIAL): #line 103 "src/core/io/gml-lexer.l" { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; return EOFF; } } YY_BREAK case 9: YY_RULE_SETUP #line 111 "src/core/io/gml-lexer.l" { return ERROR; } YY_BREAK case 10: YY_RULE_SETUP #line 112 "src/core/io/gml-lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK #line 1163 "src/core/io/gml-lexer.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; yy_current_state += YY_AT_BOL(); for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 15); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 29 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; YY_CHAR yy_c = 15; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 29 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_is_jam = (yy_current_state == 28); (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void __attribute__((unused)) yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ YYSTYPE * yyget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } YYLTYPE *yyget_lloc (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylloc; } void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylloc = yylloc_param; } /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 112 "src/core/io/gml-lexer.l" leidenbase/src/core/io/gml-header.h0000644000176200001440000000246414447675374016704 0ustar liggesusers/* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge MA, 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_error.h" #include "io/gml-tree.h" typedef struct { void *scanner; int eof; int depth; char errmsg[300]; igraph_gml_tree_t *tree; } igraph_i_gml_parsedata_t; /** * Initializes a GML parser context. */ int igraph_i_gml_parsedata_init(igraph_i_gml_parsedata_t* context); /** * Destroys a GML parser context, freeing all memory currently used by the * context. */ void igraph_i_gml_parsedata_destroy(igraph_i_gml_parsedata_t* context); leidenbase/src/core/io/dl-header.h0000644000176200001440000000250614447675374016521 0ustar liggesusers/* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_error.h" #include "igraph_types.h" #include "core/trie.h" typedef enum { IGRAPH_DL_MATRIX, IGRAPH_DL_EDGELIST1, IGRAPH_DL_NODELIST1 } igraph_i_dl_type_t; typedef struct { void *scanner; int eof; int mode; long int n; long int from, to; igraph_vector_t edges; igraph_vector_t weights; igraph_strvector_t labels; igraph_trie_t trie; igraph_i_dl_type_t type; char errmsg[300]; } igraph_i_dl_parsedata_t; leidenbase/src/core/io/dl-parser.c0000644000176200001440000023352514447675375016570 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ #define YYBISON 30802 /* Bison version string. */ #define YYBISON_VERSION "3.8.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Substitute the variable and function names. */ #define yyparse igraph_dl_yyparse #define yylex igraph_dl_yylex #define yyerror igraph_dl_yyerror #define yydebug igraph_dl_yydebug #define yynerrs igraph_dl_yynerrs /* First part of user prologue. */ #line 23 "src/core/io/dl-parser.y" /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include "core/math.h" #include "internal/hacks.h" #include "io/dl-header.h" #include "io/dl-parser.h" #include "io/dl-lexer.h" #include int igraph_dl_yyerror(YYLTYPE* locp, igraph_i_dl_parsedata_t* context, const char *s); int igraph_i_dl_add_str(char *newstr, int length, igraph_i_dl_parsedata_t *context); int igraph_i_dl_add_edge(long int from, long int to, igraph_i_dl_parsedata_t *context); int igraph_i_dl_add_edge_w(long int from, long int to, igraph_real_t weight, igraph_i_dl_parsedata_t *context); extern igraph_real_t igraph_pajek_get_number(const char *str, long int len); #define scanner context->scanner #line 126 "yy.tab.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif #include "io/dl-parser.h" /* Symbol kind. */ enum yysymbol_kind_t { YYSYMBOL_YYEMPTY = -2, YYSYMBOL_YYEOF = 0, /* "end of file" */ YYSYMBOL_YYerror = 1, /* error */ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ YYSYMBOL_NUM = 3, /* NUM */ YYSYMBOL_NEWLINE = 4, /* NEWLINE */ YYSYMBOL_DL = 5, /* DL */ YYSYMBOL_NEQ = 6, /* NEQ */ YYSYMBOL_DATA = 7, /* DATA */ YYSYMBOL_LABELS = 8, /* LABELS */ YYSYMBOL_LABELSEMBEDDED = 9, /* LABELSEMBEDDED */ YYSYMBOL_FORMATFULLMATRIX = 10, /* FORMATFULLMATRIX */ YYSYMBOL_FORMATEDGELIST1 = 11, /* FORMATEDGELIST1 */ YYSYMBOL_FORMATNODELIST1 = 12, /* FORMATNODELIST1 */ YYSYMBOL_DIGIT = 13, /* DIGIT */ YYSYMBOL_LABEL = 14, /* LABEL */ YYSYMBOL_EOFF = 15, /* EOFF */ YYSYMBOL_ERROR = 16, /* ERROR */ YYSYMBOL_YYACCEPT = 17, /* $accept */ YYSYMBOL_input = 18, /* input */ YYSYMBOL_trail = 19, /* trail */ YYSYMBOL_eof = 20, /* eof */ YYSYMBOL_rest = 21, /* rest */ YYSYMBOL_formfullmatrix = 22, /* formfullmatrix */ YYSYMBOL_newline = 23, /* newline */ YYSYMBOL_fullmatrix = 24, /* fullmatrix */ YYSYMBOL_labels = 25, /* labels */ YYSYMBOL_fullmatrixdata = 26, /* fullmatrixdata */ YYSYMBOL_zerooneseq = 27, /* zerooneseq */ YYSYMBOL_zeroone = 28, /* zeroone */ YYSYMBOL_labeledfullmatrixdata = 29, /* labeledfullmatrixdata */ YYSYMBOL_reallabeledfullmatrixdata = 30, /* reallabeledfullmatrixdata */ YYSYMBOL_labelseq = 31, /* labelseq */ YYSYMBOL_label = 32, /* label */ YYSYMBOL_labeledmatrixlines = 33, /* labeledmatrixlines */ YYSYMBOL_labeledmatrixline = 34, /* labeledmatrixline */ YYSYMBOL_edgelist1 = 35, /* edgelist1 */ YYSYMBOL_edgelist1rest = 36, /* edgelist1rest */ YYSYMBOL_edgelist1data = 37, /* edgelist1data */ YYSYMBOL_edgelist1dataline = 38, /* edgelist1dataline */ YYSYMBOL_integer = 39, /* integer */ YYSYMBOL_labelededgelist1data = 40, /* labelededgelist1data */ YYSYMBOL_labelededgelist1dataline = 41, /* labelededgelist1dataline */ YYSYMBOL_weight = 42, /* weight */ YYSYMBOL_elabel = 43, /* elabel */ YYSYMBOL_nodelist1 = 44, /* nodelist1 */ YYSYMBOL_nodelist1rest = 45, /* nodelist1rest */ YYSYMBOL_nodelist1data = 46, /* nodelist1data */ YYSYMBOL_nodelist1dataline = 47, /* nodelist1dataline */ YYSYMBOL_from = 48, /* from */ YYSYMBOL_tolist = 49, /* tolist */ YYSYMBOL_labelednodelist1data = 50, /* labelednodelist1data */ YYSYMBOL_labelednodelist1dataline = 51, /* labelednodelist1dataline */ YYSYMBOL_fromelabel = 52, /* fromelabel */ YYSYMBOL_labeltolist = 53 /* labeltolist */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif /* Work around bug in HP-UX 11.23, which defines these macros incorrectly for preprocessor constants. This workaround can likely be removed in 2023, as HPE has promised support for HP-UX 11.23 (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of . */ #ifdef __hpux # undef UINT_LEAST8_MAX # undef UINT_LEAST16_MAX # define UINT_LEAST8_MAX 255 # define UINT_LEAST16_MAX 65535 #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_uint8 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YY_USE(E) ((void) (E)) #else # define YY_USE(E) /* empty */ #endif /* Suppress an incorrect diagnostic about yylval being uninitialized. */ #if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ # if __GNUC__ * 100 + __GNUC_MINOR__ < 407 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") # else # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # endif # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if 1 /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* 1 */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ + YYSIZEOF (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 4 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 118 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 17 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 37 /* YYNRULES -- Number of rules. */ #define YYNRULES 66 /* YYNSTATES -- Number of states. */ #define YYNSTATES 138 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 271 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK \ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { 0, 108, 108, 110, 110, 112, 112, 114, 115, 116, 119, 119, 121, 121, 123, 124, 125, 128, 129, 135, 135, 140, 140, 142, 152, 154, 156, 156, 158, 162, 166, 171, 175, 177, 178, 179, 180, 181, 184, 185, 188, 190, 194, 197, 198, 201, 203, 207, 210, 226, 228, 229, 230, 231, 232, 235, 236, 239, 241, 244, 244, 250, 251, 254, 256, 260, 260 }; #endif /** Accessing symbol of state STATE. */ #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) #if 1 /* The user-facing name of the symbol whose (internal) number is YYSYMBOL. No bounds checking. */ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "\"end of file\"", "error", "\"invalid token\"", "NUM", "NEWLINE", "DL", "NEQ", "DATA", "LABELS", "LABELSEMBEDDED", "FORMATFULLMATRIX", "FORMATEDGELIST1", "FORMATNODELIST1", "DIGIT", "LABEL", "EOFF", "ERROR", "$accept", "input", "trail", "eof", "rest", "formfullmatrix", "newline", "fullmatrix", "labels", "fullmatrixdata", "zerooneseq", "zeroone", "labeledfullmatrixdata", "reallabeledfullmatrixdata", "labelseq", "label", "labeledmatrixlines", "labeledmatrixline", "edgelist1", "edgelist1rest", "edgelist1data", "edgelist1dataline", "integer", "labelededgelist1data", "labelededgelist1dataline", "weight", "elabel", "nodelist1", "nodelist1rest", "nodelist1data", "nodelist1dataline", "from", "tolist", "labelednodelist1data", "labelednodelist1dataline", "fromelabel", "labeltolist", YY_NULLPTR }; static const char * yysymbol_name (yysymbol_kind_t yysymbol) { return yytname[yysymbol]; } #endif #define YYPACT_NINF (-114) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-22) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int8 yypact[] = { 8, 38, 11, 43, -114, -114, 44, 57, 46, 46, 46, 46, 46, 46, -114, -114, -114, -114, -114, -114, -114, -114, 69, 53, 63, 66, 6, 65, 46, 46, -114, 46, 46, 46, -114, -114, 46, 46, -114, -114, -114, -114, 5, 19, -114, -114, -114, 76, 84, -114, 82, -114, -114, -114, 46, -114, -114, -114, 93, 43, 46, 46, 46, -114, -114, -114, 46, 46, 46, -114, 85, 86, -114, 43, 23, -114, -114, 88, 33, -114, -114, 65, -114, 85, -114, -114, -114, 90, 46, 46, 87, 46, -114, -114, 46, 46, 87, 46, 25, -114, -114, -114, 94, -114, 95, -114, -114, 87, 29, -114, 96, -114, -114, -114, 49, -114, -114, 43, 46, 92, 46, 84, 46, 2, 46, -114, -114, 100, -114, -114, -114, -114, -114, 87, -114, 87, 87, 87 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_int8 yydefact[] = { 0, 0, 0, 0, 1, 42, 0, 0, 12, 12, 12, 12, 12, 12, 3, 7, 11, 8, 9, 13, 19, 17, 0, 0, 0, 0, 5, 14, 12, 12, 10, 12, 12, 12, 32, 55, 12, 12, 49, 6, 2, 4, 0, 0, 26, 38, 17, 0, 50, 17, 0, 20, 23, 22, 12, 18, 16, 24, 12, 33, 12, 12, 12, 58, 56, 59, 12, 12, 12, 19, 0, 0, 39, 0, 0, 43, 17, 0, 0, 61, 17, 15, 21, 25, 29, 28, 27, 0, 12, 12, 35, 12, 57, 60, 12, 12, 52, 12, 0, 30, 47, 41, 0, 38, 0, 48, 44, 0, 0, 55, 0, 64, 62, 65, 0, 31, 40, 34, 12, 0, 12, 51, 12, 0, 12, 43, 46, 0, 43, 61, 63, 66, 61, 36, 45, 37, 53, 54 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -114, -114, -114, -114, -114, -114, -9, 83, -41, 36, 26, -114, -114, -114, -114, -114, -114, 24, -114, -114, 7, -114, 4, -113, -114, -7, -82, -114, -114, 9, -114, -114, -114, -98, -114, -114, -114 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { 0, 2, 26, 40, 14, 15, 20, 16, 28, 27, 42, 53, 56, 57, 58, 86, 83, 84, 17, 34, 59, 72, 73, 90, 106, 102, 107, 18, 38, 48, 64, 65, 77, 96, 112, 113, 123 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { 21, 22, 23, 24, 25, 60, 130, 6, 66, 51, 19, 4, 133, 1, 111, 135, 105, 41, 52, 43, 44, 39, 45, 46, 47, 119, 54, 49, 50, 115, 88, 136, 89, 55, 137, 91, 120, 55, 52, 97, 94, 131, 95, 55, 3, 69, 5, 55, 7, 71, 19, 74, 75, 76, 111, 111, 124, 78, 79, 80, 8, 9, 10, 55, 8, 9, 10, 11, 12, 13, 31, 32, 33, 35, 36, 37, 29, 87, -21, 103, 104, 93, 108, 61, 62, 109, 110, 63, 114, 67, 68, 5, 92, 100, 101, 100, 126, 70, 116, 82, 85, 105, 118, 122, 134, 81, 30, 99, 98, 125, 117, 128, 127, 129, 0, 132, 0, 0, 121 }; static const yytype_int16 yycheck[] = { 9, 10, 11, 12, 13, 46, 4, 3, 49, 4, 4, 0, 125, 5, 96, 128, 14, 26, 13, 28, 29, 15, 31, 32, 33, 107, 7, 36, 37, 4, 7, 129, 9, 14, 132, 76, 7, 14, 13, 80, 7, 123, 9, 14, 6, 54, 3, 14, 4, 58, 4, 60, 61, 62, 136, 137, 7, 66, 67, 68, 7, 8, 9, 14, 7, 8, 9, 10, 11, 12, 7, 8, 9, 7, 8, 9, 7, 73, 13, 88, 89, 77, 91, 7, 8, 94, 95, 3, 97, 7, 8, 3, 4, 3, 4, 3, 4, 4, 4, 14, 14, 14, 7, 7, 4, 69, 23, 83, 82, 118, 103, 120, 119, 122, -1, 124, -1, -1, 109 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { 0, 5, 18, 6, 0, 3, 39, 4, 7, 8, 9, 10, 11, 12, 21, 22, 24, 35, 44, 4, 23, 23, 23, 23, 23, 23, 19, 26, 25, 7, 24, 7, 8, 9, 36, 7, 8, 9, 45, 15, 20, 23, 27, 23, 23, 23, 23, 23, 46, 23, 23, 4, 13, 28, 7, 14, 29, 30, 31, 37, 25, 7, 8, 3, 47, 48, 25, 7, 8, 23, 4, 23, 38, 39, 23, 23, 23, 49, 23, 23, 23, 26, 14, 33, 34, 14, 32, 39, 7, 9, 40, 25, 4, 39, 7, 9, 50, 25, 27, 34, 3, 4, 42, 23, 23, 14, 41, 43, 23, 23, 23, 43, 51, 52, 23, 4, 4, 37, 7, 43, 7, 46, 7, 53, 7, 23, 4, 42, 23, 23, 4, 43, 23, 40, 4, 40, 50, 50 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int8 yyr1[] = { 0, 17, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27, 28, 29, 30, 31, 31, 32, 33, 33, 34, 35, 36, 36, 36, 36, 36, 37, 37, 38, 38, 39, 40, 40, 41, 41, 42, 43, 44, 45, 45, 45, 45, 45, 46, 46, 47, 48, 49, 49, 50, 50, 51, 52, 53, 53 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ static const yytype_int8 yyr2[] = { 0, 2, 7, 0, 2, 0, 1, 1, 1, 1, 3, 1, 0, 1, 3, 7, 5, 0, 3, 0, 3, 0, 2, 1, 1, 3, 0, 3, 1, 1, 2, 3, 3, 3, 7, 5, 9, 9, 0, 2, 4, 3, 1, 0, 2, 4, 3, 1, 1, 3, 2, 7, 5, 9, 9, 0, 2, 3, 1, 0, 2, 0, 2, 3, 1, 0, 2 }; enum { YYENOMEM = -2 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Backward compatibility with an undocumented macro. Use YYerror or YYUNDEF. */ #define YYERRCODE YYUNDEF /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (N) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (0) #endif #define YYRHSLOC(Rhs, K) ((Rhs)[K]) /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* YYLOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ # ifndef YYLOCATION_PRINT # if defined YY_LOCATION_PRINT /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc)) # elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL /* Print *YYLOCP on YYO. Private, do not rely on its existence. */ YY_ATTRIBUTE_UNUSED static int yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) { int res = 0; int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; if (0 <= yylocp->first_line) { res += YYFPRINTF (yyo, "%d", yylocp->first_line); if (0 <= yylocp->first_column) res += YYFPRINTF (yyo, ".%d", yylocp->first_column); } if (0 <= yylocp->last_line) { if (yylocp->first_line < yylocp->last_line) { res += YYFPRINTF (yyo, "-%d", yylocp->last_line); if (0 <= end_col) res += YYFPRINTF (yyo, ".%d", end_col); } else if (0 <= end_col && yylocp->first_column < end_col) res += YYFPRINTF (yyo, "-%d", end_col); } return res; } # define YYLOCATION_PRINT yy_location_print_ /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc)) # else # define YYLOCATION_PRINT(File, Loc) ((void) 0) /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT YYLOCATION_PRINT # endif # endif /* !defined YYLOCATION_PRINT */ # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Kind, Value, Location, context); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_dl_parsedata_t* context) { FILE *yyoutput = yyo; YY_USE (yyoutput); YY_USE (yylocationp); YY_USE (context); if (!yyvaluep) return; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_dl_parsedata_t* context) { YYFPRINTF (yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); YYLOCATION_PRINT (yyo, yylocationp); YYFPRINTF (yyo, ": "); yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp, context); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, igraph_i_dl_parsedata_t* context) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), &yyvsp[(yyi + 1) - (yynrhs)], &(yylsp[(yyi + 1) - (yynrhs)]), context); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, yylsp, Rule, context); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) ((void) 0) # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif /* Context of a parse error. */ typedef struct { yy_state_t *yyssp; yysymbol_kind_t yytoken; YYLTYPE *yylloc; } yypcontext_t; /* Put in YYARG at most YYARGN of the expected tokens given the current YYCTX, and return the number of tokens stored in YYARG. If YYARG is null, return the number of expected tokens (guaranteed to be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. Return 0 if there are more than YYARGN expected tokens, yet fill YYARG up to YYARGN. */ static int yypcontext_expected_tokens (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; int yyn = yypact[+*yyctx->yyssp]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror && !yytable_value_is_error (yytable[yyx + yyn])) { if (!yyarg) ++yycount; else if (yycount == yyargn) return 0; else yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); } } if (yyarg && yycount == 0 && 0 < yyargn) yyarg[0] = YYSYMBOL_YYEMPTY; return yycount; } #ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) { YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif #endif #ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif #endif #ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; else goto append; append: default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (yyres) return yystpcpy (yyres, yystr) - yyres; else return yystrlen (yystr); } #endif static int yy_syntax_error_arguments (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yyctx->yytoken != YYSYMBOL_YYEMPTY) { int yyn; if (yyarg) yyarg[yycount] = yyctx->yytoken; ++yycount; yyn = yypcontext_expected_tokens (yyctx, yyarg ? yyarg + 1 : yyarg, yyargn - 1); if (yyn == YYENOMEM) return YYENOMEM; else yycount += yyn; } return yycount; } /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the required number of bytes is too large to store. */ static int yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, const yypcontext_t *yyctx) { enum { YYARGS_MAX = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ yysymbol_kind_t yyarg[YYARGS_MAX]; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; /* Actual size of YYARG. */ int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); if (yycount == YYENOMEM) return YYENOMEM; switch (yycount) { #define YYCASE_(N, S) \ case N: \ yyformat = S; \ break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); #undef YYCASE_ } /* Compute error message size. Don't count the "%s"s, but reserve room for the terminator. */ yysize = yystrlen (yyformat) - 2 * yycount + 1; { int yyi; for (yyi = 0; yyi < yycount; ++yyi) { YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return YYENOMEM; } } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return -1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); yyformat += 2; } else { ++yyp; ++yyformat; } } return 0; } /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, igraph_i_dl_parsedata_t* context) { YY_USE (yyvaluep); YY_USE (yylocationp); YY_USE (context); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*----------. | yyparse. | `----------*/ int yyparse (igraph_i_dl_parsedata_t* context) { /* Lookahead token kind. */ int yychar; /* The semantic value of the lookahead symbol. */ /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Location data for the lookahead symbol. */ static YYLTYPE yyloc_default # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL = { 1, 1, 1, 1 } # endif ; YYLTYPE yylloc = yyloc_default; /* Number of syntax errors so far. */ int yynerrs = 0; yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus = 0; /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* Their size. */ YYPTRDIFF_T yystacksize = YYINITDEPTH; /* The state stack: array, bottom, top. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss = yyssa; yy_state_t *yyssp = yyss; /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp = yyvs; /* The location stack: array, bottom, top. */ YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp = yyls; int yyn; /* The return value of yyparse. */ int yyresult; /* Lookahead symbol kind. */ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; /* The locations where the error started and ended. */ YYLTYPE yyerror_range[3]; /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ yylsp[0] = yylloc; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE YYNOMEM; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; YYLTYPE *yyls1 = yyls; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yyls1, yysize * YYSIZEOF (*yylsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; yyls = yyls1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) YYNOMEM; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) YYNOMEM; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; yylsp = yyls + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (&yylval, &yylloc, scanner); } if (yychar <= YYEOF) { yychar = YYEOF; yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else if (yychar == YYerror) { /* The scanner already issued an error message, process directly to error recovery. But do not keep the error token as lookahead, it is too special and may lead us to an endless loop in error recovery. */ yychar = YYUNDEF; yytoken = YYSYMBOL_YYerror; yyerror_range[1] = yylloc; goto yyerrlab1; } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END *++yylsp = yylloc; /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); yyerror_range[1] = yyloc; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: /* input: DL NEQ integer NEWLINE rest trail eof */ #line 108 "src/core/io/dl-parser.y" { context->n=(yyvsp[-4].integer); } #line 1646 "yy.tab.c" break; case 7: /* rest: formfullmatrix */ #line 114 "src/core/io/dl-parser.y" { context->type=IGRAPH_DL_MATRIX; } #line 1652 "yy.tab.c" break; case 8: /* rest: edgelist1 */ #line 115 "src/core/io/dl-parser.y" { context->type=IGRAPH_DL_EDGELIST1; } #line 1658 "yy.tab.c" break; case 9: /* rest: nodelist1 */ #line 116 "src/core/io/dl-parser.y" { context->type=IGRAPH_DL_NODELIST1; } #line 1664 "yy.tab.c" break; case 10: /* formfullmatrix: FORMATFULLMATRIX newline fullmatrix */ #line 119 "src/core/io/dl-parser.y" {} #line 1670 "yy.tab.c" break; case 11: /* formfullmatrix: fullmatrix */ #line 119 "src/core/io/dl-parser.y" {} #line 1676 "yy.tab.c" break; case 14: /* fullmatrix: DATA newline fullmatrixdata */ #line 123 "src/core/io/dl-parser.y" { } #line 1682 "yy.tab.c" break; case 15: /* fullmatrix: LABELS newline labels newline DATA newline fullmatrixdata */ #line 124 "src/core/io/dl-parser.y" { } #line 1688 "yy.tab.c" break; case 16: /* fullmatrix: LABELSEMBEDDED newline DATA newline labeledfullmatrixdata */ #line 125 "src/core/io/dl-parser.y" { } #line 1694 "yy.tab.c" break; case 17: /* labels: %empty */ #line 128 "src/core/io/dl-parser.y" {} #line 1700 "yy.tab.c" break; case 18: /* labels: labels newline LABEL */ #line 129 "src/core/io/dl-parser.y" { igraph_i_dl_add_str(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner), context); } #line 1709 "yy.tab.c" break; case 19: /* fullmatrixdata: %empty */ #line 135 "src/core/io/dl-parser.y" {} #line 1715 "yy.tab.c" break; case 20: /* fullmatrixdata: fullmatrixdata zerooneseq NEWLINE */ #line 135 "src/core/io/dl-parser.y" { context->from += 1; context->to = 0; } #line 1724 "yy.tab.c" break; case 22: /* zerooneseq: zerooneseq zeroone */ #line 140 "src/core/io/dl-parser.y" { } #line 1730 "yy.tab.c" break; case 23: /* zeroone: DIGIT */ #line 142 "src/core/io/dl-parser.y" { if (igraph_dl_yyget_text(scanner)[0]=='1') { IGRAPH_CHECK(igraph_vector_push_back(&context->edges, context->from)); IGRAPH_CHECK(igraph_vector_push_back(&context->edges, context->to)); } context->to += 1; } #line 1744 "yy.tab.c" break; case 24: /* labeledfullmatrixdata: reallabeledfullmatrixdata */ #line 152 "src/core/io/dl-parser.y" {} #line 1750 "yy.tab.c" break; case 25: /* reallabeledfullmatrixdata: labelseq NEWLINE labeledmatrixlines */ #line 154 "src/core/io/dl-parser.y" {} #line 1756 "yy.tab.c" break; case 28: /* label: LABEL */ #line 158 "src/core/io/dl-parser.y" { igraph_i_dl_add_str(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner), context); } #line 1764 "yy.tab.c" break; case 29: /* labeledmatrixlines: labeledmatrixline */ #line 162 "src/core/io/dl-parser.y" { context->from += 1; context->to = 0; } #line 1773 "yy.tab.c" break; case 30: /* labeledmatrixlines: labeledmatrixlines labeledmatrixline */ #line 166 "src/core/io/dl-parser.y" { context->from += 1; context->to = 0; } #line 1782 "yy.tab.c" break; case 31: /* labeledmatrixline: LABEL zerooneseq NEWLINE */ #line 171 "src/core/io/dl-parser.y" { } #line 1788 "yy.tab.c" break; case 32: /* edgelist1: FORMATEDGELIST1 newline edgelist1rest */ #line 175 "src/core/io/dl-parser.y" {} #line 1794 "yy.tab.c" break; case 33: /* edgelist1rest: DATA newline edgelist1data */ #line 177 "src/core/io/dl-parser.y" {} #line 1800 "yy.tab.c" break; case 34: /* edgelist1rest: LABELS newline labels newline DATA newline edgelist1data */ #line 178 "src/core/io/dl-parser.y" {} #line 1806 "yy.tab.c" break; case 35: /* edgelist1rest: LABELSEMBEDDED newline DATA newline labelededgelist1data */ #line 179 "src/core/io/dl-parser.y" {} #line 1812 "yy.tab.c" break; case 36: /* edgelist1rest: LABELS newline labels newline LABELSEMBEDDED newline DATA newline labelededgelist1data */ #line 180 "src/core/io/dl-parser.y" {} #line 1818 "yy.tab.c" break; case 37: /* edgelist1rest: LABELSEMBEDDED newline LABELS newline labels newline DATA newline labelededgelist1data */ #line 181 "src/core/io/dl-parser.y" {} #line 1824 "yy.tab.c" break; case 38: /* edgelist1data: %empty */ #line 184 "src/core/io/dl-parser.y" {} #line 1830 "yy.tab.c" break; case 39: /* edgelist1data: edgelist1data edgelist1dataline */ #line 185 "src/core/io/dl-parser.y" {} #line 1836 "yy.tab.c" break; case 40: /* edgelist1dataline: integer integer weight NEWLINE */ #line 188 "src/core/io/dl-parser.y" { igraph_i_dl_add_edge_w((yyvsp[-3].integer)-1, (yyvsp[-2].integer)-1, (yyvsp[-1].real), context); } #line 1843 "yy.tab.c" break; case 41: /* edgelist1dataline: integer integer NEWLINE */ #line 190 "src/core/io/dl-parser.y" { igraph_i_dl_add_edge((yyvsp[-2].integer)-1, (yyvsp[-1].integer)-1, context); } #line 1851 "yy.tab.c" break; case 42: /* integer: NUM */ #line 194 "src/core/io/dl-parser.y" { (yyval.integer)=igraph_pajek_get_number(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner)); } #line 1858 "yy.tab.c" break; case 43: /* labelededgelist1data: %empty */ #line 197 "src/core/io/dl-parser.y" {} #line 1864 "yy.tab.c" break; case 44: /* labelededgelist1data: labelededgelist1data labelededgelist1dataline */ #line 198 "src/core/io/dl-parser.y" {} #line 1870 "yy.tab.c" break; case 45: /* labelededgelist1dataline: elabel elabel weight NEWLINE */ #line 201 "src/core/io/dl-parser.y" { igraph_i_dl_add_edge_w((yyvsp[-3].integer), (yyvsp[-2].integer), (yyvsp[-1].real), context); } #line 1877 "yy.tab.c" break; case 46: /* labelededgelist1dataline: elabel elabel NEWLINE */ #line 203 "src/core/io/dl-parser.y" { igraph_i_dl_add_edge((yyvsp[-2].integer), (yyvsp[-1].integer), context); } #line 1885 "yy.tab.c" break; case 47: /* weight: NUM */ #line 207 "src/core/io/dl-parser.y" { (yyval.real)=igraph_pajek_get_number(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner)); } #line 1892 "yy.tab.c" break; case 48: /* elabel: LABEL */ #line 210 "src/core/io/dl-parser.y" { /* Copy label list to trie, if needed */ if (igraph_strvector_size(&context->labels) != 0) { long int i, id, n=igraph_strvector_size(&context->labels); for (i=0; itrie, STR(context->labels, i), &id); } igraph_strvector_clear(&context->labels); } igraph_trie_get2(&context->trie, igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner), &(yyval.integer)); } #line 1910 "yy.tab.c" break; case 49: /* nodelist1: FORMATNODELIST1 newline nodelist1rest */ #line 226 "src/core/io/dl-parser.y" {} #line 1916 "yy.tab.c" break; case 50: /* nodelist1rest: DATA nodelist1data */ #line 228 "src/core/io/dl-parser.y" {} #line 1922 "yy.tab.c" break; case 51: /* nodelist1rest: LABELS newline labels newline DATA newline nodelist1data */ #line 229 "src/core/io/dl-parser.y" {} #line 1928 "yy.tab.c" break; case 52: /* nodelist1rest: LABELSEMBEDDED newline DATA newline labelednodelist1data */ #line 230 "src/core/io/dl-parser.y" {} #line 1934 "yy.tab.c" break; case 53: /* nodelist1rest: LABELS newline labels newline LABELSEMBEDDED newline DATA newline labelednodelist1data */ #line 231 "src/core/io/dl-parser.y" {} #line 1940 "yy.tab.c" break; case 54: /* nodelist1rest: LABELSEMBEDDED newline LABELS newline labels newline DATA newline labelednodelist1data */ #line 232 "src/core/io/dl-parser.y" {} #line 1946 "yy.tab.c" break; case 55: /* nodelist1data: %empty */ #line 235 "src/core/io/dl-parser.y" {} #line 1952 "yy.tab.c" break; case 56: /* nodelist1data: nodelist1data nodelist1dataline */ #line 236 "src/core/io/dl-parser.y" {} #line 1958 "yy.tab.c" break; case 57: /* nodelist1dataline: from tolist NEWLINE */ #line 239 "src/core/io/dl-parser.y" {} #line 1964 "yy.tab.c" break; case 58: /* from: NUM */ #line 241 "src/core/io/dl-parser.y" { context->from=igraph_pajek_get_number(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner)); } #line 1971 "yy.tab.c" break; case 59: /* tolist: %empty */ #line 244 "src/core/io/dl-parser.y" {} #line 1977 "yy.tab.c" break; case 60: /* tolist: tolist integer */ #line 244 "src/core/io/dl-parser.y" { IGRAPH_CHECK(igraph_vector_push_back(&context->edges, context->from-1)); IGRAPH_CHECK(igraph_vector_push_back(&context->edges, (yyvsp[0].integer)-1)); } #line 1987 "yy.tab.c" break; case 61: /* labelednodelist1data: %empty */ #line 250 "src/core/io/dl-parser.y" {} #line 1993 "yy.tab.c" break; case 62: /* labelednodelist1data: labelednodelist1data labelednodelist1dataline */ #line 251 "src/core/io/dl-parser.y" {} #line 1999 "yy.tab.c" break; case 63: /* labelednodelist1dataline: fromelabel labeltolist NEWLINE */ #line 254 "src/core/io/dl-parser.y" { } #line 2005 "yy.tab.c" break; case 64: /* fromelabel: elabel */ #line 256 "src/core/io/dl-parser.y" { context->from=(yyvsp[0].integer); } #line 2013 "yy.tab.c" break; case 66: /* labeltolist: labeltolist elabel */ #line 260 "src/core/io/dl-parser.y" { IGRAPH_CHECK(igraph_vector_push_back(&context->edges, context->from)); IGRAPH_CHECK(igraph_vector_push_back(&context->edges, (yyvsp[0].integer))); } #line 2023 "yy.tab.c" break; #line 2027 "yy.tab.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; *++yyvsp = yyval; *++yylsp = yyloc; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; { yypcontext_t yyctx = {yyssp, yytoken, &yylloc}; char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == -1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (yymsg) { yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); yymsgp = yymsg; } else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = YYENOMEM; } } yyerror (&yylloc, context, yymsgp); if (yysyntax_error_status == YYENOMEM) YYNOMEM; } } yyerror_range[1] = yylloc; if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, &yylloc, context); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYSYMBOL_YYerror; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yyerror_range[1] = *yylsp; yydestruct ("Error: popping", YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp, context); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END yyerror_range[2] = yylloc; ++yylsp; YYLLOC_DEFAULT (*yylsp, yyerror_range, 2); /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturnlab; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturnlab; /*-----------------------------------------------------------. | yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | `-----------------------------------------------------------*/ yyexhaustedlab: yyerror (&yylloc, context, YY_("memory exhausted")); yyresult = 2; goto yyreturnlab; /*----------------------------------------------------------. | yyreturnlab -- parsing is finished, clean up and return. | `----------------------------------------------------------*/ yyreturnlab: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, context); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp, context); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); return yyresult; } #line 266 "src/core/io/dl-parser.y" int igraph_dl_yyerror(YYLTYPE* locp, igraph_i_dl_parsedata_t* context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char)-1, "%s in line %i", s, locp->first_line); return 0; } int igraph_i_dl_add_str(char *newstr, int length, igraph_i_dl_parsedata_t *context) { int tmp=newstr[length]; newstr[length]='\0'; IGRAPH_CHECK(igraph_strvector_add(&context->labels, newstr)); newstr[length]=tmp; return 0; } int igraph_i_dl_add_edge(long int from, long int to, igraph_i_dl_parsedata_t *context) { IGRAPH_CHECK(igraph_vector_push_back(&context->edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&context->edges, to)); return 0; } int igraph_i_dl_add_edge_w(long int from, long int to, igraph_real_t weight, igraph_i_dl_parsedata_t *context) { long int n=igraph_vector_size(&context->weights); long int n2=igraph_vector_size(&context->edges)/2; if (n != n2) { igraph_vector_resize(&context->weights, n2); for (; nweights)[n]=IGRAPH_NAN; } } IGRAPH_CHECK(igraph_i_dl_add_edge(from, to, context)); IGRAPH_CHECK(igraph_vector_push_back(&context->weights, weight)); return 0; } leidenbase/src/core/io/gml-tree.c0000644000176200001440000001717114447675374016407 0ustar liggesusers/* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_memory.h" #include "igraph_error.h" #include "io/gml-tree.h" #include int igraph_gml_tree_init_integer(igraph_gml_tree_t *t, const char *name, int namelen, igraph_integer_t value) { igraph_integer_t *p; IGRAPH_UNUSED(namelen); IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1); IGRAPH_CHECK(igraph_vector_char_init(&t->types, 1)); IGRAPH_FINALLY(igraph_vector_char_destroy, &t->types); IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1); /* names */ VECTOR(t->names)[0] = (void*)name; /* types */ VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_INTEGER; /* children */ p = IGRAPH_CALLOC(1, igraph_integer_t); if (!p) { IGRAPH_ERROR("Cannot create integer GML tree node", IGRAPH_ENOMEM); } *p = value; VECTOR(t->children)[0] = p; IGRAPH_FINALLY_CLEAN(3); return 0; } int igraph_gml_tree_init_real(igraph_gml_tree_t *t, const char *name, int namelen, igraph_real_t value) { igraph_real_t *p; IGRAPH_UNUSED(namelen); IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1); IGRAPH_CHECK(igraph_vector_char_init(&t->types, 1)); IGRAPH_FINALLY(igraph_vector_char_destroy, &t->types); IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1); /* names */ VECTOR(t->names)[0] = (void*) name; /* types */ VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_REAL; /* children */ p = IGRAPH_CALLOC(1, igraph_real_t); if (!p) { IGRAPH_ERROR("Cannot create real GML tree node", IGRAPH_ENOMEM); } *p = value; VECTOR(t->children)[0] = p; IGRAPH_FINALLY_CLEAN(3); return 0; } int igraph_gml_tree_init_string(igraph_gml_tree_t *t, const char *name, int namelen, const char *value, int valuelen) { IGRAPH_UNUSED(namelen); IGRAPH_UNUSED(valuelen); IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1); IGRAPH_CHECK(igraph_vector_char_init(&t->types, 1)); IGRAPH_FINALLY(igraph_vector_char_destroy, &t->types); IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1); /* names */ VECTOR(t->names)[0] = (void*) name; /* types */ VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_STRING; /* children */ VECTOR(t->children)[0] = (void*)value; IGRAPH_FINALLY_CLEAN(3); return 0; } int igraph_gml_tree_init_tree(igraph_gml_tree_t *t, const char *name, int namelen, igraph_gml_tree_t *value) { IGRAPH_UNUSED(namelen); IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1); IGRAPH_CHECK(igraph_vector_char_init(&t->types, 1)); IGRAPH_FINALLY(igraph_vector_char_destroy, &t->types); IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1); /* names */ VECTOR(t->names)[0] = (void*)name; /* types */ VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_TREE; /* children */ VECTOR(t->children)[0] = value; IGRAPH_FINALLY_CLEAN(3); return 0; } /* merge is destructive, the _second_ tree is destroyed */ int igraph_gml_tree_mergedest(igraph_gml_tree_t *t1, igraph_gml_tree_t *t2) { long int i, n = igraph_vector_ptr_size(&t2->children); for (i = 0; i < n; i++) { IGRAPH_CHECK(igraph_vector_ptr_push_back(&t1->names, VECTOR(t2->names)[i])); IGRAPH_CHECK(igraph_vector_char_push_back(&t1->types, VECTOR(t2->types)[i])); IGRAPH_CHECK(igraph_vector_ptr_push_back(&t1->children, VECTOR(t2->children)[i])); } igraph_vector_ptr_destroy(&t2->names); igraph_vector_char_destroy(&t2->types); igraph_vector_ptr_destroy(&t2->children); return 0; } void igraph_gml_tree_destroy(igraph_gml_tree_t *t) { long int i, n = igraph_vector_ptr_size(&t->children); for (i = 0; i < n; i++) { int type = VECTOR(t->types)[i]; switch (type) { case IGRAPH_I_GML_TREE_TREE: igraph_gml_tree_destroy(VECTOR(t->children)[i]); IGRAPH_FREE(VECTOR(t->names)[i]); break; case IGRAPH_I_GML_TREE_INTEGER: IGRAPH_FREE(VECTOR(t->children)[i]); IGRAPH_FREE(VECTOR(t->names)[i]); break; case IGRAPH_I_GML_TREE_REAL: IGRAPH_FREE(VECTOR(t->children)[i]); IGRAPH_FREE(VECTOR(t->names)[i]); break; case IGRAPH_I_GML_TREE_STRING: IGRAPH_FREE(VECTOR(t->children)[i]); IGRAPH_FREE(VECTOR(t->names)[i]); break; case IGRAPH_I_GML_TREE_DELETED: break; } } igraph_vector_ptr_destroy(&t->names); igraph_vector_char_destroy(&t->types); igraph_vector_ptr_destroy(&t->children); IGRAPH_FREE(t); } long int igraph_gml_tree_length(const igraph_gml_tree_t *t) { return igraph_vector_ptr_size(&t->names); } long int igraph_gml_tree_find(const igraph_gml_tree_t *t, const char *name, long int from) { long int size = igraph_vector_ptr_size(&t->names); while ( from < size && (! VECTOR(t->names)[from] || strcmp(VECTOR(t->names)[from], name)) ) { from++; } if (from == size) { from = -1; } return from; } long int igraph_gml_tree_findback(const igraph_gml_tree_t *t, const char *name, long int from) { while ( from >= 0 && (! VECTOR(t->names)[from] || strcmp(VECTOR(t->names)[from], name)) ) { from--; } return from; } int igraph_gml_tree_type(const igraph_gml_tree_t *t, long int pos) { return VECTOR(t->types)[pos]; } const char *igraph_gml_tree_name(const igraph_gml_tree_t *t, long int pos) { return VECTOR(t->names)[pos]; } igraph_integer_t igraph_gml_tree_get_integer(const igraph_gml_tree_t *t, long int pos) { igraph_integer_t *i = VECTOR(t->children)[pos]; return *i; } igraph_real_t igraph_gml_tree_get_real(const igraph_gml_tree_t *t, long int pos) { igraph_real_t *d = VECTOR(t->children)[pos]; return *d; } const char *igraph_gml_tree_get_string(const igraph_gml_tree_t *t, long int pos) { const char *s = VECTOR(t->children)[pos]; return s; } igraph_gml_tree_t *igraph_gml_tree_get_tree(const igraph_gml_tree_t *t, long int pos) { igraph_gml_tree_t *tree = VECTOR(t->children)[pos]; return tree; } void igraph_gml_tree_delete(igraph_gml_tree_t *t, long int pos) { if (VECTOR(t->types)[pos] == IGRAPH_I_GML_TREE_TREE) { igraph_gml_tree_destroy(VECTOR(t->children)[pos]); } IGRAPH_FREE(VECTOR(t->names)[pos]); IGRAPH_FREE(VECTOR(t->children)[pos]); VECTOR(t->children)[pos] = 0; VECTOR(t->names)[pos] = 0; VECTOR(t->types)[pos] = IGRAPH_I_GML_TREE_DELETED; } leidenbase/src/core/io/lgl.c0000644000176200001440000003647014447675374015454 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_attributes.h" #include "igraph_interface.h" #include "graph/attributes.h" #include "lgl-header.h" int igraph_lgl_yylex_init_extra (igraph_i_lgl_parsedata_t* user_defined, void* scanner); void igraph_lgl_yylex_destroy (void *scanner ); int igraph_lgl_yyparse (igraph_i_lgl_parsedata_t* context); void igraph_lgl_yyset_in (FILE * in_str, void* yyscanner ); /** * \ingroup loadsave * \function igraph_read_graph_lgl * \brief Reads a graph from an .lgl file * * * The .lgl format is used by the Large Graph * Layout visualization software * (http://lgl.sourceforge.net), it can * describe undirected optionally weighted graphs. From the LGL * manual: * * \blockquote The second format is the LGL file format * (.lgl file * suffix). This is yet another graph file format that tries to be as * stingy as possible with space, yet keeping the edge file in a human * readable (not binary) format. The format itself is like the * following: * \verbatim # vertex1name vertex2name [optionalWeight] vertex3name [optionalWeight] \endverbatim * Here, the first vertex of an edge is preceded with a pound sign * '#'. Then each vertex that shares an edge with that vertex is * listed one per line on subsequent lines. \endblockquote * * * LGL cannot handle loop and multiple edges or directed graphs, but * in \a igraph it is not an error to have multiple and loop edges. * \param graph Pointer to an uninitialized graph object. * \param instream A stream, it should be readable. * \param names Logical value, if TRUE the symbolic names of the * vertices will be added to the graph as a vertex attribute * called \quote name\endquote. * \param weights Whether to add the weights of the edges to the * graph as an edge attribute called \quote weight\endquote. * \c IGRAPH_ADD_WEIGHTS_YES adds the weights (even if they * are not present in the file, in this case they are assumed * to be zero). \c IGRAPH_ADD_WEIGHTS_NO does not add any * edge attribute. \c IGRAPH_ADD_WEIGHTS_IF_PRESENT adds the * attribute if and only if there is at least one explicit * edge weight in the input file. * \param directed Whether to create a directed graph. As this format * was originally used only for undirected graphs there is no * information in the file about the directedness of the graph. * Set this parameter to \c IGRAPH_DIRECTED or \c * IGRAPH_UNDIRECTED to create a directed or undirected graph. * \return Error code: * \c IGRAPH_PARSEERROR: if there is a * problem reading the file, or the file is syntactically * incorrect. * * Time complexity: * O(|V|+|E|log(|V|)) if we neglect * the time required by the parsing. As usual * |V| is the number of vertices, * while |E| is the number of edges. * * \sa \ref igraph_read_graph_ncol(), \ref igraph_write_graph_lgl() * * \example examples/simple/igraph_read_graph_lgl.c */ int igraph_read_graph_lgl(igraph_t *graph, FILE *instream, igraph_bool_t names, igraph_add_weights_t weights, igraph_bool_t directed) { igraph_vector_t edges = IGRAPH_VECTOR_NULL, ws = IGRAPH_VECTOR_NULL; igraph_trie_t trie = IGRAPH_TRIE_NULL; igraph_vector_ptr_t name, weight; igraph_vector_ptr_t *pname = 0, *pweight = 0; igraph_attribute_record_t namerec, weightrec; const char *namestr = "name", *weightstr = "weight"; igraph_i_lgl_parsedata_t context; IGRAPH_VECTOR_INIT_FINALLY(&ws, 0); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_TRIE_INIT_FINALLY(&trie, names); context.has_weights = 0; context.vector = &edges; context.weights = &ws; context.trie = ≜ context.eof = 0; igraph_lgl_yylex_init_extra(&context, &context.scanner); IGRAPH_FINALLY(igraph_lgl_yylex_destroy, context.scanner); igraph_lgl_yyset_in(instream, context.scanner); if (igraph_lgl_yyparse(&context)) { if (context.errmsg[0] != 0) { IGRAPH_ERROR(context.errmsg, IGRAPH_PARSEERROR); } else { IGRAPH_ERROR("Cannot read LGL file", IGRAPH_PARSEERROR); } } IGRAPH_CHECK(igraph_empty(graph, 0, directed)); IGRAPH_FINALLY(igraph_destroy, graph); if (names) { const igraph_strvector_t *namevec; IGRAPH_CHECK(igraph_vector_ptr_init(&name, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &name); pname = &name; igraph_trie_getkeys(&trie, &namevec); /* dirty */ namerec.name = namestr; namerec.type = IGRAPH_ATTRIBUTE_STRING; namerec.value = namevec; VECTOR(name)[0] = &namerec; } if (weights == IGRAPH_ADD_WEIGHTS_YES || (weights == IGRAPH_ADD_WEIGHTS_IF_PRESENT && context.has_weights)) { IGRAPH_CHECK(igraph_vector_ptr_init(&weight, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &weight); pweight = &weight; weightrec.name = weightstr; weightrec.type = IGRAPH_ATTRIBUTE_NUMERIC; weightrec.value = &ws; VECTOR(weight)[0] = &weightrec; } IGRAPH_CHECK(igraph_add_vertices(graph, (igraph_integer_t) igraph_trie_size(&trie), pname)); IGRAPH_CHECK(igraph_add_edges(graph, &edges, pweight)); if (pweight) { igraph_vector_ptr_destroy(pweight); IGRAPH_FINALLY_CLEAN(1); } if (pname) { igraph_vector_ptr_destroy(pname); IGRAPH_FINALLY_CLEAN(1); } igraph_trie_destroy(&trie); igraph_vector_destroy(&edges); igraph_vector_destroy(&ws); igraph_lgl_yylex_destroy(context.scanner); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \ingroup loadsave * \function igraph_write_graph_lgl * \brief Writes the graph to a file in .lgl format * * * .lgl is a format used by LGL, see \ref * igraph_read_graph_lgl() for details. * * * Note that having multiple or loop edges in an * .lgl file breaks the LGL software but \a igraph * does not check for this condition. * * \param graph The graph to write. * \param outstream The stream object to write to, it should be * writable. * \param names The name of a string vertex attribute, if symbolic names * are to be written to the file. Supply \c NULL to write vertex * ids instead. * \param weights The name of a numerical edge attribute, which will be * written as weights to the file. Supply \c NULL to skip writing * edge weights. * \param isolates Logical, if TRUE isolated vertices are also written * to the file. If FALSE they will be omitted. * \return Error code: * \c IGRAPH_EFILE if there is an error * writing the file. * * Time complexity: O(|E|), the * number of edges if \p isolates is * FALSE, O(|V|+|E|) otherwise. All * file operations are expected to have time complexity * O(1). * * \sa \ref igraph_read_graph_lgl(), \ref igraph_write_graph_ncol() * * \example examples/simple/igraph_write_graph_lgl.c */ int igraph_write_graph_lgl(const igraph_t *graph, FILE *outstream, const char *names, const char *weights, igraph_bool_t isolates) { igraph_eit_t it; long int actvertex = -1; igraph_attribute_type_t nametype, weighttype; IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_FROM), &it)); IGRAPH_FINALLY(igraph_eit_destroy, &it); /* Check if we have the names attribute */ if (names && !igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, names)) { names = 0; IGRAPH_WARNING("names attribute does not exists"); } if (names) { IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &nametype, IGRAPH_ATTRIBUTE_VERTEX, names)); if (nametype != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_WARNING("ignoring names attribute, unknown attribute type"); names = 0; } } /* Check the weights as well */ if (weights && !igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, weights)) { weights = 0; IGRAPH_WARNING("weights attribute does not exists"); } if (weights) { IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &weighttype, IGRAPH_ATTRIBUTE_EDGE, weights)); if (weighttype != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_WARNING("ignoring weights attribute, unknown attribute type"); weights = 0; } } if (names == 0 && weights == 0) { /* No names, no weights */ while (!IGRAPH_EIT_END(it)) { igraph_integer_t from, to; int ret; igraph_edge(graph, IGRAPH_EIT_GET(it), &from, &to); if (from == actvertex) { ret = fprintf(outstream, "%li\n", (long int)to); } else { actvertex = from; ret = fprintf(outstream, "# %li\n%li\n", (long int)from, (long int)to); } if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } } else if (weights == 0) { /* No weights but use names */ igraph_strvector_t nvec; IGRAPH_CHECK(igraph_strvector_init(&nvec, igraph_vcount(graph))); IGRAPH_FINALLY(igraph_strvector_destroy, &nvec); IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr(graph, names, igraph_vss_all(), &nvec)); while (!IGRAPH_EIT_END(it)) { igraph_integer_t edge = IGRAPH_EIT_GET(it); igraph_integer_t from, to; int ret = 0; char *str1, *str2; igraph_edge(graph, edge, &from, &to); igraph_strvector_get(&nvec, to, &str2); if (from == actvertex) { ret = fprintf(outstream, "%s\n", str2); } else { actvertex = from; igraph_strvector_get(&nvec, from, &str1); ret = fprintf(outstream, "# %s\n%s\n", str1, str2); } if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } IGRAPH_FINALLY_CLEAN(1); } else if (names == 0) { /* No names but weights */ igraph_vector_t wvec; IGRAPH_VECTOR_INIT_FINALLY(&wvec, igraph_ecount(graph)); IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr(graph, weights, igraph_ess_all(IGRAPH_EDGEORDER_ID), &wvec)); while (!IGRAPH_EIT_END(it)) { igraph_integer_t edge = IGRAPH_EIT_GET(it); igraph_integer_t from, to; int ret1, ret2, ret3; igraph_edge(graph, edge, &from, &to); if (from == actvertex) { ret1 = fprintf(outstream, "%li ", (long)to); } else { actvertex = from; ret1 = fprintf(outstream, "# %li\n%li ", (long)from, (long)to); } ret2 = igraph_real_fprintf_precise(outstream, VECTOR(wvec)[(long int)edge]); ret3 = fputc('\n', outstream); if (ret1 < 0 || ret2 < 0 || ret3 == EOF) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } igraph_vector_destroy(&wvec); IGRAPH_FINALLY_CLEAN(1); } else { /* Both names and weights */ igraph_strvector_t nvec; igraph_vector_t wvec; IGRAPH_VECTOR_INIT_FINALLY(&wvec, igraph_ecount(graph)); IGRAPH_CHECK(igraph_strvector_init(&nvec, igraph_vcount(graph))); IGRAPH_FINALLY(igraph_strvector_destroy, &nvec); IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr(graph, weights, igraph_ess_all(IGRAPH_EDGEORDER_ID), &wvec)); IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr(graph, names, igraph_vss_all(), &nvec)); while (!IGRAPH_EIT_END(it)) { igraph_integer_t edge = IGRAPH_EIT_GET(it); igraph_integer_t from, to; int ret = 0, ret2; char *str1, *str2; igraph_edge(graph, edge, &from, &to); igraph_strvector_get(&nvec, to, &str2); if (from == actvertex) { ret = fprintf(outstream, "%s ", str2); } else { actvertex = from; igraph_strvector_get(&nvec, from, &str1); ret = fprintf(outstream, "# %s\n%s ", str1, str2); } if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = igraph_real_fprintf_precise(outstream, VECTOR(wvec)[(long int)edge]); ret2 = fputc('\n', outstream); if (ret < 0 || ret2 == EOF) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } igraph_strvector_destroy(&nvec); igraph_vector_destroy(&wvec); IGRAPH_FINALLY_CLEAN(2); } if (isolates) { long int nov = igraph_vcount(graph); long int i; int ret = 0; igraph_vector_t deg; igraph_strvector_t nvec; char *str; IGRAPH_VECTOR_INIT_FINALLY(°, 1); IGRAPH_CHECK(igraph_strvector_init(&nvec, 1)); IGRAPH_FINALLY(igraph_strvector_destroy, &nvec); for (i = 0; i < nov; i++) { igraph_degree(graph, °, igraph_vss_1((igraph_integer_t) i), IGRAPH_ALL, IGRAPH_LOOPS); if (VECTOR(deg)[0] == 0) { if (names == 0) { ret = fprintf(outstream, "# %li\n", i); } else { IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr(graph, names, igraph_vss_1((igraph_integer_t) i), &nvec)); igraph_strvector_get(&nvec, 0, &str); ret = fprintf(outstream, "# %s\n", str); } } if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } igraph_strvector_destroy(&nvec); igraph_vector_destroy(°); IGRAPH_FINALLY_CLEAN(2); } igraph_eit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/io/pajek-header.h0000644000176200001440000000265514447675374017221 0ustar liggesusers/* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge MA, 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_error.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" #include "core/trie.h" typedef struct { void *scanner; int eof; char errmsg[300]; igraph_vector_t *vector; igraph_bool_t directed; int vcount, vcount2; int actfrom; int actto; int mode; /* 0: general, 1: vertex, 2: edge */ igraph_trie_t *vertex_attribute_names; igraph_vector_ptr_t *vertex_attributes; igraph_trie_t *edge_attribute_names; igraph_vector_ptr_t *edge_attributes; int vertexid; int actvertex; int actedge; } igraph_i_pajek_parsedata_t; leidenbase/src/core/io/dl-lexer.h0000644000176200001440000004201214447675375016405 0ustar liggesusers#ifndef igraph_dl_yyHEADER_H #define igraph_dl_yyHEADER_H 1 #define igraph_dl_yyIN_HEADER 1 #line 6 "src/core/io/dl-lexer.h" #line 8 "src/core/io/dl-lexer.h" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_dl_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_dl_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_dl_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_dl_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_dl_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_dl_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_dl_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_dl_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_dl_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_dl_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_dl_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_dl_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_dl_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_dl_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_dl_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_dl_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_dl_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_dl_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_dl_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_dl_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_dl_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_dl_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_dl_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_dl_yyensure_buffer_stack #endif #ifdef yylex #define igraph_dl_yylex_ALREADY_DEFINED #else #define yylex igraph_dl_yylex #endif #ifdef yyrestart #define igraph_dl_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_dl_yyrestart #endif #ifdef yylex_init #define igraph_dl_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_dl_yylex_init #endif #ifdef yylex_init_extra #define igraph_dl_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_dl_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_dl_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_dl_yylex_destroy #endif #ifdef yyget_debug #define igraph_dl_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_dl_yyget_debug #endif #ifdef yyset_debug #define igraph_dl_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_dl_yyset_debug #endif #ifdef yyget_extra #define igraph_dl_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_dl_yyget_extra #endif #ifdef yyset_extra #define igraph_dl_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_dl_yyset_extra #endif #ifdef yyget_in #define igraph_dl_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_dl_yyget_in #endif #ifdef yyset_in #define igraph_dl_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_dl_yyset_in #endif #ifdef yyget_out #define igraph_dl_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_dl_yyget_out #endif #ifdef yyset_out #define igraph_dl_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_dl_yyset_out #endif #ifdef yyget_leng #define igraph_dl_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_dl_yyget_leng #endif #ifdef yyget_text #define igraph_dl_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_dl_yyget_text #endif #ifdef yyget_lineno #define igraph_dl_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_dl_yyget_lineno #endif #ifdef yyset_lineno #define igraph_dl_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_dl_yyset_lineno #endif #ifdef yyget_column #define igraph_dl_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_dl_yyget_column #endif #ifdef yyset_column #define igraph_dl_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_dl_yyset_column #endif #ifdef yywrap #define igraph_dl_yywrap_ALREADY_DEFINED #else #define yywrap igraph_dl_yywrap #endif #ifdef yyget_lval #define igraph_dl_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_dl_yyget_lval #endif #ifdef yyset_lval #define igraph_dl_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_dl_yyset_lval #endif #ifdef yyget_lloc #define igraph_dl_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_dl_yyget_lloc #endif #ifdef yyset_lloc #define igraph_dl_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_dl_yyset_lloc #endif #ifdef yyalloc #define igraph_dl_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_dl_yyalloc #endif #ifdef yyrealloc #define igraph_dl_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_dl_yyrealloc #endif #ifdef yyfree #define igraph_dl_yyfree_ALREADY_DEFINED #else #define yyfree igraph_dl_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define igraph_dl_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP #define yytext_ptr yytext_r #ifdef YY_HEADER_EXPORT_START_CONDITIONS #define INITIAL 0 #define LABELM 1 #define FULLMATRIX 2 #define EDGELIST 3 #define NODELIST 4 #endif #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* yy_get_previous_state - get the state just before the EOB char was reached */ #undef YY_NEW_FILE #undef YY_FLUSH_BUFFER #undef yy_set_bol #undef yy_new_buffer #undef yy_set_interactive #undef YY_DO_BEFORE_ACTION #ifdef YY_DECL_IS_OURS #undef YY_DECL_IS_OURS #undef YY_DECL #endif #ifndef igraph_dl_yy_create_buffer_ALREADY_DEFINED #undef yy_create_buffer #endif #ifndef igraph_dl_yy_delete_buffer_ALREADY_DEFINED #undef yy_delete_buffer #endif #ifndef igraph_dl_yy_scan_buffer_ALREADY_DEFINED #undef yy_scan_buffer #endif #ifndef igraph_dl_yy_scan_string_ALREADY_DEFINED #undef yy_scan_string #endif #ifndef igraph_dl_yy_scan_bytes_ALREADY_DEFINED #undef yy_scan_bytes #endif #ifndef igraph_dl_yy_init_buffer_ALREADY_DEFINED #undef yy_init_buffer #endif #ifndef igraph_dl_yy_flush_buffer_ALREADY_DEFINED #undef yy_flush_buffer #endif #ifndef igraph_dl_yy_load_buffer_state_ALREADY_DEFINED #undef yy_load_buffer_state #endif #ifndef igraph_dl_yy_switch_to_buffer_ALREADY_DEFINED #undef yy_switch_to_buffer #endif #ifndef igraph_dl_yypush_buffer_state_ALREADY_DEFINED #undef yypush_buffer_state #endif #ifndef igraph_dl_yypop_buffer_state_ALREADY_DEFINED #undef yypop_buffer_state #endif #ifndef igraph_dl_yyensure_buffer_stack_ALREADY_DEFINED #undef yyensure_buffer_stack #endif #ifndef igraph_dl_yylex_ALREADY_DEFINED #undef yylex #endif #ifndef igraph_dl_yyrestart_ALREADY_DEFINED #undef yyrestart #endif #ifndef igraph_dl_yylex_init_ALREADY_DEFINED #undef yylex_init #endif #ifndef igraph_dl_yylex_init_extra_ALREADY_DEFINED #undef yylex_init_extra #endif #ifndef igraph_dl_yylex_destroy_ALREADY_DEFINED #undef yylex_destroy #endif #ifndef igraph_dl_yyget_debug_ALREADY_DEFINED #undef yyget_debug #endif #ifndef igraph_dl_yyset_debug_ALREADY_DEFINED #undef yyset_debug #endif #ifndef igraph_dl_yyget_extra_ALREADY_DEFINED #undef yyget_extra #endif #ifndef igraph_dl_yyset_extra_ALREADY_DEFINED #undef yyset_extra #endif #ifndef igraph_dl_yyget_in_ALREADY_DEFINED #undef yyget_in #endif #ifndef igraph_dl_yyset_in_ALREADY_DEFINED #undef yyset_in #endif #ifndef igraph_dl_yyget_out_ALREADY_DEFINED #undef yyget_out #endif #ifndef igraph_dl_yyset_out_ALREADY_DEFINED #undef yyset_out #endif #ifndef igraph_dl_yyget_leng_ALREADY_DEFINED #undef yyget_leng #endif #ifndef igraph_dl_yyget_text_ALREADY_DEFINED #undef yyget_text #endif #ifndef igraph_dl_yyget_lineno_ALREADY_DEFINED #undef yyget_lineno #endif #ifndef igraph_dl_yyset_lineno_ALREADY_DEFINED #undef yyset_lineno #endif #ifndef igraph_dl_yyget_column_ALREADY_DEFINED #undef yyget_column #endif #ifndef igraph_dl_yyset_column_ALREADY_DEFINED #undef yyset_column #endif #ifndef igraph_dl_yywrap_ALREADY_DEFINED #undef yywrap #endif #ifndef igraph_dl_yyget_lval_ALREADY_DEFINED #undef yyget_lval #endif #ifndef igraph_dl_yyset_lval_ALREADY_DEFINED #undef yyset_lval #endif #ifndef igraph_dl_yyget_lloc_ALREADY_DEFINED #undef yyget_lloc #endif #ifndef igraph_dl_yyset_lloc_ALREADY_DEFINED #undef yyset_lloc #endif #ifndef igraph_dl_yyalloc_ALREADY_DEFINED #undef yyalloc #endif #ifndef igraph_dl_yyrealloc_ALREADY_DEFINED #undef yyrealloc #endif #ifndef igraph_dl_yyfree_ALREADY_DEFINED #undef yyfree #endif #ifndef igraph_dl_yytext_ALREADY_DEFINED #undef yytext #endif #ifndef igraph_dl_yyleng_ALREADY_DEFINED #undef yyleng #endif #ifndef igraph_dl_yyin_ALREADY_DEFINED #undef yyin #endif #ifndef igraph_dl_yyout_ALREADY_DEFINED #undef yyout #endif #ifndef igraph_dl_yy_flex_debug_ALREADY_DEFINED #undef yy_flex_debug #endif #ifndef igraph_dl_yylineno_ALREADY_DEFINED #undef yylineno #endif #ifndef igraph_dl_yytables_fload_ALREADY_DEFINED #undef yytables_fload #endif #ifndef igraph_dl_yytables_destroy_ALREADY_DEFINED #undef yytables_destroy #endif #ifndef igraph_dl_yyTABLES_NAME_ALREADY_DEFINED #undef yyTABLES_NAME #endif #line 138 "src/core/io/dl-lexer.l" #line 736 "src/core/io/dl-lexer.h" #undef igraph_dl_yyIN_HEADER #endif /* igraph_dl_yyHEADER_H */ leidenbase/src/core/io/gml-parser.c0000644000176200001440000017614414447675375016753 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ #define YYBISON 30802 /* Bison version string. */ #define YYBISON_VERSION "3.8.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Substitute the variable and function names. */ #define yyparse igraph_gml_yyparse #define yylex igraph_gml_yylex #define yyerror igraph_gml_yyerror #define yydebug igraph_gml_yydebug #define yynerrs igraph_gml_yynerrs /* First part of user prologue. */ #line 23 "src/core/io/gml-parser.y" /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "igraph_error.h" #include "igraph_memory.h" #include "config.h" #include "core/math.h" #include "io/gml-header.h" #include "io/gml-tree.h" #include "io/gml-parser.h" #include "io/gml-lexer.h" #include "internal/hacks.h" /* strcasecmp */ int igraph_gml_yyerror(YYLTYPE* locp, igraph_i_gml_parsedata_t *context, const char *s); void igraph_i_gml_get_keyword(char *s, int len, void *res); void igraph_i_gml_get_string(char *s, int len, void *res); double igraph_i_gml_get_real(char *s, int len); igraph_gml_tree_t *igraph_i_gml_make_numeric(char* s, int len, double value); igraph_gml_tree_t *igraph_i_gml_make_numeric2(char* s, int len, char *v, int vlen); igraph_gml_tree_t *igraph_i_gml_make_string(char* s, int len, char *value, int valuelen); igraph_gml_tree_t *igraph_i_gml_make_list(char* s, int len, igraph_gml_tree_t *list); igraph_gml_tree_t *igraph_i_gml_merge(igraph_gml_tree_t *t1, igraph_gml_tree_t* t2); #define scanner context->scanner #define USE(x) /*(x)*/ #line 134 "yy.tab.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif #include "io/gml-parser.h" /* Symbol kind. */ enum yysymbol_kind_t { YYSYMBOL_YYEMPTY = -2, YYSYMBOL_YYEOF = 0, /* "end of file" */ YYSYMBOL_YYerror = 1, /* error */ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ YYSYMBOL_STRING = 3, /* STRING */ YYSYMBOL_NUM = 4, /* NUM */ YYSYMBOL_KEYWORD = 5, /* KEYWORD */ YYSYMBOL_LISTOPEN = 6, /* LISTOPEN */ YYSYMBOL_LISTCLOSE = 7, /* LISTCLOSE */ YYSYMBOL_EOFF = 8, /* EOFF */ YYSYMBOL_ERROR = 9, /* ERROR */ YYSYMBOL_YYACCEPT = 10, /* $accept */ YYSYMBOL_input = 11, /* input */ YYSYMBOL_list = 12, /* list */ YYSYMBOL_keyvalue = 13, /* keyvalue */ YYSYMBOL_key = 14, /* key */ YYSYMBOL_num = 15, /* num */ YYSYMBOL_string = 16 /* string */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif /* Work around bug in HP-UX 11.23, which defines these macros incorrectly for preprocessor constants. This workaround can likely be removed in 2023, as HPE has promised support for HP-UX 11.23 (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of . */ #ifdef __hpux # undef UINT_LEAST8_MAX # undef UINT_LEAST16_MAX # define UINT_LEAST8_MAX 255 # define UINT_LEAST16_MAX 65535 #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_int8 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YY_USE(E) ((void) (E)) #else # define YY_USE(E) /* empty */ #endif /* Suppress an incorrect diagnostic about yylval being uninitialized. */ #if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ # if __GNUC__ * 100 + __GNUC_MINOR__ < 407 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") # else # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # endif # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if 1 /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* 1 */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ + YYSIZEOF (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 6 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 14 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 10 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 7 /* YYNRULES -- Number of rules. */ #define YYNRULES 12 /* YYNSTATES -- Number of states. */ #define YYNSTATES 17 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 264 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK \ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 119, 119, 120, 123, 124, 126, 128, 130, 132, 136, 139, 142 }; #endif /** Accessing symbol of state STATE. */ #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) #if 1 /* The user-facing name of the symbol whose (internal) number is YYSYMBOL. No bounds checking. */ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "\"end of file\"", "error", "\"invalid token\"", "STRING", "NUM", "KEYWORD", "LISTOPEN", "LISTCLOSE", "EOFF", "ERROR", "$accept", "input", "list", "keyvalue", "key", "num", "string", YY_NULLPTR }; static const char * yysymbol_name (yysymbol_kind_t yysymbol) { return yytname[yysymbol]; } #endif #define YYPACT_NINF (-4) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-1) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int8 yypact[] = { 1, -4, 10, 0, -4, -2, -4, -4, -4, -4, -4, 1, -4, -4, -4, 2, -4 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_int8 yydefact[] = { 0, 10, 0, 2, 4, 0, 1, 3, 5, 12, 11, 0, 9, 6, 7, 0, 8 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -4, -4, 3, -3, 6, -4, -4 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { 0, 2, 3, 4, 5, 13, 14 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { 8, 9, 10, 1, 11, 1, 1, 1, 7, 16, 6, 12, 8, 0, 15 }; static const yytype_int8 yycheck[] = { 3, 3, 4, 5, 6, 5, 5, 5, 8, 7, 0, 5, 15, -1, 11 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { 0, 5, 11, 12, 13, 14, 0, 8, 13, 3, 4, 6, 14, 15, 16, 12, 7 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int8 yyr1[] = { 0, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 15, 16 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ static const yytype_int8 yyr2[] = { 0, 2, 1, 2, 1, 2, 2, 2, 4, 2, 1, 1, 1 }; enum { YYENOMEM = -2 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Backward compatibility with an undocumented macro. Use YYerror or YYUNDEF. */ #define YYERRCODE YYUNDEF /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (N) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (0) #endif #define YYRHSLOC(Rhs, K) ((Rhs)[K]) /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* YYLOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ # ifndef YYLOCATION_PRINT # if defined YY_LOCATION_PRINT /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc)) # elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL /* Print *YYLOCP on YYO. Private, do not rely on its existence. */ YY_ATTRIBUTE_UNUSED static int yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) { int res = 0; int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; if (0 <= yylocp->first_line) { res += YYFPRINTF (yyo, "%d", yylocp->first_line); if (0 <= yylocp->first_column) res += YYFPRINTF (yyo, ".%d", yylocp->first_column); } if (0 <= yylocp->last_line) { if (yylocp->first_line < yylocp->last_line) { res += YYFPRINTF (yyo, "-%d", yylocp->last_line); if (0 <= end_col) res += YYFPRINTF (yyo, ".%d", end_col); } else if (0 <= end_col && yylocp->first_column < end_col) res += YYFPRINTF (yyo, "-%d", end_col); } return res; } # define YYLOCATION_PRINT yy_location_print_ /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc)) # else # define YYLOCATION_PRINT(File, Loc) ((void) 0) /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT YYLOCATION_PRINT # endif # endif /* !defined YYLOCATION_PRINT */ # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Kind, Value, Location, context); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_gml_parsedata_t* context) { FILE *yyoutput = yyo; YY_USE (yyoutput); YY_USE (yylocationp); YY_USE (context); if (!yyvaluep) return; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_gml_parsedata_t* context) { YYFPRINTF (yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); YYLOCATION_PRINT (yyo, yylocationp); YYFPRINTF (yyo, ": "); yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp, context); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, igraph_i_gml_parsedata_t* context) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), &yyvsp[(yyi + 1) - (yynrhs)], &(yylsp[(yyi + 1) - (yynrhs)]), context); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, yylsp, Rule, context); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) ((void) 0) # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif /* Context of a parse error. */ typedef struct { yy_state_t *yyssp; yysymbol_kind_t yytoken; YYLTYPE *yylloc; } yypcontext_t; /* Put in YYARG at most YYARGN of the expected tokens given the current YYCTX, and return the number of tokens stored in YYARG. If YYARG is null, return the number of expected tokens (guaranteed to be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. Return 0 if there are more than YYARGN expected tokens, yet fill YYARG up to YYARGN. */ static int yypcontext_expected_tokens (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; int yyn = yypact[+*yyctx->yyssp]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror && !yytable_value_is_error (yytable[yyx + yyn])) { if (!yyarg) ++yycount; else if (yycount == yyargn) return 0; else yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); } } if (yyarg && yycount == 0 && 0 < yyargn) yyarg[0] = YYSYMBOL_YYEMPTY; return yycount; } #ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) { YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif #endif #ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif #endif #ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; else goto append; append: default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (yyres) return yystpcpy (yyres, yystr) - yyres; else return yystrlen (yystr); } #endif static int yy_syntax_error_arguments (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yyctx->yytoken != YYSYMBOL_YYEMPTY) { int yyn; if (yyarg) yyarg[yycount] = yyctx->yytoken; ++yycount; yyn = yypcontext_expected_tokens (yyctx, yyarg ? yyarg + 1 : yyarg, yyargn - 1); if (yyn == YYENOMEM) return YYENOMEM; else yycount += yyn; } return yycount; } /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the required number of bytes is too large to store. */ static int yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, const yypcontext_t *yyctx) { enum { YYARGS_MAX = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ yysymbol_kind_t yyarg[YYARGS_MAX]; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; /* Actual size of YYARG. */ int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); if (yycount == YYENOMEM) return YYENOMEM; switch (yycount) { #define YYCASE_(N, S) \ case N: \ yyformat = S; \ break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); #undef YYCASE_ } /* Compute error message size. Don't count the "%s"s, but reserve room for the terminator. */ yysize = yystrlen (yyformat) - 2 * yycount + 1; { int yyi; for (yyi = 0; yyi < yycount; ++yyi) { YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return YYENOMEM; } } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return -1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); yyformat += 2; } else { ++yyp; ++yyformat; } } return 0; } /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, igraph_i_gml_parsedata_t* context) { YY_USE (yyvaluep); YY_USE (yylocationp); YY_USE (context); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN switch (yykind) { case YYSYMBOL_KEYWORD: /* KEYWORD */ #line 114 "src/core/io/gml-parser.y" { IGRAPH_FREE(((*yyvaluep).str).s); } #line 1234 "yy.tab.c" break; case YYSYMBOL_list: /* list */ #line 115 "src/core/io/gml-parser.y" { igraph_gml_tree_destroy(((*yyvaluep).tree)); } #line 1240 "yy.tab.c" break; case YYSYMBOL_keyvalue: /* keyvalue */ #line 115 "src/core/io/gml-parser.y" { igraph_gml_tree_destroy(((*yyvaluep).tree)); } #line 1246 "yy.tab.c" break; case YYSYMBOL_key: /* key */ #line 114 "src/core/io/gml-parser.y" { IGRAPH_FREE(((*yyvaluep).str).s); } #line 1252 "yy.tab.c" break; case YYSYMBOL_string: /* string */ #line 114 "src/core/io/gml-parser.y" { IGRAPH_FREE(((*yyvaluep).str).s); } #line 1258 "yy.tab.c" break; default: break; } YY_IGNORE_MAYBE_UNINITIALIZED_END } /*----------. | yyparse. | `----------*/ int yyparse (igraph_i_gml_parsedata_t* context) { /* Lookahead token kind. */ int yychar; /* The semantic value of the lookahead symbol. */ /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Location data for the lookahead symbol. */ static YYLTYPE yyloc_default # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL = { 1, 1, 1, 1 } # endif ; YYLTYPE yylloc = yyloc_default; /* Number of syntax errors so far. */ int yynerrs = 0; yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus = 0; /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* Their size. */ YYPTRDIFF_T yystacksize = YYINITDEPTH; /* The state stack: array, bottom, top. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss = yyssa; yy_state_t *yyssp = yyss; /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp = yyvs; /* The location stack: array, bottom, top. */ YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp = yyls; int yyn; /* The return value of yyparse. */ int yyresult; /* Lookahead symbol kind. */ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; /* The locations where the error started and ended. */ YYLTYPE yyerror_range[3]; /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ yylsp[0] = yylloc; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE YYNOMEM; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; YYLTYPE *yyls1 = yyls; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yyls1, yysize * YYSIZEOF (*yylsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; yyls = yyls1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) YYNOMEM; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) YYNOMEM; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; yylsp = yyls + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (&yylval, &yylloc, scanner); } if (yychar <= YYEOF) { yychar = YYEOF; yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else if (yychar == YYerror) { /* The scanner already issued an error message, process directly to error recovery. But do not keep the error token as lookahead, it is too special and may lead us to an endless loop in error recovery. */ yychar = YYUNDEF; yytoken = YYSYMBOL_YYerror; yyerror_range[1] = yylloc; goto yyerrlab1; } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END *++yylsp = yylloc; /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); yyerror_range[1] = yyloc; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: /* input: list */ #line 119 "src/core/io/gml-parser.y" { context->tree=(yyvsp[0].tree); } #line 1564 "yy.tab.c" break; case 3: /* input: list EOFF */ #line 120 "src/core/io/gml-parser.y" { context->tree=(yyvsp[-1].tree); } #line 1570 "yy.tab.c" break; case 4: /* list: keyvalue */ #line 123 "src/core/io/gml-parser.y" { (yyval.tree)=(yyvsp[0].tree); } #line 1576 "yy.tab.c" break; case 5: /* list: list keyvalue */ #line 124 "src/core/io/gml-parser.y" { (yyval.tree)=igraph_i_gml_merge((yyvsp[-1].tree), (yyvsp[0].tree)); } #line 1582 "yy.tab.c" break; case 6: /* keyvalue: key num */ #line 127 "src/core/io/gml-parser.y" { (yyval.tree)=igraph_i_gml_make_numeric((yyvsp[-1].str).s, (yyvsp[-1].str).len, (yyvsp[0].real)); } #line 1588 "yy.tab.c" break; case 7: /* keyvalue: key string */ #line 129 "src/core/io/gml-parser.y" { (yyval.tree)=igraph_i_gml_make_string((yyvsp[-1].str).s, (yyvsp[-1].str).len, (yyvsp[0].str).s, (yyvsp[0].str).len); } #line 1594 "yy.tab.c" break; case 8: /* keyvalue: key LISTOPEN list LISTCLOSE */ #line 131 "src/core/io/gml-parser.y" { (yyval.tree)=igraph_i_gml_make_list((yyvsp[-3].str).s, (yyvsp[-3].str).len, (yyvsp[-1].tree)); } #line 1600 "yy.tab.c" break; case 9: /* keyvalue: key key */ #line 133 "src/core/io/gml-parser.y" { (yyval.tree)=igraph_i_gml_make_numeric2((yyvsp[-1].str).s, (yyvsp[-1].str).len, (yyvsp[0].str).s, (yyvsp[0].str).len); } #line 1606 "yy.tab.c" break; case 10: /* key: KEYWORD */ #line 136 "src/core/io/gml-parser.y" { igraph_i_gml_get_keyword(igraph_gml_yyget_text(scanner), igraph_gml_yyget_leng(scanner), &(yyval.str)); USE((yyvsp[0].str)); } #line 1614 "yy.tab.c" break; case 11: /* num: NUM */ #line 139 "src/core/io/gml-parser.y" { (yyval.real)=igraph_i_gml_get_real(igraph_gml_yyget_text(scanner), igraph_gml_yyget_leng(scanner)); } #line 1621 "yy.tab.c" break; case 12: /* string: STRING */ #line 142 "src/core/io/gml-parser.y" { igraph_i_gml_get_string(igraph_gml_yyget_text(scanner), igraph_gml_yyget_leng(scanner), &(yyval.str)); } #line 1629 "yy.tab.c" break; #line 1633 "yy.tab.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; *++yyvsp = yyval; *++yylsp = yyloc; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; { yypcontext_t yyctx = {yyssp, yytoken, &yylloc}; char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == -1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (yymsg) { yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); yymsgp = yymsg; } else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = YYENOMEM; } } yyerror (&yylloc, context, yymsgp); if (yysyntax_error_status == YYENOMEM) YYNOMEM; } } yyerror_range[1] = yylloc; if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, &yylloc, context); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYSYMBOL_YYerror; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yyerror_range[1] = *yylsp; yydestruct ("Error: popping", YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp, context); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END yyerror_range[2] = yylloc; ++yylsp; YYLLOC_DEFAULT (*yylsp, yyerror_range, 2); /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturnlab; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturnlab; /*-----------------------------------------------------------. | yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | `-----------------------------------------------------------*/ yyexhaustedlab: yyerror (&yylloc, context, YY_("memory exhausted")); yyresult = 2; goto yyreturnlab; /*----------------------------------------------------------. | yyreturnlab -- parsing is finished, clean up and return. | `----------------------------------------------------------*/ yyreturnlab: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, context); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp, context); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); return yyresult; } #line 146 "src/core/io/gml-parser.y" int igraph_gml_yyerror(YYLTYPE* locp, igraph_i_gml_parsedata_t *context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char)-1, "Parse error in GML file, line %i (%s)", locp->first_line, s); return 0; } void igraph_i_gml_get_keyword(char *s, int len, void *res) { struct { char *s; int len; } *p=res; p->s=IGRAPH_CALLOC(len+1, char); if (!p->s) { igraph_error("Cannot read GML file", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_PARSEERROR); } memcpy(p->s, s, sizeof(char)*len); p->s[len]='\0'; p->len=len; } void igraph_i_gml_get_string(char *s, int len, void *res) { struct { char *s; int len; } *p=res; p->s=IGRAPH_CALLOC(len-1, char); if (!p->s) { igraph_error("Cannot read GML file", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_PARSEERROR); } memcpy(p->s, s+1, sizeof(char)*(len-2)); p->s[len-2]='\0'; p->len=len-2; } double igraph_i_gml_get_real(char *s, int len) { igraph_real_t num; char tmp=s[len]; s[len]='\0'; sscanf(s, "%lf", &num); s[len]=tmp; return num; } igraph_gml_tree_t *igraph_i_gml_make_numeric(char* s, int len, double value) { igraph_gml_tree_t *t = IGRAPH_CALLOC(1, igraph_gml_tree_t); if (!t) { igraph_error("Cannot build GML tree", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } if (floor(value)==value) { if (igraph_gml_tree_init_integer(t, s, len, value)) { free(t); return 0; } } else { if (igraph_gml_tree_init_real(t, s, len, value)) { free(t); return 0; } } return t; } igraph_gml_tree_t *igraph_i_gml_make_numeric2(char* s, int len, char* v, int vlen) { igraph_gml_tree_t *t = IGRAPH_CALLOC(1, igraph_gml_tree_t); char tmp = v[vlen]; if (!t) { igraph_error("Cannot build GML tree", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } v[vlen]='\0'; /* if v == "inf" or v == "nan", the newly created tree node will take ownership * of s. If the creation fails, we need to free s and v as well in order not * to leak memory */ if (strcasecmp(v, "inf")) { if (igraph_gml_tree_init_real(t, s, len, IGRAPH_INFINITY)) { free(t); t = 0; } } else if (strcasecmp(v, "nan")) { if (igraph_gml_tree_init_real(t, s, len, IGRAPH_NAN)) { free(t); t = 0; } } else { igraph_error("Parse error", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_PARSEERROR); free(t); t = 0; } v[vlen]=tmp; free(v); if (t == 0) { /* no new tree node was created so s has no owner any more */ free(s); } return t; } igraph_gml_tree_t *igraph_i_gml_make_string(char* s, int len, char *value, int valuelen) { igraph_gml_tree_t *t = IGRAPH_CALLOC(1, igraph_gml_tree_t); if (!t) { igraph_error("Cannot build GML tree", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } /* if igraph_gml_tree_init_string succeeds, the newly created tree node takes * ownership of 'value'. If it fails, we need to free 'value' ourselves in order * not to leak memory */ if (igraph_gml_tree_init_string(t, s, len, value, valuelen)) { free(t); free(value); t = 0; } return t; } igraph_gml_tree_t *igraph_i_gml_make_list(char* s, int len, igraph_gml_tree_t *list) { igraph_gml_tree_t *t=IGRAPH_CALLOC(1, igraph_gml_tree_t); if (!t) { igraph_error("Cannot build GML tree", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } if (igraph_gml_tree_init_tree(t, s, len, list)) { free(t); return 0; } return t; } igraph_gml_tree_t *igraph_i_gml_merge(igraph_gml_tree_t *t1, igraph_gml_tree_t* t2) { igraph_gml_tree_mergedest(t1, t2); IGRAPH_FREE(t2); return t1; } leidenbase/src/core/io/ncol-lexer.h0000644000176200001440000004234614447675375016753 0ustar liggesusers#ifndef igraph_ncol_yyHEADER_H #define igraph_ncol_yyHEADER_H 1 #define igraph_ncol_yyIN_HEADER 1 #line 6 "src/core/io/ncol-lexer.h" #line 8 "src/core/io/ncol-lexer.h" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_ncol_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_ncol_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_ncol_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_ncol_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_ncol_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_ncol_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_ncol_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_ncol_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_ncol_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_ncol_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_ncol_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_ncol_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_ncol_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_ncol_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_ncol_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_ncol_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_ncol_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_ncol_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_ncol_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_ncol_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_ncol_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_ncol_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_ncol_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_ncol_yyensure_buffer_stack #endif #ifdef yylex #define igraph_ncol_yylex_ALREADY_DEFINED #else #define yylex igraph_ncol_yylex #endif #ifdef yyrestart #define igraph_ncol_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_ncol_yyrestart #endif #ifdef yylex_init #define igraph_ncol_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_ncol_yylex_init #endif #ifdef yylex_init_extra #define igraph_ncol_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_ncol_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_ncol_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_ncol_yylex_destroy #endif #ifdef yyget_debug #define igraph_ncol_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_ncol_yyget_debug #endif #ifdef yyset_debug #define igraph_ncol_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_ncol_yyset_debug #endif #ifdef yyget_extra #define igraph_ncol_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_ncol_yyget_extra #endif #ifdef yyset_extra #define igraph_ncol_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_ncol_yyset_extra #endif #ifdef yyget_in #define igraph_ncol_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_ncol_yyget_in #endif #ifdef yyset_in #define igraph_ncol_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_ncol_yyset_in #endif #ifdef yyget_out #define igraph_ncol_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_ncol_yyget_out #endif #ifdef yyset_out #define igraph_ncol_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_ncol_yyset_out #endif #ifdef yyget_leng #define igraph_ncol_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_ncol_yyget_leng #endif #ifdef yyget_text #define igraph_ncol_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_ncol_yyget_text #endif #ifdef yyget_lineno #define igraph_ncol_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_ncol_yyget_lineno #endif #ifdef yyset_lineno #define igraph_ncol_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_ncol_yyset_lineno #endif #ifdef yyget_column #define igraph_ncol_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_ncol_yyget_column #endif #ifdef yyset_column #define igraph_ncol_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_ncol_yyset_column #endif #ifdef yywrap #define igraph_ncol_yywrap_ALREADY_DEFINED #else #define yywrap igraph_ncol_yywrap #endif #ifdef yyget_lval #define igraph_ncol_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_ncol_yyget_lval #endif #ifdef yyset_lval #define igraph_ncol_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_ncol_yyset_lval #endif #ifdef yyget_lloc #define igraph_ncol_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_ncol_yyget_lloc #endif #ifdef yyset_lloc #define igraph_ncol_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_ncol_yyset_lloc #endif #ifdef yyalloc #define igraph_ncol_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_ncol_yyalloc #endif #ifdef yyrealloc #define igraph_ncol_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_ncol_yyrealloc #endif #ifdef yyfree #define igraph_ncol_yyfree_ALREADY_DEFINED #else #define yyfree igraph_ncol_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); /* Begin user sect3 */ #define igraph_ncol_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP #define yytext_ptr yytext_r #ifdef YY_HEADER_EXPORT_START_CONDITIONS #define INITIAL 0 #endif #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* yy_get_previous_state - get the state just before the EOB char was reached */ #undef YY_NEW_FILE #undef YY_FLUSH_BUFFER #undef yy_set_bol #undef yy_new_buffer #undef yy_set_interactive #undef YY_DO_BEFORE_ACTION #ifdef YY_DECL_IS_OURS #undef YY_DECL_IS_OURS #undef YY_DECL #endif #ifndef igraph_ncol_yy_create_buffer_ALREADY_DEFINED #undef yy_create_buffer #endif #ifndef igraph_ncol_yy_delete_buffer_ALREADY_DEFINED #undef yy_delete_buffer #endif #ifndef igraph_ncol_yy_scan_buffer_ALREADY_DEFINED #undef yy_scan_buffer #endif #ifndef igraph_ncol_yy_scan_string_ALREADY_DEFINED #undef yy_scan_string #endif #ifndef igraph_ncol_yy_scan_bytes_ALREADY_DEFINED #undef yy_scan_bytes #endif #ifndef igraph_ncol_yy_init_buffer_ALREADY_DEFINED #undef yy_init_buffer #endif #ifndef igraph_ncol_yy_flush_buffer_ALREADY_DEFINED #undef yy_flush_buffer #endif #ifndef igraph_ncol_yy_load_buffer_state_ALREADY_DEFINED #undef yy_load_buffer_state #endif #ifndef igraph_ncol_yy_switch_to_buffer_ALREADY_DEFINED #undef yy_switch_to_buffer #endif #ifndef igraph_ncol_yypush_buffer_state_ALREADY_DEFINED #undef yypush_buffer_state #endif #ifndef igraph_ncol_yypop_buffer_state_ALREADY_DEFINED #undef yypop_buffer_state #endif #ifndef igraph_ncol_yyensure_buffer_stack_ALREADY_DEFINED #undef yyensure_buffer_stack #endif #ifndef igraph_ncol_yylex_ALREADY_DEFINED #undef yylex #endif #ifndef igraph_ncol_yyrestart_ALREADY_DEFINED #undef yyrestart #endif #ifndef igraph_ncol_yylex_init_ALREADY_DEFINED #undef yylex_init #endif #ifndef igraph_ncol_yylex_init_extra_ALREADY_DEFINED #undef yylex_init_extra #endif #ifndef igraph_ncol_yylex_destroy_ALREADY_DEFINED #undef yylex_destroy #endif #ifndef igraph_ncol_yyget_debug_ALREADY_DEFINED #undef yyget_debug #endif #ifndef igraph_ncol_yyset_debug_ALREADY_DEFINED #undef yyset_debug #endif #ifndef igraph_ncol_yyget_extra_ALREADY_DEFINED #undef yyget_extra #endif #ifndef igraph_ncol_yyset_extra_ALREADY_DEFINED #undef yyset_extra #endif #ifndef igraph_ncol_yyget_in_ALREADY_DEFINED #undef yyget_in #endif #ifndef igraph_ncol_yyset_in_ALREADY_DEFINED #undef yyset_in #endif #ifndef igraph_ncol_yyget_out_ALREADY_DEFINED #undef yyget_out #endif #ifndef igraph_ncol_yyset_out_ALREADY_DEFINED #undef yyset_out #endif #ifndef igraph_ncol_yyget_leng_ALREADY_DEFINED #undef yyget_leng #endif #ifndef igraph_ncol_yyget_text_ALREADY_DEFINED #undef yyget_text #endif #ifndef igraph_ncol_yyget_lineno_ALREADY_DEFINED #undef yyget_lineno #endif #ifndef igraph_ncol_yyset_lineno_ALREADY_DEFINED #undef yyset_lineno #endif #ifndef igraph_ncol_yyget_column_ALREADY_DEFINED #undef yyget_column #endif #ifndef igraph_ncol_yyset_column_ALREADY_DEFINED #undef yyset_column #endif #ifndef igraph_ncol_yywrap_ALREADY_DEFINED #undef yywrap #endif #ifndef igraph_ncol_yyget_lval_ALREADY_DEFINED #undef yyget_lval #endif #ifndef igraph_ncol_yyset_lval_ALREADY_DEFINED #undef yyset_lval #endif #ifndef igraph_ncol_yyget_lloc_ALREADY_DEFINED #undef yyget_lloc #endif #ifndef igraph_ncol_yyset_lloc_ALREADY_DEFINED #undef yyset_lloc #endif #ifndef igraph_ncol_yyalloc_ALREADY_DEFINED #undef yyalloc #endif #ifndef igraph_ncol_yyrealloc_ALREADY_DEFINED #undef yyrealloc #endif #ifndef igraph_ncol_yyfree_ALREADY_DEFINED #undef yyfree #endif #ifndef igraph_ncol_yytext_ALREADY_DEFINED #undef yytext #endif #ifndef igraph_ncol_yyleng_ALREADY_DEFINED #undef yyleng #endif #ifndef igraph_ncol_yyin_ALREADY_DEFINED #undef yyin #endif #ifndef igraph_ncol_yyout_ALREADY_DEFINED #undef yyout #endif #ifndef igraph_ncol_yy_flex_debug_ALREADY_DEFINED #undef yy_flex_debug #endif #ifndef igraph_ncol_yylineno_ALREADY_DEFINED #undef yylineno #endif #ifndef igraph_ncol_yytables_fload_ALREADY_DEFINED #undef yytables_fload #endif #ifndef igraph_ncol_yytables_destroy_ALREADY_DEFINED #undef yytables_destroy #endif #ifndef igraph_ncol_yyTABLES_NAME_ALREADY_DEFINED #undef yyTABLES_NAME #endif #line 99 "src/core/io/ncol-lexer.l" #line 735 "src/core/io/ncol-lexer.h" #undef igraph_ncol_yyIN_HEADER #endif /* igraph_ncol_yyHEADER_H */ leidenbase/src/core/io/lgl-parser.c0000644000176200001440000016233714447675375016751 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ #define YYBISON 30802 /* Bison version string. */ #define YYBISON_VERSION "3.8.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Substitute the variable and function names. */ #define yyparse igraph_lgl_yyparse #define yylex igraph_lgl_yylex #define yyerror igraph_lgl_yyerror #define yydebug igraph_lgl_yydebug #define yynerrs igraph_lgl_yynerrs /* First part of user prologue. */ #line 23 "src/core/io/lgl-parser.y" /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" #include "config.h" #include "core/math.h" #include "io/lgl-header.h" #include "io/lgl-parser.h" #include "io/lgl-lexer.h" #include "internal/hacks.h" int igraph_lgl_yyerror(YYLTYPE* locp, igraph_i_lgl_parsedata_t *context, const char *s); igraph_real_t igraph_lgl_get_number(const char *str, long int len); #define scanner context->scanner #line 121 "yy.tab.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif #include "io/lgl-parser.h" /* Symbol kind. */ enum yysymbol_kind_t { YYSYMBOL_YYEMPTY = -2, YYSYMBOL_YYEOF = 0, /* "end of file" */ YYSYMBOL_YYerror = 1, /* error */ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ YYSYMBOL_ALNUM = 3, /* ALNUM */ YYSYMBOL_NEWLINE = 4, /* NEWLINE */ YYSYMBOL_HASH = 5, /* HASH */ YYSYMBOL_ERROR = 6, /* ERROR */ YYSYMBOL_YYACCEPT = 7, /* $accept */ YYSYMBOL_input = 8, /* input */ YYSYMBOL_vertex = 9, /* vertex */ YYSYMBOL_vertexdef = 10, /* vertexdef */ YYSYMBOL_edges = 11, /* edges */ YYSYMBOL_edge = 12, /* edge */ YYSYMBOL_edgeid = 13, /* edgeid */ YYSYMBOL_weight = 14 /* weight */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif /* Work around bug in HP-UX 11.23, which defines these macros incorrectly for preprocessor constants. This workaround can likely be removed in 2023, as HPE has promised support for HP-UX 11.23 (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of . */ #ifdef __hpux # undef UINT_LEAST8_MAX # undef UINT_LEAST16_MAX # define UINT_LEAST8_MAX 255 # define UINT_LEAST16_MAX 65535 #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_int8 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YY_USE(E) ((void) (E)) #else # define YY_USE(E) /* empty */ #endif /* Suppress an incorrect diagnostic about yylval being uninitialized. */ #if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ # if __GNUC__ * 100 + __GNUC_MINOR__ < 407 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") # else # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # endif # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if 1 /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* 1 */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ + YYSIZEOF (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 10 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 7 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 8 /* YYNRULES -- Number of rules. */ #define YYNRULES 12 /* YYNSTATES -- Number of states. */ #define YYNSTATES 17 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 261 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK \ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int8 yyrline[] = { 0, 93, 93, 94, 95, 98, 100, 102, 102, 104, 109, 118, 123 }; #endif /** Accessing symbol of state STATE. */ #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) #if 1 /* The user-facing name of the symbol whose (internal) number is YYSYMBOL. No bounds checking. */ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "\"end of file\"", "error", "\"invalid token\"", "ALNUM", "NEWLINE", "HASH", "ERROR", "$accept", "input", "vertex", "vertexdef", "edges", "edge", "edgeid", "weight", YY_NULLPTR }; static const char * yysymbol_name (yysymbol_kind_t yysymbol) { return yytname[yysymbol]; } #endif #define YYPACT_NINF (-3) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-1) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int8 yypact[] = { -3, 0, -3, -3, 3, -3, -3, -3, -1, 3, -3, -3, -2, -3, -3, 4, -3 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_int8 yydefact[] = { 2, 0, 1, 3, 0, 4, 7, 11, 0, 5, 6, 8, 0, 12, 9, 0, 10 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -3, -3, -3, -3, -3, -3, 1, -3 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { 0, 1, 5, 6, 9, 11, 8, 15 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { 2, 13, 14, 10, 3, 4, 7, 0, 16, 0, 12 }; static const yytype_int8 yycheck[] = { 0, 3, 4, 4, 4, 5, 3, -1, 4, -1, 9 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { 0, 8, 0, 4, 5, 9, 10, 3, 13, 11, 4, 12, 13, 3, 4, 14, 4 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int8 yyr1[] = { 0, 7, 8, 8, 8, 9, 10, 11, 11, 12, 12, 13, 14 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ static const yytype_int8 yyr2[] = { 0, 2, 0, 2, 2, 2, 3, 0, 2, 2, 3, 1, 1 }; enum { YYENOMEM = -2 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Backward compatibility with an undocumented macro. Use YYerror or YYUNDEF. */ #define YYERRCODE YYUNDEF /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (N) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (0) #endif #define YYRHSLOC(Rhs, K) ((Rhs)[K]) /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* YYLOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ # ifndef YYLOCATION_PRINT # if defined YY_LOCATION_PRINT /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc)) # elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL /* Print *YYLOCP on YYO. Private, do not rely on its existence. */ YY_ATTRIBUTE_UNUSED static int yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) { int res = 0; int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; if (0 <= yylocp->first_line) { res += YYFPRINTF (yyo, "%d", yylocp->first_line); if (0 <= yylocp->first_column) res += YYFPRINTF (yyo, ".%d", yylocp->first_column); } if (0 <= yylocp->last_line) { if (yylocp->first_line < yylocp->last_line) { res += YYFPRINTF (yyo, "-%d", yylocp->last_line); if (0 <= end_col) res += YYFPRINTF (yyo, ".%d", end_col); } else if (0 <= end_col && yylocp->first_column < end_col) res += YYFPRINTF (yyo, "-%d", end_col); } return res; } # define YYLOCATION_PRINT yy_location_print_ /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc)) # else # define YYLOCATION_PRINT(File, Loc) ((void) 0) /* Temporary convenience wrapper in case some people defined the undocumented and private YY_LOCATION_PRINT macros. */ # define YY_LOCATION_PRINT YYLOCATION_PRINT # endif # endif /* !defined YYLOCATION_PRINT */ # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Kind, Value, Location, context); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_lgl_parsedata_t* context) { FILE *yyoutput = yyo; YY_USE (yyoutput); YY_USE (yylocationp); YY_USE (context); if (!yyvaluep) return; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, igraph_i_lgl_parsedata_t* context) { YYFPRINTF (yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); YYLOCATION_PRINT (yyo, yylocationp); YYFPRINTF (yyo, ": "); yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp, context); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, igraph_i_lgl_parsedata_t* context) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), &yyvsp[(yyi + 1) - (yynrhs)], &(yylsp[(yyi + 1) - (yynrhs)]), context); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, yylsp, Rule, context); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) ((void) 0) # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif /* Context of a parse error. */ typedef struct { yy_state_t *yyssp; yysymbol_kind_t yytoken; YYLTYPE *yylloc; } yypcontext_t; /* Put in YYARG at most YYARGN of the expected tokens given the current YYCTX, and return the number of tokens stored in YYARG. If YYARG is null, return the number of expected tokens (guaranteed to be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. Return 0 if there are more than YYARGN expected tokens, yet fill YYARG up to YYARGN. */ static int yypcontext_expected_tokens (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; int yyn = yypact[+*yyctx->yyssp]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror && !yytable_value_is_error (yytable[yyx + yyn])) { if (!yyarg) ++yycount; else if (yycount == yyargn) return 0; else yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); } } if (yyarg && yycount == 0 && 0 < yyargn) yyarg[0] = YYSYMBOL_YYEMPTY; return yycount; } #ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) { YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif #endif #ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif #endif #ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; else goto append; append: default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (yyres) return yystpcpy (yyres, yystr) - yyres; else return yystrlen (yystr); } #endif static int yy_syntax_error_arguments (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yyctx->yytoken != YYSYMBOL_YYEMPTY) { int yyn; if (yyarg) yyarg[yycount] = yyctx->yytoken; ++yycount; yyn = yypcontext_expected_tokens (yyctx, yyarg ? yyarg + 1 : yyarg, yyargn - 1); if (yyn == YYENOMEM) return YYENOMEM; else yycount += yyn; } return yycount; } /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the required number of bytes is too large to store. */ static int yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, const yypcontext_t *yyctx) { enum { YYARGS_MAX = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ yysymbol_kind_t yyarg[YYARGS_MAX]; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; /* Actual size of YYARG. */ int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); if (yycount == YYENOMEM) return YYENOMEM; switch (yycount) { #define YYCASE_(N, S) \ case N: \ yyformat = S; \ break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); #undef YYCASE_ } /* Compute error message size. Don't count the "%s"s, but reserve room for the terminator. */ yysize = yystrlen (yyformat) - 2 * yycount + 1; { int yyi; for (yyi = 0; yyi < yycount; ++yyi) { YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return YYENOMEM; } } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return -1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); yyformat += 2; } else { ++yyp; ++yyformat; } } return 0; } /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, igraph_i_lgl_parsedata_t* context) { YY_USE (yyvaluep); YY_USE (yylocationp); YY_USE (context); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*----------. | yyparse. | `----------*/ int yyparse (igraph_i_lgl_parsedata_t* context) { /* Lookahead token kind. */ int yychar; /* The semantic value of the lookahead symbol. */ /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Location data for the lookahead symbol. */ static YYLTYPE yyloc_default # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL = { 1, 1, 1, 1 } # endif ; YYLTYPE yylloc = yyloc_default; /* Number of syntax errors so far. */ int yynerrs = 0; yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus = 0; /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* Their size. */ YYPTRDIFF_T yystacksize = YYINITDEPTH; /* The state stack: array, bottom, top. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss = yyssa; yy_state_t *yyssp = yyss; /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp = yyvs; /* The location stack: array, bottom, top. */ YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp = yyls; int yyn; /* The return value of yyparse. */ int yyresult; /* Lookahead symbol kind. */ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; /* The locations where the error started and ended. */ YYLTYPE yyerror_range[3]; /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ yylsp[0] = yylloc; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE YYNOMEM; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; YYLTYPE *yyls1 = yyls; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yyls1, yysize * YYSIZEOF (*yylsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; yyls = yyls1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) YYNOMEM; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) YYNOMEM; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; yylsp = yyls + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (&yylval, &yylloc, scanner); } if (yychar <= YYEOF) { yychar = YYEOF; yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else if (yychar == YYerror) { /* The scanner already issued an error message, process directly to error recovery. But do not keep the error token as lookahead, it is too special and may lead us to an endless loop in error recovery. */ yychar = YYUNDEF; yytoken = YYSYMBOL_YYerror; yyerror_range[1] = yylloc; goto yyerrlab1; } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END *++yylsp = yylloc; /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); yyerror_range[1] = yyloc; YY_REDUCE_PRINT (yyn); switch (yyn) { case 6: /* vertexdef: HASH edgeid NEWLINE */ #line 100 "src/core/io/lgl-parser.y" { context->actvertex=(yyvsp[-1].edgenum); } #line 1515 "yy.tab.c" break; case 9: /* edge: edgeid NEWLINE */ #line 104 "src/core/io/lgl-parser.y" { igraph_vector_push_back(context->vector, context->actvertex); igraph_vector_push_back(context->vector, (yyvsp[-1].edgenum)); igraph_vector_push_back(context->weights, 0); } #line 1525 "yy.tab.c" break; case 10: /* edge: edgeid weight NEWLINE */ #line 109 "src/core/io/lgl-parser.y" { igraph_vector_push_back(context->vector, context->actvertex); igraph_vector_push_back(context->vector, (yyvsp[-2].edgenum)); igraph_vector_push_back(context->weights, (yyvsp[-1].weightnum)); context->has_weights = 1; } #line 1536 "yy.tab.c" break; case 11: /* edgeid: ALNUM */ #line 118 "src/core/io/lgl-parser.y" { igraph_trie_get2(context->trie, igraph_lgl_yyget_text(scanner), igraph_lgl_yyget_leng(scanner), &(yyval.edgenum)); } #line 1545 "yy.tab.c" break; case 12: /* weight: ALNUM */ #line 123 "src/core/io/lgl-parser.y" { (yyval.weightnum)=igraph_lgl_get_number(igraph_lgl_yyget_text(scanner), igraph_lgl_yyget_leng(scanner)); } #line 1552 "yy.tab.c" break; #line 1556 "yy.tab.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; *++yyvsp = yyval; *++yylsp = yyloc; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; { yypcontext_t yyctx = {yyssp, yytoken, &yylloc}; char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == -1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (yymsg) { yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); yymsgp = yymsg; } else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = YYENOMEM; } } yyerror (&yylloc, context, yymsgp); if (yysyntax_error_status == YYENOMEM) YYNOMEM; } } yyerror_range[1] = yylloc; if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, &yylloc, context); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYSYMBOL_YYerror; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yyerror_range[1] = *yylsp; yydestruct ("Error: popping", YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp, context); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END yyerror_range[2] = yylloc; ++yylsp; YYLLOC_DEFAULT (*yylsp, yyerror_range, 2); /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturnlab; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturnlab; /*-----------------------------------------------------------. | yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | `-----------------------------------------------------------*/ yyexhaustedlab: yyerror (&yylloc, context, YY_("memory exhausted")); yyresult = 2; goto yyreturnlab; /*----------------------------------------------------------. | yyreturnlab -- parsing is finished, clean up and return. | `----------------------------------------------------------*/ yyreturnlab: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, context); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp, context); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); return yyresult; } #line 126 "src/core/io/lgl-parser.y" int igraph_lgl_yyerror(YYLTYPE* locp, igraph_i_lgl_parsedata_t *context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char), "Parse error in LGL file, line %i (%s)", locp->first_line, s); return 0; } igraph_real_t igraph_lgl_get_number(const char *str, long int length) { igraph_real_t num; char *tmp=IGRAPH_CALLOC(length+1, char); strncpy(tmp, str, length); tmp[length]='\0'; sscanf(tmp, "%lf", &num); IGRAPH_FREE(tmp); return num; } leidenbase/src/core/io/lgl-lexer.c0000644000176200001440000017046714447675375016577 0ustar liggesusers#line 2 "src/core/io/lgl-lexer.c" #line 4 "src/core/io/lgl-lexer.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_lgl_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_lgl_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_lgl_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_lgl_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_lgl_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_lgl_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_lgl_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_lgl_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_lgl_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_lgl_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_lgl_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_lgl_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_lgl_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_lgl_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_lgl_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_lgl_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_lgl_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_lgl_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_lgl_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_lgl_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_lgl_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_lgl_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_lgl_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_lgl_yyensure_buffer_stack #endif #ifdef yylex #define igraph_lgl_yylex_ALREADY_DEFINED #else #define yylex igraph_lgl_yylex #endif #ifdef yyrestart #define igraph_lgl_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_lgl_yyrestart #endif #ifdef yylex_init #define igraph_lgl_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_lgl_yylex_init #endif #ifdef yylex_init_extra #define igraph_lgl_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_lgl_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_lgl_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_lgl_yylex_destroy #endif #ifdef yyget_debug #define igraph_lgl_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_lgl_yyget_debug #endif #ifdef yyset_debug #define igraph_lgl_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_lgl_yyset_debug #endif #ifdef yyget_extra #define igraph_lgl_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_lgl_yyget_extra #endif #ifdef yyset_extra #define igraph_lgl_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_lgl_yyset_extra #endif #ifdef yyget_in #define igraph_lgl_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_lgl_yyget_in #endif #ifdef yyset_in #define igraph_lgl_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_lgl_yyset_in #endif #ifdef yyget_out #define igraph_lgl_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_lgl_yyget_out #endif #ifdef yyset_out #define igraph_lgl_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_lgl_yyset_out #endif #ifdef yyget_leng #define igraph_lgl_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_lgl_yyget_leng #endif #ifdef yyget_text #define igraph_lgl_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_lgl_yyget_text #endif #ifdef yyget_lineno #define igraph_lgl_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_lgl_yyget_lineno #endif #ifdef yyset_lineno #define igraph_lgl_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_lgl_yyset_lineno #endif #ifdef yyget_column #define igraph_lgl_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_lgl_yyget_column #endif #ifdef yyset_column #define igraph_lgl_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_lgl_yyset_column #endif #ifdef yywrap #define igraph_lgl_yywrap_ALREADY_DEFINED #else #define yywrap igraph_lgl_yywrap #endif #ifdef yyget_lval #define igraph_lgl_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_lgl_yyget_lval #endif #ifdef yyset_lval #define igraph_lgl_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_lgl_yyset_lval #endif #ifdef yyget_lloc #define igraph_lgl_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_lgl_yyget_lloc #endif #ifdef yyset_lloc #define igraph_lgl_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_lgl_yyset_lloc #endif #ifdef yyalloc #define igraph_lgl_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_lgl_yyalloc #endif #ifdef yyrealloc #define igraph_lgl_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_lgl_yyrealloc #endif #ifdef yyfree #define igraph_lgl_yyfree_ALREADY_DEFINED #else #define yyfree igraph_lgl_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define igraph_lgl_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void __attribute__((unused)) yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 6 #define YY_END_OF_BUFFER 7 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[14] = { 0, 0, 0, 7, 4, 2, 3, 3, 1, 5, 4, 2, 3, 0 } ; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static const YY_CHAR yy_meta[7] = { 0, 1, 2, 3, 4, 5, 5 } ; static const flex_int16_t yy_base[18] = { 0, 0, 0, 11, 0, 0, 0, 0, 12, 12, 0, 0, 12, 12, 9, 7, 4, 4 } ; static const flex_int16_t yy_def[18] = { 0, 13, 1, 13, 14, 15, 16, 17, 13, 13, 14, 15, 13, 0, 13, 13, 13, 13 } ; static const flex_int16_t yy_nxt[19] = { 0, 4, 5, 6, 7, 8, 9, 12, 12, 11, 10, 13, 3, 13, 13, 13, 13, 13, 13 } ; static const flex_int16_t yy_chk[19] = { 0, 1, 1, 1, 1, 1, 1, 17, 16, 15, 14, 3, 13, 13, 13, 13, 13, 13, 13 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "src/core/io/lgl-lexer.l" /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #line 24 "src/core/io/lgl-lexer.l" /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "io/lgl-header.h" #include "io/lgl-parser.h" #define YY_EXTRA_TYPE igraph_i_lgl_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in LGL parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif #line 722 "src/core/io/lgl-lexer.c" #define YY_NO_INPUT 1 #line 724 "src/core/io/lgl-lexer.c" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; YYSTYPE * yylval_r; YYLTYPE * yylloc_r; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r # define yylloc yyg->yylloc_r int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; yylloc = yylloc_param; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 76 "src/core/io/lgl-lexer.l" #line 79 "src/core/io/lgl-lexer.l" /* --------------------------------------------------hashmark------*/ #line 1011 "src/core/io/lgl-lexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 14 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 12 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 80 "src/core/io/lgl-lexer.l" { return HASH; } YY_BREAK /* ------------------------------------------------whitespace------*/ case 2: YY_RULE_SETUP #line 83 "src/core/io/lgl-lexer.l" { } YY_BREAK /* ---------------------------------------------------newline------*/ case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 86 "src/core/io/lgl-lexer.l" { return NEWLINE; } YY_BREAK /* ----------------------------------------------alphanumeric------*/ case 4: YY_RULE_SETUP #line 89 "src/core/io/lgl-lexer.l" { return ALNUM; } YY_BREAK case YY_STATE_EOF(INITIAL): #line 91 "src/core/io/lgl-lexer.l" { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; return NEWLINE; } } YY_BREAK case 5: YY_RULE_SETUP #line 99 "src/core/io/lgl-lexer.l" { return ERROR; } YY_BREAK case 6: YY_RULE_SETUP #line 101 "src/core/io/lgl-lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK #line 1112 "src/core/io/lgl-lexer.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 6); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 14 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; YY_CHAR yy_c = 6; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 14 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_is_jam = (yy_current_state == 13); (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void __attribute__((unused)) yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ YYSTYPE * yyget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } YYLTYPE *yyget_lloc (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylloc; } void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylloc = yylloc_param; } /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 101 "src/core/io/lgl-lexer.l" leidenbase/src/core/io/gml-tree.h0000644000176200001440000000624514447675374016414 0ustar liggesusers/* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef REST_GML_TREE_H #define REST_GML_TREE_H #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" __BEGIN_DECLS typedef enum { IGRAPH_I_GML_TREE_TREE = 0, IGRAPH_I_GML_TREE_INTEGER, IGRAPH_I_GML_TREE_REAL, IGRAPH_I_GML_TREE_STRING, IGRAPH_I_GML_TREE_DELETED } igraph_i_gml_tree_type_t; typedef struct igraph_gml_tree_t { igraph_vector_ptr_t names; igraph_vector_char_t types; igraph_vector_ptr_t children; } igraph_gml_tree_t; int igraph_gml_tree_init_integer(igraph_gml_tree_t *t, const char *name, int namelen, igraph_integer_t value); int igraph_gml_tree_init_real(igraph_gml_tree_t *t, const char *name, int namelen, igraph_real_t value); int igraph_gml_tree_init_string(igraph_gml_tree_t *t, const char *name, int namelen, const char *value, int valuelen); int igraph_gml_tree_init_tree(igraph_gml_tree_t *t, const char *name, int namelen, igraph_gml_tree_t *value); void igraph_gml_tree_destroy(igraph_gml_tree_t *t); void igraph_gml_tree_delete(igraph_gml_tree_t *t, long int pos); int igraph_gml_tree_mergedest(igraph_gml_tree_t *t1, igraph_gml_tree_t *t2); long int igraph_gml_tree_length(const igraph_gml_tree_t *t); long int igraph_gml_tree_find(const igraph_gml_tree_t *t, const char *name, long int from); long int igraph_gml_tree_findback(const igraph_gml_tree_t *t, const char *name, long int from); int igraph_gml_tree_type(const igraph_gml_tree_t *t, long int pos); const char *igraph_gml_tree_name(const igraph_gml_tree_t *t, long int pos); igraph_integer_t igraph_gml_tree_get_integer(const igraph_gml_tree_t *t, long int pos); igraph_real_t igraph_gml_tree_get_real(const igraph_gml_tree_t *t, long int pos); const char *igraph_gml_tree_get_string(const igraph_gml_tree_t *t, long int pos); igraph_gml_tree_t *igraph_gml_tree_get_tree(const igraph_gml_tree_t *t, long int pos); __END_DECLS #endif leidenbase/src/core/io/dl-parser.h0000644000176200001440000000705714447675375016574 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ #ifndef YY_IGRAPH_DL_YY_YY_TAB_H_INCLUDED # define YY_IGRAPH_DL_YY_YY_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int igraph_dl_yydebug; #endif /* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { YYEMPTY = -2, YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ NUM = 258, /* NUM */ NEWLINE = 259, /* NEWLINE */ DL = 260, /* DL */ NEQ = 261, /* NEQ */ DATA = 262, /* DATA */ LABELS = 263, /* LABELS */ LABELSEMBEDDED = 264, /* LABELSEMBEDDED */ FORMATFULLMATRIX = 265, /* FORMATFULLMATRIX */ FORMATEDGELIST1 = 266, /* FORMATEDGELIST1 */ FORMATNODELIST1 = 267, /* FORMATNODELIST1 */ DIGIT = 268, /* DIGIT */ LABEL = 269, /* LABEL */ EOFF = 270, /* EOFF */ ERROR = 271 /* ERROR */ }; typedef enum yytokentype yytoken_kind_t; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 83 "src/core/io/dl-parser.y" long int integer; igraph_real_t real; #line 85 "yy.tab.h" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif /* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE YYLTYPE; struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; }; # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif int igraph_dl_yyparse (igraph_i_dl_parsedata_t* context); #endif /* !YY_IGRAPH_DL_YY_YY_TAB_H_INCLUDED */ leidenbase/src/core/io/gml-parser.y0000644000176200001440000002066114447675374016770 0ustar liggesusers/* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "igraph_error.h" #include "igraph_memory.h" #include "config.h" #include "core/math.h" #include "io/gml-header.h" #include "io/gml-tree.h" #include "io/parsers/gml-parser.h" #include "io/parsers/gml-lexer.h" #include "internal/hacks.h" /* strcasecmp */ int igraph_gml_yyerror(YYLTYPE* locp, igraph_i_gml_parsedata_t *context, const char *s); void igraph_i_gml_get_keyword(char *s, int len, void *res); void igraph_i_gml_get_string(char *s, int len, void *res); double igraph_i_gml_get_real(char *s, int len); igraph_gml_tree_t *igraph_i_gml_make_numeric(char* s, int len, double value); igraph_gml_tree_t *igraph_i_gml_make_numeric2(char* s, int len, char *v, int vlen); igraph_gml_tree_t *igraph_i_gml_make_string(char* s, int len, char *value, int valuelen); igraph_gml_tree_t *igraph_i_gml_make_list(char* s, int len, igraph_gml_tree_t *list); igraph_gml_tree_t *igraph_i_gml_merge(igraph_gml_tree_t *t1, igraph_gml_tree_t* t2); #define scanner context->scanner #define USE(x) /*(x)*/ %} %pure-parser /* bison: do not remove the equals sign; macOS XCode ships with bison 2.3, which * needs the equals sign */ %name-prefix="igraph_gml_yy" %defines %locations %error-verbose %parse-param { igraph_i_gml_parsedata_t* context } %lex-param { void *scanner } %union { struct { char *s; int len; } str; void *tree; double real; } %type list; %type keyvalue; %type key; %type num; %type string; %token STRING %token NUM %token KEYWORD %token LISTOPEN %token LISTCLOSE %token EOFF %token ERROR %destructor { IGRAPH_FREE($$.s); } string key KEYWORD; %destructor { igraph_gml_tree_destroy($$); } list keyvalue; %% input: list { context->tree=$1; } | list EOFF { context->tree=$1; } ; list: keyvalue { $$=$1; } | list keyvalue { $$=igraph_i_gml_merge($1, $2); }; keyvalue: key num { $$=igraph_i_gml_make_numeric($1.s, $1.len, $2); } | key string { $$=igraph_i_gml_make_string($1.s, $1.len, $2.s, $2.len); } | key LISTOPEN list LISTCLOSE { $$=igraph_i_gml_make_list($1.s, $1.len, $3); } | key key { $$=igraph_i_gml_make_numeric2($1.s, $1.len, $2.s, $2.len); } ; key: KEYWORD { igraph_i_gml_get_keyword(igraph_gml_yyget_text(scanner), igraph_gml_yyget_leng(scanner), &$$); USE($1); }; num : NUM { $$=igraph_i_gml_get_real(igraph_gml_yyget_text(scanner), igraph_gml_yyget_leng(scanner)); }; string: STRING { igraph_i_gml_get_string(igraph_gml_yyget_text(scanner), igraph_gml_yyget_leng(scanner), &$$); }; %% int igraph_gml_yyerror(YYLTYPE* locp, igraph_i_gml_parsedata_t *context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char)-1, "Parse error in GML file, line %i (%s)", locp->first_line, s); return 0; } void igraph_i_gml_get_keyword(char *s, int len, void *res) { struct { char *s; int len; } *p=res; p->s=IGRAPH_CALLOC(len+1, char); if (!p->s) { igraph_error("Cannot read GML file", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_PARSEERROR); } memcpy(p->s, s, sizeof(char)*len); p->s[len]='\0'; p->len=len; } void igraph_i_gml_get_string(char *s, int len, void *res) { struct { char *s; int len; } *p=res; p->s=IGRAPH_CALLOC(len-1, char); if (!p->s) { igraph_error("Cannot read GML file", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_PARSEERROR); } memcpy(p->s, s+1, sizeof(char)*(len-2)); p->s[len-2]='\0'; p->len=len-2; } double igraph_i_gml_get_real(char *s, int len) { igraph_real_t num; char tmp=s[len]; s[len]='\0'; sscanf(s, "%lf", &num); s[len]=tmp; return num; } igraph_gml_tree_t *igraph_i_gml_make_numeric(char* s, int len, double value) { igraph_gml_tree_t *t = IGRAPH_CALLOC(1, igraph_gml_tree_t); if (!t) { igraph_error("Cannot build GML tree", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } if (floor(value)==value) { if (igraph_gml_tree_init_integer(t, s, len, value)) { free(t); return 0; } } else { if (igraph_gml_tree_init_real(t, s, len, value)) { free(t); return 0; } } return t; } igraph_gml_tree_t *igraph_i_gml_make_numeric2(char* s, int len, char* v, int vlen) { igraph_gml_tree_t *t = IGRAPH_CALLOC(1, igraph_gml_tree_t); char tmp = v[vlen]; if (!t) { igraph_error("Cannot build GML tree", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } v[vlen]='\0'; /* if v == "inf" or v == "nan", the newly created tree node will take ownership * of s. If the creation fails, we need to free s and v as well in order not * to leak memory */ if (strcasecmp(v, "inf")) { if (igraph_gml_tree_init_real(t, s, len, IGRAPH_INFINITY)) { free(t); t = 0; } } else if (strcasecmp(v, "nan")) { if (igraph_gml_tree_init_real(t, s, len, IGRAPH_NAN)) { free(t); t = 0; } } else { igraph_error("Parse error", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_PARSEERROR); free(t); t = 0; } v[vlen]=tmp; free(v); if (t == 0) { /* no new tree node was created so s has no owner any more */ free(s); } return t; } igraph_gml_tree_t *igraph_i_gml_make_string(char* s, int len, char *value, int valuelen) { igraph_gml_tree_t *t = IGRAPH_CALLOC(1, igraph_gml_tree_t); if (!t) { igraph_error("Cannot build GML tree", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } /* if igraph_gml_tree_init_string succeeds, the newly created tree node takes * ownership of 'value'. If it fails, we need to free 'value' ourselves in order * not to leak memory */ if (igraph_gml_tree_init_string(t, s, len, value, valuelen)) { free(t); free(value); t = 0; } return t; } igraph_gml_tree_t *igraph_i_gml_make_list(char* s, int len, igraph_gml_tree_t *list) { igraph_gml_tree_t *t=IGRAPH_CALLOC(1, igraph_gml_tree_t); if (!t) { igraph_error("Cannot build GML tree", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } if (igraph_gml_tree_init_tree(t, s, len, list)) { free(t); return 0; } return t; } igraph_gml_tree_t *igraph_i_gml_merge(igraph_gml_tree_t *t1, igraph_gml_tree_t* t2) { igraph_gml_tree_mergedest(t1, t2); IGRAPH_FREE(t2); return t1; } leidenbase/src/core/io/dot.c0000644000176200001440000003175314447675374015463 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_attributes.h" #include "igraph_error.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_version.h" #include "graph/attributes.h" #include "internal/hacks.h" /* strcasecmp */ #include #include #define CHECK(cmd) do { ret=cmd; if (ret<0) IGRAPH_ERROR("Write DOT format failed.", IGRAPH_EFILE); } while (0) static int igraph_i_dot_escape(const char *orig, char **result) { /* do we have to escape the string at all? */ long int i, j, len = (long int) strlen(orig), newlen = 0; igraph_bool_t need_quote = 0, is_number = 1; /* first, check whether the string is equal to some reserved word */ if (!strcasecmp(orig, "graph") || !strcasecmp(orig, "digraph") || !strcasecmp(orig, "node") || !strcasecmp(orig, "edge") || !strcasecmp(orig, "strict") || !strcasecmp(orig, "subgraph")) { need_quote = 1; is_number = 0; } /* next, check whether we need to escape the string for any other reason. * Also update is_number and newlen */ for (i = 0; i < len; i++) { if (isdigit(orig[i])) { newlen++; } else if (orig[i] == '-' && i == 0) { newlen++; } else if (orig[i] == '.') { if (is_number) { newlen++; } else { need_quote = 1; newlen++; } } else if (orig[i] == '_') { is_number = 0; newlen++; } else if (orig[i] == '\\' || orig[i] == '"' || orig[i] == '\n') { need_quote = 1; is_number = 0; newlen += 2; /* will be escaped */ } else if (isalpha(orig[i])) { is_number = 0; newlen++; } else { is_number = 0; need_quote = 1; newlen++; } } if (is_number && orig[len - 1] == '.') { is_number = 0; } if (!is_number && isdigit(orig[0])) { need_quote = 1; } if (is_number || !need_quote) { *result = strdup(orig); if (!*result) { IGRAPH_ERROR("Writing DOT format failed.", IGRAPH_ENOMEM); } } else { *result = IGRAPH_CALLOC(newlen + 3, char); if (!*result) { IGRAPH_ERROR("Writing DOT format failed.", IGRAPH_ENOMEM); } (*result)[0] = '"'; (*result)[newlen + 1] = '"'; (*result)[newlen + 2] = '\0'; for (i = 0, j = 1; i < len; i++) { if (orig[i] == '\n') { (*result)[j++] = '\\'; (*result)[j++] = 'n'; continue; } if (orig[i] == '\\' || orig[i] == '"') { (*result)[j++] = '\\'; } (*result)[j++] = orig[i]; } } return IGRAPH_SUCCESS; } /** * \function igraph_write_graph_dot * \brief Write the graph to a stream in DOT format * * DOT is the format used by the widely known GraphViz software, see * http://www.graphviz.org for details. The grammar of the DOT format * can be found here: http://www.graphviz.org/doc/info/lang.html * * This is only a preliminary implementation, only the vertices * and the edges are written but not the attributes or any visualization * information. * * \param graph The graph to write to the stream. * \param outstream The stream to write the file to. * * Time complexity: should be proportional to the number of characters written * to the file. * * \sa \ref igraph_write_graph_graphml() for a more modern format. * * \example examples/simple/dot.c */ int igraph_write_graph_dot(const igraph_t *graph, FILE* outstream) { int ret; long int i, j; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); char edgeop[3]; igraph_strvector_t gnames, vnames, enames; igraph_vector_t gtypes, vtypes, etypes; igraph_vector_t numv; igraph_strvector_t strv; igraph_vector_bool_t boolv; IGRAPH_STRVECTOR_INIT_FINALLY(&gnames, 0); IGRAPH_STRVECTOR_INIT_FINALLY(&vnames, 0); IGRAPH_STRVECTOR_INIT_FINALLY(&enames, 0); IGRAPH_VECTOR_INIT_FINALLY(>ypes, 0); IGRAPH_VECTOR_INIT_FINALLY(&vtypes, 0); IGRAPH_VECTOR_INIT_FINALLY(&etypes, 0); IGRAPH_CHECK(igraph_i_attribute_get_info(graph, &gnames, >ypes, &vnames, &vtypes, &enames, &etypes)); IGRAPH_VECTOR_INIT_FINALLY(&numv, 1); IGRAPH_STRVECTOR_INIT_FINALLY(&strv, 1); IGRAPH_VECTOR_BOOL_INIT_FINALLY(&boolv, 1); CHECK(fprintf(outstream, "/* Created by igraph %s */\n", IGRAPH_VERSION)); if (igraph_is_directed(graph)) { CHECK(fprintf(outstream, "digraph {\n")); strcpy(edgeop, "->"); } else { CHECK(fprintf(outstream, "graph {\n")); strcpy(edgeop, "--"); } /* Write the graph attributes */ if (igraph_vector_size(>ypes) > 0) { CHECK(fprintf(outstream, " graph [\n")); for (i = 0; i < igraph_vector_size(>ypes); i++) { char *name, *newname; igraph_strvector_get(&gnames, i, &name); IGRAPH_CHECK(igraph_i_dot_escape(name, &newname)); IGRAPH_FINALLY(igraph_free, newname); if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_i_attribute_get_numeric_graph_attr(graph, name, &numv)); if (VECTOR(numv)[0] == (long)VECTOR(numv)[0]) { CHECK(fprintf(outstream, " %s=%ld\n", newname, (long)VECTOR(numv)[0])); } else { CHECK(fprintf(outstream, " %s=", newname)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(numv)[0])); CHECK(fputc('\n', outstream)); } } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_STRING) { char *s, *news; IGRAPH_CHECK(igraph_i_attribute_get_string_graph_attr(graph, name, &strv)); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_dot_escape(s, &news)); CHECK(fprintf(outstream, " %s=%s\n", newname, news)); IGRAPH_FREE(news); } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_CHECK(igraph_i_attribute_get_bool_graph_attr(graph, name, &boolv)); CHECK(fprintf(outstream, " %s=%d\n", newname, VECTOR(boolv)[0] ? 1 : 0)); IGRAPH_WARNING("A boolean graph attribute was converted to numeric"); } else { IGRAPH_WARNING("A non-numeric, non-string, non-boolean graph attribute ignored"); } IGRAPH_FREE(newname); IGRAPH_FINALLY_CLEAN(1); } CHECK(fprintf(outstream, " ];\n")); } /* Write the vertices */ if (igraph_vector_size(&vtypes) > 0) { for (i = 0; i < no_of_nodes; i++) { CHECK(fprintf(outstream, " %ld [\n", i)); for (j = 0; j < igraph_vector_size(&vtypes); j++) { char *name, *newname; igraph_strvector_get(&vnames, j, &name); IGRAPH_CHECK(igraph_i_dot_escape(name, &newname)); IGRAPH_FINALLY(igraph_free, newname); if (VECTOR(vtypes)[j] == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_i_attribute_get_numeric_vertex_attr(graph, name, igraph_vss_1((igraph_integer_t) i), &numv)); if (VECTOR(numv)[0] == (long)VECTOR(numv)[0]) { CHECK(fprintf(outstream, " %s=%ld\n", newname, (long)VECTOR(numv)[0])); } else { CHECK(fprintf(outstream, " %s=", newname)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(numv)[0])); CHECK(fputc('\n', outstream)); } } else if (VECTOR(vtypes)[j] == IGRAPH_ATTRIBUTE_STRING) { char *s, *news; IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr(graph, name, igraph_vss_1((igraph_integer_t) i), &strv)); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_dot_escape(s, &news)); CHECK(fprintf(outstream, " %s=%s\n", newname, news)); IGRAPH_FREE(news); } else if (VECTOR(vtypes)[j] == IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_CHECK(igraph_i_attribute_get_bool_vertex_attr(graph, name, igraph_vss_1((igraph_integer_t) i), &boolv)); CHECK(fprintf(outstream, " %s=%d\n", newname, VECTOR(boolv)[0] ? 1 : 0)); IGRAPH_WARNING("A boolean vertex attribute was converted to numeric"); } else { IGRAPH_WARNING("A non-numeric, non-string, non-boolean vertex attribute was ignored"); } IGRAPH_FREE(newname); IGRAPH_FINALLY_CLEAN(1); } CHECK(fprintf(outstream, " ];\n")); } } else { for (i = 0; i < no_of_nodes; i++) { CHECK(fprintf(outstream, " %ld;\n", i)); } } CHECK(fprintf(outstream, "\n")); /* Write the edges */ if (igraph_vector_size(&etypes) > 0) { for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); CHECK(fprintf(outstream, " %ld %s %ld [\n", from, edgeop, to)); for (j = 0; j < igraph_vector_size(&etypes); j++) { char *name, *newname; igraph_strvector_get(&enames, j, &name); IGRAPH_CHECK(igraph_i_dot_escape(name, &newname)); IGRAPH_FINALLY(igraph_free, newname); if (VECTOR(etypes)[j] == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) i), &numv)); if (VECTOR(numv)[0] == (long)VECTOR(numv)[0]) { CHECK(fprintf(outstream, " %s=%ld\n", newname, (long)VECTOR(numv)[0])); } else { CHECK(fprintf(outstream, " %s=", newname)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(numv)[0])); CHECK(fputc('\n', outstream)); } } else if (VECTOR(etypes)[j] == IGRAPH_ATTRIBUTE_STRING) { char *s, *news; IGRAPH_CHECK(igraph_i_attribute_get_string_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) i), &strv)); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_dot_escape(s, &news)); CHECK(fprintf(outstream, " %s=%s\n", newname, news)); IGRAPH_FREE(news); } else if (VECTOR(etypes)[j] == IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_CHECK(igraph_i_attribute_get_bool_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) i), &boolv)); CHECK(fprintf(outstream, " %s=%d\n", newname, VECTOR(boolv)[0] ? 1 : 0)); IGRAPH_WARNING("A boolean edge attribute was converted to numeric"); } else { IGRAPH_WARNING("A non-numeric, non-string graph attribute ignored"); } IGRAPH_FREE(newname); IGRAPH_FINALLY_CLEAN(1); } CHECK(fprintf(outstream, " ];\n")); } } else { for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); CHECK(fprintf(outstream, " %ld %s %ld;\n", from, edgeop, to)); } } CHECK(fprintf(outstream, "}\n")); igraph_vector_bool_destroy(&boolv); igraph_strvector_destroy(&strv); igraph_vector_destroy(&numv); igraph_vector_destroy(&etypes); igraph_vector_destroy(&vtypes); igraph_vector_destroy(>ypes); igraph_strvector_destroy(&enames); igraph_strvector_destroy(&vnames); igraph_strvector_destroy(&gnames); IGRAPH_FINALLY_CLEAN(9); return IGRAPH_SUCCESS; } #undef CHECK leidenbase/src/core/io/gml-lexer.l0000644000176200001440000000675114447675374016602 0ustar liggesusers/* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "io/gml-header.h" #include "io/parsers/gml-parser.h" #define YY_EXTRA_TYPE igraph_i_gml_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in GML parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif %} %option noyywrap %option prefix="igraph_gml_yy" %option nounput %option noinput %option nodefault %option reentrant %option bison-bridge %option bison-locations digit [0-9] whitespace [ \r\n\t] %% ^#[^\n\r]*[\n]|[\r] { /* comments ignored */ } \"[^\x00\"]*\" { return STRING; } \-?{digit}+(\.{digit}+)?([eE](\+|\-)?{digit}+)? { return NUM; } [a-zA-Z_][a-zA-Z_0-9]* { return KEYWORD; } \[ { yyextra->depth++; if (yyextra->depth >= 32) { return ERROR; } else { return LISTOPEN; } } \] { yyextra->depth--; if (yyextra->depth < 0) { return ERROR; } else { return LISTCLOSE; } } \n\r|\r\n|\r|\n { } {whitespace} { /* other whitespace ignored */ } <> { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; return EOFF; } } . { return ERROR; } %% leidenbase/src/core/io/gml.c.orig0000644000176200001440000007775414447675374016426 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_attributes.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_version.h" #include "core/trie.h" #include "graph/attributes.h" #include "io/gml-header.h" #include #include #include int igraph_gml_yylex_init_extra (igraph_i_gml_parsedata_t* user_defined, void* scanner); void igraph_gml_yylex_destroy (void *scanner ); int igraph_gml_yyparse (igraph_i_gml_parsedata_t* context); void igraph_gml_yyset_in (FILE * in_str, void* yyscanner ); static void igraph_i_gml_destroy_attrs(igraph_vector_ptr_t **ptr) { long int i; igraph_vector_ptr_t *vec; for (i = 0; i < 3; i++) { long int j; vec = ptr[i]; for (j = 0; j < igraph_vector_ptr_size(vec); j++) { igraph_attribute_record_t *atrec = VECTOR(*vec)[j]; if (atrec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *value = (igraph_vector_t*)atrec->value; if (value != 0) { igraph_vector_destroy(value); IGRAPH_FREE(value); } } else { igraph_strvector_t *value = (igraph_strvector_t*)atrec->value; if (value != 0) { igraph_strvector_destroy(value); IGRAPH_FREE(value); } } IGRAPH_FREE(atrec->name); IGRAPH_FREE(atrec); } igraph_vector_ptr_destroy(vec); } } static int igraph_i_gml_toreal(igraph_gml_tree_t *node, long int pos, igraph_real_t *result) { igraph_real_t value = 0.0; int type = igraph_gml_tree_type(node, pos); switch (type) { case IGRAPH_I_GML_TREE_INTEGER: value = igraph_gml_tree_get_integer(node, pos); break; case IGRAPH_I_GML_TREE_REAL: value = igraph_gml_tree_get_real(node, pos); break; default: IGRAPH_ERROR("Internal error while parsing GML file.", IGRAPH_FAILURE); break; } *result = value; return IGRAPH_SUCCESS; } static const char *igraph_i_gml_tostring(igraph_gml_tree_t *node, long int pos) { int type = igraph_gml_tree_type(node, pos); static char tmp[256]; const char *p = tmp; long int i; igraph_real_t d; switch (type) { case IGRAPH_I_GML_TREE_INTEGER: i = igraph_gml_tree_get_integer(node, pos); snprintf(tmp, sizeof(tmp) / sizeof(char), "%li", i); break; case IGRAPH_I_GML_TREE_REAL: d = igraph_gml_tree_get_real(node, pos); igraph_real_snprintf_precise(tmp, sizeof(tmp) / sizeof(char), d); break; case IGRAPH_I_GML_TREE_STRING: p = igraph_gml_tree_get_string(node, pos); break; default: break; } return p; } int igraph_i_gml_parsedata_init(igraph_i_gml_parsedata_t* context) { context->eof = 0; context->depth = 0; context->scanner = 0; context->tree = 0; context->errmsg[0] = 0; return IGRAPH_SUCCESS; } void igraph_i_gml_parsedata_destroy(igraph_i_gml_parsedata_t* context) { if (context->tree != 0) { igraph_gml_tree_destroy(context->tree); context->tree = 0; } if (context->scanner != 0) { igraph_gml_yylex_destroy(context->scanner); context->scanner = 0; } } /** * \function igraph_read_graph_gml * \brief Read a graph in GML format. * * GML is a simple textual format, see * http://www.fim.uni-passau.de/en/fim/faculty/chairs/theoretische-informatik/projects.html for details. * * * Although all syntactically correct GML can be parsed, * we implement only a subset of this format, some attributes might be * ignored. Here is a list of all the differences: * \olist * \oli Only node and edge attributes are * used, and only if they have a simple type: integer, real or * string. So if an attribute is an array or a record, then it is * ignored. This is also true if only some values of the * attribute are complex. * \oli Top level attributes except for Version and the * first graph attribute are completely ignored. * \oli Graph attributes except for node and * edge are completely ignored. * \oli There is no maximum line length. * \oli There is no maximum keyword length. * \oli Character entities in strings are not interpreted. * \oli We allow inf (infinity) and nan * (not a number) as a real number. This is case insensitive, so * nan, NaN and NAN are equal. * \endolist * * Please contact us if you cannot live with these * limitations of the GML parser. * \param graph Pointer to an uninitialized graph object. * \param instream The stream to read the GML file from. * \return Error code. * * Time complexity: should be proportional to the length of the file. * * \sa \ref igraph_read_graph_graphml() for a more modern format, * \ref igraph_write_graph_gml() for writing GML files. * * \example examples/simple/gml.c */ int igraph_read_graph_gml(igraph_t *graph, FILE *instream) { long int i, p; long int no_of_nodes = 0, no_of_edges = 0; igraph_trie_t trie; igraph_vector_t edges; igraph_bool_t directed = IGRAPH_UNDIRECTED; igraph_gml_tree_t *gtree; long int gidx; igraph_trie_t vattrnames; igraph_trie_t eattrnames; igraph_trie_t gattrnames; igraph_vector_ptr_t gattrs = IGRAPH_VECTOR_PTR_NULL, vattrs = IGRAPH_VECTOR_PTR_NULL, eattrs = IGRAPH_VECTOR_PTR_NULL; igraph_vector_ptr_t *attrs[3]; long int edgeptr = 0; igraph_i_gml_parsedata_t context; attrs[0] = &gattrs; attrs[1] = &vattrs; attrs[2] = &eattrs; IGRAPH_CHECK(igraph_i_gml_parsedata_init(&context)); IGRAPH_FINALLY(igraph_i_gml_parsedata_destroy, &context); igraph_gml_yylex_init_extra(&context, &context.scanner); igraph_gml_yyset_in(instream, context.scanner); i = igraph_gml_yyparse(&context); if (i != 0) { if (context.errmsg[0] != 0) { IGRAPH_ERROR(context.errmsg, IGRAPH_PARSEERROR); } else { IGRAPH_ERROR("Cannot read GML file.", IGRAPH_PARSEERROR); } } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); /* Check version, if present, integer and not '1' then ignored */ i = igraph_gml_tree_find(context.tree, "Version", 0); if (i >= 0 && igraph_gml_tree_type(context.tree, i) == IGRAPH_I_GML_TREE_INTEGER && igraph_gml_tree_get_integer(context.tree, i) != 1) { IGRAPH_ERROR("Unknown GML version.", IGRAPH_UNIMPLEMENTED); /* RETURN HERE!!!! */ } /* get the graph */ gidx = igraph_gml_tree_find(context.tree, "graph", 0); if (gidx == -1) { IGRAPH_ERROR("No 'graph' object in GML file.", IGRAPH_PARSEERROR); } if (igraph_gml_tree_type(context.tree, gidx) != IGRAPH_I_GML_TREE_TREE) { IGRAPH_ERROR("Invalid type for 'graph' object in GML file.", IGRAPH_PARSEERROR); } gtree = igraph_gml_tree_get_tree(context.tree, gidx); IGRAPH_FINALLY(igraph_i_gml_destroy_attrs, attrs); igraph_vector_ptr_init(&gattrs, 0); igraph_vector_ptr_init(&vattrs, 0); igraph_vector_ptr_init(&eattrs, 0); IGRAPH_TRIE_INIT_FINALLY(&trie, 0); IGRAPH_TRIE_INIT_FINALLY(&vattrnames, 0); IGRAPH_TRIE_INIT_FINALLY(&eattrnames, 0); IGRAPH_TRIE_INIT_FINALLY(&gattrnames, 0); /* Is is directed? */ i = igraph_gml_tree_find(gtree, "directed", 0); if (i >= 0 && igraph_gml_tree_type(gtree, i) == IGRAPH_I_GML_TREE_INTEGER) { if (igraph_gml_tree_get_integer(gtree, i) == 1) { directed = IGRAPH_DIRECTED; } } /* Now we go over all objects in the graph and collect the attribute names and types. Plus we collect node ids. We also do some checks. */ for (i = 0; i < igraph_gml_tree_length(gtree); i++) { long int j; char cname[100]; const char *name = igraph_gml_tree_name(gtree, i); if (!strcmp(name, "node")) { igraph_gml_tree_t *node; igraph_bool_t hasid; no_of_nodes++; if (igraph_gml_tree_type(gtree, i) != IGRAPH_I_GML_TREE_TREE) { IGRAPH_ERROR("'node' is not a list in GML file.", IGRAPH_PARSEERROR); } node = igraph_gml_tree_get_tree(gtree, i); hasid = 0; for (j = 0; j < igraph_gml_tree_length(node); j++) { const char *name = igraph_gml_tree_name(node, j); long int trieid, triesize = igraph_trie_size(&vattrnames); IGRAPH_CHECK(igraph_trie_get(&vattrnames, name, &trieid)); if (trieid == triesize) { /* new attribute */ igraph_attribute_record_t *atrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); int type = igraph_gml_tree_type(node, j); if (!atrec) { IGRAPH_ERROR("Cannot read GML file.", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_ptr_push_back(&vattrs, atrec)); atrec->name = strdup(name); if (type == IGRAPH_I_GML_TREE_INTEGER || type == IGRAPH_I_GML_TREE_REAL) { atrec->type = IGRAPH_ATTRIBUTE_NUMERIC; } else { atrec->type = IGRAPH_ATTRIBUTE_STRING; } } else { /* already seen, should we update type? */ igraph_attribute_record_t *atrec = VECTOR(vattrs)[trieid]; int type1 = atrec->type; int type2 = igraph_gml_tree_type(node, j); if (type1 == IGRAPH_ATTRIBUTE_NUMERIC && type2 == IGRAPH_I_GML_TREE_STRING) { atrec->type = IGRAPH_ATTRIBUTE_STRING; } } /* check id */ if (!hasid && !strcmp(name, "id")) { long int id; if (igraph_gml_tree_type(node, j) != IGRAPH_I_GML_TREE_INTEGER) { IGRAPH_ERROR("Non-integer node id in GML file.", IGRAPH_PARSEERROR); } id = igraph_gml_tree_get_integer(node, j); snprintf(cname, sizeof(cname) / sizeof(char) -1, "%li", id); IGRAPH_CHECK(igraph_trie_get(&trie, cname, &id)); hasid = 1; } } if (!hasid) { IGRAPH_ERROR("Node without 'id' while parsing GML file.", IGRAPH_PARSEERROR); } } else if (!strcmp(name, "edge")) { igraph_gml_tree_t *edge; igraph_bool_t has_source = 0, has_target = 0; no_of_edges++; if (igraph_gml_tree_type(gtree, i) != IGRAPH_I_GML_TREE_TREE) { IGRAPH_ERROR("'edge' is not a list in GML file.", IGRAPH_PARSEERROR); } edge = igraph_gml_tree_get_tree(gtree, i); has_source = has_target = 0; for (j = 0; j < igraph_gml_tree_length(edge); j++) { const char *name = igraph_gml_tree_name(edge, j); if (!strcmp(name, "source")) { has_source = 1; if (igraph_gml_tree_type(edge, j) != IGRAPH_I_GML_TREE_INTEGER) { IGRAPH_ERROR("Non-integer 'source' for an edge in GML file.", IGRAPH_PARSEERROR); } } else if (!strcmp(name, "target")) { has_target = 1; if (igraph_gml_tree_type(edge, j) != IGRAPH_I_GML_TREE_INTEGER) { IGRAPH_ERROR("Non-integer 'source' for an edge in GML file.", IGRAPH_PARSEERROR); } } else { long int trieid, triesize = igraph_trie_size(&eattrnames); IGRAPH_CHECK(igraph_trie_get(&eattrnames, name, &trieid)); if (trieid == triesize) { /* new attribute */ igraph_attribute_record_t *atrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); int type = igraph_gml_tree_type(edge, j); if (!atrec) { IGRAPH_ERROR("Cannot read GML file.", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_ptr_push_back(&eattrs, atrec)); atrec->name = strdup(name); if (type == IGRAPH_I_GML_TREE_INTEGER || type == IGRAPH_I_GML_TREE_REAL) { atrec->type = IGRAPH_ATTRIBUTE_NUMERIC; } else { atrec->type = IGRAPH_ATTRIBUTE_STRING; } } else { /* already seen, should we update type? */ igraph_attribute_record_t *atrec = VECTOR(eattrs)[trieid]; int type1 = atrec->type; int type2 = igraph_gml_tree_type(edge, j); if (type1 == IGRAPH_ATTRIBUTE_NUMERIC && type2 == IGRAPH_I_GML_TREE_STRING) { atrec->type = IGRAPH_ATTRIBUTE_STRING; } } } } /* for */ if (!has_source) { IGRAPH_ERROR("No 'source' for edge in GML file.", IGRAPH_PARSEERROR); } if (!has_target) { IGRAPH_ERROR("No 'target' for edge in GML file.", IGRAPH_PARSEERROR); } } else { /* anything to do? Maybe add as graph attribute.... */ } } /* check vertex id uniqueness */ if (igraph_trie_size(&trie) != no_of_nodes) { IGRAPH_ERROR("Node 'id' not unique in GML file.", IGRAPH_PARSEERROR); } /* now we allocate the vectors and strvectors for the attributes */ for (i = 0; i < igraph_vector_ptr_size(&vattrs); i++) { igraph_attribute_record_t *atrec = VECTOR(vattrs)[i]; int type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *p = IGRAPH_CALLOC(1, igraph_vector_t); atrec->value = p; IGRAPH_CHECK(igraph_vector_init(p, no_of_nodes)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *p = IGRAPH_CALLOC(1, igraph_strvector_t); atrec->value = p; IGRAPH_CHECK(igraph_strvector_init(p, no_of_nodes)); } else { IGRAPH_WARNING("A composite attribute was ignored in the GML file."); } } for (i = 0; i < igraph_vector_ptr_size(&eattrs); i++) { igraph_attribute_record_t *atrec = VECTOR(eattrs)[i]; int type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *p = IGRAPH_CALLOC(1, igraph_vector_t); atrec->value = p; IGRAPH_CHECK(igraph_vector_init(p, no_of_edges)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *p = IGRAPH_CALLOC(1, igraph_strvector_t); atrec->value = p; IGRAPH_CHECK(igraph_strvector_init(p, no_of_edges)); } else { IGRAPH_WARNING("A composite attribute was ignored in the GML file."); } } /* Ok, now the edges, attributes too */ IGRAPH_CHECK(igraph_vector_resize(&edges, no_of_edges * 2)); p = -1; while ( (p = igraph_gml_tree_find(gtree, "edge", p + 1)) != -1) { igraph_gml_tree_t *edge; long int from, to, fromidx = 0, toidx = 0; char name[100]; long int j; edge = igraph_gml_tree_get_tree(gtree, p); for (j = 0; j < igraph_gml_tree_length(edge); j++) { const char *n = igraph_gml_tree_name(edge, j); if (!strcmp(n, "source")) { fromidx = igraph_gml_tree_find(edge, "source", 0); } else if (!strcmp(n, "target")) { toidx = igraph_gml_tree_find(edge, "target", 0); } else { long int edgeid = edgeptr / 2; long int trieidx; igraph_attribute_record_t *atrec; int type; igraph_trie_get(&eattrnames, n, &trieidx); atrec = VECTOR(eattrs)[trieidx]; type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *v = (igraph_vector_t *)atrec->value; IGRAPH_CHECK(igraph_i_gml_toreal(edge, j, VECTOR(*v) + edgeid)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *v = (igraph_strvector_t *)atrec->value; const char *value = igraph_i_gml_tostring(edge, j); IGRAPH_CHECK(igraph_strvector_set(v, edgeid, value)); } } } from = igraph_gml_tree_get_integer(edge, fromidx); to = igraph_gml_tree_get_integer(edge, toidx); snprintf(name, sizeof(name) / sizeof(char) -1, "%li", from); IGRAPH_CHECK(igraph_trie_get(&trie, name, &from)); snprintf(name, sizeof(name) / sizeof(char) -1, "%li", to); IGRAPH_CHECK(igraph_trie_get(&trie, name, &to)); if (igraph_trie_size(&trie) != no_of_nodes) { IGRAPH_ERROR("Unknown node id found in an edge in GML file.", IGRAPH_PARSEERROR); } VECTOR(edges)[edgeptr++] = from; VECTOR(edges)[edgeptr++] = to; } /* and add vertex attributes */ for (i = 0; i < igraph_gml_tree_length(gtree); i++) { const char *n; char name[100]; long int j, k; n = igraph_gml_tree_name(gtree, i); if (!strcmp(n, "node")) { igraph_gml_tree_t *node = igraph_gml_tree_get_tree(gtree, i); long int iidx = igraph_gml_tree_find(node, "id", 0); long int id = igraph_gml_tree_get_integer(node, iidx); snprintf(name, sizeof(name) / sizeof(char) -1, "%li", id); igraph_trie_get(&trie, name, &id); for (j = 0; j < igraph_gml_tree_length(node); j++) { const char *aname = igraph_gml_tree_name(node, j); igraph_attribute_record_t *atrec; int type; igraph_trie_get(&vattrnames, aname, &k); atrec = VECTOR(vattrs)[k]; type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *v = (igraph_vector_t *)atrec->value; IGRAPH_CHECK(igraph_i_gml_toreal(node, j, VECTOR(*v) + id)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *v = (igraph_strvector_t *)atrec->value; const char *value = igraph_i_gml_tostring(node, j); IGRAPH_CHECK(igraph_strvector_set(v, id, value)); } } } } igraph_trie_destroy(&trie); igraph_trie_destroy(&gattrnames); igraph_trie_destroy(&vattrnames); igraph_trie_destroy(&eattrnames); IGRAPH_FINALLY_CLEAN(4); IGRAPH_CHECK(igraph_empty_attrs(graph, 0, directed, 0)); /* TODO */ IGRAPH_CHECK(igraph_add_vertices(graph, (igraph_integer_t) no_of_nodes, &vattrs)); IGRAPH_CHECK(igraph_add_edges(graph, &edges, &eattrs)); igraph_i_gml_destroy_attrs(attrs); igraph_vector_destroy(&edges); igraph_i_gml_parsedata_destroy(&context); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } static int igraph_i_gml_convert_to_key(const char *orig, char **key) { int no = 1; char strno[50]; size_t i, len = strlen(orig), newlen = 0, plen = 0; /* do we need a prefix? */ if (len == 0 || !isalpha(orig[0])) { no++; snprintf(strno, sizeof(strno) - 1, "igraph"); plen = newlen = strlen(strno); } for (i = 0; i < len; i++) { if (isalnum(orig[i])) { newlen++; } } *key = IGRAPH_CALLOC(newlen + 1, char); if (! *key) { IGRAPH_ERROR("Writing GML format failed.", IGRAPH_ENOMEM); } memcpy(*key, strno, plen * sizeof(char)); for (i = 0; i < len; i++) { if (isalnum(orig[i])) { (*key)[plen++] = orig[i]; } } (*key)[newlen] = '\0'; return IGRAPH_SUCCESS; } #define CHECK(cmd) do { ret=cmd; if (ret<0) IGRAPH_ERROR("Writing GML format failed.", IGRAPH_EFILE); } while (0) /** * \function igraph_write_graph_gml * \brief Write the graph to a stream in GML format * * GML is a quite general textual format, see * http://www.fim.uni-passau.de/en/fim/faculty/chairs/theoretische-informatik/projects.html for details. * * The graph, vertex and edges attributes are written to the * file as well, if they are numeric or string. * * As igraph is more forgiving about attribute names, it might * be necessary to simplify the them before writing to the GML file. * This way we'll have a syntactically correct GML file. The following * simple procedure is performed on each attribute name: first the alphanumeric * characters are extracted, the others are ignored. Then if the first character * is not a letter then the attribute name is prefixed with igraph. * Note that this might result identical names for two attributes, igraph * does not check this. * * The id vertex attribute is treated specially. * If the id argument is not 0 then it should be a numeric * vector with the vertex ids and the id vertex attribute is * ignored (if there is one). If id is 0 and there is a * numeric id vertex attribute that is used instead. If ids * are not specified in either way then the regular igraph vertex ids are used. * * Note that whichever way vertex ids are specified, their * uniqueness is not checked. * * If the graph has edge attributes named source * or target they're silently ignored. GML uses these attributes * to specify the edges, so we cannot write them to the file. Rename them * before calling this function if you want to preserve them. * \param graph The graph to write to the stream. * \param outstream The stream to write the file to. * \param id Either NULL or a numeric vector with the vertex ids. * See details above. * \param creator An optional string to write to the stream in the creator line. * If this is 0 then the current date and time is added. * \return Error code. * * Time complexity: should be proportional to the number of characters written * to the file. * * \sa \ref igraph_read_graph_gml() for reading GML files, * \ref igraph_read_graph_graphml() for a more modern format. * * \example examples/simple/gml.c */ int igraph_write_graph_gml(const igraph_t *graph, FILE *outstream, const igraph_vector_t *id, const char *creator) { int ret; igraph_strvector_t gnames, vnames, enames; igraph_vector_t gtypes, vtypes, etypes; igraph_vector_t numv; igraph_strvector_t strv; igraph_vector_bool_t boolv; long int i; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vector_t v_myid; const igraph_vector_t *myid = id; time_t curtime = time(0); char *timestr = ctime(&curtime); timestr[strlen(timestr) - 1] = '\0'; /* nicely remove \n */ CHECK(fprintf(outstream, "Creator \"igraph version %s %s\"\nVersion 1\ngraph\n[\n", IGRAPH_VERSION, creator ? creator : timestr)); IGRAPH_STRVECTOR_INIT_FINALLY(&gnames, 0); IGRAPH_STRVECTOR_INIT_FINALLY(&vnames, 0); IGRAPH_STRVECTOR_INIT_FINALLY(&enames, 0); IGRAPH_VECTOR_INIT_FINALLY(>ypes, 0); IGRAPH_VECTOR_INIT_FINALLY(&vtypes, 0); IGRAPH_VECTOR_INIT_FINALLY(&etypes, 0); IGRAPH_CHECK(igraph_i_attribute_get_info(graph, &gnames, >ypes, &vnames, &vtypes, &enames, &etypes)); IGRAPH_VECTOR_INIT_FINALLY(&numv, 1); IGRAPH_STRVECTOR_INIT_FINALLY(&strv, 1); IGRAPH_VECTOR_BOOL_INIT_FINALLY(&boolv, 1); /* Check whether there is an 'id' node attribute if the supplied is 0 */ if (!id) { igraph_bool_t found = 0; for (i = 0; i < igraph_vector_size(&vtypes); i++) { char *n; igraph_strvector_get(&vnames, i, &n); if (!strcmp(n, "id") && VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { found = 1; break; } } if (found) { IGRAPH_VECTOR_INIT_FINALLY(&v_myid, no_of_nodes); IGRAPH_CHECK(igraph_i_attribute_get_numeric_vertex_attr(graph, "id", igraph_vss_all(), &v_myid)); myid = &v_myid; } } /* directedness */ CHECK(fprintf(outstream, " directed %i\n", igraph_is_directed(graph) ? 1 : 0)); /* Graph attributes first */ for (i = 0; i < igraph_vector_size(>ypes); i++) { char *name, *newname; igraph_strvector_get(&gnames, i, &name); IGRAPH_CHECK(igraph_i_gml_convert_to_key(name, &newname)); IGRAPH_FINALLY(igraph_free, newname); if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_i_attribute_get_numeric_graph_attr(graph, name, &numv)); CHECK(fprintf(outstream, " %s ", newname)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(numv)[0])); CHECK(fputc('\n', outstream)); } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_STRING) { char *s; IGRAPH_CHECK(igraph_i_attribute_get_string_graph_attr(graph, name, &strv)); igraph_strvector_get(&strv, 0, &s); CHECK(fprintf(outstream, " %s \"%s\"\n", newname, s)); } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_CHECK(igraph_i_attribute_get_bool_graph_attr(graph, name, &boolv)); CHECK(fprintf(outstream, " %s %d\n", newname, VECTOR(boolv)[0] ? 1 : 0)); IGRAPH_WARNING("A boolean graph attribute was converted to numeric"); } else { IGRAPH_WARNING("A non-numeric, non-string, non-boolean graph attribute ignored"); } IGRAPH_FREE(newname); IGRAPH_FINALLY_CLEAN(1); } /* Now come the vertices */ for (i = 0; i < no_of_nodes; i++) { long int j; CHECK(fprintf(outstream, " node\n [\n")); /* id */ CHECK(fprintf(outstream, " id %li\n", myid ? (long int)VECTOR(*myid)[i] : i)); /* other attributes */ for (j = 0; j < igraph_vector_size(&vtypes); j++) { int type = (int) VECTOR(vtypes)[j]; char *name, *newname; igraph_strvector_get(&vnames, j, &name); if (!strcmp(name, "id")) { continue; } IGRAPH_CHECK(igraph_i_gml_convert_to_key(name, &newname)); IGRAPH_FINALLY(igraph_free, newname); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_i_attribute_get_numeric_vertex_attr(graph, name, igraph_vss_1((igraph_integer_t) i), &numv)); CHECK(fprintf(outstream, " %s ", newname)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(numv)[0])); CHECK(fputc('\n', outstream)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { char *s; IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr(graph, name, igraph_vss_1((igraph_integer_t) i), &strv)); igraph_strvector_get(&strv, 0, &s); CHECK(fprintf(outstream, " %s \"%s\"\n", newname, s)); } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_CHECK(igraph_i_attribute_get_bool_vertex_attr(graph, name, igraph_vss_1((igraph_integer_t) i), &boolv)); CHECK(fprintf(outstream, " %s %d\n", newname, VECTOR(boolv)[0] ? 1 : 0)); IGRAPH_WARNING("A boolean vertex attribute was converted to numeric"); } else { IGRAPH_WARNING("A non-numeric, non-string, non-boolean edge attribute was ignored"); } IGRAPH_FREE(newname); IGRAPH_FINALLY_CLEAN(1); } CHECK(fprintf(outstream, " ]\n")); } /* The edges too */ for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); long int j; CHECK(fprintf(outstream, " edge\n [\n")); /* source and target */ CHECK(fprintf(outstream, " source %li\n", myid ? (long int)VECTOR(*myid)[from] : from)); CHECK(fprintf(outstream, " target %li\n", myid ? (long int)VECTOR(*myid)[to] : to)); /* other attributes */ for (j = 0; j < igraph_vector_size(&etypes); j++) { int type = (int) VECTOR(etypes)[j]; char *name, *newname; igraph_strvector_get(&enames, j, &name); if (!strcmp(name, "source") || !strcmp(name, "target")) { continue; } IGRAPH_CHECK(igraph_i_gml_convert_to_key(name, &newname)); IGRAPH_FINALLY(igraph_free, newname); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) i), &numv)); CHECK(fprintf(outstream, " %s ", newname)); CHECK(igraph_real_fprintf_precise(outstream, VECTOR(numv)[0])); CHECK(fputc('\n', outstream)); } else if (type == IGRAPH_ATTRIBUTE_STRING) { char *s; IGRAPH_CHECK(igraph_i_attribute_get_string_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) i), &strv)); igraph_strvector_get(&strv, 0, &s); CHECK(fprintf(outstream, " %s \"%s\"\n", newname, s)); } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_CHECK(igraph_i_attribute_get_bool_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) i), &boolv)); CHECK(fprintf(outstream, " %s %d\n", newname, VECTOR(boolv)[0] ? 1 : 0)); IGRAPH_WARNING("A boolean edge attribute was converted to numeric"); } else { IGRAPH_WARNING("A non-numeric, non-string, non-boolean edge attribute was ignored"); } IGRAPH_FREE(newname); IGRAPH_FINALLY_CLEAN(1); } CHECK(fprintf(outstream, " ]\n")); } CHECK(fprintf(outstream, "]\n")); if (&v_myid == myid) { igraph_vector_destroy(&v_myid); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_bool_destroy(&boolv); igraph_strvector_destroy(&strv); igraph_vector_destroy(&numv); igraph_vector_destroy(&etypes); igraph_vector_destroy(&vtypes); igraph_vector_destroy(>ypes); igraph_strvector_destroy(&enames); igraph_strvector_destroy(&vnames); igraph_strvector_destroy(&gnames); IGRAPH_FINALLY_CLEAN(9); return IGRAPH_SUCCESS; } #undef CHECK leidenbase/src/core/io/pajek-lexer.c0000644000176200001440000023635214447675375017107 0ustar liggesusers#line 2 "src/core/io/pajek-lexer.c" #line 4 "src/core/io/pajek-lexer.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_pajek_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_pajek_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_pajek_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_pajek_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_pajek_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_pajek_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_pajek_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_pajek_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_pajek_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_pajek_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_pajek_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_pajek_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_pajek_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_pajek_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_pajek_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_pajek_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_pajek_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_pajek_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_pajek_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_pajek_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_pajek_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_pajek_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_pajek_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_pajek_yyensure_buffer_stack #endif #ifdef yylex #define igraph_pajek_yylex_ALREADY_DEFINED #else #define yylex igraph_pajek_yylex #endif #ifdef yyrestart #define igraph_pajek_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_pajek_yyrestart #endif #ifdef yylex_init #define igraph_pajek_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_pajek_yylex_init #endif #ifdef yylex_init_extra #define igraph_pajek_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_pajek_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_pajek_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_pajek_yylex_destroy #endif #ifdef yyget_debug #define igraph_pajek_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_pajek_yyget_debug #endif #ifdef yyset_debug #define igraph_pajek_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_pajek_yyset_debug #endif #ifdef yyget_extra #define igraph_pajek_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_pajek_yyget_extra #endif #ifdef yyset_extra #define igraph_pajek_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_pajek_yyset_extra #endif #ifdef yyget_in #define igraph_pajek_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_pajek_yyget_in #endif #ifdef yyset_in #define igraph_pajek_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_pajek_yyset_in #endif #ifdef yyget_out #define igraph_pajek_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_pajek_yyget_out #endif #ifdef yyset_out #define igraph_pajek_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_pajek_yyset_out #endif #ifdef yyget_leng #define igraph_pajek_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_pajek_yyget_leng #endif #ifdef yyget_text #define igraph_pajek_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_pajek_yyget_text #endif #ifdef yyget_lineno #define igraph_pajek_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_pajek_yyget_lineno #endif #ifdef yyset_lineno #define igraph_pajek_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_pajek_yyset_lineno #endif #ifdef yyget_column #define igraph_pajek_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_pajek_yyget_column #endif #ifdef yyset_column #define igraph_pajek_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_pajek_yyset_column #endif #ifdef yywrap #define igraph_pajek_yywrap_ALREADY_DEFINED #else #define yywrap igraph_pajek_yywrap #endif #ifdef yyget_lval #define igraph_pajek_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_pajek_yyget_lval #endif #ifdef yyset_lval #define igraph_pajek_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_pajek_yyset_lval #endif #ifdef yyget_lloc #define igraph_pajek_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_pajek_yyget_lloc #endif #ifdef yyset_lloc #define igraph_pajek_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_pajek_yyset_lloc #endif #ifdef yyalloc #define igraph_pajek_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_pajek_yyalloc #endif #ifdef yyrealloc #define igraph_pajek_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_pajek_yyrealloc #endif #ifdef yyfree #define igraph_pajek_yyfree_ALREADY_DEFINED #else #define yyfree igraph_pajek_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); static void yyensure_buffer_stack ( yyscan_t yyscanner ); static void yy_load_buffer_state ( yyscan_t yyscanner ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define igraph_pajek_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); static int yy_get_next_buffer ( yyscan_t yyscanner ); static void __attribute__((unused)) yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 48 #define YY_END_OF_BUFFER 49 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[161] = { 0, 0, 0, 49, 46, 1, 12, 12, 46, 46, 46, 46, 46, 15, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 46, 1, 12, 46, 0, 13, 46, 0, 2, 3, 46, 0, 14, 46, 46, 46, 46, 46, 15, 46, 46, 29, 46, 46, 46, 46, 46, 26, 46, 46, 46, 46, 46, 46, 38, 46, 46, 46, 46, 27, 46, 23, 22, 28, 46, 46, 30, 46, 46, 13, 2, 2, 14, 46, 46, 46, 46, 46, 15, 46, 15, 33, 34, 37, 19, 20, 46, 46, 31, 32, 18, 35, 36, 43, 41, 39, 46, 42, 46, 46, 46, 46, 46, 3, 46, 46, 46, 4, 46, 46, 45, 46, 21, 46, 25, 46, 46, 7, 46, 46, 46, 46, 24, 40, 44, 46, 46, 46, 8, 46, 46, 46, 46, 46, 46, 46, 11, 46, 46, 16, 17, 46, 46, 5, 46, 9, 46, 6, 10, 0 } ; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 1, 1, 6, 1, 1, 7, 8, 9, 10, 1, 11, 12, 1, 13, 14, 15, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 19, 20, 21, 22, 23, 24, 1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 1, 1, 1, 1, 41, 1, 16, 17, 18, 19, 20, 21, 22, 23, 24, 1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static const YY_CHAR yy_meta[43] = { 0, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 } ; static const flex_int16_t yy_base[168] = { 0, 0, 0, 295, 0, 292, 289, 289, 41, 45, 48, 37, 45, 54, 74, 43, 68, 262, 40, 272, 48, 103, 89, 82, 92, 96, 257, 99, 247, 246, 296, 0, 284, 296, 106, 280, 0, 111, 78, 280, 113, 120, 275, 0, 250, 262, 264, 259, 258, 117, 112, 128, 296, 142, 147, 152, 155, 161, 296, 119, 164, 167, 170, 173, 176, 296, 179, 182, 185, 188, 296, 253, 296, 296, 296, 236, 249, 296, 253, 252, 296, 268, 157, 296, 253, 248, 235, 234, 235, 180, 183, 188, 296, 296, 296, 296, 296, 232, 202, 296, 296, 296, 296, 296, 296, 296, 296, 241, 296, 207, 244, 210, 247, 246, 258, 227, 239, 226, 220, 222, 213, 296, 216, 296, 219, 296, 237, 236, 227, 219, 227, 221, 225, 296, 296, 296, 214, 213, 222, 219, 206, 211, 224, 222, 225, 174, 175, 0, 115, 116, 296, 296, 100, 85, 0, 64, 0, 45, 0, 0, 296, 74, 229, 231, 233, 235, 237, 239 } ; static const flex_int16_t yy_def[168] = { 0, 160, 1, 160, 161, 160, 160, 160, 162, 163, 164, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 161, 160, 160, 162, 165, 161, 163, 166, 160, 166, 164, 167, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 161, 161, 161, 161, 161, 160, 161, 161, 161, 161, 161, 161, 160, 161, 161, 161, 161, 160, 161, 160, 160, 160, 161, 161, 160, 161, 161, 160, 160, 160, 160, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 161, 160, 161, 161, 161, 161, 161, 160, 161, 161, 161, 161, 161, 161, 160, 161, 160, 161, 160, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 161, 161, 161, 161, 161, 161, 161, 161, 0, 160, 160, 160, 160, 160, 160, 160 } ; static const flex_int16_t yy_nxt[339] = { 0, 4, 5, 6, 7, 8, 9, 10, 4, 11, 4, 12, 4, 13, 13, 13, 14, 15, 16, 4, 4, 17, 4, 18, 19, 20, 21, 4, 4, 4, 22, 23, 24, 25, 4, 26, 4, 27, 28, 29, 4, 4, 30, 35, 35, 35, 36, 38, 39, 40, 42, 42, 42, 44, 60, 61, 43, 45, 49, 49, 49, 56, 63, 64, 46, 47, 50, 49, 49, 49, 58, 58, 58, 48, 51, 31, 52, 52, 52, 159, 57, 39, 40, 35, 72, 72, 72, 38, 53, 54, 42, 70, 70, 70, 73, 73, 73, 158, 74, 74, 74, 77, 77, 77, 55, 65, 65, 65, 35, 35, 35, 36, 71, 38, 39, 40, 82, 40, 157, 66, 75, 67, 42, 42, 42, 89, 89, 89, 43, 50, 49, 49, 49, 68, 156, 69, 155, 51, 90, 90, 154, 91, 91, 91, 92, 92, 92, 97, 35, 93, 93, 93, 98, 38, 94, 94, 94, 95, 95, 95, 114, 81, 42, 96, 96, 96, 99, 99, 99, 100, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 106, 108, 108, 108, 89, 89, 89, 91, 91, 91, 153, 51, 91, 91, 91, 121, 121, 121, 152, 107, 123, 123, 123, 125, 125, 125, 133, 133, 133, 134, 134, 134, 135, 135, 135, 150, 150, 150, 151, 151, 151, 34, 34, 37, 37, 41, 41, 35, 35, 38, 38, 42, 42, 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, 132, 131, 130, 129, 128, 114, 127, 126, 124, 122, 120, 119, 118, 117, 116, 115, 81, 113, 112, 111, 110, 109, 88, 87, 86, 85, 84, 83, 81, 80, 32, 79, 78, 76, 62, 59, 33, 33, 32, 160, 3, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160 } ; static const flex_int16_t yy_chk[339] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 18, 18, 10, 11, 12, 12, 12, 15, 20, 20, 11, 11, 13, 13, 13, 13, 16, 16, 16, 11, 13, 161, 14, 14, 14, 157, 15, 38, 38, 8, 23, 23, 23, 9, 14, 14, 10, 22, 22, 22, 24, 24, 24, 155, 25, 25, 25, 27, 27, 27, 14, 21, 21, 21, 34, 34, 34, 34, 22, 37, 37, 37, 40, 40, 153, 21, 25, 21, 41, 41, 41, 50, 50, 50, 41, 49, 49, 49, 49, 21, 152, 21, 149, 49, 51, 51, 148, 51, 51, 51, 53, 53, 53, 59, 34, 54, 54, 54, 59, 37, 55, 55, 55, 56, 56, 56, 82, 82, 41, 57, 57, 57, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 89, 89, 89, 90, 90, 90, 146, 89, 91, 91, 91, 98, 98, 98, 145, 68, 109, 109, 109, 111, 111, 111, 120, 120, 120, 122, 122, 122, 124, 124, 124, 143, 143, 143, 144, 144, 144, 162, 162, 163, 163, 164, 164, 165, 165, 166, 166, 167, 167, 142, 141, 140, 139, 138, 137, 136, 132, 131, 130, 129, 128, 127, 126, 119, 118, 117, 116, 115, 114, 113, 112, 110, 107, 97, 88, 87, 86, 85, 84, 81, 79, 78, 76, 75, 71, 48, 47, 46, 45, 44, 42, 39, 35, 32, 29, 28, 26, 19, 17, 7, 6, 5, 3, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "src/core/io/pajek-lexer.l" /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #line 24 "src/core/io/pajek-lexer.l" /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "io/pajek-header.h" #include "io/pajek-parser.h" #define YY_EXTRA_TYPE igraph_i_pajek_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in Pajek parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif #line 843 "src/core/io/pajek-lexer.c" #define YY_NO_INPUT 1 #line 845 "src/core/io/pajek-lexer.c" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; YYSTYPE * yylval_r; YYLTYPE * yylloc_r; }; /* end struct yyguts_t */ static int yy_init_globals ( yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r # define yylloc yyg->yylloc_r int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef YY_NO_UNPUT #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( yyscan_t yyscanner ); #else static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; yylloc = yylloc_param; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_load_buffer_state( yyscanner ); } { #line 77 "src/core/io/pajek-lexer.l" #line 1130 "src/core/io/pajek-lexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 161 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 296 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 79 "src/core/io/pajek-lexer.l" { } YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP #line 80 "src/core/io/pajek-lexer.l" { } YY_BREAK case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 81 "src/core/io/pajek-lexer.l" { } YY_BREAK case 4: YY_RULE_SETUP #line 82 "src/core/io/pajek-lexer.l" { return NETWORKLINE; } YY_BREAK case 5: YY_RULE_SETUP #line 83 "src/core/io/pajek-lexer.l" { return NETWORKLINE; } YY_BREAK case 6: YY_RULE_SETUP #line 84 "src/core/io/pajek-lexer.l" { return VERTICESLINE; } YY_BREAK case 7: YY_RULE_SETUP #line 85 "src/core/io/pajek-lexer.l" { return ARCSLINE; } YY_BREAK case 8: YY_RULE_SETUP #line 86 "src/core/io/pajek-lexer.l" { return EDGESLINE; } YY_BREAK case 9: YY_RULE_SETUP #line 87 "src/core/io/pajek-lexer.l" { return ARCSLISTLINE; } YY_BREAK case 10: YY_RULE_SETUP #line 88 "src/core/io/pajek-lexer.l" { return EDGESLISTLINE; } YY_BREAK case 11: YY_RULE_SETUP #line 89 "src/core/io/pajek-lexer.l" { return MATRIXLINE; } YY_BREAK case 12: /* rule 12 can match eol */ YY_RULE_SETUP #line 90 "src/core/io/pajek-lexer.l" { yyextra->mode=0; return NEWLINE; } YY_BREAK case 13: /* rule 13 can match eol */ YY_RULE_SETUP #line 91 "src/core/io/pajek-lexer.l" { return QSTR; } YY_BREAK case 14: /* rule 14 can match eol */ YY_RULE_SETUP #line 92 "src/core/io/pajek-lexer.l" { return PSTR; } YY_BREAK case 15: YY_RULE_SETUP #line 93 "src/core/io/pajek-lexer.l" { return NUM; } YY_BREAK case 16: /* rule 16 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 6); yyg->yy_c_buf_p = yy_cp = yy_bp + 6; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 96 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_X_FACT; } else { return ALNUM; } } YY_BREAK case 17: /* rule 17 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 6); yyg->yy_c_buf_p = yy_cp = yy_bp + 6; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 97 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_Y_FACT; } else { return ALNUM; } } YY_BREAK case 18: /* rule 18 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 98 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_IC; } else { return ALNUM; } } YY_BREAK case 19: /* rule 19 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 99 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_BC; } else { return ALNUM; } } YY_BREAK case 20: /* rule 20 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 100 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_BW; } else { return ALNUM; } } YY_BREAK case 21: /* rule 21 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 3); yyg->yy_c_buf_p = yy_cp = yy_bp + 3; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 101 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_PHI; } else { return ALNUM; } } YY_BREAK case 22: /* rule 22 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 1); yyg->yy_c_buf_p = yy_cp = yy_bp + 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 102 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_R; } else { return ALNUM; } } YY_BREAK case 23: /* rule 23 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 1); yyg->yy_c_buf_p = yy_cp = yy_bp + 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 103 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_Q; } else { return ALNUM; } } YY_BREAK case 24: /* rule 24 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 4); yyg->yy_c_buf_p = yy_cp = yy_bp + 4; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 104 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_FONT; } else { return ALNUM; } } YY_BREAK case 25: /* rule 25 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 3); yyg->yy_c_buf_p = yy_cp = yy_bp + 3; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 105 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_URL; } else { return ALNUM; } } YY_BREAK case 26: /* rule 26 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 1); yyg->yy_c_buf_p = yy_cp = yy_bp + 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 107 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_C; } else { return ALNUM; } } YY_BREAK case 27: /* rule 27 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 1); yyg->yy_c_buf_p = yy_cp = yy_bp + 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 108 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_P; } else { return ALNUM; } } YY_BREAK case 28: /* rule 28 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 1); yyg->yy_c_buf_p = yy_cp = yy_bp + 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 109 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_S; } else { return ALNUM; } } YY_BREAK case 29: /* rule 29 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 1); yyg->yy_c_buf_p = yy_cp = yy_bp + 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 110 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_A; } else { return ALNUM; } } YY_BREAK case 30: /* rule 30 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 1); yyg->yy_c_buf_p = yy_cp = yy_bp + 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 111 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_W; } else { return ALNUM; } } YY_BREAK case 31: /* rule 31 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 112 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_H1; } else { return ALNUM; } } YY_BREAK case 32: /* rule 32 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 113 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_H2; } else { return ALNUM; } } YY_BREAK case 33: /* rule 33 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 114 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_A1; } else { return ALNUM; } } YY_BREAK case 34: /* rule 34 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 115 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_A2; } else { return ALNUM; } } YY_BREAK case 35: /* rule 35 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 116 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_K1; } else { return ALNUM; } } YY_BREAK case 36: /* rule 36 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 117 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_K2; } else { return ALNUM; } } YY_BREAK case 37: /* rule 37 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 118 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_AP; } else { return ALNUM; } } YY_BREAK case 38: /* rule 38 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 1); yyg->yy_c_buf_p = yy_cp = yy_bp + 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 119 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_L; } else { return ALNUM; } } YY_BREAK case 39: /* rule 39 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 120 "src/core/io/pajek-lexer.l" { if (yyextra->mode==2) { return EP_LP; } else { return ALNUM; } } YY_BREAK case 40: /* rule 40 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 4); yyg->yy_c_buf_p = yy_cp = yy_bp + 4; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 122 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_LPHI; } else if (yyextra->mode==2) { return EP_LPHI; } else { return ALNUM; } } YY_BREAK case 41: /* rule 41 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 124 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_LC; } else if (yyextra->mode==2) { return EP_LC; } else { return ALNUM; } } YY_BREAK case 42: /* rule 42 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 126 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_LR; } else if (yyextra->mode==2) { return EP_LR; } else { return ALNUM; } } YY_BREAK case 43: /* rule 43 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 2); yyg->yy_c_buf_p = yy_cp = yy_bp + 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 128 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_LA; } else if (yyextra->mode==2) { return EP_LA; } else { return ALNUM; } } YY_BREAK case 44: /* rule 44 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 4); yyg->yy_c_buf_p = yy_cp = yy_bp + 4; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 130 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_SIZE; } else if (yyextra->mode==2) { return EP_SIZE; } else { return ALNUM; } } YY_BREAK case 45: /* rule 45 can match eol */ *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ YY_LINENO_REWIND_TO(yy_bp + 3); yyg->yy_c_buf_p = yy_cp = yy_bp + 3; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 132 "src/core/io/pajek-lexer.l" { if (yyextra->mode==1) { return VP_FOS; } else if (yyextra->mode==2) { return EP_FOS; } else { return ALNUM; } } YY_BREAK case 46: YY_RULE_SETUP #line 135 "src/core/io/pajek-lexer.l" { return ALNUM; } YY_BREAK case YY_STATE_EOF(INITIAL): #line 137 "src/core/io/pajek-lexer.l" { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; return NEWLINE; } } YY_BREAK case 47: YY_RULE_SETUP #line 145 "src/core/io/pajek-lexer.l" { return ERROR; } YY_BREAK case 48: YY_RULE_SETUP #line 147 "src/core/io/pajek-lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK #line 1599 "src/core/io/pajek-lexer.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = yyg->yytext_ptr; int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin , yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { yy_state_type yy_current_state; char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 42); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 161 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ char *yy_cp = yyg->yy_c_buf_p; YY_CHAR yy_c = 42; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 161 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_is_jam = (yy_current_state == 160); (void)yyg; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf , yyscanner ); yyfree( (void *) b , yyscanner ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; yyensure_buffer_stack(yyscanner); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { yy_load_buffer_state( yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b , yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) { return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n , yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n , yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void __attribute__((unused)) yy_fatal_error (const char* msg , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; fprintf( stderr, "%s\n", msg ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param _line_number line number * @param yyscanner The scanner object. */ void yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = _line_number; } /** Set the current column. * @param _column_no column number * @param yyscanner The scanner object. */ void yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = _in_str ; } void yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = _out_str ; } int yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ YYSTYPE * yyget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } YYLTYPE *yyget_lloc (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylloc; } void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylloc = yylloc_param; } /* User-visible API */ /* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ yyfree(yyg->yy_buffer_stack , yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ yyfree( yyg->yy_start_stack , yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; (void)yyg; free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 147 "src/core/io/pajek-lexer.l" leidenbase/src/core/io/lgl-lexer.l0000644000176200001440000000566014447675374016577 0ustar liggesusers/* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "io/lgl-header.h" #include "io/parsers/lgl-parser.h" #define YY_EXTRA_TYPE igraph_i_lgl_parsedata_t* #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) IGRAPH_FATAL("Error in LGL parser: " # msg) #ifdef USING_R #define fprintf(file, msg, ...) (1) #ifdef stdout # undef stdout #endif #define stdout 0 #endif %} %option noyywrap %option prefix="igraph_lgl_yy" %option nounput %option noinput %option nodefault %option reentrant %option bison-bridge %option bison-locations alnum [^ \t\r\n\0#] %% /* --------------------------------------------------hashmark------*/ # { return HASH; } /* ------------------------------------------------whitespace------*/ [ \t]+ { } /* ---------------------------------------------------newline------*/ \n\r|\r\n|\n|\r { return NEWLINE; } /* ----------------------------------------------alphanumeric------*/ {alnum}+ { return ALNUM; } <> { if (yyextra->eof) { yyterminate(); } else { yyextra->eof=1; return NEWLINE; } } . { return ERROR; } %% leidenbase/src/core/io/graphml.c0000644000176200001440000021360414447675374016324 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph R package. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_attributes.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "core/math.h" #include "core/trie.h" #include "graph/attributes.h" #include "internal/hacks.h" /* strcasecmp */ #include "config.h" #include #include /* isnan */ #include #include /* va_start & co */ #define GRAPHML_NAMESPACE_URI "http://graphml.graphdrawing.org/xmlns" #if HAVE_LIBXML == 1 #include #include xmlEntity blankEntityStruct = { #ifndef XML_WITHOUT_CORBA 0, #endif XML_ENTITY_DECL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, XML_EXTERNAL_GENERAL_PARSED_ENTITY, 0, 0, 0, 0, 0, 1 }; xmlEntityPtr blankEntity = &blankEntityStruct; #define GRAPHML_PARSE_ERROR_WITH_CODE(state, msg, code) do { \ if (state->successful) { \ igraph_i_graphml_sax_handler_error(state, msg); \ } \ } while (0) #define GRAPHML_PARSE_ERROR(state, msg) \ GRAPHML_PARSE_ERROR_WITH_CODE(state, msg, IGRAPH_PARSEERROR) #define RETURN_GRAPHML_PARSE_ERROR_WITH_CODE(state, msg, code) do { \ GRAPHML_PARSE_ERROR_WITH_CODE(state, msg, code); \ return; \ } while (1) #define RETURN_GRAPHML_PARSE_ERROR(state, msg) do { \ GRAPHML_PARSE_ERROR(state, msg); \ return; \ } while (1) /* TODO: proper error handling */ typedef struct igraph_i_graphml_attribute_record_t { const char *id; /* GraphML id */ enum { I_GRAPHML_BOOLEAN, I_GRAPHML_INTEGER, I_GRAPHML_LONG, I_GRAPHML_FLOAT, I_GRAPHML_DOUBLE, I_GRAPHML_STRING, I_GRAPHML_UNKNOWN_TYPE } type; /* GraphML type */ union { igraph_real_t as_numeric; igraph_bool_t as_boolean; char* as_string; } default_value; /* Default value of the attribute, if any */ igraph_attribute_record_t record; } igraph_i_graphml_attribute_record_t; struct igraph_i_graphml_parser_state { enum { START, INSIDE_GRAPHML, INSIDE_GRAPH, INSIDE_NODE, INSIDE_EDGE, INSIDE_KEY, INSIDE_DEFAULT, INSIDE_DATA, FINISH, UNKNOWN, ERROR } st; igraph_t *g; igraph_trie_t node_trie; igraph_strvector_t edgeids; igraph_vector_t edgelist; igraph_vector_int_t prev_state_stack; unsigned int unknown_depth; int index; igraph_bool_t successful; igraph_bool_t edges_directed; igraph_trie_t v_names; igraph_vector_ptr_t v_attrs; igraph_trie_t e_names; igraph_vector_ptr_t e_attrs; igraph_trie_t g_names; igraph_vector_ptr_t g_attrs; igraph_i_graphml_attribute_record_t* current_attr_record; xmlChar *data_key; igraph_attribute_elemtype_t data_type; char *error_message; char *data_char; long int act_node; igraph_bool_t ignore_namespaces; }; static void igraph_i_report_unhandled_attribute_target(const char* target, const char* file, int line) { igraph_warningf("Attribute target '%s' is not handled; ignoring corresponding " "attribute specifications", file, line, 0, target); } static igraph_real_t igraph_i_graphml_parse_numeric(const char* char_data, igraph_real_t default_value) { double result; if (char_data == 0) { return default_value; } if (sscanf(char_data, "%lf", &result) == 0) { return default_value; } return result; } static igraph_bool_t igraph_i_graphml_parse_boolean(const char* char_data, igraph_bool_t default_value) { int value; if (char_data == 0) { return default_value; } if (!strcasecmp("true", char_data)) { return 1; } if (!strcasecmp("yes", char_data)) { return 1; } if (!strcasecmp("false", char_data)) { return 0; } if (!strcasecmp("no", char_data)) { return 0; } if (sscanf(char_data, "%d", &value) == 0) { return default_value; } return value != 0; } static void igraph_i_graphml_attribute_record_destroy(igraph_i_graphml_attribute_record_t* rec) { if (rec->record.type == IGRAPH_ATTRIBUTE_NUMERIC) { if (rec->record.value != 0) { igraph_vector_destroy((igraph_vector_t*)rec->record.value); IGRAPH_FREE(rec->record.value); } } else if (rec->record.type == IGRAPH_ATTRIBUTE_STRING) { if (rec->record.value != 0) { igraph_strvector_destroy((igraph_strvector_t*)rec->record.value); IGRAPH_FREE(rec->record.value); } if (rec->default_value.as_string != 0) { IGRAPH_FREE(rec->default_value.as_string); } } else if (rec->record.type == IGRAPH_ATTRIBUTE_BOOLEAN) { if (rec->record.value != 0) { igraph_vector_bool_destroy((igraph_vector_bool_t*)rec->record.value); IGRAPH_FREE(rec->record.value); } } if (rec->id != 0) { IGRAPH_FREE(rec->id); } if (rec->record.name != 0) { IGRAPH_FREE(rec->record.name); } } static int igraph_i_graphml_parser_state_init(struct igraph_i_graphml_parser_state* state, igraph_t* graph, int index) { memset(state, 0, sizeof(struct igraph_i_graphml_parser_state)); state->g = graph; state->index = index < 0 ? 0 : index; state->successful = 1; state->error_message = NULL; IGRAPH_CHECK(igraph_vector_int_init(&state->prev_state_stack, 0)); IGRAPH_CHECK(igraph_vector_int_reserve(&state->prev_state_stack, 32)); IGRAPH_FINALLY(igraph_vector_int_destroy, &state->prev_state_stack); IGRAPH_CHECK(igraph_vector_ptr_init(&state->v_attrs, 0)); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&state->v_attrs, igraph_i_graphml_attribute_record_destroy); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &state->v_attrs); IGRAPH_CHECK(igraph_vector_ptr_init(&state->e_attrs, 0)); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&state->e_attrs, igraph_i_graphml_attribute_record_destroy); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &state->e_attrs); IGRAPH_CHECK(igraph_vector_ptr_init(&state->g_attrs, 0)); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&state->g_attrs, igraph_i_graphml_attribute_record_destroy); IGRAPH_FINALLY(igraph_vector_ptr_destroy_all, &state->g_attrs); IGRAPH_CHECK(igraph_vector_init(&state->edgelist, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &state->edgelist); IGRAPH_CHECK(igraph_trie_init(&state->node_trie, 1)); IGRAPH_FINALLY(igraph_trie_destroy, &state->node_trie); IGRAPH_CHECK(igraph_strvector_init(&state->edgeids, 0)); IGRAPH_FINALLY(igraph_strvector_destroy, &state->edgeids); IGRAPH_CHECK(igraph_trie_init(&state->v_names, 0)); IGRAPH_FINALLY(igraph_trie_destroy, &state->v_names); IGRAPH_CHECK(igraph_trie_init(&state->e_names, 0)); IGRAPH_FINALLY(igraph_trie_destroy, &state->e_names); IGRAPH_CHECK(igraph_trie_init(&state->g_names, 0)); IGRAPH_FINALLY_CLEAN(9); return IGRAPH_SUCCESS; } static void igraph_i_graphml_parser_state_destroy(struct igraph_i_graphml_parser_state* state) { igraph_trie_destroy(&state->node_trie); igraph_strvector_destroy(&state->edgeids); igraph_trie_destroy(&state->v_names); igraph_trie_destroy(&state->e_names); igraph_trie_destroy(&state->g_names); igraph_vector_destroy(&state->edgelist); igraph_vector_int_destroy(&state->prev_state_stack); igraph_vector_ptr_destroy_all(&state->v_attrs); igraph_vector_ptr_destroy_all(&state->e_attrs); igraph_vector_ptr_destroy_all(&state->g_attrs); if (state->data_key) { free(state->data_key); state->data_key = NULL; } if (state->data_char) { free(state->data_char); state->data_char = NULL; } if (state->error_message) { free(state->error_message); state->error_message = NULL; } } static void igraph_i_graphml_sax_handler_error(void *state0, const char* msg, ...) { struct igraph_i_graphml_parser_state *state = (struct igraph_i_graphml_parser_state*)state0; const size_t max_error_message_length = 4096; va_list ap; va_start(ap, msg); if (state->error_message == 0) { /* ownership of state->error_message passed on immediately to * state so the state destructor is responsible for freeing it */ state->error_message = IGRAPH_CALLOC(max_error_message_length, char); } state->successful = 0; state->st = ERROR; vsnprintf(state->error_message, max_error_message_length, msg, ap); va_end(ap); } static xmlEntityPtr igraph_i_graphml_sax_handler_get_entity(void *state0, const xmlChar* name) { xmlEntityPtr predef = xmlGetPredefinedEntity(name); IGRAPH_UNUSED(state0); if (predef != NULL) { return predef; } IGRAPH_WARNING("unknown XML entity found\n"); return blankEntity; } static void igraph_i_graphml_handle_unknown_start_tag(struct igraph_i_graphml_parser_state *state) { if (state->st != UNKNOWN) { igraph_vector_int_push_back(&state->prev_state_stack, state->st); state->st = UNKNOWN; state->unknown_depth = 1; } else { state->unknown_depth++; } } static void igraph_i_graphml_sax_handler_start_document(void *state0) { struct igraph_i_graphml_parser_state *state = (struct igraph_i_graphml_parser_state*)state0; state->st = START; state->successful = 1; state->edges_directed = 0; state->data_key = NULL; state->data_char = NULL; state->unknown_depth = 0; state->ignore_namespaces = 0; } static int igraph_i_graphml_parser_state_finish_parsing(struct igraph_i_graphml_parser_state *state) { long i, l; igraph_attribute_record_t idrec, eidrec; const char *idstr = "id"; igraph_bool_t already_has_vertex_id = 0, already_has_edge_id = 0; igraph_vector_ptr_t vattr, eattr, gattr; long int esize; const void **tmp; IGRAPH_ASSERT(state->successful); /* check that we have found and parsed the graph the user is interested in */ IGRAPH_ASSERT(state->index < 0); IGRAPH_CHECK(igraph_vector_ptr_init(&vattr, igraph_vector_ptr_size(&state->v_attrs) + 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &vattr); esize = igraph_vector_ptr_size(&state->e_attrs); if (igraph_strvector_size(&state->edgeids) != 0) { esize++; } IGRAPH_CHECK(igraph_vector_ptr_init(&eattr, esize)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &eattr); IGRAPH_CHECK(igraph_vector_ptr_init(&gattr, igraph_vector_ptr_size(&state->g_attrs))); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &gattr); for (i = 0; i < igraph_vector_ptr_size(&state->v_attrs); i++) { igraph_i_graphml_attribute_record_t *graphmlrec = VECTOR(state->v_attrs)[i]; igraph_attribute_record_t *rec = &graphmlrec->record; /* Check that the name of the vertex attribute is not 'id'. If it is then we cannot the complimentary 'id' attribute. */ if (! strcmp(rec->name, idstr)) { already_has_vertex_id = 1; } if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *vec = (igraph_vector_t*)rec->value; long int origsize = igraph_vector_size(vec); long int nodes = igraph_trie_size(&state->node_trie); IGRAPH_CHECK(igraph_vector_resize(vec, nodes)); for (l = origsize; l < nodes; l++) { VECTOR(*vec)[l] = graphmlrec->default_value.as_numeric; } } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strvec = (igraph_strvector_t*)rec->value; long int origsize = igraph_strvector_size(strvec); long int nodes = igraph_trie_size(&state->node_trie); IGRAPH_CHECK(igraph_strvector_resize(strvec, nodes)); for (l = origsize; l < nodes; l++) { IGRAPH_CHECK(igraph_strvector_set(strvec, l, graphmlrec->default_value.as_string)); } } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_vector_bool_t *boolvec = (igraph_vector_bool_t*)rec->value; long int origsize = igraph_vector_bool_size(boolvec); long int nodes = igraph_trie_size(&state->node_trie); IGRAPH_CHECK(igraph_vector_bool_resize(boolvec, nodes)); for (l = origsize; l < nodes; l++) { VECTOR(*boolvec)[l] = graphmlrec->default_value.as_boolean; } } VECTOR(vattr)[i] = rec; } if (!already_has_vertex_id) { idrec.name = idstr; idrec.type = IGRAPH_ATTRIBUTE_STRING; tmp = &idrec.value; IGRAPH_CHECK(igraph_trie_getkeys(&state->node_trie, (const igraph_strvector_t **)tmp)); VECTOR(vattr)[i] = &idrec; } else { igraph_vector_ptr_pop_back(&vattr); } for (i = 0; i < igraph_vector_ptr_size(&state->e_attrs); i++) { igraph_i_graphml_attribute_record_t *graphmlrec = VECTOR(state->e_attrs)[i]; igraph_attribute_record_t *rec = &graphmlrec->record; if (! strcmp(rec->name, idstr)) { already_has_edge_id = 1; } if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *vec = (igraph_vector_t*)rec->value; long int origsize = igraph_vector_size(vec); long int edges = igraph_vector_size(&state->edgelist) / 2; IGRAPH_CHECK(igraph_vector_resize(vec, edges)); for (l = origsize; l < edges; l++) { VECTOR(*vec)[l] = graphmlrec->default_value.as_numeric; } } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strvec = (igraph_strvector_t*)rec->value; long int origsize = igraph_strvector_size(strvec); long int edges = igraph_vector_size(&state->edgelist) / 2; IGRAPH_CHECK(igraph_strvector_resize(strvec, edges)); for (l = origsize; l < edges; l++) { IGRAPH_CHECK(igraph_strvector_set(strvec, l, graphmlrec->default_value.as_string)); } } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_vector_bool_t *boolvec = (igraph_vector_bool_t*)rec->value; long int origsize = igraph_vector_bool_size(boolvec); long int edges = igraph_vector_size(&state->edgelist) / 2; IGRAPH_CHECK(igraph_vector_bool_resize(boolvec, edges)); for (l = origsize; l < edges; l++) { VECTOR(*boolvec)[l] = graphmlrec->default_value.as_boolean; } } VECTOR(eattr)[i] = rec; } if (igraph_strvector_size(&state->edgeids) != 0) { if (!already_has_edge_id) { long int origsize = igraph_strvector_size(&state->edgeids); eidrec.name = idstr; eidrec.type = IGRAPH_ATTRIBUTE_STRING; IGRAPH_CHECK(igraph_strvector_resize(&state->edgeids, igraph_vector_size(&state->edgelist) / 2)); for (; origsize < igraph_strvector_size(&state->edgeids); origsize++) { IGRAPH_CHECK(igraph_strvector_set(&state->edgeids, origsize, "")); } eidrec.value = &state->edgeids; VECTOR(eattr)[(long int)igraph_vector_ptr_size(&eattr) - 1] = &eidrec; } else { igraph_vector_ptr_pop_back(&eattr); IGRAPH_WARNING("Could not add edge ids, " "there is already an 'id' edge attribute"); } } for (i = 0; i < igraph_vector_ptr_size(&state->g_attrs); i++) { igraph_i_graphml_attribute_record_t *graphmlrec = VECTOR(state->g_attrs)[i]; igraph_attribute_record_t *rec = &graphmlrec->record; if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *vec = (igraph_vector_t*)rec->value; long int origsize = igraph_vector_size(vec); IGRAPH_CHECK(igraph_vector_resize(vec, 1)); for (l = origsize; l < 1; l++) { VECTOR(*vec)[l] = graphmlrec->default_value.as_numeric; } } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strvec = (igraph_strvector_t*)rec->value; long int origsize = igraph_strvector_size(strvec); IGRAPH_CHECK(igraph_strvector_resize(strvec, 1)); for (l = origsize; l < 1; l++) { IGRAPH_CHECK(igraph_strvector_set(strvec, l, graphmlrec->default_value.as_string)); } } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_vector_bool_t *boolvec = (igraph_vector_bool_t*)rec->value; long int origsize = igraph_vector_bool_size(boolvec); IGRAPH_CHECK(igraph_vector_bool_resize(boolvec, 1)); for (l = origsize; l < 1; l++) { VECTOR(*boolvec)[l] = graphmlrec->default_value.as_boolean; } } VECTOR(gattr)[i] = rec; } IGRAPH_CHECK(igraph_empty_attrs(state->g, 0, state->edges_directed, &gattr)); IGRAPH_CHECK(igraph_add_vertices(state->g, (igraph_integer_t) igraph_trie_size(&state->node_trie), &vattr)); IGRAPH_CHECK(igraph_add_edges(state->g, &state->edgelist, &eattr)); igraph_vector_ptr_destroy(&vattr); igraph_vector_ptr_destroy(&eattr); igraph_vector_ptr_destroy(&gattr); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } #define toXmlChar(a) (BAD_CAST(a)) #define fromXmlChar(a) ((char *)(a)) /* not the most elegant way... */ #define XML_ATTR_LOCALNAME(it) (*(it)) #define XML_ATTR_PREFIX(it) (*(it+1)) #define XML_ATTR_URI(it) (*(it+2)) #define XML_ATTR_VALUE_START(it) (*(it+3)) #define XML_ATTR_VALUE_END(it) (*(it+4)) #define XML_ATTR_VALUE(it) *(it+3), (*(it+4))-(*(it+3)) static igraph_i_graphml_attribute_record_t* igraph_i_graphml_add_attribute_key( const xmlChar** attrs, int nb_attrs, struct igraph_i_graphml_parser_state *state) { xmlChar **it; xmlChar *localname; igraph_trie_t *trie = NULL; igraph_vector_ptr_t *ptrvector = NULL; long int id; unsigned short int skip = 0; int i, ret; igraph_i_graphml_attribute_record_t *rec; if (!state->successful) { return 0; } rec = IGRAPH_CALLOC(1, igraph_i_graphml_attribute_record_t); if (rec == 0) { GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot parse GraphML file", IGRAPH_ENOMEM); return 0; } IGRAPH_FINALLY(igraph_free, rec); IGRAPH_FINALLY(igraph_i_graphml_attribute_record_destroy, rec); rec->type = I_GRAPHML_UNKNOWN_TYPE; for (i = 0, it = (xmlChar**)attrs; i < nb_attrs; i++, it += 5) { if (XML_ATTR_URI(it) != 0 && !xmlStrEqual(toXmlChar(GRAPHML_NAMESPACE_URI), XML_ATTR_URI(it))) { continue; } localname = XML_ATTR_LOCALNAME(it); if (xmlStrEqual(localname, toXmlChar("id"))) { rec->id = fromXmlChar(xmlStrndup(XML_ATTR_VALUE(it))); } else if (xmlStrEqual(localname, toXmlChar("attr.name"))) { rec->record.name = fromXmlChar(xmlStrndup(XML_ATTR_VALUE(it))); } else if (xmlStrEqual(localname, toXmlChar("attr.type"))) { if (!xmlStrncmp(toXmlChar("boolean"), XML_ATTR_VALUE(it))) { rec->type = I_GRAPHML_BOOLEAN; rec->record.type = IGRAPH_ATTRIBUTE_BOOLEAN; rec->default_value.as_boolean = 0; } else if (!xmlStrncmp(toXmlChar("string"), XML_ATTR_VALUE(it))) { rec->type = I_GRAPHML_STRING; rec->record.type = IGRAPH_ATTRIBUTE_STRING; rec->default_value.as_string = strdup(""); } else if (!xmlStrncmp(toXmlChar("float"), XML_ATTR_VALUE(it))) { rec->type = I_GRAPHML_FLOAT; rec->record.type = IGRAPH_ATTRIBUTE_NUMERIC; rec->default_value.as_numeric = IGRAPH_NAN; } else if (!xmlStrncmp(toXmlChar("double"), XML_ATTR_VALUE(it))) { rec->type = I_GRAPHML_DOUBLE; rec->record.type = IGRAPH_ATTRIBUTE_NUMERIC; rec->default_value.as_numeric = IGRAPH_NAN; } else if (!xmlStrncmp(toXmlChar("int"), XML_ATTR_VALUE(it))) { rec->type = I_GRAPHML_INTEGER; rec->record.type = IGRAPH_ATTRIBUTE_NUMERIC; rec->default_value.as_numeric = IGRAPH_NAN; } else if (!xmlStrncmp(toXmlChar("long"), XML_ATTR_VALUE(it))) { rec->type = I_GRAPHML_LONG; rec->record.type = IGRAPH_ATTRIBUTE_NUMERIC; rec->default_value.as_numeric = IGRAPH_NAN; } else { GRAPHML_PARSE_ERROR(state, "Cannot parse GraphML file, unknown attribute type"); return 0; } } else if (xmlStrEqual(*it, toXmlChar("for"))) { /* graph, vertex or edge attribute? */ if (!xmlStrncmp(toXmlChar("graph"), XML_ATTR_VALUE(it))) { trie = &state->g_names; ptrvector = &state->g_attrs; } else if (!xmlStrncmp(toXmlChar("node"), XML_ATTR_VALUE(it))) { trie = &state->v_names; ptrvector = &state->v_attrs; } else if (!xmlStrncmp(toXmlChar("edge"), XML_ATTR_VALUE(it))) { trie = &state->e_names; ptrvector = &state->e_attrs; } else if (!xmlStrncmp(toXmlChar("graphml"), XML_ATTR_VALUE(it))) { igraph_i_report_unhandled_attribute_target("graphml", IGRAPH_FILE_BASENAME, __LINE__); skip = 1; } else if (!xmlStrncmp(toXmlChar("hyperedge"), XML_ATTR_VALUE(it))) { igraph_i_report_unhandled_attribute_target("hyperedge", IGRAPH_FILE_BASENAME, __LINE__); skip = 1; } else if (!xmlStrncmp(toXmlChar("port"), XML_ATTR_VALUE(it))) { igraph_i_report_unhandled_attribute_target("port", IGRAPH_FILE_BASENAME, __LINE__); skip = 1; } else if (!xmlStrncmp(toXmlChar("endpoint"), XML_ATTR_VALUE(it))) { igraph_i_report_unhandled_attribute_target("endpoint", IGRAPH_FILE_BASENAME, __LINE__); skip = 1; } else if (!xmlStrncmp(toXmlChar("all"), XML_ATTR_VALUE(it))) { /* TODO: we should handle this */ igraph_i_report_unhandled_attribute_target("all", IGRAPH_FILE_BASENAME, __LINE__); skip = 1; } else { GRAPHML_PARSE_ERROR(state, "Cannot parse GraphML file, unknown value in the 'for' attribute of a tag"); return 0; } } } /* throw an error if there is no ID; this is a clear violation of the GraphML * DTD */ if (rec->id == 0) { GRAPHML_PARSE_ERROR(state, "Found tag with no 'id' attribute"); return 0; } /* in case of a missing attr.name attribute, use the id as the attribute name */ if (rec->record.name == 0) { rec->record.name = strdup(rec->id); } /* if the attribute type is missing, throw an error */ if (!skip && rec->type == I_GRAPHML_UNKNOWN_TYPE) { igraph_warningf("Ignoring because of a missing or unknown 'attr.type' attribute", IGRAPH_FILE_BASENAME, __LINE__, 0, rec->id); skip = 1; } /* if the value of the 'for' attribute was unknown, throw an error */ if (!skip && trie == 0) { GRAPHML_PARSE_ERROR(state, "Cannot parse GraphML file, missing 'for' attribute in a tag"); return 0; } /* if the code above requested skipping the attribute, free everything and * return */ if (skip) { igraph_i_graphml_attribute_record_destroy(rec); igraph_free(rec); IGRAPH_FINALLY_CLEAN(2); return 0; } /* add to trie, attribues */ igraph_trie_get(trie, rec->id, &id); if (id != igraph_trie_size(trie) - 1) { GRAPHML_PARSE_ERROR(state, "Cannot parse GraphML file, duplicate attribute"); return 0; } ret = igraph_vector_ptr_push_back(ptrvector, rec); if (ret) { GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot read GraphML file", ret); return 0; } /* Ownership of 'rec' is now taken by ptrvector so we can clean the * finally stack */ IGRAPH_FINALLY_CLEAN(2); /* rec, destructor + igraph_free */ /* create the attribute values */ switch (rec->record.type) { igraph_vector_t *vec; igraph_vector_bool_t *boolvec; igraph_strvector_t *strvec; case IGRAPH_ATTRIBUTE_BOOLEAN: boolvec = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (boolvec == 0) { GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot parse GraphML file", IGRAPH_ENOMEM); return 0; } rec->record.value = boolvec; igraph_vector_bool_init(boolvec, 0); break; case IGRAPH_ATTRIBUTE_NUMERIC: vec = IGRAPH_CALLOC(1, igraph_vector_t); if (vec == 0) { GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot parse GraphML file", IGRAPH_ENOMEM); return 0; } rec->record.value = vec; igraph_vector_init(vec, 0); break; case IGRAPH_ATTRIBUTE_STRING: strvec = IGRAPH_CALLOC(1, igraph_strvector_t); if (strvec == 0) { GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot parse GraphML file", IGRAPH_ENOMEM); return 0; } rec->record.value = strvec; igraph_strvector_init(strvec, 0); break; default: break; } return rec; } static void igraph_i_graphml_attribute_data_setup(struct igraph_i_graphml_parser_state *state, const xmlChar **attrs, int nb_attrs, igraph_attribute_elemtype_t type) { xmlChar **it; int i; if (!state->successful) { return; } for (i = 0, it = (xmlChar**)attrs; i < nb_attrs; i++, it += 5) { if (XML_ATTR_URI(it) != 0 && !xmlStrEqual(toXmlChar(GRAPHML_NAMESPACE_URI), XML_ATTR_URI(it))) { continue; } if (xmlStrEqual(*it, toXmlChar("key"))) { if (state->data_key) { free(state->data_key); } state->data_key = xmlStrndup(XML_ATTR_VALUE(it)); if (state->data_char) { free(state->data_char); } state->data_char = NULL; state->data_type = type; } else { /* ignore */ } } } static void igraph_i_graphml_append_to_data_char(struct igraph_i_graphml_parser_state *state, const xmlChar *data, int len) { long int data_char_new_start = 0; if (!state->successful) { return; } if (state->data_char) { data_char_new_start = (long int) strlen(state->data_char); state->data_char = IGRAPH_REALLOC(state->data_char, (size_t)(data_char_new_start + len + 1), char); } else { state->data_char = IGRAPH_CALLOC((size_t) len + 1, char); } if (state->data_char == 0) { RETURN_GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot parse GraphML file", IGRAPH_ENOMEM); } memcpy(state->data_char + data_char_new_start, data, (size_t) len * sizeof(xmlChar)); state->data_char[data_char_new_start + len] = '\0'; } static void igraph_i_graphml_attribute_data_finish(struct igraph_i_graphml_parser_state *state) { const char *key = fromXmlChar(state->data_key); igraph_attribute_elemtype_t type = state->data_type; igraph_trie_t *trie = NULL; igraph_vector_ptr_t *ptrvector = NULL; igraph_i_graphml_attribute_record_t *graphmlrec; igraph_attribute_record_t *rec; long int recid, id = 0; int ret; switch (type) { case IGRAPH_ATTRIBUTE_GRAPH: trie = &state->g_names; ptrvector = &state->g_attrs; id = 0; break; case IGRAPH_ATTRIBUTE_VERTEX: trie = &state->v_names; ptrvector = &state->v_attrs; id = state->act_node; break; case IGRAPH_ATTRIBUTE_EDGE: trie = &state->e_names; ptrvector = &state->e_attrs; id = igraph_vector_size(&state->edgelist) / 2 - 1; /* hack */ break; default: /* impossible */ break; } if (key == 0) { /* no key specified, issue a warning */ IGRAPH_WARNING("missing attribute key in a tag, ignoring attribute"); IGRAPH_FREE(state->data_char); return; } igraph_trie_check(trie, key, &recid); if (recid < 0) { /* no such attribute key, issue a warning */ igraph_warningf( "unknown attribute key '%s' in a tag, ignoring attribute", IGRAPH_FILE_BASENAME, __LINE__, 0, key ); IGRAPH_FREE(state->data_char); return; } graphmlrec = VECTOR(*ptrvector)[recid]; rec = &graphmlrec->record; switch (rec->type) { igraph_vector_bool_t *boolvec; igraph_vector_t *vec; igraph_strvector_t *strvec; long int s, i; const char* strvalue; case IGRAPH_ATTRIBUTE_BOOLEAN: boolvec = (igraph_vector_bool_t *)rec->value; s = igraph_vector_bool_size(boolvec); if (id >= s) { ret = igraph_vector_bool_resize(boolvec, id + 1); if (ret) { RETURN_GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot parse GraphML file", ret); } for (i = s; i < id; i++) { VECTOR(*boolvec)[i] = graphmlrec->default_value.as_boolean; } } VECTOR(*boolvec)[id] = igraph_i_graphml_parse_boolean(state->data_char, graphmlrec->default_value.as_boolean); break; case IGRAPH_ATTRIBUTE_NUMERIC: vec = (igraph_vector_t *)rec->value; s = igraph_vector_size(vec); if (id >= s) { ret = igraph_vector_resize(vec, id + 1); if (ret) { RETURN_GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot parse GraphML file", ret); } for (i = s; i < id; i++) { VECTOR(*vec)[i] = graphmlrec->default_value.as_numeric; } } VECTOR(*vec)[id] = igraph_i_graphml_parse_numeric(state->data_char, graphmlrec->default_value.as_numeric); break; case IGRAPH_ATTRIBUTE_STRING: strvec = (igraph_strvector_t *)rec->value; s = igraph_strvector_size(strvec); if (id >= s) { ret = igraph_strvector_resize(strvec, id + 1); if (ret) { RETURN_GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot parse GraphML file", ret); } strvalue = graphmlrec->default_value.as_string; for (i = s; i < id; i++) { igraph_strvector_set(strvec, i, strvalue); } } if (state->data_char) { strvalue = state->data_char; } else { strvalue = graphmlrec->default_value.as_string; } ret = igraph_strvector_set(strvec, id, strvalue); if (ret) { RETURN_GRAPHML_PARSE_ERROR_WITH_CODE(state, "Cannot parse GraphML file", ret); } break; default: break; } if (state->data_char) { IGRAPH_FREE(state->data_char); } } static void igraph_i_graphml_attribute_default_value_finish( struct igraph_i_graphml_parser_state *state) { igraph_i_graphml_attribute_record_t *graphmlrec = state->current_attr_record; if (graphmlrec == 0) { IGRAPH_FATAL( "state->current_attr_record was null where it should have been " "non-null; please report as a bug." ); return; } if (state->data_char == 0) { return; } switch (graphmlrec->record.type) { case IGRAPH_ATTRIBUTE_BOOLEAN: graphmlrec->default_value.as_boolean = igraph_i_graphml_parse_boolean( state->data_char, 0); break; case IGRAPH_ATTRIBUTE_NUMERIC: graphmlrec->default_value.as_numeric = igraph_i_graphml_parse_numeric( state->data_char, IGRAPH_NAN); break; case IGRAPH_ATTRIBUTE_STRING: if (state->data_char) { if (graphmlrec->default_value.as_string != 0) { free(graphmlrec->default_value.as_string); } graphmlrec->default_value.as_string = strdup(state->data_char); } break; default: break; } if (state->data_char) { IGRAPH_FREE(state->data_char); } } static void igraph_i_graphml_sax_handler_start_element_ns( void *state0, const xmlChar* localname, const xmlChar* prefix, const xmlChar* uri, int nb_namespaces, const xmlChar** namespaces, int nb_attributes, int nb_defaulted, const xmlChar** attributes) { struct igraph_i_graphml_parser_state *state = (struct igraph_i_graphml_parser_state*)state0; xmlChar** it; char* attr_value; long int id1, id2; int i; igraph_bool_t tag_is_unknown = 0; IGRAPH_UNUSED(prefix); IGRAPH_UNUSED(nb_namespaces); IGRAPH_UNUSED(namespaces); IGRAPH_UNUSED(nb_defaulted); if (!state->successful) { return; } if (uri) { if (!xmlStrEqual(toXmlChar(GRAPHML_NAMESPACE_URI), uri)) { /* Tag is in a different namespace, so treat it as an unknown start * tag irrespectively of our state */ tag_is_unknown = 1; } } else { /* No namespace URI. If we are in lenient mode, accept it and proceed * as if we are in the GraphML namespace to handle lots of naive * non-namespace-aware GraphML files floating out there. If we are not * in lenient mode _but_ we are in the START state, accept it as well * and see whether the root tag is (in which case we will * enter lenient mode). Otherwise, reject the tag */ if (!state->ignore_namespaces && state->st != START) { tag_is_unknown = 1; } } if (tag_is_unknown) { igraph_i_graphml_handle_unknown_start_tag(state); return; } switch (state->st) { case START: /* If we are in the START state and received a graphml tag, * change to INSIDE_GRAPHML state. Otherwise, change to UNKNOWN. */ if (xmlStrEqual(localname, toXmlChar("graphml"))) { if (uri == 0) { state->ignore_namespaces = 1; } state->st = INSIDE_GRAPHML; } else { igraph_i_graphml_handle_unknown_start_tag(state); } break; case INSIDE_GRAPHML: /* If we are in the INSIDE_GRAPHML state and received a graph tag, * change to INSIDE_GRAPH state if the state->index counter reached * zero (this is to handle multiple graphs in the same file). * Otherwise, change to UNKNOWN. */ if (xmlStrEqual(localname, toXmlChar("graph"))) { if (state->index == 0) { state->st = INSIDE_GRAPH; for (i = 0, it = (xmlChar**)attributes; i < nb_attributes; i++, it += 5) { if (XML_ATTR_URI(it) != 0 && !xmlStrEqual(toXmlChar(GRAPHML_NAMESPACE_URI), XML_ATTR_URI(it))) { /* Attribute is from a different namespace, so skip it */ continue; } if (xmlStrEqual(*it, toXmlChar("edgedefault"))) { if (!xmlStrncmp(toXmlChar("directed"), XML_ATTR_VALUE(it))) { state->edges_directed = 1; } else if (!xmlStrncmp(toXmlChar("undirected"), XML_ATTR_VALUE(it))) { state->edges_directed = 0; } } } } state->index--; } else if (xmlStrEqual(localname, toXmlChar("key"))) { state->current_attr_record = igraph_i_graphml_add_attribute_key(attributes, nb_attributes, state); state->st = INSIDE_KEY; } else { igraph_i_graphml_handle_unknown_start_tag(state); } break; case INSIDE_KEY: /* If we are in the INSIDE_KEY state and we are not skipping the current * attribute, check for default tag */ if (state->current_attr_record != NULL && xmlStrEqual(localname, toXmlChar("default"))) { state->st = INSIDE_DEFAULT; } else { igraph_i_graphml_handle_unknown_start_tag(state); } break; case INSIDE_DEFAULT: /* If we are in the INSIDE_DEFAULT state, every further tag will be unknown */ igraph_i_graphml_handle_unknown_start_tag(state); break; case INSIDE_GRAPH: /* If we are in the INSIDE_GRAPH state, check for node and edge tags */ if (xmlStrEqual(localname, toXmlChar("edge"))) { id1 = -1; id2 = -1; for (i = 0, it = (xmlChar**)attributes; i < nb_attributes; i++, it += 5) { if (XML_ATTR_URI(it) != 0 && !xmlStrEqual(toXmlChar(GRAPHML_NAMESPACE_URI), XML_ATTR_URI(it))) { /* Attribute is from a different namespace, so skip it */ continue; } if (xmlStrEqual(*it, toXmlChar("source"))) { attr_value = fromXmlChar(xmlStrndup(XML_ATTR_VALUE(it))); igraph_trie_get(&state->node_trie, attr_value, &id1); free(attr_value); } else if (xmlStrEqual(*it, toXmlChar("target"))) { attr_value = fromXmlChar(xmlStrndup(XML_ATTR_VALUE(it))); igraph_trie_get(&state->node_trie, attr_value, &id2); free(attr_value); } else if (xmlStrEqual(*it, toXmlChar("id"))) { long int edges = igraph_vector_size(&state->edgelist) / 2 + 1; long int origsize = igraph_strvector_size(&state->edgeids); attr_value = fromXmlChar(xmlStrndup(XML_ATTR_VALUE(it))); igraph_strvector_resize(&state->edgeids, edges); for (; origsize < edges - 1; origsize++) { igraph_strvector_set(&state->edgeids, origsize, ""); } igraph_strvector_set(&state->edgeids, edges - 1, attr_value); free(attr_value); } } if (id1 >= 0 && id2 >= 0) { igraph_vector_push_back(&state->edgelist, id1); igraph_vector_push_back(&state->edgelist, id2); } else { igraph_i_graphml_sax_handler_error(state, "Edge with missing source or target encountered"); return; } state->st = INSIDE_EDGE; } else if (xmlStrEqual(localname, toXmlChar("node"))) { id1 = -1; for (i = 0, it = (xmlChar**)attributes; i < nb_attributes; i++, it += 5) { if (XML_ATTR_URI(it) != 0 && !xmlStrEqual(toXmlChar(GRAPHML_NAMESPACE_URI), XML_ATTR_URI(it))) { /* Attribute is from a different namespace, so skip it */ continue; } if (xmlStrEqual(XML_ATTR_LOCALNAME(it), toXmlChar("id"))) { attr_value = fromXmlChar(xmlStrndup(XML_ATTR_VALUE(it))); igraph_trie_get(&state->node_trie, attr_value, &id1); free(attr_value); break; } } if (id1 >= 0) { state->act_node = id1; } else { state->act_node = -1; igraph_i_graphml_sax_handler_error(state, "Node with missing id encountered"); return; } state->st = INSIDE_NODE; } else if (xmlStrEqual(localname, toXmlChar("data"))) { igraph_i_graphml_attribute_data_setup(state, attributes, nb_attributes, IGRAPH_ATTRIBUTE_GRAPH); igraph_vector_int_push_back(&state->prev_state_stack, state->st); state->st = INSIDE_DATA; } else { igraph_i_graphml_handle_unknown_start_tag(state); } break; case INSIDE_NODE: if (xmlStrEqual(localname, toXmlChar("data"))) { igraph_i_graphml_attribute_data_setup(state, attributes, nb_attributes, IGRAPH_ATTRIBUTE_VERTEX); igraph_vector_int_push_back(&state->prev_state_stack, state->st); state->st = INSIDE_DATA; } break; case INSIDE_EDGE: if (xmlStrEqual(localname, toXmlChar("data"))) { igraph_i_graphml_attribute_data_setup(state, attributes, nb_attributes, IGRAPH_ATTRIBUTE_EDGE); igraph_vector_int_push_back(&state->prev_state_stack, state->st); state->st = INSIDE_DATA; } break; case INSIDE_DATA: /* We do not expect any new tags within a tag */ igraph_i_graphml_handle_unknown_start_tag(state); break; case UNKNOWN: igraph_i_graphml_handle_unknown_start_tag(state); break; default: break; } } static void igraph_i_graphml_sax_handler_end_element_ns( void *state0, const xmlChar* localname, const xmlChar* prefix, const xmlChar* uri) { struct igraph_i_graphml_parser_state *state = (struct igraph_i_graphml_parser_state*)state0; if (!state->successful) { return; } IGRAPH_UNUSED(localname); IGRAPH_UNUSED(prefix); IGRAPH_UNUSED(uri); switch (state->st) { case INSIDE_GRAPHML: state->st = FINISH; break; case INSIDE_GRAPH: state->st = INSIDE_GRAPHML; break; case INSIDE_KEY: state->current_attr_record = NULL; state->st = INSIDE_GRAPHML; break; case INSIDE_DEFAULT: igraph_i_graphml_attribute_default_value_finish(state); state->st = INSIDE_KEY; break; case INSIDE_NODE: state->st = INSIDE_GRAPH; break; case INSIDE_EDGE: state->st = INSIDE_GRAPH; break; case INSIDE_DATA: igraph_i_graphml_attribute_data_finish(state); state->st = igraph_vector_int_pop_back(&state->prev_state_stack); break; case UNKNOWN: state->unknown_depth--; if (!state->unknown_depth) { state->st = igraph_vector_int_pop_back(&state->prev_state_stack); } break; default: break; } } static void igraph_i_graphml_sax_handler_chars(void* state0, const xmlChar* ch, int len) { struct igraph_i_graphml_parser_state *state = (struct igraph_i_graphml_parser_state*)state0; if (!state->successful) { return; } switch (state->st) { case INSIDE_KEY: break; case INSIDE_DATA: case INSIDE_DEFAULT: igraph_i_graphml_append_to_data_char(state, ch, len); break; default: /* just ignore it */ break; } } static xmlSAXHandler igraph_i_graphml_sax_handler = { /* internalSubset = */ 0, /* isStandalone = */ 0, /* hasInternalSubset = */ 0, /* hasExternalSubset = */ 0, /* resolveEntity = */ 0, /* getEntity = */ igraph_i_graphml_sax_handler_get_entity, /* entityDecl = */ 0, /* notationDecl = */ 0, /* attributeDecl = */ 0, /* elementDecl = */ 0, /* unparsedEntityDecl = */ 0, /* setDocumentLocator = */ 0, /* startDocument = */ igraph_i_graphml_sax_handler_start_document, /* endDocument = */ 0, /* startElement = */ 0, /* endElement = */ 0, /* reference = */ 0, /* characters = */ igraph_i_graphml_sax_handler_chars, /* ignorableWhitespaceFunc = */ 0, /* processingInstruction = */ 0, /* comment = */ 0, /* warning = */ igraph_i_graphml_sax_handler_error, /* error = */ igraph_i_graphml_sax_handler_error, /* fatalError = */ igraph_i_graphml_sax_handler_error, /* getParameterEntity = */ 0, /* cdataBlock = */ 0, /* externalSubset = */ 0, /* initialized = */ XML_SAX2_MAGIC, /* _private = */ 0, /* startElementNs = */ igraph_i_graphml_sax_handler_start_element_ns, /* endElementNs = */ igraph_i_graphml_sax_handler_end_element_ns, /* serror = */ 0 }; #endif #define IS_FORBIDDEN_CONTROL_CHAR(x) ((x) < ' ' && (x) != '\t' && (x) != '\r' && (x) != '\n') static int igraph_i_xml_escape(char* src, char** dest) { long int destlen = 0; char *s, *d; unsigned char ch; for (s = src; *s; s++, destlen++) { ch = (unsigned char)(*s); if (ch == '&') { destlen += 4; } else if (ch == '<') { destlen += 3; } else if (ch == '>') { destlen += 3; } else if (ch == '"') { destlen += 5; } else if (ch == '\'') { destlen += 5; } else if (IS_FORBIDDEN_CONTROL_CHAR(ch)) { char msg[4096]; snprintf(msg, 4096, "Forbidden control character 0x%02X found in igraph_i_xml_escape", ch); IGRAPH_ERROR(msg, IGRAPH_EINVAL); } } *dest = IGRAPH_CALLOC(destlen + 1, char); if (!*dest) { IGRAPH_ERROR("Not enough memory", IGRAPH_ENOMEM); } for (s = src, d = *dest; *s; s++, d++) { ch = (unsigned char)(*s); switch (ch) { case '&': strcpy(d, "&"); d += 4; break; case '<': strcpy(d, "<"); d += 3; break; case '>': strcpy(d, ">"); d += 3; break; case '"': strcpy(d, """); d += 5; break; case '\'': strcpy(d, "'"); d += 5; break; default: *d = ch; } } *d = 0; return 0; } /** * \ingroup loadsave * \function igraph_read_graph_graphml * \brief Reads a graph from a GraphML file. * * * GraphML is an XML-based file format for representing various types of * graphs. Currently only the most basic import functionality is implemented * in igraph: it can read GraphML files without nested graphs and hyperedges. * Attributes of the graph are loaded only if an attribute interface * is attached, i.e. if you use igraph from R or Python. * * * Graph attribute names are taken from the attr.name attributes of the * \c key tags in the GraphML file. Since attr.name is not mandatory, * igraph will fall back to the \c id attribute of the \c key tag if * attr.name is missing. * * \param graph Pointer to an uninitialized graph object. * \param instream A stream, it should be readable. * \param index If the GraphML file contains more than one graph, the one * specified by this index will be loaded. Indices start from * zero, so supply zero here if your GraphML file contains only * a single graph. * * \return Error code: * \c IGRAPH_PARSEERROR: if there is a * problem reading the file, or the file is syntactically * incorrect. * \c IGRAPH_UNIMPLEMENTED: the GraphML functionality was disabled * at compile-time * * \example examples/simple/graphml.c */ int igraph_read_graph_graphml(igraph_t *graph, FILE *instream, int index) { #if HAVE_LIBXML == 1 xmlParserCtxtPtr ctxt; xmlDocPtr doc; struct igraph_i_graphml_parser_state state; int res; char buffer[4096]; igraph_bool_t parsing_successful; char* error_message; if (index < 0) { IGRAPH_ERROR("Graph index must be non-negative", IGRAPH_EINVAL); } xmlInitParser(); IGRAPH_CHECK(igraph_i_graphml_parser_state_init(&state, graph, index)); IGRAPH_FINALLY(igraph_i_graphml_parser_state_destroy, &state); /* Create a progressive parser context */ res = (int) fread(buffer, 1, sizeof(buffer), instream); if (res < sizeof(buffer) && !feof(instream)) { IGRAPH_ERROR("IO error while reading GraphML data", IGRAPH_PARSEERROR); } ctxt = xmlCreatePushParserCtxt(&igraph_i_graphml_sax_handler, &state, buffer, res, NULL); /* ctxt=xmlCreateIOParserCtxt(&igraph_i_graphml_sax_handler, &state, */ /* igraph_i_libxml2_read_callback, */ /* igraph_i_libxml2_close_callback, */ /* instream, XML_CHAR_ENCODING_NONE); */ if (ctxt == NULL) { IGRAPH_ERROR("Can't create progressive parser context", IGRAPH_PARSEERROR); } /* Set parsing options */ if (xmlCtxtUseOptions(ctxt, XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NSCLEAN | XML_PARSE_NOCDATA | XML_PARSE_HUGE )) { xmlFreeParserCtxt(ctxt); IGRAPH_ERROR("Cannot set options for the parser context", IGRAPH_EINVAL); } /* Okay, parsing will start now. The parser might do things that eventually * trigger the igraph error handler, but we want the parser state to * survive whatever happens here. So, we need to pop off * igraph_i_graphml_parser_state_destroy() from the stack and temporarily * assume responsibility for calling it ourselves until we are back from the * parser */ IGRAPH_FINALLY_CLEAN(1); /* Do the parsing */ while ((res = (int) fread(buffer, 1, sizeof(buffer), instream)) > 0) { xmlParseChunk(ctxt, buffer, res, 0); if (!state.successful) { break; } } xmlParseChunk(ctxt, buffer, res, 1); /* Free the context */ doc = ctxt->myDoc; xmlFreeParserCtxt(ctxt); if (doc) { /* In theory this should not be necessary, but it looks like certain malformed * GraphML files leave a partially-parsed doc in memory */ xmlFreeDoc(doc); } /* Extract the error message from the parser state (if any), and make a * copy so we can safely destroy the parser state before triggering the * error */ parsing_successful = state.successful; error_message = parsing_successful || state.error_message == NULL ? NULL : strdup(state.error_message); /* Now that we have lifted error_message out of the parser state, we can * put the destructor of the parser state back on the FINALLY stack */ IGRAPH_FINALLY(igraph_i_graphml_parser_state_destroy, &state); /* ...and we can also put the error message pointer on the FINALLY stack */ if (error_message != NULL) { IGRAPH_FINALLY(free, error_message); } /* Trigger the stored error if needed */ if (!parsing_successful) { if (error_message != NULL) { IGRAPH_ERROR(error_message, IGRAPH_PARSEERROR); } else { IGRAPH_ERROR("Malformed GraphML file", IGRAPH_PARSEERROR); } } /* Did we actually manage to reach the graph to be parsed, given its index? * If not, that's an error as well. */ if (state.index >= 0) { IGRAPH_ERROR("Graph index was too large", IGRAPH_EINVAL); } /* Okay, everything seems good. We can now take the parser state and * construct our graph from the data gathered during the parsing */ IGRAPH_CHECK(igraph_i_graphml_parser_state_finish_parsing(&state)); igraph_i_graphml_parser_state_destroy(&state); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; #else IGRAPH_UNUSED(graph); IGRAPH_UNUSED(instream); IGRAPH_UNUSED(index); IGRAPH_ERROR("GraphML support is disabled", IGRAPH_UNIMPLEMENTED); #endif } /** * \ingroup loadsave * \function igraph_write_graph_graphml * \brief Writes the graph to a file in GraphML format * * * GraphML is an XML-based file format for representing various types of * graphs. See the GraphML Primer (http://graphml.graphdrawing.org/primer/graphml-primer.html) * for detailed format description. * * \param graph The graph to write. * \param outstream The stream object to write to, it should be * writable. * \param prefixattr Logical value, whether to put a prefix in front of the * attribute names to ensure uniqueness if the graph has vertex and * edge (or graph) attributes with the same name. * \return Error code: * \c IGRAPH_EFILE if there is an error * writing the file. * * Time complexity: O(|V|+|E|) otherwise. All * file operations are expected to have time complexity * O(1). * * \example examples/simple/graphml.c */ int igraph_write_graph_graphml(const igraph_t *graph, FILE *outstream, igraph_bool_t prefixattr) { int ret; igraph_integer_t l, vc; igraph_eit_t it; igraph_strvector_t gnames, vnames, enames; igraph_vector_t gtypes, vtypes, etypes; long int i; igraph_vector_t numv; igraph_strvector_t strv; igraph_vector_bool_t boolv; const char *gprefix = prefixattr ? "g_" : ""; const char *vprefix = prefixattr ? "v_" : ""; const char *eprefix = prefixattr ? "e_" : ""; /* set standard C locale lest we sometimes get commas instead of dots */ char *saved_locale = strdup(setlocale(LC_NUMERIC, NULL)); if (saved_locale == NULL) { IGRAPH_ERROR("Not enough memory", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, saved_locale); setlocale(LC_NUMERIC, "C"); ret = fprintf(outstream, "\n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = fprintf(outstream, "\n", GRAPHML_NAMESPACE_URI); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = fprintf(outstream, "\n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } /* dump the elements if any */ IGRAPH_VECTOR_INIT_FINALLY(&numv, 1); IGRAPH_STRVECTOR_INIT_FINALLY(&strv, 1); IGRAPH_VECTOR_BOOL_INIT_FINALLY(&boolv, 1); IGRAPH_STRVECTOR_INIT_FINALLY(&gnames, 0); IGRAPH_STRVECTOR_INIT_FINALLY(&vnames, 0); IGRAPH_STRVECTOR_INIT_FINALLY(&enames, 0); IGRAPH_VECTOR_INIT_FINALLY(>ypes, 0); IGRAPH_VECTOR_INIT_FINALLY(&vtypes, 0); IGRAPH_VECTOR_INIT_FINALLY(&etypes, 0); igraph_i_attribute_get_info(graph, &gnames, >ypes, &vnames, &vtypes, &enames, &etypes); /* graph attributes */ for (i = 0; i < igraph_vector_size(>ypes); i++) { char *name, *name_escaped; igraph_strvector_get(&gnames, i, &name); IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_STRING) { ret = fprintf(outstream, " \n", gprefix, name_escaped, name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { ret = fprintf(outstream, " \n", gprefix, name_escaped, name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) { ret = fprintf(outstream, " \n", gprefix, name_escaped, name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } IGRAPH_FREE(name_escaped); } /* vertex attributes */ for (i = 0; i < igraph_vector_size(&vtypes); i++) { char *name, *name_escaped; igraph_strvector_get(&vnames, i, &name); IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_STRING) { ret = fprintf(outstream, " \n", vprefix, name_escaped, name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } else if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { ret = fprintf(outstream, " \n", vprefix, name_escaped, name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } else if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) { ret = fprintf(outstream, " \n", vprefix, name_escaped, name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } IGRAPH_FREE(name_escaped); } /* edge attributes */ for (i = 0; i < igraph_vector_size(&etypes); i++) { char *name, *name_escaped; igraph_strvector_get(&enames, i, &name); IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_STRING) { ret = fprintf(outstream, " \n", eprefix, name_escaped, name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } else if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { ret = fprintf(outstream, " \n", eprefix, name_escaped, name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } else if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) { ret = fprintf(outstream, " \n", eprefix, name_escaped, name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } IGRAPH_FREE(name_escaped); } ret = fprintf(outstream, " \n", (igraph_is_directed(graph) ? "directed" : "undirected")); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } /* Write the graph atributes before anything else */ for (i = 0; i < igraph_vector_size(>ypes); i++) { char *name, *name_escaped; if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_strvector_get(&gnames, i, &name); IGRAPH_CHECK(igraph_i_attribute_get_numeric_graph_attr(graph, name, &numv)); if (!isnan(VECTOR(numv)[0])) { IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); ret = fprintf(outstream, " ", gprefix, name_escaped); IGRAPH_FREE(name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = fprintf(outstream, "\n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_STRING) { char *s, *s_escaped; igraph_strvector_get(&gnames, i, &name); IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); ret = fprintf(outstream, " ", gprefix, name_escaped); IGRAPH_FREE(name_escaped); IGRAPH_CHECK(igraph_i_attribute_get_string_graph_attr(graph, name, &strv)); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_xml_escape(s, &s_escaped)); ret = fprintf(outstream, "%s", s_escaped); IGRAPH_FREE(s_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = fprintf(outstream, "\n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_strvector_get(&gnames, i, &name); IGRAPH_CHECK(igraph_i_attribute_get_bool_graph_attr(graph, name, &boolv)); IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); ret = fprintf(outstream, " %s\n", gprefix, name_escaped, VECTOR(boolv)[0] ? "true" : "false"); IGRAPH_FREE(name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } } /* Let's dump the nodes first */ vc = igraph_vcount(graph); for (l = 0; l < vc; l++) { char *name, *name_escaped; ret = fprintf(outstream, " \n", (long)l); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } for (i = 0; i < igraph_vector_size(&vtypes); i++) { if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_strvector_get(&vnames, i, &name); IGRAPH_CHECK(igraph_i_attribute_get_numeric_vertex_attr(graph, name, igraph_vss_1(l), &numv)); if (!isnan(VECTOR(numv)[0])) { IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); ret = fprintf(outstream, " ", vprefix, name_escaped); IGRAPH_FREE(name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = fprintf(outstream, "\n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } } else if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_STRING) { char *s, *s_escaped; igraph_strvector_get(&vnames, i, &name); IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); ret = fprintf(outstream, " ", vprefix, name_escaped); IGRAPH_FREE(name_escaped); IGRAPH_CHECK(igraph_i_attribute_get_string_vertex_attr(graph, name, igraph_vss_1(l), &strv)); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_xml_escape(s, &s_escaped)); ret = fprintf(outstream, "%s", s_escaped); IGRAPH_FREE(s_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = fprintf(outstream, "\n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } else if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_strvector_get(&vnames, i, &name); IGRAPH_CHECK(igraph_i_attribute_get_bool_vertex_attr(graph, name, igraph_vss_1(l), &boolv)); IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); ret = fprintf(outstream, " %s\n", vprefix, name_escaped, VECTOR(boolv)[0] ? "true" : "false"); IGRAPH_FREE(name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } } ret = fprintf(outstream, " \n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } /* Now the edges */ IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(0), &it)); IGRAPH_FINALLY(igraph_eit_destroy, &it); while (!IGRAPH_EIT_END(it)) { igraph_integer_t from, to; char *name, *name_escaped; long int edge = IGRAPH_EIT_GET(it); igraph_edge(graph, (igraph_integer_t) edge, &from, &to); ret = fprintf(outstream, " \n", (long int)from, (long int)to); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } for (i = 0; i < igraph_vector_size(&etypes); i++) { if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_strvector_get(&enames, i, &name); IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) edge), &numv)); if (!isnan(VECTOR(numv)[0])) { IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); ret = fprintf(outstream, " ", eprefix, name_escaped); IGRAPH_FREE(name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = fprintf(outstream, "\n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } } else if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_STRING) { char *s, *s_escaped; igraph_strvector_get(&enames, i, &name); IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); ret = fprintf(outstream, " ", eprefix, name_escaped); IGRAPH_FREE(name_escaped); IGRAPH_CHECK(igraph_i_attribute_get_string_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) edge), &strv)); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_xml_escape(s, &s_escaped)); ret = fprintf(outstream, "%s", s_escaped); IGRAPH_FREE(s_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } ret = fprintf(outstream, "\n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } else if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_strvector_get(&enames, i, &name); IGRAPH_CHECK(igraph_i_attribute_get_bool_edge_attr(graph, name, igraph_ess_1((igraph_integer_t) edge), &boolv)); IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped)); ret = fprintf(outstream, " %s\n", eprefix, name_escaped, VECTOR(boolv)[0] ? "true" : "false"); IGRAPH_FREE(name_escaped); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } } } ret = fprintf(outstream, " \n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } IGRAPH_EIT_NEXT(it); } igraph_eit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); ret = fprintf(outstream, " \n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } fprintf(outstream, "\n"); if (ret < 0) { IGRAPH_ERROR("Write failed", IGRAPH_EFILE); } /* reset locale to whatever was before this function */ setlocale(LC_NUMERIC, saved_locale); igraph_free(saved_locale); igraph_strvector_destroy(&gnames); igraph_strvector_destroy(&vnames); igraph_strvector_destroy(&enames); igraph_vector_destroy(>ypes); igraph_vector_destroy(&vtypes); igraph_vector_destroy(&etypes); igraph_vector_destroy(&numv); igraph_strvector_destroy(&strv); igraph_vector_bool_destroy(&boolv); IGRAPH_FINALLY_CLEAN(10); return 0; } leidenbase/src/core/io/pajek-lexer.h0000644000176200001440000004255714447675375017116 0ustar liggesusers#ifndef igraph_pajek_yyHEADER_H #define igraph_pajek_yyHEADER_H 1 #define igraph_pajek_yyIN_HEADER 1 #line 6 "src/core/io/pajek-lexer.h" #line 8 "src/core/io/pajek-lexer.h" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define igraph_pajek_yy_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer igraph_pajek_yy_create_buffer #endif #ifdef yy_delete_buffer #define igraph_pajek_yy_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer igraph_pajek_yy_delete_buffer #endif #ifdef yy_scan_buffer #define igraph_pajek_yy_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer igraph_pajek_yy_scan_buffer #endif #ifdef yy_scan_string #define igraph_pajek_yy_scan_string_ALREADY_DEFINED #else #define yy_scan_string igraph_pajek_yy_scan_string #endif #ifdef yy_scan_bytes #define igraph_pajek_yy_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes igraph_pajek_yy_scan_bytes #endif #ifdef yy_init_buffer #define igraph_pajek_yy_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer igraph_pajek_yy_init_buffer #endif #ifdef yy_flush_buffer #define igraph_pajek_yy_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer igraph_pajek_yy_flush_buffer #endif #ifdef yy_load_buffer_state #define igraph_pajek_yy_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state igraph_pajek_yy_load_buffer_state #endif #ifdef yy_switch_to_buffer #define igraph_pajek_yy_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer igraph_pajek_yy_switch_to_buffer #endif #ifdef yypush_buffer_state #define igraph_pajek_yypush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state igraph_pajek_yypush_buffer_state #endif #ifdef yypop_buffer_state #define igraph_pajek_yypop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state igraph_pajek_yypop_buffer_state #endif #ifdef yyensure_buffer_stack #define igraph_pajek_yyensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack igraph_pajek_yyensure_buffer_stack #endif #ifdef yylex #define igraph_pajek_yylex_ALREADY_DEFINED #else #define yylex igraph_pajek_yylex #endif #ifdef yyrestart #define igraph_pajek_yyrestart_ALREADY_DEFINED #else #define yyrestart igraph_pajek_yyrestart #endif #ifdef yylex_init #define igraph_pajek_yylex_init_ALREADY_DEFINED #else #define yylex_init igraph_pajek_yylex_init #endif #ifdef yylex_init_extra #define igraph_pajek_yylex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra igraph_pajek_yylex_init_extra #endif #ifdef yylex_destroy #define igraph_pajek_yylex_destroy_ALREADY_DEFINED #else #define yylex_destroy igraph_pajek_yylex_destroy #endif #ifdef yyget_debug #define igraph_pajek_yyget_debug_ALREADY_DEFINED #else #define yyget_debug igraph_pajek_yyget_debug #endif #ifdef yyset_debug #define igraph_pajek_yyset_debug_ALREADY_DEFINED #else #define yyset_debug igraph_pajek_yyset_debug #endif #ifdef yyget_extra #define igraph_pajek_yyget_extra_ALREADY_DEFINED #else #define yyget_extra igraph_pajek_yyget_extra #endif #ifdef yyset_extra #define igraph_pajek_yyset_extra_ALREADY_DEFINED #else #define yyset_extra igraph_pajek_yyset_extra #endif #ifdef yyget_in #define igraph_pajek_yyget_in_ALREADY_DEFINED #else #define yyget_in igraph_pajek_yyget_in #endif #ifdef yyset_in #define igraph_pajek_yyset_in_ALREADY_DEFINED #else #define yyset_in igraph_pajek_yyset_in #endif #ifdef yyget_out #define igraph_pajek_yyget_out_ALREADY_DEFINED #else #define yyget_out igraph_pajek_yyget_out #endif #ifdef yyset_out #define igraph_pajek_yyset_out_ALREADY_DEFINED #else #define yyset_out igraph_pajek_yyset_out #endif #ifdef yyget_leng #define igraph_pajek_yyget_leng_ALREADY_DEFINED #else #define yyget_leng igraph_pajek_yyget_leng #endif #ifdef yyget_text #define igraph_pajek_yyget_text_ALREADY_DEFINED #else #define yyget_text igraph_pajek_yyget_text #endif #ifdef yyget_lineno #define igraph_pajek_yyget_lineno_ALREADY_DEFINED #else #define yyget_lineno igraph_pajek_yyget_lineno #endif #ifdef yyset_lineno #define igraph_pajek_yyset_lineno_ALREADY_DEFINED #else #define yyset_lineno igraph_pajek_yyset_lineno #endif #ifdef yyget_column #define igraph_pajek_yyget_column_ALREADY_DEFINED #else #define yyget_column igraph_pajek_yyget_column #endif #ifdef yyset_column #define igraph_pajek_yyset_column_ALREADY_DEFINED #else #define yyset_column igraph_pajek_yyset_column #endif #ifdef yywrap #define igraph_pajek_yywrap_ALREADY_DEFINED #else #define yywrap igraph_pajek_yywrap #endif #ifdef yyget_lval #define igraph_pajek_yyget_lval_ALREADY_DEFINED #else #define yyget_lval igraph_pajek_yyget_lval #endif #ifdef yyset_lval #define igraph_pajek_yyset_lval_ALREADY_DEFINED #else #define yyset_lval igraph_pajek_yyset_lval #endif #ifdef yyget_lloc #define igraph_pajek_yyget_lloc_ALREADY_DEFINED #else #define yyget_lloc igraph_pajek_yyget_lloc #endif #ifdef yyset_lloc #define igraph_pajek_yyset_lloc_ALREADY_DEFINED #else #define yyset_lloc igraph_pajek_yyset_lloc #endif #ifdef yyalloc #define igraph_pajek_yyalloc_ALREADY_DEFINED #else #define yyalloc igraph_pajek_yyalloc #endif #ifdef yyrealloc #define igraph_pajek_yyrealloc_ALREADY_DEFINED #else #define yyrealloc igraph_pajek_yyrealloc #endif #ifdef yyfree #define igraph_pajek_yyfree_ALREADY_DEFINED #else #define yyfree igraph_pajek_yyfree #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ void yyrestart ( FILE *input_file , yyscan_t yyscanner ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); void yypop_buffer_state ( yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); void *yyalloc ( yy_size_t , yyscan_t yyscanner ); void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); void yyfree ( void * , yyscan_t yyscanner ); /* Begin user sect3 */ #define igraph_pajek_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP #define yytext_ptr yytext_r #ifdef YY_HEADER_EXPORT_START_CONDITIONS #define INITIAL 0 #endif #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif int yylex_init (yyscan_t* scanner); int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( yyscan_t yyscanner ); int yyget_debug ( yyscan_t yyscanner ); void yyset_debug ( int debug_flag , yyscan_t yyscanner ); YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); FILE *yyget_in ( yyscan_t yyscanner ); void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); FILE *yyget_out ( yyscan_t yyscanner ); void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); int yyget_leng ( yyscan_t yyscanner ); char *yyget_text ( yyscan_t yyscanner ); int yyget_lineno ( yyscan_t yyscanner ); void yyset_lineno ( int _line_number , yyscan_t yyscanner ); int yyget_column ( yyscan_t yyscanner ); void yyset_column ( int _column_no , yyscan_t yyscanner ); YYSTYPE * yyget_lval ( yyscan_t yyscanner ); void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( yyscan_t yyscanner ); #else extern int yywrap ( yyscan_t yyscanner ); #endif #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); #define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* yy_get_previous_state - get the state just before the EOB char was reached */ #undef YY_NEW_FILE #undef YY_FLUSH_BUFFER #undef yy_set_bol #undef yy_new_buffer #undef yy_set_interactive #undef YY_DO_BEFORE_ACTION #ifdef YY_DECL_IS_OURS #undef YY_DECL_IS_OURS #undef YY_DECL #endif #ifndef igraph_pajek_yy_create_buffer_ALREADY_DEFINED #undef yy_create_buffer #endif #ifndef igraph_pajek_yy_delete_buffer_ALREADY_DEFINED #undef yy_delete_buffer #endif #ifndef igraph_pajek_yy_scan_buffer_ALREADY_DEFINED #undef yy_scan_buffer #endif #ifndef igraph_pajek_yy_scan_string_ALREADY_DEFINED #undef yy_scan_string #endif #ifndef igraph_pajek_yy_scan_bytes_ALREADY_DEFINED #undef yy_scan_bytes #endif #ifndef igraph_pajek_yy_init_buffer_ALREADY_DEFINED #undef yy_init_buffer #endif #ifndef igraph_pajek_yy_flush_buffer_ALREADY_DEFINED #undef yy_flush_buffer #endif #ifndef igraph_pajek_yy_load_buffer_state_ALREADY_DEFINED #undef yy_load_buffer_state #endif #ifndef igraph_pajek_yy_switch_to_buffer_ALREADY_DEFINED #undef yy_switch_to_buffer #endif #ifndef igraph_pajek_yypush_buffer_state_ALREADY_DEFINED #undef yypush_buffer_state #endif #ifndef igraph_pajek_yypop_buffer_state_ALREADY_DEFINED #undef yypop_buffer_state #endif #ifndef igraph_pajek_yyensure_buffer_stack_ALREADY_DEFINED #undef yyensure_buffer_stack #endif #ifndef igraph_pajek_yylex_ALREADY_DEFINED #undef yylex #endif #ifndef igraph_pajek_yyrestart_ALREADY_DEFINED #undef yyrestart #endif #ifndef igraph_pajek_yylex_init_ALREADY_DEFINED #undef yylex_init #endif #ifndef igraph_pajek_yylex_init_extra_ALREADY_DEFINED #undef yylex_init_extra #endif #ifndef igraph_pajek_yylex_destroy_ALREADY_DEFINED #undef yylex_destroy #endif #ifndef igraph_pajek_yyget_debug_ALREADY_DEFINED #undef yyget_debug #endif #ifndef igraph_pajek_yyset_debug_ALREADY_DEFINED #undef yyset_debug #endif #ifndef igraph_pajek_yyget_extra_ALREADY_DEFINED #undef yyget_extra #endif #ifndef igraph_pajek_yyset_extra_ALREADY_DEFINED #undef yyset_extra #endif #ifndef igraph_pajek_yyget_in_ALREADY_DEFINED #undef yyget_in #endif #ifndef igraph_pajek_yyset_in_ALREADY_DEFINED #undef yyset_in #endif #ifndef igraph_pajek_yyget_out_ALREADY_DEFINED #undef yyget_out #endif #ifndef igraph_pajek_yyset_out_ALREADY_DEFINED #undef yyset_out #endif #ifndef igraph_pajek_yyget_leng_ALREADY_DEFINED #undef yyget_leng #endif #ifndef igraph_pajek_yyget_text_ALREADY_DEFINED #undef yyget_text #endif #ifndef igraph_pajek_yyget_lineno_ALREADY_DEFINED #undef yyget_lineno #endif #ifndef igraph_pajek_yyset_lineno_ALREADY_DEFINED #undef yyset_lineno #endif #ifndef igraph_pajek_yyget_column_ALREADY_DEFINED #undef yyget_column #endif #ifndef igraph_pajek_yyset_column_ALREADY_DEFINED #undef yyset_column #endif #ifndef igraph_pajek_yywrap_ALREADY_DEFINED #undef yywrap #endif #ifndef igraph_pajek_yyget_lval_ALREADY_DEFINED #undef yyget_lval #endif #ifndef igraph_pajek_yyset_lval_ALREADY_DEFINED #undef yyset_lval #endif #ifndef igraph_pajek_yyget_lloc_ALREADY_DEFINED #undef yyget_lloc #endif #ifndef igraph_pajek_yyset_lloc_ALREADY_DEFINED #undef yyset_lloc #endif #ifndef igraph_pajek_yyalloc_ALREADY_DEFINED #undef yyalloc #endif #ifndef igraph_pajek_yyrealloc_ALREADY_DEFINED #undef yyrealloc #endif #ifndef igraph_pajek_yyfree_ALREADY_DEFINED #undef yyfree #endif #ifndef igraph_pajek_yytext_ALREADY_DEFINED #undef yytext #endif #ifndef igraph_pajek_yyleng_ALREADY_DEFINED #undef yyleng #endif #ifndef igraph_pajek_yyin_ALREADY_DEFINED #undef yyin #endif #ifndef igraph_pajek_yyout_ALREADY_DEFINED #undef yyout #endif #ifndef igraph_pajek_yy_flex_debug_ALREADY_DEFINED #undef yy_flex_debug #endif #ifndef igraph_pajek_yylineno_ALREADY_DEFINED #undef yylineno #endif #ifndef igraph_pajek_yytables_fload_ALREADY_DEFINED #undef yytables_fload #endif #ifndef igraph_pajek_yytables_destroy_ALREADY_DEFINED #undef yytables_destroy #endif #ifndef igraph_pajek_yyTABLES_NAME_ALREADY_DEFINED #undef yyTABLES_NAME #endif #line 147 "src/core/io/pajek-lexer.l" #line 735 "src/core/io/pajek-lexer.h" #undef igraph_pajek_yyIN_HEADER #endif /* igraph_pajek_yyHEADER_H */ leidenbase/src/core/io/pajek-parser.y0000644000176200001440000006003314447675374017300 0ustar liggesusers/* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" #include "igraph_attributes.h" #include "config.h" #include "core/math.h" #include "io/pajek-header.h" #include "io/parsers/pajek-parser.h" /* it must come first because of YYSTYPE */ #include "io/parsers/pajek-lexer.h" #include "internal/hacks.h" int igraph_pajek_yyerror(YYLTYPE* locp, igraph_i_pajek_parsedata_t *context, const char *s); int igraph_i_pajek_add_string_vertex_attribute(const char *name, const char *value, int len, igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_add_string_edge_attribute(const char *name, const char *value, int len, igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_add_numeric_vertex_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_add_numeric_edge_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_add_numeric_attribute(igraph_trie_t *names, igraph_vector_ptr_t *attrs, long int count, const char *attrname, igraph_integer_t vid, igraph_real_t number); int igraph_i_pajek_add_string_attribute(igraph_trie_t *names, igraph_vector_ptr_t *attrs, long int count, const char *attrname, igraph_integer_t vid, const char *str); int igraph_i_pajek_add_bipartite_type(igraph_i_pajek_parsedata_t *context); int igraph_i_pajek_check_bipartite(igraph_i_pajek_parsedata_t *context); extern igraph_real_t igraph_pajek_get_number(const char *str, long int len); extern long int igraph_i_pajek_actvertex; extern long int igraph_i_pajek_actedge; #define scanner context->scanner %} %pure-parser /* bison: do not remove the equals sign; macOS XCode ships with bison 2.3, which * needs the equals sign */ %name-prefix="igraph_pajek_yy" %defines %locations %error-verbose %parse-param { igraph_i_pajek_parsedata_t* context } %lex-param { void *scanner } %union { long int intnum; double realnum; struct { char *str; int len; } string; } %type longint; %type arcfrom; %type arcto; %type edgefrom; %type edgeto; %type number; %type word; %type vpwordpar; %type epwordpar; %type vertex; %token NEWLINE %token NUM %token ALNUM %token QSTR %token PSTR %token NETWORKLINE %token VERTICESLINE %token ARCSLINE %token EDGESLINE %token ARCSLISTLINE %token EDGESLISTLINE %token MATRIXLINE %token ERROR %token VP_X_FACT %token VP_Y_FACT %token VP_IC %token VP_BC %token VP_LC %token VP_LR %token VP_LPHI %token VP_BW %token VP_FOS %token VP_PHI %token VP_R %token VP_Q %token VP_LA %token VP_FONT %token VP_URL %token VP_SIZE %token EP_C %token EP_S %token EP_A %token EP_W %token EP_H1 %token EP_H2 %token EP_A1 %token EP_A2 %token EP_K1 %token EP_K2 %token EP_AP %token EP_P %token EP_L %token EP_LP %token EP_LR %token EP_LPHI %token EP_LC %token EP_LA %token EP_SIZE %token EP_FOS %% input: nethead vertices edgeblock { if (context->vcount2 > 0) { igraph_i_pajek_check_bipartite(context); } }; nethead: /* empty */ | NETWORKLINE words NEWLINE; vertices: verticeshead NEWLINE vertdefs; verticeshead: VERTICESLINE longint { context->vcount=$2; context->vcount2=0; } | VERTICESLINE longint longint { context->vcount=$2; context->vcount2=$3; igraph_i_pajek_add_bipartite_type(context); }; vertdefs: /* empty */ | vertdefs vertexline; vertexline: NEWLINE | vertex NEWLINE | vertex { context->actvertex=$1; } vertexid vertexcoords shape params NEWLINE { } ; vertex: longint { $$=$1; context->mode=1; }; vertexid: word { igraph_i_pajek_add_string_vertex_attribute("id", $1.str, $1.len, context); igraph_i_pajek_add_string_vertex_attribute("name", $1.str, $1.len, context); }; vertexcoords: /* empty */ | number number { igraph_i_pajek_add_numeric_vertex_attribute("x", $1, context); igraph_i_pajek_add_numeric_vertex_attribute("y", $2, context); } | number number number { igraph_i_pajek_add_numeric_vertex_attribute("x", $1, context); igraph_i_pajek_add_numeric_vertex_attribute("y", $2, context); igraph_i_pajek_add_numeric_vertex_attribute("z", $3, context); }; shape: /* empty */ | word { igraph_i_pajek_add_string_vertex_attribute("shape", $1.str, $1.len, context); }; params: /* empty */ | params param; param: vpword | VP_X_FACT number { igraph_i_pajek_add_numeric_vertex_attribute("xfact", $2, context); } | VP_Y_FACT number { igraph_i_pajek_add_numeric_vertex_attribute("yfact", $2, context); } | VP_IC number number number { /* RGB color */ igraph_i_pajek_add_numeric_vertex_attribute("color-red", $2, context); igraph_i_pajek_add_numeric_vertex_attribute("color-green", $3, context); igraph_i_pajek_add_numeric_vertex_attribute("color-blue", $4, context); } | VP_BC number number number { igraph_i_pajek_add_numeric_vertex_attribute("framecolor-red", $2, context); igraph_i_pajek_add_numeric_vertex_attribute("framecolor-green", $3, context); igraph_i_pajek_add_numeric_vertex_attribute("framecolor-blue", $4, context); } | VP_LC number number number { igraph_i_pajek_add_numeric_vertex_attribute("labelcolor-red", $2, context); igraph_i_pajek_add_numeric_vertex_attribute("labelcolor-green", $3, context); igraph_i_pajek_add_numeric_vertex_attribute("labelcolor-blue", $4, context); } | VP_LR number { igraph_i_pajek_add_numeric_vertex_attribute("labeldist", $2, context); } | VP_LPHI number { igraph_i_pajek_add_numeric_vertex_attribute("labeldegree2", $2, context); } | VP_BW number { igraph_i_pajek_add_numeric_vertex_attribute("framewidth", $2, context); } | VP_FOS number { igraph_i_pajek_add_numeric_vertex_attribute("fontsize", $2, context); } | VP_PHI number { igraph_i_pajek_add_numeric_vertex_attribute("rotation", $2, context); } | VP_R number { igraph_i_pajek_add_numeric_vertex_attribute("radius", $2, context); } | VP_Q number { igraph_i_pajek_add_numeric_vertex_attribute("diamondratio", $2, context); } | VP_LA number { igraph_i_pajek_add_numeric_vertex_attribute("labeldegree", $2, context); } | VP_SIZE number { igraph_i_pajek_add_numeric_vertex_attribute("vertexsize", $2, context); } ; vpword: VP_FONT { context->mode=3; } vpwordpar { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("font", $3.str, $3.len, context); } | VP_URL { context->mode=3; } vpwordpar { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("url", $3.str, $3.len, context); } | VP_IC { context->mode=3; } vpwordpar { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("color", $3.str, $3.len, context); } | VP_BC { context->mode=3; } vpwordpar { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("framecolor", $3.str, $3.len, context); } | VP_LC { context->mode=3; } vpwordpar { context->mode=1; igraph_i_pajek_add_string_vertex_attribute("labelcolor", $3.str, $3.len, context); } ; vpwordpar: word { $$=$1; }; edgeblock: /* empty */ | edgeblock arcs | edgeblock edges | edgeblock arcslist | edgeblock edgeslist | edgeblock adjmatrix; arcs: ARCSLINE NEWLINE arcsdefs { context->directed=1; } | ARCSLINE number NEWLINE arcsdefs { context->directed=1; }; arcsdefs: /* empty */ | arcsdefs arcsline; arcsline: NEWLINE | arcfrom arcto { context->actedge++; context->mode=2; } weight edgeparams NEWLINE { igraph_vector_push_back(context->vector, $1-1); igraph_vector_push_back(context->vector, $2-1); } ; arcfrom: longint; arcto: longint; edges: EDGESLINE NEWLINE edgesdefs { context->directed=0; } | EDGESLINE number NEWLINE edgesdefs { context->directed=0; } edgesdefs: /* empty */ | edgesdefs edgesline; edgesline: NEWLINE | edgefrom edgeto { context->actedge++; context->mode=2; } weight edgeparams NEWLINE { igraph_vector_push_back(context->vector, $1-1); igraph_vector_push_back(context->vector, $2-1); } ; edgefrom: longint; edgeto: longint; weight: /* empty */ | number { igraph_i_pajek_add_numeric_edge_attribute("weight", $1, context); }; edgeparams: /* empty */ | edgeparams edgeparam; edgeparam: epword | EP_C number number number { igraph_i_pajek_add_numeric_edge_attribute("color-red", $2, context); igraph_i_pajek_add_numeric_edge_attribute("color-green", $3, context); igraph_i_pajek_add_numeric_edge_attribute("color-blue", $4, context); } | EP_S number { igraph_i_pajek_add_numeric_edge_attribute("arrowsize", $2, context); } | EP_W number { igraph_i_pajek_add_numeric_edge_attribute("edgewidth", $2, context); } | EP_H1 number { igraph_i_pajek_add_numeric_edge_attribute("hook1", $2, context); } | EP_H2 number { igraph_i_pajek_add_numeric_edge_attribute("hook2", $2, context); } | EP_A1 number { igraph_i_pajek_add_numeric_edge_attribute("angle1", $2, context); } | EP_A2 number { igraph_i_pajek_add_numeric_edge_attribute("angle2", $2, context); } | EP_K1 number { igraph_i_pajek_add_numeric_edge_attribute("velocity1", $2, context); } | EP_K2 number { igraph_i_pajek_add_numeric_edge_attribute("velocity2", $2, context); } | EP_AP number { igraph_i_pajek_add_numeric_edge_attribute("arrowpos", $2, context); } | EP_LP number { igraph_i_pajek_add_numeric_edge_attribute("labelpos", $2, context); } | EP_LR number { igraph_i_pajek_add_numeric_edge_attribute("labelangle", $2, context); } | EP_LPHI number { igraph_i_pajek_add_numeric_edge_attribute("labelangle2", $2, context); } | EP_LA number { igraph_i_pajek_add_numeric_edge_attribute("labeldegree", $2, context); } | EP_SIZE number { /* what is this??? */ igraph_i_pajek_add_numeric_edge_attribute("arrowsize", $2, context); } | EP_FOS number { igraph_i_pajek_add_numeric_edge_attribute("fontsize", $2, context); } ; epword: EP_A { context->mode=4; } epwordpar { context->mode=2; igraph_i_pajek_add_string_edge_attribute("arrowtype", $3.str, $3.len, context); } | EP_P { context->mode=4; } epwordpar { context->mode=2; igraph_i_pajek_add_string_edge_attribute("linepattern", $3.str, $3.len, context); } | EP_L { context->mode=4; } epwordpar { context->mode=2; igraph_i_pajek_add_string_edge_attribute("label", $3.str, $3.len, context); } | EP_LC { context->mode=4; } epwordpar { context->mode=2; igraph_i_pajek_add_string_edge_attribute("labelcolor", $3.str, $3.len, context); } | EP_C { context->mode=4; } epwordpar { context->mode=2; igraph_i_pajek_add_string_edge_attribute("color", $3.str, $3.len, context); } ; epwordpar: word { context->mode=2; $$=$1; }; arcslist: ARCSLISTLINE NEWLINE arcslistlines { context->directed=1; }; arcslistlines: /* empty */ | arcslistlines arclistline; arclistline: NEWLINE | arclistfrom arctolist NEWLINE; arctolist: /* empty */ | arctolist arclistto; arclistfrom: longint { context->mode=0; context->actfrom=labs($1)-1; }; arclistto: longint { igraph_vector_push_back(context->vector, context->actfrom); igraph_vector_push_back(context->vector, labs($1)-1); }; edgeslist: EDGESLISTLINE NEWLINE edgelistlines { context->directed=0; }; edgelistlines: /* empty */ | edgelistlines edgelistline; edgelistline: NEWLINE | edgelistfrom edgetolist NEWLINE; edgetolist: /* empty */ | edgetolist edgelistto; edgelistfrom: longint { context->mode=0; context->actfrom=labs($1)-1; }; edgelistto: longint { igraph_vector_push_back(context->vector, context->actfrom); igraph_vector_push_back(context->vector, labs($1)-1); }; /* -----------------------------------------------------*/ adjmatrix: matrixline NEWLINE adjmatrixlines; matrixline: MATRIXLINE { context->actfrom=0; context->actto=0; context->directed=(context->vcount2==0); }; adjmatrixlines: /* empty */ | adjmatrixlines adjmatrixline; adjmatrixline: adjmatrixnumbers NEWLINE { context->actfrom++; context->actto=0; }; adjmatrixnumbers: /* empty */ | adjmatrixentry adjmatrixnumbers; adjmatrixentry: number { if ($1 != 0) { if (context->vcount2==0) { context->actedge++; igraph_i_pajek_add_numeric_edge_attribute("weight", $1, context); igraph_vector_push_back(context->vector, context->actfrom); igraph_vector_push_back(context->vector, context->actto); } else if (context->vcount2 + context->actto < context->vcount) { context->actedge++; igraph_i_pajek_add_numeric_edge_attribute("weight", $1, context); igraph_vector_push_back(context->vector, context->actfrom); igraph_vector_push_back(context->vector, context->vcount2+context->actto); } } context->actto++; }; /* -----------------------------------------------------*/ longint: NUM { $$=igraph_pajek_get_number(igraph_pajek_yyget_text(scanner), igraph_pajek_yyget_leng(scanner)); }; number: NUM { $$=igraph_pajek_get_number(igraph_pajek_yyget_text(scanner), igraph_pajek_yyget_leng(scanner)); }; words: /* empty */ | words word; word: ALNUM { $$.str=igraph_pajek_yyget_text(scanner); $$.len=igraph_pajek_yyget_leng(scanner); } | NUM { $$.str=igraph_pajek_yyget_text(scanner); $$.len=igraph_pajek_yyget_leng(scanner); } | QSTR { $$.str=igraph_pajek_yyget_text(scanner)+1; $$.len=igraph_pajek_yyget_leng(scanner)-2; }; %% int igraph_pajek_yyerror(YYLTYPE* locp, igraph_i_pajek_parsedata_t *context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char)-1, "Parse error in Pajek file, line %i (%s)", locp->first_line, s); return 0; } igraph_real_t igraph_pajek_get_number(const char *str, long int length) { igraph_real_t num; char *tmp=IGRAPH_CALLOC(length+1, char); strncpy(tmp, str, length); tmp[length]='\0'; sscanf(tmp, "%lf", &num); IGRAPH_FREE(tmp); return num; } /* TODO: NA's */ int igraph_i_pajek_add_numeric_attribute(igraph_trie_t *names, igraph_vector_ptr_t *attrs, long int count, const char *attrname, igraph_integer_t vid, igraph_real_t number) { long int attrsize=igraph_trie_size(names); long int id; igraph_vector_t *na; igraph_attribute_record_t *rec; igraph_trie_get(names, attrname, &id); if (id == attrsize) { /* add a new attribute */ rec=IGRAPH_CALLOC(1, igraph_attribute_record_t); na=IGRAPH_CALLOC(1, igraph_vector_t); igraph_vector_init(na, count); rec->name=strdup(attrname); rec->type=IGRAPH_ATTRIBUTE_NUMERIC; rec->value=na; igraph_vector_ptr_push_back(attrs, rec); } rec=VECTOR(*attrs)[id]; na=(igraph_vector_t*)rec->value; if (igraph_vector_size(na) == vid) { IGRAPH_CHECK(igraph_vector_push_back(na, number)); } else if (igraph_vector_size(na) < vid) { long int origsize=igraph_vector_size(na); IGRAPH_CHECK(igraph_vector_resize(na, (long int)vid+1)); for (;origsizename=strdup(attrname); rec->type=IGRAPH_ATTRIBUTE_STRING; rec->value=na; igraph_vector_ptr_push_back(attrs, rec); } rec=VECTOR(*attrs)[id]; na=(igraph_strvector_t*)rec->value; if (igraph_strvector_size(na) <= vid) { long int origsize=igraph_strvector_size(na); IGRAPH_CHECK(igraph_strvector_resize(na, vid+1)); for (;origsizevertex_attribute_names, context->vertex_attributes, context->vcount, name, context->actvertex-1, tmp); IGRAPH_FREE(tmp); IGRAPH_FINALLY_CLEAN(1); return ret; } int igraph_i_pajek_add_string_edge_attribute(const char *name, const char *value, int len, igraph_i_pajek_parsedata_t *context) { char *tmp; int ret; tmp=IGRAPH_CALLOC(len+1, char); if (tmp==0) { IGRAPH_ERROR("cannot add element to hash table", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmp); strncpy(tmp, value, len); tmp[len]='\0'; ret=igraph_i_pajek_add_string_attribute(context->edge_attribute_names, context->edge_attributes, context->actedge, name, context->actedge-1, tmp); IGRAPH_FREE(tmp); IGRAPH_FINALLY_CLEAN(1); return ret; } int igraph_i_pajek_add_numeric_vertex_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context) { return igraph_i_pajek_add_numeric_attribute(context->vertex_attribute_names, context->vertex_attributes, context->vcount, name, context->actvertex-1, value); } int igraph_i_pajek_add_numeric_edge_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context) { return igraph_i_pajek_add_numeric_attribute(context->edge_attribute_names, context->edge_attributes, context->actedge, name, context->actedge-1, value); } int igraph_i_pajek_add_bipartite_type(igraph_i_pajek_parsedata_t *context) { const char *attrname="type"; igraph_trie_t *names=context->vertex_attribute_names; igraph_vector_ptr_t *attrs=context->vertex_attributes; int i, n=context->vcount, n1=context->vcount2; long int attrid, attrsize=igraph_trie_size(names); igraph_attribute_record_t *rec; igraph_vector_t *na; if (n1 > n) { IGRAPH_ERROR("Invalid number of vertices in bipartite Pajek file", IGRAPH_PARSEERROR); } igraph_trie_get(names, attrname, &attrid); if (attrid != attrsize) { IGRAPH_ERROR("Duplicate 'type' attribute in Pajek file, " "this should not happen", IGRAPH_EINTERNAL); } /* add a new attribute */ rec=IGRAPH_CALLOC(1, igraph_attribute_record_t); na=IGRAPH_CALLOC(1, igraph_vector_t); igraph_vector_init(na, n); rec->name=strdup(attrname); rec->type=IGRAPH_ATTRIBUTE_NUMERIC; rec->value=na; igraph_vector_ptr_push_back(attrs, rec); for (i=0; ivector; int i, n1=context->vcount2; int ne=igraph_vector_size(edges); for (i=0; i n1 && v2 > n1) ) { IGRAPH_WARNING("Invalid edge in bipartite graph"); } } return 0; } leidenbase/src/core/io/dl-parser.y0000644000176200001440000002333014447675374016604 0ustar liggesusers/* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ %{ /* IGraph library. Copyright (C) 2009-2012 Gabor Csardi 334 Harvard st, Cambridge, MA, 02138 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include "core/math.h" #include "internal/hacks.h" #include "io/dl-header.h" #include "io/parsers/dl-parser.h" #include "io/parsers/dl-lexer.h" #include int igraph_dl_yyerror(YYLTYPE* locp, igraph_i_dl_parsedata_t* context, const char *s); int igraph_i_dl_add_str(char *newstr, int length, igraph_i_dl_parsedata_t *context); int igraph_i_dl_add_edge(long int from, long int to, igraph_i_dl_parsedata_t *context); int igraph_i_dl_add_edge_w(long int from, long int to, igraph_real_t weight, igraph_i_dl_parsedata_t *context); extern igraph_real_t igraph_pajek_get_number(const char *str, long int len); #define scanner context->scanner %} %pure-parser /* bison: do not remove the equals sign; macOS XCode ships with bison 2.3, which * needs the equals sign */ %name-prefix="igraph_dl_yy" %defines %locations %error-verbose %parse-param { igraph_i_dl_parsedata_t* context } %lex-param { void* scanner } %union { long int integer; igraph_real_t real; }; %type integer elabel; %type weight; %token NUM %token NEWLINE %token DL %token NEQ %token DATA %token LABELS %token LABELSEMBEDDED %token FORMATFULLMATRIX %token FORMATEDGELIST1 %token FORMATNODELIST1 %token DIGIT %token LABEL %token EOFF %token ERROR %% input: DL NEQ integer NEWLINE rest trail eof { context->n=$3; }; trail: | trail newline; eof: | EOFF; rest: formfullmatrix { context->type=IGRAPH_DL_MATRIX; } | edgelist1 { context->type=IGRAPH_DL_EDGELIST1; } | nodelist1 { context->type=IGRAPH_DL_NODELIST1; } ; formfullmatrix: FORMATFULLMATRIX newline fullmatrix {} | fullmatrix {} ; newline: | NEWLINE ; fullmatrix: DATA newline fullmatrixdata { } | LABELS newline labels newline DATA newline fullmatrixdata { } | LABELSEMBEDDED newline DATA newline labeledfullmatrixdata { } ; labels: {} /* nothing, empty matrix */ | labels newline LABEL { igraph_i_dl_add_str(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner), context); } ; fullmatrixdata: {} | fullmatrixdata zerooneseq NEWLINE { context->from += 1; context->to = 0; } ; zerooneseq: | zerooneseq zeroone { } ; zeroone: DIGIT { if (igraph_dl_yyget_text(scanner)[0]=='1') { IGRAPH_CHECK(igraph_vector_push_back(&context->edges, context->from)); IGRAPH_CHECK(igraph_vector_push_back(&context->edges, context->to)); } context->to += 1; } ; labeledfullmatrixdata: reallabeledfullmatrixdata {} ; reallabeledfullmatrixdata: labelseq NEWLINE labeledmatrixlines {} ; labelseq: | labelseq newline label ; label: LABEL { igraph_i_dl_add_str(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner), context); }; labeledmatrixlines: labeledmatrixline { context->from += 1; context->to = 0; } | labeledmatrixlines labeledmatrixline { context->from += 1; context->to = 0; }; labeledmatrixline: LABEL zerooneseq NEWLINE { } ; /*-----------------------------------------------------------*/ edgelist1: FORMATEDGELIST1 newline edgelist1rest {} ; edgelist1rest: DATA newline edgelist1data {} | LABELS newline labels newline DATA newline edgelist1data {} | LABELSEMBEDDED newline DATA newline labelededgelist1data {} | LABELS newline labels newline LABELSEMBEDDED newline DATA newline labelededgelist1data {} | LABELSEMBEDDED newline LABELS newline labels newline DATA newline labelededgelist1data {} ; edgelist1data: {} /* nothing, empty graph */ | edgelist1data edgelist1dataline {} ; edgelist1dataline: integer integer weight NEWLINE { igraph_i_dl_add_edge_w($1-1, $2-1, $3, context); } | integer integer NEWLINE { igraph_i_dl_add_edge($1-1, $2-1, context); } ; integer: NUM { $$=igraph_pajek_get_number(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner)); }; labelededgelist1data: {} /* nothing, empty graph */ | labelededgelist1data labelededgelist1dataline {} ; labelededgelist1dataline: elabel elabel weight NEWLINE { igraph_i_dl_add_edge_w($1, $2, $3, context); } | elabel elabel NEWLINE { igraph_i_dl_add_edge($1, $2, context); }; weight: NUM { $$=igraph_pajek_get_number(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner)); }; elabel: LABEL { /* Copy label list to trie, if needed */ if (igraph_strvector_size(&context->labels) != 0) { long int i, id, n=igraph_strvector_size(&context->labels); for (i=0; itrie, STR(context->labels, i), &id); } igraph_strvector_clear(&context->labels); } igraph_trie_get2(&context->trie, igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner), &$$); }; /*-----------------------------------------------------------*/ nodelist1: FORMATNODELIST1 newline nodelist1rest {} ; nodelist1rest: DATA nodelist1data {} | LABELS newline labels newline DATA newline nodelist1data {} | LABELSEMBEDDED newline DATA newline labelednodelist1data {} | LABELS newline labels newline LABELSEMBEDDED newline DATA newline labelednodelist1data {} | LABELSEMBEDDED newline LABELS newline labels newline DATA newline labelednodelist1data {} ; nodelist1data: {} /* nothing, empty graph */ | nodelist1data nodelist1dataline {} ; nodelist1dataline: from tolist NEWLINE {} ; from: NUM { context->from=igraph_pajek_get_number(igraph_dl_yyget_text(scanner), igraph_dl_yyget_leng(scanner)); } ; tolist: {} | tolist integer { IGRAPH_CHECK(igraph_vector_push_back(&context->edges, context->from-1)); IGRAPH_CHECK(igraph_vector_push_back(&context->edges, $2-1)); } ; labelednodelist1data: {} /* nothing, empty graph */ | labelednodelist1data labelednodelist1dataline {} ; labelednodelist1dataline: fromelabel labeltolist NEWLINE { } ; fromelabel: elabel { context->from=$1; }; labeltolist: | labeltolist elabel { IGRAPH_CHECK(igraph_vector_push_back(&context->edges, context->from)); IGRAPH_CHECK(igraph_vector_push_back(&context->edges, $2)); } ; %% int igraph_dl_yyerror(YYLTYPE* locp, igraph_i_dl_parsedata_t* context, const char *s) { snprintf(context->errmsg, sizeof(context->errmsg)/sizeof(char)-1, "%s in line %i", s, locp->first_line); return 0; } int igraph_i_dl_add_str(char *newstr, int length, igraph_i_dl_parsedata_t *context) { int tmp=newstr[length]; newstr[length]='\0'; IGRAPH_CHECK(igraph_strvector_add(&context->labels, newstr)); newstr[length]=tmp; return 0; } int igraph_i_dl_add_edge(long int from, long int to, igraph_i_dl_parsedata_t *context) { IGRAPH_CHECK(igraph_vector_push_back(&context->edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&context->edges, to)); return 0; } int igraph_i_dl_add_edge_w(long int from, long int to, igraph_real_t weight, igraph_i_dl_parsedata_t *context) { long int n=igraph_vector_size(&context->weights); long int n2=igraph_vector_size(&context->edges)/2; if (n != n2) { igraph_vector_resize(&context->weights, n2); for (; nweights)[n]=IGRAPH_NAN; } } IGRAPH_CHECK(igraph_i_dl_add_edge(from, to, context)); IGRAPH_CHECK(igraph_vector_push_back(&context->weights, weight)); return 0; } leidenbase/src/core/io/pajek-parser.h0000644000176200001440000001243014447675375017256 0ustar liggesusers/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ #ifndef YY_IGRAPH_PAJEK_YY_YY_TAB_H_INCLUDED # define YY_IGRAPH_PAJEK_YY_YY_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int igraph_pajek_yydebug; #endif /* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { YYEMPTY = -2, YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ NEWLINE = 258, /* NEWLINE */ NUM = 259, /* NUM */ ALNUM = 260, /* ALNUM */ QSTR = 261, /* QSTR */ PSTR = 262, /* PSTR */ NETWORKLINE = 263, /* NETWORKLINE */ VERTICESLINE = 264, /* VERTICESLINE */ ARCSLINE = 265, /* ARCSLINE */ EDGESLINE = 266, /* EDGESLINE */ ARCSLISTLINE = 267, /* ARCSLISTLINE */ EDGESLISTLINE = 268, /* EDGESLISTLINE */ MATRIXLINE = 269, /* MATRIXLINE */ ERROR = 270, /* ERROR */ VP_X_FACT = 271, /* VP_X_FACT */ VP_Y_FACT = 272, /* VP_Y_FACT */ VP_IC = 273, /* VP_IC */ VP_BC = 274, /* VP_BC */ VP_LC = 275, /* VP_LC */ VP_LR = 276, /* VP_LR */ VP_LPHI = 277, /* VP_LPHI */ VP_BW = 278, /* VP_BW */ VP_FOS = 279, /* VP_FOS */ VP_PHI = 280, /* VP_PHI */ VP_R = 281, /* VP_R */ VP_Q = 282, /* VP_Q */ VP_LA = 283, /* VP_LA */ VP_FONT = 284, /* VP_FONT */ VP_URL = 285, /* VP_URL */ VP_SIZE = 286, /* VP_SIZE */ EP_C = 287, /* EP_C */ EP_S = 288, /* EP_S */ EP_A = 289, /* EP_A */ EP_W = 290, /* EP_W */ EP_H1 = 291, /* EP_H1 */ EP_H2 = 292, /* EP_H2 */ EP_A1 = 293, /* EP_A1 */ EP_A2 = 294, /* EP_A2 */ EP_K1 = 295, /* EP_K1 */ EP_K2 = 296, /* EP_K2 */ EP_AP = 297, /* EP_AP */ EP_P = 298, /* EP_P */ EP_L = 299, /* EP_L */ EP_LP = 300, /* EP_LP */ EP_LR = 301, /* EP_LR */ EP_LPHI = 302, /* EP_LPHI */ EP_LC = 303, /* EP_LC */ EP_LA = 304, /* EP_LA */ EP_SIZE = 305, /* EP_SIZE */ EP_FOS = 306 /* EP_FOS */ }; typedef enum yytokentype yytoken_kind_t; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 115 "src/core/io/pajek-parser.y" long int intnum; double realnum; struct { char *str; int len; } string; #line 124 "yy.tab.h" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif /* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE YYLTYPE; struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; }; # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif int igraph_pajek_yyparse (igraph_i_pajek_parsedata_t* context); #endif /* !YY_IGRAPH_PAJEK_YY_YY_TAB_H_INCLUDED */ leidenbase/src/core/io/pajek.c0000644000176200001440000007306714447675374015773 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_attributes.h" #include "igraph_error.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "graph/attributes.h" #include "pajek-header.h" #include #include int igraph_pajek_yylex_init_extra(igraph_i_pajek_parsedata_t* user_defined, void* scanner); void igraph_pajek_yylex_destroy (void *scanner ); int igraph_pajek_yyparse (igraph_i_pajek_parsedata_t* context); void igraph_pajek_yyset_in (FILE * in_str, void* yyscanner ); /** * \function igraph_read_graph_pajek * \brief Reads a file in Pajek format * * \param graph Pointer to an uninitialized graph object. * \param file An already opened file handler. * \return Error code. * * * Only a subset of the Pajek format is implemented. This is partially * because this format is not very well documented, but also because * igraph does not support some Pajek features, like * multigraphs. * * * Starting from version 0.6.1 igraph reads bipartite (two-mode) * graphs from Pajek files and add the \c type vertex attribute for them. * Warnings are given for invalid edges, i.e. edges connecting * vertices of the same type. * * * The list of the current limitations: * \olist * \oli Only .net files are supported, Pajek * project files (.paj) are not. These might be * supported in the future if there is need for it. * \oli Time events networks are not supported. * \oli Hypergraphs (i.e. graphs with non-binary edges) are not * supported. * \oli Graphs with both directed and non-directed edges are not * supported, are they cannot be represented in * igraph. * \oli Only Pajek networks are supported, permutations, hierarchies, * clusters and vectors are not. * \oli Graphs with multiple edge sets are not supported. * \endolist * * * If there are attribute handlers installed, * igraph also reads the vertex and edge attributes * from the file. Most attributes are renamed to be more informative: * \c color instead of \c c, \c xfact instead of \c x_fact, * \c yfact instead of y_fact, \c labeldist instead of \c lr, * \c labeldegree2 instead of \c lphi, \c framewidth instead of \c bw, * \c fontsize * instead of \c fos, \c rotation instead of \c phi, \c radius instead * of \c r, * \c diamondratio instead of \c q, \c labeldegree instead of \c la, * \c vertexsize * instead of \c size, \c color instead of \c ic, \c framecolor instead of * \c bc, \c labelcolor instead of \c lc, these belong to vertices. * * * Edge attributes are also renamed, \c s to \c arrowsize, \c w * to \c edgewidth, \c h1 to \c hook1, \c h2 to \c hook2, * \c a1 to \c angle1, \c a2 to \c angle2, \c k1 to * \c velocity1, \c k2 to \c velocity2, \c ap to \c * arrowpos, \c lp to \c labelpos, \c lr to * \c labelangle, \c lphi to \c labelangle2, \c la to \c * labeldegree, \c fos to * \c fontsize, \c a to \c arrowtype, \c p to \c * linepattern, \c l to \c label, \c lc to * \c labelcolor, \c c to \c color. * * * In addition the following vertex attributes might be added: \c id * if there are vertex ids in the file, \c x and \c y or \c x * and \c y and \c z if there are vertex coordinates in the file. * * The \c weight edge attribute might be * added if there are edge weights present. * * * See the pajek homepage: * http://vlado.fmf.uni-lj.si/pub/networks/pajek/ for more info on * Pajek and the Pajek manual: * http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/pajekman.pdf for * information on the Pajek file format. * * * Time complexity: O(|V|+|E|+|A|), |V| is the number of vertices, |E| * the number of edges, |A| the number of attributes (vertex + edge) * in the graph if there are attribute handlers installed. * * \sa \ref igraph_write_graph_pajek() for writing Pajek files, \ref * igraph_read_graph_graphml() for reading GraphML files. * * \example examples/simple/foreign.c */ int igraph_read_graph_pajek(igraph_t *graph, FILE *instream) { igraph_vector_t edges; igraph_trie_t vattrnames; igraph_vector_ptr_t vattrs; igraph_trie_t eattrnames; igraph_vector_ptr_t eattrs; long int i, j; igraph_i_pajek_parsedata_t context; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_TRIE_INIT_FINALLY(&vattrnames, 1); IGRAPH_VECTOR_PTR_INIT_FINALLY(&vattrs, 0); IGRAPH_TRIE_INIT_FINALLY(&eattrnames, 1); IGRAPH_VECTOR_PTR_INIT_FINALLY(&eattrs, 0); context.vector = &edges; context.mode = 0; context.vcount = -1; context.vertexid = 0; context.vertex_attribute_names = &vattrnames; context.vertex_attributes = &vattrs; context.edge_attribute_names = &eattrnames; context.edge_attributes = &eattrs; context.actedge = 0; context.eof = 0; igraph_pajek_yylex_init_extra(&context, &context.scanner); IGRAPH_FINALLY(igraph_pajek_yylex_destroy, context.scanner); igraph_pajek_yyset_in(instream, context.scanner); if (igraph_pajek_yyparse(&context)) { if (context.errmsg[0] != 0) { IGRAPH_ERROR(context.errmsg, IGRAPH_PARSEERROR); } else { IGRAPH_ERROR("Cannot read Pajek file", IGRAPH_PARSEERROR); } } if (context.vcount < 0) { IGRAPH_ERROR("invalid vertex count in Pajek file", IGRAPH_EINVAL); } if (context.vcount2 < 0) { IGRAPH_ERROR("invalid 2-mode vertex count in Pajek file", IGRAPH_EINVAL); } for (i = 0; i < igraph_vector_ptr_size(&eattrs); i++) { igraph_attribute_record_t *rec = VECTOR(eattrs)[i]; if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *vec = (igraph_vector_t*)rec->value; long int origsize = igraph_vector_size(vec); igraph_vector_resize(vec, context.actedge); for (j = origsize; j < context.actedge; j++) { VECTOR(*vec)[j] = IGRAPH_NAN; } } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strvec = (igraph_strvector_t*)rec->value; long int origsize = igraph_strvector_size(strvec); igraph_strvector_resize(strvec, context.actedge); for (j = origsize; j < context.actedge; j++) { igraph_strvector_set(strvec, j, ""); } } } IGRAPH_CHECK(igraph_empty(graph, 0, context.directed)); IGRAPH_FINALLY(igraph_destroy, graph); IGRAPH_CHECK(igraph_add_vertices(graph, context.vcount, &vattrs)); IGRAPH_CHECK(igraph_add_edges(graph, &edges, &eattrs)); for (i = 0; i < igraph_vector_ptr_size(&vattrs); i++) { igraph_attribute_record_t *rec = VECTOR(vattrs)[i]; if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *vec = (igraph_vector_t*) rec->value; igraph_vector_destroy(vec); IGRAPH_FREE(vec); } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strvec = (igraph_strvector_t *)rec->value; igraph_strvector_destroy(strvec); IGRAPH_FREE(strvec); } igraph_free( (char*)(rec->name)); IGRAPH_FREE(rec); } for (i = 0; i < igraph_vector_ptr_size(&eattrs); i++) { igraph_attribute_record_t *rec = VECTOR(eattrs)[i]; if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *vec = (igraph_vector_t*) rec->value; igraph_vector_destroy(vec); IGRAPH_FREE(vec); } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strvec = (igraph_strvector_t *)rec->value; igraph_strvector_destroy(strvec); IGRAPH_FREE(strvec); } igraph_free( (char*)(rec->name)); IGRAPH_FREE(rec); } igraph_vector_destroy(&edges); igraph_vector_ptr_destroy(&eattrs); igraph_trie_destroy(&eattrnames); igraph_vector_ptr_destroy(&vattrs); igraph_trie_destroy(&vattrnames); igraph_pajek_yylex_destroy(context.scanner); IGRAPH_FINALLY_CLEAN(7); return 0; } /* Order matters here! */ #define V_ID 0 #define V_X 1 #define V_Y 2 #define V_Z 3 #define V_SHAPE 4 #define V_XFACT 5 #define V_YFACT 6 #define V_COLOR_RED 7 #define V_COLOR_GREEN 8 #define V_COLOR_BLUE 9 #define V_FRAMECOLOR_RED 10 #define V_FRAMECOLOR_GREEN 11 #define V_FRAMECOLOR_BLUE 12 #define V_LABELCOLOR_RED 13 #define V_LABELCOLOR_GREEN 14 #define V_LABELCOLOR_BLUE 15 #define V_LABELDIST 16 #define V_LABELDEGREE2 17 #define V_FRAMEWIDTH 18 #define V_FONTSIZE 19 #define V_ROTATION 20 #define V_RADIUS 21 #define V_DIAMONDRATIO 22 #define V_LABELDEGREE 23 #define V_VERTEXSIZE 24 #define V_FONT 25 #define V_URL 26 #define V_COLOR 27 #define V_FRAMECOLOR 28 #define V_LABELCOLOR 29 #define V_LAST 30 #define E_WEIGHT 0 #define E_COLOR_RED 1 #define E_COLOR_GREEN 2 #define E_COLOR_BLUE 3 #define E_ARROWSIZE 4 #define E_EDGEWIDTH 5 #define E_HOOK1 6 #define E_HOOK2 7 #define E_ANGLE1 8 #define E_ANGLE2 9 #define E_VELOCITY1 10 #define E_VELOCITY2 11 #define E_ARROWPOS 12 #define E_LABELPOS 13 #define E_LABELANGLE 14 #define E_LABELANGLE2 15 #define E_LABELDEGREE 16 #define E_FONTSIZE 17 #define E_ARROWTYPE 18 #define E_LINEPATTERN 19 #define E_LABEL 20 #define E_LABELCOLOR 21 #define E_COLOR 22 #define E_LAST 23 static int igraph_i_pajek_escape(char* src, char** dest) { long int destlen = 0; igraph_bool_t need_escape = 0; /* Determine whether the string contains characters to be escaped */ char *s, *d; for (s = src; *s; s++, destlen++) { if (*s == '\\') { need_escape = 1; destlen++; } else if (*s == '"') { need_escape = 1; destlen++; } else if (!isalnum(*s)) { need_escape = 1; } } if (!need_escape) { /* At this point, we know that the string does not contain any chars * that would warrant escaping. Therefore, we simply quote it and * return the quoted string. This is necessary because Pajek uses some * reserved words in its format (like 'c' standing for color) and they * have to be quoted as well. */ *dest = IGRAPH_CALLOC(destlen + 3, char); if (!*dest) { IGRAPH_ERROR("Not enough memory", IGRAPH_ENOMEM); } d = *dest; strcpy(d + 1, src); d[0] = d[destlen + 1] = '"'; d[destlen + 2] = 0; return IGRAPH_SUCCESS; } *dest = IGRAPH_CALLOC(destlen + 3, char); if (!*dest) { IGRAPH_ERROR("Not enough memory", IGRAPH_ENOMEM); } d = *dest; *d = '"'; d++; for (s = src; *s; s++, d++) { switch (*s) { case '\\': case '"': *d = '\\'; d++; *d = *s; break; default: *d = *s; } } *d = '"'; d++; *d = 0; return IGRAPH_SUCCESS; } /** * \function igraph_write_graph_pajek * \brief Writes a graph to a file in Pajek format. * * * The Pajek vertex and edge parameters (like color) are determined by * the attributes of the vertices and edges, of course this requires * an attribute handler to be installed. The names of the * corresponding vertex and edge attributes are listed at \ref * igraph_read_graph_pajek(), e.g. the \c color vertex attributes * determines the color (\c c in Pajek) parameter. * * * As of version 0.6.1 igraph writes bipartite graphs into Pajek files * correctly, i.e. they will be also bipartite when read into Pajek. * As Pajek is less flexible for bipartite graphs (the numeric IDs of * the vertices must be sorted according to vertex type), igraph might * need to reorder the vertices when writing a bipartite Pajek file. * This effectively means that numeric vertex IDs usually change when * a bipartite graph is written to a Pajek file, and then read back * into igraph. * * * Early versions of Pajek supported only Windows-style line endings * in Pajek files, but recent versions support both Windows and Unix * line endings. igraph therefore uses the platform-native line endings * when the input file is opened in text mode, and uses Unix-style * line endings when the input file is opened in binary mode. If you * are using an old version of Pajek, you are on Unix and you are having * problems reading files written by igraph on a Windows machine, convert the * line endings manually with a text editor or with \c unix2dos or \c iconv * from the command line). * * \param graph The graph object to write. * \param outstream The file to write to. It should be opened and * writable. Make sure that you open the file in binary format if you use MS Windows, * otherwise end of line characters will be messed up. (igraph will be able * to read back these messed up files, but Pajek won't.) * \return Error code. * * Time complexity: O(|V|+|E|+|A|), |V| is the number of vertices, |E| * is the number of edges, |A| the number of attributes (vertex + * edge) in the graph if there are attribute handlers installed. * * \sa \ref igraph_read_graph_pajek() for reading Pajek graphs, \ref * igraph_write_graph_graphml() for writing a graph in GraphML format, * this suites igraph graphs better. * * \example examples/simple/igraph_write_graph_pajek.c */ int igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream) { long int no_of_nodes = igraph_vcount(graph); long int i, j; igraph_attribute_type_t vtypes[V_LAST], etypes[E_LAST]; igraph_bool_t write_vertex_attrs = 0; /* Same order as the #define's */ const char *vnames[] = { "id", "x", "y", "z", "shape", "xfact", "yfact", "", "", "", "", "", "", "", "", "", "labeldist", "labeldegree2", "framewidth", "fontsize", "rotation", "radius", "diamondratio", "labeldegree", "vertexsize", "font", "url", "color", "framecolor", "labelcolor" }; const char *vnumnames[] = { "xfact", "yfact", "labeldist", "labeldegree2", "framewidth", "fontsize", "rotation", "radius", "diamondratio", "labeldegree", "vertexsize" }; const char *vnumnames2[] = { "x_fact", "y_fact", "lr", "lphi", "bw", "fos", "phi", "r", "q", "la", "size" }; const char *vstrnames[] = { "font", "url", "color", "framecolor", "labelcolor" }; const char *vstrnames2[] = { "font", "url", "ic", "bc", "lc" }; const char *enames[] = { "weight", "", "", "", "arrowsize", "edgewidth", "hook1", "hook2", "angle1", "angle2", "velocity1", "velocity2", "arrowpos", "labelpos", "labelangle", "labelangle2", "labeldegree", "fontsize", "arrowtype", "linepattern", "label", "labelcolor", "color" }; const char *enumnames[] = { "arrowsize", "edgewidth", "hook1", "hook2", "angle1", "angle2", "velocity1", "velocity2", "arrowpos", "labelpos", "labelangle", "labelangle2", "labeldegree", "fontsize" }; const char *enumnames2[] = { "s", "w", "h1", "h2", "a1", "a2", "k1", "k2", "ap", "lp", "lr", "lphi", "la", "fos" }; const char *estrnames[] = { "arrowtype", "linepattern", "label", "labelcolor", "color" }; const char *estrnames2[] = { "a", "p", "l", "lc", "c" }; /* Newer Pajek versions support both Unix and Windows-style line endings, * so we just use Unix style. This will get converted to CRLF on Windows * when the file is opened in text mode */ const char *newline = "\n"; igraph_es_t es; igraph_eit_t eit; igraph_vector_t numv; igraph_strvector_t strv; igraph_vector_t ex_numa; igraph_vector_t ex_stra; igraph_vector_t vx_numa; igraph_vector_t vx_stra; char *s, *escaped; igraph_bool_t bipartite = 0; igraph_vector_int_t bip_index, bip_index2; igraph_vector_bool_t bvec; long int notop = 0, nobottom = 0; IGRAPH_VECTOR_INIT_FINALLY(&numv, 1); IGRAPH_STRVECTOR_INIT_FINALLY(&strv, 1); IGRAPH_VECTOR_INIT_FINALLY(&ex_numa, 0); IGRAPH_VECTOR_INIT_FINALLY(&ex_stra, 0); IGRAPH_VECTOR_INIT_FINALLY(&vx_numa, 0); IGRAPH_VECTOR_INIT_FINALLY(&vx_stra, 0); /* Check if graph is bipartite */ if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, "type")) { igraph_attribute_type_t type_type; igraph_i_attribute_gettype(graph, &type_type, IGRAPH_ATTRIBUTE_VERTEX, "type"); if (type_type == IGRAPH_ATTRIBUTE_BOOLEAN) { int bptr = 0, tptr = 0; bipartite = 1; write_vertex_attrs = 1; /* Count top and bottom vertices, we go over them twice, because we want to keep their original order */ IGRAPH_CHECK(igraph_vector_int_init(&bip_index, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &bip_index); IGRAPH_CHECK(igraph_vector_int_init(&bip_index2, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_int_destroy, &bip_index2); IGRAPH_CHECK(igraph_vector_bool_init(&bvec, 1)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &bvec); for (i = 0; i < no_of_nodes; i++) { IGRAPH_CHECK(igraph_i_attribute_get_bool_vertex_attr(graph, "type", igraph_vss_1((igraph_integer_t) i), &bvec)); if (VECTOR(bvec)[0]) { notop++; } else { nobottom++; } } for (i = 0, bptr = 0, tptr = (int) nobottom; i < no_of_nodes; i++) { IGRAPH_CHECK(igraph_i_attribute_get_bool_vertex_attr(graph, "type", igraph_vss_1((igraph_integer_t) i), &bvec)); if (VECTOR(bvec)[0]) { VECTOR(bip_index)[tptr] = (int) i; VECTOR(bip_index2)[i] = tptr; tptr++; } else { VECTOR(bip_index)[bptr] = (int) i; VECTOR(bip_index2)[i] = bptr; bptr++; } } igraph_vector_bool_destroy(&bvec); IGRAPH_FINALLY_CLEAN(1); } } /* Write header */ if (bipartite) { if (fprintf(outstream, "*Vertices %li %li%s", no_of_nodes, nobottom, newline) < 0) { IGRAPH_ERROR("Cannot write pajek file", IGRAPH_EFILE); } } else { if (fprintf(outstream, "*Vertices %li%s", no_of_nodes, newline) < 0) { IGRAPH_ERROR("Cannot write pajek file", IGRAPH_EFILE); } } /* Check the vertex attributes */ memset(vtypes, 0, sizeof(vtypes[0])*V_LAST); for (i = 0; i < V_LAST; i++) { if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, vnames[i])) { igraph_i_attribute_gettype(graph, &vtypes[i], IGRAPH_ATTRIBUTE_VERTEX, vnames[i]); write_vertex_attrs = 1; } else { vtypes[i] = (igraph_attribute_type_t) -1; } } for (i = 0; i < (long int) (sizeof(vnumnames) / sizeof(const char*)); i++) { igraph_attribute_type_t type; if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, vnumnames[i])) { igraph_i_attribute_gettype(graph, &type, IGRAPH_ATTRIBUTE_VERTEX, vnumnames[i]); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_vector_push_back(&vx_numa, i)); } } } for (i = 0; i < (long int) (sizeof(vstrnames) / sizeof(const char*)); i++) { igraph_attribute_type_t type; if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, vstrnames[i])) { igraph_i_attribute_gettype(graph, &type, IGRAPH_ATTRIBUTE_VERTEX, vstrnames[i]); if (type == IGRAPH_ATTRIBUTE_STRING) { IGRAPH_CHECK(igraph_vector_push_back(&vx_stra, i)); } } } /* Write vertices */ if (write_vertex_attrs) { for (i = 0; i < no_of_nodes; i++) { long int id = bipartite ? VECTOR(bip_index)[i] : i; /* vertex id */ fprintf(outstream, "%li", i + 1); if (vtypes[V_ID] == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_i_attribute_get_numeric_vertex_attr(graph, vnames[V_ID], igraph_vss_1((igraph_integer_t) id), &numv); fputs(" \"", outstream); igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); fputc('"', outstream); } else if (vtypes[V_ID] == IGRAPH_ATTRIBUTE_STRING) { igraph_i_attribute_get_string_vertex_attr(graph, vnames[V_ID], igraph_vss_1((igraph_integer_t) id), &strv); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_pajek_escape(s, &escaped)); fprintf(outstream, " %s", escaped); IGRAPH_FREE(escaped); } else { fprintf(outstream, " \"%li\"", id + 1); } /* coordinates */ if (vtypes[V_X] == IGRAPH_ATTRIBUTE_NUMERIC && vtypes[V_Y] == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_i_attribute_get_numeric_vertex_attr(graph, vnames[V_X], igraph_vss_1((igraph_integer_t) id), &numv); fputc(' ', outstream); igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); igraph_i_attribute_get_numeric_vertex_attr(graph, vnames[V_Y], igraph_vss_1((igraph_integer_t) id), &numv); fputc(' ', outstream); igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); if (vtypes[V_Z] == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_i_attribute_get_numeric_vertex_attr(graph, vnames[V_Z], igraph_vss_1((igraph_integer_t) id), &numv); fputc(' ', outstream); igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); } } /* shape */ if (vtypes[V_SHAPE] == IGRAPH_ATTRIBUTE_STRING) { igraph_i_attribute_get_string_vertex_attr(graph, vnames[V_SHAPE], igraph_vss_1((igraph_integer_t) id), &strv); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_pajek_escape(s, &escaped)); fprintf(outstream, " %s", escaped); IGRAPH_FREE(escaped); } /* numeric parameters */ for (j = 0; j < igraph_vector_size(&vx_numa); j++) { int idx = (int) VECTOR(vx_numa)[j]; igraph_i_attribute_get_numeric_vertex_attr(graph, vnumnames[idx], igraph_vss_1((igraph_integer_t) id), &numv); fprintf(outstream, " %s ", vnumnames2[idx]); igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); } /* string parameters */ for (j = 0; j < igraph_vector_size(&vx_stra); j++) { int idx = (int) VECTOR(vx_stra)[j]; igraph_i_attribute_get_string_vertex_attr(graph, vstrnames[idx], igraph_vss_1((igraph_integer_t) id), &strv); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_pajek_escape(s, &escaped)); fprintf(outstream, " %s %s", vstrnames2[idx], escaped); IGRAPH_FREE(escaped); } /* trailing newline */ fprintf(outstream, "%s", newline); } } /* edges header */ if (igraph_is_directed(graph)) { fprintf(outstream, "*Arcs%s", newline); } else { fprintf(outstream, "*Edges%s", newline); } IGRAPH_CHECK(igraph_es_all(&es, IGRAPH_EDGEORDER_ID)); IGRAPH_FINALLY(igraph_es_destroy, &es); IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); /* Check edge attributes */ for (i = 0; i < E_LAST; i++) { if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, enames[i])) { igraph_i_attribute_gettype(graph, &etypes[i], IGRAPH_ATTRIBUTE_EDGE, enames[i]); } else { etypes[i] = (igraph_attribute_type_t) -1; } } for (i = 0; i < (long int) (sizeof(enumnames) / sizeof(const char*)); i++) { igraph_attribute_type_t type; if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, enumnames[i])) { igraph_i_attribute_gettype(graph, &type, IGRAPH_ATTRIBUTE_EDGE, enumnames[i]); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_vector_push_back(&ex_numa, i)); } } } for (i = 0; i < (long int) (sizeof(estrnames) / sizeof(const char*)); i++) { igraph_attribute_type_t type; if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, estrnames[i])) { igraph_i_attribute_gettype(graph, &type, IGRAPH_ATTRIBUTE_EDGE, estrnames[i]); if (type == IGRAPH_ATTRIBUTE_STRING) { IGRAPH_CHECK(igraph_vector_push_back(&ex_stra, i)); } } } for (i = 0; !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit), i++) { long int edge = IGRAPH_EIT_GET(eit); igraph_integer_t from, to; igraph_edge(graph, (igraph_integer_t) edge, &from, &to); if (bipartite) { from = VECTOR(bip_index2)[from]; to = VECTOR(bip_index2)[to]; } fprintf(outstream, "%li %li", (long int) from + 1, (long int) to + 1); /* Weights */ if (etypes[E_WEIGHT] == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_i_attribute_get_numeric_edge_attr(graph, enames[E_WEIGHT], igraph_ess_1((igraph_integer_t) edge), &numv); fputc(' ', outstream); igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); } /* numeric parameters */ for (j = 0; j < igraph_vector_size(&ex_numa); j++) { int idx = (int) VECTOR(ex_numa)[j]; igraph_i_attribute_get_numeric_edge_attr(graph, enumnames[idx], igraph_ess_1((igraph_integer_t) edge), &numv); fprintf(outstream, " %s ", enumnames2[idx]); igraph_real_fprintf_precise(outstream, VECTOR(numv)[0]); } /* string parameters */ for (j = 0; j < igraph_vector_size(&ex_stra); j++) { int idx = (int) VECTOR(ex_stra)[j]; igraph_i_attribute_get_string_edge_attr(graph, estrnames[idx], igraph_ess_1((igraph_integer_t) edge), &strv); igraph_strvector_get(&strv, 0, &s); IGRAPH_CHECK(igraph_i_pajek_escape(s, &escaped)); fprintf(outstream, " %s %s", estrnames2[idx], escaped); IGRAPH_FREE(escaped); } /* trailing newline */ fprintf(outstream, "%s", newline); } igraph_eit_destroy(&eit); igraph_es_destroy(&es); IGRAPH_FINALLY_CLEAN(2); if (bipartite) { igraph_vector_int_destroy(&bip_index2); igraph_vector_int_destroy(&bip_index); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_destroy(&ex_numa); igraph_vector_destroy(&ex_stra); igraph_vector_destroy(&vx_numa); igraph_vector_destroy(&vx_stra); igraph_strvector_destroy(&strv); igraph_vector_destroy(&numv); IGRAPH_FINALLY_CLEAN(6); return 0; } leidenbase/src/core/io/dl.c0000644000176200001440000001341514447675374015267 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_foreign.h" #include "igraph_attributes.h" #include "igraph_interface.h" #include "io/dl-header.h" int igraph_dl_yylex_init_extra (igraph_i_dl_parsedata_t* user_defined, void* scanner); void igraph_dl_yylex_destroy (void *scanner ); int igraph_dl_yyparse (igraph_i_dl_parsedata_t* context); void igraph_dl_yyset_in (FILE * in_str, void* yyscanner ); /** * \function igraph_read_graph_dl * \brief Read a file in the DL format of UCINET * * This is a simple textual file format used by UCINET. See * http://www.analytictech.com/networks/dataentry.htm for * examples. All the forms described here are supported by * igraph. Vertex names and edge weights are also supported and they * are added as attributes. (If an attribute handler is attached.) * * Note the specification does not mention whether the * format is case sensitive or not. For igraph DL files are case * sensitive, i.e. \c Larry and \c larry are not the same. * \param graph Pointer to an uninitialized graph object. * \param instream The stream to read the DL file from. * \param directed Logical scalar, whether to create a directed file. * \return Error code. * * Time complexity: linear in terms of the number of edges and * vertices, except for the matrix format, which is quadratic in the * number of vertices. * * \example examples/simple/igraph_read_graph_dl.c */ int igraph_read_graph_dl(igraph_t *graph, FILE *instream, igraph_bool_t directed) { int i; long int n, n2; const igraph_strvector_t *namevec = 0; igraph_vector_ptr_t name, weight; igraph_vector_ptr_t *pname = 0, *pweight = 0; igraph_attribute_record_t namerec, weightrec; const char *namestr = "name", *weightstr = "weight"; igraph_i_dl_parsedata_t context; context.eof = 0; context.mode = 0; context.n = -1; context.from = 0; context.to = 0; IGRAPH_VECTOR_INIT_FINALLY(&context.edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&context.weights, 0); IGRAPH_CHECK(igraph_strvector_init(&context.labels, 0)); IGRAPH_FINALLY(igraph_strvector_destroy, &context.labels); IGRAPH_TRIE_INIT_FINALLY(&context.trie, /*names=*/ 1); igraph_dl_yylex_init_extra(&context, &context.scanner); IGRAPH_FINALLY(igraph_dl_yylex_destroy, context.scanner); igraph_dl_yyset_in(instream, context.scanner); i = igraph_dl_yyparse(&context); if (i != 0) { if (context.errmsg[0] != 0) { IGRAPH_ERROR(context.errmsg, IGRAPH_PARSEERROR); } else { IGRAPH_ERROR("Cannot read DL file", IGRAPH_PARSEERROR); } } /* Extend the weight vector, if needed */ n = igraph_vector_size(&context.weights); n2 = igraph_vector_size(&context.edges) / 2; if (n != 0) { igraph_vector_resize(&context.weights, n2); for (; n < n2; n++) { VECTOR(context.weights)[n] = IGRAPH_NAN; } } /* Check number of vertices */ if (n2 > 0) { n = (long int) igraph_vector_max(&context.edges); } else { n = 0; } if (n >= context.n) { IGRAPH_WARNING("More vertices than specified in `DL' file"); context.n = n; } /* OK, everything is ready, create the graph */ IGRAPH_CHECK(igraph_empty(graph, 0, directed)); IGRAPH_FINALLY(igraph_destroy, graph); /* Labels */ if (igraph_strvector_size(&context.labels) != 0) { namevec = (const igraph_strvector_t*) &context.labels; } else if (igraph_trie_size(&context.trie) != 0) { igraph_trie_getkeys(&context.trie, &namevec); } if (namevec) { IGRAPH_CHECK(igraph_vector_ptr_init(&name, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &name); pname = &name; namerec.name = namestr; namerec.type = IGRAPH_ATTRIBUTE_STRING; namerec.value = namevec; VECTOR(name)[0] = &namerec; } /* Weights */ if (igraph_vector_size(&context.weights) != 0) { IGRAPH_CHECK(igraph_vector_ptr_init(&weight, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &weight); pweight = &weight; weightrec.name = weightstr; weightrec.type = IGRAPH_ATTRIBUTE_NUMERIC; weightrec.value = &context.weights; VECTOR(weight)[0] = &weightrec; } IGRAPH_CHECK(igraph_add_vertices(graph, (igraph_integer_t) context.n, pname)); IGRAPH_CHECK(igraph_add_edges(graph, &context.edges, pweight)); if (pweight) { igraph_vector_ptr_destroy(pweight); IGRAPH_FINALLY_CLEAN(1); } if (pname) { igraph_vector_ptr_destroy(pname); IGRAPH_FINALLY_CLEAN(1); } /* don't destroy the graph itself but pop it from the finally stack */ IGRAPH_FINALLY_CLEAN(1); igraph_trie_destroy(&context.trie); igraph_strvector_destroy(&context.labels); igraph_vector_destroy(&context.edges); igraph_vector_destroy(&context.weights); igraph_dl_yylex_destroy(context.scanner); IGRAPH_FINALLY_CLEAN(5); return 0; } leidenbase/src/core/centrality/0000755000176200001440000000000014532173045016246 5ustar liggesusersleidenbase/src/core/centrality/centralization.c0000644000176200001440000005566714447675374021504 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_centrality.h" #include "igraph_interface.h" #include "igraph_vector.h" #include "core/math.h" /** * \function igraph_centralization * Calculate the centralization score from the node level scores * * For a centrality score defined on the vertices of a graph, it is * possible to define a graph level centralization index, by * calculating the sum of the deviation from the maximum centrality * score. Consequently, the higher the centralization index of the * graph, the more centralized the structure is. * * In order to make graphs of different sizes comparable, * the centralization index is usually normalized to a number between * zero and one, by dividing the (unnormalized) centralization score * of the most centralized structure with the same number of vertices. * * For most centrality indices the most centralized * structure is the star graph, a single center connected to all other * nodes in the network. There are some variation depending on whether * the graph is directed or not, whether loop edges are allowed, etc. * * * This function simply calculates the graph level index, if the node * level scores and the theoretical maximum are given. It is called by * all the measure-specific centralization functions. * * \param scores A vector containing the node-level centrality * scores. * \param theoretical_max The graph level centrality score of the most * centralized graph with the same number of vertices. Only used * if \c normalized set to true. * \param normalized Boolean, whether to normalize the centralization * by dividing the supplied theoretical maximum. * \return The graph level index. * * \sa \ref igraph_centralization_degree(), \ref * igraph_centralization_betweenness(), \ref * igraph_centralization_closeness(), and \ref * igraph_centralization_eigenvector_centrality() for specific * centralization functions. * * Time complexity: O(n), the length of the score vector. * * \example examples/simple/centralization.c */ igraph_real_t igraph_centralization(const igraph_vector_t *scores, igraph_real_t theoretical_max, igraph_bool_t normalized) { long int no_of_nodes = igraph_vector_size(scores); igraph_real_t maxscore = 0.0; igraph_real_t cent = 0.0; if (no_of_nodes != 0) { maxscore = igraph_vector_max(scores); cent = no_of_nodes * maxscore - igraph_vector_sum(scores); if (normalized) { cent = cent / theoretical_max; } } else { cent = IGRAPH_NAN; } return cent; } /** * \function igraph_centralization_degree * Calculate vertex degree and graph centralization * * This function calculates the degree of the vertices by passing its * arguments to \ref igraph_degree(); and it calculates the graph * level centralization index based on the results by calling \ref * igraph_centralization(). * \param graph The input graph. * \param res A vector if you need the node-level degree scores, or a * null pointer otherwise. * \param mode Constant the specifies the type of degree for directed * graphs. Possible values: \c IGRAPH_IN, \c IGRAPH_OUT and \c * IGRAPH_ALL. This argument is ignored for undirected graphs. * \param loops Boolean, whether to consider loop edges when * calculating the degree (and the centralization). * \param centralization Pointer to a real number, the centralization * score is placed here. * \param theoretical_max Pointer to real number or a null pointer. If * not a null pointer, then the theoretical maximum graph * centrality score for a graph with the same number vertices is * stored here. * \param normalized Boolean, whether to calculate a normalized * centralization score. See \ref igraph_centralization() for how * the normalization is done. * \return Error code. * * \sa \ref igraph_centralization(), \ref igraph_degree(). * * Time complexity: the complexity of \ref igraph_degree() plus O(n), * the number of vertices queried, for calculating the centralization * score. */ int igraph_centralization_degree(const igraph_t *graph, igraph_vector_t *res, igraph_neimode_t mode, igraph_bool_t loops, igraph_real_t *centralization, igraph_real_t *theoretical_max, igraph_bool_t normalized) { igraph_vector_t myscores; igraph_vector_t *scores = res; igraph_real_t *tmax = theoretical_max, mytmax; if (!tmax) { tmax = &mytmax; } if (!res) { scores = &myscores; IGRAPH_VECTOR_INIT_FINALLY(scores, 0); } IGRAPH_CHECK(igraph_degree(graph, scores, igraph_vss_all(), mode, loops)); IGRAPH_CHECK(igraph_centralization_degree_tmax(graph, 0, mode, loops, tmax)); *centralization = igraph_centralization(scores, *tmax, normalized); if (!res) { igraph_vector_destroy(scores); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_centralization_degree_tmax * Theoretical maximum for graph centralization based on degree * * This function returns the theoretical maximum graph centrality * based on vertex degree. * * * There are two ways to call this function, the first is to supply a * graph as the graph argument, and then the number of * vertices is taken from this object, and its directedness is * considered as well. The nodes argument is ignored in * this case. The mode argument is also ignored if the * supplied graph is undirected. * * * The other way is to supply a null pointer as the graph * argument. In this case the nodes and mode * arguments are considered. * * * The most centralized structure is the star. More specifically, for * undirected graphs it is the star, for directed graphs it is the * in-star or the out-star. * \param graph A graph object or a null pointer, see the description * above. * \param nodes The number of nodes. This is ignored if the * graph argument is not a null pointer. * \param mode Constant, whether the calculation is based on in-degree * (IGRAPH_IN), out-degree (IGRAPH_OUT) * or total degree (IGRAPH_ALL). This is ignored if * the graph argument is not a null pointer and the * given graph is undirected. * \param loops Boolean scalar, whether to consider loop edges in the * calculation. * \param res Pointer to a real variable, the result is stored here. * \return Error code. * * Time complexity: O(1). * * \sa \ref igraph_centralization_degree() and \ref * igraph_centralization(). */ int igraph_centralization_degree_tmax(const igraph_t *graph, igraph_integer_t nodes, igraph_neimode_t mode, igraph_bool_t loops, igraph_real_t *res) { igraph_bool_t directed = mode != IGRAPH_ALL; igraph_real_t real_nodes; if (graph) { directed = igraph_is_directed(graph); nodes = igraph_vcount(graph); } real_nodes = nodes; /* implicit cast to igraph_real_t */ if (directed) { switch (mode) { case IGRAPH_IN: case IGRAPH_OUT: if (!loops) { *res = (real_nodes - 1) * (real_nodes - 1); } else { *res = (real_nodes - 1) * real_nodes; } break; case IGRAPH_ALL: if (!loops) { *res = 2 * (real_nodes - 1) * (real_nodes - 2); } else { *res = 2 * (real_nodes - 1) * (real_nodes - 1); } break; } } else { if (!loops) { *res = (real_nodes - 1) * (real_nodes - 2); } else { *res = (real_nodes - 1) * real_nodes; } } return 0; } /** * \function igraph_centralization_betweenness * Calculate vertex betweenness and graph centralization * * This function calculates the betweenness centrality of the vertices * by passing its arguments to \ref igraph_betweenness(); and it * calculates the graph level centralization index based on the * results by calling \ref igraph_centralization(). * \param graph The input graph. * \param res A vector if you need the node-level betweenness scores, or a * null pointer otherwise. * \param directed Boolean, whether to consider directed paths when * calculating betweenness. * \param centralization Pointer to a real number, the centralization * score is placed here. * \param theoretical_max Pointer to real number or a null pointer. If * not a null pointer, then the theoretical maximum graph * centrality score for a graph with the same number vertices is * stored here. * \param normalized Boolean, whether to calculate a normalized * centralization score. See \ref igraph_centralization() for how * the normalization is done. * \return Error code. * * \sa \ref igraph_centralization(), \ref igraph_betweenness(). * * Time complexity: the complexity of \ref igraph_betweenness() plus * O(n), the number of vertices queried, for calculating the * centralization score. */ int igraph_centralization_betweenness(const igraph_t *graph, igraph_vector_t *res, igraph_bool_t directed, igraph_real_t *centralization, igraph_real_t *theoretical_max, igraph_bool_t normalized) { igraph_vector_t myscores; igraph_vector_t *scores = res; igraph_real_t *tmax = theoretical_max, mytmax; if (!tmax) { tmax = &mytmax; } if (!res) { scores = &myscores; IGRAPH_VECTOR_INIT_FINALLY(scores, 0); } IGRAPH_CHECK(igraph_betweenness(graph, scores, igraph_vss_all(), directed, /*weights=*/ 0)); IGRAPH_CHECK(igraph_centralization_betweenness_tmax(graph, 0, directed, tmax)); *centralization = igraph_centralization(scores, *tmax, normalized); if (!res) { igraph_vector_destroy(scores); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_centralization_betweenness_tmax * Theoretical maximum for graph centralization based on betweenness * * This function returns the theoretical maximum graph centrality * based on vertex betweenness. * * * There are two ways to call this function, the first is to supply a * graph as the graph argument, and then the number of * vertices is taken from this object, and its directedness is * considered as well. The nodes argument is ignored in * this case. The directed argument is also ignored if the * supplied graph is undirected. * * * The other way is to supply a null pointer as the graph * argument. In this case the nodes and directed * arguments are considered. * * * The most centralized structure is the star. * \param graph A graph object or a null pointer, see the description * above. * \param nodes The number of nodes. This is ignored if the * graph argument is not a null pointer. * \param directed Boolean scalar, whether to use directed paths in * the betweenness calculation. This argument is ignored if * graph is not a null pointer and it is undirected. * \param res Pointer to a real variable, the result is stored here. * \return Error code. * * Time complexity: O(1). * * \sa \ref igraph_centralization_betweenness() and \ref * igraph_centralization(). */ int igraph_centralization_betweenness_tmax(const igraph_t *graph, igraph_integer_t nodes, igraph_bool_t directed, igraph_real_t *res) { igraph_real_t real_nodes; if (graph) { directed = directed && igraph_is_directed(graph); nodes = igraph_vcount(graph); } real_nodes = nodes; /* implicit cast to igraph_real_t */ if (directed) { *res = (real_nodes - 1) * (real_nodes - 1) * (real_nodes - 2); } else { *res = (real_nodes - 1) * (real_nodes - 1) * (real_nodes - 2) / 2.0; } return 0; } /** * \function igraph_centralization_closeness * Calculate vertex closeness and graph centralization * * This function calculates the closeness centrality of the vertices * by passing its arguments to \ref igraph_closeness(); and it * calculates the graph level centralization index based on the * results by calling \ref igraph_centralization(). * \param graph The input graph. * \param res A vector if you need the node-level closeness scores, or a * null pointer otherwise. * \param mode Constant the specifies the type of closeness for directed * graphs. Possible values: \c IGRAPH_IN, \c IGRAPH_OUT and \c * IGRAPH_ALL. This argument is ignored for undirected graphs. See * \ref igraph_closeness() argument with the same name for more. * \param centralization Pointer to a real number, the centralization * score is placed here. * \param theoretical_max Pointer to real number or a null pointer. If * not a null pointer, then the theoretical maximum graph * centrality score for a graph with the same number vertices is * stored here. * \param normalized Boolean, whether to calculate a normalized * centralization score. See \ref igraph_centralization() for how * the normalization is done. * \return Error code. * * \sa \ref igraph_centralization(), \ref igraph_closeness(). * * Time complexity: the complexity of \ref igraph_closeness() plus * O(n), the number of vertices queried, for calculating the * centralization score. */ int igraph_centralization_closeness(const igraph_t *graph, igraph_vector_t *res, igraph_neimode_t mode, igraph_real_t *centralization, igraph_real_t *theoretical_max, igraph_bool_t normalized) { igraph_vector_t myscores; igraph_vector_t *scores = res; igraph_real_t *tmax = theoretical_max, mytmax; if (!tmax) { tmax = &mytmax; } if (!res) { scores = &myscores; IGRAPH_VECTOR_INIT_FINALLY(scores, 0); } IGRAPH_CHECK(igraph_closeness(graph, scores, NULL, NULL, igraph_vss_all(), mode, /*weights=*/ 0, /*normalize=*/ 1)); IGRAPH_CHECK(igraph_centralization_closeness_tmax(graph, 0, mode, tmax)); *centralization = igraph_centralization(scores, *tmax, normalized); if (!res) { igraph_vector_destroy(scores); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_centralization_closeness_tmax * Theoretical maximum for graph centralization based on closeness * * This function returns the theoretical maximum graph centrality * based on vertex closeness. * * * There are two ways to call this function, the first is to supply a * graph as the graph argument, and then the number of * vertices is taken from this object, and its directedness is * considered as well. The nodes argument is ignored in * this case. The mode argument is also ignored if the * supplied graph is undirected. * * * The other way is to supply a null pointer as the graph * argument. In this case the nodes and mode * arguments are considered. * * * The most centralized structure is the star. * \param graph A graph object or a null pointer, see the description * above. * \param nodes The number of nodes. This is ignored if the * graph argument is not a null pointer. * \param mode Constant, specifies what kinf of distances to consider * to calculate closeness. See the mode argument of * \ref igraph_closeness() for details. This argument is ignored * if graph is not a null pointer and it is * undirected. * \param res Pointer to a real variable, the result is stored here. * \return Error code. * * Time complexity: O(1). * * \sa \ref igraph_centralization_closeness() and \ref * igraph_centralization(). */ int igraph_centralization_closeness_tmax(const igraph_t *graph, igraph_integer_t nodes, igraph_neimode_t mode, igraph_real_t *res) { igraph_real_t real_nodes; if (graph) { nodes = igraph_vcount(graph); if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } } real_nodes = nodes; /* implicit cast to igraph_real_t */ if (mode != IGRAPH_ALL) { *res = (real_nodes - 1) * (1.0 - 1.0 / real_nodes); } else { *res = (real_nodes - 1) * (real_nodes - 2) / (2.0 * real_nodes - 3); } return 0; } /** * \function igraph_centralization_eigenvector_centrality * Calculate eigenvector centrality scores and graph centralization * * This function calculates the eigenvector centrality of the vertices * by passing its arguments to \ref igraph_eigenvector_centrality); * and it calculates the graph level centralization index based on the * results by calling \ref igraph_centralization(). * \param graph The input graph. * \param vector A vector if you need the node-level eigenvector * centrality scores, or a null pointer otherwise. * \param value If not a null pointer, then the leading eigenvalue is * stored here. * \param scale If not zero then the result will be scaled, such that * the absolute value of the maximum centrality is one. * \param options Options to ARPACK. See \ref igraph_arpack_options_t * for details. Note that the function overwrites the * n (number of vertices) parameter and * it always starts the calculation from a non-random vector * calculated based on the degree of the vertices. * \param centralization Pointer to a real number, the centralization * score is placed here. * \param theoretical_max Pointer to real number or a null pointer. If * not a null pointer, then the theoretical maximum graph * centrality score for a graph with the same number vertices is * stored here. * \param normalized Boolean, whether to calculate a normalized * centralization score. See \ref igraph_centralization() for how * the normalization is done. * \return Error code. * * \sa \ref igraph_centralization(), \ref igraph_eigenvector_centrality(). * * Time complexity: the complexity of \ref * igraph_eigenvector_centrality() plus O(|V|), the number of vertices * for the calculating the centralization. */ int igraph_centralization_eigenvector_centrality( const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t directed, igraph_bool_t scale, igraph_arpack_options_t *options, igraph_real_t *centralization, igraph_real_t *theoretical_max, igraph_bool_t normalized) { igraph_vector_t myscores; igraph_vector_t *scores = vector; igraph_real_t realvalue, *myvalue = value; igraph_real_t *tmax = theoretical_max, mytmax; if (!tmax) { tmax = &mytmax; } if (!vector) { scores = &myscores; IGRAPH_VECTOR_INIT_FINALLY(scores, 0); } if (!value) { myvalue = &realvalue; } IGRAPH_CHECK(igraph_eigenvector_centrality(graph, scores, myvalue, directed, scale, /*weights=*/ 0, options)); IGRAPH_CHECK(igraph_centralization_eigenvector_centrality_tmax( graph, 0, directed, scale, tmax)); *centralization = igraph_centralization(scores, *tmax, normalized); if (!vector) { igraph_vector_destroy(scores); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_centralization_eigenvector_centrality_tmax * Theoretical maximum centralization for eigenvector centrality * * This function returns the theoretical maximum graph centrality * based on vertex eigenvector centrality. * * * There are two ways to call this function, the first is to supply a * graph as the graph argument, and then the number of * vertices is taken from this object, and its directedness is * considered as well. The nodes argument is ignored in * this case. The directed argument is also ignored if the * supplied graph is undirected. * * * The other way is to supply a null pointer as the graph * argument. In this case the nodes and directed * arguments are considered. * * * The most centralized directed structure is the in-star. The most * centralized undirected structure is the graph with a single edge. * \param graph A graph object or a null pointer, see the description * above. * \param nodes The number of nodes. This is ignored if the * graph argument is not a null pointer. * \param directed Boolean scalar, whether to consider edge * directions. This argument is ignored if * graph is not a null pointer and it is undirected. * \param scale Whether to rescale the node-level centrality scores to * have a maximum of one. * \param res Pointer to a real variable, the result is stored here. * \return Error code. * * Time complexity: O(1). * * \sa \ref igraph_centralization_closeness() and \ref * igraph_centralization(). */ int igraph_centralization_eigenvector_centrality_tmax( const igraph_t *graph, igraph_integer_t nodes, igraph_bool_t directed, igraph_bool_t scale, igraph_real_t *res) { if (graph) { nodes = igraph_vcount(graph); directed = directed && igraph_is_directed(graph); } if (directed) { *res = nodes - 1; } else { if (scale) { *res = nodes - 2; } else { *res = (nodes - 2.0) / M_SQRT2; } } return 0; } leidenbase/src/core/centrality/coreness.c0000644000176200001440000001223014447675374020252 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_community.h" #include "igraph_memory.h" #include "igraph_interface.h" #include "igraph_iterators.h" /** * \function igraph_coreness * \brief Finding the coreness of the vertices in a network. * * The k-core of a graph is a maximal subgraph in which each vertex * has at least degree k. (Degree here means the degree in the * subgraph of course.). The coreness of a vertex is the highest order * of a k-core containing the vertex. * * * This function implements the algorithm presented in Vladimir * Batagelj, Matjaz Zaversnik: An O(m) Algorithm for Cores * Decomposition of Networks. * \param graph The input graph. * \param cores Pointer to an initialized vector, the result of the * computation will be stored here. It will be resized as * needed. For each vertex it contains the highest order of a * core containing the vertex. * \param mode For directed graph it specifies whether to calculate * in-cores, out-cores or the undirected version. It is ignored * for undirected graphs. Possible values: \c IGRAPH_ALL * undirected version, \c IGRAPH_IN in-cores, \c IGRAPH_OUT * out-cores. * \return Error code. * * Time complexity: O(|E|), the number of edges. */ int igraph_coreness(const igraph_t *graph, igraph_vector_t *cores, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); long int *bin, *vert, *pos; long int maxdeg; long int i, j = 0; igraph_vector_t neis; igraph_neimode_t omode; if (mode != IGRAPH_ALL && mode != IGRAPH_OUT && mode != IGRAPH_IN) { IGRAPH_ERROR("Invalid mode in k-cores", IGRAPH_EINVAL); } if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) { mode = omode = IGRAPH_ALL; } else if (mode == IGRAPH_IN) { omode = IGRAPH_OUT; } else { omode = IGRAPH_IN; } if (no_of_nodes == 0) { igraph_vector_clear(cores); return IGRAPH_SUCCESS; } vert = IGRAPH_CALLOC(no_of_nodes, long int); if (vert == 0) { IGRAPH_ERROR("Cannot calculate k-cores", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, vert); pos = IGRAPH_CALLOC(no_of_nodes, long int); if (pos == 0) { IGRAPH_ERROR("Cannot calculate k-cores", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, pos); /* maximum degree + degree of vertices */ IGRAPH_CHECK(igraph_degree(graph, cores, igraph_vss_all(), mode, IGRAPH_LOOPS)); maxdeg = (long int) igraph_vector_max(cores); bin = IGRAPH_CALLOC(maxdeg + 1, long int); if (bin == 0) { IGRAPH_ERROR("Cannot calculate k-cores", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, bin); /* degree histogram */ for (i = 0; i < no_of_nodes; i++) { bin[ (long int)VECTOR(*cores)[i] ] += 1; } /* start pointers */ j = 0; for (i = 0; i <= maxdeg; i++) { long int k = bin[i]; bin[i] = j; j += k; } /* sort in vert (and corrupt bin) */ for (i = 0; i < no_of_nodes; i++) { pos[i] = bin[(long int)VECTOR(*cores)[i]]; vert[pos[i]] = i; bin[(long int)VECTOR(*cores)[i]] += 1; } /* correct bin */ for (i = maxdeg; i > 0; i--) { bin[i] = bin[i - 1]; } bin[0] = 0; /* this is the main algorithm */ IGRAPH_VECTOR_INIT_FINALLY(&neis, maxdeg); for (i = 0; i < no_of_nodes; i++) { long int v = vert[i]; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) v, omode)); for (j = 0; j < igraph_vector_size(&neis); j++) { long int u = (long int) VECTOR(neis)[j]; if (VECTOR(*cores)[u] > VECTOR(*cores)[v]) { long int du = (long int) VECTOR(*cores)[u]; long int pu = pos[u]; long int pw = bin[du]; long int w = vert[pw]; if (u != w) { pos[u] = pw; pos[w] = pu; vert[pu] = w; vert[pw] = u; } bin[du] += 1; VECTOR(*cores)[u] -= 1; } } } igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(1); igraph_free(bin); igraph_free(pos); igraph_free(vert); IGRAPH_FINALLY_CLEAN(3); return 0; } leidenbase/src/core/centrality/closeness.c0000644000176200001440000010302414447675374020431 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_centrality.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "igraph_dqueue.h" #include "core/indheap.h" #include "core/interruption.h" #include "core/math.h" /***** Closeness centrality *****/ /** * \ingroup structural * \function igraph_closeness * \brief Closeness centrality calculations for some vertices. * * The closeness centrality of a vertex measures how easily other * vertices can be reached from it (or the other way: how easily it * can be reached from the other vertices). It is defined as * the inverse of the mean distance to (or from) all other vertices. * * * Closeness centrality is meaningful only for connected graphs. * If the graph is not connected, igraph computes the inverse of the * mean distance to (or from) all \em reachable vertices. In undirected * graphs, this is equivalent to computing the closeness separately in * each connected component. The optional \p all_reachable output * parameter is provided to help detect when the graph is disconnected. * * * While there is no universally adopted definition of closeness centrality * for disconnected graphs, there have been some attempts for generalizing * the concept to the disconnected case. One type of approach considers the mean distance * only to reachable vertices, then re-scales the obtained certrality score * by a factor that depends on the number of reachable vertices * (i.e. the size of the component in the undirected case). * To facilitate computing these generalizations of closeness centrality, * the number of reachable vertices (not including the starting vertex) * is returned in \p reachable_count. * * * In disconnected graphs, consider using the harmonic centrality, * computable using \ref igraph_harmonic_centrality(). * * * For isolated vertices, i.e. those having no associated paths, NaN is returned. * * \param graph The graph object. * \param res The result of the computation, a vector containing the * closeness centrality scores for the given vertices. * \param reachable_count If not \c NULL, this vector will contain the number of * vertices reachable from each vertex for which the closeness is calculated * (not including that vertex). * \param all_reachable Pointer to a Boolean. If not \c NULL, it indicates if all * vertices of the graph were reachable from each vertex in \p vids. * If false, the graph is non-connected. If true, and the graph is undirected, * or if the graph is directed and \p vids contains all vertices, then the * graph is connected. * \param vids The vertices for which the closeness centrality will be computed. * \param mode The type of shortest paths to be used for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the lengths of the outgoing paths are calculated. * \cli IGRAPH_IN * the lengths of the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an * undirected one for the computation. * \endclist * \param weights An optional vector containing edge weights for * weighted closeness. No edge weight may be NaN. Supply a null * pointer here for traditional, unweighted closeness. * \param normalized If true, the inverse of the mean distance to reachable * vetices is returned. If false, the inverse of the sum of distances * is returned. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(n|E|), * n is the number * of vertices for which the calculation is done and * |E| is the number * of edges in the graph. * * \sa Other centrality types: \ref igraph_degree(), \ref igraph_betweenness(), * \ref igraph_harmonic_centrality(). * See \ref igraph_closeness_cutoff() for the range-limited closeness centrality. */ int igraph_closeness(const igraph_t *graph, igraph_vector_t *res, igraph_vector_t *reachable_count, igraph_bool_t *all_reachable, const igraph_vs_t vids, igraph_neimode_t mode, const igraph_vector_t *weights, igraph_bool_t normalized) { return igraph_closeness_cutoff(graph, res, reachable_count, all_reachable, vids, mode, weights, normalized, -1); } static int igraph_i_closeness_cutoff_weighted(const igraph_t *graph, igraph_vector_t *res, igraph_vector_t *reachable_count, igraph_bool_t *all_reachable, const igraph_vs_t vids, igraph_neimode_t mode, igraph_real_t cutoff, const igraph_vector_t *weights, igraph_bool_t normalized) { /* See igraph_shortest_paths_dijkstra() for the implementation details and the dirty tricks. */ long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_2wheap_t Q; igraph_vit_t vit; long int nodes_to_calc; igraph_lazy_inclist_t inclist; long int i, j; igraph_vector_t dist; igraph_vector_long_t which; long int nodes_reached; igraph_real_t mindist = 0; if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Invalid weight vector length.", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t minweight = igraph_vector_min(weights); if (minweight <= 0) { IGRAPH_ERROR("Weight vector must be positive.", IGRAPH_EINVAL); } else if (igraph_is_nan(minweight)) { IGRAPH_ERROR("Weight vector must not contain NaN values.", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); if (reachable_count) { igraph_vector_resize(reachable_count, nodes_to_calc); } if (all_reachable) { *all_reachable = 1; /* be optimistic */ } IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &inclist, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); IGRAPH_VECTOR_INIT_FINALLY(&dist, no_of_nodes); IGRAPH_CHECK(igraph_vector_long_init(&which, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &which); IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); igraph_vector_null(res); for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int source = IGRAPH_VIT_GET(vit); igraph_2wheap_clear(&Q); igraph_2wheap_push_with_index(&Q, source, -1.0); VECTOR(which)[source] = i + 1; VECTOR(dist)[source] = 1.0; /* actual distance is zero but we need to store distance + 1 */ nodes_reached = 0; while (!igraph_2wheap_empty(&Q)) { igraph_integer_t minnei = (igraph_integer_t) igraph_2wheap_max_index(&Q); /* Now check all neighbors of minnei for a shorter path */ igraph_vector_int_t *neis = igraph_lazy_inclist_get(&inclist, minnei); long int nlen = igraph_vector_int_size(neis); mindist = -igraph_2wheap_delete_max(&Q); if (cutoff >= 0 && (mindist - 1.0) > cutoff) { continue; /* NOT break!!! */ } VECTOR(*res)[i] += (mindist - 1.0); nodes_reached++; for (j = 0; j < nlen; j++) { long int edge = (long int) VECTOR(*neis)[j]; long int to = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_real_t curdist = VECTOR(dist)[to]; if (VECTOR(which)[to] != i + 1) { /* First non-infinite distance */ VECTOR(which)[to] = i + 1; VECTOR(dist)[to] = altdist; IGRAPH_CHECK(igraph_2wheap_push_with_index(&Q, to, -altdist)); } else if (curdist == 0 /* this means curdist is infinity */ || altdist < curdist) { /* This is a shorter path */ VECTOR(dist)[to] = altdist; IGRAPH_CHECK(igraph_2wheap_modify(&Q, to, -altdist)); } } } /* !igraph_2wheap_empty(&Q) */ if (reachable_count) { VECTOR(*reachable_count)[i] = nodes_reached - 1; } if (normalized) { /* compute the inverse of the average distance, considering only reachable nodes */ VECTOR(*res)[i] = VECTOR(*res)[i] == 0 ? IGRAPH_NAN : ((igraph_real_t) (nodes_reached-1)) / VECTOR(*res)[i]; } else { /* compute the inverse of the sum of distances */ VECTOR(*res)[i] = VECTOR(*res)[i] == 0 ? IGRAPH_NAN : 1.0 / VECTOR(*res)[i]; } if (all_reachable) { if (nodes_reached < no_of_nodes) { *all_reachable = 0 /* false */; } } } /* !IGRAPH_VIT_END(vit) */ igraph_vector_long_destroy(&which); igraph_vector_destroy(&dist); igraph_lazy_inclist_destroy(&inclist); igraph_2wheap_destroy(&Q); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \ingroup structural * \function igraph_closeness_estimate * \brief Closeness centrality estimations for some vertices. * * \deprecated-by igraph_closeness_cutoff 0.9 * * * The closeness centrality of a vertex measures how easily other * vertices can be reached from it (or the other way: how easily it * can be reached from the other vertices). It is defined as * the number of vertices minus one divided by the sum of the * lengths of all geodesics from/to the given vertex. When estimating * closeness centrality, igraph considers paths having a length less than * or equal to a prescribed cutoff value. * * * If the graph is not connected, and there is no such path between two * vertices, the number of vertices is used instead the length of the * geodesic. This is always longer than the longest possible geodesic. * * * Since the estimation considers vertex pairs with a distance greater than * the given value as disconnected, the resulting estimation will always be * lower than the actual closeness centrality. * * \param graph The graph object. * \param res The result of the computation, a vector containing the * closeness centrality scores for the given vertices. * \param vids The vertices for which the closeness centrality will be estimated. * \param mode The type of shortest paths to be used for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the lengths of the outgoing paths are calculated. * \cli IGRAPH_IN * the lengths of the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an * undirected one for the computation. * \endclist * \param cutoff The maximal length of paths that will be considered. * If negative, the exact closeness will be calculated (no upper * limit on path lengths). * \param weights An optional vector containing edge weights for * weighted closeness. No edge weight may be NaN. Supply a * null pointer here for traditional, unweighted closeness. * \param normalized Boolean, whether to normalize results by multiplying * by the number of vertices minus one. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(n|E|), * n is the number * of vertices for which the calculation is done and * |E| is the number * of edges in the graph. * * \sa Other centrality types: \ref igraph_degree(), \ref igraph_betweenness(). */ int igraph_closeness_estimate(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_real_t cutoff, const igraph_vector_t *weights, igraph_bool_t normalized) { IGRAPH_WARNING("igraph_closeness_estimate is deprecated, use igraph_closeness_cutoff."); return igraph_closeness_cutoff(graph, res, NULL, NULL, vids, mode, weights, normalized, cutoff); } /** * \ingroup structural * \function igraph_closeness_cutoff * \brief Range limited closeness centrality. * * This function computes a range-limited version of closeness centrality * by considering only those shortest paths whose length is no greater * then the given cutoff value. * * \param graph The graph object. * \param res The result of the computation, a vector containing the * range-limited closeness centrality scores for the given vertices. * \param reachable_count If not \c NULL, this vector will contain the number of * vertices reachable within the cutoff distance from each vertex for which * the range-limited closeness is calculated (not including that vertex). * \param all_reachable Pointer to a Boolean. If not \c NULL, it indicates if all * vertices of the graph were reachable from each vertex in \p vids within * the given cutoff distance. * \param vids The vertices for which the range limited closeness centrality * will be computed. * \param mode The type of shortest paths to be used for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the lengths of the outgoing paths are calculated. * \cli IGRAPH_IN * the lengths of the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an * undirected one for the computation. * \endclist * \param weights An optional vector containing edge weights for * weighted closeness. No edge weight may be NaN. Supply a null * pointer here for traditional, unweighted closeness. * \param normalized If true, the inverse of the mean distance to vertices * reachable within the cutoff is returned. If false, the inverse * of the sum of distances is returned. * \param cutoff The maximal length of paths that will be considered. * If negative, the exact closeness will be calculated (no upper * limit on path lengths). * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(n|E|), * n is the number * of vertices for which the calculation is done and * |E| is the number * of edges in the graph. * * \sa \ref igraph_closeness() to calculate the exact closeness centrality. */ int igraph_closeness_cutoff(const igraph_t *graph, igraph_vector_t *res, igraph_vector_t *reachable_count, igraph_bool_t *all_reachable, const igraph_vs_t vids, igraph_neimode_t mode, const igraph_vector_t *weights, igraph_bool_t normalized, igraph_real_t cutoff) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t already_counted; igraph_vector_int_t *neis; long int i, j; long int nodes_reached; igraph_adjlist_t allneis; long int actdist = 0; igraph_dqueue_t q; long int nodes_to_calc; igraph_vit_t vit; if (weights) { return igraph_i_closeness_cutoff_weighted(graph, res, reachable_count, all_reachable, vids, mode, cutoff, weights, normalized); } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); if (reachable_count) { igraph_vector_resize(reachable_count, nodes_to_calc); } if (all_reachable) { *all_reachable = 1; /* be optimistic */ } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode for closeness.", IGRAPH_EINVMODE); } IGRAPH_VECTOR_INIT_FINALLY(&already_counted, no_of_nodes); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_adjlist_init(graph, &allneis, mode, IGRAPH_LOOPS, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); igraph_vector_null(res); for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { nodes_reached = 0; igraph_dqueue_clear(&q); IGRAPH_CHECK(igraph_dqueue_push(&q, IGRAPH_VIT_GET(vit))); IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); VECTOR(already_counted)[(long int)IGRAPH_VIT_GET(vit)] = i + 1; IGRAPH_PROGRESS("Closeness: ", 100.0 * i / nodes_to_calc, NULL); IGRAPH_ALLOW_INTERRUPTION(); while (!igraph_dqueue_empty(&q)) { long int act = (long int) igraph_dqueue_pop(&q); actdist = (long int) igraph_dqueue_pop(&q); if (cutoff >= 0 && actdist > cutoff) { continue; /* NOT break!!! */ } VECTOR(*res)[i] += actdist; nodes_reached++; /* check the neighbors */ neis = igraph_adjlist_get(&allneis, act); for (j = 0; j < igraph_vector_int_size(neis); j++) { long int neighbor = (long int) VECTOR(*neis)[j]; if (VECTOR(already_counted)[neighbor] == i + 1) { continue; } VECTOR(already_counted)[neighbor] = i + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); } } if (reachable_count) { VECTOR(*reachable_count)[i] = nodes_reached - 1; } if (normalized) { /* compute the inverse of the average distance, considering only reachable nodes */ VECTOR(*res)[i] = VECTOR(*res)[i] == 0 ? IGRAPH_NAN : ((igraph_real_t) (nodes_reached-1)) / VECTOR(*res)[i]; } else { /* compute the inverse of the sum of distances */ VECTOR(*res)[i] = VECTOR(*res)[i] == 0 ? IGRAPH_NAN : 1.0 / VECTOR(*res)[i]; } if (all_reachable) { if (nodes_reached < no_of_nodes) { *all_reachable = 0 /* false */; } } } IGRAPH_PROGRESS("Closeness: ", 100.0, NULL); /* Clean */ igraph_dqueue_destroy(&q); igraph_vector_destroy(&already_counted); igraph_vit_destroy(&vit); igraph_adjlist_destroy(&allneis); IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; } /***** Harmonic centrality *****/ static int igraph_i_harmonic_centrality_unweighted(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t normalized, igraph_real_t cutoff) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t already_counted; igraph_vector_int_t *neis; long int i, j; igraph_adjlist_t allneis; long int actdist = 0; igraph_dqueue_t q; long int nodes_to_calc; igraph_vit_t vit; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode for harmonic centrality.", IGRAPH_EINVMODE); } IGRAPH_VECTOR_INIT_FINALLY(&already_counted, no_of_nodes); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_adjlist_init(graph, &allneis, mode, IGRAPH_LOOPS, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); igraph_vector_null(res); for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int source = IGRAPH_VIT_GET(vit); igraph_dqueue_clear(&q); IGRAPH_CHECK(igraph_dqueue_push(&q, source)); IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); VECTOR(already_counted)[source] = i + 1; IGRAPH_PROGRESS("Harmonic centrality: ", 100.0 * i / nodes_to_calc, NULL); IGRAPH_ALLOW_INTERRUPTION(); while (!igraph_dqueue_empty(&q)) { long int act = (long int) igraph_dqueue_pop(&q); actdist = (long int) igraph_dqueue_pop(&q); if (cutoff >= 0 && actdist > cutoff) { continue; /* NOT break!!! */ } /* Exclude self-distance, which is zero. */ if (source != act) { VECTOR(*res)[i] += 1.0/actdist; } /* check the neighbors */ neis = igraph_adjlist_get(&allneis, act); for (j = 0; j < igraph_vector_int_size(neis); j++) { long int neighbor = (long int) VECTOR(*neis)[j]; if (VECTOR(already_counted)[neighbor] == i + 1) { continue; } VECTOR(already_counted)[neighbor] = i + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); } } } if (normalized && no_of_nodes > 1 /* not a null graph or singleton graph */) { igraph_vector_scale(res, 1.0 / (no_of_nodes - 1)); } IGRAPH_PROGRESS("Harmonic centrality: ", 100.0, NULL); /* Clean */ igraph_dqueue_destroy(&q); igraph_vector_destroy(&already_counted); igraph_vit_destroy(&vit); igraph_adjlist_destroy(&allneis); IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; } static int igraph_i_harmonic_centrality_weighted(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, const igraph_vector_t *weights, igraph_bool_t normalized, igraph_real_t cutoff) { /* See igraph_shortest_paths_dijkstra() for the implementation details and the dirty tricks. */ long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_2wheap_t Q; igraph_vit_t vit; long int nodes_to_calc; igraph_lazy_inclist_t inclist; long int i, j; igraph_vector_t dist; igraph_vector_long_t which; igraph_real_t mindist = 0; if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Invalid weight vector length.", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t minweight = igraph_vector_min(weights); if (minweight <= 0) { IGRAPH_ERROR("Weight vector must be positive.", IGRAPH_EINVAL); } else if (igraph_is_nan(minweight)) { IGRAPH_ERROR("Weight vector must not contain NaN values.", IGRAPH_EINVAL); } } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &inclist, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); IGRAPH_VECTOR_INIT_FINALLY(&dist, no_of_nodes); IGRAPH_CHECK(igraph_vector_long_init(&which, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &which); IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); igraph_vector_null(res); for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int source = IGRAPH_VIT_GET(vit); igraph_2wheap_clear(&Q); igraph_2wheap_push_with_index(&Q, source, -1.0); VECTOR(which)[source] = i + 1; VECTOR(dist)[source] = 1.0; /* actual distance is zero but we need to store distance + 1 */ while (!igraph_2wheap_empty(&Q)) { igraph_integer_t minnei = (igraph_integer_t) igraph_2wheap_max_index(&Q); /* Now check all neighbors of minnei for a shorter path */ igraph_vector_int_t *neis = igraph_lazy_inclist_get(&inclist, minnei); long int nlen = igraph_vector_int_size(neis); mindist = -igraph_2wheap_delete_max(&Q); if (cutoff >= 0 && (mindist - 1.0) > cutoff) { continue; /* NOT break!!! */ } /* Exclude self-distance, which is zero. */ if (source != minnei) { VECTOR(*res)[i] += 1.0 / (mindist - 1.0); } for (j = 0; j < nlen; j++) { long int edge = (long int) VECTOR(*neis)[j]; long int to = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_real_t curdist = VECTOR(dist)[to]; if (VECTOR(which)[to] != i + 1) { /* First non-infinite distance */ VECTOR(which)[to] = i + 1; VECTOR(dist)[to] = altdist; IGRAPH_CHECK(igraph_2wheap_push_with_index(&Q, to, -altdist)); } else if (curdist == 0 /* this means curdist is infinity */ || altdist < curdist) { /* This is a shorter path */ VECTOR(dist)[to] = altdist; IGRAPH_CHECK(igraph_2wheap_modify(&Q, to, -altdist)); } } } /* !igraph_2wheap_empty(&Q) */ } /* !IGRAPH_VIT_END(vit) */ if (normalized && no_of_nodes > 1 /* not a null graph or singleton graph */) { igraph_vector_scale(res, 1.0 / (no_of_nodes - 1)); } igraph_vector_long_destroy(&which); igraph_vector_destroy(&dist); igraph_lazy_inclist_destroy(&inclist); igraph_2wheap_destroy(&Q); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_harmonic_centrality_cutoff * \brief Range limited harmonic centrality. * * This function computes the range limited version of harmonic centrality: * only those shortest paths are considered whose length is not above the given cutoff. * The inverse distance to vertices not reachable within the cutoff is considered * to be zero. * * \param graph The graph object. * \param res The result of the computation, a vector containing the * range limited harmonic centrality scores for the given vertices. * \param vids The vertices for which the harmonic centrality will be computed. * \param mode The type of shortest paths to be used for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the lengths of the outgoing paths are calculated. * \cli IGRAPH_IN * the lengths of the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an * undirected one for the computation. * \endclist * \param weights An optional vector containing edge weights for * weighted harmonic centrality. No edge weight may be NaN. * If \c NULL, all weights are considered to be one. * \param normalized Boolean, whether to normalize the result. If true, * the result is the mean inverse path length to other vertices. * i.e. it is normalized by the number of vertices minus one. * If false, the result is the sum of inverse path lengths to other * vertices. * \param cutoff The maximal length of paths that will be considered. * The inverse distance to vertices that are not reachable within * the cutoff path length is considered to be zero. * Supply a negative value to compute the exact harmonic centrality, * without any upper limit on the length of paths. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(n|E|), where * n is the number of vertices for which the calculation is done and * |E| is the number of edges in the graph. * * \sa Other centrality types: \ref igraph_closeness(), \ref igraph_betweenness(). */ int igraph_harmonic_centrality_cutoff(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, const igraph_vector_t *weights, igraph_bool_t normalized, igraph_real_t cutoff) { if (weights) { return igraph_i_harmonic_centrality_weighted(graph, res, vids, mode, weights, normalized, cutoff); } else { return igraph_i_harmonic_centrality_unweighted(graph, res, vids, mode, normalized, cutoff); } } /** * \ingroup structural * \function igraph_harmonic_centrality * \brief Harmonic centrality for some vertices. * * The harmonic centrality of a vertex is the mean inverse distance to * all other vertices. The inverse distance to an unreachable vertex * is considered to be zero. * * * References: * * * M. Marchiori and V. Latora, Harmony in the small-world, Physica A 285, pp. 539-546 (2000). * https://doi.org/10.1016/S0378-4371%2800%2900311-3 * * * Y. Rochat, Closeness Centrality Extended to Unconnected Graphs: the Harmonic Centrality Index, ASNA 2009. * https://infoscience.epfl.ch/record/200525 * * * S. Vigna and P. Boldi, Axioms for Centrality, Internet Mathematics 10, (2014). * https://doi.org/10.1080/15427951.2013.865686 * * \param graph The graph object. * \param res The result of the computation, a vector containing the * harmonic centrality scores for the given vertices. * \param vids The vertices for which the harmonic centrality will be computed. * \param mode The type of shortest paths to be used for the * calculation in directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the lengths of the outgoing paths are calculated. * \cli IGRAPH_IN * the lengths of the incoming paths are calculated. * \cli IGRAPH_ALL * the directed graph is considered as an * undirected one for the computation. * \endclist * \param weights An optional vector containing edge weights for * weighted harmonic centrality. No edge weight may be NaN. * If \c NULL, all weights are considered to be one. * \param normalized Boolean, whether to normalize the result. If true, * the result is the mean inverse path length to other vertices, * i.e. it is normalized by the number of vertices minus one. * If false, the result is the sum of inverse path lengths to other * vertices. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(n|E|), where * n is the numberof vertices for which the calculation is done and * |E| is the number of edges in the graph. * * \sa Other centrality types: \ref igraph_closeness(), \ref igraph_degree(), \ref igraph_betweenness(). */ int igraph_harmonic_centrality(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, const igraph_vector_t *weights, igraph_bool_t normalized) { return igraph_harmonic_centrality_cutoff(graph, res, vids, mode, weights, normalized, /* cutoff= */ -1); } leidenbase/src/core/centrality/betweenness.c0000644000176200001440000012112314447675374020755 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2020 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_centrality.h" #include "igraph_memory.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "igraph_stack.h" #include "igraph_dqueue.h" #include "core/indheap.h" #include "core/interruption.h" #include "core/math.h" /***** Vertex betweenness *****/ /** * \ingroup structural * \function igraph_betweenness * \brief Betweenness centrality of some vertices. * * The betweenness centrality of a vertex is the number of geodesics * going through it. If there are more than one geodesic between two * vertices, the value of these geodesics are weighted by one over the * number of geodesics. * \param graph The graph object. * \param res The result of the computation, a vector containing the * betweenness scores for the specified vertices. * \param vids The vertices of which the betweenness centrality scores * will be calculated. * \param directed Logical, if true directed paths will be considered * for directed graphs. It is ignored for undirected graphs. * \param weights An optional vector containing edge weights for * calculating weighted betweenness. No edge weight may be NaN. * Supply a null pointer here for unweighted betweenness. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * \c IGRAPH_EINVVID, invalid vertex id passed in * \p vids. * * Time complexity: O(|V||E|), * |V| and * |E| are the number of vertices and * edges in the graph. * Note that the time complexity is independent of the number of * vertices for which the score is calculated. * * \sa Other centrality types: \ref igraph_degree(), \ref igraph_closeness(). * See \ref igraph_edge_betweenness() for calculating the betweenness score * of the edges in a graph. See \ref igraph_betweenness_cutoff() to * calculate the range-limited betweenness of the vertices in a graph. */ int igraph_betweenness(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_bool_t directed, const igraph_vector_t* weights) { return igraph_betweenness_cutoff(graph, res, vids, directed, weights, -1); } static int igraph_i_betweenness_cutoff_weighted( const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t cutoff, const igraph_vector_t *weights) { igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph); igraph_integer_t no_of_edges = (igraph_integer_t) igraph_ecount(graph); igraph_2wheap_t Q; igraph_inclist_t inclist; igraph_adjlist_t fathers; long int source, j; igraph_stack_t S; igraph_neimode_t mode = directed ? IGRAPH_OUT : IGRAPH_ALL; igraph_vector_t dist, nrgeo, tmpscore; igraph_vector_t v_tmpres, *tmpres = &v_tmpres; igraph_vit_t vit; int cmp_result; const double eps = IGRAPH_SHORTEST_PATH_EPSILON; if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length must agree with number of edges.", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t minweight = igraph_vector_min(weights); if (minweight <= 0) { IGRAPH_ERROR("Weight vector must be positive.", IGRAPH_EINVAL); } else if (igraph_is_nan(minweight)) { IGRAPH_ERROR("Weight vector must not contain NaN values.", IGRAPH_EINVAL); } else if (minweight <= eps) { IGRAPH_WARNING("Some weights are smaller than epsilon, calculations may suffer from numerical precision."); } } IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); IGRAPH_CHECK(igraph_adjlist_init_empty(&fathers, no_of_nodes)); IGRAPH_FINALLY(igraph_adjlist_destroy, &fathers); IGRAPH_CHECK(igraph_stack_init(&S, no_of_nodes)); IGRAPH_FINALLY(igraph_stack_destroy, &S); IGRAPH_VECTOR_INIT_FINALLY(&dist, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&tmpscore, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&nrgeo, no_of_nodes); if (igraph_vs_is_all(&vids)) { IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes)); igraph_vector_null(res); tmpres = res; } else { IGRAPH_VECTOR_INIT_FINALLY(tmpres, no_of_nodes); } for (source = 0; source < no_of_nodes; source++) { IGRAPH_PROGRESS("Betweenness centrality: ", 100.0 * source / no_of_nodes, 0); IGRAPH_ALLOW_INTERRUPTION(); igraph_2wheap_push_with_index(&Q, source, -1.0); VECTOR(dist)[source] = 1.0; VECTOR(nrgeo)[source] = 1; while (!igraph_2wheap_empty(&Q)) { long int minnei = igraph_2wheap_max_index(&Q); igraph_real_t mindist = -igraph_2wheap_delete_max(&Q); igraph_vector_int_t *neis; long int nlen; /* Ignore vertices that are more distant than the cutoff */ if (cutoff >= 0 && mindist > cutoff + 1.0) { /* Reset variables if node is too distant */ VECTOR(tmpscore)[minnei] = 0; VECTOR(dist)[minnei] = 0; VECTOR(nrgeo)[minnei] = 0; igraph_vector_int_clear(igraph_adjlist_get(&fathers, minnei)); continue; } igraph_stack_push(&S, minnei); /* Now check all neighbors of 'minnei' for a shorter path */ neis = igraph_inclist_get(&inclist, minnei); nlen = igraph_vector_int_size(neis); for (j = 0; j < nlen; j++) { long int edge = (long int) VECTOR(*neis)[j]; long int to = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_real_t curdist = VECTOR(dist)[to]; if (curdist == 0) { /* this means curdist is infinity */ cmp_result = -1; } else { cmp_result = igraph_cmp_epsilon(altdist, curdist, eps); } if (curdist == 0) { /* This is the first non-infinite distance */ igraph_vector_int_t *v = igraph_adjlist_get(&fathers, to); igraph_vector_int_resize(v, 1); VECTOR(*v)[0] = minnei; VECTOR(nrgeo)[to] = VECTOR(nrgeo)[minnei]; VECTOR(dist)[to] = altdist; IGRAPH_CHECK(igraph_2wheap_push_with_index(&Q, to, -altdist)); } else if (cmp_result < 0) { /* This is a shorter path */ igraph_vector_int_t *v = igraph_adjlist_get(&fathers, to); igraph_vector_int_resize(v, 1); VECTOR(*v)[0] = minnei; VECTOR(nrgeo)[to] = VECTOR(nrgeo)[minnei]; VECTOR(dist)[to] = altdist; IGRAPH_CHECK(igraph_2wheap_modify(&Q, to, -altdist)); } else if (cmp_result == 0 && (altdist <= cutoff + 1.0 || cutoff < 0)) { /* Only add if the node is not more distant than the cutoff */ igraph_vector_int_t *v = igraph_adjlist_get(&fathers, to); igraph_vector_int_push_back(v, minnei); VECTOR(nrgeo)[to] += VECTOR(nrgeo)[minnei]; } } } /* !igraph_2wheap_empty(&Q) */ while (!igraph_stack_empty(&S)) { long int w = (long int) igraph_stack_pop(&S); igraph_vector_int_t *fatv = igraph_adjlist_get(&fathers, w); long int fatv_len = igraph_vector_int_size(fatv); for (j = 0; j < fatv_len; j++) { long int f = (long int) VECTOR(*fatv)[j]; VECTOR(tmpscore)[f] += VECTOR(nrgeo)[f] / VECTOR(nrgeo)[w] * (1 + VECTOR(tmpscore)[w]); } if (w != source) { VECTOR(*tmpres)[w] += VECTOR(tmpscore)[w]; } /* Reset variables */ VECTOR(tmpscore)[w] = 0; VECTOR(dist)[w] = 0; VECTOR(nrgeo)[w] = 0; igraph_vector_int_clear(igraph_adjlist_get(&fathers, w)); } } /* source < no_of_nodes */ if (!igraph_vs_is_all(&vids)) { IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_CHECK(igraph_vector_resize(res, IGRAPH_VIT_SIZE(vit))); for (j = 0, IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), j++) { long int node = IGRAPH_VIT_GET(vit); VECTOR(*res)[j] = VECTOR(*tmpres)[node]; } no_of_nodes = (igraph_integer_t) j; igraph_vit_destroy(&vit); igraph_vector_destroy(tmpres); IGRAPH_FINALLY_CLEAN(2); } if (!directed || !igraph_is_directed(graph)) { for (j = 0; j < no_of_nodes; j++) { VECTOR(*res)[j] /= 2.0; } } IGRAPH_PROGRESS("Betweenness centrality: ", 100.0, 0); igraph_vector_destroy(&nrgeo); igraph_vector_destroy(&tmpscore); igraph_vector_destroy(&dist); igraph_stack_destroy(&S); igraph_adjlist_destroy(&fathers); igraph_inclist_destroy(&inclist); igraph_2wheap_destroy(&Q); IGRAPH_FINALLY_CLEAN(7); return 0; } /** * \ingroup structural * \function igraph_betweenness_cutoff * \brief Range-limited betweenness centrality. * * This function computes a range-limited version of betweenness centrality * by considering only those shortest paths whose length is no greater * then the given cutoff value. * * \param graph The graph object. * \param res The result of the computation, a vector containing the * range-limited betweenness scores for the specified vertices. * \param vids The vertices for which the range-limited betweenness centrality * scores will be computed. * \param directed Logical, if true directed paths will be considered * for directed graphs. It is ignored for undirected graphs. * \param weights An optional vector containing edge weights for * calculating weighted betweenness. No edge weight may be NaN. * Supply a null pointer here for unweighted betweenness. * \param cutoff The maximal length of paths that will be considered. * If negative, the exact betweenness will be calculated, and * there will be no upper limit on path lengths. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * \c IGRAPH_EINVVID, invalid vertex id passed in * \p vids. * * Time complexity: O(|V||E|), * |V| and * |E| are the number of vertices and * edges in the graph. * Note that the time complexity is independent of the number of * vertices for which the score is calculated. * * \sa \ref igraph_betweenness() to calculate the exact betweenness and * \ref igraph_edge_betweenness_cutoff() to calculate the range-limited * edge betweenness. */ int igraph_betweenness_cutoff(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_bool_t directed, const igraph_vector_t *weights, igraph_real_t cutoff) { long int no_of_nodes = igraph_vcount(graph); igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; long int *distance; /* Note: nrgeo holds the number of shortest paths, which may be very large in some cases, * e.g. in a grid graph. If using an integer type, this results in overflow. * With a 'long long int', overflow already affects the result for a grid as small as 36*36. * Therefore, we use a 'double' instead. While a 'double' holds fewer digits than a 'long long int', * i.e. its precision is lower, it is effectively immune to overflow. The impact on the precision * of the final result is negligible. The max betweenness is correct to 14 decimal digits, * i.e. the precision limit of 'double', even for a 101*101 grid graph. */ double *nrgeo = 0; double *tmpscore; igraph_stack_t stack = IGRAPH_STACK_NULL; long int source; long int j, k, nneis; igraph_vector_int_t *neis; igraph_vector_t v_tmpres, *tmpres = &v_tmpres; igraph_vit_t vit; igraph_adjlist_t adjlist_out, adjlist_in; igraph_adjlist_t *adjlist_out_p, *adjlist_in_p; if (weights) { return igraph_i_betweenness_cutoff_weighted(graph, res, vids, directed, cutoff, weights); } if (!igraph_vs_is_all(&vids)) { /* subset */ IGRAPH_VECTOR_INIT_FINALLY(tmpres, no_of_nodes); } else { /* only */ IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes)); igraph_vector_null(res); tmpres = res; } directed = directed && igraph_is_directed(graph); if (directed) { IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist_out, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist_out); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist_in, IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist_in); adjlist_out_p = &adjlist_out; adjlist_in_p = &adjlist_in; } else { IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist_out, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist_out); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist_in, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist_in); adjlist_out_p = &adjlist_out; adjlist_in_p = &adjlist_in; } for (j = 0; j < no_of_nodes; j++) { igraph_vector_int_clear(igraph_adjlist_get(adjlist_in_p, j)); } distance = IGRAPH_CALLOC(no_of_nodes, long int); if (distance == 0) { IGRAPH_ERROR("Insufficient memory for betweenness calculation.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, distance); nrgeo = IGRAPH_CALLOC(no_of_nodes, double); if (nrgeo == 0) { IGRAPH_ERROR("Insufficient memory for betweenness calculation.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, nrgeo); tmpscore = IGRAPH_CALLOC(no_of_nodes, double); if (tmpscore == 0) { IGRAPH_ERROR("Insufficient memory for betweenness calculation.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmpscore); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); igraph_stack_init(&stack, no_of_nodes); IGRAPH_FINALLY(igraph_stack_destroy, &stack); /* here we go */ for (source = 0; source < no_of_nodes; source++) { IGRAPH_PROGRESS("Betweenness centrality: ", 100.0 * source / no_of_nodes, 0); IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_dqueue_push(&q, source)); nrgeo[source] = 1; distance[source] = 1; while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); /* Ignore vertices that are more distant than the cutoff */ if (cutoff >= 0 && distance[actnode] > cutoff + 1) { /* Reset variables if node is too distant */ distance[actnode] = 0; nrgeo[actnode] = 0; tmpscore[actnode] = 0; igraph_vector_int_clear(igraph_adjlist_get(adjlist_in_p, actnode)); continue; } IGRAPH_CHECK(igraph_stack_push(&stack, actnode)); neis = igraph_adjlist_get(adjlist_out_p, actnode); nneis = igraph_vector_int_size(neis); for (j = 0; j < nneis; j++) { long int neighbor = (long int) VECTOR(*neis)[j]; if (distance[neighbor] == 0) { distance[neighbor] = distance[actnode] + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); } if (distance[neighbor] == distance[actnode] + 1 && (distance[neighbor] <= cutoff + 1 || cutoff < 0)) { /* Only add if the node is not more distant than the cutoff */ igraph_vector_int_t *v = igraph_adjlist_get(adjlist_in_p, neighbor); igraph_vector_int_push_back(v, actnode); nrgeo[neighbor] += nrgeo[actnode]; } } } /* while !igraph_dqueue_empty */ /* Ok, we've the distance of each node and also the number of shortest paths to them. Now we do an inverse search, starting with the farthest nodes. */ while (!igraph_stack_empty(&stack)) { long int actnode = (long int) igraph_stack_pop(&stack); neis = igraph_adjlist_get(adjlist_in_p, actnode); nneis = igraph_vector_int_size(neis); for (j = 0; j < nneis; j++) { long int neighbor = (long int) VECTOR(*neis)[j]; tmpscore[neighbor] += (tmpscore[actnode] + 1) * nrgeo[neighbor] / nrgeo[actnode]; } if (actnode != source) { VECTOR(*tmpres)[actnode] += tmpscore[actnode]; } /* Reset variables */ distance[actnode] = 0; nrgeo[actnode] = 0; tmpscore[actnode] = 0; igraph_vector_int_clear(igraph_adjlist_get(adjlist_in_p, actnode)); } } /* for source < no_of_nodes */ IGRAPH_PROGRESS("Betweenness centrality: ", 100.0, 0); /* clean */ IGRAPH_FREE(distance); IGRAPH_FREE(nrgeo); IGRAPH_FREE(tmpscore); igraph_dqueue_destroy(&q); igraph_stack_destroy(&stack); IGRAPH_FINALLY_CLEAN(5); /* Keep only the requested vertices */ if (!igraph_vs_is_all(&vids)) { IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_CHECK(igraph_vector_resize(res, IGRAPH_VIT_SIZE(vit))); for (k = 0, IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), k++) { long int node = IGRAPH_VIT_GET(vit); VECTOR(*res)[k] = VECTOR(*tmpres)[node]; } igraph_vit_destroy(&vit); igraph_vector_destroy(tmpres); IGRAPH_FINALLY_CLEAN(2); } /* divide by 2 for undirected graph */ if (!directed) { nneis = igraph_vector_size(res); for (j = 0; j < nneis; j++) { VECTOR(*res)[j] /= 2.0; } } igraph_adjlist_destroy(&adjlist_out); igraph_adjlist_destroy(&adjlist_in); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \ingroup structural * \function igraph_betweenness_estimate * \brief Estimated betweenness centrality of some vertices. * * \deprecated-by igraph_betweenness_cutoff 0.9 * * * The betweenness centrality of a vertex is the number of geodesics * going through it. If there are more than one geodesic between two * vertices, the value of these geodesics are weighted by one over the * number of geodesics. When estimating betweenness centrality, igraph * takes into consideration only those paths that are shorter than or * equal to a prescribed length. Note that the estimated centrality * will always be less than the real one. * * \param graph The graph object. * \param res The result of the computation, a vector containing the * estimated betweenness scores for the specified vertices. * \param vids The vertices of which the betweenness centrality scores * will be estimated. * \param directed Logical, if true directed paths will be considered * for directed graphs. It is ignored for undirected graphs. * \param cutoff The maximal length of paths that will be considered. * If negative, the exact betweenness will be calculated, and * there will be no upper limit on path lengths. * \param weights An optional vector containing edge weights for * calculating weighted betweenness. No edge weight may be NaN. * Supply a null pointer here for unweighted betweenness. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * \c IGRAPH_EINVVID, invalid vertex id passed in * \p vids. * * Time complexity: O(|V||E|), * |V| and * |E| are the number of vertices and * edges in the graph. * Note that the time complexity is independent of the number of * vertices for which the score is calculated. * * \sa Other centrality types: \ref igraph_degree(), \ref igraph_closeness(). * See \ref igraph_edge_betweenness() for calculating the betweenness score * of the edges in a graph. */ int igraph_betweenness_estimate(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t cutoff, const igraph_vector_t *weights) { IGRAPH_WARNING("igraph_betweenness_estimate is deprecated, use igraph_betweenness_cutoff."); return igraph_betweenness_cutoff(graph, res, vids, directed, weights, cutoff); } /***** Edge betweenness *****/ static int igraph_i_edge_betweenness_cutoff_weighted( const igraph_t *graph, igraph_vector_t *result, igraph_bool_t directed, igraph_real_t cutoff, const igraph_vector_t *weights) { igraph_integer_t no_of_nodes = (igraph_integer_t) igraph_vcount(graph); igraph_integer_t no_of_edges = (igraph_integer_t) igraph_ecount(graph); igraph_2wheap_t Q; igraph_inclist_t inclist; igraph_inclist_t fathers; igraph_neimode_t mode = directed ? IGRAPH_OUT : IGRAPH_ALL; igraph_vector_t distance, tmpscore; igraph_vector_long_t nrgeo; long int source, j; int cmp_result; const double eps = IGRAPH_SHORTEST_PATH_EPSILON; igraph_stack_t S; if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Weight vector length must match number of edges.", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t minweight = igraph_vector_min(weights); if (minweight <= 0) { IGRAPH_ERROR("Weight vector must be positive.", IGRAPH_EINVAL); } else if (igraph_is_nan(minweight)) { IGRAPH_ERROR("Weight vector must not contain NaN values.", IGRAPH_EINVAL); } else if (minweight <= eps) { IGRAPH_WARNING("Some weights are smaller than epsilon, calculations may suffer from numerical precision."); } } IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, mode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); IGRAPH_CHECK(igraph_inclist_init_empty(&fathers, no_of_nodes)); IGRAPH_FINALLY(igraph_inclist_destroy, &fathers); IGRAPH_VECTOR_INIT_FINALLY(&distance, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&tmpscore, no_of_nodes); IGRAPH_CHECK(igraph_vector_long_init(&nrgeo, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &nrgeo); IGRAPH_CHECK(igraph_2wheap_init(&Q, no_of_nodes)); IGRAPH_FINALLY(igraph_2wheap_destroy, &Q); IGRAPH_CHECK(igraph_stack_init(&S, no_of_nodes)); IGRAPH_FINALLY(igraph_stack_destroy, &S); IGRAPH_CHECK(igraph_vector_resize(result, no_of_edges)); igraph_vector_null(result); for (source = 0; source < no_of_nodes; source++) { IGRAPH_PROGRESS("Edge betweenness centrality: ", 100.0 * source / no_of_nodes, 0); IGRAPH_ALLOW_INTERRUPTION(); /* printf("source: %li\n", source); */ igraph_2wheap_push_with_index(&Q, source, -1.0); VECTOR(distance)[source] = 1.0; VECTOR(nrgeo)[source] = 1; while (!igraph_2wheap_empty(&Q)) { long int minnei = igraph_2wheap_max_index(&Q); igraph_real_t mindist = -igraph_2wheap_delete_max(&Q); igraph_vector_int_t *neis; long int nlen; /* printf("SP to %li is final, dist: %g, nrgeo: %li\n", minnei, */ /* VECTOR(distance)[minnei]-1.0, VECTOR(nrgeo)[minnei]); */ /* Ignore vertices that are more distant than the cutoff */ if (cutoff >= 0 && VECTOR(distance)[minnei] > cutoff + 1.0) { /* Reset variables if node is too distant */ VECTOR(tmpscore)[minnei] = 0; VECTOR(distance)[minnei] = 0; VECTOR(nrgeo)[minnei] = 0; igraph_vector_int_clear(igraph_inclist_get(&fathers, minnei)); continue; } igraph_stack_push(&S, minnei); neis = igraph_inclist_get(&inclist, minnei); nlen = igraph_vector_int_size(neis); for (j = 0; j < nlen; j++) { long int edge = (long int) VECTOR(*neis)[j]; long int to = IGRAPH_OTHER(graph, edge, minnei); igraph_real_t altdist = mindist + VECTOR(*weights)[edge]; igraph_real_t curdist = VECTOR(distance)[to]; if (curdist == 0) { /* this means curdist is infinity */ cmp_result = -1; } else { cmp_result = igraph_cmp_epsilon(altdist, curdist, eps); } /* printf("to=%ld, altdist = %lg, curdist = %lg, cmp = %d\n", to, altdist, curdist-1, cmp_result); */ if (curdist == 0) { /* This is the first finite distance to 'to' */ igraph_vector_int_t *v = igraph_inclist_get(&fathers, to); /* printf("Found first path to %li (from %li)\n", to, minnei); */ igraph_vector_int_resize(v, 1); VECTOR(*v)[0] = edge; VECTOR(nrgeo)[to] = VECTOR(nrgeo)[minnei]; VECTOR(distance)[to] = altdist; IGRAPH_CHECK(igraph_2wheap_push_with_index(&Q, to, -altdist)); } else if (cmp_result < 0) { /* This is a shorter path */ igraph_vector_int_t *v = igraph_inclist_get(&fathers, to); /* printf("Found a shorter path to %li (from %li)\n", to, minnei); */ igraph_vector_int_resize(v, 1); VECTOR(*v)[0] = edge; VECTOR(nrgeo)[to] = VECTOR(nrgeo)[minnei]; VECTOR(distance)[to] = altdist; IGRAPH_CHECK(igraph_2wheap_modify(&Q, to, -altdist)); } else if (cmp_result == 0 && (altdist <= cutoff + 1.0 || cutoff < 0)) { /* Only add if the edge is not more distant than the cutoff */ igraph_vector_int_t *v = igraph_inclist_get(&fathers, to); /* printf("Found a second SP to %li (from %li)\n", to, minnei); */ IGRAPH_CHECK(igraph_vector_int_push_back(v, edge)); VECTOR(nrgeo)[to] += VECTOR(nrgeo)[minnei]; } } } /* igraph_2wheap_empty(&Q) */ while (!igraph_stack_empty(&S)) { long int w = (long int) igraph_stack_pop(&S); igraph_vector_int_t *fatv = igraph_inclist_get(&fathers, w); long int fatv_len = igraph_vector_int_size(fatv); /* printf("Popping %li.\n", w); */ for (j = 0; j < fatv_len; j++) { long int fedge = (long int) VECTOR(*fatv)[j]; long int neighbor = IGRAPH_OTHER(graph, fedge, w); VECTOR(tmpscore)[neighbor] += ((double)VECTOR(nrgeo)[neighbor]) / VECTOR(nrgeo)[w] * (1.0 + VECTOR(tmpscore)[w]); /* printf("Scoring %li (edge %li)\n", neighbor, fedge); */ VECTOR(*result)[fedge] += ((VECTOR(tmpscore)[w] + 1) * VECTOR(nrgeo)[neighbor]) / VECTOR(nrgeo)[w]; } /* Reset variables */ VECTOR(tmpscore)[w] = 0; VECTOR(distance)[w] = 0; VECTOR(nrgeo)[w] = 0; igraph_vector_int_clear(fatv); } } /* source < no_of_nodes */ if (!directed || !igraph_is_directed(graph)) { for (j = 0; j < no_of_edges; j++) { VECTOR(*result)[j] /= 2.0; } } IGRAPH_PROGRESS("Edge betweenness centrality: ", 100.0, 0); igraph_stack_destroy(&S); igraph_2wheap_destroy(&Q); IGRAPH_FINALLY_CLEAN(2); igraph_inclist_destroy(&inclist); igraph_inclist_destroy(&fathers); igraph_vector_destroy(&distance); igraph_vector_destroy(&tmpscore); igraph_vector_long_destroy(&nrgeo); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \ingroup structural * \function igraph_edge_betweenness * \brief Betweenness centrality of the edges. * * The betweenness centrality of an edge is the number of geodesics * going through it. If there are more than one geodesics between two * vertices, the value of these geodesics are weighted by one over the * number of geodesics. * * \param graph The graph object. * \param result The result of the computation, vector containing the * betweenness scores for the edges. * \param directed Logical, if true directed paths will be considered * for directed graphs. It is ignored for undirected graphs. * \param weights An optional weight vector for weighted edge * betweenness. No edge weight may be NaN. Supply a null * pointer here for the unweighted version. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * * Time complexity: O(|V||E|), * |V| and * |E| are the number of vertices and * edges in the graph. * * \sa Other centrality types: \ref igraph_degree(), \ref igraph_closeness(). * See \ref igraph_edge_betweenness() for calculating the betweenness score * of the edges in a graph. See \ref igraph_edge_betweenness_cutoff() to * compute the range-limited betweenness score of the edges in a graph. */ int igraph_edge_betweenness(const igraph_t *graph, igraph_vector_t *result, igraph_bool_t directed, const igraph_vector_t *weights) { return igraph_edge_betweenness_cutoff(graph, result, directed, weights, -1); } /** * \ingroup structural * \function igraph_edge_betweenness_cutoff * \brief Range-limited betweenness centrality of the edges. * * This function computes a range-limited version of edge betweenness centrality * by considering only those shortest paths whose length is no greater * then the given cutoff value. * * \param graph The graph object. * \param result The result of the computation, vector containing the * betweenness scores for the edges. * \param directed Logical, if true directed paths will be considered * for directed graphs. It is ignored for undirected graphs. * \param weights An optional weight vector for weighted * betweenness. No edge weight may be NaN. Supply a null * pointer here for unweighted betweenness. * \param cutoff The maximal length of paths that will be considered. * If negative, the exact betweenness will be calculated (no * upper limit on path lengths). * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * * Time complexity: O(|V||E|), * |V| and * |E| are the number of vertices and * edges in the graph. * * \sa \ref igraph_edge_betweenness() to compute the exact edge betweenness and * \ref igraph_betweenness_cutoff() to compute the range-limited vertex betweenness. */ int igraph_edge_betweenness_cutoff(const igraph_t *graph, igraph_vector_t *result, igraph_bool_t directed, const igraph_vector_t *weights, igraph_real_t cutoff) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; long int *distance; double *nrgeo; double *tmpscore; igraph_stack_t stack = IGRAPH_STACK_NULL; long int source; long int j; igraph_inclist_t elist_out, elist_in; igraph_inclist_t *elist_out_p, *elist_in_p; igraph_vector_int_t *neip; long int neino; long int i; if (weights) { return igraph_i_edge_betweenness_cutoff_weighted(graph, result, directed, cutoff, weights); } directed = directed && igraph_is_directed(graph); if (directed) { IGRAPH_CHECK(igraph_inclist_init(graph, &elist_out, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &elist_out); IGRAPH_CHECK(igraph_inclist_init(graph, &elist_in, IGRAPH_IN, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &elist_in); elist_out_p = &elist_out; elist_in_p = &elist_in; } else { IGRAPH_CHECK(igraph_inclist_init(graph, &elist_out, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &elist_out); elist_out_p = elist_in_p = &elist_out; } distance = IGRAPH_CALLOC(no_of_nodes, long int); if (distance == 0) { IGRAPH_ERROR("Insufficient memory for edge betweenness calculation.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, distance); nrgeo = IGRAPH_CALLOC(no_of_nodes, double); if (nrgeo == 0) { IGRAPH_ERROR("Insufficient memory for edge betweenness calculation.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, nrgeo); tmpscore = IGRAPH_CALLOC(no_of_nodes, double); if (tmpscore == 0) { IGRAPH_ERROR("Insufficient memory for edge betweenness calculation.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmpscore); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_stack_init(&stack, no_of_nodes)); IGRAPH_FINALLY(igraph_stack_destroy, &stack); IGRAPH_CHECK(igraph_vector_resize(result, no_of_edges)); igraph_vector_null(result); /* here we go */ for (source = 0; source < no_of_nodes; source++) { IGRAPH_PROGRESS("Edge betweenness centrality: ", 100.0 * source / no_of_nodes, 0); IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_dqueue_push(&q, source)); nrgeo[source] = 1; distance[source] = 0; while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); if (cutoff >= 0 && distance[actnode] > cutoff ) { /* Reset variables if node is too distant */ distance[actnode] = 0; tmpscore[actnode] = 0; nrgeo[actnode] = 0; continue; } IGRAPH_CHECK(igraph_stack_push(&stack, actnode)); /* check the neighbors and add to them to the queue if unseen before */ neip = igraph_inclist_get(elist_out_p, actnode); neino = igraph_vector_int_size(neip); for (i = 0; i < neino; i++) { igraph_integer_t edge = (igraph_integer_t) VECTOR(*neip)[i]; long int neighbor = (long int) IGRAPH_OTHER(graph, edge, actnode); if (nrgeo[neighbor] != 0) { /* we've already seen this node, another shortest path? */ if (distance[neighbor] == distance[actnode] + 1) { nrgeo[neighbor] += nrgeo[actnode]; } } else if (distance[actnode] + 1 <= cutoff || cutoff < 0) { /* we haven't seen this node yet, but we only consider * it if it is not more distant than the cutoff. */ nrgeo[neighbor] += nrgeo[actnode]; distance[neighbor] = distance[actnode] + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); } } } /* while !igraph_dqueue_empty */ /* Ok, we've the distance of each node and also the number of shortest paths to them. Now we do an inverse search, starting with the farthest nodes. */ while (!igraph_stack_empty(&stack)) { long int actnode = (long int) igraph_stack_pop(&stack); if (distance[actnode] < 1) { distance[actnode] = 0; tmpscore[actnode] = 0; nrgeo[actnode] = 0; continue; /* skip source node */ } /* set the temporary score of the friends */ neip = igraph_inclist_get(elist_in_p, actnode); neino = igraph_vector_int_size(neip); for (i = 0; i < neino; i++) { igraph_integer_t edgeno = (igraph_integer_t) VECTOR(*neip)[i]; long int neighbor = (long int) IGRAPH_OTHER(graph, edgeno, actnode); if (distance[neighbor] == distance[actnode] - 1 && nrgeo[neighbor] != 0) { tmpscore[neighbor] += (tmpscore[actnode] + 1) * nrgeo[neighbor] / nrgeo[actnode]; VECTOR(*result)[edgeno] += (tmpscore[actnode] + 1) * nrgeo[neighbor] / nrgeo[actnode]; } } /* Reset variables */ distance[actnode] = 0; tmpscore[actnode] = 0; nrgeo[actnode] = 0; } /* Ok, we've the scores for this source */ } /* for source <= no_of_nodes */ IGRAPH_PROGRESS("Edge betweenness centrality: ", 100.0, 0); /* clean and return */ IGRAPH_FREE(distance); IGRAPH_FREE(nrgeo); IGRAPH_FREE(tmpscore); igraph_dqueue_destroy(&q); igraph_stack_destroy(&stack); IGRAPH_FINALLY_CLEAN(5); if (directed) { igraph_inclist_destroy(&elist_out); igraph_inclist_destroy(&elist_in); IGRAPH_FINALLY_CLEAN(2); } else { igraph_inclist_destroy(&elist_out); IGRAPH_FINALLY_CLEAN(1); } /* divide by 2 for undirected graph */ if (!directed || !igraph_is_directed(graph)) { for (j = 0; j < igraph_vector_size(result); j++) { VECTOR(*result)[j] /= 2.0; } } return 0; } /** * \ingroup structural * \function igraph_edge_betweenness_estimate * \brief Estimated betweenness centrality of the edges. * * \deprecated-by igraph_edge_betweenness_cutoff 0.9 * * * The betweenness centrality of an edge is the number of geodesics * going through it. If there are more than one geodesics between two * vertices, the value of these geodesics are weighted by one over the * number of geodesics. When estimating betweenness centrality, igraph * takes into consideration only those paths that are shorter than or * equal to a prescribed length. Note that the estimated centrality * will always be less than the real one. * * \param graph The graph object. * \param result The result of the computation, vector containing the * betweenness scores for the edges. * \param directed Logical, if true directed paths will be considered * for directed graphs. It is ignored for undirected graphs. * \param cutoff The maximal length of paths that will be considered. * If negative, the exact betweenness will be calculated (no * upper limit on path lengths). * \param weights An optional weight vector for weighted betweenness. * No edge weight may be NaN. Supply a null pointer here for * unweighted betweenness. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * * Time complexity: O(|V||E|), * |V| and * |E| are the number of vertices and * edges in the graph. * * \sa Other centrality types: \ref igraph_degree(), \ref igraph_closeness(). * See \ref igraph_betweenness() for calculating the betweenness score * of the vertices in a graph. */ int igraph_edge_betweenness_estimate(const igraph_t *graph, igraph_vector_t *result, igraph_bool_t directed, igraph_real_t cutoff, const igraph_vector_t *weights) { IGRAPH_WARNING("igraph_edge_betweenness_estimate is deprecated, use igraph_edge_betweenness_cutoff."); return igraph_edge_betweenness_cutoff(graph, result, directed, weights, cutoff); } leidenbase/src/core/centrality/prpack.cpp0000644000176200001440000001124014447675374020251 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_error.h" #include "centrality/prpack_internal.h" #include "centrality/prpack/prpack_igraph_graph.h" #include "centrality/prpack/prpack_solver.h" #include "core/exceptions.h" using namespace prpack; using namespace std; /* * PRPACK-based implementation of \c igraph_personalized_pagerank. * * See \c igraph_personalized_pagerank for the documentation of the parameters. */ int igraph_i_personalized_pagerank_prpack(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *reset, const igraph_vector_t *weights) { long int i, no_of_nodes = igraph_vcount(graph), nodes_to_calc; igraph_vit_t vit; double *u = nullptr; double *v = nullptr; const prpack_result *res; IGRAPH_HANDLE_EXCEPTIONS( if (reset) { if (igraph_vector_size(reset) != no_of_nodes) { IGRAPH_ERROR("Invalid length of reset vector when calculating personalized PageRank scores.", IGRAPH_EINVAL); } /* Normalize reset vector so the sum is 1 */ double reset_min = igraph_vector_min(reset); if (reset_min < 0) { IGRAPH_ERROR("The reset vector must not contain negative elements.", IGRAPH_EINVAL); } if (igraph_is_nan(reset_min)) { IGRAPH_ERROR("The reset vector must not contain NaN values.", IGRAPH_EINVAL); } double reset_sum = igraph_vector_sum(reset); if (reset_sum == 0) { IGRAPH_ERROR("The sum of the elements in the reset vector must not be zero.", IGRAPH_EINVAL); } // Construct the personalization vector v = new double[no_of_nodes]; for (i = 0; i < no_of_nodes; i++) { v[i] = VECTOR(*reset)[i] / reset_sum; } // u is the distribution used when restarting the walk due to being stuck in a sink // v is the distribution used when restarting due to damping // Here we use the same distribution for both u = v; } // Since PRPACK uses the algebraic method to solve PageRank, damping factors very close to 1.0 // may lead to numerical instability, the apperance of non-finite values, or the iteration // never terminating. if (damping > 0.999) { IGRAPH_WARNINGF( "Damping factor is %g. " "Damping values close to 1 may lead to numerical instability when using PRPACK.", damping); } // Construct and run the solver prpack_igraph_graph prpack_graph(graph, weights, directed); prpack_solver solver(&prpack_graph, false); res = solver.solve(damping, 1e-10, u, v, ""); // Delete the personalization vector delete [] v; ); // Check whether the solver converged // TODO: this is commented out because some of the solvers do not implement it yet /* if (!res->converged) { IGRAPH_WARNING("PRPACK solver failed to converge. Results may be inaccurate."); } */ // Fill the result vector IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); IGRAPH_CHECK(igraph_vector_resize(vector, nodes_to_calc)); for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { VECTOR(*vector)[i] = res->x[(long int)IGRAPH_VIT_GET(vit)]; } igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); // TODO: can we get the eigenvalue? We'll just fake it until we can. if (value) { *value = 1.0; } delete res; return IGRAPH_SUCCESS; } leidenbase/src/core/centrality/prpack/0000755000176200001440000000000014532326115017524 5ustar liggesusersleidenbase/src/core/centrality/prpack/prpack_edge_list.h0000644000176200001440000000034614447675374023222 0ustar liggesusers#ifndef PRPACK_EDGE_LIST #define PRPACK_EDGE_LIST namespace prpack { class prpack_edge_list { public: int num_vs; int num_es; int* heads; int* tails; }; } #endif leidenbase/src/core/centrality/prpack/prpack_preprocessed_scc_graph.cpp0000644000176200001440000001600014447675374026317 0ustar liggesusers#include "prpack_preprocessed_scc_graph.h" #include #include #include using namespace prpack; using namespace std; void prpack_preprocessed_scc_graph::initialize() { heads_inside = NULL; tails_inside = NULL; vals_inside = NULL; heads_outside = NULL; tails_outside = NULL; vals_outside = NULL; ii = NULL; d = NULL; num_outlinks = NULL; divisions = NULL; encoding = NULL; decoding = NULL; } void prpack_preprocessed_scc_graph::initialize_weighted(const prpack_base_graph* bg) { vals_inside = new double[num_es]; vals_outside = new double[num_es]; d = new double[num_vs]; fill(d, d + num_vs, 1); for (int comp_i = 0; comp_i < num_comps; ++comp_i) { const int start_i = divisions[comp_i]; const int end_i = (comp_i + 1 != num_comps) ? divisions[comp_i + 1] : num_vs; for (int i = start_i; i < end_i; ++i) { ii[i] = 0; const int decoded = decoding[i]; const int start_j = bg->tails[decoded]; const int end_j = (decoded + 1 != num_vs) ? bg->tails[decoded + 1] : bg->num_es; tails_inside[i] = num_es_inside; tails_outside[i] = num_es_outside; for (int j = start_j; j < end_j; ++j) { const int h = encoding[bg->heads[j]]; if (h == i) { ii[i] += bg->vals[j]; } else { if (start_i <= h && h < end_i) { heads_inside[num_es_inside] = h; vals_inside[num_es_inside] = bg->vals[j]; ++num_es_inside; } else { heads_outside[num_es_outside] = h; vals_outside[num_es_outside] = bg->vals[j]; ++num_es_outside; } } d[h] -= bg->vals[j]; } } } } void prpack_preprocessed_scc_graph::initialize_unweighted(const prpack_base_graph* bg) { num_outlinks = new double[num_vs]; fill(num_outlinks, num_outlinks + num_vs, 0); for (int comp_i = 0; comp_i < num_comps; ++comp_i) { const int start_i = divisions[comp_i]; const int end_i = (comp_i + 1 != num_comps) ? divisions[comp_i + 1] : num_vs; for (int i = start_i; i < end_i; ++i) { ii[i] = 0; const int decoded = decoding[i]; const int start_j = bg->tails[decoded]; const int end_j = (decoded + 1 != num_vs) ? bg->tails[decoded + 1] : bg->num_es; tails_inside[i] = num_es_inside; tails_outside[i] = num_es_outside; for (int j = start_j; j < end_j; ++j) { const int h = encoding[bg->heads[j]]; if (h == i) { ++ii[i]; } else { if (start_i <= h && h < end_i) heads_inside[num_es_inside++] = h; else heads_outside[num_es_outside++] = h; } ++num_outlinks[h]; } } } for (int i = 0; i < num_vs; ++i) { if (num_outlinks[i] == 0) num_outlinks[i] = -1; ii[i] /= num_outlinks[i]; } } prpack_preprocessed_scc_graph::prpack_preprocessed_scc_graph(const prpack_base_graph* bg) { initialize(); // initialize instance variables num_vs = bg->num_vs; num_es = bg->num_es - bg->num_self_es; // initialize Tarjan's algorithm variables num_comps = 0; int mn = 0; // the number of vertices seen so far int sz = 0; // size of st int decoding_i = 0; // size of decoding currently filled in decoding = new int[num_vs]; int* scc = new int[num_vs]; // the strongly connected component this vertex is in int* low = new int[num_vs]; // the lowest index this vertex can reach int* num = new int[num_vs]; // the index of this vertex in the dfs traversal int* st = new int[num_vs]; // a stack for the dfs memset(num, -1, num_vs*sizeof(num[0])); memset(scc, -1, num_vs*sizeof(scc[0])); int* cs1 = new int[num_vs]; // call stack variable for dfs int* cs2 = new int[num_vs]; // call stack variable for dfs // run iterative Tarjan's algorithm for (int root = 0; root < num_vs; ++root) { if (num[root] != -1) continue; int csz = 1; cs1[0] = root; cs2[0] = bg->tails[root]; // dfs while (csz) { const int p = cs1[csz - 1]; // node we're dfs-ing on int& it = cs2[csz - 1]; // iteration of the for loop if (it == bg->tails[p]) { low[p] = num[p] = mn++; st[sz++] = p; } else { low[p] = min(low[p], low[bg->heads[it - 1]]); } bool done = false; int end_it = (p + 1 != num_vs) ? bg->tails[p + 1] : bg->num_es; for (; it < end_it; ++it) { int h = bg->heads[it]; if (scc[h] == -1) { if (num[h] == -1) { // dfs(h, p); cs1[csz] = h; cs2[csz++] = bg->tails[h]; ++it; done = true; break; } low[p] = min(low[p], low[h]); } } if (done) continue; // if p is the first explored vertex of a scc if (low[p] == num[p]) { cs1[num_vs - 1 - num_comps] = decoding_i; while (scc[p] != num_comps) { scc[st[--sz]] = num_comps; decoding[decoding_i++] = st[sz]; } ++num_comps; } --csz; } } // set up other instance variables divisions = new int[num_comps]; divisions[0] = 0; for (int i = 1; i < num_comps; ++i) divisions[i] = cs1[num_vs - 1 - i]; encoding = num; for (int i = 0; i < num_vs; ++i) encoding[decoding[i]] = i; // fill in inside and outside instance variables ii = new double[num_vs]; tails_inside = cs1; heads_inside = new int[num_es]; tails_outside = cs2; heads_outside = new int[num_es]; num_es_inside = num_es_outside = 0; // continue initialization based off of weightedness if (bg->vals != NULL) initialize_weighted(bg); else initialize_unweighted(bg); // free memory // do not free num <==> encoding // do not free cs1 <==> tails_inside // do not free cs2 <==> tails_outside delete[] scc; delete[] low; delete[] st; } prpack_preprocessed_scc_graph::~prpack_preprocessed_scc_graph() { delete[] heads_inside; delete[] tails_inside; delete[] vals_inside; delete[] heads_outside; delete[] tails_outside; delete[] vals_outside; delete[] ii; delete[] d; delete[] num_outlinks; delete[] divisions; delete[] encoding; delete[] decoding; } leidenbase/src/core/centrality/prpack/prpack_utils.h0000644000176200001440000000171414447675374022423 0ustar liggesusers#ifndef PRPACK_UTILS #define PRPACK_UTILS #ifdef MATLAB_MEX_FILE #include "mex.h" #endif #include // Computes the time taken to do X and stores it in T. #define TIME(T, X) \ (T) = prpack_utils::get_time(); \ (X); \ (T) = prpack_utils::get_time() - (T) // Computes S += A using C as a carry-over. // This is a macro over a function as it is faster this way. #define COMPENSATED_SUM(S, A, C) \ double compensated_sum_y = (A) - (C); \ double compensated_sum_t = (S) + compensated_sum_y; \ (C) = compensated_sum_t - (S) - compensated_sum_y; \ (S) = compensated_sum_t namespace prpack { class prpack_utils { public: static double get_time(); static void validate(const bool condition, const std::string& msg); static double* permute(const int length, const double* a, const int* coding); }; } #endif leidenbase/src/core/centrality/prpack/prpack_base_graph.cpp0000644000176200001440000002345414447675374023716 0ustar liggesusers#include "prpack_base_graph.h" #include "prpack_utils.h" #include #include #include #include #include #include #include using namespace prpack; using namespace std; void prpack_base_graph::initialize() { heads = NULL; tails = NULL; vals = NULL; } prpack_base_graph::prpack_base_graph() { initialize(); num_vs = num_es = 0; } prpack_base_graph::prpack_base_graph(const prpack_csc* g) { initialize(); num_vs = g->num_vs; num_es = g->num_es; // fill in heads and tails num_self_es = 0; int* hs = g->heads; int* ts = g->tails; tails = new int[num_vs]; memset(tails, 0, num_vs*sizeof(tails[0])); for (int h = 0; h < num_vs; ++h) { const int start_ti = hs[h]; const int end_ti = (h + 1 != num_vs) ? hs[h + 1] : num_es; for (int ti = start_ti; ti < end_ti; ++ti) { const int t = ts[ti]; ++tails[t]; if (h == t) ++num_self_es; } } for (int i = 0, sum = 0; i < num_vs; ++i) { const int temp = sum; sum += tails[i]; tails[i] = temp; } heads = new int[num_es]; int* osets = new int[num_vs]; memset(osets, 0, num_vs*sizeof(osets[0])); for (int h = 0; h < num_vs; ++h) { const int start_ti = hs[h]; const int end_ti = (h + 1 != num_vs) ? hs[h + 1] : num_es; for (int ti = start_ti; ti < end_ti; ++ti) { const int t = ts[ti]; heads[tails[t] + osets[t]++] = h; } } // clean up delete[] osets; } prpack_base_graph::prpack_base_graph(const prpack_int64_csc* g) { initialize(); // TODO remove the assert and add better behavior assert(num_vs <= std::numeric_limits::max()); num_vs = (int)g->num_vs; num_es = (int)g->num_es; // fill in heads and tails num_self_es = 0; int64_t* hs = g->heads; int64_t* ts = g->tails; tails = new int[num_vs]; memset(tails, 0, num_vs*sizeof(tails[0])); for (int h = 0; h < num_vs; ++h) { const int start_ti = (int)hs[h]; const int end_ti = (h + 1 != num_vs) ? (int)hs[h + 1] : num_es; for (int ti = start_ti; ti < end_ti; ++ti) { const int t = (int)ts[ti]; ++tails[t]; if (h == t) ++num_self_es; } } for (int i = 0, sum = 0; i < num_vs; ++i) { const int temp = sum; sum += tails[i]; tails[i] = temp; } heads = new int[num_es]; int* osets = new int[num_vs]; memset(osets, 0, num_vs*sizeof(osets[0])); for (int h = 0; h < num_vs; ++h) { const int start_ti = (int)hs[h]; const int end_ti = (h + 1 != num_vs) ? (int)hs[h + 1] : num_es; for (int ti = start_ti; ti < end_ti; ++ti) { const int t = (int)ts[ti]; heads[tails[t] + osets[t]++] = h; } } // clean up delete[] osets; } prpack_base_graph::prpack_base_graph(const prpack_csr* g) { (void)g; // to silence an unused argument warning initialize(); throw std::runtime_error("not implemented yet"); } prpack_base_graph::prpack_base_graph(const prpack_edge_list* g) { initialize(); num_vs = g->num_vs; num_es = g->num_es; // fill in heads and tails num_self_es = 0; int* hs = g->heads; int* ts = g->tails; tails = new int[num_vs]; memset(tails, 0, num_vs*sizeof(tails[0])); for (int i = 0; i < num_es; ++i) { ++tails[ts[i]]; if (hs[i] == ts[i]) ++num_self_es; } for (int i = 0, sum = 0; i < num_vs; ++i) { const int temp = sum; sum += tails[i]; tails[i] = temp; } heads = new int[num_es]; int* osets = new int[num_vs]; memset(osets, 0, num_vs*sizeof(osets[0])); for (int i = 0; i < num_es; ++i) heads[tails[ts[i]] + osets[ts[i]]++] = hs[i]; // clean up delete[] osets; } prpack_base_graph::prpack_base_graph(const char* filename, const char* format, const bool weighted) { initialize(); FILE* f = fopen(filename, "r"); const string s(filename); const string t(format); const string ext = (t == "") ? s.substr(s.rfind('.') + 1) : t; if (ext == "smat") { read_smat(f, weighted); } else { prpack_utils::validate(!weighted, "Error: graph format is not compatible with weighted option."); if (ext == "edges" || ext == "eg2") { read_edges(f); } else if (ext == "graph-txt") { read_ascii(f); } else { prpack_utils::validate(false, "Error: invalid graph format."); } } fclose(f); } prpack_base_graph::~prpack_base_graph() { delete[] heads; delete[] tails; delete[] vals; } void prpack_base_graph::read_smat(FILE* f, const bool weighted) { // read in header double ignore = 0.0; int retval = fscanf(f, "%d %lf %d", &num_vs, &ignore, &num_es); if (retval != 3) { throw std::runtime_error("error while parsing smat file"); } // fill in heads and tails num_self_es = 0; int* hs = new int[num_es]; int* ts = new int[num_es]; heads = new int[num_es]; tails = new int[num_vs]; double* vs = NULL; if (weighted) { vs = new double[num_es]; vals = new double[num_es]; } memset(tails, 0, num_vs*sizeof(tails[0])); for (int i = 0; i < num_es; ++i) { retval = fscanf(f, "%d %d %lf", &hs[i], &ts[i], &((weighted) ? vs[i] : ignore)); if (retval != 3) { throw std::runtime_error("error while parsing smat file"); } ++tails[ts[i]]; if (hs[i] == ts[i]) ++num_self_es; } for (int i = 0, sum = 0; i < num_vs; ++i) { const int temp = sum; sum += tails[i]; tails[i] = temp; } int* osets = new int[num_vs]; memset(osets, 0, num_vs*sizeof(osets[0])); for (int i = 0; i < num_es; ++i) { const int idx = tails[ts[i]] + osets[ts[i]]++; heads[idx] = hs[i]; if (weighted) vals[idx] = vs[i]; } // clean up delete[] hs; delete[] ts; delete[] vs; delete[] osets; } void prpack_base_graph::read_edges(FILE* f) { vector > al; int h, t; num_es = num_self_es = 0; while (fscanf(f, "%d %d", &h, &t) == 2) { const int m = (h < t) ? t : h; if ((int) al.size() < m + 1) al.resize(m + 1); al[t].push_back(h); ++num_es; if (h == t) ++num_self_es; } num_vs = al.size(); heads = new int[num_es]; tails = new int[num_vs]; for (int tails_i = 0, heads_i = 0; tails_i < num_vs; ++tails_i) { tails[tails_i] = heads_i; for (int j = 0; j < (int) al[tails_i].size(); ++j) heads[heads_i++] = al[tails_i][j]; } } void prpack_base_graph::read_ascii(FILE* f) { int retval = fscanf(f, "%d", &num_vs); if (retval != 1) { throw std::runtime_error("error while parsing ascii file"); } while (getc(f) != '\n'); vector* al = new vector[num_vs]; num_es = num_self_es = 0; char s[32]; for (int h = 0; h < num_vs; ++h) { bool line_ended = false; while (!line_ended) { for (int i = 0; ; ++i) { s[i] = getc(f); if ('9' < s[i] || s[i] < '0') { line_ended = s[i] == '\n'; if (i != 0) { s[i] = '\0'; const int t = atoi(s); al[t].push_back(h); ++num_es; if (h == t) ++num_self_es; } break; } } } } heads = new int[num_es]; tails = new int[num_vs]; for (int tails_i = 0, heads_i = 0; tails_i < num_vs; ++tails_i) { tails[tails_i] = heads_i; for (int j = 0; j < (int) al[tails_i].size(); ++j) heads[heads_i++] = al[tails_i][j]; } delete[] al; } prpack_base_graph::prpack_base_graph(int nverts, int nedges, std::pair* edges) { initialize(); num_vs = nverts; num_es = nedges; // fill in heads and tails num_self_es = 0; int* hs = new int[num_es]; int* ts = new int[num_es]; tails = new int[num_vs]; memset(tails, 0, num_vs*sizeof(tails[0])); for (int i = 0; i < num_es; ++i) { assert(edges[i].first >= 0 && edges[i].first < num_vs); assert(edges[i].second >= 0 && edges[i].second < num_vs); hs[i] = edges[i].first; ts[i] = edges[i].second; ++tails[ts[i]]; if (hs[i] == ts[i]) ++num_self_es; } for (int i = 0, sum = 0; i < num_vs; ++i) { int temp = sum; sum += tails[i]; tails[i] = temp; } heads = new int[num_es]; int* osets = new int[num_vs]; memset(osets, 0, num_vs*sizeof(osets[0])); for (int i = 0; i < num_es; ++i) heads[tails[ts[i]] + osets[ts[i]]++] = hs[i]; // clean up delete[] hs; delete[] ts; delete[] osets; } /** Normalize the edge weights to sum to one. */ void prpack_base_graph::normalize_weights() { if (!vals) { // skip normalizing weights if not using values return; } std::vector rowsums(num_vs,0.); // the graph is in a compressed in-edge list. for (int i=0; i namespace prpack { // Result class. class prpack_result { public: // instance variables int num_vs; int num_es; double* x; double read_time; double preprocess_time; double compute_time; long num_es_touched; std::string method; int converged; // constructor prpack_result(); // destructor ~prpack_result(); }; } #endif leidenbase/src/core/centrality/prpack/prpack_result.cpp0000644000176200001440000000025514447675374023133 0ustar liggesusers#include "prpack_result.h" #include using namespace prpack; prpack_result::prpack_result() { x = NULL; } prpack_result::~prpack_result() { delete[] x; } leidenbase/src/core/centrality/prpack/prpack_base_graph.h0000644000176200001440000000240714447675374023356 0ustar liggesusers#ifndef PRPACK_ADJACENCY_LIST #define PRPACK_ADJACENCY_LIST #include "prpack_csc.h" #include "prpack_csr.h" #include "prpack_edge_list.h" #include #include namespace prpack { class prpack_base_graph { private: // helper methods void initialize(); void read_smat(std::FILE* f, const bool weighted); void read_edges(std::FILE* f); void read_ascii(std::FILE* f); public: // instance variables int num_vs; int num_es; int num_self_es; int* heads; int* tails; double* vals; // constructors prpack_base_graph(); // only to support inheritance prpack_base_graph(const prpack_csc* g); prpack_base_graph(const prpack_int64_csc* g); prpack_base_graph(const prpack_csr* g); prpack_base_graph(const prpack_edge_list* g); prpack_base_graph(const char* filename, const char* format, const bool weighted); prpack_base_graph(int nverts, int nedges, std::pair* edges); // destructor ~prpack_base_graph(); // operations void normalize_weights(); }; } #endif leidenbase/src/core/centrality/prpack/prpack_csc.h0000644000176200001440000000102514447675374022026 0ustar liggesusers#ifndef PRPACK_CSC #define PRPACK_CSC #if !defined(_MSC_VER) && !defined (__MINGW32__) && !defined (__MINGW64__) # include #else # include typedef __int64 int64_t; #endif namespace prpack { class prpack_csc { public: int num_vs; int num_es; int* heads; int* tails; }; class prpack_int64_csc { public: int64_t num_vs; int64_t num_es; int64_t* heads; int64_t* tails; }; } #endif leidenbase/src/core/centrality/prpack/prpack_csr.h0000644000176200001440000000032414447675374022046 0ustar liggesusers#ifndef PRPACK_CSR #define PRPACK_CSR namespace prpack { class prpack_csr { public: int num_vs; int num_es; int* heads; int* tails; }; } #endif leidenbase/src/core/centrality/prpack/prpack_solver.h0000644000176200001440000001547114447675374022602 0ustar liggesusers#ifndef PRPACK_SOLVER #define PRPACK_SOLVER #include "prpack_base_graph.h" #include "prpack_csc.h" #include "prpack_csr.h" #include "prpack_edge_list.h" #include "prpack_preprocessed_ge_graph.h" #include "prpack_preprocessed_gs_graph.h" #include "prpack_preprocessed_scc_graph.h" #include "prpack_preprocessed_schur_graph.h" #include "prpack_result.h" // TODO Make this a user configurable variable #define PRPACK_SOLVER_MAX_ITERS 1000000 namespace prpack { // Solver class. class prpack_solver { private: // instance variables double read_time; prpack_base_graph* bg; prpack_preprocessed_ge_graph* geg; prpack_preprocessed_gs_graph* gsg; prpack_preprocessed_schur_graph* sg; prpack_preprocessed_scc_graph* sccg; bool owns_bg; // methods void initialize(); static prpack_result* solve_via_ge( const double alpha, const double tol, const int num_vs, const double* matrix, const double* uv); static prpack_result* solve_via_ge_uv( const double alpha, const double tol, const int num_vs, const double* matrix, const double* d, const double* u, const double* v); static prpack_result* solve_via_gs( const double alpha, const double tol, const int num_vs, const int num_es, const int* heads, const int* tails, const double* vals, const double* ii, const double* d, const double* num_outlinks, const double* u, const double* v); static prpack_result* solve_via_gs_err( const double alpha, const double tol, const int num_vs, const int num_es, const int* heads, const int* tails, const double* ii, const double* num_outlinks, const double* u, const double* v); static prpack_result* solve_via_schur_gs( const double alpha, const double tol, const int num_vs, const int num_no_in_vs, const int num_no_out_vs, const int num_es, const int* heads, const int* tails, const double* vals, const double* ii, const double* d, const double* num_outlinks, const double* uv, const int* encoding, const int* decoding, const bool should_normalize = true); static prpack_result* solve_via_schur_gs_uv( const double alpha, const double tol, const int num_vs, const int num_no_in_vs, const int num_no_out_vs, const int num_es, const int* heads, const int* tails, const double* vals, const double* ii, const double* d, const double* num_outlinks, const double* u, const double* v, const int* encoding, const int* decoding); static prpack_result* solve_via_scc_gs( const double alpha, const double tol, const int num_vs, const int num_es_inside, const int* heads_inside, const int* tails_inside, const double* vals_inside, const int num_es_outside, const int* heads_outside, const int* tails_outside, const double* vals_outside, const double* ii, const double* d, const double* num_outlinks, const double* uv, const int num_comps, const int* divisions, const int* encoding, const int* decoding, const bool should_normalize = true); static prpack_result* solve_via_scc_gs_uv( const double alpha, const double tol, const int num_vs, const int num_es_inside, const int* heads_inside, const int* tails_inside, const double* vals_inside, const int num_es_outside, const int* heads_outside, const int* tails_outside, const double* vals_outside, const double* ii, const double* d, const double* num_outlinks, const double* u, const double* v, const int num_comps, const int* divisions, const int* encoding, const int* decoding); static void ge(const int sz, double* A, double* b); static void normalize(const int length, double* x); static prpack_result* combine_uv( const int num_vs, const double* d, const double* num_outlinks, const int* encoding, const double alpha, const prpack_result* ret_u, const prpack_result* ret_v); public: // constructors prpack_solver(const prpack_csc* g); prpack_solver(const prpack_int64_csc* g); prpack_solver(const prpack_csr* g); prpack_solver(const prpack_edge_list* g); prpack_solver(prpack_base_graph* g, bool owns_bg=true); prpack_solver(const char* filename, const char* format, const bool weighted); // destructor ~prpack_solver(); // methods int get_num_vs(); prpack_result* solve(const double alpha, const double tol, const char* method); prpack_result* solve( const double alpha, const double tol, const double* u, const double* v, const char* method); }; } #endif leidenbase/src/core/centrality/prpack/prpack_igraph_graph.h0000644000176200001440000000076614447675374023724 0ustar liggesusers#ifndef PRPACK_IGRAPH_GRAPH #define PRPACK_IGRAPH_GRAPH #ifdef PRPACK_IGRAPH_SUPPORT #include "prpack_base_graph.h" struct igraph_s; struct igraph_vector_t; namespace prpack { class prpack_igraph_graph : public prpack_base_graph { public: // constructors explicit prpack_igraph_graph(const struct igraph_s* g, const struct igraph_vector_t* weights = 0, bool directed = true); }; } // PRPACK_IGRAPH_SUPPORT #endif // PRPACK_IGRAPH_GRAPH #endif leidenbase/src/core/centrality/prpack/prpack_igraph_graph.cpp0000644000176200001440000000770314447675374024255 0ustar liggesusers#include "prpack_igraph_graph.h" #include #include #include "igraph_interface.h" using namespace prpack; using namespace std; #ifdef PRPACK_IGRAPH_SUPPORT prpack_igraph_graph::prpack_igraph_graph(const igraph_t* g, const igraph_vector_t* weights, bool directed) { const igraph_bool_t treat_as_directed = igraph_is_directed(g) && directed; igraph_es_t es; igraph_eit_t eit; igraph_vector_t neis; long int i, j, eid, sum, temp, num_ignored_es; int *p_head, *p_head_copy; double* p_weight = 0; // Get the number of vertices and edges. For undirected graphs, we add // an edge in both directions. num_vs = igraph_vcount(g); num_es = igraph_ecount(g); num_self_es = 0; if (!treat_as_directed) { num_es *= 2; } // Allocate memory for heads and tails p_head = heads = new int[num_es]; tails = new int[num_vs]; memset(tails, 0, num_vs * sizeof(tails[0])); // Allocate memory for weights if needed if (weights != 0) { p_weight = vals = new double[num_es]; } // Count the number of ignored edges (those with negative or zero weight) num_ignored_es = 0; if (treat_as_directed) { // Select all the edges and iterate over them by the source vertices es = igraph_ess_all(IGRAPH_EDGEORDER_TO); // Add the edges igraph_eit_create(g, es, &eit); while (!IGRAPH_EIT_END(eit)) { eid = IGRAPH_EIT_GET(eit); IGRAPH_EIT_NEXT(eit); // Handle the weight if (weights != 0) { // Does this edge have zero or negative weight? if (VECTOR(*weights)[eid] <= 0) { // Ignore it. num_ignored_es++; continue; } *p_weight = VECTOR(*weights)[eid]; ++p_weight; } *p_head = IGRAPH_FROM(g, eid); ++p_head; ++tails[IGRAPH_TO(g, eid)]; if (IGRAPH_FROM(g, eid) == IGRAPH_TO(g, eid)) { ++num_self_es; } } igraph_eit_destroy(&eit); } else { // Select all the edges and iterate over them by the target vertices igraph_vector_init(&neis, 0); for (i = 0; i < num_vs; i++) { igraph_incident(g, &neis, i, IGRAPH_ALL); temp = igraph_vector_size(&neis); // TODO: should loop edges be added in both directions? p_head_copy = p_head; for (j = 0; j < temp; j++) { if (weights != 0) { if (VECTOR(*weights)[(long int)VECTOR(neis)[j]] <= 0) { // Ignore num_ignored_es++; continue; } *p_weight = VECTOR(*weights)[(long int)VECTOR(neis)[j]]; ++p_weight; } *p_head = IGRAPH_OTHER(g, VECTOR(neis)[j], i); if (i == *p_head) { num_self_es++; } ++p_head; } tails[i] = p_head - p_head_copy; } igraph_vector_destroy(&neis); } // Decrease num_es by the number of ignored edges num_es -= num_ignored_es; // Finalize the tails vector for (i = 0, sum = 0; i < num_vs; ++i) { temp = sum; sum += tails[i]; tails[i] = temp; } // Normalize the weights normalize_weights(); // Debug /* printf("Heads:"); for (i = 0; i < num_es; ++i) { printf(" %d", heads[i]); } printf("\n"); printf("Tails:"); for (i = 0; i < num_vs; ++i) { printf(" %d", tails[i]); } printf("\n"); if (vals) { printf("Vals:"); for (i = 0; i < num_es; ++i) { printf(" %.4f", vals[i]); } printf("\n"); } printf("===========================\n"); */ } // PRPACK_IGRAPH_SUPPORT #endif leidenbase/src/core/centrality/prpack/prpack_preprocessed_schur_graph.h0000644000176200001440000000167314447675374026352 0ustar liggesusers#ifndef PRPACK_PREPROCESSED_SCHUR_GRAPH #define PRPACK_PREPROCESSED_SCHUR_GRAPH #include "prpack_preprocessed_graph.h" #include "prpack_base_graph.h" namespace prpack { class prpack_preprocessed_schur_graph : public prpack_preprocessed_graph { private: // helper methods void initialize(); void initialize_weighted(const prpack_base_graph* bg); void initialize_unweighted(const prpack_base_graph* bg); public: // instance variables int num_no_in_vs; int num_no_out_vs; int* heads; int* tails; double* vals; double* ii; double* num_outlinks; int* encoding; int* decoding; // constructors prpack_preprocessed_schur_graph(const prpack_base_graph* bg); // destructor ~prpack_preprocessed_schur_graph(); }; } #endif leidenbase/src/core/centrality/prpack/prpack_solver.cpp0000644000176200001440000007310514447675374023133 0ustar liggesusers#include "prpack_solver.h" #include "prpack_utils.h" #include #include #include #include #include using namespace prpack; using namespace std; void prpack_solver::initialize() { geg = NULL; gsg = NULL; sg = NULL; sccg = NULL; owns_bg = true; } prpack_solver::prpack_solver(const prpack_csc* g) { initialize(); TIME(read_time, bg = new prpack_base_graph(g)); } prpack_solver::prpack_solver(const prpack_int64_csc* g) { initialize(); TIME(read_time, bg = new prpack_base_graph(g)); } prpack_solver::prpack_solver(const prpack_csr* g) { initialize(); TIME(read_time, bg = new prpack_base_graph(g)); } prpack_solver::prpack_solver(const prpack_edge_list* g) { initialize(); TIME(read_time, bg = new prpack_base_graph(g)); } prpack_solver::prpack_solver(prpack_base_graph* g, bool owns_bg) { initialize(); this->owns_bg = owns_bg; TIME(read_time, bg = g); } prpack_solver::prpack_solver(const char* filename, const char* format, const bool weighted) { initialize(); TIME(read_time, bg = new prpack_base_graph(filename, format, weighted)); } prpack_solver::~prpack_solver() { if (owns_bg) { delete bg; } delete geg; delete gsg; delete sg; delete sccg; } int prpack_solver::get_num_vs() { return bg->num_vs; } prpack_result* prpack_solver::solve(const double alpha, const double tol, const char* method) { return solve(alpha, tol, NULL, NULL, method); } prpack_result* prpack_solver::solve( const double alpha, const double tol, const double* u, const double* v, const char* method) { double preprocess_time = 0; double compute_time = 0; prpack_result* ret = NULL; // decide which method to run string m; if (strcmp(method, "") != 0) m = string(method); else { if (bg->num_vs < 128) m = "ge"; else if (sccg != NULL) m = "sccgs"; else if (sg != NULL) m = "sg"; else m = "sccgs"; if (u != v) m += "_uv"; } // run the appropriate method if (m == "ge") { if (geg == NULL) { TIME(preprocess_time, geg = new prpack_preprocessed_ge_graph(bg)); } TIME(compute_time, ret = solve_via_ge( alpha, tol, geg->num_vs, geg->matrix, u)); } else if (m == "ge_uv") { if (geg == NULL) { TIME(preprocess_time, geg = new prpack_preprocessed_ge_graph(bg)); } TIME(compute_time, ret = solve_via_ge_uv( alpha, tol, geg->num_vs, geg->matrix, geg->d, u, v)); } else if (m == "gs") { if (gsg == NULL) { TIME(preprocess_time, gsg = new prpack_preprocessed_gs_graph(bg)); } TIME(compute_time, ret = solve_via_gs( alpha, tol, gsg->num_vs, gsg->num_es, gsg->heads, gsg->tails, gsg->vals, gsg->ii, gsg->d, gsg->num_outlinks, u, v)); } else if (m == "gserr") { if (gsg == NULL) { TIME(preprocess_time, gsg = new prpack_preprocessed_gs_graph(bg)); } TIME(compute_time, ret = solve_via_gs_err( alpha, tol, gsg->num_vs, gsg->num_es, gsg->heads, gsg->tails, gsg->ii, gsg->num_outlinks, u, v)); } else if (m == "sgs") { if (sg == NULL) { TIME(preprocess_time, sg = new prpack_preprocessed_schur_graph(bg)); } TIME(compute_time, ret = solve_via_schur_gs( alpha, tol, sg->num_vs, sg->num_no_in_vs, sg->num_no_out_vs, sg->num_es, sg->heads, sg->tails, sg->vals, sg->ii, sg->d, sg->num_outlinks, u, sg->encoding, sg->decoding)); } else if (m == "sgs_uv") { if (sg == NULL) { TIME(preprocess_time, sg = new prpack_preprocessed_schur_graph(bg)); } TIME(compute_time, ret = solve_via_schur_gs_uv( alpha, tol, sg->num_vs, sg->num_no_in_vs, sg->num_no_out_vs, sg->num_es, sg->heads, sg->tails, sg->vals, sg->ii, sg->d, sg->num_outlinks, u, v, sg->encoding, sg->decoding)); } else if (m == "sccgs") { if (sccg == NULL) { TIME(preprocess_time, sccg = new prpack_preprocessed_scc_graph(bg)); } TIME(compute_time, ret = solve_via_scc_gs( alpha, tol, sccg->num_vs, sccg->num_es_inside, sccg->heads_inside, sccg->tails_inside, sccg->vals_inside, sccg->num_es_outside, sccg->heads_outside, sccg->tails_outside, sccg->vals_outside, sccg->ii, sccg->d, sccg->num_outlinks, u, sccg->num_comps, sccg->divisions, sccg->encoding, sccg->decoding)); } else if (m == "sccgs_uv") { if (sccg == NULL) { TIME(preprocess_time, sccg = new prpack_preprocessed_scc_graph(bg)); } TIME(compute_time, ret = solve_via_scc_gs_uv( alpha, tol, sccg->num_vs, sccg->num_es_inside, sccg->heads_inside, sccg->tails_inside, sccg->vals_inside, sccg->num_es_outside, sccg->heads_outside, sccg->tails_outside, sccg->vals_outside, sccg->ii, sccg->d, sccg->num_outlinks, u, v, sccg->num_comps, sccg->divisions, sccg->encoding, sccg->decoding)); } else { throw invalid_argument("Unknown method specified for PRPACK: '" + m + "'."); } ret->method = m; ret->read_time = read_time; ret->preprocess_time = preprocess_time; ret->compute_time = compute_time; ret->num_vs = bg->num_vs; ret->num_es = bg->num_es; return ret; } // VARIOUS SOLVING METHODS //////////////////////////////////////////////////////////////////////// prpack_result* prpack_solver::solve_via_ge( const double alpha, const double tol, const int num_vs, const double* matrix, const double* uv) { prpack_result* ret = new prpack_result(); // initialize uv values const double uv_const = 1.0/num_vs; const int uv_exists = (uv) ? 1 : 0; uv = (uv) ? uv : &uv_const; // create matrix A double* A = new double[num_vs*num_vs]; for (int i = 0; i < num_vs*num_vs; ++i) A[i] = -alpha*matrix[i]; for (int i = 0; i < num_vs*num_vs; i += num_vs + 1) ++A[i]; // create vector b double* b = new double[num_vs]; for (int i = 0; i < num_vs; ++i) b[i] = uv[uv_exists*i]; // solve and normalize ge(num_vs, A, b); normalize(num_vs, b); // clean up and return delete[] A; ret->num_es_touched = -1; ret->x = b; return ret; } prpack_result* prpack_solver::solve_via_ge_uv( const double alpha, const double tol, const int num_vs, const double* matrix, const double* d, const double* u, const double* v) { prpack_result* ret = new prpack_result(); // initialize u and v values const double u_const = 1.0/num_vs; const double v_const = 1.0/num_vs; const int u_exists = (u) ? 1 : 0; const int v_exists = (v) ? 1 : 0; u = (u) ? u : &u_const; v = (v) ? v : &v_const; // create matrix A double* A = new double[num_vs*num_vs]; for (int i = 0; i < num_vs*num_vs; ++i) A[i] = -alpha*matrix[i]; for (int i = 0, inum_vs = 0; i < num_vs; ++i, inum_vs += num_vs) for (int j = 0; j < num_vs; ++j) A[inum_vs + j] -= alpha*u[u_exists*i]*d[j]; for (int i = 0; i < num_vs*num_vs; i += num_vs + 1) ++A[i]; // create vector b double* b = new double[num_vs]; for (int i = 0; i < num_vs; ++i) b[i] = (1 - alpha)*v[v_exists*i]; // solve ge(num_vs, A, b); // clean up and return delete[] A; ret->num_es_touched = -1; ret->x = b; return ret; } // Vanilla Gauss-Seidel. prpack_result* prpack_solver::solve_via_gs( const double alpha, const double tol, const int num_vs, const int num_es, const int* heads, const int* tails, const double* vals, const double* ii, const double* d, const double* num_outlinks, const double* u, const double* v) { prpack_result* ret = new prpack_result(); const bool weighted = vals != NULL; // initialize u and v values const double u_const = 1.0/num_vs; const double v_const = 1.0/num_vs; const int u_exists = (u) ? 1 : 0; const int v_exists = (v) ? 1 : 0; u = (u) ? u : &u_const; v = (v) ? v : &v_const; // initialize the eigenvector (and use personalization vector) double* x = new double[num_vs]; for (int i = 0; i < num_vs; ++i) x[i] = 0; // initialize delta double delta = 0; // run Gauss-Seidel ret->num_es_touched = 0; double err = 1, c = 0; do { if (weighted) { for (int i = 0; i < num_vs; ++i) { double new_val = 0; const int start_j = tails[i]; const int end_j = (i + 1 != num_vs) ? tails[i + 1] : num_es; for (int j = start_j; j < end_j; ++j) // TODO: might want to use compensation summation for large: end_j - start_j new_val += x[heads[j]]*vals[j]; new_val = alpha*new_val + (1 - alpha)*v[v_exists*i]; delta -= alpha*x[i]*d[i]; new_val += delta*u[u_exists*i]; new_val /= 1 - alpha*(d[i]*u[u_exists*i] + (1 - d[i])*ii[i]); delta += alpha*new_val*d[i]; COMPENSATED_SUM(err, x[i] - new_val, c); x[i] = new_val; } } else { for (int i = 0; i < num_vs; ++i) { const double old_val = x[i]*num_outlinks[i]; double new_val = 0; const int start_j = tails[i]; const int end_j = (i + 1 != num_vs) ? tails[i + 1] : num_es; for (int j = start_j; j < end_j; ++j) // TODO: might want to use compensation summation for large: end_j - start_j new_val += x[heads[j]]; new_val = alpha*new_val + (1 - alpha)*v[v_exists*i]; if (num_outlinks[i] < 0) { delta -= alpha*old_val; new_val += delta*u[u_exists*i]; new_val /= 1 - alpha*u[u_exists*i]; delta += alpha*new_val; } else { new_val += delta*u[u_exists*i]; new_val /= 1 - alpha*ii[i]; } COMPENSATED_SUM(err, old_val - new_val, c); x[i] = new_val/num_outlinks[i]; } } // update iteration index ret->num_es_touched += num_es; } while (err >= tol); // undo num_outlinks transformation if (!weighted) for (int i = 0; i < num_vs; ++i) x[i] *= num_outlinks[i]; // return results ret->x = x; return ret; } // Implement a gauss-seidel-like process with a strict error bound // we return a solution with 1-norm error less than tol. prpack_result* prpack_solver::solve_via_gs_err( const double alpha, const double tol, const int num_vs, const int num_es, const int* heads, const int* tails, const double* ii, const double* num_outlinks, const double* u, const double* v) { prpack_result* ret = new prpack_result(); // initialize u and v values const double u_const = 1.0/num_vs; const double v_const = 1.0/num_vs; const int u_exists = (u) ? 1 : 0; const int v_exists = (v) ? 1 : 0; u = (u) ? u : &u_const; v = (v) ? v : &v_const; // Note to Dave, we can't rescale v because we could be running this // same routine from multiple threads. // initialize the eigenvector (and use personalization vector) double* x = new double[num_vs]; for (int i = 0; i < num_vs; ++i) { x[i] = 0.; } // initialize delta double delta = 0.; // run Gauss-Seidel, note that we store x/deg[i] throughout this // iteration. int64_t maxedges = (int64_t)((double)num_es*std::min( log(tol)/log(alpha), (double)PRPACK_SOLVER_MAX_ITERS)); ret->num_es_touched = 0; double err=1., c = 0.; do { // iterate through vertices for (int i = 0; i < num_vs; ++i) { double old_val = x[i]*num_outlinks[i]; // adjust back to the "true" value. double new_val = 0.; int start_j = tails[i], end_j = (i + 1 != num_vs) ? tails[i + 1] : num_es; for (int j = start_j; j < end_j; ++j) { // TODO: might want to use compensation summation for large: end_j - start_j new_val += x[heads[j]]; } new_val = alpha*new_val + alpha*ii[i]*old_val + (1.0-alpha)*v[v_exists*i]; new_val += delta*u[u_exists*i]; // add the dangling node adjustment if (num_outlinks[i] < 0) { delta += alpha*(new_val - old_val); } // note that new_val > old_val, but the fabs is just for COMPENSATED_SUM(err, -(new_val - old_val), c); x[i] = new_val/num_outlinks[i]; } // update iteration index ret->num_es_touched += num_es; } while (err >= tol && ret->num_es_touched < maxedges); if (err >= tol) { ret->converged = 0; } else { ret->converged = 1; } // undo num_outlinks transformation for (int i = 0; i < num_vs; ++i) x[i] *= num_outlinks[i]; // return results ret->x = x; return ret; } // Gauss-Seidel using the Schur complement to separate dangling nodes. prpack_result* prpack_solver::solve_via_schur_gs( const double alpha, const double tol, const int num_vs, const int num_no_in_vs, const int num_no_out_vs, const int num_es, const int* heads, const int* tails, const double* vals, const double* ii, const double* d, const double* num_outlinks, const double* uv, const int* encoding, const int* decoding, const bool should_normalize) { prpack_result* ret = new prpack_result(); const bool weighted = vals != NULL; // initialize uv values const double uv_const = 1.0/num_vs; const int uv_exists = (uv) ? 1 : 0; uv = (uv) ? prpack_utils::permute(num_vs, uv, encoding) : &uv_const; // initialize the eigenvector (and use personalization vector) double* x = new double[num_vs]; for (int i = 0; i < num_vs - num_no_out_vs; ++i) x[i] = uv[uv_exists*i]/(1 - alpha*ii[i])/((weighted) ? 1 : num_outlinks[i]); // run Gauss-Seidel for the top left part of (I - alpha*P)*x = uv ret->num_es_touched = 0; double err, c; do { // iterate through vertices int num_es_touched = 0; err = c = 0; #ifdef _OPENMP #pragma omp parallel for firstprivate(c) reduction(+:err, num_es_touched) schedule(dynamic, 64) #endif for (int i = num_no_in_vs; i < num_vs - num_no_out_vs; ++i) { double new_val = 0; const int start_j = tails[i]; const int end_j = (i + 1 != num_vs) ? tails[i + 1] : num_es; if (weighted) { for (int j = start_j; j < end_j; ++j) // TODO: might want to use compensation summation for large: end_j - start_j new_val += x[heads[j]]*vals[j]; COMPENSATED_SUM(err, fabs(uv[uv_exists*i] + alpha*new_val - (1 - alpha*ii[i])*x[i]), c); new_val = (alpha*new_val + uv[uv_exists*i])/(1 - alpha*ii[i]); x[i] = new_val; } else { for (int j = start_j; j < end_j; ++j) // TODO: might want to use compensation summation for large: end_j - start_j new_val += x[heads[j]]; COMPENSATED_SUM(err, fabs(uv[uv_exists*i] + alpha*new_val - (1 - alpha*ii[i])*x[i]*num_outlinks[i]), c); new_val = (alpha*new_val + uv[uv_exists*i])/(1 - alpha*ii[i]); x[i] = new_val/num_outlinks[i]; } num_es_touched += end_j - start_j; } // update iteration index ret->num_es_touched += num_es_touched; } while (err/(1 - alpha) >= tol); // solve for the dangling nodes int num_es_touched = 0; #ifdef _OPENMP #pragma omp parallel for reduction(+:num_es_touched) schedule(dynamic, 64) #endif for (int i = num_vs - num_no_out_vs; i < num_vs; ++i) { x[i] = 0; const int start_j = tails[i]; const int end_j = (i + 1 != num_vs) ? tails[i + 1] : num_es; for (int j = start_j; j < end_j; ++j) x[i] += x[heads[j]]*((weighted) ? vals[j] : 1); x[i] = (alpha*x[i] + uv[uv_exists*i])/(1 - alpha*ii[i]); num_es_touched += end_j - start_j; } ret->num_es_touched += num_es_touched; // undo num_outlinks transformation if (!weighted) for (int i = 0; i < num_vs - num_no_out_vs; ++i) x[i] *= num_outlinks[i]; // normalize x to get the solution for: (I - alpha*P - alpha*u*d')*x = (1 - alpha)*v if (should_normalize) normalize(num_vs, x); // return results ret->x = prpack_utils::permute(num_vs, x, decoding); delete[] x; if (uv_exists) delete[] uv; return ret; } prpack_result* prpack_solver::solve_via_schur_gs_uv( const double alpha, const double tol, const int num_vs, const int num_no_in_vs, const int num_no_out_vs, const int num_es, const int* heads, const int* tails, const double* vals, const double* ii, const double* d, const double* num_outlinks, const double* u, const double* v, const int* encoding, const int* decoding) { // solve uv = u prpack_result* ret_u = solve_via_schur_gs( alpha, tol, num_vs, num_no_in_vs, num_no_out_vs, num_es, heads, tails, vals, ii, d, num_outlinks, u, encoding, decoding, false); // solve uv = v prpack_result* ret_v = solve_via_schur_gs( alpha, tol, num_vs, num_no_in_vs, num_no_out_vs, num_es, heads, tails, vals, ii, d, num_outlinks, v, encoding, decoding, false); // combine the u and v cases return combine_uv(num_vs, d, num_outlinks, encoding, alpha, ret_u, ret_v); } /** Gauss-Seidel using strongly connected components. * Notes: * If not weighted, then we store x[i] = "x[i]/outdegree" to * avoid additional arithmetic. We don't do this for the weighted * case because the adjustment may not be constant. */ prpack_result* prpack_solver::solve_via_scc_gs( const double alpha, const double tol, const int num_vs, const int num_es_inside, const int* heads_inside, const int* tails_inside, const double* vals_inside, const int num_es_outside, const int* heads_outside, const int* tails_outside, const double* vals_outside, const double* ii, const double* d, const double* num_outlinks, const double* uv, const int num_comps, const int* divisions, const int* encoding, const int* decoding, const bool should_normalize) { prpack_result* ret = new prpack_result(); const bool weighted = vals_inside != NULL; // initialize uv values const double uv_const = 1.0/num_vs; const int uv_exists = (uv) ? 1 : 0; uv = (uv) ? prpack_utils::permute(num_vs, uv, encoding) : &uv_const; // CHECK initialize the solution with one iteration of GS from x=0. double* x = new double[num_vs]; for (int i = 0; i < num_vs; ++i) x[i] = uv[uv_exists*i]/(1 - alpha*ii[i])/((weighted) ? 1 : num_outlinks[i]); // create x_outside double* x_outside = new double[num_vs]; // run Gauss-Seidel for (I - alpha*P)*x = uv ret->num_es_touched = 0; for (int comp_i = 0; comp_i < num_comps; ++comp_i) { const int start_comp = divisions[comp_i]; const int end_comp = (comp_i + 1 != num_comps) ? divisions[comp_i + 1] : num_vs; const bool parallelize = end_comp - start_comp > 512; // initialize relevant x_outside values for (int i = start_comp; i < end_comp; ++i) { x_outside[i] = 0; const int start_j = tails_outside[i]; const int end_j = (i + 1 != num_vs) ? tails_outside[i + 1] : num_es_outside; for (int j = start_j; j < end_j; ++j) x_outside[i] += x[heads_outside[j]]*((weighted) ? vals_outside[j] : 1.); ret->num_es_touched += end_j - start_j; } double err, c; do { int num_es_touched = 0; err = c = 0; if (parallelize) { // iterate through vertices #ifdef _OPENMP #pragma omp parallel for firstprivate(c) reduction(+:err, num_es_touched) schedule(dynamic, 64) #endif for (int i = start_comp; i < end_comp; ++i) { double new_val = x_outside[i]; const int start_j = tails_inside[i]; const int end_j = (i + 1 != num_vs) ? tails_inside[i + 1] : num_es_inside; if (weighted) { for (int j = start_j; j < end_j; ++j) { // TODO: might want to use compensation summation for large: end_j - start_j new_val += x[heads_inside[j]]*vals_inside[j]; } COMPENSATED_SUM(err, fabs(uv[uv_exists*i] + alpha*new_val - (1 - alpha*ii[i])*x[i]), c); x[i] = (alpha*new_val + uv[uv_exists*i])/(1 - alpha*ii[i]); } else { for (int j = start_j; j < end_j; ++j) { // TODO: might want to use compensation summation for large: end_j - start_j new_val += x[heads_inside[j]]; } COMPENSATED_SUM(err, fabs(uv[uv_exists*i] + alpha*new_val - (1 - alpha*ii[i])*x[i]*num_outlinks[i]), c); x[i] = (alpha*new_val + uv[uv_exists*i])/(1 - alpha*ii[i])/num_outlinks[i]; } num_es_touched += end_j - start_j; } } else { for (int i = start_comp; i < end_comp; ++i) { double new_val = x_outside[i]; const int start_j = tails_inside[i]; const int end_j = (i + 1 != num_vs) ? tails_inside[i + 1] : num_es_inside; if (weighted) { for (int j = start_j; j < end_j; ++j) { // TODO: might want to use compensation summation for large: end_j - start_j new_val += x[heads_inside[j]]*vals_inside[j]; } COMPENSATED_SUM(err, fabs(uv[uv_exists*i] + alpha*new_val - (1 - alpha*ii[i])*x[i]), c); x[i] = (alpha*new_val + uv[uv_exists*i])/(1 - alpha*ii[i]); } else { for (int j = start_j; j < end_j; ++j) { // TODO: might want to use compensation summation for large: end_j - start_j new_val += x[heads_inside[j]]; } COMPENSATED_SUM(err, fabs(uv[uv_exists*i] + alpha*new_val - (1 - alpha*ii[i])*x[i]*num_outlinks[i]), c); x[i] = (alpha*new_val + uv[uv_exists*i])/(1 - alpha*ii[i])/num_outlinks[i]; } num_es_touched += end_j - start_j; } } // update iteration index ret->num_es_touched += num_es_touched; } while (err/(1 - alpha) >= tol*(end_comp - start_comp)/num_vs); } // undo num_outlinks transformation if (!weighted) for (int i = 0; i < num_vs; ++i) x[i] *= num_outlinks[i]; // normalize x to get the solution for: (I - alpha*P - alpha*u*d')*x = (1 - alpha)*v if (should_normalize) normalize(num_vs, x); // return results ret->x = prpack_utils::permute(num_vs, x, decoding); delete[] x; delete[] x_outside; if (uv_exists) delete[] uv; return ret; } prpack_result* prpack_solver::solve_via_scc_gs_uv( const double alpha, const double tol, const int num_vs, const int num_es_inside, const int* heads_inside, const int* tails_inside, const double* vals_inside, const int num_es_outside, const int* heads_outside, const int* tails_outside, const double* vals_outside, const double* ii, const double* d, const double* num_outlinks, const double* u, const double* v, const int num_comps, const int* divisions, const int* encoding, const int* decoding) { // solve uv = u prpack_result* ret_u = solve_via_scc_gs( alpha, tol, num_vs, num_es_inside, heads_inside, tails_inside, vals_inside, num_es_outside, heads_outside, tails_outside, vals_outside, ii, d, num_outlinks, u, num_comps, divisions, encoding, decoding, false); // solve uv = v prpack_result* ret_v = solve_via_scc_gs( alpha, tol, num_vs, num_es_inside, heads_inside, tails_inside, vals_inside, num_es_outside, heads_outside, tails_outside, vals_outside, ii, d, num_outlinks, v, num_comps, divisions, encoding, decoding, false); // combine u and v return combine_uv(num_vs, d, num_outlinks, encoding, alpha, ret_u, ret_v); } // VARIOUS HELPER METHODS ///////////////////////////////////////////////////////////////////////// // Run Gaussian-Elimination (note: this changes A and returns the solution in b) void prpack_solver::ge(const int sz, double* A, double* b) { // put into triangular form for (int i = 0, isz = 0; i < sz; ++i, isz += sz) for (int k = 0, ksz = 0; k < i; ++k, ksz += sz) if (A[isz + k] != 0) { const double coeff = A[isz + k]/A[ksz + k]; A[isz + k] = 0; for (int j = k + 1; j < sz; ++j) A[isz + j] -= coeff*A[ksz + j]; b[i] -= coeff*b[k]; } // backwards substitution for (int i = sz - 1, isz = (sz - 1)*sz; i >= 0; --i, isz -= sz) { for (int j = i + 1; j < sz; ++j) b[i] -= A[isz + j]*b[j]; b[i] /= A[isz + i]; } } // Normalize a vector to sum to 1. void prpack_solver::normalize(const int length, double* x) { double norm = 0, c = 0; for (int i = 0; i < length; ++i) { COMPENSATED_SUM(norm, x[i], c); } norm = 1/norm; for (int i = 0; i < length; ++i) x[i] *= norm; } // Combine u and v results. prpack_result* prpack_solver::combine_uv( const int num_vs, const double* d, const double* num_outlinks, const int* encoding, const double alpha, const prpack_result* ret_u, const prpack_result* ret_v) { prpack_result* ret = new prpack_result(); const bool weighted = d != NULL; double delta_u = 0; double delta_v = 0; for (int i = 0; i < num_vs; ++i) { if ((weighted) ? (d[encoding[i]] == 1) : (num_outlinks[encoding[i]] < 0)) { delta_u += ret_u->x[i]; delta_v += ret_v->x[i]; } } const double s = ((1 - alpha)*alpha*delta_v)/(1 - alpha*delta_u); const double t = 1 - alpha; ret->x = new double[num_vs]; for (int i = 0; i < num_vs; ++i) ret->x[i] = s*ret_u->x[i] + t*ret_v->x[i]; ret->num_es_touched = ret_u->num_es_touched + ret_v->num_es_touched; // clean up and return delete ret_u; delete ret_v; return ret; } leidenbase/src/core/centrality/prpack/prpack_preprocessed_gs_graph.h0000644000176200001440000000153214447675374025631 0ustar liggesusers#ifndef PRPACK_PREPROCESSED_GS_GRAPH #define PRPACK_PREPROCESSED_GS_GRAPH #include "prpack_preprocessed_graph.h" #include "prpack_base_graph.h" namespace prpack { // Pre-processed graph class class prpack_preprocessed_gs_graph : public prpack_preprocessed_graph { private: // helper methods void initialize(); void initialize_weighted(const prpack_base_graph* bg); void initialize_unweighted(const prpack_base_graph* bg); public: // instance variables int* heads; int* tails; double* vals; double* ii; double* num_outlinks; // constructors prpack_preprocessed_gs_graph(const prpack_base_graph* bg); // destructor ~prpack_preprocessed_gs_graph(); }; } #endif leidenbase/src/core/centrality/prpack/prpack_preprocessed_scc_graph.h0000644000176200001440000000220214447675374025763 0ustar liggesusers#ifndef PRPACK_PREPROCESSED_SCC_GRAPH #define PRPACK_PREPROCESSED_SCC_GRAPH #include "prpack_preprocessed_graph.h" #include "prpack_base_graph.h" namespace prpack { // Pre-processed graph class class prpack_preprocessed_scc_graph : public prpack_preprocessed_graph { private: // helper methods void initialize(); void initialize_weighted(const prpack_base_graph* bg); void initialize_unweighted(const prpack_base_graph* bg); public: // instance variables int num_es_inside; int* heads_inside; int* tails_inside; double* vals_inside; int num_es_outside; int* heads_outside; int* tails_outside; double* vals_outside; double* ii; double* num_outlinks; int num_comps; int* divisions; int* encoding; int* decoding; // constructors prpack_preprocessed_scc_graph(const prpack_base_graph* bg); // destructor ~prpack_preprocessed_scc_graph(); }; } #endif leidenbase/src/core/centrality/prpack/prpack_preprocessed_schur_graph.cpp0000644000176200001440000001001414447675374026672 0ustar liggesusers#include "prpack_preprocessed_schur_graph.h" #include #include using namespace prpack; using namespace std; void prpack_preprocessed_schur_graph::initialize() { heads = NULL; tails = NULL; vals = NULL; ii = NULL; d = NULL; num_outlinks = NULL; encoding = NULL; decoding = NULL; } void prpack_preprocessed_schur_graph::initialize_weighted(const prpack_base_graph* bg) { // permute d ii = d; d = new double[num_vs]; for (int i = 0; i < num_vs; ++i) d[encoding[i]] = ii[i]; // convert bg to head/tail format for (int tails_i = 0, heads_i = 0; tails_i < num_vs; ++tails_i) { ii[tails_i] = 0; tails[tails_i] = heads_i; const int decoded = decoding[tails_i]; const int start_i = bg->tails[decoded]; const int end_i = (decoded + 1 != num_vs) ? bg->tails[decoded + 1] : bg->num_es; for (int i = start_i; i < end_i; ++i) { if (decoded == bg->heads[i]) ii[tails_i] += bg->vals[i]; else { heads[heads_i] = encoding[bg->heads[i]]; vals[heads_i] = bg->vals[i]; ++heads_i; } } } } void prpack_preprocessed_schur_graph::initialize_unweighted(const prpack_base_graph* bg) { // permute num_outlinks ii = num_outlinks; num_outlinks = new double[num_vs]; for (int i = 0; i < num_vs; ++i) num_outlinks[encoding[i]] = (ii[i] == 0) ? -1 : ii[i]; // convert bg to head/tail format for (int tails_i = 0, heads_i = 0; tails_i < num_vs; ++tails_i) { ii[tails_i] = 0; tails[tails_i] = heads_i; const int decoded = decoding[tails_i]; const int start_i = bg->tails[decoded]; const int end_i = (decoded + 1 != num_vs) ? bg->tails[decoded + 1] : bg->num_es; for (int i = start_i; i < end_i; ++i) { if (decoded == bg->heads[i]) ++ii[tails_i]; else heads[heads_i++] = encoding[bg->heads[i]]; } if (ii[tails_i] > 0) ii[tails_i] /= num_outlinks[tails_i]; } } prpack_preprocessed_schur_graph::prpack_preprocessed_schur_graph(const prpack_base_graph* bg) { initialize(); // initialize instance variables num_vs = bg->num_vs; num_es = bg->num_es - bg->num_self_es; tails = new int[num_vs]; heads = new int[num_es]; const bool weighted = bg->vals != NULL; if (weighted) { vals = new double[num_vs]; d = new double[num_vs]; fill(d, d + num_vs, 1); for (int i = 0; i < bg->num_es; ++i) d[bg->heads[i]] -= bg->vals[i]; } else { num_outlinks = new double[num_vs]; fill(num_outlinks, num_outlinks + num_vs, 0); for (int i = 0; i < bg->num_es; ++i) ++num_outlinks[bg->heads[i]]; } // permute no-inlink vertices to the beginning, and no-outlink vertices to the end encoding = new int[num_vs]; decoding = new int[num_vs]; num_no_in_vs = num_no_out_vs = 0; for (int i = 0; i < num_vs; ++i) { if (bg->tails[i] == ((i + 1 != num_vs) ? bg->tails[i + 1] : bg->num_es)) { decoding[encoding[i] = num_no_in_vs] = i; ++num_no_in_vs; } else if ((weighted) ? (d[i] == 1) : (num_outlinks[i] == 0)) { decoding[encoding[i] = num_vs - 1 - num_no_out_vs] = i; ++num_no_out_vs; } } // permute everything else for (int i = 0, p = num_no_in_vs; i < num_vs; ++i) if (bg->tails[i] < ((i + 1 != num_vs) ? bg->tails[i + 1] : bg->num_es) && ((weighted) ? (d[i] < 1) : (num_outlinks[i] > 0))) decoding[encoding[i] = p++] = i; // continue initialization based off of weightedness if (weighted) initialize_weighted(bg); else initialize_unweighted(bg); } prpack_preprocessed_schur_graph::~prpack_preprocessed_schur_graph() { delete[] heads; delete[] tails; delete[] vals; delete[] ii; delete[] d; delete[] num_outlinks; delete[] encoding; delete[] decoding; } leidenbase/src/core/centrality/prpack/prpack_utils.cpp0000644000176200001440000000261514447675374022757 0ustar liggesusers/** * @file prpack_utils.cpp * An assortment of utility functions for reporting errors, checking time, * and working with vectors. */ #include #include "prpack_utils.h" #include #include #include using namespace prpack; using namespace std; #ifdef PRPACK_IGRAPH_SUPPORT #include "igraph_error.h" #endif #if defined(_WIN32) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #include #endif double prpack_utils::get_time() { LARGE_INTEGER t, freq; QueryPerformanceCounter(&t); QueryPerformanceFrequency(&freq); return double(t.QuadPart)/double(freq.QuadPart); } #else #include #include double prpack_utils::get_time() { struct timeval t; gettimeofday(&t, 0); return (t.tv_sec*1.0 + t.tv_usec/1000000.0); } #endif // Fails and outputs 'msg' if 'condition' is false. void prpack_utils::validate(const bool condition, const string& msg) { if (!condition) { #ifdef PRPACK_IGRAPH_SUPPORT igraph_error("Internal error in PRPACK", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINTERNAL); #else cerr << msg << endl; exit(-1); #endif } } // Permute a vector. double* prpack_utils::permute(const int length, const double* a, const int* coding) { double* ret = new double[length]; for (int i = 0; i < length; ++i) ret[coding[i]] = a[i]; return ret; } leidenbase/src/core/centrality/prpack/prpack_preprocessed_ge_graph.h0000644000176200001440000000136214447675374025614 0ustar liggesusers#ifndef PRPACK_PREPROCESSED_GE_GRAPH #define PRPACK_PREPROCESSED_GE_GRAPH #include "prpack_preprocessed_graph.h" #include "prpack_base_graph.h" namespace prpack { // Pre-processed graph class class prpack_preprocessed_ge_graph : public prpack_preprocessed_graph { private: // helper methods void initialize(); void initialize_weighted(const prpack_base_graph* bg); void initialize_unweighted(const prpack_base_graph* bg); public: // instance variables double* matrix; // constructors prpack_preprocessed_ge_graph(const prpack_base_graph* bg); // destructor ~prpack_preprocessed_ge_graph(); }; } #endif leidenbase/src/core/centrality/prpack/prpack_preprocessed_ge_graph.cpp0000644000176200001440000000402614447675374026147 0ustar liggesusers#include "prpack_preprocessed_ge_graph.h" #include using namespace prpack; using namespace std; void prpack_preprocessed_ge_graph::initialize() { matrix = NULL; d = NULL; } void prpack_preprocessed_ge_graph::initialize_weighted(const prpack_base_graph* bg) { // initialize d fill(d, d + num_vs, 1); // fill in the matrix for (int i = 0, inum_vs = 0; i < num_vs; ++i, inum_vs += num_vs) { const int start_j = bg->tails[i]; const int end_j = (i + 1 != num_vs) ? bg->tails[i + 1] : bg->num_es; for (int j = start_j; j < end_j; ++j) { matrix[inum_vs + bg->heads[j]] += bg->vals[j]; d[bg->heads[j]] -= bg->vals[j]; } } } void prpack_preprocessed_ge_graph::initialize_unweighted(const prpack_base_graph* bg) { // fill in the matrix for (int i = 0, inum_vs = 0; i < num_vs; ++i, inum_vs += num_vs) { const int start_j = bg->tails[i]; const int end_j = (i + 1 != num_vs) ? bg->tails[i + 1] : bg->num_es; for (int j = start_j; j < end_j; ++j) ++matrix[inum_vs + bg->heads[j]]; } // normalize the columns for (int j = 0; j < num_vs; ++j) { double sum = 0; for (int inum_vs = 0; inum_vs < num_vs*num_vs; inum_vs += num_vs) sum += matrix[inum_vs + j]; if (sum > 0) { d[j] = 0; const double coeff = 1/sum; for (int inum_vs = 0; inum_vs < num_vs*num_vs; inum_vs += num_vs) matrix[inum_vs + j] *= coeff; } else { d[j] = 1; } } } prpack_preprocessed_ge_graph::prpack_preprocessed_ge_graph(const prpack_base_graph* bg) { initialize(); num_vs = bg->num_vs; num_es = bg->num_es; matrix = new double[num_vs*num_vs]; d = new double[num_vs]; fill(matrix, matrix + num_vs*num_vs, 0); if (bg->vals != NULL) initialize_weighted(bg); else initialize_unweighted(bg); } prpack_preprocessed_ge_graph::~prpack_preprocessed_ge_graph() { delete[] matrix; delete[] d; } leidenbase/src/core/centrality/prpack/prpack_preprocessed_gs_graph.cpp0000644000176200001440000000461514447675374026171 0ustar liggesusers#include "prpack_preprocessed_gs_graph.h" #include using namespace prpack; using namespace std; void prpack_preprocessed_gs_graph::initialize() { heads = NULL; tails = NULL; vals = NULL; ii = NULL; d = NULL; num_outlinks = NULL; } void prpack_preprocessed_gs_graph::initialize_weighted(const prpack_base_graph* bg) { vals = new double[num_es]; d = new double[num_vs]; fill(d, d + num_vs, 1); for (int tails_i = 0, heads_i = 0; tails_i < num_vs; ++tails_i) { tails[tails_i] = heads_i; ii[tails_i] = 0; const int start_j = bg->tails[tails_i]; const int end_j = (tails_i + 1 != num_vs) ? bg->tails[tails_i + 1]: bg->num_es; for (int j = start_j; j < end_j; ++j) { if (tails_i == bg->heads[j]) ii[tails_i] += bg->vals[j]; else { heads[heads_i] = bg->heads[j]; vals[heads_i] = bg->vals[j]; ++heads_i; } d[bg->heads[j]] -= bg->vals[j]; } } } void prpack_preprocessed_gs_graph::initialize_unweighted(const prpack_base_graph* bg) { num_outlinks = new double[num_vs]; fill(num_outlinks, num_outlinks + num_vs, 0); for (int tails_i = 0, heads_i = 0; tails_i < num_vs; ++tails_i) { tails[tails_i] = heads_i; ii[tails_i] = 0; const int start_j = bg->tails[tails_i]; const int end_j = (tails_i + 1 != num_vs) ? bg->tails[tails_i + 1]: bg->num_es; for (int j = start_j; j < end_j; ++j) { if (tails_i == bg->heads[j]) ++ii[tails_i]; else heads[heads_i++] = bg->heads[j]; ++num_outlinks[bg->heads[j]]; } } for (int i = 0; i < num_vs; ++i) { if (num_outlinks[i] == 0) num_outlinks[i] = -1; ii[i] /= num_outlinks[i]; } } prpack_preprocessed_gs_graph::prpack_preprocessed_gs_graph(const prpack_base_graph* bg) { initialize(); num_vs = bg->num_vs; num_es = bg->num_es - bg->num_self_es; heads = new int[num_es]; tails = new int[num_vs]; ii = new double[num_vs]; if (bg->vals != NULL) initialize_weighted(bg); else initialize_unweighted(bg); } prpack_preprocessed_gs_graph::~prpack_preprocessed_gs_graph() { delete[] heads; delete[] tails; delete[] vals; delete[] ii; delete[] d; delete[] num_outlinks; } leidenbase/src/core/centrality/centrality_other.c0000644000176200001440000016673714447675374022036 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2007-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "igraph_centrality.h" #include "igraph_memory.h" #include "igraph_random.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_progress.h" #include "igraph_structural.h" #include "igraph_topology.h" #include "igraph_stack.h" #include "igraph_dqueue.h" #include "centrality/prpack_internal.h" #include "core/indheap.h" #include "core/interruption.h" #include "core/math.h" #include "config.h" #include #include /* memset */ static int igraph_i_personalized_pagerank_arpack(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *reset, const igraph_vector_t *weights, igraph_arpack_options_t *options); static igraph_bool_t igraph_i_vector_mostly_negative(const igraph_vector_t *vector) { /* Many of the centrality measures correspond to the eigenvector of some * matrix. When v is an eigenvector, c*v is also an eigenvector, therefore * it may happen that all the scores in the eigenvector are negative, in which * case we want to negate them since the centrality scores should be positive. * However, since ARPACK is not always stable, sometimes it happens that * *some* of the centrality scores are small negative numbers. This function * helps distinguish between the two cases; it should return true if most of * the values are relatively large negative numbers, in which case we should * negate the eigenvector. */ long int n = igraph_vector_size(vector); igraph_real_t mi, ma; if (n == 0) { return 0; } igraph_vector_minmax(vector, &mi, &ma); if (mi >= 0) { return 0; } if (ma <= 0) { return 1; } /* is the most negative value larger in magnitude than the most positive? */ return (-mi/ma > 1); } static int igraph_i_eigenvector_centrality(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_adjlist_t *adjlist = extra; igraph_vector_int_t *neis; long int i, j, nlen; for (i = 0; i < n; i++) { neis = igraph_adjlist_get(adjlist, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; to[i] += from[nei]; } } return 0; } typedef struct igraph_i_eigenvector_centrality_t { const igraph_t *graph; const igraph_inclist_t *inclist; const igraph_vector_t *weights; } igraph_i_eigenvector_centrality_t; static int igraph_i_eigenvector_centrality2(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_eigenvector_centrality_t *data = extra; const igraph_t *graph = data->graph; const igraph_inclist_t *inclist = data->inclist; const igraph_vector_t *weights = data->weights; igraph_vector_int_t *edges; long int i, j, nlen; for (i = 0; i < n; i++) { edges = igraph_inclist_get(inclist, i); nlen = igraph_vector_int_size(edges); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int edge = VECTOR(*edges)[j]; long int nei = IGRAPH_OTHER(graph, edge, i); igraph_real_t w = VECTOR(*weights)[edge]; to[i] += w * from[nei]; } } return IGRAPH_SUCCESS; } static int igraph_i_eigenvector_centrality_undirected(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options) { igraph_vector_t values; igraph_matrix_t vectors; igraph_vector_t degree; long int i; options->n = igraph_vcount(graph); options->start = 1; /* no random start vector */ if (igraph_ecount(graph) == 0) { /* special case: empty graph */ if (value) { *value = 0; } if (vector) { igraph_vector_resize(vector, igraph_vcount(graph)); igraph_vector_fill(vector, 1); } return IGRAPH_SUCCESS; } if (weights) { igraph_real_t min, max; if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid length of weights vector when calculating " "eigenvector centrality", IGRAPH_EINVAL); } /* Safe to call minmax, ecount == 0 case was caught earlier */ IGRAPH_CHECK(igraph_vector_minmax(weights, &min, &max)); if (min == 0 && max == 0) { /* special case: all weights are zeros */ if (value) { *value = 0; } if (vector) { igraph_vector_resize(vector, igraph_vcount(graph)); igraph_vector_fill(vector, 1); } return IGRAPH_SUCCESS; } } IGRAPH_VECTOR_INIT_FINALLY(&values, 0); IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1); IGRAPH_VECTOR_INIT_FINALLY(°ree, options->n); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, /*loops=*/ 0)); RNG_BEGIN(); for (i = 0; i < options->n; i++) { if (VECTOR(degree)[i]) { MATRIX(vectors, i, 0) = VECTOR(degree)[i] + RNG_UNIF(-1e-4, 1e-4); } else { MATRIX(vectors, i, 0) = 1.0; } } RNG_END(); igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); options->n = igraph_vcount(graph); options->nev = 1; options->ncv = 0; /* 0 means "automatic" in igraph_arpack_rssolve */ options->which[0] = 'L'; options->which[1] = 'A'; options->start = 1; /* no random start vector */ if (!weights) { igraph_adjlist_t adjlist; IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_eigenvector_centrality, &adjlist, options, 0, &values, &vectors)); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); } else { igraph_inclist_t inclist; igraph_i_eigenvector_centrality_t data; data.graph = graph; data.inclist = &inclist; data.weights = weights; IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_eigenvector_centrality2, &data, options, 0, &values, &vectors)); igraph_inclist_destroy(&inclist); IGRAPH_FINALLY_CLEAN(1); } if (value) { *value = VECTOR(values)[0]; } if (vector) { igraph_real_t amax = 0; long int which = 0; long int i; IGRAPH_CHECK(igraph_vector_resize(vector, options->n)); if (VECTOR(values)[0] <= 0) { /* Pathological case: largest eigenvalue is zero, therefore all the * scores can also be zeros, this will be a valid eigenvector. * This usually happens with graphs that have lots of sinks and * sources only. */ igraph_vector_fill(vector, 0); } else { for (i = 0; i < options->n; i++) { igraph_real_t tmp; VECTOR(*vector)[i] = MATRIX(vectors, i, 0); tmp = fabs(VECTOR(*vector)[i]); if (tmp > amax) { amax = tmp; which = i; } } if (scale && amax != 0) { igraph_vector_scale(vector, 1 / VECTOR(*vector)[which]); } else if (igraph_i_vector_mostly_negative(vector)) { igraph_vector_scale(vector, -1.0); } /* Correction for numeric inaccuracies (eliminating -0.0) */ for (i = 0; i < options->n; i++) { if (VECTOR(*vector)[i] < 0) { VECTOR(*vector)[i] = 0; } } } } if (options->info) { IGRAPH_WARNING("Non-zero return code from ARPACK routine!"); } igraph_matrix_destroy(&vectors); igraph_vector_destroy(&values); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /* int igraph_i_evcent_dir(igraph_real_t *to, const igraph_real_t *from, */ /* long int n, void *extra) { */ /* /\* TODO *\/ */ /* return 0; */ /* } */ /* int igraph_i_evcent_dir2(igraph_real_t *to, const igraph_real_t *from, */ /* long int n, void *extra) { */ /* /\* TODO *\/ */ /* return 0; */ /* } */ static int igraph_i_eigenvector_centrality_directed(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options) { igraph_matrix_t values; igraph_matrix_t vectors; igraph_vector_t indegree; igraph_bool_t dag; long int i; if (igraph_ecount(graph) == 0) { /* special case: empty graph */ if (value) { *value = 0; } if (vector) { igraph_vector_resize(vector, igraph_vcount(graph)); igraph_vector_fill(vector, 1); } return IGRAPH_SUCCESS; } /* Quick check: if the graph is a DAG, all the eigenvector centralities are * zeros, and so is the eigenvalue */ IGRAPH_CHECK(igraph_is_dag(graph, &dag)); if (dag) { /* special case: graph is a DAG */ IGRAPH_WARNING("graph is directed and acyclic; eigenvector centralities " "will be zeros"); if (value) { *value = 0; } if (vector) { igraph_vector_resize(vector, igraph_vcount(graph)); igraph_vector_fill(vector, 0); } return IGRAPH_SUCCESS; } if (weights) { igraph_real_t min, max; if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid length of weights vector when calculating " "eigenvector centrality", IGRAPH_EINVAL); } if (igraph_is_directed(graph)) { IGRAPH_WARNING("Weighted directed graph in eigenvector centrality"); } /* Safe to call minmax, ecount == 0 case was caught earlier */ IGRAPH_CHECK(igraph_vector_minmax(weights, &min, &max)); if (min < 0.0) { IGRAPH_WARNING("Negative weights, eigenpair might be complex"); } if (min == 0.0 && max == 0.0) { /* special case: all weights are zeros */ if (value) { *value = 0; } if (vector) { igraph_vector_resize(vector, igraph_vcount(graph)); igraph_vector_fill(vector, 1); } return IGRAPH_SUCCESS; } } options->n = igraph_vcount(graph); options->start = 1; options->nev = 1; options->ncv = 0; /* 0 means "automatic" in igraph_arpack_rnsolve */ /* LM mode is not OK here because +1 and -1 can be eigenvalues at the * same time, e.g.: a -> b -> a, c -> a */ options->which[0] = 'L' ; options->which[1] = 'R'; IGRAPH_MATRIX_INIT_FINALLY(&values, 0, 0); IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1); IGRAPH_VECTOR_INIT_FINALLY(&indegree, options->n); IGRAPH_CHECK(igraph_strength(graph, &indegree, igraph_vss_all(), IGRAPH_IN, /*loops=*/ 1, weights)); RNG_BEGIN(); for (i = 0; i < options->n; i++) { if (VECTOR(indegree)[i]) { MATRIX(vectors, i, 0) = VECTOR(indegree)[i] + RNG_UNIF(-1e-4, 1e-4); } else { MATRIX(vectors, i, 0) = 1.0; } } RNG_END(); igraph_vector_destroy(&indegree); IGRAPH_FINALLY_CLEAN(1); if (!weights) { igraph_adjlist_t adjlist; IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_arpack_rnsolve(igraph_i_eigenvector_centrality, &adjlist, options, 0, &values, &vectors)); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); } else { igraph_inclist_t inclist; igraph_i_eigenvector_centrality_t data; data.graph = graph; data.inclist = &inclist; data.weights = weights; IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, IGRAPH_IN, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); IGRAPH_CHECK(igraph_arpack_rnsolve(igraph_i_eigenvector_centrality2, &data, options, 0, &values, &vectors)); igraph_inclist_destroy(&inclist); IGRAPH_FINALLY_CLEAN(1); } if (value) { *value = MATRIX(values, 0, 0); } if (vector) { igraph_real_t amax = 0; long int which = 0; long int i; IGRAPH_CHECK(igraph_vector_resize(vector, options->n)); if (MATRIX(values, 0, 0) <= 0) { /* Pathological case: largest eigenvalue is zero, therefore all the * scores can also be zeros, this will be a valid eigenvector. * This usually happens with graphs that have lots of sinks and * sources only. */ igraph_vector_fill(vector, 0); MATRIX(values, 0, 0) = 0; } else { for (i = 0; i < options->n; i++) { igraph_real_t tmp; VECTOR(*vector)[i] = MATRIX(vectors, i, 0); tmp = fabs(VECTOR(*vector)[i]); if (tmp > amax) { amax = tmp; which = i; } } if (scale && amax != 0) { igraph_vector_scale(vector, 1 / VECTOR(*vector)[which]); } else if (igraph_i_vector_mostly_negative(vector)) { igraph_vector_scale(vector, -1.0); } } /* Correction for numeric inaccuracies (eliminating -0.0) */ for (i = 0; i < options->n; i++) { if (VECTOR(*vector)[i] < 0) { VECTOR(*vector)[i] = 0; } } } if (options->info) { IGRAPH_WARNING("Non-zero return code from ARPACK routine!"); } igraph_matrix_destroy(&vectors); igraph_matrix_destroy(&values); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_eigenvector_centrality * Eigenvector centrality of the vertices * * Eigenvector centrality is a measure of the importance of a node in a * network. It assigns relative scores to all nodes in the network based * on the principle that connections from high-scoring nodes contribute * more to the score of the node in question than equal connections from * low-scoring nodes. Specifically, the eigenvector centrality of each * vertex is proportional to the sum of eigenvector centralities of its * neighbors. In practice, the centralities are determined by calculating the * eigenvector corresponding to the largest positive eigenvalue of the * adjacency matrix. In the undirected case, this function considers * the diagonal entries of the adjacency matrix to be \em twice the number of * self-loops on the corresponding vertex. * * * In the weighted case, the eigenvector centrality of a vertex is proportional * to the weighted sum of centralities of its neighbours, i.e. * c_i = sum_j w_ij c_j, where w_ij is the weight * of the edge connecting vertices \c i and \c j. The weights of parallel edges * are added up. * * * The centrality scores returned by igraph can be normalized * (using the \p scale parameter) such that the largest eigenvector centrality * score is 1 (with one exception, see below). * * * In the directed case, the left eigenvector of the adjacency matrix is * calculated. In other words, the centrality of a vertex is proportional * to the sum of centralities of vertices pointing to it. * * * Eigenvector centrality is meaningful only for connected graphs. * Graphs that are not connected should be decomposed into connected * components, and the eigenvector centrality calculated for each separately. * This function does not verify that the graph is connected. If it is not, * in the undirected case the scores of all but one component will be zeros. * * * Also note that the adjacency matrix of a directed acyclic graph or the * adjacency matrix of an empty graph does not possess positive eigenvalues, * therefore the eigenvector centrality is not defined for these graphs. * igraph will return an eigenvalue of zero in such cases. The eigenvector * centralities will all be equal for an empty graph and will all be zeros * for a directed acyclic graph. Such pathological cases can be detected * by asking igraph to calculate the eigenvalue as well (using the \p value * parameter, see below) and checking whether the eigenvalue is very close * to zero. * * \param graph The input graph. It may be directed. * \param vector Pointer to an initialized vector, it will be resized * as needed. The result of the computation is stored here. It can * be a null pointer, then it is ignored. * \param value If not a null pointer, then the eigenvalue * corresponding to the found eigenvector is stored here. * \param directed Boolean scalar, whether to consider edge directions * in a directed graph. It is ignored for undirected graphs. * \param scale If not zero then the result will be scaled such that * the absolute value of the maximum centrality is one. * \param weights A null pointer (= no edge weights), or a vector * giving the weights of the edges. The algorithm might produce * complex numbers when some weights are negative. In this case only * the real part is reported. * \param options Options to ARPACK. See \ref igraph_arpack_options_t * for details. Note that the function overwrites the * n (number of vertices) parameter and * it always starts the calculation from a non-random vector * calculated based on the degree of the vertices. * \return Error code. * * Time complexity: depends on the input graph, usually it is O(|V|+|E|). * * \sa \ref igraph_pagerank and \ref igraph_personalized_pagerank for * modifications of eigenvector centrality. * * \example examples/simple/eigenvector_centrality.c */ int igraph_eigenvector_centrality(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t directed, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options) { if (directed && igraph_is_directed(graph)) { return igraph_i_eigenvector_centrality_directed(graph, vector, value, scale, weights, options); } else { return igraph_i_eigenvector_centrality_undirected(graph, vector, value, scale, weights, options); } } /* struct for the unweighted variant of the HITS algorithm */ typedef struct igraph_i_kleinberg_data_t { igraph_adjlist_t *in; igraph_adjlist_t *out; igraph_vector_t *tmp; } igraph_i_kleinberg_data_t; /* struct for the weighted variant of the HITS algorithm */ typedef struct igraph_i_kleinberg_data2_t { const igraph_t *graph; igraph_inclist_t *in; igraph_inclist_t *out; igraph_vector_t *tmp; const igraph_vector_t *weights; } igraph_i_kleinberg_data2_t; /* ARPACK auxiliary routine for the unweighted HITS algorithm */ static int igraph_i_kleinberg_unweighted(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_kleinberg_data_t *data = (igraph_i_kleinberg_data_t*)extra; igraph_adjlist_t *in = data->in; igraph_adjlist_t *out = data->out; igraph_vector_t *tmp = data->tmp; igraph_vector_int_t *neis; long int i, j, nlen; for (i = 0; i < n; i++) { neis = igraph_adjlist_get(in, i); nlen = igraph_vector_int_size(neis); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; VECTOR(*tmp)[i] += from[nei]; } } for (i = 0; i < n; i++) { neis = igraph_adjlist_get(out, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; to[i] += VECTOR(*tmp)[nei]; } } return 0; } /* ARPACK auxiliary routine for the weighted HITS algorithm */ static int igraph_i_kleinberg_weighted(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_kleinberg_data2_t *data = (igraph_i_kleinberg_data2_t*)extra; igraph_inclist_t *in = data->in; igraph_inclist_t *out = data->out; igraph_vector_t *tmp = data->tmp; const igraph_vector_t *weights = data->weights; const igraph_t *g = data->graph; igraph_vector_int_t *neis; long int i, j, nlen; for (i = 0; i < n; i++) { neis = igraph_inclist_get(in, i); nlen = igraph_vector_int_size(neis); VECTOR(*tmp)[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei_edge = (long int) VECTOR(*neis)[j]; long int nei = IGRAPH_OTHER(g, nei_edge, i); VECTOR(*tmp)[i] += from[nei] * VECTOR(*weights)[nei_edge]; } } for (i = 0; i < n; i++) { neis = igraph_inclist_get(out, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei_edge = (long int) VECTOR(*neis)[j]; long int nei = IGRAPH_OTHER(g, nei_edge, i); to[i] += VECTOR(*tmp)[nei] * VECTOR(*weights)[nei_edge]; } } return 0; } static int igraph_i_kleinberg(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options, int inout) { igraph_adjlist_t myinadjlist, myoutadjlist; igraph_inclist_t myininclist, myoutinclist; igraph_adjlist_t *inadjlist, *outadjlist; igraph_inclist_t *ininclist, *outinclist; igraph_vector_t tmp; igraph_vector_t values; igraph_matrix_t vectors; igraph_i_kleinberg_data_t extra; igraph_i_kleinberg_data2_t extra2; long int i; if (igraph_ecount(graph) == 0 || igraph_vcount(graph) == 1) { /* special case: empty graph or single vertex */ if (value) { *value = igraph_ecount(graph) ? 1.0 : IGRAPH_NAN; } if (vector) { igraph_vector_resize(vector, igraph_vcount(graph)); igraph_vector_fill(vector, 1); } return IGRAPH_SUCCESS; } if (weights) { igraph_real_t min, max; if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid length of weights vector when calculating " "hub or authority scores", IGRAPH_EINVAL); } /* Safe to call minmax, ecount == 0 case was caught earlier */ IGRAPH_CHECK(igraph_vector_minmax(weights, &min, &max)); if (min == 0 && max == 0) { /* special case: all weights are zeros */ if (value) { *value = IGRAPH_NAN; } if (vector) { igraph_vector_resize(vector, igraph_vcount(graph)); igraph_vector_fill(vector, 1); } return IGRAPH_SUCCESS; } } options->n = igraph_vcount(graph); options->start = 1; /* no random start vector */ IGRAPH_VECTOR_INIT_FINALLY(&values, 0); IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1); IGRAPH_VECTOR_INIT_FINALLY(&tmp, options->n); if (inout == 0) { inadjlist = &myinadjlist; outadjlist = &myoutadjlist; ininclist = &myininclist; outinclist = &myoutinclist; } else if (inout == 1) { inadjlist = &myoutadjlist; outadjlist = &myinadjlist; ininclist = &myoutinclist; outinclist = &myininclist; } else { /* This should not happen */ IGRAPH_ERROR("Invalid 'inout' argument, please do not call " "this function directly", IGRAPH_FAILURE); } if (weights == 0) { IGRAPH_CHECK(igraph_adjlist_init(graph, &myinadjlist, IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &myinadjlist); IGRAPH_CHECK(igraph_adjlist_init(graph, &myoutadjlist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &myoutadjlist); } else { IGRAPH_CHECK(igraph_inclist_init(graph, &myininclist, IGRAPH_IN, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &myininclist); IGRAPH_CHECK(igraph_inclist_init(graph, &myoutinclist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &myoutinclist); } IGRAPH_CHECK(igraph_degree(graph, &tmp, igraph_vss_all(), IGRAPH_ALL, 0)); for (i = 0; i < options->n; i++) { if (VECTOR(tmp)[i] != 0) { MATRIX(vectors, i, 0) = VECTOR(tmp)[i]; } else { MATRIX(vectors, i, 0) = 1.0; } } extra.in = inadjlist; extra.out = outadjlist; extra.tmp = &tmp; extra2.in = ininclist; extra2.out = outinclist; extra2.tmp = &tmp; extra2.graph = graph; extra2.weights = weights; options->nev = 1; options->ncv = 0; /* 0 means "automatic" in igraph_arpack_rssolve */ options->which[0] = 'L'; options->which[1] = 'M'; if (weights == 0) { IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_kleinberg_unweighted, &extra, options, 0, &values, &vectors)); igraph_adjlist_destroy(&myoutadjlist); igraph_adjlist_destroy(&myinadjlist); IGRAPH_FINALLY_CLEAN(2); } else { IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_kleinberg_weighted, &extra2, options, 0, &values, &vectors)); igraph_inclist_destroy(&myoutinclist); igraph_inclist_destroy(&myininclist); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); if (value) { *value = VECTOR(values)[0]; } if (vector) { igraph_real_t amax = 0; long int which = 0; long int i; IGRAPH_CHECK(igraph_vector_resize(vector, options->n)); for (i = 0; i < options->n; i++) { igraph_real_t tmp; VECTOR(*vector)[i] = MATRIX(vectors, i, 0); tmp = fabs(VECTOR(*vector)[i]); if (tmp > amax) { amax = tmp; which = i; } } if (scale && amax != 0) { igraph_vector_scale(vector, 1 / VECTOR(*vector)[which]); } else if (igraph_i_vector_mostly_negative(vector)) { igraph_vector_scale(vector, -1.0); } /* Correction for numeric inaccuracies (eliminating -0.0) */ for (i = 0; i < options->n; i++) { if (VECTOR(*vector)[i] < 0) { VECTOR(*vector)[i] = 0; } } } if (options->info) { IGRAPH_WARNING("Non-zero return code from ARPACK routine!"); } igraph_matrix_destroy(&vectors); igraph_vector_destroy(&values); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_hub_score * \brief Kleinberg's hub scores. * * The hub scores of the vertices are defined as the principal * eigenvector of A*A^T, where A is the adjacency * matrix of the graph, A^T is its transposed. * * See the following reference on the meaning of this score: * J. Kleinberg. Authoritative sources in a hyperlinked * environment. \emb Proc. 9th ACM-SIAM Symposium on Discrete * Algorithms, \eme 1998. Extended version in \emb Journal of the * ACM \eme 46(1999). Also appears as IBM Research Report RJ 10076, May * 1997. * \param graph The input graph. Can be directed and undirected. * \param vector Pointer to an initialized vector, the result is * stored here. If a null pointer then it is ignored. * \param value If not a null pointer then the eigenvalue * corresponding to the calculated eigenvector is stored here. * \param scale If not zero then the result will be scaled such that * the absolute value of the maximum centrality is one. * \param weights A null pointer (=no edge weights), or a vector * giving the weights of the edges. * \param options Options to ARPACK. See \ref igraph_arpack_options_t * for details. Note that the function overwrites the * n (number of vertices) parameter and * it always starts the calculation from a non-random vector * calculated based on the degree of the vertices. * \return Error code. * * Time complexity: depends on the input graph, usually it is O(|V|), * the number of vertices. * * \sa \ref igraph_authority_score() for the companion measure, * \ref igraph_pagerank(), \ref igraph_personalized_pagerank(), * \ref igraph_eigenvector_centrality() for similar measures. */ int igraph_hub_score(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options) { return igraph_i_kleinberg(graph, vector, value, scale, weights, options, 0); } /** * \function igraph_authority_score * \brief Kleinerg's authority scores. * * The authority scores of the vertices are defined as the principal * eigenvector of A^T*A, where A is the adjacency * matrix of the graph, A^T is its transposed. * * See the following reference on the meaning of this score: * J. Kleinberg. Authoritative sources in a hyperlinked * environment. \emb Proc. 9th ACM-SIAM Symposium on Discrete * Algorithms, \eme 1998. Extended version in \emb Journal of the * ACM \eme 46(1999). Also appears as IBM Research Report RJ 10076, May * 1997. * \param graph The input graph. Can be directed and undirected. * \param vector Pointer to an initialized vector, the result is * stored here. If a null pointer then it is ignored. * \param value If not a null pointer then the eigenvalue * corresponding to the calculated eigenvector is stored here. * \param scale If not zero then the result will be scaled such that * the absolute value of the maximum centrality is one. * \param weights A null pointer (=no edge weights), or a vector * giving the weights of the edges. * \param options Options to ARPACK. See \ref igraph_arpack_options_t * for details. Note that the function overwrites the * n (number of vertices) parameter and * it always starts the calculation from a non-random vector * calculated based on the degree of the vertices. * \return Error code. * * Time complexity: depends on the input graph, usually it is O(|V|), * the number of vertices. * * \sa \ref igraph_hub_score() for the companion measure, * \ref igraph_pagerank(), \ref igraph_personalized_pagerank(), * \ref igraph_eigenvector_centrality() for similar measures. */ int igraph_authority_score(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options) { return igraph_i_kleinberg(graph, vector, value, scale, weights, options, 1); } typedef struct igraph_i_pagerank_data_t { const igraph_t *graph; igraph_adjlist_t *adjlist; igraph_real_t damping; igraph_vector_t *outdegree; igraph_vector_t *tmp; igraph_vector_t *reset; } igraph_i_pagerank_data_t; typedef struct igraph_i_pagerank_data2_t { const igraph_t *graph; igraph_inclist_t *inclist; const igraph_vector_t *weights; igraph_real_t damping; igraph_vector_t *outdegree; igraph_vector_t *tmp; igraph_vector_t *reset; } igraph_i_pagerank_data2_t; static int igraph_i_pagerank(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_pagerank_data_t *data = extra; igraph_adjlist_t *adjlist = data->adjlist; igraph_vector_t *outdegree = data->outdegree; igraph_vector_t *tmp = data->tmp; igraph_vector_t *reset = data->reset; igraph_vector_int_t *neis; long int i, j, nlen; igraph_real_t sumfrom = 0.0; igraph_real_t fact = 1 - data->damping; /* Calculate p(x) / outdegree(x) in advance for all the vertices. * Note that we may divide by zero here; this is intentional since * we won't use those values and we save a comparison this way. * At the same time, we calculate the global probability of a * random jump in `sumfrom`. For vertices with no outgoing edges, * we will surely jump from there if we are there, hence those * vertices contribute p(x) to the teleportation probability. * For vertices with some outgoing edges, we jump from there with * probability `fact` if we are there, hence they contribute * p(x)*fact */ for (i = 0; i < n; i++) { sumfrom += VECTOR(*outdegree)[i] != 0 ? from[i] * fact : from[i]; VECTOR(*tmp)[i] = from[i] / VECTOR(*outdegree)[i]; } /* Here we calculate the part of the `to` vector that results from * moving along links (and not from teleportation) */ for (i = 0; i < n; i++) { neis = igraph_adjlist_get(adjlist, i); nlen = igraph_vector_int_size(neis); to[i] = 0.0; for (j = 0; j < nlen; j++) { long int nei = (long int) VECTOR(*neis)[j]; to[i] += VECTOR(*tmp)[nei]; } to[i] *= data->damping; } /* Now we add the contribution from random jumps. `reset` is a vector * that defines the probability of ending up in vertex i after a jump. * `sumfrom` is the global probability of jumping as mentioned above. */ /* printf("sumfrom = %.6f\n", (float)sumfrom); */ if (reset) { /* Running personalized PageRank */ for (i = 0; i < n; i++) { to[i] += sumfrom * VECTOR(*reset)[i]; } } else { /* Traditional PageRank with uniform reset vector */ sumfrom /= n; for (i = 0; i < n; i++) { to[i] += sumfrom; } } return 0; } static int igraph_i_pagerank2(igraph_real_t *to, const igraph_real_t *from, int n, void *extra) { igraph_i_pagerank_data2_t *data = extra; const igraph_t *graph = data->graph; igraph_inclist_t *inclist = data->inclist; const igraph_vector_t *weights = data->weights; igraph_vector_t *outdegree = data->outdegree; igraph_vector_t *tmp = data->tmp; igraph_vector_t *reset = data->reset; long int i, j, nlen; igraph_real_t sumfrom = 0.0; igraph_vector_int_t *neis; igraph_real_t fact = 1 - data->damping; /* printf("PageRank weighted: multiplying vector: "); for (i=0; idamping; } /* printf("sumfrom = %.6f\n", (float)sumfrom); */ if (reset) { /* Running personalized PageRank */ for (i = 0; i < n; i++) { to[i] += sumfrom * VECTOR(*reset)[i]; } } else { /* Traditional PageRank with uniform reset vector */ sumfrom /= n; for (i = 0; i < n; i++) { to[i] += sumfrom; } } /* printf("PageRank weighted: multiplied vector: "); for (i=0; i1 - damping. * If the random walker gets stuck in a sink vertex, it will also restart * from a random vertex. * * * The PageRank centrality is mainly useful for directed graphs. In undirected * graphs it converges to trivial values proportional to degrees as the damping * factor approaches 1. * * * Starting from version 0.9, igraph has two PageRank implementations, * and the user can choose between them. The first implementation is * \c IGRAPH_PAGERANK_ALGO_ARPACK, based on the ARPACK library. This * was the default before igraph version 0.7. The second and recommended * implementation is \c IGRAPH_PAGERANK_ALGO_PRPACK. This is using the * PRPACK package, see https://github.com/dgleich/prpack . * * * Note that the PageRank of a given vertex depends on the PageRank * of all other vertices, so even if you want to calculate the PageRank for * only some of the vertices, all of them must be calculated. Requesting * the PageRank for only some of the vertices does not result in any * performance increase at all. * * * References: * * * Sergey Brin and Larry Page: The Anatomy of a Large-Scale Hypertextual * Web Search Engine. Proceedings of the 7th World-Wide Web Conference, * Brisbane, Australia, April 1998. * * \param graph The graph object. * \param algo The PageRank implementation to use. Possible values: * \c IGRAPH_PAGERANK_ALGO_ARPACK, \c IGRAPH_PAGERANK_ALGO_PRPACK. * \param vector Pointer to an initialized vector, the result is * stored here. It is resized as needed. * \param value Pointer to a real variable, the eigenvalue * corresponding to the PageRank vector is stored here. It should * be always exactly one. * \param vids The vertex ids for which the PageRank is returned. * \param directed Boolean, whether to consider the directedness of * the edges. This is ignored for undirected graphs. * \param damping The damping factor ("d" in the original paper). * Must be a probability in the range [0, 1]. A commonly used value is 0.85. * \param weights Optional edge weights. May be a \c NULL pointer, * meaning unweighted edges, or a vector of non-negative values * of the same length as the number of edges. * \param options Options for the ARPACK method. See \ref igraph_arpack_options_t * for details. Note that the function overwrites the n (number * of vertices), nev (1), ncv (3) and which * (LM) parameters and it always starts the calculation from a non-random vector * calculated based on the degree of the vertices. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for temporary data. * \c IGRAPH_EINVVID, invalid vertex id in \p vids. * * Time complexity: depends on the input graph, usually it is O(|E|), * the number of edges. * * \sa \ref igraph_personalized_pagerank() and \ref igraph_personalized_pagerank_vs() * for the personalized PageRank measure. See \ref igraph_arpack_rssolve() and * \ref igraph_arpack_rnsolve() for the underlying machinery used by * \c IGRAPH_PAGERANK_ALGO_ARPACK. * * \example examples/simple/igraph_pagerank.c */ int igraph_pagerank(const igraph_t *graph, igraph_pagerank_algo_t algo, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *weights, igraph_arpack_options_t *options) { return igraph_personalized_pagerank(graph, algo, vector, value, vids, directed, damping, NULL, weights, options); } /** * \function igraph_personalized_pagerank_vs * \brief Calculates the personalized Google PageRank for the specified vertices. * * The personalized PageRank is similar to the original PageRank measure, but * when the random walk is restarted, a new starting vertex is chosen according to * a specified distribution. * This distribution is used both when restarting randomly with probability * 1 - damping, and when the walker is forced to restart due to being * stuck in a sink vertex (a vertex with no outgoing edges). * * * This simplified interface takes a vertex sequence and resets the random walk to * one of the vertices in the specified vertex sequence, chosen uniformly. A typical * application of personalized PageRank is when the random walk is reset to the same * vertex every time - this can easily be achieved using \ref igraph_vss_1() which * generates a vertex sequence containing only a single vertex. * * * Note that the personalized PageRank of a given vertex depends on the * personalized PageRank of all other vertices, so even if you want to calculate * the personalized PageRank for only some of the vertices, all of them must be * calculated. Requesting the personalized PageRank for only some of the vertices * does not result in any performance increase at all. * * * * \param graph The graph object. * \param algo The PageRank implementation to use. Possible values: * \c IGRAPH_PAGERANK_ALGO_ARPACK, \c IGRAPH_PAGERANK_ALGO_PRPACK. * \param vector Pointer to an initialized vector, the result is * stored here. It is resized as needed. * \param value Pointer to a real variable, the eigenvalue * corresponding to the PageRank vector is stored here. It should * be always exactly one. * \param vids The vertex ids for which the PageRank is returned. * \param directed Boolean, whether to consider the directedness of * the edges. This is ignored for undirected graphs. * \param damping The damping factor ("d" in the original paper). * Must be a probability in the range [0, 1]. A commonly used value is 0.85. * \param reset_vids IDs of the vertices used when resetting the random walk. * \param weights Optional edge weights, it is either a null pointer, * then the edges are not weighted, or a vector of the same length * as the number of edges. * \param options Options for the ARPACK method. See \ref igraph_arpack_options_t * for details. Note that the function overwrites the n (number * of vertices), nev (1), ncv (3) and which * (LM) parameters and it always starts the calculation from a non-random vector * calculated based on the degree of the vertices. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * \c IGRAPH_EINVVID, invalid vertex id in * \p vids or an empty reset vertex sequence in * \p vids_reset. * * Time complexity: depends on the input graph, usually it is O(|E|), * the number of edges. * * \sa \ref igraph_pagerank() for the non-personalized implementation. */ int igraph_personalized_pagerank_vs(const igraph_t *graph, igraph_pagerank_algo_t algo, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, igraph_vs_t reset_vids, const igraph_vector_t *weights, igraph_arpack_options_t *options) { igraph_vector_t reset; igraph_vit_t vit; IGRAPH_VECTOR_INIT_FINALLY(&reset, igraph_vcount(graph)); IGRAPH_CHECK(igraph_vit_create(graph, reset_vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); while (!IGRAPH_VIT_END(vit)) { VECTOR(reset)[(long int)IGRAPH_VIT_GET(vit)]++; IGRAPH_VIT_NEXT(vit); } igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_personalized_pagerank(graph, algo, vector, value, vids, directed, damping, &reset, weights, options)); igraph_vector_destroy(&reset); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_personalized_pagerank * \brief Calculates the personalized Google PageRank for the specified vertices. * * The personalized PageRank is similar to the original PageRank measure, but * when the random walk is restarted, a new starting vertex is chosen non-uniformly, * according to the distribution specified in \p reset * (instead of the uniform distribution in the original PageRank measure). * The \p reset distribution is used both when restarting randomly with probability * 1 - damping, and when the walker is forced to restart due to being * stuck in a sink vertex (a vertex with no outgoing edges). * * * Note that the personalized PageRank of a given vertex depends on the * personalized PageRank of all other vertices, so even if you want to calculate * the personalized PageRank for only some of the vertices, all of them must be * calculated. Requesting the personalized PageRank for only some of the vertices * does not result in any performance increase at all. * * * * \param graph The graph object. * \param algo The PageRank implementation to use. Possible values: * \c IGRAPH_PAGERANK_ALGO_ARPACK, \c IGRAPH_PAGERANK_ALGO_PRPACK. * \param vector Pointer to an initialized vector, the result is * stored here. It is resized as needed. * \param value Pointer to a real variable, the eigenvalue * corresponding to the PageRank vector is stored here. It should * be always exactly one. * \param vids The vertex ids for which the PageRank is returned. * \param directed Boolean, whether to consider the directedness of * the edges. This is ignored for undirected graphs. * \param damping The damping factor ("d" in the original paper). * Must be a probability in the range [0, 1]. A commonly used value is 0.85. * \param reset The probability distribution over the vertices used when * resetting the random walk. It is either a \c NULL pointer (denoting * a uniform choice that results in the original PageRank measure) * or a vector of the same length as the number of vertices. * \param weights Optional edge weights. May be a \c NULL pointer, * meaning unweighted edges, or a vector of non-negative values * of the same length as the number of edges. * \param options Options for the ARPACK method. See \ref igraph_arpack_options_t * for details. Note that the function overwrites the n (number * of vertices), nev (1), ncv (3) and which * (LM) parameters and it always starts the calculation from a non-random vector * calculated based on the degree of the vertices. * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for * temporary data. * \c IGRAPH_EINVVID, invalid vertex id in * \p vids or an invalid reset vector in \p reset. * * Time complexity: depends on the input graph, usually it is O(|E|), * the number of edges. * * \sa \ref igraph_pagerank() for the non-personalized implementation, * \ref igraph_personalized_pagerank_vs() for a personalized implementation * with resetting to specific vertices. */ int igraph_personalized_pagerank(const igraph_t *graph, igraph_pagerank_algo_t algo, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *reset, const igraph_vector_t *weights, igraph_arpack_options_t *options) { if (damping < 0.0 || damping > 1.0) { IGRAPH_ERROR("The PageRank damping factor must be in the range [0,1].", IGRAPH_EINVAL); } if (algo == IGRAPH_PAGERANK_ALGO_ARPACK) { return igraph_i_personalized_pagerank_arpack(graph, vector, value, vids, directed, damping, reset, weights, options); } else if (algo == IGRAPH_PAGERANK_ALGO_PRPACK) { return igraph_i_personalized_pagerank_prpack(graph, vector, value, vids, directed, damping, reset, weights); } IGRAPH_ERROR("Unknown PageRank algorithm", IGRAPH_EINVAL); } /* * ARPACK-based implementation of \c igraph_personalized_pagerank. * * See \c igraph_personalized_pagerank for the documentation of the parameters. */ static int igraph_i_personalized_pagerank_arpack(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *reset, const igraph_vector_t *weights, igraph_arpack_options_t *options) { igraph_matrix_t values; igraph_matrix_t vectors; igraph_neimode_t dirmode; igraph_vector_t outdegree; igraph_vector_t indegree; igraph_vector_t tmp; igraph_vector_t normalized_reset; long int i; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); if (reset && igraph_vector_size(reset) != no_of_nodes) { IGRAPH_ERROR("Invalid length of reset vector when calculating personalized PageRank scores.", IGRAPH_EINVAL); } if (no_of_edges == 0) { /* Special case: graph with no edges. Result is the same as the personalization vector. */ if (value) { *value = 1.0; } if (vector) { IGRAPH_CHECK(igraph_vector_resize(vector, no_of_nodes)); if (reset && no_of_nodes > 0) { for (i=0; i < no_of_nodes; ++i) { VECTOR(*vector)[i] = VECTOR(*reset)[i]; } igraph_vector_scale(vector, 1.0 / igraph_vector_sum(vector)); } else { igraph_vector_fill(vector, 1.0 / no_of_nodes); } } return IGRAPH_SUCCESS; } options->n = (int) no_of_nodes; options->nev = 1; options->ncv = 0; /* 0 means "automatic" in igraph_arpack_rnsolve */ options->which[0] = 'L'; options->which[1] = 'M'; options->start = 1; /* no random start vector */ directed = directed && igraph_is_directed(graph); if (weights) { igraph_real_t min, max; if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Invalid length of weights vector when calculating PageRank scores.", IGRAPH_EINVAL); } /* Safe to call minmax, ecount == 0 case was caught earlier */ IGRAPH_CHECK(igraph_vector_minmax(weights, &min, &max)); if (igraph_is_nan(min)) { IGRAPH_ERROR("Weight vector must not contain NaN values.", IGRAPH_EINVAL); } if (min == 0 && max == 0) { /* Special case: all weights are zeros. Result is the same as the personalization vector. */ if (value) { *value = 1.0; } if (vector) { IGRAPH_CHECK(igraph_vector_resize(vector, no_of_nodes)); if (reset) { for (i=0; i < no_of_nodes; ++i) { VECTOR(*vector)[i] = VECTOR(*reset)[i]; } igraph_vector_scale(vector, 1.0 / igraph_vector_sum(vector)); } else { igraph_vector_fill(vector, 1.0 / no_of_nodes); } } return IGRAPH_SUCCESS; } } IGRAPH_MATRIX_INIT_FINALLY(&values, 0, 0); IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1); if (directed) { dirmode = IGRAPH_IN; } else { dirmode = IGRAPH_ALL; } IGRAPH_VECTOR_INIT_FINALLY(&indegree, options->n); IGRAPH_VECTOR_INIT_FINALLY(&outdegree, options->n); IGRAPH_VECTOR_INIT_FINALLY(&tmp, options->n); RNG_BEGIN(); if (reset) { /* Normalize reset vector so the sum is 1 */ double reset_sum, reset_min; reset_min = igraph_vector_min(reset); if (reset_min < 0) { IGRAPH_ERROR("The reset vector must not contain negative elements.", IGRAPH_EINVAL); } if (igraph_is_nan(reset_min)) { IGRAPH_ERROR("The reset vector must not contain NaN values.", IGRAPH_EINVAL); } reset_sum = igraph_vector_sum(reset); if (reset_sum == 0) { IGRAPH_ERROR("The sum of the elements in the reset vector must not be zero.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_copy(&normalized_reset, reset)); IGRAPH_FINALLY(igraph_vector_destroy, &normalized_reset); igraph_vector_scale(&normalized_reset, 1.0 / reset_sum); } if (!weights) { igraph_adjlist_t adjlist; igraph_i_pagerank_data_t data; data.graph = graph; data.adjlist = &adjlist; data.damping = damping; data.outdegree = &outdegree; data.tmp = &tmp; data.reset = reset ? &normalized_reset : NULL; IGRAPH_CHECK(igraph_degree(graph, &outdegree, igraph_vss_all(), directed ? IGRAPH_OUT : IGRAPH_ALL, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_degree(graph, &indegree, igraph_vss_all(), directed ? IGRAPH_IN : IGRAPH_ALL, IGRAPH_LOOPS)); /* Set up an appropriate starting vector. We start from the in-degrees * plus some small random noise to avoid convergence problems */ for (i = 0; i < options->n; i++) { if (VECTOR(indegree)[i]) { MATRIX(vectors, i, 0) = VECTOR(indegree)[i] + RNG_UNIF(-1e-4, 1e-4); } else { MATRIX(vectors, i, 0) = 1; } } IGRAPH_CHECK(igraph_adjlist_init( graph, &adjlist, dirmode, IGRAPH_LOOPS, IGRAPH_MULTIPLE )); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_arpack_rnsolve(igraph_i_pagerank, &data, options, 0, &values, &vectors)); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); } else { igraph_inclist_t inclist; igraph_bool_t negative_weight_warned = 0; igraph_i_pagerank_data2_t data; data.graph = graph; data.inclist = &inclist; data.weights = weights; data.damping = damping; data.outdegree = &outdegree; data.tmp = &tmp; data.reset = reset ? &normalized_reset : NULL; IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, dirmode, IGRAPH_LOOPS)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); /* Weighted degree */ for (i = 0; i < no_of_edges; i++) { long int from = IGRAPH_FROM(graph, i); long int to = IGRAPH_TO(graph, i); igraph_real_t weight = VECTOR(*weights)[i]; if (weight < 0 && !negative_weight_warned) { IGRAPH_WARNING("Replacing negative weights with zeros during PageRank calculation."); weight = 0; negative_weight_warned = 1; } VECTOR(outdegree)[from] += weight; VECTOR(indegree) [to] += weight; if (!directed) { VECTOR(outdegree)[to] += weight; VECTOR(indegree) [from] += weight; } } /* Set up an appropriate starting vector. We start from the in-degrees * plus some small random noise to avoid convergence problems */ for (i = 0; i < options->n; i++) { if (VECTOR(indegree)[i]) { MATRIX(vectors, i, 0) = VECTOR(indegree)[i] + RNG_UNIF(-1e-4, 1e-4); } else { MATRIX(vectors, i, 0) = 1; } } IGRAPH_CHECK(igraph_arpack_rnsolve(igraph_i_pagerank2, &data, options, 0, &values, &vectors)); igraph_inclist_destroy(&inclist); IGRAPH_FINALLY_CLEAN(1); } RNG_END(); if (reset) { igraph_vector_destroy(&normalized_reset); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&tmp); igraph_vector_destroy(&outdegree); igraph_vector_destroy(&indegree); IGRAPH_FINALLY_CLEAN(3); if (value) { *value = MATRIX(values, 0, 0); } if (vector) { long int i; igraph_vit_t vit; long int nodes_to_calc; igraph_real_t sum = 0; for (i = 0; i < no_of_nodes; i++) { sum += MATRIX(vectors, i, 0); } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); IGRAPH_CHECK(igraph_vector_resize(vector, nodes_to_calc)); for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { VECTOR(*vector)[i] = MATRIX(vectors, (long int)IGRAPH_VIT_GET(vit), 0); VECTOR(*vector)[i] /= sum; } igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); } if (options->info) { IGRAPH_WARNING("Non-zero return code from ARPACK routine!"); } igraph_matrix_destroy(&vectors); igraph_matrix_destroy(&values); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } leidenbase/src/core/centrality/prpack_internal.h0000644000176200001440000000275514447675374021625 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2007-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IGRAPH_PRPACK #define IGRAPH_PRPACK #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_datatype.h" #include "igraph_iterators.h" #include "igraph_interface.h" __BEGIN_DECLS int igraph_i_personalized_pagerank_prpack(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *reset, const igraph_vector_t *weights); __END_DECLS #endif leidenbase/src/core/hrg/0000755000176200001440000000000014532173045014650 5ustar liggesusersleidenbase/src/core/hrg/hrg_types.cc0000644000176200001440000036402414447675374017215 0ustar liggesusers// *********************************************************************** // *** COPYRIGHT NOTICE ************************************************** // rbtree - red-black tree (self-balancing binary tree data structure) // Copyright (C) 2004 Aaron Clauset // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.gnu.org/licenses/gpl.txt for more details. // // *********************************************************************** // Author : Aaron Clauset ( aaronc@santafe.edu | // http://www.santafe.edu/~aaronc/ ) // Collaborators: Cristopher Moore and Mark Newman // Project : Hierarchical Random Graphs // Location : University of New Mexico, Dept. of Computer Science // AND Santa Fe Institute // Created : Spring 2004 // Modified : many, many times // // *********************************************************************** #include "hrg/rbtree.h" #include "hrg/dendro.h" #include "hrg/graph.h" #include "hrg/splittree_eq.h" #include "hrg/graph_simp.h" #include "igraph_hrg.h" #include "igraph_constructors.h" #include "igraph_random.h" using namespace std; using namespace fitHRG; // ******** Red-Black Tree Methods *************************************** rbtree::rbtree() { root = new elementrb; leaf = new elementrb; leaf->parent = root; root->left = leaf; root->right = leaf; support = 0; } rbtree::~rbtree() { if (root != NULL && (root->left != leaf || root->right != leaf)) { deleteSubTree(root); } if (root) { delete root; } delete leaf; support = 0; root = 0; leaf = 0; } void rbtree::deleteTree() { if (root != NULL) { deleteSubTree(root); } } // does not leak memory void rbtree::deleteSubTree(elementrb *z) { if (z->left != leaf) { deleteSubTree(z->left); } if (z->right != leaf) { deleteSubTree(z->right); } delete z; } // ******** Search Functions ********************************************* // public search function - if there exists a elementrb in the tree // with key=searchKey, it returns TRUE and foundNode is set to point // to the found node; otherwise, it sets foundNode=NULL and returns // FALSE elementrb* rbtree::findItem(const int searchKey) { elementrb *current = root; // empty tree; bail out if (current->key == -1) { return NULL; } while (current != leaf) { // left-or-right? if (searchKey < current->key) { // try moving down-left if (current->left != leaf) { current = current->left; } else { // failure; bail out return NULL; } } else { // left-or-right? if (searchKey > current->key) { // try moving down-left if (current->right != leaf) { current = current->right; } else { // failure; bail out return NULL; } } else { // found (searchKey==current->key) return current; } } } return NULL; } int rbtree::returnValue(const int searchKey) { elementrb* test = findItem(searchKey); if (!test) { return 0; } else { return test->value; } } // ******** Return Item Functions **************************************** int* rbtree::returnArrayOfKeys() { int* array; array = new int [support]; bool flag_go = true; int index = 0; elementrb *curr; if (support == 1) { array[0] = root->key; } else if (support == 2) { array[0] = root->key; if (root->left == leaf) { array[1] = root->right->key; } else { array[1] = root->left->key; } } else { for (int i = 0; i < support; i++) { array[i] = -1; } // non-recursive traversal of tree structure curr = root; curr->mark = 1; while (flag_go) { // - is it time, and is left child the leaf node? if (curr->mark == 1 && curr->left == leaf) { curr->mark = 2; } // - is it time, and is right child the leaf node? if (curr->mark == 2 && curr->right == leaf) { curr->mark = 3; } if (curr->mark == 1) { // - go left curr->mark = 2; curr = curr->left; curr->mark = 1; } else if (curr->mark == 2) { // - else go right curr->mark = 3; curr = curr->right; curr->mark = 1; } else { // - else go up a level curr->mark = 0; array[index++] = curr->key; curr = curr->parent; if (curr == NULL) { flag_go = false; } } } } return array; } list* rbtree::returnListOfKeys() { keyValuePair *curr, *prev; list *head = 0, *tail = 0, *newlist; curr = returnTreeAsList(); while (curr != NULL) { newlist = new list; newlist->x = curr->x; if (head == NULL) { head = newlist; tail = head; } else { tail->next = newlist; tail = newlist; } prev = curr; curr = curr->next; delete prev; prev = NULL; } return head; } keyValuePair* rbtree::returnTreeAsList() { // pre-order traversal keyValuePair *head, *tail; head = new keyValuePair; head->x = root->key; head->y = root->value; tail = head; if (root->left != leaf) { tail = returnSubtreeAsList(root->left, tail); } if (root->right != leaf) { tail = returnSubtreeAsList(root->right, tail); } if (head->x == -1) { return NULL; /* empty tree */ } else { return head; } } keyValuePair* rbtree::returnSubtreeAsList(elementrb *z, keyValuePair *head) { keyValuePair *newnode, *tail; newnode = new keyValuePair; newnode->x = z->key; newnode->y = z->value; head->next = newnode; tail = newnode; if (z->left != leaf) { tail = returnSubtreeAsList(z->left, tail); } if (z->right != leaf) { tail = returnSubtreeAsList(z->right, tail); } return tail; } keyValuePair rbtree::returnMaxKey() { keyValuePair themax; elementrb *current; current = root; // search to bottom-right corner of tree while (current->right != leaf) { current = current->right; } themax.x = current->key; themax.y = current->value; return themax; } keyValuePair rbtree::returnMinKey() { keyValuePair themin; elementrb *current; current = root; // search to bottom-left corner of tree while (current->left != leaf) { current = current->left; } themin.x = current->key; themin.y = current->value; return themin; } // private functions for deleteItem() (although these could easily be // made public, I suppose) elementrb* rbtree::returnMinKey(elementrb *z) { elementrb *current; current = z; // search to bottom-right corner of tree while (current->left != leaf) { current = current->left; } return current; } elementrb* rbtree::returnSuccessor(elementrb *z) { elementrb *current, *w; w = z; // if right-subtree exists, return min of it if (w->right != leaf) { return returnMinKey(w->right); } // else search up in tree current = w->parent; while ((current != NULL) && (w == current->right)) { w = current; // move up in tree until find a non-right-child current = current->parent; } return current; } int rbtree::returnNodecount() { return support; } // ******** Insert Functions ********************************************* // public insert function void rbtree::insertItem(int newKey, int newValue) { // first we check to see if newKey is already present in the tree; // if so, we do nothing; if not, we must find where to insert the // key elementrb *newNode, *current; // find newKey in tree; return pointer to it O(log k) current = findItem(newKey); if (current == NULL) { newNode = new elementrb; // elementrb for the rbtree newNode->key = newKey; newNode->value = newValue; newNode->color = true; // new nodes are always RED newNode->parent = NULL; // new node initially has no parent newNode->left = leaf; // left leaf newNode->right = leaf; // right leaf support++; // increment node count in rbtree // must now search for where to insert newNode, i.e., find the // correct parent and set the parent and child to point to each // other properly current = root; if (current->key == -1) { // insert as root delete root; // delete old root root = newNode; // set root to newNode leaf->parent = newNode; // set leaf's parent current = leaf; // skip next loop } // search for insertion point while (current != leaf) { // left-or-right? if (newKey < current->key) { // try moving down-left if (current->left != leaf) { current = current->left; } else { // else found new parent newNode->parent = current; // set parent current->left = newNode; // set child current = leaf; // exit search } } else { // try moving down-right if (current->right != leaf) { current = current->right; } else { // else found new parent newNode->parent = current; // set parent current->right = newNode; // set child current = leaf; // exit search } } } // now do the house-keeping necessary to preserve the red-black // properties insertCleanup(newNode); } return; } // private house-keeping function for insertion void rbtree::insertCleanup(elementrb *z) { // fix now if z is root if (z->parent == NULL) { z->color = false; return; } elementrb *temp; // while z is not root and z's parent is RED while (z->parent != NULL && z->parent->color) { if (z->parent == z->parent->parent->left) { // z's parent is LEFT-CHILD temp = z->parent->parent->right; // grab z's uncle if (temp->color) { z->parent->color = false; // color z's parent BLACK (Case 1) temp->color = false; // color z's uncle BLACK (Case 1) z->parent->parent->color = true; // color z's grandpar. RED (Case 1) z = z->parent->parent; // set z = z's grandparent (Case 1) } else { if (z == z->parent->right) { // z is RIGHT-CHILD z = z->parent; // set z = z's parent (Case 2) rotateLeft(z); // perform left-rotation (Case 2) } z->parent->color = false; // color z's parent BLACK (Case 3) z->parent->parent->color = true; // color z's grandpar. RED (Case 3) rotateRight(z->parent->parent); // perform right-rotation (Case 3) } } else { // z's parent is RIGHT-CHILD temp = z->parent->parent->left; // grab z's uncle if (temp->color) { z->parent->color = false; // color z's parent BLACK (Case 1) temp->color = false; // color z's uncle BLACK (Case 1) z->parent->parent->color = true; // color z's grandpar. RED (Case 1) z = z->parent->parent; // set z = z's grandparent (Case 1) } else { if (z == z->parent->left) { // z is LEFT-CHILD z = z->parent; // set z = z's parent (Case 2) rotateRight(z); // perform right-rotation (Case 2) } z->parent->color = false; // color z's parent BLACK (Case 3) z->parent->parent->color = true; // color z's grandpar. RED (Case 3) rotateLeft(z->parent->parent); // perform left-rotation (Case 3) } } } root->color = false; // color the root BLACK return; } // ******** Delete // ******** Functions ********************************************* void rbtree::replaceItem(int key, int newValue) { elementrb* ptr; ptr = findItem(key); ptr->value = newValue; return; } void rbtree::incrementValue(int key) { elementrb* ptr; ptr = findItem(key); ptr->value = 1 + ptr->value; return; } // public delete function void rbtree::deleteItem(int killKey) { elementrb *x, *y, *z; z = findItem(killKey); if (z == NULL) { return; // item not present; bail out } if (support == 1) { // attempt to delete the root root->key = -1; // restore root node to default state root->value = -1; root->color = false; root->parent = NULL; root->left = leaf; root->right = leaf; support--; // set support to zero return; // exit - no more work to do } if (z != NULL) { support--; // decrement node count if ((z->left == leaf) || (z->right == leaf)) { y = z; // case of less than two children, // set y to be z } else { y = returnSuccessor(z); // set y to be z's key-successor } if (y->left != leaf) { x = y->left; // pick y's one child (left-child) } else { x = y->right; // (right-child) } x->parent = y->parent; // make y's child's parent be y's parent if (y->parent == NULL) { root = x; // if y is the root, x is now root } else { if (y == y->parent->left) { // decide y's relationship with y's parent y->parent->left = x; // replace x as y's parent's left child } else { y->parent->right = x; // replace x as y's parent's left child } } if (y != z) { // insert y into z's spot z->key = y->key; // copy y data into z z->value = y->value; } // do house-keeping to maintain balance if (y->color == false) { deleteCleanup(x); } delete y; y = NULL; } return; } void rbtree::deleteCleanup(elementrb *x) { elementrb *w, *t; // until x is the root, or x is RED while ((x != root) && (x->color == false)) { if (x == x->parent->left) { // branch on x being a LEFT-CHILD w = x->parent->right; // grab x's sibling if (w->color == true) { // if x's sibling is RED w->color = false; // color w BLACK (case 1) x->parent->color = true; // color x's parent RED (case 1) rotateLeft(x->parent); // left rotation on x's parent (case 1) w = x->parent->right; // make w be x's right sibling (case 1) } if ((w->left->color == false) && (w->right->color == false)) { w->color = true; // color w RED (case 2) x = x->parent; // examine x's parent (case 2) } else { if (w->right->color == false) { w->left->color = false; // color w's left child BLACK (case 3) w->color = true; // color w RED (case 3) t = x->parent; // store x's parent (case 3) rotateRight(w); // right rotation on w (case 3) x->parent = t; // restore x's parent (case 3) w = x->parent->right; // make w be x's right sibling (case 3) } w->color = x->parent->color; // w's color := x's parent's (case 4) x->parent->color = false; // color x's parent BLACK (case 4) w->right->color = false; // color w's right child BLACK (case 4) rotateLeft(x->parent); // left rotation on x's parent (case 4) x = root; // finished work. bail out (case 4) } } else { // x is RIGHT-CHILD w = x->parent->left; // grab x's sibling if (w->color == true) { // if x's sibling is RED w->color = false; // color w BLACK (case 1) x->parent->color = true; // color x's parent RED (case 1) rotateRight(x->parent); // right rotation on x's parent (case 1) w = x->parent->left; // make w be x's left sibling (case 1) } if ((w->right->color == false) && (w->left->color == false)) { w->color = true; // color w RED (case 2) x = x->parent; // examine x's parent (case 2) } else { if (w->left->color == false) { w->right->color = false; // color w's right child BLACK (case 3) w->color = true; // color w RED (case 3) t = x->parent; // store x's parent (case 3) rotateLeft(w); // left rotation on w (case 3) x->parent = t; // restore x's parent (case 3) w = x->parent->left; // make w be x's left sibling (case 3) } w->color = x->parent->color; // w's color := x's parent's (case 4) x->parent->color = false; // color x's parent BLACK (case 4) w->left->color = false; // color w's left child BLACK (case 4) rotateRight(x->parent); // right rotation on x's parent (case 4) x = root; // x is now the root (case 4) } } } x->color = false; // color x (the root) BLACK (exit) return; } // ******** Rotation Functions ****************************************** void rbtree::rotateLeft(elementrb *x) { elementrb *y; // do pointer-swapping operations for left-rotation y = x->right; // grab right child x->right = y->left; // make x's RIGHT-CHILD be y's LEFT-CHILD y->left->parent = x; // make x be y's LEFT-CHILD's parent y->parent = x->parent; // make y's new parent be x's old parent if (x->parent == NULL) { root = y; // if x was root, make y root } else { // if x is LEFT-CHILD, make y be x's parent's if (x == x->parent->left) { x->parent->left = y; // left-child } else { x->parent->right = y; // right-child } } y->left = x; // make x be y's LEFT-CHILD x->parent = y; // make y be x's parent return; } void rbtree::rotateRight(elementrb *y) { elementrb *x; // do pointer-swapping operations for right-rotation x = y->left; // grab left child y->left = x->right; // replace left child yith x's right subtree x->right->parent = y; // replace y as x's right subtree's parent x->parent = y->parent; // make x's new parent be y's old parent // if y was root, make x root if (y->parent == NULL) { root = x; } else { // if y is RIGHT-CHILD, make x be y's parent's if (y == y->parent->right) { // right-child y->parent->right = x; } else { // left-child y->parent->left = x; } } x->right = y; // make y be x's RIGHT-CHILD y->parent = x; // make x be y's parent return; } // *********************************************************************** // *** COPYRIGHT NOTICE ************************************************** // dendro.h - hierarchical random graph (hrg) data structure // Copyright (C) 2005-2009 Aaron Clauset // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.gnu.org/licenses/gpl.txt for more details. // // *********************************************************************** // Author : Aaron Clauset ( aaronc@santafe.edu | // http://www.santafe.edu/~aaronc/ ) // Collaborators: Cristopher Moore and Mark E.J. Newman // Project : Hierarchical Random Graphs // Location : University of New Mexico, Dept. of Computer Science // AND Santa Fe Institute // Created : 26 October 2005 - 7 December 2005 // Modified : 23 December 2007 (cleaned up for public consumption) // // *********************************************************************** // // Maximum likelihood dendrogram data structure. This is the heart of // the HRG algorithm: all manipulations are done here and all data is // stored here. The data structure uses the separate graph data // structure to store the basic adjacency information (in a // dangerously mutable way). // // *********************************************************************** // ******** Dendrogram Methods ******************************************* dendro::dendro(): root(0), internal(0), leaf(0), d(0), splithist(0), paths(0), ctree(0), cancestor(0), g(0) { } dendro::~dendro() { list *curr, *prev; if (g) { delete g; // O(m) g = 0; } if (internal) { delete [] internal; // O(n) internal = 0; } if (leaf) { delete [] leaf; // O(n) leaf = 0; } if (d) { delete d; // O(n) d = 0; } if (splithist) { delete splithist; // potentially long splithist = 0; } if (paths) { for (int i = 0; i < n; i++) { curr = paths[i]; while (curr) { prev = curr; curr = curr->next; delete prev; prev = 0; } paths[i] = 0; } delete [] paths; } paths = 0; if (ctree) { delete [] ctree; // O(n) ctree = 0; } if (cancestor) { delete [] cancestor; // O(n) cancestor = 0; } } // ********************************************************************* void dendro::binarySearchInsert(elementd* x, elementd* y) { if (y->p < x->p) { // go to left subtree if (x->L == NULL) { // check if left subtree is empty x->L = y; // make x left child y->M = x; // make y parent of child return; } else { binarySearchInsert(x->L, y); } } else { // go to right subtree if (x->R == NULL) { // check if right subtree is empty x->R = y; // make x right child y->M = x; // make y parent of child return; } else { binarySearchInsert(x->R, y); } } return; } // ********************************************************************** list* dendro::binarySearchFind(const double v) { list *head = NULL, *tail = NULL, *newlist; elementd *current = root; bool flag_stopSearch = false; while (!flag_stopSearch) { // continue until we're finished newlist = new list; // add this node to the path newlist->x = current->label; if (current == root) { head = newlist; tail = head; } else { tail->next = newlist; tail = newlist; } if (v < current->p) { // now try left subtree if (current->L->type == GRAPH) { flag_stopSearch = true; } else { current = current->L; } } else { // else try right subtree if (current->R->type == GRAPH) { flag_stopSearch = true; } else { current = current->R; } } } return head; } // *********************************************************************** string dendro::buildSplit(elementd* thisNode) { // A "split" is defined as the bipartition of vertices into the sets // of leaves below the internal vertex in the tree (denoted by "C"), // and those above it (denoted as "M"). For simplicity, we represent // this bipartition as a character string of length n, where the ith // character denotes the partition membership (C,M) of the ith leaf // node. bool flag_go = true; const short int k = 1 + DENDRO + GRAPH; elementd* curr; split sp; sp.initializeSplit(n); // default split string O(n) curr = thisNode; // - set start node as top this sub-tree curr->type = k + 1; // - initialize in-order tree traversal while (flag_go) { // - is it time, and is left child a graph node? if (curr->type == k + 1 && curr->L->type == GRAPH) { sp.s[curr->L->index] = 'C'; // - mark this leaf curr->type = k + 2; } // - is it time, and is right child a graph node? if (curr->type == k + 2 && curr->R->type == GRAPH) { sp.s[curr->R->index] = 'C'; // - mark this leaf curr->type = k + 3; } if (curr->type == k + 1) { // - go left curr->type = k + 2; curr = curr->L; curr->type = k + 1; } else if (curr->type == k + 2) { // - else go right curr->type = k + 3; curr = curr->R; curr->type = k + 1; } else { // - else go up a level curr->type = DENDRO; if (curr->index == thisNode->index || curr->M == NULL) { flag_go = false; curr = NULL; } else { curr = curr->M; } } } // any leaf that was not already marked must be in the remainder of // the tree for (int i = 0; i < n; i++) { if (sp.s[i] != 'C') { sp.s[i] = 'M'; } } return sp.s; } // ********************************************************************** void dendro::buildDendrogram() { /* the initialization of the dendrogram structure goes like this: * 1) we allocate space for the n-1 internal nodes of the * dendrogram, and then the n leaf nodes * 2) we build a random binary tree structure out of the internal * nodes by assigning each a uniformly random value over [0,1] and * then inserting it into the tree according to the * binary-search rule. * 3) next, we make a random permutation of the n leaf nodes and add * them to the dendrogram D by replacing the emptpy spots in-order * 4) then, we compute the path from the root to each leaf and store * that in each leaf (this is prep work for the next step) * 5) finally, we compute the values for nL, nR, e (and thus p) and * the label for each internal node by allocating each of the m * edges in g to the appropriate internal node */ // --- Initialization and memory allocation for data structures // After allocating the memory for D and G, we need to mark the // nodes for G as being non-internal vertices, and then insert them // into a random binary tree structure. For simplicity, we make the // first internal node in the array the root. n = g->numNodes(); // size of graph leaf = new elementd [n]; // allocate memory for G, O(n) internal = new elementd [n - 1]; // allocate memory for D, O(n) d = new interns(n - 2); // allocate memory for internal // edges of D, O(n) for (int i = 0; i < n; i++) { // initialize leaf nodes leaf[i].type = GRAPH; leaf[i].label = i; leaf[i].index = i; leaf[i].n = 1; } // initialize internal nodes root = &internal[0]; root->label = 0; root->index = 0; root->p = RNG_UNIF01(); // insert remaining internal vertices, O(n log n) for (int i = 1; i < (n - 1); i++) { internal[i].label = i; internal[i].index = i; internal[i].p = RNG_UNIF01(); binarySearchInsert(root, &internal[i]); } // --- Hang leaf nodes off end of dendrogram O(n log n) // To impose this random hierarchical relationship on G, we first // take a random permutation of the leaf vertices and then replace // the NULLs at the bottom of the tree in-order with the leafs. As a // hack to ensure that we can find the leafs later using a binary // search, we assign each of them the p value of their parent, // perturbed slightly so as to preserve the binary search property. block* array; array = new block [n]; for (int i = 0; i < n; i++) { array[i].x = RNG_UNIF01(); array[i].y = i; } QsortMain(array, 0, n - 1); int k = 0; // replace NULLs with leaf nodes, and for (int i = 0; i < (n - 1); i++) { // maintain binary search property, O(n) if (internal[i].L == NULL) { internal[i].L = &leaf[array[k].y]; leaf[array[k].y].M = &internal[i]; leaf[array[k++].y].p = internal[i].p - 0.0000000000001; } if (internal[i].R == NULL) { internal[i].R = &leaf[array[k].y]; leaf[array[k].y].M = &internal[i]; leaf[array[k++].y].p = internal[i].p + 0.0000000000001; } } delete [] array; // --- Compute the path from root -> leaf for each leaf O(n log n) // Using the binary search property, we can find each leaf node in // O(log n) time. The binarySearchFind() function returns the list // of internal node indices that the search crossed, in the order of // root -> ... -> leaf, for use in the subsequent few operations. if (paths != NULL) { list *curr, *prev; for (int i = 0; i < n; i++) { curr = paths[i]; while (curr != NULL) { prev = curr; curr = curr->next; delete prev; prev = NULL; } paths[i] = NULL; } delete [] paths; } paths = NULL; paths = new list* [n]; for (int i = 0; i < n; i++) { paths[i] = binarySearchFind(leaf[i].p); } // --- Count e for each internal node O(m) // To count the number of edges that span the L and R subtrees for // each internal node, we use the path information we just // computed. Then, we loop over all edges in G and find the common // ancestor in D of the two endpoints and increment that internal // node's e count. This process takes O(m) time because in a roughly // balanced binary tree (given by our random dendrogram), the vast // majority of vertices take basically constant time to find their // common ancestor. Note that because our adjacency list is // symmetric, we overcount each e by a factor of 2, so we need to // correct this after. elementd* ancestor; edge* curr; for (int i = 0; i < (n - 1); i++) { internal[i].e = 0; internal[i].label = -1; } for (int i = 0; i < n; i++) { curr = g->getNeighborList(i); while (curr != NULL) { ancestor = findCommonAncestor(paths, i, curr->x); ancestor->e += 1; curr = curr->next; } } for (int i = 0; i < (n - 1); i++) { internal[i].e /= 2; } // --- Count n for each internal node O(n log n) // To tabulate the number of leafs in each subtree rooted at an // internal node, we use the path information computed above. for (int i = 0; i < n; i++) { ancestor = &leaf[i]; ancestor = ancestor->M; while (ancestor != NULL) { ancestor->n++; ancestor = ancestor->M; } } // --- Label all internal vertices O(n log n) // We want to label each internal vertex with the smallest leaf // index of its children. This will allow us to collapse many // leaf-orderings into a single dendrogram structure that is // independent of child-exhanges (since these have no impact on the // likelihood of the hierarchical structure). To do this, we loop // over the leaf vertices from smallest to largest and walk along // that leaf's path from the root. If we find an unlabeled internal // node, then we mark it with this leaf's index. for (int i = 0; i < n; i++) { ancestor = &leaf[i]; while (ancestor != NULL) { if (ancestor->label == -1 || ancestor->label > leaf[i].label) { ancestor->label = leaf[i].label; } ancestor = ancestor->M; } } // --- Exchange children to enforce order-property O(n) // We state that the order-property requires that an internal node's // label is the smallest index of its left subtree. The dendrogram // so far doesn't reflect this, so we need to step through each // internal vertex and make that adjustment (swapping nL and nR if // we make a change). elementd *tempe; for (int i = 0; i < (n - 1); i++) { if (internal[i].L->label > internal[i].label) { tempe = internal[i].L; internal[i].L = internal[i].R; internal[i].R = tempe; } } // --- Tabulate internal dendrogram edges O(n^2) // For the MCMC moves later on, we'll need to be able to choose, // uniformly at random, an internal edge of the dendrogram to // manipulate. There are always n-2 of them, and we can find them // simply by scanning across the internal vertices and observing // which have children that are also internal vertices. Note: very // important that the order property be enforced before this step is // taken; otherwise, the internal edges wont reflect the actual // dendrogram structure. for (int i = 0; i < (n - 1); i++) { if (internal[i].L->type == DENDRO) { d->addEdge(i, internal[i].L->index, LEFT); } if (internal[i].R->type == DENDRO) { d->addEdge(i, internal[i].R->index, RIGHT); } } // --- Clear memory for paths O(n log n) // Now that we're finished using the paths, we need to deallocate // them manually. list *current, *previous; for (int i = 0; i < n; i++) { current = paths[i]; while (current) { previous = current; current = current->next; delete previous; previous = NULL; } paths[i] = NULL; } delete [] paths; paths = NULL; // --- Compute p_i for each internal node O(n) // Each internal node's p_i = e_i / (nL_i*nR_i), and now that we // have each of those pieces, we may calculate this value for each // internal node. Given these, we can then calculate the // log-likelihood of the entire dendrogram structure \log(L) = // \sum_{i=1}^{n} ( ( e_i \log[p_i] ) + ( (nL_i*nR_i - e_i) // \log[1-p_i] ) ) L = 0.0; double dL; int nL_nR, ei; for (int i = 0; i < (n - 1); i++) { nL_nR = internal[i].L->n * internal[i].R->n; ei = internal[i].e; internal[i].p = (double)(ei) / (double)(nL_nR); if (ei == 0 || ei == nL_nR) { dL = 0.0; } else { dL = ei * log(internal[i].p) + (nL_nR - ei) * log(1.0 - internal[i].p); } internal[i].logL = dL; L += dL; } for (int i = 0; i < (n - 1); i++) { if (internal[i].label > internal[i].L->label) { tempe = internal[i].L; internal[i].L = internal[i].R; internal[i].R = tempe; } } // Dendrogram is now built return; } // *********************************************************************** void dendro::clearDendrograph() { // Clear out the memory and references used by the dendrograph // structure - this is intended to be called just before an // importDendrogramStructure call so as to avoid memory leaks and // overwriting the references therein. if (g != NULL) { delete g; // O(m) g = NULL; } if (leaf != NULL) { delete [] leaf; // O(n) leaf = NULL; } if (internal != NULL) { delete [] internal; // O(n) internal = NULL; } if (d != NULL) { delete d; // O(n) d = NULL; } root = NULL; return; } // ********************************************************************** int dendro::computeEdgeCount(const int a, const short int atype, const int b, const short int btype) { // This function computes the number of edges that cross between the // subtree internal[a] and the subtree internal[b]. To do this, we // use an array A[1..n] integers which take values -1 if A[i] is in // the subtree defined by internal[a], +1 if A[i] is in the subtree // internal[b], and 0 otherwise. Taking the smaller of the two sets, // we then scan over the edges attached to that set of vertices and // count the number of endpoints we see in the other set. bool flag_go = true; int nA, nB; int count = 0; const short int k = 1 + DENDRO + GRAPH; elementd* curr; // First, we push the leaf nodes in the L and R subtrees into // balanced binary tree structures so that we can search them // quickly later on. if (atype == GRAPH) { // default case, subtree A is size 1 // insert single node as member of left subtree subtreeL.insertItem(a, -1); nA = 1; // } else { // explore subtree A, O(|A|) curr = &internal[a]; curr->type = k + 1; nA = 0; while (flag_go) { if (curr->index == internal[a].M->index) { internal[a].type = DENDRO; flag_go = false; } else { // - is it time, and is left child a graph node? if (curr->type == k + 1 && curr->L->type == GRAPH) { subtreeL.insertItem(curr->L->index, -1); curr->type = k + 2; nA++; } // - is it time, and is right child a graph node? if (curr->type == k + 2 && curr->R->type == GRAPH) { subtreeL.insertItem(curr->R->index, -1); curr->type = k + 3; nA++; } if (curr->type == k + 1) { // - go left curr->type = k + 2; curr = curr->L; curr->type = k + 1; } else if (curr->type == k + 2) { // - else go right curr->type = k + 3; curr = curr->R; curr->type = k + 1; } else { // - else go up a level curr->type = DENDRO; curr = curr->M; if (curr == NULL) { flag_go = false; } } } } } if (btype == GRAPH) { // default case, subtree A is size 1 // insert node as single member of right subtree subtreeR.insertItem(b, 1); nB = 1; } else { flag_go = true; // explore subtree B, O(|B|) curr = &internal[b]; curr->type = k + 1; nB = 0; while (flag_go) { if (curr->index == internal[b].M->index) { internal[b].type = DENDRO; flag_go = false; } else { // - is it time, and is left child a graph node? if (curr->type == k + 1 && curr->L->type == GRAPH) { subtreeR.insertItem(curr->L->index, 1); curr->type = k + 2; nB++; } // - is it time, and is right child a graph node? if (curr->type == k + 2 && curr->R->type == GRAPH) { subtreeR.insertItem(curr->R->index, 1); curr->type = k + 3; nB++; } if (curr->type == k + 1) { // - look left curr->type = k + 2; curr = curr->L; curr->type = k + 1; } else if (curr->type == k + 2) { // - look right curr->type = k + 3; curr = curr->R; curr->type = k + 1; } else { // - else go up a level curr->type = DENDRO; curr = curr->M; if (curr == NULL) { flag_go = false; } } } } } // Now, we take the smaller subtree and ask how many of its // emerging edges have their partner in the other subtree. O(|A| log // |A|) time edge* current; int* treeList; if (nA < nB) { // subtreeL is smaller treeList = subtreeL.returnArrayOfKeys(); for (int i = 0; i < nA; i++) { current = g->getNeighborList(treeList[i]); // loop over each of its neighbors v_j while (current != NULL) { // to see if v_j is in A if (subtreeR.findItem(current->x) != NULL) { count++; } current = current->next; } subtreeL.deleteItem(treeList[i]); } delete [] treeList; treeList = subtreeR.returnArrayOfKeys(); for (int i = 0; i < nB; i++) { subtreeR.deleteItem(treeList[i]); } delete [] treeList; } else { // subtreeR is smaller treeList = subtreeR.returnArrayOfKeys(); for (int i = 0; i < nB; i++) { current = g->getNeighborList(treeList[i]); // loop over each of its neighbors v_j while (current != NULL) { // to see if v_j is in B if (subtreeL.findItem(current->x) != NULL) { count++; } current = current->next; } subtreeR.deleteItem(treeList[i]); } delete [] treeList; treeList = subtreeL.returnArrayOfKeys(); for (int i = 0; i < nA; i++) { subtreeL.deleteItem(treeList[i]); } delete [] treeList; } return count; } // *********************************************************************** int dendro::countChildren(const string s) { int len = s.size(); int numC = 0; for (int i = 0; i < len; i++) { if (s[i] == 'C') { numC++; } } return numC; } // *********************************************************************** void dendro::cullSplitHist() { string* array; int tot, leng; array = splithist->returnArrayOfKeys(); tot = splithist->returnTotal(); leng = splithist->returnNodecount(); for (int i = 0; i < leng; i++) { if ((splithist->returnValue(array[i]) / tot) < 0.5) { splithist->deleteItem(array[i]); } } delete [] array; array = NULL; return; } // ********************************************************************** elementd* dendro::findCommonAncestor(list** paths_, const int i, const int j) { list* headOne = paths_[i]; list* headTwo = paths_[j]; elementd* lastStep = NULL; while (headOne->x == headTwo->x) { lastStep = &internal[headOne->x]; headOne = headOne->next; headTwo = headTwo->next; if (headOne == NULL || headTwo == NULL) { break; } } return lastStep; // Returns address of an internal node; do not deallocate } // ********************************************************************** int dendro::getConsensusSize() { string *array; double value, tot; int numSplits, numCons; numSplits = splithist->returnNodecount(); array = splithist->returnArrayOfKeys(); tot = splithist->returnTotal(); numCons = 0; for (int i = 0; i < numSplits; i++) { value = splithist->returnValue(array[i]); if (value / tot > 0.5) { numCons++; } } delete [] array; array = NULL; return numCons; } // ********************************************************************** splittree* dendro::getConsensusSplits() { string *array; splittree *consensusTree; double value, tot; consensusTree = new splittree; int numSplits; // We look at all of the splits in our split histogram and add any // one that's in the majority to our consensusTree, which we then // return (note that consensusTree needs to be deallocated by the // user). numSplits = splithist->returnNodecount(); array = splithist->returnArrayOfKeys(); tot = splithist->returnTotal(); for (int i = 0; i < numSplits; i++) { value = splithist->returnValue(array[i]); if (value / tot > 0.5) { consensusTree->insertItem(array[i], value / tot); } } delete [] array; array = NULL; return consensusTree; } // *********************************************************************** double dendro::getLikelihood() { return L; } // *********************************************************************** void dendro::getSplitList(splittree* split_tree) { string sp; for (int i = 0; i < (n - 1); i++) { sp = d->getSplit(i); if (!sp.empty() && sp[1] != '-') { split_tree->insertItem(sp, 0.0); } } return; } // *********************************************************************** double dendro::getSplitTotalWeight() { if (splithist) { return splithist->returnTotal(); } else { return 0; } } // *********************************************************************** bool dendro::importDendrogramStructure(const igraph_hrg_t *hrg) { n = igraph_hrg_size(hrg); // allocate memory for G, O(n) leaf = new elementd[n]; // allocate memory for D, O(n) internal = new elementd[n - 1]; // allocate memory for internal edges of D, O(n) d = new interns(n - 2); // initialize leaf nodes for (int i = 0; i < n; i++) { leaf[i].type = GRAPH; leaf[i].label = i; leaf[i].index = i; leaf[i].n = 1; } // initialize internal nodes root = &internal[0]; root->label = 0; for (int i = 1; i < n - 1; i++) { internal[i].index = i; internal[i].label = -1; } // import basic structure from hrg object, O(n) for (int i = 0; i < n - 1; i++) { int left_index = VECTOR(hrg->left)[i]; int right_index = VECTOR(hrg->right)[i]; if (left_index < 0) { internal[i].L = &internal[-left_index - 1]; internal[-left_index - 1].M = &internal[i]; } else { internal[i].L = &leaf[left_index]; leaf[left_index].M = &internal[i]; } if (right_index < 0) { internal[i].R = &internal[-right_index - 1]; internal[-right_index - 1].M = &internal[i]; } else { internal[i].R = &leaf[right_index]; leaf[right_index].M = &internal[i]; } internal[i].p = VECTOR(hrg->prob)[i]; internal[i].e = VECTOR(hrg->edges)[i]; internal[i].n = VECTOR(hrg->vertices)[i]; internal[i].index = i; } // --- Label all internal vertices O(n log n) elementd *curr; for (int i = 0; i < n; i++) { curr = &leaf[i]; while (curr) { if (curr->label == -1 || curr->label > leaf[i].label) { curr->label = leaf[i].label; } curr = curr -> M; } } // --- Exchange children to enforce order-property O(n) elementd *tempe; for (int i = 0; i < n - 1; i++) { if (internal[i].L->label > internal[i].label) { tempe = internal[i].L; internal[i].L = internal[i].R; internal[i].R = tempe; } } // --- Tabulate internal dendrogram edges O(n) for (int i = 0; i < (n - 1); i++) { if (internal[i].L->type == DENDRO) { d->addEdge(i, internal[i].L->index, LEFT); } if (internal[i].R->type == DENDRO) { d->addEdge(i, internal[i].R->index, RIGHT); } } // --- Compute p_i for each internal node O(n) // Each internal node's p_i = e_i / (nL_i*nR_i), and now that we // have each of those pieces, we may calculate this value for each // internal node. Given these, we can then calculate the // log-likelihood of the entire dendrogram structure // \log(L) = \sum_{i=1}^{n} ( ( e_i \log[p_i] ) + // ( (nL_i*nR_i - e_i) \log[1-p_i] ) ) L = 0.0; double dL; int nL_nR, ei; for (int i = 0; i < (n - 1); i++) { nL_nR = internal[i].L->n * internal[i].R->n; ei = internal[i].e; if (ei == 0 || ei == nL_nR) { dL = 0.0; } else { dL = (double)(ei) * log(internal[i].p) + (double)(nL_nR - ei) * log(1.0 - internal[i].p); } internal[i].logL = dL; L += dL; } return true; } // *********************************************************************** void dendro::makeRandomGraph() { if (g != NULL) { delete g; } g = NULL; g = new graph(n); list *curr, *prev; if (paths) { for (int i = 0; i < n; i++) { curr = paths[i]; while (curr != NULL) { prev = curr; curr = curr->next; delete prev; prev = NULL; } paths[i] = NULL; } delete [] paths; } // build paths from root O(n d) paths = new list* [n]; for (int i = 0; i < n; i++) { paths[i] = reversePathToRoot(i); } elementd* commonAncestor; // O((h+d)*n^2) - h: height of D; d: average degree in G for (int i = 0; i < n; i++) { // decide neighbors of v_i for (int j = (i + 1); j < n; j++) { commonAncestor = findCommonAncestor(paths, i, j); if (RNG_UNIF01() < commonAncestor->p) { if (!(g->doesLinkExist(i, j))) { g->addLink(i, j); } if (!(g->doesLinkExist(j, i))) { g->addLink(j, i); } } } } for (int i = 0; i < n; i++) { curr = paths[i]; while (curr != NULL) { prev = curr; curr = curr->next; delete prev; prev = NULL; } paths[i] = NULL; } delete [] paths; // delete paths data structure O(n log n) paths = NULL; return; } // ********************************************************************** bool dendro::monteCarloMove(double& delta, bool& ftaken, const double T) { // A single MC move begins with the selection of a random internal // edge (a,b) of the dendrogram. This also determines the three // subtrees i, j, k that we will rearrange, and we choose uniformly // from among the options. // // If (a,b) is a left-edge, then we have ((i,j),k), and moves // ((i,j),k) -> ((i,k),j) (alpha move) // -> (i,(j,k)) + enforce order-property for (j,k) (beta move) // // If (a,b) is a right-edge, then we have (i,(j,k)), and moves // (i,(j,k)) -> ((i,k),j) (alpha move) // -> ((i,j),k) (beta move) // // For each of these moves, we need to know what the change in // likelihood will be, so that we can determine with what // probability we execute the move. elementd *temp; ipair *tempPair; int x, y, e_x, e_y, n_i, n_j, n_k, n_x, n_y; short int t; double p_x, p_y, L_x, L_y, dLogL; string new_split; // The remainder of the code executes a single MCMC move, where we // sample the dendrograms proportionally to their likelihoods (i.e., // temperature=1, if you're comparing it to the usual MCMC // framework). delta = 0.0; ftaken = false; tempPair = d->getRandomEdge(); // returns address; no need to deallocate x = tempPair->x; // copy contents of referenced random edge y = tempPair->y; // into local variables t = tempPair->t; if (t == LEFT) { if (RNG_UNIF01() < 0.5) { // ## LEFT ALPHA move: ((i,j),k) -> ((i,k),j) // We need to calculate the change in the likelihood (dLogL) // that would result from this move. Most of the information // needed to do this is already available, the exception being // e_ik, the number of edges that span the i and k subtrees. I // use a slow algorithm O(n) to do this, since I don't know of a // better way at this point. (After several attempts to find a // faster method, no luck.) n_i = internal[y].L->n; n_j = internal[y].R->n; n_k = internal[x].R->n; n_y = n_i * n_k; e_y = computeEdgeCount(internal[y].L->index, internal[y].L->type, internal[x].R->index, internal[x].R->type); p_y = (double)(e_y) / (double)(n_y); if (e_y == 0 || e_y == n_y) { L_y = 0.0; } else { L_y = (double)(e_y) * log(p_y) + (double)(n_y - e_y) * log(1.0 - p_y); } n_x = (n_i + n_k) * n_j; e_x = internal[x].e + internal[y].e - e_y; // e_yj p_x = (double)(e_x) / (double)(n_x); if (e_x == 0 || e_x == n_x) { L_x = 0.0; } else { L_x = (double)(e_x) * log(p_x) + (double)(n_x - e_x) * log(1.0 - p_x); } dLogL = (L_x - internal[x].logL) + (L_y - internal[y].logL); if ((dLogL > 0.0) || (RNG_UNIF01() < exp(T * dLogL))) { // make LEFT ALPHA move ftaken = true; d->swapEdges(x, internal[x].R->index, RIGHT, y, internal[y].R->index, RIGHT); temp = internal[x].R; // - swap j and k internal[x].R = internal[y].R; internal[y].R = temp; internal[x].R->M = &internal[x]; // - adjust parent pointers internal[y].R->M = &internal[y]; internal[y].n = n_i + n_k; // - update n for [y] internal[x].e = e_x; // - update e_i for [x] and [y] internal[y].e = e_y; internal[x].p = p_x; // - update p_i for [x] and [y] internal[y].p = p_y; internal[x].logL = L_x; // - update L_i for [x] and [y] internal[y].logL = L_y; // - order-property maintained L += dLogL; // - update LogL delta = dLogL; } } else { // ## LEFT BETA move: ((i,j),k) -> (i,(j,k)) n_i = internal[y].L->n; n_j = internal[y].R->n; n_k = internal[x].R->n; n_y = n_j * n_k; e_y = computeEdgeCount(internal[y].R->index, internal[y].R->type, internal[x].R->index, internal[x].R->type); p_y = (double)(e_y) / (double)(n_y); if (e_y == 0 || e_y == n_y) { L_y = 0.0; } else { L_y = (double)(e_y) * log(p_y) + (double)(n_y - e_y) * log(1.0 - p_y); } n_x = (n_j + n_k) * n_i; e_x = internal[x].e + internal[y].e - e_y; // e_yj p_x = (double)(e_x) / (double)(n_x); if (e_x == 0 || e_x == n_x) { L_x = 0.0; } else { L_x = (double)(e_x) * log(p_x) + (double)(n_x - e_x) * log(1.0 - p_x); } dLogL = (L_x - internal[x].logL) + (L_y - internal[y].logL); if ((dLogL > 0.0) || (RNG_UNIF01() < exp(T * dLogL))) { // make LEFT BETA move ftaken = true; d->swapEdges(y, internal[y].L->index, LEFT, y, internal[y].R->index, RIGHT); temp = internal[y].L; // - swap L and R of [y] internal[y].L = internal[y].R; internal[y].R = temp; d->swapEdges(x, internal[x].R->index, RIGHT, y, internal[y].R->index, RIGHT); temp = internal[x].R; // - swap i and k internal[x].R = internal[y].R; internal[y].R = temp; internal[x].R->M = &internal[x]; // - adjust parent pointers internal[y].R->M = &internal[y]; d->swapEdges(x, internal[x].L->index, LEFT, x, internal[x].R->index, RIGHT); temp = internal[x].L; // - swap L and R of [x] internal[x].L = internal[x].R; internal[x].R = temp; internal[y].n = n_j + n_k; // - update n internal[x].e = e_x; // - update e_i internal[y].e = e_y; internal[x].p = p_x; // - update p_i internal[y].p = p_y; internal[x].logL = L_x; // - update logL_i internal[y].logL = L_y; if (internal[y].R->label < internal[y].L->label) { // - enforce order-property if necessary d->swapEdges(y, internal[y].L->index, LEFT, y, internal[y].R->index, RIGHT); temp = internal[y].L; internal[y].L = internal[y].R; internal[y].R = temp; } // internal[y].label = internal[y].L->label; L += dLogL; // - update LogL delta = dLogL; } } } else { // right-edge: t == RIGHT if (RNG_UNIF01() < 0.5) { // alpha move: (i,(j,k)) -> ((i,k),j) n_i = internal[x].L->n; n_j = internal[y].L->n; n_k = internal[y].R->n; n_y = n_i * n_k; e_y = computeEdgeCount(internal[x].L->index, internal[x].L->type, internal[y].R->index, internal[y].R->type); p_y = (double)(e_y) / (double)(n_y); if (e_y == 0 || e_y == n_y) { L_y = 0.0; } else { L_y = (double)(e_y) * log(p_y) + (double)(n_y - e_y) * log(1.0 - p_y); } n_x = (n_i + n_k) * n_j; e_x = internal[x].e + internal[y].e - e_y; // e_yj p_x = (double)(e_x) / (double)(n_x); if (e_x == 0 || e_x == n_x) { L_x = 0.0; } else { L_x = (double)(e_x) * log(p_x) + (double)(n_x - e_x) * log(1.0 - p_x); } dLogL = (L_x - internal[x].logL) + (L_y - internal[y].logL); if ((dLogL > 0.0) || (RNG_UNIF01() < exp(T * dLogL))) { // make RIGHT ALPHA move ftaken = true; d->swapEdges(x, internal[x].L->index, LEFT, x, internal[x].R->index, RIGHT); temp = internal[x].L; // - swap L and R of [x] internal[x].L = internal[x].R; internal[x].R = temp; d->swapEdges(y, internal[y].L->index, LEFT, x, internal[x].R->index, RIGHT); temp = internal[y].L; // - swap i and j internal[y].L = internal[x].R; internal[x].R = temp; internal[x].R->M = &internal[x]; // - adjust parent pointers internal[y].L->M = &internal[y]; internal[y].n = n_i + n_k; // - update n internal[x].e = e_x; // - update e_i internal[y].e = e_y; internal[x].p = p_x; // - update p_i internal[y].p = p_y; internal[x].logL = L_x; // - update logL_i internal[y].logL = L_y; internal[y].label = internal[x].label; // - update order property L += dLogL; // - update LogL delta = dLogL; } } else { // beta move: (i,(j,k)) -> ((i,j),k) n_i = internal[x].L->n; n_j = internal[y].L->n; n_k = internal[y].R->n; n_y = n_i * n_j; e_y = computeEdgeCount(internal[x].L->index, internal[x].L->type, internal[y].L->index, internal[y].L->type); p_y = (double)(e_y) / (double)(n_y); if (e_y == 0 || e_y == n_y) { L_y = 0.0; } else { L_y = (double)(e_y) * log(p_y) + (double)(n_y - e_y) * log(1.0 - p_y); } n_x = (n_i + n_j) * n_k; e_x = internal[x].e + internal[y].e - e_y; // e_yk p_x = (double)(e_x) / (double)(n_x); if (e_x == 0 || e_x == n_x) { L_x = 0.0; } else { L_x = (double)(e_x) * log(p_x) + (double)(n_x - e_x) * log(1.0 - p_x); } dLogL = (L_x - internal[x].logL) + (L_y - internal[y].logL); if ((dLogL > 0.0) || (RNG_UNIF01() < exp(T * dLogL))) { // make RIGHT BETA move ftaken = true; d->swapEdges(x, internal[x].L->index, LEFT, x, internal[x].R->index, RIGHT); temp = internal[x].L; // - swap L and R of [x] internal[x].L = internal[x].R; internal[x].R = temp; d->swapEdges(x, internal[x].R->index, RIGHT, y, internal[y].R->index, RIGHT); temp = internal[x].R; // - swap i and k internal[x].R = internal[y].R; internal[y].R = temp; internal[x].R->M = &internal[x]; // - adjust parent pointers internal[y].R->M = &internal[y]; d->swapEdges(y, internal[y].L->index, LEFT, y, internal[y].R->index, RIGHT); temp = internal[y].L; // - swap L and R of [y] internal[y].L = internal[y].R; internal[y].R = temp; internal[y].n = n_i + n_j; // - update n internal[x].e = e_x; // - update e_i internal[y].e = e_y; internal[x].p = p_x; // - update p_i internal[y].p = p_y; internal[x].logL = L_x; // - update logL_i internal[y].logL = L_y; internal[y].label = internal[x].label; // - order-property L += dLogL; // - update LogL delta = dLogL; } } } return true; } // ********************************************************************** void dendro::refreshLikelihood() { // recalculates the log-likelihood of the dendrogram structure L = 0.0; double dL; int nL_nR, ei; for (int i = 0; i < (n - 1); i++) { nL_nR = internal[i].L->n * internal[i].R->n; ei = internal[i].e; internal[i].p = (double)(ei) / (double)(nL_nR); if (ei == 0 || ei == nL_nR) { dL = 0.0; } else { dL = ei * log(internal[i].p) + (nL_nR - ei) * log(1.0 - internal[i].p); } internal[i].logL = dL; L += dL; } return; } // ********************************************************************** void dendro::QsortMain (block* array, int left, int right) { if (right > left) { int pivot = left; int part = QsortPartition(array, left, right, pivot); QsortMain(array, left, part - 1); QsortMain(array, part + 1, right ); } return; } int dendro::QsortPartition (block* array, int left, int right, int index) { block p_value, temp; p_value.x = array[index].x; p_value.y = array[index].y; // swap(array[p_value], array[right]) temp.x = array[right].x; temp.y = array[right].y; array[right].x = array[index].x; array[right].y = array[index].y; array[index].x = temp.x; array[index].y = temp.y; int stored = left; for (int i = left; i < right; i++) { if (array[i].x <= p_value.x) { // swap(array[stored], array[i]) temp.x = array[i].x; temp.y = array[i].y; array[i].x = array[stored].x; array[i].y = array[stored].y; array[stored].x = temp.x; array[stored].y = temp.y; stored++; } } // swap(array[right], array[stored]) temp.x = array[stored].x; temp.y = array[stored].y; array[stored].x = array[right].x; array[stored].y = array[right].y; array[right].x = temp.x; array[right].y = temp.y; return stored; } void dendro::recordConsensusTree(igraph_vector_t *parents, igraph_vector_t *weights) { keyValuePairSplit *curr, *prev; child *newChild; int orig_nodes = g->numNodes(); // First, cull the split hist so that only splits with weight >= 0.5 // remain cullSplitHist(); int treesize = splithist->returnNodecount(); // Now, initialize the various arrays we use to keep track of the // internal structure of the consensus tree. ctree = new cnode[treesize]; cancestor = new int[n]; for (int i = 0; i < treesize; i++) { ctree[i].index = i; } for (int i = 0; i < n; i++) { cancestor[i] = -1; } int ii = 0; // To build the majority consensus tree, we do the following: For // each possible number of Ms in the split string (a number that // ranges from n-2 down to 0), and for each split with that number // of Ms, we create a new internal node of the tree, and connect the // oldest ancestor of each C to that node (at most once). Then, we // update our list of oldest ancestors to reflect this new join, and // proceed. for (int i = n - 2; i >= 0; i--) { // First, we get a list of all the splits with this exactly i Ms curr = splithist->returnTheseSplits(i); // Now we loop over that list while (curr != NULL) { splithist->deleteItem(curr->x); // add weight to this internal node ctree[ii].weight = curr->y; // examine each letter of this split for (int j = 0; j < n; j++) { if (curr->x[j] == 'C') { // - node is child of this internal node if (cancestor[j] == -1) { // - first time this leaf has ever been seen newChild = new child; newChild->type = GRAPH; newChild->index = j; newChild->next = NULL; // - attach child to list if (ctree[ii].lastChild == NULL) { ctree[ii].children = newChild; ctree[ii].lastChild = newChild; ctree[ii].degree = 1; } else { ctree[ii].lastChild->next = newChild; ctree[ii].lastChild = newChild; ctree[ii].degree += 1; } } else { // - this leaf has been seen before // If the parent of the ancestor of this leaf is the // current internal node then this leaf is already a // descendant of this internal node, and we can move on; // otherwise, we need to add that ancestor to this // internal node's child list, and update various // relations if (ctree[cancestor[j]].parent != ii) { ctree[cancestor[j]].parent = ii; newChild = new child; newChild->type = DENDRO; newChild->index = cancestor[j]; newChild->next = NULL; // - attach child to list if (ctree[ii].lastChild == NULL) { ctree[ii].children = newChild; ctree[ii].lastChild = newChild; ctree[ii].degree = 1; } else { ctree[ii].lastChild->next = newChild; ctree[ii].lastChild = newChild; ctree[ii].degree += 1; } } } // note new ancestry for this leaf cancestor[j] = ii; } } // update internal node index ii++; prev = curr; curr = curr->next; delete prev; } } // Return the consensus tree igraph_vector_resize(parents, ii + orig_nodes); if (weights) { igraph_vector_resize(weights, ii); } for (int i = 0; i < ii; i++) { child *sat, *sit = ctree[i].children; while (sit) { VECTOR(*parents)[orig_nodes + i] = ctree[i].parent < 0 ? -1 : orig_nodes + ctree[i].parent; if (sit->type == GRAPH) { VECTOR(*parents)[sit->index] = orig_nodes + i; } sat = sit; sit = sit->next; delete sat; } if (weights) { VECTOR(*weights)[i] = ctree[i].weight; } ctree[i].children = 0; } // Plus the isolate nodes for (int i = 0; i < n; i++) { if (cancestor[i] == -1) { VECTOR(*parents)[i] = -1; } } } // ********************************************************************** void dendro::recordDendrogramStructure(igraph_hrg_t *hrg) { for (int i = 0; i < n - 1; i++) { int li = internal[i].L->index; int ri = internal[i].R->index; VECTOR(hrg->left )[i] = internal[i].L->type == DENDRO ? -li - 1 : li; VECTOR(hrg->right)[i] = internal[i].R->type == DENDRO ? -ri - 1 : ri; VECTOR(hrg->prob )[i] = internal[i].p; VECTOR(hrg->edges)[i] = internal[i].e; VECTOR(hrg->vertices)[i] = internal[i].n; } } void dendro::recordGraphStructure(igraph_t *graph) { igraph_vector_t edges; int no_of_nodes = g->numNodes(); int no_of_edges = g->numLinks() / 2; int idx = 0; igraph_vector_init(&edges, no_of_edges * 2); IGRAPH_FINALLY(igraph_vector_destroy, &edges); for (int i = 0; i < n; i++) { edge *curr = g->getNeighborList(i); while (curr) { if (i < curr->x) { VECTOR(edges)[idx++] = i; VECTOR(edges)[idx++] = curr->x; } curr = curr->next; } } igraph_create(graph, &edges, no_of_nodes, /* directed= */ 0); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); } // ********************************************************************** list* dendro::reversePathToRoot(const int leafIndex) { list *head, *subhead, *newlist; head = subhead = newlist = NULL; elementd *current = &leaf[leafIndex]; // continue until we're finished while (current != NULL) { // add this node to the path newlist = new list; newlist->x = current->index; newlist->next = NULL; if (head == NULL) { head = newlist; } else { subhead = head; head = newlist; head->next = subhead; } current = current->M; } return head; } // *********************************************************************** bool dendro::sampleSplitLikelihoods(int &sample_num) { // In order to compute the majority agreement dendrogram at // equilibrium, we need to calculate the leaf partition defined by // each split (internal edge) of the tree. Because splits are only // defined on a Cayley tree, the buildSplit() function returns the // default "--...--" string for the root and the root's left // child. When tabulating the frequency of splits, one of these // needs to be excluded. IGRAPH_UNUSED(sample_num); string* array; int k; double tot; string new_split; // To decompose the tree into its splits, we simply loop over all // the internal nodes and replace the old split for the ith internal // node with its new split. This is a bit time consuming to do // O(n^2), so try not to do this very often. Once the decomposition // is had, we insert them into the split histogram, which tracks the // cumulative weight for each respective split observed. if (splithist == NULL) { splithist = new splittree; } for (int i = 0; i < (n - 1); i++) { new_split = buildSplit(&internal[i]); d->replaceSplit(i, new_split); if (!new_split.empty() && new_split[1] != '-') { if (!splithist->insertItem(new_split, 1.0)) { return false; } } } splithist->finishedThisRound(); // For large graphs, the split histogram can get extremely large, so // we need to employ some measures to prevent it from swamping the // available memory. When the number of splits exceeds a threshold // (say, a million), we progressively delete splits that have a // weight less than a rising (k*0.001 of the total weight) fraction // of the splits, on the assumption that losing such weight is // unlikely to effect the ultimate split statistics. This deletion // procedure is slow O(m lg m), but should only happen very rarely. int split_max = n * 500; int leng; if (splithist->returnNodecount() > split_max) { k = 1; while (splithist->returnNodecount() > split_max) { array = splithist->returnArrayOfKeys(); tot = splithist->returnTotal(); leng = splithist->returnNodecount(); for (int i = 0; i < leng; i++) { if ((splithist->returnValue(array[i]) / tot) < k * 0.001) { splithist->deleteItem(array[i]); } } delete [] array; array = NULL; k++; } } return true; } void dendro::sampleAdjacencyLikelihoods() { // Here, we sample the probability values associated with every // adjacency in A, weighted by their likelihood. The weighted // histogram is stored in the graph data structure, so we simply // need to add an observation to each node-pair that corresponds to // the associated branch point's probability and the dendrogram's // overall likelihood. double nn; double norm = ((double)(n) * (double)(n)) / 4.0; if (L > 0.0) { L = 0.0; } elementd* ancestor; list *currL, *prevL; if (paths != NULL) { for (int i = 0; i < n; i++) { currL = paths[i]; while (currL != NULL) { prevL = currL; currL = currL->next; delete prevL; prevL = NULL; } paths[i] = NULL; } delete [] paths; } paths = NULL; paths = new list* [n]; for (int i = 0; i < n; i++) { // construct paths from root, O(n^2) at worst paths[i] = reversePathToRoot(i); } // add obs for every node-pair, always O(n^2) for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { // find internal node, O(n) at worst ancestor = findCommonAncestor(paths, i, j); nn = ((double)(ancestor->L->n) * (double)(ancestor->R->n)) / norm; // add obs of ->p to (i,j) histogram, and g->addAdjacencyObs(i, j, ancestor->p, nn); // add obs of ->p to (j,i) histogram g->addAdjacencyObs(j, i, ancestor->p, nn); } } // finish-up: upate total weight in histograms g->addAdjacencyEnd(); return; } void dendro::resetDendrograph() { // Reset the dendrograph structure for the next trial if (leaf != NULL) { delete [] leaf; // O(n) leaf = NULL; } if (internal != NULL) { delete [] internal; // O(n) internal = NULL; } if (d != NULL) { delete d; // O(n) d = NULL; } root = NULL; if (paths != NULL) { list *curr, *prev; for (int i = 0; i < n; i++) { curr = paths[i]; while (curr != NULL) { prev = curr; curr = curr->next; delete prev; prev = NULL; } paths[i] = NULL; } delete [] paths; } paths = NULL; L = 1.0; return; } // ********************************************************************** // *** COPYRIGHT NOTICE ************************************************* // graph.h - graph data structure for hierarchical random graphs // Copyright (C) 2005-2008 Aaron Clauset // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.gnu.org/licenses/gpl.txt for more details. // // ********************************************************************** // Author : Aaron Clauset ( aaronc@santafe.edu | // http://www.santafe.edu/~aaronc/ ) // Collaborators: Cristopher Moore and Mark E.J. Newman // Project : Hierarchical Random Graphs // Location : University of New Mexico, Dept. of Computer Science // AND Santa Fe Institute // Created : 8 November 2005 // Modified : 23 December 2007 (cleaned up for public consumption) // // *********************************************************************** // // Graph data structure for hierarchical random graphs. The basic // structure is an adjacency list of edges; however, many additional // pieces of metadata are stored as well. Each node stores its // external name, its degree and (if assigned) its group index. // // *********************************************************************** // ******** Constructor / Destructor ************************************* graph::graph(const int size, bool predict) : predict(predict) { n = size; m = 0; nodes = new vert [n]; nodeLink = new edge* [n]; nodeLinkTail = new edge* [n]; for (int i = 0; i < n; i++) { nodeLink[i] = NULL; nodeLinkTail[i] = NULL; } if (predict) { A = new double** [n]; for (int i = 0; i < n; i++) { A[i] = new double* [n]; } obs_count = 0; total_weight = 0.0; bin_resolution = 0.0; num_bins = 0; } } graph::~graph() { edge *curr, *prev; for (int i = 0; i < n; i++) { curr = nodeLink[i]; while (curr != NULL) { prev = curr; curr = curr->next; delete prev; } } delete [] nodeLink; nodeLink = NULL; delete [] nodeLinkTail; nodeLinkTail = NULL; delete [] nodes; nodes = NULL; if (predict) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { delete [] A[i][j]; } delete [] A[i]; } delete [] A; A = NULL; } } // ********************************************************************** bool graph::addLink(const int i, const int j) { // Adds the directed edge (i,j) to the adjacency list for v_i edge* newedge; if (i >= 0 && i < n && j >= 0 && j < n) { newedge = new edge; newedge->x = j; if (nodeLink[i] == NULL) { // first neighbor nodeLink[i] = newedge; nodeLinkTail[i] = newedge; nodes[i].degree = 1; } else { // subsequent neighbor nodeLinkTail[i]->next = newedge; nodeLinkTail[i] = newedge; nodes[i].degree++; } // increment edge count m++; return true; } else { return false; } } // *********************************************************************** bool graph::addAdjacencyObs(const int i, const int j, const double probability, const double size) { // Adds the observation obs to the histogram of the edge (i,j) // Note: user must manually add observation to edge (j,i) by calling // this function with that argument if (bin_resolution > 0.0 && probability >= 0.0 && probability <= 1.0 && size >= 0.0 && size <= 1.0 && i >= 0 && i < n && j >= 0 && j < n) { int index = (int)(probability / bin_resolution + 0.5); if (index < 0) { index = 0; } else if (index > num_bins) { index = num_bins; } // Add the weight to the proper probability bin if (A[i][j][index] < 0.5) { A[i][j][index] = 1.0; } else { A[i][j][index] += 1.0; } return true; } return false; } // ********************************************************************** void graph::addAdjacencyEnd() { // We need to also keep a running total of how much weight has been added // to the histogram, and the number of observations in the histogram. if (obs_count == 0) { total_weight = 1.0; obs_count = 1; } else { total_weight += 1.0; obs_count++; } return; } bool graph::doesLinkExist(const int i, const int j) { // This function determines if the edge (i,j) already exists in the // adjacency list of v_i edge* curr; if (i >= 0 && i < n && j >= 0 && j < n) { curr = nodeLink[i]; while (curr != NULL) { if (curr->x == j) { return true; } curr = curr->next; } } return false; } // ********************************************************************** int graph::getDegree(const int i) { if (i >= 0 && i < n) { return nodes[i].degree; } else { return -1; } } string graph::getName(const int i) { if (i >= 0 && i < n) { return nodes[i].name; } else { return ""; } } // NOTE: Returns address; deallocation of returned object is dangerous edge* graph::getNeighborList(const int i) { if (i >= 0 && i < n) { return nodeLink[i]; } else { return NULL; } } double* graph::getAdjacencyHist(const int i, const int j) { if (i >= 0 && i < n && j >= 0 && j < n) { return A[i][j]; } else { return NULL; } } // ********************************************************************** double graph::getAdjacencyAverage(const int i, const int j) { double average = 0.0; if (i != j) { for (int k = 0; k < num_bins; k++) { if (A[i][j][k] > 0.0) { average += (A[i][j][k] / total_weight) * ((double)(k) * bin_resolution); } } } return average; } int graph::numLinks() { return m; } int graph::numNodes() { return n; } double graph::getBinResolution() { return bin_resolution; } int graph::getNumBins() { return num_bins; } double graph::getTotalWeight() { return total_weight; } // *********************************************************************** void graph::resetAllAdjacencies() { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < num_bins; k++) { A[i][j][k] = 0.0; } } } obs_count = 0; total_weight = 0.0; return; } // ********************************************************************** void graph::resetAdjacencyHistogram(const int i, const int j) { if (i >= 0 && i < n && j >= 0 && j < n) { for (int k = 0; k < num_bins; k++) { A[i][j][k] = 0.0; } } return; } // ********************************************************************** void graph::resetLinks() { edge *curr, *prev; for (int i = 0; i < n; i++) { curr = nodeLink[i]; while (curr != NULL) { prev = curr; curr = curr->next; delete prev; } nodeLink[i] = NULL; nodeLinkTail[i] = NULL; nodes[i].degree = 0; } m = 0; return; } // ********************************************************************** void graph::setAdjacencyHistograms(const int bin_count) { // For all possible adjacencies, setup an edge histograms num_bins = bin_count + 1; bin_resolution = 1.0 / (double)(bin_count); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { A[i][j] = new double [num_bins]; for (int k = 0; k < num_bins; k++) { A[i][j][k] = 0.0; } } } return; } bool graph::setName(const int i, const string text) { if (i >= 0 && i < n) { nodes[i].name = text; return true; } else { return false; } } // ********************************************************************** interns::interns(const int n) { q = n; count = 0; edgelist = new ipair [q]; splitlist = new string [q + 1]; indexLUT = new int* [q + 1]; for (int i = 0; i < (q + 1); i++) { indexLUT[i] = new int [2]; indexLUT[i][0] = indexLUT[i][1] = -1; } } interns::~interns() { delete [] edgelist; delete [] splitlist; for (int i = 0; i < (q + 1); i++) { delete [] indexLUT[i]; } delete [] indexLUT; } // *********************************************************************** // NOTE: Returns an address to another object -- do not deallocate ipair* interns::getEdge(const int i) { return &edgelist[i]; } // *********************************************************************** // NOTE: Returns an address to another object -- do not deallocate ipair* interns::getRandomEdge() { return &edgelist[(int)(floor((double)(q) * RNG_UNIF01()))]; } // *********************************************************************** string interns::getSplit(const int i) { if (i >= 0 && i <= q) { return splitlist[i]; } else { return ""; } } // ********************************************************************** bool interns::addEdge(const int new_x, const int new_y, const short int new_type) { // This function adds a new edge (i,j,t,sp) to the list of internal // edges. After checking that the inputs fall in the appropriate // range of values, it records the new edgelist index in the // indexLUT and then puts the input values into that edgelist // location. if (count < q && new_x >= 0 && new_x < (q + 1) && new_y >= 0 && new_y < (q + 2) && (new_type == LEFT || new_type == RIGHT)) { if (new_type == LEFT) { indexLUT[new_x][0] = count; } else { indexLUT[new_x][1] = count; } edgelist[count].x = new_x; edgelist[count].y = new_y; edgelist[count].t = new_type; count++; return true; } else { return false; } } // ********************************************************************** bool interns::replaceSplit(const int i, const string sp) { // When an internal edge is changed, its split must be replaced as // well. This function provides that access; it stores the split // defined by an internal edge (x,y) at the location [y], which // is unique. if (i >= 0 && i <= q) { splitlist[i] = sp; return true; } return false; } // *********************************************************************** bool interns::swapEdges(const int one_x, const int one_y, const short int one_type, const int two_x, const int two_y, const short int two_type) { // The moves on the dendrogram always swap edges, either of which // (or both, or neither) can by internal edges. So, this function // mirrors that operation for the internal edgelist and indexLUT. int index, jndex, temp; bool one_isInternal = false; bool two_isInternal = false; if (one_x >= 0 && one_x < (q + 1) && two_x >= 0 && two_x < (q + 1) && (two_type == LEFT || two_type == RIGHT) && one_y >= 0 && one_y < (q + 2) && two_y >= 0 && two_y < (q + 2) && (one_type == LEFT || one_type == RIGHT)) { if (one_type == LEFT) { temp = 0; } else { temp = 1; } if (indexLUT[one_x][temp] > -1) { one_isInternal = true; } if (two_type == LEFT) { temp = 0; } else { temp = 1; } if (indexLUT[two_x][temp] > -1) { two_isInternal = true; } if (one_isInternal && two_isInternal) { if (one_type == LEFT) { index = indexLUT[one_x][0]; } else { index = indexLUT[one_x][1]; } if (two_type == LEFT) { jndex = indexLUT[two_x][0]; } else { jndex = indexLUT[two_x][1]; } temp = edgelist[index].y; edgelist[index].y = edgelist[jndex].y; edgelist[jndex].y = temp; } else if (one_isInternal) { if (one_type == LEFT) { index = indexLUT[one_x][0]; indexLUT[one_x][0] = -1; } else { index = indexLUT[one_x][1]; indexLUT[one_x][1] = -1; } edgelist[index].x = two_x; edgelist[index].t = two_type; if (two_type == LEFT) { indexLUT[two_x][0] = index; } else { indexLUT[two_x][1] = index; } // add new } else if (two_isInternal) { if (two_type == LEFT) { index = indexLUT[two_x][0]; indexLUT[two_x][0] = -1; } else { index = indexLUT[two_x][1]; indexLUT[two_x][1] = -1; } edgelist[index].x = one_x; edgelist[index].t = one_type; if (one_type == LEFT) { indexLUT[one_x][0] = index; } else { indexLUT[one_x][1] = index; } // add new } else { ; } // else neither is internal return true; } else { return false; } } // ******** Red-Black Tree Methods *************************************** splittree::splittree() { root = new elementsp; leaf = new elementsp; leaf->parent = root; root->left = leaf; root->right = leaf; support = 0; total_weight = 0.0; total_count = 0; } splittree::~splittree() { if (root != NULL && (root->left != leaf || root->right != leaf)) { deleteSubTree(root); root = NULL; } support = 0; total_weight = 0.0; total_count = 0; if (root) { delete root; } delete leaf; root = NULL; leaf = NULL; } void splittree::deleteTree() { if (root != NULL) { deleteSubTree(root); root = NULL; } return; } void splittree::deleteSubTree(elementsp *z) { if (z->left != leaf) { deleteSubTree(z->left); z->left = NULL; } if (z->right != leaf) { deleteSubTree(z->right); z->right = NULL; } delete z; /* No point in setting z to NULL here because z is passed by value */ /* z = NULL; */ return; } // ******** Reset Functions ********************************************* // O(n lg n) void splittree::clearTree() { string *array = returnArrayOfKeys(); for (int i = 0; i < support; i++) { deleteItem(array[i]); } delete [] array; return; } // ******** Search Functions ********************************************* // public search function - if there exists a elementsp in the tree // with key=searchKey, it returns TRUE and foundNode is set to point // to the found node; otherwise, it sets foundNode=NULL and returns // FALSE elementsp* splittree::findItem(const string searchKey) { elementsp *current = root; if (current->split.empty()) { return NULL; // empty tree; bail out } while (current != leaf) { if (searchKey.compare(current->split) < 0) { // left-or-right? // try moving down-left if (current->left != leaf) { current = current->left; } else { // failure; bail out return NULL; } } else { if (searchKey.compare(current->split) > 0) { // left-or-right? if (current->right != leaf) { // try moving down-left current = current->right; } else { // failure; bail out return NULL; } } else { // found (searchKey==current->split) return current; } } } return NULL; } double splittree::returnValue(const string searchKey) { elementsp* test = findItem(searchKey); if (test == NULL) { return 0.0; } else { return test->weight; } } // ******** Return Item Functions *************************************** // public function which returns the tree, via pre-order traversal, as // a linked list string* splittree::returnArrayOfKeys() { string* array; array = new string [support]; bool flag_go = true; int index = 0; elementsp *curr; if (support == 1) { array[0] = root->split; } else if (support == 2) { array[0] = root->split; if (root->left == leaf) { array[1] = root->right->split; } else { array[1] = root->left->split; } } else { for (int i = 0; i < support; i++) { array[i] = -1; } // non-recursive traversal of tree structure curr = root; curr->mark = 1; while (flag_go) { // - is it time, and is left child the leaf node? if (curr->mark == 1 && curr->left == leaf) { curr->mark = 2; } // - is it time, and is right child the leaf node? if (curr->mark == 2 && curr->right == leaf) { curr->mark = 3; } if (curr->mark == 1) { // - go left curr->mark = 2; curr = curr->left; curr->mark = 1; } else if (curr->mark == 2) { // - else go right curr->mark = 3; curr = curr->right; curr->mark = 1; } else { // - else go up a level curr->mark = 0; array[index++] = curr->split; curr = curr->parent; if (curr == NULL) { flag_go = false; } } } } return array; } slist* splittree::returnListOfKeys() { keyValuePairSplit *curr, *prev; slist *head = NULL, *tail = NULL, *newlist; curr = returnTreeAsList(); while (curr != NULL) { newlist = new slist; newlist->x = curr->x; if (head == NULL) { head = newlist; tail = head; } else { tail->next = newlist; tail = newlist; } prev = curr; curr = curr->next; delete prev; prev = NULL; } return head; } // pre-order traversal keyValuePairSplit* splittree::returnTreeAsList() { keyValuePairSplit *head, *tail; head = new keyValuePairSplit; head->x = root->split; head->y = root->weight; head->c = root->count; tail = head; if (root->left != leaf) { tail = returnSubtreeAsList(root->left, tail); } if (root->right != leaf) { tail = returnSubtreeAsList(root->right, tail); } if (head->x.empty()) { return NULL; /* empty tree */ } else { return head; } } keyValuePairSplit* splittree::returnSubtreeAsList(elementsp *z, keyValuePairSplit *head) { keyValuePairSplit *newnode, *tail; newnode = new keyValuePairSplit; newnode->x = z->split; newnode->y = z->weight; newnode->c = z->count; head->next = newnode; tail = newnode; if (z->left != leaf) { tail = returnSubtreeAsList(z->left, tail); } if (z->right != leaf) { tail = returnSubtreeAsList(z->right, tail); } return tail; } keyValuePairSplit splittree::returnMaxKey() { keyValuePairSplit themax; elementsp *current; current = root; // search to bottom-right corner of tree while (current->right != leaf) { current = current->right; } themax.x = current->split; themax.y = current->weight; return themax; } keyValuePairSplit splittree::returnMinKey() { keyValuePairSplit themin; elementsp *current; current = root; // search to bottom-left corner of tree while (current->left != leaf) { current = current->left; } themin.x = current->split; themin.y = current->weight; return themin; } // private functions for deleteItem() (although these could easily be // made public, I suppose) elementsp* splittree::returnMinKey(elementsp *z) { elementsp *current; current = z; // search to bottom-right corner of tree while (current->left != leaf) { current = current->left; } // return pointer to the minimum return current; } elementsp* splittree::returnSuccessor(elementsp *z) { elementsp *current, *w; w = z; // if right-subtree exists, return min of it if (w->right != leaf) { return returnMinKey(w->right); } // else search up in tree // move up in tree until find a non-right-child current = w->parent; while ((current != NULL) && (w == current->right)) { w = current; current = current->parent; } return current; } int splittree::returnNodecount() { return support; } keyValuePairSplit* splittree::returnTheseSplits(const int target) { keyValuePairSplit *head, *curr, *prev, *newhead, *newtail, *newpair; int count, len; head = returnTreeAsList(); prev = newhead = newtail = newpair = NULL; curr = head; while (curr != NULL) { count = 0; len = curr->x.size(); for (int i = 0; i < len; i++) { if (curr->x[i] == 'M') { count++; } } if (count == target && curr->x[1] != '*') { newpair = new keyValuePairSplit; newpair->x = curr->x; newpair->y = curr->y; newpair->next = NULL; if (newhead == NULL) { newhead = newpair; newtail = newpair; } else { newtail->next = newpair; newtail = newpair; } } prev = curr; curr = curr->next; delete prev; prev = NULL; } return newhead; } double splittree::returnTotal() { return total_weight; } // ******** Insert Functions ********************************************* void splittree::finishedThisRound() { // We need to also keep a running total of how much weight has been // added to the histogram. if (total_count == 0) { total_weight = 1.0; total_count = 1; } else { total_weight += 1.0; total_count++; } return; } // public insert function bool splittree::insertItem(string newKey, double newValue) { // first we check to see if newKey is already present in the tree; // if so, we do nothing; if not, we must find where to insert the // key elementsp *newNode, *current; // find newKey in tree; return pointer to it O(log k) current = findItem(newKey); if (current != NULL) { current->weight += 1.0; // And finally, we keep track of how many observations went into // the histogram current->count++; return true; } else { newNode = new elementsp; // elementsp for the splittree newNode->split = newKey; // store newKey newNode->weight = newValue; // store newValue newNode->color = true; // new nodes are always RED newNode->parent = NULL; // new node initially has no parent newNode->left = leaf; // left leaf newNode->right = leaf; // right leaf newNode->count = 1; support++; // increment node count in splittree // must now search for where to insert newNode, i.e., find the // correct parent and set the parent and child to point to each // other properly current = root; if (current->split.empty()) { // insert as root delete root; // delete old root root = newNode; // set root to newNode leaf->parent = newNode; // set leaf's parent current = leaf; // skip next loop } // search for insertion point while (current != leaf) { // left-or-right? if (newKey.compare(current->split) < 0) { // try moving down-left if (current->left != leaf) { current = current->left; } else { // else found new parent newNode->parent = current; // set parent current->left = newNode; // set child current = leaf; // exit search } } else { // if (current->right != leaf) { // try moving down-right current = current->right; } else { // else found new parent newNode->parent = current; // set parent current->right = newNode; // set child current = leaf; // exit search } } } // now do the house-keeping necessary to preserve the red-black // properties insertCleanup(newNode); } return true; } // private house-keeping function for insertion void splittree::insertCleanup(elementsp *z) { // fix now if z is root if (z->parent == NULL) { z->color = false; return; } elementsp *temp; // while z is not root and z's parent is RED while (z->parent != NULL && z->parent->color) { if (z->parent == z->parent->parent->left) { // z's parent is LEFT-CHILD temp = z->parent->parent->right; // grab z's uncle if (temp->color) { z->parent->color = false; // color z's parent BLACK (Case 1) temp->color = false; // color z's uncle BLACK (Case 1) z->parent->parent->color = true; // color z's grandpa RED (Case 1) z = z->parent->parent; // set z = z's grandpa (Case 1) } else { if (z == z->parent->right) { // z is RIGHT-CHILD z = z->parent; // set z = z's parent (Case 2) rotateLeft(z); // perform left-rotation (Case 2) } z->parent->color = false; // color z's parent BLACK (Case 3) z->parent->parent->color = true; // color z's grandpa RED (Case 3) rotateRight(z->parent->parent); // perform right-rotation (Case 3) } } else { // z's parent is RIGHT-CHILD temp = z->parent->parent->left; // grab z's uncle if (temp->color) { z->parent->color = false; // color z's parent BLACK (Case 1) temp->color = false; // color z's uncle BLACK (Case 1) z->parent->parent->color = true; // color z's grandpa RED (Case 1) z = z->parent->parent; // set z = z's grandpa (Case 1) } else { if (z == z->parent->left) { // z is LEFT-CHILD z = z->parent; // set z = z's parent (Case 2) rotateRight(z); // perform right-rotation (Case 2) } z->parent->color = false; // color z's parent BLACK (Case 3) z->parent->parent->color = true; // color z's grandpa RED (Case 3) rotateLeft(z->parent->parent); // perform left-rotation (Case 3) } } } root->color = false; // color the root BLACK return; } // ******** Delete Functions ******************************************** // public delete function void splittree::deleteItem(string killKey) { elementsp *x, *y, *z; z = findItem(killKey); if (z == NULL) { return; // item not present; bail out } if (support == 1) { // -- attempt to delete the root root->split = ""; // restore root node to default state root->weight = 0.0; // root->color = false; // root->parent = NULL; // root->left = leaf; // root->right = leaf; // support--; // set support to zero total_weight = 0.0; // set total weight to zero total_count--; // return; // exit - no more work to do } if (z != NULL) { support--; // decrement node count if ((z->left == leaf) || (z->right == leaf)) { // case of less than two children y = z; // set y to be z } else { y = returnSuccessor(z); // set y to be z's key-successor } if (y->left != leaf) { x = y->left; // pick y's one child (left-child) } else { x = y->right; // (right-child) } x->parent = y->parent; // make y's child's parent be y's parent if (y->parent == NULL) { root = x; // if y is the root, x is now root } else { if (y == y->parent->left) {// decide y's relationship with y's parent y->parent->left = x; // replace x as y's parent's left child } else { y->parent->right = x; } // replace x as y's parent's left child } if (y != z) { // insert y into z's spot z->split = y->split; // copy y data into z z->weight = y->weight; // z->count = y->count; // } // // do house-keeping to maintain balance if (y->color == false) { deleteCleanup(x); } delete y; // deallocate y y = NULL; // point y to NULL for safety } // return; } void splittree::deleteCleanup(elementsp *x) { elementsp *w, *t; // until x is the root, or x is RED while ((x != root) && (x->color == false)) { if (x == x->parent->left) { // branch on x being a LEFT-CHILD w = x->parent->right; // grab x's sibling if (w->color == true) { // if x's sibling is RED w->color = false; // color w BLACK (case 1) x->parent->color = true; // color x's parent RED (case 1) rotateLeft(x->parent); // left rotation on x's parent (case 1) w = x->parent->right; // make w be x's right sibling (case 1) } if ((w->left->color == false) && (w->right->color == false)) { w->color = true; // color w RED (case 2) x = x->parent; // examine x's parent (case 2) } else { // if (w->right->color == false) { w->left->color = false; // color w's left child BLACK (case 3) w->color = true; // color w RED (case 3) t = x->parent; // store x's parent rotateRight(w); // right rotation on w (case 3) x->parent = t; // restore x's parent w = x->parent->right; // make w be x's right sibling (case 3) } // w->color = x->parent->color; // w's color := x's parent's (case 4) x->parent->color = false; // color x's parent BLACK (case 4) w->right->color = false; // color w's right child BLACK (case 4) rotateLeft(x->parent); // left rotation on x's parent (case 4) x = root; // finished work. bail out (case 4) } // } else { // x is RIGHT-CHILD w = x->parent->left; // grab x's sibling if (w->color == true) { // if x's sibling is RED w->color = false; // color w BLACK (case 1) x->parent->color = true; // color x's parent RED (case 1) rotateRight(x->parent); // right rotation on x's parent (case 1) w = x->parent->left; // make w be x's left sibling (case 1) } if ((w->right->color == false) && (w->left->color == false)) { w->color = true; // color w RED (case 2) x = x->parent; // examine x's parent (case 2) } else { // if (w->left->color == false) { // w->right->color = false; // color w's right child BLACK (case 3) w->color = true; // color w RED (case 3) t = x->parent; // store x's parent rotateLeft(w); // left rotation on w (case 3) x->parent = t; // restore x's parent w = x->parent->left; // make w be x's left sibling (case 3) } // w->color = x->parent->color; // w's color := x's parent's (case 4) x->parent->color = false; // color x's parent BLACK (case 4) w->left->color = false; // color w's left child BLACK (case 4) rotateRight(x->parent); // right rotation on x's parent (case 4) x = root; // x is now the root (case 4) } } } x->color = false; // color x (the root) BLACK (exit) return; } // ******** Rotation Functions ******************************************* void splittree::rotateLeft(elementsp *x) { elementsp *y; // do pointer-swapping operations for left-rotation y = x->right; // grab right child x->right = y->left; // make x's RIGHT-CHILD be y's LEFT-CHILD y->left->parent = x; // make x be y's LEFT-CHILD's parent y->parent = x->parent; // make y's new parent be x's old parent if (x->parent == NULL) { root = y; // if x was root, make y root } else { // if (x == x->parent->left) { // if x is LEFT-CHILD, make y be x's parent's x->parent->left = y; // left-child } else { x->parent->right = y; // right-child } } y->left = x; // make x be y's LEFT-CHILD x->parent = y; // make y be x's parent return; } void splittree::rotateRight(elementsp *y) { elementsp *x; // do pointer-swapping operations for right-rotation x = y->left; // grab left child y->left = x->right; // replace left child yith x's right subtree x->right->parent = y; // replace y as x's right subtree's parent x->parent = y->parent; // make x's new parent be y's old parent if (y->parent == NULL) { root = x; // if y was root, make x root } else { if (y == y->parent->right) { // if y is R-CHILD, make x be y's parent's y->parent->right = x; // right-child } else { y->parent->left = x; // left-child } } x->right = y; // make y be x's RIGHT-CHILD y->parent = x; // make x be y's parent return; } // *********************************************************************** // *** COPYRIGHT NOTICE ************************************************** // graph_simp.h - graph data structure // Copyright (C) 2006-2008 Aaron Clauset // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.gnu.org/licenses/gpl.txt for more details. // // *********************************************************************** // Author : Aaron Clauset ( aaronc@santafe.edu | // http://www.santafe.edu/~aaronc/ ) // Collaborators: Cristopher Moore and Mark E.J. Newman // Project : Hierarchical Random Graphs // Location : University of New Mexico, Dept. of Computer Science // AND Santa Fe Institute // Created : 21 June 2006 // Modified : 23 December 2007 (cleaned up for public consumption) // // ************************************************************************ // ******** Constructor / Destructor ************************************* simpleGraph::simpleGraph(const int size): n(size), m(0), num_groups(0) { nodes = new simpleVert [n]; nodeLink = new simpleEdge* [n]; nodeLinkTail = new simpleEdge* [n]; A = new double* [n]; for (int i = 0; i < n; i++) { nodeLink[i] = NULL; nodeLinkTail[i] = NULL; A[i] = new double [n]; for (int j = 0; j < n; j++) { A[i][j] = 0.0; } } E = NULL; } simpleGraph::~simpleGraph() { simpleEdge *curr, *prev; for (int i = 0; i < n; i++) { curr = nodeLink[i]; delete [] A[i]; while (curr != NULL) { prev = curr; curr = curr->next; delete prev; } } curr = NULL; prev = NULL; if (E != NULL) { delete [] E; E = NULL; } delete [] A; A = NULL; delete [] nodeLink; nodeLink = NULL; delete [] nodeLinkTail; nodeLinkTail = NULL; delete [] nodes; nodes = NULL; } // *********************************************************************** bool simpleGraph::addGroup(const int i, const int group_index) { if (i >= 0 && i < n) { nodes[i].group_true = group_index; return true; } else { return false; } } // *********************************************************************** bool simpleGraph::addLink(const int i, const int j) { // Adds the directed edge (i,j) to the adjacency list for v_i simpleEdge* newedge; if (i >= 0 && i < n && j >= 0 && j < n) { A[i][j] = 1.0; newedge = new simpleEdge; newedge->x = j; if (nodeLink[i] == NULL) { // first neighbor nodeLink[i] = newedge; nodeLinkTail[i] = newedge; nodes[i].degree = 1; } else { // subsequent neighbor nodeLinkTail[i]->next = newedge; nodeLinkTail[i] = newedge; nodes[i].degree++; } m++; // increment edge count newedge = NULL; return true; } else { return false; } } // *********************************************************************** bool simpleGraph::doesLinkExist(const int i, const int j) { // This function determines if the edge (i,j) already exists in the // adjacency list of v_i if (i >= 0 && i < n && j >= 0 && j < n) { if (A[i][j] > 0.1) { return true; } else { return false; } } else { return false; } } // ********************************************************************** double simpleGraph::getAdjacency(const int i, const int j) { if (i >= 0 && i < n && j >= 0 && j < n) { return A[i][j]; } else { return -1.0; } } int simpleGraph::getDegree(const int i) { if (i >= 0 && i < n) { return nodes[i].degree; } else { return -1; } } int simpleGraph::getGroupLabel(const int i) { if (i >= 0 && i < n) { return nodes[i].group_true; } else { return -1; } } string simpleGraph::getName(const int i) { if (i >= 0 && i < n) { return nodes[i].name; } else { return ""; } } // NOTE: The following three functions return addresses; deallocation // of returned object is dangerous simpleEdge* simpleGraph::getNeighborList(const int i) { if (i >= 0 && i < n) { return nodeLink[i]; } else { return NULL; } } // END-NOTE // ********************************************************************* int simpleGraph::getNumGroups() { return num_groups; } int simpleGraph::getNumLinks() { return m; } int simpleGraph::getNumNodes() { return n; } simpleVert* simpleGraph::getNode(const int i) { if (i >= 0 && i < n) { return &nodes[i]; } else { return NULL; } } // ********************************************************************** bool simpleGraph::setName(const int i, const string text) { if (i >= 0 && i < n) { nodes[i].name = text; return true; } else { return false; } } // ********************************************************************** void simpleGraph::QsortMain (block* array, int left, int right) { if (right > left) { int pivot = left; int part = QsortPartition(array, left, right, pivot); QsortMain(array, left, part - 1); QsortMain(array, part + 1, right ); } return; } int simpleGraph::QsortPartition (block* array, int left, int right, int index) { block p_value, temp; p_value.x = array[index].x; p_value.y = array[index].y; // swap(array[p_value], array[right]) temp.x = array[right].x; temp.y = array[right].y; array[right].x = array[index].x; array[right].y = array[index].y; array[index].x = temp.x; array[index].y = temp.y; int stored = left; for (int i = left; i < right; i++) { if (array[i].x <= p_value.x) { // swap(array[stored], array[i]) temp.x = array[i].x; temp.y = array[i].y; array[i].x = array[stored].x; array[i].y = array[stored].y; array[stored].x = temp.x; array[stored].y = temp.y; stored++; } } // swap(array[right], array[stored]) temp.x = array[stored].x; temp.y = array[stored].y; array[stored].x = array[right].x; array[stored].y = array[right].y; array[right].x = temp.x; array[right].y = temp.y; return stored; } // *********************************************************************** leidenbase/src/core/hrg/graph_simp.h0000644000176200001440000001252314447675374017176 0ustar liggesusers/* -*- mode: C++ -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // **************************************************************************************************** // *** COPYRIGHT NOTICE ******************************************************************************* // graph_simp.h - graph data structure // Copyright (C) 2006-2008 Aaron Clauset // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.gnu.org/licenses/gpl.txt for more details. // // **************************************************************************************************** // Author : Aaron Clauset ( aaronc@santafe.edu | http://www.santafe.edu/~aaronc/ ) // Collaborators: Cristopher Moore and Mark E.J. Newman // Project : Hierarchical Random Graphs // Location : University of New Mexico, Dept. of Computer Science AND Santa Fe Institute // Created : 21 June 2006 // Modified : 23 December 2007 (cleaned up for public consumption) // // ************************************************************************ // // Simple graph data structure. The basic structure is an adjacency // list of edges, along with degree information for the vertices. // // ************************************************************************ #ifndef IGRAPH_HRG_SIMPLEGRAPH #define IGRAPH_HRG_SIMPLEGRAPH #include "hrg/rbtree.h" #include "hrg/dendro.h" #include #include namespace fitHRG { // ******** Basic Structures ********************************************* #ifndef IGRAPH_HRG_SIMPLEEDGE #define IGRAPH_HRG_SIMPLEEDGE class simpleEdge { public: int x; // index of edge terminator simpleEdge* next; // pointer to next elementd simpleEdge(): x(-1), next(0) { } ~simpleEdge() { } }; #endif #ifndef IGRAPH_HRG_SIMPLEVERT #define IGRAPH_HRG_SIMPLEVERT class simpleVert { public: std::string name; // (external) name of vertex int degree; // degree of this vertex int group_true; // index of vertex's true group simpleVert(): name(""), degree(0), group_true(-1) { } ~simpleVert() { } }; #endif #ifndef IGRAPH_HRG_TWOEDGE #define IGRAPH_HRG_TWOEDGE class twoEdge { public: int o; // index of edge originator int x; // index of edge terminator twoEdge(): o(-1), x(-1) { } ~twoEdge() { } }; #endif // ******** Graph Class with Edge Statistics ***************************** class simpleGraph { public: simpleGraph(const int); ~simpleGraph(); // add group label to vertex i bool addGroup(const int, const int); // add (i,j) to graph bool addLink(const int, const int); // true if (i,j) is already in graph bool doesLinkExist(const int, const int); // returns A(i,j) double getAdjacency(const int, const int); // returns degree of vertex i int getDegree(const int); // returns group label of vertex i int getGroupLabel(const int); // returns name of vertex i std::string getName(const int); // returns edge list of vertex i simpleEdge* getNeighborList(const int); // return pointer to a node simpleVert* getNode(const int); // returns num_groups int getNumGroups(); // returns m int getNumLinks(); // returns n int getNumNodes(); // set name of vertex i bool setName(const int, const std::string); private: simpleVert* nodes; // list of nodes simpleEdge** nodeLink; // linked list of neighbors to vertex simpleEdge** nodeLinkTail; // pointers to tail of neighbor list double** A; // adjacency matrix for this graph twoEdge* E; // list of all edges (array) int n; // number of vertices int m; // number of directed edges int num_groups; // number of bins in node histograms // quicksort functions void QsortMain(block*, int, int); int QsortPartition(block*, int, int, int); }; } // namespace fitHRG #endif leidenbase/src/core/hrg/graph.h0000644000176200001440000001376214447675374016154 0ustar liggesusers/* -*- mode: C++ -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // **************************************************************************************************** // *** COPYRIGHT NOTICE ******************************************************************************* // graph.h - graph data structure for hierarchical random graphs // Copyright (C) 2005-2008 Aaron Clauset // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.gnu.org/licenses/gpl.txt for more details. // // **************************************************************************************************** // Author : Aaron Clauset ( aaronc@santafe.edu | http://www.santafe.edu/~aaronc/ ) // Collaborators: Cristopher Moore and Mark E.J. Newman // Project : Hierarchical Random Graphs // Location : University of New Mexico, Dept. of Computer Science AND Santa Fe Institute // Created : 8 November 2005 // Modified : 23 December 2007 (cleaned up for public consumption) // // **************************************************************************************************** // // Graph data structure for hierarchical random graphs. The basic structure is an adjacency list of // edges; however, many additional pieces of metadata are stored as well. Each node stores its // external name, its degree and (if assigned) its group index. // // **************************************************************************************************** #ifndef IGRAPH_HRG_GRAPH #define IGRAPH_HRG_GRAPH #include "hrg/rbtree.h" #include #include #include namespace fitHRG { // ******** Basic Structures ********************************************* #ifndef IGRAPH_HRG_EDGE #define IGRAPH_HRG_EDGE class edge { public: int x; // stored integer value (edge terminator) double* h; // (histogram) weights of edge existence double total_weight; // (histogram) total weight observed int obs_count; // number of observations in histogram edge* next; // pointer to next elementd edge(): x(-1), h(0), total_weight(0.0), obs_count(0), next(0) { } ~edge() { if (h != NULL) { delete [] h; } h = NULL; } }; #endif #ifndef IGRAPH_HRG_VERT #define IGRAPH_HRG_VERT class vert { public: std::string name; // (external) name of vertex int degree; // degree of this vertex vert(): name(""), degree(0) { } ~vert() { } }; #endif // ******** Graph Class with Edge Statistics ***************************** class graph { public: graph(const int, bool predict = false); ~graph(); // add (i,j) to graph bool addLink(const int, const int); // add weight to (i,j)'s histogram bool addAdjacencyObs(const int, const int, const double, const double); // add to obs_count and total_weight void addAdjacencyEnd(); // true if (i,j) is already in graph bool doesLinkExist(const int, const int); // returns degree of vertex i int getDegree(const int); // returns name of vertex i std::string getName(const int); // returns edge list of vertex i edge* getNeighborList(const int); // return ptr to histogram of edge (i,j) double* getAdjacencyHist(const int, const int); // return average value of adjacency A(i,j) double getAdjacencyAverage(const int, const int); // returns bin_resolution double getBinResolution(); // returns num_bins int getNumBins(); // returns m int numLinks(); // returns n int numNodes(); // returns total_weight double getTotalWeight(); // reset edge (i,j)'s histogram void resetAdjacencyHistogram(const int, const int); // reset all edge histograms void resetAllAdjacencies(); // clear all links from graph void resetLinks(); // allocate edge histograms void setAdjacencyHistograms(const int); // set name of vertex i bool setName(const int, const std::string); private: bool predict; // do we need prediction? vert* nodes; // list of nodes edge** nodeLink; // linked list of neighbors to vertex edge** nodeLinkTail; // pointers to tail of neighbor list double*** A; // stochastic adjacency matrix for this graph int obs_count; // number of observations in A double total_weight; // total weight added to A int n; // number of vertices int m; // number of directed edges int num_bins; // number of bins in edge histograms double bin_resolution; // width of histogram bin }; } // namespace fitHRG #endif leidenbase/src/core/hrg/rbtree.h0000644000176200001440000001370714447675374016335 0ustar liggesusers/* -*- mode: C++ -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // **************************************************************************************************** // *** COPYRIGHT NOTICE ******************************************************************************* // rbtree - red-black tree (self-balancing binary tree data structure) // Copyright (C) 2004 Aaron Clauset // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.gnu.org/licenses/gpl.txt for more details. // // **************************************************************************************************** // Author : Aaron Clauset ( aaronc@santafe.edu | http://www.santafe.edu/~aaronc/ ) // Collaborators: Cristopher Moore and Mark Newman // Project : Hierarchical Random Graphs // Location : University of New Mexico, Dept. of Computer Science AND Santa Fe Institute // Created : Spring 2004 // Modified : many, many times // // **************************************************************************************************** #ifndef IGRAPH_HRG_RBTREE #define IGRAPH_HRG_RBTREE namespace fitHRG { // ******** Basic Structures ********************************************* #ifndef IGRAPH_HRG_LIST #define IGRAPH_HRG_LIST class list { public: int x; // stored elementd in linked-list list* next; // pointer to next elementd list(): x(-1), next(0) { } ~list() { } }; #endif class keyValuePair { public: int x; // elementrb key (int) int y; // stored value (int) keyValuePair* next; // linked-list pointer keyValuePair(): x(-1), y(-1), next(0) { } ~keyValuePair() { } }; // ******** Tree elementrb Class ***************************************** class elementrb { public: int key; // search key (int) int value; // stored value (int) bool color; // F: BLACK, T: RED short int mark; // marker elementrb *parent; // pointer to parent node elementrb *left; // pointer for left subtree elementrb *right; // pointer for right subtree elementrb(): key(-1), value(-1), color(false), mark(0), parent(0), left(0), right(0) { } ~elementrb() { } }; // ******** Red-Black Tree Class ***************************************** // This vector implementation is a red-black balanced binary tree data // structure. It provides find a stored elementrb in time O(log n), // find the maximum elementrb in time O(1), delete an elementrb in // time O(log n), and insert an elementrb in time O(log n). // // Note that the key=0 is assumed to be a special value, and thus you // cannot insert such an item. Beware of this limitation. class rbtree { private: elementrb* root; // binary tree root elementrb* leaf; // all leaf nodes int support; // number of nodes in the tree void rotateLeft(elementrb *x); // left-rotation operator void rotateRight(elementrb *y); // right-rotation operator void insertCleanup(elementrb *z); // house-keeping after insertion void deleteCleanup(elementrb *x); // house-keeping after deletion keyValuePair* returnSubtreeAsList(elementrb *z, keyValuePair *head); void deleteSubTree(elementrb *z); // delete subtree rooted at z elementrb* returnMinKey(elementrb *z); // returns minimum of subtree // rooted at z elementrb* returnSuccessor(elementrb *z); // returns successor of z's key public: rbtree(); ~rbtree(); // default constructor/destructor // returns value associated with searchKey int returnValue(const int searchKey); // returns T if searchKey found, and points foundNode at the // corresponding node elementrb* findItem(const int searchKey); // insert a new key with stored value void insertItem(int newKey, int newValue); // selete a node with given key void deleteItem(int killKey); // replace value of a node with given key void replaceItem(int key, int newValue); // increment the value of the given key void incrementValue(int key); // delete the entire tree void deleteTree(); // return array of keys in tree int* returnArrayOfKeys(); // return list of keys in tree list* returnListOfKeys(); // return the tree as a list of keyValuePairs keyValuePair* returnTreeAsList(); // returns the maximum key in the tree keyValuePair returnMaxKey(); // returns the minimum key in the tree keyValuePair returnMinKey(); // returns number of items in tree int returnNodecount(); }; } #endif leidenbase/src/core/hrg/dendro.h0000644000176200001440000002675214447675374016331 0ustar liggesusers/* -*- mode: C++ -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // **************************************************************************************************** // *** COPYRIGHT NOTICE ******************************************************************************* // dendro_eq.h - hierarchical random graph (hrg) data structure // Copyright (C) 2006-2008 Aaron Clauset // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.gnu.org/licenses/gpl.txt for more details. // // **************************************************************************************************** // Author : Aaron Clauset ( aaronc@santafe.edu | http://www.santafe.edu/~aaronc/ ) // Collaborators: Cristopher Moore and Mark E.J. Newman // Project : Hierarchical Random Graphs // Location : University of New Mexico, Dept. of Computer Science AND Santa Fe Institute // Created : 19 April 2006 // Modified : 19 May 2007 // : 19 May 2008 (cleaned up for public consumption) // // **************************************************************************************************** // // Maximum likelihood dendrogram data structure. This is the heart of the HRG algorithm: all // manipulations are done here and all data is stored here. The data structure uses the separate // graph data structure to store the basic adjacency information (in a dangerously mutable way). // // Note: This version (dendro_eq.h) differs from other versions because it includes methods for // doing the consensus dendrogram calculation. // // **************************************************************************************************** #ifndef IGRAPH_HRG_DENDRO #define IGRAPH_HRG_DENDRO #include "hrg/graph.h" #include "hrg/rbtree.h" #include "hrg/splittree_eq.h" #include "igraph_hrg.h" #include #include using namespace fitHRG; namespace fitHRG { // *********************************************************************** // ******** Basic Structures ********************************************* #ifndef IGRAPH_HRG_LIST #define IGRAPH_HRG_LIST class list { public: int x; // stored elementd in linked-list list* next; // pointer to next elementd list::list(): x(-1), next(0) { } list::~list() { } }; #endif enum {DENDRO, GRAPH, LEFT, RIGHT}; struct block { double x; int y; }; struct ipair { int x; int y; short int t; std::string sp; }; struct child { int index; short int type; child* next; }; // *********************************************************************** // ******** Cnode Class ************************************************** #ifndef IGRAPH_HRG_CNODE #define IGRAPH_HRG_CNODE class cnode { public: int index; // array index of this node int degree; // number of children in list int parent; // index of parent node double weight; // sampled posterior weight child* children; // list of children (and their types) child* lastChild; // pointer to last child in list cnode(): index(-1), degree(0), parent(-1), weight(0.0), children(0), lastChild(0) { } ~cnode() { child *curr, *prev; curr = children; while (curr != NULL) { prev = curr; curr = curr->next; delete prev; prev = NULL; } lastChild = NULL; } }; #endif // *********************************************************************** // ******** Split Class ************************************************** class split { public: std::string s; // partition assignment of leaf vertices split(): s("") { } ~split() { } void initializeSplit(const int n) { s = ""; for (int i = 0; i < n; i++) { s += "-"; } } bool checkSplit() { if (s.empty() || s.find("-", 0) != std::string::npos) { return false; } else { return true; } } }; // *********************************************************************** // ******** Internal Edge Class ****************************************** // The usefulness of this data structure is to provide an easy to way // maintain the set of internal edges, and the corresponding splits, // in the dendrogram D. It allows for the selection of a random // internal edge in O(1) time, and it takes O(1) time to update its // structure given an internal move. This structure does not provide // any means to directly manipulate the splits, but does allow them to // be replaced. A split has the form "int.int...int#int.int...int", // where all ints on the left side of the # are in the left partition // and all ints on the right side of the # marker are in the right // partition defined by the split. class interns { private: ipair* edgelist; // list of internal edges represented std::string* splitlist; // split representation of the internal edges int** indexLUT; // table of indices of internal edges in edgelist int q; // number of internal edges int count; // (for adding edges) edgelist index of new edge to add public: interns(const int); ~interns(); // add an internal edge, O(1) bool addEdge(const int, const int, const short int); // returns the ith edge of edgelist, O(1) ipair* getEdge(const int); // returns a uniformly random internal edge, O(1) ipair* getRandomEdge(); // returns the ith split of the splitlist, O(1) std::string getSplit(const int); // replace an existing split, O(1) bool replaceSplit(const int, const std::string); // swaps two edges, O(1) bool swapEdges(const int, const int, const short int, const int, const int, const short int); }; // *********************************************************************** // ******** Tree elementd Class ****************************************** class elementd { public: short int type; // either DENDRO or GRAPH double logL; // log-likelihood contribution of this internal node double p; // probability p_i that an edge exists between L and // R subtrees int e; // number of edges between L and R subtrees int n; // number of leafs in subtree rooted here int label; // subtree label: smallest leaf index int index; // index in containing array elementd *M; // pointer to parent node elementd *L; // pointer for L subtree elementd *R; // pointer for R subtree elementd(): type(DENDRO), logL(0.0), p(0.0), e(0), n(0), label(-1), index(-1), M(0), L(0), R(0) { } ~elementd() { } }; // *********************************************************************** // ******** Dendrogram Class ********************************************* class dendro { private: elementd* root; // root of the dendrogram elementd* internal; // array of n-1 internal vertices (the dendrogram D) elementd* leaf; // array of n leaf vertices (the graph G) int n; // number of leaf vertices to allocate interns* d; // list of internal edges of dendrogram D splittree* splithist; // histogram of cumulative split weights list** paths; // array of path-lists from root to leaf double L; // log-likelihood of graph G given dendrogram D rbtree subtreeL, subtreeR; // trees for computeEdgeCount() function cnode* ctree; // (consensus tree) array of internal tree nodes int* cancestor; // (consensus tree) oldest ancetor's index for // each leaf // insert node i according to binary search property void binarySearchInsert(elementd*, elementd*); // return path to root from leaf list* binarySearchFind(const double); // build split for this internal edge std::string buildSplit(elementd*); // compute number of edges between two internal subtrees int computeEdgeCount(const int, const short int, const int, const short int); // (consensus tree) counts children int countChildren(const std::string); // find internal node of D that is common ancestor of i,j elementd* findCommonAncestor(list**, const int, const int); // return reverse of path to leaf from root list* reversePathToRoot(const int); // quicksort functions void QsortMain(block*, int, int); int QsortPartition(block*, int, int, int); public: // underlying G (dangerously accessible) graph* g; // constructor / destructor dendro(); ~dendro(); // build dendrogram from g void buildDendrogram(); // delete dendrograph in prep for importDendrogramStructure void clearDendrograph(); // read dendrogram structure from HRG structure bool importDendrogramStructure(const igraph_hrg_t *hrg); // (consensus tree) delete splits with less than 0.5 weight void cullSplitHist(); // return size of consensus split int getConsensusSize(); // return split tree with consensus splits splittree* getConsensusSplits(); // return likelihood of G given D double getLikelihood(); // store splits in this splittree void getSplitList(splittree*); // return total weight of splittree double getSplitTotalWeight(); // make random G from D void makeRandomGraph(); // make single MCMC move bool monteCarloMove(double&, bool&, const double); // record consensus tree from splithist void recordConsensusTree(igraph_vector_t *parents, igraph_vector_t *weights); // record D structure void recordDendrogramStructure(igraph_hrg_t *hrg); // record G structure to igraph graph void recordGraphStructure(igraph_t *graph); // force refresh of log-likelihood value void refreshLikelihood(); // sample dendrogram edge likelihoods and update edge histograms void sampleAdjacencyLikelihoods(); // reset the dendrograph structures void resetDendrograph(); // sample dendrogram's splits and update the split histogram bool sampleSplitLikelihoods(int&); // reset splits histogram void resetAllSplits(); }; } // namespace fitHRG #endif leidenbase/src/core/hrg/splittree_eq.h0000644000176200001440000001545114447675374017550 0ustar liggesusers/* -*- mode: C++ -*- */ /* IGraph library. Copyright (C) 2011-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // **************************************************************************************************** // *** COPYRIGHT NOTICE ******************************************************************************* // splittree_eq.h - a binary search tree data structure for storing dendrogram split frequencies // Copyright (C) 2006-2008 Aaron Clauset // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.gnu.org/licenses/gpl.txt for more details. // // **************************************************************************************************** // Author : Aaron Clauset ( aaronc@santafe.edu | http://www.santafe.edu/~aaronc/ ) // Collaborators: Cristopher Moore and Mark E.J. Newman // Project : Hierarchical Random Graphs // Location : University of New Mexico, Dept. of Computer Science AND Santa Fe Institute // Created : 19 April 2006 // Modified : 19 May 2007 // : 20 May 2008 (cleaned up for public consumption) // // *********************************************************************** // // Data structure for storing the split frequences in the sampled // dendrograms. Data is stored efficiently as a red-black binary // search tree (this is a modified version of the rbtree.h file). // // *********************************************************************** #ifndef IGRAPH_HRG_SPLITTREE #define IGRAPH_HRG_SPLITTREE #include namespace fitHRG { // ******** Basic Structures ********************************************* #ifndef IGRAPH_HRG_SLIST #define IGRAPH_HRG_SLIST class slist { public: std::string x; // stored elementd in linked-list slist* next; // pointer to next elementd slist(): x(""), next(0) { } ~slist() { } }; #endif class keyValuePairSplit { public: std::string x; // elementsp split (string) double y; // stored weight (double) int c; // stored count (int) keyValuePairSplit* next; // linked-list pointer keyValuePairSplit(): x(""), y(0.0), c(0), next(0) { } ~keyValuePairSplit() { } }; // ******** Tree elementsp Class ***************************************** class elementsp { public: std::string split; // split represented as a string double weight; // total weight of this split int count; // number of observations of this split bool color; // F: BLACK, T: RED short int mark; // marker elementsp *parent; // pointer to parent node elementsp *left; // pointer for left subtree elementsp *right; // pointer for right subtree elementsp(): split(""), weight(0.0), count(0), color(false), mark(0), parent(0), left(0), right(0) { } ~elementsp() { } }; // ******** Red-Black Tree Class ***************************************** // This vector implementation is a red-black balanced binary tree data // structure. It provides find a stored elementsp in time O(log n), // find the maximum elementsp in time O(1), delete an elementsp in // time O(log n), and insert an elementsp in time O(log n). // // Note that the split="" is assumed to be a special value, and thus // you cannot insert such an item. Beware of this limitation. // class splittree { private: elementsp* root; // binary tree root elementsp* leaf; // all leaf nodes int support; // number of nodes in the tree double total_weight; // total weight stored int total_count; // total number of observations stored // left-rotation operator void rotateLeft(elementsp*); // right-rotation operator void rotateRight(elementsp*); // house-keeping after insertion void insertCleanup(elementsp*); // house-keeping after deletion void deleteCleanup(elementsp*); keyValuePairSplit* returnSubtreeAsList(elementsp*, keyValuePairSplit*); // delete subtree rooted at z void deleteSubTree(elementsp*); // returns minimum of subtree rooted at z elementsp* returnMinKey(elementsp*); // returns successor of z's key elementsp* returnSuccessor(elementsp*); public: // default constructor/destructor splittree(); ~splittree(); // returns value associated with searchKey double returnValue(const std::string); // returns T if searchKey found, and points foundNode at the // corresponding node elementsp* findItem(const std::string); // update total_count and total_weight void finishedThisRound(); // insert a new key with stored value bool insertItem(std::string, double); void clearTree(); // delete a node with given key void deleteItem(std::string); // delete the entire tree void deleteTree(); // return array of keys in tree std::string* returnArrayOfKeys(); // return list of keys in tree slist* returnListOfKeys(); // return the tree as a list of keyValuePairSplits keyValuePairSplit* returnTreeAsList(); // returns the maximum key in the tree keyValuePairSplit returnMaxKey(); // returns the minimum key in the tree keyValuePairSplit returnMinKey(); // returns number of items in tree int returnNodecount(); // returns list of splits with given number of Ms keyValuePairSplit* returnTheseSplits(const int); // returns sum of stored values double returnTotal(); }; } // namespace fitHRG #endif leidenbase/src/core/hrg/hrg.cc0000644000176200001440000010333714447675374015767 0ustar liggesusers/* -*- mode: C++ -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_attributes.h" #include "igraph_hrg.h" #include "igraph_random.h" #include "hrg/dendro.h" #include "hrg/graph.h" #include "hrg/graph_simp.h" using namespace fitHRG; /** * \section hrg_intro Introduction * * A hierarchical random graph is an ensemble of undirected * graphs with \c n vertices. It is defined via a binary tree with \c * n leaf and \c n-1 internal vertices, where the * internal vertices are labeled with probabilities. * The probability that two vertices are connected in the random graph * is given by the probability label at their closest common * ancestor. * * * Please read the following two articles for more about * hierarchical random graphs: A. Clauset, C. Moore, and M.E.J. Newman. * Hierarchical structure and the prediction of missing links in networks. * Nature 453, 98 - 101 (2008); and A. Clauset, C. Moore, and M.E.J. Newman. * Structural Inference of Hierarchies in Networks. In E. M. Airoldi * et al. (Eds.): ICML 2006 Ws, Lecture Notes in Computer Science * 4503, 1-13. Springer-Verlag, Berlin Heidelberg (2007). * * * * igraph contains functions for fitting HRG models to a given network * (\ref igraph_hrg_fit), for generating networks from a given HRG * ensemble (\ref igraph_hrg_game, \ref igraph_hrg_sample), converting * an igraph graph to a HRG and back (\ref igraph_hrg_create, \ref * igraph_hrg_dendrogram), for calculating a consensus tree from a * set of sampled HRGs (\ref igraph_hrg_consensus) and for predicting * missing edges in a network based on its HRG models (\ref * igraph_hrg_predict). * * * The igraph HRG implementation is heavily based on the code * published by Aaron Clauset, at his website, * http://tuvalu.santafe.edu/~aaronc/hierarchy/ * */ namespace fitHRG { struct pblock { double L; int i; int j; }; } static int markovChainMonteCarlo(dendro *d, unsigned int period, igraph_hrg_t *hrg) { igraph_real_t bestL = d->getLikelihood(); double dL; bool flag_taken; // Because moves in the dendrogram space are chosen (Monte // Carlo) so that we sample dendrograms with probability // proportional to their likelihood, a likelihood-proportional // sampling of the dendrogram models would be equivalent to a // uniform sampling of the walk itself. We would still have to // decide how often to sample the walk (at most once every n // steps is recommended) but for simplicity, the code here // simply runs the MCMC itself. To actually compute something // over the set of sampled dendrogram models (in a Bayesian // model averaging sense), you'll need to code that yourself. // do 'period' MCMC moves before doing anything else for (unsigned int i = 0; i < period; i++) { // make a MCMC move IGRAPH_CHECK(! d->monteCarloMove(dL, flag_taken, 1.0)); // get likelihood of this D given G igraph_real_t cl = d->getLikelihood(); if (cl > bestL) { // store the current best likelihood bestL = cl; // record the HRG structure d->recordDendrogramStructure(hrg); } } // corrects floating-point errors O(n) d->refreshLikelihood(); return 0; } static int markovChainMonteCarlo2(dendro *d, int num_samples) { bool flag_taken; double dL, ptest = 1.0 / (50.0 * (double)(d->g->numNodes())); int sample_num = 0, t = 1, thresh = 200 * d->g->numNodes(); // Since we're sampling uniformly at random over the equilibrium // walk, we just need to do a bunch of MCMC moves and let the // sampling happen on its own. while (sample_num < num_samples) { // Make a single MCMC move d->monteCarloMove(dL, flag_taken, 1.0); // We sample the dendrogram space once every n MCMC moves (on // average). Depending on the flags on the command line, we sample // different aspects of the dendrograph structure. if (t > thresh && RNG_UNIF01() < ptest) { sample_num++; d->sampleSplitLikelihoods(sample_num); } t++; // correct floating-point errors O(n) d->refreshLikelihood(); // TODO: less frequently } return 0; } static int MCMCEquilibrium_Find(dendro *d, igraph_hrg_t *hrg) { // We want to run the MCMC until we've found equilibrium; we // use the heuristic of the average log-likelihood (which is // exactly the entropy) over X steps being very close to the // average log-likelihood (entropy) over the X steps that // preceded those. In other words, we look for an apparent // local convergence of the entropy measure of the MCMC. bool flag_taken; igraph_real_t dL, Likeli; igraph_real_t oldMeanL; igraph_real_t newMeanL = -1e-49; while (1) { oldMeanL = newMeanL; newMeanL = 0.0; for (int i = 0; i < 65536; i++) { IGRAPH_CHECK(! d->monteCarloMove(dL, flag_taken, 1.0)); Likeli = d->getLikelihood(); newMeanL += Likeli; } // corrects floating-point errors O(n) d->refreshLikelihood(); if (fabs(newMeanL - oldMeanL) / 65536.0 < 1.0) { break; } } // Record the result if (hrg) { d->recordDendrogramStructure(hrg); } return 0; } static int igraph_i_hrg_getgraph(const igraph_t *igraph, dendro *d) { int no_of_nodes = igraph_vcount(igraph); int no_of_edges = igraph_ecount(igraph); int i; // Create graph d->g = new graph(no_of_nodes); // Add edges for (i = 0; i < no_of_edges; i++) { int from = IGRAPH_FROM(igraph, i); int to = IGRAPH_TO(igraph, i); if (from == to) { continue; } if (!d->g->doesLinkExist(from, to)) { d->g->addLink(from, to); } if (!d->g->doesLinkExist(to, from)) { d->g->addLink(to, from); } } d->buildDendrogram(); return 0; } static int igraph_i_hrg_getsimplegraph(const igraph_t *igraph, dendro *d, simpleGraph **sg, int num_bins) { int no_of_nodes = igraph_vcount(igraph); int no_of_edges = igraph_ecount(igraph); int i; // Create graphs d->g = new graph(no_of_nodes, true); d->g->setAdjacencyHistograms(num_bins); (*sg) = new simpleGraph(no_of_nodes); for (i = 0; i < no_of_edges; i++) { int from = IGRAPH_FROM(igraph, i); int to = IGRAPH_TO(igraph, i); if (from == to) { continue; } if (!d->g->doesLinkExist(from, to)) { d->g->addLink(from, to); } if (!d->g->doesLinkExist(to, from)) { d->g->addLink(to, from); } if (!(*sg)->doesLinkExist(from, to)) { (*sg)->addLink(from, to); } if (!(*sg)->doesLinkExist(to, from)) { (*sg)->addLink(to, from); } } d->buildDendrogram(); return 0; } /** * \function igraph_hrg_init * Allocate memory for a HRG. * * This function must be called before passing an \ref igraph_hrg_t to * an igraph function. * \param hrg Pointer to the HRG data structure to initialize. * \param n The number of vertices in the graph that is modeled by * this HRG. It can be zero, if this is not yet known. * \return Error code. * * Time complexity: O(n), the number of vertices in the graph. */ int igraph_hrg_init(igraph_hrg_t *hrg, int n) { IGRAPH_VECTOR_INIT_FINALLY(&hrg->left, n - 1); IGRAPH_VECTOR_INIT_FINALLY(&hrg->right, n - 1); IGRAPH_VECTOR_INIT_FINALLY(&hrg->prob, n - 1); IGRAPH_VECTOR_INIT_FINALLY(&hrg->edges, n - 1); IGRAPH_VECTOR_INIT_FINALLY(&hrg->vertices, n - 1); IGRAPH_FINALLY_CLEAN(5); return 0; } /** * \function igraph_hrg_destroy * Deallocate memory for an HRG. * * The HRG data structure can be reinitialized again with an \ref * igraph_hrg_destroy call. * \param hrg Pointer to the HRG data structure to deallocate. * * Time complexity: operating system dependent. */ void igraph_hrg_destroy(igraph_hrg_t *hrg) { igraph_vector_destroy(&hrg->left); igraph_vector_destroy(&hrg->right); igraph_vector_destroy(&hrg->prob); igraph_vector_destroy(&hrg->edges); igraph_vector_destroy(&hrg->vertices); } /** * \function igraph_hrg_size * Returns the size of the HRG, the number of leaf nodes. * * \param hrg Pointer to the HRG. * \return The number of leaf nodes in the HRG. * * Time complexity: O(1). */ int igraph_hrg_size(const igraph_hrg_t *hrg) { return igraph_vector_size(&hrg->left) + 1; } /** * \function igraph_hrg_resize * Resize a HRG. * * \param hrg Pointer to an initialized (see \ref igraph_hrg_init) * HRG. * \param newsize The new size, i.e. the number of leaf nodes. * \return Error code. * * Time complexity: O(n), n is the new size. */ int igraph_hrg_resize(igraph_hrg_t *hrg, int newsize) { int origsize = igraph_hrg_size(hrg); int ret = 0; igraph_error_handler_t *oldhandler = igraph_set_error_handler(igraph_error_handler_ignore); ret = igraph_vector_resize(&hrg->left, newsize - 1); ret |= igraph_vector_resize(&hrg->right, newsize - 1); ret |= igraph_vector_resize(&hrg->prob, newsize - 1); ret |= igraph_vector_resize(&hrg->edges, newsize - 1); ret |= igraph_vector_resize(&hrg->vertices, newsize - 1); igraph_set_error_handler(oldhandler); if (ret) { igraph_vector_resize(&hrg->left, origsize); igraph_vector_resize(&hrg->right, origsize); igraph_vector_resize(&hrg->prob, origsize); igraph_vector_resize(&hrg->edges, origsize); igraph_vector_resize(&hrg->vertices, origsize); IGRAPH_ERROR("Cannot resize HRG", ret); } return 0; } /** * \function igraph_hrg_fit * Fit a hierarchical random graph model to a network * * \param graph The igraph graph to fit the model to. Edge directions * are ignored in directed graphs. * \param hrg Pointer to an initialized HRG, the result of the fitting * is stored here. It can also be used to pass a HRG to the * function, that can be used as the starting point of the Markov * Chain Monte Carlo fitting, if the \c start argument is true. * \param start Logical, whether to start the fitting from the given * HRG. * \param steps Integer, the number of MCMC steps to take in the * fitting procedure. If this is zero, then the fitting stop is a * convergence criteria is fulfilled. * \return Error code. * * Time complexity: TODO. */ int igraph_hrg_fit(const igraph_t *graph, igraph_hrg_t *hrg, igraph_bool_t start, int steps) { int no_of_nodes = igraph_vcount(graph); dendro *d; RNG_BEGIN(); d = new dendro; // If we want to start from HRG if (start) { d->clearDendrograph(); if (igraph_hrg_size(hrg) != no_of_nodes) { delete d; IGRAPH_ERROR("Invalid HRG to start from", IGRAPH_EINVAL); } // Convert the igraph graph IGRAPH_CHECK(igraph_i_hrg_getgraph(graph, d)); d->importDendrogramStructure(hrg); } else { // Convert the igraph graph IGRAPH_CHECK(igraph_i_hrg_getgraph(graph, d)); IGRAPH_CHECK(igraph_hrg_resize(hrg, no_of_nodes)); } // Run fixed number of steps, or until convergence if (steps > 0) { IGRAPH_CHECK(markovChainMonteCarlo(d, steps, hrg)); } else { IGRAPH_CHECK(MCMCEquilibrium_Find(d, hrg)); } delete d; RNG_END(); return 0; } /** * \function igraph_hrg_sample * Sample from a hierarchical random graph model * * Sample from a hierarchical random graph ensemble. The ensemble can * be given as a graph (\c input_graph), or as a HRG object (\c hrg). * If a graph is given, then first an MCMC optimization is performed * to find the optimal fitting model; then the MCMC is used to sample * the graph(s). * \param input_graph An igraph graph, or a null pointer. If not a * null pointer, then a HRG is first fitted to the graph, possibly * starting from the given HRG, if the \c start argument is true. If * is is a null pointer, then the given HRG is used as a starting * point, to find the optimum of the Markov chain, before the * sampling. * \param sample Pointer to an uninitialized graph, or a null * pointer. If only one sample is requested, and it is not a null * pointer, then the sample is stored here. * \param samples An initialized vector of pointers. If more than one * samples are requested, then they are stored here. Note that to * free this data structure, you need to call \ref igraph_destroy() on * each graph first, then \ref igraph_free() on all pointers, and finally * \ref igraph_vector_ptr_destroy. * \param no_samples The number of samples to generate. * \param hrg A HRG. It is modified during the sampling. * \param start Logical, whether to start the MCMC from the given * HRG. * \return Error code. * * Time complexity: TODO. */ int igraph_hrg_sample(const igraph_t *input_graph, igraph_t *sample, igraph_vector_ptr_t *samples, igraph_integer_t no_samples, igraph_hrg_t *hrg, igraph_bool_t start) { int i; dendro *d; if (no_samples < 0) { IGRAPH_ERROR("Number of samples must be non-negative", IGRAPH_EINVAL); } if (!sample && !samples) { IGRAPH_ERROR("Give at least one of `sample' and `samples'", IGRAPH_EINVAL); } if (no_samples != 1 && sample) { IGRAPH_ERROR("Number of samples should be one if `sample' is given", IGRAPH_EINVAL); } if (no_samples > 1 && !samples) { IGRAPH_ERROR("`samples' must be non-null if number of samples " "is larger than 1", IGRAPH_EINVAL); } if (!start && !input_graph) { IGRAPH_ERROR("Input graph must be given if initial HRG is not used", IGRAPH_EINVAL); } if (!start) { IGRAPH_CHECK(igraph_hrg_resize(hrg, igraph_vcount(input_graph))); } if (input_graph && igraph_hrg_size(hrg) != igraph_vcount(input_graph)) { IGRAPH_ERROR("Invalid HRG size, should match number of nodes", IGRAPH_EINVAL); } RNG_BEGIN(); d = new dendro; // Need to find equilibrium first? if (start) { d->clearDendrograph(); d->importDendrogramStructure(hrg); } else { IGRAPH_CHECK(MCMCEquilibrium_Find(d, hrg)); } // TODO: free on error if (sample) { // A single graph d->makeRandomGraph(); d->recordGraphStructure(sample); if (samples) { igraph_t *G = IGRAPH_CALLOC(1, igraph_t); if (!G) { IGRAPH_ERROR("Cannot sample HRG graphs", IGRAPH_ENOMEM); } d->recordGraphStructure(G); IGRAPH_CHECK(igraph_vector_ptr_resize(samples, 1)); VECTOR(*samples)[0] = G; } } else { // Sample many IGRAPH_CHECK(igraph_vector_ptr_resize(samples, no_samples)); for (i = 0; i < no_samples; i++) { igraph_t *G = IGRAPH_CALLOC(1, igraph_t); if (!G) { IGRAPH_ERROR("Cannot sample HRG graphs", IGRAPH_ENOMEM); } d->makeRandomGraph(); d->recordGraphStructure(G); VECTOR(*samples)[i] = G; } } delete d; RNG_END(); return 0; } /** * \function igraph_hrg_game * Generate a hierarchical random graph * * This function is a simple shortcut to \ref igraph_hrg_sample. * It creates a single graph, from the given HRG. * \param graph Pointer to an uninitialized graph, the new graph is * created here. * \param hrg The hierarchical random graph model to sample from. It * is modified during the MCMC process. * \return Error code. * * Time complexity: TODO. */ int igraph_hrg_game(igraph_t *graph, const igraph_hrg_t *hrg) { return igraph_hrg_sample(/* input_graph= */ 0, /* sample= */ graph, /* samples= */ 0, /* no_samples=*/ 1, /* hrg= */ (igraph_hrg_t*) hrg, /* start= */ 1); } /** * \function igraph_hrg_dendrogram * Create a dendrogram from a hierarchical random graph. * * Creates the igraph graph equivalent of an \ref igraph_hrg_t data * structure. * \param graph Pointer to an uninitialized graph, the result is * stored here. * \param hrg The hierarchical random graph to convert. * \return Error code. * * Time complexity: O(n), the number of vertices in the graph. */ int igraph_hrg_dendrogram(igraph_t *graph, const igraph_hrg_t *hrg) { int orig_nodes = igraph_hrg_size(hrg); int no_of_nodes = orig_nodes * 2 - 1; int no_of_edges = no_of_nodes > 0 ? no_of_nodes - 1 : 0; igraph_vector_t edges; int i, idx = 0; igraph_vector_ptr_t vattrs; igraph_vector_t prob; igraph_attribute_record_t rec = { "probability", IGRAPH_ATTRIBUTE_NUMERIC, &prob }; // Probability labels, for leaf nodes they are IGRAPH_NAN IGRAPH_VECTOR_INIT_FINALLY(&prob, no_of_nodes); for (i = 0; i < orig_nodes; i++) { VECTOR(prob)[i] = IGRAPH_NAN; } for (i = 0; i < orig_nodes - 1; i++) { VECTOR(prob)[orig_nodes + i] = VECTOR(hrg->prob)[i]; } IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2); IGRAPH_CHECK(igraph_vector_ptr_init(&vattrs, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &vattrs); VECTOR(vattrs)[0] = &rec; for (i = 0; i < orig_nodes - 1; i++) { int left = VECTOR(hrg->left)[i]; int right = VECTOR(hrg->right)[i]; VECTOR(edges)[idx++] = orig_nodes + i; VECTOR(edges)[idx++] = left < 0 ? orig_nodes - left - 1 : left; VECTOR(edges)[idx++] = orig_nodes + i; VECTOR(edges)[idx++] = right < 0 ? orig_nodes - right - 1 : right; } IGRAPH_CHECK(igraph_empty(graph, 0, IGRAPH_DIRECTED)); IGRAPH_FINALLY(igraph_destroy, graph); IGRAPH_CHECK(igraph_add_vertices(graph, no_of_nodes, &vattrs)); IGRAPH_CHECK(igraph_add_edges(graph, &edges, 0)); igraph_vector_ptr_destroy(&vattrs); igraph_vector_destroy(&edges); igraph_vector_destroy(&prob); IGRAPH_FINALLY_CLEAN(4); // + 1 for graph return 0; } /** * \function igraph_hrg_consensus * Calculate a consensus tree for a HRG. * * The calculation can be started from the given HRG (\c hrg), or (if * \c start is false), a HRG is first fitted to the given graph. * * \param graph The input graph. * \param parents An initialized vector, the results are stored * here. For each vertex, the id of its parent vertex is stored, or * -1, if the vertex is the root vertex in the tree. The first n * vertex ids (from 0) refer to the original vertices of the graph, * the other ids refer to vertex groups. * \param weights Numeric vector, counts the number of times a given * tree split occured in the generated network samples, for each * internal vertices. The order is the same as in \c parents. * \param hrg A hierarchical random graph. It is used as a starting * point for the sampling, if the \c start argument is true. It is * modified along the MCMC. * \param start Logical, whether to use the supplied HRG (in \c hrg) * as a starting point for the MCMC. * \param num_samples The number of samples to generate for creating * the consensus tree. * \return Error code. * * Time complexity: TODO. */ int igraph_hrg_consensus(const igraph_t *graph, igraph_vector_t *parents, igraph_vector_t *weights, igraph_hrg_t *hrg, igraph_bool_t start, int num_samples) { dendro *d; if (start && !hrg) { IGRAPH_ERROR("`hrg' must be given is `start' is true", IGRAPH_EINVAL); } RNG_BEGIN(); d = new dendro; if (start) { d->clearDendrograph(); IGRAPH_CHECK(igraph_i_hrg_getgraph(graph, d)); d->importDendrogramStructure(hrg); } else { IGRAPH_CHECK(igraph_i_hrg_getgraph(graph, d)); if (hrg) { igraph_hrg_resize(hrg, igraph_vcount(graph)); } IGRAPH_CHECK(MCMCEquilibrium_Find(d, hrg)); } IGRAPH_CHECK(markovChainMonteCarlo2(d, num_samples)); d->recordConsensusTree(parents, weights); delete d; RNG_END(); return 0; } static int MCMCEquilibrium_Sample(dendro *d, int num_samples) { // Because moves in the dendrogram space are chosen (Monte // Carlo) so that we sample dendrograms with probability // proportional to their likelihood, a likelihood-proportional // sampling of the dendrogram models would be equivalent to a // uniform sampling of the walk itself. We would still have to // decide how often to sample the walk (at most once every n steps // is recommended) but for simplicity, the code here simply runs the // MCMC itself. To actually compute something over the set of // sampled dendrogram models (in a Bayesian model averaging sense), // you'll need to code that yourself. double dL; bool flag_taken; int sample_num = 0; int t = 1, thresh = 100 * d->g->numNodes(); double ptest = 1.0 / 10.0 / d->g->numNodes(); while (sample_num < num_samples) { d->monteCarloMove(dL, flag_taken, 1.0); if (t > thresh && RNG_UNIF01() < ptest) { sample_num++; d->sampleAdjacencyLikelihoods(); } d->refreshLikelihood(); // TODO: less frequently t++; } return 0; } static int QsortPartition (pblock* array, int left, int right, int index) { pblock p_value, temp; p_value.L = array[index].L; p_value.i = array[index].i; p_value.j = array[index].j; // swap(array[p_value], array[right]) temp.L = array[right].L; temp.i = array[right].i; temp.j = array[right].j; array[right].L = array[index].L; array[right].i = array[index].i; array[right].j = array[index].j; array[index].L = temp.L; array[index].i = temp.i; array[index].j = temp.j; int stored = left; for (int i = left; i < right; i++) { if (array[i].L <= p_value.L) { // swap(array[stored], array[i]) temp.L = array[i].L; temp.i = array[i].i; temp.j = array[i].j; array[i].L = array[stored].L; array[i].i = array[stored].i; array[i].j = array[stored].j; array[stored].L = temp.L; array[stored].i = temp.i; array[stored].j = temp.j; stored++; } } // swap(array[right], array[stored]) temp.L = array[stored].L; temp.i = array[stored].i; temp.j = array[stored].j; array[stored].L = array[right].L; array[stored].i = array[right].i; array[stored].j = array[right].j; array[right].L = temp.L; array[right].i = temp.i; array[right].j = temp.j; return stored; } static void QsortMain (pblock* array, int left, int right) { if (right > left) { int pivot = left; int part = QsortPartition(array, left, right, pivot); QsortMain(array, left, part - 1); QsortMain(array, part + 1, right ); } return; } static int rankCandidatesByProbability(simpleGraph *sg, dendro *d, pblock *br_list, int mk) { int mkk = 0; int n = sg->getNumNodes(); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (sg->getAdjacency(i, j) < 0.5) { double temp = d->g->getAdjacencyAverage(i, j); br_list[mkk].L = temp * (1.0 + RNG_UNIF01() / 1000.0); br_list[mkk].i = i; br_list[mkk].j = j; mkk++; } } } // Sort the candidates by their average probability QsortMain(br_list, 0, mk - 1); return 0; } static int recordPredictions(pblock *br_list, igraph_vector_t *edges, igraph_vector_t *prob, int mk) { IGRAPH_CHECK(igraph_vector_resize(edges, mk * 2)); IGRAPH_CHECK(igraph_vector_resize(prob, mk)); for (int i = mk - 1, idx = 0, idx2 = 0; i >= 0; i--) { VECTOR(*edges)[idx++] = br_list[i].i; VECTOR(*edges)[idx++] = br_list[i].j; VECTOR(*prob)[idx2++] = br_list[i].L; } return 0; } /** * \function igraph_hrg_predict * Predict missing edges in a graph, based on HRG models * * Samples HRG models for a network, and estimated the probability * that an edge was falsely observed as non-existent in the network. * \param graph The input graph. * \param edges The list of missing edges is stored here, the first * two elements are the first edge, the next two the second edge, * etc. * \param prob Vector of probabilies for the existence of missing * edges, in the order corresponding to \c edges. * \param hrg A HRG, it is used as a starting point if \c start is * true. It is also modified during the MCMC sampling. * \param start Logical, whether to start the MCMC from the given HRG. * \param num_samples The number of samples to generate. * \param num_bins Controls the resolution of the edge * probabilities. Higher numbers result higher resolution. * \return Error code. * * Time complexity: TODO. */ int igraph_hrg_predict(const igraph_t *graph, igraph_vector_t *edges, igraph_vector_t *prob, igraph_hrg_t *hrg, igraph_bool_t start, int num_samples, int num_bins) { dendro *d; pblock *br_list; int mk; simpleGraph *sg; if (start && !hrg) { IGRAPH_ERROR("`hrg' must be given is `start' is true", IGRAPH_EINVAL); } RNG_BEGIN(); d = new dendro; IGRAPH_CHECK(igraph_i_hrg_getsimplegraph(graph, d, &sg, num_bins)); mk = sg->getNumNodes() * (sg->getNumNodes() - 1) / 2 - sg->getNumLinks() / 2; br_list = new pblock[mk]; for (int i = 0; i < mk; i++) { br_list[i].L = 0.0; br_list[i].i = -1; br_list[i].j = -1; } if (start) { d->clearDendrograph(); // this has cleared the graph as well.... bug? IGRAPH_CHECK(igraph_i_hrg_getsimplegraph(graph, d, &sg, num_bins)); d->importDendrogramStructure(hrg); } else { if (hrg) { igraph_hrg_resize(hrg, igraph_vcount(graph)); } IGRAPH_CHECK(MCMCEquilibrium_Find(d, hrg)); } IGRAPH_CHECK(MCMCEquilibrium_Sample(d, num_samples)); IGRAPH_CHECK(rankCandidatesByProbability(sg, d, br_list, mk)); IGRAPH_CHECK(recordPredictions(br_list, edges, prob, mk)); delete d; delete sg; delete [] br_list; RNG_END(); return 0; } /** * \function igraph_hrg_create * Create a HRG from an igraph graph. * * \param hrg Pointer to an initialized \ref igraph_hrg_t. The result * is stored here. * \param graph The igraph graph to convert. It must be a directed * binary tree, with n-1 internal and n leaf vertices. The root * vertex must have in-degree zero. * \param prob The vector of probabilities, this is used to label the * internal nodes of the hierarchical random graph. The values * corresponding to the leaves are ignored. * \return Error code. * * Time complexity: O(n), the number of vertices in the tree. */ int igraph_hrg_create(igraph_hrg_t *hrg, const igraph_t *graph, const igraph_vector_t *prob) { int no_of_nodes = igraph_vcount(graph); int no_of_internal = no_of_nodes > 0 ? (no_of_nodes - 1) / 2 : 0; igraph_vector_t deg, idx; int root = 0; int d0 = 0, d1 = 0, d2 = 0; int ii = 0, il = 0; igraph_vector_t neis; igraph_vector_t path; // -------------------------------------------------------- // CHECKS // -------------------------------------------------------- // At least three vertices are required if (no_of_nodes < 3) { IGRAPH_ERROR("HRG tree must have at least three vertices", IGRAPH_EINVAL); } // Prob vector was given if (!prob) { IGRAPH_ERROR("Probability vector must be given for HRG", IGRAPH_EINVAL); } // Length of prob vector if (igraph_vector_size(prob) != no_of_nodes) { IGRAPH_ERROR("HRG probability vector of wrong size", IGRAPH_EINVAL); } // Must be a directed graph if (!igraph_is_directed(graph)) { IGRAPH_ERROR("HRG graph must be directed", IGRAPH_EINVAL); } // Number of nodes must be odd if (no_of_nodes % 2 == 0) { IGRAPH_ERROR("Complete HRG graph must have odd number of vertices", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(°, 0); // Every vertex, except for the root must have in-degree one. IGRAPH_CHECK(igraph_degree(graph, °, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS)); for (int i = 0; i < no_of_nodes; i++) { int d = VECTOR(deg)[i]; switch (d) { case 0: d0++; root = i; break; case 1: d1++; break; default: IGRAPH_ERROR("HRG nodes must have in-degree one, except for the " "root vertex", IGRAPH_EINVAL); } } if (d1 != no_of_nodes - 1 || d0 != 1) { IGRAPH_ERROR("HRG nodes must have in-degree one, except for the " "root vertex", IGRAPH_EINVAL); } // Every internal vertex must have out-degree two, // leaves out-degree zero d0 = d1 = d2 = 0; IGRAPH_CHECK(igraph_degree(graph, °, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); for (int i = 0; i < no_of_nodes; i++) { int d = VECTOR(deg)[i]; switch (d) { case 0: d0++; break; case 2: d2++; break; default: IGRAPH_ERROR("HRG nodes must have out-degree 2 (internal nodes) or " "degree 0 (leaves)", IGRAPH_EINVAL); } } // Number of internal and external nodes is correct // This basically checks that the graph has one component if (d0 != d2 + 1) { IGRAPH_ERROR("HRG degrees are incorrect, maybe multiple components?", IGRAPH_EINVAL); } // -------------------------------------------------------- // Graph is good, do the conversion // -------------------------------------------------------- // Create an index, that maps the root node as first, then // the internal nodes, then the leaf nodes IGRAPH_VECTOR_INIT_FINALLY(&idx, no_of_nodes); VECTOR(idx)[root] = - (ii++) - 1; for (int i = 0; i < no_of_nodes; i++) { int d = VECTOR(deg)[i]; if (i == root) { continue; } if (d == 2) { VECTOR(idx)[i] = - (ii++) - 1; } if (d == 0) { VECTOR(idx)[i] = (il++); } } igraph_hrg_resize(hrg, no_of_internal + 1); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); for (int i = 0; i < no_of_nodes; i++) { int ri = VECTOR(idx)[i]; if (ri >= 0) { continue; } IGRAPH_CHECK(igraph_neighbors(graph, &neis, i, IGRAPH_OUT)); VECTOR(hrg->left )[-ri - 1] = VECTOR(idx)[ (int) VECTOR(neis)[0] ]; VECTOR(hrg->right)[-ri - 1] = VECTOR(idx)[ (int) VECTOR(neis)[1] ]; VECTOR(hrg->prob )[-ri - 1] = VECTOR(*prob)[i]; } // Calculate the number of vertices and edges in each subtree igraph_vector_null(&hrg->edges); igraph_vector_null(&hrg->vertices); IGRAPH_VECTOR_INIT_FINALLY(&path, 0); IGRAPH_CHECK(igraph_vector_push_back(&path, VECTOR(idx)[root])); while (!igraph_vector_empty(&path)) { int ri = igraph_vector_tail(&path); int lc = VECTOR(hrg->left)[-ri - 1]; int rc = VECTOR(hrg->right)[-ri - 1]; if (lc < 0 && VECTOR(hrg->vertices)[-lc - 1] == 0) { // Go left IGRAPH_CHECK(igraph_vector_push_back(&path, lc)); } else if (rc < 0 && VECTOR(hrg->vertices)[-rc - 1] == 0) { // Go right IGRAPH_CHECK(igraph_vector_push_back(&path, rc)); } else { // Subtrees are done, update node and go up VECTOR(hrg->vertices)[-ri - 1] += lc < 0 ? VECTOR(hrg->vertices)[-lc - 1] : 1; VECTOR(hrg->vertices)[-ri - 1] += rc < 0 ? VECTOR(hrg->vertices)[-rc - 1] : 1; VECTOR(hrg->edges)[-ri - 1] += lc < 0 ? VECTOR(hrg->edges)[-lc - 1] + 1 : 1; VECTOR(hrg->edges)[-ri - 1] += rc < 0 ? VECTOR(hrg->edges)[-rc - 1] + 1 : 1; igraph_vector_pop_back(&path); } } igraph_vector_destroy(&path); igraph_vector_destroy(&neis); igraph_vector_destroy(&idx); igraph_vector_destroy(°); IGRAPH_FINALLY_CLEAN(4); return 0; } leidenbase/src/core/connectivity/0000755000176200001440000000000014532173045016606 5ustar liggesusersleidenbase/src/core/connectivity/cohesive_blocks.c0000644000176200001440000005260214447675374022142 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_cohesive_blocks.h" #include "igraph_constructors.h" #include "igraph_dqueue.h" #include "igraph_flow.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_operators.h" #include "igraph_separators.h" #include "igraph_statusbar.h" #include "igraph_structural.h" #include "core/interruption.h" static void igraph_i_cohesive_blocks_free_graphs(igraph_vector_ptr_t *ptr) { long int i, n = igraph_vector_ptr_size(ptr); for (i = 0; i < n; i++) { igraph_t *g = VECTOR(*ptr)[i]; if (g) { igraph_destroy(g); igraph_free(g); } } } static void igraph_i_cohesive_blocks_free_vectors(igraph_vector_ptr_t *ptr) { long int i, n = igraph_vector_ptr_size(ptr); for (i = 0; i < n; i++) { igraph_vector_t *v = VECTOR(*ptr)[i]; if (v) { igraph_vector_destroy(v); igraph_free(v); } } } /* This is kind of a BFS to find the components of the graph, after * deleting the vertices marked in 'excluded'. * These vertices are not put in the BFS queue, but they are added to * all neighboring components. */ static int igraph_i_cb_components(igraph_t *graph, const igraph_vector_bool_t *excluded, igraph_vector_long_t *components, long int *no, /* working area follows */ igraph_vector_long_t *compid, igraph_dqueue_t *Q, igraph_vector_t *neis) { long int no_of_nodes = igraph_vcount(graph); long int i; long int cno = 0; igraph_vector_long_clear(components); igraph_dqueue_clear(Q); IGRAPH_CHECK(igraph_vector_long_resize(compid, no_of_nodes)); igraph_vector_long_null(compid); for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*compid)[i]) { continue; } if (VECTOR(*excluded)[i]) { continue; } IGRAPH_CHECK(igraph_dqueue_push(Q, i)); IGRAPH_CHECK(igraph_vector_long_push_back(components, i)); VECTOR(*compid)[i] = ++cno; while (!igraph_dqueue_empty(Q)) { igraph_integer_t node = (igraph_integer_t) igraph_dqueue_pop(Q); long int j, n; IGRAPH_CHECK(igraph_neighbors(graph, neis, node, IGRAPH_ALL)); n = igraph_vector_size(neis); for (j = 0; j < n; j++) { long int v = (long int) VECTOR(*neis)[j]; if (VECTOR(*excluded)[v]) { if (VECTOR(*compid)[v] != cno) { VECTOR(*compid)[v] = cno; IGRAPH_CHECK(igraph_vector_long_push_back(components, v)); } } else { if (!VECTOR(*compid)[v]) { VECTOR(*compid)[v] = cno; /* could be anything positive */ IGRAPH_CHECK(igraph_vector_long_push_back(components, v)); IGRAPH_CHECK(igraph_dqueue_push(Q, v)); } } } } /* while !igraph_dqueue_empty */ IGRAPH_CHECK(igraph_vector_long_push_back(components, -1)); } /* for ik. Thus a hiearchy of vertex subsets * is found, whith the entire graph G at its root. See the following * reference for details: J. Moody and D. R. White. Structural * cohesion and embeddedness: A hierarchical concept of social * groups. American Sociological Review, 68(1):103--127, Feb 2003. * * This function implements cohesive blocking and * calculates the complete cohesive block hierarchy of a graph. * * \param graph The input graph. It must be undirected and simple. See * \ref igraph_is_simple(). * \param blocks If not a null pointer, then it must be an initialized * vector of pointers and the cohesive blocks are stored here. * Each block is encoded with a numeric vector, that contains the * vertex ids of the block. * \param cohesion If not a null pointer, then it must be an initialized * vector and the cohesion of the blocks is stored here, in the same * order as the blocks in the \p blocks pointer vector. * \param parent If not a null pointer, then it must be an initialized * vector and the block hierarchy is stored here. For each block, the * id (i.e. the position in the \p blocks pointer vector) of its * parent block is stored. For the top block in the hierarchy, * -1 is stored. * \param block_tree If not a null pointer, then it must be a pointer * to an uninitialized graph, and the block hierarchy is stored * here as an igraph graph. The vertex ids correspond to the order * of the blocks in the \p blocks vector. * \return Error code. * * Time complexity: TODO. * * \example examples/simple/cohesive_blocks.c */ int igraph_cohesive_blocks(const igraph_t *graph, igraph_vector_ptr_t *blocks, igraph_vector_t *cohesion, igraph_vector_t *parent, igraph_t *block_tree) { /* Some implementation comments. Everything is relatively straightforward, except, that we need to follow the vertex ids of the various subgraphs, without having to store two-way mappings at each level. The subgraphs can overlap, this complicates things a bit. The 'Q' vector is used as a double ended queue and it contains the subgraphs to work on in the future. Some other vectors are associated with it. 'Qparent' gives the parent graph of a graph in Q. Qmapping gives the mapping of the vertices from the graph to the parent graph. Qcohesion is the vertex connectivity of the graph. Qptr is an integer and points to the next graph to work on. */ igraph_vector_ptr_t Q; igraph_vector_ptr_t Qmapping; igraph_vector_long_t Qparent; igraph_vector_long_t Qcohesion; igraph_vector_bool_t Qcheck; long int Qptr = 0; igraph_integer_t conn; igraph_bool_t is_simple; igraph_t *graph_copy; igraph_vector_ptr_t separators; igraph_vector_t compvertices; igraph_vector_long_t components; igraph_vector_bool_t marked; igraph_vector_long_t compid; igraph_dqueue_t bfsQ; igraph_vector_t neis; if (igraph_is_directed(graph)) { IGRAPH_ERROR("Cohesive blocking only works on undirected graphs", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_is_simple(graph, &is_simple)); if (!is_simple) { IGRAPH_ERROR("Cohesive blocking only works on simple graphs", IGRAPH_EINVAL); } IGRAPH_STATUS("Starting cohesive block calculation.\n", 0); if (blocks) { igraph_vector_ptr_clear(blocks); } if (cohesion) { igraph_vector_clear(cohesion); } if (parent) { igraph_vector_clear(parent); } IGRAPH_CHECK(igraph_vector_ptr_init(&Q, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &Q); IGRAPH_FINALLY(igraph_i_cohesive_blocks_free_graphs, &Q); IGRAPH_CHECK(igraph_vector_ptr_init(&Qmapping, 1)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &Qmapping); IGRAPH_FINALLY(igraph_i_cohesive_blocks_free_vectors, &Qmapping); IGRAPH_CHECK(igraph_vector_long_init(&Qparent, 1)); IGRAPH_FINALLY(igraph_vector_long_destroy, &Qparent); IGRAPH_CHECK(igraph_vector_long_init(&Qcohesion, 1)); IGRAPH_FINALLY(igraph_vector_long_destroy, &Qcohesion); IGRAPH_CHECK(igraph_vector_bool_init(&Qcheck, 1)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &Qcheck); IGRAPH_CHECK(igraph_vector_ptr_init(&separators, 0)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &separators); IGRAPH_VECTOR_INIT_FINALLY(&compvertices, 0); IGRAPH_CHECK(igraph_vector_bool_init(&marked, 0)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &marked); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_dqueue_init(&bfsQ, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &bfsQ); IGRAPH_CHECK(igraph_vector_long_init(&compid, 0)); IGRAPH_FINALLY(igraph_vector_long_destroy, &compid); IGRAPH_CHECK(igraph_vector_long_init(&components, 0)); IGRAPH_FINALLY(igraph_vector_long_destroy, &components); /* Put the input graph in the queue */ graph_copy = IGRAPH_CALLOC(1, igraph_t); if (!graph_copy) { IGRAPH_ERROR("Cannot do cohesive blocking", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_copy(graph_copy, graph)); VECTOR(Q)[0] = graph_copy; VECTOR(Qmapping)[0] = NULL; /* Identity mapping */ VECTOR(Qparent)[0] = -1; /* Has no parent */ IGRAPH_CHECK(igraph_vertex_connectivity(graph, &conn, /*checks=*/ 1)); VECTOR(Qcohesion)[0] = conn; VECTOR(Qcheck)[0] = 0; /* Then work until the queue is empty */ while (Qptr < igraph_vector_ptr_size(&Q)) { igraph_t *mygraph = VECTOR(Q)[Qptr]; igraph_bool_t mycheck = VECTOR(Qcheck)[Qptr]; long int mynodes = igraph_vcount(mygraph); long int i, nsep; long int no, kept = 0; long int cptr = 0; long int nsepv = 0; igraph_bool_t addedsep = 0; IGRAPH_STATUSF(("Candidate %li: %li vertices,", 0, Qptr, mynodes)); IGRAPH_ALLOW_INTERRUPTION(); /* Get the separators */ IGRAPH_CHECK(igraph_minimum_size_separators(mygraph, &separators)); IGRAPH_FINALLY(igraph_i_cohesive_blocks_free_vectors, &separators); nsep = igraph_vector_ptr_size(&separators); IGRAPH_STATUSF((" %li separators,", 0, nsep)); /* Remove them from the graph, also mark them */ IGRAPH_CHECK(igraph_vector_bool_resize(&marked, mynodes)); igraph_vector_bool_null(&marked); for (i = 0; i < nsep; i++) { igraph_vector_t *v = VECTOR(separators)[i]; long int j, n = igraph_vector_size(v); for (j = 0; j < n; j++) { long int vv = (long int) VECTOR(*v)[j]; if (!VECTOR(marked)[vv]) { nsepv++; VECTOR(marked)[vv] = 1; } } } /* Find the connected components, omitting the separator vertices, but including the neighboring separator vertices */ IGRAPH_CHECK(igraph_i_cb_components(mygraph, &marked, &components, &no, &compid, &bfsQ, &neis)); /* Add the separator vertices themselves, as another component, but only if there is at least one vertex not included in any separator. */ if (nsepv != mynodes) { addedsep = 1; for (i = 0; i < mynodes; i++) { if (VECTOR(marked)[i]) { IGRAPH_CHECK(igraph_vector_long_push_back(&components, i)); } } IGRAPH_CHECK(igraph_vector_long_push_back(&components, -1)); no++; } IGRAPH_STATUSF((" %li new candidates,", 0, no)); for (i = 0; i < no; i++) { igraph_vector_t *newmapping; igraph_t *newgraph; igraph_integer_t maxdeg; igraph_vector_clear(&compvertices); while (1) { long int v = VECTOR(components)[cptr++]; if (v < 0) { break; } IGRAPH_CHECK(igraph_vector_push_back(&compvertices, v)); } newmapping = IGRAPH_CALLOC(1, igraph_vector_t); if (!newmapping) { IGRAPH_ERROR("Cannot do cohesive blocking", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newmapping); IGRAPH_VECTOR_INIT_FINALLY(newmapping, 0); newgraph = IGRAPH_CALLOC(1, igraph_t); if (!newgraph) { IGRAPH_ERROR("Cannot do cohesive blocking", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newgraph); IGRAPH_CHECK(igraph_induced_subgraph_map(mygraph, newgraph, igraph_vss_vector(&compvertices), IGRAPH_SUBGRAPH_AUTO, /*map=*/ 0, /*invmap=*/ newmapping)); IGRAPH_FINALLY(igraph_destroy, newgraph); IGRAPH_CHECK(igraph_maxdegree(newgraph, &maxdeg, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS)); if (maxdeg > VECTOR(Qcohesion)[Qptr]) { igraph_integer_t newconn; kept++; IGRAPH_CHECK(igraph_vector_ptr_push_back(&Q, newgraph)); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_vector_ptr_push_back(&Qmapping, newmapping)); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_vertex_connectivity(newgraph, &newconn, /*checks=*/ 1)); IGRAPH_CHECK(igraph_vector_long_push_back(&Qcohesion, newconn)); IGRAPH_CHECK(igraph_vector_long_push_back(&Qparent, Qptr)); IGRAPH_CHECK(igraph_vector_bool_push_back(&Qcheck, mycheck || addedsep)); } else { igraph_destroy(newgraph); igraph_free(newgraph); igraph_vector_destroy(newmapping); igraph_free(newmapping); IGRAPH_FINALLY_CLEAN(4); } } IGRAPH_STATUSF((" keeping %li.\n", 0, kept)); igraph_destroy(mygraph); igraph_free(mygraph); VECTOR(Q)[Qptr] = 0; igraph_i_cohesive_blocks_free_vectors(&separators); IGRAPH_FINALLY_CLEAN(1); Qptr++; } igraph_vector_long_destroy(&components); igraph_vector_long_destroy(&compid); igraph_dqueue_destroy(&bfsQ); igraph_vector_destroy(&neis); igraph_vector_bool_destroy(&marked); igraph_vector_destroy(&compvertices); igraph_vector_ptr_destroy(&separators); IGRAPH_FINALLY_CLEAN(7); if (blocks || cohesion || parent || block_tree) { igraph_integer_t noblocks = (igraph_integer_t) Qptr, badblocks = 0; igraph_vector_bool_t removed; long int i, resptr = 0; igraph_vector_long_t rewritemap; IGRAPH_CHECK(igraph_vector_bool_init(&removed, noblocks)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &removed); IGRAPH_CHECK(igraph_vector_long_init(&rewritemap, noblocks)); IGRAPH_FINALLY(igraph_vector_long_destroy, &rewritemap); for (i = 1; i < noblocks; i++) { long int p = VECTOR(Qparent)[i]; while (VECTOR(removed)[p]) { p = VECTOR(Qparent)[p]; } if (VECTOR(Qcohesion)[p] >= VECTOR(Qcohesion)[i]) { VECTOR(removed)[i] = 1; badblocks++; } } /* Rewrite the mappings */ for (i = 1; i < Qptr; i++) { long int p = VECTOR(Qparent)[i]; igraph_vector_t *mapping = VECTOR(Qmapping)[i]; igraph_vector_t *pmapping = VECTOR(Qmapping)[p]; long int j, n = igraph_vector_size(mapping); if (!pmapping) { continue; } for (j = 0; j < n; j++) { long int v = (long int) VECTOR(*mapping)[j]; VECTOR(*mapping)[j] = VECTOR(*pmapping)[v]; } } /* Because we also put the separator vertices in the queue, it is not ensured that the found blocks are not subsets of each other. We check this now. */ for (i = 1; i < noblocks; i++) { long int j, ic; igraph_vector_t *ivec; if (!VECTOR(Qcheck)[i] || VECTOR(removed)[i]) { continue; } ivec = VECTOR(Qmapping)[i]; ic = VECTOR(Qcohesion)[i]; for (j = 1; j < noblocks; j++) { igraph_vector_t *jvec; long int jc; if (j == i || !VECTOR(Qcheck)[j] || VECTOR(removed)[j]) { continue; } jvec = VECTOR(Qmapping)[j]; jc = VECTOR(Qcohesion)[j]; if (igraph_i_cb_isin(ivec, jvec) && jc >= ic) { badblocks++; VECTOR(removed)[i] = 1; break; } } } noblocks -= badblocks; if (blocks) { IGRAPH_CHECK(igraph_vector_ptr_resize(blocks, noblocks)); } if (cohesion) { IGRAPH_CHECK(igraph_vector_resize(cohesion, noblocks)); } if (parent) { IGRAPH_CHECK(igraph_vector_resize(parent, noblocks)); } for (i = 0; i < Qptr; i++) { if (VECTOR(removed)[i]) { IGRAPH_STATUSF(("Candidate %li ignored.\n", 0, i)); continue; } else { IGRAPH_STATUSF(("Candidate %li is a cohesive (sub)block\n", 0, i)); } VECTOR(rewritemap)[i] = resptr; if (cohesion) { VECTOR(*cohesion)[resptr] = VECTOR(Qcohesion)[i]; } if (parent || block_tree) { long int p = VECTOR(Qparent)[i]; while (p >= 0 && VECTOR(removed)[p]) { p = VECTOR(Qparent)[p]; } if (p >= 0) { p = VECTOR(rewritemap)[p]; } VECTOR(Qparent)[i] = p; if (parent) { VECTOR(*parent)[resptr] = p; } } if (blocks) { VECTOR(*blocks)[resptr] = VECTOR(Qmapping)[i]; VECTOR(Qmapping)[i] = 0; } resptr++; } /* Plus the original graph */ if (blocks) { igraph_vector_t *orig = IGRAPH_CALLOC(1, igraph_vector_t); if (!orig) { IGRAPH_ERROR("Cannot do cohesive blocking", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, orig); IGRAPH_CHECK(igraph_vector_init_seq(orig, 0, igraph_vcount(graph) - 1)); VECTOR(*blocks)[0] = orig; IGRAPH_FINALLY_CLEAN(1); } if (block_tree) { igraph_vector_t edges; long int eptr = 0; IGRAPH_VECTOR_INIT_FINALLY(&edges, noblocks * 2 - 2); for (i = 1; i < Qptr; i++) { if (VECTOR(removed)[i]) { continue; } VECTOR(edges)[eptr++] = VECTOR(Qparent)[i]; VECTOR(edges)[eptr++] = VECTOR(rewritemap)[i]; } IGRAPH_CHECK(igraph_create(block_tree, &edges, noblocks, IGRAPH_DIRECTED)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_long_destroy(&rewritemap); igraph_vector_bool_destroy(&removed); IGRAPH_FINALLY_CLEAN(2); } igraph_vector_bool_destroy(&Qcheck); igraph_vector_long_destroy(&Qcohesion); igraph_vector_long_destroy(&Qparent); igraph_i_cohesive_blocks_free_vectors(&Qmapping); IGRAPH_FINALLY_CLEAN(4); igraph_vector_ptr_destroy(&Qmapping); igraph_vector_ptr_destroy(&Q); IGRAPH_FINALLY_CLEAN(3); /* + the elements of Q, they were already destroyed */ IGRAPH_STATUS("Cohesive blocking done.\n", 0); return 0; } leidenbase/src/core/connectivity/components.c0000644000176200001440000015021114447675374021160 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_components.h" #include "igraph_adjlist.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_operators.h" #include "igraph_progress.h" #include "igraph_stack.h" #include "igraph_structural.h" #include "igraph_vector.h" #include "core/interruption.h" #include "operators/subgraph.h" #include static int igraph_i_clusters_weak(const igraph_t *graph, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t *no); static int igraph_i_clusters_strong(const igraph_t *graph, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t *no); /** * \ingroup structural * \function igraph_clusters * \brief Calculates the (weakly or strongly) connected components in a graph. * * \param graph The graph object to analyze. * \param membership First half of the result will be stored here. For * every vertex the id of its component is given. The vector * has to be preinitialized and will be resized. Alternatively * this argument can be \c NULL, in which case it is ignored. * \param csize The second half of the result. For every component it * gives its size, the order is defined by the component ids. * The vector has to be preinitialized and will be resized. * Alternatively this argument can be \c NULL, in which * case it is ignored. * \param no Pointer to an integer, if not \c NULL then the number of * clusters will be stored here. * \param mode For directed graph this specifies whether to calculate * weakly or strongly connected components. Possible values: * \c IGRAPH_WEAK, * \c IGRAPH_STRONG. This argument is * ignored for undirected graphs. * \return Error code: * \c IGRAPH_EINVAL: invalid mode argument. * * Time complexity: O(|V|+|E|), * |V| and * |E| are the number of vertices and * edges in the graph. */ int igraph_clusters(const igraph_t *graph, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t *no, igraph_connectedness_t mode) { if (mode == IGRAPH_WEAK || !igraph_is_directed(graph)) { return igraph_i_clusters_weak(graph, membership, csize, no); } else if (mode == IGRAPH_STRONG) { return igraph_i_clusters_strong(graph, membership, csize, no); } IGRAPH_ERROR("Cannot calculate clusters", IGRAPH_EINVAL); } static int igraph_i_clusters_weak(const igraph_t *graph, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t *no) { long int no_of_nodes = igraph_vcount(graph); char *already_added; long int first_node, act_cluster_size = 0, no_of_clusters = 1; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; long int i; igraph_vector_t neis = IGRAPH_VECTOR_NULL; already_added = IGRAPH_CALLOC(no_of_nodes, char); if (already_added == 0) { IGRAPH_ERROR("Cannot calculate clusters", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_DQUEUE_INIT_FINALLY(&q, no_of_nodes > 100000 ? 10000 : no_of_nodes / 10); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); /* Memory for result, csize is dynamically allocated */ if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); } if (csize) { igraph_vector_clear(csize); } /* The algorithm */ for (first_node = 0; first_node < no_of_nodes; ++first_node) { if (already_added[first_node] == 1) { continue; } IGRAPH_ALLOW_INTERRUPTION(); already_added[first_node] = 1; act_cluster_size = 1; if (membership) { VECTOR(*membership)[first_node] = no_of_clusters - 1; } IGRAPH_CHECK(igraph_dqueue_push(&q, first_node)); while ( !igraph_dqueue_empty(&q) ) { long int act_node = (long int) igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) act_node, IGRAPH_ALL)); for (i = 0; i < igraph_vector_size(&neis); i++) { long int neighbor = (long int) VECTOR(neis)[i]; if (already_added[neighbor] == 1) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); already_added[neighbor] = 1; act_cluster_size++; if (membership) { VECTOR(*membership)[neighbor] = no_of_clusters - 1; } } } no_of_clusters++; if (csize) { IGRAPH_CHECK(igraph_vector_push_back(csize, act_cluster_size)); } } /* Cleaning up */ if (no) { *no = (igraph_integer_t) no_of_clusters - 1; } IGRAPH_FREE(already_added); igraph_dqueue_destroy(&q); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(3); return 0; } static int igraph_i_clusters_strong(const igraph_t *graph, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t *no) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t next_nei = IGRAPH_VECTOR_NULL; long int i, n, num_seen; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; long int no_of_clusters = 1; long int act_cluster_size; igraph_vector_t out = IGRAPH_VECTOR_NULL; const igraph_vector_int_t* tmp; igraph_adjlist_t adjlist; /* The result */ IGRAPH_VECTOR_INIT_FINALLY(&next_nei, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&out, 0); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); } IGRAPH_CHECK(igraph_vector_reserve(&out, no_of_nodes)); igraph_vector_null(&out); if (csize) { igraph_vector_clear(csize); } IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); num_seen = 0; for (i = 0; i < no_of_nodes; i++) { IGRAPH_ALLOW_INTERRUPTION(); tmp = igraph_adjlist_get(&adjlist, i); if (VECTOR(next_nei)[i] > igraph_vector_int_size(tmp)) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, i)); while (!igraph_dqueue_empty(&q)) { long int act_node = (long int) igraph_dqueue_back(&q); tmp = igraph_adjlist_get(&adjlist, act_node); if (VECTOR(next_nei)[act_node] == 0) { /* this is the first time we've met this vertex */ VECTOR(next_nei)[act_node]++; } else if (VECTOR(next_nei)[act_node] <= igraph_vector_int_size(tmp)) { /* we've already met this vertex but it has more children */ long int neighbor = (long int) VECTOR(*tmp)[(long int) VECTOR(next_nei)[act_node] - 1]; if (VECTOR(next_nei)[neighbor] == 0) { IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); } VECTOR(next_nei)[act_node]++; } else { /* we've met this vertex and it has no more children */ IGRAPH_CHECK(igraph_vector_push_back(&out, act_node)); igraph_dqueue_pop_back(&q); num_seen++; if (num_seen % 10000 == 0) { /* time to report progress and allow the user to interrupt */ IGRAPH_PROGRESS("Strongly connected components: ", num_seen * 50.0 / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); } } } /* while q */ } /* for */ IGRAPH_PROGRESS("Strongly connected components: ", 50.0, NULL); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); /* OK, we've the 'out' values for the nodes, let's use them in decreasing order with the help of a heap */ igraph_vector_null(&next_nei); /* mark already added vertices */ num_seen = 0; while (!igraph_vector_empty(&out)) { long int grandfather = (long int) igraph_vector_pop_back(&out); if (VECTOR(next_nei)[grandfather] != 0) { continue; } VECTOR(next_nei)[grandfather] = 1; act_cluster_size = 1; if (membership) { VECTOR(*membership)[grandfather] = no_of_clusters - 1; } IGRAPH_CHECK(igraph_dqueue_push(&q, grandfather)); num_seen++; if (num_seen % 10000 == 0) { /* time to report progress and allow the user to interrupt */ IGRAPH_PROGRESS("Strongly connected components: ", 50.0 + num_seen * 50.0 / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); } while (!igraph_dqueue_empty(&q)) { long int act_node = (long int) igraph_dqueue_pop_back(&q); tmp = igraph_adjlist_get(&adjlist, act_node); n = igraph_vector_int_size(tmp); for (i = 0; i < n; i++) { long int neighbor = (long int) VECTOR(*tmp)[i]; if (VECTOR(next_nei)[neighbor] != 0) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); VECTOR(next_nei)[neighbor] = 1; act_cluster_size++; if (membership) { VECTOR(*membership)[neighbor] = no_of_clusters - 1; } num_seen++; if (num_seen % 10000 == 0) { /* time to report progress and allow the user to interrupt */ IGRAPH_PROGRESS("Strongly connected components: ", 50.0 + num_seen * 50.0 / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); } } } no_of_clusters++; if (csize) { IGRAPH_CHECK(igraph_vector_push_back(csize, act_cluster_size)); } } IGRAPH_PROGRESS("Strongly connected components: ", 100.0, NULL); if (no) { *no = (igraph_integer_t) no_of_clusters - 1; } /* Clean up, return */ igraph_adjlist_destroy(&adjlist); igraph_vector_destroy(&out); igraph_dqueue_destroy(&q); igraph_vector_destroy(&next_nei); IGRAPH_FINALLY_CLEAN(4); return 0; } static int igraph_is_connected_weak(const igraph_t *graph, igraph_bool_t *res); /** * \ingroup structural * \function igraph_is_connected * \brief Decides whether the graph is (weakly or strongly) connected. * * A graph is considered connected when any of its vertices is reachable * from any other. A directed graph with this property is called * \em strongly connected. A directed graph that would be connected when * ignoring the directions of its edges is called \em weakly connected. * * * A graph with zero vertices (i.e. the null graph) is \em not connected by * definition. This behaviour changed in igraph 0.9; earlier versions assumed * that the null graph is connected. See the following issue on Github for the * argument that led us to change the definition: * https://github.com/igraph/igraph/issues/1539 * * \param graph The graph object to analyze. * \param res Pointer to a logical variable, the result will be stored * here. * \param mode For a directed graph this specifies whether to calculate * weak or strong connectedness. Possible values: * \c IGRAPH_WEAK, * \c IGRAPH_STRONG. This argument is * ignored for undirected graphs. * \return Error code: * \c IGRAPH_EINVAL: invalid mode argument. * * Time complexity: O(|V|+|E|), the * number of vertices * plus the number of edges in the graph. */ int igraph_is_connected(const igraph_t *graph, igraph_bool_t *res, igraph_connectedness_t mode) { long int no_of_nodes = igraph_vcount(graph); if (no_of_nodes == 0) { /* Changed in igraph 0.9; see https://github.com/igraph/igraph/issues/1539 * for the reasoning behind the change */ *res = 0; return IGRAPH_SUCCESS; } if (no_of_nodes == 1) { *res = 1; return IGRAPH_SUCCESS; } if (mode == IGRAPH_WEAK || !igraph_is_directed(graph)) { return igraph_is_connected_weak(graph, res); } else if (mode == IGRAPH_STRONG) { int retval; igraph_integer_t no; /* A strongly connected graph has at least as many edges as vertices, * except for the singleton graph, which is handled above. */ if (igraph_ecount(graph) < no_of_nodes) { *res = 0; return IGRAPH_SUCCESS; } retval = igraph_i_clusters_strong(graph, NULL, NULL, &no); *res = (no == 1); return retval; } IGRAPH_ERROR("Invalid connectedness mode.", IGRAPH_EINVAL); } static int igraph_is_connected_weak(const igraph_t *graph, igraph_bool_t *res) { long int no_of_nodes = igraph_vcount(graph), no_of_edges = igraph_ecount(graph); long int added_count; char *already_added; igraph_vector_t neis = IGRAPH_VECTOR_NULL; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; /* By convention, the null graph is not considered connected. * See https://github.com/igraph/igraph/issues/1538 */ if (no_of_nodes == 0) { *res = 0; return IGRAPH_SUCCESS; } /* A connected graph has at least |V| - 1 edges. */ if (no_of_edges < no_of_nodes - 1) { *res = 0; return IGRAPH_SUCCESS; } already_added = IGRAPH_CALLOC(no_of_nodes, char); if (already_added == 0) { IGRAPH_ERROR("Weak connectedness check failed.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_DQUEUE_INIT_FINALLY(&q, 10); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); /* Try to find at least two clusters */ already_added[0] = 1; IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); added_count = 1; while ( !igraph_dqueue_empty(&q)) { IGRAPH_ALLOW_INTERRUPTION(); long int actnode = (long int) igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) actnode, IGRAPH_ALL)); long int nei_count = igraph_vector_size(&neis); for (long int i = 0; i < nei_count; i++) { long int neighbor = (long int) VECTOR(neis)[i]; if (already_added[neighbor]) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); added_count++; already_added[neighbor] = 1; if (added_count == no_of_nodes) { /* We have already reached all nodes: the graph is connected. * We can stop the traversal now. */ igraph_dqueue_clear(&q); break; } } } /* Connected? */ *res = (added_count == no_of_nodes); IGRAPH_FREE(already_added); igraph_dqueue_destroy(&q); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /** * \function igraph_decompose_destroy * \brief Free the memory allocated by \ref igraph_decompose(). * * This function destroys and frees all igraph_t * objects held in \p complist. However, it does not destroy * \p complist itself, as it was not allocated by \ref igraph_decompose(). * Use \ref igraph_vector_ptr_destroy() to destroy \p complist. * * \param complist The list of graph components, as returned by * \ref igraph_decompose(). * * Time complexity: O(c), c is the number of components. */ void igraph_decompose_destroy(igraph_vector_ptr_t *complist) { long int i; for (i = 0; i < igraph_vector_ptr_size(complist); i++) { if (VECTOR(*complist)[i] != 0) { igraph_destroy(VECTOR(*complist)[i]); igraph_free(VECTOR(*complist)[i]); } } } static int igraph_i_decompose_weak(const igraph_t *graph, igraph_vector_ptr_t *components, long int maxcompno, long int minelements); static int igraph_i_decompose_strong(const igraph_t *graph, igraph_vector_ptr_t *components, long int maxcompno, long int minelements); /** * \function igraph_decompose * \brief Decompose a graph into connected components. * * Create separate graph for each component of a graph. Note that the * vertex ids in the new graphs will be different than in the original * graph. (Except if there is only one component in the original graph.) * * \param graph The original graph. * \param components This pointer vector will contain pointers to the * subcomponent graphs. It should be initialized before calling this * function and will be resized to hold the graphs. Don't forget to * call \ref igraph_destroy() and \ref igraph_free() on the elements of * this pointer vector to free unneeded memory. Alternatively, you can * simply call \ref igraph_decompose_destroy() that does this for you. * \param mode Either \c IGRAPH_WEAK or \c IGRAPH_STRONG for weakly * and strongly connected components respectively. * \param maxcompno The maximum number of components to return. The * first \p maxcompno components will be returned (which hold at * least \p minelements vertices, see the next parameter), the * others will be ignored. Supply -1 here if you don't want to limit * the number of components. * \param minelements The minimum number of vertices a component * should contain in order to place it in the \p components * vector. Eg. supply 2 here to ignore isolated vertices. * \return Error code, \c IGRAPH_ENOMEM if there is not enough memory * to perform the operation. * * Added in version 0.2. * * Time complexity: O(|V|+|E|), the number of vertices plus the number * of edges. * * \example examples/simple/igraph_decompose.c */ int igraph_decompose(const igraph_t *graph, igraph_vector_ptr_t *components, igraph_connectedness_t mode, long int maxcompno, long int minelements) { if (mode == IGRAPH_WEAK || !igraph_is_directed(graph)) { return igraph_i_decompose_weak(graph, components, maxcompno, minelements); } else if (mode == IGRAPH_STRONG) { return igraph_i_decompose_strong(graph, components, maxcompno, minelements); } IGRAPH_ERROR("Cannot decompose graph", IGRAPH_EINVAL); } static int igraph_i_decompose_weak(const igraph_t *graph, igraph_vector_ptr_t *components, long int maxcompno, long int minelements) { long int actstart; long int no_of_nodes = igraph_vcount(graph); long int resco = 0; /* number of graphs created so far */ char *already_added; igraph_dqueue_t q; igraph_vector_t verts; igraph_vector_t neis; igraph_vector_t vids_old2new; long int i; igraph_t *newg; if (maxcompno < 0) { maxcompno = LONG_MAX; } igraph_vector_ptr_clear(components); IGRAPH_FINALLY(igraph_decompose_destroy, components); /* already_added keeps track of what nodes made it into a graph already */ already_added = IGRAPH_CALLOC(no_of_nodes, char); if (already_added == 0) { IGRAPH_ERROR("Cannot decompose graph", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_CHECK(igraph_dqueue_init(&q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &q); IGRAPH_VECTOR_INIT_FINALLY(&verts, 0); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_INIT_FINALLY(&vids_old2new, no_of_nodes); /* vids_old2new would have been created internally in igraph_induced_subgraph(), but it is slow if the graph is large and consists of many small components, so we create it once here and then re-use it */ /* add a node and its neighbors at once, recursively then switch to next node that has not been added already */ for (actstart = 0; resco < maxcompno && actstart < no_of_nodes; actstart++) { if (already_added[actstart]) { continue; } IGRAPH_ALLOW_INTERRUPTION(); igraph_vector_clear(&verts); /* add the node itself */ already_added[actstart] = 1; IGRAPH_CHECK(igraph_vector_push_back(&verts, actstart)); IGRAPH_CHECK(igraph_dqueue_push(&q, actstart)); /* add the neighbors, recursively */ while (!igraph_dqueue_empty(&q) ) { /* pop from the queue of this component */ long int actvert = (long int) igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) actvert, IGRAPH_ALL)); /* iterate over the neighbors */ for (i = 0; i < igraph_vector_size(&neis); i++) { long int neighbor = (long int) VECTOR(neis)[i]; if (already_added[neighbor] == 1) { continue; } /* add neighbor */ already_added[neighbor] = 1; /* recursion: append neighbor to the queues */ IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_vector_push_back(&verts, neighbor)); } } /* ok, we have a component */ if (igraph_vector_size(&verts) < minelements) { continue; } newg = IGRAPH_CALLOC(1, igraph_t); if (newg == 0) { IGRAPH_ERROR("Cannot decompose graph", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_ptr_push_back(components, newg)); IGRAPH_CHECK(igraph_i_induced_subgraph_map( graph, newg, igraph_vss_vector(&verts), IGRAPH_SUBGRAPH_AUTO, &vids_old2new, /* invmap = */ 0, /* map_is_prepared = */ 1 )); resco++; /* vids_old2new does not have to be cleaned up here; since we are doing * weak decomposition, each vertex will appear in only one of the * connected components so we won't ever touch an item in vids_old2new * if it was already set to a non-zero value in a previous component */ } /* for actstart++ */ igraph_vector_destroy(&vids_old2new); igraph_vector_destroy(&neis); igraph_vector_destroy(&verts); igraph_dqueue_destroy(&q); IGRAPH_FREE(already_added); IGRAPH_FINALLY_CLEAN(6); /* + components */ return 0; } static int igraph_i_decompose_strong(const igraph_t *graph, igraph_vector_ptr_t *components, long int maxcompno, long int minelements) { long int no_of_nodes = igraph_vcount(graph); /* this is a heap used twice for checking what nodes have * been counted already */ igraph_vector_t next_nei = IGRAPH_VECTOR_NULL; long int i, n, num_seen; igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; long int no_of_clusters = 0; long int act_cluster_size; igraph_vector_t out = IGRAPH_VECTOR_NULL; const igraph_vector_int_t* tmp; igraph_adjlist_t adjlist; igraph_vector_t verts; igraph_vector_t vids_old2new; igraph_t *newg; if (maxcompno < 0) { maxcompno = LONG_MAX; } igraph_vector_ptr_clear(components); IGRAPH_FINALLY(igraph_decompose_destroy, components); /* The result */ IGRAPH_VECTOR_INIT_FINALLY(&vids_old2new, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&verts, 0); IGRAPH_VECTOR_INIT_FINALLY(&next_nei, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&out, 0); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_vector_reserve(&out, no_of_nodes)); igraph_vector_null(&out); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); /* vids_old2new would have been created internally in igraph_induced_subgraph(), but it is slow if the graph is large and consists of many small components, so we create it once here and then re-use it */ /* number of components seen */ num_seen = 0; /* populate the 'out' vector by browsing a node and following up all its neighbors recursively, then switching to the next unassigned node */ for (i = 0; i < no_of_nodes; i++) { IGRAPH_ALLOW_INTERRUPTION(); /* get all the 'out' neighbors of this node * NOTE: next_nei is initialized [0, 0, ...] */ tmp = igraph_adjlist_get(&adjlist, i); if (VECTOR(next_nei)[i] > igraph_vector_int_size(tmp)) { continue; } /* add this node to the queue for this component */ IGRAPH_CHECK(igraph_dqueue_push(&q, i)); /* consume the tree from this node ("root") recursively * until there is no more */ while (!igraph_dqueue_empty(&q)) { /* this looks up but does NOT consume the queue */ long int act_node = (long int) igraph_dqueue_back(&q); /* get all neighbors of this node */ tmp = igraph_adjlist_get(&adjlist, act_node); if (VECTOR(next_nei)[act_node] == 0) { /* this is the first time we've met this vertex, * because next_nei is initialized [0, 0, ...] */ VECTOR(next_nei)[act_node]++; /* back to the queue, same vertex is up again */ } else if (VECTOR(next_nei)[act_node] <= igraph_vector_int_size(tmp)) { /* we've already met this vertex but it has more children */ long int neighbor = (long int) VECTOR(*tmp)[(long int) VECTOR(next_nei)[act_node] - 1]; if (VECTOR(next_nei)[neighbor] == 0) { /* add the root of the other children to the queue */ IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); } VECTOR(next_nei)[act_node]++; } else { /* we've met this vertex and it has no more children */ IGRAPH_CHECK(igraph_vector_push_back(&out, act_node)); /* this consumes the queue, since there's nowhere to go */ igraph_dqueue_pop_back(&q); num_seen++; if (num_seen % 10000 == 0) { /* time to report progress and allow the user to interrupt */ IGRAPH_PROGRESS("Strongly connected components: ", num_seen * 50.0 / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); } } } /* while q */ } /* for */ IGRAPH_PROGRESS("Strongly connected components: ", 50.0, NULL); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); /* OK, we've the 'out' values for the nodes, let's use them in * decreasing order with the help of the next_nei heap */ igraph_vector_null(&next_nei); /* mark already added vertices */ /* number of components built */ num_seen = 0; while (!igraph_vector_empty(&out) && no_of_clusters < maxcompno) { /* consume the vector from the last element */ long int grandfather = (long int) igraph_vector_pop_back(&out); /* been here, done that * NOTE: next_nei is initialized as [0, 0, ...] */ if (VECTOR(next_nei)[grandfather] != 0) { continue; } /* collect all the members of this component */ igraph_vector_clear(&verts); /* this node is gone for any future components */ VECTOR(next_nei)[grandfather] = 1; act_cluster_size = 1; /* add to component */ IGRAPH_CHECK(igraph_vector_push_back(&verts, grandfather)); IGRAPH_CHECK(igraph_dqueue_push(&q, grandfather)); num_seen++; if (num_seen % 10000 == 0) { /* time to report progress and allow the user to interrupt */ IGRAPH_PROGRESS("Strongly connected components: ", 50.0 + num_seen * 50.0 / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); } while (!igraph_dqueue_empty(&q)) { /* consume the queue from this node */ long int act_node = (long int) igraph_dqueue_pop_back(&q); tmp = igraph_adjlist_get(&adjlist, act_node); n = igraph_vector_int_size(tmp); for (i = 0; i < n; i++) { long int neighbor = (long int) VECTOR(*tmp)[i]; if (VECTOR(next_nei)[neighbor] != 0) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); VECTOR(next_nei)[neighbor] = 1; act_cluster_size++; /* add to component */ IGRAPH_CHECK(igraph_vector_push_back(&verts, neighbor)); num_seen++; if (num_seen % 10000 == 0) { /* time to report progress and allow the user to interrupt */ IGRAPH_PROGRESS("Strongly connected components: ", 50.0 + num_seen * 50.0 / no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); } } } /* ok, we have a component */ if (igraph_vector_size(&verts) < minelements) { continue; } newg = IGRAPH_CALLOC(1, igraph_t); if (newg == 0) { IGRAPH_ERROR("Cannot decompose graph", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_ptr_push_back(components, newg)); IGRAPH_CHECK(igraph_i_induced_subgraph_map( graph, newg, igraph_vss_vector(&verts), IGRAPH_SUBGRAPH_AUTO, &vids_old2new, /* invmap = */ 0, /* map_is_prepared = */ 1 )); /* vids_old2new has to be cleaned up here because a vertex may appear * in multiple strongly connected components. Simply calling * igraph_vector_fill() would be an O(n) operation where n is the number * of vertices in the large graph so we cannot do that; we have to * iterate over 'verts' instead */ n = igraph_vector_size(&verts); for (i = 0; i < n; i++) { VECTOR(vids_old2new)[(igraph_integer_t) VECTOR(verts)[i]] = 0; } no_of_clusters++; } IGRAPH_PROGRESS("Strongly connected components: ", 100.0, NULL); /* Clean up, return */ igraph_vector_destroy(&vids_old2new); igraph_vector_destroy(&verts); igraph_adjlist_destroy(&adjlist); igraph_vector_destroy(&out); igraph_dqueue_destroy(&q); igraph_vector_destroy(&next_nei); IGRAPH_FINALLY_CLEAN(7); /* + components */ return 0; } /** * \function igraph_articulation_points * Find the articulation points in a graph. * * A vertex is an articulation point if its removal increases * the number of connected components in the graph. * \param graph The input graph. * \param res Pointer to an initialized vector, the * articulation points will be stored here. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and edges. * * \sa \ref igraph_biconnected_components(), \ref igraph_clusters(), \ref igraph_bridges() */ int igraph_articulation_points(const igraph_t *graph, igraph_vector_t *res) { igraph_integer_t no; return igraph_biconnected_components(graph, &no, 0, 0, 0, res); } void igraph_i_free_vectorlist(igraph_vector_ptr_t *list); void igraph_i_free_vectorlist(igraph_vector_ptr_t *list) { long int i, n = igraph_vector_ptr_size(list); for (i = 0; i < n; i++) { igraph_vector_t *v = VECTOR(*list)[i]; if (v) { igraph_vector_destroy(v); IGRAPH_FREE(v); } } igraph_vector_ptr_destroy(list); } /** * \function igraph_biconnected_components * Calculate biconnected components * * A graph is biconnected if the removal of any single vertex (and * its incident edges) does not disconnect it. * * * A biconnected component of a graph is a maximal biconnected * subgraph of it. The biconnected components of a graph can be given * by the partition of its edges: every edge is a member of exactly * one biconnected component. Note that this is not true for * vertices: the same vertex can be part of many biconnected * components. * * * Somewhat arbitrarily, igraph does not consider components containing * a single vertex only as being biconnected. Isolated vertices will * not be part of any of the biconnected components. * * \param graph The input graph. * \param no The number of biconnected components will be stored here. * \param tree_edges If not a NULL pointer, then the found components * are stored here, in a list of vectors. Every vector in the list * is a biconnected component, represented by its edges. More precisely, * a spanning tree of the biconnected component is returned. * Note you'll have to * destroy each vector first by calling \ref igraph_vector_destroy() * and then \ref igraph_free() on it, plus you need to call * \ref igraph_vector_ptr_destroy() on the list to regain all * allocated memory. * \param component_edges If not a NULL pointer, then the edges of the * biconnected components are stored here, in the same form as for * \c tree_edges. * \param components If not a NULL pointer, then the vertices of the * biconnected components are stored here, in the same format as * for the previous two arguments. * \param articulation_points If not a NULL pointer, then the * articulation points of the graph are stored in this vector. * A vertex is an articulation point if its removal increases the * number of (weakly) connected components in the graph. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges, but only if you do not calculate \c components and * \c component_edges. If you calculate \c components, then it is * quadratic in the number of vertices. If you calculate \c * component_edges as well, then it is cubic in the number of * vertices. * * \sa \ref igraph_articulation_points(), \ref igraph_clusters(). * * \example examples/simple/igraph_biconnected_components.c */ int igraph_biconnected_components(const igraph_t *graph, igraph_integer_t *no, igraph_vector_ptr_t *tree_edges, igraph_vector_ptr_t *component_edges, igraph_vector_ptr_t *components, igraph_vector_t *articulation_points) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_long_t nextptr; igraph_vector_long_t num, low; igraph_vector_bool_t found; igraph_vector_int_t *adjedges; igraph_stack_t path; igraph_vector_t edgestack; igraph_inclist_t inclist; long int i, counter, rootdfs = 0; igraph_vector_long_t vertex_added; long int comps = 0; igraph_vector_ptr_t *mycomponents = components, vcomponents; IGRAPH_CHECK(igraph_vector_long_init(&nextptr, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &nextptr); IGRAPH_CHECK(igraph_vector_long_init(&num, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &num); IGRAPH_CHECK(igraph_vector_long_init(&low, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &low); IGRAPH_CHECK(igraph_vector_bool_init(&found, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &found); IGRAPH_CHECK(igraph_stack_init(&path, 100)); IGRAPH_FINALLY(igraph_stack_destroy, &path); IGRAPH_VECTOR_INIT_FINALLY(&edgestack, 0); IGRAPH_CHECK(igraph_vector_reserve(&edgestack, 100)); IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); IGRAPH_CHECK(igraph_vector_long_init(&vertex_added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &vertex_added); if (no) { *no = 0; } if (tree_edges) { igraph_vector_ptr_clear(tree_edges); } if (components) { igraph_vector_ptr_clear(components); } if (component_edges) { igraph_vector_ptr_clear(component_edges); } if (articulation_points) { igraph_vector_clear(articulation_points); } if (component_edges && !components) { mycomponents = &vcomponents; IGRAPH_CHECK(igraph_vector_ptr_init(mycomponents, 0)); IGRAPH_FINALLY(igraph_i_free_vectorlist, mycomponents); } for (i = 0; i < no_of_nodes; i++) { if (VECTOR(low)[i] != 0) { continue; /* already visited */ } IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_stack_push(&path, i)); counter = 1; rootdfs = 0; VECTOR(low)[i] = VECTOR(num)[i] = counter++; while (!igraph_stack_empty(&path)) { long int n; long int act = (long int) igraph_stack_top(&path); long int actnext = VECTOR(nextptr)[act]; adjedges = igraph_inclist_get(&inclist, act); n = igraph_vector_int_size(adjedges); if (actnext < n) { /* Step down (maybe) */ long int edge = (long int) VECTOR(*adjedges)[actnext]; long int nei = IGRAPH_OTHER(graph, edge, act); if (VECTOR(low)[nei] == 0) { if (act == i) { rootdfs++; } IGRAPH_CHECK(igraph_vector_push_back(&edgestack, edge)); IGRAPH_CHECK(igraph_stack_push(&path, nei)); VECTOR(low)[nei] = VECTOR(num)[nei] = counter++; } else { /* Update low value if needed */ if (VECTOR(num)[nei] < VECTOR(low)[act]) { VECTOR(low)[act] = VECTOR(num)[nei]; } } VECTOR(nextptr)[act] += 1; } else { /* Step up */ igraph_stack_pop(&path); if (!igraph_stack_empty(&path)) { long int prev = (long int) igraph_stack_top(&path); /* Update LOW value if needed */ if (VECTOR(low)[act] < VECTOR(low)[prev]) { VECTOR(low)[prev] = VECTOR(low)[act]; } /* Check for articulation point */ if (VECTOR(low)[act] >= VECTOR(num)[prev]) { if (articulation_points && !VECTOR(found)[prev] && prev != i /* the root */) { IGRAPH_CHECK(igraph_vector_push_back(articulation_points, prev)); VECTOR(found)[prev] = 1; } if (no) { *no += 1; } /*------------------------------------*/ /* Record the biconnected component just found */ if (tree_edges || mycomponents) { igraph_vector_t *v = 0, *v2 = 0; comps++; if (tree_edges) { v = IGRAPH_CALLOC(1, igraph_vector_t); if (!v) { IGRAPH_ERROR("Out of memory", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(v, 0)); IGRAPH_FINALLY(igraph_vector_destroy, v); } if (mycomponents) { v2 = IGRAPH_CALLOC(1, igraph_vector_t); if (!v2) { IGRAPH_ERROR("Out of memory", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(v2, 0)); IGRAPH_FINALLY(igraph_vector_destroy, v2); } while (!igraph_vector_empty(&edgestack)) { long int e = (long int) igraph_vector_pop_back(&edgestack); long int from = IGRAPH_FROM(graph, e); long int to = IGRAPH_TO(graph, e); if (tree_edges) { IGRAPH_CHECK(igraph_vector_push_back(v, e)); } if (mycomponents) { if (VECTOR(vertex_added)[from] != comps) { VECTOR(vertex_added)[from] = comps; IGRAPH_CHECK(igraph_vector_push_back(v2, from)); } if (VECTOR(vertex_added)[to] != comps) { VECTOR(vertex_added)[to] = comps; IGRAPH_CHECK(igraph_vector_push_back(v2, to)); } } if (from == prev || to == prev) { break; } } if (mycomponents) { IGRAPH_CHECK(igraph_vector_ptr_push_back(mycomponents, v2)); IGRAPH_FINALLY_CLEAN(1); } if (tree_edges) { IGRAPH_CHECK(igraph_vector_ptr_push_back(tree_edges, v)); IGRAPH_FINALLY_CLEAN(1); } if (component_edges) { igraph_vector_t *nodes = VECTOR(*mycomponents)[comps - 1]; igraph_vector_t *vv = IGRAPH_CALLOC(1, igraph_vector_t); long int ii, no_vert = igraph_vector_size(nodes); if (!vv) { IGRAPH_ERROR("Out of memory", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_init(vv, 0)); IGRAPH_FINALLY(igraph_vector_destroy, vv); for (ii = 0; ii < no_vert; ii++) { long int vert = (long int) VECTOR(*nodes)[ii]; igraph_vector_int_t *edges = igraph_inclist_get(&inclist, vert); long int j, nn = igraph_vector_int_size(edges); for (j = 0; j < nn; j++) { long int e = (long int) VECTOR(*edges)[j]; long int nei = IGRAPH_OTHER(graph, e, vert); if (VECTOR(vertex_added)[nei] == comps && nei < vert) { IGRAPH_CHECK(igraph_vector_push_back(vv, e)); } } } IGRAPH_CHECK(igraph_vector_ptr_push_back(component_edges, vv)); IGRAPH_FINALLY_CLEAN(1); } } /* record component if requested */ /*------------------------------------*/ } } /* !igraph_stack_empty(&path) */ } } /* !igraph_stack_empty(&path) */ if (articulation_points && rootdfs >= 2) { IGRAPH_CHECK(igraph_vector_push_back(articulation_points, i)); } } /* i < no_of_nodes */ if (mycomponents != components) { igraph_i_free_vectorlist(mycomponents); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_long_destroy(&vertex_added); igraph_inclist_destroy(&inclist); igraph_vector_destroy(&edgestack); igraph_stack_destroy(&path); igraph_vector_bool_destroy(&found); igraph_vector_long_destroy(&low); igraph_vector_long_destroy(&num); igraph_vector_long_destroy(&nextptr); IGRAPH_FINALLY_CLEAN(8); return 0; } /* igraph_bridges -- find all bridges in the graph */ /* The algorithm is based on https://www.geeksforgeeks.org/bridge-in-a-graph/ but instead of keeping track of the parent of each vertex in the DFS tree we keep track of its incoming edge. This is necessary to support multigraphs. */ static int igraph_i_bridges_rec( const igraph_t *graph, const igraph_inclist_t *il, igraph_integer_t u, igraph_integer_t *time, igraph_vector_t *bridges, igraph_vector_bool_t *visited, igraph_vector_int_t *disc, igraph_vector_int_t *low, igraph_vector_int_t *incoming_edge) { igraph_vector_int_t *incedges; long nc; /* neighbour count */ long i; VECTOR(*visited)[u] = 1; *time += 1; VECTOR(*disc)[u] = *time; VECTOR(*low)[u] = *time; incedges = igraph_inclist_get(il, u); nc = igraph_vector_int_size(incedges); for (i = 0; i < nc; ++i) { long edge = (long) VECTOR(*incedges)[i]; igraph_integer_t v = IGRAPH_TO(graph, edge) == u ? IGRAPH_FROM(graph, edge) : IGRAPH_TO(graph, edge); if (! VECTOR(*visited)[v]) { VECTOR(*incoming_edge)[v] = edge; IGRAPH_CHECK(igraph_i_bridges_rec(graph, il, v, time, bridges, visited, disc, low, incoming_edge)); VECTOR(*low)[u] = VECTOR(*low)[u] < VECTOR(*low)[v] ? VECTOR(*low)[u] : VECTOR(*low)[v]; if (VECTOR(*low)[v] > VECTOR(*disc)[u]) { IGRAPH_CHECK(igraph_vector_push_back(bridges, edge)); } } else if (edge != VECTOR(*incoming_edge)[u]) { VECTOR(*low)[u] = VECTOR(*low)[u] < VECTOR(*disc)[v] ? VECTOR(*low)[u] : VECTOR(*disc)[v]; } } return IGRAPH_SUCCESS; } /** * \function igraph_bridges * Find all bridges in a graph. * * An edge is a bridge if its removal increases the number of (weakly) * connected components in the graph. * * \param graph The input graph. * \param res Pointer to an initialized vector, the * bridges will be stored here as edge indices. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and edges. * * \sa \ref igraph_articulation_points(), \ref igraph_biconnected_components(), \ref igraph_clusters() */ int igraph_bridges(const igraph_t *graph, igraph_vector_t *bridges) { igraph_inclist_t il; igraph_vector_bool_t visited; igraph_vector_int_t disc, low; igraph_vector_int_t incoming_edge; long n; long i; igraph_integer_t time; n = igraph_vcount(graph); IGRAPH_CHECK(igraph_inclist_init(graph, &il, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &il); IGRAPH_CHECK(igraph_vector_bool_init(&visited, n)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &visited); IGRAPH_CHECK(igraph_vector_int_init(&disc, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &disc); IGRAPH_CHECK(igraph_vector_int_init(&low, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &low); IGRAPH_CHECK(igraph_vector_int_init(&incoming_edge, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &incoming_edge); for (i = 0; i < n; ++i) { VECTOR(incoming_edge)[i] = -1; } igraph_vector_clear(bridges); time = 0; for (i = 0; i < n; ++i) if (! VECTOR(visited)[i]) { IGRAPH_CHECK(igraph_i_bridges_rec(graph, &il, i, &time, bridges, &visited, &disc, &low, &incoming_edge)); } igraph_vector_int_destroy(&incoming_edge); igraph_vector_int_destroy(&low); igraph_vector_int_destroy(&disc); igraph_vector_bool_destroy(&visited); igraph_inclist_destroy(&il); IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_subcomponent * \brief The vertices in the same component as a given vertex. * * \param graph The graph object. * \param res The result, vector with the ids of the vertices in the * same component. * \param vertex The id of the vertex of which the component is * searched. * \param mode Type of the component for directed graphs, possible * values: * \clist * \cli IGRAPH_OUT * the set of vertices reachable \em from the * \p vertex, * \cli IGRAPH_IN * the set of vertices from which the * \p vertex is reachable. * \cli IGRAPH_ALL * the graph is considered as an * undirected graph. Note that this is \em not the same * as the union of the previous two. * \endclist * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * \p vertex is an invalid vertex id * \cli IGRAPH_EINVMODE * invalid mode argument passed. * \endclist * * Time complexity: O(|V|+|E|), * |V| and * |E| are the number of vertices and * edges in the graph. * * \sa \ref igraph_induced_subgraph() if you want a graph object consisting only * a given set of vertices and the edges between them. */ int igraph_subcomponent(const igraph_t *graph, igraph_vector_t *res, igraph_real_t vertex, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); igraph_dqueue_t q = IGRAPH_DQUEUE_NULL; char *already_added; long int i, vsize; igraph_vector_t tmp = IGRAPH_VECTOR_NULL; if (!IGRAPH_FINITE(vertex) || vertex < 0 || vertex >= no_of_nodes) { IGRAPH_ERROR("Vertex id out of range.", IGRAPH_EINVVID); } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument.", IGRAPH_EINVMODE); } already_added = IGRAPH_CALLOC(no_of_nodes, char); if (already_added == 0) { IGRAPH_ERROR("Subcomponent failed.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); igraph_vector_clear(res); IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_dqueue_push(&q, vertex)); IGRAPH_CHECK(igraph_vector_push_back(res, vertex)); already_added[(long int)vertex] = 1; while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_neighbors(graph, &tmp, (igraph_integer_t) actnode, mode)); vsize = igraph_vector_size(&tmp); for (i = 0; i < vsize; i++) { long int neighbor = (long int) VECTOR(tmp)[i]; if (already_added[neighbor]) { continue; } already_added[neighbor] = 1; IGRAPH_CHECK(igraph_vector_push_back(res, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); } } igraph_dqueue_destroy(&q); igraph_vector_destroy(&tmp); IGRAPH_FREE(already_added); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } leidenbase/src/core/connectivity/separators.c0000644000176200001440000007575614447675374021202 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2010-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_separators.h" #include "igraph_adjlist.h" #include "igraph_components.h" #include "igraph_dqueue.h" #include "igraph_flow.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_operators.h" #include "igraph_structural.h" #include "igraph_vector.h" #include "core/interruption.h" static int igraph_i_is_separator(const igraph_t *graph, igraph_vit_t *vit, long int except, igraph_bool_t *res, igraph_vector_bool_t *removed, igraph_dqueue_t *Q, igraph_vector_t *neis, long int no_of_nodes) { long int start = 0; if (IGRAPH_VIT_SIZE(*vit) >= no_of_nodes - 1) { /* Just need to check that we really have at least n-1 vertices in it */ igraph_vector_bool_t hit; long int nohit = 0; IGRAPH_CHECK(igraph_vector_bool_init(&hit, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &hit); for (IGRAPH_VIT_RESET(*vit); !IGRAPH_VIT_END(*vit); IGRAPH_VIT_NEXT(*vit)) { long int v = IGRAPH_VIT_GET(*vit); if (!VECTOR(hit)[v]) { nohit++; VECTOR(hit)[v] = 1; } } igraph_vector_bool_destroy(&hit); IGRAPH_FINALLY_CLEAN(1); if (nohit >= no_of_nodes - 1) { *res = 0; return 0; } } /* Remove the given vertices from the graph, do a breadth-first search and check the number of components */ if (except < 0) { for (IGRAPH_VIT_RESET(*vit); !IGRAPH_VIT_END(*vit); IGRAPH_VIT_NEXT(*vit)) { VECTOR(*removed)[ (long int) IGRAPH_VIT_GET(*vit) ] = 1; } } else { /* There is an exception */ long int i; for (i = 0, IGRAPH_VIT_RESET(*vit); i < except; i++, IGRAPH_VIT_NEXT(*vit)) { VECTOR(*removed)[ (long int) IGRAPH_VIT_GET(*vit) ] = 1; } for (IGRAPH_VIT_NEXT(*vit); !IGRAPH_VIT_END(*vit); IGRAPH_VIT_NEXT(*vit)) { VECTOR(*removed)[ (long int) IGRAPH_VIT_GET(*vit) ] = 1; } } /* Look for the first node that is not removed */ while (start < no_of_nodes && VECTOR(*removed)[start]) { start++; } if (start == no_of_nodes) { IGRAPH_ERROR("All vertices are included in the separator", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_dqueue_push(Q, start)); VECTOR(*removed)[start] = 1; while (!igraph_dqueue_empty(Q)) { long int node = (long int) igraph_dqueue_pop(Q); long int j, n; IGRAPH_CHECK(igraph_neighbors(graph, neis, (igraph_integer_t) node, IGRAPH_ALL)); n = igraph_vector_size(neis); for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(*neis)[j]; if (!VECTOR(*removed)[nei]) { IGRAPH_CHECK(igraph_dqueue_push(Q, nei)); VECTOR(*removed)[nei] = 1; } } } /* Look for the next node that was neighter removed, not visited */ while (start < no_of_nodes && VECTOR(*removed)[start]) { start++; } /* If there is another component, then we have a separator */ *res = (start < no_of_nodes); return 0; } /** * \function igraph_is_separator * \brief Would removing this set of vertices disconnect the graph? * * \param graph The input graph. It may be directed, but edge * directions are ignored. * \param candidate The candidate separator. It must not contain all * vertices. * \param res Pointer to a Boolean variable, the result is stored here. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number vertices and edges. * * \example examples/simple/igraph_is_separator.c */ int igraph_is_separator(const igraph_t *graph, const igraph_vs_t candidate, igraph_bool_t *res) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_bool_t removed; igraph_dqueue_t Q; igraph_vector_t neis; igraph_vit_t vit; IGRAPH_CHECK(igraph_vit_create(graph, candidate, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_CHECK(igraph_vector_bool_init(&removed, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &removed); IGRAPH_CHECK(igraph_dqueue_init(&Q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &Q); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_i_is_separator(graph, &vit, -1, res, &removed, &Q, &neis, no_of_nodes)); igraph_vector_destroy(&neis); igraph_dqueue_destroy(&Q); igraph_vector_bool_destroy(&removed); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(4); return 0; } /** * \function igraph_is_minimal_separator * \brief Decides whether a set of vertices is a minimal separator. * * A set of vertices is a minimal separator, if the removal of the * vertices disconnects the graph, and this is not true for any subset * of the set. * * This implementation first checks that the given * candidate is a separator, by calling \ref * igraph_is_separator(). If it is a separator, then it checks that * each subset of size n-1, where n is the size of the candidate, is * not a separator. * * \param graph The input graph. It may be directed, but edge * directions are ignored. * \param candidate Pointer to a vector of long integers, the * candidate minimal separator. * \param res Pointer to a boolean variable, the result is stored * here. * \return Error code. * * Time complexity: O(n(|V|+|E|)), |V| is the number of vertices, |E| * is the number of edges, n is the number vertices in the candidate * separator. * * \example examples/simple/igraph_is_minimal_separator.c */ int igraph_is_minimal_separator(const igraph_t *graph, const igraph_vs_t candidate, igraph_bool_t *res) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_bool_t removed; igraph_dqueue_t Q; igraph_vector_t neis; long int candsize; igraph_vit_t vit; IGRAPH_CHECK(igraph_vit_create(graph, candidate, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); candsize = IGRAPH_VIT_SIZE(vit); IGRAPH_CHECK(igraph_vector_bool_init(&removed, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &removed); IGRAPH_CHECK(igraph_dqueue_init(&Q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &Q); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); /* Is it a separator at all? */ IGRAPH_CHECK(igraph_i_is_separator(graph, &vit, -1, res, &removed, &Q, &neis, no_of_nodes)); if (!(*res)) { /* Not a separator at all, nothing to do, *res is already set */ } else if (candsize == 0) { /* Nothing to do, minimal, *res is already set */ } else { /* General case, we need to remove each vertex from 'candidate' * and check whether the remainder is a separator. If this is * false for all vertices, then 'candidate' is a minimal * separator. */ long int i; for (i = 0, *res = 0; i < candsize && (!*res); i++) { igraph_vector_bool_null(&removed); IGRAPH_CHECK(igraph_i_is_separator(graph, &vit, i, res, &removed, &Q, &neis, no_of_nodes)); } (*res) = (*res) ? 0 : 1; /* opposite */ } igraph_vector_destroy(&neis); igraph_dqueue_destroy(&Q); igraph_vector_bool_destroy(&removed); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(4); return 0; } /* --------------------------------------------------------------------*/ #define UPDATEMARK() do { \ (*mark)++; \ if (!(*mark)) { \ igraph_vector_null(leaveout); \ (*mark)=1; \ } \ } while (0) static int igraph_i_clusters_leaveout(const igraph_adjlist_t *adjlist, igraph_vector_t *components, igraph_vector_t *leaveout, unsigned long int *mark, igraph_dqueue_t *Q) { /* Another trick: we use the same 'leaveout' vector to mark the * vertices that were already found in the BFS */ long int i, no_of_nodes = igraph_adjlist_size(adjlist); igraph_dqueue_clear(Q); igraph_vector_clear(components); for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*leaveout)[i] == *mark) { continue; } VECTOR(*leaveout)[i] = *mark; igraph_dqueue_push(Q, i); igraph_vector_push_back(components, i); while (!igraph_dqueue_empty(Q)) { long int act_node = (long int) igraph_dqueue_pop(Q); igraph_vector_int_t *neis = igraph_adjlist_get(adjlist, act_node); long int j, n = igraph_vector_int_size(neis); for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(*neis)[j]; if (VECTOR(*leaveout)[nei] == *mark) { continue; } IGRAPH_CHECK(igraph_dqueue_push(Q, nei)); VECTOR(*leaveout)[nei] = *mark; igraph_vector_push_back(components, nei); } } igraph_vector_push_back(components, -1); } UPDATEMARK(); return 0; } static igraph_bool_t igraph_i_separators_newsep(const igraph_vector_ptr_t *comps, const igraph_vector_t *newc) { long int co, nocomps = igraph_vector_ptr_size(comps); for (co = 0; co < nocomps; co++) { igraph_vector_t *act = VECTOR(*comps)[co]; if (igraph_vector_all_e(act, newc)) { return 0; } } /* If not found, then it is new */ return 1; } static int igraph_i_separators_store(igraph_vector_ptr_t *separators, const igraph_adjlist_t *adjlist, igraph_vector_t *components, igraph_vector_t *leaveout, unsigned long int *mark, igraph_vector_t *sorter) { /* We need to stote N(C), the neighborhood of C, but only if it is * not already stored among the separators. */ long int cptr = 0, next, complen = igraph_vector_size(components); while (cptr < complen) { long int saved = cptr; igraph_vector_clear(sorter); /* Calculate N(C) for the next C */ while ( (next = (long int) VECTOR(*components)[cptr++]) != -1) { VECTOR(*leaveout)[next] = *mark; } cptr = saved; while ( (next = (long int) VECTOR(*components)[cptr++]) != -1) { igraph_vector_int_t *neis = igraph_adjlist_get(adjlist, next); long int j, nn = igraph_vector_int_size(neis); for (j = 0; j < nn; j++) { long int nei = (long int) VECTOR(*neis)[j]; if (VECTOR(*leaveout)[nei] != *mark) { igraph_vector_push_back(sorter, nei); VECTOR(*leaveout)[nei] = *mark; } } } igraph_vector_sort(sorter); UPDATEMARK(); /* Add it to the list of separators, if it is new */ if (igraph_i_separators_newsep(separators, sorter)) { igraph_vector_t *newc = IGRAPH_CALLOC(1, igraph_vector_t); if (!newc) { IGRAPH_ERROR("Cannot calculate minimal separators", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newc); igraph_vector_copy(newc, sorter); IGRAPH_FINALLY(igraph_vector_destroy, newc); IGRAPH_CHECK(igraph_vector_ptr_push_back(separators, newc)); IGRAPH_FINALLY_CLEAN(2); } } /* while cptr < complen */ return 0; } static void igraph_i_separators_free(igraph_vector_ptr_t *separators) { long int i, n = igraph_vector_ptr_size(separators); for (i = 0; i < n; i++) { igraph_vector_t *vec = VECTOR(*separators)[i]; if (vec) { igraph_vector_destroy(vec); IGRAPH_FREE(vec); } } } /** * \function igraph_all_minimal_st_separators * \brief List all vertex sets that are minimal (s,t) separators for some s and t. * * This function lists all vertex sets that are minimal (s,t) * separators for some (s,t) vertex pair. * * * Note that some vertex sets returned by this function may not be minimal * with respect to disconnecting the graph (or increasing the number of * connected components). Take for example the 5-vertex graph with edges * 0-1-2-3-4-1. This function returns the vertex sets * {1}, {2,4} and {1,3}. * Notice that {1,3} is not minimal with respect to disconnecting * the graph, as {1} would be sufficient for that. However, it is * minimal with respect to separating vertices \c 2 and \c 4. * * * See more about the implemented algorithm in * Anne Berry, Jean-Paul Bordat and Olivier Cogis: Generating All the * Minimal Separators of a Graph, In: Peter Widmayer, Gabriele Neyer * and Stephan Eidenbenz (editors): Graph-theoretic concepts in * computer science, 1665, 167--172, 1999. Springer. * https://doi.org/10.1007/3-540-46784-X_17 * * \param graph The input graph. It may be directed, but edge * directions are ignored. * \param separators An initialized pointer vector, the separators * are stored here. It is a list of pointers to igraph_vector_t * objects. Each vector will contain the ids of the vertices in * the separator. * To free all memory allocated for \p separators, you need call * \ref igraph_vector_destroy() and then \ref igraph_free() on * each element, before destroying the pointer vector itself. * \return Error code. * * \sa \ref igraph_minimum_size_separators() * * Time complexity: O(n|V|^3), |V| is the number of vertices, n is the * number of separators. * * \example examples/simple/igraph_minimal_separators.c */ int igraph_all_minimal_st_separators(const igraph_t *graph, igraph_vector_ptr_t *separators) { /* * Some notes about the tricks used here. For finding the components * of the graph after removing some vertices, we do the * following. First we mark the vertices with the actual mark stamp * (mark), then run breadth-first search on the graph, but not * considering the marked vertices. Then we increase the mark. If * there is integer overflow here, then we zero out the mark and set * it to one. (We might as well just always zero it out.) * * For each separator the vertices are stored in vertex id order. * This facilitates the comparison of the separators when we find a * potential new candidate. * * To keep track of which separator we already used as a basis, we * keep a boolean vector (already_tried). The try_next pointer show * the next separator to try as a basis. */ long int no_of_nodes = igraph_vcount(graph); igraph_vector_t leaveout; igraph_vector_bool_t already_tried; long int try_next = 0; unsigned long int mark = 1; long int v; igraph_adjlist_t adjlist; igraph_vector_t components; igraph_dqueue_t Q; igraph_vector_t sorter; igraph_vector_ptr_clear(separators); IGRAPH_FINALLY(igraph_i_separators_free, separators); IGRAPH_CHECK(igraph_vector_init(&leaveout, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_destroy, &leaveout); IGRAPH_CHECK(igraph_vector_bool_init(&already_tried, 0)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &already_tried); IGRAPH_CHECK(igraph_vector_init(&components, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &components); IGRAPH_CHECK(igraph_vector_reserve(&components, no_of_nodes * 2)); IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_dqueue_init(&Q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &Q); IGRAPH_CHECK(igraph_vector_init(&sorter, 0)); IGRAPH_FINALLY(igraph_vector_destroy, &sorter); IGRAPH_CHECK(igraph_vector_reserve(&sorter, no_of_nodes)); /* --------------------------------------------------------------- * INITIALIZATION, we check whether the neighborhoods of the * vertices separate the graph. The ones that do will form the * initial basis. */ for (v = 0; v < no_of_nodes; v++) { /* Mark v and its neighbors */ igraph_vector_int_t *neis = igraph_adjlist_get(&adjlist, v); long int i, n = igraph_vector_int_size(neis); VECTOR(leaveout)[v] = mark; for (i = 0; i < n; i++) { long int nei = (long int) VECTOR(*neis)[i]; VECTOR(leaveout)[nei] = mark; } /* Find the components */ IGRAPH_CHECK(igraph_i_clusters_leaveout(&adjlist, &components, &leaveout, &mark, &Q)); /* Store the corresponding separators, N(C) for each component C */ IGRAPH_CHECK(igraph_i_separators_store(separators, &adjlist, &components, &leaveout, &mark, &sorter)); } /* --------------------------------------------------------------- * GENERATION, we need to use all already found separators as * basis and see if they generate more separators */ while (try_next < igraph_vector_ptr_size(separators)) { igraph_vector_t *basis = VECTOR(*separators)[try_next]; long int b, basislen = igraph_vector_size(basis); for (b = 0; b < basislen; b++) { /* Remove N(x) U basis */ long int x = (long int) VECTOR(*basis)[b]; igraph_vector_int_t *neis = igraph_adjlist_get(&adjlist, x); long int i, n = igraph_vector_int_size(neis); for (i = 0; i < basislen; i++) { long int sn = (long int) VECTOR(*basis)[i]; VECTOR(leaveout)[sn] = mark; } for (i = 0; i < n; i++) { long int nei = (long int) VECTOR(*neis)[i]; VECTOR(leaveout)[nei] = mark; } /* Find the components */ IGRAPH_CHECK(igraph_i_clusters_leaveout(&adjlist, &components, &leaveout, &mark, &Q)); /* Store the corresponding separators, N(C) for each component C */ IGRAPH_CHECK(igraph_i_separators_store(separators, &adjlist, &components, &leaveout, &mark, &sorter)); } try_next++; } /* --------------------------------------------------------------- */ igraph_vector_destroy(&sorter); igraph_dqueue_destroy(&Q); igraph_adjlist_destroy(&adjlist); igraph_vector_destroy(&components); igraph_vector_bool_destroy(&already_tried); igraph_vector_destroy(&leaveout); IGRAPH_FINALLY_CLEAN(7); /* +1 for separators */ return 0; } #undef UPDATEMARK static int igraph_i_minimum_size_separators_append(igraph_vector_ptr_t *old, igraph_vector_ptr_t *new) { long int olen = igraph_vector_ptr_size(old); long int nlen = igraph_vector_ptr_size(new); long int i; for (i = 0; i < nlen; i++) { igraph_vector_t *newvec = VECTOR(*new)[i]; long int j; for (j = 0; j < olen; j++) { igraph_vector_t *oldvec = VECTOR(*old)[j]; if (igraph_vector_all_e(oldvec, newvec)) { break; } } if (j == olen) { IGRAPH_CHECK(igraph_vector_ptr_push_back(old, newvec)); olen++; } else { igraph_vector_destroy(newvec); igraph_free(newvec); } VECTOR(*new)[i] = 0; } igraph_vector_ptr_clear(new); return 0; } static int igraph_i_minimum_size_separators_topkdeg(const igraph_t *graph, igraph_vector_t *res, long int k) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t deg, order; long int i; IGRAPH_VECTOR_INIT_FINALLY(°, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&order, no_of_nodes); IGRAPH_CHECK(igraph_degree(graph, °, igraph_vss_all(), IGRAPH_ALL, /*loops=*/ 0)); IGRAPH_CHECK(igraph_vector_order1(°, &order, no_of_nodes)); IGRAPH_CHECK(igraph_vector_resize(res, k)); for (i = 0; i < k; i++) { VECTOR(*res)[i] = VECTOR(order)[no_of_nodes - 1 - i]; } igraph_vector_destroy(&order); igraph_vector_destroy(°); IGRAPH_FINALLY_CLEAN(2); return 0; } static void igraph_i_separators_stcuts_free(igraph_vector_ptr_t *p) { long int i, n = igraph_vector_ptr_size(p); for (i = 0; i < n; i++) { igraph_vector_t *v = VECTOR(*p)[i]; if (v) { igraph_vector_destroy(v); igraph_free(v); VECTOR(*p)[i] = 0; } } igraph_vector_ptr_destroy(p); } /** * \function igraph_minimum_size_separators * \brief Find all minimum size separating vertex sets. * * This function lists all separator vertex sets of minimum size. * A vertex set is a separator if its removal disconnects the graph. * * * The implementation is based on the following paper: * Arkady Kanevsky: Finding all minimum-size separating vertex sets in * a graph, Networks 23, 533--541, 1993. * * \param graph The input graph, which must be undirected. * \param separators An initialized pointer vector, the separators * are stored here. It is a list of pointers to igraph_vector_t * objects. Each vector will contain the ids of the vertices in * the separator. * To free all memory allocated for \c separators, you need call * \ref igraph_vector_destroy() and then \ref igraph_free() on * each element, before destroying the pointer vector itself. * \return Error code. * * Time complexity: TODO. * * \example examples/simple/igraph_minimum_size_separators.c */ int igraph_minimum_size_separators(const igraph_t *graph, igraph_vector_ptr_t *separators) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_integer_t conn; long int k; igraph_vector_t X; long int i, j; igraph_bool_t issepX; igraph_t Gbar; igraph_vector_t phi; igraph_t graph_copy; igraph_vector_t capacity; igraph_maxflow_stats_t stats; if (igraph_is_directed(graph)) { IGRAPH_ERROR("Minimum size separators currently only works on undirected graphs", IGRAPH_EINVAL); } igraph_vector_ptr_clear(separators); IGRAPH_FINALLY(igraph_i_separators_free, separators); /* ---------------------------------------------------------------- */ /* 1 Find the vertex connectivity of 'graph' */ IGRAPH_CHECK(igraph_vertex_connectivity(graph, &conn, /* checks= */ 1)); k = conn; /* Special cases for low connectivity, two exits here! */ if (conn == 0) { /* Nothing to do */ IGRAPH_FINALLY_CLEAN(1); /* separators */ return 0; } else if (conn == 1) { igraph_vector_t ap; long int i, n; IGRAPH_VECTOR_INIT_FINALLY(&ap, 0); IGRAPH_CHECK(igraph_articulation_points(graph, &ap)); n = igraph_vector_size(&ap); IGRAPH_CHECK(igraph_vector_ptr_resize(separators, n)); igraph_vector_ptr_null(separators); for (i = 0; i < n; i++) { igraph_vector_t *v = IGRAPH_CALLOC(1, igraph_vector_t); if (!v) { IGRAPH_ERROR("Minimum size separators failed", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(v, 1); VECTOR(*v)[0] = VECTOR(ap)[i]; VECTOR(*separators)[i] = v; IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&ap); IGRAPH_FINALLY_CLEAN(2); /* +1 for separators */ return 0; } else if (conn == no_of_nodes - 1) { long int k; IGRAPH_CHECK(igraph_vector_ptr_resize(separators, no_of_nodes)); igraph_vector_ptr_null(separators); for (i = 0; i < no_of_nodes; i++) { igraph_vector_t *v = IGRAPH_CALLOC(1, igraph_vector_t); if (!v) { IGRAPH_ERROR("Cannot list minimum size separators", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(v, no_of_nodes - 1); for (j = 0, k = 0; j < no_of_nodes; j++) { if (j != i) { VECTOR(*v)[k++] = j; } } VECTOR(*separators)[i] = v; IGRAPH_FINALLY_CLEAN(1); } IGRAPH_FINALLY_CLEAN(1); /* separators */ return 0; } /* Work on a copy of 'graph' */ IGRAPH_CHECK(igraph_copy(&graph_copy, graph)); IGRAPH_FINALLY(igraph_destroy, &graph_copy); IGRAPH_CHECK(igraph_simplify(&graph_copy, /* multiple */ 1, /* loops */ 1, NULL)); /* ---------------------------------------------------------------- */ /* 2 Find k vertices with the largest degrees (x1;..,xk). Check if these k vertices form a separating k-set of G */ IGRAPH_CHECK(igraph_vector_init(&X, conn)); IGRAPH_FINALLY(igraph_vector_destroy, &X); IGRAPH_CHECK(igraph_i_minimum_size_separators_topkdeg(&graph_copy, &X, k)); IGRAPH_CHECK(igraph_is_separator(&graph_copy, igraph_vss_vector(&X), &issepX)); if (issepX) { igraph_vector_t *v = IGRAPH_CALLOC(1, igraph_vector_t); if (!v) { IGRAPH_ERROR("Cannot find minimal size separators", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(v, k); for (i = 0; i < k; i++) { VECTOR(*v)[i] = VECTOR(X)[i]; } IGRAPH_CHECK(igraph_vector_ptr_push_back(separators, v)); IGRAPH_FINALLY_CLEAN(1); } /* Create Gbar, the Even-Tarjan reduction of graph */ IGRAPH_VECTOR_INIT_FINALLY(&capacity, 0); IGRAPH_CHECK(igraph_even_tarjan_reduction(&graph_copy, &Gbar, &capacity)); IGRAPH_FINALLY(igraph_destroy, &Gbar); IGRAPH_VECTOR_INIT_FINALLY(&phi, no_of_edges); /* ---------------------------------------------------------------- */ /* 3 If v[j] != x[i] and v[j] is not adjacent to x[i] then */ for (i = 0; i < k; i++) { IGRAPH_ALLOW_INTERRUPTION(); for (j = 0; j < no_of_nodes; j++) { long int ii = (long int) VECTOR(X)[i]; igraph_real_t phivalue; igraph_bool_t conn; if (ii == j) { continue; /* the same vertex */ } IGRAPH_CHECK(igraph_are_connected(&graph_copy, (igraph_integer_t) ii, (igraph_integer_t) j, &conn)); if (conn) { continue; /* they are connected */ } /* --------------------------------------------------------------- */ /* 4 Compute a maximum flow phi in Gbar from x[i] to v[j]. If |phi|=k, then */ IGRAPH_CHECK(igraph_maxflow(&Gbar, &phivalue, &phi, /*cut=*/ 0, /*partition=*/ 0, /*partition2=*/ 0, /* source= */ (igraph_integer_t) (ii + no_of_nodes), /* target= */ (igraph_integer_t) j, &capacity, &stats)); if (phivalue == k) { /* ------------------------------------------------------------- */ /* 5-6-7. Find all k-sets separating x[i] and v[j]. */ igraph_vector_ptr_t stcuts; IGRAPH_CHECK(igraph_vector_ptr_init(&stcuts, 0)); IGRAPH_FINALLY(igraph_i_separators_stcuts_free, &stcuts); IGRAPH_CHECK(igraph_all_st_mincuts(&Gbar, /*value=*/ 0, /*cuts=*/ &stcuts, /*partition1s=*/ 0, /*source=*/ (igraph_integer_t) (ii + no_of_nodes), /*target=*/ (igraph_integer_t) j, /*capacity=*/ &capacity)); IGRAPH_CHECK(igraph_i_minimum_size_separators_append(separators, &stcuts)); igraph_vector_ptr_destroy(&stcuts); IGRAPH_FINALLY_CLEAN(1); } /* if phivalue == k */ /* --------------------------------------------------------------- */ /* 8 Add edge (x[i],v[j]) to G. */ IGRAPH_CHECK(igraph_add_edge(&graph_copy, (igraph_integer_t) ii, (igraph_integer_t) j)); IGRAPH_CHECK(igraph_add_edge(&Gbar, (igraph_integer_t) (ii + no_of_nodes), (igraph_integer_t) j)); IGRAPH_CHECK(igraph_add_edge(&Gbar, (igraph_integer_t) (j + no_of_nodes), (igraph_integer_t) ii)); IGRAPH_CHECK(igraph_vector_push_back(&capacity, no_of_nodes)); IGRAPH_CHECK(igraph_vector_push_back(&capacity, no_of_nodes)); } /* for j 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_random.h" #include "igraph_nongraph.h" #include "igraph_error.h" #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_memory.h" #include "core/math.h" #include "config.h" #include #include /** * \section about_rngs * *
* About random numbers in igraph, use cases * * * Some algorithms in igraph, e.g. the generation of random graphs, * require random number generators (RNGs). Prior to version 0.6 * igraph did not have a sophisticated way to deal with random number * generators at the C level, but this has changed. From version 0.6 * different and multiple random number generators are supported. * *
* */ /** * \section rng_use_cases * *
Use cases * *
Normal (default) use * * If the user does not use any of the RNG functions explicitly, but calls * some of the randomized igraph functions, then a default RNG is set * up the first time an igraph function needs random numbers. The * seed of this RNG is the output of the time(0) function * call, using the time function from the standard C * library. This ensures that igraph creates a different random graph, * each time the C program is called. * * * * The created default generator is stored internally and can be * queried with the \ref igraph_rng_default() function. * *
* *
Reproducible simulations * * If reproducible results are needed, then the user should set the * seed of the default random number generator explicitly, using the * \ref igraph_rng_seed() function on the default generator, \ref * igraph_rng_default(). When setting the seed to the same number, * igraph generates exactly the same random graph (or series of random * graphs). * *
* *
Changing the default generator * * By default igraph uses the \ref igraph_rng_default() random number * generator. This can be changed any time by calling \ref * igraph_rng_set_default(), with an already initialized random number * generator. Note that the old (replaced) generator is not * destroyed, so no memory is deallocated. * *
* *
Using multiple generators * * igraph also provides functions to set up multiple random number * generators, using the \ref igraph_rng_init() function, and then * generating random numbers from them, e.g. with \ref igraph_rng_get_integer() * and/or \ref igraph_rng_get_unif() calls. * * * * Note that initializing a new random number generator is * independent of the generator that the igraph functions themselves * use. If you want to replace that, then please use \ref * igraph_rng_set_default(). * *
* *
Example * * \example examples/simple/random_seed.c * *
* *
*/ /* ------------------------------------ */ typedef struct { int i, j; long int x[31]; } igraph_i_rng_glibc2_state_t; static unsigned long int igraph_i_rng_glibc2_get(int *i, int *j, int n, long int *x) { unsigned long int k; x[*i] += x[*j]; k = (x[*i] >> 1) & 0x7FFFFFFF; (*i)++; if (*i == n) { *i = 0; } (*j)++ ; if (*j == n) { *j = 0; } return k; } static unsigned long int igraph_rng_glibc2_get(void *vstate) { igraph_i_rng_glibc2_state_t *state = (igraph_i_rng_glibc2_state_t*) vstate; return igraph_i_rng_glibc2_get(&state->i, &state->j, 31, state->x); } static igraph_real_t igraph_rng_glibc2_get_real(void *state) { return igraph_rng_glibc2_get(state) / 2147483648.0; } /* this function is independent of the bit size */ static void igraph_i_rng_glibc2_init(long int *x, int n, unsigned long int s) { int i; if (s == 0) { s = 1; } x[0] = (long) s; for (i = 1 ; i < n ; i++) { const long int h = s / 127773; const long int t = 16807 * ((long) s - h * 127773) - h * 2836; if (t < 0) { s = (unsigned long) t + 2147483647 ; } else { s = (unsigned long) t ; } x[i] = (long int) s ; } } static int igraph_rng_glibc2_seed(void *vstate, unsigned long int seed) { igraph_i_rng_glibc2_state_t *state = (igraph_i_rng_glibc2_state_t*) vstate; int i; igraph_i_rng_glibc2_init(state->x, 31, seed); state->i = 3; state->j = 0; for (i = 0; i < 10 * 31; i++) { igraph_rng_glibc2_get(state); } return IGRAPH_SUCCESS; } static int igraph_rng_glibc2_init(void **state) { igraph_i_rng_glibc2_state_t *st; st = IGRAPH_CALLOC(1, igraph_i_rng_glibc2_state_t); if (!st) { IGRAPH_ERROR("Cannot initialize RNG", IGRAPH_ENOMEM); } (*state) = st; igraph_rng_glibc2_seed(st, 0); return IGRAPH_SUCCESS; } static void igraph_rng_glibc2_destroy(void *vstate) { igraph_i_rng_glibc2_state_t *state = (igraph_i_rng_glibc2_state_t*) vstate; IGRAPH_FREE(state); } /** * \var igraph_rngtype_glibc2 * \brief The random number generator introduced in GNU libc 2. * * This is a linear feedback shift register generator with a 128-byte * buffer. This generator was the default prior to igraph version 0.6, * at least on systems relying on GNU libc. * * This generator was ported from the GNU Scientific Library. It is a * reimplementation and does not call the system glibc generator. */ const igraph_rng_type_t igraph_rngtype_glibc2 = { /* name= */ "LIBC", /* min= */ 0, /* max= */ 0x7fffffffUL, /* init= */ igraph_rng_glibc2_init, /* destroy= */ igraph_rng_glibc2_destroy, /* seed= */ igraph_rng_glibc2_seed, /* get= */ igraph_rng_glibc2_get, /* get_real= */ igraph_rng_glibc2_get_real, /* get_norm= */ 0, /* get_geom= */ 0, /* get_binom= */ 0, /* get_exp= */ 0, /* get_gamma= */ 0 }; /* ------------------------------------ */ typedef struct { unsigned long int x; } igraph_i_rng_rand_state_t; static unsigned long int igraph_rng_rand_get(void *vstate) { igraph_i_rng_rand_state_t *state = vstate; state->x = (1103515245 * state->x + 12345) & 0x7fffffffUL; return state->x; } static igraph_real_t igraph_rng_rand_get_real(void *vstate) { return igraph_rng_rand_get (vstate) / 2147483648.0 ; } static int igraph_rng_rand_seed(void *vstate, unsigned long int seed) { igraph_i_rng_rand_state_t *state = vstate; state->x = seed; return IGRAPH_SUCCESS; } static int igraph_rng_rand_init(void **state) { igraph_i_rng_rand_state_t *st; st = IGRAPH_CALLOC(1, igraph_i_rng_rand_state_t); if (!st) { IGRAPH_ERROR("Cannot initialize RNG", IGRAPH_ENOMEM); } (*state) = st; igraph_rng_rand_seed(st, 0); return IGRAPH_SUCCESS; } static void igraph_rng_rand_destroy(void *vstate) { igraph_i_rng_rand_state_t *state = (igraph_i_rng_rand_state_t*) vstate; IGRAPH_FREE(state); } /** * \var igraph_rngtype_rand * \brief The old BSD rand/srand random number generator. * * The sequence is * x_{n+1} = (a x_n + c) mod m * with a = 1103515245, c = 12345 and * m = 2^31 = 2147483648. * The seed specifies the initial value, x_1. * *
* The theoretical value of x_{10001} is 1910041713. * * * The period of this generator is 2^31. * * * This generator is not very good—the low bits of successive * numbers are correlated. * * * This generator was ported from the GNU Scientific Library. */ const igraph_rng_type_t igraph_rngtype_rand = { /* name= */ "RAND", /* min= */ 0, /* max= */ 0x7fffffffUL, /* init= */ igraph_rng_rand_init, /* destroy= */ igraph_rng_rand_destroy, /* seed= */ igraph_rng_rand_seed, /* get= */ igraph_rng_rand_get, /* get_real= */ igraph_rng_rand_get_real, /* get_norm= */ 0, /* get_geom= */ 0, /* get_binom= */ 0, /* get_exp= */ 0, /* get_gamma= */ 0 }; /* ------------------------------------ */ #define N 624 /* Period parameters */ #define M 397 /* most significant w-r bits */ static const unsigned long UPPER_MASK = 0x80000000UL; /* least significant r bits */ static const unsigned long LOWER_MASK = 0x7fffffffUL; typedef struct { unsigned long mt[N]; int mti; } igraph_i_rng_mt19937_state_t; static unsigned long int igraph_rng_mt19937_get(void *vstate) { igraph_i_rng_mt19937_state_t *state = vstate; unsigned long k ; unsigned long int *const mt = state->mt; #define MAGIC(y) (((y)&0x1) ? 0x9908b0dfUL : 0) if (state->mti >= N) { /* generate N words at one time */ int kk; for (kk = 0; kk < N - M; kk++) { unsigned long y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); mt[kk] = mt[kk + M] ^ (y >> 1) ^ MAGIC(y); } for (; kk < N - 1; kk++) { unsigned long y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ MAGIC(y); } { unsigned long y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK); mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ MAGIC(y); } state->mti = 0; } #undef MAGIC /* Tempering */ k = mt[state->mti]; k ^= (k >> 11); k ^= (k << 7) & 0x9d2c5680UL; k ^= (k << 15) & 0xefc60000UL; k ^= (k >> 18); state->mti++; return k; } static igraph_real_t igraph_rng_mt19937_get_real(void *vstate) { return igraph_rng_mt19937_get (vstate) / 4294967296.0 ; } static int igraph_rng_mt19937_seed(void *vstate, unsigned long int seed) { igraph_i_rng_mt19937_state_t *state = vstate; int i; memset(state, 0, sizeof(igraph_i_rng_mt19937_state_t)); if (seed == 0) { seed = 4357; /* the default seed is 4357 */ } state->mt[0] = seed & 0xffffffffUL; for (i = 1; i < N; i++) { /* See Knuth's "Art of Computer Programming" Vol. 2, 3rd Ed. p.106 for multiplier. */ state->mt[i] = (1812433253UL * (state->mt[i - 1] ^ (state->mt[i - 1] >> 30)) + (unsigned long) i); state->mt[i] &= 0xffffffffUL; } state->mti = i; return IGRAPH_SUCCESS; } static int igraph_rng_mt19937_init(void **state) { igraph_i_rng_mt19937_state_t *st; st = IGRAPH_CALLOC(1, igraph_i_rng_mt19937_state_t); if (!st) { IGRAPH_ERROR("Cannot initialize RNG", IGRAPH_ENOMEM); } (*state) = st; igraph_rng_mt19937_seed(st, 0); return IGRAPH_SUCCESS; } static void igraph_rng_mt19937_destroy(void *vstate) { igraph_i_rng_mt19937_state_t *state = (igraph_i_rng_mt19937_state_t*) vstate; IGRAPH_FREE(state); } /** * \var igraph_rngtype_mt19937 * \brief The MT19937 random number generator. * * The MT19937 generator of Makoto Matsumoto and Takuji Nishimura is a * variant of the twisted generalized feedback shift-register * algorithm, and is known as the “Mersenne Twister” generator. It has * a Mersenne prime period of 2^19937 - 1 (about 10^6000) and is * equi-distributed in 623 dimensions. It has passed the diehard * statistical tests. It uses 624 words of state per generator and is * comparable in speed to the other generators. The original generator * used a default seed of 4357 and choosing \c s equal to zero in * \c gsl_rng_set reproduces this. Later versions switched to 5489 as the * default seed, you can choose this explicitly via \ref igraph_rng_seed() * instead if you require it. * * * For more information see, * Makoto Matsumoto and Takuji Nishimura, “Mersenne Twister: A * 623-dimensionally equidistributed uniform pseudorandom number * generator”. ACM Transactions on Modeling and Computer Simulation, * Vol. 8, No. 1 (Jan. 1998), Pages 3–30 * * * The generator \c igraph_rngtype_mt19937 uses the second revision of the * seeding procedure published by the two authors above in 2002. The * original seeding procedures could cause spurious artifacts for some * seed values. * * * This generator was ported from the GNU Scientific Library. */ const igraph_rng_type_t igraph_rngtype_mt19937 = { /* name= */ "MT19937", /* min= */ 0, /* max= */ 0xffffffffUL, /* init= */ igraph_rng_mt19937_init, /* destroy= */ igraph_rng_mt19937_destroy, /* seed= */ igraph_rng_mt19937_seed, /* get= */ igraph_rng_mt19937_get, /* get_real= */ igraph_rng_mt19937_get_real, /* get_norm= */ 0, /* get_geom= */ 0, /* get_binom= */ 0, /* get_exp= */ 0, /* get_gamma= */ 0 }; #undef N #undef M /* ------------------------------------ */ igraph_i_rng_mt19937_state_t igraph_i_rng_default_state; #define addr(a) (&a) /** * \var igraph_i_rng_default * The default igraph random number generator * * This generator is used by all builtin igraph functions that need to * generate random numbers; e.g. all random graph generators. * * You can use \ref igraph_i_rng_default with \ref igraph_rng_seed() * to set its seed. * * You can change the default generator using the \ref * igraph_rng_set_default() function. */ IGRAPH_THREAD_LOCAL igraph_rng_t igraph_i_rng_default = { addr(igraph_rngtype_mt19937), addr(igraph_i_rng_default_state), /* def= */ 1 }; #undef addr /** * \function igraph_rng_set_default * \brief Set the default igraph random number generator. * * \param rng The random number generator to use as default from now * on. Calling \ref igraph_rng_destroy() on it, while it is still * being used as the default will result in crashes and/or * unpredictable results. * * Time complexity: O(1). */ void igraph_rng_set_default(igraph_rng_t *rng) { igraph_i_rng_default = (*rng); } /* ------------------------------------ */ /** * \function igraph_rng_default * \brief Query the default random number generator. * * \return A pointer to the default random number generator. * * \sa igraph_rng_set_default() */ igraph_rng_t *igraph_rng_default(void) { return &igraph_i_rng_default; } /* ------------------------------------ */ static double igraph_norm_rand(igraph_rng_t *rng); static double igraph_rgeom(igraph_rng_t *rng, double p); static double igraph_rbinom(igraph_rng_t *rng, double nin, double pp); static double igraph_rexp(igraph_rng_t *rng, double rate); static double igraph_rgamma(igraph_rng_t *rng, double shape, double scale); /** * \function igraph_rng_init * \brief Initialize a random number generator. * * This function allocates memory for a random number generator, with * the given type, and sets its seed to the default. * * \param rng Pointer to an uninitialized RNG. * \param type The type of the RNG, like \ref igraph_rngtype_glibc2, * \ref igraph_rngtype_mt19937 or \ref igraph_rngtype_rand. * \return Error code. * * Time complexity: depends on the type of the generator, but usually * it should be O(1). */ int igraph_rng_init(igraph_rng_t *rng, const igraph_rng_type_t *type) { rng->type = type; IGRAPH_CHECK(rng->type->init(&rng->state)); return IGRAPH_SUCCESS; } /** * \function igraph_rng_destroy * \brief Deallocate memory associated with a random number generator. * * \param rng The RNG to destroy. Do not destroy an RNG that is used * as the default igraph RNG. * * Time complexity: O(1). */ void igraph_rng_destroy(igraph_rng_t *rng) { rng->type->destroy(rng->state); } /** * \function igraph_rng_seed * \brief Set the seed of a random number generator. * * \param rng The RNG. * \param seed The new seed. * \return Error code. * * Time complexity: usually O(1), but may depend on the type of the * RNG. */ int igraph_rng_seed(igraph_rng_t *rng, unsigned long int seed) { const igraph_rng_type_t *type = rng->type; rng->def = 0; IGRAPH_CHECK(type->seed(rng->state, seed)); return IGRAPH_SUCCESS; } /** * \function igraph_rng_max * \brief Query the maximum possible integer for a random number generator. * * \param rng The RNG. * \return The largest possible integer that can be generated by * calling \ref igraph_rng_get_integer() on the RNG. * * Time complexity: O(1). */ unsigned long int igraph_rng_max(igraph_rng_t *rng) { const igraph_rng_type_t *type = rng->type; return type->max; } /** * \function igraph_rng_min * \brief Query the minimum possible integer for a random number generator. * * This function will be removed in a future version. Assume zero * as the retun value. * * \param rng The RNG. * \return The smallest possible integer that can be generated by * calling \ref igraph_rng_get_integer() on the RNG. * * Time complexity: O(1). * * \deprecated 0.9.3 */ unsigned long int igraph_rng_min(igraph_rng_t *rng) { const igraph_rng_type_t *type = rng->type; IGRAPH_WARNING("igraph_rng_min() is deprecated; assume 0 as the return value."); return type->min; } /** * \function igraph_rng_name * \brief Query the type of a random number generator. * * \param rng The RNG. * \return The name of the type of the generator. Do not deallocate or * change the returned string pointer. * * Time complexity: O(1). */ const char *igraph_rng_name(igraph_rng_t *rng) { const igraph_rng_type_t *type = rng->type; return type->name; } /** * \function igraph_rng_get_integer * \brief Generate an integer random number from an interval. * * \param rng Pointer to the RNG to use for the generation. Use \ref * igraph_rng_default() here to use the default igraph RNG. * \param l Lower limit, inclusive, it can be negative as well. * \param h Upper limit, inclusive, it can be negative as well, but it * should be at least l. * \return The generated random integer. * * Time complexity: depends on the generator, but should be usually * O(1). */ long int igraph_rng_get_integer(igraph_rng_t *rng, long int l, long int h) { const igraph_rng_type_t *type = rng->type; /* We require the random integer to be in the range [l, h]. We do so by * first casting (truncate toward zero) to the range [0, h - l] and then add * l to arrive at the range [l, h]. That is, we calculate * (long)( r * (h - l + 1) ) + l * instead of * (long)( r * (h - l + 1) + l), * please note the difference in the parentheses. * * In the latter formulation, if l is negative, this would incorrectly lead * to the range [l + 1, h] instead of the desired [l, h] because negative * numbers are truncated towards zero when cast. For example, if l = -5, any * real in the range (-5, -4] would get cast to -4, not to -5. */ if (type->get_real) { return (long int)(type->get_real(rng->state) * (h - l + 1)) + l; } else if (type->get) { unsigned long int max = type->max; return (long int)(type->get(rng->state) / ((double)max + 1) * (h - l + 1)) + l; } IGRAPH_FATAL("Internal random generator error"); } /** * \function igraph_rng_get_normal * \brief Normally distributed random numbers. * * \param rng Pointer to the RNG to use. Use \ref igraph_rng_default() * here to use the default igraph RNG. * \param m The mean. * \param s Standard deviation. * \return The generated normally distributed random number. * * Time complexity: depends on the type of the RNG. */ igraph_real_t igraph_rng_get_normal(igraph_rng_t *rng, igraph_real_t m, igraph_real_t s) { const igraph_rng_type_t *type = rng->type; if (type->get_norm) { return type->get_norm(rng->state) * s + m; } else { return igraph_norm_rand(rng) * s + m; } } /** * \function igraph_rng_get_unif * \brief Generate real, uniform random numbers from an interval. * * \param rng Pointer to the RNG to use. Use \ref igraph_rng_default() * here to use the default igraph RNG. * \param l The lower bound, it can be negative. * \param h The upper bound, it can be negative, but it has to be * larger than the lower bound. * \return The generated uniformly distributed random number. * * Time complexity: depends on the type of the RNG. */ igraph_real_t igraph_rng_get_unif(igraph_rng_t *rng, igraph_real_t l, igraph_real_t h) { const igraph_rng_type_t *type = rng->type; if (type->get_real) { return type->get_real(rng->state) * (h - l) + l; } else if (type->get) { unsigned long int max = type->max; return type->get(rng->state) / ((double)max + 1) * (double)(h - l) + l; } IGRAPH_FATAL("Internal random generator error"); } /** * \function igraph_rng_get_unif01 * \brief Generate real, uniform random number from the unit interval. * * \param rng Pointer to the RNG to use. Use \ref igraph_rng_default() * here to use the default igraph RNG. * \return The generated uniformly distributed random number. * * Time complexity: depends on the type of the RNG. */ igraph_real_t igraph_rng_get_unif01(igraph_rng_t *rng) { const igraph_rng_type_t *type = rng->type; if (type->get_real) { return type->get_real(rng->state); } else if (type->get) { unsigned long int max = type->max; return type->get(rng->state) / ((double)max + 1); } IGRAPH_FATAL("Internal random generator error"); } /** * \function igraph_rng_get_geom * \brief Generate geometrically distributed random numbers. * * \param rng Pointer to the RNG to use. Use \ref igraph_rng_default() * here to use the default igraph RNG. * \param p The probability of success in each trial. Must be larger * than zero and smaller or equal to 1. * \return The generated geometrically distributed random number. * * Time complexity: depends on the type of the RNG. */ igraph_real_t igraph_rng_get_geom(igraph_rng_t *rng, igraph_real_t p) { const igraph_rng_type_t *type = rng->type; if (type->get_geom) { return type->get_geom(rng->state, p); } else { return igraph_rgeom(rng, p); } } /** * \function igraph_rng_get_binom * \brief Generate binomially distributed random numbers. * * \param rng Pointer to the RNG to use. Use \ref igraph_rng_default() * here to use the default igraph RNG. * \param n Number of observations. * \param p Probability of an event. * \return The generated binomially distributed random number. * * Time complexity: depends on the type of the RNG. */ igraph_real_t igraph_rng_get_binom(igraph_rng_t *rng, long int n, igraph_real_t p) { const igraph_rng_type_t *type = rng->type; if (type->get_binom) { return type->get_binom(rng->state, n, p); } else { return igraph_rbinom(rng, n, p); } } /** * \function igraph_rng_get_gamma * \brief Generate sample from a Gamma distribution. * * \param rng Pointer to the RNG to use. Use \ref igraph_rng_default() * here to use the default igraph RNG. * \param shape Shape parameter. * \param scale Scale parameter. * \return The generated sample * * Time complexity: depends on RNG. */ igraph_real_t igraph_rng_get_gamma(igraph_rng_t *rng, igraph_real_t shape, igraph_real_t scale) { const igraph_rng_type_t *type = rng->type; if (type->get_gamma) { return type->get_gamma(rng->state, shape, scale); } else { return igraph_rgamma(rng, shape, scale); } } unsigned long int igraph_rng_get_int31(igraph_rng_t *rng) { const igraph_rng_type_t *type = rng->type; unsigned long int max = type->max; if (type->get && max == 0x7FFFFFFFUL) { return type->get(rng->state); } else if (type->get_real) { return (unsigned long int) (type->get_real(rng->state) * 0x7FFFFFFFUL); } else { return (unsigned long int) (igraph_rng_get_unif01(rng) * 0x7FFFFFFFUL); } } igraph_real_t igraph_rng_get_exp(igraph_rng_t *rng, igraph_real_t rate) { const igraph_rng_type_t *type = rng->type; if (type->get_exp) { return type->get_exp(rng->state, rate); } else { return igraph_rexp(rng, rate); } } /* * \ingroup internal * * This function appends the rest of the needed random number to the * result vector. */ static int igraph_i_random_sample_alga(igraph_vector_t *res, igraph_integer_t l, igraph_integer_t h, igraph_integer_t length) { igraph_real_t N = h - l + 1; igraph_real_t n = length; igraph_real_t top = N - n; igraph_real_t Nreal = N; igraph_real_t S = 0; igraph_real_t V, quot; l = l - 1; while (n >= 2) { V = RNG_UNIF01(); S = 1; quot = top / Nreal; while (quot > V) { S += 1; top = -1.0 + top; Nreal = -1.0 + Nreal; quot = (quot * top) / Nreal; } l += S; igraph_vector_push_back(res, l); /* allocated */ Nreal = -1.0 + Nreal; n = -1 + n; } S = floor(round(Nreal) * RNG_UNIF01()); l += S + 1; igraph_vector_push_back(res, l); /* allocated */ return IGRAPH_SUCCESS; } /** * \ingroup nongraph * \function igraph_random_sample * \brief Generates an increasing random sequence of integers. * * * This function generates an increasing sequence of random integer * numbers from a given interval. The algorithm is taken literally * from (Vitter 1987). This method can be used for generating numbers from a * \em very large interval. It is primarily created for randomly * selecting some edges from the sometimes huge set of possible edges * in a large graph. * * Note that the type of the lower and the upper limit is \c igraph_real_t, * not \c igraph_integer_t. This does not mean that you can pass fractional * numbers there; these values must still be integral, but we need the * longer range of \c igraph_real_t in several places in the library * (for instance, when generating Erdos-Renyi graphs). * \param res Pointer to an initialized vector. This will hold the * result. It will be resized to the proper size. * \param l The lower limit of the generation interval (inclusive). This must * be less than or equal to the upper limit, and it must be integral. * Passing a fractional number here results in undefined behaviour. * \param h The upper limit of the generation interval (inclusive). This must * be greater than or equal to the lower limit, and it must be integral. * Passing a fractional number here results in undefined behaviour. * \param length The number of random integers to generate. * \return The error code \c IGRAPH_EINVAL is returned in each of the * following cases: (1) The given lower limit is greater than the * given upper limit, i.e. \c l > \c h. (2) Assuming that * \c l < \c h and N is the sample size, the above error code is * returned if N > |\c h - \c l|, i.e. the sample size exceeds the * size of the candidate pool. * * Time complexity: according to (Vitter 1987), the expected * running time is O(length). * * * Reference: * \clist * \cli (Vitter 1987) * J. S. Vitter. An efficient algorithm for sequential random sampling. * \emb ACM Transactions on Mathematical Software, \eme 13(1):58--67, 1987. * \endclist * * \example examples/simple/igraph_random_sample.c */ int igraph_random_sample(igraph_vector_t *res, igraph_real_t l, igraph_real_t h, igraph_integer_t length) { igraph_real_t N = h - l + 1; igraph_real_t n = length; int retval; igraph_real_t nreal = length; igraph_real_t ninv = (nreal != 0) ? 1.0 / nreal : 0.0; igraph_real_t Nreal = N; igraph_real_t Vprime; igraph_real_t qu1 = -n + 1 + N; igraph_real_t qu1real = -nreal + 1.0 + Nreal; igraph_real_t negalphainv = -13; igraph_real_t threshold = -negalphainv * n; igraph_real_t S; /* getting back some sense of sanity */ if (l > h) { IGRAPH_ERROR("Lower limit is greater than upper limit", IGRAPH_EINVAL); } /* now we know that l <= h */ if (length > N) { IGRAPH_ERROR("Sample size exceeds size of candidate pool", IGRAPH_EINVAL); } /* treat rare cases quickly */ if (l == h) { IGRAPH_CHECK(igraph_vector_resize(res, 1)); VECTOR(*res)[0] = l; return IGRAPH_SUCCESS; } if (length == 0) { igraph_vector_clear(res); return IGRAPH_SUCCESS; } if (length == N) { long int i = 0; IGRAPH_CHECK(igraph_vector_resize(res, length)); for (i = 0; i < length; i++) { VECTOR(*res)[i] = l++; } return IGRAPH_SUCCESS; } igraph_vector_clear(res); IGRAPH_CHECK(igraph_vector_reserve(res, length)); RNG_BEGIN(); Vprime = exp(log(RNG_UNIF01()) * ninv); l = l - 1; while (n > 1 && threshold < N) { igraph_real_t X, U; igraph_real_t limit, t; igraph_real_t negSreal, y1, y2, top, bottom; igraph_real_t nmin1inv = 1.0 / (-1.0 + nreal); while (1) { while (1) { X = Nreal * (-Vprime + 1.0); S = floor(X); /* if (S==0) { S=1; } */ if (S < qu1) { break; } Vprime = exp(log(RNG_UNIF01()) * ninv); } U = RNG_UNIF01(); negSreal = -S; y1 = exp(log(U * Nreal / qu1real) * nmin1inv); Vprime = y1 * (-X / Nreal + 1.0) * (qu1real / (negSreal + qu1real)); if (Vprime <= 1.0) { break; } y2 = 1.0; top = -1.0 + Nreal; if (-1 + n > S) { bottom = -nreal + Nreal; limit = -S + N; } else { bottom = -1.0 + negSreal + Nreal; limit = qu1; } for (t = -1 + N; t >= limit; t--) { y2 = (y2 * top) / bottom; top = -1.0 + top; bottom = -1.0 + bottom; } if (Nreal / (-X + Nreal) >= y1 * exp(log(y2)*nmin1inv)) { Vprime = exp(log(RNG_UNIF01()) * nmin1inv); break; } Vprime = exp(log(RNG_UNIF01()) * ninv); } l += S + 1; igraph_vector_push_back(res, l); /* allocated */ N = -S + (-1 + N); Nreal = negSreal + (-1.0 + Nreal); n = -1 + n; nreal = -1.0 + nreal; ninv = nmin1inv; qu1 = -S + qu1; qu1real = negSreal + qu1real; threshold = threshold + negalphainv; } if (n > 1) { retval = igraph_i_random_sample_alga(res, (igraph_integer_t) l + 1, (igraph_integer_t) h, (igraph_integer_t) n); } else { retval = 0; S = floor(N * Vprime); l += S + 1; igraph_vector_push_back(res, l); /* allocated */ } RNG_END(); return retval; } /* * Mathlib : A C Library of Special Functions * Copyright (C) 1998 Ross Ihaka * Copyright (C) 2000 The R Development Core Team * based on AS 111 (C) 1977 Royal Statistical Society * and on AS 241 (C) 1988 Royal Statistical Society * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * SYNOPSIS * * double qnorm5(double p, double mu, double sigma, * int lower_tail, int log_p) * {qnorm (..) is synonymous and preferred inside R} * * DESCRIPTION * * Compute the quantile function for the normal distribution. * * For small to moderate probabilities, algorithm referenced * below is used to obtain an initial approximation which is * polished with a final Newton step. * * For very large arguments, an algorithm of Wichura is used. * * REFERENCE * * Beasley, J. D. and S. G. Springer (1977). * Algorithm AS 111: The percentage points of the normal distribution, * Applied Statistics, 26, 118-121. * * Wichura, M.J. (1988). * Algorithm AS 241: The Percentage Points of the Normal Distribution. * Applied Statistics, 37, 477-484. */ /* * Mathlib : A C Library of Special Functions * Copyright (C) 1998-2004 The R Development Core Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* Private header file for use during compilation of Mathlib */ #ifndef MATHLIB_PRIVATE_H #define MATHLIB_PRIVATE_H #define ML_POSINF IGRAPH_INFINITY #define ML_NEGINF -IGRAPH_INFINITY #define ML_NAN IGRAPH_NAN #define ML_ERROR(x) /* nothing */ #define ML_UNDERFLOW (DBL_MIN * DBL_MIN) #define ML_VALID(x) (!ISNAN(x)) #define ME_NONE 0 /* no error */ #define ME_DOMAIN 1 /* argument out of domain */ #define ME_RANGE 2 /* value out of range */ #define ME_NOCONV 4 /* process did not converge */ #define ME_PRECISION 8 /* does not have "full" precision */ #define ME_UNDERFLOW 16 /* and underflow occurred (important for IEEE)*/ #define ML_ERR_return_NAN { ML_ERROR(ME_DOMAIN); return ML_NAN; } /* Wilcoxon Rank Sum Distribution */ #define WILCOX_MAX 50 /* Wilcoxon Signed Rank Distribution */ #define SIGNRANK_MAX 50 /* Formerly private part of Mathlib.h */ /* always remap internal functions */ #define bd0 Rf_bd0 #define chebyshev_eval Rf_chebyshev_eval #define chebyshev_init Rf_chebyshev_init #define i1mach Rf_i1mach #define gammalims Rf_gammalims #define lfastchoose Rf_lfastchoose #define lgammacor Rf_lgammacor #define stirlerr Rf_stirlerr /* Chebyshev Series */ int chebyshev_init(double*, int, double); double chebyshev_eval(double, const double *, const int); /* Gamma and Related Functions */ void gammalims(double*, double*); double lgammacor(double); /* log(gamma) correction */ double stirlerr(double); /* Stirling expansion "error" */ double lfastchoose(double, double); double bd0(double, double); /* Consider adding these two to the API (Rmath.h): */ double dbinom_raw(double, double, double, double, int); double dpois_raw (double, double, int); double pnchisq_raw(double, double, double, double, double, int); int i1mach(int); /* From toms708.c */ void bratio(double a, double b, double x, double y, double *w, double *w1, int *ierr); #endif /* MATHLIB_PRIVATE_H */ /* Utilities for `dpq' handling (density/probability/quantile) */ /* give_log in "d"; log_p in "p" & "q" : */ #define give_log log_p /* "DEFAULT" */ /* --------- */ #define R_D__0 (log_p ? ML_NEGINF : 0.) /* 0 */ #define R_D__1 (log_p ? 0. : 1.) /* 1 */ #define R_DT_0 (lower_tail ? R_D__0 : R_D__1) /* 0 */ #define R_DT_1 (lower_tail ? R_D__1 : R_D__0) /* 1 */ #define R_D_Lval(p) (lower_tail ? (p) : (1 - (p))) /* p */ #define R_D_Cval(p) (lower_tail ? (1 - (p)) : (p)) /* 1 - p */ #define R_D_val(x) (log_p ? log(x) : (x)) /* x in pF(x,..) */ #define R_D_qIv(p) (log_p ? exp(p) : (p)) /* p in qF(p,..) */ #define R_D_exp(x) (log_p ? (x) : exp(x)) /* exp(x) */ #define R_D_log(p) (log_p ? (p) : log(p)) /* log(p) */ #define R_D_Clog(p) (log_p ? log1p(-(p)) : (1 - (p)))/* [log](1-p) */ /* log(1-exp(x)): R_D_LExp(x) == (log1p(- R_D_qIv(x))) but even more stable:*/ #define R_D_LExp(x) (log_p ? R_Log1_Exp(x) : log1p(-x)) /*till 1.8.x: * #define R_DT_val(x) R_D_val(R_D_Lval(x)) * #define R_DT_Cval(x) R_D_val(R_D_Cval(x)) */ #define R_DT_val(x) (lower_tail ? R_D_val(x) : R_D_Clog(x)) #define R_DT_Cval(x) (lower_tail ? R_D_Clog(x) : R_D_val(x)) /*#define R_DT_qIv(p) R_D_Lval(R_D_qIv(p)) * p in qF ! */ #define R_DT_qIv(p) (log_p ? (lower_tail ? exp(p) : - expm1(p)) \ : R_D_Lval(p)) /*#define R_DT_CIv(p) R_D_Cval(R_D_qIv(p)) * 1 - p in qF */ #define R_DT_CIv(p) (log_p ? (lower_tail ? -expm1(p) : exp(p)) \ : R_D_Cval(p)) #define R_DT_exp(x) R_D_exp(R_D_Lval(x)) /* exp(x) */ #define R_DT_Cexp(x) R_D_exp(R_D_Cval(x)) /* exp(1 - x) */ #define R_DT_log(p) (lower_tail? R_D_log(p) : R_D_LExp(p))/* log(p) in qF */ #define R_DT_Clog(p) (lower_tail? R_D_LExp(p): R_D_log(p))/* log(1-p) in qF*/ #define R_DT_Log(p) (lower_tail? (p) : R_Log1_Exp(p)) /* == R_DT_log when we already "know" log_p == TRUE :*/ #define R_Q_P01_check(p) \ if ((log_p && p > 0) || \ (!log_p && (p < 0 || p > 1)) ) \ ML_ERR_return_NAN /* additions for density functions (C.Loader) */ #define R_D_fexp(f,x) (give_log ? -0.5*log(f)+(x) : exp(x)/sqrt(f)) #define R_D_forceint(x) floor((x) + 0.5) #define R_D_nonint(x) (fabs((x) - floor((x)+0.5)) > 1e-7) /* [neg]ative or [non int]eger : */ #define R_D_negInonint(x) (x < 0. || R_D_nonint(x)) #define R_D_nonint_check(x) \ if(R_D_nonint(x)) { \ MATHLIB_WARNING("non-integer x = %f", x); \ return R_D__0; \ } double igraph_qnorm5(double p, double mu, double sigma, int lower_tail, int log_p) { double p_, q, r, val; #ifdef IEEE_754 if (ISNAN(p) || ISNAN(mu) || ISNAN(sigma)) { return p + mu + sigma; } #endif if (p == R_DT_0) { return ML_NEGINF; } if (p == R_DT_1) { return ML_POSINF; } R_Q_P01_check(p); if (sigma < 0) { ML_ERR_return_NAN; } if (sigma == 0) { return mu; } p_ = R_DT_qIv(p);/* real lower_tail prob. p */ q = p_ - 0.5; /*-- use AS 241 --- */ /* double ppnd16_(double *p, long *ifault)*/ /* ALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3 Produces the normal deviate Z corresponding to a given lower tail area of P; Z is accurate to about 1 part in 10**16. (original fortran code used PARAMETER(..) for the coefficients and provided hash codes for checking them...) */ if (fabs(q) <= .425) {/* 0.075 <= p <= 0.925 */ r = .180625 - q * q; val = q * (((((((r * 2509.0809287301226727 + 33430.575583588128105) * r + 67265.770927008700853) * r + 45921.953931549871457) * r + 13731.693765509461125) * r + 1971.5909503065514427) * r + 133.14166789178437745) * r + 3.387132872796366608) / (((((((r * 5226.495278852854561 + 28729.085735721942674) * r + 39307.89580009271061) * r + 21213.794301586595867) * r + 5394.1960214247511077) * r + 687.1870074920579083) * r + 42.313330701600911252) * r + 1.); } else { /* closer than 0.075 from {0,1} boundary */ /* r = min(p, 1-p) < 0.075 */ if (q > 0) { r = R_DT_CIv(p); /* 1-p */ } else { r = p_; /* = R_DT_Iv(p) ^= p */ } r = sqrt(- ((log_p && ((lower_tail && q <= 0) || (!lower_tail && q > 0))) ? p : /* else */ log(r))); /* r = sqrt(-log(r)) <==> min(p, 1-p) = exp( - r^2 ) */ if (r <= 5.) { /* <==> min(p,1-p) >= exp(-25) ~= 1.3888e-11 */ r += -1.6; val = (((((((r * 7.7454501427834140764e-4 + .0227238449892691845833) * r + .24178072517745061177) * r + 1.27045825245236838258) * r + 3.64784832476320460504) * r + 5.7694972214606914055) * r + 4.6303378461565452959) * r + 1.42343711074968357734) / (((((((r * 1.05075007164441684324e-9 + 5.475938084995344946e-4) * r + .0151986665636164571966) * r + .14810397642748007459) * r + .68976733498510000455) * r + 1.6763848301838038494) * r + 2.05319162663775882187) * r + 1.); } else { /* very close to 0 or 1 */ r += -5.; val = (((((((r * 2.01033439929228813265e-7 + 2.71155556874348757815e-5) * r + .0012426609473880784386) * r + .026532189526576123093) * r + .29656057182850489123) * r + 1.7848265399172913358) * r + 5.4637849111641143699) * r + 6.6579046435011037772) / (((((((r * 2.04426310338993978564e-15 + 1.4215117583164458887e-7) * r + 1.8463183175100546818e-5) * r + 7.868691311456132591e-4) * r + .0148753612908506148525) * r + .13692988092273580531) * r + .59983220655588793769) * r + 1.); } if (q < 0.0) { val = -val; } /* return (q >= 0.)? r : -r ;*/ } return mu + sigma * val; } static double fsign(double x, double y) { #ifdef IEEE_754 if (ISNAN(x) || ISNAN(y)) { return x + y; } #endif return ((y >= 0) ? fabs(x) : -fabs(x)); } static int imax2(int x, int y) { return (x < y) ? y : x; } static int imin2(int x, int y) { return (x < y) ? x : y; } static double igraph_norm_rand(igraph_rng_t *rng) { double u1; #define BIG 134217728 /* 2^27 */ /* unif_rand() alone is not of high enough precision */ u1 = igraph_rng_get_unif01(rng); u1 = (int)(BIG * u1) + igraph_rng_get_unif01(rng); return igraph_qnorm5(u1 / BIG, 0.0, 1.0, 1, 0); } /* * Mathlib : A C Library of Special Functions * Copyright (C) 1998 Ross Ihaka * Copyright (C) 2000-2002 the R Development Core Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * SYNOPSIS * * #include * double exp_rand(void); * * DESCRIPTION * * Random variates from the standard exponential distribution. * * REFERENCE * * Ahrens, J.H. and Dieter, U. (1972). * Computer methods for sampling from the exponential and * normal distributions. * Comm. ACM, 15, 873-882. */ double igraph_exp_rand(igraph_rng_t *rng) { /* q[k-1] = sum(log(2)^k / k!) k=1,..,n, */ /* The highest n (here 8) is determined by q[n-1] = 1.0 */ /* within standard precision */ const double q[] = { 0.6931471805599453, 0.9333736875190459, 0.9888777961838675, 0.9984959252914960, 0.9998292811061389, 0.9999833164100727, 0.9999985691438767, 0.9999998906925558, 0.9999999924734159, 0.9999999995283275, 0.9999999999728814, 0.9999999999985598, 0.9999999999999289, 0.9999999999999968, 0.9999999999999999, 1.0000000000000000 }; double a, u, ustar, umin; int i; a = 0.; /* precaution if u = 0 is ever returned */ u = igraph_rng_get_unif01(rng); while (u <= 0.0 || u >= 1.0) { u = igraph_rng_get_unif01(rng); } for (;;) { u += u; if (u > 1.0) { break; } a += q[0]; } u -= 1.; if (u <= q[0]) { return a + u; } i = 0; ustar = igraph_rng_get_unif01(rng); umin = ustar; do { ustar = igraph_rng_get_unif01(rng); if (ustar < umin) { umin = ustar; } i++; } while (u > q[i]); return a + umin * q[0]; } /* * Mathlib : A C Library of Special Functions * Copyright (C) 1998 Ross Ihaka * Copyright (C) 2000-2001 The R Development Core Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * SYNOPSIS * * #include * double rpois(double lambda) * * DESCRIPTION * * Random variates from the Poisson distribution. * * REFERENCE * * Ahrens, J.H. and Dieter, U. (1982). * Computer generation of Poisson deviates * from modified normal distributions. * ACM Trans. Math. Software 8, 163-179. */ #define a0 -0.5 #define a1 0.3333333 #define a2 -0.2500068 #define a3 0.2000118 #define a4 -0.1661269 #define a5 0.1421878 #define a6 -0.1384794 #define a7 0.1250060 #define one_7 0.1428571428571428571 #define one_12 0.0833333333333333333 #define one_24 0.0416666666666666667 #define repeat for(;;) #define FALSE 0 #define TRUE 1 #define M_1_SQRT_2PI 0.398942280401432677939946059934 /* 1/sqrt(2pi) */ static double igraph_rpois(igraph_rng_t *rng, double mu) { /* Factorial Table (0:9)! */ const double fact[10] = { 1., 1., 2., 6., 24., 120., 720., 5040., 40320., 362880. }; /* These are static --- persistent between calls for same mu : */ static IGRAPH_THREAD_LOCAL int l, m; static IGRAPH_THREAD_LOCAL double b1, b2, c, c0, c1, c2, c3; static IGRAPH_THREAD_LOCAL double pp[36], p0, p, q, s, d, omega; static IGRAPH_THREAD_LOCAL double big_l;/* integer "w/o overflow" */ static IGRAPH_THREAD_LOCAL double muprev = 0., muprev2 = 0.;/*, muold = 0.*/ /* Local Vars [initialize some for -Wall]: */ double del, difmuk = 0., E = 0., fk = 0., fx, fy, g, px, py, t, u = 0., v, x; double pois = -1.; int k, kflag, big_mu, new_big_mu = FALSE; if (!igraph_finite(mu)) { ML_ERR_return_NAN; } if (mu <= 0.) { return 0.; } big_mu = mu >= 10.; if (big_mu) { new_big_mu = FALSE; } if (!(big_mu && mu == muprev)) {/* maybe compute new persistent par.s */ if (big_mu) { new_big_mu = TRUE; /* Case A. (recalculation of s,d,l because mu has changed): * The Poisson probabilities pk exceed the discrete normal * probabilities fk whenever k >= m(mu). */ muprev = mu; s = sqrt(mu); d = 6. * mu * mu; big_l = floor(mu - 1.1484); /* = an upper bound to m(mu) for all mu >= 10.*/ } else { /* Small mu ( < 10) -- not using normal approx. */ /* Case B. (start new table and calculate p0 if necessary) */ /*muprev = 0.;-* such that next time, mu != muprev ..*/ if (mu != muprev) { muprev = mu; m = imax2(1, (int) mu); l = 0; /* pp[] is already ok up to pp[l] */ q = p0 = p = exp(-mu); } repeat { /* Step U. uniform sample for inversion method */ u = igraph_rng_get_unif01(rng); if (u <= p0) { return 0.; } /* Step T. table comparison until the end pp[l] of the pp-table of cumulative Poisson probabilities (0.458 > ~= pp[9](= 0.45792971447) for mu=10 ) */ if (l != 0) { for (k = (u <= 0.458) ? 1 : imin2(l, m); k <= l; k++) if (u <= pp[k]) { return (double)k; } if (l == 35) { /* u > pp[35] */ continue; } } /* Step C. creation of new Poisson probabilities p[l..] and their cumulatives q =: pp[k] */ l++; for (k = l; k <= 35; k++) { p *= mu / k; q += p; pp[k] = q; if (u <= q) { l = k; return (double)k; } } l = 35; } /* end(repeat) */ }/* mu < 10 */ } /* end {initialize persistent vars} */ /* Only if mu >= 10 : ----------------------- */ /* Step N. normal sample */ g = mu + s * igraph_norm_rand(rng);/* norm_rand() ~ N(0,1), standard normal */ if (g >= 0.) { pois = floor(g); /* Step I. immediate acceptance if pois is large enough */ if (pois >= big_l) { return pois; } /* Step S. squeeze acceptance */ fk = pois; difmuk = mu - fk; u = igraph_rng_get_unif01(rng); /* ~ U(0,1) - sample */ if (d * u >= difmuk * difmuk * difmuk) { return pois; } } /* Step P. preparations for steps Q and H. (recalculations of parameters if necessary) */ if (new_big_mu || mu != muprev2) { /* Careful! muprev2 is not always == muprev because one might have exited in step I or S */ muprev2 = mu; omega = M_1_SQRT_2PI / s; /* The quantities b1, b2, c3, c2, c1, c0 are for the Hermite * approximations to the discrete normal probabilities fk. */ b1 = one_24 / mu; b2 = 0.3 * b1 * b1; c3 = one_7 * b1 * b2; c2 = b2 - 15. * c3; c1 = b1 - 6. * b2 + 45. * c3; c0 = 1. - b1 + 3. * b2 - 15. * c3; c = 0.1069 / mu; /* guarantees majorization by the 'hat'-function. */ } if (g >= 0.) { /* 'Subroutine' F is called (kflag=0 for correct return) */ kflag = 0; goto Step_F; } repeat { /* Step E. Exponential Sample */ E = igraph_exp_rand(rng);/* ~ Exp(1) (standard exponential) */ /* sample t from the laplace 'hat' (if t <= -0.6744 then pk < fk for all mu >= 10.) */ u = 2 * igraph_rng_get_unif01(rng) - 1.; t = 1.8 + fsign(E, u); if (t > -0.6744) { pois = floor(mu + s * t); fk = pois; difmuk = mu - fk; /* 'subroutine' F is called (kflag=1 for correct return) */ kflag = 1; Step_F: /* 'subroutine' F : calculation of px,py,fx,fy. */ if (pois < 10) { /* use factorials from table fact[] */ px = -mu; py = pow(mu, pois) / fact[(int)pois]; } else { /* Case pois >= 10 uses polynomial approximation a0-a7 for accuracy when advisable */ del = one_12 / fk; del = del * (1. - 4.8 * del * del); v = difmuk / fk; if (fabs(v) <= 0.25) px = fk * v * v * (((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v + a0) - del; else { /* |v| > 1/4 */ px = fk * log(1. + v) - difmuk - del; } py = M_1_SQRT_2PI / sqrt(fk); } x = (0.5 - difmuk) / s; x *= x;/* x^2 */ fx = -0.5 * x; fy = omega * (((c3 * x + c2) * x + c1) * x + c0); if (kflag > 0) { /* Step H. Hat acceptance (E is repeated on rejection) */ if (c * fabs(u) <= py * exp(px + E) - fy * exp(fx + E)) { break; } } else /* Step Q. Quotient acceptance (rare case) */ if (fy - u * fy <= py * exp(px - fx)) { break; } }/* t > -.67.. */ } return pois; } #undef a1 #undef a2 #undef a3 #undef a4 #undef a5 #undef a6 #undef a7 static double igraph_rgeom(igraph_rng_t *rng, double p) { if (igraph_is_nan(p) || p <= 0 || p > 1) { ML_ERR_return_NAN; } return igraph_rpois(rng, igraph_exp_rand(rng) * ((1 - p) / p)); } /* This is from nmath/rbinom.c */ #define repeat for(;;) static double igraph_rbinom(igraph_rng_t *rng, double nin, double pp) { /* FIXME: These should become THREAD_specific globals : */ static IGRAPH_THREAD_LOCAL double c, fm, npq, p1, p2, p3, p4, qn; static IGRAPH_THREAD_LOCAL double xl, xll, xlr, xm, xr; static IGRAPH_THREAD_LOCAL double psave = -1.0; static IGRAPH_THREAD_LOCAL int nsave = -1; static IGRAPH_THREAD_LOCAL int m; double f, f1, f2, u, v, w, w2, x, x1, x2, z, z2; double p, q, np, g, r, al, alv, amaxp, ffm, ynorm; int i, ix, k, n; if (!igraph_finite(nin)) { ML_ERR_return_NAN; } n = floor(nin + 0.5); if (n != nin) { ML_ERR_return_NAN; } if (!igraph_finite(pp) || /* n=0, p=0, p=1 are not errors */ n < 0 || pp < 0. || pp > 1.) { ML_ERR_return_NAN; } if (n == 0 || pp == 0.) { return 0; } if (pp == 1.) { return n; } p = fmin(pp, 1. - pp); q = 1. - p; np = n * p; r = p / q; g = r * (n + 1); /* Setup, perform only when parameters change [using static (globals): */ /* FIXING: Want this thread safe -- use as little (thread globals) as possible */ if (pp != psave || n != nsave) { psave = pp; nsave = n; if (np < 30.0) { /* inverse cdf logic for mean less than 30 */ qn = pow(q, (double) n); goto L_np_small; } else { ffm = np + p; m = ffm; fm = m; npq = np * q; p1 = (int)(2.195 * sqrt(npq) - 4.6 * q) + 0.5; xm = fm + 0.5; xl = xm - p1; xr = xm + p1; c = 0.134 + 20.5 / (15.3 + fm); al = (ffm - xl) / (ffm - xl * p); xll = al * (1.0 + 0.5 * al); al = (xr - ffm) / (xr * q); xlr = al * (1.0 + 0.5 * al); p2 = p1 * (1.0 + c + c); p3 = p2 + c / xll; p4 = p3 + c / xlr; } } else if (n == nsave) { if (np < 30.0) { goto L_np_small; } } /*-------------------------- np = n*p >= 30 : ------------------- */ repeat { u = igraph_rng_get_unif01(rng) * p4; v = igraph_rng_get_unif01(rng); /* triangular region */ if (u <= p1) { ix = xm - p1 * v + u; goto finis; } /* parallelogram region */ if (u <= p2) { x = xl + (u - p1) / c; v = v * c + 1.0 - fabs(xm - x) / p1; if (v > 1.0 || v <= 0.) { continue; } ix = x; } else { if (u > p3) { /* right tail */ ix = xr - log(v) / xlr; if (ix > n) { continue; } v = v * (u - p3) * xlr; } else {/* left tail */ ix = xl + log(v) / xll; if (ix < 0) { continue; } v = v * (u - p2) * xll; } } /* determine appropriate way to perform accept/reject test */ k = abs(ix - m); if (k <= 20 || k >= npq / 2 - 1) { /* explicit evaluation */ f = 1.0; if (m < ix) { for (i = m + 1; i <= ix; i++) { f *= (g / i - r); } } else if (m != ix) { for (i = ix + 1; i <= m; i++) { f /= (g / i - r); } } if (v <= f) { goto finis; } } else { /* squeezing using upper and lower bounds on log(f(x)) */ amaxp = (k / npq) * ((k * (k / 3. + 0.625) + 0.1666666666666) / npq + 0.5); ynorm = -k * k / (2.0 * npq); alv = log(v); if (alv < ynorm - amaxp) { goto finis; } if (alv <= ynorm + amaxp) { /* Stirling's formula to machine accuracy */ /* for the final acceptance/rejection test */ x1 = ix + 1; f1 = fm + 1.0; z = n + 1 - fm; w = n - ix + 1.0; z2 = z * z; x2 = x1 * x1; f2 = f1 * f1; w2 = w * w; if (alv <= xm * log(f1 / x1) + (n - m + 0.5) * log(z / w) + (ix - m) * log(w * p / (x1 * q)) + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / f2) / f2) / f2) / f2) / f1 / 166320.0 + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / z2) / z2) / z2) / z2) / z / 166320.0 + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / x2) / x2) / x2) / x2) / x1 / 166320.0 + (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / w2) / w2) / w2) / w2) / w / 166320.) { goto finis; } } } } L_np_small: /*---------------------- np = n*p < 30 : ------------------------- */ repeat { ix = 0; f = qn; u = igraph_rng_get_unif01(rng); repeat { if (u < f) { goto finis; } if (ix > 110) { break; } u -= f; ix++; f *= (g / ix - r); } } finis: if (psave > 0.5) { ix = n - ix; } return (double)ix; } static igraph_real_t igraph_rexp(igraph_rng_t *rng, double rate) { igraph_real_t scale = 1.0 / rate; if (!IGRAPH_FINITE(scale) || scale <= 0.0) { if (scale == 0.0) { return 0.0; } return IGRAPH_NAN; } return scale * igraph_exp_rand(rng); } /* * Mathlib : A C Library of Special Functions * Copyright (C) 1998 Ross Ihaka * Copyright (C) 2000 The R Core Team * Copyright (C) 2003 The R Foundation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ * * SYNOPSIS * * double dnorm4(double x, double mu, double sigma, int give_log) * {dnorm (..) is synonymous and preferred inside R} * * DESCRIPTION * * Compute the density of the normal distribution. */ double igraph_dnorm(double x, double mu, double sigma, int give_log) { #ifdef IEEE_754 if (ISNAN(x) || ISNAN(mu) || ISNAN(sigma)) { return x + mu + sigma; } #endif if (!igraph_finite(sigma)) { return R_D__0; } if (!igraph_finite(x) && mu == x) { return ML_NAN; /* x-mu is NaN */ } if (sigma <= 0) { if (sigma < 0) { ML_ERR_return_NAN; } /* sigma == 0 */ return (x == mu) ? ML_POSINF : R_D__0; } x = (x - mu) / sigma; if (!igraph_finite(x)) { return R_D__0; } return (give_log ? -(M_LN_SQRT_2PI + 0.5 * x * x + log(sigma)) : M_1_SQRT_2PI * exp(-0.5 * x * x) / sigma); /* M_1_SQRT_2PI = 1 / sqrt(2 * pi) */ } /* This is from nmath/rgamma.c */ /* * Mathlib : A C Library of Special Functions * Copyright (C) 1998 Ross Ihaka * Copyright (C) 2000--2008 The R Core Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ * * SYNOPSIS * * #include * double rgamma(double a, double scale); * * DESCRIPTION * * Random variates from the gamma distribution. * * REFERENCES * * [1] Shape parameter a >= 1. Algorithm GD in: * * Ahrens, J.H. and Dieter, U. (1982). * Generating gamma variates by a modified * rejection technique. * Comm. ACM, 25, 47-54. * * * [2] Shape parameter 0 < a < 1. Algorithm GS in: * * Ahrens, J.H. and Dieter, U. (1974). * Computer methods for sampling from gamma, beta, * poisson and binomial distributions. * Computing, 12, 223-246. * * Input: a = parameter (mean) of the standard gamma distribution. * Output: a variate from the gamma(a)-distribution */ static double igraph_rgamma(igraph_rng_t *rng, double a, double scale) { /* Constants : */ static const double sqrt32 = 5.656854; static const double exp_m1 = 0.36787944117144232159;/* exp(-1) = 1/e */ /* Coefficients q[k] - for q0 = sum(q[k]*a^(-k)) * Coefficients a[k] - for q = q0+(t*t/2)*sum(a[k]*v^k) * Coefficients e[k] - for exp(q)-1 = sum(e[k]*q^k) */ static const double q1 = 0.04166669; static const double q2 = 0.02083148; static const double q3 = 0.00801191; static const double q4 = 0.00144121; static const double q5 = -7.388e-5; static const double q6 = 2.4511e-4; static const double q7 = 2.424e-4; static const double a1 = 0.3333333; static const double a2 = -0.250003; static const double a3 = 0.2000062; static const double a4 = -0.1662921; static const double a5 = 0.1423657; static const double a6 = -0.1367177; static const double a7 = 0.1233795; /* State variables [FIXME for threading!] :*/ static double aa = 0.; static double aaa = 0.; static double s, s2, d; /* no. 1 (step 1) */ static double q0, b, si, c;/* no. 2 (step 4) */ double e, p, q, r, t, u, v, w, x, ret_val; if (!igraph_finite(a) || !igraph_finite(scale) || a < 0.0 || scale <= 0.0) { if (scale == 0.) { return 0.; } ML_ERR_return_NAN; } if (a < 1.) { /* GS algorithm for parameters a < 1 */ if (a == 0) { return 0.; } e = 1.0 + exp_m1 * a; repeat { p = e * igraph_rng_get_unif01(rng); if (p >= 1.0) { x = -log((e - p) / a); if (igraph_exp_rand(rng) >= (1.0 - a) * log(x)) { break; } } else { x = exp(log(p) / a); if (igraph_exp_rand(rng) >= x) { break; } } } return scale * x; } /* --- a >= 1 : GD algorithm --- */ /* Step 1: Recalculations of s2, s, d if a has changed */ if (a != aa) { aa = a; s2 = a - 0.5; s = sqrt(s2); d = sqrt32 - s * 12.0; } /* Step 2: t = standard normal deviate, x = (s,1/2) -normal deviate. */ /* immediate acceptance (i) */ t = igraph_norm_rand(rng); x = s + 0.5 * t; ret_val = x * x; if (t >= 0.0) { return scale * ret_val; } /* Step 3: u = 0,1 - uniform sample. squeeze acceptance (s) */ u = igraph_rng_get_unif01(rng); if (d * u <= t * t * t) { return scale * ret_val; } /* Step 4: recalculations of q0, b, si, c if necessary */ if (a != aaa) { aaa = a; r = 1.0 / a; q0 = ((((((q7 * r + q6) * r + q5) * r + q4) * r + q3) * r + q2) * r + q1) * r; /* Approximation depending on size of parameter a */ /* The constants in the expressions for b, si and c */ /* were established by numerical experiments */ if (a <= 3.686) { b = 0.463 + s + 0.178 * s2; si = 1.235; c = 0.195 / s - 0.079 + 0.16 * s; } else if (a <= 13.022) { b = 1.654 + 0.0076 * s2; si = 1.68 / s + 0.275; c = 0.062 / s + 0.024; } else { b = 1.77; si = 0.75; c = 0.1515 / s; } } /* Step 5: no quotient test if x not positive */ if (x > 0.0) { /* Step 6: calculation of v and quotient q */ v = t / (s + s); if (fabs(v) <= 0.25) q = q0 + 0.5 * t * t * ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v; else { q = q0 - s * t + 0.25 * t * t + (s2 + s2) * log(1.0 + v); } /* Step 7: quotient acceptance (q) */ if (log(1.0 - u) <= q) { return scale * ret_val; } } repeat { /* Step 8: e = standard exponential deviate * u = 0,1 -uniform deviate * t = (b,si)-double exponential (laplace) sample */ e = igraph_exp_rand(rng); u = igraph_rng_get_unif01(rng); u = u + u - 1.0; if (u < 0.0) { t = b - si * e; } else { t = b + si * e; } /* Step 9: rejection if t < tau(1) = -0.71874483771719 */ if (t >= -0.71874483771719) { /* Step 10: calculation of v and quotient q */ v = t / (s + s); if (fabs(v) <= 0.25) q = q0 + 0.5 * t * t * ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v; else { q = q0 - s * t + 0.25 * t * t + (s2 + s2) * log(1.0 + v); } /* Step 11: hat acceptance (h) */ /* (if q not positive go to step 8) */ if (q > 0.0) { w = expm1(q); /* ^^^^^ original code had approximation with rel.err < 2e-7 */ /* if t is rejected sample again at step 8 */ if (c * fabs(u) <= w * exp(e - 0.5 * t * t)) { break; } } } } /* repeat .. until `t' is accepted */ x = s + 0.5 * t; return scale * x * x; } int igraph_rng_get_dirichlet(igraph_rng_t *rng, const igraph_vector_t *alpha, igraph_vector_t *result) { igraph_integer_t len = igraph_vector_size(alpha); igraph_integer_t j; igraph_real_t sum = 0.0; if (len < 2) { IGRAPH_ERROR("Dirichlet parameter vector too short, must " "have at least two entries", IGRAPH_EINVAL); } if (igraph_vector_min(alpha) <= 0) { IGRAPH_ERROR("Dirichlet concentration parameters must be positive", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_resize(result, len)); RNG_BEGIN(); for (j = 0; j < len; j++) { VECTOR(*result)[j] = igraph_rng_get_gamma(rng, VECTOR(*alpha)[j], 1.0); sum += VECTOR(*result)[j]; } for (j = 0; j < len; j++) { VECTOR(*result)[j] /= sum; } RNG_END(); return IGRAPH_SUCCESS; } leidenbase/src/core/properties/0000755000176200001440000000000014532173045016264 5ustar liggesusersleidenbase/src/core/properties/triangles_template1.h0000644000176200001440000000560714447675375022433 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ long int no_of_nodes = igraph_vcount(graph); igraph_vit_t vit; long int nodes_to_calc; igraph_vector_int_t *neis1, *neis2; igraph_real_t triangles; long int i, j, k; long int neilen1, neilen2; long int *neis; igraph_lazy_adjlist_t adjlist; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); if (nodes_to_calc == 0) { igraph_vector_clear(res); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } neis = IGRAPH_CALLOC(no_of_nodes, long int); if (neis == 0) { IGRAPH_ERROR("local undirected transitivity failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, neis); IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist); for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int node = IGRAPH_VIT_GET(vit); IGRAPH_ALLOW_INTERRUPTION(); neis1 = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) node); neilen1 = igraph_vector_int_size(neis1); for (j = 0; j < neilen1; j++) { neis[ (long int)VECTOR(*neis1)[j] ] = i + 1; } triangles = 0; for (j = 0; j < neilen1; j++) { long int v = (long int) VECTOR(*neis1)[j]; neis2 = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) v); neilen2 = igraph_vector_int_size(neis2); for (k = 0; k < neilen2; k++) { long int v2 = (long int) VECTOR(*neis2)[k]; if (neis[v2] == i + 1) { triangles += 1.0; } } } #ifdef TRANSIT if (mode == IGRAPH_TRANSITIVITY_ZERO && neilen1 < 2) { VECTOR(*res)[i] = 0.0; } else { VECTOR(*res)[i] = triangles / neilen1 / (neilen1 - 1); } #else VECTOR(*res)[i] = triangles / 2; #endif } igraph_lazy_adjlist_destroy(&adjlist); IGRAPH_FREE(neis); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(3); leidenbase/src/core/properties/triangles_template.h0000644000176200001440000001003514447675375022341 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef TRANSIT #define TRANSIT_TRIEDGES #endif long int no_of_nodes = igraph_vcount(graph); long int node, i, j, nn; igraph_adjlist_t allneis; igraph_vector_int_t *neis1, *neis2; long int neilen1, neilen2; long int *neis; long int maxdegree; #ifdef TRANSIT_TRIEDGES long int deg1; #endif igraph_vector_int_t order; igraph_vector_int_t rank; igraph_vector_t degree; if (no_of_nodes == 0) { #ifndef TRIANGLES igraph_vector_clear(res); #else igraph_vector_int_clear(res); #endif return IGRAPH_SUCCESS; } igraph_vector_int_init(&order, no_of_nodes); IGRAPH_FINALLY(igraph_vector_int_destroy, &order); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); IGRAPH_CHECK(igraph_adjlist_init(graph, &allneis, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); for (i = 0; i < no_of_nodes; i++) { VECTOR(degree)[i] = igraph_vector_int_size(igraph_adjlist_get(&allneis, i)); } maxdegree = (long int) igraph_vector_max(°ree) + 1; igraph_vector_order1_int(°ree, &order, maxdegree); igraph_vector_int_init(&rank, no_of_nodes); IGRAPH_FINALLY(igraph_vector_int_destroy, &rank); for (i = 0; i < no_of_nodes; i++) { VECTOR(rank)[ VECTOR(order)[i] ] = no_of_nodes - i - 1; } IGRAPH_CHECK(igraph_i_trans4_al_simplify(&allneis, &rank)); neis = IGRAPH_CALLOC(no_of_nodes, long int); if (neis == 0) { IGRAPH_ERROR("undirected local transitivity failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, neis); #ifndef TRIANGLES IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes)); igraph_vector_null(res); #else igraph_vector_int_clear(res); #endif for (nn = no_of_nodes - 1; nn >= 0; nn--) { node = VECTOR(order)[nn]; IGRAPH_ALLOW_INTERRUPTION(); neis1 = igraph_adjlist_get(&allneis, node); neilen1 = igraph_vector_int_size(neis1); #ifdef TRANSIT_TRIEDGES deg1 = (long int) VECTOR(degree)[node]; #endif /* Mark the neighbors of the node */ for (i = 0; i < neilen1; i++) { neis[ (long int) VECTOR(*neis1)[i] ] = node + 1; } for (i = 0; i < neilen1; i++) { long int nei = (long int) VECTOR(*neis1)[i]; neis2 = igraph_adjlist_get(&allneis, nei); neilen2 = igraph_vector_int_size(neis2); for (j = 0; j < neilen2; j++) { long int nei2 = (long int) VECTOR(*neis2)[j]; if (neis[nei2] == node + 1) { #ifndef TRIANGLES VECTOR(*res)[nei2] += 1; VECTOR(*res)[nei] += 1; VECTOR(*res)[node] += 1; #else IGRAPH_CHECK(igraph_vector_int_push_back(res, node)); IGRAPH_CHECK(igraph_vector_int_push_back(res, nei)); IGRAPH_CHECK(igraph_vector_int_push_back(res, nei2)); #endif } } } #ifdef TRANSIT if (mode == IGRAPH_TRANSITIVITY_ZERO && deg1 < 2) { VECTOR(*res)[node] = 0.0; } else { VECTOR(*res)[node] = VECTOR(*res)[node] / deg1 / (deg1 - 1) * 2.0; } #endif } igraph_free(neis); igraph_adjlist_destroy(&allneis); igraph_vector_int_destroy(&rank); igraph_vector_destroy(°ree); igraph_vector_int_destroy(&order); IGRAPH_FINALLY_CLEAN(5); #ifdef TRANSIT_TRIEDGES #undef TRANSIT_TRIEDGES #endif leidenbase/src/core/properties/loops.c0000644000176200001440000000540714447675375017614 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_structural.h" #include "igraph_interface.h" /** * \function igraph_has_loop * \brief Returns whether the graph has at least one loop edge. * * * A loop edge is an edge from a vertex to itself. * \param graph The input graph. * \param res Pointer to an initialized boolean vector for storing the result. * * \sa \ref igraph_simplify() to get rid of loop edges. * * Time complexity: O(e), the number of edges to check. * * \example examples/simple/igraph_has_loop.c */ int igraph_has_loop(const igraph_t *graph, igraph_bool_t *res) { long int i, m = igraph_ecount(graph); *res = 0; for (i = 0; i < m; i++) { if (IGRAPH_FROM(graph, i) == IGRAPH_TO(graph, i)) { *res = 1; break; } } return 0; } /** * \function igraph_is_loop * \brief Find the loop edges in a graph. * * * A loop edge is an edge from a vertex to itself. * \param graph The input graph. * \param res Pointer to an initialized boolean vector for storing the result, * it will be resized as needed. * \param es The edges to check, for all edges supply \ref igraph_ess_all() here. * \return Error code. * * \sa \ref igraph_simplify() to get rid of loop edges. * * Time complexity: O(e), the number of edges to check. * * \example examples/simple/igraph_is_loop.c */ int igraph_is_loop(const igraph_t *graph, igraph_vector_bool_t *res, igraph_es_t es) { igraph_eit_t eit; long int i; IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); IGRAPH_CHECK(igraph_vector_bool_resize(res, IGRAPH_EIT_SIZE(eit))); for (i = 0; !IGRAPH_EIT_END(eit); i++, IGRAPH_EIT_NEXT(eit)) { long int e = IGRAPH_EIT_GET(eit); VECTOR(*res)[i] = (IGRAPH_FROM(graph, e) == IGRAPH_TO(graph, e)) ? 1 : 0; } igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/properties/degrees.c0000644000176200001440000004321414447675375020074 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_structural.h" #include "igraph_interface.h" /** * \function igraph_maxdegree * \brief The maximum degree in a graph (or set of vertices). * * * The largest in-, out- or total degree of the specified vertices is * calculated. If the graph has no vertices, or \p vids is empty, * 0 is returned, as this is the smallest possible value for degrees. * * \param graph The input graph. * \param res Pointer to an integer (\c igraph_integer_t), the result * will be stored here. * \param vids Vector giving the vertex IDs for which the maximum degree will * be calculated. * \param mode Defines the type of the degree. * \c IGRAPH_OUT, out-degree, * \c IGRAPH_IN, in-degree, * \c IGRAPH_ALL, total degree (sum of the * in- and out-degree). * This parameter is ignored for undirected graphs. * \param loops Boolean, gives whether the self-loops should be * counted. * \return Error code: * \c IGRAPH_EINVVID: invalid vertex id. * \c IGRAPH_EINVMODE: invalid mode argument. * * Time complexity: O(v) if loops is TRUE, and O(v*d) otherwise. v is the number * of vertices for which the degree will be calculated, and d is their * (average) degree. */ int igraph_maxdegree(const igraph_t *graph, igraph_integer_t *res, igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops) { igraph_vector_t tmp; IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_CHECK(igraph_degree(graph, &tmp, vids, mode, loops)); if (igraph_vector_size(&tmp) == 0) { *res = 0; } else { *res = (igraph_integer_t) igraph_vector_max(&tmp); } igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } static int igraph_i_avg_nearest_neighbor_degree_weighted(const igraph_t *graph, igraph_vs_t vids, igraph_neimode_t mode, igraph_neimode_t neighbor_degree_mode, igraph_vector_t *knn, igraph_vector_t *knnk, const igraph_vector_t *weights) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t neis, edge_neis; long int i, j, no_vids; igraph_vit_t vit; igraph_vector_t my_knn_v, *my_knn = knn; igraph_vector_t strength, deg; igraph_integer_t maxdeg; igraph_vector_t deghist; igraph_real_t mynan = IGRAPH_NAN; if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector size", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); no_vids = IGRAPH_VIT_SIZE(vit); if (!knn) { IGRAPH_VECTOR_INIT_FINALLY(&my_knn_v, no_vids); my_knn = &my_knn_v; } else { IGRAPH_CHECK(igraph_vector_resize(knn, no_vids)); } /* Get degree of neighbours */ IGRAPH_VECTOR_INIT_FINALLY(°, no_of_nodes); IGRAPH_CHECK(igraph_degree(graph, °, igraph_vss_all(), neighbor_degree_mode, IGRAPH_LOOPS)); IGRAPH_VECTOR_INIT_FINALLY(&strength, no_of_nodes); /* Get strength of all nodes */ IGRAPH_CHECK(igraph_strength(graph, &strength, igraph_vss_all(), mode, IGRAPH_LOOPS, weights)); /* Get maximum degree for initialization */ IGRAPH_CHECK(igraph_maxdegree(graph, &maxdeg, igraph_vss_all(), mode, IGRAPH_LOOPS)); IGRAPH_VECTOR_INIT_FINALLY(&neis, (long int)maxdeg); IGRAPH_VECTOR_INIT_FINALLY(&edge_neis, (long int)maxdeg); igraph_vector_resize(&neis, 0); igraph_vector_resize(&edge_neis, 0); if (knnk) { IGRAPH_CHECK(igraph_vector_resize(knnk, (long int)maxdeg)); igraph_vector_null(knnk); IGRAPH_VECTOR_INIT_FINALLY(°hist, (long int)maxdeg); } for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { igraph_real_t sum = 0.0; long int v = IGRAPH_VIT_GET(vit); long int nv; igraph_real_t str = VECTOR(strength)[v]; /* Get neighbours and incident edges */ IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) v, mode)); IGRAPH_CHECK(igraph_incident(graph, &edge_neis, (igraph_integer_t) v, mode)); nv = igraph_vector_size(&neis); for (j = 0; j < nv; j++) { long int nei = (long int) VECTOR(neis)[j]; long int e = (long int) VECTOR(edge_neis)[j]; double w = VECTOR(*weights)[e]; sum += w * VECTOR(deg)[nei]; } if (str != 0.0) { VECTOR(*my_knn)[i] = sum / str; } else { VECTOR(*my_knn)[i] = mynan; } if (knnk && nv > 0) { VECTOR(*knnk)[nv - 1] += VECTOR(*my_knn)[i]; VECTOR(deghist)[nv - 1] += 1; } } igraph_vector_destroy(&edge_neis); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(2); if (knnk) { for (i = 0; i < maxdeg; i++) { igraph_real_t dh = VECTOR(deghist)[i]; if (dh != 0) { VECTOR(*knnk)[i] /= dh; } else { VECTOR(*knnk)[i] = mynan; } } igraph_vector_destroy(°hist); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&strength); igraph_vector_destroy(°); IGRAPH_FINALLY_CLEAN(2); if (!knn) { igraph_vector_destroy(&my_knn_v); IGRAPH_FINALLY_CLEAN(1); } igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_avg_nearest_neighbor_degree * Average neighbor degree. * * Calculates the average degree of the neighbors for each vertex (\p knn), and * optionally, the same quantity as a function of the vertex degree (\p knnk). * * * For isolated vertices \p knn is set to NaN. * The same is done in \p knnk for vertex degrees that * don't appear in the graph. * * * The weighted version computes a weighted average of the neighbor degrees as * * k_nn_u = 1/s_u sum_v w_uv k_v, * * where s_u = sum_v w_uv is the sum of the incident edge weights * of vertex \c u, i.e. its strength. * The sum runs over the neighbors \c v of vertex \c u * as indicated by \p mode. w_uv denotes the weighted adjacency matrix * and k_v is the neighbors' degree, specified by \p neighbor_degree_mode. * * * Reference: * A. Barrat, M. Barthélemy, R. Pastor-Satorras, and A. Vespignani, * The architecture of complex weighted networks, * Proc. Natl. Acad. Sci. USA 101, 3747 (2004). * https://dx.doi.org/10.1073/pnas.0400087101 * * \param graph The input graph. It may be directed. * \param vids The vertices for which the calculation is performed. * \param mode The type of neighbors to consider in directed graphs. * \c IGRAPH_OUT considers out-neighbors, \c IGRAPH_IN in-neighbors * and \c IGRAPH_ALL ignores edge directions. * \param neighbor_degree_mode The type of degree to average in directed graphs. * \c IGRAPH_OUT averages out-degrees, \c IGRAPH_IN averages in-degrees * and \c IGRAPH_ALL ignores edge directions for the degree calculation. * \param vids The vertices for which the calculation is performed. * \param knn Pointer to an initialized vector, the result will be * stored here. It will be resized as needed. Supply a \c NULL pointer * here, if you only want to calculate \c knnk. * \param knnk Pointer to an initialized vector, the average * neighbor degree as a function of the vertex degree is stored * here. The first (zeroth) element is for degree one vertices, * etc. Supply a \c NULL pointer here if you don't want to calculate * this. * \param weights Optional edge weights. Supply a null pointer here * for the non-weighted version. * * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. * * \example examples/simple/igraph_knn.c */ int igraph_avg_nearest_neighbor_degree(const igraph_t *graph, igraph_vs_t vids, igraph_neimode_t mode, igraph_neimode_t neighbor_degree_mode, igraph_vector_t *knn, igraph_vector_t *knnk, const igraph_vector_t *weights) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t neis; long int i, j, no_vids; igraph_vit_t vit; igraph_vector_t my_knn_v, *my_knn = knn; igraph_vector_t deg; igraph_integer_t maxdeg; igraph_vector_t deghist; igraph_real_t mynan = IGRAPH_NAN; igraph_bool_t simple; IGRAPH_CHECK(igraph_is_simple(graph, &simple)); if (!simple) { IGRAPH_ERROR("Average nearest neighbor degree works only with " "simple graphs", IGRAPH_EINVAL); } if (weights) { return igraph_i_avg_nearest_neighbor_degree_weighted(graph, vids, mode, neighbor_degree_mode, knn, knnk, weights); } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); no_vids = IGRAPH_VIT_SIZE(vit); if (!knn) { IGRAPH_VECTOR_INIT_FINALLY(&my_knn_v, no_vids); my_knn = &my_knn_v; } else { IGRAPH_CHECK(igraph_vector_resize(knn, no_vids)); } IGRAPH_VECTOR_INIT_FINALLY(°, no_of_nodes); IGRAPH_CHECK(igraph_degree(graph, °, igraph_vss_all(), neighbor_degree_mode, IGRAPH_LOOPS)); IGRAPH_CHECK(igraph_maxdegree(graph, &maxdeg, igraph_vss_all(), mode, IGRAPH_LOOPS)); IGRAPH_VECTOR_INIT_FINALLY(&neis, maxdeg); igraph_vector_resize(&neis, 0); if (knnk) { IGRAPH_CHECK(igraph_vector_resize(knnk, (long int)maxdeg)); igraph_vector_null(knnk); IGRAPH_VECTOR_INIT_FINALLY(°hist, (long int)maxdeg); } for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { igraph_real_t sum = 0.0; long int v = IGRAPH_VIT_GET(vit); long int nv; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) v, mode)); nv = igraph_vector_size(&neis); for (j = 0; j < nv; j++) { long int nei = (long int) VECTOR(neis)[j]; sum += VECTOR(deg)[nei]; } if (nv != 0) { VECTOR(*my_knn)[i] = sum / nv; } else { VECTOR(*my_knn)[i] = mynan; } if (knnk && nv > 0) { VECTOR(*knnk)[nv - 1] += VECTOR(*my_knn)[i]; VECTOR(deghist)[nv - 1] += 1; } } if (knnk) { for (i = 0; i < maxdeg; i++) { long int dh = (long int) VECTOR(deghist)[i]; if (dh != 0) { VECTOR(*knnk)[i] /= dh; } else { VECTOR(*knnk)[i] = mynan; } } igraph_vector_destroy(°hist); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&neis); igraph_vector_destroy(°); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(3); if (!knn) { igraph_vector_destroy(&my_knn_v); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_strength * Strength of the vertices, weighted vertex degree in other words. * * In a weighted network the strength of a vertex is the sum of the * weights of all incident edges. In a non-weighted network this is * exactly the vertex degree. * \param graph The input graph. * \param res Pointer to an initialized vector, the result is stored * here. It will be resized as needed. * \param vids The vertices for which the calculation is performed. * \param mode Gives whether to count only outgoing (\c IGRAPH_OUT), * incoming (\c IGRAPH_IN) edges or both (\c IGRAPH_ALL). * \param loops A logical scalar, whether to count loop edges as well. * \param weights A vector giving the edge weights. If this is a NULL * pointer, then \ref igraph_degree() is called to perform the * calculation. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number vertices and * edges. * * \sa \ref igraph_degree() for the traditional, non-weighted version. */ int igraph_strength(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops, const igraph_vector_t *weights) { long int no_of_nodes = igraph_vcount(graph); igraph_vit_t vit; long int no_vids; igraph_vector_t neis; long int i; if (!weights) { return igraph_degree(graph, res, vids, mode, loops); } if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); no_vids = IGRAPH_VIT_SIZE(vit); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_vector_reserve(&neis, no_of_nodes)); IGRAPH_CHECK(igraph_vector_resize(res, no_vids)); igraph_vector_null(res); if (loops) { for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int vid = IGRAPH_VIT_GET(vit); long int j, n; IGRAPH_CHECK(igraph_incident(graph, &neis, (igraph_integer_t) vid, mode)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { long int edge = (long int) VECTOR(neis)[j]; VECTOR(*res)[i] += VECTOR(*weights)[edge]; } } } else { for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int vid = IGRAPH_VIT_GET(vit); long int j, n; IGRAPH_CHECK(igraph_incident(graph, &neis, (igraph_integer_t) vid, mode)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { long int edge = (long int) VECTOR(neis)[j]; long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO(graph, edge); if (from != to) { VECTOR(*res)[i] += VECTOR(*weights)[edge]; } } } } igraph_vit_destroy(&vit); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_sort_vertex_ids_by_degree * \brief Calculate a list of vertex ids sorted by degree of the corresponding vertex. * * The list of vertex ids is returned in a vector that is sorted * in ascending or descending order of vertex degree. * * \param graph The input graph. * \param outvids Pointer to an initialized vector that will be * resized and will contain the ordered vertex ids. * \param vids Input vertex selector of vertex ids to include in * calculation. * \param mode Defines the type of the degree. * \c IGRAPH_OUT, out-degree, * \c IGRAPH_IN, in-degree, * \c IGRAPH_ALL, total degree (sum of the * in- and out-degree). * This parameter is ignored for undirected graphs. * \param loops Boolean, gives whether the self-loops should be * counted. * \param order Specifies whether the ordering should be ascending * (\c IGRAPH_ASCENDING) or descending (\c IGRAPH_DESCENDING). * \param only_indices If true, then return a sorted list of indices * into a vector corresponding to \c vids, rather than a list * of vertex ids. This parameter is ignored if \c vids is set * to all vertices via igraph_vs_all() or igraph_vss_all(), * because in this case the indices and vertex ids are the * same. * \return Error code: * \c IGRAPH_EINVVID: invalid vertex id. * \c IGRAPH_EINVMODE: invalid mode argument. * */ int igraph_sort_vertex_ids_by_degree(const igraph_t *graph, igraph_vector_t *outvids, igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops, igraph_order_t order, igraph_bool_t only_indices) { long int i; igraph_vector_t degrees, vs_vec; IGRAPH_VECTOR_INIT_FINALLY(°rees, 0); IGRAPH_CHECK(igraph_degree(graph, °rees, vids, mode, loops)); IGRAPH_CHECK((int) igraph_vector_qsort_ind(°rees, outvids, order == IGRAPH_DESCENDING)); if (only_indices || igraph_vs_is_all(&vids) ) { igraph_vector_destroy(°rees); IGRAPH_FINALLY_CLEAN(1); } else { IGRAPH_VECTOR_INIT_FINALLY(&vs_vec, 0); IGRAPH_CHECK(igraph_vs_as_vector(graph, vids, &vs_vec)); for (i = 0; i < igraph_vector_size(outvids); i++) { VECTOR(*outvids)[i] = VECTOR(vs_vec)[(long int)VECTOR(*outvids)[i]]; } igraph_vector_destroy(&vs_vec); igraph_vector_destroy(°rees); IGRAPH_FINALLY_CLEAN(2); } return 0; } leidenbase/src/core/properties/triangles.c0000644000176200001440000010202414447675375020441 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_transitivity.h" #include "igraph_interface.h" #include "igraph_adjlist.h" #include "igraph_memory.h" #include "igraph_motifs.h" #include "igraph_structural.h" #include "core/interruption.h" #include "properties/properties_internal.h" /** * \function igraph_transitivity_avglocal_undirected * \brief Average local transitivity (clustering coefficient). * * The transitivity measures the probability that two neighbors of a * vertex are connected. In case of the average local transitivity, * this probability is calculated for each vertex and then the average * is taken. Vertices with less than two neighbors require special treatment, * they will either be left out from the calculation or they will be considered * as having zero transitivity, depending on the \c mode argument. * Edge directions and edge multiplicities are ignored. * * * Note that this measure is different from the global transitivity measure * (see \ref igraph_transitivity_undirected() ) as it simply takes the * average local transitivity across the whole network. * * * Clustering coefficient is an alternative name for transitivity. * * * References: * * * D. J. Watts and S. Strogatz: Collective dynamics of small-world networks. * Nature 393(6684):440-442 (1998). * * \param graph The input graph. Edge directions and multiplicites are ignored. * \param res Pointer to a real variable, the result will be stored here. * \param mode Defines how to treat vertices with degree less than two. * \c IGRAPH_TRANSITIVITY_NAN leaves them out from averaging, * \c IGRAPH_TRANSITIVITY_ZERO includes them with zero transitivity. * The result will be \c NaN if the mode is \c IGRAPH_TRANSITIVITY_NAN * and there are no vertices with more than one neighbor. * * \return Error code. * * \sa \ref igraph_transitivity_undirected(), \ref * igraph_transitivity_local_undirected(). * * Time complexity: O(|V|*d^2), |V| is the number of vertices in the * graph and d is the average degree. */ int igraph_transitivity_avglocal_undirected(const igraph_t *graph, igraph_real_t *res, igraph_transitivity_mode_t mode) { igraph_integer_t i, no_of_nodes = igraph_vcount(graph), nans = 0; igraph_real_t sum = 0.0; igraph_vector_t vec; if (no_of_nodes == 0) { if (mode == IGRAPH_TRANSITIVITY_ZERO) { *res = 0; } else { *res = IGRAPH_NAN; } } else { IGRAPH_VECTOR_INIT_FINALLY(&vec, no_of_nodes); IGRAPH_CHECK(igraph_transitivity_local_undirected(graph, &vec, igraph_vss_all(), mode)); for (i = 0, nans = 0; i < no_of_nodes; i++) { if (!igraph_is_nan(VECTOR(vec)[i])) { sum += VECTOR(vec)[i]; } else { nans++; } } igraph_vector_destroy(&vec); IGRAPH_FINALLY_CLEAN(1); *res = sum / (no_of_nodes - nans); } return IGRAPH_SUCCESS; } int igraph_transitivity_local_undirected1(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_transitivity_mode_t mode) { #define TRANSIT #include "properties/triangles_template1.h" #undef TRANSIT return IGRAPH_SUCCESS; } int igraph_transitivity_local_undirected2(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_transitivity_mode_t mode) { long int no_of_nodes = igraph_vcount(graph); igraph_vit_t vit; long int nodes_to_calc, affected_nodes; long int maxdegree = 0; long int i, j, k, nn; igraph_lazy_adjlist_t adjlist; igraph_vector_t indexv, avids, rank, order, triangles, degree; long int *neis; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist); IGRAPH_VECTOR_INIT_FINALLY(&indexv, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&avids, 0); IGRAPH_CHECK(igraph_vector_reserve(&avids, nodes_to_calc)); k = 0; for (i = 0; i < nodes_to_calc; IGRAPH_VIT_NEXT(vit), i++) { long int v = IGRAPH_VIT_GET(vit); igraph_vector_int_t *neis2; long int neilen; if (VECTOR(indexv)[v] == 0) { VECTOR(indexv)[v] = k + 1; k++; IGRAPH_CHECK(igraph_vector_push_back(&avids, v)); } neis2 = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) v); neilen = igraph_vector_int_size(neis2); for (j = 0; j < neilen; j++) { long int nei = (long int) VECTOR(*neis2)[j]; if (VECTOR(indexv)[nei] == 0) { VECTOR(indexv)[nei] = k + 1; k++; IGRAPH_CHECK(igraph_vector_push_back(&avids, nei)); } } } /* Degree, ordering, ranking */ affected_nodes = igraph_vector_size(&avids); IGRAPH_VECTOR_INIT_FINALLY(&order, 0); IGRAPH_VECTOR_INIT_FINALLY(°ree, affected_nodes); for (i = 0; i < affected_nodes; i++) { long int v = (long int) VECTOR(avids)[i]; igraph_vector_int_t *neis2; long int deg; neis2 = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) v); VECTOR(degree)[i] = deg = igraph_vector_int_size(neis2); if (deg > maxdegree) { maxdegree = deg; } } igraph_vector_order1(°ree, &order, maxdegree + 1); igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); IGRAPH_VECTOR_INIT_FINALLY(&rank, affected_nodes); for (i = 0; i < affected_nodes; i++) { VECTOR(rank)[ (long int) VECTOR(order)[i] ] = affected_nodes - i - 1; } neis = IGRAPH_CALLOC(no_of_nodes, long int); if (neis == 0) { IGRAPH_ERROR("Insufficient memory for local transitivity calculation.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, neis); IGRAPH_VECTOR_INIT_FINALLY(&triangles, affected_nodes); for (nn = affected_nodes - 1; nn >= 0; nn--) { long int node = (long int) VECTOR(avids) [ (long int) VECTOR(order)[nn] ]; igraph_vector_int_t *neis1, *neis2; long int neilen1, neilen2; long int nodeindex = (long int) VECTOR(indexv)[node]; long int noderank = (long int) VECTOR(rank) [nodeindex - 1]; /* fprintf(stderr, "node %li (indexv %li, rank %li)\n", node, */ /* (long int)VECTOR(indexv)[node]-1, noderank); */ IGRAPH_ALLOW_INTERRUPTION(); neis1 = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) node); neilen1 = igraph_vector_int_size(neis1); for (i = 0; i < neilen1; i++) { long int nei = (long int) VECTOR(*neis1)[i]; neis[nei] = node + 1; } for (i = 0; i < neilen1; i++) { long int nei = (long int) VECTOR(*neis1)[i]; long int neiindex = (long int) VECTOR(indexv)[nei]; long int neirank = (long int) VECTOR(rank)[neiindex - 1]; /* fprintf(stderr, " nei %li (indexv %li, rank %li)\n", nei, */ /* neiindex, neirank); */ if (neirank > noderank) { neis2 = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) nei); neilen2 = igraph_vector_int_size(neis2); for (j = 0; j < neilen2; j++) { long int nei2 = (long int) VECTOR(*neis2)[j]; long int nei2index = (long int) VECTOR(indexv)[nei2]; long int nei2rank = (long int) VECTOR(rank)[nei2index - 1]; /* fprintf(stderr, " triple %li %li %li\n", node, nei, nei2); */ if (nei2rank < neirank) { continue; } if (neis[nei2] == node + 1) { /* fprintf(stderr, " triangle\n"); */ VECTOR(triangles) [ nei2index - 1 ] += 1; VECTOR(triangles) [ neiindex - 1 ] += 1; VECTOR(triangles) [ nodeindex - 1 ] += 1; } } } } } /* Ok, for all affected vertices the number of triangles were counted */ IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); IGRAPH_VIT_RESET(vit); for (i = 0; i < nodes_to_calc; i++, IGRAPH_VIT_NEXT(vit)) { long int node = IGRAPH_VIT_GET(vit); long int idx = (long int) VECTOR(indexv)[node] - 1; igraph_vector_int_t *neis2 = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) node); long int deg = igraph_vector_int_size(neis2); if (mode == IGRAPH_TRANSITIVITY_ZERO && deg < 2) { VECTOR(*res)[i] = 0.0; } else { VECTOR(*res)[i] = VECTOR(triangles)[idx] / deg / (deg - 1) * 2.0; } /* fprintf(stderr, "%f %f\n", VECTOR(triangles)[idx], triples); */ } igraph_vector_destroy(&triangles); igraph_free(neis); igraph_vector_destroy(&rank); igraph_vector_destroy(&order); igraph_vector_destroy(&avids); igraph_vector_destroy(&indexv); igraph_lazy_adjlist_destroy(&adjlist); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(8); return 0; } /* We don't use this, it is theoretically good, but practically not. */ /* int igraph_transitivity_local_undirected3(const igraph_t *graph, */ /* igraph_vector_t *res, */ /* const igraph_vs_t vids) { */ /* igraph_vit_t vit; */ /* long int nodes_to_calc; */ /* igraph_lazy_adjlist_t adjlist; */ /* long int i, j; */ /* IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); */ /* IGRAPH_FINALLY(igraph_vit_destroy, &vit); */ /* nodes_to_calc=IGRAPH_VIT_SIZE(vit); */ /* IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, IGRAPH_ALL, */ /* IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); */ /* IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist); */ /* IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); */ /* for (i=0, IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); */ /* i++, IGRAPH_VIT_NEXT(vit)) { */ /* long int node=IGRAPH_VIT_GET(vit); */ /* igraph_vector_t *neis=igraph_lazy_adjlist_get(&adjlist, node); */ /* long int n1=igraph_vector_size(neis); */ /* igraph_real_t triangles=0; */ /* igraph_real_t triples=(double)n1*(n1-1); */ /* IGRAPH_ALLOW_INTERRUPTION(); */ /* for (j=0; j nei2) { */ /* l2++; */ /* } else { */ /* triangles+=1; */ /* l1++; l2++; */ /* } */ /* } */ /* } */ /* /\* We're done with 'node' *\/ */ /* VECTOR(*res)[i] = triangles / triples; */ /* } */ /* igraph_lazy_adjlist_destroy(&adjlist); */ /* igraph_vit_destroy(&vit); */ /* IGRAPH_FINALLY_CLEAN(2); */ /* return 0; */ /* } */ /* This removes loop, multiple edges and edges that point "backwards" according to the rank vector. */ /* Note: Also used in scan.c */ int igraph_i_trans4_al_simplify(igraph_adjlist_t *al, const igraph_vector_int_t *rank) { long int i; long int n = al->length; igraph_vector_int_t mark; igraph_vector_int_init(&mark, n); IGRAPH_FINALLY(igraph_vector_int_destroy, &mark); for (i = 0; i < n; i++) { igraph_vector_int_t *v = &al->adjs[i]; int j, l = igraph_vector_int_size(v); int irank = VECTOR(*rank)[i]; VECTOR(mark)[i] = i + 1; for (j = 0; j < l; /* nothing */) { long int e = (long int) VECTOR(*v)[j]; if (VECTOR(*rank)[e] > irank && VECTOR(mark)[e] != i + 1) { VECTOR(mark)[e] = i + 1; j++; } else { VECTOR(*v)[j] = igraph_vector_int_tail(v); igraph_vector_int_pop_back(v); l--; } } } igraph_vector_int_destroy(&mark); IGRAPH_FINALLY_CLEAN(1); return 0; } int igraph_transitivity_local_undirected4(const igraph_t *graph, igraph_vector_t *res, igraph_transitivity_mode_t mode) { #define TRANSIT 1 #include "properties/triangles_template.h" #undef TRANSIT return 0; } /** * \function igraph_transitivity_local_undirected * \brief Calculates the local transitivity (clustering coefficient) of a graph. * * The transitivity measures the probability that two neighbors of a * vertex are connected. In case of the local transitivity, this * probability is calculated separately for each vertex. * * * Note that this measure is different from the global transitivity measure * (see \ref igraph_transitivity_undirected() ) as it calculates a transitivity * value for each vertex individually. * * * Clustering coefficient is an alternative name for transitivity. * * * References: * * * D. J. Watts and S. Strogatz: Collective dynamics of small-world networks. * Nature 393(6684):440-442 (1998). * * \param graph The input graph. Edge directions and multiplicities are ignored. * \param res Pointer to an initialized vector, the result will be * stored here. It will be resized as needed. * \param vids Vertex set, the vertices for which the local * transitivity will be calculated. * \param mode Defines how to treat vertices with degree less than two. * \c IGRAPH_TRANSITIVITY_NAN returns \c NaN for these vertices, * \c IGRAPH_TRANSITIVITY_ZERO returns zero. * \return Error code. * * \sa \ref igraph_transitivity_undirected(), \ref * igraph_transitivity_avglocal_undirected(). * * Time complexity: O(n*d^2), n is the number of vertices for which * the transitivity is calculated, d is the average vertex degree. */ int igraph_transitivity_local_undirected(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_transitivity_mode_t mode) { if (igraph_vs_is_all(&vids)) { return igraph_transitivity_local_undirected4(graph, res, mode); } else { igraph_vit_t vit; long int size; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); size = IGRAPH_VIT_SIZE(vit); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); if (size < 100) { return igraph_transitivity_local_undirected1(graph, res, vids, mode); } else { return igraph_transitivity_local_undirected2(graph, res, vids, mode); } } } static int igraph_adjacent_triangles1(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids) { # include "properties/triangles_template1.h" return 0; } static int igraph_adjacent_triangles4(const igraph_t *graph, igraph_vector_t *res) { # include "properties/triangles_template.h" return 0; } /** * \function igraph_adjacent_triangles * \brief Count the number of triangles a vertex is part of. * * \param graph The input graph. Edge directions and multiplicities are ignored. * \param res Initiliazed vector, the results are stored here. * \param vids The vertices to perform the calculation for. * \return Error mode. * * \sa \ref igraph_list_triangles() to list them. * * Time complexity: O(d^2 n), d is the average vertex degree of the * queried vertices, n is their number. */ int igraph_adjacent_triangles(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids) { if (igraph_vs_is_all(&vids)) { return igraph_adjacent_triangles4(graph, res); } else { return igraph_adjacent_triangles1(graph, res, vids); } } /** * \function igraph_list_triangles * \brief Find all triangles in a graph. * * \param graph The input graph, edge directions are ignored. * Multiple edges are ignored. * \param res Pointer to an initialized integer vector, the result * is stored here, in a long list of triples of vertex ids. * Each triple is a triangle in the graph. Each triangle is * listed exactly once. * \return Error code. * * \sa \ref igraph_transitivity_undirected() to count the triangles, * \ref igraph_adjacent_triangles() to count the triangles a vertex * participates in. * * Time complexity: O(d^2 n), d is the average degree, n is the number * of vertices. */ int igraph_list_triangles(const igraph_t *graph, igraph_vector_int_t *res) { # define TRIANGLES # include "properties/triangles_template.h" # undef TRIANGLES return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_transitivity_undirected * \brief Calculates the transitivity (clustering coefficient) of a graph. * * * The transitivity measures the probability that two neighbors of a * vertex are connected. More precisely, this is the ratio of the * triangles and connected triples in the graph, the result is a * single real number. Directed graphs are considered as undirected ones * and multi-edges are ignored. * * * Note that this measure is different from the local transitivity measure * (see \ref igraph_transitivity_local_undirected() ) as it calculates a single * value for the whole graph. * * * Clustering coefficient is an alternative name for transitivity. * * * References: * * * S. Wasserman and K. Faust: Social Network Analysis: Methods and * Applications. Cambridge: Cambridge University Press, 1994. * * \param graph The graph object. Edge directions and multiplicites are ignored. * \param res Pointer to a real variable, the result will be stored here. * \param mode Defines how to treat graphs with no connected triples. * \c IGRAPH_TRANSITIVITY_NAN returns \c NaN in this case, * \c IGRAPH_TRANSITIVITY_ZERO returns zero. * \return Error code: * \c IGRAPH_ENOMEM: not enough memory for * temporary data. * * \sa \ref igraph_transitivity_local_undirected(), * \ref igraph_transitivity_avglocal_undirected(). * * Time complexity: O(|V|*d^2), |V| is the number of vertices in * the graph, d is the average node degree. * * \example examples/simple/igraph_transitivity.c */ int igraph_transitivity_undirected(const igraph_t *graph, igraph_real_t *res, igraph_transitivity_mode_t mode) { long int no_of_nodes = igraph_vcount(graph); igraph_real_t triples = 0, triangles = 0; long int node, nn; long int maxdegree; long int *neis; igraph_vector_t order; igraph_vector_t rank; igraph_vector_t degree; igraph_adjlist_t allneis; igraph_vector_int_t *neis1, *neis2; long int i, j, neilen1, neilen2; if (no_of_nodes == 0) { *res = mode == IGRAPH_TRANSITIVITY_ZERO ? 0.0 : IGRAPH_NAN; return IGRAPH_SUCCESS; } IGRAPH_VECTOR_INIT_FINALLY(&order, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS)); maxdegree = (long int) igraph_vector_max(°ree) + 1; IGRAPH_CHECK(igraph_vector_order1(°ree, &order, maxdegree)); igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); IGRAPH_VECTOR_INIT_FINALLY(&rank, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { VECTOR(rank)[ (long int) VECTOR(order)[i] ] = no_of_nodes - i - 1; } IGRAPH_CHECK(igraph_adjlist_init(graph, &allneis, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_adjlist_destroy, &allneis); neis = IGRAPH_CALLOC(no_of_nodes, long int); if (! neis) { IGRAPH_ERROR("Insufficient memory for undirected global transitivity.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, neis); for (nn = no_of_nodes - 1; nn >= 0; nn--) { node = (long int) VECTOR(order)[nn]; IGRAPH_ALLOW_INTERRUPTION(); neis1 = igraph_adjlist_get(&allneis, node); neilen1 = igraph_vector_int_size(neis1); triples += (double)neilen1 * (neilen1 - 1); /* Mark the neighbors of 'node' */ for (i = 0; i < neilen1; i++) { long int nei = (long int) VECTOR(*neis1)[i]; neis[nei] = node + 1; } for (i = 0; i < neilen1; i++) { long int nei = (long int) VECTOR(*neis1)[i]; /* If 'nei' is not ready yet */ if (VECTOR(rank)[nei] > VECTOR(rank)[node]) { neis2 = igraph_adjlist_get(&allneis, nei); neilen2 = igraph_vector_int_size(neis2); for (j = 0; j < neilen2; j++) { long int nei2 = (long int) VECTOR(*neis2)[j]; if (neis[nei2] == node + 1) { triangles += 1.0; } } } } } IGRAPH_FREE(neis); igraph_adjlist_destroy(&allneis); igraph_vector_destroy(&rank); igraph_vector_destroy(&order); IGRAPH_FINALLY_CLEAN(4); if (triples == 0 && mode == IGRAPH_TRANSITIVITY_ZERO) { *res = 0; } else { *res = triangles / triples * 2.0; } return 0; } static int igraph_i_transitivity_barrat1(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, const igraph_vector_t *weights, igraph_transitivity_mode_t mode) { long int no_of_nodes = igraph_vcount(graph); igraph_vit_t vit; long int nodes_to_calc; igraph_vector_int_t *adj1, *adj2; igraph_vector_long_t neis; igraph_vector_t actw; igraph_lazy_inclist_t incident; long int i; igraph_vector_t strength; /* Precondition: weight vector is not null, its length equals the number of * edges, and the graph has at least one vertex. The graph must not have * multi-edges. These must be ensured by the caller. */ IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); IGRAPH_CHECK(igraph_vector_long_init(&neis, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &neis); IGRAPH_VECTOR_INIT_FINALLY(&actw, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&strength, 0); IGRAPH_CHECK(igraph_strength(graph, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, weights)); IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &incident, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &incident); IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int node = IGRAPH_VIT_GET(vit); long int adjlen1, adjlen2, j, k; igraph_real_t triples, triangles; IGRAPH_ALLOW_INTERRUPTION(); adj1 = igraph_lazy_inclist_get(&incident, (igraph_integer_t) node); adjlen1 = igraph_vector_int_size(adj1); /* Mark the neighbors of the node */ for (j = 0; j < adjlen1; j++) { long int edge = (long int) VECTOR(*adj1)[j]; long int nei = IGRAPH_OTHER(graph, edge, node); VECTOR(neis)[nei] = i + 1; VECTOR(actw)[nei] = VECTOR(*weights)[edge]; } triples = VECTOR(strength)[node] * (adjlen1 - 1); triangles = 0.0; for (j = 0; j < adjlen1; j++) { long int edge1 = (long int) VECTOR(*adj1)[j]; igraph_real_t weight1 = VECTOR(*weights)[edge1]; long int v = IGRAPH_OTHER(graph, edge1, node); adj2 = igraph_lazy_inclist_get(&incident, (igraph_integer_t) v); adjlen2 = igraph_vector_int_size(adj2); for (k = 0; k < adjlen2; k++) { long int edge2 = (long int) VECTOR(*adj2)[k]; long int v2 = IGRAPH_OTHER(graph, edge2, v); if (VECTOR(neis)[v2] == i + 1) { triangles += (VECTOR(actw)[v2] + weight1) / 2.0; } } } if (mode == IGRAPH_TRANSITIVITY_ZERO && triples == 0) { VECTOR(*res)[i] = 0.0; } else { VECTOR(*res)[i] = triangles / triples; } } igraph_lazy_inclist_destroy(&incident); igraph_vector_destroy(&strength); igraph_vector_destroy(&actw); igraph_vector_long_destroy(&neis); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; } static int igraph_i_transitivity_barrat4(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, const igraph_vector_t *weights, igraph_transitivity_mode_t mode) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t order, degree, rank; long int maxdegree; igraph_inclist_t incident; igraph_vector_long_t neis; igraph_vector_int_t *adj1, *adj2; igraph_vector_t actw; long int i, nn; /* Precondition: weight vector is not null, its length equals the number of * edges, and the graph has at least one vertex. The graph must not have * multi-edges. These must be ensured by the caller. */ IGRAPH_VECTOR_INIT_FINALLY(&order, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS)); maxdegree = (long int) igraph_vector_max(°ree) + 1; IGRAPH_CHECK(igraph_vector_order1(°ree, &order, maxdegree)); IGRAPH_CHECK(igraph_strength(graph, °ree, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, weights)); IGRAPH_VECTOR_INIT_FINALLY(&rank, no_of_nodes); for (i = 0; i < no_of_nodes; i++) { VECTOR(rank)[ (long int)VECTOR(order)[i] ] = no_of_nodes - i - 1; } IGRAPH_CHECK(igraph_inclist_init(graph, &incident, IGRAPH_ALL, IGRAPH_LOOPS_TWICE)); IGRAPH_FINALLY(igraph_inclist_destroy, &incident); IGRAPH_CHECK(igraph_vector_long_init(&neis, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &neis); IGRAPH_VECTOR_INIT_FINALLY(&actw, no_of_nodes); IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes)); igraph_vector_null(res); for (nn = no_of_nodes - 1; nn >= 0; nn--) { long int adjlen1, adjlen2; igraph_real_t triples; long int node = (long int) VECTOR(order)[nn]; IGRAPH_ALLOW_INTERRUPTION(); adj1 = igraph_inclist_get(&incident, node); adjlen1 = igraph_vector_int_size(adj1); triples = VECTOR(degree)[node] * (adjlen1 - 1) / 2.0; /* Mark the neighbors of the node */ for (i = 0; i < adjlen1; i++) { long int edge = (long int) VECTOR(*adj1)[i]; long int nei = IGRAPH_OTHER(graph, edge, node); VECTOR(neis)[nei] = node + 1; VECTOR(actw)[nei] = VECTOR(*weights)[edge]; } for (i = 0; i < adjlen1; i++) { long int edge1 = (long int) VECTOR(*adj1)[i]; igraph_real_t weight1 = VECTOR(*weights)[edge1]; long int nei = IGRAPH_OTHER(graph, edge1, node); long int j; if (VECTOR(rank)[nei] > VECTOR(rank)[node]) { adj2 = igraph_inclist_get(&incident, nei); adjlen2 = igraph_vector_int_size(adj2); for (j = 0; j < adjlen2; j++) { long int edge2 = (long int) VECTOR(*adj2)[j]; igraph_real_t weight2 = VECTOR(*weights)[edge2]; long int nei2 = IGRAPH_OTHER(graph, edge2, nei); if (VECTOR(rank)[nei2] < VECTOR(rank)[nei]) { continue; } if (VECTOR(neis)[nei2] == node + 1) { VECTOR(*res)[nei2] += (VECTOR(actw)[nei2] + weight2) / 2.0; VECTOR(*res)[nei] += (weight1 + weight2) / 2.0; VECTOR(*res)[node] += (VECTOR(actw)[nei2] + weight1) / 2.0; } } } } if (mode == IGRAPH_TRANSITIVITY_ZERO && triples == 0) { VECTOR(*res)[node] = 0.0; } else { VECTOR(*res)[node] /= triples; } } igraph_vector_destroy(&actw); igraph_vector_long_destroy(&neis); igraph_inclist_destroy(&incident); igraph_vector_destroy(&rank); igraph_vector_destroy(°ree); igraph_vector_destroy(&order); IGRAPH_FINALLY_CLEAN(6); return IGRAPH_SUCCESS; } /** * \function igraph_transitivity_barrat * Weighted transitivity, as defined by A. Barrat. * * This is a local transitivity, i.e. a vertex-level index. For a * given vertex \c i, from all triangles in which it participates we * consider the weight of the edges incident on \c i. The transitivity * is the sum of these weights divided by twice the strength of the * vertex (see \ref igraph_strength()) and the degree of the vertex * minus one. See Alain Barrat, Marc Barthelemy, Romualdo * Pastor-Satorras, Alessandro Vespignani: The architecture of complex * weighted networks, Proc. Natl. Acad. Sci. USA 101, 3747 (2004) at * http://arxiv.org/abs/cond-mat/0311416 for the exact formula. * * \param graph The input graph. Edge directions are ignored for * directed graphs. Note that the function does \em not work for * non-simple graphs. * \param res Pointer to an initialized vector, the result will be * stored here. It will be resized as needed. * \param vids The vertices for which the calculation is performed. * \param weights Edge weights. If this is a null pointer, then a * warning is given and \ref igraph_transitivity_local_undirected() * is called. * \param mode Defines how to treat vertices with zero strength. * \c IGRAPH_TRANSITIVITY_NAN says that the transitivity of these * vertices is \c NaN, \c IGRAPH_TRANSITIVITY_ZERO says it is zero. * * \return Error code. * * Time complexity: O(|V|*d^2), |V| is the number of vertices in * the graph, d is the average node degree. * * \sa \ref igraph_transitivity_undirected(), \ref * igraph_transitivity_local_undirected() and \ref * igraph_transitivity_avglocal_undirected() for other kinds of * (non-weighted) transitivity. */ int igraph_transitivity_barrat(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, const igraph_vector_t *weights, igraph_transitivity_mode_t mode) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_bool_t has_multiple; /* Handle fallback to unweighted version and common cases */ if (!weights) { if (no_of_edges != 0) { IGRAPH_WARNING("No weights given for Barrat's transitivity, unweighted version is used."); } return igraph_transitivity_local_undirected(graph, res, vids, mode); } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERRORF("Edge weight vector length (%ld) not equal to " "number of edges (%ld).", IGRAPH_EINVAL, igraph_vector_size(weights), no_of_edges); } if (no_of_nodes == 0) { igraph_vector_clear(res); return IGRAPH_SUCCESS; } IGRAPH_CHECK(igraph_has_multiple(graph, &has_multiple)); if (has_multiple) { IGRAPH_ERROR( "Barrat's weighted transitivity measure works only if the graph " "has no multiple edges.", IGRAPH_EINVAL ); } /* Preconditions validated, now we can call the real implementation */ if (igraph_vs_is_all(&vids)) { return igraph_i_transitivity_barrat4(graph, res, vids, weights, mode); } else { return igraph_i_transitivity_barrat1(graph, res, vids, weights, mode); } } leidenbase/src/core/properties/neighborhood.c0000644000176200001440000004303414447675375021125 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_neighborhood.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_operators.h" /** * \function igraph_neighborhood_size * \brief Calculates the size of the neighborhood of a given vertex. * * The neighborhood of a given order of a vertex includes all vertices * which are closer to the vertex than the order. I.e., order 0 is * always the vertex itself, order 1 is the vertex plus its immediate * neighbors, order 2 is order 1 plus the immediate neighbors of the * vertices in order 1, etc. * * * This function calculates the size of the neighborhood * of the given order for the given vertices. * * \param graph The input graph. * \param res Pointer to an initialized vector, the result will be * stored here. It will be resized as needed. * \param vids The vertices for which the calculation is performed. * \param order Integer giving the order of the neighborhood. * \param mode Specifies how to use the direction of the edges if a * directed graph is analyzed. For \c IGRAPH_OUT only the outgoing * edges are followed, so all vertices reachable from the source * vertex in at most \c order steps are counted. For \c IGRAPH_IN * all vertices from which the source vertex is reachable in at most * \c order steps are counted. \c IGRAPH_ALL ignores the direction * of the edges. This argument is ignored for undirected graphs. * \param mindist The minimum distance to include a vertex in the counting. * Vertices reachable with a path shorter than this value are excluded. * If this is one, then the starting vertex is not counted. If this is * two, then its neighbors are not counted either, etc. * \return Error code. * * \sa \ref igraph_neighborhood() for calculating the actual neighborhood, * \ref igraph_neighborhood_graphs() for creating separate graphs from * the neighborhoods. * * Time complexity: O(n*d*o), where n is the number vertices for which * the calculation is performed, d is the average degree, o is the order. */ int igraph_neighborhood_size(const igraph_t *graph, igraph_vector_t *res, igraph_vs_t vids, igraph_integer_t order, igraph_neimode_t mode, igraph_integer_t mindist) { long int no_of_nodes = igraph_vcount(graph); igraph_dqueue_t q; igraph_vit_t vit; long int i, j; long int *added; igraph_vector_t neis; if (order < 0) { IGRAPH_ERRORF("Negative order in neighborhood size: %" IGRAPH_PRId ".", IGRAPH_EINVAL, order); } if (mindist < 0 || mindist > order) { IGRAPH_ERRORF("Minimum distance should be between 0 and the neighborhood order (%" IGRAPH_PRId "), got %" IGRAPH_PRId ".", IGRAPH_EINVAL, order, mindist); } added = IGRAPH_CALLOC(no_of_nodes, long int); if (added == 0) { IGRAPH_ERROR("Cannot calculate neighborhood size.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_vector_resize(res, IGRAPH_VIT_SIZE(vit))); for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int node = IGRAPH_VIT_GET(vit); long int size = mindist == 0 ? 1 : 0; added[node] = i + 1; igraph_dqueue_clear(&q); if (order > 0) { igraph_dqueue_push(&q, node); igraph_dqueue_push(&q, 0); } while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); long int n; igraph_neighbors(graph, &neis, (igraph_integer_t) actnode, mode); n = igraph_vector_size(&neis); if (actdist < order - 1) { /* we add them to the q */ for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (added[nei] != i + 1) { added[nei] = i + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, nei)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); if (actdist + 1 >= mindist) { size++; } } } } else { /* we just count them, but don't add them */ for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (added[nei] != i + 1) { added[nei] = i + 1; if (actdist + 1 >= mindist) { size++; } } } } } /* while q not empty */ VECTOR(*res)[i] = size; } /* for VIT, i */ igraph_vector_destroy(&neis); igraph_vit_destroy(&vit); igraph_dqueue_destroy(&q); IGRAPH_FREE(added); IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; } /** * \function igraph_neighborhood * \brief Calculate the neighborhood of vertices. * * The neighborhood of a given order of a vertex includes all vertices * which are closer to the vertex than the order. I.e., order 0 is * always the vertex itself, order 1 is the vertex plus its immediate * neighbors, order 2 is order 1 plus the immediate neighbors of the * vertices in order 1, etc. * * * This function calculates the vertices within the * neighborhood of the specified vertices. * * \param graph The input graph. * \param res An initialized pointer vector. Note that the objects * (pointers) in the vector will \em not be freed, but the pointer * vector will be resized as needed. The result of the calculation * will be stored here in \ref igraph_vector_t objects. * \param vids The vertices for which the calculation is performed. * \param order Integer giving the order of the neighborhood. * \param mode Specifies how to use the direction of the edges if a * directed graph is analyzed. For \c IGRAPH_OUT only the outgoing * edges are followed, so all vertices reachable from the source * vertex in at most \p order steps are included. For \c IGRAPH_IN * all vertices from which the source vertex is reachable in at most * \p order steps are included. \c IGRAPH_ALL ignores the direction * of the edges. This argument is ignored for undirected graphs. * \param mindist The minimum distance to include a vertex in the counting. * Vertices reachable with a path shorter than this value are excluded. * If this is one, then the starting vertex is not counted. If this is * two, then its neighbors are not counted either, etc. * \return Error code. * * \sa \ref igraph_neighborhood_size() to calculate the size of the * neighborhood, \ref igraph_neighborhood_graphs() for creating * graphs from the neighborhoods. * * Time complexity: O(n*d*o), n is the number of vertices for which * the calculation is performed, d is the average degree, o is the * order. */ int igraph_neighborhood(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_vs_t vids, igraph_integer_t order, igraph_neimode_t mode, igraph_integer_t mindist) { long int no_of_nodes = igraph_vcount(graph); igraph_dqueue_t q; igraph_vit_t vit; long int i, j; long int *added; igraph_vector_t neis; igraph_vector_t tmp; igraph_vector_t *newv; if (order < 0) { IGRAPH_ERROR("Negative order in neighborhood size", IGRAPH_EINVAL); } if (mindist < 0 || mindist > order) { IGRAPH_ERROR("Minimum distance should be between zero and order", IGRAPH_EINVAL); } added = IGRAPH_CALLOC(no_of_nodes, long int); if (added == 0) { IGRAPH_ERROR("Cannot calculate neighborhood size", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_CHECK(igraph_vector_ptr_resize(res, IGRAPH_VIT_SIZE(vit))); for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int node = IGRAPH_VIT_GET(vit); added[node] = i + 1; igraph_vector_clear(&tmp); if (mindist == 0) { IGRAPH_CHECK(igraph_vector_push_back(&tmp, node)); } if (order > 0) { igraph_dqueue_push(&q, node); igraph_dqueue_push(&q, 0); } while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); long int n; igraph_neighbors(graph, &neis, (igraph_integer_t) actnode, mode); n = igraph_vector_size(&neis); if (actdist < order - 1) { /* we add them to the q */ for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (added[nei] != i + 1) { added[nei] = i + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, nei)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); if (actdist + 1 >= mindist) { IGRAPH_CHECK(igraph_vector_push_back(&tmp, nei)); } } } } else { /* we just count them but don't add them to q */ for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (added[nei] != i + 1) { added[nei] = i + 1; if (actdist + 1 >= mindist) { IGRAPH_CHECK(igraph_vector_push_back(&tmp, nei)); } } } } } /* while q not empty */ newv = IGRAPH_CALLOC(1, igraph_vector_t); if (newv == 0) { IGRAPH_ERROR("Cannot calculate neighborhood", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_vector_copy(newv, &tmp)); VECTOR(*res)[i] = newv; IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&tmp); igraph_vector_destroy(&neis); igraph_vit_destroy(&vit); igraph_dqueue_destroy(&q); IGRAPH_FREE(added); IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; } /** * \function igraph_neighborhood_graphs * \brief Create graphs from the neighborhood(s) of some vertex/vertices. * * The neighborhood of a given order of a vertex includes all vertices * which are closer to the vertex than the order. Ie. order 0 is * always the vertex itself, order 1 is the vertex plus its immediate * neighbors, order 2 is order 1 plus the immediate neighbors of the * vertices in order 1, etc. * * * This function finds every vertex in the neighborhood * of a given parameter vertex and creates the induced subgraph from these * vertices. * * * The first version of this function was written by * Vincent Matossian, thanks Vincent. * \param graph The input graph. * \param res Pointer to a pointer vector, the result will be stored * here, ie. \p res will contain pointers to \c igraph_t * objects. It will be resized if needed but note that the * objects in the pointer vector will not be freed. * \param vids The vertices for which the calculation is performed. * \param order Integer giving the order of the neighborhood. * \param mode Specifies how to use the direction of the edges if a * directed graph is analyzed. For \c IGRAPH_OUT only the outgoing * edges are followed, so all vertices reachable from the source * vertex in at most \p order steps are counted. For \c IGRAPH_IN * all vertices from which the source vertex is reachable in at most * \p order steps are counted. \c IGRAPH_ALL ignores the direction * of the edges. This argument is ignored for undirected graphs. * \param mindist The minimum distance to include a vertex in the counting. * Vertices reachable with a path shorter than this value are excluded. * If this is one, then the starting vertex is not counted. If this is * two, then its neighbors are not counted either, etc. * \return Error code. * * \sa \ref igraph_neighborhood_size() for calculating the neighborhood * sizes only, \ref igraph_neighborhood() for calculating the * neighborhoods (but not creating graphs). * * Time complexity: O(n*(|V|+|E|)), where n is the number vertices for * which the calculation is performed, |V| and |E| are the number of * vertices and edges in the original input graph. */ int igraph_neighborhood_graphs(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_vs_t vids, igraph_integer_t order, igraph_neimode_t mode, igraph_integer_t mindist) { long int no_of_nodes = igraph_vcount(graph); igraph_dqueue_t q; igraph_vit_t vit; long int i, j; long int *added; igraph_vector_t neis; igraph_vector_t tmp; igraph_t *newg; if (order < 0) { IGRAPH_ERROR("Negative order in neighborhood size", IGRAPH_EINVAL); } if (mindist < 0 || mindist > order) { IGRAPH_ERROR("Minimum distance should be between zero and order", IGRAPH_EINVAL); } added = IGRAPH_CALLOC(no_of_nodes, long int); if (added == 0) { IGRAPH_ERROR("Cannot calculate neighborhood size", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_CHECK(igraph_vector_ptr_resize(res, IGRAPH_VIT_SIZE(vit))); for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int node = IGRAPH_VIT_GET(vit); added[node] = i + 1; igraph_vector_clear(&tmp); if (mindist == 0) { IGRAPH_CHECK(igraph_vector_push_back(&tmp, node)); } if (order > 0) { igraph_dqueue_push(&q, node); igraph_dqueue_push(&q, 0); } while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); long int n; igraph_neighbors(graph, &neis, (igraph_integer_t) actnode, mode); n = igraph_vector_size(&neis); if (actdist < order - 1) { /* we add them to the q */ for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (added[nei] != i + 1) { added[nei] = i + 1; IGRAPH_CHECK(igraph_dqueue_push(&q, nei)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); if (actdist + 1 >= mindist) { IGRAPH_CHECK(igraph_vector_push_back(&tmp, nei)); } } } } else { /* we just count them but don't add them to q */ for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neis)[j]; if (added[nei] != i + 1) { added[nei] = i + 1; if (actdist + 1 >= mindist) { IGRAPH_CHECK(igraph_vector_push_back(&tmp, nei)); } } } } } /* while q not empty */ newg = IGRAPH_CALLOC(1, igraph_t); if (newg == 0) { IGRAPH_ERROR("Cannot create neighborhood graph", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newg); if (igraph_vector_size(&tmp) < no_of_nodes) { IGRAPH_CHECK(igraph_induced_subgraph(graph, newg, igraph_vss_vector(&tmp), IGRAPH_SUBGRAPH_AUTO)); } else { IGRAPH_CHECK(igraph_copy(newg, graph)); } VECTOR(*res)[i] = newg; IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&tmp); igraph_vector_destroy(&neis); igraph_vit_destroy(&vit); igraph_dqueue_destroy(&q); IGRAPH_FREE(added); IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; } leidenbase/src/core/properties/trees.c0000644000176200001440000002752214447675375017604 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_structural.h" #include "igraph_adjlist.h" #include "igraph_constructors.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_stack.h" /** * \function igraph_unfold_tree * Unfolding a graph into a tree, by possibly multiplicating its vertices. * * A graph is converted into a tree (or forest, if it is unconnected), * by performing a breadth-first search on it, and replicating * vertices that were found a second, third, etc. time. * \param graph The input graph, it can be either directed or * undirected. * \param tree Pointer to an uninitialized graph object, the result is * stored here. * \param mode For directed graphs; whether to follow paths along edge * directions (\c IGRAPH_OUT), or the opposite (\c IGRAPH_IN), or * ignore edge directions completely (\c IGRAPH_ALL). It is ignored * for undirected graphs. * \param roots A numeric vector giving the root vertex, or vertices * (if the graph is not connected), to start from. * \param vertex_index Pointer to an initialized vector, or a null * pointer. If not a null pointer, then a mapping from the vertices * in the new graph to the ones in the original is created here. * \return Error code. * * Time complexity: O(n+m), linear in the number vertices and edges. * */ int igraph_unfold_tree(const igraph_t *graph, igraph_t *tree, igraph_neimode_t mode, const igraph_vector_t *roots, igraph_vector_t *vertex_index) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int no_of_roots = igraph_vector_size(roots); long int tree_vertex_count = no_of_nodes; igraph_vector_t edges; igraph_vector_bool_t seen_vertices; igraph_vector_bool_t seen_edges; igraph_dqueue_t Q; igraph_vector_t neis; long int i, n, r, v_ptr = no_of_nodes; /* TODO: handle not-connected graphs, multiple root vertices */ IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); igraph_vector_reserve(&edges, no_of_edges * 2); IGRAPH_DQUEUE_INIT_FINALLY(&Q, 100); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_BOOL_INIT_FINALLY(&seen_vertices, no_of_nodes); IGRAPH_VECTOR_BOOL_INIT_FINALLY(&seen_edges, no_of_edges); if (vertex_index) { IGRAPH_CHECK(igraph_vector_resize(vertex_index, no_of_nodes)); for (i = 0; i < no_of_nodes; i++) { VECTOR(*vertex_index)[i] = i; } } for (r = 0; r < no_of_roots; r++) { long int root = (long int) VECTOR(*roots)[r]; VECTOR(seen_vertices)[root] = 1; igraph_dqueue_push(&Q, root); while (!igraph_dqueue_empty(&Q)) { long int actnode = (long int) igraph_dqueue_pop(&Q); IGRAPH_CHECK(igraph_incident(graph, &neis, (igraph_integer_t) actnode, mode)); n = igraph_vector_size(&neis); for (i = 0; i < n; i++) { long int edge = (long int) VECTOR(neis)[i]; long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO(graph, edge); long int nei = IGRAPH_OTHER(graph, edge, actnode); if (! VECTOR(seen_edges)[edge]) { VECTOR(seen_edges)[edge] = 1; if (! VECTOR(seen_vertices)[nei]) { igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); VECTOR(seen_vertices)[nei] = 1; IGRAPH_CHECK(igraph_dqueue_push(&Q, nei)); } else { tree_vertex_count++; if (vertex_index) { IGRAPH_CHECK(igraph_vector_push_back(vertex_index, nei)); } if (from == nei) { igraph_vector_push_back(&edges, v_ptr++); igraph_vector_push_back(&edges, to); } else { igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, v_ptr++); } } } } /* for i * * In the directed case, a possible additional requirement is that all * edges are oriented away from a root (out-tree or arborescence) or all edges * are oriented towards a root (in-tree or anti-arborescence). * This test can be controlled using the \p mode parameter. * * * By convention, the null graph (i.e. the graph with no vertices) is considered not to be a tree. * * \param graph The graph object to analyze. * \param res Pointer to a logical variable, the result will be stored * here. * \param root If not \c NULL, the root node will be stored here. When \p mode * is \c IGRAPH_ALL or the graph is undirected, any vertex can be the root * and \p root is set to 0 (the first vertex). When \p mode is \c IGRAPH_OUT * or \c IGRAPH_IN, the root is set to the vertex with zero in- or out-degree, * respectively. * \param mode For a directed graph this specifies whether to test for an * out-tree, an in-tree or ignore edge directions. The respective * possible values are: * \c IGRAPH_OUT, \c IGRAPH_IN, \c IGRAPH_ALL. This argument is * ignored for undirected graphs. * \return Error code: * \c IGRAPH_EINVAL: invalid mode argument. * * Time complexity: At most O(|V|+|E|), the * number of vertices plus the number of edges in the graph. * * \sa igraph_is_weakly_connected() * * \example examples/simple/igraph_tree.c */ int igraph_is_tree(const igraph_t *graph, igraph_bool_t *res, igraph_integer_t *root, igraph_neimode_t mode) { igraph_integer_t iroot = 0; igraph_integer_t visited_count; igraph_integer_t vcount, ecount; vcount = igraph_vcount(graph); ecount = igraph_ecount(graph); /* A tree must have precisely vcount-1 edges. */ /* By convention, the zero-vertex graph will not be considered a tree. */ if (ecount != vcount - 1) { *res = 0; return IGRAPH_SUCCESS; } /* The single-vertex graph is a tree, provided it has no edges (checked in the previous if (..)) */ if (vcount == 1) { *res = 1; if (root) { *root = 0; } return IGRAPH_SUCCESS; } /* For higher vertex counts we cannot short-circuit due to the possibility * of loops or multi-edges even when the edge count is correct. */ /* Ignore mode for undirected graphs. */ if (! igraph_is_directed(graph)) { mode = IGRAPH_ALL; } /* The main algorithm: * We find a root and check that all other vertices are reachable from it. * We have already checked the number of edges, so with the additional * reachability condition we can verify if the graph is a tree. * * For directed graphs, the root is the node with no incoming/outgoing * connections, depending on 'mode'. For undirected, it is arbitrary, so * we choose 0. */ *res = 1; /* assume success */ switch (mode) { case IGRAPH_ALL: iroot = 0; break; case IGRAPH_IN: case IGRAPH_OUT: { igraph_vector_t degree; igraph_integer_t i; IGRAPH_CHECK(igraph_vector_init(°ree, 0)); IGRAPH_FINALLY(igraph_vector_destroy, °ree); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), mode == IGRAPH_IN ? IGRAPH_OUT : IGRAPH_IN, /* loops = */ 1)); for (i = 0; i < vcount; ++i) { if (VECTOR(degree)[i] == 0) { break; } if (VECTOR(degree)[i] > 1) { /* In an out-tree, all vertices have in-degree 1, except for the root, * which has in-degree 0. Thus, if we encounter a larger in-degree, * the graph cannot be an out-tree. * We could perform this check for all degrees, but that would not * improve performance when the graph is indeed a tree, persumably * the most common case. Thus we only check until finding the root. */ *res = 0; break; } } /* If no suitable root is found, the graph is not a tree. */ if (*res && i == vcount) { *res = 0; } else { iroot = i; } igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); } break; default: IGRAPH_ERROR("Invalid mode,", IGRAPH_EINVMODE); } /* if no suitable root was found, skip visiting vertices */ if (*res) { IGRAPH_CHECK(igraph_i_is_tree_visitor(graph, iroot, mode, &visited_count)); *res = visited_count == vcount; } if (root) { *root = iroot; } return IGRAPH_SUCCESS; } leidenbase/src/core/properties/dag.c0000644000176200001440000002475614447675375017223 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_topology.h" #include "igraph_constructors.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_stack.h" /** * \function igraph_topological_sorting * \brief Calculate a possible topological sorting of the graph. * * * A topological sorting of a directed acyclic graph (DAG) is a linear ordering * of its vertices where each vertex comes before all nodes to which it has * edges. Every DAG has at least one topological sort, and may have many. * This function returns one possible topological sort among them. If the * graph contains any cycles that are not self-loops, an error is raised. * * \param graph The input graph. * \param res Pointer to a vector, the result will be stored here. * It will be resized if needed. * \param mode Specifies how to use the direction of the edges. * For \c IGRAPH_OUT, the sorting order ensures that each vertex comes * before all vertices to which it has edges, so vertices with no incoming * edges go first. For \c IGRAPH_IN, it is quite the opposite: each * vertex comes before all vertices from which it receives edges. Vertices * with no outgoing edges go first. * \return Error code. * * Time complexity: O(|V|+|E|), where |V| and |E| are the number of * vertices and edges in the original input graph. * * \sa \ref igraph_is_dag() if you are only interested in whether a given * graph is a DAG or not, or \ref igraph_feedback_arc_set() to find a * set of edges whose removal makes the graph acyclic. * * \example examples/simple/igraph_topological_sorting.c */ int igraph_topological_sorting(const igraph_t* graph, igraph_vector_t *res, igraph_neimode_t mode) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t degrees, neis; igraph_dqueue_t sources; igraph_neimode_t deg_mode; long int node, i, j; if (mode == IGRAPH_ALL || !igraph_is_directed(graph)) { IGRAPH_ERROR("Topological sorting does not make sense for undirected graphs", IGRAPH_EINVAL); } else if (mode == IGRAPH_OUT) { deg_mode = IGRAPH_IN; } else if (mode == IGRAPH_IN) { deg_mode = IGRAPH_OUT; } else { IGRAPH_ERROR("Invalid mode", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(°rees, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_dqueue_init(&sources, 0)); IGRAPH_FINALLY(igraph_dqueue_destroy, &sources); IGRAPH_CHECK(igraph_degree(graph, °rees, igraph_vss_all(), deg_mode, 0)); igraph_vector_clear(res); /* Do we have nodes with no incoming vertices? */ for (i = 0; i < no_of_nodes; i++) { if (VECTOR(degrees)[i] == 0) { IGRAPH_CHECK(igraph_dqueue_push(&sources, i)); } } /* Take all nodes with no incoming vertices and remove them */ while (!igraph_dqueue_empty(&sources)) { igraph_real_t tmp = igraph_dqueue_pop(&sources); node = (long) tmp; /* Add the node to the result vector */ igraph_vector_push_back(res, node); /* Exclude the node from further source searches */ VECTOR(degrees)[node] = -1; /* Get the neighbors and decrease their degrees by one */ IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) node, mode)); j = igraph_vector_size(&neis); for (i = 0; i < j; i++) { VECTOR(degrees)[(long)VECTOR(neis)[i]]--; if (VECTOR(degrees)[(long)VECTOR(neis)[i]] == 0) { IGRAPH_CHECK(igraph_dqueue_push(&sources, VECTOR(neis)[i])); } } } if (igraph_vector_size(res) < no_of_nodes) { IGRAPH_ERROR("The graph has cycles; topological sorting is only possible in acyclic graphs", IGRAPH_EINVAL); } igraph_vector_destroy(°rees); igraph_vector_destroy(&neis); igraph_dqueue_destroy(&sources); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_is_dag * \brief Checks whether a graph is a directed acyclic graph (DAG). * * * A directed acyclic graph (DAG) is a directed graph with no cycles. * * \param graph The input graph. * \param res Pointer to a boolean constant, the result * is stored here. * \return Error code. * * Time complexity: O(|V|+|E|), where |V| and |E| are the number of * vertices and edges in the original input graph. * * \sa \ref igraph_topological_sorting() to get a possible topological * sorting of a DAG. */ int igraph_is_dag(const igraph_t* graph, igraph_bool_t *res) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t degrees, neis; igraph_dqueue_t sources; long int node, i, j, nei, vertices_left; if (!igraph_is_directed(graph)) { *res = 0; return IGRAPH_SUCCESS; } IGRAPH_VECTOR_INIT_FINALLY(°rees, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_dqueue_init(&sources, 0)); IGRAPH_FINALLY(igraph_dqueue_destroy, &sources); IGRAPH_CHECK(igraph_degree(graph, °rees, igraph_vss_all(), IGRAPH_OUT, 1)); vertices_left = no_of_nodes; /* Do we have nodes with no incoming edges? */ for (i = 0; i < no_of_nodes; i++) { if (VECTOR(degrees)[i] == 0) { IGRAPH_CHECK(igraph_dqueue_push(&sources, i)); } } /* Take all nodes with no incoming edges and remove them */ while (!igraph_dqueue_empty(&sources)) { igraph_real_t tmp = igraph_dqueue_pop(&sources); node = (long) tmp; /* Exclude the node from further source searches */ VECTOR(degrees)[node] = -1; vertices_left--; /* Get the neighbors and decrease their degrees by one */ IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) node, IGRAPH_IN)); j = igraph_vector_size(&neis); for (i = 0; i < j; i++) { nei = (long)VECTOR(neis)[i]; if (nei == node) { continue; } VECTOR(degrees)[nei]--; if (VECTOR(degrees)[nei] == 0) { IGRAPH_CHECK(igraph_dqueue_push(&sources, nei)); } } } *res = (vertices_left == 0); if (vertices_left < 0) { IGRAPH_WARNING("vertices_left < 0 in igraph_is_dag, possible bug"); } igraph_vector_destroy(°rees); igraph_vector_destroy(&neis); igraph_dqueue_destroy(&sources); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; } /* Create the transitive closure of a tree graph. This is fairly simple, we just collect all ancestors of a vertex using a depth-first search. */ int igraph_transitive_closure_dag(const igraph_t *graph, igraph_t *closure) { long int no_of_nodes = igraph_vcount(graph); igraph_vector_t deg; igraph_vector_t new_edges; igraph_vector_t ancestors; long int root; igraph_vector_t neighbors; igraph_stack_t path; igraph_vector_bool_t done; if (!igraph_is_directed(graph)) { IGRAPH_ERROR("Tree transitive closure of a directed graph", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&new_edges, 0); IGRAPH_VECTOR_INIT_FINALLY(°, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&ancestors, 0); IGRAPH_VECTOR_INIT_FINALLY(&neighbors, 0); IGRAPH_CHECK(igraph_stack_init(&path, 0)); IGRAPH_FINALLY(igraph_stack_destroy, &path); IGRAPH_CHECK(igraph_vector_bool_init(&done, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &done); IGRAPH_CHECK(igraph_degree(graph, °, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS)); #define STAR (-1) for (root = 0; root < no_of_nodes; root++) { if (VECTOR(deg)[root] != 0) { continue; } IGRAPH_CHECK(igraph_stack_push(&path, root)); while (!igraph_stack_empty(&path)) { long int node = (long int) igraph_stack_top(&path); if (node == STAR) { /* Leaving a node */ long int j, n; igraph_stack_pop(&path); node = (long int) igraph_stack_pop(&path); if (!VECTOR(done)[node]) { igraph_vector_pop_back(&ancestors); VECTOR(done)[node] = 1; } n = igraph_vector_size(&ancestors); for (j = 0; j < n; j++) { IGRAPH_CHECK(igraph_vector_push_back(&new_edges, node)); IGRAPH_CHECK(igraph_vector_push_back(&new_edges, VECTOR(ancestors)[j])); } } else { /* Getting into a node */ long int n, j; if (!VECTOR(done)[node]) { IGRAPH_CHECK(igraph_vector_push_back(&ancestors, node)); } IGRAPH_CHECK(igraph_neighbors(graph, &neighbors, (igraph_integer_t) node, IGRAPH_IN)); n = igraph_vector_size(&neighbors); IGRAPH_CHECK(igraph_stack_push(&path, STAR)); for (j = 0; j < n; j++) { long int nei = (long int) VECTOR(neighbors)[j]; IGRAPH_CHECK(igraph_stack_push(&path, nei)); } } } } #undef STAR igraph_vector_bool_destroy(&done); igraph_stack_destroy(&path); igraph_vector_destroy(&neighbors); igraph_vector_destroy(&ancestors); igraph_vector_destroy(°); IGRAPH_FINALLY_CLEAN(5); IGRAPH_CHECK(igraph_create(closure, &new_edges, (igraph_integer_t)no_of_nodes, IGRAPH_DIRECTED)); igraph_vector_destroy(&new_edges); IGRAPH_FINALLY_CLEAN(1); return 0; } leidenbase/src/core/properties/properties_internal.h0000644000176200001440000000207714447675375022555 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2011-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IGRAPH_PROPERTIES_INTERNAL_H #define IGRAPH_PROPERTIES_INTERNAL_H #include "igraph_adjlist.h" #include "igraph_constants.h" #include "igraph_iterators.h" #include "igraph_types.h" int igraph_i_trans4_al_simplify(igraph_adjlist_t *al, const igraph_vector_int_t *rank); #endif leidenbase/src/core/properties/basic_properties.c0000644000176200001440000002665614447675375022026 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_structural.h" #include "igraph_interface.h" /** * \section about_structural * * These functions usually calculate some structural property * of a graph, like its diameter, the degree of the nodes, etc. */ /** * \function igraph_density * \brief Calculate the density of a graph. * * The density of a graph is simply the ratio of the actual number of its * edges and the largest possible number of edges it could have. * The maximum number of edges depends on interpretation: are vertices * allowed to have a connected to themselves? This is controlled by the * \p loops parameter. * * * Note that density is ill-defined for graphs which have multiple edges * between some pairs of vertices. Consider calling \ref igraph_simplify() * on such graphs. * * \param graph The input graph object. * \param res Pointer to a real number, the result will be stored * here. * \param loops Logical constant, whether to include self-loops in the * calculation. If this constant is TRUE then * loop edges are thought to be possible in the graph (this does not * necessarily mean that the graph really contains any loops). If * this is FALSE then the result is only correct if the graph does not * contain loops. * \return Error code. * * Time complexity: O(1). */ int igraph_density(const igraph_t *graph, igraph_real_t *res, igraph_bool_t loops) { igraph_integer_t no_of_nodes = igraph_vcount(graph); igraph_real_t no_of_edges = igraph_ecount(graph); igraph_bool_t directed = igraph_is_directed(graph); if (no_of_nodes == 0) { *res = IGRAPH_NAN; return 0; } if (!loops) { if (no_of_nodes == 1) { *res = IGRAPH_NAN; } else if (directed) { *res = no_of_edges / no_of_nodes / (no_of_nodes - 1); } else { *res = no_of_edges / no_of_nodes * 2.0 / (no_of_nodes - 1); } } else { if (directed) { *res = no_of_edges / no_of_nodes / no_of_nodes; } else { *res = no_of_edges / no_of_nodes * 2.0 / (no_of_nodes + 1); } } return 0; } /** * \function igraph_diversity * Structural diversity index of the vertices * * This measure was defined in Nathan Eagle, Michael Macy and Rob * Claxton: Network Diversity and Economic Development, Science 328, * 1029--1031, 2010. * * * It is simply the (normalized) Shannon entropy of the * incident edges' weights. D(i)=H(i)/log(k[i]), and * H(i) = -sum(p[i,j] log(p[i,j]), j=1..k[i]), * where p[i,j]=w[i,j]/sum(w[i,l], l=1..k[i]), k[i] is the (total) * degree of vertex i, and w[i,j] is the weight of the edge(s) between * vertex i and j. The diversity of isolated vertices will be NaN * (not-a-number), while that of vertices with a single connection * will be zero. * * * The measure works only if the graph is undirected and has no multiple edges. * If the graph has multiple edges, simplify it first using \ref * igraph_simplify(). If the graph is directed, convert it into an undirected * graph with \ref igraph_to_undirected() . * * \param graph The undirected input graph. * \param weights The edge weights, in the order of the edge ids, must * have appropriate length. Weights must be non-negative. * \param res An initialized vector, the results are stored here. * \param vids Vertex selector that specifies the vertices which to calculate * the measure. * \return Error code. * * Time complexity: O(|V|+|E|), linear. * */ int igraph_diversity(const igraph_t *graph, const igraph_vector_t *weights, igraph_vector_t *res, const igraph_vs_t vids) { long int no_of_edges = igraph_ecount(graph); long int k, i; igraph_vector_t incident; igraph_bool_t has_multiple; igraph_vit_t vit; if (igraph_is_directed(graph)) { IGRAPH_ERROR("Diversity measure works with undirected graphs only.", IGRAPH_EINVAL); } if (!weights) { IGRAPH_ERROR("Edge weights must be given.", IGRAPH_EINVAL); } if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Invalid edge weight vector length.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_has_multiple(graph, &has_multiple)); if (has_multiple) { IGRAPH_ERROR("Diversity measure works only if the graph has no multiple edges.", IGRAPH_EINVAL); } if (no_of_edges > 0) { igraph_real_t minweight = igraph_vector_min(weights); if (minweight < 0) { IGRAPH_ERROR("Weight vector must be non-negative.", IGRAPH_EINVAL); } else if (igraph_is_nan(minweight)) { IGRAPH_ERROR("Weight vector must not contain NaN values.", IGRAPH_EINVAL); } } IGRAPH_VECTOR_INIT_FINALLY(&incident, 10); IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); igraph_vector_clear(res); IGRAPH_CHECK(igraph_vector_reserve(res, IGRAPH_VIT_SIZE(vit))); for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { igraph_real_t d; long int v = IGRAPH_VIT_GET(vit); IGRAPH_CHECK(igraph_incident(graph, &incident, v, /*mode=*/ IGRAPH_ALL)); k = igraph_vector_size(&incident); /* degree */ /* * Non-normalized diversity is defined as * d = -sum_i w_i/s log (w_i/s) * where s = sum_i w_i. In order to avoid two passes through the w vector, * we use the equivalent formulation of * d = log s - (sum_i w_i log w_i) / s * However, this formulation may not give an exact 0.0 for some w when k=1, * due to roundoff errors (examples: w=3 or w=7). For this reason, we * special-case the computation for k=1 even for the unnormalized diversity * insted of just setting the normalization factor to 1 for this case. */ if (k == 0) { d = IGRAPH_NAN; } else if (k == 1) { if (VECTOR(*weights)[0] > 0) d = 0.0; /* s > 0 */ else d = IGRAPH_NAN; /* s == 0 */ } else { igraph_real_t s = 0.0, ent = 0.0; for (i = 0; i < k; i++) { igraph_real_t w = VECTOR(*weights)[(long int)VECTOR(incident)[i]]; if (w == 0) continue; s += w; ent += (w * log(w)); } d = (log(s) - ent / s) / log(k); } igraph_vector_push_back(res, d); /* reserved */ } igraph_vit_destroy(&vit); igraph_vector_destroy(&incident); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /** * \ingroup structural * \function igraph_reciprocity * \brief Calculates the reciprocity of a directed graph. * * * The measure of reciprocity defines the proportion of mutual * connections, in a directed graph. It is most commonly defined as * the probability that the opposite counterpart of a directed edge is * also included in the graph. In adjacency matrix notation: * sum(i, j, (A.*A')ij) / sum(i, j, Aij), where * A.*A' is the element-wise product of matrix * A and its transpose. This measure is * calculated if the \p mode argument is \c * IGRAPH_RECIPROCITY_DEFAULT. * * * Prior to igraph version 0.6, another measure was implemented, * defined as the probability of mutual connection between a vertex * pair if we know that there is a (possibly non-mutual) connection * between them. In other words, (unordered) vertex pairs are * classified into three groups: (1) disconnected, (2) * non-reciprocally connected, (3) reciprocally connected. * The result is the size of group (3), divided by the sum of group * sizes (2)+(3). This measure is calculated if \p mode is \c * IGRAPH_RECIPROCITY_RATIO. * * \param graph The graph object. * \param res Pointer to an \c igraph_real_t which will contain the result. * \param ignore_loops Whether to ignore loop edges. * \param mode Type of reciprocity to calculate, possible values are * \c IGRAPH_RECIPROCITY_DEFAULT and \c IGRAPH_RECIPROCITY_RATIO, * please see their description above. * \return Error code: * \c IGRAPH_EINVAL: graph has no edges * \c IGRAPH_ENOMEM: not enough memory for * temporary data. * * Time complexity: O(|V|+|E|), |V| is the number of vertices, * |E| is the number of edges. * * \example examples/simple/igraph_reciprocity.c */ int igraph_reciprocity(const igraph_t *graph, igraph_real_t *res, igraph_bool_t ignore_loops, igraph_reciprocity_t mode) { igraph_integer_t nonrec = 0, rec = 0, loops = 0; igraph_vector_t inneis, outneis; long int i; long int no_of_nodes = igraph_vcount(graph); if (mode != IGRAPH_RECIPROCITY_DEFAULT && mode != IGRAPH_RECIPROCITY_RATIO) { IGRAPH_ERROR("Invalid reciprocity type", IGRAPH_EINVAL); } /* THIS IS AN EXIT HERE !!!!!!!!!!!!!! */ if (!igraph_is_directed(graph)) { *res = 1.0; return 0; } IGRAPH_VECTOR_INIT_FINALLY(&inneis, 0); IGRAPH_VECTOR_INIT_FINALLY(&outneis, 0); for (i = 0; i < no_of_nodes; i++) { long int ip, op; igraph_neighbors(graph, &inneis, (igraph_integer_t) i, IGRAPH_IN); igraph_neighbors(graph, &outneis, (igraph_integer_t) i, IGRAPH_OUT); ip = op = 0; while (ip < igraph_vector_size(&inneis) && op < igraph_vector_size(&outneis)) { if (VECTOR(inneis)[ip] < VECTOR(outneis)[op]) { nonrec += 1; ip++; } else if (VECTOR(inneis)[ip] > VECTOR(outneis)[op]) { nonrec += 1; op++; } else { /* loop edge? */ if (VECTOR(inneis)[ip] == i) { loops += 1; if (!ignore_loops) { rec += 1; } } else { rec += 1; } ip++; op++; } } nonrec += (igraph_vector_size(&inneis) - ip) + (igraph_vector_size(&outneis) - op); } if (mode == IGRAPH_RECIPROCITY_DEFAULT) { if (ignore_loops) { *res = (igraph_real_t) rec / (igraph_ecount(graph) - loops); } else { *res = (igraph_real_t) rec / (igraph_ecount(graph)); } } else if (mode == IGRAPH_RECIPROCITY_RATIO) { *res = (igraph_real_t) rec / (rec + nonrec); } igraph_vector_destroy(&inneis); igraph_vector_destroy(&outneis); IGRAPH_FINALLY_CLEAN(2); return 0; } leidenbase/src/core/properties/girth.c0000644000176200001440000001644614447675375017602 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_structural.h" #include "igraph_adjlist.h" #include "igraph_components.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "core/interruption.h" #include /** * \function igraph_girth * \brief The girth of a graph is the length of the shortest cycle in it. * * * The current implementation works for undirected graphs only, * directed graphs are treated as undirected graphs. Self-loops and * multiple edges are ignored. * * * For graphs that contain no cycles, and only for such graphs, * zero is returned. Note that in some applications, it is customary * to define the girth of acyclic graphs to be infinity. However, infinity * is not representable as an \c igraph_integer_t, therefore zero is used * for this case. * * * This implementation is based on Alon Itai and Michael Rodeh: * Finding a minimum circuit in a graph * \emb Proceedings of the ninth annual ACM symposium on Theory of * computing \eme, 1-10, 1977. The first implementation of this * function was done by Keith Briggs, thanks Keith. * \param graph The input graph. * \param girth Pointer to an integer, if not \c NULL then the result * will be stored here. * \param circle Pointer to an initialized vector, the vertex ids in * the shortest circle will be stored here. If \c NULL then it is * ignored. * \return Error code. * * Time complexity: O((|V|+|E|)^2), |V| is the number of vertices, |E| * is the number of edges in the general case. If the graph has no * cycles at all then the function needs O(|V|+|E|) time to realize * this and then it stops. * * \example examples/simple/igraph_girth.c */ int igraph_girth(const igraph_t *graph, igraph_integer_t *girth, igraph_vector_t *circle) { long int no_of_nodes = igraph_vcount(graph); igraph_dqueue_t q; igraph_lazy_adjlist_t adjlist; long int mincirc = LONG_MAX, minvertex = 0; long int node; igraph_bool_t triangle = 0; igraph_vector_int_t *neis; igraph_vector_long_t level; long int stoplevel = no_of_nodes + 1; igraph_bool_t anycircle = 0; long int t1 = 0, t2 = 0; IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_CHECK(igraph_vector_long_init(&level, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &level); for (node = 0; !triangle && node < no_of_nodes; node++) { /* Are there circles in this graph at all? */ if (node == 1 && anycircle == 0) { igraph_bool_t conn; IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK)); if (conn) { /* No, there are none */ break; } } anycircle = 0; igraph_dqueue_clear(&q); igraph_vector_long_null(&level); IGRAPH_CHECK(igraph_dqueue_push(&q, node)); VECTOR(level)[node] = 1; IGRAPH_ALLOW_INTERRUPTION(); while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actlevel = VECTOR(level)[actnode]; long int i, n; if (actlevel >= stoplevel) { break; } neis = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) actnode); n = igraph_vector_int_size(neis); for (i = 0; i < n; i++) { long int nei = (long int) VECTOR(*neis)[i]; long int neilevel = VECTOR(level)[nei]; if (neilevel != 0) { if (neilevel == actlevel - 1) { continue; } else { /* found circle */ stoplevel = neilevel; anycircle = 1; if (actlevel < mincirc) { /* Is it a minimum circle? */ mincirc = actlevel + neilevel - 1; minvertex = node; t1 = actnode; t2 = nei; if (neilevel == 2) { /* Is it a triangle? */ triangle = 1; } } if (neilevel == actlevel) { break; } } } else { igraph_dqueue_push(&q, nei); VECTOR(level)[nei] = actlevel + 1; } } } /* while q !empty */ } /* node */ if (girth) { if (mincirc == LONG_MAX) { *girth = mincirc = 0; } else { *girth = (igraph_integer_t) mincirc; } } /* Store the actual circle, if needed */ if (circle) { IGRAPH_CHECK(igraph_vector_resize(circle, mincirc)); if (mincirc != 0) { long int i, n, idx = 0; igraph_dqueue_clear(&q); igraph_vector_long_null(&level); /* used for father pointers */ #define FATHER(x) (VECTOR(level)[(x)]) IGRAPH_CHECK(igraph_dqueue_push(&q, minvertex)); FATHER(minvertex) = minvertex; while (FATHER(t1) == 0 || FATHER(t2) == 0) { long int actnode = (long int) igraph_dqueue_pop(&q); neis = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) actnode); n = igraph_vector_int_size(neis); for (i = 0; i < n; i++) { long int nei = (long int) VECTOR(*neis)[i]; if (FATHER(nei) == 0) { FATHER(nei) = actnode + 1; igraph_dqueue_push(&q, nei); } } } /* while q !empty */ /* Ok, now use FATHER to create the path */ while (t1 != minvertex) { VECTOR(*circle)[idx++] = t1; t1 = FATHER(t1) - 1; } VECTOR(*circle)[idx] = minvertex; idx = mincirc - 1; while (t2 != minvertex) { VECTOR(*circle)[idx--] = t2; t2 = FATHER(t2) - 1; } } /* anycircle */ } /* circle */ #undef FATHER igraph_vector_long_destroy(&level); igraph_dqueue_destroy(&q); igraph_lazy_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(3); return 0; } leidenbase/src/core/properties/convergence_degree.c0000644000176200001440000002066414447675375022273 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_centrality.h" #include "igraph_adjlist.h" #include "igraph_dqueue.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "core/interruption.h" #include /** * \function igraph_convergence_degree * \brief Calculates the convergence degree of each edge in a graph. * * Let us define the input set of an edge (i, j) as the set of vertices where * the shortest paths passing through (i, j) originate, and similarly, let us * defined the output set of an edge (i, j) as the set of vertices where the * shortest paths passing through (i, j) terminate. The convergence degree of * an edge is defined as the normalized value of the difference between the * size of the input set and the output set, i.e. the difference of them * divided by the sum of them. Convergence degrees are in the range (-1, 1); a * positive value indicates that the edge is \em convergent since the shortest * paths passing through it originate from a larger set and terminate in a * smaller set, while a negative value indicates that the edge is \em divergent * since the paths originate from a small set and terminate in a larger set. * * * Note that the convergence degree as defined above does not make sense in * undirected graphs as there is no distinction between the input and output * set. Therefore, for undirected graphs, the input and output sets of an edge * are determined by orienting the edge arbitrarily while keeping the remaining * edges undirected, and then taking the absolute value of the convergence * degree. * * \param graph The input graph, it can be either directed or undirected. * \param result Pointer to an initialized vector; the convergence degrees of * each edge will be stored here. May be \c NULL if we are not interested in * the exact convergence degrees. * \param ins Pointer to an initialized vector; the size of the input set of * each edge will be stored here. May be \c NULL if we are not interested in * the sizes of the input sets. * \param outs Pointer to an initialized vector; the size of the output set of * each edge will be stored here. May be \c NULL if we are not interested in * the sizes of the output sets. * \return Error code. * * Time complexity: O(|V||E|), the number of vertices times the number of edges. */ int igraph_convergence_degree(const igraph_t *graph, igraph_vector_t *result, igraph_vector_t *ins, igraph_vector_t *outs) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int i, j, k, n; long int *geodist; igraph_vector_int_t *eids; igraph_vector_t *ins_p, *outs_p, ins_v, outs_v; igraph_dqueue_t q; igraph_inclist_t inclist; igraph_bool_t directed = igraph_is_directed(graph); if (result != 0) { IGRAPH_CHECK(igraph_vector_resize(result, no_of_edges)); } IGRAPH_CHECK(igraph_dqueue_init(&q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &q); if (ins == 0) { ins_p = &ins_v; IGRAPH_VECTOR_INIT_FINALLY(ins_p, no_of_edges); } else { ins_p = ins; IGRAPH_CHECK(igraph_vector_resize(ins_p, no_of_edges)); igraph_vector_null(ins_p); } if (outs == 0) { outs_p = &outs_v; IGRAPH_VECTOR_INIT_FINALLY(outs_p, no_of_edges); } else { outs_p = outs; IGRAPH_CHECK(igraph_vector_resize(outs_p, no_of_edges)); igraph_vector_null(outs_p); } geodist = IGRAPH_CALLOC(no_of_nodes, long int); if (geodist == 0) { IGRAPH_ERROR("Cannot calculate convergence degrees", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, geodist); /* Collect shortest paths originating from/to every node to correctly * determine input and output field sizes */ for (k = 0; k < (directed ? 2 : 1); k++) { igraph_neimode_t neimode = (k == 0) ? IGRAPH_OUT : IGRAPH_IN; igraph_real_t *vec; IGRAPH_CHECK(igraph_inclist_init(graph, &inclist, neimode, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_inclist_destroy, &inclist); vec = (k == 0) ? VECTOR(*ins_p) : VECTOR(*outs_p); for (i = 0; i < no_of_nodes; i++) { igraph_dqueue_clear(&q); memset(geodist, 0, sizeof(long int) * (size_t) no_of_nodes); geodist[i] = 1; IGRAPH_CHECK(igraph_dqueue_push(&q, i)); IGRAPH_CHECK(igraph_dqueue_push(&q, 0.0)); while (!igraph_dqueue_empty(&q)) { long int actnode = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); IGRAPH_ALLOW_INTERRUPTION(); eids = igraph_inclist_get(&inclist, actnode); n = igraph_vector_int_size(eids); for (j = 0; j < n; j++) { long int neighbor = IGRAPH_OTHER(graph, VECTOR(*eids)[j], actnode); if (geodist[neighbor] != 0) { /* we've already seen this node, another shortest path? */ if (geodist[neighbor] - 1 == actdist + 1) { /* Since this edge is in the BFS tree rooted at i, we must * increase either the size of the infield or the outfield */ if (!directed) { if (actnode < neighbor) { VECTOR(*ins_p)[(long int)VECTOR(*eids)[j]] += 1; } else { VECTOR(*outs_p)[(long int)VECTOR(*eids)[j]] += 1; } } else { vec[(long int)VECTOR(*eids)[j]] += 1; } } else if (geodist[neighbor] - 1 < actdist + 1) { continue; } } else { /* we haven't seen this node yet */ IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); /* Since this edge is in the BFS tree rooted at i, we must * increase either the size of the infield or the outfield */ if (!directed) { if (actnode < neighbor) { VECTOR(*ins_p)[(long int)VECTOR(*eids)[j]] += 1; } else { VECTOR(*outs_p)[(long int)VECTOR(*eids)[j]] += 1; } } else { vec[(long int)VECTOR(*eids)[j]] += 1; } geodist[neighbor] = actdist + 2; } } } } igraph_inclist_destroy(&inclist); IGRAPH_FINALLY_CLEAN(1); } if (result != 0) { for (i = 0; i < no_of_edges; i++) { VECTOR(*result)[i] = (VECTOR(*ins_p)[i] - VECTOR(*outs_p)[i]) / (VECTOR(*ins_p)[i] + VECTOR(*outs_p)[i]); } if (!directed) { for (i = 0; i < no_of_edges; i++) { if (VECTOR(*result)[i] < 0) { VECTOR(*result)[i] = -VECTOR(*result)[i]; } } } } if (ins == 0) { igraph_vector_destroy(ins_p); IGRAPH_FINALLY_CLEAN(1); } if (outs == 0) { igraph_vector_destroy(outs_p); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_FREE(geodist); igraph_dqueue_destroy(&q); IGRAPH_FINALLY_CLEAN(2); return 0; } leidenbase/src/core/properties/spectral.c0000644000176200001440000003771014447675375020277 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_structural.h" #include "igraph_interface.h" #include static int igraph_i_weighted_laplacian(const igraph_t *graph, igraph_matrix_t *res, igraph_sparsemat_t *sparseres, igraph_bool_t normalized, const igraph_vector_t *weights) { igraph_eit_t edgeit; int no_of_nodes = (int) igraph_vcount(graph); int no_of_edges = (int) igraph_ecount(graph); igraph_bool_t directed = igraph_is_directed(graph); igraph_vector_t degree; long int i; if (igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Invalid edge weight vector length", IGRAPH_EINVAL); } if (res) { IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, no_of_nodes)); igraph_matrix_null(res); } if (sparseres) { int nz = directed ? no_of_edges + no_of_nodes : no_of_edges * 2 + no_of_nodes; igraph_sparsemat_resize(sparseres, no_of_nodes, no_of_nodes, nz); } IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(0), &edgeit)); IGRAPH_FINALLY(igraph_eit_destroy, &edgeit); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); if (directed) { if (!normalized) { while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO (graph, edge); igraph_real_t weight = VECTOR(*weights)[edge]; if (from != to) { if (res) { MATRIX(*res, from, to) -= weight; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) from, (int)to, -weight)); } VECTOR(degree)[from] += weight; } IGRAPH_EIT_NEXT(edgeit); } /* And the diagonal */ for (i = 0; i < no_of_nodes; i++) { if (res) { MATRIX(*res, i, i) = VECTOR(degree)[i]; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) i, (int) i, VECTOR(degree)[i])); } } } else { /* normalized */ while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO (graph, edge); igraph_real_t weight = VECTOR(*weights)[edge]; if (from != to) { VECTOR(degree)[from] += weight; } IGRAPH_EIT_NEXT(edgeit); } for (i = 0; i < no_of_nodes; i++) { int t = VECTOR(degree)[i] > 0 ? 1 : 0; if (res) { MATRIX(*res, i, i) = t; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) i, (int) i, t)); } } IGRAPH_EIT_RESET(edgeit); while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO (graph, edge); igraph_real_t weight = VECTOR(*weights)[edge]; if (from != to) { igraph_real_t t = weight / VECTOR(degree)[from]; if (res) { MATRIX(*res, from, to) -= t; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) from, (int) to, -t)); } } IGRAPH_EIT_NEXT(edgeit); } } } else { /* undirected */ if (!normalized) { while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO (graph, edge); igraph_real_t weight = VECTOR(*weights)[edge]; if (from != to) { if (res) { MATRIX(*res, from, to) -= weight; MATRIX(*res, to, from) -= weight; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) from, (int) to, -weight)); IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) to, (int) from, -weight)); } VECTOR(degree)[from] += weight; VECTOR(degree)[to] += weight; } IGRAPH_EIT_NEXT(edgeit); } /* And the diagonal */ for (i = 0; i < no_of_nodes; i++) { if (res) { MATRIX(*res, i, i) = VECTOR(degree)[i]; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) i, (int) i, VECTOR(degree)[i])); } } } else { /* normalized */ while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO (graph, edge); igraph_real_t weight = VECTOR(*weights)[edge]; if (from != to) { VECTOR(degree)[from] += weight; VECTOR(degree)[to] += weight; } IGRAPH_EIT_NEXT(edgeit); } for (i = 0; i < no_of_nodes; i++) { int t = VECTOR(degree)[i] > 0 ? 1 : 0; if (res) { MATRIX(*res, i, i) = t; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) i, (int) i, t)); } VECTOR(degree)[i] = sqrt(VECTOR(degree)[i]); } IGRAPH_EIT_RESET(edgeit); while (!IGRAPH_EIT_END(edgeit)) { long int edge = IGRAPH_EIT_GET(edgeit); long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO (graph, edge); igraph_real_t weight = VECTOR(*weights)[edge]; if (from != to) { double diff = weight / (VECTOR(degree)[from] * VECTOR(degree)[to]); if (res) { MATRIX(*res, from, to) -= diff; MATRIX(*res, to, from) -= diff; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) from, (int) to, -diff)); IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, (int) to, (int) from, -diff)); } } IGRAPH_EIT_NEXT(edgeit); } } } igraph_vector_destroy(°ree); igraph_eit_destroy(&edgeit); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_laplacian * \brief Returns the Laplacian matrix of a graph * * * The graph Laplacian matrix is similar to an adjacency matrix but * contains -1's instead of 1's and the vertex degrees are included in * the diagonal. So the result for edge i--j is -1 if i!=j and is equal * to the degree of vertex i if i==j. igraph_laplacian will work on a * directed graph; in this case, the diagonal will contain the out-degrees. * Loop edges will be ignored. * * * The normalized version of the Laplacian matrix has 1 in the diagonal and * -1/sqrt(d[i]d[j]) if there is an edge from i to j. * * * The first version of this function was written by Vincent Matossian. * \param graph Pointer to the graph to convert. * \param res Pointer to an initialized matrix object, the result is * stored here. It will be resized if needed. * If it is a null pointer, then it is ignored. * At least one of \p res and \p sparseres must be a non-null pointer. * \param sparseres Pointer to an initialized sparse matrix object, the * result is stored here, if it is not a null pointer. * At least one of \p res and \p sparseres must be a non-null pointer. * \param normalized Whether to create a normalized Laplacian matrix. * \param weights An optional vector containing edge weights, to calculate * the weighted Laplacian matrix. Set it to a null pointer to * calculate the unweighted Laplacian. * \return Error code. * * Time complexity: O(|V||V|), * |V| is the * number of vertices in the graph. * * \example examples/simple/igraph_laplacian.c */ int igraph_laplacian(const igraph_t *graph, igraph_matrix_t *res, igraph_sparsemat_t *sparseres, igraph_bool_t normalized, const igraph_vector_t *weights) { igraph_eit_t edgeit; int no_of_nodes = (int) igraph_vcount(graph); int no_of_edges = (int) igraph_ecount(graph); igraph_bool_t directed = igraph_is_directed(graph); int from, to; igraph_integer_t ffrom, fto; igraph_vector_t degree; int i; if (!res && !sparseres) { IGRAPH_ERROR("Laplacian: give at least one of `res' or `sparseres'", IGRAPH_EINVAL); } if (weights) { return igraph_i_weighted_laplacian(graph, res, sparseres, normalized, weights); } if (res) { IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, no_of_nodes)); igraph_matrix_null(res); } if (sparseres) { int nz = directed ? no_of_edges + no_of_nodes : no_of_edges * 2 + no_of_nodes; IGRAPH_CHECK(igraph_sparsemat_resize(sparseres, no_of_nodes, no_of_nodes, nz)); } IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(0), &edgeit)); IGRAPH_FINALLY(igraph_eit_destroy, &edgeit); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_OUT, IGRAPH_NO_LOOPS)); if (directed) { if (!normalized) { for (i = 0; i < no_of_nodes; i++) { if (res) { MATRIX(*res, i, i) = VECTOR(degree)[i]; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, i, i, VECTOR(degree)[i])); } } while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from = ffrom; to = fto; if (from != to) { if (res) { MATRIX(*res, from, to) -= 1; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, from, to, -1.0)); } } IGRAPH_EIT_NEXT(edgeit); } } else { for (i = 0; i < no_of_nodes; i++) { int t = VECTOR(degree)[i] > 0 ? 1 : 0; if (res) { MATRIX(*res, i, i) = t; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, i, i, t)); } if (VECTOR(degree)[i] > 0) { VECTOR(degree)[i] = 1.0 / VECTOR(degree)[i]; } } while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from = ffrom; to = fto; if (from != to) { if (res) { MATRIX(*res, from, to) -= VECTOR(degree)[from]; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, from, to, -VECTOR(degree)[from])); } } IGRAPH_EIT_NEXT(edgeit); } } } else { if (!normalized) { for (i = 0; i < no_of_nodes; i++) { if (res) { MATRIX(*res, i, i) = VECTOR(degree)[i]; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, i, i, VECTOR(degree)[i])); } } while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from = ffrom; to = fto; if (from != to) { if (res) { MATRIX(*res, to, from) -= 1; MATRIX(*res, from, to) -= 1; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, to, from, -1.0)); IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, from, to, -1.0)); } } IGRAPH_EIT_NEXT(edgeit); } } else { for (i = 0; i < no_of_nodes; i++) { int t = VECTOR(degree)[i] > 0 ? 1 : 0; if (res) { MATRIX(*res, i, i) = t; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, i, i, t)); } VECTOR(degree)[i] = sqrt(VECTOR(degree)[i]); } while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from = ffrom; to = fto; if (from != to) { double diff = 1.0 / (VECTOR(degree)[from] * VECTOR(degree)[to]); if (res) { MATRIX(*res, from, to) -= diff; MATRIX(*res, to, from) -= diff; } if (sparseres) { IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, from, to, -diff)); IGRAPH_CHECK(igraph_sparsemat_entry(sparseres, to, from, -diff)); } } IGRAPH_EIT_NEXT(edgeit); } } } igraph_vector_destroy(°ree); igraph_eit_destroy(&edgeit); IGRAPH_FINALLY_CLEAN(2); return 0; } leidenbase/src/core/properties/multiplicity.c0000644000176200001440000002757714447675375021224 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_structural.h" #include "igraph_adjlist.h" #include "igraph_interface.h" /** * \function igraph_is_simple * \brief Decides whether the input graph is a simple graph. * * * A graph is a simple graph if it does not contain loop edges and * multiple edges. * * \param graph The input graph. * \param res Pointer to a boolean constant, the result * is stored here. * \return Error code. * * \sa \ref igraph_is_loop() and \ref igraph_is_multiple() to * find the loops and multiple edges, \ref igraph_simplify() to * get rid of them, or \ref igraph_has_multiple() to decide whether * there is at least one multiple edge. * * Time complexity: O(|V|+|E|). */ int igraph_is_simple(const igraph_t *graph, igraph_bool_t *res) { long int vc = igraph_vcount(graph); long int ec = igraph_ecount(graph); if (vc == 0 || ec == 0) { *res = 1; } else { igraph_vector_t neis; long int i, j, n; igraph_bool_t found = 0; IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); for (i = 0; i < vc; i++) { IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) i, IGRAPH_OUT)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { if (VECTOR(neis)[j] == i) { found = 1; break; } if (j > 0 && VECTOR(neis)[j - 1] == VECTOR(neis)[j]) { found = 1; break; } } } *res = !found; igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_has_multiple * \brief Check whether the graph has at least one multiple edge. * * * An edge is a multiple edge if there is another * edge with the same head and tail vertices in the graph. * * \param graph The input graph. * \param res Pointer to a boolean variable, the result will be stored here. * \return Error code. * * \sa \ref igraph_count_multiple(), \ref igraph_is_multiple() and \ref igraph_simplify(). * * Time complexity: O(e*d), e is the number of edges to check and d is the * average degree (out-degree in directed graphs) of the vertices at the * tail of the edges. * * \example examples/simple/igraph_has_multiple.c */ int igraph_has_multiple(const igraph_t *graph, igraph_bool_t *res) { long int vc = igraph_vcount(graph); long int ec = igraph_ecount(graph); igraph_bool_t directed = igraph_is_directed(graph); if (vc == 0 || ec == 0) { *res = 0; } else { igraph_vector_t neis; long int i, j, n; igraph_bool_t found = 0; IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); for (i = 0; i < vc && !found; i++) { IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) i, IGRAPH_OUT)); n = igraph_vector_size(&neis); for (j = 1; j < n; j++) { if (VECTOR(neis)[j - 1] == VECTOR(neis)[j]) { /* If the graph is undirected, loop edges appear twice in the neighbor * list, so check the next item as well */ if (directed) { /* Directed, so this is a real multiple edge */ found = 1; break; } else if (VECTOR(neis)[j - 1] != i) { /* Undirected, but not a loop edge */ found = 1; break; } else if (j < n - 1 && VECTOR(neis)[j] == VECTOR(neis)[j + 1]) { /* Undirected, loop edge, multiple times */ found = 1; break; } } } } *res = found; igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \function igraph_is_multiple * \brief Find the multiple edges in a graph. * * * An edge is a multiple edge if there is another * edge with the same head and tail vertices in the graph. * * * Note that this function returns true only for the second or more * appearances of the multiple edges. * \param graph The input graph. * \param res Pointer to a boolean vector, the result will be stored * here. It will be resized as needed. * \param es The edges to check. Supply \ref igraph_ess_all() if you want * to check all edges. * \return Error code. * * \sa \ref igraph_count_multiple(), \ref igraph_has_multiple() and \ref igraph_simplify(). * * Time complexity: O(e*d), e is the number of edges to check and d is the * average degree (out-degree in directed graphs) of the vertices at the * tail of the edges. * * \example examples/simple/igraph_is_multiple.c */ int igraph_is_multiple(const igraph_t *graph, igraph_vector_bool_t *res, igraph_es_t es) { igraph_eit_t eit; long int i, j, n; igraph_lazy_inclist_t inclist; IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &inclist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); IGRAPH_CHECK(igraph_vector_bool_resize(res, IGRAPH_EIT_SIZE(eit))); for (i = 0; !IGRAPH_EIT_END(eit); i++, IGRAPH_EIT_NEXT(eit)) { long int e = IGRAPH_EIT_GET(eit); long int from = IGRAPH_FROM(graph, e); long int to = IGRAPH_TO(graph, e); igraph_vector_int_t *neis = igraph_lazy_inclist_get(&inclist, (igraph_integer_t) from); if (neis == 0) { /* Most likely out of memory */ IGRAPH_ERROR("Out of memory while building lazy incidence list", IGRAPH_ENOMEM); } VECTOR(*res)[i] = 0; n = igraph_vector_int_size(neis); for (j = 0; j < n; j++) { long int e2 = (long int) VECTOR(*neis)[j]; long int to2 = IGRAPH_OTHER(graph, e2, from); if (to2 == to && e2 < e) { VECTOR(*res)[i] = 1; } } } igraph_lazy_inclist_destroy(&inclist); igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_count_multiple * \brief Count the number of appearances of the edges in a graph. * * * If the graph has no multiple edges then the result vector will be * filled with ones. * (An edge is a multiple edge if there is another * edge with the same head and tail vertices in the graph.) * * * \param graph The input graph. * \param res Pointer to a vector, the result will be stored * here. It will be resized as needed. * \param es The edges to check. Supply \ref igraph_ess_all() if you want * to check all edges. * \return Error code. * * \sa \ref igraph_is_multiple() and \ref igraph_simplify(). * * Time complexity: O(E d), E is the number of edges to check and d is the * average degree (out-degree in directed graphs) of the vertices at the * tail of the edges. */ int igraph_count_multiple(const igraph_t *graph, igraph_vector_t *res, igraph_es_t es) { igraph_eit_t eit; long int i, j, n; igraph_lazy_inclist_t inclist; IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); IGRAPH_CHECK(igraph_lazy_inclist_init(graph, &inclist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE)); IGRAPH_FINALLY(igraph_lazy_inclist_destroy, &inclist); IGRAPH_CHECK(igraph_vector_resize(res, IGRAPH_EIT_SIZE(eit))); for (i = 0; !IGRAPH_EIT_END(eit); i++, IGRAPH_EIT_NEXT(eit)) { long int e = IGRAPH_EIT_GET(eit); long int from = IGRAPH_FROM(graph, e); long int to = IGRAPH_TO(graph, e); igraph_vector_int_t *neis = igraph_lazy_inclist_get(&inclist, (igraph_integer_t) from); if (neis == 0) { /* Most likely out of memory */ IGRAPH_ERROR("Out of memory while building lazy incidence list", IGRAPH_ENOMEM); } VECTOR(*res)[i] = 0; n = igraph_vector_int_size(neis); for (j = 0; j < n; j++) { long int e2 = (long int) VECTOR(*neis)[j]; long int to2 = IGRAPH_OTHER(graph, e2, from); if (to2 == to) { VECTOR(*res)[i] += 1; } } } igraph_lazy_inclist_destroy(&inclist); igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } /** * \function igraph_is_mutual * Check whether the edges of a directed graph are mutual. * * An (A,B) edge is mutual if the graph contains the (B,A) edge, too. * * * An undirected graph only has mutual edges, by definition. * * * Edge multiplicity is not considered here, e.g. if there are two * (A,B) edges and one (B,A) edge, then all three are considered to be * mutual. * * * Loops are always mutual. * * \param graph The input graph. * \param res Pointer to an initialized vector, the result is stored * here. * \param es The sequence of edges to check. Supply * igraph_ess_all() for all edges, see \ref * igraph_ess_all(). * \return Error code. * * Time complexity: O(n log(d)), n is the number of edges supplied, d * is the maximum in-degree of the vertices that are targets of the * supplied edges. An upper limit of the time complexity is O(n log(|E|)), * |E| is the number of edges in the graph. */ int igraph_is_mutual(const igraph_t *graph, igraph_vector_bool_t *res, igraph_es_t es) { igraph_eit_t eit; igraph_lazy_adjlist_t adjlist; long int i; /* How many edges do we have? */ IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); IGRAPH_CHECK(igraph_vector_bool_resize(res, IGRAPH_EIT_SIZE(eit))); /* An undirected graph has mutual edges by definition, res is already properly resized */ if (! igraph_is_directed(graph)) { igraph_vector_bool_fill(res, 1); igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist); for (i = 0; ! IGRAPH_EIT_END(eit); i++, IGRAPH_EIT_NEXT(eit)) { long int edge = IGRAPH_EIT_GET(eit); long int from = IGRAPH_FROM(graph, edge); long int to = IGRAPH_TO(graph, edge); /* Check whether there is a to->from edge, search for from in the out-list of to. We don't search an empty vector, because vector_binsearch seems to have a bug with this. */ igraph_vector_int_t *neis = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) to); if (igraph_vector_int_empty(neis)) { VECTOR(*res)[i] = 0; } else { VECTOR(*res)[i] = igraph_vector_int_binsearch2(neis, from); } } igraph_lazy_adjlist_destroy(&adjlist); igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } leidenbase/src/core/properties/constraint.c0000644000176200001440000003015714447675375020644 0ustar liggesusers/* -*- mode: C -*- */ /* vim:set ts=4 sw=4 sts=4 et: */ /* IGraph library. Copyright (C) 2005-2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_centrality.h" #include "igraph_interface.h" /** * \function igraph_constraint * \brief Burt's constraint scores. * * * This function calculates Burt's constraint scores for the given * vertices, also known as structural holes. * * * Burt's constraint is higher if ego has less, or mutually stronger * related (i.e. more redundant) contacts. Burt's measure of * constraint, C[i], of vertex i's ego network V[i], is defined for * directed and valued graphs, *
* C[i] = sum( sum( (p[i,q] p[q,j])^2, q in V[i], q != i,j ), j in * V[], j != i) *
* for a graph of order (i.e. number of vertices) N, where proportional * tie strengths are defined as *
* p[i,j]=(a[i,j]+a[j,i]) / sum(a[i,k]+a[k,i], k in V[i], k != i), *
* a[i,j] are elements of A and * the latter being the graph adjacency matrix. For isolated vertices, * constraint is undefined. * *
* Burt, R.S. (2004). Structural holes and good ideas. American * Journal of Sociology 110, 349-399. * * * The first R version of this function was contributed by Jeroen * Bruggeman. * \param graph A graph object. * \param res Pointer to an initialized vector, the result will be * stored here. The vector will be resized to have the * appropriate size for holding the result. * \param vids Vertex selector containing the vertices for which the * constraint should be calculated. * \param weights Vector giving the weights of the edges. If it is * \c NULL then each edge is supposed to have the same weight. * \return Error code. * * Time complexity: O(|V|+E|+n*d^2), n is the number of vertices for * which the constraint is calculated and d is the average degree, |V| * is the number of vertices, |E| the number of edges in the * graph. If the weights argument is \c NULL then the time complexity * is O(|V|+n*d^2). */ int igraph_constraint(const igraph_t *graph, igraph_vector_t *res, igraph_vs_t vids, const igraph_vector_t *weights) { long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_vit_t vit; long int nodes_to_calc; long int a, b, c, i, j, q, vsize, vsize2; igraph_integer_t edge, from, to, edge2; igraph_vector_t contrib; igraph_vector_t degree; igraph_vector_t ineis_in, ineis_out, jneis_in, jneis_out; if (weights != 0 && igraph_vector_size(weights) != no_of_edges) { IGRAPH_ERROR("Invalid length of weight vector", IGRAPH_EINVAL); } IGRAPH_VECTOR_INIT_FINALLY(&contrib, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(°ree, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&ineis_in, 0); IGRAPH_VECTOR_INIT_FINALLY(&ineis_out, 0); IGRAPH_VECTOR_INIT_FINALLY(&jneis_in, 0); IGRAPH_VECTOR_INIT_FINALLY(&jneis_out, 0); IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc = IGRAPH_VIT_SIZE(vit); if (weights == 0) { IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, IGRAPH_NO_LOOPS)); } else { for (a = 0; a < no_of_edges; a++) { igraph_edge(graph, (igraph_integer_t) a, &from, &to); if (from != to) { VECTOR(degree)[(long int) from] += VECTOR(*weights)[a]; VECTOR(degree)[(long int) to ] += VECTOR(*weights)[a]; } } } IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); igraph_vector_null(res); for (a = 0; a < nodes_to_calc; a++, IGRAPH_VIT_NEXT(vit)) { i = IGRAPH_VIT_GET(vit); /* get neighbors of i */ IGRAPH_CHECK(igraph_incident(graph, &ineis_in, (igraph_integer_t) i, IGRAPH_IN)); IGRAPH_CHECK(igraph_incident(graph, &ineis_out, (igraph_integer_t) i, IGRAPH_OUT)); /* NaN for isolates */ if (igraph_vector_size(&ineis_in) == 0 && igraph_vector_size(&ineis_out) == 0) { VECTOR(*res)[a] = IGRAPH_NAN; } /* zero their contribution */ vsize = igraph_vector_size(&ineis_in); for (b = 0; b < vsize; b++) { edge = (igraph_integer_t) VECTOR(ineis_in)[b]; j = (long int) IGRAPH_OTHER(graph, edge, i); VECTOR(contrib)[j] = 0.0; } vsize = igraph_vector_size(&ineis_out); for (b = 0; b < vsize; b++) { edge = (igraph_integer_t) VECTOR(ineis_out)[b]; j = (long int) IGRAPH_OTHER(graph, edge, i); VECTOR(contrib)[j] = 0.0; } /* add the direct contributions, in-neighbors and out-neighbors */ vsize = igraph_vector_size(&ineis_in); for (b = 0; b < vsize; b++) { edge = (igraph_integer_t) VECTOR(ineis_in)[b]; j = (long int) IGRAPH_OTHER(graph, edge, i); if (i != j) { /* excluding loops */ if (weights) { VECTOR(contrib)[j] += VECTOR(*weights)[(long int)edge] / VECTOR(degree)[i]; } else { VECTOR(contrib)[j] += 1.0 / VECTOR(degree)[i]; } } } if (igraph_is_directed(graph)) { vsize = igraph_vector_size(&ineis_out); for (b = 0; b < vsize; b++) { edge = (igraph_integer_t) VECTOR(ineis_out)[b]; j = (long int) IGRAPH_OTHER(graph, edge, i); if (i != j) { if (weights) { VECTOR(contrib)[j] += VECTOR(*weights)[(long int)edge] / VECTOR(degree)[i]; } else { VECTOR(contrib)[j] += 1.0 / VECTOR(degree)[i]; } } } } /* add the indirect contributions, in-in, in-out, out-in, out-out */ vsize = igraph_vector_size(&ineis_in); for (b = 0; b < vsize; b++) { edge = (igraph_integer_t) VECTOR(ineis_in)[b]; j = (long int) IGRAPH_OTHER(graph, edge, i); if (i == j) { continue; } IGRAPH_CHECK(igraph_incident(graph, &jneis_in, (igraph_integer_t) j, IGRAPH_IN)); IGRAPH_CHECK(igraph_incident(graph, &jneis_out, (igraph_integer_t) j, IGRAPH_OUT)); vsize2 = igraph_vector_size(&jneis_in); for (c = 0; c < vsize2; c++) { edge2 = (igraph_integer_t) VECTOR(jneis_in)[c]; q = (long int) IGRAPH_OTHER(graph, edge2, j); if (j != q) { if (weights) { VECTOR(contrib)[q] += VECTOR(*weights)[(long int)edge] * VECTOR(*weights)[(long int)edge2] / VECTOR(degree)[i] / VECTOR(degree)[j]; } else { VECTOR(contrib)[q] += 1 / VECTOR(degree)[i] / VECTOR(degree)[j]; } } } if (igraph_is_directed(graph)) { vsize2 = igraph_vector_size(&jneis_out); for (c = 0; c < vsize2; c++) { edge2 = (igraph_integer_t) VECTOR(jneis_out)[c]; q = (long int) IGRAPH_OTHER(graph, edge2, j); if (j != q) { if (weights) { VECTOR(contrib)[q] += VECTOR(*weights)[(long int)edge] * VECTOR(*weights)[(long int)edge2] / VECTOR(degree)[i] / VECTOR(degree)[j]; } else { VECTOR(contrib)[q] += 1 / VECTOR(degree)[i] / VECTOR(degree)[j]; } } } } } if (igraph_is_directed(graph)) { vsize = igraph_vector_size(&ineis_out); for (b = 0; b < vsize; b++) { edge = (igraph_integer_t) VECTOR(ineis_out)[b]; j = (long int) IGRAPH_OTHER(graph, edge, i); if (i == j) { continue; } IGRAPH_CHECK(igraph_incident(graph, &jneis_in, (igraph_integer_t) j, IGRAPH_IN)); IGRAPH_CHECK(igraph_incident(graph, &jneis_out, (igraph_integer_t) j, IGRAPH_OUT)); vsize2 = igraph_vector_size(&jneis_in); for (c = 0; c < vsize2; c++) { edge2 = (igraph_integer_t) VECTOR(jneis_in)[c]; q = (long int) IGRAPH_OTHER(graph, edge2, j); if (j != q) { if (weights) { VECTOR(contrib)[q] += VECTOR(*weights)[(long int)edge] * VECTOR(*weights)[(long int)edge2] / VECTOR(degree)[i] / VECTOR(degree)[j]; } else { VECTOR(contrib)[q] += 1 / VECTOR(degree)[i] / VECTOR(degree)[j]; } } } vsize2 = igraph_vector_size(&jneis_out); for (c = 0; c < vsize2; c++) { edge2 = (igraph_integer_t) VECTOR(jneis_out)[c]; q = (long int) IGRAPH_OTHER(graph, edge2, j); if (j != q) { if (weights) { VECTOR(contrib)[q] += VECTOR(*weights)[(long int)edge] * VECTOR(*weights)[(long int)edge2] / VECTOR(degree)[i] / VECTOR(degree)[j]; } else { VECTOR(contrib)[q] += 1 / VECTOR(degree)[i] / VECTOR(degree)[j]; } } } } } /* squared sum of the contributions */ vsize = igraph_vector_size(&ineis_in); for (b = 0; b < vsize; b++) { edge = (igraph_integer_t) VECTOR(ineis_in)[b]; j = (long int) IGRAPH_OTHER(graph, edge, i); if (i == j) { continue; } VECTOR(*res)[a] += VECTOR(contrib)[j] * VECTOR(contrib)[j]; VECTOR(contrib)[j] = 0.0; } if (igraph_is_directed(graph)) { vsize = igraph_vector_size(&ineis_out); for (b = 0; b < vsize; b++) { edge = (igraph_integer_t) VECTOR(ineis_out)[b]; j = (long int) IGRAPH_OTHER(graph, edge, i); if (i == j) { continue; } VECTOR(*res)[a] += VECTOR(contrib)[j] * VECTOR(contrib)[j]; VECTOR(contrib)[j] = 0.0; } } } igraph_vit_destroy(&vit); igraph_vector_destroy(&jneis_out); igraph_vector_destroy(&jneis_in); igraph_vector_destroy(&ineis_out); igraph_vector_destroy(&ineis_in); igraph_vector_destroy(°ree); igraph_vector_destroy(&contrib); IGRAPH_FINALLY_CLEAN(7); return 0; } leidenbase/src/core/graph/0000755000176200001440000000000014532173045015171 5ustar liggesusersleidenbase/src/core/graph/visitors.c0000644000176200001440000005676114447675374017257 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph R package. Copyright (C) 2006-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_visitor.h" #include "igraph_memory.h" #include "igraph_adjlist.h" #include "igraph_interface.h" #include "igraph_dqueue.h" #include "igraph_stack.h" /** * \function igraph_bfs * Breadth-first search * * A simple breadth-first search, with a lot of different results and * the possibility to call a callback whenever a vertex is visited. * It is allowed to supply null pointers as the output arguments the * user is not interested in, in this case they will be ignored. * * * If not all vertices can be reached from the supplied root vertex, * then additional root vertices will be used, in the order of their * vertex ids. * * * Consider using \ref igraph_bfs_simple instead if you set most of the output * arguments provided by this function to a null pointer. * * \param graph The input graph. * \param root The id of the root vertex. It is ignored if the \c * roots argument is not a null pointer. * \param roots Pointer to an initialized vector, or a null * pointer. If not a null pointer, then it is a vector * containing root vertices to start the BFS from. The vertices * are considered in the order they appear. If a root vertex * was already found while searching from another one, then no * search is conducted from it. * \param mode For directed graphs, it defines which edges to follow. * \c IGRAPH_OUT means following the direction of the edges, * \c IGRAPH_IN means the opposite, and * \c IGRAPH_ALL ignores the direction of the edges. * This parameter is ignored for undirected graphs. * \param unreachable Logical scalar, whether the search should visit * the vertices that are unreachable from the given root * node(s). If true, then additional searches are performed * until all vertices are visited. * \param restricted If not a null pointer, then it must be a pointer * to a vector containing vertex ids. The BFS is carried out * only on these vertices. * \param order If not null pointer, then the vertex ids of the graph are * stored here, in the same order as they were visited. * \param rank If not a null pointer, then the rank of each vertex is * stored here. * \param father If not a null pointer, then the id of the father of * each vertex is stored here. * \param pred If not a null pointer, then the id of vertex that was * visited before the current one is stored here. If there is * no such vertex (the current vertex is the root of a search * tree), then -1 is stored. * \param succ If not a null pointer, then the id of the vertex that * was visited after the current one is stored here. If there * is no such vertex (the current one is the last in a search * tree), then -1 is stored. * \param dist If not a null pointer, then the distance from the root of * the current search tree is stored here. * \param callback If not null, then it should be a pointer to a * function of type \ref igraph_bfshandler_t. This function * will be called, whenever a new vertex is visited. * \param extra Extra argument to pass to the callback function. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. * * \example examples/simple/igraph_bfs.c * \example examples/simple/igraph_bfs_callback.c */ int igraph_bfs(const igraph_t *graph, igraph_integer_t root, const igraph_vector_t *roots, igraph_neimode_t mode, igraph_bool_t unreachable, const igraph_vector_t *restricted, igraph_vector_t *order, igraph_vector_t *rank, igraph_vector_t *father, igraph_vector_t *pred, igraph_vector_t *succ, igraph_vector_t *dist, igraph_bfshandler_t *callback, void *extra) { igraph_dqueue_t Q; long int no_of_nodes = igraph_vcount(graph); long int actroot = 0; igraph_vector_char_t added; igraph_lazy_adjlist_t adjlist; long int act_rank = 0; long int pred_vec = -1; long int rootpos = 0; long int noroots = roots ? igraph_vector_size(roots) : 1; if (!roots && (root < 0 || root >= no_of_nodes)) { IGRAPH_ERROR("Invalid root vertex in BFS", IGRAPH_EINVAL); } if (roots && noroots > 0) { igraph_real_t min, max; igraph_vector_minmax(roots, &min, &max); if (min < 0 || max >= no_of_nodes) { IGRAPH_ERROR("Invalid root vertex in BFS", IGRAPH_EINVAL); } } if (restricted && igraph_vector_size(restricted) > 0) { igraph_real_t min, max; igraph_vector_minmax(restricted, &min, &max); if (min < 0 || max >= no_of_nodes) { IGRAPH_ERROR("Invalid vertex id in restricted set", IGRAPH_EINVAL); } } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } IGRAPH_CHECK(igraph_vector_char_init(&added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_char_destroy, &added); IGRAPH_CHECK(igraph_dqueue_init(&Q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &Q); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist); /* Mark the vertices that are not in the restricted set, as already found. Special care must be taken for vertices that are not in the restricted set, but are to be used as 'root' vertices. */ if (restricted) { long int i, n = igraph_vector_size(restricted); igraph_vector_char_fill(&added, 1); for (i = 0; i < n; i++) { long int v = (long int) VECTOR(*restricted)[i]; VECTOR(added)[v] = 0; } } /* Resize result vectors, and fill them with IGRAPH_NAN */ # define VINIT(v) if (v) { \ igraph_vector_resize((v), no_of_nodes); \ igraph_vector_fill((v), IGRAPH_NAN); } VINIT(order); VINIT(rank); VINIT(father); VINIT(pred); VINIT(succ); VINIT(dist); # undef VINIT while (1) { /* Get the next root vertex, if any */ if (roots && rootpos < noroots) { /* We are still going through the 'roots' vector */ actroot = (long int) VECTOR(*roots)[rootpos++]; } else if (!roots && rootpos == 0) { /* We have a single root vertex given, and start now */ actroot = root; rootpos++; } else if (rootpos == noroots && unreachable) { /* We finished the given root(s), but other vertices are also tried as root */ actroot = 0; rootpos++; } else if (unreachable && actroot + 1 < no_of_nodes) { /* We are already doing the other vertices, take the next one */ actroot++; } else { /* No more root nodes to do */ break; } /* OK, we have a new root, start BFS */ if (VECTOR(added)[actroot]) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&Q, actroot)); IGRAPH_CHECK(igraph_dqueue_push(&Q, 0)); VECTOR(added)[actroot] = 1; if (father) { VECTOR(*father)[actroot] = -1; } pred_vec = -1; while (!igraph_dqueue_empty(&Q)) { long int actvect = (long int) igraph_dqueue_pop(&Q); long int actdist = (long int) igraph_dqueue_pop(&Q); long int succ_vec; igraph_vector_int_t *neis = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) actvect); long int i, n = igraph_vector_int_size(neis); if (pred) { VECTOR(*pred)[actvect] = pred_vec; } if (rank) { VECTOR(*rank) [actvect] = act_rank; } if (order) { VECTOR(*order)[act_rank++] = actvect; } if (dist) { VECTOR(*dist)[actvect] = actdist; } for (i = 0; i < n; i++) { long int nei = (long int) VECTOR(*neis)[i]; if (! VECTOR(added)[nei]) { VECTOR(added)[nei] = 1; IGRAPH_CHECK(igraph_dqueue_push(&Q, nei)); IGRAPH_CHECK(igraph_dqueue_push(&Q, actdist + 1)); if (father) { VECTOR(*father)[nei] = actvect; } } } succ_vec = igraph_dqueue_empty(&Q) ? -1L : (long int) igraph_dqueue_head(&Q); if (callback) { igraph_bool_t terminate = callback(graph, (igraph_integer_t) actvect, (igraph_integer_t) pred_vec, (igraph_integer_t) succ_vec, (igraph_integer_t) act_rank - 1, (igraph_integer_t) actdist, extra); if (terminate) { igraph_lazy_adjlist_destroy(&adjlist); igraph_dqueue_destroy(&Q); igraph_vector_char_destroy(&added); IGRAPH_FINALLY_CLEAN(3); return 0; } } if (succ) { VECTOR(*succ)[actvect] = succ_vec; } pred_vec = actvect; } /* while Q !empty */ } /* for actroot < no_of_nodes */ igraph_lazy_adjlist_destroy(&adjlist); igraph_dqueue_destroy(&Q); igraph_vector_char_destroy(&added); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_bfs_simple * Breadth-first search, single-source version * * An alternative breadth-first search implementation to cater for the * simpler use-cases when only a single breadth-first search has to be conducted * from a source node and most of the output arguments from \ref igraph_bfs * are not needed. It is allowed to supply null pointers as * the output arguments the user is not interested in, in this case they will * be ignored. * * \param graph The input graph. * \param vid The id of the root vertex. * \param mode For directed graphs, it defines which edges to follow. * \c IGRAPH_OUT means following the direction of the edges, * \c IGRAPH_IN means the opposite, and * \c IGRAPH_ALL ignores the direction of the edges. * This parameter is ignored for undirected graphs. * \param vids If not a null pointer, then an initialized vector must be passed * here. The ids of the vertices visited during the traversal will be * stored here, in the same order as they were visited. * \param layers If not a null pointer, then an initialized vector must be * passed here. The i-th element of the vector will contain the index * into \c vids where the vertices that are at distance i from the root * are stored. In other words, if you are interested in the vertices that * are at distance i from the root, you need to look in the \c vids * vector from \c layers[i] to \c layers[i+1]. * \param parents If not a null pointer, then an initialized vector must be * passed here. The vector will be resized so its length is equal to the * number of nodes, and it will contain the index of the parent node for * each \em visited node. The values in the vector are undefined for * vertices that were \em not visited. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. * * \example examples/simple/igraph_bfs_simple.c */ int igraph_bfs_simple(igraph_t *graph, igraph_integer_t vid, igraph_neimode_t mode, igraph_vector_t *vids, igraph_vector_t *layers, igraph_vector_t *parents) { igraph_dqueue_t q; long int num_visited = 0; igraph_vector_t neis; long int no_of_nodes = igraph_vcount(graph); long int i; char *added; long int lastlayer = -1; if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } /* temporary storage */ added = IGRAPH_CALLOC(no_of_nodes, char); if (added == 0) { IGRAPH_ERROR("Cannot calculate BFS", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_dqueue_init(&q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &q); /* results */ if (vids) { igraph_vector_clear(vids); } if (layers) { igraph_vector_clear(layers); } if (parents) { IGRAPH_CHECK(igraph_vector_resize(parents, no_of_nodes)); } /* ok start with vid */ IGRAPH_CHECK(igraph_dqueue_push(&q, vid)); IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); if (layers) { IGRAPH_CHECK(igraph_vector_push_back(layers, num_visited)); } if (vids) { IGRAPH_CHECK(igraph_vector_push_back(vids, vid)); } if (parents) { VECTOR(*parents)[(long int)vid] = vid; } num_visited++; added[(long int)vid] = 1; while (!igraph_dqueue_empty(&q)) { long int actvect = (long int) igraph_dqueue_pop(&q); long int actdist = (long int) igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) actvect, mode)); for (i = 0; i < igraph_vector_size(&neis); i++) { long int neighbor = (long int) VECTOR(neis)[i]; if (added[neighbor] == 0) { added[neighbor] = 1; if (parents) { VECTOR(*parents)[neighbor] = actvect; } IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist + 1)); if (layers && lastlayer != actdist + 1) { IGRAPH_CHECK(igraph_vector_push_back(layers, num_visited)); } if (vids) { IGRAPH_CHECK(igraph_vector_push_back(vids, neighbor)); } num_visited++; lastlayer = actdist + 1; } } /* for i in neis */ } /* while ! dqueue_empty */ if (layers) { IGRAPH_CHECK(igraph_vector_push_back(layers, num_visited)); } igraph_vector_destroy(&neis); igraph_dqueue_destroy(&q); IGRAPH_FREE(added); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_dfs * Depth-first search * * A simple depth-first search, with * the possibility to call a callback whenever a vertex is discovered * and/or whenever a subtree is finished. * It is allowed to supply null pointers as the output arguments the * user is not interested in, in this case they will be ignored. * * * If not all vertices can be reached from the supplied root vertex, * then additional root vertices will be used, in the order of their * vertex ids. * * \param graph The input graph. * \param root The id of the root vertex. * \param mode For directed graphs, it defines which edges to follow. * \c IGRAPH_OUT means following the direction of the edges, * \c IGRAPH_IN means the opposite, and * \c IGRAPH_ALL ignores the direction of the edges. * This parameter is ignored for undirected graphs. * \param unreachable Logical scalar, whether the search should visit * the vertices that are unreachable from the given root * node(s). If true, then additional searches are performed * until all vertices are visited. * \param order If not null pointer, then the vertex ids of the graph are * stored here, in the same order as they were discovered. * \param order_out If not a null pointer, then the vertex ids of the * graphs are stored here, in the order of the completion of * their subtree. * \param father If not a null pointer, then the id of the father of * each vertex is stored here. * \param dist If not a null pointer, then the distance from the root of * the current search tree is stored here. * \param in_callback If not null, then it should be a pointer to a * function of type \ref igraph_dfshandler_t. This function * will be called, whenever a new vertex is discovered. * \param out_callback If not null, then it should be a pointer to a * function of type \ref igraph_dfshandler_t. This function * will be called, whenever the subtree of a vertex is completed. * \param extra Extra argument to pass to the callback function(s). * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. */ int igraph_dfs(const igraph_t *graph, igraph_integer_t root, igraph_neimode_t mode, igraph_bool_t unreachable, igraph_vector_t *order, igraph_vector_t *order_out, igraph_vector_t *father, igraph_vector_t *dist, igraph_dfshandler_t *in_callback, igraph_dfshandler_t *out_callback, void *extra) { long int no_of_nodes = igraph_vcount(graph); igraph_lazy_adjlist_t adjlist; igraph_stack_t stack; igraph_vector_char_t added; igraph_vector_long_t nptr; long int actroot; long int act_rank = 0; long int rank_out = 0; long int act_dist = 0; if (root < 0 || root >= no_of_nodes) { IGRAPH_ERROR("Invalid root vertex for DFS", IGRAPH_EINVAL); } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } IGRAPH_CHECK(igraph_vector_char_init(&added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_char_destroy, &added); IGRAPH_CHECK(igraph_stack_init(&stack, 100)); IGRAPH_FINALLY(igraph_stack_destroy, &stack); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS, IGRAPH_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_vector_long_init(&nptr, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &nptr); # define FREE_ALL() do { \ igraph_vector_long_destroy(&nptr); \ igraph_lazy_adjlist_destroy(&adjlist); \ igraph_stack_destroy(&stack); \ igraph_vector_char_destroy(&added); \ IGRAPH_FINALLY_CLEAN(4); } while (0) /* Resize result vectors and fill them with IGRAPH_NAN */ # define VINIT(v) if (v) { \ igraph_vector_resize(v, no_of_nodes); \ igraph_vector_fill(v, IGRAPH_NAN); } VINIT(order); VINIT(order_out); VINIT(father); VINIT(dist); # undef VINIT IGRAPH_CHECK(igraph_stack_push(&stack, root)); VECTOR(added)[(long int)root] = 1; if (father) { VECTOR(*father)[(long int)root] = -1; } if (order) { VECTOR(*order)[act_rank++] = root; } if (dist) { VECTOR(*dist)[(long int)root] = 0; } if (in_callback) { igraph_bool_t terminate = in_callback(graph, root, 0, extra); if (terminate) { FREE_ALL(); return 0; } } for (actroot = 0; actroot < no_of_nodes; ) { /* 'root' first, then all other vertices */ if (igraph_stack_empty(&stack)) { if (!unreachable) { break; } if (VECTOR(added)[actroot]) { actroot++; continue; } IGRAPH_CHECK(igraph_stack_push(&stack, actroot)); VECTOR(added)[actroot] = 1; if (father) { VECTOR(*father)[actroot] = -1; } if (order) { VECTOR(*order)[act_rank++] = actroot; } if (dist) { VECTOR(*dist)[actroot] = 0; } if (in_callback) { igraph_bool_t terminate = in_callback(graph, (igraph_integer_t) actroot, 0, extra); if (terminate) { FREE_ALL(); return 0; } } actroot++; } while (!igraph_stack_empty(&stack)) { long int actvect = (long int) igraph_stack_top(&stack); igraph_vector_int_t *neis = igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) actvect); long int n = igraph_vector_int_size(neis); long int *ptr = igraph_vector_long_e_ptr(&nptr, actvect); /* Search for a neighbor that was not yet visited */ igraph_bool_t any = 0; long int nei = 0; while (!any && (*ptr) < n) { nei = (long int) VECTOR(*neis)[(*ptr)]; any = !VECTOR(added)[nei]; (*ptr) ++; } if (any) { /* There is such a neighbor, add it */ IGRAPH_CHECK(igraph_stack_push(&stack, nei)); VECTOR(added)[nei] = 1; if (father) { VECTOR(*father)[ nei ] = actvect; } if (order) { VECTOR(*order)[act_rank++] = nei; } act_dist++; if (dist) { VECTOR(*dist)[nei] = act_dist; } if (in_callback) { igraph_bool_t terminate = in_callback(graph, (igraph_integer_t) nei, (igraph_integer_t) act_dist, extra); if (terminate) { FREE_ALL(); return 0; } } } else { /* There is no such neighbor, finished with the subtree */ igraph_stack_pop(&stack); if (order_out) { VECTOR(*order_out)[rank_out++] = actvect; } act_dist--; if (out_callback) { igraph_bool_t terminate = out_callback(graph, (igraph_integer_t) actvect, (igraph_integer_t) act_dist, extra); if (terminate) { FREE_ALL(); return 0; } } } } } FREE_ALL(); # undef FREE_ALL return 0; } leidenbase/src/core/graph/type_indexededgelist.c0000644000176200001440000021665514447675374021577 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_datatype.h" #include "igraph_interface.h" #include "igraph_memory.h" #include "graph/attributes.h" #include "graph/neighbors.h" /* Internal functions */ static int igraph_i_create_start( igraph_vector_t *res, igraph_vector_t *el, igraph_vector_t *index, igraph_integer_t nodes); /** * \section about_basic_interface * * This is the very minimal API in \a igraph. All the other * functions use this minimal set for creating and manipulating * graphs. * * This is a very important principle since it makes possible to * implement other data representations by implementing only this * minimal set. */ /** * \ingroup interface * \function igraph_empty * \brief Creates an empty graph with some vertices and no edges. * * * The most basic constructor, all the other constructors should call * this to create a minimal graph object. Our use of the term "empty graph" * in the above description should be distinguished from the mathematical * definition of the empty or null graph. Strictly speaking, the empty or null * graph in graph theory is the graph with no vertices and no edges. However * by "empty graph" as used in \c igraph we mean a graph having zero or more * vertices, but no edges. * \param graph Pointer to a not-yet initialized graph object. * \param n The number of vertices in the graph, a non-negative * integer number is expected. * \param directed Boolean; whether the graph is directed or not. Supported * values are: * \clist * \cli IGRAPH_DIRECTED * The graph will be \em directed. * \cli IGRAPH_UNDIRECTED * The graph will be \em undirected. * \endclist * \return Error code: * \c IGRAPH_EINVAL: invalid number of vertices. * * Time complexity: O(|V|) for a graph with * |V| vertices (and no edges). * * \example examples/simple/igraph_empty.c */ int igraph_empty(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed) { return igraph_empty_attrs(graph, n, directed, 0); } /** * \ingroup interface * \function igraph_empty_attrs * \brief Creates an empty graph with some vertices, no edges and some graph attributes. * * * Use this instead of \ref igraph_empty() if you wish to add some graph * attributes right after initialization. This function is currently * not very interesting for the ordinary user. Just supply 0 here or * use \ref igraph_empty(). * \param graph Pointer to a not-yet initialized graph object. * \param n The number of vertices in the graph; a non-negative * integer number is expected. * \param directed Boolean; whether the graph is directed or not. Supported * values are: * \clist * \cli IGRAPH_DIRECTED * Create a \em directed graph. * \cli IGRAPH_UNDIRECTED * Create an \em undirected graph. * \endclist * \param attr The attributes. * \return Error code: * \c IGRAPH_EINVAL: invalid number of vertices. * * Time complexity: O(|V|) for a graph with * |V| vertices (and no edges). */ int igraph_empty_attrs(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, void* attr) { if (n < 0) { IGRAPH_ERROR("cannot create empty graph with negative number of vertices", IGRAPH_EINVAL); } if (!IGRAPH_FINITE(n)) { IGRAPH_ERROR("number of vertices is not finite (NA, NaN or Inf)", IGRAPH_EINVAL); } graph->n = 0; graph->directed = directed; IGRAPH_VECTOR_INIT_FINALLY(&graph->from, 0); IGRAPH_VECTOR_INIT_FINALLY(&graph->to, 0); IGRAPH_VECTOR_INIT_FINALLY(&graph->oi, 0); IGRAPH_VECTOR_INIT_FINALLY(&graph->ii, 0); IGRAPH_VECTOR_INIT_FINALLY(&graph->os, 1); IGRAPH_VECTOR_INIT_FINALLY(&graph->is, 1); VECTOR(graph->os)[0] = 0; VECTOR(graph->is)[0] = 0; /* init attributes */ graph->attr = 0; IGRAPH_CHECK(igraph_i_attribute_init(graph, attr)); /* add the vertices */ IGRAPH_CHECK(igraph_add_vertices(graph, n, 0)); IGRAPH_FINALLY_CLEAN(6); return 0; } /** * \ingroup interface * \function igraph_destroy * \brief Frees the memory allocated for a graph object. * * * This function should be called for every graph object exactly once. * * * This function invalidates all iterators (of course), but the * iterators of a graph should be destroyed before the graph itself * anyway. * \param graph Pointer to the graph to free. * * Time complexity: operating system specific. */ void igraph_destroy(igraph_t *graph) { IGRAPH_I_ATTRIBUTE_DESTROY(graph); igraph_vector_destroy(&graph->from); igraph_vector_destroy(&graph->to); igraph_vector_destroy(&graph->oi); igraph_vector_destroy(&graph->ii); igraph_vector_destroy(&graph->os); igraph_vector_destroy(&graph->is); } /** * \ingroup interface * \function igraph_copy * \brief Creates an exact (deep) copy of a graph. * * * This function deeply copies a graph object to create an exact * replica of it. The new replica should be destroyed by calling * \ref igraph_destroy() on it when not needed any more. * * * You can also create a shallow copy of a graph by simply using the * standard assignment operator, but be careful and do \em not * destroy a shallow replica. To avoid this mistake, creating shallow * copies is not recommended. * \param to Pointer to an uninitialized graph object. * \param from Pointer to the graph object to copy. * \return Error code. * * Time complexity: O(|V|+|E|) for a * graph with |V| vertices and * |E| edges. * * \example examples/simple/igraph_copy.c */ int igraph_copy(igraph_t *to, const igraph_t *from) { to->n = from->n; to->directed = from->directed; IGRAPH_CHECK(igraph_vector_copy(&to->from, &from->from)); IGRAPH_FINALLY(igraph_vector_destroy, &to->from); IGRAPH_CHECK(igraph_vector_copy(&to->to, &from->to)); IGRAPH_FINALLY(igraph_vector_destroy, &to->to); IGRAPH_CHECK(igraph_vector_copy(&to->oi, &from->oi)); IGRAPH_FINALLY(igraph_vector_destroy, &to->oi); IGRAPH_CHECK(igraph_vector_copy(&to->ii, &from->ii)); IGRAPH_FINALLY(igraph_vector_destroy, &to->ii); IGRAPH_CHECK(igraph_vector_copy(&to->os, &from->os)); IGRAPH_FINALLY(igraph_vector_destroy, &to->os); IGRAPH_CHECK(igraph_vector_copy(&to->is, &from->is)); IGRAPH_FINALLY(igraph_vector_destroy, &to->is); IGRAPH_I_ATTRIBUTE_COPY(to, from, 1, 1, 1); /* does IGRAPH_CHECK */ IGRAPH_FINALLY_CLEAN(6); return 0; } /** * \ingroup interface * \function igraph_add_edges * \brief Adds edges to a graph object. * * * The edges are given in a vector, the * first two elements define the first edge (the order is * from, to for directed * graphs). The vector * should contain even number of integer numbers between zero and the * number of vertices in the graph minus one (inclusive). If you also * want to add new vertices, call igraph_add_vertices() first. * \param graph The graph to which the edges will be added. * \param edges The edges themselves. * \param attr The attributes of the new edges, only used by high level * interfaces currently, you can supply 0 here. * \return Error code: * \c IGRAPH_EINVEVECTOR: invalid (odd) * edges vector length, \c IGRAPH_EINVVID: * invalid vertex id in edges vector. * * This function invalidates all iterators. * * * Time complexity: O(|V|+|E|) where * |V| is the number of vertices and * |E| is the number of * edges in the \em new, extended graph. * * \example examples/simple/igraph_add_edges.c */ int igraph_add_edges(igraph_t *graph, const igraph_vector_t *edges, void *attr) { long int no_of_edges = igraph_vector_size(&graph->from); long int edges_to_add = igraph_vector_size(edges) / 2; long int i = 0; igraph_error_handler_t *oldhandler; int ret1, ret2; igraph_vector_t newoi, newii; igraph_bool_t directed = igraph_is_directed(graph); if (igraph_vector_size(edges) % 2 != 0) { IGRAPH_ERROR("invalid (odd) length of edges vector", IGRAPH_EINVEVECTOR); } if (!igraph_vector_isininterval(edges, 0, igraph_vcount(graph) - 1)) { IGRAPH_ERROR("cannot add edges", IGRAPH_EINVVID); } /* from & to */ IGRAPH_CHECK(igraph_vector_reserve(&graph->from, no_of_edges + edges_to_add)); IGRAPH_CHECK(igraph_vector_reserve(&graph->to, no_of_edges + edges_to_add)); while (i < edges_to_add * 2) { if (directed || VECTOR(*edges)[i] > VECTOR(*edges)[i + 1]) { igraph_vector_push_back(&graph->from, VECTOR(*edges)[i++]); /* reserved */ igraph_vector_push_back(&graph->to, VECTOR(*edges)[i++]); /* reserved */ } else { igraph_vector_push_back(&graph->to, VECTOR(*edges)[i++]); /* reserved */ igraph_vector_push_back(&graph->from, VECTOR(*edges)[i++]); /* reserved */ } } /* disable the error handler temporarily */ oldhandler = igraph_set_error_handler(igraph_error_handler_ignore); /* oi & ii */ ret1 = igraph_vector_init(&newoi, no_of_edges); ret2 = igraph_vector_init(&newii, no_of_edges); if (ret1 != 0 || ret2 != 0) { igraph_vector_resize(&graph->from, no_of_edges); /* gets smaller */ igraph_vector_resize(&graph->to, no_of_edges); /* gets smaller */ igraph_set_error_handler(oldhandler); IGRAPH_ERROR("cannot add edges", IGRAPH_ERROR_SELECT_2(ret1, ret2)); } ret1 = igraph_vector_order(&graph->from, &graph->to, &newoi, graph->n); ret2 = igraph_vector_order(&graph->to, &graph->from, &newii, graph->n); if (ret1 != 0 || ret2 != 0) { igraph_vector_resize(&graph->from, no_of_edges); igraph_vector_resize(&graph->to, no_of_edges); igraph_vector_destroy(&newoi); igraph_vector_destroy(&newii); igraph_set_error_handler(oldhandler); IGRAPH_ERROR("cannot add edges", IGRAPH_ERROR_SELECT_2(ret1, ret2)); } /* Attributes */ if (graph->attr) { igraph_set_error_handler(oldhandler); ret1 = igraph_i_attribute_add_edges(graph, edges, attr); igraph_set_error_handler(igraph_error_handler_ignore); if (ret1 != 0) { igraph_vector_resize(&graph->from, no_of_edges); igraph_vector_resize(&graph->to, no_of_edges); igraph_vector_destroy(&newoi); igraph_vector_destroy(&newii); igraph_set_error_handler(oldhandler); IGRAPH_ERROR("cannot add edges", ret1); } } /* os & is, its length does not change, error safe */ igraph_i_create_start(&graph->os, &graph->from, &newoi, graph->n); igraph_i_create_start(&graph->is, &graph->to, &newii, graph->n); /* everything went fine */ igraph_vector_destroy(&graph->oi); igraph_vector_destroy(&graph->ii); graph->oi = newoi; graph->ii = newii; igraph_set_error_handler(oldhandler); return 0; } /** * \ingroup interface * \function igraph_add_vertices * \brief Adds vertices to a graph. * * * This function invalidates all iterators. * * \param graph The graph object to extend. * \param nv Non-negative integer giving the number of * vertices to add. * \param attr The attributes of the new vertices, only used by * high level interfaces, you can supply 0 here. * \return Error code: * \c IGRAPH_EINVAL: invalid number of new * vertices. * * Time complexity: O(|V|) where * |V| is * the number of vertices in the \em new, extended graph. * * \example examples/simple/igraph_add_vertices.c */ int igraph_add_vertices(igraph_t *graph, igraph_integer_t nv, void *attr) { long int ec = igraph_ecount(graph); long int i; if (nv < 0) { IGRAPH_ERROR("cannot add negative number of vertices", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_reserve(&graph->os, graph->n + nv + 1)); IGRAPH_CHECK(igraph_vector_reserve(&graph->is, graph->n + nv + 1)); igraph_vector_resize(&graph->os, graph->n + nv + 1); /* reserved */ igraph_vector_resize(&graph->is, graph->n + nv + 1); /* reserved */ for (i = graph->n + 1; i < graph->n + nv + 1; i++) { VECTOR(graph->os)[i] = ec; VECTOR(graph->is)[i] = ec; } graph->n += nv; if (graph->attr) { IGRAPH_CHECK(igraph_i_attribute_add_vertices(graph, nv, attr)); } return 0; } /** * \ingroup interface * \function igraph_delete_edges * \brief Removes edges from a graph. * * * The edges to remove are given as an edge selector. * * * This function cannot remove vertices, they will be kept, even if * they lose all their edges. * * * This function invalidates all iterators. * \param graph The graph to work on. * \param edges The edges to remove. * \return Error code. * * Time complexity: O(|V|+|E|) where * |V| * and |E| are the number of vertices * and edges in the \em original graph, respectively. * * \example examples/simple/igraph_delete_edges.c */ int igraph_delete_edges(igraph_t *graph, igraph_es_t edges) { long int no_of_edges = igraph_ecount(graph); long int no_of_nodes = igraph_vcount(graph); long int edges_to_remove = 0; long int remaining_edges; igraph_eit_t eit; igraph_vector_t newfrom, newto, newoi; int *mark; long int i, j; mark = IGRAPH_CALLOC(no_of_edges, int); if (mark == 0) { IGRAPH_ERROR("Cannot delete edges", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, mark); IGRAPH_CHECK(igraph_eit_create(graph, edges, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); for (IGRAPH_EIT_RESET(eit); !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { long int e = IGRAPH_EIT_GET(eit); if (mark[e] == 0) { edges_to_remove++; mark[e]++; } } remaining_edges = no_of_edges - edges_to_remove; /* We don't need the iterator any more */ igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(1); IGRAPH_VECTOR_INIT_FINALLY(&newfrom, remaining_edges); IGRAPH_VECTOR_INIT_FINALLY(&newto, remaining_edges); /* Actually remove the edges, move from pos i to pos j in newfrom/newto */ for (i = 0, j = 0; j < remaining_edges; i++) { if (mark[i] == 0) { VECTOR(newfrom)[j] = VECTOR(graph->from)[i]; VECTOR(newto)[j] = VECTOR(graph->to)[i]; j++; } } /* Create index, this might require additional memory */ IGRAPH_VECTOR_INIT_FINALLY(&newoi, remaining_edges); IGRAPH_CHECK(igraph_vector_order(&newfrom, &newto, &newoi, no_of_nodes)); IGRAPH_CHECK(igraph_vector_order(&newto, &newfrom, &graph->ii, no_of_nodes)); /* Edge attributes, we need an index that gives the ids of the original edges for every new edge. */ if (graph->attr) { igraph_vector_t idx; IGRAPH_VECTOR_INIT_FINALLY(&idx, remaining_edges); for (i = 0, j = 0; i < no_of_edges; i++) { if (mark[i] == 0) { VECTOR(idx)[j++] = i; } } IGRAPH_CHECK(igraph_i_attribute_permute_edges(graph, graph, &idx)); igraph_vector_destroy(&idx); IGRAPH_FINALLY_CLEAN(1); } /* Ok, we've all memory needed, free the old structure */ igraph_vector_destroy(&graph->from); igraph_vector_destroy(&graph->to); igraph_vector_destroy(&graph->oi); graph->from = newfrom; graph->to = newto; graph->oi = newoi; IGRAPH_FINALLY_CLEAN(3); IGRAPH_FREE(mark); IGRAPH_FINALLY_CLEAN(1); /* Create start vectors, no memory is needed for this */ igraph_i_create_start(&graph->os, &graph->from, &graph->oi, (igraph_integer_t) no_of_nodes); igraph_i_create_start(&graph->is, &graph->to, &graph->ii, (igraph_integer_t) no_of_nodes); /* Nothing to deallocate... */ return 0; } /** * \ingroup interface * \function igraph_delete_vertices * \brief Removes vertices (with all their edges) from the graph. * * * This function changes the ids of the vertices (except in some very * special cases, but these should not be relied on anyway). * * * This function invalidates all iterators. * * \param graph The graph to work on. * \param vertices The ids of the vertices to remove in a * vector. The vector may contain the same id more * than once. * \return Error code: * \c IGRAPH_EINVVID: invalid vertex id. * * Time complexity: O(|V|+|E|), * |V| and * |E| are the number of vertices and * edges in the original graph. * * \example examples/simple/igraph_delete_vertices.c */ int igraph_delete_vertices(igraph_t *graph, const igraph_vs_t vertices) { return igraph_delete_vertices_idx(graph, vertices, /* idx= */ 0, /* invidx= */ 0); } int igraph_delete_vertices_idx(igraph_t *graph, const igraph_vs_t vertices, igraph_vector_t *idx, igraph_vector_t *invidx) { long int no_of_edges = igraph_ecount(graph); long int no_of_nodes = igraph_vcount(graph); igraph_vector_t edge_recoding, vertex_recoding; igraph_vector_t *my_vertex_recoding = &vertex_recoding; igraph_vit_t vit; igraph_t newgraph; long int i, j; long int remaining_vertices, remaining_edges; if (idx) { my_vertex_recoding = idx; IGRAPH_CHECK(igraph_vector_resize(idx, no_of_nodes)); igraph_vector_null(idx); } else { IGRAPH_VECTOR_INIT_FINALLY(&vertex_recoding, no_of_nodes); } IGRAPH_VECTOR_INIT_FINALLY(&edge_recoding, no_of_edges); IGRAPH_CHECK(igraph_vit_create(graph, vertices, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); /* mark the vertices to delete */ for (; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit) ) { long int vertex = IGRAPH_VIT_GET(vit); if (vertex < 0 || vertex >= no_of_nodes) { IGRAPH_ERROR("Cannot delete vertices", IGRAPH_EINVVID); } VECTOR(*my_vertex_recoding)[vertex] = 1; } /* create vertex recoding vector */ for (remaining_vertices = 0, i = 0; i < no_of_nodes; i++) { if (VECTOR(*my_vertex_recoding)[i] == 0) { VECTOR(*my_vertex_recoding)[i] = remaining_vertices + 1; remaining_vertices++; } else { VECTOR(*my_vertex_recoding)[i] = 0; } } /* create edge recoding vector */ for (remaining_edges = 0, i = 0; i < no_of_edges; i++) { long int from = (long int) VECTOR(graph->from)[i]; long int to = (long int) VECTOR(graph->to)[i]; if (VECTOR(*my_vertex_recoding)[from] != 0 && VECTOR(*my_vertex_recoding)[to ] != 0) { VECTOR(edge_recoding)[i] = remaining_edges + 1; remaining_edges++; } } /* start creating the graph */ newgraph.n = (igraph_integer_t) remaining_vertices; newgraph.directed = graph->directed; /* allocate vectors */ IGRAPH_VECTOR_INIT_FINALLY(&newgraph.from, remaining_edges); IGRAPH_VECTOR_INIT_FINALLY(&newgraph.to, remaining_edges); IGRAPH_VECTOR_INIT_FINALLY(&newgraph.oi, remaining_edges); IGRAPH_VECTOR_INIT_FINALLY(&newgraph.ii, remaining_edges); IGRAPH_VECTOR_INIT_FINALLY(&newgraph.os, remaining_vertices + 1); IGRAPH_VECTOR_INIT_FINALLY(&newgraph.is, remaining_vertices + 1); /* Add the edges */ for (i = 0, j = 0; j < remaining_edges; i++) { if (VECTOR(edge_recoding)[i] > 0) { long int from = (long int) VECTOR(graph->from)[i]; long int to = (long int) VECTOR(graph->to )[i]; VECTOR(newgraph.from)[j] = VECTOR(*my_vertex_recoding)[from] - 1; VECTOR(newgraph.to )[j] = VECTOR(*my_vertex_recoding)[to] - 1; j++; } } /* update oi & ii */ IGRAPH_CHECK(igraph_vector_order(&newgraph.from, &newgraph.to, &newgraph.oi, remaining_vertices)); IGRAPH_CHECK(igraph_vector_order(&newgraph.to, &newgraph.from, &newgraph.ii, remaining_vertices)); IGRAPH_CHECK(igraph_i_create_start(&newgraph.os, &newgraph.from, &newgraph.oi, (igraph_integer_t) remaining_vertices)); IGRAPH_CHECK(igraph_i_create_start(&newgraph.is, &newgraph.to, &newgraph.ii, (igraph_integer_t) remaining_vertices)); /* attributes */ IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, /*graph=*/ 1, /*vertex=*/0, /*edge=*/0); IGRAPH_FINALLY_CLEAN(6); IGRAPH_FINALLY(igraph_destroy, &newgraph); if (newgraph.attr) { igraph_vector_t iidx; IGRAPH_VECTOR_INIT_FINALLY(&iidx, remaining_vertices); for (i = 0; i < no_of_nodes; i++) { long int jj = (long int) VECTOR(*my_vertex_recoding)[i]; if (jj != 0) { VECTOR(iidx)[ jj - 1 ] = i; } } IGRAPH_CHECK(igraph_i_attribute_permute_vertices(graph, &newgraph, &iidx)); IGRAPH_CHECK(igraph_vector_resize(&iidx, remaining_edges)); for (i = 0; i < no_of_edges; i++) { long int jj = (long int) VECTOR(edge_recoding)[i]; if (jj != 0) { VECTOR(iidx)[ jj - 1 ] = i; } } IGRAPH_CHECK(igraph_i_attribute_permute_edges(graph, &newgraph, &iidx)); igraph_vector_destroy(&iidx); IGRAPH_FINALLY_CLEAN(1); } igraph_vit_destroy(&vit); igraph_vector_destroy(&edge_recoding); igraph_destroy(graph); *graph = newgraph; IGRAPH_FINALLY_CLEAN(3); /* TODO: this is duplicate */ if (invidx) { IGRAPH_CHECK(igraph_vector_resize(invidx, remaining_vertices)); for (i = 0; i < no_of_nodes; i++) { long int newid = (long int) VECTOR(*my_vertex_recoding)[i]; if (newid != 0) { VECTOR(*invidx)[newid - 1] = i; } } } if (!idx) { igraph_vector_destroy(my_vertex_recoding); IGRAPH_FINALLY_CLEAN(1); } return 0; } /** * \ingroup interface * \function igraph_vcount * \brief The number of vertices in a graph. * * \param graph The graph. * \return Number of vertices. * * Time complexity: O(1) */ igraph_integer_t igraph_vcount(const igraph_t *graph) { return graph->n; } /** * \ingroup interface * \function igraph_ecount * \brief The number of edges in a graph. * * \param graph The graph. * \return Number of edges. * * Time complexity: O(1) */ igraph_integer_t igraph_ecount(const igraph_t *graph) { return (igraph_integer_t) igraph_vector_size(&graph->from); } /** * \ingroup interface * \function igraph_neighbors * \brief Adjacent vertices to a vertex. * * \param graph The graph to work on. * \param neis This vector will contain the result. The vector should * be initialized beforehand and will be resized. Starting from igraph * version 0.4 this vector is always sorted, the vertex ids are * in increasing order. * \param pnode The id of the node for which the adjacent vertices are * to be searched. * \param mode Defines the way adjacent vertices are searched in * directed graphs. It can have the following values: * \c IGRAPH_OUT, vertices reachable by an * edge from the specified vertex are searched; * \c IGRAPH_IN, vertices from which the * specified vertex is reachable are searched; * \c IGRAPH_ALL, both kinds of vertices are * searched. * This parameter is ignored for undirected graphs. * \return Error code: * \c IGRAPH_EINVVID: invalid vertex id. * \c IGRAPH_EINVMODE: invalid mode argument. * \c IGRAPH_ENOMEM: not enough memory. * * Time complexity: O(d), * d is the number * of adjacent vertices to the queried vertex. * * \example examples/simple/igraph_neighbors.c */ int igraph_neighbors(const igraph_t *graph, igraph_vector_t *neis, igraph_integer_t pnode, igraph_neimode_t mode) { if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) { return igraph_i_neighbors(graph, neis, pnode, mode, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE); } else { return igraph_i_neighbors(graph, neis, pnode, mode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE); } } int igraph_i_neighbors(const igraph_t *graph, igraph_vector_t *neis, igraph_integer_t pnode, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple) { #define DEDUPLICATE_IF_NEEDED(vertex, n) \ if (should_filter_duplicates) { \ if ((loops == IGRAPH_NO_LOOPS && vertex == pnode) || \ (loops == IGRAPH_LOOPS_ONCE && vertex == pnode && last_added == pnode) || \ (multiple == IGRAPH_NO_MULTIPLE && vertex == last_added)) { \ length -= n; \ continue; \ } else { \ last_added = vertex; \ } \ } long int length = 0, idx = 0; long int i, j; long int node = pnode; igraph_real_t last_added = -1; igraph_bool_t should_filter_duplicates; if (node < 0 || node > igraph_vcount(graph) - 1) { IGRAPH_ERROR("Given vertex is not in the graph.", IGRAPH_EINVVID); } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Mode should be either IGRAPH_OUT, IGRAPH_IN or IGRAPH_ALL.", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } if (mode != IGRAPH_ALL && loops == IGRAPH_LOOPS_TWICE) { IGRAPH_ERROR("For a directed graph (with directions not ignored), " "IGRAPH_LOOPS_TWICE does not make sense.\n", IGRAPH_EINVAL); } /* Calculate needed space first & allocate it */ /* Note that 'mode' is treated as a bit field here; it's okay because * IGRAPH_ALL = IGRAPH_IN | IGRAPH_OUT, bit-wise */ if (mode & IGRAPH_OUT) { length += (VECTOR(graph->os)[node + 1] - VECTOR(graph->os)[node]); } if (mode & IGRAPH_IN) { length += (VECTOR(graph->is)[node + 1] - VECTOR(graph->is)[node]); } IGRAPH_CHECK(igraph_vector_resize(neis, length)); /* The loops below produce an ordering what is consistent with the * ordering returned by igraph_neighbors(), and this should be preserved. * We are dealing with two sorted lists; one for the successors and one * for the predecessors. If we have requested only one of them, we have * an easy job. If we have requested both, we need to merge the two lists * to ensure that the output is sorted by the vertex IDs of the "other" * endpoint of the affected edges. We don't need to merge if the graph * is undirected, because in that case the data structure guarantees that * the "out-edges" contain only (u, v) pairs where u <= v and the * "in-edges" contains the rest, so the result is sorted even without * merging. */ if (!igraph_is_directed(graph) || mode != IGRAPH_ALL) { /* graph is undirected or we did not ask for both directions in a * directed graph; this is the easy case */ should_filter_duplicates = !(multiple == IGRAPH_MULTIPLE && ((!igraph_is_directed(graph) && loops == IGRAPH_LOOPS_TWICE) || (igraph_is_directed(graph) && loops != IGRAPH_NO_LOOPS))); if (mode & IGRAPH_OUT) { j = (long int) VECTOR(graph->os)[node + 1]; for (i = (long int) VECTOR(graph->os)[node]; i < j; i++) { igraph_real_t to = VECTOR(graph->to)[ (long int)VECTOR(graph->oi)[i] ]; DEDUPLICATE_IF_NEEDED(to, 1); VECTOR(*neis)[idx++] = to; } } if (mode & IGRAPH_IN) { j = (long int) VECTOR(graph->is)[node + 1]; for (i = (long int) VECTOR(graph->is)[node]; i < j; i++) { igraph_real_t from = VECTOR(graph->from)[ (long int)VECTOR(graph->ii)[i] ]; DEDUPLICATE_IF_NEEDED(from, 1); VECTOR(*neis)[idx++] = from; } } } else { /* Both in- and out- neighbors in a directed graph, we need to merge the two 'vectors' so the result is correctly ordered. */ long int j1 = (long int) VECTOR(graph->os)[node + 1]; long int j2 = (long int) VECTOR(graph->is)[node + 1]; long int i1 = (long int) VECTOR(graph->os)[node]; long int i2 = (long int) VECTOR(graph->is)[node]; long int eid1, eid2; long int n1, n2; should_filter_duplicates = !(multiple == IGRAPH_MULTIPLE && loops == IGRAPH_LOOPS_TWICE); while (i1 < j1 && i2 < j2) { eid1 = (long int) VECTOR(graph->oi)[i1]; eid2 = (long int) VECTOR(graph->ii)[i2]; n1 = (long int) VECTOR(graph->to)[eid1]; n2 = (long int) VECTOR(graph->from)[eid2]; if (n1 < n2) { i1++; DEDUPLICATE_IF_NEEDED(n1, 1); VECTOR(*neis)[idx++] = n1; } else if (n1 > n2) { i2++; DEDUPLICATE_IF_NEEDED(n2, 1); VECTOR(*neis)[idx++] = n2; } else { i1++; i2++; DEDUPLICATE_IF_NEEDED(n1, 2); VECTOR(*neis)[idx++] = n1; if (should_filter_duplicates && ((loops == IGRAPH_LOOPS_ONCE && n1 == pnode && last_added == pnode) || (multiple == IGRAPH_NO_MULTIPLE))) { length--; continue; } VECTOR(*neis)[idx++] = n2; } } while (i1 < j1) { eid1 = (long int) VECTOR(graph->oi)[i1++]; igraph_real_t to = (long int) VECTOR(graph->to)[eid1]; DEDUPLICATE_IF_NEEDED(to, 1); VECTOR(*neis)[idx++] = to; } while (i2 < j2) { eid2 = (long int) VECTOR(graph->ii)[i2++]; igraph_real_t from = (long int) VECTOR(graph->from)[eid2]; DEDUPLICATE_IF_NEEDED(from, 1); VECTOR(*neis)[idx++] = from; } } IGRAPH_CHECK(igraph_vector_resize(neis, length)); return IGRAPH_SUCCESS; #undef DEDUPLICATE_IF_NEEDED } /** * \ingroup internal * */ static int igraph_i_create_start( igraph_vector_t *res, igraph_vector_t *el, igraph_vector_t *iindex, igraph_integer_t nodes) { # define EDGE(i) (VECTOR(*el)[ (long int) VECTOR(*iindex)[(i)] ]) long int no_of_nodes; long int no_of_edges; long int i, j, idx; no_of_nodes = nodes; no_of_edges = igraph_vector_size(el); /* result */ IGRAPH_CHECK(igraph_vector_resize(res, nodes + 1)); /* create the index */ if (igraph_vector_size(el) == 0) { /* empty graph */ igraph_vector_null(res); } else { idx = -1; for (i = 0; i <= EDGE(0); i++) { idx++; VECTOR(*res)[idx] = 0; } for (i = 1; i < no_of_edges; i++) { long int n = (long int) (EDGE(i) - EDGE((long int)VECTOR(*res)[idx])); for (j = 0; j < n; j++) { idx++; VECTOR(*res)[idx] = i; } } j = (long int) EDGE((long int)VECTOR(*res)[idx]); for (i = 0; i < no_of_nodes - j; i++) { idx++; VECTOR(*res)[idx] = no_of_edges; } } /* clean */ # undef EDGE return 0; } /** * \ingroup interface * \function igraph_is_directed * \brief Is this a directed graph? * * \param graph The graph. * \return Logical value, TRUE if the graph is directed, * FALSE otherwise. * * Time complexity: O(1) * * \example examples/simple/igraph_is_directed.c */ igraph_bool_t igraph_is_directed(const igraph_t *graph) { return graph->directed; } /** * \ingroup interface * \function igraph_degree * \brief The degree of some vertices in a graph. * * * This function calculates the in-, out- or total degree of the * specified vertices. * \param graph The graph. * \param res Vector, this will contain the result. It should be * initialized and will be resized to be the appropriate size. * \param vids Vector, giving the vertex ids of which the degree will * be calculated. * \param mode Defines the type of the degree. Valid modes are: * \c IGRAPH_OUT, out-degree; * \c IGRAPH_IN, in-degree; * \c IGRAPH_ALL, total degree (sum of the * in- and out-degree). * This parameter is ignored for undirected graphs. * \param loops Boolean, gives whether the self-loops should be * counted. * \return Error code: * \c IGRAPH_EINVVID: invalid vertex id. * \c IGRAPH_EINVMODE: invalid mode argument. * * Time complexity: O(v) if * loops is * TRUE, and * O(v*d) * otherwise. v is the number of * vertices for which the degree will be calculated, and * d is their (average) degree. * * \sa \ref igraph_strength() for the version that takes into account * edge weights. * * \example examples/simple/igraph_degree.c */ int igraph_degree(const igraph_t *graph, igraph_vector_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops) { long int nodes_to_calc; long int i, j; igraph_vit_t vit; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("degree calculation failed", IGRAPH_EINVMODE); } nodes_to_calc = IGRAPH_VIT_SIZE(vit); if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } IGRAPH_CHECK(igraph_vector_resize(res, nodes_to_calc)); igraph_vector_null(res); if (loops) { if (mode & IGRAPH_OUT) { for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int vid = IGRAPH_VIT_GET(vit); VECTOR(*res)[i] += (VECTOR(graph->os)[vid + 1] - VECTOR(graph->os)[vid]); } } if (mode & IGRAPH_IN) { for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int vid = IGRAPH_VIT_GET(vit); VECTOR(*res)[i] += (VECTOR(graph->is)[vid + 1] - VECTOR(graph->is)[vid]); } } } else { /* no loops */ if (mode & IGRAPH_OUT) { for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int vid = IGRAPH_VIT_GET(vit); VECTOR(*res)[i] += (VECTOR(graph->os)[vid + 1] - VECTOR(graph->os)[vid]); for (j = (long int) VECTOR(graph->os)[vid]; j < VECTOR(graph->os)[vid + 1]; j++) { if (VECTOR(graph->to)[ (long int)VECTOR(graph->oi)[j] ] == vid) { VECTOR(*res)[i] -= 1; } } } } if (mode & IGRAPH_IN) { for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { long int vid = IGRAPH_VIT_GET(vit); VECTOR(*res)[i] += (VECTOR(graph->is)[vid + 1] - VECTOR(graph->is)[vid]); for (j = (long int) VECTOR(graph->is)[vid]; j < VECTOR(graph->is)[vid + 1]; j++) { if (VECTOR(graph->from)[ (long int)VECTOR(graph->ii)[j] ] == vid) { VECTOR(*res)[i] -= 1; } } } } } /* loops */ igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_edge * \brief Gives the head and tail vertices of an edge. * * \param graph The graph object. * \param eid The edge id. * \param from Pointer to an \type igraph_integer_t. The tail (head) of * the edge will be placed here for undirected (directed) graphs. * \param to Pointer to an \type igraph_integer_t. The head (tail) of the * edge will be placed here for undirected (directed) graphs. * \return Error code. The current implementation always returns with * success. * \sa \ref igraph_get_eid() for the opposite operation; * \ref igraph_edges() to get the endpoints of several edges; * \ref IGRAPH_TO(), \ref IGRAPH_FROM() and \ref IGRAPH_OTHER() for * a faster but non-error-checked version. * * Added in version 0.2. * * Time complexity: O(1). */ int igraph_edge(const igraph_t *graph, igraph_integer_t eid, igraph_integer_t *from, igraph_integer_t *to) { if (igraph_is_directed(graph)) { *from = IGRAPH_FROM(graph, eid); *to = IGRAPH_TO(graph, eid); } else { *from = IGRAPH_TO(graph, eid); *to = IGRAPH_FROM(graph, eid); } return IGRAPH_SUCCESS; } /** * \function igraph_edges * \brief Gives the head and tail vertices of a series of edges. * * \param graph The graph object. * \param eids Edge selector, the series of edges. * \param edges Pointer to an initialized vector. The start and endpoints of * each edge will be placed here. * \return Error code. * \sa \ref igraph_get_edgelist() to get the endpoints of all edges; * \ref igraph_get_eids() and \ref igraph_get_eids_multi() * for the opposite operation; * \ref igraph_edge() for getting the endpoints of a single edge; * \ref IGRAPH_TO(), \ref IGRAPH_FROM() and \ref IGRAPH_OTHER() for * a faster but non-error-checked method. * * Time complexity: O(k) where k is the number of edges in the selector. */ int igraph_edges(const igraph_t *graph, igraph_es_t eids, igraph_vector_t *edges) { igraph_eit_t eit; long int n, ptr = 0; IGRAPH_CHECK(igraph_eit_create(graph, eids, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); n = IGRAPH_EIT_SIZE(eit); IGRAPH_CHECK(igraph_vector_resize(edges, n * 2)); if (igraph_is_directed(graph)) { for (; !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { long int e = IGRAPH_EIT_GET(eit); VECTOR(*edges)[ptr++] = IGRAPH_FROM(graph, e); VECTOR(*edges)[ptr++] = IGRAPH_TO(graph, e); } } else { for (; !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { long int e = IGRAPH_EIT_GET(eit); VECTOR(*edges)[ptr++] = IGRAPH_TO(graph, e); VECTOR(*edges)[ptr++] = IGRAPH_FROM(graph, e); } } igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } /* This is an unsafe macro. Only supply variable names, i.e. no expressions as parameters, otherwise nasty things can happen */ #define BINSEARCH(start,end,value,iindex,edgelist,N,pos) \ do { \ while ((start) < (end)) { \ long int mid=(start)+((end)-(start))/2; \ long int e=(long int) VECTOR((iindex))[mid]; \ if (VECTOR((edgelist))[e] < (value)) { \ (start)=mid+1; \ } else { \ (end)=mid; \ } \ } \ if ((start)<(N)) { \ long int e=(long int) VECTOR((iindex))[(start)]; \ if (VECTOR((edgelist))[e] == (value)) { \ *(pos)=(igraph_integer_t) e; \ } \ } } while(0) #define FIND_DIRECTED_EDGE(graph,xfrom,xto,eid) \ do { \ long int start=(long int) VECTOR(graph->os)[xfrom]; \ long int end=(long int) VECTOR(graph->os)[xfrom+1]; \ long int N=end; \ long int start2=(long int) VECTOR(graph->is)[xto]; \ long int end2=(long int) VECTOR(graph->is)[xto+1]; \ long int N2=end2; \ if (end-startoi,graph->to,N,eid); \ } else { \ BINSEARCH(start2,end2,xfrom,graph->ii,graph->from,N2,eid); \ } \ } while (0) #define FIND_UNDIRECTED_EDGE(graph,from,to,eid) \ do { \ long int xfrom1= from > to ? from : to; \ long int xto1= from > to ? to : from; \ FIND_DIRECTED_EDGE(graph,xfrom1,xto1,eid); \ } while (0) /** * \function igraph_get_eid * \brief Get the edge id from the end points of an edge. * * For undirected graphs \c pfrom and \c pto are exchangeable. * * \param graph The graph object. * \param eid Pointer to an integer, the edge id will be stored here. * \param pfrom The starting point of the edge. * \param pto The end point of the edge. * \param directed Logical constant, whether to search for directed * edges in a directed graph. Ignored for undirected graphs. * \param error Logical scalar, whether to report an error if the edge * was not found. If it is false, then -1 will be assigned to \p eid. * \return Error code. * \sa \ref igraph_edge() for the opposite operation. * * Time complexity: O(log (d)), where d is smaller of the out-degree * of \c pfrom and in-degree of \c pto if \p directed is true. If \p directed * is false, then it is O(log(d)+log(d2)), where d is the same as before and * d2 is the minimum of the out-degree of \c pto and the in-degree of \c pfrom. * * \example examples/simple/igraph_get_eid.c * * Added in version 0.2. */ int igraph_get_eid(const igraph_t *graph, igraph_integer_t *eid, igraph_integer_t pfrom, igraph_integer_t pto, igraph_bool_t directed, igraph_bool_t error) { long int from = pfrom, to = pto; long int nov = igraph_vcount(graph); if (from < 0 || to < 0 || from > nov - 1 || to > nov - 1) { IGRAPH_ERROR("cannot get edge id", IGRAPH_EINVVID); } *eid = -1; if (igraph_is_directed(graph)) { /* Directed graph */ FIND_DIRECTED_EDGE(graph, from, to, eid); if (!directed && *eid < 0) { FIND_DIRECTED_EDGE(graph, to, from, eid); } } else { /* Undirected graph, they only have one mode */ FIND_UNDIRECTED_EDGE(graph, from, to, eid); } if (*eid < 0) { if (error) { IGRAPH_ERROR("Cannot get edge id, no such edge", IGRAPH_EINVAL); } } return IGRAPH_SUCCESS; } int igraph_get_eids_pairs(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *pairs, igraph_bool_t directed, igraph_bool_t error); int igraph_get_eids_path(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t error); int igraph_get_eids_pairs(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *pairs, igraph_bool_t directed, igraph_bool_t error) { long int n = igraph_vector_size(pairs); long int no_of_nodes = igraph_vcount(graph); long int i; igraph_integer_t eid = -1; if (n % 2 != 0) { IGRAPH_ERROR("Cannot get edge ids, invalid length of edge ids", IGRAPH_EINVAL); } if (!igraph_vector_isininterval(pairs, 0, no_of_nodes - 1)) { IGRAPH_ERROR("Cannot get edge ids, invalid vertex id", IGRAPH_EINVVID); } IGRAPH_CHECK(igraph_vector_resize(eids, n / 2)); if (igraph_is_directed(graph)) { for (i = 0; i < n / 2; i++) { long int from = (long int) VECTOR(*pairs)[2 * i]; long int to = (long int) VECTOR(*pairs)[2 * i + 1]; eid = -1; FIND_DIRECTED_EDGE(graph, from, to, &eid); if (!directed && eid < 0) { FIND_DIRECTED_EDGE(graph, to, from, &eid); } VECTOR(*eids)[i] = eid; if (eid < 0 && error) { IGRAPH_ERROR("Cannot get edge id, no such edge", IGRAPH_EINVAL); } } } else { for (i = 0; i < n / 2; i++) { long int from = (long int) VECTOR(*pairs)[2 * i]; long int to = (long int) VECTOR(*pairs)[2 * i + 1]; eid = -1; FIND_UNDIRECTED_EDGE(graph, from, to, &eid); VECTOR(*eids)[i] = eid; if (eid < 0 && error) { IGRAPH_ERROR("Cannot get edge id, no such edge", IGRAPH_EINVAL); } } } return 0; } int igraph_get_eids_path(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t error) { long int n = igraph_vector_size(path); long int no_of_nodes = igraph_vcount(graph); long int i; igraph_integer_t eid = -1; if (!igraph_vector_isininterval(path, 0, no_of_nodes - 1)) { IGRAPH_ERROR("Cannot get edge ids, invalid vertex id", IGRAPH_EINVVID); } IGRAPH_CHECK(igraph_vector_resize(eids, n == 0 ? 0 : n - 1)); if (igraph_is_directed(graph)) { for (i = 0; i < n - 1; i++) { long int from = (long int) VECTOR(*path)[i]; long int to = (long int) VECTOR(*path)[i + 1]; eid = -1; FIND_DIRECTED_EDGE(graph, from, to, &eid); if (!directed && eid < 0) { FIND_DIRECTED_EDGE(graph, to, from, &eid); } VECTOR(*eids)[i] = eid; if (eid < 0 && error) { IGRAPH_ERROR("Cannot get edge id, no such edge", IGRAPH_EINVAL); } } } else { for (i = 0; i < n - 1; i++) { long int from = (long int) VECTOR(*path)[i]; long int to = (long int) VECTOR(*path)[i + 1]; eid = -1; FIND_UNDIRECTED_EDGE(graph, from, to, &eid); VECTOR(*eids)[i] = eid; if (eid < 0 && error) { IGRAPH_ERROR("Cannot get edge id, no such edge", IGRAPH_EINVAL); } } } return 0; } /** * \function igraph_get_eids * Return edge ids based on the adjacent vertices. * * This function operates in two modes. If the \c pairs argument is * not a null pointer, but the \c path argument is, then it searches * for the edge ids of all pairs of vertices given in \c pairs. The * pairs of vertex ids are taken consecutively from the vector, * i.e. VECTOR(pairs)[0] and * VECTOR(pairs)[1] give the first * pair, VECTOR(pairs)[2] and * VECTOR(pairs)[3] the second pair, etc. * * * If the \c pairs argument is a null pointer, and \c path is not a * null pointer, then the \c path is interpreted as a path given by * vertex ids and the edges along the path are returned. * * * If neither \c pairs nor \c path are null pointers, then both are * considered (first \c pairs and then \c path), and the results are * concatenated. * * * If the \c error argument is true, then it is an error to give pairs * of vertices that are not connected. Otherwise -1 is * reported for not connected vertices. * * * If there are multiple edges in the graph, then these are ignored; * i.e. for a given pair of vertex ids, always the same edge id is * returned, even if the pair is given multiple time in \c pairs or in * \c path. See \ref igraph_get_eids_multi() for a similar function * that works differently in case of multiple edges. * * \param graph The input graph. * \param eids Pointer to an initialized vector, the result is stored * here. It will be resized as needed. * \param pairs Vector giving pairs of vertices, or a null pointer. * \param path Vector giving vertex ids along a path, or a null * pointer. * \param directed Logical scalar, whether to consider edge directions * in directed graphs. This is ignored for undirected graphs. * \param error Logical scalar, whether it is an error to supply * non-connected vertices. If false, then -1 is * returned for non-connected pairs. * \return Error code. * * Time complexity: O(n log(d)), where n is the number of queried * edges and d is the average degree of the vertices. * * \sa \ref igraph_get_eid() for a single edge, \ref * igraph_get_eids_multi() for a version that handles multiple edges * better (at a cost). * * \example examples/simple/igraph_get_eids.c */ int igraph_get_eids(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *pairs, const igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t error) { if (!pairs && !path) { igraph_vector_clear(eids); return 0; } else if (pairs && !path) { return igraph_get_eids_pairs(graph, eids, pairs, directed, error); } else if (!pairs && path) { return igraph_get_eids_path(graph, eids, path, directed, error); } else { /* both */ igraph_vector_t tmp; IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_CHECK(igraph_get_eids_pairs(graph, eids, pairs, directed, error)); IGRAPH_CHECK(igraph_get_eids_path(graph, &tmp, path, directed, error)); IGRAPH_CHECK(igraph_vector_append(eids, &tmp)); igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(1); return 0; } } #undef BINSEARCH #undef FIND_DIRECTED_EDGE #undef FIND_UNDIRECTED_EDGE #define BINSEARCH(start,end,value,iindex,edgelist,N,pos,seen) \ do { \ while ((start) < (end)) { \ long int mid=(start)+((end)-(start))/2; \ long int e=(long int) VECTOR((iindex))[mid]; \ if (VECTOR((edgelist))[e] < (value)) { \ (start)=mid+1; \ } else { \ (end)=mid; \ } \ } \ if ((start)<(N)) { \ long int e=(long int) VECTOR((iindex))[(start)]; \ while ((start)<(N) && seen[e] && VECTOR(edgelist)[e] == (value)) { \ (start)++; \ e=(long int) VECTOR(iindex)[(start)]; \ } \ if ((start)<(N) && !(seen[e]) && VECTOR(edgelist)[e] == (value)) { \ *(pos)=(igraph_integer_t) e; \ } \ } } while(0) #define FIND_DIRECTED_EDGE(graph,xfrom,xto,eid,seen) \ do { \ long int start=(long int) VECTOR(graph->os)[xfrom]; \ long int end=(long int) VECTOR(graph->os)[xfrom+1]; \ long int N=end; \ long int start2=(long int) VECTOR(graph->is)[xto]; \ long int end2=(long int) VECTOR(graph->is)[xto+1]; \ long int N2=end2; \ if (end-startoi,graph->to,N,eid,seen); \ } else { \ BINSEARCH(start2,end2,xfrom,graph->ii,graph->from,N2,eid,seen); \ } \ } while (0) #define FIND_UNDIRECTED_EDGE(graph,from,to,eid,seen) \ do { \ long int xfrom1= from > to ? from : to; \ long int xto1= from > to ? to : from; \ FIND_DIRECTED_EDGE(graph,xfrom1,xto1,eid,seen); \ } while (0) int igraph_get_eids_multipairs(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *pairs, igraph_bool_t directed, igraph_bool_t error); int igraph_get_eids_multipath(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t error); int igraph_get_eids_multipairs(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *pairs, igraph_bool_t directed, igraph_bool_t error) { long int n = igraph_vector_size(pairs); long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_bool_t *seen; long int i; igraph_integer_t eid = -1; if (n % 2 != 0) { IGRAPH_ERROR("Cannot get edge ids, invalid length of edge ids", IGRAPH_EINVAL); } if (!igraph_vector_isininterval(pairs, 0, no_of_nodes - 1)) { IGRAPH_ERROR("Cannot get edge ids, invalid vertex id", IGRAPH_EINVVID); } seen = IGRAPH_CALLOC(no_of_edges, igraph_bool_t); if (seen == 0) { IGRAPH_ERROR("Cannot get edge ids", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, seen); IGRAPH_CHECK(igraph_vector_resize(eids, n / 2)); if (igraph_is_directed(graph)) { for (i = 0; i < n / 2; i++) { long int from = (long int) VECTOR(*pairs)[2 * i]; long int to = (long int) VECTOR(*pairs)[2 * i + 1]; eid = -1; FIND_DIRECTED_EDGE(graph, from, to, &eid, seen); if (!directed && eid < 0) { FIND_DIRECTED_EDGE(graph, to, from, &eid, seen); } VECTOR(*eids)[i] = eid; if (eid >= 0) { seen[(long int)(eid)] = 1; } else if (error) { IGRAPH_ERROR("Cannot get edge id, no such edge", IGRAPH_EINVAL); } } } else { for (i = 0; i < n / 2; i++) { long int from = (long int) VECTOR(*pairs)[2 * i]; long int to = (long int) VECTOR(*pairs)[2 * i + 1]; eid = -1; FIND_UNDIRECTED_EDGE(graph, from, to, &eid, seen); VECTOR(*eids)[i] = eid; if (eid >= 0) { seen[(long int)(eid)] = 1; } else if (error) { IGRAPH_ERROR("Cannot get edge id, no such edge", IGRAPH_EINVAL); } } } IGRAPH_FREE(seen); IGRAPH_FINALLY_CLEAN(1); return 0; } int igraph_get_eids_multipath(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t error) { long int n = igraph_vector_size(path); long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); igraph_bool_t *seen; long int i; igraph_integer_t eid = -1; if (!igraph_vector_isininterval(path, 0, no_of_nodes - 1)) { IGRAPH_ERROR("Cannot get edge ids, invalid vertex id", IGRAPH_EINVVID); } seen = IGRAPH_CALLOC(no_of_edges, igraph_bool_t); if (!seen) { IGRAPH_ERROR("Cannot get edge ids", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, seen); IGRAPH_CHECK(igraph_vector_resize(eids, n == 0 ? 0 : n - 1)); if (igraph_is_directed(graph)) { for (i = 0; i < n - 1; i++) { long int from = (long int) VECTOR(*path)[i]; long int to = (long int) VECTOR(*path)[i + 1]; eid = -1; FIND_DIRECTED_EDGE(graph, from, to, &eid, seen); if (!directed && eid < 0) { FIND_DIRECTED_EDGE(graph, to, from, &eid, seen); } VECTOR(*eids)[i] = eid; if (eid >= 0) { seen[(long int)(eid)] = 1; } else if (error) { IGRAPH_ERROR("Cannot get edge id, no such edge", IGRAPH_EINVAL); } } } else { for (i = 0; i < n - 1; i++) { long int from = (long int) VECTOR(*path)[i]; long int to = (long int) VECTOR(*path)[i + 1]; eid = -1; FIND_UNDIRECTED_EDGE(graph, from, to, &eid, seen); VECTOR(*eids)[i] = eid; if (eid >= 0) { seen[(long int)(eid)] = 1; } else if (error) { IGRAPH_ERROR("Cannot get edge id, no such edge", IGRAPH_EINVAL); } } } IGRAPH_FREE(seen); IGRAPH_FINALLY_CLEAN(1); return 0; } #undef BINSEARCH #undef FIND_DIRECTED_EDGE #undef FIND_UNDIRECTED_EDGE /** * \function igraph_get_eids_multi * \brief Query edge ids based on their adjacent vertices, handle multiple edges. * * This function operates in two modes. If the \c pairs argument is * not a null pointer, but the \c path argument is, then it searches * for the edge ids of all pairs of vertices given in \c pairs. The * pairs of vertex ids are taken consecutively from the vector, * i.e. VECTOR(pairs)[0] and * VECTOR(pairs)[1] give the first pair, * VECTOR(pairs)[2] and VECTOR(pairs)[3] the * second pair, etc. * * * If the \c pairs argument is a null pointer, and \c path is not a * null pointer, then the \c path is interpreted as a path given by * vertex ids and the edges along the path are returned. * * * If the \c error argument is true, then it is an error to give pairs of * vertices that are not connected. Otherwise -1 is * returned for not connected vertex pairs. * * * An error is triggered if both \c pairs and \c path are non-null * pointers. * * * This function handles multiple edges properly, i.e. if the same * pair is given multiple times and they are indeed connected by * multiple edges, then each time a different edge id is reported. * * \param graph The input graph. * \param eids Pointer to an initialized vector, the result is stored * here. It will be resized as needed. * \param pairs Vector giving pairs of vertices, or a null pointer. * \param path Vector giving vertex ids along a path, or a null * pointer. * \param directed Logical scalar, whether to consider edge directions * in directed graphs. This is ignored for undirected graphs. * \param error Logical scalar, whether to report an error if * non-connected vertices are specified. If false, then -1 * is returned for non-connected vertex pairs. * \return Error code. * * Time complexity: O(|E|+n log(d)), where |E| is the number of edges * in the graph, n is the number of queried edges and d is the average * degree of the vertices. * * \sa \ref igraph_get_eid() for a single edge, \ref * igraph_get_eids() for a faster version that does not handle * multiple edges. */ int igraph_get_eids_multi(const igraph_t *graph, igraph_vector_t *eids, const igraph_vector_t *pairs, const igraph_vector_t *path, igraph_bool_t directed, igraph_bool_t error) { if (!pairs && !path) { igraph_vector_clear(eids); return 0; } else if (pairs && !path) { return igraph_get_eids_multipairs(graph, eids, pairs, directed, error); } else if (!pairs && path) { return igraph_get_eids_multipath(graph, eids, path, directed, error); } else { /* both */ IGRAPH_ERROR("Give `pairs' or `path' but not both", IGRAPH_EINVAL); } } /** * \function igraph_incident * \brief Gives the incident edges of a vertex. * * \param graph The graph object. * \param eids An initialized \type vector_t object. It will be resized * to hold the result. * \param pnode A vertex id. * \param mode Specifies what kind of edges to include for directed * graphs. \c IGRAPH_OUT means only outgoing edges, \c IGRAPH_IN only * incoming edges, \c IGRAPH_ALL both. This parameter is ignored for * undirected graphs. * \return Error code. \c IGRAPH_EINVVID: invalid \p pnode argument, * \c IGRAPH_EINVMODE: invalid \p mode argument. * * Added in version 0.2. * * Time complexity: O(d), the number of incident edges to \p pnode. */ int igraph_incident(const igraph_t *graph, igraph_vector_t *eids, igraph_integer_t pnode, igraph_neimode_t mode) { if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) { return igraph_i_incident(graph, eids, pnode, mode, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE); } else { return igraph_i_incident(graph, eids, pnode, mode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE); } } int igraph_i_incident(const igraph_t *graph, igraph_vector_t *eids, igraph_integer_t pnode, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple) { #define DEDUPLICATE_IF_NEEDED(vertex, n) \ if (should_filter_duplicates) { \ if ((loops == IGRAPH_NO_LOOPS && vertex == pnode) || \ (loops == IGRAPH_LOOPS_ONCE && vertex == pnode && last_added == pnode) || \ (multiple == IGRAPH_NO_MULTIPLE && vertex == last_added)) { \ length -= n; \ continue; \ } else { \ last_added = vertex; \ } \ } long int length = 0, idx = 0; long int i, j; long int node = pnode; igraph_real_t last_added = -1; igraph_bool_t should_filter_duplicates; if (node < 0 || node > igraph_vcount(graph) - 1) { IGRAPH_ERROR("Given vertex is not in the graph.", IGRAPH_EINVVID); } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Mode should be either IGRAPH_OUT, IGRAPH_IN or IGRAPH_ALL.", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } if (mode != IGRAPH_ALL && loops == IGRAPH_LOOPS_TWICE) { IGRAPH_ERROR("For a directed graph (with directions not ignored), " "IGRAPH_LOOPS_TWICE does not make sense.\n", IGRAPH_EINVAL); } /* Calculate needed space first & allocate it */ /* Note that 'mode' is treated as a bit field here; it's okay because * IGRAPH_ALL = IGRAPH_IN | IGRAPH_OUT, bit-wise */ if (mode & IGRAPH_OUT) { length += (VECTOR(graph->os)[node + 1] - VECTOR(graph->os)[node]); } if (mode & IGRAPH_IN) { length += (VECTOR(graph->is)[node + 1] - VECTOR(graph->is)[node]); } IGRAPH_CHECK(igraph_vector_resize(eids, length)); /* The loops below produce an ordering what is consistent with the * ordering returned by igraph_neighbors(), and this should be preserved. * We are dealing with two sorted lists; one for the successors and one * for the predecessors. If we have requested only one of them, we have * an easy job. If we have requested both, we need to merge the two lists * to ensure that the output is sorted by the vertex IDs of the "other" * endpoint of the affected edges */ if (!igraph_is_directed(graph) || mode != IGRAPH_ALL) { /* We did not ask for both directions; this is the easy case */ should_filter_duplicates = !(multiple == IGRAPH_MULTIPLE && ((!igraph_is_directed(graph) && loops == IGRAPH_LOOPS_TWICE) || (igraph_is_directed(graph) && loops != IGRAPH_NO_LOOPS))); if (mode & IGRAPH_OUT) { j = (long int) VECTOR(graph->os)[node + 1]; for (i = (long int) VECTOR(graph->os)[node]; i < j; i++) { long int edge = VECTOR(graph->oi)[i]; igraph_real_t other = VECTOR(graph->to)[edge]; DEDUPLICATE_IF_NEEDED(other, 1); VECTOR(*eids)[idx++] = edge; } } if (mode & IGRAPH_IN) { j = (long int) VECTOR(graph->is)[node + 1]; for (i = (long int) VECTOR(graph->is)[node]; i < j; i++) { long int edge = VECTOR(graph->ii)[i]; igraph_real_t other = VECTOR(graph->from)[edge]; DEDUPLICATE_IF_NEEDED(other, 1); VECTOR(*eids)[idx++] = edge; } } } else { /* both in- and out- neighbors in a directed graph, we need to merge the two 'vectors' */ long int j1 = (long int) VECTOR(graph->os)[node + 1]; long int j2 = (long int) VECTOR(graph->is)[node + 1]; long int i1 = (long int) VECTOR(graph->os)[node]; long int i2 = (long int) VECTOR(graph->is)[node]; long int eid1, eid2; long int n1, n2; should_filter_duplicates = !(multiple == IGRAPH_MULTIPLE && loops == IGRAPH_LOOPS_TWICE); while (i1 < j1 && i2 < j2) { eid1 = (long int) VECTOR(graph->oi)[i1]; eid2 = (long int) VECTOR(graph->ii)[i2]; n1 = (long int) VECTOR(graph->to)[eid1]; n2 = (long int) VECTOR(graph->from)[eid2]; if (n1 < n2) { i1++; DEDUPLICATE_IF_NEEDED(n1, 1); VECTOR(*eids)[idx++] = eid1; } else if (n1 > n2) { i2++; DEDUPLICATE_IF_NEEDED(n2, 1); VECTOR(*eids)[idx++] = eid2; } else { i1++; i2++; DEDUPLICATE_IF_NEEDED(n2, 2); VECTOR(*eids)[idx++] = eid1; if (should_filter_duplicates && ((loops == IGRAPH_LOOPS_ONCE && n1 == pnode && last_added == pnode) || (multiple == IGRAPH_NO_MULTIPLE))) { length--; continue; } VECTOR(*eids)[idx++] = eid2; } } while (i1 < j1) { eid1 = VECTOR(graph->oi)[i1++]; igraph_real_t to = VECTOR(graph->to)[eid1]; DEDUPLICATE_IF_NEEDED(to, 1); VECTOR(*eids)[idx++] = eid1; } while (i2 < j2) { eid2 = VECTOR(graph->ii)[i2++]; igraph_real_t from = VECTOR(graph->from)[eid2]; DEDUPLICATE_IF_NEEDED(from, 1); VECTOR(*eids)[idx++] = eid2; } } IGRAPH_CHECK(igraph_vector_resize(eids, length)); return IGRAPH_SUCCESS; #undef DEDUPLICATE_IF_NEEDED } /** * \function igraph_is_same_graph * \brief Are two graphs identical as labelled graphs? * * Two graphs are considered to be the same if they have the same vertex and edge sets. * Graphs which are the same may have multiple different representations in igraph, * hence the need for this function. * * * This function verifies that the two graphs have the same directedness, the same * number of vertices, and that they contain precisely the same edges (regardless of their ordering) * when written in terms of vertex indices. Graph attributes are not taken into account. * * * This concept is different from isomorphism. For example, the graphs * 0-1, 2-1 and 1-2, 0-1 are considered the same * because they only differ in the ordering of their edge lists and the ordering * of vertices in an undirected edge. However, they are not the same as * 0-2, 1-2, even though they are isomorphic to it. * Note that this latter graph contains the edge 0-2 * while the former two do not — thus their edge sets differ. * * \param graph1 The first graph object. * \param graph2 The second graph object. * \param res The result will be stored here. * \return Error code. * * Time complexity: O(E), the number of edges in the graphs. * * \sa igraph_isomorphic() to test if two graphs are isomorphic. */ int igraph_is_same_graph(const igraph_t *graph1, const igraph_t *graph2, igraph_bool_t *res) { long int nv1 = igraph_vcount(graph1); long int nv2 = igraph_vcount(graph2); long int ne1 = igraph_ecount(graph1); long int ne2 = igraph_ecount(graph2); long int i, eid1, eid2; *res = 0; /* Assume that the graphs differ */ /* Check for same number of vertices/edges */ if ((nv1 != nv2) || (ne1 != ne2)) { return IGRAPH_SUCCESS; } /* Check for same directedness */ if (igraph_is_directed(graph1) != igraph_is_directed(graph2)) { return IGRAPH_SUCCESS; } /* Vertices have no names, so they must be 0 to nv - 1 */ /* Edges are double sorted in the current representations ii/oi of * igraph_t (ii: by incoming, then outgoing, oi: vice versa), so * we just need to check them one by one. If that representation * changes, this part will need to change too. * * Furthermore, in the current representation the "source" of undirected * edges always has a vertex index that is no larger than that of the * "target". */ for (i = 0; i < ne1; i++) { eid1 = (long int) VECTOR(graph1->ii)[i]; eid2 = (long int) VECTOR(graph2->ii)[i]; /* Check they have the same source */ if (IGRAPH_FROM(graph1, eid1) != IGRAPH_FROM(graph2, eid2)) { return IGRAPH_SUCCESS; } /* Check they have the same target */ if (IGRAPH_TO(graph1, eid1) != IGRAPH_TO(graph2, eid2)) { return IGRAPH_SUCCESS; } } *res = 1; /* No difference was found, graphs are the same */ return IGRAPH_SUCCESS; } leidenbase/src/core/graph/attributes.c0000644000176200001440000003651514453301034017526 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_attributes.h" #include "igraph_memory.h" #include "graph/attributes.h" #include "config.h" #include #include /* Should you ever want to have a thread-local attribute handler table, prepend * IGRAPH_THREAD_LOCAL to the following declaration */ igraph_attribute_table_t *igraph_i_attribute_table = 0; int igraph_i_attribute_init(igraph_t *graph, void *attr) { graph->attr = 0; if (igraph_i_attribute_table) { return igraph_i_attribute_table->init(graph, attr); } else { return 0; } } void igraph_i_attribute_destroy(igraph_t *graph) { if (igraph_i_attribute_table) { igraph_i_attribute_table->destroy(graph); } } int igraph_i_attribute_copy(igraph_t *to, const igraph_t *from, igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->copy(to, from, ga, va, ea); } else { return 0; } } int igraph_i_attribute_add_vertices(igraph_t *graph, long int nv, void *attr) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->add_vertices(graph, nv, attr); } else { return 0; } } int igraph_i_attribute_permute_vertices(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_t *idx) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->permute_vertices(graph, newgraph, idx); } else { return 0; } } int igraph_i_attribute_combine_vertices(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_ptr_t *merges, const igraph_attribute_combination_t *comb) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->combine_vertices(graph, newgraph, merges, comb); } else { return 0; } } int igraph_i_attribute_add_edges(igraph_t *graph, const igraph_vector_t *edges, void *attr) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->add_edges(graph, edges, attr); } else { return 0; } } int igraph_i_attribute_permute_edges(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_t *idx) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->permute_edges(graph, newgraph, idx); } else { return 0; } } int igraph_i_attribute_combine_edges(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_ptr_t *merges, const igraph_attribute_combination_t *comb) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->combine_edges(graph, newgraph, merges, comb); } else { return 0; } } int igraph_i_attribute_get_info(const igraph_t *graph, igraph_strvector_t *gnames, igraph_vector_t *gtypes, igraph_strvector_t *vnames, igraph_vector_t *vtypes, igraph_strvector_t *enames, igraph_vector_t *etypes) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_info(graph, gnames, gtypes, vnames, vtypes, enames, etypes); } else { return 0; } } igraph_bool_t igraph_i_attribute_has_attr(const igraph_t *graph, igraph_attribute_elemtype_t type, const char *name) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->has_attr(graph, type, name); } else { return 0; } } int igraph_i_attribute_gettype(const igraph_t *graph, igraph_attribute_type_t *type, igraph_attribute_elemtype_t elemtype, const char *name) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->gettype(graph, type, elemtype, name); } else { return 0; } } int igraph_i_attribute_get_numeric_graph_attr(const igraph_t *graph, const char *name, igraph_vector_t *value) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_numeric_graph_attr(graph, name, value); } else { return 0; } } int igraph_i_attribute_get_numeric_vertex_attr(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_vector_t *value) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_numeric_vertex_attr(graph, name, vs, value); } else { return 0; } } int igraph_i_attribute_get_numeric_edge_attr(const igraph_t *graph, const char *name, igraph_es_t es, igraph_vector_t *value) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_numeric_edge_attr(graph, name, es, value); } else { return 0; } } int igraph_i_attribute_get_string_graph_attr(const igraph_t *graph, const char *name, igraph_strvector_t *value) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_string_graph_attr(graph, name, value); } else { return 0; } } int igraph_i_attribute_get_string_vertex_attr(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_strvector_t *value) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_string_vertex_attr(graph, name, vs, value); } else { return 0; } } int igraph_i_attribute_get_string_edge_attr(const igraph_t *graph, const char *name, igraph_es_t es, igraph_strvector_t *value) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_string_edge_attr(graph, name, es, value); } else { return 0; } } int igraph_i_attribute_get_bool_graph_attr(const igraph_t *graph, const char *name, igraph_vector_bool_t *value) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_bool_graph_attr(graph, name, value); } else { return 0; } } int igraph_i_attribute_get_bool_vertex_attr(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_vector_bool_t *value) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_bool_vertex_attr(graph, name, vs, value); } else { return 0; } } int igraph_i_attribute_get_bool_edge_attr(const igraph_t *graph, const char *name, igraph_es_t es, igraph_vector_bool_t *value) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->get_bool_edge_attr(graph, name, es, value); } else { return 0; } } /** * \function igraph_set_attribute_table * \brief Attach an attribute table. * * This function attaches attribute handling code to the igraph library. * Note that the attribute handler table is \em not thread-local even if * igraph is compiled in thread-local mode. In the vast majority of cases, * this is not a significant restriction. * * \param table Pointer to an \ref igraph_attribute_table_t object * containing the functions for attribute manipulation. Supply \c * NULL here if you don't want attributes. * \return Pointer to the old attribute handling table. * * Time complexity: O(1). */ igraph_attribute_table_t * igraph_set_attribute_table(const igraph_attribute_table_t * table) { igraph_attribute_table_t *old = igraph_i_attribute_table; igraph_i_attribute_table = (igraph_attribute_table_t*) table; return old; } igraph_attribute_table_t * igraph_i_set_attribute_table(const igraph_attribute_table_t * table) { IGRAPH_WARNING("igraph_i_set_attribute_table is deprecated, use igraph_set_attribute_table."); return igraph_set_attribute_table(table); } igraph_bool_t igraph_has_attribute_table(void) { return igraph_i_attribute_table != 0; } /** * \function igraph_attribute_combination_init * \brief Initialize attribute combination list. * * \param comb The uninitialized attribute combination list. * \return Error code. * * Time complexity: O(1) */ int igraph_attribute_combination_init(igraph_attribute_combination_t *comb) { IGRAPH_CHECK(igraph_vector_ptr_init(&comb->list, 0)); return IGRAPH_SUCCESS; } /** * \function igraph_attribute_combination_destroy * \brief Destroy attribute combination list. * * \param comb The attribute combination list. * * Time complexity: O(n), where n is the number of records in the attribute combination list. */ void igraph_attribute_combination_destroy(igraph_attribute_combination_t *comb) { long int i, n = igraph_vector_ptr_size(&comb->list); for (i = 0; i < n; i++) { igraph_attribute_combination_record_t *rec = VECTOR(comb->list)[i]; if (rec->name) { IGRAPH_FREE(rec->name); } IGRAPH_FREE(rec); } igraph_vector_ptr_destroy(&comb->list); } /** * \function igraph_attribute_combination_add * \brief Add combination record to attribute combination list. * * \param comb The attribute combination list. * \param name The name of the attribute. If the name already exists * the attribute combination record will be replaced. * Use NULL to add a default combination record for all * atributes not in the list. * \param type The type of the attribute combination. See \ref * igraph_attribute_combination_type_t for the options. * \param func Function to be used if \p type is * \c IGRAPH_ATTRIBUTE_COMBINE_FUNCTION. * \return Error code. * * Time complexity: O(n), where n is the number of current attribute * combinations. */ int igraph_attribute_combination_add(igraph_attribute_combination_t *comb, const char *name, igraph_attribute_combination_type_t type, igraph_function_pointer_t func) { long int i, n = igraph_vector_ptr_size(&comb->list); /* Search, in case it is already there */ for (i = 0; i < n; i++) { igraph_attribute_combination_record_t *r = VECTOR(comb->list)[i]; const char *n = r->name; if ( (!name && !n) || (name && n && !strcmp(n, name)) ) { r->type = type; r->func = func; break; } } if (i == n) { /* This is a new attribute name */ igraph_attribute_combination_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_combination_record_t); if (!rec) { IGRAPH_ERROR("Cannot create attribute combination data", IGRAPH_ENOMEM); } if (!name) { rec->name = NULL; } else { rec->name = strdup(name); } rec->type = type; rec->func = func; IGRAPH_CHECK(igraph_vector_ptr_push_back(&comb->list, rec)); } return IGRAPH_SUCCESS; } /** * \function igraph_attribute_combination_remove * \brief Remove a record from an attribute combination list. * * \param comb The attribute combination list. * \param name The attribute name of the attribute combination record * to remove. It will be ignored if the named attribute * does not exist. It can be NULL to remove the default * combination record. * \return Error code. This currently always returns IGRAPH_SUCCESS. * * Time complexity: O(n), where n is the number of records in the attribute combination list. */ int igraph_attribute_combination_remove(igraph_attribute_combination_t *comb, const char *name) { long int i, n = igraph_vector_ptr_size(&comb->list); /* Search, in case it is already there */ for (i = 0; i < n; i++) { igraph_attribute_combination_record_t *r = VECTOR(comb->list)[i]; const char *n = r->name; if ( (!name && !n) || (name && n && !strcmp(n, name)) ) { break; } } if (i != n) { igraph_attribute_combination_record_t *r = VECTOR(comb->list)[i]; if (r->name) { IGRAPH_FREE(r->name); } IGRAPH_FREE(r); igraph_vector_ptr_remove(&comb->list, i); } else { /* It is not there, we don't do anything */ } return IGRAPH_SUCCESS; } int igraph_attribute_combination_query(const igraph_attribute_combination_t *comb, const char *name, igraph_attribute_combination_type_t *type, igraph_function_pointer_t *func) { long int i, def = -1, len = igraph_vector_ptr_size(&comb->list); for (i = 0; i < len; i++) { igraph_attribute_combination_record_t *rec = VECTOR(comb->list)[i]; const char *n = rec->name; if ( (!name && !n) || (name && n && !strcmp(n, name)) ) { *type = rec->type; *func = rec->func; return 0; } if (!n) { def = i; } } if (def == -1) { /* Did not find anything */ *type = IGRAPH_ATTRIBUTE_COMBINE_DEFAULT; *func = 0; } else { igraph_attribute_combination_record_t *rec = VECTOR(comb->list)[def]; *type = rec->type; *func = rec->func; } return 0; } int igraph_attribute_combination(igraph_attribute_combination_t *comb, ...) { va_list ap; IGRAPH_CHECK(igraph_attribute_combination_init(comb)); va_start(ap, comb); while (1) { igraph_function_pointer_t func = 0; igraph_attribute_combination_type_t type; const char *name; name = va_arg(ap, const char *); if (name == IGRAPH_NO_MORE_ATTRIBUTES) { break; } type = (igraph_attribute_combination_type_t)va_arg(ap, int); if (type == IGRAPH_ATTRIBUTE_COMBINE_FUNCTION) { func = va_arg(ap, igraph_function_pointer_t); } if (strlen(name) == 0) { name = 0; } IGRAPH_CHECK(igraph_attribute_combination_add(comb, name, type, func)); } va_end(ap); return 0; } leidenbase/src/core/graph/iterators.c0000644000176200001440000016767614447675374017421 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_iterators.h" #include "igraph_memory.h" #include "igraph_interface.h" #include #include /** * \section about_iterators About selectors, iterators * * Everything about vertices and vertex selectors also applies * to edges and edge selectors unless explicitly noted otherwise. * * The vertex (and edge) selector notion was introduced in igraph 0.2. * It is a way to reference a sequence of vertices or edges * independently of the graph. * * While this might sound quite mysterious, it is actually very * simple. For example, all vertices of a graph can be selected by * \ref igraph_vs_all() and the graph independence means that * \ref igraph_vs_all() is not parametrized by a graph object. That is, * \ref igraph_vs_all() is the general \em concept of selecting all vertices * of a graph. A vertex selector is then a way to specify the class of vertices * to be visited. The selector might specify that all vertices of a graph or * all the neighbours of a vertex are to be visited. A vertex selector is a * way of saying that you want to visit a bunch of vertices, as opposed to a * vertex iterator which is a concrete plan for visiting each of the * chosen vertices of a specific graph. * * To determine the actual vertex IDs implied by a vertex selector, you * need to apply the concept of selecting vertices to a specific graph object. * This can be accomplished by instantiating a vertex iterator using a * specific vertex selection concept and a specific graph object. The notion * of vertex iterators can be thought of in the following way. Given a * specific graph object and the class of vertices to be visited, a vertex * iterator is a road map, plan or route for how to visit the chosen * vertices. * * Some vertex selectors have \em immediate versions. These have the * prefix \c igraph_vss instead of \c igraph_vs, e.g. \ref igraph_vss_all() * instead of \ref igraph_vs_all(). The immediate versions are to be used in * the parameter list of the igraph functions, such as \ref igraph_degree(). * These functions are not associated with any \type igraph_vs_t object, so * they have no separate constructors and destructors * (destroy functions). */ /** * \section about_vertex_selectors * * Vertex selectors are created by vertex selector constructors, * can be instantiated with \ref igraph_vit_create(), and are * destroyed with \ref igraph_vs_destroy(). */ /** * \function igraph_vs_all * \brief Vertex set, all vertices of a graph. * * \param vs Pointer to an uninitialized \type igraph_vs_t object. * \return Error code. * \sa \ref igraph_vss_all(), \ref igraph_vs_destroy() * * This selector includes all vertices of a given graph in * increasing vertex id order. * * * Time complexity: O(1). */ int igraph_vs_all(igraph_vs_t *vs) { vs->type = IGRAPH_VS_ALL; return 0; } /** * \function igraph_vss_all * \brief All vertices of a graph (immediate version). * * Immediate vertex selector for all vertices in a graph. It can * be used conveniently when some vertex property (e.g. betweenness, * degree, etc.) should be calculated for all vertices. * * \return A vertex selector for all vertices in a graph. * \sa \ref igraph_vs_all() * * Time complexity: O(1). */ igraph_vs_t igraph_vss_all(void) { igraph_vs_t allvs; allvs.type = IGRAPH_VS_ALL; return allvs; } /** * \function igraph_vs_adj * \brief Adjacent vertices of a vertex. * * All neighboring vertices of a given vertex are selected by this * selector. The \c mode argument controls the type of the neighboring * vertices to be selected. The vertices are visited in increasing vertex * ID order, as of igraph version 0.4. * * \param vs Pointer to an uninitialized vertex selector object. * \param vid Vertex ID, the center of the neighborhood. * \param mode Decides the type of the neighborhood for directed * graphs. This parameter is ignored for undirected graphs. * Possible values: * \clist * \cli IGRAPH_OUT * All vertices to which there is a directed edge from \c vid. That * is, all the out-neighbors of \c vid. * \cli IGRAPH_IN * All vertices from which there is a directed edge to \c vid. In * other words, all the in-neighbors of \c vid. * \cli IGRAPH_ALL * All vertices to which or from which there is a directed edge * from/to \c vid. That is, all the neighbors of \c vid considered * as if the graph is undirected. * \endclist * \return Error code. * \sa \ref igraph_vs_destroy() * * Time complexity: O(1). */ int igraph_vs_adj(igraph_vs_t *vs, igraph_integer_t vid, igraph_neimode_t mode) { vs->type = IGRAPH_VS_ADJ; vs->data.adj.vid = vid; vs->data.adj.mode = mode; return 0; } /** * \function igraph_vs_nonadj * \brief Non-adjacent vertices of a vertex. * * All non-neighboring vertices of a given vertex. The \p mode * argument controls the type of neighboring vertices \em not to * select. Instead of selecting immediate neighbors of \c vid as is done by * \ref igraph_vs_adj(), the current function selects vertices that are \em not * immediate neighbors of \c vid. * * \param vs Pointer to an uninitialized vertex selector object. * \param vid Vertex ID, the \quote center \endquote of the * non-neighborhood. * \param mode The type of neighborhood not to select in directed * graphs. Possible values: * \clist * \cli IGRAPH_OUT * All vertices will be selected except those to which there is a * directed edge from \c vid. That is, we select all vertices * excluding the out-neighbors of \c vid. * \cli IGRAPH_IN * All vertices will be selected except those from which there is a * directed edge to \c vid. In other words, we select all vertices * but the in-neighbors of \c vid. * \cli IGRAPH_ALL * All vertices will be selected except those from or to which there * is a directed edge to or from \c vid. That is, we select all * vertices of \c vid except for its immediate neighbors. * \endclist * \return Error code. * \sa \ref igraph_vs_destroy() * * Time complexity: O(1). * * \example examples/simple/igraph_vs_nonadj.c */ int igraph_vs_nonadj(igraph_vs_t *vs, igraph_integer_t vid, igraph_neimode_t mode) { vs->type = IGRAPH_VS_NONADJ; vs->data.adj.vid = vid; vs->data.adj.mode = mode; return 0; } /** * \function igraph_vs_none * \brief Empty vertex set. * * Creates an empty vertex selector. * * \param vs Pointer to an uninitialized vertex selector object. * \return Error code. * \sa \ref igraph_vss_none(), \ref igraph_vs_destroy() * * Time complexity: O(1). */ int igraph_vs_none(igraph_vs_t *vs) { vs->type = IGRAPH_VS_NONE; return 0; } /** * \function igraph_vss_none * \brief Empty vertex set (immediate version). * * The immediate version of the empty vertex selector. * * \return An empty vertex selector. * \sa \ref igraph_vs_none() * * Time complexity: O(1). */ igraph_vs_t igraph_vss_none(void) { igraph_vs_t nonevs; nonevs.type = IGRAPH_VS_NONE; return nonevs; } /** * \function igraph_vs_1 * \brief Vertex set with a single vertex. * * This vertex selector selects a single vertex. * * \param vs Pointer to an uninitialized vertex selector object. * \param vid The vertex id to be selected. * \return Error Code. * \sa \ref igraph_vss_1(), \ref igraph_vs_destroy() * * Time complexity: O(1). */ int igraph_vs_1(igraph_vs_t *vs, igraph_integer_t vid) { vs->type = IGRAPH_VS_1; vs->data.vid = vid; return 0; } /** * \function igraph_vss_1 * \brief Vertex set with a single vertex (immediate version). * * The immediate version of the single-vertex selector. * * \param vid The vertex to be selected. * \return A vertex selector containing a single vertex. * \sa \ref igraph_vs_1() * * Time complexity: O(1). */ igraph_vs_t igraph_vss_1(igraph_integer_t vid) { igraph_vs_t onevs; onevs.type = IGRAPH_VS_1; onevs.data.vid = vid; return onevs; } /** * \function igraph_vs_vector * \brief Vertex set based on a vector. * * This function makes it possible to handle a \type vector_t * temporarily as a vertex selector. The vertex selector should be * thought of like a \em view to the vector. If you make changes to * the vector that also affects the vertex selector. Destroying the * vertex selector does not destroy the vector. (Of course.) Do not * destroy the vector before destroying the vertex selector, or you * might get strange behavior. * * \param vs Pointer to an uninitialized vertex selector. * \param v Pointer to a \type igraph_vector_t object. * \return Error code. * \sa \ref igraph_vss_vector(), \ref igraph_vs_destroy() * * Time complexity: O(1). * * \example examples/simple/igraph_vs_vector.c */ int igraph_vs_vector(igraph_vs_t *vs, const igraph_vector_t *v) { vs->type = IGRAPH_VS_VECTORPTR; vs->data.vecptr = v; return 0; } /** * \function igraph_vss_vector * \brief Vertex set based on a vector (immediate version). * * This is the immediate version of \ref igraph_vs_vector. * * \param v Pointer to a \type igraph_vector_t object. * \return A vertex selector object containing the vertices in the * vector. * \sa \ref igraph_vs_vector() * * Time complexity: O(1). */ igraph_vs_t igraph_vss_vector(const igraph_vector_t *v) { igraph_vs_t vecvs; vecvs.type = IGRAPH_VS_VECTORPTR; vecvs.data.vecptr = v; return vecvs; } /** * \function igraph_vs_vector_small * \brief Create a vertex set by giving its elements. * * This function can be used to create a vertex selector with a couple * of vertices. Do not forget to include a -1 after the * last vertex id. The behavior of the function is undefined if you * don't use a -1 properly. * * * Note that the vertex ids supplied will be parsed as * int's so you cannot supply arbitrarily large (too * large for int) vertex ids here. * * \param vs Pointer to an uninitialized vertex selector object. * \param ... Additional parameters, these will be the vertex ids to * be included in the vertex selector. Supply a -1 * after the last vertex id. * \return Error code. * \sa \ref igraph_vs_destroy() * * Time complexity: O(n), the number of vertex ids supplied. */ int igraph_vs_vector_small(igraph_vs_t *vs, ...) { va_list ap; long int i, n = 0; vs->type = IGRAPH_VS_VECTOR; vs->data.vecptr = IGRAPH_CALLOC(1, igraph_vector_t); if (vs->data.vecptr == 0) { IGRAPH_ERROR("Cannot create vertex selector", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*)vs->data.vecptr); va_start(ap, vs); while (1) { int num = va_arg(ap, int); if (num == -1) { break; } n++; } va_end(ap); IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t*)vs->data.vecptr, n); va_start(ap, vs); for (i = 0; i < n; i++) { VECTOR(*vs->data.vecptr)[i] = (igraph_real_t) va_arg(ap, int); } va_end(ap); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_vs_vector_copy * \brief Vertex set based on a vector, with copying. * * This function makes it possible to handle a \type vector_t * permanently as a vertex selector. The vertex selector creates a * copy of the original vector, so the vector can safely be destroyed * after creating the vertex selector. Changing the original vector * will not affect the vertex selector. The vertex selector is * responsible for deleting the copy made by itself. * * \param vs Pointer to an uninitialized vertex selector. * \param v Pointer to a \type igraph_vector_t object. * \return Error code. * \sa \ref igraph_vs_destroy() * * Time complexity: O(1). */ int igraph_vs_vector_copy(igraph_vs_t *vs, const igraph_vector_t *v) { vs->type = IGRAPH_VS_VECTOR; vs->data.vecptr = IGRAPH_CALLOC(1, igraph_vector_t); if (vs->data.vecptr == 0) { IGRAPH_ERROR("Cannot create vertex selector", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*)vs->data.vecptr); IGRAPH_CHECK(igraph_vector_copy((igraph_vector_t*)vs->data.vecptr, v)); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_vs_seq * \brief Vertex set, an interval of vertices. * * Creates a vertex selector containing all vertices with vertex id * equal to or bigger than \c from and equal to or smaller than \c * to. * * \param vs Pointer to an uninitialized vertex selector object. * \param from The first vertex id to be included in the vertex * selector. * \param to The last vertex id to be included in the vertex * selector. * \return Error code. * \sa \ref igraph_vss_seq(), \ref igraph_vs_destroy() * * Time complexity: O(1). * * \example examples/simple/igraph_vs_seq.c */ int igraph_vs_seq(igraph_vs_t *vs, igraph_integer_t from, igraph_integer_t to) { vs->type = IGRAPH_VS_SEQ; vs->data.seq.from = from; vs->data.seq.to = to + 1; return 0; } /** * \function igraph_vss_seq * \brief An interval of vertices (immediate version). * * The immediate version of \ref igraph_vs_seq(). * * \param from The first vertex id to be included in the vertex * selector. * \param to The last vertex id to be included in the vertex * selector. * \return Error code. * \sa \ref igraph_vs_seq() * * Time complexity: O(1). */ igraph_vs_t igraph_vss_seq(igraph_integer_t from, igraph_integer_t to) { igraph_vs_t vs; vs.type = IGRAPH_VS_SEQ; vs.data.seq.from = from; vs.data.seq.to = to + 1; return vs; } /** * \function igraph_vs_destroy * \brief Destroy a vertex set. * * This function should be called for all vertex selectors when they * are not needed. The memory allocated for the vertex selector will * be deallocated. Do not call this function on vertex selectors * created with the immediate versions of the vertex selector * constructors (starting with igraph_vss). * * \param vs Pointer to a vertex selector object. * * Time complexity: operating system dependent, usually O(1). */ void igraph_vs_destroy(igraph_vs_t *vs) { switch (vs->type) { case IGRAPH_VS_ALL: case IGRAPH_VS_ADJ: case IGRAPH_VS_NONE: case IGRAPH_VS_1: case IGRAPH_VS_VECTORPTR: case IGRAPH_VS_SEQ: case IGRAPH_VS_NONADJ: break; case IGRAPH_VS_VECTOR: igraph_vector_destroy((igraph_vector_t*)vs->data.vecptr); IGRAPH_FREE(vs->data.vecptr); break; default: break; } } /** * \function igraph_vs_is_all * \brief Check whether all vertices are included. * * This function checks whether the vertex selector object was created * by \ref igraph_vs_all() or \ref igraph_vss_all(). Note that the * vertex selector might contain all vertices in a given graph but if * it wasn't created by the two constructors mentioned here the return * value will be FALSE. * * \param vs Pointer to a vertex selector object. * \return TRUE (1) if the vertex selector contains all vertices and * FALSE (0) otherwise. * * Time complexity: O(1). */ igraph_bool_t igraph_vs_is_all(const igraph_vs_t *vs) { return vs->type == IGRAPH_VS_ALL; } int igraph_vs_as_vector(const igraph_t *graph, igraph_vs_t vs, igraph_vector_t *v) { igraph_vit_t vit; IGRAPH_CHECK(igraph_vit_create(graph, vs, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); IGRAPH_CHECK(igraph_vit_as_vector(&vit, v)); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_vs_copy * \brief Creates a copy of a vertex selector. * \param src The selector being copied. * \param dest An uninitialized selector that will contain the copy. */ int igraph_vs_copy(igraph_vs_t* dest, const igraph_vs_t* src) { memcpy(dest, src, sizeof(igraph_vs_t)); switch (dest->type) { case IGRAPH_VS_VECTOR: dest->data.vecptr = IGRAPH_CALLOC(1, igraph_vector_t); if (!dest->data.vecptr) { IGRAPH_ERROR("Cannot copy vertex selector", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_copy((igraph_vector_t*)dest->data.vecptr, (igraph_vector_t*)src->data.vecptr)); break; } return 0; } /** * \function igraph_vs_type * \brief Returns the type of the vertex selector. */ int igraph_vs_type(const igraph_vs_t *vs) { return vs->type; } /** * \function igraph_vs_size * \brief Returns the size of the vertex selector. * * The size of the vertex selector is the number of vertices it will * yield when it is iterated over. * * \param graph The graph over which we will iterate. * \param result The result will be returned here. */ int igraph_vs_size(const igraph_t *graph, const igraph_vs_t *vs, igraph_integer_t *result) { igraph_vector_t vec; igraph_bool_t *seen; long i; switch (vs->type) { case IGRAPH_VS_NONE: *result = 0; return 0; case IGRAPH_VS_1: *result = 0; if (vs->data.vid < igraph_vcount(graph) && vs->data.vid >= 0) { *result = 1; } return 0; case IGRAPH_VS_SEQ: *result = vs->data.seq.to - vs->data.seq.from; return 0; case IGRAPH_VS_ALL: *result = igraph_vcount(graph); return 0; case IGRAPH_VS_ADJ: IGRAPH_VECTOR_INIT_FINALLY(&vec, 0); IGRAPH_CHECK(igraph_neighbors(graph, &vec, vs->data.adj.vid, vs->data.adj.mode)); *result = (igraph_integer_t) igraph_vector_size(&vec); igraph_vector_destroy(&vec); IGRAPH_FINALLY_CLEAN(1); return 0; case IGRAPH_VS_NONADJ: IGRAPH_VECTOR_INIT_FINALLY(&vec, 0); IGRAPH_CHECK(igraph_neighbors(graph, &vec, vs->data.adj.vid, vs->data.adj.mode)); *result = igraph_vcount(graph); seen = IGRAPH_CALLOC(*result, igraph_bool_t); if (seen == 0) { IGRAPH_ERROR("Cannot calculate selector length", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, seen); for (i = 0; i < igraph_vector_size(&vec); i++) { if (!seen[(long int)VECTOR(vec)[i]]) { (*result)--; seen[(long int)VECTOR(vec)[i]] = 1; } } igraph_free(seen); igraph_vector_destroy(&vec); IGRAPH_FINALLY_CLEAN(2); return 0; case IGRAPH_VS_VECTOR: case IGRAPH_VS_VECTORPTR: *result = (igraph_integer_t) igraph_vector_size((igraph_vector_t*)vs->data.vecptr); return 0; } IGRAPH_ERROR("Cannot calculate selector length, invalid selector type", IGRAPH_EINVAL); } /***************************************************/ /** * \function igraph_vit_create * \brief Creates a vertex iterator from a vertex selector. * * This function instantiates a vertex selector object with a given * graph. This is the step when the actual vertex ids are created from * the \em logical notion of the vertex selector based on the graph. * E.g. a vertex selector created with \ref igraph_vs_all() contains * knowledge that \em all vertices are included in a (yet indefinite) * graph. When instantiating it a vertex iterator object is created, * this contains the actual vertex ids in the graph supplied as a * parameter. * * * The same vertex selector object can be used to instantiate any * number vertex iterators. * * \param graph An \type igraph_t object, a graph. * \param vs A vertex selector object. * \param vit Pointer to an uninitialized vertex iterator object. * \return Error code. * \sa \ref igraph_vit_destroy(). * * Time complexity: it depends on the vertex selector type. O(1) for * vertex selectors created with \ref igraph_vs_all(), \ref * igraph_vs_none(), \ref igraph_vs_1, \ref igraph_vs_vector, \ref * igraph_vs_seq(), \ref igraph_vs_vector(), \ref * igraph_vs_vector_small(). O(d) for \ref igraph_vs_adj(), d is the * number of vertex ids to be included in the iterator. O(|V|) for * \ref igraph_vs_nonadj(), |V| is the number of vertices in the graph. */ int igraph_vit_create(const igraph_t *graph, igraph_vs_t vs, igraph_vit_t *vit) { igraph_vector_t vec; igraph_bool_t *seen; long int i, j, n; switch (vs.type) { case IGRAPH_VS_ALL: vit->type = IGRAPH_VIT_SEQ; vit->pos = 0; vit->start = 0; vit->end = igraph_vcount(graph); break; case IGRAPH_VS_ADJ: vit->type = IGRAPH_VIT_VECTOR; vit->pos = 0; vit->start = 0; vit->vec = IGRAPH_CALLOC(1, igraph_vector_t); if (vit->vec == 0) { IGRAPH_ERROR("Cannot create iterator", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*) vit->vec); IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t*)vit->vec, 0); IGRAPH_CHECK(igraph_neighbors(graph, (igraph_vector_t*)vit->vec, vs.data.adj.vid, vs.data.adj.mode)); vit->end = igraph_vector_size(vit->vec); IGRAPH_FINALLY_CLEAN(2); break; case IGRAPH_VS_NONADJ: vit->type = IGRAPH_VIT_VECTOR; vit->pos = 0; vit->start = 0; vit->vec = IGRAPH_CALLOC(1, igraph_vector_t); if (vit->vec == 0) { IGRAPH_ERROR("Cannot create iterator", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*) vit->vec); IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t *) vit->vec, 0); IGRAPH_VECTOR_INIT_FINALLY(&vec, 0); IGRAPH_CHECK(igraph_neighbors(graph, &vec, vs.data.adj.vid, vs.data.adj.mode)); n = igraph_vcount(graph); seen = IGRAPH_CALLOC(n, igraph_bool_t); if (seen == 0) { IGRAPH_ERROR("Cannot create iterator", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, seen); for (i = 0; i < igraph_vector_size(&vec); i++) { if (! seen [ (long int) VECTOR(vec)[i] ] ) { n--; seen[ (long int) VECTOR(vec)[i] ] = 1; } } IGRAPH_CHECK(igraph_vector_resize((igraph_vector_t*)vit->vec, n)); for (i = 0, j = 0; j < n; i++) { if (!seen[i]) { VECTOR(*vit->vec)[j++] = i; } } IGRAPH_FREE(seen); igraph_vector_destroy(&vec); vit->end = n; IGRAPH_FINALLY_CLEAN(4); break; case IGRAPH_VS_NONE: vit->type = IGRAPH_VIT_SEQ; vit->pos = 0; vit->start = 0; vit->end = 0; break; case IGRAPH_VS_1: vit->type = IGRAPH_VIT_SEQ; vit->pos = vs.data.vid; vit->start = vs.data.vid; vit->end = vs.data.vid + 1; if (vit->pos >= igraph_vcount(graph)) { IGRAPH_ERROR("Cannot create iterator, invalid vertex id", IGRAPH_EINVVID); } break; case IGRAPH_VS_VECTORPTR: case IGRAPH_VS_VECTOR: vit->type = IGRAPH_VIT_VECTORPTR; vit->pos = 0; vit->start = 0; vit->vec = vs.data.vecptr; vit->end = igraph_vector_size(vit->vec); if (!igraph_vector_isininterval(vit->vec, 0, igraph_vcount(graph) - 1)) { IGRAPH_ERROR("Cannot create iterator, invalid vertex id", IGRAPH_EINVVID); } break; case IGRAPH_VS_SEQ: vit->type = IGRAPH_VIT_SEQ; vit->pos = vs.data.seq.from; vit->start = vs.data.seq.from; vit->end = vs.data.seq.to; break; default: IGRAPH_ERROR("Cannot create iterator, invalid selector", IGRAPH_EINVAL); break; } return 0; } /** * \function igraph_vit_destroy * \brief Destroys a vertex iterator. * * * Deallocates memory allocated for a vertex iterator. * * \param vit Pointer to an initialized vertex iterator object. * \sa \ref igraph_vit_create() * * Time complexity: operating system dependent, usually O(1). */ void igraph_vit_destroy(const igraph_vit_t *vit) { switch (vit->type) { case IGRAPH_VIT_SEQ: case IGRAPH_VIT_VECTORPTR: break; case IGRAPH_VIT_VECTOR: igraph_vector_destroy((igraph_vector_t*)vit->vec); igraph_free((igraph_vector_t*)vit->vec); break; default: /* IGRAPH_ERROR("Cannot destroy iterator, unknown type", IGRAPH_EINVAL); */ break; } } int igraph_vit_as_vector(const igraph_vit_t *vit, igraph_vector_t *v) { long int i; IGRAPH_CHECK(igraph_vector_resize(v, IGRAPH_VIT_SIZE(*vit))); switch (vit->type) { case IGRAPH_VIT_SEQ: for (i = 0; i < IGRAPH_VIT_SIZE(*vit); i++) { VECTOR(*v)[i] = vit->start + i; } break; case IGRAPH_VIT_VECTOR: case IGRAPH_VIT_VECTORPTR: for (i = 0; i < IGRAPH_VIT_SIZE(*vit); i++) { VECTOR(*v)[i] = VECTOR(*vit->vec)[i]; } break; default: IGRAPH_ERROR("Cannot convert to vector, unknown iterator type", IGRAPH_EINVAL); break; } return 0; } /*******************************************************/ /** * \function igraph_es_all * \brief Edge set, all edges. * * \param es Pointer to an uninitialized edge selector object. * \param order Constant giving the order in which the edges will be * included in the selector. Possible values: * \c IGRAPH_EDGEORDER_ID, edge id order. * \c IGRAPH_EDGEORDER_FROM, vertex id order, the id of the * \em source vertex counts for directed graphs. The order * of the incident edges of a given vertex is arbitrary. * \c IGRAPH_EDGEORDER_TO, vertex id order, the id of the \em * target vertex counts for directed graphs. The order * of the incident edges of a given vertex is arbitrary. * For undirected graph the latter two is the same. * \return Error code. * \sa \ref igraph_ess_all(), \ref igraph_es_destroy() * * Time complexity: O(1). */ int igraph_es_all(igraph_es_t *es, igraph_edgeorder_type_t order) { switch (order) { case IGRAPH_EDGEORDER_ID: es->type = IGRAPH_ES_ALL; break; case IGRAPH_EDGEORDER_FROM: es->type = IGRAPH_ES_ALLFROM; break; case IGRAPH_EDGEORDER_TO: es->type = IGRAPH_ES_ALLTO; break; default: IGRAPH_ERROR("Invalid edge order, cannot create selector", IGRAPH_EINVAL); break; } return 0; } /** * \function igraph_ess_all * \brief Edge set, all edges (immediate version) * * The immediate version of the all-edges selector. * * \param order Constant giving the order of the edges in the edge * selector. See \ref igraph_es_all() for the possible values. * \return The edge selector. * \sa \ref igraph_es_all() * * Time complexity: O(1). */ igraph_es_t igraph_ess_all(igraph_edgeorder_type_t order) { igraph_es_t es; igraph_es_all(&es, order); /* cannot fail */ return es; } /** * \function igraph_es_incident * \brief Edges incident on a given vertex. * * \param es Pointer to an uninitialized edge selector object. * \param vid Vertex id, of which the incident edges will be * selected. * \param mode Constant giving the type of the incident edges to * select. This is ignored for undirected graphs. Possible values: * \c IGRAPH_OUT, outgoing edges; * \c IGRAPH_IN, incoming edges; * \c IGRAPH_ALL, all edges. * \return Error code. * \sa \ref igraph_es_destroy() * * Time complexity: O(1). */ int igraph_es_incident(igraph_es_t *es, igraph_integer_t vid, igraph_neimode_t mode) { es->type = IGRAPH_ES_INCIDENT; es->data.incident.vid = vid; es->data.incident.mode = mode; return 0; } /** * \function igraph_es_none * \brief Empty edge selector. * * \param es Pointer to an uninitialized edge selector object to * initialize. * \return Error code. * \sa \ref igraph_ess_none(), \ref igraph_es_destroy() * * Time complexity: O(1). */ int igraph_es_none(igraph_es_t *es) { es->type = IGRAPH_ES_NONE; return 0; } /** * \function igraph_ess_none * \brief Immediate empty edge selector. * * * Immediate version of the empty edge selector. * * \return Initialized empty edge selector. * \sa \ref igraph_es_none() * * Time complexity: O(1). */ igraph_es_t igraph_ess_none(void) { igraph_es_t es; es.type = IGRAPH_ES_NONE; return es; } /** * \function igraph_es_1 * \brief Edge selector containing a single edge. * * \param es Pointer to an uninitialized edge selector object. * \param eid Edge id of the edge to select. * \return Error code. * \sa \ref igraph_ess_1(), \ref igraph_es_destroy() * * Time complexity: O(1). */ int igraph_es_1(igraph_es_t *es, igraph_integer_t eid) { es->type = IGRAPH_ES_1; es->data.eid = eid; return 0; } /** * \function igraph_ess_1 * \brief Immediate version of the single edge edge selector. * * \param eid The id of the edge. * \return The edge selector. * \sa \ref igraph_es_1() * * Time complexity: O(1). */ igraph_es_t igraph_ess_1(igraph_integer_t eid) { igraph_es_t es; es.type = IGRAPH_ES_1; es.data.eid = eid; return es; } /** * \function igraph_es_vector * \brief Handle a vector as an edge selector. * * * Creates an edge selector which serves as a view to a vector * containing edge ids. Do not destroy the vector before destroying * the view. * * Many views can be created to the same vector. * * \param es Pointer to an uninitialized edge selector. * \param v Vector containing edge ids. * \return Error code. * \sa \ref igraph_ess_vector(), \ref igraph_es_destroy() * * Time complexity: O(1). */ int igraph_es_vector(igraph_es_t *es, const igraph_vector_t *v) { es->type = IGRAPH_ES_VECTORPTR; es->data.vecptr = v; return 0; } /** * \function igraph_es_vector_copy * \brief Edge set, based on a vector, with copying. * * * This function makes it possible to handle a \type vector_t * permanently as an edge selector. The edge selector creates a * copy of the original vector, so the vector can safely be destroyed * after creating the edge selector. Changing the original vector * will not affect the edge selector. The edge selector is * responsible for deleting the copy made by itself. * * \param es Pointer to an uninitialized edge selector. * \param v Pointer to a \type igraph_vector_t object. * \return Error code. * \sa \ref igraph_es_destroy() * * Time complexity: O(1). */ int igraph_es_vector_copy(igraph_es_t *es, const igraph_vector_t *v) { es->type = IGRAPH_ES_VECTOR; es->data.vecptr = IGRAPH_CALLOC(1, igraph_vector_t); if (es->data.vecptr == 0) { IGRAPH_ERROR("Cannot create edge selector", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*)es->data.vecptr); IGRAPH_CHECK(igraph_vector_copy((igraph_vector_t*)es->data.vecptr, v)); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_ess_vector * \brief Immediate vector view edge selector. * * * This is the immediate version of the vector of edge ids edge * selector. * * \param v The vector of edge ids. * \return Edge selector, initialized. * \sa \ref igraph_es_vector() * * Time complexity: O(1). */ igraph_es_t igraph_ess_vector(const igraph_vector_t *v) { igraph_es_t es; es.type = IGRAPH_ES_VECTORPTR; es.data.vecptr = v; return es; } /** * \function igraph_es_fromto * \brief Edge selector, all edges between two vertex sets. * * * This function is not implemented yet. * * \param es Pointer to an uninitialized edge selector. * \param from Vertex selector, their outgoing edges will be * selected. * \param to Vertex selector, their incoming edges will be selected * from the previous selection. * \return Error code. * \sa \ref igraph_es_destroy() * * Time complexity: O(1). */ int igraph_es_fromto(igraph_es_t *es, igraph_vs_t from, igraph_vs_t to) { IGRAPH_UNUSED(es); IGRAPH_UNUSED(from); IGRAPH_UNUSED(to); IGRAPH_ERROR("igraph_es_fromto not implemented yet", IGRAPH_UNIMPLEMENTED); /* TODO */ } /** * \function igraph_es_seq * \brief Edge selector, a sequence of edge ids. * * All edge ids between from and to will be * included in the edge selection. This includes from and * excludes to. * * \param es Pointer to an uninitialized edge selector object. * \param from The first edge id to be included. * \param to The last edge id to be included. * \return Error code. * \sa \ref igraph_ess_seq(), \ref igraph_es_destroy() * * Time complexity: O(1). */ int igraph_es_seq(igraph_es_t *es, igraph_integer_t from, igraph_integer_t to) { es->type = IGRAPH_ES_SEQ; es->data.seq.from = from; es->data.seq.to = to; return 0; } /** * \function igraph_ess_seq * \brief Immediate version of the sequence edge selector. * * \param from The first edge id to include. * \param to The last edge id to include. * \return The initialized edge selector. * \sa \ref igraph_es_seq() * * Time complexity: O(1). */ igraph_es_t igraph_ess_seq(igraph_integer_t from, igraph_integer_t to) { igraph_es_t es; es.type = IGRAPH_ES_SEQ; es.data.seq.from = from; es.data.seq.to = to; return es; } /** * \function igraph_es_pairs * \brief Edge selector, multiple edges defined by their endpoints in a vector. * * The edges between the given pairs of vertices will be included in the * edge selection. The vertex pairs must be defined in the vector v, * the first element of the vector is the first vertex of the first edge * to be selected, the second element is the second vertex of the first * edge, the third element is the first vertex of the second edge and * so on. * * \param es Pointer to an uninitialized edge selector object. * \param v The vector containing the endpoints of the edges. * \param directed Whether the graph is directed or not. * \return Error code. * \sa \ref igraph_es_pairs_small(), \ref igraph_es_destroy() * * Time complexity: O(n), the number of edges being selected. * * \example examples/simple/igraph_es_pairs.c */ int igraph_es_pairs(igraph_es_t *es, const igraph_vector_t *v, igraph_bool_t directed) { es->type = IGRAPH_ES_PAIRS; es->data.path.mode = directed; es->data.path.ptr = IGRAPH_CALLOC(1, igraph_vector_t); if (es->data.path.ptr == 0) { IGRAPH_ERROR("Cannot create edge selector", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*) es->data.path.ptr); IGRAPH_CHECK(igraph_vector_copy((igraph_vector_t*) es->data.path.ptr, v)); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_es_pairs_small * \brief Edge selector, multiple edges defined by their endpoints as arguments. * * The edges between the given pairs of vertices will be included in the * edge selection. The vertex pairs must be given as the arguments of the * function call, the third argument is the first vertex of the first edge, * the fourth argument is the second vertex of the first edge, the fifth * is the first vertex of the second edge and so on. The last element of the * argument list must be -1 to denote the end of the argument list. * * \param es Pointer to an uninitialized edge selector object. * \param directed Whether the graph is directed or not. * \return Error code. * \sa \ref igraph_es_pairs(), \ref igraph_es_destroy() * * Time complexity: O(n), the number of edges being selected. */ int igraph_es_pairs_small(igraph_es_t *es, igraph_bool_t directed, ...) { va_list ap; long int i, n = 0; es->type = IGRAPH_ES_PAIRS; es->data.path.mode = directed; es->data.path.ptr = IGRAPH_CALLOC(1, igraph_vector_t); if (es->data.path.ptr == 0) { IGRAPH_ERROR("Cannot create edge selector", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*)es->data.path.ptr); va_start(ap, directed); while (1) { int num = va_arg(ap, int); if (num == -1) { break; } n++; } va_end(ap); IGRAPH_VECTOR_INIT_FINALLY( (igraph_vector_t*) es->data.path.ptr, n); va_start(ap, directed); for (i = 0; i < n; i++) { VECTOR(*es->data.path.ptr)[i] = (igraph_real_t) va_arg(ap, int); } va_end(ap); IGRAPH_FINALLY_CLEAN(2); return 0; } int igraph_es_multipairs(igraph_es_t *es, const igraph_vector_t *v, igraph_bool_t directed) { es->type = IGRAPH_ES_MULTIPAIRS; es->data.path.mode = directed; es->data.path.ptr = IGRAPH_CALLOC(1, igraph_vector_t); if (es->data.path.ptr == 0) { IGRAPH_ERROR("Cannot create edge selector", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*) es->data.path.ptr); IGRAPH_CHECK(igraph_vector_copy((igraph_vector_t*) es->data.path.ptr, v)); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_es_path * \brief Edge selector, edge ids on a path. * * This function takes a vector of vertices and creates a selector of * edges between those vertices. Vector {0, 3, 4, 7} will select edges * (0 -> 3), (3 -> 4), (4 -> 7). If these edges don't exist then trying * to create an iterator using this selector will fail. * * \param es Pointer to an uninitialized edge selector object. * \param v Pointer to a vector of vertex id's along the path. * \param directed If edge directions should be taken into account. This * will be ignored if the graph to select from is undirected. * \return Error code. * \sa \ref igraph_es_destroy() * * Time complexity: O(n), the number of vertices. */ int igraph_es_path(igraph_es_t *es, const igraph_vector_t *v, igraph_bool_t directed) { es->type = IGRAPH_ES_PATH; es->data.path.mode = directed; es->data.path.ptr = IGRAPH_CALLOC(1, igraph_vector_t); if (es->data.path.ptr == 0) { IGRAPH_ERROR("Cannot create edge selector", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*) es->data.path.ptr); IGRAPH_CHECK(igraph_vector_copy((igraph_vector_t*) es->data.path.ptr, v)); IGRAPH_FINALLY_CLEAN(1); return 0; } int igraph_es_path_small(igraph_es_t *es, igraph_bool_t directed, ...) { va_list ap; long int i, n = 0; es->type = IGRAPH_ES_PATH; es->data.path.mode = directed; es->data.path.ptr = IGRAPH_CALLOC(1, igraph_vector_t); if (es->data.path.ptr == 0) { IGRAPH_ERROR("Cannot create edge selector", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*)es->data.path.ptr); va_start(ap, directed); while (1) { int num = va_arg(ap, int); if (num == -1) { break; } n++; } va_end(ap); IGRAPH_VECTOR_INIT_FINALLY( (igraph_vector_t*) es->data.path.ptr, n); va_start(ap, directed); for (i = 0; i < n; i++) { VECTOR(*es->data.path.ptr)[i] = (igraph_real_t) va_arg(ap, int); } va_end(ap); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_es_destroy * \brief Destroys an edge selector object. * * * Call this function on an edge selector when it is not needed any * more. Do \em not call this function on edge selectors created by * immediate constructors, those don't need to be destroyed. * * \param es Pointer to an edge selector object. * * Time complexity: operating system dependent, usually O(1). */ void igraph_es_destroy(igraph_es_t *es) { switch (es->type) { case IGRAPH_ES_ALL: case IGRAPH_ES_ALLFROM: case IGRAPH_ES_ALLTO: case IGRAPH_ES_INCIDENT: case IGRAPH_ES_NONE: case IGRAPH_ES_1: case IGRAPH_ES_VECTORPTR: case IGRAPH_ES_SEQ: break; case IGRAPH_ES_VECTOR: igraph_vector_destroy((igraph_vector_t*)es->data.vecptr); IGRAPH_FREE(es->data.vecptr); break; case IGRAPH_ES_PAIRS: case IGRAPH_ES_PATH: case IGRAPH_ES_MULTIPAIRS: igraph_vector_destroy((igraph_vector_t*)es->data.path.ptr); IGRAPH_FREE(es->data.path.ptr); break; default: break; } } /** * \function igraph_es_is_all * \brief Check whether an edge selector includes all edges. * * \param es Pointer to an edge selector object. * \return TRUE (1) if es was created with \ref * igraph_es_all() or \ref igraph_ess_all(), and FALSE (0) otherwise. * * Time complexity: O(1). */ igraph_bool_t igraph_es_is_all(const igraph_es_t *es) { return es->type == IGRAPH_ES_ALL; } /** * \function igraph_es_copy * \brief Creates a copy of an edge selector. * \param src The selector being copied. * \param dest An uninitialized selector that will contain the copy. * \sa \ref igraph_es_destroy() */ int igraph_es_copy(igraph_es_t* dest, const igraph_es_t* src) { memcpy(dest, src, sizeof(igraph_es_t)); switch (dest->type) { case IGRAPH_ES_VECTOR: dest->data.vecptr = IGRAPH_CALLOC(1, igraph_vector_t); if (!dest->data.vecptr) { IGRAPH_ERROR("Cannot copy edge selector", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_copy((igraph_vector_t*)dest->data.vecptr, (igraph_vector_t*)src->data.vecptr)); break; case IGRAPH_ES_PATH: case IGRAPH_ES_PAIRS: case IGRAPH_ES_MULTIPAIRS: dest->data.path.ptr = IGRAPH_CALLOC(1, igraph_vector_t); if (!dest->data.path.ptr) { IGRAPH_ERROR("Cannot copy edge selector", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_copy((igraph_vector_t*)dest->data.path.ptr, (igraph_vector_t*)src->data.path.ptr)); break; } return 0; } /** * \function igraph_es_as_vector * \brief Transform edge selector into vector. * * * Call this function on an edge selector to transform it into a vector. * This is only implemented for sequence and vector selectors. If the * edges do not exist in the graph, this will result in an error. * * \param graph Pointer to a graph to check if the edges in the selector exist. * \param es An edge selector object. * \param v Pointer to initialized vector. The result will be stored here. * * Time complexity: O(n), the number of edges in the selector. */ int igraph_es_as_vector(const igraph_t *graph, igraph_es_t es, igraph_vector_t *v) { igraph_eit_t eit; IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); IGRAPH_CHECK(igraph_eit_as_vector(&eit, v)); igraph_eit_destroy(&eit); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_es_type * \brief Returns the type of the edge selector. */ int igraph_es_type(const igraph_es_t *es) { return es->type; } static int igraph_i_es_pairs_size(const igraph_t *graph, const igraph_es_t *es, igraph_integer_t *result); static int igraph_i_es_path_size(const igraph_t *graph, const igraph_es_t *es, igraph_integer_t *result); static int igraph_i_es_multipairs_size(const igraph_t *graph, const igraph_es_t *es, igraph_integer_t *result); /** * \function igraph_es_size * \brief Returns the size of the edge selector. * * The size of the edge selector is the number of edges it will * yield when it is iterated over. * * \param graph The graph over which we will iterate. * \param result The result will be returned here. */ int igraph_es_size(const igraph_t *graph, const igraph_es_t *es, igraph_integer_t *result) { igraph_vector_t v; switch (es->type) { case IGRAPH_ES_ALL: *result = igraph_ecount(graph); return 0; case IGRAPH_ES_ALLFROM: *result = igraph_ecount(graph); return 0; case IGRAPH_ES_ALLTO: *result = igraph_ecount(graph); return 0; case IGRAPH_ES_INCIDENT: IGRAPH_VECTOR_INIT_FINALLY(&v, 0); IGRAPH_CHECK(igraph_incident(graph, &v, es->data.incident.vid, es->data.incident.mode)); *result = (igraph_integer_t) igraph_vector_size(&v); igraph_vector_destroy(&v); IGRAPH_FINALLY_CLEAN(1); return 0; case IGRAPH_ES_NONE: *result = 0; return 0; case IGRAPH_ES_1: if (es->data.eid < igraph_ecount(graph) && es->data.eid >= 0) { *result = 1; } else { *result = 0; } return 0; case IGRAPH_ES_VECTOR: case IGRAPH_ES_VECTORPTR: *result = (igraph_integer_t) igraph_vector_size((igraph_vector_t*)es->data.vecptr); return 0; case IGRAPH_ES_SEQ: *result = es->data.seq.to - es->data.seq.from; return 0; case IGRAPH_ES_PAIRS: IGRAPH_CHECK(igraph_i_es_pairs_size(graph, es, result)); return 0; case IGRAPH_ES_PATH: IGRAPH_CHECK(igraph_i_es_path_size(graph, es, result)); return 0; case IGRAPH_ES_MULTIPAIRS: IGRAPH_CHECK(igraph_i_es_multipairs_size(graph, es, result)); return 0; default: IGRAPH_ERROR("Cannot calculate selector length, invalid selector type", IGRAPH_EINVAL); } } static int igraph_i_es_pairs_size(const igraph_t *graph, const igraph_es_t *es, igraph_integer_t *result) { long int n = igraph_vector_size(es->data.path.ptr); long int no_of_nodes = igraph_vcount(graph); long int i; if (n % 2 != 0) { IGRAPH_ERROR("Cannot calculate edge selector length from odd number of vertices", IGRAPH_EINVAL); } if (!igraph_vector_isininterval(es->data.path.ptr, 0, no_of_nodes - 1)) { IGRAPH_ERROR("Cannot calculate edge selector length", IGRAPH_EINVVID); } *result = (igraph_integer_t) (n / 2); /* Check for the existence of all edges */ for (i = 0; i < *result; i++) { long int from = (long int) VECTOR(*es->data.path.ptr)[2 * i]; long int to = (long int) VECTOR(*es->data.path.ptr)[2 * i + 1]; igraph_integer_t eid; IGRAPH_CHECK(igraph_get_eid(graph, &eid, (igraph_integer_t) from, (igraph_integer_t) to, es->data.path.mode, /*error=*/ 1)); } return 0; } static int igraph_i_es_path_size(const igraph_t *graph, const igraph_es_t *es, igraph_integer_t *result) { long int n = igraph_vector_size(es->data.path.ptr); long int no_of_nodes = igraph_vcount(graph); long int i; if (!igraph_vector_isininterval(es->data.path.ptr, 0, no_of_nodes - 1)) { IGRAPH_ERROR("Cannot calculate selector length", IGRAPH_EINVVID); } if (n <= 1) { *result = 0; } else { *result = (igraph_integer_t) (n - 1); } for (i = 0; i < *result; i++) { long int from = (long int) VECTOR(*es->data.path.ptr)[i]; long int to = (long int) VECTOR(*es->data.path.ptr)[i + 1]; igraph_integer_t eid; IGRAPH_CHECK(igraph_get_eid(graph, &eid, (igraph_integer_t) from, (igraph_integer_t) to, es->data.path.mode, /*error=*/ 1)); } return 0; } static int igraph_i_es_multipairs_size(const igraph_t *graph, const igraph_es_t *es, igraph_integer_t *result) { IGRAPH_UNUSED(graph); IGRAPH_UNUSED(es); IGRAPH_UNUSED(result); IGRAPH_ERROR("Cannot calculate edge selector length", IGRAPH_UNIMPLEMENTED); } /**************************************************/ static int igraph_i_eit_create_allfromto(const igraph_t *graph, igraph_eit_t *eit, igraph_neimode_t mode); static int igraph_i_eit_pairs(const igraph_t *graph, igraph_es_t es, igraph_eit_t *eit); static int igraph_i_eit_multipairs(const igraph_t *graph, igraph_es_t es, igraph_eit_t *eit); static int igraph_i_eit_path(const igraph_t *graph, igraph_es_t es, igraph_eit_t *eit); static int igraph_i_eit_create_allfromto(const igraph_t *graph, igraph_eit_t *eit, igraph_neimode_t mode) { igraph_vector_t *vec; long int no_of_nodes = igraph_vcount(graph); long int no_of_edges = igraph_ecount(graph); long int i; vec = IGRAPH_CALLOC(1, igraph_vector_t); if (vec == 0) { IGRAPH_ERROR("Cannot create edge iterator", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, vec); IGRAPH_VECTOR_INIT_FINALLY(vec, 0); IGRAPH_CHECK(igraph_vector_reserve(vec, no_of_edges)); if (igraph_is_directed(graph)) { igraph_vector_t adj; IGRAPH_VECTOR_INIT_FINALLY(&adj, 0); for (i = 0; i < no_of_nodes; i++) { igraph_incident(graph, &adj, (igraph_integer_t) i, mode); igraph_vector_append(vec, &adj); } igraph_vector_destroy(&adj); IGRAPH_FINALLY_CLEAN(1); } else { igraph_vector_t adj; igraph_bool_t *added; long int j; IGRAPH_VECTOR_INIT_FINALLY(&adj, 0); added = IGRAPH_CALLOC(no_of_edges, igraph_bool_t); if (added == 0) { IGRAPH_ERROR("Cannot create edge iterator", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); for (i = 0; i < no_of_nodes; i++) { igraph_incident(graph, &adj, (igraph_integer_t) i, IGRAPH_ALL); for (j = 0; j < igraph_vector_size(&adj); j++) { if (!added[ (long int)VECTOR(adj)[j] ]) { igraph_vector_push_back(vec, VECTOR(adj)[j]); added[ (long int)VECTOR(adj)[j] ] += 1; } } } igraph_vector_destroy(&adj); IGRAPH_FREE(added); IGRAPH_FINALLY_CLEAN(2); } eit->type = IGRAPH_EIT_VECTOR; eit->pos = 0; eit->start = 0; eit->vec = vec; eit->end = igraph_vector_size(eit->vec); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_eit_pairs(const igraph_t *graph, igraph_es_t es, igraph_eit_t *eit) { long int n = igraph_vector_size(es.data.path.ptr); long int no_of_nodes = igraph_vcount(graph); long int i; if (n % 2 != 0) { IGRAPH_ERROR("Cannot create edge iterator from odd number of vertices", IGRAPH_EINVAL); } if (!igraph_vector_isininterval(es.data.path.ptr, 0, no_of_nodes - 1)) { IGRAPH_ERROR("Cannot create edge iterator", IGRAPH_EINVVID); } eit->type = IGRAPH_EIT_VECTOR; eit->pos = 0; eit->start = 0; eit->end = n / 2; eit->vec = IGRAPH_CALLOC(1, igraph_vector_t); if (eit->vec == 0) { IGRAPH_ERROR("Cannot create edge iterator", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*)eit->vec); IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t*)eit->vec, n / 2); for (i = 0; i < igraph_vector_size(eit->vec); i++) { long int from = (long int) VECTOR(*es.data.path.ptr)[2 * i]; long int to = (long int) VECTOR(*es.data.path.ptr)[2 * i + 1]; igraph_integer_t eid; IGRAPH_CHECK(igraph_get_eid(graph, &eid, (igraph_integer_t) from, (igraph_integer_t) to, es.data.path.mode, /*error=*/ 1)); VECTOR(*eit->vec)[i] = eid; } IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_eit_multipairs(const igraph_t *graph, igraph_es_t es, igraph_eit_t *eit) { long int n = igraph_vector_size(es.data.path.ptr); long int no_of_nodes = igraph_vcount(graph); if (n % 2 != 0) { IGRAPH_ERROR("Cannot create edge iterator from odd number of vertices", IGRAPH_EINVAL); } if (!igraph_vector_isininterval(es.data.path.ptr, 0, no_of_nodes - 1)) { IGRAPH_ERROR("Cannot create edge iterator", IGRAPH_EINVVID); } eit->type = IGRAPH_EIT_VECTOR; eit->pos = 0; eit->start = 0; eit->end = n / 2; eit->vec = IGRAPH_CALLOC(1, igraph_vector_t); if (eit->vec == 0) { IGRAPH_ERROR("Cannot create edge iterator", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*)eit->vec); IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t*)eit->vec, n / 2); IGRAPH_CHECK(igraph_get_eids_multi(graph, (igraph_vector_t *) eit->vec, /*pairs=*/ es.data.path.ptr, /*path=*/ 0, es.data.path.mode, /*error=*/ 1)); IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_eit_path(const igraph_t *graph, igraph_es_t es, igraph_eit_t *eit) { long int n = igraph_vector_size(es.data.path.ptr); long int no_of_nodes = igraph_vcount(graph); long int i, len; if (!igraph_vector_isininterval(es.data.path.ptr, 0, no_of_nodes - 1)) { IGRAPH_ERROR("Cannot create edge iterator.", IGRAPH_EINVVID); } if (n <= 1) { len = 0; } else { len = n - 1; } eit->type = IGRAPH_EIT_VECTOR; eit->pos = 0; eit->start = 0; eit->end = len; eit->vec = IGRAPH_CALLOC(1, igraph_vector_t); if (eit->vec == 0) { IGRAPH_ERROR("Cannot create edge iterator.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*)eit->vec); IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t *)eit->vec, len); for (i = 0; i < len; i++) { long int from = (long int) VECTOR(*es.data.path.ptr)[i]; long int to = (long int) VECTOR(*es.data.path.ptr)[i + 1]; igraph_integer_t eid; IGRAPH_CHECK(igraph_get_eid(graph, &eid, (igraph_integer_t) from, (igraph_integer_t) to, es.data.path.mode, /*error=*/ 1)); VECTOR(*eit->vec)[i] = eid; } IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_eit_create * \brief Creates an edge iterator from an edge selector. * * * This function creates an edge iterator based on an edge selector * and a graph. * * * The same edge selector can be used to create many edge iterators, * also for different graphs. * * \param graph An \type igraph_t object for which the edge selector * will be instantiated. * \param es The edge selector to instantiate. * \param eit Pointer to an uninitialized edge iterator. * \return Error code. * \sa \ref igraph_eit_destroy() * * Time complexity: depends on the type of the edge selector. For edge * selectors created by \ref igraph_es_all(), \ref igraph_es_none(), * \ref igraph_es_1(), igraph_es_vector(), igraph_es_seq() it is * O(1). For \ref igraph_es_incident() it is O(d) where d is the number of * incident edges of the vertex. */ int igraph_eit_create(const igraph_t *graph, igraph_es_t es, igraph_eit_t *eit) { switch (es.type) { case IGRAPH_ES_ALL: eit->type = IGRAPH_EIT_SEQ; eit->pos = 0; eit->start = 0; eit->end = igraph_ecount(graph); break; case IGRAPH_ES_ALLFROM: IGRAPH_CHECK(igraph_i_eit_create_allfromto(graph, eit, IGRAPH_OUT)); break; case IGRAPH_ES_ALLTO: IGRAPH_CHECK(igraph_i_eit_create_allfromto(graph, eit, IGRAPH_IN)); break; case IGRAPH_ES_INCIDENT: eit->type = IGRAPH_EIT_VECTOR; eit->pos = 0; eit->start = 0; eit->vec = IGRAPH_CALLOC(1, igraph_vector_t); if (eit->vec == 0) { IGRAPH_ERROR("Cannot create iterator.", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (igraph_vector_t*) eit->vec); IGRAPH_VECTOR_INIT_FINALLY((igraph_vector_t*)eit->vec, 0); IGRAPH_CHECK(igraph_incident(graph, (igraph_vector_t*)eit->vec, es.data.incident.vid, es.data.incident.mode)); eit->end = igraph_vector_size(eit->vec); IGRAPH_FINALLY_CLEAN(2); break; case IGRAPH_ES_NONE: eit->type = IGRAPH_EIT_SEQ; eit->pos = 0; eit->start = 0; eit->end = 0; break; case IGRAPH_ES_1: eit->type = IGRAPH_EIT_SEQ; eit->pos = es.data.eid; eit->start = es.data.eid; eit->end = es.data.eid + 1; if (eit->pos >= igraph_ecount(graph)) { IGRAPH_ERROR("Cannot create iterator, invalid edge id.", IGRAPH_EINVAL); } break; case IGRAPH_ES_VECTOR: case IGRAPH_ES_VECTORPTR: eit->type = IGRAPH_EIT_VECTORPTR; eit->pos = 0; eit->start = 0; eit->vec = es.data.vecptr; eit->end = igraph_vector_size(eit->vec); if (!igraph_vector_isininterval(eit->vec, 0, igraph_ecount(graph) - 1)) { IGRAPH_ERROR("Cannot create iterator, invalid edge id.", IGRAPH_EINVAL); } break; case IGRAPH_ES_SEQ: eit->type = IGRAPH_EIT_SEQ; eit->pos = es.data.seq.from; eit->start = es.data.seq.from; eit->end = es.data.seq.to; if (eit->start < 0) { IGRAPH_ERROR("Cannot create iterator, invalid edge id.", IGRAPH_EINVAL); } if (eit->end < 0) { IGRAPH_ERROR("Cannot create iterator, invalid edge id.", IGRAPH_EINVAL); } if (eit->start >= igraph_ecount(graph)) { IGRAPH_ERROR("Cannot create iterator, starting edge greater than number of edges.", IGRAPH_EINVAL); } break; case IGRAPH_ES_PAIRS: IGRAPH_CHECK(igraph_i_eit_pairs(graph, es, eit)); break; case IGRAPH_ES_MULTIPAIRS: IGRAPH_CHECK(igraph_i_eit_multipairs(graph, es, eit)); break; case IGRAPH_ES_PATH: IGRAPH_CHECK(igraph_i_eit_path(graph, es, eit)); break; default: IGRAPH_ERROR("Cannot create iterator, invalid selector.", IGRAPH_EINVAL); break; } return 0; } /** * \function igraph_eit_destroy * \brief Destroys an edge iterator. * * \param eit Pointer to an edge iterator to destroy. * \sa \ref igraph_eit_create() * * Time complexity: operating system dependent, usually O(1). */ void igraph_eit_destroy(const igraph_eit_t *eit) { switch (eit->type) { case IGRAPH_EIT_SEQ: case IGRAPH_EIT_VECTORPTR: break; case IGRAPH_EIT_VECTOR: igraph_vector_destroy((igraph_vector_t*)eit->vec); igraph_free((igraph_vector_t*)eit->vec); break; default: /* IGRAPH_ERROR("Cannot destroy iterator, unknown type", IGRAPH_EINVAL); */ break; } } int igraph_eit_as_vector(const igraph_eit_t *eit, igraph_vector_t *v) { long int i; IGRAPH_CHECK(igraph_vector_resize(v, IGRAPH_EIT_SIZE(*eit))); switch (eit->type) { case IGRAPH_EIT_SEQ: for (i = 0; i < IGRAPH_EIT_SIZE(*eit); i++) { VECTOR(*v)[i] = eit->start + i; } break; case IGRAPH_EIT_VECTOR: case IGRAPH_EIT_VECTORPTR: for (i = 0; i < IGRAPH_EIT_SIZE(*eit); i++) { VECTOR(*v)[i] = VECTOR(*eit->vec)[i]; } break; default: IGRAPH_ERROR("Cannot convert to vector, unknown iterator type", IGRAPH_EINVAL); break; } return 0; } leidenbase/src/core/graph/attributes.h0000644000176200001440000001340514447675374017554 0ustar liggesusers/* IGraph library. Copyright (C) 2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IGRAPH_GRAPH_ATTRIBUTES_H #define IGRAPH_GRAPH_ATTRIBUTES_H #include "igraph_attributes.h" #include "igraph_strvector.h" #include "igraph_types.h" #include "igraph_vector_ptr.h" #define IGRAPH_I_ATTRIBUTE_DESTROY(graph) \ do {if ((graph)->attr) igraph_i_attribute_destroy(graph);} while(0) #define IGRAPH_I_ATTRIBUTE_COPY(to,from,ga,va,ea) do { \ int igraph_i_ret2=0; \ if ((from)->attr) { \ IGRAPH_CHECK(igraph_i_ret2=igraph_i_attribute_copy((to),(from),(ga),(va),(ea))); \ } else { \ (to)->attr = 0; \ } \ if (igraph_i_ret2 != 0) { \ IGRAPH_ERROR("", igraph_i_ret2); \ } \ } while(0) int igraph_i_attribute_init(igraph_t *graph, void *attr); void igraph_i_attribute_destroy(igraph_t *graph); int igraph_i_attribute_copy(igraph_t *to, const igraph_t *from, igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea); int igraph_i_attribute_add_vertices(igraph_t *graph, long int nv, void *attr); int igraph_i_attribute_permute_vertices(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_t *idx); int igraph_i_attribute_combine_vertices(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_ptr_t *merges, const igraph_attribute_combination_t *comb); int igraph_i_attribute_add_edges(igraph_t *graph, const igraph_vector_t *edges, void *attr); int igraph_i_attribute_permute_edges(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_t *idx); int igraph_i_attribute_combine_edges(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_ptr_t *merges, const igraph_attribute_combination_t *comb); int igraph_i_attribute_get_info(const igraph_t *graph, igraph_strvector_t *gnames, igraph_vector_t *gtypes, igraph_strvector_t *vnames, igraph_vector_t *vtypes, igraph_strvector_t *enames, igraph_vector_t *etypes); igraph_bool_t igraph_i_attribute_has_attr(const igraph_t *graph, igraph_attribute_elemtype_t type, const char *name); int igraph_i_attribute_gettype(const igraph_t *graph, igraph_attribute_type_t *type, igraph_attribute_elemtype_t elemtype, const char *name); int igraph_i_attribute_get_numeric_graph_attr(const igraph_t *graph, const char *name, igraph_vector_t *value); int igraph_i_attribute_get_numeric_vertex_attr(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_vector_t *value); int igraph_i_attribute_get_numeric_edge_attr(const igraph_t *graph, const char *name, igraph_es_t es, igraph_vector_t *value); int igraph_i_attribute_get_string_graph_attr(const igraph_t *graph, const char *name, igraph_strvector_t *value); int igraph_i_attribute_get_string_vertex_attr(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_strvector_t *value); int igraph_i_attribute_get_string_edge_attr(const igraph_t *graph, const char *name, igraph_es_t es, igraph_strvector_t *value); int igraph_i_attribute_get_bool_graph_attr(const igraph_t *graph, const char *name, igraph_vector_bool_t *value); int igraph_i_attribute_get_bool_vertex_attr(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_vector_bool_t *value); int igraph_i_attribute_get_bool_edge_attr(const igraph_t *graph, const char *name, igraph_es_t es, igraph_vector_bool_t *value); #endif /* IGRAPH_GRAPH_ATTRIBUTES_H */ leidenbase/src/core/graph/basic_query.c0000644000176200001440000000407014447675374017665 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_datatype.h" #include "igraph_types.h" #include "igraph_interface.h" #include "igraph_structural.h" /** * \ingroup structural * \function igraph_are_connected * \brief Decides whether two vertices are connected * * \param graph The graph object. * \param v1 The first vertex. * \param v2 The second vertex. * \param res Boolean, \c TRUE if there is an edge from * \p v1 to \p v2, \c FALSE otherwise. * \return The error code \c IGRAPH_EINVVID is returned if an invalid * vertex ID is given. * * The function is of course symmetric for undirected graphs. * * * Time complexity: O( min(log(d1), log(d2)) ), * d1 is the (out-)degree of \p v1 and d2 is the (in-)degree of \p v2. */ int igraph_are_connected(const igraph_t *graph, igraph_integer_t v1, igraph_integer_t v2, igraph_bool_t *res) { long int nov = igraph_vcount(graph); igraph_integer_t eid = -1; if (v1 < 0 || v2 < 0 || v1 > nov - 1 || v2 > nov - 1) { IGRAPH_ERROR("are connected", IGRAPH_EINVVID); } igraph_get_eid(graph, &eid, v1, v2, /*directed=*/1, /*error=*/ 0); *res = (eid >= 0); return IGRAPH_SUCCESS; } leidenbase/src/core/graph/adjlist.c0000644000176200001440000011565314447675374017023 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2003-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_adjlist.h" #include "igraph_memory.h" #include "igraph_interface.h" #include "core/interruption.h" #include /* memset */ #include /** * Helper function that simplifies a sorted adjacency vector by removing * duplicate elements and optionally self-loops. */ static int igraph_i_simplify_sorted_int_adjacency_vector_in_place( igraph_vector_int_t *v, igraph_integer_t index, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple ); /** * Helper function that removes loops from an incidence vector (either both * occurrences or only one of them). */ static int igraph_i_remove_loops_from_incidence_vector_in_place( igraph_vector_int_t *v, const igraph_t *graph, igraph_loops_t loops ); /** * \section about_adjlists * * Sometimes it is easier to work with a graph which is in * adjacency list format: a list of vectors; each vector contains the * neighbor vertices or incident edges of a given vertex. Typically, * this representation is good if we need to iterate over the neighbors * of all vertices many times. E.g. when finding the shortest paths * between all pairs of vertices or calculating closeness centrality * for all the vertices. * * The igraph_adjlist_t stores the adjacency lists * of a graph. After creation it is independent of the original graph, * it can be modified freely with the usual vector operations, the * graph is not affected. E.g. the adjacency list can be used to * rewire the edges of a graph efficiently. If one used the * straightforward \ref igraph_delete_edges() and \ref * igraph_add_edges() combination for this that needs O(|V|+|E|) time * for every single deletion and insertion operation, it is thus very * slow if many edges are rewired. Extracting the graph into an * adjacency list, do all the rewiring operations on the vectors of * the adjacency list and then creating a new graph needs (depending * on how exactly the rewiring is done) typically O(|V|+|E|) time for * the whole rewiring process. * * Lazy adjacency lists are a bit different. When creating a * lazy adjacency list, the neighbors of the vertices are not queried, * only some memory is allocated for the vectors. When \ref * igraph_lazy_adjlist_get() is called for vertex v the first time, * the neighbors of v are queried and stored in a vector of the * adjacency list, so they don't need to be queried again. Lazy * adjacency lists are handy if you have an at least linear operation * (because initialization is generally linear in terms of the number of * vertices), but you don't know how many vertices you will visit * during the computation. * * * * \example examples/simple/adjlist.c * */ /** * \function igraph_adjlist_init * \brief Constructs an adjacency list of vertices from a given graph. * * Creates a list of vectors containing the neighbors of all vertices * in a graph. The adjacency list is independent of the graph after * creation, e.g. the graph can be destroyed and modified, the * adjacency list contains the state of the graph at the time of its * initialization. * * \param graph The input graph. * \param al Pointer to an uninitialized igraph_adjlist_t object. * \param mode Constant specifying whether outgoing * (IGRAPH_OUT), incoming (IGRAPH_IN), * or both (IGRAPH_ALL) types of neighbors to include * in the adjacency list. It is ignored for undirected networks. * \param loops Specifies how to treat loop edges. IGRAPH_NO_LOOPS * removes loop edges from the adjacency list. IGRAPH_LOOPS_ONCE * makes each loop edge appear only once in the adjacency list of the * corresponding vertex. IGRAPH_LOOPS_TWICE makes loop edges * appear \em twice in the adjacency list of the corresponding vertex, * but only if the graph is undirected or mode is set to * IGRAPH_ALL. * \param multiple Specifies how to treat multiple (parallel) edges. * IGRAPH_NO_MULTIPLE collapses parallel edges into a single one; * IGRAPH_MULTIPLE keeps the multiplicities of parallel edges * so the same vertex will appear as many times in the adjacency list of * another vertex as the number of parallel edges going between the two * vertices. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. */ int igraph_adjlist_init(const igraph_t *graph, igraph_adjlist_t *al, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple) { igraph_integer_t i; igraph_vector_t tmp; int j, n; if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) { IGRAPH_ERROR("Cannot create adjacency list view", IGRAPH_EINVMODE); } igraph_vector_init(&tmp, 0); IGRAPH_FINALLY(igraph_vector_destroy, &tmp); if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } al->length = igraph_vcount(graph); al->adjs = IGRAPH_CALLOC(al->length, igraph_vector_int_t); if (al->adjs == 0) { IGRAPH_ERROR("Cannot create adjacency list view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_adjlist_destroy, al); for (i = 0; i < al->length; i++) { IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_neighbors(graph, &tmp, i, mode)); n = igraph_vector_size(&tmp); IGRAPH_CHECK(igraph_vector_int_init(&al->adjs[i], n)); for (j = 0; j < n; j++) { VECTOR(al->adjs[i])[j] = VECTOR(tmp)[j]; } IGRAPH_CHECK(igraph_i_simplify_sorted_int_adjacency_vector_in_place( &al->adjs[i], i, mode, loops, multiple )); } igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_adjlist_init_empty * \brief Initializes an empty adjacency list. * * Creates a list of vectors, one for each vertex. This is useful when you * are \em constructing a graph using an adjacency list representation as * it does not require your graph to exist yet. * \param no_of_nodes The number of vertices * \param al Pointer to an uninitialized igraph_adjlist_t object. * \return Error code. * * Time complexity: O(|V|), linear in the number of vertices. */ int igraph_adjlist_init_empty(igraph_adjlist_t *al, igraph_integer_t no_of_nodes) { long int i; al->length = no_of_nodes; al->adjs = IGRAPH_CALLOC(al->length, igraph_vector_int_t); if (al->adjs == 0) { IGRAPH_ERROR("Cannot create adjlist view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_adjlist_destroy, al); for (i = 0; i < al->length; i++) { IGRAPH_CHECK(igraph_vector_int_init(&al->adjs[i], 0)); } IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_adjlist_init_complementer * \brief Adjacency lists for the complementer graph. * * This function creates adjacency lists for the complementer * of the input graph. In the complementer graph all edges are present * which are not present in the original graph. Multiple edges in the * input graph are ignored. * \param graph The input graph. * \param al Pointer to a not yet initialized adjacency list. * \param mode Constant specifying whether outgoing * (IGRAPH_OUT), incoming (IGRAPH_IN), * or both (IGRAPH_ALL) types of neighbors (in the * complementer graph) to include in the adjacency list. It is * ignored for undirected networks. * \param loops Whether to consider loop edges. * \return Error code. * * Time complexity: O(|V|^2+|E|), quadratic in the number of vertices. */ int igraph_adjlist_init_complementer(const igraph_t *graph, igraph_adjlist_t *al, igraph_neimode_t mode, igraph_bool_t loops) { igraph_integer_t i, j, k, n; igraph_bool_t* seen; igraph_vector_t vec; if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) { IGRAPH_ERROR("Cannot create complementer adjlist view", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } al->length = igraph_vcount(graph); al->adjs = IGRAPH_CALLOC(al->length, igraph_vector_int_t); if (al->adjs == 0) { IGRAPH_ERROR("Cannot create complementer adjlist view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_adjlist_destroy, al); n = al->length; seen = IGRAPH_CALLOC(n, igraph_bool_t); if (seen == 0) { IGRAPH_ERROR("Cannot create complementer adjlist view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, seen); IGRAPH_VECTOR_INIT_FINALLY(&vec, 0); for (i = 0; i < al->length; i++) { IGRAPH_ALLOW_INTERRUPTION(); igraph_neighbors(graph, &vec, i, mode); memset(seen, 0, sizeof(igraph_bool_t) * (unsigned) al->length); n = al->length; if (!loops) { seen[i] = 1; n--; } for (j = 0; j < igraph_vector_size(&vec); j++) { if (! seen [ (long int) VECTOR(vec)[j] ] ) { n--; seen[ (long int) VECTOR(vec)[j] ] = 1; } } IGRAPH_CHECK(igraph_vector_int_init(&al->adjs[i], n)); for (j = 0, k = 0; k < n; j++) { if (!seen[j]) { VECTOR(al->adjs[i])[k++] = j; } } } IGRAPH_FREE(seen); igraph_vector_destroy(&vec); IGRAPH_FINALLY_CLEAN(3); return 0; } /** * \function igraph_adjlist_destroy * \brief Deallocates an adjacency list. * * Free all memory allocated for an adjacency list. * \param al The adjacency list to destroy. * * Time complexity: depends on memory management. */ void igraph_adjlist_destroy(igraph_adjlist_t *al) { long int i; for (i = 0; i < al->length; i++) { igraph_vector_int_destroy(&al->adjs[i]); } IGRAPH_FREE(al->adjs); } /** * \function igraph_adjlist_clear * Removes all edges from an adjacency list. * * \param al The adjacency list. * Time complexity: depends on memory management, typically O(n), where n is * the total number of elements in the adjacency list. */ void igraph_adjlist_clear(igraph_adjlist_t *al) { long int i; for (i = 0; i < al->length; i++) { igraph_vector_int_clear(&al->adjs[i]); } } /** * \function igraph_adjlist_size * \brief Returns the number of vertices in an adjacency list. * * \param al The adjacency list. * \return The number of vertices in the adjacency list. * * Time complexity: O(1). */ igraph_integer_t igraph_adjlist_size(const igraph_adjlist_t *al) { return al->length; } /** * \function igraph_adjlist_sort * \brief Sorts each vector in an adjacency list. * * Sorts every vector of the adjacency list. * \param al The adjacency list. * * Time complexity: O(n log n), n is the total number of elements in * the adjacency list. */ void igraph_adjlist_sort(igraph_adjlist_t *al) { long int i; for (i = 0; i < al->length; i++) { igraph_vector_int_sort(&al->adjs[i]); } } /** * \function igraph_adjlist_simplify * \brief Simplifies an adjacency list. * * Simplifies an adjacency list, i.e. removes loop and multiple edges. * * \param al The adjacency list. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of edges and * vertices. */ int igraph_adjlist_simplify(igraph_adjlist_t *al) { long int i; long int n = al->length; igraph_vector_int_t mark; igraph_vector_int_init(&mark, n); IGRAPH_FINALLY(igraph_vector_int_destroy, &mark); for (i = 0; i < n; i++) { igraph_vector_int_t *v = &al->adjs[i]; long int j, l = igraph_vector_int_size(v); VECTOR(mark)[i] = i + 1; for (j = 0; j < l; /* nothing */) { long int e = (long int) VECTOR(*v)[j]; if (VECTOR(mark)[e] != i + 1) { VECTOR(mark)[e] = i + 1; j++; } else { VECTOR(*v)[j] = igraph_vector_int_tail(v); igraph_vector_int_pop_back(v); l--; } } } igraph_vector_int_destroy(&mark); IGRAPH_FINALLY_CLEAN(1); return 0; } int igraph_adjlist_remove_duplicate(const igraph_t *graph, igraph_adjlist_t *al) { long int i, j, l, n, p; igraph_vector_int_t *v; IGRAPH_WARNING( "igraph_adjlist_remove_duplicate() is deprecated; use the constructor " "arguments of igraph_adjlist_init() to specify whether you want loop " "edges to appear once or twice in the adjacency list." ); IGRAPH_UNUSED(graph); n = al->length; for (i = 0; i < n; i++) { v = &al->adjs[i]; l = igraph_vector_int_size(v); if (l > 0) { p = 1; for (j = 1; j < l; j++) { long int e = (long int) VECTOR(*v)[j]; /* Non-loop edges, and one end of loop edges are fine. */ /* We assume that the vector is sorted and we also keep it sorted */ if (e != i || VECTOR(*v)[j - 1] != e) { VECTOR(*v)[p++] = e; } } igraph_vector_int_resize(v, p); } } return 0; } #ifndef USING_R int igraph_adjlist_print(const igraph_adjlist_t *al) { long int i; long int n = al->length; for (i = 0; i < n; i++) { igraph_vector_int_t *v = &al->adjs[i]; igraph_vector_int_print(v); } return 0; } #endif int igraph_adjlist_fprint(const igraph_adjlist_t *al, FILE *outfile) { long int i; long int n = al->length; for (i = 0; i < n; i++) { igraph_vector_int_t *v = &al->adjs[i]; igraph_vector_int_fprint(v, outfile); } return 0; } #define ADJLIST_CANON_EDGE(from, to, directed) \ do { \ igraph_integer_t temp; \ if((!directed) && from < to) { \ temp = to; \ to = from; \ from = temp; \ } \ } while(0); igraph_bool_t igraph_adjlist_has_edge(igraph_adjlist_t* al, igraph_integer_t from, igraph_integer_t to, igraph_bool_t directed) { igraph_vector_int_t* fromvec; ADJLIST_CANON_EDGE(from, to, directed); fromvec = igraph_adjlist_get(al, from); return igraph_vector_int_binsearch2(fromvec, to); } int igraph_adjlist_replace_edge(igraph_adjlist_t* al, igraph_integer_t from, igraph_integer_t oldto, igraph_integer_t newto, igraph_bool_t directed) { igraph_vector_int_t *oldfromvec, *newfromvec; int err1, err2; long int oldpos, newpos; igraph_integer_t oldfrom = from, newfrom = from; ADJLIST_CANON_EDGE(oldfrom, oldto, directed); ADJLIST_CANON_EDGE(newfrom, newto, directed); oldfromvec = igraph_adjlist_get(al, oldfrom); newfromvec = igraph_adjlist_get(al, newfrom); err1 = igraph_vector_int_binsearch(oldfromvec, oldto, &oldpos); err2 = igraph_vector_int_binsearch(newfromvec, newto, &newpos); /* oldfrom -> oldto should exist; newfrom -> newto should not. */ if ((!err1) || err2) { return 1; } igraph_vector_int_remove(oldfromvec, oldpos); if (oldfromvec == newfromvec && oldpos < newpos) { --newpos; } IGRAPH_CHECK(igraph_vector_int_insert(newfromvec, newpos, newto)); return 0; } static int igraph_i_remove_loops_from_incidence_vector_in_place( igraph_vector_int_t *v, const igraph_t *graph, igraph_loops_t loops ) { long int i, length, eid, write_ptr; igraph_vector_int_t *seen_loops = 0; /* In this function we make use of the fact that we are dealing with * _incidence_ lists, and the only way for an edge ID to appear twice * within an incidence list is if the edge is a loop edge; otherwise each * element will be unique. * * Note that incidence vectors are not sorted by edge ID, so we need to * look up the edges in the graph to decide whether they are loops or not. * * Also, it may be tempting to introduce a boolean in case of IGRAPH_LOOPS_ONCE, * and flip it every time we see a loop to get rid of half of the occurrences, * but the problem is that even if the same loop edge ID appears twice in * the input list, they are not guaranteed to be next to each other; it * may be the case that there are multiple loop edges, each edge appears * twice, and we want to keep exactly one of them for each ID. That's why * we have a "seen_loops" vector. */ if (loops == IGRAPH_LOOPS_TWICE) { /* Loop edges appear twice by default, nothing to do. */ return IGRAPH_SUCCESS; } length = igraph_vector_int_size(v); if (length == 0) { return IGRAPH_SUCCESS; } if (loops == IGRAPH_LOOPS_ONCE) { /* We need a helper vector */ seen_loops = IGRAPH_CALLOC(1, igraph_vector_int_t); IGRAPH_FINALLY(igraph_free, seen_loops); IGRAPH_CHECK(igraph_vector_int_init(seen_loops, 0)); IGRAPH_FINALLY(igraph_vector_int_destroy, seen_loops); } else if (loops != IGRAPH_NO_LOOPS) { IGRAPH_ERROR("Invalid value for 'loops' argument", IGRAPH_EINVAL); } for (i = 0, write_ptr = 0; i < length; i++) { eid = VECTOR(*v)[i]; if (IGRAPH_FROM(graph, eid) == IGRAPH_TO(graph, eid)) { /* Loop edge */ if (seen_loops && !igraph_vector_int_contains(seen_loops, eid)) { VECTOR(*v)[write_ptr++] = eid; IGRAPH_CHECK(igraph_vector_int_push_back(seen_loops, eid)); } } else { /* Not a loop edge */ VECTOR(*v)[write_ptr++] = eid; } } /* Always succeeds since we never grow the vector */ igraph_vector_int_resize(v, write_ptr); /* Destroy the helper vector */ if (seen_loops) { igraph_vector_int_destroy(seen_loops); IGRAPH_FREE(seen_loops); IGRAPH_FINALLY_CLEAN(2); } return IGRAPH_SUCCESS; } int igraph_inclist_remove_duplicate(const igraph_t *graph, igraph_inclist_t *il) { long int i, n; IGRAPH_WARNING( "igraph_inclist_remove_duplicate() is deprecated; use the constructor " "arguments of igraph_inclist_init() to specify whether you want loop " "edges to appear once or twice in the incidence list." ); IGRAPH_UNUSED(graph); n = il->length; for (i = 0; i < n; i++) { IGRAPH_CHECK( igraph_i_remove_loops_from_incidence_vector_in_place( &il->incs[i], graph, IGRAPH_LOOPS_ONCE ) ); } return 0; } #ifndef USING_R int igraph_inclist_print(const igraph_inclist_t *al) { long int i; long int n = al->length; for (i = 0; i < n; i++) { igraph_vector_int_t *v = &al->incs[i]; igraph_vector_int_print(v); } return 0; } #endif int igraph_inclist_fprint(const igraph_inclist_t *al, FILE *outfile) { long int i; long int n = al->length; for (i = 0; i < n; i++) { igraph_vector_int_t *v = &al->incs[i]; igraph_vector_int_fprint(v, outfile); } return 0; } /** * \function igraph_inclist_init * \brief Initializes an incidence list. * * Creates a list of vectors containing the incident edges for all * vertices. The incidence list is independent of the graph after * creation, subsequent changes of the graph object do not update the * incidence list, and changes to the incidence list do not update the * graph. * * * When \p mode is \c IGRAPH_IN or \c IGRAPH_OUT, each edge ID will appear * in the incidence list \em once. When \p mode is \c IGRAPH_ALL, each edge ID * will appear in the incidence list \em twice, once for the source vertex * and once for the target edge. It also means that the edge IDs of loop edges * may potentially appear \em twice for the \em same vertex. Use the \p loops * argument to control whether this will be the case (\c IGRAPH_LOOPS_TWICE ) * or not (\c IGRAPH_LOOPS_ONCE or \c IGRAPH_NO_LOOPS). * * \param graph The input graph. * \param il Pointer to an uninitialized incidence list. * \param mode Constant specifying whether incoming edges * (IGRAPH_IN), outgoing edges (IGRAPH_OUT) or * both (IGRAPH_ALL) to include in the incidence lists * of directed graphs. It is ignored for undirected graphs. * \param loops Specifies how to treat loop edges. IGRAPH_NO_LOOPS * removes loop edges from the incidence list. IGRAPH_LOOPS_ONCE * makes each loop edge appear only once in the incidence list of the * corresponding vertex. IGRAPH_LOOPS_TWICE makes loop edges * appear \em twice in the incidence list of the corresponding vertex, * but only if the graph is undirected or mode is set to * IGRAPH_ALL. * \return Error code. * * Time complexity: O(|V|+|E|), linear in the number of vertices and * edges. */ int igraph_inclist_init(const igraph_t *graph, igraph_inclist_t *il, igraph_neimode_t mode, igraph_loops_t loops) { igraph_integer_t i; igraph_vector_t tmp; if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) { IGRAPH_ERROR("Cannot create incidence list view", IGRAPH_EINVMODE); } igraph_vector_init(&tmp, 0); IGRAPH_FINALLY(igraph_vector_destroy, &tmp); if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } il->length = igraph_vcount(graph); il->incs = IGRAPH_CALLOC(il->length, igraph_vector_int_t); if (il->incs == 0) { IGRAPH_ERROR("Cannot create incidence list view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_inclist_destroy, il); for (i = 0; i < il->length; i++) { int j, n; IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_incident(graph, &tmp, i, mode)); n = igraph_vector_size(&tmp); IGRAPH_CHECK(igraph_vector_int_init(&il->incs[i], n)); for (j = 0; j < n; j++) { VECTOR(il->incs[i])[j] = VECTOR(tmp)[j]; } if (loops != IGRAPH_LOOPS_TWICE) { IGRAPH_CHECK( igraph_i_remove_loops_from_incidence_vector_in_place(&il->incs[i], graph, loops) ); } } igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(2); return 0; } /** * \function igraph_inclist_init_empty * \brief Initializes an incidence list corresponding to an empty graph. * * This function essentially creates a list of empty vectors that may * be treated as an incidence list for a graph with a given number of * vertices. * * \param il Pointer to an uninitialized incidence list. * \param n The number of vertices in the incidence list. * \return Error code. * * Time complexity: O(|V|), linear in the number of vertices. */ int igraph_inclist_init_empty(igraph_inclist_t *il, igraph_integer_t n) { long int i; il->length = n; il->incs = IGRAPH_CALLOC(il->length, igraph_vector_int_t); if (il->incs == 0) { IGRAPH_ERROR("Cannot create incidence list view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_inclist_destroy, il); for (i = 0; i < n; i++) { IGRAPH_CHECK(igraph_vector_int_init(&il->incs[i], 0)); } IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_inclist_destroy * \brief Frees all memory allocated for an incidence list. * * \param eal The incidence list to destroy. * * Time complexity: depends on memory management. */ void igraph_inclist_destroy(igraph_inclist_t *il) { long int i; for (i = 0; i < il->length; i++) { /* This works if some igraph_vector_int_t's are 0, because igraph_vector_destroy can handle this. */ igraph_vector_int_destroy(&il->incs[i]); } IGRAPH_FREE(il->incs); } /** * \function igraph_inclist_clear * \brief Removes all edges from an incidence list. * * \param il The incidence list. * * Time complexity: depends on memory management, typically O(n), where n is * the total number of elements in the incidence list. */ void igraph_inclist_clear(igraph_inclist_t *il) { long int i; for (i = 0; i < il->length; i++) { igraph_vector_int_clear(&il->incs[i]); } } /** * \function igraph_inclist_size * \brief Returns the number of vertices in an incidence list. * * \param il The incidence list. * \return The number of vertices in the incidence list. * * Time complexity: O(1). */ igraph_integer_t igraph_inclist_size(const igraph_inclist_t *il) { return il->length; } static int igraph_i_simplify_sorted_int_adjacency_vector_in_place( igraph_vector_int_t *v, igraph_integer_t index, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple ) { long int i, p = 0; long int n = igraph_vector_int_size(v); if ( multiple == IGRAPH_MULTIPLE && ( loops == IGRAPH_LOOPS_TWICE || (loops == IGRAPH_LOOPS_ONCE && (mode == IGRAPH_IN || mode == IGRAPH_OUT)) ) ) { /* nothing to simplify */ return IGRAPH_SUCCESS; } if (loops == IGRAPH_NO_LOOPS) { if (multiple == IGRAPH_NO_MULTIPLE) { /* We need to get rid of loops and multiple edges completely */ for (i = 0; i < n; i++) { if (VECTOR(*v)[i] != index && (i == n - 1 || VECTOR(*v)[i + 1] != VECTOR(*v)[i])) { VECTOR(*v)[p] = VECTOR(*v)[i]; p++; } } } else { /* We need to get rid of loops but keep multiple edges */ for (i = 0; i < n; i++) { if (VECTOR(*v)[i] != index) { VECTOR(*v)[p] = VECTOR(*v)[i]; p++; } } } } else if (loops == IGRAPH_LOOPS_ONCE) { if (multiple == IGRAPH_NO_MULTIPLE) { /* We need to get rid of multiple edges completely (including * multiple loop edges), but keep one edge from each loop edge */ /* TODO(ntamas): think this through! */ for (i = 0; i < n; i++) { if (i == n - 1 || VECTOR(*v)[i + 1] != VECTOR(*v)[i]) { VECTOR(*v)[p] = VECTOR(*v)[i]; p++; } } } else { /* We need to keep one edge from each loop edge and we don't need to * touch multiple edges. Note that we can get here only if * mode == IGRAPH_ALL; if mode was IGRAPH_IN or IGRAPH_OUT, we would * have bailed out earlier */ for (i = 0; i < n; i++) { VECTOR(*v)[p] = VECTOR(*v)[i]; if (VECTOR(*v)[i] == index) { /* this was a loop edge so if the next element is the same, we * need to skip that */ if (i < n-1 && VECTOR(*v)[i + 1] == index) { i++; } } p++; } } } else if (loops == IGRAPH_LOOPS_TWICE && multiple == IGRAPH_NO_MULTIPLE) { /* We need to get rid of multiple edges completely (including * multiple loop edges), but keep both edge from each loop edge */ /* TODO(ntamas): think this through! */ for (i = 0; i < n; i++) { if (i == n - 1 || VECTOR(*v)[i + 1] != VECTOR(*v)[i]) { VECTOR(*v)[p] = VECTOR(*v)[i]; p++; } else { /* Current item is the same as the next one, but if it is a * loop edge, then the first one or two items are okay. We need * to keep one if mode == IGRAPH_IN or mode == IGRAPH_OUT, * otherwise we need to keep two */ if (VECTOR(*v)[i] == index) { VECTOR(*v)[p] = VECTOR(*v)[i]; p++; if (mode == IGRAPH_ALL) { VECTOR(*v)[p] = VECTOR(*v)[i]; p++; } /* skip over all the items corresponding to the loop edges */ while (i < n && VECTOR(*v)[i] == index) { i++; } i--; /* because the for loop also increases i by 1 */ } } } } else { /* TODO; we don't use this combination yet */ return IGRAPH_UNIMPLEMENTED; } /* always succeeds since we are never growing the vector */ igraph_vector_int_resize(v, p); return IGRAPH_SUCCESS; } /** * \function igraph_lazy_adjlist_init * \brief Initialized a lazy adjacency list. * * Create a lazy adjacency list for vertices. This function only * allocates some memory for storing the vectors of an adjacency list, * but the neighbor vertices are not queried, only at the \ref * igraph_lazy_adjlist_get() calls. * \param graph The input graph. * \param al Pointer to an uninitialized adjacency list object. * \param mode Constant, it gives whether incoming edges * (IGRAPH_IN), outgoing edges * (IGRPAH_OUT) or both types of edges * (IGRAPH_ALL) are considered. It is ignored for * undirected graphs. * \param simplify Constant, it gives whether to simplify the vectors * in the adjacency list (IGRAPH_SIMPLIFY) or not * (IGRAPH_DONT_SIMPLIFY). * \return Error code. * * Time complexity: O(|V|), the number of vertices, possibly, but * depends on the underlying memory management too. */ int igraph_lazy_adjlist_init(const igraph_t *graph, igraph_lazy_adjlist_t *al, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple) { if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) { IGRAPH_ERROR("Cannor create lazy adjacency list view", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } al->mode = mode; al->loops = loops; al->multiple = multiple; al->graph = graph; al->length = igraph_vcount(graph); al->adjs = IGRAPH_CALLOC(al->length, igraph_vector_int_t*); if (al->adjs == 0) { IGRAPH_ERROR("Cannot create lazy adjacency list view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, al->adjs); IGRAPH_CHECK(igraph_vector_init(&al->dummy, 0)); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_lazy_adjlist_destroy * \brief Deallocate a lazt adjacency list. * * Free all allocated memory for a lazy adjacency list. * \param al The adjacency list to deallocate. * * Time complexity: depends on the memory management. */ void igraph_lazy_adjlist_destroy(igraph_lazy_adjlist_t *al) { igraph_lazy_adjlist_clear(al); igraph_vector_destroy(&al->dummy); IGRAPH_FREE(al->adjs); } /** * \function igraph_lazy_adjlist_clear * \brief Removes all edges from a lazy adjacency list. * * \param al The lazy adjacency list. * Time complexity: depends on memory management, typically O(n), where n is * the total number of elements in the adjacency list. */ void igraph_lazy_adjlist_clear(igraph_lazy_adjlist_t *al) { long int i, n = al->length; for (i = 0; i < n; i++) { if (al->adjs[i] != 0) { igraph_vector_int_destroy(al->adjs[i]); IGRAPH_FREE(al->adjs[i]); } } } /** * \function igraph_lazy_adjlist_size * \brief Returns the number of vertices in a lazy adjacency list. * * \param al The lazy adjacency list. * \return The number of vertices in the lazy adjacency list. * * Time complexity: O(1). */ igraph_integer_t igraph_lazy_adjlist_size(const igraph_lazy_adjlist_t *al) { return al->length; } igraph_vector_int_t *igraph_i_lazy_adjlist_get_real(igraph_lazy_adjlist_t *al, igraph_integer_t pno) { igraph_integer_t no = pno; long int i, n; int ret; if (al->adjs[no] == 0) { ret = igraph_neighbors(al->graph, &al->dummy, no, al->mode); if (ret != 0) { igraph_error("", IGRAPH_FILE_BASENAME, __LINE__, ret); return 0; } al->adjs[no] = IGRAPH_CALLOC(1, igraph_vector_int_t); if (al->adjs[no] == 0) { igraph_error("Lazy adjlist failed", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } n = igraph_vector_size(&al->dummy); ret = igraph_vector_int_init(al->adjs[no], n); if (ret != 0) { IGRAPH_FREE(al->adjs[no]); igraph_error("", IGRAPH_FILE_BASENAME, __LINE__, ret); return 0; } for (i = 0; i < n; i++) { VECTOR(*al->adjs[no])[i] = VECTOR(al->dummy)[i]; } ret = igraph_i_simplify_sorted_int_adjacency_vector_in_place( al->adjs[no], no, al->mode, al->loops, al->multiple ); if (ret != 0) { igraph_vector_int_destroy(al->adjs[no]); IGRAPH_FREE(al->adjs[no]); igraph_error("", IGRAPH_FILE_BASENAME, __LINE__, ret); return 0; } } return al->adjs[no]; } /** * \function igraph_lazy_inclist_init * \brief Initializes a lazy incidence list of edges. * * Create a lazy incidence list for edges. This function only * allocates some memory for storing the vectors of an incidence list, * but the incident edges are not queried, only when \ref * igraph_lazy_inclist_get() is called. * * * When \p mode is \c IGRAPH_IN or \c IGRAPH_OUT, each edge ID will appear * in the incidence list \em once. When \p mode is \c IGRAPH_ALL, each edge ID * will appear in the incidence list \em twice, once for the source vertex * and once for the target edge. It also means that the edge IDs of loop edges * will appear \em twice for the \em same vertex. * * \param graph The input graph. * \param al Pointer to an uninitialized incidence list. * \param mode Constant, it gives whether incoming edges * (IGRAPH_IN), outgoing edges * (IGRAPH_OUT) or both types of edges * (IGRAPH_ALL) are considered. It is ignored for * undirected graphs. * \param loops Specifies how to treat loop edges. IGRAPH_NO_LOOPS * removes loop edges from the incidence list. IGRAPH_LOOPS_ONCE * makes each loop edge appear only once in the incidence list of the * corresponding vertex. IGRAPH_LOOPS_TWICE makes loop edges * appear \em twice in the incidence list of the corresponding vertex, * but only if the graph is undirected or mode is set to * IGRAPH_ALL. * \return Error code. * * Time complexity: O(|V|), the number of vertices, possibly. But it * also depends on the underlying memory management. */ int igraph_lazy_inclist_init(const igraph_t *graph, igraph_lazy_inclist_t *il, igraph_neimode_t mode, igraph_loops_t loops) { if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) { IGRAPH_ERROR("Cannot create lazy incidence list view", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode = IGRAPH_ALL; } il->graph = graph; il->loops = loops; il->mode = mode; il->length = igraph_vcount(graph); il->incs = IGRAPH_CALLOC(il->length, igraph_vector_int_t*); if (il->incs == 0) { IGRAPH_ERROR("Cannot create lazy incidence list view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, il->incs); IGRAPH_CHECK(igraph_vector_init(&il->dummy, 0)); IGRAPH_FINALLY_CLEAN(1); return 0; } /** * \function igraph_lazy_inclist_destroy * \brief Deallocates a lazy incidence list. * * Frees all allocated memory for a lazy incidence list. * \param al The incidence list to deallocate. * * Time complexity: depends on memory management. */ void igraph_lazy_inclist_destroy(igraph_lazy_inclist_t *il) { igraph_lazy_inclist_clear(il); igraph_vector_destroy(&il->dummy); IGRAPH_FREE(il->incs); } /** * \function igraph_lazy_inclist_clear * \brief Removes all edges from a lazy incidence list. * * \param il The lazy incidence list. * * Time complexity: depends on memory management, typically O(n), where n is * the total number of elements in the incidence list. */ void igraph_lazy_inclist_clear(igraph_lazy_inclist_t *il) { long int i, n = il->length; for (i = 0; i < n; i++) { if (il->incs[i] != 0) { igraph_vector_int_destroy(il->incs[i]); IGRAPH_FREE(il->incs[i]); } } } /** * \function igraph_lazy_inclist_size * \brief Returns the number of vertices in a lazy incidence list. * * \param il The lazy incidence list. * \return The number of vertices in the lazy incidence list. * * Time complexity: O(1). */ igraph_integer_t igraph_lazy_inclist_size(const igraph_lazy_inclist_t *il) { return il->length; } igraph_vector_int_t *igraph_i_lazy_inclist_get_real(igraph_lazy_inclist_t *il, igraph_integer_t pno) { igraph_integer_t no = pno; int ret; long int i, n; if (il->incs[no] == 0) { ret = igraph_incident(il->graph, &il->dummy, no, il->mode); if (ret != 0) { igraph_error("", IGRAPH_FILE_BASENAME, __LINE__, ret); return 0; } il->incs[no] = IGRAPH_CALLOC(1, igraph_vector_int_t); if (il->incs[no] == 0) { igraph_error("Lazy incidence list query failed", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_ENOMEM); return 0; } n = igraph_vector_size(&il->dummy); ret = igraph_vector_int_init(il->incs[no], n); if (ret != 0) { IGRAPH_FREE(il->incs[no]); igraph_error("", IGRAPH_FILE_BASENAME, __LINE__, ret); return 0; } for (i = 0; i < n; i++) { VECTOR(*il->incs[no])[i] = VECTOR(il->dummy)[i]; } if (il->loops != IGRAPH_LOOPS_TWICE) { ret = igraph_i_remove_loops_from_incidence_vector_in_place(il->incs[no], il->graph, il->loops); if (ret != 0) { igraph_vector_int_destroy(il->incs[no]); IGRAPH_FREE(il->incs[no]); return 0; } } } return il->incs[no]; } leidenbase/src/core/graph/cattributes.c0000644000176200001440000045305414447675374017722 0ustar liggesusers/* -*- mode: C -*- */ /* IGraph library. Copyright (C) 2005-2012 Gabor Csardi 334 Harvard street, Cambridge, MA 02139 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "igraph_attributes.h" #include "igraph_memory.h" #include "core/math.h" #include "igraph_interface.h" #include "igraph_random.h" #include /* An attribute is either a numeric vector (vector_t) or a string vector (strvector_t). The attribute itself is stored in a struct igraph_attribute_record_t, there is one such object for each attribute. The igraph_t has a pointer to an array of three vector_ptr_t's which contains pointers to igraph_i_cattribute_t's. Graph attributes are first, then vertex and edge attributes. */ static igraph_bool_t igraph_i_cattribute_find(const igraph_vector_ptr_t *ptrvec, const char *name, long int *idx) { long int i, n = igraph_vector_ptr_size(ptrvec); igraph_bool_t l = 0; for (i = 0; !l && i < n; i++) { igraph_attribute_record_t *rec = VECTOR(*ptrvec)[i]; l = !strcmp(rec->name, name); } if (idx) { *idx = i - 1; } return l; } typedef struct igraph_i_cattributes_t { igraph_vector_ptr_t gal; igraph_vector_ptr_t val; igraph_vector_ptr_t eal; } igraph_i_cattributes_t; static int igraph_i_cattributes_copy_attribute_record(igraph_attribute_record_t **newrec, const igraph_attribute_record_t *rec) { igraph_vector_t *num, *newnum; igraph_strvector_t *str, *newstr; *newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); if (!(*newrec)) { IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, *newrec); (*newrec)->type = rec->type; (*newrec)->name = strdup(rec->name); if (!(*newrec)->name) { IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (void*)(*newrec)->name); if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { num = (igraph_vector_t *)rec->value; newnum = IGRAPH_CALLOC(1, igraph_vector_t); if (!newnum) { IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newnum); IGRAPH_CHECK(igraph_vector_copy(newnum, num)); IGRAPH_FINALLY(igraph_vector_destroy, newnum); (*newrec)->value = newnum; } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { str = (igraph_strvector_t*)rec->value; newstr = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newstr) { IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newstr); IGRAPH_CHECK(igraph_strvector_copy(newstr, str)); IGRAPH_FINALLY(igraph_strvector_destroy, newstr); (*newrec)->value = newstr; } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_vector_bool_t *log = (igraph_vector_bool_t*) rec->value; igraph_vector_bool_t *newlog = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!newlog) { IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newlog); IGRAPH_CHECK(igraph_vector_bool_copy(newlog, log)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newlog); (*newrec)->value = newlog; } IGRAPH_FINALLY_CLEAN(4); return 0; } static int igraph_i_cattribute_init(igraph_t *graph, igraph_vector_ptr_t *attr) { igraph_attribute_record_t *attr_rec; long int i, n; igraph_i_cattributes_t *nattr; n = attr ? igraph_vector_ptr_size(attr) : 0; nattr = IGRAPH_CALLOC(1, igraph_i_cattributes_t); if (!nattr) { IGRAPH_ERROR("Can't init attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, nattr); IGRAPH_CHECK(igraph_vector_ptr_init(&nattr->gal, n)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &nattr->gal); IGRAPH_CHECK(igraph_vector_ptr_init(&nattr->val, 0)); IGRAPH_FINALLY(igraph_vector_ptr_destroy, &nattr->val); IGRAPH_CHECK(igraph_vector_ptr_init(&nattr->eal, 0)); IGRAPH_FINALLY_CLEAN(3); for (i = 0; i < n; i++) { IGRAPH_CHECK(igraph_i_cattributes_copy_attribute_record( &attr_rec, VECTOR(*attr)[i])); VECTOR(nattr->gal)[i] = attr_rec; } graph->attr = nattr; return 0; } static void igraph_i_cattribute_destroy(igraph_t *graph) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *als[3] = { &attr->gal, &attr->val, &attr->eal }; long int i, n, a; igraph_vector_t *num; igraph_strvector_t *str; igraph_vector_bool_t *boolvec; igraph_attribute_record_t *rec; for (a = 0; a < 3; a++) { n = igraph_vector_ptr_size(als[a]); for (i = 0; i < n; i++) { rec = VECTOR(*als[a])[i]; if (rec) { if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { num = (igraph_vector_t*)rec->value; igraph_vector_destroy(num); igraph_free(num); } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { str = (igraph_strvector_t*)rec->value; igraph_strvector_destroy(str); igraph_free(str); } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { boolvec = (igraph_vector_bool_t*)rec->value; igraph_vector_bool_destroy(boolvec); igraph_free(boolvec); } igraph_free((char*)rec->name); igraph_free(rec); } } } igraph_vector_ptr_destroy(&attr->gal); igraph_vector_ptr_destroy(&attr->val); igraph_vector_ptr_destroy(&attr->eal); igraph_free(graph->attr); graph->attr = 0; } /* Almost the same as destroy, but we might have null pointers */ static void igraph_i_cattribute_copy_free(igraph_i_cattributes_t *attr) { igraph_vector_ptr_t *als[3] = { &attr->gal, &attr->val, &attr->eal }; long int i, n, a; igraph_vector_t *num; igraph_strvector_t *str; igraph_vector_bool_t *boolvec; igraph_attribute_record_t *rec; for (a = 0; a < 3; a++) { n = igraph_vector_ptr_size(als[a]); for (i = 0; i < n; i++) { rec = VECTOR(*als[a])[i]; if (!rec) { continue; } if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { num = (igraph_vector_t*)rec->value; igraph_vector_destroy(num); igraph_free(num); } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { boolvec = (igraph_vector_bool_t*)rec->value; igraph_vector_bool_destroy(boolvec); igraph_free(boolvec); } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { str = (igraph_strvector_t*)rec->value; igraph_strvector_destroy(str); igraph_free(str); } igraph_free((char*)rec->name); igraph_free(rec); } } } /* No reference counting here. If you use attributes in C you should know what you're doing. */ static int igraph_i_cattribute_copy(igraph_t *to, const igraph_t *from, igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea) { igraph_i_cattributes_t *attrfrom = from->attr, *attrto; igraph_vector_ptr_t *alto[3], *alfrom[3] = { &attrfrom->gal, &attrfrom->val, &attrfrom->eal }; long int i, n, a; igraph_bool_t copy[3] = { ga, va, ea }; to->attr = attrto = IGRAPH_CALLOC(1, igraph_i_cattributes_t); if (!attrto) { IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, attrto); IGRAPH_VECTOR_PTR_INIT_FINALLY(&attrto->gal, 0); IGRAPH_VECTOR_PTR_INIT_FINALLY(&attrto->val, 0); IGRAPH_VECTOR_PTR_INIT_FINALLY(&attrto->eal, 0); IGRAPH_FINALLY_CLEAN(3); IGRAPH_FINALLY(igraph_i_cattribute_copy_free, attrto); alto[0] = &attrto->gal; alto[1] = &attrto->val; alto[2] = &attrto->eal; for (a = 0; a < 3; a++) { if (copy[a]) { n = igraph_vector_ptr_size(alfrom[a]); IGRAPH_CHECK(igraph_vector_ptr_resize(alto[a], n)); igraph_vector_ptr_null(alto[a]); for (i = 0; i < n; i++) { igraph_attribute_record_t *newrec; IGRAPH_CHECK(igraph_i_cattributes_copy_attribute_record(&newrec, VECTOR(*alfrom[a])[i])); VECTOR(*alto[a])[i] = newrec; } } } IGRAPH_FINALLY_CLEAN(2); return 0; } static int igraph_i_cattribute_add_vertices(igraph_t *graph, long int nv, igraph_vector_ptr_t *nattr) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int length = igraph_vector_ptr_size(val); long int nattrno = nattr == NULL ? 0 : igraph_vector_ptr_size(nattr); long int origlen = igraph_vcount(graph) - nv; long int newattrs = 0, i; igraph_vector_t news; /* First add the new attributes if any */ newattrs = 0; IGRAPH_VECTOR_INIT_FINALLY(&news, 0); for (i = 0; i < nattrno; i++) { igraph_attribute_record_t *nattr_entry = VECTOR(*nattr)[i]; const char *nname = nattr_entry->name; long int j; igraph_bool_t l = igraph_i_cattribute_find(val, nname, &j); if (!l) { newattrs++; IGRAPH_CHECK(igraph_vector_push_back(&news, i)); } else { /* check types */ if (nattr_entry->type != ((igraph_attribute_record_t*)VECTOR(*val)[j])->type) { IGRAPH_ERROR("You cannot mix attribute types", IGRAPH_EINVAL); } } } /* Add NA/empty string vectors for the existing vertices */ if (newattrs != 0) { for (i = 0; i < newattrs; i++) { igraph_attribute_record_t *tmp = VECTOR(*nattr)[(long int)VECTOR(news)[i]]; igraph_attribute_record_t *newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_attribute_type_t type = tmp->type; if (!newrec) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newrec); newrec->type = type; newrec->name = strdup(tmp->name); if (!newrec->name) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)newrec->name); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *newnum = IGRAPH_CALLOC(1, igraph_vector_t); if (!newnum) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newnum); IGRAPH_VECTOR_INIT_FINALLY(newnum, origlen); newrec->value = newnum; igraph_vector_fill(newnum, IGRAPH_NAN); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *newstr = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newstr) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newstr); IGRAPH_STRVECTOR_INIT_FINALLY(newstr, origlen); newrec->value = newstr; } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_vector_bool_t *newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!newbool) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newbool); IGRAPH_CHECK(igraph_vector_bool_init(newbool, origlen)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newbool); newrec->value = newbool; igraph_vector_bool_fill(newbool, 0); } IGRAPH_CHECK(igraph_vector_ptr_push_back(val, newrec)); IGRAPH_FINALLY_CLEAN(4); } length = igraph_vector_ptr_size(val); } /* Now append the new values */ for (i = 0; i < length; i++) { igraph_attribute_record_t *oldrec = VECTOR(*val)[i]; igraph_attribute_record_t *newrec = 0; const char *name = oldrec->name; long int j = -1; igraph_bool_t l = 0; if (nattr) { l = igraph_i_cattribute_find(nattr, name, &j); } if (l) { /* This attribute is present in nattr */ igraph_vector_t *oldnum, *newnum; igraph_strvector_t *oldstr, *newstr; igraph_vector_bool_t *oldbool, *newbool; newrec = VECTOR(*nattr)[j]; oldnum = (igraph_vector_t*)oldrec->value; newnum = (igraph_vector_t*)newrec->value; oldstr = (igraph_strvector_t*)oldrec->value; newstr = (igraph_strvector_t*)newrec->value; oldbool = (igraph_vector_bool_t*)oldrec->value; newbool = (igraph_vector_bool_t*)newrec->value; if (oldrec->type != newrec->type) { IGRAPH_ERROR("Attribute types do not match", IGRAPH_EINVAL); } switch (oldrec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: if (nv != igraph_vector_size(newnum)) { IGRAPH_ERROR("Invalid numeric attribute length", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_append(oldnum, newnum)); break; case IGRAPH_ATTRIBUTE_STRING: if (nv != igraph_strvector_size(newstr)) { IGRAPH_ERROR("Invalid string attribute length", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_strvector_append(oldstr, newstr)); break; case IGRAPH_ATTRIBUTE_BOOLEAN: if (nv != igraph_vector_bool_size(newbool)) { IGRAPH_ERROR("Invalid Boolean attribute length", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_bool_append(oldbool, newbool)); break; default: IGRAPH_WARNING("Invalid attribute type"); break; } } else { /* No such attribute, append NA's */ igraph_vector_t *oldnum = (igraph_vector_t *)oldrec->value; igraph_strvector_t *oldstr = (igraph_strvector_t*)oldrec->value; igraph_vector_bool_t *oldbool = (igraph_vector_bool_t*)oldrec->value; switch (oldrec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: IGRAPH_CHECK(igraph_vector_resize(oldnum, origlen + nv)); for (j = origlen; j < origlen + nv; j++) { VECTOR(*oldnum)[j] = IGRAPH_NAN; } break; case IGRAPH_ATTRIBUTE_STRING: IGRAPH_CHECK(igraph_strvector_resize(oldstr, origlen + nv)); break; case IGRAPH_ATTRIBUTE_BOOLEAN: IGRAPH_CHECK(igraph_vector_bool_resize(oldbool, origlen + nv)); for (j = origlen; j < origlen + nv; j++) { VECTOR(*oldbool)[j] = 0; } break; default: IGRAPH_WARNING("Invalid attribute type"); break; } } } igraph_vector_destroy(&news); IGRAPH_FINALLY_CLEAN(1); return 0; } static void igraph_i_cattribute_permute_free(igraph_vector_ptr_t *v) { long int i, n = igraph_vector_ptr_size(v); for (i = 0; i < n; i++) { igraph_attribute_record_t *rec = VECTOR(*v)[i]; IGRAPH_FREE(rec->name); if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *numv = (igraph_vector_t*) rec->value; igraph_vector_destroy(numv); IGRAPH_FREE(numv); } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strv = (igraph_strvector_t*) rec->value; igraph_strvector_destroy(strv); IGRAPH_FREE(strv); } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_vector_bool_t *boolv = (igraph_vector_bool_t*) rec->value; igraph_vector_bool_destroy(boolv); IGRAPH_FREE(boolv); } IGRAPH_FREE(rec); } igraph_vector_ptr_clear(v); } static int igraph_i_cattribute_permute_vertices(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_t *idx) { if (graph == newgraph) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int valno = igraph_vector_ptr_size(val); long int i; for (i = 0; i < valno; i++) { igraph_attribute_record_t *oldrec = VECTOR(*val)[i]; igraph_attribute_type_t type = oldrec->type; igraph_vector_t *num, *newnum; igraph_strvector_t *str, *newstr; igraph_vector_bool_t *oldbool, *newbool; switch (type) { case IGRAPH_ATTRIBUTE_NUMERIC: num = (igraph_vector_t*) oldrec->value; newnum = IGRAPH_CALLOC(1, igraph_vector_t); if (!newnum) { IGRAPH_ERROR("Cannot permute vertex attributes", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(newnum, 0); igraph_vector_index(num, newnum, idx); oldrec->value = newnum; igraph_vector_destroy(num); IGRAPH_FREE(num); IGRAPH_FINALLY_CLEAN(1); break; case IGRAPH_ATTRIBUTE_BOOLEAN: oldbool = (igraph_vector_bool_t*) oldrec->value; newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!newbool) { IGRAPH_ERROR("Cannot permute vertex attributes", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_bool_init(newbool, 0)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newbool); igraph_vector_bool_index(oldbool, newbool, idx); oldrec->value = newbool; igraph_vector_bool_destroy(oldbool); IGRAPH_FREE(oldbool); IGRAPH_FINALLY_CLEAN(1); break; case IGRAPH_ATTRIBUTE_STRING: str = (igraph_strvector_t*)oldrec->value; newstr = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newstr) { IGRAPH_ERROR("Cannot permute vertex attributes", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_strvector_init(newstr, 0)); IGRAPH_FINALLY(igraph_strvector_destroy, newstr); igraph_strvector_index(str, newstr, idx); oldrec->value = newstr; igraph_strvector_destroy(str); IGRAPH_FREE(str); IGRAPH_FINALLY_CLEAN(1); break; default: IGRAPH_WARNING("Unknown edge attribute ignored"); } } } else { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int valno = igraph_vector_ptr_size(val); long int i; /* New vertex attributes */ igraph_i_cattributes_t *new_attr = newgraph->attr; igraph_vector_ptr_t *new_val = &new_attr->val; if (igraph_vector_ptr_size(new_val) != 0) { IGRAPH_ERROR("Vertex attributes were already copied", IGRAPH_EATTRIBUTES); } IGRAPH_CHECK(igraph_vector_ptr_resize(new_val, valno)); IGRAPH_FINALLY(igraph_i_cattribute_permute_free, new_val); for (i = 0; i < valno; i++) { igraph_attribute_record_t *oldrec = VECTOR(*val)[i]; igraph_attribute_type_t type = oldrec->type; igraph_vector_t *num, *newnum; igraph_strvector_t *str, *newstr; igraph_vector_bool_t *oldbool, *newbool; /* The record itself */ igraph_attribute_record_t *new_rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); if (!new_rec) { IGRAPH_ERROR("Cannot create vertex attributes", IGRAPH_ENOMEM); } new_rec->name = strdup(oldrec->name); new_rec->type = oldrec->type; VECTOR(*new_val)[i] = new_rec; /* The data */ switch (type) { case IGRAPH_ATTRIBUTE_NUMERIC: num = (igraph_vector_t*)oldrec->value; newnum = IGRAPH_CALLOC(1, igraph_vector_t); if (!newnum) { IGRAPH_ERROR("Cannot permute vertex attributes", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(newnum, 0); igraph_vector_index(num, newnum, idx); new_rec->value = newnum; IGRAPH_FINALLY_CLEAN(1); break; case IGRAPH_ATTRIBUTE_BOOLEAN: oldbool = (igraph_vector_bool_t*)oldrec->value; newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!newbool) { IGRAPH_ERROR("Cannot permute vertex attributes", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_bool_init(newbool, 0)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newbool); igraph_vector_bool_index(oldbool, newbool, idx); new_rec->value = newbool; IGRAPH_FINALLY_CLEAN(1); break; case IGRAPH_ATTRIBUTE_STRING: str = (igraph_strvector_t*)oldrec->value; newstr = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newstr) { IGRAPH_ERROR("Cannot permute vertex attributes", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_strvector_init(newstr, 0)); IGRAPH_FINALLY(igraph_strvector_destroy, newstr); igraph_strvector_index(str, newstr, idx); new_rec->value = newstr; IGRAPH_FINALLY_CLEAN(1); break; default: IGRAPH_WARNING("Unknown vertex attribute ignored"); } } } IGRAPH_FINALLY_CLEAN(1); return 0; } typedef int igraph_cattributes_combine_num_t(const igraph_vector_t *input, igraph_real_t *output); typedef int igraph_cattributes_combine_str_t(const igraph_strvector_t *input, char **output); typedef int igraph_cattributes_combine_bool_t(const igraph_vector_bool_t *input, igraph_bool_t *output); static int igraph_i_cattributes_cn_sum(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_t *oldv = oldrec->value; igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); long int newlen = igraph_vector_ptr_size(merges); long int i; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); for (i = 0; i < newlen; i++) { igraph_real_t s = 0.0; igraph_vector_t *idx = VECTOR(*merges)[i]; long int j, n = igraph_vector_size(idx); for (j = 0; j < n; j++) { long int x = (long int) VECTOR(*idx)[j]; s += VECTOR(*oldv)[x]; } VECTOR(*newv)[i] = s; } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cn_prod(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_t *oldv = oldrec->value; igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); long int newlen = igraph_vector_ptr_size(merges); long int i; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); for (i = 0; i < newlen; i++) { igraph_real_t s = 1.0; igraph_vector_t *idx = VECTOR(*merges)[i]; long int j, n = igraph_vector_size(idx); for (j = 0; j < n; j++) { long int x = (long int) VECTOR(*idx)[j]; s *= VECTOR(*oldv)[x]; } VECTOR(*newv)[i] = s; } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cn_min(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_t *oldv = oldrec->value; igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_real_t nan = IGRAPH_NAN; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int j, n = igraph_vector_size(idx); igraph_real_t m = n > 0 ? VECTOR(*oldv)[ (long int) VECTOR(*idx)[0] ] : nan; for (j = 1; j < n; j++) { long int x = (long int) VECTOR(*idx)[j]; igraph_real_t val = VECTOR(*oldv)[x]; if (val < m) { m = val; } } VECTOR(*newv)[i] = m; } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cn_max(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_t *oldv = oldrec->value; igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_real_t nan = IGRAPH_NAN; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int j, n = igraph_vector_size(idx); igraph_real_t m = n > 0 ? VECTOR(*oldv)[ (long int) VECTOR(*idx)[0] ] : nan; for (j = 1; j < n; j++) { long int x = (long int) VECTOR(*idx)[j]; igraph_real_t val = VECTOR(*oldv)[x]; if (val > m) { m = val; } } VECTOR(*newv)[i] = m; } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cn_random(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_t *oldv = oldrec->value; igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_real_t nan = IGRAPH_NAN; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); RNG_BEGIN(); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int n = igraph_vector_size(idx); if (n == 0) { VECTOR(*newv)[i] = nan; } else if (n == 1) { VECTOR(*newv)[i] = VECTOR(*oldv)[ (long int) VECTOR(*idx)[0] ]; } else { long int r = RNG_INTEGER(0, n - 1); VECTOR(*newv)[i] = VECTOR(*oldv)[ (long int) VECTOR(*idx)[r] ]; } } RNG_END(); IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cn_first(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_t *oldv = oldrec->value; igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_real_t nan = IGRAPH_NAN; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int n = igraph_vector_size(idx); if (n == 0) { VECTOR(*newv)[i] = nan; } else { VECTOR(*newv)[i] = VECTOR(*oldv)[ (long int) VECTOR(*idx)[0] ]; } } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cn_last(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_t *oldv = oldrec->value; igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_real_t nan = IGRAPH_NAN; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int n = igraph_vector_size(idx); if (n == 0) { VECTOR(*newv)[i] = nan; } else { VECTOR(*newv)[i] = VECTOR(*oldv)[ (long int) VECTOR(*idx)[n - 1] ]; } } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cn_mean(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_t *oldv = oldrec->value; igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_real_t nan = IGRAPH_NAN; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int j, n = igraph_vector_size(idx); igraph_real_t s = n > 0 ? 0.0 : nan; for (j = 0; j < n; j++) { long int x = (long int) VECTOR(*idx)[j]; s += VECTOR(*oldv)[x]; } if (n > 0) { s = s / n; } VECTOR(*newv)[i] = s; } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cn_func(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_ptr_t *merges, igraph_cattributes_combine_num_t *func) { const igraph_vector_t *oldv = oldrec->value; long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); igraph_vector_t values; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); IGRAPH_VECTOR_INIT_FINALLY(&values, 0); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int j, n = igraph_vector_size(idx); igraph_real_t res; IGRAPH_CHECK(igraph_vector_resize(&values, n)); for (j = 0; j < n; j++) { long int x = (long int) VECTOR(*idx)[j]; VECTOR(values)[j] = VECTOR(*oldv)[x]; } IGRAPH_CHECK(func(&values, &res)); VECTOR(*newv)[i] = res; } igraph_vector_destroy(&values); IGRAPH_FINALLY_CLEAN(3); newrec->value = newv; return 0; } static int igraph_i_cattributes_cb_random(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_bool_t *oldv = oldrec->value; igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); long int newlen = igraph_vector_ptr_size(merges); long int i; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_vector_bool_init(newv, newlen)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newv); RNG_BEGIN(); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int n = igraph_vector_size(idx); if (n == 0) { VECTOR(*newv)[i] = 0; } else if (n == 1) { VECTOR(*newv)[i] = VECTOR(*oldv)[ (long int) VECTOR(*idx)[0] ]; } else { long int r = RNG_INTEGER(0, n - 1); VECTOR(*newv)[i] = VECTOR(*oldv)[ (long int) VECTOR(*idx)[r] ]; } } RNG_END(); IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cb_first(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_bool_t *oldv = oldrec->value; igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); long int newlen = igraph_vector_ptr_size(merges); long int i; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_vector_bool_init(newv, newlen)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newv); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int n = igraph_vector_size(idx); if (n == 0) { VECTOR(*newv)[i] = 0; } else { VECTOR(*newv)[i] = VECTOR(*oldv)[ (long int) VECTOR(*idx)[0] ]; } } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cb_last(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_bool_t *oldv = oldrec->value; igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); long int newlen = igraph_vector_ptr_size(merges); long int i; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_vector_bool_init(newv, newlen)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newv); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int n = igraph_vector_size(idx); if (n == 0) { VECTOR(*newv)[i] = 0; } else { VECTOR(*newv)[i] = VECTOR(*oldv)[ (long int) VECTOR(*idx)[n - 1] ]; } } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cb_all_is_true(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_bool_t *oldv = oldrec->value; igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); long int newlen = igraph_vector_ptr_size(merges); long int i, j, n, x; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_vector_bool_init(newv, newlen)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newv); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; n = igraph_vector_size(idx); VECTOR(*newv)[i] = 1; for (j = 0; j < n; j++) { x = (long int) VECTOR(*idx)[j]; if (!VECTOR(*oldv)[x]) { VECTOR(*newv)[i] = 0; break; } } } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cb_any_is_true(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_bool_t *oldv = oldrec->value; igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); long int newlen = igraph_vector_ptr_size(merges); long int i, j, n, x; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_vector_bool_init(newv, newlen)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newv); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; n = igraph_vector_size(idx); VECTOR(*newv)[i] = 0; for (j = 0; j < n; j++) { x = (long int) VECTOR(*idx)[j]; if (VECTOR(*oldv)[x]) { VECTOR(*newv)[i] = 1; break; } } } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cb_majority(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_ptr_t *merges) { const igraph_vector_bool_t *oldv = oldrec->value; igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); long int newlen = igraph_vector_ptr_size(merges); long int i, j, n, x, num_trues; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_vector_bool_init(newv, newlen)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newv); RNG_BEGIN(); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; n = igraph_vector_size(idx); num_trues = 0; for (j = 0; j < n; j++) { x = (long int) VECTOR(*idx)[j]; if (VECTOR(*oldv)[x]) { num_trues++; } } if (n % 2 != 0) { VECTOR(*newv)[i] = (num_trues > n / 2); } else { if (num_trues == n / 2) { VECTOR(*newv)[i] = (RNG_UNIF01() < 0.5); } else { VECTOR(*newv)[i] = (num_trues > n / 2); } } } RNG_END(); IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_cb_func(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_ptr_t *merges, igraph_cattributes_combine_bool_t *func) { const igraph_vector_bool_t *oldv = oldrec->value; long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); igraph_vector_bool_t values; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_vector_bool_init(newv, newlen)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newv); IGRAPH_CHECK(igraph_vector_bool_init(&values, 0)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newv); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int j, n = igraph_vector_size(idx); igraph_bool_t res; IGRAPH_CHECK(igraph_vector_bool_resize(&values, n)); for (j = 0; j < n; j++) { long int x = (long int) VECTOR(*idx)[j]; VECTOR(values)[j] = VECTOR(*oldv)[x]; } IGRAPH_CHECK(func(&values, &res)); VECTOR(*newv)[i] = res; } igraph_vector_bool_destroy(&values); IGRAPH_FINALLY_CLEAN(3); newrec->value = newv; return 0; } static int igraph_i_cattributes_sn_random(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_ptr_t *merges) { const igraph_strvector_t *oldv = oldrec->value; long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_strvector_init(newv, newlen)); IGRAPH_FINALLY(igraph_strvector_destroy, newv); RNG_BEGIN(); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int n = igraph_vector_size(idx); char *tmp; if (n == 0) { IGRAPH_CHECK(igraph_strvector_set(newv, i, "")); } else if (n == 1) { igraph_strvector_get(oldv, 0, &tmp); IGRAPH_CHECK(igraph_strvector_set(newv, i, tmp)); } else { long int r = RNG_INTEGER(0, n - 1); igraph_strvector_get(oldv, r, &tmp); IGRAPH_CHECK(igraph_strvector_set(newv, i, tmp)); } } RNG_END(); IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_sn_first(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_ptr_t *merges) { const igraph_strvector_t *oldv = oldrec->value; long int i, newlen = igraph_vector_ptr_size(merges); igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_strvector_init(newv, newlen)); IGRAPH_FINALLY(igraph_strvector_destroy, newv); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int n = igraph_vector_size(idx); if (n == 0) { IGRAPH_CHECK(igraph_strvector_set(newv, i, "")); } else { char *tmp; igraph_strvector_get(oldv, (long int) VECTOR(*idx)[0], &tmp); IGRAPH_CHECK(igraph_strvector_set(newv, i, tmp)); } } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_sn_last(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_ptr_t *merges) { const igraph_strvector_t *oldv = oldrec->value; long int i, newlen = igraph_vector_ptr_size(merges); igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_strvector_init(newv, newlen)); IGRAPH_FINALLY(igraph_strvector_destroy, newv); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int n = igraph_vector_size(idx); if (n == 0) { IGRAPH_CHECK(igraph_strvector_set(newv, i, "")); } else { char *tmp; igraph_strvector_get(oldv, (long int) VECTOR(*idx)[n - 1], &tmp); IGRAPH_CHECK(igraph_strvector_set(newv, i, tmp)); } } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_sn_concat(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_ptr_t *merges) { const igraph_strvector_t *oldv = oldrec->value; long int i, newlen = igraph_vector_ptr_size(merges); igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_strvector_init(newv, newlen)); IGRAPH_FINALLY(igraph_strvector_destroy, newv); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int j, n = igraph_vector_size(idx); size_t len = 0; char *tmp, *tmp2; for (j = 0; j < n; j++) { igraph_strvector_get(oldv, j, &tmp); len += strlen(tmp); } tmp2 = IGRAPH_CALLOC(len + 1, char); if (!tmp2) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, tmp2); len = 0; for (j = 0; j < n; j++) { igraph_strvector_get(oldv, j, &tmp); strcpy(tmp2 + len, tmp); len += strlen(tmp); } IGRAPH_CHECK(igraph_strvector_set(newv, i, tmp2)); IGRAPH_FREE(tmp2); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_FINALLY_CLEAN(2); newrec->value = newv; return 0; } static int igraph_i_cattributes_sn_func(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_ptr_t *merges, igraph_cattributes_combine_str_t *func) { const igraph_strvector_t *oldv = oldrec->value; long int newlen = igraph_vector_ptr_size(merges); long int i; igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); igraph_strvector_t values; if (!newv) { IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newv); IGRAPH_CHECK(igraph_strvector_init(newv, newlen)); IGRAPH_FINALLY(igraph_strvector_destroy, newv); IGRAPH_CHECK(igraph_strvector_init(newv, 0)); IGRAPH_FINALLY(igraph_strvector_destroy, &values); for (i = 0; i < newlen; i++) { igraph_vector_t *idx = VECTOR(*merges)[i]; long int j, n = igraph_vector_size(idx); char *res; IGRAPH_CHECK(igraph_strvector_resize(&values, n)); for (j = 0; j < n; j++) { long int x = (long int) VECTOR(*idx)[j]; char *elem; igraph_strvector_get(oldv, x, &elem); IGRAPH_CHECK(igraph_strvector_set(newv, j, elem)); } IGRAPH_CHECK(func(&values, &res)); IGRAPH_FINALLY(igraph_free, res); IGRAPH_CHECK(igraph_strvector_set(newv, i, res)); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FREE(res); } igraph_strvector_destroy(&values); IGRAPH_FINALLY_CLEAN(3); newrec->value = newv; return 0; } static int igraph_i_cattribute_combine_vertices(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_ptr_t *merges, const igraph_attribute_combination_t *comb) { igraph_i_cattributes_t *attr = graph->attr; igraph_i_cattributes_t *toattr = newgraph->attr; igraph_vector_ptr_t *val = &attr->val; igraph_vector_ptr_t *new_val = &toattr->val; long int valno = igraph_vector_ptr_size(val); long int i, j, keepno = 0; int *TODO; igraph_function_pointer_t *funcs; TODO = IGRAPH_CALLOC(valno, int); if (!TODO) { IGRAPH_ERROR("Cannot combine vertex attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, TODO); funcs = IGRAPH_CALLOC(valno, igraph_function_pointer_t); if (!funcs) { IGRAPH_ERROR("Cannot combine vertex attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, funcs); for (i = 0; i < valno; i++) { igraph_attribute_record_t *oldrec = VECTOR(*val)[i]; const char *name = oldrec->name; igraph_attribute_combination_type_t todo; igraph_function_pointer_t voidfunc; igraph_attribute_combination_query(comb, name, &todo, &voidfunc); TODO[i] = todo; funcs[i] = voidfunc; if (todo != IGRAPH_ATTRIBUTE_COMBINE_IGNORE) { keepno++; } } IGRAPH_CHECK(igraph_vector_ptr_resize(new_val, keepno)); IGRAPH_FINALLY(igraph_i_cattribute_permute_free, new_val); for (i = 0, j = 0; i < valno; i++) { igraph_attribute_record_t *newrec, *oldrec = VECTOR(*val)[i]; const char *name = oldrec->name; igraph_attribute_combination_type_t todo = (igraph_attribute_combination_type_t) (TODO[i]); igraph_attribute_type_t type = oldrec->type; igraph_cattributes_combine_num_t *numfunc = (igraph_cattributes_combine_num_t*) funcs[i]; igraph_cattributes_combine_str_t *strfunc = (igraph_cattributes_combine_str_t*) funcs[i]; igraph_cattributes_combine_bool_t *boolfunc = (igraph_cattributes_combine_bool_t*) funcs[i]; if (todo == IGRAPH_ATTRIBUTE_COMBINE_DEFAULT || todo == IGRAPH_ATTRIBUTE_COMBINE_IGNORE) { continue; } newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); if (!newrec) { IGRAPH_ERROR("Cannot combine vertex attributes", IGRAPH_ENOMEM); } newrec->name = strdup(name); newrec->type = type; VECTOR(*new_val)[j] = newrec; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { switch (todo) { case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: IGRAPH_CHECK(igraph_i_cattributes_cn_func(oldrec, newrec, merges, numfunc)); break; case IGRAPH_ATTRIBUTE_COMBINE_SUM: IGRAPH_CHECK(igraph_i_cattributes_cn_sum(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_PROD: IGRAPH_CHECK(igraph_i_cattributes_cn_prod(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MIN: IGRAPH_CHECK(igraph_i_cattributes_cn_min(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MAX: IGRAPH_CHECK(igraph_i_cattributes_cn_max(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: IGRAPH_CHECK(igraph_i_cattributes_cn_random(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_FIRST: IGRAPH_CHECK(igraph_i_cattributes_cn_first(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_LAST: IGRAPH_CHECK(igraph_i_cattributes_cn_last(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MEAN: IGRAPH_CHECK(igraph_i_cattributes_cn_mean(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: IGRAPH_ERROR("Median calculation not implemented", IGRAPH_UNIMPLEMENTED); break; case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: IGRAPH_ERROR("Cannot concatenate numeric attributes", IGRAPH_EATTRCOMBINE); break; default: IGRAPH_ERROR("Unknown attribute_combination", IGRAPH_UNIMPLEMENTED); break; } } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { switch (todo) { case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: IGRAPH_CHECK(igraph_i_cattributes_cb_func(oldrec, newrec, merges, boolfunc)); break; case IGRAPH_ATTRIBUTE_COMBINE_SUM: case IGRAPH_ATTRIBUTE_COMBINE_MAX: IGRAPH_CHECK(igraph_i_cattributes_cb_any_is_true(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_PROD: case IGRAPH_ATTRIBUTE_COMBINE_MIN: IGRAPH_CHECK(igraph_i_cattributes_cb_all_is_true(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MEAN: case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: IGRAPH_CHECK(igraph_i_cattributes_cb_majority(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: IGRAPH_CHECK(igraph_i_cattributes_cb_random(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_FIRST: IGRAPH_CHECK(igraph_i_cattributes_cb_first(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_LAST: IGRAPH_CHECK(igraph_i_cattributes_cb_last(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: IGRAPH_ERROR("Cannot calculate concatenation of Booleans", IGRAPH_EATTRCOMBINE); break; default: IGRAPH_ERROR("Unknown attribute_combination", IGRAPH_UNIMPLEMENTED); break; } } else if (type == IGRAPH_ATTRIBUTE_STRING) { switch (todo) { case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: IGRAPH_CHECK(igraph_i_cattributes_sn_func(oldrec, newrec, merges, strfunc)); break; case IGRAPH_ATTRIBUTE_COMBINE_SUM: IGRAPH_ERROR("Cannot sum strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_PROD: IGRAPH_ERROR("Cannot multiply strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_MIN: IGRAPH_ERROR("Cannot find minimum of strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_MAX: IGRAPH_ERROR("Cannot find maximum of strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_MEAN: IGRAPH_ERROR("Cannot calculate mean of strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: IGRAPH_ERROR("Cannot calculate median of strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: IGRAPH_CHECK(igraph_i_cattributes_sn_random(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_FIRST: IGRAPH_CHECK(igraph_i_cattributes_sn_first(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_LAST: IGRAPH_CHECK(igraph_i_cattributes_sn_last(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: IGRAPH_CHECK(igraph_i_cattributes_sn_concat(oldrec, newrec, merges)); break; default: IGRAPH_ERROR("Unknown attribute_combination", IGRAPH_UNIMPLEMENTED); break; } } else { IGRAPH_ERROR("Unknown attribute type, this should not happen", IGRAPH_UNIMPLEMENTED); } j++; } igraph_free(funcs); igraph_free(TODO); igraph_i_cattribute_permute_free(new_val); IGRAPH_FINALLY_CLEAN(3); return 0; } /* void igraph_i_cattribute_delete_vertices(igraph_t *graph, */ /* const igraph_vector_t *eidx, */ /* const igraph_vector_t *vidx) { */ /* igraph_i_cattributes_t *attr=graph->attr; */ /* igraph_vector_ptr_t *val=&attr->val; */ /* igraph_vector_ptr_t *eal=&attr->eal; */ /* long int valno=igraph_vector_ptr_size(val); */ /* long int ealno=igraph_vector_ptr_size(eal); */ /* long int i; */ /* long int origlen, newlen; */ /* /\* Vertices *\/ */ /* origlen=igraph_vector_size(vidx); */ /* newlen=0; */ /* for (i=0; i0) { */ /* newlen++; */ /* } */ /* } */ /* for (i=0; itype; */ /* igraph_vector_t *num=(igraph_vector_t*)oldrec->value; */ /* igraph_strvector_t *str=(igraph_strvector_t*)oldrec->value; */ /* switch (type) { */ /* case IGRAPH_ATTRIBUTE_NUMERIC: */ /* igraph_vector_permdelete(num, vidx, origlen-newlen); */ /* break; */ /* case IGRAPH_ATTRIBUTE_STRING: */ /* igraph_strvector_permdelete(str, vidx, origlen-newlen); */ /* break; */ /* default: */ /* IGRAPH_WARNING("Unknown vertex attribute ignored"); */ /* } */ /* } */ /* /\* Edges *\/ */ /* origlen=igraph_vector_size(eidx); */ /* newlen=0; */ /* for (i=0; i0) { */ /* newlen++; */ /* } */ /* } */ /* for (i=0; itype; */ /* igraph_vector_t *num=(igraph_vector_t*)oldrec->value; */ /* igraph_strvector_t *str=(igraph_strvector_t*)oldrec->value; */ /* switch (type) { */ /* case IGRAPH_ATTRIBUTE_NUMERIC: */ /* igraph_vector_permdelete(num, eidx, origlen-newlen); */ /* break; */ /* case IGRAPH_ATTRIBUTE_STRING: */ /* igraph_strvector_permdelete(str, eidx, origlen-newlen); */ /* break; */ /* default: */ /* IGRAPH_WARNING("Unknown edge attribute ignored"); */ /* } */ /* } */ /* } */ static int igraph_i_cattribute_add_edges(igraph_t *graph, const igraph_vector_t *edges, igraph_vector_ptr_t *nattr) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int ealno = igraph_vector_ptr_size(eal); long int ne = igraph_vector_size(edges) / 2; long int origlen = igraph_ecount(graph) - ne; long int nattrno = nattr == 0 ? 0 : igraph_vector_ptr_size(nattr); igraph_vector_t news; long int newattrs, i; /* First add the new attributes if any */ newattrs = 0; IGRAPH_VECTOR_INIT_FINALLY(&news, 0); for (i = 0; i < nattrno; i++) { igraph_attribute_record_t *nattr_entry = VECTOR(*nattr)[i]; const char *nname = nattr_entry->name; long int j; igraph_bool_t l = igraph_i_cattribute_find(eal, nname, &j); if (!l) { newattrs++; IGRAPH_CHECK(igraph_vector_push_back(&news, i)); } else { /* check types */ if (nattr_entry->type != ((igraph_attribute_record_t*)VECTOR(*eal)[j])->type) { IGRAPH_ERROR("You cannot mix attribute types", IGRAPH_EINVAL); } } } /* Add NA/empty string vectors for the existing vertices */ if (newattrs != 0) { for (i = 0; i < newattrs; i++) { igraph_attribute_record_t *tmp = VECTOR(*nattr)[(long int)VECTOR(news)[i]]; igraph_attribute_record_t *newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_attribute_type_t type = tmp->type; if (!newrec) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newrec); newrec->type = type; newrec->name = strdup(tmp->name); if (!newrec->name) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)newrec->name); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *newnum = IGRAPH_CALLOC(1, igraph_vector_t); if (!newnum) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newnum); IGRAPH_VECTOR_INIT_FINALLY(newnum, origlen); newrec->value = newnum; igraph_vector_fill(newnum, IGRAPH_NAN); } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_vector_bool_t *newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!newbool) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newbool); IGRAPH_CHECK(igraph_vector_bool_init(newbool, origlen)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newbool); newrec->value = newbool; igraph_vector_bool_fill(newbool, 0); } else if (type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *newstr = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newstr) { IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newstr); IGRAPH_STRVECTOR_INIT_FINALLY(newstr, origlen); newrec->value = newstr; } IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, newrec)); IGRAPH_FINALLY_CLEAN(4); } ealno = igraph_vector_ptr_size(eal); } /* Now append the new values */ for (i = 0; i < ealno; i++) { igraph_attribute_record_t *oldrec = VECTOR(*eal)[i]; igraph_attribute_record_t *newrec = 0; const char *name = oldrec->name; long int j = -1; igraph_bool_t l = 0; if (nattr) { l = igraph_i_cattribute_find(nattr, name, &j); } if (l) { /* This attribute is present in nattr */ igraph_vector_t *oldnum, *newnum; igraph_strvector_t *oldstr, *newstr; igraph_vector_bool_t *oldbool, *newbool; newrec = VECTOR(*nattr)[j]; oldnum = (igraph_vector_t*)oldrec->value; newnum = (igraph_vector_t*)newrec->value; oldstr = (igraph_strvector_t*)oldrec->value; newstr = (igraph_strvector_t*)newrec->value; oldbool = (igraph_vector_bool_t*)oldrec->value; newbool = (igraph_vector_bool_t*)newrec->value; if (oldrec->type != newrec->type) { IGRAPH_ERROR("Attribute types do not match", IGRAPH_EINVAL); } switch (oldrec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: if (ne != igraph_vector_size(newnum)) { IGRAPH_ERROR("Invalid numeric attribute length", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_append(oldnum, newnum)); break; case IGRAPH_ATTRIBUTE_STRING: if (ne != igraph_strvector_size(newstr)) { IGRAPH_ERROR("Invalid string attribute length", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_strvector_append(oldstr, newstr)); break; case IGRAPH_ATTRIBUTE_BOOLEAN: if (ne != igraph_vector_bool_size(newbool)) { IGRAPH_ERROR("Invalid Boolean attribute length", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_bool_append(oldbool, newbool)); break; default: IGRAPH_WARNING("Invalid attribute type"); break; } } else { /* No such attribute, append NA's */ igraph_vector_t *oldnum = (igraph_vector_t *)oldrec->value; igraph_strvector_t *oldstr = (igraph_strvector_t*)oldrec->value; igraph_vector_bool_t *oldbool = (igraph_vector_bool_t *)oldrec->value; switch (oldrec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: IGRAPH_CHECK(igraph_vector_resize(oldnum, origlen + ne)); for (j = origlen; j < origlen + ne; j++) { VECTOR(*oldnum)[j] = IGRAPH_NAN; } break; case IGRAPH_ATTRIBUTE_STRING: IGRAPH_CHECK(igraph_strvector_resize(oldstr, origlen + ne)); break; case IGRAPH_ATTRIBUTE_BOOLEAN: IGRAPH_CHECK(igraph_vector_bool_resize(oldbool, origlen + ne)); for (j = origlen; j < origlen + ne; j++) { VECTOR(*oldbool)[j] = 0; } break; default: IGRAPH_WARNING("Invalid attribute type"); break; } } } igraph_vector_destroy(&news); IGRAPH_FINALLY_CLEAN(1); return 0; } /* void igraph_i_cattribute_delete_edges(igraph_t *graph, const igraph_vector_t *idx) { */ /* igraph_i_cattributes_t *attr=graph->attr; */ /* igraph_vector_ptr_t *eal=&attr->eal; */ /* long int ealno=igraph_vector_ptr_size(eal); */ /* long int i; */ /* long int origlen=igraph_vector_size(idx), newlen; */ /* newlen=0; */ /* for (i=0; i0) { */ /* newlen++; */ /* } */ /* } */ /* for (i=0; itype; */ /* igraph_vector_t *num=(igraph_vector_t*)oldrec->value; */ /* igraph_strvector_t *str=(igraph_strvector_t*)oldrec->value; */ /* switch (type) { */ /* case IGRAPH_ATTRIBUTE_NUMERIC: */ /* igraph_vector_permdelete(num, idx, origlen-newlen); */ /* break; */ /* case IGRAPH_ATTRIBUTE_STRING: */ /* igraph_strvector_permdelete(str, idx, origlen-newlen); */ /* break; */ /* default: */ /* IGRAPH_WARNING("Unknown edge attribute ignored"); */ /* } */ /* } */ /* } */ static int igraph_i_cattribute_permute_edges(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_t *idx) { if (graph == newgraph) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int ealno = igraph_vector_ptr_size(eal); long int i; for (i = 0; i < ealno; i++) { igraph_attribute_record_t *oldrec = VECTOR(*eal)[i]; igraph_attribute_type_t type = oldrec->type; igraph_vector_t *num, *newnum; igraph_strvector_t *str, *newstr; igraph_vector_bool_t *oldbool, *newbool; switch (type) { case IGRAPH_ATTRIBUTE_NUMERIC: num = (igraph_vector_t*) oldrec->value; newnum = IGRAPH_CALLOC(1, igraph_vector_t); if (!newnum) { IGRAPH_ERROR("Cannot permute edge attributes", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(newnum, 0); igraph_vector_index(num, newnum, idx); oldrec->value = newnum; igraph_vector_destroy(num); IGRAPH_FREE(num); IGRAPH_FINALLY_CLEAN(1); break; case IGRAPH_ATTRIBUTE_BOOLEAN: oldbool = (igraph_vector_bool_t*) oldrec->value; newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!newbool) { IGRAPH_ERROR("Cannot permute edge attributes", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_bool_init(newbool, 0)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newbool); igraph_vector_bool_index(oldbool, newbool, idx); oldrec->value = newbool; igraph_vector_bool_destroy(oldbool); IGRAPH_FREE(oldbool); IGRAPH_FINALLY_CLEAN(1); break; case IGRAPH_ATTRIBUTE_STRING: str = (igraph_strvector_t*)oldrec->value; newstr = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newstr) { IGRAPH_ERROR("Cannot permute edge attributes", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_strvector_init(newstr, 0)); IGRAPH_FINALLY(igraph_strvector_destroy, newstr); igraph_strvector_index(str, newstr, idx); oldrec->value = newstr; igraph_strvector_destroy(str); IGRAPH_FREE(str); IGRAPH_FINALLY_CLEAN(1); break; default: IGRAPH_WARNING("Unknown edge attribute ignored"); } } } else { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int ealno = igraph_vector_ptr_size(eal); long int i; /* New edge attributes */ igraph_i_cattributes_t *new_attr = newgraph->attr; igraph_vector_ptr_t *new_eal = &new_attr->eal; IGRAPH_CHECK(igraph_vector_ptr_resize(new_eal, ealno)); IGRAPH_FINALLY(igraph_i_cattribute_permute_free, new_eal); for (i = 0; i < ealno; i++) { igraph_attribute_record_t *oldrec = VECTOR(*eal)[i]; igraph_attribute_type_t type = oldrec->type; igraph_vector_t *num, *newnum; igraph_strvector_t *str, *newstr; igraph_vector_bool_t *oldbool, *newbool; /* The record itself */ igraph_attribute_record_t *new_rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); if (!new_rec) { IGRAPH_ERROR("Cannot create edge attributes", IGRAPH_ENOMEM); } new_rec->name = strdup(oldrec->name); new_rec->type = oldrec->type; VECTOR(*new_eal)[i] = new_rec; switch (type) { case IGRAPH_ATTRIBUTE_NUMERIC: num = (igraph_vector_t*) oldrec->value; newnum = IGRAPH_CALLOC(1, igraph_vector_t); if (!newnum) { IGRAPH_ERROR("Cannot permute edge attributes", IGRAPH_ENOMEM); } IGRAPH_VECTOR_INIT_FINALLY(newnum, 0); igraph_vector_index(num, newnum, idx); new_rec->value = newnum; IGRAPH_FINALLY_CLEAN(1); break; case IGRAPH_ATTRIBUTE_STRING: str = (igraph_strvector_t*)oldrec->value; newstr = IGRAPH_CALLOC(1, igraph_strvector_t); if (!newstr) { IGRAPH_ERROR("Cannot permute edge attributes", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_strvector_init(newstr, 0)); IGRAPH_FINALLY(igraph_strvector_destroy, newstr); igraph_strvector_index(str, newstr, idx); new_rec->value = newstr; IGRAPH_FINALLY_CLEAN(1); break; case IGRAPH_ATTRIBUTE_BOOLEAN: oldbool = (igraph_vector_bool_t*) oldrec->value; newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!newbool) { IGRAPH_ERROR("Cannot permute edge attributes", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_bool_init(newbool, 0)); IGRAPH_FINALLY(igraph_vector_bool_destroy, newbool); igraph_vector_bool_index(oldbool, newbool, idx); new_rec->value = newbool; IGRAPH_FINALLY_CLEAN(1); break; default: IGRAPH_WARNING("Unknown edge attribute ignored"); } } IGRAPH_FINALLY_CLEAN(1); } return 0; } static int igraph_i_cattribute_combine_edges(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_ptr_t *merges, const igraph_attribute_combination_t *comb) { igraph_i_cattributes_t *attr = graph->attr; igraph_i_cattributes_t *toattr = newgraph->attr; igraph_vector_ptr_t *eal = &attr->eal; igraph_vector_ptr_t *new_eal = &toattr->eal; long int ealno = igraph_vector_ptr_size(eal); long int i, j, keepno = 0; int *TODO; igraph_function_pointer_t *funcs; TODO = IGRAPH_CALLOC(ealno, int); if (!TODO) { IGRAPH_ERROR("Cannot combine edge attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, TODO); funcs = IGRAPH_CALLOC(ealno, igraph_function_pointer_t); if (!funcs) { IGRAPH_ERROR("Cannot combine edge attributes", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, funcs); for (i = 0; i < ealno; i++) { igraph_attribute_record_t *oldrec = VECTOR(*eal)[i]; const char *name = oldrec->name; igraph_attribute_combination_type_t todo; igraph_function_pointer_t voidfunc; igraph_attribute_combination_query(comb, name, &todo, &voidfunc); TODO[i] = todo; funcs[i] = voidfunc; if (todo != IGRAPH_ATTRIBUTE_COMBINE_IGNORE) { keepno++; } } IGRAPH_CHECK(igraph_vector_ptr_resize(new_eal, keepno)); IGRAPH_FINALLY(igraph_i_cattribute_permute_free, new_eal); for (i = 0, j = 0; i < ealno; i++) { igraph_attribute_record_t *newrec, *oldrec = VECTOR(*eal)[i]; const char *name = oldrec->name; igraph_attribute_combination_type_t todo = (igraph_attribute_combination_type_t) (TODO[i]); igraph_attribute_type_t type = oldrec->type; igraph_cattributes_combine_num_t *numfunc = (igraph_cattributes_combine_num_t*) funcs[i]; igraph_cattributes_combine_str_t *strfunc = (igraph_cattributes_combine_str_t*) funcs[i]; igraph_cattributes_combine_bool_t *boolfunc = (igraph_cattributes_combine_bool_t*) funcs[i]; if (todo == IGRAPH_ATTRIBUTE_COMBINE_DEFAULT || todo == IGRAPH_ATTRIBUTE_COMBINE_IGNORE) { continue; } newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); if (!newrec) { IGRAPH_ERROR("Cannot combine edge attributes", IGRAPH_ENOMEM); } newrec->name = strdup(name); newrec->type = type; VECTOR(*new_eal)[j] = newrec; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { switch (todo) { case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: IGRAPH_CHECK(igraph_i_cattributes_cn_func(oldrec, newrec, merges, numfunc)); break; case IGRAPH_ATTRIBUTE_COMBINE_SUM: IGRAPH_CHECK(igraph_i_cattributes_cn_sum(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_PROD: IGRAPH_CHECK(igraph_i_cattributes_cn_prod(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MIN: IGRAPH_CHECK(igraph_i_cattributes_cn_min(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MAX: IGRAPH_CHECK(igraph_i_cattributes_cn_max(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: IGRAPH_CHECK(igraph_i_cattributes_cn_random(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_FIRST: IGRAPH_CHECK(igraph_i_cattributes_cn_first(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_LAST: IGRAPH_CHECK(igraph_i_cattributes_cn_last(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MEAN: IGRAPH_CHECK(igraph_i_cattributes_cn_mean(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: IGRAPH_ERROR("Median calculation not implemented", IGRAPH_UNIMPLEMENTED); break; case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: IGRAPH_ERROR("Cannot concatenate numeric attributes", IGRAPH_EATTRCOMBINE); break; default: IGRAPH_ERROR("Unknown attribute_combination", IGRAPH_UNIMPLEMENTED); break; } } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { switch (todo) { case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: IGRAPH_CHECK(igraph_i_cattributes_cb_func(oldrec, newrec, merges, boolfunc)); break; case IGRAPH_ATTRIBUTE_COMBINE_SUM: case IGRAPH_ATTRIBUTE_COMBINE_MAX: IGRAPH_CHECK(igraph_i_cattributes_cb_any_is_true(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_PROD: case IGRAPH_ATTRIBUTE_COMBINE_MIN: IGRAPH_CHECK(igraph_i_cattributes_cb_all_is_true(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MEAN: case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: IGRAPH_CHECK(igraph_i_cattributes_cb_majority(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: IGRAPH_CHECK(igraph_i_cattributes_cb_random(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_FIRST: IGRAPH_CHECK(igraph_i_cattributes_cb_first(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_LAST: IGRAPH_CHECK(igraph_i_cattributes_cb_last(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: IGRAPH_ERROR("Cannot calculate concatenation of Booleans", IGRAPH_EATTRCOMBINE); break; default: IGRAPH_ERROR("Unknown attribute_combination", IGRAPH_UNIMPLEMENTED); break; } } else if (type == IGRAPH_ATTRIBUTE_STRING) { switch (todo) { case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: IGRAPH_CHECK(igraph_i_cattributes_sn_func(oldrec, newrec, merges, strfunc)); break; case IGRAPH_ATTRIBUTE_COMBINE_SUM: IGRAPH_ERROR("Cannot sum strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_PROD: IGRAPH_ERROR("Cannot multiply strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_MIN: IGRAPH_ERROR("Cannot find minimum of strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_MAX: IGRAPH_ERROR("Cannot find maximum of strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_MEAN: IGRAPH_ERROR("Cannot calculate mean of strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: IGRAPH_ERROR("Cannot calculate median of strings", IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: IGRAPH_CHECK(igraph_i_cattributes_sn_random(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_FIRST: IGRAPH_CHECK(igraph_i_cattributes_sn_first(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_LAST: IGRAPH_CHECK(igraph_i_cattributes_sn_last(oldrec, newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: IGRAPH_CHECK(igraph_i_cattributes_sn_concat(oldrec, newrec, merges)); break; default: IGRAPH_ERROR("Unknown attribute_combination", IGRAPH_UNIMPLEMENTED); break; } } else { IGRAPH_ERROR("Unknown attribute type, this should not happen", IGRAPH_UNIMPLEMENTED); } j++; } igraph_free(funcs); igraph_free(TODO); IGRAPH_FINALLY_CLEAN(3); return 0; } static int igraph_i_cattribute_get_info(const igraph_t *graph, igraph_strvector_t *gnames, igraph_vector_t *gtypes, igraph_strvector_t *vnames, igraph_vector_t *vtypes, igraph_strvector_t *enames, igraph_vector_t *etypes) { igraph_strvector_t *names[3] = { gnames, vnames, enames }; igraph_vector_t *types[3] = { gtypes, vtypes, etypes }; igraph_i_cattributes_t *at = graph->attr; igraph_vector_ptr_t *attr[3] = { &at->gal, &at->val, &at->eal }; long int i, j; for (i = 0; i < 3; i++) { igraph_strvector_t *n = names[i]; igraph_vector_t *t = types[i]; igraph_vector_ptr_t *al = attr[i]; long int len = igraph_vector_ptr_size(al); if (n) { IGRAPH_CHECK(igraph_strvector_resize(n, len)); } if (t) { IGRAPH_CHECK(igraph_vector_resize(t, len)); } for (j = 0; j < len; j++) { igraph_attribute_record_t *rec = VECTOR(*al)[j]; const char *name = rec->name; igraph_attribute_type_t type = rec->type; if (n) { IGRAPH_CHECK(igraph_strvector_set(n, j, name)); } if (t) { VECTOR(*t)[j] = type; } } } return 0; } static igraph_bool_t igraph_i_cattribute_has_attr(const igraph_t *graph, igraph_attribute_elemtype_t type, const char *name) { igraph_i_cattributes_t *at = graph->attr; igraph_vector_ptr_t *attr[3] = { &at->gal, &at->val, &at->eal }; long int attrnum; switch (type) { case IGRAPH_ATTRIBUTE_GRAPH: attrnum = 0; break; case IGRAPH_ATTRIBUTE_VERTEX: attrnum = 1; break; case IGRAPH_ATTRIBUTE_EDGE: attrnum = 2; break; default: IGRAPH_ERROR("Unknown attribute element type", IGRAPH_EINVAL); break; } return igraph_i_cattribute_find(attr[attrnum], name, 0); } static int igraph_i_cattribute_gettype(const igraph_t *graph, igraph_attribute_type_t *type, igraph_attribute_elemtype_t elemtype, const char *name) { long int attrnum; igraph_attribute_record_t *rec; igraph_i_cattributes_t *at = graph->attr; igraph_vector_ptr_t *attr[3] = { &at->gal, &at->val, &at->eal }; igraph_vector_ptr_t *al; long int j; igraph_bool_t l = 0; switch (elemtype) { case IGRAPH_ATTRIBUTE_GRAPH: attrnum = 0; break; case IGRAPH_ATTRIBUTE_VERTEX: attrnum = 1; break; case IGRAPH_ATTRIBUTE_EDGE: attrnum = 2; break; default: IGRAPH_ERROR("Unknown attribute element type", IGRAPH_EINVAL); break; } al = attr[attrnum]; l = igraph_i_cattribute_find(al, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*al)[j]; *type = rec->type; return 0; } static int igraph_i_cattribute_get_numeric_graph_attr(const igraph_t *graph, const char *name, igraph_vector_t *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_attribute_record_t *rec; igraph_vector_t *num; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*gal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_ERROR("Numeric graph attribute expected.", IGRAPH_EINVAL); } num = (igraph_vector_t*)rec->value; IGRAPH_CHECK(igraph_vector_resize(value, 1)); VECTOR(*value)[0] = VECTOR(*num)[0]; return 0; } static int igraph_i_cattribute_get_bool_graph_attr(const igraph_t *graph, const char *name, igraph_vector_bool_t *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*gal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_ERROR("Boolean graph attribute expected.", IGRAPH_EINVAL); } log = (igraph_vector_bool_t*)rec->value; IGRAPH_CHECK(igraph_vector_bool_resize(value, 1)); VECTOR(*value)[0] = VECTOR(*log)[0]; return 0; } static int igraph_i_cattribute_get_string_graph_attr(const igraph_t *graph, const char *name, igraph_strvector_t *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_attribute_record_t *rec; igraph_strvector_t *str; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*gal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_ERROR("String graph attribute expected.", IGRAPH_EINVAL); } str = (igraph_strvector_t*)rec->value; IGRAPH_CHECK(igraph_strvector_resize(value, 1)); IGRAPH_CHECK(igraph_strvector_set(value, 0, STR(*str, 0))); return 0; } static int igraph_i_cattribute_get_numeric_vertex_attr(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_vector_t *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_attribute_record_t *rec; igraph_vector_t *num; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*val)[j]; if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_ERROR("Numeric vertex attribute expected.", IGRAPH_EINVAL); } num = (igraph_vector_t*)rec->value; if (igraph_vs_is_all(&vs)) { igraph_vector_clear(value); IGRAPH_CHECK(igraph_vector_append(value, num)); } else { igraph_vit_t it; long int i = 0; IGRAPH_CHECK(igraph_vit_create(graph, vs, &it)); IGRAPH_FINALLY(igraph_vit_destroy, &it); IGRAPH_CHECK(igraph_vector_resize(value, IGRAPH_VIT_SIZE(it))); for (; !IGRAPH_VIT_END(it); IGRAPH_VIT_NEXT(it), i++) { long int v = IGRAPH_VIT_GET(it); VECTOR(*value)[i] = VECTOR(*num)[v]; } igraph_vit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); } return 0; } static int igraph_i_cattribute_get_bool_vertex_attr(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_vector_bool_t *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; igraph_vit_t it; long int i, j, v; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*val)[j]; if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_ERROR("Boolean vertex attribute expected.", IGRAPH_EINVAL); } log = (igraph_vector_bool_t*)rec->value; if (igraph_vs_is_all(&vs)) { igraph_vector_bool_clear(value); IGRAPH_CHECK(igraph_vector_bool_append(value, log)); } else { IGRAPH_CHECK(igraph_vit_create(graph, vs, &it)); IGRAPH_FINALLY(igraph_vit_destroy, &it); IGRAPH_CHECK(igraph_vector_bool_resize(value, IGRAPH_VIT_SIZE(it))); for (i = 0; !IGRAPH_VIT_END(it); IGRAPH_VIT_NEXT(it), i++) { v = IGRAPH_VIT_GET(it); VECTOR(*value)[i] = VECTOR(*log)[v]; } igraph_vit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); } return 0; } static int igraph_i_cattribute_get_string_vertex_attr(const igraph_t *graph, const char *name, igraph_vs_t vs, igraph_strvector_t *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_attribute_record_t *rec; igraph_strvector_t *str; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*val)[j]; if (rec->type != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_ERROR("String vertex attribute expected.", IGRAPH_EINVAL); } str = (igraph_strvector_t*)rec->value; if (igraph_vs_is_all(&vs)) { igraph_strvector_resize(value, 0); IGRAPH_CHECK(igraph_strvector_append(value, str)); } else { igraph_vit_t it; long int i = 0; IGRAPH_CHECK(igraph_vit_create(graph, vs, &it)); IGRAPH_FINALLY(igraph_vit_destroy, &it); IGRAPH_CHECK(igraph_strvector_resize(value, IGRAPH_VIT_SIZE(it))); for (; !IGRAPH_VIT_END(it); IGRAPH_VIT_NEXT(it), i++) { long int v = IGRAPH_VIT_GET(it); char *s; igraph_strvector_get(str, v, &s); IGRAPH_CHECK(igraph_strvector_set(value, i, s)); } igraph_vit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); } return 0; } static int igraph_i_cattribute_get_numeric_edge_attr(const igraph_t *graph, const char *name, igraph_es_t es, igraph_vector_t *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_attribute_record_t *rec; igraph_vector_t *num; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*eal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_ERROR("Numeric edge attribute expected.", IGRAPH_EINVAL); } num = (igraph_vector_t*)rec->value; if (igraph_es_is_all(&es)) { igraph_vector_clear(value); IGRAPH_CHECK(igraph_vector_append(value, num)); } else { igraph_eit_t it; long int i = 0; IGRAPH_CHECK(igraph_eit_create(graph, es, &it)); IGRAPH_FINALLY(igraph_eit_destroy, &it); IGRAPH_CHECK(igraph_vector_resize(value, IGRAPH_EIT_SIZE(it))); for (; !IGRAPH_EIT_END(it); IGRAPH_EIT_NEXT(it), i++) { long int e = IGRAPH_EIT_GET(it); VECTOR(*value)[i] = VECTOR(*num)[e]; } igraph_eit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); } return 0; } static int igraph_i_cattribute_get_string_edge_attr(const igraph_t *graph, const char *name, igraph_es_t es, igraph_strvector_t *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_attribute_record_t *rec; igraph_strvector_t *str; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*eal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_ERROR("String edge attribute expected.", IGRAPH_EINVAL); } str = (igraph_strvector_t*)rec->value; if (igraph_es_is_all(&es)) { igraph_strvector_resize(value, 0); IGRAPH_CHECK(igraph_strvector_append(value, str)); } else { igraph_eit_t it; long int i = 0; IGRAPH_CHECK(igraph_eit_create(graph, es, &it)); IGRAPH_FINALLY(igraph_eit_destroy, &it); IGRAPH_CHECK(igraph_strvector_resize(value, IGRAPH_EIT_SIZE(it))); for (; !IGRAPH_EIT_END(it); IGRAPH_EIT_NEXT(it), i++) { long int e = IGRAPH_EIT_GET(it); char *s; igraph_strvector_get(str, e, &s); IGRAPH_CHECK(igraph_strvector_set(value, i, s)); } igraph_eit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); } return 0; } static int igraph_i_cattribute_get_bool_edge_attr(const igraph_t *graph, const char *name, igraph_es_t es, igraph_vector_bool_t *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (!l) { IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); } rec = VECTOR(*eal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_ERROR("Boolean edge attribute expected.", IGRAPH_EINVAL); } log = (igraph_vector_bool_t*)rec->value; if (igraph_es_is_all(&es)) { igraph_vector_bool_clear(value); IGRAPH_CHECK(igraph_vector_bool_append(value, log)); } else { igraph_eit_t it; long int i = 0; IGRAPH_CHECK(igraph_eit_create(graph, es, &it)); IGRAPH_FINALLY(igraph_eit_destroy, &it); IGRAPH_CHECK(igraph_vector_bool_resize(value, IGRAPH_EIT_SIZE(it))); for (; !IGRAPH_EIT_END(it); IGRAPH_EIT_NEXT(it), i++) { long int e = IGRAPH_EIT_GET(it); VECTOR(*value)[i] = VECTOR(*log)[e]; } igraph_eit_destroy(&it); IGRAPH_FINALLY_CLEAN(1); } return 0; } /* -------------------------------------- */ const igraph_attribute_table_t igraph_cattribute_table = { &igraph_i_cattribute_init, &igraph_i_cattribute_destroy, &igraph_i_cattribute_copy, &igraph_i_cattribute_add_vertices, &igraph_i_cattribute_permute_vertices, &igraph_i_cattribute_combine_vertices, &igraph_i_cattribute_add_edges, &igraph_i_cattribute_permute_edges, &igraph_i_cattribute_combine_edges, &igraph_i_cattribute_get_info, &igraph_i_cattribute_has_attr, &igraph_i_cattribute_gettype, &igraph_i_cattribute_get_numeric_graph_attr, &igraph_i_cattribute_get_string_graph_attr, &igraph_i_cattribute_get_bool_graph_attr, &igraph_i_cattribute_get_numeric_vertex_attr, &igraph_i_cattribute_get_string_vertex_attr, &igraph_i_cattribute_get_bool_vertex_attr, &igraph_i_cattribute_get_numeric_edge_attr, &igraph_i_cattribute_get_string_edge_attr, &igraph_i_cattribute_get_bool_edge_attr }; /* -------------------------------------- */ /** * \section cattributes * There is an experimental attribute handler that can be used * from C code. In this section we show how this works. This attribute * handler is by default not attached (the default is no attribute * handler), so we first need to attach it: * * igraph_set_attribute_table(&igraph_cattribute_table); * * * Now the attribute functions are available. Please note that * the attribute handler must be attached before you call any other * igraph functions, otherwise you might end up with graphs without * attributes and an active attribute handler, which might cause * unexpected program behaviour. The rule is that you attach the * attribute handler in the beginning of your * main() and never touch it again. (Detaching * the attribute handler might lead to memory leaks.) * * It is not currently possible to have attribute handlers on a * per-graph basis. All graphs in an application must be managed with * the same attribute handler. (Including the default case when there * is no attribute handler at all. * * The C attribute handler supports attaching real numbers and * character strings as attributes. No vectors are allowed, i.e. every * vertex might have an attribute called name, but it is * not possible to have a coords graph (or other) * attribute which is a vector of numbers. * * \example examples/simple/cattributes.c * \example examples/simple/cattributes2.c * \example examples/simple/cattributes3.c * \example examples/simple/cattributes4.c */ /** * \function igraph_cattribute_GAN * Query a numeric graph attribute. * * Returns the value of the given numeric graph attribute. * The attribute must exist, otherwise an error is triggered. * \param graph The input graph. * \param name The name of the attribute to query. * \return The value of the attribute. * * \sa \ref GAN for a simpler interface. * * Time complexity: O(Ag), the number of graph attributes. */ igraph_real_t igraph_cattribute_GAN(const igraph_t *graph, const char *name) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_attribute_record_t *rec; igraph_vector_t *num; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (!l) { igraph_error("Unknown attribute", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return 0; } rec = VECTOR(*gal)[j]; num = (igraph_vector_t*)rec->value; return VECTOR(*num)[0]; } /** * \function igraph_cattribute_GAB * Query a boolean graph attribute. * * Returns the value of the given numeric graph attribute. * The attribute must exist, otherwise an error is triggered. * \param graph The input graph. * \param name The name of the attribute to query. * \return The value of the attribute. * * \sa \ref GAB for a simpler interface. * * Time complexity: O(Ag), the number of graph attributes. */ igraph_bool_t igraph_cattribute_GAB(const igraph_t *graph, const char *name) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (!l) { igraph_error("Unknown attribute", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return 0; } rec = VECTOR(*gal)[j]; log = (igraph_vector_bool_t*)rec->value; return VECTOR(*log)[0]; } /** * \function igraph_cattribute_GAS * Query a string graph attribute. * * Returns a const pointer to the string graph attribute * specified in \p name. * The attribute must exist, otherwise an error is triggered. * \param graph The input graph. * \param name The name of the attribute to query. * \return The value of the attribute. * * \sa \ref GAS for a simpler interface. * * Time complexity: O(Ag), the number of graph attributes. */ const char* igraph_cattribute_GAS(const igraph_t *graph, const char *name) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_attribute_record_t *rec; igraph_strvector_t *str; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (!l) { igraph_error("Unknown attribute", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return 0; } rec = VECTOR(*gal)[j]; str = (igraph_strvector_t*)rec->value; return STR(*str, 0); } /** * \function igraph_cattribute_VAN * Query a numeric vertex attribute. * * The attribute must exist, otherwise an error is triggered. * \param graph The input graph. * \param name The name of the attribute. * \param vid The id of the queried vertex. * \return The value of the attribute. * * \sa \ref VAN macro for a simpler interface. * * Time complexity: O(Av), the number of vertex attributes. */ igraph_real_t igraph_cattribute_VAN(const igraph_t *graph, const char *name, igraph_integer_t vid) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_attribute_record_t *rec; igraph_vector_t *num; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (!l) { igraph_error("Unknown attribute", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return 0; } rec = VECTOR(*val)[j]; num = (igraph_vector_t*)rec->value; return VECTOR(*num)[(long int)vid]; } /** * \function igraph_cattribute_VAB * Query a boolean vertex attribute. * * The attribute must exist, otherwise an error is triggered. * \param graph The input graph. * \param name The name of the attribute. * \param vid The id of the queried vertex. * \return The value of the attribute. * * \sa \ref VAB macro for a simpler interface. * * Time complexity: O(Av), the number of vertex attributes. */ igraph_bool_t igraph_cattribute_VAB(const igraph_t *graph, const char *name, igraph_integer_t vid) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (!l) { igraph_error("Unknown attribute", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return 0; } rec = VECTOR(*val)[j]; log = (igraph_vector_bool_t*)rec->value; return VECTOR(*log)[(long int)vid]; } /** * \function igraph_cattribute_VAS * Query a string vertex attribute. * * The attribute must exist, otherwise an error is triggered. * \param graph The input graph. * \param name The name of the attribute. * \param vid The id of the queried vertex. * \return The value of the attribute. * * \sa The macro \ref VAS for a simpler interface. * * Time complexity: O(Av), the number of vertex attributes. */ const char* igraph_cattribute_VAS(const igraph_t *graph, const char *name, igraph_integer_t vid) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_attribute_record_t *rec; igraph_strvector_t *str; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (!l) { igraph_error("Unknown attribute", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return 0; } rec = VECTOR(*val)[j]; str = (igraph_strvector_t*)rec->value; return STR(*str, (long int)vid); } /** * \function igraph_cattribute_EAN * Query a numeric edge attribute. * * The attribute must exist, otherwise an error is triggered. * \param graph The input graph. * \param name The name of the attribute. * \param eid The id of the queried edge. * \return The value of the attribute. * * \sa \ref EAN for an easier interface. * * Time complexity: O(Ae), the number of edge attributes. */ igraph_real_t igraph_cattribute_EAN(const igraph_t *graph, const char *name, igraph_integer_t eid) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_attribute_record_t *rec; igraph_vector_t *num; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (!l) { igraph_error("Unknown attribute", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return 0; } rec = VECTOR(*eal)[j]; num = (igraph_vector_t*)rec->value; return VECTOR(*num)[(long int)eid]; } /** * \function igraph_cattribute_EAB * Query a boolean edge attribute. * * The attribute must exist, otherwise an error is triggered. * \param graph The input graph. * \param name The name of the attribute. * \param eid The id of the queried edge. * \return The value of the attribute. * * \sa \ref EAB for an easier interface. * * Time complexity: O(Ae), the number of edge attributes. */ igraph_bool_t igraph_cattribute_EAB(const igraph_t *graph, const char *name, igraph_integer_t eid) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (!l) { igraph_error("Unknown attribute", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return 0; } rec = VECTOR(*eal)[j]; log = (igraph_vector_bool_t*)rec->value; return VECTOR(*log)[(long int)eid]; } /** * \function igraph_cattribute_EAS * Query a string edge attribute. * * The attribute must exist, otherwise an error is triggered. * \param graph The input graph. * \param name The name of the attribute. * \param eid The id of the queried edge. * \return The value of the attribute. * * \se \ref EAS if you want to type less. * * Time complexity: O(Ae), the number of edge attributes. */ const char* igraph_cattribute_EAS(const igraph_t *graph, const char *name, igraph_integer_t eid) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_attribute_record_t *rec; igraph_strvector_t *str; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (!l) { igraph_error("Unknown attribute", IGRAPH_FILE_BASENAME, __LINE__, IGRAPH_EINVAL); return 0; } rec = VECTOR(*eal)[j]; str = (igraph_strvector_t*)rec->value; return STR(*str, (long int)eid); } /** * \function igraph_cattribute_VANV * Query a numeric vertex attribute for many vertices * * \param graph The input graph. * \param name The name of the attribute. * \param vids The vertices to query. * \param result Pointer to an initialized vector, the result is * stored here. It will be resized, if needed. * \return Error code. * * Time complexity: O(v), where v is the number of vertices in 'vids'. */ int igraph_cattribute_VANV(const igraph_t *graph, const char *name, igraph_vs_t vids, igraph_vector_t *result) { return igraph_i_cattribute_get_numeric_vertex_attr(graph, name, vids, result); } /** * \function igraph_cattribute_VABV * Query a boolean vertex attribute for many vertices * * \param graph The input graph. * \param name The name of the attribute. * \param vids The vertices to query. * \param result Pointer to an initialized boolean vector, the result is * stored here. It will be resized, if needed. * \return Error code. * * Time complexity: O(v), where v is the number of vertices in 'vids'. */ int igraph_cattribute_VABV(const igraph_t *graph, const char *name, igraph_vs_t vids, igraph_vector_bool_t *result) { return igraph_i_cattribute_get_bool_vertex_attr(graph, name, vids, result); } /** * \function igraph_cattribute_EANV * Query a numeric edge attribute for many edges * * \param graph The input graph. * \param name The name of the attribute. * \param eids The edges to query. * \param result Pointer to an initialized vector, the result is * stored here. It will be resized, if needed. * \return Error code. * * Time complexity: O(e), where e is the number of edges in 'eids'. */ int igraph_cattribute_EANV(const igraph_t *graph, const char *name, igraph_es_t eids, igraph_vector_t *result) { return igraph_i_cattribute_get_numeric_edge_attr(graph, name, eids, result); } /** * \function igraph_cattribute_EABV * Query a boolean edge attribute for many edges * * \param graph The input graph. * \param name The name of the attribute. * \param eids The edges to query. * \param result Pointer to an initialized boolean vector, the result is * stored here. It will be resized, if needed. * \return Error code. * * Time complexity: O(e), where e is the number of edges in 'eids'. */ int igraph_cattribute_EABV(const igraph_t *graph, const char *name, igraph_es_t eids, igraph_vector_bool_t *result) { return igraph_i_cattribute_get_bool_edge_attr(graph, name, eids, result); } /** * \function igraph_cattribute_VASV * Query a string vertex attribute for many vertices * * \param graph The input graph. * \param name The name of the attribute. * \param vids The vertices to query. * \param result Pointer to an initialized string vector, the result * is stored here. It will be resized, if needed. * \return Error code. * * Time complexity: O(v), where v is the number of vertices in 'vids'. * (We assume that the string attributes have a bounded length.) */ int igraph_cattribute_VASV(const igraph_t *graph, const char *name, igraph_vs_t vids, igraph_strvector_t *result) { return igraph_i_cattribute_get_string_vertex_attr(graph, name, vids, result); } /** * \function igraph_cattribute_EASV * Query a string edge attribute for many edges * * \param graph The input graph. * \param name The name of the attribute. * \param vids The edges to query. * \param result Pointer to an initialized string vector, the result * is stored here. It will be resized, if needed. * \return Error code. * * Time complexity: O(e), where e is the number of edges in * 'eids'. (We assume that the string attributes have a bounded length.) */ int igraph_cattribute_EASV(const igraph_t *graph, const char *name, igraph_es_t eids, igraph_strvector_t *result) { return igraph_i_cattribute_get_string_edge_attr(graph, name, eids, result); } /** * \function igraph_cattribute_list * List all attributes * * See \ref igraph_attribute_type_t for the various attribute types. * \param graph The input graph. * \param gnames String vector, the names of the graph attributes. * \param gtypes Numeric vector, the types of the graph attributes. * \param vnames String vector, the names of the vertex attributes. * \param vtypes Numeric vector, the types of the vertex attributes. * \param enames String vector, the names of the edge attributes. * \param etypes Numeric vector, the types of the edge attributes. * \return Error code. * * Naturally, the string vector with the attribute names and the * numeric vector with the attribute types are in the right order, * i.e. the first name corresponds to the first type, etc. * * Time complexity: O(Ag+Av+Ae), the number of all attributes. */ int igraph_cattribute_list(const igraph_t *graph, igraph_strvector_t *gnames, igraph_vector_t *gtypes, igraph_strvector_t *vnames, igraph_vector_t *vtypes, igraph_strvector_t *enames, igraph_vector_t *etypes) { return igraph_i_cattribute_get_info(graph, gnames, gtypes, vnames, vtypes, enames, etypes); } /** * \function igraph_cattribute_has_attr * Checks whether a (graph, vertex or edge) attribute exists * * \param graph The graph. * \param type The type of the attribute, \c IGRAPH_ATTRIBUTE_GRAPH, * \c IGRAPH_ATTRIBUTE_VERTEX or \c IGRAPH_ATTRIBUTE_EDGE. * \param name Character constant, the name of the attribute. * \return Logical value, TRUE if the attribute exists, FALSE otherwise. * * Time complexity: O(A), the number of (graph, vertex or edge) * attributes, assuming attribute names are not too long. */ igraph_bool_t igraph_cattribute_has_attr(const igraph_t *graph, igraph_attribute_elemtype_t type, const char *name) { return igraph_i_cattribute_has_attr(graph, type, name); } /** * \function igraph_cattribute_GAN_set * Set a numeric graph attribute * * \param graph The graph. * \param name Name of the graph attribute. If there is no such * attribute yet, then it will be added. * \param value The (new) value of the graph attribute. * \return Error code. * * \se \ref SETGAN if you want to type less. * * Time complexity: O(1). */ int igraph_cattribute_GAN_set(igraph_t *graph, const char *name, igraph_real_t value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (l) { igraph_attribute_record_t *rec = VECTOR(*gal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); } else { igraph_vector_t *num = (igraph_vector_t *)rec->value; VECTOR(*num)[0] = value; } } else { igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_t *num; if (!rec) { IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); rec->type = IGRAPH_ATTRIBUTE_NUMERIC; num = IGRAPH_CALLOC(1, igraph_vector_t); if (!num) { IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, num); IGRAPH_VECTOR_INIT_FINALLY(num, 1); VECTOR(*num)[0] = value; rec->value = num; IGRAPH_CHECK(igraph_vector_ptr_push_back(gal, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_GAB_set * Set a boolean graph attribute * * \param graph The graph. * \param name Name of the graph attribute. If there is no such * attribute yet, then it will be added. * \param value The (new) value of the graph attribute. * \return Error code. * * \se \ref SETGAN if you want to type less. * * Time complexity: O(1). */ int igraph_cattribute_GAB_set(igraph_t *graph, const char *name, igraph_bool_t value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (l) { igraph_attribute_record_t *rec = VECTOR(*gal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); } else { igraph_vector_bool_t *log = (igraph_vector_bool_t *)rec->value; VECTOR(*log)[0] = value; } } else { igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_bool_t *log; if (!rec) { IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; log = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!log) { IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, log); IGRAPH_CHECK(igraph_vector_bool_init(log, 1)); IGRAPH_FINALLY(igraph_vector_bool_destroy, log); VECTOR(*log)[0] = value; rec->value = log; IGRAPH_CHECK(igraph_vector_ptr_push_back(gal, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_GAS_set * Set a string graph attribute. * * \param graph The graph. * \param name Name of the graph attribute. If there is no such * attribute yet, then it will be added. * \param value The (new) value of the graph attribute. It will be * copied. * \return Error code. * * \se \ref SETGAS if you want to type less. * * Time complexity: O(1). */ int igraph_cattribute_GAS_set(igraph_t *graph, const char *name, const char *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (l) { igraph_attribute_record_t *rec = VECTOR(*gal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); } else { igraph_strvector_t *str = (igraph_strvector_t*)rec->value; IGRAPH_CHECK(igraph_strvector_set(str, 0, value)); } } else { igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_strvector_t *str; if (!rec) { IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); rec->type = IGRAPH_ATTRIBUTE_STRING; str = IGRAPH_CALLOC(1, igraph_strvector_t); if (!str) { IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, str); IGRAPH_STRVECTOR_INIT_FINALLY(str, 1); IGRAPH_CHECK(igraph_strvector_set(str, 0, value)); rec->value = str; IGRAPH_CHECK(igraph_vector_ptr_push_back(gal, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_VAN_set * Set a numeric vertex attribute * * The attribute will be added if not present already. If present it * will be overwritten. The same \p value is set for all vertices * included in \p vid. * \param graph The graph. * \param name Name of the attribute. * \param vid Vertices for which to set the attribute. * \param value The (new) value of the attribute. * \return Error code. * * \sa \ref SETVAN for a simpler way. * * Time complexity: O(n), the number of vertices if the attribute is * new, O(|vid|) otherwise. */ int igraph_cattribute_VAN_set(igraph_t *graph, const char *name, igraph_integer_t vid, igraph_real_t value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (l) { igraph_attribute_record_t *rec = VECTOR(*val)[j]; if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); } else { igraph_vector_t *num = (igraph_vector_t*)rec->value; VECTOR(*num)[(long int)vid] = value; } } else { igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_t *num; if (!rec) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); rec->type = IGRAPH_ATTRIBUTE_NUMERIC; num = IGRAPH_CALLOC(1, igraph_vector_t); if (!num) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, num); IGRAPH_VECTOR_INIT_FINALLY(num, igraph_vcount(graph)); igraph_vector_fill(num, IGRAPH_NAN); VECTOR(*num)[(long int)vid] = value; rec->value = num; IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_VAB_set * Set a boolean vertex attribute * * The attribute will be added if not present already. If present it * will be overwritten. The same \p value is set for all vertices * included in \p vid. * \param graph The graph. * \param name Name of the attribute. * \param vid Vertices for which to set the attribute. * \param value The (new) value of the attribute. * \return Error code. * * \sa \ref SETVAB for a simpler way. * * Time complexity: O(n), the number of vertices if the attribute is * new, O(|vid|) otherwise. */ int igraph_cattribute_VAB_set(igraph_t *graph, const char *name, igraph_integer_t vid, igraph_bool_t value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (l) { igraph_attribute_record_t *rec = VECTOR(*val)[j]; if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); } else { igraph_vector_bool_t *log = (igraph_vector_bool_t*)rec->value; VECTOR(*log)[(long int)vid] = value; } } else { igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_bool_t *log; if (!rec) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; log = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!log) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, log); IGRAPH_CHECK(igraph_vector_bool_init(log, igraph_vcount(graph))); IGRAPH_FINALLY(igraph_vector_bool_destroy, log); igraph_vector_bool_fill(log, 0); VECTOR(*log)[(long int)vid] = value; rec->value = log; IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_VAS_set * Set a string vertex attribute * * The attribute will be added if not present already. If present it * will be overwritten. The same \p value is set for all vertices * included in \p vid. * \param graph The graph. * \param name Name of the attribute. * \param vid Vertices for which to set the attribute. * \param value The (new) value of the attribute. * \return Error code. * * \sa \ref SETVAS for a simpler way. * * Time complexity: O(n*l), n is the number of vertices, l is the * length of the string to set. If the attribute if not new then only * O(|vid|*l). */ int igraph_cattribute_VAS_set(igraph_t *graph, const char *name, igraph_integer_t vid, const char *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (l) { igraph_attribute_record_t *rec = VECTOR(*val)[j]; if (rec->type != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); } else { igraph_strvector_t *str = (igraph_strvector_t*)rec->value; IGRAPH_CHECK(igraph_strvector_set(str, vid, value)); } } else { igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_strvector_t *str; if (!rec) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); rec->type = IGRAPH_ATTRIBUTE_STRING; str = IGRAPH_CALLOC(1, igraph_strvector_t); if (!str) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, str); IGRAPH_STRVECTOR_INIT_FINALLY(str, igraph_vcount(graph)); IGRAPH_CHECK(igraph_strvector_set(str, vid, value)); rec->value = str; IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_EAN_set * Set a numeric edge attribute * * The attribute will be added if not present already. If present it * will be overwritten. The same \p value is set for all edges * included in \p vid. * \param graph The graph. * \param name Name of the attribute. * \param eid Edges for which to set the attribute. * \param value The (new) value of the attribute. * \return Error code. * * \sa \ref SETEAN for a simpler way. * * Time complexity: O(e), the number of edges if the attribute is * new, O(|eid|) otherwise. */ int igraph_cattribute_EAN_set(igraph_t *graph, const char *name, igraph_integer_t eid, igraph_real_t value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (l) { igraph_attribute_record_t *rec = VECTOR(*eal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); } else { igraph_vector_t *num = (igraph_vector_t*)rec->value; VECTOR(*num)[(long int)eid] = value; } } else { igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_t *num; if (!rec) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); rec->type = IGRAPH_ATTRIBUTE_NUMERIC; num = IGRAPH_CALLOC(1, igraph_vector_t); if (!num) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, num); IGRAPH_VECTOR_INIT_FINALLY(num, igraph_ecount(graph)); igraph_vector_fill(num, IGRAPH_NAN); VECTOR(*num)[(long int)eid] = value; rec->value = num; IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_EAB_set * Set a boolean edge attribute * * The attribute will be added if not present already. If present it * will be overwritten. The same \p value is set for all edges * included in \p vid. * \param graph The graph. * \param name Name of the attribute. * \param eid Edges for which to set the attribute. * \param value The (new) value of the attribute. * \return Error code. * * \sa \ref SETEAB for a simpler way. * * Time complexity: O(e), the number of edges if the attribute is * new, O(|eid|) otherwise. */ int igraph_cattribute_EAB_set(igraph_t *graph, const char *name, igraph_integer_t eid, igraph_bool_t value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (l) { igraph_attribute_record_t *rec = VECTOR(*eal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); } else { igraph_vector_bool_t *log = (igraph_vector_bool_t*)rec->value; VECTOR(*log)[(long int)eid] = value; } } else { igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_bool_t *log; if (!rec) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; log = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!log) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, log); IGRAPH_CHECK(igraph_vector_bool_init(log, igraph_ecount(graph))); IGRAPH_FINALLY(igraph_vector_bool_destroy, log); igraph_vector_bool_fill(log, 0); VECTOR(*log)[(long int)eid] = value; rec->value = log; IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_EAS_set * Set a string edge attribute * * The attribute will be added if not present already. If present it * will be overwritten. The same \p value is set for all edges * included in \p vid. * \param graph The graph. * \param name Name of the attribute. * \param eid Edges for which to set the attribute. * \param value The (new) value of the attribute. * \return Error code. * * \sa \ref SETEAS for a simpler way. * * Time complexity: O(e*l), n is the number of edges, l is the * length of the string to set. If the attribute if not new then only * O(|eid|*l). */ int igraph_cattribute_EAS_set(igraph_t *graph, const char *name, igraph_integer_t eid, const char *value) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (l) { igraph_attribute_record_t *rec = VECTOR(*eal)[j]; if (rec->type != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); } else { igraph_strvector_t *str = (igraph_strvector_t*)rec->value; IGRAPH_CHECK(igraph_strvector_set(str, eid, value)); } } else { igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_strvector_t *str; if (!rec) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); rec->type = IGRAPH_ATTRIBUTE_STRING; str = IGRAPH_CALLOC(1, igraph_strvector_t); if (!str) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, str); IGRAPH_STRVECTOR_INIT_FINALLY(str, igraph_ecount(graph)); IGRAPH_CHECK(igraph_strvector_set(str, eid, value)); rec->value = str; IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_VAN_setv * Set a numeric vertex attribute for all vertices. * * The attribute will be added if not present yet. * \param graph The graph. * \param name Name of the attribute. * \param v The new attribute values. The length of this vector must * match the number of vertices. * \return Error code. * * \sa \ref SETVANV for a simpler way. * * Time complexity: O(n), the number of vertices. */ int igraph_cattribute_VAN_setv(igraph_t *graph, const char *name, const igraph_vector_t *v) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); /* Check length first */ if (igraph_vector_size(v) != igraph_vcount(graph)) { IGRAPH_ERROR("Invalid vertex attribute vector length", IGRAPH_EINVAL); } if (l) { /* Already present, check type */ igraph_attribute_record_t *rec = VECTOR(*val)[j]; igraph_vector_t *num = (igraph_vector_t *)rec->value; if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); } igraph_vector_clear(num); IGRAPH_CHECK(igraph_vector_append(num, v)); } else { /* Add it */ igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_t *num; if (!rec) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->type = IGRAPH_ATTRIBUTE_NUMERIC; rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); num = IGRAPH_CALLOC(1, igraph_vector_t); if (!num) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, num); rec->value = num; IGRAPH_CHECK(igraph_vector_copy(num, v)); IGRAPH_FINALLY(igraph_vector_destroy, num); IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_VAB_setv * Set a boolean vertex attribute for all vertices. * * The attribute will be added if not present yet. * \param graph The graph. * \param name Name of the attribute. * \param v The new attribute values. The length of this boolean vector must * match the number of vertices. * \return Error code. * * \sa \ref SETVANV for a simpler way. * * Time complexity: O(n), the number of vertices. */ int igraph_cattribute_VAB_setv(igraph_t *graph, const char *name, const igraph_vector_bool_t *v) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); /* Check length first */ if (igraph_vector_bool_size(v) != igraph_vcount(graph)) { IGRAPH_ERROR("Invalid vertex attribute vector length", IGRAPH_EINVAL); } if (l) { /* Already present, check type */ igraph_attribute_record_t *rec = VECTOR(*val)[j]; igraph_vector_bool_t *log = (igraph_vector_bool_t *)rec->value; if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); } igraph_vector_bool_clear(log); IGRAPH_CHECK(igraph_vector_bool_append(log, v)); } else { /* Add it */ igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_bool_t *log; if (!rec) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); log = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!log) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, log); rec->value = log; IGRAPH_CHECK(igraph_vector_bool_copy(log, v)); IGRAPH_FINALLY(igraph_vector_bool_destroy, log); IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_VAS_setv * Set a string vertex attribute for all vertices. * * The attribute will be added if not present yet. * \param graph The graph. * \param name Name of the attribute. * \param sv String vector, the new attribute values. The length of this vector must * match the number of vertices. * \return Error code. * * \sa \ref SETVASV for a simpler way. * * Time complexity: O(n+l), n is the number of vertices, l is the * total length of the strings. */ int igraph_cattribute_VAS_setv(igraph_t *graph, const char *name, const igraph_strvector_t *sv) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); /* Check length first */ if (igraph_strvector_size(sv) != igraph_vcount(graph)) { IGRAPH_ERROR("Invalid vertex attribute vector length", IGRAPH_EINVAL); } if (l) { /* Already present, check type */ igraph_attribute_record_t *rec = VECTOR(*val)[j]; igraph_strvector_t *str = (igraph_strvector_t *)rec->value; if (rec->type != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); } igraph_strvector_clear(str); IGRAPH_CHECK(igraph_strvector_append(str, sv)); } else { /* Add it */ igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_strvector_t *str; if (!rec) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->type = IGRAPH_ATTRIBUTE_STRING; rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); str = IGRAPH_CALLOC(1, igraph_strvector_t); if (!str) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, str); rec->value = str; IGRAPH_CHECK(igraph_strvector_copy(str, sv)); IGRAPH_FINALLY(igraph_strvector_destroy, str); IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_EAN_setv * Set a numeric edge attribute for all edges. * * The attribute will be added if not present yet. * \param graph The graph. * \param name Name of the attribute. * \param v The new attribute values. The length of this vector must * match the number of edges. * \return Error code. * * \sa \ref SETEANV for a simpler way. * * Time complexity: O(e), the number of edges. */ int igraph_cattribute_EAN_setv(igraph_t *graph, const char *name, const igraph_vector_t *v) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); /* Check length first */ if (igraph_vector_size(v) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid edge attribute vector length", IGRAPH_EINVAL); } if (l) { /* Already present, check type */ igraph_attribute_record_t *rec = VECTOR(*eal)[j]; igraph_vector_t *num = (igraph_vector_t *)rec->value; if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); } igraph_vector_clear(num); IGRAPH_CHECK(igraph_vector_append(num, v)); } else { /* Add it */ igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_t *num; if (!rec) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->type = IGRAPH_ATTRIBUTE_NUMERIC; rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); num = IGRAPH_CALLOC(1, igraph_vector_t); if (!num) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, num); rec->value = num; IGRAPH_CHECK(igraph_vector_copy(num, v)); IGRAPH_FINALLY(igraph_vector_destroy, num); IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_EAB_setv * Set a boolean edge attribute for all edges. * * The attribute will be added if not present yet. * \param graph The graph. * \param name Name of the attribute. * \param v The new attribute values. The length of this vector must * match the number of edges. * \return Error code. * * \sa \ref SETEABV for a simpler way. * * Time complexity: O(e), the number of edges. */ int igraph_cattribute_EAB_setv(igraph_t *graph, const char *name, const igraph_vector_bool_t *v) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); /* Check length first */ if (igraph_vector_bool_size(v) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid edge attribute vector length", IGRAPH_EINVAL); } if (l) { /* Already present, check type */ igraph_attribute_record_t *rec = VECTOR(*eal)[j]; igraph_vector_bool_t *log = (igraph_vector_bool_t *)rec->value; if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); } igraph_vector_bool_clear(log); IGRAPH_CHECK(igraph_vector_bool_append(log, v)); } else { /* Add it */ igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_vector_bool_t *log; if (!rec) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); log = IGRAPH_CALLOC(1, igraph_vector_bool_t); if (!log) { IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, log); rec->value = log; IGRAPH_CHECK(igraph_vector_bool_copy(log, v)); IGRAPH_FINALLY(igraph_vector_bool_destroy, log); IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } /** * \function igraph_cattribute_EAS_setv * Set a string edge attribute for all edges. * * The attribute will be added if not present yet. * \param graph The graph. * \param name Name of the attribute. * \param sv String vector, the new attribute values. The length of this vector must * match the number of edges. * \return Error code. * * \sa \ref SETEASV for a simpler way. * * Time complexity: O(e+l), e is the number of edges, l is the * total length of the strings. */ int igraph_cattribute_EAS_setv(igraph_t *graph, const char *name, const igraph_strvector_t *sv) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); /* Check length first */ if (igraph_strvector_size(sv) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid edge attribute vector length", IGRAPH_EINVAL); } if (l) { /* Already present, check type */ igraph_attribute_record_t *rec = VECTOR(*eal)[j]; igraph_strvector_t *str = (igraph_strvector_t *)rec->value; if (rec->type != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); } igraph_strvector_clear(str); IGRAPH_CHECK(igraph_strvector_append(str, sv)); } else { /* Add it */ igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); igraph_strvector_t *str; if (!rec) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, rec); rec->type = IGRAPH_ATTRIBUTE_STRING; rec->name = strdup(name); if (!rec->name) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, (char*)rec->name); str = IGRAPH_CALLOC(1, igraph_strvector_t); if (!str) { IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, str); rec->value = str; IGRAPH_CHECK(igraph_strvector_copy(str, sv)); IGRAPH_FINALLY(igraph_strvector_destroy, str); IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); IGRAPH_FINALLY_CLEAN(4); } return 0; } static void igraph_i_cattribute_free_rec(igraph_attribute_record_t *rec) { if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *num = (igraph_vector_t*)rec->value; igraph_vector_destroy(num); } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *str = (igraph_strvector_t*)rec->value; igraph_strvector_destroy(str); } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { igraph_vector_bool_t *boolvec = (igraph_vector_bool_t*)rec->value; igraph_vector_bool_destroy(boolvec); } IGRAPH_FREE(rec->name); IGRAPH_FREE(rec->value); IGRAPH_FREE(rec); } /** * \function igraph_cattribute_remove_g * Remove a graph attribute * * \param graph The graph object. * \param name Name of the graph attribute to remove. * * \sa \ref DELGA for a simpler way. * */ void igraph_cattribute_remove_g(igraph_t *graph, const char *name) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *gal = &attr->gal; long int j; igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); if (l) { igraph_i_cattribute_free_rec(VECTOR(*gal)[j]); igraph_vector_ptr_remove(gal, j); } else { IGRAPH_WARNING("Cannot remove non-existent graph attribute"); } } /** * \function igraph_cattribute_remove_v * Remove a vertex attribute * * \param graph The graph object. * \param name Name of the vertex attribute to remove. * * \sa \ref DELVA for a simpler way. * */ void igraph_cattribute_remove_v(igraph_t *graph, const char *name) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *val = &attr->val; long int j; igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); if (l) { igraph_i_cattribute_free_rec(VECTOR(*val)[j]); igraph_vector_ptr_remove(val, j); } else { IGRAPH_WARNING("Cannot remove non-existent graph attribute"); } } /** * \function igraph_cattribute_remove_e * Remove an edge attribute * * \param graph The graph object. * \param name Name of the edge attribute to remove. * * \sa \ref DELEA for a simpler way. * */ void igraph_cattribute_remove_e(igraph_t *graph, const char *name) { igraph_i_cattributes_t *attr = graph->attr; igraph_vector_ptr_t *eal = &attr->eal; long int j; igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); if (l) { igraph_i_cattribute_free_rec(VECTOR(*eal)[j]); igraph_vector_ptr_remove(eal, j); } else { IGRAPH_WARNING("Cannot remove non-existent graph attribute"); } } /** * \function igraph_cattribute_remove_all * Remove all graph/vertex/edge attributes * * \param graph The graph object. * \param g Boolean, whether to remove graph attributes. * \param v Boolean, whether to remove vertex attributes. * \param e Boolean, whether to remove edge attributes. * * \sa \ref DELGAS, \ref DELVAS, \ref DELEAS, \ref DELALL for simpler * ways. */ void igraph_cattribute_remove_all(igraph_t *graph, igraph_bool_t g, igraph_bool_t v, igraph_bool_t e) { igraph_i_cattributes_t *attr = graph->attr; if (g) { igraph_vector_ptr_t *gal = &attr->gal; long int i, n = igraph_vector_ptr_size(gal); for (i = 0; i < n; i++) { igraph_i_cattribute_free_rec(VECTOR(*gal)[i]); } igraph_vector_ptr_clear(gal); } if (v) { igraph_vector_ptr_t *val = &attr->val; long int i, n = igraph_vector_ptr_size(val); for (i = 0; i < n; i++) { igraph_i_cattribute_free_rec(VECTOR(*val)[i]); } igraph_vector_ptr_clear(val); } if (e) { igraph_vector_ptr_t *eal = &attr->eal; long int i, n = igraph_vector_ptr_size(eal); for (i = 0; i < n; i++) { igraph_i_cattribute_free_rec(VECTOR(*eal)[i]); } igraph_vector_ptr_clear(eal); } } leidenbase/src/core/graph/neighbors.h0000644000176200001440000000273014447675374017345 0ustar liggesusers/* IGraph library. Copyright (C) 2021 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IGRAPH_NEIGHBORS_H #define IGRAPH_NEIGHBORS_H #include "igraph_constants.h" __BEGIN_DECLS IGRAPH_PRIVATE_EXPORT int igraph_i_neighbors(const igraph_t *graph, igraph_vector_t *neis, igraph_integer_t pnode, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple); IGRAPH_PRIVATE_EXPORT int igraph_i_incident(const igraph_t *graph, igraph_vector_t *eids, igraph_integer_t pnode, igraph_neimode_t mode, igraph_loops_t loops, igraph_multiple_t multiple); __END_DECLS #endif /* IGRAPH_NEIGHBORS_H */ leidenbase/src/Makevars.ucrt0000644000176200001440000002503514457511135015617 0ustar liggesusersLIB_XML ?= $(R_TOOLS_SOFT) GLPK_HOME ?= $(R_TOOLS_SOFT) LIB_GMP ?= $(R_TOOLS_SOFT) PKG_CPPFLAGS = -I${LIB_XML}/include/libxml2 -I${LIB_XML}/include -DLIBXML_STATIC -DUSING_R \ -DHAVE_FMEMOPEN=0 -DHAVE_OPEN_MEMSTREAM=0 -DHAVE_RINTF -DHAVE_STRCASECMP -DWin32 \ -DHAVE_LIBXML=1 -DHAVE_UNISTD_H -Wall -DHAVE_FMIN=1 -DHAVE_LOG2=1 -DHAVE_GFORTRAN \ -DINTERNAL_ARPACK -I${GLPK_HOME}/include -DHAVE_GLPK=1 -DIGRAPH_THREAD_LOCAL= \ -DPRPACK_IGRAPH_SUPPORT -I. -Icore -Iinclude -Ivendor -DNDEBUG -DNTIMER -DNPRINT \ -I${LIB_GMP}/include -Ileidenalg -Ileidenbase PKG_LIBS = -L${LIB_XML}/lib -lxml2 -liconv -lz -lws2_32 -lstdc++ -L${GLPK_HOME}/lib \ -lglpk -lgmp -lgfortran -L$(LIB_GMP)/lib $(BLAS_LIBS) $(LAPACK_LIBS) -llzma # # Debian i386 fix. # # ifneq (,$(filter $(DEB_HOST_ARCH),i386)) # PKG_CPPFLAGS += -ffloat-store # endif OBJECTS=core/centrality/betweenness.o core/centrality/centrality_other.o core/centrality/centralization.o core/centrality/closeness.o core/centrality/coreness.o core/centrality/prpack.o core/centrality/prpack/prpack_base_graph.o core/centrality/prpack/prpack_igraph_graph.o core/centrality/prpack/prpack_preprocessed_ge_graph.o core/centrality/prpack/prpack_preprocessed_gs_graph.o core/centrality/prpack/prpack_preprocessed_scc_graph.o core/centrality/prpack/prpack_preprocessed_schur_graph.o core/centrality/prpack/prpack_result.o core/centrality/prpack/prpack_solver.o core/centrality/prpack/prpack_utils.o core/cliques/cliquer/cliquer.o core/cliques/cliquer/cliquer_graph.o core/cliques/cliquer/reorder.o core/cliques/cliquer_wrapper.o core/cliques/cliques.o core/cliques/glet.o core/cliques/maximal_cliques.o core/community/community_misc.o core/community/edge_betweenness.o core/community/fast_modularity.o core/community/fluid.o core/community/infomap/infomap.o core/community/infomap/infomap_FlowGraph.o core/community/infomap/infomap_Greedy.o core/community/infomap/infomap_Node.o core/community/label_propagation.o core/community/leading_eigenvector.o core/community/leiden.o core/community/louvain.o core/community/modularity.o core/community/optimal_modularity.o core/community/spinglass/NetDataTypes.o core/community/spinglass/NetRoutines.o core/community/spinglass/clustertool.o core/community/spinglass/pottsmodel_2.o core/community/walktrap/walktrap.o core/community/walktrap/walktrap_communities.o core/community/walktrap/walktrap_graph.o core/community/walktrap/walktrap_heap.o core/connectivity/cohesive_blocks.o core/connectivity/components.o core/connectivity/separators.o core/constructors/adjacency.o core/constructors/atlas.o core/constructors/basic_constructors.o core/constructors/de_bruijn.o core/constructors/famous.o core/constructors/full.o core/constructors/kautz.o core/constructors/lcf.o core/constructors/linegraph.o core/constructors/prufer.o core/constructors/regular.o core/core/array.o core/core/buckets.o core/core/cutheap.o core/core/dqueue.o core/core/error.o core/core/estack.o core/core/fixed_vectorlist.o core/core/grid.o core/core/heap.o core/core/indheap.o core/core/interruption.o core/core/marked_queue.o core/core/matrix.o core/core/memory.o core/core/printing.o core/core/progress.o core/core/psumtree.o core/core/set.o core/core/sparsemat.o core/core/spmatrix.o core/core/stack.o core/core/statusbar.o core/core/strvector.o core/core/trie.o core/core/vector.o core/core/vector_ptr.o core/flow/flow.o core/flow/st-cuts.o core/games/barabasi.o core/games/callaway_traits.o core/games/citations.o core/games/correlated.o core/games/degree_sequence.o core/games/degree_sequence_vl/gengraph_box_list.o core/games/degree_sequence_vl/gengraph_degree_sequence.o core/games/degree_sequence_vl/gengraph_graph_molloy_hash.o core/games/degree_sequence_vl/gengraph_graph_molloy_optimized.o core/games/degree_sequence_vl/gengraph_mr-connected.o core/games/degree_sequence_vl/gengraph_powerlaw.o core/games/degree_sequence_vl/gengraph_random.o core/games/dotproduct.o core/games/erdos_renyi.o core/games/establishment.o core/games/forestfire.o core/games/grg.o core/games/growing_random.o core/games/islands.o core/games/k_regular.o core/games/preference.o core/games/recent_degree.o core/games/sbm.o core/games/static_fitness.o core/games/tree.o core/games/watts_strogatz.o core/graph/adjlist.o core/graph/attributes.o core/graph/basic_query.o core/graph/cattributes.o core/graph/iterators.o core/graph/type_indexededgelist.o core/graph/visitors.o core/hrg/hrg.o core/hrg/hrg_types.o core/internal/glpk_support.o core/internal/hacks.o core/internal/lsap.o core/internal/qsort.o core/internal/qsort_r.o core/internal/zeroin.o core/io/dimacs.o core/io/dl-lexer.o core/io/dl-parser.o core/io/dl.o core/io/dot.o core/io/edgelist.o core/io/gml-lexer.o core/io/gml-parser.o core/io/gml-tree.o core/io/gml.o core/io/graphdb.o core/io/graphml.o core/io/leda.o core/io/lgl-lexer.o core/io/lgl-parser.o core/io/lgl.o core/io/ncol-lexer.o core/io/ncol-parser.o core/io/ncol.o core/io/pajek-lexer.o core/io/pajek-parser.o core/io/pajek.o core/isomorphism/bliss.o core/isomorphism/bliss/defs.o core/isomorphism/bliss/graph.o core/isomorphism/bliss/heap.o core/isomorphism/bliss/orbit.o core/isomorphism/bliss/partition.o core/isomorphism/bliss/uintseqhash.o core/isomorphism/bliss/utils.o core/isomorphism/isoclasses.o core/isomorphism/isomorphism_misc.o core/isomorphism/lad.o core/isomorphism/queries.o core/isomorphism/vf2.o core/layout/circular.o core/layout/davidson_harel.o core/layout/drl/DensityGrid.o core/layout/drl/DensityGrid_3d.o core/layout/drl/drl_graph.o core/layout/drl/drl_graph_3d.o core/layout/drl/drl_layout.o core/layout/drl/drl_layout_3d.o core/layout/drl/drl_parse.o core/layout/fruchterman_reingold.o core/layout/gem.o core/layout/graphopt.o core/layout/kamada_kawai.o core/layout/large_graph.o core/layout/layout_bipartite.o core/layout/layout_grid.o core/layout/layout_random.o core/layout/mds.o core/layout/merge_dla.o core/layout/merge_grid.o core/layout/reingold_tilford.o core/layout/sugiyama.o core/linalg/arpack.o core/linalg/blas.o core/linalg/eigen.o core/linalg/lapack.o core/math/bfgs.o core/math/complex.o core/math/utils.o core/misc/bipartite.o core/misc/chordality.o core/misc/cocitation.o core/misc/coloring.o core/misc/conversion.o core/misc/degree_sequence.o core/misc/embedding.o core/misc/feedback_arc_set.o core/misc/graphicality.o core/misc/matching.o core/misc/microscopic_update.o core/misc/mixing.o core/misc/motifs.o core/misc/other.o core/misc/scan.o core/misc/sir.o core/misc/spanning_trees.o core/operators/add_edge.o core/operators/complementer.o core/operators/compose.o core/operators/connect_neighborhood.o core/operators/contract.o core/operators/difference.o core/operators/disjoint_union.o core/operators/intersection.o core/operators/misc_internal.o core/operators/permute.o core/operators/rewire.o core/operators/rewire_edges.o core/operators/simplify.o core/operators/subgraph.o core/operators/union.o core/paths/all_shortest_paths.o core/paths/bellman_ford.o core/paths/dijkstra.o core/paths/distances.o core/paths/eulerian.o core/paths/histogram.o core/paths/johnson.o core/paths/random_walk.o core/paths/shortest_paths.o core/paths/simple_paths.o core/paths/unweighted.o core/properties/basic_properties.o core/properties/constraint.o core/properties/convergence_degree.o core/properties/dag.o core/properties/degrees.o core/properties/girth.o core/properties/loops.o core/properties/multiplicity.o core/properties/neighborhood.o core/properties/spectral.o core/properties/trees.o core/properties/triangles.o core/random/random.o core/scg/scg.o core/scg/scg_approximate_methods.o core/scg/scg_exact_scg.o core/scg/scg_kmeans.o core/scg/scg_optimal_method.o core/scg/scg_utils.o core/version.o vendor/cs/cs_add.o vendor/cs/cs_amd.o vendor/cs/cs_chol.o vendor/cs/cs_cholsol.o vendor/cs/cs_compress.o vendor/cs/cs_counts.o vendor/cs/cs_cumsum.o vendor/cs/cs_dfs.o vendor/cs/cs_dmperm.o vendor/cs/cs_droptol.o vendor/cs/cs_dropzeros.o vendor/cs/cs_dupl.o vendor/cs/cs_entry.o vendor/cs/cs_ereach.o vendor/cs/cs_etree.o vendor/cs/cs_fkeep.o vendor/cs/cs_gaxpy.o vendor/cs/cs_happly.o vendor/cs/cs_house.o vendor/cs/cs_ipvec.o vendor/cs/cs_leaf.o vendor/cs/cs_load.o vendor/cs/cs_lsolve.o vendor/cs/cs_ltsolve.o vendor/cs/cs_lu.o vendor/cs/cs_lusol.o vendor/cs/cs_malloc.o vendor/cs/cs_maxtrans.o vendor/cs/cs_multiply.o vendor/cs/cs_norm.o vendor/cs/cs_permute.o vendor/cs/cs_pinv.o vendor/cs/cs_post.o vendor/cs/cs_print.o vendor/cs/cs_pvec.o vendor/cs/cs_qr.o vendor/cs/cs_qrsol.o vendor/cs/cs_randperm.o vendor/cs/cs_reach.o vendor/cs/cs_scatter.o vendor/cs/cs_scc.o vendor/cs/cs_schol.o vendor/cs/cs_spsolve.o vendor/cs/cs_sqr.o vendor/cs/cs_symperm.o vendor/cs/cs_tdfs.o vendor/cs/cs_transpose.o vendor/cs/cs_updown.o vendor/cs/cs_usolve.o vendor/cs/cs_util.o vendor/cs/cs_utsolve.o vendor/mini-gmp/mini-gmp.o vendor/plfit/gss.o vendor/plfit/hzeta.o vendor/plfit/kolmogorov.o vendor/plfit/lbfgs.o vendor/plfit/mt.o vendor/plfit/options.o vendor/plfit/platform.o vendor/plfit/plfit.o vendor/plfit/plfit_error.o vendor/plfit/rbinom.o vendor/plfit/sampling.o vendor/arpack/dgetv0.o vendor/arpack/dlaqrb.o vendor/arpack/dmout.o vendor/arpack/dnaitr.o vendor/arpack/dnapps.o vendor/arpack/dnaup2.o vendor/arpack/dnaupd.o vendor/arpack/dnconv.o vendor/arpack/dneigh.o vendor/arpack/dneupd.o vendor/arpack/dngets.o vendor/arpack/dsaitr.o vendor/arpack/dsapps.o vendor/arpack/dsaup2.o vendor/arpack/dsaupd.o vendor/arpack/dsconv.o vendor/arpack/dseigt.o vendor/arpack/dsesrt.o vendor/arpack/dseupd.o vendor/arpack/dsgets.o vendor/arpack/dsortc.o vendor/arpack/dsortr.o vendor/arpack/dstatn.o vendor/arpack/dstats.o vendor/arpack/dstqrb.o vendor/arpack/dvout.o vendor/arpack/ivout.o vendor/arpack/second.o vendor/arpack/wrap.o vendor/simpleraytracer/Color.o vendor/simpleraytracer/Light.o vendor/simpleraytracer/Point.o vendor/simpleraytracer/RIgraphRay.o vendor/simpleraytracer/Ray.o vendor/simpleraytracer/RayTracer.o vendor/simpleraytracer/RayVector.o vendor/simpleraytracer/Shape.o vendor/simpleraytracer/Sphere.o vendor/simpleraytracer/Triangle.o vendor/simpleraytracer/unit_limiter.o vendor/uuid/R.o vendor/uuid/clear.o vendor/uuid/compare.o vendor/uuid/copy.o vendor/uuid/gen_uuid.o vendor/uuid/isnull.o vendor/uuid/pack.o vendor/uuid/parse.o vendor/uuid/unpack.o vendor/uuid/unparse.o leidenalg/CPMVertexPartition.o leidenalg/GraphHelper.o leidenalg/LinearResolutionParameterVertexPartition.o leidenalg/ModularityVertexPartition.o leidenalg/MutableVertexPartition.o leidenalg/Optimiser.o leidenalg/RBConfigurationVertexPartition.o leidenalg/RBERVertexPartition.o leidenalg/ResolutionParameterVertexPartition.o leidenalg/SignificanceVertexPartition.o leidenalg/SurpriseVertexPartition.o leidenbase/leidenFindPartition.o leidenbase/leidenFindPartitionR2C.o leidenbase/src/config.h.in0000644000176200001440000000737414447675376015221 0ustar liggesusers/* src/config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `expm1' function. */ #undef HAVE_EXPM1 /* Define to 1 if you have the `finite' function. */ #undef HAVE_FINITE /* Define to 1 if you have the `fmin' function. */ #undef HAVE_FMIN /* Define to 1 if using the GNU Fortran compiler */ #undef HAVE_GFORTRAN /* Define to 1 if you have the GLPK library */ #undef HAVE_GLPK /* Define to 1 if you have the GMP library */ #undef HAVE_GMP /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `isfinite' function. */ #undef HAVE_ISFINITE /* Define to 1 if you have the libxml2 libraries installed */ #undef HAVE_LIBXML /* Define to 1 if you have the `log1p' function. */ #undef HAVE_LOG1P /* Define to 1 if you have the `log2' function. */ #undef HAVE_LOG2 /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_DL_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H /* Define to 1 if you have the `rint' function. */ #undef HAVE_RINT /* Define to 1 if you have the `rintf' function. */ #undef HAVE_RINTF /* Define to 1 if you have the `round' function. */ #undef HAVE_ROUND /* Define if struct sockaddr contains sa_len */ #undef HAVE_SA_LEN /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `stpcpy' function. */ #undef HAVE_STPCPY /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UN_H /* Define to 1 if you have the sys/times.h header */ #undef HAVE_TIMES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `_stricmp' function. */ #undef HAVE__STRICMP /* We don't care about thread-local storage in R */ #undef IGRAPH_THREAD_LOCAL /* Define to 1 if you use the vendored mini-GMP library */ #undef INTERNAL_GMP /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS #define HAVE_ISFINITE HAVE_DECL_ISFINITE leidenbase/src/leidenalg/0000755000176200001440000000000014532173045015064 5ustar liggesusersleidenbase/src/leidenalg/RBERVertexPartition.h0000644000176200001440000000154514445377560021077 0ustar liggesusers#ifndef RBERVERTEXPARTITION_H #define RBERVERTEXPARTITION_H #include "LinearResolutionParameterVertexPartition.h" class RBERVertexPartition : public LinearResolutionParameterVertexPartition { public: RBERVertexPartition(Graph* graph, vector const& membership, double resolution_parameter); RBERVertexPartition(Graph* graph, vector const& membership); RBERVertexPartition(Graph* graph, double resolution_parameter); RBERVertexPartition(Graph* graph); virtual ~RBERVertexPartition(); virtual RBERVertexPartition* create(Graph* graph); virtual RBERVertexPartition* create(Graph* graph, vector const& membership); virtual double diff_move(size_t v, size_t new_comm); virtual double quality(double resolution_parameter); protected: private: }; #endif // RBERVERTEXPARTITION_H leidenbase/src/leidenalg/RBConfigurationVertexPartition.h0000644000176200001440000000173514444673466023404 0ustar liggesusers#ifndef RBCONFIGURATIONVERTEXPARTITION_H #define RBCONFIGURATIONVERTEXPARTITION_H #include "LinearResolutionParameterVertexPartition.h" class RBConfigurationVertexPartition : public LinearResolutionParameterVertexPartition { public: RBConfigurationVertexPartition(Graph* graph, vector const& membership, double resolution_parameter); RBConfigurationVertexPartition(Graph* graph, vector const& membership); RBConfigurationVertexPartition(Graph* graph, double resolution_parameter); RBConfigurationVertexPartition(Graph* graph); virtual ~RBConfigurationVertexPartition(); virtual RBConfigurationVertexPartition* create(Graph* graph); virtual RBConfigurationVertexPartition* create(Graph* graph, vector const& membership); virtual double diff_move(size_t v, size_t new_comm); virtual double quality(double resolution_parameter); protected: private: }; #endif // RBCONFIGURATIONVERTEXPARTITION_H leidenbase/src/leidenalg/GraphHelper.h0000644000176200001440000001446214444673466017463 0ustar liggesusers#ifndef GRAPHHELPER_INCLUDED #define GRAPHHELPER_INCLUDED #include #include #include #include #include //#ifdef DEBUG #include using std::cerr; using std::endl; //#endif class MutableVertexPartition; using std::vector; using std::pair; using std::set; using std::deque; using std::make_pair; vector range(size_t n); bool orderCSize(const size_t* A, const size_t* B); double KL(double q, double p); double KLL(double q, double p); template T sum(vector vec) { T sum_of_elems = T(); for (T x : vec) sum_of_elems += x; return sum_of_elems; }; class Exception : public std::exception { public: Exception(const char* str) { this->str = str; } virtual const char* what() const throw() { return this->str; } private: const char* str; }; inline size_t get_random_int(size_t from, size_t to, igraph_rng_t* rng) { return igraph_rng_get_integer(rng, from, to); }; void shuffle(vector& v, igraph_rng_t* rng); class Graph { public: Graph(igraph_t* graph, vector const& edge_weights, vector const& node_sizes, vector const& node_self_weights, int correct_self_loops); Graph(igraph_t* graph, vector const& edge_weights, vector const& node_sizes, vector const& node_self_weights); Graph(igraph_t* graph, vector const& edge_weights, vector const& node_sizes, int correct_self_loops); Graph(igraph_t* graph, vector const& edge_weights, vector const& node_sizes); Graph(igraph_t* graph, vector const& edge_weights, int correct_self_loops); Graph(igraph_t* graph, vector const& edge_weights); Graph(igraph_t* graph, vector const& node_sizes, int correct_self_loops); Graph(igraph_t* graph, vector const& node_sizes); Graph(igraph_t* graph, int correct_self_loops); Graph(igraph_t* graph); Graph(); ~Graph(); int has_self_loops(); size_t possible_edges(); size_t possible_edges(size_t n); Graph* collapse_graph(MutableVertexPartition* partition); vector const& get_neighbour_edges(size_t v, igraph_neimode_t mode); vector const& get_neighbours(size_t v, igraph_neimode_t mode); size_t get_random_neighbour(size_t v, igraph_neimode_t mode, igraph_rng_t* rng); inline size_t get_random_node(igraph_rng_t* rng) { return get_random_int(0, this->vcount() - 1, rng); }; inline igraph_t* get_igraph() { return this->_graph; }; inline size_t vcount() { return igraph_vcount(this->_graph); }; inline size_t ecount() { return igraph_ecount(this->_graph); }; inline double total_weight() { return this->_total_weight; }; inline size_t total_size() { return this->_total_size; }; inline int is_directed() { return this->_is_directed; }; inline double density() { return this->_density; }; inline int correct_self_loops() { return this->_correct_self_loops; }; inline int is_weighted() { return this->_is_weighted; }; // Get weight of edge based on attribute (or 1.0 if there is none). inline double edge_weight(size_t e) { #ifdef DEBUG if (e > this->_edge_weights.size()) throw Exception("Edges outside of range of edge weights."); #endif return this->_edge_weights[e]; }; inline void edge(size_t eid, size_t &from, size_t &to) { from = IGRAPH_FROM(this->get_igraph(), eid); to = IGRAPH_TO(this->get_igraph(), eid); } inline vector edge(size_t e) { vector edge(2); this->edge(e, edge[0], edge[1]); return edge; } // Get size of node based on attribute (or 1.0 if there is none). inline size_t node_size(size_t v) { return this->_node_sizes[v]; }; // Get self weight of node based on attribute (or set to 0.0 if there is none) inline double node_self_weight(size_t v) { return this->_node_self_weights[v]; }; inline size_t degree(size_t v, igraph_neimode_t mode) { if (mode == IGRAPH_IN || !this->is_directed()) return this->_degree_in[v]; else if (mode == IGRAPH_OUT) return this->_degree_out[v]; else if (mode == IGRAPH_ALL) return this->_degree_all[v]; else throw Exception("Incorrect mode specified."); }; inline double strength(size_t v, igraph_neimode_t mode) { if (mode == IGRAPH_IN || !this->is_directed()) return this->_strength_in[v]; else if (mode == IGRAPH_OUT) return this->_strength_out[v]; else throw Exception("Incorrect mode specified."); }; protected: int _remove_graph; private: igraph_t* _graph; igraph_vector_t _temp_igraph_vector; // Utility variables to easily access the strength of each node vector _strength_in; vector _strength_out; vector _degree_in; vector _degree_out; vector _degree_all; vector _edge_weights; // Used for the weight of the edges. vector _node_sizes; // Used for the size of the nodes. vector _node_self_weights; // Used for the self weight of the nodes. void cache_neighbours(size_t v, igraph_neimode_t mode); vector _cached_neighs_from; size_t _current_node_cache_neigh_from; vector _cached_neighs_to; size_t _current_node_cache_neigh_to; vector _cached_neighs_all; size_t _current_node_cache_neigh_all; void cache_neighbour_edges(size_t v, igraph_neimode_t mode); vector _cached_neigh_edges_from; size_t _current_node_cache_neigh_edges_from; vector _cached_neigh_edges_to; size_t _current_node_cache_neigh_edges_to; vector _cached_neigh_edges_all; size_t _current_node_cache_neigh_edges_all; double _total_weight; size_t _total_size; int _is_weighted; bool _is_directed; int _correct_self_loops; double _density; void init_admin(); void set_defaults(); void set_default_edge_weight(); void set_default_node_size(); void set_self_weights(); }; // We need this ugly way to include the MutableVertexPartition // to overcome a circular linkage problem. #include "MutableVertexPartition.h" #endif // GRAPHHELPER_INCLUDED leidenbase/src/leidenalg/ModularityVertexPartition.h0000644000176200001440000000123714445413074022463 0ustar liggesusers#ifndef MODULARITYVERTEXPARTITION_H #define MODULARITYVERTEXPARTITION_H #include "MutableVertexPartition.h" class ModularityVertexPartition : public MutableVertexPartition { public: ModularityVertexPartition(Graph* graph, vector const& membership); ModularityVertexPartition(Graph* graph); virtual ~ModularityVertexPartition(); virtual ModularityVertexPartition* create(Graph* graph); virtual ModularityVertexPartition* create(Graph* graph, vector const& membership); virtual double diff_move(size_t v, size_t new_comm); virtual double quality(); protected: private: }; #endif // MODULARITYVERTEXPARTITION_H leidenbase/src/leidenalg/RBConfigurationVertexPartition.cpp0000644000176200001440000001351014444671323023717 0ustar liggesusers#include "RBConfigurationVertexPartition.h" RBConfigurationVertexPartition::RBConfigurationVertexPartition(Graph* graph, vector const& membership, double resolution_parameter) : LinearResolutionParameterVertexPartition(graph, membership, resolution_parameter) { } RBConfigurationVertexPartition::RBConfigurationVertexPartition(Graph* graph, vector const& membership) : LinearResolutionParameterVertexPartition(graph, membership) { } RBConfigurationVertexPartition::RBConfigurationVertexPartition(Graph* graph, double resolution_parameter) : LinearResolutionParameterVertexPartition(graph, resolution_parameter) { } RBConfigurationVertexPartition::RBConfigurationVertexPartition(Graph* graph) : LinearResolutionParameterVertexPartition(graph) { } RBConfigurationVertexPartition::~RBConfigurationVertexPartition() { } RBConfigurationVertexPartition* RBConfigurationVertexPartition::create(Graph* graph) { return new RBConfigurationVertexPartition(graph, this->resolution_parameter); } RBConfigurationVertexPartition* RBConfigurationVertexPartition::create(Graph* graph, vector const& membership) { return new RBConfigurationVertexPartition(graph, membership, this->resolution_parameter); } /***************************************************************************** Returns the difference in modularity if we move a node to a new community *****************************************************************************/ double RBConfigurationVertexPartition::diff_move(size_t v, size_t new_comm) { #ifdef DEBUG cerr << "double RBConfigurationVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; #endif size_t old_comm = this->_membership[v]; double diff = 0.0; double total_weight = this->graph->total_weight()*(2.0 - this->graph->is_directed()); if (total_weight == 0.0) return 0.0; if (new_comm != old_comm) { #ifdef DEBUG cerr << "\t" << "old_comm: " << old_comm << endl; #endif double w_to_old = this->weight_to_comm(v, old_comm); #ifdef DEBUG cerr << "\t" << "w_to_old: " << w_to_old << endl; #endif double w_from_old = this->weight_from_comm(v, old_comm); #ifdef DEBUG cerr << "\t" << "w_from_old: " << w_from_old << endl; #endif double w_to_new = this->weight_to_comm(v, new_comm); #ifdef DEBUG cerr << "\t" << "w_to_new: " << w_to_new << endl; #endif double w_from_new = this->weight_from_comm(v, new_comm); #ifdef DEBUG cerr << "\t" << "w_from_new: " << w_from_new << endl; #endif double k_out = this->graph->strength(v, IGRAPH_OUT); #ifdef DEBUG cerr << "\t" << "k_out: " << k_out << endl; #endif double k_in = this->graph->strength(v, IGRAPH_IN); #ifdef DEBUG cerr << "\t" << "k_in: " << k_in << endl; #endif double self_weight = this->graph->node_self_weight(v); #ifdef DEBUG cerr << "\t" << "self_weight: " << self_weight << endl; #endif double K_out_old = this->total_weight_from_comm(old_comm); #ifdef DEBUG cerr << "\t" << "K_out_old: " << K_out_old << endl; #endif double K_in_old = this->total_weight_to_comm(old_comm); #ifdef DEBUG cerr << "\t" << "K_in_old: " << K_in_old << endl; #endif double K_out_new = this->total_weight_from_comm(new_comm) + k_out; #ifdef DEBUG cerr << "\t" << "K_out_new: " << K_out_new << endl; #endif double K_in_new = this->total_weight_to_comm(new_comm) + k_in; #ifdef DEBUG cerr << "\t" << "K_in_new: " << K_in_new << endl; cerr << "\t" << "total_weight: " << total_weight << endl; #endif double diff_old = (w_to_old - this->resolution_parameter*k_out*K_in_old/total_weight) + \ (w_from_old - this->resolution_parameter*k_in*K_out_old/total_weight); #ifdef DEBUG cerr << "\t" << "diff_old: " << diff_old << endl; #endif double diff_new = (w_to_new + self_weight - this->resolution_parameter*k_out*K_in_new/total_weight) + \ (w_from_new + self_weight - this->resolution_parameter*k_in*K_out_new/total_weight); #ifdef DEBUG cerr << "\t" << "diff_new: " << diff_new << endl; #endif diff = diff_new - diff_old; #ifdef DEBUG cerr << "\t" << "diff: " << diff << endl; #endif } #ifdef DEBUG cerr << "exit RBConfigurationVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; cerr << "return " << diff << endl << endl; #endif return diff; } /***************************************************************************** Give the modularity of the partition. We here use the unscaled version of modularity, in other words, we don"t normalise by the number of edges. ******************************************************************************/ double RBConfigurationVertexPartition::quality(double resolution_parameter) { #ifdef DEBUG cerr << "double ModularityVertexPartition::quality()" << endl; #endif double mod = 0.0; double m; if (this->graph->is_directed()) m = this->graph->total_weight(); else m = 2*this->graph->total_weight(); if (m == 0) return 0.0; for (size_t c = 0; c < this->n_communities(); c++) { double w = this->total_weight_in_comm(c); double w_out = this->total_weight_from_comm(c); double w_in = this->total_weight_to_comm(c); #ifdef DEBUG size_t csize = this->csize(c); cerr << "\t" << "Comm: " << c << ", size=" << csize << ", w=" << w << ", w_out=" << w_out << ", w_in=" << w_in << "." << endl; #endif mod += w - resolution_parameter*w_out*w_in/((this->graph->is_directed() ? 1.0 : 4.0)*this->graph->total_weight()); } double q = (2.0 - this->graph->is_directed())*mod; #ifdef DEBUG cerr << "exit double RBConfigurationVertexPartition::quality()" << endl; cerr << "return " << q << endl << endl; #endif return q; } leidenbase/src/leidenalg/GraphHelper.cpp0000644000176200001440000005620514444671323020005 0ustar liggesusers#include "GraphHelper.h" #ifdef DEBUG using std::cerr; using std::endl; #endif vector range(size_t n) { vector range_vec(n); for(size_t i = 0; i < n; i++) range_vec[i] = i; return range_vec; } bool orderCSize(const size_t* A, const size_t* B) { if (A[1] == B[1]) { if (A[2] == B[2]) return A[0] < B[0]; else return A[2] > B[2]; } else return A[1] > B[1]; } void shuffle(vector& v, igraph_rng_t* rng) { size_t n = v.size(); if (n > 0) { for (size_t idx = n - 1; idx > 0; idx--) { size_t rand_idx = get_random_int(0, idx, rng); size_t tmp = v[idx]; v[idx] = v[rand_idx]; v[rand_idx] = tmp; } } } /**************************************************************************** The binary Kullback-Leibler divergence. ****************************************************************************/ double KL(double q, double p) { double KL = 0.0; if (q > 0.0 && p > 0.0) KL += q*log(q/p); if (q < 1.0 && p < 1.0) KL += (1.0-q)*log((1.0-q)/(1.0-p)); return KL; } double KLL(double q, double p) { double KL = 0.0; if (q > 0.0 && p > 0.0) KL += q*log(q/p); if (q < 1.0 && p < 1.0) KL += (1.0-q)*log((1.0-q)/(1.0-p)); if (q < p) KL *= -1; return KL; } Graph::Graph(igraph_t* graph, vector const& edge_weights, vector const& node_sizes, vector const& node_self_weights, int correct_self_loops) { this->_graph = graph; this->_remove_graph = false; if (edge_weights.size() != this->ecount()) throw Exception("Edge weights vector inconsistent length with the edge count of the graph."); this->_edge_weights = edge_weights; this->_is_weighted = true; if (node_sizes.size() != this->vcount()) throw Exception("Node size vector inconsistent length with the vertex count of the graph."); this->_node_sizes = node_sizes; if (node_self_weights.size() != this->vcount()) throw Exception("Node self weights vector inconsistent length with the vertex count of the graph."); this->_node_self_weights = node_self_weights; this->_correct_self_loops = correct_self_loops; igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); } Graph::Graph(igraph_t* graph, vector const& edge_weights, vector const& node_sizes, vector const& node_self_weights) { this->_graph = graph; this->_remove_graph = false; if (edge_weights.size() != this->ecount()) throw Exception("Edge weights vector inconsistent length with the edge count of the graph."); this->_edge_weights = edge_weights; this->_is_weighted = true; if (node_sizes.size() != this->vcount()) throw Exception("Node size vector inconsistent length with the vertex count of the graph."); this->_node_sizes = node_sizes; this->_correct_self_loops = this->has_self_loops(); this->_node_self_weights = node_self_weights; igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); } Graph::Graph(igraph_t* graph, vector const& edge_weights, vector const& node_sizes, int correct_self_loops) { this->_graph = graph; this->_remove_graph = false; if (edge_weights.size() != this->ecount()) throw Exception("Edge weights vector inconsistent length with the edge count of the graph."); this->_edge_weights = edge_weights; this->_is_weighted = true; if (node_sizes.size() != this->vcount()) throw Exception("Node size vector inconsistent length with the vertex count of the graph."); this->_node_sizes = node_sizes; this->_correct_self_loops = correct_self_loops; igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); this->set_self_weights(); } Graph::Graph(igraph_t* graph, vector const& edge_weights, vector const& node_sizes) { this->_graph = graph; this->_remove_graph = false; if (edge_weights.size() != this->ecount()) throw Exception("Edge weights vector inconsistent length with the edge count of the graph."); this->_edge_weights = edge_weights; this->_is_weighted = true; if (node_sizes.size() != this->vcount()) throw Exception("Node size vector inconsistent length with the vertex count of the graph."); this->_node_sizes = node_sizes; this->_correct_self_loops = this->has_self_loops(); igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); this->set_self_weights(); } Graph::Graph(igraph_t* graph, vector const& edge_weights, int correct_self_loops) { this->_graph = graph; this->_remove_graph = false; this->_correct_self_loops = correct_self_loops; if (edge_weights.size() != this->ecount()) throw Exception("Edge weights vector inconsistent length with the edge count of the graph."); this->_edge_weights = edge_weights; this->_is_weighted = true; this->set_default_node_size(); igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); this->set_self_weights(); } Graph::Graph(igraph_t* graph, vector const& edge_weights) { this->_graph = graph; this->_remove_graph = false; if (edge_weights.size() != this->ecount()) throw Exception("Edge weights vector inconsistent length with the edge count of the graph."); this->_edge_weights = edge_weights; this->_is_weighted = true; this->_correct_self_loops = this->has_self_loops(); this->set_default_node_size(); igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); this->set_self_weights(); } Graph::Graph(igraph_t* graph, vector const& node_sizes, int correct_self_loops) { this->_graph = graph; this->_remove_graph = false; this->_correct_self_loops = correct_self_loops; if (node_sizes.size() != this->vcount()) throw Exception("Node size vector inconsistent length with the vertex count of the graph."); this->_node_sizes = node_sizes; this->set_default_edge_weight(); this->_is_weighted = false; igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); this->set_self_weights(); } Graph::Graph(igraph_t* graph, vector const& node_sizes) { this->_graph = graph; this->_remove_graph = false; this->set_defaults(); this->_is_weighted = false; if (node_sizes.size() != this->vcount()) throw Exception("Node size vector inconsistent length with the vertex count of the graph."); this->_node_sizes = node_sizes; this->_correct_self_loops = this->has_self_loops(); igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); this->set_self_weights(); } Graph::Graph(igraph_t* graph, int correct_self_loops) { this->_graph = graph; this->_remove_graph = false; this->_correct_self_loops = correct_self_loops; this->set_defaults(); this->_is_weighted = false; igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); this->set_self_weights(); } Graph::Graph(igraph_t* graph) { this->_graph = graph; this->_remove_graph = false; this->set_defaults(); this->_is_weighted = false; this->_correct_self_loops = this->has_self_loops(); igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); this->set_self_weights(); } Graph::Graph() { this->_graph = new igraph_t(); this->_remove_graph = true; this->set_defaults(); this->_is_weighted = false; this->_correct_self_loops = false; igraph_vector_init(&this->_temp_igraph_vector, this->vcount()); this->init_admin(); this->set_self_weights(); } Graph::~Graph() { if (this->_remove_graph) { igraph_destroy(this->_graph); delete this->_graph; } igraph_vector_destroy(&this->_temp_igraph_vector); } int Graph::has_self_loops() { size_t m = this->ecount(); igraph_vector_bool_t loop; igraph_vector_bool_init(&loop, m); igraph_is_loop(this->_graph, &loop, igraph_ess_all(IGRAPH_EDGEORDER_ID)); int has_self_loops = false; for (size_t idx = 0; idx < m; idx++) { if (VECTOR(loop)[idx]) { has_self_loops = true; break; } } igraph_vector_bool_destroy(&loop); return has_self_loops; } size_t Graph::possible_edges() { return this->possible_edges(this->vcount()); } size_t Graph::possible_edges(size_t n) { size_t possible_edges = n*(n-1); if (!this->is_directed()) possible_edges /= 2; if (this->correct_self_loops()) possible_edges += n; return possible_edges; } void Graph::set_defaults() { this->set_default_edge_weight(); this->set_default_node_size(); } void Graph::set_default_edge_weight() { size_t m = this->ecount(); // Set default edge weight of 1.0 this->_edge_weights.clear(); this->_edge_weights.resize(m); fill(this->_edge_weights.begin(), this->_edge_weights.end(), 1.0); this->_is_weighted = false; } void Graph::set_default_node_size() { size_t n = this->vcount(); // Set default node size of 1 this->_node_sizes.clear(); this->_node_sizes.resize(n); fill(this->_node_sizes.begin(), this->_node_sizes.end(), 1); } void Graph::set_self_weights() { size_t n = this->vcount(); // Set default self_weights of the total weight of any possible self-loops this->_node_self_weights.clear(); this->_node_self_weights.resize(n); for (size_t v = 0; v < n; v++) { #ifdef DEBUG cerr << "\t" << "Size node " << v << ": " << this->node_size(v) << endl; #endif double self_weight = 0.0; // There should be only one self loop igraph_integer_t eid; // Get edge id for self loop igraph_get_eid(this->_graph, &eid, v, v, this->is_directed(), false); if (eid >= 0) self_weight = this->edge_weight(eid); this->_node_self_weights[v] = self_weight; #ifdef DEBUG cerr << "\t" << "Self weight node " << v << ": " << self_weight << endl; #endif } } void Graph::init_admin() { size_t m = this->ecount(); size_t n = this->vcount(); this->_is_directed = igraph_is_directed(this->_graph); this->_strength_in.clear(); this->_strength_in.resize(n, 0.0); this->_degree_in.clear(); this->_degree_in.resize(n, 0.0); if (this->_is_directed) { this->_strength_out.clear(); this->_strength_out.resize(n, 0.0); this->_degree_out.clear(); this->_degree_out.resize(n, 0); this->_degree_all.clear(); this->_degree_all.resize(n, 0); } // Determine total weight in the graph. this->_total_weight = 0.0; for (size_t e = 0; e < m; e++) { double w = this->edge_weight(e); this->_total_weight += w; size_t from, to; this->edge(e, from, to); if (this->is_directed()) { this->_strength_in[to] += w; this->_strength_out[from] += w; this->_degree_in[to]++; this->_degree_out[from]++; this->_degree_all[to]++; this->_degree_all[from]++; } else { // we only compute strength_in and degree_in for undirected graphs this->_strength_in[to] += w; this->_strength_in[from] += w; // recall that igraph ignores the mode for undirected graphs this->_degree_in[to]++; this->_degree_in[from]++; } } // Make sure to multiply by 2 for undirected graphs //if (!this->is_directed()) // this->_total_weight *= 2.0; this->_total_size = 0; for (size_t v = 0; v < n; v++) this->_total_size += this->node_size(v); // Calculate density; double w = this->total_weight(); size_t n_size = this->total_size(); // For now we default to not correcting self loops. // this->_correct_self_loops = false; (remove this as this is set in the constructor) double normalise = 0.0; if (this->_correct_self_loops) normalise = n_size*n_size; else normalise = n_size*(n_size - 1); if (this->is_directed()) this->_density = w/normalise; else this->_density = 2*w/normalise; this->_current_node_cache_neigh_edges_from = n + 1; this->_current_node_cache_neigh_edges_to = n + 1; this->_current_node_cache_neigh_edges_all = n + 1; this->_current_node_cache_neigh_from = n + 1; this->_current_node_cache_neigh_to = n + 1; this->_current_node_cache_neigh_all = n + 1; } void Graph::cache_neighbour_edges(size_t v, igraph_neimode_t mode) { #ifdef DEBUG cerr << "void Graph::cache_neighbour_edges(" << v << ", " << mode << ");" << endl; #endif size_t degree = this->degree(v, mode); #ifdef DEBUG cerr << "Degree: " << degree << endl; #endif igraph_vector_t *incident_edges = &this->_temp_igraph_vector; igraph_incident(this->_graph, incident_edges, v, mode); vector* _cached_neigh_edges = NULL; switch (mode) { case IGRAPH_IN: this->_current_node_cache_neigh_edges_from = v; _cached_neigh_edges = &(this->_cached_neigh_edges_from); break; case IGRAPH_OUT: this->_current_node_cache_neigh_edges_to = v; _cached_neigh_edges = &(this->_cached_neigh_edges_to); break; case IGRAPH_ALL: this->_current_node_cache_neigh_edges_all = v; _cached_neigh_edges = &(this->_cached_neigh_edges_all); break; } _cached_neigh_edges->assign(igraph_vector_e_ptr(incident_edges, 0), igraph_vector_e_ptr(incident_edges, degree)); #ifdef DEBUG cerr << "Number of edges: " << _cached_neigh_edges->size() << endl; #endif #ifdef DEBUG cerr << "exit void Graph::cache_neighbour_edges(" << v << ", " << mode << ");" << endl; #endif } vector const& Graph::get_neighbour_edges(size_t v, igraph_neimode_t mode) { if (!this->is_directed()) mode = IGRAPH_ALL; // igraph ignores mode for undirected graphs switch (mode) { case IGRAPH_IN: if (this->_current_node_cache_neigh_edges_from != v) { cache_neighbour_edges(v, mode); this->_current_node_cache_neigh_edges_from = v; } return this->_cached_neigh_edges_from; case IGRAPH_OUT: if (this->_current_node_cache_neigh_edges_to != v) { cache_neighbour_edges(v, mode); this->_current_node_cache_neigh_edges_to = v; } return this->_cached_neigh_edges_to; case IGRAPH_ALL: if (this->_current_node_cache_neigh_edges_all != v) { cache_neighbour_edges(v, mode); this->_current_node_cache_neigh_edges_all = v; } return this->_cached_neigh_edges_all; } throw Exception("Incorrect model for getting neighbour edges."); } void Graph::cache_neighbours(size_t v, igraph_neimode_t mode) { #ifdef DEBUG cerr << "void Graph::cache_neighbours(" << v << ", " << mode << ");" << endl; #endif size_t degree = this->degree(v, mode); #ifdef DEBUG cerr << "Degree: " << degree << endl; #endif igraph_vector_t *neighbours = &this->_temp_igraph_vector; igraph_neighbors(this->_graph, neighbours, v, mode); vector* _cached_neighs = NULL; switch (mode) { case IGRAPH_IN: this->_current_node_cache_neigh_from = v; _cached_neighs = &(this->_cached_neighs_from); break; case IGRAPH_OUT: this->_current_node_cache_neigh_to = v; _cached_neighs = &(this->_cached_neighs_to); break; case IGRAPH_ALL: this->_current_node_cache_neigh_all = v; _cached_neighs = &(this->_cached_neighs_all); break; } _cached_neighs->assign(igraph_vector_e_ptr(neighbours, 0),igraph_vector_e_ptr(neighbours, degree)); #ifdef DEBUG cerr << "Number of edges: " << _cached_neighs->size() << endl; #endif #ifdef DEBUG cerr << "exit void Graph::cache_neighbours(" << v << ", " << mode << ");" << endl; #endif } vector< size_t > const& Graph::get_neighbours(size_t v, igraph_neimode_t mode) { if (!this->is_directed()) mode = IGRAPH_ALL; // igraph ignores mode for undirected graphs switch (mode) { case IGRAPH_IN: if (this->_current_node_cache_neigh_from != v) { cache_neighbours(v, mode); this -> _current_node_cache_neigh_from = v; } #ifdef DEBUG cerr << "Returning " << this->_cached_neighs_from.size() << " incoming neighbours" << endl; #endif return this->_cached_neighs_from; case IGRAPH_OUT: if (this->_current_node_cache_neigh_to != v) { cache_neighbours(v, mode); this -> _current_node_cache_neigh_to = v; } #ifdef DEBUG cerr << "Returning " << this->_cached_neighs_to.size() << " incoming neighbours" << endl; #endif return this->_cached_neighs_to; case IGRAPH_ALL: if (this->_current_node_cache_neigh_all != v) { cache_neighbours(v, mode); this->_current_node_cache_neigh_all = v; } #ifdef DEBUG cerr << "Returning " << this->_cached_neighs_all.size() << " incoming neighbours" << endl; #endif return this->_cached_neighs_all; } throw Exception("Invalid mode for getting neighbours."); } /******************************************************************************** * This should return a random neighbour in O(1) ********************************************************************************/ size_t Graph::get_random_neighbour(size_t v, igraph_neimode_t mode, igraph_rng_t* rng) { size_t node=v; size_t rand_neigh = -1; if (this->degree(v, mode) <= 0) throw Exception("Cannot select a random neighbour for an isolated node."); if (this->is_directed() && mode != IGRAPH_ALL) { if (mode == IGRAPH_OUT) { // Get indices of where neighbours are size_t cum_degree_this_node = (size_t) VECTOR(this->_graph->os)[node]; size_t cum_degree_next_node = (size_t) VECTOR(this->_graph->os)[node+1]; // Get a random index from them size_t rand_neigh_idx = get_random_int(cum_degree_this_node, cum_degree_next_node - 1, rng); // Return the neighbour at that index #ifdef DEBUG cerr << "Degree: " << this->degree(node, mode) << " diff in cumulative: " << cum_degree_next_node - cum_degree_this_node << endl; #endif rand_neigh = VECTOR(this->_graph->to)[ (size_t)VECTOR(this->_graph->oi)[rand_neigh_idx] ]; } else if (mode == IGRAPH_IN) { // Get indices of where neighbours are size_t cum_degree_this_node = (size_t) VECTOR(this->_graph->is)[node]; size_t cum_degree_next_node = (size_t) VECTOR(this->_graph->is)[node+1]; // Get a random index from them size_t rand_neigh_idx = get_random_int(cum_degree_this_node, cum_degree_next_node - 1, rng); #ifdef DEBUG cerr << "Degree: " << this->degree(node, mode) << " diff in cumulative: " << cum_degree_next_node - cum_degree_this_node << endl; #endif // Return the neighbour at that index rand_neigh = VECTOR(this->_graph->from)[ (size_t)VECTOR(this->_graph->ii)[rand_neigh_idx] ]; } } else { // both in- and out- neighbors in a directed graph. size_t cum_outdegree_this_node = (size_t)VECTOR(this->_graph->os)[node]; size_t cum_indegree_this_node = (size_t)VECTOR(this->_graph->is)[node]; size_t cum_outdegree_next_node = (size_t)VECTOR(this->_graph->os)[node+1]; size_t cum_indegree_next_node = (size_t)VECTOR(this->_graph->is)[node+1]; size_t total_outdegree = cum_outdegree_next_node - cum_outdegree_this_node; size_t total_indegree = cum_indegree_next_node - cum_indegree_this_node; size_t rand_idx = get_random_int(0, total_outdegree + total_indegree - 1, rng); #ifdef DEBUG cerr << "Degree: " << this->degree(node, mode) << " diff in cumulative: " << total_outdegree + total_indegree << endl; #endif // From among in or out neighbours? if (rand_idx < total_outdegree) { // From among outgoing neighbours size_t rand_neigh_idx = cum_outdegree_this_node + rand_idx; rand_neigh = VECTOR(this->_graph->to)[ (size_t)VECTOR(this->_graph->oi)[rand_neigh_idx] ]; } else { // From among incoming neighbours size_t rand_neigh_idx = cum_indegree_this_node + rand_idx - total_outdegree; rand_neigh = VECTOR(this->_graph->from)[ (size_t)VECTOR(this->_graph->ii)[rand_neigh_idx] ]; } } return rand_neigh; } /**************************************************************************** Creates a graph with communities as node and links as weights between communities. The weight of the edges in the new graph is simply the sum of the weight of the edges between the communities. The self weight of a node (i.e. the weight of its self loop) is the internal weight of a community. The size of a node in the new graph is simply the size of the community in the old graph. *****************************************************************************/ Graph* Graph::collapse_graph(MutableVertexPartition* partition) { #ifdef DEBUG cerr << "Graph* Graph::collapse_graph(vector membership)" << endl; #endif #ifdef DEBUG cerr << "Current graph has " << this->vcount() << " nodes and " << this->ecount() << " edges." << endl; cerr << "Collapsing to graph with " << partition->n_communities() << " nodes." << endl; #endif size_t n_collapsed = partition->n_communities(); vector > community_memberships = partition->get_communities(); vector collapsed_weights; double total_collapsed_weight = 0.0; vector edge_weight_to_community(n_collapsed, 0.0); vector neighbour_comm_added(n_collapsed, false); // collapsed edges for new graph igraph_vector_t edges; igraph_vector_init(&edges, 0); for (size_t v_comm = 0; v_comm < n_collapsed; v_comm++) { vector neighbour_communities; for (size_t v : community_memberships[v_comm]) { for (size_t e : this->get_neighbour_edges(v, IGRAPH_OUT)) { size_t from, to; this->edge(e, from, to); if ((size_t) from != v) { // need to skip because IGRAPH_OUT is ignored for undirected graphs continue; } size_t u_comm = partition->membership(to); double w = this->edge_weight(e); // Self loops appear twice here if the graph is undirected, so divide by 2.0 in that case. if (from == to && !this->is_directed()) w /= 2.0; if (!neighbour_comm_added[u_comm]) { neighbour_comm_added[u_comm] = true; neighbour_communities.push_back(u_comm); } edge_weight_to_community[u_comm] += w; } } for (size_t u_comm : neighbour_communities) { igraph_vector_push_back(&edges, v_comm); igraph_vector_push_back(&edges, u_comm); collapsed_weights.push_back(edge_weight_to_community[u_comm]); total_collapsed_weight += edge_weight_to_community[u_comm]; // reset edge_weight_to_community to all 0.0 and neighbour_comm_added to all false edge_weight_to_community[u_comm] = 0.0; neighbour_comm_added[u_comm] = false; } } // Create graph based on edges igraph_t* graph = new igraph_t(); igraph_create(graph, &edges, n_collapsed, this->is_directed()); igraph_vector_destroy(&edges); if ((size_t) igraph_vcount(graph) != partition->n_communities()) throw Exception("Something went wrong with collapsing the graph."); // Calculate new node sizes vector csizes(n_collapsed, 0); for (size_t c = 0; c < partition->n_communities(); c++) csizes[c] = partition->csize(c); Graph* G = new Graph(graph, collapsed_weights, csizes, this->_correct_self_loops); G->_remove_graph = true; #ifdef DEBUG cerr << "exit Graph::collapse_graph(vector membership)" << endl << endl; #endif return G; } leidenbase/src/leidenalg/Optimiser.cpp0000644000176200001440000016120114445427310017544 0ustar liggesusers#include "Optimiser.h" /**************************************************************************** Create a new Optimiser object Be sure to call igraph_i_set_attribute_table(&igraph_cattribute_table); before using this package, otherwise the attribute handling will not be dealt with correctly. Parameters: consider_comms -- Consider communities in a specific manner: ALL_COMMS -- Consider all communities for improvement. ALL_NEIGH_COMMS -- Consider all neighbour communities for improvement. RAND_COMM -- Consider a random commmunity for improvement. RAND_NEIGH_COMM -- Consider a random community among the neighbours for improvement. ****************************************************************************/ Optimiser::Optimiser() { this->consider_comms = Optimiser::ALL_NEIGH_COMMS; this->optimise_routine = Optimiser::MOVE_NODES; this->refine_consider_comms = Optimiser::ALL_NEIGH_COMMS; this->refine_routine = Optimiser::MERGE_NODES; this->refine_partition = true; this->consider_empty_community = true; this->max_comm_size = 0; igraph_rng_init(&rng, &igraph_rngtype_mt19937); igraph_rng_seed(&rng, time(NULL)); } Optimiser::~Optimiser() { igraph_rng_destroy(&rng); } /***************************************************************************** optimise the provided partition. *****************************************************************************/ double Optimiser::optimise_partition(MutableVertexPartition* partition) { size_t n = partition->get_graph()->vcount(); vector is_membership_fixed(n, false); return this->optimise_partition(partition, is_membership_fixed); } double Optimiser::optimise_partition(MutableVertexPartition* partition, vector const& is_membership_fixed) { return this->optimise_partition(partition, is_membership_fixed, this->max_comm_size); } double Optimiser::optimise_partition(MutableVertexPartition* partition, vector const& is_membership_fixed, size_t max_comm_size) { vector partitions(1); partitions[0] = partition; vector layer_weights(1, 1.0); return this->optimise_partition(partitions, layer_weights, is_membership_fixed, max_comm_size); } double Optimiser::optimise_partition(vector partitions, vector layer_weights, vector const& is_membership_fixed) { return this->optimise_partition(partitions, layer_weights, is_membership_fixed, this->max_comm_size); } /***************************************************************************** optimise the providede partitions simultaneously. We here use the sum of the difference of the moves as the overall quality function, each partition weighted by the layer weight. *****************************************************************************/ /***************************************************************************** optimise the provided partition. *****************************************************************************/ double Optimiser::optimise_partition(vector partitions, vector layer_weights, vector const& is_membership_fixed, size_t max_comm_size) { #ifdef DEBUG cerr << "void Optimiser::optimise_partition(vector partitions, vector layer_weights, vector const& is_membership_fixed, size_t max_comm_size)" << endl; #endif double q = 0.0; // Number of multiplex layers size_t nb_layers = partitions.size(); if (nb_layers == 0) throw Exception("No partitions provided."); // Get graphs for all layers vector graphs(nb_layers); for (size_t layer = 0; layer < nb_layers; layer++) graphs[layer] = partitions[layer]->get_graph(); // Number of nodes in the graphs. Should be the same across // all graphs, so we only take the first one. size_t n = graphs[0]->vcount(); // Make sure that all graphs contain the exact same number of nodes. // We assume the index of each vertex in the graph points to the // same node (but then in a different layer). for (Graph* graph : graphs) if (graph->vcount() != n) throw Exception("Number of nodes are not equal for all graphs."); // Get the fixed membership for fixed nodes vector fixed_nodes; vector fixed_membership(n); for (size_t v = 0; v < n; v++) { if (is_membership_fixed[v]) { fixed_nodes.push_back(v); fixed_membership[v] = partitions[0]->membership(v); } } // Initialize the vector of the collapsed graphs for all layers vector collapsed_graphs(nb_layers); vector collapsed_partitions(nb_layers); // Declare the collapsed_graph variable which will contain the graph // collapsed by its communities. We will use this variables at each // further iteration, so we don't keep a collapsed graph at each pass. for (size_t layer = 0; layer < nb_layers; layer++) { collapsed_graphs[layer] = graphs[layer]; collapsed_partitions[layer] = partitions[layer]; } // Declare which nodes in the collapsed graph are fixed, which to start is // simply equal to is_membership_fixed vector is_collapsed_membership_fixed(is_membership_fixed); // This reflects the aggregate node, which to start with is simply equal to the graph. vector aggregate_node_per_individual_node = range(n); bool aggregate_further = true; // As long as there remains improvement iterate double improv = 0.0; do { // Optimise partition for collapsed graph #ifdef DEBUG q = 0.0; for (size_t layer = 0; layer < nb_layers; layer++) q += partitions[layer]->quality()*layer_weights[layer]; cerr << "Quality before moving " << q << endl; #endif if (this->optimise_routine == Optimiser::MOVE_NODES) improv += this->move_nodes(collapsed_partitions, layer_weights, is_collapsed_membership_fixed, this->consider_comms, this->consider_empty_community, false, max_comm_size); else if (this->optimise_routine == Optimiser::MERGE_NODES) improv += this->merge_nodes(collapsed_partitions, layer_weights, is_collapsed_membership_fixed, this->consider_comms, false, max_comm_size); #ifdef DEBUG cerr << "Found " << collapsed_partitions[0]->n_communities() << " communities, improved " << improv << endl; q = 0.0; for (size_t layer = 0; layer < nb_layers; layer++) q += partitions[layer]->quality()*layer_weights[layer]; cerr << "Quality after moving " << q << endl; #endif // DEBUG // Make sure improvement on coarser scale is reflected on the // scale of the graph as a whole. for (size_t layer = 0; layer < nb_layers; layer++) { if (collapsed_partitions[layer] != partitions[layer]) { if (this->refine_partition) partitions[layer]->from_coarse_partition(collapsed_partitions[layer], aggregate_node_per_individual_node); else partitions[layer]->from_coarse_partition(collapsed_partitions[layer]); } } #ifdef DEBUG q = 0.0; for (size_t layer = 0; layer < nb_layers; layer++) q += partitions[layer]->quality()*layer_weights[layer]; cerr << "Quality on finer partition " << q << endl; #endif // DEBUG #ifdef DEBUG cerr << "Number of communities: " << partitions[0]->n_communities() << endl; #endif // Collapse graph (i.e. community graph) // If we do refine the partition, we separate communities in slightly more // fine-grained parts for which we collapse the graph. vector sub_collapsed_partitions(nb_layers); vector new_collapsed_graphs(nb_layers); vector new_collapsed_partitions(nb_layers); if (this->refine_partition) { // First create a new partition, which should be a sub partition // of the collapsed partition, i.e. such that all clusters of // the partition are strictly partitioned in the subpartition. #ifdef DEBUG cerr << "\tBefore SLM " << collapsed_partitions[0]->n_communities() << " communities." << endl; #endif for (size_t layer = 0; layer < nb_layers; layer++) { sub_collapsed_partitions[layer] = collapsed_partitions[layer]->create(collapsed_graphs[layer]); } // Then move around nodes but restrict movement to within original communities. #ifdef DEBUG cerr << "\tStarting refinement with " << sub_collapsed_partitions[0]->n_communities() << " communities." << endl; #endif if (this->refine_routine == Optimiser::MOVE_NODES) this->move_nodes_constrained(sub_collapsed_partitions, layer_weights, refine_consider_comms, collapsed_partitions[0], max_comm_size); else if (this->refine_routine == Optimiser::MERGE_NODES) this->merge_nodes_constrained(sub_collapsed_partitions, layer_weights, refine_consider_comms, collapsed_partitions[0], max_comm_size); #ifdef DEBUG cerr << "\tAfter applying refinement found " << sub_collapsed_partitions[0]->n_communities() << " communities." << endl; #endif // Determine new aggregate node per individual node for (size_t v = 0; v < n; v++) { size_t aggregate_node = aggregate_node_per_individual_node[v]; aggregate_node_per_individual_node[v] = sub_collapsed_partitions[0]->membership(aggregate_node); } // Collapse graph based on sub collapsed partition for (size_t layer = 0; layer < nb_layers; layer++) { new_collapsed_graphs[layer] = collapsed_graphs[layer]->collapse_graph(sub_collapsed_partitions[layer]); } // Determine the membership for the collapsed graph vector new_collapsed_membership(new_collapsed_graphs[0]->vcount()); // Every node within the collapsed graph should be assigned // to the community of the original partition before the refinement. // We thus check for each node what the community is in the refined partition // and set the membership equal to the original partition (i.e. // even though the aggregation may be slightly different, the // membership of the aggregated nodes is as indicated by the original partition.) #ifdef DEBUG //cerr << "Refinement\tOrig" << endl; #endif // DEBUG for (size_t v = 0; v < collapsed_graphs[0]->vcount(); v++) { size_t new_aggregate_node = sub_collapsed_partitions[0]->membership(v); new_collapsed_membership[new_aggregate_node] = collapsed_partitions[0]->membership(v); #ifdef DEBUG //cerr << sub_collapsed_partition->membership(v) << "\t" << sub_collapsed_partition->membership(v) << endl; #endif // DEBUG } // Determine which collapsed nodes are fixed is_collapsed_membership_fixed.clear(); is_collapsed_membership_fixed.resize(new_collapsed_graphs[0]->vcount(), false); for (size_t v = 0; v < n; v++) if (is_membership_fixed[v]) is_collapsed_membership_fixed[aggregate_node_per_individual_node[v]] = true; // Create new collapsed partition for (size_t layer = 0; layer < nb_layers; layer++) { delete sub_collapsed_partitions[layer]; new_collapsed_partitions[layer] = collapsed_partitions[layer]->create(new_collapsed_graphs[layer], new_collapsed_membership); } } else { for (size_t layer = 0; layer < nb_layers; layer++) { new_collapsed_graphs[layer] = collapsed_graphs[layer]->collapse_graph(collapsed_partitions[layer]); // Create collapsed partition (i.e. default partition of each node in its own community). new_collapsed_partitions[layer] = collapsed_partitions[layer]->create(new_collapsed_graphs[layer]); #ifdef DEBUG cerr << "Layer " << layer << endl; cerr << "Old collapsed graph " << collapsed_graphs[layer] << ", vcount is " << collapsed_graphs[layer]->vcount() << endl; cerr << "New collapsed graph " << new_collapsed_graphs[layer] << ", vcount is " << new_collapsed_graphs[layer]->vcount() << endl; #endif } } // Determine whether to aggregate further // If all is fixed, no need to aggregate aggregate_further = false; for (const bool& membership_fixed : is_collapsed_membership_fixed) { if(!membership_fixed) { aggregate_further = true; break; } } // else, check whether anything has stirred since last time aggregate_further &= (new_collapsed_graphs[0]->vcount() < collapsed_graphs[0]->vcount()) && (collapsed_graphs[0]->vcount() > collapsed_partitions[0]->n_communities()); #ifdef DEBUG cerr << "Aggregate further " << aggregate_further << endl; #endif // Delete the previous collapsed partition and graph for (size_t layer = 0; layer < nb_layers; layer++) { if (collapsed_partitions[layer] != partitions[layer]) delete collapsed_partitions[layer]; if (collapsed_graphs[layer] != graphs[layer]) delete collapsed_graphs[layer]; } // and set them to the new one. collapsed_partitions = new_collapsed_partitions; collapsed_graphs = new_collapsed_graphs; #ifdef DEBUG for (size_t layer = 0; layer < nb_layers; layer++) { cerr << "Calculate partition " << layer << " quality." << endl; q = partitions[layer]->quality()*layer_weights[layer]; cerr << "Calculate collapsed partition quality." << endl; double q_collapsed = 0.0; q_collapsed += collapsed_partitions[layer]->quality()*layer_weights[layer]; if (fabs(q - q_collapsed) > 1e-6) { cerr << "ERROR: Quality of original partition and collapsed partition are not equal." << endl; } cerr << "partition->quality()=" << q << ", collapsed_partition->quality()=" << q_collapsed << endl; cerr << "graph->total_weight()=" << graphs[layer]->total_weight() << ", collapsed_graph->total_weight()=" << collapsed_graphs[layer]->total_weight() << endl; cerr << "graph->vcount()=" << graphs[layer]->vcount() << ", collapsed_graph->vcount()=" << collapsed_graphs[layer]->vcount() << endl; cerr << "graph->ecount()=" << graphs[layer]->ecount() << ", collapsed_graph->ecount()=" << collapsed_graphs[layer]->ecount() << endl; cerr << "graph->is_directed()=" << graphs[layer]->is_directed() << ", collapsed_graph->is_directed()=" << collapsed_graphs[layer]->is_directed() << endl; cerr << "graph->correct_self_loops()=" << graphs[layer]->correct_self_loops() << ", collapsed_graph->correct_self_loops()=" << collapsed_graphs[layer]->correct_self_loops() << endl << endl; } #endif // DEBUG } while (aggregate_further); // Clean up memory after use. for (size_t layer = 0; layer < nb_layers; layer++) { if (collapsed_partitions[layer] != partitions[layer]) delete collapsed_partitions[layer]; if (collapsed_graphs[layer] != graphs[layer]) delete collapsed_graphs[layer]; } // Make sure the resulting communities are called 0,...,r-1 // where r is the number of communities. The exception is fixed // nodes which should keep the numbers of the original communities q = 0.0; partitions[0]->renumber_communities(); partitions[0]->renumber_communities(fixed_nodes, fixed_membership); vector const& membership = partitions[0]->membership(); // We only renumber the communities for the first graph, // since the communities for the other graphs should just be equal // to the membership of the first graph. for (size_t layer = 1; layer < nb_layers; layer++) { partitions[layer]->set_membership(membership); q += partitions[layer]->quality()*layer_weights[layer]; } return improv; } /***************************************************************************** Move nodes to other communities depending on how other communities are considered, see consider_comms parameter of the class. Parameters: partition -- The partition to optimise. ******************************************************************************/ double Optimiser::move_nodes(MutableVertexPartition* partition) { return this->move_nodes(partition, this->consider_comms); } double Optimiser::move_nodes(MutableVertexPartition* partition, int consider_comms) { vector is_membership_fixed(partition->get_graph()->vcount()); return this->move_nodes(partition, is_membership_fixed, consider_comms, false); } double Optimiser::move_nodes(MutableVertexPartition* partition, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes) { return this->move_nodes(partition, is_membership_fixed, consider_comms, renumber_fixed_nodes, this->max_comm_size); } double Optimiser::move_nodes(MutableVertexPartition* partition, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes, size_t max_comm_size) { vector partitions(1); partitions[0] = partition; vector layer_weights(1, 1.0); return this->move_nodes(partitions, layer_weights, is_membership_fixed, consider_comms, this->consider_empty_community, renumber_fixed_nodes, max_comm_size); } double Optimiser::merge_nodes(MutableVertexPartition* partition) { return this->merge_nodes(partition, this->consider_comms); } double Optimiser::merge_nodes(MutableVertexPartition* partition, int consider_comms) { vector is_membership_fixed(partition->get_graph()->vcount()); return this->merge_nodes(partition, is_membership_fixed, consider_comms, false); } double Optimiser::merge_nodes(MutableVertexPartition* partition, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes) { return this->merge_nodes(partition, is_membership_fixed, consider_comms, renumber_fixed_nodes, this->max_comm_size); } double Optimiser::merge_nodes(MutableVertexPartition* partition, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes, size_t max_comm_size) { vector partitions(1); partitions[0] = partition; vector layer_weights(1, 1.0); return this->merge_nodes(partitions, layer_weights, is_membership_fixed, consider_comms, renumber_fixed_nodes, max_comm_size); } double Optimiser::move_nodes_constrained(MutableVertexPartition* partition, MutableVertexPartition* constrained_partition) { return this->move_nodes_constrained(partition, this->refine_consider_comms, constrained_partition); } double Optimiser::move_nodes_constrained(MutableVertexPartition* partition, int consider_comms, MutableVertexPartition* constrained_partition) { return this->move_nodes_constrained(partition, consider_comms, constrained_partition, this->max_comm_size); } double Optimiser::move_nodes_constrained(MutableVertexPartition* partition, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size) { vector partitions(1); partitions[0] = partition; vector layer_weights(1, 1.0); return this->move_nodes_constrained(partitions, layer_weights, consider_comms, constrained_partition, max_comm_size); } double Optimiser::merge_nodes_constrained(MutableVertexPartition* partition, MutableVertexPartition* constrained_partition) { return this->merge_nodes_constrained(partition, this->refine_consider_comms, constrained_partition); } double Optimiser::merge_nodes_constrained(MutableVertexPartition* partition, int consider_comms, MutableVertexPartition* constrained_partition) { return this->merge_nodes_constrained(partition, consider_comms, constrained_partition, this->max_comm_size); } double Optimiser::merge_nodes_constrained(MutableVertexPartition* partition, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size) { vector partitions(1); partitions[0] = partition; vector layer_weights(1, 1.0); return this->merge_nodes_constrained(partitions, layer_weights, consider_comms, constrained_partition, max_comm_size); } /***************************************************************************** Move nodes to neighbouring communities such that each move improves the given quality function maximally (i.e. greedily) for multiple layers, i.e. for multiplex networks. Each node will be in the same community in each layer, but the method may be different, or the weighting may be different for different layers. Notably, this can be used in the case of negative links, where you would like to weigh the negative links with a negative weight. Parameters: partitions -- The partitions to optimise. layer_weights -- The weights used for the different layers. ******************************************************************************/ double Optimiser::move_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, bool renumber_fixed_nodes) { return this->move_nodes(partitions, layer_weights, is_membership_fixed, this->consider_comms, this->consider_empty_community, renumber_fixed_nodes); } double Optimiser::move_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, int consider_empty_community) { return this->move_nodes(partitions, layer_weights, is_membership_fixed, consider_comms, consider_empty_community, true); } double Optimiser::move_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, int consider_empty_community, bool renumber_fixed_nodes) { return this->move_nodes(partitions, layer_weights, is_membership_fixed, consider_comms, consider_empty_community, renumber_fixed_nodes, this->max_comm_size); } double Optimiser::move_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, int consider_empty_community, bool renumber_fixed_nodes, size_t max_comm_size) { #ifdef DEBUG cerr << "double Optimiser::move_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, int consider_empty_community, bool renumber_fixed_nodes, size_t max_comm_size)" << endl; #endif // Number of multiplex layers size_t nb_layers = partitions.size(); if (nb_layers == 0) return -1.0; // Get graphs vector graphs(nb_layers); for (size_t layer = 0; layer < nb_layers; layer++) graphs[layer] = partitions[layer]->get_graph(); // Number of nodes in the graph size_t n = graphs[0]->vcount(); // Get the fixed membership for fixed nodes vector fixed_nodes; vector fixed_membership(n); if (renumber_fixed_nodes) { for (size_t v = 0; v < n; v++) { if (is_membership_fixed[v]) { fixed_nodes.push_back(v); fixed_membership[v] = partitions[0]->membership(v); } } } // Total improvement while moving nodes double total_improv = 0.0; for (Graph* graph : graphs) if (graph->vcount() != n) throw Exception("Number of nodes are not equal for all graphs."); // Number of moved nodes during one loop size_t nb_moves = 0; // Fixed nodes are also stable nodes vector is_node_stable(is_membership_fixed); // Establish vertex order // We normally initialize the normal vertex order // of considering node 0,1,... // But if we use a random order, we shuffle this order. // Also, we skip fixed nodes from the queue for efficiency reasons vector nodes; for (size_t v = 0; v != is_membership_fixed.size(); v++) { if (!is_membership_fixed[v]) nodes.push_back(v); } shuffle(nodes, &rng); deque vertex_order(nodes.begin(), nodes.end()); // Initialize the degree vector // If we want to debug the function, we will calculate some additional values. // In particular, the following consistencies could be checked: // (1) - The difference in the quality function after a move should match // the reported difference when calling diff_move. // (2) - The quality function should be exactly the same value after // aggregating/collapsing the graph. vector comm_added(partitions[0]->n_communities(), false); vector comms; // As long as the queue is not empty while(!vertex_order.empty()) { size_t v = vertex_order.front(); vertex_order.pop_front(); // What is the current community of the node (this should be the same for all layers) size_t v_comm = partitions[0]->membership(v); if (consider_comms == ALL_COMMS) { for(size_t comm = 0; comm < partitions[0]->n_communities(); comm++) { for (size_t layer = 0; layer < nb_layers; layer++) { if (partitions[layer]->cnodes(comm) > 0 && !comm_added[comm]) { comms.push_back(comm); comm_added[comm] = true; break; // Break from for loop in layer } } } } else if (consider_comms == ALL_NEIGH_COMMS) { /****************************ALL NEIGH COMMS*****************************/ for (size_t layer = 0; layer < nb_layers; layer++) { for (size_t comm : partitions[layer]->get_neigh_comms(v, IGRAPH_ALL)) { if (!comm_added[comm]) { comms.push_back(comm); comm_added[comm] = true; } } } } else if (consider_comms == RAND_COMM) { /****************************RAND COMM***********************************/ size_t rand_comm = partitions[0]->membership(graphs[0]->get_random_node(&rng)); // No need to check if random_comm is already added, we only add one comm comms.push_back(rand_comm); comm_added[rand_comm] = true; } else if (consider_comms == RAND_NEIGH_COMM) { /****************************RAND NEIGH COMM*****************************/ size_t rand_layer = get_random_int(0, nb_layers - 1, &rng); if (graphs[rand_layer]->degree(v, IGRAPH_ALL) > 0) { size_t rand_comm = partitions[0]->membership(graphs[rand_layer]->get_random_neighbour(v, IGRAPH_ALL, &rng)); // No need to check if random_comm is already added, we only add one comm comms.push_back(rand_comm); comm_added[rand_comm] = true; } } // Check if we should move to an empty community if (consider_empty_community) { if ( partitions[0]->cnodes(v_comm) > 1 ) // We should not move a node when it is already in its own empty community (this may otherwise create more empty communities than nodes) { size_t n_comms = partitions[0]->n_communities(); size_t comm = partitions[0]->get_empty_community(); #ifdef DEBUG cerr << "Checking empty community (" << comm << ") for partition " << partitions[0] << endl; #endif comms.push_back(comm); if (partitions[0]->n_communities() > n_comms) { // If the empty community has just been added, we need to make sure // that is has also been added to the other layers for (size_t layer = 1; layer < nb_layers; layer++) partitions[layer]->add_empty_community(); comm_added.push_back(true); } } } #ifdef DEBUG cerr << "Consider " << comms.size() << " communities for moving." << endl; #endif size_t max_comm = v_comm; double max_improv = (0 < max_comm_size && max_comm_size < partitions[0]->csize(v_comm)) ? -INFINITY : 10*DBL_EPSILON; size_t v_size = graphs[0]->node_size(v); for (size_t comm : comms) { // reset comm_added to all false comm_added[comm] = false; // Do not create too-large communities. if (0 < max_comm_size && max_comm_size < partitions[0]->csize(comm) + v_size) { continue; } double possible_improv = 0.0; // Consider the improvement of moving to a community for all layers for (size_t layer = 0; layer < nb_layers; layer++) { // Make sure to multiply it by the weight per layer possible_improv += layer_weights[layer]*partitions[layer]->diff_move(v, comm); } if (possible_improv > max_improv) { max_comm = comm; max_improv = possible_improv; } } // Clear comms comms.clear(); is_node_stable[v] = true; // If we actually plan to move the node if (max_comm != v_comm) { // Keep track of improvement total_improv += max_improv; #ifdef DEBUG // If we are debugging, calculate quality function double q_improv = 0; #endif for (size_t layer = 0; layer < nb_layers; layer++) { MutableVertexPartition* partition = partitions[layer]; #ifdef DEBUG // If we are debugging, calculate quality function double q1 = partition->quality(); #endif // Actually move the node partition->move_node(v, max_comm); #ifdef DEBUG // If we are debugging, calculate quality function // and report difference double q2 = partition->quality(); double q_delta = layer_weights[layer]*(q2 - q1); q_improv += q_delta; cerr << "Move node " << v << " from " << v_comm << " to " << max_comm << " for layer " << layer << " (diff_move=" << max_improv << ", q2 - q1=" << q_delta << ")" << endl; #endif } #ifdef DEBUG if (fabs(q_improv - max_improv) > 1e-6) { cerr << "ERROR: Inconsistency while moving nodes, improvement as measured by quality function did not equal the improvement measured by the diff_move function." << endl << " (diff_move=" << max_improv << ", q2 - q1=" << q_improv << ")" << endl; } #endif // Mark neighbours as unstable (if not in new community and not fixed) for (Graph* graph : graphs) { for (size_t u : graph->get_neighbours(v, IGRAPH_ALL)) { // If the neighbour was stable and is not in the new community, we // should mark it as unstable, and add it to the queue, skipping // fixed nodes if (is_node_stable[u] && partitions[0]->membership(u) != max_comm && !is_membership_fixed[u]) { vertex_order.push_back(u); is_node_stable[u] = false; } } } // Keep track of number of moves nb_moves += 1; } } partitions[0]->renumber_communities(); if (renumber_fixed_nodes) partitions[0]->renumber_communities(fixed_nodes, fixed_membership); vector const& membership = partitions[0]->membership(); for (size_t layer = 1; layer < nb_layers; layer++) { partitions[layer]->set_membership(membership); #ifdef DEBUG cerr << "Renumbered communities for layer " << layer << " for " << partitions[layer]->n_communities() << " communities." << endl; #endif //DEBUG } return total_improv; } double Optimiser::merge_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, bool renumber_fixed_nodes) { return this->merge_nodes(partitions, layer_weights, is_membership_fixed, this->consider_comms, renumber_fixed_nodes); } double Optimiser::merge_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes) { return this->merge_nodes(partitions, layer_weights, is_membership_fixed, consider_comms, renumber_fixed_nodes, this->max_comm_size); } double Optimiser::merge_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes, size_t max_comm_size) { #ifdef DEBUG cerr << "double Optimiser::merge_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes, size_t max_comm)" << std::endl; #endif // Number of multiplex layers size_t nb_layers = partitions.size(); if (nb_layers == 0) return -1.0; // Get graphs vector graphs(nb_layers); for (size_t layer = 0; layer < nb_layers; layer++) graphs[layer] = partitions[layer]->get_graph(); // Number of nodes in the graph size_t n = graphs[0]->vcount(); // Get the fixed membership for fixed nodes vector fixed_nodes; vector fixed_membership(n); if (renumber_fixed_nodes) { for (size_t v = 0; v < n; v++) { if (is_membership_fixed[v]) { fixed_nodes.push_back(v); fixed_membership[v] = partitions[0]->membership(v); } } } // Total improvement while merging nodes double total_improv = 0.0; for (Graph* graph : graphs) if (graph->vcount() != n) throw Exception("Number of nodes are not equal for all graphs."); // Establish vertex order, skipping fixed nodes // We normally initialize the normal vertex order // of considering node 0,1,... vector vertex_order; for (size_t v = 0; v != n; v++) if (!is_membership_fixed[v]) vertex_order.push_back(v); // But if we use a random order, we shuffle this order. shuffle(vertex_order, &rng); vector comm_added(partitions[0]->n_communities(), false); vector comms; // Iterate over all nodes for (size_t v : vertex_order) { // What is the current community of the node (this should be the same for all layers) size_t v_comm = partitions[0]->membership(v); // Clear comms for (size_t comm : comms) comm_added[comm] = false; comms.clear(); #ifdef DEBUG cerr << "Consider moving node " << v << " from " << v_comm << "." << endl; #endif if (partitions[0]->cnodes(v_comm) == 1) { if (consider_comms == ALL_COMMS) { for(size_t comm = 0; comm < partitions[0]->n_communities(); comm++) { for (size_t layer = 0; layer < nb_layers; layer++) { if (partitions[layer]->cnodes(comm) > 0 && !comm_added[comm]) { comms.push_back(comm); comm_added[comm] = true; break; // Break from for loop in layer } } } } else if (consider_comms == ALL_NEIGH_COMMS) { /****************************ALL NEIGH COMMS*****************************/ for (size_t layer = 0; layer < nb_layers; layer++) { for (size_t comm : partitions[layer]->get_neigh_comms(v, IGRAPH_ALL)) { if (!comm_added[comm]) { comms.push_back(comm); comm_added[comm] = true; } } } } else if (consider_comms == RAND_COMM) { /****************************RAND COMM***********************************/ size_t rand_comm = partitions[0]->membership(graphs[0]->get_random_node(&rng)); // No need to check if random_comm is already added, we only add one comm comms.push_back(rand_comm); comm_added[rand_comm] = true; } else if (consider_comms == RAND_NEIGH_COMM) { /****************************RAND NEIGH COMM*****************************/ size_t rand_layer = get_random_int(0, nb_layers - 1, &rng); size_t k = graphs[rand_layer]->degree(v, IGRAPH_ALL); if (k > 0) { // Make sure there is also a probability not to move the node if (get_random_int(0, k, &rng) > 0) { size_t rand_comm = partitions[0]->membership(graphs[rand_layer]->get_random_neighbour(v, IGRAPH_ALL, &rng)); // No need to check if random_comm is already added, we only add one comm comms.push_back(rand_comm); comm_added[rand_comm] = true; } } } #ifdef DEBUG cerr << "Consider " << comms.size() << " communities for moving node " << v << "." << endl; #endif size_t max_comm = v_comm; double max_improv = (0 < max_comm_size && max_comm_size < partitions[0]->csize(v_comm)) ? -INFINITY : 0; size_t v_size = graphs[0]->node_size(v); for (size_t comm : comms) { // Do not create too-large communities. if (0 < max_comm_size && max_comm_size < partitions[0]->csize(comm) + v_size) { continue; } double possible_improv = 0.0; // Consider the improvement of moving to a community for all layers for (size_t layer = 0; layer < nb_layers; layer++) { // Make sure to multiply it by the weight per layer possible_improv += layer_weights[layer]*partitions[layer]->diff_move(v, comm); } #ifdef DEBUG cerr << "Improvement of " << possible_improv << " when move to " << comm << "." << endl; #endif if (possible_improv >= max_improv) { max_comm = comm; max_improv = possible_improv; } } // If we actually plan to move the node if (max_comm != v_comm) { // Keep track of improvement total_improv += max_improv; #ifdef DEBUG // If we are debugging, calculate quality function double q_improv = 0; #endif for (size_t layer = 0; layer < nb_layers; layer++) { MutableVertexPartition* partition = partitions[layer]; #ifdef DEBUG // If we are debugging, calculate quality function double q1 = partition->quality(); #endif // Actually move the node partition->move_node(v, max_comm); #ifdef DEBUG // If we are debugging, calculate quality function // and report difference double q2 = partition->quality(); double q_delta = layer_weights[layer]*(q2 - q1); q_improv += q_delta; cerr << "Move node " << v << " from " << v_comm << " to " << max_comm << " for layer " << layer << " (diff_move=" << max_improv << ", q2 - q1=" << q_delta << ")" << endl; #endif } #ifdef DEBUG if (fabs(q_improv - max_improv) > 1e-6) { cerr << "ERROR: Inconsistency while moving nodes, improvement as measured by quality function did not equal the improvement measured by the diff_move function." << endl << " (diff_move=" << max_improv << ", q2 - q1=" << q_improv << ")" << endl; } #endif } } } partitions[0]->renumber_communities(); if (renumber_fixed_nodes) partitions[0]->renumber_communities(fixed_nodes, fixed_membership); vector const& membership = partitions[0]->membership(); for (size_t layer = 1; layer < nb_layers; layer++) { partitions[layer]->set_membership(membership); #ifdef DEBUG cerr << "Renumbered communities for layer " << layer << " for " << partitions[layer]->n_communities() << " communities." << endl; #endif //DEBUG } return total_improv; } double Optimiser::move_nodes_constrained(vector partitions, vector layer_weights, MutableVertexPartition* constrained_partition) { return this->move_nodes_constrained(partitions, layer_weights, this->refine_consider_comms, constrained_partition); } double Optimiser::move_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition) { return this->move_nodes_constrained(partitions, layer_weights, refine_consider_comms, constrained_partition, this->max_comm_size); } double Optimiser::move_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size) { #ifdef DEBUG cerr << "double Optimiser::move_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size)" << std::endl; #endif // Number of multiplex layers size_t nb_layers = partitions.size(); if (nb_layers == 0) return -1.0; // Get graphs vector graphs(nb_layers); for (size_t layer = 0; layer < nb_layers; layer++) graphs[layer] = partitions[layer]->get_graph(); // Number of nodes in the graph size_t n = graphs[0]->vcount(); // Total improvement while moving nodes double total_improv = 0.0; for (size_t layer = 0; layer < nb_layers; layer++) if (graphs[layer]->vcount() != n) throw Exception("Number of nodes are not equal for all graphs."); // Number of moved nodes during one loop size_t nb_moves = 0; // Establish vertex order // We normally initialize the normal vertex order // of considering node 0,1,... vector is_node_stable(n, false); // But if we use a random order, we shuffle this order. vector nodes = range(n); shuffle(nodes, &rng); deque vertex_order(nodes.begin(), nodes.end()); vector< vector > constrained_comms = constrained_partition->get_communities(); // Initialize the degree vector // If we want to debug the function, we will calculate some additional values. // In particular, the following consistencies could be checked: // (1) - The difference in the quality function after a move should match // the reported difference when calling diff_move. // (2) - The quality function should be exactly the same value after // aggregating/collapsing the graph. vector comm_added(partitions[0]->n_communities(), false); vector comms; // As long as the queue is not empty while(!vertex_order.empty()) { size_t v = vertex_order.front(); vertex_order.pop_front(); // Clear comms for (size_t comm : comms) comm_added[comm] = false; comms.clear(); // What is the current community of the node (this should be the same for all layers) size_t v_comm = partitions[0]->membership(v); if (consider_comms == ALL_COMMS) { // Add all communities to the set comms that are within the constrained community. size_t v_constrained_comm = constrained_partition->membership(v); for (size_t u : constrained_comms[v_constrained_comm]) { size_t u_comm = partitions[0]->membership(u); if (!comm_added[u_comm]) { comms.push_back(u_comm); comm_added[u_comm] = true; } } } else if (consider_comms == ALL_NEIGH_COMMS) { /****************************ALL NEIGH COMMS*****************************/ for (size_t layer = 0; layer < nb_layers; layer++) { for (size_t comm : partitions[layer]->get_neigh_comms(v, IGRAPH_ALL, constrained_partition->membership())) { if (!comm_added[comm]) { comms.push_back(comm); comm_added[comm] = true; } } } } else if (consider_comms == RAND_COMM) { /****************************RAND COMM***********************************/ size_t v_constrained_comm = constrained_partition->membership(v); size_t random_idx = get_random_int(0, constrained_comms[v_constrained_comm].size() - 1, &rng); size_t rand_comm = constrained_comms[v_constrained_comm][random_idx]; // No need to check if random_comm is already added, we only add one comm comms.push_back(rand_comm); comm_added[rand_comm] = true; } else if (consider_comms == RAND_NEIGH_COMM) { /****************************RAND NEIGH COMM*****************************/ // Draw a random community among the neighbours, proportional to the // frequency of the communities among the neighbours. Notice this is no // longer vector all_neigh_comms_incl_dupes; for (size_t layer = 0; layer < nb_layers; layer++) { vector neigh_comm_layer = partitions[layer]->get_neigh_comms(v, IGRAPH_ALL, constrained_partition->membership()); all_neigh_comms_incl_dupes.insert(all_neigh_comms_incl_dupes.end(), neigh_comm_layer.begin(), neigh_comm_layer.end()); } if (all_neigh_comms_incl_dupes.size() > 0) { size_t random_idx = get_random_int(0, all_neigh_comms_incl_dupes.size() - 1, &rng); size_t rand_comm = all_neigh_comms_incl_dupes[random_idx]; // No need to check if random_comm is already added, we only add one comm comms.push_back(rand_comm); comm_added[rand_comm] = true; } } #ifdef DEBUG cerr << "Consider " << comms.size() << " communities for moving." << endl; #endif size_t max_comm = v_comm; double max_improv = (0 < max_comm_size && max_comm_size < partitions[0]->csize(v_comm)) ? -INFINITY : 10*DBL_EPSILON; size_t v_size = graphs[0]->node_size(v); for (size_t comm : comms) { // Do not create too-large communities. if (0 < max_comm_size && max_comm_size < partitions[0]->csize(comm) + v_size) { continue; } double possible_improv = 0.0; // Consider the improvement of moving to a community for all layers for (size_t layer = 0; layer < nb_layers; layer++) { // Make sure to multiply it by the weight per layer possible_improv += layer_weights[layer]*partitions[layer]->diff_move(v, comm); } // Check if improvement is best if (possible_improv > max_improv) { max_comm = comm; max_improv = possible_improv; } } is_node_stable[v] = true; // If we actually plan to move the nove if (max_comm != v_comm) { // Keep track of improvement total_improv += max_improv; #ifdef DEBUG // If we are debugging, calculate quality function double q_improv = 0; #endif for (size_t layer = 0; layer < nb_layers; layer++) { MutableVertexPartition* partition = partitions[layer]; #ifdef DEBUG // If we are debugging, calculate quality function double q1 = partition->quality(); #endif // Actually move the node partition->move_node(v, max_comm); #ifdef DEBUG // If we are debugging, calculate quality function // and report difference double q2 = partition->quality(); double q_delta = layer_weights[layer]*(q2 - q1); q_improv += q_delta; cerr << "Move node " << v << " from " << v_comm << " to " << max_comm << " for layer " << layer << " (diff_move=" << max_improv << ", q2 - q1=" << q_delta << ")" << endl; #endif } #ifdef DEBUG if (fabs(q_improv - max_improv) > 1e-6) { cerr << "ERROR: Inconsistency while moving nodes, improvement as measured by quality function did not equal the improvement measured by the diff_move function." << endl << " (diff_move=" << max_improv << ", q2 - q1=" << q_improv << ")" << endl; } #endif // Mark neighbours as unstable (if not in new community and not fixed) for (Graph* graph : graphs) { for (size_t u : graph->get_neighbours(v, IGRAPH_ALL)) { // If the neighbour was stable and is not in the new community, we // should mark it as unstable, and add it to the queue, skipping // fixed nodes if (is_node_stable[u] && partitions[0]->membership(u) != max_comm && constrained_partition->membership(u) == constrained_partition->membership(v)) { vertex_order.push_back(u); is_node_stable[u] = false; } } } // Keep track of number of moves nb_moves += 1; } #ifdef DEBUG cerr << "Moved " << nb_moves << " nodes." << endl; #endif } partitions[0]->renumber_communities(); vector const& membership = partitions[0]->membership(); for (size_t layer = 1; layer < nb_layers; layer++) { partitions[layer]->set_membership(membership); #ifdef DEBUG cerr << "Renumbered communities for layer " << layer << " for " << partitions[layer]->n_communities() << " communities." << endl; #endif //DEBUG } return total_improv; } double Optimiser::merge_nodes_constrained(vector partitions, vector layer_weights, MutableVertexPartition* constrained_partition) { return this->merge_nodes_constrained(partitions, layer_weights, this->refine_consider_comms, constrained_partition); } double Optimiser::merge_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition) { return this->merge_nodes_constrained(partitions, layer_weights, refine_consider_comms, constrained_partition, this->max_comm_size); } double Optimiser::merge_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size) { #ifdef DEBUG cerr << "double Optimiser::merge_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size)" << std::endl; #endif // Number of multiplex layers size_t nb_layers = partitions.size(); if (nb_layers == 0) return -1.0; // Get graphs vector graphs(nb_layers); for (size_t layer = 0; layer < nb_layers; layer++) graphs[layer] = partitions[layer]->get_graph(); // Number of nodes in the graph size_t n = graphs[0]->vcount(); // Total improvement while merging nodes double total_improv = 0.0; for (size_t layer = 0; layer < nb_layers; layer++) if (graphs[layer]->vcount() != n) throw Exception("Number of nodes are not equal for all graphs."); // Establish vertex order // We normally initialize the normal vertex order // of considering node 0,1,... vector vertex_order = range(n); // But if we use a random order, we shuffle this order. shuffle(vertex_order, &rng); vector< vector > constrained_comms = constrained_partition->get_communities(); vector comm_added(partitions[0]->n_communities(), false); vector comms; // For each node for (size_t v : vertex_order) { // What is the current community of the node (this should be the same for all layers) size_t v_comm = partitions[0]->membership(v); if (partitions[0]->cnodes(v_comm) == 1) { // Clear comms for (size_t comm : comms) comm_added[comm] = false; comms.clear(); if (consider_comms == ALL_COMMS) { // Add all communities to the set comms that are within the constrained community. size_t v_constrained_comm = constrained_partition->membership(v); for (size_t u : constrained_comms[v_constrained_comm]) { size_t u_comm = partitions[0]->membership(u); if (!comm_added[u_comm]) { comms.push_back(u_comm); comm_added[u_comm] = true; } } } else if (consider_comms == ALL_NEIGH_COMMS) { /****************************ALL NEIGH COMMS*****************************/ for (size_t layer = 0; layer < nb_layers; layer++) { for (size_t u : partitions[layer]->get_graph()->get_neighbours(v, IGRAPH_ALL)) { if (constrained_partition->membership(v) == constrained_partition->membership(u)) { size_t comm = partitions[layer]->membership(u); if (!comm_added[comm]) { comms.push_back(comm); comm_added[comm] = true; } } } } } else if (consider_comms == RAND_COMM) { /****************************RAND COMM***********************************/ size_t v_constrained_comm = constrained_partition->membership(v); size_t random_idx = get_random_int(0, constrained_comms[v_constrained_comm].size() - 1, &rng); size_t rand_comm = constrained_comms[v_constrained_comm][random_idx]; // No need to check if random_comm is already added, we only add one comm comms.push_back(rand_comm); comm_added[rand_comm] = true; } else if (consider_comms == RAND_NEIGH_COMM) { /****************************RAND NEIGH COMM*****************************/ // Draw a random community among the neighbours, proportional to the // frequency of the communities among the neighbours. Notice this is no // longer vector all_neigh_comms_incl_dupes; for (size_t layer = 0; layer < nb_layers; layer++) { vector neigh_comm_layer = partitions[layer]->get_neigh_comms(v, IGRAPH_ALL, constrained_partition->membership()); all_neigh_comms_incl_dupes.insert(all_neigh_comms_incl_dupes.end(), neigh_comm_layer.begin(), neigh_comm_layer.end()); } size_t k = all_neigh_comms_incl_dupes.size(); if (k > 0) { // Make sure there is also a probability not to move the node if (get_random_int(0, k, &rng) > 0) { size_t random_idx = get_random_int(0, k - 1, &rng); size_t rand_comm = all_neigh_comms_incl_dupes[random_idx]; // No need to check if random_comm is already added, we only add one comm comms.push_back(rand_comm); comm_added[rand_comm] = true; } } } #ifdef DEBUG cerr << "Consider " << comms.size() << " communities for moving." << endl; #endif size_t max_comm = v_comm; double max_improv = (0 < max_comm_size && max_comm_size < partitions[0]->csize(v_comm)) ? -INFINITY : 0; size_t v_size = graphs[0]->node_size(v); for (size_t comm : comms) { // reset comm_added to all false comm_added[comm] = false; // Do not create too-large communities. if (0 < max_comm_size && max_comm_size < partitions[0]->csize(comm) + v_size) { continue; } double possible_improv = 0.0; // Consider the improvement of moving to a community for all layers for (size_t layer = 0; layer < nb_layers; layer++) { // Make sure to multiply it by the weight per layer possible_improv += layer_weights[layer]*partitions[layer]->diff_move(v, comm); } if (possible_improv >= max_improv) { max_comm = comm; max_improv = possible_improv; } } // If we actually plan to move the node if (max_comm != v_comm) { // Keep track of improvement total_improv += max_improv; #ifdef DEBUG // If we are debugging, calculate quality function double q_improv = 0; #endif for (size_t layer = 0; layer < nb_layers; layer++) { MutableVertexPartition* partition = partitions[layer]; #ifdef DEBUG // If we are debugging, calculate quality function double q1 = partition->quality(); #endif // Actually move the node partition->move_node(v, max_comm); #ifdef DEBUG // If we are debugging, calculate quality function // and report difference double q2 = partition->quality(); double q_delta = layer_weights[layer]*(q2 - q1); q_improv += q_delta; cerr << "Move node " << v << " from " << v_comm << " to " << max_comm << " for layer " << layer << " (diff_move=" << max_improv << ", q2 - q1=" << q_delta << ")" << endl; #endif } #ifdef DEBUG if (fabs(q_improv - max_improv) > 1e-6) { cerr << "ERROR: Inconsistency while moving nodes, improvement as measured by quality function did not equal the improvement measured by the diff_move function." << endl << " (diff_move=" << max_improv << ", q2 - q1=" << q_improv << ")" << endl; } #endif } } } partitions[0]->renumber_communities(); vector const& membership = partitions[0]->membership(); for (size_t layer = 1; layer < nb_layers; layer++) { partitions[layer]->set_membership(membership); #ifdef DEBUG cerr << "Renumbered communities for layer " << layer << " for " << partitions[layer]->n_communities() << " communities." << endl; #endif //DEBUG } return total_improv; } leidenbase/src/leidenalg/SurpriseVertexPartition.h0000644000176200001440000000141414444673466022157 0ustar liggesusers#ifndef SURPRISEVERTEXPARTITION_H #define SURPRISEVERTEXPARTITION_H #include "MutableVertexPartition.h" #include using std::cerr; using std::endl; class SurpriseVertexPartition: public MutableVertexPartition { public: SurpriseVertexPartition(Graph* graph, vector const& membership); SurpriseVertexPartition(Graph* graph, SurpriseVertexPartition* partition); SurpriseVertexPartition(Graph* graph); virtual ~SurpriseVertexPartition(); virtual SurpriseVertexPartition* create(Graph* graph); virtual SurpriseVertexPartition* create(Graph* graph, vector const& membership); virtual double diff_move(size_t v, size_t new_comm); virtual double quality(); protected: private: }; #endif // SURPRISEVERTEXPARTITION_H leidenbase/src/leidenalg/LinearResolutionParameterVertexPartition.h0000644000176200001440000000135414445413042025464 0ustar liggesusers#ifndef LINEARRESOLUTIONPARAMETERVERTEXPARTITION_H #define LINEARRESOLUTIONPARAMETERVERTEXPARTITION_H #include "ResolutionParameterVertexPartition.h" class LinearResolutionParameterVertexPartition : public ResolutionParameterVertexPartition { public: LinearResolutionParameterVertexPartition(Graph* graph, vector membership, double resolution_parameter); LinearResolutionParameterVertexPartition(Graph* graph, vector membership); LinearResolutionParameterVertexPartition(Graph* graph, double resolution_parameter); LinearResolutionParameterVertexPartition(Graph* graph); virtual ~LinearResolutionParameterVertexPartition(); private: }; #endif // RESOLUTIONPARAMETERVERTEXPARTITION_H leidenbase/src/leidenalg/Optimiser.h0000644000176200001440000001753514444673466017241 0ustar liggesusers#ifndef OPTIMISER_H #define OPTIMISER_H #include "GraphHelper.h" #include "MutableVertexPartition.h" #include #include #include #include using std::cerr; using std::endl; using std::set; using std::map; /**************************************************************************** Class for doing community detection using the Leiden algorithm. Given a certain partition type is calls diff_move for trying to move a node to another community. It moves the node to the community that *maximises* this diff_move. If no further improvement is possible, the graph is aggregated (collapse_graph) and the method is reiterated on that graph. ****************************************************************************/ class Optimiser { public: Optimiser(); double optimise_partition(MutableVertexPartition* partition); double optimise_partition(MutableVertexPartition* partition, vector const& is_membership_fixed); double optimise_partition(MutableVertexPartition* partition, vector const& is_membership_fixed, size_t max_comm_size); template T* find_partition(Graph* graph); template T* find_partition(Graph* graph, double resolution_parameter); // The multiplex functions that simultaneously optimise multiple graphs and partitions (i.e. methods) // Each node will be in the same community in all graphs, and the graphs are expected to have identical nodes // Optionally we can loop over all possible communities instead of only the neighbours. In the case of negative // layer weights this may be necessary. double optimise_partition(vector partitions, vector layer_weights, vector const& is_membership_fixed); double optimise_partition(vector partitions, vector layer_weights, vector const& is_membership_fixed, size_t max_comm_size); double move_nodes(MutableVertexPartition* partition); double move_nodes(MutableVertexPartition* partition, int consider_comms); double move_nodes(MutableVertexPartition* partition, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes); double move_nodes(MutableVertexPartition* partition, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes, size_t max_comm_size); double move_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, bool renumber_fixed_nodes); double move_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, int consider_empty_community); double move_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, int consider_empty_community, bool renumber_fixed_nodes); double move_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, int consider_empty_community, bool renumber_fixed_nodes, size_t max_comm_size); double merge_nodes(MutableVertexPartition* partition); double merge_nodes(MutableVertexPartition* partition, int consider_comms); double merge_nodes(MutableVertexPartition* partition, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes); double merge_nodes(MutableVertexPartition* partition, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes, size_t max_comm_size); double merge_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, bool renumber_fixed_nodes); double merge_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes); double merge_nodes(vector partitions, vector layer_weights, vector const& is_membership_fixed, int consider_comms, bool renumber_fixed_nodes, size_t max_comm_size); double move_nodes_constrained(MutableVertexPartition* partition, MutableVertexPartition* constrained_partition); double move_nodes_constrained(MutableVertexPartition* partition, int consider_comms, MutableVertexPartition* constrained_partition); double move_nodes_constrained(MutableVertexPartition* partition, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size); double move_nodes_constrained(vector partitions, vector layer_weights, MutableVertexPartition* constrained_partition); double move_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition); double move_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size); double merge_nodes_constrained(MutableVertexPartition* partition, MutableVertexPartition* constrained_partition); double merge_nodes_constrained(MutableVertexPartition* partition, int consider_comms, MutableVertexPartition* constrained_partition); double merge_nodes_constrained(MutableVertexPartition* partition, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size); double merge_nodes_constrained(vector partitions, vector layer_weights, MutableVertexPartition* constrained_partition); double merge_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition); double merge_nodes_constrained(vector partitions, vector layer_weights, int consider_comms, MutableVertexPartition* constrained_partition, size_t max_comm_size); inline void set_rng_seed(size_t seed) { igraph_rng_seed(&rng, seed); }; virtual ~Optimiser(); int consider_comms; // Indicates how communities will be considered for improvement. Should be one of the parameters below int refine_partition; // Refine partition before aggregating int refine_consider_comms; // Indicates how communities will be considered for improvement within the refinement. Should be one of the parameters below int optimise_routine; // What routine to use for optimisation int refine_routine; // What routine to use for optimisation int consider_empty_community; // Determine whether to consider moving nodes to an empty community size_t max_comm_size; // Constrain the maximal community size. static const int ALL_COMMS = 1; // Consider all communities for improvement. static const int ALL_NEIGH_COMMS = 2; // Consider all neighbour communities for improvement. static const int RAND_COMM = 3; // Consider a random commmunity for improvement. static const int RAND_NEIGH_COMM = 4; // Consider a random community among the neighbours for improvement. static const int MOVE_NODES = 10; // Use move node routine static const int MERGE_NODES = 11; // Use merge node routine protected: private: void print_settings(); igraph_rng_t rng; }; template T* Optimiser::find_partition(Graph* graph) { T* partition = new T(graph); #ifdef DEBUG cerr << "Use default partition (all nodes in own community)" << endl; #endif this->optimise_partition(partition); return partition; } template T* Optimiser::find_partition(Graph* graph, double resolution_parameter) { T* partition = new T(graph, resolution_parameter); #ifdef DEBUG cerr << "Use default partition (all nodes in own community)" << endl; #endif this->optimise_partition(partition); return partition; } #endif // OPTIMISER_H leidenbase/src/leidenalg/ResolutionParameterVertexPartition.h0000644000176200001440000000201314445413207024325 0ustar liggesusers#ifndef RESOLUTIONPARAMETERVERTEXPARTITION_H #define RESOLUTIONPARAMETERVERTEXPARTITION_H #include "MutableVertexPartition.h" class ResolutionParameterVertexPartition : public MutableVertexPartition { public: ResolutionParameterVertexPartition(Graph* graph, vector membership, double resolution_parameter); ResolutionParameterVertexPartition(Graph* graph, vector membership); ResolutionParameterVertexPartition(Graph* graph, double resolution_parameter); ResolutionParameterVertexPartition(Graph* graph); virtual ~ResolutionParameterVertexPartition(); double resolution_parameter; virtual double quality() { return this->quality(this->resolution_parameter); }; virtual double quality(double resolution_parameter) { throw Exception("Function not implemented. This should be implented in a derived class, since the base class does not implement a specific method."); }; private: }; #endif // RESOLUTIONPARAMETERVERTEXPARTITION_H leidenbase/src/leidenalg/ResolutionParameterVertexPartition.cpp0000644000176200001440000000173114444671323024672 0ustar liggesusers#include "ResolutionParameterVertexPartition.h" ResolutionParameterVertexPartition::ResolutionParameterVertexPartition(Graph* graph, vector membership, double resolution_parameter) : MutableVertexPartition(graph, membership) { this->resolution_parameter = resolution_parameter; } ResolutionParameterVertexPartition::ResolutionParameterVertexPartition(Graph* graph, vector membership) : MutableVertexPartition(graph, membership) { this->resolution_parameter = 1.0; } ResolutionParameterVertexPartition::ResolutionParameterVertexPartition(Graph* graph, double resolution_parameter) : MutableVertexPartition(graph) { this->resolution_parameter = resolution_parameter; } ResolutionParameterVertexPartition::ResolutionParameterVertexPartition(Graph* graph) : MutableVertexPartition(graph) { this->resolution_parameter = 1.0; } ResolutionParameterVertexPartition::~ResolutionParameterVertexPartition() { } leidenbase/src/leidenalg/SignificanceVertexPartition.h0000644000176200001440000000125114445413242022705 0ustar liggesusers#ifndef SIGNIFICANCEVERTEXPARTITION_H #define SIGNIFICANCEVERTEXPARTITION_H #include "MutableVertexPartition.h" class SignificanceVertexPartition : public MutableVertexPartition { public: SignificanceVertexPartition(Graph* graph, vector const& membership); SignificanceVertexPartition(Graph* graph); virtual ~SignificanceVertexPartition(); virtual SignificanceVertexPartition* create(Graph* graph); virtual SignificanceVertexPartition* create(Graph* graph, vector const& membership); virtual double diff_move(size_t v, size_t new_comm); virtual double quality(); protected: private: }; #endif // SIGNIFICANCEVERTEXPARTITION_H leidenbase/src/leidenalg/MutableVertexPartition.cpp0000644000176200001440000010142014445371145022253 0ustar liggesusers#include "MutableVertexPartition.h" #undef DEBUG #ifdef DEBUG using std::cerr; using std::endl; #endif /**************************************************************************** Create a new vertex partition. Parameters: graph -- The igraph.Graph on which this partition is defined. membership=None -- The membership vector of this partition, i.e. an community number for each node. So membership[i] = c implies that node i is in community c. If None, it is initialised with each node in its own community. weight_attr=None -- What edge attribute should be used as a weight for the edges? If None, the weight defaults to 1. size_attr=None -- What node attribute should be used for keeping track of the size of the node? In some methods (e.g. CPM or Significance), we need to keep track of the total size of the community. So when we aggregate/collapse the graph, we should know how many nodes were in a community. If None, the size of a node defaults to 1. self_weight_attr=None -- What node attribute should be used for the self weight? If None, the self_weight is recalculated each time.""" *****************************************************************************/ MutableVertexPartition::MutableVertexPartition(Graph* graph, vector const& membership) { this->destructor_delete_graph = false; this->graph = graph; if (membership.size() != graph->vcount()) { throw Exception("Membership vector has incorrect size."); } this->_membership = membership; this->init_admin(); } MutableVertexPartition::MutableVertexPartition(Graph* graph) { this->destructor_delete_graph = false; this->graph = graph; this->_membership = range(graph->vcount()); this->init_admin(); } MutableVertexPartition* MutableVertexPartition::create(Graph* graph) { return new MutableVertexPartition(graph); } MutableVertexPartition* MutableVertexPartition::create(Graph* graph, vector const& membership) { return new MutableVertexPartition(graph, membership); } MutableVertexPartition::~MutableVertexPartition() { this->clean_mem(); if (this->destructor_delete_graph) delete this->graph; } void MutableVertexPartition::clean_mem() { } size_t MutableVertexPartition::csize(size_t comm) { if (comm < this->_csize.size()) return this->_csize[comm]; else return 0; } size_t MutableVertexPartition::cnodes(size_t comm) { if (comm < this->_cnodes.size()) return this->_cnodes[comm]; else return 0; } vector MutableVertexPartition::get_community(size_t comm) { vector community; community.reserve(this->_cnodes[comm]); for (size_t i = 0; i < this->graph->vcount(); i++) if (this->_membership[i] == comm) community.push_back(i); return community; } vector< vector > MutableVertexPartition::get_communities() { vector< vector > communities(this->_n_communities); for (size_t c = 0; c < this->_n_communities; c++) { size_t cn = this->_cnodes[c]; communities[c].reserve(cn); } for (size_t i = 0; i < this->graph->vcount(); i++) communities[this->_membership[i]].push_back(i); return communities; } size_t MutableVertexPartition::n_communities() { return this->_n_communities; } /**************************************************************************** Initialise all the administration based on the membership vector. *****************************************************************************/ void MutableVertexPartition::init_admin() { #ifdef DEBUG cerr << "void MutableVertexPartition::init_admin()" << endl; #endif size_t n = this->graph->vcount(); // First determine number of communities (assuming they are consecutively numbered this->update_n_communities(); // Reset administration this->_total_weight_in_comm.clear(); this->_total_weight_in_comm.resize(this->_n_communities); this->_total_weight_from_comm.clear(); this->_total_weight_from_comm.resize(this->_n_communities); this->_total_weight_to_comm.clear(); this->_total_weight_to_comm.resize(this->_n_communities); this->_csize.clear(); this->_csize.resize(this->_n_communities); this->_cnodes.clear(); this->_cnodes.resize(this->_n_communities); this->_current_node_cache_community_from = n + 1; this->_cached_weight_from_community.resize(this->_n_communities, 0); this->_current_node_cache_community_to = n + 1; this->_cached_weight_to_community.resize(this->_n_communities, 0); this->_current_node_cache_community_all = n + 1; this->_cached_weight_all_community.resize(this->_n_communities, 0); this->_cached_neigh_comms_all.resize(n); if (this->get_graph()->is_directed()) { this->_cached_neigh_comms_from.resize(n); this->_cached_neigh_comms_to.resize(n); } this->_empty_communities.clear(); this->_total_weight_in_all_comms = 0.0; for (size_t v = 0; v < n; v++) { size_t v_comm = this->_membership[v]; // Update the community size this->_csize[v_comm] += this->graph->node_size(v); // Update the community size this->_cnodes[v_comm] += 1; } size_t m = graph->ecount(); for (size_t e = 0; e < m; e++) { size_t v, u; this->graph->edge(e, v, u); size_t v_comm = this->_membership[v]; size_t u_comm = this->_membership[u]; // Get the weight of the edge double w = this->graph->edge_weight(e); // Add weight to the outgoing weight of community of v this->_total_weight_from_comm[v_comm] += w; #ifdef DEBUG cerr << "\t" << "Add (" << v << ", " << u << ") weight " << w << " to from_comm " << v_comm << "." << endl; #endif // Add weight to the incoming weight of community of u this->_total_weight_to_comm[u_comm] += w; #ifdef DEBUG cerr << "\t" << "Add (" << v << ", " << u << ") weight " << w << " to to_comm " << u_comm << "." << endl; #endif if (!this->graph->is_directed()) { #ifdef DEBUG cerr << "\t" << "Add (" << u << ", " << v << ") weight " << w << " to from_comm " << u_comm << "." << endl; #endif this->_total_weight_from_comm[u_comm] += w; #ifdef DEBUG cerr << "\t" << "Add (" << u << ", " << v << ") weight " << w << " to to_comm " << v_comm << "." << endl; #endif this->_total_weight_to_comm[v_comm] += w; } // If it is an edge within a community if (v_comm == u_comm) { this->_total_weight_in_comm[v_comm] += w; this->_total_weight_in_all_comms += w; #ifdef DEBUG cerr << "\t" << "Add (" << v << ", " << u << ") weight " << w << " to in_comm " << v_comm << "." << endl; #endif } } this->_total_possible_edges_in_all_comms = 0; for (size_t c = 0; c < this->_n_communities; c++) { size_t n_c = this->csize(c); size_t possible_edges = this->graph->possible_edges(n_c); #ifdef DEBUG cerr << "\t" << "c=" << c << ", n_c=" << n_c << ", possible_edges=" << possible_edges << endl; #endif this->_total_possible_edges_in_all_comms += possible_edges; // It is possible that some community have a zero size (if the order // is for example not consecutive. We add those communities to the empty // communities vector for consistency. if (this->_cnodes[c] == 0) this->_empty_communities.push_back(c); } #ifdef DEBUG cerr << "exit MutableVertexPartition::init_admin()" << endl << endl; #endif } void MutableVertexPartition::update_n_communities() { this->_n_communities = 0; for (size_t i = 0; i < this->graph->vcount(); i++) if (this->_membership[i] >= this->_n_communities) this->_n_communities = this->_membership[i] + 1; } /**************************************************************************** Renumber the communities so that they are numbered 0,...,q-1 where q is the number of communities. This also removes any empty communities, as they will not be given a new number. *****************************************************************************/ void MutableVertexPartition::renumber_communities() { vector partitions(1); partitions[0] = this; vector new_comm_id = MutableVertexPartition::rank_order_communities(partitions); this->relabel_communities(new_comm_id); } /**************************************************************************** Renumber the communities according to the new labels in new_comm_id. This adjusts the internal bookkeeping as required, avoiding the more costly setup required in init_admin(). In particular, this avoids recomputation of weights in/from/to each community by simply assigning the previously computed values to the new, relabeled communities. For instance, a new_comm_id of <1, 2, 0> will change the labels such that community 0 becomes 1, community 1 becomes 2, and community 2 becomes 0. *****************************************************************************/ void MutableVertexPartition::relabel_communities(vector const& new_comm_id) { if (this->_n_communities != new_comm_id.size()) { throw Exception("Problem swapping community labels. Mismatch between n_communities and new_comm_id vector."); } size_t n = this->graph->vcount(); for (size_t i = 0; i < n; i++) this->_membership[i] = new_comm_id[this->_membership[i]]; this->update_n_communities(); size_t nbcomms = this->n_communities(); vector new_total_weight_in_comm(nbcomms, 0.0); vector new_total_weight_from_comm(nbcomms, 0.0); vector new_total_weight_to_comm(nbcomms, 0.0); vector new_csize(nbcomms, 0); vector new_cnodes(nbcomms, 0); // Relabel community admin for (size_t c = 0; c < new_comm_id.size(); c++) { size_t new_c = new_comm_id[c]; if (this->_cnodes[c] > 0) { new_total_weight_in_comm[new_c] = this->_total_weight_in_comm[c]; new_total_weight_from_comm[new_c] = this->_total_weight_from_comm[c]; new_total_weight_to_comm[new_c] = this->_total_weight_to_comm[c]; new_csize[new_c] = this->_csize[c]; new_cnodes[new_c] = this->_cnodes[c]; } } this->_total_weight_in_comm = new_total_weight_in_comm; this->_total_weight_from_comm = new_total_weight_from_comm; this->_total_weight_to_comm = new_total_weight_to_comm; this->_csize = new_csize; this->_cnodes = new_cnodes; this->_empty_communities.clear(); for (size_t c = 0; c < nbcomms; c++) { if (this->_cnodes[c] == 0) { this->_empty_communities.push_back(c); } } // invalidate cached weight vectors for (size_t c : this->_cached_neigh_comms_from) this->_cached_weight_from_community[c] = 0; this->_cached_neigh_comms_from.clear(); this->_cached_weight_from_community.resize(nbcomms, 0); this->_current_node_cache_community_from = n + 1; for (size_t c : this->_cached_neigh_comms_to) this->_cached_weight_to_community[c] = 0; this->_cached_neigh_comms_to.clear(); this->_cached_weight_to_community.resize(nbcomms, 0); this->_current_node_cache_community_to = n + 1; for (size_t c : this->_cached_neigh_comms_all) this->_cached_weight_all_community[c] = 0; this->_cached_neigh_comms_all.clear(); this->_cached_weight_all_community.resize(nbcomms, 0); this->_current_node_cache_community_all = n + 1; #ifdef DEBUG if (this->_csize.size() < this->_n_communities || this->_cnodes.size() < this->_n_communities || this->_total_weight_in_comm.size() < this->_n_communities || this->_total_weight_to_comm.size() < this->_n_communities || this->_total_weight_from_comm.size() < this->_n_communities || this->_cached_weight_from_community.size() < this->_n_communities || this->_cached_weight_to_community.size() < this->_n_communities || this->_cached_weight_all_community.size() < this->_n_communities) { cerr << "ERROR: MutableVertexPartition bookkeeping is too small after rearrange_community_labels." << endl; } this->init_admin(); for (size_t c = 0; c < this->_n_communities; c++) { if (fabs(new_total_weight_in_comm[c] - this->_total_weight_in_comm[c]) > 1e-6 || fabs(new_total_weight_from_comm[c] - this->_total_weight_from_comm[c]) > 1e-6 || fabs(new_total_weight_to_comm[c] - this->_total_weight_to_comm[c]) > 1e-6 || new_csize[c] != this->_csize[c] || new_cnodes[c] != this->_cnodes[c]) { cerr << "ERROR: MutableVertexPartition bookkeeping is incorrect after rearrange_community_labels." << endl; cerr << "Community c has " << endl << "total_weight_in_comm=" << new_total_weight_in_comm[c] << " (should be " << this->_total_weight_in_comm[c] << ")" << endl << "total_weight_from_comm=" << new_total_weight_from_comm[c] << " (should be " << this->_total_weight_from_comm[c] << ")" << endl << "total_weight_to_comm=" << new_total_weight_to_comm[c] << " (should be " << this->_total_weight_to_comm[c] << ")" << endl << "csize=" << new_csize[c] << " (should be " << this->_csize[c] << ")" << endl << "cnodes=" << new_cnodes[c] << " (should be " << this->_cnodes[c] << ")" << endl; } } #endif } vector MutableVertexPartition::rank_order_communities(vector partitions) { size_t nb_layers = partitions.size(); size_t nb_comms = partitions[0]->n_communities(); #ifdef DEBUG size_t n = partitions[0]->graph->vcount(); for (size_t layer = 0; layer < nb_layers; layer++) { for (size_t v = 0; v < n; v++) { if (partitions[0]->membership(v) != partitions[layer]->membership(v)) cerr << "Membership of all partitions are not equal"; } } #endif // First sort the communities by size // Csizes // first - community // second - csize // third - number of nodes (may be aggregate nodes), to account for communities with zero weight. vector csizes; for (size_t i = 0; i < nb_comms; i++) { size_t csize = 0; for (size_t layer = 0; layer < nb_layers; layer++) csize += partitions[layer]->csize(i); size_t* row = new size_t[3]; row[0] = i; row[1] = csize; row[2] = partitions[0]->cnodes(i); csizes.push_back(row); } sort(csizes.begin(), csizes.end(), orderCSize); // Then use the sort order to assign new communities, // such that the largest community gets the lowest index. vector new_comm_id(nb_comms, 0); for (size_t i = 0; i < nb_comms; i++) { size_t comm = csizes[i][0]; new_comm_id[comm] = i; delete[] csizes[i]; } return new_comm_id; } /**************************************************************************** Renumber the communities using the original fixed membership vector. Notice that this doesn't ensure any property of the community numbers. *****************************************************************************/ void MutableVertexPartition::renumber_communities(vector const& fixed_nodes, vector const& fixed_membership) { #ifdef DEBUG cerr << "void MutableVertexPartition::renumber_communities(" << &fixed_nodes << ", " << &fixed_membership << ")" << endl; #endif // Skip whole thing if there are no fixed nodes for efficiency if (fixed_nodes.size() == 0) return; // The number of communities does not depend on whether some are fixed size_t nb_comms = n_communities(); // Fill the community map with the original communities vector new_comm_id(nb_comms); vector comm_assigned_bool(nb_comms); priority_queue, std::greater > new_comm_assigned; for (size_t v : fixed_nodes) { if (!comm_assigned_bool[_membership[v]]) { size_t fixed_comm_v = fixed_membership[v]; #ifdef DEBUG cerr << "Setting map for fixed community " << fixed_comm_v << endl; #endif new_comm_id[_membership[v]] = fixed_comm_v; comm_assigned_bool[_membership[v]] = true; new_comm_assigned.push(fixed_comm_v); } } // Index of the most recently added community size_t cc = 0; for (size_t c = 0; c != nb_comms; c++) { if(!comm_assigned_bool[c]) { // Look for the first free integer while (!new_comm_assigned.empty() && cc == new_comm_assigned.top()) { new_comm_assigned.pop(); cc++; } // Assign the community #ifdef DEBUG cerr << "Setting map for free community " << cc << endl; #endif new_comm_id[c] = cc++; } } this->relabel_communities(new_comm_id); } void MutableVertexPartition::renumber_communities(vector const& membership) { this->set_membership(membership); } size_t MutableVertexPartition::get_empty_community() { if (this->_empty_communities.empty()) { // If there was no empty community yet, // we will create a new one. add_empty_community(); } return this->_empty_communities.back(); } void MutableVertexPartition::set_membership(vector const& membership) { #ifdef DEBUG cerr << "void MutableVertexPartition::set_membership(" << &membership << ")" << endl; #endif this->_membership = membership; this->clean_mem(); this->init_admin(); #ifdef DEBUG cerr << "exit MutableVertexPartition::set_membership(" << &membership << ")" << endl; #endif } size_t MutableVertexPartition::add_empty_community() { this->_n_communities = this->_n_communities + 1; if (this->_n_communities > this->graph->vcount()) throw Exception("There cannot be more communities than nodes, so there must already be an empty community."); size_t new_comm = this->_n_communities - 1; this->_csize.resize(this->_n_communities); this->_csize[new_comm] = 0; this->_cnodes.resize(this->_n_communities); this->_cnodes[new_comm] = 0; this->_total_weight_in_comm.resize(this->_n_communities); this->_total_weight_in_comm[new_comm] = 0; this->_total_weight_from_comm.resize(this->_n_communities); this->_total_weight_from_comm[new_comm] = 0; this->_total_weight_to_comm.resize(this->_n_communities); this->_total_weight_to_comm[new_comm] = 0; this->_cached_weight_all_community.resize(this->_n_communities); this->_cached_weight_from_community.resize(this->_n_communities); this->_cached_weight_to_community.resize(this->_n_communities); this->_empty_communities.push_back(new_comm); #ifdef DEBUG cerr << "Added empty community " << new_comm << endl; #endif return new_comm; } /**************************************************************************** Move a node to a new community and update the administration. Parameters: v -- Node to move. new_comm -- To which community should it move. *****************************************************************************/ void MutableVertexPartition::move_node(size_t v,size_t new_comm) { #ifdef DEBUG cerr << "void MutableVertexPartition::move_node(" << v << ", " << new_comm << ")" << endl; if (new_comm >= this->n_communities()) cerr << "ERROR: New community (" << new_comm << ") larger than total number of communities (" << this->n_communities() << ")." << endl; #endif // Move node and update internal administration if (new_comm >= this->_n_communities) { if (new_comm < this->graph->vcount()) { while (new_comm >= this->_n_communities) this->add_empty_community(); } else { throw Exception("Cannot add new communities beyond the number of nodes."); } } // Keep track of all possible edges in all communities; size_t node_size = this->graph->node_size(v); size_t old_comm = this->_membership[v]; #ifdef DEBUG cerr << "Node size: " << node_size << ", old comm: " << old_comm << ", new comm: " << new_comm << endl; #endif // Incidentally, this is independent of whether we take into account self-loops or not // (i.e. whether we count as n_c^2 or as n_c(n_c - 1). Be careful to do this before the // adaptation of the community sizes, otherwise the calculations are incorrect. if (new_comm != old_comm) { double delta_possible_edges_in_comms = 2.0*node_size*(ptrdiff_t)(this->_csize[new_comm] - this->_csize[old_comm] + node_size)/(2.0 - this->graph->is_directed()); _total_possible_edges_in_all_comms += delta_possible_edges_in_comms; #ifdef DEBUG cerr << "Change in possible edges in all comms: " << delta_possible_edges_in_comms << endl; #endif } // Remove from old community #ifdef DEBUG cerr << "Removing from old community " << old_comm << ", community size: " << this->_csize[old_comm] << endl; #endif this->_cnodes[old_comm] -= 1; this->_csize[old_comm] -= node_size; #ifdef DEBUG cerr << "Removed from old community." << endl; #endif // We have to use the size of the set of nodes rather than the csize // to account for nodes that have a zero size (i.e. community may not be empty, but // may have zero size). if (this->_cnodes[old_comm] == 0) { #ifdef DEBUG cerr << "Adding community " << old_comm << " to empty communities." << endl; #endif this->_empty_communities.push_back(old_comm); #ifdef DEBUG cerr << "Added community " << old_comm << " to empty communities." << endl; #endif } if (this->_cnodes[new_comm] == 0) { #ifdef DEBUG cerr << "Removing from empty communities (number of empty communities is " << this->_empty_communities.size() << ")." << endl; #endif vector::reverse_iterator it_comm = this->_empty_communities.rbegin(); while (it_comm != this->_empty_communities.rend() && *it_comm != new_comm) { #ifdef DEBUG cerr << "Empty community " << *it_comm << " != new community " << new_comm << endl; #endif it_comm++; } #ifdef DEBUG cerr << "Erasing empty community " << *it_comm << endl; if (it_comm == this->_empty_communities.rend()) cerr << "ERROR: empty community does not exist." << endl; #endif if (it_comm != this->_empty_communities.rend()) this->_empty_communities.erase( (++it_comm).base() ); } #ifdef DEBUG cerr << "Adding to new community " << new_comm << ", community size: " << this->_csize[new_comm] << endl; #endif // Add to new community this->_cnodes[new_comm] += 1; this->_csize[new_comm] += this->graph->node_size(v); // Switch outgoing links #ifdef DEBUG cerr << "Added to new community." << endl; #endif // Use set for incident edges, because self loop appears twice igraph_neimode_t modes[2] = {IGRAPH_OUT, IGRAPH_IN}; for (size_t mode_i = 0; mode_i < 2; mode_i++) { igraph_neimode_t mode = modes[mode_i]; // Loop over all incident edges vector const& neighbours = this->graph->get_neighbours(v, mode); vector const& neighbour_edges = this->graph->get_neighbour_edges(v, mode); size_t degree = neighbours.size(); #ifdef DEBUG if (mode == IGRAPH_OUT) cerr << "\t" << "Looping over outgoing links." << endl; else if (mode == IGRAPH_IN) cerr << "\t" << "Looping over incoming links." << endl; else cerr << "\t" << "Looping over unknown mode." << endl; #endif for (size_t idx = 0; idx < degree; idx++) { size_t u = neighbours[idx]; size_t e = neighbour_edges[idx]; size_t u_comm = this->_membership[u]; // Get the weight of the edge double w = this->graph->edge_weight(e); if (mode == IGRAPH_OUT) { // Remove the weight from the outgoing weights of the old community this->_total_weight_from_comm[old_comm] -= w; // Add the weight to the outgoing weights of the new community this->_total_weight_from_comm[new_comm] += w; #ifdef DEBUG cerr << "\t" << "Moving link (" << v << "-" << u << ") " << "outgoing weight " << w << " from " << old_comm << " to " << new_comm << "." << endl; #endif } else if (mode == IGRAPH_IN) { // Remove the weight from the outgoing weights of the old community this->_total_weight_to_comm[old_comm] -= w; // Add the weight to the outgoing weights of the new community this->_total_weight_to_comm[new_comm] += w; #ifdef DEBUG cerr << "\t" << "Moving link (" << v << "-" << u << ") " << "incoming weight " << w << " from " << old_comm << " to " << new_comm << "." << endl; #endif } else throw Exception("Incorrect mode for updating the admin."); // Get internal weight (if it is an internal edge) double int_weight = w/(this->graph->is_directed() ? 1.0 : 2.0)/( u == v ? 2.0 : 1.0); // If it is an internal edge in the old community if (old_comm == u_comm) { // Remove the internal weight this->_total_weight_in_comm[old_comm] -= int_weight; this->_total_weight_in_all_comms -= int_weight; #ifdef DEBUG cerr << "\t" << "From link (" << v << "-" << u << ") " << "remove internal weight " << int_weight << " from " << old_comm << "." << endl; #endif } // If it is an internal edge in the new community // i.e. if u is in the new community, or if it is a self loop if ((new_comm == u_comm) || (u == v)) { // Add the internal weight this->_total_weight_in_comm[new_comm] += int_weight; this->_total_weight_in_all_comms += int_weight; #ifdef DEBUG cerr << "\t" << "From link (" << v << "-" << u << ") " << "add internal weight " << int_weight << " to " << new_comm << "." << endl; #endif } } } #ifdef DEBUG // Check this->_total_weight_in_all_comms double check_total_weight_in_all_comms = 0.0; for (size_t c = 0; c < this->n_communities(); c++) check_total_weight_in_all_comms += this->total_weight_in_comm(c); cerr << "Internal _total_weight_in_all_comms=" << this->_total_weight_in_all_comms << ", calculated check_total_weight_in_all_comms=" << check_total_weight_in_all_comms << endl; #endif // Update the membership vector this->_membership[v] = new_comm; #ifdef DEBUG cerr << "exit MutableVertexPartition::move_node(" << v << ", " << new_comm << ")" << endl << endl; #endif } /**************************************************************************** Read new communities from coarser partition assuming that the community represents a node in the coarser partition (with the same index as the community number). ****************************************************************************/ void MutableVertexPartition::from_coarse_partition(vector const& coarse_partition_membership) { this->from_coarse_partition(coarse_partition_membership, this->_membership); } void MutableVertexPartition::from_coarse_partition(MutableVertexPartition* coarse_partition) { this->from_coarse_partition(coarse_partition, this->_membership); } void MutableVertexPartition::from_coarse_partition(MutableVertexPartition* coarse_partition, vector const& coarse_node) { this->from_coarse_partition(coarse_partition->membership(), coarse_node); } /**************************************************************************** Set the current community of all nodes to the community specified in the partition assuming that the coarser partition is created using the membership as specified by coarser_membership. In other words node i becomes node coarse_node[i] in the coarser partition and thus has community coarse_partition_membership[coarse_node[i]]. ****************************************************************************/ void MutableVertexPartition::from_coarse_partition(vector const& coarse_partition_membership, vector const& coarse_node) { // Read the coarser partition for (size_t v = 0; v < this->graph->vcount(); v++) { // In the coarser partition, the node should have the community id // as represented by the coarser_membership vector size_t v_level2 = coarse_node[v]; // In the coarser partition, this node is represented by v_level2 size_t v_comm_level2 = coarse_partition_membership[v_level2]; // Set local membership to community found for node at second level this->_membership[v] = v_comm_level2; } this->clean_mem(); this->init_admin(); } /**************************************************************************** Read new partition from another partition. ****************************************************************************/ void MutableVertexPartition::from_partition(MutableVertexPartition* partition) { // Assign the membership of every node in the supplied partition // to the one in this partition for (size_t v = 0; v < this->graph->vcount(); v++) this->_membership[v] = partition->membership(v); this->clean_mem(); this->init_admin(); } void MutableVertexPartition::cache_neigh_communities(size_t v, igraph_neimode_t mode) { // TODO: We can probably calculate at once the IN, OUT and ALL // rather than this being called multiple times. // Weight between vertex and community #ifdef DEBUG cerr << "double MutableVertexPartition::cache_neigh_communities(" << v << ", " << mode << ")." << endl; #endif vector* _cached_weight_tofrom_community = NULL; vector* _cached_neighs_comms = NULL; switch (mode) { case IGRAPH_IN: _cached_weight_tofrom_community = &(this->_cached_weight_from_community); _cached_neighs_comms = &(this->_cached_neigh_comms_from); break; case IGRAPH_OUT: _cached_weight_tofrom_community = &(this->_cached_weight_to_community); _cached_neighs_comms = &(this->_cached_neigh_comms_to); break; case IGRAPH_ALL: _cached_weight_tofrom_community = &(this->_cached_weight_all_community); _cached_neighs_comms = &(this->_cached_neigh_comms_all); break; } // Reset cached communities for (size_t c : *_cached_neighs_comms) (*_cached_weight_tofrom_community)[c] = 0; // Loop over all incident edges vector const& neighbours = this->graph->get_neighbours(v, mode); vector const& neighbour_edges = this->graph->get_neighbour_edges(v, mode); size_t degree = neighbours.size(); // Reset cached neighbours _cached_neighs_comms->clear(); for (size_t idx = 0; idx < degree; idx++) { size_t u = neighbours[idx]; size_t e = neighbour_edges[idx]; // If it is an edge to the requested community #ifdef DEBUG size_t v_comm = this->_membership[v]; #endif size_t comm = this->_membership[u]; // Get the weight of the edge double w = this->graph->edge_weight(e); // Self loops appear twice here if the graph is undirected, so divide by 2.0 in that case. if (u == v && !this->graph->is_directed()) w /= 2.0; #ifdef DEBUG cerr << "\t" << "Edge (" << v << "-" << u << "), Comm (" << v_comm << "-" << comm << ") weight: " << w << "." << endl; #endif (*_cached_weight_tofrom_community)[comm] += w; // REMARK: Notice in the rare case of negative weights, being exactly equal // for a certain community, that this community may then potentially be added multiple // times to the _cached_neighs. However, I don' believe this causes any further issue, // so that's why I leave this here as is. if ((*_cached_weight_tofrom_community)[comm] != 0) _cached_neighs_comms->push_back(comm); } #ifdef DEBUG cerr << "exit Graph::cache_neigh_communities(" << v << ", " << mode << ")." << endl; #endif } vector const& MutableVertexPartition::get_neigh_comms(size_t v, igraph_neimode_t mode) { if (!this->get_graph()->is_directed()) mode = IGRAPH_ALL; // igraph ignores mode for undirected graphs switch (mode) { case IGRAPH_IN: if (this->_current_node_cache_community_from != v) { cache_neigh_communities(v, mode); this->_current_node_cache_community_from = v; } return this->_cached_neigh_comms_from; case IGRAPH_OUT: if (this->_current_node_cache_community_to != v) { cache_neigh_communities(v, mode); this->_current_node_cache_community_to = v; } return this->_cached_neigh_comms_to; case IGRAPH_ALL: if (this->_current_node_cache_community_all != v) { cache_neigh_communities(v, mode); this->_current_node_cache_community_all = v; } return this->_cached_neigh_comms_all; } throw Exception("Problem obtaining neighbour communities, invalid mode."); } vector MutableVertexPartition::get_neigh_comms(size_t v, igraph_neimode_t mode, vector const& constrained_membership) { vector neigh_comms; for (size_t u : this->graph->get_neighbours(v, mode)) { if (constrained_membership[v] == constrained_membership[u]) { size_t comm = this->membership(u); neigh_comms.push_back(comm); } } return neigh_comms; } leidenbase/src/leidenalg/CPMVertexPartition.cpp0000644000176200001440000001203414444671323021303 0ustar liggesusers#include "CPMVertexPartition.h" CPMVertexPartition::CPMVertexPartition(Graph* graph, vector membership, double resolution_parameter) : LinearResolutionParameterVertexPartition(graph, membership, resolution_parameter) { } CPMVertexPartition::CPMVertexPartition(Graph* graph, vector membership) : LinearResolutionParameterVertexPartition(graph, membership) { } CPMVertexPartition::CPMVertexPartition(Graph* graph, double resolution_parameter) : LinearResolutionParameterVertexPartition(graph, resolution_parameter) { } CPMVertexPartition::CPMVertexPartition(Graph* graph) : LinearResolutionParameterVertexPartition(graph) { } CPMVertexPartition::~CPMVertexPartition() { } CPMVertexPartition* CPMVertexPartition::create(Graph* graph) { return new CPMVertexPartition(graph, this->resolution_parameter); } CPMVertexPartition* CPMVertexPartition::create(Graph* graph, vector const& membership) { return new CPMVertexPartition(graph, membership, this->resolution_parameter); } /******************************************************************************** RBER implementation of a vertex partition (which includes a resolution parameter). ********************************************************************************/ double CPMVertexPartition::diff_move(size_t v, size_t new_comm) { #ifdef DEBUG cerr << "double CPMVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; cerr << "Using resolution parameter: " << this->resolution_parameter << "." << endl; #endif size_t old_comm = this->membership(v); double diff = 0.0; if (new_comm != old_comm) { double w_to_old = this->weight_to_comm(v, old_comm); #ifdef DEBUG cerr << "\t" << "w_to_old: " << w_to_old << endl; #endif double w_to_new = this->weight_to_comm(v, new_comm); #ifdef DEBUG cerr << "\t" << "w_to_new: " << w_to_new << endl; #endif double w_from_old = this->weight_from_comm(v, old_comm); #ifdef DEBUG cerr << "\t" << "w_from_old: " << w_from_old << endl; #endif double w_from_new = this->weight_from_comm(v, new_comm); #ifdef DEBUG cerr << "\t" << "w_from_new: " << w_from_new << endl; #endif size_t nsize = this->graph->node_size(v); #ifdef DEBUG cerr << "\t" << "nsize: " << nsize << endl; #endif size_t csize_old = this->csize(old_comm); #ifdef DEBUG cerr << "\t" << "csize_old: " << csize_old << endl; #endif size_t csize_new = this->csize(new_comm); #ifdef DEBUG cerr << "\t" << "csize_new: " << csize_new << endl; #endif double self_weight = this->graph->node_self_weight(v); #ifdef DEBUG cerr << "\t" << "self_weight: " << self_weight << endl; cerr << "\t" << "density: " << this->graph->density() << endl; #endif double possible_edge_difference_old = 0.0; if (this->graph->correct_self_loops()) possible_edge_difference_old = nsize*(2.0*csize_old - nsize); else possible_edge_difference_old = nsize*(2.0*csize_old - nsize - 1.0); #ifdef DEBUG cerr << "\t" << "possible_edge_difference_old: " << possible_edge_difference_old << endl; #endif double diff_old = w_to_old + w_from_old - self_weight - this->resolution_parameter*possible_edge_difference_old; #ifdef DEBUG cerr << "\t" << "diff_old: " << diff_old << endl; #endif double possible_edge_difference_new = 0.0; if (this->graph->correct_self_loops()) possible_edge_difference_new = nsize*(2.0*csize_new + nsize); else possible_edge_difference_new = nsize*(2.0*csize_new + nsize - 1.0); #ifdef DEBUG cerr << "\t" << "possible_edge_difference_new: " << possible_edge_difference_new << endl; #endif double diff_new = w_to_new + w_from_new + self_weight - this->resolution_parameter*possible_edge_difference_new; #ifdef DEBUG cerr << "\t" << "diff_new: " << diff_new << endl; #endif diff = diff_new - diff_old; #ifdef DEBUG cerr << "\t" << "diff: " << diff << endl;; #endif } #ifdef DEBUG cerr << "exit CPMVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; cerr << "return " << diff << endl << endl; #endif return diff; } double CPMVertexPartition::quality(double resolution_parameter) { #ifdef DEBUG cerr << "double CPMVertexPartition::quality()" << endl; #endif double mod = 0.0; for (size_t c = 0; c < this->n_communities(); c++) { size_t csize = this->csize(c); double w = this->total_weight_in_comm(c); size_t comm_possible_edges = this->graph->possible_edges(csize); #ifdef DEBUG cerr << "\t" << "Comm: " << c << ", w_c=" << w << ", n_c=" << csize << ", comm_possible_edges=" << comm_possible_edges << ", p=" << this->graph->density() << "." << endl; #endif mod += w - resolution_parameter*comm_possible_edges; } #ifdef DEBUG cerr << "exit double CPMVertexPartition::quality()" << endl; cerr << "return " << mod << endl << endl; #endif return (2.0 - this->graph->is_directed())*mod; } leidenbase/src/leidenalg/ModularityVertexPartition.cpp0000644000176200001440000001242114444671323023015 0ustar liggesusers#include "ModularityVertexPartition.h" #ifdef DEBUG #include using std::cerr; using std::endl; #endif ModularityVertexPartition::ModularityVertexPartition(Graph* graph, vector const& membership) : MutableVertexPartition(graph, membership) { } ModularityVertexPartition::ModularityVertexPartition(Graph* graph) : MutableVertexPartition(graph) { } ModularityVertexPartition::~ModularityVertexPartition() { } ModularityVertexPartition* ModularityVertexPartition::create(Graph* graph) { return new ModularityVertexPartition(graph); } ModularityVertexPartition* ModularityVertexPartition::create(Graph* graph, vector const& membership) { return new ModularityVertexPartition(graph, membership); } /***************************************************************************** Returns the difference in modularity if we move a node to a new community *****************************************************************************/ double ModularityVertexPartition::diff_move(size_t v, size_t new_comm) { #ifdef DEBUG cerr << "double ModularityVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; #endif size_t old_comm = this->_membership[v]; double diff = 0.0; double total_weight = this->graph->total_weight()*(2.0 - this->graph->is_directed()); if (total_weight == 0.0) return 0.0; if (new_comm != old_comm) { #ifdef DEBUG cerr << "\t" << "old_comm: " << old_comm << endl; #endif double w_to_old = this->weight_to_comm(v, old_comm); #ifdef DEBUG cerr << "\t" << "w_to_old: " << w_to_old << endl; #endif double w_from_old = this->weight_from_comm(v, old_comm); #ifdef DEBUG cerr << "\t" << "w_from_old: " << w_from_old << endl; #endif double w_to_new = this->weight_to_comm(v, new_comm); #ifdef DEBUG cerr << "\t" << "w_to_new: " << w_to_new << endl; #endif double w_from_new = this->weight_from_comm(v, new_comm); #ifdef DEBUG cerr << "\t" << "w_from_new: " << w_from_new << endl; #endif double k_out = this->graph->strength(v, IGRAPH_OUT); #ifdef DEBUG cerr << "\t" << "k_out: " << k_out << endl; #endif double k_in = this->graph->strength(v, IGRAPH_IN); #ifdef DEBUG cerr << "\t" << "k_in: " << k_in << endl; #endif double self_weight = this->graph->node_self_weight(v); #ifdef DEBUG cerr << "\t" << "self_weight: " << self_weight << endl; #endif double K_out_old = this->total_weight_from_comm(old_comm); #ifdef DEBUG cerr << "\t" << "K_out_old: " << K_out_old << endl; #endif double K_in_old = this->total_weight_to_comm(old_comm); #ifdef DEBUG cerr << "\t" << "K_in_old: " << K_in_old << endl; #endif double K_out_new = this->total_weight_from_comm(new_comm) + k_out; #ifdef DEBUG cerr << "\t" << "K_out_new: " << K_out_new << endl; #endif double K_in_new = this->total_weight_to_comm(new_comm) + k_in; #ifdef DEBUG cerr << "\t" << "K_in_new: " << K_in_new << endl; cerr << "\t" << "total_weight: " << total_weight << endl; #endif double diff_old = (w_to_old - k_out*K_in_old/total_weight) + \ (w_from_old - k_in*K_out_old/total_weight); #ifdef DEBUG cerr << "\t" << "diff_old: " << diff_old << endl; #endif double diff_new = (w_to_new + self_weight - k_out*K_in_new/total_weight) + \ (w_from_new + self_weight - k_in*K_out_new/total_weight); #ifdef DEBUG cerr << "\t" << "diff_new: " << diff_new << endl; #endif diff = diff_new - diff_old; #ifdef DEBUG cerr << "\t" << "diff: " << diff << endl; #endif } #ifdef DEBUG cerr << "exit double ModularityVertexPartition::diff_move((" << v << ", " << new_comm << ")" << endl; cerr << "return " << diff << endl << endl; #endif double m; if (this->graph->is_directed()) m = this->graph->total_weight(); else m = 2*this->graph->total_weight(); return diff/m; } /***************************************************************************** Give the modularity of the partition. We here use the unscaled version of modularity, in other words, we don"t normalise by the number of edges. ******************************************************************************/ double ModularityVertexPartition::quality() { #ifdef DEBUG cerr << "double ModularityVertexPartition::quality()" << endl; #endif double mod = 0.0; double m; if (this->graph->is_directed()) m = this->graph->total_weight(); else m = 2*this->graph->total_weight(); if (m == 0) return 0.0; for (size_t c = 0; c < this->n_communities(); c++) { double w = this->total_weight_in_comm(c); double w_out = this->total_weight_from_comm(c); double w_in = this->total_weight_to_comm(c); #ifdef DEBUG size_t csize = this->csize(c); cerr << "\t" << "Comm: " << c << ", size=" << csize << ", w=" << w << ", w_out=" << w_out << ", w_in=" << w_in << "." << endl; #endif mod += w - w_out*w_in/((this->graph->is_directed() ? 1.0 : 4.0)*this->graph->total_weight()); } double q = (2.0 - this->graph->is_directed())*mod; #ifdef DEBUG cerr << "exit double ModularityVertexPartition::quality()" << endl; cerr << "return " << q/m << endl << endl; #endif return q/m; } leidenbase/src/leidenalg/SurpriseVertexPartition.cpp0000644000176200001440000001057614444671323022511 0ustar liggesusers#include "SurpriseVertexPartition.h" SurpriseVertexPartition::SurpriseVertexPartition(Graph* graph, vector const& membership) : MutableVertexPartition(graph, membership) { } SurpriseVertexPartition::SurpriseVertexPartition(Graph* graph) : MutableVertexPartition(graph) { } SurpriseVertexPartition* SurpriseVertexPartition::create(Graph* graph) { return new SurpriseVertexPartition(graph); } SurpriseVertexPartition* SurpriseVertexPartition::create(Graph* graph, vector const& membership) { return new SurpriseVertexPartition(graph, membership); } SurpriseVertexPartition::~SurpriseVertexPartition() { } double SurpriseVertexPartition::diff_move(size_t v, size_t new_comm) { #ifdef DEBUG cerr << "virtual double SurpriseVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; #endif size_t old_comm = this->membership(v); size_t nsize = this->graph->node_size(v); #ifdef DEBUG cerr << "\t" << "nsize: " << nsize << endl; #endif double diff = 0.0; double m = this->graph->total_weight(); if (m == 0) return 0.0; if (new_comm != old_comm) { double normalise = (2.0 - this->graph->is_directed()); size_t n = this->graph->total_size(); size_t n2 = this->graph->possible_edges(n); #ifdef DEBUG cerr << "\t" << "Community: " << old_comm << " => " << new_comm << "." << endl; cerr << "\t" << "m: " << m << ", n2: " << n2 << "." << endl; #endif // Before move double mc = this->total_weight_in_all_comms(); size_t nc2 = this->total_possible_edges_in_all_comms(); #ifdef DEBUG cerr << "\t" << "mc: " << mc << ", nc2: " << nc2 << "." << endl; #endif // To old comm size_t n_old = this->csize(old_comm); double sw = this->graph->node_self_weight(v); double wtc = this->weight_to_comm(v, old_comm) - sw; double wfc = this->weight_from_comm(v, old_comm) - sw; #ifdef DEBUG cerr << "\t" << "wtc: " << wtc << ", wfc: " << wfc << ", sw: " << sw << "." << endl; #endif double m_old = wtc/normalise + wfc/normalise + sw; #ifdef DEBUG cerr << "\t" << "m_old: " << m_old << ", n_old: " << n_old << "." << endl; #endif // To new comm size_t n_new = this->csize(new_comm); wtc = this->weight_to_comm(v, new_comm); wfc = this->weight_from_comm(v, new_comm); sw = this->graph->node_self_weight(v); #ifdef DEBUG cerr << "\t" << "wtc: " << wtc << ", wfc: " << wfc << ", sw: " << sw << "." << endl; #endif double m_new = wtc/normalise + wfc/normalise + sw; #ifdef DEBUG cerr << "\t" << "m_new: " << m_new << ", n_new: " << n_new << "." << endl; #endif double q = mc/m; double s = (double)nc2/(double)n2; double q_new = (mc - m_old + m_new)/m; #ifdef DEBUG cerr << "\t" << "mc - m_old + m_new=" << (mc - m_old + m_new) << endl; #endif double delta_nc2 = 2.0*nsize*(ptrdiff_t)(n_new - n_old + nsize)/normalise; double s_new = (double)(nc2 + delta_nc2)/(double)n2; #ifdef DEBUG cerr << "\t" << "delta_nc2=" << delta_nc2 << endl; #endif #ifdef DEBUG cerr << "\t" << "q:\t" << q << ", s:\t" << s << "." << endl; cerr << "\t" << "q_new:\t" << q_new << ", s_new:\t" << s_new << "." << endl; #endif diff = m*(KLL(q_new, s_new) - KLL(q, s)); #ifdef DEBUG cerr << "\t" << "diff: " << diff << "." << endl; #endif } #ifdef DEBUG cerr << "exit double SurpriseVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; cerr << "return " << diff << endl << endl; #endif return diff; } double SurpriseVertexPartition::quality() { #ifdef DEBUG cerr << "double SurpriseVertexPartition::quality()" << endl; #endif double mc = this->total_weight_in_all_comms(); size_t nc2 = this->total_possible_edges_in_all_comms(); double m = this->graph->total_weight(); size_t n = this->graph->total_size(); if (m == 0) return 0.0; size_t n2 = this->graph->possible_edges(n); #ifdef DEBUG cerr << "\t" << "mc=" << mc << ", m=" << m << ", nc2=" << nc2 << ", n2=" << n2 << "." << endl; #endif double q = mc/m; double s = (double)nc2/(double)n2; #ifdef DEBUG cerr << "\t" << "q:\t" << q << ", s:\t" << s << "." << endl; #endif double S = m*KLL(q,s); #ifdef DEBUG cerr << "exit SurpriseVertexPartition::quality()" << endl; cerr << "return " << S << endl << endl; #endif return S; } leidenbase/src/leidenalg/MutableVertexPartition.h0000644000176200001440000001603614444673466021742 0ustar liggesusers#ifndef MUTABLEVERTEXPARTITION_H #define MUTABLEVERTEXPARTITION_H #include #include "GraphHelper.h" #include #include #include #include using std::string; using std::map; using std::make_pair; using std::pair; using std::sort; using std::reverse; using std::priority_queue; /**************************************************************************** Contains a partition of graph. This class contains the basic implementation for optimising a partition. Specifically, it implements all the administration necessary to keep track of the partition from various points of view. Internally, it keeps track of the number of internal edges (or total weight), the size of the communities, the total incoming degree (or weight) for a community, etc... When deriving from this class, one can easily use this administration to provide their own implementation. In order to keep the administration up-to-date, all changes in partition should be done through move_node. This function moves a node from one community to another, and updates all the administration. It is possible to manually update the membership vector, and then call __init_admin() which completely refreshes all the administration. This is only possible by updating the membership vector, not by changing some of the other variables. The basic idea is that diff_move computes the difference in the quality function if we call move_node for the same move. Using this framework, the Leiden method in the optimisation class can call these general functions in order to optimise the quality function. *****************************************************************************/ class MutableVertexPartition { public: MutableVertexPartition(Graph* graph, vector const& membership); MutableVertexPartition(Graph* graph); virtual MutableVertexPartition* create(Graph* graph); virtual MutableVertexPartition* create(Graph* graph, vector const& membership); virtual ~MutableVertexPartition(); inline size_t membership(size_t v) { return this->_membership[v]; }; inline vector const& membership() const { return this->_membership; }; size_t csize(size_t comm); size_t cnodes(size_t comm); vector get_community(size_t comm); vector< vector > get_communities(); size_t n_communities(); void move_node(size_t v,size_t new_comm); virtual double diff_move(size_t v, size_t new_comm) { throw Exception("Function not implemented. This should be implented in a derived class, since the base class does not implement a specific method."); }; virtual double quality() { throw Exception("Function not implemented. This should be implented in a derived class, since the base class does not implement a specific method."); }; inline Graph* get_graph() { return this->graph; }; void renumber_communities(); void renumber_communities(vector const& fixed_nodes, vector const& fixed_membership); void renumber_communities(vector const& new_membership); void set_membership(vector const& new_membership); void relabel_communities(vector const& new_comm_id); vector static rank_order_communities(vector partitions); size_t get_empty_community(); size_t add_empty_community(); void from_coarse_partition(vector const& coarse_partition_membership); void from_coarse_partition(MutableVertexPartition* partition); void from_coarse_partition(MutableVertexPartition* partition, vector const& coarser_membership); void from_coarse_partition(vector const& coarse_partition_membership, vector const& coarse_node); void from_partition(MutableVertexPartition* partition); inline double total_weight_in_comm(size_t comm) { return comm < _n_communities ? this->_total_weight_in_comm[comm] : 0.0; }; inline double total_weight_from_comm(size_t comm) { return comm < _n_communities ? this->_total_weight_from_comm[comm] : 0.0; }; inline double total_weight_to_comm(size_t comm) { return comm < _n_communities ? this->_total_weight_to_comm[comm] : 0.0; }; inline double total_weight_in_all_comms() { return this->_total_weight_in_all_comms; }; inline size_t total_possible_edges_in_all_comms() { return this->_total_possible_edges_in_all_comms; }; inline double weight_to_comm(size_t v, size_t comm) { if (this->_current_node_cache_community_to != v) { this->cache_neigh_communities(v, IGRAPH_OUT); this->_current_node_cache_community_to = v; } if (comm < this->_cached_weight_to_community.size()) return this->_cached_weight_to_community[comm]; else return 0.0; } inline double weight_from_comm(size_t v, size_t comm) { if (!this->graph->is_directed()) return weight_to_comm(v, comm); if (this->_current_node_cache_community_from != v) { this->cache_neigh_communities(v, IGRAPH_IN); this->_current_node_cache_community_from = v; } if (comm < this->_cached_weight_from_community.size()) return this->_cached_weight_from_community[comm]; else return 0.0; } vector const& get_neigh_comms(size_t v, igraph_neimode_t); vector get_neigh_comms(size_t v, igraph_neimode_t mode, vector const& constrained_membership); // By delegating the responsibility for deleting the graph to the partition, // we no longer have to worry about deleting this graph. int destructor_delete_graph; protected: void init_admin(); vector _membership; // Membership vector, i.e. \sigma_i = c means that node i is in community c Graph* graph; // Community size vector< size_t > _csize; // Number of nodes in community vector< size_t > _cnodes; double weight_vertex_tofrom_comm(size_t v, size_t comm, igraph_neimode_t mode); void set_default_attrs(); private: // Keep track of the internal weight of each community vector _total_weight_in_comm; // Keep track of the total weight to a community vector _total_weight_to_comm; // Keep track of the total weight from a community vector _total_weight_from_comm; // Keep track of the total internal weight double _total_weight_in_all_comms; size_t _total_possible_edges_in_all_comms; size_t _n_communities; vector _empty_communities; void cache_neigh_communities(size_t v, igraph_neimode_t mode); size_t _current_node_cache_community_from; vector _cached_weight_from_community; vector _cached_neigh_comms_from; size_t _current_node_cache_community_to; vector _cached_weight_to_community; vector _cached_neigh_comms_to; size_t _current_node_cache_community_all; vector _cached_weight_all_community; vector _cached_neigh_comms_all; void clean_mem(); void init_graph_admin(); void update_n_communities(); }; #endif // MUTABLEVERTEXPARTITION_H leidenbase/src/leidenalg/LinearResolutionParameterVertexPartition.cpp0000644000176200001440000000171314444671323026025 0ustar liggesusers#include "LinearResolutionParameterVertexPartition.h" LinearResolutionParameterVertexPartition::LinearResolutionParameterVertexPartition(Graph* graph, vector membership, double resolution_parameter) : ResolutionParameterVertexPartition(graph, membership, resolution_parameter) { } LinearResolutionParameterVertexPartition::LinearResolutionParameterVertexPartition(Graph* graph, vector membership) : ResolutionParameterVertexPartition(graph, membership) { } LinearResolutionParameterVertexPartition::LinearResolutionParameterVertexPartition(Graph* graph, double resolution_parameter) : ResolutionParameterVertexPartition(graph, resolution_parameter) { } LinearResolutionParameterVertexPartition::LinearResolutionParameterVertexPartition(Graph* graph) : ResolutionParameterVertexPartition(graph) { } LinearResolutionParameterVertexPartition::~LinearResolutionParameterVertexPartition() { } leidenbase/src/leidenalg/CPMVertexPartition.h0000644000176200001440000000151314445377543020760 0ustar liggesusers#ifndef CPMVERTEXPARTITION_H #define CPMVERTEXPARTITION_H #include "LinearResolutionParameterVertexPartition.h" class CPMVertexPartition : public LinearResolutionParameterVertexPartition { public: CPMVertexPartition(Graph* graph, vector membership, double resolution_parameter); CPMVertexPartition(Graph* graph, vector membership); CPMVertexPartition(Graph* graph, double resolution_parameter); CPMVertexPartition(Graph* graph); virtual ~CPMVertexPartition(); virtual CPMVertexPartition* create(Graph* graph); virtual CPMVertexPartition* create(Graph* graph, vector const& membership); virtual double diff_move(size_t v, size_t new_comm); virtual double quality(double resolution_parameter); protected: private: }; #endif // CPMVERTEXPARTITION_H leidenbase/src/leidenalg/SignificanceVertexPartition.cpp0000644000176200001440000001325014444671323023247 0ustar liggesusers#include "SignificanceVertexPartition.h" #ifdef DEBUG #include using std::cerr; using std::endl; #endif SignificanceVertexPartition::SignificanceVertexPartition(Graph* graph, vector const& membership) : MutableVertexPartition(graph, membership) { } SignificanceVertexPartition::SignificanceVertexPartition(Graph* graph) : MutableVertexPartition(graph) { } SignificanceVertexPartition* SignificanceVertexPartition::create(Graph* graph) { return new SignificanceVertexPartition(graph); } SignificanceVertexPartition* SignificanceVertexPartition::create(Graph* graph, vector const& membership) { return new SignificanceVertexPartition(graph, membership); } SignificanceVertexPartition::~SignificanceVertexPartition() { } double SignificanceVertexPartition::diff_move(size_t v, size_t new_comm) { #ifdef DEBUG cerr << "virtual double SignificanceVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; #endif size_t old_comm = this->membership(v); size_t nsize = this->graph->node_size(v); double diff = 0.0; if (new_comm != old_comm) { double normalise = (2.0 - this->graph->is_directed()); double p = this->graph->density(); #ifdef DEBUG size_t n = this->graph->total_size(); cerr << "\t" << "Community: " << old_comm << " => " << new_comm << "." << endl; cerr << "\t" << "n: " << n << ", m: " << this->graph->total_weight() << ", p: " << p << "." << endl; #endif //Old comm size_t n_old = this->csize(old_comm); size_t N_old = this->graph->possible_edges(n_old); double m_old = this->total_weight_in_comm(old_comm); double q_old = 0.0; if (N_old > 0) q_old = m_old/N_old; #ifdef DEBUG cerr << "\t" << "n_old: " << n_old << ", N_old: " << N_old << ", m_old: " << m_old << ", q_old: " << q_old << ", KL: " << KL(q_old, p) << "." << endl; #endif // Old comm after move size_t n_oldx = n_old - nsize; // It should not be possible that this becomes negative, so no need for ptrdiff_t here. size_t N_oldx = this->graph->possible_edges(n_oldx); double sw = this->graph->node_self_weight(v); // Be careful to exclude the self weight here, because this is include in the weight_to_comm function. double wtc = this->weight_to_comm(v, old_comm) - sw; double wfc = this->weight_from_comm(v, old_comm) - sw; #ifdef DEBUG cerr << "\t" << "wtc: " << wtc << ", wfc: " << wfc << ", sw: " << sw << "." << endl; #endif double m_oldx = m_old - wtc/normalise - wfc/normalise - sw; double q_oldx = 0.0; if (N_oldx > 0) q_oldx = m_oldx/N_oldx; #ifdef DEBUG cerr << "\t" << "n_oldx: " << n_oldx << ", N_oldx: " << N_oldx << ", m_oldx: " << m_oldx << ", q_oldx: " << q_oldx << ", KL: " << KL(q_oldx, p) << "." << endl; #endif // New comm size_t n_new = this->csize(new_comm); size_t N_new = this->graph->possible_edges(n_new); double m_new = this->total_weight_in_comm(new_comm); double q_new = 0.0; if (N_new > 0) q_new = m_new/N_new; #ifdef DEBUG cerr << "\t" << "n_new: " << n_new << ", N_new: " << N_new << ", m_new: " << m_new << ", q_new: " << q_new << ", KL: " << KL(q_new, p) << "." << endl; #endif // New comm after move size_t n_newx = n_new + nsize; size_t N_newx = this->graph->possible_edges(n_newx); wtc = this->weight_to_comm(v, new_comm); wfc = this->weight_from_comm(v, new_comm); sw = this->graph->node_self_weight(v); #ifdef DEBUG cerr << "\t" << "wtc: " << wtc << ", wfc: " << wfc << ", sw: " << sw << "." << endl; #endif double m_newx = m_new + wtc/normalise + wfc/normalise + sw; double q_newx = 0.0; if (N_newx > 0) q_newx = m_newx/N_newx; #ifdef DEBUG cerr << "\t" << "n_newx: " << n_newx << ", N_newx: " << N_newx << ", m_newx: " << m_newx << ", q_newx: " << q_newx << ", KL: " << KL(q_newx, p) << "." << endl; #endif // Calculate actual diff if (N_oldx != N_new || q_oldx != q_new) diff += (double)N_oldx*KLL(q_oldx, p) - (double)N_new*KLL(q_new, p); if (N_newx != N_old || q_newx != q_old) diff += (double)N_newx*KLL(q_newx, p) - (double)N_old*KLL(q_old, p); #ifdef DEBUG cerr << "\t" << "diff: " << diff << "." << endl; #endif } #ifdef DEBUG cerr << "exit double SignificanceVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; cerr << "return " << diff << endl << endl; #endif return diff; } /******************************************************************************** Calculate the significance of the partition. *********************************************************************************/ double SignificanceVertexPartition::quality() { #ifdef DEBUG cerr << "double SignificanceVertexPartition::quality()"; size_t n = this->graph->total_size(); #endif double S = 0.0; double p = this->graph->density(); #ifdef DEBUG cerr << "\t" << "n=" << n << ", m=" << this->graph->total_weight() << ", p=" << p << "." << endl; #endif for (size_t c = 0; c < this->n_communities(); c++) { size_t n_c = this->csize(c); double m_c = this->total_weight_in_comm(c); double p_c = 0.0; size_t N_c = this->graph->possible_edges(n_c); if (N_c > 0) p_c = m_c/N_c; #ifdef DEBUG cerr << "\t" << "c=" << c << ", n_c=" << n_c << ", m_c=" << m_c << ", N_c=" << N_c << ", p_c=" << p_c << ", p=" << p << ", KLL=" << KL(p_c, p) << "." << endl; #endif S += N_c*KLL(p_c, p); } #ifdef DEBUG cerr << "exit SignificanceVertexPartition::quality()" << endl; cerr << "return " << S << endl << endl; #endif return S; } leidenbase/src/leidenalg/RBERVertexPartition.cpp0000644000176200001440000001213014444671323021413 0ustar liggesusers#include "RBERVertexPartition.h" RBERVertexPartition::RBERVertexPartition(Graph* graph, vector const& membership, double resolution_parameter) : LinearResolutionParameterVertexPartition(graph, membership, resolution_parameter) { } RBERVertexPartition::RBERVertexPartition(Graph* graph, vector const& membership) : LinearResolutionParameterVertexPartition(graph, membership) { } RBERVertexPartition::RBERVertexPartition(Graph* graph, double resolution_parameter) : LinearResolutionParameterVertexPartition(graph, resolution_parameter) { } RBERVertexPartition::RBERVertexPartition(Graph* graph) : LinearResolutionParameterVertexPartition(graph) { } RBERVertexPartition* RBERVertexPartition::create(Graph* graph) { return new RBERVertexPartition(graph, this->resolution_parameter); } RBERVertexPartition* RBERVertexPartition::create(Graph* graph, vector const& membership) { return new RBERVertexPartition(graph, membership, this->resolution_parameter); } RBERVertexPartition::~RBERVertexPartition() { } /******************************************************************************** RBER implementation of a vertex partition (which includes a resolution parameter). ********************************************************************************/ double RBERVertexPartition::diff_move(size_t v, size_t new_comm) { #ifdef DEBUG cerr << "double RBERVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; #endif size_t old_comm = this->membership(v); double diff = 0.0; if (new_comm != old_comm) { double w_to_old = this->weight_to_comm(v, old_comm); #ifdef DEBUG cerr << "\t" << "w_to_old: " << w_to_old << endl; #endif double w_to_new = this->weight_to_comm(v, new_comm); #ifdef DEBUG cerr << "\t" << "w_to_new: " << w_to_new << endl; #endif double w_from_old = this->weight_from_comm(v, old_comm); #ifdef DEBUG cerr << "\t" << "w_from_old: " << w_from_old << endl; #endif double w_from_new = this->weight_from_comm(v, new_comm); #ifdef DEBUG cerr << "\t" << "w_from_new: " << w_from_new << endl; #endif size_t nsize = this->graph->node_size(v); #ifdef DEBUG cerr << "\t" << "nsize: " << nsize << endl; #endif size_t csize_old = this->csize(old_comm); #ifdef DEBUG cerr << "\t" << "csize_old: " << csize_old << endl; #endif size_t csize_new = this->csize(new_comm); #ifdef DEBUG cerr << "\t" << "csize_new: " << csize_new << endl; #endif double self_weight = this->graph->node_self_weight(v); #ifdef DEBUG cerr << "\t" << "self_weight: " << self_weight << endl; cerr << "\t" << "density: " << this->graph->density() << endl; #endif double possible_edge_difference_old = 0.0; if (this->graph->correct_self_loops()) possible_edge_difference_old = nsize*(ptrdiff_t)(2.0*csize_old - nsize); else possible_edge_difference_old = nsize*(ptrdiff_t)(2.0*csize_old - nsize - 1.0); #ifdef DEBUG cerr << "\t" << "possible_edge_difference_old: " << possible_edge_difference_old << endl; #endif double diff_old = w_to_old + w_from_old - self_weight - this->resolution_parameter*this->graph->density()*possible_edge_difference_old; #ifdef DEBUG cerr << "\t" << "diff_old: " << diff_old << endl; #endif double possible_edge_difference_new = 0.0; if (this->graph->correct_self_loops()) possible_edge_difference_new = nsize*(ptrdiff_t)(2.0*csize_new + nsize); else possible_edge_difference_new = nsize*(ptrdiff_t)(2.0*csize_new + nsize - 1.0); #ifdef DEBUG cerr << "\t" << "possible_edge_difference_new: " << possible_edge_difference_new << endl; #endif double diff_new = w_to_new + w_from_new + self_weight - this->resolution_parameter*this->graph->density()*possible_edge_difference_new; #ifdef DEBUG cerr << "\t" << "diff_new: " << diff_new << endl; #endif diff = diff_new - diff_old; #ifdef DEBUG cerr << "\t" << "diff: " << diff << endl;; #endif } #ifdef DEBUG cerr << "exit RBERVertexPartition::diff_move(" << v << ", " << new_comm << ")" << endl; cerr << "return " << diff << endl << endl; #endif return diff; } double RBERVertexPartition::quality(double resolution_parameter) { #ifdef DEBUG cerr << "double RBERVertexPartition::quality()" << endl; #endif double mod = 0.0; for (size_t c = 0; c < this->n_communities(); c++) { size_t csize = this->csize(c); double w = this->total_weight_in_comm(c); size_t comm_possible_edges = this->graph->possible_edges(csize); #ifdef DEBUG cerr << "\t" << "Comm: " << c << ", w_c=" << w << ", n_c=" << csize << ", comm_possible_edges=" << comm_possible_edges << ", p=" << this->graph->density() << "." << endl; #endif mod += w - resolution_parameter*this->graph->density()*comm_possible_edges; } #ifdef DEBUG cerr << "exit double RBERVertexPartition::quality()" << endl; cerr << "return " << mod << endl << endl; #endif return (2.0 - this->graph->is_directed())*mod; } leidenbase/src/Makevars.in0000644000176200001440000002431114457511122015240 0ustar liggesusersPKG_CFLAGS=$(C_VISIBILITY) PKG_CXXFLAGS=$(CXX_VISIBILITY) PKG_FFLAGS=$(F_VISIBILITY) PKG_CPPFLAGS=-DUSING_R -I. -Icore -Iinclude -Ivendor \ -I. -Ileidenalg -Ileidenbase \ @XML2_CPPFLAGS@ -DNDEBUG -DNTIMER -DNPRINT \ -DINTERNAL_ARPACK \ -DPRPACK_IGRAPH_SUPPORT -DIGRAPH_THREAD_LOCAL=/**/ PKG_LIBS=@XML2_LIBS@ @GMP_LIBS@ @GLPK_LIBS@ $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) # # Debian i386 fix. # # ifneq (,$(filter $(DEB_HOST_ARCH),i386)) # PKG_CPPFLAGS += -ffloat-store # endif all: $(SHLIB) OBJECTS=core/centrality/betweenness.o core/centrality/centrality_other.o core/centrality/centralization.o core/centrality/closeness.o core/centrality/coreness.o core/centrality/prpack.o core/centrality/prpack/prpack_base_graph.o core/centrality/prpack/prpack_igraph_graph.o core/centrality/prpack/prpack_preprocessed_ge_graph.o core/centrality/prpack/prpack_preprocessed_gs_graph.o core/centrality/prpack/prpack_preprocessed_scc_graph.o core/centrality/prpack/prpack_preprocessed_schur_graph.o core/centrality/prpack/prpack_result.o core/centrality/prpack/prpack_solver.o core/centrality/prpack/prpack_utils.o core/cliques/cliquer/cliquer.o core/cliques/cliquer/cliquer_graph.o core/cliques/cliquer/reorder.o core/cliques/cliquer_wrapper.o core/cliques/cliques.o core/cliques/glet.o core/cliques/maximal_cliques.o core/community/community_misc.o core/community/edge_betweenness.o core/community/fast_modularity.o core/community/fluid.o core/community/infomap/infomap.o core/community/infomap/infomap_FlowGraph.o core/community/infomap/infomap_Greedy.o core/community/infomap/infomap_Node.o core/community/label_propagation.o core/community/leading_eigenvector.o core/community/leiden.o core/community/louvain.o core/community/modularity.o core/community/optimal_modularity.o core/community/spinglass/NetDataTypes.o core/community/spinglass/NetRoutines.o core/community/spinglass/clustertool.o core/community/spinglass/pottsmodel_2.o core/community/walktrap/walktrap.o core/community/walktrap/walktrap_communities.o core/community/walktrap/walktrap_graph.o core/community/walktrap/walktrap_heap.o core/connectivity/cohesive_blocks.o core/connectivity/components.o core/connectivity/separators.o core/constructors/adjacency.o core/constructors/atlas.o core/constructors/basic_constructors.o core/constructors/de_bruijn.o core/constructors/famous.o core/constructors/full.o core/constructors/kautz.o core/constructors/lcf.o core/constructors/linegraph.o core/constructors/prufer.o core/constructors/regular.o core/core/array.o core/core/buckets.o core/core/cutheap.o core/core/dqueue.o core/core/error.o core/core/estack.o core/core/fixed_vectorlist.o core/core/grid.o core/core/heap.o core/core/indheap.o core/core/interruption.o core/core/marked_queue.o core/core/matrix.o core/core/memory.o core/core/printing.o core/core/progress.o core/core/psumtree.o core/core/set.o core/core/sparsemat.o core/core/spmatrix.o core/core/stack.o core/core/statusbar.o core/core/strvector.o core/core/trie.o core/core/vector.o core/core/vector_ptr.o core/flow/flow.o core/flow/st-cuts.o core/games/barabasi.o core/games/callaway_traits.o core/games/citations.o core/games/correlated.o core/games/degree_sequence.o core/games/degree_sequence_vl/gengraph_box_list.o core/games/degree_sequence_vl/gengraph_degree_sequence.o core/games/degree_sequence_vl/gengraph_graph_molloy_hash.o core/games/degree_sequence_vl/gengraph_graph_molloy_optimized.o core/games/degree_sequence_vl/gengraph_mr-connected.o core/games/degree_sequence_vl/gengraph_powerlaw.o core/games/degree_sequence_vl/gengraph_random.o core/games/dotproduct.o core/games/erdos_renyi.o core/games/establishment.o core/games/forestfire.o core/games/grg.o core/games/growing_random.o core/games/islands.o core/games/k_regular.o core/games/preference.o core/games/recent_degree.o core/games/sbm.o core/games/static_fitness.o core/games/tree.o core/games/watts_strogatz.o core/graph/adjlist.o core/graph/attributes.o core/graph/basic_query.o core/graph/cattributes.o core/graph/iterators.o core/graph/type_indexededgelist.o core/graph/visitors.o core/hrg/hrg.o core/hrg/hrg_types.o core/internal/glpk_support.o core/internal/hacks.o core/internal/lsap.o core/internal/qsort.o core/internal/qsort_r.o core/internal/zeroin.o core/io/dimacs.o core/io/dl-lexer.o core/io/dl-parser.o core/io/dl.o core/io/dot.o core/io/edgelist.o core/io/gml-lexer.o core/io/gml-parser.o core/io/gml-tree.o core/io/gml.o core/io/graphdb.o core/io/graphml.o core/io/leda.o core/io/lgl-lexer.o core/io/lgl-parser.o core/io/lgl.o core/io/ncol-lexer.o core/io/ncol-parser.o core/io/ncol.o core/io/pajek-lexer.o core/io/pajek-parser.o core/io/pajek.o core/isomorphism/bliss.o core/isomorphism/bliss/defs.o core/isomorphism/bliss/graph.o core/isomorphism/bliss/heap.o core/isomorphism/bliss/orbit.o core/isomorphism/bliss/partition.o core/isomorphism/bliss/uintseqhash.o core/isomorphism/bliss/utils.o core/isomorphism/isoclasses.o core/isomorphism/isomorphism_misc.o core/isomorphism/lad.o core/isomorphism/queries.o core/isomorphism/vf2.o core/layout/circular.o core/layout/davidson_harel.o core/layout/drl/DensityGrid.o core/layout/drl/DensityGrid_3d.o core/layout/drl/drl_graph.o core/layout/drl/drl_graph_3d.o core/layout/drl/drl_layout.o core/layout/drl/drl_layout_3d.o core/layout/drl/drl_parse.o core/layout/fruchterman_reingold.o core/layout/gem.o core/layout/graphopt.o core/layout/kamada_kawai.o core/layout/large_graph.o core/layout/layout_bipartite.o core/layout/layout_grid.o core/layout/layout_random.o core/layout/mds.o core/layout/merge_dla.o core/layout/merge_grid.o core/layout/reingold_tilford.o core/layout/sugiyama.o core/linalg/arpack.o core/linalg/blas.o core/linalg/eigen.o core/linalg/lapack.o core/math/bfgs.o core/math/complex.o core/math/utils.o core/misc/bipartite.o core/misc/chordality.o core/misc/cocitation.o core/misc/coloring.o core/misc/conversion.o core/misc/degree_sequence.o core/misc/embedding.o core/misc/feedback_arc_set.o core/misc/graphicality.o core/misc/matching.o core/misc/microscopic_update.o core/misc/mixing.o core/misc/motifs.o core/misc/other.o core/misc/scan.o core/misc/sir.o core/misc/spanning_trees.o core/operators/add_edge.o core/operators/complementer.o core/operators/compose.o core/operators/connect_neighborhood.o core/operators/contract.o core/operators/difference.o core/operators/disjoint_union.o core/operators/intersection.o core/operators/misc_internal.o core/operators/permute.o core/operators/rewire.o core/operators/rewire_edges.o core/operators/simplify.o core/operators/subgraph.o core/operators/union.o core/paths/all_shortest_paths.o core/paths/bellman_ford.o core/paths/dijkstra.o core/paths/distances.o core/paths/eulerian.o core/paths/histogram.o core/paths/johnson.o core/paths/random_walk.o core/paths/shortest_paths.o core/paths/simple_paths.o core/paths/unweighted.o core/properties/basic_properties.o core/properties/constraint.o core/properties/convergence_degree.o core/properties/dag.o core/properties/degrees.o core/properties/girth.o core/properties/loops.o core/properties/multiplicity.o core/properties/neighborhood.o core/properties/spectral.o core/properties/trees.o core/properties/triangles.o core/random/random.o core/scg/scg.o core/scg/scg_approximate_methods.o core/scg/scg_exact_scg.o core/scg/scg_kmeans.o core/scg/scg_optimal_method.o core/scg/scg_utils.o core/version.o vendor/cs/cs_add.o vendor/cs/cs_amd.o vendor/cs/cs_chol.o vendor/cs/cs_cholsol.o vendor/cs/cs_compress.o vendor/cs/cs_counts.o vendor/cs/cs_cumsum.o vendor/cs/cs_dfs.o vendor/cs/cs_dmperm.o vendor/cs/cs_droptol.o vendor/cs/cs_dropzeros.o vendor/cs/cs_dupl.o vendor/cs/cs_entry.o vendor/cs/cs_ereach.o vendor/cs/cs_etree.o vendor/cs/cs_fkeep.o vendor/cs/cs_gaxpy.o vendor/cs/cs_happly.o vendor/cs/cs_house.o vendor/cs/cs_ipvec.o vendor/cs/cs_leaf.o vendor/cs/cs_load.o vendor/cs/cs_lsolve.o vendor/cs/cs_ltsolve.o vendor/cs/cs_lu.o vendor/cs/cs_lusol.o vendor/cs/cs_malloc.o vendor/cs/cs_maxtrans.o vendor/cs/cs_multiply.o vendor/cs/cs_norm.o vendor/cs/cs_permute.o vendor/cs/cs_pinv.o vendor/cs/cs_post.o vendor/cs/cs_print.o vendor/cs/cs_pvec.o vendor/cs/cs_qr.o vendor/cs/cs_qrsol.o vendor/cs/cs_randperm.o vendor/cs/cs_reach.o vendor/cs/cs_scatter.o vendor/cs/cs_scc.o vendor/cs/cs_schol.o vendor/cs/cs_spsolve.o vendor/cs/cs_sqr.o vendor/cs/cs_symperm.o vendor/cs/cs_tdfs.o vendor/cs/cs_transpose.o vendor/cs/cs_updown.o vendor/cs/cs_usolve.o vendor/cs/cs_util.o vendor/cs/cs_utsolve.o vendor/mini-gmp/mini-gmp.o vendor/plfit/gss.o vendor/plfit/hzeta.o vendor/plfit/kolmogorov.o vendor/plfit/lbfgs.o vendor/plfit/mt.o vendor/plfit/options.o vendor/plfit/platform.o vendor/plfit/plfit.o vendor/plfit/plfit_error.o vendor/plfit/rbinom.o vendor/plfit/sampling.o vendor/arpack/dgetv0.o vendor/arpack/dlaqrb.o vendor/arpack/dmout.o vendor/arpack/dnaitr.o vendor/arpack/dnapps.o vendor/arpack/dnaup2.o vendor/arpack/dnaupd.o vendor/arpack/dnconv.o vendor/arpack/dneigh.o vendor/arpack/dneupd.o vendor/arpack/dngets.o vendor/arpack/dsaitr.o vendor/arpack/dsapps.o vendor/arpack/dsaup2.o vendor/arpack/dsaupd.o vendor/arpack/dsconv.o vendor/arpack/dseigt.o vendor/arpack/dsesrt.o vendor/arpack/dseupd.o vendor/arpack/dsgets.o vendor/arpack/dsortc.o vendor/arpack/dsortr.o vendor/arpack/dstatn.o vendor/arpack/dstats.o vendor/arpack/dstqrb.o vendor/arpack/dvout.o vendor/arpack/ivout.o vendor/arpack/second.o vendor/arpack/wrap.o vendor/simpleraytracer/Color.o vendor/simpleraytracer/Light.o vendor/simpleraytracer/Point.o vendor/simpleraytracer/RIgraphRay.o vendor/simpleraytracer/Ray.o vendor/simpleraytracer/RayTracer.o vendor/simpleraytracer/RayVector.o vendor/simpleraytracer/Shape.o vendor/simpleraytracer/Sphere.o vendor/simpleraytracer/Triangle.o vendor/simpleraytracer/unit_limiter.o vendor/uuid/R.o vendor/uuid/clear.o vendor/uuid/compare.o vendor/uuid/copy.o vendor/uuid/gen_uuid.o vendor/uuid/isnull.o vendor/uuid/pack.o vendor/uuid/parse.o vendor/uuid/unpack.o vendor/uuid/unparse.o leidenalg/CPMVertexPartition.o leidenalg/GraphHelper.o leidenalg/LinearResolutionParameterVertexPartition.o leidenalg/ModularityVertexPartition.o leidenalg/MutableVertexPartition.o leidenalg/Optimiser.o leidenalg/RBConfigurationVertexPartition.o leidenalg/RBERVertexPartition.o leidenalg/ResolutionParameterVertexPartition.o leidenalg/SignificanceVertexPartition.o leidenalg/SurpriseVertexPartition.o leidenbase/leidenFindPartition.o leidenbase/leidenFindPartitionR2C.o leidenbase/vignettes/0000755000176200001440000000000014532173045014361 5ustar liggesusersleidenbase/vignettes/leidenbase.Rmd0000644000176200001440000001460514444624115017127 0ustar liggesusers--- title: "leidenbase.Rmd" author: "Brent Ewing" date: "1/19/2022" output: html_vignette vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{leidenbase} %\VignetteEncoding{UTF-8} --- ```{r setup, echo=FALSE, results='hide', message=FALSE} require(knitr) opts_chunk$set(error=FALSE, message=FALSE, warning=FALSE) library(leidenbase) library(igraph) ``` ### Introduction Leidenbase consists of R and C++ interfaces for the basic community detection functions of Vincent Traags's Leidenalg package. The Leidenalg algorithm is described in the article Traag, V.A., Waltman. L., Van Eck, N.-J. (2018). *From Louvain to Leiden: guaranteeing well-connected communities.* Scientific reports, 9(1), 5233. [10.1038/s41598-019-41695-z](http://dx.doi.org/10.1038/s41598-019-41695-z) Detailed information describing use of the leiden algorithm is available at https://leidenalg.readthedocs.io/en/latest/ leidenalg source code is available at https://github.com/vtraag/leidenalg ### R Interface The R interface consists of the `leiden_find_partition` function ``` r leiden_find_partition( igraph, partition_type = c("CPMVertexPartition", "ModularityVertexPartition", "RBConfigurationVertexPartition", "RBERVertexPartition", "SignificanceVertexPartition", "SurpriseVertexPartition"), initial_membership = NULL, edge_weights = NULL, node_sizes = NULL, seed = NULL, resolution_parameter = 0.1, num_iter = 2, verbose = FALSE ) Arguments: igraph: R igraph graph. partition_type: String partition type name. Default is CPMVertexParition. initial_membership: Numeric vector of initial membership assignments of nodes. These are 1-based indices. Default is one community per node. edge_weights: Numeric vector of edge weights. Default is 1.0 for all edges. node_sizes: Numeric vector of node sizes. Default is 1 for all nodes. seed: Numeric random number generator seed. The seed value must be either NULL for random seed values or greater than 0 for a fixed seed value. Default is NULL. resolution_parameter: Numeric resolution parameter. The value must be greater than 0.0. Default is 0.1. The resolution_parameter is ignored for the partition_types ModularityVertexPartition, SignificanceVertexPartition, and SurpriseVertexPartition. num_iter: Numeric number of iterations. Default is 2. verbose: A logic flag to determine whether or not we should print run diagnostics. Value: A named list consisting of a numeric vector where each value is the community to which the node belongs (1-based indices), a numeric quality value, a numeric modularity, a numeric significance, a numeric vector of edge weights within each community, a numeric vector of edge weights from each community, a numeric vector of edge weights to each community, and total edge weight. ``` In order to use `leiden_find_partition`, create or load an igraph graph and then call `leiden_find_partition`. For example, ```{r} library(igraph) fpath <- system.file('testdata', 'igraph_n1500_edgelist.txt.gz', package='leidenbase') zfp <- gzfile(fpath) igraph <- read_graph(file = zfp, format='edgelist') res <- leiden_find_partition(igraph, partition_type = 'CPMVertexPartition', seed = 123456, resolution_parameter = 0.5) ``` `leiden_find_partition` returns ```{r} str(res) ``` The membership vector consists of the community value for each node. For example, ```{r} head(res[['membership']]) ``` The nodes that belong to community 1 are ```{r} which(res[['membership']]==1) ``` The first three communities are ```{r} # lim1 <- max(res$membership) lim1 <- 3 for( i in seq(lim1)) { cat(paste0('Community ', i, ':')) for(j in which(res[['membership']]==i)) cat(' ', j) cat('\n') } ``` ### C/C++ Interface The C/C++ interface consists of the `leidenFindPartition` function ``` c++ int leidenFindPartition( igraph_t *pigraph, std::string const partitionType, std::vector < size_t > const *pinitialMembership, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, size_t seed, double resolutionParameter, std::int32_t numIter, std::vector < size_t > *pmembership, std::vector < double > *pweightInCommunity, std::vector < double > *pweightFromCommunity, std::vector < double > *pweightToCommunity, double *pweightTotal, double *pquality, double *pmodularity, double *psignificance, int *pstatus ) Parameters: igraph: pointer to igraph_t graph partitionType partition type used for optimization initialMembership vector of initial membership assignments of nodes (NULL for default of one community per node) edgeWeights vector of weights of edges (NULL for default of 1.0) nodeSizes vector of node sizes (NULL for default of 1) seed random number generator seed (0=random seed) resolutionParameter resolution parameter numIter number of iterations pmembership vector of node membership assignments pweightInCommunity vector of edge weights within community pweightFromCommunity vector of edge weights from community pweightToCommunity vector of edge weights to community pweightTotal total edge weights pquality partition quality pmodularity partition modularity psignificance partition significance pstatus function status (0=success; -1=failure) ``` Notes for the C/C++ interface: * Edit leidenFindPartition.cpp to set the preprocessor definition `R_INTERFACE` to 0. * The resolution parameter is ignored for the partition types ModularityVertexPartition, SignificanceVertexPartition, and SurpriseVertexPartition * To use the `leidenFindPartition` function, compile and link to the files src/leidenFindPartition.(cpp|h), src/leidenalg/src/\*.cpp, and src/leidenalg/include/\*.h and a C igraph object library. leidenbase/configure.win0000644000176200001440000000000014447673547015060 0ustar liggesusersleidenbase/R/0000755000176200001440000000000014451631176012556 5ustar liggesusersleidenbase/R/leidenbase.R0000644000176200001440000002161414451377654015010 0ustar liggesusers# # Leidenalg find partition R-C interface. # Copyright (C) 2019 Cole Trapnell # University of Washington, Genome Sciences Department, Seattle, WA # # This file is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation, either version 3 of the License, or (at your option) any later # version. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this program. If not, see http://www.gnu.org/licenses/. # #'@title Leiden find partition community detection function #' #'@description R to C wrapper that runs the basic Leiden community detection algorithm, #'which is similar to the find_partition() function in the python Leidenalg distribution. #' #'@details #'The Leiden algorithm is described in #' From Louvain to Leiden: guaranteeing well-connected communities. #' V. A. Traag and L. Waltman and N. J. van Eck #' Scientific Reports, 9(1) (2019) #' DOI: 10.1038/s41598-019-41695-z. #' #'Significance is described in #' Significant Scales in Community Structure #' V. A. Traag, G. Krings, and P. Van Dooren #' Scientific Reports, 3(1) (2013) #' DOI: 10.1038/srep02930 #' #' Notes excerpted from leidenalg/src/VertexPartition.py #' \itemize{ #' \item \emph{ CPMVertexPartition } #' Implements Constant Potts Model. #' This quality function uses a linear resolution parameter and #' is well-defined for both positive and negative edge weights. #' \item \emph{ ModularityVertexPartition } #' Implements modularity. #' This quality function is well-defined only for positive edge weights. #' \item\emph{ RBConfigurationVertexPartition } #' Implements Reichardt and Bornholdt’s Potts model with a configuration null model. #' This quality function uses a linear resolution parameter and is well-defined only #' for positive edge weights. #' \item \emph{ RBERVertexPartition } #' Implements Reichardt and Bornholdt’s Potts model with an Erdos-Renyi null model. #' This quality function uses a linear resolution parameter and is well-defined only #' for positive edge weights. #' \item \emph{ SignificanceVertexPartition } #' Implements Significance. #' This quality function is well-defined only for unweighted graphs. #' \item \emph{ SurpriseVertexPartition } #' Implements (asymptotic) Surprise. #' This quality function is well-defined only for positive edge weights. #' } #' #'@param igraph R igraph graph. #'@param partition_type String partition type name. Default is #' CPMVertexParition. #'@param initial_membership Numeric vector of initial membership #' assignments of nodes. These are 1-based indices. Default is one #' community per node. #'@param edge_weights Numeric vector of edge weights. Default is 1.0 for #' all edges. #'@param node_sizes Numeric vector of node sizes. Default is 1 for all #' nodes. #'@param seed Numeric random number generator seed. The seed value must be #' either NULL for random seed values or greater than 0 for a fixed seed #' value. Default is NULL. #'@param resolution_parameter Numeric resolution parameter. The value #' must be greater than 0.0. Default is 0.1. The resolution_parameter is #' ignored for the partition_types ModularityVertexPartition, #' SignificanceVertexPartition, and SurpriseVertexPartition. #'@param num_iter Numeric number of iterations. Default is 2. #'@param verbose A logic flag to determine whether or not we should print #' run diagnostics. #' #'@return A named list consisting of a numeric vector of the node #' community memberships (1-based indices), a numeric quality value, #' a numeric modularity, a numeric significance, a numeric vector of #' edge weights within each community, a numeric vector of edge weights #' from each community, a numeric vector of edge weights to each #' community, and total edge weight in the graph. #' #'@references #' V. A. Traag, L. Waltman, N. J. van Eck (2019). From Louvain #' to Leiden: guaranteeing well-connected communities. #' Scientific Reports, 9(1). #' DOI: 10.1038/s41598-019-41695-z #' #'Significant Scales in Community Structure #' V. A. Traag, G. Krings, and P. Van Dooren #' Scientific Reports, 3(1) (2013) #' DOI: 10.1038/srep02930 #' #' @examples #' library(igraph) #' fpath <- system.file( 'testdata', 'igraph_n1500_edgelist.txt.gz', package = 'leidenbase' ) #' zfp <- gzfile(fpath) #' igraph <- read_graph( file = zfp, format='edgelist', n=1500 ) #' res <- leiden_find_partition(igraph=igraph, #' partition_type='CPMVertexPartition', #' resolution_parameter=1e-5) #' #'@import igraph #'@useDynLib leidenbase _leiden_find_partition #'@export leiden_find_partition <- function( igraph, partition_type = c( 'CPMVertexPartition', 'ModularityVertexPartition', 'RBConfigurationVertexPartition', 'RBERVertexPartition', 'SignificanceVertexPartition', 'SurpriseVertexPartition' ), initial_membership = NULL, edge_weights = NULL, node_sizes = NULL, seed = NULL, resolution_parameter = 0.1, num_iter = 2, verbose = FALSE ) { partition_type <- match.arg( partition_type ) # Check input parameters err_string = '' # igraph must be an igraph graph object stopifnot( is_igraph( igraph ) ) # we need the vertex and edge counts to check input vector lengths num_edge = igraph::gsize( igraph ) num_vertex = igraph::gorder( igraph ) # check input vector parameters if( !is.null( initial_membership ) ) { if( length( initial_membership ) != num_vertex ) err_string <- paste( err_string, ' -> initial_membership length != number of vertices\n', sep = '' ) if( mode( initial_membership ) != 'numeric' ) err_string <- paste( err_string, ' -> initial_membership is not an numeric vector\n', sep = '' ) } if( !is.null( edge_weights ) ) { if( length( edge_weights ) != num_edge ) err_string <- paste( err_string, ' -> edge_weights length != number of edges\n', sep = '' ) if( mode( edge_weights ) != 'numeric' ) err_string <- paste( err_string, ' -> edge_weights is not an double vector\n', sep = '' ) } if( !is.null( node_sizes ) ) { if( length( node_sizes ) != num_vertex ) err_string <- paste( err_string, ' -> node_sizes length != number of vertices\n', sep = '' ) if( mode( node_sizes ) != 'numeric' ) err_string <- paste( err_string, ' -> node_sizes is not an numeric vector\n', sep = '' ) } # check remaining parameters if( !is.null( seed ) && ( mode( seed ) != 'numeric' || seed <= 0 ) ) err_string <- paste( err_string, ' -> seed < 1\n', sep = '' ) # Check resolution parameter if relevant. if( partition_type %in% c('CPMVertexPartition','RBConfigurationVertexPartition','RBERVertexPartition') ) { if( is.null( resolution_parameter ) ) resolution_parameter = 0.1 if( mode( resolution_parameter ) != 'numeric' || resolution_parameter <= 0.0 ) err_string <- paste( err_string, ' -> resolution_parameter <= 0\n', sep = '' ) } if( is.null( num_iter ) ) num_iter = 2 if( mode( num_iter ) != 'numeric' || num_iter < 1 ) err_string <- paste( err_string, ' -> num_iter < 1\n', sep = '' ) if( !identical( err_string, '' ) ) stop( paste( 'input parameter error(s):\n', err_string, sep = '' ) ) if( verbose ) { message( 'leiden_find_partition: partition_type ', partition_type ) if( is.null( seed ) ) message( 'leiden_find_partition: seed NULL' ) else message( 'leiden_find_partition: seed ', seed ) message( 'leiden_find_partition: resolution_parameter ', resolution_parameter ) message( 'leiden_find_partition: num_iter ', num_iter ) message( 'leiden_find_partition: initial_membership ', length(initial_membership ) ) message( 'leiden_find_partition: edge_weights ', length( edge_weights ) ) message( 'leiden_find_partition: node_sizes ', length( node_sizes ) ) message( 'leiden_find_partition: number vertices ', num_vertex ) message( 'leiden_find_partition: number edges ', num_edge ) } igraph_edgelist <- as_edgelist(igraph, names=FALSE) igraph_numvertex <- as.numeric(vcount(igraph)) igraph_numedge <- as.numeric(ecount(igraph)) igraph_directed <- if(is_directed(igraph) == TRUE) 1 else 0 result = .Call( '_leiden_find_partition', igraph_edgelist, igraph_numvertex, igraph_numedge, igraph_directed, partition_type, initial_membership, edge_weights, node_sizes, seed, resolution_parameter, num_iter ) return( result ) } .onUnload <- function (libpath) { library.dynam.unload("leidenbase", libpath) } leidenbase/NEWS.md0000644000176200001440000000112714532143105013442 0ustar liggesusers# leidenbase 0.1.26 * placate compilers # leidenbase 0.1.25 * use edgelist to pass graph to C * update C igraph to 0.9.8 * update leidenalg to 0.8.10 # leidenbase 0.1.14 * fix regression in src/rigraph/src/rinterface_extra.c # leidenbase 0.1.13 * reduce test precision # leidenbase 0.1.9 * fixes for CRAN submission * configure script improvements and fixes # leidenbase 0.1.4 * update leidenalg to most recent code on github * update igraph to version 1.2.11 * test on ARM MacOS # leidenbase 0.1.3 * update leidenalg to version 0.8.4.dev4+g0947e63 * update igraph to version 0.8.5 leidenbase/MD50000644000176200001440000013227714532326115012673 0ustar liggesusersecb8b6577934aab542592563d29e747a *DESCRIPTION 8a259a047d89e88d6bcfa9d0a6d2d965 *NAMESPACE 4488f661a903f0a10c46b61497545c68 *NEWS.md 3bf6487a053b083d3729752ae5a55471 *R/leidenbase.R 7982aacd2f2efc9dc4dface6db8ccf00 *build/vignette.rds f89c7780070ec8f00ba8069a744208b5 *cleanup f89c7780070ec8f00ba8069a744208b5 *cleanup.win 3a1bf751223ed6d19ec32cb01ba6c40c *configure ab162a480907a8008cc7ffed9d3b4528 *configure.ac d41d8cd98f00b204e9800998ecf8427e *configure.win f11584f41ffa991c4a79a3a261bbefc3 *inst/doc/leidenbase.R a7a20c17b8bd529cf8d0093aed18b87d *inst/doc/leidenbase.Rmd c687ce38e8ce920d03aa6ac4bca7f80f *inst/doc/leidenbase.html 1cf7b57f6bd5d1c985f7a54a9eb3fe8b *inst/testdata/expected_values.txt fe47c49467b20821b5af59eb9b906354 *inst/testdata/igraph_n1500_edgelist.txt.gz 13fe4e344ab07f7e5a5afc24458995c6 *inst/testdata/test01_file01.txt 1ae5491432d1a6dceba113ac7bcb166f *inst/testdata/test02_file01.txt fede5f595e9421cb88ef5440adcb7c7c *inst/testdata/test03_file01.txt 3dd2957652f55d15e03ce52eceb34913 *inst/testdata/test04_file01.txt 48d38d2bd2e1bf261714a5a5120b8fb1 *inst/testdata/test05_file01.txt 1ae5491432d1a6dceba113ac7bcb166f *inst/testdata/test06_file01.txt a8f5fa41ddfc9d38665cf29a62fe7272 *inst/testdata/test07_file01.txt a8f5fa41ddfc9d38665cf29a62fe7272 *inst/testdata/test08_file01.txt a8f5fa41ddfc9d38665cf29a62fe7272 *inst/testdata/test09_file01.txt a8f5fa41ddfc9d38665cf29a62fe7272 *inst/testdata/test10_file01.txt d3fb816bf4ce4814cf4c899e2944782b *man/leiden_find_partition.Rd e3e238aa4d7c5abf3ddcb254f09c475b *src/Makevars.in 966e71b9e1fecec3fba99d9c3e7f4764 *src/Makevars.ucrt 55106dfe614425199dab55d3aa30d8a4 *src/Makevars.win d41d8cd98f00b204e9800998ecf8427e *src/config.h ed9754682235a2408cb82b195ff42f5d *src/config.h.in d08e71d2839e90e735b4e31ef6853b75 *src/core/centrality/betweenness.c b9642acc12714ed6f9062372ab93a24c *src/core/centrality/centrality_other.c b7fd69bf60866c8c56757230155c512b *src/core/centrality/centralization.c e711d4286d1262aafee76ea53ab217e9 *src/core/centrality/closeness.c 535e85a3e20f6c2737b7a09b51adf39e *src/core/centrality/coreness.c ecf0908c04b5f6055540799987805166 *src/core/centrality/prpack.cpp 9cdd08531c091877493dc38d6d9a76a6 *src/core/centrality/prpack/prpack.h 26eb720486ddd4202eef0bdceb5f147c *src/core/centrality/prpack/prpack_base_graph.cpp de425a2ce15f49873a78bf066160a8bb *src/core/centrality/prpack/prpack_base_graph.h ce237527dbb79aba4c3f197af2089ab0 *src/core/centrality/prpack/prpack_csc.h 1d324e52dcd60f9e160e29da8abb743b *src/core/centrality/prpack/prpack_csr.h c2b48092d1a622e0164d27f87e965236 *src/core/centrality/prpack/prpack_edge_list.h 792d5e0e15dd5cc3c16b1869ad54dc8a *src/core/centrality/prpack/prpack_igraph_graph.cpp d74913055c3de3af26ddfe2c3a532e56 *src/core/centrality/prpack/prpack_igraph_graph.h c6b097e47682a09ee4d79daa737b2433 *src/core/centrality/prpack/prpack_preprocessed_ge_graph.cpp 272ef27772eb360fc7bd04cfc0a49966 *src/core/centrality/prpack/prpack_preprocessed_ge_graph.h 23062aa2dd3f10a441ee1cbcdcd7569e *src/core/centrality/prpack/prpack_preprocessed_graph.h 9affaca2378bcafb6739ffe64dbd70ec *src/core/centrality/prpack/prpack_preprocessed_gs_graph.cpp 9d70bca6d969ba2d4dbc44f4299464d0 *src/core/centrality/prpack/prpack_preprocessed_gs_graph.h 921946f11802cf885ef2a068632402dd *src/core/centrality/prpack/prpack_preprocessed_scc_graph.cpp f03c8a4e5a4c7820e22c49777b6a9db4 *src/core/centrality/prpack/prpack_preprocessed_scc_graph.h 373931191c0dd689498f6e7730f91f4e *src/core/centrality/prpack/prpack_preprocessed_schur_graph.cpp 5310e7f136665a4fb83cf38399f4386a *src/core/centrality/prpack/prpack_preprocessed_schur_graph.h 5caea69fd3640b0ea23b7324092c3106 *src/core/centrality/prpack/prpack_result.cpp f2b8f72eac8bcd6d82309fd3cd43f7ab *src/core/centrality/prpack/prpack_result.h 8f13f2a6e30aae02f5949498ac9d9617 *src/core/centrality/prpack/prpack_solver.cpp d911dc6eaff52b55807ee6deb1625b9f *src/core/centrality/prpack/prpack_solver.h 70e75452f74b31992a58c78e69325468 *src/core/centrality/prpack/prpack_utils.cpp a987278dc20edff4eae2f889477bcc86 *src/core/centrality/prpack/prpack_utils.h cc9c9502b7396556a4c428557326b1a3 *src/core/centrality/prpack_internal.h 77c7b501090e21b9f2404885e6049fc9 *src/core/cliques/cliquer/cliquer.c a788a20d33308abb310436da1002437f *src/core/cliques/cliquer/cliquer.h def5b5b4e60d44598b846c58054ea5f7 *src/core/cliques/cliquer/cliquer_graph.c 113c0673e6102fa0103b1f4e01b1b6d0 *src/core/cliques/cliquer/cliquerconf.h 4cf4b5919f3418e1a6881bb28198a0e2 *src/core/cliques/cliquer/graph.h e2c6b268c6741abaf0b31a529c3d9c93 *src/core/cliques/cliquer/misc.h c8cca9d2788a22dd362f5a3d1d0208b5 *src/core/cliques/cliquer/reorder.c 164d316a2ead051b7054673bad48277d *src/core/cliques/cliquer/reorder.h 91bbe466cd13bb3ce0db21d4f8ecfa4e *src/core/cliques/cliquer/set.h 3f81c57c0dc1392e7ea0aec6837188ea *src/core/cliques/cliquer_internal.h 637c5a3ec62edd92a53661db0fa983a7 *src/core/cliques/cliquer_wrapper.c b5c4ee4037f05b9d180a73a66a67caef *src/core/cliques/cliques.c cac895d063b0c6e7ce5f24d96a484460 *src/core/cliques/glet.c 8ca1915ff062c0f2bb5778375b0a66e9 *src/core/cliques/maximal_cliques.c 8128546ba6b6506160a2e3c41dea62ed *src/core/cliques/maximal_cliques_template.h 9042bbfc3822f5c0a15e27f4491c49ac *src/core/community/community_misc.c a18cd1facde22fe9fc415657a43b984e *src/core/community/edge_betweenness.c 96aa75d1fc3e95b570f2a9128841c1ec *src/core/community/fast_modularity.c d2a06c5263c1dd6378946e1ccab0b70f *src/core/community/fluid.c c847383b591ef39f5f9a10f131946970 *src/core/community/infomap/infomap.cc 71bcadb66335c7098df7477b620a7ecd *src/core/community/infomap/infomap_FlowGraph.cc 02dc0c863532822d40030751b43fdbbf *src/core/community/infomap/infomap_FlowGraph.h b603e1b4de5a609d42e881703e85ca42 *src/core/community/infomap/infomap_Greedy.cc 9c24bfc97bf0dff0c7d15df92aab33c8 *src/core/community/infomap/infomap_Greedy.h 722462daf1946a209cf2a54ad286c804 *src/core/community/infomap/infomap_Node.cc b7d583db2d7b06d0ccea9282b3199e01 *src/core/community/infomap/infomap_Node.h 9d9f92f0b3cbb5f05828039508d718d3 *src/core/community/label_propagation.c cf20910ff1b0880cd752f19e7e536da4 *src/core/community/leading_eigenvector.c eafca7d053e478a6100a0711f9de8b30 *src/core/community/leiden.c 62a5bd96e406c7a1acb908f22870f9d8 *src/core/community/louvain.c 0b302dd22ea8de55494c5f970b44ba7a *src/core/community/modularity.c 00347f22161711d9a3a5ba932b94ea10 *src/core/community/optimal_modularity.c 3dd36251e086c58a5aeb3c5c0f0f1a35 *src/core/community/spinglass/NetDataTypes.cpp e95cf5a8759c3a16b567a3d2ef7b4f98 *src/core/community/spinglass/NetDataTypes.h 4ab665df3172c25d96825709f0f92a8f *src/core/community/spinglass/NetRoutines.cpp 52680969d2ee4aee2ae060850812544e *src/core/community/spinglass/NetRoutines.h 4f2f913dfc2e14e839fb5b0ac9dba36e *src/core/community/spinglass/clustertool.cpp 68563d87b828a77767f0c18f39861411 *src/core/community/spinglass/pottsmodel_2.cpp 50ff03e2a1857b169961c3745e06be7a *src/core/community/spinglass/pottsmodel_2.h 4d31e30443503bc53f415bea3fa3f496 *src/core/community/walktrap/walktrap.cpp c8789cc2f6bb1cdd6af47357a50459f8 *src/core/community/walktrap/walktrap_communities.cpp 7e4bd276107bf99b3b444e3595f5e4d6 *src/core/community/walktrap/walktrap_communities.h 432ffe27a508d255f8065c9391aac201 *src/core/community/walktrap/walktrap_graph.cpp 041cdea7d3a98eaa905aee512394e3ad *src/core/community/walktrap/walktrap_graph.h 01eca7aeb862dd4158f733498fc668b0 *src/core/community/walktrap/walktrap_heap.cpp 71a5b8e98c91667acccbb09a340787ba *src/core/community/walktrap/walktrap_heap.h c7a731624933d8aa2cd8d3553735f7e6 *src/core/connectivity/cohesive_blocks.c a7c2016e3b802ae4af78cb12f2f17e7b *src/core/connectivity/components.c 980d906d3b47274597e9faae3d805105 *src/core/connectivity/separators.c 4f1c6327ba05ff51e14ae0e970d531d5 *src/core/constructors/adjacency.c 3c109268ddd0458081268dfa49aee140 *src/core/constructors/atlas-edges.h 3b1c0e03e35fd033d5398a93f6ee347a *src/core/constructors/atlas.c 32e2e7a655d657fdfae3e4cbe50ca02a *src/core/constructors/basic_constructors.c bcc3d986153d2d64ed9ff46ae23beb52 *src/core/constructors/de_bruijn.c dfafadd45096c960574d8ef62f1c9727 *src/core/constructors/famous.c ed52e3d469efd8febc2888cdcf53754b *src/core/constructors/full.c e04fb0d4283f80ac2d854ab9e4ffea14 *src/core/constructors/kautz.c 95be54fdf110dbb4b2643ff2bac9d721 *src/core/constructors/lcf.c 256faa93f66d925f48437ee2ada23fb8 *src/core/constructors/linegraph.c 4f02fc2a55485d234b4f88ac26d252aa *src/core/constructors/prufer.c 78959695c77ddc9ba7ea70306807429b *src/core/constructors/regular.c 4221ca433cc7eff3f4f4504d0c5114f1 *src/core/core/array.c 44f64db0ad9bb299c590e3cc2a64ddd8 *src/core/core/array.pmt 9fdf9211c7e4a1b77f485b53d890d4e2 *src/core/core/buckets.c c7784a7b81fc0020b87af8b9b3128f04 *src/core/core/buckets.h 4e31798252e302512b803c47b7be3973 *src/core/core/cutheap.c 0e267b727def3b5e5d44b80a3cc7eb72 *src/core/core/cutheap.h 2a785ab747ee2da29837dbd75de8de86 *src/core/core/dqueue.c 0dc161f6dacfdcfcdbd1fbb9a98966d7 *src/core/core/dqueue.pmt b4aaaf02566b4218038db128ded6e484 *src/core/core/error.c 5ae5cde80da3efe6fa00c9eb29413208 *src/core/core/estack.c 2b40b41bde02fbe961a0860803f0f4bb *src/core/core/estack.h a9cd0fc35a7a7af895a4bc330307d9cf *src/core/core/exceptions.h 6c5dc4585947111cf52e16994bfb9c56 *src/core/core/fixed_vectorlist.c 4af3ad722990a92b733e5df50984cc66 *src/core/core/fixed_vectorlist.h 65339f6b02e506a41c19f26ff7cf53f7 *src/core/core/grid.c 73858f5273e965621b2c95efbb65662b *src/core/core/grid.h 7ee1262183b727df1c76b99d007316f8 *src/core/core/heap.c 59b65257dcb09bbb719060f573e16e64 *src/core/core/heap.pmt 9354f29dbfba8036f3f97c77d119ed31 *src/core/core/indheap.c a5b1c1edaef4d3f8ba1ece24b5c7efbf *src/core/core/indheap.h ec28405731d3c11fd6ea0efda9fdbf70 *src/core/core/interruption.c 96ced82d18fe588b8ca3c6f7e5b15ee3 *src/core/core/interruption.h 46673546d2eeae7dd22013a0ab177cc5 *src/core/core/marked_queue.c d4f71b8901283e2d78384e250ddcee5c *src/core/core/marked_queue.h 4e18206de437adc2f9b50070f562308e *src/core/core/math.h 3a943d446c6935a023f36333daccbffe *src/core/core/matrix.c 46b35746fdee80935eaa6f9f5ff3343e *src/core/core/matrix.pmt 6c289f64140d894d3b2589bf4ef64837 *src/core/core/memory.c b139874245f26cc58fc0b5b9410b6e8b *src/core/core/printing.c 455b9430e62392d06338a08beebcb2a5 *src/core/core/progress.c cbe67ff873ad69d8cb8b1ba4866fdc19 *src/core/core/psumtree.c 66d63eb1a4d8f2e2f7d9440ac32a3b31 *src/core/core/set.c e7481526de5cf8f7ad153bf9f1697ffb *src/core/core/set.h 5556da33527c62e96d8c4e292c1b0e4a *src/core/core/sparsemat.c e0faa5f324b0e00e6e50f774a3417ecc *src/core/core/spmatrix.c 43589b026325b9eff1bc928a17cf2fc1 *src/core/core/stack.c e5dfd6930ec2705c6577bf0b28a78dba *src/core/core/stack.pmt a2125a6be1cec0077f455481a4671c99 *src/core/core/statusbar.c 5199b5793fe83a63be2cbeb2b4f4cc83 *src/core/core/strvector.c 124d797af3fc0693f74e344aace73ca7 *src/core/core/trie.c 13aba8ee2e168ddb58da6576215bb37c *src/core/core/trie.h f7a6f44feb3227c572b7160d5ef25a51 *src/core/core/vector.c b6a7f8231ccf807f4ff9ea73de7fa77f *src/core/core/vector.pmt 29855637821c37e5bbbbfb7ffd970c4d *src/core/core/vector_ptr.c 632d76fc35e6568fbd6b3428d4c5029e *src/core/f2c.h e5bf0689b4f47bf0137d82df1adf4b34 *src/core/flow/flow.c de53d2859aa04c95236f72ad128fcafd *src/core/flow/flow_internal.h 88a40c0a49572a641118ef30c07c4ec9 *src/core/flow/st-cuts.c fee6274a62bf36689354683683a62211 *src/core/games/barabasi.c 32258a750229beb0b9c0f628dfe87b5c *src/core/games/callaway_traits.c 02ff2c8943313637c05bec873449464f *src/core/games/citations.c f91933e3b9a133f96bbdb2f69ffbc429 *src/core/games/correlated.c 56fb35fa05788cd74f019f2115173b72 *src/core/games/degree_sequence.c 8835b22b95b668dae1ce7ca674192d9b *src/core/games/degree_sequence_vl/gengraph_box_list.cpp 5733ff53fc37ff61fef4d9f9400a114b *src/core/games/degree_sequence_vl/gengraph_box_list.h a4813b9ed2a626b583fc17bd556d86de *src/core/games/degree_sequence_vl/gengraph_definitions.h 6ffbdc76f28490c908c0dcc916780cc0 *src/core/games/degree_sequence_vl/gengraph_degree_sequence.cpp 34799fe31c6d26a7b9d9e74cdb8c13e0 *src/core/games/degree_sequence_vl/gengraph_degree_sequence.h 985f1dff969b6ec8ce92c3767d47e3f3 *src/core/games/degree_sequence_vl/gengraph_graph_molloy_hash.cpp 006188726cc11d1eb206a9d425a5b27b *src/core/games/degree_sequence_vl/gengraph_graph_molloy_hash.h 24eb30dd762e93e5730796ae14595d67 *src/core/games/degree_sequence_vl/gengraph_graph_molloy_optimized.cpp 237a3492442b4294120c39c2005ae149 *src/core/games/degree_sequence_vl/gengraph_graph_molloy_optimized.h c37e6bc5da5fa880efc4333bcdb5895a *src/core/games/degree_sequence_vl/gengraph_hash.h c234018f81195730534175836749e5bc *src/core/games/degree_sequence_vl/gengraph_header.h 039eecdf0f410d72221e063a48af0553 *src/core/games/degree_sequence_vl/gengraph_mr-connected.cpp 79981e890cf6aed322bb2bf2a5d2df09 *src/core/games/degree_sequence_vl/gengraph_powerlaw.cpp 771bd1a46a0759a308c0dee3991554bb *src/core/games/degree_sequence_vl/gengraph_powerlaw.h 83166a25b9c2f31f6890510b24ed8f4f *src/core/games/degree_sequence_vl/gengraph_qsort.h ca142e84158ab21737c321148f6b639a *src/core/games/degree_sequence_vl/gengraph_random.cpp 1dc1fd674cbbbca655f09ede6a6862ce *src/core/games/degree_sequence_vl/gengraph_random.h f36f13a28a6d343a61f078b6076a3cb6 *src/core/games/degree_sequence_vl/gengraph_vertex_cover.h 6fb53c30b5e5b8a2ef8017ebd4a6ccc1 *src/core/games/dotproduct.c 660ae1fc1daa558594810048c2f2080f *src/core/games/erdos_renyi.c 37842f5322a3468ca5685a749459edf6 *src/core/games/establishment.c 0a937b9f3465023d5d816df4bf0d4155 *src/core/games/forestfire.c 8f91faf602f730f3b9d62acb3ef9bd95 *src/core/games/grg.c 3a3d0fd4d9344bfde2379bd7eebaf79f *src/core/games/growing_random.c 0c0350e9891739b4576d9915f7281698 *src/core/games/islands.c cae38481031fe81cac7adb1aed0ff7a1 *src/core/games/k_regular.c f976ba0bdc95637bdd9f2bb4bde29a1e *src/core/games/preference.c e066fd9b813e03cceca3ecccd150e169 *src/core/games/recent_degree.c adceac5a56b7b55dbb5a2d1a99f1d8db *src/core/games/sbm.c e5979d45d83a2ad3994fb3c996fb2013 *src/core/games/static_fitness.c 7a047b4d5fedff5d423592ba33343bf8 *src/core/games/tree.c 7d99133ced5134f90a77735582130dfd *src/core/games/watts_strogatz.c ee7e73831b7228c41b6d211a04d94074 *src/core/graph/adjlist.c 2205093674d6b198958e32c215e143bb *src/core/graph/attributes.c 0bbadfdfc8ca9defaa80472da0e2b0fb *src/core/graph/attributes.h e57cd3392c479d30956821d27df20dc6 *src/core/graph/basic_query.c de62b8f7aa564f15eecda0adf907ae06 *src/core/graph/cattributes.c a60ab61bc1daf0904800fc2722c7edb0 *src/core/graph/iterators.c 0d285db7ac23cc4c025f4e612bcb3c64 *src/core/graph/neighbors.h e06adeaa8ed88f72262ef85845c50571 *src/core/graph/type_indexededgelist.c c3774d24fb5ad9b86067176033c01cd6 *src/core/graph/visitors.c f845795b8703449175caf7abcfb6fbf4 *src/core/hrg/dendro.h aafe772f14c5f58363e5772f66f8271a *src/core/hrg/graph.h 763b373e5d951112601b9276d02d5f5a *src/core/hrg/graph_simp.h 3c51d06775e909d8d04a1fd36875384e *src/core/hrg/hrg.cc d3fe4fc3f416976dc4257b0f8c05c319 *src/core/hrg/hrg_types.cc 2f675735d46e86e469b04a3f92d683d5 *src/core/hrg/rbtree.h 35fafbee80408a440d59ddf32e6311aa *src/core/hrg/splittree_eq.h a3ab7ff044ab8174db706c95fe590448 *src/core/internal/glpk_support.c aa00a606ed39a36e528f18aa868de1f5 *src/core/internal/glpk_support.h aeda4437c23b006bf19f9fbf3251b75e *src/core/internal/gmp_internal.h 04e415d657e24e4fc7d9e4b71bcc2b63 *src/core/internal/hacks.c 6bca5b70665639078d7c7ee1f3addae4 *src/core/internal/hacks.h 54a787ab747cfd0a977cb625ab327ce0 *src/core/internal/lsap.c 9f32084aa44b4e6520b66f1a2d80c69c *src/core/internal/pstdint.h 5c27095f6b81434474ea32673c204ad2 *src/core/internal/qsort.c f9a82bcf4a3a750ab39528bc8d304053 *src/core/internal/qsort_r.c 551237b8be92ac50c0d6555bfa1a7060 *src/core/internal/zeroin.c 47200242857709627a006760a764bc72 *src/core/io/dimacs.c 169b2d24426ea62d78a4bc0f14173803 *src/core/io/dl-header.h 7109cc374eaa20ece28c93dc4d1f02f4 *src/core/io/dl-lexer.c 233523a2ec7655c36849f7f0342ecae6 *src/core/io/dl-lexer.h 84a3288350b75d5810873804660c820e *src/core/io/dl-lexer.l fcf0a19ddc6a5ce3fb777b034995c8f2 *src/core/io/dl-parser.c afb7f932cad3141b34af72ab5a905411 *src/core/io/dl-parser.h 81485655e700dae756881f249b6f3a31 *src/core/io/dl-parser.y 59e8d0c5f44088f248c62e14d3bc6836 *src/core/io/dl.c 2df98ae92a9ab5997f8616c719479562 *src/core/io/dot.c fba5b8195b42e7ce2699b0cebe9f9051 *src/core/io/edgelist.c 9c4547daaf3cc9bd1a4c759d66717dce *src/core/io/gml-header.h 06b2565183b4b14a46ebb5fd73cbbc5f *src/core/io/gml-lexer.c 9a1e18c32431d559696c49f79e00ff1e *src/core/io/gml-lexer.h ff08e16cb1c4a43a081084103d8b9b23 *src/core/io/gml-lexer.l 50471698d6a6b811c3c4d217b4868857 *src/core/io/gml-parser.c 24acd949f805cb45b98528f87abe6d4f *src/core/io/gml-parser.h b05cbd9007f03bd9b86f817a360e7f0d *src/core/io/gml-parser.y 5c5439c865efa9b5e4d7de2be588086b *src/core/io/gml-tree.c d86659e2e870bdb76e3f2b98f678f7e4 *src/core/io/gml-tree.h 48fd7fbcccf23dc804d4b94b00281fbd *src/core/io/gml.c bbcf30e02179f5faebe318e44ae043d3 *src/core/io/gml.c.orig 7cd111a545c8b6aa174258003b037f3a *src/core/io/graphdb.c 10b6d7ba29719d9ab5bb6f50e2e3cc2d *src/core/io/graphml.c 6240269676d0e1cb43c8d091c6a3b431 *src/core/io/leda.c 71d8b8e91ad99daddd6e6b4fded3d3ce *src/core/io/lgl-header.h 59e1d003c39ff4c2145d8d0c6ad8ad5d *src/core/io/lgl-lexer.c 0911df62438a5b009d61f823c8522456 *src/core/io/lgl-lexer.h f593d30c405290ccce99038e79e9e693 *src/core/io/lgl-lexer.l 791b2d8d4b8b389511f597bfdc1988a3 *src/core/io/lgl-parser.c 2bc5dccc9c49bf5fbcf650a37af5bca9 *src/core/io/lgl-parser.h 9755eb96a479313a9c4f2ac9e29aab0a *src/core/io/lgl-parser.y 4238794be414d656a5725028953009a9 *src/core/io/lgl.c 125ceb8e1a45e32444f847207e47611d *src/core/io/ncol-header.h 17d183351af057801459a798d45a5b51 *src/core/io/ncol-lexer.c e1f83c796b078914d62aa052d753980f *src/core/io/ncol-lexer.h 567f25771aeb0f843a6fdf4d2600a68f *src/core/io/ncol-lexer.l 2ae4193d88fe64bc90c9c67eccbc29f4 *src/core/io/ncol-parser.c f9e5f9453b758c9f31ad8b8316b986b1 *src/core/io/ncol-parser.h f31f8e0dd0d3bc66c24cf8b206068e31 *src/core/io/ncol-parser.y 96d0299a08a0bd29aa6814601b2c5ba8 *src/core/io/ncol.c 5d60fac154f2e98392aee6f0f5a0cf7b *src/core/io/pajek-header.h f162fc16d98845b663628068d138795e *src/core/io/pajek-lexer.c fc52962ccbf057c09156e4262cf5dd7b *src/core/io/pajek-lexer.h 9bb2a3c81bae3ee0c10e2c763eb3f8d6 *src/core/io/pajek-lexer.l 53b86a7431feab101d10e1710065f63e *src/core/io/pajek-parser.c 47a7167ae6dec45a65298b4148c121d7 *src/core/io/pajek-parser.h 56c6f557f424b4fc7aea464cc0610e4e *src/core/io/pajek-parser.y 948df032c2f14ae73d9ea1c04a3a3ce5 *src/core/io/pajek.c f6958ba726921584a876c67563ff9368 *src/core/isomorphism/bliss.cc 4f1c74b4e9a48621b6506cd87abc9499 *src/core/isomorphism/bliss/bignum.hh 6fa7b8de9e402f1b11645f2bf92913ee *src/core/isomorphism/bliss/defs.cc 598fa15a531cead834e6a5eefa0cb412 *src/core/isomorphism/bliss/defs.hh 8cfe32f78fc059af26557a683685568b *src/core/isomorphism/bliss/graph.cc 28c76dbb10c37633d0121d1b69ca1f6d *src/core/isomorphism/bliss/graph.hh 7bb9a7fc051087172881bd0fdf85cde0 *src/core/isomorphism/bliss/heap.cc c6e1fa7e6689e0ed5b058a3254eb2ac5 *src/core/isomorphism/bliss/heap.hh 7146f1ffcd502ba8b5a652f33c748b8f *src/core/isomorphism/bliss/igraph-changes.md 054e461349ff54ba810b4c329dfb44b5 *src/core/isomorphism/bliss/kqueue.hh d3d33dad1f60f32493593a434548c91b *src/core/isomorphism/bliss/kstack.hh ca7955c5dfaf3cb7b3f09a01897f4584 *src/core/isomorphism/bliss/orbit.cc cd832e66f841a86c27764959dddd9d49 *src/core/isomorphism/bliss/orbit.hh 329c4be8ad951bbfbb64267067db4371 *src/core/isomorphism/bliss/partition.cc c28f03f11931346f1162b1e47c92f8bb *src/core/isomorphism/bliss/partition.hh 05c219cbb0bebac2c8cac129a32c8eeb *src/core/isomorphism/bliss/stats.hh e3b87f650f7372df36aea1bc424241b2 *src/core/isomorphism/bliss/uintseqhash.cc 2894aa7f3c118f8b55192e6ef809ac4b *src/core/isomorphism/bliss/uintseqhash.hh d9f154cc326105844a90dced77e03d9a *src/core/isomorphism/bliss/utils.cc 5d7adc00c62ae75163ef4b4fc394488b *src/core/isomorphism/bliss/utils.hh 01decfc494d34fda4495497916b6beae *src/core/isomorphism/isoclasses.c e91bb14bf8d1f312602cc841eb212b5b *src/core/isomorphism/isoclasses.h f46daf3ec120c4c84a984fa8dcb70ce2 *src/core/isomorphism/isomorphism_misc.c 5153843e7b6d3ffa7fde14c0451a08dc *src/core/isomorphism/lad.c 33b14a143445d22c5c784567dd3fcde3 *src/core/isomorphism/queries.c 1eed9416425b1fd96c2358e2f152f292 *src/core/isomorphism/vf2.c bea727310bd0e5ad9e34a4ac344ab04a *src/core/layout/circular.c c16853bba3637e1973c3d7e553e1e5c6 *src/core/layout/davidson_harel.c e9cfa4b9faf3729436e376d7b932b273 *src/core/layout/drl/DensityGrid.cpp a21a4218c8f41a2d09500cc18c4d74c8 *src/core/layout/drl/DensityGrid.h 059c7380e9c4066947f264e449ce02c3 *src/core/layout/drl/DensityGrid_3d.cpp 91e7b0fb8d38fa9083bd18f178fee1d0 *src/core/layout/drl/DensityGrid_3d.h 7c8571b936fb96a891f15af3995fbed7 *src/core/layout/drl/drl_Node.h a722468ac06354d8d69506562b2fccdc *src/core/layout/drl/drl_Node_3d.h 548499d086060e0ffbd7010d12c1791e *src/core/layout/drl/drl_graph.cpp 4e1bfaaaeb816211b79a903257a33863 *src/core/layout/drl/drl_graph.h 08f40730dafd687a5619c97bbfaf867c *src/core/layout/drl/drl_graph_3d.cpp 60381e739df03d470c0b406bdc8ef300 *src/core/layout/drl/drl_graph_3d.h 3a4ac9e14798d36f2e37270d735cdb9a *src/core/layout/drl/drl_layout.cpp 731439023b9112ef998b4f0532ba8bbd *src/core/layout/drl/drl_layout.h c3034e5131c185eb281a32f3253b32e8 *src/core/layout/drl/drl_layout_3d.cpp bccdf8aed148550fdf64d40ad30f6621 *src/core/layout/drl/drl_layout_3d.h 23c1caa2a8b841db6f4315ee273cddb8 *src/core/layout/drl/drl_parse.cpp 759aaaa9b7e2af02695f0fc4f9b3c441 *src/core/layout/drl/drl_parse.h 96113a01e55d1014e217e2ebaa10e45c *src/core/layout/fruchterman_reingold.c d83fd1ea7cdabfd75fb46317ef3d30a6 *src/core/layout/gem.c 24adb77787ee3574198b636d18b4668e *src/core/layout/graphopt.c 5516bed24cbba00b80c1bfe0bfba9256 *src/core/layout/kamada_kawai.c f84454a2955b23244733c912580cdf37 *src/core/layout/large_graph.c e0eaef7f15899b0f514c2e8365af0f28 *src/core/layout/layout_bipartite.c d49887836b08d1bf6e03462460b813d4 *src/core/layout/layout_grid.c f220f58db61cf6617317cb862c0b5775 *src/core/layout/layout_internal.h 6a6c93be5b667d26cc9444f12fdbaa08 *src/core/layout/layout_random.c d2a4a3377666a2e714fd5cd5d1bdc82f *src/core/layout/mds.c 208f5bf2e8857704156ad4d611874d4c *src/core/layout/merge_dla.c a346d978ce52304972f5f47264c34145 *src/core/layout/merge_grid.c 86f9adeff7c5005f575b4741ece85991 *src/core/layout/merge_grid.h 2b0d9aab64dc6c46e6c49bd166bbf4d3 *src/core/layout/reingold_tilford.c b107bbc6d4e0d514a06e41dec459b43a *src/core/layout/sugiyama.c 64c04665f162c915b33e95798c767c83 *src/core/linalg/arpack.c b2b1ef73333f48a0960dd6702fb4698f *src/core/linalg/arpack_internal.h 7bd4c469304fa7851216ab753675c239 *src/core/linalg/blas.c 2c7a2491d55923405084e28f0cdba6b4 *src/core/linalg/blas_internal.h f5fe3174eb8683dda674c9472a172de1 *src/core/linalg/eigen.c 7e80a0a8b7f167e2e6d426d808c72aa0 *src/core/linalg/lapack.c 3d15abdf5b4fe4cdd3cabaddba83c03b *src/core/linalg/lapack_internal.h 155b2ed40ce0798eab6a45ff9286dbc4 *src/core/math/bfgs.c c251877a22881e4944af2aab51b2b802 *src/core/math/complex.c c7b28f4c41be548685ca6cca5fd95c20 *src/core/math/utils.c 98ac0df9ee698a99a151c6f7368250a7 *src/core/misc/bipartite.c 8755aa39a47d48f4e79e4a0d82b38989 *src/core/misc/chordality.c 8d90db90b914fec384dab16d8e18c780 *src/core/misc/cocitation.c 93eb61b197a19d3008d40731f1789196 *src/core/misc/coloring.c d3dad056b1ce1730396e9ea9f2412029 *src/core/misc/conversion.c 9f1d89ff095b8e9958d0f64faeb3aa23 *src/core/misc/conversion_internal.h 76487f1f51173e3e2062de027ba99e0e *src/core/misc/degree_sequence.cpp ea3115f3abe564834ef6eb609c626ab7 *src/core/misc/embedding.c c5a00b1feed45870575606070f64dcc0 *src/core/misc/feedback_arc_set.c 00466b6e5e003ca1ed2b1a3fafdc07fc *src/core/misc/feedback_arc_set.h 07e92fbdc55fd5781a64c4dbd0a04384 *src/core/misc/graphicality.c 93f223c5cbaa76eb356b439fe81bf41d *src/core/misc/matching.c 6c432bd714410e08445d702649f7b52d *src/core/misc/microscopic_update.c ff6a1bb5216621ffed8358f9657c7b78 *src/core/misc/mixing.c c09b57f7b49857bd52b210b0e29d3736 *src/core/misc/motifs.c 0a6a2364776be90781b8e839897b38a5 *src/core/misc/other.c 124bd7946bf6f5b65bf5812eb0c40c53 *src/core/misc/scan.c e150d697465b658db6d043caa2963f18 *src/core/misc/sir.c d023fac1d6957e85eb865ad4b7be225e *src/core/misc/spanning_trees.c 844dd0617dbf7c2a9f3c8c92f9ce3239 *src/core/operators/add_edge.c c77e708d0597e110b13fd413e23c31a3 *src/core/operators/complementer.c 2703a960dc1cef033e19bb472ee7116e *src/core/operators/compose.c 895a24becc77e77ed354842e5fc559e3 *src/core/operators/connect_neighborhood.c 1b9f22bb12190b6ba8b9972a9d76266d *src/core/operators/contract.c 3512022d539eec4c7112eb192fe622b9 *src/core/operators/difference.c a6f2fd2fdec263434c2a7ab362978121 *src/core/operators/disjoint_union.c 45ba953ba0b82099a567473ef02328bc *src/core/operators/intersection.c cdcefa2ed49065ff23744c56eae09a84 *src/core/operators/misc_internal.c 986a7601cca1a5dd1a2980bb723d0de0 *src/core/operators/misc_internal.h 70cd77547e77ad29fa96d653231e9896 *src/core/operators/permute.c 2f0d3097cd2e4eab0cc7bc892f75e6d9 *src/core/operators/rewire.c c24b52d2cfd8ff5067139cde87293c28 *src/core/operators/rewire_edges.c 331d4bf3f2c366c9e66d024f7f1023c8 *src/core/operators/rewire_internal.h 33ec27ff8feed53f65ba6e8f577bd130 *src/core/operators/simplify.c ab48eb6d4b88c2e085224a4ca6b38d6e *src/core/operators/subgraph.c e97d13d0e5e43f6055dfbf0fd670bf39 *src/core/operators/subgraph.h cf6d7eabd74ae81148d93ee7b74e573a *src/core/operators/union.c 9af2fdb21086ec68005ab05ab57cbfec *src/core/paths/all_shortest_paths.c 1f3d47681b8d0aacde9e35d51bcb65b1 *src/core/paths/bellman_ford.c 9553bc7fdb6a76e105ac3f312e2899ed *src/core/paths/dijkstra.c 130cf56d22a55a5f1879bd4581964f84 *src/core/paths/distances.c 8252621cdce74c45d1c0042f8a575dcb *src/core/paths/eulerian.c 62ac2953037eed2b21f03ea3bbbb19d1 *src/core/paths/histogram.c 4da96c249884c625460eaf2d9ef4e3dd *src/core/paths/johnson.c 3c30421134bf438dd6073041891d625c *src/core/paths/random_walk.c 9e596484ab51b6d5e6738d515c0f7a44 *src/core/paths/shortest_paths.c d3b97f805130b1d55a6b448959d82afd *src/core/paths/simple_paths.c a00d3796c2cdf6a044a8bb07f710b8cd *src/core/paths/unweighted.c bc55b7ea7102bb7e5cad323d843858b5 *src/core/properties/basic_properties.c 2d9fc1935c251b3347992d3629788018 *src/core/properties/constraint.c 613e7aff7125ad5049eb318f029e672f *src/core/properties/convergence_degree.c d9e28aa456bf309436a4928f130c2a7a *src/core/properties/dag.c 05d3d8696c69edda7987c965c9426c6c *src/core/properties/degrees.c c20330bfb2acad0314b7cbee96dcddc7 *src/core/properties/girth.c e9373750e61ef0a053ecaa1acca20ab5 *src/core/properties/loops.c 7e413739c5b25ed01f1a4dcf09f503de *src/core/properties/multiplicity.c ad5c3bc612fc40cc95dd435336005c34 *src/core/properties/neighborhood.c c02adbdf78063e48ae7865dd15a7cd94 *src/core/properties/properties_internal.h d3181e6f017768ccd14dcb70c4a0f09c *src/core/properties/spectral.c 5f66a36ab2f99786229e6552b1333fde *src/core/properties/trees.c b23cef2884711e6d6b1f73601b98a053 *src/core/properties/triangles.c fde6e4b9c434db22ce3826ad2745a78c *src/core/properties/triangles_template.h d7f1a6770504ccb117a38a2a55625ead *src/core/properties/triangles_template1.h a7dea1a04eaf0ffcf14d1e7833f55719 *src/core/random/random.c bb529812532b2f293520a44d1f511b9b *src/core/scg/scg.c 1b2eee22fb5e0631264c66fa3a8a8283 *src/core/scg/scg_approximate_methods.c dedc1190143dc284b2ef450cdd8f8d08 *src/core/scg/scg_exact_scg.c 27ce1c3a4447a33f43cf6aab43337c4c *src/core/scg/scg_headers.h 5dfae46cb37d2ad004ed3c0496cb9df3 *src/core/scg/scg_kmeans.c fbd7f88db5310f4ea3360e5ed3cd5c0e *src/core/scg/scg_optimal_method.c 5d20880cdd8047b3a134d879ce93e338 *src/core/scg/scg_utils.c 1449a40ca4c724cd2a59db2d12fbdb51 *src/core/version.c 3cec04064dc04a4dfcbe182b98f83488 *src/doc/issue_report_install.md 85b76133af58d9e0d88a4cfb9d5191f8 *src/doc/issue_report_run.md 8f106920b8a2f3f81e16eb824687c40d *src/dummy.cpp 632d76fc35e6568fbd6b3428d4c5029e *src/f2c.h 4e9c070f26286c6037ad240b1cc64f51 *src/include/igraph.h 5149616c5368978897db8d88896e7d3f *src/include/igraph_adjlist.h 0fd6e9b4409387c66c02c9f462ccf170 *src/include/igraph_arpack.h 218f91f71f30cc20106fb755dbc8897e *src/include/igraph_array.h 710b39cc4a150017822c75df7f38263c *src/include/igraph_array_pmt.h 487bffd319336e1b74fbf4b27b68d6ac *src/include/igraph_attributes.h 63b04afa732d442e98b00344e1dc0917 *src/include/igraph_bipartite.h c38c1446a811189e86f9a6a616ae0af5 *src/include/igraph_blas.h 7ec5e72f8f6964f7e8891fbccdc7409e *src/include/igraph_centrality.h 2775242bc1bed86922742d6b9f847d50 *src/include/igraph_cliques.h e523c45acadf6e60d23989293554c6b1 *src/include/igraph_cocitation.h f441a08d30ea755632a4eb6bb7607170 *src/include/igraph_cohesive_blocks.h 59bfc8e5c8fc3743ab7d966fcacd052f *src/include/igraph_coloring.h d60577e5f81c475b277316f0968ef16e *src/include/igraph_community.h 10e5e446841e25a62d7fb7613fba92fb *src/include/igraph_complex.h 1ee1854a018ccc460685809903d2e7b1 *src/include/igraph_components.h 395c8fbf84fe6c78d963ee4daecd38cb *src/include/igraph_constants.h bb088099021a67d47dd00735884fc209 *src/include/igraph_constructors.h d2d323da89102263030328b859da3ac1 *src/include/igraph_conversion.h cf618987b8bc72dfa7b85ee93980c209 *src/include/igraph_datatype.h ad81c74ddfbb45b0615faf8851165704 *src/include/igraph_decls.h 4218caee1e94ea5615b8d74973ac3cf5 *src/include/igraph_dqueue.h b189a47816e9d594726bcd4ca19e828d *src/include/igraph_dqueue_pmt.h 6b3eb590a02057fc822ae782564b070d *src/include/igraph_eigen.h 2659cbfd8183ed5ba4026811ad4d4684 *src/include/igraph_embedding.h 46be64a3f22dba9e081753a3ce91377c *src/include/igraph_epidemics.h 5c1a000fcc1501c2d3c308c175690828 *src/include/igraph_error.h de078dbc5412e48fffa6724ff7b52e50 *src/include/igraph_eulerian.h 19dddb2e64e1f706709b302197136f5a *src/include/igraph_export.h afcf05b9643c576e76d97d5987e1b910 *src/include/igraph_flow.h d6bbaab1acd0ac966c25e19b31617a8c *src/include/igraph_foreign.h 61da18e3a24ee70f42c2a31991916765 *src/include/igraph_games.h 9f2599ded6709a3f14a2cb82b0ffb5ab *src/include/igraph_graphicality.h e475e1ef7207f8ddd6a70c6418281d4e *src/include/igraph_graphlets.h 12db1019511694f3c2a16f4fd79bce2c *src/include/igraph_heap.h 80c422c1b84fd894d004777fcd5e3ae3 *src/include/igraph_heap_pmt.h 1b0193bb2080b2bd26e14714482cef5d *src/include/igraph_hrg.h b70eeee3bcd2f242b235b1387358c625 *src/include/igraph_interface.h cf62a9edceaf90202bc69685e74bc077 *src/include/igraph_interrupt.h a480c95de0c8dd7b661caf54483247a3 *src/include/igraph_iterators.h f6ea72c48f49fa213f9454140db6e76a *src/include/igraph_lapack.h a32d6a1ad8aeceb85cdcc1c201a0fa9f *src/include/igraph_layout.h 1d99a1876c05983d7a37991038728afe *src/include/igraph_lsap.h dfdfcdaf7674883b6efb86caa26171be *src/include/igraph_matching.h 77eaee2ada883f2ce1aa5039823e8e39 *src/include/igraph_matrix.h 1259e4a1e913de25802617919345b024 *src/include/igraph_matrix_pmt.h 258db9c1e52149219bb560c0050a6c29 *src/include/igraph_memory.h 5f6452b1280b81ca228cb39580201ed5 *src/include/igraph_microscopic_update.h ad52e3ec4308f7bbec7c4fa0712d1c26 *src/include/igraph_mixing.h f4967ab8695bba61dd27121efe9f9a02 *src/include/igraph_motifs.h 98d812bf72fba363b755369e097cf221 *src/include/igraph_neighborhood.h 97543a7124b976e5e40f6167f786d9a3 *src/include/igraph_nongraph.h 19b78a273ff624c155227caf8cbd0bc5 *src/include/igraph_operators.h f02289433b79c8141094693cba234262 *src/include/igraph_paths.h 111bfd80ddd8895a8911f08bcb501f47 *src/include/igraph_pmt.h 9b708469a3b17250d200a433fd5e8cd1 *src/include/igraph_pmt_off.h c5376d1bc059414d3459d8bf60404b47 *src/include/igraph_progress.h 7ff1292f749f9b95b1f185712af608a7 *src/include/igraph_psumtree.h e7e405bbf255e77f971b64c59217aa9c *src/include/igraph_qsort.h 6a866ece4944ae8e0e8d5cb2ddfb5e97 *src/include/igraph_random.h e10b6bebdce4da293c17bfcac5782eff *src/include/igraph_scan.h 923c27cd523608466e26382767b90785 *src/include/igraph_scg.h e2d04247cc92107e7fc515bb46701699 *src/include/igraph_separators.h 107156dadec51b728b646b75c05d6e90 *src/include/igraph_sparsemat.h 2c1331234a73eee2e778469e01da9004 *src/include/igraph_spmatrix.h 7bb5ce4700e7859f97539f1552f56842 *src/include/igraph_stack.h f899657466f70a2852955b68872f258b *src/include/igraph_stack_pmt.h ce9395d569766f5d063076f2cc9799e3 *src/include/igraph_statusbar.h 4c7094f11f308d43fa8a02813cc87ee8 *src/include/igraph_structural.h e01a2455d1040a493f6c083d36bd9aa8 *src/include/igraph_strvector.h fe6f026ca2bd7374445be0afd63ea298 *src/include/igraph_threading.h af5d8b94a6fe143fda89af87681d9293 *src/include/igraph_threading.h.in be7de9e7f7b18652c57d80d615337574 *src/include/igraph_topology.h d25541974c416a50c5495de5c4eb15c9 *src/include/igraph_transitivity.h 2b92d7629037f64061d44494f1400153 *src/include/igraph_types.h 010a520de6ddc0f9a87437f682601fa1 *src/include/igraph_vector.h 28ff5e90db59b4b76d37b193b700f6d6 *src/include/igraph_vector_pmt.h e5e9b7d86a82521a9da3e2c81afc6456 *src/include/igraph_vector_ptr.h 5f99a89b4f9b60fdfc8b56232e06c0dc *src/include/igraph_vector_type.h fc85f88e706ec014c6c3012b335d7e21 *src/include/igraph_version.h fc85f88e706ec014c6c3012b335d7e21 *src/include/igraph_version.h.in b2782363c5cdbf31d263a6e9e1c83528 *src/include/igraph_visitor.h dc6c3db9ec85634d1d8d6f39567fbe6b *src/leidenalg/CPMVertexPartition.cpp 64ba8d1cb75c82ad80e7b5c60729d5a6 *src/leidenalg/CPMVertexPartition.h 2f941a1aac50a65ec265eb70e591f608 *src/leidenalg/GraphHelper.cpp 706035af477f6d7596c82280d920e891 *src/leidenalg/GraphHelper.h f04d8d29c9c30bf798d66fd9440be439 *src/leidenalg/LinearResolutionParameterVertexPartition.cpp 7842714c2969bb453fd9ede5ce385a1d *src/leidenalg/LinearResolutionParameterVertexPartition.h 9286df6bf614a56edd144b25f1a09f2e *src/leidenalg/ModularityVertexPartition.cpp 2b69da7418f9b8086bab6637decce63c *src/leidenalg/ModularityVertexPartition.h d830f12b0d2fa006c45c9bfa2e163254 *src/leidenalg/MutableVertexPartition.cpp 42bb53a508655dd8eb4e99f438e2165c *src/leidenalg/MutableVertexPartition.h 9bf046b1a8b6630ebd008e231784cd85 *src/leidenalg/Optimiser.cpp 110ce9c3d203e76220a905393a5b6254 *src/leidenalg/Optimiser.h ab98e2494da8e3077f4f22e09f973a5d *src/leidenalg/RBConfigurationVertexPartition.cpp 9266c14673b71c8025fff6af4544d91e *src/leidenalg/RBConfigurationVertexPartition.h 76eabc90d28e8da1146d94b5d2b9361f *src/leidenalg/RBERVertexPartition.cpp 44a54698a23a6792db1e44cd5c0af2cd *src/leidenalg/RBERVertexPartition.h a2fb9bc3b8d7504bb9303fcb0ad63c6d *src/leidenalg/ResolutionParameterVertexPartition.cpp 280eb0c4e019cfa22ea4478373d1b649 *src/leidenalg/ResolutionParameterVertexPartition.h 25b916bff2251fb4590202acd7f9d280 *src/leidenalg/SignificanceVertexPartition.cpp 3409ac29dea976bdb02810bc8624c615 *src/leidenalg/SignificanceVertexPartition.h 45f4f20231f6e0d7e1310412a9ce410c *src/leidenalg/SurpriseVertexPartition.cpp 5799d22c535af101a399f53c8fbb3d5e *src/leidenalg/SurpriseVertexPartition.h ac62b6952065567ca0c5b4521b014847 *src/leidenbase/leidenFindPartition.cpp bd4ac93aff3daedea076dd25efd74ff5 *src/leidenbase/leidenFindPartition.h 4fd7192434ad9341f6ea7ff7f38b4da6 *src/leidenbase/leidenFindPartitionR2C.cpp ae2b99c6930b9d78a067b9f304e4d021 *src/vendor/arpack/debug.h bc623b699b4c2d87ac2c4a0b82002276 *src/vendor/arpack/dgetv0.f ae7917a56c25a07b9860819bebf32f40 *src/vendor/arpack/dlaqrb.f 334cfcb89b71acd8bcf5e8398923f7f5 *src/vendor/arpack/dmout.f 0e11f9b76a7e46477224bebd83080f25 *src/vendor/arpack/dnaitr.f 7d4f11d47644fbbf52ed09e58e174dc4 *src/vendor/arpack/dnapps.f 22de713abf558787ed9c5b33eb4b83d4 *src/vendor/arpack/dnaup2.f 13ef3f91e6a93a0fb365d456cbd51d9d *src/vendor/arpack/dnaupd.f 8285764ecec3f0da1831503affd69067 *src/vendor/arpack/dnconv.f 7e7766bc466e28155a85211734e36426 *src/vendor/arpack/dneigh.f 00daa2578ee9f4ade26d3cab1b4076b8 *src/vendor/arpack/dneupd.f 238271976008654f1e512760f71943b4 *src/vendor/arpack/dngets.f ef22d5267a5f3e54a66b5c6fc97e8785 *src/vendor/arpack/dsaitr.f f226039f08b329d7a276b9c920c757b0 *src/vendor/arpack/dsapps.f 4ccdc4e43c8b3f590f7ed53783b30cee *src/vendor/arpack/dsaup2.f 221f58799c95c17f73a5043d9edb959f *src/vendor/arpack/dsaupd.f 573fb11e41307018f2fdb32ce3111be5 *src/vendor/arpack/dsconv.f f976b4529dead76e497c2f35fe067b00 *src/vendor/arpack/dseigt.f 0f7c847fa63252f466a7c312a9baa052 *src/vendor/arpack/dsesrt.f 6e2dd99b6e2450fa315e9132806eae90 *src/vendor/arpack/dseupd.f 604cef634a570edd5e9e1f0e57b85800 *src/vendor/arpack/dsgets.f d37e30b6becbd695f77bb83e86fc8845 *src/vendor/arpack/dsortc.f 8baf60e7aaca0c70f8ce165fa60f0eb4 *src/vendor/arpack/dsortr.f d4ead7e7ae03b16c06bc2eee64bc99fd *src/vendor/arpack/dstatn.f 40dc3cb9ded24c012fd5810e6175d7f9 *src/vendor/arpack/dstats.f de4792cfaab6cdda8d557902c2310fcc *src/vendor/arpack/dstqrb.f 10246dd04cc987d389f1f369f4b1813b *src/vendor/arpack/dvout.f e9e8f2dac33c5cc7bfe1da70a95cc05f *src/vendor/arpack/ivout.f ae9869d33e820c063b2de45a73f449c9 *src/vendor/arpack/second.f b5163c86a9a4ff980ad7a02f9303d2b7 *src/vendor/arpack/stat.h 7f4d2d68f1da7d835424e600ab462b4e *src/vendor/arpack/wrap.f f25fcb86725df43a5ab4ae434f1e7798 *src/vendor/cs/SuiteSparse_config.h c46f409d3c9042de2b2452ebea188f04 *src/vendor/cs/cs.h 38b5032cefcca9136aca0866d403c9dd *src/vendor/cs/cs_add.c 2c60e8c804449d788a2e29f64b33470c *src/vendor/cs/cs_amd.c 2986541b8915d584fbf9da61835af70b *src/vendor/cs/cs_chol.c 6e5f79bf2c8203281977bd4e28eedf62 *src/vendor/cs/cs_cholsol.c 93af3522ff50007cd668fb9d3c4c2551 *src/vendor/cs/cs_compress.c 13335f33a7da43ba6fdbaa081b7469c7 *src/vendor/cs/cs_counts.c 86565ee322504861dc3f202621a5733f *src/vendor/cs/cs_cumsum.c 8524302be8ab3302a5fa3e1955956b03 *src/vendor/cs/cs_dfs.c ba567511d54dfc335e31f8be2f00fdf0 *src/vendor/cs/cs_dmperm.c 9740988c93c2c59fa513b200bd4efaf9 *src/vendor/cs/cs_droptol.c 26cb6a937fc1dd071e7f9e4f2b140e7f *src/vendor/cs/cs_dropzeros.c d9bbcb69a1e03dc1e23e5a503237c121 *src/vendor/cs/cs_dupl.c b7f2b5a4cff294a59808f1eb02598339 *src/vendor/cs/cs_entry.c 3541d7394fb980f03678fe72482b3003 *src/vendor/cs/cs_ereach.c 63cc05d216ddd03134d54d28376e66b8 *src/vendor/cs/cs_etree.c 6173d7a2de1eb3f5477539e9d7dae64b *src/vendor/cs/cs_fkeep.c 0326b3a2fe19b360869b32778907ceed *src/vendor/cs/cs_gaxpy.c 6c1184a56fdcba521d29e87a30f29bae *src/vendor/cs/cs_happly.c abf50df78523dd20a218bf5b0cd7d1b5 *src/vendor/cs/cs_house.c c31a1cd620c12928d5d4957374b2735f *src/vendor/cs/cs_ipvec.c 263a00d35bb7386dccbb1d5f413f4bf8 *src/vendor/cs/cs_leaf.c 43d95c352e19937ed17b7a13acac3a84 *src/vendor/cs/cs_load.c 424c03520d5714aee9a9d681b6d53601 *src/vendor/cs/cs_lsolve.c b708c5988969f88017ea233d90a0134a *src/vendor/cs/cs_ltsolve.c 1adb4739b1b4a7eefc73d3ac4919cef0 *src/vendor/cs/cs_lu.c ba5d07fc08f1e70ddeb260977d4e3b25 *src/vendor/cs/cs_lusol.c c61696d4766c37b891bf2d10f375bf69 *src/vendor/cs/cs_malloc.c 78f39aac9c51b6062d59cc41bf9e17ef *src/vendor/cs/cs_maxtrans.c f4ca96d28bba4ab55be1ce8162fd29e5 *src/vendor/cs/cs_multiply.c 290cd630e2af44272a614d734798a292 *src/vendor/cs/cs_norm.c 4396acc0b9de17a40550e460f7b8bb79 *src/vendor/cs/cs_permute.c 709f86cb0b7fda2704b6312666a93697 *src/vendor/cs/cs_pinv.c 8f2f300ebaea112149be5cb5a68b22c4 *src/vendor/cs/cs_post.c f3a3d2c8e36b4ca0d204c26e2d037eea *src/vendor/cs/cs_print.c a0c55dbaa6d29713267d3e2506269a29 *src/vendor/cs/cs_pvec.c b54dac6518d878b744b4864b771c296d *src/vendor/cs/cs_qr.c 825c206684c11e0c77a50c370c433d96 *src/vendor/cs/cs_qrsol.c 0f19754c6852fccd018f2e459a4d553e *src/vendor/cs/cs_randperm.c a346dbce84219454037a753462c22151 *src/vendor/cs/cs_reach.c 31fa9bead8d17d520ab84d606b552e72 *src/vendor/cs/cs_scatter.c 8bca848261843e680890041c9bf080c9 *src/vendor/cs/cs_scc.c 7f595d67af0dc7b8d24af9eff726f35b *src/vendor/cs/cs_schol.c 3a10bebc54ce621de4e9e68df807990d *src/vendor/cs/cs_spsolve.c a91bd2d1178bf1b1ef0307aa71bf9170 *src/vendor/cs/cs_sqr.c fc58ccd98c36110b883a4e77e3d7ada7 *src/vendor/cs/cs_symperm.c 5449c532fe7894332a7b70630ca73b44 *src/vendor/cs/cs_tdfs.c ee1dd5aae3f15f280dccd2121f03f258 *src/vendor/cs/cs_transpose.c bc849b654aad6ef696c1a9f6b86c8c53 *src/vendor/cs/cs_updown.c b2ea4bc03b57554b35e0357bc2f3cae5 *src/vendor/cs/cs_usolve.c c2d0f948c12eb14fbe354aa2e66c180f *src/vendor/cs/cs_util.c dfbd25c90af085908603d05cb9ef0936 *src/vendor/cs/cs_utsolve.c 07f1a4a3bf53d73cd6ec53219c79343a *src/vendor/mini-gmp/mini-gmp.c 6f9dfcb5fe7f853a8507468c2721ba9f *src/vendor/mini-gmp/mini-gmp.h a6595cc90c64e0aab7a336856a219e53 *src/vendor/plfit/arithmetic_ansi.h 098651533f8c80ffeef3d3e43bf39783 *src/vendor/plfit/arithmetic_sse_double.h 896685565ace49c58c8587e52c9fdfcb *src/vendor/plfit/arithmetic_sse_float.h 5bca16a08ed3d981452457827d59714d *src/vendor/plfit/gss.c 3dcbb962532e6f702944e3028d4ea8b7 *src/vendor/plfit/gss.h 24154049f33c7f2b4815e5218dc7b376 *src/vendor/plfit/hzeta.c 9e54addfa4e5d62d0942c844284fc5c4 *src/vendor/plfit/hzeta.h 8e07e3dc944320924e8d59977c4b80a4 *src/vendor/plfit/kolmogorov.c b4afe617ab25aaa7629a19262a6246f5 *src/vendor/plfit/kolmogorov.h 38576b0913213b24986142a49346a233 *src/vendor/plfit/lbfgs.c f3601e97b1249e5888d73fd10e8126d9 *src/vendor/plfit/lbfgs.h 0974c0b3165a7c7269f8d751bc6dc069 *src/vendor/plfit/mt.c 0bf0d2d9ea0c2bc59037497ff22851ee *src/vendor/plfit/options.c 873a3eef6b073177bd158e97dd31e57a *src/vendor/plfit/platform.c eb7e4077697e8a31fe7dd2c350ce04a6 *src/vendor/plfit/platform.h 7d00d84022e136173b21f33dbf939b2a *src/vendor/plfit/plfit.c a60104e0ac1a48b9da677267e1b79cc2 *src/vendor/plfit/plfit.h c3ae08b7256ffe6cf667b7627c16f008 *src/vendor/plfit/plfit_error.c 547be33bd29e0aea6d0d7ab5c874a067 *src/vendor/plfit/plfit_error.h 3915cd50430dbafcabdb4d8e86fd6950 *src/vendor/plfit/plfit_mt.h 72a3908e8c54c54b2202dc4c5a877466 *src/vendor/plfit/plfit_sampling.h 7c6aa654430b1d2aa00a6529b55e9445 *src/vendor/plfit/plfit_version.h 8df5a0aabdc6185d8eb7c67a3d0c91d2 *src/vendor/plfit/rbinom.c 160de60ece4f24ffdd4ae6de90ac021d *src/vendor/plfit/sampling.c af447f07a45af2b4f7edaee5d0a877a7 *src/vendor/simpleraytracer/Color.cpp be39147aa9a658a401d5d8e304bfbb68 *src/vendor/simpleraytracer/Color.h 605d507fd74ae304c92e9a08d23443fa *src/vendor/simpleraytracer/Light.cpp a06dcdf977661620d9a30542d0708979 *src/vendor/simpleraytracer/Light.h b9106690e86aab37621da51d42ba6673 *src/vendor/simpleraytracer/Point.cpp a62fbead2d3a236d5303cc9085c8b2eb *src/vendor/simpleraytracer/Point.h e4e180e6869e932c1f4da706b9a02d64 *src/vendor/simpleraytracer/RIgraphRay.cpp a799c64d3087459d00e419f3fe8d6570 *src/vendor/simpleraytracer/Ray.cpp 2e3885be19867ed6a3562aeadf9e5271 *src/vendor/simpleraytracer/Ray.h 1feae5499e54a7b2015c14e67dbf25e7 *src/vendor/simpleraytracer/RayTracer.cpp 79ce54bb866d3c8341d6ca072b034bb3 *src/vendor/simpleraytracer/RayTracer.h c5e9fe64aa620a4c2578d84ce4eb3a69 *src/vendor/simpleraytracer/RayVector.cpp 61172ce5b49dfa8b864abcfb8808d5bc *src/vendor/simpleraytracer/RayVector.h bd7cf3fc7d493820b559dc1a65b6736a *src/vendor/simpleraytracer/Shape.cpp e8afe23482477c8dc53db328272ccd7e *src/vendor/simpleraytracer/Shape.h 1b626a1d4388dfea33527dd760e565f1 *src/vendor/simpleraytracer/Sphere.cpp a4e697cdced0ed1c4d1caf55e7dba557 *src/vendor/simpleraytracer/Sphere.h dc312c8337bad1b31afdf169f3e9e194 *src/vendor/simpleraytracer/Triangle.cpp c422300a2a528aa3da4ec98ed2dd1c8f *src/vendor/simpleraytracer/Triangle.h fc6fc5c9aa5a5187e6a2b1643f72ed4a *src/vendor/simpleraytracer/unit_limiter.cpp 10c5f89c9426685c966b72e159221f1a *src/vendor/simpleraytracer/unit_limiter.h cfb66084ea2bfc7648ab47ed1018e8a4 *src/vendor/uuid/COPYING c733862ac29e8bbd01a49b5ac7d4a780 *src/vendor/uuid/Makevars.in 81a759562546aeea16d466fece227601 *src/vendor/uuid/Makevars.win 3eb0f4eb28341a52ddd7790ad4c043ae *src/vendor/uuid/R.c 137be172372dd9bfeb50ed7aa2869b3e *src/vendor/uuid/clear.c d2b39a0b3d72632db235a9c6d36ef344 *src/vendor/uuid/compare.c 76087d772af7d37cab53b1a56cf72ade *src/vendor/uuid/config.h.in d0026e30bb2f3feb7ac1db9827dd4820 *src/vendor/uuid/copy.c f9ea1dca0e2aad3075fdf2b4ae6938ff *src/vendor/uuid/gen_uuid.c 7374a713629b202c4fb82d650e510acb *src/vendor/uuid/isnull.c b671656493c2119636a4e981e9aad857 *src/vendor/uuid/pack.c dcc91eb622c08bf2fca11680c71b92cc *src/vendor/uuid/parse.c bededb71c0c869f06c3275a79781ed17 *src/vendor/uuid/unpack.c 2bd888ee5f8a798961fb49a7531c8d5a *src/vendor/uuid/unparse.c 35a97c82d22737936a4ba8fb6924bcd4 *src/vendor/uuid/uuid.h 84c21b1a1c769a488f5ff52e91be798a *src/vendor/uuid/uuidP.h aad9fd83e8f3cc7eb80e2ab0b2c4f84c *src/vendor/uuid/uuidd.h 9e16418d043b96a6061ffb43150c5abd *src/vendor/uuid/win32/config.h e8ac46ae847800bdb978dced1394150e *tests/cpp_tests/Makefile 3d6c6c8858725fdc0f9bfa42909019f6 *tests/cpp_tests/NOTES 779ccf5ac758df5a6b7d5a6ec2af9e10 *tests/cpp_tests/edge_weights.txt 56c433f2667f21206e12bd0a0b6d1a53 *tests/cpp_tests/edgelist.edg b35a27dfa1191281354d640070748b21 *tests/cpp_tests/igraph_edgelist.txt.gz 2b75dd3411f97232cb9e9222affd3e69 *tests/cpp_tests/initial_memberships.txt f6caac600aedcfaa581a6e57b304882b *tests/cpp_tests/leiden.cpp a9c07288c0e5b760d216d72093a2db4e *tests/cpp_tests/leidenalg_refs.py a08a85e8546243a8ff7970798128f342 *tests/cpp_tests/leidenalg_test.py d309591e6da8bc3463679c64c6f2fba5 *tests/cpp_tests/node_sizes.txt e200b3950e5f1c24ee7719b3be2d091c *tests/cpp_tests/test_files/equals/test_set_1.txt eb29715ce4a20ad1efdc214e30cde154 *tests/cpp_tests/test_files/equals/test_set_2.txt f7bc3c34959965939bfd04572a28418e *tests/cpp_tests/test_files/equals/test_set_3.txt 7baa46e4addcfe2c9ab842b90cfe24e7 *tests/cpp_tests/test_files/equals/test_set_4.txt 90301d37dd240c7cf7fcada0931b13d0 *tests/cpp_tests/test_files/equals/test_set_5.txt 86cb0cf03b0e9ab593cf4367f154e647 *tests/cpp_tests/test_files/test_set_1.txt 8b9b96e7332e873b405415beeff4f49b *tests/cpp_tests/test_files/test_set_2.txt 6091db88a5b9802026d7cf59ce239d11 *tests/cpp_tests/test_files/test_set_3.txt 73f4a3eeb6578eab52246074e62b1f6f *tests/cpp_tests/test_files/test_set_4.txt 53b76f72f494210e0761d7bb8e3cb412 *tests/cpp_tests/test_files/test_set_5.txt 779ccf5ac758df5a6b7d5a6ec2af9e10 *tests/cpp_tests/tests_out/edge_weights.txt 56c433f2667f21206e12bd0a0b6d1a53 *tests/cpp_tests/tests_out/edgelist.edg 2b75dd3411f97232cb9e9222affd3e69 *tests/cpp_tests/tests_out/initial_memberships.txt 8d1633a13e6d2461f329344da28fa79e *tests/testthat.R dae1d5911d5f6c674ac8150b013e3c0a *tests/testthat/test-leidenbase.R a7a20c17b8bd529cf8d0093aed18b87d *vignettes/leidenbase.Rmd leidenbase/inst/0000755000176200001440000000000014532173045013326 5ustar liggesusersleidenbase/inst/doc/0000755000176200001440000000000014532173045014073 5ustar liggesusersleidenbase/inst/doc/leidenbase.Rmd0000644000176200001440000001460514444624115016641 0ustar liggesusers--- title: "leidenbase.Rmd" author: "Brent Ewing" date: "1/19/2022" output: html_vignette vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{leidenbase} %\VignetteEncoding{UTF-8} --- ```{r setup, echo=FALSE, results='hide', message=FALSE} require(knitr) opts_chunk$set(error=FALSE, message=FALSE, warning=FALSE) library(leidenbase) library(igraph) ``` ### Introduction Leidenbase consists of R and C++ interfaces for the basic community detection functions of Vincent Traags's Leidenalg package. The Leidenalg algorithm is described in the article Traag, V.A., Waltman. L., Van Eck, N.-J. (2018). *From Louvain to Leiden: guaranteeing well-connected communities.* Scientific reports, 9(1), 5233. [10.1038/s41598-019-41695-z](http://dx.doi.org/10.1038/s41598-019-41695-z) Detailed information describing use of the leiden algorithm is available at https://leidenalg.readthedocs.io/en/latest/ leidenalg source code is available at https://github.com/vtraag/leidenalg ### R Interface The R interface consists of the `leiden_find_partition` function ``` r leiden_find_partition( igraph, partition_type = c("CPMVertexPartition", "ModularityVertexPartition", "RBConfigurationVertexPartition", "RBERVertexPartition", "SignificanceVertexPartition", "SurpriseVertexPartition"), initial_membership = NULL, edge_weights = NULL, node_sizes = NULL, seed = NULL, resolution_parameter = 0.1, num_iter = 2, verbose = FALSE ) Arguments: igraph: R igraph graph. partition_type: String partition type name. Default is CPMVertexParition. initial_membership: Numeric vector of initial membership assignments of nodes. These are 1-based indices. Default is one community per node. edge_weights: Numeric vector of edge weights. Default is 1.0 for all edges. node_sizes: Numeric vector of node sizes. Default is 1 for all nodes. seed: Numeric random number generator seed. The seed value must be either NULL for random seed values or greater than 0 for a fixed seed value. Default is NULL. resolution_parameter: Numeric resolution parameter. The value must be greater than 0.0. Default is 0.1. The resolution_parameter is ignored for the partition_types ModularityVertexPartition, SignificanceVertexPartition, and SurpriseVertexPartition. num_iter: Numeric number of iterations. Default is 2. verbose: A logic flag to determine whether or not we should print run diagnostics. Value: A named list consisting of a numeric vector where each value is the community to which the node belongs (1-based indices), a numeric quality value, a numeric modularity, a numeric significance, a numeric vector of edge weights within each community, a numeric vector of edge weights from each community, a numeric vector of edge weights to each community, and total edge weight. ``` In order to use `leiden_find_partition`, create or load an igraph graph and then call `leiden_find_partition`. For example, ```{r} library(igraph) fpath <- system.file('testdata', 'igraph_n1500_edgelist.txt.gz', package='leidenbase') zfp <- gzfile(fpath) igraph <- read_graph(file = zfp, format='edgelist') res <- leiden_find_partition(igraph, partition_type = 'CPMVertexPartition', seed = 123456, resolution_parameter = 0.5) ``` `leiden_find_partition` returns ```{r} str(res) ``` The membership vector consists of the community value for each node. For example, ```{r} head(res[['membership']]) ``` The nodes that belong to community 1 are ```{r} which(res[['membership']]==1) ``` The first three communities are ```{r} # lim1 <- max(res$membership) lim1 <- 3 for( i in seq(lim1)) { cat(paste0('Community ', i, ':')) for(j in which(res[['membership']]==i)) cat(' ', j) cat('\n') } ``` ### C/C++ Interface The C/C++ interface consists of the `leidenFindPartition` function ``` c++ int leidenFindPartition( igraph_t *pigraph, std::string const partitionType, std::vector < size_t > const *pinitialMembership, std::vector < double > const *pedgeWeights, std::vector < size_t > const *pnodeSizes, size_t seed, double resolutionParameter, std::int32_t numIter, std::vector < size_t > *pmembership, std::vector < double > *pweightInCommunity, std::vector < double > *pweightFromCommunity, std::vector < double > *pweightToCommunity, double *pweightTotal, double *pquality, double *pmodularity, double *psignificance, int *pstatus ) Parameters: igraph: pointer to igraph_t graph partitionType partition type used for optimization initialMembership vector of initial membership assignments of nodes (NULL for default of one community per node) edgeWeights vector of weights of edges (NULL for default of 1.0) nodeSizes vector of node sizes (NULL for default of 1) seed random number generator seed (0=random seed) resolutionParameter resolution parameter numIter number of iterations pmembership vector of node membership assignments pweightInCommunity vector of edge weights within community pweightFromCommunity vector of edge weights from community pweightToCommunity vector of edge weights to community pweightTotal total edge weights pquality partition quality pmodularity partition modularity psignificance partition significance pstatus function status (0=success; -1=failure) ``` Notes for the C/C++ interface: * Edit leidenFindPartition.cpp to set the preprocessor definition `R_INTERFACE` to 0. * The resolution parameter is ignored for the partition types ModularityVertexPartition, SignificanceVertexPartition, and SurpriseVertexPartition * To use the `leidenFindPartition` function, compile and link to the files src/leidenFindPartition.(cpp|h), src/leidenalg/src/\*.cpp, and src/leidenalg/include/\*.h and a C igraph object library. leidenbase/inst/doc/leidenbase.html0000644000176200001440000007332714532173045017070 0ustar liggesusers leidenbase.Rmd

leidenbase.Rmd

Brent Ewing

1/19/2022

Introduction

Leidenbase consists of R and C++ interfaces for the basic community detection functions of Vincent Traags’s Leidenalg package. The Leidenalg algorithm is described in the article

Traag, V.A., Waltman. L., Van Eck, N.-J. (2018). From Louvain to Leiden: guaranteeing well-connected communities. Scientific reports, 9(1), 5233. 10.1038/s41598-019-41695-z

Detailed information describing use of the leiden algorithm is available at

https://leidenalg.readthedocs.io/en/latest/

leidenalg source code is available at

https://github.com/vtraag/leidenalg

R Interface

The R interface consists of the leiden_find_partition function

leiden_find_partition( igraph, partition_type = c("CPMVertexPartition", "ModularityVertexPartition", "RBConfigurationVertexPartition", "RBERVertexPartition", "SignificanceVertexPartition", "SurpriseVertexPartition"), initial_membership = NULL, edge_weights = NULL, node_sizes = NULL, seed = NULL, resolution_parameter = 0.1, num_iter = 2, verbose = FALSE )

Arguments:

  igraph: R igraph graph.

  partition_type: String partition type name. Default is CPMVertexParition.

  initial_membership: Numeric vector of initial membership assignments of nodes.
                      These are 1-based indices. Default is one community per
                      node.

  edge_weights: Numeric vector of edge weights. Default is 1.0 for all edges.

  node_sizes: Numeric vector of node sizes. Default is 1 for all nodes.

  seed: Numeric random number generator seed. The seed value must be
        either NULL for random seed values or greater than 0 for a
        fixed seed value. Default is NULL.

  resolution_parameter: Numeric resolution parameter. The value must be
                        greater than 0.0. Default is 0.1. The
                        resolution_parameter is ignored
                        for the partition_types ModularityVertexPartition,   
                        SignificanceVertexPartition, and
                        SurpriseVertexPartition.

  num_iter: Numeric number of iterations. Default is 2.

  verbose: A logic flag to determine whether or not we should print run
           diagnostics.
           
Value:
   A named list consisting of a numeric vector where each value is the community
   to which the node belongs (1-based indices), a numeric quality value, a
   numeric modularity, a numeric significance, a numeric vector of edge weights
   within each community, a numeric vector of edge weights from each community,
   a numeric vector of edge weights to each community, and total edge weight.

In order to use leiden_find_partition, create or load an igraph graph and then call leiden_find_partition. For example,

library(igraph)
fpath <- system.file('testdata', 'igraph_n1500_edgelist.txt.gz', package='leidenbase')
zfp <- gzfile(fpath)
igraph <- read_graph(file = zfp, format='edgelist')
res <- leiden_find_partition(igraph, partition_type = 'CPMVertexPartition', seed = 123456, resolution_parameter = 0.5)

leiden_find_partition returns

str(res)
## List of 8
##  $ membership                  : int [1:1500] 22 41 2 30 39 12 40 31 30 4 ...
##  $ quality                     : num 11835
##  $ modularity                  : num 0.426
##  $ significance                : num 87495
##  $ edge_weight_within_community: num [1:115] 1489 1284 1205 1147 893 ...
##  $ edge_weight_from_community  : num [1:115] 1786 2021 2069 1576 1742 ...
##  $ edge_weight_to_community    : num [1:115] 1786 2021 2069 1576 1742 ...
##  $ total_edge_weight           : num 61636

The membership vector consists of the community value for each node. For example,

head(res[['membership']])
## [1] 22 41  2 30 39 12

The nodes that belong to community 1 are

which(res[['membership']]==1)
##  [1]   33   35   41  116  140  151  172  178  208  214  238  308  367  440  454
## [16]  496  745  814  834  836  849  854  860  869  870  927  937 1042 1062 1104
## [31] 1111 1139 1238 1248 1263 1277 1297 1323 1348 1377 1382 1407 1483

The first three communities are

# lim1 <- max(res$membership)
lim1 <- 3
for( i in seq(lim1)) {
  cat(paste0('Community ', i, ':'))
  for(j in which(res[['membership']]==i))
    cat(' ', j)
  cat('\n')
}
## Community 1:  33  35  41  116  140  151  172  178  208  214  238  308  367  440  454  496  745  814  834  836  849  854  860  869  870  927  937  1042  1062  1104  1111  1139  1238  1248  1263  1277  1297  1323  1348  1377  1382  1407  1483
## Community 2:  3  94  96  112  127  154  195  232  248  283  297  363  385  451  455  464  517  565  671  797  802  839  971  976  1002  1037  1051  1106  1117  1120  1123  1195  1249  1257  1281  1283  1355  1395  1397  1479
## Community 3:  168  179  220  320  327  351  417  419  423  509  594  618  623  645  733  778  801  887  929  959  998  1011  1016  1088  1147  1155  1168  1201  1206  1258  1269  1290  1295  1312  1347  1389  1427  1432  1480

C/C++ Interface

The C/C++ interface consists of the leidenFindPartition function

int leidenFindPartition( igraph_t *pigraph,
                           std::string const partitionType,
                           std::vector < size_t > const *pinitialMembership,
                           std::vector < double > const *pedgeWeights,
                           std::vector < size_t > const *pnodeSizes,
                           size_t seed,
                           double resolutionParameter,
                           std::int32_t numIter,
                           std::vector < size_t > *pmembership,
                           std::vector < double > *pweightInCommunity,
                           std::vector < double > *pweightFromCommunity,
                           std::vector < double > *pweightToCommunity,
                           double *pweightTotal,
                           double *pquality,
                           double *pmodularity,
                           double *psignificance,
                           int *pstatus )

Parameters:

  igraph: pointer to igraph_t graph
  partitionType         partition type used for optimization
  initialMembership     vector of initial membership assignments of nodes (NULL
                        for default of one community per node)
  edgeWeights           vector of weights of edges (NULL for default of 1.0)
  nodeSizes             vector of node sizes (NULL for default of 1)
  seed                  random number generator seed (0=random seed)
  resolutionParameter   resolution parameter
  numIter               number of iterations
  pmembership           vector of node membership assignments
  pweightInCommunity    vector of edge weights within community
  pweightFromCommunity  vector of edge weights from community
  pweightToCommunity    vector of edge weights to community
  pweightTotal          total edge weights
  pquality              partition quality
  pmodularity           partition modularity
  psignificance         partition significance
  pstatus               function status (0=success; -1=failure)

Notes for the C/C++ interface:

  • Edit leidenFindPartition.cpp to set the preprocessor definition R_INTERFACE to 0.
  • The resolution parameter is ignored for the partition types ModularityVertexPartition, SignificanceVertexPartition, and SurpriseVertexPartition
  • To use the leidenFindPartition function, compile and link to the files src/leidenFindPartition.(cpp|h), src/leidenalg/src/*.cpp, and src/leidenalg/include/*.h and a C igraph object library.
leidenbase/inst/doc/leidenbase.R0000644000176200001440000000215414532173045016313 0ustar liggesusers## ----setup, echo=FALSE, results='hide', message=FALSE------------------------- require(knitr) opts_chunk$set(error=FALSE, message=FALSE, warning=FALSE) library(leidenbase) library(igraph) ## ----------------------------------------------------------------------------- library(igraph) fpath <- system.file('testdata', 'igraph_n1500_edgelist.txt.gz', package='leidenbase') zfp <- gzfile(fpath) igraph <- read_graph(file = zfp, format='edgelist') res <- leiden_find_partition(igraph, partition_type = 'CPMVertexPartition', seed = 123456, resolution_parameter = 0.5) ## ----------------------------------------------------------------------------- str(res) ## ----------------------------------------------------------------------------- head(res[['membership']]) ## ----------------------------------------------------------------------------- which(res[['membership']]==1) ## ----------------------------------------------------------------------------- # lim1 <- max(res$membership) lim1 <- 3 for( i in seq(lim1)) { cat(paste0('Community ', i, ':')) for(j in which(res[['membership']]==i)) cat(' ', j) cat('\n') } leidenbase/inst/testdata/0000755000176200001440000000000014444624070015140 5ustar liggesusersleidenbase/inst/testdata/test02_file01.txt0000644000176200001440000000573114444624070020170 0ustar liggesusers1 1 4 4 7 3 1 2 4 6 9 1 3 3 3 6 7 5 1 6 2 1 2 2 5 4 6 5 5 1 6 2 7 9 7 1 3 2 6 8 7 1 1 8 3 1 8 3 1 2 9 1 3 6 6 3 3 3 6 10 8 9 8 3 4 3 5 10 2 4 1 7 3 6 4 2 3 8 6 3 1 1 6 3 4 3 6 2 4 5 6 2 3 4 1 4 5 4 1 1 1 3 6 9 8 8 1 2 1 8 9 4 8 4 1 7 5 4 8 4 4 6 2 2 5 3 4 5 2 5 6 5 4 5 1 3 7 5 5 7 1 9 11 2 3 5 1 3 2 3 7 1 6 4 8 9 2 11 6 2 3 10 5 1 3 3 4 2 8 9 2 7 5 4 5 6 8 7 2 1 5 1 6 4 2 1 1 3 1 3 10 6 5 6 4 9 2 4 2 1 6 4 3 2 2 6 5 7 8 4 9 6 6 7 1 8 6 3 3 2 4 6 6 3 3 1 1 4 5 6 3 4 3 5 3 5 1 7 1 4 3 4 2 5 5 1 1 4 7 1 6 1 7 3 8 5 1 6 8 6 1 5 6 5 1 1 2 5 5 5 6 4 3 1 7 4 1 6 1 3 8 1 4 5 1 6 6 8 1 5 2 3 2 4 2 3 4 7 1 9 2 1 8 1 5 3 4 7 6 8 1 4 6 1 9 4 11 7 1 2 1 1 5 6 4 5 2 6 5 1 4 7 6 2 4 10 2 1 6 1 5 9 9 3 3 2 8 1 6 6 2 6 5 4 5 5 5 2 1 1 2 4 4 1 9 3 7 1 2 8 3 3 4 3 1 3 2 3 2 9 1 6 1 2 4 8 4 3 3 3 7 3 5 1 5 5 2 3 1 5 2 3 2 2 3 6 1 4 3 8 8 1 1 1 10 1 2 1 2 1 4 1 2 7 3 5 8 4 6 5 1 6 7 2 3 10 1 1 1 7 6 3 1 2 6 1 2 9 2 2 4 6 3 7 4 3 8 2 9 1 6 4 6 4 6 6 4 1 2 7 5 4 4 4 4 1 1 4 3 5 1 4 5 3 3 6 5 1 4 8 6 3 3 9 1 7 1 3 1 4 8 5 5 2 9 1 6 2 2 1 1 6 1 1 9 4 4 2 1 7 3 1 5 1 3 4 3 4 3 1 2 5 8 6 6 1 6 6 2 5 1 8 9 2 3 1 1 3 7 6 1 2 5 4 4 2 3 8 2 2 6 5 3 6 4 8 4 3 5 3 2 9 4 2 2 5 5 1 9 6 6 4 2 2 3 1 9 6 7 2 5 3 3 2 1 1 1 1 1 6 3 9 1 3 2 2 3 2 3 3 6 3 3 2 4 2 1 2 6 6 3 2 2 6 3 5 6 2 4 5 3 6 7 8 5 1 2 6 3 2 3 7 3 9 2 1 5 4 3 5 1 8 5 1 4 6 1 2 6 4 4 1 4 1 1 1 9 3 4 2 4 2 1 2 1 4 1 4 5 5 3 5 1 1 3 6 1 9 1 1 3 2 1 2 3 5 4 2 6 1 5 6 6 2 9 5 7 2 5 4 8 5 1 1 5 5 7 1 1 4 6 1 1 4 8 2 5 2 4 1 3 1 2 3 6 6 2 4 7 2 1 5 3 3 7 5 5 8 4 9 2 3 6 5 1 5 2 5 1 3 1 6 1 2 2 4 2 5 1 5 2 1 1 9 10 5 5 2 6 8 4 1 1 7 3 6 5 1 4 5 1 2 5 4 4 5 4 5 4 3 2 4 6 1 4 2 1 3 6 3 1 9 6 7 3 6 4 1 4 11 1 1 3 6 1 4 8 6 1 6 5 5 5 7 1 7 2 6 4 3 10 10 1 9 3 1 6 2 7 4 1 5 1 7 2 1 1 10 4 7 3 8 2 6 6 5 6 3 7 7 3 6 1 2 6 3 1 11 8 5 1 5 3 3 6 5 2 5 3 7 1 8 6 3 1 1 5 6 2 8 2 6 8 2 9 6 3 1 3 5 3 3 1 9 11 9 2 8 1 10 2 5 1 6 4 5 7 8 2 1 2 5 1 2 6 2 7 2 5 3 3 9 5 9 5 1 5 2 2 1 1 4 1 10 8 2 9 8 2 6 2 1 2 1 7 1 1 6 1 5 4 4 3 1 1 4 8 7 3 5 5 1 4 6 1 5 1 2 1 8 3 5 5 3 2 5 1 2 1 3 1 4 4 6 1 2 4 5 9 5 2 1 4 8 3 2 5 5 3 1 2 10 1 4 6 8 3 3 3 2 8 1 1 1 3 6 4 2 2 5 4 7 1 11 6 1 6 5 1 1 4 4 1 7 6 1 4 6 4 5 1 7 4 1 5 6 6 5 3 3 1 2 5 7 1 3 3 1 3 1 4 1 3 4 6 1 1 2 2 5 2 3 5 4 1 9 4 3 3 3 2 2 6 7 4 4 2 2 3 9 7 5 2 6 8 4 4 1 6 4 5 11 4 5 6 5 2 2 8 3 7 6 4 4 8 6 3 6 7 1 5 6 3 4 6 1 2 1 8 4 8 2 1 6 2 5 2 4 1 3 5 2 2 1 1 5 2 2 9 2 1 2 2 5 7 1 2 1 5 3 3 1 8 6 2 2 4 6 2 9 1 4 4 5 4 1 3 1 3 5 2 1 3 2 5 2 3 8 1 5 8 2 6 5 6 1 3 3 1 6 8 6 4 1 2 3 1 4 1 3 3 10 4 8 6 3 3 7 6 1 9 1 4 8 5 7 2 7 4 6 3 1 7 4 4 7 4 2 6 4 4 5 7 1 8 3 1 2 2 9 8 1 4 2 7 9 7 3 3 8 4 3 4 5 7 4 1 2 1 2 3 3 5 4 2 8 7 9 4 3 2 8 4 4 1 1 1 4 4 6 8 2 9 3 5 1 5 1 1 8 10 5 7 2 2 2 2 6 7 4 6 3 5 5 6 1 6 1 9 5 6 6 1 6 2 9 2 7 3 5 8 6 9 5 4 3 3 7 3 5 6 3 1 1 2 10 8 7 8 3 3 1 5 3 9 3 7 4 5 9 8 7 6 8 4 4 2 1 2 6 6 4 5 3 4 4 4 1 1 1 6 5 2 5 2 4 7 3 1 10 5 5 1 6 5 6 7 1 6 4 9 9 7 7 4 1 2 4 1 2 11 2 10 2 2 4 2 9 1 8 1 3 6 10 2 1 5 4 6 5 2 7 6 1 10 6 3 2 2 6 2 3 2 6 2 1 1 5 5 4 1 1 3 1 3 6 3 10 4 2 7 6 7 2 3 5 6 1 1 8 2 10 2 2 6 9 3 10 3 5 leidenbase/inst/testdata/test05_file01.txt0000644000176200001440000001436614444624070020177 0ustar liggesusers2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 1 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 leidenbase/inst/testdata/test06_file01.txt0000644000176200001440000000573114444624070020174 0ustar liggesusers1 1 4 4 7 3 1 2 4 6 9 1 3 3 3 6 7 5 1 6 2 1 2 2 5 4 6 5 5 1 6 2 7 9 7 1 3 2 6 8 7 1 1 8 3 1 8 3 1 2 9 1 3 6 6 3 3 3 6 10 8 9 8 3 4 3 5 10 2 4 1 7 3 6 4 2 3 8 6 3 1 1 6 3 4 3 6 2 4 5 6 2 3 4 1 4 5 4 1 1 1 3 6 9 8 8 1 2 1 8 9 4 8 4 1 7 5 4 8 4 4 6 2 2 5 3 4 5 2 5 6 5 4 5 1 3 7 5 5 7 1 9 11 2 3 5 1 3 2 3 7 1 6 4 8 9 2 11 6 2 3 10 5 1 3 3 4 2 8 9 2 7 5 4 5 6 8 7 2 1 5 1 6 4 2 1 1 3 1 3 10 6 5 6 4 9 2 4 2 1 6 4 3 2 2 6 5 7 8 4 9 6 6 7 1 8 6 3 3 2 4 6 6 3 3 1 1 4 5 6 3 4 3 5 3 5 1 7 1 4 3 4 2 5 5 1 1 4 7 1 6 1 7 3 8 5 1 6 8 6 1 5 6 5 1 1 2 5 5 5 6 4 3 1 7 4 1 6 1 3 8 1 4 5 1 6 6 8 1 5 2 3 2 4 2 3 4 7 1 9 2 1 8 1 5 3 4 7 6 8 1 4 6 1 9 4 11 7 1 2 1 1 5 6 4 5 2 6 5 1 4 7 6 2 4 10 2 1 6 1 5 9 9 3 3 2 8 1 6 6 2 6 5 4 5 5 5 2 1 1 2 4 4 1 9 3 7 1 2 8 3 3 4 3 1 3 2 3 2 9 1 6 1 2 4 8 4 3 3 3 7 3 5 1 5 5 2 3 1 5 2 3 2 2 3 6 1 4 3 8 8 1 1 1 10 1 2 1 2 1 4 1 2 7 3 5 8 4 6 5 1 6 7 2 3 10 1 1 1 7 6 3 1 2 6 1 2 9 2 2 4 6 3 7 4 3 8 2 9 1 6 4 6 4 6 6 4 1 2 7 5 4 4 4 4 1 1 4 3 5 1 4 5 3 3 6 5 1 4 8 6 3 3 9 1 7 1 3 1 4 8 5 5 2 9 1 6 2 2 1 1 6 1 1 9 4 4 2 1 7 3 1 5 1 3 4 3 4 3 1 2 5 8 6 6 1 6 6 2 5 1 8 9 2 3 1 1 3 7 6 1 2 5 4 4 2 3 8 2 2 6 5 3 6 4 8 4 3 5 3 2 9 4 2 2 5 5 1 9 6 6 4 2 2 3 1 9 6 7 2 5 3 3 2 1 1 1 1 1 6 3 9 1 3 2 2 3 2 3 3 6 3 3 2 4 2 1 2 6 6 3 2 2 6 3 5 6 2 4 5 3 6 7 8 5 1 2 6 3 2 3 7 3 9 2 1 5 4 3 5 1 8 5 1 4 6 1 2 6 4 4 1 4 1 1 1 9 3 4 2 4 2 1 2 1 4 1 4 5 5 3 5 1 1 3 6 1 9 1 1 3 2 1 2 3 5 4 2 6 1 5 6 6 2 9 5 7 2 5 4 8 5 1 1 5 5 7 1 1 4 6 1 1 4 8 2 5 2 4 1 3 1 2 3 6 6 2 4 7 2 1 5 3 3 7 5 5 8 4 9 2 3 6 5 1 5 2 5 1 3 1 6 1 2 2 4 2 5 1 5 2 1 1 9 10 5 5 2 6 8 4 1 1 7 3 6 5 1 4 5 1 2 5 4 4 5 4 5 4 3 2 4 6 1 4 2 1 3 6 3 1 9 6 7 3 6 4 1 4 11 1 1 3 6 1 4 8 6 1 6 5 5 5 7 1 7 2 6 4 3 10 10 1 9 3 1 6 2 7 4 1 5 1 7 2 1 1 10 4 7 3 8 2 6 6 5 6 3 7 7 3 6 1 2 6 3 1 11 8 5 1 5 3 3 6 5 2 5 3 7 1 8 6 3 1 1 5 6 2 8 2 6 8 2 9 6 3 1 3 5 3 3 1 9 11 9 2 8 1 10 2 5 1 6 4 5 7 8 2 1 2 5 1 2 6 2 7 2 5 3 3 9 5 9 5 1 5 2 2 1 1 4 1 10 8 2 9 8 2 6 2 1 2 1 7 1 1 6 1 5 4 4 3 1 1 4 8 7 3 5 5 1 4 6 1 5 1 2 1 8 3 5 5 3 2 5 1 2 1 3 1 4 4 6 1 2 4 5 9 5 2 1 4 8 3 2 5 5 3 1 2 10 1 4 6 8 3 3 3 2 8 1 1 1 3 6 4 2 2 5 4 7 1 11 6 1 6 5 1 1 4 4 1 7 6 1 4 6 4 5 1 7 4 1 5 6 6 5 3 3 1 2 5 7 1 3 3 1 3 1 4 1 3 4 6 1 1 2 2 5 2 3 5 4 1 9 4 3 3 3 2 2 6 7 4 4 2 2 3 9 7 5 2 6 8 4 4 1 6 4 5 11 4 5 6 5 2 2 8 3 7 6 4 4 8 6 3 6 7 1 5 6 3 4 6 1 2 1 8 4 8 2 1 6 2 5 2 4 1 3 5 2 2 1 1 5 2 2 9 2 1 2 2 5 7 1 2 1 5 3 3 1 8 6 2 2 4 6 2 9 1 4 4 5 4 1 3 1 3 5 2 1 3 2 5 2 3 8 1 5 8 2 6 5 6 1 3 3 1 6 8 6 4 1 2 3 1 4 1 3 3 10 4 8 6 3 3 7 6 1 9 1 4 8 5 7 2 7 4 6 3 1 7 4 4 7 4 2 6 4 4 5 7 1 8 3 1 2 2 9 8 1 4 2 7 9 7 3 3 8 4 3 4 5 7 4 1 2 1 2 3 3 5 4 2 8 7 9 4 3 2 8 4 4 1 1 1 4 4 6 8 2 9 3 5 1 5 1 1 8 10 5 7 2 2 2 2 6 7 4 6 3 5 5 6 1 6 1 9 5 6 6 1 6 2 9 2 7 3 5 8 6 9 5 4 3 3 7 3 5 6 3 1 1 2 10 8 7 8 3 3 1 5 3 9 3 7 4 5 9 8 7 6 8 4 4 2 1 2 6 6 4 5 3 4 4 4 1 1 1 6 5 2 5 2 4 7 3 1 10 5 5 1 6 5 6 7 1 6 4 9 9 7 7 4 1 2 4 1 2 11 2 10 2 2 4 2 9 1 8 1 3 6 10 2 1 5 4 6 5 2 7 6 1 10 6 3 2 2 6 2 3 2 6 2 1 1 5 5 4 1 1 3 1 3 6 3 10 4 2 7 6 7 2 3 5 6 1 1 8 2 10 2 2 6 9 3 10 3 5 leidenbase/inst/testdata/test01_file01.txt0000644000176200001440000001014514444624070020162 0ustar liggesusers22 41 2 30 39 12 40 31 30 4 34 63 12 12 7 4 19 20 57 30 31 11 18 45 80 59 26 54 42 43 5 31 1 9 1 29 14 15 58 49 1 63 40 6 48 70 6 7 40 15 17 43 12 5 4 14 14 48 46 23 35 9 47 92 30 12 83 23 17 77 52 39 24 37 33 17 24 35 5 55 11 32 26 14 27 12 46 31 16 42 62 79 7 2 63 2 66 75 72 32 10 14 5 34 6 47 32 18 52 35 9 2 35 33 69 1 21 68 6 77 27 4 61 31 70 7 2 25 15 51 37 25 33 101 10 24 19 58 64 1 29 17 65 79 24 21 57 48 31 24 1 11 37 2 35 39 50 65 4 13 7 23 54 44 14 12 38 3 49 9 88 1 20 16 21 76 6 1 3 11 20 81 4 30 45 36 43 14 32 55 23 5 51 46 2 111 13 75 15 63 26 33 96 17 31 4 21 1 35 16 34 46 5 1 67 49 58 28 12 3 59 4 60 8 24 11 44 33 25 4 7 2 24 26 12 21 67 1 22 27 12 33 31 25 73 11 44 2 39 93 46 90 19 28 47 20 40 98 49 37 10 21 4 91 36 41 18 56 70 51 5 27 7 52 19 27 11 46 11 8 35 22 2 20 29 4 5 6 36 84 15 12 31 27 17 7 2 19 22 9 17 22 49 40 20 28 33 1 5 6 44 27 60 29 17 27 65 19 64 3 44 29 20 62 33 21 3 22 20 10 77 39 26 17 16 23 31 10 37 11 51 9 9 8 48 13 49 11 53 53 3 4 51 68 66 56 21 17 82 36 15 27 2 29 9 12 1 43 17 6 24 8 68 7 29 48 45 95 18 9 85 4 29 13 2 6 33 7 48 8 19 8 25 10 20 20 50 24 36 20 13 24 15 86 55 26 29 30 8 49 35 74 11 74 23 68 3 10 3 11 16 10 3 19 24 80 47 77 5 80 32 53 19 17 12 23 36 11 52 1 46 7 22 15 46 10 79 9 13 18 2 5 28 1 2 24 6 45 9 63 5 38 4 2 53 60 107 69 61 39 42 38 16 30 33 22 67 16 8 54 36 33 56 7 55 4 25 10 16 47 4 48 12 9 85 1 11 14 74 30 6 25 25 45 9 42 62 18 3 11 32 5 40 64 9 33 2 61 22 39 24 74 76 44 14 112 28 30 12 32 50 113 6 98 58 64 4 5 17 21 29 6 34 13 95 11 36 14 19 5 32 15 21 38 33 15 55 6 18 15 37 66 14 46 2 6 33 28 21 7 18 17 16 45 15 91 91 29 34 26 53 16 15 50 24 32 9 71 19 45 20 28 8 3 43 67 10 43 36 30 7 34 32 12 50 13 100 18 14 12 5 24 7 18 30 13 10 3 4 4 14 18 3 73 7 53 26 45 30 56 12 5 39 35 20 40 79 5 8 106 7 19 12 34 3 72 21 27 92 25 36 6 53 44 75 37 93 15 26 16 30 43 75 82 11 32 34 14 38 50 2 31 41 15 36 110 43 27 42 25 8 20 72 72 28 4 42 34 44 70 7 50 81 61 7 20 38 17 4 43 57 4 62 31 34 87 19 13 56 30 47 66 41 11 21 85 39 10 40 27 46 82 52 16 6 45 25 50 16 43 12 52 3 24 37 4 88 16 19 13 44 74 12 55 1 51 25 6 38 9 45 94 37 87 10 56 15 25 36 94 72 5 10 86 13 71 45 51 11 51 15 22 29 9 23 25 76 3 37 6 52 29 29 104 8 62 20 11 16 54 63 18 58 68 59 73 2 25 33 48 3 2 71 52 38 15 10 55 62 7 40 34 5 1 8 37 30 64 16 65 32 11 28 4 22 69 47 4 11 5 54 54 87 1 64 1 17 4 2 8 23 23 36 9 8 93 26 13 1 30 41 51 29 1 18 41 41 23 27 1 24 35 18 26 4 42 22 14 1 1 14 71 43 18 58 28 41 65 35 25 44 66 7 12 5 21 3 66 55 19 89 35 71 48 81 85 42 76 34 47 18 26 6 50 9 37 14 57 14 54 7 8 11 9 65 34 17 47 10 109 13 42 10 5 38 84 1 6 3 29 17 56 44 15 60 18 1 18 97 12 8 9 66 9 21 41 25 13 50 11 70 30 11 78 49 15 9 6 3 26 13 40 79 44 19 42 69 37 70 20 2 27 14 67 44 2 35 39 8 64 20 67 59 108 67 21 42 78 89 49 55 54 20 48 50 42 82 3 57 7 89 2 33 5 57 50 99 73 34 42 3 22 69 6 28 3 25 58 7 32 15 23 32 27 26 35 114 48 12 17 6 52 81 11 14 26 2 13 50 80 38 1 10 65 4 11 53 83 64 74 2 99 40 39 60 81 68 5 27 53 72 1 16 11 53 5 26 51 8 55 32 18 25 39 41 7 7 10 8 36 16 63 55 59 5 22 43 3 17 58 13 14 66 16 29 34 16 8 14 8 17 15 60 1 16 2 31 15 92 9 1 84 88 26 47 16 2 67 60 2 54 65 2 57 22 20 13 103 35 12 19 46 30 77 49 26 24 46 1 10 20 76 8 16 4 22 3 22 35 47 6 79 32 4 3 51 18 27 29 12 42 31 18 40 29 83 15 3 34 78 11 31 13 25 13 69 18 57 21 24 8 44 6 4 18 45 59 62 86 9 32 38 16 57 2 41 7 72 8 73 3 40 48 17 76 3 8 35 40 20 6 31 60 25 71 90 28 28 36 62 47 4 77 29 18 14 10 30 52 8 24 23 33 49 58 24 7 1 53 44 61 10 71 6 21 115 61 1 2 5 28 29 19 68 38 19 2 3 4 33 59 21 1 52 105 12 22 13 3 9 47 22 38 78 19 61 1 7 48 6 2 8 2 46 19 38 64 13 11 3 28 100 87 16 3 6 1 34 59 14 17 49 38 38 63 22 57 27 69 46 35 3 9 28 56 10 53 41 36 49 23 56 1 61 13 13 31 26 19 75 37 96 83 51 62 63 5 41 9 21 26 46 41 37 61 9 3 1 28 70 47 20 61 21 2 55 28 39 48 58 4 8 40 40 17 23 6 39 49 12 28 22 25 14 34 28 1 27 73 78 6 1 37 47 75 59 13 10 3 4 5 33 84 24 2 27 2 41 43 40 22 21 31 56 86 38 1 8 32 23 54 97 36 37 54 51 19 43 5 30 9 9 19 39 27 42 3 38 10 45 65 3 23 15 13 27 13 9 10 35 36 8 60 23 18 10 54 59 4 42 50 39 4 10 23 37 48 45 78 5 17 12 88 102 31 32 52 73 80 16 10 90 7 41 8 26 7 23 2 3 39 5 1 15 7 56 60 43 52 6 31 23 45 13 26 34 14 23 28 101 leidenbase/inst/testdata/test04_file01.txt0000644000176200001440000000760514444624070020174 0ustar liggesusers4 5 3 28 22 19 27 7 28 18 8 16 19 19 17 18 22 10 36 28 7 16 7 8 20 3 1 14 23 39 1 2 12 15 12 21 9 2 1 31 12 21 27 11 35 23 11 17 27 8 24 39 19 1 18 9 9 35 1 30 11 15 33 19 28 19 14 30 24 41 27 22 6 25 32 24 6 11 1 17 16 34 1 9 29 19 1 7 13 23 1 2 17 3 16 3 14 28 4 34 5 9 1 8 11 33 34 7 27 31 15 3 31 32 45 12 20 3 11 41 29 18 8 2 14 17 3 14 8 10 25 14 32 10 5 6 22 20 23 12 21 15 40 2 6 20 36 35 7 6 12 16 25 3 11 15 7 40 18 26 17 30 14 43 9 19 13 2 31 15 2 12 10 13 20 20 11 12 2 16 10 43 18 28 8 4 4 9 21 6 30 1 10 1 3 15 26 4 8 21 1 32 19 24 24 18 20 12 11 13 8 1 1 12 42 31 1 6 19 2 4 18 25 9 9 16 16 3 14 18 17 3 6 37 19 20 42 12 4 29 19 3 2 14 37 16 5 3 22 16 1 4 22 6 33 10 27 18 31 25 5 20 18 14 4 5 7 23 23 47 1 29 17 27 12 29 16 1 16 17 11 4 3 10 21 18 1 11 4 14 8 19 7 29 24 17 3 22 4 15 24 4 31 27 10 6 13 12 1 11 16 29 25 21 24 29 40 12 38 2 5 21 10 20 32 20 2 4 10 5 41 22 1 24 13 30 7 5 25 16 10 15 15 9 35 26 31 16 1 1 2 18 10 3 10 37 20 24 4 4 2 29 3 21 15 19 12 4 24 11 6 9 29 17 21 35 8 9 7 15 23 18 21 26 3 11 32 17 35 9 22 9 14 5 10 10 7 6 4 10 26 6 2 7 17 1 21 28 9 31 11 21 16 21 30 43 2 5 2 16 13 5 2 22 6 20 33 41 1 20 34 1 22 24 19 30 4 16 27 12 1 19 4 8 1 5 7 15 26 7 3 1 6 12 3 6 11 2 15 16 1 13 18 3 1 25 54 45 8 22 23 13 13 28 32 4 42 13 6 14 4 3 23 17 17 18 14 5 13 13 18 35 19 15 23 12 16 9 21 28 11 14 14 8 15 23 47 7 2 16 34 1 27 38 15 32 3 8 4 22 6 21 20 43 9 13 6 28 19 34 7 10 11 1 1 38 18 1 24 20 21 11 8 26 9 16 4 9 22 1 34 8 20 13 32 2 6 11 7 8 25 10 9 1 3 11 32 6 20 17 7 24 13 8 8 10 10 21 15 1 1 13 8 7 6 34 15 25 22 8 10 6 9 2 39 42 5 4 4 28 17 8 34 19 7 26 17 7 9 19 1 6 17 7 28 26 5 2 18 18 9 7 2 37 17 37 1 8 28 20 19 1 22 11 10 27 2 1 9 2 17 22 19 8 2 4 20 29 19 14 4 11 10 5 3 25 5 24 1 13 28 39 28 4 16 16 8 9 13 7 3 24 5 24 4 3 39 29 14 14 9 10 16 4 6 18 23 15 5 23 17 46 43 8 17 10 13 24 18 4 36 18 1 2 15 48 22 26 23 28 33 10 5 16 20 50 22 5 21 29 1 4 27 13 11 8 14 46 13 39 19 27 2 6 25 18 51 13 22 26 5 14 19 17 12 10 14 11 13 15 8 49 1 14 5 23 8 14 4 19 4 1 5 7 26 28 8 10 16 10 8 4 21 15 30 14 20 2 25 11 41 21 21 53 9 1 10 16 13 14 21 7 44 29 41 37 3 14 32 35 2 3 25 4 13 8 5 17 18 17 27 15 1 12 6 25 28 38 13 40 34 16 6 18 4 45 33 18 16 1 14 14 48 12 38 12 24 18 3 6 30 46 4 15 9 16 1 26 12 28 5 36 21 12 7 5 5 30 29 12 6 11 7 1 18 23 4 9 12 12 9 25 39 7 1 6 36 40 11 14 5 10 17 19 1 20 2 10 17 12 52 11 25 35 43 4 23 20 8 33 7 1 11 7 15 18 9 36 9 14 17 17 16 15 40 15 24 33 5 46 26 23 5 1 13 14 12 11 2 21 24 23 43 2 25 2 12 7 49 19 6 15 14 15 20 5 14 26 7 16 23 28 16 46 31 8 15 11 2 1 26 21 2 43 22 23 45 1 14 10 3 29 9 50 5 3 11 22 6 38 10 42 3 47 42 20 23 7 52 31 6 14 10 35 7 23 4 2 21 17 5 3 3 1 36 7 13 23 8 23 2 4 3 11 6 2 14 44 17 34 8 30 16 29 1 11 19 35 19 24 11 27 16 16 9 1 3 26 7 10 13 12 5 40 18 16 1 44 21 21 3 55 27 22 1 45 3 1 29 10 23 12 13 16 20 1 1 10 9 17 34 7 14 22 5 17 19 5 9 4 13 21 17 3 1 4 39 2 24 44 26 9 10 13 21 15 13 17 9 9 24 8 25 12 13 3 2 8 19 15 12 14 2 25 33 13 3 42 25 3 14 40 3 36 25 10 26 7 11 19 22 1 28 41 31 1 6 1 12 5 10 1 6 13 18 4 2 4 31 33 11 46 16 18 2 10 7 29 21 19 23 2 7 27 21 20 2 2 15 24 16 2 26 14 26 45 7 36 20 6 9 5 11 18 7 2 3 47 24 15 16 13 13 36 3 5 17 4 9 10 2 21 35 24 20 2 17 31 16 10 11 2 25 14 25 38 6 6 4 1 33 18 41 21 7 9 5 28 27 6 6 30 32 31 1 6 17 12 1 27 8 5 28 11 20 12 8 12 3 1 6 21 22 3 13 22 3 2 18 32 41 20 12 27 42 19 4 26 2 15 33 4 13 2 22 15 12 17 35 11 3 17 3 44 12 13 38 26 16 2 6 19 48 13 2 11 12 15 3 9 24 31 3 13 23 4 36 29 45 1 11 2 15 6 23 5 37 5 4 31 30 23 12 8 7 26 7 25 22 3 25 19 44 10 1 16 1 5 15 20 1 1 5 18 8 15 2 12 6 23 33 10 8 20 3 17 6 22 6 44 18 9 27 27 24 30 11 22 31 19 6 4 14 9 15 6 12 29 37 46 11 12 25 33 3 3 26 5 2 18 1 32 38 6 3 29 3 5 50 27 25 20 51 20 7 13 12 9 34 30 14 49 4 25 14 47 22 39 1 28 15 15 22 22 29 23 2 13 5 8 40 2 30 8 26 29 26 15 5 11 4 9 25 30 7 5 14 3 18 23 7 22 18 5 30 18 35 8 7 1 24 19 24 18 7 34 27 37 20 13 5 38 19 5 9 1 17 30 3 2 22 1 12 8 17 37 25 39 27 11 24 30 8 26 1 15 9 30 6 10 leidenbase/inst/testdata/test08_file01.txt0000644000176200001440000000567014444624070020200 0ustar liggesusers2 2 5 5 6 4 2 3 5 1 3 2 4 4 4 1 6 1 2 5 3 2 3 3 1 5 1 1 1 2 1 3 6 3 6 2 4 3 1 7 6 2 2 7 4 2 7 4 2 3 3 2 4 1 1 4 4 4 1 8 7 3 7 4 5 4 1 8 3 5 2 6 4 1 5 3 4 7 1 4 2 2 1 4 5 4 1 3 5 1 1 3 4 5 2 5 1 5 2 2 2 4 1 3 7 7 2 3 2 7 3 5 7 5 2 6 1 5 7 5 5 1 3 3 1 4 5 1 3 1 1 1 5 1 2 4 6 1 2 6 2 3 6 3 4 1 2 4 3 4 6 2 1 5 7 3 3 6 1 3 4 8 1 2 4 4 5 3 7 3 3 6 1 5 1 1 7 6 3 2 1 2 1 5 3 2 2 4 2 4 8 1 1 1 5 3 3 5 3 2 1 5 4 3 3 1 1 6 7 5 3 1 1 6 2 7 1 4 4 3 2 1 1 4 4 2 2 5 1 1 4 5 4 1 4 1 2 6 2 5 4 5 3 1 1 2 2 5 6 2 1 2 6 4 7 1 2 1 7 1 2 1 1 1 2 2 3 1 1 1 1 5 4 2 6 5 2 1 2 4 7 2 5 1 2 1 1 7 2 1 3 4 3 5 3 4 5 6 2 3 3 2 7 2 1 4 5 6 1 7 2 5 1 2 3 5 6 6 2 3 2 2 1 1 5 1 3 1 1 2 5 6 1 3 5 8 3 2 1 2 1 3 3 4 4 3 7 2 1 1 3 1 1 5 1 1 1 3 2 2 3 5 5 2 3 4 6 2 3 7 4 4 5 4 2 4 3 4 3 3 2 1 2 3 5 7 5 4 4 4 6 4 1 2 1 1 3 4 2 1 3 4 3 3 4 1 2 5 4 7 7 2 2 2 8 2 3 2 3 2 5 2 3 6 4 1 7 5 1 1 2 1 6 3 4 8 2 2 2 6 1 4 2 3 1 2 3 3 3 3 5 1 4 6 5 4 7 3 3 2 1 5 1 5 1 1 5 2 3 6 2 5 5 5 5 2 2 5 4 1 2 5 1 4 4 1 1 2 5 7 1 4 4 3 2 6 2 4 2 5 7 1 1 3 3 2 1 3 3 2 2 1 2 2 3 5 5 3 2 6 4 2 1 2 4 5 4 5 4 2 3 1 7 1 1 2 1 1 3 1 2 7 3 3 4 2 2 4 6 1 2 3 1 5 5 3 4 7 3 3 1 1 4 1 5 7 5 4 1 4 3 3 5 3 3 1 1 2 3 1 1 5 3 3 4 2 3 1 6 3 1 4 4 3 2 2 2 2 2 1 4 3 2 4 3 3 4 3 4 4 1 4 4 3 5 3 2 3 1 1 4 3 3 1 4 1 1 3 5 1 4 1 6 7 1 2 3 1 4 3 4 6 4 3 3 2 1 5 4 1 2 7 1 2 5 1 2 3 1 5 5 2 5 2 2 2 3 4 5 3 5 3 2 3 2 5 2 5 1 1 4 1 2 2 4 1 2 3 2 2 4 3 2 3 4 1 5 3 1 2 2 1 1 3 3 1 6 3 1 5 7 1 2 2 1 2 6 2 2 5 1 2 2 5 7 3 1 3 5 2 4 2 3 4 1 1 3 5 6 3 2 2 4 4 6 1 1 7 5 3 3 4 1 1 2 1 3 1 2 4 2 1 2 3 3 5 3 1 2 1 3 1 2 3 8 1 1 3 1 7 5 2 2 6 4 1 1 2 5 1 2 3 1 5 5 1 5 1 5 4 3 5 1 2 5 3 2 4 1 4 2 3 1 6 4 1 5 2 5 3 2 2 4 1 2 2 7 1 2 1 1 1 2 6 2 6 3 1 5 4 8 8 2 3 4 2 1 3 6 5 2 1 2 6 3 2 2 8 5 6 4 7 3 1 1 1 1 4 6 6 4 1 2 3 1 4 2 6 7 1 2 1 4 4 1 1 3 1 4 6 2 7 1 4 2 2 1 1 3 7 3 1 7 3 3 1 4 2 4 1 4 4 2 3 6 3 3 7 2 8 3 1 2 1 5 1 6 7 3 2 3 1 2 3 1 3 6 3 1 4 4 3 1 3 1 2 1 3 3 2 2 5 2 3 7 3 3 7 3 1 3 2 3 2 6 2 2 1 2 1 5 5 4 2 2 5 7 6 4 2 1 2 5 1 2 1 2 3 2 7 4 1 1 4 3 1 2 3 2 4 2 5 5 1 2 3 5 1 3 2 3 2 5 7 4 3 1 1 4 2 3 8 2 5 1 7 4 4 4 3 7 2 2 2 4 1 5 3 3 1 5 6 2 6 1 2 1 1 2 2 5 5 2 6 1 2 5 1 5 1 2 6 5 2 1 1 1 1 4 4 2 3 1 6 2 4 4 2 4 2 5 2 4 5 1 2 2 3 3 1 3 4 1 5 2 3 5 4 4 4 3 3 1 6 5 5 3 3 4 3 6 1 3 1 7 5 5 2 1 5 1 6 5 2 1 1 3 3 7 4 6 1 5 5 7 1 4 1 6 2 1 1 4 5 1 2 3 2 7 5 7 3 2 1 3 1 3 5 2 4 1 3 3 2 2 1 3 3 3 3 2 3 3 1 6 2 3 2 1 4 4 2 7 1 3 3 5 1 3 3 2 5 5 2 5 2 4 2 4 1 3 2 4 3 1 3 4 7 2 1 7 3 1 1 1 2 4 4 2 1 7 1 5 2 3 4 2 5 2 4 4 8 5 7 1 4 4 6 1 2 3 2 5 7 1 6 3 6 5 1 4 2 6 5 5 6 5 3 1 5 5 1 6 2 7 4 2 3 3 3 7 2 5 3 6 3 6 4 4 7 5 4 5 1 6 5 2 3 2 3 4 4 1 5 3 7 6 3 5 4 3 7 5 5 2 2 2 5 5 1 7 3 3 4 1 2 1 2 2 7 8 2 6 3 3 3 3 1 6 5 1 4 1 1 1 2 1 2 3 1 1 1 2 1 3 3 3 6 4 1 7 1 3 1 5 4 4 6 4 1 1 4 2 2 3 8 7 6 7 4 4 2 1 4 3 4 6 5 1 3 7 6 1 7 5 5 3 2 3 1 1 5 2 4 5 5 5 2 2 2 1 1 3 1 3 5 6 4 2 8 1 1 2 1 1 1 6 2 1 5 3 3 6 6 5 2 3 5 2 3 6 3 8 3 3 5 3 3 2 7 2 4 1 8 3 2 1 5 1 2 3 6 1 2 8 1 4 3 3 1 3 4 3 1 3 2 2 1 1 5 2 2 4 2 4 1 4 8 5 3 6 1 6 3 4 1 1 2 2 7 3 8 3 3 1 3 4 8 4 1 leidenbase/inst/testdata/test07_file01.txt0000644000176200001440000000567014444624070020177 0ustar liggesusers2 2 5 5 6 4 2 3 5 1 3 2 4 4 4 1 6 1 2 5 3 2 3 3 1 5 1 1 1 2 1 3 6 3 6 2 4 3 1 7 6 2 2 7 4 2 7 4 2 3 3 2 4 1 1 4 4 4 1 8 7 3 7 4 5 4 1 8 3 5 2 6 4 1 5 3 4 7 1 4 2 2 1 4 5 4 1 3 5 1 1 3 4 5 2 5 1 5 2 2 2 4 1 3 7 7 2 3 2 7 3 5 7 5 2 6 1 5 7 5 5 1 3 3 1 4 5 1 3 1 1 1 5 1 2 4 6 1 2 6 2 3 6 3 4 1 2 4 3 4 6 2 1 5 7 3 3 6 1 3 4 8 1 2 4 4 5 3 7 3 3 6 1 5 1 1 7 6 3 2 1 2 1 5 3 2 2 4 2 4 8 1 1 1 5 3 3 5 3 2 1 5 4 3 3 1 1 6 7 5 3 1 1 6 2 7 1 4 4 3 2 1 1 4 4 2 2 5 1 1 4 5 4 1 4 1 2 6 2 5 4 5 3 1 1 2 2 5 6 2 1 2 6 4 7 1 2 1 7 1 2 1 1 1 2 2 3 1 1 1 1 5 4 2 6 5 2 1 2 4 7 2 5 1 2 1 1 7 2 1 3 4 3 5 3 4 5 6 2 3 3 2 7 2 1 4 5 6 1 7 2 5 1 2 3 5 6 6 2 3 2 2 1 1 5 1 3 1 1 2 5 6 1 3 5 8 3 2 1 2 1 3 3 4 4 3 7 2 1 1 3 1 1 5 1 1 1 3 2 2 3 5 5 2 3 4 6 2 3 7 4 4 5 4 2 4 3 4 3 3 2 1 2 3 5 7 5 4 4 4 6 4 1 2 1 1 3 4 2 1 3 4 3 3 4 1 2 5 4 7 7 2 2 2 8 2 3 2 3 2 5 2 3 6 4 1 7 5 1 1 2 1 6 3 4 8 2 2 2 6 1 4 2 3 1 2 3 3 3 3 5 1 4 6 5 4 7 3 3 2 1 5 1 5 1 1 5 2 3 6 2 5 5 5 5 2 2 5 4 1 2 5 1 4 4 1 1 2 5 7 1 4 4 3 2 6 2 4 2 5 7 1 1 3 3 2 1 3 3 2 2 1 2 2 3 5 5 3 2 6 4 2 1 2 4 5 4 5 4 2 3 1 7 1 1 2 1 1 3 1 2 7 3 3 4 2 2 4 6 1 2 3 1 5 5 3 4 7 3 3 1 1 4 1 5 7 5 4 1 4 3 3 5 3 3 1 1 2 3 1 1 5 3 3 4 2 3 1 6 3 1 4 4 3 2 2 2 2 2 1 4 3 2 4 3 3 4 3 4 4 1 4 4 3 5 3 2 3 1 1 4 3 3 1 4 1 1 3 5 1 4 1 6 7 1 2 3 1 4 3 4 6 4 3 3 2 1 5 4 1 2 7 1 2 5 1 2 3 1 5 5 2 5 2 2 2 3 4 5 3 5 3 2 3 2 5 2 5 1 1 4 1 2 2 4 1 2 3 2 2 4 3 2 3 4 1 5 3 1 2 2 1 1 3 3 1 6 3 1 5 7 1 2 2 1 2 6 2 2 5 1 2 2 5 7 3 1 3 5 2 4 2 3 4 1 1 3 5 6 3 2 2 4 4 6 1 1 7 5 3 3 4 1 1 2 1 3 1 2 4 2 1 2 3 3 5 3 1 2 1 3 1 2 3 8 1 1 3 1 7 5 2 2 6 4 1 1 2 5 1 2 3 1 5 5 1 5 1 5 4 3 5 1 2 5 3 2 4 1 4 2 3 1 6 4 1 5 2 5 3 2 2 4 1 2 2 7 1 2 1 1 1 2 6 2 6 3 1 5 4 8 8 2 3 4 2 1 3 6 5 2 1 2 6 3 2 2 8 5 6 4 7 3 1 1 1 1 4 6 6 4 1 2 3 1 4 2 6 7 1 2 1 4 4 1 1 3 1 4 6 2 7 1 4 2 2 1 1 3 7 3 1 7 3 3 1 4 2 4 1 4 4 2 3 6 3 3 7 2 8 3 1 2 1 5 1 6 7 3 2 3 1 2 3 1 3 6 3 1 4 4 3 1 3 1 2 1 3 3 2 2 5 2 3 7 3 3 7 3 1 3 2 3 2 6 2 2 1 2 1 5 5 4 2 2 5 7 6 4 2 1 2 5 1 2 1 2 3 2 7 4 1 1 4 3 1 2 3 2 4 2 5 5 1 2 3 5 1 3 2 3 2 5 7 4 3 1 1 4 2 3 8 2 5 1 7 4 4 4 3 7 2 2 2 4 1 5 3 3 1 5 6 2 6 1 2 1 1 2 2 5 5 2 6 1 2 5 1 5 1 2 6 5 2 1 1 1 1 4 4 2 3 1 6 2 4 4 2 4 2 5 2 4 5 1 2 2 3 3 1 3 4 1 5 2 3 5 4 4 4 3 3 1 6 5 5 3 3 4 3 6 1 3 1 7 5 5 2 1 5 1 6 5 2 1 1 3 3 7 4 6 1 5 5 7 1 4 1 6 2 1 1 4 5 1 2 3 2 7 5 7 3 2 1 3 1 3 5 2 4 1 3 3 2 2 1 3 3 3 3 2 3 3 1 6 2 3 2 1 4 4 2 7 1 3 3 5 1 3 3 2 5 5 2 5 2 4 2 4 1 3 2 4 3 1 3 4 7 2 1 7 3 1 1 1 2 4 4 2 1 7 1 5 2 3 4 2 5 2 4 4 8 5 7 1 4 4 6 1 2 3 2 5 7 1 6 3 6 5 1 4 2 6 5 5 6 5 3 1 5 5 1 6 2 7 4 2 3 3 3 7 2 5 3 6 3 6 4 4 7 5 4 5 1 6 5 2 3 2 3 4 4 1 5 3 7 6 3 5 4 3 7 5 5 2 2 2 5 5 1 7 3 3 4 1 2 1 2 2 7 8 2 6 3 3 3 3 1 6 5 1 4 1 1 1 2 1 2 3 1 1 1 2 1 3 3 3 6 4 1 7 1 3 1 5 4 4 6 4 1 1 4 2 2 3 8 7 6 7 4 4 2 1 4 3 4 6 5 1 3 7 6 1 7 5 5 3 2 3 1 1 5 2 4 5 5 5 2 2 2 1 1 3 1 3 5 6 4 2 8 1 1 2 1 1 1 6 2 1 5 3 3 6 6 5 2 3 5 2 3 6 3 8 3 3 5 3 3 2 7 2 4 1 8 3 2 1 5 1 2 3 6 1 2 8 1 4 3 3 1 3 4 3 1 3 2 2 1 1 5 2 2 4 2 4 1 4 8 5 3 6 1 6 3 4 1 1 2 2 7 3 8 3 3 1 3 4 8 4 1 leidenbase/inst/testdata/igraph_n1500_edgelist.txt.gz0000644000176200001440000050235414444624070022306 0ustar liggesusers/7]igraph_n1500_edgelist.txtDɡ*DߊgIEI1$Đu^?>c /\l]"̽\R ɿB[Qȷ/_uZ]KnraFrlB_C?n[_/ſLj.B>Shm0].ڰ_骐,ȿ0K.ZMe;C.?&PKƖɸ;?{d~a7>J!)KYR妈WU39Hdw|xh'u_K=]OW Mw7_ƿ_+2YȻOw>_о)K M# ~]?{+ۉj߿i 0[E,W~7t%ib?v?>'r|FPr~ aOyrSCn~OU7KOvmNM"O{M wGN#=R-Kv\َGPMsj2_r}%&݇?alo~NNb3䬵p6a{܄ ~+ߟ.~πEߘSM~1r,s/7S8w+}>=+}ˤ&]*RX0Hpݶ cwWj7e4P%7ۆwUWUqU{_UXR;GG.5ȥ R\jK rAR~_ܲ__~?\-󉉲 w2ژ/ɗXoRtllJ';mcb86|͉t&j// JP=(l\߻ [e}ح˥vya]ݞxߎaoޗ0O'gwjHku5YD6W:M81B+UFWP*_{㪫ۯRn>򵸚q{Qx8E(j<bPj5Jô_ۜCqǰ௭?6NB_=AaP_;R>;_yrgI>t SS׺?r̉4zeB1  uՄ."\۩C9K硜Js5{[7ww̟;CMJWsQ.6]4Jk6_䶸@kt W'j*?`jw76pwWư_-nA gr}x 5wkQ?@m0.R~:?,{X7[حulx1ܺ)4 5 I`gI hp}~8; [85 O9_y=?lS`PiW Wh'6MHc1C:kwnn_]PkFm}ך-ՒxFuqxš4G܍kNԼ,}ǯ<yv `fHl'E Ak0344~ Tj_ z .5#8I`N\SkN};KT5y&O@3L? `򭴶P};q;UP$4_ A<|]vaAs1O^]p vVְU sa2Xu)6iw|UO|Sֿ\7_wҍ4LFC7溍j_5e_q6P dƁwaFuYx,$8u{j7'Tc鈴 ~BGt:W mkUwa`F重;5T4v+Ƈˡk>u1 Q°:/ͤ#|"C+t?:|4 _Χ/=OϩrY 3*۰>&\"0}Fgt~|?DQ6PK'ܦZ[%Z4`mzw8<}O){V}&"S ~O5r.x\8T7T8=X(Q2cBL'80uJMاgC&̌όt|)ٹvT|g4aJEI3 {3m>W__khI8hdN fg0Q(DPٙIQPtZ3Bǻt˕PTpPm0yP:bfR^_!%Uh5X:Sp9>F^)KUa* 76.P՛0@`C"TM :.ˁS{ݝn <5AuGԤz2qw8YtU')+_[ȉq ?<0~ }T5>@n<°_(Wt3 ]aq_?.^k5PӍ{A, ^`A>Ɵn+⁝„^a1' cIbk+/Ed`.+/ÿR?0%ؼ> km5~7o?o?Oo?ۏ8<۟ro3qBxwm/ty?ڞzV%Ki.*C'GP_WZEKP bX $dԺH3KK*p&5\s,}.a yV"䲒e%ܝS4(?t١qzc/ {d] bݴe^^ߋ)z_ͮ_Ԙ"ԛzQ8.;kv| \~/Kw*k䇹y]m|n>q7oyi&`[Wtppѥ2vp&eT+z{Dfivan+i'vWg_ة*\0$::ꐚۅ[ ,E.h貢 ֒FŹڭMX ^5_VڴWJ}Y%xIQG8jJe]>mY|YG$ZQY#_QY%/mwɬӟI󅦉e?ppxY5F\KQ0QjjێaoXp51Eˆ86zC 唕;f3+&{MQ6W: | 5B ]*}롯XK.o}kU+k +ηD ++89jb((C_:|UM %m;uS@?Bt0R^x*7aOc4^c8W vW:lǰO%9 qy sH.5D|aX2wwZ{ۜT LZ= Y]D";5r4K^7ZkK )o PpJ]"l]쨵&:k-NcN (8Q6r Una`xK0,:(vMľӊp O)v8tསaP:p N# *"Ϭ\kWs. 5 L_m4s1! Ln\j&KfL_530|[gDO.4˓˓r4͗g1g1˳˳ƉZk^`7lG_$5,V 9caBJ=K>s3pޫVrдŀ8gnBjzQ?)&DVKWZѬ" pkgR]Mw[RN6vkP4BAtx`pAqc0NpA Wj.R tD `[WjRWΆO~p~{"Hu#f줦.HiA8n(-WDTTp\s.g'TK[K䖰0Xqp^Fq㹍Pnq*s6-\MެܬZE*x*;WT AI]/@zvj=Y'wvnWÛ*wA ,jPjfKŋ#?p㉏0T|#lm9qN "!Nc[  Cm ptRdv,a5'T7]mAD)uA#] IKT謘ǼOZ<4/: uч{P,+,TԺ?S7lND_G< m1t._]k]zc| c DCeƥru(8)39r=\1_+ ݌}w!esA#j]?m/#{qV5K!(NcX ?<LǀB,<;Srf4\.aM:Zo_ͣu< όʩ3SWt!@-o~\MSRUׂ]HĺThUNԱV2]'P}C v|#G wydzpvEE.ps5\IM(چ-Î@rZ?h KX8TQ9!Ha`Q*E5:#hpp֓TjPuu5tuW' jʙyL6yxD{+ʊԉ/L<+hLը*ɮw1 Z.4Ӣ#l\R'h4n,\jԕ6.O9W ck;2vXf:fp^7B?k ׋z5үv) 0^kit.P?kW pq)Xw0vPSS?hP\}آ-EC,;x?RHLs,sszoӁu=u2 Kەדד!W[^OÜO O k{Mx2}.W݆<6Q\^q(e|A`Jp`R$R&1ޏPA$ HL5IvWg]fC 5^MOOt߻ub.V> _Mcɱ=0bCQm<Goa‰SJXA &LSwsQ'ql];.?}Qʾc_6XK@j45[ˆ0:vy)`+]A ½N-ݜ?4eM2AFFFf+]jKYUB5gʅ /*oc[.{_ZPQu&ÕjmV@&LӂCQMV*426P޼fc vWp~Krp;UW^e_a&+aN-/Aԛ ^~xepD=]4{=,/Lx ;p_w]PYИJ$Up;5Lx]`O6uujDラuut] f}&3$en(YIV;ǾYyҌJR\FTAUuq]y\&feɺxq9`A(gʁilG k@S"g5B1T=&NST47__L>O66WRץXrn`&ž3ʥqQ3LА"\Jz7aX9:́465V$V.[|ieѴaWlRlRj$0QT޳@maln[8*~.\e6TT\F]ZEN {&/]Өke[8l'-%{ kw&lRΥKe?r_Ok5ZXi~\0Ҧ؛Oh8`lP} WڢO"8-E7v(d%Y}@JMDͳ>%uueڴppdu:% ;vtv6Po 6ho;ۉP߼]<\"=a$s7/OO6e^]v Gx w4әD堢m=EkfOoV7_E\Vj_ʱ^?(0}5mw|u XkSmOac h .u⍰qRp~@ىo\wMg@'\;,۟ZЅB4 ڟk oX+hNrPKYdD&c(¯3 |u9g Jd@X&dDķF C(xטAMc)э+ "*;Z k(ض׈ }; ^K:\(6,7dxZ~C`B,(/,(/.,[#֒%Mx_ߗee6ؾ۳,=oM(A3N=+o۳s!n=+o[֬-+oے=*kPG{WwBP4UV*+MdTY1U/f6pUa`4n`Ejդ 2JS5TE=U]c󑊺TEMҕAvc_EiZܪ}A1z0}?~PAP(舤M(,_ك #M TrH a:Nݼ鼨5 ?l+ѿ˚9AҹWa\*kNkbR3Uoei w3lIb/WC1l]E e.vn@D:PН,Pʱk}1l [ݻ9N%QƮuMg -İ5N>03-}> ڗ 6>>s>(&ym8XQ(cݩM}ls~[-b- bs1@zBFUpIE#!s )ΫjE5'ABnC ~^pz*3b q='|g|޸*/?7H$|VӃy\ 3n8 rX-Ze'"K#%w-Kl4㤌ϳ/~.[wxLMkN<s1pܤJn3̘k}r+a;BBoxi/2I5_fr,f4R>˙L0jX=`w7o 9m cFl9m䬶FNk9m䄶#Fhw#TLba Ap͉a 5!^gu@#Ir1E쟯9HAH~&{c&Ik;= 0YWL{^p嫿 /9jjɛ?YtF=!0!)d}V7NrJqJ1b]8bb^P+wqJJJ1z^)IIg4!qqW\z^QWDz s٘sD#]+iw|6M/x}Wܭp65Fc\':]gs_tiU⫄z90"p~BŤ3Q8 ?Ls7p8x<$دeE2;fCx8 E

gv kZm:<=p_IfOCI!_x&H5 &<=ÃV|{w^9P542IL߭@qZd'N|qȨ^t/V1#g>rM|UVh3ݬ^Wwkz嚷US g|/l$sZh\׈+U&YwzdW6qܒF\ )!Vb[Hk 29|Zi˚+׮qNj&9IN>'ɓI rR3|=؉[3)y߭jjcUE 7sEc\Va>WPpuDS!_cw*r뮇 m4Gulw|'bf}1;uEXKBc*B9e 2svm+[tiɴvV7y(rloX6hYNѲmzb&L "Y'Vfr篪x*ҶRW5+nIΈ5 xJ<G#B0S4Ϙ#'|>Օ: ~o6MQ/xprmissN8Ƿnx/qiJNŸxl+Nvv+i%-I+@K)_9tq n~OcG5ןdh6TSee9nj?ZxlfG9T.0hfMߤ&l'LXx&7nzɶ&G@GlVIۜzM}œ2{K t9#91t vͥY M+힡$\Jp8ZkcM>=vGh=,cb!X>+i,W^k`Y Yx:5Ta U8W{NshFk۝Tv N.8~%5c^r/j8Bm7Y&w-T/e<͐8ŁIu&5v|niĉ<>gWtuq`vyNY~QT 'A]q-rz\ ݖxi&,;r|x/n4\E&~@p澯k6H¥`u/'Iɧi,k@Łjb_vG:<&nwnmĂ\WWܭßNmjtV> ]Y1Ι-)c Iz&g<Ծ؟>$: c0ձC>ԛWw#$;z95Z/9c^N:ᜤލtwGz9Uҍ;p]2P. ~&7%GG'H ʠaW5OzK__Sۋ|\xaUpFrxzhwb»ɕԁ Or '~B@Ka='.ʔ%NS ( l<@MNG39 tHr#ݔi@_q R];qZBYQ*)`FZYІka!?j_bccV,?g]goZs mqLJ%N܌ϩ,J|}v]kVlL3Դ&H?S[k™WiUnHquґ0i 9AXQC7~FֈXX#$k` 866o։Ɵr\lA b7*8q9Zl{mWӹݯ[csrMJLNUfS+ a{+ G8),2!A^IlxwE8E×ӫa;%a^g|O>$ܛt{}]G ' Gz[3XzB|͖jRˠ2`M9 z\SMh01ý _)0OnI G4I6Ox& 8I(m*dæ1fNQG7_YP6s}z=%^)c1L:mN=Ií*ֶJ:cDvy#X1?P)xIw3'xLlC&"dy6ZGˬ4!;|f} sfz|#°"󄵅g~&*x&LX40aPfV̬Y=2zӎٿJ x͉^l-y;IFXNJ+X| q7x7I)lJNY"+/}~[2ߚ̷֤&'a=)-}A~ D8PLGa::T8Q>&< ORv'QHicc Ft'*Z>YX12r{6gEaP&Ԅ؆LDEh"J2NHGJaj4dJHTm{0n)N_] bOfݡm,מp;~`IzNJ:vSI> {}X["'͖N3:ߜ|sJ)Le G$7|Hr)-$,Ip93^A4EnS&1iH1-Ɯxi@ܲJ84OӚ{wn#GvrrBW+D1:Nqjy$ɃOմQ{mws7Q^8r}^z'=#+"l~NR-𗹗$7_i4_~$pL NI&m|9::̙Wt[enXgnnG:D2T 7IZFNL_; Xpsހ.fNGe7<>ԌumgfaǁxBLЎz^&uH ]0wwiwz_G_ yq$t{4 ˶aiz"'䆉{!d,a}3ផr\5rFȕTjJ\Qq|UJM]+5tЕVjJ\+5oyCE dX೻V}p#‰@Œ@܃tl cNL&:WGVǺl:]g2_²vWII܇E+ŠKl#pCXT ,UcTIӪEbٞL{`up6g˺ cVu:ۡ3=5@q̃ ͇7.lm*{^N%!rx)τj{&Qs#G'9\;^s;XB2!-t!> ${ `1,qGma#Wwgp#aLŠ{rv7p#C B?0Xhf64mB`bsJ;xa:z>VΎRy| Y _nt8$1}, )B_9B֌ܼm/@FTIXhqCa1YfW鋝N,B^n.0__tdg~n^慹yw{c_ig{űP \(tLԬ[ wxr:蓈 e2"OC7 t>Q88pW⼮z&禐RJ11oA&m: 7N4x;b6K 38JlݱNotma?M/N="xB*8my|l(x-&Jޜ8vfk9Ίݣ$alR{6+CS)J**qLn%ހBgyk-#~z):}۰ܑ;8An{f:_h.cX+%8(GM_ɸ3|%Rl{||V 8zg3$l@.g{Jgp؎I'm81[%nowZqvUzJ+b=:0OZ!'8OOgqĖ~GWEtܴT2!nϞzq8ia0GŲtҲ8RN42_oqEqkOsq˹GOWDN+c=>Gۜ/;^zjprl}[nL𞧂z5#gupGBKV Bx /BJZC5NOiY} S _Rs?D4UbٜZ~nߋgx;F\ _IJ=Zpv9I?)h|Ųyż/6x?/jВ-YbR@Xd jN_|Oؖ[/W 7t0۹y8/C|&?m%O>H@2=DLǰ/kԑ${\\vOל1g\3λw?aE];/j1N_/Ol3Hru5+e: N_%gO{4vJm2Υc+v6ELUBGO6< e;\i pdC˧[641i S]tj|w8'9a5M>N#ߍп}VHFH42xgLG˧H_4fxz:{ 7,^cxW‰:!e]hrY :~?:~:[쏭9%_\:%Q38x&''=I$Z:xm)2)m4ĕkvEv7ۺb9\tŲ5:♡3}uxiܜr+~i%n $Yn <_R_Wݍ`dvO񤲈us {||O+ǘocX\4xYцL"Ccħ!<+C6 p 8fL0X/@[Xn,j,ܵ]}q|sGɝ/ |Oʉsu7Z^D/{jUcU^oyܬݡt.oVPe-U=7znYfu(6%7}Dn[Y +Ŋy0da?za|OH91҆pD5m%B8 0e>C)Jf}VJQbQnV%)h{J\t{ޏ ؓA -z$Tk:A [ܠϗj>`P6gQQpp;twlVpZ#lD]ـrՒ^ɥӟl4-&J8pr+a뙤p{!e/ўph9W˺ǜ8zGkwK<3PDi %R)y W渪\ݛV氪{meJ܎巊*M֛BqzS&ϗI a}y~޵egc]*70|*lZ$ĞYR=ltttnюURGoGmeF|_,ENWF5HgO@iO8z;Ac7%^o$ǘJGeR!F'ϊXf55M*+jDnFVTVT6#lFVYSYRYCYRYq6GBzW_Q qzV-[Zc[R'[No9۾p:؞xa%v~ist}Al[Z%c["t0hZ罷置置':u0RK)>N~'%җ}/D [7?7~{sy~ "afʾϕ}*?WMۑ|N[-zEW*E2UR?g :x#-Og2%=`y3Dr_$/wX {'`;$M%  Z_5Q-HөP ,#\}%tF+vXtZ,<7I7A ㋐b}nP YJp)`R:ɍO #ף̙p%JA ~t&#v1=qŝ~; k,YIg%aaH*:*+&-8V+1ss6xP J+ؾ`۰q;wv?kĽ''Z#j( cBEHt:Ws`qpm΍NS'Ǘ(iJtc:θW\__8rM0R" o$g9K;b~jpPFhI6Z yn^W"/d\q#XI83B3 Oui5@[㋣^?rݳYԭ|faܽ$, u哷wmoגܗl۟orYv#?f-lżBk⦿)|KG"'fٟp53e^vNt( C>>Wxnt_b9^r8txqwG?8wk]]- 7cҒYF\lYd+JW&ۃcNqNϷ6z&̕k+u i3Yr+[`I,79Ϥbrk i{:gL;&7p5+{ hu'8r.P '%.-<ﮥ j7,x'3mUkVIEw4/fo}^kI_4aK?$NnJ:_0鯛}mD/{Yf?J*3{?!}V7qtv}\%-ǰ Q+b ML \V>qEHBYg|V"T|яiW1Uۇ ԇ} B=+bhH;} ¸ټ\(W:I8Ł;`1,C;T_pI9L7QnPIϊˆ"p2ӧdOqc2U _cvɌ91me‚|Lg]pZ[WK,+M 7k$ڞ[sK{n7׾u=*ONJ87J8=3A{2oF,ޛtVܺ8-NwSnL#g͝ɎG )mnT&PS 7ĕV#׼`M%8XM$Eo&v>?9Up tx?M$1߄CI1߹fu[/4H;vܹP oH;I/vĭ%"C`mrxݸW#lZ;6{m[7lk,[QWy_W"Obl?{̯iƌ06T[_k}}J :ONݲY ٩cvꔝ$}+Ex\G ;uF&ZjHL`ۋ ,@7 C7boa!gtE}#[ܺ^pqf/Rfҵfwxc^-t~w]nۡQbBx¾vP1#vg+Zw*2; g|Oxw$ajoL=DNq zi-C9Q0fzL\}IKöeh\|391f\=t5*;;Br/BqVS/G8V bI4'v !rFb^఻=s=s}}}ECIl/;Θ[L~*s a??:Op$nI!$ynRu>w';s׉qK a?I }B'(v-n3ÂN-> .0[lO[:sfṋ^[}0a[3߭wGuwk+ҞQ}eD+d|E]Ю'פXw|R|'vm! 67INϾ/4; s+߾Ū;8}]IWp;ł,"[7bүc?gu ={w;ſS9]۽ofm??vH7;8kN&[ݝβcorpr5lb,~7Nŷ'$y!`o±Vg-qz>>bc~m>DI ~\/Ci >NYI'J[9JZ=+c_)#|e!! *Y?,aFdHeył ewnk>6_ewlg9sl)iȰ9Nb^NW7/B?RG7bGP ˍrx4+Jx4+Jx4˃rb͸s#߱? ͘wǿ/?a9?>gXfxcX}#GG`o|XDH>87*aѨ5hG4hGs%)v2*6)j'g ښ#G=#2rss"؞C;7iq؞+;3#o"t֤֤֤֤&hThThThThThThPhNhNoI4gG-`DsrDCrDCrxLhJhJhJhJhJo i5]3oDh k/WOAr<$SOAr<I瘦;׃""lA$2/%ܹ&뉀qZ\"+5C"oe(q5ۯ}=,x>z`hzYGvFx<LYcn™45 ?+;r+]]WiUu\y-+v]]Wii.J-6Q yv[yL>";'8cP&Y&YeuBRy&L^}DdAa(Cӝf*zc}Mh38mO_h3};>ӇAU3}!f$1> OOo8}63__AUgrbGrœ|3_g|z?~&tg3fzA3gzA3Lg3~fz?3 gzA3 gzA3^̺Bqݶ?1Y4ffzE3gzG3gc |5PLzvͷp|]"$U BXWE+X;w4 fG`jzΰ57ל2z"OtށB#JD@#;n}q8|B۟}$[٭7O^y| Y3-V[!h?Ey' f _e: 0d9@"e>_v 3~{ ISfgfffffĝpdO,C'Fl+t3VfofofOό 72s}&Rv[@+WpGOŠJ|DE7n|?_(n!x3D d!kn7$TDDXg$NZa'1jmf&g&g&7* }3_1{zf#" If6"JT#+keG" ljoqP;*Qd!I|ק'I{Vw#s="R] PVgԏ7wr. =&b5",17% Ǚa C7Q$\q8nIkWU4GaU[V*_WU*vTYe%UT+S ǬTE*^ SC2OG/FE`tP>z"8fbu}Xk(x8 YR*xVvYuG_8g{Wvce To).;DX1aT@Me `5i.VhAc]##^3Z&#.FGt57VVX&jBPbOXqáEZEX+Bܲ7-$W AgV/OU{@W,tVg?mN=>{E$۟xOR?I;WB?!V//TK3kxQ&3+"Y\3?fφlG 3)ƞH1ږZdrES~~X~3Yzj"Odd%(AUsMV/V ~(vsxE*"5_<u쾒ͬ7~ئ&nXP>P o|د;ŽXԋלv?VWmG`t8;O7|^i!jχ{aDu[1_I-J0oρew%aƞs `sL]}Mv&eX3Yo\Ҟ{r쉛!} Ϥ}7HDqZ]D u8&+ Q7txnFGAL<&.PN4J@ܫ:^>G0ebeRD>^._?sݕQVv:Y75M __0|&7r]F?`D8{Z2oY\( cn*2J+.;C^qYyc, vMcwl%&+ɪ@0#̡p)OIak_alm 7paڜyFGI'1r"g " qL 83  kDCzJvc~7kzv@<<&eռ:lc_^p٧D<m_8e6өx0%+}dW]q_ ssSH|f2O)/z^aqpW/.)ޑd{G)tԭ,.;>,SC;4>0;[lI%au0ngkIvup8^j] ,Y&}i|za>^QnF OEOx%5tvAO`xL5 @e~FLhewLlo# ;ڃp8Lxdx!΄΄΄h9#LzivyJhf$MWfSPܓ4QE^\\w|cޘ߸O|ńCSvgL;z"0?$r#iw4miڊ/0"&~d/ҴCH,~Sq-% +6fP{R`& } JK%\ΜpA:z{˼e^ܙ+_/ʗxK%^/o0W{F'i{&HvH@({[fbʤ֤`ܽL;hn43"u]+e|@ rEr'glùn%t| 8Vj>:U3唄qEJE( {cDV;GaXN9gbDXO/p;3ndp:iMs|_1fx+Tqؿ[n'2}+a+T8&Ec]r%9x]Z^Sp=õ⍻Ks^]s^rinFB}Ј0}<~@u5 uBC|ھڪi.ϛֱⱻpQw9#H]~s;+`$JdE񾏣:3V~,$ Ufzy(qۜHF+ .Hq^^c^Ӷ^^`fF|VG'Xh=9|+תI=c{nq '5'$p|7qvO# n=9b24'P#ZƎ@Oֳ@7Yr&YDLz ˤ\g?E*,rLe4ur3`S\m vzL~*,9_ipn©3 DHV@8X߂0"lOoAH"bY˙Q@xVږke%sxLjeesgc]9Wjeer1\1Q9+5ZM^5JMSYiWjڕvYih'!R"iW+*H/.-FVmx  '~'[|((+a<)g(ggc.E#r%7Q;DO,{櫔ăyp}Λ:OO]eWV(?kxG԰m_y5qe_YFMaeX^/&{~YOx&GgU)wr"Yx&'!3@|**:XE'{Œws?f=Dy^[g~U }X9=  }8yVqaŊV&B{&Iu}r熶mTѪi0cK])=1p m܍}sFR,u'̵:QOx$Rt&MF6w*nԍG"?G_aTx{]tAY},r#us]f9TPCo9TAp9L0o9Lo 9, to?5"/VUܿܿܿQ= sm+=.a~9jnq`{Q8lW{]v>b=bc8)3Y:m!L'Rw"}'Rw"}QܝَN\?Ǯ B'Mc{M^̠s曢n-ēI x2^!2zRgǵ~Xf^_wa,zⶽ_5"kGhwSyo- $-F=AVѥcK^JxbTe[^~+flΊv1X~+_Ȳ-/Sݳ]?}e:)lN*;* ڈZ[X.V?er8sRu@9/}k;S;p8w%n%O=xBu3V39=մLenLra'۸nGi<=tHlFЫ=\q9p9:Ҳm4ewc'=A#nsb~s>gF8;B恃Bg3sbS7 P'e(ZaIyÒ%2[ڎqe$I*T6&lLmJ*TOeCpPlPRو 2+וK7/>HE,b"9 _BņBJixאz5ޮ!5$u 3kx'YjxrEOqe#͙\w̏å[Iq9L3@eVzrDM^׉P=OXnLLAHR*i7gg_Uk/ v|w#$~< b\p>>_ yR 0yRF'eI(}KY͑ S4yFBns-"'~DXz+},$k"2DxVDzF%wsjMـdP:c2}h^sǾb_+t<+W}^ǻwxR'Ӄ0Rk;J>o$í{BʨOH;IP ]Fޡ؛]G.6!8nmmMÿ$m5Ä_ [p;BN߾Hо(ynNLkDL Q:K6#d~3:$ҿwY|6t8w|faGh߈^=z3=IȽ"f̙h„ v^'؝&xM15oB) /3nCزϙ) Z"iYg!eº?͠X9Z\Qꮤbz{nw|lO"ppsʵ{*!9B_ߤ6(;V«,0Ap#8n{oWDDHa!!3bI*= l<G66y0w&d'\ ȃ.װJiL|];ܻ|}cOQL:^>?ǫBPVVܴ ,a*GlL ԋL tѱy@r=x&3@Gj+%k$57I^fwkF˚ I"ܘIvL^_aH 뙜qH P~~L[+/v~V*yr^W*yr^W*J+EW_nM[rns'\W΋%8ϕJeRY//Yɑk7n r } } } }z|yB Iq8u8pÃXxl_<( E aJ .Qsy& \S`5dk-x\/kFJ ҅jtszΰ9].UKKҕjJ5tmZLl!W<-qIwZ,!n_תe+BkXb|Nt{zYQ ;qj+DOtyes83CC6' Ñv_+Չyg 3%%+,C`bXZ>成(~&<2)mu.`2$׿NQq1VkOSivodSeg,w;g{m^V%_"X/yf!7C(6d-adfx7V #ӽ!&XO70SԲ{ft7ʄJR0fqZantzYbݗaNjHeꯗpNUu:c;f \lA&fgoLft I!eK6։n +D{s_X\{0eLj7kMST])i\Mο'!ehG"t$:_ zv÷q2q8MʰkF-5C4q|rhu_|0᭤G>¤B|;i?r:рÙbv*WI;=+fPYϠ WmeoT z{eYS0ؕ[]~*>B[&[]qBCW\ܱ.͑qL"XсFxV: yV7⃉S㕣Y">^9dà< I9> )·~lO } 1ѹ17"wxMLodNOkZZD{^9f΢/?7[l {X.|48Pڶ?3ZnxJ~?kSWc=-nQݰ.-$-$_7D@{XB^nu-ۦ\{Y4`)> ;1;x}a'!dvCC{Ib^iYXnZښ^{sh!VJ89~½_9~ٕRy:!IwRTxvN޽&M?]T|cMjsTr.މC?;8Dj:y$Otea?D<Ճ8n&4n>7yo oٿgM\ޟ=y3qg}پyo>ߗ5]ϟ{M&Q|'O}[f^t;g (uEfzz {W-R-WnG?HZ6_+7x7JgT!>Ìlt_v-0VQe*V*V:{Gwz /KғUNU.۶\׳۞~|~JZ -JWeR0'^mja>8=ГZ"6BOHQxhȊ \8'R嶷mj6H#‰5Ž0㙓,$>u3/؎QPh|Afs>5MeWKZNhA={F_\NfŹlc~tԏLLo cEXdڳjIk$ZdJa9#2/ҙRd>}@xh,_IA[ڜ-u F yU͙, \ngjx2d ¸cC#9vjwwo:x=_bq0Ey__L>xN%IM n7W,+EbloU8 _n{znsr<[3^kT,)+M'rʴ< F7T\߅ mQ18|n,xvxӓ;@"#}Iv&.txwˠ;s-౮:ihwL.-;wc 1fܭäZX=bpX*wt' 9M:7ЎRV_ Ƥ%iJLVS+I,g/g#3cZtqkCr(alkyJk(aCIS>3 %ypz:l' mΦq++VV쭬[›Rp87T]>3IXF"gr*]Seͫ"pgrdRoU>6R DC,_3'PJgz%"uJYYU+oB"ae}r\|&L!/~&JvrGN^sX&/Nrc}ǜNs~hn`:]:tt0w:;˝Nrc}@LJ0NrCӑHt$w:))'rwoqޢg~VUIk{7u6[ܯ_p~}C 6,;l*;lF*;la8E\fS3[ eP eP eP΃$c|mKW[Mft88쏞p&r8#3ã}*v8{t8wl|mc>_lb^I7@@hd$_{S\Z ;HWd<#X%F6GHF+!ww*;;>k}vvTQegGTvvىsgTIJ?h;;tn'uggUvvVYegGT7eR.eR.L(L{2ͿU<=ۿW^ݗ3/oBӳ"(;{+k'3/N_W1s^k V}#ܘrj(Caz' G2)^{CN\633 mOso-n4;ӖE/E3])&{쟖>i#$D77Nw'mp_REn^WD.nC7MϛuXf - vM.]]biJ4%o{7 d"xݵ7Y -)MM?=#t[nmq{ǭdŕcg{wv|Ł}""#;?cgGqڞwqPXTxqgGFړRW!oMO'&=yNtxvzl7(Rs>T %YJviFP%_b|uGJN!9*YH,_}m=ZYp̙k 8Ppe2Q1kj&5gh(!?P&ZQbp8:^M>0ᢄuLAY 3XH9~)k3I™T1eǧHÙiwtIJ:W'qܦpgRN?;K'LL|Nw' &ݴgn#$Qn[Hv6Qc+&kvxz{߉T3):6#*p69eNPggzYu~U+Uٿ8p#!qG2V{xa|O+] \MwD5Nv:W$%o% wO:ZgDBg{ˣ]m:g'<>skÊ㳧EV;e'ୄvLtVL"w{eUXpĕjaY5=+ʊNY˲ApF,+JgӥU,Nl-;߆vy {xhh ᜤ`vўvo/('T^Y9i"a䕜,2ywͤZ#[2H$ekfHk"]o_ktG!i! [|_͠;=x]!59=xm!55b1(Љ`H@vN;$; o%S$"Dh=B"iyc;3ˍwC3鿻6.iQ\/vH|Rq=#u8$RLFJnw*)0tzWFLR1E(#ɩGLHwm5ߛCn%90DD<9n`Cس#ac7]T= m /=V}i+)CͭPCͬV Ph3+i3+WImn0ΰdvfWͮd]6mv%Jٕl#+FV ^(m0\V:ds xZ]K>ǫV ڽ:VQHڥV"o6Q"t6EklR.,=UG -dau`ʿ:Bp*~u Ϩ1UWGRk} :L=R)٫3ISz"BYYx&0Ž#/+A'ʽ"Aol:xS _+uy &KF盩%AGɘ&.;{, {:LltPq,Y}~N[Kϛ2,fLg)1!RaYMng^l _eh&(2'"].k^0ٮE9 oU ́Wg/|_,Ug7rB·n|ϨrS%a% /l~m}RX)rupDjuzO`Ɏxeck)ØT=得ٴxK/痮U>M+ vOI[dmt3FK-93.kXۿGZ[%o-S@s%?}l˚m|a|%|Jo2S~Rr0hI;K{ө %w2tu)+J/ܓ:<%[4Bt)3/j"tn;mompQ& "@@|C_WgP3QٞR/5p) Oc7p*&`˥Ypp!;".9'"kb/Bg"5u9.1L^E3б{;~˒{-` 9QӔ(1[8Y$}M⭭Ϛ.%!G_-!<*GF+>h.Yvv3`0Np&@4m2j)TǧZJZX _r$)^ x*Bs؀X*ON• e0\6S27MKSL1Y_W9L+MMq}b9>IJVpLQt6X#KP(^14 ]]HV6tvavSNGer]4,Kȏ zFūݬ=15Q)t:uNϒvwKqx|Õt9ry+|] ^Eji2qᰅ$bU9XpIIƪX̦ @^3A,4/ [Ozy_gYlFew]2|JW/ \GLw A.e z|&r۫3B\ɨc#F RVX A?T7=#&+A2X؅O8. sz=Nno+pzf3t 6=M\0!ZI ֔U5ϼ_V=§ܯݧ >!H=FK#!rUYd.d7/PLV?:D-| \HpXp*S[8~8S,d&AȲy ϟYj]|\J!ô, hyLyL[Tir?TkF@\E jj8CǺ|L8JB::: N]Dʖp\e9Lrܥof*\rr[>ǹs_%=&a}^8ttqU~Lč6}ܙ}R"\L5&פ p+ =I1`?3K 8w ٽDJGByI :~L5z,(dU>Hi/QN;ϡt؎^23!{!VCS ]p FWtNikyvNE^jBJQd8PGⶩ8uhk+w>i0&W^!)3 ew .~>F?ua=>W3.\|C>vH؋]Dcqa R_=؋;#[0AƭšP#LMh y&kjb[JmFȶtخZ4(<*.3]S«r0]X3aMk+1g0vn9M_!.]A¡PF´-81B'a#FXx1Oe tz,\*≄RjY,XK ]o&$ۥ57?B͑. $ JL^ύi25.w[^.K2䚤`vYr-]u~RXu?::+W::[Gc~0la9 [LJ`E8[LJ`t?>m\@DO~cZ|sPI iD!ՅW1)Ϩ&Bs~3.7 ^4 YU}Io])8\Yǵd);D<< ]n.dB{m<~9qezf[z=OdL6͠W#?Q/J0K ~^2^+8l?/Ly\NMtϳP~~fr[:Gk+wֈ` )1>Z9rGZ0̱>z-~>ϱ}?H,Lsc&Kc}, {q/e9>d5L9߿e"CdI0ܖ,*WO[6EQhZn٦Y?o٬./[)g 0t(*$#mBiXъQ-M yRqjm;&[ĎIbQHsSEt?LOamsq͞vIeNXJ &nV;\ȷZj~![h;yT yd!Ua!- Zճ CPهD.tw;9&kCڅ_5U4?R.Lg);B]S*Յ[Qrׇ\=˦?tT S+T=# y ;R*ݴwL_ TBN'cNou3Htk;g,8[(gVGP-kg 1:\/W-sߎdmnC~H涐ҕGC:0©t-ta{*>2vG6# RN;5GQ,I~'sKyq|UHgޤNJxќ?e=^iΟ+cYsa(4 9_uA_x\C\\kU84 S)4 O>hSL[z☨ e.[shqNv GGHV!{\ef8b >3})~~vx| 0a:<";W鰧{ I*s *= Cˋ&Fa*. 3 {yqf5T n)\@MTHM; vUNhW Jݕ])[J0lݔ§p즜nJ?˫gr{&:g"Zgrji \I*+'Y&X 4F!_FbTSyop({} xAssHQn#EQ8]l"WWCu+ NQ[M(7m*7AN [Jz@ycMw?!ՂӲБ6"+<Æ'HO15(wI2x~Z>Tϒu t1 .܁h.! ! ¥༷{Hs GsN Dr3Ch^vɝ&.NCzM%I:$"2TZj@Է|kӪpSfnwrh C&no#Oy' ε]W4ke.g],0] ?HlB4] OXHq^yV8潅|˅Wljݥugu@?[wi3. k=PŶ>.|ZU:M00E: r7j5dQccuh,V8v֚n\\g?v{յ }UUjf1|Z(w>D>D2j(Rw0.n^KeYpc,2.!tzmߤ]0IzwooteTp^ᵅ)I#kBeKK!CE Cڢ孕VҍR!&rWxےmV6W)&:0#X`fmtc ᭼д'WU ոWSAԋ:4蔜W=1]յPj!z2Nuw}MJ!-$smNN$$smND[ !RI#Zr%d"`@2MQke ϛRK,̭黱g!_sJ \sx-Y䏺IS>R7<oT%ĥr 伮 k2"N{HM朂j>a@/:ҕ;O)>ݧ\Ȋep}5@?Sw5 |SA[U-gt2x/.aYY-9Ao^HeV~H|!Ӂ9m0 ~W?ϧ|y><.y> *qXTQ<~w?ϳ izRzRz.z.z.z z -&%KKKMtMYOym4FSޅt[Mt[Mt[Mi~鶘n)M©m0qLC2Ie֚H 7Tnm&ȩ:z:vaTXV? +O>B^%㻅5:U5.[0u,# dl Cj~)Z:e,"dO|52S v}2-7)LR'HLz#gs`Q[ SAlylyV~:>5)019lT/F- ZX?aظEظEe4 F-@øEx^Tu9{ r+hJmr2T-'N9{ v/ b314k)^ ³KY ~ASxf-14kyxbC1[ neNdlS $M̮Kkq!R|H:/:혘)RԴ'_)T4`SӚB^4][¡t g&u_pC(Qҧ8yѺE|݋k"b! y7xK' Y3s(M)|S!ߍmOjauaa?ԧ0̶f©\ R| *t:f}/TuPFmW@3qzm,wGEۮSmt8:o5d~tVhO!w C9[9gl(y[o}ϊ9jeS?:+\뺸|:4,0J@.g/N a 9Iue)v IjWB+g mXlj';{+Am<*5 @w> Sᘵ:aF_T2 -o{4˕"WW<,RYغ:x [Y/dzتzتz!MӕXa+Kw[Y B KfaT:Ӆ:\^8lw(vw=]dt i:Hn-v6 W,Kc\)Y6m={r#wJ1˸ D!AhɲPqg*PQ(DxSā%"1&MNRM!M1E }S=L{0E|S g&|?S~&rjN dWgv٫rҖ D1Ðj%`n9VggkOa + Xmmʽ4ɷ*hb,@M:^ YYⱹ%ش!BZiIL6d+/k[%1B~%1\M$,|G\§0,r˕ܮWt$Om]kFRYKd+:ϭ]B]ڥ-dG#pP"Cv1 V~NOwa]g)5d43޴ȃS+ kGjNHGjNOї@UrS0UHLePp?nC T:Bԡ CA 2\%v!.H rIttlTC:0zpoEf;//" \@|Ww߂.$+{Z_Y+Kz4EBîn^ rDJ?.6S剥xr0/`G羥D_8S@nn\ozH\B1~ P3is0W8*L=LYHGySx/NZACrm$G&z^+A2ȳb޶: -L[CH7:*|B*0lh1[nŅNml7^6p,V3$m l2̶OY"ο>D,#(f)_}i9ANc:աd(<~fɔ!*PHdrxȺ&^, kð/zbk&:(qLIkf ~_poXPK'1*pi Cz/'[:t#ҝ-9*ҙ FU:s*ҭ"8>~ܨƉ5:bѕvKJ^ĭ[j,Emk1P;_Y[p1Qak{S7TjVnQk{| Wۋ(Tu.f ÿ+SێBs=jۑ*_F7 W#]ح;H..ҋ"a_ReA؅leqѤbqW;4OdG' JwǛɉ>;7h?| vO[wրrw)k7ƃ8ڣIn<N-̐yul+ֶ\r /L Q5rߩtӿW^{S=ǧpzZ&3^ÅG2]!pȞnݙvka)P$gJpG~;gϱ(Q-;_"+/~ͪ| 6f0;w;N lVυV1>cU~> &au 4YN톚bM3\ z"Rƒ] ϧXgȽx`^#_M P:eۥ .LN]a-3"5]F9-CdGk2\u :RFk>GRu; 8=}OON?C8F("OvkryksW1:…W({>̚wZaLpw(ex/Se *Wъ8vv.NÌ 叚o$`2ԫ1ȹAӺ :Sudnct!jүB!](Ց9gCAWrOQis:?ZH t~|ۃkXRdm/g0qO S^a(G\}ۥ1 ++HՑ谥TX{5>d2WX'Q}pCOHe{Yp*|Ƃ 2叩o@H59AqVdprkX%P70> ۫5-/[[Lg<.fM8^ 6(}ւk`?k5؜ó+\heۨ8 EzD`LXqsҚ|!~:'lT3٭O1 W:`?}S'F;Rs嗟0]tynA7I<7 (3iÄ3]9c/{mލ:Տ&e|B~QH?w]&P.39:t1^ӏuQiStS8 .G&\e*J;hn0n`)&y',ds_rm> 8Y&>cӰoG?gpJ:FgTl+\taOJ]->qՍDr`6n2 /zo9ܦg\;}`tEξEB!QUȡ?$}}5A+?HҔO&k U`z*(<ø8u7?-430e"ǁdbBvf `;Y]1_%Y'\°{uK?Jl Wx+<}W?'C pʟAaȟY^a=0Tt:|5+I&麖]Mj K>BCDOMQH&ʵ u *LVSXgTn*~vN]§rV/R{|_x"5fyanagKdu-MV#\YBtaLߔ;”;[dGztl/_>ܵ(_״6Jf5Rh]l y7L7\$VgOg*~H.^=Fr G66L.r? &hV*cK\I:-q%M}/ːyPIˍyPLk c Yv=k" ٟI4qZ(U@3YĪ$@~=]A>z`3aRw=]lE~z{.ƘJ/Wڄ]5'lDj0vILVlY.j"ہ5fzHt' $&/}~Lf0@զOZ X3_8 qPHOF³?}S=¸.Ȝ]2yv`X򬏓Ukgz)oV )⮏{-wb C(Vu ]4.eT<h)9_z}gNK'qL 8vU@*v ^Cmr(\WAO@tUo J+ܴҹWݏqnV:o~εp.WUϥrb+έ(dn$LXC5cmf hʭjJn-PzPj6:K\Z Sn۰ݶm_ նMIݧb0Uvo7dQoIW¯%wS`, C@Q'txϿꓔDSU#%QxU)v S',ICgWKX]FtGZ'5kr&ӄJd[F \X_k܆ .?Zjpb~tnJ&?Ήb')7 ݯ0*>+!d5Lecn!{i-2 qhIi&F.LtZO6ݶݶݖAT)rG0ٿʵ~m!Tmki?{ӨlUo?G5g8xc+O);"[nn9q{X*) tƕ§P 3*q-Ju.s4q[H : *.6`}Oy2NQH٧N k')<'{Jp+4S'{J:aS.R=raNڋ}>kD]C4<r빕qCr6{H{iLaͤE6&R#_ȫTzeSi/m&.&pH^Myy?Ra*m.Ak&'/\1G`b/ a؀0 }pt6yEe /foyhho PL0 }Pv qPe ePx)'.BCaR7;w쥗 ϕ]kgMgEϊ-BX4?_֭ =P N,` e*(wJl`au~?{..B§p-܊1BSb.Wۤd8;\e, rH:v6(Pagޓ+џ}۸)W+}R붿WΗ'w6)W^o@Fu~fګoޮ=e}o^z⛓ |SX>??[ga?2n?KF!'M[f1@:_q(9\2!T<%6!q?lɀSu =F1DMY 㟆f 9 S̐,\,5EB.<Ѕ") 3I(AXW8xbms6Y& u;p<ALR[;(RF~9pliEF K(Ie|BzGӹ4kjj0RxQ鼮ϖHUlU;7<{LW{"; q5 9nay!ȑבױb|҃+rkjkbk`k^k^k^k^OzoGiuIUx=cM Rh<ŕ^EΆ*d6&X8!3:ua g)t\*Di_%N ecU:@{gһN:{JU-‡j~FgHĸp(pٓ*\p6 S"ĉn=)vLΰ`1o7Df*>JAd}3or,W>ud p_FsԽpjjFQCBv 3U8>'aTNѩ.1g J <:@a8u~U!/S>M.\ d]cyg6 >6r),ќ鲎aO 8,gvMgBۦA+5`A*R*=@A*]}N4>gr KPzI8'uS AOFszN%=^>̯I+a0hG }YNgu:@3|HtlW{{ p)iP:,2yXW4|/ 5dC5`U&ߡ5ߵ/…P~PPb3"JQWG^lPzbSH24SLWFrgӸp7*WF+6~fsHa:mCzb֑'@-PT6- kؾ_WG!u-\?{>m ݹ*uᑮ+J);r.Cz/d͉1XeBh0 ~RoK 8V] }.KݫRn*\xo>.Rz[\oktΡtpL`\|Ww˺p w˺Bi( zE d"+ "JEVDdXCdZB@Eı;9v?r8w e@Sڂ 0l̶ɛBm5l̶whf[xme{̶p˟=ޣm:l!,W)ȚBf源^.x a{mX^6$rm@ڀHa*<:D ^mܫP46o+ySx͛3j^m6qǽސ8Mhj0l/i[h 8$HQHC,S@$5]fBfv9 AQ!ǁ5>aET<_fս /Jh?^x9 M,/|zfp(6A3?=`]^@:p)}dל,ZKK N%ͅI"i{X G GI}Z?4k=>k9Okg-g-z͞Ac> ^6cR:$BzȾ&SZk7Y:|:|C2녩gY\#^X/yeSpC+t|''#aao\997,G s vvzj@r3<mSzorhP9xSi|Bg~SV¹ϡUc|V|k)g ) 0zK)rLj&Y@:AN,?YJ >mima~Uc -?[lI--<[/e3;?-?[_s_JgkUjfP{[fLuRӨxֆ:B}}T!Eۧow; ŐEX5 6\2Yr8m@\C2y*L@|iޫvf@aTt gRy?x!L6eT8ffוSx=хjv]]֕mTt=W`p=I{,#CgVp3~s8Iզ~n')bSQ'gP%dPxv! S"jy"e]±+,BY貳+YVxv Ov=:&,5&$fR}}Ht`6$_EBdCA)>~ ZF_) ?c nLQ+/W?ɠ ^(?zPxSP]gPO˅Ox>N7~qȾ&'M\F"Ւ0 y&FZH:֢ `C{i14/&,  +Ƨt|?c_+ =NTCt๚SEBy!LZc3V֫8!rg_l%̾a%3J)pX/Wx2\<LJ}a"G+AbHGā!hh=v1vq4Æ,ڮfرX讇BX؄ [%)L>J=z_3 XX/V닥]Z_ V j{SsIOXm]?vU 3MV<5\e+q3@Rq!NgVc#UR͋-B~mU m8m;򢖜d S!UV ŖTUX/V+mJ_\cg9l1l1m1Z/(&aWm1!^l1GEEEEA!t5Yi#ʄi!* _UF_YV _MVzAW |g2J.τ;ZMD6M1Mx/#eRWBޒ*vh~s?BIt\M ܙ,-wOb :lsJ@vq=lfo6>iƓxJ!$RhwGF cW/,VxeqBfeX\ T8vAG-ZJ  M KIt9ZJ HPr LZ9Z&-Z-?6 ӶU2;珷 OSz^0ng֕^(8>-N٬^'YBPaٞJ/t _k19iSV:&ؽZG:4ȡ2 )oɬ3![40)!WܙiHaAȻLGrp|LO Tttu07$+m&'"ϤY k>Mڼ^~^^Ns2iLIݥ I5%_ޔBNM 0*”;gL;N1T.GJ øWD ]]M"!7L^TYL&!V"0tt&2~"sy.r*˶K9`Nf3'~9kT<íхr\CeWp]Wx.?F.ïP{vt0@ܜhrY Zd4&cmr;0]ɰtiYS^H8p*s[! _ *vmsHnN ( c[g',|[زY8Un-#|&T lua(\:t8@B)覌ܖgI: U~RRB^Lx(VM0yik47 +[J.[.9.?o?3pC~Fcp6*>BS!w%N_U.=&x{O~. kۮ ,r炊BEýq|{69&s! I~R+T1Ak MV}E]?>m ۹ϼOz~L3f=VFJfTkkwVw>LS|lN?OG*tdr?nRdKg|4@/ na_Ε\˹ i)LHVS  XBO!-SOy "yjŞ}wWr8P],낉?/Xb}7K'ROʏGÆ5.<9ԦBSx?'lb)U/L.3$""c,׃Yjߌ<)d6"=g. ϧpȽ,GP|3&OQ&Ika;V2dE~ %~Uԉ,n)\Q)g:Nd%G{m[sah48?9:4iTuc?%h5_q0"ۚ"'Uٜ.>y_a nPp#- N{һW^Mc˽3N[jT< 90IԬRpnn7ӯtܢC -S6oSIia>-q'/TLr|뙤]ƼM5)dch~W_W{5_}F>2p)> aB PK&TzFӗw]a t|}q_p| \; {駼nhW* "۱1镨0aѬ//À '=rON{g}2/س=\.P˓ir;SGUz&&i&"D&%[~ tV&Le 4z~}\-_@ =-Mo=9I^n cߠpZ,%7=]A8R3=pt @(ӟkzLJ1= [.ڡXOL-4 "ӁfߢDTyry%$!Xِa0\`WJ9S9*u~£x̐(KN,P ʷ* KRg+J0-T9x^)ϨJ,fRS{}MX4&0Hn4qn.1Ej=j/ї0!CbhUZR?F=Oug$(txVCGaYWv@?6tn?*K\gR'^"kVc8| 5Xf@@/,O=OZn~CTp ߧxWIV'(0nG*^$6!Q1Bt%8dS[SϓK%jxI5BI,T|^Z / i2b¥QKKK++%6Zc_xjs+pt^Na߃Sc4tUxRaNT)~cs(<;PCTߞM&ʋc(&.:8֊&iOD\mL{ s?8)nq~/3єa|WZ(=SuBjqZE"Ma芻FnO6sɏ. 4 oYF)sx2X)CqpPm.'peb.xp,0JznnL\ۛM*T;ڹHNE ntæ4ݠ5GA ^sM7lzmnt6pn%@vCe7TvdO'c8? @Ot*Ia}ı0΄p"DkW|D c - BJgA\2m yaJI r<%oZTӴ9͡9ԏ?`^:)5Pe3o+|v3y\aK^] GXxU?P? ytP2+t90+vɊnaJ[+ĩ-$ҤS^80Hb475'{Id`\+05jM)`W )D 'wv ΗS),1*TݧqtS ZB#.WIk~rNӊ\"opHn]\" 37߉Q i&0CkR%aA$jQ4 ݒ@jYx2z-7 , x^11uLj"HhbakkMʛA5lmom}έ-ϩ7JPʅBʝ-)%+ekgn$[ͅCPrݨZ-քʇ-jl9;MH`&6t6 ?{@*YYܖ:*eé,`zz {H (PF?~_\>C82 Se 6@D\E2GWYF)]d!͜fN3(-LکV@ xތ_j3.ES>!K jRz{Fr2/ }UT(~d_݇ kU{ '";=k?Czf>%}=cdMaɚ5?IڐUKym#ySH ?cMTxHT y\pX$3/ҕd~M$5\yԯGg)rѻ %T#,҉ڣ3 fGW Uڣ+Ƨp@ԆcϮ~ GWxU]?{tU,~F oM;B\ 0MKwn~B>tPtՍp~; M^fRNɛCY&7L:>]ZUȭ&5+)G"X#L#$b,8./Bׇ5F-fQEq|2M0X^./F ?+9t,X~v~ƮSlN+±,8S!5L\'@@jL1\j F5P,d[xAƜ%CB?a@{!cOIRx%wf U)WLkT::=(F{ N5<'&DZVUH΂ht'3` y_4.geatre:YR:t^&Ϥv!8rl'U"ߴi?WOdWm]+r|]eTz.g*}N.kS| {]ty9,)&ۤkzgX4?_a3 ~~gY45z?+O4? y3: ygΊ o<רz~>ꀄ #ֳlĹy~^9RuM\bM*!@Wl@?BsTaw^n32*=NF*S3\,t8lVhp)z~̲eRyiZ\P T^0yM\vF7pP L,re 2e ^h@ݸ:7q*?>J p^{w`6Dګݐ=&ו_8(BSҙ{jc[r0Js5Kݖ, ه&JI0Ñǰ[qHe+ĢG8FAypskZW Sx9I0 pw90I` MKMl"ρƼT㊳E! mғms J]O.+9WQP@3ʁs,Vf6!ꄲ*s,Pcm@/wVx6C;[C=aTO#l?zV<%Ҟ)|_aB8>)z=qX]cS: yAK ^˧t,2i/;g 2PУH`OZm;4wl ¥óZo[j kxYkxó5C:i$L4!ܖc0]@aρ {^Ts[子&į_=:Ve;Ve;Ve;Ve;Va;WƐ@Rtovn\AVzOG}G}G}G}(p#Gy܉(;j٠r;;+~vvV!hC nq>ǨRgp1T_S ,x,$x,x" 9<<<-xZ6li@k;`ړ9-?xZSrg(% !.|V, N;O }[ ?p BB'6 FBPK-rGZF#Eq:*=uV!§gN ]%o C Y(<+wX u>r4¡wPxnmi{MkNtD¤p_mRdMfwQƆ<)%\&'BВk`k 7_B %W˂O=J^sSSB?Jg0>w9§˧ճ"8pj\V%W4I^W8:;L'IR:-5&3N'W<8A$v+ ̭|"t^\\B60 ±[XM~vp j,W?;wTvvX.޸tə:A^,!ӵe;kB{'31-W0\ S\?O?<5-?=COXUd:&X!a~ fU*_jψ4`i. g/0 BZ|iznOoNyS=?xrcVNׁ49_c],d:.jM"v @w½.~Ffk{n?o?F p)>#K!_du!«|rWn at«+ZWs4p+0i/&"݊ǚ5VE^0\ݜ{pqXקaקa_ka\_t#Oq_SBg_F7Cg*q~tJG}Ou{z}v}v}v}ŏq_vw~n8e2^2t37:_U~>B7z6C]&ɐMx:_M!±47fE3KbUJ`F y RF$nJ0.0 )k©(w/6 ܱ\xF!)ap+< S$Yav2vB}5+}۬y[BbmOja(S«p2K-tx`ܫ0U4{iˤj0WA]\cc/TjWR]ɫ6`޴Wiu쉽®;_EEm&.v|t {mr[k˔ >7k(^|ޔ©VOlBaj\G;oh|c;& kܠM8崴 YM4vI "do-.24[c$(gf9(qά-˯n&Nn$+~O7~_~_{HVd[ _ dז[Mngrۿ_/Bx~ŷ5ƂX$ʞn+d!^8ya Yc>0k PYcnW鰖s~ޖ$^?kTzznGd&4%[͠u8: vu$x0{XgLs4n-K42I:]抅t)WWK+ܡN#|4',LkD>Zr#p{z=g8FQx'^1,PzOF>KKsbda(QW+giI ZAv1Rᮟx,hgf-W+gBweǥɧp~oۚzk6vNW[kZv:zյ@ e3)) #H,8,8,8,8,8,8,8Zpkׂ'_K|-/Z^ Ԁ_`( @Ȑ@PUK2?S-*|QpC@?Nqcw`zW'[˨"Wm`Pŵ˃͠;@G 0z b@"nѯ1 ț_GJ0Ɇ%(w// C%W,Yx~# a> a> _> ]> ]a#t]> [V?P9,rwK𥈫5^ _Id!VtBIB.P]UeU T*pa[| _VVGB;/Aew:*ePx:נb*?:0ӎMfz­呁h#.ثqm{24Yl ~ϙ"j!!\ #!a{#5#Qn4͐ "SXH-LĐ`aN'C2a{#:Mp5@\HǢD[uqsнh1_HRSg#aPO+|ggw3{@#RT8['bj>Qx*dP`gQ/<;sv Wm9$&*T[bzq5_<-t >P (pi>W~GL ~s^<0l&\Tv}>nyVn>>J[BB$?!%!n]RX{l]:Ql0e Gkm)2-5T<. [,t<0  o? Zql}%!ei&zmĐnفEیt^HbG[Mu׿^xw{*ye`4;Tq$63 hܑ,JͰfQTñRB]B{&Ce9Hp..Uu9nd9!8kdFhyOHC)Z3Z3Zr ƮE2<ȍojd,2;+BJcxX8Q]wTWg4KDpGL o蚵UoU$9d4z d7yOQNvfN!oX&RA V_,Gq& Ikn!RӘ ?#!GW&vQ86 C?2R?مH1=??UMB׏to[qh!ǁ jk?&^n~GkH"/H#yZ8|Ltm2 ۫,L{C;BًXFj3~Hva*_tZ-ڢ%0m2aZ)V)()(i(iiici#ic)cz嘟f7i)i)ic)ic)ic)ic)ic)ii#)i#)iG4m2m<%m<%m<%m<%m<%m<%m2m<%m2mD%m2}w3ۘJMlc*TTTdS6̶6CW1dhʟ  kCrt<}uB!NWd.QN:{ D;.p#]S8v )tL/ BPC䯣jȟ9&2!Beќ] LMTHTHS8ҦBҦB&B@cKII6 m$**FHl!6BMd6 yvA'7`r۽vobi+i[x-^ߧBX-,|q%jɔ|U>ӫPfJۃUN%;7Eًa 9_AWWߧ²WX[Mes-eWKUHB8 ֣"i$\+ۚgoos}{+\s(޶v-WkPF1=.Yhai ʆWߨ+t:z_)n["c5 ^HnYǚ:&7`K 珸`u\0DE TK:p ᔿ~Ɏp~WY)ܴGxqX ^{w(ʂxQ别ʺWa~ ._r}&H o̡G8ZS۾"ϱJt٤~#^=铖t#3=I/RnIC)\˰Q,a^(Hp(ms {Rx4*u*sKgD↻Ƨx-iH픮Ґ&i0ln#E4I{u?׿.a&jWLgQ cBZ+4(mo kY8 k :%lv \\LM*\^W鼭1>R9_W8쏋t)'d&sX5uU[ί[u/Gǰ5 W@Μ 1F w8),),(ܹ>=$QϹ~4L4뼯Σ>!]-!Ŝ1/yp0oOkSx^[xΫJ']ս+Y&d,Win̋e6 5g0 naJ8}Na S zwN׼4C()Fa\e`=vDypSJ?gĖgD^MT0Ys7q+}ݤ]]BN$O]d4*TN3F S`UB6Sn{gT > ?;H˩ Ra$M6yv3Ѹ iToThbDܷS}_9i[K nX(n =dCN捭~Z . \~;Ud G6ock(Qzu&"t>ak:[p cw%ckCik<]@n?Rο G% >ZWJA!AL=3%(|J7SL I{&g#.i\dXxv˅g!F1k'#.M6@Oz&nu7{Rx7i?WLh rǑY+*=(-r]9]F ;]vi&™ݴ^p5\Z΅ ʝ\a;Mi 2,5@殺7g׆5p?6Dr5Qw$Mұ|BNPMR2y1|O[2* B:JvO 1>[Ngu(>(OOܧ^K~S\l.DUWL=׽ TtzpŲ<&sp#p9&Nu?k ".+7-@VY6q "|χYcohǷ~0Tp쩀ϩ\%)uND 顏@sùlBB<:&+J\v'Bדc3 kbe8ьG^Et byEbs:l ]S1D5Z6_/E(^pMP8Rܭp TTj .6z+tl~vYnV-ȸn#4kmy{$CHJڅ,C@\/}CP8b>KaHHHlCO&=44Fٽ+(ԐH&j( !0<C^x y!/<ԅ=̝H&WD ߉$MLC\+k(q'@Y,-IEC<9hzJZ e(%5.-weF.׽ʏ󘙞J* \U9劧֛s\z} ča<%Z/r'x}&u:|ȈxߒZ `X% >2)vps8E@nItze(~}IExaT>e9scud6ye0E ԐfEBڋ*@}k'K [@!8˰%䅼yŗl5RTv.\.UX/Up>?&gv]Nb Jl\d6kxy΂wyvȽM/HDPZj15}UFšv-RUnU&Uq1m ibMII:[NNpѸWUFc ˶80*\ x ^ٖM.yTx$ 9 eWTӈJȞ&&"{.aJ k݈#ĖhkQhk e|B>͝"g«|N*=DZkˁcS:ŋt)\H킔HL{M׊D J>Uak^kwۍVK/z ! u2NZ4\!,Grīn;rKt^DHNw!* /Box\W›|IW“{Z-.|+E!]hW4]2V.i~[mry-:}法2]6&iB aBx!籐tٱQ*b57$ kb_|p)^WHRp)?+tDVJ*b-Q:H^. ;G,",@O]zp+Ԗ]xՖ_~ ٿyzf*}ؖbW\9=KvAǖ; %T3Nsf!AlbVˆMInݤ]Cӱ^a4EU8t]s*0\},w/lYSn K0>[Pq3m钗޶sJ>A&.P6鮙@[r߅5ڂd-5+ ??EgѶ姮s C@%?.rޅ[xqN\!f~d Wٮgiƙiδ!ir:;$t0@eUx4 9RB/DyKټm=2P4L%gp"A}[#\XY8 bN67'eiכۛۛۛ0WMMP1{s~{s~{s~{s~{s~{s~{S~{3~{3~{}{ӝj>lC\sϯ>lQt kSBs*>^tOgG9C,\* gG9KR-sX|8K,|*g,p*|:t=2\O!M0\w!0|tquqYu!6q 3EEo2l]SkR a֥:,ƶ.)aw&>M}*!ϱXh>;qH4|`nNZsp١n)ue$ ܤvJbJ m Sje;VV=Gp92PJ';ܹ]W2Hevݐ D&ˁYVAvn&b|ZC阺r7Ma}IF9.~ފϱt(>Sˬx.ͅG>sLi&OE1u_Vb+3TWt1TdhFyz{Ex!d H_`OOcMM ${ӅBQ.!c5ccc% ե ϩgը+rXx\gT9bܨ[Y \-5^PQ_[yZ55$VSc WwZ[ıVۿ6*!nSim>}ǂDf8|\V(vPXF!/, |?W'Dp>G'T:TP󙳬4 5abq$U!FlI>=qt3Qp6*5-!w:­t8y:[Rㅩ"Z«j-rG ]DN?;_IC#rsʡ #&.Lgm\8O ±F.F<MJYP5!#L˞$q4Tʩs{݂#?#5Cթړޠ Gޠ=C +{i< 0~HZ%\a[X?sZhw_X)a3ЅKtv.YT8^BLl/*2=&T:O:[6E KIjybɯ;t?{BڅEāѱQ-|ҕh5ҵɰBQl:tX;k9+%釬 0[Y+.V6V~N=?5ҵ«p1|YI׏Q}novq @XܶvLm3a"פ βp' &nw 5m֔S{wjW3)f=x|5SS{M[ܙ_k_k_k_kߩ&~Q:(d4 {ҏC?D0>v~굼O%~2:r *s51SA[Μ!ۭ3sN4t }{Hc3IH: R~ZJYLHYMȌ nKYB,'/9B+ܵ WY?3 !ss63*-1KBPp+~7ױ˥NXyඡjⴥݭVlmFB҄SiH/7zV Mf+Y**ؑ;|)l,e(}^)F[klҟMI)5pQʣ*dYZBzׯt>:>'>/XpEJNT*ϧϧK|JXx?~Sʟ1} ]upMŃ6BBrcqq@ hz~Ʌg Ϻ=& b=[~^ҶC[Poh p+IBwڝ9̳IgS ohR?\p:lAn>׆^k^6Z%iO k2Wo"&ob_M e20: p^n>/7 0ڽFl:r }S"F7%I[8#Wa *OH>/SSPv}^>/W S%-zzzz i;ӿmϿ] o!oI{IB/ x%BJ$ԛxKOp=v?',z- u \=a. tsϨxq͏?'8gL(eIH *±6y. "r8~G26M#I ?ݚB~F 9:. YwtP¨g}6ǟbƠʡ9:xy$mg8¡rp*t{Av{L:mGrMaL73ޱLVjw|(rWWmkZ6ng~Sȏ}=\S*Lu8m- B6?A?e3Q!-§]k>t:-{u)~:|!EO Bϧt5:Z7kfa4OAԓJjk2ԅKI䩄*!iRʪ1a~e]l;tʚ&wY 3<=kBYܿvtoYXS])T"t(BϺC< !D!B:!p+[4S̢8[9lxSsrrP'Ed>_t!: l!\]%T%zq"IHIS̅OY8qfP1Tx~)£tk.I3^Gq\\«p38sTtz L}2d}n6@xYT% q$ q$ː{MjYTyS'ħD> [HE_J#=Vp׈R {t~kr>> y; Ծb`8֍_kȮfa1NcQW7υYa\$ х|*=c$B5t^4t+(*11Q9.֩ ?:H7Ecc2)LJ EO3 @ .z%#*n*}LnWgSjT0} !; (Sκe$ ^*m1 # j# .(ZA0Gس>DlDVKxP@kT|h5/ݏŸ{kиNc?4~5B FŃ7D) pPlJ DŚ(tЪ[^55SCRMnHw@w9 PE.e2U4⽚p6_c1}L<UX{L1.2( 3ay9#&*2' .aз !/ ؃p#F>/)DK/ްQu5,Bś66E=׫0ߘ"tʯqff__cr@s!qags{?Po鿂[鰀 H00n),bzWݹU~*1MSGpKbe=ྊZP ImƍgNYcu:o|S6!ݳ()Xklbٜ,*@e0`'R }BЇ'`i~=-mc\DЇ>sRCz'`Q܄2ԉu}2JKP_,]MTiqrJ!2=77SxYxUL%UXVokⲪ!n.-ۯBC.;zT5` Lb2*uHLwoLX?*,-L:`9 ײDiYbcKjԫwI2)"ׁ*tDk8aQqLQvq:IG[3Ι@/6QiC $N3IELrH7SDa~ )J}WkFG LzHs0GNL0<&AaҨTʗOp+l''4" XhokȄ X&!&wtM~X^b:-\e>+πЃ8(s'0?n`g9X^dll{u粀l&p oZPc ƋEb ƻ6\_x!t2*=jkPaUIbRJV \@SDdYtfڠ| %,D\Ǧ۠ K)gb<#Q5G:pnHE2Bd/)&ېD|;m?\ŝFT6;_8.v 1!lLi(Z\CR(ݠrlc' 6&߀ =J`>XLҤr5L]VddZm)e4iol+/>]y~Bƙv#@^x@c{\]o%d*;F9`ro;D_?El%E,/πr2WJ@[r-\ Q5 z/$.0͉91ya@̫Ӝ?5x\\ 0P!c^Ո'99 JyTb-T]T cќ&S 9D)DR $&8>)g4j< `q4'NeX Ta;v\H5lH5._&`qoBeK䊸ܸCg0j/4Q̍A LEܜ4.UE*<x[ԆEFxе6!8~9l!L.ˀ3" Д.qnT@0%Y"č- k0耊9*|FI|&,y]baO!E`7!OKХЁSCx.>e[_S荩9~&]wߢ{BPšsŔDnQL{\0 HNdɑ,9FHR#Yj$Kd8)h< w#[jdKl-5F Qxt%L %dy8ҥFHR[P3=䥇C^zKt.=] gs6SKmy]nϫ)ՔjJv5%ԮbWS)Ź/`1N.tqu5庚R]MP;9]MTWSAz9!G\j}^m\z.u=KAZ"G^ ); 1watELKinct\ ][ ÇnQCe8'XΜO?b`׶5Kx4)"Փ joyivuI;encP֬^Sct {`I>zNoE^MۧրW֊p)TV 5*R$ͥ2lUw `PKR7bǭ5d|4MleTi "ӹEZp@HwF 3*A.2.CRU[hFpX`,ڻnM3 nc{L\X8rM?z&IMvMWߌ@a "Qc!_X4\H.#ӁcIڱ$!6'SrD \r,&*# tº,Xr,7AgZ[{7 4br3`_mD74!nL㫻hT xd<:dx#Ⱦ"0l7U,[R ʚR$ʴ]6Q@趂)ԍW)(kDW4LM"kDw  [-i?q+C1B8 Ӂƭp7 wp7 @kks  3 x.ʕPu-_&n&٧6Vp'CP\v(Je*n,$MK]0,H#M yfX-.AKˠgiYZ,-w;K˝Nc2pXtvX,-s9+YZ,-k7cyY^,fW3˫jfy5 sgy}! ̩no)# rT70A:mٜɰfC5PjW L$PRuhUgERXIWc{82wqw`?vM xxT5n%==)5bUpkI>"/6̝r=  vIirӮ7M,lnl{H{v&ByqB0mi-C߿qq mR@R@4T<|SxS(b(/CqDJ-Mqt0n) m)m_+٨ɹ"i2Ri[Oe4BTD?66ڲGR"/ՎՎL‘ NH_ٸy>wpM00ш͠lIEeSDH/ff8Ҩ//b9r~[-)]J4nf>MFҙ̇vC:]Aİ·tXŰ=̇vC:.rHg>֙o"5ÛM&rXg>Vo+҆?Y5Lo솹6%,q?8"ÇkqX%taC0b׸ro3sdry9< 3s樭Ⱥ"%:s0/2xA6jǔz5ߌŁI6h!7iو4k$R+r$K^l+ŽJ$6~FtFQ$[)Ni ǶI6"IrB < !T:$!i*惛MۀޅtC"nO#hH>s8 ڇ6uæf١[ߘ`9Cpr=_D j-/Wg;/S.|/iKZ/i Z/gqA/gYRŅb/fYb\Qr/gIP--K--K--@2 )@?a;t>nx^oqnq{q~HcV eRz7&^ZmF7htDZƢ)=7ҝ{AMЫ@I}QeXK9^ 4Q<-iLƁAc2^_E+bPlܩN+ J*_]U@$3D]m; 2U@$,5n"A1&fgr؈VkiC^K#TLNQ @t!ajx&LXnĔq1\m\!RrDuyJS;X`&/L@SqZWyY; DZ _#|N; ]b|5NH{u]-tQ.%CQU;d]9{~Af: D>G]"+D.Ǎx_5L$ELi5wAb-(vE r՟[6gC6pDtMy!ylĈxKܿE 6@{yqz@ƣz@@b\JBr(ؗA'//C{ |vh*}{bx(G VH2PRK㥗J|coMp{:A4Nb8(^m7J?ھe}0=v4q2T:p^ޫLUzt6^+l4<}ms赩QSH)0]Jv8^,NDBw5bax*nlg8|(q;  ;x7!wU=UL/PW Cx*)vVttK>6|pm9abW~{?fՍ2-2mTXt2S|T(.ݷG(ϭZgl6.u@_ǻq1kA2LRSm] ct f&77/[|xS[zZKOi,=ZDȧ8%j!zϝĽ[}ڗg~A.Crd١sEbXi,ә]L՟wr]+}U UXYD`>.srJ0kE*5J6xp9J\z -dxNr#D)S,ikKgcHk#3Vw+\? mrLøA9J@\2М.=&Ix٪ }}0}%%T. 1r\J9yf%1>gRW3#c}!t-I]ͤ.KyiHğzfu=}d@)䅅8kn2R6r)Rm\ C WB+!`28 "$Q +H'lԕJHr%\ CTޮ ^)Y0.E "=4Q,薁S4m ,q-y>K~/C݁!n K2%E%D֝}(1T#D9" mGDM"E].YQKV%+钕tJdrQICV!+u.YIKV%+钕tp:öQISV%+钕tʺde].YYKV%+뒕u*de2\ Qeݹxa_A#BT:+XD';8!)z(w*݂Xta$Jn?lat bĮF?x[:>:U3&tzLv) Ulq7bA1oa ԾD]P4211hڈ٠//\F-d]bA0f$X"RP;%뗷7`#inP[cvרùeÝbDfR~8kՑmie!Dҗ=2W R(G2p&Qq`26$} b27z#`ס3Iƃ\uDCq;ÀXYy $ER֐ R. (2oaLx_Ce2\c 'Xm6&;@C٬1(3ոLgCQtkD-%4˅- rDIBP{9[1Q{/9&EN^&\ht} ʇ& _7W ƗT0 *wiL]ѱpQUx{+B1.W}ኃF WbLWb=nL(]\XtX< .Wf5"_P^r六KtZn9~ U"$r.3EjD[#qS,ׅƜ$^CJk։ x9u;}`:ej {~ KaׇIM ýnrL,\ENf^%{ \k % wB P 0~^ģx}"8Y}*,& 𰜭)D̷5RLTR|2ԂDkSQb\$04QޝHk9p+ou'Q@Gb#-b,̀ 0\Q` \0 O0^}Gd>wR l"uk(̸cL"b$9 p>Q@|O N>h0|| h'0R)9oJY,o>_Kʍ( [ua԰%Q+a5JRJg9:ʫW$ (8A?x': 4:-NK9*QO>/>stZF#cZ8Od:/,r¥9Z-RK(E9"ъs@GӁR qZ Kʅ򸳸M%9⸳<`a(D-~#n 66+b y$0n?fa1> tcƤ N&pw)\ ,g\pq\OUh\* d]Vh[!lvjT׿譸-}!;B 76q_x2g3$cTy?2ޝKȚ޻U-IoC#zUqU-uUC^ Q0PEr ޼GDBN|#QGzXr_,;2^*BwWKIY"M@ CeFdOSn ~$lm xCdB 5 L*d\֧۫g{l_=ӫgz,兢QGճzWP|W_?'z.UXIf''zJGE dA@]RNx+ȯ oYUe~&bRRVV Z"*n 9O]}L7Jgڽ~t Gc1.}'M4z #cpXY4*~$a .IÊ׼3p%4,o?꧊prȕ  ܹY 5/qwKM5mI킾?0xgD yF: O-BO-BO)BO)BO)tBO'TBO% כGSBO)^Q|JzJv רD$.X|pCd.$(F%/" h' PH\R4| ̷*JXͬ>r]*F4~+\,G aU{1ޙSG;pz$6.6% N$WM7ܗ!I1ET1M̽!=Dt 9q<6v@ CXD1!in-[-bHHd# R\Bҹ5R弟 ̘UeGTxSs*[& ΂9)h3 F{K Dg2_b|t0W:S#G42~^_U[W ƣ #ӤDTf@<"*/dhЭƢ;F/rz􂂍F6Žd?!k0|!,.ǨTp0x 5?TuJER1MIE,Ǟ7.bwF>gfS)ܔdnJ27%[txxt^mC`q2RR98{ +MH1,L4 6R }FG..JN\o4h v-TأҠ;V2=vMމęzt;˻*E_,Ǚt6Kn pDeS\L{\ ;w G04qȨjxn sa[#GlFHg5ݍet4vpH ͡&d(ae:@υp|1d*440pC.p` XL; @ǣ?XEdk2ZDX"9"cYLkP V.g%/YWyavB{00i 剡`"i0Xb5!m%J~B@1J8VLj4nVԒ0JfRq2|)R=; `J)̔R ọ*KfJ5L@P{!b/d^4x??UMLZ( r[8B{ mKwl[m]5mT/Cp&itB dJl[9^nSEȰWIԣܼ҂QSDF,,gaKP!_o ƉdqG1~zii^\7s^\_8rE\ĭp*)+2|SU愼4/M%aA4:@sDa 0Qd(AHHH( g婢$)2v Zv(ׇwMXHbϬq;Jg* Fkc>6.7 2En Q׆^ čaE0H= rPMGԑYq0r/-VKԥE"uiکcqmLDPSҽ/g}~i\Z\.-. Lhyq٤OK@^\.)Kd(AJ-kM@*YimED q*(+, }-Y=]ԟjT*K+"3DIOow #ޥt.W]DCͩ`Nl#p 0he> P4Q ٯz9*3] ,齐 .$k,EBJ&:ͅdsJ\_HV:::׸>a>{@CBBJ~~S~!_t_H3$ k 5G,!t6, 2𩾘¾>70LEwcrH%XՏIB,w'@7|9d%a(a+(a@$AR^|l 7x< Kfl1̈c:8~ _噡]e- @ġ8D\ U˾" ^ Bң3C6#L5Bژic2=LAiң|4BаlPBO=4iD'q?ҡN"=DMFVO 'aİzbX=1. B:q)\ "tC!ÐaH0| tjZ.ťh6L 6.h͆tC!2)cxָJ ְaX}0>V K`Xk0Bk>;(Q>Hvr^$4.FEи&: EKJb^u?*ԹL ӥU:%R>U` Q_%XCMQ^_^Y~DGqԀWCoGގv;:ߚCoGގz;:vt Hl4vَ5%@lb;:vtxᵣkLJ׎Y;>F"/ی<y|)SlǧΧlَOߔ@O m$Btq?=:G:yn ܞ~r'xt7XŞcc?'^cc0^Н?P[cнq{D>;DiQL!w7[wFgroL1q!CLnu5%dXިr@hr,2=鍇01180")/ %/WY쟋ꔍ=R6n;Rq+Ϣzec{x% 1_>Y04^/KFKFKv 22Q\Β$ʣθy42ϒB; gS"%1jD7u%j,ƇNQbx:[.7uL:E@7lT4B OR :85MרCœV mFW)sT S l62Ơ3!7b? cgо#vq4=C;( ?Y҅3ar v0"D%6ˎn J,$D9.:ENHhP9i9ܯ9G'?*=.%PT܁鄖ILL iD&mzZoLSSxYmLÑU`1&mr6SHЇ# I )ùHt1M؊>Rs)=qdKȖF>ш#H>dvz8qdC?li8qd#FFVƑ|!l Zl=c{lߑ+i5ޑ0i}1)xapJ3(787?V!P2Hfbb:8YҸ(sYԸpfXT9Ee#+pPP H>HuKu{}( v @Kδ$V `э d8h6^Y jexHF,;t _ɽT_oW0N,USYwU)' +=8:dz,9AN r'AӨBG"sU6 yagdE' M/gU#>/;9#)xH csGNndr1>@R+C8INH(uD2RT~q%/aFɫOØvF-7PJFb9ax@)pJfǧ_R!Q`~ſ:FAQqhD$~r_*S7/Rz(Rq +R/Q@]-,NdzXAX4&Tʼcџ[Qi{i3ii8)/ldi(m~؅iM2ō2D <0]ӓ+wrX ȕQ.Nҿs("S^X%(2q$}Dh@6Q^X@ߩ:.`EĻ-3E8tgN[wQ5ʚ_q%׸_b.&6U``$Tmj%a7ihWnʭ^+7Oޭ޹;zv۽3p2A<Ԙ FpBR 1Ƈ` dqw%hLÁs?گ4n˛4 EѮ.×C __GC:$n3Y"J{Hs jQY eNw-9v!} &N܄P,S(ǁ6OFi,"ԩQg:߈Oޯ_o\ E՛E זM0[W'rKa|KFIq{KFP^? 8%-.q/n1Kd>XZaʃ%-dA萂l`% p{K Xj n VU8tQJJƺdTtUɨ@ɨ@aQ˪ҝV%c%cJw[ j;q d0>m%%%%%d:\\6c֚nF|tA^ʉK%+~3 +'/nt0hװ_]ҹAIZIWdi6h{EHHa4.[.[.NUtrY"˚<`Sp&פdCx%{1|2h.AAc1_6䜨2Qls5[`5%qC UK0cjp V63 oFQai%NEZ~DuKo۾v/Kou/⥷wQXۺBJ[BmJur@Wq \~v5jkmj6gZkS[m&j,k#mS;q/cшwSRS-֒TCѯ1_*Z7 mbxjY4"ŰTkI@baXIDZV IY廒կ WOIhU-&DJX%EVIxUZE5+oqLJ9B pT^2R@[N: XC:2.-Cqڮ*-wTex,P8?Qp Y :<טLҢDRCpb m K$f38:{HSd2n] 5J))++B,!Ĥơ!h ØT?n?BxϒjǍpP3n R^L4jYc[>*+u.їZ x.n2.&q87NC׻lVȩt~/]TbjoT~.b?FKqpc٪M1 XוD eKDb;%l)bdei_IBK>D9c.-f?kmPLK䢴(/@ȱW"0˱` DM›jA~Ы^6$&W -!Y W d'U_DazN Ho9${kA\eڋ%e?+1T}$9v"Xm6f񘋇 %0Kl(yQ``iUFN++y{#bLUʛa@j@r G?΢5D{<@4 _Q`(>M\n ~2 b{:5 ֌SY,JbϜ^7te0bCL#LhO?='TUHHK[Ib)=^׹8$^!6sd{2=蓥Yطn1>|-Ixyqn26Gc &p d~c(<&9c`*zݒlym[^2EJ'[, DRdIWuIҹ.~R g=I\Ϊl0HKĜ,,Ub׹iߵcέ#QfGdOߘwTc6HO@P`[R]\%6&S$K˙V:L`߷͜TbfeVl#8 :Wb s2YSǟ9HRz".W.@E iQ1^δ*g "U%?f+SġQ7 nyc^i ,mn>%h ? J@Kd.%:\xFrewT*zs;{caYfpP&۬Fk-HȊI8$$|$W.k*pOqIHll)!?JabD)3I(90X+g[ w`sJYT2r:c,;5gVr~1-?'lՈ<~ 04$by{qHd+ÆuW쀬!6B/ tb+8"\y~. J|^%Td_雳Tt;uj]8v{9k\#6r-ݮ{we0\d./(.GaGW~O]y$[YE)mbCSa(;]*ާ]>"K/uH?I;z9_jQ@YRv~]d),0J^:k^#{`,l-0jh!(q"X͊pZP QYQűu8 A$OJP8 |SNP)ߣu%TU΢\1aW}W{¾s<rz[.7Nʈq,oW"K S"jm@PɾԤK/*0hUqT$LJϧ0geDr+&SRMk|&ʢ]\*bcs\, \W`)Xx RSYZ&K,<)7)7)Jӳzؘf6;;^*e-x*F4.4.4.4.4.4.(cu8MRpD HDן>7}nȀ(Tznf =]F\[<.b9sd^!kkHB>*b(xw}Da(R%$[YD*9&|1x}R/&`gl'%C*=n#ì춾m6ܴE$1@$":q73&(A<&%/iɱ Vہd%I\ʝ{ *K9y+8I*L:SnE**"ʜ(0,%X.3_|Ɂ̾Yq1]Yz)s̅G.0!pfk>پ H.r3QNN (2[ӌ=fX:]1M#5"954 riXl\ͩiNOM85 9|]&eAhq6>P| J^52q+r)h h-! ,U4se6{f[!u_Kr¹}фqq3#q Υ(KJHE.R94lPm7 ڏ9= nJ!F%- OO6ዴir>6 3s2t8[ZM A-&.K R$k⪬mJ{8qr7L1N9 8&'r}6sK,5WsݥA槱>Ku0JJdNer>)X@dɃq37{uMK&aTdn5 \%嚄\ }m5 yqNY%S rIܨ&Se]׫έ;fsˌ蚭6?t#h;,F ǽW{וĩp&v᢭ ˌJ>JyK \p5WW8&f%@#dهVM? R[~M=OQ)1; 5[VW 5k;u8;(Ruz:֜^k62I,e qøaR{l:pT?o7oF~Kˋ^Ak*Pd%䢉nyPҚ,t^5""ח,Ucvzc8fyn5Sf2#4RHُpnb/ JJCvP,(&!/Mvʋcw\%$L\Sh̦C<(σ2) X9zv%+kP޸$^m!mśHRh/ 5_[/b 4kHsNQrleyzB ' ^Ojzazbľxv *wI[.E˾enymk&iXz$Jeߚ8%ݲwY컼C rmy\[^Փ p[w=7W܏-[p[oᶦ%-^G:C[\NF3AC Z~PK| uDaԱh* eM2 ~좧pO UY 5AuhNz bD/ki-sT?e;xnO`dNR=_{T+"~C !fD5aoX)\& \kk׿I):% ^ګTt2J'nS1Qr\|3I$`/֓\71e$ɂ<݈܍h{ *hT8]&|͈NSn=4YBgiNB{+$Zh[qq9A漪|DY$Nh[ݮp[U֫6[av6B f/xqep o+`4̩p̏bm2|`7CD*XcZMBAW#nJǚYN;yM¬4ʂ{{ v9*ttojr'8:UI'Œ~\6il>.NivkM+}5?NoV5ױJYC0 %RrQKX aIY+DȾ&Jbe0Sg&qXLi2ʀl'fVL{s牙&sʀ:(n?;X S摙>2w\? #j j+u0ӄ-|W+ud؅+&X6)y@MBa"5nev55C(} i2s"nV]FIaZDq' p9 o5 Q<x IMp*E³58VekD$WD3HށB,teav^?%*ڿ?&W.ټxDD^< $' ,r:,ߦ&[^gi{2>JƧ]6#] d|zO[M8qѹ 79*F`,8  v8c"fh٠vp UZ!6qXw8;V+ǖ.VnrD^LU}sPJ@E1[`y,K<Wի-qͯγ4ag(z1&G ks=׹WX:sgAu@Ex9`.}}|_O^h It-,]9$ˁ;R"̭dGO-xkrBvM ׄpb)]XפK}w6O8ev.,EyC,Y#Yrp;>MXL sѩx><,)&S ylӺ R3L삉 p D^<#=3q|/q`|gjxz"S &N]Ӈ3-6ECMb\&vYJ&΂6FLzƷEdeVNoT09!sZx<ˣnn\{Ky/=V=V=Kcccc&3Q[%yLiy,c@րQ 2Iy|lxdLv;H؇t7A8 Ĝ-#MҹW>7}؋V.,W}PFܜ>-%vOyG8OpxR=!ױB sH%ڧpЁ&.(g(J A첔;\M_~]TAs̥,FdnDяf>g>G&l#e Qm4Y"j#(ZhU4\ߥ|rR︉k?b K`n~9*9#0篓`pRQ5 Qm^o*0M>˦I;KNJf_n9';1a -4^Kx6؜ѹ:Є󿫃 MJ.V5IC ʰ^0ge<4וTxCT ñ9&΢*y;o)utY9:XMg%5XN)4$):%KO)\JrM(KOy !C)}>cه+ж)?%Cet=xP%:5nYRc "KR*`˅R]J黔lNO/IT;$m4?Wks旾]) 9]jmWeJU,m2}E4m˷́C9xh;-:f/AӎM]RaymJhRri&xsȢc}LN8 E9C&s(Sn 0( A2;=4rSB8⹝<||`{yp 6_xO\AGvd=M[ױڗ$nat>KGIgJ{v&AB]$4- MKBsIa=-MKBӒд$U:a(MD"[:i!iZHO4O4O O O O O O O O O }TA~MbQOIlihL^)B@m[iVv BD~j&O2h[&3 LtABV:Am4id8;pv%\ XLyER DiܮGv(0[n5D8jR 5 O2{7V'Z{l:KkܶLyYd/rf琡< }NWQQ~L4e49 ǝK6uV{ E?3QeV8GwȚk[sp{=^G}ش.~21WVzr>zA-A-c R$g)L|/=-O7 C%LM&G%ӳԙ&Ga4 ,RiJF|S||bjs+?O/^ J+:?oR [YЀAkR" Hz(MՔ+&C^S.VVVVVVVlcvYilWD|x0vK%i-O[ҷ<5_ 乔HɅ{k+V7Ae˧"Rd4}%TAF*m8N.wj=,oqkv*wL~Ȝ2, ~]] $lg`>/V0<$ e(|Gde)A6)SCE`3kK zLY *YwLuR;(AG/=K)k/cY"0Xa/69"EE&N4wH[.P8z#;\s~ 3\T=&'wrt&M|87ibR`n6IKU`.4T|iFlǜܧN~g,|{>pqVE?Ǔ#-&W7G{eNd]{LX59Rl*wA񄧯2R<$M\r,*&z| + 79x;%MXfySwtXšAz.-?;Gpm\eDnJdɋ7ݔtT:S ƋET1xH+/ʛ,hLd.7\Ch&M(__~݄ ˯8++a7Y ;hnrE&N؋7\_pj)/=ke&K.~`evU$ٖsb-}qJ@u1dQ5y-4Xg1T4*oQxK?a&%[irI)٩0Ti L & P:>)Wey@Лu&ص/|^ۭ>bO@J/]}2W} 2i5D RPd) -5IВѼ&/OFLeR`+_U'nMFbTXSܞNj;-u8JȞc J,jиl?6Aת!E]kN?\h/ɶQZ)Wh(0]\*sͨQW p_YÛ5iѮ~azA.|%OUׇ1I%|SfjF{L-mR1*|W ^ 0Gw1҆`- >I؄[n5avji\&ʋ~M{wji Ɠ`.X~`|ʩsZΫMWlזY&ToRrEл LȴK: MJa#؅}ek$R |\0n6q)(jrMW4.XŠɵW)An6YNi|—kJlmݮӔ ,mh,[Jbzz5|dV=Cȋᷫ |E UC洸CxDn@~s/FknMk^܈MT+r w\TH8e=VpC/Qq3HFpp^g8{~(Ō~Syﲘ[Fs54g$sI1 z';fF/w-n MdkL$A)) M!lCS&M(gEY"H\,S:J QlY3l-`}u!cDQp=ȶiq̒ŭh)r aG޼2O#UvٯLGϭP052Tza5\1;m縴 Uo&ZvͿcW'ƍWb ǃ $i ')A0np \F K9en %ȹ3]H2s< q rW͘"4K qY Tz1b}p`Ag04&8=$16 NQ(tpd=258 Wn )Pcیnrf4&gFcj&\-6D&uǚ3פ8 ',MkLMXsrQ9s ӓ1sˉ&`.6:qUmke )c+Z8L勄cYlvœQ G.h |\1v4@li^)r],.>HP `+1s&>5{ T4F;"`Suӎce^ 7v FF[ 6 UȲr2.f^ۏ6,EԮ=9}x$^Q:ݸQ vU]:#EKG+s[͂"?d EFh;dvA`ı@yt!s[MIn Y 3Z{`s u.r*>hA4>4qp=2>]DJ&}H8LPnV ]( rx_fƐ&ܺuQ/gQuL{d+0a g8(# 5kʼc]/!F FaZ:DR.QrI>֤ \w()04R+8j V/7Ktrїҿ&]$Q\mMqy䊔>@r@_;ߝK+ |u+sWk }qmT}_N(_^~/zE/6+\6_$pD^ܬlrE8~> _]~{zouw޻\].{HzrϏFGgn8ڱC8o2NPiI#.H`ti$bpeZdʔ+&CY@D v=xT"%+%5.͊`w6Iʫ.1CH ֜xQ2'_ S/ʜzQ]J~4Y!r2>M2n"/1M 7? .ߪ&S; \^/V=8meӞl:kUh`|\J^*+Z6!CofXTmK.>$1g'HȕK}fQ[偶*Y)QvӋ>{-^UR8~ÚSW "݄=pe CIԭC )CYQO]?D2]- |8q^Es#L뛜t|lS8o qM//9";e5̏WWx<ǐo|Bc?$33xCS:4-W2xޞ#%rE֧ܮ"[ r#ā0QQ A ^-8.GntORtf)9(6f<EO#G3tJi918<Ebz(>a?ãPMb+ ~5,eglwa0b^0[i}!#9<1dNYޣcMbύ-}I~a šfT$Gt$l;`N4cNfMT6#|/7f"%q8&4"!/K dc-g@UWSMbqO ;T+/rd?K.i,g/+KJ0g2!Oy^5^8ؔjj#]M0\w5A7,jR { 5YӤDH8e ֧Ѭ<0ڄReyײQy`#T0X@{嗌 Udk=y})@YONuo \Hj!X &V@ؤD(h?-9ʅ&RQR,\ 6f)( Kv  ;p|2_B-Ej+LD6 p\+AR^ abIÊ4PtR.f&q؁ڵh1/;H a/Kvpѹ.X%汻z(- eDdliIMGkYZ,$Y[&lW[ ׏beI beɲcYaYOqq=QzD!`n(dm=(d=Q:EƦ WhP?V:48W ǡ32lQ#x>E(T, 1%zl2M¨ҍ8 KYh -,na]ɥctY輶q504xD)LI66[aY<ܮ?1c<^H^cs2l׎`46W`|{@Ĕm;lL&Km`t(OoRr; .uء血Kyݣ,nɥL&'8n9R姡;2g8VOno|JTc~˕:ҟ;ا?L6)gw*;MEd 91\1\^9 6R~k+^{.Uy=:$Yu=KdeKݫcT,x0 SWz_M XC&^.W(*S QCl!(X:a`3)k| ^bdź>Y !S+ZahB&G.\5&,k-2@zMu+g9SSa>CɣXﬢ\SN _GT^FXvcNY>_u|]-I$x[-o $^a-ݖn wmLw[[X)gJpw?~]]ͶݸpEզ~"]2MDx>arj6*Ohʳd3+eIYAf[ `/ 7𭈏 n0$Fl ®$>7;ɅSI(p9!/v&[a{ial2rꞨF"ہ\DN%?]1ŊAsMR Z0 ̏PmSNVrG(t/K,:T+/}6F"3׫ҫ\|!L\=ȃ}MB>ܿor텗I @#J6dL^G®ׅ uAW)CÙ{ HuZQ FVl Wn׈cKl857[A3FX؅5E,)~8卥\ڢpmʋK&WK&ÕDQǁDIŵƵEjiI"pw 5`n -.>$s .3$Ɗ=hlmNe$fMnMck* bv1g|olM|aGpT,(i224  f{^fi4)s vˬz1^0i۞G ʼn+FH= tz J߰nX6zV +چm#֦ kӂ( ćUfWq8l<YkVv vq`џ.l'l'l'l'^څWt]xEׄS+Æmaذ-}x+28f: cmxVqٸ!{n˩pǨ䁙h,m<80"R cdMtScᡘ&c(enEKPR{t rɡyˁul.3H3vq2˾N:hp;#3tJFW& labcU\,iiȤ (W"θq6}%lr.*?Bf)t1(lc69*MNjs%lrԌ҈CcۿMs-2MJ:w&Mi3P醦v}4xd)SΖMv> Y9C3&SYp=~`NIvr|*&dNg…`Wlk?v2_窉yҹqMxߍZ$fgj#KS&'95aF!ݵpǥ+;&L*9 a^u 7MpGx rD]ä8!m?B&NIȗA ' Da UӅδNjr6$h|m9̫K44NS:;sz^eWvuwzݝ^wws\䈄?x6]ᚹo׷>,^[Xox݂AOvRj݄U i49r8a$w9sӤX_b +B߹rU-xNUCya֟ҶivZa7aSZj瑊XZo5pFb3PiwZ=9-N_6IJ(7*X9'8g *s>z>y>y>y>9-ǚS?az>z&6SRL5auSnPǢF4Q4#6؄}2%lR.&lN-L`׾Hzly4qp:s]aITYp ҷJ%mMDa$>iW,E'm+t1<-aV}N8;}ߟ?}k|cn\ՁqX?Vh!y=-P}sN:1z1z1z1hh\drB6Fԍr{o0.bo7N\n8b (5 ˌR~J+?0yA U.* )ohz&Ub\4᥽Ztտ=4nw)_@A;ѧe &4̣¢>n{\I^< _ 0z 2QQ(AW`b-03q ւT!c'hR-%nݒʀۨMQI4X5O?=Ɏ @^xcJ 0{/:0,x@^,U@ap@.P,\GjdyAUxT1mqAAtָ&)SMoL1pθ#vjW٤pa pɹ 璶24LdyMP~ &̷Y,4 [>d`%m8K@%Rb 1t¼uI8\2WQr )F^N+,v=p ' !F$Z#ٔ~. FRfНUZCWnh Zق5tk>WCܰsj̽1ܘTcnS95ԘRc$17Up\"K=<`V@Dg 6`-%z,<v l ;syΔ7%-Hza`osOU';VcPklH͆&grkMz럛JFe&=0.rxh~:ڴtx-iaZP.(8ߟ4碅 $Ӂ(C/7%Ӥ&ߢs :CJ-Nޢ8U_橫FCcVRKi~ uPbAn*x,XU] '& rVR3/Z&hzf[|RDW*Ny5Rmg|xPFRb%AK [sP?9ʜrnʣy1//f N،cA+'Ӆͼ9c _efy9˻ SQP+Py8k:ЧyW6`"I)b ѴhQ c;Micv*__ێxgdߓ]‚XE2dx%,Hzaw}(AEɦdOGtŸV?0$abxz&O@Oe)?{L6̐ՑƷ͸;@/+@բ)cwg 61S}a}A0el7 73!) ngKVR,mSS6_w`J,~n0'hezbq^<%o]&a2/{ ek30gjJ&)S;nStW\KeSjEWU~_eC"` Z,&(* |A2eeQ j`E\CU.Yv B?Wd!dq)kRF Ɇ&$BE!OTRh2ڂISt'Yt3 $<΂d,\^ -0RTx*}%Ry{<xvVp 81ڠLfw\b.S^L&L۲<"&U)t|ސ﹦H7|\L"*m 4 ~8dp 8riB>M(&Oy+4} sB4xPOI8$@E3xh!BR3y&&WIǩjPRD$!r1{ K~L0a\V"c@}6xʱ)$ Y}_{HIh]txjq]/'9*0s$ 6S:|%96'co-F^,s;6#VJ * Vm=,]q' ]Lw8BRV#0Mw*?n'oD{[ ކX\S7}6 }xwSʿOo\nX7!3QQ{V{ ~/~k& Gs^Q`rq %u=;LߢSO%|OŦ)cX`i[eKHU@WM%kbRWy/ޚ\orn-ߍn1_m\d\RxƼj g aG r&HٶN/R(4$kz"gJmlZ[&o![w5q.av|Ӥfav-m~P?*}!u^> W.Wac,K%\.*s*:[]sE*13cOMW1jjrb`o7 NP(xf?' 0_ZӠe8Ұc}AVrQ)J+̋cUYPgC7 HuX<:GRn{8Rt!Av~gr8hU%mcl~e[t lVLU5\m[cho2 !!DŽuɠaa .Zхsܝs0A '۹-RHVL(y` 3gQ9mP*|1:#;ݔKOp!M ͓aʃ}\-' O.xPYC8rA8> Z>W'd92P^q++ %73C[|bwDK_>"hl\y`5ޔrrk=rї`л~Q%sڄ6SUBߟ}+! j܁$<*u r'/ ?q]^(S[U j 0p"EB$_GÛGjHqNdh5=-__4xBM$V'16*/p&u}b2+'+CmRѾ@e{ѡrX2(+a;_WNH%I̓`׿Yjh*7T)qJM'MW:J_֭ 6\6~ R.XmhNkHP/Dʟ?A*RpgDgiVS! [0]ܳe; Ն r傦9% L (p[+pN9dm A5U[.YZDzC'?= e7oZJ;͛BL8(i^B+߻Twŭx)rKꕸnj$`k`+߂d^I2H2(߂BLT!a53$*3C`y 1{zyXEc:|* XEe`8MQ8Q4mU릭Jbz3\T}09n f" ƾZ^`Tp腳IrRt::~uԼ ΕTN_,/xrq1 Q,pYBs "sU<j`T<~g')&pz,vs2&?C!mn& %}\G=.En 6 XBܧBѓkl"hr: qMxM D40M4L ^܀dq4\241ALs41Al6 i4fa3ͰfL3l6ӌڣKl2.ф=Hl/SRj){Z^-eWK٫ j{pZ^-\o0X^WG j{Z^`VA`?RRRRRRRβββββtY5~_3#F{%9Mp_! W.(_I8bHr/XK0X@%UA,AŔ_`cFx2x N*0ogUn bʵa^^k0 WWwp(Q{-bC*U\PT *QmJwTq?I[M'!kA?Ǜz |$l`[@\rIya`3 l-pfdTߧI FTڴStЄ{JoOظm!R;p4ֆɷ@*\o!{TLk)01g5 0kFMR G,* LijM*vhj.Rjӏk(+x*P2|Wq9U`Lǃ`1JqT`,a:UQrUw;$ +eo68:yE#_}\9ULCi0-g LC=S |M6ަ>[ \cx1T2i12x`3،JS(ܿ2{҃hS adMK=Ӣylx q~140)(Ub;V[:Y@{)G#@` :M*>O`ХA.ISRa⥁q`? K&pF!ƂW:Rp KA0Xd|}0WS&E dElل&eg:I[mH0M>1hI݁VK+ns/p>.+ &,PyS`` p* 'ZBLpza]-xUNՋ _(a;M=ķ79Զ:KK*@[)IRG r2ͨc'/DRč@ !Hg"HK6)M+R3}7=kK/0 ͭ8tIqH(;,؂* O>~Ȱ ^Q@X[uYPؔI  S8|T[h'JiZsق-ʷ MEiV3,t+T@b PEVA'tCU` l*l٢쪠Gg:PYYbyReNyQuS{US'δNM(*ר!8ߋߞbۦ6O^xjӺ#gGa0.0*  Cn4 rłܠ@6@qA .hZGM6Zm+|8_ 4M<}jՉߞ7فR;衇P JpTCS(s42/;h?zSKtRȔ6^rgJ٥BPK탂`|@Jv>P)wg7JQ0`wMQeoQOBnKhjR5LͣOP?:y$0ҽ~y1%gCp2e݌a s.gI] g\HQdRm:>dW`zH5F*H)6M-zAn;~GEWv\m%u^@úX3Mcq\p2.'=7W}K;ĘT nߧX6Mz)/ w߄+u[ W.xg8л1ݩx)4`L^G(o.x?%d X0eLJ:.XTs?Pr"3X[ߢR =ݼ{zx'TCsjQ2PtrrvYrY.trrrr%%[*5ηؒ%cUǪU)R>V|Jؗ/!t{/N z *0A a/P#/| GI_^(eL 6p'/ހZV1Mn:Cnv]j |k\c韯&7=r oN:/n豧 ]W>7caϦ>!.ι8M)J[|ӶH{ΤE!a?]vyrܫ#캔.*pFGY٢ nr庋}& *s>Lu0V^"G>"Pk@O&ܛ3Oi>>Ww'Is K. _ r3/@ .x(A )Haa,H]& ` aSI@}. Я'R({R4X U{XNL )?0EǙ?~ ˓ί~ғ/DSp|I^"7_'^7v4þܸ?[!#iY+6nqC)cC@V`2`CMg]0br 4nE{u=L8잹i ^wv-Dyq;wot/!߹'p ).Ƽp`-˃S.;.;)_ 5:W 6[RL?p)Gܔ -QZpS4cIϛf\@J/`\tݿ_<AT;h }#hp 8 ^)E8s93Tc-膉\sO-LRːm985h`,ӧM\$ųNL>BpN9>JW $`3 *UK0eq_AkmWO!,0M5rU wN詢R4nGmLTAmŝƤh|Ozx%@#LΤ|TC*ĂݒXtrkAVAaP`PSa*H_X Y)L'Ÿkd(E&z,}/V |%bR"x }x{7Z ?jpve%%%$\bz5e>9d>9d>9dIkmdrB&B& ^Yr7=U;[16blp5m˶].bl= 6M*|MFsMm*yhe$JaZ&>! FA7f` Մ全L_f(;̏=.B  JȥCph\ phܐDZC ನCJ1 tB?ȩ\"rA=hE+t}hR8zPog(EYx֜l%0\~o+6ޠˏjڜ?A.t$sLJ C)1tJ C)1t!p&G2#ΑLHs$9td:G2#ΑLHs$9td:kqrn[SUIhwd:$өPeȆb|!JA䋽ti<6B ,_% IࡸI +@Gni,U50ȖRRIٜnwjι'ǂT3u ]?R*ؾ񸦜>4n29-)~1E=,5CM-=tOA20vs apAY >ݩI)0A)Me r`:CMT93۹ȧib2H!ʹUl9L'ѽV_4T4(j5(p>z\aSoca*;1VM)ԐtA^miRݠ+7$i5 djVBlRruB&en{ixr} *W0籠uݐ w48g~訴}KSA;n_?=b]ʆ+@PhpA0V/v\ Q۷?ô1 !AKh?~So(JoT,]`l|&Gb.Tł4EbݸZl&kCݸ6l J-y Ѵ)),@Xn4_S4&ՕD tF-Wn}Gc_mH .> q)Ǭ.d1.58jq”M0ƍ ztW$cR-\IeN *K'ݘ((H]i/wwE*P墭aw> pƤ8L<1ihIs}?;uXWa.>O|aey^2 lͯgv䢂$TL'2 MX̵ )<]{Hp4|<7H5FƜp/HEӺ cr%FEy+=a2׵ܖ)eY;1"vv*ΏU+6zC"*8k uL.h W۹>DPe_˕r<N]F>7nSP!q- Bq!N߅DL\cXd68&k""I#鉒i[5|cw0ܿ_/Ƨ[іpƃRA+4$_XnRYLrc X0o&TvFϏ)c:=)" 7-w +ΧUj,ևzS7~ oQh(x Ӄ /L++Ïz,OztCW]͔{Efg10V!)dTyz# T,PABtEX48= TzgatR`IVī_L LakdZ!׏Y#Os?j@^*U1eAkˆA4(zzj`,WuZX970V7D*$DMiE2ѻ"_yrkl ERg! =cY{&h޿?jcag.&ox"7?%s~xB&`ʮt^A,Ny:Gry!7͐"/vVR%KڢXJca8h% B?`[0L $@g`lm6eDg'Hg7=ܮIE?Ա<yD 8 A/~Q/L)5(0A0e,SIv0sH1wDມm EüMܸSXRnkO6'2fQ` mc:v0e`G螌. *jn'U>ԐMCjO M 1 SsY3w^.e~ְY+S*-0jЂ\j zaA.E6h۠*Ze3mngS8Lۜ ÖfV ln6ت9,gR9<%ni6aZY4Cݧ eA(%< La|^b \sO啪W_*9O }EW1ډ#X^"cY<eMT Ƿ;=/(.-ܜАK &d?;|zH;<ٰ)e|'s"CLnGR>;=p|6~φ͛Ǡr?*"F;M< 7 ɔMCi6  GwфWrP9{C|HAC҅] ȥWP`h\z9ppUPAU:S㶠$hA q.7tLjzo@uqY +J}җ Ņg sX 5` 9jWt荛Ps5YjKL7Aׄ!A<[`R܂+ t\ %DަXjN\ӄ۪;ׅE6+l\FT̵Fp&M#a)AæqP`ea/ ?KDp_R640>ۦע a3kEzr57{`"z+lހ Cj.,jz?l&eၤHBx G# `ëD|G" 9ޑB);.=3b=#;#;#;#;#;#a's?'S w\ @҃ @ ̬ La>Pa|J' | XBhl*¾pA2T`OMŸi"5% pFim<l(woHzBM6(ArX{Rpys兽 ̈́ O.EuJ z.NN c.N\10O6t]RƂ8.=6+:ODXܥ]`#nK,ew'n~R'l6t48a3:>wsY_?׶gS}'TBgmJqWnQ[?S-v>ǹG#>N%6A 7d:/7k M.r=ܚ)P]8Lp '7!Οyϼ-/6S/TGʗ,^ʢ^ t/R\Go*w2Q/, %+ }݇}Կ.@]xIEXQɺ@}yCI+.3z6a|Npn@%m#}5Z]い Ժ]•(O40AW@A8$z-7n5]቙\?H@vG4@j%ʽ@Gd3M^_5^L:k )vj89 ^VujzLC=etzL!P+D8д LͶȕ%HigAe 0oPk \\-K(L2/l6Aa_& >?W~3n C âI%͟c[Mh]g4+g30t B^<<Լ+5Jpo`5m<*Tv>^|:'tN Ӊ_=^dž~Ϟ={:x#2g׿kLG{s@}RP}s@7[Xѽ-U`( {v (h` Ix O0Wѱo``koOe]bLwDv@- 7OژcD 0xOO̞XR'*zatb LBO z4؛`oK͹7Dd"W\L-raՄ|qQDbwOקN?;걇+;#^1XpIUKW^ JORwS,(Ljrag(T/mUW*#mwh w Pvx=Hx eJ տq(peӇwiu?Ƃd1e['P,8TrfWҚAW0wj=討zxWZMob]@}& MLW/>EzB(s~tn+`}A.܃Xvt;]Տ08mY`=UT^G64n%ZS8HYdKWuL-ϹA ut!e?@5c0ߞKE+lAd4  +)J5^P Qd!욡ꑡ1_@^/bBmƮ VJ{!Y0?^XNIt{#U3>H-j'٩$Px yvjjR10'+2r/ K/5#Ijt6%nC-)3Ijxzlߏ?=0JLB#^B&1R7ɓ L1' * 8!aj@*I/IXaj ۧ]aȧԞ{ Oe=bx1BOK,6X}a,oQhp(SlfOm\Ba^@ltxa =<1]sG7HM&g 3nO1oSS8|\W5[Pωmcc~x!6lsd& θPhO "W^ITU?c` J 0L𦊆 O.AY[9"bRi|w laR\=?t&Eo?vdB(IIoPZ~t#>z4 B9~ $=ǣg$m?4iXXP-U5tĜgZL(mhO̓8{4nhDFՂpt%1 L)u 6+ /A Ԡ01VUbba*, R T7Dl\MP]Nɗp-p=/xJ'W"o2&MO'\a: j7!0N ԙN]A02v Ly<w P4t16h2 ֙qCی 6ä鹦Bo(f7t||U^`zZaf\ĤifZVk՚if6Ӳʹl3-lm66s[Y(,lu6:E͢fQgKnXFCة&7*>Jʅ})ԗB$OB#(ﰠ퍂P1 r;E ;nCфa0 /`W>=b/ ?&4VxI$s0H/)©K0͔MyK ‡h9[:N1przp4<{bfu\W]DPнy^cΫ^P) 6 5+}zMy yauscup޹pNm Q\[4t|:M)Mgb!pDS쀁2k@ʣ*Ab烾 R^P_aƀX0PyrY+0Ƃ '`y0-0Ki 0)-rL3/CA49mOpB=ΦBZprʃI/MmuM6nq$7/V N@Ut!pp7fq|SϠa G+0QM-irϵs^Cؐ,|t"L0\Z%Uw|εy+D9 74鴩ZeAI^:<ѥ?QoPf`T3(0ރ[2 ue  _ 9W.W.t,f+E?qYtY;j2l4j-[9M-&@yf<3Pm8ekUXA(@<_Z8CK@Zր_Bخ_&)~1YbUSUlRehQ3Q3muiQz8h> &\~ .?\( \Q?67T8'񮿙E oyl@g >n8/wlxrAt %S- 儦rG\S-]f6*MKuʩTNm+eXhJA4qĀʩp {5\jpݫW(xL* 6\l.p]W VZDo&vj 6|j 񠍌t1-+)x 4 jzAEǂdD B^&JV57gTm2`48PW0bZ'{x: |[ݕ/"~H Qao~ OB!אk| jS`g22*x`G` ŕv&C!}  bg2tFH6s\#tFrnrWiuD{|jubI͵UEŨԾ(6 )e^ao95c )xꗠ?+@u??W s^(RA֞ z8R EǗerQe*8~L/SaZkjQm+=|1|8_X 5?l(9om[l*=ĦC`T:ETQy$IIrAt4{fT &xjIMx$k L.BUYjÇ.#qr g0q(' =禞+g/9&}M=z9<8gkVLÆ@n[p TAf Rc[o3 *`Rbc,CE*: MmCDLKMKM.< ϼOKM\7ø9S0(v ,KXldB1_Swq_!mzɴФ虘)ͤVa7?4.zXMj Dm/ w´;=&Z=kѿ=MOHSUS є3L6S()S%ejֽ %ej%c|5jκ0 &b39kŜbZ1gVY!f`1eR֑Sf~QʁYAF GF{I/s&hX^@1 Xkn A,;BA&SVl$]PjBO&L?I?`hāLO)+y h6$FlW_zRDhĒX'H MGR3Rj쿅MYZ7G$' P]؂^7zg陗j; _Cy؉`/<\܀!AѦa3E0 ~a Z2Hnݙ.OR<#JC[IekM"R'ߋoahB~Q*LaVi@ 0'@KS˲ S坛y#Bk7""W*;Egzk~r?? C 0Ԁq  PoH\ B`Vph^QbÕ˕K%XBl& U0s}9i}R1os"2HE"2h+܎%\8O :z|s WI/&__G%/vvjæKP |yO}C&x|0;z (a] A/ǰ.!Nla[(Ti{*o'Zӊw^miC(S иqSmֵqk?|IjH{o;]2p{}iٟȘ⧦Kώȕ5Tn9f}4X!9 :L}}8RVТvE ZL ($Z,j0)uKKbiQ 5K5K&ķ_`z[sP5gA0 Vuc6Y > ߧ26rtQ![1]o-BZQl-KW:B){.PuI-p BC 6(- x|;!4azl u7 ;zj2EfH|^B(H]REmiqםO VöBUfBH%ӳ*cf:$<3Oh a]o˿_ =_ j k ix,0a`9 j-/vWچPdW#q[j \sUSY\PZZ]lő{gmUBM`K0;&A5$]<\tX,N\âW`z);XHF4au R}]-M .l Ԇ aZCO PM@ eaҘ{0rP)HUX|OD}j5~.嘢p3x#$ڏ.j~~쵆TW񦜽ߠ0fK g:qȏXج`.H51sn~\<5JӪ/?NYMsնyqh7~sϯS@ Ne[ .3XK9EL8^,O`= f%B;4*u@*F%%˳8RŌTA-?W3t651JMggؐ eNMzg:Ŕm3AiPj8$ӀGKg9CtYIYf<$y4-+K%W.={?ȝo Z =+HfV`0p(pn ma oj`g)䶧} ](FGi°لZlm/4R.5R#.5R-R-݂*`,W6}V}UA* nn뙪4fr,uM9f]Ӭkuco8 ^gs~74$D _EW,&`z8˃ÇM|[S&Ui$i|1hB9c 0oۇ :( f`XV G&]fOM SMT&_/8k M}_L=Qs)nzPk`Kw[i~X!n\L^/O9l 6u P s ,pA{^X;mo /l6< :S\] w{ rXMʉ~ڢmR,5dCA"oDjd8R1杀F; uv.0}0AwK#xL=pb wEC-)MT37A4m|UrI)/m*t;(Cҫ?tt;)%B&():M.(Heg_q/mPi:B[]lt2?[RP9l?vvɁD;[-Ζh`\a| 0ev@a3x R-A OfϹhΐfq- ~mЫ yo{aaHO\p݌);ŭ *p|A=K&R%zv/'4yLW߄;,1@P^`RX@J9Çۯ陨   Pӈ btv\g|bC~.9#`ylvLb/0`/pFs.FOǼr` ,!>qP__7g"I)dzT Vߐ&=.~MBqkҤ纰ߕ!p=׳)p-l \Ϧ@.MkCZ@z$gKdL&<-kӻ"Wʐ`:zY{ߔ6cp*n5% *zA2 0 Vpd<#c['`V覼L)˕ͮ:)_s 0І,P-R(z#AkDkLnv_Uxg^M*ޚƥZ¼za.sa.7~ .1-ލ  ;^ wX\Ls\LbkfmԹRwhBqigK3M W`tyryƄ=fc4v-Z(`31Zh0y)z&4@EM#j2!b76ԦtSn8v6~GsnlrADsn~6lBa@ b/Z% ㊅}gS.tIi*|Ngj-ՙM۞F¾qm6`oU&[&%~ 4]8"hw;ZێmG˵LZ\ \C;Z5%v*XURm&9ʑK3K3C)rrIM'1 (s_'` ~ljrXC01 aa|3e00 gtɏk J9TuDMBtT[.Tb؄OM{  ~7Q,^ebAVpm?x^_+X@,^#Pg70L2k0նh2TQEKڝ#O BP݄o(@aC䂖 0h@! :O@r@\B. k@^mAC!n XT1R Лl`IՂlR*eRi3 X ꠣNzF #|ڑ&.B^xuiK[|iвA!4VY9^^UϘ zT2W ڊG뛶 JJЕ/ LX?Rz\M*md{?q'Dz=ܟ( 'DS:ؖGh[ɘ%0:mK4f?G{ F[Ak xJKQޮ,[1e΍$ôٽcuh;n rr(`ci%J;ӚTHv?R\(\b׬'Ky};є+)ff zک*Ԃ B^ t^I:$W+IgA+g+gw TW-`M1ٽpv31SH:$ J=zC' .7lI B)iRn|4nS;e7hT. QXvBa؍ר]0.t ׾F#|;᪍ѡ]W*VЉnI׹tDdؠ+J6~:l g mDq^1Kd3z,DqToj*'&=yaCO7~C :ڝ2 MB8/ j@O Wa *D2A[2T.y>'60ݴSWN0؄Pka7.Zr$HԹF~6RAؐ<_.H$Opfj*!WsKUm >y̬rSAjfLʽnreDEcvXbi}=7{뿏S~*Hf}}lCõCu펧9(,PO·9C_`{ #^4xJJ/ N8t0>^nF7kĦX5+>a||ԟw'֯Wc\zy% Vs%0؏~&\ГN`FøC'K[0kXL9c@]䂌i1fϠs榧TpRIevrS]]].p$ /r10/ju~J{gZ7hr˵ӻ"WW=Dqx=FsxƓiK]iV1 LVJMw o\>4g ȟRA ژ*t54 \:): E&/VOӾ"_g ɭĪ?۶H%+9 : L⇂Îa*siasMH'AvMTtӱdsZ`>#n 2S(FeTa' }EDEDJ36rB6}=3ÛgNSb__w\U1.+M+jZV,ƅ6a]5`,xL(K ! qo T^ %hLJZZ~*za%`rآi55FI]#ūd[1\*-8\ab]P3 ڡ5avrqbE%]2 [!Q4n.7hz:,ϛT慓&Muz4i4i2i2iiY9(VwNNNjN˛6V6mlXlRUcyloⷧ<ùMA 7[x''vxL0:hyzƭyz3 ʉm4]};Zۑ$ߣqoGަ+_Lq!5K656565\h&AjM"R\ΉLV%NM$l5XM6M2VD$Q5ITM8MT $?5OMS$65IKje#1i#mq W FHj#S~hF4jotO /l`z.xbgz4g:ZrlSM8+&{[j`1`*UM/6dwAYݴָ-:gZ77W\L6pIm͍Tڂ95J`B0mbUFAa`E 䅞i4b-.wEda7i9l:ȾOTQÝvYqu(L$0 fxtԝ|:KۧI1D{ypBδ 崁ͺ[EZxܼjA6 BpxAay`{`d+xA{W©3n'EI;G0CMtMCJ/4aI_-=L.<"\2%O7lL*[p^Ҷrf'.P:߆2qmQ[!5],7GŊ? *0¸,}GD\zzVGiDAwʂQ>2{ ȫ?J#ȡ`o7"g"Aݦ.5Rܣ2S M'4w|a?|-‹P5K.G.A\ F&  ,Ex  ayn/FRl|U'lJaZФF]ӈԈICS84ihoH%6n=}c_:.8rW2dؿ6ٕ!ѺAY~rY*L=]*fwA wU"w7d$LRn[o-TI Me?ş/$.K^.K釧e\OT=9Kf>LGp#lJS2>KGp#_1z-!.@/``{y, oU7:(wH)w<1' A @c:8Pp Po`:o`Q_)hBC~E~oRSm!&*t=Hc P:l^~C0e(xK9]1O ?ʻUk*2F; E6 +Ұ4 "W!8tINpnMci 7 4xoL/i 7ub_F^TpԦZ*b`6C̀m3` 6MǴmiafmi;t$yΡm;% wF40:rzk$c00t 㚑ǔa\Xzn),zp(W6` \XFߠRoj)~Cm3nxvE[1}x)X6|{T{).E s2IS_xnI1F]ӻJnOM`ʾ}%i*@ѡ7YV0PcA_,04z"W!awE&\(iIէS.&x9ئtu|дz@ۭT. % ` 20\IzO4P 5㓲fCJ_֦ z,ca.E9K2.^A?Ug̜0hHB0%( YhEW J\T 6 fTA1q./ TeuS2SL?Q rjL_ykC7cMܥp KNXkk:CWOL@4%!6n劍[Ua =8qUOПJs2&?eC)zؼ+Jk-hu}Cf[J_Ю΄;l#ZR ZRC屐 j8H=Y> 9 9*py9S~8Tc(8rytbXQQȼQ ІhL10cͨ*V5-bv%qqZ=oQuA0V^f(p2̷C [Z6+6bf 9Tf_o`(Yq9\ b ->s$?f !)}[Yb f YƬa ٌYƬW|:ȔOAUCOO yxģ(@ap5A<^D-me銜)QԴאQOmОڨ,]̥ 0)0SQ}gc^>bRc>ӫμByKȔv{S7U~C0p&leidenbase/inst/testdata/test03_file01.txt0000644000176200001440000000567014444624070020173 0ustar liggesusers2 2 5 5 6 4 2 3 5 1 3 2 4 4 4 1 6 1 2 5 3 2 3 3 1 5 1 1 1 2 1 3 6 3 6 2 4 3 1 7 6 2 2 7 4 2 7 4 2 3 3 2 4 1 1 4 4 4 1 8 7 3 7 4 5 4 1 8 3 5 2 6 4 1 5 3 4 7 1 4 2 2 1 4 5 4 1 3 5 1 1 3 4 5 2 5 1 5 2 2 2 4 1 3 7 7 2 3 2 7 3 5 7 5 2 6 1 5 7 5 5 1 3 3 1 4 5 1 3 1 1 1 5 1 2 4 6 1 1 6 2 3 9 3 4 1 2 4 3 4 6 2 1 5 7 3 3 9 1 3 4 8 1 2 4 4 5 3 7 3 3 6 1 5 1 1 7 6 3 2 1 2 1 5 3 2 2 4 2 4 8 1 1 1 5 3 3 5 3 2 1 5 4 3 3 1 1 6 7 5 3 1 1 6 2 7 1 4 4 3 2 1 1 4 4 2 2 5 1 1 4 5 4 1 4 1 7 6 2 5 4 5 3 1 1 2 2 5 6 2 1 2 6 4 7 1 2 1 7 1 2 1 1 1 2 2 3 1 1 1 1 5 4 2 6 5 2 1 2 4 7 2 5 1 2 1 1 7 2 1 3 4 3 5 3 4 5 6 2 3 3 2 7 2 1 4 5 6 1 7 2 5 1 2 3 5 9 6 2 3 2 2 1 1 5 1 3 1 1 2 5 6 1 3 5 8 3 2 1 2 1 3 3 4 4 3 7 2 1 1 3 1 1 5 1 1 1 3 2 2 3 5 5 2 3 4 6 2 3 7 4 4 5 4 2 4 3 4 3 3 2 1 2 3 5 7 5 4 4 4 6 4 1 2 1 1 3 4 2 1 3 4 3 3 4 1 2 5 4 7 7 2 2 2 8 2 3 2 3 2 5 2 3 6 4 1 7 5 1 1 2 1 6 3 4 8 2 2 2 6 1 4 2 3 1 2 3 3 3 3 5 1 4 6 5 4 7 3 3 2 1 5 1 5 1 1 5 2 3 6 1 5 5 5 5 2 2 5 4 1 2 5 1 4 4 1 1 2 5 7 1 4 4 3 2 6 2 4 2 5 7 1 1 3 3 2 1 3 3 2 2 1 2 2 3 5 5 3 2 6 4 2 1 2 4 5 4 5 4 2 3 1 7 1 1 2 1 1 3 1 2 7 3 3 4 2 2 4 6 1 2 3 1 5 5 3 4 7 3 3 1 1 4 1 5 7 5 4 1 4 3 3 5 3 3 1 1 2 3 1 1 5 3 3 4 2 3 1 6 3 1 4 4 3 2 7 2 2 2 5 4 3 2 4 3 3 4 3 4 4 1 4 4 3 5 3 2 3 1 1 4 3 3 1 4 1 1 3 5 1 4 1 6 7 1 2 3 1 4 3 4 6 4 3 3 2 1 5 4 1 2 7 1 2 5 1 2 3 1 5 5 2 5 2 2 2 3 4 5 3 5 3 2 3 2 5 2 5 1 1 4 1 2 2 4 1 2 3 2 2 4 3 2 3 4 1 5 3 1 2 2 1 1 3 3 1 6 3 1 5 7 1 2 2 1 2 6 2 2 5 1 2 2 5 7 3 1 3 5 2 4 2 3 4 1 1 3 5 6 3 2 2 4 4 6 1 1 7 5 3 3 8 1 1 2 1 3 1 2 4 2 1 2 3 3 5 3 1 2 1 3 1 2 3 8 1 1 3 1 7 5 2 2 6 4 1 1 2 5 1 2 3 1 5 5 1 5 1 5 4 3 5 1 2 5 3 2 4 1 4 2 3 1 6 4 1 5 2 5 9 2 2 4 1 2 2 7 1 2 1 1 1 1 6 2 6 3 1 5 4 8 8 2 3 4 2 1 3 6 5 2 1 2 6 3 2 2 8 5 6 4 7 3 1 1 1 1 4 6 6 4 1 2 3 1 4 2 9 7 1 2 1 4 4 1 1 3 1 4 6 2 7 1 4 2 2 1 1 3 7 3 1 7 3 3 1 4 2 4 1 4 4 2 3 9 3 3 7 2 8 3 1 2 1 5 1 6 7 3 2 3 1 2 3 1 3 6 3 1 4 4 3 1 3 1 2 1 3 3 2 2 5 2 8 7 3 3 7 3 1 3 2 3 2 6 2 2 1 2 1 5 5 4 2 2 5 7 6 4 2 1 7 5 1 7 1 2 3 2 7 4 1 1 4 3 1 2 3 2 4 2 5 5 1 2 3 5 1 3 1 3 2 5 7 4 3 1 1 4 2 3 8 2 5 1 7 4 4 4 3 7 2 2 2 4 1 5 3 3 1 5 6 2 9 1 2 1 1 2 2 5 5 2 6 1 2 5 1 5 1 2 6 5 2 1 1 1 1 4 4 2 3 1 6 2 4 4 2 4 2 5 2 4 5 1 2 2 3 3 1 3 4 1 5 2 3 5 4 4 4 3 3 1 6 5 5 3 3 4 3 6 1 3 1 7 5 5 2 1 5 1 9 5 2 1 1 3 3 7 4 6 1 5 5 7 1 4 1 6 2 1 1 4 5 1 2 3 2 7 5 7 3 2 1 3 1 3 5 2 4 1 3 3 2 2 1 3 3 3 3 2 3 3 1 6 2 3 2 1 4 4 2 7 1 3 3 5 1 3 3 2 5 5 2 5 2 4 2 4 1 3 2 4 3 1 3 4 7 2 1 7 3 1 1 1 2 4 4 2 1 7 1 5 2 3 4 2 5 2 4 4 8 5 7 1 4 4 6 1 2 3 2 5 7 1 6 3 6 5 1 4 2 6 5 5 6 5 3 1 5 5 1 6 2 7 4 2 3 3 3 7 2 5 3 6 3 6 4 4 7 5 4 5 1 6 5 2 3 2 3 4 4 1 5 3 7 6 3 5 4 3 7 5 5 2 2 2 5 5 1 7 3 3 4 1 2 1 2 2 7 8 1 6 3 3 3 3 1 6 5 1 4 1 1 1 2 1 2 3 1 1 1 2 1 3 3 3 6 4 1 7 1 3 1 5 4 4 6 4 1 1 4 2 2 3 8 7 6 7 4 4 2 1 4 3 4 6 5 1 3 7 6 1 7 5 5 3 2 3 1 1 5 2 4 5 5 5 2 2 2 1 1 3 1 3 5 6 4 2 8 1 1 2 1 1 1 6 2 1 5 3 3 6 6 5 2 3 5 2 3 9 3 8 3 3 5 3 3 2 7 2 4 1 8 3 2 1 5 1 2 3 6 1 2 8 1 4 3 3 1 3 4 3 1 3 2 2 1 1 5 2 2 4 2 4 1 4 8 5 3 6 1 6 3 4 1 1 2 2 7 3 8 3 3 1 3 4 8 4 1 leidenbase/inst/testdata/test09_file01.txt0000644000176200001440000000567014444624070020201 0ustar liggesusers2 2 5 5 6 4 2 3 5 1 3 2 4 4 4 1 6 1 2 5 3 2 3 3 1 5 1 1 1 2 1 3 6 3 6 2 4 3 1 7 6 2 2 7 4 2 7 4 2 3 3 2 4 1 1 4 4 4 1 8 7 3 7 4 5 4 1 8 3 5 2 6 4 1 5 3 4 7 1 4 2 2 1 4 5 4 1 3 5 1 1 3 4 5 2 5 1 5 2 2 2 4 1 3 7 7 2 3 2 7 3 5 7 5 2 6 1 5 7 5 5 1 3 3 1 4 5 1 3 1 1 1 5 1 2 4 6 1 2 6 2 3 6 3 4 1 2 4 3 4 6 2 1 5 7 3 3 6 1 3 4 8 1 2 4 4 5 3 7 3 3 6 1 5 1 1 7 6 3 2 1 2 1 5 3 2 2 4 2 4 8 1 1 1 5 3 3 5 3 2 1 5 4 3 3 1 1 6 7 5 3 1 1 6 2 7 1 4 4 3 2 1 1 4 4 2 2 5 1 1 4 5 4 1 4 1 2 6 2 5 4 5 3 1 1 2 2 5 6 2 1 2 6 4 7 1 2 1 7 1 2 1 1 1 2 2 3 1 1 1 1 5 4 2 6 5 2 1 2 4 7 2 5 1 2 1 1 7 2 1 3 4 3 5 3 4 5 6 2 3 3 2 7 2 1 4 5 6 1 7 2 5 1 2 3 5 6 6 2 3 2 2 1 1 5 1 3 1 1 2 5 6 1 3 5 8 3 2 1 2 1 3 3 4 4 3 7 2 1 1 3 1 1 5 1 1 1 3 2 2 3 5 5 2 3 4 6 2 3 7 4 4 5 4 2 4 3 4 3 3 2 1 2 3 5 7 5 4 4 4 6 4 1 2 1 1 3 4 2 1 3 4 3 3 4 1 2 5 4 7 7 2 2 2 8 2 3 2 3 2 5 2 3 6 4 1 7 5 1 1 2 1 6 3 4 8 2 2 2 6 1 4 2 3 1 2 3 3 3 3 5 1 4 6 5 4 7 3 3 2 1 5 1 5 1 1 5 2 3 6 2 5 5 5 5 2 2 5 4 1 2 5 1 4 4 1 1 2 5 7 1 4 4 3 2 6 2 4 2 5 7 1 1 3 3 2 1 3 3 2 2 1 2 2 3 5 5 3 2 6 4 2 1 2 4 5 4 5 4 2 3 1 7 1 1 2 1 1 3 1 2 7 3 3 4 2 2 4 6 1 2 3 1 5 5 3 4 7 3 3 1 1 4 1 5 7 5 4 1 4 3 3 5 3 3 1 1 2 3 1 1 5 3 3 4 2 3 1 6 3 1 4 4 3 2 2 2 2 2 1 4 3 2 4 3 3 4 3 4 4 1 4 4 3 5 3 2 3 1 1 4 3 3 1 4 1 1 3 5 1 4 1 6 7 1 2 3 1 4 3 4 6 4 3 3 2 1 5 4 1 2 7 1 2 5 1 2 3 1 5 5 2 5 2 2 2 3 4 5 3 5 3 2 3 2 5 2 5 1 1 4 1 2 2 4 1 2 3 2 2 4 3 2 3 4 1 5 3 1 2 2 1 1 3 3 1 6 3 1 5 7 1 2 2 1 2 6 2 2 5 1 2 2 5 7 3 1 3 5 2 4 2 3 4 1 1 3 5 6 3 2 2 4 4 6 1 1 7 5 3 3 4 1 1 2 1 3 1 2 4 2 1 2 3 3 5 3 1 2 1 3 1 2 3 8 1 1 3 1 7 5 2 2 6 4 1 1 2 5 1 2 3 1 5 5 1 5 1 5 4 3 5 1 2 5 3 2 4 1 4 2 3 1 6 4 1 5 2 5 3 2 2 4 1 2 2 7 1 2 1 1 1 2 6 2 6 3 1 5 4 8 8 2 3 4 2 1 3 6 5 2 1 2 6 3 2 2 8 5 6 4 7 3 1 1 1 1 4 6 6 4 1 2 3 1 4 2 6 7 1 2 1 4 4 1 1 3 1 4 6 2 7 1 4 2 2 1 1 3 7 3 1 7 3 3 1 4 2 4 1 4 4 2 3 6 3 3 7 2 8 3 1 2 1 5 1 6 7 3 2 3 1 2 3 1 3 6 3 1 4 4 3 1 3 1 2 1 3 3 2 2 5 2 3 7 3 3 7 3 1 3 2 3 2 6 2 2 1 2 1 5 5 4 2 2 5 7 6 4 2 1 2 5 1 2 1 2 3 2 7 4 1 1 4 3 1 2 3 2 4 2 5 5 1 2 3 5 1 3 2 3 2 5 7 4 3 1 1 4 2 3 8 2 5 1 7 4 4 4 3 7 2 2 2 4 1 5 3 3 1 5 6 2 6 1 2 1 1 2 2 5 5 2 6 1 2 5 1 5 1 2 6 5 2 1 1 1 1 4 4 2 3 1 6 2 4 4 2 4 2 5 2 4 5 1 2 2 3 3 1 3 4 1 5 2 3 5 4 4 4 3 3 1 6 5 5 3 3 4 3 6 1 3 1 7 5 5 2 1 5 1 6 5 2 1 1 3 3 7 4 6 1 5 5 7 1 4 1 6 2 1 1 4 5 1 2 3 2 7 5 7 3 2 1 3 1 3 5 2 4 1 3 3 2 2 1 3 3 3 3 2 3 3 1 6 2 3 2 1 4 4 2 7 1 3 3 5 1 3 3 2 5 5 2 5 2 4 2 4 1 3 2 4 3 1 3 4 7 2 1 7 3 1 1 1 2 4 4 2 1 7 1 5 2 3 4 2 5 2 4 4 8 5 7 1 4 4 6 1 2 3 2 5 7 1 6 3 6 5 1 4 2 6 5 5 6 5 3 1 5 5 1 6 2 7 4 2 3 3 3 7 2 5 3 6 3 6 4 4 7 5 4 5 1 6 5 2 3 2 3 4 4 1 5 3 7 6 3 5 4 3 7 5 5 2 2 2 5 5 1 7 3 3 4 1 2 1 2 2 7 8 2 6 3 3 3 3 1 6 5 1 4 1 1 1 2 1 2 3 1 1 1 2 1 3 3 3 6 4 1 7 1 3 1 5 4 4 6 4 1 1 4 2 2 3 8 7 6 7 4 4 2 1 4 3 4 6 5 1 3 7 6 1 7 5 5 3 2 3 1 1 5 2 4 5 5 5 2 2 2 1 1 3 1 3 5 6 4 2 8 1 1 2 1 1 1 6 2 1 5 3 3 6 6 5 2 3 5 2 3 6 3 8 3 3 5 3 3 2 7 2 4 1 8 3 2 1 5 1 2 3 6 1 2 8 1 4 3 3 1 3 4 3 1 3 2 2 1 1 5 2 2 4 2 4 1 4 8 5 3 6 1 6 3 4 1 1 2 2 7 3 8 3 3 1 3 4 8 4 1 leidenbase/inst/testdata/test10_file01.txt0000644000176200001440000000567014444624070020171 0ustar liggesusers2 2 5 5 6 4 2 3 5 1 3 2 4 4 4 1 6 1 2 5 3 2 3 3 1 5 1 1 1 2 1 3 6 3 6 2 4 3 1 7 6 2 2 7 4 2 7 4 2 3 3 2 4 1 1 4 4 4 1 8 7 3 7 4 5 4 1 8 3 5 2 6 4 1 5 3 4 7 1 4 2 2 1 4 5 4 1 3 5 1 1 3 4 5 2 5 1 5 2 2 2 4 1 3 7 7 2 3 2 7 3 5 7 5 2 6 1 5 7 5 5 1 3 3 1 4 5 1 3 1 1 1 5 1 2 4 6 1 2 6 2 3 6 3 4 1 2 4 3 4 6 2 1 5 7 3 3 6 1 3 4 8 1 2 4 4 5 3 7 3 3 6 1 5 1 1 7 6 3 2 1 2 1 5 3 2 2 4 2 4 8 1 1 1 5 3 3 5 3 2 1 5 4 3 3 1 1 6 7 5 3 1 1 6 2 7 1 4 4 3 2 1 1 4 4 2 2 5 1 1 4 5 4 1 4 1 2 6 2 5 4 5 3 1 1 2 2 5 6 2 1 2 6 4 7 1 2 1 7 1 2 1 1 1 2 2 3 1 1 1 1 5 4 2 6 5 2 1 2 4 7 2 5 1 2 1 1 7 2 1 3 4 3 5 3 4 5 6 2 3 3 2 7 2 1 4 5 6 1 7 2 5 1 2 3 5 6 6 2 3 2 2 1 1 5 1 3 1 1 2 5 6 1 3 5 8 3 2 1 2 1 3 3 4 4 3 7 2 1 1 3 1 1 5 1 1 1 3 2 2 3 5 5 2 3 4 6 2 3 7 4 4 5 4 2 4 3 4 3 3 2 1 2 3 5 7 5 4 4 4 6 4 1 2 1 1 3 4 2 1 3 4 3 3 4 1 2 5 4 7 7 2 2 2 8 2 3 2 3 2 5 2 3 6 4 1 7 5 1 1 2 1 6 3 4 8 2 2 2 6 1 4 2 3 1 2 3 3 3 3 5 1 4 6 5 4 7 3 3 2 1 5 1 5 1 1 5 2 3 6 2 5 5 5 5 2 2 5 4 1 2 5 1 4 4 1 1 2 5 7 1 4 4 3 2 6 2 4 2 5 7 1 1 3 3 2 1 3 3 2 2 1 2 2 3 5 5 3 2 6 4 2 1 2 4 5 4 5 4 2 3 1 7 1 1 2 1 1 3 1 2 7 3 3 4 2 2 4 6 1 2 3 1 5 5 3 4 7 3 3 1 1 4 1 5 7 5 4 1 4 3 3 5 3 3 1 1 2 3 1 1 5 3 3 4 2 3 1 6 3 1 4 4 3 2 2 2 2 2 1 4 3 2 4 3 3 4 3 4 4 1 4 4 3 5 3 2 3 1 1 4 3 3 1 4 1 1 3 5 1 4 1 6 7 1 2 3 1 4 3 4 6 4 3 3 2 1 5 4 1 2 7 1 2 5 1 2 3 1 5 5 2 5 2 2 2 3 4 5 3 5 3 2 3 2 5 2 5 1 1 4 1 2 2 4 1 2 3 2 2 4 3 2 3 4 1 5 3 1 2 2 1 1 3 3 1 6 3 1 5 7 1 2 2 1 2 6 2 2 5 1 2 2 5 7 3 1 3 5 2 4 2 3 4 1 1 3 5 6 3 2 2 4 4 6 1 1 7 5 3 3 4 1 1 2 1 3 1 2 4 2 1 2 3 3 5 3 1 2 1 3 1 2 3 8 1 1 3 1 7 5 2 2 6 4 1 1 2 5 1 2 3 1 5 5 1 5 1 5 4 3 5 1 2 5 3 2 4 1 4 2 3 1 6 4 1 5 2 5 3 2 2 4 1 2 2 7 1 2 1 1 1 2 6 2 6 3 1 5 4 8 8 2 3 4 2 1 3 6 5 2 1 2 6 3 2 2 8 5 6 4 7 3 1 1 1 1 4 6 6 4 1 2 3 1 4 2 6 7 1 2 1 4 4 1 1 3 1 4 6 2 7 1 4 2 2 1 1 3 7 3 1 7 3 3 1 4 2 4 1 4 4 2 3 6 3 3 7 2 8 3 1 2 1 5 1 6 7 3 2 3 1 2 3 1 3 6 3 1 4 4 3 1 3 1 2 1 3 3 2 2 5 2 3 7 3 3 7 3 1 3 2 3 2 6 2 2 1 2 1 5 5 4 2 2 5 7 6 4 2 1 2 5 1 2 1 2 3 2 7 4 1 1 4 3 1 2 3 2 4 2 5 5 1 2 3 5 1 3 2 3 2 5 7 4 3 1 1 4 2 3 8 2 5 1 7 4 4 4 3 7 2 2 2 4 1 5 3 3 1 5 6 2 6 1 2 1 1 2 2 5 5 2 6 1 2 5 1 5 1 2 6 5 2 1 1 1 1 4 4 2 3 1 6 2 4 4 2 4 2 5 2 4 5 1 2 2 3 3 1 3 4 1 5 2 3 5 4 4 4 3 3 1 6 5 5 3 3 4 3 6 1 3 1 7 5 5 2 1 5 1 6 5 2 1 1 3 3 7 4 6 1 5 5 7 1 4 1 6 2 1 1 4 5 1 2 3 2 7 5 7 3 2 1 3 1 3 5 2 4 1 3 3 2 2 1 3 3 3 3 2 3 3 1 6 2 3 2 1 4 4 2 7 1 3 3 5 1 3 3 2 5 5 2 5 2 4 2 4 1 3 2 4 3 1 3 4 7 2 1 7 3 1 1 1 2 4 4 2 1 7 1 5 2 3 4 2 5 2 4 4 8 5 7 1 4 4 6 1 2 3 2 5 7 1 6 3 6 5 1 4 2 6 5 5 6 5 3 1 5 5 1 6 2 7 4 2 3 3 3 7 2 5 3 6 3 6 4 4 7 5 4 5 1 6 5 2 3 2 3 4 4 1 5 3 7 6 3 5 4 3 7 5 5 2 2 2 5 5 1 7 3 3 4 1 2 1 2 2 7 8 2 6 3 3 3 3 1 6 5 1 4 1 1 1 2 1 2 3 1 1 1 2 1 3 3 3 6 4 1 7 1 3 1 5 4 4 6 4 1 1 4 2 2 3 8 7 6 7 4 4 2 1 4 3 4 6 5 1 3 7 6 1 7 5 5 3 2 3 1 1 5 2 4 5 5 5 2 2 2 1 1 3 1 3 5 6 4 2 8 1 1 2 1 1 1 6 2 1 5 3 3 6 6 5 2 3 5 2 3 6 3 8 3 3 5 3 3 2 7 2 4 1 8 3 2 1 5 1 2 3 6 1 2 8 1 4 3 3 1 3 4 3 1 3 2 2 1 1 5 2 2 4 2 4 1 4 8 5 3 6 1 6 3 4 1 1 2 2 7 3 8 3 3 1 3 4 8 4 1 leidenbase/inst/testdata/expected_values.txt0000644000176200001440000000050014444624070021054 0ustar liggesuserst01_v02_expect <- 11835.00 t02_v02_expect <- 0.7822 t03_v02_expect <- 53195.37 t04_v02_expect <- 98402.11 t05_v02_expect <- 13864.21 t06_v02_expect <- 48209.73 t07_v02_expect <- 52930.96 t08_v02_expect <- 52930.96 t09_v02_expect <- 52930.96 t10_v02_expect <- 52930.96 t11_v01_expect <- 0.7095 t11_v02_expect <- 93834.96 leidenbase/cleanup0000755000176200001440000000043214532173045013725 0ustar liggesusers#! /bin/sh rm -f src/config.h src/Makevars touch src/config.h # Object files cause problems on Github Actions where they get included # in the source package that is re-generated from the original source, so # we remove them here in the cleanup step find src -name *.o | xargs rm leidenbase/configure0000755000176200001440000053764214532173045014301 0ustar liggesusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='' PACKAGE_TARNAME='' PACKAGE_VERSION='' PACKAGE_STRING='' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="igraph" ac_unique_file="src/f2c.h" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_cxx_list= ac_subst_vars='LTLIBOBJS LIBOBJS GLPK_LIBS HAVE_GLPK EGREP GREP CXXCPP GMP_LIBS INTERNAL_GMP HAVE_GMP XML2_CPPFLAGS XML2_LIBS HAVE_LIBXML XML2CONFIG ac_ct_FC FCFLAGS FC ac_ct_CXX CXXFLAGS CXX OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_graphml enable_glpk ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC FC FCFLAGS CXXCPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-graphml Disable support for GraphML format --disable-glpk Compile without the GLPK library Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags FC Fortran compiler command FCFLAGS Fortran compiler flags CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_fc_try_compile LINENO # --------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_fc_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_fc_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_fc_try_compile # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_cxx_check_func LINENO FUNC VAR # ------------------------------------ # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_cxx_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func # ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_cxx_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile # ac_fn_cxx_check_member LINENO AGGR MEMBER VAR INCLUDES # ------------------------------------------------------ # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_cxx_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 printf %s "checking for $2.$3... " >&6; } if eval test \${$4+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main (void) { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval "$4=yes" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main (void) { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval "$4=yes" else $as_nop eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$4 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_member # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " # Test code for whether the C++ compiler supports C++98 (global declarations) ac_cxx_conftest_cxx98_globals=' // Does the compiler advertise C++98 conformance? #if !defined __cplusplus || __cplusplus < 199711L # error "Compiler does not advertise C++98 conformance" #endif // These inclusions are to reject old compilers that // lack the unsuffixed header files. #include #include // and are *not* freestanding headers in C++98. extern void assert (int); namespace std { extern int strcmp (const char *, const char *); } // Namespaces, exceptions, and templates were all added after "C++ 2.0". using std::exception; using std::strcmp; namespace { void test_exception_syntax() { try { throw "test"; } catch (const char *s) { // Extra parentheses suppress a warning when building autoconf itself, // due to lint rules shared with more typical C programs. assert (!(strcmp) (s, "test")); } } template struct test_template { T const val; explicit test_template(T t) : val(t) {} template T add(U u) { return static_cast(u) + val; } }; } // anonymous namespace ' # Test code for whether the C++ compiler supports C++98 (body of main) ac_cxx_conftest_cxx98_main=' assert (argc); assert (! argv[0]); { test_exception_syntax (); test_template tt (2.0); assert (tt.add (4) == 6.0); assert (true && !false); } ' # Test code for whether the C++ compiler supports C++11 (global declarations) ac_cxx_conftest_cxx11_globals=' // Does the compiler advertise C++ 2011 conformance? #if !defined __cplusplus || __cplusplus < 201103L # error "Compiler does not advertise C++11 conformance" #endif namespace cxx11test { constexpr int get_val() { return 20; } struct testinit { int i; double d; }; class delegate { public: delegate(int n) : n(n) {} delegate(): delegate(2354) {} virtual int getval() { return this->n; }; protected: int n; }; class overridden : public delegate { public: overridden(int n): delegate(n) {} virtual int getval() override final { return this->n * 2; } }; class nocopy { public: nocopy(int i): i(i) {} nocopy() = default; nocopy(const nocopy&) = delete; nocopy & operator=(const nocopy&) = delete; private: int i; }; // for testing lambda expressions template Ret eval(Fn f, Ret v) { return f(v); } // for testing variadic templates and trailing return types template auto sum(V first) -> V { return first; } template auto sum(V first, Args... rest) -> V { return first + sum(rest...); } } ' # Test code for whether the C++ compiler supports C++11 (body of main) ac_cxx_conftest_cxx11_main=' { // Test auto and decltype auto a1 = 6538; auto a2 = 48573953.4; auto a3 = "String literal"; int total = 0; for (auto i = a3; *i; ++i) { total += *i; } decltype(a2) a4 = 34895.034; } { // Test constexpr short sa[cxx11test::get_val()] = { 0 }; } { // Test initializer lists cxx11test::testinit il = { 4323, 435234.23544 }; } { // Test range-based for int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; for (auto &x : array) { x += 23; } } { // Test lambda expressions using cxx11test::eval; assert (eval ([](int x) { return x*2; }, 21) == 42); double d = 2.0; assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); assert (d == 5.0); assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); assert (d == 5.0); } { // Test use of variadic templates using cxx11test::sum; auto a = sum(1); auto b = sum(1, 2); auto c = sum(1.0, 2.0, 3.0); } { // Test constructor delegation cxx11test::delegate d1; cxx11test::delegate d2(); cxx11test::delegate d3(45); } { // Test override and final cxx11test::overridden o1(55464); } { // Test nullptr char *c = nullptr; } { // Test template brackets test_template<::test_template> v(test_template(12)); } { // Unicode literals char const *utf8 = u8"UTF-8 string \u2500"; char16_t const *utf16 = u"UTF-8 string \u2500"; char32_t const *utf32 = U"UTF-32 string \u2500"; } ' # Test code for whether the C compiler supports C++11 (complete). ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} ${ac_cxx_conftest_cxx11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} ${ac_cxx_conftest_cxx11_main} return ok; } " # Test code for whether the C compiler supports C++98 (complete). ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} return ok; } " as_fn_append ac_header_cxx_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_cxx_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_cxx_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_cxx_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_cxx_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_cxx_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_cxx_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_cxx_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_cxx_list " unistd.h unistd_h HAVE_UNISTD_H" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers src/config.h" : ${R_HOME=`R RHOME`} if test -z "${R_HOME}"; then echo "could not determine R_HOME" exit 1 fi CC=`"${R_HOME}/bin/R" CMD config CC` CXX=`"${R_HOME}/bin/R" CMD config CXX11` if test -z "$CXX"; then as_fn_error $? "No C++11 compiler is available" "$LINENO" 5 fi CXX11STD=`"${R_HOME}/bin/R" CMD config CXX11STD` CXX="${CXX} ${CXX11STD}" FC=`"${R_HOME}/bin/R" CMD config FC` CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS` CXXFLAGS=`"${R_HOME}/bin/R" CMD config CXX11FLAGS` CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS` FCFLAGS=`"${R_HOME}/bin/R" CMD config FCFLAGS` FLIBS=`"${R_HOME}/bin/R" CMD config FLIBS` LDFLAGS=`"${R_HOME}/bin/R" CMD config LDFLAGS` ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 printf "%s\n" "$CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 printf "%s\n" "$ac_ct_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } if test $ac_test_CXXFLAGS; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_prog_cxx_stdcxx=no if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } if test ${ac_cv_prog_cxx_cxx11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx11_program _ACEOF for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx11" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 ac_prog_cxx_stdcxx=cxx11 fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } if test ${ac_cv_prog_cxx_cxx98+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx98_program _ACEOF for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx98=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx98" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 ac_prog_cxx_stdcxx=cxx98 fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # Fortran compiler, we need to check if it is the GNU compiler ac_ext=${ac_fc_srcext-f} ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_fc_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor xlf90 f90 pgf90 pghpf epcf90 g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$FC"; then ac_cv_prog_FC="$FC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_FC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi FC=$ac_cv_prog_FC if test -n "$FC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FC" >&5 printf "%s\n" "$FC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$FC" && break done fi if test -z "$FC"; then ac_ct_FC=$FC for ac_prog in gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor xlf90 f90 pgf90 pghpf epcf90 g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_FC"; then ac_cv_prog_ac_ct_FC="$ac_ct_FC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_FC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_FC=$ac_cv_prog_ac_ct_FC if test -n "$ac_ct_FC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FC" >&5 printf "%s\n" "$ac_ct_FC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_FC" && break done if test "x$ac_ct_FC" = x; then FC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FC=$ac_ct_FC fi fi # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Fortran compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done rm -f a.out # If we don't use `.F' as extension, the preprocessor is not run on the # input file. (Note that this only needs to work for GNU compilers.) ac_save_ext=$ac_ext ac_ext=F { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU Fortran" >&5 printf %s "checking whether the compiler supports GNU Fortran... " >&6; } if test ${ac_cv_fc_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat > conftest.$ac_ext <<_ACEOF program main #ifndef __GNUC__ choke me #endif end _ACEOF if ac_fn_fc_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_fc_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_compiler_gnu" >&5 printf "%s\n" "$ac_cv_fc_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_fc_compiler_gnu ac_ext=$ac_save_ext ac_test_FCFLAGS=${FCFLAGS+y} ac_save_FCFLAGS=$FCFLAGS FCFLAGS= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $FC accepts -g" >&5 printf %s "checking whether $FC accepts -g... " >&6; } if test ${ac_cv_prog_fc_g+y} then : printf %s "(cached) " >&6 else $as_nop FCFLAGS=-g cat > conftest.$ac_ext <<_ACEOF program main end _ACEOF if ac_fn_fc_try_compile "$LINENO" then : ac_cv_prog_fc_g=yes else $as_nop ac_cv_prog_fc_g=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_fc_g" >&5 printf "%s\n" "$ac_cv_prog_fc_g" >&6; } if test $ac_test_FCFLAGS; then FCFLAGS=$ac_save_FCFLAGS elif test $ac_cv_prog_fc_g = yes; then if test "x$ac_cv_fc_compiler_gnu" = xyes; then FCFLAGS="-g -O2" else FCFLAGS="-g" fi else if test "x$ac_cv_fc_compiler_gnu" = xyes; then FCFLAGS="-O2" else FCFLAGS= fi fi if test $ac_compiler_gnu = yes; then GFC=yes else GFC= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test "x$ac_cv_fc_compiler_gnu" = xyes; then printf "%s\n" "#define HAVE_GFORTRAN 1" >>confdefs.h fi LIBS_SAVE=$LIBS LIBS="$LIBS -lm" ac_fn_cxx_check_func "$LINENO" "expm1" "ac_cv_func_expm1" if test "x$ac_cv_func_expm1" = xyes then : printf "%s\n" "#define HAVE_EXPM1 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "fmin" "ac_cv_func_fmin" if test "x$ac_cv_func_fmin" = xyes then : printf "%s\n" "#define HAVE_FMIN 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "finite" "ac_cv_func_finite" if test "x$ac_cv_func_finite" = xyes then : printf "%s\n" "#define HAVE_FINITE 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "log2" "ac_cv_func_log2" if test "x$ac_cv_func_log2" = xyes then : printf "%s\n" "#define HAVE_LOG2 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "log1p" "ac_cv_func_log1p" if test "x$ac_cv_func_log1p" = xyes then : printf "%s\n" "#define HAVE_LOG1P 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "rint" "ac_cv_func_rint" if test "x$ac_cv_func_rint" = xyes then : printf "%s\n" "#define HAVE_RINT 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "rintf" "ac_cv_func_rintf" if test "x$ac_cv_func_rintf" = xyes then : printf "%s\n" "#define HAVE_RINTF 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "round" "ac_cv_func_round" if test "x$ac_cv_func_round" = xyes then : printf "%s\n" "#define HAVE_ROUND 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "stpcpy" "ac_cv_func_stpcpy" if test "x$ac_cv_func_stpcpy" = xyes then : printf "%s\n" "#define HAVE_STPCPY 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" if test "x$ac_cv_func_strcasecmp" = xyes then : printf "%s\n" "#define HAVE_STRCASECMP 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "_stricmp" "ac_cv_func__stricmp" if test "x$ac_cv_func__stricmp" = xyes then : printf "%s\n" "#define HAVE__STRICMP 1" >>confdefs.h fi ac_fn_cxx_check_func "$LINENO" "strdup" "ac_cv_func_strdup" if test "x$ac_cv_func_strdup" = xyes then : printf "%s\n" "#define HAVE_STRDUP 1" >>confdefs.h fi for ac_func in isfinite do : ac_fn_cxx_check_func "$LINENO" "isfinite" "ac_cv_func_isfinite" if test "x$ac_cv_func_isfinite" = xyes then : printf "%s\n" "#define HAVE_ISFINITE 1" >>confdefs.h printf "%s\n" "#define HAVE_ISFINITE 1" >>confdefs.h else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { double f = 0.0; isfinite(f) ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : printf "%s\n" "#define HAVE_ISFINITE 1" >>confdefs.h else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "isfinite() not available See \`config.log' for more details" "$LINENO" 5; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi done LIBS=$LIBS_SAVE ac_header= ac_cache= for ac_item in $ac_header_cxx_list do if test $ac_cache; then ac_fn_cxx_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "sys/times.h" "ac_cv_header_sys_times_h" "$ac_includes_default" if test "x$ac_cv_header_sys_times_h" = xyes then : printf "%s\n" "#define HAVE_TIMES_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_h" = xyes then : printf "%s\n" "#define HAVE_NET_IF_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default" if test "x$ac_cv_header_netinet_in_h" = xyes then : printf "%s\n" "#define HAVE_NETINET_IN_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "net/if_dl.h" "ac_cv_header_net_if_dl_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_dl_h" = xyes then : printf "%s\n" "#define HAVE_NET_IF_DL_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "sys/sockio.h" "ac_cv_header_sys_sockio_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sockio_h" = xyes then : printf "%s\n" "#define HAVE_SYS_SOCKIO_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default" if test "x$ac_cv_header_sys_un_h" = xyes then : printf "%s\n" "#define HAVE_SYS_UN_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default" if test "x$ac_cv_header_sys_socket_h" = xyes then : printf "%s\n" "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" if test "x$ac_cv_header_sys_ioctl_h" = xyes then : printf "%s\n" "#define HAVE_SYS_IOCTL_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" if test "x$ac_cv_header_sys_time_h" = xyes then : printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "sys/file.h" "ac_cv_header_sys_file_h" "$ac_includes_default" if test "x$ac_cv_header_sys_file_h" = xyes then : printf "%s\n" "#define HAVE_SYS_FILE_H 1" >>confdefs.h fi ac_fn_cxx_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "#include #include " if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes then : printf "%s\n" "#define HAVE_SA_LEN 1" >>confdefs.h fi graphml_support=yes # Check whether --enable-graphml was given. if test ${enable_graphml+y} then : enableval=$enable_graphml; graphml_support=$enableval else $as_nop graphml_support=yes fi HAVE_LIBXML=0 if test $graphml_support = yes; then # Extract the first word of "xml2-config", so it can be a program name with args. set dummy xml2-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_XML2CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $XML2CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_XML2CONFIG="$XML2CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_XML2CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_XML2CONFIG" && ac_cv_path_XML2CONFIG="none" ;; esac fi XML2CONFIG=$ac_cv_path_XML2CONFIG if test -n "$XML2CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $XML2CONFIG" >&5 printf "%s\n" "$XML2CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "$XML2CONFIG" = "none"; then graphml_support=no else # xml2-config puts only preprocessor flags in --cflags (i.e. -D and -I) so # we can put them in XML2_CPPFLAGS. This might not be true for other # libraries, though. XML2_CPPFLAGS=`$XML2CONFIG --cflags` XML2_LIBS=`$XML2CONFIG --libs` OLDLIBS=${LIBS} LIBS=${XML2_LIBS} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlSAXUserParseFile in -lxml2" >&5 printf %s "checking for xmlSAXUserParseFile in -lxml2... " >&6; } if test ${ac_cv_lib_xml2_xmlSAXUserParseFile+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lxml2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int xmlSAXUserParseFile (); } int main (void) { return conftest::xmlSAXUserParseFile (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : ac_cv_lib_xml2_xmlSAXUserParseFile=yes else $as_nop ac_cv_lib_xml2_xmlSAXUserParseFile=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xml2_xmlSAXUserParseFile" >&5 printf "%s\n" "$ac_cv_lib_xml2_xmlSAXUserParseFile" >&6; } if test "x$ac_cv_lib_xml2_xmlSAXUserParseFile" = xyes then : OLDCPPFLAGS=${CPPFLAGS} CPPFLAGS=${XML2_CPPFLAGS} ac_fn_cxx_check_header_compile "$LINENO" "libxml/parser.h" "ac_cv_header_libxml_parser_h" "$ac_includes_default" if test "x$ac_cv_header_libxml_parser_h" = xyes then : HAVE_LIBXML=1 printf "%s\n" "#define HAVE_LIBXML 1" >>confdefs.h else $as_nop graphml_support=no fi CPPFLAGS=${OLDCPPFLAGS} else $as_nop graphml_support=no fi LIBS=${OLDLIBS} fi fi printf "%s\n" "#define INTERNAL_GMP 1" >>confdefs.h ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu HAVE_GMP=0 INTERNAL_GMP=1 GMP_LIBS="" gmp_support=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __gmpz_add in -lgmp" >&5 printf %s "checking for __gmpz_add in -lgmp... " >&6; } if test ${ac_cv_lib_gmp___gmpz_add+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lgmp $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int __gmpz_add (); } int main (void) { return conftest::__gmpz_add (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : ac_cv_lib_gmp___gmpz_add=yes else $as_nop ac_cv_lib_gmp___gmpz_add=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp___gmpz_add" >&5 printf "%s\n" "$ac_cv_lib_gmp___gmpz_add" >&6; } if test "x$ac_cv_lib_gmp___gmpz_add" = xyes then : ac_fn_cxx_check_header_compile "$LINENO" "gmp.h" "ac_cv_header_gmp_h" "$ac_includes_default" if test "x$ac_cv_header_gmp_h" = xyes then : HAVE_GMP=1 INTERNAL_GMP=0 printf "%s\n" "#define HAVE_GMP 1" >>confdefs.h gmp_support=yes GMP_LIBS="-lgmp" fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu HAVE_GLPK=0 GLPK_LIBS="" glpk_support=no # Check whether --enable-glpk was given. if test ${enable_glpk+y} then : enableval=$enable_glpk; fi if test "x$enable_glpk" != "xno"; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 printf %s "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test ${ac_cv_prog_CXXCPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CXX needs to be expanded for CXXCPP in "$CXX -E" cpp /lib/cpp do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 printf "%s\n" "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in grep ggrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in egrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for glp_read_mps in -lglpk" >&5 printf %s "checking for glp_read_mps in -lglpk... " >&6; } if test ${ac_cv_lib_glpk_glp_read_mps+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lglpk $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int glp_read_mps (); } int main (void) { return conftest::glp_read_mps (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : ac_cv_lib_glpk_glp_read_mps=yes else $as_nop ac_cv_lib_glpk_glp_read_mps=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_glpk_glp_read_mps" >&5 printf "%s\n" "$ac_cv_lib_glpk_glp_read_mps" >&6; } if test "x$ac_cv_lib_glpk_glp_read_mps" = xyes then : ac_fn_cxx_check_header_compile "$LINENO" "glpk.h" "ac_cv_header_glpk_h" "$ac_includes_default" if test "x$ac_cv_header_glpk_h" = xyes then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION >= 57) yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1 then : HAVE_GLPK=1 printf "%s\n" "#define HAVE_GLPK 1" >>confdefs.h glpk_support=yes GLPK_LIBS="-lglpk" fi rm -rf conftest* fi fi fi printf "%s\n" "#define IGRAPH_THREAD_LOCAL /**/" >>confdefs.h ac_config_files="$ac_config_files src/Makevars.tmp:src/Makevars.in" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to the package provider." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; "src/Makevars.tmp") CONFIG_FILES="$CONFIG_FILES src/Makevars.tmp:src/Makevars.in" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac case $ac_file$ac_mode in "src/Makevars.tmp":F) if test -f src/Makevars && cmp -s src/Makevars.tmp src/Makevars; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating src/Makevars" >&5 printf "%s\n" "$as_me: creating src/Makevars" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: src/Makevars is unchanged" >&5 printf "%s\n" "$as_me: src/Makevars is unchanged" >&6;} rm src/Makevars.tmp else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating src/Makevars" >&5 printf "%s\n" "$as_me: creating src/Makevars" >&6;} mv src/Makevars.tmp src/Makevars fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi echo "" echo "*** Compiler settings used:" echo " CC=${CC}" echo " LD=${LD}" echo " CFLAGS=${CFLAGS}" echo " CPPFLAGS=${CPPFLAGS}" echo " CXX=${CXX}" echo " CXXFLAGS=${CXXFLAGS}" echo " LDFLAGS=${LDFLAGS}" echo " LIBS=${LIBS}"